From 335b992683293186fb14f98dcc1dc3c977592060 Mon Sep 17 00:00:00 2001 From: JohnTheCoolingFan Date: Sat, 18 May 2024 20:50:53 +0300 Subject: [PATCH 1/8] BigTreeTech CB1 config update Changed maintainer to th current person Switched board family to sun50iw9, removed legacy kernel target, removed DEFAULT_CONSOLE --- config/boards/bigtreetech-cb1.conf | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/config/boards/bigtreetech-cb1.conf b/config/boards/bigtreetech-cb1.conf index a521e467caab..1edafb96d332 100644 --- a/config/boards/bigtreetech-cb1.conf +++ b/config/boards/bigtreetech-cb1.conf @@ -1,12 +1,10 @@ # Allwinner H616 quad core 512MB/1GB RAM SoC WiFi BOARD_NAME="BigTreeTech CB1" -BOARDFAMILY="sun50iw9-btt" -BOARD_MAINTAINER="bigtreetech" +BOARDFAMILY="sun50iw9" +BOARD_MAINTAINER="JohnTheCoolingFan" BOOTCONFIG="bigtreetech_cb1_defconfig" -DEFAULT_CONSOLE="serial" SERIALCON="ttyS0" -KERNEL_TARGET="legacy,current,edge" -KERNEL_TEST_TARGET="legacy" +KERNEL_TARGET="current,edge" FORCE_BOOTSCRIPT_UPDATE="yes" BOOTFS_TYPE="fat" BOOT_FS_LABEL="BOOT" From cb66f497782af5d2b0c767dcf94a6c12ac264145 Mon Sep 17 00:00:00 2001 From: JohnTheCoolingFan Date: Thu, 13 Jun 2024 14:09:07 +0300 Subject: [PATCH 2/8] Patches to enable hdmi and emac1 on BigTreeTech CB1 --- ...0i-h616-bigtreetech-cb1-enable-emac1.patch | 46 +++++++++++++ ...50i-h616-bigtreetech-cb1-enable-hdmi.patch | 65 +++++++++++++++++++ patch/kernel/archive/sunxi-6.6/series.armbian | 2 + patch/kernel/archive/sunxi-6.6/series.conf | 2 + ...0i-h616-bigtreetech-cb1-enable-emac1.patch | 1 + ...50i-h616-bigtreetech-cb1-enable-hdmi.patch | 1 + patch/kernel/archive/sunxi-6.7/series.armbian | 2 + patch/kernel/archive/sunxi-6.7/series.conf | 2 + 8 files changed, 121 insertions(+) create mode 100644 patch/kernel/archive/sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch create mode 100644 patch/kernel/archive/sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch create mode 120000 patch/kernel/archive/sunxi-6.7/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch create mode 120000 patch/kernel/archive/sunxi-6.7/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch diff --git a/patch/kernel/archive/sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch b/patch/kernel/archive/sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch new file mode 100644 index 000000000000..6509e0f87fbb --- /dev/null +++ b/patch/kernel/archive/sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JohnTheCoolingFan +Date: Thu, 13 Jun 2024 11:50:55 +0000 +Subject: ARM64: dts: sun50i-h616: BigTreeTech CB1: Enable EMAC1 + +Signed-off-by: JohnTheCoolingFan +--- + arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi | 18 ++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi +index bbff30ccf..b98e85a51 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi +@@ -142,10 +142,28 @@ mcp2515_clock: mcp2515_clock { + #clock-cells = <0>; + clock-frequency = <12000000>; + }; + }; + ++&emac1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rmii_pins>; ++ phy-mode = "rmii"; ++ phy-handle = <&rmii_phy>; ++ phy-supply = <®_dldo1>; ++ allwinner,rx-delay-ps = <3100>; ++ allwinner,tx-delay-ps = <700>; ++ status = "okay"; ++}; ++ ++&mdio1 { ++ rmii_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ }; ++}; ++ + &mmc0 { + vmmc-supply = <®_dldo1>; + broken-cd; + bus-width = <4>; + max-frequency = <50000000>; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch b/patch/kernel/archive/sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch new file mode 100644 index 000000000000..2d9e9768e897 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JohnTheCoolingFan +Date: Thu, 13 Jun 2024 11:07:35 +0000 +Subject: ARM64: dts: sun50i-h616: BigTreeTech CB1: Enable HDMI + +Signed-off-by: JohnTheCoolingFan +--- + arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi | 26 ++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi +index e82da4b6e..bbff30ccf 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi +@@ -23,10 +23,21 @@ aliases { + + chosen { + stdout-path = "serial0:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ type = "d"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + + act_led: led-0 { + gpios = <&pio 7 5 GPIO_ACTIVE_LOW>; /* PH5 */ +@@ -255,10 +266,25 @@ reg_dldo1: dldo1 { + }; + }; + }; + }; + ++&de { ++ status = "okay"; ++}; ++ ++&hdmi { ++ hvcc-supply = <®_aldo1>; ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ + &cpu0 { + cpu-supply = <®_dcdc2>; + status = "okay"; + }; + +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/archive/sunxi-6.6/series.armbian b/patch/kernel/archive/sunxi-6.6/series.armbian index 4f73271fb3eb..2db06bb403d0 100644 --- a/patch/kernel/archive/sunxi-6.6/series.armbian +++ b/patch/kernel/archive/sunxi-6.6/series.armbian @@ -189,3 +189,5 @@ patches.armbian/add-dtb-overlay-for-zero2w.patch patches.armbian/adding-dummy-regulators-in-pinctr-arch-arm-boot-dts-allwinner-s.patch patches.armbian/Sound-for-H616-H618-Allwinner-SOCs-arch-arm64-boot-dts-allwinne.patch + patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch + patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch diff --git a/patch/kernel/archive/sunxi-6.6/series.conf b/patch/kernel/archive/sunxi-6.6/series.conf index c80922884a38..634890b1d68b 100644 --- a/patch/kernel/archive/sunxi-6.6/series.conf +++ b/patch/kernel/archive/sunxi-6.6/series.conf @@ -441,3 +441,5 @@ patches.armbian/add-dtb-overlay-for-zero2w.patch patches.armbian/adding-dummy-regulators-in-pinctr-arch-arm-boot-dts-allwinner-s.patch patches.armbian/Sound-for-H616-H618-Allwinner-SOCs-arch-arm64-boot-dts-allwinne.patch + patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch + patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch diff --git a/patch/kernel/archive/sunxi-6.7/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch b/patch/kernel/archive/sunxi-6.7/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch new file mode 120000 index 000000000000..93a6f46415e3 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.7/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch @@ -0,0 +1 @@ +../../sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch \ No newline at end of file diff --git a/patch/kernel/archive/sunxi-6.7/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch b/patch/kernel/archive/sunxi-6.7/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch new file mode 120000 index 000000000000..0de064853345 --- /dev/null +++ b/patch/kernel/archive/sunxi-6.7/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch @@ -0,0 +1 @@ +../../sunxi-6.6/patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch \ No newline at end of file diff --git a/patch/kernel/archive/sunxi-6.7/series.armbian b/patch/kernel/archive/sunxi-6.7/series.armbian index 5f3193917c72..ce3bb1fd9a8c 100644 --- a/patch/kernel/archive/sunxi-6.7/series.armbian +++ b/patch/kernel/archive/sunxi-6.7/series.armbian @@ -204,3 +204,5 @@ patches.armbian/arm64-dts-allwinner-sun50i-h616-spi1-cs1-pin.patch patches.armbian/arm64-dts-sun50i-h618-add-overlay.patch patches.armbian/sound-soc-sunxi-h616-h618.patch + patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch + patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch diff --git a/patch/kernel/archive/sunxi-6.7/series.conf b/patch/kernel/archive/sunxi-6.7/series.conf index 88c515575f4e..7bf43c144ff0 100644 --- a/patch/kernel/archive/sunxi-6.7/series.conf +++ b/patch/kernel/archive/sunxi-6.7/series.conf @@ -526,3 +526,5 @@ patches.armbian/arm64-dts-allwinner-sun50i-h616-spi1-cs1-pin.patch patches.armbian/arm64-dts-sun50i-h618-add-overlay.patch patches.armbian/sound-soc-sunxi-h616-h618.patch + patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-hdmi.patch + patches.armbian/arm64-dts-sun50i-h616-bigtreetech-cb1-enable-emac1.patch From e3fab56c8e7c14e5e12149a6bf5b642144ccb31e Mon Sep 17 00:00:00 2001 From: JohnTheCoolingFan Date: Fri, 9 Aug 2024 09:15:35 +0300 Subject: [PATCH 3/8] U-Boot patch for BigTreeTech CB1 ethernet --- .../z-bigtreetech-cb1-PHY-EMAC1.patch | 346 ++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/z-bigtreetech-cb1-PHY-EMAC1.patch diff --git a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/z-bigtreetech-cb1-PHY-EMAC1.patch b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/z-bigtreetech-cb1-PHY-EMAC1.patch new file mode 100644 index 000000000000..7b62d95ccd57 --- /dev/null +++ b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/z-bigtreetech-cb1-PHY-EMAC1.patch @@ -0,0 +1,346 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JohnTheCoolingFan +Date: Fri, 9 Aug 2024 06:13:19 +0000 +Subject: Add built-in H616 PHY support for bigtreetech cb1 + +Signed-off-by: JohnTheCoolingFan +--- + arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts | 19 ++++++ + arch/arm/dts/sun50i-h616.dtsi | 27 +++++++++ + arch/arm/include/asm/arch-sunxi/i2c.h | 3 + + arch/arm/mach-sunxi/Kconfig | 9 +++ + arch/arm/mach-sunxi/board.c | 1 + + arch/arm/mach-sunxi/clock_sun50i_h6.c | 4 ++ + board/sunxi/board.c | 30 ++++++++++ + configs/bigtreetech_cb1_defconfig | 5 +- + drivers/net/sun8i_emac.c | 7 +++ + drivers/pinctrl/sunxi/pinctrl-sunxi.c | 1 + + 10 files changed, 104 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts +index dc0e04be947..acef7ef4f03 100644 +--- a/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts ++++ b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts +@@ -14,10 +14,11 @@ + / { + model = "BigTreeTech CB1"; + compatible = "bigtreetech,cb1", "allwinner,sun50i-h616"; + + aliases { ++ ethernet0 = &emac1; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; +@@ -92,10 +93,28 @@ + reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */ + post-power-on-delay-ms = <200>; + }; + }; + ++&emac1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rmii_pins>; ++ phy-mode = "rmii"; ++ phy-handle = <&rmii_phy>; ++ phy-supply = <®_aldo1>; ++ allwinner,rx-delay-ps = <3100>; ++ allwinner,tx-delay-ps = <700>; ++ status = "okay"; ++}; ++ ++&mdio1 { ++ rmii_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ }; ++}; ++ + &ehci1 { + status = "okay"; + }; + + &ohci1 { +diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi +index 46651703e9b..87d62cb1d3f 100644 +--- a/arch/arm/dts/sun50i-h616.dtsi ++++ b/arch/arm/dts/sun50i-h616.dtsi +@@ -207,10 +207,18 @@ + function = "mmc2"; + drive-strength = <40>; + bias-pull-up; + }; + ++ /omit-if-no-ref/ ++ rmii_pins: rmii-pins { ++ pins = "PA0", "PA1", "PA2", "PA3", "PA4", ++ "PA5", "PA6", "PA7", "PA8", "PA9"; ++ function = "emac1"; ++ drive-strength = <40>; ++ }; ++ + /omit-if-no-ref/ + spi0_pins: spi0-pins { + pins = "PC0", "PC2", "PC4"; + function = "spi0"; + }; +@@ -502,10 +510,29 @@ + #address-cells = <1>; + #size-cells = <0>; + }; + }; + ++ emac1: ethernet@5030000 { ++ compatible = "allwinner,sun50i-h616-emac1"; ++ syscon = <&syscon 1>; ++ reg = <0x05030000 0x10000>; ++ interrupts = ; ++ interrupt-names = "macirq"; ++ resets = <&ccu RST_BUS_EMAC1>; ++ reset-names = "stmmaceth"; ++ clocks = <&ccu CLK_BUS_EMAC1>; ++ clock-names = "stmmaceth"; ++ status = "disabled"; ++ ++ mdio1: mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ + usbotg: usb@5100000 { + compatible = "allwinner,sun50i-h616-musb", + "allwinner,sun8i-h3-musb"; + reg = <0x05100000 0x0400>; + clocks = <&ccu CLK_BUS_OTG>; +diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h +index f0da46d863c..98c26d7408e 100644 +--- a/arch/arm/include/asm/arch-sunxi/i2c.h ++++ b/arch/arm/include/asm/arch-sunxi/i2c.h +@@ -11,10 +11,13 @@ + #define CFG_I2C_MVTWSI_BASE0 SUNXI_TWI0_BASE + #endif + #ifdef CONFIG_I2C1_ENABLE + #define CFG_I2C_MVTWSI_BASE1 SUNXI_TWI1_BASE + #endif ++#ifdef CONFIG_I2C3_ENABLE ++#define CONFIG_I2C_MVTWSI_BASE3 SUNXI_TWI3_BASE ++#endif + #ifdef CONFIG_R_I2C_ENABLE + #define CFG_I2C_MVTWSI_BASE2 SUNXI_R_TWI_BASE + #endif + + /* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ +diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig +index d91faf9ab13..59cd48653c3 100644 +--- a/arch/arm/mach-sunxi/Kconfig ++++ b/arch/arm/mach-sunxi/Kconfig +@@ -807,10 +807,19 @@ config I2C1_ENABLE + bool "Enable I2C/TWI controller 1" + select CMD_I2C + ---help--- + See I2C0_ENABLE help text. + ++if MACH_SUN50I_H616 ++config I2C3_ENABLE ++ bool "Enable I2C/TWI controller 3" ++ default n ++ select CMD_I2C ++ ---help--- ++ See I2C0_ENABLE help text. ++endif ++ + if SUNXI_GEN_SUN6I || SUN50I_GEN_H6 + config R_I2C_ENABLE + bool "Enable the PRCM I2C/TWI controller" + # This is used for the pmic on H3 + default y if SY8106A_POWER +diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c +index 7d2d5d478fc..ca084bddda0 100644 +--- a/arch/arm/mach-sunxi/board.c ++++ b/arch/arm/mach-sunxi/board.c +@@ -479,10 +479,11 @@ void board_init_f(ulong dummy) + + #if CONFIG_IS_ENABLED(I2C) && CONFIG_IS_ENABLED(SYS_I2C_LEGACY) + /* Needed early by sunxi_board_init if PMU is enabled */ + i2c_init_board(); + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); ++ i2c_set_bus_num(0); + #endif + sunxi_board_init(); + } + #endif /* CONFIG_SPL_BUILD */ + +diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c +index 7f60b8c79fc..8c97ddb66c4 100644 +--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c ++++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c +@@ -51,10 +51,14 @@ void clock_init_safe(void) + /* + * The mux and factor are set, but the clock will be enabled in + * DRAM initialization code. + */ + writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), &ccm->mbus_cfg); ++ ++ writel(0x10001, 0x030017ac); ++ writel(0x50, 0x0300a028); ++ writel(0x20, 0x0300a040); + } + #endif + + void clock_init_uart(void) + { +diff --git a/board/sunxi/board.c b/board/sunxi/board.c +index 2163fac5e06..302a927f524 100644 +--- a/board/sunxi/board.c ++++ b/board/sunxi/board.c +@@ -13,10 +13,11 @@ + #include + #include + #include + #include + #include ++#include + #include + #include + #include + #include + #include +@@ -107,10 +108,21 @@ void i2c_init_board(void) + sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1); + clock_twi_onoff(1, 1); + #endif + #endif + ++#ifdef CONFIG_I2C3_ENABLE ++#if defined(CONFIG_MACH_SUN50I_H616) ++ sunxi_gpio_set_cfgpin(SUNXI_GPA(10), 2); ++ sunxi_gpio_set_cfgpin(SUNXI_GPA(11), 2); ++ sunxi_gpio_set_cfgpin(SUNXI_GPA(12), 2); ++ sunxi_gpio_set_pull(SUNXI_GPA(10), SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_pull(SUNXI_GPA(11), SUNXI_GPIO_PULL_UP); ++ clock_twi_onoff(3, 1); ++#endif ++#endif ++ + #ifdef CONFIG_R_I2C_ENABLE + #ifdef CONFIG_MACH_SUN50I + clock_twi_onoff(5, 1); + sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI); + sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI); +@@ -568,10 +580,11 @@ static void sunxi_spl_store_dram_size(phys_addr_t dram_size) + } + + void sunxi_board_init(void) + { + int power_failed = 0; ++ u8 data[2]; + + #ifdef CONFIG_LED_STATUS + if (IS_ENABLED(CONFIG_SPL_DRIVERS_MISC)) + status_led_init(); + #endif +@@ -658,10 +671,27 @@ void sunxi_board_init(void) + */ + if (!power_failed) + clock_set_pll1(get_board_sys_clk()); + else + printf("Failed to set core voltage! Can't set CPU frequency\n"); ++ ++ i2c_set_bus_num(1); ++ data[0] = 0; ++ data[1] = 1; ++ i2c_write(0x10, 0xfe, 1, data, 2); ++ i2c_write(0x10, 2, 1, data, 2); ++ data[1] = 1; ++ i2c_write(0x10, 2, 1, data, 2); ++ data[1] = 0xf; ++ i2c_write(0x10, 0x16, 1, data, 2); ++ data[1] = 3; ++ i2c_write(0x10, 0x14, 1, data, 2); ++ data[1] = 0x60; ++ i2c_write(0x10, 0xfe, 1, data, 2); ++ data[0] = 0x08; ++ data[1] = 0x14; ++ i2c_write(0x10, 0, 1, data, 2); + } + #endif /* CONFIG_SPL_BUILD */ + + #ifdef CONFIG_USB_GADGET + int g_dnl_board_usb_cable_connected(void) +diff --git a/configs/bigtreetech_cb1_defconfig b/configs/bigtreetech_cb1_defconfig +index d7b638e38a3..3dbd152c7c1 100644 +--- a/configs/bigtreetech_cb1_defconfig ++++ b/configs/bigtreetech_cb1_defconfig +@@ -15,14 +15,15 @@ CONFIG_SPL_MAX_SIZE=0xbfa0 + CONFIG_SPL_STACK=0x58000 + CONFIG_SPL_I2C=y + CONFIG_SPL_SYS_I2C_LEGACY=y + CONFIG_SYS_I2C_MVTWSI=y + CONFIG_SYS_I2C_SLAVE=0x7f +-CONFIG_SYS_I2C_SPEED=400000 ++CONFIG_SYS_I2C_SPEED=100000 + CONFIG_SPI_FLASH_MACRONIX=y +-CONFIG_NET=n + CONFIG_LED=y + CONFIG_LED_GPIO=y + CONFIG_SYS_PROMPT="CB1@uboot:~$ " + CONFIG_AXP313_POWER=y + CONFIG_MMC_SUNXI_SLOT_EXTRA=2 + CONFIG_MMC_BROKEN_CD=y ++CONFIG_SUN8I_EMAC=y ++CONFIG_I2C3_ENABLE=y +diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c +index a12f7e32e8f..98804029719 100644 +--- a/drivers/net/sun8i_emac.c ++++ b/drivers/net/sun8i_emac.c +@@ -904,10 +904,15 @@ static const struct emac_variant emac_variant_a64 = { + static const struct emac_variant emac_variant_h6 = { + .syscon_offset = 0x30, + .support_rmii = true, + }; + ++static const struct emac_variant emac_variant_h616_1 = { ++ .syscon_offset = 0x34, ++ .support_rmii = true, ++}; ++ + static const struct udevice_id sun8i_emac_eth_ids[] = { + { .compatible = "allwinner,sun8i-a83t-emac", + .data = (ulong)&emac_variant_a83t }, + { .compatible = "allwinner,sun8i-h3-emac", + .data = (ulong)&emac_variant_h3 }, +@@ -915,10 +920,12 @@ static const struct udevice_id sun8i_emac_eth_ids[] = { + .data = (ulong)&emac_variant_r40 }, + { .compatible = "allwinner,sun50i-a64-emac", + .data = (ulong)&emac_variant_a64 }, + { .compatible = "allwinner,sun50i-h6-emac", + .data = (ulong)&emac_variant_h6 }, ++ { .compatible = "allwinner,sun50i-h616-emac1", ++ .data = (ulong)&emac_variant_h616_1 }, + { } + }; + + U_BOOT_DRIVER(eth_sun8i_emac) = { + .name = "eth_sun8i_emac", +diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c +index 37ea93715d1..a9c3bf05702 100644 +--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c ++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c +@@ -735,10 +735,11 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = + .num_banks = 2, + }; + + static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { + { "emac0", 2 }, /* PI0-PI16 */ ++ { "emac1", 2 }, /* PA0-PA9 */ + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC0-PC16 */ +-- +Created with Armbian build tools https://github.com/armbian/build + From 55ab60f792151c66aa31a580e14fadf379bcda56 Mon Sep 17 00:00:00 2001 From: JohnTheCoolingFan Date: Fri, 9 Aug 2024 10:24:32 +0300 Subject: [PATCH 4/8] Rearrange BTT CB1 patches --- ...n50i-h616-enable-internal-phy-emac1.patch} | 91 +++---------------- .../bigtreetech-cb1-dts-add-deconfig.patch | 83 +++++++---------- 2 files changed, 46 insertions(+), 128 deletions(-) rename patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/{z-bigtreetech-cb1-PHY-EMAC1.patch => allwinner-sun50i-h616-enable-internal-phy-emac1.patch} (76%) diff --git a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/z-bigtreetech-cb1-PHY-EMAC1.patch b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-sun50i-h616-enable-internal-phy-emac1.patch similarity index 76% rename from patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/z-bigtreetech-cb1-PHY-EMAC1.patch rename to patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-sun50i-h616-enable-internal-phy-emac1.patch index 7b62d95ccd57..a867f8bd228d 100644 --- a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/z-bigtreetech-cb1-PHY-EMAC1.patch +++ b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-sun50i-h616-enable-internal-phy-emac1.patch @@ -1,67 +1,20 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: JohnTheCoolingFan -Date: Fri, 9 Aug 2024 06:13:19 +0000 -Subject: Add built-in H616 PHY support for bigtreetech cb1 +Date: Fri, 9 Aug 2024 07:14:37 +0000 +Subject: Enable H616 Internal PHY (emac1) Signed-off-by: JohnTheCoolingFan --- - arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts | 19 ++++++ - arch/arm/dts/sun50i-h616.dtsi | 27 +++++++++ - arch/arm/include/asm/arch-sunxi/i2c.h | 3 + - arch/arm/mach-sunxi/Kconfig | 9 +++ - arch/arm/mach-sunxi/board.c | 1 + - arch/arm/mach-sunxi/clock_sun50i_h6.c | 4 ++ - board/sunxi/board.c | 30 ++++++++++ - configs/bigtreetech_cb1_defconfig | 5 +- - drivers/net/sun8i_emac.c | 7 +++ - drivers/pinctrl/sunxi/pinctrl-sunxi.c | 1 + - 10 files changed, 104 insertions(+), 2 deletions(-) + arch/arm/dts/sun50i-h616.dtsi | 27 +++++++++ + arch/arm/include/asm/arch-sunxi/i2c.h | 3 + + arch/arm/mach-sunxi/Kconfig | 9 +++ + arch/arm/mach-sunxi/board.c | 1 + + arch/arm/mach-sunxi/clock_sun50i_h6.c | 4 ++ + board/sunxi/board.c | 30 ++++++++++ + drivers/net/sun8i_emac.c | 7 +++ + drivers/pinctrl/sunxi/pinctrl-sunxi.c | 1 + + 8 files changed, 82 insertions(+) -diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts -index dc0e04be947..acef7ef4f03 100644 ---- a/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts -+++ b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts -@@ -14,10 +14,11 @@ - / { - model = "BigTreeTech CB1"; - compatible = "bigtreetech,cb1", "allwinner,sun50i-h616"; - - aliases { -+ ethernet0 = &emac1; - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; -@@ -92,10 +93,28 @@ - reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */ - post-power-on-delay-ms = <200>; - }; - }; - -+&emac1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rmii_pins>; -+ phy-mode = "rmii"; -+ phy-handle = <&rmii_phy>; -+ phy-supply = <®_aldo1>; -+ allwinner,rx-delay-ps = <3100>; -+ allwinner,tx-delay-ps = <700>; -+ status = "okay"; -+}; -+ -+&mdio1 { -+ rmii_phy: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <1>; -+ }; -+}; -+ - &ehci1 { - status = "okay"; - }; - - &ohci1 { diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi index 46651703e9b..87d62cb1d3f 100644 --- a/arch/arm/dts/sun50i-h616.dtsi @@ -270,28 +223,6 @@ index 2163fac5e06..302a927f524 100644 #ifdef CONFIG_USB_GADGET int g_dnl_board_usb_cable_connected(void) -diff --git a/configs/bigtreetech_cb1_defconfig b/configs/bigtreetech_cb1_defconfig -index d7b638e38a3..3dbd152c7c1 100644 ---- a/configs/bigtreetech_cb1_defconfig -+++ b/configs/bigtreetech_cb1_defconfig -@@ -15,14 +15,15 @@ CONFIG_SPL_MAX_SIZE=0xbfa0 - CONFIG_SPL_STACK=0x58000 - CONFIG_SPL_I2C=y - CONFIG_SPL_SYS_I2C_LEGACY=y - CONFIG_SYS_I2C_MVTWSI=y - CONFIG_SYS_I2C_SLAVE=0x7f --CONFIG_SYS_I2C_SPEED=400000 -+CONFIG_SYS_I2C_SPEED=100000 - CONFIG_SPI_FLASH_MACRONIX=y --CONFIG_NET=n - CONFIG_LED=y - CONFIG_LED_GPIO=y - CONFIG_SYS_PROMPT="CB1@uboot:~$ " - CONFIG_AXP313_POWER=y - CONFIG_MMC_SUNXI_SLOT_EXTRA=2 - CONFIG_MMC_BROKEN_CD=y -+CONFIG_SUN8I_EMAC=y -+CONFIG_I2C3_ENABLE=y diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index a12f7e32e8f..98804029719 100644 --- a/drivers/net/sun8i_emac.c diff --git a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/bigtreetech-cb1-dts-add-deconfig.patch b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/bigtreetech-cb1-dts-add-deconfig.patch index ad8dd72b488c..673eee9a97c6 100644 --- a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/bigtreetech-cb1-dts-add-deconfig.patch +++ b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/bigtreetech-cb1-dts-add-deconfig.patch @@ -1,22 +1,20 @@ -From ca605c51044593c72587e589ac2be90e1aa34795 Mon Sep 17 00:00:00 2001 -From: Alan -Date: Fri, 19 May 2023 17:01:37 +0800 -Subject: [PATCH 06/11] Add: add BigTreeTech CB1 dts & deconfig files +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JohnTheCoolingFan +Date: Fri, 9 Aug 2024 07:23:02 +0000 +Subject: Add BigTreeTech CB1 device tree and defconfig +Signed-off-by: JohnTheCoolingFan --- - arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts | 219 +++++++++++++++++++ - arch/arm/dts/sun50i-h616.dtsi | 6 +- - configs/bigtreetech_cb1_defconfig | 28 +++ - 3 files changed, 250 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts - create mode 100644 configs/bigtreetech_cb1_defconfig + arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts | 238 ++++++++++ + configs/bigtreetech_cb1_defconfig | 29 ++ + 2 files changed, 267 insertions(+) diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts new file mode 100644 -index 0000000000..dc0e04be94 +index 00000000000..acef7ef4f03 --- /dev/null +++ b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dts -@@ -0,0 +1,219 @@ +@@ -0,0 +1,238 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (C) 2022 Arm Ltd. @@ -35,6 +33,7 @@ index 0000000000..dc0e04be94 + compatible = "bigtreetech,cb1", "allwinner,sun50i-h616"; + + aliases { ++ ethernet0 = &emac1; + serial0 = &uart0; + }; + @@ -113,6 +112,24 @@ index 0000000000..dc0e04be94 + }; +}; + ++&emac1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rmii_pins>; ++ phy-mode = "rmii"; ++ phy-handle = <&rmii_phy>; ++ phy-supply = <®_aldo1>; ++ allwinner,rx-delay-ps = <3100>; ++ allwinner,tx-delay-ps = <700>; ++ status = "okay"; ++}; ++ ++&mdio1 { ++ rmii_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ }; ++}; ++ +&ehci1 { + status = "okay"; +}; @@ -236,43 +253,12 @@ index 0000000000..dc0e04be94 + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; +}; -diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi -index 74aed0d232..46651703e9 100644 ---- a/arch/arm/dts/sun50i-h616.dtsi -+++ b/arch/arm/dts/sun50i-h616.dtsi -@@ -187,7 +187,7 @@ - pins = "PF0", "PF1", "PF2", "PF3", - "PF4", "PF5"; - function = "mmc0"; -- drive-strength = <30>; -+ drive-strength = <40>; - bias-pull-up; - }; - -@@ -196,7 +196,7 @@ - pins = "PG0", "PG1", "PG2", "PG3", - "PG4", "PG5"; - function = "mmc1"; -- drive-strength = <30>; -+ drive-strength = <40>; - bias-pull-up; - }; - -@@ -205,7 +205,7 @@ - "PC8", "PC9", "PC10", "PC11", - "PC13", "PC14", "PC15", "PC16"; - function = "mmc2"; -- drive-strength = <30>; -+ drive-strength = <40>; - bias-pull-up; - }; - diff --git a/configs/bigtreetech_cb1_defconfig b/configs/bigtreetech_cb1_defconfig new file mode 100644 -index 0000000000..96c5c17cff +index 00000000000..3dbd152c7c1 --- /dev/null +++ b/configs/bigtreetech_cb1_defconfig -@@ -0,0 +1,28 @@ +@@ -0,0 +1,29 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-bigtreetech-cb1" @@ -292,15 +278,16 @@ index 0000000000..96c5c17cff +CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_SYS_I2C_SLAVE=0x7f -+CONFIG_SYS_I2C_SPEED=400000 ++CONFIG_SYS_I2C_SPEED=100000 +CONFIG_SPI_FLASH_MACRONIX=y -+CONFIG_NET=n +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_SYS_PROMPT="CB1@uboot:~$ " +CONFIG_AXP313_POWER=y +CONFIG_MMC_SUNXI_SLOT_EXTRA=2 +CONFIG_MMC_BROKEN_CD=y ++CONFIG_SUN8I_EMAC=y ++CONFIG_I2C3_ENABLE=y -- -2.34.1 +Created with Armbian build tools https://github.com/armbian/build From a6453b10ede8ad0c84b21c81475044eeda912e64 Mon Sep 17 00:00:00 2001 From: JohnTheCoolingFan Date: Sun, 11 Aug 2024 14:28:16 +0300 Subject: [PATCH 5/8] Break the BigTreeTech Ethernet patches into 3 --- .../allwinner-h616-driver-i2c3.patch | 92 ++++++ ...r-h616-dts-enable-internal-phy-emac1.patch | 117 ++++++++ ...winner-h616-setup-internal-phy-emac1.patch | 93 ++++++ ...un50i-h616-enable-internal-phy-emac1.patch | 277 ------------------ 4 files changed, 302 insertions(+), 277 deletions(-) create mode 100644 patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-driver-i2c3.patch create mode 100644 patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-dts-enable-internal-phy-emac1.patch create mode 100644 patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-setup-internal-phy-emac1.patch delete mode 100644 patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-sun50i-h616-enable-internal-phy-emac1.patch diff --git a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-driver-i2c3.patch b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-driver-i2c3.patch new file mode 100644 index 000000000000..1ed1015e47b7 --- /dev/null +++ b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-driver-i2c3.patch @@ -0,0 +1,92 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JohnTheCoolingFan +Date: Fri, 9 Aug 2024 07:14:37 +0000 +Subject: Allwinner H616: driver: I2C3 + +Signed-off-by: JohnTheCoolingFan +--- + arch/arm/include/asm/arch-sunxi/i2c.h | 3 + + arch/arm/mach-sunxi/Kconfig | 9 +++ + board/sunxi/board.c | 12 +++++ + 3 files changed, 24 insertions(+) + +diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h +index f0da46d863c..98c26d7408e 100644 +--- a/arch/arm/include/asm/arch-sunxi/i2c.h ++++ b/arch/arm/include/asm/arch-sunxi/i2c.h +@@ -11,10 +11,13 @@ + #define CFG_I2C_MVTWSI_BASE0 SUNXI_TWI0_BASE + #endif + #ifdef CONFIG_I2C1_ENABLE + #define CFG_I2C_MVTWSI_BASE1 SUNXI_TWI1_BASE + #endif ++#ifdef CONFIG_I2C3_ENABLE ++#define CONFIG_I2C_MVTWSI_BASE3 SUNXI_TWI3_BASE ++#endif + #ifdef CONFIG_R_I2C_ENABLE + #define CFG_I2C_MVTWSI_BASE2 SUNXI_R_TWI_BASE + #endif + + /* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ +diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig +index d91faf9ab13..59cd48653c3 100644 +--- a/arch/arm/mach-sunxi/Kconfig ++++ b/arch/arm/mach-sunxi/Kconfig +@@ -807,10 +807,19 @@ config I2C1_ENABLE + bool "Enable I2C/TWI controller 1" + select CMD_I2C + ---help--- + See I2C0_ENABLE help text. + ++if MACH_SUN50I_H616 ++config I2C3_ENABLE ++ bool "Enable I2C/TWI controller 3" ++ default n ++ select CMD_I2C ++ ---help--- ++ See I2C0_ENABLE help text. ++endif ++ + if SUNXI_GEN_SUN6I || SUN50I_GEN_H6 + config R_I2C_ENABLE + bool "Enable the PRCM I2C/TWI controller" + # This is used for the pmic on H3 + default y if SY8106A_POWER +diff --git a/board/sunxi/board.c b/board/sunxi/board.c +index 2163fac5e06..302a927f524 100644 +--- a/board/sunxi/board.c ++++ b/board/sunxi/board.c +@@ -13,10 +13,11 @@ + #include + #include + #include + #include + #include ++#include + #include + #include + #include + #include + #include +@@ -107,10 +108,21 @@ void i2c_init_board(void) + sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1); + clock_twi_onoff(1, 1); + #endif + #endif + ++#ifdef CONFIG_I2C3_ENABLE ++#if defined(CONFIG_MACH_SUN50I_H616) ++ sunxi_gpio_set_cfgpin(SUNXI_GPA(10), 2); ++ sunxi_gpio_set_cfgpin(SUNXI_GPA(11), 2); ++ sunxi_gpio_set_cfgpin(SUNXI_GPA(12), 2); ++ sunxi_gpio_set_pull(SUNXI_GPA(10), SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_pull(SUNXI_GPA(11), SUNXI_GPIO_PULL_UP); ++ clock_twi_onoff(3, 1); ++#endif ++#endif ++ + #ifdef CONFIG_R_I2C_ENABLE + #ifdef CONFIG_MACH_SUN50I + clock_twi_onoff(5, 1); + sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI); + sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI); diff --git a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-dts-enable-internal-phy-emac1.patch b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-dts-enable-internal-phy-emac1.patch new file mode 100644 index 000000000000..91cb865d331d --- /dev/null +++ b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-dts-enable-internal-phy-emac1.patch @@ -0,0 +1,117 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JohnTheCoolingFan +Date: Fri, 9 Aug 2024 07:14:37 +0000 +Subject: Allwinner H616 DTS: Enable internal PHY (EMAC1) + +Signed-off-by: JohnTheCoolingFan +--- + arch/arm/dts/sun50i-h616.dtsi | 27 +++++++++ + drivers/net/sun8i_emac.c | 7 +++ + drivers/pinctrl/sunxi/pinctrl-sunxi.c | 1 + + 3 files changed, 35 insertions(+) + +diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi +index 46651703e9b..87d62cb1d3f 100644 +--- a/arch/arm/dts/sun50i-h616.dtsi ++++ b/arch/arm/dts/sun50i-h616.dtsi +@@ -207,10 +207,18 @@ + function = "mmc2"; + drive-strength = <40>; + bias-pull-up; + }; + ++ /omit-if-no-ref/ ++ rmii_pins: rmii-pins { ++ pins = "PA0", "PA1", "PA2", "PA3", "PA4", ++ "PA5", "PA6", "PA7", "PA8", "PA9"; ++ function = "emac1"; ++ drive-strength = <40>; ++ }; ++ + /omit-if-no-ref/ + spi0_pins: spi0-pins { + pins = "PC0", "PC2", "PC4"; + function = "spi0"; + }; +@@ -502,10 +510,29 @@ + #address-cells = <1>; + #size-cells = <0>; + }; + }; + ++ emac1: ethernet@5030000 { ++ compatible = "allwinner,sun50i-h616-emac1"; ++ syscon = <&syscon 1>; ++ reg = <0x05030000 0x10000>; ++ interrupts = ; ++ interrupt-names = "macirq"; ++ resets = <&ccu RST_BUS_EMAC1>; ++ reset-names = "stmmaceth"; ++ clocks = <&ccu CLK_BUS_EMAC1>; ++ clock-names = "stmmaceth"; ++ status = "disabled"; ++ ++ mdio1: mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ + usbotg: usb@5100000 { + compatible = "allwinner,sun50i-h616-musb", + "allwinner,sun8i-h3-musb"; + reg = <0x05100000 0x0400>; + clocks = <&ccu CLK_BUS_OTG>; +diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c +index a12f7e32e8f..98804029719 100644 +--- a/drivers/net/sun8i_emac.c ++++ b/drivers/net/sun8i_emac.c +@@ -904,10 +904,15 @@ static const struct emac_variant emac_variant_a64 = { + static const struct emac_variant emac_variant_h6 = { + .syscon_offset = 0x30, + .support_rmii = true, + }; + ++static const struct emac_variant emac_variant_h616_1 = { ++ .syscon_offset = 0x34, ++ .support_rmii = true, ++}; ++ + static const struct udevice_id sun8i_emac_eth_ids[] = { + { .compatible = "allwinner,sun8i-a83t-emac", + .data = (ulong)&emac_variant_a83t }, + { .compatible = "allwinner,sun8i-h3-emac", + .data = (ulong)&emac_variant_h3 }, +@@ -915,10 +920,12 @@ static const struct udevice_id sun8i_emac_eth_ids[] = { + .data = (ulong)&emac_variant_r40 }, + { .compatible = "allwinner,sun50i-a64-emac", + .data = (ulong)&emac_variant_a64 }, + { .compatible = "allwinner,sun50i-h6-emac", + .data = (ulong)&emac_variant_h6 }, ++ { .compatible = "allwinner,sun50i-h616-emac1", ++ .data = (ulong)&emac_variant_h616_1 }, + { } + }; + + U_BOOT_DRIVER(eth_sun8i_emac) = { + .name = "eth_sun8i_emac", +diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c +index 37ea93715d1..a9c3bf05702 100644 +--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c ++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c +@@ -735,10 +735,11 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = + .num_banks = 2, + }; + + static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { + { "emac0", 2 }, /* PI0-PI16 */ ++ { "emac1", 2 }, /* PA0-PA9 */ + { "gpio_in", 0 }, + { "gpio_out", 1 }, + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC0-PC16 */ +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-setup-internal-phy-emac1.patch b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-setup-internal-phy-emac1.patch new file mode 100644 index 000000000000..b9dfe8b12ab4 --- /dev/null +++ b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-h616-setup-internal-phy-emac1.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: JohnTheCoolingFan +Date: Fri, 9 Aug 2024 07:14:37 +0000 +Subject: Allwinner H616: Setup internal PHY (EMAC1) + +Signed-off-by: JohnTheCoolingFan +--- + arch/arm/mach-sunxi/board.c | 1 + + arch/arm/mach-sunxi/clock_sun50i_h6.c | 4 ++ + board/sunxi/board.c | 18 ++++++ + drivers/net/sun8i_emac.c | 7 +++ + drivers/pinctrl/sunxi/pinctrl-sunxi.c | 1 + + 8 files changed, 82 insertions(+) + +diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c +index 7d2d5d478fc..ca084bddda0 100644 +--- a/arch/arm/mach-sunxi/board.c ++++ b/arch/arm/mach-sunxi/board.c +@@ -479,10 +479,11 @@ void board_init_f(ulong dummy) + + #if CONFIG_IS_ENABLED(I2C) && CONFIG_IS_ENABLED(SYS_I2C_LEGACY) + /* Needed early by sunxi_board_init if PMU is enabled */ + i2c_init_board(); + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); ++ i2c_set_bus_num(0); + #endif + sunxi_board_init(); + } + #endif /* CONFIG_SPL_BUILD */ + +diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c +index 7f60b8c79fc..8c97ddb66c4 100644 +--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c ++++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c +@@ -51,10 +51,14 @@ void clock_init_safe(void) + /* + * The mux and factor are set, but the clock will be enabled in + * DRAM initialization code. + */ + writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), &ccm->mbus_cfg); ++ ++ writel(0x10001, 0x030017ac); ++ writel(0x50, 0x0300a028); ++ writel(0x20, 0x0300a040); + } + #endif + + void clock_init_uart(void) + { +diff --git a/board/sunxi/board.c b/board/sunxi/board.c +index 2163fac5e06..302a927f524 100644 +--- a/board/sunxi/board.c ++++ b/board/sunxi/board.c +@@ -568,10 +580,11 @@ static void sunxi_spl_store_dram_size(phys_addr_t dram_size) + } + + void sunxi_board_init(void) + { + int power_failed = 0; ++ u8 data[2]; + + #ifdef CONFIG_LED_STATUS + if (IS_ENABLED(CONFIG_SPL_DRIVERS_MISC)) + status_led_init(); + #endif +@@ -658,10 +671,27 @@ void sunxi_board_init(void) + */ + if (!power_failed) + clock_set_pll1(get_board_sys_clk()); + else + printf("Failed to set core voltage! Can't set CPU frequency\n"); ++ ++ i2c_set_bus_num(1); ++ data[0] = 0; ++ data[1] = 1; ++ i2c_write(0x10, 0xfe, 1, data, 2); ++ i2c_write(0x10, 2, 1, data, 2); ++ data[1] = 1; ++ i2c_write(0x10, 2, 1, data, 2); ++ data[1] = 0xf; ++ i2c_write(0x10, 0x16, 1, data, 2); ++ data[1] = 3; ++ i2c_write(0x10, 0x14, 1, data, 2); ++ data[1] = 0x60; ++ i2c_write(0x10, 0xfe, 1, data, 2); ++ data[0] = 0x08; ++ data[1] = 0x14; ++ i2c_write(0x10, 0, 1, data, 2); + } + #endif /* CONFIG_SPL_BUILD */ + + #ifdef CONFIG_USB_GADGET + int g_dnl_board_usb_cable_connected(void) diff --git a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-sun50i-h616-enable-internal-phy-emac1.patch b/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-sun50i-h616-enable-internal-phy-emac1.patch deleted file mode 100644 index a867f8bd228d..000000000000 --- a/patch/u-boot/u-boot-sunxi/board_bigtreetech-cb1/allwinner-sun50i-h616-enable-internal-phy-emac1.patch +++ /dev/null @@ -1,277 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: JohnTheCoolingFan -Date: Fri, 9 Aug 2024 07:14:37 +0000 -Subject: Enable H616 Internal PHY (emac1) - -Signed-off-by: JohnTheCoolingFan ---- - arch/arm/dts/sun50i-h616.dtsi | 27 +++++++++ - arch/arm/include/asm/arch-sunxi/i2c.h | 3 + - arch/arm/mach-sunxi/Kconfig | 9 +++ - arch/arm/mach-sunxi/board.c | 1 + - arch/arm/mach-sunxi/clock_sun50i_h6.c | 4 ++ - board/sunxi/board.c | 30 ++++++++++ - drivers/net/sun8i_emac.c | 7 +++ - drivers/pinctrl/sunxi/pinctrl-sunxi.c | 1 + - 8 files changed, 82 insertions(+) - -diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi -index 46651703e9b..87d62cb1d3f 100644 ---- a/arch/arm/dts/sun50i-h616.dtsi -+++ b/arch/arm/dts/sun50i-h616.dtsi -@@ -207,10 +207,18 @@ - function = "mmc2"; - drive-strength = <40>; - bias-pull-up; - }; - -+ /omit-if-no-ref/ -+ rmii_pins: rmii-pins { -+ pins = "PA0", "PA1", "PA2", "PA3", "PA4", -+ "PA5", "PA6", "PA7", "PA8", "PA9"; -+ function = "emac1"; -+ drive-strength = <40>; -+ }; -+ - /omit-if-no-ref/ - spi0_pins: spi0-pins { - pins = "PC0", "PC2", "PC4"; - function = "spi0"; - }; -@@ -502,10 +510,29 @@ - #address-cells = <1>; - #size-cells = <0>; - }; - }; - -+ emac1: ethernet@5030000 { -+ compatible = "allwinner,sun50i-h616-emac1"; -+ syscon = <&syscon 1>; -+ reg = <0x05030000 0x10000>; -+ interrupts = ; -+ interrupt-names = "macirq"; -+ resets = <&ccu RST_BUS_EMAC1>; -+ reset-names = "stmmaceth"; -+ clocks = <&ccu CLK_BUS_EMAC1>; -+ clock-names = "stmmaceth"; -+ status = "disabled"; -+ -+ mdio1: mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ - usbotg: usb@5100000 { - compatible = "allwinner,sun50i-h616-musb", - "allwinner,sun8i-h3-musb"; - reg = <0x05100000 0x0400>; - clocks = <&ccu CLK_BUS_OTG>; -diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h -index f0da46d863c..98c26d7408e 100644 ---- a/arch/arm/include/asm/arch-sunxi/i2c.h -+++ b/arch/arm/include/asm/arch-sunxi/i2c.h -@@ -11,10 +11,13 @@ - #define CFG_I2C_MVTWSI_BASE0 SUNXI_TWI0_BASE - #endif - #ifdef CONFIG_I2C1_ENABLE - #define CFG_I2C_MVTWSI_BASE1 SUNXI_TWI1_BASE - #endif -+#ifdef CONFIG_I2C3_ENABLE -+#define CONFIG_I2C_MVTWSI_BASE3 SUNXI_TWI3_BASE -+#endif - #ifdef CONFIG_R_I2C_ENABLE - #define CFG_I2C_MVTWSI_BASE2 SUNXI_R_TWI_BASE - #endif - - /* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ -diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig -index d91faf9ab13..59cd48653c3 100644 ---- a/arch/arm/mach-sunxi/Kconfig -+++ b/arch/arm/mach-sunxi/Kconfig -@@ -807,10 +807,19 @@ config I2C1_ENABLE - bool "Enable I2C/TWI controller 1" - select CMD_I2C - ---help--- - See I2C0_ENABLE help text. - -+if MACH_SUN50I_H616 -+config I2C3_ENABLE -+ bool "Enable I2C/TWI controller 3" -+ default n -+ select CMD_I2C -+ ---help--- -+ See I2C0_ENABLE help text. -+endif -+ - if SUNXI_GEN_SUN6I || SUN50I_GEN_H6 - config R_I2C_ENABLE - bool "Enable the PRCM I2C/TWI controller" - # This is used for the pmic on H3 - default y if SY8106A_POWER -diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c -index 7d2d5d478fc..ca084bddda0 100644 ---- a/arch/arm/mach-sunxi/board.c -+++ b/arch/arm/mach-sunxi/board.c -@@ -479,10 +479,11 @@ void board_init_f(ulong dummy) - - #if CONFIG_IS_ENABLED(I2C) && CONFIG_IS_ENABLED(SYS_I2C_LEGACY) - /* Needed early by sunxi_board_init if PMU is enabled */ - i2c_init_board(); - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); -+ i2c_set_bus_num(0); - #endif - sunxi_board_init(); - } - #endif /* CONFIG_SPL_BUILD */ - -diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c -index 7f60b8c79fc..8c97ddb66c4 100644 ---- a/arch/arm/mach-sunxi/clock_sun50i_h6.c -+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c -@@ -51,10 +51,14 @@ void clock_init_safe(void) - /* - * The mux and factor are set, but the clock will be enabled in - * DRAM initialization code. - */ - writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), &ccm->mbus_cfg); -+ -+ writel(0x10001, 0x030017ac); -+ writel(0x50, 0x0300a028); -+ writel(0x20, 0x0300a040); - } - #endif - - void clock_init_uart(void) - { -diff --git a/board/sunxi/board.c b/board/sunxi/board.c -index 2163fac5e06..302a927f524 100644 ---- a/board/sunxi/board.c -+++ b/board/sunxi/board.c -@@ -13,10 +13,11 @@ - #include - #include - #include - #include - #include -+#include - #include - #include - #include - #include - #include -@@ -107,10 +108,21 @@ void i2c_init_board(void) - sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1); - clock_twi_onoff(1, 1); - #endif - #endif - -+#ifdef CONFIG_I2C3_ENABLE -+#if defined(CONFIG_MACH_SUN50I_H616) -+ sunxi_gpio_set_cfgpin(SUNXI_GPA(10), 2); -+ sunxi_gpio_set_cfgpin(SUNXI_GPA(11), 2); -+ sunxi_gpio_set_cfgpin(SUNXI_GPA(12), 2); -+ sunxi_gpio_set_pull(SUNXI_GPA(10), SUNXI_GPIO_PULL_UP); -+ sunxi_gpio_set_pull(SUNXI_GPA(11), SUNXI_GPIO_PULL_UP); -+ clock_twi_onoff(3, 1); -+#endif -+#endif -+ - #ifdef CONFIG_R_I2C_ENABLE - #ifdef CONFIG_MACH_SUN50I - clock_twi_onoff(5, 1); - sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI); - sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI); -@@ -568,10 +580,11 @@ static void sunxi_spl_store_dram_size(phys_addr_t dram_size) - } - - void sunxi_board_init(void) - { - int power_failed = 0; -+ u8 data[2]; - - #ifdef CONFIG_LED_STATUS - if (IS_ENABLED(CONFIG_SPL_DRIVERS_MISC)) - status_led_init(); - #endif -@@ -658,10 +671,27 @@ void sunxi_board_init(void) - */ - if (!power_failed) - clock_set_pll1(get_board_sys_clk()); - else - printf("Failed to set core voltage! Can't set CPU frequency\n"); -+ -+ i2c_set_bus_num(1); -+ data[0] = 0; -+ data[1] = 1; -+ i2c_write(0x10, 0xfe, 1, data, 2); -+ i2c_write(0x10, 2, 1, data, 2); -+ data[1] = 1; -+ i2c_write(0x10, 2, 1, data, 2); -+ data[1] = 0xf; -+ i2c_write(0x10, 0x16, 1, data, 2); -+ data[1] = 3; -+ i2c_write(0x10, 0x14, 1, data, 2); -+ data[1] = 0x60; -+ i2c_write(0x10, 0xfe, 1, data, 2); -+ data[0] = 0x08; -+ data[1] = 0x14; -+ i2c_write(0x10, 0, 1, data, 2); - } - #endif /* CONFIG_SPL_BUILD */ - - #ifdef CONFIG_USB_GADGET - int g_dnl_board_usb_cable_connected(void) -diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c -index a12f7e32e8f..98804029719 100644 ---- a/drivers/net/sun8i_emac.c -+++ b/drivers/net/sun8i_emac.c -@@ -904,10 +904,15 @@ static const struct emac_variant emac_variant_a64 = { - static const struct emac_variant emac_variant_h6 = { - .syscon_offset = 0x30, - .support_rmii = true, - }; - -+static const struct emac_variant emac_variant_h616_1 = { -+ .syscon_offset = 0x34, -+ .support_rmii = true, -+}; -+ - static const struct udevice_id sun8i_emac_eth_ids[] = { - { .compatible = "allwinner,sun8i-a83t-emac", - .data = (ulong)&emac_variant_a83t }, - { .compatible = "allwinner,sun8i-h3-emac", - .data = (ulong)&emac_variant_h3 }, -@@ -915,10 +920,12 @@ static const struct udevice_id sun8i_emac_eth_ids[] = { - .data = (ulong)&emac_variant_r40 }, - { .compatible = "allwinner,sun50i-a64-emac", - .data = (ulong)&emac_variant_a64 }, - { .compatible = "allwinner,sun50i-h6-emac", - .data = (ulong)&emac_variant_h6 }, -+ { .compatible = "allwinner,sun50i-h616-emac1", -+ .data = (ulong)&emac_variant_h616_1 }, - { } - }; - - U_BOOT_DRIVER(eth_sun8i_emac) = { - .name = "eth_sun8i_emac", -diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c -index 37ea93715d1..a9c3bf05702 100644 ---- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c -+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c -@@ -735,10 +735,11 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = - .num_banks = 2, - }; - - static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { - { "emac0", 2 }, /* PI0-PI16 */ -+ { "emac1", 2 }, /* PA0-PA9 */ - { "gpio_in", 0 }, - { "gpio_out", 1 }, - { "mmc0", 2 }, /* PF0-PF5 */ - { "mmc1", 2 }, /* PG0-PG5 */ - { "mmc2", 3 }, /* PC0-PC16 */ --- -Created with Armbian build tools https://github.com/armbian/build - From b05228db6405fe49ac946aa42ec802ac08aa71c2 Mon Sep 17 00:00:00 2001 From: JohnTheCoolingFan Date: Fri, 9 Aug 2024 12:31:20 +0300 Subject: [PATCH 6/8] Remove sun50iw9-btt board family --- .../kernel/linux-sun50iw9-btt-legacy.config | 8515 ----- config/sources/families/sun50iw9-btt.conf | 65 - .../sun50iw9-btt-6.1/linux-6.1.43-44.patch | 2841 -- .../sun50iw9-btt-6.1/linux-6.1.44-45.patch | 5988 --- .../sun50iw9-btt-6.1/linux-6.1.45-46.patch | 6914 ---- .../sun50iw9-btt-6.1/linux-6.1.46-47.patch | 8047 ---- .../sun50iw9-btt-6.1/linux-6.1.47-48.patch | 604 - .../sun50iw9-btt-6.1/linux-6.1.48-49.patch | 292 - .../sun50iw9-btt-6.1/linux-6.1.49-50.patch | 31691 ---------------- .../sun50iw9-btt-6.1/linux-6.1.50-51.patch | 550 - .../sun50iw9-btt-6.1/linux-6.1.51-52.patch | 957 - .../sun50iw9-btt-6.1/linux-6.1.52-53.patch | 23057 ----------- .../sun50iw9-btt-6.1/linux-6.1.53-54.patch | 9258 ----- .../sun50iw9-btt-6.1/linux-6.1.54-55.patch | 6107 --- .../sun50iw9-btt-6.1/linux-6.1.55-56.patch | 11323 ------ .../sun50iw9-btt-6.1/linux-6.1.56-57.patch | 11235 ------ .../sun50iw9-btt-6.1/linux-6.1.57-58.patch | 389 - .../sun50iw9-btt-6.1/linux-6.1.58-59.patch | 4902 --- .../sun50iw9-btt-6.1/linux-6.1.59-60.patch | 7686 ---- .../sun50iw9-btt-6.1/linux-6.1.60-61.patch | 2922 -- .../sun50iw9-btt-6.1/linux-6.1.61-62.patch | 1798 - .../sun50iw9-btt-6.1/linux-6.1.62-63.patch | 22957 ----------- .../sun50iw9-btt-6.1/linux-6.1.63-64.patch | 12540 ------ .../sun50iw9-btt-6.1/linux-6.1.64-65.patch | 4244 --- .../sun50iw9-btt-6.1/linux-6.1.65-66.patch | 4837 --- .../sun50iw9-btt-6.1/linux-6.1.66-67.patch | 122 - .../sun50iw9-btt-6.1/linux-6.1.67-68.patch | 9166 ----- .../sun50iw9-btt-6.1/linux-6.1.68-69.patch | 4110 -- .../sun50iw9-btt-6.1/linux-6.1.69-70.patch | 5394 --- .../sun50iw9-btt-6.1/linux-6.1.70-71.patch | 7517 ---- .../sun50iw9-btt-6.1/linux-6.1.71-72.patch | 9332 ----- .../sun50iw9-btt-6.1/linux-6.1.72-73.patch | 294 - .../sun50iw9-btt-6.1/linux-6.1.73-74.patch | 3175 -- .../sun50iw9-btt-6.1/linux-6.1.74-75.patch | 15017 -------- .../sun50iw9-btt-6.1/linux-6.1.75-76.patch | 8801 ----- .../sun50iw9-btt-6.1/linux-6.1.76-77.patch | 10940 ------ .../sun50iw9-btt-6.1/linux-6.1.77-78.patch | 2252 -- .../sun50iw9-btt-6.1/linux-6.1.78-79.patch | 9468 ----- 38 files changed, 275307 deletions(-) delete mode 100644 config/kernel/linux-sun50iw9-btt-legacy.config delete mode 100644 config/sources/families/sun50iw9-btt.conf delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.43-44.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.44-45.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.45-46.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.46-47.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.47-48.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.48-49.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.49-50.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.50-51.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.51-52.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.52-53.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.53-54.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.54-55.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.55-56.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.56-57.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.57-58.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.58-59.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.59-60.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.60-61.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.61-62.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.62-63.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.63-64.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.64-65.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.65-66.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.66-67.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.67-68.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.68-69.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.69-70.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.70-71.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.71-72.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.72-73.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.73-74.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.74-75.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.75-76.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.76-77.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.77-78.patch delete mode 100644 patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.78-79.patch diff --git a/config/kernel/linux-sun50iw9-btt-legacy.config b/config/kernel/linux-sun50iw9-btt-legacy.config deleted file mode 100644 index 0b7c32ea59f0..000000000000 --- a/config/kernel/linux-sun50iw9-btt-legacy.config +++ /dev/null @@ -1,8515 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# Linux/arm64 6.1.79 Kernel Configuration -# -CONFIG_CC_VERSION_TEXT="aarch64-linux-gnu-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0" -CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=110400 -CONFIG_CLANG_VERSION=0 -CONFIG_AS_IS_GNU=y -CONFIG_AS_VERSION=23800 -CONFIG_LD_IS_BFD=y -CONFIG_LD_VERSION=23800 -CONFIG_LLD_VERSION=0 -CONFIG_CC_CAN_LINK=y -CONFIG_CC_CAN_LINK_STATIC=y -CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y -CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y -CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y -CONFIG_CC_HAS_ASM_INLINE=y -CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y -CONFIG_PAHOLE_VERSION=125 -CONFIG_IRQ_WORK=y -CONFIG_BUILDTIME_TABLE_SORT=y -CONFIG_THREAD_INFO_IN_TASK=y - -# -# General setup -# -CONFIG_INIT_ENV_ARG_LIMIT=32 -# CONFIG_COMPILE_TEST is not set -# CONFIG_WERROR is not set -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_BUILD_SALT="" -CONFIG_DEFAULT_INIT="" -CONFIG_DEFAULT_HOSTNAME="(none)" -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_SYSVIPC_COMPAT=y -CONFIG_POSIX_MQUEUE=y -CONFIG_POSIX_MQUEUE_SYSCTL=y -# CONFIG_WATCH_QUEUE is not set -CONFIG_CROSS_MEMORY_ATTACH=y -# CONFIG_USELIB is not set -CONFIG_AUDIT=y -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_AUDITSYSCALL=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_SIM=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y -CONFIG_GENERIC_IRQ_IPI=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_IRQ_MSI_IOMMU=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_SPARSE_IRQ=y -# CONFIG_GENERIC_IRQ_DEBUGFS is not set -# end of IRQ subsystem - -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y -CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y -CONFIG_CONTEXT_TRACKING=y -CONFIG_CONTEXT_TRACKING_IDLE=y - -# -# Timers subsystem -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ_COMMON=y -# CONFIG_HZ_PERIODIC is not set -CONFIG_NO_HZ_IDLE=y -# CONFIG_NO_HZ_FULL is not set -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -# end of Timers subsystem - -CONFIG_BPF=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y - -# -# BPF subsystem -# -CONFIG_BPF_SYSCALL=y -CONFIG_BPF_JIT=y -# CONFIG_BPF_JIT_ALWAYS_ON is not set -CONFIG_BPF_JIT_DEFAULT_ON=y -# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set -CONFIG_USERMODE_DRIVER=y -# CONFIG_BPF_PRELOAD is not set -# end of BPF subsystem - -CONFIG_PREEMPT_NONE_BUILD=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -# CONFIG_PREEMPT_DYNAMIC is not set - -# -# CPU/Task time and stats accounting -# -CONFIG_TICK_CPU_ACCOUNTING=y -# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -# CONFIG_IRQ_TIME_ACCOUNTING is not set -CONFIG_SCHED_THERMAL_PRESSURE=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_PSI=y -# CONFIG_PSI_DEFAULT_DISABLED is not set -# end of CPU/Task time and stats accounting - -CONFIG_CPU_ISOLATION=y - -# -# RCU Subsystem -# -CONFIG_TREE_RCU=y -# CONFIG_RCU_EXPERT is not set -CONFIG_SRCU=y -CONFIG_TREE_SRCU=y -CONFIG_TASKS_RCU_GENERIC=y -CONFIG_TASKS_TRACE_RCU=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_RCU_NEED_SEGCBLIST=y -# end of RCU Subsystem - -CONFIG_BUILD_BIN2C=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_IKHEADERS=m -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 -# CONFIG_PRINTK_INDEX is not set -CONFIG_GENERIC_SCHED_CLOCK=y - -# -# Scheduler features -# -# CONFIG_UCLAMP_TASK is not set -# end of Scheduler features - -CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y -CONFIG_CC_HAS_INT128=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_GCC11_NO_ARRAY_BOUNDS=y -CONFIG_CC_NO_ARRAY_BOUNDS=y -CONFIG_ARCH_SUPPORTS_INT128=y -# CONFIG_NUMA_BALANCING is not set -CONFIG_CGROUPS=y -CONFIG_PAGE_COUNTER=y -# CONFIG_CGROUP_FAVOR_DYNMODS is not set -CONFIG_MEMCG=y -CONFIG_MEMCG_KMEM=y -CONFIG_BLK_CGROUP=y -CONFIG_CGROUP_WRITEBACK=y -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_CFS_BANDWIDTH=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_CGROUP_PIDS=y -CONFIG_CGROUP_RDMA=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_HUGETLB=y -CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_BPF=y -# CONFIG_CGROUP_MISC is not set -CONFIG_SOCK_CGROUP_DATA=y -CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_TIME_NS=y -CONFIG_IPC_NS=y -CONFIG_USER_NS=y -CONFIG_PID_NS=y -CONFIG_NET_NS=y -# CONFIG_CHECKPOINT_RESTORE is not set -# CONFIG_SCHED_AUTOGROUP is not set -# CONFIG_SYSFS_DEPRECATED is not set -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y -CONFIG_RD_LZ4=y -CONFIG_RD_ZSTD=y -# CONFIG_BOOT_CONFIG is not set -CONFIG_INITRAMFS_PRESERVE_MTIME=y -CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_LD_ORPHAN_WARN=y -CONFIG_SYSCTL=y -CONFIG_HAVE_UID16=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -# CONFIG_EXPERT is not set -CONFIG_UID16=y -CONFIG_MULTIUSER=y -CONFIG_SYSFS_SYSCALL=y -CONFIG_FHANDLE=y -CONFIG_POSIX_TIMERS=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_FUTEX_PI=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_IO_URING=y -CONFIG_ADVISE_SYSCALLS=y -CONFIG_MEMBARRIER=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_BASE_RELATIVE=y -CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_KCMP=y -CONFIG_RSEQ=y -# CONFIG_EMBEDDED is not set -CONFIG_HAVE_PERF_EVENTS=y - -# -# Kernel Performance Events And Counters -# -CONFIG_PERF_EVENTS=y -# end of Kernel Performance Events And Counters - -CONFIG_SYSTEM_DATA_VERIFICATION=y -# CONFIG_PROFILING is not set -# end of General setup - -CONFIG_ARM64=y -CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_64BIT=y -CONFIG_MMU=y -CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_CONT_PTE_SHIFT=4 -CONFIG_ARM64_CONT_PMD_SHIFT=4 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=33 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 -CONFIG_NO_IOPORT_MAP=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y -CONFIG_SMP=y -CONFIG_KERNEL_MODE_NEON=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_PGTABLE_LEVELS=4 -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_PROC_KCORE_TEXT=y - -# -# Platform selection -# -# CONFIG_ARCH_ACTIONS is not set -CONFIG_ARCH_SUNXI=y -# CONFIG_ARCH_ALPINE is not set -# CONFIG_ARCH_APPLE is not set -# CONFIG_ARCH_BCM is not set -# CONFIG_ARCH_BERLIN is not set -# CONFIG_ARCH_BITMAIN is not set -# CONFIG_ARCH_EXYNOS is not set -# CONFIG_ARCH_SPARX5 is not set -# CONFIG_ARCH_K3 is not set -# CONFIG_ARCH_LG1K is not set -# CONFIG_ARCH_HISI is not set -# CONFIG_ARCH_KEEMBAY is not set -# CONFIG_ARCH_MEDIATEK is not set -# CONFIG_ARCH_MESON is not set -# CONFIG_ARCH_MVEBU is not set -# CONFIG_ARCH_NXP is not set -# CONFIG_ARCH_NPCM is not set -# CONFIG_ARCH_QCOM is not set -# CONFIG_ARCH_REALTEK is not set -# CONFIG_ARCH_RENESAS is not set -# CONFIG_ARCH_ROCKCHIP is not set -# CONFIG_ARCH_SEATTLE is not set -# CONFIG_ARCH_INTEL_SOCFPGA is not set -# CONFIG_ARCH_SYNQUACER is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_SPRD is not set -# CONFIG_ARCH_THUNDER is not set -# CONFIG_ARCH_THUNDER2 is not set -# CONFIG_ARCH_UNIPHIER is not set -# CONFIG_ARCH_VEXPRESS is not set -# CONFIG_ARCH_VISCONTI is not set -# CONFIG_ARCH_XGENE is not set -# CONFIG_ARCH_ZYNQMP is not set -# end of Platform selection - -# -# Kernel Features -# - -# -# ARM errata workarounds via the alternatives framework -# -CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y -CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_819472=y -# CONFIG_ARM64_ERRATUM_832075 is not set -CONFIG_ARM64_ERRATUM_1742098=y -CONFIG_ARM64_ERRATUM_845719=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y -CONFIG_ARM64_ERRATUM_1024718=y -CONFIG_ARM64_ERRATUM_1418040=y -CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y -CONFIG_ARM64_ERRATUM_1165522=y -CONFIG_ARM64_ERRATUM_1319367=y -CONFIG_ARM64_ERRATUM_1530923=y -CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y -CONFIG_ARM64_ERRATUM_2441007=y -CONFIG_ARM64_ERRATUM_1286807=y -CONFIG_ARM64_ERRATUM_1463225=y -CONFIG_ARM64_ERRATUM_1542419=y -CONFIG_ARM64_ERRATUM_1508412=y -CONFIG_ARM64_ERRATUM_2051678=y -CONFIG_ARM64_ERRATUM_2077057=y -CONFIG_ARM64_ERRATUM_2658417=y -CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y -CONFIG_ARM64_ERRATUM_2054223=y -CONFIG_ARM64_ERRATUM_2067961=y -CONFIG_ARM64_ERRATUM_2441009=y -CONFIG_ARM64_ERRATUM_2457168=y -CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD=y -CONFIG_ARM64_ERRATUM_2966298=y -# CONFIG_CAVIUM_ERRATUM_22375 is not set -CONFIG_CAVIUM_ERRATUM_23144=y -# CONFIG_CAVIUM_ERRATUM_23154 is not set -# CONFIG_CAVIUM_ERRATUM_27456 is not set -# CONFIG_CAVIUM_ERRATUM_30115 is not set -CONFIG_CAVIUM_TX2_ERRATUM_219=y -CONFIG_FUJITSU_ERRATUM_010001=y -CONFIG_HISILICON_ERRATUM_161600802=y -# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set -# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set -# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set -CONFIG_QCOM_FALKOR_ERRATUM_E1041=y -CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y -CONFIG_SOCIONEXT_SYNQUACER_PREITS=y -# end of ARM errata workarounds via the alternatives framework - -CONFIG_ARM64_4K_PAGES=y -# CONFIG_ARM64_16K_PAGES is not set -# CONFIG_ARM64_64K_PAGES is not set -# CONFIG_ARM64_VA_BITS_39 is not set -CONFIG_ARM64_VA_BITS_48=y -CONFIG_ARM64_VA_BITS=48 -CONFIG_ARM64_PA_BITS_48=y -CONFIG_ARM64_PA_BITS=48 -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_CLUSTER=y -# CONFIG_SCHED_SMT is not set -CONFIG_NR_CPUS=8 -CONFIG_HOTPLUG_CPU=y -CONFIG_NUMA=y -CONFIG_NODES_SHIFT=2 -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_SCHED_HRTICK=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_HW_PERF_EVENTS=y -CONFIG_PARAVIRT=y -# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -# CONFIG_KEXEC is not set -# CONFIG_KEXEC_FILE is not set -# CONFIG_CRASH_DUMP is not set -# CONFIG_XEN is not set -CONFIG_ARCH_FORCE_MAX_ORDER=11 -CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y -CONFIG_RODATA_FULL_DEFAULT_ENABLED=y -# CONFIG_ARM64_SW_TTBR0_PAN is not set -CONFIG_ARM64_TAGGED_ADDR_ABI=y -CONFIG_COMPAT=y -CONFIG_KUSER_HELPERS=y -# CONFIG_COMPAT_ALIGNMENT_FIXUPS is not set -CONFIG_ARMV8_DEPRECATED=y -CONFIG_SWP_EMULATION=y -CONFIG_CP15_BARRIER_EMULATION=y -CONFIG_SETEND_EMULATION=y - -# -# ARMv8.1 architectural features -# -CONFIG_ARM64_HW_AFDBM=y -CONFIG_ARM64_PAN=y -CONFIG_AS_HAS_LDAPR=y -CONFIG_AS_HAS_LSE_ATOMICS=y -CONFIG_ARM64_LSE_ATOMICS=y -CONFIG_ARM64_USE_LSE_ATOMICS=y -# end of ARMv8.1 architectural features - -# -# ARMv8.2 architectural features -# -CONFIG_AS_HAS_ARMV8_2=y -CONFIG_AS_HAS_SHA3=y -# CONFIG_ARM64_PMEM is not set -CONFIG_ARM64_RAS_EXTN=y -CONFIG_ARM64_CNP=y -# end of ARMv8.2 architectural features - -# -# ARMv8.3 architectural features -# -CONFIG_ARM64_PTR_AUTH=y -CONFIG_ARM64_PTR_AUTH_KERNEL=y -CONFIG_CC_HAS_BRANCH_PROT_PAC_RET=y -CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y -CONFIG_AS_HAS_PAC=y -CONFIG_AS_HAS_CFI_NEGATE_RA_STATE=y -# end of ARMv8.3 architectural features - -# -# ARMv8.4 architectural features -# -CONFIG_ARM64_AMU_EXTN=y -CONFIG_AS_HAS_ARMV8_4=y -CONFIG_ARM64_TLB_RANGE=y -# end of ARMv8.4 architectural features - -# -# ARMv8.5 architectural features -# -CONFIG_AS_HAS_ARMV8_5=y -CONFIG_ARM64_BTI=y -CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI=y -CONFIG_ARM64_E0PD=y -CONFIG_ARM64_AS_HAS_MTE=y -CONFIG_ARM64_MTE=y -# end of ARMv8.5 architectural features - -# -# ARMv8.7 architectural features -# -CONFIG_ARM64_EPAN=y -# end of ARMv8.7 architectural features - -CONFIG_ARM64_SVE=y -CONFIG_ARM64_SME=y -CONFIG_ARM64_MODULE_PLTS=y -# CONFIG_ARM64_PSEUDO_NMI is not set -CONFIG_RELOCATABLE=y -CONFIG_RANDOMIZE_BASE=y -CONFIG_RANDOMIZE_MODULE_REGION_FULL=y -CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_STACKPROTECTOR_PER_TASK=y -CONFIG_ARCH_NR_GPIO=0 -# end of Kernel Features - -# -# Boot options -# -CONFIG_CMDLINE="" -# CONFIG_EFI is not set -# end of Boot options - -# -# Power management options -# -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -# CONFIG_HIBERNATION is not set -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -# CONFIG_PM_AUTOSLEEP is not set -# CONFIG_PM_USERSPACE_AUTOSLEEP is not set -# CONFIG_PM_WAKELOCKS is not set -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_CLK=y -CONFIG_PM_GENERIC_DOMAINS=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_CPU_PM=y -# CONFIG_ENERGY_MODEL is not set -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -# end of Power management options - -# -# CPU Power Management -# - -# -# CPU Idle -# -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y -# CONFIG_CPU_IDLE_GOV_LADDER is not set -CONFIG_CPU_IDLE_GOV_MENU=y -# CONFIG_CPU_IDLE_GOV_TEO is not set -CONFIG_DT_IDLE_STATES=y -CONFIG_DT_IDLE_GENPD=y - -# -# ARM CPU Idle Drivers -# -CONFIG_ARM_PSCI_CPUIDLE=y -CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y -# end of ARM CPU Idle Drivers -# end of CPU Idle - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y - -# -# CPU frequency scaling drivers -# -CONFIG_CPUFREQ_DT=m -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=y -CONFIG_ARM_SCPI_CPUFREQ=m -# CONFIG_ARM_SCMI_CPUFREQ is not set -# end of CPU Frequency scaling -# end of CPU Power Management - -CONFIG_HAVE_KVM=y -# CONFIG_VIRTUALIZATION is not set - -# -# General architecture-dependent options -# -CONFIG_CRASH_CORE=y -CONFIG_ARCH_HAS_SUBPAGE_FAULTS=y -CONFIG_KPROBES=y -CONFIG_JUMP_LABEL=y -# CONFIG_STATIC_KEYS_SELFTEST is not set -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_KRETPROBES=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y -CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y -CONFIG_HAVE_NMI=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_KEEPINITRD=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SET_DIRECT_MAP=y -CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -CONFIG_ARCH_WANTS_NO_INSTR=y -CONFIG_HAVE_ASM_MODVERSIONS=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y -CONFIG_HAVE_HW_BREAKPOINT=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y -CONFIG_MMU_GATHER_TABLE_FREE=y -CONFIG_MMU_GATHER_RCU_TABLE_FREE=y -CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y -CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y -CONFIG_HAVE_CMPXCHG_LOCAL=y -CONFIG_HAVE_CMPXCHG_DOUBLE=y -CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y -CONFIG_HAVE_ARCH_SECCOMP=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_SECCOMP=y -CONFIG_SECCOMP_FILTER=y -# CONFIG_SECCOMP_CACHE_DEBUG is not set -CONFIG_HAVE_ARCH_STACKLEAK=y -CONFIG_HAVE_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR_STRONG=y -CONFIG_ARCH_SUPPORTS_LTO_CLANG=y -CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y -CONFIG_LTO_NONE=y -CONFIG_ARCH_SUPPORTS_CFI_CLANG=y -CONFIG_HAVE_CONTEXT_TRACKING_USER=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MOVE_PUD=y -CONFIG_HAVE_MOVE_PMD=y -CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -CONFIG_HAVE_ARCH_HUGE_VMAP=y -CONFIG_HAVE_ARCH_HUGE_VMALLOC=y -CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y -CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_COMPAT_OLD_SIGACTION=y -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_HAVE_ARCH_VMAP_STACK=y -CONFIG_VMAP_STACK=y -CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y -CONFIG_RANDOMIZE_KSTACK_OFFSET=y -# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_STRICT_MODULE_RWX=y -CONFIG_HAVE_ARCH_COMPILER_H=y -CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y -# CONFIG_LOCK_EVENT_COUNTS is not set -CONFIG_ARCH_HAS_RELR=y -CONFIG_HAVE_PREEMPT_DYNAMIC=y -CONFIG_HAVE_PREEMPT_DYNAMIC_KEY=y -CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y -CONFIG_ARCH_HAVE_TRACE_MMIO_ACCESS=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -# end of GCOV-based kernel profiling - -CONFIG_HAVE_GCC_PLUGINS=y -# end of General architecture-dependent options - -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_MODULE_SIG is not set -CONFIG_MODULE_COMPRESS_NONE=y -# CONFIG_MODULE_COMPRESS_GZIP is not set -# CONFIG_MODULE_COMPRESS_XZ is not set -# CONFIG_MODULE_COMPRESS_ZSTD is not set -# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set -CONFIG_MODPROBE_PATH="/sbin/modprobe" -CONFIG_MODULES_TREE_LOOKUP=y -CONFIG_BLOCK=y -CONFIG_BLOCK_LEGACY_AUTOLOAD=y -CONFIG_BLK_CGROUP_RWSTAT=y -CONFIG_BLK_DEV_BSG_COMMON=y -CONFIG_BLK_ICQ=y -CONFIG_BLK_DEV_BSGLIB=y -CONFIG_BLK_DEV_INTEGRITY=y -CONFIG_BLK_DEV_INTEGRITY_T10=y -CONFIG_BLK_DEV_ZONED=y -CONFIG_BLK_DEV_THROTTLING=y -# CONFIG_BLK_DEV_THROTTLING_LOW is not set -CONFIG_BLK_WBT=y -CONFIG_BLK_WBT_MQ=y -# CONFIG_BLK_CGROUP_IOLATENCY is not set -# CONFIG_BLK_CGROUP_IOCOST is not set -CONFIG_BLK_CGROUP_IOPRIO=y -# CONFIG_BLK_DEBUG_FS is not set -# CONFIG_BLK_SED_OPAL is not set -# CONFIG_BLK_INLINE_ENCRYPTION is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_EFI_PARTITION=y -# end of Partition Types - -CONFIG_BLOCK_COMPAT=y -CONFIG_BLK_MQ_VIRTIO=y -CONFIG_BLK_PM=y -CONFIG_BLOCK_HOLDER_DEPRECATED=y -CONFIG_BLK_MQ_STACKING=y - -# -# IO Schedulers -# -CONFIG_MQ_IOSCHED_DEADLINE=y -CONFIG_MQ_IOSCHED_KYBER=y -CONFIG_IOSCHED_BFQ=y -CONFIG_BFQ_GROUP_IOSCHED=y -# CONFIG_BFQ_CGROUP_DEBUG is not set -# end of IO Schedulers - -CONFIG_PADATA=y -CONFIG_ASN1=y -CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y -CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_LOCK=y -CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y -CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_INLINE_READ_LOCK=y -CONFIG_ARCH_INLINE_READ_LOCK_BH=y -CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y -CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_READ_UNLOCK=y -CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y -CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_INLINE_WRITE_LOCK=y -CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y -CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y -CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_SPIN_TRYLOCK=y -CONFIG_INLINE_SPIN_TRYLOCK_BH=y -CONFIG_INLINE_SPIN_LOCK=y -CONFIG_INLINE_SPIN_LOCK_BH=y -CONFIG_INLINE_SPIN_LOCK_IRQ=y -CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y -CONFIG_INLINE_SPIN_UNLOCK_BH=y -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_READ_LOCK=y -CONFIG_INLINE_READ_LOCK_BH=y -CONFIG_INLINE_READ_LOCK_IRQ=y -CONFIG_INLINE_READ_LOCK_IRQSAVE=y -CONFIG_INLINE_READ_UNLOCK=y -CONFIG_INLINE_READ_UNLOCK_BH=y -CONFIG_INLINE_READ_UNLOCK_IRQ=y -CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_WRITE_LOCK=y -CONFIG_INLINE_WRITE_LOCK_BH=y -CONFIG_INLINE_WRITE_LOCK_IRQ=y -CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y -CONFIG_INLINE_WRITE_UNLOCK=y -CONFIG_INLINE_WRITE_UNLOCK_BH=y -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_ARCH_USE_QUEUED_RWLOCKS=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y -CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y -CONFIG_FREEZER=y - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -CONFIG_COMPAT_BINFMT_ELF=y -CONFIG_ARCH_BINFMT_ELF_STATE=y -CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y -CONFIG_ARCH_HAVE_ELF_PROT=y -CONFIG_ARCH_USE_GNU_PROPERTY=y -CONFIG_ELFCORE=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_BINFMT_SCRIPT=y -CONFIG_BINFMT_MISC=m -CONFIG_COREDUMP=y -# end of Executable file formats - -# -# Memory Management options -# -CONFIG_ZPOOL=y -CONFIG_SWAP=y -CONFIG_ZSWAP=y -CONFIG_ZSWAP_DEFAULT_ON=y -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set -# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set -CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y -CONFIG_ZSWAP_COMPRESSOR_DEFAULT="zstd" -# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD is not set -CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD=y -# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set -CONFIG_ZSWAP_ZPOOL_DEFAULT="z3fold" -CONFIG_ZBUD=y -CONFIG_Z3FOLD=y -CONFIG_ZSMALLOC=y -# CONFIG_ZSMALLOC_STAT is not set - -# -# SLAB allocator options -# -# CONFIG_SLAB is not set -CONFIG_SLUB=y -CONFIG_SLAB_MERGE_DEFAULT=y -# CONFIG_SLAB_FREELIST_RANDOM is not set -# CONFIG_SLAB_FREELIST_HARDENED is not set -# CONFIG_SLUB_STATS is not set -CONFIG_SLUB_CPU_PARTIAL=y -# end of SLAB allocator options - -# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_HAVE_FAST_GUP=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y -# CONFIG_MEMORY_HOTPLUG is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y -CONFIG_MEMORY_BALLOON=y -CONFIG_BALLOON_COMPACTION=y -CONFIG_COMPACTION=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -CONFIG_PAGE_REPORTING=y -CONFIG_MIGRATION=y -CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y -CONFIG_ARCH_ENABLE_THP_MIGRATION=y -CONFIG_CONTIG_ALLOC=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_KSM=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -# CONFIG_MEMORY_FAILURE is not set -CONFIG_ARCH_WANTS_THP_SWAP=y -CONFIG_TRANSPARENT_HUGEPAGE=y -# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set -CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y -CONFIG_THP_SWAP=y -# CONFIG_READ_ONLY_THP_FOR_FS is not set -CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y -CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y -CONFIG_USE_PERCPU_NUMA_NODE_ID=y -CONFIG_HAVE_SETUP_PER_CPU_AREA=y -CONFIG_FRONTSWAP=y -CONFIG_CMA=y -# CONFIG_CMA_DEBUGFS is not set -# CONFIG_CMA_SYSFS is not set -CONFIG_CMA_AREAS=7 -CONFIG_GENERIC_EARLY_IOREMAP=y -# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set -CONFIG_PAGE_IDLE_FLAG=y -CONFIG_IDLE_PAGE_TRACKING=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y -CONFIG_ARCH_HAS_PTE_DEVMAP=y -CONFIG_ZONE_DMA=y -CONFIG_ZONE_DMA32=y -CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PERCPU_STATS=y -# CONFIG_GUP_TEST is not set -CONFIG_ARCH_HAS_PTE_SPECIAL=y -CONFIG_SECRETMEM=y -# CONFIG_ANON_VMA_NAME is not set -# CONFIG_USERFAULTFD is not set -# CONFIG_LRU_GEN is not set -CONFIG_LOCK_MM_AND_FIND_VMA=y - -# -# Data Access Monitoring -# -# CONFIG_DAMON is not set -# end of Data Access Monitoring -# end of Memory Management options - -CONFIG_NET=y -CONFIG_COMPAT_NETLINK_MESSAGES=y -CONFIG_NET_INGRESS=y -CONFIG_NET_EGRESS=y -CONFIG_NET_REDIRECT=y -CONFIG_SKB_EXTENSIONS=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_DIAG=m -CONFIG_UNIX=y -CONFIG_UNIX_SCM=y -CONFIG_AF_UNIX_OOB=y -CONFIG_UNIX_DIAG=m -CONFIG_TLS=y -# CONFIG_TLS_DEVICE is not set -# CONFIG_TLS_TOE is not set -CONFIG_XFRM=y -CONFIG_XFRM_OFFLOAD=y -CONFIG_XFRM_ALGO=m -CONFIG_XFRM_USER=m -CONFIG_XFRM_INTERFACE=m -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_XFRM_AH=m -CONFIG_XFRM_ESP=m -CONFIG_XFRM_IPCOMP=m -CONFIG_NET_KEY=m -# CONFIG_NET_KEY_MIGRATE is not set -# CONFIG_XDP_SOCKETS is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_FIB_TRIE_STATS=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_CLASSID=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IP_TUNNEL=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE_COMMON=y -CONFIG_IP_MROUTE=y -CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_SYN_COOKIES=y -CONFIG_NET_IPVTI=m -CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_ESP_OFFLOAD=m -# CONFIG_INET_ESPINTCP is not set -CONFIG_INET_IPCOMP=m -CONFIG_INET_TABLE_PERTURB_ORDER=16 -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m -CONFIG_INET_UDP_DIAG=m -CONFIG_INET_RAW_DIAG=m -# CONFIG_INET_DIAG_DESTROY is not set -CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=m -CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -CONFIG_TCP_CONG_HSTCP=m -CONFIG_TCP_CONG_HYBLA=m -CONFIG_TCP_CONG_VEGAS=m -CONFIG_TCP_CONG_NV=m -CONFIG_TCP_CONG_SCALABLE=m -CONFIG_TCP_CONG_LP=m -CONFIG_TCP_CONG_VENO=m -CONFIG_TCP_CONG_YEAH=m -CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_TCP_CONG_DCTCP=m -CONFIG_TCP_CONG_CDG=m -CONFIG_TCP_CONG_BBR=m -CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -CONFIG_IPV6=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_ESP_OFFLOAD=m -# CONFIG_INET6_ESPINTCP is not set -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=m -# CONFIG_IPV6_ILA is not set -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_IPV6_VTI=m -CONFIG_IPV6_SIT=m -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=m -CONFIG_IPV6_GRE=m -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_IPV6_MROUTE=y -# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set -# CONFIG_IPV6_PIMSM_V2 is not set -CONFIG_IPV6_SEG6_LWTUNNEL=y -CONFIG_IPV6_SEG6_HMAC=y -CONFIG_IPV6_SEG6_BPF=y -# CONFIG_IPV6_RPL_LWTUNNEL is not set -# CONFIG_IPV6_IOAM6_LWTUNNEL is not set -CONFIG_NETLABEL=y -# CONFIG_MPTCP is not set -CONFIG_NETWORK_SECMARK=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NETWORK_PHY_TIMESTAMPING=y -CONFIG_NETFILTER=y -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=m - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_INGRESS=y -CONFIG_NETFILTER_EGRESS=y -CONFIG_NETFILTER_SKIP_EGRESS=y -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_FAMILY_BRIDGE=y -CONFIG_NETFILTER_FAMILY_ARP=y -CONFIG_NETFILTER_NETLINK_HOOK=m -CONFIG_NETFILTER_NETLINK_ACCT=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NETFILTER_NETLINK_OSF=m -CONFIG_NF_CONNTRACK=m -CONFIG_NF_LOG_SYSLOG=m -CONFIG_NETFILTER_CONNCOUNT=m -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_ZONES=y -# CONFIG_NF_CONNTRACK_PROCFS is not set -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_TIMEOUT=y -CONFIG_NF_CONNTRACK_TIMESTAMP=y -CONFIG_NF_CONNTRACK_LABELS=y -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=y -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_BROADCAST=m -CONFIG_NF_CONNTRACK_NETBIOS_NS=m -CONFIG_NF_CONNTRACK_SNMP=m -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NF_CT_NETLINK_TIMEOUT=m -CONFIG_NF_CT_NETLINK_HELPER=m -CONFIG_NETFILTER_NETLINK_GLUE_CT=y -CONFIG_NF_NAT=m -CONFIG_NF_NAT_AMANDA=m -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT_SIP=m -CONFIG_NF_NAT_TFTP=m -CONFIG_NF_NAT_REDIRECT=y -CONFIG_NF_NAT_MASQUERADE=y -CONFIG_NETFILTER_SYNPROXY=m -CONFIG_NF_TABLES=m -CONFIG_NF_TABLES_INET=y -CONFIG_NF_TABLES_NETDEV=y -CONFIG_NFT_NUMGEN=m -CONFIG_NFT_CT=m -CONFIG_NFT_FLOW_OFFLOAD=m -CONFIG_NFT_CONNLIMIT=m -CONFIG_NFT_LOG=m -CONFIG_NFT_LIMIT=m -CONFIG_NFT_MASQ=m -CONFIG_NFT_REDIR=m -CONFIG_NFT_NAT=m -CONFIG_NFT_TUNNEL=m -CONFIG_NFT_OBJREF=m -CONFIG_NFT_QUEUE=m -CONFIG_NFT_QUOTA=m -CONFIG_NFT_REJECT=m -CONFIG_NFT_REJECT_INET=m -CONFIG_NFT_COMPAT=m -CONFIG_NFT_HASH=m -CONFIG_NFT_FIB=m -CONFIG_NFT_FIB_INET=m -CONFIG_NFT_XFRM=m -CONFIG_NFT_SOCKET=m -CONFIG_NFT_OSF=m -CONFIG_NFT_TPROXY=m -# CONFIG_NFT_SYNPROXY is not set -CONFIG_NF_DUP_NETDEV=m -CONFIG_NFT_DUP_NETDEV=m -CONFIG_NFT_FWD_NETDEV=m -CONFIG_NFT_FIB_NETDEV=m -CONFIG_NFT_REJECT_NETDEV=m -CONFIG_NF_FLOW_TABLE_INET=m -CONFIG_NF_FLOW_TABLE=m -# CONFIG_NF_FLOW_TABLE_PROCFS is not set -CONFIG_NETFILTER_XTABLES=y -CONFIG_NETFILTER_XTABLES_COMPAT=y - -# -# Xtables combined modules -# -CONFIG_NETFILTER_XT_MARK=m -CONFIG_NETFILTER_XT_CONNMARK=m -CONFIG_NETFILTER_XT_SET=m - -# -# Xtables targets -# -CONFIG_NETFILTER_XT_TARGET_AUDIT=m -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m -CONFIG_NETFILTER_XT_TARGET_CT=m -CONFIG_NETFILTER_XT_TARGET_DSCP=m -CONFIG_NETFILTER_XT_TARGET_HL=m -CONFIG_NETFILTER_XT_TARGET_HMARK=m -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -CONFIG_NETFILTER_XT_TARGET_LED=m -CONFIG_NETFILTER_XT_TARGET_LOG=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_NAT=m -CONFIG_NETFILTER_XT_TARGET_NETMAP=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -CONFIG_NETFILTER_XT_TARGET_RATEEST=m -CONFIG_NETFILTER_XT_TARGET_REDIRECT=m -CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m -CONFIG_NETFILTER_XT_TARGET_TEE=m -CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m - -# -# Xtables matches -# -CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -CONFIG_NETFILTER_XT_MATCH_BPF=m -CONFIG_NETFILTER_XT_MATCH_CGROUP=m -CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_CPU=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ECN=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_HL=m -CONFIG_NETFILTER_XT_MATCH_IPCOMP=m -CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -CONFIG_NETFILTER_XT_MATCH_IPVS=m -CONFIG_NETFILTER_XT_MATCH_L2TP=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_NFACCT=m -CONFIG_NETFILTER_XT_MATCH_OSF=m -CONFIG_NETFILTER_XT_MATCH_OWNER=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_RATEEST=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_SOCKET=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_TIME=m -CONFIG_NETFILTER_XT_MATCH_U32=m -# end of Core Netfilter Configuration - -CONFIG_IP_SET=m -CONFIG_IP_SET_MAX=256 -CONFIG_IP_SET_BITMAP_IP=m -CONFIG_IP_SET_BITMAP_IPMAC=m -CONFIG_IP_SET_BITMAP_PORT=m -CONFIG_IP_SET_HASH_IP=m -CONFIG_IP_SET_HASH_IPMARK=m -CONFIG_IP_SET_HASH_IPPORT=m -CONFIG_IP_SET_HASH_IPPORTIP=m -CONFIG_IP_SET_HASH_IPPORTNET=m -CONFIG_IP_SET_HASH_IPMAC=m -CONFIG_IP_SET_HASH_MAC=m -CONFIG_IP_SET_HASH_NETPORTNET=m -CONFIG_IP_SET_HASH_NET=m -CONFIG_IP_SET_HASH_NETNET=m -CONFIG_IP_SET_HASH_NETPORT=m -CONFIG_IP_SET_HASH_NETIFACE=m -CONFIG_IP_SET_LIST_SET=m -CONFIG_IP_VS=m -CONFIG_IP_VS_IPV6=y -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_AH_ESP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y -CONFIG_IP_VS_PROTO_SCTP=y - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_FO=m -CONFIG_IP_VS_OVF=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_MH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m -CONFIG_IP_VS_TWOS=m - -# -# IPVS SH scheduler -# -CONFIG_IP_VS_SH_TAB_BITS=8 - -# -# IPVS MH scheduler -# -CONFIG_IP_VS_MH_TAB_INDEX=12 - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -CONFIG_IP_VS_NFCT=y -CONFIG_IP_VS_PE_SIP=m - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=m -CONFIG_NF_SOCKET_IPV4=m -CONFIG_NF_TPROXY_IPV4=m -CONFIG_NF_TABLES_IPV4=y -CONFIG_NFT_REJECT_IPV4=m -CONFIG_NFT_DUP_IPV4=m -CONFIG_NFT_FIB_IPV4=m -CONFIG_NF_TABLES_ARP=y -CONFIG_NF_DUP_IPV4=m -CONFIG_NF_LOG_ARP=m -CONFIG_NF_LOG_IPV4=m -CONFIG_NF_REJECT_IPV4=m -CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_PPTP=m -CONFIG_NF_NAT_H323=m -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_RPFILTER=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_SYNPROXY=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -# end of IP: Netfilter Configuration - -# -# IPv6: Netfilter Configuration -# -CONFIG_NF_SOCKET_IPV6=m -CONFIG_NF_TPROXY_IPV6=m -CONFIG_NF_TABLES_IPV6=y -CONFIG_NFT_REJECT_IPV6=m -CONFIG_NFT_DUP_IPV6=m -CONFIG_NFT_FIB_IPV6=m -CONFIG_NF_DUP_IPV6=m -CONFIG_NF_REJECT_IPV6=m -CONFIG_NF_LOG_IPV6=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_AH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_MH=m -CONFIG_IP6_NF_MATCH_RPFILTER=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m -CONFIG_IP6_NF_TARGET_NPT=m -# end of IPv6: Netfilter Configuration - -CONFIG_NF_DEFRAG_IPV6=m -CONFIG_NF_TABLES_BRIDGE=m -CONFIG_NFT_BRIDGE_META=m -CONFIG_NFT_BRIDGE_REJECT=m -CONFIG_NF_CONNTRACK_BRIDGE=m -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_802_3=m -CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_IP=m -CONFIG_BRIDGE_EBT_IP6=m -CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_MARK=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_EBT_ARPREPLY=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_MARK_T=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_BRIDGE_EBT_NFLOG=m -CONFIG_BPFILTER=y -CONFIG_BPFILTER_UMH=m -# CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_OBJCNT is not set -CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y -# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set -# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set -CONFIG_SCTP_COOKIE_HMAC_MD5=y -# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set -CONFIG_INET_SCTP_DIAG=m -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -CONFIG_L2TP=m -# CONFIG_L2TP_DEBUGFS is not set -CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=m -CONFIG_L2TP_ETH=m -CONFIG_STP=y -CONFIG_GARP=y -CONFIG_MRP=y -CONFIG_BRIDGE=m -CONFIG_BRIDGE_IGMP_SNOOPING=y -CONFIG_BRIDGE_VLAN_FILTERING=y -CONFIG_BRIDGE_MRP=y -# CONFIG_BRIDGE_CFM is not set -CONFIG_NET_DSA=m -CONFIG_NET_DSA_TAG_AR9331=m -CONFIG_NET_DSA_TAG_BRCM_COMMON=m -CONFIG_NET_DSA_TAG_BRCM=m -CONFIG_NET_DSA_TAG_BRCM_LEGACY=m -CONFIG_NET_DSA_TAG_BRCM_PREPEND=m -CONFIG_NET_DSA_TAG_HELLCREEK=m -CONFIG_NET_DSA_TAG_GSWIP=m -CONFIG_NET_DSA_TAG_DSA_COMMON=m -CONFIG_NET_DSA_TAG_DSA=m -CONFIG_NET_DSA_TAG_EDSA=m -CONFIG_NET_DSA_TAG_MTK=m -CONFIG_NET_DSA_TAG_KSZ=m -CONFIG_NET_DSA_TAG_OCELOT=m -CONFIG_NET_DSA_TAG_OCELOT_8021Q=m -CONFIG_NET_DSA_TAG_QCA=m -CONFIG_NET_DSA_TAG_RTL4_A=m -CONFIG_NET_DSA_TAG_RTL8_4=m -CONFIG_NET_DSA_TAG_RZN1_A5PSW=m -CONFIG_NET_DSA_TAG_LAN9303=m -CONFIG_NET_DSA_TAG_SJA1105=m -CONFIG_NET_DSA_TAG_TRAILER=m -CONFIG_NET_DSA_TAG_XRS700X=m -CONFIG_VLAN_8021Q=y -CONFIG_VLAN_8021Q_GVRP=y -CONFIG_VLAN_8021Q_MVRP=y -CONFIG_LLC=y -# CONFIG_LLC2 is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_PHONET is not set -CONFIG_6LOWPAN=m -# CONFIG_6LOWPAN_DEBUGFS is not set -CONFIG_6LOWPAN_NHC=m -CONFIG_6LOWPAN_NHC_DEST=m -CONFIG_6LOWPAN_NHC_FRAGMENT=m -CONFIG_6LOWPAN_NHC_HOP=m -CONFIG_6LOWPAN_NHC_IPV6=m -CONFIG_6LOWPAN_NHC_MOBILITY=m -CONFIG_6LOWPAN_NHC_ROUTING=m -CONFIG_6LOWPAN_NHC_UDP=m -# CONFIG_6LOWPAN_GHC_EXT_HDR_HOP is not set -# CONFIG_6LOWPAN_GHC_UDP is not set -# CONFIG_6LOWPAN_GHC_ICMPV6 is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_DEST is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE is not set -CONFIG_IEEE802154=m -# CONFIG_IEEE802154_NL802154_EXPERIMENTAL is not set -CONFIG_IEEE802154_SOCKET=m -# CONFIG_IEEE802154_6LOWPAN is not set -# CONFIG_MAC802154 is not set -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_MULTIQ=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFB=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_CBS=m -CONFIG_NET_SCH_ETF=m -CONFIG_NET_SCH_TAPRIO=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_DRR=m -CONFIG_NET_SCH_MQPRIO=m -CONFIG_NET_SCH_SKBPRIO=m -CONFIG_NET_SCH_CHOKE=m -CONFIG_NET_SCH_QFQ=m -CONFIG_NET_SCH_CODEL=m -CONFIG_NET_SCH_FQ_CODEL=m -CONFIG_NET_SCH_CAKE=m -CONFIG_NET_SCH_FQ=m -CONFIG_NET_SCH_HHF=m -CONFIG_NET_SCH_PIE=m -CONFIG_NET_SCH_FQ_PIE=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_SCH_PLUG=m -CONFIG_NET_SCH_ETS=m -CONFIG_NET_SCH_DEFAULT=y -# CONFIG_DEFAULT_FQ is not set -# CONFIG_DEFAULT_CODEL is not set -# CONFIG_DEFAULT_FQ_CODEL is not set -# CONFIG_DEFAULT_FQ_PIE is not set -# CONFIG_DEFAULT_SFQ is not set -CONFIG_DEFAULT_PFIFO_FAST=y -CONFIG_DEFAULT_NET_SCH="pfifo_fast" - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_CLS_U32_PERF=y -CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_FLOW=m -CONFIG_NET_CLS_CGROUP=m -CONFIG_NET_CLS_BPF=m -CONFIG_NET_CLS_FLOWER=m -CONFIG_NET_CLS_MATCHALL=m -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_STACK=32 -CONFIG_NET_EMATCH_CMP=m -CONFIG_NET_EMATCH_NBYTE=m -CONFIG_NET_EMATCH_U32=m -CONFIG_NET_EMATCH_META=m -CONFIG_NET_EMATCH_TEXT=m -CONFIG_NET_EMATCH_CANID=m -CONFIG_NET_EMATCH_IPSET=m -CONFIG_NET_EMATCH_IPT=m -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=m -CONFIG_NET_ACT_GACT=m -CONFIG_GACT_PROB=y -CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_SAMPLE=m -CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_NAT=m -CONFIG_NET_ACT_PEDIT=m -CONFIG_NET_ACT_SIMP=m -CONFIG_NET_ACT_SKBEDIT=m -CONFIG_NET_ACT_CSUM=m -# CONFIG_NET_ACT_MPLS is not set -CONFIG_NET_ACT_VLAN=m -CONFIG_NET_ACT_BPF=m -CONFIG_NET_ACT_CONNMARK=m -CONFIG_NET_ACT_CTINFO=m -CONFIG_NET_ACT_SKBMOD=m -CONFIG_NET_ACT_IFE=m -CONFIG_NET_ACT_TUNNEL_KEY=m -CONFIG_NET_ACT_CT=m -CONFIG_NET_ACT_GATE=m -CONFIG_NET_IFE_SKBMARK=m -CONFIG_NET_IFE_SKBPRIO=m -CONFIG_NET_IFE_SKBTCINDEX=m -# CONFIG_NET_TC_SKB_EXT is not set -CONFIG_NET_SCH_FIFO=y -CONFIG_DCB=y -CONFIG_DNS_RESOLVER=y -CONFIG_BATMAN_ADV=m -CONFIG_BATMAN_ADV_BATMAN_V=y -CONFIG_BATMAN_ADV_BLA=y -CONFIG_BATMAN_ADV_DAT=y -CONFIG_BATMAN_ADV_NC=y -CONFIG_BATMAN_ADV_MCAST=y -CONFIG_BATMAN_ADV_DEBUG=y -CONFIG_OPENVSWITCH=m -CONFIG_OPENVSWITCH_GRE=m -CONFIG_OPENVSWITCH_VXLAN=m -CONFIG_OPENVSWITCH_GENEVE=m -CONFIG_VSOCKETS=m -CONFIG_VSOCKETS_DIAG=m -CONFIG_VSOCKETS_LOOPBACK=m -CONFIG_VIRTIO_VSOCKETS=m -CONFIG_VIRTIO_VSOCKETS_COMMON=m -CONFIG_NETLINK_DIAG=m -CONFIG_MPLS=y -CONFIG_NET_MPLS_GSO=m -CONFIG_MPLS_ROUTING=m -CONFIG_MPLS_IPTUNNEL=m -CONFIG_NET_NSH=m -# CONFIG_HSR is not set -CONFIG_NET_SWITCHDEV=y -CONFIG_NET_L3_MASTER_DEV=y -# CONFIG_QRTR is not set -# CONFIG_NET_NCSI is not set -CONFIG_PCPU_DEV_REFCNT=y -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_XPS=y -CONFIG_CGROUP_NET_PRIO=y -CONFIG_CGROUP_NET_CLASSID=y -CONFIG_NET_RX_BUSY_POLL=y -CONFIG_BQL=y -# CONFIG_BPF_STREAM_PARSER is not set -CONFIG_NET_FLOW_LIMIT=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# end of Network testing -# end of Networking options - -CONFIG_HAMRADIO=y - -# -# Packet Radio protocols -# -CONFIG_AX25=m -CONFIG_AX25_DAMA_SLAVE=y -CONFIG_NETROM=m -CONFIG_ROSE=m - -# -# AX.25 network device drivers -# -CONFIG_MKISS=m -CONFIG_6PACK=m -CONFIG_BPQETHER=m -CONFIG_BAYCOM_SER_FDX=m -CONFIG_BAYCOM_SER_HDX=m -CONFIG_YAM=m -# end of AX.25 network device drivers - -CONFIG_CAN=m -CONFIG_CAN_RAW=m -CONFIG_CAN_BCM=m -CONFIG_CAN_GW=m -CONFIG_CAN_J1939=m -# CONFIG_CAN_ISOTP is not set -CONFIG_BT=m -CONFIG_BT_BREDR=y -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m -CONFIG_BT_HS=y -CONFIG_BT_LE=y -# CONFIG_BT_6LOWPAN is not set -CONFIG_BT_LEDS=y -# CONFIG_BT_MSFTEXT is not set -# CONFIG_BT_AOSPEXT is not set -CONFIG_BT_DEBUGFS=y - -# -# Bluetooth device drivers -# -CONFIG_BT_INTEL=m -CONFIG_BT_BCM=m -CONFIG_BT_RTL=m -CONFIG_BT_QCA=m -CONFIG_BT_MTK=m -CONFIG_BT_HCIBTUSB=m -# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set -CONFIG_BT_HCIBTUSB_BCM=y -# CONFIG_BT_HCIBTUSB_MTK is not set -CONFIG_BT_HCIBTUSB_RTL=y -CONFIG_BT_HCIBTSDIO=m -CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_SERDEV=y -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_NOKIA=m -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_ATH3K=y -CONFIG_BT_HCIUART_LL=y -CONFIG_BT_HCIUART_3WIRE=y -CONFIG_BT_HCIUART_INTEL=y -CONFIG_BT_HCIUART_BCM=y -CONFIG_BT_HCIUART_RTL=y -CONFIG_BT_HCIUART_QCA=y -CONFIG_BT_HCIUART_AG6XX=y -CONFIG_BT_HCIUART_MRVL=y -CONFIG_BT_HCIBCM203X=m -CONFIG_BT_HCIBPA10X=m -CONFIG_BT_HCIBFUSB=m -CONFIG_BT_HCIVHCI=m -CONFIG_BT_MRVL=m -CONFIG_BT_MRVL_SDIO=m -CONFIG_BT_ATH3K=m -CONFIG_BT_MTKSDIO=m -CONFIG_BT_MTKUART=m -CONFIG_BT_VIRTIO=m -# end of Bluetooth device drivers - -CONFIG_AF_RXRPC=m -# CONFIG_AF_RXRPC_IPV6 is not set -# CONFIG_AF_RXRPC_INJECT_LOSS is not set -# CONFIG_AF_RXRPC_DEBUG is not set -# CONFIG_RXKAD is not set -# CONFIG_AF_KCM is not set -CONFIG_STREAM_PARSER=y -CONFIG_MCTP=y -CONFIG_MCTP_FLOWS=y -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_PRIV=y -CONFIG_CFG80211=m -# CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y -CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y -# CONFIG_CFG80211_DEFAULT_PS is not set -# CONFIG_CFG80211_DEBUGFS is not set -CONFIG_CFG80211_CRDA_SUPPORT=y -CONFIG_CFG80211_WEXT=y -CONFIG_LIB80211=m -CONFIG_LIB80211_CRYPT_WEP=m -CONFIG_LIB80211_CRYPT_CCMP=m -CONFIG_LIB80211_DEBUG=y -CONFIG_MAC80211=m -CONFIG_MAC80211_HAS_RC=y -CONFIG_MAC80211_RC_MINSTREL=y -CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -CONFIG_MAC80211_MESH=y -CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_MESSAGE_TRACING is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -CONFIG_RFKILL=m -CONFIG_RFKILL_LEDS=y -CONFIG_RFKILL_INPUT=y -# CONFIG_RFKILL_GPIO is not set -CONFIG_NET_9P=y -CONFIG_NET_9P_FD=m -CONFIG_NET_9P_VIRTIO=y -# CONFIG_NET_9P_DEBUG is not set -# CONFIG_CAIF is not set -CONFIG_CEPH_LIB=m -# CONFIG_CEPH_LIB_PRETTYDEBUG is not set -# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set -CONFIG_NFC=m -CONFIG_NFC_DIGITAL=m -CONFIG_NFC_NCI=m -CONFIG_NFC_NCI_SPI=m -CONFIG_NFC_NCI_UART=m -CONFIG_NFC_HCI=m -CONFIG_NFC_SHDLC=y - -# -# Near Field Communication (NFC) devices -# -CONFIG_NFC_TRF7970A=m -CONFIG_NFC_SIM=m -CONFIG_NFC_PORT100=m -CONFIG_NFC_VIRTUAL_NCI=m -CONFIG_NFC_FDP=m -CONFIG_NFC_FDP_I2C=m -CONFIG_NFC_PN544=m -CONFIG_NFC_PN544_I2C=m -CONFIG_NFC_PN533=m -CONFIG_NFC_PN533_USB=m -CONFIG_NFC_PN533_I2C=m -CONFIG_NFC_PN532_UART=m -CONFIG_NFC_MICROREAD=m -CONFIG_NFC_MICROREAD_I2C=m -CONFIG_NFC_MRVL=m -CONFIG_NFC_MRVL_USB=m -CONFIG_NFC_MRVL_UART=m -CONFIG_NFC_MRVL_I2C=m -CONFIG_NFC_MRVL_SPI=m -CONFIG_NFC_ST21NFCA=m -CONFIG_NFC_ST21NFCA_I2C=m -CONFIG_NFC_ST_NCI=m -CONFIG_NFC_ST_NCI_I2C=m -CONFIG_NFC_ST_NCI_SPI=m -CONFIG_NFC_NXP_NCI=m -CONFIG_NFC_NXP_NCI_I2C=m -CONFIG_NFC_S3FWRN5=m -CONFIG_NFC_S3FWRN5_I2C=m -CONFIG_NFC_S3FWRN82_UART=m -CONFIG_NFC_ST95HF=m -# end of Near Field Communication (NFC) devices - -CONFIG_PSAMPLE=m -CONFIG_NET_IFE=m -CONFIG_LWTUNNEL=y -# CONFIG_LWTUNNEL_BPF is not set -CONFIG_DST_CACHE=y -CONFIG_GRO_CELLS=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SOCK_MSG=y -CONFIG_NET_DEVLINK=y -CONFIG_PAGE_POOL=y -# CONFIG_PAGE_POOL_STATS is not set -CONFIG_FAILOVER=m -CONFIG_ETHTOOL_NETLINK=y - -# -# Device Drivers -# -CONFIG_ARM_AMBA=y -CONFIG_HAVE_PCI=y -# CONFIG_PCI is not set -# CONFIG_PCCARD is not set - -# -# Generic Driver Options -# -CONFIG_AUXILIARY_BUS=y -CONFIG_UEVENT_HELPER=y -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_DEVTMPFS_SAFE is not set -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y - -# -# Firmware loader -# -CONFIG_FW_LOADER=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_FW_LOADER_USER_HELPER is not set -# CONFIG_FW_LOADER_COMPRESS is not set -CONFIG_FW_CACHE=y -# CONFIG_FW_UPLOAD is not set -# end of Firmware loader - -CONFIG_WANT_DEV_COREDUMP=y -CONFIG_ALLOW_DEV_COREDUMP=y -CONFIG_DEV_COREDUMP=y -# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_SOC_BUS=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_SPI=y -CONFIG_REGMAP_SPMI=m -CONFIG_REGMAP_W1=m -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_IRQ=y -CONFIG_REGMAP_SCCB=m -CONFIG_DMA_SHARED_BUFFER=y -# CONFIG_DMA_FENCE_TRACE is not set -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_ARCH_NUMA=y -# end of Generic Driver Options - -# -# Bus devices -# -CONFIG_ARM_CCI=y -# CONFIG_BRCMSTB_GISB_ARB is not set -# CONFIG_MOXTET is not set -CONFIG_SUN50I_DE2_BUS=y -CONFIG_SUNXI_RSB=y -# CONFIG_VEXPRESS_CONFIG is not set -CONFIG_MHI_BUS=m -# CONFIG_MHI_BUS_DEBUG is not set -CONFIG_MHI_BUS_EP=m -# end of Bus devices - -CONFIG_CONNECTOR=m - -# -# Firmware Drivers -# - -# -# ARM System Control and Management Interface Protocol -# -CONFIG_ARM_SCMI_PROTOCOL=y -CONFIG_ARM_SCMI_HAVE_TRANSPORT=y -CONFIG_ARM_SCMI_HAVE_SHMEM=y -CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y -CONFIG_ARM_SCMI_TRANSPORT_SMC=y -# CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE is not set -# CONFIG_ARM_SCMI_TRANSPORT_VIRTIO is not set -CONFIG_ARM_SCMI_POWER_DOMAIN=y -CONFIG_ARM_SCMI_POWER_CONTROL=m -# end of ARM System Control and Management Interface Protocol - -CONFIG_ARM_SCPI_PROTOCOL=y -CONFIG_ARM_SCPI_POWER_DOMAIN=y -CONFIG_ARM_FFA_TRANSPORT=y -CONFIG_ARM_FFA_SMCCC=y -CONFIG_CS_DSP=m -# CONFIG_GOOGLE_FIRMWARE is not set -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_PSCI_CHECKER is not set -CONFIG_HAVE_ARM_SMCCC=y -CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y -CONFIG_ARM_SMCCC_SOC_ID=y - -# -# Tegra firmware driver -# -# end of Tegra firmware driver -# end of Firmware Drivers - -CONFIG_GNSS=m -CONFIG_GNSS_SERIAL=m -CONFIG_GNSS_MTK_SERIAL=m -CONFIG_GNSS_SIRF_SERIAL=m -CONFIG_GNSS_UBX_SERIAL=m -CONFIG_GNSS_USB=m -CONFIG_MTD=y -# CONFIG_MTD_TESTS is not set - -# -# Partition parsers -# -# CONFIG_MTD_AR7_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# end of Partition parsers - -# -# User Modules And Translation Layers -# -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y - -# -# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK. -# -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_SM_FTL is not set -# CONFIG_MTD_OOPS is not set -CONFIG_MTD_PSTORE=m -# CONFIG_MTD_SWAP is not set -# CONFIG_MTD_PARTITIONED_MASTER is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_INTELEXT is not set -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# end of RAM/ROM/Flash chip drivers - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PLATRAM is not set -# end of Mapping drivers for chip access - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_MCHP23K256 is not set -CONFIG_MTD_MCHP48L640=m -# CONFIG_MTD_SST25L is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOCG3 is not set -# end of Self-contained MTD device drivers - -# -# NAND -# -CONFIG_MTD_NAND_CORE=y -# CONFIG_MTD_ONENAND is not set -CONFIG_MTD_RAW_NAND=m - -# -# Raw/parallel NAND flash controllers -# -CONFIG_MTD_NAND_DENALI=m -CONFIG_MTD_NAND_DENALI_DT=m -CONFIG_MTD_NAND_BRCMNAND=m -CONFIG_MTD_NAND_BRCMNAND_BCM63XX=m -CONFIG_MTD_NAND_BRCMNAND_BCMBCA=m -CONFIG_MTD_NAND_BRCMNAND_BRCMSTB=m -CONFIG_MTD_NAND_BRCMNAND_IPROC=m -CONFIG_MTD_NAND_SUNXI=m -CONFIG_MTD_NAND_MXIC=m -CONFIG_MTD_NAND_GPIO=m -CONFIG_MTD_NAND_PLATFORM=m -CONFIG_MTD_NAND_CADENCE=m -# CONFIG_MTD_NAND_ARASAN is not set -CONFIG_MTD_NAND_INTEL_LGM=m - -# -# Misc -# -CONFIG_MTD_NAND_NANDSIM=m -CONFIG_MTD_NAND_DISKONCHIP=m -# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set -CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 -# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set -CONFIG_MTD_SPI_NAND=m - -# -# ECC engine support -# -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_ECC_SW_HAMMING=y -# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set -# CONFIG_MTD_NAND_ECC_SW_BCH is not set -CONFIG_MTD_NAND_ECC_MXIC=y -# end of ECC engine support -# end of NAND - -# -# LPDDR & LPDDR2 PCM memory drivers -# -# CONFIG_MTD_LPDDR is not set -# end of LPDDR & LPDDR2 PCM memory drivers - -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set -CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y -# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set -# CONFIG_MTD_UBI is not set -# CONFIG_MTD_HYPERBUS is not set -CONFIG_DTC=y -CONFIG_OF=y -# CONFIG_OF_UNITTEST is not set -CONFIG_OF_FLATTREE=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_KOBJ=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_IRQ=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OF_RESOLVE=y -CONFIG_OF_OVERLAY=y -CONFIG_OF_NUMA=y -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_NULL_BLK is not set -CONFIG_CDROM=m -CONFIG_ZRAM=m -CONFIG_ZRAM_DEF_COMP_LZORLE=y -# CONFIG_ZRAM_DEF_COMP_ZSTD is not set -# CONFIG_ZRAM_DEF_COMP_LZ4 is not set -# CONFIG_ZRAM_DEF_COMP_LZO is not set -# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set -# CONFIG_ZRAM_DEF_COMP_842 is not set -CONFIG_ZRAM_DEF_COMP="lzo-rle" -CONFIG_ZRAM_WRITEBACK=y -# CONFIG_ZRAM_MEMORY_TRACKING is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -CONFIG_BLK_DEV_DRBD=m -# CONFIG_DRBD_FAULT_INJECTION is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=m -CONFIG_BLK_DEV_RAM_COUNT=8 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_CDROM_PKTCDVD is not set -CONFIG_ATA_OVER_ETH=m -# CONFIG_VIRTIO_BLK is not set -CONFIG_BLK_DEV_RBD=m -CONFIG_BLK_DEV_UBLK=m - -# -# NVME Support -# -CONFIG_NVME_CORE=m -# CONFIG_NVME_MULTIPATH is not set -# CONFIG_NVME_VERBOSE_ERRORS is not set -# CONFIG_NVME_HWMON is not set -CONFIG_NVME_FABRICS=m -# CONFIG_NVME_FC is not set -CONFIG_NVME_TCP=m -# CONFIG_NVME_AUTH is not set -# CONFIG_NVME_TARGET is not set -# end of NVME Support - -# -# Misc devices -# -# CONFIG_AD525X_DPOT is not set -# CONFIG_DUMMY_IRQ is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HI6421V600_IRQ=m -# CONFIG_APDS9802ALS is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_HMC6352 is not set -# CONFIG_DS1682 is not set -# CONFIG_LATTICE_ECP3_CONFIG is not set -# CONFIG_SRAM is not set -# CONFIG_XILINX_SDFEC is not set -# CONFIG_HISI_HIKEY_USB is not set -CONFIG_OPEN_DICE=m -CONFIG_VCPU_STALL_DETECTOR=m -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -CONFIG_EEPROM_AT24=m -CONFIG_EEPROM_AT25=m -CONFIG_EEPROM_LEGACY=m -# CONFIG_EEPROM_MAX6875 is not set -CONFIG_EEPROM_93CX6=m -# CONFIG_EEPROM_93XX46 is not set -# CONFIG_EEPROM_IDT_89HPESX is not set -CONFIG_EEPROM_EE1004=m -# end of EEPROM support - -# -# Texas Instruments shared transport line discipline -# -# CONFIG_TI_ST is not set -# end of Texas Instruments shared transport line discipline - -# CONFIG_SENSORS_LIS3_SPI is not set -# CONFIG_SENSORS_LIS3_I2C is not set -# CONFIG_ALTERA_STAPL is not set -# CONFIG_ECHO is not set -# CONFIG_MISC_RTSX_USB is not set -CONFIG_UACCE=m -# CONFIG_PVPANIC is not set -# end of Misc devices - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI_COMMON=y -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_PROC_FS is not set - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -CONFIG_BLK_DEV_SR=m -CONFIG_CHR_DEV_SG=y -CONFIG_BLK_DEV_BSG=y -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -CONFIG_SCSI_ISCSI_ATTRS=m -CONFIG_SCSI_SAS_ATTRS=m -# CONFIG_SCSI_SAS_LIBSAS is not set -CONFIG_SCSI_SRP_ATTRS=m -# end of SCSI Transports - -CONFIG_SCSI_LOWLEVEL=y -CONFIG_ISCSI_TCP=m -CONFIG_ISCSI_BOOT_SYSFS=m -# CONFIG_SCSI_HISI_SAS is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_VIRTIO is not set -# CONFIG_SCSI_DH is not set -# end of SCSI device support - -CONFIG_ATA=m -CONFIG_SATA_HOST=y -# CONFIG_ATA_VERBOSE_ERROR is not set -CONFIG_ATA_FORCE=y -CONFIG_SATA_PMP=y - -# -# Controllers with non-SFF native interface -# -# CONFIG_SATA_AHCI_PLATFORM is not set -CONFIG_AHCI_DWC=m -# CONFIG_AHCI_CEVA is not set -# CONFIG_AHCI_SUNXI is not set -# CONFIG_AHCI_QORIQ is not set -# CONFIG_ATA_SFF is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_AUTODETECT=y -CONFIG_MD_LINEAR=y -CONFIG_MD_RAID0=y -CONFIG_MD_RAID1=y -CONFIG_MD_RAID10=y -CONFIG_MD_RAID456=y -CONFIG_MD_MULTIPATH=y -CONFIG_MD_FAULTY=y -CONFIG_MD_CLUSTER=m -CONFIG_BCACHE=y -# CONFIG_BCACHE_DEBUG is not set -# CONFIG_BCACHE_CLOSURES_DEBUG is not set -# CONFIG_BCACHE_ASYNC_REGISTRATION is not set -CONFIG_BLK_DEV_DM_BUILTIN=y -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -CONFIG_DM_BUFIO=m -# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set -CONFIG_DM_BIO_PRISON=m -CONFIG_DM_PERSISTENT_DATA=m -CONFIG_DM_UNSTRIPED=m -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_THIN_PROVISIONING=m -CONFIG_DM_CACHE=m -CONFIG_DM_CACHE_SMQ=m -CONFIG_DM_WRITECACHE=m -# CONFIG_DM_EBS is not set -CONFIG_DM_ERA=m -CONFIG_DM_CLONE=m -CONFIG_DM_MIRROR=m -CONFIG_DM_LOG_USERSPACE=m -CONFIG_DM_RAID=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -# CONFIG_DM_MULTIPATH_QL is not set -# CONFIG_DM_MULTIPATH_ST is not set -# CONFIG_DM_MULTIPATH_HST is not set -CONFIG_DM_MULTIPATH_IOA=m -CONFIG_DM_DELAY=m -CONFIG_DM_DUST=m -# CONFIG_DM_UEVENT is not set -# CONFIG_DM_FLAKEY is not set -# CONFIG_DM_VERITY is not set -# CONFIG_DM_SWITCH is not set -# CONFIG_DM_LOG_WRITES is not set -CONFIG_DM_INTEGRITY=m -# CONFIG_DM_ZONED is not set -CONFIG_DM_AUDIT=y -CONFIG_TARGET_CORE=m -CONFIG_TCM_IBLOCK=m -CONFIG_TCM_FILEIO=m -CONFIG_TCM_PSCSI=m -CONFIG_LOOPBACK_TARGET=m -CONFIG_ISCSI_TARGET=m -CONFIG_NETDEVICES=y -CONFIG_MII=y -CONFIG_NET_CORE=y -CONFIG_BONDING=m -CONFIG_DUMMY=m -CONFIG_WIREGUARD=m -# CONFIG_WIREGUARD_DEBUG is not set -CONFIG_EQUALIZER=m -CONFIG_IFB=m -CONFIG_NET_TEAM=m -CONFIG_NET_TEAM_MODE_BROADCAST=m -CONFIG_NET_TEAM_MODE_ROUNDROBIN=m -CONFIG_NET_TEAM_MODE_RANDOM=m -CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m -CONFIG_NET_TEAM_MODE_LOADBALANCE=m -CONFIG_MACVLAN=m -CONFIG_MACVTAP=m -CONFIG_IPVLAN_L3S=y -CONFIG_IPVLAN=m -CONFIG_IPVTAP=m -CONFIG_VXLAN=m -CONFIG_GENEVE=m -CONFIG_BAREUDP=m -CONFIG_GTP=m -CONFIG_AMT=m -CONFIG_MACSEC=m -CONFIG_NETCONSOLE=m -# CONFIG_NETCONSOLE_DYNAMIC is not set -CONFIG_NETPOLL=y -CONFIG_NET_POLL_CONTROLLER=y -CONFIG_TUN=m -CONFIG_TAP=m -# CONFIG_TUN_VNET_CROSS_LE is not set -CONFIG_VETH=m -CONFIG_VIRTIO_NET=m -CONFIG_NLMON=m -# CONFIG_NET_VRF is not set -CONFIG_MHI_NET=m - -# -# Distributed Switch Architecture drivers -# -# CONFIG_B53 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set -# CONFIG_NET_DSA_LOOP is not set -CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK=m -CONFIG_NET_DSA_LANTIQ_GSWIP=m -# CONFIG_NET_DSA_MT7530 is not set -# CONFIG_NET_DSA_MV88E6060 is not set -CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m -CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m -CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=m -CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MSCC_SEVILLE is not set -CONFIG_NET_DSA_AR9331=m -# CONFIG_NET_DSA_QCA8K is not set -CONFIG_NET_DSA_SJA1105=m -# CONFIG_NET_DSA_SJA1105_PTP is not set -CONFIG_NET_DSA_XRS700X=m -CONFIG_NET_DSA_XRS700X_I2C=m -CONFIG_NET_DSA_XRS700X_MDIO=m -CONFIG_NET_DSA_REALTEK=m -CONFIG_NET_DSA_REALTEK_MDIO=m -CONFIG_NET_DSA_REALTEK_SMI=m -CONFIG_NET_DSA_REALTEK_RTL8365MB=m -CONFIG_NET_DSA_REALTEK_RTL8366RB=m -# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set -# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set -# end of Distributed Switch Architecture drivers - -CONFIG_ETHERNET=y -CONFIG_MDIO=m -CONFIG_NET_VENDOR_ALACRITECH=y -CONFIG_NET_VENDOR_ALLWINNER=y -CONFIG_SUN4I_EMAC=y -CONFIG_SUNXI_GMAC=y -# CONFIG_ALTERA_TSE is not set -CONFIG_NET_VENDOR_AMAZON=y -CONFIG_NET_VENDOR_AMD=y -CONFIG_AMD_XGBE=m -# CONFIG_AMD_XGBE_DCB is not set -CONFIG_NET_VENDOR_AQUANTIA=y -# CONFIG_NET_VENDOR_ARC is not set -CONFIG_NET_VENDOR_ASIX=y -CONFIG_SPI_AX88796C=m -# CONFIG_SPI_AX88796C_COMPRESSION is not set -# CONFIG_NET_VENDOR_BROADCOM is not set -CONFIG_NET_VENDOR_CADENCE=y -# CONFIG_MACB is not set -CONFIG_NET_VENDOR_CAVIUM=y -CONFIG_NET_VENDOR_CORTINA=y -# CONFIG_GEMINI_ETHERNET is not set -CONFIG_NET_VENDOR_DAVICOM=y -CONFIG_DM9051=m -# CONFIG_DNET is not set -CONFIG_NET_VENDOR_ENGLEDER=y -CONFIG_TSNEP=m -# CONFIG_TSNEP_SELFTESTS is not set -CONFIG_NET_VENDOR_EZCHIP=y -# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set -CONFIG_NET_VENDOR_FUNGIBLE=y -CONFIG_NET_VENDOR_GOOGLE=y -CONFIG_NET_VENDOR_HISILICON=y -# CONFIG_HIX5HD2_GMAC is not set -# CONFIG_HISI_FEMAC is not set -CONFIG_HIP04_ETH=m -# CONFIG_HI13X1_GMAC is not set -CONFIG_HNS_MDIO=m -# CONFIG_HNS_DSAF is not set -# CONFIG_HNS_ENET is not set -CONFIG_NET_VENDOR_HUAWEI=y -# CONFIG_NET_VENDOR_INTEL is not set -CONFIG_NET_VENDOR_WANGXUN=y -CONFIG_NET_VENDOR_ADI=y -CONFIG_ADIN1110=m -CONFIG_NET_VENDOR_LITEX=y -# CONFIG_LITEX_LITEETH is not set -# CONFIG_NET_VENDOR_MARVELL is not set -CONFIG_NET_VENDOR_MELLANOX=y -# CONFIG_MLXSW_CORE is not set -# CONFIG_MLXFW is not set -# CONFIG_NET_VENDOR_MICREL is not set -CONFIG_NET_VENDOR_MICROCHIP=y -CONFIG_ENC28J60=m -CONFIG_ENC28J60_WRITEVERIFY=y -# CONFIG_ENCX24J600 is not set -CONFIG_LAN966X_SWITCH=m -CONFIG_NET_VENDOR_MICROSEMI=y -# CONFIG_MSCC_OCELOT_SWITCH is not set -CONFIG_NET_VENDOR_MICROSOFT=y -CONFIG_NET_VENDOR_NI=y -CONFIG_NI_XGE_MANAGEMENT_ENET=m -# CONFIG_NET_VENDOR_NATSEMI is not set -CONFIG_NET_VENDOR_NETRONOME=y -# CONFIG_ETHOC is not set -CONFIG_NET_VENDOR_PENSANDO=y -CONFIG_NET_VENDOR_QUALCOMM=y -CONFIG_QCA7000=m -# CONFIG_QCA7000_SPI is not set -CONFIG_QCA7000_UART=m -# CONFIG_QCOM_EMAC is not set -# CONFIG_RMNET is not set -CONFIG_NET_VENDOR_RENESAS=y -CONFIG_NET_VENDOR_ROCKER=y -# CONFIG_NET_VENDOR_SAMSUNG is not set -# CONFIG_NET_VENDOR_SEEQ is not set -CONFIG_NET_VENDOR_SOLARFLARE=y -# CONFIG_NET_VENDOR_SMSC is not set -CONFIG_NET_VENDOR_SOCIONEXT=y -CONFIG_NET_VENDOR_STMICRO=y -CONFIG_STMMAC_ETH=y -# CONFIG_STMMAC_SELFTESTS is not set -CONFIG_STMMAC_PLATFORM=y -CONFIG_DWMAC_DWC_QOS_ETH=m -CONFIG_DWMAC_GENERIC=y -CONFIG_DWMAC_SUNXI=m -CONFIG_DWMAC_SUN8I=m -# CONFIG_DWMAC_INTEL_PLAT is not set -CONFIG_NET_VENDOR_SYNOPSYS=y -# CONFIG_DWC_XLGMAC is not set -CONFIG_NET_VENDOR_VERTEXCOM=y -CONFIG_MSE102X=m -# CONFIG_NET_VENDOR_VIA is not set -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_NET_VENDOR_XILINX=y -CONFIG_XILINX_EMACLITE=m -CONFIG_XILINX_AXI_EMAC=m -CONFIG_XILINX_LL_TEMAC=m -CONFIG_PHYLINK=y -CONFIG_PHYLIB=y -CONFIG_SWPHY=y -CONFIG_LED_TRIGGER_PHY=y -CONFIG_FIXED_PHY=y -# CONFIG_SFP is not set - -# -# MII PHY device drivers -# -CONFIG_AMD_PHY=m -CONFIG_ADIN_PHY=m -CONFIG_ADIN1100_PHY=m -CONFIG_AQUANTIA_PHY=m -CONFIG_AX88796B_PHY=m -CONFIG_BROADCOM_PHY=m -# CONFIG_BCM54140_PHY is not set -# CONFIG_BCM7XXX_PHY is not set -# CONFIG_BCM84881_PHY is not set -CONFIG_BCM87XX_PHY=m -CONFIG_BCM_NET_PHYLIB=m -CONFIG_BCM_NET_PHYPTP=m -CONFIG_CICADA_PHY=m -# CONFIG_CORTINA_PHY is not set -CONFIG_DAVICOM_PHY=m -CONFIG_ICPLUS_PHY=m -CONFIG_LXT_PHY=m -# CONFIG_INTEL_XWAY_PHY is not set -CONFIG_LSI_ET1011C_PHY=m -CONFIG_MARVELL_PHY=m -# CONFIG_MARVELL_10G_PHY is not set -CONFIG_MARVELL_88X2222_PHY=m -CONFIG_MAXLINEAR_GPHY=m -CONFIG_MEDIATEK_GE_PHY=m -CONFIG_MICREL_PHY=m -CONFIG_MICROCHIP_PHY=m -CONFIG_MICROCHIP_T1_PHY=m -# CONFIG_MICROSEMI_PHY is not set -CONFIG_MOTORCOMM_PHY=m -CONFIG_NATIONAL_PHY=m -CONFIG_NXP_C45_TJA11XX_PHY=m -# CONFIG_NXP_TJA11XX_PHY is not set -CONFIG_AT803X_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_REALTEK_PHY=m -# CONFIG_RENESAS_PHY is not set -# CONFIG_ROCKCHIP_PHY is not set -CONFIG_SMSC_PHY=m -CONFIG_STE10XP=m -CONFIG_TERANETICS_PHY=m -# CONFIG_DP83822_PHY is not set -CONFIG_DP83TC811_PHY=m -CONFIG_DP83848_PHY=m -# CONFIG_DP83867_PHY is not set -CONFIG_DP83869_PHY=m -CONFIG_DP83TD510_PHY=m -CONFIG_VITESSE_PHY=m -# CONFIG_XILINX_GMII2RGMII is not set -# CONFIG_MICREL_KS8995MA is not set -# CONFIG_PSE_CONTROLLER is not set -CONFIG_CAN_DEV=m -CONFIG_CAN_VCAN=m -CONFIG_CAN_VXCAN=m -CONFIG_CAN_NETLINK=y -CONFIG_CAN_CALC_BITTIMING=y -CONFIG_CAN_RX_OFFLOAD=y -CONFIG_CAN_CAN327=m -# CONFIG_CAN_FLEXCAN is not set -# CONFIG_CAN_GRCAN is not set -CONFIG_CAN_SLCAN=m -# CONFIG_CAN_XILINXCAN is not set -# CONFIG_CAN_C_CAN is not set -# CONFIG_CAN_CC770 is not set -CONFIG_CAN_CTUCANFD=m -CONFIG_CAN_CTUCANFD_PLATFORM=m -# CONFIG_CAN_IFI_CANFD is not set -# CONFIG_CAN_M_CAN is not set -# CONFIG_CAN_SJA1000 is not set -# CONFIG_CAN_SOFTING is not set - -# -# CAN SPI interfaces -# -CONFIG_CAN_HI311X=m -CONFIG_CAN_MCP251X=m -CONFIG_CAN_MCP251XFD=m -# CONFIG_CAN_MCP251XFD_SANITY is not set -# end of CAN SPI interfaces - -# -# CAN USB interfaces -# -CONFIG_CAN_8DEV_USB=m -CONFIG_CAN_EMS_USB=m -CONFIG_CAN_ESD_USB=m -CONFIG_CAN_ETAS_ES58X=m -CONFIG_CAN_GS_USB=m -CONFIG_CAN_KVASER_USB=m -CONFIG_CAN_MCBA_USB=m -CONFIG_CAN_PEAK_USB=m -CONFIG_CAN_UCAN=m -# end of CAN USB interfaces - -# CONFIG_CAN_DEBUG_DEVICES is not set - -# -# MCTP Device Drivers -# -CONFIG_MCTP_SERIAL=m -CONFIG_MCTP_TRANSPORT_I2C=m -# end of MCTP Device Drivers - -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_BUS=y -CONFIG_FWNODE_MDIO=y -CONFIG_OF_MDIO=y -CONFIG_MDIO_DEVRES=y -CONFIG_MDIO_SUN4I=y -CONFIG_MDIO_BITBANG=y -# CONFIG_MDIO_BCM_UNIMAC is not set -# CONFIG_MDIO_GPIO is not set -# CONFIG_MDIO_HISI_FEMAC is not set -CONFIG_MDIO_MVUSB=m -CONFIG_MDIO_MSCC_MIIM=m -# CONFIG_MDIO_OCTEON is not set -# CONFIG_MDIO_IPQ4019 is not set -CONFIG_MDIO_IPQ8064=m - -# -# MDIO Multiplexers -# -CONFIG_MDIO_BUS_MUX=m -# CONFIG_MDIO_BUS_MUX_GPIO is not set -CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set - -# -# PCS device drivers -# -CONFIG_PCS_XPCS=y -# end of PCS device drivers - -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOE=m -CONFIG_PPTP=m -CONFIG_PPPOL2TP=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -# CONFIG_SLIP is not set -CONFIG_SLHC=m -CONFIG_USB_NET_DRIVERS=m -CONFIG_USB_CATC=m -CONFIG_USB_KAWETH=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_RTL8152=m -CONFIG_USB_LAN78XX=m -CONFIG_USB_USBNET=m -CONFIG_USB_NET_AX8817X=m -CONFIG_USB_NET_AX88179_178A=m -CONFIG_USB_NET_CDCETHER=m -CONFIG_USB_NET_CDC_EEM=m -CONFIG_USB_NET_CDC_NCM=m -CONFIG_USB_NET_HUAWEI_CDC_NCM=m -CONFIG_USB_NET_CDC_MBIM=m -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_SR9700=m -CONFIG_USB_NET_SR9800=m -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=m -CONFIG_USB_NET_GL620A=m -CONFIG_USB_NET_NET1080=m -CONFIG_USB_NET_PLUSB=m -CONFIG_USB_NET_MCS7830=m -CONFIG_USB_NET_RNDIS_HOST=m -CONFIG_USB_NET_CDC_SUBSET_ENABLE=m -CONFIG_USB_NET_CDC_SUBSET=m -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -CONFIG_USB_BELKIN=y -CONFIG_USB_ARMLINUX=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_KC2190=y -CONFIG_USB_NET_ZAURUS=m -CONFIG_USB_NET_CX82310_ETH=m -CONFIG_USB_NET_KALMIA=m -CONFIG_USB_NET_QMI_WWAN=m -CONFIG_USB_HSO=m -CONFIG_USB_NET_INT51X1=m -CONFIG_USB_IPHETH=m -CONFIG_USB_SIERRA_NET=m -CONFIG_USB_VL600=m -CONFIG_USB_NET_CH9200=m -# CONFIG_USB_NET_AQC111 is not set -CONFIG_USB_RTL8153_ECM=m -CONFIG_WLAN=y -CONFIG_WLAN_VENDOR_ADMTEK=y -CONFIG_ATH_COMMON=m -CONFIG_WLAN_VENDOR_ATH=y -# CONFIG_ATH_DEBUG is not set -CONFIG_ATH9K_HW=m -CONFIG_ATH9K_COMMON=m -CONFIG_ATH9K_BTCOEX_SUPPORT=y -CONFIG_ATH9K=m -# CONFIG_ATH9K_AHB is not set -# CONFIG_ATH9K_DEBUGFS is not set -# CONFIG_ATH9K_DYNACK is not set -# CONFIG_ATH9K_WOW is not set -CONFIG_ATH9K_RFKILL=y -# CONFIG_ATH9K_CHANNEL_CONTEXT is not set -CONFIG_ATH9K_PCOEM=y -CONFIG_ATH9K_HTC=m -# CONFIG_ATH9K_HTC_DEBUGFS is not set -CONFIG_ATH9K_HWRNG=y -CONFIG_CARL9170=m -CONFIG_CARL9170_LEDS=y -CONFIG_CARL9170_WPC=y -CONFIG_CARL9170_HWRNG=y -# CONFIG_ATH6KL is not set -CONFIG_AR5523=m -CONFIG_ATH10K=m -CONFIG_ATH10K_CE=y -# CONFIG_ATH10K_SDIO is not set -CONFIG_ATH10K_USB=m -# CONFIG_ATH10K_DEBUG is not set -# CONFIG_ATH10K_DEBUGFS is not set -# CONFIG_WCN36XX is not set -# CONFIG_ATH11K is not set -# CONFIG_WLAN_VENDOR_ATMEL is not set -CONFIG_WLAN_VENDOR_BROADCOM=y -CONFIG_B43=m -CONFIG_B43_BCMA=y -CONFIG_B43_SSB=y -CONFIG_B43_BUSES_BCMA_AND_SSB=y -# CONFIG_B43_BUSES_BCMA is not set -# CONFIG_B43_BUSES_SSB is not set -CONFIG_B43_SDIO=y -CONFIG_B43_BCMA_PIO=y -CONFIG_B43_PIO=y -CONFIG_B43_PHY_G=y -CONFIG_B43_PHY_N=y -CONFIG_B43_PHY_LP=y -CONFIG_B43_PHY_HT=y -CONFIG_B43_LEDS=y -CONFIG_B43_HWRNG=y -# CONFIG_B43_DEBUG is not set -CONFIG_B43LEGACY=m -CONFIG_B43LEGACY_LEDS=y -CONFIG_B43LEGACY_HWRNG=y -CONFIG_B43LEGACY_DEBUG=y -CONFIG_B43LEGACY_DMA=y -CONFIG_B43LEGACY_PIO=y -CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y -# CONFIG_B43LEGACY_DMA_MODE is not set -# CONFIG_B43LEGACY_PIO_MODE is not set -CONFIG_BRCMUTIL=m -CONFIG_BRCMSMAC=m -CONFIG_BRCMFMAC=m -CONFIG_BRCMFMAC_PROTO_BCDC=y -CONFIG_BRCMFMAC_SDIO=y -# CONFIG_BRCMFMAC_USB is not set -# CONFIG_BRCM_TRACING is not set -# CONFIG_BRCMDBG is not set -# CONFIG_WLAN_VENDOR_CISCO is not set -# CONFIG_WLAN_VENDOR_INTEL is not set -# CONFIG_WLAN_VENDOR_INTERSIL is not set -# CONFIG_WLAN_VENDOR_MARVELL is not set -CONFIG_WLAN_VENDOR_MEDIATEK=y -CONFIG_MT7601U=m -CONFIG_MT76_CORE=m -CONFIG_MT76_LEDS=y -CONFIG_MT76_USB=m -CONFIG_MT76_SDIO=m -CONFIG_MT76x02_LIB=m -CONFIG_MT76x02_USB=m -CONFIG_MT76_CONNAC_LIB=m -CONFIG_MT76x0_COMMON=m -CONFIG_MT76x0U=m -CONFIG_MT76x2_COMMON=m -CONFIG_MT76x2U=m -CONFIG_MT7615_COMMON=m -CONFIG_MT7663_USB_SDIO_COMMON=m -CONFIG_MT7663U=m -# CONFIG_MT7663S is not set -CONFIG_MT7921_COMMON=m -CONFIG_MT7921S=m -CONFIG_MT7921U=m -CONFIG_WLAN_VENDOR_MICROCHIP=y -# CONFIG_WILC1000_SDIO is not set -# CONFIG_WILC1000_SPI is not set -CONFIG_WLAN_VENDOR_PURELIFI=y -CONFIG_PLFXLC=m -CONFIG_WLAN_VENDOR_RALINK=y -CONFIG_RT2X00=m -CONFIG_RT2500USB=m -CONFIG_RT73USB=m -CONFIG_RT2800USB=m -CONFIG_RT2800USB_RT33XX=y -CONFIG_RT2800USB_RT35XX=y -CONFIG_RT2800USB_RT3573=y -CONFIG_RT2800USB_RT53XX=y -CONFIG_RT2800USB_RT55XX=y -# CONFIG_RT2800USB_UNKNOWN is not set -CONFIG_RT2800_LIB=m -CONFIG_RT2X00_LIB_USB=m -CONFIG_RT2X00_LIB=m -CONFIG_RT2X00_LIB_FIRMWARE=y -CONFIG_RT2X00_LIB_CRYPTO=y -CONFIG_RT2X00_LIB_LEDS=y -# CONFIG_RT2X00_DEBUG is not set -CONFIG_WLAN_VENDOR_REALTEK=y -CONFIG_RTL8187=m -CONFIG_RTL8187_LEDS=y -CONFIG_RTL_CARDS=m -CONFIG_RTL8192CU=m -CONFIG_RTLWIFI=m -CONFIG_RTLWIFI_USB=m -# CONFIG_RTLWIFI_DEBUG is not set -CONFIG_RTL8192C_COMMON=m -CONFIG_RTL8XXXU=m -CONFIG_RTL8XXXU_UNTESTED=y -CONFIG_RTW88=m -CONFIG_RTW89=m -# CONFIG_WLAN_VENDOR_RSI is not set -CONFIG_WLAN_VENDOR_SILABS=y -CONFIG_WFX=m -# CONFIG_WLAN_VENDOR_ST is not set -# CONFIG_WLAN_VENDOR_TI is not set -CONFIG_RTL8723DU=m -CONFIG_RTL8723DS=m -# CONFIG_RTL8822BU is not set -CONFIG_RTL8821CU=m -CONFIG_88XXAU=m -CONFIG_RTL8192EU=m -CONFIG_RTL8189FS=m -CONFIG_RTL8189ES=m -# CONFIG_WLAN_VENDOR_ZYDAS is not set -CONFIG_WLAN_VENDOR_QUANTENNA=y -# CONFIG_MAC80211_HWSIM is not set -CONFIG_USB_NET_RNDIS_WLAN=m -CONFIG_VIRT_WIFI=m -# CONFIG_WAN is not set -CONFIG_IEEE802154_DRIVERS=m - -# -# Wireless WAN -# -CONFIG_WWAN=m -CONFIG_WWAN_DEBUGFS=y -CONFIG_WWAN_HWSIM=m -CONFIG_MHI_WWAN_CTRL=m -CONFIG_MHI_WWAN_MBIM=m -# end of Wireless WAN - -CONFIG_NETDEVSIM=m -CONFIG_NET_FAILOVER=m -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_LEDS=y -CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_SPARSEKMAP is not set -CONFIG_INPUT_MATRIXKMAP=m -CONFIG_INPUT_VIVALDIFMAP=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ADC is not set -# CONFIG_KEYBOARD_ADP5588 is not set -# CONFIG_KEYBOARD_ADP5589 is not set -CONFIG_KEYBOARD_ATKBD=y -CONFIG_KEYBOARD_QT1050=m -# CONFIG_KEYBOARD_QT1070 is not set -# CONFIG_KEYBOARD_QT2160 is not set -# CONFIG_KEYBOARD_DLINK_DIR685 is not set -# CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_KEYBOARD_GPIO_POLLED is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_LM8333 is not set -# CONFIG_KEYBOARD_MAX7359 is not set -# CONFIG_KEYBOARD_MCS is not set -# CONFIG_KEYBOARD_MPR121 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OPENCORES is not set -CONFIG_KEYBOARD_PINEPHONE=m -# CONFIG_KEYBOARD_SAMSUNG is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_SUN4I_LRADC is not set -CONFIG_KEYBOARD_IQS62X=m -# CONFIG_KEYBOARD_OMAP4 is not set -# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_CAP11XX is not set -# CONFIG_KEYBOARD_BCM is not set -CONFIG_KEYBOARD_CYPRESS_SF=m -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_BYD=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y -CONFIG_MOUSE_PS2_CYPRESS=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -# CONFIG_MOUSE_PS2_SENTELIC is not set -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -CONFIG_MOUSE_PS2_FOCALTECH=y -CONFIG_MOUSE_PS2_SMBUS=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_CYAPA is not set -# CONFIG_MOUSE_ELAN_I2C is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_MOUSE_GPIO is not set -# CONFIG_MOUSE_SYNAPTICS_I2C is not set -# CONFIG_MOUSE_SYNAPTICS_USB is not set -CONFIG_INPUT_JOYSTICK=y -# CONFIG_JOYSTICK_ANALOG is not set -# CONFIG_JOYSTICK_A3D is not set -# CONFIG_JOYSTICK_ADC is not set -# CONFIG_JOYSTICK_ADI is not set -# CONFIG_JOYSTICK_COBRA is not set -# CONFIG_JOYSTICK_GF2K is not set -# CONFIG_JOYSTICK_GRIP is not set -# CONFIG_JOYSTICK_GRIP_MP is not set -# CONFIG_JOYSTICK_GUILLEMOT is not set -# CONFIG_JOYSTICK_INTERACT is not set -# CONFIG_JOYSTICK_SIDEWINDER is not set -# CONFIG_JOYSTICK_TMDC is not set -CONFIG_JOYSTICK_IFORCE=m -CONFIG_JOYSTICK_IFORCE_USB=m -# CONFIG_JOYSTICK_IFORCE_232 is not set -# CONFIG_JOYSTICK_WARRIOR is not set -# CONFIG_JOYSTICK_MAGELLAN is not set -# CONFIG_JOYSTICK_SPACEORB is not set -# CONFIG_JOYSTICK_SPACEBALL is not set -# CONFIG_JOYSTICK_STINGER is not set -# CONFIG_JOYSTICK_TWIDJOY is not set -# CONFIG_JOYSTICK_ZHENHUA is not set -# CONFIG_JOYSTICK_AS5011 is not set -# CONFIG_JOYSTICK_JOYDUMP is not set -CONFIG_JOYSTICK_XPAD=m -CONFIG_JOYSTICK_XPAD_FF=y -CONFIG_JOYSTICK_XPAD_LEDS=y -# CONFIG_JOYSTICK_PSXPAD_SPI is not set -# CONFIG_JOYSTICK_PXRC is not set -CONFIG_JOYSTICK_QWIIC=m -# CONFIG_JOYSTICK_FSIA6B is not set -CONFIG_JOYSTICK_SENSEHAT=m -# CONFIG_INPUT_TABLET is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=m -CONFIG_TOUCHSCREEN_AD7877=m -CONFIG_TOUCHSCREEN_AD7879=m -CONFIG_TOUCHSCREEN_AD7879_I2C=m -CONFIG_TOUCHSCREEN_AD7879_SPI=m -CONFIG_TOUCHSCREEN_ADC=m -CONFIG_TOUCHSCREEN_AR1021_I2C=m -CONFIG_TOUCHSCREEN_ATMEL_MXT=m -# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -# CONFIG_TOUCHSCREEN_BU21013 is not set -CONFIG_TOUCHSCREEN_BU21029=m -# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set -# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set -# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set -# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set -# CONFIG_TOUCHSCREEN_DYNAPRO is not set -# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set -# CONFIG_TOUCHSCREEN_EETI is not set -# CONFIG_TOUCHSCREEN_EGALAX is not set -# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set -CONFIG_TOUCHSCREEN_EXC3000=m -# CONFIG_TOUCHSCREEN_FUJITSU is not set -CONFIG_TOUCHSCREEN_GOODIX=m -CONFIG_TOUCHSCREEN_HIDEEP=m -CONFIG_TOUCHSCREEN_HYCON_HY46XX=m -CONFIG_TOUCHSCREEN_ILI210X=m -CONFIG_TOUCHSCREEN_ILITEK=m -CONFIG_TOUCHSCREEN_S6SY761=m -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_EKTF2127 is not set -# CONFIG_TOUCHSCREEN_ELAN is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -# CONFIG_TOUCHSCREEN_WACOM_I2C is not set -CONFIG_TOUCHSCREEN_MAX11801=m -# CONFIG_TOUCHSCREEN_MCS5000 is not set -# CONFIG_TOUCHSCREEN_MMS114 is not set -# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set -CONFIG_TOUCHSCREEN_MSG2638=m -# CONFIG_TOUCHSCREEN_MTOUCH is not set -CONFIG_TOUCHSCREEN_IMAGIS=m -# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_PIXCIR is not set -# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set -CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -CONFIG_TOUCHSCREEN_USB_EGALAX=y -CONFIG_TOUCHSCREEN_USB_PANJIT=y -CONFIG_TOUCHSCREEN_USB_3M=y -CONFIG_TOUCHSCREEN_USB_ITM=y -CONFIG_TOUCHSCREEN_USB_ETURBO=y -CONFIG_TOUCHSCREEN_USB_GUNZE=y -CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y -CONFIG_TOUCHSCREEN_USB_IRTOUCH=y -CONFIG_TOUCHSCREEN_USB_IDEALTEK=y -CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y -CONFIG_TOUCHSCREEN_USB_GOTOP=y -CONFIG_TOUCHSCREEN_USB_JASTEC=y -CONFIG_TOUCHSCREEN_USB_ELO=y -CONFIG_TOUCHSCREEN_USB_E2I=y -CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y -CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y -CONFIG_TOUCHSCREEN_USB_NEXIO=y -CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y -# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -# CONFIG_TOUCHSCREEN_TSC_SERIO is not set -# CONFIG_TOUCHSCREEN_TSC2004 is not set -# CONFIG_TOUCHSCREEN_TSC2005 is not set -CONFIG_TOUCHSCREEN_TSC2007=m -# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set -# CONFIG_TOUCHSCREEN_RM_TS is not set -CONFIG_TOUCHSCREEN_SILEAD=m -# CONFIG_TOUCHSCREEN_SIS_I2C is not set -# CONFIG_TOUCHSCREEN_ST1232 is not set -# CONFIG_TOUCHSCREEN_STMFTS is not set -# CONFIG_TOUCHSCREEN_SUN4I is not set -# CONFIG_TOUCHSCREEN_SUR40 is not set -# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set -# CONFIG_TOUCHSCREEN_SX8654 is not set -# CONFIG_TOUCHSCREEN_TPS6507X is not set -# CONFIG_TOUCHSCREEN_ZET6223 is not set -# CONFIG_TOUCHSCREEN_ZFORCE is not set -CONFIG_TOUCHSCREEN_COLIBRI_VF50=m -# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set -CONFIG_TOUCHSCREEN_IQS5XX=m -# CONFIG_TOUCHSCREEN_ZINITIX is not set -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_AD714X is not set -CONFIG_INPUT_ATC260X_ONKEY=m -# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -# CONFIG_INPUT_BMA150 is not set -# CONFIG_INPUT_E3X0_BUTTON is not set -CONFIG_INPUT_MAX77650_ONKEY=m -# CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_GPIO_BEEPER is not set -CONFIG_INPUT_GPIO_DECODER=m -CONFIG_INPUT_GPIO_VIBRA=m -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_KXTJ9 is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_CM109 is not set -# CONFIG_INPUT_REGULATOR_HAPTIC is not set -CONFIG_INPUT_AXP20X_PEK=y -CONFIG_INPUT_UINPUT=m -CONFIG_INPUT_PCF8574=m -# CONFIG_INPUT_PWM_BEEPER is not set -CONFIG_INPUT_PWM_VIBRA=m -CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -CONFIG_INPUT_DA7280_HAPTICS=m -# CONFIG_INPUT_ADXL34X is not set -CONFIG_INPUT_IBM_PANEL=m -# CONFIG_INPUT_IMS_PCU is not set -# CONFIG_INPUT_IQS269A is not set -CONFIG_INPUT_IQS626A=m -CONFIG_INPUT_IQS7222=m -# CONFIG_INPUT_CMA3000 is not set -# CONFIG_INPUT_DRV260X_HAPTICS is not set -# CONFIG_INPUT_DRV2665_HAPTICS is not set -# CONFIG_INPUT_DRV2667_HAPTICS is not set -CONFIG_INPUT_RAVE_SP_PWRBUTTON=m -CONFIG_INPUT_RT5120_PWRKEY=m -CONFIG_RMI4_CORE=m -CONFIG_RMI4_I2C=m -CONFIG_RMI4_SPI=m -CONFIG_RMI4_SMB=m -CONFIG_RMI4_F03=y -CONFIG_RMI4_F03_SERIO=m -CONFIG_RMI4_2D_SENSOR=y -CONFIG_RMI4_F11=y -CONFIG_RMI4_F12=y -CONFIG_RMI4_F30=y -# CONFIG_RMI4_F34 is not set -# CONFIG_RMI4_F3A is not set -# CONFIG_RMI4_F54 is not set -# CONFIG_RMI4_F55 is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=m -CONFIG_SERIO_AMBAKMI=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_SERIO_ARC_PS2 is not set -# CONFIG_SERIO_APBPS2 is not set -# CONFIG_SERIO_SUN4I_PS2 is not set -CONFIG_SERIO_GPIO_PS2=m -# CONFIG_USERIO is not set -# CONFIG_GAMEPORT is not set -# end of Hardware I/O ports -# end of Input device support - -# -# Character devices -# -CONFIG_TTY=y -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_LDISC_AUTOLOAD=y - -# -# Serial drivers -# -CONFIG_SERIAL_EARLYCON=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -# CONFIG_SERIAL_8250_16550A_VARIANTS is not set -# CONFIG_SERIAL_8250_FINTEK is not set -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_DMA=y -CONFIG_SERIAL_8250_NR_UARTS=6 -CONFIG_SERIAL_8250_RUNTIME_UARTS=6 -# CONFIG_SERIAL_8250_EXTENDED is not set -CONFIG_SERIAL_8250_DWLIB=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_DW=y -# CONFIG_SERIAL_8250_RT288X is not set -CONFIG_SERIAL_OF_PLATFORM=y - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_AMBA_PL010 is not set -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX310X is not set -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_SIFIVE=m -# CONFIG_SERIAL_SCCNXP is not set -CONFIG_SERIAL_SC16IS7XX_CORE=m -CONFIG_SERIAL_SC16IS7XX=m -CONFIG_SERIAL_SC16IS7XX_I2C=y -# CONFIG_SERIAL_SC16IS7XX_SPI is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_SERIAL_XILINX_PS_UART=y -CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -# CONFIG_SERIAL_ARC is not set -# CONFIG_SERIAL_FSL_LPUART is not set -CONFIG_SERIAL_FSL_LINFLEXUART=m -# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -CONFIG_SERIAL_SPRD=m -CONFIG_SERIAL_LITEUART=m -CONFIG_SERIAL_LITEUART_MAX_PORTS=1 -# end of Serial drivers - -CONFIG_SERIAL_MCTRL_GPIO=y -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set -CONFIG_NULL_TTY=m -CONFIG_HVC_DRIVER=y -# CONFIG_HVC_DCC is not set -CONFIG_SERIAL_DEV_BUS=y -CONFIG_SERIAL_DEV_CTRL_TTYPORT=y -CONFIG_VIRTIO_CONSOLE=y -# CONFIG_IPMI_HANDLER is not set -# CONFIG_IPMB_DEVICE_INTERFACE is not set -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_TIMERIOMEM=m -CONFIG_HW_RANDOM_BA431=m -CONFIG_HW_RANDOM_VIRTIO=m -CONFIG_HW_RANDOM_CCTRNG=m -CONFIG_HW_RANDOM_XIPHERA=m -CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y -CONFIG_DEVMEM=y -CONFIG_TCG_TPM=y -CONFIG_HW_RANDOM_TPM=y -CONFIG_TCG_TIS_CORE=m -CONFIG_TCG_TIS=m -CONFIG_TCG_TIS_SPI=m -# CONFIG_TCG_TIS_SPI_CR50 is not set -CONFIG_TCG_TIS_I2C=m -CONFIG_TCG_TIS_I2C_CR50=m -CONFIG_TCG_TIS_I2C_ATMEL=m -CONFIG_TCG_TIS_I2C_INFINEON=m -CONFIG_TCG_TIS_I2C_NUVOTON=m -CONFIG_TCG_VTPM_PROXY=m -CONFIG_TCG_TIS_ST33ZP24=m -CONFIG_TCG_TIS_ST33ZP24_I2C=m -CONFIG_TCG_TIS_ST33ZP24_SPI=m -CONFIG_XILLYBUS_CLASS=m -# CONFIG_XILLYBUS is not set -CONFIG_XILLYUSB=m -# CONFIG_RANDOM_TRUST_CPU is not set -# CONFIG_RANDOM_TRUST_BOOTLOADER is not set -# end of Character devices - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=y - -# -# Multiplexer I2C Chip support -# -CONFIG_I2C_ARB_GPIO_CHALLENGE=m -CONFIG_I2C_MUX_GPIO=m -CONFIG_I2C_MUX_GPMUX=m -CONFIG_I2C_MUX_LTC4306=m -CONFIG_I2C_MUX_PCA9541=m -CONFIG_I2C_MUX_PCA954x=m -CONFIG_I2C_MUX_PINCTRL=m -CONFIG_I2C_MUX_REG=m -CONFIG_I2C_DEMUX_PINCTRL=m -CONFIG_I2C_MUX_MLXCPLD=m -# end of Multiplexer I2C Chip support - -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_SMBUS=m -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_ALGOPCA=m - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -CONFIG_I2C_CADENCE=m -CONFIG_I2C_CBUS_GPIO=m -CONFIG_I2C_DESIGNWARE_CORE=y -# CONFIG_I2C_DESIGNWARE_SLAVE is not set -CONFIG_I2C_DESIGNWARE_PLATFORM=y -CONFIG_I2C_EMEV2=m -CONFIG_I2C_GPIO=m -# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set -CONFIG_I2C_MV64XXX=y -CONFIG_I2C_NOMADIK=m -CONFIG_I2C_OCORES=m -CONFIG_I2C_PCA_PLATFORM=m -CONFIG_I2C_RK3X=m -CONFIG_I2C_SIMTEC=m -CONFIG_I2C_XILINX=m - -# -# External I2C/SMBus adapter drivers -# -CONFIG_I2C_DIOLAN_U2C=m -CONFIG_I2C_CP2615=m -CONFIG_I2C_ROBOTFUZZ_OSIF=m -CONFIG_I2C_TAOS_EVM=m -CONFIG_I2C_TINY_USB=m - -# -# Other I2C/SMBus bus drivers -# -CONFIG_I2C_VIRTIO=m -# end of I2C Hardware Bus support - -CONFIG_I2C_STUB=m -CONFIG_I2C_SLAVE=y -CONFIG_I2C_SLAVE_EEPROM=m -# CONFIG_I2C_SLAVE_TESTUNIT is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# end of I2C support - -CONFIG_I3C=m -CONFIG_CDNS_I3C_MASTER=m -CONFIG_DW_I3C_MASTER=m -CONFIG_SVC_I3C_MASTER=m -CONFIG_MIPI_I3C_HCI=m -CONFIG_SPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y - -# -# SPI Master Controller Drivers -# -CONFIG_SPI_ALTERA=m -CONFIG_SPI_ALTERA_CORE=m -CONFIG_SPI_AXI_SPI_ENGINE=m -CONFIG_SPI_BITBANG=m -CONFIG_SPI_CADENCE=m -# CONFIG_SPI_CADENCE_QUADSPI is not set -CONFIG_SPI_CADENCE_XSPI=m -CONFIG_SPI_DESIGNWARE=m -CONFIG_SPI_DW_DMA=y -CONFIG_SPI_DW_MMIO=m -CONFIG_SPI_NXP_FLEXSPI=m -CONFIG_SPI_GPIO=m -CONFIG_SPI_FSL_LIB=m -CONFIG_SPI_FSL_SPI=m -CONFIG_SPI_MICROCHIP_CORE=m -CONFIG_SPI_MICROCHIP_CORE_QSPI=m -CONFIG_SPI_OC_TINY=m -CONFIG_SPI_PL022=y -CONFIG_SPI_ROCKCHIP=m -CONFIG_SPI_SC18IS602=m -CONFIG_SPI_SIFIVE=m -CONFIG_SPI_SUN4I=y -CONFIG_SPI_SUN6I=y -CONFIG_SPI_MXIC=m -CONFIG_SPI_XCOMM=m -CONFIG_SPI_XILINX=m -CONFIG_SPI_ZYNQMP_GQSPI=m -CONFIG_SPI_AMD=m - -# -# SPI Multiplexer support -# -CONFIG_SPI_MUX=m - -# -# SPI Protocol Masters -# -CONFIG_SPI_SPIDEV=m -CONFIG_SPI_LOOPBACK_TEST=m -CONFIG_SPI_TLE62X0=m -CONFIG_SPI_SLAVE=y -CONFIG_SPI_SLAVE_TIME=m -CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m -CONFIG_SPI_DYNAMIC=y -CONFIG_SPMI=y -# CONFIG_SPMI_HISI3670 is not set -# CONFIG_HSI is not set -CONFIG_PPS=y -# CONFIG_PPS_DEBUG is not set - -# -# PPS clients support -# -# CONFIG_PPS_CLIENT_KTIMER is not set -CONFIG_PPS_CLIENT_LDISC=m -CONFIG_PPS_CLIENT_GPIO=m - -# -# PPS generators support -# - -# -# PTP clock support -# -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -# CONFIG_DP83640_PHY is not set -CONFIG_PTP_1588_CLOCK_INES=m -CONFIG_PTP_1588_CLOCK_KVM=m -CONFIG_PTP_1588_CLOCK_IDT82P33=m -CONFIG_PTP_1588_CLOCK_IDTCM=m -# end of PTP clock support - -CONFIG_PINCTRL=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_PINMUX=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_PINCONF=y -CONFIG_GENERIC_PINCONF=y -CONFIG_PINCTRL_AXP209=m -CONFIG_PINCTRL_CY8C95X0=m -# CONFIG_PINCTRL_MCP23S08 is not set -# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set -# CONFIG_PINCTRL_OCELOT is not set -CONFIG_PINCTRL_SINGLE=y -CONFIG_PINCTRL_STMFX=m -# CONFIG_PINCTRL_SX150X is not set -CONFIG_PINCTRL_MADERA=m - -# -# Renesas pinctrl drivers -# -# end of Renesas pinctrl drivers - -CONFIG_PINCTRL_SUNXI=y -# CONFIG_PINCTRL_SUN4I_A10 is not set -# CONFIG_PINCTRL_SUN5I is not set -# CONFIG_PINCTRL_SUN6I_A31 is not set -# CONFIG_PINCTRL_SUN6I_A31_R is not set -# CONFIG_PINCTRL_SUN8I_A23 is not set -# CONFIG_PINCTRL_SUN8I_A33 is not set -# CONFIG_PINCTRL_SUN8I_A83T is not set -# CONFIG_PINCTRL_SUN8I_A83T_R is not set -# CONFIG_PINCTRL_SUN8I_A23_R is not set -# CONFIG_PINCTRL_SUN8I_H3 is not set -CONFIG_PINCTRL_SUN8I_H3_R=y -# CONFIG_PINCTRL_SUN8I_V3S is not set -# CONFIG_PINCTRL_SUN9I_A80 is not set -# CONFIG_PINCTRL_SUN9I_A80_R is not set -CONFIG_PINCTRL_SUN20I_D1=y -CONFIG_PINCTRL_SUN50I_A64=y -CONFIG_PINCTRL_SUN50I_A64_R=y -CONFIG_PINCTRL_SUN50I_A100=y -CONFIG_PINCTRL_SUN50I_A100_R=y -CONFIG_PINCTRL_SUN50I_H5=y -CONFIG_PINCTRL_SUN50I_H6=y -CONFIG_PINCTRL_SUN50I_H6_R=y -CONFIG_PINCTRL_SUN50I_H616=y -CONFIG_PINCTRL_SUN50I_H616_R=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_FASTPATH_LIMIT=512 -CONFIG_OF_GPIO=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_CDEV_V1=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_MAX730X=m - -# -# Memory mapped GPIO drivers -# -# CONFIG_GPIO_74XX_MMIO is not set -# CONFIG_GPIO_ALTERA is not set -CONFIG_GPIO_CADENCE=m -CONFIG_GPIO_DWAPB=y -# CONFIG_GPIO_FTGPIO010 is not set -CONFIG_GPIO_GENERIC_PLATFORM=y -# CONFIG_GPIO_GRGPIO is not set -CONFIG_GPIO_HLWD=m -CONFIG_GPIO_LOGICVC=m -# CONFIG_GPIO_MB86S7X is not set -# CONFIG_GPIO_PL061 is not set -# CONFIG_GPIO_SIFIVE is not set -CONFIG_GPIO_SYSCON=m -# CONFIG_GPIO_XGENE is not set -# CONFIG_GPIO_XILINX is not set -CONFIG_GPIO_AMD_FCH=m -# end of Memory mapped GPIO drivers - -# -# I2C GPIO expanders -# -CONFIG_GPIO_ADNP=m -CONFIG_GPIO_GW_PLD=m -CONFIG_GPIO_MAX7300=m -CONFIG_GPIO_MAX732X=m -CONFIG_GPIO_PCA953X=m -# CONFIG_GPIO_PCA953X_IRQ is not set -# CONFIG_GPIO_PCA9570 is not set -CONFIG_GPIO_PCF857X=m -CONFIG_GPIO_TPIC2810=m -# end of I2C GPIO expanders - -# -# MFD GPIO expanders -# -CONFIG_GPIO_BD71815=m -CONFIG_GPIO_BD71828=m -CONFIG_GPIO_BD9571MWV=m -CONFIG_GPIO_MADERA=m -CONFIG_GPIO_MAX77650=m -# end of MFD GPIO expanders - -# -# SPI GPIO expanders -# -CONFIG_GPIO_74X164=m -CONFIG_GPIO_MAX3191X=m -CONFIG_GPIO_MAX7301=m -CONFIG_GPIO_MC33880=m -CONFIG_GPIO_PISOSR=m -CONFIG_GPIO_XRA1403=m -# end of SPI GPIO expanders - -# -# USB GPIO expanders -# -# end of USB GPIO expanders - -# -# Virtual GPIO drivers -# -CONFIG_GPIO_AGGREGATOR=m -CONFIG_GPIO_MOCKUP=m -CONFIG_GPIO_VIRTIO=m -# CONFIG_GPIO_SIM is not set -# end of Virtual GPIO drivers - -CONFIG_W1=m -CONFIG_W1_CON=y - -# -# 1-wire Bus Masters -# -CONFIG_W1_MASTER_DS2490=m -CONFIG_W1_MASTER_DS2482=m -CONFIG_W1_MASTER_DS1WM=m -CONFIG_W1_MASTER_GPIO=m -CONFIG_W1_MASTER_SGI=m -# end of 1-wire Bus Masters - -# -# 1-wire Slaves -# -CONFIG_W1_SLAVE_THERM=m -CONFIG_W1_SLAVE_SMEM=m -CONFIG_W1_SLAVE_DS2405=m -CONFIG_W1_SLAVE_DS2408=m -CONFIG_W1_SLAVE_DS2408_READBACK=y -CONFIG_W1_SLAVE_DS2413=m -CONFIG_W1_SLAVE_DS2406=m -CONFIG_W1_SLAVE_DS2423=m -CONFIG_W1_SLAVE_DS2805=m -CONFIG_W1_SLAVE_DS2430=m -CONFIG_W1_SLAVE_DS2431=m -CONFIG_W1_SLAVE_DS2433=m -# CONFIG_W1_SLAVE_DS2433_CRC is not set -# CONFIG_W1_SLAVE_DS2438 is not set -CONFIG_W1_SLAVE_DS250X=m -CONFIG_W1_SLAVE_DS2780=m -CONFIG_W1_SLAVE_DS2781=m -CONFIG_W1_SLAVE_DS28E04=m -CONFIG_W1_SLAVE_DS28E17=m -# end of 1-wire Slaves - -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_ATC260X=m -# CONFIG_POWER_RESET_BRCMSTB is not set -# CONFIG_POWER_RESET_GPIO is not set -# CONFIG_POWER_RESET_GPIO_RESTART is not set -# CONFIG_POWER_RESET_LTC2952 is not set -# CONFIG_POWER_RESET_REGULATOR is not set -# CONFIG_POWER_RESET_RESTART is not set -# CONFIG_POWER_RESET_XGENE is not set -CONFIG_POWER_RESET_SYSCON=y -# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -# CONFIG_SYSCON_REBOOT_MODE is not set -# CONFIG_NVMEM_REBOOT_MODE is not set -CONFIG_POWER_SUPPLY=y -# CONFIG_POWER_SUPPLY_DEBUG is not set -CONFIG_POWER_SUPPLY_HWMON=y -# CONFIG_PDA_POWER is not set -# CONFIG_GENERIC_ADC_BATTERY is not set -CONFIG_IP5XXX_POWER=m -# CONFIG_TEST_POWER is not set -CONFIG_CHARGER_ADP5061=m -CONFIG_BATTERY_CW2015=m -CONFIG_BATTERY_DS2760=m -CONFIG_BATTERY_DS2780=m -CONFIG_BATTERY_DS2781=m -CONFIG_BATTERY_DS2782=m -# CONFIG_BATTERY_SAMSUNG_SDI is not set -CONFIG_BATTERY_SBS=m -CONFIG_CHARGER_SBS=m -CONFIG_MANAGER_SBS=m -CONFIG_BATTERY_BQ27XXX=m -CONFIG_BATTERY_BQ27XXX_I2C=m -CONFIG_BATTERY_BQ27XXX_HDQ=m -# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set -CONFIG_CHARGER_AXP20X=m -CONFIG_BATTERY_AXP20X=m -CONFIG_AXP20X_POWER=m -# CONFIG_BATTERY_MAX17040 is not set -# CONFIG_BATTERY_MAX17042 is not set -CONFIG_BATTERY_MAX1721X=m -# CONFIG_CHARGER_ISP1704 is not set -# CONFIG_CHARGER_MAX8903 is not set -# CONFIG_CHARGER_LP8727 is not set -CONFIG_CHARGER_GPIO=m -# CONFIG_CHARGER_MANAGER is not set -CONFIG_CHARGER_LT3651=m -CONFIG_CHARGER_LTC4162L=m -CONFIG_CHARGER_DETECTOR_MAX14656=m -CONFIG_CHARGER_MAX77650=m -CONFIG_CHARGER_MAX77976=m -CONFIG_CHARGER_MT6370=m -# CONFIG_CHARGER_BQ2415X is not set -# CONFIG_CHARGER_BQ24190 is not set -# CONFIG_CHARGER_BQ24257 is not set -# CONFIG_CHARGER_BQ24735 is not set -# CONFIG_CHARGER_BQ2515X is not set -# CONFIG_CHARGER_BQ25890 is not set -# CONFIG_CHARGER_BQ25980 is not set -CONFIG_CHARGER_BQ256XX=m -# CONFIG_CHARGER_SMB347 is not set -# CONFIG_BATTERY_GAUGE_LTC2941 is not set -CONFIG_BATTERY_GOLDFISH=m -CONFIG_BATTERY_RT5033=m -# CONFIG_CHARGER_RT9455 is not set -CONFIG_CHARGER_UCS1002=m -# CONFIG_CHARGER_BD99954 is not set -CONFIG_BATTERY_UG3105=m -CONFIG_HWMON=y -CONFIG_HWMON_VID=m -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -CONFIG_SENSORS_AD7314=m -CONFIG_SENSORS_AD7414=m -CONFIG_SENSORS_AD7418=m -CONFIG_SENSORS_ADM1025=m -CONFIG_SENSORS_ADM1026=m -CONFIG_SENSORS_ADM1029=m -CONFIG_SENSORS_ADM1031=m -CONFIG_SENSORS_ADM1177=m -CONFIG_SENSORS_ADM9240=m -CONFIG_SENSORS_ADT7X10=m -CONFIG_SENSORS_ADT7310=m -CONFIG_SENSORS_ADT7410=m -CONFIG_SENSORS_ADT7411=m -CONFIG_SENSORS_ADT7462=m -CONFIG_SENSORS_ADT7470=m -CONFIG_SENSORS_ADT7475=m -CONFIG_SENSORS_AHT10=m -CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=m -CONFIG_SENSORS_AS370=m -CONFIG_SENSORS_ASC7621=m -CONFIG_SENSORS_AXI_FAN_CONTROL=m -CONFIG_SENSORS_ARM_SCMI=m -CONFIG_SENSORS_ARM_SCPI=m -CONFIG_SENSORS_ATXP1=m -# CONFIG_SENSORS_CORSAIR_CPRO is not set -CONFIG_SENSORS_CORSAIR_PSU=m -CONFIG_SENSORS_DRIVETEMP=m -CONFIG_SENSORS_DS620=m -CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_F71805F=m -CONFIG_SENSORS_F71882FG=m -CONFIG_SENSORS_F75375S=m -CONFIG_SENSORS_FTSTEUTATES=m -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_GL520SM=m -CONFIG_SENSORS_G760A=m -CONFIG_SENSORS_G762=m -CONFIG_SENSORS_GPIO_FAN=m -CONFIG_SENSORS_HIH6130=m -CONFIG_SENSORS_IIO_HWMON=m -CONFIG_SENSORS_IT87=m -CONFIG_SENSORS_JC42=m -CONFIG_SENSORS_POWR1220=m -CONFIG_SENSORS_LINEAGE=m -CONFIG_SENSORS_LTC2945=m -CONFIG_SENSORS_LTC2947=m -CONFIG_SENSORS_LTC2947_I2C=m -# CONFIG_SENSORS_LTC2947_SPI is not set -CONFIG_SENSORS_LTC2990=m -CONFIG_SENSORS_LTC2992=m -CONFIG_SENSORS_LTC4151=m -CONFIG_SENSORS_LTC4215=m -CONFIG_SENSORS_LTC4222=m -CONFIG_SENSORS_LTC4245=m -CONFIG_SENSORS_LTC4260=m -CONFIG_SENSORS_LTC4261=m -CONFIG_SENSORS_MAX1111=m -CONFIG_SENSORS_MAX127=m -CONFIG_SENSORS_MAX16065=m -CONFIG_SENSORS_MAX1619=m -CONFIG_SENSORS_MAX1668=m -CONFIG_SENSORS_MAX197=m -CONFIG_SENSORS_MAX31722=m -CONFIG_SENSORS_MAX31730=m -CONFIG_SENSORS_MAX31760=m -CONFIG_SENSORS_MAX6620=m -CONFIG_SENSORS_MAX6621=m -CONFIG_SENSORS_MAX6639=m -CONFIG_SENSORS_MAX6650=m -CONFIG_SENSORS_MAX6697=m -CONFIG_SENSORS_MAX31790=m -CONFIG_SENSORS_MCP3021=m -CONFIG_SENSORS_TC654=m -CONFIG_SENSORS_TPS23861=m -# CONFIG_SENSORS_MR75203 is not set -CONFIG_SENSORS_ADCXX=m -CONFIG_SENSORS_LM63=m -CONFIG_SENSORS_LM70=m -CONFIG_SENSORS_LM73=m -CONFIG_SENSORS_LM75=m -CONFIG_SENSORS_LM77=m -CONFIG_SENSORS_LM78=m -CONFIG_SENSORS_LM80=m -CONFIG_SENSORS_LM83=m -CONFIG_SENSORS_LM85=m -CONFIG_SENSORS_LM87=m -CONFIG_SENSORS_LM90=m -CONFIG_SENSORS_LM92=m -CONFIG_SENSORS_LM93=m -CONFIG_SENSORS_LM95234=m -CONFIG_SENSORS_LM95241=m -CONFIG_SENSORS_LM95245=m -CONFIG_SENSORS_PC87360=m -CONFIG_SENSORS_PC87427=m -CONFIG_SENSORS_NTC_THERMISTOR=m -CONFIG_SENSORS_NCT6683=m -CONFIG_SENSORS_NCT6775_CORE=m -CONFIG_SENSORS_NCT6775=m -CONFIG_SENSORS_NCT6775_I2C=m -CONFIG_SENSORS_NCT7802=m -CONFIG_SENSORS_NCT7904=m -CONFIG_SENSORS_NPCM7XX=m -CONFIG_SENSORS_NZXT_KRAKEN2=m -CONFIG_SENSORS_NZXT_SMART2=m -CONFIG_SENSORS_OCC_P8_I2C=m -CONFIG_SENSORS_OCC=m -CONFIG_SENSORS_PCF8591=m -CONFIG_SENSORS_PECI_CPUTEMP=m -CONFIG_SENSORS_PECI_DIMMTEMP=m -CONFIG_SENSORS_PECI=m -CONFIG_PMBUS=m -CONFIG_SENSORS_PMBUS=m -# CONFIG_SENSORS_ADM1266 is not set -CONFIG_SENSORS_ADM1275=m -CONFIG_SENSORS_BEL_PFE=m -CONFIG_SENSORS_BPA_RS600=m -CONFIG_SENSORS_DELTA_AHE50DC_FAN=m -CONFIG_SENSORS_FSP_3Y=m -CONFIG_SENSORS_IBM_CFFPS=m -CONFIG_SENSORS_DPS920AB=m -CONFIG_SENSORS_INSPUR_IPSPS=m -CONFIG_SENSORS_IR35221=m -CONFIG_SENSORS_IR36021=m -CONFIG_SENSORS_IR38064=m -# CONFIG_SENSORS_IR38064_REGULATOR is not set -# CONFIG_SENSORS_IRPS5401 is not set -CONFIG_SENSORS_ISL68137=m -CONFIG_SENSORS_LM25066=m -# CONFIG_SENSORS_LM25066_REGULATOR is not set -CONFIG_SENSORS_LT7182S=m -# CONFIG_SENSORS_LTC2978 is not set -CONFIG_SENSORS_LTC3815=m -CONFIG_SENSORS_MAX15301=m -CONFIG_SENSORS_MAX16064=m -CONFIG_SENSORS_MAX16601=m -CONFIG_SENSORS_MAX20730=m -CONFIG_SENSORS_MAX20751=m -CONFIG_SENSORS_MAX31785=m -CONFIG_SENSORS_MAX34440=m -CONFIG_SENSORS_MAX8688=m -CONFIG_SENSORS_MP2888=m -# CONFIG_SENSORS_MP2975 is not set -CONFIG_SENSORS_MP5023=m -CONFIG_SENSORS_PIM4328=m -# CONFIG_SENSORS_PLI1209BC is not set -CONFIG_SENSORS_PM6764TR=m -# CONFIG_SENSORS_PXE1610 is not set -CONFIG_SENSORS_Q54SJ108A2=m -CONFIG_SENSORS_STPDDC60=m -CONFIG_SENSORS_TPS40422=m -CONFIG_SENSORS_TPS53679=m -CONFIG_SENSORS_TPS546D24=m -CONFIG_SENSORS_UCD9000=m -CONFIG_SENSORS_UCD9200=m -CONFIG_SENSORS_XDPE152=m -CONFIG_SENSORS_XDPE122=m -# CONFIG_SENSORS_XDPE122_REGULATOR is not set -CONFIG_SENSORS_ZL6100=m -CONFIG_SENSORS_PWM_FAN=m -CONFIG_SENSORS_SBTSI=m -CONFIG_SENSORS_SBRMI=m -CONFIG_SENSORS_SHT15=m -CONFIG_SENSORS_SHT21=m -CONFIG_SENSORS_SHT3x=m -CONFIG_SENSORS_SHT4x=m -CONFIG_SENSORS_SHTC1=m -CONFIG_SENSORS_SY7636A=m -CONFIG_SENSORS_DME1737=m -CONFIG_SENSORS_EMC1403=m -CONFIG_SENSORS_EMC2103=m -CONFIG_SENSORS_EMC2305=m -CONFIG_SENSORS_EMC6W201=m -CONFIG_SENSORS_SMSC47M1=m -CONFIG_SENSORS_SMSC47M192=m -CONFIG_SENSORS_SMSC47B397=m -CONFIG_SENSORS_SCH56XX_COMMON=m -CONFIG_SENSORS_SCH5627=m -CONFIG_SENSORS_SCH5636=m -CONFIG_SENSORS_STTS751=m -CONFIG_SENSORS_SMM665=m -CONFIG_SENSORS_ADC128D818=m -CONFIG_SENSORS_ADS7828=m -CONFIG_SENSORS_ADS7871=m -CONFIG_SENSORS_AMC6821=m -CONFIG_SENSORS_INA209=m -CONFIG_SENSORS_INA2XX=m -CONFIG_SENSORS_INA238=m -CONFIG_SENSORS_INA3221=m -CONFIG_SENSORS_TC74=m -CONFIG_SENSORS_THMC50=m -CONFIG_SENSORS_TMP102=m -CONFIG_SENSORS_TMP103=m -CONFIG_SENSORS_TMP108=m -CONFIG_SENSORS_TMP401=m -CONFIG_SENSORS_TMP421=m -CONFIG_SENSORS_TMP464=m -CONFIG_SENSORS_TMP513=m -CONFIG_SENSORS_VT1211=m -CONFIG_SENSORS_W83773G=m -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_W83791D=m -CONFIG_SENSORS_W83792D=m -CONFIG_SENSORS_W83793=m -CONFIG_SENSORS_W83795=m -# CONFIG_SENSORS_W83795_FANCTRL is not set -CONFIG_SENSORS_W83L785TS=m -CONFIG_SENSORS_W83L786NG=m -CONFIG_SENSORS_W83627HF=m -CONFIG_SENSORS_W83627EHF=m -CONFIG_THERMAL=y -# CONFIG_THERMAL_NETLINK is not set -# CONFIG_THERMAL_STATISTICS is not set -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_HWMON=y -CONFIG_THERMAL_OF=y -CONFIG_THERMAL_WRITABLE_TRIPS=y -# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set -CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE=y -# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -CONFIG_THERMAL_GOV_FAIR_SHARE=y -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_GOV_BANG_BANG=y -CONFIG_THERMAL_GOV_USER_SPACE=y -CONFIG_CPU_THERMAL=y -CONFIG_CPU_FREQ_THERMAL=y -CONFIG_DEVFREQ_THERMAL=y -CONFIG_THERMAL_EMULATION=y -CONFIG_THERMAL_MMIO=m -CONFIG_SUN8I_THERMAL=y -CONFIG_GENERIC_ADC_THERMAL=m -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WATCHDOG_NOWAYOUT is not set -CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y -CONFIG_WATCHDOG_OPEN_TIMEOUT=0 -# CONFIG_WATCHDOG_SYSFS is not set -# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set - -# -# Watchdog Pretimeout Governors -# -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set - -# -# Watchdog Device Drivers -# -CONFIG_SOFT_WATCHDOG=m -CONFIG_BD957XMUF_WATCHDOG=m -CONFIG_GPIO_WATCHDOG=m -# CONFIG_XILINX_WATCHDOG is not set -# CONFIG_ZIIRAVE_WATCHDOG is not set -CONFIG_RAVE_SP_WATCHDOG=m -CONFIG_ARM_SP805_WATCHDOG=m -CONFIG_ARM_SBSA_WATCHDOG=m -# CONFIG_CADENCE_WATCHDOG is not set -# CONFIG_DW_WATCHDOG is not set -CONFIG_SUNXI_WATCHDOG=y -# CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_MAX77620_WATCHDOG=m -# CONFIG_ARM_SMC_WATCHDOG is not set -# CONFIG_MEN_A21_WDT is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -CONFIG_SSB_POSSIBLE=y -CONFIG_SSB=m -CONFIG_SSB_BLOCKIO=y -CONFIG_SSB_SDIOHOST_POSSIBLE=y -CONFIG_SSB_SDIOHOST=y -# CONFIG_SSB_DRIVER_GPIO is not set -CONFIG_BCMA_POSSIBLE=y -CONFIG_BCMA=m -CONFIG_BCMA_BLOCKIO=y -# CONFIG_BCMA_HOST_SOC is not set -# CONFIG_BCMA_DRIVER_GMAC_CMN is not set -# CONFIG_BCMA_DRIVER_GPIO is not set -# CONFIG_BCMA_DEBUG is not set - -# -# Multifunction device drivers -# -CONFIG_MFD_CORE=y -# CONFIG_MFD_ACT8945A is not set -CONFIG_MFD_SUN4I_GPADC=y -# CONFIG_MFD_AS3711 is not set -# CONFIG_MFD_AS3722 is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_ATMEL_FLEXCOM is not set -# CONFIG_MFD_ATMEL_HLCDC is not set -# CONFIG_MFD_BCM590XX is not set -CONFIG_MFD_BD9571MWV=m -CONFIG_MFD_AC100=y -CONFIG_MFD_AC200=y -CONFIG_MFD_AXP20X=y -CONFIG_MFD_AXP20X_I2C=y -CONFIG_MFD_AXP20X_RSB=y -CONFIG_MFD_MADERA=m -CONFIG_MFD_MADERA_I2C=m -# CONFIG_MFD_MADERA_SPI is not set -# CONFIG_MFD_CS47L15 is not set -# CONFIG_MFD_CS47L35 is not set -# CONFIG_MFD_CS47L85 is not set -# CONFIG_MFD_CS47L90 is not set -# CONFIG_MFD_CS47L92 is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_DA9052_SPI is not set -# CONFIG_MFD_DA9052_I2C is not set -# CONFIG_MFD_DA9055 is not set -# CONFIG_MFD_DA9062 is not set -# CONFIG_MFD_DA9063 is not set -# CONFIG_MFD_DA9150 is not set -# CONFIG_MFD_DLN2 is not set -# CONFIG_MFD_GATEWORKS_GSC is not set -# CONFIG_MFD_MC13XXX_SPI is not set -# CONFIG_MFD_MC13XXX_I2C is not set -# CONFIG_MFD_MP2629 is not set -# CONFIG_MFD_HI6421_PMIC is not set -# CONFIG_MFD_HI6421_SPMI is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -CONFIG_MFD_IQS62X=m -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_88PM800 is not set -# CONFIG_MFD_88PM805 is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_MAX14577 is not set -# CONFIG_MFD_MAX77620 is not set -CONFIG_MFD_MAX77650=m -# CONFIG_MFD_MAX77686 is not set -# CONFIG_MFD_MAX77693 is not set -CONFIG_MFD_MAX77714=m -# CONFIG_MFD_MAX77843 is not set -# CONFIG_MFD_MAX8907 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_MT6360 is not set -CONFIG_MFD_MT6370=m -# CONFIG_MFD_MT6397 is not set -# CONFIG_MFD_MENF21BMC is not set -CONFIG_MFD_OCELOT=m -# CONFIG_EZX_PCAP is not set -# CONFIG_MFD_CPCAP is not set -# CONFIG_MFD_VIPERBOARD is not set -CONFIG_MFD_NTXEC=m -# CONFIG_MFD_RETU is not set -# CONFIG_MFD_PCF50633 is not set -CONFIG_MFD_SY7636A=m -CONFIG_MFD_RT4831=m -# CONFIG_MFD_RT5033 is not set -CONFIG_MFD_RT5120=m -# CONFIG_MFD_RC5T583 is not set -# CONFIG_MFD_RK808 is not set -# CONFIG_MFD_RN5T618 is not set -CONFIG_MFD_SEC_CORE=y -# CONFIG_MFD_SI476X_CORE is not set -CONFIG_MFD_SIMPLE_MFD_I2C=m -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_SKY81452 is not set -# CONFIG_MFD_STMPE is not set -CONFIG_MFD_SUN6I_PRCM=y -CONFIG_MFD_SYSCON=y -# CONFIG_MFD_LP3943 is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_TI_LMU is not set -# CONFIG_MFD_PALMAS is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_MFD_TPS65086 is not set -# CONFIG_MFD_TPS65090 is not set -# CONFIG_MFD_TPS65217 is not set -# CONFIG_MFD_TI_LP873X is not set -# CONFIG_MFD_TI_LP87565 is not set -# CONFIG_MFD_TPS65218 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_TWL6040_CORE is not set -CONFIG_MFD_WL1273_CORE=m -# CONFIG_MFD_LM3533 is not set -# CONFIG_MFD_TC3589X is not set -CONFIG_MFD_TQMX86=m -# CONFIG_MFD_LOCHNAGAR is not set -# CONFIG_MFD_ARIZONA_I2C is not set -# CONFIG_MFD_ARIZONA_SPI is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -CONFIG_MFD_ROHM_BD718XX=m -CONFIG_MFD_ROHM_BD71828=m -CONFIG_MFD_ROHM_BD957XMUF=m -# CONFIG_MFD_STPMIC1 is not set -CONFIG_MFD_STMFX=m -CONFIG_MFD_ATC260X=m -CONFIG_MFD_ATC260X_I2C=m -CONFIG_MFD_QCOM_PM8008=m -CONFIG_RAVE_SP_CORE=m -# CONFIG_MFD_INTEL_M10_BMC is not set -CONFIG_MFD_RSMU_I2C=m -# CONFIG_MFD_RSMU_SPI is not set -# end of Multifunction device drivers - -CONFIG_REGULATOR=y -# CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_FIXED_VOLTAGE=y -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -CONFIG_REGULATOR_88PG86X=m -# CONFIG_REGULATOR_ACT8865 is not set -# CONFIG_REGULATOR_AD5398 is not set -# CONFIG_REGULATOR_ARIZONA_LDO1 is not set -# CONFIG_REGULATOR_ARIZONA_MICSUPP is not set -CONFIG_REGULATOR_ARM_SCMI=m -CONFIG_REGULATOR_ATC260X=m -CONFIG_REGULATOR_AXP20X=y -CONFIG_REGULATOR_BD71815=m -CONFIG_REGULATOR_BD71828=m -CONFIG_REGULATOR_BD718XX=m -CONFIG_REGULATOR_BD9571MWV=m -CONFIG_REGULATOR_BD957XMUF=m -CONFIG_REGULATOR_DA9121=m -# CONFIG_REGULATOR_DA9210 is not set -# CONFIG_REGULATOR_DA9211 is not set -# CONFIG_REGULATOR_FAN53555 is not set -# CONFIG_REGULATOR_FAN53880 is not set -CONFIG_REGULATOR_GPIO=y -# CONFIG_REGULATOR_ISL9305 is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -# CONFIG_REGULATOR_LP872X is not set -# CONFIG_REGULATOR_LP8755 is not set -# CONFIG_REGULATOR_LTC3589 is not set -# CONFIG_REGULATOR_LTC3676 is not set -# CONFIG_REGULATOR_MAX1586 is not set -CONFIG_REGULATOR_MAX77650=m -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -CONFIG_REGULATOR_MAX8893=m -# CONFIG_REGULATOR_MAX8952 is not set -# CONFIG_REGULATOR_MAX8973 is not set -CONFIG_REGULATOR_MAX20086=m -# CONFIG_REGULATOR_MAX77826 is not set -CONFIG_REGULATOR_MCP16502=m -CONFIG_REGULATOR_MP5416=m -CONFIG_REGULATOR_MP8859=m -CONFIG_REGULATOR_MP886X=m -CONFIG_REGULATOR_MPQ7920=m -# CONFIG_REGULATOR_MT6311 is not set -CONFIG_REGULATOR_MT6315=m -CONFIG_REGULATOR_MT6370=m -# CONFIG_REGULATOR_PCA9450 is not set -CONFIG_REGULATOR_PF8X00=m -# CONFIG_REGULATOR_PFUZE100 is not set -# CONFIG_REGULATOR_PV88060 is not set -# CONFIG_REGULATOR_PV88080 is not set -# CONFIG_REGULATOR_PV88090 is not set -# CONFIG_REGULATOR_PWM is not set -CONFIG_REGULATOR_QCOM_SPMI=y -# CONFIG_REGULATOR_QCOM_USB_VBUS is not set -# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set -CONFIG_REGULATOR_ROHM=m -# CONFIG_REGULATOR_RT4801 is not set -CONFIG_REGULATOR_RT4831=m -CONFIG_REGULATOR_RT5120=m -CONFIG_REGULATOR_RT5190A=m -CONFIG_REGULATOR_RT5759=m -CONFIG_REGULATOR_RT6160=m -CONFIG_REGULATOR_RT6245=m -CONFIG_REGULATOR_RTQ2134=m -# CONFIG_REGULATOR_RTMV20 is not set -CONFIG_REGULATOR_RTQ6752=m -# CONFIG_REGULATOR_S2MPA01 is not set -CONFIG_REGULATOR_S2MPS11=y -# CONFIG_REGULATOR_S5M8767 is not set -# CONFIG_REGULATOR_SLG51000 is not set -CONFIG_REGULATOR_SY7636A=m -CONFIG_REGULATOR_SY8106A=m -CONFIG_REGULATOR_SY8824X=m -# CONFIG_REGULATOR_SY8827N is not set -# CONFIG_REGULATOR_TPS51632 is not set -# CONFIG_REGULATOR_TPS62360 is not set -CONFIG_REGULATOR_TPS6286X=m -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_TPS65132 is not set -# CONFIG_REGULATOR_TPS6524X is not set -# CONFIG_REGULATOR_VCTRL is not set -# CONFIG_REGULATOR_QCOM_LABIBB is not set -CONFIG_RC_CORE=m -CONFIG_LIRC=y -CONFIG_RC_MAP=m -CONFIG_RC_DECODERS=y -CONFIG_IR_IMON_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_MCE_KBD_DECODER=m -CONFIG_IR_NEC_DECODER=m -CONFIG_IR_RC5_DECODER=m -CONFIG_IR_RC6_DECODER=m -CONFIG_IR_RCMM_DECODER=m -CONFIG_IR_SANYO_DECODER=m -CONFIG_IR_SHARP_DECODER=m -CONFIG_IR_SONY_DECODER=m -CONFIG_IR_XMP_DECODER=m -CONFIG_RC_DEVICES=y -CONFIG_IR_GPIO_CIR=m -CONFIG_IR_GPIO_TX=m -# CONFIG_IR_HIX5HD2 is not set -# CONFIG_IR_IGORPLUGUSB is not set -# CONFIG_IR_IGUANA is not set -# CONFIG_IR_IMON is not set -CONFIG_IR_IMON_RAW=m -# CONFIG_IR_MCEUSB is not set -CONFIG_IR_PWM_TX=m -# CONFIG_IR_REDRAT3 is not set -# CONFIG_IR_SERIAL is not set -CONFIG_IR_SPI=m -# CONFIG_IR_STREAMZAP is not set -CONFIG_IR_SUNXI=m -# CONFIG_IR_TOY is not set -# CONFIG_IR_TTUSBIR is not set -# CONFIG_RC_ATI_REMOTE is not set -# CONFIG_RC_LOOPBACK is not set -CONFIG_RC_XBOX_DVD=m -CONFIG_CEC_CORE=y -CONFIG_CEC_NOTIFIER=y - -# -# CEC support -# -# CONFIG_MEDIA_CEC_SUPPORT is not set -# end of CEC support - -CONFIG_MEDIA_SUPPORT=m -CONFIG_MEDIA_SUPPORT_FILTER=y -CONFIG_MEDIA_SUBDRV_AUTOSELECT=y - -# -# Media device types -# -CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -CONFIG_MEDIA_RADIO_SUPPORT=y -CONFIG_MEDIA_SDR_SUPPORT=y -CONFIG_MEDIA_PLATFORM_SUPPORT=y -CONFIG_MEDIA_TEST_SUPPORT=y -# end of Media device types - -CONFIG_VIDEO_DEV=m -CONFIG_MEDIA_CONTROLLER=y -CONFIG_DVB_CORE=m - -# -# Video4Linux options -# -CONFIG_VIDEO_V4L2_I2C=y -CONFIG_VIDEO_V4L2_SUBDEV_API=y -# CONFIG_VIDEO_ADV_DEBUG is not set -CONFIG_VIDEO_FIXED_MINOR_RANGES=y -CONFIG_VIDEO_TUNER=m -CONFIG_V4L2_MEM2MEM_DEV=m -CONFIG_V4L2_FWNODE=m -CONFIG_V4L2_ASYNC=m -# end of Video4Linux options - -# -# Media controller options -# -CONFIG_MEDIA_CONTROLLER_DVB=y -CONFIG_MEDIA_CONTROLLER_REQUEST_API=y -# end of Media controller options - -# -# Digital TV options -# -# CONFIG_DVB_MMAP is not set -CONFIG_DVB_NET=y -CONFIG_DVB_MAX_ADAPTERS=8 -CONFIG_DVB_DYNAMIC_MINORS=y -# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set -# CONFIG_DVB_ULE_DEBUG is not set -# end of Digital TV options - -# -# Media drivers -# - -# -# Drivers filtered as selected at 'Filter media drivers' -# - -# -# Media drivers -# -CONFIG_MEDIA_USB_SUPPORT=y - -# -# Webcam devices -# -CONFIG_USB_GSPCA=m -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_DTCS033=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_JEILINJ=m -CONFIG_USB_GSPCA_JL2005BCD=m -CONFIG_USB_GSPCA_KINECT=m -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_MR97310A=m -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7302=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SE401=m -CONFIG_USB_GSPCA_SN9C2028=m -CONFIG_USB_GSPCA_SN9C20X=m -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA1528=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SQ905=m -CONFIG_USB_GSPCA_SQ905C=m -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_STK1135=m -CONFIG_USB_GSPCA_STV0680=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TOPRO=m -CONFIG_USB_GSPCA_TOUPTEK=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m -CONFIG_USB_GL860=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -CONFIG_USB_PWC=m -# CONFIG_USB_PWC_DEBUG is not set -CONFIG_USB_PWC_INPUT_EVDEV=y -CONFIG_USB_S2255=m -CONFIG_VIDEO_USBTV=m -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y - -# -# Analog TV USB devices -# -# CONFIG_VIDEO_GO7007 is not set -CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_SYSFS=y -CONFIG_VIDEO_PVRUSB2_DVB=y -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -CONFIG_VIDEO_STK1160_COMMON=m -CONFIG_VIDEO_STK1160=m - -# -# Analog/digital TV USB devices -# -CONFIG_VIDEO_AU0828=m -CONFIG_VIDEO_AU0828_V4L2=y -# CONFIG_VIDEO_AU0828_RC is not set -CONFIG_VIDEO_CX231XX=m -CONFIG_VIDEO_CX231XX_RC=y -CONFIG_VIDEO_CX231XX_ALSA=m -CONFIG_VIDEO_CX231XX_DVB=m - -# -# Digital TV USB devices -# -CONFIG_DVB_AS102=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set -CONFIG_DVB_USB_V2=m -CONFIG_DVB_USB_AF9015=m -CONFIG_DVB_USB_AF9035=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_AZ6007=m -CONFIG_DVB_USB_CE6230=m -CONFIG_DVB_USB_DVBSKY=m -CONFIG_DVB_USB_EC168=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_MXL111SF=m -CONFIG_DVB_USB_RTL28XXU=m -CONFIG_DVB_USB_ZD1301=m -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_CXUSB=m -# CONFIG_DVB_USB_CXUSB_ANALOG is not set -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_DIB3000MC=m -CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_PCTV452E=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_VP7045=m -CONFIG_SMS_USB_DRV=m - -# -# Webcam, TV (analog/digital) USB devices -# -CONFIG_VIDEO_EM28XX=m -CONFIG_VIDEO_EM28XX_V4L2=m -CONFIG_VIDEO_EM28XX_ALSA=m -CONFIG_VIDEO_EM28XX_DVB=m -CONFIG_VIDEO_EM28XX_RC=m - -# -# Software defined radio USB devices -# -CONFIG_USB_AIRSPY=m -CONFIG_USB_HACKRF=m -CONFIG_USB_MSI2500=m -CONFIG_RADIO_ADAPTERS=m -CONFIG_RADIO_SAA7706H=m -CONFIG_RADIO_SHARK=m -CONFIG_RADIO_SHARK2=m -# CONFIG_RADIO_SI4713 is not set -CONFIG_RADIO_TEA575X=m -CONFIG_RADIO_TEA5764=m -CONFIG_RADIO_TEF6862=m -CONFIG_RADIO_WL1273=m -CONFIG_USB_DSBR=m -CONFIG_USB_KEENE=m -CONFIG_USB_MA901=m -# CONFIG_USB_MR800 is not set -CONFIG_USB_RAREMONO=m -# CONFIG_RADIO_SI470X is not set -CONFIG_MEDIA_PLATFORM_DRIVERS=y -CONFIG_V4L_PLATFORM_DRIVERS=y -# CONFIG_SDR_PLATFORM_DRIVERS is not set -# CONFIG_DVB_PLATFORM_DRIVERS is not set -# CONFIG_V4L_MEM2MEM_DRIVERS is not set -# CONFIG_VIDEO_MUX is not set - -# -# Allegro DVT media platform drivers -# - -# -# Amlogic media platform drivers -# - -# -# Amphion drivers -# - -# -# Aspeed media platform drivers -# -# CONFIG_VIDEO_ASPEED is not set - -# -# Atmel media platform drivers -# - -# -# Cadence media platform drivers -# -# CONFIG_VIDEO_CADENCE_CSI2RX is not set -# CONFIG_VIDEO_CADENCE_CSI2TX is not set - -# -# Chips&Media media platform drivers -# - -# -# Intel media platform drivers -# - -# -# Marvell media platform drivers -# - -# -# Mediatek media platform drivers -# - -# -# NVidia media platform drivers -# - -# -# NXP media platform drivers -# - -# -# Qualcomm media platform drivers -# - -# -# Renesas media platform drivers -# - -# -# Rockchip media platform drivers -# - -# -# Samsung media platform drivers -# - -# -# STMicroelectronics media platform drivers -# - -# -# Sunxi media platform drivers -# -# CONFIG_VIDEO_SUN4I_CSI is not set -CONFIG_VIDEO_SUN6I_CSI=m -# CONFIG_VIDEO_SUN6I_MIPI_CSI2 is not set -# CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2 is not set - -# -# Texas Instruments drivers -# - -# -# Verisilicon media platform drivers -# - -# -# VIA media platform drivers -# - -# -# Xilinx media platform drivers -# -# CONFIG_VIDEO_XILINX is not set - -# -# MMC/SDIO DVB adapters -# -# CONFIG_SMS_SDIO_DRV is not set -# CONFIG_V4L_TEST_DRIVERS is not set -# CONFIG_DVB_TEST_DRIVERS is not set -CONFIG_MEDIA_COMMON_OPTIONS=y - -# -# common driver options -# -CONFIG_CYPRESS_FIRMWARE=m -CONFIG_TTPCI_EEPROM=m -CONFIG_VIDEO_CX2341X=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_SMS_SIANO_MDTV=m -CONFIG_SMS_SIANO_RC=y -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_V4L2=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_DMA_CONTIG=m -CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_VIDEOBUF2_DMA_SG=m -# end of Media drivers - -CONFIG_MEDIA_HIDE_ANCILLARY_SUBDRV=y - -# -# Media ancillary drivers -# -CONFIG_MEDIA_ATTACH=y - -# -# IR I2C driver auto-selected by 'Autoselect ancillary drivers' -# -CONFIG_VIDEO_IR_I2C=m -CONFIG_VIDEO_CAMERA_SENSOR=y -CONFIG_VIDEO_APTINA_PLL=m -CONFIG_VIDEO_CCS_PLL=m -CONFIG_VIDEO_AR0521=m -CONFIG_VIDEO_HI556=m -CONFIG_VIDEO_HI846=m -CONFIG_VIDEO_HI847=m -CONFIG_VIDEO_IMX208=m -CONFIG_VIDEO_IMX214=m -CONFIG_VIDEO_IMX219=m -CONFIG_VIDEO_IMX258=m -CONFIG_VIDEO_IMX274=m -CONFIG_VIDEO_IMX290=m -CONFIG_VIDEO_IMX319=m -CONFIG_VIDEO_IMX334=m -CONFIG_VIDEO_IMX335=m -CONFIG_VIDEO_IMX355=m -CONFIG_VIDEO_IMX412=m -CONFIG_VIDEO_MAX9271_LIB=m -CONFIG_VIDEO_MT9M001=m -CONFIG_VIDEO_MT9M032=m -CONFIG_VIDEO_MT9M111=m -CONFIG_VIDEO_MT9P031=m -CONFIG_VIDEO_MT9T001=m -CONFIG_VIDEO_MT9T112=m -CONFIG_VIDEO_MT9V011=m -CONFIG_VIDEO_MT9V032=m -CONFIG_VIDEO_MT9V111=m -CONFIG_VIDEO_NOON010PC30=m -CONFIG_VIDEO_OG01A1B=m -CONFIG_VIDEO_OV02A10=m -CONFIG_VIDEO_OV08D10=m -CONFIG_VIDEO_OV13858=m -CONFIG_VIDEO_OV13B10=m -CONFIG_VIDEO_OV2640=m -CONFIG_VIDEO_OV2659=m -CONFIG_VIDEO_OV2680=m -CONFIG_VIDEO_OV2685=m -CONFIG_VIDEO_OV5640=m -CONFIG_VIDEO_OV5645=m -CONFIG_VIDEO_OV5647=m -CONFIG_VIDEO_OV5648=m -CONFIG_VIDEO_OV5670=m -CONFIG_VIDEO_OV5675=m -CONFIG_VIDEO_OV5693=m -CONFIG_VIDEO_OV5695=m -CONFIG_VIDEO_OV6650=m -CONFIG_VIDEO_OV7251=m -CONFIG_VIDEO_OV7640=m -CONFIG_VIDEO_OV7670=m -CONFIG_VIDEO_OV772X=m -CONFIG_VIDEO_OV7740=m -CONFIG_VIDEO_OV8856=m -CONFIG_VIDEO_OV8865=m -CONFIG_VIDEO_OV9282=m -CONFIG_VIDEO_OV9640=m -CONFIG_VIDEO_OV9650=m -CONFIG_VIDEO_RDACM20=m -CONFIG_VIDEO_RDACM21=m -CONFIG_VIDEO_RJ54N1=m -CONFIG_VIDEO_S5C73M3=m -CONFIG_VIDEO_S5K4ECGX=m -CONFIG_VIDEO_S5K5BAF=m -CONFIG_VIDEO_S5K6A3=m -CONFIG_VIDEO_S5K6AA=m -CONFIG_VIDEO_SR030PC30=m -CONFIG_VIDEO_VS6624=m -CONFIG_VIDEO_CCS=m -CONFIG_VIDEO_ET8EK8=m -CONFIG_VIDEO_M5MOLS=m - -# -# Lens drivers -# -# CONFIG_VIDEO_AD5820 is not set -# CONFIG_VIDEO_AK7375 is not set -# CONFIG_VIDEO_DW9714 is not set -# CONFIG_VIDEO_DW9768 is not set -# CONFIG_VIDEO_DW9807_VCM is not set -# end of Lens drivers - -# -# Flash devices -# -# CONFIG_VIDEO_ADP1653 is not set -# CONFIG_VIDEO_LM3560 is not set -# CONFIG_VIDEO_LM3646 is not set -# end of Flash devices - -# -# audio, video and radio I2C drivers auto-selected by 'Autoselect ancillary drivers' -# -CONFIG_VIDEO_CS53L32A=m -CONFIG_VIDEO_MSP3400=m -CONFIG_VIDEO_WM8775=m -CONFIG_VIDEO_SAA711X=m -CONFIG_VIDEO_TVP5150=m - -# -# Video and audio decoders -# -CONFIG_VIDEO_CX25840=m - -# -# SPI I2C drivers auto-selected by 'Autoselect ancillary drivers' -# - -# -# Media SPI Adapters -# -CONFIG_CXD2880_SPI_DRV=m -CONFIG_VIDEO_GS1662=m -# end of Media SPI Adapters - -CONFIG_MEDIA_TUNER=m - -# -# Tuner drivers auto-selected by 'Autoselect ancillary drivers' -# -CONFIG_MEDIA_TUNER_E4000=m -CONFIG_MEDIA_TUNER_FC0011=m -CONFIG_MEDIA_TUNER_FC0012=m -CONFIG_MEDIA_TUNER_FC0013=m -CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_IT913X=m -CONFIG_MEDIA_TUNER_MAX2165=m -CONFIG_MEDIA_TUNER_MC44S803=m -CONFIG_MEDIA_TUNER_MSI001=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2063=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_MEDIA_TUNER_QM1D1C0042=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_R820T=m -CONFIG_MEDIA_TUNER_SI2157=m -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA18212=m -CONFIG_MEDIA_TUNER_TDA18218=m -CONFIG_MEDIA_TUNER_TDA18250=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_TUA9001=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC4000=m -CONFIG_MEDIA_TUNER_XC5000=m - -# -# DVB Frontend drivers auto-selected by 'Autoselect ancillary drivers' -# - -# -# Multistandard (satellite) frontends -# -CONFIG_DVB_M88DS3103=m -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV6110x=m - -# -# Multistandard (cable + terrestrial) frontends -# -CONFIG_DVB_DRXK=m -CONFIG_DVB_MN88472=m -CONFIG_DVB_MN88473=m -CONFIG_DVB_SI2165=m -CONFIG_DVB_TDA18271C2DD=m - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24116=m -CONFIG_DVB_CX24120=m -CONFIG_DVB_CX24123=m -CONFIG_DVB_DS3000=m -CONFIG_DVB_MT312=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_TDA10071=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_TS2020=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_ZL10039=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_AF9013=m -CONFIG_DVB_AS102_FE=m -CONFIG_DVB_CX22702=m -CONFIG_DVB_CXD2820R=m -CONFIG_DVB_CXD2841ER=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_DRXD=m -CONFIG_DVB_EC100=m -CONFIG_DVB_GP8PSK_FE=m -CONFIG_DVB_MT352=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_RTL2830=m -CONFIG_DVB_RTL2832=m -CONFIG_DVB_RTL2832_SDR=m -CONFIG_DVB_SI2168=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_ZD1301_DEMOD=m -CONFIG_DVB_ZL10353=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_STV0297=m -CONFIG_DVB_TDA10023=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_AU8522=m -CONFIG_DVB_AU8522_DTV=m -CONFIG_DVB_AU8522_V4L=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LG2160=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_LGDT3306A=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_MXL692=m -CONFIG_DVB_NXT200X=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_S5H1411=m - -# -# ISDB-T (terrestrial) frontends -# -CONFIG_DVB_DIB8000=m -CONFIG_DVB_MB86A20S=m -CONFIG_DVB_S921=m - -# -# ISDB-S (satellite) & ISDB-T (terrestrial) frontends -# -CONFIG_DVB_TC90522=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_A8293=m -CONFIG_DVB_AF9033=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_ISL6423=m -CONFIG_DVB_IX2505V=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_LNBP21=m -CONFIG_DVB_LNBP22=m -CONFIG_DVB_M88RS2000=m -CONFIG_DVB_DRX39XYJ=m - -# -# Common Interface (EN50221) controller drivers -# -CONFIG_DVB_SP2=m - -# -# Tools to develop new frontends -# -# CONFIG_DVB_DUMMY_FE is not set -# end of Media ancillary drivers - -# -# Graphics support -# -CONFIG_APERTURE_HELPERS=y -CONFIG_DRM=y -CONFIG_DRM_MIPI_DBI=m -CONFIG_DRM_MIPI_DSI=y -# CONFIG_DRM_DEBUG_MM is not set -CONFIG_DRM_KMS_HELPER=y -CONFIG_DRM_FBDEV_EMULATION=y -CONFIG_DRM_FBDEV_OVERALLOC=100 -CONFIG_DRM_LOAD_EDID_FIRMWARE=y -CONFIG_DRM_DP_AUX_BUS=m -CONFIG_DRM_DISPLAY_HELPER=y -CONFIG_DRM_DISPLAY_DP_HELPER=y -CONFIG_DRM_DISPLAY_HDCP_HELPER=y -CONFIG_DRM_DISPLAY_HDMI_HELPER=y -# CONFIG_DRM_DP_AUX_CHARDEV is not set -# CONFIG_DRM_DP_CEC is not set -CONFIG_DRM_GEM_DMA_HELPER=y -CONFIG_DRM_GEM_SHMEM_HELPER=m -CONFIG_DRM_SCHED=m - -# -# I2C encoder or helper chips -# -CONFIG_DRM_I2C_CH7006=m -CONFIG_DRM_I2C_SIL164=m -# CONFIG_DRM_I2C_NXP_TDA998X is not set -CONFIG_DRM_I2C_NXP_TDA9950=m -# end of I2C encoder or helper chips - -# -# ARM devices -# -# CONFIG_DRM_HDLCD is not set -# CONFIG_DRM_MALI_DISPLAY is not set -CONFIG_DRM_KOMEDA=m -# end of ARM devices - -# CONFIG_DRM_VGEM is not set -CONFIG_DRM_VKMS=m -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_RCAR_DW_HDMI is not set -# CONFIG_DRM_RCAR_USE_LVDS is not set -# CONFIG_DRM_RCAR_USE_MIPI_DSI is not set -CONFIG_DRM_SUN4I=y -CONFIG_DRM_SUN6I_DSI=y -CONFIG_DRM_SUN8I_DW_HDMI=y -CONFIG_DRM_SUN8I_MIXER=y -CONFIG_DRM_SUN8I_TCON_TOP=y -# CONFIG_DRM_VIRTIO_GPU is not set -CONFIG_DRM_PANEL=y - -# -# Display Panels -# -CONFIG_DRM_PANEL_ABT_Y030XX067A=m -CONFIG_DRM_PANEL_ARM_VERSATILE=m -# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set -CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0=m -CONFIG_DRM_PANEL_BOE_HIMAX8279D=m -# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set -CONFIG_DRM_PANEL_DSI_CM=m -CONFIG_DRM_PANEL_LVDS=m -CONFIG_DRM_PANEL_SIMPLE=m -CONFIG_DRM_PANEL_EDP=m -CONFIG_DRM_PANEL_EBBG_FT8719=m -# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set -CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m -CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m -CONFIG_DRM_PANEL_ILITEK_IL9322=m -CONFIG_DRM_PANEL_ILITEK_ILI9341=m -CONFIG_DRM_PANEL_ILITEK_ILI9881C=m -CONFIG_DRM_PANEL_INNOLUX_EJ030NA=m -CONFIG_DRM_PANEL_INNOLUX_P079ZCA=m -CONFIG_DRM_PANEL_JDI_LT070ME05000=m -CONFIG_DRM_PANEL_JDI_R63452=m -CONFIG_DRM_PANEL_KHADAS_TS050=m -CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m -# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set -CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=m -# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set -CONFIG_DRM_PANEL_LG_LB035Q02=m -# CONFIG_DRM_PANEL_LG_LG4573 is not set -CONFIG_DRM_PANEL_NEC_NL8048HL11=m -CONFIG_DRM_PANEL_NEWVISION_NV3052C=m -CONFIG_DRM_PANEL_NOVATEK_NT35510=m -CONFIG_DRM_PANEL_NOVATEK_NT35560=m -CONFIG_DRM_PANEL_NOVATEK_NT35950=m -CONFIG_DRM_PANEL_NOVATEK_NT36672A=m -CONFIG_DRM_PANEL_NOVATEK_NT39016=m -# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set -CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m -CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m -# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set -CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00=m -CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m -CONFIG_DRM_PANEL_RAYDIUM_RM67191=m -CONFIG_DRM_PANEL_RAYDIUM_RM68200=m -CONFIG_DRM_PANEL_RONBO_RB070D30=m -CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m -CONFIG_DRM_PANEL_SAMSUNG_DB7430=m -CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m -CONFIG_DRM_PANEL_SAMSUNG_S6D27A1=m -CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=m -CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m -# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set -CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m -# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set -CONFIG_DRM_PANEL_SAMSUNG_SOFEF00=m -CONFIG_DRM_PANEL_SEIKO_43WVF1G=m -CONFIG_DRM_PANEL_SHARP_LQ101R1SX01=m -CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m -CONFIG_DRM_PANEL_SHARP_LS043T1LE01=m -CONFIG_DRM_PANEL_SHARP_LS060T1SX01=m -CONFIG_DRM_PANEL_SITRONIX_ST7701=m -# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -CONFIG_DRM_PANEL_SONY_ACX565AKM=m -CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521=m -CONFIG_DRM_PANEL_TDO_TL070WSH30=m -CONFIG_DRM_PANEL_TPO_TD028TTEC1=m -CONFIG_DRM_PANEL_TPO_TD043MTEA1=m -CONFIG_DRM_PANEL_TPO_TPG110=m -CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m -# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set -CONFIG_DRM_PANEL_WIDECHIPS_WS2401=m -CONFIG_DRM_PANEL_XINPENG_XPP055C272=m -# end of Display Panels - -CONFIG_DRM_BRIDGE=y -CONFIG_DRM_PANEL_BRIDGE=y - -# -# Display Interface Bridges -# -CONFIG_DRM_CDNS_DSI=m -CONFIG_DRM_CHIPONE_ICN6211=m -# CONFIG_DRM_CHRONTEL_CH7033 is not set -CONFIG_DRM_DISPLAY_CONNECTOR=m -CONFIG_DRM_ITE_IT6505=m -CONFIG_DRM_LONTIUM_LT8912B=m -CONFIG_DRM_LONTIUM_LT9211=m -# CONFIG_DRM_LONTIUM_LT9611 is not set -CONFIG_DRM_LONTIUM_LT9611UXC=m -CONFIG_DRM_ITE_IT66121=m -CONFIG_DRM_LVDS_CODEC=m -# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set -# CONFIG_DRM_NWL_MIPI_DSI is not set -# CONFIG_DRM_NXP_PTN3460 is not set -# CONFIG_DRM_PARADE_PS8622 is not set -CONFIG_DRM_PARADE_PS8640=m -# CONFIG_DRM_SIL_SII8620 is not set -# CONFIG_DRM_SII902X is not set -CONFIG_DRM_SII9234=m -CONFIG_DRM_SIMPLE_BRIDGE=m -CONFIG_DRM_THINE_THC63LVD1024=m -# CONFIG_DRM_TOSHIBA_TC358762 is not set -CONFIG_DRM_TOSHIBA_TC358764=m -# CONFIG_DRM_TOSHIBA_TC358767 is not set -CONFIG_DRM_TOSHIBA_TC358768=m -# CONFIG_DRM_TOSHIBA_TC358775 is not set -CONFIG_DRM_TI_DLPC3433=m -# CONFIG_DRM_TI_TFP410 is not set -CONFIG_DRM_TI_SN65DSI83=m -CONFIG_DRM_TI_SN65DSI86=m -CONFIG_DRM_TI_TPD12S015=m -CONFIG_DRM_ANALOGIX_ANX6345=m -CONFIG_DRM_ANALOGIX_ANX78XX=m -CONFIG_DRM_ANALOGIX_DP=m -CONFIG_DRM_ANALOGIX_ANX7625=m -# CONFIG_DRM_I2C_ADV7511 is not set -# CONFIG_DRM_CDNS_MHDP8546 is not set -CONFIG_DRM_DW_HDMI=y -CONFIG_DRM_DW_HDMI_AHB_AUDIO=m -CONFIG_DRM_DW_HDMI_I2S_AUDIO=y -CONFIG_DRM_DW_HDMI_GP_AUDIO=m -CONFIG_DRM_DW_HDMI_CEC=m -# end of Display Interface Bridges - -CONFIG_DRM_ETNAVIV=m -CONFIG_DRM_ETNAVIV_THERMAL=y -# CONFIG_DRM_HISI_KIRIN is not set -CONFIG_DRM_LOGICVC=m -# CONFIG_DRM_ARCPGU is not set -CONFIG_DRM_GM12U320=m -CONFIG_DRM_PANEL_MIPI_DBI=m -CONFIG_DRM_SIMPLEDRM=m -CONFIG_TINYDRM_HX8357D=m -CONFIG_TINYDRM_ILI9163=m -CONFIG_TINYDRM_ILI9225=m -CONFIG_TINYDRM_ILI9341=m -CONFIG_TINYDRM_ILI9486=m -CONFIG_TINYDRM_MI0283QT=m -CONFIG_TINYDRM_REPAPER=m -CONFIG_TINYDRM_ST7586=m -CONFIG_TINYDRM_ST7735R=m -# CONFIG_DRM_PL111 is not set -CONFIG_DRM_LIMA=m -CONFIG_DRM_PANFROST=m -CONFIG_DRM_TIDSS=m -CONFIG_DRM_GUD=m -CONFIG_DRM_SSD130X=m -CONFIG_DRM_SSD130X_I2C=m -CONFIG_DRM_SSD130X_SPI=m -# CONFIG_DRM_LEGACY is not set -CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y -CONFIG_DRM_NOMODESET=y - -# -# Frame buffer Devices -# -CONFIG_FB_CMDLINE=y -CONFIG_FB_NOTIFY=y -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SYS_FILLRECT=y -CONFIG_FB_SYS_COPYAREA=y -CONFIG_FB_SYS_IMAGEBLIT=y -# CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=y -CONFIG_FB_DEFERRED_IO=y -CONFIG_FB_BACKLIGHT=m -CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_ARMCLCD is not set -# CONFIG_FB_UVESA is not set -# CONFIG_FB_OPENCORES is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_SMSCUFX is not set -# CONFIG_FB_UDL is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -CONFIG_FB_SIMPLE=m -# CONFIG_FB_SSD1307 is not set -# end of Frame buffer Devices - -# -# Backlight & LCD device support -# -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_L4F00242T03 is not set -# CONFIG_LCD_LMS283GF05 is not set -# CONFIG_LCD_LTV350QV is not set -# CONFIG_LCD_ILI922X is not set -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_TDO24M is not set -# CONFIG_LCD_VGG2432A4 is not set -# CONFIG_LCD_PLATFORM is not set -# CONFIG_LCD_AMS369FG06 is not set -# CONFIG_LCD_LMS501KF03 is not set -# CONFIG_LCD_HX8357 is not set -CONFIG_LCD_OTM3225A=m -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_KTD253 is not set -CONFIG_BACKLIGHT_PWM=m -CONFIG_BACKLIGHT_MT6370=m -CONFIG_BACKLIGHT_QCOM_WLED=m -CONFIG_BACKLIGHT_RT4831=m -# CONFIG_BACKLIGHT_ADP8860 is not set -# CONFIG_BACKLIGHT_ADP8870 is not set -# CONFIG_BACKLIGHT_LM3630A is not set -# CONFIG_BACKLIGHT_LM3639 is not set -# CONFIG_BACKLIGHT_LP855X is not set -CONFIG_BACKLIGHT_GPIO=m -# CONFIG_BACKLIGHT_LV5207LP is not set -# CONFIG_BACKLIGHT_BD6107 is not set -# CONFIG_BACKLIGHT_ARCXCNN is not set -CONFIG_BACKLIGHT_RAVE_SP=m -CONFIG_BACKLIGHT_LED=m -# end of Backlight & LCD device support - -CONFIG_VIDEOMODE_HELPERS=y -CONFIG_HDMI=y - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -CONFIG_DUMMY_CONSOLE_COLUMNS=80 -CONFIG_DUMMY_CONSOLE_ROWS=25 -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y -# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set -# end of Console display driver support - -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -# end of Graphics support - -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_PCM_ELD=y -CONFIG_SND_PCM_IEC958=y -CONFIG_SND_DMAENGINE_PCM=y -CONFIG_SND_HWDEP=m -CONFIG_SND_SEQ_DEVICE=m -CONFIG_SND_RAWMIDI=m -CONFIG_SND_COMPRESS_OFFLOAD=y -CONFIG_SND_JACK=y -CONFIG_SND_JACK_INPUT_DEV=y -# CONFIG_SND_OSSEMUL is not set -CONFIG_SND_PCM_TIMER=y -# CONFIG_SND_HRTIMER is not set -CONFIG_SND_DYNAMIC_MINORS=y -CONFIG_SND_MAX_CARDS=32 -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_PROC_FS=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -CONFIG_SND_CTL_FAST_LOOKUP=y -# CONFIG_SND_DEBUG is not set -# CONFIG_SND_CTL_INPUT_VALIDATION is not set -CONFIG_SND_VMASTER=y -CONFIG_SND_CTL_LED=m -CONFIG_SND_SEQUENCER=m -# CONFIG_SND_SEQ_DUMMY is not set -CONFIG_SND_SEQ_MIDI_EVENT=m -CONFIG_SND_SEQ_MIDI=m -CONFIG_SND_SEQ_VIRMIDI=m -CONFIG_SND_MPU401_UART=m -CONFIG_SND_DRIVERS=y -CONFIG_SND_DUMMY=m -CONFIG_SND_ALOOP=m -CONFIG_SND_VIRMIDI=m -CONFIG_SND_MTPAV=m -CONFIG_SND_SERIAL_U16550=m -CONFIG_SND_SERIAL_GENERIC=m -CONFIG_SND_MPU401=m - -# -# HD-Audio -# -CONFIG_SND_HDA=m -CONFIG_SND_HDA_GENERIC_LEDS=y -# CONFIG_SND_HDA_HWDEP is not set -# CONFIG_SND_HDA_RECONFIG is not set -# CONFIG_SND_HDA_INPUT_BEEP is not set -# CONFIG_SND_HDA_PATCH_LOADER is not set -# CONFIG_SND_HDA_CODEC_REALTEK is not set -CONFIG_SND_HDA_CODEC_ANALOG=m -CONFIG_SND_HDA_CODEC_SIGMATEL=m -CONFIG_SND_HDA_CODEC_VIA=m -CONFIG_SND_HDA_CODEC_HDMI=m -CONFIG_SND_HDA_CODEC_CIRRUS=m -CONFIG_SND_HDA_CODEC_CS8409=m -CONFIG_SND_HDA_CODEC_CONEXANT=m -CONFIG_SND_HDA_CODEC_CA0110=m -CONFIG_SND_HDA_CODEC_CA0132=m -CONFIG_SND_HDA_CODEC_CA0132_DSP=y -CONFIG_SND_HDA_CODEC_CMEDIA=m -CONFIG_SND_HDA_CODEC_SI3054=m -CONFIG_SND_HDA_GENERIC=m -CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 -# end of HD-Audio - -CONFIG_SND_HDA_CORE=m -CONFIG_SND_HDA_DSP_LOADER=y -CONFIG_SND_HDA_EXT_CORE=m -CONFIG_SND_HDA_PREALLOC_SIZE=64 -# CONFIG_SND_SPI is not set -CONFIG_SND_USB=y -CONFIG_SND_USB_AUDIO=m -CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y -# CONFIG_SND_USB_UA101 is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_USB_6FIRE is not set -# CONFIG_SND_USB_HIFACE is not set -# CONFIG_SND_BCD2000 is not set -# CONFIG_SND_USB_POD is not set -# CONFIG_SND_USB_PODHD is not set -# CONFIG_SND_USB_TONEPORT is not set -# CONFIG_SND_USB_VARIAX is not set -CONFIG_SND_SOC=y -CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y -CONFIG_SND_SOC_COMPRESS=y -CONFIG_SND_SOC_ADI=m -CONFIG_SND_SOC_ADI_AXI_I2S=m -CONFIG_SND_SOC_ADI_AXI_SPDIF=m -# CONFIG_SND_SOC_AMD_ACP is not set -# CONFIG_SND_AMD_ACP_CONFIG is not set -# CONFIG_SND_ATMEL_SOC is not set -CONFIG_SND_BCM63XX_I2S_WHISTLER=m -# CONFIG_SND_DESIGNWARE_I2S is not set - -# -# SoC Audio for Freescale CPUs -# - -# -# Common SoC Audio options for Freescale CPUs: -# -# CONFIG_SND_SOC_FSL_ASRC is not set -# CONFIG_SND_SOC_FSL_SAI is not set -CONFIG_SND_SOC_FSL_AUDMIX=m -# CONFIG_SND_SOC_FSL_SSI is not set -# CONFIG_SND_SOC_FSL_SPDIF is not set -# CONFIG_SND_SOC_FSL_ESAI is not set -CONFIG_SND_SOC_FSL_MICFIL=m -CONFIG_SND_SOC_FSL_XCVR=m -CONFIG_SND_SOC_FSL_UTILS=m -# CONFIG_SND_SOC_IMX_AUDMUX is not set -# end of SoC Audio for Freescale CPUs - -# CONFIG_SND_I2S_HI6210_I2S is not set -# CONFIG_SND_SOC_IMG is not set -CONFIG_SND_SOC_MTK_BTCVSD=m -# CONFIG_SND_SOC_SOF_TOPLEVEL is not set - -# -# STMicroelectronics STM32 SOC audio support -# -# end of STMicroelectronics STM32 SOC audio support - -# -# Allwinner SoC Audio support -# -CONFIG_SND_SUN4I_CODEC=y -CONFIG_SND_SUN50IW9_CODEC=m -CONFIG_SND_SUN8I_CODEC=y -CONFIG_SND_SUN8I_CODEC_ANALOG=y -CONFIG_SND_SUN50I_CODEC_ANALOG=y -CONFIG_SND_SUN4I_I2S=m -CONFIG_SND_SUN4I_SPDIF=m -CONFIG_SND_SUN50I_DMIC=m -CONFIG_SND_SUN8I_ADDA_PR_REGMAP=y -CONFIG_SND_SOC_SUN50I_AHUB=y -CONFIG_SND_SOC_SUN50I_HDMI=y -# end of Allwinner SoC Audio support - -CONFIG_SND_SOC_XILINX_I2S=m -CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m -CONFIG_SND_SOC_XILINX_SPDIF=m -# CONFIG_SND_SOC_XTFPGA_I2S is not set -CONFIG_SND_SOC_I2C_AND_SPI=y - -# -# CODEC drivers -# -CONFIG_SND_SOC_WM_ADSP=m -# CONFIG_SND_SOC_AC97_CODEC is not set -CONFIG_SND_SOC_ADAU_UTILS=m -CONFIG_SND_SOC_ADAU1372=m -CONFIG_SND_SOC_ADAU1372_I2C=m -CONFIG_SND_SOC_ADAU1372_SPI=m -# CONFIG_SND_SOC_ADAU1701 is not set -# CONFIG_SND_SOC_ADAU1761_I2C is not set -# CONFIG_SND_SOC_ADAU1761_SPI is not set -# CONFIG_SND_SOC_ADAU7002 is not set -CONFIG_SND_SOC_ADAU7118=m -CONFIG_SND_SOC_ADAU7118_HW=m -CONFIG_SND_SOC_ADAU7118_I2C=m -# CONFIG_SND_SOC_AK4104 is not set -CONFIG_SND_SOC_AK4118=m -CONFIG_SND_SOC_AK4375=m -CONFIG_SND_SOC_AK4458=m -# CONFIG_SND_SOC_AK4554 is not set -# CONFIG_SND_SOC_AK4613 is not set -# CONFIG_SND_SOC_AK4642 is not set -# CONFIG_SND_SOC_AK5386 is not set -CONFIG_SND_SOC_AK5558=m -# CONFIG_SND_SOC_ALC5623 is not set -# CONFIG_SND_SOC_AW8738 is not set -CONFIG_SND_SOC_BD28623=m -# CONFIG_SND_SOC_BT_SCO is not set -# CONFIG_SND_SOC_CS35L32 is not set -# CONFIG_SND_SOC_CS35L33 is not set -# CONFIG_SND_SOC_CS35L34 is not set -# CONFIG_SND_SOC_CS35L35 is not set -CONFIG_SND_SOC_CS35L36=m -CONFIG_SND_SOC_CS35L41_LIB=m -CONFIG_SND_SOC_CS35L41=m -CONFIG_SND_SOC_CS35L41_SPI=m -CONFIG_SND_SOC_CS35L41_I2C=m -CONFIG_SND_SOC_CS35L45_TABLES=m -CONFIG_SND_SOC_CS35L45=m -CONFIG_SND_SOC_CS35L45_SPI=m -CONFIG_SND_SOC_CS35L45_I2C=m -CONFIG_SND_SOC_CS42L42_CORE=m -# CONFIG_SND_SOC_CS42L42 is not set -# CONFIG_SND_SOC_CS42L51_I2C is not set -# CONFIG_SND_SOC_CS42L52 is not set -# CONFIG_SND_SOC_CS42L56 is not set -# CONFIG_SND_SOC_CS42L73 is not set -CONFIG_SND_SOC_CS42L83=m -# CONFIG_SND_SOC_CS4234 is not set -# CONFIG_SND_SOC_CS4265 is not set -# CONFIG_SND_SOC_CS4270 is not set -# CONFIG_SND_SOC_CS4271_I2C is not set -# CONFIG_SND_SOC_CS4271_SPI is not set -# CONFIG_SND_SOC_CS42XX8_I2C is not set -CONFIG_SND_SOC_CS43130=m -CONFIG_SND_SOC_CS4341=m -# CONFIG_SND_SOC_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_CX2072X is not set -CONFIG_SND_SOC_DA7213=m -CONFIG_SND_SOC_DMIC=m -CONFIG_SND_SOC_HDMI_CODEC=y -# CONFIG_SND_SOC_ES7134 is not set -CONFIG_SND_SOC_ES7241=m -# CONFIG_SND_SOC_ES8316 is not set -CONFIG_SND_SOC_ES8326=m -# CONFIG_SND_SOC_ES8328_I2C is not set -# CONFIG_SND_SOC_ES8328_SPI is not set -# CONFIG_SND_SOC_GTM601 is not set -CONFIG_SND_SOC_HDA=m -CONFIG_SND_SOC_ICS43432=m -# CONFIG_SND_SOC_INNO_RK3036 is not set -CONFIG_SND_SOC_MAX98088=m -# CONFIG_SND_SOC_MAX98357A is not set -# CONFIG_SND_SOC_MAX98504 is not set -CONFIG_SND_SOC_MAX9867=m -# CONFIG_SND_SOC_MAX98927 is not set -CONFIG_SND_SOC_MAX98520=m -# CONFIG_SND_SOC_MAX98373_I2C is not set -# CONFIG_SND_SOC_MAX98390 is not set -CONFIG_SND_SOC_MAX98396=m -# CONFIG_SND_SOC_MAX9860 is not set -# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set -# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -# CONFIG_SND_SOC_PCM1681 is not set -CONFIG_SND_SOC_PCM1789=m -CONFIG_SND_SOC_PCM1789_I2C=m -# CONFIG_SND_SOC_PCM179X_I2C is not set -# CONFIG_SND_SOC_PCM179X_SPI is not set -CONFIG_SND_SOC_PCM186X=m -CONFIG_SND_SOC_PCM186X_I2C=m -CONFIG_SND_SOC_PCM186X_SPI=m -CONFIG_SND_SOC_PCM3060=m -CONFIG_SND_SOC_PCM3060_I2C=m -CONFIG_SND_SOC_PCM3060_SPI=m -# CONFIG_SND_SOC_PCM3168A_I2C is not set -# CONFIG_SND_SOC_PCM3168A_SPI is not set -CONFIG_SND_SOC_PCM5102A=m -# CONFIG_SND_SOC_PCM512x_I2C is not set -# CONFIG_SND_SOC_PCM512x_SPI is not set -CONFIG_SND_SOC_RK3328=m -CONFIG_SND_SOC_RL6231=m -# CONFIG_SND_SOC_RT5616 is not set -# CONFIG_SND_SOC_RT5631 is not set -CONFIG_SND_SOC_RT5640=m -CONFIG_SND_SOC_RT5659=m -CONFIG_SND_SOC_RT9120=m -# CONFIG_SND_SOC_SGTL5000 is not set -CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m -CONFIG_SND_SOC_SIMPLE_MUX=m -CONFIG_SND_SOC_SPDIF=m -CONFIG_SND_SOC_SRC4XXX_I2C=m -CONFIG_SND_SOC_SRC4XXX=m -CONFIG_SND_SOC_SSM2305=m -CONFIG_SND_SOC_SSM2518=m -# CONFIG_SND_SOC_SSM2602_SPI is not set -# CONFIG_SND_SOC_SSM2602_I2C is not set -# CONFIG_SND_SOC_SSM4567 is not set -# CONFIG_SND_SOC_STA32X is not set -# CONFIG_SND_SOC_STA350 is not set -# CONFIG_SND_SOC_STI_SAS is not set -# CONFIG_SND_SOC_TAS2552 is not set -CONFIG_SND_SOC_TAS2562=m -# CONFIG_SND_SOC_TAS2764 is not set -CONFIG_SND_SOC_TAS2770=m -CONFIG_SND_SOC_TAS2780=m -# CONFIG_SND_SOC_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set -CONFIG_SND_SOC_TAS5805M=m -CONFIG_SND_SOC_TAS6424=m -CONFIG_SND_SOC_TDA7419=m -# CONFIG_SND_SOC_TFA9879 is not set -CONFIG_SND_SOC_TFA989X=m -CONFIG_SND_SOC_TLV320ADC3XXX=m -# CONFIG_SND_SOC_TLV320AIC23_I2C is not set -# CONFIG_SND_SOC_TLV320AIC23_SPI is not set -# CONFIG_SND_SOC_TLV320AIC31XX is not set -CONFIG_SND_SOC_TLV320AIC32X4=m -CONFIG_SND_SOC_TLV320AIC32X4_I2C=m -# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set -CONFIG_SND_SOC_TLV320AIC3X=m -CONFIG_SND_SOC_TLV320AIC3X_I2C=m -CONFIG_SND_SOC_TLV320AIC3X_SPI=m -CONFIG_SND_SOC_TLV320ADCX140=m -# CONFIG_SND_SOC_TS3A227E is not set -# CONFIG_SND_SOC_TSCS42XX is not set -CONFIG_SND_SOC_TSCS454=m -CONFIG_SND_SOC_UDA1334=m -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8523 is not set -CONFIG_SND_SOC_WM8524=m -# CONFIG_SND_SOC_WM8580 is not set -# CONFIG_SND_SOC_WM8711 is not set -# CONFIG_SND_SOC_WM8728 is not set -CONFIG_SND_SOC_WM8731=m -CONFIG_SND_SOC_WM8731_I2C=m -CONFIG_SND_SOC_WM8731_SPI=m -# CONFIG_SND_SOC_WM8737 is not set -# CONFIG_SND_SOC_WM8741 is not set -# CONFIG_SND_SOC_WM8750 is not set -# CONFIG_SND_SOC_WM8753 is not set -# CONFIG_SND_SOC_WM8770 is not set -# CONFIG_SND_SOC_WM8776 is not set -CONFIG_SND_SOC_WM8782=m -# CONFIG_SND_SOC_WM8804_I2C is not set -# CONFIG_SND_SOC_WM8804_SPI is not set -# CONFIG_SND_SOC_WM8903 is not set -CONFIG_SND_SOC_WM8904=m -CONFIG_SND_SOC_WM8940=m -# CONFIG_SND_SOC_WM8960 is not set -# CONFIG_SND_SOC_WM8962 is not set -# CONFIG_SND_SOC_WM8974 is not set -# CONFIG_SND_SOC_WM8978 is not set -# CONFIG_SND_SOC_WM8985 is not set -# CONFIG_SND_SOC_ZL38060 is not set -CONFIG_SND_SOC_MAX9759=m -CONFIG_SND_SOC_MT6351=m -CONFIG_SND_SOC_MT6358=m -CONFIG_SND_SOC_MT6660=m -CONFIG_SND_SOC_NAU8315=m -# CONFIG_SND_SOC_NAU8540 is not set -# CONFIG_SND_SOC_NAU8810 is not set -CONFIG_SND_SOC_NAU8821=m -CONFIG_SND_SOC_NAU8822=m -# CONFIG_SND_SOC_NAU8824 is not set -# CONFIG_SND_SOC_TPA6130A2 is not set -CONFIG_SND_SOC_LPASS_MACRO_COMMON=m -CONFIG_SND_SOC_LPASS_WSA_MACRO=m -CONFIG_SND_SOC_LPASS_VA_MACRO=m -CONFIG_SND_SOC_LPASS_RX_MACRO=m -CONFIG_SND_SOC_LPASS_TX_MACRO=m -# end of CODEC drivers - -CONFIG_SND_SIMPLE_CARD_UTILS=m -CONFIG_SND_SIMPLE_CARD=m -# CONFIG_SND_AUDIO_GRAPH_CARD is not set -CONFIG_SND_AUDIO_GRAPH_CARD2=m -CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE=m -CONFIG_SND_TEST_COMPONENT=m -CONFIG_SND_VIRTIO=m - -# -# HID support -# -CONFIG_HID=y -CONFIG_HID_BATTERY_STRENGTH=y -CONFIG_HIDRAW=y -CONFIG_UHID=m -CONFIG_HID_GENERIC=y - -# -# Special HID drivers -# -CONFIG_HID_A4TECH=m -CONFIG_HID_ACCUTOUCH=m -CONFIG_HID_ACRUX=m -CONFIG_HID_ACRUX_FF=y -CONFIG_HID_APPLE=m -CONFIG_HID_APPLEIR=m -# CONFIG_HID_ASUS is not set -CONFIG_HID_AUREAL=m -CONFIG_HID_BELKIN=m -CONFIG_HID_BETOP_FF=m -CONFIG_HID_BIGBEN_FF=m -CONFIG_HID_CHERRY=m -CONFIG_HID_CHICONY=m -CONFIG_HID_CORSAIR=m -CONFIG_HID_COUGAR=m -CONFIG_HID_MACALLY=m -CONFIG_HID_PRODIKEYS=m -# CONFIG_HID_CMEDIA is not set -CONFIG_HID_CP2112=m -CONFIG_HID_CREATIVE_SB0540=m -CONFIG_HID_CYPRESS=m -CONFIG_HID_DRAGONRISE=m -CONFIG_DRAGONRISE_FF=y -CONFIG_HID_EMS_FF=m -CONFIG_HID_ELAN=m -CONFIG_HID_ELECOM=m -CONFIG_HID_ELO=m -CONFIG_HID_EZKEY=m -CONFIG_HID_FT260=m -CONFIG_HID_GEMBIRD=m -CONFIG_HID_GFRM=m -CONFIG_HID_GLORIOUS=m -CONFIG_HID_HOLTEK=m -CONFIG_HOLTEK_FF=y -# CONFIG_HID_VIVALDI is not set -CONFIG_HID_GT683R=m -CONFIG_HID_KEYTOUCH=m -CONFIG_HID_KYE=m -CONFIG_HID_UCLOGIC=m -CONFIG_HID_WALTOP=m -CONFIG_HID_VIEWSONIC=m -CONFIG_HID_VRC2=m -CONFIG_HID_XIAOMI=m -CONFIG_HID_GYRATION=m -CONFIG_HID_ICADE=m -# CONFIG_HID_ITE is not set -# CONFIG_HID_JABRA is not set -CONFIG_HID_TWINHAN=m -CONFIG_HID_KENSINGTON=m -CONFIG_HID_LCPOWER=m -CONFIG_HID_LED=m -CONFIG_HID_LENOVO=m -# CONFIG_HID_LETSKETCH is not set -CONFIG_HID_LOGITECH=m -CONFIG_HID_LOGITECH_DJ=m -CONFIG_HID_LOGITECH_HIDPP=m -CONFIG_LOGITECH_FF=y -CONFIG_LOGIRUMBLEPAD2_FF=y -CONFIG_LOGIG940_FF=y -CONFIG_LOGIWHEELS_FF=y -CONFIG_HID_MAGICMOUSE=m -CONFIG_HID_MALTRON=m -# CONFIG_HID_MAYFLASH is not set -CONFIG_HID_MEGAWORLD_FF=m -CONFIG_HID_REDRAGON=m -CONFIG_HID_MICROSOFT=m -CONFIG_HID_MONTEREY=m -CONFIG_HID_MULTITOUCH=m -CONFIG_HID_NINTENDO=m -# CONFIG_NINTENDO_FF is not set -CONFIG_HID_NTI=m -CONFIG_HID_NTRIG=m -CONFIG_HID_ORTEK=m -CONFIG_HID_PANTHERLORD=m -CONFIG_PANTHERLORD_FF=y -CONFIG_HID_PENMOUNT=m -CONFIG_HID_PETALYNX=m -CONFIG_HID_PICOLCD=m -CONFIG_HID_PICOLCD_FB=y -CONFIG_HID_PICOLCD_BACKLIGHT=y -CONFIG_HID_PICOLCD_LCD=y -CONFIG_HID_PICOLCD_LEDS=y -CONFIG_HID_PICOLCD_CIR=y -CONFIG_HID_PLANTRONICS=m -# CONFIG_HID_PLAYSTATION is not set -CONFIG_HID_PXRC=m -CONFIG_HID_RAZER=m -CONFIG_HID_PRIMAX=m -# CONFIG_HID_RETRODE is not set -CONFIG_HID_ROCCAT=m -CONFIG_HID_SAITEK=m -CONFIG_HID_SAMSUNG=m -CONFIG_HID_SEMITEK=m -CONFIG_HID_SIGMAMICRO=m -CONFIG_HID_SONY=m -CONFIG_SONY_FF=y -CONFIG_HID_SPEEDLINK=m -CONFIG_HID_STEAM=m -CONFIG_HID_STEELSERIES=m -CONFIG_HID_SUNPLUS=m -CONFIG_HID_RMI=m -CONFIG_HID_GREENASIA=m -CONFIG_GREENASIA_FF=y -CONFIG_HID_SMARTJOYPLUS=m -CONFIG_SMARTJOYPLUS_FF=y -CONFIG_HID_TIVO=m -CONFIG_HID_TOPSEED=m -CONFIG_HID_TOPRE=m -CONFIG_HID_THINGM=m -CONFIG_HID_THRUSTMASTER=m -CONFIG_THRUSTMASTER_FF=y -# CONFIG_HID_UDRAW_PS3 is not set -CONFIG_HID_U2FZERO=m -CONFIG_HID_WACOM=m -CONFIG_HID_WIIMOTE=m -CONFIG_HID_XINMO=m -CONFIG_HID_ZEROPLUS=m -CONFIG_ZEROPLUS_FF=y -CONFIG_HID_ZYDACRON=m -CONFIG_HID_SENSOR_HUB=m -CONFIG_HID_SENSOR_CUSTOM_SENSOR=m -CONFIG_HID_ALPS=m -CONFIG_HID_MCP2221=m -# end of Special HID drivers - -# -# USB HID support -# -CONFIG_USB_HID=y -CONFIG_HID_PID=y -CONFIG_USB_HIDDEV=y -# end of USB HID support - -# -# I2C HID support -# -CONFIG_I2C_HID_OF=m -CONFIG_I2C_HID_OF_ELAN=m -CONFIG_I2C_HID_OF_GOODIX=m -# end of I2C HID support - -CONFIG_I2C_HID_CORE=m -# end of HID support - -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_COMMON=y -CONFIG_USB_LED_TRIG=y -# CONFIG_USB_ULPI_BUS is not set -CONFIG_USB_CONN_GPIO=m -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEFAULT_PERSIST=y -# CONFIG_USB_FEW_INIT_RETRIES is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -CONFIG_USB_OTG=y -# CONFIG_USB_OTG_PRODUCTLIST is not set -# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set -# CONFIG_USB_OTG_FSM is not set -CONFIG_USB_LEDS_TRIGGER_USBPORT=y -CONFIG_USB_AUTOSUSPEND_DELAY=2 -CONFIG_USB_MON=m - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_XHCI_HCD=y -# CONFIG_USB_XHCI_DBGCAP is not set -# CONFIG_USB_XHCI_PCI_RENESAS is not set -CONFIG_USB_XHCI_PLATFORM=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_EHCI_FSL is not set -CONFIG_USB_EHCI_HCD_PLATFORM=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_FOTG210_HCD is not set -# CONFIG_USB_MAX3421_HCD is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PLATFORM=y -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HCD_BCMA is not set -# CONFIG_USB_HCD_SSB is not set -# CONFIG_USB_HCD_TEST_MODE is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m -CONFIG_USB_WDM=m -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# - -# -# also be needed; see USB_STORAGE Help for more info -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set -CONFIG_USB_UAS=m - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -CONFIG_USBIP_CORE=m -CONFIG_USBIP_VHCI_HCD=m -CONFIG_USBIP_VHCI_HC_PORTS=8 -CONFIG_USBIP_VHCI_NR_HCS=1 -CONFIG_USBIP_HOST=m -CONFIG_USBIP_VUDC=m -# CONFIG_USBIP_DEBUG is not set -CONFIG_USB_CDNS_SUPPORT=m -CONFIG_USB_CDNS3=m -# CONFIG_USB_CDNS3_GADGET is not set -# CONFIG_USB_CDNS3_HOST is not set -CONFIG_USB_MUSB_HDRC=y -# CONFIG_USB_MUSB_HOST is not set -# CONFIG_USB_MUSB_GADGET is not set -CONFIG_USB_MUSB_DUAL_ROLE=y - -# -# Platform Glue Layer -# -CONFIG_USB_MUSB_SUNXI=y - -# -# MUSB DMA mode -# -# CONFIG_MUSB_PIO_ONLY is not set -CONFIG_USB_DWC3=y -# CONFIG_USB_DWC3_HOST is not set -# CONFIG_USB_DWC3_GADGET is not set -CONFIG_USB_DWC3_DUAL_ROLE=y - -# -# Platform Glue Driver Support -# -CONFIG_USB_DWC3_OF_SIMPLE=m -CONFIG_USB_DWC2=y -# CONFIG_USB_DWC2_HOST is not set - -# -# Gadget/Dual-role mode requires USB Gadget support to be enabled -# -# CONFIG_USB_DWC2_PERIPHERAL is not set -CONFIG_USB_DWC2_DUAL_ROLE=y -# CONFIG_USB_DWC2_DEBUG is not set -# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set -# CONFIG_USB_CHIPIDEA is not set -# CONFIG_USB_ISP1760 is not set - -# -# USB port drivers -# -CONFIG_USB_SERIAL=m -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_SIMPLE=m -CONFIG_USB_SERIAL_AIRCABLE=m -CONFIG_USB_SERIAL_ARK3116=m -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_CH341=m -CONFIG_USB_SERIAL_WHITEHEAT=m -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_CP210X=m -CONFIG_USB_SERIAL_CYPRESS_M8=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_F81232=m -# CONFIG_USB_SERIAL_F8153X is not set -CONFIG_USB_SERIAL_GARMIN=m -CONFIG_USB_SERIAL_IPW=m -CONFIG_USB_SERIAL_IUU=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_METRO=m -CONFIG_USB_SERIAL_MOS7720=m -CONFIG_USB_SERIAL_MOS7840=m -CONFIG_USB_SERIAL_MXUPORT=m -CONFIG_USB_SERIAL_NAVMAN=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_OTI6858=m -CONFIG_USB_SERIAL_QCAUX=m -CONFIG_USB_SERIAL_QUALCOMM=m -CONFIG_USB_SERIAL_SPCP8X5=m -CONFIG_USB_SERIAL_SAFE=m -# CONFIG_USB_SERIAL_SAFE_PADDED is not set -CONFIG_USB_SERIAL_SIERRAWIRELESS=m -CONFIG_USB_SERIAL_SYMBOL=m -CONFIG_USB_SERIAL_TI=m -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_WWAN=m -CONFIG_USB_SERIAL_OPTION=m -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_SERIAL_OPTICON=m -CONFIG_USB_SERIAL_XSENS_MT=m -CONFIG_USB_SERIAL_WISHBONE=m -CONFIG_USB_SERIAL_SSU100=m -CONFIG_USB_SERIAL_QT2=m -CONFIG_USB_SERIAL_UPD78F0730=m -CONFIG_USB_SERIAL_XR=m -CONFIG_USB_SERIAL_DEBUG=m - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -CONFIG_APPLE_MFI_FASTCHARGE=m -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_EHSET_TEST_FIXTURE is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set -CONFIG_USB_EZUSB_FX2=m -CONFIG_USB_HUB_USB251XB=m -# CONFIG_USB_HSIC_USB3503 is not set -# CONFIG_USB_HSIC_USB4604 is not set -# CONFIG_USB_LINK_LAYER_TEST is not set -CONFIG_USB_CHAOSKEY=m -CONFIG_USB_ONBOARD_HUB=m - -# -# USB Physical Layer drivers -# -CONFIG_USB_PHY=y -CONFIG_NOP_USB_XCEIV=y -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_ISP1301 is not set -# CONFIG_USB_ULPI is not set -# end of USB Physical Layer drivers - -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_DEBUG_FS is not set -CONFIG_USB_GADGET_VBUS_DRAW=2 -CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -CONFIG_U_SERIAL_CONSOLE=y - -# -# USB Peripheral Controller -# -# CONFIG_USB_FOTG210_UDC is not set -# CONFIG_USB_GR_UDC is not set -# CONFIG_USB_R8A66597 is not set -# CONFIG_USB_PXA27X is not set -# CONFIG_USB_MV_UDC is not set -# CONFIG_USB_MV_U3D is not set -# CONFIG_USB_SNP_UDC_PLAT is not set -# CONFIG_USB_M66592 is not set -# CONFIG_USB_BDC_UDC is not set -# CONFIG_USB_NET2272 is not set -# CONFIG_USB_GADGET_XILINX is not set -CONFIG_USB_MAX3420_UDC=m -# CONFIG_USB_DUMMY_HCD is not set -# end of USB Peripheral Controller - -CONFIG_USB_LIBCOMPOSITE=m -CONFIG_USB_F_ACM=m -CONFIG_USB_F_SS_LB=m -CONFIG_USB_U_SERIAL=m -CONFIG_USB_U_ETHER=m -CONFIG_USB_U_AUDIO=m -CONFIG_USB_F_SERIAL=m -CONFIG_USB_F_OBEX=m -CONFIG_USB_F_NCM=m -CONFIG_USB_F_ECM=m -CONFIG_USB_F_EEM=m -CONFIG_USB_F_SUBSET=m -CONFIG_USB_F_RNDIS=m -CONFIG_USB_F_MASS_STORAGE=m -CONFIG_USB_F_FS=m -CONFIG_USB_F_UAC1=m -CONFIG_USB_F_UAC2=m -CONFIG_USB_F_UVC=m -CONFIG_USB_F_MIDI=m -CONFIG_USB_F_HID=m -CONFIG_USB_F_PRINTER=m -CONFIG_USB_F_TCM=m -CONFIG_USB_CONFIGFS=m -CONFIG_USB_CONFIGFS_SERIAL=y -CONFIG_USB_CONFIGFS_ACM=y -CONFIG_USB_CONFIGFS_OBEX=y -CONFIG_USB_CONFIGFS_NCM=y -CONFIG_USB_CONFIGFS_ECM=y -CONFIG_USB_CONFIGFS_ECM_SUBSET=y -CONFIG_USB_CONFIGFS_RNDIS=y -CONFIG_USB_CONFIGFS_EEM=y -CONFIG_USB_CONFIGFS_MASS_STORAGE=y -CONFIG_USB_CONFIGFS_F_LB_SS=y -CONFIG_USB_CONFIGFS_F_FS=y -CONFIG_USB_CONFIGFS_F_UAC1=y -# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set -CONFIG_USB_CONFIGFS_F_UAC2=y -CONFIG_USB_CONFIGFS_F_MIDI=y -CONFIG_USB_CONFIGFS_F_HID=y -CONFIG_USB_CONFIGFS_F_UVC=y -CONFIG_USB_CONFIGFS_F_PRINTER=y -# CONFIG_USB_CONFIGFS_F_TCM is not set - -# -# USB Gadget precomposed configurations -# -CONFIG_USB_ZERO=m -# CONFIG_USB_ZERO_HNPTEST is not set -CONFIG_USB_AUDIO=m -# CONFIG_GADGET_UAC1 is not set -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -CONFIG_USB_ETH_EEM=y -CONFIG_USB_G_NCM=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_FUNCTIONFS=m -CONFIG_USB_FUNCTIONFS_ETH=y -CONFIG_USB_FUNCTIONFS_RNDIS=y -CONFIG_USB_FUNCTIONFS_GENERIC=y -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_GADGET_TARGET=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_MIDI_GADGET=m -CONFIG_USB_G_PRINTER=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_USB_G_ACM_MS=m -CONFIG_USB_G_MULTI=m -CONFIG_USB_G_MULTI_RNDIS=y -CONFIG_USB_G_MULTI_CDC=y -CONFIG_USB_G_HID=m -# CONFIG_USB_G_DBGP is not set -CONFIG_USB_G_WEBCAM=m -CONFIG_USB_RAW_GADGET=m -# end of USB Gadget precomposed configurations - -CONFIG_TYPEC=m -# CONFIG_TYPEC_TCPM is not set -# CONFIG_TYPEC_UCSI is not set -CONFIG_TYPEC_TPS6598X=m -CONFIG_TYPEC_ANX7411=m -CONFIG_TYPEC_RT1719=m -CONFIG_TYPEC_HD3SS3220=m -# CONFIG_TYPEC_STUSB160X is not set -CONFIG_TYPEC_WUSB3801=m - -# -# USB Type-C Multiplexer/DeMultiplexer Switch support -# -CONFIG_TYPEC_MUX_FSA4480=m -CONFIG_TYPEC_MUX_PI3USB30532=m -# end of USB Type-C Multiplexer/DeMultiplexer Switch support - -# -# USB Type-C Alternate Mode drivers -# -CONFIG_TYPEC_DP_ALTMODE=m -# CONFIG_TYPEC_NVIDIA_ALTMODE is not set -# end of USB Type-C Alternate Mode drivers - -CONFIG_USB_ROLE_SWITCH=y -CONFIG_MMC=y -CONFIG_PWRSEQ_EMMC=y -# CONFIG_PWRSEQ_SD8787 is not set -CONFIG_PWRSEQ_SIMPLE=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_ARMMMCI=y -CONFIG_MMC_STM32_SDMMC=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -# CONFIG_MMC_SDHCI_OF_ARASAN is not set -# CONFIG_MMC_SDHCI_OF_AT91 is not set -# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set -# CONFIG_MMC_SDHCI_CADENCE is not set -# CONFIG_MMC_SDHCI_F_SDH30 is not set -CONFIG_MMC_SDHCI_MILBEAUT=m -CONFIG_MMC_SPI=y -CONFIG_MMC_DW=y -CONFIG_MMC_DW_PLTFM=y -CONFIG_MMC_DW_BLUEFIELD=m -CONFIG_MMC_DW_EXYNOS=y -CONFIG_MMC_DW_HI3798CV200=m -CONFIG_MMC_DW_K3=y -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MMC_USDHI6ROL0 is not set -CONFIG_MMC_SUNXI=y -CONFIG_MMC_CQHCI=m -CONFIG_MMC_HSQ=m -# CONFIG_MMC_MTK is not set -# CONFIG_MMC_SDHCI_XENON is not set -CONFIG_MMC_LITEX=m -CONFIG_SCSI_UFSHCD=m -# CONFIG_SCSI_UFS_BSG is not set -# CONFIG_SCSI_UFS_HPB is not set -# CONFIG_SCSI_UFS_HWMON is not set -# CONFIG_SCSI_UFSHCD_PLATFORM is not set -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -# CONFIG_LEDS_CLASS_FLASH is not set -CONFIG_LEDS_CLASS_MULTICOLOR=m -# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set - -# -# LED drivers -# -CONFIG_LEDS_AN30259A=m -# CONFIG_LEDS_AW2013 is not set -# CONFIG_LEDS_BCM6328 is not set -# CONFIG_LEDS_BCM6358 is not set -CONFIG_LEDS_CR0014114=m -CONFIG_LEDS_EL15203000=m -# CONFIG_LEDS_LM3530 is not set -CONFIG_LEDS_LM3532=m -# CONFIG_LEDS_LM3642 is not set -CONFIG_LEDS_LM3692X=m -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=y -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP50XX is not set -# CONFIG_LEDS_LP55XX_COMMON is not set -# CONFIG_LEDS_LP8860 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_PCA963X is not set -# CONFIG_LEDS_DAC124S085 is not set -CONFIG_LEDS_PWM=m -CONFIG_LEDS_REGULATOR=m -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TLC591XX is not set -CONFIG_LEDS_MAX77650=m -# CONFIG_LEDS_LM355x is not set -# CONFIG_LEDS_IS31FL319X is not set -# CONFIG_LEDS_IS31FL32XX is not set - -# -# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) -# -# CONFIG_LEDS_BLINKM is not set -CONFIG_LEDS_SYSCON=y -CONFIG_LEDS_MLXREG=m -CONFIG_LEDS_USER=y -# CONFIG_LEDS_SPI_BYTE is not set -# CONFIG_LEDS_TI_LMU_COMMON is not set - -# -# Flash and Torch LED drivers -# - -# -# RGB LED drivers -# -# CONFIG_LEDS_PWM_MULTICOLOR is not set -# CONFIG_LEDS_QCOM_LPG is not set -CONFIG_LEDS_WS2812=m - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_ONESHOT=m -CONFIG_LEDS_TRIGGER_DISK=y -CONFIG_LEDS_TRIGGER_MTD=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_BACKLIGHT=m -CONFIG_LEDS_TRIGGER_CPU=y -CONFIG_LEDS_TRIGGER_ACTIVITY=y -CONFIG_LEDS_TRIGGER_GPIO=m -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - -# -# iptables trigger is under Netfilter config (LED target) -# -CONFIG_LEDS_TRIGGER_TRANSIENT=m -CONFIG_LEDS_TRIGGER_CAMERA=m -CONFIG_LEDS_TRIGGER_PANIC=y -CONFIG_LEDS_TRIGGER_NETDEV=m -CONFIG_LEDS_TRIGGER_PATTERN=m -CONFIG_LEDS_TRIGGER_AUDIO=m -CONFIG_LEDS_TRIGGER_TTY=m - -# -# Simple LED drivers -# -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -CONFIG_EDAC_SUPPORT=y -CONFIG_EDAC=m -CONFIG_EDAC_LEGACY_SYSFS=y -# CONFIG_EDAC_DEBUG is not set -CONFIG_EDAC_XGENE=m -CONFIG_EDAC_DMC520=m -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -CONFIG_RTC_SYSTOHC=y -CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set -CONFIG_RTC_NVMEM=y - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -# CONFIG_RTC_INTF_PROC is not set -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -CONFIG_RTC_DRV_ABB5ZES3=m -CONFIG_RTC_DRV_ABEOZ9=m -CONFIG_RTC_DRV_ABX80X=m -CONFIG_RTC_DRV_AC100=m -CONFIG_RTC_DRV_DS1307=m -CONFIG_RTC_DRV_DS1307_CENTURY=y -CONFIG_RTC_DRV_DS1374=m -CONFIG_RTC_DRV_DS1374_WDT=y -CONFIG_RTC_DRV_DS1672=m -CONFIG_RTC_DRV_HYM8563=m -CONFIG_RTC_DRV_MAX6900=m -CONFIG_RTC_DRV_MAX77686=m -CONFIG_RTC_DRV_NCT3018Y=m -CONFIG_RTC_DRV_RS5C372=m -CONFIG_RTC_DRV_ISL1208=m -CONFIG_RTC_DRV_ISL12022=m -CONFIG_RTC_DRV_ISL12026=m -CONFIG_RTC_DRV_X1205=m -CONFIG_RTC_DRV_PCF8523=m -CONFIG_RTC_DRV_PCF85063=m -CONFIG_RTC_DRV_PCF85363=m -CONFIG_RTC_DRV_PCF8563=m -CONFIG_RTC_DRV_PCF8583=m -CONFIG_RTC_DRV_M41T80=m -CONFIG_RTC_DRV_M41T80_WDT=y -CONFIG_RTC_DRV_BD70528=m -CONFIG_RTC_DRV_BQ32K=m -CONFIG_RTC_DRV_S35390A=m -CONFIG_RTC_DRV_FM3130=m -CONFIG_RTC_DRV_RX8010=m -CONFIG_RTC_DRV_RX8581=m -CONFIG_RTC_DRV_RX8025=m -CONFIG_RTC_DRV_EM3027=m -CONFIG_RTC_DRV_RV3028=m -# CONFIG_RTC_DRV_RV3032 is not set -CONFIG_RTC_DRV_RV8803=m -CONFIG_RTC_DRV_S5M=m -CONFIG_RTC_DRV_SD3078=m - -# -# SPI RTC drivers -# -CONFIG_RTC_DRV_M41T93=m -CONFIG_RTC_DRV_M41T94=m -CONFIG_RTC_DRV_DS1302=m -CONFIG_RTC_DRV_DS1305=m -CONFIG_RTC_DRV_DS1343=m -CONFIG_RTC_DRV_DS1347=m -CONFIG_RTC_DRV_DS1390=m -CONFIG_RTC_DRV_MAX6916=m -CONFIG_RTC_DRV_R9701=m -CONFIG_RTC_DRV_RX4581=m -CONFIG_RTC_DRV_RS5C348=m -CONFIG_RTC_DRV_MAX6902=m -CONFIG_RTC_DRV_PCF2123=m -CONFIG_RTC_DRV_MCP795=m -CONFIG_RTC_I2C_AND_SPI=y - -# -# SPI and I2C RTC drivers -# -CONFIG_RTC_DRV_DS3232=m -CONFIG_RTC_DRV_DS3232_HWMON=y -CONFIG_RTC_DRV_PCF2127=m -CONFIG_RTC_DRV_RV3029C2=m -CONFIG_RTC_DRV_RV3029_HWMON=y -CONFIG_RTC_DRV_RX6110=m - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1685_FAMILY is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_DS2404 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set -# CONFIG_RTC_DRV_ZYNQMP is not set -CONFIG_RTC_DRV_NTXEC=m - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_PL030=m -CONFIG_RTC_DRV_PL031=m -CONFIG_RTC_DRV_SUN6I=y -CONFIG_RTC_DRV_CADENCE=m -# CONFIG_RTC_DRV_FTRTC010 is not set -# CONFIG_RTC_DRV_R7301 is not set - -# -# HID Sensor RTC drivers -# -# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -CONFIG_RTC_DRV_GOLDFISH=m -CONFIG_DMADEVICES=y -# CONFIG_DMADEVICES_DEBUG is not set - -# -# DMA Devices -# -CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DMA_OF=y -CONFIG_ALTERA_MSGDMA=m -# CONFIG_AMBA_PL08X is not set -# CONFIG_BCM_SBA_RAID is not set -CONFIG_DMA_SUN6I=y -CONFIG_DW_AXI_DMAC=m -# CONFIG_FSL_EDMA is not set -CONFIG_FSL_QDMA=m -# CONFIG_INTEL_IDMA64 is not set -# CONFIG_MV_XOR_V2 is not set -# CONFIG_PL330_DMA is not set -# CONFIG_XILINX_DMA is not set -# CONFIG_XILINX_ZYNQMP_DMA is not set -# CONFIG_XILINX_ZYNQMP_DPDMA is not set -# CONFIG_QCOM_HIDMA_MGMT is not set -# CONFIG_QCOM_HIDMA is not set -# CONFIG_DW_DMAC is not set -CONFIG_SF_PDMA=m - -# -# DMA Clients -# -# CONFIG_ASYNC_TX_DMA is not set -# CONFIG_DMATEST is not set -CONFIG_DMA_ENGINE_RAID=y - -# -# DMABUF options -# -CONFIG_SYNC_FILE=y -# CONFIG_SW_SYNC is not set -# CONFIG_UDMABUF is not set -# CONFIG_DMABUF_MOVE_NOTIFY is not set -# CONFIG_DMABUF_DEBUG is not set -CONFIG_DMABUF_SELFTESTS=m -# CONFIG_DMABUF_HEAPS is not set -# CONFIG_DMABUF_SYSFS_STATS is not set -# end of DMABUF options - -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set -# CONFIG_VFIO is not set -# CONFIG_VIRT_DRIVERS is not set -CONFIG_VIRTIO_ANCHOR=y -CONFIG_VIRTIO=y -CONFIG_VIRTIO_MENU=y -CONFIG_VIRTIO_BALLOON=y -# CONFIG_VIRTIO_INPUT is not set -CONFIG_VIRTIO_MMIO=y -# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set -# CONFIG_VDPA is not set -CONFIG_VHOST_IOTLB=m -CONFIG_VHOST=m -CONFIG_VHOST_MENU=y -# CONFIG_VHOST_NET is not set -CONFIG_VHOST_SCSI=m -# CONFIG_VHOST_VSOCK is not set -# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set - -# -# Microsoft Hyper-V guest support -# -# end of Microsoft Hyper-V guest support - -# CONFIG_GREYBUS is not set -# CONFIG_COMEDI is not set -CONFIG_STAGING=y -# CONFIG_PRISM2_USB is not set -# CONFIG_RTLLIB is not set -CONFIG_RTL8723BS=m -CONFIG_R8712U=m -CONFIG_R8188EU=m -# CONFIG_VT6656 is not set - -# -# IIO staging drivers -# - -# -# Accelerometers -# -# CONFIG_ADIS16203 is not set -# CONFIG_ADIS16240 is not set -# end of Accelerometers - -# -# Analog to digital converters -# -# CONFIG_AD7816 is not set -# end of Analog to digital converters - -# -# Analog digital bi-direction converters -# -# CONFIG_ADT7316 is not set -# end of Analog digital bi-direction converters - -# -# Direct Digital Synthesis -# -CONFIG_AD9832=m -CONFIG_AD9834=m -# end of Direct Digital Synthesis - -# -# Network Analyzer, Impedance Converters -# -# CONFIG_AD5933 is not set -# end of Network Analyzer, Impedance Converters - -# -# Active energy metering IC -# -# CONFIG_ADE7854 is not set -# end of Active energy metering IC - -# -# Resolver to digital converters -# -# CONFIG_AD2S1210 is not set -# end of Resolver to digital converters -# end of IIO staging drivers - -CONFIG_STAGING_MEDIA=y -# CONFIG_VIDEO_MAX96712 is not set -CONFIG_VIDEO_SUNXI=y -CONFIG_VIDEO_SUNXI_CEDRUS=m -# CONFIG_STAGING_MEDIA_DEPRECATED is not set -# CONFIG_STAGING_BOARD is not set -# CONFIG_LTE_GDM724X is not set -CONFIG_FB_TFT=m -CONFIG_FB_TFT_AGM1264K_FL=m -CONFIG_FB_TFT_BD663474=m -CONFIG_FB_TFT_HX8340BN=m -CONFIG_FB_TFT_HX8347D=m -CONFIG_FB_TFT_HX8353D=m -CONFIG_FB_TFT_HX8357D=m -CONFIG_FB_TFT_ILI9163=m -CONFIG_FB_TFT_ILI9320=m -CONFIG_FB_TFT_ILI9325=m -CONFIG_FB_TFT_ILI9340=m -CONFIG_FB_TFT_ILI9341=m -CONFIG_FB_TFT_ILI9481=m -CONFIG_FB_TFT_ILI9486=m -CONFIG_FB_TFT_PCD8544=m -CONFIG_FB_TFT_RA8875=m -CONFIG_FB_TFT_S6D02A1=m -CONFIG_FB_TFT_S6D1121=m -CONFIG_FB_TFT_SEPS525=m -CONFIG_FB_TFT_SH1106=m -CONFIG_FB_TFT_SSD1289=m -CONFIG_FB_TFT_SSD1305=m -CONFIG_FB_TFT_SSD1306=m -CONFIG_FB_TFT_SSD1331=m -CONFIG_FB_TFT_SSD1351=m -CONFIG_FB_TFT_ST7735R=m -CONFIG_FB_TFT_ST7789V=m -CONFIG_FB_TFT_ST7796S=m -CONFIG_FB_TFT_TINYLCD=m -CONFIG_FB_TFT_TLS8204=m -CONFIG_FB_TFT_UC1611=m -CONFIG_FB_TFT_UC1701=m -CONFIG_FB_TFT_UPD161704=m -CONFIG_MOST_COMPONENTS=m -# CONFIG_MOST_NET is not set -# CONFIG_MOST_VIDEO is not set -# CONFIG_MOST_DIM2 is not set -# CONFIG_MOST_I2C is not set -# CONFIG_KS7010 is not set -# CONFIG_PI433 is not set -CONFIG_XIL_AXIS_FIFO=m -# CONFIG_FIELDBUS_DEV is not set -CONFIG_RTL8723CS=m -# CONFIG_GOLDFISH is not set -# CONFIG_CHROME_PLATFORMS is not set -# CONFIG_MELLANOX_PLATFORM is not set -# CONFIG_SURFACE_PLATFORMS is not set -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_COMMON_CLK=y - -# -# Clock driver for ARM Reference designs -# -# CONFIG_CLK_ICST is not set -# CONFIG_CLK_SP810 is not set -# end of Clock driver for ARM Reference designs - -CONFIG_LMK04832=m -CONFIG_COMMON_CLK_MAX9485=m -# CONFIG_COMMON_CLK_SCMI is not set -CONFIG_COMMON_CLK_SCPI=y -# CONFIG_COMMON_CLK_SI5341 is not set -# CONFIG_COMMON_CLK_SI5351 is not set -# CONFIG_COMMON_CLK_SI514 is not set -CONFIG_COMMON_CLK_SI544=m -# CONFIG_COMMON_CLK_SI570 is not set -# CONFIG_COMMON_CLK_CDCE706 is not set -# CONFIG_COMMON_CLK_CDCE925 is not set -# CONFIG_COMMON_CLK_CS2000_CP is not set -# CONFIG_COMMON_CLK_S2MPS11 is not set -CONFIG_COMMON_CLK_AXI_CLKGEN=m -# CONFIG_COMMON_CLK_XGENE is not set -CONFIG_COMMON_CLK_PWM=y -CONFIG_COMMON_CLK_RS9_PCIE=m -# CONFIG_COMMON_CLK_VC5 is not set -CONFIG_COMMON_CLK_VC7=m -CONFIG_COMMON_CLK_BD718XX=m -# CONFIG_COMMON_CLK_FIXED_MMIO is not set -CONFIG_SUNXI_CCU=y -CONFIG_SUN50I_A64_CCU=y -CONFIG_SUN50I_A100_CCU=y -CONFIG_SUN50I_A100_R_CCU=y -CONFIG_SUN50I_H6_CCU=y -CONFIG_SUN50I_H616_CCU=y -CONFIG_SUN50I_H6_R_CCU=y -CONFIG_SUN6I_RTC_CCU=m -CONFIG_SUN8I_H3_CCU=y -CONFIG_SUN8I_DE2_CCU=y -CONFIG_SUN8I_DE33_CCU=y -CONFIG_SUN8I_R_CCU=y -# CONFIG_XILINX_VCU is not set -CONFIG_COMMON_CLK_XLNX_CLKWZRD=m -# CONFIG_HWSPINLOCK is not set - -# -# Clock Source drivers -# -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_CLKSRC_MMIO=y -CONFIG_SUN4I_TIMER=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y -CONFIG_FSL_ERRATUM_A008585=y -# CONFIG_HISILICON_ERRATUM_161010101 is not set -# CONFIG_ARM64_ERRATUM_858921 is not set -CONFIG_SUN50I_ERRATUM_UNKNOWN1=y -# CONFIG_MICROCHIP_PIT64B is not set -# end of Clock Source drivers - -CONFIG_MAILBOX=y -CONFIG_ARM_MHU=y -CONFIG_ARM_MHU_V2=m -# CONFIG_PLATFORM_MHU is not set -# CONFIG_PL320_MBOX is not set -# CONFIG_ALTERA_MBOX is not set -# CONFIG_MAILBOX_TEST is not set -CONFIG_SUN6I_MSGBOX=y -CONFIG_IOMMU_IOVA=y -CONFIG_IOMMU_API=y -CONFIG_IOMMU_SUPPORT=y - -# -# Generic IOMMU Pagetable Support -# -CONFIG_IOMMU_IO_PGTABLE=y -CONFIG_IOMMU_IO_PGTABLE_LPAE=y -# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set -# CONFIG_IOMMU_IO_PGTABLE_DART is not set -# end of Generic IOMMU Pagetable Support - -# CONFIG_IOMMU_DEBUGFS is not set -CONFIG_IOMMU_DEFAULT_DMA_STRICT=y -# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set -# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set -CONFIG_OF_IOMMU=y -CONFIG_IOMMU_DMA=y -CONFIG_SUN50I_IOMMU=y -CONFIG_ARM_SMMU=y -# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set -CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y -# CONFIG_ARM_SMMU_V3 is not set -# CONFIG_VIRTIO_IOMMU is not set - -# -# Remoteproc drivers -# -# CONFIG_REMOTEPROC is not set -# end of Remoteproc drivers - -# -# Rpmsg drivers -# -# CONFIG_RPMSG_QCOM_GLINK_RPM is not set -# CONFIG_RPMSG_VIRTIO is not set -# end of Rpmsg drivers - -# CONFIG_SOUNDWIRE is not set - -# -# SOC (System On Chip) specific Drivers -# - -# -# Amlogic SoC drivers -# -# end of Amlogic SoC drivers - -# -# Broadcom SoC drivers -# -# CONFIG_SOC_BRCMSTB is not set -# end of Broadcom SoC drivers - -# -# NXP/Freescale QorIQ SoC drivers -# -# CONFIG_QUICC_ENGINE is not set -# CONFIG_FSL_RCPM is not set -# end of NXP/Freescale QorIQ SoC drivers - -# -# fujitsu SoC drivers -# -# end of fujitsu SoC drivers - -# -# i.MX SoC drivers -# -# end of i.MX SoC drivers - -# -# Enable LiteX SoC Builder specific drivers -# -CONFIG_LITEX=y -CONFIG_LITEX_SOC_CONTROLLER=m -# end of Enable LiteX SoC Builder specific drivers - -# -# Qualcomm SoC drivers -# -# end of Qualcomm SoC drivers - -CONFIG_SUNXI_MBUS=y -CONFIG_SUNXI_SRAM=y -# CONFIG_SOC_TI is not set - -# -# Xilinx SoC drivers -# -# end of Xilinx SoC drivers -# end of SOC (System On Chip) specific Drivers - -CONFIG_PM_DEVFREQ=y - -# -# DEVFREQ Governors -# -CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -CONFIG_DEVFREQ_GOV_PERFORMANCE=y -CONFIG_DEVFREQ_GOV_POWERSAVE=y -CONFIG_DEVFREQ_GOV_USERSPACE=y -CONFIG_DEVFREQ_GOV_PASSIVE=y - -# -# DEVFREQ Drivers -# -CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ=m -CONFIG_PM_DEVFREQ_EVENT=y -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_FSA9480 is not set -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_MAX3355 is not set -CONFIG_EXTCON_PTN5150=m -# CONFIG_EXTCON_RT8973A is not set -# CONFIG_EXTCON_SM5502 is not set -CONFIG_EXTCON_USB_GPIO=y -CONFIG_EXTCON_USBC_TUSB320=m -# CONFIG_MEMORY is not set -CONFIG_IIO=m -CONFIG_IIO_BUFFER=y -CONFIG_IIO_BUFFER_CB=m -# CONFIG_IIO_BUFFER_DMA is not set -# CONFIG_IIO_BUFFER_DMAENGINE is not set -# CONFIG_IIO_BUFFER_HW_CONSUMER is not set -CONFIG_IIO_KFIFO_BUF=m -CONFIG_IIO_TRIGGERED_BUFFER=m -CONFIG_IIO_CONFIGFS=m -CONFIG_IIO_TRIGGER=y -CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 -CONFIG_IIO_SW_DEVICE=m -CONFIG_IIO_SW_TRIGGER=m -CONFIG_IIO_TRIGGERED_EVENT=m - -# -# Accelerometers -# -CONFIG_ADIS16201=m -CONFIG_ADIS16209=m -CONFIG_ADXL313=m -CONFIG_ADXL313_I2C=m -CONFIG_ADXL313_SPI=m -CONFIG_ADXL345=m -CONFIG_ADXL345_I2C=m -CONFIG_ADXL345_SPI=m -CONFIG_ADXL355=m -CONFIG_ADXL355_I2C=m -CONFIG_ADXL355_SPI=m -CONFIG_ADXL367=m -CONFIG_ADXL367_SPI=m -CONFIG_ADXL367_I2C=m -CONFIG_ADXL372=m -CONFIG_ADXL372_SPI=m -CONFIG_ADXL372_I2C=m -CONFIG_BMA180=m -CONFIG_BMA220=m -CONFIG_BMA400=m -CONFIG_BMA400_I2C=m -CONFIG_BMA400_SPI=m -CONFIG_BMC150_ACCEL=m -CONFIG_BMC150_ACCEL_I2C=m -CONFIG_BMC150_ACCEL_SPI=m -CONFIG_BMI088_ACCEL=m -CONFIG_BMI088_ACCEL_SPI=m -CONFIG_DA280=m -CONFIG_DA311=m -CONFIG_DMARD06=m -CONFIG_DMARD09=m -CONFIG_DMARD10=m -CONFIG_FXLS8962AF=m -CONFIG_FXLS8962AF_I2C=m -CONFIG_FXLS8962AF_SPI=m -CONFIG_HID_SENSOR_ACCEL_3D=m -CONFIG_IIO_ST_ACCEL_3AXIS=m -CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m -CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m -CONFIG_KXSD9=m -CONFIG_KXSD9_SPI=m -CONFIG_KXSD9_I2C=m -CONFIG_KXCJK1013=m -CONFIG_MC3230=m -CONFIG_MMA7455=m -CONFIG_MMA7455_I2C=m -CONFIG_MMA7455_SPI=m -CONFIG_MMA7660=m -CONFIG_MMA8452=m -CONFIG_MMA9551_CORE=m -CONFIG_MMA9551=m -CONFIG_MMA9553=m -CONFIG_MSA311=m -CONFIG_MXC4005=m -CONFIG_MXC6255=m -CONFIG_SCA3000=m -CONFIG_SCA3300=m -CONFIG_STK8312=m -CONFIG_STK8BA50=m -# end of Accelerometers - -# -# Analog to digital converters -# -CONFIG_AD_SIGMA_DELTA=m -CONFIG_AD7091R5=m -CONFIG_AD7124=m -# CONFIG_AD7192 is not set -CONFIG_AD7266=m -# CONFIG_AD7280 is not set -CONFIG_AD7291=m -CONFIG_AD7292=m -CONFIG_AD7298=m -CONFIG_AD7476=m -CONFIG_AD7606=m -CONFIG_AD7606_IFACE_PARALLEL=m -CONFIG_AD7606_IFACE_SPI=m -CONFIG_AD7766=m -CONFIG_AD7768_1=m -# CONFIG_AD7780 is not set -CONFIG_AD7791=m -CONFIG_AD7793=m -CONFIG_AD7887=m -CONFIG_AD7923=m -CONFIG_AD7949=m -CONFIG_AD799X=m -# CONFIG_ADI_AXI_ADC is not set -CONFIG_AXP20X_ADC=m -CONFIG_AXP288_ADC=m -CONFIG_CC10001_ADC=m -CONFIG_ENVELOPE_DETECTOR=m -CONFIG_HI8435=m -# CONFIG_HX711 is not set -CONFIG_INA2XX_ADC=m -CONFIG_LTC2471=m -CONFIG_LTC2485=m -CONFIG_LTC2496=m -CONFIG_LTC2497=m -CONFIG_MAX1027=m -CONFIG_MAX11100=m -CONFIG_MAX1118=m -CONFIG_MAX11205=m -# CONFIG_MAX1241 is not set -CONFIG_MAX1363=m -CONFIG_MAX9611=m -CONFIG_MCP320X=m -CONFIG_MCP3422=m -CONFIG_MCP3911=m -# CONFIG_NAU7802 is not set -CONFIG_QCOM_VADC_COMMON=m -# CONFIG_QCOM_SPMI_IADC is not set -# CONFIG_QCOM_SPMI_VADC is not set -CONFIG_QCOM_SPMI_ADC5=m -CONFIG_RICHTEK_RTQ6056=m -# CONFIG_SD_ADC_MODULATOR is not set -CONFIG_SUN4I_GPADC=m -CONFIG_TI_ADC081C=m -CONFIG_TI_ADC0832=m -CONFIG_TI_ADC084S021=m -CONFIG_TI_ADC12138=m -CONFIG_TI_ADC108S102=m -CONFIG_TI_ADC128S052=m -CONFIG_TI_ADC161S626=m -CONFIG_TI_ADS1015=m -CONFIG_TI_ADS7950=m -CONFIG_TI_ADS8344=m -CONFIG_TI_ADS8688=m -CONFIG_TI_ADS124S08=m -CONFIG_TI_ADS131E08=m -CONFIG_TI_TLC4541=m -CONFIG_TI_TSC2046=m -# CONFIG_VF610_ADC is not set -# CONFIG_XILINX_XADC is not set -# end of Analog to digital converters - -# -# Analog to digital and digital to analog converters -# -CONFIG_AD74413R=m -# end of Analog to digital and digital to analog converters - -# -# Analog Front Ends -# -# CONFIG_IIO_RESCALE is not set -# end of Analog Front Ends - -# -# Amplifiers -# -# CONFIG_AD8366 is not set -CONFIG_ADA4250=m -CONFIG_HMC425=m -# end of Amplifiers - -# -# Capacitance to digital converters -# -# CONFIG_AD7150 is not set -# CONFIG_AD7746 is not set -# end of Capacitance to digital converters - -# -# Chemical Sensors -# -# CONFIG_ATLAS_PH_SENSOR is not set -# CONFIG_ATLAS_EZO_SENSOR is not set -CONFIG_BME680=m -CONFIG_BME680_I2C=m -CONFIG_BME680_SPI=m -# CONFIG_CCS811 is not set -# CONFIG_IAQCORE is not set -CONFIG_PMS7003=m -# CONFIG_SCD30_CORE is not set -CONFIG_SCD4X=m -CONFIG_SENSIRION_SGP30=m -CONFIG_SENSIRION_SGP40=m -CONFIG_SPS30=m -CONFIG_SPS30_I2C=m -CONFIG_SPS30_SERIAL=m -CONFIG_SENSEAIR_SUNRISE_CO2=m -# CONFIG_VZ89X is not set -# end of Chemical Sensors - -# -# Hid Sensor IIO Common -# -CONFIG_HID_SENSOR_IIO_COMMON=m -CONFIG_HID_SENSOR_IIO_TRIGGER=m -# end of Hid Sensor IIO Common - -CONFIG_IIO_MS_SENSORS_I2C=m - -# -# IIO SCMI Sensors -# -CONFIG_IIO_SCMI=m -# end of IIO SCMI Sensors - -# -# SSP Sensor Common -# -# CONFIG_IIO_SSP_SENSORHUB is not set -# end of SSP Sensor Common - -CONFIG_IIO_ST_SENSORS_I2C=m -CONFIG_IIO_ST_SENSORS_SPI=m -CONFIG_IIO_ST_SENSORS_CORE=m - -# -# Digital to analog converters -# -CONFIG_AD3552R=m -# CONFIG_AD5064 is not set -# CONFIG_AD5360 is not set -# CONFIG_AD5380 is not set -# CONFIG_AD5421 is not set -# CONFIG_AD5446 is not set -# CONFIG_AD5449 is not set -# CONFIG_AD5592R is not set -# CONFIG_AD5593R is not set -# CONFIG_AD5504 is not set -# CONFIG_AD5624R_SPI is not set -CONFIG_LTC2688=m -CONFIG_AD5686=m -CONFIG_AD5686_SPI=m -CONFIG_AD5696_I2C=m -# CONFIG_AD5755 is not set -CONFIG_AD5758=m -# CONFIG_AD5761 is not set -# CONFIG_AD5764 is not set -CONFIG_AD5766=m -CONFIG_AD5770R=m -# CONFIG_AD5791 is not set -CONFIG_AD7293=m -# CONFIG_AD7303 is not set -# CONFIG_AD8801 is not set -# CONFIG_DPOT_DAC is not set -# CONFIG_DS4424 is not set -CONFIG_LTC1660=m -# CONFIG_LTC2632 is not set -# CONFIG_M62332 is not set -# CONFIG_MAX517 is not set -# CONFIG_MAX5821 is not set -# CONFIG_MCP4725 is not set -# CONFIG_MCP4922 is not set -# CONFIG_TI_DAC082S085 is not set -CONFIG_TI_DAC5571=m -CONFIG_TI_DAC7311=m -CONFIG_TI_DAC7612=m -# CONFIG_VF610_DAC is not set -# end of Digital to analog converters - -# -# IIO dummy driver -# -CONFIG_IIO_SIMPLE_DUMMY=m -# CONFIG_IIO_SIMPLE_DUMMY_EVENTS is not set -# CONFIG_IIO_SIMPLE_DUMMY_BUFFER is not set -# end of IIO dummy driver - -# -# Filters -# -CONFIG_ADMV8818=m -# end of Filters - -# -# Frequency Synthesizers DDS/PLL -# - -# -# Clock Generator/Distribution -# -# CONFIG_AD9523 is not set -# end of Clock Generator/Distribution - -# -# Phase-Locked Loop (PLL) frequency synthesizers -# -# CONFIG_ADF4350 is not set -# CONFIG_ADF4371 is not set -# CONFIG_ADMV1013 is not set -CONFIG_ADMV1014=m -CONFIG_ADMV4420=m -CONFIG_ADRF6780=m -# end of Phase-Locked Loop (PLL) frequency synthesizers -# end of Frequency Synthesizers DDS/PLL - -# -# Digital gyroscope sensors -# -CONFIG_ADIS16080=m -CONFIG_ADIS16130=m -CONFIG_ADIS16136=m -CONFIG_ADIS16260=m -# CONFIG_ADXRS290 is not set -CONFIG_ADXRS450=m -CONFIG_BMG160=m -CONFIG_BMG160_I2C=m -CONFIG_BMG160_SPI=m -CONFIG_FXAS21002C=m -CONFIG_FXAS21002C_I2C=m -CONFIG_FXAS21002C_SPI=m -CONFIG_HID_SENSOR_GYRO_3D=m -CONFIG_MPU3050=m -CONFIG_MPU3050_I2C=m -CONFIG_IIO_ST_GYRO_3AXIS=m -CONFIG_IIO_ST_GYRO_I2C_3AXIS=m -CONFIG_IIO_ST_GYRO_SPI_3AXIS=m -CONFIG_ITG3200=m -# end of Digital gyroscope sensors - -# -# Health Sensors -# - -# -# Heart Rate Monitors -# -# CONFIG_AFE4403 is not set -# CONFIG_AFE4404 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX30102 is not set -# end of Heart Rate Monitors -# end of Health Sensors - -# -# Humidity sensors -# -CONFIG_AM2315=m -CONFIG_DHT11=m -CONFIG_HDC100X=m -# CONFIG_HDC2010 is not set -CONFIG_HID_SENSOR_HUMIDITY=m -CONFIG_HTS221=m -CONFIG_HTS221_I2C=m -CONFIG_HTS221_SPI=m -CONFIG_HTU21=m -CONFIG_SI7005=m -CONFIG_SI7020=m -# end of Humidity sensors - -# -# Inertial measurement units -# -# CONFIG_ADIS16400 is not set -CONFIG_ADIS16460=m -# CONFIG_ADIS16475 is not set -# CONFIG_ADIS16480 is not set -# CONFIG_BMI160_I2C is not set -# CONFIG_BMI160_SPI is not set -CONFIG_BOSCH_BNO055=m -CONFIG_BOSCH_BNO055_SERIAL=m -CONFIG_BOSCH_BNO055_I2C=m -CONFIG_FXOS8700=m -CONFIG_FXOS8700_I2C=m -CONFIG_FXOS8700_SPI=m -# CONFIG_KMX61 is not set -# CONFIG_INV_ICM42600_I2C is not set -# CONFIG_INV_ICM42600_SPI is not set -# CONFIG_INV_MPU6050_I2C is not set -# CONFIG_INV_MPU6050_SPI is not set -# CONFIG_IIO_ST_LSM6DSX is not set -CONFIG_IIO_ST_LSM9DS0=m -CONFIG_IIO_ST_LSM9DS0_I2C=m -CONFIG_IIO_ST_LSM9DS0_SPI=m -# end of Inertial measurement units - -CONFIG_IIO_ADIS_LIB=m -CONFIG_IIO_ADIS_LIB_BUFFER=y - -# -# Light sensors -# -CONFIG_ADJD_S311=m -CONFIG_ADUX1020=m -CONFIG_AL3010=m -CONFIG_AL3320A=m -CONFIG_APDS9300=m -CONFIG_APDS9960=m -# CONFIG_AS73211 is not set -CONFIG_BH1750=m -CONFIG_BH1780=m -CONFIG_CM32181=m -CONFIG_CM3232=m -CONFIG_CM3323=m -CONFIG_CM3605=m -CONFIG_CM36651=m -CONFIG_GP2AP002=m -CONFIG_GP2AP020A00F=m -CONFIG_IQS621_ALS=m -CONFIG_SENSORS_ISL29018=m -CONFIG_SENSORS_ISL29028=m -CONFIG_ISL29125=m -CONFIG_HID_SENSOR_ALS=m -CONFIG_HID_SENSOR_PROX=m -CONFIG_JSA1212=m -CONFIG_RPR0521=m -CONFIG_LTR501=m -CONFIG_LTRF216A=m -CONFIG_LV0104CS=m -CONFIG_MAX44000=m -CONFIG_MAX44009=m -CONFIG_NOA1305=m -CONFIG_OPT3001=m -CONFIG_PA12203001=m -CONFIG_SI1133=m -CONFIG_SI1145=m -CONFIG_STK3310=m -CONFIG_ST_UVIS25=m -CONFIG_ST_UVIS25_I2C=m -CONFIG_ST_UVIS25_SPI=m -CONFIG_TCS3414=m -CONFIG_TCS3472=m -CONFIG_SENSORS_TSL2563=m -CONFIG_TSL2583=m -CONFIG_TSL2591=m -CONFIG_TSL2772=m -CONFIG_TSL4531=m -CONFIG_US5182D=m -CONFIG_VCNL4000=m -CONFIG_VCNL4035=m -CONFIG_VEML6030=m -CONFIG_VEML6070=m -CONFIG_VL6180=m -CONFIG_ZOPT2201=m -# end of Light sensors - -# -# Magnetometer sensors -# -CONFIG_AK8974=m -CONFIG_AK8975=m -CONFIG_AK09911=m -CONFIG_BMC150_MAGN=m -CONFIG_BMC150_MAGN_I2C=m -CONFIG_BMC150_MAGN_SPI=m -CONFIG_MAG3110=m -CONFIG_HID_SENSOR_MAGNETOMETER_3D=m -CONFIG_MMC35240=m -CONFIG_IIO_ST_MAGN_3AXIS=m -CONFIG_IIO_ST_MAGN_I2C_3AXIS=m -CONFIG_IIO_ST_MAGN_SPI_3AXIS=m -CONFIG_SENSORS_HMC5843=m -CONFIG_SENSORS_HMC5843_I2C=m -CONFIG_SENSORS_HMC5843_SPI=m -CONFIG_SENSORS_RM3100=m -CONFIG_SENSORS_RM3100_I2C=m -CONFIG_SENSORS_RM3100_SPI=m -CONFIG_YAMAHA_YAS530=m -# end of Magnetometer sensors - -# -# Multiplexers -# -# CONFIG_IIO_MUX is not set -# end of Multiplexers - -# -# Inclinometer sensors -# -CONFIG_HID_SENSOR_INCLINOMETER_3D=m -CONFIG_HID_SENSOR_DEVICE_ROTATION=m -# end of Inclinometer sensors - -# -# Triggers - standalone -# -CONFIG_IIO_HRTIMER_TRIGGER=m -# CONFIG_IIO_INTERRUPT_TRIGGER is not set -CONFIG_IIO_TIGHTLOOP_TRIGGER=m -# CONFIG_IIO_SYSFS_TRIGGER is not set -# end of Triggers - standalone - -# -# Linear and angular position sensors -# -CONFIG_IQS624_POS=m -CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=m -# end of Linear and angular position sensors - -# -# Digital potentiometers -# -CONFIG_AD5110=m -CONFIG_AD5272=m -CONFIG_DS1803=m -CONFIG_MAX5432=m -# CONFIG_MAX5481 is not set -# CONFIG_MAX5487 is not set -CONFIG_MCP4018=m -# CONFIG_MCP4131 is not set -# CONFIG_MCP4531 is not set -CONFIG_MCP41010=m -# CONFIG_TPL0102 is not set -# end of Digital potentiometers - -# -# Digital potentiostats -# -# CONFIG_LMP91000 is not set -# end of Digital potentiostats - -# -# Pressure sensors -# -# CONFIG_ABP060MG is not set -CONFIG_BMP280=m -CONFIG_BMP280_I2C=m -CONFIG_BMP280_SPI=m -CONFIG_DLHL60D=m -# CONFIG_DPS310 is not set -# CONFIG_HID_SENSOR_PRESS is not set -# CONFIG_HP03 is not set -CONFIG_ICP10100=m -# CONFIG_MPL115_I2C is not set -# CONFIG_MPL115_SPI is not set -# CONFIG_MPL3115 is not set -# CONFIG_MS5611 is not set -# CONFIG_MS5637 is not set -# CONFIG_IIO_ST_PRESS is not set -# CONFIG_T5403 is not set -# CONFIG_HP206C is not set -# CONFIG_ZPA2326 is not set -# end of Pressure sensors - -# -# Lightning sensors -# -# CONFIG_AS3935 is not set -# end of Lightning sensors - -# -# Proximity and distance sensors -# -CONFIG_ISL29501=m -# CONFIG_LIDAR_LITE_V2 is not set -CONFIG_MB1232=m -CONFIG_PING=m -# CONFIG_RFD77402 is not set -# CONFIG_SRF04 is not set -CONFIG_SX_COMMON=m -# CONFIG_SX9310 is not set -CONFIG_SX9324=m -CONFIG_SX9360=m -# CONFIG_SX9500 is not set -# CONFIG_SRF08 is not set -# CONFIG_VCNL3020 is not set -CONFIG_VL53L0X_I2C=m -# end of Proximity and distance sensors - -# -# Resolver to digital converters -# -# CONFIG_AD2S90 is not set -# CONFIG_AD2S1200 is not set -# end of Resolver to digital converters - -# -# Temperature sensors -# -CONFIG_IQS620AT_TEMP=m -CONFIG_LTC2983=m -CONFIG_MAXIM_THERMOCOUPLE=m -CONFIG_HID_SENSOR_TEMP=m -CONFIG_MLX90614=m -# CONFIG_MLX90632 is not set -CONFIG_TMP006=m -CONFIG_TMP007=m -CONFIG_TMP117=m -CONFIG_TSYS01=m -CONFIG_TSYS02D=m -CONFIG_MAX31856=m -CONFIG_MAX31865=m -# end of Temperature sensors - -CONFIG_PWM=y -CONFIG_PWM_SYSFS=y -CONFIG_PWM_ATMEL_TCB=m -CONFIG_PWM_CLK=m -# CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_IQS620A is not set -CONFIG_PWM_NTXEC=m -CONFIG_PWM_PCA9685=m -CONFIG_PWM_SUN4I=m -CONFIG_PWM_SUNXI_ENHANCE=m -CONFIG_PWM_XILINX=m - -# -# IRQ chip support -# -CONFIG_IRQCHIP=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_MAX_NR=1 -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -# CONFIG_AL_FIC is not set -CONFIG_MADERA_IRQ=m -CONFIG_SUN6I_R_INTC=y -CONFIG_SUNXI_NMI_INTC=y -# CONFIG_XILINX_INTC is not set -CONFIG_PARTITION_PERCPU=y -# end of IRQ chip support - -# CONFIG_IPACK_BUS is not set -CONFIG_ARCH_HAS_RESET_CONTROLLER=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RESET_SCMI=y -CONFIG_RESET_SIMPLE=y -CONFIG_RESET_SUNXI=y -# CONFIG_RESET_TI_SYSCON is not set -CONFIG_RESET_TI_TPS380X=m - -# -# PHY Subsystem -# -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PHY_MIPI_DPHY=y -# CONFIG_PHY_XGENE is not set -CONFIG_PHY_CAN_TRANSCEIVER=m -CONFIG_PHY_SUN4I_USB=y -CONFIG_PHY_SUN6I_MIPI_DPHY=y -CONFIG_PHY_SUN9I_USB=y -CONFIG_PHY_SUN50I_USB3=y - -# -# PHY drivers for Broadcom platforms -# -# CONFIG_BCM_KONA_USB2_PHY is not set -# end of PHY drivers for Broadcom platforms - -CONFIG_PHY_CADENCE_TORRENT=m -CONFIG_PHY_CADENCE_DPHY=m -CONFIG_PHY_CADENCE_DPHY_RX=m -CONFIG_PHY_CADENCE_SIERRA=m -# CONFIG_PHY_CADENCE_SALVO is not set -# CONFIG_PHY_PXA_28NM_HSIC is not set -# CONFIG_PHY_PXA_28NM_USB2 is not set -CONFIG_PHY_LAN966X_SERDES=m -# CONFIG_PHY_CPCAP_USB is not set -CONFIG_PHY_MAPPHONE_MDM6600=m -CONFIG_PHY_OCELOT_SERDES=m -CONFIG_PHY_SAMSUNG_USB2=y -# end of PHY Subsystem - -# CONFIG_POWERCAP is not set -# CONFIG_MCB is not set - -# -# Performance monitor support -# -CONFIG_ARM_CCI_PMU=m -# CONFIG_ARM_CCI400_PMU is not set -# CONFIG_ARM_CCI5xx_PMU is not set -# CONFIG_ARM_CCN is not set -# CONFIG_ARM_CMN is not set -CONFIG_ARM_PMU=y -CONFIG_ARM_DSU_PMU=m -CONFIG_ARM_SPE_PMU=m -# end of Performance monitor support - -CONFIG_RAS=y - -# -# Android -# -CONFIG_ANDROID_BINDER_IPC=y -CONFIG_ANDROID_BINDERFS=y -CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder,anbox-binder,anbox-hwbinder,anbox-vndbinder" -# CONFIG_ANDROID_BINDER_IPC_SELFTEST is not set -# end of Android - -# CONFIG_LIBNVDIMM is not set -# CONFIG_DAX is not set -CONFIG_NVMEM=y -CONFIG_NVMEM_SYSFS=y -CONFIG_NVMEM_RAVE_SP_EEPROM=m -CONFIG_NVMEM_RMEM=m -CONFIG_NVMEM_SPMI_SDAM=m -CONFIG_NVMEM_SUNXI_SID=y -CONFIG_NVMEM_U_BOOT_ENV=m - -# -# HW tracing support -# -# CONFIG_STM is not set -# CONFIG_INTEL_TH is not set -# end of HW tracing support - -# CONFIG_FPGA is not set -# CONFIG_FSI is not set -# CONFIG_TEE is not set -CONFIG_MULTIPLEXER=m - -# -# Multiplexer drivers -# -CONFIG_MUX_ADG792A=m -CONFIG_MUX_ADGS1408=m -CONFIG_MUX_GPIO=m -CONFIG_MUX_MMIO=m -# end of Multiplexer drivers - -CONFIG_PM_OPP=y -# CONFIG_SIOX is not set -# CONFIG_SLIMBUS is not set -# CONFIG_INTERCONNECT is not set -CONFIG_COUNTER=m -CONFIG_INTERRUPT_CNT=m -CONFIG_FTM_QUADDEC=m -# CONFIG_MICROCHIP_TCB_CAPTURE is not set -CONFIG_MOST=m -# CONFIG_MOST_USB_HDM is not set -# CONFIG_MOST_CDEV is not set -CONFIG_MOST_SND=m -CONFIG_PECI=m -CONFIG_PECI_CPU=m -# CONFIG_HTE is not set -# end of Device Drivers - -# -# File systems -# -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_VALIDATE_FS_PARSER=y -CONFIG_FS_IOMAP=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_EXT4_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_XFS_FS=m -CONFIG_XFS_SUPPORT_V4=y -# CONFIG_XFS_QUOTA is not set -CONFIG_XFS_POSIX_ACL=y -CONFIG_XFS_RT=y -# CONFIG_XFS_ONLINE_SCRUB is not set -# CONFIG_XFS_WARN is not set -# CONFIG_XFS_DEBUG is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_BTRFS_FS=y -CONFIG_BTRFS_FS_POSIX_ACL=y -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set -# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set -# CONFIG_BTRFS_DEBUG is not set -# CONFIG_BTRFS_ASSERT is not set -# CONFIG_BTRFS_FS_REF_VERIFY is not set -# CONFIG_NILFS2_FS is not set -CONFIG_F2FS_FS=y -CONFIG_F2FS_STAT_FS=y -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_FS_POSIX_ACL=y -CONFIG_F2FS_FS_SECURITY=y -# CONFIG_F2FS_CHECK_FS is not set -# CONFIG_F2FS_FAULT_INJECTION is not set -CONFIG_F2FS_FS_COMPRESSION=y -CONFIG_F2FS_FS_LZO=y -CONFIG_F2FS_FS_LZORLE=y -CONFIG_F2FS_FS_LZ4=y -CONFIG_F2FS_FS_LZ4HC=y -CONFIG_F2FS_FS_ZSTD=y -CONFIG_F2FS_IOSTAT=y -# CONFIG_F2FS_UNFAIR_RWSEM is not set -CONFIG_ZONEFS_FS=m -CONFIG_FS_POSIX_ACL=y -CONFIG_EXPORTFS=y -CONFIG_EXPORTFS_BLOCK_OPS=y -CONFIG_FILE_LOCKING=y -CONFIG_FS_ENCRYPTION=y -CONFIG_FS_ENCRYPTION_ALGS=y -# CONFIG_FS_VERITY is not set -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_FANOTIFY=y -CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y -CONFIG_QUOTA=y -CONFIG_QUOTA_NETLINK_INTERFACE=y -CONFIG_PRINT_QUOTA_WARNING=y -# CONFIG_QUOTA_DEBUG is not set -CONFIG_QUOTA_TREE=m -CONFIG_QFMT_V1=m -CONFIG_QFMT_V2=m -CONFIG_QUOTACTL=y -CONFIG_AUTOFS4_FS=y -CONFIG_AUTOFS_FS=y -CONFIG_FUSE_FS=m -CONFIG_CUSE=m -CONFIG_VIRTIO_FS=m -CONFIG_OVERLAY_FS=m -# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set -CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y -# CONFIG_OVERLAY_FS_INDEX is not set -# CONFIG_OVERLAY_FS_XINO_AUTO is not set -# CONFIG_OVERLAY_FS_METACOPY is not set - -# -# Caches -# -CONFIG_NETFS_SUPPORT=m -# CONFIG_NETFS_STATS is not set -CONFIG_FSCACHE=m -# CONFIG_FSCACHE_STATS is not set -# CONFIG_FSCACHE_DEBUG is not set -CONFIG_CACHEFILES=m -# CONFIG_CACHEFILES_DEBUG is not set -# CONFIG_CACHEFILES_ERROR_INJECTION is not set -# CONFIG_CACHEFILES_ONDEMAND is not set -# end of Caches - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=m -# end of CD-ROM/DVD Filesystems - -# -# DOS/FAT/EXFAT/NT Filesystems -# -CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_FAT_DEFAULT_UTF8 is not set -CONFIG_EXFAT_FS=m -CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" -# CONFIG_NTFS_FS is not set -CONFIG_NTFS3_FS=m -# CONFIG_NTFS3_64BIT_CLUSTER is not set -CONFIG_NTFS3_LZX_XPRESS=y -CONFIG_NTFS3_FS_POSIX_ACL=y -# end of DOS/FAT/EXFAT/NT Filesystems - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PROC_CHILDREN=y -CONFIG_KERNFS=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TMPFS_XATTR=y -# CONFIG_TMPFS_INODE64 is not set -CONFIG_ARCH_SUPPORTS_HUGETLBFS=y -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_MEMFD_CREATE=y -CONFIG_ARCH_HAS_GIGANTIC_PAGE=y -CONFIG_CONFIGFS_FS=y -# end of Pseudo filesystems - -CONFIG_MISC_FILESYSTEMS=y -CONFIG_ORANGEFS_FS=m -CONFIG_ADFS_FS=m -# CONFIG_ADFS_FS_RW is not set -CONFIG_AFFS_FS=m -CONFIG_ECRYPT_FS=y -CONFIG_ECRYPT_FS_MESSAGING=y -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_JFFS2_FS=m -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -CONFIG_JFFS2_FS_XATTR=y -CONFIG_JFFS2_FS_POSIX_ACL=y -CONFIG_JFFS2_FS_SECURITY=y -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_LZO=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_JFFS2_CMODE_NONE is not set -# CONFIG_JFFS2_CMODE_PRIORITY is not set -# CONFIG_JFFS2_CMODE_SIZE is not set -CONFIG_JFFS2_CMODE_FAVOURLZO=y -CONFIG_CRAMFS=m -CONFIG_CRAMFS_BLOCKDEV=y -CONFIG_CRAMFS_MTD=y -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_FILE_CACHE is not set -CONFIG_SQUASHFS_FILE_DIRECT=y -CONFIG_SQUASHFS_DECOMP_SINGLE=y -# CONFIG_SQUASHFS_DECOMP_MULTI is not set -# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set -CONFIG_SQUASHFS_XATTR=y -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SQUASHFS_LZ4=y -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -CONFIG_SQUASHFS_ZSTD=y -# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -CONFIG_VXFS_FS=m -CONFIG_MINIX_FS=m -CONFIG_OMFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_QNX6FS_FS=m -# CONFIG_QNX6FS_DEBUG is not set -CONFIG_ROMFS_FS=m -CONFIG_ROMFS_BACKED_BY_BLOCK=y -# CONFIG_ROMFS_BACKED_BY_MTD is not set -# CONFIG_ROMFS_BACKED_BY_BOTH is not set -CONFIG_ROMFS_ON_BLOCK=y -CONFIG_PSTORE=y -CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 -CONFIG_PSTORE_DEFLATE_COMPRESS=y -# CONFIG_PSTORE_LZO_COMPRESS is not set -# CONFIG_PSTORE_LZ4_COMPRESS is not set -# CONFIG_PSTORE_LZ4HC_COMPRESS is not set -# CONFIG_PSTORE_842_COMPRESS is not set -# CONFIG_PSTORE_ZSTD_COMPRESS is not set -CONFIG_PSTORE_COMPRESS=y -CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y -CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" -# CONFIG_PSTORE_CONSOLE is not set -# CONFIG_PSTORE_PMSG is not set -CONFIG_PSTORE_RAM=m -CONFIG_PSTORE_ZONE=m -CONFIG_PSTORE_BLK=m -CONFIG_PSTORE_BLK_BLKDEV="m" -CONFIG_PSTORE_BLK_KMSG_SIZE=64 -CONFIG_PSTORE_BLK_MAX_REASON=2 -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_UFS_DEBUG is not set -CONFIG_EROFS_FS=m -# CONFIG_EROFS_FS_DEBUG is not set -CONFIG_EROFS_FS_XATTR=y -CONFIG_EROFS_FS_POSIX_ACL=y -CONFIG_EROFS_FS_SECURITY=y -# CONFIG_EROFS_FS_ZIP is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=m -CONFIG_NFS_V2=m -CONFIG_NFS_V3=m -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=m -CONFIG_NFS_SWAP=y -CONFIG_NFS_V4_1=y -CONFIG_NFS_V4_2=y -CONFIG_PNFS_FILE_LAYOUT=m -CONFIG_PNFS_BLOCK=m -CONFIG_PNFS_FLEXFILE_LAYOUT=m -CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" -CONFIG_NFS_V4_1_MIGRATION=y -CONFIG_NFS_V4_SECURITY_LABEL=y -CONFIG_NFS_FSCACHE=y -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_USE_KERNEL_DNS=y -CONFIG_NFS_DEBUG=y -CONFIG_NFS_DISABLE_UDP_SUPPORT=y -# CONFIG_NFS_V4_2_READ_PLUS is not set -CONFIG_NFSD=m -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_NFSD_PNFS=y -CONFIG_NFSD_BLOCKLAYOUT=y -CONFIG_NFSD_SCSILAYOUT=y -CONFIG_NFSD_FLEXFILELAYOUT=y -# CONFIG_NFSD_V4_2_INTER_SSC is not set -CONFIG_NFSD_V4_SECURITY_LABEL=y -CONFIG_GRACE_PERIOD=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=m -CONFIG_NFS_COMMON=y -CONFIG_NFS_V4_2_SSC_HELPER=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m -CONFIG_SUNRPC_BACKCHANNEL=y -CONFIG_SUNRPC_SWAP=y -CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES is not set -CONFIG_SUNRPC_DEBUG=y -CONFIG_CEPH_FS=m -CONFIG_CEPH_FSCACHE=y -CONFIG_CEPH_FS_POSIX_ACL=y -CONFIG_CEPH_FS_SECURITY_LABEL=y -CONFIG_CIFS=m -# CONFIG_CIFS_STATS2 is not set -CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -CONFIG_CIFS_UPCALL=y -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -CONFIG_CIFS_DEBUG=y -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set -CONFIG_CIFS_DFS_UPCALL=y -# CONFIG_CIFS_SWN_UPCALL is not set -CONFIG_CIFS_FSCACHE=y -CONFIG_SMB_SERVER=m -CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=y -CONFIG_SMB_SERVER_KERBEROS5=y -CONFIG_SMBFS=m -CONFIG_CODA_FS=m -CONFIG_AFS_FS=m -# CONFIG_AFS_DEBUG is not set -CONFIG_AFS_FSCACHE=y -# CONFIG_AFS_DEBUG_CURSOR is not set -CONFIG_9P_FS=m -CONFIG_9P_FSCACHE=y -CONFIG_9P_FS_POSIX_ACL=y -CONFIG_9P_FS_SECURITY=y -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_MAC_ROMAN=m -CONFIG_NLS_MAC_CELTIC=m -CONFIG_NLS_MAC_CENTEURO=m -CONFIG_NLS_MAC_CROATIAN=m -CONFIG_NLS_MAC_CYRILLIC=m -CONFIG_NLS_MAC_GAELIC=m -CONFIG_NLS_MAC_GREEK=m -CONFIG_NLS_MAC_ICELAND=m -CONFIG_NLS_MAC_INUIT=m -CONFIG_NLS_MAC_ROMANIAN=m -CONFIG_NLS_MAC_TURKISH=m -CONFIG_NLS_UTF8=m -CONFIG_DLM=m -# CONFIG_DLM_DEPRECATED_API is not set -# CONFIG_DLM_DEBUG is not set -CONFIG_UNICODE=y -# CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set -CONFIG_IO_WQ=y -# end of File systems - -# -# Security options -# -CONFIG_KEYS=y -CONFIG_KEYS_REQUEST_CACHE=y -CONFIG_PERSISTENT_KEYRINGS=y -CONFIG_TRUSTED_KEYS=y -CONFIG_TRUSTED_KEYS_TPM=y -CONFIG_ENCRYPTED_KEYS=y -# CONFIG_USER_DECRYPTED_DATA is not set -CONFIG_KEY_DH_OPERATIONS=y -# CONFIG_SECURITY_DMESG_RESTRICT is not set -CONFIG_SECURITY=y -CONFIG_SECURITYFS=y -CONFIG_SECURITY_NETWORK=y -CONFIG_SECURITY_NETWORK_XFRM=y -CONFIG_SECURITY_PATH=y -CONFIG_LSM_MMAP_MIN_ADDR=0 -CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -CONFIG_HARDENED_USERCOPY=y -CONFIG_FORTIFY_SOURCE=y -# CONFIG_STATIC_USERMODEHELPER is not set -CONFIG_SECURITY_SELINUX=y -CONFIG_SECURITY_SELINUX_BOOTPARAM=y -# CONFIG_SECURITY_SELINUX_DISABLE is not set -CONFIG_SECURITY_SELINUX_DEVELOP=y -CONFIG_SECURITY_SELINUX_AVC_STATS=y -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 -CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9 -CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256 -CONFIG_SECURITY_SMACK=y -# CONFIG_SECURITY_SMACK_BRINGUP is not set -CONFIG_SECURITY_SMACK_NETFILTER=y -CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y -CONFIG_SECURITY_TOMOYO=y -CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048 -CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024 -# CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set -CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" -CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" -# CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING is not set -CONFIG_SECURITY_APPARMOR=y -# CONFIG_SECURITY_APPARMOR_DEBUG is not set -CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY=y -CONFIG_SECURITY_APPARMOR_HASH=y -CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y -CONFIG_SECURITY_APPARMOR_EXPORT_BINARY=y -CONFIG_SECURITY_APPARMOR_PARANOID_LOAD=y -# CONFIG_SECURITY_LOADPIN is not set -CONFIG_SECURITY_YAMA=y -CONFIG_SECURITY_SAFESETID=y -# CONFIG_SECURITY_LOCKDOWN_LSM is not set -# CONFIG_SECURITY_LANDLOCK is not set -CONFIG_INTEGRITY=y -CONFIG_INTEGRITY_SIGNATURE=y -CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y -CONFIG_INTEGRITY_TRUSTED_KEYRING=y -CONFIG_INTEGRITY_PLATFORM_KEYRING=y -CONFIG_INTEGRITY_AUDIT=y -CONFIG_IMA=y -CONFIG_IMA_MEASURE_PCR_IDX=10 -CONFIG_IMA_LSM_RULES=y -CONFIG_IMA_NG_TEMPLATE=y -# CONFIG_IMA_SIG_TEMPLATE is not set -CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng" -CONFIG_IMA_DEFAULT_HASH_SHA1=y -# CONFIG_IMA_DEFAULT_HASH_SHA256 is not set -# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set -CONFIG_IMA_DEFAULT_HASH="sha1" -# CONFIG_IMA_WRITE_POLICY is not set -# CONFIG_IMA_READ_POLICY is not set -CONFIG_IMA_APPRAISE=y -# CONFIG_IMA_ARCH_POLICY is not set -# CONFIG_IMA_APPRAISE_BUILD_POLICY is not set -CONFIG_IMA_APPRAISE_BOOTPARAM=y -# CONFIG_IMA_APPRAISE_MODSIG is not set -# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set -# CONFIG_IMA_BLACKLIST_KEYRING is not set -# CONFIG_IMA_LOAD_X509 is not set -CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y -CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y -# CONFIG_IMA_DISABLE_HTABLE is not set -CONFIG_EVM=y -CONFIG_EVM_ATTR_FSUUID=y -CONFIG_EVM_EXTRA_SMACK_XATTRS=y -# CONFIG_EVM_ADD_XATTRS is not set -# CONFIG_EVM_LOAD_X509 is not set -# CONFIG_DEFAULT_SECURITY_SELINUX is not set -# CONFIG_DEFAULT_SECURITY_SMACK is not set -# CONFIG_DEFAULT_SECURITY_TOMOYO is not set -CONFIG_DEFAULT_SECURITY_APPARMOR=y -# CONFIG_DEFAULT_SECURITY_DAC is not set -CONFIG_LSM="lockdown,yama,integrity,apparmor" - -# -# Kernel hardening options -# - -# -# Memory initialization -# -CONFIG_INIT_STACK_NONE=y -# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set -# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set -CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y -# CONFIG_ZERO_CALL_USED_REGS is not set -# end of Memory initialization - -CONFIG_RANDSTRUCT_NONE=y -# end of Kernel hardening options -# end of Security options - -CONFIG_XOR_BLOCKS=y -CONFIG_ASYNC_CORE=y -CONFIG_ASYNC_MEMCPY=y -CONFIG_ASYNC_XOR=y -CONFIG_ASYNC_PQ=y -CONFIG_ASYNC_RAID6_RECOV=y -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_SKCIPHER=y -CONFIG_CRYPTO_SKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RNG_DEFAULT=y -CONFIG_CRYPTO_AKCIPHER2=y -CONFIG_CRYPTO_AKCIPHER=y -CONFIG_CRYPTO_KPP2=y -CONFIG_CRYPTO_KPP=y -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_USER=m -CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_PCRYPT=m -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_AUTHENC=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_ENGINE=y -# end of Crypto core or helper - -# -# Public-key cryptography -# -CONFIG_CRYPTO_RSA=y -CONFIG_CRYPTO_DH=y -# CONFIG_CRYPTO_DH_RFC7919_GROUPS is not set -CONFIG_CRYPTO_ECC=m -CONFIG_CRYPTO_ECDH=m -CONFIG_CRYPTO_ECDSA=m -CONFIG_CRYPTO_ECRDSA=m -# CONFIG_CRYPTO_SM2 is not set -CONFIG_CRYPTO_CURVE25519=m -# end of Public-key cryptography - -# -# Block ciphers -# -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARIA=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_BLOWFISH_COMMON=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAST_COMMON=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_SEED=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_SM4=m -CONFIG_CRYPTO_SM4_GENERIC=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -# end of Block ciphers - -# -# Length-preserving ciphers and modes -# -CONFIG_CRYPTO_ADIANTUM=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_CHACHA20=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CFB=m -CONFIG_CRYPTO_CTR=y -CONFIG_CRYPTO_CTS=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_HCTR2=m -CONFIG_CRYPTO_KEYWRAP=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_OFB=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XCTR=m -CONFIG_CRYPTO_XTS=y -CONFIG_CRYPTO_NHPOLY1305=m -# end of Length-preserving ciphers and modes - -# -# AEAD (authenticated encryption with associated data) ciphers -# -CONFIG_CRYPTO_AEGIS128=m -CONFIG_CRYPTO_AEGIS128_SIMD=y -CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_SEQIV=y -CONFIG_CRYPTO_ECHAINIV=m -CONFIG_CRYPTO_ESSIV=m -# end of AEAD (authenticated encryption with associated data) ciphers - -# -# Hashes, digests, and MACs -# -CONFIG_CRYPTO_BLAKE2B=y -CONFIG_CRYPTO_CMAC=m -CONFIG_CRYPTO_GHASH=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_POLYVAL=m -CONFIG_CRYPTO_POLY1305=m -CONFIG_CRYPTO_RMD160=m -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_SHA3=m -CONFIG_CRYPTO_SM3=m -CONFIG_CRYPTO_SM3_GENERIC=m -CONFIG_CRYPTO_STREEBOG=m -CONFIG_CRYPTO_VMAC=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_XXHASH=y -# end of Hashes, digests, and MACs - -# -# CRCs (cyclic redundancy checks) -# -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_CRC64_ROCKSOFT=y -# end of CRCs (cyclic redundancy checks) - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_842=m -CONFIG_CRYPTO_LZ4=m -CONFIG_CRYPTO_LZ4HC=m -CONFIG_CRYPTO_ZSTD=y -# end of Compression - -# -# Random number generation -# -CONFIG_CRYPTO_ANSI_CPRNG=m -CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_DRBG_HMAC=y -# CONFIG_CRYPTO_DRBG_HASH is not set -# CONFIG_CRYPTO_DRBG_CTR is not set -CONFIG_CRYPTO_DRBG=y -CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_KDF800108_CTR=y -# end of Random number generation - -# -# Userspace interface -# -CONFIG_CRYPTO_USER_API=m -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -CONFIG_CRYPTO_USER_API_RNG=m -# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set -CONFIG_CRYPTO_USER_API_AEAD=m -CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y -# CONFIG_CRYPTO_STATS is not set -# end of Userspace interface - -CONFIG_CRYPTO_HASH_INFO=y -# CONFIG_CRYPTO_NHPOLY1305_NEON is not set -CONFIG_CRYPTO_CHACHA20_NEON=y - -# -# Accelerated Cryptographic Algorithms for CPU (arm64) -# -CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_POLY1305_NEON=m -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA256_ARM64=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y -CONFIG_CRYPTO_SHA512_ARM64=y -# CONFIG_CRYPTO_SHA512_ARM64_CE is not set -# CONFIG_CRYPTO_SHA3_ARM64 is not set -CONFIG_CRYPTO_SM3_NEON=m -# CONFIG_CRYPTO_SM3_ARM64_CE is not set -CONFIG_CRYPTO_POLYVAL_ARM64_CE=m -CONFIG_CRYPTO_AES_ARM64=y -CONFIG_CRYPTO_AES_ARM64_CE=y -CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y -CONFIG_CRYPTO_AES_ARM64_BS=y -CONFIG_CRYPTO_SM4_ARM64_CE=m -CONFIG_CRYPTO_SM4_ARM64_CE_BLK=m -CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=m -CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set -# end of Accelerated Cryptographic Algorithms for CPU (arm64) - -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_DEV_ALLWINNER=y -CONFIG_CRYPTO_DEV_SUN4I_SS=y -CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG=y -# CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG is not set -CONFIG_CRYPTO_DEV_SUN8I_CE=y -# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set -CONFIG_CRYPTO_DEV_SUN8I_CE_HASH=y -CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG=y -CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG=y -CONFIG_CRYPTO_DEV_SUN8I_SS=y -# CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG is not set -CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG=y -CONFIG_CRYPTO_DEV_SUN8I_SS_HASH=y -# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set -# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set -# CONFIG_CRYPTO_DEV_CCP is not set -CONFIG_CRYPTO_DEV_VIRTIO=m -CONFIG_CRYPTO_DEV_SAFEXCEL=m -CONFIG_CRYPTO_DEV_CCREE=m -# CONFIG_CRYPTO_DEV_HISI_SEC is not set -CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m -# CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG is not set -CONFIG_ASYMMETRIC_KEY_TYPE=y -CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y -CONFIG_X509_CERTIFICATE_PARSER=y -CONFIG_PKCS8_PRIVATE_KEY_PARSER=m -CONFIG_PKCS7_MESSAGE_PARSER=y -CONFIG_PKCS7_TEST_KEY=m -CONFIG_SIGNED_PE_FILE_VERIFICATION=y -# CONFIG_FIPS_SIGNATURE_SELFTEST is not set - -# -# Certificates for signature checking -# -CONFIG_SYSTEM_TRUSTED_KEYRING=y -CONFIG_SYSTEM_TRUSTED_KEYS="" -CONFIG_SYSTEM_EXTRA_CERTIFICATE=y -CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096 -CONFIG_SECONDARY_TRUSTED_KEYRING=y -CONFIG_SYSTEM_BLACKLIST_KEYRING=y -CONFIG_SYSTEM_BLACKLIST_HASH_LIST="" -# CONFIG_SYSTEM_REVOCATION_LIST is not set -# CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE is not set -# end of Certificates for signature checking - -CONFIG_BINARY_PRINTF=y - -# -# Library routines -# -CONFIG_RAID6_PQ=y -CONFIG_RAID6_PQ_BENCHMARK=y -CONFIG_LINEAR_RANGES=y -CONFIG_PACKING=y -CONFIG_BITREVERSE=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_NET_UTILS=y -CONFIG_CORDIC=m -CONFIG_PRIME_NUMBERS=m -CONFIG_RATIONAL=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_HAS_FAST_MULTIPLIER=y -CONFIG_ARCH_USE_SYM_ANNOTATIONS=y -# CONFIG_INDIRECT_PIO is not set - -# -# Crypto library routines -# -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_ARC4=m -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y -CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y -CONFIG_CRYPTO_LIB_CHACHA=m -CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m -CONFIG_CRYPTO_LIB_CURVE25519=m -CONFIG_CRYPTO_LIB_DES=y -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 -CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m -CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m -CONFIG_CRYPTO_LIB_POLY1305=m -CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m -CONFIG_CRYPTO_LIB_SHA1=y -CONFIG_CRYPTO_LIB_SHA256=y -# end of Crypto library routines - -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -CONFIG_CRC_T10DIF=y -CONFIG_CRC64_ROCKSOFT=y -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -# CONFIG_CRC32_SELFTEST is not set -CONFIG_CRC32_SLICEBY8=y -# CONFIG_CRC32_SLICEBY4 is not set -# CONFIG_CRC32_SARWATE is not set -# CONFIG_CRC32_BIT is not set -CONFIG_CRC64=y -CONFIG_CRC4=m -CONFIG_CRC7=y -CONFIG_LIBCRC32C=y -CONFIG_CRC8=m -CONFIG_XXHASH=y -CONFIG_AUDIT_GENERIC=y -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -CONFIG_AUDIT_COMPAT_GENERIC=y -# CONFIG_RANDOM32_SELFTEST is not set -CONFIG_842_COMPRESS=m -CONFIG_842_DECOMPRESS=m -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_LZ4_COMPRESS=y -CONFIG_LZ4HC_COMPRESS=y -CONFIG_LZ4_DECOMPRESS=y -CONFIG_ZSTD_COMMON=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y -CONFIG_XZ_DEC=y -CONFIG_XZ_DEC_X86=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_SPARC=y -# CONFIG_XZ_DEC_MICROLZMA is not set -CONFIG_XZ_DEC_BCJ=y -CONFIG_XZ_DEC_TEST=m -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_DECOMPRESS_LZ4=y -CONFIG_DECOMPRESS_ZSTD=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_REED_SOLOMON=m -CONFIG_REED_SOLOMON_ENC8=y -CONFIG_REED_SOLOMON_DEC8=y -CONFIG_REED_SOLOMON_DEC16=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_XARRAY_MULTI=y -CONFIG_ASSOCIATIVE_ARRAY=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_DMA=y -CONFIG_DMA_OPS=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_DMA_DECLARE_COHERENT=y -CONFIG_ARCH_HAS_SETUP_DMA_OPS=y -CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y -CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y -CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y -CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y -CONFIG_SWIOTLB=y -# CONFIG_DMA_RESTRICTED_POOL is not set -CONFIG_DMA_NONCOHERENT_MMAP=y -CONFIG_DMA_COHERENT_POOL=y -CONFIG_DMA_DIRECT_REMAP=y -CONFIG_DMA_CMA=y -CONFIG_DMA_PERNUMA_CMA=y - -# -# Default contiguous memory area size: -# -CONFIG_CMA_SIZE_MBYTES=128 -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_ALIGNMENT=8 -# CONFIG_DMA_API_DEBUG is not set -# CONFIG_DMA_MAP_BENCHMARK is not set -CONFIG_SGL_ALLOC=y -# CONFIG_FORCE_NR_CPUS is not set -CONFIG_CPU_RMAP=y -CONFIG_DQL=y -CONFIG_GLOB=y -# CONFIG_GLOB_SELFTEST is not set -CONFIG_NLATTR=y -CONFIG_LRU_CACHE=m -CONFIG_CLZ_TAB=y -CONFIG_IRQ_POLL=y -CONFIG_MPILIB=y -CONFIG_SIGNATURE=y -CONFIG_LIBFDT=y -CONFIG_OID_REGISTRY=y -CONFIG_HAVE_GENERIC_VDSO=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_VDSO_TIME_NS=y -CONFIG_FONT_SUPPORT=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -CONFIG_FONT_ACORN_8x8=y -# CONFIG_FONT_MINI_4x6 is not set -CONFIG_FONT_6x10=y -# CONFIG_FONT_10x18 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -CONFIG_FONT_TER16x32=y -# CONFIG_FONT_6x8 is not set -CONFIG_SG_POOL=y -CONFIG_ARCH_STACKWALK=y -CONFIG_STACKDEPOT=y -CONFIG_SBITMAP=y -# end of Library routines - -CONFIG_GENERIC_IOREMAP=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_ASN1_ENCODER=y -CONFIG_POLYNOMIAL=m - -# -# Kernel hacking -# - -# -# printk and dmesg options -# -CONFIG_PRINTK_TIME=y -# CONFIG_PRINTK_CALLER is not set -# CONFIG_STACKTRACE_BUILD_ID is not set -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 -CONFIG_CONSOLE_LOGLEVEL_QUIET=4 -CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -CONFIG_DYNAMIC_DEBUG=y -CONFIG_DYNAMIC_DEBUG_CORE=y -CONFIG_SYMBOLIC_ERRNAME=y -CONFIG_DEBUG_BUGVERBOSE=y -# end of printk and dmesg options - -# CONFIG_DEBUG_KERNEL is not set - -# -# Compile-time checks and compiler options -# -CONFIG_AS_HAS_NON_CONST_LEB128=y -CONFIG_FRAME_WARN=2048 -# CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_HEADERS_INSTALL is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_SECTION_MISMATCH_WARN_ONLY=y -CONFIG_ARCH_WANT_FRAME_POINTERS=y -CONFIG_FRAME_POINTER=y -# end of Compile-time checks and compiler options - -# -# Generic Kernel Debugging Instruments -# -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 -CONFIG_MAGIC_SYSRQ_SERIAL=y -CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_FS_ALLOW_ALL=y -# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set -# CONFIG_DEBUG_FS_ALLOW_NONE is not set -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y -# CONFIG_UBSAN is not set -CONFIG_HAVE_KCSAN_COMPILER=y -# end of Generic Kernel Debugging Instruments - -# -# Networking Debugging -# -# end of Networking Debugging - -# -# Memory Debugging -# -# CONFIG_PAGE_EXTENSION is not set -CONFIG_SLUB_DEBUG=y -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_PAGE_POISONING is not set -# CONFIG_DEBUG_RODATA_TEST is not set -CONFIG_ARCH_HAS_DEBUG_WX=y -# CONFIG_DEBUG_WX is not set -CONFIG_GENERIC_PTDUMP=y -# CONFIG_SHRINKER_DEBUG is not set -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y -# CONFIG_DEBUG_VM_PGTABLE is not set -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_DEBUG_MEMORY_INIT=y -CONFIG_HAVE_ARCH_KASAN=y -CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y -CONFIG_HAVE_ARCH_KASAN_HW_TAGS=y -CONFIG_HAVE_ARCH_KASAN_VMALLOC=y -CONFIG_CC_HAS_KASAN_GENERIC=y -CONFIG_CC_HAS_KASAN_SW_TAGS=y -CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y -# CONFIG_KASAN is not set -CONFIG_HAVE_ARCH_KFENCE=y -# CONFIG_KFENCE is not set -# end of Memory Debugging - -# -# Debug Oops, Lockups and Hangs -# -# CONFIG_PANIC_ON_OOPS is not set -CONFIG_PANIC_ON_OOPS_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 -CONFIG_TEST_LOCKUP=m -# end of Debug Oops, Lockups and Hangs - -# -# Scheduler Debugging -# -CONFIG_SCHED_INFO=y -# end of Scheduler Debugging - -# CONFIG_DEBUG_TIMEKEEPING is not set - -# -# Lock Debugging (spinlocks, mutexes, etc...) -# -CONFIG_LOCK_DEBUGGING_SUPPORT=y -# CONFIG_WW_MUTEX_SELFTEST is not set -# end of Lock Debugging (spinlocks, mutexes, etc...) - -# CONFIG_DEBUG_IRQFLAGS is not set -CONFIG_STACKTRACE=y -# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set - -# -# Debug kernel data structures -# -# CONFIG_BUG_ON_DATA_CORRUPTION is not set -# end of Debug kernel data structures - -# -# RCU Debugging -# -CONFIG_RCU_CPU_STALL_TIMEOUT=60 -CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 -# end of RCU Debugging - -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_TRACING_SUPPORT=y -# CONFIG_FTRACE is not set -# CONFIG_SAMPLES is not set -# CONFIG_STRICT_DEVMEM is not set - -# -# arm64 Debugging -# -# CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_ARM64_RELOC_TEST is not set -# CONFIG_CORESIGHT is not set -# end of arm64 Debugging - -# -# Kernel Testing and Coverage -# -# CONFIG_KUNIT is not set -CONFIG_FUNCTION_ERROR_INJECTION=y -CONFIG_ARCH_HAS_KCOV=y -CONFIG_CC_HAS_SANCOV_TRACE_PC=y -CONFIG_RUNTIME_TESTING_MENU=y -# CONFIG_LKDTM is not set -CONFIG_TEST_MIN_HEAP=m -CONFIG_TEST_DIV64=m -# CONFIG_REED_SOLOMON_TEST is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ASYNC_RAID6_TEST is not set -# CONFIG_TEST_HEXDUMP is not set -# CONFIG_STRING_SELFTEST is not set -# CONFIG_TEST_STRING_HELPERS is not set -CONFIG_TEST_STRSCPY=m -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_TEST_PRINTF is not set -CONFIG_TEST_SCANF=m -# CONFIG_TEST_BITMAP is not set -# CONFIG_TEST_UUID is not set -CONFIG_TEST_XARRAY=m -# CONFIG_TEST_MAPLE_TREE is not set -# CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_SIPHASH is not set -# CONFIG_TEST_IDA is not set -# CONFIG_TEST_LKM is not set -# CONFIG_TEST_BITOPS is not set -# CONFIG_TEST_VMALLOC is not set -# CONFIG_TEST_USER_COPY is not set -CONFIG_TEST_BPF=m -CONFIG_TEST_BLACKHOLE_DEV=m -# CONFIG_FIND_BIT_BENCHMARK is not set -# CONFIG_TEST_FIRMWARE is not set -# CONFIG_TEST_SYSCTL is not set -# CONFIG_TEST_UDELAY is not set -# CONFIG_TEST_STATIC_KEYS is not set -CONFIG_TEST_DYNAMIC_DEBUG=m -# CONFIG_TEST_KMOD is not set -CONFIG_TEST_MEMCAT_P=m -# CONFIG_TEST_MEMINIT is not set -# CONFIG_TEST_FREE_PAGES is not set -CONFIG_ARCH_USE_MEMTEST=y -# CONFIG_MEMTEST is not set -# end of Kernel Testing and Coverage - -# -# Rust hacking -# -# end of Rust hacking -# end of Kernel hacking -# CONFIG_DEBUG_INFO is not set -# CONFIG_GDB_SCRIPTS is not set diff --git a/config/sources/families/sun50iw9-btt.conf b/config/sources/families/sun50iw9-btt.conf deleted file mode 100644 index a6d37e882a1f..000000000000 --- a/config/sources/families/sun50iw9-btt.conf +++ /dev/null @@ -1,65 +0,0 @@ -# -# SPDX-License-Identifier: GPL-2.0 -# -# Copyright (c) 2013-2023 Igor Pecovnik, igor@armbian.com -# -# This file is a part of the Armbian Build Framework -# https://github.com/armbian/build/ -# -# shellcheck source=config/sources/families/include/sunxi64_common.inc -source "${BASH_SOURCE%/*}/include/sunxi64_common.inc" - -[[ -z $CPUMIN ]] && CPUMIN=480000 -[[ -z $CPUMAX ]] && CPUMAX=1512000 -GOVERNOR=ondemand - -case $BRANCH in - - legacy) - LINUXFAMILY=sun50iw9-btt - KERNELSOURCE='https://github.com/bigtreetech/linux.git' - declare -g KERNEL_MAJOR_MINOR="6.1" # Major and minor versions of this kernel. - KERNELBRANCH="branch:linux-6.1.y-cb1" - KERNELPATCHDIR="archive/sun50iw9-btt-6.1" - BOOTSOURCE='https://github.com/bigtreetech/u-boot.git' - BOOTBRANCH='branch:v2023.07-cb1' - BOOTPATCHDIR='NEED-NOT' - BOOTDELAY=-2 - ASOUND_STATE='asound.state.sun50iw9-legacy' - - ATFSOURCE='https://github.com/ARM-software/arm-trusted-firmware' - ATFBRANCH='tag:lts-v2.10.2' - ATF_PLAT="sun50i_h616" - ATF_TARGET_MAP='PLAT=sun50i_h616 DEBUG=1 bl31;;build/sun50i_h616/debug/bl31.bin' - BOOTSCRIPT='boot-sun50i-next.cmd:boot.cmd' - KERNEL_DRIVERS_SKIP+=(driver_rtw88) # This is custom 6.1 driver, skip rtw88 to avoid patching failures - ;; - - current | edge) - ATFSOURCE='https://github.com/ARM-software/arm-trusted-firmware' - ATFBRANCH='tag:lts-v2.10.2' - ATF_PLAT="sun50i_h616" - ATF_TARGET_MAP='PLAT=sun50i_h616 DEBUG=1 bl31;;build/sun50i_h616/debug/bl31.bin' - BOOTSCRIPT='boot-sun50i-next.cmd:boot.cmd' - - ;; -esac - -# This build requires busybox (and dos2unix) -function add_host_dependencies__sun50iw9_add_busybox_hostdep() { - display_alert "Adding busybox dep" "for ${BOARD} bootloader compile" "debug" - declare -g EXTRA_BUILD_DEPS="${EXTRA_BUILD_DEPS} busybox" -} - -function family_tweaks_s() { - if [[ -f $SDCARD/lib/systemd/system/hdmi-audio.service ]]; then - chroot $SDCARD /bin/bash -c "systemctl --no-reload enable hdmi-audio.service >/dev/null 2>&1" - fi -} - -function family_tweaks_bsp() { - install -m 755 $SRC/packages/blobs/sunxi/h616/inithdmiaudio $destination/usr/bin/ - cp $SRC/packages/blobs/sunxi/h616/libtinyalsa.so $destination/usr/lib/ - cp $SRC/packages/bsp/sunxi/hdmi-audio.service $destination/lib/systemd/system/ - -} diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.43-44.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.43-44.patch deleted file mode 100644 index 0c2a79ffb411..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.43-44.patch +++ /dev/null @@ -1,2841 +0,0 @@ -diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu -index f54867cadb0f6..13c01b641dc70 100644 ---- a/Documentation/ABI/testing/sysfs-devices-system-cpu -+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu -@@ -513,17 +513,18 @@ Description: information about CPUs heterogeneity. - cpu_capacity: capacity of cpuX. - - What: /sys/devices/system/cpu/vulnerabilities -+ /sys/devices/system/cpu/vulnerabilities/gather_data_sampling -+ /sys/devices/system/cpu/vulnerabilities/itlb_multihit -+ /sys/devices/system/cpu/vulnerabilities/l1tf -+ /sys/devices/system/cpu/vulnerabilities/mds - /sys/devices/system/cpu/vulnerabilities/meltdown -+ /sys/devices/system/cpu/vulnerabilities/mmio_stale_data -+ /sys/devices/system/cpu/vulnerabilities/retbleed -+ /sys/devices/system/cpu/vulnerabilities/spec_store_bypass - /sys/devices/system/cpu/vulnerabilities/spectre_v1 - /sys/devices/system/cpu/vulnerabilities/spectre_v2 -- /sys/devices/system/cpu/vulnerabilities/spec_store_bypass -- /sys/devices/system/cpu/vulnerabilities/l1tf -- /sys/devices/system/cpu/vulnerabilities/mds - /sys/devices/system/cpu/vulnerabilities/srbds - /sys/devices/system/cpu/vulnerabilities/tsx_async_abort -- /sys/devices/system/cpu/vulnerabilities/itlb_multihit -- /sys/devices/system/cpu/vulnerabilities/mmio_stale_data -- /sys/devices/system/cpu/vulnerabilities/retbleed - Date: January 2018 - Contact: Linux kernel mailing list - Description: Information about CPU vulnerabilities -diff --git a/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst b/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst -new file mode 100644 -index 0000000000000..264bfa937f7de ---- /dev/null -+++ b/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst -@@ -0,0 +1,109 @@ -+.. SPDX-License-Identifier: GPL-2.0 -+ -+GDS - Gather Data Sampling -+========================== -+ -+Gather Data Sampling is a hardware vulnerability which allows unprivileged -+speculative access to data which was previously stored in vector registers. -+ -+Problem -+------- -+When a gather instruction performs loads from memory, different data elements -+are merged into the destination vector register. However, when a gather -+instruction that is transiently executed encounters a fault, stale data from -+architectural or internal vector registers may get transiently forwarded to the -+destination vector register instead. This will allow a malicious attacker to -+infer stale data using typical side channel techniques like cache timing -+attacks. GDS is a purely sampling-based attack. -+ -+The attacker uses gather instructions to infer the stale vector register data. -+The victim does not need to do anything special other than use the vector -+registers. The victim does not need to use gather instructions to be -+vulnerable. -+ -+Because the buffers are shared between Hyper-Threads cross Hyper-Thread attacks -+are possible. -+ -+Attack scenarios -+---------------- -+Without mitigation, GDS can infer stale data across virtually all -+permission boundaries: -+ -+ Non-enclaves can infer SGX enclave data -+ Userspace can infer kernel data -+ Guests can infer data from hosts -+ Guest can infer guest from other guests -+ Users can infer data from other users -+ -+Because of this, it is important to ensure that the mitigation stays enabled in -+lower-privilege contexts like guests and when running outside SGX enclaves. -+ -+The hardware enforces the mitigation for SGX. Likewise, VMMs should ensure -+that guests are not allowed to disable the GDS mitigation. If a host erred and -+allowed this, a guest could theoretically disable GDS mitigation, mount an -+attack, and re-enable it. -+ -+Mitigation mechanism -+-------------------- -+This issue is mitigated in microcode. The microcode defines the following new -+bits: -+ -+ ================================ === ============================ -+ IA32_ARCH_CAPABILITIES[GDS_CTRL] R/O Enumerates GDS vulnerability -+ and mitigation support. -+ IA32_ARCH_CAPABILITIES[GDS_NO] R/O Processor is not vulnerable. -+ IA32_MCU_OPT_CTRL[GDS_MITG_DIS] R/W Disables the mitigation -+ 0 by default. -+ IA32_MCU_OPT_CTRL[GDS_MITG_LOCK] R/W Locks GDS_MITG_DIS=0. Writes -+ to GDS_MITG_DIS are ignored -+ Can't be cleared once set. -+ ================================ === ============================ -+ -+GDS can also be mitigated on systems that don't have updated microcode by -+disabling AVX. This can be done by setting gather_data_sampling="force" or -+"clearcpuid=avx" on the kernel command-line. -+ -+If used, these options will disable AVX use by turning off XSAVE YMM support. -+However, the processor will still enumerate AVX support. Userspace that -+does not follow proper AVX enumeration to check both AVX *and* XSAVE YMM -+support will break. -+ -+Mitigation control on the kernel command line -+--------------------------------------------- -+The mitigation can be disabled by setting "gather_data_sampling=off" or -+"mitigations=off" on the kernel command line. Not specifying either will default -+to the mitigation being enabled. Specifying "gather_data_sampling=force" will -+use the microcode mitigation when available or disable AVX on affected systems -+where the microcode hasn't been updated to include the mitigation. -+ -+GDS System Information -+------------------------ -+The kernel provides vulnerability status information through sysfs. For -+GDS this can be accessed by the following sysfs file: -+ -+/sys/devices/system/cpu/vulnerabilities/gather_data_sampling -+ -+The possible values contained in this file are: -+ -+ ============================== ============================================= -+ Not affected Processor not vulnerable. -+ Vulnerable Processor vulnerable and mitigation disabled. -+ Vulnerable: No microcode Processor vulnerable and microcode is missing -+ mitigation. -+ Mitigation: AVX disabled, -+ no microcode Processor is vulnerable and microcode is missing -+ mitigation. AVX disabled as mitigation. -+ Mitigation: Microcode Processor is vulnerable and mitigation is in -+ effect. -+ Mitigation: Microcode (locked) Processor is vulnerable and mitigation is in -+ effect and cannot be disabled. -+ Unknown: Dependent on -+ hypervisor status Running on a virtual guest processor that is -+ affected but with no way to know if host -+ processor is mitigated or vulnerable. -+ ============================== ============================================= -+ -+GDS Default mitigation -+---------------------- -+The updated microcode will enable the mitigation by default. The kernel's -+default action is to leave the mitigation enabled. -diff --git a/Documentation/admin-guide/hw-vuln/index.rst b/Documentation/admin-guide/hw-vuln/index.rst -index e0614760a99e7..6828102baaa7a 100644 ---- a/Documentation/admin-guide/hw-vuln/index.rst -+++ b/Documentation/admin-guide/hw-vuln/index.rst -@@ -19,3 +19,5 @@ are configurable at compile, boot or run time. - l1d_flush.rst - processor_mmio_stale_data.rst - cross-thread-rsb.rst -+ gather_data_sampling.rst -+ srso -diff --git a/Documentation/admin-guide/hw-vuln/srso.rst b/Documentation/admin-guide/hw-vuln/srso.rst -new file mode 100644 -index 0000000000000..2f923c805802f ---- /dev/null -+++ b/Documentation/admin-guide/hw-vuln/srso.rst -@@ -0,0 +1,133 @@ -+.. SPDX-License-Identifier: GPL-2.0 -+ -+Speculative Return Stack Overflow (SRSO) -+======================================== -+ -+This is a mitigation for the speculative return stack overflow (SRSO) -+vulnerability found on AMD processors. The mechanism is by now the well -+known scenario of poisoning CPU functional units - the Branch Target -+Buffer (BTB) and Return Address Predictor (RAP) in this case - and then -+tricking the elevated privilege domain (the kernel) into leaking -+sensitive data. -+ -+AMD CPUs predict RET instructions using a Return Address Predictor (aka -+Return Address Stack/Return Stack Buffer). In some cases, a non-architectural -+CALL instruction (i.e., an instruction predicted to be a CALL but is -+not actually a CALL) can create an entry in the RAP which may be used -+to predict the target of a subsequent RET instruction. -+ -+The specific circumstances that lead to this varies by microarchitecture -+but the concern is that an attacker can mis-train the CPU BTB to predict -+non-architectural CALL instructions in kernel space and use this to -+control the speculative target of a subsequent kernel RET, potentially -+leading to information disclosure via a speculative side-channel. -+ -+The issue is tracked under CVE-2023-20569. -+ -+Affected processors -+------------------- -+ -+AMD Zen, generations 1-4. That is, all families 0x17 and 0x19. Older -+processors have not been investigated. -+ -+System information and options -+------------------------------ -+ -+First of all, it is required that the latest microcode be loaded for -+mitigations to be effective. -+ -+The sysfs file showing SRSO mitigation status is: -+ -+ /sys/devices/system/cpu/vulnerabilities/spec_rstack_overflow -+ -+The possible values in this file are: -+ -+ - 'Not affected' The processor is not vulnerable -+ -+ - 'Vulnerable: no microcode' The processor is vulnerable, no -+ microcode extending IBPB functionality -+ to address the vulnerability has been -+ applied. -+ -+ - 'Mitigation: microcode' Extended IBPB functionality microcode -+ patch has been applied. It does not -+ address User->Kernel and Guest->Host -+ transitions protection but it does -+ address User->User and VM->VM attack -+ vectors. -+ -+ (spec_rstack_overflow=microcode) -+ -+ - 'Mitigation: safe RET' Software-only mitigation. It complements -+ the extended IBPB microcode patch -+ functionality by addressing User->Kernel -+ and Guest->Host transitions protection. -+ -+ Selected by default or by -+ spec_rstack_overflow=safe-ret -+ -+ - 'Mitigation: IBPB' Similar protection as "safe RET" above -+ but employs an IBPB barrier on privilege -+ domain crossings (User->Kernel, -+ Guest->Host). -+ -+ (spec_rstack_overflow=ibpb) -+ -+ - 'Mitigation: IBPB on VMEXIT' Mitigation addressing the cloud provider -+ scenario - the Guest->Host transitions -+ only. -+ -+ (spec_rstack_overflow=ibpb-vmexit) -+ -+In order to exploit vulnerability, an attacker needs to: -+ -+ - gain local access on the machine -+ -+ - break kASLR -+ -+ - find gadgets in the running kernel in order to use them in the exploit -+ -+ - potentially create and pin an additional workload on the sibling -+ thread, depending on the microarchitecture (not necessary on fam 0x19) -+ -+ - run the exploit -+ -+Considering the performance implications of each mitigation type, the -+default one is 'Mitigation: safe RET' which should take care of most -+attack vectors, including the local User->Kernel one. -+ -+As always, the user is advised to keep her/his system up-to-date by -+applying software updates regularly. -+ -+The default setting will be reevaluated when needed and especially when -+new attack vectors appear. -+ -+As one can surmise, 'Mitigation: safe RET' does come at the cost of some -+performance depending on the workload. If one trusts her/his userspace -+and does not want to suffer the performance impact, one can always -+disable the mitigation with spec_rstack_overflow=off. -+ -+Similarly, 'Mitigation: IBPB' is another full mitigation type employing -+an indrect branch prediction barrier after having applied the required -+microcode patch for one's system. This mitigation comes also at -+a performance cost. -+ -+Mitigation: safe RET -+-------------------- -+ -+The mitigation works by ensuring all RET instructions speculate to -+a controlled location, similar to how speculation is controlled in the -+retpoline sequence. To accomplish this, the __x86_return_thunk forces -+the CPU to mispredict every function return using a 'safe return' -+sequence. -+ -+To ensure the safety of this mitigation, the kernel must ensure that the -+safe return sequence is itself free from attacker interference. In Zen3 -+and Zen4, this is accomplished by creating a BTB alias between the -+untraining function srso_untrain_ret_alias() and the safe return -+function srso_safe_ret_alias() which results in evicting a potentially -+poisoned BTB entry and using that safe one for all function returns. -+ -+In older Zen1 and Zen2, this is accomplished using a reinterpretation -+technique similar to Retbleed one: srso_untrain_ret() and -+srso_safe_ret(). -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 6b838869554b1..286be425f3bfa 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -1593,6 +1593,26 @@ - Format: off | on - default: on - -+ gather_data_sampling= -+ [X86,INTEL] Control the Gather Data Sampling (GDS) -+ mitigation. -+ -+ Gather Data Sampling is a hardware vulnerability which -+ allows unprivileged speculative access to data which was -+ previously stored in vector registers. -+ -+ This issue is mitigated by default in updated microcode. -+ The mitigation may have a performance impact but can be -+ disabled. On systems without the microcode mitigation -+ disabling AVX serves as a mitigation. -+ -+ force: Disable AVX to mitigate systems without -+ microcode mitigation. No effect if the microcode -+ mitigation is present. Known to cause crashes in -+ userspace with buggy AVX enumeration. -+ -+ off: Disable GDS mitigation. -+ - gcov_persist= [GCOV] When non-zero (default), profiling data for - kernel modules is saved and remains accessible via - debugfs, even when the module is unloaded/reloaded. -@@ -3228,24 +3248,25 @@ - Disable all optional CPU mitigations. This - improves system performance, but it may also - expose users to several CPU vulnerabilities. -- Equivalent to: nopti [X86,PPC] -- if nokaslr then kpti=0 [ARM64] -- nospectre_v1 [X86,PPC] -- nobp=0 [S390] -- nospectre_v2 [X86,PPC,S390,ARM64] -- spectre_v2_user=off [X86] -- spec_store_bypass_disable=off [X86,PPC] -- ssbd=force-off [ARM64] -- nospectre_bhb [ARM64] -+ Equivalent to: if nokaslr then kpti=0 [ARM64] -+ gather_data_sampling=off [X86] -+ kvm.nx_huge_pages=off [X86] - l1tf=off [X86] - mds=off [X86] -- tsx_async_abort=off [X86] -- kvm.nx_huge_pages=off [X86] -- srbds=off [X86,INTEL] -+ mmio_stale_data=off [X86] - no_entry_flush [PPC] - no_uaccess_flush [PPC] -- mmio_stale_data=off [X86] -+ nobp=0 [S390] -+ nopti [X86,PPC] -+ nospectre_bhb [ARM64] -+ nospectre_v1 [X86,PPC] -+ nospectre_v2 [X86,PPC,S390,ARM64] - retbleed=off [X86] -+ spec_store_bypass_disable=off [X86,PPC] -+ spectre_v2_user=off [X86] -+ srbds=off [X86,INTEL] -+ ssbd=force-off [ARM64] -+ tsx_async_abort=off [X86] - - Exceptions: - This does not have any effect on -@@ -5764,6 +5785,17 @@ - Not specifying this option is equivalent to - spectre_v2_user=auto. - -+ spec_rstack_overflow= -+ [X86] Control RAS overflow mitigation on AMD Zen CPUs -+ -+ off - Disable mitigation -+ microcode - Enable microcode mitigation only -+ safe-ret - Enable sw-only safe RET mitigation (default) -+ ibpb - Enable mitigation by issuing IBPB on -+ kernel entry -+ ibpb-vmexit - Issue IBPB only on VMEXIT -+ (cloud-specific mitigation) -+ - spec_store_bypass_disable= - [HW] Control Speculative Store Bypass (SSB) Disable mitigation - (Speculative Store Bypass vulnerability) -diff --git a/Makefile b/Makefile -index 69cdd0d2946c3..612f3d83629b4 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 43 -+SUBLEVEL = 44 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/Kconfig b/arch/Kconfig -index 81599f5c17b0f..b60d271bf76a9 100644 ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -285,6 +285,9 @@ config ARCH_HAS_DMA_SET_UNCACHED - config ARCH_HAS_DMA_CLEAR_UNCACHED - bool - -+config ARCH_HAS_CPU_FINALIZE_INIT -+ bool -+ - # Select if arch init_task must go in the __init_task_data section - config ARCH_TASK_STRUCT_ON_STACK - bool -diff --git a/arch/alpha/include/asm/bugs.h b/arch/alpha/include/asm/bugs.h -deleted file mode 100644 -index 78030d1c7e7e0..0000000000000 ---- a/arch/alpha/include/asm/bugs.h -+++ /dev/null -@@ -1,20 +0,0 @@ --/* -- * include/asm-alpha/bugs.h -- * -- * Copyright (C) 1994 Linus Torvalds -- */ -- --/* -- * This is included by init/main.c to check for architecture-dependent bugs. -- * -- * Needs: -- * void check_bugs(void); -- */ -- --/* -- * I don't know of any alpha bugs yet.. Nice chip -- */ -- --static void check_bugs(void) --{ --} -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 0202e48e7a207..6d5afe2e6ba33 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -5,6 +5,7 @@ config ARM - select ARCH_32BIT_OFF_T - select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND - select ARCH_HAS_BINFMT_FLAT -+ select ARCH_HAS_CPU_FINALIZE_INIT if MMU - select ARCH_HAS_CURRENT_STACK_POINTER - select ARCH_HAS_DEBUG_VIRTUAL if MMU - select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE -diff --git a/arch/arm/include/asm/bugs.h b/arch/arm/include/asm/bugs.h -index 97a312ba08401..fe385551edeca 100644 ---- a/arch/arm/include/asm/bugs.h -+++ b/arch/arm/include/asm/bugs.h -@@ -1,7 +1,5 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ - /* -- * arch/arm/include/asm/bugs.h -- * - * Copyright (C) 1995-2003 Russell King - */ - #ifndef __ASM_BUGS_H -@@ -10,10 +8,8 @@ - extern void check_writebuffer_bugs(void); - - #ifdef CONFIG_MMU --extern void check_bugs(void); - extern void check_other_bugs(void); - #else --#define check_bugs() do { } while (0) - #define check_other_bugs() do { } while (0) - #endif - -diff --git a/arch/arm/kernel/bugs.c b/arch/arm/kernel/bugs.c -index 14c8dbbb7d2df..087bce6ec8e9b 100644 ---- a/arch/arm/kernel/bugs.c -+++ b/arch/arm/kernel/bugs.c -@@ -1,5 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0 - #include -+#include - #include - #include - -@@ -11,7 +12,7 @@ void check_other_bugs(void) - #endif - } - --void __init check_bugs(void) -+void __init arch_cpu_finalize_init(void) - { - check_writebuffer_bugs(); - check_other_bugs(); -diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig -index c6e06cdc738f0..283b751cbf6ab 100644 ---- a/arch/ia64/Kconfig -+++ b/arch/ia64/Kconfig -@@ -9,6 +9,7 @@ menu "Processor type and features" - config IA64 - bool - select ARCH_BINFMT_ELF_EXTRA_PHDRS -+ select ARCH_HAS_CPU_FINALIZE_INIT - select ARCH_HAS_DMA_MARK_CLEAN - select ARCH_HAS_STRNCPY_FROM_USER - select ARCH_HAS_STRNLEN_USER -diff --git a/arch/ia64/include/asm/bugs.h b/arch/ia64/include/asm/bugs.h -deleted file mode 100644 -index 0d6b9bded56c6..0000000000000 ---- a/arch/ia64/include/asm/bugs.h -+++ /dev/null -@@ -1,20 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * This is included by init/main.c to check for architecture-dependent bugs. -- * -- * Needs: -- * void check_bugs(void); -- * -- * Based on . -- * -- * Modified 1998, 1999, 2003 -- * David Mosberger-Tang , Hewlett-Packard Co. -- */ --#ifndef _ASM_IA64_BUGS_H --#define _ASM_IA64_BUGS_H -- --#include -- --extern void check_bugs (void); -- --#endif /* _ASM_IA64_BUGS_H */ -diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c -index c057280442727..9009f1871e3b8 100644 ---- a/arch/ia64/kernel/setup.c -+++ b/arch/ia64/kernel/setup.c -@@ -1067,8 +1067,7 @@ cpu_init (void) - } - } - --void __init --check_bugs (void) -+void __init arch_cpu_finalize_init(void) - { - ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles, - (unsigned long) __end___mckinley_e9_bundles); -diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig -index e737dc8cd660c..270742cc3ca49 100644 ---- a/arch/loongarch/Kconfig -+++ b/arch/loongarch/Kconfig -@@ -10,6 +10,7 @@ config LOONGARCH - select ARCH_ENABLE_MEMORY_HOTPLUG - select ARCH_ENABLE_MEMORY_HOTREMOVE - select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI -+ select ARCH_HAS_CPU_FINALIZE_INIT - select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - select ARCH_HAS_PTE_SPECIAL - select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST -diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c -index ae436def7ee98..29725b37b35ca 100644 ---- a/arch/loongarch/kernel/setup.c -+++ b/arch/loongarch/kernel/setup.c -@@ -12,6 +12,7 @@ - */ - #include - #include -+#include - #include - #include - #include -@@ -80,6 +81,11 @@ const char *get_system_type(void) - return "generic-loongson-machine"; - } - -+void __init arch_cpu_finalize_init(void) -+{ -+ alternative_instructions(); -+} -+ - static const char *dmi_string_parse(const struct dmi_header *dm, u8 s) - { - const u8 *bp = ((u8 *) dm) + dm->length; -diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig -index 7bff881185070..1fe5b20187457 100644 ---- a/arch/m68k/Kconfig -+++ b/arch/m68k/Kconfig -@@ -4,6 +4,7 @@ config M68K - default y - select ARCH_32BIT_OFF_T - select ARCH_HAS_BINFMT_FLAT -+ select ARCH_HAS_CPU_FINALIZE_INIT if MMU - select ARCH_HAS_CURRENT_STACK_POINTER - select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE - select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA -diff --git a/arch/m68k/include/asm/bugs.h b/arch/m68k/include/asm/bugs.h -deleted file mode 100644 -index 745530651e0bf..0000000000000 ---- a/arch/m68k/include/asm/bugs.h -+++ /dev/null -@@ -1,21 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * include/asm-m68k/bugs.h -- * -- * Copyright (C) 1994 Linus Torvalds -- */ -- --/* -- * This is included by init/main.c to check for architecture-dependent bugs. -- * -- * Needs: -- * void check_bugs(void); -- */ -- --#ifdef CONFIG_MMU --extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */ --#else --static void check_bugs(void) --{ --} --#endif -diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c -index fbff1cea62caa..6f1ae01f322cf 100644 ---- a/arch/m68k/kernel/setup_mm.c -+++ b/arch/m68k/kernel/setup_mm.c -@@ -10,6 +10,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -504,7 +505,7 @@ static int __init proc_hardware_init(void) - module_init(proc_hardware_init); - #endif - --void check_bugs(void) -+void __init arch_cpu_finalize_init(void) - { - #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU) - if (m68k_fputype == 0) { -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 7b0856c76c9ad..cf1fbf4eaa8a0 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -4,6 +4,7 @@ config MIPS - default y - select ARCH_32BIT_OFF_T if !64BIT - select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT -+ select ARCH_HAS_CPU_FINALIZE_INIT - select ARCH_HAS_CURRENT_STACK_POINTER if !CC_IS_CLANG || CLANG_VERSION >= 140000 - select ARCH_HAS_DEBUG_VIRTUAL if !64BIT - select ARCH_HAS_FORTIFY_SOURCE -diff --git a/arch/mips/include/asm/bugs.h b/arch/mips/include/asm/bugs.h -index d72dc6e1cf3cd..8d4cf29861b87 100644 ---- a/arch/mips/include/asm/bugs.h -+++ b/arch/mips/include/asm/bugs.h -@@ -1,17 +1,11 @@ - /* SPDX-License-Identifier: GPL-2.0 */ - /* -- * This is included by init/main.c to check for architecture-dependent bugs. -- * - * Copyright (C) 2007 Maciej W. Rozycki -- * -- * Needs: -- * void check_bugs(void); - */ - #ifndef _ASM_BUGS_H - #define _ASM_BUGS_H - - #include --#include - #include - - #include -@@ -30,17 +24,6 @@ static inline void check_bugs_early(void) - check_bugs64_early(); - } - --static inline void check_bugs(void) --{ -- unsigned int cpu = smp_processor_id(); -- -- cpu_data[cpu].udelay_val = loops_per_jiffy; -- check_bugs32(); -- -- if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64)) -- check_bugs64(); --} -- - static inline int r4k_daddiu_bug(void) - { - if (!IS_ENABLED(CONFIG_CPU_R4X00_BUGS64)) -diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c -index 81dbb4ef52317..7c540572f1f72 100644 ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -11,6 +11,8 @@ - * Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki - */ - #include -+#include -+#include - #include - #include - #include -@@ -840,3 +842,14 @@ static int __init setnocoherentio(char *str) - } - early_param("nocoherentio", setnocoherentio); - #endif -+ -+void __init arch_cpu_finalize_init(void) -+{ -+ unsigned int cpu = smp_processor_id(); -+ -+ cpu_data[cpu].udelay_val = loops_per_jiffy; -+ check_bugs32(); -+ -+ if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64)) -+ check_bugs64(); -+} -diff --git a/arch/parisc/include/asm/bugs.h b/arch/parisc/include/asm/bugs.h -deleted file mode 100644 -index 0a7f9db6bd1c7..0000000000000 ---- a/arch/parisc/include/asm/bugs.h -+++ /dev/null -@@ -1,20 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * include/asm-parisc/bugs.h -- * -- * Copyright (C) 1999 Mike Shaver -- */ -- --/* -- * This is included by init/main.c to check for architecture-dependent bugs. -- * -- * Needs: -- * void check_bugs(void); -- */ -- --#include -- --static inline void check_bugs(void) --{ --// identify_cpu(&boot_cpu_data); --} -diff --git a/arch/powerpc/include/asm/bugs.h b/arch/powerpc/include/asm/bugs.h -deleted file mode 100644 -index 01b8f6ca4dbbc..0000000000000 ---- a/arch/powerpc/include/asm/bugs.h -+++ /dev/null -@@ -1,15 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-or-later */ --#ifndef _ASM_POWERPC_BUGS_H --#define _ASM_POWERPC_BUGS_H -- --/* -- */ -- --/* -- * This file is included by 'init/main.c' to check for -- * architecture-dependent bugs. -- */ -- --static inline void check_bugs(void) { } -- --#endif /* _ASM_POWERPC_BUGS_H */ -diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig -index 8e4d1f757bcc9..a0593f6ce0e0f 100644 ---- a/arch/sh/Kconfig -+++ b/arch/sh/Kconfig -@@ -7,6 +7,7 @@ config SUPERH - select ARCH_HAVE_CUSTOM_GPIO_H - select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A) - select ARCH_HAS_BINFMT_FLAT if !MMU -+ select ARCH_HAS_CPU_FINALIZE_INIT - select ARCH_HAS_CURRENT_STACK_POINTER - select ARCH_HAS_GIGANTIC_PAGE - select ARCH_HAS_GCOV_PROFILE_ALL -diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h -deleted file mode 100644 -index fe52abb69cea3..0000000000000 ---- a/arch/sh/include/asm/bugs.h -+++ /dev/null -@@ -1,74 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --#ifndef __ASM_SH_BUGS_H --#define __ASM_SH_BUGS_H -- --/* -- * This is included by init/main.c to check for architecture-dependent bugs. -- * -- * Needs: -- * void check_bugs(void); -- */ -- --/* -- * I don't know of any Super-H bugs yet. -- */ -- --#include -- --extern void select_idle_routine(void); -- --static void __init check_bugs(void) --{ -- extern unsigned long loops_per_jiffy; -- char *p = &init_utsname()->machine[2]; /* "sh" */ -- -- select_idle_routine(); -- -- current_cpu_data.loops_per_jiffy = loops_per_jiffy; -- -- switch (current_cpu_data.family) { -- case CPU_FAMILY_SH2: -- *p++ = '2'; -- break; -- case CPU_FAMILY_SH2A: -- *p++ = '2'; -- *p++ = 'a'; -- break; -- case CPU_FAMILY_SH3: -- *p++ = '3'; -- break; -- case CPU_FAMILY_SH4: -- *p++ = '4'; -- break; -- case CPU_FAMILY_SH4A: -- *p++ = '4'; -- *p++ = 'a'; -- break; -- case CPU_FAMILY_SH4AL_DSP: -- *p++ = '4'; -- *p++ = 'a'; -- *p++ = 'l'; -- *p++ = '-'; -- *p++ = 'd'; -- *p++ = 's'; -- *p++ = 'p'; -- break; -- case CPU_FAMILY_UNKNOWN: -- /* -- * Specifically use CPU_FAMILY_UNKNOWN rather than -- * default:, so we're able to have the compiler whine -- * about unhandled enumerations. -- */ -- break; -- } -- -- printk("CPU: %s\n", get_cpu_subtype(¤t_cpu_data)); -- --#ifndef __LITTLE_ENDIAN__ -- /* 'eb' means 'Endian Big' */ -- *p++ = 'e'; -- *p++ = 'b'; --#endif -- *p = '\0'; --} --#endif /* __ASM_SH_BUGS_H */ -diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h -index 85a6c1c3c16e7..73fba7c922f92 100644 ---- a/arch/sh/include/asm/processor.h -+++ b/arch/sh/include/asm/processor.h -@@ -166,6 +166,8 @@ extern unsigned int instruction_size(unsigned int insn); - #define instruction_size(insn) (2) - #endif - -+void select_idle_routine(void); -+ - #endif /* __ASSEMBLY__ */ - - #include -diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c -index f59814983bd59..a80b2a5b25c7f 100644 ---- a/arch/sh/kernel/idle.c -+++ b/arch/sh/kernel/idle.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - -diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c -index af977ec4ca5e5..cf7c0f72f2935 100644 ---- a/arch/sh/kernel/setup.c -+++ b/arch/sh/kernel/setup.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -354,3 +355,57 @@ int test_mode_pin(int pin) - { - return sh_mv.mv_mode_pins() & pin; - } -+ -+void __init arch_cpu_finalize_init(void) -+{ -+ char *p = &init_utsname()->machine[2]; /* "sh" */ -+ -+ select_idle_routine(); -+ -+ current_cpu_data.loops_per_jiffy = loops_per_jiffy; -+ -+ switch (current_cpu_data.family) { -+ case CPU_FAMILY_SH2: -+ *p++ = '2'; -+ break; -+ case CPU_FAMILY_SH2A: -+ *p++ = '2'; -+ *p++ = 'a'; -+ break; -+ case CPU_FAMILY_SH3: -+ *p++ = '3'; -+ break; -+ case CPU_FAMILY_SH4: -+ *p++ = '4'; -+ break; -+ case CPU_FAMILY_SH4A: -+ *p++ = '4'; -+ *p++ = 'a'; -+ break; -+ case CPU_FAMILY_SH4AL_DSP: -+ *p++ = '4'; -+ *p++ = 'a'; -+ *p++ = 'l'; -+ *p++ = '-'; -+ *p++ = 'd'; -+ *p++ = 's'; -+ *p++ = 'p'; -+ break; -+ case CPU_FAMILY_UNKNOWN: -+ /* -+ * Specifically use CPU_FAMILY_UNKNOWN rather than -+ * default:, so we're able to have the compiler whine -+ * about unhandled enumerations. -+ */ -+ break; -+ } -+ -+ pr_info("CPU: %s\n", get_cpu_subtype(¤t_cpu_data)); -+ -+#ifndef __LITTLE_ENDIAN__ -+ /* 'eb' means 'Endian Big' */ -+ *p++ = 'e'; -+ *p++ = 'b'; -+#endif -+ *p = '\0'; -+} -diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig -index dbb1760cbe8c9..b67d96e3392e5 100644 ---- a/arch/sparc/Kconfig -+++ b/arch/sparc/Kconfig -@@ -51,6 +51,7 @@ config SPARC - config SPARC32 - def_bool !64BIT - select ARCH_32BIT_OFF_T -+ select ARCH_HAS_CPU_FINALIZE_INIT if !SMP - select ARCH_HAS_SYNC_DMA_FOR_CPU - select CLZ_TAB - select DMA_DIRECT_REMAP -diff --git a/arch/sparc/include/asm/bugs.h b/arch/sparc/include/asm/bugs.h -deleted file mode 100644 -index 02fa369b9c21f..0000000000000 ---- a/arch/sparc/include/asm/bugs.h -+++ /dev/null -@@ -1,18 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* include/asm/bugs.h: Sparc probes for various bugs. -- * -- * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) -- */ -- --#ifdef CONFIG_SPARC32 --#include --#endif -- --extern unsigned long loops_per_jiffy; -- --static void __init check_bugs(void) --{ --#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP) -- cpu_data(0).udelay_val = loops_per_jiffy; --#endif --} -diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c -index c8e0dd99f3700..c9d1ba4f311b9 100644 ---- a/arch/sparc/kernel/setup_32.c -+++ b/arch/sparc/kernel/setup_32.c -@@ -412,3 +412,10 @@ static int __init topology_init(void) - } - - subsys_initcall(topology_init); -+ -+#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP) -+void __init arch_cpu_finalize_init(void) -+{ -+ cpu_data(0).udelay_val = loops_per_jiffy; -+} -+#endif -diff --git a/arch/um/Kconfig b/arch/um/Kconfig -index ad4ff3b0e91e5..82709bc36df7d 100644 ---- a/arch/um/Kconfig -+++ b/arch/um/Kconfig -@@ -6,6 +6,7 @@ config UML - bool - default y - select ARCH_EPHEMERAL_INODES -+ select ARCH_HAS_CPU_FINALIZE_INIT - select ARCH_HAS_FORTIFY_SOURCE - select ARCH_HAS_GCOV_PROFILE_ALL - select ARCH_HAS_KCOV -diff --git a/arch/um/include/asm/bugs.h b/arch/um/include/asm/bugs.h -deleted file mode 100644 -index 4473942a08397..0000000000000 ---- a/arch/um/include/asm/bugs.h -+++ /dev/null -@@ -1,7 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --#ifndef __UM_BUGS_H --#define __UM_BUGS_H -- --void check_bugs(void); -- --#endif -diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c -index 8adf8e89b2558..334c91191b316 100644 ---- a/arch/um/kernel/um_arch.c -+++ b/arch/um/kernel/um_arch.c -@@ -3,6 +3,7 @@ - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - */ - -+#include - #include - #include - #include -@@ -426,7 +427,7 @@ void __init setup_arch(char **cmdline_p) - } - } - --void __init check_bugs(void) -+void __init arch_cpu_finalize_init(void) - { - arch_check_bugs(); - os_check_bugs(); -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index b3d5706579d43..4c9bfc4be58d4 100644 ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -69,6 +69,7 @@ config X86 - select ARCH_ENABLE_THP_MIGRATION if X86_64 && TRANSPARENT_HUGEPAGE - select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI - select ARCH_HAS_CACHE_LINE_SIZE -+ select ARCH_HAS_CPU_FINALIZE_INIT - select ARCH_HAS_CURRENT_STACK_POINTER - select ARCH_HAS_DEBUG_VIRTUAL - select ARCH_HAS_DEBUG_VM_PGTABLE if !X86_PAE -@@ -2511,6 +2512,13 @@ config CPU_IBRS_ENTRY - This mitigates both spectre_v2 and retbleed at great cost to - performance. - -+config CPU_SRSO -+ bool "Mitigate speculative RAS overflow on AMD" -+ depends on CPU_SUP_AMD && X86_64 && RETHUNK -+ default y -+ help -+ Enable the SRSO mitigation needed on AMD Zen1-4 machines. -+ - config SLS - bool "Mitigate Straight-Line-Speculation" - depends on CC_HAS_SLS && X86_64 -@@ -2521,6 +2529,25 @@ config SLS - against straight line speculation. The kernel image might be slightly - larger. - -+config GDS_FORCE_MITIGATION -+ bool "Force GDS Mitigation" -+ depends on CPU_SUP_INTEL -+ default n -+ help -+ Gather Data Sampling (GDS) is a hardware vulnerability which allows -+ unprivileged speculative access to data which was previously stored in -+ vector registers. -+ -+ This option is equivalent to setting gather_data_sampling=force on the -+ command line. The microcode mitigation is used if present, otherwise -+ AVX is disabled as a mitigation. On affected systems that are missing -+ the microcode any userspace code that unconditionally uses AVX will -+ break with this option set. -+ -+ Setting this option on systems not vulnerable to GDS has no effect. -+ -+ If in doubt, say N. -+ - endif - - config ARCH_HAS_ADD_PAGES -diff --git a/arch/x86/include/asm/bugs.h b/arch/x86/include/asm/bugs.h -index 92ae283899409..f25ca2d709d40 100644 ---- a/arch/x86/include/asm/bugs.h -+++ b/arch/x86/include/asm/bugs.h -@@ -4,8 +4,6 @@ - - #include - --extern void check_bugs(void); -- - #if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32) - int ppro_with_ram_bug(void); - #else -diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h -index 1a85e1fb09226..ce0c8f7d32186 100644 ---- a/arch/x86/include/asm/cpufeature.h -+++ b/arch/x86/include/asm/cpufeature.h -@@ -32,6 +32,7 @@ enum cpuid_leafs - CPUID_8000_0007_EBX, - CPUID_7_EDX, - CPUID_8000_001F_EAX, -+ CPUID_8000_0021_EAX, - }; - - #define X86_CAP_FMT_NUM "%d:%d" -@@ -94,8 +95,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \ - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \ - CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \ -+ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \ - REQUIRED_MASK_CHECK || \ -- BUILD_BUG_ON_ZERO(NCAPINTS != 20)) -+ BUILD_BUG_ON_ZERO(NCAPINTS != 21)) - - #define DISABLED_MASK_BIT_SET(feature_bit) \ - ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \ -@@ -118,8 +120,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \ - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \ - CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \ -+ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \ - DISABLED_MASK_CHECK || \ -- BUILD_BUG_ON_ZERO(NCAPINTS != 20)) -+ BUILD_BUG_ON_ZERO(NCAPINTS != 21)) - - #define cpu_has(c, bit) \ - (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ -diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h -index 92729c38853d1..e721b8426c245 100644 ---- a/arch/x86/include/asm/cpufeatures.h -+++ b/arch/x86/include/asm/cpufeatures.h -@@ -13,8 +13,8 @@ - /* - * Defines x86 CPU feature bits - */ --#define NCAPINTS 20 /* N 32-bit words worth of info */ --#define NBUGINTS 1 /* N 32-bit bug flags */ -+#define NCAPINTS 21 /* N 32-bit words worth of info */ -+#define NBUGINTS 2 /* N 32-bit bug flags */ - - /* - * Note: If the comment begins with a quoted string, that string is used -@@ -308,6 +308,10 @@ - - #define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */ - -+#define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */ -+#define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */ -+#define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* "" Issue an IBPB only on VMEXIT */ -+ - /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ - #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ - #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ -@@ -423,6 +427,10 @@ - #define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* "" Virtual TSC_AUX */ - #define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */ - -+#define X86_FEATURE_SBPB (20*32+27) /* "" Selective Branch Prediction Barrier */ -+#define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* "" MSR_PRED_CMD[IBPB] flushes all branch type predictions */ -+#define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */ -+ - /* - * BUG word(s) - */ -@@ -464,5 +472,8 @@ - #define X86_BUG_RETBLEED X86_BUG(27) /* CPU is affected by RETBleed */ - #define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */ - #define X86_BUG_SMT_RSB X86_BUG(29) /* CPU is vulnerable to Cross-Thread Return Address Predictions */ -+#define X86_BUG_GDS X86_BUG(30) /* CPU is affected by Gather Data Sampling */ - -+/* BUG word 2 */ -+#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */ - #endif /* _ASM_X86_CPUFEATURES_H */ -diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h -index 33d2cd04d2544..000037078db43 100644 ---- a/arch/x86/include/asm/disabled-features.h -+++ b/arch/x86/include/asm/disabled-features.h -@@ -111,6 +111,7 @@ - #define DISABLED_MASK17 0 - #define DISABLED_MASK18 0 - #define DISABLED_MASK19 0 --#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20) -+#define DISABLED_MASK20 0 -+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21) - - #endif /* _ASM_X86_DISABLED_FEATURES_H */ -diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h -index 503a577814b2e..b475d9a582b88 100644 ---- a/arch/x86/include/asm/fpu/api.h -+++ b/arch/x86/include/asm/fpu/api.h -@@ -109,7 +109,7 @@ extern void fpu_reset_from_exception_fixup(void); - - /* Boot, hotplug and resume */ - extern void fpu__init_cpu(void); --extern void fpu__init_system(struct cpuinfo_x86 *c); -+extern void fpu__init_system(void); - extern void fpu__init_check_bugs(void); - extern void fpu__resume_cpu(void); - -diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h -index 72ca90552b6a4..8f513372cd8d4 100644 ---- a/arch/x86/include/asm/mem_encrypt.h -+++ b/arch/x86/include/asm/mem_encrypt.h -@@ -17,6 +17,12 @@ - - #include - -+#ifdef CONFIG_X86_MEM_ENCRYPT -+void __init mem_encrypt_init(void); -+#else -+static inline void mem_encrypt_init(void) { } -+#endif -+ - #ifdef CONFIG_AMD_MEM_ENCRYPT - - extern u64 sme_me_mask; -@@ -86,9 +92,6 @@ static inline void mem_encrypt_free_decrypted_mem(void) { } - - #endif /* CONFIG_AMD_MEM_ENCRYPT */ - --/* Architecture __weak replacement functions */ --void __init mem_encrypt_init(void); -- - void add_encrypt_protection_map(void); - - /* -diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h -index 846067e1ee8bb..52d8c67d93081 100644 ---- a/arch/x86/include/asm/msr-index.h -+++ b/arch/x86/include/asm/msr-index.h -@@ -60,6 +60,7 @@ - - #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ - #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */ -+#define PRED_CMD_SBPB BIT(7) /* Selective Branch Prediction Barrier */ - - #define MSR_PPIN_CTL 0x0000004e - #define MSR_PPIN 0x0000004f -@@ -158,6 +159,15 @@ - * Not susceptible to Post-Barrier - * Return Stack Buffer Predictions. - */ -+#define ARCH_CAP_GDS_CTRL BIT(25) /* -+ * CPU is vulnerable to Gather -+ * Data Sampling (GDS) and -+ * has controls for mitigation. -+ */ -+#define ARCH_CAP_GDS_NO BIT(26) /* -+ * CPU is not vulnerable to Gather -+ * Data Sampling (GDS). -+ */ - - #define ARCH_CAP_XAPIC_DISABLE BIT(21) /* - * IA32_XAPIC_DISABLE_STATUS MSR -@@ -181,6 +191,8 @@ - #define RNGDS_MITG_DIS BIT(0) /* SRBDS support */ - #define RTM_ALLOW BIT(1) /* TSX development mode */ - #define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */ -+#define GDS_MITG_DIS BIT(4) /* Disable GDS mitigation */ -+#define GDS_MITG_LOCKED BIT(5) /* GDS mitigation locked */ - - #define MSR_IA32_SYSENTER_CS 0x00000174 - #define MSR_IA32_SYSENTER_ESP 0x00000175 -diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h -index dfdb103ae4f6f..31fa631c8587c 100644 ---- a/arch/x86/include/asm/nospec-branch.h -+++ b/arch/x86/include/asm/nospec-branch.h -@@ -112,7 +112,7 @@ - * eventually turn into it's own annotation. - */ - .macro ANNOTATE_UNRET_END --#ifdef CONFIG_DEBUG_ENTRY -+#if (defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO)) - ANNOTATE_RETPOLINE_SAFE - nop - #endif -@@ -185,12 +185,18 @@ - * where we have a stack but before any RET instruction. - */ - .macro UNTRAIN_RET --#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY) -+#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_IBPB_ENTRY) || \ -+ defined(CONFIG_CPU_SRSO) - ANNOTATE_UNRET_END - ALTERNATIVE_2 "", \ - CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET, \ - "call entry_ibpb", X86_FEATURE_ENTRY_IBPB - #endif -+ -+#ifdef CONFIG_CPU_SRSO -+ ALTERNATIVE_2 "", "call srso_untrain_ret", X86_FEATURE_SRSO, \ -+ "call srso_untrain_ret_alias", X86_FEATURE_SRSO_ALIAS -+#endif - .endm - - #else /* __ASSEMBLY__ */ -@@ -206,6 +212,8 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[]; - - extern void __x86_return_thunk(void); - extern void zen_untrain_ret(void); -+extern void srso_untrain_ret(void); -+extern void srso_untrain_ret_alias(void); - extern void entry_ibpb(void); - - #ifdef CONFIG_RETPOLINE -@@ -311,11 +319,11 @@ void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature) - : "memory"); - } - -+extern u64 x86_pred_cmd; -+ - static inline void indirect_branch_prediction_barrier(void) - { -- u64 val = PRED_CMD_IBPB; -- -- alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB); -+ alternative_msr_write(MSR_IA32_PRED_CMD, x86_pred_cmd, X86_FEATURE_USE_IBPB); - } - - /* The Intel SPEC CTRL MSR base value cache */ -diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h -index d8277eec1bcd6..c13e4ff8ec70c 100644 ---- a/arch/x86/include/asm/processor.h -+++ b/arch/x86/include/asm/processor.h -@@ -800,9 +800,11 @@ extern u16 get_llc_id(unsigned int cpu); - #ifdef CONFIG_CPU_SUP_AMD - extern u32 amd_get_nodes_per_socket(void); - extern u32 amd_get_highest_perf(void); -+extern bool cpu_has_ibpb_brtype_microcode(void); - #else - static inline u32 amd_get_nodes_per_socket(void) { return 0; } - static inline u32 amd_get_highest_perf(void) { return 0; } -+static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } - #endif - - #define for_each_possible_hypervisor_cpuid_base(function) \ -diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h -index aff774775c678..7ba1726b71c7b 100644 ---- a/arch/x86/include/asm/required-features.h -+++ b/arch/x86/include/asm/required-features.h -@@ -98,6 +98,7 @@ - #define REQUIRED_MASK17 0 - #define REQUIRED_MASK18 0 - #define REQUIRED_MASK19 0 --#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20) -+#define REQUIRED_MASK20 0 -+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21) - - #endif /* _ASM_X86_REQUIRED_FEATURES_H */ -diff --git a/arch/x86/include/asm/sigframe.h b/arch/x86/include/asm/sigframe.h -index 5b1ed650b1248..84eab27248754 100644 ---- a/arch/x86/include/asm/sigframe.h -+++ b/arch/x86/include/asm/sigframe.h -@@ -85,6 +85,4 @@ struct rt_sigframe_x32 { - - #endif /* CONFIG_X86_64 */ - --void __init init_sigframe_size(void); -- - #endif /* _ASM_X86_SIGFRAME_H */ -diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c -index 7f4eb8b027cc8..7f0cf4a959c02 100644 ---- a/arch/x86/kernel/cpu/amd.c -+++ b/arch/x86/kernel/cpu/amd.c -@@ -1245,6 +1245,25 @@ u32 amd_get_highest_perf(void) - } - EXPORT_SYMBOL_GPL(amd_get_highest_perf); - -+bool cpu_has_ibpb_brtype_microcode(void) -+{ -+ switch (boot_cpu_data.x86) { -+ /* Zen1/2 IBPB flushes branch type predictions too. */ -+ case 0x17: -+ return boot_cpu_has(X86_FEATURE_AMD_IBPB); -+ case 0x19: -+ /* Poke the MSR bit on Zen3/4 to check its presence. */ -+ if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { -+ setup_force_cpu_cap(X86_FEATURE_SBPB); -+ return true; -+ } else { -+ return false; -+ } -+ default: -+ return false; -+ } -+} -+ - static void zenbleed_check_cpu(void *unused) - { - struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); -diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c -index f54992887491e..d98f33ea57e47 100644 ---- a/arch/x86/kernel/cpu/bugs.c -+++ b/arch/x86/kernel/cpu/bugs.c -@@ -9,7 +9,6 @@ - * - Andrew D. Balsa (code cleanup). - */ - #include --#include - #include - #include - #include -@@ -27,8 +26,6 @@ - #include - #include - #include --#include --#include - #include - #include - #include -@@ -49,6 +46,8 @@ static void __init taa_select_mitigation(void); - static void __init mmio_select_mitigation(void); - static void __init srbds_select_mitigation(void); - static void __init l1d_flush_select_mitigation(void); -+static void __init gds_select_mitigation(void); -+static void __init srso_select_mitigation(void); - - /* The base value of the SPEC_CTRL MSR without task-specific bits set */ - u64 x86_spec_ctrl_base; -@@ -58,6 +57,9 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_base); - DEFINE_PER_CPU(u64, x86_spec_ctrl_current); - EXPORT_SYMBOL_GPL(x86_spec_ctrl_current); - -+u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB; -+EXPORT_SYMBOL_GPL(x86_pred_cmd); -+ - static DEFINE_MUTEX(spec_ctrl_mutex); - - /* Update SPEC_CTRL MSR and its cached copy unconditionally */ -@@ -124,21 +126,8 @@ DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); - DEFINE_STATIC_KEY_FALSE(mmio_stale_data_clear); - EXPORT_SYMBOL_GPL(mmio_stale_data_clear); - --void __init check_bugs(void) -+void __init cpu_select_mitigations(void) - { -- identify_boot_cpu(); -- -- /* -- * identify_boot_cpu() initialized SMT support information, let the -- * core code know. -- */ -- cpu_smt_check_topology(); -- -- if (!IS_ENABLED(CONFIG_SMP)) { -- pr_info("CPU: "); -- print_cpu_info(&boot_cpu_data); -- } -- - /* - * Read the SPEC_CTRL MSR to account for reserved bits which may - * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD -@@ -175,39 +164,8 @@ void __init check_bugs(void) - md_clear_select_mitigation(); - srbds_select_mitigation(); - l1d_flush_select_mitigation(); -- -- arch_smt_update(); -- --#ifdef CONFIG_X86_32 -- /* -- * Check whether we are able to run this kernel safely on SMP. -- * -- * - i386 is no longer supported. -- * - In order to run on anything without a TSC, we need to be -- * compiled for a i486. -- */ -- if (boot_cpu_data.x86 < 4) -- panic("Kernel requires i486+ for 'invlpg' and other features"); -- -- init_utsname()->machine[1] = -- '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); -- alternative_instructions(); -- -- fpu__init_check_bugs(); --#else /* CONFIG_X86_64 */ -- alternative_instructions(); -- -- /* -- * Make sure the first 2MB area is not mapped by huge pages -- * There are typically fixed size MTRRs in there and overlapping -- * MTRRs into large pages causes slow downs. -- * -- * Right now we don't do that with gbpages because there seems -- * very little benefit for that case. -- */ -- if (!direct_gbpages) -- set_memory_4k((unsigned long)__va(0), 1); --#endif -+ gds_select_mitigation(); -+ srso_select_mitigation(); - } - - /* -@@ -693,6 +651,149 @@ static int __init l1d_flush_parse_cmdline(char *str) - } - early_param("l1d_flush", l1d_flush_parse_cmdline); - -+#undef pr_fmt -+#define pr_fmt(fmt) "GDS: " fmt -+ -+enum gds_mitigations { -+ GDS_MITIGATION_OFF, -+ GDS_MITIGATION_UCODE_NEEDED, -+ GDS_MITIGATION_FORCE, -+ GDS_MITIGATION_FULL, -+ GDS_MITIGATION_FULL_LOCKED, -+ GDS_MITIGATION_HYPERVISOR, -+}; -+ -+#if IS_ENABLED(CONFIG_GDS_FORCE_MITIGATION) -+static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FORCE; -+#else -+static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL; -+#endif -+ -+static const char * const gds_strings[] = { -+ [GDS_MITIGATION_OFF] = "Vulnerable", -+ [GDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", -+ [GDS_MITIGATION_FORCE] = "Mitigation: AVX disabled, no microcode", -+ [GDS_MITIGATION_FULL] = "Mitigation: Microcode", -+ [GDS_MITIGATION_FULL_LOCKED] = "Mitigation: Microcode (locked)", -+ [GDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status", -+}; -+ -+bool gds_ucode_mitigated(void) -+{ -+ return (gds_mitigation == GDS_MITIGATION_FULL || -+ gds_mitigation == GDS_MITIGATION_FULL_LOCKED); -+} -+EXPORT_SYMBOL_GPL(gds_ucode_mitigated); -+ -+void update_gds_msr(void) -+{ -+ u64 mcu_ctrl_after; -+ u64 mcu_ctrl; -+ -+ switch (gds_mitigation) { -+ case GDS_MITIGATION_OFF: -+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); -+ mcu_ctrl |= GDS_MITG_DIS; -+ break; -+ case GDS_MITIGATION_FULL_LOCKED: -+ /* -+ * The LOCKED state comes from the boot CPU. APs might not have -+ * the same state. Make sure the mitigation is enabled on all -+ * CPUs. -+ */ -+ case GDS_MITIGATION_FULL: -+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); -+ mcu_ctrl &= ~GDS_MITG_DIS; -+ break; -+ case GDS_MITIGATION_FORCE: -+ case GDS_MITIGATION_UCODE_NEEDED: -+ case GDS_MITIGATION_HYPERVISOR: -+ return; -+ }; -+ -+ wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); -+ -+ /* -+ * Check to make sure that the WRMSR value was not ignored. Writes to -+ * GDS_MITG_DIS will be ignored if this processor is locked but the boot -+ * processor was not. -+ */ -+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl_after); -+ WARN_ON_ONCE(mcu_ctrl != mcu_ctrl_after); -+} -+ -+static void __init gds_select_mitigation(void) -+{ -+ u64 mcu_ctrl; -+ -+ if (!boot_cpu_has_bug(X86_BUG_GDS)) -+ return; -+ -+ if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { -+ gds_mitigation = GDS_MITIGATION_HYPERVISOR; -+ goto out; -+ } -+ -+ if (cpu_mitigations_off()) -+ gds_mitigation = GDS_MITIGATION_OFF; -+ /* Will verify below that mitigation _can_ be disabled */ -+ -+ /* No microcode */ -+ if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) { -+ if (gds_mitigation == GDS_MITIGATION_FORCE) { -+ /* -+ * This only needs to be done on the boot CPU so do it -+ * here rather than in update_gds_msr() -+ */ -+ setup_clear_cpu_cap(X86_FEATURE_AVX); -+ pr_warn("Microcode update needed! Disabling AVX as mitigation.\n"); -+ } else { -+ gds_mitigation = GDS_MITIGATION_UCODE_NEEDED; -+ } -+ goto out; -+ } -+ -+ /* Microcode has mitigation, use it */ -+ if (gds_mitigation == GDS_MITIGATION_FORCE) -+ gds_mitigation = GDS_MITIGATION_FULL; -+ -+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); -+ if (mcu_ctrl & GDS_MITG_LOCKED) { -+ if (gds_mitigation == GDS_MITIGATION_OFF) -+ pr_warn("Mitigation locked. Disable failed.\n"); -+ -+ /* -+ * The mitigation is selected from the boot CPU. All other CPUs -+ * _should_ have the same state. If the boot CPU isn't locked -+ * but others are then update_gds_msr() will WARN() of the state -+ * mismatch. If the boot CPU is locked update_gds_msr() will -+ * ensure the other CPUs have the mitigation enabled. -+ */ -+ gds_mitigation = GDS_MITIGATION_FULL_LOCKED; -+ } -+ -+ update_gds_msr(); -+out: -+ pr_info("%s\n", gds_strings[gds_mitigation]); -+} -+ -+static int __init gds_parse_cmdline(char *str) -+{ -+ if (!str) -+ return -EINVAL; -+ -+ if (!boot_cpu_has_bug(X86_BUG_GDS)) -+ return 0; -+ -+ if (!strcmp(str, "off")) -+ gds_mitigation = GDS_MITIGATION_OFF; -+ else if (!strcmp(str, "force")) -+ gds_mitigation = GDS_MITIGATION_FORCE; -+ -+ return 0; -+} -+early_param("gather_data_sampling", gds_parse_cmdline); -+ - #undef pr_fmt - #define pr_fmt(fmt) "Spectre V1 : " fmt - -@@ -2207,6 +2308,165 @@ static int __init l1tf_cmdline(char *str) - } - early_param("l1tf", l1tf_cmdline); - -+#undef pr_fmt -+#define pr_fmt(fmt) "Speculative Return Stack Overflow: " fmt -+ -+enum srso_mitigation { -+ SRSO_MITIGATION_NONE, -+ SRSO_MITIGATION_MICROCODE, -+ SRSO_MITIGATION_SAFE_RET, -+ SRSO_MITIGATION_IBPB, -+ SRSO_MITIGATION_IBPB_ON_VMEXIT, -+}; -+ -+enum srso_mitigation_cmd { -+ SRSO_CMD_OFF, -+ SRSO_CMD_MICROCODE, -+ SRSO_CMD_SAFE_RET, -+ SRSO_CMD_IBPB, -+ SRSO_CMD_IBPB_ON_VMEXIT, -+}; -+ -+static const char * const srso_strings[] = { -+ [SRSO_MITIGATION_NONE] = "Vulnerable", -+ [SRSO_MITIGATION_MICROCODE] = "Mitigation: microcode", -+ [SRSO_MITIGATION_SAFE_RET] = "Mitigation: safe RET", -+ [SRSO_MITIGATION_IBPB] = "Mitigation: IBPB", -+ [SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only" -+}; -+ -+static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE; -+static enum srso_mitigation_cmd srso_cmd __ro_after_init = SRSO_CMD_SAFE_RET; -+ -+static int __init srso_parse_cmdline(char *str) -+{ -+ if (!str) -+ return -EINVAL; -+ -+ if (!strcmp(str, "off")) -+ srso_cmd = SRSO_CMD_OFF; -+ else if (!strcmp(str, "microcode")) -+ srso_cmd = SRSO_CMD_MICROCODE; -+ else if (!strcmp(str, "safe-ret")) -+ srso_cmd = SRSO_CMD_SAFE_RET; -+ else if (!strcmp(str, "ibpb")) -+ srso_cmd = SRSO_CMD_IBPB; -+ else if (!strcmp(str, "ibpb-vmexit")) -+ srso_cmd = SRSO_CMD_IBPB_ON_VMEXIT; -+ else -+ pr_err("Ignoring unknown SRSO option (%s).", str); -+ -+ return 0; -+} -+early_param("spec_rstack_overflow", srso_parse_cmdline); -+ -+#define SRSO_NOTICE "WARNING: See https://kernel.org/doc/html/latest/admin-guide/hw-vuln/srso.html for mitigation options." -+ -+static void __init srso_select_mitigation(void) -+{ -+ bool has_microcode; -+ -+ if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) -+ goto pred_cmd; -+ -+ /* -+ * The first check is for the kernel running as a guest in order -+ * for guests to verify whether IBPB is a viable mitigation. -+ */ -+ has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode(); -+ if (!has_microcode) { -+ pr_warn("IBPB-extending microcode not applied!\n"); -+ pr_warn(SRSO_NOTICE); -+ } else { -+ /* -+ * Enable the synthetic (even if in a real CPUID leaf) -+ * flags for guests. -+ */ -+ setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); -+ -+ /* -+ * Zen1/2 with SMT off aren't vulnerable after the right -+ * IBPB microcode has been applied. -+ */ -+ if ((boot_cpu_data.x86 < 0x19) && -+ (!cpu_smt_possible() || (cpu_smt_control == CPU_SMT_DISABLED))) -+ setup_force_cpu_cap(X86_FEATURE_SRSO_NO); -+ } -+ -+ if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) { -+ if (has_microcode) { -+ pr_err("Retbleed IBPB mitigation enabled, using same for SRSO\n"); -+ srso_mitigation = SRSO_MITIGATION_IBPB; -+ goto pred_cmd; -+ } -+ } -+ -+ switch (srso_cmd) { -+ case SRSO_CMD_OFF: -+ return; -+ -+ case SRSO_CMD_MICROCODE: -+ if (has_microcode) { -+ srso_mitigation = SRSO_MITIGATION_MICROCODE; -+ pr_warn(SRSO_NOTICE); -+ } -+ break; -+ -+ case SRSO_CMD_SAFE_RET: -+ if (IS_ENABLED(CONFIG_CPU_SRSO)) { -+ /* -+ * Enable the return thunk for generated code -+ * like ftrace, static_call, etc. -+ */ -+ setup_force_cpu_cap(X86_FEATURE_RETHUNK); -+ -+ if (boot_cpu_data.x86 == 0x19) -+ setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS); -+ else -+ setup_force_cpu_cap(X86_FEATURE_SRSO); -+ srso_mitigation = SRSO_MITIGATION_SAFE_RET; -+ } else { -+ pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); -+ goto pred_cmd; -+ } -+ break; -+ -+ case SRSO_CMD_IBPB: -+ if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) { -+ if (has_microcode) { -+ setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); -+ srso_mitigation = SRSO_MITIGATION_IBPB; -+ } -+ } else { -+ pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n"); -+ goto pred_cmd; -+ } -+ break; -+ -+ case SRSO_CMD_IBPB_ON_VMEXIT: -+ if (IS_ENABLED(CONFIG_CPU_SRSO)) { -+ if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { -+ setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); -+ srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; -+ } -+ } else { -+ pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); -+ goto pred_cmd; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode")); -+ -+pred_cmd: -+ if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) && -+ boot_cpu_has(X86_FEATURE_SBPB)) -+ x86_pred_cmd = PRED_CMD_SBPB; -+} -+ - #undef pr_fmt - #define pr_fmt(fmt) fmt - -@@ -2405,6 +2665,18 @@ static ssize_t retbleed_show_state(char *buf) - return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]); - } - -+static ssize_t gds_show_state(char *buf) -+{ -+ return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]); -+} -+ -+static ssize_t srso_show_state(char *buf) -+{ -+ return sysfs_emit(buf, "%s%s\n", -+ srso_strings[srso_mitigation], -+ (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); -+} -+ - static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, - char *buf, unsigned int bug) - { -@@ -2454,6 +2726,12 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr - case X86_BUG_RETBLEED: - return retbleed_show_state(buf); - -+ case X86_BUG_GDS: -+ return gds_show_state(buf); -+ -+ case X86_BUG_SRSO: -+ return srso_show_state(buf); -+ - default: - break; - } -@@ -2518,4 +2796,14 @@ ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, cha - { - return cpu_show_common(dev, attr, buf, X86_BUG_RETBLEED); - } -+ -+ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ return cpu_show_common(dev, attr, buf, X86_BUG_GDS); -+} -+ -+ssize_t cpu_show_spec_rstack_overflow(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ return cpu_show_common(dev, attr, buf, X86_BUG_SRSO); -+} - #endif -diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c -index d298d70f74ce6..d38ae25e7c01f 100644 ---- a/arch/x86/kernel/cpu/common.c -+++ b/arch/x86/kernel/cpu/common.c -@@ -18,11 +18,15 @@ - #include - #include - #include -+#include - #include -+#include - #include - #include - #include -+#include - -+#include - #include - #include - #include -@@ -58,7 +62,7 @@ - #include - #include - #include --#include -+#include - #include - #include - -@@ -1072,6 +1076,9 @@ void get_cpu_cap(struct cpuinfo_x86 *c) - if (c->extended_cpuid_level >= 0x8000001f) - c->x86_capability[CPUID_8000_001F_EAX] = cpuid_eax(0x8000001f); - -+ if (c->extended_cpuid_level >= 0x80000021) -+ c->x86_capability[CPUID_8000_0021_EAX] = cpuid_eax(0x80000021); -+ - init_scattered_cpuid_features(c); - init_speculation_control(c); - -@@ -1237,6 +1244,10 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { - #define RETBLEED BIT(3) - /* CPU is affected by SMT (cross-thread) return predictions */ - #define SMT_RSB BIT(4) -+/* CPU is affected by SRSO */ -+#define SRSO BIT(5) -+/* CPU is affected by GDS */ -+#define GDS BIT(6) - - static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { - VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), -@@ -1249,27 +1260,30 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { - VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), - VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), - VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), -- VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED), -+ VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), - VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), -- VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), -- VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), -+ VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), -+ VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), - VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED), -- VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), -- VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO), -- VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO), -- VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), -+ VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), -+ VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS), -+ VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS), -+ VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), - VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED), -- VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), -+ VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), -+ VULNBL_INTEL_STEPPINGS(TIGERLAKE_L, X86_STEPPING_ANY, GDS), -+ VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS), - VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), -- VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED), -+ VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS), - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO), - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS), - - VULNBL_AMD(0x15, RETBLEED), - VULNBL_AMD(0x16, RETBLEED), -- VULNBL_AMD(0x17, RETBLEED | SMT_RSB), -+ VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), - VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), -+ VULNBL_AMD(0x19, SRSO), - {} - }; - -@@ -1390,6 +1404,21 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) - if (cpu_matches(cpu_vuln_blacklist, SMT_RSB)) - setup_force_cpu_bug(X86_BUG_SMT_RSB); - -+ /* -+ * Check if CPU is vulnerable to GDS. If running in a virtual machine on -+ * an affected processor, the VMM may have disabled the use of GATHER by -+ * disabling AVX2. The only way to do this in HW is to clear XCR0[2], -+ * which means that AVX will be disabled. -+ */ -+ if (cpu_matches(cpu_vuln_blacklist, GDS) && !(ia32_cap & ARCH_CAP_GDS_NO) && -+ boot_cpu_has(X86_FEATURE_AVX)) -+ setup_force_cpu_bug(X86_BUG_GDS); -+ -+ if (!cpu_has(c, X86_FEATURE_SRSO_NO)) { -+ if (cpu_matches(cpu_vuln_blacklist, SRSO)) -+ setup_force_cpu_bug(X86_BUG_SRSO); -+ } -+ - if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) - return; - -@@ -1571,10 +1600,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) - - sld_setup(c); - -- fpu__init_system(c); -- -- init_sigframe_size(); -- - #ifdef CONFIG_X86_32 - /* - * Regardless of whether PCID is enumerated, the SDM says -@@ -1957,6 +1982,8 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c) - validate_apic_and_package_id(c); - x86_spec_ctrl_setup_ap(); - update_srbds_msr(); -+ if (boot_cpu_has_bug(X86_BUG_GDS)) -+ update_gds_msr(); - - tsx_ap_init(); - } -@@ -2290,8 +2317,6 @@ void cpu_init(void) - - doublefault_init_cpu_tss(); - -- fpu__init_cpu(); -- - if (is_uv_system()) - uv_cpu_init(); - -@@ -2307,6 +2332,7 @@ void cpu_init_secondary(void) - */ - cpu_init_exception_handling(); - cpu_init(); -+ fpu__init_cpu(); - } - #endif - -@@ -2369,3 +2395,69 @@ void arch_smt_update(void) - /* Check whether IPI broadcasting can be enabled */ - apic_smt_update(); - } -+ -+void __init arch_cpu_finalize_init(void) -+{ -+ identify_boot_cpu(); -+ -+ /* -+ * identify_boot_cpu() initialized SMT support information, let the -+ * core code know. -+ */ -+ cpu_smt_check_topology(); -+ -+ if (!IS_ENABLED(CONFIG_SMP)) { -+ pr_info("CPU: "); -+ print_cpu_info(&boot_cpu_data); -+ } -+ -+ cpu_select_mitigations(); -+ -+ arch_smt_update(); -+ -+ if (IS_ENABLED(CONFIG_X86_32)) { -+ /* -+ * Check whether this is a real i386 which is not longer -+ * supported and fixup the utsname. -+ */ -+ if (boot_cpu_data.x86 < 4) -+ panic("Kernel requires i486+ for 'invlpg' and other features"); -+ -+ init_utsname()->machine[1] = -+ '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); -+ } -+ -+ /* -+ * Must be before alternatives because it might set or clear -+ * feature bits. -+ */ -+ fpu__init_system(); -+ fpu__init_cpu(); -+ -+ alternative_instructions(); -+ -+ if (IS_ENABLED(CONFIG_X86_64)) { -+ /* -+ * Make sure the first 2MB area is not mapped by huge pages -+ * There are typically fixed size MTRRs in there and overlapping -+ * MTRRs into large pages causes slow downs. -+ * -+ * Right now we don't do that with gbpages because there seems -+ * very little benefit for that case. -+ */ -+ if (!direct_gbpages) -+ set_memory_4k((unsigned long)__va(0), 1); -+ } else { -+ fpu__init_check_bugs(); -+ } -+ -+ /* -+ * This needs to be called before any devices perform DMA -+ * operations that might use the SWIOTLB bounce buffers. It will -+ * mark the bounce buffers as decrypted so that their usage will -+ * not cause "plain-text" data to be decrypted when accessed. It -+ * must be called after late_time_init() so that Hyper-V x86/x64 -+ * hypercalls work when the SWIOTLB bounce buffers are decrypted. -+ */ -+ mem_encrypt_init(); -+} -diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h -index 7c9b5893c30ab..d9aeb335002dd 100644 ---- a/arch/x86/kernel/cpu/cpu.h -+++ b/arch/x86/kernel/cpu/cpu.h -@@ -79,9 +79,11 @@ extern void detect_ht(struct cpuinfo_x86 *c); - extern void check_null_seg_clears_base(struct cpuinfo_x86 *c); - - unsigned int aperfmperf_get_khz(int cpu); -+void cpu_select_mitigations(void); - - extern void x86_spec_ctrl_setup_ap(void); - extern void update_srbds_msr(void); -+extern void update_gds_msr(void); - - extern u64 x86_read_arch_cap_msr(void); - -diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c -index 851eb13edc014..998a08f17e331 100644 ---- a/arch/x86/kernel/fpu/init.c -+++ b/arch/x86/kernel/fpu/init.c -@@ -53,7 +53,7 @@ void fpu__init_cpu(void) - fpu__init_cpu_xstate(); - } - --static bool fpu__probe_without_cpuid(void) -+static bool __init fpu__probe_without_cpuid(void) - { - unsigned long cr0; - u16 fsw, fcw; -@@ -71,7 +71,7 @@ static bool fpu__probe_without_cpuid(void) - return fsw == 0 && (fcw & 0x103f) == 0x003f; - } - --static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) -+static void __init fpu__init_system_early_generic(void) - { - if (!boot_cpu_has(X86_FEATURE_CPUID) && - !test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { -@@ -211,10 +211,10 @@ static void __init fpu__init_system_xstate_size_legacy(void) - * Called on the boot CPU once per system bootup, to set up the initial - * FPU state that is later cloned into all processes: - */ --void __init fpu__init_system(struct cpuinfo_x86 *c) -+void __init fpu__init_system(void) - { - fpstate_reset(¤t->thread.fpu); -- fpu__init_system_early_generic(c); -+ fpu__init_system_early_generic(); - - /* - * The FPU has to be operational for some of the -diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c -index 82c562e2cc982..55ed638cb3fdc 100644 ---- a/arch/x86/kernel/signal.c -+++ b/arch/x86/kernel/signal.c -@@ -724,7 +724,7 @@ badframe: - static unsigned long __ro_after_init max_frame_size; - static unsigned int __ro_after_init fpu_default_state_size; - --void __init init_sigframe_size(void) -+static int __init init_sigframe_size(void) - { - fpu_default_state_size = fpu__get_fpstate_size(); - -@@ -736,7 +736,9 @@ void __init init_sigframe_size(void) - max_frame_size = round_up(max_frame_size, FRAME_ALIGNMENT); - - pr_info("max sigframe size: %lu\n", max_frame_size); -+ return 0; - } -+early_initcall(init_sigframe_size); - - unsigned long get_sigframe_size(void) - { -diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S -index 15f29053cec46..fd03f5a1f0ef0 100644 ---- a/arch/x86/kernel/vmlinux.lds.S -+++ b/arch/x86/kernel/vmlinux.lds.S -@@ -133,7 +133,20 @@ SECTIONS - LOCK_TEXT - KPROBES_TEXT - ALIGN_ENTRY_TEXT_BEGIN -+#ifdef CONFIG_CPU_SRSO -+ *(.text.__x86.rethunk_untrain) -+#endif -+ - ENTRY_TEXT -+ -+#ifdef CONFIG_CPU_SRSO -+ /* -+ * See the comment above srso_untrain_ret_alias()'s -+ * definition. -+ */ -+ . = srso_untrain_ret_alias | (1 << 2) | (1 << 8) | (1 << 14) | (1 << 20); -+ *(.text.__x86.rethunk_safe) -+#endif - ALIGN_ENTRY_TEXT_END - SOFTIRQENTRY_TEXT - STATIC_CALL_TEXT -@@ -141,13 +154,15 @@ SECTIONS - - #ifdef CONFIG_RETPOLINE - __indirect_thunk_start = .; -- *(.text.__x86.*) -+ *(.text.__x86.indirect_thunk) -+ *(.text.__x86.return_thunk) - __indirect_thunk_end = .; - #endif - } :text =0xcccc - - /* End of text section, which should occupy whole number of pages */ - _etext = .; -+ - . = ALIGN(PAGE_SIZE); - - X86_ALIGN_RODATA_BEGIN -@@ -492,6 +507,21 @@ INIT_PER_CPU(irq_stack_backing_store); - "fixed_percpu_data is not at start of per-cpu area"); - #endif - -+ #ifdef CONFIG_RETHUNK -+. = ASSERT((__ret & 0x3f) == 0, "__ret not cacheline-aligned"); -+. = ASSERT((srso_safe_ret & 0x3f) == 0, "srso_safe_ret not cacheline-aligned"); -+#endif -+ -+#ifdef CONFIG_CPU_SRSO -+/* -+ * GNU ld cannot do XOR so do: (A | B) - (A & B) in order to compute the XOR -+ * of the two function addresses: -+ */ -+. = ASSERT(((srso_untrain_ret_alias | srso_safe_ret_alias) - -+ (srso_untrain_ret_alias & srso_safe_ret_alias)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)), -+ "SRSO function pair won't alias"); -+#endif -+ - #endif /* CONFIG_X86_64 */ - - #ifdef CONFIG_KEXEC_CORE -diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c -index 6047dbe048803..7b4224f5ee2de 100644 ---- a/arch/x86/kvm/cpuid.c -+++ b/arch/x86/kvm/cpuid.c -@@ -736,6 +736,9 @@ void kvm_set_cpu_caps(void) - F(PMM) | F(PMM_EN) - ); - -+ if (cpu_feature_enabled(X86_FEATURE_SRSO_NO)) -+ kvm_cpu_cap_set(X86_FEATURE_SRSO_NO); -+ - /* - * Hide RDTSCP and RDPID if either feature is reported as supported but - * probing MSR_TSC_AUX failed. This is purely a sanity check and -diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h -index a19d473d01847..7eeade35a425b 100644 ---- a/arch/x86/kvm/reverse_cpuid.h -+++ b/arch/x86/kvm/reverse_cpuid.h -@@ -48,6 +48,7 @@ static const struct cpuid_reg reverse_cpuid[] = { - [CPUID_7_1_EAX] = { 7, 1, CPUID_EAX}, - [CPUID_12_EAX] = {0x00000012, 0, CPUID_EAX}, - [CPUID_8000_001F_EAX] = {0x8000001f, 0, CPUID_EAX}, -+ [CPUID_8000_0021_EAX] = {0x80000021, 0, CPUID_EAX}, - }; - - /* -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index 0a212fe2cd398..fdb6007f2eb86 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -1485,7 +1485,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) - - if (sd->current_vmcb != svm->vmcb) { - sd->current_vmcb = svm->vmcb; -- indirect_branch_prediction_barrier(); -+ -+ if (!cpu_feature_enabled(X86_FEATURE_IBPB_ON_VMEXIT)) -+ indirect_branch_prediction_barrier(); - } - if (kvm_vcpu_apicv_active(vcpu)) - avic_vcpu_load(vcpu, cpu); -diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S -index 34367dc203f21..5be9a63f09fff 100644 ---- a/arch/x86/kvm/svm/vmenter.S -+++ b/arch/x86/kvm/svm/vmenter.S -@@ -223,6 +223,9 @@ SYM_FUNC_START(__svm_vcpu_run) - */ - UNTRAIN_RET - -+ /* SRSO */ -+ ALTERNATIVE "", "call entry_ibpb", X86_FEATURE_IBPB_ON_VMEXIT -+ - /* - * Clear all general purpose registers except RSP and RAX to prevent - * speculative use of the guest's values, even those that are reloaded -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 32f589b96d997..f4b12c3c30a01 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -311,6 +311,8 @@ u64 __read_mostly host_xcr0; - - static struct kmem_cache *x86_emulator_cache; - -+extern bool gds_ucode_mitigated(void); -+ - /* - * When called, it means the previous get/set msr reached an invalid msr. - * Return true if we want to ignore/silent this failed msr access. -@@ -1613,7 +1615,7 @@ static unsigned int num_msr_based_features; - ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \ - ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \ - ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \ -- ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO) -+ ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO) - - static u64 kvm_get_arch_capabilities(void) - { -@@ -1670,6 +1672,9 @@ static u64 kvm_get_arch_capabilities(void) - */ - } - -+ if (!boot_cpu_has_bug(X86_BUG_GDS) || gds_ucode_mitigated()) -+ data |= ARCH_CAP_GDS_NO; -+ - return data; - } - -diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S -index 841955dc2573d..30e76fab678a5 100644 ---- a/arch/x86/lib/retpoline.S -+++ b/arch/x86/lib/retpoline.S -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - .section .text.__x86.indirect_thunk - -@@ -74,6 +75,46 @@ SYM_CODE_END(__x86_indirect_thunk_array) - */ - #ifdef CONFIG_RETHUNK - -+/* -+ * srso_untrain_ret_alias() and srso_safe_ret_alias() are placed at -+ * special addresses: -+ * -+ * - srso_untrain_ret_alias() is 2M aligned -+ * - srso_safe_ret_alias() is also in the same 2M page but bits 2, 8, 14 -+ * and 20 in its virtual address are set (while those bits in the -+ * srso_untrain_ret_alias() function are cleared). -+ * -+ * This guarantees that those two addresses will alias in the branch -+ * target buffer of Zen3/4 generations, leading to any potential -+ * poisoned entries at that BTB slot to get evicted. -+ * -+ * As a result, srso_safe_ret_alias() becomes a safe return. -+ */ -+#ifdef CONFIG_CPU_SRSO -+ .section .text.__x86.rethunk_untrain -+ -+SYM_START(srso_untrain_ret_alias, SYM_L_GLOBAL, SYM_A_NONE) -+ ANNOTATE_NOENDBR -+ ASM_NOP2 -+ lfence -+ jmp __x86_return_thunk -+SYM_FUNC_END(srso_untrain_ret_alias) -+__EXPORT_THUNK(srso_untrain_ret_alias) -+ -+ .section .text.__x86.rethunk_safe -+#endif -+ -+/* Needs a definition for the __x86_return_thunk alternative below. */ -+SYM_START(srso_safe_ret_alias, SYM_L_GLOBAL, SYM_A_NONE) -+#ifdef CONFIG_CPU_SRSO -+ add $8, %_ASM_SP -+ UNWIND_HINT_FUNC -+#endif -+ ANNOTATE_UNRET_SAFE -+ ret -+ int3 -+SYM_FUNC_END(srso_safe_ret_alias) -+ - .section .text.__x86.return_thunk - - /* -@@ -86,7 +127,7 @@ SYM_CODE_END(__x86_indirect_thunk_array) - * from re-poisioning the BTB prediction. - */ - .align 64 -- .skip 63, 0xcc -+ .skip 64 - (__ret - zen_untrain_ret), 0xcc - SYM_START(zen_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) - ANNOTATE_NOENDBR - /* -@@ -118,10 +159,10 @@ SYM_START(zen_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) - * evicted, __x86_return_thunk will suffer Straight Line Speculation - * which will be contained safely by the INT3. - */ --SYM_INNER_LABEL(__x86_return_thunk, SYM_L_GLOBAL) -+SYM_INNER_LABEL(__ret, SYM_L_GLOBAL) - ret - int3 --SYM_CODE_END(__x86_return_thunk) -+SYM_CODE_END(__ret) - - /* - * Ensure the TEST decoding / BTB invalidation is complete. -@@ -132,11 +173,45 @@ SYM_CODE_END(__x86_return_thunk) - * Jump back and execute the RET in the middle of the TEST instruction. - * INT3 is for SLS protection. - */ -- jmp __x86_return_thunk -+ jmp __ret - int3 - SYM_FUNC_END(zen_untrain_ret) - __EXPORT_THUNK(zen_untrain_ret) - -+/* -+ * SRSO untraining sequence for Zen1/2, similar to zen_untrain_ret() -+ * above. On kernel entry, srso_untrain_ret() is executed which is a -+ * -+ * movabs $0xccccccc308c48348,%rax -+ * -+ * and when the return thunk executes the inner label srso_safe_ret() -+ * later, it is a stack manipulation and a RET which is mispredicted and -+ * thus a "safe" one to use. -+ */ -+ .align 64 -+ .skip 64 - (srso_safe_ret - srso_untrain_ret), 0xcc -+SYM_START(srso_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) -+ ANNOTATE_NOENDBR -+ .byte 0x48, 0xb8 -+ -+SYM_INNER_LABEL(srso_safe_ret, SYM_L_GLOBAL) -+ add $8, %_ASM_SP -+ ret -+ int3 -+ int3 -+ int3 -+ lfence -+ call srso_safe_ret -+ int3 -+SYM_CODE_END(srso_safe_ret) -+SYM_FUNC_END(srso_untrain_ret) -+__EXPORT_THUNK(srso_untrain_ret) -+ -+SYM_FUNC_START(__x86_return_thunk) -+ ALTERNATIVE_2 "jmp __ret", "call srso_safe_ret", X86_FEATURE_SRSO, \ -+ "call srso_safe_ret_alias", X86_FEATURE_SRSO_ALIAS -+ int3 -+SYM_CODE_END(__x86_return_thunk) - EXPORT_SYMBOL(__x86_return_thunk) - - #endif /* CONFIG_RETHUNK */ -diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c -index 0d5ccea2538fc..913287b9340c9 100644 ---- a/arch/x86/mm/init.c -+++ b/arch/x86/mm/init.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - /* - * We need to define the tracepoints somewhere, and tlb.c -@@ -826,9 +827,12 @@ void __init poking_init(void) - spinlock_t *ptl; - pte_t *ptep; - -- poking_mm = copy_init_mm(); -+ poking_mm = mm_alloc(); - BUG_ON(!poking_mm); - -+ /* Xen PV guests need the PGD to be pinned. */ -+ paravirt_arch_dup_mmap(NULL, poking_mm); -+ - /* - * Randomize the poking address, but make sure that the following page - * will be mapped at the same PMD. We need 2 pages, so find space for 3, -diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c -index 6175f2c5c8224..e97bab7b00100 100644 ---- a/arch/x86/xen/smp_pv.c -+++ b/arch/x86/xen/smp_pv.c -@@ -63,6 +63,7 @@ static void cpu_bringup(void) - - cr4_init(); - cpu_init(); -+ fpu__init_cpu(); - touch_softlockup_watchdog(); - - /* PVH runs in ring 0 and allows us to do native syscalls. Yay! */ -diff --git a/arch/xtensa/include/asm/bugs.h b/arch/xtensa/include/asm/bugs.h -deleted file mode 100644 -index 69b29d1982494..0000000000000 ---- a/arch/xtensa/include/asm/bugs.h -+++ /dev/null -@@ -1,18 +0,0 @@ --/* -- * include/asm-xtensa/bugs.h -- * -- * This is included by init/main.c to check for architecture-dependent bugs. -- * -- * Xtensa processors don't have any bugs. :) -- * -- * This file is subject to the terms and conditions of the GNU General -- * Public License. See the file "COPYING" in the main directory of -- * this archive for more details. -- */ -- --#ifndef _XTENSA_BUGS_H --#define _XTENSA_BUGS_H -- --static void check_bugs(void) { } -- --#endif /* _XTENSA_BUGS_H */ -diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c -index 7af8e33735a36..dab70a65377c8 100644 ---- a/drivers/base/cpu.c -+++ b/drivers/base/cpu.c -@@ -577,6 +577,18 @@ ssize_t __weak cpu_show_retbleed(struct device *dev, - return sysfs_emit(buf, "Not affected\n"); - } - -+ssize_t __weak cpu_show_gds(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sysfs_emit(buf, "Not affected\n"); -+} -+ -+ssize_t __weak cpu_show_spec_rstack_overflow(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sysfs_emit(buf, "Not affected\n"); -+} -+ - static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); - static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); - static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); -@@ -588,6 +600,8 @@ static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); - static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL); - static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL); - static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL); -+static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); -+static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL); - - static struct attribute *cpu_root_vulnerabilities_attrs[] = { - &dev_attr_meltdown.attr, -@@ -601,6 +615,8 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { - &dev_attr_srbds.attr, - &dev_attr_mmio_stale_data.attr, - &dev_attr_retbleed.attr, -+ &dev_attr_gather_data_sampling.attr, -+ &dev_attr_spec_rstack_overflow.attr, - NULL - }; - -diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c -index c35c085dbc877..c3a8d78a41a7b 100644 ---- a/drivers/net/xen-netback/netback.c -+++ b/drivers/net/xen-netback/netback.c -@@ -396,7 +396,7 @@ static void xenvif_get_requests(struct xenvif_queue *queue, - struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops; - struct xen_netif_tx_request *txp = first; - -- nr_slots = shinfo->nr_frags + 1; -+ nr_slots = shinfo->nr_frags + frag_overflow + 1; - - copy_count(skb) = 0; - XENVIF_TX_CB(skb)->split_mask = 0; -@@ -462,8 +462,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue, - } - } - -- for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; -- shinfo->nr_frags++, gop++) { -+ for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; -+ shinfo->nr_frags++, gop++, nr_slots--) { - index = pending_index(queue->pending_cons++); - pending_idx = queue->pending_ring[index]; - xenvif_tx_create_map_op(queue, pending_idx, txp, -@@ -476,12 +476,12 @@ static void xenvif_get_requests(struct xenvif_queue *queue, - txp++; - } - -- if (frag_overflow) { -+ if (nr_slots > 0) { - - shinfo = skb_shinfo(nskb); - frags = shinfo->frags; - -- for (shinfo->nr_frags = 0; shinfo->nr_frags < frag_overflow; -+ for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; - shinfo->nr_frags++, txp++, gop++) { - index = pending_index(queue->pending_cons++); - pending_idx = queue->pending_ring[index]; -@@ -492,6 +492,11 @@ static void xenvif_get_requests(struct xenvif_queue *queue, - } - - skb_shinfo(skb)->frag_list = nskb; -+ } else if (nskb) { -+ /* A frag_list skb was allocated but it is no longer needed -+ * because enough slots were converted to copy ops above. -+ */ -+ kfree_skb(nskb); - } - - (*copy_ops) = cop - queue->tx_copy_ops; -diff --git a/include/asm-generic/bugs.h b/include/asm-generic/bugs.h -deleted file mode 100644 -index 69021830f078d..0000000000000 ---- a/include/asm-generic/bugs.h -+++ /dev/null -@@ -1,11 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --#ifndef __ASM_GENERIC_BUGS_H --#define __ASM_GENERIC_BUGS_H --/* -- * This file is included by 'init/main.c' to check for -- * architecture-dependent bugs. -- */ -- --static inline void check_bugs(void) { } -- --#endif /* __ASM_GENERIC_BUGS_H */ -diff --git a/include/linux/cpu.h b/include/linux/cpu.h -index 314802f98b9da..f98cfe9f188f5 100644 ---- a/include/linux/cpu.h -+++ b/include/linux/cpu.h -@@ -70,6 +70,8 @@ extern ssize_t cpu_show_mmio_stale_data(struct device *dev, - char *buf); - extern ssize_t cpu_show_retbleed(struct device *dev, - struct device_attribute *attr, char *buf); -+extern ssize_t cpu_show_spec_rstack_overflow(struct device *dev, -+ struct device_attribute *attr, char *buf); - - extern __printf(4, 5) - struct device *cpu_device_create(struct device *parent, void *drvdata, -@@ -187,6 +189,12 @@ void arch_cpu_idle_enter(void); - void arch_cpu_idle_exit(void); - void arch_cpu_idle_dead(void); - -+#ifdef CONFIG_ARCH_HAS_CPU_FINALIZE_INIT -+void arch_cpu_finalize_init(void); -+#else -+static inline void arch_cpu_finalize_init(void) { } -+#endif -+ - int cpu_report_state(int cpu); - int cpu_check_up_prepare(int cpu); - void cpu_set_state_online(int cpu); -diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h -index d6c48163c6def..357e0068497c1 100644 ---- a/include/linux/sched/task.h -+++ b/include/linux/sched/task.h -@@ -65,6 +65,7 @@ extern void sched_dead(struct task_struct *p); - void __noreturn do_task_dead(void); - void __noreturn make_task_dead(int signr); - -+extern void mm_cache_init(void); - extern void proc_caches_init(void); - - extern void fork_init(void); -@@ -90,7 +91,6 @@ extern void exit_itimers(struct task_struct *); - extern pid_t kernel_clone(struct kernel_clone_args *kargs); - struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node); - struct task_struct *fork_idle(int); --struct mm_struct *copy_init_mm(void); - extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); - extern pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags); - extern long kernel_wait4(pid_t, int __user *, int, struct rusage *); -diff --git a/init/main.c b/init/main.c -index aa21add5f7c54..fe378351e8a95 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -96,7 +96,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -104,7 +103,6 @@ - #include - - #include --#include - #include - #include - #include -@@ -781,8 +779,6 @@ void __init __weak thread_stack_cache_init(void) - } - #endif - --void __init __weak mem_encrypt_init(void) { } -- - void __init __weak poking_init(void) { } - - void __init __weak pgtable_cache_init(void) { } -@@ -860,6 +856,7 @@ static void __init mm_init(void) - /* Should be run after espfix64 is set up. */ - pti_init(); - kmsan_init_runtime(); -+ mm_cache_init(); - } - - #ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET -@@ -995,7 +992,7 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) - sort_main_extable(); - trap_init(); - mm_init(); -- -+ poking_init(); - ftrace_init(); - - /* trace_printk can be enabled here */ -@@ -1084,14 +1081,6 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) - */ - locking_selftest(); - -- /* -- * This needs to be called before any devices perform DMA -- * operations that might use the SWIOTLB bounce buffers. It will -- * mark the bounce buffers as decrypted so that their usage will -- * not cause "plain-text" data to be decrypted when accessed. -- */ -- mem_encrypt_init(); -- - #ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start && !initrd_below_start_ok && - page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { -@@ -1108,6 +1097,9 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) - late_time_init(); - sched_clock_init(); - calibrate_delay(); -+ -+ arch_cpu_finalize_init(); -+ - pid_idr_init(); - anon_vma_init(); - #ifdef CONFIG_X86 -@@ -1134,9 +1126,6 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) - taskstats_init_early(); - delayacct_init(); - -- poking_init(); -- check_bugs(); -- - acpi_subsystem_init(); - arch_post_acpi_subsys_init(); - kcsan_init(); -diff --git a/kernel/fork.c b/kernel/fork.c -index 6bb91fbbf73cc..41950ff90aa34 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -2600,11 +2600,6 @@ struct task_struct * __init fork_idle(int cpu) - return task; - } - --struct mm_struct *copy_init_mm(void) --{ -- return dup_mm(NULL, &init_mm); --} -- - /* - * This is like kernel_clone(), but shaved down and tailored to just - * creating io_uring workers. It returns a created task, or an error pointer. -@@ -3023,10 +3018,27 @@ static void sighand_ctor(void *data) - init_waitqueue_head(&sighand->signalfd_wqh); - } - --void __init proc_caches_init(void) -+void __init mm_cache_init(void) - { - unsigned int mm_size; - -+ /* -+ * The mm_cpumask is located at the end of mm_struct, and is -+ * dynamically sized based on the maximum CPU number this system -+ * can have, taking hotplug into account (nr_cpu_ids). -+ */ -+ mm_size = sizeof(struct mm_struct) + cpumask_size(); -+ -+ mm_cachep = kmem_cache_create_usercopy("mm_struct", -+ mm_size, ARCH_MIN_MMSTRUCT_ALIGN, -+ SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, -+ offsetof(struct mm_struct, saved_auxv), -+ sizeof_field(struct mm_struct, saved_auxv), -+ NULL); -+} -+ -+void __init proc_caches_init(void) -+{ - sighand_cachep = kmem_cache_create("sighand_cache", - sizeof(struct sighand_struct), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_TYPESAFE_BY_RCU| -@@ -3044,19 +3056,6 @@ void __init proc_caches_init(void) - SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, - NULL); - -- /* -- * The mm_cpumask is located at the end of mm_struct, and is -- * dynamically sized based on the maximum CPU number this system -- * can have, taking hotplug into account (nr_cpu_ids). -- */ -- mm_size = sizeof(struct mm_struct) + cpumask_size(); -- -- mm_cachep = kmem_cache_create_usercopy("mm_struct", -- mm_size, ARCH_MIN_MMSTRUCT_ALIGN, -- SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, -- offsetof(struct mm_struct, saved_auxv), -- sizeof_field(struct mm_struct, saved_auxv), -- NULL); - vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC|SLAB_ACCOUNT); - mmap_init(); - nsproxy_cache_init(); -diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h -index b71f4f2ecdd57..9ecc62861194e 100644 ---- a/tools/arch/x86/include/asm/cpufeatures.h -+++ b/tools/arch/x86/include/asm/cpufeatures.h -@@ -14,7 +14,7 @@ - * Defines x86 CPU feature bits - */ - #define NCAPINTS 20 /* N 32-bit words worth of info */ --#define NBUGINTS 1 /* N 32-bit bug flags */ -+#define NBUGINTS 2 /* N 32-bit bug flags */ - - /* - * Note: If the comment begins with a quoted string, that string is used -diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c -index 1c253b4b7ce00..a60c5efe34b36 100644 ---- a/tools/objtool/arch/x86/decode.c -+++ b/tools/objtool/arch/x86/decode.c -@@ -796,5 +796,8 @@ bool arch_is_retpoline(struct symbol *sym) - - bool arch_is_rethunk(struct symbol *sym) - { -- return !strcmp(sym->name, "__x86_return_thunk"); -+ return !strcmp(sym->name, "__x86_return_thunk") || -+ !strcmp(sym->name, "srso_untrain_ret") || -+ !strcmp(sym->name, "srso_safe_ret") || -+ !strcmp(sym->name, "__ret"); - } diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.44-45.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.44-45.patch deleted file mode 100644 index 225474101d3b..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.44-45.patch +++ /dev/null @@ -1,5988 +0,0 @@ -diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst -index bbc80eff03f98..b3c8ac6a2c385 100644 ---- a/Documentation/arm64/silicon-errata.rst -+++ b/Documentation/arm64/silicon-errata.rst -@@ -141,6 +141,10 @@ stable kernels. - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | MMU-500 | #841119,826419 | N/A | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | MMU-600 | #1076982,1209401| N/A | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | MMU-700 | #2268618,2812531| N/A | -++----------------+-----------------+-----------------+-----------------------------+ - +----------------+-----------------+-----------------+-----------------------------+ - | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | - +----------------+-----------------+-----------------+-----------------------------+ -diff --git a/Makefile b/Makefile -index 612f3d83629b4..82c958299e982 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 44 -+SUBLEVEL = 45 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts -index 48424e459f125..15b5651b88d03 100644 ---- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts -+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts -@@ -128,7 +128,7 @@ - status = "okay"; - clock-frequency = <100000>; - i2c-sda-falling-time-ns = <890>; /* hcnt */ -- i2c-sdl-falling-time-ns = <890>; /* lcnt */ -+ i2c-scl-falling-time-ns = <890>; /* lcnt */ - - adc@14 { - compatible = "lltc,ltc2497"; -diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts -index 847a7c01f5af5..fcf640de90b6b 100644 ---- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts -+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts -@@ -141,7 +141,7 @@ - status = "okay"; - clock-frequency = <100000>; - i2c-sda-falling-time-ns = <890>; /* hcnt */ -- i2c-sdl-falling-time-ns = <890>; /* lcnt */ -+ i2c-scl-falling-time-ns = <890>; /* lcnt */ - - adc@14 { - compatible = "lltc,ltc2497"; -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts -index 4a3df2b77b0be..6720ddf597839 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts -+++ b/arch/arm64/boot/dts/freescale/imx8mm-phyboard-polis-rdk.dts -@@ -141,7 +141,7 @@ - }; - - &gpio1 { -- gpio-line-names = "nINT_ETHPHY", "LED_RED", "WDOG_INT", "X_RTC_INT", -+ gpio-line-names = "", "LED_RED", "WDOG_INT", "X_RTC_INT", - "", "", "", "RESET_ETHPHY", - "CAN_nINT", "CAN_EN", "nENABLE_FLATLINK", "", - "USB_OTG_VBUS_EN", "", "LED_GREEN", "LED_BLUE"; -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi -index 995b44efb1b65..9d9b103c79c77 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mm-phycore-som.dtsi -@@ -111,7 +111,7 @@ - }; - - &gpio1 { -- gpio-line-names = "nINT_ETHPHY", "", "WDOG_INT", "X_RTC_INT", -+ gpio-line-names = "", "", "WDOG_INT", "X_RTC_INT", - "", "", "", "RESET_ETHPHY", - "", "", "nENABLE_FLATLINK"; - }; -@@ -210,7 +210,7 @@ - }; - }; - -- reg_vdd_gpu: buck3 { -+ reg_vdd_vpu: buck3 { - regulator-always-on; - regulator-boot-on; - regulator-max-microvolt = <1000000>; -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts -index 8e861b920d09e..7c9b60f4da922 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts -+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts -@@ -559,6 +559,10 @@ - status = "okay"; - }; - -+&disp_blk_ctrl { -+ status = "disabled"; -+}; -+ - &pgc_mipi { - status = "disabled"; - }; -diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts -index a67771d021464..46a07dfc0086c 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts -+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts -@@ -617,6 +617,10 @@ - status = "okay"; - }; - -+&disp_blk_ctrl { -+ status = "disabled"; -+}; -+ - &pgc_mipi { - status = "disabled"; - }; -diff --git a/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi -index d053ef302fb82..faafefe562e4b 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi -@@ -351,7 +351,7 @@ - MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 - MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 - MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f -- MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 -+ MX8MN_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x159 - >; - }; - -diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi -index 4724ed0cbff94..bf8f02c1535c1 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi -@@ -756,7 +756,7 @@ - <&clk IMX8MQ_SYS1_PLL_800M>, - <&clk IMX8MQ_VPU_PLL>; - assigned-clock-rates = <600000000>, -- <600000000>, -+ <300000000>, - <800000000>, - <0>; - }; -diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c -index 59aaf2e688336..356036babd093 100644 ---- a/arch/arm64/kernel/fpsimd.c -+++ b/arch/arm64/kernel/fpsimd.c -@@ -634,7 +634,7 @@ static void fpsimd_to_sve(struct task_struct *task) - void *sst = task->thread.sve_state; - struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state; - -- if (!system_supports_sve()) -+ if (!system_supports_sve() && !system_supports_sme()) - return; - - vq = sve_vq_from_vl(thread_get_cur_vl(&task->thread)); -@@ -660,7 +660,7 @@ static void sve_to_fpsimd(struct task_struct *task) - unsigned int i; - __uint128_t const *p; - -- if (!system_supports_sve()) -+ if (!system_supports_sve() && !system_supports_sme()) - return; - - vl = thread_get_cur_vl(&task->thread); -@@ -791,7 +791,8 @@ void sve_sync_from_fpsimd_zeropad(struct task_struct *task) - void *sst = task->thread.sve_state; - struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state; - -- if (!test_tsk_thread_flag(task, TIF_SVE)) -+ if (!test_tsk_thread_flag(task, TIF_SVE) && -+ !thread_sm_enabled(&task->thread)) - return; - - vq = sve_vq_from_vl(thread_get_cur_vl(&task->thread)); -@@ -863,7 +864,7 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type, - */ - task->thread.svcr &= ~(SVCR_SM_MASK | - SVCR_ZA_MASK); -- clear_thread_flag(TIF_SME); -+ clear_tsk_thread_flag(task, TIF_SME); - free_sme = true; - } - } -diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c -index 92bc9a2d702cb..f19f020ccff96 100644 ---- a/arch/arm64/kernel/ptrace.c -+++ b/arch/arm64/kernel/ptrace.c -@@ -937,11 +937,13 @@ static int sve_set_common(struct task_struct *target, - /* - * Ensure target->thread.sve_state is up to date with target's - * FPSIMD regs, so that a short copyin leaves trailing -- * registers unmodified. Always enable SVE even if going into -- * streaming mode. -+ * registers unmodified. Only enable SVE if we are -+ * configuring normal SVE, a system with streaming SVE may not -+ * have normal SVE. - */ - fpsimd_sync_to_sve(target); -- set_tsk_thread_flag(target, TIF_SVE); -+ if (type == ARM64_VEC_SVE) -+ set_tsk_thread_flag(target, TIF_SVE); - - BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header)); - start = SVE_PT_SVE_OFFSET; -diff --git a/arch/powerpc/include/asm/word-at-a-time.h b/arch/powerpc/include/asm/word-at-a-time.h -index 46c31fb8748d5..30a12d2086871 100644 ---- a/arch/powerpc/include/asm/word-at-a-time.h -+++ b/arch/powerpc/include/asm/word-at-a-time.h -@@ -34,7 +34,7 @@ static inline long find_zero(unsigned long mask) - return leading_zero_bits >> 3; - } - --static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) -+static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) - { - unsigned long rhs = val | c->low_bits; - *data = rhs; -diff --git a/arch/powerpc/kernel/trace/ftrace_mprofile.S b/arch/powerpc/kernel/trace/ftrace_mprofile.S -index d031093bc4367..6f9c2dea905b7 100644 ---- a/arch/powerpc/kernel/trace/ftrace_mprofile.S -+++ b/arch/powerpc/kernel/trace/ftrace_mprofile.S -@@ -33,6 +33,9 @@ - * and then arrange for the ftrace function to be called. - */ - .macro ftrace_regs_entry allregs -+ /* Create a minimal stack frame for representing B */ -+ PPC_STLU r1, -STACK_FRAME_MIN_SIZE(r1) -+ - /* Create our stack frame + pt_regs */ - PPC_STLU r1,-SWITCH_FRAME_SIZE(r1) - -@@ -42,7 +45,7 @@ - - #ifdef CONFIG_PPC64 - /* Save the original return address in A's stack frame */ -- std r0, LRSAVE+SWITCH_FRAME_SIZE(r1) -+ std r0, LRSAVE+SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE(r1) - /* Ok to continue? */ - lbz r3, PACA_FTRACE_ENABLED(r13) - cmpdi r3, 0 -@@ -77,6 +80,8 @@ - mflr r7 - /* Save it as pt_regs->nip */ - PPC_STL r7, _NIP(r1) -+ /* Also save it in B's stackframe header for proper unwind */ -+ PPC_STL r7, LRSAVE+SWITCH_FRAME_SIZE(r1) - /* Save the read LR in pt_regs->link */ - PPC_STL r0, _LINK(r1) - -@@ -142,7 +147,7 @@ - #endif - - /* Pop our stack frame */ -- addi r1, r1, SWITCH_FRAME_SIZE -+ addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE - - #ifdef CONFIG_LIVEPATCH_64 - /* Based on the cmpd above, if the NIP was altered handle livepatch */ -diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c -index fe1b83020e0df..0ec5b45b1e86a 100644 ---- a/arch/powerpc/mm/init_64.c -+++ b/arch/powerpc/mm/init_64.c -@@ -314,8 +314,7 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, - start = ALIGN_DOWN(start, page_size); - if (altmap) { - alt_start = altmap->base_pfn; -- alt_end = altmap->base_pfn + altmap->reserve + -- altmap->free + altmap->alloc + altmap->align; -+ alt_end = altmap->base_pfn + altmap->reserve + altmap->free; - } - - pr_debug("vmemmap_free %lx...%lx\n", start, end); -diff --git a/arch/s390/kernel/sthyi.c b/arch/s390/kernel/sthyi.c -index 4d141e2c132e5..2ea7f208f0e73 100644 ---- a/arch/s390/kernel/sthyi.c -+++ b/arch/s390/kernel/sthyi.c -@@ -459,9 +459,9 @@ static int sthyi_update_cache(u64 *rc) - * - * Fills the destination with system information returned by the STHYI - * instruction. The data is generated by emulation or execution of STHYI, -- * if available. The return value is the condition code that would be -- * returned, the rc parameter is the return code which is passed in -- * register R2 + 1. -+ * if available. The return value is either a negative error value or -+ * the condition code that would be returned, the rc parameter is the -+ * return code which is passed in register R2 + 1. - */ - int sthyi_fill(void *dst, u64 *rc) - { -diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c -index ee7478a601442..b37bb960bfaf0 100644 ---- a/arch/s390/kvm/intercept.c -+++ b/arch/s390/kvm/intercept.c -@@ -389,8 +389,8 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu) - */ - int handle_sthyi(struct kvm_vcpu *vcpu) - { -- int reg1, reg2, r = 0; -- u64 code, addr, cc = 0, rc = 0; -+ int reg1, reg2, cc = 0, r = 0; -+ u64 code, addr, rc = 0; - struct sthyi_sctns *sctns = NULL; - - if (!test_kvm_facility(vcpu->kvm, 74)) -@@ -421,7 +421,10 @@ int handle_sthyi(struct kvm_vcpu *vcpu) - return -ENOMEM; - - cc = sthyi_fill(sctns, &rc); -- -+ if (cc < 0) { -+ free_page((unsigned long)sctns); -+ return cc; -+ } - out: - if (!cc) { - if (kvm_s390_pv_cpu_is_protected(vcpu)) { -diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c -index 85863b9c9e684..189ae92de4d06 100644 ---- a/arch/x86/hyperv/hv_init.c -+++ b/arch/x86/hyperv/hv_init.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -467,6 +468,26 @@ void __init hyperv_init(void) - wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - } - -+ /* -+ * Some versions of Hyper-V that provide IBT in guest VMs have a bug -+ * in that there's no ENDBR64 instruction at the entry to the -+ * hypercall page. Because hypercalls are invoked via an indirect call -+ * to the hypercall page, all hypercall attempts fail when IBT is -+ * enabled, and Linux panics. For such buggy versions, disable IBT. -+ * -+ * Fixed versions of Hyper-V always provide ENDBR64 on the hypercall -+ * page, so if future Linux kernel versions enable IBT for 32-bit -+ * builds, additional hypercall page hackery will be required here -+ * to provide an ENDBR32. -+ */ -+#ifdef CONFIG_X86_KERNEL_IBT -+ if (cpu_feature_enabled(X86_FEATURE_IBT) && -+ *(u32 *)hv_hypercall_pg != gen_endbr()) { -+ setup_clear_cpu_cap(X86_FEATURE_IBT); -+ pr_warn("Hyper-V: Disabling IBT because of Hyper-V bug\n"); -+ } -+#endif -+ - /* - * hyperv_init() is called before LAPIC is initialized: see - * apic_intr_mode_init() -> x86_platform.apic_post_init() and -diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h -index e721b8426c245..b122708792c4d 100644 ---- a/arch/x86/include/asm/cpufeatures.h -+++ b/arch/x86/include/asm/cpufeatures.h -@@ -476,4 +476,5 @@ - - /* BUG word 2 */ - #define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */ -+#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */ - #endif /* _ASM_X86_CPUFEATURES_H */ -diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h -index c13e4ff8ec70c..45bf26862b99b 100644 ---- a/arch/x86/include/asm/processor.h -+++ b/arch/x86/include/asm/processor.h -@@ -801,10 +801,12 @@ extern u16 get_llc_id(unsigned int cpu); - extern u32 amd_get_nodes_per_socket(void); - extern u32 amd_get_highest_perf(void); - extern bool cpu_has_ibpb_brtype_microcode(void); -+extern void amd_clear_divider(void); - #else - static inline u32 amd_get_nodes_per_socket(void) { return 0; } - static inline u32 amd_get_highest_perf(void) { return 0; } - static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } -+static inline void amd_clear_divider(void) { } - #endif - - #define for_each_possible_hypervisor_cpuid_base(function) \ -diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c -index 7f0cf4a959c02..43910eb55b2e9 100644 ---- a/arch/x86/kernel/cpu/amd.c -+++ b/arch/x86/kernel/cpu/amd.c -@@ -75,6 +75,10 @@ static const int amd_zenbleed[] = - AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf), - AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf)); - -+static const int amd_div0[] = -+ AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x00, 0x0, 0x2f, 0xf), -+ AMD_MODEL_RANGE(0x17, 0x50, 0x0, 0x5f, 0xf)); -+ - static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) - { - int osvw_id = *erratum++; -@@ -1115,6 +1119,11 @@ static void init_amd(struct cpuinfo_x86 *c) - check_null_seg_clears_base(c); - - zenbleed_check(c); -+ -+ if (cpu_has_amd_erratum(c, amd_div0)) { -+ pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n"); -+ setup_force_cpu_bug(X86_BUG_DIV0); -+ } - } - - #ifdef CONFIG_X86_32 -@@ -1275,3 +1284,13 @@ void amd_check_microcode(void) - { - on_each_cpu(zenbleed_check_cpu, NULL, 1); - } -+ -+/* -+ * Issue a DIV 0/1 insn to clear any division data from previous DIV -+ * operations. -+ */ -+void noinstr amd_clear_divider(void) -+{ -+ asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0) -+ :: "a" (0), "d" (0), "r" (1)); -+} -diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c -index c0a5a4f225d9a..7e8795d8b0f17 100644 ---- a/arch/x86/kernel/traps.c -+++ b/arch/x86/kernel/traps.c -@@ -206,6 +206,8 @@ DEFINE_IDTENTRY(exc_divide_error) - { - do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE, - FPE_INTDIV, error_get_trap_addr(regs)); -+ -+ amd_clear_divider(); - } - - DEFINE_IDTENTRY(exc_overflow) -diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c -index daec0321cd76b..74ef3da545361 100644 ---- a/drivers/block/rbd.c -+++ b/drivers/block/rbd.c -@@ -3676,7 +3676,7 @@ static int rbd_lock(struct rbd_device *rbd_dev) - ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, - RBD_LOCK_NAME, CEPH_CLS_LOCK_EXCLUSIVE, cookie, - RBD_LOCK_TAG, "", 0); -- if (ret) -+ if (ret && ret != -EEXIST) - return ret; - - __rbd_lock(rbd_dev, cookie); -@@ -3879,7 +3879,7 @@ static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) - &rbd_dev->header_oloc, RBD_LOCK_NAME, - &lock_type, &lock_tag, &lockers, &num_lockers); - if (ret) { -- rbd_warn(rbd_dev, "failed to retrieve lockers: %d", ret); -+ rbd_warn(rbd_dev, "failed to get header lockers: %d", ret); - return ERR_PTR(ret); - } - -@@ -3941,8 +3941,10 @@ static int find_watcher(struct rbd_device *rbd_dev, - ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid, - &rbd_dev->header_oloc, &watchers, - &num_watchers); -- if (ret) -+ if (ret) { -+ rbd_warn(rbd_dev, "failed to get watchers: %d", ret); - return ret; -+ } - - sscanf(locker->id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", &cookie); - for (i = 0; i < num_watchers; i++) { -@@ -3986,8 +3988,12 @@ static int rbd_try_lock(struct rbd_device *rbd_dev) - locker = refreshed_locker = NULL; - - ret = rbd_lock(rbd_dev); -- if (ret != -EBUSY) -+ if (!ret) -+ goto out; -+ if (ret != -EBUSY) { -+ rbd_warn(rbd_dev, "failed to lock header: %d", ret); - goto out; -+ } - - /* determine if the current lock holder is still alive */ - locker = get_lock_owner_info(rbd_dev); -@@ -4090,11 +4096,8 @@ static int rbd_try_acquire_lock(struct rbd_device *rbd_dev) - - ret = rbd_try_lock(rbd_dev); - if (ret < 0) { -- rbd_warn(rbd_dev, "failed to lock header: %d", ret); -- if (ret == -EBLOCKLISTED) -- goto out; -- -- ret = 1; /* request lock anyway */ -+ rbd_warn(rbd_dev, "failed to acquire lock: %d", ret); -+ goto out; - } - if (ret > 0) { - up_write(&rbd_dev->lock_rwsem); -@@ -6628,12 +6631,11 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) - cancel_delayed_work_sync(&rbd_dev->lock_dwork); - if (!ret) - ret = -ETIMEDOUT; -- } - -- if (ret) { -- rbd_warn(rbd_dev, "failed to acquire exclusive lock: %ld", ret); -- return ret; -+ rbd_warn(rbd_dev, "failed to acquire lock: %ld", ret); - } -+ if (ret) -+ return ret; - - /* - * The lock may have been released by now, unless automatic lock -diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c -index 5e3d299190c89..61d9f9bf86e63 100644 ---- a/drivers/clk/imx/clk-imx93.c -+++ b/drivers/clk/imx/clk-imx93.c -@@ -288,7 +288,7 @@ static int imx93_clocks_probe(struct platform_device *pdev) - anatop_base = devm_of_iomap(dev, np, 0, NULL); - of_node_put(np); - if (WARN_ON(IS_ERR(anatop_base))) { -- ret = PTR_ERR(base); -+ ret = PTR_ERR(anatop_base); - goto unregister_hws; - } - -diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c -index a455f3c0e98b2..25d31dfdad15d 100644 ---- a/drivers/firmware/arm_scmi/mailbox.c -+++ b/drivers/firmware/arm_scmi/mailbox.c -@@ -106,8 +106,10 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, - return -ENOMEM; - - shmem = of_parse_phandle(cdev->of_node, "shmem", idx); -- if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) -+ if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { -+ of_node_put(shmem); - return -ENXIO; -+ } - - ret = of_address_to_resource(shmem, 0, &res); - of_node_put(shmem); -diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c -index 87a7b13cf868b..ac0bd51ef16a2 100644 ---- a/drivers/firmware/arm_scmi/smc.c -+++ b/drivers/firmware/arm_scmi/smc.c -@@ -23,6 +23,7 @@ - /** - * struct scmi_smc - Structure representing a SCMI smc transport - * -+ * @irq: An optional IRQ for completion - * @cinfo: SCMI channel info - * @shmem: Transmit/Receive shared memory area - * @shmem_lock: Lock to protect access to Tx/Rx shared memory area. -@@ -33,6 +34,7 @@ - */ - - struct scmi_smc { -+ int irq; - struct scmi_chan_info *cinfo; - struct scmi_shared_mem __iomem *shmem; - /* Protect access to shmem area */ -@@ -106,7 +108,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, - struct resource res; - struct device_node *np; - u32 func_id; -- int ret, irq; -+ int ret; - - if (!tx) - return -ENODEV; -@@ -116,8 +118,10 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, - return -ENOMEM; - - np = of_parse_phandle(cdev->of_node, "shmem", 0); -- if (!of_device_is_compatible(np, "arm,scmi-shmem")) -+ if (!of_device_is_compatible(np, "arm,scmi-shmem")) { -+ of_node_put(np); - return -ENXIO; -+ } - - ret = of_address_to_resource(np, 0, &res); - of_node_put(np); -@@ -142,11 +146,10 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, - * completion of a message is signaled by an interrupt rather than by - * the return of the SMC call. - */ -- irq = of_irq_get_byname(cdev->of_node, "a2p"); -- if (irq > 0) { -- ret = devm_request_irq(dev, irq, smc_msg_done_isr, -- IRQF_NO_SUSPEND, -- dev_name(dev), scmi_info); -+ scmi_info->irq = of_irq_get_byname(cdev->of_node, "a2p"); -+ if (scmi_info->irq > 0) { -+ ret = request_irq(scmi_info->irq, smc_msg_done_isr, -+ IRQF_NO_SUSPEND, dev_name(dev), scmi_info); - if (ret) { - dev_err(dev, "failed to setup SCMI smc irq\n"); - return ret; -@@ -168,6 +171,10 @@ static int smc_chan_free(int id, void *p, void *data) - struct scmi_chan_info *cinfo = p; - struct scmi_smc *scmi_info = cinfo->transport_info; - -+ /* Ignore any possible further reception on the IRQ path */ -+ if (scmi_info->irq > 0) -+ free_irq(scmi_info->irq, scmi_info); -+ - cinfo->transport_info = NULL; - scmi_info->cinfo = NULL; - -diff --git a/drivers/firmware/smccc/soc_id.c b/drivers/firmware/smccc/soc_id.c -index 890eb454599a3..1990263fbba0e 100644 ---- a/drivers/firmware/smccc/soc_id.c -+++ b/drivers/firmware/smccc/soc_id.c -@@ -34,7 +34,6 @@ static struct soc_device_attribute *soc_dev_attr; - - static int __init smccc_soc_init(void) - { -- struct arm_smccc_res res; - int soc_id_rev, soc_id_version; - static char soc_id_str[20], soc_id_rev_str[12]; - static char soc_id_jep106_id_str[12]; -@@ -49,13 +48,13 @@ static int __init smccc_soc_init(void) - } - - if (soc_id_version < 0) { -- pr_err("ARCH_SOC_ID(0) returned error: %lx\n", res.a0); -+ pr_err("Invalid SoC Version: %x\n", soc_id_version); - return -EINVAL; - } - - soc_id_rev = arm_smccc_get_soc_id_revision(); - if (soc_id_rev < 0) { -- pr_err("ARCH_SOC_ID(1) returned error: %lx\n", res.a0); -+ pr_err("Invalid SoC Revision: %x\n", soc_id_rev); - return -EINVAL; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c -index b81b77a9efa61..9b97fa39d47a2 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c -@@ -101,39 +101,97 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev) - } - } - -+static int amdgpu_atomfirmware_allocate_fb_v2_1(struct amdgpu_device *adev, -+ struct vram_usagebyfirmware_v2_1 *fw_usage, int *usage_bytes) -+{ -+ uint32_t start_addr, fw_size, drv_size; -+ -+ start_addr = le32_to_cpu(fw_usage->start_address_in_kb); -+ fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb); -+ drv_size = le16_to_cpu(fw_usage->used_by_driver_in_kb); -+ -+ DRM_DEBUG("atom firmware v2_1 requested %08x %dkb fw %dkb drv\n", -+ start_addr, -+ fw_size, -+ drv_size); -+ -+ if ((start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == -+ (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << -+ ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { -+ /* Firmware request VRAM reservation for SR-IOV */ -+ adev->mman.fw_vram_usage_start_offset = (start_addr & -+ (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; -+ adev->mman.fw_vram_usage_size = fw_size << 10; -+ /* Use the default scratch size */ -+ *usage_bytes = 0; -+ } else { -+ *usage_bytes = drv_size << 10; -+ } -+ return 0; -+} -+ -+static int amdgpu_atomfirmware_allocate_fb_v2_2(struct amdgpu_device *adev, -+ struct vram_usagebyfirmware_v2_2 *fw_usage, int *usage_bytes) -+{ -+ uint32_t fw_start_addr, fw_size, drv_start_addr, drv_size; -+ -+ fw_start_addr = le32_to_cpu(fw_usage->fw_region_start_address_in_kb); -+ fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb); -+ -+ drv_start_addr = le32_to_cpu(fw_usage->driver_region0_start_address_in_kb); -+ drv_size = le32_to_cpu(fw_usage->used_by_driver_region0_in_kb); -+ -+ DRM_DEBUG("atom requested fw start at %08x %dkb and drv start at %08x %dkb\n", -+ fw_start_addr, -+ fw_size, -+ drv_start_addr, -+ drv_size); -+ -+ if ((fw_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION << 30)) == 0) { -+ /* Firmware request VRAM reservation for SR-IOV */ -+ adev->mman.fw_vram_usage_start_offset = (fw_start_addr & -+ (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; -+ adev->mman.fw_vram_usage_size = fw_size << 10; -+ } -+ -+ if ((drv_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION << 30)) == 0) { -+ /* driver request VRAM reservation for SR-IOV */ -+ adev->mman.drv_vram_usage_start_offset = (drv_start_addr & -+ (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; -+ adev->mman.drv_vram_usage_size = drv_size << 10; -+ } -+ -+ *usage_bytes = 0; -+ return 0; -+} -+ - int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) - { - struct atom_context *ctx = adev->mode_info.atom_context; - int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, - vram_usagebyfirmware); -- struct vram_usagebyfirmware_v2_1 *firmware_usage; -- uint32_t start_addr, size; -+ struct vram_usagebyfirmware_v2_1 *fw_usage_v2_1; -+ struct vram_usagebyfirmware_v2_2 *fw_usage_v2_2; - uint16_t data_offset; -+ uint8_t frev, crev; - int usage_bytes = 0; - -- if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { -- firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); -- DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n", -- le32_to_cpu(firmware_usage->start_address_in_kb), -- le16_to_cpu(firmware_usage->used_by_firmware_in_kb), -- le16_to_cpu(firmware_usage->used_by_driver_in_kb)); -- -- start_addr = le32_to_cpu(firmware_usage->start_address_in_kb); -- size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb); -- -- if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) == -- (uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION << -- ATOM_VRAM_OPERATION_FLAGS_SHIFT)) { -- /* Firmware request VRAM reservation for SR-IOV */ -- adev->mman.fw_vram_usage_start_offset = (start_addr & -- (~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10; -- adev->mman.fw_vram_usage_size = size << 10; -- /* Use the default scratch size */ -- usage_bytes = 0; -- } else { -- usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10; -+ if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) { -+ if (frev == 2 && crev == 1) { -+ fw_usage_v2_1 = -+ (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset); -+ amdgpu_atomfirmware_allocate_fb_v2_1(adev, -+ fw_usage_v2_1, -+ &usage_bytes); -+ } else if (frev >= 2 && crev >= 2) { -+ fw_usage_v2_2 = -+ (struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset); -+ amdgpu_atomfirmware_allocate_fb_v2_2(adev, -+ fw_usage_v2_2, -+ &usage_bytes); - } - } -+ - ctx->scratch_size_bytes = 0; - if (usage_bytes == 0) - usage_bytes = 20 * 1024; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c -index ad8cb9e6d1ab0..0ee7c935fba1f 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c -@@ -347,17 +347,16 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev, - * @adev: amdgpu device object - * @offset: offset of the BO - * @size: size of the BO -- * @domain: where to place it - * @bo_ptr: used to initialize BOs in structures - * @cpu_addr: optional CPU address mapping - * -- * Creates a kernel BO at a specific offset in the address space of the domain. -+ * Creates a kernel BO at a specific offset in VRAM. - * - * Returns: - * 0 on success, negative error code otherwise. - */ - int amdgpu_bo_create_kernel_at(struct amdgpu_device *adev, -- uint64_t offset, uint64_t size, uint32_t domain, -+ uint64_t offset, uint64_t size, - struct amdgpu_bo **bo_ptr, void **cpu_addr) - { - struct ttm_operation_ctx ctx = { false, false }; -@@ -367,8 +366,9 @@ int amdgpu_bo_create_kernel_at(struct amdgpu_device *adev, - offset &= PAGE_MASK; - size = ALIGN(size, PAGE_SIZE); - -- r = amdgpu_bo_create_reserved(adev, size, PAGE_SIZE, domain, bo_ptr, -- NULL, cpu_addr); -+ r = amdgpu_bo_create_reserved(adev, size, PAGE_SIZE, -+ AMDGPU_GEM_DOMAIN_VRAM, bo_ptr, NULL, -+ cpu_addr); - if (r) - return r; - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h -index 147b79c10cbb6..93207badf83f3 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h -@@ -284,7 +284,7 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev, - u32 domain, struct amdgpu_bo **bo_ptr, - u64 *gpu_addr, void **cpu_addr); - int amdgpu_bo_create_kernel_at(struct amdgpu_device *adev, -- uint64_t offset, uint64_t size, uint32_t domain, -+ uint64_t offset, uint64_t size, - struct amdgpu_bo **bo_ptr, void **cpu_addr); - int amdgpu_bo_create_user(struct amdgpu_device *adev, - struct amdgpu_bo_param *bp, -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c -index b64938ed8cb68..10469f20a10ca 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c -@@ -1537,6 +1537,23 @@ static void amdgpu_ttm_fw_reserve_vram_fini(struct amdgpu_device *adev) - NULL, &adev->mman.fw_vram_usage_va); - } - -+/* -+ * Driver Reservation functions -+ */ -+/** -+ * amdgpu_ttm_drv_reserve_vram_fini - free drv reserved vram -+ * -+ * @adev: amdgpu_device pointer -+ * -+ * free drv reserved vram if it has been reserved. -+ */ -+static void amdgpu_ttm_drv_reserve_vram_fini(struct amdgpu_device *adev) -+{ -+ amdgpu_bo_free_kernel(&adev->mman.drv_vram_usage_reserved_bo, -+ NULL, -+ NULL); -+} -+ - /** - * amdgpu_ttm_fw_reserve_vram_init - create bo vram reservation from fw - * -@@ -1558,11 +1575,34 @@ static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev) - return amdgpu_bo_create_kernel_at(adev, - adev->mman.fw_vram_usage_start_offset, - adev->mman.fw_vram_usage_size, -- AMDGPU_GEM_DOMAIN_VRAM, - &adev->mman.fw_vram_usage_reserved_bo, - &adev->mman.fw_vram_usage_va); - } - -+/** -+ * amdgpu_ttm_drv_reserve_vram_init - create bo vram reservation from driver -+ * -+ * @adev: amdgpu_device pointer -+ * -+ * create bo vram reservation from drv. -+ */ -+static int amdgpu_ttm_drv_reserve_vram_init(struct amdgpu_device *adev) -+{ -+ uint64_t vram_size = adev->gmc.visible_vram_size; -+ -+ adev->mman.drv_vram_usage_reserved_bo = NULL; -+ -+ if (adev->mman.drv_vram_usage_size == 0 || -+ adev->mman.drv_vram_usage_size > vram_size) -+ return 0; -+ -+ return amdgpu_bo_create_kernel_at(adev, -+ adev->mman.drv_vram_usage_start_offset, -+ adev->mman.drv_vram_usage_size, -+ &adev->mman.drv_vram_usage_reserved_bo, -+ NULL); -+} -+ - /* - * Memoy training reservation functions - */ -@@ -1585,14 +1625,15 @@ static int amdgpu_ttm_training_reserve_vram_fini(struct amdgpu_device *adev) - return 0; - } - --static void amdgpu_ttm_training_data_block_init(struct amdgpu_device *adev) -+static void amdgpu_ttm_training_data_block_init(struct amdgpu_device *adev, -+ uint32_t reserve_size) - { - struct psp_memory_training_context *ctx = &adev->psp.mem_train_ctx; - - memset(ctx, 0, sizeof(*ctx)); - - ctx->c2p_train_data_offset = -- ALIGN((adev->gmc.mc_vram_size - adev->mman.discovery_tmr_size - SZ_1M), SZ_1M); -+ ALIGN((adev->gmc.mc_vram_size - reserve_size - SZ_1M), SZ_1M); - ctx->p2c_train_data_offset = - (adev->gmc.mc_vram_size - GDDR6_MEM_TRAINING_OFFSET); - ctx->train_data_size = -@@ -1610,9 +1651,10 @@ static void amdgpu_ttm_training_data_block_init(struct amdgpu_device *adev) - */ - static int amdgpu_ttm_reserve_tmr(struct amdgpu_device *adev) - { -- int ret; - struct psp_memory_training_context *ctx = &adev->psp.mem_train_ctx; - bool mem_train_support = false; -+ uint32_t reserve_size = 0; -+ int ret; - - if (!amdgpu_sriov_vf(adev)) { - if (amdgpu_atomfirmware_mem_training_supported(adev)) -@@ -1628,18 +1670,18 @@ static int amdgpu_ttm_reserve_tmr(struct amdgpu_device *adev) - * Otherwise, fallback to legacy approach to check and reserve tmr block for ip - * discovery data and G6 memory training data respectively - */ -- adev->mman.discovery_tmr_size = -- amdgpu_atomfirmware_get_fw_reserved_fb_size(adev); -- if (!adev->mman.discovery_tmr_size) -- adev->mman.discovery_tmr_size = DISCOVERY_TMR_OFFSET; -+ if (adev->bios) -+ reserve_size = -+ amdgpu_atomfirmware_get_fw_reserved_fb_size(adev); -+ if (!reserve_size) -+ reserve_size = DISCOVERY_TMR_OFFSET; - - if (mem_train_support) { - /* reserve vram for mem train according to TMR location */ -- amdgpu_ttm_training_data_block_init(adev); -+ amdgpu_ttm_training_data_block_init(adev, reserve_size); - ret = amdgpu_bo_create_kernel_at(adev, - ctx->c2p_train_data_offset, - ctx->train_data_size, -- AMDGPU_GEM_DOMAIN_VRAM, - &ctx->c2p_bo, - NULL); - if (ret) { -@@ -1651,14 +1693,14 @@ static int amdgpu_ttm_reserve_tmr(struct amdgpu_device *adev) - } - - ret = amdgpu_bo_create_kernel_at(adev, -- adev->gmc.real_vram_size - adev->mman.discovery_tmr_size, -- adev->mman.discovery_tmr_size, -- AMDGPU_GEM_DOMAIN_VRAM, -- &adev->mman.discovery_memory, -+ adev->gmc.real_vram_size - reserve_size, -+ reserve_size, -+ &adev->mman.fw_reserved_memory, - NULL); - if (ret) { - DRM_ERROR("alloc tmr failed(%d)!\n", ret); -- amdgpu_bo_free_kernel(&adev->mman.discovery_memory, NULL, NULL); -+ amdgpu_bo_free_kernel(&adev->mman.fw_reserved_memory, -+ NULL, NULL); - return ret; - } - -@@ -1730,6 +1772,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) - return r; - } - -+ /* -+ *The reserved vram for driver must be pinned to the specified -+ *place on the VRAM, so reserve it early. -+ */ -+ r = amdgpu_ttm_drv_reserve_vram_init(adev); -+ if (r) -+ return r; -+ - /* - * only NAVI10 and onwards ASIC support for IP discovery. - * If IP discovery enabled, a block of memory should be -@@ -1746,21 +1796,18 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) - * avoid display artifacts while transitioning between pre-OS - * and driver. */ - r = amdgpu_bo_create_kernel_at(adev, 0, adev->mman.stolen_vga_size, -- AMDGPU_GEM_DOMAIN_VRAM, - &adev->mman.stolen_vga_memory, - NULL); - if (r) - return r; - r = amdgpu_bo_create_kernel_at(adev, adev->mman.stolen_vga_size, - adev->mman.stolen_extended_size, -- AMDGPU_GEM_DOMAIN_VRAM, - &adev->mman.stolen_extended_memory, - NULL); - if (r) - return r; - r = amdgpu_bo_create_kernel_at(adev, adev->mman.stolen_reserved_offset, - adev->mman.stolen_reserved_size, -- AMDGPU_GEM_DOMAIN_VRAM, - &adev->mman.stolen_reserved_memory, - NULL); - if (r) -@@ -1847,14 +1894,16 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) - /* return the stolen vga memory back to VRAM */ - amdgpu_bo_free_kernel(&adev->mman.stolen_vga_memory, NULL, NULL); - amdgpu_bo_free_kernel(&adev->mman.stolen_extended_memory, NULL, NULL); -- /* return the IP Discovery TMR memory back to VRAM */ -- amdgpu_bo_free_kernel(&adev->mman.discovery_memory, NULL, NULL); -+ /* return the FW reserved memory back to VRAM */ -+ amdgpu_bo_free_kernel(&adev->mman.fw_reserved_memory, NULL, -+ NULL); - if (adev->mman.stolen_reserved_size) - amdgpu_bo_free_kernel(&adev->mman.stolen_reserved_memory, - NULL, NULL); - amdgpu_bo_free_kernel(&adev->mman.sdma_access_bo, NULL, - &adev->mman.sdma_access_ptr); - amdgpu_ttm_fw_reserve_vram_fini(adev); -+ amdgpu_ttm_drv_reserve_vram_fini(adev); - - if (drm_dev_enter(adev_to_drm(adev), &idx)) { - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h -index a37207011a69a..0fefa5e3a524b 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h -@@ -78,7 +78,8 @@ struct amdgpu_mman { - /* discovery */ - uint8_t *discovery_bin; - uint32_t discovery_tmr_size; -- struct amdgpu_bo *discovery_memory; -+ /* fw reserved memory */ -+ struct amdgpu_bo *fw_reserved_memory; - - /* firmware VRAM reservation */ - u64 fw_vram_usage_start_offset; -@@ -86,6 +87,11 @@ struct amdgpu_mman { - struct amdgpu_bo *fw_vram_usage_reserved_bo; - void *fw_vram_usage_va; - -+ /* driver VRAM reservation */ -+ u64 drv_vram_usage_start_offset; -+ u64 drv_vram_usage_size; -+ struct amdgpu_bo *drv_vram_usage_reserved_bo; -+ - /* PAGE_SIZE'd BO for process memory r/w over SDMA. */ - struct amdgpu_bo *sdma_access_bo; - void *sdma_access_ptr; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c -index c73abe54d9747..81549f1edfe01 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c -@@ -391,7 +391,6 @@ static void amdgpu_virt_ras_reserve_bps(struct amdgpu_device *adev) - */ - if (amdgpu_bo_create_kernel_at(adev, bp << AMDGPU_GPU_PAGE_SHIFT, - AMDGPU_GPU_PAGE_SIZE, -- AMDGPU_GEM_DOMAIN_VRAM, - &bo, NULL)) - DRM_DEBUG("RAS WARN: reserve vram for retired page %llx fail\n", bp); - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 9b2915764306b..86e07cc1d3dcc 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -351,6 +351,19 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state, - return false; - } - -+static inline void reverse_planes_order(struct dc_surface_update *array_of_surface_update, -+ int planes_count) -+{ -+ int i, j; -+ struct dc_surface_update surface_updates_temp; -+ -+ for (i = 0, j = planes_count - 1; i < j; i++, j--) { -+ surface_updates_temp = array_of_surface_update[i]; -+ array_of_surface_update[i] = array_of_surface_update[j]; -+ array_of_surface_update[j] = surface_updates_temp; -+ } -+} -+ - /** - * update_planes_and_stream_adapter() - Send planes to be updated in DC - * -@@ -367,6 +380,8 @@ static inline bool update_planes_and_stream_adapter(struct dc *dc, - struct dc_stream_update *stream_update, - struct dc_surface_update *array_of_surface_update) - { -+ reverse_planes_order(array_of_surface_update, planes_count); -+ - /* - * Previous frame finished and HW is ready for optimization. - */ -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c -index 5d53e54ebe90b..c2c6c4587a5ce 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c -@@ -2092,6 +2092,7 @@ static enum dc_status enable_link_dp_mst( - struct pipe_ctx *pipe_ctx) - { - struct dc_link *link = pipe_ctx->stream->link; -+ unsigned char mstm_cntl; - - /* sink signal type after MST branch is MST. Multiple MST sinks - * share one link. Link DP PHY is enable or training only once. -@@ -2100,7 +2101,9 @@ static enum dc_status enable_link_dp_mst( - return DC_OK; - - /* clear payload table */ -- dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link); -+ core_link_read_dpcd(link, DP_MSTM_CTRL, &mstm_cntl, 1); -+ if (mstm_cntl & DP_MST_EN) -+ dm_helpers_dp_mst_clear_payload_allocation_table(link->ctx, link); - - /* to make sure the pending down rep can be processed - * before enabling the link -diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h -index ff855cb21d3f9..bbe1337a8cee3 100644 ---- a/drivers/gpu/drm/amd/include/atomfirmware.h -+++ b/drivers/gpu/drm/amd/include/atomfirmware.h -@@ -705,20 +705,65 @@ struct atom_gpio_pin_lut_v2_1 - }; - - --/* -- *************************************************************************** -- Data Table vram_usagebyfirmware structure -- *************************************************************************** --*/ -+/* -+ * VBIOS/PRE-OS always reserve a FB region at the top of frame buffer. driver should not write -+ * access that region. driver can allocate their own reservation region as long as it does not -+ * overlap firwmare's reservation region. -+ * if (pre-NV1X) atom data table firmwareInfoTable version < 3.3: -+ * in this case, atom data table vram_usagebyfirmwareTable version always <= 2.1 -+ * if VBIOS/UEFI GOP is posted: -+ * VBIOS/UEFIGOP update used_by_firmware_in_kb = total reserved size by VBIOS -+ * update start_address_in_kb = total_mem_size_in_kb - used_by_firmware_in_kb; -+ * ( total_mem_size_in_kb = reg(CONFIG_MEMSIZE)<<10) -+ * driver can allocate driver reservation region under firmware reservation, -+ * used_by_driver_in_kb = driver reservation size -+ * driver reservation start address = (start_address_in_kb - used_by_driver_in_kb) -+ * Comment1[hchan]: There is only one reservation at the beginning of the FB reserved by -+ * host driver. Host driver would overwrite the table with the following -+ * used_by_firmware_in_kb = total reserved size for pf-vf info exchange and -+ * set SRIOV_MSG_SHARE_RESERVATION mask start_address_in_kb = 0 -+ * else there is no VBIOS reservation region: -+ * driver must allocate driver reservation region at top of FB. -+ * driver set used_by_driver_in_kb = driver reservation size -+ * driver reservation start address = (total_mem_size_in_kb - used_by_driver_in_kb) -+ * same as Comment1 -+ * else (NV1X and after): -+ * if VBIOS/UEFI GOP is posted: -+ * VBIOS/UEFIGOP update: -+ * used_by_firmware_in_kb = atom_firmware_Info_v3_3.fw_reserved_size_in_kb; -+ * start_address_in_kb = total_mem_size_in_kb - used_by_firmware_in_kb; -+ * (total_mem_size_in_kb = reg(CONFIG_MEMSIZE)<<10) -+ * if vram_usagebyfirmwareTable version <= 2.1: -+ * driver can allocate driver reservation region under firmware reservation, -+ * driver set used_by_driver_in_kb = driver reservation size -+ * driver reservation start address = start_address_in_kb - used_by_driver_in_kb -+ * same as Comment1 -+ * else driver can: -+ * allocate it reservation any place as long as it does overlap pre-OS FW reservation area -+ * set used_by_driver_region0_in_kb = driver reservation size -+ * set driver_region0_start_address_in_kb = driver reservation region start address -+ * Comment2[hchan]: Host driver can set used_by_firmware_in_kb and start_address_in_kb to -+ * zero as the reservation for VF as it doesn’t exist. And Host driver should also -+ * update atom_firmware_Info table to remove the same VBIOS reservation as well. -+ */ - - struct vram_usagebyfirmware_v2_1 - { -- struct atom_common_table_header table_header; -- uint32_t start_address_in_kb; -- uint16_t used_by_firmware_in_kb; -- uint16_t used_by_driver_in_kb; -+ struct atom_common_table_header table_header; -+ uint32_t start_address_in_kb; -+ uint16_t used_by_firmware_in_kb; -+ uint16_t used_by_driver_in_kb; - }; - -+struct vram_usagebyfirmware_v2_2 { -+ struct atom_common_table_header table_header; -+ uint32_t fw_region_start_address_in_kb; -+ uint16_t used_by_firmware_in_kb; -+ uint16_t reserved; -+ uint32_t driver_region0_start_address_in_kb; -+ uint32_t used_by_driver_region0_in_kb; -+ uint32_t reserved32[7]; -+}; - - /* - *************************************************************************** -diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c -index da9b995b54c8f..96e679a176e94 100644 ---- a/drivers/gpu/drm/i915/display/intel_display.c -+++ b/drivers/gpu/drm/i915/display/intel_display.c -@@ -7123,8 +7123,6 @@ static void intel_update_crtc(struct intel_atomic_state *state, - - intel_fbc_update(state, crtc); - -- drm_WARN_ON(&i915->drm, !intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF)); -- - if (!modeset && - (new_crtc_state->uapi.color_mgmt_changed || - new_crtc_state->update_pipe)) -@@ -7501,28 +7499,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) - drm_atomic_helper_wait_for_dependencies(&state->base); - drm_dp_mst_atomic_wait_for_dependencies(&state->base); - -- /* -- * During full modesets we write a lot of registers, wait -- * for PLLs, etc. Doing that while DC states are enabled -- * is not a good idea. -- * -- * During fastsets and other updates we also need to -- * disable DC states due to the following scenario: -- * 1. DC5 exit and PSR exit happen -- * 2. Some or all _noarm() registers are written -- * 3. Due to some long delay PSR is re-entered -- * 4. DC5 entry -> DMC saves the already written new -- * _noarm() registers and the old not yet written -- * _arm() registers -- * 5. DC5 exit -> DMC restores a mixture of old and -- * new register values and arms the update -- * 6. PSR exit -> hardware latches a mixture of old and -- * new register values -> corrupted frame, or worse -- * 7. New _arm() registers are finally written -- * 8. Hardware finally latches a complete set of new -- * register values, and subsequent frames will be OK again -- */ -- wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF); -+ if (state->modeset) -+ wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET); - - intel_atomic_prepare_plane_clear_colors(state); - -@@ -7661,8 +7639,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) - * the culprit. - */ - intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore); -+ intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref); - } -- intel_display_power_put(dev_priv, POWER_DOMAIN_DC_OFF, wakeref); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); - - /* -diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -index e49fa6fa6aee1..b2838732ac936 100644 ---- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -@@ -256,8 +256,8 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) - - if (!HAS_FLAT_CCS(rq->engine->i915)) { - /* hsdes: 1809175790 */ -- cs = gen12_emit_aux_table_inv(rq->engine->gt, -- cs, GEN12_GFX_CCS_AUX_NV); -+ cs = gen12_emit_aux_table_inv(rq->engine->gt, cs, -+ GEN12_CCS_AUX_INV); - } - - *cs++ = preparser_disable(false); -@@ -317,10 +317,10 @@ int gen12_emit_flush_xcs(struct i915_request *rq, u32 mode) - if (aux_inv) { /* hsdes: 1809175790 */ - if (rq->engine->class == VIDEO_DECODE_CLASS) - cs = gen12_emit_aux_table_inv(rq->engine->gt, -- cs, GEN12_VD0_AUX_NV); -+ cs, GEN12_VD0_AUX_INV); - else - cs = gen12_emit_aux_table_inv(rq->engine->gt, -- cs, GEN12_VE0_AUX_NV); -+ cs, GEN12_VE0_AUX_INV); - } - - if (mode & EMIT_INVALIDATE) -diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h -index 2275ee47da955..dd006563cc81e 100644 ---- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h -+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h -@@ -301,9 +301,11 @@ - #define GEN8_PRIVATE_PAT_HI _MMIO(0x40e0 + 4) - #define GEN10_PAT_INDEX(index) _MMIO(0x40e0 + (index) * 4) - #define BSD_HWS_PGA_GEN7 _MMIO(0x4180) --#define GEN12_GFX_CCS_AUX_NV _MMIO(0x4208) --#define GEN12_VD0_AUX_NV _MMIO(0x4218) --#define GEN12_VD1_AUX_NV _MMIO(0x4228) -+ -+#define GEN12_CCS_AUX_INV _MMIO(0x4208) -+#define GEN12_VD0_AUX_INV _MMIO(0x4218) -+#define GEN12_VE0_AUX_INV _MMIO(0x4238) -+#define GEN12_BCS0_AUX_INV _MMIO(0x4248) - - #define GEN8_RTCR _MMIO(0x4260) - #define GEN8_M1TCR _MMIO(0x4264) -@@ -311,14 +313,12 @@ - #define GEN8_BTCR _MMIO(0x426c) - #define GEN8_VTCR _MMIO(0x4270) - --#define GEN12_VD2_AUX_NV _MMIO(0x4298) --#define GEN12_VD3_AUX_NV _MMIO(0x42a8) --#define GEN12_VE0_AUX_NV _MMIO(0x4238) -- - #define BLT_HWS_PGA_GEN7 _MMIO(0x4280) - --#define GEN12_VE1_AUX_NV _MMIO(0x42b8) -+#define GEN12_VD2_AUX_INV _MMIO(0x4298) -+#define GEN12_CCS0_AUX_INV _MMIO(0x42c8) - #define AUX_INV REG_BIT(0) -+ - #define VEBOX_HWS_PGA_GEN7 _MMIO(0x4380) - - #define GEN12_AUX_ERR_DBG _MMIO(0x43f4) -diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c -index 3955292483a6f..137e41e37ea54 100644 ---- a/drivers/gpu/drm/i915/gt/intel_lrc.c -+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c -@@ -1299,7 +1299,7 @@ gen12_emit_indirect_ctx_rcs(const struct intel_context *ce, u32 *cs) - /* hsdes: 1809175790 */ - if (!HAS_FLAT_CCS(ce->engine->i915)) - cs = gen12_emit_aux_table_inv(ce->engine->gt, -- cs, GEN12_GFX_CCS_AUX_NV); -+ cs, GEN12_CCS_AUX_INV); - - /* Wa_16014892111 */ - if (IS_DG2(ce->engine->i915)) -@@ -1326,10 +1326,10 @@ gen12_emit_indirect_ctx_xcs(const struct intel_context *ce, u32 *cs) - if (!HAS_FLAT_CCS(ce->engine->i915)) { - if (ce->engine->class == VIDEO_DECODE_CLASS) - cs = gen12_emit_aux_table_inv(ce->engine->gt, -- cs, GEN12_VD0_AUX_NV); -+ cs, GEN12_VD0_AUX_INV); - else if (ce->engine->class == VIDEO_ENHANCEMENT_CLASS) - cs = gen12_emit_aux_table_inv(ce->engine->gt, -- cs, GEN12_VE0_AUX_NV); -+ cs, GEN12_VE0_AUX_INV); - } - - return cs; -diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c -index 8ef93889061a6..5ec293011d990 100644 ---- a/drivers/gpu/drm/i915/i915_active.c -+++ b/drivers/gpu/drm/i915/i915_active.c -@@ -449,8 +449,11 @@ int i915_active_add_request(struct i915_active *ref, struct i915_request *rq) - } - } while (unlikely(is_barrier(active))); - -- if (!__i915_active_fence_set(active, fence)) -+ fence = __i915_active_fence_set(active, fence); -+ if (!fence) - __i915_active_acquire(ref); -+ else -+ dma_fence_put(fence); - - out: - i915_active_release(ref); -@@ -469,13 +472,9 @@ __i915_active_set_fence(struct i915_active *ref, - return NULL; - } - -- rcu_read_lock(); - prev = __i915_active_fence_set(active, fence); -- if (prev) -- prev = dma_fence_get_rcu(prev); -- else -+ if (!prev) - __i915_active_acquire(ref); -- rcu_read_unlock(); - - return prev; - } -@@ -1019,10 +1018,11 @@ void i915_request_add_active_barriers(struct i915_request *rq) - * - * Records the new @fence as the last active fence along its timeline in - * this active tracker, moving the tracking callbacks from the previous -- * fence onto this one. Returns the previous fence (if not already completed), -- * which the caller must ensure is executed before the new fence. To ensure -- * that the order of fences within the timeline of the i915_active_fence is -- * understood, it should be locked by the caller. -+ * fence onto this one. Gets and returns a reference to the previous fence -+ * (if not already completed), which the caller must put after making sure -+ * that it is executed before the new fence. To ensure that the order of -+ * fences within the timeline of the i915_active_fence is understood, it -+ * should be locked by the caller. - */ - struct dma_fence * - __i915_active_fence_set(struct i915_active_fence *active, -@@ -1031,7 +1031,23 @@ __i915_active_fence_set(struct i915_active_fence *active, - struct dma_fence *prev; - unsigned long flags; - -- if (fence == rcu_access_pointer(active->fence)) -+ /* -+ * In case of fences embedded in i915_requests, their memory is -+ * SLAB_FAILSAFE_BY_RCU, then it can be reused right after release -+ * by new requests. Then, there is a risk of passing back a pointer -+ * to a new, completely unrelated fence that reuses the same memory -+ * while tracked under a different active tracker. Combined with i915 -+ * perf open/close operations that build await dependencies between -+ * engine kernel context requests and user requests from different -+ * timelines, this can lead to dependency loops and infinite waits. -+ * -+ * As a countermeasure, we try to get a reference to the active->fence -+ * first, so if we succeed and pass it back to our user then it is not -+ * released and potentially reused by an unrelated request before the -+ * user has a chance to set up an await dependency on it. -+ */ -+ prev = i915_active_fence_get(active); -+ if (fence == prev) - return fence; - - GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)); -@@ -1040,27 +1056,56 @@ __i915_active_fence_set(struct i915_active_fence *active, - * Consider that we have two threads arriving (A and B), with - * C already resident as the active->fence. - * -- * A does the xchg first, and so it sees C or NULL depending -- * on the timing of the interrupt handler. If it is NULL, the -- * previous fence must have been signaled and we know that -- * we are first on the timeline. If it is still present, -- * we acquire the lock on that fence and serialise with the interrupt -- * handler, in the process removing it from any future interrupt -- * callback. A will then wait on C before executing (if present). -- * -- * As B is second, it sees A as the previous fence and so waits for -- * it to complete its transition and takes over the occupancy for -- * itself -- remembering that it needs to wait on A before executing. -+ * Both A and B have got a reference to C or NULL, depending on the -+ * timing of the interrupt handler. Let's assume that if A has got C -+ * then it has locked C first (before B). - * - * Note the strong ordering of the timeline also provides consistent - * nesting rules for the fence->lock; the inner lock is always the - * older lock. - */ - spin_lock_irqsave(fence->lock, flags); -- prev = xchg(__active_fence_slot(active), fence); -- if (prev) { -- GEM_BUG_ON(prev == fence); -+ if (prev) - spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING); -+ -+ /* -+ * A does the cmpxchg first, and so it sees C or NULL, as before, or -+ * something else, depending on the timing of other threads and/or -+ * interrupt handler. If not the same as before then A unlocks C if -+ * applicable and retries, starting from an attempt to get a new -+ * active->fence. Meanwhile, B follows the same path as A. -+ * Once A succeeds with cmpxch, B fails again, retires, gets A from -+ * active->fence, locks it as soon as A completes, and possibly -+ * succeeds with cmpxchg. -+ */ -+ while (cmpxchg(__active_fence_slot(active), prev, fence) != prev) { -+ if (prev) { -+ spin_unlock(prev->lock); -+ dma_fence_put(prev); -+ } -+ spin_unlock_irqrestore(fence->lock, flags); -+ -+ prev = i915_active_fence_get(active); -+ GEM_BUG_ON(prev == fence); -+ -+ spin_lock_irqsave(fence->lock, flags); -+ if (prev) -+ spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING); -+ } -+ -+ /* -+ * If prev is NULL then the previous fence must have been signaled -+ * and we know that we are first on the timeline. If it is still -+ * present then, having the lock on that fence already acquired, we -+ * serialise with the interrupt handler, in the process of removing it -+ * from any future interrupt callback. A will then wait on C before -+ * executing (if present). -+ * -+ * As B is second, it sees A as the previous fence and so waits for -+ * it to complete its transition and takes over the occupancy for -+ * itself -- remembering that it needs to wait on A before executing. -+ */ -+ if (prev) { - __list_del_entry(&active->cb.node); - spin_unlock(prev->lock); /* serialise with prev->cb_list */ - } -@@ -1077,11 +1122,7 @@ int i915_active_fence_set(struct i915_active_fence *active, - int err = 0; - - /* Must maintain timeline ordering wrt previous active requests */ -- rcu_read_lock(); - fence = __i915_active_fence_set(active, &rq->fence); -- if (fence) /* but the previous fence may not belong to that timeline! */ -- fence = dma_fence_get_rcu(fence); -- rcu_read_unlock(); - if (fence) { - err = i915_request_await_dma_fence(rq, fence); - dma_fence_put(fence); -diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c -index 62fad16a55e84..803cd2ad4deb5 100644 ---- a/drivers/gpu/drm/i915/i915_request.c -+++ b/drivers/gpu/drm/i915/i915_request.c -@@ -1647,6 +1647,11 @@ __i915_request_ensure_parallel_ordering(struct i915_request *rq, - - request_to_parent(rq)->parallel.last_rq = i915_request_get(rq); - -+ /* -+ * Users have to put a reference potentially got by -+ * __i915_active_fence_set() to the returned request -+ * when no longer needed -+ */ - return to_request(__i915_active_fence_set(&timeline->last_request, - &rq->fence)); - } -@@ -1693,6 +1698,10 @@ __i915_request_ensure_ordering(struct i915_request *rq, - 0); - } - -+ /* -+ * Users have to put the reference to prev potentially got -+ * by __i915_active_fence_set() when no longer needed -+ */ - return prev; - } - -@@ -1736,6 +1745,8 @@ __i915_request_add_to_timeline(struct i915_request *rq) - prev = __i915_request_ensure_ordering(rq, timeline); - else - prev = __i915_request_ensure_parallel_ordering(rq, timeline); -+ if (prev) -+ i915_request_put(prev); - - /* - * Make sure that no request gazumped us - if it was allocated after -diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c -index 5f26090b0c985..89585b31b985e 100644 ---- a/drivers/gpu/drm/imx/ipuv3-crtc.c -+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c -@@ -310,7 +310,7 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) - dev_warn(ipu_crtc->dev, "8-pixel align hactive %d -> %d\n", - sig_cfg.mode.hactive, new_hactive); - -- sig_cfg.mode.hfront_porch = new_hactive - sig_cfg.mode.hactive; -+ sig_cfg.mode.hfront_porch -= new_hactive - sig_cfg.mode.hactive; - sig_cfg.mode.hactive = new_hactive; - } - -diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c -index f7aeeee6f5266..db332de134f1c 100644 ---- a/drivers/gpu/drm/ttm/ttm_bo.c -+++ b/drivers/gpu/drm/ttm/ttm_bo.c -@@ -552,7 +552,8 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo, - - if (bo->pin_count) { - *locked = false; -- *busy = false; -+ if (busy) -+ *busy = false; - return false; - } - -diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -index d4d8bfee9febc..db33dc87f69ed 100644 ---- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -@@ -882,6 +882,12 @@ static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu, - { - int index; - -+ if (cmds->num == CMDQ_BATCH_ENTRIES - 1 && -+ (smmu->options & ARM_SMMU_OPT_CMDQ_FORCE_SYNC)) { -+ arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, true); -+ cmds->num = 0; -+ } -+ - if (cmds->num == CMDQ_BATCH_ENTRIES) { - arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, false); - cmds->num = 0; -@@ -3410,6 +3416,44 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) - return 0; - } - -+#define IIDR_IMPLEMENTER_ARM 0x43b -+#define IIDR_PRODUCTID_ARM_MMU_600 0x483 -+#define IIDR_PRODUCTID_ARM_MMU_700 0x487 -+ -+static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu) -+{ -+ u32 reg; -+ unsigned int implementer, productid, variant, revision; -+ -+ reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR); -+ implementer = FIELD_GET(IIDR_IMPLEMENTER, reg); -+ productid = FIELD_GET(IIDR_PRODUCTID, reg); -+ variant = FIELD_GET(IIDR_VARIANT, reg); -+ revision = FIELD_GET(IIDR_REVISION, reg); -+ -+ switch (implementer) { -+ case IIDR_IMPLEMENTER_ARM: -+ switch (productid) { -+ case IIDR_PRODUCTID_ARM_MMU_600: -+ /* Arm erratum 1076982 */ -+ if (variant == 0 && revision <= 2) -+ smmu->features &= ~ARM_SMMU_FEAT_SEV; -+ /* Arm erratum 1209401 */ -+ if (variant < 2) -+ smmu->features &= ~ARM_SMMU_FEAT_NESTING; -+ break; -+ case IIDR_PRODUCTID_ARM_MMU_700: -+ /* Arm erratum 2812531 */ -+ smmu->features &= ~ARM_SMMU_FEAT_BTM; -+ smmu->options |= ARM_SMMU_OPT_CMDQ_FORCE_SYNC; -+ /* Arm errata 2268618, 2812531 */ -+ smmu->features &= ~ARM_SMMU_FEAT_NESTING; -+ break; -+ } -+ break; -+ } -+} -+ - static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) - { - u32 reg; -@@ -3615,6 +3659,12 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) - - smmu->ias = max(smmu->ias, smmu->oas); - -+ if ((smmu->features & ARM_SMMU_FEAT_TRANS_S1) && -+ (smmu->features & ARM_SMMU_FEAT_TRANS_S2)) -+ smmu->features |= ARM_SMMU_FEAT_NESTING; -+ -+ arm_smmu_device_iidr_probe(smmu); -+ - if (arm_smmu_sva_supported(smmu)) - smmu->features |= ARM_SMMU_FEAT_SVA; - -diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h -index cd48590ada303..d0b207cae1071 100644 ---- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h -+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h -@@ -69,6 +69,12 @@ - #define IDR5_VAX GENMASK(11, 10) - #define IDR5_VAX_52_BIT 1 - -+#define ARM_SMMU_IIDR 0x18 -+#define IIDR_PRODUCTID GENMASK(31, 20) -+#define IIDR_VARIANT GENMASK(19, 16) -+#define IIDR_REVISION GENMASK(15, 12) -+#define IIDR_IMPLEMENTER GENMASK(11, 0) -+ - #define ARM_SMMU_CR0 0x20 - #define CR0_ATSCHK (1 << 4) - #define CR0_CMDQEN (1 << 3) -@@ -639,11 +645,13 @@ struct arm_smmu_device { - #define ARM_SMMU_FEAT_BTM (1 << 16) - #define ARM_SMMU_FEAT_SVA (1 << 17) - #define ARM_SMMU_FEAT_E2H (1 << 18) -+#define ARM_SMMU_FEAT_NESTING (1 << 19) - u32 features; - - #define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0) - #define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1) - #define ARM_SMMU_OPT_MSIPOLL (1 << 2) -+#define ARM_SMMU_OPT_CMDQ_FORCE_SYNC (1 << 3) - u32 options; - - struct arm_smmu_cmdq cmdq; -diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c -index c0331b2680108..fe391de1aba32 100644 ---- a/drivers/isdn/hardware/mISDN/hfcpci.c -+++ b/drivers/isdn/hardware/mISDN/hfcpci.c -@@ -839,7 +839,7 @@ hfcpci_fill_fifo(struct bchannel *bch) - *z1t = cpu_to_le16(new_z1); /* now send data */ - if (bch->tx_idx < bch->tx_skb->len) - return; -- dev_kfree_skb(bch->tx_skb); -+ dev_kfree_skb_any(bch->tx_skb); - if (get_next_bframe(bch)) - goto next_t_frame; - return; -@@ -895,7 +895,7 @@ hfcpci_fill_fifo(struct bchannel *bch) - } - bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */ - bz->f1 = new_f1; /* next frame */ -- dev_kfree_skb(bch->tx_skb); -+ dev_kfree_skb_any(bch->tx_skb); - get_next_bframe(bch); - } - -@@ -1119,7 +1119,7 @@ tx_birq(struct bchannel *bch) - if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) - hfcpci_fill_fifo(bch); - else { -- dev_kfree_skb(bch->tx_skb); -+ dev_kfree_skb_any(bch->tx_skb); - if (get_next_bframe(bch)) - hfcpci_fill_fifo(bch); - } -@@ -2277,7 +2277,7 @@ _hfcpci_softirq(struct device *dev, void *unused) - return 0; - - if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { -- spin_lock(&hc->lock); -+ spin_lock_irq(&hc->lock); - bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); - if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ - main_rec_hfcpci(bch); -@@ -2288,7 +2288,7 @@ _hfcpci_softirq(struct device *dev, void *unused) - main_rec_hfcpci(bch); - tx_birq(bch); - } -- spin_unlock(&hc->lock); -+ spin_unlock_irq(&hc->lock); - } - return 0; - } -diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c -index b3cc427100a22..636e65328bb32 100644 ---- a/drivers/mtd/nand/raw/fsl_upm.c -+++ b/drivers/mtd/nand/raw/fsl_upm.c -@@ -135,7 +135,7 @@ static int fun_exec_op(struct nand_chip *chip, const struct nand_operation *op, - unsigned int i; - int ret; - -- if (op->cs > NAND_MAX_CHIPS) -+ if (op->cs >= NAND_MAX_CHIPS) - return -EINVAL; - - if (check_only) -diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c -index 029a2a302aa65..ac4947f720478 100644 ---- a/drivers/mtd/nand/raw/meson_nand.c -+++ b/drivers/mtd/nand/raw/meson_nand.c -@@ -1184,7 +1184,6 @@ static int meson_nand_attach_chip(struct nand_chip *nand) - struct meson_nfc *nfc = nand_get_controller_data(nand); - struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); - struct mtd_info *mtd = nand_to_mtd(nand); -- int nsectors = mtd->writesize / 1024; - int ret; - - if (!mtd->name) { -@@ -1202,7 +1201,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand) - nand->options |= NAND_NO_SUBPAGE_WRITE; - - ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, -- mtd->oobsize - 2 * nsectors); -+ mtd->oobsize - 2); - if (ret) { - dev_err(nfc->dev, "failed to ECC init\n"); - return -EINVAL; -diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c -index 4796a48e1012a..22d37fc37e98a 100644 ---- a/drivers/mtd/nand/raw/omap_elm.c -+++ b/drivers/mtd/nand/raw/omap_elm.c -@@ -177,17 +177,17 @@ static void elm_load_syndrome(struct elm_info *info, - switch (info->bch_type) { - case BCH8_ECC: - /* syndrome fragment 0 = ecc[9-12B] */ -- val = cpu_to_be32(*(u32 *) &ecc[9]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[9]); - elm_write_reg(info, offset, val); - - /* syndrome fragment 1 = ecc[5-8B] */ - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[5]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[5]); - elm_write_reg(info, offset, val); - - /* syndrome fragment 2 = ecc[1-4B] */ - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[1]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[1]); - elm_write_reg(info, offset, val); - - /* syndrome fragment 3 = ecc[0B] */ -@@ -197,35 +197,35 @@ static void elm_load_syndrome(struct elm_info *info, - break; - case BCH4_ECC: - /* syndrome fragment 0 = ecc[20-52b] bits */ -- val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) | -+ val = ((__force u32)cpu_to_be32(*(u32 *)&ecc[3]) >> 4) | - ((ecc[2] & 0xf) << 28); - elm_write_reg(info, offset, val); - - /* syndrome fragment 1 = ecc[0-20b] bits */ - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12; -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 12; - elm_write_reg(info, offset, val); - break; - case BCH16_ECC: -- val = cpu_to_be32(*(u32 *) &ecc[22]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[22]); - elm_write_reg(info, offset, val); - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[18]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[18]); - elm_write_reg(info, offset, val); - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[14]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[14]); - elm_write_reg(info, offset, val); - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[10]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[10]); - elm_write_reg(info, offset, val); - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[6]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[6]); - elm_write_reg(info, offset, val); - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[2]); -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[2]); - elm_write_reg(info, offset, val); - offset += 4; -- val = cpu_to_be32(*(u32 *) &ecc[0]) >> 16; -+ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 16; - elm_write_reg(info, offset, val); - break; - default: -diff --git a/drivers/mtd/nand/raw/rockchip-nand-controller.c b/drivers/mtd/nand/raw/rockchip-nand-controller.c -index f133985cc053a..c9c4e9ffcae18 100644 ---- a/drivers/mtd/nand/raw/rockchip-nand-controller.c -+++ b/drivers/mtd/nand/raw/rockchip-nand-controller.c -@@ -562,9 +562,10 @@ static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf, - * BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3 - * - * The rk_nfc_ooblayout_free() function already has reserved -- * these 4 bytes with: -+ * these 4 bytes together with 2 bytes for BBM -+ * by reducing it's length: - * -- * oob_region->offset = NFC_SYS_DATA_SIZE + 2; -+ * oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2; - */ - if (!i) - memcpy(rk_nfc_oob_ptr(chip, i), -@@ -597,7 +598,7 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, - int pages_per_blk = mtd->erasesize / mtd->writesize; - int ret = 0, i, boot_rom_mode = 0; - dma_addr_t dma_data, dma_oob; -- u32 reg; -+ u32 tmp; - u8 *oob; - - nand_prog_page_begin_op(chip, page, 0, NULL, 0); -@@ -624,6 +625,13 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, - * - * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ... - * -+ * The code here just swaps the first 4 bytes with the last -+ * 4 bytes without losing any data. -+ * -+ * The chip->oob_poi data layout: -+ * -+ * BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3 -+ * - * Configure the ECC algorithm supported by the boot ROM. - */ - if ((page < (pages_per_blk * rknand->boot_blks)) && -@@ -634,21 +642,17 @@ static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf, - } - - for (i = 0; i < ecc->steps; i++) { -- if (!i) { -- reg = 0xFFFFFFFF; -- } else { -+ if (!i) -+ oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE; -+ else - oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; -- reg = oob[0] | oob[1] << 8 | oob[2] << 16 | -- oob[3] << 24; -- } - -- if (!i && boot_rom_mode) -- reg = (page & (pages_per_blk - 1)) * 4; -+ tmp = oob[0] | oob[1] << 8 | oob[2] << 16 | oob[3] << 24; - - if (nfc->cfg->type == NFC_V9) -- nfc->oob_buf[i] = reg; -+ nfc->oob_buf[i] = tmp; - else -- nfc->oob_buf[i * (oob_step / 4)] = reg; -+ nfc->oob_buf[i * (oob_step / 4)] = tmp; - } - - dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf, -@@ -811,12 +815,17 @@ static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on, - goto timeout_err; - } - -- for (i = 1; i < ecc->steps; i++) { -- oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; -+ for (i = 0; i < ecc->steps; i++) { -+ if (!i) -+ oob = chip->oob_poi + (ecc->steps - 1) * NFC_SYS_DATA_SIZE; -+ else -+ oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE; -+ - if (nfc->cfg->type == NFC_V9) - tmp = nfc->oob_buf[i]; - else - tmp = nfc->oob_buf[i * (oob_step / 4)]; -+ - *oob++ = (u8)tmp; - *oob++ = (u8)(tmp >> 8); - *oob++ = (u8)(tmp >> 16); -@@ -933,12 +942,8 @@ static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section, - if (section) - return -ERANGE; - -- /* -- * The beginning of the OOB area stores the reserved data for the NFC, -- * the size of the reserved data is NFC_SYS_DATA_SIZE bytes. -- */ - oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2; -- oob_region->offset = NFC_SYS_DATA_SIZE + 2; -+ oob_region->offset = 2; - - return 0; - } -diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c -index 7380b1ebaccd5..a80427c131216 100644 ---- a/drivers/mtd/nand/spi/toshiba.c -+++ b/drivers/mtd/nand/spi/toshiba.c -@@ -73,7 +73,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, - { - struct nand_device *nand = spinand_to_nand(spinand); - u8 mbf = 0; -- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); -+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf); - - switch (status & STATUS_ECC_MASK) { - case STATUS_ECC_NO_BITFLIPS: -@@ -92,7 +92,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, - if (spi_mem_exec_op(spinand->spimem, &op)) - return nanddev_get_ecc_conf(nand)->strength; - -- mbf >>= 4; -+ mbf = *(spinand->scratchbuf) >> 4; - - if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) - return nanddev_get_ecc_conf(nand)->strength; -diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c -index cde253d27bd08..72374b066f64a 100644 ---- a/drivers/net/dsa/bcm_sf2.c -+++ b/drivers/net/dsa/bcm_sf2.c -@@ -1436,7 +1436,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) - if (IS_ERR(priv->clk)) - return PTR_ERR(priv->clk); - -- clk_prepare_enable(priv->clk); -+ ret = clk_prepare_enable(priv->clk); -+ if (ret) -+ return ret; - - priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv"); - if (IS_ERR(priv->clk_mdiv)) { -@@ -1444,7 +1446,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) - goto out_clk; - } - -- clk_prepare_enable(priv->clk_mdiv); -+ ret = clk_prepare_enable(priv->clk_mdiv); -+ if (ret) -+ goto out_clk; - - ret = bcm_sf2_sw_rst(priv); - if (ret) { -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -index 6469fb8a42a89..969db3c45d176 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -@@ -721,17 +721,24 @@ next_tx_int: - - static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping, - struct bnxt_rx_ring_info *rxr, -+ unsigned int *offset, - gfp_t gfp) - { - struct device *dev = &bp->pdev->dev; - struct page *page; - -- page = page_pool_dev_alloc_pages(rxr->page_pool); -+ if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) { -+ page = page_pool_dev_alloc_frag(rxr->page_pool, offset, -+ BNXT_RX_PAGE_SIZE); -+ } else { -+ page = page_pool_dev_alloc_pages(rxr->page_pool); -+ *offset = 0; -+ } - if (!page) - return NULL; - -- *mapping = dma_map_page_attrs(dev, page, 0, PAGE_SIZE, bp->rx_dir, -- DMA_ATTR_WEAK_ORDERING); -+ *mapping = dma_map_page_attrs(dev, page, *offset, BNXT_RX_PAGE_SIZE, -+ bp->rx_dir, DMA_ATTR_WEAK_ORDERING); - if (dma_mapping_error(dev, *mapping)) { - page_pool_recycle_direct(rxr->page_pool, page); - return NULL; -@@ -771,15 +778,16 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, - dma_addr_t mapping; - - if (BNXT_RX_PAGE_MODE(bp)) { -+ unsigned int offset; - struct page *page = -- __bnxt_alloc_rx_page(bp, &mapping, rxr, gfp); -+ __bnxt_alloc_rx_page(bp, &mapping, rxr, &offset, gfp); - - if (!page) - return -ENOMEM; - - mapping += bp->rx_dma_offset; - rx_buf->data = page; -- rx_buf->data_ptr = page_address(page) + bp->rx_offset; -+ rx_buf->data_ptr = page_address(page) + offset + bp->rx_offset; - } else { - u8 *data = __bnxt_alloc_rx_frag(bp, &mapping, gfp); - -@@ -839,7 +847,7 @@ static inline int bnxt_alloc_rx_page(struct bnxt *bp, - unsigned int offset = 0; - - if (BNXT_RX_PAGE_MODE(bp)) { -- page = __bnxt_alloc_rx_page(bp, &mapping, rxr, gfp); -+ page = __bnxt_alloc_rx_page(bp, &mapping, rxr, &offset, gfp); - - if (!page) - return -ENOMEM; -@@ -986,15 +994,15 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp, - return NULL; - } - dma_addr -= bp->rx_dma_offset; -- dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir, -- DMA_ATTR_WEAK_ORDERING); -- skb = build_skb(page_address(page), PAGE_SIZE); -+ dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, BNXT_RX_PAGE_SIZE, -+ bp->rx_dir, DMA_ATTR_WEAK_ORDERING); -+ skb = build_skb(data_ptr - bp->rx_offset, BNXT_RX_PAGE_SIZE); - if (!skb) { - page_pool_recycle_direct(rxr->page_pool, page); - return NULL; - } - skb_mark_for_recycle(skb); -- skb_reserve(skb, bp->rx_dma_offset); -+ skb_reserve(skb, bp->rx_offset); - __skb_put(skb, len); - - return skb; -@@ -1020,8 +1028,8 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp, - return NULL; - } - dma_addr -= bp->rx_dma_offset; -- dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir, -- DMA_ATTR_WEAK_ORDERING); -+ dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, BNXT_RX_PAGE_SIZE, -+ bp->rx_dir, DMA_ATTR_WEAK_ORDERING); - - if (unlikely(!payload)) - payload = eth_get_headlen(bp->dev, data_ptr, len); -@@ -1034,7 +1042,7 @@ static struct sk_buff *bnxt_rx_page_skb(struct bnxt *bp, - - skb_mark_for_recycle(skb); - off = (void *)data_ptr - page_address(page); -- skb_add_rx_frag(skb, 0, page, off, len, PAGE_SIZE); -+ skb_add_rx_frag(skb, 0, page, off, len, BNXT_RX_PAGE_SIZE); - memcpy(skb->data - NET_IP_ALIGN, data_ptr - NET_IP_ALIGN, - payload + NET_IP_ALIGN); - -@@ -1169,7 +1177,7 @@ static struct sk_buff *bnxt_rx_agg_pages_skb(struct bnxt *bp, - - skb->data_len += total_frag_len; - skb->len += total_frag_len; -- skb->truesize += PAGE_SIZE * agg_bufs; -+ skb->truesize += BNXT_RX_PAGE_SIZE * agg_bufs; - return skb; - } - -@@ -2972,8 +2980,8 @@ skip_rx_tpa_free: - rx_buf->data = NULL; - if (BNXT_RX_PAGE_MODE(bp)) { - mapping -= bp->rx_dma_offset; -- dma_unmap_page_attrs(&pdev->dev, mapping, PAGE_SIZE, -- bp->rx_dir, -+ dma_unmap_page_attrs(&pdev->dev, mapping, -+ BNXT_RX_PAGE_SIZE, bp->rx_dir, - DMA_ATTR_WEAK_ORDERING); - page_pool_recycle_direct(rxr->page_pool, data); - } else { -@@ -3241,6 +3249,8 @@ static int bnxt_alloc_rx_page_pool(struct bnxt *bp, - pp.nid = dev_to_node(&bp->pdev->dev); - pp.dev = &bp->pdev->dev; - pp.dma_dir = DMA_BIDIRECTIONAL; -+ if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) -+ pp.flags |= PP_FLAG_PAGE_FRAG; - - rxr->page_pool = page_pool_create(&pp); - if (IS_ERR(rxr->page_pool)) { -@@ -4017,26 +4027,29 @@ void bnxt_set_ring_params(struct bnxt *bp) - */ - int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) - { -+ struct net_device *dev = bp->dev; -+ - if (page_mode) { - bp->flags &= ~BNXT_FLAG_AGG_RINGS; - bp->flags |= BNXT_FLAG_RX_PAGE_MODE; - -- if (bp->dev->mtu > BNXT_MAX_PAGE_MODE_MTU) { -+ if (bp->xdp_prog->aux->xdp_has_frags) -+ dev->max_mtu = min_t(u16, bp->max_mtu, BNXT_MAX_MTU); -+ else -+ dev->max_mtu = -+ min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU); -+ if (dev->mtu > BNXT_MAX_PAGE_MODE_MTU) { - bp->flags |= BNXT_FLAG_JUMBO; - bp->rx_skb_func = bnxt_rx_multi_page_skb; -- bp->dev->max_mtu = -- min_t(u16, bp->max_mtu, BNXT_MAX_MTU); - } else { - bp->flags |= BNXT_FLAG_NO_AGG_RINGS; - bp->rx_skb_func = bnxt_rx_page_skb; -- bp->dev->max_mtu = -- min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU); - } - bp->rx_dir = DMA_BIDIRECTIONAL; - /* Disable LRO or GRO_HW */ -- netdev_update_features(bp->dev); -+ netdev_update_features(dev); - } else { -- bp->dev->max_mtu = bp->max_mtu; -+ dev->max_mtu = bp->max_mtu; - bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE; - bp->rx_dir = DMA_FROM_DEVICE; - bp->rx_skb_func = bnxt_rx_skb; -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c -index 36d5202c0aeec..aa56db138d6b5 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c -@@ -180,8 +180,8 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, - u16 cons, u8 *data_ptr, unsigned int len, - struct xdp_buff *xdp) - { -+ u32 buflen = BNXT_RX_PAGE_SIZE; - struct bnxt_sw_rx_bd *rx_buf; -- u32 buflen = PAGE_SIZE; - struct pci_dev *pdev; - dma_addr_t mapping; - u32 offset; -@@ -297,7 +297,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, - rx_buf = &rxr->rx_buf_ring[cons]; - mapping = rx_buf->mapping - bp->rx_dma_offset; - dma_unmap_page_attrs(&pdev->dev, mapping, -- PAGE_SIZE, bp->rx_dir, -+ BNXT_RX_PAGE_SIZE, bp->rx_dir, - DMA_ATTR_WEAK_ORDERING); - - /* if we are unable to allocate a new buffer, abort and reuse */ -@@ -478,7 +478,7 @@ bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags, - } - xdp_update_skb_shared_info(skb, num_frags, - sinfo->xdp_frags_size, -- PAGE_SIZE * sinfo->nr_frags, -+ BNXT_RX_PAGE_SIZE * sinfo->nr_frags, - xdp_buff_is_frag_pfmemalloc(xdp)); - return skb; - } -diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c -index 8f77088900e94..a771e597795d3 100644 ---- a/drivers/net/ethernet/intel/ice/ice_main.c -+++ b/drivers/net/ethernet/intel/ice/ice_main.c -@@ -8777,6 +8777,7 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type, - { - struct ice_netdev_priv *np = netdev_priv(netdev); - struct ice_pf *pf = np->vsi->back; -+ bool locked = false; - int err; - - switch (type) { -@@ -8786,10 +8787,27 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type, - ice_setup_tc_block_cb, - np, np, true); - case TC_SETUP_QDISC_MQPRIO: -+ if (pf->adev) { -+ mutex_lock(&pf->adev_mutex); -+ device_lock(&pf->adev->dev); -+ locked = true; -+ if (pf->adev->dev.driver) { -+ netdev_err(netdev, "Cannot change qdisc when RDMA is active\n"); -+ err = -EBUSY; -+ goto adev_unlock; -+ } -+ } -+ - /* setup traffic classifier for receive side */ - mutex_lock(&pf->tc_mutex); - err = ice_setup_tc_mqprio_qdisc(netdev, type_data); - mutex_unlock(&pf->tc_mutex); -+ -+adev_unlock: -+ if (locked) { -+ device_unlock(&pf->adev->dev); -+ mutex_unlock(&pf->adev_mutex); -+ } - return err; - default: - return -EOPNOTSUPP; -diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c -index 2b9335cb4bb3a..8537578e1cf1d 100644 ---- a/drivers/net/ethernet/korina.c -+++ b/drivers/net/ethernet/korina.c -@@ -1302,11 +1302,10 @@ static int korina_probe(struct platform_device *pdev) - else if (of_get_ethdev_address(pdev->dev.of_node, dev) < 0) - eth_hw_addr_random(dev); - -- clk = devm_clk_get_optional(&pdev->dev, "mdioclk"); -+ clk = devm_clk_get_optional_enabled(&pdev->dev, "mdioclk"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - if (clk) { -- clk_prepare_enable(clk); - lp->mii_clock_freq = clk_get_rate(clk); - } else { - lp->mii_clock_freq = 200000000; /* max possible input clk */ -diff --git a/drivers/net/ethernet/marvell/prestera/prestera_pci.c b/drivers/net/ethernet/marvell/prestera/prestera_pci.c -index 59470d99f5228..a37dbbda8de39 100644 ---- a/drivers/net/ethernet/marvell/prestera/prestera_pci.c -+++ b/drivers/net/ethernet/marvell/prestera/prestera_pci.c -@@ -702,7 +702,8 @@ pick_fw_ver: - - err = request_firmware_direct(&fw->bin, fw_path, fw->dev.dev); - if (err) { -- if (ver_maj == PRESTERA_SUPP_FW_MAJ_VER) { -+ if (ver_maj != PRESTERA_PREV_FW_MAJ_VER || -+ ver_min != PRESTERA_PREV_FW_MIN_VER) { - ver_maj = PRESTERA_PREV_FW_MAJ_VER; - ver_min = PRESTERA_PREV_FW_MIN_VER; - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c -index 6859f1c1a8319..c4a84f0a3b733 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c -@@ -58,7 +58,9 @@ static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x) - - trailer_len = alen + plen + 2; - -- pskb_trim(skb, skb->len - trailer_len); -+ ret = pskb_trim(skb, skb->len - trailer_len); -+ if (unlikely(ret)) -+ return ret; - if (skb->protocol == htons(ETH_P_IP)) { - ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len); - ip_send_check(ipv4hdr); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c -index 5b658a5588c64..6ecf0bf2366ad 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c -@@ -160,6 +160,7 @@ static int macsec_fs_tx_create_crypto_table_groups(struct mlx5e_flow_table *ft) - - if (!in) { - kfree(ft->g); -+ ft->g = NULL; - return -ENOMEM; - } - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c -index 0ae1865086ff1..dc0a0a27ac84a 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c -@@ -136,6 +136,16 @@ static void arfs_del_rules(struct mlx5e_flow_steering *fs); - - int mlx5e_arfs_disable(struct mlx5e_flow_steering *fs) - { -+ /* Moving to switchdev mode, fs->arfs is freed by mlx5e_nic_profile -+ * cleanup_rx callback and it is not recreated when -+ * mlx5e_uplink_rep_profile is loaded as mlx5e_create_flow_steering() -+ * is not called by the uplink_rep profile init_rx callback. Thus, if -+ * ntuple is set, moving to switchdev flow will enter this function -+ * with fs->arfs nullified. -+ */ -+ if (!mlx5e_fs_get_arfs(fs)) -+ return 0; -+ - arfs_del_rules(fs); - - return arfs_disable(fs); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -index 9bd1a93a512d4..bd895ef341a0b 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -@@ -912,7 +912,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv) - err = mlx5e_open_drop_rq(priv, &priv->drop_rq); - if (err) { - mlx5_core_err(mdev, "open drop rq failed, %d\n", err); -- return err; -+ goto err_rx_res_free; - } - - err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, 0, -@@ -946,6 +946,7 @@ err_destroy_rx_res: - mlx5e_rx_res_destroy(priv->rx_res); - err_close_drop_rq: - mlx5e_close_drop_rq(&priv->drop_rq); -+err_rx_res_free: - mlx5e_rx_res_free(priv->rx_res); - priv->rx_res = NULL; - err_free_fs: -@@ -1039,6 +1040,10 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv) - return err; - } - -+ err = mlx5e_rep_neigh_init(rpriv); -+ if (err) -+ goto err_neigh_init; -+ - if (rpriv->rep->vport == MLX5_VPORT_UPLINK) { - err = mlx5e_init_uplink_rep_tx(rpriv); - if (err) -@@ -1055,6 +1060,8 @@ err_ht_init: - if (rpriv->rep->vport == MLX5_VPORT_UPLINK) - mlx5e_cleanup_uplink_rep_tx(rpriv); - err_init_tx: -+ mlx5e_rep_neigh_cleanup(rpriv); -+err_neigh_init: - mlx5e_destroy_tises(priv); - return err; - } -@@ -1068,22 +1075,17 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv) - if (rpriv->rep->vport == MLX5_VPORT_UPLINK) - mlx5e_cleanup_uplink_rep_tx(rpriv); - -+ mlx5e_rep_neigh_cleanup(rpriv); - mlx5e_destroy_tises(priv); - } - - static void mlx5e_rep_enable(struct mlx5e_priv *priv) - { -- struct mlx5e_rep_priv *rpriv = priv->ppriv; -- - mlx5e_set_netdev_mtu_boundaries(priv); -- mlx5e_rep_neigh_init(rpriv); - } - - static void mlx5e_rep_disable(struct mlx5e_priv *priv) - { -- struct mlx5e_rep_priv *rpriv = priv->ppriv; -- -- mlx5e_rep_neigh_cleanup(rpriv); - } - - static int mlx5e_update_rep_rx(struct mlx5e_priv *priv) -@@ -1118,7 +1120,6 @@ static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event - - static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) - { -- struct mlx5e_rep_priv *rpriv = priv->ppriv; - struct net_device *netdev = priv->netdev; - struct mlx5_core_dev *mdev = priv->mdev; - u16 max_mtu; -@@ -1138,7 +1139,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) - mlx5_notifier_register(mdev, &priv->events_nb); - mlx5e_dcbnl_initialize(priv); - mlx5e_dcbnl_init_app(priv); -- mlx5e_rep_neigh_init(rpriv); - mlx5e_rep_bridge_init(priv); - - netdev->wanted_features |= NETIF_F_HW_TC; -@@ -1153,7 +1153,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) - - static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv) - { -- struct mlx5e_rep_priv *rpriv = priv->ppriv; - struct mlx5_core_dev *mdev = priv->mdev; - - rtnl_lock(); -@@ -1163,7 +1162,6 @@ static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv) - rtnl_unlock(); - - mlx5e_rep_bridge_cleanup(priv); -- mlx5e_rep_neigh_cleanup(rpriv); - mlx5e_dcbnl_delete_app(priv); - mlx5_notifier_unregister(mdev, &priv->events_nb); - mlx5e_rep_tc_disable(priv); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c -index a0242dc15741c..e112b5685b02b 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c -@@ -1061,7 +1061,7 @@ void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev) - mutex_lock(&table->lock); /* sync with create/destroy_async_eq */ - if (!mlx5_core_is_sf(dev)) - clear_rmap(dev); -- mlx5_irq_table_destroy(dev); -+ mlx5_irq_table_free_irqs(dev); - mutex_unlock(&table->lock); - } - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c -index d53749248fa09..e6674118bc428 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c -@@ -860,7 +860,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root, - struct fs_node *iter = list_entry(start, struct fs_node, list); - struct mlx5_flow_table *ft = NULL; - -- if (!root || root->type == FS_TYPE_PRIO_CHAINS) -+ if (!root) - return NULL; - - list_for_each_advance_continue(iter, &root->children, reverse) { -@@ -876,20 +876,42 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root, - return ft; - } - --/* If reverse is false then return the first flow table in next priority of -- * prio in the tree, else return the last flow table in the previous priority -- * of prio in the tree. -+static struct fs_node *find_prio_chains_parent(struct fs_node *parent, -+ struct fs_node **child) -+{ -+ struct fs_node *node = NULL; -+ -+ while (parent && parent->type != FS_TYPE_PRIO_CHAINS) { -+ node = parent; -+ parent = parent->parent; -+ } -+ -+ if (child) -+ *child = node; -+ -+ return parent; -+} -+ -+/* If reverse is false then return the first flow table next to the passed node -+ * in the tree, else return the last flow table before the node in the tree. -+ * If skip is true, skip the flow tables in the same prio_chains prio. - */ --static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool reverse) -+static struct mlx5_flow_table *find_closest_ft(struct fs_node *node, bool reverse, -+ bool skip) - { -+ struct fs_node *prio_chains_parent = NULL; - struct mlx5_flow_table *ft = NULL; - struct fs_node *curr_node; - struct fs_node *parent; - -- parent = prio->node.parent; -- curr_node = &prio->node; -+ if (skip) -+ prio_chains_parent = find_prio_chains_parent(node, NULL); -+ parent = node->parent; -+ curr_node = node; - while (!ft && parent) { -- ft = find_closest_ft_recursive(parent, &curr_node->list, reverse); -+ if (parent != prio_chains_parent) -+ ft = find_closest_ft_recursive(parent, &curr_node->list, -+ reverse); - curr_node = parent; - parent = curr_node->parent; - } -@@ -897,15 +919,15 @@ static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool revers - } - - /* Assuming all the tree is locked by mutex chain lock */ --static struct mlx5_flow_table *find_next_chained_ft(struct fs_prio *prio) -+static struct mlx5_flow_table *find_next_chained_ft(struct fs_node *node) - { -- return find_closest_ft(prio, false); -+ return find_closest_ft(node, false, true); - } - - /* Assuming all the tree is locked by mutex chain lock */ --static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio) -+static struct mlx5_flow_table *find_prev_chained_ft(struct fs_node *node) - { -- return find_closest_ft(prio, true); -+ return find_closest_ft(node, true, true); - } - - static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft, -@@ -917,7 +939,7 @@ static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft, - next_ns = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS; - fs_get_obj(prio, next_ns ? ft->ns->node.parent : ft->node.parent); - -- return find_next_chained_ft(prio); -+ return find_next_chained_ft(&prio->node); - } - - static int connect_fts_in_prio(struct mlx5_core_dev *dev, -@@ -941,21 +963,55 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev, - return 0; - } - -+static struct mlx5_flow_table *find_closet_ft_prio_chains(struct fs_node *node, -+ struct fs_node *parent, -+ struct fs_node **child, -+ bool reverse) -+{ -+ struct mlx5_flow_table *ft; -+ -+ ft = find_closest_ft(node, reverse, false); -+ -+ if (ft && parent == find_prio_chains_parent(&ft->node, child)) -+ return ft; -+ -+ return NULL; -+} -+ - /* Connect flow tables from previous priority of prio to ft */ - static int connect_prev_fts(struct mlx5_core_dev *dev, - struct mlx5_flow_table *ft, - struct fs_prio *prio) - { -+ struct fs_node *prio_parent, *parent = NULL, *child, *node; - struct mlx5_flow_table *prev_ft; -+ int err = 0; -+ -+ prio_parent = find_prio_chains_parent(&prio->node, &child); -+ -+ /* return directly if not under the first sub ns of prio_chains prio */ -+ if (prio_parent && !list_is_first(&child->list, &prio_parent->children)) -+ return 0; - -- prev_ft = find_prev_chained_ft(prio); -- if (prev_ft) { -+ prev_ft = find_prev_chained_ft(&prio->node); -+ while (prev_ft) { - struct fs_prio *prev_prio; - - fs_get_obj(prev_prio, prev_ft->node.parent); -- return connect_fts_in_prio(dev, prev_prio, ft); -+ err = connect_fts_in_prio(dev, prev_prio, ft); -+ if (err) -+ break; -+ -+ if (!parent) { -+ parent = find_prio_chains_parent(&prev_prio->node, &child); -+ if (!parent) -+ break; -+ } -+ -+ node = child; -+ prev_ft = find_closet_ft_prio_chains(node, parent, &child, true); - } -- return 0; -+ return err; - } - - static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio -@@ -1094,7 +1150,7 @@ static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table - if (err) - return err; - -- next_ft = first_ft ? first_ft : find_next_chained_ft(prio); -+ next_ft = first_ft ? first_ft : find_next_chained_ft(&prio->node); - err = connect_fwd_rules(dev, ft, next_ft); - if (err) - return err; -@@ -1169,7 +1225,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa - - tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table); - next_ft = unmanaged ? ft_attr->next_ft : -- find_next_chained_ft(fs_prio); -+ find_next_chained_ft(&fs_prio->node); - ft->def_miss_action = ns->def_miss_action; - ft->ns = ns; - err = root->cmds->create_flow_table(root, ft, ft_attr, next_ft); -@@ -2157,13 +2213,20 @@ EXPORT_SYMBOL(mlx5_del_flow_rules); - /* Assuming prio->node.children(flow tables) is sorted by level */ - static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft) - { -+ struct fs_node *prio_parent, *child; - struct fs_prio *prio; - - fs_get_obj(prio, ft->node.parent); - - if (!list_is_last(&ft->node.list, &prio->node.children)) - return list_next_entry(ft, node.list); -- return find_next_chained_ft(prio); -+ -+ prio_parent = find_prio_chains_parent(&prio->node, &child); -+ -+ if (prio_parent && list_is_first(&child->list, &prio_parent->children)) -+ return find_closest_ft(&prio->node, false, false); -+ -+ return find_next_chained_ft(&prio->node); - } - - static int update_root_ft_destroy(struct mlx5_flow_table *ft) -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_irq.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_irq.h -index 23cb63fa45886..2e728e4e81fac 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_irq.h -+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_irq.h -@@ -14,6 +14,7 @@ int mlx5_irq_table_init(struct mlx5_core_dev *dev); - void mlx5_irq_table_cleanup(struct mlx5_core_dev *dev); - int mlx5_irq_table_create(struct mlx5_core_dev *dev); - void mlx5_irq_table_destroy(struct mlx5_core_dev *dev); -+void mlx5_irq_table_free_irqs(struct mlx5_core_dev *dev); - int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table); - int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table); - struct mlx5_irq_table *mlx5_irq_table_get(struct mlx5_core_dev *dev); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -index 662f1d55e30e0..5e0f7d96aac51 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -@@ -591,6 +591,24 @@ static void irq_pools_destroy(struct mlx5_irq_table *table) - irq_pool_free(table->pf_pool); - } - -+static void mlx5_irq_pool_free_irqs(struct mlx5_irq_pool *pool) -+{ -+ struct mlx5_irq *irq; -+ unsigned long index; -+ -+ xa_for_each(&pool->irqs, index, irq) -+ free_irq(irq->irqn, &irq->nh); -+} -+ -+static void mlx5_irq_pools_free_irqs(struct mlx5_irq_table *table) -+{ -+ if (table->sf_ctrl_pool) { -+ mlx5_irq_pool_free_irqs(table->sf_comp_pool); -+ mlx5_irq_pool_free_irqs(table->sf_ctrl_pool); -+ } -+ mlx5_irq_pool_free_irqs(table->pf_pool); -+} -+ - /* irq_table API */ - - int mlx5_irq_table_init(struct mlx5_core_dev *dev) -@@ -670,6 +688,17 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev) - pci_free_irq_vectors(dev->pdev); - } - -+void mlx5_irq_table_free_irqs(struct mlx5_core_dev *dev) -+{ -+ struct mlx5_irq_table *table = dev->priv.irq_table; -+ -+ if (mlx5_core_is_sf(dev)) -+ return; -+ -+ mlx5_irq_pools_free_irqs(table); -+ pci_free_irq_vectors(dev->pdev); -+} -+ - int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table) - { - if (table->sf_comp_pool) -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c -index 84364691a3791..d7b1a230b59e8 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c -@@ -538,11 +538,12 @@ int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev, - - err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); - if (err) -- return err; -+ goto err_free_in; - - *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id); -- kvfree(in); - -+err_free_in: -+ kvfree(in); - return err; - } - -diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h -index f8682356d0cf4..94d4f9413ab7a 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h -+++ b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h -@@ -193,6 +193,22 @@ void qed_hw_remove(struct qed_dev *cdev); - */ - struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn); - -+/** -+ * qed_ptt_acquire_context(): Allocate a PTT window honoring the context -+ * atomicy. -+ * -+ * @p_hwfn: HW device data. -+ * @is_atomic: Hint from the caller - if the func can sleep or not. -+ * -+ * Context: The function should not sleep in case is_atomic == true. -+ * Return: struct qed_ptt. -+ * -+ * Should be called at the entry point to the driver -+ * (at the beginning of an exported function). -+ */ -+struct qed_ptt *qed_ptt_acquire_context(struct qed_hwfn *p_hwfn, -+ bool is_atomic); -+ - /** - * qed_ptt_release(): Release PTT Window. - * -diff --git a/drivers/net/ethernet/qlogic/qed/qed_fcoe.c b/drivers/net/ethernet/qlogic/qed/qed_fcoe.c -index 3764190b948eb..04602ac947087 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_fcoe.c -+++ b/drivers/net/ethernet/qlogic/qed/qed_fcoe.c -@@ -693,13 +693,14 @@ static void _qed_fcoe_get_pstats(struct qed_hwfn *p_hwfn, - } - - static int qed_fcoe_get_stats(struct qed_hwfn *p_hwfn, -- struct qed_fcoe_stats *p_stats) -+ struct qed_fcoe_stats *p_stats, -+ bool is_atomic) - { - struct qed_ptt *p_ptt; - - memset(p_stats, 0, sizeof(*p_stats)); - -- p_ptt = qed_ptt_acquire(p_hwfn); -+ p_ptt = qed_ptt_acquire_context(p_hwfn, is_atomic); - - if (!p_ptt) { - DP_ERR(p_hwfn, "Failed to acquire ptt\n"); -@@ -973,19 +974,27 @@ static int qed_fcoe_destroy_conn(struct qed_dev *cdev, - QED_SPQ_MODE_EBLOCK, NULL); - } - -+static int qed_fcoe_stats_context(struct qed_dev *cdev, -+ struct qed_fcoe_stats *stats, -+ bool is_atomic) -+{ -+ return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats, is_atomic); -+} -+ - static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats) - { -- return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats); -+ return qed_fcoe_stats_context(cdev, stats, false); - } - - void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, -- struct qed_mcp_fcoe_stats *stats) -+ struct qed_mcp_fcoe_stats *stats, -+ bool is_atomic) - { - struct qed_fcoe_stats proto_stats; - - /* Retrieve FW statistics */ - memset(&proto_stats, 0, sizeof(proto_stats)); -- if (qed_fcoe_stats(cdev, &proto_stats)) { -+ if (qed_fcoe_stats_context(cdev, &proto_stats, is_atomic)) { - DP_VERBOSE(cdev, QED_MSG_STORAGE, - "Failed to collect FCoE statistics\n"); - return; -diff --git a/drivers/net/ethernet/qlogic/qed/qed_fcoe.h b/drivers/net/ethernet/qlogic/qed/qed_fcoe.h -index 19c85adf4ceb1..214e8299ecb4e 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_fcoe.h -+++ b/drivers/net/ethernet/qlogic/qed/qed_fcoe.h -@@ -28,8 +28,20 @@ int qed_fcoe_alloc(struct qed_hwfn *p_hwfn); - void qed_fcoe_setup(struct qed_hwfn *p_hwfn); - - void qed_fcoe_free(struct qed_hwfn *p_hwfn); -+/** -+ * qed_get_protocol_stats_fcoe(): Fills provided statistics -+ * struct with statistics. -+ * -+ * @cdev: Qed dev pointer. -+ * @stats: Points to struct that will be filled with statistics. -+ * @is_atomic: Hint from the caller - if the func can sleep or not. -+ * -+ * Context: The function should not sleep in case is_atomic == true. -+ * Return: Void. -+ */ - void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, -- struct qed_mcp_fcoe_stats *stats); -+ struct qed_mcp_fcoe_stats *stats, -+ bool is_atomic); - #else /* CONFIG_QED_FCOE */ - static inline int qed_fcoe_alloc(struct qed_hwfn *p_hwfn) - { -@@ -40,7 +52,8 @@ static inline void qed_fcoe_setup(struct qed_hwfn *p_hwfn) {} - static inline void qed_fcoe_free(struct qed_hwfn *p_hwfn) {} - - static inline void qed_get_protocol_stats_fcoe(struct qed_dev *cdev, -- struct qed_mcp_fcoe_stats *stats) -+ struct qed_mcp_fcoe_stats *stats, -+ bool is_atomic) - { - } - #endif /* CONFIG_QED_FCOE */ -diff --git a/drivers/net/ethernet/qlogic/qed/qed_hw.c b/drivers/net/ethernet/qlogic/qed/qed_hw.c -index 554f30b0cfd5e..6263f847b6b92 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_hw.c -+++ b/drivers/net/ethernet/qlogic/qed/qed_hw.c -@@ -23,7 +23,10 @@ - #include "qed_reg_addr.h" - #include "qed_sriov.h" - --#define QED_BAR_ACQUIRE_TIMEOUT 1000 -+#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT 1000 -+#define QED_BAR_ACQUIRE_TIMEOUT_USLEEP 1000 -+#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT 100000 -+#define QED_BAR_ACQUIRE_TIMEOUT_UDELAY 10 - - /* Invalid values */ - #define QED_BAR_INVALID_OFFSET (cpu_to_le32(-1)) -@@ -84,12 +87,22 @@ void qed_ptt_pool_free(struct qed_hwfn *p_hwfn) - } - - struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn) -+{ -+ return qed_ptt_acquire_context(p_hwfn, false); -+} -+ -+struct qed_ptt *qed_ptt_acquire_context(struct qed_hwfn *p_hwfn, bool is_atomic) - { - struct qed_ptt *p_ptt; -- unsigned int i; -+ unsigned int i, count; -+ -+ if (is_atomic) -+ count = QED_BAR_ACQUIRE_TIMEOUT_UDELAY_CNT; -+ else -+ count = QED_BAR_ACQUIRE_TIMEOUT_USLEEP_CNT; - - /* Take the free PTT from the list */ -- for (i = 0; i < QED_BAR_ACQUIRE_TIMEOUT; i++) { -+ for (i = 0; i < count; i++) { - spin_lock_bh(&p_hwfn->p_ptt_pool->lock); - - if (!list_empty(&p_hwfn->p_ptt_pool->free_list)) { -@@ -105,7 +118,12 @@ struct qed_ptt *qed_ptt_acquire(struct qed_hwfn *p_hwfn) - } - - spin_unlock_bh(&p_hwfn->p_ptt_pool->lock); -- usleep_range(1000, 2000); -+ -+ if (is_atomic) -+ udelay(QED_BAR_ACQUIRE_TIMEOUT_UDELAY); -+ else -+ usleep_range(QED_BAR_ACQUIRE_TIMEOUT_USLEEP, -+ QED_BAR_ACQUIRE_TIMEOUT_USLEEP * 2); - } - - DP_NOTICE(p_hwfn, "PTT acquire timeout - failed to allocate PTT\n"); -diff --git a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c -index 511ab214eb9c8..980e7289b4814 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c -+++ b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c -@@ -999,13 +999,14 @@ static void _qed_iscsi_get_pstats(struct qed_hwfn *p_hwfn, - } - - static int qed_iscsi_get_stats(struct qed_hwfn *p_hwfn, -- struct qed_iscsi_stats *stats) -+ struct qed_iscsi_stats *stats, -+ bool is_atomic) - { - struct qed_ptt *p_ptt; - - memset(stats, 0, sizeof(*stats)); - -- p_ptt = qed_ptt_acquire(p_hwfn); -+ p_ptt = qed_ptt_acquire_context(p_hwfn, is_atomic); - if (!p_ptt) { - DP_ERR(p_hwfn, "Failed to acquire ptt\n"); - return -EAGAIN; -@@ -1336,9 +1337,16 @@ static int qed_iscsi_destroy_conn(struct qed_dev *cdev, - QED_SPQ_MODE_EBLOCK, NULL); - } - -+static int qed_iscsi_stats_context(struct qed_dev *cdev, -+ struct qed_iscsi_stats *stats, -+ bool is_atomic) -+{ -+ return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats, is_atomic); -+} -+ - static int qed_iscsi_stats(struct qed_dev *cdev, struct qed_iscsi_stats *stats) - { -- return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats); -+ return qed_iscsi_stats_context(cdev, stats, false); - } - - static int qed_iscsi_change_mac(struct qed_dev *cdev, -@@ -1358,13 +1366,14 @@ static int qed_iscsi_change_mac(struct qed_dev *cdev, - } - - void qed_get_protocol_stats_iscsi(struct qed_dev *cdev, -- struct qed_mcp_iscsi_stats *stats) -+ struct qed_mcp_iscsi_stats *stats, -+ bool is_atomic) - { - struct qed_iscsi_stats proto_stats; - - /* Retrieve FW statistics */ - memset(&proto_stats, 0, sizeof(proto_stats)); -- if (qed_iscsi_stats(cdev, &proto_stats)) { -+ if (qed_iscsi_stats_context(cdev, &proto_stats, is_atomic)) { - DP_VERBOSE(cdev, QED_MSG_STORAGE, - "Failed to collect ISCSI statistics\n"); - return; -diff --git a/drivers/net/ethernet/qlogic/qed/qed_iscsi.h b/drivers/net/ethernet/qlogic/qed/qed_iscsi.h -index dec2b00259d42..974cb8d26608c 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_iscsi.h -+++ b/drivers/net/ethernet/qlogic/qed/qed_iscsi.h -@@ -39,11 +39,14 @@ void qed_iscsi_free(struct qed_hwfn *p_hwfn); - * - * @cdev: Qed dev pointer. - * @stats: Points to struct that will be filled with statistics. -+ * @is_atomic: Hint from the caller - if the func can sleep or not. - * -+ * Context: The function should not sleep in case is_atomic == true. - * Return: Void. - */ - void qed_get_protocol_stats_iscsi(struct qed_dev *cdev, -- struct qed_mcp_iscsi_stats *stats); -+ struct qed_mcp_iscsi_stats *stats, -+ bool is_atomic); - #else /* IS_ENABLED(CONFIG_QED_ISCSI) */ - static inline int qed_iscsi_alloc(struct qed_hwfn *p_hwfn) - { -@@ -56,7 +59,8 @@ static inline void qed_iscsi_free(struct qed_hwfn *p_hwfn) {} - - static inline void - qed_get_protocol_stats_iscsi(struct qed_dev *cdev, -- struct qed_mcp_iscsi_stats *stats) {} -+ struct qed_mcp_iscsi_stats *stats, -+ bool is_atomic) {} - #endif /* IS_ENABLED(CONFIG_QED_ISCSI) */ - - #endif -diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c -index 7776d3bdd459a..970b9aabbc3d7 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_l2.c -+++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c -@@ -1863,7 +1863,8 @@ static void __qed_get_vport_stats(struct qed_hwfn *p_hwfn, - } - - static void _qed_get_vport_stats(struct qed_dev *cdev, -- struct qed_eth_stats *stats) -+ struct qed_eth_stats *stats, -+ bool is_atomic) - { - u8 fw_vport = 0; - int i; -@@ -1872,10 +1873,11 @@ static void _qed_get_vport_stats(struct qed_dev *cdev, - - for_each_hwfn(cdev, i) { - struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; -- struct qed_ptt *p_ptt = IS_PF(cdev) ? qed_ptt_acquire(p_hwfn) -- : NULL; -+ struct qed_ptt *p_ptt; - bool b_get_port_stats; - -+ p_ptt = IS_PF(cdev) ? qed_ptt_acquire_context(p_hwfn, is_atomic) -+ : NULL; - if (IS_PF(cdev)) { - /* The main vport index is relative first */ - if (qed_fw_vport(p_hwfn, 0, &fw_vport)) { -@@ -1900,6 +1902,13 @@ out: - } - - void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats) -+{ -+ qed_get_vport_stats_context(cdev, stats, false); -+} -+ -+void qed_get_vport_stats_context(struct qed_dev *cdev, -+ struct qed_eth_stats *stats, -+ bool is_atomic) - { - u32 i; - -@@ -1908,7 +1917,7 @@ void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats) - return; - } - -- _qed_get_vport_stats(cdev, stats); -+ _qed_get_vport_stats(cdev, stats, is_atomic); - - if (!cdev->reset_stats) - return; -@@ -1960,7 +1969,7 @@ void qed_reset_vport_stats(struct qed_dev *cdev) - if (!cdev->reset_stats) { - DP_INFO(cdev, "Reset stats not allocated\n"); - } else { -- _qed_get_vport_stats(cdev, cdev->reset_stats); -+ _qed_get_vport_stats(cdev, cdev->reset_stats, false); - cdev->reset_stats->common.link_change_count = 0; - } - } -diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.h b/drivers/net/ethernet/qlogic/qed/qed_l2.h -index a538cf478c14e..2d2f82c785ad2 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_l2.h -+++ b/drivers/net/ethernet/qlogic/qed/qed_l2.h -@@ -249,8 +249,32 @@ qed_sp_eth_rx_queues_update(struct qed_hwfn *p_hwfn, - enum spq_mode comp_mode, - struct qed_spq_comp_cb *p_comp_data); - -+/** -+ * qed_get_vport_stats(): Fills provided statistics -+ * struct with statistics. -+ * -+ * @cdev: Qed dev pointer. -+ * @stats: Points to struct that will be filled with statistics. -+ * -+ * Return: Void. -+ */ - void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats); - -+/** -+ * qed_get_vport_stats_context(): Fills provided statistics -+ * struct with statistics. -+ * -+ * @cdev: Qed dev pointer. -+ * @stats: Points to struct that will be filled with statistics. -+ * @is_atomic: Hint from the caller - if the func can sleep or not. -+ * -+ * Context: The function should not sleep in case is_atomic == true. -+ * Return: Void. -+ */ -+void qed_get_vport_stats_context(struct qed_dev *cdev, -+ struct qed_eth_stats *stats, -+ bool is_atomic); -+ - void qed_reset_vport_stats(struct qed_dev *cdev); - - /** -diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c -index c91898be7c030..25d9c254288b5 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_main.c -+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c -@@ -3101,7 +3101,7 @@ void qed_get_protocol_stats(struct qed_dev *cdev, - - switch (type) { - case QED_MCP_LAN_STATS: -- qed_get_vport_stats(cdev, ð_stats); -+ qed_get_vport_stats_context(cdev, ð_stats, true); - stats->lan_stats.ucast_rx_pkts = - eth_stats.common.rx_ucast_pkts; - stats->lan_stats.ucast_tx_pkts = -@@ -3109,10 +3109,10 @@ void qed_get_protocol_stats(struct qed_dev *cdev, - stats->lan_stats.fcs_err = -1; - break; - case QED_MCP_FCOE_STATS: -- qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats); -+ qed_get_protocol_stats_fcoe(cdev, &stats->fcoe_stats, true); - break; - case QED_MCP_ISCSI_STATS: -- qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats); -+ qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats, true); - break; - default: - DP_VERBOSE(cdev, QED_MSG_SP, -diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c -index 9b46579b5a103..b130e978366c1 100644 ---- a/drivers/net/ethernet/socionext/netsec.c -+++ b/drivers/net/ethernet/socionext/netsec.c -@@ -1851,6 +1851,17 @@ static int netsec_of_probe(struct platform_device *pdev, - return err; - } - -+ /* -+ * SynQuacer is physically configured with TX and RX delays -+ * but the standard firmware claimed otherwise for a long -+ * time, ignore it. -+ */ -+ if (of_machine_is_compatible("socionext,developer-box") && -+ priv->phy_interface != PHY_INTERFACE_MODE_RGMII_ID) { -+ dev_warn(&pdev->dev, "Outdated firmware reports incorrect PHY mode, overriding\n"); -+ priv->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; -+ } -+ - priv->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); - if (!priv->phy_np) { - dev_err(&pdev->dev, "missing required property 'phy-handle'\n"); -diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c -index 1066420d6a83a..6bf5e341c3c11 100644 ---- a/drivers/net/ethernet/xilinx/ll_temac_main.c -+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c -@@ -1568,12 +1568,16 @@ static int temac_probe(struct platform_device *pdev) - } - - /* Error handle returned DMA RX and TX interrupts */ -- if (lp->rx_irq < 0) -- return dev_err_probe(&pdev->dev, lp->rx_irq, -+ if (lp->rx_irq <= 0) { -+ rc = lp->rx_irq ?: -EINVAL; -+ return dev_err_probe(&pdev->dev, rc, - "could not get DMA RX irq\n"); -- if (lp->tx_irq < 0) -- return dev_err_probe(&pdev->dev, lp->tx_irq, -+ } -+ if (lp->tx_irq <= 0) { -+ rc = lp->tx_irq ?: -EINVAL; -+ return dev_err_probe(&pdev->dev, rc, - "could not get DMA TX irq\n"); -+ } - - if (temac_np) { - /* Retrieve the MAC address */ -diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c -index 510ff2dc8999a..cd81dd916c29e 100644 ---- a/drivers/net/ipa/ipa_table.c -+++ b/drivers/net/ipa/ipa_table.c -@@ -311,16 +311,15 @@ static int ipa_filter_reset(struct ipa *ipa, bool modem) - if (ret) - return ret; - -- ret = ipa_filter_reset_table(ipa, IPA_MEM_V4_FILTER_HASHED, modem); -- if (ret) -+ ret = ipa_filter_reset_table(ipa, IPA_MEM_V6_FILTER, modem); -+ if (ret || !ipa_table_hash_support(ipa)) - return ret; - -- ret = ipa_filter_reset_table(ipa, IPA_MEM_V6_FILTER, modem); -+ ret = ipa_filter_reset_table(ipa, IPA_MEM_V4_FILTER_HASHED, modem); - if (ret) - return ret; -- ret = ipa_filter_reset_table(ipa, IPA_MEM_V6_FILTER_HASHED, modem); - -- return ret; -+ return ipa_filter_reset_table(ipa, IPA_MEM_V6_FILTER_HASHED, modem); - } - - /* The AP routes and modem routes are each contiguous within the -@@ -329,11 +328,12 @@ static int ipa_filter_reset(struct ipa *ipa, bool modem) - * */ - static int ipa_route_reset(struct ipa *ipa, bool modem) - { -+ bool hash_support = ipa_table_hash_support(ipa); - struct gsi_trans *trans; - u16 first; - u16 count; - -- trans = ipa_cmd_trans_alloc(ipa, 4); -+ trans = ipa_cmd_trans_alloc(ipa, hash_support ? 4 : 2); - if (!trans) { - dev_err(&ipa->pdev->dev, - "no transaction for %s route reset\n", -@@ -350,12 +350,14 @@ static int ipa_route_reset(struct ipa *ipa, bool modem) - } - - ipa_table_reset_add(trans, false, first, count, IPA_MEM_V4_ROUTE); -- ipa_table_reset_add(trans, false, first, count, -- IPA_MEM_V4_ROUTE_HASHED); -- - ipa_table_reset_add(trans, false, first, count, IPA_MEM_V6_ROUTE); -- ipa_table_reset_add(trans, false, first, count, -- IPA_MEM_V6_ROUTE_HASHED); -+ -+ if (hash_support) { -+ ipa_table_reset_add(trans, false, first, count, -+ IPA_MEM_V4_ROUTE_HASHED); -+ ipa_table_reset_add(trans, false, first, count, -+ IPA_MEM_V6_ROUTE_HASHED); -+ } - - gsi_trans_commit_wait(trans); - -diff --git a/drivers/net/tap.c b/drivers/net/tap.c -index 3c468ef8f245f..8c010857e6d70 100644 ---- a/drivers/net/tap.c -+++ b/drivers/net/tap.c -@@ -533,7 +533,7 @@ static int tap_open(struct inode *inode, struct file *file) - q->sock.state = SS_CONNECTED; - q->sock.file = file; - q->sock.ops = &tap_socket_ops; -- sock_init_data_uid(&q->sock, &q->sk, inode->i_uid); -+ sock_init_data_uid(&q->sock, &q->sk, current_fsuid()); - q->sk.sk_write_space = tap_sock_write_space; - q->sk.sk_destruct = tap_sock_destruct; - q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP; -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index 7c8db8f6f661e..228f5f9ef1dde 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -3457,7 +3457,7 @@ static int tun_chr_open(struct inode *inode, struct file * file) - tfile->socket.file = file; - tfile->socket.ops = &tun_socket_ops; - -- sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid); -+ sock_init_data_uid(&tfile->socket, &tfile->sk, current_fsuid()); - - tfile->sk.sk_write_space = tun_sock_write_space; - tfile->sk.sk_sndbuf = INT_MAX; -diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c -index fb5f59d0d55d7..f07bfe56ec875 100644 ---- a/drivers/net/usb/cdc_ether.c -+++ b/drivers/net/usb/cdc_ether.c -@@ -618,9 +618,23 @@ static const struct usb_device_id products[] = { - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_DEVICE, - .idVendor = 0x04DD, -+ .idProduct = 0x8005, /* A-300 */ -+ ZAURUS_FAKE_INTERFACE, -+ .driver_info = 0, -+}, { -+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO -+ | USB_DEVICE_ID_MATCH_DEVICE, -+ .idVendor = 0x04DD, - .idProduct = 0x8006, /* B-500/SL-5600 */ - ZAURUS_MASTER_INTERFACE, - .driver_info = 0, -+}, { -+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO -+ | USB_DEVICE_ID_MATCH_DEVICE, -+ .idVendor = 0x04DD, -+ .idProduct = 0x8006, /* B-500/SL-5600 */ -+ ZAURUS_FAKE_INTERFACE, -+ .driver_info = 0, - }, { - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_DEVICE, -@@ -628,6 +642,13 @@ static const struct usb_device_id products[] = { - .idProduct = 0x8007, /* C-700 */ - ZAURUS_MASTER_INTERFACE, - .driver_info = 0, -+}, { -+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO -+ | USB_DEVICE_ID_MATCH_DEVICE, -+ .idVendor = 0x04DD, -+ .idProduct = 0x8007, /* C-700 */ -+ ZAURUS_FAKE_INTERFACE, -+ .driver_info = 0, - }, { - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_DEVICE, -diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c -index 64a9a80b23094..405e588f8a3a5 100644 ---- a/drivers/net/usb/usbnet.c -+++ b/drivers/net/usb/usbnet.c -@@ -1770,6 +1770,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) - } else if (!info->in || !info->out) - status = usbnet_get_endpoints (dev, udev); - else { -+ u8 ep_addrs[3] = { -+ info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0 -+ }; -+ - dev->in = usb_rcvbulkpipe (xdev, info->in); - dev->out = usb_sndbulkpipe (xdev, info->out); - if (!(info->flags & FLAG_NO_SETINT)) -@@ -1779,6 +1783,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) - else - status = 0; - -+ if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs)) -+ status = -EINVAL; - } - if (status >= 0 && dev->status) - status = init_status (dev, udev); -diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c -index 7984f2157d222..df3617c4c44e8 100644 ---- a/drivers/net/usb/zaurus.c -+++ b/drivers/net/usb/zaurus.c -@@ -289,9 +289,23 @@ static const struct usb_device_id products [] = { - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_DEVICE, - .idVendor = 0x04DD, -+ .idProduct = 0x8005, /* A-300 */ -+ ZAURUS_FAKE_INTERFACE, -+ .driver_info = (unsigned long)&bogus_mdlm_info, -+}, { -+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO -+ | USB_DEVICE_ID_MATCH_DEVICE, -+ .idVendor = 0x04DD, - .idProduct = 0x8006, /* B-500/SL-5600 */ - ZAURUS_MASTER_INTERFACE, - .driver_info = ZAURUS_PXA_INFO, -+}, { -+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO -+ | USB_DEVICE_ID_MATCH_DEVICE, -+ .idVendor = 0x04DD, -+ .idProduct = 0x8006, /* B-500/SL-5600 */ -+ ZAURUS_FAKE_INTERFACE, -+ .driver_info = (unsigned long)&bogus_mdlm_info, - }, { - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_DEVICE, -@@ -299,6 +313,13 @@ static const struct usb_device_id products [] = { - .idProduct = 0x8007, /* C-700 */ - ZAURUS_MASTER_INTERFACE, - .driver_info = ZAURUS_PXA_INFO, -+}, { -+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO -+ | USB_DEVICE_ID_MATCH_DEVICE, -+ .idVendor = 0x04DD, -+ .idProduct = 0x8007, /* C-700 */ -+ ZAURUS_FAKE_INTERFACE, -+ .driver_info = (unsigned long)&bogus_mdlm_info, - }, { - .match_flags = USB_DEVICE_ID_MATCH_INT_INFO - | USB_DEVICE_ID_MATCH_DEVICE, -diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c -index 6dbaaf95ee385..2092aa373ab32 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c -@@ -123,12 +123,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev) - case MT_EE_5GHZ: - dev->mphy.cap.has_5ghz = true; - break; -- case MT_EE_2GHZ: -- dev->mphy.cap.has_2ghz = true; -- break; - case MT_EE_DBDC: - dev->dbdc_support = true; - fallthrough; -+ case MT_EE_2GHZ: -+ dev->mphy.cap.has_2ghz = true; -+ break; - default: - dev->mphy.cap.has_2ghz = true; - dev->mphy.cap.has_5ghz = true; -diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h -index 1d195429753dd..613eab7297046 100644 ---- a/drivers/s390/net/qeth_core.h -+++ b/drivers/s390/net/qeth_core.h -@@ -716,7 +716,6 @@ struct qeth_card_info { - u16 chid; - u8 ids_valid:1; /* cssid,iid,chid */ - u8 dev_addr_is_registered:1; -- u8 open_when_online:1; - u8 promisc_mode:1; - u8 use_v1_blkt:1; - u8 is_vm_nic:1; -diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c -index 8bd9fd51208c9..ae4b6d24bc902 100644 ---- a/drivers/s390/net/qeth_core_main.c -+++ b/drivers/s390/net/qeth_core_main.c -@@ -5371,8 +5371,6 @@ int qeth_set_offline(struct qeth_card *card, const struct qeth_discipline *disc, - qeth_clear_ipacmd_list(card); - - rtnl_lock(); -- card->info.open_when_online = card->dev->flags & IFF_UP; -- dev_close(card->dev); - netif_device_detach(card->dev); - netif_carrier_off(card->dev); - rtnl_unlock(); -diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c -index c6ded3fdd715c..9ef2118fc7a2a 100644 ---- a/drivers/s390/net/qeth_l2_main.c -+++ b/drivers/s390/net/qeth_l2_main.c -@@ -2387,9 +2387,12 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok) - qeth_enable_hw_features(dev); - qeth_l2_enable_brport_features(card); - -- if (card->info.open_when_online) { -- card->info.open_when_online = 0; -- dev_open(dev, NULL); -+ if (netif_running(dev)) { -+ local_bh_disable(); -+ napi_schedule(&card->napi); -+ /* kick-start the NAPI softirq: */ -+ local_bh_enable(); -+ qeth_l2_set_rx_mode(dev); - } - rtnl_unlock(); - } -diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c -index d8487a10cd555..c0f30cefec102 100644 ---- a/drivers/s390/net/qeth_l3_main.c -+++ b/drivers/s390/net/qeth_l3_main.c -@@ -2017,9 +2017,11 @@ static int qeth_l3_set_online(struct qeth_card *card, bool carrier_ok) - netif_device_attach(dev); - qeth_enable_hw_features(dev); - -- if (card->info.open_when_online) { -- card->info.open_when_online = 0; -- dev_open(dev, NULL); -+ if (netif_running(dev)) { -+ local_bh_disable(); -+ napi_schedule(&card->napi); -+ /* kick-start the NAPI softirq: */ -+ local_bh_enable(); - } - rtnl_unlock(); - } -diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c -index 77917b3398709..a64def01d8249 100644 ---- a/drivers/s390/scsi/zfcp_fc.c -+++ b/drivers/s390/scsi/zfcp_fc.c -@@ -534,8 +534,7 @@ static void zfcp_fc_adisc_handler(void *data) - - /* re-init to undo drop from zfcp_fc_adisc() */ - port->d_id = ntoh24(adisc_resp->adisc_port_id); -- /* port is good, unblock rport without going through erp */ -- zfcp_scsi_schedule_rport_register(port); -+ /* port is still good, nothing to do */ - out: - atomic_andnot(ZFCP_STATUS_PORT_LINK_TEST, &port->status); - put_device(&port->dev); -@@ -595,9 +594,6 @@ void zfcp_fc_link_test_work(struct work_struct *work) - int retval; - - set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */ -- get_device(&port->dev); -- port->rport_task = RPORT_DEL; -- zfcp_scsi_rport_work(&port->rport_work); - - /* only issue one test command at one time per port */ - if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST) -diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c -index 5284f9a0b826e..54a1b8514f04b 100644 ---- a/drivers/scsi/storvsc_drv.c -+++ b/drivers/scsi/storvsc_drv.c -@@ -365,6 +365,7 @@ static void storvsc_on_channel_callback(void *context); - #define STORVSC_FC_MAX_LUNS_PER_TARGET 255 - #define STORVSC_FC_MAX_TARGETS 128 - #define STORVSC_FC_MAX_CHANNELS 8 -+#define STORVSC_FC_MAX_XFER_SIZE ((u32)(512 * 1024)) - - #define STORVSC_IDE_MAX_LUNS_PER_TARGET 64 - #define STORVSC_IDE_MAX_TARGETS 1 -@@ -2002,6 +2003,9 @@ static int storvsc_probe(struct hv_device *device, - * protecting it from any weird value. - */ - max_xfer_bytes = round_down(stor_device->max_transfer_bytes, HV_HYP_PAGE_SIZE); -+ if (is_fc) -+ max_xfer_bytes = min(max_xfer_bytes, STORVSC_FC_MAX_XFER_SIZE); -+ - /* max_hw_sectors_kb */ - host->max_sectors = max_xfer_bytes >> 9; - /* -diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c -index d93e8735ab1f9..d7aad5e8ee377 100644 ---- a/fs/btrfs/block-group.c -+++ b/fs/btrfs/block-group.c -@@ -494,12 +494,16 @@ static void fragment_free_space(struct btrfs_block_group *block_group) - * used yet since their free space will be released as soon as the transaction - * commits. - */ --u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end) -+int add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end, -+ u64 *total_added_ret) - { - struct btrfs_fs_info *info = block_group->fs_info; -- u64 extent_start, extent_end, size, total_added = 0; -+ u64 extent_start, extent_end, size; - int ret; - -+ if (total_added_ret) -+ *total_added_ret = 0; -+ - while (start < end) { - ret = find_first_extent_bit(&info->excluded_extents, start, - &extent_start, &extent_end, -@@ -512,10 +516,12 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end - start = extent_end + 1; - } else if (extent_start > start && extent_start < end) { - size = extent_start - start; -- total_added += size; - ret = btrfs_add_free_space_async_trimmed(block_group, - start, size); -- BUG_ON(ret); /* -ENOMEM or logic error */ -+ if (ret) -+ return ret; -+ if (total_added_ret) -+ *total_added_ret += size; - start = extent_end + 1; - } else { - break; -@@ -524,13 +530,15 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end - - if (start < end) { - size = end - start; -- total_added += size; - ret = btrfs_add_free_space_async_trimmed(block_group, start, - size); -- BUG_ON(ret); /* -ENOMEM or logic error */ -+ if (ret) -+ return ret; -+ if (total_added_ret) -+ *total_added_ret += size; - } - -- return total_added; -+ return 0; - } - - static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl) -@@ -637,8 +645,13 @@ next: - - if (key.type == BTRFS_EXTENT_ITEM_KEY || - key.type == BTRFS_METADATA_ITEM_KEY) { -- total_found += add_new_free_space(block_group, last, -- key.objectid); -+ u64 space_added; -+ -+ ret = add_new_free_space(block_group, last, key.objectid, -+ &space_added); -+ if (ret) -+ goto out; -+ total_found += space_added; - if (key.type == BTRFS_METADATA_ITEM_KEY) - last = key.objectid + - fs_info->nodesize; -@@ -653,11 +666,10 @@ next: - } - path->slots[0]++; - } -- ret = 0; -- -- total_found += add_new_free_space(block_group, last, -- block_group->start + block_group->length); - -+ ret = add_new_free_space(block_group, last, -+ block_group->start + block_group->length, -+ NULL); - out: - btrfs_free_path(path); - return ret; -@@ -2101,9 +2113,11 @@ static int read_one_block_group(struct btrfs_fs_info *info, - btrfs_free_excluded_extents(cache); - } else if (cache->used == 0) { - cache->cached = BTRFS_CACHE_FINISHED; -- add_new_free_space(cache, cache->start, -- cache->start + cache->length); -+ ret = add_new_free_space(cache, cache->start, -+ cache->start + cache->length, NULL); - btrfs_free_excluded_extents(cache); -+ if (ret) -+ goto error; - } - - ret = btrfs_add_block_group_cache(info, cache); -@@ -2529,9 +2543,12 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran - return ERR_PTR(ret); - } - -- add_new_free_space(cache, chunk_offset, chunk_offset + size); -- -+ ret = add_new_free_space(cache, chunk_offset, chunk_offset + size, NULL); - btrfs_free_excluded_extents(cache); -+ if (ret) { -+ btrfs_put_block_group(cache); -+ return ERR_PTR(ret); -+ } - - /* - * Ensure the corresponding space_info object is created and -diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h -index 8fb14b99a1d1f..0a3d386823583 100644 ---- a/fs/btrfs/block-group.h -+++ b/fs/btrfs/block-group.h -@@ -284,8 +284,8 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait); - void btrfs_put_caching_control(struct btrfs_caching_control *ctl); - struct btrfs_caching_control *btrfs_get_caching_control( - struct btrfs_block_group *cache); --u64 add_new_free_space(struct btrfs_block_group *block_group, -- u64 start, u64 end); -+int add_new_free_space(struct btrfs_block_group *block_group, -+ u64 start, u64 end, u64 *total_added_ret); - struct btrfs_trans_handle *btrfs_start_trans_remove_block_group( - struct btrfs_fs_info *fs_info, - const u64 chunk_offset); -diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c -index a07450f64abb1..a207db9322264 100644 ---- a/fs/btrfs/free-space-tree.c -+++ b/fs/btrfs/free-space-tree.c -@@ -1510,9 +1510,13 @@ static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl, - if (prev_bit == 0 && bit == 1) { - extent_start = offset; - } else if (prev_bit == 1 && bit == 0) { -- total_found += add_new_free_space(block_group, -- extent_start, -- offset); -+ u64 space_added; -+ -+ ret = add_new_free_space(block_group, extent_start, -+ offset, &space_added); -+ if (ret) -+ goto out; -+ total_found += space_added; - if (total_found > CACHING_CTL_WAKE_UP) { - total_found = 0; - wake_up(&caching_ctl->wait); -@@ -1524,8 +1528,9 @@ static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl, - } - } - if (prev_bit == 1) { -- total_found += add_new_free_space(block_group, extent_start, -- end); -+ ret = add_new_free_space(block_group, extent_start, end, NULL); -+ if (ret) -+ goto out; - extent_count++; - } - -@@ -1564,6 +1569,8 @@ static int load_free_space_extents(struct btrfs_caching_control *caching_ctl, - end = block_group->start + block_group->length; - - while (1) { -+ u64 space_added; -+ - ret = btrfs_next_item(root, path); - if (ret < 0) - goto out; -@@ -1578,8 +1585,11 @@ static int load_free_space_extents(struct btrfs_caching_control *caching_ctl, - ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY); - ASSERT(key.objectid < end && key.objectid + key.offset <= end); - -- total_found += add_new_free_space(block_group, key.objectid, -- key.objectid + key.offset); -+ ret = add_new_free_space(block_group, key.objectid, -+ key.objectid + key.offset, &space_added); -+ if (ret) -+ goto out; -+ total_found += space_added; - if (total_found > CACHING_CTL_WAKE_UP) { - total_found = 0; - wake_up(&caching_ctl->wait); -diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c -index 1989c8deea55a..dcabe2783edfe 100644 ---- a/fs/ceph/mds_client.c -+++ b/fs/ceph/mds_client.c -@@ -4758,7 +4758,7 @@ static void delayed_work(struct work_struct *work) - - dout("mdsc delayed_work\n"); - -- if (mdsc->stopping) -+ if (mdsc->stopping >= CEPH_MDSC_STOPPING_FLUSHED) - return; - - mutex_lock(&mdsc->mutex); -@@ -4937,7 +4937,7 @@ void send_flush_mdlog(struct ceph_mds_session *s) - void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) - { - dout("pre_umount\n"); -- mdsc->stopping = 1; -+ mdsc->stopping = CEPH_MDSC_STOPPING_BEGIN; - - ceph_mdsc_iterate_sessions(mdsc, send_flush_mdlog, true); - ceph_mdsc_iterate_sessions(mdsc, lock_unlock_session, false); -diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h -index 18b026b1ac63f..9a80658f41679 100644 ---- a/fs/ceph/mds_client.h -+++ b/fs/ceph/mds_client.h -@@ -380,6 +380,11 @@ struct cap_wait { - int want; - }; - -+enum { -+ CEPH_MDSC_STOPPING_BEGIN = 1, -+ CEPH_MDSC_STOPPING_FLUSHED = 2, -+}; -+ - /* - * mds client state - */ -diff --git a/fs/ceph/super.c b/fs/ceph/super.c -index 3fc48b43cab0a..a5f52013314d6 100644 ---- a/fs/ceph/super.c -+++ b/fs/ceph/super.c -@@ -1374,6 +1374,16 @@ static void ceph_kill_sb(struct super_block *s) - ceph_mdsc_pre_umount(fsc->mdsc); - flush_fs_workqueues(fsc); - -+ /* -+ * Though the kill_anon_super() will finally trigger the -+ * sync_filesystem() anyway, we still need to do it here -+ * and then bump the stage of shutdown to stop the work -+ * queue as earlier as possible. -+ */ -+ sync_filesystem(s); -+ -+ fsc->mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHED; -+ - kill_anon_super(s); - - fsc->client->extra_mon_dispatch = NULL; -diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c -index 533e612b6a486..361f3c29897e8 100644 ---- a/fs/erofs/zdata.c -+++ b/fs/erofs/zdata.c -@@ -989,10 +989,11 @@ static void z_erofs_do_decompressed_bvec(struct z_erofs_decompress_backend *be, - struct z_erofs_bvec *bvec) - { - struct z_erofs_bvec_item *item; -+ unsigned int pgnr; - -- if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK)) { -- unsigned int pgnr; -- -+ if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK) && -+ (bvec->end == PAGE_SIZE || -+ bvec->offset + bvec->end == be->pcl->length)) { - pgnr = (bvec->offset + be->pcl->pageofs_out) >> PAGE_SHIFT; - DBG_BUGON(pgnr >= be->nr_pages); - if (!be->decompressed_pages[pgnr]) { -diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c -index 9f42f25fab920..e918decb37358 100644 ---- a/fs/exfat/balloc.c -+++ b/fs/exfat/balloc.c -@@ -69,7 +69,7 @@ static int exfat_allocate_bitmap(struct super_block *sb, - } - sbi->map_sectors = ((need_map_size - 1) >> - (sb->s_blocksize_bits)) + 1; -- sbi->vol_amap = kmalloc_array(sbi->map_sectors, -+ sbi->vol_amap = kvmalloc_array(sbi->map_sectors, - sizeof(struct buffer_head *), GFP_KERNEL); - if (!sbi->vol_amap) - return -ENOMEM; -@@ -84,7 +84,7 @@ static int exfat_allocate_bitmap(struct super_block *sb, - while (j < i) - brelse(sbi->vol_amap[j++]); - -- kfree(sbi->vol_amap); -+ kvfree(sbi->vol_amap); - sbi->vol_amap = NULL; - return -EIO; - } -@@ -138,7 +138,7 @@ void exfat_free_bitmap(struct exfat_sb_info *sbi) - for (i = 0; i < sbi->map_sectors; i++) - __brelse(sbi->vol_amap[i]); - -- kfree(sbi->vol_amap); -+ kvfree(sbi->vol_amap); - } - - int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync) -diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c -index 15c4f901be369..51b03b0dd5f75 100644 ---- a/fs/exfat/dir.c -+++ b/fs/exfat/dir.c -@@ -34,6 +34,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, - { - int i; - struct exfat_entry_set_cache *es; -+ unsigned int uni_len = 0, len; - - es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES); - if (!es) -@@ -52,7 +53,10 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, - if (exfat_get_entry_type(ep) != TYPE_EXTEND) - break; - -- exfat_extract_uni_name(ep, uniname); -+ len = exfat_extract_uni_name(ep, uniname); -+ uni_len += len; -+ if (len != EXFAT_FILE_NAME_LEN || uni_len >= MAX_NAME_LENGTH) -+ break; - uniname += EXFAT_FILE_NAME_LEN; - } - -@@ -210,7 +214,10 @@ static void exfat_free_namebuf(struct exfat_dentry_namebuf *nb) - exfat_init_namebuf(nb); - } - --/* skip iterating emit_dots when dir is empty */ -+/* -+ * Before calling dir_emit*(), sbi->s_lock should be released -+ * because page fault can occur in dir_emit*(). -+ */ - #define ITER_POS_FILLED_DOTS (2) - static int exfat_iterate(struct file *file, struct dir_context *ctx) - { -@@ -225,11 +232,10 @@ static int exfat_iterate(struct file *file, struct dir_context *ctx) - int err = 0, fake_offset = 0; - - exfat_init_namebuf(nb); -- mutex_lock(&EXFAT_SB(sb)->s_lock); - - cpos = ctx->pos; - if (!dir_emit_dots(file, ctx)) -- goto unlock; -+ goto out; - - if (ctx->pos == ITER_POS_FILLED_DOTS) { - cpos = 0; -@@ -241,16 +247,18 @@ static int exfat_iterate(struct file *file, struct dir_context *ctx) - /* name buffer should be allocated before use */ - err = exfat_alloc_namebuf(nb); - if (err) -- goto unlock; -+ goto out; - get_new: -+ mutex_lock(&EXFAT_SB(sb)->s_lock); -+ - if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode)) - goto end_of_dir; - - err = exfat_readdir(inode, &cpos, &de); - if (err) { - /* -- * At least we tried to read a sector. Move cpos to next sector -- * position (should be aligned). -+ * At least we tried to read a sector. -+ * Move cpos to next sector position (should be aligned). - */ - if (err == -EIO) { - cpos += 1 << (sb->s_blocksize_bits); -@@ -273,16 +281,10 @@ get_new: - inum = iunique(sb, EXFAT_ROOT_INO); - } - -- /* -- * Before calling dir_emit(), sb_lock should be released. -- * Because page fault can occur in dir_emit() when the size -- * of buffer given from user is larger than one page size. -- */ - mutex_unlock(&EXFAT_SB(sb)->s_lock); - if (!dir_emit(ctx, nb->lfn, strlen(nb->lfn), inum, - (de.attr & ATTR_SUBDIR) ? DT_DIR : DT_REG)) -- goto out_unlocked; -- mutex_lock(&EXFAT_SB(sb)->s_lock); -+ goto out; - ctx->pos = cpos; - goto get_new; - -@@ -290,9 +292,8 @@ end_of_dir: - if (!cpos && fake_offset) - cpos = ITER_POS_FILLED_DOTS; - ctx->pos = cpos; --unlock: - mutex_unlock(&EXFAT_SB(sb)->s_lock); --out_unlocked: -+out: - /* - * To improve performance, free namebuf after unlock sb_lock. - * If namebuf is not allocated, this function do nothing -@@ -1027,7 +1028,8 @@ rewind: - if (entry_type == TYPE_EXTEND) { - unsigned short entry_uniname[16], unichar; - -- if (step != DIRENT_STEP_NAME) { -+ if (step != DIRENT_STEP_NAME || -+ name_len >= MAX_NAME_LENGTH) { - step = DIRENT_STEP_FILE; - continue; - } -diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h -index dc5dcb78bc27f..2c95916aead88 100644 ---- a/fs/ext2/ext2.h -+++ b/fs/ext2/ext2.h -@@ -70,10 +70,7 @@ struct mb_cache; - * second extended-fs super-block data in memory - */ - struct ext2_sb_info { -- unsigned long s_frag_size; /* Size of a fragment in bytes */ -- unsigned long s_frags_per_block;/* Number of fragments per block */ - unsigned long s_inodes_per_block;/* Number of inodes per block */ -- unsigned long s_frags_per_group;/* Number of fragments in a group */ - unsigned long s_blocks_per_group;/* Number of blocks in a group */ - unsigned long s_inodes_per_group;/* Number of inodes in a group */ - unsigned long s_itb_per_group; /* Number of inode table blocks per group */ -@@ -188,15 +185,6 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb) - #define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size) - #define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino) - --/* -- * Macro-instructions used to manage fragments -- */ --#define EXT2_MIN_FRAG_SIZE 1024 --#define EXT2_MAX_FRAG_SIZE 4096 --#define EXT2_MIN_FRAG_LOG_SIZE 10 --#define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size) --#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block) -- - /* - * Structure of a blocks group descriptor - */ -diff --git a/fs/ext2/super.c b/fs/ext2/super.c -index 3feea4b31fa7e..99b26fe20d17c 100644 ---- a/fs/ext2/super.c -+++ b/fs/ext2/super.c -@@ -668,10 +668,9 @@ static int ext2_setup_super (struct super_block * sb, - es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); - le16_add_cpu(&es->s_mnt_count, 1); - if (test_opt (sb, DEBUG)) -- ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, " -+ ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, gc=%lu, " - "bpg=%lu, ipg=%lu, mo=%04lx]", - EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, -- sbi->s_frag_size, - sbi->s_groups_count, - EXT2_BLOCKS_PER_GROUP(sb), - EXT2_INODES_PER_GROUP(sb), -@@ -1012,14 +1011,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) - } - } - -- sbi->s_frag_size = EXT2_MIN_FRAG_SIZE << -- le32_to_cpu(es->s_log_frag_size); -- if (sbi->s_frag_size == 0) -- goto cantfind_ext2; -- sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size; -- - sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); -- sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); - sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); - - sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb); -@@ -1045,11 +1037,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) - goto failed_mount; - } - -- if (sb->s_blocksize != sbi->s_frag_size) { -+ if (es->s_log_frag_size != es->s_log_block_size) { - ext2_msg(sb, KERN_ERR, -- "error: fragsize %lu != blocksize %lu" -- "(not supported yet)", -- sbi->s_frag_size, sb->s_blocksize); -+ "error: fragsize log %u != blocksize log %u", -+ le32_to_cpu(es->s_log_frag_size), sb->s_blocksize_bits); - goto failed_mount; - } - -@@ -1066,12 +1057,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) - sbi->s_blocks_per_group, sbi->s_inodes_per_group + 3); - goto failed_mount; - } -- if (sbi->s_frags_per_group > sb->s_blocksize * 8) { -- ext2_msg(sb, KERN_ERR, -- "error: #fragments per group too big: %lu", -- sbi->s_frags_per_group); -- goto failed_mount; -- } - if (sbi->s_inodes_per_group < sbi->s_inodes_per_block || - sbi->s_inodes_per_group > sb->s_blocksize * 8) { - ext2_msg(sb, KERN_ERR, -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 4d1e48c676fab..78f39a78de29a 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -3431,7 +3431,6 @@ static inline bool __is_valid_data_blkaddr(block_t blkaddr) - * file.c - */ - int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync); --void f2fs_truncate_data_blocks(struct dnode_of_data *dn); - int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock); - int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock); - int f2fs_truncate(struct inode *inode); -diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c -index 7b94f047cbf79..3ce6da4fac9c6 100644 ---- a/fs/f2fs/file.c -+++ b/fs/f2fs/file.c -@@ -628,11 +628,6 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) - dn->ofs_in_node, nr_free); - } - --void f2fs_truncate_data_blocks(struct dnode_of_data *dn) --{ -- f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode)); --} -- - static int truncate_partial_data_page(struct inode *inode, u64 from, - bool cache_only) - { -diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c -index a010b4bc36d2c..9fe502485930f 100644 ---- a/fs/f2fs/node.c -+++ b/fs/f2fs/node.c -@@ -923,6 +923,7 @@ static int truncate_node(struct dnode_of_data *dn) - - static int truncate_dnode(struct dnode_of_data *dn) - { -+ struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); - struct page *page; - int err; - -@@ -930,16 +931,25 @@ static int truncate_dnode(struct dnode_of_data *dn) - return 1; - - /* get direct node */ -- page = f2fs_get_node_page(F2FS_I_SB(dn->inode), dn->nid); -+ page = f2fs_get_node_page(sbi, dn->nid); - if (PTR_ERR(page) == -ENOENT) - return 1; - else if (IS_ERR(page)) - return PTR_ERR(page); - -+ if (IS_INODE(page) || ino_of_node(page) != dn->inode->i_ino) { -+ f2fs_err(sbi, "incorrect node reference, ino: %lu, nid: %u, ino_of_node: %u", -+ dn->inode->i_ino, dn->nid, ino_of_node(page)); -+ set_sbi_flag(sbi, SBI_NEED_FSCK); -+ f2fs_handle_error(sbi, ERROR_INVALID_NODE_REFERENCE); -+ f2fs_put_page(page, 1); -+ return -EFSCORRUPTED; -+ } -+ - /* Make dnode_of_data for parameter */ - dn->node_page = page; - dn->ofs_in_node = 0; -- f2fs_truncate_data_blocks(dn); -+ f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode)); - err = truncate_node(dn); - if (err) { - f2fs_put_page(page, 1); -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index b6dad389fa144..ff47aad636e5b 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -1347,6 +1347,12 @@ default_check: - return -EINVAL; - } - -+ if ((f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb)) && -+ test_opt(sbi, FLUSH_MERGE)) { -+ f2fs_err(sbi, "FLUSH_MERGE not compatible with readonly mode"); -+ return -EINVAL; -+ } -+ - if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) { - f2fs_err(sbi, "Allow to mount readonly mode only"); - return -EROFS; -@@ -1933,8 +1939,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) - seq_puts(seq, ",inline_dentry"); - else - seq_puts(seq, ",noinline_dentry"); -- if (!f2fs_readonly(sbi->sb) && test_opt(sbi, FLUSH_MERGE)) -+ if (test_opt(sbi, FLUSH_MERGE)) - seq_puts(seq, ",flush_merge"); -+ else -+ seq_puts(seq, ",noflush_merge"); - if (test_opt(sbi, NOBARRIER)) - seq_puts(seq, ",nobarrier"); - if (test_opt(sbi, FASTBOOT)) -@@ -2032,9 +2040,22 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) - return 0; - } - --static void default_options(struct f2fs_sb_info *sbi) -+static void default_options(struct f2fs_sb_info *sbi, bool remount) - { - /* init some FS parameters */ -+ if (!remount) { -+ set_opt(sbi, READ_EXTENT_CACHE); -+ clear_opt(sbi, DISABLE_CHECKPOINT); -+ -+ if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi)) -+ set_opt(sbi, DISCARD); -+ -+ if (f2fs_sb_has_blkzoned(sbi)) -+ F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION; -+ else -+ F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK; -+ } -+ - if (f2fs_sb_has_readonly(sbi)) - F2FS_OPTION(sbi).active_logs = NR_CURSEG_RO_TYPE; - else -@@ -2057,22 +2078,16 @@ static void default_options(struct f2fs_sb_info *sbi) - set_opt(sbi, INLINE_XATTR); - set_opt(sbi, INLINE_DATA); - set_opt(sbi, INLINE_DENTRY); -- set_opt(sbi, READ_EXTENT_CACHE); - set_opt(sbi, NOHEAP); -- clear_opt(sbi, DISABLE_CHECKPOINT); - set_opt(sbi, MERGE_CHECKPOINT); - F2FS_OPTION(sbi).unusable_cap = 0; - sbi->sb->s_flags |= SB_LAZYTIME; -- set_opt(sbi, FLUSH_MERGE); -- if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi)) -- set_opt(sbi, DISCARD); -- if (f2fs_sb_has_blkzoned(sbi)) { -+ if (!f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) -+ set_opt(sbi, FLUSH_MERGE); -+ if (f2fs_sb_has_blkzoned(sbi)) - F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; -- F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION; -- } else { -+ else - F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE; -- F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK; -- } - - #ifdef CONFIG_F2FS_FS_XATTR - set_opt(sbi, XATTR_USER); -@@ -2244,7 +2259,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) - clear_sbi_flag(sbi, SBI_NEED_SB_WRITE); - } - -- default_options(sbi); -+ default_options(sbi, true); - - /* parse mount options */ - err = parse_options(sb, data, true); -@@ -4141,7 +4156,7 @@ try_onemore: - sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid, - sizeof(raw_super->uuid)); - -- default_options(sbi); -+ default_options(sbi, false); - /* parse mount options */ - options = kstrdup((const char *)data, GFP_KERNEL); - if (data && !options) { -diff --git a/fs/file.c b/fs/file.c -index 35c62b54c9d65..dbca26ef7a01a 100644 ---- a/fs/file.c -+++ b/fs/file.c -@@ -1036,12 +1036,28 @@ unsigned long __fdget_raw(unsigned int fd) - return __fget_light(fd, 0); - } - -+/* -+ * Try to avoid f_pos locking. We only need it if the -+ * file is marked for FMODE_ATOMIC_POS, and it can be -+ * accessed multiple ways. -+ * -+ * Always do it for directories, because pidfd_getfd() -+ * can make a file accessible even if it otherwise would -+ * not be, and for directories this is a correctness -+ * issue, not a "POSIX requirement". -+ */ -+static inline bool file_needs_f_pos_lock(struct file *file) -+{ -+ return (file->f_mode & FMODE_ATOMIC_POS) && -+ (file_count(file) > 1 || S_ISDIR(file_inode(file)->i_mode)); -+} -+ - unsigned long __fdget_pos(unsigned int fd) - { - unsigned long v = __fdget(fd); - struct file *file = (struct file *)(v & ~3); - -- if (file && (file->f_mode & FMODE_ATOMIC_POS)) { -+ if (file && file_needs_f_pos_lock(file)) { - v |= FDPUT_POS_UNLOCK; - mutex_lock(&file->f_pos_lock); - } -diff --git a/fs/ntfs3/attrlist.c b/fs/ntfs3/attrlist.c -index c0c6bcbc8c05c..81c22df27c725 100644 ---- a/fs/ntfs3/attrlist.c -+++ b/fs/ntfs3/attrlist.c -@@ -52,7 +52,7 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr) - - if (!attr->non_res) { - lsize = le32_to_cpu(attr->res.data_size); -- le = kmalloc(al_aligned(lsize), GFP_NOFS); -+ le = kmalloc(al_aligned(lsize), GFP_NOFS | __GFP_NOWARN); - if (!le) { - err = -ENOMEM; - goto out; -@@ -80,7 +80,7 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr) - if (err < 0) - goto out; - -- le = kmalloc(al_aligned(lsize), GFP_NOFS); -+ le = kmalloc(al_aligned(lsize), GFP_NOFS | __GFP_NOWARN); - if (!le) { - err = -ENOMEM; - goto out; -diff --git a/fs/open.c b/fs/open.c -index 9541430ec5b30..51dc46620d033 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -1233,7 +1233,7 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op) - lookup_flags |= LOOKUP_IN_ROOT; - if (how->resolve & RESOLVE_CACHED) { - /* Don't bother even trying for create/truncate/tmpfile open */ -- if (flags & (O_TRUNC | O_CREAT | O_TMPFILE)) -+ if (flags & (O_TRUNC | O_CREAT | __O_TMPFILE)) - return -EAGAIN; - lookup_flags |= LOOKUP_CACHED; - } -diff --git a/fs/super.c b/fs/super.c -index 7c140ee60c547..d138332e57a94 100644 ---- a/fs/super.c -+++ b/fs/super.c -@@ -904,6 +904,7 @@ int reconfigure_super(struct fs_context *fc) - struct super_block *sb = fc->root->d_sb; - int retval; - bool remount_ro = false; -+ bool remount_rw = false; - bool force = fc->sb_flags & SB_FORCE; - - if (fc->sb_flags_mask & ~MS_RMT_MASK) -@@ -921,7 +922,7 @@ int reconfigure_super(struct fs_context *fc) - bdev_read_only(sb->s_bdev)) - return -EACCES; - #endif -- -+ remount_rw = !(fc->sb_flags & SB_RDONLY) && sb_rdonly(sb); - remount_ro = (fc->sb_flags & SB_RDONLY) && !sb_rdonly(sb); - } - -@@ -951,6 +952,14 @@ int reconfigure_super(struct fs_context *fc) - if (retval) - return retval; - } -+ } else if (remount_rw) { -+ /* -+ * We set s_readonly_remount here to protect filesystem's -+ * reconfigure code from writes from userspace until -+ * reconfigure finishes. -+ */ -+ sb->s_readonly_remount = 1; -+ smp_wmb(); - } - - if (fc->ops->reconfigure) { -diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c -index 3b8567564e7e4..9925cfe571595 100644 ---- a/fs/sysv/itree.c -+++ b/fs/sysv/itree.c -@@ -145,6 +145,10 @@ static int alloc_branch(struct inode *inode, - */ - parent = block_to_cpu(SYSV_SB(inode->i_sb), branch[n-1].key); - bh = sb_getblk(inode->i_sb, parent); -+ if (!bh) { -+ sysv_free_block(inode->i_sb, branch[n].key); -+ break; -+ } - lock_buffer(bh); - memset(bh->b_data, 0, blocksize); - branch[n].bh = bh; -diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h -index 20c93f08c9933..95a1d214108a5 100644 ---- a/include/asm-generic/word-at-a-time.h -+++ b/include/asm-generic/word-at-a-time.h -@@ -38,7 +38,7 @@ static inline long find_zero(unsigned long mask) - return (mask >> 8) ? byte : byte + 1; - } - --static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) -+static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) - { - unsigned long rhs = val | c->low_bits; - *data = rhs; -diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h -index ee0d75d9a302d..77055b239165a 100644 ---- a/include/linux/f2fs_fs.h -+++ b/include/linux/f2fs_fs.h -@@ -104,6 +104,7 @@ enum f2fs_error { - ERROR_INCONSISTENT_SIT, - ERROR_CORRUPTED_VERITY_XATTR, - ERROR_CORRUPTED_XATTR, -+ ERROR_INVALID_NODE_REFERENCE, - ERROR_MAX, - }; - -diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h -index 51857117ac099..c8ef3b881f03d 100644 ---- a/include/net/inet_sock.h -+++ b/include/net/inet_sock.h -@@ -107,11 +107,12 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) - - static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb) - { -- if (!sk->sk_mark && -- READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept)) -+ u32 mark = READ_ONCE(sk->sk_mark); -+ -+ if (!mark && READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept)) - return skb->mark; - -- return sk->sk_mark; -+ return mark; - } - - static inline int inet_request_bound_dev_if(const struct sock *sk, -diff --git a/include/net/ip.h b/include/net/ip.h -index 83a1a9bc3ceb1..530e7257e4389 100644 ---- a/include/net/ip.h -+++ b/include/net/ip.h -@@ -93,7 +93,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm, - { - ipcm_init(ipcm); - -- ipcm->sockc.mark = inet->sk.sk_mark; -+ ipcm->sockc.mark = READ_ONCE(inet->sk.sk_mark); - ipcm->sockc.tsflags = inet->sk.sk_tsflags; - ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if); - ipcm->addr = inet->inet_saddr; -diff --git a/include/net/route.h b/include/net/route.h -index fe00b0a2e4759..af8431b25f800 100644 ---- a/include/net/route.h -+++ b/include/net/route.h -@@ -171,7 +171,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi - __be16 dport, __be16 sport, - __u8 proto, __u8 tos, int oif) - { -- flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos, -+ flowi4_init_output(fl4, oif, sk ? READ_ONCE(sk->sk_mark) : 0, tos, - RT_SCOPE_UNIVERSE, proto, - sk ? inet_sk_flowi_flags(sk) : 0, - daddr, saddr, dport, sport, sock_net_uid(net, sk)); -@@ -304,7 +304,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, - if (inet_sk(sk)->transparent) - flow_flags |= FLOWI_FLAG_ANYSRC; - -- flowi4_init_output(fl4, oif, sk->sk_mark, ip_sock_rt_tos(sk), -+ flowi4_init_output(fl4, oif, READ_ONCE(sk->sk_mark), ip_sock_rt_tos(sk), - ip_sock_rt_scope(sk), protocol, flow_flags, dst, - src, dport, sport, sk->sk_uid); - } -diff --git a/include/net/vxlan.h b/include/net/vxlan.h -index 03bcc1ef0d61e..a46ec889acb73 100644 ---- a/include/net/vxlan.h -+++ b/include/net/vxlan.h -@@ -548,12 +548,12 @@ static inline void vxlan_flag_attr_error(int attrtype, - } - - static inline bool vxlan_fdb_nh_path_select(struct nexthop *nh, -- int hash, -+ u32 hash, - struct vxlan_rdst *rdst) - { - struct fib_nh_common *nhc; - -- nhc = nexthop_path_fdb_result(nh, hash); -+ nhc = nexthop_path_fdb_result(nh, hash >> 1); - if (unlikely(!nhc)) - return false; - -diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c -index f091153bc8540..ed8e9deae284a 100644 ---- a/io_uring/io_uring.c -+++ b/io_uring/io_uring.c -@@ -2349,12 +2349,21 @@ int io_run_task_work_sig(struct io_ring_ctx *ctx) - return 0; - } - -+static bool current_pending_io(void) -+{ -+ struct io_uring_task *tctx = current->io_uring; -+ -+ if (!tctx) -+ return false; -+ return percpu_counter_read_positive(&tctx->inflight); -+} -+ - /* when returns >0, the caller should retry */ - static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx, - struct io_wait_queue *iowq, - ktime_t *timeout) - { -- int token, ret; -+ int io_wait, ret; - unsigned long check_cq; - - /* make sure we run task_work before checking for signals */ -@@ -2372,15 +2381,17 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx, - } - - /* -- * Use io_schedule_prepare/finish, so cpufreq can take into account -- * that the task is waiting for IO - turns out to be important for low -- * QD IO. -+ * Mark us as being in io_wait if we have pending requests, so cpufreq -+ * can take into account that the task is waiting for IO - turns out -+ * to be important for low QD IO. - */ -- token = io_schedule_prepare(); -+ io_wait = current->in_iowait; -+ if (current_pending_io()) -+ current->in_iowait = 1; - ret = 1; - if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS)) - ret = -ETIME; -- io_schedule_finish(token); -+ current->in_iowait = io_wait; - return ret; - } - -diff --git a/io_uring/timeout.c b/io_uring/timeout.c -index 4c6a5666541cf..b0cf05ebcbcc3 100644 ---- a/io_uring/timeout.c -+++ b/io_uring/timeout.c -@@ -545,7 +545,7 @@ int io_timeout(struct io_kiocb *req, unsigned int issue_flags) - goto add; - } - -- tail = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts); -+ tail = data_race(ctx->cached_cq_tail) - atomic_read(&ctx->cq_timeouts); - timeout->target_seq = tail + off; - - /* Update the last seq here in case io_flush_timeouts() hasn't. -diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c -index 09141351d5457..08a8e81027289 100644 ---- a/kernel/bpf/cpumap.c -+++ b/kernel/bpf/cpumap.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -71,6 +72,7 @@ struct bpf_cpu_map_entry { - struct rcu_head rcu; - - struct work_struct kthread_stop_wq; -+ struct completion kthread_running; - }; - - struct bpf_cpu_map { -@@ -134,11 +136,17 @@ static void __cpu_map_ring_cleanup(struct ptr_ring *ring) - * invoked cpu_map_kthread_stop(). Catch any broken behaviour - * gracefully and warn once. - */ -- struct xdp_frame *xdpf; -+ void *ptr; - -- while ((xdpf = ptr_ring_consume(ring))) -- if (WARN_ON_ONCE(xdpf)) -- xdp_return_frame(xdpf); -+ while ((ptr = ptr_ring_consume(ring))) { -+ WARN_ON_ONCE(1); -+ if (unlikely(__ptr_test_bit(0, &ptr))) { -+ __ptr_clear_bit(0, &ptr); -+ kfree_skb(ptr); -+ continue; -+ } -+ xdp_return_frame(ptr); -+ } - } - - static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu) -@@ -158,7 +166,6 @@ static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu) - static void cpu_map_kthread_stop(struct work_struct *work) - { - struct bpf_cpu_map_entry *rcpu; -- int err; - - rcpu = container_of(work, struct bpf_cpu_map_entry, kthread_stop_wq); - -@@ -168,14 +175,7 @@ static void cpu_map_kthread_stop(struct work_struct *work) - rcu_barrier(); - - /* kthread_stop will wake_up_process and wait for it to complete */ -- err = kthread_stop(rcpu->kthread); -- if (err) { -- /* kthread_stop may be called before cpu_map_kthread_run -- * is executed, so we need to release the memory related -- * to rcpu. -- */ -- put_cpu_map_entry(rcpu); -- } -+ kthread_stop(rcpu->kthread); - } - - static void cpu_map_bpf_prog_run_skb(struct bpf_cpu_map_entry *rcpu, -@@ -303,11 +303,11 @@ static int cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames, - return nframes; - } - -- - static int cpu_map_kthread_run(void *data) - { - struct bpf_cpu_map_entry *rcpu = data; - -+ complete(&rcpu->kthread_running); - set_current_state(TASK_INTERRUPTIBLE); - - /* When kthread gives stop order, then rcpu have been disconnected -@@ -472,6 +472,7 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value, - goto free_ptr_ring; - - /* Setup kthread */ -+ init_completion(&rcpu->kthread_running); - rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa, - "cpumap/%d/map:%d", cpu, - map->id); -@@ -485,6 +486,12 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value, - kthread_bind(rcpu->kthread, cpu); - wake_up_process(rcpu->kthread); - -+ /* Make sure kthread has been running, so kthread_stop() will not -+ * stop the kthread prematurely and all pending frames or skbs -+ * will be handled by the kthread before kthread_stop() returns. -+ */ -+ wait_for_completion(&rcpu->kthread_running); -+ - return rcpu; - - free_prog: -diff --git a/kernel/events/core.c b/kernel/events/core.c -index 934332b3eb541..db1065daabb62 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -1133,6 +1133,11 @@ static int perf_mux_hrtimer_restart(struct perf_cpu_context *cpuctx) - return 0; - } - -+static int perf_mux_hrtimer_restart_ipi(void *arg) -+{ -+ return perf_mux_hrtimer_restart(arg); -+} -+ - void perf_pmu_disable(struct pmu *pmu) - { - int *count = this_cpu_ptr(pmu->pmu_disable_count); -@@ -11155,8 +11160,7 @@ perf_event_mux_interval_ms_store(struct device *dev, - cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); - cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer); - -- cpu_function_call(cpu, -- (remote_function_f)perf_mux_hrtimer_restart, cpuctx); -+ cpu_function_call(cpu, perf_mux_hrtimer_restart_ipi, cpuctx); - } - cpus_read_unlock(); - mutex_unlock(&mux_interval_mutex); -diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c -index 1642548892a8e..ad04390883ada 100644 ---- a/kernel/trace/bpf_trace.c -+++ b/kernel/trace/bpf_trace.c -@@ -662,8 +662,7 @@ static DEFINE_PER_CPU(int, bpf_trace_nest_level); - BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, - u64, flags, void *, data, u64, size) - { -- struct bpf_trace_sample_data *sds = this_cpu_ptr(&bpf_trace_sds); -- int nest_level = this_cpu_inc_return(bpf_trace_nest_level); -+ struct bpf_trace_sample_data *sds; - struct perf_raw_record raw = { - .frag = { - .size = size, -@@ -671,7 +670,11 @@ BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, - }, - }; - struct perf_sample_data *sd; -- int err; -+ int nest_level, err; -+ -+ preempt_disable(); -+ sds = this_cpu_ptr(&bpf_trace_sds); -+ nest_level = this_cpu_inc_return(bpf_trace_nest_level); - - if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(sds->sds))) { - err = -EBUSY; -@@ -690,9 +693,9 @@ BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, - sd->sample_flags |= PERF_SAMPLE_RAW; - - err = __bpf_perf_event_output(regs, map, flags, sd); -- - out: - this_cpu_dec(bpf_trace_nest_level); -+ preempt_enable(); - return err; - } - -@@ -717,7 +720,6 @@ static DEFINE_PER_CPU(struct bpf_trace_sample_data, bpf_misc_sds); - u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, - void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy) - { -- int nest_level = this_cpu_inc_return(bpf_event_output_nest_level); - struct perf_raw_frag frag = { - .copy = ctx_copy, - .size = ctx_size, -@@ -734,8 +736,12 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, - }; - struct perf_sample_data *sd; - struct pt_regs *regs; -+ int nest_level; - u64 ret; - -+ preempt_disable(); -+ nest_level = this_cpu_inc_return(bpf_event_output_nest_level); -+ - if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(bpf_misc_sds.sds))) { - ret = -EBUSY; - goto out; -@@ -751,6 +757,7 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, - ret = __bpf_perf_event_output(regs, map, flags, sd); - out: - this_cpu_dec(bpf_event_output_nest_level); -+ preempt_enable(); - return ret; - } - -diff --git a/lib/Makefile b/lib/Makefile -index 59bd7c2f793a7..5ffe72ec99797 100644 ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -81,8 +81,14 @@ obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o - obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o - obj-$(CONFIG_TEST_PRINTF) += test_printf.o - obj-$(CONFIG_TEST_SCANF) += test_scanf.o -+ - obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o - obj-$(CONFIG_TEST_STRSCPY) += test_strscpy.o -+ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_KASAN),yy) -+# FIXME: Clang breaks test_bitmap_const_eval when KASAN and GCOV are enabled -+GCOV_PROFILE_test_bitmap.o := n -+endif -+ - obj-$(CONFIG_TEST_UUID) += test_uuid.o - obj-$(CONFIG_TEST_XARRAY) += test_xarray.o - obj-$(CONFIG_TEST_MAPLE_TREE) += test_maple_tree.o -diff --git a/lib/debugobjects.c b/lib/debugobjects.c -index c46736210363a..dacb80c22c4f1 100644 ---- a/lib/debugobjects.c -+++ b/lib/debugobjects.c -@@ -498,6 +498,15 @@ static void debug_print_object(struct debug_obj *obj, char *msg) - const struct debug_obj_descr *descr = obj->descr; - static int limit; - -+ /* -+ * Don't report if lookup_object_or_alloc() by the current thread -+ * failed because lookup_object_or_alloc()/debug_objects_oom() by a -+ * concurrent thread turned off debug_objects_enabled and cleared -+ * the hash buckets. -+ */ -+ if (!debug_objects_enabled) -+ return; -+ - if (limit < 5 && descr != descr_test) { - void *hint = descr->debug_hint ? - descr->debug_hint(obj->object) : NULL; -diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c -index a8005ad3bd589..37a9108c4f588 100644 ---- a/lib/test_bitmap.c -+++ b/lib/test_bitmap.c -@@ -1149,6 +1149,10 @@ static void __init test_bitmap_print_buf(void) - } - } - -+/* -+ * FIXME: Clang breaks compile-time evaluations when KASAN and GCOV are enabled. -+ * To workaround it, GCOV is force-disabled in Makefile for this configuration. -+ */ - static void __init test_bitmap_const_eval(void) - { - DECLARE_BITMAP(bitmap, BITS_PER_LONG); -@@ -1174,11 +1178,7 @@ static void __init test_bitmap_const_eval(void) - * the compiler is fixed. - */ - bitmap_clear(bitmap, 0, BITS_PER_LONG); --#if defined(__s390__) && defined(__clang__) -- if (!const_test_bit(7, bitmap)) --#else - if (!test_bit(7, bitmap)) --#endif - bitmap_set(bitmap, 5, 2); - - /* Equals to `unsigned long bitopvar = BIT(20)` */ -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 3e8f1ad0fe9db..67b6d8238b3ed 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -3165,12 +3165,12 @@ void mod_objcg_state(struct obj_cgroup *objcg, struct pglist_data *pgdat, - * accumulating over a page of vmstat data or when pgdat or idx - * changes. - */ -- if (stock->cached_objcg != objcg) { -+ if (READ_ONCE(stock->cached_objcg) != objcg) { - old = drain_obj_stock(stock); - obj_cgroup_get(objcg); - stock->nr_bytes = atomic_read(&objcg->nr_charged_bytes) - ? atomic_xchg(&objcg->nr_charged_bytes, 0) : 0; -- stock->cached_objcg = objcg; -+ WRITE_ONCE(stock->cached_objcg, objcg); - stock->cached_pgdat = pgdat; - } else if (stock->cached_pgdat != pgdat) { - /* Flush the existing cached vmstat data */ -@@ -3224,7 +3224,7 @@ static bool consume_obj_stock(struct obj_cgroup *objcg, unsigned int nr_bytes) - local_lock_irqsave(&memcg_stock.stock_lock, flags); - - stock = this_cpu_ptr(&memcg_stock); -- if (objcg == stock->cached_objcg && stock->nr_bytes >= nr_bytes) { -+ if (objcg == READ_ONCE(stock->cached_objcg) && stock->nr_bytes >= nr_bytes) { - stock->nr_bytes -= nr_bytes; - ret = true; - } -@@ -3236,7 +3236,7 @@ static bool consume_obj_stock(struct obj_cgroup *objcg, unsigned int nr_bytes) - - static struct obj_cgroup *drain_obj_stock(struct memcg_stock_pcp *stock) - { -- struct obj_cgroup *old = stock->cached_objcg; -+ struct obj_cgroup *old = READ_ONCE(stock->cached_objcg); - - if (!old) - return NULL; -@@ -3289,7 +3289,7 @@ static struct obj_cgroup *drain_obj_stock(struct memcg_stock_pcp *stock) - stock->cached_pgdat = NULL; - } - -- stock->cached_objcg = NULL; -+ WRITE_ONCE(stock->cached_objcg, NULL); - /* - * The `old' objects needs to be released by the caller via - * obj_cgroup_put() outside of memcg_stock_pcp::stock_lock. -@@ -3300,10 +3300,11 @@ static struct obj_cgroup *drain_obj_stock(struct memcg_stock_pcp *stock) - static bool obj_stock_flush_required(struct memcg_stock_pcp *stock, - struct mem_cgroup *root_memcg) - { -+ struct obj_cgroup *objcg = READ_ONCE(stock->cached_objcg); - struct mem_cgroup *memcg; - -- if (stock->cached_objcg) { -- memcg = obj_cgroup_memcg(stock->cached_objcg); -+ if (objcg) { -+ memcg = obj_cgroup_memcg(objcg); - if (memcg && mem_cgroup_is_descendant(memcg, root_memcg)) - return true; - } -@@ -3322,10 +3323,10 @@ static void refill_obj_stock(struct obj_cgroup *objcg, unsigned int nr_bytes, - local_lock_irqsave(&memcg_stock.stock_lock, flags); - - stock = this_cpu_ptr(&memcg_stock); -- if (stock->cached_objcg != objcg) { /* reset if necessary */ -+ if (READ_ONCE(stock->cached_objcg) != objcg) { /* reset if necessary */ - old = drain_obj_stock(stock); - obj_cgroup_get(objcg); -- stock->cached_objcg = objcg; -+ WRITE_ONCE(stock->cached_objcg, objcg); - stock->nr_bytes = atomic_read(&objcg->nr_charged_bytes) - ? atomic_xchg(&objcg->nr_charged_bytes, 0) : 0; - allow_uncharge = true; /* Allow uncharge when objcg changes */ -diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c -index eebe256104bc0..947ca580bb9a2 100644 ---- a/net/bluetooth/l2cap_sock.c -+++ b/net/bluetooth/l2cap_sock.c -@@ -46,6 +46,7 @@ static const struct proto_ops l2cap_sock_ops; - static void l2cap_sock_init(struct sock *sk, struct sock *parent); - static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, - int proto, gfp_t prio, int kern); -+static void l2cap_sock_cleanup_listen(struct sock *parent); - - bool l2cap_is_socket(struct socket *sock) - { -@@ -1415,6 +1416,7 @@ static int l2cap_sock_release(struct socket *sock) - if (!sk) - return 0; - -+ l2cap_sock_cleanup_listen(sk); - bt_sock_unlink(&l2cap_sk_list, sk); - - err = l2cap_sock_shutdown(sock, SHUT_RDWR); -diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c -index 4e4f1e4bc265a..c22bb06b450ee 100644 ---- a/net/ceph/osd_client.c -+++ b/net/ceph/osd_client.c -@@ -3334,17 +3334,24 @@ static int linger_reg_commit_wait(struct ceph_osd_linger_request *lreq) - int ret; - - dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id); -- ret = wait_for_completion_interruptible(&lreq->reg_commit_wait); -+ ret = wait_for_completion_killable(&lreq->reg_commit_wait); - return ret ?: lreq->reg_commit_error; - } - --static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq) -+static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq, -+ unsigned long timeout) - { -- int ret; -+ long left; - - dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id); -- ret = wait_for_completion_interruptible(&lreq->notify_finish_wait); -- return ret ?: lreq->notify_finish_error; -+ left = wait_for_completion_killable_timeout(&lreq->notify_finish_wait, -+ ceph_timeout_jiffies(timeout)); -+ if (left <= 0) -+ left = left ?: -ETIMEDOUT; -+ else -+ left = lreq->notify_finish_error; /* completed */ -+ -+ return left; - } - - /* -@@ -4896,7 +4903,8 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc, - linger_submit(lreq); - ret = linger_reg_commit_wait(lreq); - if (!ret) -- ret = linger_notify_finish_wait(lreq); -+ ret = linger_notify_finish_wait(lreq, -+ msecs_to_jiffies(2 * timeout * MSEC_PER_SEC)); - else - dout("lreq %p failed to initiate notify %d\n", lreq, ret); - -diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c -index 94374d529ea42..ad01b1bea52e4 100644 ---- a/net/core/bpf_sk_storage.c -+++ b/net/core/bpf_sk_storage.c -@@ -531,8 +531,11 @@ bpf_sk_storage_diag_alloc(const struct nlattr *nla_stgs) - return ERR_PTR(-EPERM); - - nla_for_each_nested(nla, nla_stgs, rem) { -- if (nla_type(nla) == SK_DIAG_BPF_STORAGE_REQ_MAP_FD) -+ if (nla_type(nla) == SK_DIAG_BPF_STORAGE_REQ_MAP_FD) { -+ if (nla_len(nla) != sizeof(u32)) -+ return ERR_PTR(-EINVAL); - nr_maps++; -+ } - } - - diag = kzalloc(struct_size(diag, maps, nr_maps), GFP_KERNEL); -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 5625ed30a06f3..2758b3f7c0214 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -5030,13 +5030,17 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, - br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); - if (br_spec) { - nla_for_each_nested(attr, br_spec, rem) { -- if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { -+ if (nla_type(attr) == IFLA_BRIDGE_FLAGS && !have_flags) { - if (nla_len(attr) < sizeof(flags)) - return -EINVAL; - - have_flags = true; - flags = nla_get_u16(attr); -- break; -+ } -+ -+ if (nla_type(attr) == IFLA_BRIDGE_MODE) { -+ if (nla_len(attr) < sizeof(u16)) -+ return -EINVAL; - } - } - } -diff --git a/net/core/sock.c b/net/core/sock.c -index 0c1baa5517f11..3b5304f084ef3 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -800,7 +800,7 @@ EXPORT_SYMBOL(sock_no_linger); - void sock_set_priority(struct sock *sk, u32 priority) - { - lock_sock(sk); -- sk->sk_priority = priority; -+ WRITE_ONCE(sk->sk_priority, priority); - release_sock(sk); - } - EXPORT_SYMBOL(sock_set_priority); -@@ -977,7 +977,7 @@ EXPORT_SYMBOL(sock_set_rcvbuf); - static void __sock_set_mark(struct sock *sk, u32 val) - { - if (val != sk->sk_mark) { -- sk->sk_mark = val; -+ WRITE_ONCE(sk->sk_mark, val); - sk_dst_reset(sk); - } - } -@@ -996,7 +996,7 @@ static void sock_release_reserved_memory(struct sock *sk, int bytes) - bytes = round_down(bytes, PAGE_SIZE); - - WARN_ON(bytes > sk->sk_reserved_mem); -- sk->sk_reserved_mem -= bytes; -+ WRITE_ONCE(sk->sk_reserved_mem, sk->sk_reserved_mem - bytes); - sk_mem_reclaim(sk); - } - -@@ -1033,7 +1033,8 @@ static int sock_reserve_memory(struct sock *sk, int bytes) - } - sk->sk_forward_alloc += pages << PAGE_SHIFT; - -- sk->sk_reserved_mem += pages << PAGE_SHIFT; -+ WRITE_ONCE(sk->sk_reserved_mem, -+ sk->sk_reserved_mem + (pages << PAGE_SHIFT)); - - return 0; - } -@@ -1202,7 +1203,7 @@ set_sndbuf: - if ((val >= 0 && val <= 6) || - sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) || - sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) -- sk->sk_priority = val; -+ WRITE_ONCE(sk->sk_priority, val); - else - ret = -EPERM; - break; -@@ -1425,7 +1426,8 @@ set_sndbuf: - cmpxchg(&sk->sk_pacing_status, - SK_PACING_NONE, - SK_PACING_NEEDED); -- sk->sk_max_pacing_rate = ulval; -+ /* Pairs with READ_ONCE() from sk_getsockopt() */ -+ WRITE_ONCE(sk->sk_max_pacing_rate, ulval); - sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval); - break; - } -@@ -1520,7 +1522,9 @@ set_sndbuf: - } - if ((u8)val == SOCK_TXREHASH_DEFAULT) - val = READ_ONCE(sock_net(sk)->core.sysctl_txrehash); -- /* Paired with READ_ONCE() in tcp_rtx_synack() */ -+ /* Paired with READ_ONCE() in tcp_rtx_synack() -+ * and sk_getsockopt(). -+ */ - WRITE_ONCE(sk->sk_txrehash, (u8)val); - break; - -@@ -1620,11 +1624,11 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - break; - - case SO_SNDBUF: -- v.val = sk->sk_sndbuf; -+ v.val = READ_ONCE(sk->sk_sndbuf); - break; - - case SO_RCVBUF: -- v.val = sk->sk_rcvbuf; -+ v.val = READ_ONCE(sk->sk_rcvbuf); - break; - - case SO_REUSEADDR: -@@ -1666,7 +1670,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - break; - - case SO_PRIORITY: -- v.val = sk->sk_priority; -+ v.val = READ_ONCE(sk->sk_priority); - break; - - case SO_LINGER: -@@ -1713,7 +1717,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - break; - - case SO_RCVLOWAT: -- v.val = sk->sk_rcvlowat; -+ v.val = READ_ONCE(sk->sk_rcvlowat); - break; - - case SO_SNDLOWAT: -@@ -1792,7 +1796,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - return security_socket_getpeersec_stream(sock, optval.user, optlen.user, len); - - case SO_MARK: -- v.val = sk->sk_mark; -+ v.val = READ_ONCE(sk->sk_mark); - break; - - case SO_RCVMARK: -@@ -1811,7 +1815,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - if (!sock->ops->set_peek_off) - return -EOPNOTSUPP; - -- v.val = sk->sk_peek_off; -+ v.val = READ_ONCE(sk->sk_peek_off); - break; - case SO_NOFCS: - v.val = sock_flag(sk, SOCK_NOFCS); -@@ -1841,7 +1845,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - - #ifdef CONFIG_NET_RX_BUSY_POLL - case SO_BUSY_POLL: -- v.val = sk->sk_ll_usec; -+ v.val = READ_ONCE(sk->sk_ll_usec); - break; - case SO_PREFER_BUSY_POLL: - v.val = READ_ONCE(sk->sk_prefer_busy_poll); -@@ -1849,12 +1853,14 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - #endif - - case SO_MAX_PACING_RATE: -+ /* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */ - if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) { - lv = sizeof(v.ulval); -- v.ulval = sk->sk_max_pacing_rate; -+ v.ulval = READ_ONCE(sk->sk_max_pacing_rate); - } else { - /* 32bit version */ -- v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U); -+ v.val = min_t(unsigned long, ~0U, -+ READ_ONCE(sk->sk_max_pacing_rate)); - } - break; - -@@ -1922,11 +1928,12 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - break; - - case SO_RESERVE_MEM: -- v.val = sk->sk_reserved_mem; -+ v.val = READ_ONCE(sk->sk_reserved_mem); - break; - - case SO_TXREHASH: -- v.val = sk->sk_txrehash; -+ /* Paired with WRITE_ONCE() in sk_setsockopt() */ -+ v.val = READ_ONCE(sk->sk_txrehash); - break; - - default: -@@ -3112,7 +3119,7 @@ EXPORT_SYMBOL(__sk_mem_reclaim); - - int sk_set_peek_off(struct sock *sk, int val) - { -- sk->sk_peek_off = val; -+ WRITE_ONCE(sk->sk_peek_off, val); - return 0; - } - EXPORT_SYMBOL_GPL(sk_set_peek_off); -diff --git a/net/core/sock_map.c b/net/core/sock_map.c -index d382672018928..c84e5073c0b66 100644 ---- a/net/core/sock_map.c -+++ b/net/core/sock_map.c -@@ -117,7 +117,6 @@ static void sock_map_sk_acquire(struct sock *sk) - __acquires(&sk->sk_lock.slock) - { - lock_sock(sk); -- preempt_disable(); - rcu_read_lock(); - } - -@@ -125,7 +124,6 @@ static void sock_map_sk_release(struct sock *sk) - __releases(&sk->sk_lock.slock) - { - rcu_read_unlock(); -- preempt_enable(); - release_sock(sk); - } - -diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c -index dc4fb699b56c3..d2981e89d3638 100644 ---- a/net/dcb/dcbnl.c -+++ b/net/dcb/dcbnl.c -@@ -946,7 +946,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, - return -EOPNOTSUPP; - - ret = nla_parse_nested_deprecated(data, DCB_BCN_ATTR_MAX, -- tb[DCB_ATTR_BCN], dcbnl_pfc_up_nest, -+ tb[DCB_ATTR_BCN], dcbnl_bcn_nest, - NULL); - if (ret) - return ret; -diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c -index c0fd8f5f3b94e..b51ce6f8ceba0 100644 ---- a/net/dccp/ipv6.c -+++ b/net/dccp/ipv6.c -@@ -237,8 +237,8 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req - opt = ireq->ipv6_opt; - if (!opt) - opt = rcu_dereference(np->opt); -- err = ip6_xmit(sk, skb, &fl6, sk->sk_mark, opt, np->tclass, -- sk->sk_priority); -+ err = ip6_xmit(sk, skb, &fl6, READ_ONCE(sk->sk_mark), opt, -+ np->tclass, sk->sk_priority); - rcu_read_unlock(); - err = net_xmit_eval(err); - } -diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c -index b812eb36f0e36..f7426926a1041 100644 ---- a/net/ipv4/inet_diag.c -+++ b/net/ipv4/inet_diag.c -@@ -150,7 +150,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb, - } - #endif - -- if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark)) -+ if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, READ_ONCE(sk->sk_mark))) - goto errout; - - if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) || -@@ -799,7 +799,7 @@ int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk) - entry.ifindex = sk->sk_bound_dev_if; - entry.userlocks = sk_fullsock(sk) ? sk->sk_userlocks : 0; - if (sk_fullsock(sk)) -- entry.mark = sk->sk_mark; -+ entry.mark = READ_ONCE(sk->sk_mark); - else if (sk->sk_state == TCP_NEW_SYN_RECV) - entry.mark = inet_rsk(inet_reqsk(sk))->ir_mark; - else if (sk->sk_state == TCP_TIME_WAIT) -diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c -index 7b4ab545c06e0..acfe58d2f1dd7 100644 ---- a/net/ipv4/ip_output.c -+++ b/net/ipv4/ip_output.c -@@ -182,9 +182,9 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk, - ip_options_build(skb, &opt->opt, daddr, rt); - } - -- skb->priority = sk->sk_priority; -+ skb->priority = READ_ONCE(sk->sk_priority); - if (!skb->mark) -- skb->mark = sk->sk_mark; -+ skb->mark = READ_ONCE(sk->sk_mark); - - /* Send it out. */ - return ip_local_out(net, skb->sk, skb); -@@ -526,8 +526,8 @@ packet_routed: - skb_shinfo(skb)->gso_segs ?: 1); - - /* TODO : should we use skb->sk here instead of sk ? */ -- skb->priority = sk->sk_priority; -- skb->mark = sk->sk_mark; -+ skb->priority = READ_ONCE(sk->sk_priority); -+ skb->mark = READ_ONCE(sk->sk_mark); - - res = ip_local_out(net, sk, skb); - rcu_read_unlock(); -diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c -index a7fd035b5b4f9..63aa52becd880 100644 ---- a/net/ipv4/ip_sockglue.c -+++ b/net/ipv4/ip_sockglue.c -@@ -591,7 +591,7 @@ void __ip_sock_set_tos(struct sock *sk, int val) - } - if (inet_sk(sk)->tos != val) { - inet_sk(sk)->tos = val; -- sk->sk_priority = rt_tos2priority(val); -+ WRITE_ONCE(sk->sk_priority, rt_tos2priority(val)); - sk_dst_reset(sk); - } - } -diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c -index 86197634dcf5d..639aa5abda9dd 100644 ---- a/net/ipv4/raw.c -+++ b/net/ipv4/raw.c -@@ -346,7 +346,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, - goto error; - skb_reserve(skb, hlen); - -- skb->priority = sk->sk_priority; -+ skb->priority = READ_ONCE(sk->sk_priority); - skb->mark = sockc->mark; - skb->tstamp = sockc->transmit_time; - skb_dst_set(skb, &rt->dst); -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index cd1fa9f70f1a1..51bd9a50a1d1d 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -518,7 +518,7 @@ static void __build_flow_key(const struct net *net, struct flowi4 *fl4, - const struct inet_sock *inet = inet_sk(sk); - - oif = sk->sk_bound_dev_if; -- mark = sk->sk_mark; -+ mark = READ_ONCE(sk->sk_mark); - tos = ip_sock_rt_tos(sk); - scope = ip_sock_rt_scope(sk); - prot = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol; -@@ -552,7 +552,7 @@ static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk) - inet_opt = rcu_dereference(inet->inet_opt); - if (inet_opt && inet_opt->opt.srr) - daddr = inet_opt->opt.faddr; -- flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, -+ flowi4_init_output(fl4, sk->sk_bound_dev_if, READ_ONCE(sk->sk_mark), - ip_sock_rt_tos(sk) & IPTOS_RT_MASK, - ip_sock_rt_scope(sk), - inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index 9a8d59e9303a0..08921b96f9728 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -931,9 +931,9 @@ static void tcp_v4_send_ack(const struct sock *sk, - ctl_sk = this_cpu_read(ipv4_tcp_sk); - sock_net_set(ctl_sk, net); - ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ? -- inet_twsk(sk)->tw_mark : sk->sk_mark; -+ inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark); - ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ? -- inet_twsk(sk)->tw_priority : sk->sk_priority; -+ inet_twsk(sk)->tw_priority : READ_ONCE(sk->sk_priority); - transmit_time = tcp_transmit_time(sk); - ip_send_unicast_reply(ctl_sk, - skb, &TCP_SKB_CB(skb)->header.h4.opt, -diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c -index 82f4575f9cd90..99ac5efe244d3 100644 ---- a/net/ipv4/tcp_metrics.c -+++ b/net/ipv4/tcp_metrics.c -@@ -40,7 +40,7 @@ struct tcp_fastopen_metrics { - - struct tcp_metrics_block { - struct tcp_metrics_block __rcu *tcpm_next; -- possible_net_t tcpm_net; -+ struct net *tcpm_net; - struct inetpeer_addr tcpm_saddr; - struct inetpeer_addr tcpm_daddr; - unsigned long tcpm_stamp; -@@ -51,34 +51,38 @@ struct tcp_metrics_block { - struct rcu_head rcu_head; - }; - --static inline struct net *tm_net(struct tcp_metrics_block *tm) -+static inline struct net *tm_net(const struct tcp_metrics_block *tm) - { -- return read_pnet(&tm->tcpm_net); -+ /* Paired with the WRITE_ONCE() in tcpm_new() */ -+ return READ_ONCE(tm->tcpm_net); - } - - static bool tcp_metric_locked(struct tcp_metrics_block *tm, - enum tcp_metric_index idx) - { -- return tm->tcpm_lock & (1 << idx); -+ /* Paired with WRITE_ONCE() in tcpm_suck_dst() */ -+ return READ_ONCE(tm->tcpm_lock) & (1 << idx); - } - --static u32 tcp_metric_get(struct tcp_metrics_block *tm, -+static u32 tcp_metric_get(const struct tcp_metrics_block *tm, - enum tcp_metric_index idx) - { -- return tm->tcpm_vals[idx]; -+ /* Paired with WRITE_ONCE() in tcp_metric_set() */ -+ return READ_ONCE(tm->tcpm_vals[idx]); - } - - static void tcp_metric_set(struct tcp_metrics_block *tm, - enum tcp_metric_index idx, - u32 val) - { -- tm->tcpm_vals[idx] = val; -+ /* Paired with READ_ONCE() in tcp_metric_get() */ -+ WRITE_ONCE(tm->tcpm_vals[idx], val); - } - - static bool addr_same(const struct inetpeer_addr *a, - const struct inetpeer_addr *b) - { -- return inetpeer_addr_cmp(a, b) == 0; -+ return (a->family == b->family) && !inetpeer_addr_cmp(a, b); - } - - struct tcpm_hash_bucket { -@@ -89,6 +93,7 @@ static struct tcpm_hash_bucket *tcp_metrics_hash __read_mostly; - static unsigned int tcp_metrics_hash_log __read_mostly; - - static DEFINE_SPINLOCK(tcp_metrics_lock); -+static DEFINE_SEQLOCK(fastopen_seqlock); - - static void tcpm_suck_dst(struct tcp_metrics_block *tm, - const struct dst_entry *dst, -@@ -97,7 +102,7 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, - u32 msval; - u32 val; - -- tm->tcpm_stamp = jiffies; -+ WRITE_ONCE(tm->tcpm_stamp, jiffies); - - val = 0; - if (dst_metric_locked(dst, RTAX_RTT)) -@@ -110,30 +115,42 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, - val |= 1 << TCP_METRIC_CWND; - if (dst_metric_locked(dst, RTAX_REORDERING)) - val |= 1 << TCP_METRIC_REORDERING; -- tm->tcpm_lock = val; -+ /* Paired with READ_ONCE() in tcp_metric_locked() */ -+ WRITE_ONCE(tm->tcpm_lock, val); - - msval = dst_metric_raw(dst, RTAX_RTT); -- tm->tcpm_vals[TCP_METRIC_RTT] = msval * USEC_PER_MSEC; -+ tcp_metric_set(tm, TCP_METRIC_RTT, msval * USEC_PER_MSEC); - - msval = dst_metric_raw(dst, RTAX_RTTVAR); -- tm->tcpm_vals[TCP_METRIC_RTTVAR] = msval * USEC_PER_MSEC; -- tm->tcpm_vals[TCP_METRIC_SSTHRESH] = dst_metric_raw(dst, RTAX_SSTHRESH); -- tm->tcpm_vals[TCP_METRIC_CWND] = dst_metric_raw(dst, RTAX_CWND); -- tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING); -+ tcp_metric_set(tm, TCP_METRIC_RTTVAR, msval * USEC_PER_MSEC); -+ tcp_metric_set(tm, TCP_METRIC_SSTHRESH, -+ dst_metric_raw(dst, RTAX_SSTHRESH)); -+ tcp_metric_set(tm, TCP_METRIC_CWND, -+ dst_metric_raw(dst, RTAX_CWND)); -+ tcp_metric_set(tm, TCP_METRIC_REORDERING, -+ dst_metric_raw(dst, RTAX_REORDERING)); - if (fastopen_clear) { -+ write_seqlock(&fastopen_seqlock); - tm->tcpm_fastopen.mss = 0; - tm->tcpm_fastopen.syn_loss = 0; - tm->tcpm_fastopen.try_exp = 0; - tm->tcpm_fastopen.cookie.exp = false; - tm->tcpm_fastopen.cookie.len = 0; -+ write_sequnlock(&fastopen_seqlock); - } - } - - #define TCP_METRICS_TIMEOUT (60 * 60 * HZ) - --static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst) -+static void tcpm_check_stamp(struct tcp_metrics_block *tm, -+ const struct dst_entry *dst) - { -- if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT))) -+ unsigned long limit; -+ -+ if (!tm) -+ return; -+ limit = READ_ONCE(tm->tcpm_stamp) + TCP_METRICS_TIMEOUT; -+ if (unlikely(time_after(jiffies, limit))) - tcpm_suck_dst(tm, dst, false); - } - -@@ -174,20 +191,23 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, - oldest = deref_locked(tcp_metrics_hash[hash].chain); - for (tm = deref_locked(oldest->tcpm_next); tm; - tm = deref_locked(tm->tcpm_next)) { -- if (time_before(tm->tcpm_stamp, oldest->tcpm_stamp)) -+ if (time_before(READ_ONCE(tm->tcpm_stamp), -+ READ_ONCE(oldest->tcpm_stamp))) - oldest = tm; - } - tm = oldest; - } else { -- tm = kmalloc(sizeof(*tm), GFP_ATOMIC); -+ tm = kzalloc(sizeof(*tm), GFP_ATOMIC); - if (!tm) - goto out_unlock; - } -- write_pnet(&tm->tcpm_net, net); -+ /* Paired with the READ_ONCE() in tm_net() */ -+ WRITE_ONCE(tm->tcpm_net, net); -+ - tm->tcpm_saddr = *saddr; - tm->tcpm_daddr = *daddr; - -- tcpm_suck_dst(tm, dst, true); -+ tcpm_suck_dst(tm, dst, reclaim); - - if (likely(!reclaim)) { - tm->tcpm_next = tcp_metrics_hash[hash].chain; -@@ -434,7 +454,7 @@ void tcp_update_metrics(struct sock *sk) - tp->reordering); - } - } -- tm->tcpm_stamp = jiffies; -+ WRITE_ONCE(tm->tcpm_stamp, jiffies); - out_unlock: - rcu_read_unlock(); - } -@@ -539,8 +559,6 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst) - return ret; - } - --static DEFINE_SEQLOCK(fastopen_seqlock); -- - void tcp_fastopen_cache_get(struct sock *sk, u16 *mss, - struct tcp_fastopen_cookie *cookie) - { -@@ -647,7 +665,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg, - } - - if (nla_put_msecs(msg, TCP_METRICS_ATTR_AGE, -- jiffies - tm->tcpm_stamp, -+ jiffies - READ_ONCE(tm->tcpm_stamp), - TCP_METRICS_ATTR_PAD) < 0) - goto nla_put_failure; - -@@ -658,7 +676,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg, - if (!nest) - goto nla_put_failure; - for (i = 0; i < TCP_METRIC_MAX_KERNEL + 1; i++) { -- u32 val = tm->tcpm_vals[i]; -+ u32 val = tcp_metric_get(tm, i); - - if (!val) - continue; -diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c -index facdc78a43e5c..27fb5479988af 100644 ---- a/net/ipv6/ip6mr.c -+++ b/net/ipv6/ip6mr.c -@@ -1073,7 +1073,7 @@ static int ip6mr_cache_report(const struct mr_table *mrt, struct sk_buff *pkt, - And all this only to mangle msg->im6_msgtype and - to set msg->im6_mbz to "mbz" :-) - */ -- skb_push(skb, -skb_network_offset(pkt)); -+ __skb_pull(skb, skb_network_offset(pkt)); - - skb_push(skb, sizeof(*msg)); - skb_reset_transport_header(skb); -diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c -index 4651aaf70db4f..4d5a27dd9a4b2 100644 ---- a/net/ipv6/ping.c -+++ b/net/ipv6/ping.c -@@ -120,7 +120,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - - ipcm6_init_sk(&ipc6, np); - ipc6.sockc.tsflags = sk->sk_tsflags; -- ipc6.sockc.mark = sk->sk_mark; -+ ipc6.sockc.mark = READ_ONCE(sk->sk_mark); - - fl6.flowi6_oif = oif; - -diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c -index 33852fc38ad91..df3abd9e5237c 100644 ---- a/net/ipv6/raw.c -+++ b/net/ipv6/raw.c -@@ -612,7 +612,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length, - skb_reserve(skb, hlen); - - skb->protocol = htons(ETH_P_IPV6); -- skb->priority = sk->sk_priority; -+ skb->priority = READ_ONCE(sk->sk_priority); - skb->mark = sockc->mark; - skb->tstamp = sockc->transmit_time; - -@@ -772,12 +772,12 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - */ - memset(&fl6, 0, sizeof(fl6)); - -- fl6.flowi6_mark = sk->sk_mark; -+ fl6.flowi6_mark = READ_ONCE(sk->sk_mark); - fl6.flowi6_uid = sk->sk_uid; - - ipcm6_init(&ipc6); - ipc6.sockc.tsflags = sk->sk_tsflags; -- ipc6.sockc.mark = sk->sk_mark; -+ ipc6.sockc.mark = fl6.flowi6_mark; - - if (sin6) { - if (addr_len < SIN6_LEN_RFC2133) -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 0b060cb8681f0..960ab43a49c46 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -2952,7 +2952,8 @@ void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu) - if (!oif && skb->dev) - oif = l3mdev_master_ifindex(skb->dev); - -- ip6_update_pmtu(skb, sock_net(sk), mtu, oif, sk->sk_mark, sk->sk_uid); -+ ip6_update_pmtu(skb, sock_net(sk), mtu, oif, READ_ONCE(sk->sk_mark), -+ sk->sk_uid); - - dst = __sk_dst_get(sk); - if (!dst || !dst->obsolete || -@@ -3173,8 +3174,8 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif) - - void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk) - { -- ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, sk->sk_mark, -- sk->sk_uid); -+ ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if, -+ READ_ONCE(sk->sk_mark), sk->sk_uid); - } - EXPORT_SYMBOL_GPL(ip6_sk_redirect); - -diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c -index d9253aa764fae..4bdd356bb5c46 100644 ---- a/net/ipv6/tcp_ipv6.c -+++ b/net/ipv6/tcp_ipv6.c -@@ -567,8 +567,8 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst, - opt = ireq->ipv6_opt; - if (!opt) - opt = rcu_dereference(np->opt); -- err = ip6_xmit(sk, skb, fl6, skb->mark ? : sk->sk_mark, opt, -- tclass, sk->sk_priority); -+ err = ip6_xmit(sk, skb, fl6, skb->mark ? : READ_ONCE(sk->sk_mark), -+ opt, tclass, sk->sk_priority); - rcu_read_unlock(); - err = net_xmit_eval(err); - } -@@ -943,7 +943,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 - if (sk->sk_state == TCP_TIME_WAIT) - mark = inet_twsk(sk)->tw_mark; - else -- mark = sk->sk_mark; -+ mark = READ_ONCE(sk->sk_mark); - skb_set_delivery_time(buff, tcp_transmit_time(sk), true); - } - if (txhash) { -@@ -1132,7 +1132,8 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, - tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, - READ_ONCE(req->ts_recent), sk->sk_bound_dev_if, - tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index), -- ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority, -+ ipv6_get_dsfield(ipv6_hdr(skb)), 0, -+ READ_ONCE(sk->sk_priority), - READ_ONCE(tcp_rsk(req)->txhash)); - } - -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 04f1d696503cd..27348172b25b9 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -622,7 +622,7 @@ int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, - if (type == NDISC_REDIRECT) { - if (tunnel) { - ip6_redirect(skb, sock_net(sk), inet6_iif(skb), -- sk->sk_mark, sk->sk_uid); -+ READ_ONCE(sk->sk_mark), sk->sk_uid); - } else { - ip6_sk_redirect(skb, sk); - } -@@ -1350,7 +1350,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - ipcm6_init(&ipc6); - ipc6.gso_size = READ_ONCE(up->gso_size); - ipc6.sockc.tsflags = sk->sk_tsflags; -- ipc6.sockc.mark = sk->sk_mark; -+ ipc6.sockc.mark = READ_ONCE(sk->sk_mark); - - /* destination address check */ - if (sin6) { -diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c -index 5137ea1861ce2..bce4132b0a5c8 100644 ---- a/net/l2tp/l2tp_ip6.c -+++ b/net/l2tp/l2tp_ip6.c -@@ -519,7 +519,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - /* Get and verify the address */ - memset(&fl6, 0, sizeof(fl6)); - -- fl6.flowi6_mark = sk->sk_mark; -+ fl6.flowi6_mark = READ_ONCE(sk->sk_mark); - fl6.flowi6_uid = sk->sk_uid; - - ipcm6_init(&ipc6); -diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c -index 696ba398d699a..937bd4c556151 100644 ---- a/net/mptcp/sockopt.c -+++ b/net/mptcp/sockopt.c -@@ -102,7 +102,7 @@ static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, in - break; - case SO_MARK: - if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) { -- ssk->sk_mark = sk->sk_mark; -+ WRITE_ONCE(ssk->sk_mark, sk->sk_mark); - sk_dst_reset(ssk); - } - break; -diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c -index 49a5348a6a14f..777561b71fcbd 100644 ---- a/net/netfilter/nft_socket.c -+++ b/net/netfilter/nft_socket.c -@@ -107,7 +107,7 @@ static void nft_socket_eval(const struct nft_expr *expr, - break; - case NFT_SOCKET_MARK: - if (sk_fullsock(sk)) { -- *dest = sk->sk_mark; -+ *dest = READ_ONCE(sk->sk_mark); - } else { - regs->verdict.code = NFT_BREAK; - return; -diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c -index 7013f55f05d1e..76e01f292aaff 100644 ---- a/net/netfilter/xt_socket.c -+++ b/net/netfilter/xt_socket.c -@@ -77,7 +77,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, - - if (info->flags & XT_SOCKET_RESTORESKMARK && !wildcard && - transparent && sk_fullsock(sk)) -- pskb->mark = sk->sk_mark; -+ pskb->mark = READ_ONCE(sk->sk_mark); - - if (sk != skb->sk) - sock_gen_put(sk); -@@ -138,7 +138,7 @@ socket_mt6_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par) - - if (info->flags & XT_SOCKET_RESTORESKMARK && !wildcard && - transparent && sk_fullsock(sk)) -- pskb->mark = sk->sk_mark; -+ pskb->mark = READ_ONCE(sk->sk_mark); - - if (sk != skb->sk) - sock_gen_put(sk); -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 6ab9d5b543387..1681068400733 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -2052,8 +2052,8 @@ retry: - - skb->protocol = proto; - skb->dev = dev; -- skb->priority = sk->sk_priority; -- skb->mark = sk->sk_mark; -+ skb->priority = READ_ONCE(sk->sk_priority); -+ skb->mark = READ_ONCE(sk->sk_mark); - skb->tstamp = sockc.transmit_time; - - skb_setup_tx_timestamp(skb, sockc.tsflags); -@@ -2575,8 +2575,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, - - skb->protocol = proto; - skb->dev = dev; -- skb->priority = po->sk.sk_priority; -- skb->mark = po->sk.sk_mark; -+ skb->priority = READ_ONCE(po->sk.sk_priority); -+ skb->mark = READ_ONCE(po->sk.sk_mark); - skb->tstamp = sockc->transmit_time; - skb_setup_tx_timestamp(skb, sockc->tsflags); - skb_zcopy_set_nouarg(skb, ph.raw); -@@ -2978,7 +2978,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) - goto out_unlock; - - sockcm_init(&sockc, sk); -- sockc.mark = sk->sk_mark; -+ sockc.mark = READ_ONCE(sk->sk_mark); - if (msg->msg_controllen) { - err = sock_cmsg_send(sk, msg, &sockc); - if (unlikely(err)) -@@ -3052,7 +3052,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) - - skb->protocol = proto; - skb->dev = dev; -- skb->priority = sk->sk_priority; -+ skb->priority = READ_ONCE(sk->sk_priority); - skb->mark = sockc.mark; - skb->tstamp = sockc.transmit_time; - -diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c -index 1212b057b129c..6160ef7d646ac 100644 ---- a/net/sched/cls_fw.c -+++ b/net/sched/cls_fw.c -@@ -265,7 +265,6 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, - return -ENOBUFS; - - fnew->id = f->id; -- fnew->res = f->res; - fnew->ifindex = f->ifindex; - fnew->tp = f->tp; - -diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c -index 9e43b929d4ca4..306188bf2d1ff 100644 ---- a/net/sched/cls_route.c -+++ b/net/sched/cls_route.c -@@ -511,7 +511,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, - if (fold) { - f->id = fold->id; - f->iif = fold->iif; -- f->res = fold->res; - f->handle = fold->handle; - - f->tp = fold->tp; -diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c -index 1280736a7b92e..ba93e2a6bdbb4 100644 ---- a/net/sched/cls_u32.c -+++ b/net/sched/cls_u32.c -@@ -824,7 +824,6 @@ static struct tc_u_knode *u32_init_knode(struct net *net, struct tcf_proto *tp, - - new->ifindex = n->ifindex; - new->fshift = n->fshift; -- new->res = n->res; - new->flags = n->flags; - RCU_INIT_POINTER(new->ht_down, ht); - -@@ -1022,18 +1021,62 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, - return -EINVAL; - } - -+ /* At this point, we need to derive the new handle that will be used to -+ * uniquely map the identity of this table match entry. The -+ * identity of the entry that we need to construct is 32 bits made of: -+ * htid(12b):bucketid(8b):node/entryid(12b) -+ * -+ * At this point _we have the table(ht)_ in which we will insert this -+ * entry. We carry the table's id in variable "htid". -+ * Note that earlier code picked the ht selection either by a) the user -+ * providing the htid specified via TCA_U32_HASH attribute or b) when -+ * no such attribute is passed then the root ht, is default to at ID -+ * 0x[800][00][000]. Rule: the root table has a single bucket with ID 0. -+ * If OTOH the user passed us the htid, they may also pass a bucketid of -+ * choice. 0 is fine. For example a user htid is 0x[600][01][000] it is -+ * indicating hash bucketid of 1. Rule: the entry/node ID _cannot_ be -+ * passed via the htid, so even if it was non-zero it will be ignored. -+ * -+ * We may also have a handle, if the user passed one. The handle also -+ * carries the same addressing of htid(12b):bucketid(8b):node/entryid(12b). -+ * Rule: the bucketid on the handle is ignored even if one was passed; -+ * rather the value on "htid" is always assumed to be the bucketid. -+ */ - if (handle) { -+ /* Rule: The htid from handle and tableid from htid must match */ - if (TC_U32_HTID(handle) && TC_U32_HTID(handle ^ htid)) { - NL_SET_ERR_MSG_MOD(extack, "Handle specified hash table address mismatch"); - return -EINVAL; - } -- handle = htid | TC_U32_NODE(handle); -- err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, handle, -- GFP_KERNEL); -- if (err) -- return err; -- } else -+ /* Ok, so far we have a valid htid(12b):bucketid(8b) but we -+ * need to finalize the table entry identification with the last -+ * part - the node/entryid(12b)). Rule: Nodeid _cannot be 0_ for -+ * entries. Rule: nodeid of 0 is reserved only for tables(see -+ * earlier code which processes TC_U32_DIVISOR attribute). -+ * Rule: The nodeid can only be derived from the handle (and not -+ * htid). -+ * Rule: if the handle specified zero for the node id example -+ * 0x60000000, then pick a new nodeid from the pool of IDs -+ * this hash table has been allocating from. -+ * If OTOH it is specified (i.e for example the user passed a -+ * handle such as 0x60000123), then we use it generate our final -+ * handle which is used to uniquely identify the match entry. -+ */ -+ if (!TC_U32_NODE(handle)) { -+ handle = gen_new_kid(ht, htid); -+ } else { -+ handle = htid | TC_U32_NODE(handle); -+ err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, -+ handle, GFP_KERNEL); -+ if (err) -+ return err; -+ } -+ } else { -+ /* The user did not give us a handle; lets just generate one -+ * from the table's pool of nodeids. -+ */ - handle = gen_new_kid(ht, htid); -+ } - - if (tb[TCA_U32_SEL] == NULL) { - NL_SET_ERR_MSG_MOD(extack, "Selector not specified"); -diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c -index a274a9332f333..8d5eebb2dd1b1 100644 ---- a/net/sched/sch_taprio.c -+++ b/net/sched/sch_taprio.c -@@ -769,6 +769,11 @@ static const struct nla_policy taprio_tc_policy[TCA_TAPRIO_TC_ENTRY_MAX + 1] = { - [TCA_TAPRIO_TC_ENTRY_MAX_SDU] = { .type = NLA_U32 }, - }; - -+static struct netlink_range_validation_signed taprio_cycle_time_range = { -+ .min = 0, -+ .max = INT_MAX, -+}; -+ - static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = { - [TCA_TAPRIO_ATTR_PRIOMAP] = { - .len = sizeof(struct tc_mqprio_qopt) -@@ -777,7 +782,8 @@ static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = { - [TCA_TAPRIO_ATTR_SCHED_BASE_TIME] = { .type = NLA_S64 }, - [TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY] = { .type = NLA_NESTED }, - [TCA_TAPRIO_ATTR_SCHED_CLOCKID] = { .type = NLA_S32 }, -- [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME] = { .type = NLA_S64 }, -+ [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME] = -+ NLA_POLICY_FULL_RANGE_SIGNED(NLA_S64, &taprio_cycle_time_range), - [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION] = { .type = NLA_S64 }, - [TCA_TAPRIO_ATTR_FLAGS] = { .type = NLA_U32 }, - [TCA_TAPRIO_ATTR_TXTIME_DELAY] = { .type = NLA_U32 }, -@@ -913,6 +919,11 @@ static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb, - return -EINVAL; - } - -+ if (cycle < 0 || cycle > INT_MAX) { -+ NL_SET_ERR_MSG(extack, "'cycle_time' is too big"); -+ return -EINVAL; -+ } -+ - new->cycle_time = cycle; - } - -@@ -1110,7 +1121,7 @@ static void setup_txtime(struct taprio_sched *q, - struct sched_gate_list *sched, ktime_t base) - { - struct sched_entry *entry; -- u32 interval = 0; -+ u64 interval = 0; - - list_for_each_entry(entry, &sched->entries, list) { - entry->next_txtime = ktime_add_ns(base, interval); -diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c -index 02d1daae77397..5ae0a54a823b5 100644 ---- a/net/smc/af_smc.c -+++ b/net/smc/af_smc.c -@@ -447,7 +447,7 @@ static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk, - nsk->sk_rcvbuf = osk->sk_rcvbuf; - nsk->sk_sndtimeo = osk->sk_sndtimeo; - nsk->sk_rcvtimeo = osk->sk_rcvtimeo; -- nsk->sk_mark = osk->sk_mark; -+ nsk->sk_mark = READ_ONCE(osk->sk_mark); - nsk->sk_priority = osk->sk_priority; - nsk->sk_rcvlowat = osk->sk_rcvlowat; - nsk->sk_bound_dev_if = osk->sk_bound_dev_if; -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index 5b19b6c53a2cb..78fa620a63981 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -779,7 +779,7 @@ static int unix_set_peek_off(struct sock *sk, int val) - if (mutex_lock_interruptible(&u->iolock)) - return -EINTR; - -- sk->sk_peek_off = val; -+ WRITE_ONCE(sk->sk_peek_off, val); - mutex_unlock(&u->iolock); - - return 0; -diff --git a/net/wireless/scan.c b/net/wireless/scan.c -index efe9283e98935..e5c1510c098fd 100644 ---- a/net/wireless/scan.c -+++ b/net/wireless/scan.c -@@ -643,7 +643,7 @@ static int cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies, - - ret = cfg80211_calc_short_ssid(ies, &ssid_elem, &s_ssid_tmp); - if (ret) -- return ret; -+ return 0; - - /* RNR IE may contain more than one NEIGHBOR_AP_INFO */ - while (pos + sizeof(*ap_info) <= end) { -diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c -index 371d269d22fa0..22bf10ffbf2d1 100644 ---- a/net/xdp/xsk.c -+++ b/net/xdp/xsk.c -@@ -504,7 +504,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs, - - skb->dev = dev; - skb->priority = xs->sk.sk_priority; -- skb->mark = xs->sk.sk_mark; -+ skb->mark = READ_ONCE(xs->sk.sk_mark); - skb_shinfo(skb)->destructor_arg = (void *)(long)desc->addr; - skb->destructor = xsk_destruct_skb; - -diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c -index 7b1b93584bdbe..e65de78cb61bf 100644 ---- a/net/xfrm/xfrm_policy.c -+++ b/net/xfrm/xfrm_policy.c -@@ -2174,7 +2174,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, - - match = xfrm_selector_match(&pol->selector, fl, family); - if (match) { -- if ((sk->sk_mark & pol->mark.m) != pol->mark.v || -+ if ((READ_ONCE(sk->sk_mark) & pol->mark.m) != pol->mark.v || - pol->if_id != if_id) { - pol = NULL; - goto out; -diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h -index c48bc284214ab..fdb4e11df3bd3 100644 ---- a/rust/bindings/bindings_helper.h -+++ b/rust/bindings/bindings_helper.h -@@ -9,5 +9,6 @@ - #include - - /* `bindgen` gets confused at certain things. */ -+const size_t BINDINGS_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN; - const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL; - const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO; -diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs -index 397a3dd57a9b1..9363b527be664 100644 ---- a/rust/kernel/allocator.rs -+++ b/rust/kernel/allocator.rs -@@ -9,6 +9,36 @@ use crate::bindings; - - struct KernelAllocator; - -+/// Calls `krealloc` with a proper size to alloc a new object aligned to `new_layout`'s alignment. -+/// -+/// # Safety -+/// -+/// - `ptr` can be either null or a pointer which has been allocated by this allocator. -+/// - `new_layout` must have a non-zero size. -+unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, flags: bindings::gfp_t) -> *mut u8 { -+ // Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. -+ let layout = new_layout.pad_to_align(); -+ -+ let mut size = layout.size(); -+ -+ if layout.align() > bindings::BINDINGS_ARCH_SLAB_MINALIGN { -+ // The alignment requirement exceeds the slab guarantee, thus try to enlarge the size -+ // to use the "power-of-two" size/alignment guarantee (see comments in `kmalloc()` for -+ // more information). -+ // -+ // Note that `layout.size()` (after padding) is guaranteed to be a multiple of -+ // `layout.align()`, so `next_power_of_two` gives enough alignment guarantee. -+ size = size.next_power_of_two(); -+ } -+ -+ // SAFETY: -+ // - `ptr` is either null or a pointer returned from a previous `k{re}alloc()` by the -+ // function safety requirement. -+ // - `size` is greater than 0 since it's either a `layout.size()` (which cannot be zero -+ // according to the function safety requirement) or a result from `next_power_of_two()`. -+ unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags) as *mut u8 } -+} -+ - unsafe impl GlobalAlloc for KernelAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - // `krealloc()` is used instead of `kmalloc()` because the latter is -@@ -30,10 +60,20 @@ static ALLOCATOR: KernelAllocator = KernelAllocator; - // to extract the object file that has them from the archive. For the moment, - // let's generate them ourselves instead. - // -+// Note: Although these are *safe* functions, they are called by the compiler -+// with parameters that obey the same `GlobalAlloc` function safety -+// requirements: size and align should form a valid layout, and size is -+// greater than 0. -+// - // Note that `#[no_mangle]` implies exported too, nowadays. - #[no_mangle] --fn __rust_alloc(size: usize, _align: usize) -> *mut u8 { -- unsafe { bindings::krealloc(core::ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 } -+fn __rust_alloc(size: usize, align: usize) -> *mut u8 { -+ // SAFETY: See assumption above. -+ let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; -+ -+ // SAFETY: `ptr::null_mut()` is null, per assumption above the size of `layout` is greater -+ // than 0. -+ unsafe { krealloc_aligned(ptr::null_mut(), layout, bindings::GFP_KERNEL) } - } - - #[no_mangle] -@@ -42,23 +82,27 @@ fn __rust_dealloc(ptr: *mut u8, _size: usize, _align: usize) { - } - - #[no_mangle] --fn __rust_realloc(ptr: *mut u8, _old_size: usize, _align: usize, new_size: usize) -> *mut u8 { -- unsafe { -- bindings::krealloc( -- ptr as *const core::ffi::c_void, -- new_size, -- bindings::GFP_KERNEL, -- ) as *mut u8 -- } -+fn __rust_realloc(ptr: *mut u8, _old_size: usize, align: usize, new_size: usize) -> *mut u8 { -+ // SAFETY: See assumption above. -+ let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, align) }; -+ -+ // SAFETY: Per assumption above, `ptr` is allocated by `__rust_*` before, and the size of -+ // `new_layout` is greater than 0. -+ unsafe { krealloc_aligned(ptr, new_layout, bindings::GFP_KERNEL) } - } - - #[no_mangle] --fn __rust_alloc_zeroed(size: usize, _align: usize) -> *mut u8 { -+fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 { -+ // SAFETY: See assumption above. -+ let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; -+ -+ // SAFETY: `ptr::null_mut()` is null, per assumption above the size of `layout` is greater -+ // than 0. - unsafe { -- bindings::krealloc( -- core::ptr::null(), -- size, -+ krealloc_aligned( -+ ptr::null_mut(), -+ layout, - bindings::GFP_KERNEL | bindings::__GFP_ZERO, -- ) as *mut u8 -+ ) - } - } -diff --git a/tools/perf/tests/shell/test_uprobe_from_different_cu.sh b/tools/perf/tests/shell/test_uprobe_from_different_cu.sh -index 00d2e0e2e0c28..319f36ebb9a40 100644 ---- a/tools/perf/tests/shell/test_uprobe_from_different_cu.sh -+++ b/tools/perf/tests/shell/test_uprobe_from_different_cu.sh -@@ -4,6 +4,12 @@ - - set -e - -+# skip if there's no gcc -+if ! [ -x "$(command -v gcc)" ]; then -+ echo "failed: no gcc compiler" -+ exit 2 -+fi -+ - temp_dir=$(mktemp -d /tmp/perf-uprobe-different-cu-sh.XXXXXXXXXX) - - cleanup() -@@ -11,7 +17,7 @@ cleanup() - trap - EXIT TERM INT - if [[ "${temp_dir}" =~ ^/tmp/perf-uprobe-different-cu-sh.*$ ]]; then - echo "--- Cleaning up ---" -- perf probe -x ${temp_dir}/testfile -d foo -+ perf probe -x ${temp_dir}/testfile -d foo || true - rm -f "${temp_dir}/"* - rmdir "${temp_dir}" - fi -diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c -index 4177f9507bbee..b736a5169aad0 100644 ---- a/tools/testing/selftests/rseq/rseq.c -+++ b/tools/testing/selftests/rseq/rseq.c -@@ -32,9 +32,17 @@ - #include "../kselftest.h" - #include "rseq.h" - --static const ptrdiff_t *libc_rseq_offset_p; --static const unsigned int *libc_rseq_size_p; --static const unsigned int *libc_rseq_flags_p; -+/* -+ * Define weak versions to play nice with binaries that are statically linked -+ * against a libc that doesn't support registering its own rseq. -+ */ -+__weak ptrdiff_t __rseq_offset; -+__weak unsigned int __rseq_size; -+__weak unsigned int __rseq_flags; -+ -+static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; -+static const unsigned int *libc_rseq_size_p = &__rseq_size; -+static const unsigned int *libc_rseq_flags_p = &__rseq_flags; - - /* Offset from the thread pointer to the rseq area. */ - ptrdiff_t rseq_offset; -@@ -108,9 +116,17 @@ int rseq_unregister_current_thread(void) - static __attribute__((constructor)) - void rseq_init(void) - { -- libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); -- libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); -- libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); -+ /* -+ * If the libc's registered rseq size isn't already valid, it may be -+ * because the binary is dynamically linked and not necessarily due to -+ * libc not having registered a restartable sequence. Try to find the -+ * symbols if that's the case. -+ */ -+ if (!*libc_rseq_size_p) { -+ libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); -+ libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); -+ libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); -+ } - if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p && - *libc_rseq_size_p != 0) { - /* rseq registration owned by glibc */ -diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json -index a44455372646a..08d4861c2e782 100644 ---- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json -+++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json -@@ -131,5 +131,30 @@ - "teardown": [ - "echo \"1\" > /sys/bus/netdevsim/del_device" - ] -+ }, -+ { -+ "id": "3e1e", -+ "name": "Add taprio Qdisc with an invalid cycle-time", -+ "category": [ -+ "qdisc", -+ "taprio" -+ ], -+ "plugins": { -+ "requires": "nsPlugin" -+ }, -+ "setup": [ -+ "echo \"1 1 8\" > /sys/bus/netdevsim/new_device", -+ "$TC qdisc add dev $ETH root handle 1: taprio num_tc 3 map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 queues 1@0 1@0 1@0 base-time 1000000000 sched-entry S 01 300000 flags 0x1 clockid CLOCK_TAI cycle-time 4294967296 || /bin/true", -+ "$IP link set dev $ETH up", -+ "$IP addr add 10.10.10.10/24 dev $ETH" -+ ], -+ "cmdUnderTest": "/bin/true", -+ "expExitCode": "0", -+ "verifyCmd": "$TC qdisc show dev $ETH", -+ "matchPattern": "qdisc taprio 1: root refcnt", -+ "matchCount": "0", -+ "teardown": [ -+ "echo \"1\" > /sys/bus/netdevsim/del_device" -+ ] - } - ] diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.45-46.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.45-46.patch deleted file mode 100644 index 5e1f1095e39f..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.45-46.patch +++ /dev/null @@ -1,6914 +0,0 @@ -diff --git a/Makefile b/Makefile -index 82c958299e982..bdb965177db52 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 45 -+SUBLEVEL = 46 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c -index 33bf3a6270027..45a920ba4921d 100644 ---- a/arch/alpha/kernel/setup.c -+++ b/arch/alpha/kernel/setup.c -@@ -385,8 +385,7 @@ setup_memory(void *kernel_end) - #endif /* CONFIG_BLK_DEV_INITRD */ - } - --int __init --page_is_ram(unsigned long pfn) -+int page_is_ram(unsigned long pfn) - { - struct memclust_struct * cluster; - struct memdesc_struct * memdesc; -diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig -index 270742cc3ca49..e737dc8cd660c 100644 ---- a/arch/loongarch/Kconfig -+++ b/arch/loongarch/Kconfig -@@ -10,7 +10,6 @@ config LOONGARCH - select ARCH_ENABLE_MEMORY_HOTPLUG - select ARCH_ENABLE_MEMORY_HOTREMOVE - select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI -- select ARCH_HAS_CPU_FINALIZE_INIT - select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - select ARCH_HAS_PTE_SPECIAL - select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST -diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c -index 29725b37b35ca..ae436def7ee98 100644 ---- a/arch/loongarch/kernel/setup.c -+++ b/arch/loongarch/kernel/setup.c -@@ -12,7 +12,6 @@ - */ - #include - #include --#include - #include - #include - #include -@@ -81,11 +80,6 @@ const char *get_system_type(void) - return "generic-loongson-machine"; - } - --void __init arch_cpu_finalize_init(void) --{ -- alternative_instructions(); --} -- - static const char *dmi_string_parse(const struct dmi_header *dm, u8 s) - { - const u8 *bp = ((u8 *) dm) + dm->length; -diff --git a/arch/riscv/include/asm/mmio.h b/arch/riscv/include/asm/mmio.h -index aff6c33ab0c08..4c58ee7f95ecf 100644 ---- a/arch/riscv/include/asm/mmio.h -+++ b/arch/riscv/include/asm/mmio.h -@@ -101,9 +101,9 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) - * Relaxed I/O memory access primitives. These follow the Device memory - * ordering rules but do not guarantee any ordering relative to Normal memory - * accesses. These are defined to order the indicated access (either a read or -- * write) with all other I/O memory accesses. Since the platform specification -- * defines that all I/O regions are strongly ordered on channel 2, no explicit -- * fences are required to enforce this ordering. -+ * write) with all other I/O memory accesses to the same peripheral. Since the -+ * platform specification defines that all I/O regions are strongly ordered on -+ * channel 0, no explicit fences are required to enforce this ordering. - */ - /* FIXME: These are now the same as asm-generic */ - #define __io_rbr() do {} while (0) -@@ -125,14 +125,14 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) - #endif - - /* -- * I/O memory access primitives. Reads are ordered relative to any -- * following Normal memory access. Writes are ordered relative to any prior -- * Normal memory access. The memory barriers here are necessary as RISC-V -+ * I/O memory access primitives. Reads are ordered relative to any following -+ * Normal memory read and delay() loop. Writes are ordered relative to any -+ * prior Normal memory write. The memory barriers here are necessary as RISC-V - * doesn't define any ordering between the memory space and the I/O space. - */ - #define __io_br() do {} while (0) --#define __io_ar(v) __asm__ __volatile__ ("fence i,r" : : : "memory") --#define __io_bw() __asm__ __volatile__ ("fence w,o" : : : "memory") -+#define __io_ar(v) ({ __asm__ __volatile__ ("fence i,ir" : : : "memory"); }) -+#define __io_bw() ({ __asm__ __volatile__ ("fence w,o" : : : "memory"); }) - #define __io_aw() mmiowb_set_pending() - - #define readb(c) ({ u8 __v; __io_br(); __v = readb_cpu(c); __io_ar(__v); __v; }) -diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c -index 5372b708fae21..c08bb5c3b3857 100644 ---- a/arch/riscv/kernel/elf_kexec.c -+++ b/arch/riscv/kernel/elf_kexec.c -@@ -281,7 +281,7 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf, - kbuf.buffer = initrd; - kbuf.bufsz = kbuf.memsz = initrd_len; - kbuf.buf_align = PAGE_SIZE; -- kbuf.top_down = false; -+ kbuf.top_down = true; - kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; - ret = kexec_add_buffer(&kbuf); - if (ret) -@@ -425,6 +425,7 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, - * sym, instead of searching the whole relsec. - */ - case R_RISCV_PCREL_HI20: -+ case R_RISCV_CALL_PLT: - case R_RISCV_CALL: - *(u64 *)loc = CLEAN_IMM(UITYPE, *(u64 *)loc) | - ENCODE_UJTYPE_IMM(val - addr); -diff --git a/arch/x86/boot/compressed/idt_64.c b/arch/x86/boot/compressed/idt_64.c -index 6debb816e83dc..3cdf94b414567 100644 ---- a/arch/x86/boot/compressed/idt_64.c -+++ b/arch/x86/boot/compressed/idt_64.c -@@ -63,7 +63,14 @@ void load_stage2_idt(void) - set_idt_entry(X86_TRAP_PF, boot_page_fault); - - #ifdef CONFIG_AMD_MEM_ENCRYPT -- set_idt_entry(X86_TRAP_VC, boot_stage2_vc); -+ /* -+ * Clear the second stage #VC handler in case guest types -+ * needing #VC have not been detected. -+ */ -+ if (sev_status & BIT(1)) -+ set_idt_entry(X86_TRAP_VC, boot_stage2_vc); -+ else -+ set_idt_entry(X86_TRAP_VC, NULL); - #endif - - load_boot_idt(&boot_idt_desc); -diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c -index d63ad8f99f83a..e65f0968e0d9d 100644 ---- a/arch/x86/boot/compressed/sev.c -+++ b/arch/x86/boot/compressed/sev.c -@@ -354,13 +354,46 @@ void sev_enable(struct boot_params *bp) - if (bp) - bp->cc_blob_address = 0; - -+ /* -+ * Do an initial SEV capability check before snp_init() which -+ * loads the CPUID page and the same checks afterwards are done -+ * without the hypervisor and are trustworthy. -+ * -+ * If the HV fakes SEV support, the guest will crash'n'burn -+ * which is good enough. -+ */ -+ -+ /* Check for the SME/SEV support leaf */ -+ eax = 0x80000000; -+ ecx = 0; -+ native_cpuid(&eax, &ebx, &ecx, &edx); -+ if (eax < 0x8000001f) -+ return; -+ -+ /* -+ * Check for the SME/SEV feature: -+ * CPUID Fn8000_001F[EAX] -+ * - Bit 0 - Secure Memory Encryption support -+ * - Bit 1 - Secure Encrypted Virtualization support -+ * CPUID Fn8000_001F[EBX] -+ * - Bits 5:0 - Pagetable bit position used to indicate encryption -+ */ -+ eax = 0x8000001f; -+ ecx = 0; -+ native_cpuid(&eax, &ebx, &ecx, &edx); -+ /* Check whether SEV is supported */ -+ if (!(eax & BIT(1))) -+ return; -+ - /* - * Setup/preliminary detection of SNP. This will be sanity-checked - * against CPUID/MSR values later. - */ - snp = snp_init(bp); - -- /* Check for the SME/SEV support leaf */ -+ /* Now repeat the checks with the SNP CPUID table. */ -+ -+ /* Recheck the SME/SEV support leaf */ - eax = 0x80000000; - ecx = 0; - native_cpuid(&eax, &ebx, &ecx, &edx); -@@ -368,7 +401,7 @@ void sev_enable(struct boot_params *bp) - return; - - /* -- * Check for the SME/SEV feature: -+ * Recheck for the SME/SEV feature: - * CPUID Fn8000_001F[EAX] - * - Bit 0 - Secure Memory Encryption support - * - Bit 1 - Secure Encrypted Virtualization support -diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c -index 311eae30e0894..1288661397f09 100644 ---- a/arch/x86/entry/vdso/vma.c -+++ b/arch/x86/entry/vdso/vma.c -@@ -322,8 +322,8 @@ static unsigned long vdso_addr(unsigned long start, unsigned len) - - /* Round the lowest possible end address up to a PMD boundary. */ - end = (start + len + PMD_SIZE - 1) & PMD_MASK; -- if (end >= TASK_SIZE_MAX) -- end = TASK_SIZE_MAX; -+ if (end >= DEFAULT_MAP_WINDOW) -+ end = DEFAULT_MAP_WINDOW; - end -= len; - - if (end > start) { -diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h -index 45bf26862b99b..94ea13adb724a 100644 ---- a/arch/x86/include/asm/processor.h -+++ b/arch/x86/include/asm/processor.h -@@ -867,4 +867,6 @@ bool arch_is_platform_page(u64 paddr); - #define arch_is_platform_page arch_is_platform_page - #endif - -+extern bool gds_ucode_mitigated(void); -+ - #endif /* _ASM_X86_PROCESSOR_H */ -diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c -index 43910eb55b2e9..239b302973d7a 100644 ---- a/arch/x86/kernel/cpu/amd.c -+++ b/arch/x86/kernel/cpu/amd.c -@@ -73,6 +73,7 @@ static const int amd_erratum_1054[] = - static const int amd_zenbleed[] = - AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x30, 0x0, 0x4f, 0xf), - AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf), -+ AMD_MODEL_RANGE(0x17, 0x90, 0x0, 0x91, 0xf), - AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf)); - - static const int amd_div0[] = -diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S -index fd03f5a1f0ef0..e6939ebb606ab 100644 ---- a/arch/x86/kernel/vmlinux.lds.S -+++ b/arch/x86/kernel/vmlinux.lds.S -@@ -514,11 +514,17 @@ INIT_PER_CPU(irq_stack_backing_store); - - #ifdef CONFIG_CPU_SRSO - /* -- * GNU ld cannot do XOR so do: (A | B) - (A & B) in order to compute the XOR -+ * GNU ld cannot do XOR until 2.41. -+ * https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f6f78318fca803c4907fb8d7f6ded8295f1947b1 -+ * -+ * LLVM lld cannot do XOR until lld-17. -+ * https://github.com/llvm/llvm-project/commit/fae96104d4378166cbe5c875ef8ed808a356f3fb -+ * -+ * Instead do: (A | B) - (A & B) in order to compute the XOR - * of the two function addresses: - */ --. = ASSERT(((srso_untrain_ret_alias | srso_safe_ret_alias) - -- (srso_untrain_ret_alias & srso_safe_ret_alias)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)), -+. = ASSERT(((ABSOLUTE(srso_untrain_ret_alias) | srso_safe_ret_alias) - -+ (ABSOLUTE(srso_untrain_ret_alias) & srso_safe_ret_alias)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)), - "SRSO function pair won't alias"); - #endif - -diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c -index 4cb2e483db533..e0437acb5cf75 100644 ---- a/arch/x86/kvm/svm/sev.c -+++ b/arch/x86/kvm/svm/sev.c -@@ -2410,15 +2410,18 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) - */ - memset(vcpu->arch.regs, 0, sizeof(vcpu->arch.regs)); - -- vcpu->arch.regs[VCPU_REGS_RAX] = ghcb_get_rax_if_valid(ghcb); -- vcpu->arch.regs[VCPU_REGS_RBX] = ghcb_get_rbx_if_valid(ghcb); -- vcpu->arch.regs[VCPU_REGS_RCX] = ghcb_get_rcx_if_valid(ghcb); -- vcpu->arch.regs[VCPU_REGS_RDX] = ghcb_get_rdx_if_valid(ghcb); -- vcpu->arch.regs[VCPU_REGS_RSI] = ghcb_get_rsi_if_valid(ghcb); -+ BUILD_BUG_ON(sizeof(svm->sev_es.valid_bitmap) != sizeof(ghcb->save.valid_bitmap)); -+ memcpy(&svm->sev_es.valid_bitmap, &ghcb->save.valid_bitmap, sizeof(ghcb->save.valid_bitmap)); - -- svm->vmcb->save.cpl = ghcb_get_cpl_if_valid(ghcb); -+ vcpu->arch.regs[VCPU_REGS_RAX] = kvm_ghcb_get_rax_if_valid(svm, ghcb); -+ vcpu->arch.regs[VCPU_REGS_RBX] = kvm_ghcb_get_rbx_if_valid(svm, ghcb); -+ vcpu->arch.regs[VCPU_REGS_RCX] = kvm_ghcb_get_rcx_if_valid(svm, ghcb); -+ vcpu->arch.regs[VCPU_REGS_RDX] = kvm_ghcb_get_rdx_if_valid(svm, ghcb); -+ vcpu->arch.regs[VCPU_REGS_RSI] = kvm_ghcb_get_rsi_if_valid(svm, ghcb); - -- if (ghcb_xcr0_is_valid(ghcb)) { -+ svm->vmcb->save.cpl = kvm_ghcb_get_cpl_if_valid(svm, ghcb); -+ -+ if (kvm_ghcb_xcr0_is_valid(svm)) { - vcpu->arch.xcr0 = ghcb_get_xcr0(ghcb); - kvm_update_cpuid_runtime(vcpu); - } -@@ -2429,14 +2432,21 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm) - control->exit_code_hi = upper_32_bits(exit_code); - control->exit_info_1 = ghcb_get_sw_exit_info_1(ghcb); - control->exit_info_2 = ghcb_get_sw_exit_info_2(ghcb); -+ svm->sev_es.sw_scratch = kvm_ghcb_get_sw_scratch_if_valid(svm, ghcb); - - /* Clear the valid entries fields */ - memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); - } - -+static u64 kvm_ghcb_get_sw_exit_code(struct vmcb_control_area *control) -+{ -+ return (((u64)control->exit_code_hi) << 32) | control->exit_code; -+} -+ - static int sev_es_validate_vmgexit(struct vcpu_svm *svm) - { -- struct kvm_vcpu *vcpu; -+ struct vmcb_control_area *control = &svm->vmcb->control; -+ struct kvm_vcpu *vcpu = &svm->vcpu; - struct ghcb *ghcb; - u64 exit_code; - u64 reason; -@@ -2447,7 +2457,7 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) - * Retrieve the exit code now even though it may not be marked valid - * as it could help with debugging. - */ -- exit_code = ghcb_get_sw_exit_code(ghcb); -+ exit_code = kvm_ghcb_get_sw_exit_code(control); - - /* Only GHCB Usage code 0 is supported */ - if (ghcb->ghcb_usage) { -@@ -2457,56 +2467,56 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) - - reason = GHCB_ERR_MISSING_INPUT; - -- if (!ghcb_sw_exit_code_is_valid(ghcb) || -- !ghcb_sw_exit_info_1_is_valid(ghcb) || -- !ghcb_sw_exit_info_2_is_valid(ghcb)) -+ if (!kvm_ghcb_sw_exit_code_is_valid(svm) || -+ !kvm_ghcb_sw_exit_info_1_is_valid(svm) || -+ !kvm_ghcb_sw_exit_info_2_is_valid(svm)) - goto vmgexit_err; - -- switch (ghcb_get_sw_exit_code(ghcb)) { -+ switch (exit_code) { - case SVM_EXIT_READ_DR7: - break; - case SVM_EXIT_WRITE_DR7: -- if (!ghcb_rax_is_valid(ghcb)) -+ if (!kvm_ghcb_rax_is_valid(svm)) - goto vmgexit_err; - break; - case SVM_EXIT_RDTSC: - break; - case SVM_EXIT_RDPMC: -- if (!ghcb_rcx_is_valid(ghcb)) -+ if (!kvm_ghcb_rcx_is_valid(svm)) - goto vmgexit_err; - break; - case SVM_EXIT_CPUID: -- if (!ghcb_rax_is_valid(ghcb) || -- !ghcb_rcx_is_valid(ghcb)) -+ if (!kvm_ghcb_rax_is_valid(svm) || -+ !kvm_ghcb_rcx_is_valid(svm)) - goto vmgexit_err; -- if (ghcb_get_rax(ghcb) == 0xd) -- if (!ghcb_xcr0_is_valid(ghcb)) -+ if (vcpu->arch.regs[VCPU_REGS_RAX] == 0xd) -+ if (!kvm_ghcb_xcr0_is_valid(svm)) - goto vmgexit_err; - break; - case SVM_EXIT_INVD: - break; - case SVM_EXIT_IOIO: -- if (ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_STR_MASK) { -- if (!ghcb_sw_scratch_is_valid(ghcb)) -+ if (control->exit_info_1 & SVM_IOIO_STR_MASK) { -+ if (!kvm_ghcb_sw_scratch_is_valid(svm)) - goto vmgexit_err; - } else { -- if (!(ghcb_get_sw_exit_info_1(ghcb) & SVM_IOIO_TYPE_MASK)) -- if (!ghcb_rax_is_valid(ghcb)) -+ if (!(control->exit_info_1 & SVM_IOIO_TYPE_MASK)) -+ if (!kvm_ghcb_rax_is_valid(svm)) - goto vmgexit_err; - } - break; - case SVM_EXIT_MSR: -- if (!ghcb_rcx_is_valid(ghcb)) -+ if (!kvm_ghcb_rcx_is_valid(svm)) - goto vmgexit_err; -- if (ghcb_get_sw_exit_info_1(ghcb)) { -- if (!ghcb_rax_is_valid(ghcb) || -- !ghcb_rdx_is_valid(ghcb)) -+ if (control->exit_info_1) { -+ if (!kvm_ghcb_rax_is_valid(svm) || -+ !kvm_ghcb_rdx_is_valid(svm)) - goto vmgexit_err; - } - break; - case SVM_EXIT_VMMCALL: -- if (!ghcb_rax_is_valid(ghcb) || -- !ghcb_cpl_is_valid(ghcb)) -+ if (!kvm_ghcb_rax_is_valid(svm) || -+ !kvm_ghcb_cpl_is_valid(svm)) - goto vmgexit_err; - break; - case SVM_EXIT_RDTSCP: -@@ -2514,19 +2524,19 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) - case SVM_EXIT_WBINVD: - break; - case SVM_EXIT_MONITOR: -- if (!ghcb_rax_is_valid(ghcb) || -- !ghcb_rcx_is_valid(ghcb) || -- !ghcb_rdx_is_valid(ghcb)) -+ if (!kvm_ghcb_rax_is_valid(svm) || -+ !kvm_ghcb_rcx_is_valid(svm) || -+ !kvm_ghcb_rdx_is_valid(svm)) - goto vmgexit_err; - break; - case SVM_EXIT_MWAIT: -- if (!ghcb_rax_is_valid(ghcb) || -- !ghcb_rcx_is_valid(ghcb)) -+ if (!kvm_ghcb_rax_is_valid(svm) || -+ !kvm_ghcb_rcx_is_valid(svm)) - goto vmgexit_err; - break; - case SVM_VMGEXIT_MMIO_READ: - case SVM_VMGEXIT_MMIO_WRITE: -- if (!ghcb_sw_scratch_is_valid(ghcb)) -+ if (!kvm_ghcb_sw_scratch_is_valid(svm)) - goto vmgexit_err; - break; - case SVM_VMGEXIT_NMI_COMPLETE: -@@ -2542,8 +2552,6 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) - return 0; - - vmgexit_err: -- vcpu = &svm->vcpu; -- - if (reason == GHCB_ERR_INVALID_USAGE) { - vcpu_unimpl(vcpu, "vmgexit: ghcb usage %#x is not valid\n", - ghcb->ghcb_usage); -@@ -2556,9 +2564,6 @@ vmgexit_err: - dump_ghcb(svm); - } - -- /* Clear the valid entries fields */ -- memset(ghcb->save.valid_bitmap, 0, sizeof(ghcb->save.valid_bitmap)); -- - ghcb_set_sw_exit_info_1(ghcb, 2); - ghcb_set_sw_exit_info_2(ghcb, reason); - -@@ -2579,7 +2584,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm) - */ - if (svm->sev_es.ghcb_sa_sync) { - kvm_write_guest(svm->vcpu.kvm, -- ghcb_get_sw_scratch(svm->sev_es.ghcb), -+ svm->sev_es.sw_scratch, - svm->sev_es.ghcb_sa, - svm->sev_es.ghcb_sa_len); - svm->sev_es.ghcb_sa_sync = false; -@@ -2630,7 +2635,7 @@ static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len) - u64 scratch_gpa_beg, scratch_gpa_end; - void *scratch_va; - -- scratch_gpa_beg = ghcb_get_sw_scratch(ghcb); -+ scratch_gpa_beg = svm->sev_es.sw_scratch; - if (!scratch_gpa_beg) { - pr_err("vmgexit: scratch gpa not provided\n"); - goto e_scratch; -@@ -2844,16 +2849,15 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) - - trace_kvm_vmgexit_enter(vcpu->vcpu_id, ghcb); - -- exit_code = ghcb_get_sw_exit_code(ghcb); -- -+ sev_es_sync_from_ghcb(svm); - ret = sev_es_validate_vmgexit(svm); - if (ret) - return ret; - -- sev_es_sync_from_ghcb(svm); - ghcb_set_sw_exit_info_1(ghcb, 0); - ghcb_set_sw_exit_info_2(ghcb, 0); - -+ exit_code = kvm_ghcb_get_sw_exit_code(control); - switch (exit_code) { - case SVM_VMGEXIT_MMIO_READ: - ret = setup_vmgexit_scratch(svm, true, control->exit_info_2); -diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h -index d0ed3f5952295..62f87492763e0 100644 ---- a/arch/x86/kvm/svm/svm.h -+++ b/arch/x86/kvm/svm/svm.h -@@ -196,10 +196,12 @@ struct vcpu_sev_es_state { - /* SEV-ES support */ - struct sev_es_save_area *vmsa; - struct ghcb *ghcb; -+ u8 valid_bitmap[16]; - struct kvm_host_map ghcb_map; - bool received_first_sipi; - - /* SEV-ES scratch area support */ -+ u64 sw_scratch; - void *ghcb_sa; - u32 ghcb_sa_len; - bool ghcb_sa_sync; -@@ -688,4 +690,28 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm); - void __svm_sev_es_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted); - void __svm_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted); - -+#define DEFINE_KVM_GHCB_ACCESSORS(field) \ -+ static __always_inline bool kvm_ghcb_##field##_is_valid(const struct vcpu_svm *svm) \ -+ { \ -+ return test_bit(GHCB_BITMAP_IDX(field), \ -+ (unsigned long *)&svm->sev_es.valid_bitmap); \ -+ } \ -+ \ -+ static __always_inline u64 kvm_ghcb_get_##field##_if_valid(struct vcpu_svm *svm, struct ghcb *ghcb) \ -+ { \ -+ return kvm_ghcb_##field##_is_valid(svm) ? ghcb->save.field : 0; \ -+ } \ -+ -+DEFINE_KVM_GHCB_ACCESSORS(cpl) -+DEFINE_KVM_GHCB_ACCESSORS(rax) -+DEFINE_KVM_GHCB_ACCESSORS(rcx) -+DEFINE_KVM_GHCB_ACCESSORS(rdx) -+DEFINE_KVM_GHCB_ACCESSORS(rbx) -+DEFINE_KVM_GHCB_ACCESSORS(rsi) -+DEFINE_KVM_GHCB_ACCESSORS(sw_exit_code) -+DEFINE_KVM_GHCB_ACCESSORS(sw_exit_info_1) -+DEFINE_KVM_GHCB_ACCESSORS(sw_exit_info_2) -+DEFINE_KVM_GHCB_ACCESSORS(sw_scratch) -+DEFINE_KVM_GHCB_ACCESSORS(xcr0) -+ - #endif -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index f4b12c3c30a01..1931d3fcbbe09 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -311,8 +311,6 @@ u64 __read_mostly host_xcr0; - - static struct kmem_cache *x86_emulator_cache; - --extern bool gds_ucode_mitigated(void); -- - /* - * When called, it means the previous get/set msr reached an invalid msr. - * Return true if we want to ignore/silent this failed msr access. -diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index dbfa58e799e28..a0e347f6f97eb 100644 ---- a/drivers/acpi/scan.c -+++ b/drivers/acpi/scan.c -@@ -1712,6 +1712,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) - {"BSG1160", }, - {"BSG2150", }, - {"CSC3551", }, -+ {"CSC3556", }, - {"INT33FE", }, - {"INT3515", }, - /* Non-conforming _HID for Cirrus Logic already released */ -diff --git a/drivers/android/binder.c b/drivers/android/binder.c -index e374a8a2da46e..e4a6da81cd4b3 100644 ---- a/drivers/android/binder.c -+++ b/drivers/android/binder.c -@@ -6602,6 +6602,7 @@ err_init_binder_device_failed: - - err_alloc_device_names_failed: - debugfs_remove_recursive(binder_debugfs_dir_entry_root); -+ binder_alloc_shrinker_exit(); - - return ret; - } -diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c -index 4fb89ef067d57..cd87f12733f27 100644 ---- a/drivers/android/binder_alloc.c -+++ b/drivers/android/binder_alloc.c -@@ -1087,6 +1087,12 @@ int binder_alloc_shrinker_init(void) - return ret; - } - -+void binder_alloc_shrinker_exit(void) -+{ -+ unregister_shrinker(&binder_shrinker); -+ list_lru_destroy(&binder_alloc_lru); -+} -+ - /** - * check_buffer() - verify that buffer/offset is safe to access - * @alloc: binder_alloc for this proc -diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h -index 138d1d5af9ce3..dc1e2b01dd64d 100644 ---- a/drivers/android/binder_alloc.h -+++ b/drivers/android/binder_alloc.h -@@ -129,6 +129,7 @@ extern struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc, - int pid); - extern void binder_alloc_init(struct binder_alloc *alloc); - extern int binder_alloc_shrinker_init(void); -+extern void binder_alloc_shrinker_exit(void); - extern void binder_alloc_vma_close(struct binder_alloc *alloc); - extern struct binder_buffer * - binder_alloc_prepare_to_free(struct binder_alloc *alloc, -diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c -index d7ef4d0a7409f..c0759d49fd145 100644 ---- a/drivers/char/tpm/tpm-chip.c -+++ b/drivers/char/tpm/tpm-chip.c -@@ -507,70 +507,6 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip) - return 0; - } - --/* -- * Some AMD fTPM versions may cause stutter -- * https://www.amd.com/en/support/kb/faq/pa-410 -- * -- * Fixes are available in two series of fTPM firmware: -- * 6.x.y.z series: 6.0.18.6 + -- * 3.x.y.z series: 3.57.y.5 + -- */ --#ifdef CONFIG_X86 --static bool tpm_amd_is_rng_defective(struct tpm_chip *chip) --{ -- u32 val1, val2; -- u64 version; -- int ret; -- -- if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) -- return false; -- -- ret = tpm_request_locality(chip); -- if (ret) -- return false; -- -- ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val1, NULL); -- if (ret) -- goto release; -- if (val1 != 0x414D4400U /* AMD */) { -- ret = -ENODEV; -- goto release; -- } -- ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_1, &val1, NULL); -- if (ret) -- goto release; -- ret = tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_2, &val2, NULL); -- --release: -- tpm_relinquish_locality(chip); -- -- if (ret) -- return false; -- -- version = ((u64)val1 << 32) | val2; -- if ((version >> 48) == 6) { -- if (version >= 0x0006000000180006ULL) -- return false; -- } else if ((version >> 48) == 3) { -- if (version >= 0x0003005700000005ULL) -- return false; -- } else { -- return false; -- } -- -- dev_warn(&chip->dev, -- "AMD fTPM version 0x%llx causes system stutter; hwrng disabled\n", -- version); -- -- return true; --} --#else --static inline bool tpm_amd_is_rng_defective(struct tpm_chip *chip) --{ -- return false; --} --#endif /* CONFIG_X86 */ -- - static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) - { - struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng); -@@ -582,10 +518,20 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) - return tpm_get_random(chip, data, max); - } - -+static bool tpm_is_hwrng_enabled(struct tpm_chip *chip) -+{ -+ if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM)) -+ return false; -+ if (tpm_is_firmware_upgrade(chip)) -+ return false; -+ if (chip->flags & TPM_CHIP_FLAG_HWRNG_DISABLED) -+ return false; -+ return true; -+} -+ - static int tpm_add_hwrng(struct tpm_chip *chip) - { -- if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip) || -- tpm_amd_is_rng_defective(chip)) -+ if (!tpm_is_hwrng_enabled(chip)) - return 0; - - snprintf(chip->hwrng_name, sizeof(chip->hwrng_name), -@@ -690,7 +636,7 @@ int tpm_chip_register(struct tpm_chip *chip) - return 0; - - out_hwrng: -- if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip)) -+ if (tpm_is_hwrng_enabled(chip)) - hwrng_unregister(&chip->hwrng); - out_ppi: - tpm_bios_log_teardown(chip); -@@ -715,8 +661,7 @@ EXPORT_SYMBOL_GPL(tpm_chip_register); - void tpm_chip_unregister(struct tpm_chip *chip) - { - tpm_del_legacy_sysfs(chip); -- if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip) && -- !tpm_amd_is_rng_defective(chip)) -+ if (tpm_is_hwrng_enabled(chip)) - hwrng_unregister(&chip->hwrng); - tpm_bios_log_teardown(chip); - if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) -diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c -index cbbedf52607c0..7f7f3bded4535 100644 ---- a/drivers/char/tpm/tpm_crb.c -+++ b/drivers/char/tpm/tpm_crb.c -@@ -463,6 +463,28 @@ static bool crb_req_canceled(struct tpm_chip *chip, u8 status) - return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE; - } - -+static int crb_check_flags(struct tpm_chip *chip) -+{ -+ u32 val; -+ int ret; -+ -+ ret = crb_request_locality(chip, 0); -+ if (ret) -+ return ret; -+ -+ ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val, NULL); -+ if (ret) -+ goto release; -+ -+ if (val == 0x414D4400U /* AMD */) -+ chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED; -+ -+release: -+ crb_relinquish_locality(chip, 0); -+ -+ return ret; -+} -+ - static const struct tpm_class_ops tpm_crb = { - .flags = TPM_OPS_AUTO_STARTUP, - .status = crb_status, -@@ -800,6 +822,14 @@ static int crb_acpi_add(struct acpi_device *device) - chip->acpi_dev_handle = device->handle; - chip->flags = TPM_CHIP_FLAG_TPM2; - -+ rc = tpm_chip_bootstrap(chip); -+ if (rc) -+ goto out; -+ -+ rc = crb_check_flags(chip); -+ if (rc) -+ goto out; -+ - rc = tpm_chip_register(chip); - - out: -diff --git a/drivers/cpuidle/dt_idle_genpd.c b/drivers/cpuidle/dt_idle_genpd.c -index b37165514d4e7..1af63c189039e 100644 ---- a/drivers/cpuidle/dt_idle_genpd.c -+++ b/drivers/cpuidle/dt_idle_genpd.c -@@ -152,6 +152,30 @@ int dt_idle_pd_init_topology(struct device_node *np) - return 0; - } - -+int dt_idle_pd_remove_topology(struct device_node *np) -+{ -+ struct device_node *node; -+ struct of_phandle_args child, parent; -+ int ret; -+ -+ for_each_child_of_node(np, node) { -+ if (of_parse_phandle_with_args(node, "power-domains", -+ "#power-domain-cells", 0, &parent)) -+ continue; -+ -+ child.np = node; -+ child.args_count = 0; -+ ret = of_genpd_remove_subdomain(&parent, &child); -+ of_node_put(parent.np); -+ if (ret) { -+ of_node_put(node); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ - struct device *dt_idle_attach_cpu(int cpu, const char *name) - { - struct device *dev; -diff --git a/drivers/cpuidle/dt_idle_genpd.h b/drivers/cpuidle/dt_idle_genpd.h -index a95483d08a02a..3be1f70f55b5c 100644 ---- a/drivers/cpuidle/dt_idle_genpd.h -+++ b/drivers/cpuidle/dt_idle_genpd.h -@@ -14,6 +14,8 @@ struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np, - - int dt_idle_pd_init_topology(struct device_node *np); - -+int dt_idle_pd_remove_topology(struct device_node *np); -+ - struct device *dt_idle_attach_cpu(int cpu, const char *name); - - void dt_idle_detach_cpu(struct device *dev); -@@ -36,6 +38,11 @@ static inline int dt_idle_pd_init_topology(struct device_node *np) - return 0; - } - -+static inline int dt_idle_pd_remove_topology(struct device_node *np) -+{ -+ return 0; -+} -+ - static inline struct device *dt_idle_attach_cpu(int cpu, const char *name) - { - return NULL; -diff --git a/drivers/dma/mcf-edma.c b/drivers/dma/mcf-edma.c -index e12b754e6398d..60d3c5f09ad67 100644 ---- a/drivers/dma/mcf-edma.c -+++ b/drivers/dma/mcf-edma.c -@@ -191,7 +191,13 @@ static int mcf_edma_probe(struct platform_device *pdev) - return -EINVAL; - } - -- chans = pdata->dma_channels; -+ if (!pdata->dma_channels) { -+ dev_info(&pdev->dev, "setting default channel number to 64"); -+ chans = 64; -+ } else { -+ chans = pdata->dma_channels; -+ } -+ - len = sizeof(*mcf_edma) + sizeof(*mcf_chan) * chans; - mcf_edma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); - if (!mcf_edma) -@@ -203,11 +209,6 @@ static int mcf_edma_probe(struct platform_device *pdev) - mcf_edma->drvdata = &mcf_data; - mcf_edma->big_endian = 1; - -- if (!mcf_edma->n_chans) { -- dev_info(&pdev->dev, "setting default channel number to 64"); -- mcf_edma->n_chans = 64; -- } -- - mutex_init(&mcf_edma->fsl_edma_mutex); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -diff --git a/drivers/dma/owl-dma.c b/drivers/dma/owl-dma.c -index 95a462a1f5111..b6e0ac8314e5c 100644 ---- a/drivers/dma/owl-dma.c -+++ b/drivers/dma/owl-dma.c -@@ -192,7 +192,7 @@ struct owl_dma_pchan { - }; - - /** -- * struct owl_dma_pchan - Wrapper for DMA ENGINE channel -+ * struct owl_dma_vchan - Wrapper for DMA ENGINE channel - * @vc: wrapped virtual channel - * @pchan: the physical channel utilized by this channel - * @txd: active transaction on this channel -diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c -index b4731fe6bbc14..3cf0b38387ae5 100644 ---- a/drivers/dma/pl330.c -+++ b/drivers/dma/pl330.c -@@ -403,6 +403,12 @@ enum desc_status { - * of a channel can be BUSY at any time. - */ - BUSY, -+ /* -+ * Pause was called while descriptor was BUSY. Due to hardware -+ * limitations, only termination is possible for descriptors -+ * that have been paused. -+ */ -+ PAUSED, - /* - * Sitting on the channel work_list but xfer done - * by PL330 core -@@ -2041,7 +2047,7 @@ static inline void fill_queue(struct dma_pl330_chan *pch) - list_for_each_entry(desc, &pch->work_list, node) { - - /* If already submitted */ -- if (desc->status == BUSY) -+ if (desc->status == BUSY || desc->status == PAUSED) - continue; - - ret = pl330_submit_req(pch->thread, desc); -@@ -2326,6 +2332,7 @@ static int pl330_pause(struct dma_chan *chan) - { - struct dma_pl330_chan *pch = to_pchan(chan); - struct pl330_dmac *pl330 = pch->dmac; -+ struct dma_pl330_desc *desc; - unsigned long flags; - - pm_runtime_get_sync(pl330->ddma.dev); -@@ -2335,6 +2342,10 @@ static int pl330_pause(struct dma_chan *chan) - _stop(pch->thread); - spin_unlock(&pl330->lock); - -+ list_for_each_entry(desc, &pch->work_list, node) { -+ if (desc->status == BUSY) -+ desc->status = PAUSED; -+ } - spin_unlock_irqrestore(&pch->lock, flags); - pm_runtime_mark_last_busy(pl330->ddma.dev); - pm_runtime_put_autosuspend(pl330->ddma.dev); -@@ -2425,7 +2436,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - else if (running && desc == running) - transferred = - pl330_get_current_xferred_count(pch, desc); -- else if (desc->status == BUSY) -+ else if (desc->status == BUSY || desc->status == PAUSED) - /* - * Busy but not running means either just enqueued, - * or finished and not yet marked done -@@ -2442,6 +2453,9 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - case DONE: - ret = DMA_COMPLETE; - break; -+ case PAUSED: -+ ret = DMA_PAUSED; -+ break; - case PREP: - case BUSY: - ret = DMA_IN_PROGRESS; -diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c -index 803676e307d73..fef12e57b1f13 100644 ---- a/drivers/gpio/gpio-sim.c -+++ b/drivers/gpio/gpio-sim.c -@@ -425,6 +425,7 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev) - gc->set_config = gpio_sim_set_config; - gc->to_irq = gpio_sim_to_irq; - gc->free = gpio_sim_free; -+ gc->can_sleep = true; - - ret = devm_gpiochip_add_data(dev, gc, chip); - if (ret) -diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c -index e73885a4dc328..afb42a8e916fe 100644 ---- a/drivers/gpio/gpio-ws16c48.c -+++ b/drivers/gpio/gpio-ws16c48.c -@@ -18,7 +18,7 @@ - #include - #include - --#define WS16C48_EXTENT 10 -+#define WS16C48_EXTENT 11 - #define MAX_NUM_WS16C48 max_num_isa_dev(WS16C48_EXTENT) - - static unsigned int base[MAX_NUM_WS16C48]; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -index c0e782a95e72e..0c962f996aff5 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -@@ -242,6 +242,7 @@ extern int amdgpu_num_kcq; - - #define AMDGPU_VCNFW_LOG_SIZE (32 * 1024) - extern int amdgpu_vcnfw_log; -+extern int amdgpu_sg_display; - - #define AMDGPU_VM_MAX_NUM_CTX 4096 - #define AMDGPU_SG_THRESHOLD (256*1024*1024) -@@ -283,6 +284,9 @@ extern int amdgpu_vcnfw_log; - #define AMDGPU_SMARTSHIFT_MAX_BIAS (100) - #define AMDGPU_SMARTSHIFT_MIN_BIAS (-100) - -+/* Extra time delay(in ms) to eliminate the influence of temperature momentary fluctuation */ -+#define AMDGPU_SWCTF_EXTRA_DELAY 50 -+ - struct amdgpu_device; - struct amdgpu_irq_src; - struct amdgpu_fpriv; -@@ -1262,6 +1266,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, - void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); - int amdgpu_device_pci_reset(struct amdgpu_device *adev); - bool amdgpu_device_need_post(struct amdgpu_device *adev); -+bool amdgpu_sg_display_supported(struct amdgpu_device *adev); - bool amdgpu_device_pcie_dynamic_switching_supported(void); - bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev); - bool amdgpu_device_aspm_support_quirk(void); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -index b60b6e6149bf7..fdb53d4394f30 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -@@ -287,7 +287,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, - - if (!p->gang_size) { - ret = -EINVAL; -- goto free_partial_kdata; -+ goto free_all_kdata; - } - - for (i = 0; i < p->gang_size; ++i) { -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index 30c97ee375636..773383e660e8c 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -1333,6 +1333,32 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev) - return true; - } - -+/* -+ * On APUs with >= 64GB white flickering has been observed w/ SG enabled. -+ * Disable S/G on such systems until we have a proper fix. -+ * https://gitlab.freedesktop.org/drm/amd/-/issues/2354 -+ * https://gitlab.freedesktop.org/drm/amd/-/issues/2735 -+ */ -+bool amdgpu_sg_display_supported(struct amdgpu_device *adev) -+{ -+ switch (amdgpu_sg_display) { -+ case -1: -+ break; -+ case 0: -+ return false; -+ case 1: -+ return true; -+ default: -+ return false; -+ } -+ if ((totalram_pages() << (PAGE_SHIFT - 10)) + -+ (adev->gmc.real_vram_size / 1024) >= 64000000) { -+ DRM_WARN("Disabling S/G due to >=64GB RAM\n"); -+ return false; -+ } -+ return true; -+} -+ - /* - * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic - * speed switching. Until we have confirmation from Intel that a specific host -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -index 49a023f59b2fc..6e5bc74846952 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -@@ -185,6 +185,7 @@ int amdgpu_num_kcq = -1; - int amdgpu_smartshift_bias; - int amdgpu_use_xgmi_p2p = 1; - int amdgpu_vcnfw_log; -+int amdgpu_sg_display = -1; /* auto */ - - static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work); - -@@ -929,6 +930,16 @@ module_param_named(num_kcq, amdgpu_num_kcq, int, 0444); - MODULE_PARM_DESC(vcnfw_log, "Enable vcnfw log(0 = disable (default value), 1 = enable)"); - module_param_named(vcnfw_log, amdgpu_vcnfw_log, int, 0444); - -+/** -+ * DOC: sg_display (int) -+ * Disable S/G (scatter/gather) display (i.e., display from system memory). -+ * This option is only relevant on APUs. Set this option to 0 to disable -+ * S/G display if you experience flickering or other issues under memory -+ * pressure and report the issue. -+ */ -+MODULE_PARM_DESC(sg_display, "S/G Display (-1 = auto (default), 0 = disable)"); -+module_param_named(sg_display, amdgpu_sg_display, int, 0444); -+ - /** - * DOC: smu_pptable_id (int) - * Used to override pptable id. id = 0 use VBIOS pptable. -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 86e07cc1d3dcc..9f718b98da1f7 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -1634,6 +1634,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) - } - break; - } -+ if (init_data.flags.gpu_vm_support) -+ init_data.flags.gpu_vm_support = amdgpu_sg_display_supported(adev); - - if (init_data.flags.gpu_vm_support) - adev->mode_info.gpu_vm_support = true; -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c -index 8f9c60ed6f8b8..674ab6d9b31e4 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c -@@ -1079,6 +1079,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) - struct dc_state *dangling_context = dc_create_state(dc); - struct dc_state *current_ctx; - struct pipe_ctx *pipe; -+ struct timing_generator *tg; - - if (dangling_context == NULL) - return; -@@ -1122,6 +1123,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) - - if (should_disable && old_stream) { - pipe = &dc->current_state->res_ctx.pipe_ctx[i]; -+ tg = pipe->stream_res.tg; - /* When disabling plane for a phantom pipe, we must turn on the - * phantom OTG so the disable programming gets the double buffer - * update. Otherwise the pipe will be left in a partially disabled -@@ -1129,7 +1131,8 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) - * again for different use. - */ - if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) { -- pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); -+ if (tg->funcs->enable_crtc) -+ tg->funcs->enable_crtc(tg); - } - dc_rem_all_planes_for_stream(dc, old_stream, dangling_context); - disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context); -@@ -1146,6 +1149,15 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) - dc->hwss.interdependent_update_lock(dc, dc->current_state, false); - dc->hwss.post_unlock_program_front_end(dc, dangling_context); - } -+ /* We need to put the phantom OTG back into it's default (disabled) state or we -+ * can get corruption when transition from one SubVP config to a different one. -+ * The OTG is set to disable on falling edge of VUPDATE so the plane disable -+ * will still get it's double buffer update. -+ */ -+ if (old_stream->mall_stream_config.type == SUBVP_PHANTOM) { -+ if (tg->funcs->disable_phantom_crtc) -+ tg->funcs->disable_phantom_crtc(tg); -+ } - } - } - -@@ -1942,6 +1954,9 @@ enum dc_status dc_commit_streams(struct dc *dc, - struct pipe_ctx *pipe; - bool handle_exit_odm2to1 = false; - -+ if (dc->ctx->dce_environment == DCE_ENV_VIRTUAL_HW) -+ return res; -+ - if (!streams_changed(dc, streams, stream_count)) - return res; - -@@ -1984,21 +1999,33 @@ enum dc_status dc_commit_streams(struct dc *dc, - - dc_resource_state_copy_construct_current(dc, context); - -- /* -- * Previous validation was perfomred with fast_validation = true and -- * the full DML state required for hardware programming was skipped. -- * -- * Re-validate here to calculate these parameters / watermarks. -- */ -- res = dc_validate_global_state(dc, context, false); -+ res = dc_validate_with_context(dc, set, stream_count, context, false); - if (res != DC_OK) { -- DC_LOG_ERROR("DC commit global validation failure: %s (%d)", -- dc_status_to_str(res), res); -- return res; -+ BREAK_TO_DEBUGGER(); -+ goto fail; - } - - res = dc_commit_state_no_check(dc, context); - -+ for (i = 0; i < stream_count; i++) { -+ for (j = 0; j < context->stream_count; j++) { -+ if (streams[i]->stream_id == context->streams[j]->stream_id) -+ streams[i]->out.otg_offset = context->stream_status[j].primary_otg_inst; -+ -+ if (dc_is_embedded_signal(streams[i]->signal)) { -+ struct dc_stream_status *status = dc_stream_get_status_from_state(context, streams[i]); -+ -+ if (dc->hwss.is_abm_supported) -+ status->is_abm_supported = dc->hwss.is_abm_supported(dc, context, streams[i]); -+ else -+ status->is_abm_supported = true; -+ } -+ } -+ } -+ -+fail: -+ dc_release_state(context); -+ - context_alloc_fail: - - DC_LOG_DC("%s Finished.\n", __func__); -@@ -3122,6 +3149,19 @@ static bool update_planes_and_stream_state(struct dc *dc, - - if (update_type == UPDATE_TYPE_FULL) { - if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { -+ /* For phantom pipes we remove and create a new set of phantom pipes -+ * for each full update (because we don't know if we'll need phantom -+ * pipes until after the first round of validation). However, if validation -+ * fails we need to keep the existing phantom pipes (because we don't update -+ * the dc->current_state). -+ * -+ * The phantom stream/plane refcount is decremented for validation because -+ * we assume it'll be removed (the free comes when the dc_state is freed), -+ * but if validation fails we have to increment back the refcount so it's -+ * consistent. -+ */ -+ if (dc->res_pool->funcs->retain_phantom_pipes) -+ dc->res_pool->funcs->retain_phantom_pipes(dc, dc->current_state); - BREAK_TO_DEBUGGER(); - goto fail; - } -@@ -3987,6 +4027,18 @@ void dc_commit_updates_for_stream(struct dc *dc, - struct dc_context *dc_ctx = dc->ctx; - int i, j; - -+ /* TODO: Since change commit sequence can have a huge impact, -+ * we decided to only enable it for DCN3x. However, as soon as -+ * we get more confident about this change we'll need to enable -+ * the new sequence for all ASICs. -+ */ -+ if (dc->ctx->dce_version >= DCN_VERSION_3_2) { -+ dc_update_planes_and_stream(dc, srf_updates, -+ surface_count, stream, -+ stream_update); -+ return; -+ } -+ - stream_status = dc_stream_get_status(stream); - context = dc->current_state; - -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c -index c2c6c4587a5ce..bbaeb6c567d0d 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c -@@ -1141,6 +1141,11 @@ static bool detect_link_and_local_sink(struct dc_link *link, - (link->dpcd_caps.dongle_type != - DISPLAY_DONGLE_DP_HDMI_CONVERTER)) - converter_disable_audio = true; -+ -+ /* limited link rate to HBR3 for DPIA until we implement USB4 V2 */ -+ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && -+ link->reported_link_cap.link_rate > LINK_RATE_HIGH3) -+ link->reported_link_cap.link_rate = LINK_RATE_HIGH3; - break; - } - -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -index a26e52abc9898..66923f51037a3 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -@@ -2616,15 +2616,241 @@ bool dc_resource_is_dsc_encoding_supported(const struct dc *dc) - return dc->res_pool->res_cap->num_dsc > 0; - } - -+static bool planes_changed_for_existing_stream(struct dc_state *context, -+ struct dc_stream_state *stream, -+ const struct dc_validation_set set[], -+ int set_count) -+{ -+ int i, j; -+ struct dc_stream_status *stream_status = NULL; -+ -+ for (i = 0; i < context->stream_count; i++) { -+ if (context->streams[i] == stream) { -+ stream_status = &context->stream_status[i]; -+ break; -+ } -+ } -+ -+ if (!stream_status) -+ ASSERT(0); -+ -+ for (i = 0; i < set_count; i++) -+ if (set[i].stream == stream) -+ break; -+ -+ if (i == set_count) -+ ASSERT(0); -+ -+ if (set[i].plane_count != stream_status->plane_count) -+ return true; -+ -+ for (j = 0; j < set[i].plane_count; j++) -+ if (set[i].plane_states[j] != stream_status->plane_states[j]) -+ return true; -+ -+ return false; -+} -+ -+/** -+ * dc_validate_with_context - Validate and update the potential new stream in the context object -+ * -+ * @dc: Used to get the current state status -+ * @set: An array of dc_validation_set with all the current streams reference -+ * @set_count: Total of streams -+ * @context: New context -+ * @fast_validate: Enable or disable fast validation -+ * -+ * This function updates the potential new stream in the context object. It -+ * creates multiple lists for the add, remove, and unchanged streams. In -+ * particular, if the unchanged streams have a plane that changed, it is -+ * necessary to remove all planes from the unchanged streams. In summary, this -+ * function is responsible for validating the new context. -+ * -+ * Return: -+ * In case of success, return DC_OK (1), otherwise, return a DC error. -+ */ -+enum dc_status dc_validate_with_context(struct dc *dc, -+ const struct dc_validation_set set[], -+ int set_count, -+ struct dc_state *context, -+ bool fast_validate) -+{ -+ struct dc_stream_state *unchanged_streams[MAX_PIPES] = { 0 }; -+ struct dc_stream_state *del_streams[MAX_PIPES] = { 0 }; -+ struct dc_stream_state *add_streams[MAX_PIPES] = { 0 }; -+ int old_stream_count = context->stream_count; -+ enum dc_status res = DC_ERROR_UNEXPECTED; -+ int unchanged_streams_count = 0; -+ int del_streams_count = 0; -+ int add_streams_count = 0; -+ bool found = false; -+ int i, j, k; -+ -+ DC_LOGGER_INIT(dc->ctx->logger); -+ -+ /* First build a list of streams to be remove from current context */ -+ for (i = 0; i < old_stream_count; i++) { -+ struct dc_stream_state *stream = context->streams[i]; -+ -+ for (j = 0; j < set_count; j++) { -+ if (stream == set[j].stream) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ del_streams[del_streams_count++] = stream; -+ -+ found = false; -+ } -+ -+ /* Second, build a list of new streams */ -+ for (i = 0; i < set_count; i++) { -+ struct dc_stream_state *stream = set[i].stream; -+ -+ for (j = 0; j < old_stream_count; j++) { -+ if (stream == context->streams[j]) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ add_streams[add_streams_count++] = stream; -+ -+ found = false; -+ } -+ -+ /* Build a list of unchanged streams which is necessary for handling -+ * planes change such as added, removed, and updated. -+ */ -+ for (i = 0; i < set_count; i++) { -+ /* Check if stream is part of the delete list */ -+ for (j = 0; j < del_streams_count; j++) { -+ if (set[i].stream == del_streams[j]) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) { -+ /* Check if stream is part of the add list */ -+ for (j = 0; j < add_streams_count; j++) { -+ if (set[i].stream == add_streams[j]) { -+ found = true; -+ break; -+ } -+ } -+ } -+ -+ if (!found) -+ unchanged_streams[unchanged_streams_count++] = set[i].stream; -+ -+ found = false; -+ } -+ -+ /* Remove all planes for unchanged streams if planes changed */ -+ for (i = 0; i < unchanged_streams_count; i++) { -+ if (planes_changed_for_existing_stream(context, -+ unchanged_streams[i], -+ set, -+ set_count)) { -+ if (!dc_rem_all_planes_for_stream(dc, -+ unchanged_streams[i], -+ context)) { -+ res = DC_FAIL_DETACH_SURFACES; -+ goto fail; -+ } -+ } -+ } -+ -+ /* Remove all planes for removed streams and then remove the streams */ -+ for (i = 0; i < del_streams_count; i++) { -+ /* Need to cpy the dwb data from the old stream in order to efc to work */ -+ if (del_streams[i]->num_wb_info > 0) { -+ for (j = 0; j < add_streams_count; j++) { -+ if (del_streams[i]->sink == add_streams[j]->sink) { -+ add_streams[j]->num_wb_info = del_streams[i]->num_wb_info; -+ for (k = 0; k < del_streams[i]->num_wb_info; k++) -+ add_streams[j]->writeback_info[k] = del_streams[i]->writeback_info[k]; -+ } -+ } -+ } -+ -+ if (!dc_rem_all_planes_for_stream(dc, del_streams[i], context)) { -+ res = DC_FAIL_DETACH_SURFACES; -+ goto fail; -+ } -+ -+ res = dc_remove_stream_from_ctx(dc, context, del_streams[i]); -+ if (res != DC_OK) -+ goto fail; -+ } -+ -+ /* Swap seamless boot stream to pipe 0 (if needed) to ensure pipe_ctx -+ * matches. This may change in the future if seamless_boot_stream can be -+ * multiple. -+ */ -+ for (i = 0; i < add_streams_count; i++) { -+ mark_seamless_boot_stream(dc, add_streams[i]); -+ if (add_streams[i]->apply_seamless_boot_optimization && i != 0) { -+ struct dc_stream_state *temp = add_streams[0]; -+ -+ add_streams[0] = add_streams[i]; -+ add_streams[i] = temp; -+ break; -+ } -+ } -+ -+ /* Add new streams and then add all planes for the new stream */ -+ for (i = 0; i < add_streams_count; i++) { -+ calculate_phy_pix_clks(add_streams[i]); -+ res = dc_add_stream_to_ctx(dc, context, add_streams[i]); -+ if (res != DC_OK) -+ goto fail; -+ -+ if (!add_all_planes_for_stream(dc, add_streams[i], set, set_count, context)) { -+ res = DC_FAIL_ATTACH_SURFACES; -+ goto fail; -+ } -+ } -+ -+ /* Add all planes for unchanged streams if planes changed */ -+ for (i = 0; i < unchanged_streams_count; i++) { -+ if (planes_changed_for_existing_stream(context, -+ unchanged_streams[i], -+ set, -+ set_count)) { -+ if (!add_all_planes_for_stream(dc, unchanged_streams[i], set, set_count, context)) { -+ res = DC_FAIL_ATTACH_SURFACES; -+ goto fail; -+ } -+ } -+ } -+ -+ res = dc_validate_global_state(dc, context, fast_validate); -+ -+fail: -+ if (res != DC_OK) -+ DC_LOG_WARNING("%s:resource validation failed, dc_status:%d\n", -+ __func__, -+ res); -+ -+ return res; -+} - - /** -- * dc_validate_global_state() - Determine if HW can support a given state -- * Checks HW resource availability and bandwidth requirement. -+ * dc_validate_global_state() - Determine if hardware can support a given state -+ * - * @dc: dc struct for this driver - * @new_ctx: state to be validated - * @fast_validate: set to true if only yes/no to support matters - * -- * Return: DC_OK if the result can be programmed. Otherwise, an error code. -+ * Checks hardware resource availability and bandwidth requirement. -+ * -+ * Return: -+ * DC_OK if the result can be programmed. Otherwise, an error code. - */ - enum dc_status dc_validate_global_state( - struct dc *dc, -@@ -3757,4 +3983,4 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm( - } - - return true; --} -\ No newline at end of file -+} -diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h -index 6409b8d8ff71e..a4540f83aae59 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc.h -+++ b/drivers/gpu/drm/amd/display/dc/dc.h -@@ -1298,6 +1298,12 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla - - void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info); - -+enum dc_status dc_validate_with_context(struct dc *dc, -+ const struct dc_validation_set set[], -+ int set_count, -+ struct dc_state *context, -+ bool fast_validate); -+ - bool dc_set_generic_gpio_for_stereo(bool enable, - struct gpio_service *gpio_service); - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -index a6fde27d13479..3940271189632 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -@@ -2284,6 +2284,12 @@ void dcn10_enable_timing_synchronization( - opp = grouped_pipes[i]->stream_res.opp; - tg = grouped_pipes[i]->stream_res.tg; - tg->funcs->get_otg_active_size(tg, &width, &height); -+ -+ if (!tg->funcs->is_tg_enabled(tg)) { -+ DC_SYNC_INFO("Skipping timing sync on disabled OTG\n"); -+ return; -+ } -+ - if (opp->funcs->opp_program_dpg_dimensions) - opp->funcs->opp_program_dpg_dimensions(opp, width, 2*(height) + 1); - } -diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c -index e5b7ef7422b83..50dc834046446 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c -@@ -357,8 +357,11 @@ void dpp3_set_cursor_attributes( - int cur_rom_en = 0; - - if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA || -- color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) -- cur_rom_en = 1; -+ color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) { -+ if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) { -+ cur_rom_en = 1; -+ } -+ } - - REG_UPDATE_3(CURSOR0_CONTROL, - CUR0_MODE, color_format, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c -index fe941b103de81..a974f86e718a8 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c -@@ -167,6 +167,13 @@ static void optc32_phantom_crtc_post_enable(struct timing_generator *optc) - REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000); - } - -+static void optc32_disable_phantom_otg(struct timing_generator *optc) -+{ -+ struct optc *optc1 = DCN10TG_FROM_TG(optc); -+ -+ REG_UPDATE(OTG_CONTROL, OTG_MASTER_EN, 0); -+} -+ - static void optc32_set_odm_bypass(struct timing_generator *optc, - const struct dc_crtc_timing *dc_crtc_timing) - { -@@ -260,6 +267,7 @@ static struct timing_generator_funcs dcn32_tg_funcs = { - .enable_crtc = optc32_enable_crtc, - .disable_crtc = optc32_disable_crtc, - .phantom_crtc_post_enable = optc32_phantom_crtc_post_enable, -+ .disable_phantom_crtc = optc32_disable_phantom_otg, - /* used by enable_timing_synchronization. Not need for FPGA */ - .is_counter_moving = optc1_is_counter_moving, - .get_position = optc1_get_position, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c -index 814620e6638fd..2b8700b291a45 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c -@@ -1719,6 +1719,27 @@ static struct dc_stream_state *dcn32_enable_phantom_stream(struct dc *dc, - return phantom_stream; - } - -+void dcn32_retain_phantom_pipes(struct dc *dc, struct dc_state *context) -+{ -+ int i; -+ struct dc_plane_state *phantom_plane = NULL; -+ struct dc_stream_state *phantom_stream = NULL; -+ -+ for (i = 0; i < dc->res_pool->pipe_count; i++) { -+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; -+ -+ if (!pipe->top_pipe && !pipe->prev_odm_pipe && -+ pipe->plane_state && pipe->stream && -+ pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) { -+ phantom_plane = pipe->plane_state; -+ phantom_stream = pipe->stream; -+ -+ dc_plane_state_retain(phantom_plane); -+ dc_stream_retain(phantom_stream); -+ } -+ } -+} -+ - // return true if removed piped from ctx, false otherwise - bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context) - { -@@ -2035,6 +2056,7 @@ static struct resource_funcs dcn32_res_pool_funcs = { - .update_soc_for_wm_a = dcn30_update_soc_for_wm_a, - .add_phantom_pipes = dcn32_add_phantom_pipes, - .remove_phantom_pipes = dcn32_remove_phantom_pipes, -+ .retain_phantom_pipes = dcn32_retain_phantom_pipes, - }; - - static uint32_t read_pipe_fuses(struct dc_context *ctx) -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h -index 615244a1f95d5..026cf13d203fc 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h -@@ -83,6 +83,9 @@ bool dcn32_release_post_bldn_3dlut( - bool dcn32_remove_phantom_pipes(struct dc *dc, - struct dc_state *context); - -+void dcn32_retain_phantom_pipes(struct dc *dc, -+ struct dc_state *context); -+ - void dcn32_add_phantom_pipes(struct dc *dc, - struct dc_state *context, - display_e2e_pipe_params_st *pipes, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c -index 213ff3672bd54..aed92ced7b762 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c -@@ -1619,6 +1619,7 @@ static struct resource_funcs dcn321_res_pool_funcs = { - .update_soc_for_wm_a = dcn30_update_soc_for_wm_a, - .add_phantom_pipes = dcn32_add_phantom_pipes, - .remove_phantom_pipes = dcn32_remove_phantom_pipes, -+ .retain_phantom_pipes = dcn32_retain_phantom_pipes, - }; - - static uint32_t read_pipe_fuses(struct dc_context *ctx) -diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h -index 9498105c98ab3..5fa7c4772af4f 100644 ---- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h -+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h -@@ -234,6 +234,7 @@ struct resource_funcs { - unsigned int index); - - bool (*remove_phantom_pipes)(struct dc *dc, struct dc_state *context); -+ void (*retain_phantom_pipes)(struct dc *dc, struct dc_state *context); - void (*get_panel_config_defaults)(struct dc_panel_config *panel_config); - }; - -diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h -index f96fb425345e4..789cf9406ca5b 100644 ---- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h -+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h -@@ -185,6 +185,7 @@ struct timing_generator_funcs { - #ifdef CONFIG_DRM_AMD_DC_DCN - void (*phantom_crtc_post_enable)(struct timing_generator *tg); - #endif -+ void (*disable_phantom_crtc)(struct timing_generator *tg); - bool (*immediate_disable_crtc)(struct timing_generator *tg); - bool (*is_counter_moving)(struct timing_generator *tg); - void (*get_position)(struct timing_generator *tg, -diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h -index d18162e9ed1da..f3d64c78feaa8 100644 ---- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h -+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h -@@ -139,6 +139,8 @@ enum amd_pp_sensors { - AMDGPU_PP_SENSOR_MIN_FAN_RPM, - AMDGPU_PP_SENSOR_MAX_FAN_RPM, - AMDGPU_PP_SENSOR_VCN_POWER_STATE, -+ AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK, -+ AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK, - }; - - enum amd_pp_task { -diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h -index cb5b9df78b4db..338fce249f5ab 100644 ---- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h -+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h -@@ -89,6 +89,8 @@ struct amdgpu_dpm_thermal { - int max_mem_crit_temp; - /* memory max emergency(shutdown) temp */ - int max_mem_emergency_temp; -+ /* SWCTF threshold */ -+ int sw_ctf_threshold; - /* was last interrupt low to high or high to low */ - bool high_to_low; - /* interrupt source */ -diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c -index 1159ae114dd02..179e1c593a53f 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include "amd_shared.h" - #include "amd_powerplay.h" - #include "power_state.h" -@@ -91,6 +92,45 @@ static int pp_early_init(void *handle) - return 0; - } - -+static void pp_swctf_delayed_work_handler(struct work_struct *work) -+{ -+ struct pp_hwmgr *hwmgr = -+ container_of(work, struct pp_hwmgr, swctf_delayed_work.work); -+ struct amdgpu_device *adev = hwmgr->adev; -+ struct amdgpu_dpm_thermal *range = -+ &adev->pm.dpm.thermal; -+ uint32_t gpu_temperature, size; -+ int ret; -+ -+ /* -+ * If the hotspot/edge temperature is confirmed as below SW CTF setting point -+ * after the delay enforced, nothing will be done. -+ * Otherwise, a graceful shutdown will be performed to prevent further damage. -+ */ -+ if (range->sw_ctf_threshold && -+ hwmgr->hwmgr_func->read_sensor) { -+ ret = hwmgr->hwmgr_func->read_sensor(hwmgr, -+ AMDGPU_PP_SENSOR_HOTSPOT_TEMP, -+ &gpu_temperature, -+ &size); -+ /* -+ * For some legacy ASICs, hotspot temperature retrieving might be not -+ * supported. Check the edge temperature instead then. -+ */ -+ if (ret == -EOPNOTSUPP) -+ ret = hwmgr->hwmgr_func->read_sensor(hwmgr, -+ AMDGPU_PP_SENSOR_EDGE_TEMP, -+ &gpu_temperature, -+ &size); -+ if (!ret && gpu_temperature / 1000 < range->sw_ctf_threshold) -+ return; -+ } -+ -+ dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); -+ dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); -+ orderly_poweroff(true); -+} -+ - static int pp_sw_init(void *handle) - { - struct amdgpu_device *adev = handle; -@@ -101,6 +141,10 @@ static int pp_sw_init(void *handle) - - pr_debug("powerplay sw init %s\n", ret ? "failed" : "successfully"); - -+ if (!ret) -+ INIT_DELAYED_WORK(&hwmgr->swctf_delayed_work, -+ pp_swctf_delayed_work_handler); -+ - return ret; - } - -@@ -136,6 +180,8 @@ static int pp_hw_fini(void *handle) - struct amdgpu_device *adev = handle; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - -+ cancel_delayed_work_sync(&hwmgr->swctf_delayed_work); -+ - hwmgr_hw_fini(hwmgr); - - return 0; -@@ -222,6 +268,8 @@ static int pp_suspend(void *handle) - struct amdgpu_device *adev = handle; - struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - -+ cancel_delayed_work_sync(&hwmgr->swctf_delayed_work); -+ - return hwmgr_suspend(hwmgr); - } - -@@ -769,10 +817,16 @@ static int pp_dpm_read_sensor(void *handle, int idx, - - switch (idx) { - case AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK: -- *((uint32_t *)value) = hwmgr->pstate_sclk; -+ *((uint32_t *)value) = hwmgr->pstate_sclk * 100; - return 0; - case AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK: -- *((uint32_t *)value) = hwmgr->pstate_mclk; -+ *((uint32_t *)value) = hwmgr->pstate_mclk * 100; -+ return 0; -+ case AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK: -+ *((uint32_t *)value) = hwmgr->pstate_sclk_peak * 100; -+ return 0; -+ case AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK: -+ *((uint32_t *)value) = hwmgr->pstate_mclk_peak * 100; - return 0; - case AMDGPU_PP_SENSOR_MIN_FAN_RPM: - *((uint32_t *)value) = hwmgr->thermal_controller.fanInfo.ulMinRPM; -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c -index 981dc8c7112d6..90452b66e1071 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hardwaremanager.c -@@ -241,7 +241,8 @@ int phm_start_thermal_controller(struct pp_hwmgr *hwmgr) - TEMP_RANGE_MAX, - TEMP_RANGE_MIN, - TEMP_RANGE_MAX, -- TEMP_RANGE_MAX}; -+ TEMP_RANGE_MAX, -+ 0}; - struct amdgpu_device *adev = hwmgr->adev; - - if (!hwmgr->not_vf) -@@ -265,6 +266,7 @@ int phm_start_thermal_controller(struct pp_hwmgr *hwmgr) - adev->pm.dpm.thermal.min_mem_temp = range.mem_min; - adev->pm.dpm.thermal.max_mem_crit_temp = range.mem_crit_max; - adev->pm.dpm.thermal.max_mem_emergency_temp = range.mem_emergency_max; -+ adev->pm.dpm.thermal.sw_ctf_threshold = range.sw_ctf_threshold; - - return ret; - } -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c -index ede71de2343dc..86d6e88c73862 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c -@@ -375,6 +375,17 @@ static int smu10_enable_gfx_off(struct pp_hwmgr *hwmgr) - return 0; - } - -+static void smu10_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) -+{ -+ hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK; -+ hwmgr->pstate_mclk = SMU10_UMD_PSTATE_FCLK; -+ -+ smum_send_msg_to_smc(hwmgr, -+ PPSMC_MSG_GetMaxGfxclkFrequency, -+ &hwmgr->pstate_sclk_peak); -+ hwmgr->pstate_mclk_peak = SMU10_UMD_PSTATE_PEAK_FCLK; -+} -+ - static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - { - struct amdgpu_device *adev = hwmgr->adev; -@@ -398,6 +409,8 @@ static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - return ret; - } - -+ smu10_populate_umdpstate_clocks(hwmgr); -+ - return 0; - } - -@@ -574,9 +587,6 @@ static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) - - hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; - -- hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK * 100; -- hwmgr->pstate_mclk = SMU10_UMD_PSTATE_FCLK * 100; -- - /* enable the pp_od_clk_voltage sysfs file */ - hwmgr->od_enabled = 1; - /* disabled fine grain tuning function by default */ -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -index 7ef7e81525a30..a31a62a1ce0b2 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -@@ -1501,6 +1501,67 @@ static int smu7_populate_edc_leakage_registers(struct pp_hwmgr *hwmgr) - return ret; - } - -+static void smu7_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) -+{ -+ struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); -+ struct smu7_dpm_table *golden_dpm_table = &data->golden_dpm_table; -+ int32_t tmp_sclk, count, percentage; -+ -+ if (golden_dpm_table->mclk_table.count == 1) { -+ percentage = 70; -+ hwmgr->pstate_mclk = golden_dpm_table->mclk_table.dpm_levels[0].value; -+ } else { -+ percentage = 100 * golden_dpm_table->sclk_table.dpm_levels[golden_dpm_table->sclk_table.count - 1].value / -+ golden_dpm_table->mclk_table.dpm_levels[golden_dpm_table->mclk_table.count - 1].value; -+ hwmgr->pstate_mclk = golden_dpm_table->mclk_table.dpm_levels[golden_dpm_table->mclk_table.count - 2].value; -+ } -+ -+ tmp_sclk = hwmgr->pstate_mclk * percentage / 100; -+ -+ if (hwmgr->pp_table_version == PP_TABLE_V0) { -+ struct phm_clock_voltage_dependency_table *vddc_dependency_on_sclk = -+ hwmgr->dyn_state.vddc_dependency_on_sclk; -+ -+ for (count = vddc_dependency_on_sclk->count - 1; count >= 0; count--) { -+ if (tmp_sclk >= vddc_dependency_on_sclk->entries[count].clk) { -+ hwmgr->pstate_sclk = vddc_dependency_on_sclk->entries[count].clk; -+ break; -+ } -+ } -+ if (count < 0) -+ hwmgr->pstate_sclk = vddc_dependency_on_sclk->entries[0].clk; -+ -+ hwmgr->pstate_sclk_peak = -+ vddc_dependency_on_sclk->entries[vddc_dependency_on_sclk->count - 1].clk; -+ } else if (hwmgr->pp_table_version == PP_TABLE_V1) { -+ struct phm_ppt_v1_information *table_info = -+ (struct phm_ppt_v1_information *)(hwmgr->pptable); -+ struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_sclk = -+ table_info->vdd_dep_on_sclk; -+ -+ for (count = vdd_dep_on_sclk->count - 1; count >= 0; count--) { -+ if (tmp_sclk >= vdd_dep_on_sclk->entries[count].clk) { -+ hwmgr->pstate_sclk = vdd_dep_on_sclk->entries[count].clk; -+ break; -+ } -+ } -+ if (count < 0) -+ hwmgr->pstate_sclk = vdd_dep_on_sclk->entries[0].clk; -+ -+ hwmgr->pstate_sclk_peak = -+ vdd_dep_on_sclk->entries[vdd_dep_on_sclk->count - 1].clk; -+ } -+ -+ hwmgr->pstate_mclk_peak = -+ golden_dpm_table->mclk_table.dpm_levels[golden_dpm_table->mclk_table.count - 1].value; -+ -+ /* make sure the output is in Mhz */ -+ hwmgr->pstate_sclk /= 100; -+ hwmgr->pstate_mclk /= 100; -+ hwmgr->pstate_sclk_peak /= 100; -+ hwmgr->pstate_mclk_peak /= 100; -+} -+ - static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - { - int tmp_result = 0; -@@ -1625,6 +1686,8 @@ static int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - PP_ASSERT_WITH_CODE((0 == tmp_result), - "pcie performance request failed!", result = tmp_result); - -+ smu7_populate_umdpstate_clocks(hwmgr); -+ - return 0; - } - -@@ -3143,15 +3206,12 @@ static int smu7_get_profiling_clk(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_le - for (count = hwmgr->dyn_state.vddc_dependency_on_sclk->count-1; - count >= 0; count--) { - if (tmp_sclk >= hwmgr->dyn_state.vddc_dependency_on_sclk->entries[count].clk) { -- tmp_sclk = hwmgr->dyn_state.vddc_dependency_on_sclk->entries[count].clk; - *sclk_mask = count; - break; - } - } -- if (count < 0 || level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { -+ if (count < 0 || level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) - *sclk_mask = 0; -- tmp_sclk = hwmgr->dyn_state.vddc_dependency_on_sclk->entries[0].clk; -- } - - if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) - *sclk_mask = hwmgr->dyn_state.vddc_dependency_on_sclk->count-1; -@@ -3161,15 +3221,12 @@ static int smu7_get_profiling_clk(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_le - - for (count = table_info->vdd_dep_on_sclk->count-1; count >= 0; count--) { - if (tmp_sclk >= table_info->vdd_dep_on_sclk->entries[count].clk) { -- tmp_sclk = table_info->vdd_dep_on_sclk->entries[count].clk; - *sclk_mask = count; - break; - } - } -- if (count < 0 || level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { -+ if (count < 0 || level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) - *sclk_mask = 0; -- tmp_sclk = table_info->vdd_dep_on_sclk->entries[0].clk; -- } - - if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) - *sclk_mask = table_info->vdd_dep_on_sclk->count - 1; -@@ -3181,8 +3238,6 @@ static int smu7_get_profiling_clk(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_le - *mclk_mask = golden_dpm_table->mclk_table.count - 1; - - *pcie_mask = data->dpm_table.pcie_speed_table.count - 1; -- hwmgr->pstate_sclk = tmp_sclk; -- hwmgr->pstate_mclk = tmp_mclk; - - return 0; - } -@@ -3195,9 +3250,6 @@ static int smu7_force_dpm_level(struct pp_hwmgr *hwmgr, - uint32_t mclk_mask = 0; - uint32_t pcie_mask = 0; - -- if (hwmgr->pstate_sclk == 0) -- smu7_get_profiling_clk(hwmgr, level, &sclk_mask, &mclk_mask, &pcie_mask); -- - switch (level) { - case AMD_DPM_FORCED_LEVEL_HIGH: - ret = smu7_force_dpm_highest(hwmgr); -@@ -5381,6 +5433,8 @@ static int smu7_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, - thermal_data->max = data->thermal_temp_setting.temperature_shutdown * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - -+ thermal_data->sw_ctf_threshold = thermal_data->max; -+ - return 0; - } - -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -index b50fd4a4a3d1a..b015a601b385a 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -@@ -1016,6 +1016,18 @@ static void smu8_reset_acp_boot_level(struct pp_hwmgr *hwmgr) - data->acp_boot_level = 0xff; - } - -+static void smu8_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) -+{ -+ struct phm_clock_voltage_dependency_table *table = -+ hwmgr->dyn_state.vddc_dependency_on_sclk; -+ -+ hwmgr->pstate_sclk = table->entries[0].clk / 100; -+ hwmgr->pstate_mclk = 0; -+ -+ hwmgr->pstate_sclk_peak = table->entries[table->count - 1].clk / 100; -+ hwmgr->pstate_mclk_peak = 0; -+} -+ - static int smu8_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - { - smu8_program_voting_clients(hwmgr); -@@ -1024,6 +1036,8 @@ static int smu8_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - smu8_program_bootup_state(hwmgr); - smu8_reset_acp_boot_level(hwmgr); - -+ smu8_populate_umdpstate_clocks(hwmgr); -+ - return 0; - } - -@@ -1167,8 +1181,6 @@ static int smu8_phm_unforce_dpm_levels(struct pp_hwmgr *hwmgr) - - data->sclk_dpm.soft_min_clk = table->entries[0].clk; - data->sclk_dpm.hard_min_clk = table->entries[0].clk; -- hwmgr->pstate_sclk = table->entries[0].clk; -- hwmgr->pstate_mclk = 0; - - level = smu8_get_max_sclk_level(hwmgr) - 1; - -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c -index bfe80ac0ad8c8..d0b1ab6c45231 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c -@@ -603,21 +603,17 @@ int phm_irq_process(struct amdgpu_device *adev, - struct amdgpu_irq_src *source, - struct amdgpu_iv_entry *entry) - { -+ struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - uint32_t client_id = entry->client_id; - uint32_t src_id = entry->src_id; - - if (client_id == AMDGPU_IRQ_CLIENTID_LEGACY) { - if (src_id == VISLANDS30_IV_SRCID_CG_TSS_THERMAL_LOW_TO_HIGH) { -- dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); -- /* -- * SW CTF just occurred. -- * Try to do a graceful shutdown to prevent further damage. -- */ -- dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); -- orderly_poweroff(true); -- } else if (src_id == VISLANDS30_IV_SRCID_CG_TSS_THERMAL_HIGH_TO_LOW) -+ schedule_delayed_work(&hwmgr->swctf_delayed_work, -+ msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); -+ } else if (src_id == VISLANDS30_IV_SRCID_CG_TSS_THERMAL_HIGH_TO_LOW) { - dev_emerg(adev->dev, "ERROR: GPU under temperature range detected!\n"); -- else if (src_id == VISLANDS30_IV_SRCID_GPIO_19) { -+ } else if (src_id == VISLANDS30_IV_SRCID_GPIO_19) { - dev_emerg(adev->dev, "ERROR: GPU HW Critical Temperature Fault(aka CTF) detected!\n"); - /* - * HW CTF just occurred. Shutdown to prevent further damage. -@@ -626,15 +622,10 @@ int phm_irq_process(struct amdgpu_device *adev, - orderly_poweroff(true); - } - } else if (client_id == SOC15_IH_CLIENTID_THM) { -- if (src_id == 0) { -- dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); -- /* -- * SW CTF just occurred. -- * Try to do a graceful shutdown to prevent further damage. -- */ -- dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); -- orderly_poweroff(true); -- } else -+ if (src_id == 0) -+ schedule_delayed_work(&hwmgr->swctf_delayed_work, -+ msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); -+ else - dev_emerg(adev->dev, "ERROR: GPU under temperature range detected!\n"); - } else if (client_id == SOC15_IH_CLIENTID_ROM_SMUIO) { - dev_emerg(adev->dev, "ERROR: GPU HW Critical Temperature Fault(aka CTF) detected!\n"); -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -index c8c9fb827bda1..d8cd23438b762 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -@@ -3008,6 +3008,30 @@ static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool - return 0; - } - -+static void vega10_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) -+{ -+ struct phm_ppt_v2_information *table_info = -+ (struct phm_ppt_v2_information *)(hwmgr->pptable); -+ -+ if (table_info->vdd_dep_on_sclk->count > VEGA10_UMD_PSTATE_GFXCLK_LEVEL && -+ table_info->vdd_dep_on_mclk->count > VEGA10_UMD_PSTATE_MCLK_LEVEL) { -+ hwmgr->pstate_sclk = table_info->vdd_dep_on_sclk->entries[VEGA10_UMD_PSTATE_GFXCLK_LEVEL].clk; -+ hwmgr->pstate_mclk = table_info->vdd_dep_on_mclk->entries[VEGA10_UMD_PSTATE_MCLK_LEVEL].clk; -+ } else { -+ hwmgr->pstate_sclk = table_info->vdd_dep_on_sclk->entries[0].clk; -+ hwmgr->pstate_mclk = table_info->vdd_dep_on_mclk->entries[0].clk; -+ } -+ -+ hwmgr->pstate_sclk_peak = table_info->vdd_dep_on_sclk->entries[table_info->vdd_dep_on_sclk->count - 1].clk; -+ hwmgr->pstate_mclk_peak = table_info->vdd_dep_on_mclk->entries[table_info->vdd_dep_on_mclk->count - 1].clk; -+ -+ /* make sure the output is in Mhz */ -+ hwmgr->pstate_sclk /= 100; -+ hwmgr->pstate_mclk /= 100; -+ hwmgr->pstate_sclk_peak /= 100; -+ hwmgr->pstate_mclk_peak /= 100; -+} -+ - static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - { - struct vega10_hwmgr *data = hwmgr->backend; -@@ -3082,6 +3106,8 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - result = tmp_result); - } - -+ vega10_populate_umdpstate_clocks(hwmgr); -+ - return result; - } - -@@ -4169,8 +4195,6 @@ static int vega10_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_fo - *sclk_mask = VEGA10_UMD_PSTATE_GFXCLK_LEVEL; - *soc_mask = VEGA10_UMD_PSTATE_SOCCLK_LEVEL; - *mclk_mask = VEGA10_UMD_PSTATE_MCLK_LEVEL; -- hwmgr->pstate_sclk = table_info->vdd_dep_on_sclk->entries[VEGA10_UMD_PSTATE_GFXCLK_LEVEL].clk; -- hwmgr->pstate_mclk = table_info->vdd_dep_on_mclk->entries[VEGA10_UMD_PSTATE_MCLK_LEVEL].clk; - } - - if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) { -@@ -4281,9 +4305,6 @@ static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, - uint32_t mclk_mask = 0; - uint32_t soc_mask = 0; - -- if (hwmgr->pstate_sclk == 0) -- vega10_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask); -- - switch (level) { - case AMD_DPM_FORCED_LEVEL_HIGH: - ret = vega10_force_dpm_highest(hwmgr); -@@ -5221,6 +5242,9 @@ static int vega10_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, - { - struct vega10_hwmgr *data = hwmgr->backend; - PPTable_t *pp_table = &(data->smc_state_table.pp_table); -+ struct phm_ppt_v2_information *pp_table_info = -+ (struct phm_ppt_v2_information *)(hwmgr->pptable); -+ struct phm_tdp_table *tdp_table = pp_table_info->tdp_table; - - memcpy(thermal_data, &SMU7ThermalWithDelayPolicy[0], sizeof(struct PP_TemperatureRange)); - -@@ -5237,6 +5261,13 @@ static int vega10_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, - thermal_data->mem_emergency_max = (pp_table->ThbmLimit + CTF_OFFSET_HBM)* - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - -+ if (tdp_table->usSoftwareShutdownTemp > pp_table->ThotspotLimit && -+ tdp_table->usSoftwareShutdownTemp < VEGA10_THERMAL_MAXIMUM_ALERT_TEMP) -+ thermal_data->sw_ctf_threshold = tdp_table->usSoftwareShutdownTemp; -+ else -+ thermal_data->sw_ctf_threshold = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP; -+ thermal_data->sw_ctf_threshold *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES; -+ - return 0; - } - -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c -index a2f4d6773d458..1069eaaae2f82 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c -@@ -1026,6 +1026,25 @@ static int vega12_get_all_clock_ranges(struct pp_hwmgr *hwmgr) - return 0; - } - -+static void vega12_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) -+{ -+ struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); -+ struct vega12_single_dpm_table *gfx_dpm_table = &(data->dpm_table.gfx_table); -+ struct vega12_single_dpm_table *mem_dpm_table = &(data->dpm_table.mem_table); -+ -+ if (gfx_dpm_table->count > VEGA12_UMD_PSTATE_GFXCLK_LEVEL && -+ mem_dpm_table->count > VEGA12_UMD_PSTATE_MCLK_LEVEL) { -+ hwmgr->pstate_sclk = gfx_dpm_table->dpm_levels[VEGA12_UMD_PSTATE_GFXCLK_LEVEL].value; -+ hwmgr->pstate_mclk = mem_dpm_table->dpm_levels[VEGA12_UMD_PSTATE_MCLK_LEVEL].value; -+ } else { -+ hwmgr->pstate_sclk = gfx_dpm_table->dpm_levels[0].value; -+ hwmgr->pstate_mclk = mem_dpm_table->dpm_levels[0].value; -+ } -+ -+ hwmgr->pstate_sclk_peak = gfx_dpm_table->dpm_levels[gfx_dpm_table->count].value; -+ hwmgr->pstate_mclk_peak = mem_dpm_table->dpm_levels[mem_dpm_table->count].value; -+} -+ - static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - { - int tmp_result, result = 0; -@@ -1077,6 +1096,9 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - PP_ASSERT_WITH_CODE(!result, - "Failed to setup default DPM tables!", - return result); -+ -+ vega12_populate_umdpstate_clocks(hwmgr); -+ - return result; - } - -@@ -2742,6 +2764,8 @@ static int vega12_notify_cac_buffer_info(struct pp_hwmgr *hwmgr, - static int vega12_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, - struct PP_TemperatureRange *thermal_data) - { -+ struct phm_ppt_v3_information *pptable_information = -+ (struct phm_ppt_v3_information *)hwmgr->pptable; - struct vega12_hwmgr *data = - (struct vega12_hwmgr *)(hwmgr->backend); - PPTable_t *pp_table = &(data->smc_state_table.pp_table); -@@ -2760,6 +2784,8 @@ static int vega12_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - thermal_data->mem_emergency_max = (pp_table->ThbmLimit + CTF_OFFSET_HBM)* - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; -+ thermal_data->sw_ctf_threshold = pptable_information->us_software_shutdown_temp * -+ PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - - return 0; - } -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c -index b30684c84e20e..ff77a3683efd5 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c -@@ -1555,26 +1555,23 @@ static int vega20_set_mclk_od( - return 0; - } - --static int vega20_populate_umdpstate_clocks( -- struct pp_hwmgr *hwmgr) -+static void vega20_populate_umdpstate_clocks(struct pp_hwmgr *hwmgr) - { - struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); - struct vega20_single_dpm_table *gfx_table = &(data->dpm_table.gfx_table); - struct vega20_single_dpm_table *mem_table = &(data->dpm_table.mem_table); - -- hwmgr->pstate_sclk = gfx_table->dpm_levels[0].value; -- hwmgr->pstate_mclk = mem_table->dpm_levels[0].value; -- - if (gfx_table->count > VEGA20_UMD_PSTATE_GFXCLK_LEVEL && - mem_table->count > VEGA20_UMD_PSTATE_MCLK_LEVEL) { - hwmgr->pstate_sclk = gfx_table->dpm_levels[VEGA20_UMD_PSTATE_GFXCLK_LEVEL].value; - hwmgr->pstate_mclk = mem_table->dpm_levels[VEGA20_UMD_PSTATE_MCLK_LEVEL].value; -+ } else { -+ hwmgr->pstate_sclk = gfx_table->dpm_levels[0].value; -+ hwmgr->pstate_mclk = mem_table->dpm_levels[0].value; - } - -- hwmgr->pstate_sclk = hwmgr->pstate_sclk * 100; -- hwmgr->pstate_mclk = hwmgr->pstate_mclk * 100; -- -- return 0; -+ hwmgr->pstate_sclk_peak = gfx_table->dpm_levels[gfx_table->count - 1].value; -+ hwmgr->pstate_mclk_peak = mem_table->dpm_levels[mem_table->count - 1].value; - } - - static int vega20_get_max_sustainable_clock(struct pp_hwmgr *hwmgr, -@@ -1753,10 +1750,7 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr) - "[EnableDPMTasks] Failed to initialize odn settings!", - return result); - -- result = vega20_populate_umdpstate_clocks(hwmgr); -- PP_ASSERT_WITH_CODE(!result, -- "[EnableDPMTasks] Failed to populate umdpstate clocks!", -- return result); -+ vega20_populate_umdpstate_clocks(hwmgr); - - result = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetPptLimit, - POWER_SOURCE_AC << 16, &hwmgr->default_power_limit); -@@ -4213,6 +4207,8 @@ static int vega20_notify_cac_buffer_info(struct pp_hwmgr *hwmgr, - static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, - struct PP_TemperatureRange *thermal_data) - { -+ struct phm_ppt_v3_information *pptable_information = -+ (struct phm_ppt_v3_information *)hwmgr->pptable; - struct vega20_hwmgr *data = - (struct vega20_hwmgr *)(hwmgr->backend); - PPTable_t *pp_table = &(data->smc_state_table.pp_table); -@@ -4231,6 +4227,8 @@ static int vega20_get_thermal_temperature_range(struct pp_hwmgr *hwmgr, - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - thermal_data->mem_emergency_max = (pp_table->ThbmLimit + CTF_OFFSET_HBM)* - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; -+ thermal_data->sw_ctf_threshold = pptable_information->us_software_shutdown_temp * -+ PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - - return 0; - } -diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h -index 27f8d0e0e6a8c..ec10643edea3e 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h -+++ b/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h -@@ -809,6 +809,10 @@ struct pp_hwmgr { - uint32_t workload_prority[Workload_Policy_Max]; - uint32_t workload_setting[Workload_Policy_Max]; - bool gfxoff_state_changed_by_workload; -+ uint32_t pstate_sclk_peak; -+ uint32_t pstate_mclk_peak; -+ -+ struct delayed_work swctf_delayed_work; - }; - - int hwmgr_early_init(struct pp_hwmgr *hwmgr); -diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/power_state.h b/drivers/gpu/drm/amd/pm/powerplay/inc/power_state.h -index a5f2227a3971c..0ffc2347829d0 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/inc/power_state.h -+++ b/drivers/gpu/drm/amd/pm/powerplay/inc/power_state.h -@@ -131,6 +131,7 @@ struct PP_TemperatureRange { - int mem_min; - int mem_crit_max; - int mem_emergency_max; -+ int sw_ctf_threshold; - }; - - struct PP_StateValidationBlock { -diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -index 91dfc229e34d7..d191ff52d4f06 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -@@ -24,6 +24,7 @@ - - #include - #include -+#include - - #include "amdgpu.h" - #include "amdgpu_smu.h" -@@ -1061,6 +1062,34 @@ static void smu_interrupt_work_fn(struct work_struct *work) - smu->ppt_funcs->interrupt_work(smu); - } - -+static void smu_swctf_delayed_work_handler(struct work_struct *work) -+{ -+ struct smu_context *smu = -+ container_of(work, struct smu_context, swctf_delayed_work.work); -+ struct smu_temperature_range *range = -+ &smu->thermal_range; -+ struct amdgpu_device *adev = smu->adev; -+ uint32_t hotspot_tmp, size; -+ -+ /* -+ * If the hotspot temperature is confirmed as below SW CTF setting point -+ * after the delay enforced, nothing will be done. -+ * Otherwise, a graceful shutdown will be performed to prevent further damage. -+ */ -+ if (range->software_shutdown_temp && -+ smu->ppt_funcs->read_sensor && -+ !smu->ppt_funcs->read_sensor(smu, -+ AMDGPU_PP_SENSOR_HOTSPOT_TEMP, -+ &hotspot_tmp, -+ &size) && -+ hotspot_tmp / 1000 < range->software_shutdown_temp) -+ return; -+ -+ dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); -+ dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); -+ orderly_poweroff(true); -+} -+ - static int smu_sw_init(void *handle) - { - struct amdgpu_device *adev = (struct amdgpu_device *)handle; -@@ -1109,6 +1138,9 @@ static int smu_sw_init(void *handle) - return ret; - } - -+ INIT_DELAYED_WORK(&smu->swctf_delayed_work, -+ smu_swctf_delayed_work_handler); -+ - ret = smu_smc_table_sw_init(smu); - if (ret) { - dev_err(adev->dev, "Failed to sw init smc table!\n"); -@@ -1581,6 +1613,8 @@ static int smu_smc_hw_cleanup(struct smu_context *smu) - return ret; - } - -+ cancel_delayed_work_sync(&smu->swctf_delayed_work); -+ - ret = smu_disable_dpms(smu); - if (ret) { - dev_err(adev->dev, "Fail to disable dpm features!\n"); -@@ -2520,6 +2554,14 @@ static int smu_read_sensor(void *handle, - *((uint32_t *)data) = pstate_table->uclk_pstate.standard * 100; - *size = 4; - break; -+ case AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK: -+ *((uint32_t *)data) = pstate_table->gfxclk_pstate.peak * 100; -+ *size = 4; -+ break; -+ case AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK: -+ *((uint32_t *)data) = pstate_table->uclk_pstate.peak * 100; -+ *size = 4; -+ break; - case AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK: - ret = smu_feature_get_enabled_mask(smu, (uint64_t *)data); - *size = 8; -diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h -index 3bc4128a22ac2..1ab77a6cdb653 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h -+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h -@@ -573,6 +573,8 @@ struct smu_context - u32 debug_param_reg; - u32 debug_msg_reg; - u32 debug_resp_reg; -+ -+ struct delayed_work swctf_delayed_work; - }; - - struct i2c_adapter; -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c -index ad5f6a15a1d7d..d490b571c8ffa 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c -@@ -1438,13 +1438,8 @@ static int smu_v11_0_irq_process(struct amdgpu_device *adev, - if (client_id == SOC15_IH_CLIENTID_THM) { - switch (src_id) { - case THM_11_0__SRCID__THM_DIG_THERM_L2H: -- dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); -- /* -- * SW CTF just occurred. -- * Try to do a graceful shutdown to prevent further damage. -- */ -- dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); -- orderly_poweroff(true); -+ schedule_delayed_work(&smu->swctf_delayed_work, -+ msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); - break; - case THM_11_0__SRCID__THM_DIG_THERM_H2L: - dev_emerg(adev->dev, "ERROR: GPU under temperature range detected\n"); -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -index 47fafb1fa6088..3104d49379090 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -@@ -1386,13 +1386,8 @@ static int smu_v13_0_irq_process(struct amdgpu_device *adev, - if (client_id == SOC15_IH_CLIENTID_THM) { - switch (src_id) { - case THM_11_0__SRCID__THM_DIG_THERM_L2H: -- dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n"); -- /* -- * SW CTF just occurred. -- * Try to do a graceful shutdown to prevent further damage. -- */ -- dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n"); -- orderly_poweroff(true); -+ schedule_delayed_work(&smu->swctf_delayed_work, -+ msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY)); - break; - case THM_11_0__SRCID__THM_DIG_THERM_H2L: - dev_emerg(adev->dev, "ERROR: GPU under temperature range detected\n"); -diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c -index 5fdc608043e76..e33f06bb66eb4 100644 ---- a/drivers/gpu/drm/drm_gem_shmem_helper.c -+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c -@@ -622,7 +622,13 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct - int ret; - - if (obj->import_attach) { -+ /* Reset both vm_ops and vm_private_data, so we don't end up with -+ * vm_ops pointing to our implementation if the dma-buf backend -+ * doesn't set those fields. -+ */ - vma->vm_private_data = NULL; -+ vma->vm_ops = NULL; -+ - ret = dma_buf_mmap(obj->dma_buf, vma, 0); - - /* Drop the reference drm_gem_mmap_obj() acquired.*/ -diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c -index f40310559d13f..49c5451cdfb16 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_connector.c -+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c -@@ -967,7 +967,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) - /* Determine display colour depth for everything except LVDS now, - * DP requires this before mode_valid() is called. - */ -- if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode) -+ if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) - nouveau_connector_detect_depth(connector); - - /* Find the native mode if this is a digital panel, if we didn't -diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c -index c1b3206f27e64..458f8efb19c6c 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c -+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c -@@ -26,6 +26,8 @@ - #include "head.h" - #include "ior.h" - -+#include -+ - #include - #include - #include -@@ -474,6 +476,50 @@ nvkm_dp_train(struct nvkm_outp *outp, u32 dataKBps) - return ret; - } - -+/* XXX: This is a big fat hack, and this is just drm_dp_read_dpcd_caps() -+ * converted to work inside nvkm. This is a temporary holdover until we start -+ * passing the drm_dp_aux device through NVKM -+ */ -+static int -+nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp) -+{ -+ struct nvkm_i2c_aux *aux = outp->dp.aux; -+ u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; -+ int ret; -+ -+ ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE); -+ if (ret < 0) -+ return ret; -+ -+ /* -+ * Prior to DP1.3 the bit represented by -+ * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved. -+ * If it is set DP_DPCD_REV at 0000h could be at a value less than -+ * the true capability of the panel. The only way to check is to -+ * then compare 0000h and 2200h. -+ */ -+ if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] & -+ DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT)) -+ return 0; -+ -+ ret = nvkm_rdaux(aux, DP_DP13_DPCD_REV, dpcd_ext, sizeof(dpcd_ext)); -+ if (ret < 0) -+ return ret; -+ -+ if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) { -+ OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n", -+ outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]); -+ return 0; -+ } -+ -+ if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext))) -+ return 0; -+ -+ memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)); -+ -+ return 0; -+} -+ - void - nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior) - { -@@ -630,7 +676,7 @@ nvkm_dp_enable(struct nvkm_outp *outp, bool enable) - memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr)); - } - -- if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) { -+ if (!nvkm_dp_read_dpcd_caps(outp)) { - const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 }; - const u8 *rate; - int rate_max; -diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h -index 32bbddc0993e8..679aff79f4d6b 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h -+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h -@@ -123,6 +123,7 @@ void gk104_grctx_generate_r418800(struct gf100_gr *); - - extern const struct gf100_grctx_func gk110_grctx; - void gk110_grctx_generate_r419eb0(struct gf100_gr *); -+void gk110_grctx_generate_r419f78(struct gf100_gr *); - - extern const struct gf100_grctx_func gk110b_grctx; - extern const struct gf100_grctx_func gk208_grctx; -diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c -index 304e9d268bad4..f894f82548242 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c -+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c -@@ -916,7 +916,9 @@ static void - gk104_grctx_generate_r419f78(struct gf100_gr *gr) - { - struct nvkm_device *device = gr->base.engine.subdev.device; -- nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); -+ -+ /* bit 3 set disables loads in fp helper invocations, we need it enabled */ -+ nvkm_mask(device, 0x419f78, 0x00000009, 0x00000000); - } - - void -diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c -index 86547cfc38dce..e88740d4e54d4 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c -+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c -@@ -820,6 +820,15 @@ gk110_grctx_generate_r419eb0(struct gf100_gr *gr) - nvkm_mask(device, 0x419eb0, 0x00001000, 0x00001000); - } - -+void -+gk110_grctx_generate_r419f78(struct gf100_gr *gr) -+{ -+ struct nvkm_device *device = gr->base.engine.subdev.device; -+ -+ /* bit 3 set disables loads in fp helper invocations, we need it enabled */ -+ nvkm_mask(device, 0x419f78, 0x00000008, 0x00000000); -+} -+ - const struct gf100_grctx_func - gk110_grctx = { - .main = gf100_grctx_generate_main, -@@ -852,4 +861,5 @@ gk110_grctx = { - .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, - .r418800 = gk104_grctx_generate_r418800, - .r419eb0 = gk110_grctx_generate_r419eb0, -+ .r419f78 = gk110_grctx_generate_r419f78, - }; -diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c -index ebb947bd1446b..086e4d49e1121 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c -+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c -@@ -101,4 +101,5 @@ gk110b_grctx = { - .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, - .r418800 = gk104_grctx_generate_r418800, - .r419eb0 = gk110_grctx_generate_r419eb0, -+ .r419f78 = gk110_grctx_generate_r419f78, - }; -diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c -index 4d40512b5c998..0bf438c3f7cbc 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c -+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c -@@ -566,4 +566,5 @@ gk208_grctx = { - .dist_skip_table = gf117_grctx_generate_dist_skip_table, - .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, - .r418800 = gk104_grctx_generate_r418800, -+ .r419f78 = gk110_grctx_generate_r419f78, - }; -diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c -index 0b3964e6b36e2..acdf0932a99e1 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c -+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c -@@ -991,4 +991,5 @@ gm107_grctx = { - .r406500 = gm107_grctx_generate_r406500, - .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, - .r419e00 = gm107_grctx_generate_r419e00, -+ .r419f78 = gk110_grctx_generate_r419f78, - }; -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index 9fea03121247e..2e2e08f4359a8 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -@@ -836,12 +836,12 @@ static int vop_plane_atomic_check(struct drm_plane *plane, - * need align with 2 pixel. - */ - if (fb->format->is_yuv && ((new_plane_state->src.x1 >> 16) % 2)) { -- DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n"); -+ DRM_DEBUG_KMS("Invalid Source: Yuv format not support odd xpos\n"); - return -EINVAL; - } - - if (fb->format->is_yuv && new_plane_state->rotation & DRM_MODE_REFLECT_Y) { -- DRM_ERROR("Invalid Source: Yuv format does not support this rotation\n"); -+ DRM_DEBUG_KMS("Invalid Source: Yuv format does not support this rotation\n"); - return -EINVAL; - } - -@@ -849,7 +849,7 @@ static int vop_plane_atomic_check(struct drm_plane *plane, - struct vop *vop = to_vop(crtc); - - if (!vop->data->afbc) { -- DRM_ERROR("vop does not support AFBC\n"); -+ DRM_DEBUG_KMS("vop does not support AFBC\n"); - return -EINVAL; - } - -@@ -858,15 +858,16 @@ static int vop_plane_atomic_check(struct drm_plane *plane, - return ret; - - if (new_plane_state->src.x1 || new_plane_state->src.y1) { -- DRM_ERROR("AFBC does not support offset display, xpos=%d, ypos=%d, offset=%d\n", -- new_plane_state->src.x1, -- new_plane_state->src.y1, fb->offsets[0]); -+ DRM_DEBUG_KMS("AFBC does not support offset display, " \ -+ "xpos=%d, ypos=%d, offset=%d\n", -+ new_plane_state->src.x1, new_plane_state->src.y1, -+ fb->offsets[0]); - return -EINVAL; - } - - if (new_plane_state->rotation && new_plane_state->rotation != DRM_MODE_ROTATE_0) { -- DRM_ERROR("No rotation support in AFBC, rotation=%d\n", -- new_plane_state->rotation); -+ DRM_DEBUG_KMS("No rotation support in AFBC, rotation=%d\n", -+ new_plane_state->rotation); - return -EINVAL; - } - } -diff --git a/drivers/hwmon/pmbus/bel-pfe.c b/drivers/hwmon/pmbus/bel-pfe.c -index 4100eefb7ac32..61c195f8fd3b8 100644 ---- a/drivers/hwmon/pmbus/bel-pfe.c -+++ b/drivers/hwmon/pmbus/bel-pfe.c -@@ -17,12 +17,13 @@ - enum chips {pfe1100, pfe3000}; - - /* -- * Disable status check for pfe3000 devices, because some devices report -- * communication error (invalid command) for VOUT_MODE command (0x20) -- * although correct VOUT_MODE (0x16) is returned: it leads to incorrect -- * exponent in linear mode. -+ * Disable status check because some devices report communication error -+ * (invalid command) for VOUT_MODE command (0x20) although the correct -+ * VOUT_MODE (0x16) is returned: it leads to incorrect exponent in linear -+ * mode. -+ * This affects both pfe3000 and pfe1100. - */ --static struct pmbus_platform_data pfe3000_plat_data = { -+static struct pmbus_platform_data pfe_plat_data = { - .flags = PMBUS_SKIP_STATUS_CHECK, - }; - -@@ -94,16 +95,15 @@ static int pfe_pmbus_probe(struct i2c_client *client) - int model; - - model = (int)i2c_match_id(pfe_device_id, client)->driver_data; -+ client->dev.platform_data = &pfe_plat_data; - - /* - * PFE3000-12-069RA devices may not stay in page 0 during device - * probe which leads to probe failure (read status word failed). - * So let's set the device to page 0 at the beginning. - */ -- if (model == pfe3000) { -- client->dev.platform_data = &pfe3000_plat_data; -+ if (model == pfe3000) - i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); -- } - - return pmbus_do_probe(client, &pfe_driver_info[model]); - } -diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c -index 8720ac43a4a4a..80eff7090f14a 100644 ---- a/drivers/iio/adc/ad7192.c -+++ b/drivers/iio/adc/ad7192.c -@@ -62,7 +62,6 @@ - #define AD7192_MODE_STA_MASK BIT(20) /* Status Register transmission Mask */ - #define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */ - #define AD7192_MODE_SINC3 BIT(15) /* SINC3 Filter Select */ --#define AD7192_MODE_ACX BIT(14) /* AC excitation enable(AD7195 only)*/ - #define AD7192_MODE_ENPAR BIT(13) /* Parity Enable */ - #define AD7192_MODE_CLKDIV BIT(12) /* Clock divide by 2 (AD7190/2 only)*/ - #define AD7192_MODE_SCYCLE BIT(11) /* Single cycle conversion */ -@@ -91,6 +90,7 @@ - /* Configuration Register Bit Designations (AD7192_REG_CONF) */ - - #define AD7192_CONF_CHOP BIT(23) /* CHOP enable */ -+#define AD7192_CONF_ACX BIT(22) /* AC excitation enable(AD7195 only) */ - #define AD7192_CONF_REFSEL BIT(20) /* REFIN1/REFIN2 Reference Select */ - #define AD7192_CONF_CHAN(x) ((x) << 8) /* Channel select */ - #define AD7192_CONF_CHAN_MASK (0x7FF << 8) /* Channel select mask */ -@@ -473,7 +473,7 @@ static ssize_t ad7192_show_ac_excitation(struct device *dev, - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct ad7192_state *st = iio_priv(indio_dev); - -- return sysfs_emit(buf, "%d\n", !!(st->mode & AD7192_MODE_ACX)); -+ return sysfs_emit(buf, "%d\n", !!(st->conf & AD7192_CONF_ACX)); - } - - static ssize_t ad7192_show_bridge_switch(struct device *dev, -@@ -514,13 +514,13 @@ static ssize_t ad7192_set(struct device *dev, - - ad_sd_write_reg(&st->sd, AD7192_REG_GPOCON, 1, st->gpocon); - break; -- case AD7192_REG_MODE: -+ case AD7192_REG_CONF: - if (val) -- st->mode |= AD7192_MODE_ACX; -+ st->conf |= AD7192_CONF_ACX; - else -- st->mode &= ~AD7192_MODE_ACX; -+ st->conf &= ~AD7192_CONF_ACX; - -- ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); -+ ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); - break; - default: - ret = -EINVAL; -@@ -580,12 +580,11 @@ static IIO_DEVICE_ATTR(bridge_switch_en, 0644, - - static IIO_DEVICE_ATTR(ac_excitation_en, 0644, - ad7192_show_ac_excitation, ad7192_set, -- AD7192_REG_MODE); -+ AD7192_REG_CONF); - - static struct attribute *ad7192_attributes[] = { - &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr, - &iio_dev_attr_bridge_switch_en.dev_attr.attr, -- &iio_dev_attr_ac_excitation_en.dev_attr.attr, - NULL - }; - -@@ -596,6 +595,7 @@ static const struct attribute_group ad7192_attribute_group = { - static struct attribute *ad7195_attributes[] = { - &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr, - &iio_dev_attr_bridge_switch_en.dev_attr.attr, -+ &iio_dev_attr_ac_excitation_en.dev_attr.attr, - NULL - }; - -diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c -index 910e7e965fc48..74092f3836b83 100644 ---- a/drivers/iio/adc/ina2xx-adc.c -+++ b/drivers/iio/adc/ina2xx-adc.c -@@ -124,6 +124,7 @@ static const struct regmap_config ina2xx_regmap_config = { - enum ina2xx_ids { ina219, ina226 }; - - struct ina2xx_config { -+ const char *name; - u16 config_default; - int calibration_value; - int shunt_voltage_lsb; /* nV */ -@@ -155,6 +156,7 @@ struct ina2xx_chip_info { - - static const struct ina2xx_config ina2xx_config[] = { - [ina219] = { -+ .name = "ina219", - .config_default = INA219_CONFIG_DEFAULT, - .calibration_value = 4096, - .shunt_voltage_lsb = 10000, -@@ -164,6 +166,7 @@ static const struct ina2xx_config ina2xx_config[] = { - .chip_id = ina219, - }, - [ina226] = { -+ .name = "ina226", - .config_default = INA226_CONFIG_DEFAULT, - .calibration_value = 2048, - .shunt_voltage_lsb = 2500, -@@ -996,7 +999,7 @@ static int ina2xx_probe(struct i2c_client *client, - /* Patch the current config register with default. */ - val = chip->config->config_default; - -- if (id->driver_data == ina226) { -+ if (type == ina226) { - ina226_set_average(chip, INA226_DEFAULT_AVG, &val); - ina226_set_int_time_vbus(chip, INA226_DEFAULT_IT, &val); - ina226_set_int_time_vshunt(chip, INA226_DEFAULT_IT, &val); -@@ -1015,7 +1018,7 @@ static int ina2xx_probe(struct i2c_client *client, - } - - indio_dev->modes = INDIO_DIRECT_MODE; -- if (id->driver_data == ina226) { -+ if (type == ina226) { - indio_dev->channels = ina226_channels; - indio_dev->num_channels = ARRAY_SIZE(ina226_channels); - indio_dev->info = &ina226_info; -@@ -1024,7 +1027,7 @@ static int ina2xx_probe(struct i2c_client *client, - indio_dev->num_channels = ARRAY_SIZE(ina219_channels); - indio_dev->info = &ina219_info; - } -- indio_dev->name = id->name; -+ indio_dev->name = id ? id->name : chip->config->name; - - ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev, - &ina2xx_setup_ops); -diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c -index 05a28d353e343..d98f7e4d202c1 100644 ---- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c -+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c -@@ -253,7 +253,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, - platform_set_drvdata(pdev, indio_dev); - - state->ec = ec->ec_dev; -- state->msg = devm_kzalloc(&pdev->dev, -+ state->msg = devm_kzalloc(&pdev->dev, sizeof(*state->msg) + - max((u16)sizeof(struct ec_params_motion_sense), - state->ec->max_response), GFP_KERNEL); - if (!state->msg) -diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c -index ed81672713586..e6311213f3e89 100644 ---- a/drivers/iio/frequency/admv1013.c -+++ b/drivers/iio/frequency/admv1013.c -@@ -344,9 +344,12 @@ static int admv1013_update_quad_filters(struct admv1013_state *st) - - static int admv1013_update_mixer_vgate(struct admv1013_state *st) - { -- unsigned int vcm, mixer_vgate; -+ unsigned int mixer_vgate; -+ int vcm; - - vcm = regulator_get_voltage(st->reg); -+ if (vcm < 0) -+ return vcm; - - if (vcm < 1800000) - mixer_vgate = (2389 * vcm / 1000000 + 8100) / 100; -diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c -index 151ff39933548..f3f8392623a46 100644 ---- a/drivers/iio/industrialio-core.c -+++ b/drivers/iio/industrialio-core.c -@@ -1916,7 +1916,7 @@ static const struct iio_buffer_setup_ops noop_ring_setup_ops; - int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) - { - struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); -- struct fwnode_handle *fwnode; -+ struct fwnode_handle *fwnode = NULL; - int ret; - - if (!indio_dev->info) -@@ -1927,7 +1927,8 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) - /* If the calling driver did not initialize firmware node, do it here */ - if (dev_fwnode(&indio_dev->dev)) - fwnode = dev_fwnode(&indio_dev->dev); -- else -+ /* The default dummy IIO device has no parent */ -+ else if (indio_dev->dev.parent) - fwnode = dev_fwnode(indio_dev->dev.parent); - device_set_node(&indio_dev->dev, fwnode); - -diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c -index 86d479772fbc6..957634eceba8f 100644 ---- a/drivers/infiniband/core/umem.c -+++ b/drivers/infiniband/core/umem.c -@@ -85,6 +85,8 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, - dma_addr_t mask; - int i; - -+ umem->iova = va = virt; -+ - if (umem->is_odp) { - unsigned int page_size = BIT(to_ib_umem_odp(umem)->page_shift); - -@@ -100,7 +102,6 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, - */ - pgsz_bitmap &= GENMASK(BITS_PER_LONG - 1, PAGE_SHIFT); - -- umem->iova = va = virt; - /* The best result is the smallest page size that results in the minimum - * number of required pages. Compute the largest page size that could - * work based on VA address bits that don't change. -diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c -index 90b672feed83d..194cac40da653 100644 ---- a/drivers/infiniband/hw/hfi1/chip.c -+++ b/drivers/infiniband/hw/hfi1/chip.c -@@ -12307,6 +12307,7 @@ static void free_cntrs(struct hfi1_devdata *dd) - - if (dd->synth_stats_timer.function) - del_timer_sync(&dd->synth_stats_timer); -+ cancel_work_sync(&dd->update_cntr_work); - ppd = (struct hfi1_pportdata *)(dd + 1); - for (i = 0; i < dd->num_pports; i++, ppd++) { - kfree(ppd->cntrs); -diff --git a/drivers/interconnect/qcom/bcm-voter.c b/drivers/interconnect/qcom/bcm-voter.c -index 8f385f9c2dd38..d5f2a6b5376bd 100644 ---- a/drivers/interconnect/qcom/bcm-voter.c -+++ b/drivers/interconnect/qcom/bcm-voter.c -@@ -83,6 +83,11 @@ static void bcm_aggregate(struct qcom_icc_bcm *bcm) - - temp = agg_peak[bucket] * bcm->vote_scale; - bcm->vote_y[bucket] = bcm_div(temp, bcm->aux_data.unit); -+ -+ if (bcm->enable_mask && (bcm->vote_x[bucket] || bcm->vote_y[bucket])) { -+ bcm->vote_x[bucket] = 0; -+ bcm->vote_y[bucket] = bcm->enable_mask; -+ } - } - - if (bcm->keepalive && bcm->vote_x[QCOM_ICC_BUCKET_AMC] == 0 && -diff --git a/drivers/interconnect/qcom/icc-rpmh.h b/drivers/interconnect/qcom/icc-rpmh.h -index 04391c1ba465c..7843d8864d6ba 100644 ---- a/drivers/interconnect/qcom/icc-rpmh.h -+++ b/drivers/interconnect/qcom/icc-rpmh.h -@@ -81,6 +81,7 @@ struct qcom_icc_node { - * @vote_x: aggregated threshold values, represents sum_bw when @type is bw bcm - * @vote_y: aggregated threshold values, represents peak_bw when @type is bw bcm - * @vote_scale: scaling factor for vote_x and vote_y -+ * @enable_mask: optional mask to send as vote instead of vote_x/vote_y - * @dirty: flag used to indicate whether the bcm needs to be committed - * @keepalive: flag used to indicate whether a keepalive is required - * @aux_data: auxiliary data used when calculating threshold values and -@@ -97,6 +98,7 @@ struct qcom_icc_bcm { - u64 vote_x[QCOM_ICC_NUM_BUCKETS]; - u64 vote_y[QCOM_ICC_NUM_BUCKETS]; - u64 vote_scale; -+ u32 enable_mask; - bool dirty; - bool keepalive; - struct bcm_db aux_data; -diff --git a/drivers/interconnect/qcom/sm8450.c b/drivers/interconnect/qcom/sm8450.c -index 2d7a8e7b85ec2..e64c214b40209 100644 ---- a/drivers/interconnect/qcom/sm8450.c -+++ b/drivers/interconnect/qcom/sm8450.c -@@ -1337,6 +1337,7 @@ static struct qcom_icc_node qns_mem_noc_sf_disp = { - - static struct qcom_icc_bcm bcm_acv = { - .name = "ACV", -+ .enable_mask = 0x8, - .num_nodes = 1, - .nodes = { &ebi }, - }; -@@ -1349,6 +1350,7 @@ static struct qcom_icc_bcm bcm_ce0 = { - - static struct qcom_icc_bcm bcm_cn0 = { - .name = "CN0", -+ .enable_mask = 0x1, - .keepalive = true, - .num_nodes = 55, - .nodes = { &qnm_gemnoc_cnoc, &qnm_gemnoc_pcie, -@@ -1383,6 +1385,7 @@ static struct qcom_icc_bcm bcm_cn0 = { - - static struct qcom_icc_bcm bcm_co0 = { - .name = "CO0", -+ .enable_mask = 0x1, - .num_nodes = 2, - .nodes = { &qxm_nsp, &qns_nsp_gemnoc }, - }; -@@ -1403,6 +1406,7 @@ static struct qcom_icc_bcm bcm_mm0 = { - - static struct qcom_icc_bcm bcm_mm1 = { - .name = "MM1", -+ .enable_mask = 0x1, - .num_nodes = 12, - .nodes = { &qnm_camnoc_hf, &qnm_camnoc_icp, - &qnm_camnoc_sf, &qnm_mdp, -@@ -1445,6 +1449,7 @@ static struct qcom_icc_bcm bcm_sh0 = { - - static struct qcom_icc_bcm bcm_sh1 = { - .name = "SH1", -+ .enable_mask = 0x1, - .num_nodes = 7, - .nodes = { &alm_gpu_tcu, &alm_sys_tcu, - &qnm_nsp_gemnoc, &qnm_pcie, -@@ -1461,6 +1466,7 @@ static struct qcom_icc_bcm bcm_sn0 = { - - static struct qcom_icc_bcm bcm_sn1 = { - .name = "SN1", -+ .enable_mask = 0x1, - .num_nodes = 4, - .nodes = { &qhm_gic, &qxm_pimem, - &xm_gic, &qns_gemnoc_gc }, -@@ -1492,6 +1498,7 @@ static struct qcom_icc_bcm bcm_sn7 = { - - static struct qcom_icc_bcm bcm_acv_disp = { - .name = "ACV", -+ .enable_mask = 0x1, - .num_nodes = 1, - .nodes = { &ebi_disp }, - }; -@@ -1510,6 +1517,7 @@ static struct qcom_icc_bcm bcm_mm0_disp = { - - static struct qcom_icc_bcm bcm_mm1_disp = { - .name = "MM1", -+ .enable_mask = 0x1, - .num_nodes = 3, - .nodes = { &qnm_mdp_disp, &qnm_rot_disp, - &qns_mem_noc_sf_disp }, -@@ -1523,6 +1531,7 @@ static struct qcom_icc_bcm bcm_sh0_disp = { - - static struct qcom_icc_bcm bcm_sh1_disp = { - .name = "SH1", -+ .enable_mask = 0x1, - .num_nodes = 1, - .nodes = { &qnm_pcie_disp }, - }; -diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h -index fa09d511a8eda..baf31258f5c90 100644 ---- a/drivers/isdn/mISDN/dsp.h -+++ b/drivers/isdn/mISDN/dsp.h -@@ -247,7 +247,7 @@ extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp); - extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id); - extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb); - extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb); --extern void dsp_cmx_send(void *arg); -+extern void dsp_cmx_send(struct timer_list *arg); - extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb); - extern int dsp_cmx_del_conf_member(struct dsp *dsp); - extern int dsp_cmx_del_conf(struct dsp_conf *conf); -diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c -index 6d2088fbaf69c..1b73af5013976 100644 ---- a/drivers/isdn/mISDN/dsp_cmx.c -+++ b/drivers/isdn/mISDN/dsp_cmx.c -@@ -1625,7 +1625,7 @@ static u16 dsp_count; /* last sample count */ - static int dsp_count_valid; /* if we have last sample count */ - - void --dsp_cmx_send(void *arg) -+dsp_cmx_send(struct timer_list *arg) - { - struct dsp_conf *conf; - struct dsp_conf_member *member; -diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c -index 386084530c2f8..fae95f1666883 100644 ---- a/drivers/isdn/mISDN/dsp_core.c -+++ b/drivers/isdn/mISDN/dsp_core.c -@@ -1195,7 +1195,7 @@ static int __init dsp_init(void) - } - - /* set sample timer */ -- timer_setup(&dsp_spl_tl, (void *)dsp_cmx_send, 0); -+ timer_setup(&dsp_spl_tl, dsp_cmx_send, 0); - dsp_spl_tl.expires = jiffies + dsp_tics; - dsp_spl_jiffies = dsp_spl_tl.expires; - add_timer(&dsp_spl_tl); -diff --git a/drivers/misc/cardreader/rts5227.c b/drivers/misc/cardreader/rts5227.c -index d676cf63a9669..3dae5e3a16976 100644 ---- a/drivers/misc/cardreader/rts5227.c -+++ b/drivers/misc/cardreader/rts5227.c -@@ -195,7 +195,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) - } - } - -- if (option->force_clkreq_0) -+ if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, - FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); - else -diff --git a/drivers/misc/cardreader/rts5228.c b/drivers/misc/cardreader/rts5228.c -index cfebad51d1d80..f4ab09439da70 100644 ---- a/drivers/misc/cardreader/rts5228.c -+++ b/drivers/misc/cardreader/rts5228.c -@@ -435,17 +435,10 @@ static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) - option->ltr_enabled = false; - } - } -- -- if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -- | PM_L1_1_EN | PM_L1_2_EN)) -- option->force_clkreq_0 = false; -- else -- option->force_clkreq_0 = true; - } - - static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) - { -- struct rtsx_cr_option *option = &pcr->option; - - rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, - CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); -@@ -476,17 +469,6 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) - else - rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); - -- /* -- * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -- * to drive low, and we forcibly request clock. -- */ -- if (option->force_clkreq_0) -- rtsx_pci_write_register(pcr, PETXCFG, -- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -- else -- rtsx_pci_write_register(pcr, PETXCFG, -- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -- - rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); - - if (pcr->rtd3_en) { -diff --git a/drivers/misc/cardreader/rts5249.c b/drivers/misc/cardreader/rts5249.c -index 91d240dd68faa..47ab72a43256b 100644 ---- a/drivers/misc/cardreader/rts5249.c -+++ b/drivers/misc/cardreader/rts5249.c -@@ -327,12 +327,11 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) - } - } - -- - /* - * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced - * to drive low, and we forcibly request clock. - */ -- if (option->force_clkreq_0) -+ if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) - rtsx_pci_write_register(pcr, PETXCFG, - FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); - else -diff --git a/drivers/misc/cardreader/rts5260.c b/drivers/misc/cardreader/rts5260.c -index 9b42b20a3e5ae..79b18f6f73a8a 100644 ---- a/drivers/misc/cardreader/rts5260.c -+++ b/drivers/misc/cardreader/rts5260.c -@@ -517,17 +517,10 @@ static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) - option->ltr_enabled = false; - } - } -- -- if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -- | PM_L1_1_EN | PM_L1_2_EN)) -- option->force_clkreq_0 = false; -- else -- option->force_clkreq_0 = true; - } - - static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) - { -- struct rtsx_cr_option *option = &pcr->option; - - /* Set mcu_cnt to 7 to ensure data can be sampled properly */ - rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); -@@ -546,17 +539,6 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) - - rts5260_init_hw(pcr); - -- /* -- * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -- * to drive low, and we forcibly request clock. -- */ -- if (option->force_clkreq_0) -- rtsx_pci_write_register(pcr, PETXCFG, -- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -- else -- rtsx_pci_write_register(pcr, PETXCFG, -- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -- - rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); - - return 0; -diff --git a/drivers/misc/cardreader/rts5261.c b/drivers/misc/cardreader/rts5261.c -index b1e76030cafda..94af6bf8a25a6 100644 ---- a/drivers/misc/cardreader/rts5261.c -+++ b/drivers/misc/cardreader/rts5261.c -@@ -498,17 +498,10 @@ static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) - option->ltr_enabled = false; - } - } -- -- if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -- | PM_L1_1_EN | PM_L1_2_EN)) -- option->force_clkreq_0 = false; -- else -- option->force_clkreq_0 = true; - } - - static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) - { -- struct rtsx_cr_option *option = &pcr->option; - u32 val; - - rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, -@@ -554,17 +547,6 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) - else - rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); - -- /* -- * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -- * to drive low, and we forcibly request clock. -- */ -- if (option->force_clkreq_0) -- rtsx_pci_write_register(pcr, PETXCFG, -- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -- else -- rtsx_pci_write_register(pcr, PETXCFG, -- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -- - rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); - - if (pcr->rtd3_en) { -diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c -index 32b7783e9d4fa..a3f4b52bb159f 100644 ---- a/drivers/misc/cardreader/rtsx_pcr.c -+++ b/drivers/misc/cardreader/rtsx_pcr.c -@@ -1326,8 +1326,11 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) - return err; - } - -- if (pcr->aspm_mode == ASPM_MODE_REG) -+ if (pcr->aspm_mode == ASPM_MODE_REG) { - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -+ } - - /* No CD interrupt if probing driver with card inserted. - * So we need to initialize pcr->card_exist here. -diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c -index 52ed30f2d9f4f..94e9a08bc90e1 100644 ---- a/drivers/mmc/host/moxart-mmc.c -+++ b/drivers/mmc/host/moxart-mmc.c -@@ -338,13 +338,7 @@ static void moxart_transfer_pio(struct moxart_host *host) - return; - } - for (len = 0; len < remain && len < host->fifo_width;) { -- /* SCR data must be read in big endian. */ -- if (data->mrq->cmd->opcode == SD_APP_SEND_SCR) -- *sgp = ioread32be(host->base + -- REG_DATA_WINDOW); -- else -- *sgp = ioread32(host->base + -- REG_DATA_WINDOW); -+ *sgp = ioread32(host->base + REG_DATA_WINDOW); - sgp++; - len += 4; - } -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 576370f89c755..7a3c7a74af04a 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -5839,7 +5839,9 @@ void bond_setup(struct net_device *bond_dev) - - bond_dev->hw_features = BOND_VLAN_FEATURES | - NETIF_F_HW_VLAN_CTAG_RX | -- NETIF_F_HW_VLAN_CTAG_FILTER; -+ NETIF_F_HW_VLAN_CTAG_FILTER | -+ NETIF_F_HW_VLAN_STAG_RX | -+ NETIF_F_HW_VLAN_STAG_FILTER; - - bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL; - bond_dev->features |= bond_dev->hw_features; -diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c -index 4faabc4364aa7..2d2c6f941272c 100644 ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -1606,8 +1606,10 @@ static void felix_teardown(struct dsa_switch *ds) - struct felix *felix = ocelot_to_felix(ocelot); - struct dsa_port *dp; - -+ rtnl_lock(); - if (felix->tag_proto_ops) - felix->tag_proto_ops->teardown(ds); -+ rtnl_unlock(); - - dsa_switch_for_each_available_port(dp, ds) - ocelot_deinit_port(ocelot, dp->index); -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -index f6ededec5a4fa..69d1549e63a98 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -@@ -458,9 +458,9 @@ static void hns3_dbg_fill_content(char *content, u16 len, - if (result) { - if (item_len < strlen(result[i])) - break; -- strscpy(pos, result[i], strlen(result[i])); -+ memcpy(pos, result[i], strlen(result[i])); - } else { -- strscpy(pos, items[i].name, strlen(items[i].name)); -+ memcpy(pos, items[i].name, strlen(items[i].name)); - } - pos += item_len; - len -= item_len; -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -index 248f15dac86ba..61f833d61f583 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -@@ -5854,6 +5854,9 @@ void hns3_external_lb_prepare(struct net_device *ndev, bool if_running) - if (!if_running) - return; - -+ if (test_and_set_bit(HNS3_NIC_STATE_DOWN, &priv->state)) -+ return; -+ - netif_carrier_off(ndev); - netif_tx_disable(ndev); - -@@ -5882,7 +5885,16 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running) - if (!if_running) - return; - -- hns3_nic_reset_all_ring(priv->ae_handle); -+ if (hns3_nic_resetting(ndev)) -+ return; -+ -+ if (!test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) -+ return; -+ -+ if (hns3_nic_reset_all_ring(priv->ae_handle)) -+ return; -+ -+ clear_bit(HNS3_NIC_STATE_DOWN, &priv->state); - - for (i = 0; i < priv->vector_num; i++) - hns3_vector_enable(&priv->tqp_vector[i]); -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c -index 726062e512939..5cb8f1818e51c 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c -@@ -110,9 +110,9 @@ static void hclge_dbg_fill_content(char *content, u16 len, - if (result) { - if (item_len < strlen(result[i])) - break; -- strscpy(pos, result[i], strlen(result[i])); -+ memcpy(pos, result[i], strlen(result[i])); - } else { -- strscpy(pos, items[i].name, strlen(items[i].name)); -+ memcpy(pos, items[i].name, strlen(items[i].name)); - } - pos += item_len; - len -= item_len; -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -index 50e956d6c3b25..6af2273f227c2 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -@@ -72,6 +72,8 @@ static void hclge_restore_hw_table(struct hclge_dev *hdev); - static void hclge_sync_promisc_mode(struct hclge_dev *hdev); - static void hclge_sync_fd_table(struct hclge_dev *hdev); - static void hclge_update_fec_stats(struct hclge_dev *hdev); -+static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, -+ int wait_cnt); - - static struct hnae3_ae_algo ae_algo; - -@@ -7567,6 +7569,8 @@ static void hclge_enable_fd(struct hnae3_handle *handle, bool enable) - - static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable) - { -+#define HCLGE_LINK_STATUS_WAIT_CNT 3 -+ - struct hclge_desc desc; - struct hclge_config_mac_mode_cmd *req = - (struct hclge_config_mac_mode_cmd *)desc.data; -@@ -7591,9 +7595,15 @@ static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable) - req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en); - - ret = hclge_cmd_send(&hdev->hw, &desc, 1); -- if (ret) -+ if (ret) { - dev_err(&hdev->pdev->dev, - "mac enable fail, ret =%d.\n", ret); -+ return; -+ } -+ -+ if (!enable) -+ hclge_mac_link_status_wait(hdev, HCLGE_LINK_STATUS_DOWN, -+ HCLGE_LINK_STATUS_WAIT_CNT); - } - - static int hclge_config_switch_param(struct hclge_dev *hdev, int vfid, -@@ -7656,10 +7666,9 @@ static void hclge_phy_link_status_wait(struct hclge_dev *hdev, - } while (++i < HCLGE_PHY_LINK_STATUS_NUM); - } - --static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret) -+static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, -+ int wait_cnt) - { --#define HCLGE_MAC_LINK_STATUS_NUM 100 -- - int link_status; - int i = 0; - int ret; -@@ -7672,13 +7681,15 @@ static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret) - return 0; - - msleep(HCLGE_LINK_STATUS_MS); -- } while (++i < HCLGE_MAC_LINK_STATUS_NUM); -+ } while (++i < wait_cnt); - return -EBUSY; - } - - static int hclge_mac_phy_link_status_wait(struct hclge_dev *hdev, bool en, - bool is_phy) - { -+#define HCLGE_MAC_LINK_STATUS_NUM 100 -+ - int link_ret; - - link_ret = en ? HCLGE_LINK_STATUS_UP : HCLGE_LINK_STATUS_DOWN; -@@ -7686,7 +7697,8 @@ static int hclge_mac_phy_link_status_wait(struct hclge_dev *hdev, bool en, - if (is_phy) - hclge_phy_link_status_wait(hdev, link_ret); - -- return hclge_mac_link_status_wait(hdev, link_ret); -+ return hclge_mac_link_status_wait(hdev, link_ret, -+ HCLGE_MAC_LINK_STATUS_NUM); - } - - static int hclge_set_app_loopback(struct hclge_dev *hdev, bool en) -diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c -index bc97f24b08270..157be4e9be4b7 100644 ---- a/drivers/net/ethernet/ibm/ibmvnic.c -+++ b/drivers/net/ethernet/ibm/ibmvnic.c -@@ -96,6 +96,8 @@ static int pending_scrq(struct ibmvnic_adapter *, - static union sub_crq *ibmvnic_next_scrq(struct ibmvnic_adapter *, - struct ibmvnic_sub_crq_queue *); - static int ibmvnic_poll(struct napi_struct *napi, int data); -+static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter); -+static inline void reinit_init_done(struct ibmvnic_adapter *adapter); - static void send_query_map(struct ibmvnic_adapter *adapter); - static int send_request_map(struct ibmvnic_adapter *, dma_addr_t, u32, u8); - static int send_request_unmap(struct ibmvnic_adapter *, u8); -@@ -113,6 +115,7 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter, - static void free_long_term_buff(struct ibmvnic_adapter *adapter, - struct ibmvnic_long_term_buff *ltb); - static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter); -+static void flush_reset_queue(struct ibmvnic_adapter *adapter); - - struct ibmvnic_stat { - char name[ETH_GSTRING_LEN]; -@@ -1314,8 +1317,8 @@ static const char *adapter_state_to_string(enum vnic_state state) - - static int ibmvnic_login(struct net_device *netdev) - { -+ unsigned long flags, timeout = msecs_to_jiffies(20000); - struct ibmvnic_adapter *adapter = netdev_priv(netdev); -- unsigned long timeout = msecs_to_jiffies(20000); - int retry_count = 0; - int retries = 10; - bool retry; -@@ -1336,11 +1339,9 @@ static int ibmvnic_login(struct net_device *netdev) - - if (!wait_for_completion_timeout(&adapter->init_done, - timeout)) { -- netdev_warn(netdev, "Login timed out, retrying...\n"); -- retry = true; -- adapter->init_done_rc = 0; -- retry_count++; -- continue; -+ netdev_warn(netdev, "Login timed out\n"); -+ adapter->login_pending = false; -+ goto partial_reset; - } - - if (adapter->init_done_rc == ABORTED) { -@@ -1382,10 +1383,69 @@ static int ibmvnic_login(struct net_device *netdev) - "SCRQ irq initialization failed\n"); - return rc; - } -+ /* Default/timeout error handling, reset and start fresh */ - } else if (adapter->init_done_rc) { - netdev_warn(netdev, "Adapter login failed, init_done_rc = %d\n", - adapter->init_done_rc); -- return -EIO; -+ -+partial_reset: -+ /* adapter login failed, so free any CRQs or sub-CRQs -+ * and register again before attempting to login again. -+ * If we don't do this then the VIOS may think that -+ * we are already logged in and reject any subsequent -+ * attempts -+ */ -+ netdev_warn(netdev, -+ "Freeing and re-registering CRQs before attempting to login again\n"); -+ retry = true; -+ adapter->init_done_rc = 0; -+ release_sub_crqs(adapter, true); -+ /* Much of this is similar logic as ibmvnic_probe(), -+ * we are essentially re-initializing communication -+ * with the server. We really should not run any -+ * resets/failovers here because this is already a form -+ * of reset and we do not want parallel resets occurring -+ */ -+ do { -+ reinit_init_done(adapter); -+ /* Clear any failovers we got in the previous -+ * pass since we are re-initializing the CRQ -+ */ -+ adapter->failover_pending = false; -+ release_crq_queue(adapter); -+ /* If we don't sleep here then we risk an -+ * unnecessary failover event from the VIOS. -+ * This is a known VIOS issue caused by a vnic -+ * device freeing and registering a CRQ too -+ * quickly. -+ */ -+ msleep(1500); -+ /* Avoid any resets, since we are currently -+ * resetting. -+ */ -+ spin_lock_irqsave(&adapter->rwi_lock, flags); -+ flush_reset_queue(adapter); -+ spin_unlock_irqrestore(&adapter->rwi_lock, -+ flags); -+ -+ rc = init_crq_queue(adapter); -+ if (rc) { -+ netdev_err(netdev, "login recovery: init CRQ failed %d\n", -+ rc); -+ return -EIO; -+ } -+ -+ rc = ibmvnic_reset_init(adapter, false); -+ if (rc) -+ netdev_err(netdev, "login recovery: Reset init failed %d\n", -+ rc); -+ /* IBMVNIC_CRQ_INIT will return EAGAIN if it -+ * fails, since ibmvnic_reset_init will free -+ * irq's in failure, we won't be able to receive -+ * new CRQs so we need to keep trying. probe() -+ * handles this similarly. -+ */ -+ } while (rc == -EAGAIN && retry_count++ < retries); - } - } while (retry); - -@@ -1397,12 +1457,22 @@ static int ibmvnic_login(struct net_device *netdev) - - static void release_login_buffer(struct ibmvnic_adapter *adapter) - { -+ if (!adapter->login_buf) -+ return; -+ -+ dma_unmap_single(&adapter->vdev->dev, adapter->login_buf_token, -+ adapter->login_buf_sz, DMA_TO_DEVICE); - kfree(adapter->login_buf); - adapter->login_buf = NULL; - } - - static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter) - { -+ if (!adapter->login_rsp_buf) -+ return; -+ -+ dma_unmap_single(&adapter->vdev->dev, adapter->login_rsp_buf_token, -+ adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); - kfree(adapter->login_rsp_buf); - adapter->login_rsp_buf = NULL; - } -@@ -4626,11 +4696,14 @@ static int send_login(struct ibmvnic_adapter *adapter) - if (rc) { - adapter->login_pending = false; - netdev_err(adapter->netdev, "Failed to send login, rc=%d\n", rc); -- goto buf_rsp_map_failed; -+ goto buf_send_failed; - } - - return 0; - -+buf_send_failed: -+ dma_unmap_single(dev, rsp_buffer_token, rsp_buffer_size, -+ DMA_FROM_DEVICE); - buf_rsp_map_failed: - kfree(login_rsp_buffer); - adapter->login_rsp_buf = NULL; -@@ -5192,6 +5265,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, - int num_tx_pools; - int num_rx_pools; - u64 *size_array; -+ u32 rsp_len; - int i; - - /* CHECK: Test/set of login_pending does not need to be atomic -@@ -5203,11 +5277,6 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, - } - adapter->login_pending = false; - -- dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz, -- DMA_TO_DEVICE); -- dma_unmap_single(dev, adapter->login_rsp_buf_token, -- adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); -- - /* If the number of queues requested can't be allocated by the - * server, the login response will return with code 1. We will need - * to resend the login buffer with fewer queues requested. -@@ -5243,6 +5312,23 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, - ibmvnic_reset(adapter, VNIC_RESET_FATAL); - return -EIO; - } -+ -+ rsp_len = be32_to_cpu(login_rsp->len); -+ if (be32_to_cpu(login->login_rsp_len) < rsp_len || -+ rsp_len <= be32_to_cpu(login_rsp->off_txsubm_subcrqs) || -+ rsp_len <= be32_to_cpu(login_rsp->off_rxadd_subcrqs) || -+ rsp_len <= be32_to_cpu(login_rsp->off_rxadd_buff_size) || -+ rsp_len <= be32_to_cpu(login_rsp->off_supp_tx_desc)) { -+ /* This can happen if a login request times out and there are -+ * 2 outstanding login requests sent, the LOGIN_RSP crq -+ * could have been for the older login request. So we are -+ * parsing the newer response buffer which may be incomplete -+ */ -+ dev_err(dev, "FATAL: Login rsp offsets/lengths invalid\n"); -+ ibmvnic_reset(adapter, VNIC_RESET_FATAL); -+ return -EIO; -+ } -+ - size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + - be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size)); - /* variable buffer sizes are not supported, so just read the -diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -index fd6d6f6263f66..f544d2b0abdbd 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -@@ -1401,14 +1401,15 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx - if (fsp->flow_type & FLOW_MAC_EXT) - return -EINVAL; - -+ spin_lock_bh(&adapter->fdir_fltr_lock); - if (adapter->fdir_active_fltr >= IAVF_MAX_FDIR_FILTERS) { -+ spin_unlock_bh(&adapter->fdir_fltr_lock); - dev_err(&adapter->pdev->dev, - "Unable to add Flow Director filter because VF reached the limit of max allowed filters (%u)\n", - IAVF_MAX_FDIR_FILTERS); - return -ENOSPC; - } - -- spin_lock_bh(&adapter->fdir_fltr_lock); - if (iavf_find_fdir_fltr_by_loc(adapter, fsp->location)) { - dev_err(&adapter->pdev->dev, "Failed to add Flow Director filter, it already exists\n"); - spin_unlock_bh(&adapter->fdir_fltr_lock); -@@ -1781,7 +1782,9 @@ static int iavf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, - case ETHTOOL_GRXCLSRLCNT: - if (!FDIR_FLTR_SUPPORT(adapter)) - break; -+ spin_lock_bh(&adapter->fdir_fltr_lock); - cmd->rule_cnt = adapter->fdir_active_fltr; -+ spin_unlock_bh(&adapter->fdir_fltr_lock); - cmd->data = IAVF_MAX_FDIR_FILTERS; - ret = 0; - break; -diff --git a/drivers/net/ethernet/intel/iavf/iavf_fdir.c b/drivers/net/ethernet/intel/iavf/iavf_fdir.c -index 6146203efd84a..505e82ebafe47 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_fdir.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_fdir.c -@@ -722,7 +722,9 @@ void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *f - bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr) - { - struct iavf_fdir_fltr *tmp; -+ bool ret = false; - -+ spin_lock_bh(&adapter->fdir_fltr_lock); - list_for_each_entry(tmp, &adapter->fdir_list_head, list) { - if (tmp->flow_type != fltr->flow_type) - continue; -@@ -732,11 +734,14 @@ bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr * - !memcmp(&tmp->ip_data, &fltr->ip_data, - sizeof(fltr->ip_data)) && - !memcmp(&tmp->ext_data, &fltr->ext_data, -- sizeof(fltr->ext_data))) -- return true; -+ sizeof(fltr->ext_data))) { -+ ret = true; -+ break; -+ } - } -+ spin_unlock_bh(&adapter->fdir_fltr_lock); - -- return false; -+ return ret; - } - - /** -diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router.c b/drivers/net/ethernet/marvell/prestera/prestera_router.c -index a9a1028cb17bb..de317179a7dcc 100644 ---- a/drivers/net/ethernet/marvell/prestera/prestera_router.c -+++ b/drivers/net/ethernet/marvell/prestera/prestera_router.c -@@ -166,11 +166,11 @@ prestera_util_neigh2nc_key(struct prestera_switch *sw, struct neighbour *n, - - static bool __prestera_fi_is_direct(struct fib_info *fi) - { -- struct fib_nh *fib_nh; -+ struct fib_nh_common *fib_nhc; - - if (fib_info_num_path(fi) == 1) { -- fib_nh = fib_info_nh(fi, 0); -- if (fib_nh->fib_nh_gw_family == AF_UNSPEC) -+ fib_nhc = fib_info_nhc(fi, 0); -+ if (fib_nhc->nhc_gw_family == AF_UNSPEC) - return true; - } - -@@ -261,7 +261,7 @@ static bool - __prestera_util_kern_n_is_reachable_v4(u32 tb_id, __be32 *addr, - struct net_device *dev) - { -- struct fib_nh *fib_nh; -+ struct fib_nh_common *fib_nhc; - struct fib_result res; - bool reachable; - -@@ -269,8 +269,8 @@ __prestera_util_kern_n_is_reachable_v4(u32 tb_id, __be32 *addr, - - if (!prestera_util_kern_get_route(&res, tb_id, addr)) - if (prestera_fi_is_direct(res.fi)) { -- fib_nh = fib_info_nh(res.fi, 0); -- if (dev == fib_nh->fib_nh_dev) -+ fib_nhc = fib_info_nhc(res.fi, 0); -+ if (dev == fib_nhc->nhc_dev) - reachable = true; - } - -@@ -324,7 +324,7 @@ prestera_kern_fib_info_nhc(struct fib_notifier_info *info, int n) - if (info->family == AF_INET) { - fen4_info = container_of(info, struct fib_entry_notifier_info, - info); -- return &fib_info_nh(fen4_info->fi, n)->nh_common; -+ return fib_info_nhc(fen4_info->fi, n); - } else if (info->family == AF_INET6) { - fen6_info = container_of(info, struct fib6_entry_notifier_info, - info); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c -index d3a3fe4ce6702..7d9bbb494d95b 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c -@@ -574,7 +574,7 @@ static int __mlx5_lag_modify_definers_destinations(struct mlx5_lag *ldev, - for (i = 0; i < ldev->ports; i++) { - for (j = 0; j < ldev->buckets; j++) { - idx = i * ldev->buckets + j; -- if (ldev->v2p_map[i] == ports[i]) -+ if (ldev->v2p_map[idx] == ports[idx]) - continue; - - dest.vport.vhca_id = MLX5_CAP_GEN(ldev->pf[ports[idx] - 1].dev, -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c -index d7ddfc489536e..2ac255bb918ba 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c -@@ -198,10 +198,15 @@ static void mlx5_timestamp_overflow(struct work_struct *work) - clock = container_of(timer, struct mlx5_clock, timer); - mdev = container_of(clock, struct mlx5_core_dev, clock); - -+ if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) -+ goto out; -+ - write_seqlock_irqsave(&clock->lock, flags); - timecounter_read(&timer->tc); - mlx5_update_clock_info_page(mdev); - write_sequnlock_irqrestore(&clock->lock, flags); -+ -+out: - schedule_delayed_work(&timer->overflow_work, timer->overflow_period); - } - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c -index 077204929fe4a..6ab0642e9de78 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/main.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c -@@ -1794,7 +1794,7 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev, - - mlx5_enter_error_state(dev, false); - mlx5_error_sw_reset(dev); -- mlx5_unload_one(dev, true); -+ mlx5_unload_one(dev, false); - mlx5_drain_health_wq(dev); - mlx5_pci_disable_device(dev); - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c -index 20d7662c10fb6..5f2195e65dd62 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c -@@ -264,8 +264,7 @@ static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev) - host_total_vfs = MLX5_GET(query_esw_functions_out, out, - host_params_context.host_total_vfs); - kvfree(out); -- if (host_total_vfs) -- return host_total_vfs; -+ return host_total_vfs; - } - - done: -diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c -index 27a0f3af8aab4..4f4204432aaa3 100644 ---- a/drivers/net/ethernet/microsoft/mana/mana_en.c -+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -1972,9 +1973,12 @@ int mana_attach(struct net_device *ndev) - static int mana_dealloc_queues(struct net_device *ndev) - { - struct mana_port_context *apc = netdev_priv(ndev); -+ unsigned long timeout = jiffies + 120 * HZ; - struct gdma_dev *gd = apc->ac->gdma_dev; - struct mana_txq *txq; -+ struct sk_buff *skb; - int i, err; -+ u32 tsleep; - - if (apc->port_is_up) - return -EINVAL; -@@ -1990,15 +1994,40 @@ static int mana_dealloc_queues(struct net_device *ndev) - * to false, but it doesn't matter since mana_start_xmit() drops any - * new packets due to apc->port_is_up being false. - * -- * Drain all the in-flight TX packets -+ * Drain all the in-flight TX packets. -+ * A timeout of 120 seconds for all the queues is used. -+ * This will break the while loop when h/w is not responding. -+ * This value of 120 has been decided here considering max -+ * number of queues. - */ -+ - for (i = 0; i < apc->num_queues; i++) { - txq = &apc->tx_qp[i].txq; -- -- while (atomic_read(&txq->pending_sends) > 0) -- usleep_range(1000, 2000); -+ tsleep = 1000; -+ while (atomic_read(&txq->pending_sends) > 0 && -+ time_before(jiffies, timeout)) { -+ usleep_range(tsleep, tsleep + 1000); -+ tsleep <<= 1; -+ } -+ if (atomic_read(&txq->pending_sends)) { -+ err = pcie_flr(to_pci_dev(gd->gdma_context->dev)); -+ if (err) { -+ netdev_err(ndev, "flr failed %d with %d pkts pending in txq %u\n", -+ err, atomic_read(&txq->pending_sends), -+ txq->gdma_txq_id); -+ } -+ break; -+ } - } - -+ for (i = 0; i < apc->num_queues; i++) { -+ txq = &apc->tx_qp[i].txq; -+ while ((skb = skb_dequeue(&txq->pending_skbs))) { -+ mana_unmap_skb(skb, apc); -+ dev_kfree_skb_any(skb); -+ } -+ atomic_set(&txq->pending_sends, 0); -+ } - /* We're 100% sure the queues can no longer be woken up, because - * we're sure now mana_poll_tx_cq() can't be running. - */ -diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c -index 983cabf9a0f67..6a7965ed63001 100644 ---- a/drivers/net/macsec.c -+++ b/drivers/net/macsec.c -@@ -743,7 +743,7 @@ static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u - u64_stats_update_begin(&rxsc_stats->syncp); - rxsc_stats->stats.InPktsLate++; - u64_stats_update_end(&rxsc_stats->syncp); -- secy->netdev->stats.rx_dropped++; -+ DEV_STATS_INC(secy->netdev, rx_dropped); - return false; - } - -@@ -767,7 +767,7 @@ static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u - rxsc_stats->stats.InPktsNotValid++; - u64_stats_update_end(&rxsc_stats->syncp); - this_cpu_inc(rx_sa->stats->InPktsNotValid); -- secy->netdev->stats.rx_errors++; -+ DEV_STATS_INC(secy->netdev, rx_errors); - return false; - } - -@@ -1059,7 +1059,7 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb) - u64_stats_update_begin(&secy_stats->syncp); - secy_stats->stats.InPktsNoTag++; - u64_stats_update_end(&secy_stats->syncp); -- macsec->secy.netdev->stats.rx_dropped++; -+ DEV_STATS_INC(macsec->secy.netdev, rx_dropped); - continue; - } - -@@ -1169,7 +1169,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) - u64_stats_update_begin(&secy_stats->syncp); - secy_stats->stats.InPktsBadTag++; - u64_stats_update_end(&secy_stats->syncp); -- secy->netdev->stats.rx_errors++; -+ DEV_STATS_INC(secy->netdev, rx_errors); - goto drop_nosa; - } - -@@ -1186,7 +1186,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) - u64_stats_update_begin(&rxsc_stats->syncp); - rxsc_stats->stats.InPktsNotUsingSA++; - u64_stats_update_end(&rxsc_stats->syncp); -- secy->netdev->stats.rx_errors++; -+ DEV_STATS_INC(secy->netdev, rx_errors); - if (active_rx_sa) - this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA); - goto drop_nosa; -@@ -1220,7 +1220,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) - u64_stats_update_begin(&rxsc_stats->syncp); - rxsc_stats->stats.InPktsLate++; - u64_stats_update_end(&rxsc_stats->syncp); -- macsec->secy.netdev->stats.rx_dropped++; -+ DEV_STATS_INC(macsec->secy.netdev, rx_dropped); - goto drop; - } - } -@@ -1261,7 +1261,7 @@ deliver: - if (ret == NET_RX_SUCCESS) - count_rx(dev, len); - else -- macsec->secy.netdev->stats.rx_dropped++; -+ DEV_STATS_INC(macsec->secy.netdev, rx_dropped); - - rcu_read_unlock(); - -@@ -1298,7 +1298,7 @@ nosci: - u64_stats_update_begin(&secy_stats->syncp); - secy_stats->stats.InPktsNoSCI++; - u64_stats_update_end(&secy_stats->syncp); -- macsec->secy.netdev->stats.rx_errors++; -+ DEV_STATS_INC(macsec->secy.netdev, rx_errors); - continue; - } - -@@ -1317,7 +1317,7 @@ nosci: - secy_stats->stats.InPktsUnknownSCI++; - u64_stats_update_end(&secy_stats->syncp); - } else { -- macsec->secy.netdev->stats.rx_dropped++; -+ DEV_STATS_INC(macsec->secy.netdev, rx_dropped); - } - } - -@@ -3418,7 +3418,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, - - if (!secy->operational) { - kfree_skb(skb); -- dev->stats.tx_dropped++; -+ DEV_STATS_INC(dev, tx_dropped); - return NETDEV_TX_OK; - } - -@@ -3426,7 +3426,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, - skb = macsec_encrypt(skb, dev); - if (IS_ERR(skb)) { - if (PTR_ERR(skb) != -EINPROGRESS) -- dev->stats.tx_dropped++; -+ DEV_STATS_INC(dev, tx_dropped); - return NETDEV_TX_OK; - } - -@@ -3663,9 +3663,9 @@ static void macsec_get_stats64(struct net_device *dev, - - dev_fetch_sw_netstats(s, dev->tstats); - -- s->rx_dropped = dev->stats.rx_dropped; -- s->tx_dropped = dev->stats.tx_dropped; -- s->rx_errors = dev->stats.rx_errors; -+ s->rx_dropped = atomic_long_read(&dev->stats.__rx_dropped); -+ s->tx_dropped = atomic_long_read(&dev->stats.__tx_dropped); -+ s->rx_errors = atomic_long_read(&dev->stats.__rx_errors); - } - - static int macsec_get_iflink(const struct net_device *dev) -diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c -index d499659075614..61824a463df85 100644 ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -2087,8 +2087,6 @@ static struct phy_driver at803x_driver[] = { - .flags = PHY_POLL_CABLE_TEST, - .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, -- .set_wol = at803x_set_wol, -- .get_wol = at803x_get_wol, - .suspend = at803x_suspend, - .resume = at803x_resume, - /* PHY_BASIC_FEATURES */ -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index 228f5f9ef1dde..7544df1ff50ec 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -1588,7 +1588,7 @@ static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile, - if (zerocopy) - return false; - -- if (SKB_DATA_ALIGN(len + TUN_RX_PAD) + -+ if (SKB_DATA_ALIGN(len + TUN_RX_PAD + XDP_PACKET_HEADROOM) + - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) > PAGE_SIZE) - return false; - -diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c -index 3e04af4c5daa1..c5cf55030158f 100644 ---- a/drivers/net/vxlan/vxlan_vnifilter.c -+++ b/drivers/net/vxlan/vxlan_vnifilter.c -@@ -713,6 +713,12 @@ static struct vxlan_vni_node *vxlan_vni_alloc(struct vxlan_dev *vxlan, - return vninode; - } - -+static void vxlan_vni_free(struct vxlan_vni_node *vninode) -+{ -+ free_percpu(vninode->stats); -+ kfree(vninode); -+} -+ - static int vxlan_vni_add(struct vxlan_dev *vxlan, - struct vxlan_vni_group *vg, - u32 vni, union vxlan_addr *group, -@@ -740,7 +746,7 @@ static int vxlan_vni_add(struct vxlan_dev *vxlan, - &vninode->vnode, - vxlan_vni_rht_params); - if (err) { -- kfree(vninode); -+ vxlan_vni_free(vninode); - return err; - } - -@@ -763,8 +769,7 @@ static void vxlan_vni_node_rcu_free(struct rcu_head *rcu) - struct vxlan_vni_node *v; - - v = container_of(rcu, struct vxlan_vni_node, rcu); -- free_percpu(v->stats); -- kfree(v); -+ vxlan_vni_free(v); - } - - static int vxlan_vni_del(struct vxlan_dev *vxlan, -diff --git a/drivers/net/wireguard/allowedips.c b/drivers/net/wireguard/allowedips.c -index 5bf7822c53f18..0ba714ca5185c 100644 ---- a/drivers/net/wireguard/allowedips.c -+++ b/drivers/net/wireguard/allowedips.c -@@ -6,7 +6,7 @@ - #include "allowedips.h" - #include "peer.h" - --enum { MAX_ALLOWEDIPS_BITS = 128 }; -+enum { MAX_ALLOWEDIPS_DEPTH = 129 }; - - static struct kmem_cache *node_cache; - -@@ -42,7 +42,7 @@ static void push_rcu(struct allowedips_node **stack, - struct allowedips_node __rcu *p, unsigned int *len) - { - if (rcu_access_pointer(p)) { -- if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_BITS)) -+ if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_DEPTH)) - return; - stack[(*len)++] = rcu_dereference_raw(p); - } -@@ -55,7 +55,7 @@ static void node_free_rcu(struct rcu_head *rcu) - - static void root_free_rcu(struct rcu_head *rcu) - { -- struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { -+ struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = { - container_of(rcu, struct allowedips_node, rcu) }; - unsigned int len = 1; - -@@ -68,7 +68,7 @@ static void root_free_rcu(struct rcu_head *rcu) - - static void root_remove_peer_lists(struct allowedips_node *root) - { -- struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { root }; -+ struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = { root }; - unsigned int len = 1; - - while (len > 0 && (node = stack[--len])) { -diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c -index 19eac00b23814..c51c794e70a0e 100644 ---- a/drivers/net/wireguard/selftest/allowedips.c -+++ b/drivers/net/wireguard/selftest/allowedips.c -@@ -593,16 +593,20 @@ bool __init wg_allowedips_selftest(void) - wg_allowedips_remove_by_peer(&t, a, &mutex); - test_negative(4, a, 192, 168, 0, 1); - -- /* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_BITS) in free_node -+ /* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_DEPTH) in free_node - * if something goes wrong. - */ -- for (i = 0; i < MAX_ALLOWEDIPS_BITS; ++i) { -- part = cpu_to_be64(~(1LLU << (i % 64))); -- memset(&ip, 0xff, 16); -- memcpy((u8 *)&ip + (i < 64) * 8, &part, 8); -+ for (i = 0; i < 64; ++i) { -+ part = cpu_to_be64(~0LLU << i); -+ memset(&ip, 0xff, 8); -+ memcpy((u8 *)&ip + 8, &part, 8); -+ wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex); -+ memcpy(&ip, &part, 8); -+ memset((u8 *)&ip + 8, 0, 8); - wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex); - } -- -+ memset(&ip, 0, 16); -+ wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex); - wg_allowedips_free(&t, &mutex); - - wg_allowedips_init(&t); -diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c -index 077fddc5fa1ea..4a1c9e18c5301 100644 ---- a/drivers/net/wireless/realtek/rtw89/mac.c -+++ b/drivers/net/wireless/realtek/rtw89/mac.c -@@ -2209,7 +2209,7 @@ static int cmac_dma_init(struct rtw89_dev *rtwdev, u8 mac_idx) - u32 reg; - int ret; - -- if (chip_id != RTL8852A && chip_id != RTL8852B) -+ if (chip_id != RTL8852B) - return 0; - - ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index ce2e628f94a05..b30269f5e68fb 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -3504,7 +3504,8 @@ static const struct pci_device_id nvme_id_table[] = { - { PCI_DEVICE(0x1d97, 0x2263), /* SPCC */ - .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, - { PCI_DEVICE(0x144d, 0xa80b), /* Samsung PM9B1 256G and 512G */ -- .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, -+ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES | -+ NVME_QUIRK_BOGUS_NID, }, - { PCI_DEVICE(0x144d, 0xa809), /* Samsung MZALQ256HBJD 256G */ - .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, - { PCI_DEVICE(0x1cc4, 0x6303), /* UMIS RPJTJ512MGE1QDY 512G */ -diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c -index 80383213b8828..c478480f54aa2 100644 ---- a/drivers/nvme/host/rdma.c -+++ b/drivers/nvme/host/rdma.c -@@ -923,6 +923,7 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new) - goto out_cleanup_tagset; - - if (!new) { -+ nvme_start_freeze(&ctrl->ctrl); - nvme_start_queues(&ctrl->ctrl); - if (!nvme_wait_freeze_timeout(&ctrl->ctrl, NVME_IO_TIMEOUT)) { - /* -@@ -931,6 +932,7 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new) - * to be safe. - */ - ret = -ENODEV; -+ nvme_unfreeze(&ctrl->ctrl); - goto out_wait_freeze_timed_out; - } - blk_mq_update_nr_hw_queues(ctrl->ctrl.tagset, -@@ -980,7 +982,6 @@ static void nvme_rdma_teardown_io_queues(struct nvme_rdma_ctrl *ctrl, - bool remove) - { - if (ctrl->ctrl.queue_count > 1) { -- nvme_start_freeze(&ctrl->ctrl); - nvme_stop_queues(&ctrl->ctrl); - nvme_sync_io_queues(&ctrl->ctrl); - nvme_rdma_stop_io_queues(ctrl); -diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c -index 8f17cbec5a0e4..f2fedd25915f9 100644 ---- a/drivers/nvme/host/tcp.c -+++ b/drivers/nvme/host/tcp.c -@@ -1890,6 +1890,7 @@ static int nvme_tcp_configure_io_queues(struct nvme_ctrl *ctrl, bool new) - goto out_cleanup_connect_q; - - if (!new) { -+ nvme_start_freeze(ctrl); - nvme_start_queues(ctrl); - if (!nvme_wait_freeze_timeout(ctrl, NVME_IO_TIMEOUT)) { - /* -@@ -1898,6 +1899,7 @@ static int nvme_tcp_configure_io_queues(struct nvme_ctrl *ctrl, bool new) - * to be safe. - */ - ret = -ENODEV; -+ nvme_unfreeze(ctrl); - goto out_wait_freeze_timed_out; - } - blk_mq_update_nr_hw_queues(ctrl->tagset, -@@ -2002,7 +2004,6 @@ static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl, - if (ctrl->queue_count <= 1) - return; - nvme_stop_admin_queue(ctrl); -- nvme_start_freeze(ctrl); - nvme_stop_queues(ctrl); - nvme_sync_io_queues(ctrl); - nvme_tcp_stop_io_queues(ctrl); -diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c -index 5362f1a7b77c5..7a9c758e95472 100644 ---- a/drivers/platform/x86/serial-multi-instantiate.c -+++ b/drivers/platform/x86/serial-multi-instantiate.c -@@ -21,6 +21,7 @@ - #define IRQ_RESOURCE_NONE 0 - #define IRQ_RESOURCE_GPIO 1 - #define IRQ_RESOURCE_APIC 2 -+#define IRQ_RESOURCE_AUTO 3 - - enum smi_bus_type { - SMI_I2C, -@@ -52,6 +53,18 @@ static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev, - int ret; - - switch (inst->flags & IRQ_RESOURCE_TYPE) { -+ case IRQ_RESOURCE_AUTO: -+ ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); -+ if (ret > 0) { -+ dev_dbg(&pdev->dev, "Using gpio irq\n"); -+ break; -+ } -+ ret = platform_get_irq(pdev, inst->irq_idx); -+ if (ret > 0) { -+ dev_dbg(&pdev->dev, "Using platform irq\n"); -+ break; -+ } -+ break; - case IRQ_RESOURCE_GPIO: - ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); - break; -@@ -308,10 +321,23 @@ static const struct smi_node int3515_data = { - - static const struct smi_node cs35l41_hda = { - .instances = { -- { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, -- { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, -- { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, -- { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, -+ { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, -+ { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, -+ { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, -+ { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, -+ {} -+ }, -+ .bus_type = SMI_AUTO_DETECT, -+}; -+ -+static const struct smi_node cs35l56_hda = { -+ .instances = { -+ { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, -+ { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, -+ { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, -+ { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, -+ /* a 5th entry is an alias address, not a real device */ -+ { "cs35l56-hda_dummy_dev" }, - {} - }, - .bus_type = SMI_AUTO_DETECT, -@@ -325,6 +351,7 @@ static const struct acpi_device_id smi_acpi_ids[] = { - { "BSG1160", (unsigned long)&bsg1160_data }, - { "BSG2150", (unsigned long)&bsg2150_data }, - { "CSC3551", (unsigned long)&cs35l41_hda }, -+ { "CSC3556", (unsigned long)&cs35l56_hda }, - { "INT3515", (unsigned long)&int3515_data }, - /* Non-conforming _HID for Cirrus Logic already released */ - { "CLSA0100", (unsigned long)&cs35l41_hda }, -diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c -index e1e4f9d108879..857be0f3ae5b9 100644 ---- a/drivers/scsi/53c700.c -+++ b/drivers/scsi/53c700.c -@@ -1598,7 +1598,7 @@ NCR_700_intr(int irq, void *dev_id) - printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG))); - #endif - resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch; -- } else if(dsp >= to32bit(&slot->pSG[0].ins) && -+ } else if (slot && dsp >= to32bit(&slot->pSG[0].ins) && - dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) { - int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff; - int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List); -diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h -index d82de34f6fd73..e51e92f932fa8 100644 ---- a/drivers/scsi/fnic/fnic.h -+++ b/drivers/scsi/fnic/fnic.h -@@ -27,7 +27,7 @@ - - #define DRV_NAME "fnic" - #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" --#define DRV_VERSION "1.6.0.54" -+#define DRV_VERSION "1.6.0.55" - #define PFX DRV_NAME ": " - #define DFX DRV_NAME "%d: " - -diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c -index 26dbd347156ef..be89ce96df46c 100644 ---- a/drivers/scsi/fnic/fnic_scsi.c -+++ b/drivers/scsi/fnic/fnic_scsi.c -@@ -2139,7 +2139,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, - bool new_sc) - - { -- int ret = SUCCESS; -+ int ret = 0; - struct fnic_pending_aborts_iter_data iter_data = { - .fnic = fnic, - .lun_dev = lr_sc->device, -@@ -2159,9 +2159,11 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, - - /* walk again to check, if IOs are still pending in fw */ - if (fnic_is_abts_pending(fnic, lr_sc)) -- ret = FAILED; -+ ret = 1; - - clean_pending_aborts_end: -+ FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, -+ "%s: exit status: %d\n", __func__, ret); - return ret; - } - -diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c -index ecff2ec83a002..c4f293d39f228 100644 ---- a/drivers/scsi/qedf/qedf_main.c -+++ b/drivers/scsi/qedf/qedf_main.c -@@ -31,6 +31,7 @@ static void qedf_remove(struct pci_dev *pdev); - static void qedf_shutdown(struct pci_dev *pdev); - static void qedf_schedule_recovery_handler(void *dev); - static void qedf_recovery_handler(struct work_struct *work); -+static int qedf_suspend(struct pci_dev *pdev, pm_message_t state); - - /* - * Driver module parameters. -@@ -3276,6 +3277,7 @@ static struct pci_driver qedf_pci_driver = { - .probe = qedf_probe, - .remove = qedf_remove, - .shutdown = qedf_shutdown, -+ .suspend = qedf_suspend, - }; - - static int __qedf_probe(struct pci_dev *pdev, int mode) -@@ -4005,6 +4007,22 @@ static void qedf_shutdown(struct pci_dev *pdev) - __qedf_remove(pdev, QEDF_MODE_NORMAL); - } - -+static int qedf_suspend(struct pci_dev *pdev, pm_message_t state) -+{ -+ struct qedf_ctx *qedf; -+ -+ if (!pdev) { -+ QEDF_ERR(NULL, "pdev is NULL.\n"); -+ return -ENODEV; -+ } -+ -+ qedf = pci_get_drvdata(pdev); -+ -+ QEDF_ERR(&qedf->dbg_ctx, "%s: Device does not support suspend operation\n", __func__); -+ -+ return -EPERM; -+} -+ - /* - * Recovery handler code - */ -diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c -index f530bb0364939..9fd68d362698f 100644 ---- a/drivers/scsi/qedi/qedi_main.c -+++ b/drivers/scsi/qedi/qedi_main.c -@@ -69,6 +69,7 @@ static struct nvm_iscsi_block *qedi_get_nvram_block(struct qedi_ctx *qedi); - static void qedi_recovery_handler(struct work_struct *work); - static void qedi_schedule_hw_err_handler(void *dev, - enum qed_hw_err_type err_type); -+static int qedi_suspend(struct pci_dev *pdev, pm_message_t state); - - static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle) - { -@@ -2510,6 +2511,22 @@ static void qedi_shutdown(struct pci_dev *pdev) - __qedi_remove(pdev, QEDI_MODE_SHUTDOWN); - } - -+static int qedi_suspend(struct pci_dev *pdev, pm_message_t state) -+{ -+ struct qedi_ctx *qedi; -+ -+ if (!pdev) { -+ QEDI_ERR(NULL, "pdev is NULL.\n"); -+ return -ENODEV; -+ } -+ -+ qedi = pci_get_drvdata(pdev); -+ -+ QEDI_ERR(&qedi->dbg_ctx, "%s: Device does not support suspend operation\n", __func__); -+ -+ return -EPERM; -+} -+ - static int __qedi_probe(struct pci_dev *pdev, int mode) - { - struct qedi_ctx *qedi; -@@ -2868,6 +2885,7 @@ static struct pci_driver qedi_pci_driver = { - .remove = qedi_remove, - .shutdown = qedi_shutdown, - .err_handler = &qedi_err_handler, -+ .suspend = qedi_suspend, - }; - - static int __init qedi_init(void) -diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c -index 898a0bdf8df67..711252e52d8e1 100644 ---- a/drivers/scsi/raid_class.c -+++ b/drivers/scsi/raid_class.c -@@ -248,6 +248,7 @@ int raid_component_add(struct raid_template *r,struct device *raid_dev, - return 0; - - err_out: -+ put_device(&rc->dev); - list_del(&rc->node); - rd->component_count--; - put_device(component_dev); -diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c -index 95aee1ad13834..7184e169a4a51 100644 ---- a/drivers/scsi/scsi_proc.c -+++ b/drivers/scsi/scsi_proc.c -@@ -311,7 +311,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, - size_t length, loff_t *ppos) - { - int host, channel, id, lun; -- char *buffer, *p; -+ char *buffer, *end, *p; - int err; - - if (!buf || length > PAGE_SIZE) -@@ -326,10 +326,14 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, - goto out; - - err = -EINVAL; -- if (length < PAGE_SIZE) -- buffer[length] = '\0'; -- else if (buffer[PAGE_SIZE-1]) -- goto out; -+ if (length < PAGE_SIZE) { -+ end = buffer + length; -+ *end = '\0'; -+ } else { -+ end = buffer + PAGE_SIZE - 1; -+ if (*end) -+ goto out; -+ } - - /* - * Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi -@@ -338,10 +342,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, - if (!strncmp("scsi add-single-device", buffer, 22)) { - p = buffer + 23; - -- host = simple_strtoul(p, &p, 0); -- channel = simple_strtoul(p + 1, &p, 0); -- id = simple_strtoul(p + 1, &p, 0); -- lun = simple_strtoul(p + 1, &p, 0); -+ host = (p < end) ? simple_strtoul(p, &p, 0) : 0; -+ channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; -+ id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; -+ lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; - - err = scsi_add_single_device(host, channel, id, lun); - -@@ -352,10 +356,10 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, - } else if (!strncmp("scsi remove-single-device", buffer, 25)) { - p = buffer + 26; - -- host = simple_strtoul(p, &p, 0); -- channel = simple_strtoul(p + 1, &p, 0); -- id = simple_strtoul(p + 1, &p, 0); -- lun = simple_strtoul(p + 1, &p, 0); -+ host = (p < end) ? simple_strtoul(p, &p, 0) : 0; -+ channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; -+ id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; -+ lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; - - err = scsi_remove_single_device(host, channel, id, lun); - } -diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c -index 8fbf3c1b1311d..cd27562ec922e 100644 ---- a/drivers/scsi/snic/snic_disc.c -+++ b/drivers/scsi/snic/snic_disc.c -@@ -303,6 +303,7 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid) - "Snic Tgt: device_add, with err = %d\n", - ret); - -+ put_device(&tgt->dev); - put_device(&snic->shost->shost_gendev); - spin_lock_irqsave(snic->shost->host_lock, flags); - list_del(&tgt->list); -diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c -index 54a1b8514f04b..83d09c2009280 100644 ---- a/drivers/scsi/storvsc_drv.c -+++ b/drivers/scsi/storvsc_drv.c -@@ -1670,10 +1670,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) - */ - static enum blk_eh_timer_return storvsc_eh_timed_out(struct scsi_cmnd *scmnd) - { --#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) -- if (scmnd->device->host->transportt == fc_transport_template) -- return fc_eh_timed_out(scmnd); --#endif - return BLK_EH_RESET_TIMER; - } - -diff --git a/drivers/ufs/host/ufs-renesas.c b/drivers/ufs/host/ufs-renesas.c -index f8a5e79ed3b4e..ab0652d8705ac 100644 ---- a/drivers/ufs/host/ufs-renesas.c -+++ b/drivers/ufs/host/ufs-renesas.c -@@ -359,7 +359,7 @@ static int ufs_renesas_init(struct ufs_hba *hba) - { - struct ufs_renesas_priv *priv; - -- priv = devm_kmalloc(hba->dev, sizeof(*priv), GFP_KERNEL); -+ priv = devm_kzalloc(hba->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - ufshcd_set_variant(hba, priv); -diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c -index e20874caba363..3f5180d64931b 100644 ---- a/drivers/usb/common/usb-conn-gpio.c -+++ b/drivers/usb/common/usb-conn-gpio.c -@@ -42,6 +42,7 @@ struct usb_conn_info { - - struct power_supply_desc desc; - struct power_supply *charger; -+ bool initial_detection; - }; - - /* -@@ -86,11 +87,13 @@ static void usb_conn_detect_cable(struct work_struct *work) - dev_dbg(info->dev, "role %s -> %s, gpios: id %d, vbus %d\n", - usb_role_string(info->last_role), usb_role_string(role), id, vbus); - -- if (info->last_role == role) { -+ if (!info->initial_detection && info->last_role == role) { - dev_warn(info->dev, "repeated role: %s\n", usb_role_string(role)); - return; - } - -+ info->initial_detection = false; -+ - if (info->last_role == USB_ROLE_HOST && info->vbus) - regulator_disable(info->vbus); - -@@ -258,6 +261,7 @@ static int usb_conn_probe(struct platform_device *pdev) - device_set_wakeup_capable(&pdev->dev, true); - - /* Perform initial detection */ -+ info->initial_detection = true; - usb_conn_queue_dwork(info, 0); - - return 0; -diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c -index c3590a0c42035..137602d9076fd 100644 ---- a/drivers/usb/dwc3/gadget.c -+++ b/drivers/usb/dwc3/gadget.c -@@ -4342,9 +4342,14 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) - u32 count; - - if (pm_runtime_suspended(dwc->dev)) { -+ dwc->pending_events = true; -+ /* -+ * Trigger runtime resume. The get() function will be balanced -+ * after processing the pending events in dwc3_process_pending -+ * events(). -+ */ - pm_runtime_get(dwc->dev); - disable_irq_nosync(dwc->irq_gadget); -- dwc->pending_events = true; - return IRQ_HANDLED; - } - -@@ -4609,6 +4614,8 @@ void dwc3_gadget_process_pending_events(struct dwc3 *dwc) - { - if (dwc->pending_events) { - dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf); -+ dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf); -+ pm_runtime_put(dwc->dev); - dwc->pending_events = false; - enable_irq(dwc->irq_gadget); - } -diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c -index 139f471894fb5..316e9cc3987be 100644 ---- a/drivers/usb/gadget/udc/core.c -+++ b/drivers/usb/gadget/udc/core.c -@@ -795,6 +795,9 @@ EXPORT_SYMBOL_GPL(usb_gadget_disconnect); - * usb_gadget_activate() is called. For example, user mode components may - * need to be activated before the system can talk to hosts. - * -+ * This routine may sleep; it must not be called in interrupt context -+ * (such as from within a gadget driver's disconnect() callback). -+ * - * Returns zero on success, else negative errno. - */ - int usb_gadget_deactivate(struct usb_gadget *gadget) -@@ -833,6 +836,8 @@ EXPORT_SYMBOL_GPL(usb_gadget_deactivate); - * This routine activates gadget which was previously deactivated with - * usb_gadget_deactivate() call. It calls usb_gadget_connect() if needed. - * -+ * This routine may sleep; it must not be called in interrupt context. -+ * - * Returns zero on success, else negative errno. - */ - int usb_gadget_activate(struct usb_gadget *gadget) -@@ -1611,7 +1616,11 @@ static void gadget_unbind_driver(struct device *dev) - usb_gadget_disable_async_callbacks(udc); - if (gadget->irq) - synchronize_irq(gadget->irq); -+ mutex_unlock(&udc->connect_lock); -+ - udc->driver->unbind(gadget); -+ -+ mutex_lock(&udc->connect_lock); - usb_gadget_udc_stop_locked(udc); - mutex_unlock(&udc->connect_lock); - -diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c -index 5e912dd29b4c9..115f05a6201a1 100644 ---- a/drivers/usb/storage/alauda.c -+++ b/drivers/usb/storage/alauda.c -@@ -318,7 +318,8 @@ static int alauda_get_media_status(struct us_data *us, unsigned char *data) - rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, - command, 0xc0, 0, 1, data, 2); - -- usb_stor_dbg(us, "Media status %02X %02X\n", data[0], data[1]); -+ if (rc == USB_STOR_XFER_GOOD) -+ usb_stor_dbg(us, "Media status %02X %02X\n", data[0], data[1]); - - return rc; - } -@@ -454,9 +455,14 @@ static int alauda_init_media(struct us_data *us) - static int alauda_check_media(struct us_data *us) - { - struct alauda_info *info = (struct alauda_info *) us->extra; -- unsigned char status[2]; -+ unsigned char *status = us->iobuf; -+ int rc; - -- alauda_get_media_status(us, status); -+ rc = alauda_get_media_status(us, status); -+ if (rc != USB_STOR_XFER_GOOD) { -+ status[0] = 0xF0; /* Pretend there's no media */ -+ status[1] = 0; -+ } - - /* Check for no media or door open */ - if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10) -diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c -index 7cdf83f4c811b..7a3caf556dae9 100644 ---- a/drivers/usb/typec/altmodes/displayport.c -+++ b/drivers/usb/typec/altmodes/displayport.c -@@ -60,6 +60,7 @@ struct dp_altmode { - - enum dp_state state; - bool hpd; -+ bool pending_hpd; - - struct mutex lock; /* device lock */ - struct work_struct work; -@@ -144,8 +145,13 @@ static int dp_altmode_status_update(struct dp_altmode *dp) - dp->state = DP_STATE_EXIT; - } else if (!(con & DP_CONF_CURRENTLY(dp->data.conf))) { - ret = dp_altmode_configure(dp, con); -- if (!ret) -+ if (!ret) { - dp->state = DP_STATE_CONFIGURE; -+ if (dp->hpd != hpd) { -+ dp->hpd = hpd; -+ dp->pending_hpd = true; -+ } -+ } - } else { - if (dp->hpd != hpd) { - drm_connector_oob_hotplug_event(dp->connector_fwnode); -@@ -160,6 +166,16 @@ static int dp_altmode_configured(struct dp_altmode *dp) - { - sysfs_notify(&dp->alt->dev.kobj, "displayport", "configuration"); - sysfs_notify(&dp->alt->dev.kobj, "displayport", "pin_assignment"); -+ /* -+ * If the DFP_D/UFP_D sends a change in HPD when first notifying the -+ * DisplayPort driver that it is connected, then we wait until -+ * configuration is complete to signal HPD. -+ */ -+ if (dp->pending_hpd) { -+ drm_connector_oob_hotplug_event(dp->connector_fwnode); -+ sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd"); -+ dp->pending_hpd = false; -+ } - - return dp_altmode_notify(dp); - } -diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c -index 524099634a1d4..d5950ef9d1f35 100644 ---- a/drivers/usb/typec/tcpm/tcpm.c -+++ b/drivers/usb/typec/tcpm/tcpm.c -@@ -5322,6 +5322,10 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) - /* Do nothing, vbus drop expected */ - break; - -+ case SNK_HARD_RESET_WAIT_VBUS: -+ /* Do nothing, its OK to receive vbus off events */ -+ break; -+ - default: - if (port->pwr_role == TYPEC_SINK && port->attached) - tcpm_set_state(port, SNK_UNATTACHED, tcpm_wait_for_discharge(port)); -@@ -5368,6 +5372,9 @@ static void _tcpm_pd_vbus_vsafe0v(struct tcpm_port *port) - case SNK_DEBOUNCED: - /*Do nothing, still waiting for VSAFE5V for connect */ - break; -+ case SNK_HARD_RESET_WAIT_VBUS: -+ /* Do nothing, its OK to receive vbus off events */ -+ break; - default: - if (port->pwr_role == TYPEC_SINK && port->auto_vbus_discharge_enabled) - tcpm_set_state(port, SNK_UNATTACHED, 0); -diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c -index d7aad5e8ee377..3495bc775afa3 100644 ---- a/fs/btrfs/block-group.c -+++ b/fs/btrfs/block-group.c -@@ -436,13 +436,23 @@ void btrfs_wait_block_group_cache_progress(struct btrfs_block_group *cache, - u64 num_bytes) - { - struct btrfs_caching_control *caching_ctl; -+ int progress; - - caching_ctl = btrfs_get_caching_control(cache); - if (!caching_ctl) - return; - -+ /* -+ * We've already failed to allocate from this block group, so even if -+ * there's enough space in the block group it isn't contiguous enough to -+ * allow for an allocation, so wait for at least the next wakeup tick, -+ * or for the thing to be done. -+ */ -+ progress = atomic_read(&caching_ctl->progress); -+ - wait_event(caching_ctl->wait, btrfs_block_group_done(cache) || -- (cache->free_space_ctl->free_space >= num_bytes)); -+ (progress != atomic_read(&caching_ctl->progress) && -+ (cache->free_space_ctl->free_space >= num_bytes))); - - btrfs_put_caching_control(caching_ctl); - } -@@ -660,8 +670,10 @@ next: - - if (total_found > CACHING_CTL_WAKE_UP) { - total_found = 0; -- if (wakeup) -+ if (wakeup) { -+ atomic_inc(&caching_ctl->progress); - wake_up(&caching_ctl->wait); -+ } - } - } - path->slots[0]++; -@@ -767,6 +779,7 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait) - init_waitqueue_head(&caching_ctl->wait); - caching_ctl->block_group = cache; - refcount_set(&caching_ctl->count, 2); -+ atomic_set(&caching_ctl->progress, 0); - btrfs_init_work(&caching_ctl->work, caching_thread, NULL, NULL); - - spin_lock(&cache->lock); -diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h -index 0a3d386823583..debd42aeae0f1 100644 ---- a/fs/btrfs/block-group.h -+++ b/fs/btrfs/block-group.h -@@ -70,6 +70,8 @@ struct btrfs_caching_control { - wait_queue_head_t wait; - struct btrfs_work work; - struct btrfs_block_group *block_group; -+ /* Track progress of caching during allocation. */ -+ atomic_t progress; - refcount_t count; - }; - -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index f22e00dfec6c4..96369c44863a1 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -1455,7 +1455,8 @@ static int btrfs_init_fs_root(struct btrfs_root *root, dev_t anon_dev) - goto fail; - - if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID && -- !btrfs_is_data_reloc_root(root)) { -+ !btrfs_is_data_reloc_root(root) && -+ is_fstree(root->root_key.objectid)) { - set_bit(BTRFS_ROOT_SHAREABLE, &root->state); - btrfs_check_and_init_root_item(&root->root_item); - } -diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c -index 571fcc5ae4dcf..f2ee70c03f0d5 100644 ---- a/fs/btrfs/extent-tree.c -+++ b/fs/btrfs/extent-tree.c -@@ -4411,8 +4411,11 @@ have_block_group: - ret = 0; - } - -- if (unlikely(block_group->cached == BTRFS_CACHE_ERROR)) -+ if (unlikely(block_group->cached == BTRFS_CACHE_ERROR)) { -+ if (!cache_block_group_error) -+ cache_block_group_error = -EIO; - goto loop; -+ } - - bg_ret = NULL; - ret = do_allocation(block_group, ffe_ctl, &bg_ret); -diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c -index 58785dc7080ad..0ad69041954ff 100644 ---- a/fs/btrfs/extent_io.c -+++ b/fs/btrfs/extent_io.c -@@ -3015,11 +3015,12 @@ retry: - } - - /* -- * the filesystem may choose to bump up nr_to_write. -+ * The filesystem may choose to bump up nr_to_write. - * We have to make sure to honor the new nr_to_write -- * at any time -+ * at any time. - */ -- nr_to_write_done = wbc->nr_to_write <= 0; -+ nr_to_write_done = (wbc->sync_mode == WB_SYNC_NONE && -+ wbc->nr_to_write <= 0); - } - pagevec_release(&pvec); - cond_resched(); -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 3c48273cd7a5a..28bcba2e05908 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -1429,8 +1429,6 @@ out_unlock: - clear_bits, - page_ops); - start += cur_alloc_size; -- if (start >= end) -- return ret; - } - - /* -@@ -1439,9 +1437,11 @@ out_unlock: - * space_info's bytes_may_use counter, reserved in - * btrfs_check_data_free_space(). - */ -- extent_clear_unlock_delalloc(inode, start, end, locked_page, -- clear_bits | EXTENT_CLEAR_DATA_RESV, -- page_ops); -+ if (start < end) { -+ clear_bits |= EXTENT_CLEAR_DATA_RESV; -+ extent_clear_unlock_delalloc(inode, start, end, locked_page, -+ clear_bits, page_ops); -+ } - return ret; - } - -diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c -index 666a37a0ee897..d3591c7f166ad 100644 ---- a/fs/btrfs/relocation.c -+++ b/fs/btrfs/relocation.c -@@ -1902,7 +1902,39 @@ again: - err = PTR_ERR(root); - break; - } -- ASSERT(root->reloc_root == reloc_root); -+ -+ if (unlikely(root->reloc_root != reloc_root)) { -+ if (root->reloc_root) { -+ btrfs_err(fs_info, -+"reloc tree mismatch, root %lld has reloc root key (%lld %u %llu) gen %llu, expect reloc root key (%lld %u %llu) gen %llu", -+ root->root_key.objectid, -+ root->reloc_root->root_key.objectid, -+ root->reloc_root->root_key.type, -+ root->reloc_root->root_key.offset, -+ btrfs_root_generation( -+ &root->reloc_root->root_item), -+ reloc_root->root_key.objectid, -+ reloc_root->root_key.type, -+ reloc_root->root_key.offset, -+ btrfs_root_generation( -+ &reloc_root->root_item)); -+ } else { -+ btrfs_err(fs_info, -+"reloc tree mismatch, root %lld has no reloc root, expect reloc root key (%lld %u %llu) gen %llu", -+ root->root_key.objectid, -+ reloc_root->root_key.objectid, -+ reloc_root->root_key.type, -+ reloc_root->root_key.offset, -+ btrfs_root_generation( -+ &reloc_root->root_item)); -+ } -+ list_add(&reloc_root->root_list, &reloc_roots); -+ btrfs_put_root(root); -+ btrfs_abort_transaction(trans, -EUCLEAN); -+ if (!err) -+ err = -EUCLEAN; -+ break; -+ } - - /* - * set reference count to 1, so btrfs_recover_relocation -@@ -1975,7 +2007,7 @@ again: - root = btrfs_get_fs_root(fs_info, reloc_root->root_key.offset, - false); - if (btrfs_root_refs(&reloc_root->root_item) > 0) { -- if (IS_ERR(root)) { -+ if (WARN_ON(IS_ERR(root))) { - /* - * For recovery we read the fs roots on mount, - * and if we didn't find the root then we marked -@@ -1984,17 +2016,14 @@ again: - * memory. However there's no reason we can't - * handle the error properly here just in case. - */ -- ASSERT(0); - ret = PTR_ERR(root); - goto out; - } -- if (root->reloc_root != reloc_root) { -+ if (WARN_ON(root->reloc_root != reloc_root)) { - /* -- * This is actually impossible without something -- * going really wrong (like weird race condition -- * or cosmic rays). -+ * This can happen if on-disk metadata has some -+ * corruption, e.g. bad reloc tree key offset. - */ -- ASSERT(0); - ret = -EINVAL; - goto out; - } -diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c -index 43f905ab0a18d..2b39c7f9226fe 100644 ---- a/fs/btrfs/tree-checker.c -+++ b/fs/btrfs/tree-checker.c -@@ -442,6 +442,20 @@ static int check_root_key(struct extent_buffer *leaf, struct btrfs_key *key, - btrfs_item_key_to_cpu(leaf, &item_key, slot); - is_root_item = (item_key.type == BTRFS_ROOT_ITEM_KEY); - -+ /* -+ * Bad rootid for reloc trees. -+ * -+ * Reloc trees are only for subvolume trees, other trees only need -+ * to be COWed to be relocated. -+ */ -+ if (unlikely(is_root_item && key->objectid == BTRFS_TREE_RELOC_OBJECTID && -+ !is_fstree(key->offset))) { -+ generic_err(leaf, slot, -+ "invalid reloc tree for root %lld, root id is not a subvolume tree", -+ key->offset); -+ return -EUCLEAN; -+ } -+ - /* No such tree id */ - if (unlikely(key->objectid == 0)) { - if (is_root_item) -diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c -index f6e44efb58e15..d4c0895a88116 100644 ---- a/fs/nilfs2/inode.c -+++ b/fs/nilfs2/inode.c -@@ -1101,9 +1101,17 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned int nr_dirty) - - int __nilfs_mark_inode_dirty(struct inode *inode, int flags) - { -+ struct the_nilfs *nilfs = inode->i_sb->s_fs_info; - struct buffer_head *ibh; - int err; - -+ /* -+ * Do not dirty inodes after the log writer has been detached -+ * and its nilfs_root struct has been freed. -+ */ -+ if (unlikely(nilfs_purging(nilfs))) -+ return 0; -+ - err = nilfs_load_inode_block(inode, &ibh); - if (unlikely(err)) { - nilfs_warn(inode->i_sb, -diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c -index 6cf64023be31e..21e8260112c8f 100644 ---- a/fs/nilfs2/segment.c -+++ b/fs/nilfs2/segment.c -@@ -2843,6 +2843,7 @@ void nilfs_detach_log_writer(struct super_block *sb) - nilfs_segctor_destroy(nilfs->ns_writer); - nilfs->ns_writer = NULL; - } -+ set_nilfs_purging(nilfs); - - /* Force to free the list of dirty files */ - spin_lock(&nilfs->ns_inode_lock); -@@ -2855,4 +2856,5 @@ void nilfs_detach_log_writer(struct super_block *sb) - up_write(&nilfs->ns_segctor_sem); - - nilfs_dispose_list(nilfs, &garbage_list, 1); -+ clear_nilfs_purging(nilfs); - } -diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h -index 47c7dfbb7ea58..cd4ae1b8ae165 100644 ---- a/fs/nilfs2/the_nilfs.h -+++ b/fs/nilfs2/the_nilfs.h -@@ -29,6 +29,7 @@ enum { - THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */ - THE_NILFS_GC_RUNNING, /* gc process is running */ - THE_NILFS_SB_DIRTY, /* super block is dirty */ -+ THE_NILFS_PURGING, /* disposing dirty files for cleanup */ - }; - - /** -@@ -208,6 +209,7 @@ THE_NILFS_FNS(INIT, init) - THE_NILFS_FNS(DISCONTINUED, discontinued) - THE_NILFS_FNS(GC_RUNNING, gc_running) - THE_NILFS_FNS(SB_DIRTY, sb_dirty) -+THE_NILFS_FNS(PURGING, purging) - - /* - * Mount option operations -diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c -index 33b7e6c4ceffb..e881df1d10cbd 100644 ---- a/fs/smb/server/smb2misc.c -+++ b/fs/smb/server/smb2misc.c -@@ -380,13 +380,13 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) - } - - if (smb2_req_struct_sizes[command] != pdu->StructureSize2) { -- if (command == SMB2_OPLOCK_BREAK_HE && -- le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 && -- le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) { -+ if (!(command == SMB2_OPLOCK_BREAK_HE && -+ (le16_to_cpu(pdu->StructureSize2) == OP_BREAK_STRUCT_SIZE_20 || -+ le16_to_cpu(pdu->StructureSize2) == OP_BREAK_STRUCT_SIZE_21))) { - /* special case for SMB2.1 lease break message */ - ksmbd_debug(SMB, -- "Illegal request size %d for oplock break\n", -- le16_to_cpu(pdu->StructureSize2)); -+ "Illegal request size %u for command %d\n", -+ le16_to_cpu(pdu->StructureSize2), command); - return 1; - } - } -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index 26cf73d664f94..f8ca44622d909 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -2340,9 +2340,16 @@ next: - break; - buf_len -= next; - eabuf = (struct smb2_ea_info *)((char *)eabuf + next); -- if (next < (u32)eabuf->EaNameLength + le16_to_cpu(eabuf->EaValueLength)) -+ if (buf_len < sizeof(struct smb2_ea_info)) { -+ rc = -EINVAL; - break; -+ } - -+ if (buf_len < sizeof(struct smb2_ea_info) + eabuf->EaNameLength + -+ le16_to_cpu(eabuf->EaValueLength)) { -+ rc = -EINVAL; -+ break; -+ } - } while (next != 0); - - kfree(attr_name); -diff --git a/include/linux/cpu.h b/include/linux/cpu.h -index f98cfe9f188f5..008bfa68cfabc 100644 ---- a/include/linux/cpu.h -+++ b/include/linux/cpu.h -@@ -72,6 +72,8 @@ extern ssize_t cpu_show_retbleed(struct device *dev, - struct device_attribute *attr, char *buf); - extern ssize_t cpu_show_spec_rstack_overflow(struct device *dev, - struct device_attribute *attr, char *buf); -+extern ssize_t cpu_show_gds(struct device *dev, -+ struct device_attribute *attr, char *buf); - - extern __printf(4, 5) - struct device *cpu_device_create(struct device *parent, void *drvdata, -diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h -index 054d7911bfc9f..c1637515a8a41 100644 ---- a/include/linux/skmsg.h -+++ b/include/linux/skmsg.h -@@ -62,6 +62,7 @@ struct sk_psock_progs { - - enum sk_psock_state_bits { - SK_PSOCK_TX_ENABLED, -+ SK_PSOCK_RX_STRP_ENABLED, - }; - - struct sk_psock_link { -diff --git a/include/linux/tpm.h b/include/linux/tpm.h -index 4e22e4f4cec85..df5cd4245f299 100644 ---- a/include/linux/tpm.h -+++ b/include/linux/tpm.h -@@ -282,6 +282,7 @@ enum tpm_chip_flags { - TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6), - TPM_CHIP_FLAG_FIRMWARE_UPGRADE = BIT(7), - TPM_CHIP_FLAG_SUSPENDED = BIT(8), -+ TPM_CHIP_FLAG_HWRNG_DISABLED = BIT(9), - }; - - #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) -diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h -index e09ff87146c1c..5976545aa26b9 100644 ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -562,6 +562,9 @@ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband, - if (WARN_ON(iftype >= NL80211_IFTYPE_MAX)) - return NULL; - -+ if (iftype == NL80211_IFTYPE_AP_VLAN) -+ iftype = NL80211_IFTYPE_AP; -+ - for (i = 0; i < sband->n_iftype_data; i++) { - const struct ieee80211_sband_iftype_data *data = - &sband->iftype_data[i]; -diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h -index f3a37cacb32c3..c752b6f509791 100644 ---- a/include/net/netfilter/nf_tables.h -+++ b/include/net/netfilter/nf_tables.h -@@ -1192,6 +1192,29 @@ int __nft_release_basechain(struct nft_ctx *ctx); - - unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv); - -+static inline bool nft_use_inc(u32 *use) -+{ -+ if (*use == UINT_MAX) -+ return false; -+ -+ (*use)++; -+ -+ return true; -+} -+ -+static inline void nft_use_dec(u32 *use) -+{ -+ WARN_ON_ONCE((*use)-- == 0); -+} -+ -+/* For error and abort path: restore use counter to previous state. */ -+static inline void nft_use_inc_restore(u32 *use) -+{ -+ WARN_ON_ONCE(!nft_use_inc(use)); -+} -+ -+#define nft_use_dec_restore nft_use_dec -+ - /** - * struct nft_table - nf_tables table - * -@@ -1275,8 +1298,8 @@ struct nft_object { - struct list_head list; - struct rhlist_head rhlhead; - struct nft_object_hash_key key; -- u32 genmask:2, -- use:30; -+ u32 genmask:2; -+ u32 use; - u64 handle; - u16 udlen; - u8 *udata; -@@ -1378,8 +1401,8 @@ struct nft_flowtable { - char *name; - int hooknum; - int ops_len; -- u32 genmask:2, -- use:30; -+ u32 genmask:2; -+ u32 use; - u64 handle; - /* runtime data below here */ - struct list_head hook_list ____cacheline_aligned; -diff --git a/include/trace/events/tcp.h b/include/trace/events/tcp.h -index 901b440238d5f..0a14c474c6f95 100644 ---- a/include/trace/events/tcp.h -+++ b/include/trace/events/tcp.h -@@ -381,6 +381,7 @@ TRACE_EVENT(tcp_cong_state_set, - __field(const void *, skaddr) - __field(__u16, sport) - __field(__u16, dport) -+ __field(__u16, family) - __array(__u8, saddr, 4) - __array(__u8, daddr, 4) - __array(__u8, saddr_v6, 16) -@@ -396,6 +397,7 @@ TRACE_EVENT(tcp_cong_state_set, - - __entry->sport = ntohs(inet->inet_sport); - __entry->dport = ntohs(inet->inet_dport); -+ __entry->family = sk->sk_family; - - p32 = (__be32 *) __entry->saddr; - *p32 = inet->inet_saddr; -@@ -409,7 +411,8 @@ TRACE_EVENT(tcp_cong_state_set, - __entry->cong_state = ca_state; - ), - -- TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c cong_state=%u", -+ TP_printk("family=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c cong_state=%u", -+ show_family_name(__entry->family), - __entry->sport, __entry->dport, - __entry->saddr, __entry->daddr, - __entry->saddr_v6, __entry->daddr_v6, -diff --git a/io_uring/openclose.c b/io_uring/openclose.c -index 67178e4bb282d..008990e581806 100644 ---- a/io_uring/openclose.c -+++ b/io_uring/openclose.c -@@ -110,9 +110,11 @@ int io_openat2(struct io_kiocb *req, unsigned int issue_flags) - if (issue_flags & IO_URING_F_NONBLOCK) { - /* - * Don't bother trying for O_TRUNC, O_CREAT, or O_TMPFILE open, -- * it'll always -EAGAIN -+ * it'll always -EAGAIN. Note that we test for __O_TMPFILE -+ * because O_TMPFILE includes O_DIRECTORY, which isn't a flag -+ * we need to force async for. - */ -- if (open->how.flags & (O_TRUNC | O_CREAT | O_TMPFILE)) -+ if (open->how.flags & (O_TRUNC | O_CREAT | __O_TMPFILE)) - return -EAGAIN; - op.lookup_flags |= LOOKUP_CACHED; - op.open_flag |= O_NONBLOCK; -diff --git a/net/core/filter.c b/net/core/filter.c -index da71e6812ab51..419ce7c61bd6b 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -4064,12 +4064,6 @@ BPF_CALL_2(bpf_xdp_adjust_tail, struct xdp_buff *, xdp, int, offset) - if (unlikely(data_end > data_hard_end)) - return -EINVAL; - -- /* ALL drivers MUST init xdp->frame_sz, chicken check below */ -- if (unlikely(xdp->frame_sz > PAGE_SIZE)) { -- WARN_ONCE(1, "Too BIG xdp->frame_sz = %d\n", xdp->frame_sz); -- return -EINVAL; -- } -- - if (unlikely(data_end < xdp->data + ETH_HLEN)) - return -EINVAL; - -diff --git a/net/core/skmsg.c b/net/core/skmsg.c -index 65fb6f5b21b28..296e45b6c3c0d 100644 ---- a/net/core/skmsg.c -+++ b/net/core/skmsg.c -@@ -1117,13 +1117,19 @@ static void sk_psock_strp_data_ready(struct sock *sk) - - int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock) - { -+ int ret; -+ - static const struct strp_callbacks cb = { - .rcv_msg = sk_psock_strp_read, - .read_sock_done = sk_psock_strp_read_done, - .parse_msg = sk_psock_strp_parse, - }; - -- return strp_init(&psock->strp, sk, &cb); -+ ret = strp_init(&psock->strp, sk, &cb); -+ if (!ret) -+ sk_psock_set_state(psock, SK_PSOCK_RX_STRP_ENABLED); -+ -+ return ret; - } - - void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock) -@@ -1151,7 +1157,7 @@ void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock) - static void sk_psock_done_strp(struct sk_psock *psock) - { - /* Parser has been stopped */ -- if (psock->progs.stream_parser) -+ if (sk_psock_test_state(psock, SK_PSOCK_RX_STRP_ENABLED)) - strp_done(&psock->strp); - } - #else -diff --git a/net/core/sock_map.c b/net/core/sock_map.c -index c84e5073c0b66..96db7409baa12 100644 ---- a/net/core/sock_map.c -+++ b/net/core/sock_map.c -@@ -148,13 +148,13 @@ static void sock_map_del_link(struct sock *sk, - list_for_each_entry_safe(link, tmp, &psock->link, list) { - if (link->link_raw == link_raw) { - struct bpf_map *map = link->map; -- struct bpf_stab *stab = container_of(map, struct bpf_stab, -- map); -- if (psock->saved_data_ready && stab->progs.stream_parser) -+ struct sk_psock_progs *progs = sock_map_progs(map); -+ -+ if (psock->saved_data_ready && progs->stream_parser) - strp_stop = true; -- if (psock->saved_data_ready && stab->progs.stream_verdict) -+ if (psock->saved_data_ready && progs->stream_verdict) - verdict_stop = true; -- if (psock->saved_data_ready && stab->progs.skb_verdict) -+ if (psock->saved_data_ready && progs->skb_verdict) - verdict_stop = true; - list_del(&link->list); - sk_psock_free_link(link); -diff --git a/net/dccp/output.c b/net/dccp/output.c -index b8a24734385ef..fd2eb148d24de 100644 ---- a/net/dccp/output.c -+++ b/net/dccp/output.c -@@ -187,7 +187,7 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) - - /* And store cached results */ - icsk->icsk_pmtu_cookie = pmtu; -- dp->dccps_mss_cache = cur_mps; -+ WRITE_ONCE(dp->dccps_mss_cache, cur_mps); - - return cur_mps; - } -diff --git a/net/dccp/proto.c b/net/dccp/proto.c -index a06b5641287a2..abc02d25edc14 100644 ---- a/net/dccp/proto.c -+++ b/net/dccp/proto.c -@@ -627,7 +627,7 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname, - return dccp_getsockopt_service(sk, len, - (__be32 __user *)optval, optlen); - case DCCP_SOCKOPT_GET_CUR_MPS: -- val = dp->dccps_mss_cache; -+ val = READ_ONCE(dp->dccps_mss_cache); - break; - case DCCP_SOCKOPT_AVAILABLE_CCIDS: - return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen); -@@ -736,7 +736,7 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - - trace_dccp_probe(sk, len); - -- if (len > dp->dccps_mss_cache) -+ if (len > READ_ONCE(dp->dccps_mss_cache)) - return -EMSGSIZE; - - lock_sock(sk); -@@ -769,6 +769,12 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - goto out_discard; - } - -+ /* We need to check dccps_mss_cache after socket is locked. */ -+ if (len > dp->dccps_mss_cache) { -+ rc = -EMSGSIZE; -+ goto out_discard; -+ } -+ - skb_reserve(skb, sk->sk_prot->max_header); - rc = memcpy_from_msg(skb_put(skb, len), msg, len); - if (rc != 0) -diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c -index 92c02c886fe73..586b1b3e35b80 100644 ---- a/net/ipv4/ip_tunnel_core.c -+++ b/net/ipv4/ip_tunnel_core.c -@@ -224,7 +224,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu) - .un.frag.__unused = 0, - .un.frag.mtu = htons(mtu), - }; -- icmph->checksum = ip_compute_csum(icmph, len); -+ icmph->checksum = csum_fold(skb_checksum(skb, 0, len, 0)); - skb_reset_transport_header(skb); - - niph = skb_push(skb, sizeof(*niph)); -diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c -index d8ef05347fd98..9cc2879024541 100644 ---- a/net/ipv4/nexthop.c -+++ b/net/ipv4/nexthop.c -@@ -3221,13 +3221,9 @@ static int rtm_dump_nexthop(struct sk_buff *skb, struct netlink_callback *cb) - &rtm_dump_nexthop_cb, &filter); - if (err < 0) { - if (likely(skb->len)) -- goto out; -- goto out_err; -+ err = skb->len; - } - --out: -- err = skb->len; --out_err: - cb->seq = net->nexthop.seq; - nl_dump_check_consistent(cb, nlmsg_hdr(skb)); - return err; -@@ -3367,25 +3363,19 @@ static int rtm_dump_nexthop_bucket_nh(struct sk_buff *skb, - dd->filter.res_bucket_nh_id != nhge->nh->id) - continue; - -+ dd->ctx->bucket_index = bucket_index; - err = nh_fill_res_bucket(skb, nh, bucket, bucket_index, - RTM_NEWNEXTHOPBUCKET, portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI, - cb->extack); -- if (err < 0) { -- if (likely(skb->len)) -- goto out; -- goto out_err; -- } -+ if (err) -+ return err; - } - - dd->ctx->done_nh_idx = dd->ctx->nh.idx + 1; -- bucket_index = 0; -+ dd->ctx->bucket_index = 0; - --out: -- err = skb->len; --out_err: -- dd->ctx->bucket_index = bucket_index; -- return err; -+ return 0; - } - - static int rtm_dump_nexthop_bucket_cb(struct sk_buff *skb, -@@ -3434,13 +3424,9 @@ static int rtm_dump_nexthop_bucket(struct sk_buff *skb, - - if (err < 0) { - if (likely(skb->len)) -- goto out; -- goto out_err; -+ err = skb->len; - } - --out: -- err = skb->len; --out_err: - cb->seq = net->nexthop.seq; - nl_dump_check_consistent(cb, nlmsg_hdr(skb)); - return err; -diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c -index 3a553494ff164..a4d43eb45a9de 100644 ---- a/net/ipv6/ndisc.c -+++ b/net/ipv6/ndisc.c -@@ -197,7 +197,8 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, - static inline int ndisc_is_useropt(const struct net_device *dev, - struct nd_opt_hdr *opt) - { -- return opt->nd_opt_type == ND_OPT_RDNSS || -+ return opt->nd_opt_type == ND_OPT_PREFIX_INFO || -+ opt->nd_opt_type == ND_OPT_RDNSS || - opt->nd_opt_type == ND_OPT_DNSSL || - opt->nd_opt_type == ND_OPT_CAPTIVE_PORTAL || - opt->nd_opt_type == ND_OPT_PREF64 || -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index f6f2e6417dcbe..61fefa1a82db2 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -2367,7 +2367,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - - lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); - -- if (flags & MPTCP_CF_FASTCLOSE) { -+ if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) { - /* be sure to force the tcp_disconnect() path, - * to generate the egress reset - */ -@@ -3370,7 +3370,7 @@ static void mptcp_release_cb(struct sock *sk) - - if (__test_and_clear_bit(MPTCP_CLEAN_UNA, &msk->cb_flags)) - __mptcp_clean_una_wakeup(sk); -- if (unlikely(&msk->cb_flags)) { -+ if (unlikely(msk->cb_flags)) { - /* be sure to set the current sk state before tacking actions - * depending on sk_state, that is processing MPTCP_ERROR_REPORT - */ -diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h -index fc00dd587a297..d77b25636125b 100644 ---- a/net/mptcp/protocol.h -+++ b/net/mptcp/protocol.h -@@ -312,7 +312,6 @@ struct mptcp_sock { - - u32 setsockopt_seq; - char ca_name[TCP_CA_NAME_MAX]; -- struct mptcp_sock *dl_next; - }; - - #define mptcp_data_lock(sk) spin_lock_bh(&(sk)->sk_lock.slock) -diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c -index 047e46dd028dd..52a747a80e88e 100644 ---- a/net/mptcp/subflow.c -+++ b/net/mptcp/subflow.c -@@ -1724,16 +1724,31 @@ static void subflow_state_change(struct sock *sk) - void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_ssk) - { - struct request_sock_queue *queue = &inet_csk(listener_ssk)->icsk_accept_queue; -- struct mptcp_sock *msk, *next, *head = NULL; -- struct request_sock *req; -- struct sock *sk; -+ struct request_sock *req, *head, *tail; -+ struct mptcp_subflow_context *subflow; -+ struct sock *sk, *ssk; - -- /* build a list of all unaccepted mptcp sockets */ -+ /* Due to lock dependencies no relevant lock can be acquired under rskq_lock. -+ * Splice the req list, so that accept() can not reach the pending ssk after -+ * the listener socket is released below. -+ */ - spin_lock_bh(&queue->rskq_lock); -- for (req = queue->rskq_accept_head; req; req = req->dl_next) { -- struct mptcp_subflow_context *subflow; -- struct sock *ssk = req->sk; -+ head = queue->rskq_accept_head; -+ tail = queue->rskq_accept_tail; -+ queue->rskq_accept_head = NULL; -+ queue->rskq_accept_tail = NULL; -+ spin_unlock_bh(&queue->rskq_lock); -+ -+ if (!head) -+ return; - -+ /* can't acquire the msk socket lock under the subflow one, -+ * or will cause ABBA deadlock -+ */ -+ release_sock(listener_ssk); -+ -+ for (req = head; req; req = req->dl_next) { -+ ssk = req->sk; - if (!sk_is_mptcp(ssk)) - continue; - -@@ -1741,32 +1756,10 @@ void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_s - if (!subflow || !subflow->conn) - continue; - -- /* skip if already in list */ - sk = subflow->conn; -- msk = mptcp_sk(sk); -- if (msk->dl_next || msk == head) -- continue; -- - sock_hold(sk); -- msk->dl_next = head; -- head = msk; -- } -- spin_unlock_bh(&queue->rskq_lock); -- if (!head) -- return; -- -- /* can't acquire the msk socket lock under the subflow one, -- * or will cause ABBA deadlock -- */ -- release_sock(listener_ssk); -- -- for (msk = head; msk; msk = next) { -- sk = (struct sock *)msk; - - lock_sock_nested(sk, SINGLE_DEPTH_NESTING); -- next = msk->dl_next; -- msk->dl_next = NULL; -- - __mptcp_unaccepted_force_close(sk); - release_sock(sk); - -@@ -1790,6 +1783,13 @@ void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_s - - /* we are still under the listener msk socket lock */ - lock_sock_nested(listener_ssk, SINGLE_DEPTH_NESTING); -+ -+ /* restore the listener queue, to let the TCP code clean it up */ -+ spin_lock_bh(&queue->rskq_lock); -+ WARN_ON_ONCE(queue->rskq_accept_head); -+ queue->rskq_accept_head = head; -+ queue->rskq_accept_tail = tail; -+ spin_unlock_bh(&queue->rskq_lock); - } - - static int subflow_ulp_init(struct sock *sk) -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index dd57a9ebe113d..f6e6273838859 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -255,8 +255,10 @@ int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain) - if (chain->bound) - return -EBUSY; - -+ if (!nft_use_inc(&chain->use)) -+ return -EMFILE; -+ - chain->bound = true; -- chain->use++; - nft_chain_trans_bind(ctx, chain); - - return 0; -@@ -439,7 +441,7 @@ static int nft_delchain(struct nft_ctx *ctx) - if (IS_ERR(trans)) - return PTR_ERR(trans); - -- ctx->table->use--; -+ nft_use_dec(&ctx->table->use); - nft_deactivate_next(ctx->net, ctx->chain); - - return 0; -@@ -478,7 +480,7 @@ nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule) - /* You cannot delete the same rule twice */ - if (nft_is_active_next(ctx->net, rule)) { - nft_deactivate_next(ctx->net, rule); -- ctx->chain->use--; -+ nft_use_dec(&ctx->chain->use); - return 0; - } - return -ENOENT; -@@ -645,7 +647,7 @@ static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set) - nft_map_deactivate(ctx, set); - - nft_deactivate_next(ctx->net, set); -- ctx->table->use--; -+ nft_use_dec(&ctx->table->use); - - return err; - } -@@ -677,7 +679,7 @@ static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj) - return err; - - nft_deactivate_next(ctx->net, obj); -- ctx->table->use--; -+ nft_use_dec(&ctx->table->use); - - return err; - } -@@ -712,7 +714,7 @@ static int nft_delflowtable(struct nft_ctx *ctx, - return err; - - nft_deactivate_next(ctx->net, flowtable); -- ctx->table->use--; -+ nft_use_dec(&ctx->table->use); - - return err; - } -@@ -2358,9 +2360,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, - unsigned int data_size; - int err; - -- if (table->use == UINT_MAX) -- return -EOVERFLOW; -- - if (nla[NFTA_CHAIN_HOOK]) { - struct nft_stats __percpu *stats = NULL; - struct nft_chain_hook hook; -@@ -2457,6 +2456,11 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, - if (err < 0) - goto err_destroy_chain; - -+ if (!nft_use_inc(&table->use)) { -+ err = -EMFILE; -+ goto err_use; -+ } -+ - trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN); - if (IS_ERR(trans)) { - err = PTR_ERR(trans); -@@ -2473,10 +2477,11 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, - goto err_unregister_hook; - } - -- table->use++; -- - return 0; -+ - err_unregister_hook: -+ nft_use_dec_restore(&table->use); -+err_use: - nf_tables_unregister_hook(net, table, chain); - err_destroy_chain: - nf_tables_chain_destroy(ctx); -@@ -3663,9 +3668,6 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, - return -EINVAL; - handle = nf_tables_alloc_handle(table); - -- if (chain->use == UINT_MAX) -- return -EOVERFLOW; -- - if (nla[NFTA_RULE_POSITION]) { - pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION])); - old_rule = __nft_rule_lookup(chain, pos_handle); -@@ -3759,6 +3761,11 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, - } - } - -+ if (!nft_use_inc(&chain->use)) { -+ err = -EMFILE; -+ goto err_release_rule; -+ } -+ - if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { - err = nft_delrule(&ctx, old_rule); - if (err < 0) -@@ -3790,7 +3797,6 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, - } - } - kvfree(expr_info); -- chain->use++; - - if (flow) - nft_trans_flow_rule(trans) = flow; -@@ -3801,6 +3807,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, - return 0; - - err_destroy_flow_rule: -+ nft_use_dec_restore(&chain->use); - if (flow) - nft_flow_rule_destroy(flow); - err_release_rule: -@@ -4818,9 +4825,15 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, - alloc_size = sizeof(*set) + size + udlen; - if (alloc_size < size || alloc_size > INT_MAX) - return -ENOMEM; -+ -+ if (!nft_use_inc(&table->use)) -+ return -EMFILE; -+ - set = kvzalloc(alloc_size, GFP_KERNEL_ACCOUNT); -- if (!set) -- return -ENOMEM; -+ if (!set) { -+ err = -ENOMEM; -+ goto err_alloc; -+ } - - name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL_ACCOUNT); - if (!name) { -@@ -4878,7 +4891,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, - goto err_set_expr_alloc; - - list_add_tail_rcu(&set->list, &table->sets); -- table->use++; -+ - return 0; - - err_set_expr_alloc: -@@ -4890,6 +4903,9 @@ err_set_init: - kfree(set->name); - err_set_name: - kvfree(set); -+err_alloc: -+ nft_use_dec_restore(&table->use); -+ - return err; - } - -@@ -5024,9 +5040,6 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, - struct nft_set_binding *i; - struct nft_set_iter iter; - -- if (set->use == UINT_MAX) -- return -EOVERFLOW; -- - if (!list_empty(&set->bindings) && nft_set_is_anonymous(set)) - return -EBUSY; - -@@ -5054,10 +5067,12 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, - return iter.err; - } - bind: -+ if (!nft_use_inc(&set->use)) -+ return -EMFILE; -+ - binding->chain = ctx->chain; - list_add_tail_rcu(&binding->list, &set->bindings); - nft_set_trans_bind(ctx, set); -- set->use++; - - return 0; - } -@@ -5131,7 +5146,7 @@ void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set) - nft_clear(ctx->net, set); - } - -- set->use++; -+ nft_use_inc_restore(&set->use); - } - EXPORT_SYMBOL_GPL(nf_tables_activate_set); - -@@ -5147,7 +5162,7 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, - else - list_del_rcu(&binding->list); - -- set->use--; -+ nft_use_dec(&set->use); - break; - case NFT_TRANS_PREPARE: - if (nft_set_is_anonymous(set)) { -@@ -5156,7 +5171,7 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, - - nft_deactivate_next(ctx->net, set); - } -- set->use--; -+ nft_use_dec(&set->use); - return; - case NFT_TRANS_ABORT: - case NFT_TRANS_RELEASE: -@@ -5164,7 +5179,7 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, - set->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) - nft_map_deactivate(ctx, set); - -- set->use--; -+ nft_use_dec(&set->use); - fallthrough; - default: - nf_tables_unbind_set(ctx, set, binding, -@@ -5933,7 +5948,7 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem, - nft_set_elem_expr_destroy(&ctx, nft_set_ext_expr(ext)); - - if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF)) -- (*nft_set_ext_obj(ext))->use--; -+ nft_use_dec(&(*nft_set_ext_obj(ext))->use); - kfree(elem); - } - EXPORT_SYMBOL_GPL(nft_set_elem_destroy); -@@ -6435,8 +6450,16 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, - set->objtype, genmask); - if (IS_ERR(obj)) { - err = PTR_ERR(obj); -+ obj = NULL; - goto err_parse_key_end; - } -+ -+ if (!nft_use_inc(&obj->use)) { -+ err = -EMFILE; -+ obj = NULL; -+ goto err_parse_key_end; -+ } -+ - err = nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF); - if (err < 0) - goto err_parse_key_end; -@@ -6505,10 +6528,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, - if (flags) - *nft_set_ext_flags(ext) = flags; - -- if (obj) { -+ if (obj) - *nft_set_ext_obj(ext) = obj; -- obj->use++; -- } -+ - if (ulen > 0) { - if (nft_set_ext_check(&tmpl, NFT_SET_EXT_USERDATA, ulen) < 0) { - err = -EINVAL; -@@ -6573,12 +6595,13 @@ err_element_clash: - kfree(trans); - err_elem_free: - nf_tables_set_elem_destroy(ctx, set, elem.priv); -- if (obj) -- obj->use--; - err_parse_data: - if (nla[NFTA_SET_ELEM_DATA] != NULL) - nft_data_release(&elem.data.val, desc.type); - err_parse_key_end: -+ if (obj) -+ nft_use_dec_restore(&obj->use); -+ - nft_data_release(&elem.key_end.val, NFT_DATA_VALUE); - err_parse_key: - nft_data_release(&elem.key.val, NFT_DATA_VALUE); -@@ -6659,7 +6682,7 @@ void nft_data_hold(const struct nft_data *data, enum nft_data_types type) - case NFT_JUMP: - case NFT_GOTO: - chain = data->verdict.chain; -- chain->use++; -+ nft_use_inc_restore(&chain->use); - break; - } - } -@@ -6674,7 +6697,7 @@ static void nft_setelem_data_activate(const struct net *net, - if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) - nft_data_hold(nft_set_ext_data(ext), set->dtype); - if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF)) -- (*nft_set_ext_obj(ext))->use++; -+ nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use); - } - - static void nft_setelem_data_deactivate(const struct net *net, -@@ -6686,7 +6709,7 @@ static void nft_setelem_data_deactivate(const struct net *net, - if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) - nft_data_release(nft_set_ext_data(ext), set->dtype); - if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF)) -- (*nft_set_ext_obj(ext))->use--; -+ nft_use_dec(&(*nft_set_ext_obj(ext))->use); - } - - static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, -@@ -7225,9 +7248,14 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info, - - nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); - -+ if (!nft_use_inc(&table->use)) -+ return -EMFILE; -+ - type = nft_obj_type_get(net, objtype); -- if (IS_ERR(type)) -- return PTR_ERR(type); -+ if (IS_ERR(type)) { -+ err = PTR_ERR(type); -+ goto err_type; -+ } - - obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]); - if (IS_ERR(obj)) { -@@ -7261,7 +7289,7 @@ static int nf_tables_newobj(struct sk_buff *skb, const struct nfnl_info *info, - goto err_obj_ht; - - list_add_tail_rcu(&obj->list, &table->objects); -- table->use++; -+ - return 0; - err_obj_ht: - /* queued in transaction log */ -@@ -7277,6 +7305,9 @@ err_strdup: - kfree(obj); - err_init: - module_put(type->owner); -+err_type: -+ nft_use_dec_restore(&table->use); -+ - return err; - } - -@@ -7667,7 +7698,7 @@ void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx, - case NFT_TRANS_PREPARE: - case NFT_TRANS_ABORT: - case NFT_TRANS_RELEASE: -- flowtable->use--; -+ nft_use_dec(&flowtable->use); - fallthrough; - default: - return; -@@ -8015,9 +8046,14 @@ static int nf_tables_newflowtable(struct sk_buff *skb, - - nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); - -+ if (!nft_use_inc(&table->use)) -+ return -EMFILE; -+ - flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL_ACCOUNT); -- if (!flowtable) -- return -ENOMEM; -+ if (!flowtable) { -+ err = -ENOMEM; -+ goto flowtable_alloc; -+ } - - flowtable->table = table; - flowtable->handle = nf_tables_alloc_handle(table); -@@ -8072,7 +8108,6 @@ static int nf_tables_newflowtable(struct sk_buff *skb, - goto err5; - - list_add_tail_rcu(&flowtable->list, &table->flowtables); -- table->use++; - - return 0; - err5: -@@ -8089,6 +8124,9 @@ err2: - kfree(flowtable->name); - err1: - kfree(flowtable); -+flowtable_alloc: -+ nft_use_dec_restore(&table->use); -+ - return err; - } - -@@ -9374,7 +9412,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - */ - if (nft_set_is_anonymous(nft_trans_set(trans)) && - !list_empty(&nft_trans_set(trans)->bindings)) -- trans->ctx.table->use--; -+ nft_use_dec(&trans->ctx.table->use); - } - nf_tables_set_notify(&trans->ctx, nft_trans_set(trans), - NFT_MSG_NEWSET, GFP_KERNEL); -@@ -9593,7 +9631,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - nft_trans_destroy(trans); - break; - } -- trans->ctx.table->use--; -+ nft_use_dec_restore(&trans->ctx.table->use); - nft_chain_del(trans->ctx.chain); - nf_tables_unregister_hook(trans->ctx.net, - trans->ctx.table, -@@ -9601,7 +9639,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - } - break; - case NFT_MSG_DELCHAIN: -- trans->ctx.table->use++; -+ nft_use_inc_restore(&trans->ctx.table->use); - nft_clear(trans->ctx.net, trans->ctx.chain); - nft_trans_destroy(trans); - break; -@@ -9610,7 +9648,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - nft_trans_destroy(trans); - break; - } -- trans->ctx.chain->use--; -+ nft_use_dec_restore(&trans->ctx.chain->use); - list_del_rcu(&nft_trans_rule(trans)->list); - nft_rule_expr_deactivate(&trans->ctx, - nft_trans_rule(trans), -@@ -9619,7 +9657,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - nft_flow_rule_destroy(nft_trans_flow_rule(trans)); - break; - case NFT_MSG_DELRULE: -- trans->ctx.chain->use++; -+ nft_use_inc_restore(&trans->ctx.chain->use); - nft_clear(trans->ctx.net, nft_trans_rule(trans)); - nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans)); - if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD) -@@ -9632,7 +9670,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - nft_trans_destroy(trans); - break; - } -- trans->ctx.table->use--; -+ nft_use_dec_restore(&trans->ctx.table->use); - if (nft_trans_set_bound(trans)) { - nft_trans_destroy(trans); - break; -@@ -9640,7 +9678,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - list_del_rcu(&nft_trans_set(trans)->list); - break; - case NFT_MSG_DELSET: -- trans->ctx.table->use++; -+ nft_use_inc_restore(&trans->ctx.table->use); - nft_clear(trans->ctx.net, nft_trans_set(trans)); - if (nft_trans_set(trans)->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) - nft_map_activate(&trans->ctx, nft_trans_set(trans)); -@@ -9683,12 +9721,12 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - nft_obj_destroy(&trans->ctx, nft_trans_obj_newobj(trans)); - nft_trans_destroy(trans); - } else { -- trans->ctx.table->use--; -+ nft_use_dec_restore(&trans->ctx.table->use); - nft_obj_del(nft_trans_obj(trans)); - } - break; - case NFT_MSG_DELOBJ: -- trans->ctx.table->use++; -+ nft_use_inc_restore(&trans->ctx.table->use); - nft_clear(trans->ctx.net, nft_trans_obj(trans)); - nft_trans_destroy(trans); - break; -@@ -9697,7 +9735,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - nft_unregister_flowtable_net_hooks(net, - &nft_trans_flowtable_hooks(trans)); - } else { -- trans->ctx.table->use--; -+ nft_use_dec_restore(&trans->ctx.table->use); - list_del_rcu(&nft_trans_flowtable(trans)->list); - nft_unregister_flowtable_net_hooks(net, - &nft_trans_flowtable(trans)->hook_list); -@@ -9708,7 +9746,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - list_splice(&nft_trans_flowtable_hooks(trans), - &nft_trans_flowtable(trans)->hook_list); - } else { -- trans->ctx.table->use++; -+ nft_use_inc_restore(&trans->ctx.table->use); - nft_clear(trans->ctx.net, nft_trans_flowtable(trans)); - } - nft_trans_destroy(trans); -@@ -10161,8 +10199,9 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, - if (desc->flags & NFT_DATA_DESC_SETELEM && - chain->flags & NFT_CHAIN_BINDING) - return -EINVAL; -+ if (!nft_use_inc(&chain->use)) -+ return -EMFILE; - -- chain->use++; - data->verdict.chain = chain; - break; - } -@@ -10180,7 +10219,7 @@ static void nft_verdict_uninit(const struct nft_data *data) - case NFT_JUMP: - case NFT_GOTO: - chain = data->verdict.chain; -- chain->use--; -+ nft_use_dec(&chain->use); - break; - } - } -@@ -10349,11 +10388,11 @@ int __nft_release_basechain(struct nft_ctx *ctx) - nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain); - list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) { - list_del(&rule->list); -- ctx->chain->use--; -+ nft_use_dec(&ctx->chain->use); - nf_tables_rule_release(ctx, rule); - } - nft_chain_del(ctx->chain); -- ctx->table->use--; -+ nft_use_dec(&ctx->table->use); - nf_tables_chain_destroy(ctx); - - return 0; -@@ -10406,18 +10445,18 @@ static void __nft_release_table(struct net *net, struct nft_table *table) - ctx.chain = chain; - list_for_each_entry_safe(rule, nr, &chain->rules, list) { - list_del(&rule->list); -- chain->use--; -+ nft_use_dec(&chain->use); - nf_tables_rule_release(&ctx, rule); - } - } - list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) { - list_del(&flowtable->list); -- table->use--; -+ nft_use_dec(&table->use); - nf_tables_flowtable_destroy(flowtable); - } - list_for_each_entry_safe(set, ns, &table->sets, list) { - list_del(&set->list); -- table->use--; -+ nft_use_dec(&table->use); - if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT)) - nft_map_deactivate(&ctx, set); - -@@ -10425,13 +10464,13 @@ static void __nft_release_table(struct net *net, struct nft_table *table) - } - list_for_each_entry_safe(obj, ne, &table->objects, list) { - nft_obj_del(obj); -- table->use--; -+ nft_use_dec(&table->use); - nft_obj_destroy(&ctx, obj); - } - list_for_each_entry_safe(chain, nc, &table->chains, list) { - ctx.chain = chain; - nft_chain_del(chain); -- table->use--; -+ nft_use_dec(&table->use); - nf_tables_chain_destroy(&ctx); - } - nf_tables_table_destroy(&ctx); -diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c -index a25c88bc8b750..8a43f6f9c90b6 100644 ---- a/net/netfilter/nft_flow_offload.c -+++ b/net/netfilter/nft_flow_offload.c -@@ -404,8 +404,10 @@ static int nft_flow_offload_init(const struct nft_ctx *ctx, - if (IS_ERR(flowtable)) - return PTR_ERR(flowtable); - -+ if (!nft_use_inc(&flowtable->use)) -+ return -EMFILE; -+ - priv->flowtable = flowtable; -- flowtable->use++; - - return nf_ct_netns_get(ctx->net, ctx->family); - } -@@ -424,7 +426,7 @@ static void nft_flow_offload_activate(const struct nft_ctx *ctx, - { - struct nft_flow_offload *priv = nft_expr_priv(expr); - -- priv->flowtable->use++; -+ nft_use_inc_restore(&priv->flowtable->use); - } - - static void nft_flow_offload_destroy(const struct nft_ctx *ctx, -diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c -index 391c18e4b3ebd..5f59dbab3e933 100644 ---- a/net/netfilter/nft_immediate.c -+++ b/net/netfilter/nft_immediate.c -@@ -168,7 +168,7 @@ static void nft_immediate_deactivate(const struct nft_ctx *ctx, - nft_immediate_chain_deactivate(ctx, chain, phase); - nft_chain_del(chain); - chain->bound = false; -- chain->table->use--; -+ nft_use_dec(&chain->table->use); - break; - } - break; -@@ -207,7 +207,7 @@ static void nft_immediate_destroy(const struct nft_ctx *ctx, - * let the transaction records release this chain and its rules. - */ - if (chain->bound) { -- chain->use--; -+ nft_use_dec(&chain->use); - break; - } - -@@ -215,9 +215,9 @@ static void nft_immediate_destroy(const struct nft_ctx *ctx, - chain_ctx = *ctx; - chain_ctx.chain = chain; - -- chain->use--; -+ nft_use_dec(&chain->use); - list_for_each_entry_safe(rule, n, &chain->rules, list) { -- chain->use--; -+ nft_use_dec(&chain->use); - list_del(&rule->list); - nf_tables_rule_destroy(&chain_ctx, rule); - } -diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c -index 7f8e480b6be5b..0017bd3418722 100644 ---- a/net/netfilter/nft_objref.c -+++ b/net/netfilter/nft_objref.c -@@ -41,8 +41,10 @@ static int nft_objref_init(const struct nft_ctx *ctx, - if (IS_ERR(obj)) - return -ENOENT; - -+ if (!nft_use_inc(&obj->use)) -+ return -EMFILE; -+ - nft_objref_priv(expr) = obj; -- obj->use++; - - return 0; - } -@@ -71,7 +73,7 @@ static void nft_objref_deactivate(const struct nft_ctx *ctx, - if (phase == NFT_TRANS_COMMIT) - return; - -- obj->use--; -+ nft_use_dec(&obj->use); - } - - static void nft_objref_activate(const struct nft_ctx *ctx, -@@ -79,7 +81,7 @@ static void nft_objref_activate(const struct nft_ctx *ctx, - { - struct nft_object *obj = nft_objref_priv(expr); - -- obj->use++; -+ nft_use_inc_restore(&obj->use); - } - - static struct nft_expr_type nft_objref_type; -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 1681068400733..451bd8bfafd23 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -404,18 +404,20 @@ static void __packet_set_status(struct packet_sock *po, void *frame, int status) - { - union tpacket_uhdr h; - -+ /* WRITE_ONCE() are paired with READ_ONCE() in __packet_get_status */ -+ - h.raw = frame; - switch (po->tp_version) { - case TPACKET_V1: -- h.h1->tp_status = status; -+ WRITE_ONCE(h.h1->tp_status, status); - flush_dcache_page(pgv_to_page(&h.h1->tp_status)); - break; - case TPACKET_V2: -- h.h2->tp_status = status; -+ WRITE_ONCE(h.h2->tp_status, status); - flush_dcache_page(pgv_to_page(&h.h2->tp_status)); - break; - case TPACKET_V3: -- h.h3->tp_status = status; -+ WRITE_ONCE(h.h3->tp_status, status); - flush_dcache_page(pgv_to_page(&h.h3->tp_status)); - break; - default: -@@ -432,17 +434,19 @@ static int __packet_get_status(const struct packet_sock *po, void *frame) - - smp_rmb(); - -+ /* READ_ONCE() are paired with WRITE_ONCE() in __packet_set_status */ -+ - h.raw = frame; - switch (po->tp_version) { - case TPACKET_V1: - flush_dcache_page(pgv_to_page(&h.h1->tp_status)); -- return h.h1->tp_status; -+ return READ_ONCE(h.h1->tp_status); - case TPACKET_V2: - flush_dcache_page(pgv_to_page(&h.h2->tp_status)); -- return h.h2->tp_status; -+ return READ_ONCE(h.h2->tp_status); - case TPACKET_V3: - flush_dcache_page(pgv_to_page(&h.h3->tp_status)); -- return h.h3->tp_status; -+ return READ_ONCE(h.h3->tp_status); - default: - WARN(1, "TPACKET version not supported.\n"); - BUG(); -diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c -index aa9842158df0a..d0e045116d4e9 100644 ---- a/net/sched/sch_netem.c -+++ b/net/sched/sch_netem.c -@@ -773,12 +773,10 @@ static void dist_free(struct disttable *d) - * signed 16 bit values. - */ - --static int get_dist_table(struct Qdisc *sch, struct disttable **tbl, -- const struct nlattr *attr) -+static int get_dist_table(struct disttable **tbl, const struct nlattr *attr) - { - size_t n = nla_len(attr)/sizeof(__s16); - const __s16 *data = nla_data(attr); -- spinlock_t *root_lock; - struct disttable *d; - int i; - -@@ -793,13 +791,7 @@ static int get_dist_table(struct Qdisc *sch, struct disttable **tbl, - for (i = 0; i < n; i++) - d->table[i] = data[i]; - -- root_lock = qdisc_root_sleeping_lock(sch); -- -- spin_lock_bh(root_lock); -- swap(*tbl, d); -- spin_unlock_bh(root_lock); -- -- dist_free(d); -+ *tbl = d; - return 0; - } - -@@ -956,6 +948,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt, - { - struct netem_sched_data *q = qdisc_priv(sch); - struct nlattr *tb[TCA_NETEM_MAX + 1]; -+ struct disttable *delay_dist = NULL; -+ struct disttable *slot_dist = NULL; - struct tc_netem_qopt *qopt; - struct clgstate old_clg; - int old_loss_model = CLG_RANDOM; -@@ -966,6 +960,18 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt, - if (ret < 0) - return ret; - -+ if (tb[TCA_NETEM_DELAY_DIST]) { -+ ret = get_dist_table(&delay_dist, tb[TCA_NETEM_DELAY_DIST]); -+ if (ret) -+ goto table_free; -+ } -+ -+ if (tb[TCA_NETEM_SLOT_DIST]) { -+ ret = get_dist_table(&slot_dist, tb[TCA_NETEM_SLOT_DIST]); -+ if (ret) -+ goto table_free; -+ } -+ - sch_tree_lock(sch); - /* backup q->clg and q->loss_model */ - old_clg = q->clg; -@@ -975,26 +981,17 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt, - ret = get_loss_clg(q, tb[TCA_NETEM_LOSS]); - if (ret) { - q->loss_model = old_loss_model; -+ q->clg = old_clg; - goto unlock; - } - } else { - q->loss_model = CLG_RANDOM; - } - -- if (tb[TCA_NETEM_DELAY_DIST]) { -- ret = get_dist_table(sch, &q->delay_dist, -- tb[TCA_NETEM_DELAY_DIST]); -- if (ret) -- goto get_table_failure; -- } -- -- if (tb[TCA_NETEM_SLOT_DIST]) { -- ret = get_dist_table(sch, &q->slot_dist, -- tb[TCA_NETEM_SLOT_DIST]); -- if (ret) -- goto get_table_failure; -- } -- -+ if (delay_dist) -+ swap(q->delay_dist, delay_dist); -+ if (slot_dist) -+ swap(q->slot_dist, slot_dist); - sch->limit = qopt->limit; - - q->latency = PSCHED_TICKS2NS(qopt->latency); -@@ -1044,17 +1041,11 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt, - - unlock: - sch_tree_unlock(sch); -- return ret; - --get_table_failure: -- /* recover clg and loss_model, in case of -- * q->clg and q->loss_model were modified -- * in get_loss_clg() -- */ -- q->clg = old_clg; -- q->loss_model = old_loss_model; -- -- goto unlock; -+table_free: -+ dist_free(delay_dist); -+ dist_free(slot_dist); -+ return ret; - } - - static int netem_init(struct Qdisc *sch, struct nlattr *opt, -diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c -index 5ae0a54a823b5..5712a5297bd01 100644 ---- a/net/smc/af_smc.c -+++ b/net/smc/af_smc.c -@@ -438,13 +438,60 @@ out: - return rc; - } - -+/* copy only relevant settings and flags of SOL_SOCKET level from smc to -+ * clc socket (since smc is not called for these options from net/core) -+ */ -+ -+#define SK_FLAGS_SMC_TO_CLC ((1UL << SOCK_URGINLINE) | \ -+ (1UL << SOCK_KEEPOPEN) | \ -+ (1UL << SOCK_LINGER) | \ -+ (1UL << SOCK_BROADCAST) | \ -+ (1UL << SOCK_TIMESTAMP) | \ -+ (1UL << SOCK_DBG) | \ -+ (1UL << SOCK_RCVTSTAMP) | \ -+ (1UL << SOCK_RCVTSTAMPNS) | \ -+ (1UL << SOCK_LOCALROUTE) | \ -+ (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE) | \ -+ (1UL << SOCK_RXQ_OVFL) | \ -+ (1UL << SOCK_WIFI_STATUS) | \ -+ (1UL << SOCK_NOFCS) | \ -+ (1UL << SOCK_FILTER_LOCKED) | \ -+ (1UL << SOCK_TSTAMP_NEW)) -+ -+/* if set, use value set by setsockopt() - else use IPv4 or SMC sysctl value */ -+static void smc_adjust_sock_bufsizes(struct sock *nsk, struct sock *osk, -+ unsigned long mask) -+{ -+ struct net *nnet = sock_net(nsk); -+ -+ nsk->sk_userlocks = osk->sk_userlocks; -+ if (osk->sk_userlocks & SOCK_SNDBUF_LOCK) { -+ nsk->sk_sndbuf = osk->sk_sndbuf; -+ } else { -+ if (mask == SK_FLAGS_SMC_TO_CLC) -+ WRITE_ONCE(nsk->sk_sndbuf, -+ READ_ONCE(nnet->ipv4.sysctl_tcp_wmem[1])); -+ else -+ WRITE_ONCE(nsk->sk_sndbuf, -+ 2 * READ_ONCE(nnet->smc.sysctl_wmem)); -+ } -+ if (osk->sk_userlocks & SOCK_RCVBUF_LOCK) { -+ nsk->sk_rcvbuf = osk->sk_rcvbuf; -+ } else { -+ if (mask == SK_FLAGS_SMC_TO_CLC) -+ WRITE_ONCE(nsk->sk_rcvbuf, -+ READ_ONCE(nnet->ipv4.sysctl_tcp_rmem[1])); -+ else -+ WRITE_ONCE(nsk->sk_rcvbuf, -+ 2 * READ_ONCE(nnet->smc.sysctl_rmem)); -+ } -+} -+ - static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk, - unsigned long mask) - { - /* options we don't get control via setsockopt for */ - nsk->sk_type = osk->sk_type; -- nsk->sk_sndbuf = osk->sk_sndbuf; -- nsk->sk_rcvbuf = osk->sk_rcvbuf; - nsk->sk_sndtimeo = osk->sk_sndtimeo; - nsk->sk_rcvtimeo = osk->sk_rcvtimeo; - nsk->sk_mark = READ_ONCE(osk->sk_mark); -@@ -455,26 +502,10 @@ static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk, - - nsk->sk_flags &= ~mask; - nsk->sk_flags |= osk->sk_flags & mask; -+ -+ smc_adjust_sock_bufsizes(nsk, osk, mask); - } - --#define SK_FLAGS_SMC_TO_CLC ((1UL << SOCK_URGINLINE) | \ -- (1UL << SOCK_KEEPOPEN) | \ -- (1UL << SOCK_LINGER) | \ -- (1UL << SOCK_BROADCAST) | \ -- (1UL << SOCK_TIMESTAMP) | \ -- (1UL << SOCK_DBG) | \ -- (1UL << SOCK_RCVTSTAMP) | \ -- (1UL << SOCK_RCVTSTAMPNS) | \ -- (1UL << SOCK_LOCALROUTE) | \ -- (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE) | \ -- (1UL << SOCK_RXQ_OVFL) | \ -- (1UL << SOCK_WIFI_STATUS) | \ -- (1UL << SOCK_NOFCS) | \ -- (1UL << SOCK_FILTER_LOCKED) | \ -- (1UL << SOCK_TSTAMP_NEW)) --/* copy only relevant settings and flags of SOL_SOCKET level from smc to -- * clc socket (since smc is not called for these options from net/core) -- */ - static void smc_copy_sock_settings_to_clc(struct smc_sock *smc) - { - smc_copy_sock_settings(smc->clcsock->sk, &smc->sk, SK_FLAGS_SMC_TO_CLC); -@@ -2466,8 +2497,6 @@ static void smc_tcp_listen_work(struct work_struct *work) - sock_hold(lsk); /* sock_put in smc_listen_work */ - INIT_WORK(&new_smc->smc_listen_work, smc_listen_work); - smc_copy_sock_settings_to_smc(new_smc); -- new_smc->sk.sk_sndbuf = lsmc->sk.sk_sndbuf; -- new_smc->sk.sk_rcvbuf = lsmc->sk.sk_rcvbuf; - sock_hold(&new_smc->sk); /* sock_put in passive closing */ - if (!queue_work(smc_hs_wq, &new_smc->smc_listen_work)) - sock_put(&new_smc->sk); -diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c -index bf69c9d6d06c0..1849827884735 100644 ---- a/net/tls/tls_device.c -+++ b/net/tls/tls_device.c -@@ -52,6 +52,8 @@ static LIST_HEAD(tls_device_list); - static LIST_HEAD(tls_device_down_list); - static DEFINE_SPINLOCK(tls_device_lock); - -+static struct page *dummy_page; -+ - static void tls_device_free_ctx(struct tls_context *ctx) - { - if (ctx->tx_conf == TLS_HW) { -@@ -313,36 +315,33 @@ static int tls_push_record(struct sock *sk, - return tls_push_sg(sk, ctx, offload_ctx->sg_tx_data, 0, flags); - } - --static int tls_device_record_close(struct sock *sk, -- struct tls_context *ctx, -- struct tls_record_info *record, -- struct page_frag *pfrag, -- unsigned char record_type) -+static void tls_device_record_close(struct sock *sk, -+ struct tls_context *ctx, -+ struct tls_record_info *record, -+ struct page_frag *pfrag, -+ unsigned char record_type) - { - struct tls_prot_info *prot = &ctx->prot_info; -- int ret; -+ struct page_frag dummy_tag_frag; - - /* append tag - * device will fill in the tag, we just need to append a placeholder - * use socket memory to improve coalescing (re-using a single buffer - * increases frag count) -- * if we can't allocate memory now, steal some back from data -+ * if we can't allocate memory now use the dummy page - */ -- if (likely(skb_page_frag_refill(prot->tag_size, pfrag, -- sk->sk_allocation))) { -- ret = 0; -- tls_append_frag(record, pfrag, prot->tag_size); -- } else { -- ret = prot->tag_size; -- if (record->len <= prot->overhead_size) -- return -ENOMEM; -+ if (unlikely(pfrag->size - pfrag->offset < prot->tag_size) && -+ !skb_page_frag_refill(prot->tag_size, pfrag, sk->sk_allocation)) { -+ dummy_tag_frag.page = dummy_page; -+ dummy_tag_frag.offset = 0; -+ pfrag = &dummy_tag_frag; - } -+ tls_append_frag(record, pfrag, prot->tag_size); - - /* fill prepend */ - tls_fill_prepend(ctx, skb_frag_address(&record->frags[0]), - record->len - prot->overhead_size, - record_type); -- return ret; - } - - static int tls_create_new_record(struct tls_offload_context_tx *offload_ctx, -@@ -535,18 +534,8 @@ last_record: - - if (done || record->len >= max_open_record_len || - (record->num_frags >= MAX_SKB_FRAGS - 1)) { -- rc = tls_device_record_close(sk, tls_ctx, record, -- pfrag, record_type); -- if (rc) { -- if (rc > 0) { -- size += rc; -- } else { -- size = orig_size; -- destroy_record(record); -- ctx->open_record = NULL; -- break; -- } -- } -+ tls_device_record_close(sk, tls_ctx, record, -+ pfrag, record_type); - - rc = tls_push_record(sk, - tls_ctx, -@@ -1466,14 +1455,26 @@ int __init tls_device_init(void) - { - int err; - -- destruct_wq = alloc_workqueue("ktls_device_destruct", 0, 0); -- if (!destruct_wq) -+ dummy_page = alloc_page(GFP_KERNEL); -+ if (!dummy_page) - return -ENOMEM; - -+ destruct_wq = alloc_workqueue("ktls_device_destruct", 0, 0); -+ if (!destruct_wq) { -+ err = -ENOMEM; -+ goto err_free_dummy; -+ } -+ - err = register_netdevice_notifier(&tls_dev_notifier); - if (err) -- destroy_workqueue(destruct_wq); -+ goto err_destroy_wq; - -+ return 0; -+ -+err_destroy_wq: -+ destroy_workqueue(destruct_wq); -+err_free_dummy: -+ put_page(dummy_page); - return err; - } - -@@ -1482,4 +1483,5 @@ void __exit tls_device_cleanup(void) - unregister_netdevice_notifier(&tls_dev_notifier); - destroy_workqueue(destruct_wq); - clean_acked_data_flush(); -+ put_page(dummy_page); - } -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index 087c0c442e231..c2363d44a1ffc 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -5378,8 +5378,11 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs) - if (!wiphy->mbssid_max_interfaces) - return ERR_PTR(-EINVAL); - -- nla_for_each_nested(nl_elems, attrs, rem_elems) -+ nla_for_each_nested(nl_elems, attrs, rem_elems) { -+ if (num_elems >= 255) -+ return ERR_PTR(-EINVAL); - num_elems++; -+ } - - elems = kzalloc(struct_size(elems, elem, num_elems), GFP_KERNEL); - if (!elems) -diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c -index 22bf10ffbf2d1..f7592638e61d3 100644 ---- a/net/xdp/xsk.c -+++ b/net/xdp/xsk.c -@@ -994,6 +994,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) - err = xp_alloc_tx_descs(xs->pool, xs); - if (err) { - xp_put_pool(xs->pool); -+ xs->pool = NULL; - sockfd_put(sock); - goto out_unlock; - } -diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h -index 9a1895747b153..84c730da36dd3 100644 ---- a/scripts/gcc-plugins/gcc-common.h -+++ b/scripts/gcc-plugins/gcc-common.h -@@ -71,7 +71,9 @@ - #include "varasm.h" - #include "stor-layout.h" - #include "internal-fn.h" -+#include "gimple.h" - #include "gimple-expr.h" -+#include "gimple-iterator.h" - #include "gimple-fold.h" - #include "context.h" - #include "tree-ssa-alias.h" -@@ -85,10 +87,8 @@ - #include "tree-eh.h" - #include "stmt.h" - #include "gimplify.h" --#include "gimple.h" - #include "tree-phinodes.h" - #include "tree-cfg.h" --#include "gimple-iterator.h" - #include "gimple-ssa.h" - #include "ssa-iterators.h" - -diff --git a/tools/testing/radix-tree/regression1.c b/tools/testing/radix-tree/regression1.c -index a61c7bcbc72da..63f468bf8245c 100644 ---- a/tools/testing/radix-tree/regression1.c -+++ b/tools/testing/radix-tree/regression1.c -@@ -177,7 +177,7 @@ void regression1_test(void) - nr_threads = 2; - pthread_barrier_init(&worker_barrier, NULL, nr_threads); - -- threads = malloc(nr_threads * sizeof(pthread_t *)); -+ threads = malloc(nr_threads * sizeof(*threads)); - - for (i = 0; i < nr_threads; i++) { - arg = i; -diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh -index 0f5e88c8f4ffe..df8d90b51867a 100755 ---- a/tools/testing/selftests/net/fib_nexthops.sh -+++ b/tools/testing/selftests/net/fib_nexthops.sh -@@ -1981,6 +1981,11 @@ basic() - - run_cmd "$IP link set dev lo up" - -+ # Dump should not loop endlessly when maximum nexthop ID is configured. -+ run_cmd "$IP nexthop add id $((2**32-1)) blackhole" -+ run_cmd "timeout 5 $IP nexthop" -+ log_test $? 0 "Maximum nexthop ID dump" -+ - # - # groups - # -@@ -2201,6 +2206,11 @@ basic_res() - run_cmd "$IP nexthop bucket list fdb" - log_test $? 255 "Dump all nexthop buckets with invalid 'fdb' keyword" - -+ # Dump should not loop endlessly when maximum nexthop ID is configured. -+ run_cmd "$IP nexthop add id $((2**32-1)) group 1/2 type resilient buckets 4" -+ run_cmd "timeout 5 $IP nexthop bucket" -+ log_test $? 0 "Maximum nexthop ID dump" -+ - # - # resilient nexthop buckets get requests - # -diff --git a/tools/testing/selftests/net/forwarding/ethtool.sh b/tools/testing/selftests/net/forwarding/ethtool.sh -index dbb9fcf759e0f..aa2eafb7b2437 100755 ---- a/tools/testing/selftests/net/forwarding/ethtool.sh -+++ b/tools/testing/selftests/net/forwarding/ethtool.sh -@@ -286,6 +286,8 @@ different_speeds_autoneg_on() - ethtool -s $h1 autoneg on - } - -+skip_on_veth -+ - trap cleanup EXIT - - setup_prepare -diff --git a/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh b/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh -index 072faa77f53bd..17f89c3b7c020 100755 ---- a/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh -+++ b/tools/testing/selftests/net/forwarding/ethtool_extended_state.sh -@@ -108,6 +108,8 @@ no_cable() - ip link set dev $swp3 down - } - -+skip_on_veth -+ - setup_prepare - - tests_run -diff --git a/tools/testing/selftests/net/forwarding/hw_stats_l3_gre.sh b/tools/testing/selftests/net/forwarding/hw_stats_l3_gre.sh -index eb9ec4a68f84b..7594bbb490292 100755 ---- a/tools/testing/selftests/net/forwarding/hw_stats_l3_gre.sh -+++ b/tools/testing/selftests/net/forwarding/hw_stats_l3_gre.sh -@@ -99,6 +99,8 @@ test_stats_rx() - test_stats g2a rx - } - -+skip_on_veth -+ - trap cleanup EXIT - - setup_prepare -diff --git a/tools/testing/selftests/net/forwarding/ip6_forward_instats_vrf.sh b/tools/testing/selftests/net/forwarding/ip6_forward_instats_vrf.sh -index 9f5b3e2e5e954..49fa94b53a1ca 100755 ---- a/tools/testing/selftests/net/forwarding/ip6_forward_instats_vrf.sh -+++ b/tools/testing/selftests/net/forwarding/ip6_forward_instats_vrf.sh -@@ -14,6 +14,8 @@ ALL_TESTS=" - NUM_NETIFS=4 - source lib.sh - -+require_command $TROUTE6 -+ - h1_create() - { - simple_if_init $h1 2001:1:1::2/64 -diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh -index f4721f1b2886b..06027772cf79a 100755 ---- a/tools/testing/selftests/net/forwarding/lib.sh -+++ b/tools/testing/selftests/net/forwarding/lib.sh -@@ -30,6 +30,7 @@ REQUIRE_MZ=${REQUIRE_MZ:=yes} - REQUIRE_MTOOLS=${REQUIRE_MTOOLS:=no} - STABLE_MAC_ADDRS=${STABLE_MAC_ADDRS:=no} - TCPDUMP_EXTRA_FLAGS=${TCPDUMP_EXTRA_FLAGS:=} -+TROUTE6=${TROUTE6:=traceroute6} - - relative_path="${BASH_SOURCE%/*}" - if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then -@@ -137,6 +138,17 @@ check_locked_port_support() - fi - } - -+skip_on_veth() -+{ -+ local kind=$(ip -j -d link show dev ${NETIFS[p1]} | -+ jq -r '.[].linkinfo.info_kind') -+ -+ if [[ $kind == veth ]]; then -+ echo "SKIP: Test cannot be run with veth pairs" -+ exit $ksft_skip -+ fi -+} -+ - if [[ "$(id -u)" -ne 0 ]]; then - echo "SKIP: need root privileges" - exit $ksft_skip -@@ -199,6 +211,11 @@ create_netif_veth() - for ((i = 1; i <= NUM_NETIFS; ++i)); do - local j=$((i+1)) - -+ if [ -z ${NETIFS[p$i]} ]; then -+ echo "SKIP: Cannot create interface. Name not specified" -+ exit $ksft_skip -+ fi -+ - ip link show dev ${NETIFS[p$i]} &> /dev/null - if [[ $? -ne 0 ]]; then - ip link add ${NETIFS[p$i]} type veth \ -diff --git a/tools/testing/selftests/net/forwarding/settings b/tools/testing/selftests/net/forwarding/settings -new file mode 100644 -index 0000000000000..e7b9417537fbc ---- /dev/null -+++ b/tools/testing/selftests/net/forwarding/settings -@@ -0,0 +1 @@ -+timeout=0 -diff --git a/tools/testing/selftests/net/forwarding/tc_flower.sh b/tools/testing/selftests/net/forwarding/tc_flower.sh -index 683711f41aa9b..b1daad19b01ec 100755 ---- a/tools/testing/selftests/net/forwarding/tc_flower.sh -+++ b/tools/testing/selftests/net/forwarding/tc_flower.sh -@@ -52,8 +52,8 @@ match_dst_mac_test() - tc_check_packets "dev $h2 ingress" 101 1 - check_fail $? "Matched on a wrong filter" - -- tc_check_packets "dev $h2 ingress" 102 1 -- check_err $? "Did not match on correct filter" -+ tc_check_packets "dev $h2 ingress" 102 0 -+ check_fail $? "Did not match on correct filter" - - tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower - tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower -@@ -78,8 +78,8 @@ match_src_mac_test() - tc_check_packets "dev $h2 ingress" 101 1 - check_fail $? "Matched on a wrong filter" - -- tc_check_packets "dev $h2 ingress" 102 1 -- check_err $? "Did not match on correct filter" -+ tc_check_packets "dev $h2 ingress" 102 0 -+ check_fail $? "Did not match on correct filter" - - tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower - tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower -diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh -index a3108c3cff471..7b20878a1af59 100755 ---- a/tools/testing/selftests/net/mptcp/mptcp_join.sh -+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh -@@ -650,6 +650,7 @@ pm_nl_del_endpoint() - local addr=$3 - - if [ $ip_mptcp -eq 1 ]; then -+ [ $id -ne 0 ] && addr='' - ip -n $ns mptcp endpoint delete id $id $addr - else - ip netns exec $ns ./pm_nl_ctl del $id $addr -@@ -740,10 +741,11 @@ pm_nl_check_endpoint() - fi - - if [ $ip_mptcp -eq 1 ]; then -+ # get line and trim trailing whitespace - line=$(ip -n $ns mptcp endpoint show $id) -+ line="${line% }" - # the dump order is: address id flags port dev -- expected_line="$addr" -- [ -n "$addr" ] && expected_line="$expected_line $addr" -+ [ -n "$addr" ] && expected_line="$addr" - expected_line="$expected_line $id" - [ -n "$_flags" ] && expected_line="$expected_line ${_flags//","/" "}" - [ -n "$dev" ] && expected_line="$expected_line $dev" -diff --git a/tools/testing/selftests/rseq/Makefile b/tools/testing/selftests/rseq/Makefile -index 3a173e184566c..cb5a9fc629fed 100644 ---- a/tools/testing/selftests/rseq/Makefile -+++ b/tools/testing/selftests/rseq/Makefile -@@ -4,8 +4,10 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) - CLANG_FLAGS += -no-integrated-as - endif - -+top_srcdir = ../../../.. -+ - CFLAGS += -O2 -Wall -g -I./ $(KHDR_INCLUDES) -L$(OUTPUT) -Wl,-rpath=./ \ -- $(CLANG_FLAGS) -+ $(CLANG_FLAGS) -I$(top_srcdir)/tools/include - LDLIBS += -lpthread -ldl - - # Own dependencies because we only want to build against 1st prerequisite, but -diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c -index b736a5169aad0..e20191fb40d49 100644 ---- a/tools/testing/selftests/rseq/rseq.c -+++ b/tools/testing/selftests/rseq/rseq.c -@@ -29,6 +29,8 @@ - #include - #include - -+#include -+ - #include "../kselftest.h" - #include "rseq.h" - diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.46-47.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.46-47.patch deleted file mode 100644 index ab31fe98ba96..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.46-47.patch +++ /dev/null @@ -1,8047 +0,0 @@ -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 286be425f3bfa..882b6198dd0d1 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -323,6 +323,7 @@ - option with care. - pgtbl_v1 - Use v1 page table for DMA-API (Default). - pgtbl_v2 - Use v2 page table for DMA-API. -+ irtcachedis - Disable Interrupt Remapping Table (IRT) caching. - - amd_iommu_dump= [HW,X86-64] - Enable AMD IOMMU driver option to dump the ACPI table -diff --git a/Makefile b/Makefile -index bdb965177db52..375efcfb91f8f 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 46 -+SUBLEVEL = 47 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/imx50-kobo-aura.dts b/arch/arm/boot/dts/imx50-kobo-aura.dts -index 51bf6117fb124..467db6b4ed7f8 100644 ---- a/arch/arm/boot/dts/imx50-kobo-aura.dts -+++ b/arch/arm/boot/dts/imx50-kobo-aura.dts -@@ -26,7 +26,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_leds>; - -- on { -+ led-on { - label = "kobo_aura:orange:on"; - gpios = <&gpio6 24 GPIO_ACTIVE_LOW>; - panic-indicator; -diff --git a/arch/arm/boot/dts/imx53-cx9020.dts b/arch/arm/boot/dts/imx53-cx9020.dts -index cfb18849a92b4..055d23a9aee7c 100644 ---- a/arch/arm/boot/dts/imx53-cx9020.dts -+++ b/arch/arm/boot/dts/imx53-cx9020.dts -@@ -86,27 +86,27 @@ - leds { - compatible = "gpio-leds"; - -- pwr-r { -+ led-pwr-r { - gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; - default-state = "off"; - }; - -- pwr-g { -+ led-pwr-g { - gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - -- pwr-b { -+ led-pwr-b { - gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; - default-state = "off"; - }; - -- sd1-b { -+ led-sd1-b { - linux,default-trigger = "mmc0"; - gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; - }; - -- sd2-b { -+ led-sd2-b { - linux,default-trigger = "mmc1"; - gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>; - }; -diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts -index a1a6228d1aa66..2bd2432d317ff 100644 ---- a/arch/arm/boot/dts/imx53-m53evk.dts -+++ b/arch/arm/boot/dts/imx53-m53evk.dts -@@ -52,13 +52,13 @@ - pinctrl-names = "default"; - pinctrl-0 = <&led_pin_gpio>; - -- user1 { -+ led-user1 { - label = "user1"; - gpios = <&gpio2 8 0>; - linux,default-trigger = "heartbeat"; - }; - -- user2 { -+ led-user2 { - label = "user2"; - gpios = <&gpio2 9 0>; - linux,default-trigger = "heartbeat"; -diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts -index d5c68d1ea707c..4d77b6077fc1b 100644 ---- a/arch/arm/boot/dts/imx53-m53menlo.dts -+++ b/arch/arm/boot/dts/imx53-m53menlo.dts -@@ -34,19 +34,19 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; - -- user1 { -+ led-user1 { - label = "TestLed601"; - gpios = <&gpio6 1 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "mmc0"; - }; - -- user2 { -+ led-user2 { - label = "TestLed602"; - gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - }; - -- eth { -+ led-eth { - label = "EthLedYe"; - gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; - linux,default-trigger = "netdev"; -diff --git a/arch/arm/boot/dts/imx53-tx53.dtsi b/arch/arm/boot/dts/imx53-tx53.dtsi -index 892dd1a4bac35..a439a47fb65ac 100644 ---- a/arch/arm/boot/dts/imx53-tx53.dtsi -+++ b/arch/arm/boot/dts/imx53-tx53.dtsi -@@ -94,7 +94,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_stk5led>; - -- user { -+ led-user { - label = "Heartbeat"; - gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; -diff --git a/arch/arm/boot/dts/imx53-usbarmory.dts b/arch/arm/boot/dts/imx53-usbarmory.dts -index f34993a490ee8..acc44010d5106 100644 ---- a/arch/arm/boot/dts/imx53-usbarmory.dts -+++ b/arch/arm/boot/dts/imx53-usbarmory.dts -@@ -67,7 +67,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; - -- user { -+ led-user { - label = "LED"; - gpios = <&gpio4 27 GPIO_ACTIVE_LOW>; - linux,default-trigger = "heartbeat"; -diff --git a/arch/arm/boot/dts/imx6dl-b1x5pv2.dtsi b/arch/arm/boot/dts/imx6dl-b1x5pv2.dtsi -index 337db29b0010a..37697fac9dea9 100644 ---- a/arch/arm/boot/dts/imx6dl-b1x5pv2.dtsi -+++ b/arch/arm/boot/dts/imx6dl-b1x5pv2.dtsi -@@ -211,17 +211,17 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_q7_gpio1 &pinctrl_q7_gpio3 &pinctrl_q7_gpio5>; - -- alarm1 { -+ led-alarm1 { - label = "alarm:red"; - gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; - }; - -- alarm2 { -+ led-alarm2 { - label = "alarm:yellow"; - gpios = <&gpio4 27 GPIO_ACTIVE_HIGH>; - }; - -- alarm3 { -+ led-alarm3 { - label = "alarm:blue"; - gpios = <&gpio4 15 GPIO_ACTIVE_HIGH>; - }; -diff --git a/arch/arm/boot/dts/imx6dl-prtrvt.dts b/arch/arm/boot/dts/imx6dl-prtrvt.dts -index 56bb1ca56a2df..36b031236e475 100644 ---- a/arch/arm/boot/dts/imx6dl-prtrvt.dts -+++ b/arch/arm/boot/dts/imx6dl-prtrvt.dts -@@ -124,6 +124,10 @@ - status = "disabled"; - }; - -+&usbotg { -+ disable-over-current; -+}; -+ - &vpu { - status = "disabled"; - }; -diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts -index e7be05f205d32..24c7f535f63bd 100644 ---- a/arch/arm/boot/dts/imx6dl-riotboard.dts -+++ b/arch/arm/boot/dts/imx6dl-riotboard.dts -@@ -25,14 +25,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio3 28 GPIO_ACTIVE_LOW>; - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi -index 52162e8c7274b..aacbf317feea6 100644 ---- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi -+++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi -@@ -274,7 +274,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- chan@0 { -+ led@0 { - chan-name = "R"; - led-cur = /bits/ 8 <0x20>; - max-cur = /bits/ 8 <0x60>; -@@ -282,7 +282,7 @@ - color = ; - }; - -- chan@1 { -+ led@1 { - chan-name = "G"; - led-cur = /bits/ 8 <0x20>; - max-cur = /bits/ 8 <0x60>; -@@ -290,7 +290,7 @@ - color = ; - }; - -- chan@2 { -+ led@2 { - chan-name = "B"; - led-cur = /bits/ 8 <0x20>; - max-cur = /bits/ 8 <0x60>; -diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts -index e894faba571f9..522a51042965a 100644 ---- a/arch/arm/boot/dts/imx6q-gw5400-a.dts -+++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts -@@ -34,20 +34,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 -> MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 10 GPIO_ACTIVE_HIGH>; /* 106 -> MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* 111 -> MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6q-h100.dts b/arch/arm/boot/dts/imx6q-h100.dts -index b8feadbff967d..6406ade14f57b 100644 ---- a/arch/arm/boot/dts/imx6q-h100.dts -+++ b/arch/arm/boot/dts/imx6q-h100.dts -@@ -76,19 +76,19 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_h100_leds>; - -- led0: power { -+ led0: led-power { - label = "power"; - gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; - default-state = "on"; - }; - -- led1: stream { -+ led1: led-stream { - label = "stream"; - gpios = <&gpio2 29 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - -- led2: rec { -+ led2: led-rec { - label = "rec"; - gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6q-kp.dtsi b/arch/arm/boot/dts/imx6q-kp.dtsi -index 1ade0bff681d6..5e0ed55600405 100644 ---- a/arch/arm/boot/dts/imx6q-kp.dtsi -+++ b/arch/arm/boot/dts/imx6q-kp.dtsi -@@ -66,14 +66,14 @@ - leds { - compatible = "gpio-leds"; - -- green { -+ led-green { - label = "led1"; - gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "gpio"; - default-state = "off"; - }; - -- red { -+ led-red { - label = "led0"; - gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "gpio"; -diff --git a/arch/arm/boot/dts/imx6q-marsboard.dts b/arch/arm/boot/dts/imx6q-marsboard.dts -index cc18010023942..2c9961333b0a8 100644 ---- a/arch/arm/boot/dts/imx6q-marsboard.dts -+++ b/arch/arm/boot/dts/imx6q-marsboard.dts -@@ -73,14 +73,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; - -- user1 { -+ led-user1 { - label = "imx6:green:user1"; - gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; - default-state = "off"; - linux,default-trigger = "heartbeat"; - }; - -- user2 { -+ led-user2 { - label = "imx6:green:user2"; - gpios = <&gpio3 28 GPIO_ACTIVE_LOW>; - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6q-tbs2910.dts b/arch/arm/boot/dts/imx6q-tbs2910.dts -index 8daef65d5bb35..2f576e2ce73f2 100644 ---- a/arch/arm/boot/dts/imx6q-tbs2910.dts -+++ b/arch/arm/boot/dts/imx6q-tbs2910.dts -@@ -49,7 +49,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- blue { -+ led-blue { - label = "blue_status_led"; - gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; - default-state = "keep"; -diff --git a/arch/arm/boot/dts/imx6qdl-emcon.dtsi b/arch/arm/boot/dts/imx6qdl-emcon.dtsi -index 7228b894a763f..ee2dd75cead6d 100644 ---- a/arch/arm/boot/dts/imx6qdl-emcon.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-emcon.dtsi -@@ -46,14 +46,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_som_leds>; - -- green { -+ led-green { - label = "som:green"; - gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - default-state = "on"; - }; - -- red { -+ led-red { - label = "som:red"; - gpios = <&gpio3 1 GPIO_ACTIVE_LOW>; - default-state = "keep"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi -index 069c27fab432c..e75e1a5364b85 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi -@@ -71,14 +71,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi -index 728810b9d677d..47d9a8d08197d 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi -@@ -80,20 +80,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi -index 6c0c109046d80..fb1d29abe0991 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi -@@ -80,20 +80,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi -index a9b04f9f1c2bc..4e20cb97058eb 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi -@@ -81,20 +81,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw551x.dtsi b/arch/arm/boot/dts/imx6qdl-gw551x.dtsi -index 435dec6338fe6..0fa4b8eeddee7 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw551x.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw551x.dtsi -@@ -115,7 +115,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 7 GPIO_ACTIVE_LOW>; - default-state = "on"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi -index 2e61102ae6946..77ae611b817a4 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi -@@ -72,20 +72,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi -index 4662408b225a5..7f16c602cc075 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi -@@ -113,14 +113,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 10 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 11 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi -index 4b81a975c979d..46cf4080fec38 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi -@@ -139,20 +139,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw5903.dtsi b/arch/arm/boot/dts/imx6qdl-gw5903.dtsi -index 1fdb7ba630f1b..a74cde0501589 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw5903.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw5903.dtsi -@@ -123,7 +123,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw5904.dtsi b/arch/arm/boot/dts/imx6qdl-gw5904.dtsi -index 612b6e068e282..9fc79af2bc9aa 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw5904.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw5904.dtsi -@@ -120,20 +120,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw5907.dtsi b/arch/arm/boot/dts/imx6qdl-gw5907.dtsi -index fcd3bdfd61827..955a51226eda7 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw5907.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw5907.dtsi -@@ -71,14 +71,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi -index 6bb4855d13ce5..218d6e667ed24 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi -@@ -74,20 +74,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw5912.dtsi b/arch/arm/boot/dts/imx6qdl-gw5912.dtsi -index 0415bcb416400..40e235e315cc4 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw5912.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw5912.dtsi -@@ -72,20 +72,20 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; - }; - -- led2: user3 { -+ led2: led-user3 { - label = "user3"; - gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi -index 696427b487f01..82f47c295b085 100644 ---- a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi -@@ -71,14 +71,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- led0: user1 { -+ led0: led-user1 { - label = "user1"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */ - default-state = "on"; - linux,default-trigger = "heartbeat"; - }; - -- led1: user2 { -+ led1: led-user2 { - label = "user2"; - gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */ - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi -index a53a5d0766a51..6d4eab1942b94 100644 ---- a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi -@@ -85,31 +85,31 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_leds>; - -- j14-pin1 { -+ led-j14-pin1 { - gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; - retain-state-suspended; - default-state = "off"; - }; - -- j14-pin3 { -+ led-j14-pin3 { - gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; - retain-state-suspended; - default-state = "off"; - }; - -- j14-pins8-9 { -+ led-j14-pins8-9 { - gpios = <&gpio3 29 GPIO_ACTIVE_LOW>; - retain-state-suspended; - default-state = "off"; - }; - -- j46-pin2 { -+ led-j46-pin2 { - gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; - retain-state-suspended; - default-state = "off"; - }; - -- j46-pin3 { -+ led-j46-pin3 { - gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; - retain-state-suspended; - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi -index 57c21a01f126d..81a9a302aec1b 100644 ---- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi -@@ -181,13 +181,13 @@ - leds { - compatible = "gpio-leds"; - -- speaker-enable { -+ led-speaker-enable { - gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>; - retain-state-suspended; - default-state = "off"; - }; - -- ttymxc4-rs232 { -+ led-ttymxc4-rs232 { - gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>; - retain-state-suspended; - default-state = "on"; -diff --git a/arch/arm/boot/dts/imx6qdl-phytec-mira.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-mira.dtsi -index 120d6e997a4c5..1ca4d219609f6 100644 ---- a/arch/arm/boot/dts/imx6qdl-phytec-mira.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-phytec-mira.dtsi -@@ -25,17 +25,17 @@ - pinctrl-0 = <&pinctrl_gpioleds>; - status = "disabled"; - -- red { -+ led-red { - label = "phyboard-mira:red"; - gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; - }; - -- green { -+ led-green { - label = "phyboard-mira:green"; - gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>; - }; - -- blue { -+ led-blue { - label = "phyboard-mira:blue"; - gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "mmc0"; -@@ -182,7 +182,7 @@ - pinctrl-0 = <&pinctrl_rtc_int>; - reg = <0x68>; - interrupt-parent = <&gpio7>; -- interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; -+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>; - status = "disabled"; - }; - }; -diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi -index 768bc0e3a2b38..80adb2a02cc94 100644 ---- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi -@@ -47,12 +47,12 @@ - pinctrl-0 = <&pinctrl_leds>; - compatible = "gpio-leds"; - -- led_green: green { -+ led_green: led-green { - label = "phyflex:green"; - gpios = <&gpio1 30 0>; - }; - -- led_red: red { -+ led_red: led-red { - label = "phyflex:red"; - gpios = <&gpio2 31 0>; - }; -diff --git a/arch/arm/boot/dts/imx6qdl-prti6q.dtsi b/arch/arm/boot/dts/imx6qdl-prti6q.dtsi -index f0db0d4471f40..36f84f4da6b0d 100644 ---- a/arch/arm/boot/dts/imx6qdl-prti6q.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-prti6q.dtsi -@@ -69,6 +69,7 @@ - vbus-supply = <®_usb_h1_vbus>; - phy_type = "utmi"; - dr_mode = "host"; -+ disable-over-current; - status = "okay"; - }; - -@@ -78,10 +79,18 @@ - pinctrl-0 = <&pinctrl_usbotg>; - phy_type = "utmi"; - dr_mode = "host"; -- disable-over-current; -+ over-current-active-low; - status = "okay"; - }; - -+&usbphynop1 { -+ status = "disabled"; -+}; -+ -+&usbphynop2 { -+ status = "disabled"; -+}; -+ - &usdhc1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc1>; -diff --git a/arch/arm/boot/dts/imx6qdl-rex.dtsi b/arch/arm/boot/dts/imx6qdl-rex.dtsi -index de514eb5aa99d..f804ff95a6ad6 100644 ---- a/arch/arm/boot/dts/imx6qdl-rex.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-rex.dtsi -@@ -55,7 +55,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; - -- led0: usr { -+ led0: led-usr { - label = "usr"; - gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi -index 3dbb460ef102e..10886a1461bfb 100644 ---- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi -@@ -21,7 +21,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- user { -+ led-user { - label = "debug"; - gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>; - }; -diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi -index 37482a9023fce..bcb83d52e26ed 100644 ---- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi -@@ -130,7 +130,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - -- red { -+ led-red { - gpios = <&gpio1 2 0>; - default-state = "on"; - }; -diff --git a/arch/arm/boot/dts/imx6qdl-ts7970.dtsi b/arch/arm/boot/dts/imx6qdl-ts7970.dtsi -index c096d25a6f5b5..1e0a041e9f60a 100644 ---- a/arch/arm/boot/dts/imx6qdl-ts7970.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-ts7970.dtsi -@@ -73,13 +73,13 @@ - default-state = "off"; - }; - -- en-usb-5v { -+ en-usb-5v-led { - label = "en-usb-5v"; - gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - -- sel_dc_usb { -+ sel-dc-usb-led { - label = "sel_dc_usb"; - gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>; - default-state = "off"; -diff --git a/arch/arm/boot/dts/imx6qdl-tx6.dtsi b/arch/arm/boot/dts/imx6qdl-tx6.dtsi -index f41f86a76ea95..a197bac95cbac 100644 ---- a/arch/arm/boot/dts/imx6qdl-tx6.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-tx6.dtsi -@@ -92,7 +92,7 @@ - leds { - compatible = "gpio-leds"; - -- user_led: user { -+ user_led: led-user { - label = "Heartbeat"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_user_led>; -diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts -index f16c830f1e918..dc5d596c18db4 100644 ---- a/arch/arm/boot/dts/imx6sl-evk.dts -+++ b/arch/arm/boot/dts/imx6sl-evk.dts -@@ -33,7 +33,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; - -- user { -+ led-user { - label = "debug"; - gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; -diff --git a/arch/arm/boot/dts/imx6sll-evk.dts b/arch/arm/boot/dts/imx6sll-evk.dts -index 32b3d82fec53c..269092ac881c5 100644 ---- a/arch/arm/boot/dts/imx6sll-evk.dts -+++ b/arch/arm/boot/dts/imx6sll-evk.dts -@@ -37,7 +37,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; - -- user { -+ led-user { - label = "debug"; - gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; -diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi -index 2873369a57c02..3659fd5ecfa62 100644 ---- a/arch/arm/boot/dts/imx6sll.dtsi -+++ b/arch/arm/boot/dts/imx6sll.dtsi -@@ -552,7 +552,7 @@ - reg = <0x020ca000 0x1000>; - interrupts = ; - clocks = <&clks IMX6SLL_CLK_USBPHY2>; -- phy-reg_3p0-supply = <®_3p0>; -+ phy-3p0-supply = <®_3p0>; - fsl,anatop = <&anatop>; - }; - -diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts -index 83ee97252ff11..b0c27b9b02446 100644 ---- a/arch/arm/boot/dts/imx6sx-sabreauto.dts -+++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts -@@ -20,7 +20,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; - -- user { -+ led-user { - label = "debug"; - gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; -diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi -index c84ea1fac5e98..725d0b5cb55f6 100644 ---- a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi -+++ b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi -@@ -15,14 +15,14 @@ - leds { - compatible = "gpio-leds"; - -- red { -+ led-red { - label = "udoo-neo:red:mmc"; - gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; - default-state = "off"; - linux,default-trigger = "mmc0"; - }; - -- orange { -+ led-orange { - label = "udoo-neo:orange:user"; - gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; - default-state = "keep"; -diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi -index abc3572d699e6..1f1053a898fbf 100644 ---- a/arch/arm/boot/dts/imx6sx.dtsi -+++ b/arch/arm/boot/dts/imx6sx.dtsi -@@ -981,6 +981,8 @@ - <&clks IMX6SX_CLK_USDHC1>; - clock-names = "ipg", "ahb", "per"; - bus-width = <4>; -+ fsl,tuning-start-tap = <20>; -+ fsl,tuning-step= <2>; - status = "disabled"; - }; - -@@ -993,6 +995,8 @@ - <&clks IMX6SX_CLK_USDHC2>; - clock-names = "ipg", "ahb", "per"; - bus-width = <4>; -+ fsl,tuning-start-tap = <20>; -+ fsl,tuning-step= <2>; - status = "disabled"; - }; - -@@ -1005,6 +1009,8 @@ - <&clks IMX6SX_CLK_USDHC3>; - clock-names = "ipg", "ahb", "per"; - bus-width = <4>; -+ fsl,tuning-start-tap = <20>; -+ fsl,tuning-step= <2>; - status = "disabled"; - }; - -diff --git a/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi -index 3cddc68917a08..e4d2652a75c0b 100644 ---- a/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi -+++ b/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi -@@ -30,7 +30,7 @@ - pinctrl-0 = <&pinctrl_gpioleds_som>; - compatible = "gpio-leds"; - -- phycore-green { -+ led-phycore-green { - gpios = <&gpio5 4 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - }; -diff --git a/arch/arm/boot/dts/imx6ul-tx6ul.dtsi b/arch/arm/boot/dts/imx6ul-tx6ul.dtsi -index 15ee0275feaff..70cef5e817bd1 100644 ---- a/arch/arm/boot/dts/imx6ul-tx6ul.dtsi -+++ b/arch/arm/boot/dts/imx6ul-tx6ul.dtsi -@@ -131,7 +131,7 @@ - leds { - compatible = "gpio-leds"; - -- user_led: user { -+ user_led: led-user { - label = "Heartbeat"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_led>; -diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi -index 420ba0d6f1343..12c82bb1bb7aa 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi -@@ -1145,10 +1145,9 @@ - compatible = "fsl,imx8mm-mipi-csi2"; - reg = <0x32e30000 0x1000>; - interrupts = ; -- assigned-clocks = <&clk IMX8MM_CLK_CSI1_CORE>, -- <&clk IMX8MM_CLK_CSI1_PHY_REF>; -- assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_1000M>, -- <&clk IMX8MM_SYS_PLL2_1000M>; -+ assigned-clocks = <&clk IMX8MM_CLK_CSI1_CORE>; -+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_1000M>; -+ - clock-frequency = <333000000>; - clocks = <&clk IMX8MM_CLK_DISP_APB_ROOT>, - <&clk IMX8MM_CLK_CSI1_ROOT>, -diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi -index 8ab9f8194702e..c2f60d41d6fd1 100644 ---- a/arch/arm64/boot/dts/freescale/imx93.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi -@@ -254,7 +254,7 @@ - - anatop: anatop@44480000 { - compatible = "fsl,imx93-anatop", "syscon"; -- reg = <0x44480000 0x10000>; -+ reg = <0x44480000 0x2000>; - }; - }; - -diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts -index bf8077a1cf9a7..9731a7c63d53b 100644 ---- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts -+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts -@@ -121,7 +121,7 @@ - }; - }; - -- pm8150l-thermal { -+ pm8150l-pcb-thermal { - polling-delay-passive = <0>; - polling-delay = <0>; - thermal-sensors = <&pm8150l_adc_tm 1>; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts -index f9884902f8745..c3f53aa1ea4ac 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts -@@ -548,9 +548,8 @@ - &sdhci { - max-frequency = <150000000>; - bus-width = <8>; -- mmc-hs400-1_8v; -+ mmc-hs200-1_8v; - non-removable; -- mmc-hs400-enhanced-strobe; - status = "okay"; - }; - -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -index 1f76d3501bda3..9bdc0b93001f4 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -@@ -45,7 +45,7 @@ - sdio_pwrseq: sdio-pwrseq { - compatible = "mmc-pwrseq-simple"; - clocks = <&rk808 1>; -- clock-names = "ext_clock"; -+ clock-names = "lpo"; - pinctrl-names = "default"; - pinctrl-0 = <&wifi_enable_h>; - reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; -@@ -645,9 +645,9 @@ - }; - - &sdhci { -+ max-frequency = <150000000>; - bus-width = <8>; -- mmc-hs400-1_8v; -- mmc-hs400-enhanced-strobe; -+ mmc-hs200-1_8v; - non-removable; - status = "okay"; - }; -diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h -index 6f86b7ab6c28f..d720b6f7e5f9c 100644 ---- a/arch/arm64/include/asm/fpsimd.h -+++ b/arch/arm64/include/asm/fpsimd.h -@@ -339,7 +339,7 @@ static inline int sme_max_virtualisable_vl(void) - return vec_max_virtualisable_vl(ARM64_VEC_SME); - } - --extern void sme_alloc(struct task_struct *task); -+extern void sme_alloc(struct task_struct *task, bool flush); - extern unsigned int sme_get_vl(void); - extern int sme_set_current_vl(unsigned long arg); - extern int sme_get_current_vl(void); -@@ -365,7 +365,7 @@ static inline void sme_smstart_sm(void) { } - static inline void sme_smstop_sm(void) { } - static inline void sme_smstop(void) { } - --static inline void sme_alloc(struct task_struct *task) { } -+static inline void sme_alloc(struct task_struct *task, bool flush) { } - static inline void sme_setup(void) { } - static inline unsigned int sme_get_vl(void) { return 0; } - static inline int sme_max_vl(void) { return 0; } -diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h -index b5a8e8b3c691c..577cf444c1135 100644 ---- a/arch/arm64/include/asm/kvm_host.h -+++ b/arch/arm64/include/asm/kvm_host.h -@@ -559,6 +559,8 @@ struct kvm_vcpu_arch { - #define SYSREGS_ON_CPU __vcpu_single_flag(sflags, BIT(4)) - /* Software step state is Active-pending */ - #define DBG_SS_ACTIVE_PENDING __vcpu_single_flag(sflags, BIT(5)) -+/* WFI instruction trapped */ -+#define IN_WFI __vcpu_single_flag(sflags, BIT(7)) - - - /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */ -diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c -index 356036babd093..8cd59d387b90b 100644 ---- a/arch/arm64/kernel/fpsimd.c -+++ b/arch/arm64/kernel/fpsimd.c -@@ -1239,9 +1239,9 @@ void fpsimd_release_task(struct task_struct *dead_task) - * the interest of testability and predictability, the architecture - * guarantees that when ZA is enabled it will be zeroed. - */ --void sme_alloc(struct task_struct *task) -+void sme_alloc(struct task_struct *task, bool flush) - { -- if (task->thread.za_state) { -+ if (task->thread.za_state && flush) { - memset(task->thread.za_state, 0, za_state_size(task)); - return; - } -@@ -1460,7 +1460,7 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs) - } - - sve_alloc(current, false); -- sme_alloc(current); -+ sme_alloc(current, true); - if (!current->thread.sve_state || !current->thread.za_state) { - force_sig(SIGKILL); - return; -diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c -index f19f020ccff96..f606c942f514e 100644 ---- a/arch/arm64/kernel/ptrace.c -+++ b/arch/arm64/kernel/ptrace.c -@@ -886,6 +886,13 @@ static int sve_set_common(struct task_struct *target, - break; - case ARM64_VEC_SME: - target->thread.svcr |= SVCR_SM_MASK; -+ -+ /* -+ * Disable traps and ensure there is SME storage but -+ * preserve any currently set values in ZA/ZT. -+ */ -+ sme_alloc(target, false); -+ set_tsk_thread_flag(target, TIF_SME); - break; - default: - WARN_ON_ONCE(1); -@@ -1107,7 +1114,7 @@ static int za_set(struct task_struct *target, - } - - /* Allocate/reinit ZA storage */ -- sme_alloc(target); -+ sme_alloc(target, true); - if (!target->thread.za_state) { - ret = -ENOMEM; - goto out; -diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c -index 43adbfa5ead78..82f4572c8ddfc 100644 ---- a/arch/arm64/kernel/signal.c -+++ b/arch/arm64/kernel/signal.c -@@ -430,7 +430,7 @@ static int restore_za_context(struct user_ctxs *user) - fpsimd_flush_task_state(current); - /* From now, fpsimd_thread_switch() won't touch thread.sve_state */ - -- sme_alloc(current); -+ sme_alloc(current, true); - if (!current->thread.za_state) { - current->thread.svcr &= ~SVCR_ZA_MASK; - clear_thread_flag(TIF_SME); -diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c -index 35481d51aada8..6cc380a15eb76 100644 ---- a/arch/arm64/kvm/arm.c -+++ b/arch/arm64/kvm/arm.c -@@ -692,13 +692,15 @@ void kvm_vcpu_wfi(struct kvm_vcpu *vcpu) - */ - preempt_disable(); - kvm_vgic_vmcr_sync(vcpu); -- vgic_v4_put(vcpu, true); -+ vcpu_set_flag(vcpu, IN_WFI); -+ vgic_v4_put(vcpu); - preempt_enable(); - - kvm_vcpu_halt(vcpu); - vcpu_clear_flag(vcpu, IN_WFIT); - - preempt_disable(); -+ vcpu_clear_flag(vcpu, IN_WFI); - vgic_v4_load(vcpu); - preempt_enable(); - } -@@ -766,7 +768,7 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu) - if (kvm_check_request(KVM_REQ_RELOAD_GICv4, vcpu)) { - /* The distributor enable bits were changed */ - preempt_disable(); -- vgic_v4_put(vcpu, false); -+ vgic_v4_put(vcpu); - vgic_v4_load(vcpu); - preempt_enable(); - } -diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c -index f86c3007a319c..1f8eea53e982f 100644 ---- a/arch/arm64/kvm/vgic/vgic-v3.c -+++ b/arch/arm64/kvm/vgic/vgic-v3.c -@@ -742,7 +742,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu) - { - struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; - -- WARN_ON(vgic_v4_put(vcpu, false)); -+ WARN_ON(vgic_v4_put(vcpu)); - - vgic_v3_vmcr_sync(vcpu); - -diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c -index c1c28fe680ba3..339a55194b2c6 100644 ---- a/arch/arm64/kvm/vgic/vgic-v4.c -+++ b/arch/arm64/kvm/vgic/vgic-v4.c -@@ -336,14 +336,14 @@ void vgic_v4_teardown(struct kvm *kvm) - its_vm->vpes = NULL; - } - --int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db) -+int vgic_v4_put(struct kvm_vcpu *vcpu) - { - struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; - - if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident) - return 0; - -- return its_make_vpe_non_resident(vpe, need_db); -+ return its_make_vpe_non_resident(vpe, !!vcpu_get_flag(vcpu, IN_WFI)); - } - - int vgic_v4_load(struct kvm_vcpu *vcpu) -@@ -354,6 +354,9 @@ int vgic_v4_load(struct kvm_vcpu *vcpu) - if (!vgic_supports_direct_msis(vcpu->kvm) || vpe->resident) - return 0; - -+ if (vcpu_get_flag(vcpu, IN_WFI)) -+ return 0; -+ - /* - * Before making the VPE resident, make sure the redistributor - * corresponding to our current CPU expects us here. See the -diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c -index bc817a5619d64..43c635ddba709 100644 ---- a/arch/powerpc/kernel/rtas_flash.c -+++ b/arch/powerpc/kernel/rtas_flash.c -@@ -710,9 +710,9 @@ static int __init rtas_flash_init(void) - if (!rtas_validate_flash_data.buf) - return -ENOMEM; - -- flash_block_cache = kmem_cache_create("rtas_flash_cache", -- RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, -- NULL); -+ flash_block_cache = kmem_cache_create_usercopy("rtas_flash_cache", -+ RTAS_BLK_SIZE, RTAS_BLK_SIZE, -+ 0, 0, RTAS_BLK_SIZE, NULL); - if (!flash_block_cache) { - printk(KERN_ERR "%s: failed to create block cache\n", - __func__); -diff --git a/arch/powerpc/mm/kasan/Makefile b/arch/powerpc/mm/kasan/Makefile -index 699eeffd9f551..f9522fd70b2f3 100644 ---- a/arch/powerpc/mm/kasan/Makefile -+++ b/arch/powerpc/mm/kasan/Makefile -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - - KASAN_SANITIZE := n -+KCOV_INSTRUMENT := n - - obj-$(CONFIG_PPC32) += init_32.o - obj-$(CONFIG_PPC_8xx) += 8xx.o -diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S -index ec486e5369d9b..09b47ebacf2e8 100644 ---- a/arch/riscv/lib/uaccess.S -+++ b/arch/riscv/lib/uaccess.S -@@ -17,8 +17,11 @@ ENTRY(__asm_copy_from_user) - li t6, SR_SUM - csrs CSR_STATUS, t6 - -- /* Save for return value */ -- mv t5, a2 -+ /* -+ * Save the terminal address which will be used to compute the number -+ * of bytes copied in case of a fixup exception. -+ */ -+ add t5, a0, a2 - - /* - * Register allocation for code below: -@@ -176,7 +179,7 @@ ENTRY(__asm_copy_from_user) - 10: - /* Disable access to user memory */ - csrc CSR_STATUS, t6 -- mv a0, t5 -+ sub a0, t5, a0 - ret - ENDPROC(__asm_copy_to_user) - ENDPROC(__asm_copy_from_user) -@@ -228,7 +231,7 @@ ENTRY(__clear_user) - 11: - /* Disable access to user memory */ - csrc CSR_STATUS, t6 -- mv a0, a1 -+ sub a0, a3, a0 - ret - ENDPROC(__clear_user) - EXPORT_SYMBOL(__clear_user) -diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c -index ad9844c5b40cb..e6468eab2681e 100644 ---- a/block/blk-crypto-fallback.c -+++ b/block/blk-crypto-fallback.c -@@ -78,7 +78,7 @@ static struct blk_crypto_fallback_keyslot { - struct crypto_skcipher *tfms[BLK_ENCRYPTION_MODE_MAX]; - } *blk_crypto_keyslots; - --static struct blk_crypto_profile blk_crypto_fallback_profile; -+static struct blk_crypto_profile *blk_crypto_fallback_profile; - static struct workqueue_struct *blk_crypto_wq; - static mempool_t *blk_crypto_bounce_page_pool; - static struct bio_set crypto_bio_split; -@@ -292,7 +292,7 @@ static bool blk_crypto_fallback_encrypt_bio(struct bio **bio_ptr) - * Get a blk-crypto-fallback keyslot that contains a crypto_skcipher for - * this bio's algorithm and key. - */ -- blk_st = blk_crypto_get_keyslot(&blk_crypto_fallback_profile, -+ blk_st = blk_crypto_get_keyslot(blk_crypto_fallback_profile, - bc->bc_key, &slot); - if (blk_st != BLK_STS_OK) { - src_bio->bi_status = blk_st; -@@ -395,7 +395,7 @@ static void blk_crypto_fallback_decrypt_bio(struct work_struct *work) - * Get a blk-crypto-fallback keyslot that contains a crypto_skcipher for - * this bio's algorithm and key. - */ -- blk_st = blk_crypto_get_keyslot(&blk_crypto_fallback_profile, -+ blk_st = blk_crypto_get_keyslot(blk_crypto_fallback_profile, - bc->bc_key, &slot); - if (blk_st != BLK_STS_OK) { - bio->bi_status = blk_st; -@@ -499,7 +499,7 @@ bool blk_crypto_fallback_bio_prep(struct bio **bio_ptr) - return false; - } - -- if (!__blk_crypto_cfg_supported(&blk_crypto_fallback_profile, -+ if (!__blk_crypto_cfg_supported(blk_crypto_fallback_profile, - &bc->bc_key->crypto_cfg)) { - bio->bi_status = BLK_STS_NOTSUPP; - return false; -@@ -526,7 +526,7 @@ bool blk_crypto_fallback_bio_prep(struct bio **bio_ptr) - - int blk_crypto_fallback_evict_key(const struct blk_crypto_key *key) - { -- return __blk_crypto_evict_key(&blk_crypto_fallback_profile, key); -+ return __blk_crypto_evict_key(blk_crypto_fallback_profile, key); - } - - static bool blk_crypto_fallback_inited; -@@ -534,7 +534,6 @@ static int blk_crypto_fallback_init(void) - { - int i; - int err; -- struct blk_crypto_profile *profile = &blk_crypto_fallback_profile; - - if (blk_crypto_fallback_inited) - return 0; -@@ -545,18 +544,27 @@ static int blk_crypto_fallback_init(void) - if (err) - goto out; - -- err = blk_crypto_profile_init(profile, blk_crypto_num_keyslots); -- if (err) -+ /* Dynamic allocation is needed because of lockdep_register_key(). */ -+ blk_crypto_fallback_profile = -+ kzalloc(sizeof(*blk_crypto_fallback_profile), GFP_KERNEL); -+ if (!blk_crypto_fallback_profile) { -+ err = -ENOMEM; - goto fail_free_bioset; -+ } -+ -+ err = blk_crypto_profile_init(blk_crypto_fallback_profile, -+ blk_crypto_num_keyslots); -+ if (err) -+ goto fail_free_profile; - err = -ENOMEM; - -- profile->ll_ops = blk_crypto_fallback_ll_ops; -- profile->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE; -+ blk_crypto_fallback_profile->ll_ops = blk_crypto_fallback_ll_ops; -+ blk_crypto_fallback_profile->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE; - - /* All blk-crypto modes have a crypto API fallback. */ - for (i = 0; i < BLK_ENCRYPTION_MODE_MAX; i++) -- profile->modes_supported[i] = 0xFFFFFFFF; -- profile->modes_supported[BLK_ENCRYPTION_MODE_INVALID] = 0; -+ blk_crypto_fallback_profile->modes_supported[i] = 0xFFFFFFFF; -+ blk_crypto_fallback_profile->modes_supported[BLK_ENCRYPTION_MODE_INVALID] = 0; - - blk_crypto_wq = alloc_workqueue("blk_crypto_wq", - WQ_UNBOUND | WQ_HIGHPRI | -@@ -597,7 +605,9 @@ fail_free_keyslots: - fail_free_wq: - destroy_workqueue(blk_crypto_wq); - fail_destroy_profile: -- blk_crypto_profile_destroy(profile); -+ blk_crypto_profile_destroy(blk_crypto_fallback_profile); -+fail_free_profile: -+ kfree(blk_crypto_fallback_profile); - fail_free_bioset: - bioset_exit(&crypto_bio_split); - out: -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index faad19b396d50..d6f405763c56f 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -600,6 +600,9 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x0489, 0xe0f5), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - { USB_DEVICE(0x13d3, 0x3568), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c -index cae078bffc715..9b7268bae66ab 100644 ---- a/drivers/bus/ti-sysc.c -+++ b/drivers/bus/ti-sysc.c -@@ -2159,6 +2159,8 @@ static int sysc_reset(struct sysc *ddata) - sysc_val = sysc_read_sysconfig(ddata); - sysc_val |= sysc_mask; - sysc_write(ddata, sysc_offset, sysc_val); -+ /* Flush posted write */ -+ sysc_val = sysc_read_sysconfig(ddata); - } - - if (ddata->cfg.srst_udelay) -diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c -index fe06644725203..f5d4359555d77 100644 ---- a/drivers/cpuidle/cpuidle-psci-domain.c -+++ b/drivers/cpuidle/cpuidle-psci-domain.c -@@ -117,20 +117,6 @@ static void psci_pd_remove(void) - } - } - --static bool psci_pd_try_set_osi_mode(void) --{ -- int ret; -- -- if (!psci_has_osi_support()) -- return false; -- -- ret = psci_set_osi_mode(true); -- if (ret) -- return false; -- -- return true; --} -- - static void psci_cpuidle_domain_sync_state(struct device *dev) - { - /* -@@ -149,15 +135,12 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev) - { - struct device_node *np = pdev->dev.of_node; - struct device_node *node; -- bool use_osi; -+ bool use_osi = psci_has_osi_support(); - int ret = 0, pd_count = 0; - - if (!np) - return -ENODEV; - -- /* If OSI mode is supported, let's try to enable it. */ -- use_osi = psci_pd_try_set_osi_mode(); -- - /* - * Parse child nodes for the "#power-domain-cells" property and - * initialize a genpd/genpd-of-provider pair when it's found. -@@ -167,32 +150,37 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev) - continue; - - ret = psci_pd_init(node, use_osi); -- if (ret) -- goto put_node; -+ if (ret) { -+ of_node_put(node); -+ goto exit; -+ } - - pd_count++; - } - - /* Bail out if not using the hierarchical CPU topology. */ - if (!pd_count) -- goto no_pd; -+ return 0; - - /* Link genpd masters/subdomains to model the CPU topology. */ - ret = dt_idle_pd_init_topology(np); - if (ret) - goto remove_pd; - -- pr_info("Initialized CPU PM domain topology\n"); -+ /* let's try to enable OSI. */ -+ ret = psci_set_osi_mode(use_osi); -+ if (ret) -+ goto remove_pd; -+ -+ pr_info("Initialized CPU PM domain topology using %s mode\n", -+ use_osi ? "OSI" : "PC"); - return 0; - --put_node: -- of_node_put(node); - remove_pd: -+ dt_idle_pd_remove_topology(np); - psci_pd_remove(); -+exit: - pr_err("failed to create CPU PM domains ret=%d\n", ret); --no_pd: -- if (use_osi) -- psci_set_osi_mode(false); - return ret; - } - -diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c -index af22be84034bb..a53eacebca339 100644 ---- a/drivers/firewire/net.c -+++ b/drivers/firewire/net.c -@@ -479,7 +479,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, - struct sk_buff *skb, u16 source_node_id, - bool is_broadcast, u16 ether_type) - { -- int status; -+ int status, len; - - switch (ether_type) { - case ETH_P_ARP: -@@ -533,13 +533,15 @@ static int fwnet_finish_incoming_packet(struct net_device *net, - } - skb->protocol = protocol; - } -+ -+ len = skb->len; - status = netif_rx(skb); - if (status == NET_RX_DROP) { - net->stats.rx_errors++; - net->stats.rx_dropped++; - } else { - net->stats.rx_packets++; -- net->stats.rx_bytes += skb->len; -+ net->stats.rx_bytes += len; - } - - return 0; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -index fdb53d4394f30..02a112d00d413 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -@@ -185,7 +185,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, - uint64_t *chunk_array_user; - uint64_t *chunk_array; - uint32_t uf_offset = 0; -- unsigned int size; -+ size_t size; - int ret; - int i; - -@@ -1607,15 +1607,15 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev, - continue; - - r = dma_fence_wait_timeout(fence, true, timeout); -+ if (r > 0 && fence->error) -+ r = fence->error; -+ - dma_fence_put(fence); - if (r < 0) - return r; - - if (r == 0) - break; -- -- if (fence->error) -- return fence->error; - } - - memset(wait, 0, sizeof(*wait)); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index 773383e660e8c..e6427a00cf6d6 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -4232,6 +4232,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) - drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); - - cancel_delayed_work_sync(&adev->delayed_init_work); -+ flush_delayed_work(&adev->gfx.gfx_off_delay_work); - - amdgpu_ras_suspend(adev); - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c -index ed6878d5b3ce3..418e4c77ceb80 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c -@@ -501,6 +501,41 @@ int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev) - return 0; - } - -+/** -+ * amdgpu_fence_need_ring_interrupt_restore - helper function to check whether -+ * fence driver interrupts need to be restored. -+ * -+ * @ring: ring that to be checked -+ * -+ * Interrupts for rings that belong to GFX IP don't need to be restored -+ * when the target power state is s0ix. -+ * -+ * Return true if need to restore interrupts, false otherwise. -+ */ -+static bool amdgpu_fence_need_ring_interrupt_restore(struct amdgpu_ring *ring) -+{ -+ struct amdgpu_device *adev = ring->adev; -+ bool is_gfx_power_domain = false; -+ -+ switch (ring->funcs->type) { -+ case AMDGPU_RING_TYPE_SDMA: -+ /* SDMA 5.x+ is part of GFX power domain so it's covered by GFXOFF */ -+ if (adev->ip_versions[SDMA0_HWIP][0] >= IP_VERSION(5, 0, 0)) -+ is_gfx_power_domain = true; -+ break; -+ case AMDGPU_RING_TYPE_GFX: -+ case AMDGPU_RING_TYPE_COMPUTE: -+ case AMDGPU_RING_TYPE_KIQ: -+ case AMDGPU_RING_TYPE_MES: -+ is_gfx_power_domain = true; -+ break; -+ default: -+ break; -+ } -+ -+ return !(adev->in_s0ix && is_gfx_power_domain); -+} -+ - /** - * amdgpu_fence_driver_hw_fini - tear down the fence driver - * for all possible rings. -@@ -529,7 +564,8 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev) - amdgpu_fence_driver_force_completion(ring); - - if (!drm_dev_is_unplugged(adev_to_drm(adev)) && -- ring->fence_drv.irq_src) -+ ring->fence_drv.irq_src && -+ amdgpu_fence_need_ring_interrupt_restore(ring)) - amdgpu_irq_put(adev, ring->fence_drv.irq_src, - ring->fence_drv.irq_type); - -@@ -604,7 +640,8 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev) - continue; - - /* enable the interrupt */ -- if (ring->fence_drv.irq_src) -+ if (ring->fence_drv.irq_src && -+ amdgpu_fence_need_ring_interrupt_restore(ring)) - amdgpu_irq_get(adev, ring->fence_drv.irq_src, - ring->fence_drv.irq_type); - } -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -index b803e785d3aff..23f0067f92e4e 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c -@@ -585,15 +585,8 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) - - if (adev->gfx.gfx_off_req_count == 0 && - !adev->gfx.gfx_off_state) { -- /* If going to s2idle, no need to wait */ -- if (adev->in_s0ix) { -- if (!amdgpu_dpm_set_powergating_by_smu(adev, -- AMD_IP_BLOCK_TYPE_GFX, true)) -- adev->gfx.gfx_off_state = true; -- } else { -- schedule_delayed_work(&adev->gfx.gfx_off_delay_work, -+ schedule_delayed_work(&adev->gfx.gfx_off_delay_work, - delay); -- } - } - } else { - if (adev->gfx.gfx_off_req_count == 0) { -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c -index ca5dc51600fac..9efbc0f7c6bdf 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c -@@ -160,7 +160,6 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev) - continue; - - for (k = 0; k < src->num_types; ++k) { -- atomic_set(&src->enabled_types[k], 0); - r = src->funcs->set(adev, src, k, - AMDGPU_IRQ_STATE_DISABLE); - if (r) -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c -index eecbd8eeb1f5a..8764ff7ed97e0 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c -@@ -514,6 +514,8 @@ static int psp_sw_fini(void *handle) - kfree(cmd); - cmd = NULL; - -+ psp_free_shared_bufs(psp); -+ - if (psp->km_ring.ring_mem) - amdgpu_bo_free_kernel(&adev->firmware.rbuf, - &psp->km_ring.ring_mem_mc_addr, -@@ -2673,8 +2675,6 @@ static int psp_hw_fini(void *handle) - - psp_ring_destroy(psp, PSP_RING_TYPE__KM); - -- psp_free_shared_bufs(psp); -- - return 0; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c -index d3558c34d406c..296b2d5976af7 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c -@@ -361,6 +361,8 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) - amdgpu_bo_free_kernel(&ring->ring_obj, - &ring->gpu_addr, - (void **)&ring->ring); -+ } else { -+ kfree(ring->fence_drv.fences); - } - - dma_fence_put(ring->vmid_wait); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c -index ec938a1a50621..4c661e024e13d 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c -@@ -1352,6 +1352,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, - amdgpu_vm_bo_base_init(&bo_va->base, vm, bo); - - bo_va->ref_count = 1; -+ bo_va->last_pt_update = dma_fence_get_stub(); - INIT_LIST_HEAD(&bo_va->valids); - INIT_LIST_HEAD(&bo_va->invalids); - -@@ -2073,7 +2074,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) - vm->update_funcs = &amdgpu_vm_cpu_funcs; - else - vm->update_funcs = &amdgpu_vm_sdma_funcs; -- vm->last_update = NULL; -+ -+ vm->last_update = dma_fence_get_stub(); - vm->last_unlocked = dma_fence_get_stub(); - vm->last_tlb_flush = dma_fence_get_stub(); - -@@ -2198,7 +2200,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm) - goto unreserve_bo; - - dma_fence_put(vm->last_update); -- vm->last_update = NULL; -+ vm->last_update = dma_fence_get_stub(); - vm->is_compute_context = true; - - /* Free the shadow bo for compute VM */ -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 9f718b98da1f7..249b269e2cc53 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -7397,27 +7397,55 @@ is_scaling_state_different(const struct dm_connector_state *dm_state, - } - - #ifdef CONFIG_DRM_AMD_DC_HDCP --static bool is_content_protection_different(struct drm_connector_state *state, -- const struct drm_connector_state *old_state, -- const struct drm_connector *connector, struct hdcp_workqueue *hdcp_w) -+static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state, -+ struct drm_crtc_state *old_crtc_state, -+ struct drm_connector_state *new_conn_state, -+ struct drm_connector_state *old_conn_state, -+ const struct drm_connector *connector, -+ struct hdcp_workqueue *hdcp_w) - { - struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); - struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state); - -- /* Handle: Type0/1 change */ -- if (old_state->hdcp_content_type != state->hdcp_content_type && -- state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { -- state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; -+ pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n", -+ connector->index, connector->status, connector->dpms); -+ pr_debug("[HDCP_DM] state protection old: %x new: %x\n", -+ old_conn_state->content_protection, new_conn_state->content_protection); -+ -+ if (old_crtc_state) -+ pr_debug("[HDCP_DM] old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", -+ old_crtc_state->enable, -+ old_crtc_state->active, -+ old_crtc_state->mode_changed, -+ old_crtc_state->active_changed, -+ old_crtc_state->connectors_changed); -+ -+ if (new_crtc_state) -+ pr_debug("[HDCP_DM] NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", -+ new_crtc_state->enable, -+ new_crtc_state->active, -+ new_crtc_state->mode_changed, -+ new_crtc_state->active_changed, -+ new_crtc_state->connectors_changed); -+ -+ /* hdcp content type change */ -+ if (old_conn_state->hdcp_content_type != new_conn_state->hdcp_content_type && -+ new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) { -+ new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; -+ pr_debug("[HDCP_DM] Type0/1 change %s :true\n", __func__); - return true; - } - -- /* CP is being re enabled, ignore this -- * -- * Handles: ENABLED -> DESIRED -- */ -- if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED && -- state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { -- state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED; -+ /* CP is being re enabled, ignore this */ -+ if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED && -+ new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { -+ if (new_crtc_state && new_crtc_state->mode_changed) { -+ new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; -+ pr_debug("[HDCP_DM] ENABLED->DESIRED & mode_changed %s :true\n", __func__); -+ return true; -+ }; -+ new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED; -+ pr_debug("[HDCP_DM] ENABLED -> DESIRED %s :false\n", __func__); - return false; - } - -@@ -7425,9 +7453,9 @@ static bool is_content_protection_different(struct drm_connector_state *state, - * - * Handles: UNDESIRED -> ENABLED - */ -- if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED && -- state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) -- state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; -+ if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED && -+ new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) -+ new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; - - /* Stream removed and re-enabled - * -@@ -7437,10 +7465,12 @@ static bool is_content_protection_different(struct drm_connector_state *state, - * - * Handles: DESIRED -> DESIRED (Special case) - */ -- if (!(old_state->crtc && old_state->crtc->enabled) && -- state->crtc && state->crtc->enabled && -+ if (!(old_conn_state->crtc && old_conn_state->crtc->enabled) && -+ new_conn_state->crtc && new_conn_state->crtc->enabled && - connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) { - dm_con_state->update_hdcp = false; -+ pr_debug("[HDCP_DM] DESIRED->DESIRED (Stream removed and re-enabled) %s :true\n", -+ __func__); - return true; - } - -@@ -7452,35 +7482,42 @@ static bool is_content_protection_different(struct drm_connector_state *state, - * - * Handles: DESIRED -> DESIRED (Special case) - */ -- if (dm_con_state->update_hdcp && state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && -- connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) { -+ if (dm_con_state->update_hdcp && -+ new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED && -+ connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) { - dm_con_state->update_hdcp = false; -+ pr_debug("[HDCP_DM] DESIRED->DESIRED (Hot-plug, headless s3, dpms) %s :true\n", -+ __func__); - return true; - } - -- /* -- * Handles: UNDESIRED -> UNDESIRED -- * DESIRED -> DESIRED -- * ENABLED -> ENABLED -- */ -- if (old_state->content_protection == state->content_protection) -+ if (old_conn_state->content_protection == new_conn_state->content_protection) { -+ if (new_conn_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) { -+ if (new_crtc_state && new_crtc_state->mode_changed) { -+ pr_debug("[HDCP_DM] DESIRED->DESIRED or ENABLE->ENABLE mode_change %s :true\n", -+ __func__); -+ return true; -+ }; -+ pr_debug("[HDCP_DM] DESIRED->DESIRED & ENABLE->ENABLE %s :false\n", -+ __func__); -+ return false; -+ }; -+ -+ pr_debug("[HDCP_DM] UNDESIRED->UNDESIRED %s :false\n", __func__); - return false; -+ } - -- /* -- * Handles: UNDESIRED -> DESIRED -- * DESIRED -> UNDESIRED -- * ENABLED -> UNDESIRED -- */ -- if (state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) -+ if (new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) { -+ pr_debug("[HDCP_DM] UNDESIRED->DESIRED or DESIRED->UNDESIRED or ENABLED->UNDESIRED %s :true\n", -+ __func__); - return true; -+ } - -- /* -- * Handles: DESIRED -> ENABLED -- */ -+ pr_debug("[HDCP_DM] DESIRED->ENABLED %s :false\n", __func__); - return false; - } -- - #endif -+ - static void remove_stream(struct amdgpu_device *adev, - struct amdgpu_crtc *acrtc, - struct dc_stream_state *stream) -@@ -8335,10 +8372,67 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) - struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); - struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); - -+ if (!adev->dm.hdcp_workqueue) -+ continue; -+ -+ pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i); -+ -+ if (!connector) -+ continue; -+ -+ pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n", -+ connector->index, connector->status, connector->dpms); -+ pr_debug("[HDCP_DM] state protection old: %x new: %x\n", -+ old_con_state->content_protection, new_con_state->content_protection); -+ -+ if (aconnector->dc_sink) { -+ if (aconnector->dc_sink->sink_signal != SIGNAL_TYPE_VIRTUAL && -+ aconnector->dc_sink->sink_signal != SIGNAL_TYPE_NONE) { -+ pr_debug("[HDCP_DM] pipe_ctx dispname=%s\n", -+ aconnector->dc_sink->edid_caps.display_name); -+ } -+ } -+ - new_crtc_state = NULL; -+ old_crtc_state = NULL; - -- if (acrtc) -+ if (acrtc) { - new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); -+ old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); -+ } -+ -+ if (old_crtc_state) -+ pr_debug("old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", -+ old_crtc_state->enable, -+ old_crtc_state->active, -+ old_crtc_state->mode_changed, -+ old_crtc_state->active_changed, -+ old_crtc_state->connectors_changed); -+ -+ if (new_crtc_state) -+ pr_debug("NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n", -+ new_crtc_state->enable, -+ new_crtc_state->active, -+ new_crtc_state->mode_changed, -+ new_crtc_state->active_changed, -+ new_crtc_state->connectors_changed); -+ } -+ -+ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { -+ struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); -+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); -+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); -+ -+ if (!adev->dm.hdcp_workqueue) -+ continue; -+ -+ new_crtc_state = NULL; -+ old_crtc_state = NULL; -+ -+ if (acrtc) { -+ new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base); -+ old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base); -+ } - - dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); - -@@ -8350,11 +8444,44 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) - continue; - } - -- if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue)) -+ if (is_content_protection_different(new_crtc_state, old_crtc_state, new_con_state, -+ old_con_state, connector, adev->dm.hdcp_workqueue)) { -+ /* when display is unplugged from mst hub, connctor will -+ * be destroyed within dm_dp_mst_connector_destroy. connector -+ * hdcp perperties, like type, undesired, desired, enabled, -+ * will be lost. So, save hdcp properties into hdcp_work within -+ * amdgpu_dm_atomic_commit_tail. if the same display is -+ * plugged back with same display index, its hdcp properties -+ * will be retrieved from hdcp_work within dm_dp_mst_get_modes -+ */ -+ -+ bool enable_encryption = false; -+ -+ if (new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) -+ enable_encryption = true; -+ -+ if (aconnector->dc_link && aconnector->dc_sink && -+ aconnector->dc_link->type == dc_connection_mst_branch) { -+ struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue; -+ struct hdcp_workqueue *hdcp_w = -+ &hdcp_work[aconnector->dc_link->link_index]; -+ -+ hdcp_w->hdcp_content_type[connector->index] = -+ new_con_state->hdcp_content_type; -+ hdcp_w->content_protection[connector->index] = -+ new_con_state->content_protection; -+ } -+ -+ if (new_crtc_state && new_crtc_state->mode_changed && -+ new_con_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) -+ enable_encryption = true; -+ -+ DRM_INFO("[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption); -+ - hdcp_update_display( - adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector, -- new_con_state->hdcp_content_type, -- new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED); -+ new_con_state->hdcp_content_type, enable_encryption); -+ } - } - #endif - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h -index 09294ff122fea..bbbf7d0eff82f 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h -@@ -52,6 +52,20 @@ struct hdcp_workqueue { - struct mod_hdcp_link link; - - enum mod_hdcp_encryption_status encryption_status; -+ -+ /* when display is unplugged from mst hub, connctor will be -+ * destroyed within dm_dp_mst_connector_destroy. connector -+ * hdcp perperties, like type, undesired, desired, enabled, -+ * will be lost. So, save hdcp properties into hdcp_work within -+ * amdgpu_dm_atomic_commit_tail. if the same display is -+ * plugged back with same display index, its hdcp properties -+ * will be retrieved from hdcp_work within dm_dp_mst_get_modes -+ */ -+ /* un-desired, desired, enabled */ -+ unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_INDEX]; -+ /* hdcp1.x, hdcp2.x */ -+ unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_INDEX]; -+ - uint8_t max_link; - - uint8_t *srm; -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -index d07e1053b36b3..a9ddff774a978 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -@@ -32,6 +32,10 @@ - #include "amdgpu_dm.h" - #include "amdgpu_dm_mst_types.h" - -+#ifdef CONFIG_DRM_AMD_DC_HDCP -+#include "amdgpu_dm_hdcp.h" -+#endif -+ - #include "dc.h" - #include "dm_helpers.h" - -@@ -363,6 +367,32 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) - /* dc_link_add_remote_sink returns a new reference */ - aconnector->dc_sink = dc_sink; - -+ /* when display is unplugged from mst hub, connctor will be -+ * destroyed within dm_dp_mst_connector_destroy. connector -+ * hdcp perperties, like type, undesired, desired, enabled, -+ * will be lost. So, save hdcp properties into hdcp_work within -+ * amdgpu_dm_atomic_commit_tail. if the same display is -+ * plugged back with same display index, its hdcp properties -+ * will be retrieved from hdcp_work within dm_dp_mst_get_modes -+ */ -+#ifdef CONFIG_DRM_AMD_DC_HDCP -+ if (aconnector->dc_sink && connector->state) { -+ struct drm_device *dev = connector->dev; -+ struct amdgpu_device *adev = drm_to_adev(dev); -+ -+ if (adev->dm.hdcp_workqueue) { -+ struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue; -+ struct hdcp_workqueue *hdcp_w = -+ &hdcp_work[aconnector->dc_link->link_index]; -+ -+ connector->state->hdcp_content_type = -+ hdcp_w->hdcp_content_type[connector->index]; -+ connector->state->content_protection = -+ hdcp_w->content_protection[connector->index]; -+ } -+ } -+#endif -+ - if (aconnector->dc_sink) { - amdgpu_dm_update_freesync_caps( - connector, aconnector->edid); -diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h -index 915a20461c77c..893c0809cd4e0 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h -@@ -230,7 +230,8 @@ - type DTBCLK_P2_SRC_SEL;\ - type DTBCLK_P2_EN;\ - type DTBCLK_P3_SRC_SEL;\ -- type DTBCLK_P3_EN; -+ type DTBCLK_P3_EN;\ -+ type DENTIST_DISPCLK_CHG_DONE; - - struct dccg_shift { - DCCG_REG_FIELD_LIST(uint8_t) -diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c -index 7d2b982506fd7..cef32a1f91cdc 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c -@@ -47,6 +47,14 @@ void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) - { - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - -+ if (dccg->dpp_clock_gated[dpp_inst]) { -+ /* -+ * Do not update the DPPCLK DTO if the clock is stopped. -+ * It is treated the same as if the pipe itself were in PG. -+ */ -+ return; -+ } -+ - if (dccg->ref_dppclk && req_dppclk) { - int ref_dppclk = dccg->ref_dppclk; - int modulo, phase; -diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c -index 85ea3334355c2..b74705c1c8dcc 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c -@@ -296,6 +296,9 @@ static void dccg314_dpp_root_clock_control( - { - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - -+ if (dccg->dpp_clock_gated[dpp_inst] != clock_on) -+ return; -+ - if (clock_on) { - /* turn off the DTO and leave phase/modulo at max */ - REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 0); -@@ -309,6 +312,8 @@ static void dccg314_dpp_root_clock_control( - DPPCLK0_DTO_PHASE, 0, - DPPCLK0_DTO_MODULO, 1); - } -+ -+ dccg->dpp_clock_gated[dpp_inst] = !clock_on; - } - - static const struct dccg_funcs dccg314_funcs = { -diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c -index b7782433ce6ba..503ab45b4ace3 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c -@@ -920,6 +920,22 @@ static const struct dc_debug_options debug_defaults_drv = { - .afmt = true, - } - }, -+ -+ .root_clock_optimization = { -+ .bits = { -+ .dpp = true, -+ .dsc = false, -+ .hdmistream = false, -+ .hdmichar = false, -+ .dpstream = false, -+ .symclk32_se = false, -+ .symclk32_le = false, -+ .symclk_fe = false, -+ .physymclk = false, -+ .dpiasymclk = false, -+ } -+ }, -+ - .seamless_boot_odm_combine = true - }; - -@@ -1917,6 +1933,10 @@ static bool dcn314_resource_construct( - dc->debug = debug_defaults_drv; - else - dc->debug = debug_defaults_diags; -+ -+ /* Disable root clock optimization */ -+ dc->debug.root_clock_optimization.u32All = 0; -+ - // Init the vm_helper - if (dc->vm_helper) - vm_helper_init(dc->vm_helper, 16); -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c -index 3fb4bcc343531..ffbb739d85b69 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c -@@ -42,6 +42,20 @@ - #define DC_LOGGER \ - dccg->ctx->logger - -+/* This function is a workaround for writing to OTG_PIXEL_RATE_DIV -+ * without the probability of causing a DIG FIFO error. -+ */ -+static void dccg32_wait_for_dentist_change_done( -+ struct dccg *dccg) -+{ -+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); -+ -+ uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL); -+ -+ REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value); -+ REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000); -+} -+ - static void dccg32_get_pixel_rate_div( - struct dccg *dccg, - uint32_t otg_inst, -@@ -110,21 +124,29 @@ static void dccg32_set_pixel_rate_div( - REG_UPDATE_2(OTG_PIXEL_RATE_DIV, - OTG0_PIXEL_RATE_DIVK1, k1, - OTG0_PIXEL_RATE_DIVK2, k2); -+ -+ dccg32_wait_for_dentist_change_done(dccg); - break; - case 1: - REG_UPDATE_2(OTG_PIXEL_RATE_DIV, - OTG1_PIXEL_RATE_DIVK1, k1, - OTG1_PIXEL_RATE_DIVK2, k2); -+ -+ dccg32_wait_for_dentist_change_done(dccg); - break; - case 2: - REG_UPDATE_2(OTG_PIXEL_RATE_DIV, - OTG2_PIXEL_RATE_DIVK1, k1, - OTG2_PIXEL_RATE_DIVK2, k2); -+ -+ dccg32_wait_for_dentist_change_done(dccg); - break; - case 3: - REG_UPDATE_2(OTG_PIXEL_RATE_DIV, - OTG3_PIXEL_RATE_DIVK1, k1, - OTG3_PIXEL_RATE_DIVK2, k2); -+ -+ dccg32_wait_for_dentist_change_done(dccg); - break; - default: - BREAK_TO_DEBUGGER(); -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h -index 1c46fad0977bf..fc3c9c650d43c 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.h -@@ -147,7 +147,8 @@ - DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_SRC_SEL, mask_sh),\ - DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_EN, mask_sh),\ - DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\ -- DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh) -+ DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\ -+ DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) - - - struct dccg *dccg32_create( -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -index f5fa7abd97fc7..d477dcc9149fa 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -@@ -1177,7 +1177,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign - *k2_div = PIXEL_RATE_DIV_BY_2; - else - *k2_div = PIXEL_RATE_DIV_BY_4; -- } else if (dc_is_dp_signal(stream->signal)) { -+ } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) { - if (two_pix_per_container) { - *k1_div = PIXEL_RATE_DIV_BY_1; - *k2_div = PIXEL_RATE_DIV_BY_2; -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h -index 026cf13d203fc..03cdfb5577888 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h -@@ -1272,7 +1272,8 @@ unsigned int dcn32_calc_num_avail_chans_for_mall(struct dc *dc, int num_chans); - DCCG_SRII(PHASE, DTBCLK_DTO, 0), DCCG_SRII(PHASE, DTBCLK_DTO, 1), \ - DCCG_SRII(PHASE, DTBCLK_DTO, 2), DCCG_SRII(PHASE, DTBCLK_DTO, 3), \ - SR(DCCG_AUDIO_DTBCLK_DTO_MODULO), SR(DCCG_AUDIO_DTBCLK_DTO_PHASE), \ -- SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), SR(DCCG_AUDIO_DTO_SOURCE) \ -+ SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), \ -+ SR(DCCG_AUDIO_DTO_SOURCE), SR(DENTIST_DISPCLK_CNTL) \ - ) - - /* VMID */ -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c -index 2bb768413c92a..19f55657272e4 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c -@@ -808,7 +808,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman - v->SwathHeightC[k], - TWait, - (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ || -- v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= MIN_DCFCLK_FREQ_MHZ) ? -+ v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? - mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, - /* Output */ - &v->DSTXAfterScaler[k], -@@ -3289,7 +3289,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l - v->swath_width_chroma_ub_this_state[k], - v->SwathHeightYThisState[k], - v->SwathHeightCThisState[k], v->TWait, -- (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= MIN_DCFCLK_FREQ_MHZ) ? -+ (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? - mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, - - /* Output */ -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h -index e92eee2c664d0..a475775bc3894 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h -@@ -52,7 +52,7 @@ - #define BPP_BLENDED_PIPE 0xffffffff - - #define MEM_STROBE_FREQ_MHZ 1600 --#define MIN_DCFCLK_FREQ_MHZ 200 -+#define DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ 300 - #define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0 - - struct display_mode_lib; -diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h -index ad6acd1b34e1d..9651cccb084a3 100644 ---- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h -+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h -@@ -68,6 +68,7 @@ struct dccg { - const struct dccg_funcs *funcs; - int pipe_dppclk_khz[MAX_PIPES]; - int ref_dppclk; -+ bool dpp_clock_gated[MAX_PIPES]; - //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */ - //int audio_dtbclk_khz;/* TODO needs to be removed */ - //int ref_dtbclk_khz;/* TODO needs to be removed */ -diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -index d191ff52d4f06..a664a0a284784 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -@@ -1562,9 +1562,9 @@ static int smu_disable_dpms(struct smu_context *smu) - - /* - * For SMU 13.0.4/11, PMFW will handle the features disablement properly -- * for gpu reset case. Driver involvement is unnecessary. -+ * for gpu reset and S0i3 cases. Driver involvement is unnecessary. - */ -- if (amdgpu_in_reset(adev)) { -+ if (amdgpu_in_reset(adev) || adev->in_s0ix) { - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(13, 0, 4): - case IP_VERSION(13, 0, 11): -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -index 31835d96deef9..839a812e0da32 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -@@ -588,7 +588,9 @@ err0_out: - return -ENOMEM; - } - --static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *smu) -+static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *smu, -+ bool use_metrics_v3, -+ bool use_metrics_v2) - { - struct smu_table_context *smu_table= &smu->smu_table; - SmuMetricsExternal_t *metrics_ext = -@@ -596,13 +598,11 @@ static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *s - uint32_t throttler_status = 0; - int i; - -- if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && -- (smu->smc_fw_version >= 0x3A4900)) { -+ if (use_metrics_v3) { - for (i = 0; i < THROTTLER_COUNT; i++) - throttler_status |= - (metrics_ext->SmuMetrics_V3.ThrottlingPercentage[i] ? 1U << i : 0); -- } else if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && -- (smu->smc_fw_version >= 0x3A4300)) { -+ } else if (use_metrics_v2) { - for (i = 0; i < THROTTLER_COUNT; i++) - throttler_status |= - (metrics_ext->SmuMetrics_V2.ThrottlingPercentage[i] ? 1U << i : 0); -@@ -864,7 +864,7 @@ static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu, - metrics->TemperatureVrSoc) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; - break; - case METRICS_THROTTLER_STATUS: -- *value = sienna_cichlid_get_throttler_status_locked(smu); -+ *value = sienna_cichlid_get_throttler_status_locked(smu, use_metrics_v3, use_metrics_v2); - break; - case METRICS_CURR_FANSPEED: - *value = use_metrics_v3 ? metrics_v3->CurrFanSpeed : -@@ -4017,7 +4017,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, - gpu_metrics->current_dclk1 = use_metrics_v3 ? metrics_v3->CurrClock[PPCLK_DCLK_1] : - use_metrics_v2 ? metrics_v2->CurrClock[PPCLK_DCLK_1] : metrics->CurrClock[PPCLK_DCLK_1]; - -- gpu_metrics->throttle_status = sienna_cichlid_get_throttler_status_locked(smu); -+ gpu_metrics->throttle_status = sienna_cichlid_get_throttler_status_locked(smu, use_metrics_v3, use_metrics_v2); - gpu_metrics->indep_throttle_status = - smu_cmn_get_indep_throttler_status(gpu_metrics->throttle_status, - sienna_cichlid_throttler_map); -diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c -index a15e09b551708..2c2e0f041f869 100644 ---- a/drivers/gpu/drm/i915/display/intel_sdvo.c -+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c -@@ -2727,7 +2727,7 @@ static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) - __drm_atomic_helper_connector_reset(&sdvo_connector->base.base, - &conn_state->base.base); - -- INIT_LIST_HEAD(&sdvo_connector->base.panel.fixed_modes); -+ intel_panel_init_alloc(&sdvo_connector->base); - - return sdvo_connector; - } -diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c -index 49c5451cdfb16..d6dd79541f6a9 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_connector.c -+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c -@@ -1407,8 +1407,7 @@ nouveau_connector_create(struct drm_device *dev, - ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index, - &nv_connector->conn); - if (ret) { -- kfree(nv_connector); -- return ERR_PTR(ret); -+ goto drm_conn_err; - } - } - -@@ -1470,4 +1469,9 @@ nouveau_connector_create(struct drm_device *dev, - - drm_connector_register(connector); - return connector; -+ -+drm_conn_err: -+ drm_connector_cleanup(connector); -+ kfree(nv_connector); -+ return ERR_PTR(ret); - } -diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c -index f851aaf2c5917..5e067ba7e5fba 100644 ---- a/drivers/gpu/drm/panel/panel-simple.c -+++ b/drivers/gpu/drm/panel/panel-simple.c -@@ -969,21 +969,21 @@ static const struct panel_desc auo_g104sn02 = { - .connector_type = DRM_MODE_CONNECTOR_LVDS, - }; - --static const struct drm_display_mode auo_g121ean01_mode = { -- .clock = 66700, -- .hdisplay = 1280, -- .hsync_start = 1280 + 58, -- .hsync_end = 1280 + 58 + 8, -- .htotal = 1280 + 58 + 8 + 70, -- .vdisplay = 800, -- .vsync_start = 800 + 6, -- .vsync_end = 800 + 6 + 4, -- .vtotal = 800 + 6 + 4 + 10, -+static const struct display_timing auo_g121ean01_timing = { -+ .pixelclock = { 60000000, 74400000, 90000000 }, -+ .hactive = { 1280, 1280, 1280 }, -+ .hfront_porch = { 20, 50, 100 }, -+ .hback_porch = { 20, 50, 100 }, -+ .hsync_len = { 30, 100, 200 }, -+ .vactive = { 800, 800, 800 }, -+ .vfront_porch = { 2, 10, 25 }, -+ .vback_porch = { 2, 10, 25 }, -+ .vsync_len = { 4, 18, 50 }, - }; - - static const struct panel_desc auo_g121ean01 = { -- .modes = &auo_g121ean01_mode, -- .num_modes = 1, -+ .timings = &auo_g121ean01_timing, -+ .num_timings = 1, - .bpc = 8, - .size = { - .width = 261, -diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h -index 432758ad39a35..94753e017ea8d 100644 ---- a/drivers/gpu/drm/qxl/qxl_drv.h -+++ b/drivers/gpu/drm/qxl/qxl_drv.h -@@ -312,7 +312,7 @@ int qxl_gem_object_create_with_handle(struct qxl_device *qdev, - u32 domain, - size_t size, - struct qxl_surface *surf, -- struct qxl_bo **qobj, -+ struct drm_gem_object **gobj, - uint32_t *handle); - void qxl_gem_object_free(struct drm_gem_object *gobj); - int qxl_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv); -diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c -index d636ba6854513..17df5c7ccf691 100644 ---- a/drivers/gpu/drm/qxl/qxl_dumb.c -+++ b/drivers/gpu/drm/qxl/qxl_dumb.c -@@ -34,6 +34,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, - { - struct qxl_device *qdev = to_qxl(dev); - struct qxl_bo *qobj; -+ struct drm_gem_object *gobj; - uint32_t handle; - int r; - struct qxl_surface surf; -@@ -62,11 +63,13 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, - - r = qxl_gem_object_create_with_handle(qdev, file_priv, - QXL_GEM_DOMAIN_CPU, -- args->size, &surf, &qobj, -+ args->size, &surf, &gobj, - &handle); - if (r) - return r; -+ qobj = gem_to_qxl_bo(gobj); - qobj->is_dumb = true; -+ drm_gem_object_put(gobj); - args->pitch = pitch; - args->handle = handle; - return 0; -diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c -index a08da0bd9098b..fc5e3763c3595 100644 ---- a/drivers/gpu/drm/qxl/qxl_gem.c -+++ b/drivers/gpu/drm/qxl/qxl_gem.c -@@ -72,32 +72,41 @@ int qxl_gem_object_create(struct qxl_device *qdev, int size, - return 0; - } - -+/* -+ * If the caller passed a valid gobj pointer, it is responsible to call -+ * drm_gem_object_put() when it no longer needs to acess the object. -+ * -+ * If gobj is NULL, it is handled internally. -+ */ - int qxl_gem_object_create_with_handle(struct qxl_device *qdev, - struct drm_file *file_priv, - u32 domain, - size_t size, - struct qxl_surface *surf, -- struct qxl_bo **qobj, -+ struct drm_gem_object **gobj, - uint32_t *handle) - { -- struct drm_gem_object *gobj; - int r; -+ struct drm_gem_object *local_gobj; - -- BUG_ON(!qobj); - BUG_ON(!handle); - - r = qxl_gem_object_create(qdev, size, 0, - domain, - false, false, surf, -- &gobj); -+ &local_gobj); - if (r) - return -ENOMEM; -- r = drm_gem_handle_create(file_priv, gobj, handle); -+ r = drm_gem_handle_create(file_priv, local_gobj, handle); - if (r) - return r; -- /* drop reference from allocate - handle holds it now */ -- *qobj = gem_to_qxl_bo(gobj); -- drm_gem_object_put(gobj); -+ -+ if (gobj) -+ *gobj = local_gobj; -+ else -+ /* drop reference from allocate - handle holds it now */ -+ drm_gem_object_put(local_gobj); -+ - return 0; - } - -diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c -index 30f58b21372aa..dd0f834d881ce 100644 ---- a/drivers/gpu/drm/qxl/qxl_ioctl.c -+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c -@@ -38,7 +38,6 @@ int qxl_alloc_ioctl(struct drm_device *dev, void *data, struct drm_file *file_pr - struct qxl_device *qdev = to_qxl(dev); - struct drm_qxl_alloc *qxl_alloc = data; - int ret; -- struct qxl_bo *qobj; - uint32_t handle; - u32 domain = QXL_GEM_DOMAIN_VRAM; - -@@ -50,7 +49,7 @@ int qxl_alloc_ioctl(struct drm_device *dev, void *data, struct drm_file *file_pr - domain, - qxl_alloc->size, - NULL, -- &qobj, &handle); -+ NULL, &handle); - if (ret) { - DRM_ERROR("%s: failed to create gem ret=%d\n", - __func__, ret); -@@ -386,7 +385,6 @@ int qxl_alloc_surf_ioctl(struct drm_device *dev, void *data, struct drm_file *fi - { - struct qxl_device *qdev = to_qxl(dev); - struct drm_qxl_alloc_surf *param = data; -- struct qxl_bo *qobj; - int handle; - int ret; - int size, actual_stride; -@@ -406,7 +404,7 @@ int qxl_alloc_surf_ioctl(struct drm_device *dev, void *data, struct drm_file *fi - QXL_GEM_DOMAIN_SURFACE, - size, - &surf, -- &qobj, &handle); -+ NULL, &handle); - if (ret) { - DRM_ERROR("%s: failed to create gem ret=%d\n", - __func__, ret); -diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c -index b7dd59fe119e6..9edb5edb2bad9 100644 ---- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c -+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c -@@ -223,20 +223,6 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) - * DU channels that have a display PLL can't use the internal - * system clock, and have no internal clock divider. - */ -- -- /* -- * The H3 ES1.x exhibits dot clock duty cycle stability issues. -- * We can work around them by configuring the DPLL to twice the -- * desired frequency, coupled with a /2 post-divider. Restrict -- * the workaround to H3 ES1.x as ES2.0 and all other SoCs have -- * no post-divider when a display PLL is present (as shown by -- * the workaround breaking HDMI output on M3-W during testing). -- */ -- if (rcdu->info->quirks & RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY) { -- target *= 2; -- div = 1; -- } -- - extclk = clk_get_rate(rcrtc->extclock); - rcar_du_dpll_divider(rcrtc, &dpll, extclk, target); - -@@ -245,30 +231,13 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) - | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m) - | DPLLCR_STBY; - -- if (rcrtc->index == 1) { -+ if (rcrtc->index == 1) - dpllcr |= DPLLCR_PLCS1 - | DPLLCR_INCS_DOTCLKIN1; -- } else { -- dpllcr |= DPLLCR_PLCS0_PLL -+ else -+ dpllcr |= DPLLCR_PLCS0 - | DPLLCR_INCS_DOTCLKIN0; - -- /* -- * On ES2.x we have a single mux controlled via bit 21, -- * which selects between DCLKIN source (bit 21 = 0) and -- * a PLL source (bit 21 = 1), where the PLL is always -- * PLL1. -- * -- * On ES1.x we have an additional mux, controlled -- * via bit 20, for choosing between PLL0 (bit 20 = 0) -- * and PLL1 (bit 20 = 1). We always want to use PLL1, -- * so on ES1.x, in addition to setting bit 21, we need -- * to set the bit 20. -- */ -- -- if (rcdu->info->quirks & RCAR_DU_QUIRK_H3_ES1_PLL) -- dpllcr |= DPLLCR_PLCS0_H3ES1X_PLL1; -- } -- - rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr); - - escr = ESCR_DCLKSEL_DCLKIN | div; -diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c -index 6381578c4db58..bd7003d6e0753 100644 ---- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c -+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c -@@ -16,7 +16,6 @@ - #include - #include - #include --#include - #include - - #include -@@ -387,43 +386,6 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = { - .dpll_mask = BIT(2) | BIT(1), - }; - --static const struct rcar_du_device_info rcar_du_r8a7795_es1_info = { -- .gen = 3, -- .features = RCAR_DU_FEATURE_CRTC_IRQ -- | RCAR_DU_FEATURE_CRTC_CLOCK -- | RCAR_DU_FEATURE_VSP1_SOURCE -- | RCAR_DU_FEATURE_INTERLACED -- | RCAR_DU_FEATURE_TVM_SYNC, -- .quirks = RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY -- | RCAR_DU_QUIRK_H3_ES1_PLL, -- .channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), -- .routes = { -- /* -- * R8A7795 has one RGB output, two HDMI outputs and one -- * LVDS output. -- */ -- [RCAR_DU_OUTPUT_DPAD0] = { -- .possible_crtcs = BIT(3), -- .port = 0, -- }, -- [RCAR_DU_OUTPUT_HDMI0] = { -- .possible_crtcs = BIT(1), -- .port = 1, -- }, -- [RCAR_DU_OUTPUT_HDMI1] = { -- .possible_crtcs = BIT(2), -- .port = 2, -- }, -- [RCAR_DU_OUTPUT_LVDS0] = { -- .possible_crtcs = BIT(0), -- .port = 3, -- }, -- }, -- .num_lvds = 1, -- .num_rpf = 5, -- .dpll_mask = BIT(2) | BIT(1), --}; -- - static const struct rcar_du_device_info rcar_du_r8a7796_info = { - .gen = 3, - .features = RCAR_DU_FEATURE_CRTC_IRQ -@@ -592,11 +554,6 @@ static const struct of_device_id rcar_du_of_table[] = { - - MODULE_DEVICE_TABLE(of, rcar_du_of_table); - --static const struct soc_device_attribute rcar_du_soc_table[] = { -- { .soc_id = "r8a7795", .revision = "ES1.*", .data = &rcar_du_r8a7795_es1_info }, -- { /* sentinel */ } --}; -- - const char *rcar_du_output_name(enum rcar_du_output output) - { - static const char * const names[] = { -@@ -688,7 +645,6 @@ static void rcar_du_shutdown(struct platform_device *pdev) - - static int rcar_du_probe(struct platform_device *pdev) - { -- const struct soc_device_attribute *soc_attr; - struct rcar_du_device *rcdu; - unsigned int mask; - int ret; -@@ -706,10 +662,6 @@ static int rcar_du_probe(struct platform_device *pdev) - - rcdu->info = of_device_get_match_data(rcdu->dev); - -- soc_attr = soc_device_match(rcar_du_soc_table); -- if (soc_attr) -- rcdu->info = soc_attr->data; -- - platform_set_drvdata(pdev, rcdu); - - /* I/O resources */ -diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h -index acc3673fefe18..5cfa2bb7ad93d 100644 ---- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h -+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h -@@ -34,8 +34,6 @@ struct rcar_du_device; - #define RCAR_DU_FEATURE_NO_BLENDING BIT(5) /* PnMR.SPIM does not have ALP nor EOR bits */ - - #define RCAR_DU_QUIRK_ALIGN_128B BIT(0) /* Align pitches to 128 bytes */ --#define RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY BIT(1) /* H3 ES1 has pclk stability issue */ --#define RCAR_DU_QUIRK_H3_ES1_PLL BIT(2) /* H3 ES1 PLL setup differs from non-ES1 */ - - enum rcar_du_output { - RCAR_DU_OUTPUT_DPAD0, -diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h -index 789ae9285108e..288eff12b2b1a 100644 ---- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h -+++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h -@@ -283,8 +283,7 @@ - #define DPLLCR 0x20044 - #define DPLLCR_CODE (0x95 << 24) - #define DPLLCR_PLCS1 (1 << 23) --#define DPLLCR_PLCS0_PLL (1 << 21) --#define DPLLCR_PLCS0_H3ES1X_PLL1 (1 << 20) -+#define DPLLCR_PLCS0 (1 << 21) - #define DPLLCR_CLKE (1 << 18) - #define DPLLCR_FDPLL(n) ((n) << 12) - #define DPLLCR_N(n) ((n) << 5) -diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c -index 03c6becda795c..b8be4c1db4235 100644 ---- a/drivers/gpu/drm/stm/ltdc.c -+++ b/drivers/gpu/drm/stm/ltdc.c -@@ -1145,7 +1145,7 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc) - - static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source) - { -- struct ltdc_device *ldev = crtc_to_ltdc(crtc); -+ struct ltdc_device *ldev; - int ret; - - DRM_DEBUG_DRIVER("\n"); -@@ -1153,6 +1153,8 @@ static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source) - if (!crtc) - return -ENODEV; - -+ ldev = crtc_to_ltdc(crtc); -+ - if (source && strcmp(source, "auto") == 0) { - ldev->crc_active = true; - ret = regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN); -diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c -index 0b4204b9a253c..97eefb77f6014 100644 ---- a/drivers/hid/hid-logitech-hidpp.c -+++ b/drivers/hid/hid-logitech-hidpp.c -@@ -4403,6 +4403,8 @@ static const struct hid_device_id hidpp_devices[] = { - HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC086) }, - { /* Logitech G903 Hero Gaming Mouse over USB */ - HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC091) }, -+ { /* Logitech G915 TKL Keyboard over USB */ -+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC343) }, - { /* Logitech G920 Wheel over USB */ - HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), - .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, -@@ -4418,6 +4420,8 @@ static const struct hid_device_id hidpp_devices[] = { - { /* MX5500 keyboard over Bluetooth */ - HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b), - .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, -+ { /* Logitech G915 TKL keyboard over Bluetooth */ -+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb35f) }, - { /* M-RCQ142 V470 Cordless Laser Mouse over Bluetooth */ - HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb008) }, - { /* MX Master mouse over Bluetooth */ -diff --git a/drivers/hid/intel-ish-hid/ipc/hw-ish.h b/drivers/hid/intel-ish-hid/ipc/hw-ish.h -index fc108f19a64c3..e99f3a3c65e15 100644 ---- a/drivers/hid/intel-ish-hid/ipc/hw-ish.h -+++ b/drivers/hid/intel-ish-hid/ipc/hw-ish.h -@@ -33,6 +33,7 @@ - #define ADL_N_DEVICE_ID 0x54FC - #define RPL_S_DEVICE_ID 0x7A78 - #define MTL_P_DEVICE_ID 0x7E45 -+#define ARL_H_DEVICE_ID 0x7745 - - #define REVISION_ID_CHT_A0 0x6 - #define REVISION_ID_CHT_Ax_SI 0x0 -diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c -index 7120b30ac51d0..55cb25038e632 100644 ---- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c -+++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c -@@ -44,6 +44,7 @@ static const struct pci_device_id ish_pci_tbl[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ADL_N_DEVICE_ID)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, RPL_S_DEVICE_ID)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MTL_P_DEVICE_ID)}, -+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ARL_H_DEVICE_ID)}, - {0, } - }; - MODULE_DEVICE_TABLE(pci, ish_pci_tbl); -diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c -index 85d8a6b048856..30a2a3200bed9 100644 ---- a/drivers/i2c/busses/i2c-bcm-iproc.c -+++ b/drivers/i2c/busses/i2c-bcm-iproc.c -@@ -233,13 +233,14 @@ static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c, - u32 offset) - { - u32 val; -+ unsigned long flags; - - if (iproc_i2c->idm_base) { -- spin_lock(&iproc_i2c->idm_lock); -+ spin_lock_irqsave(&iproc_i2c->idm_lock, flags); - writel(iproc_i2c->ape_addr_mask, - iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET); - val = readl(iproc_i2c->base + offset); -- spin_unlock(&iproc_i2c->idm_lock); -+ spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags); - } else { - val = readl(iproc_i2c->base + offset); - } -@@ -250,12 +251,14 @@ static inline u32 iproc_i2c_rd_reg(struct bcm_iproc_i2c_dev *iproc_i2c, - static inline void iproc_i2c_wr_reg(struct bcm_iproc_i2c_dev *iproc_i2c, - u32 offset, u32 val) - { -+ unsigned long flags; -+ - if (iproc_i2c->idm_base) { -- spin_lock(&iproc_i2c->idm_lock); -+ spin_lock_irqsave(&iproc_i2c->idm_lock, flags); - writel(iproc_i2c->ape_addr_mask, - iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET); - writel(val, iproc_i2c->base + offset); -- spin_unlock(&iproc_i2c->idm_lock); -+ spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags); - } else { - writel(val, iproc_i2c->base + offset); - } -diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c -index dc3c5a15a95b9..004ccb2d9f369 100644 ---- a/drivers/i2c/busses/i2c-designware-master.c -+++ b/drivers/i2c/busses/i2c-designware-master.c -@@ -525,9 +525,21 @@ i2c_dw_read(struct dw_i2c_dev *dev) - u32 flags = msgs[dev->msg_read_idx].flags; - - regmap_read(dev->map, DW_IC_DATA_CMD, &tmp); -+ tmp &= DW_IC_DATA_CMD_DAT; - /* Ensure length byte is a valid value */ -- if (flags & I2C_M_RECV_LEN && -- (tmp & DW_IC_DATA_CMD_DAT) <= I2C_SMBUS_BLOCK_MAX && tmp > 0) { -+ if (flags & I2C_M_RECV_LEN) { -+ /* -+ * if IC_EMPTYFIFO_HOLD_MASTER_EN is set, which cannot be -+ * detected from the registers, the controller can be -+ * disabled if the STOP bit is set. But it is only set -+ * after receiving block data response length in -+ * I2C_FUNC_SMBUS_BLOCK_DATA case. That needs to read -+ * another byte with STOP bit set when the block data -+ * response length is invalid to complete the transaction. -+ */ -+ if (!tmp || tmp > I2C_SMBUS_BLOCK_MAX) -+ tmp = 1; -+ - len = i2c_dw_recv_len(dev, tmp); - } - *buf++ = tmp; -diff --git a/drivers/i2c/busses/i2c-hisi.c b/drivers/i2c/busses/i2c-hisi.c -index 8a61bee745a16..14ec9ee8f6f35 100644 ---- a/drivers/i2c/busses/i2c-hisi.c -+++ b/drivers/i2c/busses/i2c-hisi.c -@@ -328,6 +328,14 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context) - struct hisi_i2c_controller *ctlr = context; - u32 int_stat; - -+ /* -+ * Don't handle the interrupt if cltr->completion is NULL. We may -+ * reach here because the interrupt is spurious or the transfer is -+ * started by another port (e.g. firmware) rather than us. -+ */ -+ if (!ctlr->completion) -+ return IRQ_NONE; -+ - int_stat = readl(ctlr->iobase + HISI_I2C_INT_MSTAT); - hisi_i2c_clear_int(ctlr, int_stat); - if (!(int_stat & HISI_I2C_INT_ALL)) -diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c -index 2bc40f957e509..aa469b33ee2ee 100644 ---- a/drivers/i2c/busses/i2c-tegra.c -+++ b/drivers/i2c/busses/i2c-tegra.c -@@ -449,7 +449,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev) - if (i2c_dev->is_vi) - return 0; - -- if (!i2c_dev->hw->has_apb_dma) { -+ if (i2c_dev->hw->has_apb_dma) { - if (!IS_ENABLED(CONFIG_TEGRA20_APB_DMA)) { - dev_dbg(i2c_dev->dev, "APB DMA support not enabled\n"); - return 0; -diff --git a/drivers/infiniband/hw/mlx5/qpc.c b/drivers/infiniband/hw/mlx5/qpc.c -index 542e4c63a8de6..d4e7864c56f18 100644 ---- a/drivers/infiniband/hw/mlx5/qpc.c -+++ b/drivers/infiniband/hw/mlx5/qpc.c -@@ -297,8 +297,7 @@ int mlx5_core_destroy_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp) - MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP); - MLX5_SET(destroy_qp_in, in, qpn, qp->qpn); - MLX5_SET(destroy_qp_in, in, uid, qp->uid); -- mlx5_cmd_exec_in(dev->mdev, destroy_qp, in); -- return 0; -+ return mlx5_cmd_exec_in(dev->mdev, destroy_qp, in); - } - - int mlx5_core_set_delay_drop(struct mlx5_ib_dev *dev, -@@ -548,14 +547,14 @@ int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn) - return mlx5_cmd_exec_in(dev->mdev, dealloc_xrcd, in); - } - --static void destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid) -+static int destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid) - { - u32 in[MLX5_ST_SZ_DW(destroy_rq_in)] = {}; - - MLX5_SET(destroy_rq_in, in, opcode, MLX5_CMD_OP_DESTROY_RQ); - MLX5_SET(destroy_rq_in, in, rqn, rqn); - MLX5_SET(destroy_rq_in, in, uid, uid); -- mlx5_cmd_exec_in(dev->mdev, destroy_rq, in); -+ return mlx5_cmd_exec_in(dev->mdev, destroy_rq, in); - } - - int mlx5_core_create_rq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen, -@@ -586,8 +585,7 @@ int mlx5_core_destroy_rq_tracked(struct mlx5_ib_dev *dev, - struct mlx5_core_qp *rq) - { - destroy_resource_common(dev, rq); -- destroy_rq_tracked(dev, rq->qpn, rq->uid); -- return 0; -+ return destroy_rq_tracked(dev, rq->qpn, rq->uid); - } - - static void destroy_sq_tracked(struct mlx5_ib_dev *dev, u32 sqn, u16 uid) -diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h -index 5ecc17240eff5..f5e9377b55212 100644 ---- a/drivers/iommu/amd/amd_iommu_types.h -+++ b/drivers/iommu/amd/amd_iommu_types.h -@@ -172,6 +172,7 @@ - #define CONTROL_GAINT_EN 29 - #define CONTROL_XT_EN 50 - #define CONTROL_INTCAPXT_EN 51 -+#define CONTROL_IRTCACHEDIS 59 - #define CONTROL_SNPAVIC_EN 61 - - #define CTRL_INV_TO_MASK (7 << CONTROL_INV_TIMEOUT) -@@ -708,6 +709,9 @@ struct amd_iommu { - /* if one, we need to send a completion wait command */ - bool need_sync; - -+ /* true if disable irte caching */ -+ bool irtcachedis_enabled; -+ - /* Handle for IOMMU core code */ - struct iommu_device iommu; - -diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c -index b0af8b5967e0d..f6e64c9858021 100644 ---- a/drivers/iommu/amd/init.c -+++ b/drivers/iommu/amd/init.c -@@ -160,6 +160,7 @@ static int amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE; - static bool amd_iommu_detected; - static bool amd_iommu_disabled __initdata; - static bool amd_iommu_force_enable __initdata; -+static bool amd_iommu_irtcachedis; - static int amd_iommu_target_ivhd_type; - - /* Global EFR and EFR2 registers */ -@@ -477,6 +478,9 @@ static void iommu_disable(struct amd_iommu *iommu) - - /* Disable IOMMU hardware itself */ - iommu_feature_disable(iommu, CONTROL_IOMMU_EN); -+ -+ /* Clear IRTE cache disabling bit */ -+ iommu_feature_disable(iommu, CONTROL_IRTCACHEDIS); - } - - /* -@@ -2700,6 +2704,33 @@ static void iommu_enable_ga(struct amd_iommu *iommu) - #endif - } - -+static void iommu_disable_irtcachedis(struct amd_iommu *iommu) -+{ -+ iommu_feature_disable(iommu, CONTROL_IRTCACHEDIS); -+} -+ -+static void iommu_enable_irtcachedis(struct amd_iommu *iommu) -+{ -+ u64 ctrl; -+ -+ if (!amd_iommu_irtcachedis) -+ return; -+ -+ /* -+ * Note: -+ * The support for IRTCacheDis feature is dertermined by -+ * checking if the bit is writable. -+ */ -+ iommu_feature_enable(iommu, CONTROL_IRTCACHEDIS); -+ ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET); -+ ctrl &= (1ULL << CONTROL_IRTCACHEDIS); -+ if (ctrl) -+ iommu->irtcachedis_enabled = true; -+ pr_info("iommu%d (%#06x) : IRT cache is %s\n", -+ iommu->index, iommu->devid, -+ iommu->irtcachedis_enabled ? "disabled" : "enabled"); -+} -+ - static void early_enable_iommu(struct amd_iommu *iommu) - { - iommu_disable(iommu); -@@ -2710,6 +2741,7 @@ static void early_enable_iommu(struct amd_iommu *iommu) - iommu_set_exclusion_range(iommu); - iommu_enable_ga(iommu); - iommu_enable_xt(iommu); -+ iommu_enable_irtcachedis(iommu); - iommu_enable(iommu); - iommu_flush_all_caches(iommu); - } -@@ -2760,10 +2792,12 @@ static void early_enable_iommus(void) - for_each_iommu(iommu) { - iommu_disable_command_buffer(iommu); - iommu_disable_event_buffer(iommu); -+ iommu_disable_irtcachedis(iommu); - iommu_enable_command_buffer(iommu); - iommu_enable_event_buffer(iommu); - iommu_enable_ga(iommu); - iommu_enable_xt(iommu); -+ iommu_enable_irtcachedis(iommu); - iommu_set_device_table(iommu); - iommu_flush_all_caches(iommu); - } -@@ -3411,6 +3445,8 @@ static int __init parse_amd_iommu_options(char *str) - amd_iommu_pgtable = AMD_IOMMU_V1; - } else if (strncmp(str, "pgtbl_v2", 8) == 0) { - amd_iommu_pgtable = AMD_IOMMU_V2; -+ } else if (strncmp(str, "irtcachedis", 11) == 0) { -+ amd_iommu_irtcachedis = true; - } else { - pr_notice("Unknown option - '%s'\n", str); - } -diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c -index f1c2419334e6f..f85a5d65d1314 100644 ---- a/drivers/leds/rgb/leds-qcom-lpg.c -+++ b/drivers/leds/rgb/leds-qcom-lpg.c -@@ -1112,8 +1112,10 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np) - i = 0; - for_each_available_child_of_node(np, child) { - ret = lpg_parse_channel(lpg, child, &led->channels[i]); -- if (ret < 0) -+ if (ret < 0) { -+ of_node_put(child); - return ret; -+ } - - info[i].color_index = led->channels[i]->color; - info[i].intensity = 0; -@@ -1291,8 +1293,10 @@ static int lpg_probe(struct platform_device *pdev) - - for_each_available_child_of_node(pdev->dev.of_node, np) { - ret = lpg_add_led(lpg, np); -- if (ret) -+ if (ret) { -+ of_node_put(np); - return ret; -+ } - } - - for (i = 0; i < lpg->num_channels; i++) -diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.c b/drivers/media/platform/mediatek/vpu/mtk_vpu.c -index 47b684b92f817..6beab9e86a22a 100644 ---- a/drivers/media/platform/mediatek/vpu/mtk_vpu.c -+++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.c -@@ -562,15 +562,17 @@ static int load_requested_vpu(struct mtk_vpu *vpu, - int vpu_load_firmware(struct platform_device *pdev) - { - struct mtk_vpu *vpu; -- struct device *dev = &pdev->dev; -+ struct device *dev; - struct vpu_run *run; - int ret; - - if (!pdev) { -- dev_err(dev, "VPU platform device is invalid\n"); -+ pr_err("VPU platform device is invalid\n"); - return -EINVAL; - } - -+ dev = &pdev->dev; -+ - vpu = platform_get_drvdata(pdev); - run = &vpu->run; - -diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c -index a26e4a5d87b6b..d8cd9b09c20de 100644 ---- a/drivers/media/platform/qcom/camss/camss-vfe.c -+++ b/drivers/media/platform/qcom/camss/camss-vfe.c -@@ -1540,7 +1540,11 @@ int msm_vfe_register_entities(struct vfe_device *vfe, - } - - video_out->ops = &vfe->video_ops; -- video_out->bpl_alignment = 8; -+ if (vfe->camss->version == CAMSS_845 || -+ vfe->camss->version == CAMSS_8250) -+ video_out->bpl_alignment = 16; -+ else -+ video_out->bpl_alignment = 8; - video_out->line_based = 0; - if (i == VFE_LINE_PIX) { - video_out->bpl_alignment = 16; -diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c -index e0dca445abf14..9ee1b6abd8a05 100644 ---- a/drivers/misc/habanalabs/common/device.c -+++ b/drivers/misc/habanalabs/common/device.c -@@ -870,6 +870,18 @@ static void device_early_fini(struct hl_device *hdev) - hdev->asic_funcs->early_fini(hdev); - } - -+static bool is_pci_link_healthy(struct hl_device *hdev) -+{ -+ u16 vendor_id; -+ -+ if (!hdev->pdev) -+ return false; -+ -+ pci_read_config_word(hdev->pdev, PCI_VENDOR_ID, &vendor_id); -+ -+ return (vendor_id == PCI_VENDOR_ID_HABANALABS); -+} -+ - static void hl_device_heartbeat(struct work_struct *work) - { - struct hl_device *hdev = container_of(work, struct hl_device, -@@ -882,7 +894,8 @@ static void hl_device_heartbeat(struct work_struct *work) - goto reschedule; - - if (hl_device_operational(hdev, NULL)) -- dev_err(hdev->dev, "Device heartbeat failed!\n"); -+ dev_err(hdev->dev, "Device heartbeat failed! PCI link is %s\n", -+ is_pci_link_healthy(hdev) ? "healthy" : "broken"); - - hl_device_reset(hdev, HL_DRV_RESET_HARD | HL_DRV_RESET_HEARTBEAT); - -diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h -index 58c95b13be69a..257b94cec6248 100644 ---- a/drivers/misc/habanalabs/common/habanalabs.h -+++ b/drivers/misc/habanalabs/common/habanalabs.h -@@ -34,6 +34,8 @@ - struct hl_device; - struct hl_fpriv; - -+#define PCI_VENDOR_ID_HABANALABS 0x1da3 -+ - /* Use upper bits of mmap offset to store habana driver specific information. - * bits[63:59] - Encode mmap type - * bits[45:0] - mmap offset value -diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c -index 112632afe7d53..ae3cab3f4aa55 100644 ---- a/drivers/misc/habanalabs/common/habanalabs_drv.c -+++ b/drivers/misc/habanalabs/common/habanalabs_drv.c -@@ -54,8 +54,6 @@ module_param(boot_error_status_mask, ulong, 0444); - MODULE_PARM_DESC(boot_error_status_mask, - "Mask of the error status during device CPU boot (If bitX is cleared then error X is masked. Default all 1's)"); - --#define PCI_VENDOR_ID_HABANALABS 0x1da3 -- - #define PCI_IDS_GOYA 0x0001 - #define PCI_IDS_GAUDI 0x1000 - #define PCI_IDS_GAUDI_SEC 0x1010 -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index 498333b769fdb..cdd7f126d4aea 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -2097,14 +2097,14 @@ static void mmc_blk_mq_poll_completion(struct mmc_queue *mq, - mmc_blk_urgent_bkops(mq, mqrq); - } - --static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, struct request *req) -+static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type) - { - unsigned long flags; - bool put_card; - - spin_lock_irqsave(&mq->lock, flags); - -- mq->in_flight[mmc_issue_type(mq, req)] -= 1; -+ mq->in_flight[issue_type] -= 1; - - put_card = (mmc_tot_in_flight(mq) == 0); - -@@ -2117,6 +2117,7 @@ static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, struct request *req) - static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req, - bool can_sleep) - { -+ enum mmc_issue_type issue_type = mmc_issue_type(mq, req); - struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req); - struct mmc_request *mrq = &mqrq->brq.mrq; - struct mmc_host *host = mq->card->host; -@@ -2136,7 +2137,7 @@ static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req, - blk_mq_complete_request(req); - } - -- mmc_blk_mq_dec_in_flight(mq, req); -+ mmc_blk_mq_dec_in_flight(mq, issue_type); - } - - void mmc_blk_mq_recovery(struct mmc_queue *mq) -diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c -index 6c4f43e112826..7ede74bf37230 100644 ---- a/drivers/mmc/host/sdhci_f_sdh30.c -+++ b/drivers/mmc/host/sdhci_f_sdh30.c -@@ -26,9 +26,16 @@ struct f_sdhost_priv { - bool enable_cmd_dat_delay; - }; - -+static void *sdhci_f_sdhost_priv(struct sdhci_host *host) -+{ -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ -+ return sdhci_pltfm_priv(pltfm_host); -+} -+ - static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host) - { -- struct f_sdhost_priv *priv = sdhci_priv(host); -+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); - u32 ctrl = 0; - - usleep_range(2500, 3000); -@@ -61,7 +68,7 @@ static unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host) - - static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask) - { -- struct f_sdhost_priv *priv = sdhci_priv(host); -+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); - u32 ctl; - - if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0) -@@ -85,30 +92,32 @@ static const struct sdhci_ops sdhci_f_sdh30_ops = { - .set_uhs_signaling = sdhci_set_uhs_signaling, - }; - -+static const struct sdhci_pltfm_data sdhci_f_sdh30_pltfm_data = { -+ .ops = &sdhci_f_sdh30_ops, -+ .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC -+ | SDHCI_QUIRK_INVERTED_WRITE_PROTECT, -+ .quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE -+ | SDHCI_QUIRK2_TUNING_WORK_AROUND, -+}; -+ - static int sdhci_f_sdh30_probe(struct platform_device *pdev) - { - struct sdhci_host *host; - struct device *dev = &pdev->dev; -- int irq, ctrl = 0, ret = 0; -+ int ctrl = 0, ret = 0; - struct f_sdhost_priv *priv; -+ struct sdhci_pltfm_host *pltfm_host; - u32 reg = 0; - -- irq = platform_get_irq(pdev, 0); -- if (irq < 0) -- return irq; -- -- host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv)); -+ host = sdhci_pltfm_init(pdev, &sdhci_f_sdh30_pltfm_data, -+ sizeof(struct f_sdhost_priv)); - if (IS_ERR(host)) - return PTR_ERR(host); - -- priv = sdhci_priv(host); -+ pltfm_host = sdhci_priv(host); -+ priv = sdhci_pltfm_priv(pltfm_host); - priv->dev = dev; - -- host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | -- SDHCI_QUIRK_INVERTED_WRITE_PROTECT; -- host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE | -- SDHCI_QUIRK2_TUNING_WORK_AROUND; -- - priv->enable_cmd_dat_delay = device_property_read_bool(dev, - "fujitsu,cmd-dat-delay-select"); - -@@ -116,18 +125,6 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev) - if (ret) - goto err; - -- platform_set_drvdata(pdev, host); -- -- host->hw_name = "f_sdh30"; -- host->ops = &sdhci_f_sdh30_ops; -- host->irq = irq; -- -- host->ioaddr = devm_platform_ioremap_resource(pdev, 0); -- if (IS_ERR(host->ioaddr)) { -- ret = PTR_ERR(host->ioaddr); -- goto err; -- } -- - if (dev_of_node(dev)) { - sdhci_get_of_property(pdev); - -@@ -182,23 +179,22 @@ err_add_host: - err_clk: - clk_disable_unprepare(priv->clk_iface); - err: -- sdhci_free_host(host); -+ sdhci_pltfm_free(pdev); -+ - return ret; - } - - static int sdhci_f_sdh30_remove(struct platform_device *pdev) - { - struct sdhci_host *host = platform_get_drvdata(pdev); -- struct f_sdhost_priv *priv = sdhci_priv(host); -- -- sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) == -- 0xffffffff); -+ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); -+ struct clk *clk_iface = priv->clk_iface; -+ struct clk *clk = priv->clk; - -- clk_disable_unprepare(priv->clk_iface); -- clk_disable_unprepare(priv->clk); -+ sdhci_pltfm_unregister(pdev); - -- sdhci_free_host(host); -- platform_set_drvdata(pdev, NULL); -+ clk_disable_unprepare(clk_iface); -+ clk_disable_unprepare(clk); - - return 0; - } -diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c -index 7c7ec8d10232b..b5b1a42ca25e1 100644 ---- a/drivers/mmc/host/wbsd.c -+++ b/drivers/mmc/host/wbsd.c -@@ -1705,8 +1705,6 @@ static int wbsd_init(struct device *dev, int base, int irq, int dma, - - wbsd_release_resources(host); - wbsd_free_mmc(dev); -- -- mmc_free_host(mmc); - return ret; - } - -diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c -index b69bd44ada1f2..a73008b9e0b3c 100644 ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3006,6 +3006,14 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip) - - /* If there is a GPIO connected to the reset pin, toggle it */ - if (gpiod) { -+ /* If the switch has just been reset and not yet completed -+ * loading EEPROM, the reset may interrupt the I2C transaction -+ * mid-byte, causing the first EEPROM read after the reset -+ * from the wrong location resulting in the switch booting -+ * to wrong mode and inoperable. -+ */ -+ mv88e6xxx_g1_wait_eeprom_done(chip); -+ - gpiod_set_value_cansleep(gpiod, 1); - usleep_range(10000, 20000); - gpiod_set_value_cansleep(gpiod, 0); -diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c -index abd6cc0cd641f..5fb991835078a 100644 ---- a/drivers/net/ethernet/cadence/macb_main.c -+++ b/drivers/net/ethernet/cadence/macb_main.c -@@ -5070,6 +5070,9 @@ static int __maybe_unused macb_suspend(struct device *dev) - unsigned int q; - int err; - -+ if (!device_may_wakeup(&bp->dev->dev)) -+ phy_exit(bp->sgmii_phy); -+ - if (!netif_running(netdev)) - return 0; - -@@ -5130,7 +5133,6 @@ static int __maybe_unused macb_suspend(struct device *dev) - if (!(bp->wol & MACB_WOL_ENABLED)) { - rtnl_lock(); - phylink_stop(bp->phylink); -- phy_exit(bp->sgmii_phy); - rtnl_unlock(); - spin_lock_irqsave(&bp->lock, flags); - macb_reset_hw(bp); -@@ -5160,6 +5162,9 @@ static int __maybe_unused macb_resume(struct device *dev) - unsigned int q; - int err; - -+ if (!device_may_wakeup(&bp->dev->dev)) -+ phy_init(bp->sgmii_phy); -+ - if (!netif_running(netdev)) - return 0; - -@@ -5220,8 +5225,6 @@ static int __maybe_unused macb_resume(struct device *dev) - macb_set_rx_mode(netdev); - macb_restore_features(bp); - rtnl_lock(); -- if (!device_may_wakeup(&bp->dev->dev)) -- phy_init(bp->sgmii_phy); - - phylink_start(bp->phylink); - rtnl_unlock(); -diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c -index 17e3f26eee4a4..779ba907009a5 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c -@@ -210,11 +210,11 @@ read_nvm_exit: - * @hw: pointer to the HW structure. - * @module_pointer: module pointer location in words from the NVM beginning - * @offset: offset in words from module start -- * @words: number of words to write -- * @data: buffer with words to write to the Shadow RAM -+ * @words: number of words to read -+ * @data: buffer with words to read to the Shadow RAM - * @last_command: tells the AdminQ that this is the last command - * -- * Writes a 16 bit words buffer to the Shadow RAM using the admin command. -+ * Reads a 16 bit words buffer to the Shadow RAM using the admin command. - **/ - static int i40e_read_nvm_aq(struct i40e_hw *hw, - u8 module_pointer, u32 offset, -@@ -234,18 +234,18 @@ static int i40e_read_nvm_aq(struct i40e_hw *hw, - */ - if ((offset + words) > hw->nvm.sr_size) - i40e_debug(hw, I40E_DEBUG_NVM, -- "NVM write error: offset %d beyond Shadow RAM limit %d\n", -+ "NVM read error: offset %d beyond Shadow RAM limit %d\n", - (offset + words), hw->nvm.sr_size); - else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS) -- /* We can write only up to 4KB (one sector), in one AQ write */ -+ /* We can read only up to 4KB (one sector), in one AQ write */ - i40e_debug(hw, I40E_DEBUG_NVM, -- "NVM write fail error: tried to write %d words, limit is %d.\n", -+ "NVM read fail error: tried to read %d words, limit is %d.\n", - words, I40E_SR_SECTOR_SIZE_IN_WORDS); - else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS) - != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS)) -- /* A single write cannot spread over two sectors */ -+ /* A single read cannot spread over two sectors */ - i40e_debug(hw, I40E_DEBUG_NVM, -- "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n", -+ "NVM read error: cannot spread over two sectors in a single read offset=%d words=%d\n", - offset, words); - else - ret_code = i40e_aq_read_nvm(hw, module_pointer, -diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -index f544d2b0abdbd..fe912b1c468ef 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -@@ -1289,6 +1289,7 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe - fltr->ip_mask.src_port = fsp->m_u.tcp_ip4_spec.psrc; - fltr->ip_mask.dst_port = fsp->m_u.tcp_ip4_spec.pdst; - fltr->ip_mask.tos = fsp->m_u.tcp_ip4_spec.tos; -+ fltr->ip_ver = 4; - break; - case AH_V4_FLOW: - case ESP_V4_FLOW: -@@ -1300,6 +1301,7 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe - fltr->ip_mask.v4_addrs.dst_ip = fsp->m_u.ah_ip4_spec.ip4dst; - fltr->ip_mask.spi = fsp->m_u.ah_ip4_spec.spi; - fltr->ip_mask.tos = fsp->m_u.ah_ip4_spec.tos; -+ fltr->ip_ver = 4; - break; - case IPV4_USER_FLOW: - fltr->ip_data.v4_addrs.src_ip = fsp->h_u.usr_ip4_spec.ip4src; -@@ -1312,6 +1314,7 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe - fltr->ip_mask.l4_header = fsp->m_u.usr_ip4_spec.l4_4_bytes; - fltr->ip_mask.tos = fsp->m_u.usr_ip4_spec.tos; - fltr->ip_mask.proto = fsp->m_u.usr_ip4_spec.proto; -+ fltr->ip_ver = 4; - break; - case TCP_V6_FLOW: - case UDP_V6_FLOW: -@@ -1330,6 +1333,7 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe - fltr->ip_mask.src_port = fsp->m_u.tcp_ip6_spec.psrc; - fltr->ip_mask.dst_port = fsp->m_u.tcp_ip6_spec.pdst; - fltr->ip_mask.tclass = fsp->m_u.tcp_ip6_spec.tclass; -+ fltr->ip_ver = 6; - break; - case AH_V6_FLOW: - case ESP_V6_FLOW: -@@ -1345,6 +1349,7 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe - sizeof(struct in6_addr)); - fltr->ip_mask.spi = fsp->m_u.ah_ip6_spec.spi; - fltr->ip_mask.tclass = fsp->m_u.ah_ip6_spec.tclass; -+ fltr->ip_ver = 6; - break; - case IPV6_USER_FLOW: - memcpy(&fltr->ip_data.v6_addrs.src_ip, fsp->h_u.usr_ip6_spec.ip6src, -@@ -1361,6 +1366,7 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe - fltr->ip_mask.l4_header = fsp->m_u.usr_ip6_spec.l4_4_bytes; - fltr->ip_mask.tclass = fsp->m_u.usr_ip6_spec.tclass; - fltr->ip_mask.proto = fsp->m_u.usr_ip6_spec.l4_proto; -+ fltr->ip_ver = 6; - break; - case ETHER_FLOW: - fltr->eth_data.etype = fsp->h_u.ether_spec.h_proto; -@@ -1371,6 +1377,10 @@ iavf_add_fdir_fltr_info(struct iavf_adapter *adapter, struct ethtool_rx_flow_spe - return -EINVAL; - } - -+ err = iavf_validate_fdir_fltr_masks(adapter, fltr); -+ if (err) -+ return err; -+ - if (iavf_fdir_is_dup_fltr(adapter, fltr)) - return -EEXIST; - -diff --git a/drivers/net/ethernet/intel/iavf/iavf_fdir.c b/drivers/net/ethernet/intel/iavf/iavf_fdir.c -index 505e82ebafe47..03e774bd2a5b4 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_fdir.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_fdir.c -@@ -18,6 +18,79 @@ static const struct in6_addr ipv6_addr_full_mask = { - } - }; - -+static const struct in6_addr ipv6_addr_zero_mask = { -+ .in6_u = { -+ .u6_addr8 = { -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ } -+ } -+}; -+ -+/** -+ * iavf_validate_fdir_fltr_masks - validate Flow Director filter fields masks -+ * @adapter: pointer to the VF adapter structure -+ * @fltr: Flow Director filter data structure -+ * -+ * Returns 0 if all masks of packet fields are either full or empty. Returns -+ * error on at least one partial mask. -+ */ -+int iavf_validate_fdir_fltr_masks(struct iavf_adapter *adapter, -+ struct iavf_fdir_fltr *fltr) -+{ -+ if (fltr->eth_mask.etype && fltr->eth_mask.etype != htons(U16_MAX)) -+ goto partial_mask; -+ -+ if (fltr->ip_ver == 4) { -+ if (fltr->ip_mask.v4_addrs.src_ip && -+ fltr->ip_mask.v4_addrs.src_ip != htonl(U32_MAX)) -+ goto partial_mask; -+ -+ if (fltr->ip_mask.v4_addrs.dst_ip && -+ fltr->ip_mask.v4_addrs.dst_ip != htonl(U32_MAX)) -+ goto partial_mask; -+ -+ if (fltr->ip_mask.tos && fltr->ip_mask.tos != U8_MAX) -+ goto partial_mask; -+ } else if (fltr->ip_ver == 6) { -+ if (memcmp(&fltr->ip_mask.v6_addrs.src_ip, &ipv6_addr_zero_mask, -+ sizeof(struct in6_addr)) && -+ memcmp(&fltr->ip_mask.v6_addrs.src_ip, &ipv6_addr_full_mask, -+ sizeof(struct in6_addr))) -+ goto partial_mask; -+ -+ if (memcmp(&fltr->ip_mask.v6_addrs.dst_ip, &ipv6_addr_zero_mask, -+ sizeof(struct in6_addr)) && -+ memcmp(&fltr->ip_mask.v6_addrs.dst_ip, &ipv6_addr_full_mask, -+ sizeof(struct in6_addr))) -+ goto partial_mask; -+ -+ if (fltr->ip_mask.tclass && fltr->ip_mask.tclass != U8_MAX) -+ goto partial_mask; -+ } -+ -+ if (fltr->ip_mask.proto && fltr->ip_mask.proto != U8_MAX) -+ goto partial_mask; -+ -+ if (fltr->ip_mask.src_port && fltr->ip_mask.src_port != htons(U16_MAX)) -+ goto partial_mask; -+ -+ if (fltr->ip_mask.dst_port && fltr->ip_mask.dst_port != htons(U16_MAX)) -+ goto partial_mask; -+ -+ if (fltr->ip_mask.spi && fltr->ip_mask.spi != htonl(U32_MAX)) -+ goto partial_mask; -+ -+ if (fltr->ip_mask.l4_header && -+ fltr->ip_mask.l4_header != htonl(U32_MAX)) -+ goto partial_mask; -+ -+ return 0; -+ -+partial_mask: -+ dev_err(&adapter->pdev->dev, "Failed to add Flow Director filter, partial masks are not supported\n"); -+ return -EOPNOTSUPP; -+} -+ - /** - * iavf_pkt_udp_no_pay_len - the length of UDP packet without payload - * @fltr: Flow Director filter data structure -@@ -263,8 +336,6 @@ iavf_fill_fdir_ip4_hdr(struct iavf_fdir_fltr *fltr, - VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, DST); - } - -- fltr->ip_ver = 4; -- - return 0; - } - -@@ -309,8 +380,6 @@ iavf_fill_fdir_ip6_hdr(struct iavf_fdir_fltr *fltr, - VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, DST); - } - -- fltr->ip_ver = 6; -- - return 0; - } - -diff --git a/drivers/net/ethernet/intel/iavf/iavf_fdir.h b/drivers/net/ethernet/intel/iavf/iavf_fdir.h -index 33c55c366315b..9eb9f73f6adf3 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_fdir.h -+++ b/drivers/net/ethernet/intel/iavf/iavf_fdir.h -@@ -110,6 +110,8 @@ struct iavf_fdir_fltr { - struct virtchnl_fdir_add vc_add_msg; - }; - -+int iavf_validate_fdir_fltr_masks(struct iavf_adapter *adapter, -+ struct iavf_fdir_fltr *fltr); - int iavf_fill_fdir_add_msg(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr); - void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr); - bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr); -diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c -index f9f15acae90a0..2ffe5708a045b 100644 ---- a/drivers/net/ethernet/intel/ice/ice_eswitch.c -+++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c -@@ -562,6 +562,12 @@ ice_eswitch_mode_set(struct devlink *devlink, u16 mode, - break; - case DEVLINK_ESWITCH_MODE_SWITCHDEV: - { -+ if (ice_is_adq_active(pf)) { -+ dev_err(ice_pf_to_dev(pf), "Couldn't change eswitch mode to switchdev - ADQ is active. Delete ADQ configs and try again, e.g. tc qdisc del dev $PF root"); -+ NL_SET_ERR_MSG_MOD(extack, "Couldn't change eswitch mode to switchdev - ADQ is active. Delete ADQ configs and try again, e.g. tc qdisc del dev $PF root"); -+ return -EOPNOTSUPP; -+ } -+ - dev_info(ice_pf_to_dev(pf), "PF %d changed eswitch mode to switchdev", - pf->hw.pf_id); - NL_SET_ERR_MSG_MOD(extack, "Changed eswitch mode to switchdev"); -diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c -index a771e597795d3..7a00d297be3a9 100644 ---- a/drivers/net/ethernet/intel/ice/ice_main.c -+++ b/drivers/net/ethernet/intel/ice/ice_main.c -@@ -8787,6 +8787,11 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type, - ice_setup_tc_block_cb, - np, np, true); - case TC_SETUP_QDISC_MQPRIO: -+ if (ice_is_eswitch_mode_switchdev(pf)) { -+ netdev_err(netdev, "TC MQPRIO offload not supported, switchdev is enabled\n"); -+ return -EOPNOTSUPP; -+ } -+ - if (pf->adev) { - mutex_lock(&pf->adev_mutex); - device_lock(&pf->adev->dev); -diff --git a/drivers/net/ethernet/intel/igc/igc_base.h b/drivers/net/ethernet/intel/igc/igc_base.h -index ce530f5fd7bda..52849f5e8048d 100644 ---- a/drivers/net/ethernet/intel/igc/igc_base.h -+++ b/drivers/net/ethernet/intel/igc/igc_base.h -@@ -85,8 +85,13 @@ union igc_adv_rx_desc { - #define IGC_RXDCTL_SWFLUSH 0x04000000 /* Receive Software Flush */ - - /* SRRCTL bit definitions */ --#define IGC_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */ --#define IGC_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */ --#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 -+#define IGC_SRRCTL_BSIZEPKT_MASK GENMASK(6, 0) -+#define IGC_SRRCTL_BSIZEPKT(x) FIELD_PREP(IGC_SRRCTL_BSIZEPKT_MASK, \ -+ (x) / 1024) /* in 1 KB resolution */ -+#define IGC_SRRCTL_BSIZEHDR_MASK GENMASK(13, 8) -+#define IGC_SRRCTL_BSIZEHDR(x) FIELD_PREP(IGC_SRRCTL_BSIZEHDR_MASK, \ -+ (x) / 64) /* in 64 bytes resolution */ -+#define IGC_SRRCTL_DESCTYPE_MASK GENMASK(27, 25) -+#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF FIELD_PREP(IGC_SRRCTL_DESCTYPE_MASK, 1) - - #endif /* _IGC_BASE_H */ -diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c -index d877dc0f87f71..2f3947cf513bd 100644 ---- a/drivers/net/ethernet/intel/igc/igc_main.c -+++ b/drivers/net/ethernet/intel/igc/igc_main.c -@@ -675,8 +675,11 @@ static void igc_configure_rx_ring(struct igc_adapter *adapter, - else - buf_size = IGC_RXBUFFER_2048; - -- srrctl = IGC_RX_HDR_LEN << IGC_SRRCTL_BSIZEHDRSIZE_SHIFT; -- srrctl |= buf_size >> IGC_SRRCTL_BSIZEPKT_SHIFT; -+ srrctl = rd32(IGC_SRRCTL(reg_idx)); -+ srrctl &= ~(IGC_SRRCTL_BSIZEPKT_MASK | IGC_SRRCTL_BSIZEHDR_MASK | -+ IGC_SRRCTL_DESCTYPE_MASK); -+ srrctl |= IGC_SRRCTL_BSIZEHDR(IGC_RX_HDR_LEN); -+ srrctl |= IGC_SRRCTL_BSIZEPKT(buf_size); - srrctl |= IGC_SRRCTL_DESCTYPE_ADV_ONEBUF; - - wr32(IGC_SRRCTL(reg_idx), srrctl); -diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -index 8979dd05e873f..d4ec46d1c8cfb 100644 ---- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -@@ -1121,12 +1121,12 @@ static void octep_remove(struct pci_dev *pdev) - if (!oct) - return; - -- cancel_work_sync(&oct->tx_timeout_task); - cancel_work_sync(&oct->ctrl_mbox_task); - netdev = oct->netdev; - if (netdev->reg_state == NETREG_REGISTERED) - unregister_netdev(netdev); - -+ cancel_work_sync(&oct->tx_timeout_task); - octep_device_cleanup(oct); - pci_release_mem_regions(pdev); - free_netdev(netdev); -diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c -index e8d427c7d1cff..dc43e74147fbf 100644 ---- a/drivers/net/ethernet/qlogic/qede/qede_main.c -+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c -@@ -177,6 +177,15 @@ static int qede_sriov_configure(struct pci_dev *pdev, int num_vfs_param) - } - #endif - -+static int __maybe_unused qede_suspend(struct device *dev) -+{ -+ dev_info(dev, "Device does not support suspend operation\n"); -+ -+ return -EOPNOTSUPP; -+} -+ -+static DEFINE_SIMPLE_DEV_PM_OPS(qede_pm_ops, qede_suspend, NULL); -+ - static const struct pci_error_handlers qede_err_handler = { - .error_detected = qede_io_error_detected, - }; -@@ -191,6 +200,7 @@ static struct pci_driver qede_pci_driver = { - .sriov_configure = qede_sriov_configure, - #endif - .err_handler = &qede_err_handler, -+ .driver.pm = &qede_pm_ops, - }; - - static struct qed_eth_cb_ops qede_ll_ops = { -diff --git a/drivers/net/ethernet/sfc/tc.c b/drivers/net/ethernet/sfc/tc.c -index 3478860d40232..d312147cd2dd7 100644 ---- a/drivers/net/ethernet/sfc/tc.c -+++ b/drivers/net/ethernet/sfc/tc.c -@@ -603,10 +603,10 @@ int efx_init_tc(struct efx_nic *efx) - rc = efx_tc_configure_rep_mport(efx); - if (rc) - return rc; -- efx->tc->up = true; - rc = flow_indr_dev_register(efx_tc_indr_setup_cb, efx); - if (rc) - return rc; -+ efx->tc->up = true; - return 0; - } - -diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c -index c1424119e8212..847ab37f13671 100644 ---- a/drivers/net/pcs/pcs-rzn1-miic.c -+++ b/drivers/net/pcs/pcs-rzn1-miic.c -@@ -317,15 +317,21 @@ struct phylink_pcs *miic_create(struct device *dev, struct device_node *np) - - pdev = of_find_device_by_node(pcs_np); - of_node_put(pcs_np); -- if (!pdev || !platform_get_drvdata(pdev)) -+ if (!pdev || !platform_get_drvdata(pdev)) { -+ if (pdev) -+ put_device(&pdev->dev); - return ERR_PTR(-EPROBE_DEFER); -+ } - - miic_port = kzalloc(sizeof(*miic_port), GFP_KERNEL); -- if (!miic_port) -+ if (!miic_port) { -+ put_device(&pdev->dev); - return ERR_PTR(-ENOMEM); -+ } - - miic = platform_get_drvdata(pdev); - device_link_add(dev, miic->dev, DL_FLAG_AUTOREMOVE_CONSUMER); -+ put_device(&pdev->dev); - - miic_port->miic = miic; - miic_port->port = port - 1; -diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c -index 61824a463df85..edd4b1e58d965 100644 ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -305,7 +305,6 @@ struct at803x_priv { - bool is_1000basex; - struct regulator_dev *vddio_rdev; - struct regulator_dev *vddh_rdev; -- struct regulator *vddio; - u64 stats[ARRAY_SIZE(at803x_hw_stats)]; - }; - -@@ -461,21 +460,27 @@ static int at803x_set_wol(struct phy_device *phydev, - phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], - mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); - -- /* Enable WOL function */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL, -- 0, AT803X_WOL_EN); -- if (ret) -- return ret; -+ /* Enable WOL function for 1588 */ -+ if (phydev->drv->phy_id == ATH8031_PHY_ID) { -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ 0, AT803X_WOL_EN); -+ if (ret) -+ return ret; -+ } - /* Enable WOL interrupt */ - ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); - if (ret) - return ret; - } else { -- /* Disable WoL function */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL, -- AT803X_WOL_EN, 0); -- if (ret) -- return ret; -+ /* Disable WoL function for 1588 */ -+ if (phydev->drv->phy_id == ATH8031_PHY_ID) { -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ AT803X_WOL_EN, 0); -+ if (ret) -+ return ret; -+ } - /* Disable WOL interrupt */ - ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); - if (ret) -@@ -510,11 +515,11 @@ static void at803x_get_wol(struct phy_device *phydev, - wol->supported = WAKE_MAGIC; - wol->wolopts = 0; - -- value = phy_read_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL); -+ value = phy_read(phydev, AT803X_INTR_ENABLE); - if (value < 0) - return; - -- if (value & AT803X_WOL_EN) -+ if (value & AT803X_INTR_ENABLE_WOL) - wol->wolopts |= WAKE_MAGIC; - } - -@@ -825,11 +830,11 @@ static int at803x_parse_dt(struct phy_device *phydev) - if (ret < 0) - return ret; - -- priv->vddio = devm_regulator_get_optional(&phydev->mdio.dev, -- "vddio"); -- if (IS_ERR(priv->vddio)) { -+ ret = devm_regulator_get_enable_optional(&phydev->mdio.dev, -+ "vddio"); -+ if (ret) { - phydev_err(phydev, "failed to get VDDIO regulator\n"); -- return PTR_ERR(priv->vddio); -+ return ret; - } - - /* Only AR8031/8033 support 1000Base-X for SFP modules */ -@@ -857,23 +862,12 @@ static int at803x_probe(struct phy_device *phydev) - if (ret) - return ret; - -- if (priv->vddio) { -- ret = regulator_enable(priv->vddio); -- if (ret < 0) -- return ret; -- } -- - if (phydev->drv->phy_id == ATH8031_PHY_ID) { - int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); - int mode_cfg; -- struct ethtool_wolinfo wol = { -- .wolopts = 0, -- }; - -- if (ccr < 0) { -- ret = ccr; -- goto err; -- } -+ if (ccr < 0) -+ return ccr; - mode_cfg = ccr & AT803X_MODE_CFG_MASK; - - switch (mode_cfg) { -@@ -887,29 +881,17 @@ static int at803x_probe(struct phy_device *phydev) - break; - } - -- /* Disable WOL by default */ -- ret = at803x_set_wol(phydev, &wol); -- if (ret < 0) { -- phydev_err(phydev, "failed to disable WOL on probe: %d\n", ret); -- goto err; -- } -+ /* Disable WoL in 1588 register which is enabled -+ * by default -+ */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ AT803X_WOL_EN, 0); -+ if (ret) -+ return ret; - } - - return 0; -- --err: -- if (priv->vddio) -- regulator_disable(priv->vddio); -- -- return ret; --} -- --static void at803x_remove(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- -- if (priv->vddio) -- regulator_disable(priv->vddio); - } - - static int at803x_get_features(struct phy_device *phydev) -@@ -2022,7 +2004,6 @@ static struct phy_driver at803x_driver[] = { - .name = "Qualcomm Atheros AR8035", - .flags = PHY_POLL_CABLE_TEST, - .probe = at803x_probe, -- .remove = at803x_remove, - .config_aneg = at803x_config_aneg, - .config_init = at803x_config_init, - .soft_reset = genphy_soft_reset, -@@ -2044,7 +2025,6 @@ static struct phy_driver at803x_driver[] = { - .name = "Qualcomm Atheros AR8030", - .phy_id_mask = AT8030_PHY_ID_MASK, - .probe = at803x_probe, -- .remove = at803x_remove, - .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, - .set_wol = at803x_set_wol, -@@ -2060,7 +2040,6 @@ static struct phy_driver at803x_driver[] = { - .name = "Qualcomm Atheros AR8031/AR8033", - .flags = PHY_POLL_CABLE_TEST, - .probe = at803x_probe, -- .remove = at803x_remove, - .config_init = at803x_config_init, - .config_aneg = at803x_config_aneg, - .soft_reset = genphy_soft_reset, -@@ -2083,7 +2062,6 @@ static struct phy_driver at803x_driver[] = { - PHY_ID_MATCH_EXACT(ATH8032_PHY_ID), - .name = "Qualcomm Atheros AR8032", - .probe = at803x_probe, -- .remove = at803x_remove, - .flags = PHY_POLL_CABLE_TEST, - .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, -@@ -2099,7 +2077,6 @@ static struct phy_driver at803x_driver[] = { - PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), - .name = "Qualcomm Atheros AR9331 built-in PHY", - .probe = at803x_probe, -- .remove = at803x_remove, - .suspend = at803x_suspend, - .resume = at803x_resume, - .flags = PHY_POLL_CABLE_TEST, -@@ -2116,7 +2093,6 @@ static struct phy_driver at803x_driver[] = { - PHY_ID_MATCH_EXACT(QCA9561_PHY_ID), - .name = "Qualcomm Atheros QCA9561 built-in PHY", - .probe = at803x_probe, -- .remove = at803x_remove, - .suspend = at803x_suspend, - .resume = at803x_resume, - .flags = PHY_POLL_CABLE_TEST, -@@ -2182,7 +2158,6 @@ static struct phy_driver at803x_driver[] = { - .name = "Qualcomm QCA8081", - .flags = PHY_POLL_CABLE_TEST, - .probe = at803x_probe, -- .remove = at803x_remove, - .config_intr = at803x_config_intr, - .handle_interrupt = at803x_handle_interrupt, - .get_tunable = at803x_get_tunable, -diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c -index ad71c88c87e78..f9ad8902100f3 100644 ---- a/drivers/net/phy/broadcom.c -+++ b/drivers/net/phy/broadcom.c -@@ -486,6 +486,17 @@ static int bcm54xx_resume(struct phy_device *phydev) - return bcm54xx_config_init(phydev); - } - -+static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, -+ u16 val) -+{ -+ return -EOPNOTSUPP; -+} -+ - static int bcm54811_config_init(struct phy_device *phydev) - { - int err, reg; -@@ -981,6 +992,8 @@ static struct phy_driver broadcom_drivers[] = { - .get_strings = bcm_phy_get_strings, - .get_stats = bcm54xx_get_stats, - .probe = bcm54xx_phy_probe, -+ .read_mmd = bcm54810_read_mmd, -+ .write_mmd = bcm54810_write_mmd, - .config_init = bcm54xx_config_init, - .config_aneg = bcm5481_config_aneg, - .config_intr = bcm_phy_config_intr, -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 82f74f96eba29..944f76e6fc8eb 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3050,6 +3050,8 @@ static int phy_probe(struct device *dev) - goto out; - } - -+ phy_disable_interrupts(phydev); -+ - /* Start out supporting everything. Eventually, - * a controller will attach, and may modify one - * or both of these values -@@ -3137,16 +3139,6 @@ static int phy_remove(struct device *dev) - return 0; - } - --static void phy_shutdown(struct device *dev) --{ -- struct phy_device *phydev = to_phy_device(dev); -- -- if (phydev->state == PHY_READY || !phydev->attached_dev) -- return; -- -- phy_disable_interrupts(phydev); --} -- - /** - * phy_driver_register - register a phy_driver with the PHY layer - * @new_driver: new phy_driver to register -@@ -3180,7 +3172,6 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner) - new_driver->mdiodrv.driver.bus = &mdio_bus_type; - new_driver->mdiodrv.driver.probe = phy_probe; - new_driver->mdiodrv.driver.remove = phy_remove; -- new_driver->mdiodrv.driver.shutdown = phy_shutdown; - new_driver->mdiodrv.driver.owner = owner; - new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS; - -diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c -index 509ba706781ed..921ca59822b0f 100644 ---- a/drivers/net/team/team.c -+++ b/drivers/net/team/team.c -@@ -2200,7 +2200,9 @@ static void team_setup(struct net_device *dev) - - dev->hw_features = TEAM_VLAN_FEATURES | - NETIF_F_HW_VLAN_CTAG_RX | -- NETIF_F_HW_VLAN_CTAG_FILTER; -+ NETIF_F_HW_VLAN_CTAG_FILTER | -+ NETIF_F_HW_VLAN_STAG_RX | -+ NETIF_F_HW_VLAN_STAG_FILTER; - - dev->hw_features |= NETIF_F_GSO_ENCAP_ALL; - dev->features |= dev->hw_features; -diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c -index 075d5d42f5eb6..21d3461fb5d1c 100644 ---- a/drivers/net/virtio_net.c -+++ b/drivers/net/virtio_net.c -@@ -2504,7 +2504,7 @@ static void virtnet_init_default_rss(struct virtnet_info *vi) - vi->ctrl->rss.indirection_table[i] = indir_val; - } - -- vi->ctrl->rss.max_tx_vq = vi->curr_queue_pairs; -+ vi->ctrl->rss.max_tx_vq = vi->has_rss ? vi->curr_queue_pairs : 0; - vi->ctrl->rss.hash_key_length = vi->rss_key_size; - - netdev_rss_key_fill(vi->ctrl->rss.key, vi->rss_key_size); -@@ -3825,6 +3825,8 @@ static int virtnet_probe(struct virtio_device *vdev) - eth_hw_addr_set(dev, addr); - } else { - eth_hw_addr_random(dev); -+ dev_info(&vdev->dev, "Assigned random MAC address %pM\n", -+ dev->dev_addr); - } - - /* Set up our device-specific information */ -@@ -3940,8 +3942,6 @@ static int virtnet_probe(struct virtio_device *vdev) - if (vi->has_rss || vi->has_rss_hash_report) - virtnet_init_default_rss(vi); - -- _virtnet_set_queues(vi, vi->curr_queue_pairs); -- - /* serialize netdev register + virtio_device_ready() with ndo_open() */ - rtnl_lock(); - -@@ -3954,6 +3954,26 @@ static int virtnet_probe(struct virtio_device *vdev) - - virtio_device_ready(vdev); - -+ _virtnet_set_queues(vi, vi->curr_queue_pairs); -+ -+ /* a random MAC address has been assigned, notify the device. -+ * We don't fail probe if VIRTIO_NET_F_CTRL_MAC_ADDR is not there -+ * because many devices work fine without getting MAC explicitly -+ */ -+ if (!virtio_has_feature(vdev, VIRTIO_NET_F_MAC) && -+ virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) { -+ struct scatterlist sg; -+ -+ sg_init_one(&sg, dev->dev_addr, dev->addr_len); -+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC, -+ VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) { -+ pr_debug("virtio_net: setting MAC address failed\n"); -+ rtnl_unlock(); -+ err = -EINVAL; -+ goto free_unregister_netdev; -+ } -+ } -+ - rtnl_unlock(); - - err = virtnet_cpu_notif_add(vi); -diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c -index 1b6b437823d22..528e73ccfa43e 100644 ---- a/drivers/pci/controller/dwc/pcie-tegra194.c -+++ b/drivers/pci/controller/dwc/pcie-tegra194.c -@@ -224,6 +224,7 @@ - #define EP_STATE_ENABLED 1 - - static const unsigned int pcie_gen_freq[] = { -+ GEN1_CORE_CLK_FREQ, /* PCI_EXP_LNKSTA_CLS == 0; undefined */ - GEN1_CORE_CLK_FREQ, - GEN2_CORE_CLK_FREQ, - GEN3_CORE_CLK_FREQ, -@@ -455,7 +456,11 @@ static irqreturn_t tegra_pcie_ep_irq_thread(int irq, void *arg) - - speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) & - PCI_EXP_LNKSTA_CLS; -- clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]); -+ -+ if (speed >= ARRAY_SIZE(pcie_gen_freq)) -+ speed = 0; -+ -+ clk_set_rate(pcie->core_clk, pcie_gen_freq[speed]); - - if (pcie->of_data->has_ltr_req_fix) - return IRQ_HANDLED; -@@ -1016,7 +1021,11 @@ retry_link: - - speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) & - PCI_EXP_LNKSTA_CLS; -- clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]); -+ -+ if (speed >= ARRAY_SIZE(pcie_gen_freq)) -+ speed = 0; -+ -+ clk_set_rate(pcie->core_clk, pcie_gen_freq[speed]); - - tegra_pcie_enable_interrupts(pp); - -diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c -index ad1141fddb4cc..8bda75990bce5 100644 ---- a/drivers/pcmcia/rsrc_nonstatic.c -+++ b/drivers/pcmcia/rsrc_nonstatic.c -@@ -1053,6 +1053,8 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s) - q = p->next; - kfree(p); - } -+ -+ kfree(data); - } - - -diff --git a/drivers/soc/aspeed/aspeed-socinfo.c b/drivers/soc/aspeed/aspeed-socinfo.c -index 1ca140356a084..3f759121dc00a 100644 ---- a/drivers/soc/aspeed/aspeed-socinfo.c -+++ b/drivers/soc/aspeed/aspeed-socinfo.c -@@ -137,6 +137,7 @@ static int __init aspeed_socinfo_init(void) - - soc_dev = soc_device_register(attrs); - if (IS_ERR(soc_dev)) { -+ kfree(attrs->machine); - kfree(attrs->soc_id); - kfree(attrs->serial_number); - kfree(attrs); -diff --git a/drivers/soc/aspeed/aspeed-uart-routing.c b/drivers/soc/aspeed/aspeed-uart-routing.c -index ef8b24fd18518..59123e1f27acb 100644 ---- a/drivers/soc/aspeed/aspeed-uart-routing.c -+++ b/drivers/soc/aspeed/aspeed-uart-routing.c -@@ -524,7 +524,7 @@ static ssize_t aspeed_uart_routing_store(struct device *dev, - struct aspeed_uart_routing_selector *sel = to_routing_selector(attr); - int val; - -- val = match_string(sel->options, -1, buf); -+ val = __sysfs_match_string(sel->options, -1, buf); - if (val < 0) { - dev_err(dev, "invalid value \"%s\"\n", buf); - return -EINVAL; -diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c -index 4a6a3802d7e51..288aaa05d0071 100644 ---- a/drivers/thunderbolt/nhi.c -+++ b/drivers/thunderbolt/nhi.c -@@ -1479,6 +1479,8 @@ static struct pci_device_id nhi_ids[] = { - .driver_data = (kernel_ulong_t)&icl_nhi_ops }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL_P_NHI1), - .driver_data = (kernel_ulong_t)&icl_nhi_ops }, -+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) }, -+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) }, - - /* Any USB4 compliant host */ - { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_USB4, ~0) }, -diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h -index b0718020c6f59..0f029ce758825 100644 ---- a/drivers/thunderbolt/nhi.h -+++ b/drivers/thunderbolt/nhi.h -@@ -75,6 +75,10 @@ extern const struct tb_nhi_ops icl_nhi_ops; - #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE 0x15ef - #define PCI_DEVICE_ID_INTEL_ADL_NHI0 0x463e - #define PCI_DEVICE_ID_INTEL_ADL_NHI1 0x466d -+#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI 0x5781 -+#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI 0x5784 -+#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_80G_BRIDGE 0x5786 -+#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_40G_BRIDGE 0x57a4 - #define PCI_DEVICE_ID_INTEL_MTL_M_NHI0 0x7eb2 - #define PCI_DEVICE_ID_INTEL_MTL_P_NHI0 0x7ec2 - #define PCI_DEVICE_ID_INTEL_MTL_P_NHI1 0x7ec3 -diff --git a/drivers/thunderbolt/quirks.c b/drivers/thunderbolt/quirks.c -index 1157b8869bcca..8c2ee431fcde8 100644 ---- a/drivers/thunderbolt/quirks.c -+++ b/drivers/thunderbolt/quirks.c -@@ -74,6 +74,14 @@ static const struct tb_quirk tb_quirks[] = { - quirk_usb3_maximum_bandwidth }, - { 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI1, 0x0000, 0x0000, - quirk_usb3_maximum_bandwidth }, -+ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI, 0x0000, 0x0000, -+ quirk_usb3_maximum_bandwidth }, -+ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI, 0x0000, 0x0000, -+ quirk_usb3_maximum_bandwidth }, -+ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_80G_BRIDGE, 0x0000, 0x0000, -+ quirk_usb3_maximum_bandwidth }, -+ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_40G_BRIDGE, 0x0000, 0x0000, -+ quirk_usb3_maximum_bandwidth }, - /* - * CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms. - */ -diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c -index 9cc28197dbc45..edbd92435b41a 100644 ---- a/drivers/thunderbolt/retimer.c -+++ b/drivers/thunderbolt/retimer.c -@@ -187,6 +187,21 @@ static ssize_t nvm_authenticate_show(struct device *dev, - return ret; - } - -+static void tb_retimer_nvm_authenticate_status(struct tb_port *port, u32 *status) -+{ -+ int i; -+ -+ tb_port_dbg(port, "reading NVM authentication status of retimers\n"); -+ -+ /* -+ * Before doing anything else, read the authentication status. -+ * If the retimer has it set, store it for the new retimer -+ * device instance. -+ */ -+ for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) -+ usb4_port_retimer_nvm_authenticate_status(port, i, &status[i]); -+} -+ - static void tb_retimer_set_inbound_sbtx(struct tb_port *port) - { - int i; -@@ -455,18 +470,16 @@ int tb_retimer_scan(struct tb_port *port, bool add) - return ret; - - /* -- * Enable sideband channel for each retimer. We can do this -- * regardless whether there is device connected or not. -+ * Immediately after sending enumerate retimers read the -+ * authentication status of each retimer. - */ -- tb_retimer_set_inbound_sbtx(port); -+ tb_retimer_nvm_authenticate_status(port, status); - - /* -- * Before doing anything else, read the authentication status. -- * If the retimer has it set, store it for the new retimer -- * device instance. -+ * Enable sideband channel for each retimer. We can do this -+ * regardless whether there is device connected or not. - */ -- for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) -- usb4_port_retimer_nvm_authenticate_status(port, i, &status[i]); -+ tb_retimer_set_inbound_sbtx(port); - - for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) { - /* -diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c -index 59a559366b614..c1fa20a4e3420 100644 ---- a/drivers/tty/n_gsm.c -+++ b/drivers/tty/n_gsm.c -@@ -2481,12 +2481,13 @@ static void gsm_error(struct gsm_mux *gsm) - static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) - { - int i; -- struct gsm_dlci *dlci = gsm->dlci[0]; -+ struct gsm_dlci *dlci; - struct gsm_msg *txq, *ntxq; - - gsm->dead = true; - mutex_lock(&gsm->mutex); - -+ dlci = gsm->dlci[0]; - if (dlci) { - if (disc && dlci->state != DLCI_CLOSED) { - gsm_dlci_begin_close(dlci); -diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c -index acf578aa9930b..38760bd6e0c29 100644 ---- a/drivers/tty/serial/8250/8250_port.c -+++ b/drivers/tty/serial/8250/8250_port.c -@@ -3281,6 +3281,7 @@ void serial8250_init_port(struct uart_8250_port *up) - struct uart_port *port = &up->port; - - spin_lock_init(&port->lock); -+ port->pm = NULL; - port->ops = &serial8250_pops; - port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE); - -diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c -index f6d0ea2c6be4b..c5a9b89c4d313 100644 ---- a/drivers/tty/serial/fsl_lpuart.c -+++ b/drivers/tty/serial/fsl_lpuart.c -@@ -1125,8 +1125,8 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) - unsigned long sr = lpuart32_read(&sport->port, UARTSTAT); - - if (sr & (UARTSTAT_PE | UARTSTAT_FE)) { -- /* Read DR to clear the error flags */ -- lpuart32_read(&sport->port, UARTDATA); -+ /* Clear the error flags */ -+ lpuart32_write(&sport->port, sr, UARTSTAT); - - if (sr & UARTSTAT_PE) - sport->port.icount.parity++; -diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c -index 28edbaf7bb329..2a9c4058824a8 100644 ---- a/drivers/tty/serial/stm32-usart.c -+++ b/drivers/tty/serial/stm32-usart.c -@@ -1753,13 +1753,10 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) - struct uart_port *port = platform_get_drvdata(pdev); - struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -- int err; - u32 cr3; - - pm_runtime_get_sync(&pdev->dev); -- err = uart_remove_one_port(&stm32_usart_driver, port); -- if (err) -- return(err); -+ uart_remove_one_port(&stm32_usart_driver, port); - - pm_runtime_disable(&pdev->dev); - pm_runtime_set_suspended(&pdev->dev); -diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c -index 9ffcecd3058c1..60b4de0a4f76d 100644 ---- a/drivers/usb/chipidea/ci_hdrc_imx.c -+++ b/drivers/usb/chipidea/ci_hdrc_imx.c -@@ -70,6 +70,10 @@ static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = { - CI_HDRC_PMQOS, - }; - -+static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = { -+ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM, -+}; -+ - static const struct of_device_id ci_hdrc_imx_dt_ids[] = { - { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data}, - { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, -@@ -80,6 +84,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = { - { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data}, - { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data}, - { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data}, -+ { .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data}, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); -diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c -index bac0f5458cab9..2318c7906acdb 100644 ---- a/drivers/usb/chipidea/usbmisc_imx.c -+++ b/drivers/usb/chipidea/usbmisc_imx.c -@@ -135,7 +135,7 @@ - #define TXVREFTUNE0_MASK (0xf << 20) - - #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \ -- MX6_BM_ID_WAKEUP) -+ MX6_BM_ID_WAKEUP | MX6SX_BM_DPDM_WAKEUP_EN) - - struct usbmisc_ops { - /* It's called once when probe a usb device */ -diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c -index ea2c5b6cde8cd..3c51355ccc94d 100644 ---- a/drivers/usb/gadget/function/u_serial.c -+++ b/drivers/usb/gadget/function/u_serial.c -@@ -915,8 +915,11 @@ static void __gs_console_push(struct gs_console *cons) - } - - req->length = size; -+ -+ spin_unlock_irq(&cons->lock); - if (usb_ep_queue(ep, req, GFP_ATOMIC)) - req->length = 0; -+ spin_lock_irq(&cons->lock); - } - - static void gs_console_work(struct work_struct *work) -diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c -index dd1c6b2ca7c6f..e81865978299c 100644 ---- a/drivers/usb/gadget/function/uvc_video.c -+++ b/drivers/usb/gadget/function/uvc_video.c -@@ -386,6 +386,9 @@ static void uvcg_video_pump(struct work_struct *work) - struct uvc_buffer *buf; - unsigned long flags; - int ret; -+ bool buf_int; -+ /* video->max_payload_size is only set when using bulk transfer */ -+ bool is_bulk = video->max_payload_size; - - while (video->ep->enabled) { - /* -@@ -408,20 +411,35 @@ static void uvcg_video_pump(struct work_struct *work) - */ - spin_lock_irqsave(&queue->irqlock, flags); - buf = uvcg_queue_head(queue); -- if (buf == NULL) { -+ -+ if (buf != NULL) { -+ video->encode(req, video, buf); -+ /* Always interrupt for the last request of a video buffer */ -+ buf_int = buf->state == UVC_BUF_STATE_DONE; -+ } else if (!(queue->flags & UVC_QUEUE_DISCONNECTED) && !is_bulk) { -+ /* -+ * No video buffer available; the queue is still connected and -+ * we're traferring over ISOC. Queue a 0 length request to -+ * prevent missed ISOC transfers. -+ */ -+ req->length = 0; -+ buf_int = false; -+ } else { -+ /* -+ * Either queue has been disconnected or no video buffer -+ * available to bulk transfer. Either way, stop processing -+ * further. -+ */ - spin_unlock_irqrestore(&queue->irqlock, flags); - break; - } - -- video->encode(req, video, buf); -- - /* - * With usb3 we have more requests. This will decrease the - * interrupt load to a quarter but also catches the corner - * cases, which needs to be handled. - */ -- if (list_empty(&video->req_free) || -- buf->state == UVC_BUF_STATE_DONE || -+ if (list_empty(&video->req_free) || buf_int || - !(video->req_int_count % - DIV_ROUND_UP(video->uvc_num_requests, 4))) { - video->req_int_count = 0; -@@ -441,8 +459,7 @@ static void uvcg_video_pump(struct work_struct *work) - - /* Endpoint now owns the request */ - req = NULL; -- if (buf->state != UVC_BUF_STATE_DONE) -- video->req_int_count++; -+ video->req_int_count++; - } - - if (!req) -@@ -527,4 +544,3 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) - V4L2_BUF_TYPE_VIDEO_OUTPUT, &video->mutex); - return 0; - } -- -diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h b/drivers/vdpa/mlx5/core/mlx5_vdpa.h -index 25fc4120b618d..b53420e874acb 100644 ---- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h -+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h -@@ -31,6 +31,7 @@ struct mlx5_vdpa_mr { - struct list_head head; - unsigned long num_directs; - unsigned long num_klms; -+ /* state of dvq mr */ - bool initialized; - - /* serialize mkey creation and destruction */ -@@ -121,6 +122,7 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *io - int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, - unsigned int asid); - void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev); -+void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid); - - #define mlx5_vdpa_warn(__dev, format, ...) \ - dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, __func__, __LINE__, \ -diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c -index a4d7ee2339fa5..113aac0446de5 100644 ---- a/drivers/vdpa/mlx5/core/mr.c -+++ b/drivers/vdpa/mlx5/core/mr.c -@@ -491,15 +491,24 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr - } - } - --void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev) -+static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid) -+{ -+ if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid) -+ return; -+ -+ prune_iotlb(mvdev); -+} -+ -+static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid) - { - struct mlx5_vdpa_mr *mr = &mvdev->mr; - -- mutex_lock(&mr->mkey_mtx); -+ if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid) -+ return; -+ - if (!mr->initialized) -- goto out; -+ return; - -- prune_iotlb(mvdev); - if (mr->user_mr) - destroy_user_mr(mvdev, mr); - else -@@ -507,45 +516,79 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev) - - memset(mr, 0, sizeof(*mr)); - mr->initialized = false; --out: -+} -+ -+void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid) -+{ -+ struct mlx5_vdpa_mr *mr = &mvdev->mr; -+ -+ mutex_lock(&mr->mkey_mtx); -+ -+ _mlx5_vdpa_destroy_dvq_mr(mvdev, asid); -+ _mlx5_vdpa_destroy_cvq_mr(mvdev, asid); -+ - mutex_unlock(&mr->mkey_mtx); - } - --static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, -- struct vhost_iotlb *iotlb, unsigned int asid) -+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev) -+{ -+ mlx5_vdpa_destroy_mr_asid(mvdev, mvdev->group2asid[MLX5_VDPA_CVQ_GROUP]); -+ mlx5_vdpa_destroy_mr_asid(mvdev, mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]); -+} -+ -+static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev, -+ struct vhost_iotlb *iotlb, -+ unsigned int asid) -+{ -+ if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid) -+ return 0; -+ -+ return dup_iotlb(mvdev, iotlb); -+} -+ -+static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev, -+ struct vhost_iotlb *iotlb, -+ unsigned int asid) - { - struct mlx5_vdpa_mr *mr = &mvdev->mr; - int err; - -- if (mr->initialized) -+ if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid) - return 0; - -- if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) { -- if (iotlb) -- err = create_user_mr(mvdev, iotlb); -- else -- err = create_dma_mr(mvdev, mr); -+ if (mr->initialized) -+ return 0; - -- if (err) -- return err; -- } -+ if (iotlb) -+ err = create_user_mr(mvdev, iotlb); -+ else -+ err = create_dma_mr(mvdev, mr); - -- if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid) { -- err = dup_iotlb(mvdev, iotlb); -- if (err) -- goto out_err; -- } -+ if (err) -+ return err; - - mr->initialized = true; -+ -+ return 0; -+} -+ -+static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, -+ struct vhost_iotlb *iotlb, unsigned int asid) -+{ -+ int err; -+ -+ err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid); -+ if (err) -+ return err; -+ -+ err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid); -+ if (err) -+ goto out_err; -+ - return 0; - - out_err: -- if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) { -- if (iotlb) -- destroy_user_mr(mvdev, mr); -- else -- destroy_dma_mr(mvdev, mr); -- } -+ _mlx5_vdpa_destroy_dvq_mr(mvdev, asid); - - return err; - } -diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c -index daac3ab314785..bf99654371b35 100644 ---- a/drivers/vdpa/mlx5/net/mlx5_vnet.c -+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c -@@ -2406,7 +2406,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, - goto err_mr; - - teardown_driver(ndev); -- mlx5_vdpa_destroy_mr(mvdev); -+ mlx5_vdpa_destroy_mr_asid(mvdev, asid); - err = mlx5_vdpa_create_mr(mvdev, iotlb, asid); - if (err) - goto err_mr; -@@ -2422,7 +2422,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, - return 0; - - err_setup: -- mlx5_vdpa_destroy_mr(mvdev); -+ mlx5_vdpa_destroy_mr_asid(mvdev, asid); - err_mr: - return err; - } -diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c -index febdc99b51a7b..908b3f98ecbee 100644 ---- a/drivers/vdpa/vdpa.c -+++ b/drivers/vdpa/vdpa.c -@@ -1172,44 +1172,41 @@ static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = { - [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING }, - [VDPA_ATTR_DEV_NAME] = { .type = NLA_STRING }, - [VDPA_ATTR_DEV_NET_CFG_MACADDR] = NLA_POLICY_ETH_ADDR, -+ [VDPA_ATTR_DEV_NET_CFG_MAX_VQP] = { .type = NLA_U16 }, - /* virtio spec 1.1 section 5.1.4.1 for valid MTU range */ - [VDPA_ATTR_DEV_NET_CFG_MTU] = NLA_POLICY_MIN(NLA_U16, 68), -+ [VDPA_ATTR_DEV_QUEUE_INDEX] = { .type = NLA_U32 }, -+ [VDPA_ATTR_DEV_FEATURES] = { .type = NLA_U64 }, - }; - - static const struct genl_ops vdpa_nl_ops[] = { - { - .cmd = VDPA_CMD_MGMTDEV_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = vdpa_nl_cmd_mgmtdev_get_doit, - .dumpit = vdpa_nl_cmd_mgmtdev_get_dumpit, - }, - { - .cmd = VDPA_CMD_DEV_NEW, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = vdpa_nl_cmd_dev_add_set_doit, - .flags = GENL_ADMIN_PERM, - }, - { - .cmd = VDPA_CMD_DEV_DEL, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = vdpa_nl_cmd_dev_del_set_doit, - .flags = GENL_ADMIN_PERM, - }, - { - .cmd = VDPA_CMD_DEV_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = vdpa_nl_cmd_dev_get_doit, - .dumpit = vdpa_nl_cmd_dev_get_dumpit, - }, - { - .cmd = VDPA_CMD_DEV_CONFIG_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = vdpa_nl_cmd_dev_config_get_doit, - .dumpit = vdpa_nl_cmd_dev_config_get_dumpit, - }, - { - .cmd = VDPA_CMD_DEV_VSTATS_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = vdpa_nl_cmd_dev_stats_get_doit, - .flags = GENL_ADMIN_PERM, - }, -diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c -index 72f924ec4658d..edcd74cc4c0f7 100644 ---- a/drivers/vdpa/vdpa_user/vduse_dev.c -+++ b/drivers/vdpa/vdpa_user/vduse_dev.c -@@ -899,10 +899,10 @@ static void vduse_dev_irq_inject(struct work_struct *work) - { - struct vduse_dev *dev = container_of(work, struct vduse_dev, inject); - -- spin_lock_irq(&dev->irq_lock); -+ spin_lock_bh(&dev->irq_lock); - if (dev->config_cb.callback) - dev->config_cb.callback(dev->config_cb.private); -- spin_unlock_irq(&dev->irq_lock); -+ spin_unlock_bh(&dev->irq_lock); - } - - static void vduse_vq_irq_inject(struct work_struct *work) -@@ -910,10 +910,10 @@ static void vduse_vq_irq_inject(struct work_struct *work) - struct vduse_virtqueue *vq = container_of(work, - struct vduse_virtqueue, inject); - -- spin_lock_irq(&vq->irq_lock); -+ spin_lock_bh(&vq->irq_lock); - if (vq->ready && vq->cb.callback) - vq->cb.callback(vq->cb.private); -- spin_unlock_irq(&vq->irq_lock); -+ spin_unlock_bh(&vq->irq_lock); - } - - static int vduse_dev_queue_irq_work(struct vduse_dev *dev, -diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c -index 41e77de1ea82c..5c94abdb1ad6d 100644 ---- a/drivers/video/aperture.c -+++ b/drivers/video/aperture.c -@@ -332,15 +332,16 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na - primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - #endif - -+ if (primary) -+ sysfb_disable(); -+ - for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) { - if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) - continue; - - base = pci_resource_start(pdev, bar); - size = pci_resource_len(pdev, bar); -- ret = aperture_remove_conflicting_devices(base, size, primary, name); -- if (ret) -- return ret; -+ aperture_detach_devices(base, size); - } - - /* -diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c -index 4ff25dfc865d9..d3d643cf7506c 100644 ---- a/drivers/video/fbdev/hyperv_fb.c -+++ b/drivers/video/fbdev/hyperv_fb.c -@@ -995,13 +995,10 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) - struct pci_dev *pdev = NULL; - void __iomem *fb_virt; - int gen2vm = efi_enabled(EFI_BOOT); -+ resource_size_t base, size; - phys_addr_t paddr; - int ret; - -- info->apertures = alloc_apertures(1); -- if (!info->apertures) -- return -ENOMEM; -- - if (!gen2vm) { - pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, - PCI_DEVICE_ID_HYPERV_VIDEO, NULL); -@@ -1010,8 +1007,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) - return -ENODEV; - } - -- info->apertures->ranges[0].base = pci_resource_start(pdev, 0); -- info->apertures->ranges[0].size = pci_resource_len(pdev, 0); -+ base = pci_resource_start(pdev, 0); -+ size = pci_resource_len(pdev, 0); - - /* - * For Gen 1 VM, we can directly use the contiguous memory -@@ -1034,8 +1031,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) - } - pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n"); - } else { -- info->apertures->ranges[0].base = screen_info.lfb_base; -- info->apertures->ranges[0].size = screen_info.lfb_size; -+ base = screen_info.lfb_base; -+ size = screen_info.lfb_size; - } - - /* -@@ -1077,9 +1074,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) - info->screen_size = dio_fb_size; - - getmem_done: -- aperture_remove_conflicting_devices(info->apertures->ranges[0].base, -- info->apertures->ranges[0].size, -- false, KBUILD_MODNAME); -+ aperture_remove_conflicting_devices(base, size, false, KBUILD_MODNAME); - - if (gen2vm) { - /* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */ -diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c -index 51fbf02a03430..76b50b6c98ad9 100644 ---- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c -+++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c -@@ -519,7 +519,9 @@ static int mmphw_probe(struct platform_device *pdev) - "unable to get clk %s\n", mi->clk_name); - goto failed; - } -- clk_prepare_enable(ctrl->clk); -+ ret = clk_prepare_enable(ctrl->clk); -+ if (ret) -+ goto failed; - - /* init global regs */ - ctrl_set_default(ctrl); -diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c -index 3ff746e3f24aa..dec3cba884586 100644 ---- a/drivers/virtio/virtio_mmio.c -+++ b/drivers/virtio/virtio_mmio.c -@@ -590,9 +590,8 @@ static void virtio_mmio_release_dev(struct device *_d) - struct virtio_device *vdev = - container_of(_d, struct virtio_device, dev); - struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); -- struct platform_device *pdev = vm_dev->pdev; - -- devm_kfree(&pdev->dev, vm_dev); -+ kfree(vm_dev); - } - - /* Platform device */ -@@ -603,7 +602,7 @@ static int virtio_mmio_probe(struct platform_device *pdev) - unsigned long magic; - int rc; - -- vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL); -+ vm_dev = kzalloc(sizeof(*vm_dev), GFP_KERNEL); - if (!vm_dev) - return -ENOMEM; - -diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c -index 14f8d8d90920f..2bd3dc25cb030 100644 ---- a/drivers/watchdog/sp5100_tco.c -+++ b/drivers/watchdog/sp5100_tco.c -@@ -96,7 +96,7 @@ static enum tco_reg_layout tco_reg_layout(struct pci_dev *dev) - sp5100_tco_pci->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS && - sp5100_tco_pci->revision >= AMD_ZEN_SMBUS_PCI_REV) { - return efch_mmio; -- } else if (dev->vendor == PCI_VENDOR_ID_AMD && -+ } else if ((dev->vendor == PCI_VENDOR_ID_AMD || dev->vendor == PCI_VENDOR_ID_HYGON) && - ((dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && - dev->revision >= 0x41) || - (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS && -@@ -579,6 +579,8 @@ static const struct pci_device_id sp5100_tco_pci_tbl[] = { - PCI_ANY_ID, }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, PCI_ANY_ID, - PCI_ANY_ID, }, -+ { PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, PCI_ANY_ID, -+ PCI_ANY_ID, }, - { 0, }, /* End of list */ - }; - MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl); -diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c -index 3495bc775afa3..08017b180a10d 100644 ---- a/fs/btrfs/block-group.c -+++ b/fs/btrfs/block-group.c -@@ -1533,6 +1533,10 @@ void btrfs_mark_bg_unused(struct btrfs_block_group *bg) - btrfs_get_block_group(bg); - trace_btrfs_add_unused_block_group(bg); - list_add_tail(&bg->bg_list, &fs_info->unused_bgs); -+ } else if (!test_bit(BLOCK_GROUP_FLAG_NEW, &bg->runtime_flags)) { -+ /* Pull out the block group from the reclaim_bgs list. */ -+ trace_btrfs_add_unused_block_group(bg); -+ list_move_tail(&bg->bg_list, &fs_info->unused_bgs); - } - spin_unlock(&fs_info->unused_bgs_lock); - } -@@ -2493,6 +2497,7 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans) - next: - btrfs_delayed_refs_rsv_release(fs_info, 1); - list_del_init(&block_group->bg_list); -+ clear_bit(BLOCK_GROUP_FLAG_NEW, &block_group->runtime_flags); - } - btrfs_trans_release_chunk_metadata(trans); - } -@@ -2532,6 +2537,13 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran - if (!cache) - return ERR_PTR(-ENOMEM); - -+ /* -+ * Mark it as new before adding it to the rbtree of block groups or any -+ * list, so that no other task finds it and calls btrfs_mark_bg_unused() -+ * before the new flag is set. -+ */ -+ set_bit(BLOCK_GROUP_FLAG_NEW, &cache->runtime_flags); -+ - cache->length = size; - set_free_space_tree_thresholds(cache); - cache->used = bytes_used; -@@ -2540,7 +2552,7 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran - cache->global_root_id = calculate_global_root_id(fs_info, cache->start); - - if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) -- cache->needs_free_space = 1; -+ set_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &cache->runtime_flags); - - ret = btrfs_load_block_group_zone_info(cache, true); - if (ret) { -diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h -index debd42aeae0f1..47a2dcbfee255 100644 ---- a/fs/btrfs/block-group.h -+++ b/fs/btrfs/block-group.h -@@ -55,6 +55,15 @@ enum btrfs_block_group_flags { - BLOCK_GROUP_FLAG_CHUNK_ITEM_INSERTED, - BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, - BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, -+ /* Does the block group need to be added to the free space tree? */ -+ BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, -+ /* Indicate that the block group is placed on a sequential zone */ -+ BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, -+ /* -+ * Indicate that block group is in the list of new block groups of a -+ * transaction. -+ */ -+ BLOCK_GROUP_FLAG_NEW, - }; - - enum btrfs_caching_type { -@@ -204,15 +213,6 @@ struct btrfs_block_group { - /* Lock for free space tree operations. */ - struct mutex free_space_lock; - -- /* -- * Does the block group need to be added to the free space tree? -- * Protected by free_space_lock. -- */ -- int needs_free_space; -- -- /* Flag indicating this block group is placed on a sequential zone */ -- bool seq_zone; -- - /* - * Number of extents in this block group used for swap files. - * All accesses protected by the spinlock 'lock'. -diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c -index 4abbe4b352533..56d7580fdc3c4 100644 ---- a/fs/btrfs/extent_map.c -+++ b/fs/btrfs/extent_map.c -@@ -784,8 +784,6 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, - - if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) { - start = em_end; -- if (end != (u64)-1) -- len = start + len - em_end; - goto next; - } - -@@ -853,8 +851,8 @@ void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end, - if (!split) - goto remove_em; - } -- split->start = start + len; -- split->len = em_end - (start + len); -+ split->start = end; -+ split->len = em_end - end; - split->block_start = em->block_start; - split->flags = flags; - split->compress_type = em->compress_type; -diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c -index a207db9322264..6a44733a95e1c 100644 ---- a/fs/btrfs/free-space-tree.c -+++ b/fs/btrfs/free-space-tree.c -@@ -803,7 +803,7 @@ int __remove_from_free_space_tree(struct btrfs_trans_handle *trans, - u32 flags; - int ret; - -- if (block_group->needs_free_space) { -+ if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) { - ret = __add_block_group_free_space(trans, block_group, path); - if (ret) - return ret; -@@ -996,7 +996,7 @@ int __add_to_free_space_tree(struct btrfs_trans_handle *trans, - u32 flags; - int ret; - -- if (block_group->needs_free_space) { -+ if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) { - ret = __add_block_group_free_space(trans, block_group, path); - if (ret) - return ret; -@@ -1350,7 +1350,7 @@ static int __add_block_group_free_space(struct btrfs_trans_handle *trans, - { - int ret; - -- block_group->needs_free_space = 0; -+ clear_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags); - - ret = add_new_free_space_info(trans, block_group, path); - if (ret) -@@ -1372,7 +1372,7 @@ int add_block_group_free_space(struct btrfs_trans_handle *trans, - return 0; - - mutex_lock(&block_group->free_space_lock); -- if (!block_group->needs_free_space) -+ if (!test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) - goto out; - - path = btrfs_alloc_path(); -@@ -1405,7 +1405,7 @@ int remove_block_group_free_space(struct btrfs_trans_handle *trans, - if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE)) - return 0; - -- if (block_group->needs_free_space) { -+ if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) { - /* We never added this block group to the free space tree. */ - return 0; - } -diff --git a/fs/btrfs/tests/free-space-tree-tests.c b/fs/btrfs/tests/free-space-tree-tests.c -index 13734ed43bfcb..766117a76d742 100644 ---- a/fs/btrfs/tests/free-space-tree-tests.c -+++ b/fs/btrfs/tests/free-space-tree-tests.c -@@ -470,7 +470,7 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize, - } - cache->bitmap_low_thresh = 0; - cache->bitmap_high_thresh = (u32)-1; -- cache->needs_free_space = 1; -+ set_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &cache->runtime_flags); - cache->fs_info = root->fs_info; - - btrfs_init_dummy_trans(&trans, root->fs_info); -diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c -index 2e0832d70406c..567c5c010f931 100644 ---- a/fs/btrfs/volumes.c -+++ b/fs/btrfs/volumes.c -@@ -4652,8 +4652,7 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info) - } - } - -- BUG_ON(fs_info->balance_ctl || -- test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags)); -+ ASSERT(!test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags)); - atomic_dec(&fs_info->balance_cancel_req); - mutex_unlock(&fs_info->balance_mutex); - return 0; -diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c -index 836babd23db52..9bc7ac06c5177 100644 ---- a/fs/btrfs/zoned.c -+++ b/fs/btrfs/zoned.c -@@ -1436,7 +1436,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new) - } - - if (num_sequential > 0) -- cache->seq_zone = true; -+ set_bit(BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, &cache->runtime_flags); - - if (num_conventional > 0) { - /* Zone capacity is always zone size in emulation */ -@@ -1658,7 +1658,7 @@ bool btrfs_use_zone_append(struct btrfs_inode *inode, u64 start) - if (!cache) - return false; - -- ret = cache->seq_zone; -+ ret = !!test_bit(BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, &cache->runtime_flags); - btrfs_put_block_group(cache); - - return ret; -@@ -2177,7 +2177,8 @@ static void btrfs_zone_finish_endio_workfn(struct work_struct *work) - void btrfs_schedule_zone_finish_bg(struct btrfs_block_group *bg, - struct extent_buffer *eb) - { -- if (!bg->seq_zone || eb->start + eb->len * 2 <= bg->start + bg->zone_capacity) -+ if (!test_bit(BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, &bg->runtime_flags) || -+ eb->start + eb->len * 2 <= bg->start + bg->zone_capacity) - return; - - if (WARN_ON(bg->zone_finish_work.func == btrfs_zone_finish_endio_workfn)) { -diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c -index dcabe2783edfe..5399a9ea5b4f1 100644 ---- a/fs/ceph/mds_client.c -+++ b/fs/ceph/mds_client.c -@@ -645,6 +645,7 @@ bad: - err = -EIO; - out_bad: - pr_err("mds parse_reply err %d\n", err); -+ ceph_msg_dump(msg); - return err; - } - -@@ -3534,6 +3535,7 @@ static void handle_forward(struct ceph_mds_client *mdsc, - - bad: - pr_err("mdsc_handle_forward decode error err=%d\n", err); -+ ceph_msg_dump(msg); - } - - static int __decode_session_metadata(void **p, void *end, -@@ -5254,6 +5256,7 @@ void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg) - bad: - pr_err("error decoding fsmap %d. Shutting down mount.\n", err); - ceph_umount_begin(mdsc->fsc->sb); -+ ceph_msg_dump(msg); - err_out: - mutex_lock(&mdsc->mutex); - mdsc->mdsmap_err = err; -@@ -5322,6 +5325,7 @@ bad_unlock: - bad: - pr_err("error decoding mdsmap %d. Shutting down mount.\n", err); - ceph_umount_begin(mdsc->fsc->sb); -+ ceph_msg_dump(msg); - return; - } - -diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c -index 9d27aa8bd2bc6..44c564f0bc622 100644 ---- a/fs/gfs2/super.c -+++ b/fs/gfs2/super.c -@@ -981,7 +981,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) - { - struct gfs2_sbd *sdp = root->d_sb->s_fs_info; - struct gfs2_args *args = &sdp->sd_args; -- int val; -+ unsigned int logd_secs, statfs_slow, statfs_quantum, quota_quantum; -+ -+ spin_lock(&sdp->sd_tune.gt_spin); -+ logd_secs = sdp->sd_tune.gt_logd_secs; -+ quota_quantum = sdp->sd_tune.gt_quota_quantum; -+ statfs_quantum = sdp->sd_tune.gt_statfs_quantum; -+ statfs_slow = sdp->sd_tune.gt_statfs_slow; -+ spin_unlock(&sdp->sd_tune.gt_spin); - - if (is_ancestor(root, sdp->sd_master_dir)) - seq_puts(s, ",meta"); -@@ -1036,17 +1043,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) - } - if (args->ar_discard) - seq_puts(s, ",discard"); -- val = sdp->sd_tune.gt_logd_secs; -- if (val != 30) -- seq_printf(s, ",commit=%d", val); -- val = sdp->sd_tune.gt_statfs_quantum; -- if (val != 30) -- seq_printf(s, ",statfs_quantum=%d", val); -- else if (sdp->sd_tune.gt_statfs_slow) -+ if (logd_secs != 30) -+ seq_printf(s, ",commit=%d", logd_secs); -+ if (statfs_quantum != 30) -+ seq_printf(s, ",statfs_quantum=%d", statfs_quantum); -+ else if (statfs_slow) - seq_puts(s, ",statfs_quantum=0"); -- val = sdp->sd_tune.gt_quota_quantum; -- if (val != 60) -- seq_printf(s, ",quota_quantum=%d", val); -+ if (quota_quantum != 60) -+ seq_printf(s, ",quota_quantum=%d", quota_quantum); - if (args->ar_statfs_percent) - seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent); - if (args->ar_errors != GFS2_ERRORS_DEFAULT) { -diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c -index b1b476fb7229b..dda13e1f1b330 100644 ---- a/fs/ntfs3/frecord.c -+++ b/fs/ntfs3/frecord.c -@@ -874,6 +874,7 @@ int ni_create_attr_list(struct ntfs_inode *ni) - if (err) - goto out1; - -+ err = -EINVAL; - /* Call mi_remove_attr() in reverse order to keep pointers 'arr_move' valid. */ - while (to_free > 0) { - struct ATTRIB *b = arr_move[--nb]; -@@ -882,7 +883,8 @@ int ni_create_attr_list(struct ntfs_inode *ni) - - attr = mi_insert_attr(mi, b->type, Add2Ptr(b, name_off), - b->name_len, asize, name_off); -- WARN_ON(!attr); -+ if (!attr) -+ goto out1; - - mi_get_ref(mi, &le_b[nb]->ref); - le_b[nb]->id = attr->id; -@@ -892,17 +894,20 @@ int ni_create_attr_list(struct ntfs_inode *ni) - attr->id = le_b[nb]->id; - - /* Remove from primary record. */ -- WARN_ON(!mi_remove_attr(NULL, &ni->mi, b)); -+ if (!mi_remove_attr(NULL, &ni->mi, b)) -+ goto out1; - - if (to_free <= asize) - break; - to_free -= asize; -- WARN_ON(!nb); -+ if (!nb) -+ goto out1; - } - - attr = mi_insert_attr(&ni->mi, ATTR_LIST, NULL, 0, - lsize + SIZEOF_RESIDENT, SIZEOF_RESIDENT); -- WARN_ON(!attr); -+ if (!attr) -+ goto out1; - - attr->non_res = 0; - attr->flags = 0; -@@ -922,9 +927,10 @@ out1: - kfree(ni->attr_list.le); - ni->attr_list.le = NULL; - ni->attr_list.size = 0; -+ return err; - - out: -- return err; -+ return 0; - } - - /* -diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c -index b6e22bcb929ba..829b62d3bb889 100644 ---- a/fs/ntfs3/fsntfs.c -+++ b/fs/ntfs3/fsntfs.c -@@ -154,7 +154,7 @@ int ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes, - /* Check errors. */ - if ((fo & 1) || fo + fn * sizeof(short) > SECTOR_SIZE || !fn-- || - fn * SECTOR_SIZE > bytes) { -- return -EINVAL; /* Native chkntfs returns ok! */ -+ return -E_NTFS_CORRUPT; - } - - /* Get fixup pointer. */ -diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c -index 9e9a9ffd92958..495cfb37962fa 100644 ---- a/fs/ntfs3/index.c -+++ b/fs/ntfs3/index.c -@@ -1103,6 +1103,12 @@ ok: - *node = in; - - out: -+ if (err == -E_NTFS_CORRUPT) { -+ ntfs_inode_err(&ni->vfs_inode, "directory corrupted"); -+ ntfs_set_state(ni->mi.sbi, NTFS_DIRTY_ERROR); -+ err = -EINVAL; -+ } -+ - if (ib != in->index) - kfree(ib); - -diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h -index 24227b2e1b2b0..8c9abaf139e67 100644 ---- a/fs/ntfs3/ntfs_fs.h -+++ b/fs/ntfs3/ntfs_fs.h -@@ -53,6 +53,8 @@ enum utf16_endian; - #define E_NTFS_NONRESIDENT 556 - /* NTFS specific error code about punch hole. */ - #define E_NTFS_NOTALIGNED 557 -+/* NTFS specific error code when on-disk struct is corrupted. */ -+#define E_NTFS_CORRUPT 558 - - - /* sbi->flags */ -diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c -index af1e4b364ea8e..ba336c7280b85 100644 ---- a/fs/ntfs3/record.c -+++ b/fs/ntfs3/record.c -@@ -124,7 +124,7 @@ int mi_read(struct mft_inode *mi, bool is_mft) - struct rw_semaphore *rw_lock = NULL; - - if (is_mounted(sbi)) { -- if (!is_mft) { -+ if (!is_mft && mft_ni) { - rw_lock = &mft_ni->file.run_lock; - down_read(rw_lock); - } -@@ -148,7 +148,7 @@ int mi_read(struct mft_inode *mi, bool is_mft) - ni_lock(mft_ni); - down_write(rw_lock); - } -- err = attr_load_runs_vcn(mft_ni, ATTR_DATA, NULL, 0, &mft_ni->file.run, -+ err = attr_load_runs_vcn(mft_ni, ATTR_DATA, NULL, 0, run, - vbo >> sbi->cluster_bits); - if (rw_lock) { - up_write(rw_lock); -@@ -180,6 +180,12 @@ ok: - return 0; - - out: -+ if (err == -E_NTFS_CORRUPT) { -+ ntfs_err(sbi->sb, "mft corrupted"); -+ ntfs_set_state(sbi, NTFS_DIRTY_ERROR); -+ err = -EINVAL; -+ } -+ - return err; - } - -diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c -index 078df1e2dd18a..18d66497c42d1 100644 ---- a/fs/smb/client/cifsfs.c -+++ b/fs/smb/client/cifsfs.c -@@ -883,11 +883,11 @@ struct dentry * - cifs_smb3_do_mount(struct file_system_type *fs_type, - int flags, struct smb3_fs_context *old_ctx) - { -- int rc; -- struct super_block *sb = NULL; -- struct cifs_sb_info *cifs_sb = NULL; - struct cifs_mnt_data mnt_data; -+ struct cifs_sb_info *cifs_sb; -+ struct super_block *sb; - struct dentry *root; -+ int rc; - - /* - * Prints in Kernel / CIFS log the attempted mount operation -@@ -898,11 +898,9 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, - else - cifs_info("Attempting to mount %s\n", old_ctx->UNC); - -- cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); -- if (cifs_sb == NULL) { -- root = ERR_PTR(-ENOMEM); -- goto out; -- } -+ cifs_sb = kzalloc(sizeof(*cifs_sb), GFP_KERNEL); -+ if (!cifs_sb) -+ return ERR_PTR(-ENOMEM); - - cifs_sb->ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL); - if (!cifs_sb->ctx) { -@@ -945,10 +943,8 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, - - sb = sget(fs_type, cifs_match_super, cifs_set_super, flags, &mnt_data); - if (IS_ERR(sb)) { -- root = ERR_CAST(sb); - cifs_umount(cifs_sb); -- cifs_sb = NULL; -- goto out; -+ return ERR_CAST(sb); - } - - if (sb->s_root) { -@@ -979,13 +975,9 @@ out_super: - deactivate_locked_super(sb); - return root; - out: -- if (cifs_sb) { -- if (!sb || IS_ERR(sb)) { /* otherwise kill_sb will handle */ -- kfree(cifs_sb->prepath); -- smb3_cleanup_fs_context(cifs_sb->ctx); -- kfree(cifs_sb); -- } -- } -+ kfree(cifs_sb->prepath); -+ smb3_cleanup_fs_context(cifs_sb->ctx); -+ kfree(cifs_sb); - return root; - } - -diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c -index 27c6d14e369f1..0f3405e0f2e48 100644 ---- a/fs/smb/client/file.c -+++ b/fs/smb/client/file.c -@@ -4885,9 +4885,9 @@ static int cifs_readpage_worker(struct file *file, struct page *page, - - io_error: - kunmap(page); -- unlock_page(page); - - read_complete: -+ unlock_page(page); - return rc; - } - -@@ -5082,9 +5082,11 @@ void cifs_oplock_break(struct work_struct *work) - struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, - oplock_break); - struct inode *inode = d_inode(cfile->dentry); -+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsInodeInfo *cinode = CIFS_I(inode); -- struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); -- struct TCP_Server_Info *server = tcon->ses->server; -+ struct cifs_tcon *tcon; -+ struct TCP_Server_Info *server; -+ struct tcon_link *tlink; - int rc = 0; - bool purge_cache = false, oplock_break_cancelled; - __u64 persistent_fid, volatile_fid; -@@ -5093,6 +5095,12 @@ void cifs_oplock_break(struct work_struct *work) - wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, - TASK_UNINTERRUPTIBLE); - -+ tlink = cifs_sb_tlink(cifs_sb); -+ if (IS_ERR(tlink)) -+ goto out; -+ tcon = tlink_tcon(tlink); -+ server = tcon->ses->server; -+ - server->ops->downgrade_oplock(server, cinode, cfile->oplock_level, - cfile->oplock_epoch, &purge_cache); - -@@ -5142,18 +5150,19 @@ oplock_break_ack: - /* - * MS-SMB2 3.2.5.19.1 and 3.2.5.19.2 (and MS-CIFS 3.2.5.42) do not require - * an acknowledgment to be sent when the file has already been closed. -- * check for server null, since can race with kill_sb calling tree disconnect. - */ - spin_lock(&cinode->open_file_lock); -- if (tcon->ses && tcon->ses->server && !oplock_break_cancelled && -- !list_empty(&cinode->openFileList)) { -+ /* check list empty since can race with kill_sb calling tree disconnect */ -+ if (!oplock_break_cancelled && !list_empty(&cinode->openFileList)) { - spin_unlock(&cinode->open_file_lock); -- rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid, -- volatile_fid, net_fid, cinode); -+ rc = server->ops->oplock_response(tcon, persistent_fid, -+ volatile_fid, net_fid, cinode); - cifs_dbg(FYI, "Oplock release rc = %d\n", rc); - } else - spin_unlock(&cinode->open_file_lock); - -+ cifs_put_tlink(tlink); -+out: - cifs_done_oplock_break(cinode); - } - -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index 3ca593cdda76e..ba46156e32680 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -3841,6 +3841,12 @@ void smb2_reconnect_server(struct work_struct *work) - - spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { -+ spin_lock(&ses->ses_lock); -+ if (ses->ses_status == SES_EXITING) { -+ spin_unlock(&ses->ses_lock); -+ continue; -+ } -+ spin_unlock(&ses->ses_lock); - - tcon_selected = false; - -diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h -index 4df9e73a8bb5f..1d7d4cffaefc6 100644 ---- a/include/kvm/arm_vgic.h -+++ b/include/kvm/arm_vgic.h -@@ -429,6 +429,6 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq, - - int vgic_v4_load(struct kvm_vcpu *vcpu); - void vgic_v4_commit(struct kvm_vcpu *vcpu); --int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db); -+int vgic_v4_put(struct kvm_vcpu *vcpu); - - #endif /* __KVM_ARM_VGIC_H */ -diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h -index 2c8860e406bd8..0417360a6db9b 100644 ---- a/include/linux/iopoll.h -+++ b/include/linux/iopoll.h -@@ -53,6 +53,7 @@ - } \ - if (__sleep_us) \ - usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ -+ cpu_relax(); \ - } \ - (cond) ? 0 : -ETIMEDOUT; \ - }) -@@ -95,6 +96,7 @@ - } \ - if (__delay_us) \ - udelay(__delay_us); \ -+ cpu_relax(); \ - } \ - (cond) ? 0 : -ETIMEDOUT; \ - }) -diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h -index a960de68ac69e..6047058d67037 100644 ---- a/include/linux/virtio_net.h -+++ b/include/linux/virtio_net.h -@@ -148,6 +148,10 @@ retry: - if (gso_type & SKB_GSO_UDP) - nh_off -= thlen; - -+ /* Kernel has a special handling for GSO_BY_FRAGS. */ -+ if (gso_size == GSO_BY_FRAGS) -+ return -EINVAL; -+ - /* Too small packets are not really GSO ones. */ - if (skb->len - nh_off > gso_size) { - shinfo->gso_size = gso_size; -diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h -index bb9de6a899e07..d6c8eb2b52019 100644 ---- a/include/media/v4l2-mem2mem.h -+++ b/include/media/v4l2-mem2mem.h -@@ -593,7 +593,14 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, - static inline - unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) - { -- return m2m_ctx->out_q_ctx.num_rdy; -+ unsigned int num_buf_rdy; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); -+ num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy; -+ spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); -+ -+ return num_buf_rdy; - } - - /** -@@ -605,7 +612,14 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) - static inline - unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) - { -- return m2m_ctx->cap_q_ctx.num_rdy; -+ unsigned int num_buf_rdy; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); -+ num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy; -+ spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); -+ -+ return num_buf_rdy; - } - - /** -diff --git a/include/net/sock.h b/include/net/sock.h -index 1bbdddcf61542..699408944952c 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -1445,6 +1445,12 @@ static inline bool sk_has_memory_pressure(const struct sock *sk) - return sk->sk_prot->memory_pressure != NULL; - } - -+static inline bool sk_under_global_memory_pressure(const struct sock *sk) -+{ -+ return sk->sk_prot->memory_pressure && -+ !!*sk->sk_prot->memory_pressure; -+} -+ - static inline bool sk_under_memory_pressure(const struct sock *sk) - { - if (!sk->sk_prot->memory_pressure) -diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c -index b4526668072e7..27596f3b4aef3 100644 ---- a/kernel/dma/remap.c -+++ b/kernel/dma/remap.c -@@ -43,13 +43,13 @@ void *dma_common_contiguous_remap(struct page *page, size_t size, - void *vaddr; - int i; - -- pages = kmalloc_array(count, sizeof(struct page *), GFP_KERNEL); -+ pages = kvmalloc_array(count, sizeof(struct page *), GFP_KERNEL); - if (!pages) - return NULL; - for (i = 0; i < count; i++) - pages[i] = nth_page(page, i); - vaddr = vmap(pages, count, VM_DMA_COHERENT, prot); -- kfree(pages); -+ kvfree(pages); - - return vaddr; - } -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 5e5aea2360a87..612873ec2197f 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -4464,17 +4464,9 @@ static inline int util_fits_cpu(unsigned long util, - * - * For uclamp_max, we can tolerate a drop in performance level as the - * goal is to cap the task. So it's okay if it's getting less. -- * -- * In case of capacity inversion we should honour the inverted capacity -- * for both uclamp_min and uclamp_max all the time. - */ -- capacity_orig = cpu_in_capacity_inversion(cpu); -- if (capacity_orig) { -- capacity_orig_thermal = capacity_orig; -- } else { -- capacity_orig = capacity_orig_of(cpu); -- capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu); -- } -+ capacity_orig = capacity_orig_of(cpu); -+ capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu); - - /* - * We want to force a task to fit a cpu as implied by uclamp_max. -@@ -4549,8 +4541,8 @@ static inline int util_fits_cpu(unsigned long util, - * handle the case uclamp_min > uclamp_max. - */ - uclamp_min = min(uclamp_min, uclamp_max); -- if (util < uclamp_min && capacity_orig != SCHED_CAPACITY_SCALE) -- fits = fits && (uclamp_min <= capacity_orig_thermal); -+ if (fits && (util < uclamp_min) && (uclamp_min > capacity_orig_thermal)) -+ return -1; - - return fits; - } -@@ -4560,7 +4552,11 @@ static inline int task_fits_cpu(struct task_struct *p, int cpu) - unsigned long uclamp_min = uclamp_eff_value(p, UCLAMP_MIN); - unsigned long uclamp_max = uclamp_eff_value(p, UCLAMP_MAX); - unsigned long util = task_util_est(p); -- return util_fits_cpu(util, uclamp_min, uclamp_max, cpu); -+ /* -+ * Return true only if the cpu fully fits the task requirements, which -+ * include the utilization but also the performance hints. -+ */ -+ return (util_fits_cpu(util, uclamp_min, uclamp_max, cpu) > 0); - } - - static inline void update_misfit_status(struct task_struct *p, struct rq *rq) -@@ -6043,6 +6039,7 @@ static inline bool cpu_overutilized(int cpu) - unsigned long rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN); - unsigned long rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX); - -+ /* Return true only if the utilization doesn't fit CPU's capacity */ - return !util_fits_cpu(cpu_util_cfs(cpu), rq_util_min, rq_util_max, cpu); - } - -@@ -6836,6 +6833,7 @@ static int - select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target) - { - unsigned long task_util, util_min, util_max, best_cap = 0; -+ int fits, best_fits = 0; - int cpu, best_cpu = -1; - struct cpumask *cpus; - -@@ -6851,12 +6849,28 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target) - - if (!available_idle_cpu(cpu) && !sched_idle_cpu(cpu)) - continue; -- if (util_fits_cpu(task_util, util_min, util_max, cpu)) -+ -+ fits = util_fits_cpu(task_util, util_min, util_max, cpu); -+ -+ /* This CPU fits with all requirements */ -+ if (fits > 0) - return cpu; -+ /* -+ * Only the min performance hint (i.e. uclamp_min) doesn't fit. -+ * Look for the CPU with best capacity. -+ */ -+ else if (fits < 0) -+ cpu_cap = capacity_orig_of(cpu) - thermal_load_avg(cpu_rq(cpu)); - -- if (cpu_cap > best_cap) { -+ /* -+ * First, select CPU which fits better (-1 being better than 0). -+ * Then, select the one with best capacity at same level. -+ */ -+ if ((fits < best_fits) || -+ ((fits == best_fits) && (cpu_cap > best_cap))) { - best_cap = cpu_cap; - best_cpu = cpu; -+ best_fits = fits; - } - } - -@@ -6869,7 +6883,11 @@ static inline bool asym_fits_cpu(unsigned long util, - int cpu) - { - if (sched_asym_cpucap_active()) -- return util_fits_cpu(util, util_min, util_max, cpu); -+ /* -+ * Return true only if the cpu fully fits the task requirements -+ * which include the utilization and the performance hints. -+ */ -+ return (util_fits_cpu(util, util_min, util_max, cpu) > 0); - - return true; - } -@@ -7236,6 +7254,9 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - unsigned long p_util_max = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MAX) : 1024; - struct root_domain *rd = this_rq()->rd; - int cpu, best_energy_cpu, target = -1; -+ int prev_fits = -1, best_fits = -1; -+ unsigned long best_thermal_cap = 0; -+ unsigned long prev_thermal_cap = 0; - struct sched_domain *sd; - struct perf_domain *pd; - struct energy_env eenv; -@@ -7271,6 +7292,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - unsigned long prev_spare_cap = 0; - int max_spare_cap_cpu = -1; - unsigned long base_energy; -+ int fits, max_fits = -1; - - cpumask_and(cpus, perf_domain_span(pd), cpu_online_mask); - -@@ -7320,7 +7342,9 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - util_min = max(rq_util_min, p_util_min); - util_max = max(rq_util_max, p_util_max); - } -- if (!util_fits_cpu(util, util_min, util_max, cpu)) -+ -+ fits = util_fits_cpu(util, util_min, util_max, cpu); -+ if (!fits) - continue; - - lsub_positive(&cpu_cap, util); -@@ -7328,7 +7352,9 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - if (cpu == prev_cpu) { - /* Always use prev_cpu as a candidate. */ - prev_spare_cap = cpu_cap; -- } else if (cpu_cap > max_spare_cap) { -+ prev_fits = fits; -+ } else if ((fits > max_fits) || -+ ((fits == max_fits) && (cpu_cap > max_spare_cap))) { - /* - * Find the CPU with the maximum spare capacity - * among the remaining CPUs in the performance -@@ -7336,6 +7362,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - */ - max_spare_cap = cpu_cap; - max_spare_cap_cpu = cpu; -+ max_fits = fits; - } - } - -@@ -7354,26 +7381,50 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - if (prev_delta < base_energy) - goto unlock; - prev_delta -= base_energy; -+ prev_thermal_cap = cpu_thermal_cap; - best_delta = min(best_delta, prev_delta); - } - - /* Evaluate the energy impact of using max_spare_cap_cpu. */ - if (max_spare_cap_cpu >= 0 && max_spare_cap > prev_spare_cap) { -+ /* Current best energy cpu fits better */ -+ if (max_fits < best_fits) -+ continue; -+ -+ /* -+ * Both don't fit performance hint (i.e. uclamp_min) -+ * but best energy cpu has better capacity. -+ */ -+ if ((max_fits < 0) && -+ (cpu_thermal_cap <= best_thermal_cap)) -+ continue; -+ - cur_delta = compute_energy(&eenv, pd, cpus, p, - max_spare_cap_cpu); - /* CPU utilization has changed */ - if (cur_delta < base_energy) - goto unlock; - cur_delta -= base_energy; -- if (cur_delta < best_delta) { -- best_delta = cur_delta; -- best_energy_cpu = max_spare_cap_cpu; -- } -+ -+ /* -+ * Both fit for the task but best energy cpu has lower -+ * energy impact. -+ */ -+ if ((max_fits > 0) && (best_fits > 0) && -+ (cur_delta >= best_delta)) -+ continue; -+ -+ best_delta = cur_delta; -+ best_energy_cpu = max_spare_cap_cpu; -+ best_fits = max_fits; -+ best_thermal_cap = cpu_thermal_cap; - } - } - rcu_read_unlock(); - -- if (best_delta < prev_delta) -+ if ((best_fits > prev_fits) || -+ ((best_fits > 0) && (best_delta < prev_delta)) || -+ ((best_fits < 0) && (best_thermal_cap > prev_thermal_cap))) - target = best_energy_cpu; - - return target; -@@ -8870,82 +8921,16 @@ static unsigned long scale_rt_capacity(int cpu) - - static void update_cpu_capacity(struct sched_domain *sd, int cpu) - { -- unsigned long capacity_orig = arch_scale_cpu_capacity(cpu); - unsigned long capacity = scale_rt_capacity(cpu); - struct sched_group *sdg = sd->groups; -- struct rq *rq = cpu_rq(cpu); - -- rq->cpu_capacity_orig = capacity_orig; -+ cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(cpu); - - if (!capacity) - capacity = 1; - -- rq->cpu_capacity = capacity; -- -- /* -- * Detect if the performance domain is in capacity inversion state. -- * -- * Capacity inversion happens when another perf domain with equal or -- * lower capacity_orig_of() ends up having higher capacity than this -- * domain after subtracting thermal pressure. -- * -- * We only take into account thermal pressure in this detection as it's -- * the only metric that actually results in *real* reduction of -- * capacity due to performance points (OPPs) being dropped/become -- * unreachable due to thermal throttling. -- * -- * We assume: -- * * That all cpus in a perf domain have the same capacity_orig -- * (same uArch). -- * * Thermal pressure will impact all cpus in this perf domain -- * equally. -- */ -- if (sched_energy_enabled()) { -- unsigned long inv_cap = capacity_orig - thermal_load_avg(rq); -- struct perf_domain *pd; -- -- rcu_read_lock(); -- -- pd = rcu_dereference(rq->rd->pd); -- rq->cpu_capacity_inverted = 0; -- -- for (; pd; pd = pd->next) { -- struct cpumask *pd_span = perf_domain_span(pd); -- unsigned long pd_cap_orig, pd_cap; -- -- /* We can't be inverted against our own pd */ -- if (cpumask_test_cpu(cpu_of(rq), pd_span)) -- continue; -- -- cpu = cpumask_any(pd_span); -- pd_cap_orig = arch_scale_cpu_capacity(cpu); -- -- if (capacity_orig < pd_cap_orig) -- continue; -- -- /* -- * handle the case of multiple perf domains have the -- * same capacity_orig but one of them is under higher -- * thermal pressure. We record it as capacity -- * inversion. -- */ -- if (capacity_orig == pd_cap_orig) { -- pd_cap = pd_cap_orig - thermal_load_avg(cpu_rq(cpu)); -- -- if (pd_cap > inv_cap) { -- rq->cpu_capacity_inverted = inv_cap; -- break; -- } -- } else if (pd_cap_orig > inv_cap) { -- rq->cpu_capacity_inverted = inv_cap; -- break; -- } -- } -- -- rcu_read_unlock(); -- } -- -- trace_sched_cpu_capacity_tp(rq); -+ cpu_rq(cpu)->cpu_capacity = capacity; -+ trace_sched_cpu_capacity_tp(cpu_rq(cpu)); - - sdg->sgc->capacity = capacity; - sdg->sgc->min_capacity = capacity; -@@ -10183,24 +10168,23 @@ static struct sched_group *find_busiest_group(struct lb_env *env) - */ - update_sd_lb_stats(env, &sds); - -- if (sched_energy_enabled()) { -- struct root_domain *rd = env->dst_rq->rd; -- -- if (rcu_dereference(rd->pd) && !READ_ONCE(rd->overutilized)) -- goto out_balanced; -- } -- -- local = &sds.local_stat; -- busiest = &sds.busiest_stat; -- - /* There is no busy sibling group to pull tasks from */ - if (!sds.busiest) - goto out_balanced; - -+ busiest = &sds.busiest_stat; -+ - /* Misfit tasks should be dealt with regardless of the avg load */ - if (busiest->group_type == group_misfit_task) - goto force_balance; - -+ if (sched_energy_enabled()) { -+ struct root_domain *rd = env->dst_rq->rd; -+ -+ if (rcu_dereference(rd->pd) && !READ_ONCE(rd->overutilized)) -+ goto out_balanced; -+ } -+ - /* ASYM feature bypasses nice load balance check */ - if (busiest->group_type == group_asym_packing) - goto force_balance; -@@ -10213,6 +10197,7 @@ static struct sched_group *find_busiest_group(struct lb_env *env) - if (busiest->group_type == group_imbalanced) - goto force_balance; - -+ local = &sds.local_stat; - /* - * If the local group is busier than the selected busiest group - * don't try and pull any tasks. -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index 5f18460f62f0f..d6d488e8eb554 100644 ---- a/kernel/sched/sched.h -+++ b/kernel/sched/sched.h -@@ -1041,7 +1041,6 @@ struct rq { - - unsigned long cpu_capacity; - unsigned long cpu_capacity_orig; -- unsigned long cpu_capacity_inverted; - - struct balance_callback *balance_callback; - -@@ -2879,24 +2878,6 @@ static inline unsigned long capacity_orig_of(int cpu) - return cpu_rq(cpu)->cpu_capacity_orig; - } - --/* -- * Returns inverted capacity if the CPU is in capacity inversion state. -- * 0 otherwise. -- * -- * Capacity inversion detection only considers thermal impact where actual -- * performance points (OPPs) gets dropped. -- * -- * Capacity inversion state happens when another performance domain that has -- * equal or lower capacity_orig_of() becomes effectively larger than the perf -- * domain this CPU belongs to due to thermal pressure throttling it hard. -- * -- * See comment in update_cpu_capacity(). -- */ --static inline unsigned long cpu_in_capacity_inversion(int cpu) --{ -- return cpu_rq(cpu)->cpu_capacity_inverted; --} -- - /** - * enum cpu_util_type - CPU utilization type - * @FREQUENCY_UTIL: Utilization used to select frequency -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index c49ed619a64dd..de55107aef5d5 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -544,6 +544,7 @@ struct trace_buffer { - unsigned flags; - int cpus; - atomic_t record_disabled; -+ atomic_t resizing; - cpumask_var_t cpumask; - - struct lock_class_key *reader_lock_key; -@@ -2173,7 +2174,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, - - /* prevent another thread from changing buffer sizes */ - mutex_lock(&buffer->mutex); -- -+ atomic_inc(&buffer->resizing); - - if (cpu_id == RING_BUFFER_ALL_CPUS) { - /* -@@ -2312,6 +2313,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, - atomic_dec(&buffer->record_disabled); - } - -+ atomic_dec(&buffer->resizing); - mutex_unlock(&buffer->mutex); - return 0; - -@@ -2332,6 +2334,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, - } - } - out_err_unlock: -+ atomic_dec(&buffer->resizing); - mutex_unlock(&buffer->mutex); - return err; - } -@@ -5539,6 +5542,15 @@ int ring_buffer_swap_cpu(struct trace_buffer *buffer_a, - if (local_read(&cpu_buffer_b->committing)) - goto out_dec; - -+ /* -+ * When resize is in progress, we cannot swap it because -+ * it will mess the state of the cpu buffer. -+ */ -+ if (atomic_read(&buffer_a->resizing)) -+ goto out_dec; -+ if (atomic_read(&buffer_b->resizing)) -+ goto out_dec; -+ - buffer_a->buffers[cpu] = cpu_buffer_b; - buffer_b->buffers[cpu] = cpu_buffer_a; - -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 709af9631be45..af33c5a4166d4 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -1885,9 +1885,10 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) - * place on this CPU. We fail to record, but we reset - * the max trace buffer (no one writes directly to it) - * and flag that it failed. -+ * Another reason is resize is in progress. - */ - trace_array_printk_buf(tr->max_buffer.buffer, _THIS_IP_, -- "Failed to swap buffers due to commit in progress\n"); -+ "Failed to swap buffers due to commit or resize in progress\n"); - } - - WARN_ON_ONCE(ret && ret != -EAGAIN && ret != -EBUSY); -diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index d3ffa0fd49e57..c38ec6efec0f7 100644 ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -1581,9 +1581,37 @@ static inline void destroy_compound_gigantic_page(struct page *page, - unsigned int order) { } - #endif - -+static inline void __clear_hugetlb_destructor(struct hstate *h, -+ struct page *page) -+{ -+ lockdep_assert_held(&hugetlb_lock); -+ -+ /* -+ * Very subtle -+ * -+ * For non-gigantic pages set the destructor to the normal compound -+ * page dtor. This is needed in case someone takes an additional -+ * temporary ref to the page, and freeing is delayed until they drop -+ * their reference. -+ * -+ * For gigantic pages set the destructor to the null dtor. This -+ * destructor will never be called. Before freeing the gigantic -+ * page destroy_compound_gigantic_folio will turn the folio into a -+ * simple group of pages. After this the destructor does not -+ * apply. -+ * -+ */ -+ if (hstate_is_gigantic(h)) -+ set_compound_page_dtor(page, NULL_COMPOUND_DTOR); -+ else -+ set_compound_page_dtor(page, COMPOUND_PAGE_DTOR); -+} -+ - /* -- * Remove hugetlb page from lists, and update dtor so that page appears -- * as just a compound page. -+ * Remove hugetlb page from lists. -+ * If vmemmap exists for the page, update dtor so that the page appears -+ * as just a compound page. Otherwise, wait until after allocating vmemmap -+ * to update dtor. - * - * A reference is held on the page, except in the case of demote. - * -@@ -1614,31 +1642,19 @@ static void __remove_hugetlb_page(struct hstate *h, struct page *page, - } - - /* -- * Very subtle -- * -- * For non-gigantic pages set the destructor to the normal compound -- * page dtor. This is needed in case someone takes an additional -- * temporary ref to the page, and freeing is delayed until they drop -- * their reference. -- * -- * For gigantic pages set the destructor to the null dtor. This -- * destructor will never be called. Before freeing the gigantic -- * page destroy_compound_gigantic_page will turn the compound page -- * into a simple group of pages. After this the destructor does not -- * apply. -- * -- * This handles the case where more than one ref is held when and -- * after update_and_free_page is called. -- * -- * In the case of demote we do not ref count the page as it will soon -- * be turned into a page of smaller size. -+ * We can only clear the hugetlb destructor after allocating vmemmap -+ * pages. Otherwise, someone (memory error handling) may try to write -+ * to tail struct pages. -+ */ -+ if (!HPageVmemmapOptimized(page)) -+ __clear_hugetlb_destructor(h, page); -+ -+ /* -+ * In the case of demote we do not ref count the page as it will soon -+ * be turned into a page of smaller size. - */ - if (!demote) - set_page_refcounted(page); -- if (hstate_is_gigantic(h)) -- set_compound_page_dtor(page, NULL_COMPOUND_DTOR); -- else -- set_compound_page_dtor(page, COMPOUND_PAGE_DTOR); - - h->nr_huge_pages--; - h->nr_huge_pages_node[nid]--; -@@ -1706,6 +1722,7 @@ static void __update_and_free_page(struct hstate *h, struct page *page) - { - int i; - struct page *subpage; -+ bool clear_dtor = HPageVmemmapOptimized(page); - - if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported()) - return; -@@ -1736,6 +1753,16 @@ static void __update_and_free_page(struct hstate *h, struct page *page) - if (unlikely(PageHWPoison(page))) - hugetlb_clear_page_hwpoison(page); - -+ /* -+ * If vmemmap pages were allocated above, then we need to clear the -+ * hugetlb destructor under the hugetlb lock. -+ */ -+ if (clear_dtor) { -+ spin_lock_irq(&hugetlb_lock); -+ __clear_hugetlb_destructor(h, page); -+ spin_unlock_irq(&hugetlb_lock); -+ } -+ - for (i = 0; i < pages_per_huge_page(h); i++) { - subpage = nth_page(page, i); - subpage->flags &= ~(1 << PG_locked | 1 << PG_error | -diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c -index d03941cace2c4..37f755c9a1b70 100644 ---- a/mm/zsmalloc.c -+++ b/mm/zsmalloc.c -@@ -33,8 +33,7 @@ - /* - * lock ordering: - * page_lock -- * pool->migrate_lock -- * class->lock -+ * pool->lock - * zspage->lock - */ - -@@ -192,7 +191,6 @@ static const int fullness_threshold_frac = 4; - static size_t huge_class_size; - - struct size_class { -- spinlock_t lock; - struct list_head fullness_list[NR_ZS_FULLNESS]; - /* - * Size of objects stored in this class. Must be multiple -@@ -247,8 +245,8 @@ struct zs_pool { - #ifdef CONFIG_COMPACTION - struct work_struct free_work; - #endif -- /* protect page/zspage migration */ -- rwlock_t migrate_lock; -+ spinlock_t lock; -+ atomic_t compaction_in_progress; - }; - - struct zspage { -@@ -355,7 +353,7 @@ static void cache_free_zspage(struct zs_pool *pool, struct zspage *zspage) - kmem_cache_free(pool->zspage_cachep, zspage); - } - --/* class->lock(which owns the handle) synchronizes races */ -+/* pool->lock(which owns the handle) synchronizes races */ - static void record_obj(unsigned long handle, unsigned long obj) - { - *(unsigned long *)handle = obj; -@@ -452,7 +450,7 @@ static __maybe_unused int is_first_page(struct page *page) - return PagePrivate(page); - } - --/* Protected by class->lock */ -+/* Protected by pool->lock */ - static inline int get_zspage_inuse(struct zspage *zspage) - { - return zspage->inuse; -@@ -597,13 +595,13 @@ static int zs_stats_size_show(struct seq_file *s, void *v) - if (class->index != i) - continue; - -- spin_lock(&class->lock); -+ spin_lock(&pool->lock); - class_almost_full = zs_stat_get(class, CLASS_ALMOST_FULL); - class_almost_empty = zs_stat_get(class, CLASS_ALMOST_EMPTY); - obj_allocated = zs_stat_get(class, OBJ_ALLOCATED); - obj_used = zs_stat_get(class, OBJ_USED); - freeable = zs_can_compact(class); -- spin_unlock(&class->lock); -+ spin_unlock(&pool->lock); - - objs_per_zspage = class->objs_per_zspage; - pages_used = obj_allocated / objs_per_zspage * -@@ -916,7 +914,7 @@ static void __free_zspage(struct zs_pool *pool, struct size_class *class, - - get_zspage_mapping(zspage, &class_idx, &fg); - -- assert_spin_locked(&class->lock); -+ assert_spin_locked(&pool->lock); - - VM_BUG_ON(get_zspage_inuse(zspage)); - VM_BUG_ON(fg != ZS_EMPTY); -@@ -1247,19 +1245,19 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, - BUG_ON(in_interrupt()); - - /* It guarantees it can get zspage from handle safely */ -- read_lock(&pool->migrate_lock); -+ spin_lock(&pool->lock); - obj = handle_to_obj(handle); - obj_to_location(obj, &page, &obj_idx); - zspage = get_zspage(page); - - /* -- * migration cannot move any zpages in this zspage. Here, class->lock -+ * migration cannot move any zpages in this zspage. Here, pool->lock - * is too heavy since callers would take some time until they calls - * zs_unmap_object API so delegate the locking from class to zspage - * which is smaller granularity. - */ - migrate_read_lock(zspage); -- read_unlock(&pool->migrate_lock); -+ spin_unlock(&pool->lock); - - class = zspage_class(pool, zspage); - off = (class->size * obj_idx) & ~PAGE_MASK; -@@ -1412,8 +1410,8 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp) - size += ZS_HANDLE_SIZE; - class = pool->size_class[get_size_class_index(size)]; - -- /* class->lock effectively protects the zpage migration */ -- spin_lock(&class->lock); -+ /* pool->lock effectively protects the zpage migration */ -+ spin_lock(&pool->lock); - zspage = find_get_zspage(class); - if (likely(zspage)) { - obj = obj_malloc(pool, zspage, handle); -@@ -1421,12 +1419,12 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp) - fix_fullness_group(class, zspage); - record_obj(handle, obj); - class_stat_inc(class, OBJ_USED, 1); -- spin_unlock(&class->lock); -+ spin_unlock(&pool->lock); - - return handle; - } - -- spin_unlock(&class->lock); -+ spin_unlock(&pool->lock); - - zspage = alloc_zspage(pool, class, gfp); - if (!zspage) { -@@ -1434,7 +1432,7 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp) - return (unsigned long)ERR_PTR(-ENOMEM); - } - -- spin_lock(&class->lock); -+ spin_lock(&pool->lock); - obj = obj_malloc(pool, zspage, handle); - newfg = get_fullness_group(class, zspage); - insert_zspage(class, zspage, newfg); -@@ -1447,7 +1445,7 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp) - - /* We completely set up zspage so mark them as movable */ - SetZsPageMovable(pool, zspage); -- spin_unlock(&class->lock); -+ spin_unlock(&pool->lock); - - return handle; - } -@@ -1491,16 +1489,14 @@ void zs_free(struct zs_pool *pool, unsigned long handle) - return; - - /* -- * The pool->migrate_lock protects the race with zpage's migration -+ * The pool->lock protects the race with zpage's migration - * so it's safe to get the page from handle. - */ -- read_lock(&pool->migrate_lock); -+ spin_lock(&pool->lock); - obj = handle_to_obj(handle); - obj_to_page(obj, &f_page); - zspage = get_zspage(f_page); - class = zspage_class(pool, zspage); -- spin_lock(&class->lock); -- read_unlock(&pool->migrate_lock); - - obj_free(class->size, obj); - class_stat_dec(class, OBJ_USED, 1); -@@ -1510,7 +1506,7 @@ void zs_free(struct zs_pool *pool, unsigned long handle) - - free_zspage(pool, class, zspage); - out: -- spin_unlock(&class->lock); -+ spin_unlock(&pool->lock); - cache_free_handle(pool, handle); - } - EXPORT_SYMBOL_GPL(zs_free); -@@ -1821,6 +1817,7 @@ static void replace_sub_page(struct size_class *class, struct zspage *zspage, - - static bool zs_page_isolate(struct page *page, isolate_mode_t mode) - { -+ struct zs_pool *pool; - struct zspage *zspage; - - /* -@@ -1831,9 +1828,10 @@ static bool zs_page_isolate(struct page *page, isolate_mode_t mode) - VM_BUG_ON_PAGE(PageIsolated(page), page); - - zspage = get_zspage(page); -- migrate_write_lock(zspage); -+ pool = zspage->pool; -+ spin_lock(&pool->lock); - inc_zspage_isolation(zspage); -- migrate_write_unlock(zspage); -+ spin_unlock(&pool->lock); - - return true; - } -@@ -1867,16 +1865,12 @@ static int zs_page_migrate(struct page *newpage, struct page *page, - pool = zspage->pool; - - /* -- * The pool migrate_lock protects the race between zpage migration -+ * The pool's lock protects the race between zpage migration - * and zs_free. - */ -- write_lock(&pool->migrate_lock); -+ spin_lock(&pool->lock); - class = zspage_class(pool, zspage); - -- /* -- * the class lock protects zpage alloc/free in the zspage. -- */ -- spin_lock(&class->lock); - /* the migrate_write_lock protects zpage access via zs_map_object */ - migrate_write_lock(zspage); - -@@ -1904,13 +1898,12 @@ static int zs_page_migrate(struct page *newpage, struct page *page, - kunmap_atomic(s_addr); - - replace_sub_page(class, zspage, newpage, page); -+ dec_zspage_isolation(zspage); - /* - * Since we complete the data copy and set up new zspage structure, -- * it's okay to release migration_lock. -+ * it's okay to release the pool's lock. - */ -- write_unlock(&pool->migrate_lock); -- spin_unlock(&class->lock); -- dec_zspage_isolation(zspage); -+ spin_unlock(&pool->lock); - migrate_write_unlock(zspage); - - get_page(newpage); -@@ -1927,15 +1920,17 @@ static int zs_page_migrate(struct page *newpage, struct page *page, - - static void zs_page_putback(struct page *page) - { -+ struct zs_pool *pool; - struct zspage *zspage; - - VM_BUG_ON_PAGE(!PageMovable(page), page); - VM_BUG_ON_PAGE(!PageIsolated(page), page); - - zspage = get_zspage(page); -- migrate_write_lock(zspage); -+ pool = zspage->pool; -+ spin_lock(&pool->lock); - dec_zspage_isolation(zspage); -- migrate_write_unlock(zspage); -+ spin_unlock(&pool->lock); - } - - static const struct movable_operations zsmalloc_mops = { -@@ -1964,9 +1959,9 @@ static void async_free_zspage(struct work_struct *work) - if (class->index != i) - continue; - -- spin_lock(&class->lock); -+ spin_lock(&pool->lock); - list_splice_init(&class->fullness_list[ZS_EMPTY], &free_pages); -- spin_unlock(&class->lock); -+ spin_unlock(&pool->lock); - } - - list_for_each_entry_safe(zspage, tmp, &free_pages, list) { -@@ -1976,9 +1971,9 @@ static void async_free_zspage(struct work_struct *work) - get_zspage_mapping(zspage, &class_idx, &fullness); - VM_BUG_ON(fullness != ZS_EMPTY); - class = pool->size_class[class_idx]; -- spin_lock(&class->lock); -+ spin_lock(&pool->lock); - __free_zspage(pool, class, zspage); -- spin_unlock(&class->lock); -+ spin_unlock(&pool->lock); - } - }; - -@@ -2039,10 +2034,11 @@ static unsigned long __zs_compact(struct zs_pool *pool, - struct zspage *dst_zspage = NULL; - unsigned long pages_freed = 0; - -- /* protect the race between zpage migration and zs_free */ -- write_lock(&pool->migrate_lock); -- /* protect zpage allocation/free */ -- spin_lock(&class->lock); -+ /* -+ * protect the race between zpage migration and zs_free -+ * as well as zpage allocation/free -+ */ -+ spin_lock(&pool->lock); - while ((src_zspage = isolate_zspage(class, true))) { - /* protect someone accessing the zspage(i.e., zs_map_object) */ - migrate_write_lock(src_zspage); -@@ -2067,7 +2063,7 @@ static unsigned long __zs_compact(struct zs_pool *pool, - putback_zspage(class, dst_zspage); - migrate_write_unlock(dst_zspage); - dst_zspage = NULL; -- if (rwlock_is_contended(&pool->migrate_lock)) -+ if (spin_is_contended(&pool->lock)) - break; - } - -@@ -2084,11 +2080,9 @@ static unsigned long __zs_compact(struct zs_pool *pool, - pages_freed += class->pages_per_zspage; - } else - migrate_write_unlock(src_zspage); -- spin_unlock(&class->lock); -- write_unlock(&pool->migrate_lock); -+ spin_unlock(&pool->lock); - cond_resched(); -- write_lock(&pool->migrate_lock); -- spin_lock(&class->lock); -+ spin_lock(&pool->lock); - } - - if (src_zspage) { -@@ -2096,8 +2090,7 @@ static unsigned long __zs_compact(struct zs_pool *pool, - migrate_write_unlock(src_zspage); - } - -- spin_unlock(&class->lock); -- write_unlock(&pool->migrate_lock); -+ spin_unlock(&pool->lock); - - return pages_freed; - } -@@ -2108,6 +2101,15 @@ unsigned long zs_compact(struct zs_pool *pool) - struct size_class *class; - unsigned long pages_freed = 0; - -+ /* -+ * Pool compaction is performed under pool->lock so it is basically -+ * single-threaded. Having more than one thread in __zs_compact() -+ * will increase pool->lock contention, which will impact other -+ * zsmalloc operations that need pool->lock. -+ */ -+ if (atomic_xchg(&pool->compaction_in_progress, 1)) -+ return 0; -+ - for (i = ZS_SIZE_CLASSES - 1; i >= 0; i--) { - class = pool->size_class[i]; - if (class->index != i) -@@ -2115,6 +2117,7 @@ unsigned long zs_compact(struct zs_pool *pool) - pages_freed += __zs_compact(pool, class); - } - atomic_long_add(pages_freed, &pool->stats.pages_compacted); -+ atomic_set(&pool->compaction_in_progress, 0); - - return pages_freed; - } -@@ -2200,7 +2203,8 @@ struct zs_pool *zs_create_pool(const char *name) - return NULL; - - init_deferred_free(pool); -- rwlock_init(&pool->migrate_lock); -+ spin_lock_init(&pool->lock); -+ atomic_set(&pool->compaction_in_progress, 0); - - pool->name = kstrdup(name, GFP_KERNEL); - if (!pool->name) -@@ -2271,7 +2275,6 @@ struct zs_pool *zs_create_pool(const char *name) - class->index = i; - class->pages_per_zspage = pages_per_zspage; - class->objs_per_zspage = objs_per_zspage; -- spin_lock_init(&class->lock); - pool->size_class[i] = class; - for (fullness = ZS_EMPTY; fullness < NR_ZS_FULLNESS; - fullness++) -diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c -index 02fc9961464cf..a7899857aee5d 100644 ---- a/net/bluetooth/l2cap_core.c -+++ b/net/bluetooth/l2cap_core.c -@@ -6375,9 +6375,14 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn, - if (!chan) - goto done; - -+ chan = l2cap_chan_hold_unless_zero(chan); -+ if (!chan) -+ goto done; -+ - l2cap_chan_lock(chan); - l2cap_chan_del(chan, ECONNREFUSED); - l2cap_chan_unlock(chan); -+ l2cap_chan_put(chan); - - done: - mutex_unlock(&conn->chan_lock); -diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c -index 89c94f3e96bc3..d2e8565d0b33f 100644 ---- a/net/bluetooth/mgmt.c -+++ b/net/bluetooth/mgmt.c -@@ -7277,7 +7277,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err) - - bt_dev_dbg(hdev, "err %d", err); - -- memcpy(&rp.addr, &cp->addr.bdaddr, sizeof(rp.addr)); -+ memcpy(&rp.addr, &cp->addr, sizeof(rp.addr)); - - status = mgmt_status(err); - if (status == MGMT_STATUS_SUCCESS) { -diff --git a/net/core/sock.c b/net/core/sock.c -index 3b5304f084ef3..509773919d302 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -3099,7 +3099,7 @@ void __sk_mem_reduce_allocated(struct sock *sk, int amount) - if (mem_cgroup_sockets_enabled && sk->sk_memcg) - mem_cgroup_uncharge_skmem(sk->sk_memcg, amount); - -- if (sk_under_memory_pressure(sk) && -+ if (sk_under_global_memory_pressure(sk) && - (sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0))) - sk_leave_memory_pressure(sk); - } -diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c -index 8c2bd1d9ddce3..615c1dcf3a28e 100644 ---- a/net/ipv4/ip_vti.c -+++ b/net/ipv4/ip_vti.c -@@ -287,12 +287,12 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) - - switch (skb->protocol) { - case htons(ETH_P_IP): -- xfrm_decode_session(skb, &fl, AF_INET); - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); -+ xfrm_decode_session(skb, &fl, AF_INET); - break; - case htons(ETH_P_IPV6): -- xfrm_decode_session(skb, &fl, AF_INET6); - memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); -+ xfrm_decode_session(skb, &fl, AF_INET6); - break; - default: - goto tx_err; -diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c -index 0b5d0a2867a8c..cf354c29ec123 100644 ---- a/net/ipv4/tcp_timer.c -+++ b/net/ipv4/tcp_timer.c -@@ -586,7 +586,9 @@ out_reset_timer: - tcp_stream_is_thin(tp) && - icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) { - icsk->icsk_backoff = 0; -- icsk->icsk_rto = min(__tcp_set_rto(tp), TCP_RTO_MAX); -+ icsk->icsk_rto = clamp(__tcp_set_rto(tp), -+ tcp_rto_min(sk), -+ TCP_RTO_MAX); - } else { - /* Use normal (exponential) backoff */ - icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c -index 151337d7f67b4..cb71463bbbabd 100644 ---- a/net/ipv6/ip6_vti.c -+++ b/net/ipv6/ip6_vti.c -@@ -570,12 +570,12 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) - vti6_addr_conflict(t, ipv6_hdr(skb))) - goto tx_err; - -- xfrm_decode_session(skb, &fl, AF_INET6); - memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); -+ xfrm_decode_session(skb, &fl, AF_INET6); - break; - case htons(ETH_P_IP): -- xfrm_decode_session(skb, &fl, AF_INET); - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); -+ xfrm_decode_session(skb, &fl, AF_INET); - break; - default: - goto tx_err; -diff --git a/net/key/af_key.c b/net/key/af_key.c -index 8c21de50eadf8..8a8f2429d5d99 100644 ---- a/net/key/af_key.c -+++ b/net/key/af_key.c -@@ -1848,9 +1848,9 @@ static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_ms - if (ext_hdrs[SADB_X_EXT_FILTER - 1]) { - struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1]; - -- if ((xfilter->sadb_x_filter_splen >= -+ if ((xfilter->sadb_x_filter_splen > - (sizeof(xfrm_address_t) << 3)) || -- (xfilter->sadb_x_filter_dplen >= -+ (xfilter->sadb_x_filter_dplen > - (sizeof(xfrm_address_t) << 3))) { - mutex_unlock(&pfk->dump_lock); - return -EINVAL; -diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c -index 03af6a2ffd567..17a1b731a76b1 100644 ---- a/net/netfilter/ipvs/ip_vs_ctl.c -+++ b/net/netfilter/ipvs/ip_vs_ctl.c -@@ -1798,6 +1798,7 @@ static int - proc_do_sync_threshold(struct ctl_table *table, int write, - void *buffer, size_t *lenp, loff_t *ppos) - { -+ struct netns_ipvs *ipvs = table->extra2; - int *valp = table->data; - int val[2]; - int rc; -@@ -1807,6 +1808,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write, - .mode = table->mode, - }; - -+ mutex_lock(&ipvs->sync_mutex); - memcpy(val, valp, sizeof(val)); - rc = proc_dointvec(&tmp, write, buffer, lenp, ppos); - if (write) { -@@ -1816,6 +1818,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write, - else - memcpy(valp, val, sizeof(val)); - } -+ mutex_unlock(&ipvs->sync_mutex); - return rc; - } - -@@ -4080,6 +4083,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs) - ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD; - ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD; - tbl[idx].data = &ipvs->sysctl_sync_threshold; -+ tbl[idx].extra2 = ipvs; - tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold); - ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD; - tbl[idx++].data = &ipvs->sysctl_sync_refresh_period; -diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c -index 895e0ca542994..7247af51bdfc4 100644 ---- a/net/netfilter/nf_conntrack_proto_sctp.c -+++ b/net/netfilter/nf_conntrack_proto_sctp.c -@@ -49,8 +49,8 @@ static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = { - [SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS, - [SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS, - [SCTP_CONNTRACK_ESTABLISHED] = 210 SECS, -- [SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000, -- [SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000, -+ [SCTP_CONNTRACK_SHUTDOWN_SENT] = 3 SECS, -+ [SCTP_CONNTRACK_SHUTDOWN_RECD] = 3 SECS, - [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS, - [SCTP_CONNTRACK_HEARTBEAT_SENT] = 30 SECS, - }; -@@ -105,7 +105,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = { - { - /* ORIGINAL */ - /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS */ --/* init */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCW}, -+/* init */ {sCL, sCL, sCW, sCE, sES, sCL, sCL, sSA, sCW}, - /* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL}, - /* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL}, - /* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL}, -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index f6e6273838859..4c2df7af73f76 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -6874,6 +6874,7 @@ static int nft_set_catchall_flush(const struct nft_ctx *ctx, - ret = __nft_set_catchall_flush(ctx, set, &elem); - if (ret < 0) - break; -+ nft_set_elem_change_active(ctx->net, set, ext); - } - - return ret; -diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c -index e65a83328b554..cf9a1ae87d9b1 100644 ---- a/net/netfilter/nft_dynset.c -+++ b/net/netfilter/nft_dynset.c -@@ -191,6 +191,9 @@ static int nft_dynset_init(const struct nft_ctx *ctx, - if (IS_ERR(set)) - return PTR_ERR(set); - -+ if (set->flags & NFT_SET_OBJECT) -+ return -EOPNOTSUPP; -+ - if (set->ops->update == NULL) - return -EOPNOTSUPP; - -diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c -index a81829c10feab..32cfd0a84b0e2 100644 ---- a/net/netfilter/nft_set_pipapo.c -+++ b/net/netfilter/nft_set_pipapo.c -@@ -1665,6 +1665,17 @@ static void nft_pipapo_commit(const struct nft_set *set) - priv->clone = new_clone; - } - -+static bool nft_pipapo_transaction_mutex_held(const struct nft_set *set) -+{ -+#ifdef CONFIG_PROVE_LOCKING -+ const struct net *net = read_pnet(&set->net); -+ -+ return lockdep_is_held(&nft_pernet(net)->commit_mutex); -+#else -+ return true; -+#endif -+} -+ - static void nft_pipapo_abort(const struct nft_set *set) - { - struct nft_pipapo *priv = nft_set_priv(set); -@@ -1673,7 +1684,7 @@ static void nft_pipapo_abort(const struct nft_set *set) - if (!priv->dirty) - return; - -- m = rcu_dereference(priv->match); -+ m = rcu_dereference_protected(priv->match, nft_pipapo_transaction_mutex_held(set)); - - new_clone = pipapo_clone(m); - if (IS_ERR(new_clone)) -diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c -index 5920fdca12875..3c7b245354096 100644 ---- a/net/openvswitch/datapath.c -+++ b/net/openvswitch/datapath.c -@@ -1806,7 +1806,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) - parms.port_no = OVSP_LOCAL; - parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID]; - parms.desired_ifindex = a[OVS_DP_ATTR_IFINDEX] -- ? nla_get_u32(a[OVS_DP_ATTR_IFINDEX]) : 0; -+ ? nla_get_s32(a[OVS_DP_ATTR_IFINDEX]) : 0; - - /* So far only local changes have been made, now need the lock. */ - ovs_lock(); -@@ -2026,7 +2026,7 @@ static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = { - [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 }, - [OVS_DP_ATTR_MASKS_CACHE_SIZE] = NLA_POLICY_RANGE(NLA_U32, 0, - PCPU_MIN_UNIT_SIZE / sizeof(struct mask_cache_entry)), -- [OVS_DP_ATTR_IFINDEX] = {.type = NLA_U32 }, -+ [OVS_DP_ATTR_IFINDEX] = NLA_POLICY_MIN(NLA_S32, 0), - }; - - static const struct genl_small_ops dp_datapath_genl_ops[] = { -@@ -2276,7 +2276,7 @@ restart: - parms.port_no = port_no; - parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID]; - parms.desired_ifindex = a[OVS_VPORT_ATTR_IFINDEX] -- ? nla_get_u32(a[OVS_VPORT_ATTR_IFINDEX]) : 0; -+ ? nla_get_s32(a[OVS_VPORT_ATTR_IFINDEX]) : 0; - - vport = new_vport(&parms); - err = PTR_ERR(vport); -@@ -2513,7 +2513,7 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = { - [OVS_VPORT_ATTR_TYPE] = { .type = NLA_U32 }, - [OVS_VPORT_ATTR_UPCALL_PID] = { .type = NLA_UNSPEC }, - [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, -- [OVS_VPORT_ATTR_IFINDEX] = { .type = NLA_U32 }, -+ [OVS_VPORT_ATTR_IFINDEX] = NLA_POLICY_MIN(NLA_S32, 0), - [OVS_VPORT_ATTR_NETNSID] = { .type = NLA_S32 }, - }; - -diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c -index 5712a5297bd01..84219c5121bc2 100644 ---- a/net/smc/af_smc.c -+++ b/net/smc/af_smc.c -@@ -379,8 +379,8 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock, - sk->sk_state = SMC_INIT; - sk->sk_destruct = smc_destruct; - sk->sk_protocol = protocol; -- WRITE_ONCE(sk->sk_sndbuf, READ_ONCE(net->smc.sysctl_wmem)); -- WRITE_ONCE(sk->sk_rcvbuf, READ_ONCE(net->smc.sysctl_rmem)); -+ WRITE_ONCE(sk->sk_sndbuf, 2 * READ_ONCE(net->smc.sysctl_wmem)); -+ WRITE_ONCE(sk->sk_rcvbuf, 2 * READ_ONCE(net->smc.sysctl_rmem)); - smc = smc_sk(sk); - INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work); - INIT_WORK(&smc->connect_work, smc_connect_work); -diff --git a/net/smc/smc.h b/net/smc/smc.h -index 5ed765ea0c731..1d36720fc019c 100644 ---- a/net/smc/smc.h -+++ b/net/smc/smc.h -@@ -161,7 +161,7 @@ struct smc_connection { - - struct smc_buf_desc *sndbuf_desc; /* send buffer descriptor */ - struct smc_buf_desc *rmb_desc; /* RMBE descriptor */ -- int rmbe_size_short;/* compressed notation */ -+ int rmbe_size_comp; /* compressed notation */ - int rmbe_update_limit; - /* lower limit for consumer - * cursor update -diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c -index dfb9797f7bc63..9b8999e2afca5 100644 ---- a/net/smc/smc_clc.c -+++ b/net/smc/smc_clc.c -@@ -1002,7 +1002,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc, - clc->hdr.typev1 = SMC_TYPE_D; - clc->d0.gid = conn->lgr->smcd->local_gid; - clc->d0.token = conn->rmb_desc->token; -- clc->d0.dmbe_size = conn->rmbe_size_short; -+ 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) { -@@ -1045,7 +1045,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc, - clc->r0.qp_mtu = min(link->path_mtu, link->peer_mtu); - break; - } -- clc->r0.rmbe_size = conn->rmbe_size_short; -+ clc->r0.rmbe_size = conn->rmbe_size_comp; - clc->r0.rmb_dma_addr = conn->rmb_desc->is_vm ? - cpu_to_be64((uintptr_t)conn->rmb_desc->cpu_addr) : - cpu_to_be64((u64)sg_dma_address -diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c -index f82f43573a159..c676d92af7b7d 100644 ---- a/net/smc/smc_core.c -+++ b/net/smc/smc_core.c -@@ -852,8 +852,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) - lgr->freeing = 0; - lgr->vlan_id = ini->vlan_id; - refcount_set(&lgr->refcnt, 1); /* set lgr refcnt to 1 */ -- mutex_init(&lgr->sndbufs_lock); -- mutex_init(&lgr->rmbs_lock); -+ init_rwsem(&lgr->sndbufs_lock); -+ init_rwsem(&lgr->rmbs_lock); - rwlock_init(&lgr->conns_lock); - for (i = 0; i < SMC_RMBE_SIZES; i++) { - INIT_LIST_HEAD(&lgr->sndbufs[i]); -@@ -1095,7 +1095,7 @@ err_out: - static void smcr_buf_unuse(struct smc_buf_desc *buf_desc, bool is_rmb, - struct smc_link_group *lgr) - { -- struct mutex *lock; /* lock buffer list */ -+ struct rw_semaphore *lock; /* lock buffer list */ - int rc; - - if (is_rmb && buf_desc->is_conf_rkey && !list_empty(&lgr->list)) { -@@ -1115,9 +1115,9 @@ static void smcr_buf_unuse(struct smc_buf_desc *buf_desc, bool is_rmb, - /* buf registration failed, reuse not possible */ - lock = is_rmb ? &lgr->rmbs_lock : - &lgr->sndbufs_lock; -- mutex_lock(lock); -+ down_write(lock); - list_del(&buf_desc->list); -- mutex_unlock(lock); -+ up_write(lock); - - smc_buf_free(lgr, is_rmb, buf_desc); - } else { -@@ -1220,15 +1220,16 @@ static void smcr_buf_unmap_lgr(struct smc_link *lnk) - int i; - - for (i = 0; i < SMC_RMBE_SIZES; i++) { -- mutex_lock(&lgr->rmbs_lock); -+ down_write(&lgr->rmbs_lock); - list_for_each_entry_safe(buf_desc, bf, &lgr->rmbs[i], list) - smcr_buf_unmap_link(buf_desc, true, lnk); -- mutex_unlock(&lgr->rmbs_lock); -- mutex_lock(&lgr->sndbufs_lock); -+ up_write(&lgr->rmbs_lock); -+ -+ down_write(&lgr->sndbufs_lock); - list_for_each_entry_safe(buf_desc, bf, &lgr->sndbufs[i], - list) - smcr_buf_unmap_link(buf_desc, false, lnk); -- mutex_unlock(&lgr->sndbufs_lock); -+ up_write(&lgr->sndbufs_lock); - } - } - -@@ -1986,19 +1987,19 @@ int smc_uncompress_bufsize(u8 compressed) - * buffer size; if not available, return NULL - */ - static struct smc_buf_desc *smc_buf_get_slot(int compressed_bufsize, -- struct mutex *lock, -+ struct rw_semaphore *lock, - struct list_head *buf_list) - { - struct smc_buf_desc *buf_slot; - -- mutex_lock(lock); -+ down_read(lock); - list_for_each_entry(buf_slot, buf_list, list) { - if (cmpxchg(&buf_slot->used, 0, 1) == 0) { -- mutex_unlock(lock); -+ up_read(lock); - return buf_slot; - } - } -- mutex_unlock(lock); -+ up_read(lock); - return NULL; - } - -@@ -2107,13 +2108,13 @@ int smcr_link_reg_buf(struct smc_link *link, struct smc_buf_desc *buf_desc) - return 0; - } - --static int _smcr_buf_map_lgr(struct smc_link *lnk, struct mutex *lock, -+static int _smcr_buf_map_lgr(struct smc_link *lnk, struct rw_semaphore *lock, - struct list_head *lst, bool is_rmb) - { - struct smc_buf_desc *buf_desc, *bf; - int rc = 0; - -- mutex_lock(lock); -+ down_write(lock); - list_for_each_entry_safe(buf_desc, bf, lst, list) { - if (!buf_desc->used) - continue; -@@ -2122,7 +2123,7 @@ static int _smcr_buf_map_lgr(struct smc_link *lnk, struct mutex *lock, - goto out; - } - out: -- mutex_unlock(lock); -+ up_write(lock); - return rc; - } - -@@ -2155,37 +2156,37 @@ int smcr_buf_reg_lgr(struct smc_link *lnk) - int i, rc = 0; - - /* reg all RMBs for a new link */ -- mutex_lock(&lgr->rmbs_lock); -+ down_write(&lgr->rmbs_lock); - for (i = 0; i < SMC_RMBE_SIZES; i++) { - list_for_each_entry_safe(buf_desc, bf, &lgr->rmbs[i], list) { - if (!buf_desc->used) - continue; - rc = smcr_link_reg_buf(lnk, buf_desc); - if (rc) { -- mutex_unlock(&lgr->rmbs_lock); -+ up_write(&lgr->rmbs_lock); - return rc; - } - } - } -- mutex_unlock(&lgr->rmbs_lock); -+ up_write(&lgr->rmbs_lock); - - if (lgr->buf_type == SMCR_PHYS_CONT_BUFS) - return rc; - - /* reg all vzalloced sndbufs for a new link */ -- mutex_lock(&lgr->sndbufs_lock); -+ down_write(&lgr->sndbufs_lock); - for (i = 0; i < SMC_RMBE_SIZES; i++) { - list_for_each_entry_safe(buf_desc, bf, &lgr->sndbufs[i], list) { - if (!buf_desc->used || !buf_desc->is_vm) - continue; - rc = smcr_link_reg_buf(lnk, buf_desc); - if (rc) { -- mutex_unlock(&lgr->sndbufs_lock); -+ up_write(&lgr->sndbufs_lock); - return rc; - } - } - } -- mutex_unlock(&lgr->sndbufs_lock); -+ up_write(&lgr->sndbufs_lock); - return rc; - } - -@@ -2304,31 +2305,30 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb) - struct smc_connection *conn = &smc->conn; - struct smc_link_group *lgr = conn->lgr; - struct list_head *buf_list; -- int bufsize, bufsize_short; -+ int bufsize, bufsize_comp; -+ struct rw_semaphore *lock; /* lock buffer list */ - bool is_dgraded = false; -- struct mutex *lock; /* lock buffer list */ -- int sk_buf_size; - - if (is_rmb) - /* use socket recv buffer size (w/o overhead) as start value */ -- sk_buf_size = smc->sk.sk_rcvbuf; -+ bufsize = smc->sk.sk_rcvbuf / 2; - else - /* use socket send buffer size (w/o overhead) as start value */ -- sk_buf_size = smc->sk.sk_sndbuf; -+ bufsize = smc->sk.sk_sndbuf / 2; - -- for (bufsize_short = smc_compress_bufsize(sk_buf_size, is_smcd, is_rmb); -- bufsize_short >= 0; bufsize_short--) { -+ for (bufsize_comp = smc_compress_bufsize(bufsize, is_smcd, is_rmb); -+ bufsize_comp >= 0; bufsize_comp--) { - if (is_rmb) { - lock = &lgr->rmbs_lock; -- buf_list = &lgr->rmbs[bufsize_short]; -+ buf_list = &lgr->rmbs[bufsize_comp]; - } else { - lock = &lgr->sndbufs_lock; -- buf_list = &lgr->sndbufs[bufsize_short]; -+ buf_list = &lgr->sndbufs[bufsize_comp]; - } -- bufsize = smc_uncompress_bufsize(bufsize_short); -+ bufsize = smc_uncompress_bufsize(bufsize_comp); - - /* check for reusable slot in the link group */ -- buf_desc = smc_buf_get_slot(bufsize_short, lock, buf_list); -+ buf_desc = smc_buf_get_slot(bufsize_comp, lock, buf_list); - if (buf_desc) { - buf_desc->is_dma_need_sync = 0; - SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, bufsize); -@@ -2354,9 +2354,9 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb) - SMC_STAT_RMB_ALLOC(smc, is_smcd, is_rmb); - SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, bufsize); - buf_desc->used = 1; -- mutex_lock(lock); -+ down_write(lock); - list_add(&buf_desc->list, buf_list); -- mutex_unlock(lock); -+ up_write(lock); - break; /* found */ - } - -@@ -2372,8 +2372,8 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb) - - if (is_rmb) { - conn->rmb_desc = buf_desc; -- conn->rmbe_size_short = bufsize_short; -- smc->sk.sk_rcvbuf = bufsize; -+ conn->rmbe_size_comp = bufsize_comp; -+ smc->sk.sk_rcvbuf = bufsize * 2; - atomic_set(&conn->bytes_to_rcv, 0); - conn->rmbe_update_limit = - smc_rmb_wnd_update_limit(buf_desc->len); -@@ -2381,7 +2381,7 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb) - smc_ism_set_conn(conn); /* map RMB/smcd_dev to conn */ - } else { - conn->sndbuf_desc = buf_desc; -- smc->sk.sk_sndbuf = bufsize; -+ smc->sk.sk_sndbuf = bufsize * 2; - atomic_set(&conn->sndbuf_space, bufsize); - } - return 0; -@@ -2430,9 +2430,9 @@ int smc_buf_create(struct smc_sock *smc, bool is_smcd) - /* create rmb */ - rc = __smc_buf_create(smc, is_smcd, true); - if (rc) { -- mutex_lock(&smc->conn.lgr->sndbufs_lock); -+ down_write(&smc->conn.lgr->sndbufs_lock); - list_del(&smc->conn.sndbuf_desc->list); -- mutex_unlock(&smc->conn.lgr->sndbufs_lock); -+ up_write(&smc->conn.lgr->sndbufs_lock); - smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc); - smc->conn.sndbuf_desc = NULL; - } -diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h -index 285f9bd8e232e..6051d92270130 100644 ---- a/net/smc/smc_core.h -+++ b/net/smc/smc_core.h -@@ -252,9 +252,9 @@ struct smc_link_group { - unsigned short vlan_id; /* vlan id of link group */ - - struct list_head sndbufs[SMC_RMBE_SIZES];/* tx buffers */ -- struct mutex sndbufs_lock; /* protects tx buffers */ -+ struct rw_semaphore sndbufs_lock; /* protects tx buffers */ - struct list_head rmbs[SMC_RMBE_SIZES]; /* rx buffers */ -- struct mutex rmbs_lock; /* protects rx buffers */ -+ struct rw_semaphore rmbs_lock; /* protects rx buffers */ - - u8 id[SMC_LGR_ID_SIZE]; /* unique lgr id */ - struct delayed_work free_work; /* delayed freeing of an lgr */ -diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c -index 760f8bbff822e..fcb24a0ccf761 100644 ---- a/net/smc/smc_llc.c -+++ b/net/smc/smc_llc.c -@@ -611,7 +611,7 @@ static int smc_llc_fill_ext_v2(struct smc_llc_msg_add_link_v2_ext *ext, - - prim_lnk_idx = link->link_idx; - lnk_idx = link_new->link_idx; -- mutex_lock(&lgr->rmbs_lock); -+ down_write(&lgr->rmbs_lock); - ext->num_rkeys = lgr->conns_num; - if (!ext->num_rkeys) - goto out; -@@ -631,7 +631,7 @@ static int smc_llc_fill_ext_v2(struct smc_llc_msg_add_link_v2_ext *ext, - } - len += i * sizeof(ext->rt[0]); - out: -- mutex_unlock(&lgr->rmbs_lock); -+ up_write(&lgr->rmbs_lock); - return len; - } - -@@ -892,7 +892,7 @@ static int smc_llc_cli_rkey_exchange(struct smc_link *link, - int rc = 0; - int i; - -- mutex_lock(&lgr->rmbs_lock); -+ down_write(&lgr->rmbs_lock); - num_rkeys_send = lgr->conns_num; - buf_pos = smc_llc_get_first_rmb(lgr, &buf_lst); - do { -@@ -919,7 +919,7 @@ static int smc_llc_cli_rkey_exchange(struct smc_link *link, - break; - } while (num_rkeys_send || num_rkeys_recv); - -- mutex_unlock(&lgr->rmbs_lock); -+ up_write(&lgr->rmbs_lock); - return rc; - } - -@@ -1002,14 +1002,14 @@ static void smc_llc_save_add_link_rkeys(struct smc_link *link, - ext = (struct smc_llc_msg_add_link_v2_ext *)((u8 *)lgr->wr_rx_buf_v2 + - SMC_WR_TX_SIZE); - max = min_t(u8, ext->num_rkeys, SMC_LLC_RKEYS_PER_MSG_V2); -- mutex_lock(&lgr->rmbs_lock); -+ down_write(&lgr->rmbs_lock); - for (i = 0; i < max; i++) { - smc_rtoken_set(lgr, link->link_idx, link_new->link_idx, - ext->rt[i].rmb_key, - ext->rt[i].rmb_vaddr_new, - ext->rt[i].rmb_key_new); - } -- mutex_unlock(&lgr->rmbs_lock); -+ up_write(&lgr->rmbs_lock); - } - - static void smc_llc_save_add_link_info(struct smc_link *link, -@@ -1316,7 +1316,7 @@ static int smc_llc_srv_rkey_exchange(struct smc_link *link, - int rc = 0; - int i; - -- mutex_lock(&lgr->rmbs_lock); -+ down_write(&lgr->rmbs_lock); - num_rkeys_send = lgr->conns_num; - buf_pos = smc_llc_get_first_rmb(lgr, &buf_lst); - do { -@@ -1341,7 +1341,7 @@ static int smc_llc_srv_rkey_exchange(struct smc_link *link, - smc_llc_flow_qentry_del(&lgr->llc_flow_lcl); - } while (num_rkeys_send || num_rkeys_recv); - out: -- mutex_unlock(&lgr->rmbs_lock); -+ up_write(&lgr->rmbs_lock); - return rc; - } - -diff --git a/net/smc/smc_sysctl.c b/net/smc/smc_sysctl.c -index b6f79fabb9d3f..0b2a957ca5f5f 100644 ---- a/net/smc/smc_sysctl.c -+++ b/net/smc/smc_sysctl.c -@@ -21,6 +21,10 @@ - - static int min_sndbuf = SMC_BUF_MIN_SIZE; - static int min_rcvbuf = SMC_BUF_MIN_SIZE; -+static int max_sndbuf = INT_MAX / 2; -+static int max_rcvbuf = INT_MAX / 2; -+static const int net_smc_wmem_init = (64 * 1024); -+static const int net_smc_rmem_init = (64 * 1024); - - static struct ctl_table smc_table[] = { - { -@@ -53,6 +57,7 @@ static struct ctl_table smc_table[] = { - .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = &min_sndbuf, -+ .extra2 = &max_sndbuf, - }, - { - .procname = "rmem", -@@ -61,6 +66,7 @@ static struct ctl_table smc_table[] = { - .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = &min_rcvbuf, -+ .extra2 = &max_rcvbuf, - }, - { } - }; -@@ -88,8 +94,8 @@ int __net_init smc_sysctl_net_init(struct net *net) - net->smc.sysctl_autocorking_size = SMC_AUTOCORKING_DEFAULT_SIZE; - net->smc.sysctl_smcr_buf_type = SMCR_PHYS_CONT_BUFS; - net->smc.sysctl_smcr_testlink_time = SMC_LLC_TESTLINK_DEFAULT_TIME; -- WRITE_ONCE(net->smc.sysctl_wmem, READ_ONCE(net->ipv4.sysctl_tcp_wmem[1])); -- WRITE_ONCE(net->smc.sysctl_rmem, READ_ONCE(net->ipv4.sysctl_tcp_rmem[1])); -+ WRITE_ONCE(net->smc.sysctl_wmem, net_smc_wmem_init); -+ WRITE_ONCE(net->smc.sysctl_rmem, net_smc_rmem_init); - - return 0; - -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index 78fa620a63981..ca31847a6c70c 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -2290,6 +2290,7 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, - - if (false) { - alloc_skb: -+ spin_unlock(&other->sk_receive_queue.lock); - unix_state_unlock(other); - mutex_unlock(&unix_sk(other)->iolock); - newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, -@@ -2329,6 +2330,7 @@ alloc_skb: - init_scm = false; - } - -+ spin_lock(&other->sk_receive_queue.lock); - skb = skb_peek_tail(&other->sk_receive_queue); - if (tail && tail == skb) { - skb = newskb; -@@ -2359,14 +2361,11 @@ alloc_skb: - refcount_add(size, &sk->sk_wmem_alloc); - - if (newskb) { -- err = unix_scm_to_skb(&scm, skb, false); -- if (err) -- goto err_state_unlock; -- spin_lock(&other->sk_receive_queue.lock); -+ unix_scm_to_skb(&scm, skb, false); - __skb_queue_tail(&other->sk_receive_queue, newskb); -- spin_unlock(&other->sk_receive_queue.lock); - } - -+ spin_unlock(&other->sk_receive_queue.lock); - unix_state_unlock(other); - mutex_unlock(&unix_sk(other)->iolock); - -diff --git a/net/xfrm/xfrm_compat.c b/net/xfrm/xfrm_compat.c -index 8cbf45a8bcdc2..655fe4ff86212 100644 ---- a/net/xfrm/xfrm_compat.c -+++ b/net/xfrm/xfrm_compat.c -@@ -108,7 +108,7 @@ static const struct nla_policy compat_policy[XFRMA_MAX+1] = { - [XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) }, - [XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) }, - [XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) }, -- [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) }, -+ [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_user_sec_ctx) }, - [XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) }, - [XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) }, - [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 }, -diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c -index 94a3609548b11..d71dbe822096a 100644 ---- a/net/xfrm/xfrm_interface_core.c -+++ b/net/xfrm/xfrm_interface_core.c -@@ -528,8 +528,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) - - switch (skb->protocol) { - case htons(ETH_P_IPV6): -- xfrm_decode_session(skb, &fl, AF_INET6); - memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); -+ xfrm_decode_session(skb, &fl, AF_INET6); - if (!dst) { - fl.u.ip6.flowi6_oif = dev->ifindex; - fl.u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; -@@ -543,8 +543,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) - } - break; - case htons(ETH_P_IP): -- xfrm_decode_session(skb, &fl, AF_INET); - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); -+ xfrm_decode_session(skb, &fl, AF_INET); - if (!dst) { - struct rtable *rt; - -diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c -index 2d68a173b2273..d042ca01211fa 100644 ---- a/net/xfrm/xfrm_user.c -+++ b/net/xfrm/xfrm_user.c -@@ -615,7 +615,7 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs, - struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH]; - struct nlattr *mt = attrs[XFRMA_MTIMER_THRESH]; - -- if (re) { -+ if (re && x->replay_esn && x->preplay_esn) { - struct xfrm_replay_state_esn *replay_esn; - replay_esn = nla_data(re); - memcpy(x->replay_esn, replay_esn, -@@ -1250,6 +1250,15 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) - sizeof(*filter), GFP_KERNEL); - if (filter == NULL) - return -ENOMEM; -+ -+ /* see addr_match(), (prefix length >> 5) << 2 -+ * will be used to compare xfrm_address_t -+ */ -+ if (filter->splen > (sizeof(xfrm_address_t) << 3) || -+ filter->dplen > (sizeof(xfrm_address_t) << 3)) { -+ kfree(filter); -+ return -EINVAL; -+ } - } - - if (attrs[XFRMA_PROTO]) -@@ -2960,7 +2969,7 @@ const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { - [XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) }, - [XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) }, - [XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) }, -- [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) }, -+ [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_user_sec_ctx) }, - [XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) }, - [XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) }, - [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 }, -@@ -2980,6 +2989,7 @@ const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { - [XFRMA_SET_MARK] = { .type = NLA_U32 }, - [XFRMA_SET_MARK_MASK] = { .type = NLA_U32 }, - [XFRMA_IF_ID] = { .type = NLA_U32 }, -+ [XFRMA_MTIMER_THRESH] = { .type = NLA_U32 }, - }; - EXPORT_SYMBOL_GPL(xfrma_policy); - -diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c -index fe3587547cfec..39610a15bcc98 100644 ---- a/sound/hda/hdac_regmap.c -+++ b/sound/hda/hdac_regmap.c -@@ -597,10 +597,9 @@ EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw_once); - */ - void snd_hdac_regmap_sync(struct hdac_device *codec) - { -- if (codec->regmap) { -- mutex_lock(&codec->regmap_lock); -+ mutex_lock(&codec->regmap_lock); -+ if (codec->regmap) - regcache_sync(codec->regmap); -- mutex_unlock(&codec->regmap_lock); -- } -+ mutex_unlock(&codec->regmap_lock); - } - EXPORT_SYMBOL_GPL(snd_hdac_regmap_sync); -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index f93b68a2a8393..aa475154c582f 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -7081,6 +7081,8 @@ enum { - ALC285_FIXUP_SPEAKER2_TO_DAC1, - ALC285_FIXUP_ASUS_SPEAKER2_TO_DAC1, - ALC285_FIXUP_ASUS_HEADSET_MIC, -+ ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1, -+ ALC285_FIXUP_ASUS_I2C_HEADSET_MIC, - ALC280_FIXUP_HP_HEADSET_MIC, - ALC221_FIXUP_HP_FRONT_MIC, - ALC292_FIXUP_TPT460, -@@ -7136,6 +7138,10 @@ enum { - ALC294_FIXUP_ASUS_DUAL_SPK, - ALC285_FIXUP_THINKPAD_X1_GEN7, - ALC285_FIXUP_THINKPAD_HEADSET_JACK, -+ ALC294_FIXUP_ASUS_ALLY, -+ ALC294_FIXUP_ASUS_ALLY_PINS, -+ ALC294_FIXUP_ASUS_ALLY_VERBS, -+ ALC294_FIXUP_ASUS_ALLY_SPEAKER, - ALC294_FIXUP_ASUS_HPE, - ALC294_FIXUP_ASUS_COEF_1B, - ALC294_FIXUP_ASUS_GX502_HP, -@@ -8069,6 +8075,22 @@ static const struct hda_fixup alc269_fixups[] = { - .chained = true, - .chain_id = ALC285_FIXUP_ASUS_SPEAKER2_TO_DAC1 - }, -+ [ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc285_fixup_speaker2_to_dac1, -+ .chained = true, -+ .chain_id = ALC287_FIXUP_CS35L41_I2C_2 -+ }, -+ [ALC285_FIXUP_ASUS_I2C_HEADSET_MIC] = { -+ .type = HDA_FIXUP_PINS, -+ .v.pins = (const struct hda_pintbl[]) { -+ { 0x19, 0x03a11050 }, -+ { 0x1b, 0x03a11c30 }, -+ { } -+ }, -+ .chained = true, -+ .chain_id = ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1 -+ }, - [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = { - .type = HDA_FIXUP_PINS, - .v.pins = (const struct hda_pintbl[]) { -@@ -8450,6 +8472,47 @@ static const struct hda_fixup alc269_fixups[] = { - .chained = true, - .chain_id = ALC294_FIXUP_SPK2_TO_DAC1 - }, -+ [ALC294_FIXUP_ASUS_ALLY] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = cs35l41_fixup_i2c_two, -+ .chained = true, -+ .chain_id = ALC294_FIXUP_ASUS_ALLY_PINS -+ }, -+ [ALC294_FIXUP_ASUS_ALLY_PINS] = { -+ .type = HDA_FIXUP_PINS, -+ .v.pins = (const struct hda_pintbl[]) { -+ { 0x19, 0x03a11050 }, -+ { 0x1a, 0x03a11c30 }, -+ { 0x21, 0x03211420 }, -+ { } -+ }, -+ .chained = true, -+ .chain_id = ALC294_FIXUP_ASUS_ALLY_VERBS -+ }, -+ [ALC294_FIXUP_ASUS_ALLY_VERBS] = { -+ .type = HDA_FIXUP_VERBS, -+ .v.verbs = (const struct hda_verb[]) { -+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 }, -+ { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 }, -+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x46 }, -+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0004 }, -+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x47 }, -+ { 0x20, AC_VERB_SET_PROC_COEF, 0xa47a }, -+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x49 }, -+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0049}, -+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x4a }, -+ { 0x20, AC_VERB_SET_PROC_COEF, 0x201b }, -+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x6b }, -+ { 0x20, AC_VERB_SET_PROC_COEF, 0x4278}, -+ { } -+ }, -+ .chained = true, -+ .chain_id = ALC294_FIXUP_ASUS_ALLY_SPEAKER -+ }, -+ [ALC294_FIXUP_ASUS_ALLY_SPEAKER] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc285_fixup_speaker2_to_dac1, -+ }, - [ALC285_FIXUP_THINKPAD_X1_GEN7] = { - .type = HDA_FIXUP_FUNC, - .v.func = alc285_fixup_thinkpad_x1_gen7, -@@ -9533,7 +9596,13 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8b97, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED), -- SND_PCI_QUIRK(0x103c, 0x8c26, "HP HP EliteBook 800G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8c46, "HP EliteBook 830 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8c47, "HP EliteBook 840 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8c48, "HP EliteBook 860 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8c49, "HP Elite x360 830 2-in-1 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8c70, "HP EliteBook 835 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), - SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), - SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), -@@ -9553,15 +9622,19 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), - SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), -+ SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650P", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), -+ SND_PCI_QUIRK(0x1043, 0x1463, "Asus GA402X", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604V", ALC285_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603V", ALC285_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), -+ SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301V", ALC285_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), - SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), - SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS), - SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), -+ 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, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC), -@@ -10547,6 +10620,7 @@ static int patch_alc269(struct hda_codec *codec) - spec = codec->spec; - spec->gen.shared_mic_vref_pin = 0x18; - codec->power_save_node = 0; -+ spec->en_3kpull_low = true; - - #ifdef CONFIG_PM - codec->patch_ops.suspend = alc269_suspend; -@@ -10629,14 +10703,16 @@ static int patch_alc269(struct hda_codec *codec) - spec->shutup = alc256_shutup; - spec->init_hook = alc256_init; - spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */ -- if (codec->bus->pci->vendor == PCI_VENDOR_ID_AMD) -- spec->en_3kpull_low = true; -+ if (codec->core.vendor_id == 0x10ec0236 && -+ codec->bus->pci->vendor != PCI_VENDOR_ID_AMD) -+ spec->en_3kpull_low = false; - break; - case 0x10ec0257: - spec->codec_variant = ALC269_TYPE_ALC257; - spec->shutup = alc256_shutup; - spec->init_hook = alc256_init; - spec->gen.mixer_nid = 0; -+ spec->en_3kpull_low = false; - break; - case 0x10ec0215: - case 0x10ec0245: -@@ -11268,6 +11344,7 @@ enum { - ALC897_FIXUP_HP_HSMIC_VERB, - ALC897_FIXUP_LENOVO_HEADSET_MODE, - ALC897_FIXUP_HEADSET_MIC_PIN2, -+ ALC897_FIXUP_UNIS_H3C_X500S, - }; - - static const struct hda_fixup alc662_fixups[] = { -@@ -11707,6 +11784,13 @@ static const struct hda_fixup alc662_fixups[] = { - .chained = true, - .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MODE - }, -+ [ALC897_FIXUP_UNIS_H3C_X500S] = { -+ .type = HDA_FIXUP_VERBS, -+ .v.verbs = (const struct hda_verb[]) { -+ { 0x14, AC_VERB_SET_EAPD_BTLENABLE, 0 }, -+ {} -+ }, -+ }, - }; - - static const struct snd_pci_quirk alc662_fixup_tbl[] = { -@@ -11868,6 +11952,7 @@ static const struct hda_model_fixup alc662_fixup_models[] = { - {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"}, - {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"}, - {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"}, -+ {.id = ALC897_FIXUP_UNIS_H3C_X500S, .name = "unis-h3c-x500s"}, - {} - }; - -diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig -index c88ebd84bdd50..3968c478c9381 100644 ---- a/sound/soc/amd/Kconfig -+++ b/sound/soc/amd/Kconfig -@@ -81,6 +81,7 @@ config SND_SOC_AMD_VANGOGH_MACH - tristate "AMD Vangogh support for NAU8821 CS35L41" - select SND_SOC_NAU8821 - select SND_SOC_CS35L41_SPI -+ select SND_AMD_ACP_CONFIG - depends on SND_SOC_AMD_ACP5x && I2C && SPI_MASTER - help - This option enables machine driver for Vangogh platform -diff --git a/sound/soc/amd/vangogh/acp5x.h b/sound/soc/amd/vangogh/acp5x.h -index bd9f1c5684d17..ac1936a8c43ff 100644 ---- a/sound/soc/amd/vangogh/acp5x.h -+++ b/sound/soc/amd/vangogh/acp5x.h -@@ -147,6 +147,8 @@ static inline void acp_writel(u32 val, void __iomem *base_addr) - writel(val, base_addr - ACP5x_PHY_BASE_ADDRESS); - } - -+int snd_amd_acp_find_config(struct pci_dev *pci); -+ - static inline u64 acp_get_byte_count(struct i2s_stream_instance *rtd, - int direction) - { -diff --git a/sound/soc/amd/vangogh/pci-acp5x.c b/sound/soc/amd/vangogh/pci-acp5x.c -index e0df17c88e8e0..c4634a8a17cdc 100644 ---- a/sound/soc/amd/vangogh/pci-acp5x.c -+++ b/sound/soc/amd/vangogh/pci-acp5x.c -@@ -125,10 +125,15 @@ static int snd_acp5x_probe(struct pci_dev *pci, - { - struct acp5x_dev_data *adata; - struct platform_device_info pdevinfo[ACP5x_DEVS]; -- unsigned int irqflags; -+ unsigned int irqflags, flag; - int ret, i; - u32 addr, val; - -+ /* Return if acp config flag is defined */ -+ flag = snd_amd_acp_find_config(pci); -+ if (flag) -+ return -ENODEV; -+ - irqflags = IRQF_SHARED; - if (pci->revision != 0x50) - return -ENODEV; -diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c -index 6e66cc218fa8d..76ff097518c88 100644 ---- a/sound/soc/codecs/rt5665.c -+++ b/sound/soc/codecs/rt5665.c -@@ -4472,6 +4472,8 @@ static void rt5665_remove(struct snd_soc_component *component) - struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component); - - regmap_write(rt5665->regmap, RT5665_RESET, 0); -+ -+ regulator_bulk_disable(ARRAY_SIZE(rt5665->supplies), rt5665->supplies); - } - - #ifdef CONFIG_PM -diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c -index a37c85d301471..064b6feb76167 100644 ---- a/sound/soc/intel/boards/sof_sdw.c -+++ b/sound/soc/intel/boards/sof_sdw.c -@@ -374,6 +374,31 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { - }, - .driver_data = (void *)(RT711_JD1), - }, -+ { -+ .callback = sof_sdw_quirk_cb, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Meteor Lake Client Platform"), -+ }, -+ .driver_data = (void *)(RT711_JD2_100K), -+ }, -+ { -+ .callback = sof_sdw_quirk_cb, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Google"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), -+ }, -+ .driver_data = (void *)(SOF_SDW_PCH_DMIC), -+ }, -+ /* LunarLake devices */ -+ { -+ .callback = sof_sdw_quirk_cb, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"), -+ }, -+ .driver_data = (void *)(RT711_JD2_100K), -+ }, - {} - }; - -diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c -index 7f16304d025be..cf8b9793fe0e5 100644 ---- a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c -+++ b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c -@@ -143,6 +143,9 @@ int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link * - if (!ctx->headset_codec_dev) - return 0; - -+ if (!SOF_RT711_JDSRC(sof_sdw_quirk)) -+ return 0; -+ - device_remove_software_node(ctx->headset_codec_dev); - put_device(ctx->headset_codec_dev); - -diff --git a/sound/soc/meson/axg-tdm-formatter.c b/sound/soc/meson/axg-tdm-formatter.c -index 9883dc777f630..63333a2b0a9c3 100644 ---- a/sound/soc/meson/axg-tdm-formatter.c -+++ b/sound/soc/meson/axg-tdm-formatter.c -@@ -30,27 +30,32 @@ int axg_tdm_formatter_set_channel_masks(struct regmap *map, - struct axg_tdm_stream *ts, - unsigned int offset) - { -- unsigned int val, ch = ts->channels; -- unsigned long mask; -- int i, j; -+ unsigned int ch = ts->channels; -+ u32 val[AXG_TDM_NUM_LANES]; -+ int i, j, k; -+ -+ /* -+ * We need to mimick the slot distribution used by the HW to keep the -+ * channel placement consistent regardless of the number of channel -+ * in the stream. This is why the odd algorithm below is used. -+ */ -+ memset(val, 0, sizeof(*val) * AXG_TDM_NUM_LANES); - - /* - * Distribute the channels of the stream over the available slots -- * of each TDM lane -+ * of each TDM lane. We need to go over the 32 slots ... - */ -- for (i = 0; i < AXG_TDM_NUM_LANES; i++) { -- val = 0; -- mask = ts->mask[i]; -- -- for (j = find_first_bit(&mask, 32); -- (j < 32) && ch; -- j = find_next_bit(&mask, 32, j + 1)) { -- val |= 1 << j; -- ch -= 1; -+ for (i = 0; (i < 32) && ch; i += 2) { -+ /* ... of all the lanes ... */ -+ for (j = 0; j < AXG_TDM_NUM_LANES; j++) { -+ /* ... then distribute the channels in pairs */ -+ for (k = 0; k < 2; k++) { -+ if ((BIT(i + k) & ts->mask[j]) && ch) { -+ val[j] |= BIT(i + k); -+ ch -= 1; -+ } -+ } - } -- -- regmap_write(map, offset, val); -- offset += regmap_get_reg_stride(map); - } - - /* -@@ -63,6 +68,11 @@ int axg_tdm_formatter_set_channel_masks(struct regmap *map, - return -EINVAL; - } - -+ for (i = 0; i < AXG_TDM_NUM_LANES; i++) { -+ regmap_write(map, offset, val[i]); -+ offset += regmap_get_reg_stride(map); -+ } -+ - return 0; - } - EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks); -diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h -index dd3c072d01721..14148c311f504 100644 ---- a/sound/soc/sof/amd/acp.h -+++ b/sound/soc/sof/amd/acp.h -@@ -54,6 +54,9 @@ - - #define ACP_DSP_TO_HOST_IRQ 0x04 - -+#define ACP_RN_PCI_ID 0x01 -+#define ACP_RMB_PCI_ID 0x6F -+ - #define HOST_BRIDGE_CZN 0x1630 - #define HOST_BRIDGE_RMB 0x14B5 - #define ACP_SHA_STAT 0x8000 -diff --git a/sound/soc/sof/amd/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c -index 4e1de462b431b..5698d910b26f3 100644 ---- a/sound/soc/sof/amd/pci-rmb.c -+++ b/sound/soc/sof/amd/pci-rmb.c -@@ -90,6 +90,9 @@ static int acp_pci_rmb_probe(struct pci_dev *pci, const struct pci_device_id *pc - unsigned int flag, i, addr; - int ret; - -+ if (pci->revision != ACP_RMB_PCI_ID) -+ return -ENODEV; -+ - flag = snd_amd_acp_find_config(pci); - if (flag != FLAG_AMD_SOF && flag != FLAG_AMD_SOF_ONLY_DMIC) - return -ENODEV; -diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c -index fca40b261671b..9189f63632789 100644 ---- a/sound/soc/sof/amd/pci-rn.c -+++ b/sound/soc/sof/amd/pci-rn.c -@@ -90,6 +90,9 @@ static int acp_pci_rn_probe(struct pci_dev *pci, const struct pci_device_id *pci - unsigned int flag, i, addr; - int ret; - -+ if (pci->revision != ACP_RN_PCI_ID) -+ return -ENODEV; -+ - flag = snd_amd_acp_find_config(pci); - if (flag != FLAG_AMD_SOF && flag != FLAG_AMD_SOF_ONLY_DMIC) - return -ENODEV; -diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c -index 625977a29d8a8..75a1e2c6539f2 100644 ---- a/sound/soc/sof/core.c -+++ b/sound/soc/sof/core.c -@@ -479,8 +479,10 @@ int snd_sof_device_shutdown(struct device *dev) - if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) - cancel_work_sync(&sdev->probe_work); - -- if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) -+ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) { -+ sof_fw_trace_free(sdev); - return snd_sof_shutdown(sdev); -+ } - - return 0; - } -diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c -index 1188ec51816bd..63764afdcf617 100644 ---- a/sound/soc/sof/intel/hda.c -+++ b/sound/soc/sof/intel/hda.c -@@ -1309,12 +1309,22 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, - hda_mach->mach_params.dmic_num = dmic_num; - pdata->tplg_filename = tplg_filename; - -- if (codec_num == 2) { -+ if (codec_num == 2 || -+ (codec_num == 1 && !HDA_IDISP_CODEC(bus->codec_mask))) { - /* - * Prevent SoundWire links from starting when an external - * HDaudio codec is used - */ - hda_mach->mach_params.link_mask = 0; -+ } else { -+ /* -+ * Allow SoundWire links to start when no external HDaudio codec -+ * was detected. This will not create a SoundWire card but -+ * will help detect if any SoundWire codec reports as ATTACHED. -+ */ -+ struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; -+ -+ hda_mach->mach_params.link_mask = hdev->info.link_mask; - } - - *mach = hda_mach; -diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h -index efb4a3311cc59..5d72dc8441cbb 100644 ---- a/sound/usb/quirks-table.h -+++ b/sound/usb/quirks-table.h -@@ -4507,6 +4507,35 @@ YAMAHA_DEVICE(0x7010, "UB99"), - } - } - }, -+{ -+ /* Advanced modes of the Mythware XA001AU. -+ * For the standard mode, Mythware XA001AU has ID ffad:a001 -+ */ -+ USB_DEVICE_VENDOR_SPEC(0xffad, 0xa001), -+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { -+ .vendor_name = "Mythware", -+ .product_name = "XA001AU", -+ .ifnum = QUIRK_ANY_INTERFACE, -+ .type = QUIRK_COMPOSITE, -+ .data = (const struct snd_usb_audio_quirk[]) { -+ { -+ .ifnum = 0, -+ .type = QUIRK_IGNORE_INTERFACE, -+ }, -+ { -+ .ifnum = 1, -+ .type = QUIRK_AUDIO_STANDARD_INTERFACE, -+ }, -+ { -+ .ifnum = 2, -+ .type = QUIRK_AUDIO_STANDARD_INTERFACE, -+ }, -+ { -+ .ifnum = -1 -+ } -+ } -+ } -+}, - - #undef USB_DEVICE_VENDOR_SPEC - #undef USB_AUDIO_DEVICE -diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh b/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh -index aff88f78e3391..5ea9d63915f77 100755 ---- a/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh -+++ b/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh -@@ -72,7 +72,8 @@ test_span_gre_ttl() - - RET=0 - -- mirror_install $swp1 ingress $tundev "matchall $tcflags" -+ mirror_install $swp1 ingress $tundev \ -+ "prot ip flower $tcflags ip_prot icmp" - tc filter add dev $h3 ingress pref 77 prot $prot \ - flower skip_hw ip_ttl 50 action pass - -diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh -index 919c0dd9fe4bc..b0f5e55d2d0b2 100755 ---- a/tools/testing/selftests/net/forwarding/tc_actions.sh -+++ b/tools/testing/selftests/net/forwarding/tc_actions.sh -@@ -9,6 +9,8 @@ NUM_NETIFS=4 - source tc_common.sh - source lib.sh - -+require_command ncat -+ - tcflags="skip_hw" - - h1_create() -@@ -201,10 +203,10 @@ mirred_egress_to_ingress_test() - - mirred_egress_to_ingress_tcp_test() - { -- local tmpfile=$(mktemp) tmpfile1=$(mktemp) -+ mirred_e2i_tf1=$(mktemp) mirred_e2i_tf2=$(mktemp) - - RET=0 -- dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile -+ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred_e2i_tf1 - tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \ - $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \ - action ct commit nat src addr 192.0.2.2 pipe \ -@@ -220,11 +222,11 @@ mirred_egress_to_ingress_tcp_test() - ip_proto icmp \ - action drop - -- ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1 & -+ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & - local rpid=$! -- ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile -+ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 - wait -n $rpid -- cmp -s $tmpfile $tmpfile1 -+ cmp -s $mirred_e2i_tf1 $mirred_e2i_tf2 - check_err $? "server output check failed" - - $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \ -@@ -241,7 +243,7 @@ mirred_egress_to_ingress_tcp_test() - tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower - tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower - -- rm -f $tmpfile $tmpfile1 -+ rm -f $mirred_e2i_tf1 $mirred_e2i_tf2 - log_test "mirred_egress_to_ingress_tcp ($tcflags)" - } - -@@ -270,6 +272,8 @@ setup_prepare() - - cleanup() - { -+ local tf -+ - pre_cleanup - - switch_destroy -@@ -280,6 +284,8 @@ cleanup() - - ip link set $swp2 address $swp2origmac - ip link set $swp1 address $swp1origmac -+ -+ for tf in $mirred_e2i_tf1 $mirred_e2i_tf2; do rm -f $tf; done - } - - mirred_egress_redirect_test() diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.47-48.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.47-48.patch deleted file mode 100644 index eb7ca312e163..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.47-48.patch +++ /dev/null @@ -1,604 +0,0 @@ -diff --git a/Documentation/admin-guide/hw-vuln/srso.rst b/Documentation/admin-guide/hw-vuln/srso.rst -index 2f923c805802f..f79cb11b080f6 100644 ---- a/Documentation/admin-guide/hw-vuln/srso.rst -+++ b/Documentation/admin-guide/hw-vuln/srso.rst -@@ -124,8 +124,8 @@ sequence. - To ensure the safety of this mitigation, the kernel must ensure that the - safe return sequence is itself free from attacker interference. In Zen3 - and Zen4, this is accomplished by creating a BTB alias between the --untraining function srso_untrain_ret_alias() and the safe return --function srso_safe_ret_alias() which results in evicting a potentially -+untraining function srso_alias_untrain_ret() and the safe return -+function srso_alias_safe_ret() which results in evicting a potentially - poisoned BTB entry and using that safe one for all function returns. - - In older Zen1 and Zen2, this is accomplished using a reinterpretation -diff --git a/Makefile b/Makefile -index 375efcfb91f8f..8bb8dd199c552 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 47 -+SUBLEVEL = 48 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/x86/include/asm/entry-common.h b/arch/x86/include/asm/entry-common.h -index 674ed46d3ceda..11203a9fe0a87 100644 ---- a/arch/x86/include/asm/entry-common.h -+++ b/arch/x86/include/asm/entry-common.h -@@ -92,6 +92,7 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, - static __always_inline void arch_exit_to_user_mode(void) - { - mds_user_clear_cpu_buffers(); -+ amd_clear_divider(); - } - #define arch_exit_to_user_mode arch_exit_to_user_mode - -diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h -index 31fa631c8587c..2f123d4fb85b5 100644 ---- a/arch/x86/include/asm/nospec-branch.h -+++ b/arch/x86/include/asm/nospec-branch.h -@@ -168,9 +168,9 @@ - .endm - - #ifdef CONFIG_CPU_UNRET_ENTRY --#define CALL_ZEN_UNTRAIN_RET "call zen_untrain_ret" -+#define CALL_UNTRAIN_RET "call entry_untrain_ret" - #else --#define CALL_ZEN_UNTRAIN_RET "" -+#define CALL_UNTRAIN_RET "" - #endif - - /* -@@ -178,7 +178,7 @@ - * return thunk isn't mapped into the userspace tables (then again, AMD - * typically has NO_MELTDOWN). - * -- * While zen_untrain_ret() doesn't clobber anything but requires stack, -+ * While retbleed_untrain_ret() doesn't clobber anything but requires stack, - * entry_ibpb() will clobber AX, CX, DX. - * - * As such, this must be placed after every *SWITCH_TO_KERNEL_CR3 at a point -@@ -189,14 +189,9 @@ - defined(CONFIG_CPU_SRSO) - ANNOTATE_UNRET_END - ALTERNATIVE_2 "", \ -- CALL_ZEN_UNTRAIN_RET, X86_FEATURE_UNRET, \ -+ CALL_UNTRAIN_RET, X86_FEATURE_UNRET, \ - "call entry_ibpb", X86_FEATURE_ENTRY_IBPB - #endif -- --#ifdef CONFIG_CPU_SRSO -- ALTERNATIVE_2 "", "call srso_untrain_ret", X86_FEATURE_SRSO, \ -- "call srso_untrain_ret_alias", X86_FEATURE_SRSO_ALIAS --#endif - .endm - - #else /* __ASSEMBLY__ */ -@@ -210,10 +205,21 @@ - typedef u8 retpoline_thunk_t[RETPOLINE_THUNK_SIZE]; - extern retpoline_thunk_t __x86_indirect_thunk_array[]; - -+#ifdef CONFIG_RETHUNK - extern void __x86_return_thunk(void); --extern void zen_untrain_ret(void); -+#else -+static inline void __x86_return_thunk(void) {} -+#endif -+ -+extern void retbleed_return_thunk(void); -+extern void srso_return_thunk(void); -+extern void srso_alias_return_thunk(void); -+ -+extern void retbleed_untrain_ret(void); - extern void srso_untrain_ret(void); --extern void srso_untrain_ret_alias(void); -+extern void srso_alias_untrain_ret(void); -+ -+extern void entry_untrain_ret(void); - extern void entry_ibpb(void); - - #ifdef CONFIG_RETPOLINE -diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c -index 239b302973d7a..f240c978d85e4 100644 ---- a/arch/x86/kernel/cpu/amd.c -+++ b/arch/x86/kernel/cpu/amd.c -@@ -1295,3 +1295,4 @@ void noinstr amd_clear_divider(void) - asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0) - :: "a" (0), "d" (0), "r" (1)); - } -+EXPORT_SYMBOL_GPL(amd_clear_divider); -diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c -index d98f33ea57e47..3a893ab398a01 100644 ---- a/arch/x86/kernel/cpu/bugs.c -+++ b/arch/x86/kernel/cpu/bugs.c -@@ -62,6 +62,8 @@ EXPORT_SYMBOL_GPL(x86_pred_cmd); - - static DEFINE_MUTEX(spec_ctrl_mutex); - -+void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk; -+ - /* Update SPEC_CTRL MSR and its cached copy unconditionally */ - static void update_spec_ctrl(u64 val) - { -@@ -164,8 +166,13 @@ void __init cpu_select_mitigations(void) - md_clear_select_mitigation(); - srbds_select_mitigation(); - l1d_flush_select_mitigation(); -- gds_select_mitigation(); -+ -+ /* -+ * srso_select_mitigation() depends and must run after -+ * retbleed_select_mitigation(). -+ */ - srso_select_mitigation(); -+ gds_select_mitigation(); - } - - /* -@@ -1013,6 +1020,9 @@ do_cmd_auto: - setup_force_cpu_cap(X86_FEATURE_RETHUNK); - setup_force_cpu_cap(X86_FEATURE_UNRET); - -+ if (IS_ENABLED(CONFIG_RETHUNK)) -+ x86_return_thunk = retbleed_return_thunk; -+ - if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && - boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) - pr_err(RETBLEED_UNTRAIN_MSG); -@@ -2388,9 +2398,10 @@ static void __init srso_select_mitigation(void) - * Zen1/2 with SMT off aren't vulnerable after the right - * IBPB microcode has been applied. - */ -- if ((boot_cpu_data.x86 < 0x19) && -- (!cpu_smt_possible() || (cpu_smt_control == CPU_SMT_DISABLED))) -+ if (boot_cpu_data.x86 < 0x19 && !cpu_smt_possible()) { - setup_force_cpu_cap(X86_FEATURE_SRSO_NO); -+ return; -+ } - } - - if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB) { -@@ -2419,11 +2430,15 @@ static void __init srso_select_mitigation(void) - * like ftrace, static_call, etc. - */ - setup_force_cpu_cap(X86_FEATURE_RETHUNK); -+ setup_force_cpu_cap(X86_FEATURE_UNRET); - -- if (boot_cpu_data.x86 == 0x19) -+ if (boot_cpu_data.x86 == 0x19) { - setup_force_cpu_cap(X86_FEATURE_SRSO_ALIAS); -- else -+ x86_return_thunk = srso_alias_return_thunk; -+ } else { - setup_force_cpu_cap(X86_FEATURE_SRSO); -+ x86_return_thunk = srso_return_thunk; -+ } - srso_mitigation = SRSO_MITIGATION_SAFE_RET; - } else { - pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); -@@ -2672,6 +2687,9 @@ static ssize_t gds_show_state(char *buf) - - static ssize_t srso_show_state(char *buf) - { -+ if (boot_cpu_has(X86_FEATURE_SRSO_NO)) -+ return sysfs_emit(buf, "Mitigation: SMT disabled\n"); -+ - return sysfs_emit(buf, "%s%s\n", - srso_strings[srso_mitigation], - (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); -diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c -index a9b54b795ebff..3fbb491688275 100644 ---- a/arch/x86/kernel/static_call.c -+++ b/arch/x86/kernel/static_call.c -@@ -184,6 +184,19 @@ EXPORT_SYMBOL_GPL(arch_static_call_transform); - */ - bool __static_call_fixup(void *tramp, u8 op, void *dest) - { -+ unsigned long addr = (unsigned long)tramp; -+ /* -+ * Not all .return_sites are a static_call trampoline (most are not). -+ * Check if the 3 bytes after the return are still kernel text, if not, -+ * then this definitely is not a trampoline and we need not worry -+ * further. -+ * -+ * This avoids the memcmp() below tripping over pagefaults etc.. -+ */ -+ if (((addr >> PAGE_SHIFT) != ((addr + 7) >> PAGE_SHIFT)) && -+ !kernel_text_address(addr + 7)) -+ return false; -+ - if (memcmp(tramp+5, tramp_ud, 3)) { - /* Not a trampoline site, not our problem. */ - return false; -diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c -index 7e8795d8b0f17..c0a5a4f225d9a 100644 ---- a/arch/x86/kernel/traps.c -+++ b/arch/x86/kernel/traps.c -@@ -206,8 +206,6 @@ DEFINE_IDTENTRY(exc_divide_error) - { - do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE, - FPE_INTDIV, error_get_trap_addr(regs)); -- -- amd_clear_divider(); - } - - DEFINE_IDTENTRY(exc_overflow) -diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S -index e6939ebb606ab..78ccb5ec3c0e7 100644 ---- a/arch/x86/kernel/vmlinux.lds.S -+++ b/arch/x86/kernel/vmlinux.lds.S -@@ -134,18 +134,18 @@ SECTIONS - KPROBES_TEXT - ALIGN_ENTRY_TEXT_BEGIN - #ifdef CONFIG_CPU_SRSO -- *(.text.__x86.rethunk_untrain) -+ *(.text..__x86.rethunk_untrain) - #endif - - ENTRY_TEXT - - #ifdef CONFIG_CPU_SRSO - /* -- * See the comment above srso_untrain_ret_alias()'s -+ * See the comment above srso_alias_untrain_ret()'s - * definition. - */ -- . = srso_untrain_ret_alias | (1 << 2) | (1 << 8) | (1 << 14) | (1 << 20); -- *(.text.__x86.rethunk_safe) -+ . = srso_alias_untrain_ret | (1 << 2) | (1 << 8) | (1 << 14) | (1 << 20); -+ *(.text..__x86.rethunk_safe) - #endif - ALIGN_ENTRY_TEXT_END - SOFTIRQENTRY_TEXT -@@ -154,8 +154,8 @@ SECTIONS - - #ifdef CONFIG_RETPOLINE - __indirect_thunk_start = .; -- *(.text.__x86.indirect_thunk) -- *(.text.__x86.return_thunk) -+ *(.text..__x86.indirect_thunk) -+ *(.text..__x86.return_thunk) - __indirect_thunk_end = .; - #endif - } :text =0xcccc -@@ -507,8 +507,8 @@ INIT_PER_CPU(irq_stack_backing_store); - "fixed_percpu_data is not at start of per-cpu area"); - #endif - -- #ifdef CONFIG_RETHUNK --. = ASSERT((__ret & 0x3f) == 0, "__ret not cacheline-aligned"); -+#ifdef CONFIG_RETHUNK -+. = ASSERT((retbleed_return_thunk & 0x3f) == 0, "retbleed_return_thunk not cacheline-aligned"); - . = ASSERT((srso_safe_ret & 0x3f) == 0, "srso_safe_ret not cacheline-aligned"); - #endif - -@@ -523,8 +523,8 @@ INIT_PER_CPU(irq_stack_backing_store); - * Instead do: (A | B) - (A & B) in order to compute the XOR - * of the two function addresses: - */ --. = ASSERT(((ABSOLUTE(srso_untrain_ret_alias) | srso_safe_ret_alias) - -- (ABSOLUTE(srso_untrain_ret_alias) & srso_safe_ret_alias)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)), -+. = ASSERT(((ABSOLUTE(srso_alias_untrain_ret) | srso_alias_safe_ret) - -+ (ABSOLUTE(srso_alias_untrain_ret) & srso_alias_safe_ret)) == ((1 << 2) | (1 << 8) | (1 << 14) | (1 << 20)), - "SRSO function pair won't alias"); - #endif - -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index fdb6007f2eb86..a96f9a17e8b5d 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -3947,6 +3947,8 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, bool spec_ctrl_in - - guest_state_enter_irqoff(); - -+ amd_clear_divider(); -+ - if (sev_es_guest(vcpu->kvm)) - __svm_sev_es_vcpu_run(svm, spec_ctrl_intercepted); - else -diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S -index 30e76fab678a5..65c5c44f006bc 100644 ---- a/arch/x86/lib/retpoline.S -+++ b/arch/x86/lib/retpoline.S -@@ -11,7 +11,7 @@ - #include - #include - -- .section .text.__x86.indirect_thunk -+ .section .text..__x86.indirect_thunk - - .macro RETPOLINE reg - ANNOTATE_INTRA_FUNCTION_CALL -@@ -76,75 +76,106 @@ SYM_CODE_END(__x86_indirect_thunk_array) - #ifdef CONFIG_RETHUNK - - /* -- * srso_untrain_ret_alias() and srso_safe_ret_alias() are placed at -+ * srso_alias_untrain_ret() and srso_alias_safe_ret() are placed at - * special addresses: - * -- * - srso_untrain_ret_alias() is 2M aligned -- * - srso_safe_ret_alias() is also in the same 2M page but bits 2, 8, 14 -+ * - srso_alias_untrain_ret() is 2M aligned -+ * - srso_alias_safe_ret() is also in the same 2M page but bits 2, 8, 14 - * and 20 in its virtual address are set (while those bits in the -- * srso_untrain_ret_alias() function are cleared). -+ * srso_alias_untrain_ret() function are cleared). - * - * This guarantees that those two addresses will alias in the branch - * target buffer of Zen3/4 generations, leading to any potential - * poisoned entries at that BTB slot to get evicted. - * -- * As a result, srso_safe_ret_alias() becomes a safe return. -+ * As a result, srso_alias_safe_ret() becomes a safe return. - */ - #ifdef CONFIG_CPU_SRSO -- .section .text.__x86.rethunk_untrain -+ .section .text..__x86.rethunk_untrain - --SYM_START(srso_untrain_ret_alias, SYM_L_GLOBAL, SYM_A_NONE) -+SYM_START(srso_alias_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) -+ UNWIND_HINT_FUNC - ANNOTATE_NOENDBR - ASM_NOP2 - lfence -- jmp __x86_return_thunk --SYM_FUNC_END(srso_untrain_ret_alias) --__EXPORT_THUNK(srso_untrain_ret_alias) -+ jmp srso_alias_return_thunk -+SYM_FUNC_END(srso_alias_untrain_ret) -+__EXPORT_THUNK(srso_alias_untrain_ret) - -- .section .text.__x86.rethunk_safe -+ .section .text..__x86.rethunk_safe -+#else -+/* dummy definition for alternatives */ -+SYM_START(srso_alias_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) -+ ANNOTATE_UNRET_SAFE -+ ret -+ int3 -+SYM_FUNC_END(srso_alias_untrain_ret) - #endif - --/* Needs a definition for the __x86_return_thunk alternative below. */ --SYM_START(srso_safe_ret_alias, SYM_L_GLOBAL, SYM_A_NONE) --#ifdef CONFIG_CPU_SRSO -- add $8, %_ASM_SP -+SYM_START(srso_alias_safe_ret, SYM_L_GLOBAL, SYM_A_NONE) -+ lea 8(%_ASM_SP), %_ASM_SP - UNWIND_HINT_FUNC --#endif - ANNOTATE_UNRET_SAFE - ret - int3 --SYM_FUNC_END(srso_safe_ret_alias) -+SYM_FUNC_END(srso_alias_safe_ret) -+ -+ .section .text..__x86.return_thunk - -- .section .text.__x86.return_thunk -+SYM_CODE_START(srso_alias_return_thunk) -+ UNWIND_HINT_FUNC -+ ANNOTATE_NOENDBR -+ call srso_alias_safe_ret -+ ud2 -+SYM_CODE_END(srso_alias_return_thunk) -+ -+/* -+ * Some generic notes on the untraining sequences: -+ * -+ * They are interchangeable when it comes to flushing potentially wrong -+ * RET predictions from the BTB. -+ * -+ * The SRSO Zen1/2 (MOVABS) untraining sequence is longer than the -+ * Retbleed sequence because the return sequence done there -+ * (srso_safe_ret()) is longer and the return sequence must fully nest -+ * (end before) the untraining sequence. Therefore, the untraining -+ * sequence must fully overlap the return sequence. -+ * -+ * Regarding alignment - the instructions which need to be untrained, -+ * must all start at a cacheline boundary for Zen1/2 generations. That -+ * is, instruction sequences starting at srso_safe_ret() and -+ * the respective instruction sequences at retbleed_return_thunk() -+ * must start at a cacheline boundary. -+ */ - - /* - * Safety details here pertain to the AMD Zen{1,2} microarchitecture: -- * 1) The RET at __x86_return_thunk must be on a 64 byte boundary, for -+ * 1) The RET at retbleed_return_thunk must be on a 64 byte boundary, for - * alignment within the BTB. -- * 2) The instruction at zen_untrain_ret must contain, and not -+ * 2) The instruction at retbleed_untrain_ret must contain, and not - * end with, the 0xc3 byte of the RET. - * 3) STIBP must be enabled, or SMT disabled, to prevent the sibling thread - * from re-poisioning the BTB prediction. - */ - .align 64 -- .skip 64 - (__ret - zen_untrain_ret), 0xcc --SYM_START(zen_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) -+ .skip 64 - (retbleed_return_thunk - retbleed_untrain_ret), 0xcc -+SYM_START(retbleed_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) - ANNOTATE_NOENDBR - /* -- * As executed from zen_untrain_ret, this is: -+ * As executed from retbleed_untrain_ret, this is: - * - * TEST $0xcc, %bl - * LFENCE -- * JMP __x86_return_thunk -+ * JMP retbleed_return_thunk - * - * Executing the TEST instruction has a side effect of evicting any BTB - * prediction (potentially attacker controlled) attached to the RET, as -- * __x86_return_thunk + 1 isn't an instruction boundary at the moment. -+ * retbleed_return_thunk + 1 isn't an instruction boundary at the moment. - */ - .byte 0xf6 - - /* -- * As executed from __x86_return_thunk, this is a plain RET. -+ * As executed from retbleed_return_thunk, this is a plain RET. - * - * As part of the TEST above, RET is the ModRM byte, and INT3 the imm8. - * -@@ -156,13 +187,13 @@ SYM_START(zen_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) - * With SMT enabled and STIBP active, a sibling thread cannot poison - * RET's prediction to a type of its choice, but can evict the - * prediction due to competitive sharing. If the prediction is -- * evicted, __x86_return_thunk will suffer Straight Line Speculation -+ * evicted, retbleed_return_thunk will suffer Straight Line Speculation - * which will be contained safely by the INT3. - */ --SYM_INNER_LABEL(__ret, SYM_L_GLOBAL) -+SYM_INNER_LABEL(retbleed_return_thunk, SYM_L_GLOBAL) - ret - int3 --SYM_CODE_END(__ret) -+SYM_CODE_END(retbleed_return_thunk) - - /* - * Ensure the TEST decoding / BTB invalidation is complete. -@@ -173,16 +204,16 @@ SYM_CODE_END(__ret) - * Jump back and execute the RET in the middle of the TEST instruction. - * INT3 is for SLS protection. - */ -- jmp __ret -+ jmp retbleed_return_thunk - int3 --SYM_FUNC_END(zen_untrain_ret) --__EXPORT_THUNK(zen_untrain_ret) -+SYM_FUNC_END(retbleed_untrain_ret) -+__EXPORT_THUNK(retbleed_untrain_ret) - - /* -- * SRSO untraining sequence for Zen1/2, similar to zen_untrain_ret() -+ * SRSO untraining sequence for Zen1/2, similar to retbleed_untrain_ret() - * above. On kernel entry, srso_untrain_ret() is executed which is a - * -- * movabs $0xccccccc308c48348,%rax -+ * movabs $0xccccc30824648d48,%rax - * - * and when the return thunk executes the inner label srso_safe_ret() - * later, it is a stack manipulation and a RET which is mispredicted and -@@ -194,22 +225,44 @@ SYM_START(srso_untrain_ret, SYM_L_GLOBAL, SYM_A_NONE) - ANNOTATE_NOENDBR - .byte 0x48, 0xb8 - -+/* -+ * This forces the function return instruction to speculate into a trap -+ * (UD2 in srso_return_thunk() below). This RET will then mispredict -+ * and execution will continue at the return site read from the top of -+ * the stack. -+ */ - SYM_INNER_LABEL(srso_safe_ret, SYM_L_GLOBAL) -- add $8, %_ASM_SP -+ lea 8(%_ASM_SP), %_ASM_SP - ret - int3 - int3 -- int3 -+ /* end of movabs */ - lfence - call srso_safe_ret -- int3 -+ ud2 - SYM_CODE_END(srso_safe_ret) - SYM_FUNC_END(srso_untrain_ret) - __EXPORT_THUNK(srso_untrain_ret) - --SYM_FUNC_START(__x86_return_thunk) -- ALTERNATIVE_2 "jmp __ret", "call srso_safe_ret", X86_FEATURE_SRSO, \ -- "call srso_safe_ret_alias", X86_FEATURE_SRSO_ALIAS -+SYM_CODE_START(srso_return_thunk) -+ UNWIND_HINT_FUNC -+ ANNOTATE_NOENDBR -+ call srso_safe_ret -+ ud2 -+SYM_CODE_END(srso_return_thunk) -+ -+SYM_FUNC_START(entry_untrain_ret) -+ ALTERNATIVE_2 "jmp retbleed_untrain_ret", \ -+ "jmp srso_untrain_ret", X86_FEATURE_SRSO, \ -+ "jmp srso_alias_untrain_ret", X86_FEATURE_SRSO_ALIAS -+SYM_FUNC_END(entry_untrain_ret) -+__EXPORT_THUNK(entry_untrain_ret) -+ -+SYM_CODE_START(__x86_return_thunk) -+ UNWIND_HINT_FUNC -+ ANNOTATE_NOENDBR -+ ANNOTATE_UNRET_SAFE -+ ret - int3 - SYM_CODE_END(__x86_return_thunk) - EXPORT_SYMBOL(__x86_return_thunk) -diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c -index a60c5efe34b36..29c35279c7ed8 100644 ---- a/tools/objtool/arch/x86/decode.c -+++ b/tools/objtool/arch/x86/decode.c -@@ -799,5 +799,5 @@ bool arch_is_rethunk(struct symbol *sym) - return !strcmp(sym->name, "__x86_return_thunk") || - !strcmp(sym->name, "srso_untrain_ret") || - !strcmp(sym->name, "srso_safe_ret") || -- !strcmp(sym->name, "__ret"); -+ !strcmp(sym->name, "retbleed_return_thunk"); - } -diff --git a/tools/objtool/check.c b/tools/objtool/check.c -index c2c350933a237..913bd361c3684 100644 ---- a/tools/objtool/check.c -+++ b/tools/objtool/check.c -@@ -379,7 +379,7 @@ static int decode_instructions(struct objtool_file *file) - - if (!strcmp(sec->name, ".noinstr.text") || - !strcmp(sec->name, ".entry.text") || -- !strncmp(sec->name, ".text.__x86.", 12)) -+ !strncmp(sec->name, ".text..__x86.", 13)) - sec->noinstr = true; - - for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) { -@@ -1430,7 +1430,7 @@ static int add_jump_destinations(struct objtool_file *file) - struct symbol *sym = find_symbol_by_offset(dest_sec, dest_off); - - /* -- * This is a special case for zen_untrain_ret(). -+ * This is a special case for retbleed_untrain_ret(). - * It jumps to __x86_return_thunk(), but objtool - * can't find the thunk's starting RET - * instruction, because the RET is also in the -@@ -2450,12 +2450,17 @@ static int decode_sections(struct objtool_file *file) - return 0; - } - --static bool is_fentry_call(struct instruction *insn) -+static bool is_special_call(struct instruction *insn) - { -- if (insn->type == INSN_CALL && -- insn->call_dest && -- insn->call_dest->fentry) -- return true; -+ if (insn->type == INSN_CALL) { -+ struct symbol *dest = insn->call_dest; -+ -+ if (!dest) -+ return false; -+ -+ if (dest->fentry) -+ return true; -+ } - - return false; - } -@@ -3448,7 +3453,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, - if (ret) - return ret; - -- if (opts.stackval && func && !is_fentry_call(insn) && -+ if (opts.stackval && func && !is_special_call(insn) && - !has_valid_stack_frame(&state)) { - WARN_FUNC("call without frame pointer save/setup", - sec, insn->offset); diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.48-49.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.48-49.patch deleted file mode 100644 index 637a71c46467..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.48-49.patch +++ /dev/null @@ -1,292 +0,0 @@ -diff --git a/Makefile b/Makefile -index 8bb8dd199c552..61ebd54aba899 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 48 -+SUBLEVEL = 49 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 78f39a78de29a..4d1e48c676fab 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -3431,6 +3431,7 @@ static inline bool __is_valid_data_blkaddr(block_t blkaddr) - * file.c - */ - int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync); -+void f2fs_truncate_data_blocks(struct dnode_of_data *dn); - int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock); - int f2fs_truncate_blocks(struct inode *inode, u64 from, bool lock); - int f2fs_truncate(struct inode *inode); -diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c -index 3ce6da4fac9c6..7b94f047cbf79 100644 ---- a/fs/f2fs/file.c -+++ b/fs/f2fs/file.c -@@ -628,6 +628,11 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) - dn->ofs_in_node, nr_free); - } - -+void f2fs_truncate_data_blocks(struct dnode_of_data *dn) -+{ -+ f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode)); -+} -+ - static int truncate_partial_data_page(struct inode *inode, u64 from, - bool cache_only) - { -diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c -index 9fe502485930f..a010b4bc36d2c 100644 ---- a/fs/f2fs/node.c -+++ b/fs/f2fs/node.c -@@ -923,7 +923,6 @@ static int truncate_node(struct dnode_of_data *dn) - - static int truncate_dnode(struct dnode_of_data *dn) - { -- struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); - struct page *page; - int err; - -@@ -931,25 +930,16 @@ static int truncate_dnode(struct dnode_of_data *dn) - return 1; - - /* get direct node */ -- page = f2fs_get_node_page(sbi, dn->nid); -+ page = f2fs_get_node_page(F2FS_I_SB(dn->inode), dn->nid); - if (PTR_ERR(page) == -ENOENT) - return 1; - else if (IS_ERR(page)) - return PTR_ERR(page); - -- if (IS_INODE(page) || ino_of_node(page) != dn->inode->i_ino) { -- f2fs_err(sbi, "incorrect node reference, ino: %lu, nid: %u, ino_of_node: %u", -- dn->inode->i_ino, dn->nid, ino_of_node(page)); -- set_sbi_flag(sbi, SBI_NEED_FSCK); -- f2fs_handle_error(sbi, ERROR_INVALID_NODE_REFERENCE); -- f2fs_put_page(page, 1); -- return -EFSCORRUPTED; -- } -- - /* Make dnode_of_data for parameter */ - dn->node_page = page; - dn->ofs_in_node = 0; -- f2fs_truncate_data_blocks_range(dn, ADDRS_PER_BLOCK(dn->inode)); -+ f2fs_truncate_data_blocks(dn); - err = truncate_node(dn); - if (err) { - f2fs_put_page(page, 1); -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index ff47aad636e5b..b6dad389fa144 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -1347,12 +1347,6 @@ default_check: - return -EINVAL; - } - -- if ((f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb)) && -- test_opt(sbi, FLUSH_MERGE)) { -- f2fs_err(sbi, "FLUSH_MERGE not compatible with readonly mode"); -- return -EINVAL; -- } -- - if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) { - f2fs_err(sbi, "Allow to mount readonly mode only"); - return -EROFS; -@@ -1939,10 +1933,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) - seq_puts(seq, ",inline_dentry"); - else - seq_puts(seq, ",noinline_dentry"); -- if (test_opt(sbi, FLUSH_MERGE)) -+ if (!f2fs_readonly(sbi->sb) && test_opt(sbi, FLUSH_MERGE)) - seq_puts(seq, ",flush_merge"); -- else -- seq_puts(seq, ",noflush_merge"); - if (test_opt(sbi, NOBARRIER)) - seq_puts(seq, ",nobarrier"); - if (test_opt(sbi, FASTBOOT)) -@@ -2040,22 +2032,9 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) - return 0; - } - --static void default_options(struct f2fs_sb_info *sbi, bool remount) -+static void default_options(struct f2fs_sb_info *sbi) - { - /* init some FS parameters */ -- if (!remount) { -- set_opt(sbi, READ_EXTENT_CACHE); -- clear_opt(sbi, DISABLE_CHECKPOINT); -- -- if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi)) -- set_opt(sbi, DISCARD); -- -- if (f2fs_sb_has_blkzoned(sbi)) -- F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION; -- else -- F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK; -- } -- - if (f2fs_sb_has_readonly(sbi)) - F2FS_OPTION(sbi).active_logs = NR_CURSEG_RO_TYPE; - else -@@ -2078,16 +2057,22 @@ static void default_options(struct f2fs_sb_info *sbi, bool remount) - set_opt(sbi, INLINE_XATTR); - set_opt(sbi, INLINE_DATA); - set_opt(sbi, INLINE_DENTRY); -+ set_opt(sbi, READ_EXTENT_CACHE); - set_opt(sbi, NOHEAP); -+ clear_opt(sbi, DISABLE_CHECKPOINT); - set_opt(sbi, MERGE_CHECKPOINT); - F2FS_OPTION(sbi).unusable_cap = 0; - sbi->sb->s_flags |= SB_LAZYTIME; -- if (!f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) -- set_opt(sbi, FLUSH_MERGE); -- if (f2fs_sb_has_blkzoned(sbi)) -+ set_opt(sbi, FLUSH_MERGE); -+ if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi)) -+ set_opt(sbi, DISCARD); -+ if (f2fs_sb_has_blkzoned(sbi)) { - F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; -- else -+ F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION; -+ } else { - F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE; -+ F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK; -+ } - - #ifdef CONFIG_F2FS_FS_XATTR - set_opt(sbi, XATTR_USER); -@@ -2259,7 +2244,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) - clear_sbi_flag(sbi, SBI_NEED_SB_WRITE); - } - -- default_options(sbi, true); -+ default_options(sbi); - - /* parse mount options */ - err = parse_options(sb, data, true); -@@ -4156,7 +4141,7 @@ try_onemore: - sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid, - sizeof(raw_super->uuid)); - -- default_options(sbi, false); -+ default_options(sbi); - /* parse mount options */ - options = kstrdup((const char *)data, GFP_KERNEL); - if (data && !options) { -diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h -index 77055b239165a..ee0d75d9a302d 100644 ---- a/include/linux/f2fs_fs.h -+++ b/include/linux/f2fs_fs.h -@@ -104,7 +104,6 @@ enum f2fs_error { - ERROR_INCONSISTENT_SIT, - ERROR_CORRUPTED_VERITY_XATTR, - ERROR_CORRUPTED_XATTR, -- ERROR_INVALID_NODE_REFERENCE, - ERROR_MAX, - }; - -diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c -index 29c35279c7ed8..1ed49ab4e871f 100644 ---- a/tools/objtool/arch/x86/decode.c -+++ b/tools/objtool/arch/x86/decode.c -@@ -796,8 +796,11 @@ bool arch_is_retpoline(struct symbol *sym) - - bool arch_is_rethunk(struct symbol *sym) - { -- return !strcmp(sym->name, "__x86_return_thunk") || -- !strcmp(sym->name, "srso_untrain_ret") || -- !strcmp(sym->name, "srso_safe_ret") || -- !strcmp(sym->name, "retbleed_return_thunk"); -+ return !strcmp(sym->name, "__x86_return_thunk"); -+} -+ -+bool arch_is_embedded_insn(struct symbol *sym) -+{ -+ return !strcmp(sym->name, "retbleed_return_thunk") || -+ !strcmp(sym->name, "srso_safe_ret"); - } -diff --git a/tools/objtool/check.c b/tools/objtool/check.c -index 913bd361c3684..f8008ab31eef0 100644 ---- a/tools/objtool/check.c -+++ b/tools/objtool/check.c -@@ -1164,16 +1164,33 @@ static int add_ignore_alternatives(struct objtool_file *file) - return 0; - } - -+/* -+ * Symbols that replace INSN_CALL_DYNAMIC, every (tail) call to such a symbol -+ * will be added to the .retpoline_sites section. -+ */ - __weak bool arch_is_retpoline(struct symbol *sym) - { - return false; - } - -+/* -+ * Symbols that replace INSN_RETURN, every (tail) call to such a symbol -+ * will be added to the .return_sites section. -+ */ - __weak bool arch_is_rethunk(struct symbol *sym) - { - return false; - } - -+/* -+ * Symbols that are embedded inside other instructions, because sometimes crazy -+ * code exists. These are mostly ignored for validation purposes. -+ */ -+__weak bool arch_is_embedded_insn(struct symbol *sym) -+{ -+ return false; -+} -+ - #define NEGATIVE_RELOC ((void *)-1L) - - static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn) -@@ -1437,7 +1454,7 @@ static int add_jump_destinations(struct objtool_file *file) - * middle of another instruction. Objtool only - * knows about the outer instruction. - */ -- if (sym && sym->return_thunk) { -+ if (sym && sym->embedded_insn) { - add_return_call(file, insn, false); - continue; - } -@@ -2327,6 +2344,9 @@ static int classify_symbols(struct objtool_file *file) - if (arch_is_rethunk(func)) - func->return_thunk = true; - -+ if (arch_is_embedded_insn(func)) -+ func->embedded_insn = true; -+ - if (!strcmp(func->name, "__fentry__")) - func->fentry = true; - -diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h -index beb2f3aa94ffc..861c0c60ac81e 100644 ---- a/tools/objtool/include/objtool/arch.h -+++ b/tools/objtool/include/objtool/arch.h -@@ -90,6 +90,7 @@ int arch_decode_hint_reg(u8 sp_reg, int *base); - - bool arch_is_retpoline(struct symbol *sym); - bool arch_is_rethunk(struct symbol *sym); -+bool arch_is_embedded_insn(struct symbol *sym); - - int arch_rewrite_retpolines(struct objtool_file *file); - -diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h -index 16f4067b82aea..5d4a841fbd311 100644 ---- a/tools/objtool/include/objtool/elf.h -+++ b/tools/objtool/include/objtool/elf.h -@@ -60,6 +60,7 @@ struct symbol { - u8 return_thunk : 1; - u8 fentry : 1; - u8 profiling_func : 1; -+ u8 embedded_insn : 1; - struct list_head pv_target; - }; - diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.49-50.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.49-50.patch deleted file mode 100644 index 4a052c919963..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.49-50.patch +++ /dev/null @@ -1,31691 +0,0 @@ -diff --git a/MAINTAINERS b/MAINTAINERS -index 379387e20a96d..07a9c274c0e29 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -6027,7 +6027,7 @@ S: Supported - F: Documentation/networking/devlink - F: include/net/devlink.h - F: include/uapi/linux/devlink.h --F: net/core/devlink.c -+F: net/devlink/ - - DH ELECTRONICS IMX6 DHCOM BOARD SUPPORT - M: Christoph Niedermaier -diff --git a/Makefile b/Makefile -index 61ebd54aba899..e5e1fdeef8bf0 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 49 -+SUBLEVEL = 50 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h -index c0983130a44c9..e0a4da4cfd8bc 100644 ---- a/arch/mips/include/asm/cpu-features.h -+++ b/arch/mips/include/asm/cpu-features.h -@@ -121,7 +121,24 @@ - #define cpu_has_4k_cache __isa_ge_or_opt(1, MIPS_CPU_4K_CACHE) - #endif - #ifndef cpu_has_octeon_cache --#define cpu_has_octeon_cache 0 -+#define cpu_has_octeon_cache \ -+({ \ -+ int __res; \ -+ \ -+ switch (boot_cpu_type()) { \ -+ case CPU_CAVIUM_OCTEON: \ -+ case CPU_CAVIUM_OCTEON_PLUS: \ -+ case CPU_CAVIUM_OCTEON2: \ -+ case CPU_CAVIUM_OCTEON3: \ -+ __res = 1; \ -+ break; \ -+ \ -+ default: \ -+ __res = 0; \ -+ } \ -+ \ -+ __res; \ -+}) - #endif - /* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work. */ - #ifndef cpu_has_fpu -@@ -351,7 +368,7 @@ - ({ \ - int __res; \ - \ -- switch (current_cpu_type()) { \ -+ switch (boot_cpu_type()) { \ - case CPU_M14KC: \ - case CPU_74K: \ - case CPU_1074K: \ -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index 6bf8dc0b8f935..d702359f8ab5e 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -447,24 +447,30 @@ config TOOLCHAIN_HAS_ZIHINTPAUSE - config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI - def_bool y - # https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc -- depends on AS_IS_GNU && AS_VERSION >= 23800 -+ # https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=98416dbb0a62579d4a7a4a76bab51b5b52fec2cd -+ depends on AS_IS_GNU && AS_VERSION >= 23600 - help -- Newer binutils versions default to ISA spec version 20191213 which -- moves some instructions from the I extension to the Zicsr and Zifencei -- extensions. -+ Binutils-2.38 and GCC-12.1.0 bumped the default ISA spec to the newer -+ 20191213 version, which moves some instructions from the I extension to -+ the Zicsr and Zifencei extensions. This requires explicitly specifying -+ Zicsr and Zifencei when binutils >= 2.38 or GCC >= 12.1.0. Zicsr -+ and Zifencei are supported in binutils from version 2.36 onwards. -+ To make life easier, and avoid forcing toolchains that default to a -+ newer ISA spec to version 2.2, relax the check to binutils >= 2.36. -+ For clang < 17 or GCC < 11.3.0, for which this is not possible or need -+ special treatment, this is dealt with in TOOLCHAIN_NEEDS_OLD_ISA_SPEC. - - config TOOLCHAIN_NEEDS_OLD_ISA_SPEC - def_bool y - depends on TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI - # https://github.com/llvm/llvm-project/commit/22e199e6afb1263c943c0c0d4498694e15bf8a16 -- depends on CC_IS_CLANG && CLANG_VERSION < 170000 -+ # https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=d29f5d6ab513c52fd872f532c492e35ae9fd6671 -+ depends on (CC_IS_CLANG && CLANG_VERSION < 170000) || (CC_IS_GCC && GCC_VERSION < 110300) - help -- Certain versions of clang do not support zicsr and zifencei via -march -- but newer versions of binutils require it for the reasons noted in the -- help text of CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI. This -- option causes an older ISA spec compatible with these older versions -- of clang to be passed to GAS, which has the same result as passing zicsr -- and zifencei to -march. -+ Certain versions of clang and GCC do not support zicsr and zifencei via -+ -march. This option causes an older ISA spec compatible with these older -+ versions of clang and GCC to be passed to GAS, which has the same result -+ as passing zicsr and zifencei to -march. - - config FPU - bool "FPU support" -diff --git a/arch/riscv/kernel/compat_vdso/Makefile b/arch/riscv/kernel/compat_vdso/Makefile -index 7f34f3c7c8827..737c0857b14cd 100644 ---- a/arch/riscv/kernel/compat_vdso/Makefile -+++ b/arch/riscv/kernel/compat_vdso/Makefile -@@ -11,7 +11,13 @@ compat_vdso-syms += flush_icache - COMPAT_CC := $(CC) - COMPAT_LD := $(LD) - --COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32 -+# binutils 2.35 does not support the zifencei extension, but in the ISA -+# spec 20191213, G stands for IMAFD_ZICSR_ZIFENCEI. -+ifdef CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI -+ COMPAT_CC_FLAGS := -march=rv32g -mabi=ilp32 -+else -+ COMPAT_CC_FLAGS := -march=rv32imafd -mabi=ilp32 -+endif - COMPAT_LD_FLAGS := -melf32lriscv - - # Disable attributes, as they're useless and break the build. -diff --git a/arch/x86/kernel/fpu/context.h b/arch/x86/kernel/fpu/context.h -index 9fcfa5c4dad79..71b5059e092ab 100644 ---- a/arch/x86/kernel/fpu/context.h -+++ b/arch/x86/kernel/fpu/context.h -@@ -19,8 +19,7 @@ - * FPU state for a task MUST let the rest of the kernel know that the - * FPU registers are no longer valid for this task. - * -- * Either one of these invalidation functions is enough. Invalidate -- * a resource you control: CPU if using the CPU for something else -+ * Invalidate a resource you control: CPU if using the CPU for something else - * (with preemption disabled), FPU for the current task, or a task that - * is prevented from running by the current task. - */ -diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c -index caf33486dc5ee..a083f9ac9e4f6 100644 ---- a/arch/x86/kernel/fpu/core.c -+++ b/arch/x86/kernel/fpu/core.c -@@ -679,7 +679,7 @@ static void fpu_reset_fpregs(void) - struct fpu *fpu = ¤t->thread.fpu; - - fpregs_lock(); -- fpu__drop(fpu); -+ __fpu_invalidate_fpregs_state(fpu); - /* - * This does not change the actual hardware registers. It just - * resets the memory image and sets TIF_NEED_FPU_LOAD so a -diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c -index 0bab497c94369..1afbc4866b100 100644 ---- a/arch/x86/kernel/fpu/xstate.c -+++ b/arch/x86/kernel/fpu/xstate.c -@@ -882,6 +882,13 @@ void __init fpu__init_system_xstate(unsigned int legacy_size) - goto out_disable; - } - -+ /* -+ * CPU capabilities initialization runs before FPU init. So -+ * X86_FEATURE_OSXSAVE is not set. Now that XSAVE is completely -+ * functional, set the feature bit so depending code works. -+ */ -+ setup_force_cpu_cap(X86_FEATURE_OSXSAVE); -+ - print_xstate_offset_size(); - pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n", - fpu_kernel_cfg.max_features, -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 230108a90cf39..beca03556379d 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -4212,7 +4212,8 @@ static int kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) - * root was invalidated by a memslot update or a relevant mmu_notifier fired. - */ - static bool is_page_fault_stale(struct kvm_vcpu *vcpu, -- struct kvm_page_fault *fault, int mmu_seq) -+ struct kvm_page_fault *fault, -+ unsigned long mmu_seq) - { - struct kvm_mmu_page *sp = to_shadow_page(vcpu->arch.mmu->root.hpa); - -diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c -index 672f0432d7777..70945f00ec412 100644 ---- a/arch/x86/kvm/mmu/tdp_mmu.c -+++ b/arch/x86/kvm/mmu/tdp_mmu.c -@@ -51,7 +51,17 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) - if (!kvm->arch.tdp_mmu_enabled) - return; - -- /* Also waits for any queued work items. */ -+ /* -+ * Invalidate all roots, which besides the obvious, schedules all roots -+ * for zapping and thus puts the TDP MMU's reference to each root, i.e. -+ * ultimately frees all roots. -+ */ -+ kvm_tdp_mmu_invalidate_all_roots(kvm); -+ -+ /* -+ * Destroying a workqueue also first flushes the workqueue, i.e. no -+ * need to invoke kvm_tdp_mmu_zap_invalidated_roots(). -+ */ - destroy_workqueue(kvm->arch.tdp_mmu_zap_wq); - - WARN_ON(!list_empty(&kvm->arch.tdp_mmu_pages)); -@@ -127,16 +137,6 @@ static void tdp_mmu_schedule_zap_root(struct kvm *kvm, struct kvm_mmu_page *root - queue_work(kvm->arch.tdp_mmu_zap_wq, &root->tdp_mmu_async_work); - } - --static inline bool kvm_tdp_root_mark_invalid(struct kvm_mmu_page *page) --{ -- union kvm_mmu_page_role role = page->role; -- role.invalid = true; -- -- /* No need to use cmpxchg, only the invalid bit can change. */ -- role.word = xchg(&page->role.word, role.word); -- return role.invalid; --} -- - void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, - bool shared) - { -@@ -145,45 +145,12 @@ void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, - if (!refcount_dec_and_test(&root->tdp_mmu_root_count)) - return; - -- WARN_ON(!root->tdp_mmu_page); -- - /* -- * The root now has refcount=0. It is valid, but readers already -- * cannot acquire a reference to it because kvm_tdp_mmu_get_root() -- * rejects it. This remains true for the rest of the execution -- * of this function, because readers visit valid roots only -- * (except for tdp_mmu_zap_root_work(), which however -- * does not acquire any reference itself). -- * -- * Even though there are flows that need to visit all roots for -- * correctness, they all take mmu_lock for write, so they cannot yet -- * run concurrently. The same is true after kvm_tdp_root_mark_invalid, -- * since the root still has refcount=0. -- * -- * However, tdp_mmu_zap_root can yield, and writers do not expect to -- * see refcount=0 (see for example kvm_tdp_mmu_invalidate_all_roots()). -- * So the root temporarily gets an extra reference, going to refcount=1 -- * while staying invalid. Readers still cannot acquire any reference; -- * but writers are now allowed to run if tdp_mmu_zap_root yields and -- * they might take an extra reference if they themselves yield. -- * Therefore, when the reference is given back by the worker, -- * there is no guarantee that the refcount is still 1. If not, whoever -- * puts the last reference will free the page, but they will not have to -- * zap the root because a root cannot go from invalid to valid. -+ * The TDP MMU itself holds a reference to each root until the root is -+ * explicitly invalidated, i.e. the final reference should be never be -+ * put for a valid root. - */ -- if (!kvm_tdp_root_mark_invalid(root)) { -- refcount_set(&root->tdp_mmu_root_count, 1); -- -- /* -- * Zapping the root in a worker is not just "nice to have"; -- * it is required because kvm_tdp_mmu_invalidate_all_roots() -- * skips already-invalid roots. If kvm_tdp_mmu_put_root() did -- * not add the root to the workqueue, kvm_tdp_mmu_zap_all_fast() -- * might return with some roots not zapped yet. -- */ -- tdp_mmu_schedule_zap_root(kvm, root); -- return; -- } -+ KVM_BUG_ON(!is_tdp_mmu_page(root) || !root->role.invalid, kvm); - - spin_lock(&kvm->arch.tdp_mmu_pages_lock); - list_del_rcu(&root->link); -@@ -329,7 +296,14 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu) - root = tdp_mmu_alloc_sp(vcpu); - tdp_mmu_init_sp(root, NULL, 0, role); - -- refcount_set(&root->tdp_mmu_root_count, 1); -+ /* -+ * TDP MMU roots are kept until they are explicitly invalidated, either -+ * by a memslot update or by the destruction of the VM. Initialize the -+ * refcount to two; one reference for the vCPU, and one reference for -+ * the TDP MMU itself, which is held until the root is invalidated and -+ * is ultimately put by tdp_mmu_zap_root_work(). -+ */ -+ refcount_set(&root->tdp_mmu_root_count, 2); - - spin_lock(&kvm->arch.tdp_mmu_pages_lock); - list_add_rcu(&root->link, &kvm->arch.tdp_mmu_roots); -@@ -1027,32 +1001,49 @@ void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm) - /* - * Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that - * is about to be zapped, e.g. in response to a memslots update. The actual -- * zapping is performed asynchronously, so a reference is taken on all roots. -- * Using a separate workqueue makes it easy to ensure that the destruction is -- * performed before the "fast zap" completes, without keeping a separate list -- * of invalidated roots; the list is effectively the list of work items in -- * the workqueue. -- * -- * Get a reference even if the root is already invalid, the asynchronous worker -- * assumes it was gifted a reference to the root it processes. Because mmu_lock -- * is held for write, it should be impossible to observe a root with zero refcount, -- * i.e. the list of roots cannot be stale. -+ * zapping is performed asynchronously. Using a separate workqueue makes it -+ * easy to ensure that the destruction is performed before the "fast zap" -+ * completes, without keeping a separate list of invalidated roots; the list is -+ * effectively the list of work items in the workqueue. - * -- * This has essentially the same effect for the TDP MMU -- * as updating mmu_valid_gen does for the shadow MMU. -+ * Note, the asynchronous worker is gifted the TDP MMU's reference. -+ * See kvm_tdp_mmu_get_vcpu_root_hpa(). - */ - void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) - { - struct kvm_mmu_page *root; - -- lockdep_assert_held_write(&kvm->mmu_lock); -- list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) { -- if (!root->role.invalid && -- !WARN_ON_ONCE(!kvm_tdp_mmu_get_root(root))) { -+ /* -+ * mmu_lock must be held for write to ensure that a root doesn't become -+ * invalid while there are active readers (invalidating a root while -+ * there are active readers may or may not be problematic in practice, -+ * but it's uncharted territory and not supported). -+ * -+ * Waive the assertion if there are no users of @kvm, i.e. the VM is -+ * being destroyed after all references have been put, or if no vCPUs -+ * have been created (which means there are no roots), i.e. the VM is -+ * being destroyed in an error path of KVM_CREATE_VM. -+ */ -+ if (IS_ENABLED(CONFIG_PROVE_LOCKING) && -+ refcount_read(&kvm->users_count) && kvm->created_vcpus) -+ lockdep_assert_held_write(&kvm->mmu_lock); -+ -+ /* -+ * As above, mmu_lock isn't held when destroying the VM! There can't -+ * be other references to @kvm, i.e. nothing else can invalidate roots -+ * or be consuming roots, but walking the list of roots does need to be -+ * guarded against roots being deleted by the asynchronous zap worker. -+ */ -+ rcu_read_lock(); -+ -+ list_for_each_entry_rcu(root, &kvm->arch.tdp_mmu_roots, link) { -+ if (!root->role.invalid) { - root->role.invalid = true; - tdp_mmu_schedule_zap_root(kvm, root); - } - } -+ -+ rcu_read_unlock(); - } - - /* -diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c -index 4459cfbdbcb18..c2f0f74193f0e 100644 ---- a/drivers/block/ublk_drv.c -+++ b/drivers/block/ublk_drv.c -@@ -1223,9 +1223,6 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, - __func__, cmd->cmd_op, ub_cmd->q_id, tag, - ub_cmd->result); - -- if (!(issue_flags & IO_URING_F_SQE128)) -- goto out; -- - if (ub_cmd->q_id >= ub->dev_info.nr_hw_queues) - goto out; - -diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c -index 4fb4fd4b06bda..737aa70e2cb3d 100644 ---- a/drivers/clk/clk-devres.c -+++ b/drivers/clk/clk-devres.c -@@ -205,18 +205,19 @@ EXPORT_SYMBOL(devm_clk_put); - struct clk *devm_get_clk_from_child(struct device *dev, - struct device_node *np, const char *con_id) - { -- struct clk **ptr, *clk; -+ struct devm_clk_state *state; -+ struct clk *clk; - -- ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); -- if (!ptr) -+ state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL); -+ if (!state) - return ERR_PTR(-ENOMEM); - - clk = of_clk_get_by_name(np, con_id); - if (!IS_ERR(clk)) { -- *ptr = clk; -- devres_add(dev, ptr); -+ state->clk = clk; -+ devres_add(dev, state); - } else { -- devres_free(ptr); -+ devres_free(state); - } - - return clk; -diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c -index 348b3a9170fa4..7f5ed1aa7a9f8 100644 ---- a/drivers/dma-buf/sw_sync.c -+++ b/drivers/dma-buf/sw_sync.c -@@ -191,6 +191,7 @@ static const struct dma_fence_ops timeline_fence_ops = { - */ - static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) - { -+ LIST_HEAD(signalled); - struct sync_pt *pt, *next; - - trace_sync_timeline(obj); -@@ -203,21 +204,20 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) - if (!timeline_fence_signaled(&pt->base)) - break; - -- list_del_init(&pt->link); -+ dma_fence_get(&pt->base); -+ -+ list_move_tail(&pt->link, &signalled); - rb_erase(&pt->node, &obj->pt_tree); - -- /* -- * A signal callback may release the last reference to this -- * fence, causing it to be freed. That operation has to be -- * last to avoid a use after free inside this loop, and must -- * be after we remove the fence from the timeline in order to -- * prevent deadlocking on timeline->lock inside -- * timeline_fence_release(). -- */ - dma_fence_signal_locked(&pt->base); - } - - spin_unlock_irq(&obj->lock); -+ -+ list_for_each_entry_safe(pt, next, &signalled, link) { -+ list_del_init(&pt->link); -+ dma_fence_put(&pt->base); -+ } - } - - /** -diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c -index fef12e57b1f13..b352775e5e0b8 100644 ---- a/drivers/gpio/gpio-sim.c -+++ b/drivers/gpio/gpio-sim.c -@@ -290,6 +290,15 @@ static void gpio_sim_mutex_destroy(void *data) - mutex_destroy(lock); - } - -+static void gpio_sim_dispose_mappings(void *data) -+{ -+ struct gpio_sim_chip *chip = data; -+ unsigned int i; -+ -+ for (i = 0; i < chip->gc.ngpio; i++) -+ irq_dispose_mapping(irq_find_mapping(chip->irq_sim, i)); -+} -+ - static void gpio_sim_sysfs_remove(void *data) - { - struct gpio_sim_chip *chip = data; -@@ -398,10 +407,14 @@ static int gpio_sim_add_bank(struct fwnode_handle *swnode, struct device *dev) - if (!chip->pull_map) - return -ENOMEM; - -- chip->irq_sim = devm_irq_domain_create_sim(dev, NULL, num_lines); -+ chip->irq_sim = devm_irq_domain_create_sim(dev, swnode, num_lines); - if (IS_ERR(chip->irq_sim)) - return PTR_ERR(chip->irq_sim); - -+ ret = devm_add_action_or_reset(dev, gpio_sim_dispose_mappings, chip); -+ if (ret) -+ return ret; -+ - mutex_init(&chip->lock); - ret = devm_add_action_or_reset(dev, gpio_sim_mutex_destroy, - &chip->lock); -diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c -index a032003c340cc..d6ea47873627f 100644 ---- a/drivers/gpu/drm/arm/hdlcd_drv.c -+++ b/drivers/gpu/drm/arm/hdlcd_drv.c -@@ -290,7 +290,7 @@ static int hdlcd_drm_bind(struct device *dev) - */ - if (hdlcd_read(hdlcd, HDLCD_REG_COMMAND)) { - hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); -- drm_aperture_remove_framebuffers(false, &hdlcd_driver); -+ drm_aperture_remove_framebuffers(&hdlcd_driver); - } - - drm_mode_config_reset(drm); -diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c -index 142668cd6d7cd..688ba358f5319 100644 ---- a/drivers/gpu/drm/armada/armada_drv.c -+++ b/drivers/gpu/drm/armada/armada_drv.c -@@ -95,7 +95,7 @@ static int armada_drm_bind(struct device *dev) - } - - /* Remove early framebuffers */ -- ret = drm_aperture_remove_framebuffers(false, &armada_drm_driver); -+ ret = drm_aperture_remove_framebuffers(&armada_drm_driver); - if (ret) { - dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n", - __func__, ret); -diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c -index b9392f31e6291..800471f2a2037 100644 ---- a/drivers/gpu/drm/ast/ast_drv.c -+++ b/drivers/gpu/drm/ast/ast_drv.c -@@ -89,27 +89,13 @@ static const struct pci_device_id ast_pciidlist[] = { - - MODULE_DEVICE_TABLE(pci, ast_pciidlist); - --static int ast_remove_conflicting_framebuffers(struct pci_dev *pdev) --{ -- bool primary = false; -- resource_size_t base, size; -- -- base = pci_resource_start(pdev, 0); -- size = pci_resource_len(pdev, 0); --#ifdef CONFIG_X86 -- primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; --#endif -- -- return drm_aperture_remove_conflicting_framebuffers(base, size, primary, &ast_driver); --} -- - static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - { - struct ast_private *ast; - struct drm_device *dev; - int ret; - -- ret = ast_remove_conflicting_framebuffers(pdev); -+ ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &ast_driver); - if (ret) - return ret; - -diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c -index 3b8fdeeafd53a..697cffbfd6037 100644 ---- a/drivers/gpu/drm/drm_aperture.c -+++ b/drivers/gpu/drm/drm_aperture.c -@@ -32,17 +32,13 @@ - * - * static int remove_conflicting_framebuffers(struct pci_dev *pdev) - * { -- * bool primary = false; - * resource_size_t base, size; - * int ret; - * - * base = pci_resource_start(pdev, 0); - * size = pci_resource_len(pdev, 0); -- * #ifdef CONFIG_X86 -- * primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -- * #endif - * -- * return drm_aperture_remove_conflicting_framebuffers(base, size, primary, -+ * return drm_aperture_remove_conflicting_framebuffers(base, size, - * &example_driver); - * } - * -@@ -161,7 +157,6 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); - * drm_aperture_remove_conflicting_framebuffers - remove existing framebuffers in the given range - * @base: the aperture's base address in physical memory - * @size: aperture size in bytes -- * @primary: also kick vga16fb if present - * @req_driver: requesting DRM driver - * - * This function removes graphics device drivers which use the memory range described by -@@ -171,9 +166,9 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); - * 0 on success, or a negative errno code otherwise - */ - int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, -- bool primary, const struct drm_driver *req_driver) -+ const struct drm_driver *req_driver) - { -- return aperture_remove_conflicting_devices(base, size, primary, req_driver->name); -+ return aperture_remove_conflicting_devices(base, size, false, req_driver->name); - } - EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers); - -diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c -index cd9c73f5a64ab..738eb558a97e9 100644 ---- a/drivers/gpu/drm/gma500/psb_drv.c -+++ b/drivers/gpu/drm/gma500/psb_drv.c -@@ -424,12 +424,17 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - - /* - * We cannot yet easily find the framebuffer's location in memory. So -- * remove all framebuffers here. -+ * remove all framebuffers here. Note that we still want the pci special -+ * handling to kick out vgacon. - * - * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then we - * might be able to read the framebuffer range from the device. - */ -- ret = drm_aperture_remove_framebuffers(true, &driver); -+ ret = drm_aperture_remove_framebuffers(&driver); -+ if (ret) -+ return ret; -+ -+ ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); - if (ret) - return ret; - -diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -index ca127ff797f75..29ee0814bccc8 100644 ---- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -+++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -@@ -74,7 +74,6 @@ static int hyperv_setup_vram(struct hyperv_drm_device *hv, - - drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, - screen_info.lfb_size, -- false, - &hyperv_driver); - - hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024; -diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -index b2838732ac936..cc84685368715 100644 ---- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -@@ -165,14 +165,60 @@ static u32 preparser_disable(bool state) - return MI_ARB_CHECK | 1 << 8 | state; - } - --u32 *gen12_emit_aux_table_inv(struct intel_gt *gt, u32 *cs, const i915_reg_t inv_reg) -+static i915_reg_t gen12_get_aux_inv_reg(struct intel_engine_cs *engine) - { -- u32 gsi_offset = gt->uncore->gsi_offset; -+ switch (engine->id) { -+ case RCS0: -+ return GEN12_CCS_AUX_INV; -+ case BCS0: -+ return GEN12_BCS0_AUX_INV; -+ case VCS0: -+ return GEN12_VD0_AUX_INV; -+ case VCS2: -+ return GEN12_VD2_AUX_INV; -+ case VECS0: -+ return GEN12_VE0_AUX_INV; -+ case CCS0: -+ return GEN12_CCS0_AUX_INV; -+ default: -+ return INVALID_MMIO_REG; -+ } -+} -+ -+static bool gen12_needs_ccs_aux_inv(struct intel_engine_cs *engine) -+{ -+ i915_reg_t reg = gen12_get_aux_inv_reg(engine); -+ -+ if (IS_PONTEVECCHIO(engine->i915)) -+ return false; -+ -+ /* -+ * So far platforms supported by i915 having flat ccs do not require -+ * AUX invalidation. Check also whether the engine requires it. -+ */ -+ return i915_mmio_reg_valid(reg) && !HAS_FLAT_CCS(engine->i915); -+} -+ -+u32 *gen12_emit_aux_table_inv(struct intel_engine_cs *engine, u32 *cs) -+{ -+ i915_reg_t inv_reg = gen12_get_aux_inv_reg(engine); -+ u32 gsi_offset = engine->gt->uncore->gsi_offset; -+ -+ if (!gen12_needs_ccs_aux_inv(engine)) -+ return cs; - - *cs++ = MI_LOAD_REGISTER_IMM(1) | MI_LRI_MMIO_REMAP_EN; - *cs++ = i915_mmio_reg_offset(inv_reg) + gsi_offset; - *cs++ = AUX_INV; -- *cs++ = MI_NOOP; -+ -+ *cs++ = MI_SEMAPHORE_WAIT_TOKEN | -+ MI_SEMAPHORE_REGISTER_POLL | -+ MI_SEMAPHORE_POLL | -+ MI_SEMAPHORE_SAD_EQ_SDD; -+ *cs++ = 0; -+ *cs++ = i915_mmio_reg_offset(inv_reg) + gsi_offset; -+ *cs++ = 0; -+ *cs++ = 0; - - return cs; - } -@@ -181,7 +227,11 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) - { - struct intel_engine_cs *engine = rq->engine; - -- if (mode & EMIT_FLUSH) { -+ /* -+ * On Aux CCS platforms the invalidation of the Aux -+ * table requires quiescing memory traffic beforehand -+ */ -+ if (mode & EMIT_FLUSH || gen12_needs_ccs_aux_inv(engine)) { - u32 flags = 0; - u32 *cs; - -@@ -236,10 +286,9 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) - else if (engine->class == COMPUTE_CLASS) - flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; - -- if (!HAS_FLAT_CCS(rq->engine->i915)) -- count = 8 + 4; -- else -- count = 8; -+ count = 8; -+ if (gen12_needs_ccs_aux_inv(rq->engine)) -+ count += 8; - - cs = intel_ring_begin(rq, count); - if (IS_ERR(cs)) -@@ -254,11 +303,7 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) - - cs = gen8_emit_pipe_control(cs, flags, LRC_PPHWSP_SCRATCH_ADDR); - -- if (!HAS_FLAT_CCS(rq->engine->i915)) { -- /* hsdes: 1809175790 */ -- cs = gen12_emit_aux_table_inv(rq->engine->gt, cs, -- GEN12_CCS_AUX_INV); -- } -+ cs = gen12_emit_aux_table_inv(engine, cs); - - *cs++ = preparser_disable(false); - intel_ring_advance(rq, cs); -@@ -269,21 +314,14 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) - - int gen12_emit_flush_xcs(struct i915_request *rq, u32 mode) - { -- intel_engine_mask_t aux_inv = 0; -- u32 cmd, *cs; -+ u32 cmd = 4; -+ u32 *cs; - -- cmd = 4; - if (mode & EMIT_INVALIDATE) { - cmd += 2; - -- if (!HAS_FLAT_CCS(rq->engine->i915) && -- (rq->engine->class == VIDEO_DECODE_CLASS || -- rq->engine->class == VIDEO_ENHANCEMENT_CLASS)) { -- aux_inv = rq->engine->mask & -- ~GENMASK(_BCS(I915_MAX_BCS - 1), BCS0); -- if (aux_inv) -- cmd += 4; -- } -+ if (gen12_needs_ccs_aux_inv(rq->engine)) -+ cmd += 8; - } - - cs = intel_ring_begin(rq, cmd); -@@ -314,14 +352,7 @@ int gen12_emit_flush_xcs(struct i915_request *rq, u32 mode) - *cs++ = 0; /* upper addr */ - *cs++ = 0; /* value */ - -- if (aux_inv) { /* hsdes: 1809175790 */ -- if (rq->engine->class == VIDEO_DECODE_CLASS) -- cs = gen12_emit_aux_table_inv(rq->engine->gt, -- cs, GEN12_VD0_AUX_INV); -- else -- cs = gen12_emit_aux_table_inv(rq->engine->gt, -- cs, GEN12_VE0_AUX_INV); -- } -+ cs = gen12_emit_aux_table_inv(rq->engine, cs); - - if (mode & EMIT_INVALIDATE) - *cs++ = preparser_disable(false); -diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.h b/drivers/gpu/drm/i915/gt/gen8_engine_cs.h -index e4d24c811dd61..651eb786e930c 100644 ---- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.h -+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.h -@@ -13,6 +13,7 @@ - #include "intel_gt_regs.h" - #include "intel_gpu_commands.h" - -+struct intel_engine_cs; - struct intel_gt; - struct i915_request; - -@@ -46,7 +47,7 @@ u32 *gen8_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs); - u32 *gen11_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs); - u32 *gen12_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs); - --u32 *gen12_emit_aux_table_inv(struct intel_gt *gt, u32 *cs, const i915_reg_t inv_reg); -+u32 *gen12_emit_aux_table_inv(struct intel_engine_cs *engine, u32 *cs); - - static inline u32 * - __gen8_emit_pipe_control(u32 *batch, u32 flags0, u32 flags1, u32 offset) -diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h -index d4e9702d3c8e7..25ea5f8a464a4 100644 ---- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h -+++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h -@@ -120,6 +120,7 @@ - #define MI_SEMAPHORE_TARGET(engine) ((engine)<<15) - #define MI_SEMAPHORE_WAIT MI_INSTR(0x1c, 2) /* GEN8+ */ - #define MI_SEMAPHORE_WAIT_TOKEN MI_INSTR(0x1c, 3) /* GEN12+ */ -+#define MI_SEMAPHORE_REGISTER_POLL (1 << 16) - #define MI_SEMAPHORE_POLL (1 << 15) - #define MI_SEMAPHORE_SAD_GT_SDD (0 << 12) - #define MI_SEMAPHORE_SAD_GTE_SDD (1 << 12) -diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c -index 137e41e37ea54..7eb01ff17d89b 100644 ---- a/drivers/gpu/drm/i915/gt/intel_lrc.c -+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c -@@ -1296,10 +1296,7 @@ gen12_emit_indirect_ctx_rcs(const struct intel_context *ce, u32 *cs) - IS_DG2_G11(ce->engine->i915)) - cs = gen8_emit_pipe_control(cs, PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE, 0); - -- /* hsdes: 1809175790 */ -- if (!HAS_FLAT_CCS(ce->engine->i915)) -- cs = gen12_emit_aux_table_inv(ce->engine->gt, -- cs, GEN12_CCS_AUX_INV); -+ cs = gen12_emit_aux_table_inv(ce->engine, cs); - - /* Wa_16014892111 */ - if (IS_DG2(ce->engine->i915)) -@@ -1322,17 +1319,7 @@ gen12_emit_indirect_ctx_xcs(const struct intel_context *ce, u32 *cs) - PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE, - 0); - -- /* hsdes: 1809175790 */ -- if (!HAS_FLAT_CCS(ce->engine->i915)) { -- if (ce->engine->class == VIDEO_DECODE_CLASS) -- cs = gen12_emit_aux_table_inv(ce->engine->gt, -- cs, GEN12_VD0_AUX_INV); -- else if (ce->engine->class == VIDEO_ENHANCEMENT_CLASS) -- cs = gen12_emit_aux_table_inv(ce->engine->gt, -- cs, GEN12_VE0_AUX_INV); -- } -- -- return cs; -+ return gen12_emit_aux_table_inv(ce->engine, cs); - } - - static void -diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c -index 35bc2a3fa811c..75a93951fe429 100644 ---- a/drivers/gpu/drm/i915/i915_driver.c -+++ b/drivers/gpu/drm/i915/i915_driver.c -@@ -574,7 +574,6 @@ static int i915_pcode_init(struct drm_i915_private *i915) - static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) - { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); -- struct pci_dev *root_pdev; - int ret; - - if (i915_inject_probe_failure(dev_priv)) -@@ -686,15 +685,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) - - intel_bw_init_hw(dev_priv); - -- /* -- * FIXME: Temporary hammer to avoid freezing the machine on our DGFX -- * This should be totally removed when we handle the pci states properly -- * on runtime PM and on s2idle cases. -- */ -- root_pdev = pcie_find_root_port(pdev); -- if (root_pdev) -- pci_d3cold_disable(root_pdev); -- - return 0; - - err_msi: -@@ -718,16 +708,11 @@ err_perf: - static void i915_driver_hw_remove(struct drm_i915_private *dev_priv) - { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); -- struct pci_dev *root_pdev; - - i915_perf_fini(dev_priv); - - if (pdev->msi_enabled) - pci_disable_msi(pdev); -- -- root_pdev = pcie_find_root_port(pdev); -- if (root_pdev) -- pci_d3cold_enable(root_pdev); - } - - /** -@@ -1625,6 +1610,8 @@ static int intel_runtime_suspend(struct device *kdev) - { - struct drm_i915_private *dev_priv = kdev_to_i915(kdev); - struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; -+ struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); -+ struct pci_dev *root_pdev; - struct intel_gt *gt; - int ret, i; - -@@ -1674,6 +1661,15 @@ static int intel_runtime_suspend(struct device *kdev) - drm_err(&dev_priv->drm, - "Unclaimed access detected prior to suspending\n"); - -+ /* -+ * FIXME: Temporary hammer to avoid freezing the machine on our DGFX -+ * This should be totally removed when we handle the pci states properly -+ * on runtime PM. -+ */ -+ root_pdev = pcie_find_root_port(pdev); -+ if (root_pdev) -+ pci_d3cold_disable(root_pdev); -+ - rpm->suspended = true; - - /* -@@ -1712,6 +1708,8 @@ static int intel_runtime_resume(struct device *kdev) - { - struct drm_i915_private *dev_priv = kdev_to_i915(kdev); - struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; -+ struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); -+ struct pci_dev *root_pdev; - struct intel_gt *gt; - int ret, i; - -@@ -1725,6 +1723,11 @@ static int intel_runtime_resume(struct device *kdev) - - intel_opregion_notify_adapter(dev_priv, PCI_D0); - rpm->suspended = false; -+ -+ root_pdev = pcie_find_root_port(pdev); -+ if (root_pdev) -+ pci_d3cold_enable(root_pdev); -+ - if (intel_uncore_unclaimed_mmio(&dev_priv->uncore)) - drm_dbg(&dev_priv->drm, - "Unclaimed access during suspend, bios?\n"); -diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index eea433ade79d0..119544d88b586 100644 ---- a/drivers/gpu/drm/meson/meson_drv.c -+++ b/drivers/gpu/drm/meson/meson_drv.c -@@ -285,7 +285,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) - * Remove early framebuffers (ie. simplefb). The framebuffer can be - * located anywhere in RAM - */ -- ret = drm_aperture_remove_framebuffers(false, &meson_driver); -+ ret = drm_aperture_remove_framebuffers(&meson_driver); - if (ret) - goto free_drm; - -diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c -index 46168eccfac4a..d4a9b501e1bcc 100644 ---- a/drivers/gpu/drm/msm/msm_fbdev.c -+++ b/drivers/gpu/drm/msm/msm_fbdev.c -@@ -157,7 +157,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) - } - - /* the fw fb could be anywhere in memory */ -- ret = drm_aperture_remove_framebuffers(false, dev->driver); -+ ret = drm_aperture_remove_framebuffers(dev->driver); - if (ret) - goto fini; - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -index 813f9f8c86982..8e12053a220b0 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c -@@ -140,7 +140,7 @@ static int rockchip_drm_bind(struct device *dev) - int ret; - - /* Remove existing drivers that may own the framebuffer memory. */ -- ret = drm_aperture_remove_framebuffers(false, &rockchip_drm_driver); -+ ret = drm_aperture_remove_framebuffers(&rockchip_drm_driver); - if (ret) { - DRM_DEV_ERROR(dev, - "Failed to remove existing framebuffers - %d.\n", -diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c -index d7914f5122dff..0a09a85ac9d69 100644 ---- a/drivers/gpu/drm/stm/drv.c -+++ b/drivers/gpu/drm/stm/drv.c -@@ -185,7 +185,7 @@ static int stm_drm_platform_probe(struct platform_device *pdev) - - DRM_DEBUG("%s\n", __func__); - -- ret = drm_aperture_remove_framebuffers(false, &drv_driver); -+ ret = drm_aperture_remove_framebuffers(&drv_driver); - if (ret) - return ret; - -diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c -index 7910c5853f0a8..5c483bbccbbbc 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_drv.c -+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c -@@ -98,7 +98,7 @@ static int sun4i_drv_bind(struct device *dev) - goto unbind_all; - - /* Remove early framebuffers (ie. simplefb) */ -- ret = drm_aperture_remove_framebuffers(false, &sun4i_drv_driver); -+ ret = drm_aperture_remove_framebuffers(&sun4i_drv_driver); - if (ret) - goto unbind_all; - -diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c -index a1f909dac89a7..5fc55b9777cbf 100644 ---- a/drivers/gpu/drm/tegra/drm.c -+++ b/drivers/gpu/drm/tegra/drm.c -@@ -1252,7 +1252,7 @@ static int host1x_drm_probe(struct host1x_device *dev) - - drm_mode_config_reset(drm); - -- err = drm_aperture_remove_framebuffers(false, &tegra_drm_driver); -+ err = drm_aperture_remove_framebuffers(&tegra_drm_driver); - if (err < 0) - goto hub; - -diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c -index 8c329c071c62d..b6384a5dfdbc1 100644 ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -351,7 +351,7 @@ static int vc4_drm_bind(struct device *dev) - return -EPROBE_DEFER; - } - -- ret = drm_aperture_remove_framebuffers(false, driver); -+ ret = drm_aperture_remove_framebuffers(driver); - if (ret) - return ret; - -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -index 1ec9c53a7bf43..8459fab9d9797 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -@@ -1683,4 +1683,16 @@ static inline bool vmw_has_fences(struct vmw_private *vmw) - return (vmw_fifo_caps(vmw) & SVGA_FIFO_CAP_FENCE) != 0; - } - -+static inline bool vmw_shadertype_is_valid(enum vmw_sm_type shader_model, -+ u32 shader_type) -+{ -+ SVGA3dShaderType max_allowed = SVGA3D_SHADERTYPE_PREDX_MAX; -+ -+ if (shader_model >= VMW_SM_5) -+ max_allowed = SVGA3D_SHADERTYPE_MAX; -+ else if (shader_model >= VMW_SM_4) -+ max_allowed = SVGA3D_SHADERTYPE_DX10_MAX; -+ return shader_type >= SVGA3D_SHADERTYPE_MIN && shader_type < max_allowed; -+} -+ - #endif -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -index 1c88b74d68cf0..58ca9adf09871 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -@@ -1985,7 +1985,7 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, - - cmd = container_of(header, typeof(*cmd), header); - -- if (cmd->body.type >= SVGA3D_SHADERTYPE_PREDX_MAX) { -+ if (!vmw_shadertype_is_valid(VMW_SM_LEGACY, cmd->body.type)) { - VMW_DEBUG_USER("Illegal shader type %u.\n", - (unsigned int) cmd->body.type); - return -EINVAL; -@@ -2108,8 +2108,6 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, - SVGA3dCmdHeader *header) - { - VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetSingleConstantBuffer); -- SVGA3dShaderType max_shader_num = has_sm5_context(dev_priv) ? -- SVGA3D_NUM_SHADERTYPE : SVGA3D_NUM_SHADERTYPE_DX10; - - struct vmw_resource *res = NULL; - struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); -@@ -2126,6 +2124,14 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, - if (unlikely(ret != 0)) - return ret; - -+ if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type) || -+ cmd->body.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { -+ VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", -+ (unsigned int) cmd->body.type, -+ (unsigned int) cmd->body.slot); -+ return -EINVAL; -+ } -+ - binding.bi.ctx = ctx_node->ctx; - binding.bi.res = res; - binding.bi.bt = vmw_ctx_binding_cb; -@@ -2134,14 +2140,6 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, - binding.size = cmd->body.sizeInBytes; - binding.slot = cmd->body.slot; - -- if (binding.shader_slot >= max_shader_num || -- binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { -- VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", -- (unsigned int) cmd->body.type, -- (unsigned int) binding.slot); -- return -EINVAL; -- } -- - vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot, - binding.slot); - -@@ -2200,15 +2198,13 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv, - { - VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) = - container_of(header, typeof(*cmd), header); -- SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ? -- SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX; - - u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) / - sizeof(SVGA3dShaderResourceViewId); - - if ((u64) cmd->body.startView + (u64) num_sr_view > - (u64) SVGA3D_DX_MAX_SRVIEWS || -- cmd->body.type >= max_allowed) { -+ !vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) { - VMW_DEBUG_USER("Invalid shader binding.\n"); - return -EINVAL; - } -@@ -2232,8 +2228,6 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, - SVGA3dCmdHeader *header) - { - VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShader); -- SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ? -- SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX; - struct vmw_resource *res = NULL; - struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); - struct vmw_ctx_bindinfo_shader binding; -@@ -2244,8 +2238,7 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, - - cmd = container_of(header, typeof(*cmd), header); - -- if (cmd->body.type >= max_allowed || -- cmd->body.type < SVGA3D_SHADERTYPE_MIN) { -+ if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) { - VMW_DEBUG_USER("Illegal shader type %u.\n", - (unsigned int) cmd->body.type); - return -EINVAL; -diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c -index c51a2678f0eb5..8c7796d3fdd2d 100644 ---- a/drivers/hwmon/aquacomputer_d5next.c -+++ b/drivers/hwmon/aquacomputer_d5next.c -@@ -12,9 +12,11 @@ - - #include - #include -+#include - #include - #include - #include -+#include - #include - #include - #include -@@ -49,6 +51,8 @@ static const char *const aqc_device_names[] = { - - #define CTRL_REPORT_ID 0x03 - -+#define CTRL_REPORT_DELAY 200 /* ms */ -+ - /* The HID report that the official software always sends - * after writing values, currently same for all devices - */ -@@ -269,6 +273,9 @@ struct aqc_data { - enum kinds kind; - const char *name; - -+ ktime_t last_ctrl_report_op; -+ int ctrl_report_delay; /* Delay between two ctrl report operations, in ms */ -+ - int buffer_size; - u8 *buffer; - int checksum_start; -@@ -325,17 +332,35 @@ static int aqc_pwm_to_percent(long val) - return DIV_ROUND_CLOSEST(val * 100 * 100, 255); - } - -+static void aqc_delay_ctrl_report(struct aqc_data *priv) -+{ -+ /* -+ * If previous read or write is too close to this one, delay the current operation -+ * to give the device enough time to process the previous one. -+ */ -+ if (priv->ctrl_report_delay) { -+ s64 delta = ktime_ms_delta(ktime_get(), priv->last_ctrl_report_op); -+ -+ if (delta < priv->ctrl_report_delay) -+ msleep(priv->ctrl_report_delay - delta); -+ } -+} -+ - /* Expects the mutex to be locked */ - static int aqc_get_ctrl_data(struct aqc_data *priv) - { - int ret; - -+ aqc_delay_ctrl_report(priv); -+ - memset(priv->buffer, 0x00, priv->buffer_size); - ret = hid_hw_raw_request(priv->hdev, CTRL_REPORT_ID, priv->buffer, priv->buffer_size, - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - if (ret < 0) - ret = -ENODATA; - -+ priv->last_ctrl_report_op = ktime_get(); -+ - return ret; - } - -@@ -345,6 +370,8 @@ static int aqc_send_ctrl_data(struct aqc_data *priv) - int ret; - u16 checksum; - -+ aqc_delay_ctrl_report(priv); -+ - /* Init and xorout value for CRC-16/USB is 0xffff */ - checksum = crc16(0xffff, priv->buffer + priv->checksum_start, priv->checksum_length); - checksum ^= 0xffff; -@@ -356,12 +383,16 @@ static int aqc_send_ctrl_data(struct aqc_data *priv) - ret = hid_hw_raw_request(priv->hdev, CTRL_REPORT_ID, priv->buffer, priv->buffer_size, - HID_FEATURE_REPORT, HID_REQ_SET_REPORT); - if (ret < 0) -- return ret; -+ goto record_access_and_ret; - - /* The official software sends this report after every change, so do it here as well */ - ret = hid_hw_raw_request(priv->hdev, SECONDARY_CTRL_REPORT_ID, secondary_ctrl_report, - SECONDARY_CTRL_REPORT_SIZE, HID_FEATURE_REPORT, - HID_REQ_SET_REPORT); -+ -+record_access_and_ret: -+ priv->last_ctrl_report_op = ktime_get(); -+ - return ret; - } - -@@ -853,6 +884,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) - priv->virtual_temp_sensor_start_offset = D5NEXT_VIRTUAL_SENSORS_START; - priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES; - priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE; -+ priv->ctrl_report_delay = CTRL_REPORT_DELAY; - - priv->temp_label = label_d5next_temp; - priv->virtual_temp_label = label_virtual_temp_sensors; -@@ -893,6 +925,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) - priv->virtual_temp_sensor_start_offset = OCTO_VIRTUAL_SENSORS_START; - priv->power_cycle_count_offset = OCTO_POWER_CYCLES; - priv->buffer_size = OCTO_CTRL_REPORT_SIZE; -+ priv->ctrl_report_delay = CTRL_REPORT_DELAY; - - priv->temp_label = label_temp_sensors; - priv->virtual_temp_label = label_virtual_temp_sensors; -@@ -913,6 +946,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) - priv->virtual_temp_sensor_start_offset = QUADRO_VIRTUAL_SENSORS_START; - priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; - priv->buffer_size = QUADRO_CTRL_REPORT_SIZE; -+ priv->ctrl_report_delay = CTRL_REPORT_DELAY; - priv->flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET; - - priv->temp_label = label_temp_sensors; -diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c -index d810a78dde51d..31e3c37662185 100644 ---- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c -+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c -@@ -821,6 +821,8 @@ static int vb2ops_venc_queue_setup(struct vb2_queue *vq, - return -EINVAL; - - if (*nplanes) { -+ if (*nplanes != q_data->fmt->num_planes) -+ return -EINVAL; - for (i = 0; i < *nplanes; i++) - if (sizes[i] < q_data->sizeimage[i]) - return -EINVAL; -diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c -index b9dbad3a8af82..fc5da5d7744da 100644 ---- a/drivers/net/bonding/bond_alb.c -+++ b/drivers/net/bonding/bond_alb.c -@@ -660,10 +660,10 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) - return NULL; - arp = (struct arp_pkt *)skb_network_header(skb); - -- /* Don't modify or load balance ARPs that do not originate locally -- * (e.g.,arrive via a bridge). -+ /* Don't modify or load balance ARPs that do not originate -+ * from the bond itself or a VLAN directly above the bond. - */ -- if (!bond_slave_has_mac_rx(bond, arp->mac_src)) -+ if (!bond_slave_has_mac_rcu(bond, arp->mac_src)) - return NULL; - - dev = ip_dev_find(dev_net(bond->dev), arp->ip_src); -diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c -index 26a472d2ea583..6d549dbdb4674 100644 ---- a/drivers/net/can/vxcan.c -+++ b/drivers/net/can/vxcan.c -@@ -192,12 +192,7 @@ static int vxcan_newlink(struct net *net, struct net_device *dev, - - nla_peer = data[VXCAN_INFO_PEER]; - ifmp = nla_data(nla_peer); -- err = rtnl_nla_parse_ifla(peer_tb, -- nla_data(nla_peer) + -- sizeof(struct ifinfomsg), -- nla_len(nla_peer) - -- sizeof(struct ifinfomsg), -- NULL); -+ err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack); - if (err < 0) - return err; - -diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c -index 51d2ef0dc835c..b988c8a40d536 100644 ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1005,6 +1005,10 @@ mt753x_trap_frames(struct mt7530_priv *priv) - mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, - MT753X_BPDU_CPU_ONLY); - -+ /* Trap 802.1X PAE frames to the CPU port(s) */ -+ mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_PORT_FW_MASK, -+ MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY)); -+ - /* Trap LLDP frames with :0E MAC DA to the CPU port(s) */ - mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_PORT_FW_MASK, - MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY)); -diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h -index 9a45663d8b4ef..6202b0f8c3f34 100644 ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -64,6 +64,8 @@ enum mt753x_id { - /* Registers for BPDU and PAE frame control*/ - #define MT753X_BPC 0x24 - #define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0) -+#define MT753X_PAE_PORT_FW_MASK GENMASK(18, 16) -+#define MT753X_PAE_PORT_FW(x) FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x) - - /* Register for :03 and :0E MAC DA frame control */ - #define MT753X_RGAC2 0x2c -diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c -index 5f6af0870dfd6..0186482194d20 100644 ---- a/drivers/net/dsa/ocelot/felix_vsc9959.c -+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c -@@ -1071,6 +1071,9 @@ static u64 vsc9959_tas_remaining_gate_len_ps(u64 gate_len_ns) - if (gate_len_ns == U64_MAX) - return U64_MAX; - -+ if (gate_len_ns < VSC9959_TAS_MIN_GATE_LEN_NS) -+ return 0; -+ - return (gate_len_ns - VSC9959_TAS_MIN_GATE_LEN_NS) * PSEC_PER_NSEC; - } - -diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c -index 10c7c232cc4ec..52ee3751187a2 100644 ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -1448,7 +1448,7 @@ int bgmac_phy_connect_direct(struct bgmac *bgmac) - int err; - - phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, NULL); -- if (!phy_dev || IS_ERR(phy_dev)) { -+ if (IS_ERR(phy_dev)) { - dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); - return -ENODEV; - } -diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c -index 1fe8038587ac8..1779ee524dac7 100644 ---- a/drivers/net/ethernet/broadcom/genet/bcmmii.c -+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c -@@ -608,7 +608,7 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) - }; - - phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL); -- if (!phydev || IS_ERR(phydev)) { -+ if (IS_ERR(phydev)) { - dev_err(kdev, "failed to register fixed PHY device\n"); - return -ENODEV; - } -diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c -index c2e7037c7ba1c..7750702900fa6 100644 ---- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c -+++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c -@@ -1466,7 +1466,7 @@ static void make_established(struct sock *sk, u32 snd_isn, unsigned int opt) - tp->write_seq = snd_isn; - tp->snd_nxt = snd_isn; - tp->snd_una = snd_isn; -- inet_sk(sk)->inet_id = get_random_u16(); -+ atomic_set(&inet_sk(sk)->inet_id, get_random_u16()); - assign_rxopt(sk, opt); - - if (tp->rcv_wnd > (RCV_BUFSIZ_M << 10)) -diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c -index 5b96cd94dcd24..0b4ec6e41eb41 100644 ---- a/drivers/net/ethernet/ibm/ibmveth.c -+++ b/drivers/net/ethernet/ibm/ibmveth.c -@@ -203,7 +203,7 @@ static inline void ibmveth_flush_buffer(void *addr, unsigned long length) - unsigned long offset; - - for (offset = 0; offset < length; offset += SMP_CACHE_BYTES) -- asm("dcbfl %0,%1" :: "b" (addr), "r" (offset)); -+ asm("dcbf %0,%1,1" :: "b" (addr), "r" (offset)); - } - - /* replenish the buffers for a pool. note that we don't need to -diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c -index 0e01b1927c1c6..08ccf0024ce1a 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -2615,7 +2615,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) - retval = i40e_correct_mac_vlan_filters - (vsi, &tmp_add_list, &tmp_del_list, - vlan_filters); -- else -+ else if (pf->vf) - retval = i40e_correct_vf_mac_vlan_filters - (vsi, &tmp_add_list, &tmp_del_list, - vlan_filters, pf->vf[vsi->vf_id].trusted); -@@ -2788,7 +2788,8 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) - } - - /* if the VF is not trusted do not do promisc */ -- if ((vsi->type == I40E_VSI_SRIOV) && !pf->vf[vsi->vf_id].trusted) { -+ if (vsi->type == I40E_VSI_SRIOV && pf->vf && -+ !pf->vf[vsi->vf_id].trusted) { - clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state); - goto out; - } -diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c -index e864634d66bc6..818eca6aa4a41 100644 ---- a/drivers/net/ethernet/intel/ice/ice_base.c -+++ b/drivers/net/ethernet/intel/ice/ice_base.c -@@ -396,7 +396,8 @@ static int ice_setup_rx_ctx(struct ice_rx_ring *ring) - /* Receive Packet Data Buffer Size. - * The Packet Data Buffer Size is defined in 128 byte units. - */ -- rlan_ctx.dbuf = ring->rx_buf_len >> ICE_RLAN_CTX_DBUF_S; -+ rlan_ctx.dbuf = DIV_ROUND_UP(ring->rx_buf_len, -+ BIT_ULL(ICE_RLAN_CTX_DBUF_S)); - - /* use 32 byte descriptors */ - rlan_ctx.dsize = 1; -diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c -index b8c31bf721ad1..b719e9a771e36 100644 ---- a/drivers/net/ethernet/intel/ice/ice_sriov.c -+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c -@@ -1240,7 +1240,7 @@ int ice_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool ena) - if (!vf) - return -EINVAL; - -- ret = ice_check_vf_ready_for_reset(vf); -+ ret = ice_check_vf_ready_for_cfg(vf); - if (ret) - goto out_put_vf; - -@@ -1355,7 +1355,7 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) - goto out_put_vf; - } - -- ret = ice_check_vf_ready_for_reset(vf); -+ ret = ice_check_vf_ready_for_cfg(vf); - if (ret) - goto out_put_vf; - -@@ -1409,7 +1409,7 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted) - return -EOPNOTSUPP; - } - -- ret = ice_check_vf_ready_for_reset(vf); -+ ret = ice_check_vf_ready_for_cfg(vf); - if (ret) - goto out_put_vf; - -@@ -1722,7 +1722,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos, - if (!vf) - return -EINVAL; - -- ret = ice_check_vf_ready_for_reset(vf); -+ ret = ice_check_vf_ready_for_cfg(vf); - if (ret) - goto out_put_vf; - -diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c -index 71047fc341392..9dbe6e9bb1f79 100644 ---- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c -+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c -@@ -185,25 +185,6 @@ int ice_check_vf_ready_for_cfg(struct ice_vf *vf) - return 0; - } - --/** -- * ice_check_vf_ready_for_reset - check if VF is ready to be reset -- * @vf: VF to check if it's ready to be reset -- * -- * The purpose of this function is to ensure that the VF is not in reset, -- * disabled, and is both initialized and active, thus enabling us to safely -- * initialize another reset. -- */ --int ice_check_vf_ready_for_reset(struct ice_vf *vf) --{ -- int ret; -- -- ret = ice_check_vf_ready_for_cfg(vf); -- if (!ret && !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) -- ret = -EAGAIN; -- -- return ret; --} -- - /** - * ice_trigger_vf_reset - Reset a VF on HW - * @vf: pointer to the VF structure -@@ -588,11 +569,17 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) - return 0; - } - -+ if (flags & ICE_VF_RESET_LOCK) -+ mutex_lock(&vf->cfg_lock); -+ else -+ lockdep_assert_held(&vf->cfg_lock); -+ - if (ice_is_vf_disabled(vf)) { - vsi = ice_get_vf_vsi(vf); - if (!vsi) { - dev_dbg(dev, "VF is already removed\n"); -- return -EINVAL; -+ err = -EINVAL; -+ goto out_unlock; - } - ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id); - -@@ -601,14 +588,9 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) - - dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n", - vf->vf_id); -- return 0; -+ goto out_unlock; - } - -- if (flags & ICE_VF_RESET_LOCK) -- mutex_lock(&vf->cfg_lock); -- else -- lockdep_assert_held(&vf->cfg_lock); -- - /* Set VF disable bit state here, before triggering reset */ - set_bit(ICE_VF_STATE_DIS, vf->vf_states); - ice_trigger_vf_reset(vf, flags & ICE_VF_RESET_VFLR, false); -diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h -index e5bed85724622..9f7fcd8e5714b 100644 ---- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h -+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h -@@ -214,7 +214,6 @@ u16 ice_get_num_vfs(struct ice_pf *pf); - struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf); - bool ice_is_vf_disabled(struct ice_vf *vf); - int ice_check_vf_ready_for_cfg(struct ice_vf *vf); --int ice_check_vf_ready_for_reset(struct ice_vf *vf); - void ice_set_vf_state_dis(struct ice_vf *vf); - bool ice_is_any_vf_in_unicast_promisc(struct ice_pf *pf); - void -diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c -index ef3c709d6a750..2b4c791b6cbad 100644 ---- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c -+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c -@@ -3722,7 +3722,6 @@ error_handler: - ice_vc_notify_vf_link_state(vf); - break; - case VIRTCHNL_OP_RESET_VF: -- clear_bit(ICE_VF_STATE_ACTIVE, vf->vf_states); - ops->reset_vf(vf); - break; - case VIRTCHNL_OP_ADD_ETH_ADDR: -diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c -index 15e57460e19ea..07171e574e7d7 100644 ---- a/drivers/net/ethernet/intel/igb/igb_ptp.c -+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c -@@ -1404,18 +1404,6 @@ void igb_ptp_init(struct igb_adapter *adapter) - return; - } - -- spin_lock_init(&adapter->tmreg_lock); -- INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work); -- -- if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK) -- INIT_DELAYED_WORK(&adapter->ptp_overflow_work, -- igb_ptp_overflow_check); -- -- adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; -- adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF; -- -- igb_ptp_reset(adapter); -- - adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, - &adapter->pdev->dev); - if (IS_ERR(adapter->ptp_clock)) { -@@ -1425,6 +1413,18 @@ void igb_ptp_init(struct igb_adapter *adapter) - dev_info(&adapter->pdev->dev, "added PHC on %s\n", - adapter->netdev->name); - adapter->ptp_flags |= IGB_PTP_ENABLED; -+ -+ spin_lock_init(&adapter->tmreg_lock); -+ INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work); -+ -+ if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK) -+ INIT_DELAYED_WORK(&adapter->ptp_overflow_work, -+ igb_ptp_overflow_check); -+ -+ adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; -+ adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF; -+ -+ igb_ptp_reset(adapter); - } - } - -diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h -index dbfa4b9dee066..90ca01889cd82 100644 ---- a/drivers/net/ethernet/intel/igc/igc_defines.h -+++ b/drivers/net/ethernet/intel/igc/igc_defines.h -@@ -536,7 +536,7 @@ - #define IGC_PTM_CTRL_START_NOW BIT(29) /* Start PTM Now */ - #define IGC_PTM_CTRL_EN BIT(30) /* Enable PTM */ - #define IGC_PTM_CTRL_TRIG BIT(31) /* PTM Cycle trigger */ --#define IGC_PTM_CTRL_SHRT_CYC(usec) (((usec) & 0x2f) << 2) -+#define IGC_PTM_CTRL_SHRT_CYC(usec) (((usec) & 0x3f) << 2) - #define IGC_PTM_CTRL_PTM_TO(usec) (((usec) & 0xff) << 8) - - #define IGC_PTM_SHORT_CYC_DEFAULT 10 /* Default Short/interrupted cycle interval */ -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -index 705325431dec3..5541e284cd3f0 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -@@ -4005,9 +4005,10 @@ rx_frscfg: - if (link < 0) - return NIX_AF_ERR_RX_LINK_INVALID; - -- nix_find_link_frs(rvu, req, pcifunc); - - linkcfg: -+ nix_find_link_frs(rvu, req, pcifunc); -+ - cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link)); - cfg = (cfg & ~(0xFFFFULL << 16)) | ((u64)req->maxlen << 16); - if (req->update_minlen) -diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c -index bd1a51a0a5408..f208a237d0b52 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c -@@ -32,8 +32,8 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = { - MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8), - MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2), - MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6), -- MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_MSB, 0x18, 17, 3), -- MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_LSB, 0x18, 20, 8), -+ MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_MSB, 0x18, 17, 4), -+ MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_LSB, 0x18, 21, 8), - MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4), - MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4), - MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4), -diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c -index c968309657dd1..51eea1f0529c8 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/pci.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c -@@ -517,11 +517,15 @@ static void mlxsw_pci_skb_cb_ts_set(struct mlxsw_pci *mlxsw_pci, - struct sk_buff *skb, - enum mlxsw_pci_cqe_v cqe_v, char *cqe) - { -+ u8 ts_type; -+ - if (cqe_v != MLXSW_PCI_CQE_V2) - return; - -- if (mlxsw_pci_cqe2_time_stamp_type_get(cqe) != -- MLXSW_PCI_CQE_TIME_STAMP_TYPE_UTC) -+ ts_type = mlxsw_pci_cqe2_time_stamp_type_get(cqe); -+ -+ if (ts_type != MLXSW_PCI_CQE_TIME_STAMP_TYPE_UTC && -+ ts_type != MLXSW_PCI_CQE_TIME_STAMP_TYPE_MIRROR_UTC) - return; - - mlxsw_skb_cb(skb)->cqe_ts.sec = mlxsw_pci_cqe2_time_stamp_sec_get(cqe); -diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h -index 0777bed5bb1af..a34ff19c58bd2 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/reg.h -+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h -@@ -97,14 +97,6 @@ MLXSW_ITEM32(reg, sspr, m, 0x00, 31, 1); - */ - MLXSW_ITEM32_LP(reg, sspr, 0x00, 16, 0x00, 12); - --/* reg_sspr_sub_port -- * Virtual port within the physical port. -- * Should be set to 0 when virtual ports are not enabled on the port. -- * -- * Access: RW -- */ --MLXSW_ITEM32(reg, sspr, sub_port, 0x00, 8, 8); -- - /* reg_sspr_system_port - * Unique identifier within the stacking domain that represents all the ports - * that are available in the system (external ports). -@@ -120,7 +112,6 @@ static inline void mlxsw_reg_sspr_pack(char *payload, u16 local_port) - MLXSW_REG_ZERO(sspr, payload); - mlxsw_reg_sspr_m_set(payload, 1); - mlxsw_reg_sspr_local_port_set(payload, local_port); -- mlxsw_reg_sspr_sub_port_set(payload, 0); - mlxsw_reg_sspr_system_port_set(payload, local_port); - } - -diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c -index e4f4cded2b6f9..b1178b7a7f51a 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c -@@ -193,7 +193,7 @@ mlxsw_sp2_mr_tcam_rule_parse(struct mlxsw_sp_acl_rule *rule, - key->vrid, GENMASK(7, 0)); - mlxsw_sp_acl_rulei_keymask_u32(rulei, - MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB, -- key->vrid >> 8, GENMASK(2, 0)); -+ key->vrid >> 8, GENMASK(3, 0)); - switch (key->proto) { - case MLXSW_SP_L3_PROTO_IPV4: - return mlxsw_sp2_mr_tcam_rule_parse4(rulei, key); -diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c -index 00c32320f8915..173808c096bab 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c -@@ -169,7 +169,7 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_2[] = { - - static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4[] = { - MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_LSB, 0x04, 24, 8), -- MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_MSB, 0x00, 0, 3), -+ MLXSW_AFK_ELEMENT_INST_EXT_U32(VIRT_ROUTER_MSB, 0x00, 0, 3, 0, true), - }; - - static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = { -@@ -319,7 +319,7 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = { - - static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4b[] = { - MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_LSB, 0x04, 13, 8), -- MLXSW_AFK_ELEMENT_INST_EXT_U32(VIRT_ROUTER_MSB, 0x04, 21, 4, 0, true), -+ MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_MSB, 0x04, 21, 4), - }; - - static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = { -diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c -index 796a38f9d7b24..cd16bc8bf154c 100644 ---- a/drivers/net/ipvlan/ipvlan_main.c -+++ b/drivers/net/ipvlan/ipvlan_main.c -@@ -748,7 +748,8 @@ static int ipvlan_device_event(struct notifier_block *unused, - - write_pnet(&port->pnet, newnet); - -- ipvlan_migrate_l3s_hook(oldnet, newnet); -+ if (port->mode == IPVLAN_MODE_L3S) -+ ipvlan_migrate_l3s_hook(oldnet, newnet); - break; - } - case NETDEV_UNREGISTER: -diff --git a/drivers/net/veth.c b/drivers/net/veth.c -index a71786b3e7ba7..727b9278b9fe5 100644 ---- a/drivers/net/veth.c -+++ b/drivers/net/veth.c -@@ -1716,10 +1716,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, - - nla_peer = data[VETH_INFO_PEER]; - ifmp = nla_data(nla_peer); -- err = rtnl_nla_parse_ifla(peer_tb, -- nla_data(nla_peer) + sizeof(struct ifinfomsg), -- nla_len(nla_peer) - sizeof(struct ifinfomsg), -- NULL); -+ err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack); - if (err < 0) - return err; - -diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index cd3821a6444f0..4e436f2d13aeb 100644 ---- a/drivers/of/dynamic.c -+++ b/drivers/of/dynamic.c -@@ -63,15 +63,14 @@ int of_reconfig_notifier_unregister(struct notifier_block *nb) - } - EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister); - --#ifdef DEBUG --const char *action_names[] = { -+static const char *action_names[] = { -+ [0] = "INVALID", - [OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE", - [OF_RECONFIG_DETACH_NODE] = "DETACH_NODE", - [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY", - [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY", - [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY", - }; --#endif - - int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) - { -@@ -594,21 +593,9 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) - } - - ret = __of_add_property(ce->np, ce->prop); -- if (ret) { -- pr_err("changeset: add_property failed @%pOF/%s\n", -- ce->np, -- ce->prop->name); -- break; -- } - break; - case OF_RECONFIG_REMOVE_PROPERTY: - ret = __of_remove_property(ce->np, ce->prop); -- if (ret) { -- pr_err("changeset: remove_property failed @%pOF/%s\n", -- ce->np, -- ce->prop->name); -- break; -- } - break; - - case OF_RECONFIG_UPDATE_PROPERTY: -@@ -622,20 +609,17 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) - } - - ret = __of_update_property(ce->np, ce->prop, &old_prop); -- if (ret) { -- pr_err("changeset: update_property failed @%pOF/%s\n", -- ce->np, -- ce->prop->name); -- break; -- } - break; - default: - ret = -EINVAL; - } - raw_spin_unlock_irqrestore(&devtree_lock, flags); - -- if (ret) -+ if (ret) { -+ pr_err("changeset: apply failed: %-15s %pOF:%s\n", -+ action_names[ce->action], ce->np, ce->prop->name); - return ret; -+ } - - switch (ce->action) { - case OF_RECONFIG_ATTACH_NODE: -@@ -921,6 +905,9 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, - if (!ce) - return -ENOMEM; - -+ if (WARN_ON(action >= ARRAY_SIZE(action_names))) -+ return -EINVAL; -+ - /* get a reference to the node */ - ce->action = action; - ce->np = of_node_get(np); -diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c -index f26d2ba8a3715..68278340cecfe 100644 ---- a/drivers/of/kexec.c -+++ b/drivers/of/kexec.c -@@ -184,7 +184,8 @@ int __init ima_free_kexec_buffer(void) - if (ret) - return ret; - -- return memblock_phys_free(addr, size); -+ memblock_free_late(addr, size); -+ return 0; - } - #endif - -diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index b89ab5d9fea55..9be6ed47a1ce4 100644 ---- a/drivers/of/unittest.c -+++ b/drivers/of/unittest.c -@@ -657,12 +657,12 @@ static void __init of_unittest_parse_phandle_with_args_map(void) - memset(&args, 0, sizeof(args)); - - EXPECT_BEGIN(KERN_INFO, -- "OF: /testcase-data/phandle-tests/consumer-b: could not find phandle"); -+ "OF: /testcase-data/phandle-tests/consumer-b: could not find phandle 12345678"); - - rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-phandle", - "phandle", 0, &args); - EXPECT_END(KERN_INFO, -- "OF: /testcase-data/phandle-tests/consumer-b: could not find phandle"); -+ "OF: /testcase-data/phandle-tests/consumer-b: could not find phandle 12345678"); - - unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); - -diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c -index 6efa3d8db9a56..ea0195337bab9 100644 ---- a/drivers/pci/hotplug/acpiphp_glue.c -+++ b/drivers/pci/hotplug/acpiphp_glue.c -@@ -504,12 +504,15 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge) - if (pass && dev->subordinate) { - check_hotplug_bridge(slot, dev); - pcibios_resource_survey_bus(dev->subordinate); -- __pci_bus_size_bridges(dev->subordinate, -- &add_list); -+ if (pci_is_root_bus(bus)) -+ __pci_bus_size_bridges(dev->subordinate, &add_list); - } - } - } -- __pci_bus_assign_resources(bus, &add_list, NULL); -+ if (pci_is_root_bus(bus)) -+ __pci_bus_assign_resources(bus, &add_list, NULL); -+ else -+ pci_assign_unassigned_bridge_resources(bus->self); - } - - acpiphp_sanitize_bus(bus); -diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c -index a8df77e80549c..be6838c252f09 100644 ---- a/drivers/pinctrl/pinctrl-amd.c -+++ b/drivers/pinctrl/pinctrl-amd.c -@@ -862,6 +862,33 @@ static const struct pinconf_ops amd_pinconf_ops = { - .pin_config_group_set = amd_pinconf_group_set, - }; - -+static void amd_gpio_irq_init(struct amd_gpio *gpio_dev) -+{ -+ struct pinctrl_desc *desc = gpio_dev->pctrl->desc; -+ unsigned long flags; -+ u32 pin_reg, mask; -+ int i; -+ -+ mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3) | -+ BIT(WAKE_CNTRL_OFF_S4); -+ -+ for (i = 0; i < desc->npins; i++) { -+ int pin = desc->pins[i].number; -+ const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin); -+ -+ if (!pd) -+ continue; -+ -+ raw_spin_lock_irqsave(&gpio_dev->lock, flags); -+ -+ pin_reg = readl(gpio_dev->base + pin * 4); -+ pin_reg &= ~mask; -+ writel(pin_reg, gpio_dev->base + pin * 4); -+ -+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); -+ } -+} -+ - #ifdef CONFIG_PM_SLEEP - static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin) - { -@@ -1099,6 +1126,9 @@ static int amd_gpio_probe(struct platform_device *pdev) - return PTR_ERR(gpio_dev->pctrl); - } - -+ /* Disable and mask interrupts */ -+ amd_gpio_irq_init(gpio_dev); -+ - girq = &gpio_dev->gc.irq; - gpio_irq_chip_set_chip(girq, &amd_gpio_irqchip); - /* This will let us handle the parent IRQ in the driver */ -diff --git a/drivers/pinctrl/renesas/pinctrl-rza2.c b/drivers/pinctrl/renesas/pinctrl-rza2.c -index c0a04f1ee994e..12126e30dc20f 100644 ---- a/drivers/pinctrl/renesas/pinctrl-rza2.c -+++ b/drivers/pinctrl/renesas/pinctrl-rza2.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -46,6 +47,7 @@ struct rza2_pinctrl_priv { - struct pinctrl_dev *pctl; - struct pinctrl_gpio_range gpio_range; - int npins; -+ struct mutex mutex; /* serialize adding groups and functions */ - }; - - #define RZA2_PDR(port) (0x0000 + (port) * 2) /* Direction 16-bit */ -@@ -358,10 +360,14 @@ static int rza2_dt_node_to_map(struct pinctrl_dev *pctldev, - psel_val[i] = MUX_FUNC(value); - } - -+ mutex_lock(&priv->mutex); -+ - /* Register a single pin group listing all the pins we read from DT */ - gsel = pinctrl_generic_add_group(pctldev, np->name, pins, npins, NULL); -- if (gsel < 0) -- return gsel; -+ if (gsel < 0) { -+ ret = gsel; -+ goto unlock; -+ } - - /* - * Register a single group function where the 'data' is an array PSEL -@@ -390,6 +396,8 @@ static int rza2_dt_node_to_map(struct pinctrl_dev *pctldev, - (*map)->data.mux.function = np->name; - *num_maps = 1; - -+ mutex_unlock(&priv->mutex); -+ - return 0; - - remove_function: -@@ -398,6 +406,9 @@ remove_function: - remove_group: - pinctrl_generic_remove_group(pctldev, gsel); - -+unlock: -+ mutex_unlock(&priv->mutex); -+ - dev_err(priv->dev, "Unable to parse DT node %s\n", np->name); - - return ret; -@@ -473,6 +484,8 @@ static int rza2_pinctrl_probe(struct platform_device *pdev) - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - -+ mutex_init(&priv->mutex); -+ - platform_set_drvdata(pdev, priv); - - priv->npins = (int)(uintptr_t)of_device_get_match_data(&pdev->dev) * -diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c -index fd11d28e5a1e4..2a617832a7e60 100644 ---- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c -+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -146,10 +147,11 @@ struct rzg2l_pinctrl { - struct gpio_chip gpio_chip; - struct pinctrl_gpio_range gpio_range; - DECLARE_BITMAP(tint_slot, RZG2L_TINT_MAX_INTERRUPT); -- spinlock_t bitmap_lock; -+ spinlock_t bitmap_lock; /* protect tint_slot bitmap */ - unsigned int hwirq[RZG2L_TINT_MAX_INTERRUPT]; - -- spinlock_t lock; -+ spinlock_t lock; /* lock read/write registers */ -+ struct mutex mutex; /* serialize adding groups and functions */ - }; - - static const unsigned int iolh_groupa_mA[] = { 2, 4, 8, 12 }; -@@ -359,11 +361,13 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, - name = np->name; - } - -+ mutex_lock(&pctrl->mutex); -+ - /* Register a single pin group listing all the pins we read from DT */ - gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pinmux, NULL); - if (gsel < 0) { - ret = gsel; -- goto done; -+ goto unlock; - } - - /* -@@ -377,6 +381,8 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, - goto remove_group; - } - -+ mutex_unlock(&pctrl->mutex); -+ - maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; - maps[idx].data.mux.group = name; - maps[idx].data.mux.function = name; -@@ -388,6 +394,8 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, - - remove_group: - pinctrl_generic_remove_group(pctldev, gsel); -+unlock: -+ mutex_unlock(&pctrl->mutex); - done: - *index = idx; - kfree(configs); -@@ -1501,6 +1509,7 @@ static int rzg2l_pinctrl_probe(struct platform_device *pdev) - - spin_lock_init(&pctrl->lock); - spin_lock_init(&pctrl->bitmap_lock); -+ mutex_init(&pctrl->mutex); - - platform_set_drvdata(pdev, pctrl); - -diff --git a/drivers/pinctrl/renesas/pinctrl-rzv2m.c b/drivers/pinctrl/renesas/pinctrl-rzv2m.c -index 35f382b055e83..2858800288bb7 100644 ---- a/drivers/pinctrl/renesas/pinctrl-rzv2m.c -+++ b/drivers/pinctrl/renesas/pinctrl-rzv2m.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -121,7 +122,8 @@ struct rzv2m_pinctrl { - struct gpio_chip gpio_chip; - struct pinctrl_gpio_range gpio_range; - -- spinlock_t lock; -+ spinlock_t lock; /* lock read/write registers */ -+ struct mutex mutex; /* serialize adding groups and functions */ - }; - - static const unsigned int drv_1_8V_group2_uA[] = { 1800, 3800, 7800, 11000 }; -@@ -320,11 +322,13 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, - name = np->name; - } - -+ mutex_lock(&pctrl->mutex); -+ - /* Register a single pin group listing all the pins we read from DT */ - gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pinmux, NULL); - if (gsel < 0) { - ret = gsel; -- goto done; -+ goto unlock; - } - - /* -@@ -338,6 +342,8 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, - goto remove_group; - } - -+ mutex_unlock(&pctrl->mutex); -+ - maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; - maps[idx].data.mux.group = name; - maps[idx].data.mux.function = name; -@@ -349,6 +355,8 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, - - remove_group: - pinctrl_generic_remove_group(pctldev, gsel); -+unlock: -+ mutex_unlock(&pctrl->mutex); - done: - *index = idx; - kfree(configs); -@@ -1070,6 +1078,7 @@ static int rzv2m_pinctrl_probe(struct platform_device *pdev) - } - - spin_lock_init(&pctrl->lock); -+ mutex_init(&pctrl->mutex); - - platform_set_drvdata(pdev, pctrl); - -diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c -index bd38c7dcae347..de03b8889e9d3 100644 ---- a/drivers/platform/x86/ideapad-laptop.c -+++ b/drivers/platform/x86/ideapad-laptop.c -@@ -1176,6 +1176,11 @@ static const struct key_entry ideapad_keymap[] = { - { KE_IGNORE, 0x03 | IDEAPAD_WMI_KEY }, - /* Customizable Lenovo Hotkey ("star" with 'S' inside) */ - { KE_KEY, 0x01 | IDEAPAD_WMI_KEY, { KEY_FAVORITES } }, -+ { KE_KEY, 0x04 | IDEAPAD_WMI_KEY, { KEY_SELECTIVE_SCREENSHOT } }, -+ /* Lenovo Support */ -+ { KE_KEY, 0x07 | IDEAPAD_WMI_KEY, { KEY_HELP } }, -+ { KE_KEY, 0x0e | IDEAPAD_WMI_KEY, { KEY_PICKUP_PHONE } }, -+ { KE_KEY, 0x0f | IDEAPAD_WMI_KEY, { KEY_HANGUP_PHONE } }, - /* Dark mode toggle */ - { KE_KEY, 0x13 | IDEAPAD_WMI_KEY, { KEY_PROG1 } }, - /* Sound profile switch */ -diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c -index f99a9ef42116f..84e3ad290f6ba 100644 ---- a/drivers/s390/crypto/zcrypt_msgtype6.c -+++ b/drivers/s390/crypto/zcrypt_msgtype6.c -@@ -926,8 +926,7 @@ static void zcrypt_msgtype6_receive(struct ap_queue *aq, - .type = TYPE82_RSP_CODE, - .reply_code = REP82_ERROR_MACHINE_FAILURE, - }; -- struct response_type *resp_type = -- (struct response_type *)msg->private; -+ struct response_type *resp_type = msg->private; - struct type86x_reply *t86r; - int len; - -@@ -982,8 +981,7 @@ static void zcrypt_msgtype6_receive_ep11(struct ap_queue *aq, - .type = TYPE82_RSP_CODE, - .reply_code = REP82_ERROR_MACHINE_FAILURE, - }; -- struct response_type *resp_type = -- (struct response_type *)msg->private; -+ struct response_type *resp_type = msg->private; - struct type86_ep11_reply *t86r; - int len; - -@@ -1156,23 +1154,36 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq, - struct ica_xcRB *xcrb, - struct ap_message *ap_msg) - { -- int rc; -- struct response_type *rtype = (struct response_type *)(ap_msg->private); -+ struct response_type *rtype = ap_msg->private; - struct { - struct type6_hdr hdr; - struct CPRBX cprbx; - /* ... more data blocks ... */ - } __packed * msg = ap_msg->msg; -- -- /* -- * Set the queue's reply buffer length minus 128 byte padding -- * as reply limit for the card firmware. -- */ -- msg->hdr.fromcardlen1 = min_t(unsigned int, msg->hdr.fromcardlen1, -- zq->reply.bufsize - 128); -- if (msg->hdr.fromcardlen2) -- msg->hdr.fromcardlen2 = -- zq->reply.bufsize - msg->hdr.fromcardlen1 - 128; -+ unsigned int max_payload_size; -+ int rc, delta; -+ -+ /* calculate maximum payload for this card and msg type */ -+ max_payload_size = zq->reply.bufsize - sizeof(struct type86_fmt2_msg); -+ -+ /* limit each of the two from fields to the maximum payload size */ -+ msg->hdr.fromcardlen1 = min(msg->hdr.fromcardlen1, max_payload_size); -+ msg->hdr.fromcardlen2 = min(msg->hdr.fromcardlen2, max_payload_size); -+ -+ /* calculate delta if the sum of both exceeds max payload size */ -+ delta = msg->hdr.fromcardlen1 + msg->hdr.fromcardlen2 -+ - max_payload_size; -+ if (delta > 0) { -+ /* -+ * Sum exceeds maximum payload size, prune fromcardlen1 -+ * (always trust fromcardlen2) -+ */ -+ if (delta > msg->hdr.fromcardlen1) { -+ rc = -EINVAL; -+ goto out; -+ } -+ msg->hdr.fromcardlen1 -= delta; -+ } - - init_completion(&rtype->work); - rc = ap_queue_message(zq->queue, ap_msg); -@@ -1243,7 +1254,7 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue * - { - int rc; - unsigned int lfmt; -- struct response_type *rtype = (struct response_type *)(ap_msg->private); -+ struct response_type *rtype = ap_msg->private; - struct { - struct type6_hdr hdr; - struct ep11_cprb cprbx; -@@ -1365,7 +1376,7 @@ static long zcrypt_msgtype6_rng(struct zcrypt_queue *zq, - short int verb_length; - short int key_length; - } __packed * msg = ap_msg->msg; -- struct response_type *rtype = (struct response_type *)(ap_msg->private); -+ struct response_type *rtype = ap_msg->private; - int rc; - - msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid); -diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c -index 711252e52d8e1..95a86e0dfd77a 100644 ---- a/drivers/scsi/raid_class.c -+++ b/drivers/scsi/raid_class.c -@@ -209,54 +209,6 @@ raid_attr_ro_state(level); - raid_attr_ro_fn(resync); - raid_attr_ro_state_fn(state); - --static void raid_component_release(struct device *dev) --{ -- struct raid_component *rc = -- container_of(dev, struct raid_component, dev); -- dev_printk(KERN_ERR, rc->dev.parent, "COMPONENT RELEASE\n"); -- put_device(rc->dev.parent); -- kfree(rc); --} -- --int raid_component_add(struct raid_template *r,struct device *raid_dev, -- struct device *component_dev) --{ -- struct device *cdev = -- attribute_container_find_class_device(&r->raid_attrs.ac, -- raid_dev); -- struct raid_component *rc; -- struct raid_data *rd = dev_get_drvdata(cdev); -- int err; -- -- rc = kzalloc(sizeof(*rc), GFP_KERNEL); -- if (!rc) -- return -ENOMEM; -- -- INIT_LIST_HEAD(&rc->node); -- device_initialize(&rc->dev); -- rc->dev.release = raid_component_release; -- rc->dev.parent = get_device(component_dev); -- rc->num = rd->component_count++; -- -- dev_set_name(&rc->dev, "component-%d", rc->num); -- list_add_tail(&rc->node, &rd->component_list); -- rc->dev.class = &raid_class.class; -- err = device_add(&rc->dev); -- if (err) -- goto err_out; -- -- return 0; -- --err_out: -- put_device(&rc->dev); -- list_del(&rc->node); -- rd->component_count--; -- put_device(component_dev); -- kfree(rc); -- return err; --} --EXPORT_SYMBOL(raid_component_add); -- - struct raid_template * - raid_class_attach(struct raid_function_template *ft) - { -diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c -index cd27562ec922e..6c529b37f3b46 100644 ---- a/drivers/scsi/snic/snic_disc.c -+++ b/drivers/scsi/snic/snic_disc.c -@@ -303,12 +303,11 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid) - "Snic Tgt: device_add, with err = %d\n", - ret); - -- put_device(&tgt->dev); - put_device(&snic->shost->shost_gendev); - spin_lock_irqsave(snic->shost->host_lock, flags); - list_del(&tgt->list); - spin_unlock_irqrestore(snic->shost->host_lock, flags); -- kfree(tgt); -+ put_device(&tgt->dev); - tgt = NULL; - - return tgt; -diff --git a/drivers/thunderbolt/tmu.c b/drivers/thunderbolt/tmu.c -index 626aca3124b1c..d9544600b3867 100644 ---- a/drivers/thunderbolt/tmu.c -+++ b/drivers/thunderbolt/tmu.c -@@ -415,7 +415,8 @@ int tb_switch_tmu_disable(struct tb_switch *sw) - * uni-directional mode and we don't want to change it's TMU - * mode. - */ -- tb_switch_tmu_rate_write(sw, TB_SWITCH_TMU_RATE_OFF); -+ ret = tb_switch_tmu_rate_write(sw, TB_SWITCH_TMU_RATE_OFF); -+ return ret; - - tb_port_tmu_time_sync_disable(up); - ret = tb_port_tmu_time_sync_disable(down); -diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c -index 5c94abdb1ad6d..3e4a1f55f51b3 100644 ---- a/drivers/video/aperture.c -+++ b/drivers/video/aperture.c -@@ -298,14 +298,6 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si - - aperture_detach_devices(base, size); - -- /* -- * If this is the primary adapter, there could be a VGA device -- * that consumes the VGA framebuffer I/O range. Remove this device -- * as well. -- */ -- if (primary) -- aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); -- - return 0; - } - EXPORT_SYMBOL(aperture_remove_conflicting_devices); -@@ -344,13 +336,22 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na - aperture_detach_devices(base, size); - } - -- /* -- * WARNING: Apparently we must kick fbdev drivers before vgacon, -- * otherwise the vga fbdev driver falls over. -- */ -- ret = vga_remove_vgacon(pdev); -- if (ret) -- return ret; -+ if (primary) { -+ /* -+ * If this is the primary adapter, there could be a VGA device -+ * that consumes the VGA framebuffer I/O range. Remove this -+ * device as well. -+ */ -+ aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); -+ -+ /* -+ * WARNING: Apparently we must kick fbdev drivers before vgacon, -+ * otherwise the vga fbdev driver falls over. -+ */ -+ ret = vga_remove_vgacon(pdev); -+ if (ret) -+ return ret; -+ } - - return 0; - -diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c -index 8b28c9bddd974..50c384ce28837 100644 ---- a/drivers/video/fbdev/aty/radeon_base.c -+++ b/drivers/video/fbdev/aty/radeon_base.c -@@ -2238,14 +2238,6 @@ static const struct bin_attribute edid2_attr = { - .read = radeon_show_edid2, - }; - --static int radeon_kick_out_firmware_fb(struct pci_dev *pdev) --{ -- resource_size_t base = pci_resource_start(pdev, 0); -- resource_size_t size = pci_resource_len(pdev, 0); -- -- return aperture_remove_conflicting_devices(base, size, false, KBUILD_MODNAME); --} -- - static int radeonfb_pci_register(struct pci_dev *pdev, - const struct pci_device_id *ent) - { -@@ -2296,7 +2288,7 @@ static int radeonfb_pci_register(struct pci_dev *pdev, - rinfo->fb_base_phys = pci_resource_start (pdev, 0); - rinfo->mmio_base_phys = pci_resource_start (pdev, 2); - -- ret = radeon_kick_out_firmware_fb(pdev); -+ ret = aperture_remove_conflicting_pci_devices(pdev, KBUILD_MODNAME); - if (ret) - goto err_release_fb; - -diff --git a/fs/attr.c b/fs/attr.c -index b45f30e516fad..9b9a70e0cc54f 100644 ---- a/fs/attr.c -+++ b/fs/attr.c -@@ -47,6 +47,7 @@ int setattr_should_drop_sgid(struct user_namespace *mnt_userns, - return ATTR_KILL_SGID; - return 0; - } -+EXPORT_SYMBOL(setattr_should_drop_sgid); - - /** - * setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to -diff --git a/fs/internal.h b/fs/internal.h -index 46caa33373a48..42df013f7fe76 100644 ---- a/fs/internal.h -+++ b/fs/internal.h -@@ -242,5 +242,3 @@ ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *po - /* - * fs/attr.c - */ --int setattr_should_drop_sgid(struct user_namespace *mnt_userns, -- const struct inode *inode); -diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c -index c4e0da6db7195..9ec91017a7f3c 100644 ---- a/fs/jbd2/checkpoint.c -+++ b/fs/jbd2/checkpoint.c -@@ -27,7 +27,7 @@ - * - * Called with j_list_lock held. - */ --static inline void __buffer_unlink_first(struct journal_head *jh) -+static inline void __buffer_unlink(struct journal_head *jh) - { - transaction_t *transaction = jh->b_cp_transaction; - -@@ -40,23 +40,6 @@ static inline void __buffer_unlink_first(struct journal_head *jh) - } - } - --/* -- * Unlink a buffer from a transaction checkpoint(io) list. -- * -- * Called with j_list_lock held. -- */ --static inline void __buffer_unlink(struct journal_head *jh) --{ -- transaction_t *transaction = jh->b_cp_transaction; -- -- __buffer_unlink_first(jh); -- if (transaction->t_checkpoint_io_list == jh) { -- transaction->t_checkpoint_io_list = jh->b_cpnext; -- if (transaction->t_checkpoint_io_list == jh) -- transaction->t_checkpoint_io_list = NULL; -- } --} -- - /* - * Check a checkpoint buffer could be release or not. - * -@@ -366,50 +349,10 @@ int jbd2_cleanup_journal_tail(journal_t *journal) - - /* Checkpoint list management */ - --/* -- * journal_clean_one_cp_list -- * -- * Find all the written-back checkpoint buffers in the given list and -- * release them. If 'destroy' is set, clean all buffers unconditionally. -- * -- * Called with j_list_lock held. -- * Returns 1 if we freed the transaction, 0 otherwise. -- */ --static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy) --{ -- struct journal_head *last_jh; -- struct journal_head *next_jh = jh; -- -- if (!jh) -- return 0; -- -- last_jh = jh->b_cpprev; -- do { -- jh = next_jh; -- next_jh = jh->b_cpnext; -- -- if (!destroy && __cp_buffer_busy(jh)) -- return 0; -- -- if (__jbd2_journal_remove_checkpoint(jh)) -- return 1; -- /* -- * This function only frees up some memory -- * if possible so we dont have an obligation -- * to finish processing. Bail out if preemption -- * requested: -- */ -- if (need_resched()) -- return 0; -- } while (jh != last_jh); -- -- return 0; --} -- - /* - * journal_shrink_one_cp_list - * -- * Find 'nr_to_scan' written-back checkpoint buffers in the given list -+ * Find all the written-back checkpoint buffers in the given list - * and try to release them. If the whole transaction is released, set - * the 'released' parameter. Return the number of released checkpointed - * buffers. -@@ -417,15 +360,15 @@ static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy) - * Called with j_list_lock held. - */ - static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, -- unsigned long *nr_to_scan, -- bool *released) -+ bool destroy, bool *released) - { - struct journal_head *last_jh; - struct journal_head *next_jh = jh; - unsigned long nr_freed = 0; - int ret; - -- if (!jh || *nr_to_scan == 0) -+ *released = false; -+ if (!jh) - return 0; - - last_jh = jh->b_cpprev; -@@ -433,12 +376,15 @@ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, - jh = next_jh; - next_jh = jh->b_cpnext; - -- (*nr_to_scan)--; -- if (__cp_buffer_busy(jh)) -- continue; -+ if (destroy) { -+ ret = __jbd2_journal_remove_checkpoint(jh); -+ } else { -+ ret = jbd2_journal_try_remove_checkpoint(jh); -+ if (ret < 0) -+ continue; -+ } - - nr_freed++; -- ret = __jbd2_journal_remove_checkpoint(jh); - if (ret) { - *released = true; - break; -@@ -446,7 +392,7 @@ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, - - if (need_resched()) - break; -- } while (jh != last_jh && *nr_to_scan); -+ } while (jh != last_jh); - - return nr_freed; - } -@@ -464,11 +410,11 @@ unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal, - unsigned long *nr_to_scan) - { - transaction_t *transaction, *last_transaction, *next_transaction; -- bool released; -+ bool __maybe_unused released; - tid_t first_tid = 0, last_tid = 0, next_tid = 0; - tid_t tid = 0; - unsigned long nr_freed = 0; -- unsigned long nr_scanned = *nr_to_scan; -+ unsigned long freed; - - again: - spin_lock(&journal->j_list_lock); -@@ -497,19 +443,11 @@ again: - transaction = next_transaction; - next_transaction = transaction->t_cpnext; - tid = transaction->t_tid; -- released = false; - -- nr_freed += journal_shrink_one_cp_list(transaction->t_checkpoint_list, -- nr_to_scan, &released); -- if (*nr_to_scan == 0) -- break; -- if (need_resched() || spin_needbreak(&journal->j_list_lock)) -- break; -- if (released) -- continue; -- -- nr_freed += journal_shrink_one_cp_list(transaction->t_checkpoint_io_list, -- nr_to_scan, &released); -+ freed = journal_shrink_one_cp_list(transaction->t_checkpoint_list, -+ false, &released); -+ nr_freed += freed; -+ (*nr_to_scan) -= min(*nr_to_scan, freed); - if (*nr_to_scan == 0) - break; - if (need_resched() || spin_needbreak(&journal->j_list_lock)) -@@ -530,9 +468,8 @@ again: - if (*nr_to_scan && next_tid) - goto again; - out: -- nr_scanned -= *nr_to_scan; - trace_jbd2_shrink_checkpoint_list(journal, first_tid, tid, last_tid, -- nr_freed, nr_scanned, next_tid); -+ nr_freed, next_tid); - - return nr_freed; - } -@@ -548,7 +485,7 @@ out: - void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) - { - transaction_t *transaction, *last_transaction, *next_transaction; -- int ret; -+ bool released; - - transaction = journal->j_checkpoint_transactions; - if (!transaction) -@@ -559,8 +496,8 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) - do { - transaction = next_transaction; - next_transaction = transaction->t_cpnext; -- ret = journal_clean_one_cp_list(transaction->t_checkpoint_list, -- destroy); -+ journal_shrink_one_cp_list(transaction->t_checkpoint_list, -+ destroy, &released); - /* - * This function only frees up some memory if possible so we - * dont have an obligation to finish processing. Bail out if -@@ -568,23 +505,12 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) - */ - if (need_resched()) - return; -- if (ret) -- continue; -- /* -- * It is essential that we are as careful as in the case of -- * t_checkpoint_list with removing the buffer from the list as -- * we can possibly see not yet submitted buffers on io_list -- */ -- ret = journal_clean_one_cp_list(transaction-> -- t_checkpoint_io_list, destroy); -- if (need_resched()) -- return; - /* - * Stop scanning if we couldn't free the transaction. This - * avoids pointless scanning of transactions which still - * weren't checkpointed. - */ -- if (!ret) -+ if (!released) - return; - } while (transaction != last_transaction); - } -@@ -663,7 +589,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) - jbd2_journal_put_journal_head(jh); - - /* Is this transaction empty? */ -- if (transaction->t_checkpoint_list || transaction->t_checkpoint_io_list) -+ if (transaction->t_checkpoint_list) - return 0; - - /* -@@ -694,6 +620,34 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) - return 1; - } - -+/* -+ * Check the checkpoint buffer and try to remove it from the checkpoint -+ * list if it's clean. Returns -EBUSY if it is not clean, returns 1 if -+ * it frees the transaction, 0 otherwise. -+ * -+ * This function is called with j_list_lock held. -+ */ -+int jbd2_journal_try_remove_checkpoint(struct journal_head *jh) -+{ -+ struct buffer_head *bh = jh2bh(jh); -+ -+ if (!trylock_buffer(bh)) -+ return -EBUSY; -+ if (buffer_dirty(bh)) { -+ unlock_buffer(bh); -+ return -EBUSY; -+ } -+ unlock_buffer(bh); -+ -+ /* -+ * Buffer is clean and the IO has finished (we held the buffer -+ * lock) so the checkpoint is done. We can safely remove the -+ * buffer from this transaction. -+ */ -+ JBUFFER_TRACE(jh, "remove from checkpoint list"); -+ return __jbd2_journal_remove_checkpoint(jh); -+} -+ - /* - * journal_insert_checkpoint: put a committed buffer onto a checkpoint - * list so that we know when it is safe to clean the transaction out of -@@ -755,7 +709,6 @@ void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transact - J_ASSERT(transaction->t_forget == NULL); - J_ASSERT(transaction->t_shadow_list == NULL); - J_ASSERT(transaction->t_checkpoint_list == NULL); -- J_ASSERT(transaction->t_checkpoint_io_list == NULL); - J_ASSERT(atomic_read(&transaction->t_updates) == 0); - J_ASSERT(journal->j_committing_transaction != transaction); - J_ASSERT(journal->j_running_transaction != transaction); -diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c -index 885a7a6cc53e6..f1d9db6686e31 100644 ---- a/fs/jbd2/commit.c -+++ b/fs/jbd2/commit.c -@@ -1171,8 +1171,7 @@ restart_loop: - spin_lock(&journal->j_list_lock); - commit_transaction->t_state = T_FINISHED; - /* Check if the transaction can be dropped now that we are finished */ -- if (commit_transaction->t_checkpoint_list == NULL && -- commit_transaction->t_checkpoint_io_list == NULL) { -+ if (commit_transaction->t_checkpoint_list == NULL) { - __jbd2_journal_drop_transaction(journal, commit_transaction); - jbd2_journal_free_transaction(commit_transaction); - } -diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c -index 18611241f4513..6ef5022949c46 100644 ---- a/fs/jbd2/transaction.c -+++ b/fs/jbd2/transaction.c -@@ -1784,8 +1784,7 @@ int jbd2_journal_forget(handle_t *handle, struct buffer_head *bh) - * Otherwise, if the buffer has been written to disk, - * it is safe to remove the checkpoint and drop it. - */ -- if (!buffer_dirty(bh)) { -- __jbd2_journal_remove_checkpoint(jh); -+ if (jbd2_journal_try_remove_checkpoint(jh) >= 0) { - spin_unlock(&journal->j_list_lock); - goto drop; - } -@@ -2112,20 +2111,14 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) - - jh = bh2jh(bh); - -- if (buffer_locked(bh) || buffer_dirty(bh)) -- goto out; -- - if (jh->b_next_transaction != NULL || jh->b_transaction != NULL) -- goto out; -+ return; - - spin_lock(&journal->j_list_lock); -- if (jh->b_cp_transaction != NULL) { -- /* written-back checkpointed metadata buffer */ -- JBUFFER_TRACE(jh, "remove from checkpoint list"); -- __jbd2_journal_remove_checkpoint(jh); -- } -+ /* Remove written-back checkpointed metadata buffer */ -+ if (jh->b_cp_transaction != NULL) -+ jbd2_journal_try_remove_checkpoint(jh); - spin_unlock(&journal->j_list_lock); --out: - return; - } - -diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c -index 1707f46b1335c..cf34d0c309459 100644 ---- a/fs/nfs/direct.c -+++ b/fs/nfs/direct.c -@@ -474,20 +474,26 @@ out: - return result; - } - --static void --nfs_direct_join_group(struct list_head *list, struct inode *inode) -+static void nfs_direct_join_group(struct list_head *list, struct inode *inode) - { -- struct nfs_page *req, *next; -+ struct nfs_page *req, *subreq; - - list_for_each_entry(req, list, wb_list) { -- if (req->wb_head != req || req->wb_this_page == req) -+ if (req->wb_head != req) - continue; -- for (next = req->wb_this_page; -- next != req->wb_head; -- next = next->wb_this_page) { -- nfs_list_remove_request(next); -- nfs_release_request(next); -- } -+ subreq = req->wb_this_page; -+ if (subreq == req) -+ continue; -+ do { -+ /* -+ * Remove subrequests from this list before freeing -+ * them in the call to nfs_join_page_group(). -+ */ -+ if (!list_empty(&subreq->wb_list)) { -+ nfs_list_remove_request(subreq); -+ nfs_release_request(subreq); -+ } -+ } while ((subreq = subreq->wb_this_page) != req); - nfs_join_page_group(req, inode); - } - } -diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c -index 6b2cfa59a1a2b..e0c1fb98f907a 100644 ---- a/fs/nfs/inode.c -+++ b/fs/nfs/inode.c -@@ -717,9 +717,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, - if ((attr->ia_valid & ATTR_KILL_SUID) != 0 && - inode->i_mode & S_ISUID) - inode->i_mode &= ~S_ISUID; -- if ((attr->ia_valid & ATTR_KILL_SGID) != 0 && -- (inode->i_mode & (S_ISGID | S_IXGRP)) == -- (S_ISGID | S_IXGRP)) -+ if (setattr_should_drop_sgid(&init_user_ns, inode)) - inode->i_mode &= ~S_ISGID; - if ((attr->ia_valid & ATTR_MODE) != 0) { - int mode = attr->ia_mode & S_IALLUGO; -diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c -index ecb428512fe1a..7c33bba179d2f 100644 ---- a/fs/nfs/nfs42proc.c -+++ b/fs/nfs/nfs42proc.c -@@ -1359,7 +1359,6 @@ ssize_t nfs42_proc_getxattr(struct inode *inode, const char *name, - for (i = 0; i < np; i++) { - pages[i] = alloc_page(GFP_KERNEL); - if (!pages[i]) { -- np = i + 1; - err = -ENOMEM; - goto out; - } -@@ -1383,8 +1382,8 @@ ssize_t nfs42_proc_getxattr(struct inode *inode, const char *name, - } while (exception.retry); - - out: -- while (--np >= 0) -- __free_page(pages[np]); -+ while (--i >= 0) -+ __free_page(pages[i]); - kfree(pages); - - return err; -diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index 177cb7b089b9a..1044305e77996 100644 ---- a/fs/nfs/nfs4proc.c -+++ b/fs/nfs/nfs4proc.c -@@ -5995,9 +5995,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, - out_ok: - ret = res.acl_len; - out_free: -- for (i = 0; i < npages; i++) -- if (pages[i]) -- __free_page(pages[i]); -+ while (--i >= 0) -+ __free_page(pages[i]); - if (res.acl_scratch) - __free_page(res.acl_scratch); - kfree(pages); -@@ -7171,8 +7170,15 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata) - } else if (!nfs4_update_lock_stateid(lsp, &data->res.stateid)) - goto out_restart; - break; -- case -NFS4ERR_BAD_STATEID: - case -NFS4ERR_OLD_STATEID: -+ if (data->arg.new_lock_owner != 0 && -+ nfs4_refresh_open_old_stateid(&data->arg.open_stateid, -+ lsp->ls_state)) -+ goto out_restart; -+ if (nfs4_refresh_lock_old_stateid(&data->arg.lock_stateid, lsp)) -+ goto out_restart; -+ fallthrough; -+ case -NFS4ERR_BAD_STATEID: - case -NFS4ERR_STALE_STATEID: - case -NFS4ERR_EXPIRED: - if (data->arg.new_lock_owner != 0) { -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index c5dc0cd6f7031..96714e105d7bf 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -1368,9 +1368,9 @@ static void revoke_delegation(struct nfs4_delegation *dp) - WARN_ON(!list_empty(&dp->dl_recall_lru)); - - if (clp->cl_minorversion) { -+ spin_lock(&clp->cl_lock); - dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID; - refcount_inc(&dp->dl_stid.sc_count); -- spin_lock(&clp->cl_lock); - list_add(&dp->dl_recall_lru, &clp->cl_revoked); - spin_unlock(&clp->cl_lock); - } -diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c -index 155b34c4683c2..4c11046800ab4 100644 ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -321,7 +321,9 @@ nfsd_sanitize_attrs(struct inode *inode, struct iattr *iap) - iap->ia_mode &= ~S_ISGID; - } else { - /* set ATTR_KILL_* bits and let VFS handle it */ -- iap->ia_valid |= (ATTR_KILL_SUID | ATTR_KILL_SGID); -+ iap->ia_valid |= ATTR_KILL_SUID; -+ iap->ia_valid |= -+ setattr_should_drop_sgid(&init_user_ns, inode); - } - } - } -diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h -index 05f2cc03d03d9..b235d6833e27d 100644 ---- a/include/drm/display/drm_dp.h -+++ b/include/drm/display/drm_dp.h -@@ -1525,7 +1525,7 @@ enum drm_dp_phy { - - #define DP_BRANCH_OUI_HEADER_SIZE 0xc - #define DP_RECEIVER_CAP_SIZE 0xf --#define DP_DSC_RECEIVER_CAP_SIZE 0xf -+#define DP_DSC_RECEIVER_CAP_SIZE 0x10 /* DSC Capabilities 0x60 through 0x6F */ - #define EDP_PSR_RECEIVER_CAP_SIZE 2 - #define EDP_DISPLAY_CTL_CAP_SIZE 3 - #define DP_LTTPR_COMMON_CAP_SIZE 8 -diff --git a/include/drm/drm_aperture.h b/include/drm/drm_aperture.h -index 7096703c39493..cbe33b49fd5dc 100644 ---- a/include/drm/drm_aperture.h -+++ b/include/drm/drm_aperture.h -@@ -13,14 +13,13 @@ int devm_aperture_acquire_from_firmware(struct drm_device *dev, resource_size_t - resource_size_t size); - - int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, -- bool primary, const struct drm_driver *req_driver); -+ const struct drm_driver *req_driver); - - int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, - const struct drm_driver *req_driver); - - /** - * drm_aperture_remove_framebuffers - remove all existing framebuffers -- * @primary: also kick vga16fb if present - * @req_driver: requesting DRM driver - * - * This function removes all graphics device drivers. Use this function on systems -@@ -30,9 +29,9 @@ int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, - * 0 on success, or a negative errno code otherwise - */ - static inline int --drm_aperture_remove_framebuffers(bool primary, const struct drm_driver *req_driver) -+drm_aperture_remove_framebuffers(const struct drm_driver *req_driver) - { -- return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, primary, -+ return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, - req_driver); - } - -diff --git a/include/linux/clk.h b/include/linux/clk.h -index 1ef0133242374..06f1b292f8a00 100644 ---- a/include/linux/clk.h -+++ b/include/linux/clk.h -@@ -183,6 +183,39 @@ int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale); - */ - bool clk_is_match(const struct clk *p, const struct clk *q); - -+/** -+ * clk_rate_exclusive_get - get exclusivity over the rate control of a -+ * producer -+ * @clk: clock source -+ * -+ * This function allows drivers to get exclusive control over the rate of a -+ * provider. It prevents any other consumer to execute, even indirectly, -+ * opereation which could alter the rate of the provider or cause glitches -+ * -+ * If exlusivity is claimed more than once on clock, even by the same driver, -+ * the rate effectively gets locked as exclusivity can't be preempted. -+ * -+ * Must not be called from within atomic context. -+ * -+ * Returns success (0) or negative errno. -+ */ -+int clk_rate_exclusive_get(struct clk *clk); -+ -+/** -+ * clk_rate_exclusive_put - release exclusivity over the rate control of a -+ * producer -+ * @clk: clock source -+ * -+ * This function allows drivers to release the exclusivity it previously got -+ * from clk_rate_exclusive_get() -+ * -+ * The caller must balance the number of clk_rate_exclusive_get() and -+ * clk_rate_exclusive_put() calls. -+ * -+ * Must not be called from within atomic context. -+ */ -+void clk_rate_exclusive_put(struct clk *clk); -+ - #else - - static inline int clk_notifier_register(struct clk *clk, -@@ -236,6 +269,13 @@ static inline bool clk_is_match(const struct clk *p, const struct clk *q) - return p == q; - } - -+static inline int clk_rate_exclusive_get(struct clk *clk) -+{ -+ return 0; -+} -+ -+static inline void clk_rate_exclusive_put(struct clk *clk) {} -+ - #endif - - #ifdef CONFIG_HAVE_CLK_PREPARE -@@ -583,38 +623,6 @@ struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id); - */ - struct clk *devm_get_clk_from_child(struct device *dev, - struct device_node *np, const char *con_id); --/** -- * clk_rate_exclusive_get - get exclusivity over the rate control of a -- * producer -- * @clk: clock source -- * -- * This function allows drivers to get exclusive control over the rate of a -- * provider. It prevents any other consumer to execute, even indirectly, -- * opereation which could alter the rate of the provider or cause glitches -- * -- * If exlusivity is claimed more than once on clock, even by the same driver, -- * the rate effectively gets locked as exclusivity can't be preempted. -- * -- * Must not be called from within atomic context. -- * -- * Returns success (0) or negative errno. -- */ --int clk_rate_exclusive_get(struct clk *clk); -- --/** -- * clk_rate_exclusive_put - release exclusivity over the rate control of a -- * producer -- * @clk: clock source -- * -- * This function allows drivers to release the exclusivity it previously got -- * from clk_rate_exclusive_get() -- * -- * The caller must balance the number of clk_rate_exclusive_get() and -- * clk_rate_exclusive_put() calls. -- * -- * Must not be called from within atomic context. -- */ --void clk_rate_exclusive_put(struct clk *clk); - - /** - * clk_enable - inform the system when the clock source should be running. -@@ -974,14 +982,6 @@ static inline void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks) {} - - static inline void devm_clk_put(struct device *dev, struct clk *clk) {} - -- --static inline int clk_rate_exclusive_get(struct clk *clk) --{ -- return 0; --} -- --static inline void clk_rate_exclusive_put(struct clk *clk) {} -- - static inline int clk_enable(struct clk *clk) - { - return 0; -diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h -index d58e0476ee8e3..0348dba5680ef 100644 ---- a/include/linux/cpuset.h -+++ b/include/linux/cpuset.h -@@ -71,8 +71,10 @@ extern void cpuset_init_smp(void); - extern void cpuset_force_rebuild(void); - extern void cpuset_update_active_cpus(void); - extern void cpuset_wait_for_hotplug(void); --extern void cpuset_read_lock(void); --extern void cpuset_read_unlock(void); -+extern void inc_dl_tasks_cs(struct task_struct *task); -+extern void dec_dl_tasks_cs(struct task_struct *task); -+extern void cpuset_lock(void); -+extern void cpuset_unlock(void); - extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); - extern bool cpuset_cpus_allowed_fallback(struct task_struct *p); - extern nodemask_t cpuset_mems_allowed(struct task_struct *p); -@@ -196,8 +198,10 @@ static inline void cpuset_update_active_cpus(void) - - static inline void cpuset_wait_for_hotplug(void) { } - --static inline void cpuset_read_lock(void) { } --static inline void cpuset_read_unlock(void) { } -+static inline void inc_dl_tasks_cs(struct task_struct *task) { } -+static inline void dec_dl_tasks_cs(struct task_struct *task) { } -+static inline void cpuset_lock(void) { } -+static inline void cpuset_unlock(void) { } - - static inline void cpuset_cpus_allowed(struct task_struct *p, - struct cpumask *mask) -diff --git a/include/linux/fs.h b/include/linux/fs.h -index a2b5592c68284..26ea1a0a59a10 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -3120,6 +3120,8 @@ extern struct inode *new_inode(struct super_block *sb); - extern void free_inode_nonrcu(struct inode *inode); - extern int setattr_should_drop_suidgid(struct user_namespace *, struct inode *); - extern int file_remove_privs(struct file *); -+int setattr_should_drop_sgid(struct user_namespace *mnt_userns, -+ const struct inode *inode); - - /* - * This must be used for allocating filesystems specific inodes to set -diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h -index 0b7242370b567..ebb1608d9dcd2 100644 ---- a/include/linux/jbd2.h -+++ b/include/linux/jbd2.h -@@ -622,12 +622,6 @@ struct transaction_s - */ - struct journal_head *t_checkpoint_list; - -- /* -- * Doubly-linked circular list of all buffers submitted for IO while -- * checkpointing. [j_list_lock] -- */ -- struct journal_head *t_checkpoint_io_list; -- - /* - * Doubly-linked circular list of metadata buffers being - * shadowed by log IO. The IO buffers on the iobuf list and -@@ -1441,6 +1435,7 @@ extern void jbd2_journal_commit_transaction(journal_t *); - void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy); - unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal, unsigned long *nr_to_scan); - int __jbd2_journal_remove_checkpoint(struct journal_head *); -+int jbd2_journal_try_remove_checkpoint(struct journal_head *jh); - void jbd2_journal_destroy_checkpoint(journal_t *journal); - void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *); - -diff --git a/include/linux/mm.h b/include/linux/mm.h -index b8ed44f401b58..104ec00823da8 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1727,6 +1727,25 @@ static inline size_t folio_size(struct folio *folio) - return PAGE_SIZE << folio_order(folio); - } - -+/** -+ * folio_estimated_sharers - Estimate the number of sharers of a folio. -+ * @folio: The folio. -+ * -+ * folio_estimated_sharers() aims to serve as a function to efficiently -+ * estimate the number of processes sharing a folio. This is done by -+ * looking at the precise mapcount of the first subpage in the folio, and -+ * assuming the other subpages are the same. This may not be true for large -+ * folios. If you want exact mapcounts for exact calculations, look at -+ * page_mapcount() or folio_total_mapcount(). -+ * -+ * Return: The estimated number of processes sharing a folio. -+ */ -+static inline int folio_estimated_sharers(struct folio *folio) -+{ -+ return page_mapcount(folio_page(folio, 0)); -+} -+ -+ - #ifndef HAVE_ARCH_MAKE_PAGE_ACCESSIBLE - static inline int arch_make_page_accessible(struct page *page) - { -@@ -3091,6 +3110,16 @@ static inline bool gup_must_unshare(unsigned int flags, struct page *page) - if (IS_ENABLED(CONFIG_HAVE_FAST_GUP)) - smp_rmb(); - -+ /* -+ * During GUP-fast we might not get called on the head page for a -+ * hugetlb page that is mapped using cont-PTE, because GUP-fast does -+ * not work with the abstracted hugetlb PTEs that always point at the -+ * head page. For hugetlb, PageAnonExclusive only applies on the head -+ * page (as it cannot be partially COW-shared), so lookup the head page. -+ */ -+ if (unlikely(!PageHead(page) && PageHuge(page))) -+ page = compound_head(page); -+ - /* - * Note that PageKsm() pages cannot be exclusive, and consequently, - * cannot get pinned. -diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h -index 5cdfcb873a8f0..772d45b2a60a0 100644 ---- a/include/linux/raid_class.h -+++ b/include/linux/raid_class.h -@@ -77,7 +77,3 @@ DEFINE_RAID_ATTRIBUTE(enum raid_state, state) - - struct raid_template *raid_class_attach(struct raid_function_template *); - void raid_class_release(struct raid_template *); -- --int __must_check raid_component_add(struct raid_template *, struct device *, -- struct device *); -- -diff --git a/include/linux/sched.h b/include/linux/sched.h -index ffb6eb55cd135..0cac69902ec58 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -1846,7 +1846,9 @@ current_restore_flags(unsigned long orig_flags, unsigned long flags) - } - - extern int cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial); --extern int task_can_attach(struct task_struct *p, const struct cpumask *cs_effective_cpus); -+extern int task_can_attach(struct task_struct *p); -+extern int dl_bw_alloc(int cpu, u64 dl_bw); -+extern void dl_bw_free(int cpu, u64 dl_bw); - #ifdef CONFIG_SMP - extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask); - extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask); -diff --git a/include/net/bonding.h b/include/net/bonding.h -index 17329a19f0c64..9a3ac960dfe15 100644 ---- a/include/net/bonding.h -+++ b/include/net/bonding.h -@@ -727,23 +727,14 @@ static inline struct slave *bond_slave_has_mac(struct bonding *bond, - } - - /* Caller must hold rcu_read_lock() for read */ --static inline bool bond_slave_has_mac_rx(struct bonding *bond, const u8 *mac) -+static inline bool bond_slave_has_mac_rcu(struct bonding *bond, const u8 *mac) - { - struct list_head *iter; - struct slave *tmp; -- struct netdev_hw_addr *ha; - - bond_for_each_slave_rcu(bond, tmp, iter) - if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr)) - return true; -- -- if (netdev_uc_empty(bond->dev)) -- return false; -- -- netdev_for_each_uc_addr(ha, bond->dev) -- if (ether_addr_equal_64bits(mac, ha->addr)) -- return true; -- - return false; - } - -diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h -index c8ef3b881f03d..c2432c2addc82 100644 ---- a/include/net/inet_sock.h -+++ b/include/net/inet_sock.h -@@ -222,8 +222,8 @@ struct inet_sock { - __s16 uc_ttl; - __u16 cmsg_flags; - struct ip_options_rcu __rcu *inet_opt; -+ atomic_t inet_id; - __be16 inet_sport; -- __u16 inet_id; - - __u8 tos; - __u8 min_ttl; -diff --git a/include/net/ip.h b/include/net/ip.h -index 530e7257e4389..1872f570abeda 100644 ---- a/include/net/ip.h -+++ b/include/net/ip.h -@@ -532,8 +532,19 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb, - * generator as much as we can. - */ - if (sk && inet_sk(sk)->inet_daddr) { -- iph->id = htons(inet_sk(sk)->inet_id); -- inet_sk(sk)->inet_id += segs; -+ int val; -+ -+ /* avoid atomic operations for TCP, -+ * as we hold socket lock at this point. -+ */ -+ if (sk_is_tcp(sk)) { -+ sock_owned_by_me(sk); -+ val = atomic_read(&inet_sk(sk)->inet_id); -+ atomic_set(&inet_sk(sk)->inet_id, val + segs); -+ } else { -+ val = atomic_add_return(segs, &inet_sk(sk)->inet_id); -+ } -+ iph->id = htons(val); - return; - } - if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) { -diff --git a/include/net/mac80211.h b/include/net/mac80211.h -index 72b739dc6d530..8a338c33118f9 100644 ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -6444,6 +6444,7 @@ void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap, - * marks frames marked in the bitmap as having been filtered. Afterwards, it - * checks if any frames in the window starting from @ssn can now be released - * (in case they were only waiting for frames that were filtered.) -+ * (Only work correctly if @max_rx_aggregation_subframes <= 64 frames) - */ - void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid, - u16 ssn, u64 filtered, -diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h -index bf8bb33578250..9f881b74f32ed 100644 ---- a/include/net/rtnetlink.h -+++ b/include/net/rtnetlink.h -@@ -189,8 +189,8 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname, - int rtnl_delete_link(struct net_device *dev); - int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm); - --int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len, -- struct netlink_ext_ack *exterr); -+int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer, -+ struct netlink_ext_ack *exterr); - struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid); - - #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind) -diff --git a/include/net/sock.h b/include/net/sock.h -index 699408944952c..d1f936ed97556 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -1320,6 +1320,7 @@ struct proto { - /* - * Pressure flag: try to collapse. - * Technical note: it is used by multiple contexts non atomically. -+ * Make sure to use READ_ONCE()/WRITE_ONCE() for all reads/writes. - * All the __sk_mem_schedule() is of this nature: accounting - * is strict, actions are advisory and have some latency. - */ -@@ -1448,7 +1449,7 @@ static inline bool sk_has_memory_pressure(const struct sock *sk) - static inline bool sk_under_global_memory_pressure(const struct sock *sk) - { - return sk->sk_prot->memory_pressure && -- !!*sk->sk_prot->memory_pressure; -+ !!READ_ONCE(*sk->sk_prot->memory_pressure); - } - - static inline bool sk_under_memory_pressure(const struct sock *sk) -@@ -1460,7 +1461,7 @@ static inline bool sk_under_memory_pressure(const struct sock *sk) - mem_cgroup_under_socket_pressure(sk->sk_memcg)) - return true; - -- return !!*sk->sk_prot->memory_pressure; -+ return !!READ_ONCE(*sk->sk_prot->memory_pressure); - } - - static inline long -@@ -1537,7 +1538,7 @@ proto_memory_pressure(struct proto *prot) - { - if (!prot->memory_pressure) - return false; -- return !!*prot->memory_pressure; -+ return !!READ_ONCE(*prot->memory_pressure); - } - - -diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h -index 8f5ee380d3093..5646ae15a957a 100644 ---- a/include/trace/events/jbd2.h -+++ b/include/trace/events/jbd2.h -@@ -462,11 +462,9 @@ TRACE_EVENT(jbd2_shrink_scan_exit, - TRACE_EVENT(jbd2_shrink_checkpoint_list, - - TP_PROTO(journal_t *journal, tid_t first_tid, tid_t tid, tid_t last_tid, -- unsigned long nr_freed, unsigned long nr_scanned, -- tid_t next_tid), -+ unsigned long nr_freed, tid_t next_tid), - -- TP_ARGS(journal, first_tid, tid, last_tid, nr_freed, -- nr_scanned, next_tid), -+ TP_ARGS(journal, first_tid, tid, last_tid, nr_freed, next_tid), - - TP_STRUCT__entry( - __field(dev_t, dev) -@@ -474,7 +472,6 @@ TRACE_EVENT(jbd2_shrink_checkpoint_list, - __field(tid_t, tid) - __field(tid_t, last_tid) - __field(unsigned long, nr_freed) -- __field(unsigned long, nr_scanned) - __field(tid_t, next_tid) - ), - -@@ -484,15 +481,14 @@ TRACE_EVENT(jbd2_shrink_checkpoint_list, - __entry->tid = tid; - __entry->last_tid = last_tid; - __entry->nr_freed = nr_freed; -- __entry->nr_scanned = nr_scanned; - __entry->next_tid = next_tid; - ), - - TP_printk("dev %d,%d shrink transaction %u-%u(%u) freed %lu " -- "scanned %lu next transaction %u", -+ "next transaction %u", - MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->first_tid, __entry->tid, __entry->last_tid, -- __entry->nr_freed, __entry->nr_scanned, __entry->next_tid) -+ __entry->nr_freed, __entry->next_tid) - ); - - #endif /* _TRACE_JBD2_H */ -diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c -index 3526389ac2180..cd922d2bef5f5 100644 ---- a/io_uring/msg_ring.c -+++ b/io_uring/msg_ring.c -@@ -15,6 +15,7 @@ - - struct io_msg { - struct file *file; -+ struct file *src_file; - u64 user_data; - u32 len; - u32 cmd; -@@ -23,33 +24,12 @@ struct io_msg { - u32 flags; - }; - --static int io_msg_ring_data(struct io_kiocb *req) -+static void io_double_unlock_ctx(struct io_ring_ctx *octx) - { -- struct io_ring_ctx *target_ctx = req->file->private_data; -- struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); -- -- if (msg->src_fd || msg->dst_fd || msg->flags) -- return -EINVAL; -- if (target_ctx->flags & IORING_SETUP_R_DISABLED) -- return -EBADFD; -- -- if (io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0, true)) -- return 0; -- -- return -EOVERFLOW; --} -- --static void io_double_unlock_ctx(struct io_ring_ctx *ctx, -- struct io_ring_ctx *octx, -- unsigned int issue_flags) --{ -- if (issue_flags & IO_URING_F_UNLOCKED) -- mutex_unlock(&ctx->uring_lock); - mutex_unlock(&octx->uring_lock); - } - --static int io_double_lock_ctx(struct io_ring_ctx *ctx, -- struct io_ring_ctx *octx, -+static int io_double_lock_ctx(struct io_ring_ctx *octx, - unsigned int issue_flags) - { - /* -@@ -62,60 +42,86 @@ static int io_double_lock_ctx(struct io_ring_ctx *ctx, - return -EAGAIN; - return 0; - } -+ mutex_lock(&octx->uring_lock); -+ return 0; -+} - -- /* Always grab smallest value ctx first. We know ctx != octx. */ -- if (ctx < octx) { -- mutex_lock(&ctx->uring_lock); -- mutex_lock(&octx->uring_lock); -- } else { -- mutex_lock(&octx->uring_lock); -- mutex_lock(&ctx->uring_lock); -- } -+void io_msg_ring_cleanup(struct io_kiocb *req) -+{ -+ struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); - -- return 0; -+ if (WARN_ON_ONCE(!msg->src_file)) -+ return; -+ -+ fput(msg->src_file); -+ msg->src_file = NULL; - } - --static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags) -+static int io_msg_ring_data(struct io_kiocb *req, unsigned int issue_flags) - { - struct io_ring_ctx *target_ctx = req->file->private_data; - struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); -- struct io_ring_ctx *ctx = req->ctx; -- unsigned long file_ptr; -- struct file *src_file; - int ret; - -- if (msg->len) -- return -EINVAL; -- if (target_ctx == ctx) -+ if (msg->src_fd || msg->dst_fd || msg->flags) - return -EINVAL; - if (target_ctx->flags & IORING_SETUP_R_DISABLED) - return -EBADFD; - -- ret = io_double_lock_ctx(ctx, target_ctx, issue_flags); -- if (unlikely(ret)) -- return ret; -+ ret = -EOVERFLOW; -+ if (target_ctx->flags & IORING_SETUP_IOPOLL) { -+ if (unlikely(io_double_lock_ctx(target_ctx, issue_flags))) -+ return -EAGAIN; -+ if (io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0, true)) -+ ret = 0; -+ io_double_unlock_ctx(target_ctx); -+ } else { -+ if (io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0, true)) -+ ret = 0; -+ } - -- ret = -EBADF; -- if (unlikely(msg->src_fd >= ctx->nr_user_files)) -- goto out_unlock; -+ return ret; -+} - -- msg->src_fd = array_index_nospec(msg->src_fd, ctx->nr_user_files); -- file_ptr = io_fixed_file_slot(&ctx->file_table, msg->src_fd)->file_ptr; -- if (!file_ptr) -- goto out_unlock; -+static struct file *io_msg_grab_file(struct io_kiocb *req, unsigned int issue_flags) -+{ -+ struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); -+ struct io_ring_ctx *ctx = req->ctx; -+ struct file *file = NULL; -+ unsigned long file_ptr; -+ int idx = msg->src_fd; -+ -+ io_ring_submit_lock(ctx, issue_flags); -+ if (likely(idx < ctx->nr_user_files)) { -+ idx = array_index_nospec(idx, ctx->nr_user_files); -+ file_ptr = io_fixed_file_slot(&ctx->file_table, idx)->file_ptr; -+ file = (struct file *) (file_ptr & FFS_MASK); -+ if (file) -+ get_file(file); -+ } -+ io_ring_submit_unlock(ctx, issue_flags); -+ return file; -+} - -- src_file = (struct file *) (file_ptr & FFS_MASK); -- get_file(src_file); -+static int io_msg_install_complete(struct io_kiocb *req, unsigned int issue_flags) -+{ -+ struct io_ring_ctx *target_ctx = req->file->private_data; -+ struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); -+ struct file *src_file = msg->src_file; -+ int ret; -+ -+ if (unlikely(io_double_lock_ctx(target_ctx, issue_flags))) -+ return -EAGAIN; - - ret = __io_fixed_fd_install(target_ctx, src_file, msg->dst_fd); -- if (ret < 0) { -- fput(src_file); -+ if (ret < 0) - goto out_unlock; -- } -+ -+ msg->src_file = NULL; -+ req->flags &= ~REQ_F_NEED_CLEANUP; - - if (msg->flags & IORING_MSG_RING_CQE_SKIP) - goto out_unlock; -- - /* - * If this fails, the target still received the file descriptor but - * wasn't notified of the fact. This means that if this request -@@ -125,10 +131,29 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags) - if (!io_post_aux_cqe(target_ctx, msg->user_data, ret, 0, true)) - ret = -EOVERFLOW; - out_unlock: -- io_double_unlock_ctx(ctx, target_ctx, issue_flags); -+ io_double_unlock_ctx(target_ctx); - return ret; - } - -+static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags) -+{ -+ struct io_ring_ctx *target_ctx = req->file->private_data; -+ struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); -+ struct io_ring_ctx *ctx = req->ctx; -+ struct file *src_file = msg->src_file; -+ -+ if (target_ctx == ctx) -+ return -EINVAL; -+ if (!src_file) { -+ src_file = io_msg_grab_file(req, issue_flags); -+ if (!src_file) -+ return -EBADF; -+ msg->src_file = src_file; -+ req->flags |= REQ_F_NEED_CLEANUP; -+ } -+ return io_msg_install_complete(req, issue_flags); -+} -+ - int io_msg_ring_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) - { - struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); -@@ -136,6 +161,7 @@ int io_msg_ring_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) - if (unlikely(sqe->buf_index || sqe->personality)) - return -EINVAL; - -+ msg->src_file = NULL; - msg->user_data = READ_ONCE(sqe->off); - msg->len = READ_ONCE(sqe->len); - msg->cmd = READ_ONCE(sqe->addr); -@@ -159,7 +185,7 @@ int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags) - - switch (msg->cmd) { - case IORING_MSG_DATA: -- ret = io_msg_ring_data(req); -+ ret = io_msg_ring_data(req, issue_flags); - break; - case IORING_MSG_SEND_FD: - ret = io_msg_send_fd(req, issue_flags); -diff --git a/io_uring/msg_ring.h b/io_uring/msg_ring.h -index fb9601f202d07..3987ee6c0e5f1 100644 ---- a/io_uring/msg_ring.h -+++ b/io_uring/msg_ring.h -@@ -2,3 +2,4 @@ - - int io_msg_ring_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); - int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags); -+void io_msg_ring_cleanup(struct io_kiocb *req); -diff --git a/io_uring/opdef.c b/io_uring/opdef.c -index 04dd2c983fce4..3aa0d65c50e34 100644 ---- a/io_uring/opdef.c -+++ b/io_uring/opdef.c -@@ -445,6 +445,7 @@ const struct io_op_def io_op_defs[] = { - .name = "MSG_RING", - .prep = io_msg_ring_prep, - .issue = io_msg_ring, -+ .cleanup = io_msg_ring_cleanup, - }, - [IORING_OP_FSETXATTR] = { - .needs_file = 1, -diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c -index 73f11e4db3a4d..97ecca43386d9 100644 ---- a/kernel/cgroup/cgroup.c -+++ b/kernel/cgroup/cgroup.c -@@ -57,6 +57,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -6681,6 +6682,9 @@ void cgroup_exit(struct task_struct *tsk) - list_add_tail(&tsk->cg_list, &cset->dying_tasks); - cset->nr_tasks--; - -+ if (dl_task(tsk)) -+ dec_dl_tasks_cs(tsk); -+ - WARN_ON_ONCE(cgroup_task_frozen(tsk)); - if (unlikely(!(tsk->flags & PF_KTHREAD) && - test_bit(CGRP_FREEZE, &task_dfl_cgroup(tsk)->flags))) -diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c -index e276db7228451..db3e05b6b4dd2 100644 ---- a/kernel/cgroup/cpuset.c -+++ b/kernel/cgroup/cpuset.c -@@ -193,6 +193,14 @@ struct cpuset { - int use_parent_ecpus; - int child_ecpus_count; - -+ /* -+ * number of SCHED_DEADLINE tasks attached to this cpuset, so that we -+ * know when to rebuild associated root domain bandwidth information. -+ */ -+ int nr_deadline_tasks; -+ int nr_migrate_dl_tasks; -+ u64 sum_migrate_dl_bw; -+ - /* Invalid partition error code, not lock protected */ - enum prs_errcode prs_err; - -@@ -245,6 +253,20 @@ static inline struct cpuset *parent_cs(struct cpuset *cs) - return css_cs(cs->css.parent); - } - -+void inc_dl_tasks_cs(struct task_struct *p) -+{ -+ struct cpuset *cs = task_cs(p); -+ -+ cs->nr_deadline_tasks++; -+} -+ -+void dec_dl_tasks_cs(struct task_struct *p) -+{ -+ struct cpuset *cs = task_cs(p); -+ -+ cs->nr_deadline_tasks--; -+} -+ - /* bits in struct cpuset flags field */ - typedef enum { - CS_ONLINE, -@@ -366,22 +388,23 @@ static struct cpuset top_cpuset = { - if (is_cpuset_online(((des_cs) = css_cs((pos_css))))) - - /* -- * There are two global locks guarding cpuset structures - cpuset_rwsem and -+ * There are two global locks guarding cpuset structures - cpuset_mutex and - * callback_lock. We also require taking task_lock() when dereferencing a - * task's cpuset pointer. See "The task_lock() exception", at the end of this -- * comment. The cpuset code uses only cpuset_rwsem write lock. Other -- * kernel subsystems can use cpuset_read_lock()/cpuset_read_unlock() to -- * prevent change to cpuset structures. -+ * comment. The cpuset code uses only cpuset_mutex. Other kernel subsystems -+ * can use cpuset_lock()/cpuset_unlock() to prevent change to cpuset -+ * structures. Note that cpuset_mutex needs to be a mutex as it is used in -+ * paths that rely on priority inheritance (e.g. scheduler - on RT) for -+ * correctness. - * - * A task must hold both locks to modify cpusets. If a task holds -- * cpuset_rwsem, it blocks others wanting that rwsem, ensuring that it -- * is the only task able to also acquire callback_lock and be able to -- * modify cpusets. It can perform various checks on the cpuset structure -- * first, knowing nothing will change. It can also allocate memory while -- * just holding cpuset_rwsem. While it is performing these checks, various -- * callback routines can briefly acquire callback_lock to query cpusets. -- * Once it is ready to make the changes, it takes callback_lock, blocking -- * everyone else. -+ * cpuset_mutex, it blocks others, ensuring that it is the only task able to -+ * also acquire callback_lock and be able to modify cpusets. It can perform -+ * various checks on the cpuset structure first, knowing nothing will change. -+ * It can also allocate memory while just holding cpuset_mutex. While it is -+ * performing these checks, various callback routines can briefly acquire -+ * callback_lock to query cpusets. Once it is ready to make the changes, it -+ * takes callback_lock, blocking everyone else. - * - * Calls to the kernel memory allocator can not be made while holding - * callback_lock, as that would risk double tripping on callback_lock -@@ -403,16 +426,16 @@ static struct cpuset top_cpuset = { - * guidelines for accessing subsystem state in kernel/cgroup.c - */ - --DEFINE_STATIC_PERCPU_RWSEM(cpuset_rwsem); -+static DEFINE_MUTEX(cpuset_mutex); - --void cpuset_read_lock(void) -+void cpuset_lock(void) - { -- percpu_down_read(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - } - --void cpuset_read_unlock(void) -+void cpuset_unlock(void) - { -- percpu_up_read(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - } - - static DEFINE_SPINLOCK(callback_lock); -@@ -496,7 +519,7 @@ static inline bool partition_is_populated(struct cpuset *cs, - * One way or another, we guarantee to return some non-empty subset - * of cpu_online_mask. - * -- * Call with callback_lock or cpuset_rwsem held. -+ * Call with callback_lock or cpuset_mutex held. - */ - static void guarantee_online_cpus(struct task_struct *tsk, - struct cpumask *pmask) -@@ -538,7 +561,7 @@ out_unlock: - * One way or another, we guarantee to return some non-empty subset - * of node_states[N_MEMORY]. - * -- * Call with callback_lock or cpuset_rwsem held. -+ * Call with callback_lock or cpuset_mutex held. - */ - static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask) - { -@@ -550,7 +573,7 @@ static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask) - /* - * update task's spread flag if cpuset's page/slab spread flag is set - * -- * Call with callback_lock or cpuset_rwsem held. The check can be skipped -+ * Call with callback_lock or cpuset_mutex held. The check can be skipped - * if on default hierarchy. - */ - static void cpuset_update_task_spread_flags(struct cpuset *cs, -@@ -575,7 +598,7 @@ static void cpuset_update_task_spread_flags(struct cpuset *cs, - * - * One cpuset is a subset of another if all its allowed CPUs and - * Memory Nodes are a subset of the other, and its exclusive flags -- * are only set if the other's are set. Call holding cpuset_rwsem. -+ * are only set if the other's are set. Call holding cpuset_mutex. - */ - - static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q) -@@ -713,7 +736,7 @@ out: - * If we replaced the flag and mask values of the current cpuset - * (cur) with those values in the trial cpuset (trial), would - * our various subset and exclusive rules still be valid? Presumes -- * cpuset_rwsem held. -+ * cpuset_mutex held. - * - * 'cur' is the address of an actual, in-use cpuset. Operations - * such as list traversal that depend on the actual address of the -@@ -829,7 +852,7 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr, - rcu_read_unlock(); - } - --/* Must be called with cpuset_rwsem held. */ -+/* Must be called with cpuset_mutex held. */ - static inline int nr_cpusets(void) - { - /* jump label reference count + the top-level cpuset */ -@@ -855,7 +878,7 @@ static inline int nr_cpusets(void) - * domains when operating in the severe memory shortage situations - * that could cause allocation failures below. - * -- * Must be called with cpuset_rwsem held. -+ * Must be called with cpuset_mutex held. - * - * The three key local variables below are: - * cp - cpuset pointer, used (together with pos_css) to perform a -@@ -1066,11 +1089,14 @@ done: - return ndoms; - } - --static void update_tasks_root_domain(struct cpuset *cs) -+static void dl_update_tasks_root_domain(struct cpuset *cs) - { - struct css_task_iter it; - struct task_struct *task; - -+ if (cs->nr_deadline_tasks == 0) -+ return; -+ - css_task_iter_start(&cs->css, 0, &it); - - while ((task = css_task_iter_next(&it))) -@@ -1079,12 +1105,12 @@ static void update_tasks_root_domain(struct cpuset *cs) - css_task_iter_end(&it); - } - --static void rebuild_root_domains(void) -+static void dl_rebuild_rd_accounting(void) - { - struct cpuset *cs = NULL; - struct cgroup_subsys_state *pos_css; - -- percpu_rwsem_assert_held(&cpuset_rwsem); -+ lockdep_assert_held(&cpuset_mutex); - lockdep_assert_cpus_held(); - lockdep_assert_held(&sched_domains_mutex); - -@@ -1107,7 +1133,7 @@ static void rebuild_root_domains(void) - - rcu_read_unlock(); - -- update_tasks_root_domain(cs); -+ dl_update_tasks_root_domain(cs); - - rcu_read_lock(); - css_put(&cs->css); -@@ -1121,7 +1147,7 @@ partition_and_rebuild_sched_domains(int ndoms_new, cpumask_var_t doms_new[], - { - mutex_lock(&sched_domains_mutex); - partition_sched_domains_locked(ndoms_new, doms_new, dattr_new); -- rebuild_root_domains(); -+ dl_rebuild_rd_accounting(); - mutex_unlock(&sched_domains_mutex); - } - -@@ -1134,7 +1160,7 @@ partition_and_rebuild_sched_domains(int ndoms_new, cpumask_var_t doms_new[], - * 'cpus' is removed, then call this routine to rebuild the - * scheduler's dynamic sched domains. - * -- * Call with cpuset_rwsem held. Takes cpus_read_lock(). -+ * Call with cpuset_mutex held. Takes cpus_read_lock(). - */ - static void rebuild_sched_domains_locked(void) - { -@@ -1145,7 +1171,7 @@ static void rebuild_sched_domains_locked(void) - int ndoms; - - lockdep_assert_cpus_held(); -- percpu_rwsem_assert_held(&cpuset_rwsem); -+ lockdep_assert_held(&cpuset_mutex); - - /* - * If we have raced with CPU hotplug, return early to avoid -@@ -1196,9 +1222,9 @@ static void rebuild_sched_domains_locked(void) - void rebuild_sched_domains(void) - { - cpus_read_lock(); -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - rebuild_sched_domains_locked(); -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - cpus_read_unlock(); - } - -@@ -1208,7 +1234,7 @@ void rebuild_sched_domains(void) - * @new_cpus: the temp variable for the new effective_cpus mask - * - * Iterate through each task of @cs updating its cpus_allowed to the -- * effective cpuset's. As this function is called with cpuset_rwsem held, -+ * effective cpuset's. As this function is called with cpuset_mutex held, - * cpuset membership stays stable. - */ - static void update_tasks_cpumask(struct cpuset *cs, struct cpumask *new_cpus) -@@ -1317,7 +1343,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cs, int cmd, - int old_prs, new_prs; - int part_error = PERR_NONE; /* Partition error? */ - -- percpu_rwsem_assert_held(&cpuset_rwsem); -+ lockdep_assert_held(&cpuset_mutex); - - /* - * The parent must be a partition root. -@@ -1540,7 +1566,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cs, int cmd, - * - * On legacy hierarchy, effective_cpus will be the same with cpu_allowed. - * -- * Called with cpuset_rwsem held -+ * Called with cpuset_mutex held - */ - static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp, - bool force) -@@ -1700,7 +1726,7 @@ static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs, - struct cpuset *sibling; - struct cgroup_subsys_state *pos_css; - -- percpu_rwsem_assert_held(&cpuset_rwsem); -+ lockdep_assert_held(&cpuset_mutex); - - /* - * Check all its siblings and call update_cpumasks_hier() -@@ -1950,12 +1976,12 @@ static void *cpuset_being_rebound; - * @cs: the cpuset in which each task's mems_allowed mask needs to be changed - * - * Iterate through each task of @cs updating its mems_allowed to the -- * effective cpuset's. As this function is called with cpuset_rwsem held, -+ * effective cpuset's. As this function is called with cpuset_mutex held, - * cpuset membership stays stable. - */ - static void update_tasks_nodemask(struct cpuset *cs) - { -- static nodemask_t newmems; /* protected by cpuset_rwsem */ -+ static nodemask_t newmems; /* protected by cpuset_mutex */ - struct css_task_iter it; - struct task_struct *task; - -@@ -1968,7 +1994,7 @@ static void update_tasks_nodemask(struct cpuset *cs) - * take while holding tasklist_lock. Forks can happen - the - * mpol_dup() cpuset_being_rebound check will catch such forks, - * and rebind their vma mempolicies too. Because we still hold -- * the global cpuset_rwsem, we know that no other rebind effort -+ * the global cpuset_mutex, we know that no other rebind effort - * will be contending for the global variable cpuset_being_rebound. - * It's ok if we rebind the same mm twice; mpol_rebind_mm() - * is idempotent. Also migrate pages in each mm to new nodes. -@@ -2014,7 +2040,7 @@ static void update_tasks_nodemask(struct cpuset *cs) - * - * On legacy hierarchy, effective_mems will be the same with mems_allowed. - * -- * Called with cpuset_rwsem held -+ * Called with cpuset_mutex held - */ - static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) - { -@@ -2067,7 +2093,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) - * mempolicies and if the cpuset is marked 'memory_migrate', - * migrate the tasks pages to the new memory. - * -- * Call with cpuset_rwsem held. May take callback_lock during call. -+ * Call with cpuset_mutex held. May take callback_lock during call. - * Will take tasklist_lock, scan tasklist for tasks in cpuset cs, - * lock each such tasks mm->mmap_lock, scan its vma's and rebind - * their mempolicies to the cpusets new mems_allowed. -@@ -2159,7 +2185,7 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val) - * @cs: the cpuset in which each task's spread flags needs to be changed - * - * Iterate through each task of @cs updating its spread flags. As this -- * function is called with cpuset_rwsem held, cpuset membership stays -+ * function is called with cpuset_mutex held, cpuset membership stays - * stable. - */ - static void update_tasks_flags(struct cpuset *cs) -@@ -2179,7 +2205,7 @@ static void update_tasks_flags(struct cpuset *cs) - * cs: the cpuset to update - * turning_on: whether the flag is being set or cleared - * -- * Call with cpuset_rwsem held. -+ * Call with cpuset_mutex held. - */ - - static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, -@@ -2229,7 +2255,7 @@ out: - * @new_prs: new partition root state - * Return: 0 if successful, != 0 if error - * -- * Call with cpuset_rwsem held. -+ * Call with cpuset_mutex held. - */ - static int update_prstate(struct cpuset *cs, int new_prs) - { -@@ -2467,19 +2493,26 @@ static int cpuset_can_attach_check(struct cpuset *cs) - return 0; - } - --/* Called by cgroups to determine if a cpuset is usable; cpuset_rwsem held */ -+static void reset_migrate_dl_data(struct cpuset *cs) -+{ -+ cs->nr_migrate_dl_tasks = 0; -+ cs->sum_migrate_dl_bw = 0; -+} -+ -+/* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */ - static int cpuset_can_attach(struct cgroup_taskset *tset) - { - struct cgroup_subsys_state *css; -- struct cpuset *cs; -+ struct cpuset *cs, *oldcs; - struct task_struct *task; - int ret; - - /* used later by cpuset_attach() */ - cpuset_attach_old_cs = task_cs(cgroup_taskset_first(tset, &css)); -+ oldcs = cpuset_attach_old_cs; - cs = css_cs(css); - -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - - /* Check to see if task is allowed in the cpuset */ - ret = cpuset_can_attach_check(cs); -@@ -2487,21 +2520,46 @@ static int cpuset_can_attach(struct cgroup_taskset *tset) - goto out_unlock; - - cgroup_taskset_for_each(task, css, tset) { -- ret = task_can_attach(task, cs->effective_cpus); -+ ret = task_can_attach(task); - if (ret) - goto out_unlock; - ret = security_task_setscheduler(task); - if (ret) - goto out_unlock; -+ -+ if (dl_task(task)) { -+ cs->nr_migrate_dl_tasks++; -+ cs->sum_migrate_dl_bw += task->dl.dl_bw; -+ } - } - -+ if (!cs->nr_migrate_dl_tasks) -+ goto out_success; -+ -+ if (!cpumask_intersects(oldcs->effective_cpus, cs->effective_cpus)) { -+ int cpu = cpumask_any_and(cpu_active_mask, cs->effective_cpus); -+ -+ if (unlikely(cpu >= nr_cpu_ids)) { -+ reset_migrate_dl_data(cs); -+ ret = -EINVAL; -+ goto out_unlock; -+ } -+ -+ ret = dl_bw_alloc(cpu, cs->sum_migrate_dl_bw); -+ if (ret) { -+ reset_migrate_dl_data(cs); -+ goto out_unlock; -+ } -+ } -+ -+out_success: - /* - * Mark attach is in progress. This makes validate_change() fail - * changes which zero cpus/mems_allowed. - */ - cs->attach_in_progress++; - out_unlock: -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - return ret; - } - -@@ -2513,15 +2571,23 @@ static void cpuset_cancel_attach(struct cgroup_taskset *tset) - cgroup_taskset_first(tset, &css); - cs = css_cs(css); - -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - cs->attach_in_progress--; - if (!cs->attach_in_progress) - wake_up(&cpuset_attach_wq); -- percpu_up_write(&cpuset_rwsem); -+ -+ if (cs->nr_migrate_dl_tasks) { -+ int cpu = cpumask_any(cs->effective_cpus); -+ -+ dl_bw_free(cpu, cs->sum_migrate_dl_bw); -+ reset_migrate_dl_data(cs); -+ } -+ -+ mutex_unlock(&cpuset_mutex); - } - - /* -- * Protected by cpuset_rwsem. cpus_attach is used only by cpuset_attach_task() -+ * Protected by cpuset_mutex. cpus_attach is used only by cpuset_attach_task() - * but we can't allocate it dynamically there. Define it global and - * allocate from cpuset_init(). - */ -@@ -2530,7 +2596,7 @@ static nodemask_t cpuset_attach_nodemask_to; - - static void cpuset_attach_task(struct cpuset *cs, struct task_struct *task) - { -- percpu_rwsem_assert_held(&cpuset_rwsem); -+ lockdep_assert_held(&cpuset_mutex); - - if (cs != &top_cpuset) - guarantee_online_cpus(task, cpus_attach); -@@ -2558,7 +2624,7 @@ static void cpuset_attach(struct cgroup_taskset *tset) - cs = css_cs(css); - - lockdep_assert_cpus_held(); /* see cgroup_attach_lock() */ -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - - guarantee_online_mems(cs, &cpuset_attach_nodemask_to); - -@@ -2594,11 +2660,17 @@ static void cpuset_attach(struct cgroup_taskset *tset) - - cs->old_mems_allowed = cpuset_attach_nodemask_to; - -+ if (cs->nr_migrate_dl_tasks) { -+ cs->nr_deadline_tasks += cs->nr_migrate_dl_tasks; -+ oldcs->nr_deadline_tasks -= cs->nr_migrate_dl_tasks; -+ reset_migrate_dl_data(cs); -+ } -+ - cs->attach_in_progress--; - if (!cs->attach_in_progress) - wake_up(&cpuset_attach_wq); - -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - } - - /* The various types of files and directories in a cpuset file system */ -@@ -2630,7 +2702,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, - int retval = 0; - - cpus_read_lock(); -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - if (!is_cpuset_online(cs)) { - retval = -ENODEV; - goto out_unlock; -@@ -2666,7 +2738,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, - break; - } - out_unlock: -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - cpus_read_unlock(); - return retval; - } -@@ -2679,7 +2751,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, - int retval = -ENODEV; - - cpus_read_lock(); -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - if (!is_cpuset_online(cs)) - goto out_unlock; - -@@ -2692,7 +2764,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, - break; - } - out_unlock: -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - cpus_read_unlock(); - return retval; - } -@@ -2725,7 +2797,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, - * operation like this one can lead to a deadlock through kernfs - * active_ref protection. Let's break the protection. Losing the - * protection is okay as we check whether @cs is online after -- * grabbing cpuset_rwsem anyway. This only happens on the legacy -+ * grabbing cpuset_mutex anyway. This only happens on the legacy - * hierarchies. - */ - css_get(&cs->css); -@@ -2733,7 +2805,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, - flush_work(&cpuset_hotplug_work); - - cpus_read_lock(); -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - if (!is_cpuset_online(cs)) - goto out_unlock; - -@@ -2757,7 +2829,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, - - free_cpuset(trialcs); - out_unlock: -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - cpus_read_unlock(); - kernfs_unbreak_active_protection(of->kn); - css_put(&cs->css); -@@ -2905,13 +2977,13 @@ static ssize_t sched_partition_write(struct kernfs_open_file *of, char *buf, - - css_get(&cs->css); - cpus_read_lock(); -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - if (!is_cpuset_online(cs)) - goto out_unlock; - - retval = update_prstate(cs, val); - out_unlock: -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - cpus_read_unlock(); - css_put(&cs->css); - return retval ?: nbytes; -@@ -3124,7 +3196,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) - return 0; - - cpus_read_lock(); -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - - set_bit(CS_ONLINE, &cs->flags); - if (is_spread_page(parent)) -@@ -3175,7 +3247,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) - cpumask_copy(cs->effective_cpus, parent->cpus_allowed); - spin_unlock_irq(&callback_lock); - out_unlock: -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - cpus_read_unlock(); - return 0; - } -@@ -3196,7 +3268,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) - struct cpuset *cs = css_cs(css); - - cpus_read_lock(); -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - - if (is_partition_valid(cs)) - update_prstate(cs, 0); -@@ -3215,7 +3287,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) - cpuset_dec(); - clear_bit(CS_ONLINE, &cs->flags); - -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - cpus_read_unlock(); - } - -@@ -3228,7 +3300,7 @@ static void cpuset_css_free(struct cgroup_subsys_state *css) - - static void cpuset_bind(struct cgroup_subsys_state *root_css) - { -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - spin_lock_irq(&callback_lock); - - if (is_in_v2_mode()) { -@@ -3241,7 +3313,7 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css) - } - - spin_unlock_irq(&callback_lock); -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - } - - /* -@@ -3262,14 +3334,14 @@ static int cpuset_can_fork(struct task_struct *task, struct css_set *cset) - return 0; - - lockdep_assert_held(&cgroup_mutex); -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - - /* Check to see if task is allowed in the cpuset */ - ret = cpuset_can_attach_check(cs); - if (ret) - goto out_unlock; - -- ret = task_can_attach(task, cs->effective_cpus); -+ ret = task_can_attach(task); - if (ret) - goto out_unlock; - -@@ -3283,7 +3355,7 @@ static int cpuset_can_fork(struct task_struct *task, struct css_set *cset) - */ - cs->attach_in_progress++; - out_unlock: -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - return ret; - } - -@@ -3299,11 +3371,11 @@ static void cpuset_cancel_fork(struct task_struct *task, struct css_set *cset) - if (same_cs) - return; - -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - cs->attach_in_progress--; - if (!cs->attach_in_progress) - wake_up(&cpuset_attach_wq); -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - } - - /* -@@ -3331,7 +3403,7 @@ static void cpuset_fork(struct task_struct *task) - } - - /* CLONE_INTO_CGROUP */ -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - guarantee_online_mems(cs, &cpuset_attach_nodemask_to); - cpuset_attach_task(cs, task); - -@@ -3339,7 +3411,7 @@ static void cpuset_fork(struct task_struct *task) - if (!cs->attach_in_progress) - wake_up(&cpuset_attach_wq); - -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - } - - struct cgroup_subsys cpuset_cgrp_subsys = { -@@ -3369,8 +3441,6 @@ struct cgroup_subsys cpuset_cgrp_subsys = { - - int __init cpuset_init(void) - { -- BUG_ON(percpu_init_rwsem(&cpuset_rwsem)); -- - BUG_ON(!alloc_cpumask_var(&top_cpuset.cpus_allowed, GFP_KERNEL)); - BUG_ON(!alloc_cpumask_var(&top_cpuset.effective_cpus, GFP_KERNEL)); - BUG_ON(!zalloc_cpumask_var(&top_cpuset.subparts_cpus, GFP_KERNEL)); -@@ -3442,7 +3512,7 @@ hotplug_update_tasks_legacy(struct cpuset *cs, - is_empty = cpumask_empty(cs->cpus_allowed) || - nodes_empty(cs->mems_allowed); - -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - - /* - * Move tasks to the nearest ancestor with execution resources, -@@ -3452,7 +3522,7 @@ hotplug_update_tasks_legacy(struct cpuset *cs, - if (is_empty) - remove_tasks_in_empty_cpuset(cs); - -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - } - - static void -@@ -3503,14 +3573,14 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) - retry: - wait_event(cpuset_attach_wq, cs->attach_in_progress == 0); - -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - - /* - * We have raced with task attaching. We wait until attaching - * is finished, so we won't attach a task to an empty cpuset. - */ - if (cs->attach_in_progress) { -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - goto retry; - } - -@@ -3604,7 +3674,7 @@ update_tasks: - hotplug_update_tasks_legacy(cs, &new_cpus, &new_mems, - cpus_updated, mems_updated); - -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - } - - /** -@@ -3634,7 +3704,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work) - if (on_dfl && !alloc_cpumasks(NULL, &tmp)) - ptmp = &tmp; - -- percpu_down_write(&cpuset_rwsem); -+ mutex_lock(&cpuset_mutex); - - /* fetch the available cpus/mems and find out which changed how */ - cpumask_copy(&new_cpus, cpu_active_mask); -@@ -3691,7 +3761,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work) - update_tasks_nodemask(&top_cpuset); - } - -- percpu_up_write(&cpuset_rwsem); -+ mutex_unlock(&cpuset_mutex); - - /* if cpus or mems changed, we need to propagate to descendants */ - if (cpus_updated || mems_updated) { -@@ -4101,7 +4171,7 @@ void __cpuset_memory_pressure_bump(void) - * - Used for /proc//cpuset. - * - No need to task_lock(tsk) on this tsk->cpuset reference, as it - * doesn't really matter if tsk->cpuset changes after we read it, -- * and we take cpuset_rwsem, keeping cpuset_attach() from changing it -+ * and we take cpuset_mutex, keeping cpuset_attach() from changing it - * anyway. - */ - int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns, -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index b23dcbeacdf33..0f6a92737c912 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -7475,6 +7475,7 @@ static int __sched_setscheduler(struct task_struct *p, - int reset_on_fork; - int queue_flags = DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK; - struct rq *rq; -+ bool cpuset_locked = false; - - /* The pi code expects interrupts enabled */ - BUG_ON(pi && in_interrupt()); -@@ -7524,8 +7525,14 @@ recheck: - return retval; - } - -- if (pi) -- cpuset_read_lock(); -+ /* -+ * SCHED_DEADLINE bandwidth accounting relies on stable cpusets -+ * information. -+ */ -+ if (dl_policy(policy) || dl_policy(p->policy)) { -+ cpuset_locked = true; -+ cpuset_lock(); -+ } - - /* - * Make sure no PI-waiters arrive (or leave) while we are -@@ -7601,8 +7608,8 @@ change: - if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) { - policy = oldpolicy = -1; - task_rq_unlock(rq, p, &rf); -- if (pi) -- cpuset_read_unlock(); -+ if (cpuset_locked) -+ cpuset_unlock(); - goto recheck; - } - -@@ -7669,7 +7676,8 @@ change: - task_rq_unlock(rq, p, &rf); - - if (pi) { -- cpuset_read_unlock(); -+ if (cpuset_locked) -+ cpuset_unlock(); - rt_mutex_adjust_pi(p); - } - -@@ -7681,8 +7689,8 @@ change: - - unlock: - task_rq_unlock(rq, p, &rf); -- if (pi) -- cpuset_read_unlock(); -+ if (cpuset_locked) -+ cpuset_unlock(); - return retval; - } - -@@ -9075,8 +9083,7 @@ int cpuset_cpumask_can_shrink(const struct cpumask *cur, - return ret; - } - --int task_can_attach(struct task_struct *p, -- const struct cpumask *cs_effective_cpus) -+int task_can_attach(struct task_struct *p) - { - int ret = 0; - -@@ -9089,21 +9096,9 @@ int task_can_attach(struct task_struct *p, - * success of set_cpus_allowed_ptr() on all attached tasks - * before cpus_mask may be changed. - */ -- if (p->flags & PF_NO_SETAFFINITY) { -+ if (p->flags & PF_NO_SETAFFINITY) - ret = -EINVAL; -- goto out; -- } - -- if (dl_task(p) && !cpumask_intersects(task_rq(p)->rd->span, -- cs_effective_cpus)) { -- int cpu = cpumask_any_and(cpu_active_mask, cs_effective_cpus); -- -- if (unlikely(cpu >= nr_cpu_ids)) -- return -EINVAL; -- ret = dl_cpu_busy(cpu, p); -- } -- --out: - return ret; - } - -@@ -9385,7 +9380,7 @@ static void cpuset_cpu_active(void) - static int cpuset_cpu_inactive(unsigned int cpu) - { - if (!cpuhp_tasks_frozen) { -- int ret = dl_cpu_busy(cpu, NULL); -+ int ret = dl_bw_check_overflow(cpu); - - if (ret) - return ret; -diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c -index f7d381b6c3133..9ce9810861ba5 100644 ---- a/kernel/sched/deadline.c -+++ b/kernel/sched/deadline.c -@@ -16,6 +16,8 @@ - * Fabio Checconi - */ - -+#include -+ - /* - * Default limits for DL period; on the top end we guard against small util - * tasks still getting ridiculously long effective runtimes, on the bottom end we -@@ -2597,6 +2599,12 @@ static void switched_from_dl(struct rq *rq, struct task_struct *p) - if (task_on_rq_queued(p) && p->dl.dl_runtime) - task_non_contending(p); - -+ /* -+ * In case a task is setscheduled out from SCHED_DEADLINE we need to -+ * keep track of that on its cpuset (for correct bandwidth tracking). -+ */ -+ dec_dl_tasks_cs(p); -+ - if (!task_on_rq_queued(p)) { - /* - * Inactive timer is armed. However, p is leaving DEADLINE and -@@ -2637,6 +2645,12 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p) - if (hrtimer_try_to_cancel(&p->dl.inactive_timer) == 1) - put_task_struct(p); - -+ /* -+ * In case a task is setscheduled to SCHED_DEADLINE we need to keep -+ * track of that on its cpuset (for correct bandwidth tracking). -+ */ -+ inc_dl_tasks_cs(p); -+ - /* If p is not queued we will update its parameters at next wakeup. */ - if (!task_on_rq_queued(p)) { - add_rq_bw(&p->dl, &rq->dl); -@@ -3023,26 +3037,38 @@ int dl_cpuset_cpumask_can_shrink(const struct cpumask *cur, - return ret; - } - --int dl_cpu_busy(int cpu, struct task_struct *p) -+enum dl_bw_request { -+ dl_bw_req_check_overflow = 0, -+ dl_bw_req_alloc, -+ dl_bw_req_free -+}; -+ -+static int dl_bw_manage(enum dl_bw_request req, int cpu, u64 dl_bw) - { -- unsigned long flags, cap; -+ unsigned long flags; - struct dl_bw *dl_b; -- bool overflow; -+ bool overflow = 0; - - rcu_read_lock_sched(); - dl_b = dl_bw_of(cpu); - raw_spin_lock_irqsave(&dl_b->lock, flags); -- cap = dl_bw_capacity(cpu); -- overflow = __dl_overflow(dl_b, cap, 0, p ? p->dl.dl_bw : 0); - -- if (!overflow && p) { -- /* -- * We reserve space for this task in the destination -- * root_domain, as we can't fail after this point. -- * We will free resources in the source root_domain -- * later on (see set_cpus_allowed_dl()). -- */ -- __dl_add(dl_b, p->dl.dl_bw, dl_bw_cpus(cpu)); -+ if (req == dl_bw_req_free) { -+ __dl_sub(dl_b, dl_bw, dl_bw_cpus(cpu)); -+ } else { -+ unsigned long cap = dl_bw_capacity(cpu); -+ -+ overflow = __dl_overflow(dl_b, cap, 0, dl_bw); -+ -+ if (req == dl_bw_req_alloc && !overflow) { -+ /* -+ * We reserve space in the destination -+ * root_domain, as we can't fail after this point. -+ * We will free resources in the source root_domain -+ * later on (see set_cpus_allowed_dl()). -+ */ -+ __dl_add(dl_b, dl_bw, dl_bw_cpus(cpu)); -+ } - } - - raw_spin_unlock_irqrestore(&dl_b->lock, flags); -@@ -3050,6 +3076,21 @@ int dl_cpu_busy(int cpu, struct task_struct *p) - - return overflow ? -EBUSY : 0; - } -+ -+int dl_bw_check_overflow(int cpu) -+{ -+ return dl_bw_manage(dl_bw_req_check_overflow, cpu, 0); -+} -+ -+int dl_bw_alloc(int cpu, u64 dl_bw) -+{ -+ return dl_bw_manage(dl_bw_req_alloc, cpu, dl_bw); -+} -+ -+void dl_bw_free(int cpu, u64 dl_bw) -+{ -+ dl_bw_manage(dl_bw_req_free, cpu, dl_bw); -+} - #endif - - #ifdef CONFIG_SCHED_DEBUG -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index d6d488e8eb554..b62d53d7c264f 100644 ---- a/kernel/sched/sched.h -+++ b/kernel/sched/sched.h -@@ -330,7 +330,7 @@ extern void __getparam_dl(struct task_struct *p, struct sched_attr *attr); - extern bool __checkparam_dl(const struct sched_attr *attr); - extern bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr); - extern int dl_cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial); --extern int dl_cpu_busy(int cpu, struct task_struct *p); -+extern int dl_bw_check_overflow(int cpu); - - #ifdef CONFIG_CGROUP_SCHED - -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index af33c5a4166d4..1a87cb70f1eb5 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -4128,8 +4128,15 @@ static void *s_start(struct seq_file *m, loff_t *pos) - * will point to the same string as current_trace->name. - */ - mutex_lock(&trace_types_lock); -- if (unlikely(tr->current_trace && iter->trace->name != tr->current_trace->name)) -+ if (unlikely(tr->current_trace && iter->trace->name != tr->current_trace->name)) { -+ /* Close iter->trace before switching to the new current tracer */ -+ if (iter->trace->close) -+ iter->trace->close(iter); - *iter->trace = *tr->current_trace; -+ /* Reopen the new current tracer */ -+ if (iter->trace->open) -+ iter->trace->open(iter); -+ } - mutex_unlock(&trace_types_lock); - - #ifdef CONFIG_TRACER_MAX_TRACE -@@ -5189,11 +5196,17 @@ int tracing_set_cpumask(struct trace_array *tr, - !cpumask_test_cpu(cpu, tracing_cpumask_new)) { - atomic_inc(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled); - ring_buffer_record_disable_cpu(tr->array_buffer.buffer, cpu); -+#ifdef CONFIG_TRACER_MAX_TRACE -+ ring_buffer_record_disable_cpu(tr->max_buffer.buffer, cpu); -+#endif - } - if (!cpumask_test_cpu(cpu, tr->tracing_cpumask) && - cpumask_test_cpu(cpu, tracing_cpumask_new)) { - atomic_dec(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled); - ring_buffer_record_enable_cpu(tr->array_buffer.buffer, cpu); -+#ifdef CONFIG_TRACER_MAX_TRACE -+ ring_buffer_record_enable_cpu(tr->max_buffer.buffer, cpu); -+#endif - } - } - arch_spin_unlock(&tr->max_lock); -diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c -index 590b3d51afae9..ba37f768e2f27 100644 ---- a/kernel/trace/trace_irqsoff.c -+++ b/kernel/trace/trace_irqsoff.c -@@ -231,7 +231,8 @@ static void irqsoff_trace_open(struct trace_iterator *iter) - { - if (is_graph(iter->tr)) - graph_trace_open(iter); -- -+ else -+ iter->private = NULL; - } - - static void irqsoff_trace_close(struct trace_iterator *iter) -diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c -index 330aee1c1a49e..0469a04a355f2 100644 ---- a/kernel/trace/trace_sched_wakeup.c -+++ b/kernel/trace/trace_sched_wakeup.c -@@ -168,6 +168,8 @@ static void wakeup_trace_open(struct trace_iterator *iter) - { - if (is_graph(iter->tr)) - graph_trace_open(iter); -+ else -+ iter->private = NULL; - } - - static void wakeup_trace_close(struct trace_iterator *iter) -diff --git a/lib/clz_ctz.c b/lib/clz_ctz.c -index 0d3a686b5ba29..fb8c0c5c2bd27 100644 ---- a/lib/clz_ctz.c -+++ b/lib/clz_ctz.c -@@ -28,36 +28,16 @@ int __weak __clzsi2(int val) - } - EXPORT_SYMBOL(__clzsi2); - --int __weak __clzdi2(long val); --int __weak __ctzdi2(long val); --#if BITS_PER_LONG == 32 -- --int __weak __clzdi2(long val) -+int __weak __clzdi2(u64 val); -+int __weak __clzdi2(u64 val) - { -- return 32 - fls((int)val); -+ return 64 - fls64(val); - } - EXPORT_SYMBOL(__clzdi2); - --int __weak __ctzdi2(long val) -+int __weak __ctzdi2(u64 val); -+int __weak __ctzdi2(u64 val) - { -- return __ffs((u32)val); -+ return __ffs64(val); - } - EXPORT_SYMBOL(__ctzdi2); -- --#elif BITS_PER_LONG == 64 -- --int __weak __clzdi2(long val) --{ -- return 64 - fls64((u64)val); --} --EXPORT_SYMBOL(__clzdi2); -- --int __weak __ctzdi2(long val) --{ -- return __ffs64((u64)val); --} --EXPORT_SYMBOL(__ctzdi2); -- --#else --#error BITS_PER_LONG not 32 or 64 --#endif -diff --git a/lib/maple_tree.c b/lib/maple_tree.c -index 47d0c95b9a01e..250b4c67fac8f 100644 ---- a/lib/maple_tree.c -+++ b/lib/maple_tree.c -@@ -4333,6 +4333,9 @@ static inline bool mas_wr_append(struct ma_wr_state *wr_mas) - struct ma_state *mas = wr_mas->mas; - unsigned char node_pivots = mt_pivots[wr_mas->type]; - -+ if (mt_in_rcu(mas->tree)) -+ return false; -+ - if ((mas->index != wr_mas->r_min) && (mas->last == wr_mas->r_max)) { - if (new_end < node_pivots) - wr_mas->pivots[new_end] = wr_mas->pivots[end]; -diff --git a/lib/radix-tree.c b/lib/radix-tree.c -index 3c78e1e8b2ad6..2ec38f08e4f0e 100644 ---- a/lib/radix-tree.c -+++ b/lib/radix-tree.c -@@ -1134,7 +1134,6 @@ static void set_iter_tags(struct radix_tree_iter *iter, - void __rcu **radix_tree_iter_resume(void __rcu **slot, - struct radix_tree_iter *iter) - { -- slot++; - iter->index = __radix_tree_iter_add(iter, 1); - iter->next_index = iter->index; - iter->tags = 0; -diff --git a/mm/madvise.c b/mm/madvise.c -index d03e149ffe6e8..5973399b2f9b7 100644 ---- a/mm/madvise.c -+++ b/mm/madvise.c -@@ -654,8 +654,8 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr, - * deactivate all pages. - */ - if (folio_test_large(folio)) { -- if (folio_mapcount(folio) != 1) -- goto out; -+ if (folio_estimated_sharers(folio) != 1) -+ break; - folio_get(folio); - if (!folio_trylock(folio)) { - folio_put(folio); -diff --git a/mm/memory-failure.c b/mm/memory-failure.c -index 4457f9423e2c1..99de0328d1bed 100644 ---- a/mm/memory-failure.c -+++ b/mm/memory-failure.c -@@ -2591,10 +2591,13 @@ retry: - if (ret > 0) { - ret = soft_offline_in_use_page(page); - } else if (ret == 0) { -- if (!page_handle_poison(page, true, false) && try_again) { -- try_again = false; -- flags &= ~MF_COUNT_INCREASED; -- goto retry; -+ if (!page_handle_poison(page, true, false)) { -+ if (try_again) { -+ try_again = false; -+ flags &= ~MF_COUNT_INCREASED; -+ goto retry; -+ } -+ ret = -EBUSY; - } - } - -diff --git a/mm/shmem.c b/mm/shmem.c -index aba041a3df739..10365ced5b1fc 100644 ---- a/mm/shmem.c -+++ b/mm/shmem.c -@@ -800,14 +800,16 @@ unsigned long shmem_partial_swap_usage(struct address_space *mapping, - XA_STATE(xas, &mapping->i_pages, start); - struct page *page; - unsigned long swapped = 0; -+ unsigned long max = end - 1; - - rcu_read_lock(); -- xas_for_each(&xas, page, end - 1) { -+ xas_for_each(&xas, page, max) { - if (xas_retry(&xas, page)) - continue; - if (xa_is_value(page)) - swapped++; -- -+ if (xas.xa_index == max) -+ break; - if (need_resched()) { - xas_pause(&xas); - cond_resched_rcu(); -diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index d5dc361dc104d..80bd104a4d42e 100644 ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -2909,6 +2909,10 @@ void *vmap_pfn(unsigned long *pfns, unsigned int count, pgprot_t prot) - free_vm_area(area); - return NULL; - } -+ -+ flush_cache_vmap((unsigned long)area->addr, -+ (unsigned long)area->addr + count * PAGE_SIZE); -+ - return area->addr; - } - EXPORT_SYMBOL_GPL(vmap_pfn); -diff --git a/net/Makefile b/net/Makefile -index 6a62e5b273781..0914bea9c335f 100644 ---- a/net/Makefile -+++ b/net/Makefile -@@ -23,6 +23,7 @@ obj-$(CONFIG_BPFILTER) += bpfilter/ - obj-$(CONFIG_PACKET) += packet/ - obj-$(CONFIG_NET_KEY) += key/ - obj-$(CONFIG_BRIDGE) += bridge/ -+obj-$(CONFIG_NET_DEVLINK) += devlink/ - obj-$(CONFIG_NET_DSA) += dsa/ - obj-$(CONFIG_ATALK) += appletalk/ - obj-$(CONFIG_X25) += x25/ -diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c -index f1741fbfb6178..98a624f32b946 100644 ---- a/net/batman-adv/bat_v_elp.c -+++ b/net/batman-adv/bat_v_elp.c -@@ -506,7 +506,7 @@ int batadv_v_elp_packet_recv(struct sk_buff *skb, - struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - struct batadv_elp_packet *elp_packet; - struct batadv_hard_iface *primary_if; -- struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); -+ struct ethhdr *ethhdr; - bool res; - int ret = NET_RX_DROP; - -@@ -514,6 +514,7 @@ int batadv_v_elp_packet_recv(struct sk_buff *skb, - if (!res) - goto free_skb; - -+ ethhdr = eth_hdr(skb); - if (batadv_is_my_mac(bat_priv, ethhdr->h_source)) - goto free_skb; - -diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c -index 033639df96d85..9f4815f4c8e89 100644 ---- a/net/batman-adv/bat_v_ogm.c -+++ b/net/batman-adv/bat_v_ogm.c -@@ -124,8 +124,10 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb, - { - struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); - -- if (hard_iface->if_status != BATADV_IF_ACTIVE) -+ if (hard_iface->if_status != BATADV_IF_ACTIVE) { -+ kfree_skb(skb); - return; -+ } - - batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX); - batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES, -@@ -986,7 +988,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb, - { - struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - struct batadv_ogm2_packet *ogm_packet; -- struct ethhdr *ethhdr = eth_hdr(skb); -+ struct ethhdr *ethhdr; - int ogm_offset; - u8 *packet_pos; - int ret = NET_RX_DROP; -@@ -1000,6 +1002,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb, - if (!batadv_check_management_packet(skb, if_incoming, BATADV_OGM2_HLEN)) - goto free_skb; - -+ ethhdr = eth_hdr(skb); - if (batadv_is_my_mac(bat_priv, ethhdr->h_source)) - goto free_skb; - -diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c -index 41c1ad33d009f..24c9c0c3f3166 100644 ---- a/net/batman-adv/hard-interface.c -+++ b/net/batman-adv/hard-interface.c -@@ -630,7 +630,19 @@ out: - */ - void batadv_update_min_mtu(struct net_device *soft_iface) - { -- soft_iface->mtu = batadv_hardif_min_mtu(soft_iface); -+ struct batadv_priv *bat_priv = netdev_priv(soft_iface); -+ int limit_mtu; -+ int mtu; -+ -+ mtu = batadv_hardif_min_mtu(soft_iface); -+ -+ if (bat_priv->mtu_set_by_user) -+ limit_mtu = bat_priv->mtu_set_by_user; -+ else -+ limit_mtu = ETH_DATA_LEN; -+ -+ mtu = min(mtu, limit_mtu); -+ dev_set_mtu(soft_iface, mtu); - - /* Check if the local translate table should be cleaned up to match a - * new (and smaller) MTU. -diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c -index a5e4a4e976cf3..86e0664e0511b 100644 ---- a/net/batman-adv/netlink.c -+++ b/net/batman-adv/netlink.c -@@ -495,7 +495,10 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info) - attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]; - - atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr)); -+ -+ rtnl_lock(); - batadv_update_min_mtu(bat_priv->soft_iface); -+ rtnl_unlock(); - } - - if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) { -diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c -index 0f5c0679b55a2..38d411a52f331 100644 ---- a/net/batman-adv/soft-interface.c -+++ b/net/batman-adv/soft-interface.c -@@ -154,11 +154,14 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) - - static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) - { -+ struct batadv_priv *bat_priv = netdev_priv(dev); -+ - /* check ranges */ - if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev)) - return -EINVAL; - - dev->mtu = new_mtu; -+ bat_priv->mtu_set_by_user = new_mtu; - - return 0; - } -diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c -index 01d30c1e412c7..5d8cee74772fe 100644 ---- a/net/batman-adv/translation-table.c -+++ b/net/batman-adv/translation-table.c -@@ -774,7 +774,6 @@ check_roaming: - if (roamed_back) { - batadv_tt_global_free(bat_priv, tt_global, - "Roaming canceled"); -- tt_global = NULL; - } else { - /* The global entry has to be marked as ROAMING and - * has to be kept for consistency purpose -diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -index 758cd797a063b..76791815b26ba 100644 ---- a/net/batman-adv/types.h -+++ b/net/batman-adv/types.h -@@ -1546,6 +1546,12 @@ struct batadv_priv { - /** @soft_iface: net device which holds this struct as private data */ - struct net_device *soft_iface; - -+ /** -+ * @mtu_set_by_user: MTU was set once by user -+ * protected by rtnl_lock -+ */ -+ int mtu_set_by_user; -+ - /** - * @bat_counters: mesh internal traffic statistic counters (see - * batadv_counters) -diff --git a/net/can/isotp.c b/net/can/isotp.c -index b3c2a49b189cc..8c97f4061ffd7 100644 ---- a/net/can/isotp.c -+++ b/net/can/isotp.c -@@ -175,12 +175,6 @@ static bool isotp_register_rxid(struct isotp_sock *so) - return (isotp_bc_flags(so) == 0); - } - --static bool isotp_register_txecho(struct isotp_sock *so) --{ -- /* all modes but SF_BROADCAST register for tx echo skbs */ -- return (isotp_bc_flags(so) != CAN_ISOTP_SF_BROADCAST); --} -- - static enum hrtimer_restart isotp_rx_timer_handler(struct hrtimer *hrtimer) - { - struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, -@@ -1176,7 +1170,7 @@ static int isotp_release(struct socket *sock) - lock_sock(sk); - - /* remove current filters & unregister */ -- if (so->bound && isotp_register_txecho(so)) { -+ if (so->bound) { - if (so->ifindex) { - struct net_device *dev; - -@@ -1293,14 +1287,12 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) - can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id), - isotp_rcv, sk, "isotp", sk); - -- if (isotp_register_txecho(so)) { -- /* no consecutive frame echo skb in flight */ -- so->cfecho = 0; -+ /* no consecutive frame echo skb in flight */ -+ so->cfecho = 0; - -- /* register for echo skb's */ -- can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id), -- isotp_rcv_echo, sk, "isotpe", sk); -- } -+ /* register for echo skb's */ -+ can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id), -+ isotp_rcv_echo, sk, "isotpe", sk); - - dev_put(dev); - -@@ -1521,7 +1513,7 @@ static void isotp_notify(struct isotp_sock *so, unsigned long msg, - case NETDEV_UNREGISTER: - lock_sock(sk); - /* remove current filters & unregister */ -- if (so->bound && isotp_register_txecho(so)) { -+ if (so->bound) { - if (isotp_register_rxid(so)) - can_rx_unregister(dev_net(dev), dev, so->rxid, - SINGLE_MASK(so->rxid), -diff --git a/net/can/raw.c b/net/can/raw.c -index 4abab2c3011a3..8c104339d538d 100644 ---- a/net/can/raw.c -+++ b/net/can/raw.c -@@ -84,6 +84,8 @@ struct raw_sock { - struct sock sk; - int bound; - int ifindex; -+ struct net_device *dev; -+ netdevice_tracker dev_tracker; - struct list_head notifier; - int loopback; - int recv_own_msgs; -@@ -277,21 +279,24 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg, - if (!net_eq(dev_net(dev), sock_net(sk))) - return; - -- if (ro->ifindex != dev->ifindex) -+ if (ro->dev != dev) - return; - - switch (msg) { - case NETDEV_UNREGISTER: - lock_sock(sk); - /* remove current filters & unregister */ -- if (ro->bound) -+ if (ro->bound) { - raw_disable_allfilters(dev_net(dev), dev, sk); -+ netdev_put(dev, &ro->dev_tracker); -+ } - - if (ro->count > 1) - kfree(ro->filter); - - ro->ifindex = 0; - ro->bound = 0; -+ ro->dev = NULL; - ro->count = 0; - release_sock(sk); - -@@ -337,6 +342,7 @@ static int raw_init(struct sock *sk) - - ro->bound = 0; - ro->ifindex = 0; -+ ro->dev = NULL; - - /* set default filter to single entry dfilter */ - ro->dfilter.can_id = 0; -@@ -383,18 +389,14 @@ static int raw_release(struct socket *sock) - list_del(&ro->notifier); - spin_unlock(&raw_notifier_lock); - -+ rtnl_lock(); - lock_sock(sk); - - /* remove current filters & unregister */ - if (ro->bound) { -- if (ro->ifindex) { -- struct net_device *dev; -- -- dev = dev_get_by_index(sock_net(sk), ro->ifindex); -- if (dev) { -- raw_disable_allfilters(dev_net(dev), dev, sk); -- dev_put(dev); -- } -+ if (ro->dev) { -+ raw_disable_allfilters(dev_net(ro->dev), ro->dev, sk); -+ netdev_put(ro->dev, &ro->dev_tracker); - } else { - raw_disable_allfilters(sock_net(sk), NULL, sk); - } -@@ -405,6 +407,7 @@ static int raw_release(struct socket *sock) - - ro->ifindex = 0; - ro->bound = 0; -+ ro->dev = NULL; - ro->count = 0; - free_percpu(ro->uniq); - -@@ -412,6 +415,8 @@ static int raw_release(struct socket *sock) - sock->sk = NULL; - - release_sock(sk); -+ rtnl_unlock(); -+ - sock_put(sk); - - return 0; -@@ -422,6 +427,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) - struct sockaddr_can *addr = (struct sockaddr_can *)uaddr; - struct sock *sk = sock->sk; - struct raw_sock *ro = raw_sk(sk); -+ struct net_device *dev = NULL; - int ifindex; - int err = 0; - int notify_enetdown = 0; -@@ -431,24 +437,23 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) - if (addr->can_family != AF_CAN) - return -EINVAL; - -+ rtnl_lock(); - lock_sock(sk); - - if (ro->bound && addr->can_ifindex == ro->ifindex) - goto out; - - if (addr->can_ifindex) { -- struct net_device *dev; -- - dev = dev_get_by_index(sock_net(sk), addr->can_ifindex); - if (!dev) { - err = -ENODEV; - goto out; - } - if (dev->type != ARPHRD_CAN) { -- dev_put(dev); - err = -ENODEV; -- goto out; -+ goto out_put_dev; - } -+ - if (!(dev->flags & IFF_UP)) - notify_enetdown = 1; - -@@ -456,7 +461,9 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) - - /* filters set by default/setsockopt */ - err = raw_enable_allfilters(sock_net(sk), dev, sk); -- dev_put(dev); -+ if (err) -+ goto out_put_dev; -+ - } else { - ifindex = 0; - -@@ -467,26 +474,30 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) - if (!err) { - if (ro->bound) { - /* unregister old filters */ -- if (ro->ifindex) { -- struct net_device *dev; -- -- dev = dev_get_by_index(sock_net(sk), -- ro->ifindex); -- if (dev) { -- raw_disable_allfilters(dev_net(dev), -- dev, sk); -- dev_put(dev); -- } -+ if (ro->dev) { -+ raw_disable_allfilters(dev_net(ro->dev), -+ ro->dev, sk); -+ /* drop reference to old ro->dev */ -+ netdev_put(ro->dev, &ro->dev_tracker); - } else { - raw_disable_allfilters(sock_net(sk), NULL, sk); - } - } - ro->ifindex = ifindex; - ro->bound = 1; -+ /* bind() ok -> hold a reference for new ro->dev */ -+ ro->dev = dev; -+ if (ro->dev) -+ netdev_hold(ro->dev, &ro->dev_tracker, GFP_KERNEL); - } - -- out: -+out_put_dev: -+ /* remove potential reference from dev_get_by_index() */ -+ if (dev) -+ dev_put(dev); -+out: - release_sock(sk); -+ rtnl_unlock(); - - if (notify_enetdown) { - sk->sk_err = ENETDOWN; -@@ -552,9 +563,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, - rtnl_lock(); - lock_sock(sk); - -- if (ro->bound && ro->ifindex) { -- dev = dev_get_by_index(sock_net(sk), ro->ifindex); -- if (!dev) { -+ dev = ro->dev; -+ if (ro->bound && dev) { -+ if (dev->reg_state != NETREG_REGISTERED) { - if (count > 1) - kfree(filter); - err = -ENODEV; -@@ -595,7 +606,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, - ro->count = count; - - out_fil: -- dev_put(dev); - release_sock(sk); - rtnl_unlock(); - -@@ -613,9 +623,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, - rtnl_lock(); - lock_sock(sk); - -- if (ro->bound && ro->ifindex) { -- dev = dev_get_by_index(sock_net(sk), ro->ifindex); -- if (!dev) { -+ dev = ro->dev; -+ if (ro->bound && dev) { -+ if (dev->reg_state != NETREG_REGISTERED) { - err = -ENODEV; - goto out_err; - } -@@ -639,7 +649,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, - ro->err_mask = err_mask; - - out_err: -- dev_put(dev); - release_sock(sk); - rtnl_unlock(); - -diff --git a/net/core/Makefile b/net/core/Makefile -index 5857cec87b839..10edd66a8a372 100644 ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -33,7 +33,6 @@ obj-$(CONFIG_LWTUNNEL) += lwtunnel.o - obj-$(CONFIG_LWTUNNEL_BPF) += lwt_bpf.o - obj-$(CONFIG_DST_CACHE) += dst_cache.o - obj-$(CONFIG_HWBM) += hwbm.o --obj-$(CONFIG_NET_DEVLINK) += devlink.o - obj-$(CONFIG_GRO_CELLS) += gro_cells.o - obj-$(CONFIG_FAILOVER) += failover.o - obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o -diff --git a/net/core/devlink.c b/net/core/devlink.c -deleted file mode 100644 -index 5a4a4b34ac15c..0000000000000 ---- a/net/core/devlink.c -+++ /dev/null -@@ -1,12547 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * net/core/devlink.c - Network physical/parent device Netlink interface -- * -- * Heavily inspired by net/wireless/ -- * Copyright (c) 2016 Mellanox Technologies. All rights reserved. -- * Copyright (c) 2016 Jiri Pirko -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#define CREATE_TRACE_POINTS --#include -- --#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \ -- (__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX) -- --struct devlink_dev_stats { -- u32 reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; -- u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; --}; -- --struct devlink { -- u32 index; -- struct list_head port_list; -- struct list_head rate_list; -- struct list_head sb_list; -- struct list_head dpipe_table_list; -- struct list_head resource_list; -- struct list_head param_list; -- struct list_head region_list; -- struct list_head reporter_list; -- struct mutex reporters_lock; /* protects reporter_list */ -- struct devlink_dpipe_headers *dpipe_headers; -- struct list_head trap_list; -- struct list_head trap_group_list; -- struct list_head trap_policer_list; -- struct list_head linecard_list; -- struct mutex linecards_lock; /* protects linecard_list */ -- const struct devlink_ops *ops; -- u64 features; -- struct xarray snapshot_ids; -- struct devlink_dev_stats stats; -- struct device *dev; -- possible_net_t _net; -- /* Serializes access to devlink instance specific objects such as -- * port, sb, dpipe, resource, params, region, traps and more. -- */ -- struct mutex lock; -- struct lock_class_key lock_key; -- u8 reload_failed:1; -- refcount_t refcount; -- struct completion comp; -- struct rcu_head rcu; -- char priv[] __aligned(NETDEV_ALIGN); --}; -- --struct devlink_linecard_ops; --struct devlink_linecard_type; -- --struct devlink_linecard { -- struct list_head list; -- struct devlink *devlink; -- unsigned int index; -- refcount_t refcount; -- const struct devlink_linecard_ops *ops; -- void *priv; -- enum devlink_linecard_state state; -- struct mutex state_lock; /* Protects state */ -- const char *type; -- struct devlink_linecard_type *types; -- unsigned int types_count; -- struct devlink *nested_devlink; --}; -- --/** -- * struct devlink_resource - devlink resource -- * @name: name of the resource -- * @id: id, per devlink instance -- * @size: size of the resource -- * @size_new: updated size of the resource, reload is needed -- * @size_valid: valid in case the total size of the resource is valid -- * including its children -- * @parent: parent resource -- * @size_params: size parameters -- * @list: parent list -- * @resource_list: list of child resources -- * @occ_get: occupancy getter callback -- * @occ_get_priv: occupancy getter callback priv -- */ --struct devlink_resource { -- const char *name; -- u64 id; -- u64 size; -- u64 size_new; -- bool size_valid; -- struct devlink_resource *parent; -- struct devlink_resource_size_params size_params; -- struct list_head list; -- struct list_head resource_list; -- devlink_resource_occ_get_t *occ_get; -- void *occ_get_priv; --}; -- --void *devlink_priv(struct devlink *devlink) --{ -- return &devlink->priv; --} --EXPORT_SYMBOL_GPL(devlink_priv); -- --struct devlink *priv_to_devlink(void *priv) --{ -- return container_of(priv, struct devlink, priv); --} --EXPORT_SYMBOL_GPL(priv_to_devlink); -- --struct device *devlink_to_dev(const struct devlink *devlink) --{ -- return devlink->dev; --} --EXPORT_SYMBOL_GPL(devlink_to_dev); -- --static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = { -- { -- .name = "destination mac", -- .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC, -- .bitwidth = 48, -- }, --}; -- --struct devlink_dpipe_header devlink_dpipe_header_ethernet = { -- .name = "ethernet", -- .id = DEVLINK_DPIPE_HEADER_ETHERNET, -- .fields = devlink_dpipe_fields_ethernet, -- .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet), -- .global = true, --}; --EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet); -- --static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = { -- { -- .name = "destination ip", -- .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP, -- .bitwidth = 32, -- }, --}; -- --struct devlink_dpipe_header devlink_dpipe_header_ipv4 = { -- .name = "ipv4", -- .id = DEVLINK_DPIPE_HEADER_IPV4, -- .fields = devlink_dpipe_fields_ipv4, -- .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4), -- .global = true, --}; --EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4); -- --static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = { -- { -- .name = "destination ip", -- .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP, -- .bitwidth = 128, -- }, --}; -- --struct devlink_dpipe_header devlink_dpipe_header_ipv6 = { -- .name = "ipv6", -- .id = DEVLINK_DPIPE_HEADER_IPV6, -- .fields = devlink_dpipe_fields_ipv6, -- .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6), -- .global = true, --}; --EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6); -- --EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg); --EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr); --EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report); -- --static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = { -- [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY }, -- [DEVLINK_PORT_FN_ATTR_STATE] = -- NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE, -- DEVLINK_PORT_FN_STATE_ACTIVE), --}; -- --static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = { -- [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG }, --}; -- --static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC); --#define DEVLINK_REGISTERED XA_MARK_1 --#define DEVLINK_UNREGISTERING XA_MARK_2 -- --/* devlink instances are open to the access from the user space after -- * devlink_register() call. Such logical barrier allows us to have certain -- * expectations related to locking. -- * -- * Before *_register() - we are in initialization stage and no parallel -- * access possible to the devlink instance. All drivers perform that phase -- * by implicitly holding device_lock. -- * -- * After *_register() - users and driver can access devlink instance at -- * the same time. -- */ --#define ASSERT_DEVLINK_REGISTERED(d) \ -- WARN_ON_ONCE(!xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED)) --#define ASSERT_DEVLINK_NOT_REGISTERED(d) \ -- WARN_ON_ONCE(xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED)) -- --struct net *devlink_net(const struct devlink *devlink) --{ -- return read_pnet(&devlink->_net); --} --EXPORT_SYMBOL_GPL(devlink_net); -- --static void __devlink_put_rcu(struct rcu_head *head) --{ -- struct devlink *devlink = container_of(head, struct devlink, rcu); -- -- complete(&devlink->comp); --} -- --void devlink_put(struct devlink *devlink) --{ -- if (refcount_dec_and_test(&devlink->refcount)) -- /* Make sure unregister operation that may await the completion -- * is unblocked only after all users are after the end of -- * RCU grace period. -- */ -- call_rcu(&devlink->rcu, __devlink_put_rcu); --} -- --struct devlink *__must_check devlink_try_get(struct devlink *devlink) --{ -- if (refcount_inc_not_zero(&devlink->refcount)) -- return devlink; -- return NULL; --} -- --void devl_assert_locked(struct devlink *devlink) --{ -- lockdep_assert_held(&devlink->lock); --} --EXPORT_SYMBOL_GPL(devl_assert_locked); -- --#ifdef CONFIG_LOCKDEP --/* For use in conjunction with LOCKDEP only e.g. rcu_dereference_protected() */ --bool devl_lock_is_held(struct devlink *devlink) --{ -- return lockdep_is_held(&devlink->lock); --} --EXPORT_SYMBOL_GPL(devl_lock_is_held); --#endif -- --void devl_lock(struct devlink *devlink) --{ -- mutex_lock(&devlink->lock); --} --EXPORT_SYMBOL_GPL(devl_lock); -- --int devl_trylock(struct devlink *devlink) --{ -- return mutex_trylock(&devlink->lock); --} --EXPORT_SYMBOL_GPL(devl_trylock); -- --void devl_unlock(struct devlink *devlink) --{ -- mutex_unlock(&devlink->lock); --} --EXPORT_SYMBOL_GPL(devl_unlock); -- --static struct devlink * --devlinks_xa_find_get(struct net *net, unsigned long *indexp, xa_mark_t filter, -- void * (*xa_find_fn)(struct xarray *, unsigned long *, -- unsigned long, xa_mark_t)) --{ -- struct devlink *devlink; -- -- rcu_read_lock(); --retry: -- devlink = xa_find_fn(&devlinks, indexp, ULONG_MAX, DEVLINK_REGISTERED); -- if (!devlink) -- goto unlock; -- -- /* In case devlink_unregister() was already called and "unregistering" -- * mark was set, do not allow to get a devlink reference here. -- * This prevents live-lock of devlink_unregister() wait for completion. -- */ -- if (xa_get_mark(&devlinks, *indexp, DEVLINK_UNREGISTERING)) -- goto retry; -- -- /* For a possible retry, the xa_find_after() should be always used */ -- xa_find_fn = xa_find_after; -- if (!devlink_try_get(devlink)) -- goto retry; -- if (!net_eq(devlink_net(devlink), net)) { -- devlink_put(devlink); -- goto retry; -- } --unlock: -- rcu_read_unlock(); -- return devlink; --} -- --static struct devlink *devlinks_xa_find_get_first(struct net *net, -- unsigned long *indexp, -- xa_mark_t filter) --{ -- return devlinks_xa_find_get(net, indexp, filter, xa_find); --} -- --static struct devlink *devlinks_xa_find_get_next(struct net *net, -- unsigned long *indexp, -- xa_mark_t filter) --{ -- return devlinks_xa_find_get(net, indexp, filter, xa_find_after); --} -- --/* Iterate over devlink pointers which were possible to get reference to. -- * devlink_put() needs to be called for each iterated devlink pointer -- * in loop body in order to release the reference. -- */ --#define devlinks_xa_for_each_get(net, index, devlink, filter) \ -- for (index = 0, \ -- devlink = devlinks_xa_find_get_first(net, &index, filter); \ -- devlink; devlink = devlinks_xa_find_get_next(net, &index, filter)) -- --#define devlinks_xa_for_each_registered_get(net, index, devlink) \ -- devlinks_xa_for_each_get(net, index, devlink, DEVLINK_REGISTERED) -- --static struct devlink *devlink_get_from_attrs(struct net *net, -- struct nlattr **attrs) --{ -- struct devlink *devlink; -- unsigned long index; -- char *busname; -- char *devname; -- -- if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME]) -- return ERR_PTR(-EINVAL); -- -- busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]); -- devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); -- -- devlinks_xa_for_each_registered_get(net, index, devlink) { -- if (strcmp(devlink->dev->bus->name, busname) == 0 && -- strcmp(dev_name(devlink->dev), devname) == 0) -- return devlink; -- devlink_put(devlink); -- } -- -- return ERR_PTR(-ENODEV); --} -- --#define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port) \ -- WARN_ON_ONCE(!(devlink_port)->registered) --#define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port) \ -- WARN_ON_ONCE((devlink_port)->registered) --#define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port) \ -- WARN_ON_ONCE(!(devlink_port)->initialized) -- --static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink, -- unsigned int port_index) --{ -- struct devlink_port *devlink_port; -- -- list_for_each_entry(devlink_port, &devlink->port_list, list) { -- if (devlink_port->index == port_index) -- return devlink_port; -- } -- return NULL; --} -- --static bool devlink_port_index_exists(struct devlink *devlink, -- unsigned int port_index) --{ -- return devlink_port_get_by_index(devlink, port_index); --} -- --static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink, -- struct nlattr **attrs) --{ -- if (attrs[DEVLINK_ATTR_PORT_INDEX]) { -- u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); -- struct devlink_port *devlink_port; -- -- devlink_port = devlink_port_get_by_index(devlink, port_index); -- if (!devlink_port) -- return ERR_PTR(-ENODEV); -- return devlink_port; -- } -- return ERR_PTR(-EINVAL); --} -- --static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink, -- struct genl_info *info) --{ -- return devlink_port_get_from_attrs(devlink, info->attrs); --} -- --static inline bool --devlink_rate_is_leaf(struct devlink_rate *devlink_rate) --{ -- return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF; --} -- --static inline bool --devlink_rate_is_node(struct devlink_rate *devlink_rate) --{ -- return devlink_rate->type == DEVLINK_RATE_TYPE_NODE; --} -- --static struct devlink_rate * --devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info) --{ -- struct devlink_rate *devlink_rate; -- struct devlink_port *devlink_port; -- -- devlink_port = devlink_port_get_from_attrs(devlink, info->attrs); -- if (IS_ERR(devlink_port)) -- return ERR_CAST(devlink_port); -- devlink_rate = devlink_port->devlink_rate; -- return devlink_rate ?: ERR_PTR(-ENODEV); --} -- --static struct devlink_rate * --devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name) --{ -- static struct devlink_rate *devlink_rate; -- -- list_for_each_entry(devlink_rate, &devlink->rate_list, list) { -- if (devlink_rate_is_node(devlink_rate) && -- !strcmp(node_name, devlink_rate->name)) -- return devlink_rate; -- } -- return ERR_PTR(-ENODEV); --} -- --static struct devlink_rate * --devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs) --{ -- const char *rate_node_name; -- size_t len; -- -- if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME]) -- return ERR_PTR(-EINVAL); -- rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]); -- len = strlen(rate_node_name); -- /* Name cannot be empty or decimal number */ -- if (!len || strspn(rate_node_name, "0123456789") == len) -- return ERR_PTR(-EINVAL); -- -- return devlink_rate_node_get_by_name(devlink, rate_node_name); --} -- --static struct devlink_rate * --devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info) --{ -- return devlink_rate_node_get_from_attrs(devlink, info->attrs); --} -- --static struct devlink_rate * --devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info) --{ -- struct nlattr **attrs = info->attrs; -- -- if (attrs[DEVLINK_ATTR_PORT_INDEX]) -- return devlink_rate_leaf_get_from_info(devlink, info); -- else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME]) -- return devlink_rate_node_get_from_info(devlink, info); -- else -- return ERR_PTR(-EINVAL); --} -- --static struct devlink_linecard * --devlink_linecard_get_by_index(struct devlink *devlink, -- unsigned int linecard_index) --{ -- struct devlink_linecard *devlink_linecard; -- -- list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) { -- if (devlink_linecard->index == linecard_index) -- return devlink_linecard; -- } -- return NULL; --} -- --static bool devlink_linecard_index_exists(struct devlink *devlink, -- unsigned int linecard_index) --{ -- return devlink_linecard_get_by_index(devlink, linecard_index); --} -- --static struct devlink_linecard * --devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs) --{ -- if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) { -- u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]); -- struct devlink_linecard *linecard; -- -- mutex_lock(&devlink->linecards_lock); -- linecard = devlink_linecard_get_by_index(devlink, linecard_index); -- if (linecard) -- refcount_inc(&linecard->refcount); -- mutex_unlock(&devlink->linecards_lock); -- if (!linecard) -- return ERR_PTR(-ENODEV); -- return linecard; -- } -- return ERR_PTR(-EINVAL); --} -- --static struct devlink_linecard * --devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info) --{ -- return devlink_linecard_get_from_attrs(devlink, info->attrs); --} -- --static void devlink_linecard_put(struct devlink_linecard *linecard) --{ -- if (refcount_dec_and_test(&linecard->refcount)) { -- mutex_destroy(&linecard->state_lock); -- kfree(linecard); -- } --} -- --struct devlink_sb { -- struct list_head list; -- unsigned int index; -- u32 size; -- u16 ingress_pools_count; -- u16 egress_pools_count; -- u16 ingress_tc_count; -- u16 egress_tc_count; --}; -- --static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb) --{ -- return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count; --} -- --static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink, -- unsigned int sb_index) --{ -- struct devlink_sb *devlink_sb; -- -- list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -- if (devlink_sb->index == sb_index) -- return devlink_sb; -- } -- return NULL; --} -- --static bool devlink_sb_index_exists(struct devlink *devlink, -- unsigned int sb_index) --{ -- return devlink_sb_get_by_index(devlink, sb_index); --} -- --static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink, -- struct nlattr **attrs) --{ -- if (attrs[DEVLINK_ATTR_SB_INDEX]) { -- u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]); -- struct devlink_sb *devlink_sb; -- -- devlink_sb = devlink_sb_get_by_index(devlink, sb_index); -- if (!devlink_sb) -- return ERR_PTR(-ENODEV); -- return devlink_sb; -- } -- return ERR_PTR(-EINVAL); --} -- --static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink, -- struct genl_info *info) --{ -- return devlink_sb_get_from_attrs(devlink, info->attrs); --} -- --static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb, -- struct nlattr **attrs, -- u16 *p_pool_index) --{ -- u16 val; -- -- if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX]) -- return -EINVAL; -- -- val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]); -- if (val >= devlink_sb_pool_count(devlink_sb)) -- return -EINVAL; -- *p_pool_index = val; -- return 0; --} -- --static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb, -- struct genl_info *info, -- u16 *p_pool_index) --{ -- return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs, -- p_pool_index); --} -- --static int --devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs, -- enum devlink_sb_pool_type *p_pool_type) --{ -- u8 val; -- -- if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE]) -- return -EINVAL; -- -- val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]); -- if (val != DEVLINK_SB_POOL_TYPE_INGRESS && -- val != DEVLINK_SB_POOL_TYPE_EGRESS) -- return -EINVAL; -- *p_pool_type = val; -- return 0; --} -- --static int --devlink_sb_pool_type_get_from_info(struct genl_info *info, -- enum devlink_sb_pool_type *p_pool_type) --{ -- return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type); --} -- --static int --devlink_sb_th_type_get_from_attrs(struct nlattr **attrs, -- enum devlink_sb_threshold_type *p_th_type) --{ -- u8 val; -- -- if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]) -- return -EINVAL; -- -- val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]); -- if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC && -- val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC) -- return -EINVAL; -- *p_th_type = val; -- return 0; --} -- --static int --devlink_sb_th_type_get_from_info(struct genl_info *info, -- enum devlink_sb_threshold_type *p_th_type) --{ -- return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type); --} -- --static int --devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb, -- struct nlattr **attrs, -- enum devlink_sb_pool_type pool_type, -- u16 *p_tc_index) --{ -- u16 val; -- -- if (!attrs[DEVLINK_ATTR_SB_TC_INDEX]) -- return -EINVAL; -- -- val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]); -- if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS && -- val >= devlink_sb->ingress_tc_count) -- return -EINVAL; -- if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS && -- val >= devlink_sb->egress_tc_count) -- return -EINVAL; -- *p_tc_index = val; -- return 0; --} -- --static int --devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb, -- struct genl_info *info, -- enum devlink_sb_pool_type pool_type, -- u16 *p_tc_index) --{ -- return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs, -- pool_type, p_tc_index); --} -- --struct devlink_region { -- struct devlink *devlink; -- struct devlink_port *port; -- struct list_head list; -- union { -- const struct devlink_region_ops *ops; -- const struct devlink_port_region_ops *port_ops; -- }; -- struct mutex snapshot_lock; /* protects snapshot_list, -- * max_snapshots and cur_snapshots -- * consistency. -- */ -- struct list_head snapshot_list; -- u32 max_snapshots; -- u32 cur_snapshots; -- u64 size; --}; -- --struct devlink_snapshot { -- struct list_head list; -- struct devlink_region *region; -- u8 *data; -- u32 id; --}; -- --static struct devlink_region * --devlink_region_get_by_name(struct devlink *devlink, const char *region_name) --{ -- struct devlink_region *region; -- -- list_for_each_entry(region, &devlink->region_list, list) -- if (!strcmp(region->ops->name, region_name)) -- return region; -- -- return NULL; --} -- --static struct devlink_region * --devlink_port_region_get_by_name(struct devlink_port *port, -- const char *region_name) --{ -- struct devlink_region *region; -- -- list_for_each_entry(region, &port->region_list, list) -- if (!strcmp(region->ops->name, region_name)) -- return region; -- -- return NULL; --} -- --static struct devlink_snapshot * --devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id) --{ -- struct devlink_snapshot *snapshot; -- -- list_for_each_entry(snapshot, ®ion->snapshot_list, list) -- if (snapshot->id == id) -- return snapshot; -- -- return NULL; --} -- --#define DEVLINK_NL_FLAG_NEED_PORT BIT(0) --#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1) --#define DEVLINK_NL_FLAG_NEED_RATE BIT(2) --#define DEVLINK_NL_FLAG_NEED_RATE_NODE BIT(3) --#define DEVLINK_NL_FLAG_NEED_LINECARD BIT(4) -- --static int devlink_nl_pre_doit(const struct genl_ops *ops, -- struct sk_buff *skb, struct genl_info *info) --{ -- struct devlink_linecard *linecard; -- struct devlink_port *devlink_port; -- struct devlink *devlink; -- int err; -- -- devlink = devlink_get_from_attrs(genl_info_net(info), info->attrs); -- if (IS_ERR(devlink)) -- return PTR_ERR(devlink); -- devl_lock(devlink); -- info->user_ptr[0] = devlink; -- if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) { -- devlink_port = devlink_port_get_from_info(devlink, info); -- if (IS_ERR(devlink_port)) { -- err = PTR_ERR(devlink_port); -- goto unlock; -- } -- info->user_ptr[1] = devlink_port; -- } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) { -- devlink_port = devlink_port_get_from_info(devlink, info); -- if (!IS_ERR(devlink_port)) -- info->user_ptr[1] = devlink_port; -- } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE) { -- struct devlink_rate *devlink_rate; -- -- devlink_rate = devlink_rate_get_from_info(devlink, info); -- if (IS_ERR(devlink_rate)) { -- err = PTR_ERR(devlink_rate); -- goto unlock; -- } -- info->user_ptr[1] = devlink_rate; -- } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE_NODE) { -- struct devlink_rate *rate_node; -- -- rate_node = devlink_rate_node_get_from_info(devlink, info); -- if (IS_ERR(rate_node)) { -- err = PTR_ERR(rate_node); -- goto unlock; -- } -- info->user_ptr[1] = rate_node; -- } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) { -- linecard = devlink_linecard_get_from_info(devlink, info); -- if (IS_ERR(linecard)) { -- err = PTR_ERR(linecard); -- goto unlock; -- } -- info->user_ptr[1] = linecard; -- } -- return 0; -- --unlock: -- devl_unlock(devlink); -- devlink_put(devlink); -- return err; --} -- --static void devlink_nl_post_doit(const struct genl_ops *ops, -- struct sk_buff *skb, struct genl_info *info) --{ -- struct devlink_linecard *linecard; -- struct devlink *devlink; -- -- devlink = info->user_ptr[0]; -- if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) { -- linecard = info->user_ptr[1]; -- devlink_linecard_put(linecard); -- } -- devl_unlock(devlink); -- devlink_put(devlink); --} -- --static struct genl_family devlink_nl_family; -- --enum devlink_multicast_groups { -- DEVLINK_MCGRP_CONFIG, --}; -- --static const struct genl_multicast_group devlink_nl_mcgrps[] = { -- [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME }, --}; -- --static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink) --{ -- if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name)) -- return -EMSGSIZE; -- if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev))) -- return -EMSGSIZE; -- return 0; --} -- --static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink) --{ -- struct nlattr *nested_attr; -- -- nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK); -- if (!nested_attr) -- return -EMSGSIZE; -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- -- nla_nest_end(msg, nested_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, nested_attr); -- return -EMSGSIZE; --} -- --struct devlink_reload_combination { -- enum devlink_reload_action action; -- enum devlink_reload_limit limit; --}; -- --static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = { -- { -- /* can't reinitialize driver with no down time */ -- .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT, -- .limit = DEVLINK_RELOAD_LIMIT_NO_RESET, -- }, --}; -- --static bool --devlink_reload_combination_is_invalid(enum devlink_reload_action action, -- enum devlink_reload_limit limit) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) -- if (devlink_reload_invalid_combinations[i].action == action && -- devlink_reload_invalid_combinations[i].limit == limit) -- return true; -- return false; --} -- --static bool --devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action) --{ -- return test_bit(action, &devlink->ops->reload_actions); --} -- --static bool --devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit) --{ -- return test_bit(limit, &devlink->ops->reload_limits); --} -- --static int devlink_reload_stat_put(struct sk_buff *msg, -- enum devlink_reload_limit limit, u32 value) --{ -- struct nlattr *reload_stats_entry; -- -- reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY); -- if (!reload_stats_entry) -- return -EMSGSIZE; -- -- if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || -- nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) -- goto nla_put_failure; -- nla_nest_end(msg, reload_stats_entry); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, reload_stats_entry); -- return -EMSGSIZE; --} -- --static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) --{ -- struct nlattr *reload_stats_attr, *act_info, *act_stats; -- int i, j, stat_idx; -- u32 value; -- -- if (!is_remote) -- reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS); -- else -- reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS); -- -- if (!reload_stats_attr) -- return -EMSGSIZE; -- -- for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { -- if ((!is_remote && -- !devlink_reload_action_is_supported(devlink, i)) || -- i == DEVLINK_RELOAD_ACTION_UNSPEC) -- continue; -- act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); -- if (!act_info) -- goto nla_put_failure; -- -- if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) -- goto action_info_nest_cancel; -- act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); -- if (!act_stats) -- goto action_info_nest_cancel; -- -- for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { -- /* Remote stats are shown even if not locally supported. -- * Stats of actions with unspecified limit are shown -- * though drivers don't need to register unspecified -- * limit. -- */ -- if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && -- !devlink_reload_limit_is_supported(devlink, j)) || -- devlink_reload_combination_is_invalid(i, j)) -- continue; -- -- stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i; -- if (!is_remote) -- value = devlink->stats.reload_stats[stat_idx]; -- else -- value = devlink->stats.remote_reload_stats[stat_idx]; -- if (devlink_reload_stat_put(msg, j, value)) -- goto action_stats_nest_cancel; -- } -- nla_nest_end(msg, act_stats); -- nla_nest_end(msg, act_info); -- } -- nla_nest_end(msg, reload_stats_attr); -- return 0; -- --action_stats_nest_cancel: -- nla_nest_cancel(msg, act_stats); --action_info_nest_cancel: -- nla_nest_cancel(msg, act_info); --nla_put_failure: -- nla_nest_cancel(msg, reload_stats_attr); -- return -EMSGSIZE; --} -- --static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink, -- enum devlink_command cmd, u32 portid, -- u32 seq, int flags) --{ -- struct nlattr *dev_stats; -- void *hdr; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed)) -- goto nla_put_failure; -- -- dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS); -- if (!dev_stats) -- goto nla_put_failure; -- -- if (devlink_reload_stats_put(msg, devlink, false)) -- goto dev_stats_nest_cancel; -- if (devlink_reload_stats_put(msg, devlink, true)) -- goto dev_stats_nest_cancel; -- -- nla_nest_end(msg, dev_stats); -- genlmsg_end(msg, hdr); -- return 0; -- --dev_stats_nest_cancel: -- nla_nest_cancel(msg, dev_stats); --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static void devlink_notify(struct devlink *devlink, enum devlink_command cmd) --{ -- struct sk_buff *msg; -- int err; -- -- WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL); -- WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)); -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -- msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --static int devlink_nl_port_attrs_put(struct sk_buff *msg, -- struct devlink_port *devlink_port) --{ -- struct devlink_port_attrs *attrs = &devlink_port->attrs; -- -- if (!devlink_port->attrs_set) -- return 0; -- if (attrs->lanes) { -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes)) -- return -EMSGSIZE; -- } -- if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable)) -- return -EMSGSIZE; -- if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour)) -- return -EMSGSIZE; -- switch (devlink_port->attrs.flavour) { -- case DEVLINK_PORT_FLAVOUR_PCI_PF: -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, -- attrs->pci_pf.controller) || -- nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf)) -- return -EMSGSIZE; -- if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external)) -- return -EMSGSIZE; -- break; -- case DEVLINK_PORT_FLAVOUR_PCI_VF: -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, -- attrs->pci_vf.controller) || -- nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) || -- nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf)) -- return -EMSGSIZE; -- if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external)) -- return -EMSGSIZE; -- break; -- case DEVLINK_PORT_FLAVOUR_PCI_SF: -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, -- attrs->pci_sf.controller) || -- nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, -- attrs->pci_sf.pf) || -- nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER, -- attrs->pci_sf.sf)) -- return -EMSGSIZE; -- break; -- case DEVLINK_PORT_FLAVOUR_PHYSICAL: -- case DEVLINK_PORT_FLAVOUR_CPU: -- case DEVLINK_PORT_FLAVOUR_DSA: -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, -- attrs->phys.port_number)) -- return -EMSGSIZE; -- if (!attrs->split) -- return 0; -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, -- attrs->phys.port_number)) -- return -EMSGSIZE; -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER, -- attrs->phys.split_subport_number)) -- return -EMSGSIZE; -- break; -- default: -- break; -- } -- return 0; --} -- --static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops, -- struct devlink_port *port, -- struct sk_buff *msg, -- struct netlink_ext_ack *extack, -- bool *msg_updated) --{ -- u8 hw_addr[MAX_ADDR_LEN]; -- int hw_addr_len; -- int err; -- -- if (!ops->port_function_hw_addr_get) -- return 0; -- -- err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len, -- extack); -- if (err) { -- if (err == -EOPNOTSUPP) -- return 0; -- return err; -- } -- err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr); -- if (err) -- return err; -- *msg_updated = true; -- return 0; --} -- --static int devlink_nl_rate_fill(struct sk_buff *msg, -- struct devlink_rate *devlink_rate, -- enum devlink_command cmd, u32 portid, u32 seq, -- int flags, struct netlink_ext_ack *extack) --{ -- struct devlink *devlink = devlink_rate->devlink; -- void *hdr; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- -- if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type)) -- goto nla_put_failure; -- -- if (devlink_rate_is_leaf(devlink_rate)) { -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, -- devlink_rate->devlink_port->index)) -- goto nla_put_failure; -- } else if (devlink_rate_is_node(devlink_rate)) { -- if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME, -- devlink_rate->name)) -- goto nla_put_failure; -- } -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE, -- devlink_rate->tx_share, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX, -- devlink_rate->tx_max, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- if (devlink_rate->parent) -- if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME, -- devlink_rate->parent->name)) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static bool --devlink_port_fn_state_valid(enum devlink_port_fn_state state) --{ -- return state == DEVLINK_PORT_FN_STATE_INACTIVE || -- state == DEVLINK_PORT_FN_STATE_ACTIVE; --} -- --static bool --devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate) --{ -- return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED || -- opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED; --} -- --static int devlink_port_fn_state_fill(const struct devlink_ops *ops, -- struct devlink_port *port, -- struct sk_buff *msg, -- struct netlink_ext_ack *extack, -- bool *msg_updated) --{ -- enum devlink_port_fn_opstate opstate; -- enum devlink_port_fn_state state; -- int err; -- -- if (!ops->port_fn_state_get) -- return 0; -- -- err = ops->port_fn_state_get(port, &state, &opstate, extack); -- if (err) { -- if (err == -EOPNOTSUPP) -- return 0; -- return err; -- } -- if (!devlink_port_fn_state_valid(state)) { -- WARN_ON_ONCE(1); -- NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver"); -- return -EINVAL; -- } -- if (!devlink_port_fn_opstate_valid(opstate)) { -- WARN_ON_ONCE(1); -- NL_SET_ERR_MSG_MOD(extack, -- "Invalid operational state read from driver"); -- return -EINVAL; -- } -- if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) || -- nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate)) -- return -EMSGSIZE; -- *msg_updated = true; -- return 0; --} -- --static int --devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port, -- struct netlink_ext_ack *extack) --{ -- const struct devlink_ops *ops; -- struct nlattr *function_attr; -- bool msg_updated = false; -- int err; -- -- function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION); -- if (!function_attr) -- return -EMSGSIZE; -- -- ops = port->devlink->ops; -- err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack, -- &msg_updated); -- if (err) -- goto out; -- err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated); --out: -- if (err || !msg_updated) -- nla_nest_cancel(msg, function_attr); -- else -- nla_nest_end(msg, function_attr); -- return err; --} -- --static int devlink_nl_port_fill(struct sk_buff *msg, -- struct devlink_port *devlink_port, -- enum devlink_command cmd, u32 portid, u32 seq, -- int flags, struct netlink_ext_ack *extack) --{ -- struct devlink *devlink = devlink_port->devlink; -- void *hdr; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) -- goto nla_put_failure; -- -- /* Hold rtnl lock while accessing port's netdev attributes. */ -- rtnl_lock(); -- spin_lock_bh(&devlink_port->type_lock); -- if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type)) -- goto nla_put_failure_type_locked; -- if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET && -- nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE, -- devlink_port->desired_type)) -- goto nla_put_failure_type_locked; -- if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) { -- struct net *net = devlink_net(devlink_port->devlink); -- struct net_device *netdev = devlink_port->type_dev; -- -- if (netdev && net_eq(net, dev_net(netdev)) && -- (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX, -- netdev->ifindex) || -- nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME, -- netdev->name))) -- goto nla_put_failure_type_locked; -- } -- if (devlink_port->type == DEVLINK_PORT_TYPE_IB) { -- struct ib_device *ibdev = devlink_port->type_dev; -- -- if (ibdev && -- nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME, -- ibdev->name)) -- goto nla_put_failure_type_locked; -- } -- spin_unlock_bh(&devlink_port->type_lock); -- rtnl_unlock(); -- if (devlink_nl_port_attrs_put(msg, devlink_port)) -- goto nla_put_failure; -- if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack)) -- goto nla_put_failure; -- if (devlink_port->linecard && -- nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, -- devlink_port->linecard->index)) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure_type_locked: -- spin_unlock_bh(&devlink_port->type_lock); -- rtnl_unlock(); --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static void devlink_port_notify(struct devlink_port *devlink_port, -- enum devlink_command cmd) --{ -- struct devlink *devlink = devlink_port->devlink; -- struct sk_buff *msg; -- int err; -- -- WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL); -- -- if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -- return; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, -- 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --static void devlink_rate_notify(struct devlink_rate *devlink_rate, -- enum devlink_command cmd) --{ -- struct devlink *devlink = devlink_rate->devlink; -- struct sk_buff *msg; -- int err; -- -- WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL); -- -- if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -- return; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, -- 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink_rate *devlink_rate; -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err = 0; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- devl_lock(devlink); -- list_for_each_entry(devlink_rate, &devlink->rate_list, list) { -- enum devlink_command cmd = DEVLINK_CMD_RATE_NEW; -- u32 id = NETLINK_CB(cb->skb).portid; -- -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI, NULL); -- if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- devl_unlock(devlink); -- devlink_put(devlink); -- } --out: -- if (err != -EMSGSIZE) -- return err; -- -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_rate *devlink_rate = info->user_ptr[1]; -- struct sk_buff *msg; -- int err; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW, -- info->snd_portid, info->snd_seq, 0, -- info->extack); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static bool --devlink_rate_is_parent_node(struct devlink_rate *devlink_rate, -- struct devlink_rate *parent) --{ -- while (parent) { -- if (parent == devlink_rate) -- return true; -- parent = parent->parent; -- } -- return false; --} -- --static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct sk_buff *msg; -- int err; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, -- info->snd_portid, info->snd_seq, 0); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- if (idx < start) { -- idx++; -- devlink_put(devlink); -- continue; -- } -- -- devl_lock(devlink); -- err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, NLM_F_MULTI); -- devl_unlock(devlink); -- devlink_put(devlink); -- -- if (err) -- goto out; -- idx++; -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port = info->user_ptr[1]; -- struct sk_buff *msg; -- int err; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW, -- info->snd_portid, info->snd_seq, 0, -- info->extack); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- struct devlink_port *devlink_port; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- devl_lock(devlink); -- list_for_each_entry(devlink_port, &devlink->port_list, list) { -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_port_fill(msg, devlink_port, -- DEVLINK_CMD_NEW, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI, cb->extack); -- if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- devl_unlock(devlink); -- devlink_put(devlink); -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_port_type_set(struct devlink_port *devlink_port, -- enum devlink_port_type port_type) -- --{ -- int err; -- -- if (!devlink_port->devlink->ops->port_type_set) -- return -EOPNOTSUPP; -- -- if (port_type == devlink_port->type) -- return 0; -- -- err = devlink_port->devlink->ops->port_type_set(devlink_port, -- port_type); -- if (err) -- return err; -- -- devlink_port->desired_type = port_type; -- devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); -- return 0; --} -- --static int devlink_port_function_hw_addr_set(struct devlink_port *port, -- const struct nlattr *attr, -- struct netlink_ext_ack *extack) --{ -- const struct devlink_ops *ops = port->devlink->ops; -- const u8 *hw_addr; -- int hw_addr_len; -- -- hw_addr = nla_data(attr); -- hw_addr_len = nla_len(attr); -- if (hw_addr_len > MAX_ADDR_LEN) { -- NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long"); -- return -EINVAL; -- } -- if (port->type == DEVLINK_PORT_TYPE_ETH) { -- if (hw_addr_len != ETH_ALEN) { -- NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device"); -- return -EINVAL; -- } -- if (!is_unicast_ether_addr(hw_addr)) { -- NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported"); -- return -EINVAL; -- } -- } -- -- if (!ops->port_function_hw_addr_set) { -- NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes"); -- return -EOPNOTSUPP; -- } -- -- return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len, -- extack); --} -- --static int devlink_port_fn_state_set(struct devlink_port *port, -- const struct nlattr *attr, -- struct netlink_ext_ack *extack) --{ -- enum devlink_port_fn_state state; -- const struct devlink_ops *ops; -- -- state = nla_get_u8(attr); -- ops = port->devlink->ops; -- if (!ops->port_fn_state_set) { -- NL_SET_ERR_MSG_MOD(extack, -- "Function does not support state setting"); -- return -EOPNOTSUPP; -- } -- return ops->port_fn_state_set(port, state, extack); --} -- --static int devlink_port_function_set(struct devlink_port *port, -- const struct nlattr *attr, -- struct netlink_ext_ack *extack) --{ -- struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1]; -- int err; -- -- err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr, -- devlink_function_nl_policy, extack); -- if (err < 0) { -- NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes"); -- return err; -- } -- -- attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR]; -- if (attr) { -- err = devlink_port_function_hw_addr_set(port, attr, extack); -- if (err) -- return err; -- } -- /* Keep this as the last function attribute set, so that when -- * multiple port function attributes are set along with state, -- * Those can be applied first before activating the state. -- */ -- attr = tb[DEVLINK_PORT_FN_ATTR_STATE]; -- if (attr) -- err = devlink_port_fn_state_set(port, attr, extack); -- -- if (!err) -- devlink_port_notify(port, DEVLINK_CMD_PORT_NEW); -- return err; --} -- --static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port = info->user_ptr[1]; -- int err; -- -- if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) { -- enum devlink_port_type port_type; -- -- port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]); -- err = devlink_port_type_set(devlink_port, port_type); -- if (err) -- return err; -- } -- -- if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) { -- struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION]; -- struct netlink_ext_ack *extack = info->extack; -- -- err = devlink_port_function_set(devlink_port, attr, extack); -- if (err) -- return err; -- } -- -- return 0; --} -- --static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port = info->user_ptr[1]; -- struct devlink *devlink = info->user_ptr[0]; -- u32 count; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT)) -- return -EINVAL; -- if (!devlink->ops->port_split) -- return -EOPNOTSUPP; -- -- count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); -- -- if (!devlink_port->attrs.splittable) { -- /* Split ports cannot be split. */ -- if (devlink_port->attrs.split) -- NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further"); -- else -- NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split"); -- return -EINVAL; -- } -- -- if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) { -- NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count"); -- return -EINVAL; -- } -- -- return devlink->ops->port_split(devlink, devlink_port, count, -- info->extack); --} -- --static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port = info->user_ptr[1]; -- struct devlink *devlink = info->user_ptr[0]; -- -- if (!devlink->ops->port_unsplit) -- return -EOPNOTSUPP; -- return devlink->ops->port_unsplit(devlink, devlink_port, info->extack); --} -- --static int devlink_port_new_notify(struct devlink *devlink, -- unsigned int port_index, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port; -- struct sk_buff *msg; -- int err; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- lockdep_assert_held(&devlink->lock); -- devlink_port = devlink_port_get_by_index(devlink, port_index); -- if (!devlink_port) { -- err = -ENODEV; -- goto out; -- } -- -- err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW, -- info->snd_portid, info->snd_seq, 0, NULL); -- if (err) -- goto out; -- -- return genlmsg_reply(msg, info); -- --out: -- nlmsg_free(msg); -- return err; --} -- --static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct netlink_ext_ack *extack = info->extack; -- struct devlink_port_new_attrs new_attrs = {}; -- struct devlink *devlink = info->user_ptr[0]; -- unsigned int new_port_index; -- int err; -- -- if (!devlink->ops->port_new || !devlink->ops->port_del) -- return -EOPNOTSUPP; -- -- if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] || -- !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) { -- NL_SET_ERR_MSG_MOD(extack, "Port flavour or PCI PF are not specified"); -- return -EINVAL; -- } -- new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]); -- new_attrs.pfnum = -- nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]); -- -- if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -- /* Port index of the new port being created by driver. */ -- new_attrs.port_index = -- nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -- new_attrs.port_index_valid = true; -- } -- if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) { -- new_attrs.controller = -- nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]); -- new_attrs.controller_valid = true; -- } -- if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF && -- info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) { -- new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]); -- new_attrs.sfnum_valid = true; -- } -- -- err = devlink->ops->port_new(devlink, &new_attrs, extack, -- &new_port_index); -- if (err) -- return err; -- -- err = devlink_port_new_notify(devlink, new_port_index, info); -- if (err && err != -ENODEV) { -- /* Fail to send the response; destroy newly created port. */ -- devlink->ops->port_del(devlink, new_port_index, extack); -- } -- return err; --} -- --static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct netlink_ext_ack *extack = info->extack; -- struct devlink *devlink = info->user_ptr[0]; -- unsigned int port_index; -- -- if (!devlink->ops->port_del) -- return -EOPNOTSUPP; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) { -- NL_SET_ERR_MSG_MOD(extack, "Port index is not specified"); -- return -EINVAL; -- } -- port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -- -- return devlink->ops->port_del(devlink, port_index, extack); --} -- --static int --devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate, -- struct genl_info *info, -- struct nlattr *nla_parent) --{ -- struct devlink *devlink = devlink_rate->devlink; -- const char *parent_name = nla_data(nla_parent); -- const struct devlink_ops *ops = devlink->ops; -- size_t len = strlen(parent_name); -- struct devlink_rate *parent; -- int err = -EOPNOTSUPP; -- -- parent = devlink_rate->parent; -- if (parent && len) { -- NL_SET_ERR_MSG_MOD(info->extack, "Rate object already has parent."); -- return -EBUSY; -- } else if (parent && !len) { -- if (devlink_rate_is_leaf(devlink_rate)) -- err = ops->rate_leaf_parent_set(devlink_rate, NULL, -- devlink_rate->priv, NULL, -- info->extack); -- else if (devlink_rate_is_node(devlink_rate)) -- err = ops->rate_node_parent_set(devlink_rate, NULL, -- devlink_rate->priv, NULL, -- info->extack); -- if (err) -- return err; -- -- refcount_dec(&parent->refcnt); -- devlink_rate->parent = NULL; -- } else if (!parent && len) { -- parent = devlink_rate_node_get_by_name(devlink, parent_name); -- if (IS_ERR(parent)) -- return -ENODEV; -- -- if (parent == devlink_rate) { -- NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed"); -- return -EINVAL; -- } -- -- if (devlink_rate_is_node(devlink_rate) && -- devlink_rate_is_parent_node(devlink_rate, parent->parent)) { -- NL_SET_ERR_MSG_MOD(info->extack, "Node is already a parent of parent node."); -- return -EEXIST; -- } -- -- if (devlink_rate_is_leaf(devlink_rate)) -- err = ops->rate_leaf_parent_set(devlink_rate, parent, -- devlink_rate->priv, parent->priv, -- info->extack); -- else if (devlink_rate_is_node(devlink_rate)) -- err = ops->rate_node_parent_set(devlink_rate, parent, -- devlink_rate->priv, parent->priv, -- info->extack); -- if (err) -- return err; -- -- refcount_inc(&parent->refcnt); -- devlink_rate->parent = parent; -- } -- -- return 0; --} -- --static int devlink_nl_rate_set(struct devlink_rate *devlink_rate, -- const struct devlink_ops *ops, -- struct genl_info *info) --{ -- struct nlattr *nla_parent, **attrs = info->attrs; -- int err = -EOPNOTSUPP; -- u64 rate; -- -- if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) { -- rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]); -- if (devlink_rate_is_leaf(devlink_rate)) -- err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv, -- rate, info->extack); -- else if (devlink_rate_is_node(devlink_rate)) -- err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv, -- rate, info->extack); -- if (err) -- return err; -- devlink_rate->tx_share = rate; -- } -- -- if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) { -- rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]); -- if (devlink_rate_is_leaf(devlink_rate)) -- err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv, -- rate, info->extack); -- else if (devlink_rate_is_node(devlink_rate)) -- err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv, -- rate, info->extack); -- if (err) -- return err; -- devlink_rate->tx_max = rate; -- } -- -- nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME]; -- if (nla_parent) { -- err = devlink_nl_rate_parent_node_set(devlink_rate, info, -- nla_parent); -- if (err) -- return err; -- } -- -- return 0; --} -- --static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops, -- struct genl_info *info, -- enum devlink_rate_type type) --{ -- struct nlattr **attrs = info->attrs; -- -- if (type == DEVLINK_RATE_TYPE_LEAF) { -- if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) { -- NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the leafs"); -- return false; -- } -- if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) { -- NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the leafs"); -- return false; -- } -- if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] && -- !ops->rate_leaf_parent_set) { -- NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs"); -- return false; -- } -- } else if (type == DEVLINK_RATE_TYPE_NODE) { -- if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) { -- NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes"); -- return false; -- } -- if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) { -- NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the nodes"); -- return false; -- } -- if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] && -- !ops->rate_node_parent_set) { -- NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes"); -- return false; -- } -- } else { -- WARN(1, "Unknown type of rate object"); -- return false; -- } -- -- return true; --} -- --static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_rate *devlink_rate = info->user_ptr[1]; -- struct devlink *devlink = devlink_rate->devlink; -- const struct devlink_ops *ops = devlink->ops; -- int err; -- -- if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type)) -- return -EOPNOTSUPP; -- -- err = devlink_nl_rate_set(devlink_rate, ops, info); -- -- if (!err) -- devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); -- return err; --} -- --static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_rate *rate_node; -- const struct devlink_ops *ops; -- int err; -- -- ops = devlink->ops; -- if (!ops || !ops->rate_node_new || !ops->rate_node_del) { -- NL_SET_ERR_MSG_MOD(info->extack, "Rate nodes aren't supported"); -- return -EOPNOTSUPP; -- } -- -- if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE)) -- return -EOPNOTSUPP; -- -- rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs); -- if (!IS_ERR(rate_node)) -- return -EEXIST; -- else if (rate_node == ERR_PTR(-EINVAL)) -- return -EINVAL; -- -- rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL); -- if (!rate_node) -- return -ENOMEM; -- -- rate_node->devlink = devlink; -- rate_node->type = DEVLINK_RATE_TYPE_NODE; -- rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL); -- if (!rate_node->name) { -- err = -ENOMEM; -- goto err_strdup; -- } -- -- err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack); -- if (err) -- goto err_node_new; -- -- err = devlink_nl_rate_set(rate_node, ops, info); -- if (err) -- goto err_rate_set; -- -- refcount_set(&rate_node->refcnt, 1); -- list_add(&rate_node->list, &devlink->rate_list); -- devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); -- return 0; -- --err_rate_set: -- ops->rate_node_del(rate_node, rate_node->priv, info->extack); --err_node_new: -- kfree(rate_node->name); --err_strdup: -- kfree(rate_node); -- return err; --} -- --static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_rate *rate_node = info->user_ptr[1]; -- struct devlink *devlink = rate_node->devlink; -- const struct devlink_ops *ops = devlink->ops; -- int err; -- -- if (refcount_read(&rate_node->refcnt) > 1) { -- NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node."); -- return -EBUSY; -- } -- -- devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); -- err = ops->rate_node_del(rate_node, rate_node->priv, info->extack); -- if (rate_node->parent) -- refcount_dec(&rate_node->parent->refcnt); -- list_del(&rate_node->list); -- kfree(rate_node->name); -- kfree(rate_node); -- return err; --} -- --struct devlink_linecard_type { -- const char *type; -- const void *priv; --}; -- --static int devlink_nl_linecard_fill(struct sk_buff *msg, -- struct devlink *devlink, -- struct devlink_linecard *linecard, -- enum devlink_command cmd, u32 portid, -- u32 seq, int flags, -- struct netlink_ext_ack *extack) --{ -- struct devlink_linecard_type *linecard_type; -- struct nlattr *attr; -- void *hdr; -- int i; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index)) -- goto nla_put_failure; -- if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state)) -- goto nla_put_failure; -- if (linecard->type && -- nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type)) -- goto nla_put_failure; -- -- if (linecard->types_count) { -- attr = nla_nest_start(msg, -- DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES); -- if (!attr) -- goto nla_put_failure; -- for (i = 0; i < linecard->types_count; i++) { -- linecard_type = &linecard->types[i]; -- if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, -- linecard_type->type)) { -- nla_nest_cancel(msg, attr); -- goto nla_put_failure; -- } -- } -- nla_nest_end(msg, attr); -- } -- -- if (linecard->nested_devlink && -- devlink_nl_put_nested_handle(msg, linecard->nested_devlink)) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static void devlink_linecard_notify(struct devlink_linecard *linecard, -- enum devlink_command cmd) --{ -- struct devlink *devlink = linecard->devlink; -- struct sk_buff *msg; -- int err; -- -- WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW && -- cmd != DEVLINK_CMD_LINECARD_DEL); -- -- if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -- return; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0, -- NULL); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -- msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_linecard *linecard = info->user_ptr[1]; -- struct devlink *devlink = linecard->devlink; -- struct sk_buff *msg; -- int err; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- mutex_lock(&linecard->state_lock); -- err = devlink_nl_linecard_fill(msg, devlink, linecard, -- DEVLINK_CMD_LINECARD_NEW, -- info->snd_portid, info->snd_seq, 0, -- info->extack); -- mutex_unlock(&linecard->state_lock); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink_linecard *linecard; -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- mutex_lock(&devlink->linecards_lock); -- list_for_each_entry(linecard, &devlink->linecard_list, list) { -- if (idx < start) { -- idx++; -- continue; -- } -- mutex_lock(&linecard->state_lock); -- err = devlink_nl_linecard_fill(msg, devlink, linecard, -- DEVLINK_CMD_LINECARD_NEW, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI, -- cb->extack); -- mutex_unlock(&linecard->state_lock); -- if (err) { -- mutex_unlock(&devlink->linecards_lock); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- mutex_unlock(&devlink->linecards_lock); -- devlink_put(devlink); -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static struct devlink_linecard_type * --devlink_linecard_type_lookup(struct devlink_linecard *linecard, -- const char *type) --{ -- struct devlink_linecard_type *linecard_type; -- int i; -- -- for (i = 0; i < linecard->types_count; i++) { -- linecard_type = &linecard->types[i]; -- if (!strcmp(type, linecard_type->type)) -- return linecard_type; -- } -- return NULL; --} -- --static int devlink_linecard_type_set(struct devlink_linecard *linecard, -- const char *type, -- struct netlink_ext_ack *extack) --{ -- const struct devlink_linecard_ops *ops = linecard->ops; -- struct devlink_linecard_type *linecard_type; -- int err; -- -- mutex_lock(&linecard->state_lock); -- if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) { -- NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned"); -- err = -EBUSY; -- goto out; -- } -- if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) { -- NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned"); -- err = -EBUSY; -- goto out; -- } -- -- linecard_type = devlink_linecard_type_lookup(linecard, type); -- if (!linecard_type) { -- NL_SET_ERR_MSG_MOD(extack, "Unsupported line card type provided"); -- err = -EINVAL; -- goto out; -- } -- -- if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED && -- linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) { -- NL_SET_ERR_MSG_MOD(extack, "Line card already provisioned"); -- err = -EBUSY; -- /* Check if the line card is provisioned in the same -- * way the user asks. In case it is, make the operation -- * to return success. -- */ -- if (ops->same_provision && -- ops->same_provision(linecard, linecard->priv, -- linecard_type->type, -- linecard_type->priv)) -- err = 0; -- goto out; -- } -- -- linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING; -- linecard->type = linecard_type->type; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); -- err = ops->provision(linecard, linecard->priv, linecard_type->type, -- linecard_type->priv, extack); -- if (err) { -- /* Provisioning failed. Assume the linecard is unprovisioned -- * for future operations. -- */ -- mutex_lock(&linecard->state_lock); -- linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -- linecard->type = NULL; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); -- } -- return err; -- --out: -- mutex_unlock(&linecard->state_lock); -- return err; --} -- --static int devlink_linecard_type_unset(struct devlink_linecard *linecard, -- struct netlink_ext_ack *extack) --{ -- int err; -- -- mutex_lock(&linecard->state_lock); -- if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) { -- NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned"); -- err = -EBUSY; -- goto out; -- } -- if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) { -- NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned"); -- err = -EBUSY; -- goto out; -- } -- if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) { -- linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -- linecard->type = NULL; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- err = 0; -- goto out; -- } -- -- if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) { -- NL_SET_ERR_MSG_MOD(extack, "Line card is not provisioned"); -- err = 0; -- goto out; -- } -- linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); -- err = linecard->ops->unprovision(linecard, linecard->priv, -- extack); -- if (err) { -- /* Unprovisioning failed. Assume the linecard is unprovisioned -- * for future operations. -- */ -- mutex_lock(&linecard->state_lock); -- linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -- linecard->type = NULL; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); -- } -- return err; -- --out: -- mutex_unlock(&linecard->state_lock); -- return err; --} -- --static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_linecard *linecard = info->user_ptr[1]; -- struct netlink_ext_ack *extack = info->extack; -- int err; -- -- if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) { -- const char *type; -- -- type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]); -- if (strcmp(type, "")) { -- err = devlink_linecard_type_set(linecard, type, extack); -- if (err) -- return err; -- } else { -- err = devlink_linecard_type_unset(linecard, extack); -- if (err) -- return err; -- } -- } -- -- return 0; --} -- --static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink, -- struct devlink_sb *devlink_sb, -- enum devlink_command cmd, u32 portid, -- u32 seq, int flags) --{ -- void *hdr; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size)) -- goto nla_put_failure; -- if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT, -- devlink_sb->ingress_pools_count)) -- goto nla_put_failure; -- if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT, -- devlink_sb->egress_pools_count)) -- goto nla_put_failure; -- if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT, -- devlink_sb->ingress_tc_count)) -- goto nla_put_failure; -- if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT, -- devlink_sb->egress_tc_count)) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_sb *devlink_sb; -- struct sk_buff *msg; -- int err; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_sb_fill(msg, devlink, devlink_sb, -- DEVLINK_CMD_SB_NEW, -- info->snd_portid, info->snd_seq, 0); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- struct devlink_sb *devlink_sb; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- devl_lock(devlink); -- list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_sb_fill(msg, devlink, devlink_sb, -- DEVLINK_CMD_SB_NEW, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI); -- if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- devl_unlock(devlink); -- devlink_put(devlink); -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink, -- struct devlink_sb *devlink_sb, -- u16 pool_index, enum devlink_command cmd, -- u32 portid, u32 seq, int flags) --{ -- struct devlink_sb_pool_info pool_info; -- void *hdr; -- int err; -- -- err = devlink->ops->sb_pool_get(devlink, devlink_sb->index, -- pool_index, &pool_info); -- if (err) -- return err; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) -- goto nla_put_failure; -- if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) -- goto nla_put_failure; -- if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size)) -- goto nla_put_failure; -- if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE, -- pool_info.threshold_type)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE, -- pool_info.cell_size)) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_sb *devlink_sb; -- struct sk_buff *msg; -- u16 pool_index; -- int err; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -- &pool_index); -- if (err) -- return err; -- -- if (!devlink->ops->sb_pool_get) -- return -EOPNOTSUPP; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index, -- DEVLINK_CMD_SB_POOL_NEW, -- info->snd_portid, info->snd_seq, 0); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, -- struct devlink *devlink, -- struct devlink_sb *devlink_sb, -- u32 portid, u32 seq) --{ -- u16 pool_count = devlink_sb_pool_count(devlink_sb); -- u16 pool_index; -- int err; -- -- for (pool_index = 0; pool_index < pool_count; pool_index++) { -- if (*p_idx < start) { -- (*p_idx)++; -- continue; -- } -- err = devlink_nl_sb_pool_fill(msg, devlink, -- devlink_sb, -- pool_index, -- DEVLINK_CMD_SB_POOL_NEW, -- portid, seq, NLM_F_MULTI); -- if (err) -- return err; -- (*p_idx)++; -- } -- return 0; --} -- --static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- struct devlink_sb *devlink_sb; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err = 0; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- if (!devlink->ops->sb_pool_get) -- goto retry; -- -- devl_lock(devlink); -- list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -- err = __sb_pool_get_dumpit(msg, start, &idx, devlink, -- devlink_sb, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq); -- if (err == -EOPNOTSUPP) { -- err = 0; -- } else if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- } -- devl_unlock(devlink); --retry: -- devlink_put(devlink); -- } --out: -- if (err != -EMSGSIZE) -- return err; -- -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index, -- u16 pool_index, u32 size, -- enum devlink_sb_threshold_type threshold_type, -- struct netlink_ext_ack *extack) -- --{ -- const struct devlink_ops *ops = devlink->ops; -- -- if (ops->sb_pool_set) -- return ops->sb_pool_set(devlink, sb_index, pool_index, -- size, threshold_type, extack); -- return -EOPNOTSUPP; --} -- --static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- enum devlink_sb_threshold_type threshold_type; -- struct devlink_sb *devlink_sb; -- u16 pool_index; -- u32 size; -- int err; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -- &pool_index); -- if (err) -- return err; -- -- err = devlink_sb_th_type_get_from_info(info, &threshold_type); -- if (err) -- return err; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE)) -- return -EINVAL; -- -- size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]); -- return devlink_sb_pool_set(devlink, devlink_sb->index, -- pool_index, size, threshold_type, -- info->extack); --} -- --static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg, -- struct devlink *devlink, -- struct devlink_port *devlink_port, -- struct devlink_sb *devlink_sb, -- u16 pool_index, -- enum devlink_command cmd, -- u32 portid, u32 seq, int flags) --{ -- const struct devlink_ops *ops = devlink->ops; -- u32 threshold; -- void *hdr; -- int err; -- -- err = ops->sb_port_pool_get(devlink_port, devlink_sb->index, -- pool_index, &threshold); -- if (err) -- return err; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) -- goto nla_put_failure; -- if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) -- goto nla_put_failure; -- -- if (ops->sb_occ_port_pool_get) { -- u32 cur; -- u32 max; -- -- err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index, -- pool_index, &cur, &max); -- if (err && err != -EOPNOTSUPP) -- goto sb_occ_get_failure; -- if (!err) { -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) -- goto nla_put_failure; -- } -- } -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- err = -EMSGSIZE; --sb_occ_get_failure: -- genlmsg_cancel(msg, hdr); -- return err; --} -- --static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port = info->user_ptr[1]; -- struct devlink *devlink = devlink_port->devlink; -- struct devlink_sb *devlink_sb; -- struct sk_buff *msg; -- u16 pool_index; -- int err; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -- &pool_index); -- if (err) -- return err; -- -- if (!devlink->ops->sb_port_pool_get) -- return -EOPNOTSUPP; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port, -- devlink_sb, pool_index, -- DEVLINK_CMD_SB_PORT_POOL_NEW, -- info->snd_portid, info->snd_seq, 0); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, -- struct devlink *devlink, -- struct devlink_sb *devlink_sb, -- u32 portid, u32 seq) --{ -- struct devlink_port *devlink_port; -- u16 pool_count = devlink_sb_pool_count(devlink_sb); -- u16 pool_index; -- int err; -- -- list_for_each_entry(devlink_port, &devlink->port_list, list) { -- for (pool_index = 0; pool_index < pool_count; pool_index++) { -- if (*p_idx < start) { -- (*p_idx)++; -- continue; -- } -- err = devlink_nl_sb_port_pool_fill(msg, devlink, -- devlink_port, -- devlink_sb, -- pool_index, -- DEVLINK_CMD_SB_PORT_POOL_NEW, -- portid, seq, -- NLM_F_MULTI); -- if (err) -- return err; -- (*p_idx)++; -- } -- } -- return 0; --} -- --static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- struct devlink_sb *devlink_sb; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err = 0; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- if (!devlink->ops->sb_port_pool_get) -- goto retry; -- -- devl_lock(devlink); -- list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -- err = __sb_port_pool_get_dumpit(msg, start, &idx, -- devlink, devlink_sb, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq); -- if (err == -EOPNOTSUPP) { -- err = 0; -- } else if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- } -- devl_unlock(devlink); --retry: -- devlink_put(devlink); -- } --out: -- if (err != -EMSGSIZE) -- return err; -- -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_sb_port_pool_set(struct devlink_port *devlink_port, -- unsigned int sb_index, u16 pool_index, -- u32 threshold, -- struct netlink_ext_ack *extack) -- --{ -- const struct devlink_ops *ops = devlink_port->devlink->ops; -- -- if (ops->sb_port_pool_set) -- return ops->sb_port_pool_set(devlink_port, sb_index, -- pool_index, threshold, extack); -- return -EOPNOTSUPP; --} -- --static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port = info->user_ptr[1]; -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_sb *devlink_sb; -- u16 pool_index; -- u32 threshold; -- int err; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -- &pool_index); -- if (err) -- return err; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD)) -- return -EINVAL; -- -- threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); -- return devlink_sb_port_pool_set(devlink_port, devlink_sb->index, -- pool_index, threshold, info->extack); --} -- --static int --devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink, -- struct devlink_port *devlink_port, -- struct devlink_sb *devlink_sb, u16 tc_index, -- enum devlink_sb_pool_type pool_type, -- enum devlink_command cmd, -- u32 portid, u32 seq, int flags) --{ -- const struct devlink_ops *ops = devlink->ops; -- u16 pool_index; -- u32 threshold; -- void *hdr; -- int err; -- -- err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index, -- tc_index, pool_type, -- &pool_index, &threshold); -- if (err) -- return err; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) -- goto nla_put_failure; -- if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index)) -- goto nla_put_failure; -- if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type)) -- goto nla_put_failure; -- if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) -- goto nla_put_failure; -- -- if (ops->sb_occ_tc_port_bind_get) { -- u32 cur; -- u32 max; -- -- err = ops->sb_occ_tc_port_bind_get(devlink_port, -- devlink_sb->index, -- tc_index, pool_type, -- &cur, &max); -- if (err && err != -EOPNOTSUPP) -- return err; -- if (!err) { -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) -- goto nla_put_failure; -- if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) -- goto nla_put_failure; -- } -- } -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port = info->user_ptr[1]; -- struct devlink *devlink = devlink_port->devlink; -- struct devlink_sb *devlink_sb; -- struct sk_buff *msg; -- enum devlink_sb_pool_type pool_type; -- u16 tc_index; -- int err; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- err = devlink_sb_pool_type_get_from_info(info, &pool_type); -- if (err) -- return err; -- -- err = devlink_sb_tc_index_get_from_info(devlink_sb, info, -- pool_type, &tc_index); -- if (err) -- return err; -- -- if (!devlink->ops->sb_tc_pool_bind_get) -- return -EOPNOTSUPP; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port, -- devlink_sb, tc_index, pool_type, -- DEVLINK_CMD_SB_TC_POOL_BIND_NEW, -- info->snd_portid, -- info->snd_seq, 0); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, -- int start, int *p_idx, -- struct devlink *devlink, -- struct devlink_sb *devlink_sb, -- u32 portid, u32 seq) --{ -- struct devlink_port *devlink_port; -- u16 tc_index; -- int err; -- -- list_for_each_entry(devlink_port, &devlink->port_list, list) { -- for (tc_index = 0; -- tc_index < devlink_sb->ingress_tc_count; tc_index++) { -- if (*p_idx < start) { -- (*p_idx)++; -- continue; -- } -- err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, -- devlink_port, -- devlink_sb, -- tc_index, -- DEVLINK_SB_POOL_TYPE_INGRESS, -- DEVLINK_CMD_SB_TC_POOL_BIND_NEW, -- portid, seq, -- NLM_F_MULTI); -- if (err) -- return err; -- (*p_idx)++; -- } -- for (tc_index = 0; -- tc_index < devlink_sb->egress_tc_count; tc_index++) { -- if (*p_idx < start) { -- (*p_idx)++; -- continue; -- } -- err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, -- devlink_port, -- devlink_sb, -- tc_index, -- DEVLINK_SB_POOL_TYPE_EGRESS, -- DEVLINK_CMD_SB_TC_POOL_BIND_NEW, -- portid, seq, -- NLM_F_MULTI); -- if (err) -- return err; -- (*p_idx)++; -- } -- } -- return 0; --} -- --static int --devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- struct devlink_sb *devlink_sb; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err = 0; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- if (!devlink->ops->sb_tc_pool_bind_get) -- goto retry; -- -- devl_lock(devlink); -- list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -- err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx, -- devlink, -- devlink_sb, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq); -- if (err == -EOPNOTSUPP) { -- err = 0; -- } else if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- } -- devl_unlock(devlink); --retry: -- devlink_put(devlink); -- } --out: -- if (err != -EMSGSIZE) -- return err; -- -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, -- unsigned int sb_index, u16 tc_index, -- enum devlink_sb_pool_type pool_type, -- u16 pool_index, u32 threshold, -- struct netlink_ext_ack *extack) -- --{ -- const struct devlink_ops *ops = devlink_port->devlink->ops; -- -- if (ops->sb_tc_pool_bind_set) -- return ops->sb_tc_pool_bind_set(devlink_port, sb_index, -- tc_index, pool_type, -- pool_index, threshold, extack); -- return -EOPNOTSUPP; --} -- --static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_port *devlink_port = info->user_ptr[1]; -- struct devlink *devlink = info->user_ptr[0]; -- enum devlink_sb_pool_type pool_type; -- struct devlink_sb *devlink_sb; -- u16 tc_index; -- u16 pool_index; -- u32 threshold; -- int err; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- err = devlink_sb_pool_type_get_from_info(info, &pool_type); -- if (err) -- return err; -- -- err = devlink_sb_tc_index_get_from_info(devlink_sb, info, -- pool_type, &tc_index); -- if (err) -- return err; -- -- err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -- &pool_index); -- if (err) -- return err; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD)) -- return -EINVAL; -- -- threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); -- return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index, -- tc_index, pool_type, -- pool_index, threshold, info->extack); --} -- --static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- const struct devlink_ops *ops = devlink->ops; -- struct devlink_sb *devlink_sb; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- if (ops->sb_occ_snapshot) -- return ops->sb_occ_snapshot(devlink, devlink_sb->index); -- return -EOPNOTSUPP; --} -- --static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- const struct devlink_ops *ops = devlink->ops; -- struct devlink_sb *devlink_sb; -- -- devlink_sb = devlink_sb_get_from_info(devlink, info); -- if (IS_ERR(devlink_sb)) -- return PTR_ERR(devlink_sb); -- -- if (ops->sb_occ_max_clear) -- return ops->sb_occ_max_clear(devlink, devlink_sb->index); -- return -EOPNOTSUPP; --} -- --static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, -- enum devlink_command cmd, u32 portid, -- u32 seq, int flags) --{ -- const struct devlink_ops *ops = devlink->ops; -- enum devlink_eswitch_encap_mode encap_mode; -- u8 inline_mode; -- void *hdr; -- int err = 0; -- u16 mode; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- err = devlink_nl_put_handle(msg, devlink); -- if (err) -- goto nla_put_failure; -- -- if (ops->eswitch_mode_get) { -- err = ops->eswitch_mode_get(devlink, &mode); -- if (err) -- goto nla_put_failure; -- err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); -- if (err) -- goto nla_put_failure; -- } -- -- if (ops->eswitch_inline_mode_get) { -- err = ops->eswitch_inline_mode_get(devlink, &inline_mode); -- if (err) -- goto nla_put_failure; -- err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, -- inline_mode); -- if (err) -- goto nla_put_failure; -- } -- -- if (ops->eswitch_encap_mode_get) { -- err = ops->eswitch_encap_mode_get(devlink, &encap_mode); -- if (err) -- goto nla_put_failure; -- err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); -- if (err) -- goto nla_put_failure; -- } -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return err; --} -- --static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct sk_buff *msg; -- int err; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, -- info->snd_portid, info->snd_seq, 0); -- -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode, -- struct netlink_ext_ack *extack) --{ -- struct devlink_rate *devlink_rate; -- -- list_for_each_entry(devlink_rate, &devlink->rate_list, list) -- if (devlink_rate_is_node(devlink_rate)) { -- NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists."); -- return -EBUSY; -- } -- return 0; --} -- --static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- const struct devlink_ops *ops = devlink->ops; -- enum devlink_eswitch_encap_mode encap_mode; -- u8 inline_mode; -- int err = 0; -- u16 mode; -- -- if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { -- if (!ops->eswitch_mode_set) -- return -EOPNOTSUPP; -- mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); -- err = devlink_rate_nodes_check(devlink, mode, info->extack); -- if (err) -- return err; -- err = ops->eswitch_mode_set(devlink, mode, info->extack); -- if (err) -- return err; -- } -- -- if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { -- if (!ops->eswitch_inline_mode_set) -- return -EOPNOTSUPP; -- inline_mode = nla_get_u8( -- info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); -- err = ops->eswitch_inline_mode_set(devlink, inline_mode, -- info->extack); -- if (err) -- return err; -- } -- -- if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { -- if (!ops->eswitch_encap_mode_set) -- return -EOPNOTSUPP; -- encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); -- err = ops->eswitch_encap_mode_set(devlink, encap_mode, -- info->extack); -- if (err) -- return err; -- } -- -- return 0; --} -- --int devlink_dpipe_match_put(struct sk_buff *skb, -- struct devlink_dpipe_match *match) --{ -- struct devlink_dpipe_header *header = match->header; -- struct devlink_dpipe_field *field = &header->fields[match->field_id]; -- struct nlattr *match_attr; -- -- match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH); -- if (!match_attr) -- return -EMSGSIZE; -- -- if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || -- nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) -- goto nla_put_failure; -- -- nla_nest_end(skb, match_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(skb, match_attr); -- return -EMSGSIZE; --} --EXPORT_SYMBOL_GPL(devlink_dpipe_match_put); -- --static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table, -- struct sk_buff *skb) --{ -- struct nlattr *matches_attr; -- -- matches_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_DPIPE_TABLE_MATCHES); -- if (!matches_attr) -- return -EMSGSIZE; -- -- if (table->table_ops->matches_dump(table->priv, skb)) -- goto nla_put_failure; -- -- nla_nest_end(skb, matches_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(skb, matches_attr); -- return -EMSGSIZE; --} -- --int devlink_dpipe_action_put(struct sk_buff *skb, -- struct devlink_dpipe_action *action) --{ -- struct devlink_dpipe_header *header = action->header; -- struct devlink_dpipe_field *field = &header->fields[action->field_id]; -- struct nlattr *action_attr; -- -- action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION); -- if (!action_attr) -- return -EMSGSIZE; -- -- if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || -- nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) -- goto nla_put_failure; -- -- nla_nest_end(skb, action_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(skb, action_attr); -- return -EMSGSIZE; --} --EXPORT_SYMBOL_GPL(devlink_dpipe_action_put); -- --static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table, -- struct sk_buff *skb) --{ -- struct nlattr *actions_attr; -- -- actions_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_DPIPE_TABLE_ACTIONS); -- if (!actions_attr) -- return -EMSGSIZE; -- -- if (table->table_ops->actions_dump(table->priv, skb)) -- goto nla_put_failure; -- -- nla_nest_end(skb, actions_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(skb, actions_attr); -- return -EMSGSIZE; --} -- --static int devlink_dpipe_table_put(struct sk_buff *skb, -- struct devlink_dpipe_table *table) --{ -- struct nlattr *table_attr; -- u64 table_size; -- -- table_size = table->table_ops->size_get(table->priv); -- table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE); -- if (!table_attr) -- return -EMSGSIZE; -- -- if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) || -- nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size, -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, -- table->counters_enabled)) -- goto nla_put_failure; -- -- if (table->resource_valid) { -- if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID, -- table->resource_id, DEVLINK_ATTR_PAD) || -- nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS, -- table->resource_units, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- } -- if (devlink_dpipe_matches_put(table, skb)) -- goto nla_put_failure; -- -- if (devlink_dpipe_actions_put(table, skb)) -- goto nla_put_failure; -- -- nla_nest_end(skb, table_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(skb, table_attr); -- return -EMSGSIZE; --} -- --static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb, -- struct genl_info *info) --{ -- int err; -- -- if (*pskb) { -- err = genlmsg_reply(*pskb, info); -- if (err) -- return err; -- } -- *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!*pskb) -- return -ENOMEM; -- return 0; --} -- --static int devlink_dpipe_tables_fill(struct genl_info *info, -- enum devlink_command cmd, int flags, -- struct list_head *dpipe_tables, -- const char *table_name) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_dpipe_table *table; -- struct nlattr *tables_attr; -- struct sk_buff *skb = NULL; -- struct nlmsghdr *nlh; -- bool incomplete; -- void *hdr; -- int i; -- int err; -- -- table = list_first_entry(dpipe_tables, -- struct devlink_dpipe_table, list); --start_again: -- err = devlink_dpipe_send_and_alloc_skb(&skb, info); -- if (err) -- return err; -- -- hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, -- &devlink_nl_family, NLM_F_MULTI, cmd); -- if (!hdr) { -- nlmsg_free(skb); -- return -EMSGSIZE; -- } -- -- if (devlink_nl_put_handle(skb, devlink)) -- goto nla_put_failure; -- tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES); -- if (!tables_attr) -- goto nla_put_failure; -- -- i = 0; -- incomplete = false; -- list_for_each_entry_from(table, dpipe_tables, list) { -- if (!table_name) { -- err = devlink_dpipe_table_put(skb, table); -- if (err) { -- if (!i) -- goto err_table_put; -- incomplete = true; -- break; -- } -- } else { -- if (!strcmp(table->name, table_name)) { -- err = devlink_dpipe_table_put(skb, table); -- if (err) -- break; -- } -- } -- i++; -- } -- -- nla_nest_end(skb, tables_attr); -- genlmsg_end(skb, hdr); -- if (incomplete) -- goto start_again; -- --send_done: -- nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, -- NLMSG_DONE, 0, flags | NLM_F_MULTI); -- if (!nlh) { -- err = devlink_dpipe_send_and_alloc_skb(&skb, info); -- if (err) -- return err; -- goto send_done; -- } -- -- return genlmsg_reply(skb, info); -- --nla_put_failure: -- err = -EMSGSIZE; --err_table_put: -- nlmsg_free(skb); -- return err; --} -- --static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- const char *table_name = NULL; -- -- if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) -- table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); -- -- return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0, -- &devlink->dpipe_table_list, -- table_name); --} -- --static int devlink_dpipe_value_put(struct sk_buff *skb, -- struct devlink_dpipe_value *value) --{ -- if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE, -- value->value_size, value->value)) -- return -EMSGSIZE; -- if (value->mask) -- if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK, -- value->value_size, value->mask)) -- return -EMSGSIZE; -- if (value->mapping_valid) -- if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING, -- value->mapping_value)) -- return -EMSGSIZE; -- return 0; --} -- --static int devlink_dpipe_action_value_put(struct sk_buff *skb, -- struct devlink_dpipe_value *value) --{ -- if (!value->action) -- return -EINVAL; -- if (devlink_dpipe_action_put(skb, value->action)) -- return -EMSGSIZE; -- if (devlink_dpipe_value_put(skb, value)) -- return -EMSGSIZE; -- return 0; --} -- --static int devlink_dpipe_action_values_put(struct sk_buff *skb, -- struct devlink_dpipe_value *values, -- unsigned int values_count) --{ -- struct nlattr *action_attr; -- int i; -- int err; -- -- for (i = 0; i < values_count; i++) { -- action_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_DPIPE_ACTION_VALUE); -- if (!action_attr) -- return -EMSGSIZE; -- err = devlink_dpipe_action_value_put(skb, &values[i]); -- if (err) -- goto err_action_value_put; -- nla_nest_end(skb, action_attr); -- } -- return 0; -- --err_action_value_put: -- nla_nest_cancel(skb, action_attr); -- return err; --} -- --static int devlink_dpipe_match_value_put(struct sk_buff *skb, -- struct devlink_dpipe_value *value) --{ -- if (!value->match) -- return -EINVAL; -- if (devlink_dpipe_match_put(skb, value->match)) -- return -EMSGSIZE; -- if (devlink_dpipe_value_put(skb, value)) -- return -EMSGSIZE; -- return 0; --} -- --static int devlink_dpipe_match_values_put(struct sk_buff *skb, -- struct devlink_dpipe_value *values, -- unsigned int values_count) --{ -- struct nlattr *match_attr; -- int i; -- int err; -- -- for (i = 0; i < values_count; i++) { -- match_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_DPIPE_MATCH_VALUE); -- if (!match_attr) -- return -EMSGSIZE; -- err = devlink_dpipe_match_value_put(skb, &values[i]); -- if (err) -- goto err_match_value_put; -- nla_nest_end(skb, match_attr); -- } -- return 0; -- --err_match_value_put: -- nla_nest_cancel(skb, match_attr); -- return err; --} -- --static int devlink_dpipe_entry_put(struct sk_buff *skb, -- struct devlink_dpipe_entry *entry) --{ -- struct nlattr *entry_attr, *matches_attr, *actions_attr; -- int err; -- -- entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY); -- if (!entry_attr) -- return -EMSGSIZE; -- -- if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index, -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- if (entry->counter_valid) -- if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, -- entry->counter, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- matches_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES); -- if (!matches_attr) -- goto nla_put_failure; -- -- err = devlink_dpipe_match_values_put(skb, entry->match_values, -- entry->match_values_count); -- if (err) { -- nla_nest_cancel(skb, matches_attr); -- goto err_match_values_put; -- } -- nla_nest_end(skb, matches_attr); -- -- actions_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES); -- if (!actions_attr) -- goto nla_put_failure; -- -- err = devlink_dpipe_action_values_put(skb, entry->action_values, -- entry->action_values_count); -- if (err) { -- nla_nest_cancel(skb, actions_attr); -- goto err_action_values_put; -- } -- nla_nest_end(skb, actions_attr); -- -- nla_nest_end(skb, entry_attr); -- return 0; -- --nla_put_failure: -- err = -EMSGSIZE; --err_match_values_put: --err_action_values_put: -- nla_nest_cancel(skb, entry_attr); -- return err; --} -- --static struct devlink_dpipe_table * --devlink_dpipe_table_find(struct list_head *dpipe_tables, -- const char *table_name, struct devlink *devlink) --{ -- struct devlink_dpipe_table *table; -- list_for_each_entry_rcu(table, dpipe_tables, list, -- lockdep_is_held(&devlink->lock)) { -- if (!strcmp(table->name, table_name)) -- return table; -- } -- return NULL; --} -- --int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx) --{ -- struct devlink *devlink; -- int err; -- -- err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb, -- dump_ctx->info); -- if (err) -- return err; -- -- dump_ctx->hdr = genlmsg_put(dump_ctx->skb, -- dump_ctx->info->snd_portid, -- dump_ctx->info->snd_seq, -- &devlink_nl_family, NLM_F_MULTI, -- dump_ctx->cmd); -- if (!dump_ctx->hdr) -- goto nla_put_failure; -- -- devlink = dump_ctx->info->user_ptr[0]; -- if (devlink_nl_put_handle(dump_ctx->skb, devlink)) -- goto nla_put_failure; -- dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb, -- DEVLINK_ATTR_DPIPE_ENTRIES); -- if (!dump_ctx->nest) -- goto nla_put_failure; -- return 0; -- --nla_put_failure: -- nlmsg_free(dump_ctx->skb); -- return -EMSGSIZE; --} --EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare); -- --int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx, -- struct devlink_dpipe_entry *entry) --{ -- return devlink_dpipe_entry_put(dump_ctx->skb, entry); --} --EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append); -- --int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx) --{ -- nla_nest_end(dump_ctx->skb, dump_ctx->nest); -- genlmsg_end(dump_ctx->skb, dump_ctx->hdr); -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close); -- --void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry) -- --{ -- unsigned int value_count, value_index; -- struct devlink_dpipe_value *value; -- -- value = entry->action_values; -- value_count = entry->action_values_count; -- for (value_index = 0; value_index < value_count; value_index++) { -- kfree(value[value_index].value); -- kfree(value[value_index].mask); -- } -- -- value = entry->match_values; -- value_count = entry->match_values_count; -- for (value_index = 0; value_index < value_count; value_index++) { -- kfree(value[value_index].value); -- kfree(value[value_index].mask); -- } --} --EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear); -- --static int devlink_dpipe_entries_fill(struct genl_info *info, -- enum devlink_command cmd, int flags, -- struct devlink_dpipe_table *table) --{ -- struct devlink_dpipe_dump_ctx dump_ctx; -- struct nlmsghdr *nlh; -- int err; -- -- dump_ctx.skb = NULL; -- dump_ctx.cmd = cmd; -- dump_ctx.info = info; -- -- err = table->table_ops->entries_dump(table->priv, -- table->counters_enabled, -- &dump_ctx); -- if (err) -- return err; -- --send_done: -- nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq, -- NLMSG_DONE, 0, flags | NLM_F_MULTI); -- if (!nlh) { -- err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info); -- if (err) -- return err; -- goto send_done; -- } -- return genlmsg_reply(dump_ctx.skb, info); --} -- --static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_dpipe_table *table; -- const char *table_name; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME)) -- return -EINVAL; -- -- table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); -- table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -- table_name, devlink); -- if (!table) -- return -EINVAL; -- -- if (!table->table_ops->entries_dump) -- return -EINVAL; -- -- return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET, -- 0, table); --} -- --static int devlink_dpipe_fields_put(struct sk_buff *skb, -- const struct devlink_dpipe_header *header) --{ -- struct devlink_dpipe_field *field; -- struct nlattr *field_attr; -- int i; -- -- for (i = 0; i < header->fields_count; i++) { -- field = &header->fields[i]; -- field_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_DPIPE_FIELD); -- if (!field_attr) -- return -EMSGSIZE; -- if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type)) -- goto nla_put_failure; -- nla_nest_end(skb, field_attr); -- } -- return 0; -- --nla_put_failure: -- nla_nest_cancel(skb, field_attr); -- return -EMSGSIZE; --} -- --static int devlink_dpipe_header_put(struct sk_buff *skb, -- struct devlink_dpipe_header *header) --{ -- struct nlattr *fields_attr, *header_attr; -- int err; -- -- header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER); -- if (!header_attr) -- return -EMSGSIZE; -- -- if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) || -- nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || -- nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) -- goto nla_put_failure; -- -- fields_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_DPIPE_HEADER_FIELDS); -- if (!fields_attr) -- goto nla_put_failure; -- -- err = devlink_dpipe_fields_put(skb, header); -- if (err) { -- nla_nest_cancel(skb, fields_attr); -- goto nla_put_failure; -- } -- nla_nest_end(skb, fields_attr); -- nla_nest_end(skb, header_attr); -- return 0; -- --nla_put_failure: -- err = -EMSGSIZE; -- nla_nest_cancel(skb, header_attr); -- return err; --} -- --static int devlink_dpipe_headers_fill(struct genl_info *info, -- enum devlink_command cmd, int flags, -- struct devlink_dpipe_headers * -- dpipe_headers) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct nlattr *headers_attr; -- struct sk_buff *skb = NULL; -- struct nlmsghdr *nlh; -- void *hdr; -- int i, j; -- int err; -- -- i = 0; --start_again: -- err = devlink_dpipe_send_and_alloc_skb(&skb, info); -- if (err) -- return err; -- -- hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, -- &devlink_nl_family, NLM_F_MULTI, cmd); -- if (!hdr) { -- nlmsg_free(skb); -- return -EMSGSIZE; -- } -- -- if (devlink_nl_put_handle(skb, devlink)) -- goto nla_put_failure; -- headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS); -- if (!headers_attr) -- goto nla_put_failure; -- -- j = 0; -- for (; i < dpipe_headers->headers_count; i++) { -- err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]); -- if (err) { -- if (!j) -- goto err_table_put; -- break; -- } -- j++; -- } -- nla_nest_end(skb, headers_attr); -- genlmsg_end(skb, hdr); -- if (i != dpipe_headers->headers_count) -- goto start_again; -- --send_done: -- nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, -- NLMSG_DONE, 0, flags | NLM_F_MULTI); -- if (!nlh) { -- err = devlink_dpipe_send_and_alloc_skb(&skb, info); -- if (err) -- return err; -- goto send_done; -- } -- return genlmsg_reply(skb, info); -- --nla_put_failure: -- err = -EMSGSIZE; --err_table_put: -- nlmsg_free(skb); -- return err; --} -- --static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- -- if (!devlink->dpipe_headers) -- return -EOPNOTSUPP; -- return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET, -- 0, devlink->dpipe_headers); --} -- --static int devlink_dpipe_table_counters_set(struct devlink *devlink, -- const char *table_name, -- bool enable) --{ -- struct devlink_dpipe_table *table; -- -- table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -- table_name, devlink); -- if (!table) -- return -EINVAL; -- -- if (table->counter_control_extern) -- return -EOPNOTSUPP; -- -- if (!(table->counters_enabled ^ enable)) -- return 0; -- -- table->counters_enabled = enable; -- if (table->table_ops->counters_set_update) -- table->table_ops->counters_set_update(table->priv, enable); -- return 0; --} -- --static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- const char *table_name; -- bool counters_enable; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) || -- GENL_REQ_ATTR_CHECK(info, -- DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED)) -- return -EINVAL; -- -- table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); -- counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]); -- -- return devlink_dpipe_table_counters_set(devlink, table_name, -- counters_enable); --} -- --static struct devlink_resource * --devlink_resource_find(struct devlink *devlink, -- struct devlink_resource *resource, u64 resource_id) --{ -- struct list_head *resource_list; -- -- if (resource) -- resource_list = &resource->resource_list; -- else -- resource_list = &devlink->resource_list; -- -- list_for_each_entry(resource, resource_list, list) { -- struct devlink_resource *child_resource; -- -- if (resource->id == resource_id) -- return resource; -- -- child_resource = devlink_resource_find(devlink, resource, -- resource_id); -- if (child_resource) -- return child_resource; -- } -- return NULL; --} -- --static void --devlink_resource_validate_children(struct devlink_resource *resource) --{ -- struct devlink_resource *child_resource; -- bool size_valid = true; -- u64 parts_size = 0; -- -- if (list_empty(&resource->resource_list)) -- goto out; -- -- list_for_each_entry(child_resource, &resource->resource_list, list) -- parts_size += child_resource->size_new; -- -- if (parts_size > resource->size_new) -- size_valid = false; --out: -- resource->size_valid = size_valid; --} -- --static int --devlink_resource_validate_size(struct devlink_resource *resource, u64 size, -- struct netlink_ext_ack *extack) --{ -- u64 reminder; -- int err = 0; -- -- if (size > resource->size_params.size_max) { -- NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum"); -- err = -EINVAL; -- } -- -- if (size < resource->size_params.size_min) { -- NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum"); -- err = -EINVAL; -- } -- -- div64_u64_rem(size, resource->size_params.size_granularity, &reminder); -- if (reminder) { -- NL_SET_ERR_MSG_MOD(extack, "Wrong granularity"); -- err = -EINVAL; -- } -- -- return err; --} -- --static int devlink_nl_cmd_resource_set(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_resource *resource; -- u64 resource_id; -- u64 size; -- int err; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) || -- GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE)) -- return -EINVAL; -- resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]); -- -- resource = devlink_resource_find(devlink, NULL, resource_id); -- if (!resource) -- return -EINVAL; -- -- size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]); -- err = devlink_resource_validate_size(resource, size, info->extack); -- if (err) -- return err; -- -- resource->size_new = size; -- devlink_resource_validate_children(resource); -- if (resource->parent) -- devlink_resource_validate_children(resource->parent); -- return 0; --} -- --static int --devlink_resource_size_params_put(struct devlink_resource *resource, -- struct sk_buff *skb) --{ -- struct devlink_resource_size_params *size_params; -- -- size_params = &resource->size_params; -- if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN, -- size_params->size_granularity, DEVLINK_ATTR_PAD) || -- nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX, -- size_params->size_max, DEVLINK_ATTR_PAD) || -- nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN, -- size_params->size_min, DEVLINK_ATTR_PAD) || -- nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit)) -- return -EMSGSIZE; -- return 0; --} -- --static int devlink_resource_occ_put(struct devlink_resource *resource, -- struct sk_buff *skb) --{ -- if (!resource->occ_get) -- return 0; -- return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC, -- resource->occ_get(resource->occ_get_priv), -- DEVLINK_ATTR_PAD); --} -- --static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb, -- struct devlink_resource *resource) --{ -- struct devlink_resource *child_resource; -- struct nlattr *child_resource_attr; -- struct nlattr *resource_attr; -- -- resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE); -- if (!resource_attr) -- return -EMSGSIZE; -- -- if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) || -- nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size, -- DEVLINK_ATTR_PAD) || -- nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id, -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- if (resource->size != resource->size_new) -- nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW, -- resource->size_new, DEVLINK_ATTR_PAD); -- if (devlink_resource_occ_put(resource, skb)) -- goto nla_put_failure; -- if (devlink_resource_size_params_put(resource, skb)) -- goto nla_put_failure; -- if (list_empty(&resource->resource_list)) -- goto out; -- -- if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID, -- resource->size_valid)) -- goto nla_put_failure; -- -- child_resource_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_RESOURCE_LIST); -- if (!child_resource_attr) -- goto nla_put_failure; -- -- list_for_each_entry(child_resource, &resource->resource_list, list) { -- if (devlink_resource_put(devlink, skb, child_resource)) -- goto resource_put_failure; -- } -- -- nla_nest_end(skb, child_resource_attr); --out: -- nla_nest_end(skb, resource_attr); -- return 0; -- --resource_put_failure: -- nla_nest_cancel(skb, child_resource_attr); --nla_put_failure: -- nla_nest_cancel(skb, resource_attr); -- return -EMSGSIZE; --} -- --static int devlink_resource_fill(struct genl_info *info, -- enum devlink_command cmd, int flags) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_resource *resource; -- struct nlattr *resources_attr; -- struct sk_buff *skb = NULL; -- struct nlmsghdr *nlh; -- bool incomplete; -- void *hdr; -- int i; -- int err; -- -- resource = list_first_entry(&devlink->resource_list, -- struct devlink_resource, list); --start_again: -- err = devlink_dpipe_send_and_alloc_skb(&skb, info); -- if (err) -- return err; -- -- hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, -- &devlink_nl_family, NLM_F_MULTI, cmd); -- if (!hdr) { -- nlmsg_free(skb); -- return -EMSGSIZE; -- } -- -- if (devlink_nl_put_handle(skb, devlink)) -- goto nla_put_failure; -- -- resources_attr = nla_nest_start_noflag(skb, -- DEVLINK_ATTR_RESOURCE_LIST); -- if (!resources_attr) -- goto nla_put_failure; -- -- incomplete = false; -- i = 0; -- list_for_each_entry_from(resource, &devlink->resource_list, list) { -- err = devlink_resource_put(devlink, skb, resource); -- if (err) { -- if (!i) -- goto err_resource_put; -- incomplete = true; -- break; -- } -- i++; -- } -- nla_nest_end(skb, resources_attr); -- genlmsg_end(skb, hdr); -- if (incomplete) -- goto start_again; --send_done: -- nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, -- NLMSG_DONE, 0, flags | NLM_F_MULTI); -- if (!nlh) { -- err = devlink_dpipe_send_and_alloc_skb(&skb, info); -- if (err) -- return err; -- goto send_done; -- } -- return genlmsg_reply(skb, info); -- --nla_put_failure: -- err = -EMSGSIZE; --err_resource_put: -- nlmsg_free(skb); -- return err; --} -- --static int devlink_nl_cmd_resource_dump(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- -- if (list_empty(&devlink->resource_list)) -- return -EOPNOTSUPP; -- -- return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); --} -- --static int --devlink_resources_validate(struct devlink *devlink, -- struct devlink_resource *resource, -- struct genl_info *info) --{ -- struct list_head *resource_list; -- int err = 0; -- -- if (resource) -- resource_list = &resource->resource_list; -- else -- resource_list = &devlink->resource_list; -- -- list_for_each_entry(resource, resource_list, list) { -- if (!resource->size_valid) -- return -EINVAL; -- err = devlink_resources_validate(devlink, resource, info); -- if (err) -- return err; -- } -- return err; --} -- --static struct net *devlink_netns_get(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID]; -- struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD]; -- struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID]; -- struct net *net; -- -- if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) { -- NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified"); -- return ERR_PTR(-EINVAL); -- } -- -- if (netns_pid_attr) { -- net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr)); -- } else if (netns_fd_attr) { -- net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr)); -- } else if (netns_id_attr) { -- net = get_net_ns_by_id(sock_net(skb->sk), -- nla_get_u32(netns_id_attr)); -- if (!net) -- net = ERR_PTR(-EINVAL); -- } else { -- WARN_ON(1); -- net = ERR_PTR(-EINVAL); -- } -- if (IS_ERR(net)) { -- NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace"); -- return ERR_PTR(-EINVAL); -- } -- if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { -- put_net(net); -- return ERR_PTR(-EPERM); -- } -- return net; --} -- --static void devlink_param_notify(struct devlink *devlink, -- unsigned int port_index, -- struct devlink_param_item *param_item, -- enum devlink_command cmd); -- --static void devlink_ns_change_notify(struct devlink *devlink, -- struct net *dest_net, struct net *curr_net, -- bool new) --{ -- struct devlink_param_item *param_item; -- enum devlink_command cmd; -- -- /* Userspace needs to be notified about devlink objects -- * removed from original and entering new network namespace. -- * The rest of the devlink objects are re-created during -- * reload process so the notifications are generated separatelly. -- */ -- -- if (!dest_net || net_eq(dest_net, curr_net)) -- return; -- -- if (new) -- devlink_notify(devlink, DEVLINK_CMD_NEW); -- -- cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL; -- list_for_each_entry(param_item, &devlink->param_list, list) -- devlink_param_notify(devlink, 0, param_item, cmd); -- -- if (!new) -- devlink_notify(devlink, DEVLINK_CMD_DEL); --} -- --static bool devlink_reload_supported(const struct devlink_ops *ops) --{ -- return ops->reload_down && ops->reload_up; --} -- --static void devlink_reload_failed_set(struct devlink *devlink, -- bool reload_failed) --{ -- if (devlink->reload_failed == reload_failed) -- return; -- devlink->reload_failed = reload_failed; -- devlink_notify(devlink, DEVLINK_CMD_NEW); --} -- --bool devlink_is_reload_failed(const struct devlink *devlink) --{ -- return devlink->reload_failed; --} --EXPORT_SYMBOL_GPL(devlink_is_reload_failed); -- --static void --__devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats, -- enum devlink_reload_limit limit, u32 actions_performed) --{ -- unsigned long actions = actions_performed; -- int stat_idx; -- int action; -- -- for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) { -- stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action; -- reload_stats[stat_idx]++; -- } -- devlink_notify(devlink, DEVLINK_CMD_NEW); --} -- --static void --devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit, -- u32 actions_performed) --{ -- __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit, -- actions_performed); --} -- --/** -- * devlink_remote_reload_actions_performed - Update devlink on reload actions -- * performed which are not a direct result of devlink reload call. -- * -- * This should be called by a driver after performing reload actions in case it was not -- * a result of devlink reload call. For example fw_activate was performed as a result -- * of devlink reload triggered fw_activate on another host. -- * The motivation for this function is to keep data on reload actions performed on this -- * function whether it was done due to direct devlink reload call or not. -- * -- * @devlink: devlink -- * @limit: reload limit -- * @actions_performed: bitmask of actions performed -- */ --void devlink_remote_reload_actions_performed(struct devlink *devlink, -- enum devlink_reload_limit limit, -- u32 actions_performed) --{ -- if (WARN_ON(!actions_performed || -- actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || -- actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) || -- limit > DEVLINK_RELOAD_LIMIT_MAX)) -- return; -- -- __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit, -- actions_performed); --} --EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed); -- --static int devlink_reload(struct devlink *devlink, struct net *dest_net, -- enum devlink_reload_action action, enum devlink_reload_limit limit, -- u32 *actions_performed, struct netlink_ext_ack *extack) --{ -- u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; -- struct net *curr_net; -- int err; -- -- memcpy(remote_reload_stats, devlink->stats.remote_reload_stats, -- sizeof(remote_reload_stats)); -- -- curr_net = devlink_net(devlink); -- devlink_ns_change_notify(devlink, dest_net, curr_net, false); -- err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack); -- if (err) -- return err; -- -- if (dest_net && !net_eq(dest_net, curr_net)) -- write_pnet(&devlink->_net, dest_net); -- -- err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack); -- devlink_reload_failed_set(devlink, !!err); -- if (err) -- return err; -- -- devlink_ns_change_notify(devlink, dest_net, curr_net, true); -- WARN_ON(!(*actions_performed & BIT(action))); -- /* Catch driver on updating the remote action within devlink reload */ -- WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats, -- sizeof(remote_reload_stats))); -- devlink_reload_stats_update(devlink, limit, *actions_performed); -- return 0; --} -- --static int --devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed, -- enum devlink_command cmd, struct genl_info *info) --{ -- struct sk_buff *msg; -- void *hdr; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd); -- if (!hdr) -- goto free_msg; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- -- if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed, -- actions_performed)) -- goto nla_put_failure; -- genlmsg_end(msg, hdr); -- -- return genlmsg_reply(msg, info); -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); --free_msg: -- nlmsg_free(msg); -- return -EMSGSIZE; --} -- --static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- enum devlink_reload_action action; -- enum devlink_reload_limit limit; -- struct net *dest_net = NULL; -- u32 actions_performed; -- int err; -- -- if (!(devlink->features & DEVLINK_F_RELOAD)) -- return -EOPNOTSUPP; -- -- err = devlink_resources_validate(devlink, NULL, info); -- if (err) { -- NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed"); -- return err; -- } -- -- if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION]) -- action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]); -- else -- action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT; -- -- if (!devlink_reload_action_is_supported(devlink, action)) { -- NL_SET_ERR_MSG_MOD(info->extack, -- "Requested reload action is not supported by the driver"); -- return -EOPNOTSUPP; -- } -- -- limit = DEVLINK_RELOAD_LIMIT_UNSPEC; -- if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) { -- struct nla_bitfield32 limits; -- u32 limits_selected; -- -- limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]); -- limits_selected = limits.value & limits.selector; -- if (!limits_selected) { -- NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected"); -- return -EINVAL; -- } -- for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++) -- if (limits_selected & BIT(limit)) -- break; -- /* UAPI enables multiselection, but currently it is not used */ -- if (limits_selected != BIT(limit)) { -- NL_SET_ERR_MSG_MOD(info->extack, -- "Multiselection of limit is not supported"); -- return -EOPNOTSUPP; -- } -- if (!devlink_reload_limit_is_supported(devlink, limit)) { -- NL_SET_ERR_MSG_MOD(info->extack, -- "Requested limit is not supported by the driver"); -- return -EOPNOTSUPP; -- } -- if (devlink_reload_combination_is_invalid(action, limit)) { -- NL_SET_ERR_MSG_MOD(info->extack, -- "Requested limit is invalid for this action"); -- return -EINVAL; -- } -- } -- if (info->attrs[DEVLINK_ATTR_NETNS_PID] || -- info->attrs[DEVLINK_ATTR_NETNS_FD] || -- info->attrs[DEVLINK_ATTR_NETNS_ID]) { -- dest_net = devlink_netns_get(skb, info); -- if (IS_ERR(dest_net)) -- return PTR_ERR(dest_net); -- } -- -- err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); -- -- if (dest_net) -- put_net(dest_net); -- -- if (err) -- return err; -- /* For backward compatibility generate reply only if attributes used by user */ -- if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) -- return 0; -- -- return devlink_nl_reload_actions_performed_snd(devlink, actions_performed, -- DEVLINK_CMD_RELOAD, info); --} -- --static int devlink_nl_flash_update_fill(struct sk_buff *msg, -- struct devlink *devlink, -- enum devlink_command cmd, -- struct devlink_flash_notify *params) --{ -- void *hdr; -- -- hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- -- if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS) -- goto out; -- -- if (params->status_msg && -- nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, -- params->status_msg)) -- goto nla_put_failure; -- if (params->component && -- nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, -- params->component)) -- goto nla_put_failure; -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, -- params->done, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, -- params->total, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, -- params->timeout, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- --out: -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static void __devlink_flash_update_notify(struct devlink *devlink, -- enum devlink_command cmd, -- struct devlink_flash_notify *params) --{ -- struct sk_buff *msg; -- int err; -- -- WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE && -- cmd != DEVLINK_CMD_FLASH_UPDATE_END && -- cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS); -- -- if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -- return; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_flash_update_fill(msg, devlink, cmd, params); -- if (err) -- goto out_free_msg; -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -- msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -- return; -- --out_free_msg: -- nlmsg_free(msg); --} -- --static void devlink_flash_update_begin_notify(struct devlink *devlink) --{ -- struct devlink_flash_notify params = {}; -- -- __devlink_flash_update_notify(devlink, -- DEVLINK_CMD_FLASH_UPDATE, -- ¶ms); --} -- --static void devlink_flash_update_end_notify(struct devlink *devlink) --{ -- struct devlink_flash_notify params = {}; -- -- __devlink_flash_update_notify(devlink, -- DEVLINK_CMD_FLASH_UPDATE_END, -- ¶ms); --} -- --void devlink_flash_update_status_notify(struct devlink *devlink, -- const char *status_msg, -- const char *component, -- unsigned long done, -- unsigned long total) --{ -- struct devlink_flash_notify params = { -- .status_msg = status_msg, -- .component = component, -- .done = done, -- .total = total, -- }; -- -- __devlink_flash_update_notify(devlink, -- DEVLINK_CMD_FLASH_UPDATE_STATUS, -- ¶ms); --} --EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); -- --void devlink_flash_update_timeout_notify(struct devlink *devlink, -- const char *status_msg, -- const char *component, -- unsigned long timeout) --{ -- struct devlink_flash_notify params = { -- .status_msg = status_msg, -- .component = component, -- .timeout = timeout, -- }; -- -- __devlink_flash_update_notify(devlink, -- DEVLINK_CMD_FLASH_UPDATE_STATUS, -- ¶ms); --} --EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); -- --struct devlink_info_req { -- struct sk_buff *msg; -- void (*version_cb)(const char *version_name, -- enum devlink_info_version_type version_type, -- void *version_cb_priv); -- void *version_cb_priv; --}; -- --struct devlink_flash_component_lookup_ctx { -- const char *lookup_name; -- bool lookup_name_found; --}; -- --static void --devlink_flash_component_lookup_cb(const char *version_name, -- enum devlink_info_version_type version_type, -- void *version_cb_priv) --{ -- struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv; -- -- if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT || -- lookup_ctx->lookup_name_found) -- return; -- -- lookup_ctx->lookup_name_found = -- !strcmp(lookup_ctx->lookup_name, version_name); --} -- --static int devlink_flash_component_get(struct devlink *devlink, -- struct nlattr *nla_component, -- const char **p_component, -- struct netlink_ext_ack *extack) --{ -- struct devlink_flash_component_lookup_ctx lookup_ctx = {}; -- struct devlink_info_req req = {}; -- const char *component; -- int ret; -- -- if (!nla_component) -- return 0; -- -- component = nla_data(nla_component); -- -- if (!devlink->ops->info_get) { -- NL_SET_ERR_MSG_ATTR(extack, nla_component, -- "component update is not supported by this device"); -- return -EOPNOTSUPP; -- } -- -- lookup_ctx.lookup_name = component; -- req.version_cb = devlink_flash_component_lookup_cb; -- req.version_cb_priv = &lookup_ctx; -- -- ret = devlink->ops->info_get(devlink, &req, NULL); -- if (ret) -- return ret; -- -- if (!lookup_ctx.lookup_name_found) { -- NL_SET_ERR_MSG_ATTR(extack, nla_component, -- "selected component is not supported by this device"); -- return -EINVAL; -- } -- *p_component = component; -- return 0; --} -- --static int devlink_nl_cmd_flash_update(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct nlattr *nla_overwrite_mask, *nla_file_name; -- struct devlink_flash_update_params params = {}; -- struct devlink *devlink = info->user_ptr[0]; -- const char *file_name; -- u32 supported_params; -- int ret; -- -- if (!devlink->ops->flash_update) -- return -EOPNOTSUPP; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME)) -- return -EINVAL; -- -- ret = devlink_flash_component_get(devlink, -- info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT], -- ¶ms.component, info->extack); -- if (ret) -- return ret; -- -- supported_params = devlink->ops->supported_flash_update_params; -- -- nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; -- if (nla_overwrite_mask) { -- struct nla_bitfield32 sections; -- -- if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { -- NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, -- "overwrite settings are not supported by this device"); -- return -EOPNOTSUPP; -- } -- sections = nla_get_bitfield32(nla_overwrite_mask); -- params.overwrite_mask = sections.value & sections.selector; -- } -- -- nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]; -- file_name = nla_data(nla_file_name); -- ret = request_firmware(¶ms.fw, file_name, devlink->dev); -- if (ret) { -- NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file"); -- return ret; -- } -- -- devlink_flash_update_begin_notify(devlink); -- ret = devlink->ops->flash_update(devlink, ¶ms, info->extack); -- devlink_flash_update_end_notify(devlink); -- -- release_firmware(params.fw); -- -- return ret; --} -- --static int --devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink, -- u32 portid, u32 seq, int flags, -- struct netlink_ext_ack *extack) --{ -- struct nlattr *selftests; -- void *hdr; -- int err; -- int i; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, -- DEVLINK_CMD_SELFTESTS_GET); -- if (!hdr) -- return -EMSGSIZE; -- -- err = -EMSGSIZE; -- if (devlink_nl_put_handle(msg, devlink)) -- goto err_cancel_msg; -- -- selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); -- if (!selftests) -- goto err_cancel_msg; -- -- for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; -- i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { -- if (devlink->ops->selftest_check(devlink, i, extack)) { -- err = nla_put_flag(msg, i); -- if (err) -- goto err_cancel_msg; -- } -- } -- -- nla_nest_end(msg, selftests); -- genlmsg_end(msg, hdr); -- return 0; -- --err_cancel_msg: -- genlmsg_cancel(msg, hdr); -- return err; --} -- --static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct sk_buff *msg; -- int err; -- -- if (!devlink->ops->selftest_check) -- return -EOPNOTSUPP; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid, -- info->snd_seq, 0, info->extack); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int devlink_nl_cmd_selftests_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err = 0; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- if (idx < start || !devlink->ops->selftest_check) -- goto inc; -- -- devl_lock(devlink); -- err = devlink_nl_selftests_fill(msg, devlink, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, NLM_F_MULTI, -- cb->extack); -- devl_unlock(devlink); -- if (err) { -- devlink_put(devlink); -- break; -- } --inc: -- idx++; -- devlink_put(devlink); -- } -- -- if (err != -EMSGSIZE) -- return err; -- -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, -- enum devlink_selftest_status test_status) --{ -- struct nlattr *result_attr; -- -- result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT); -- if (!result_attr) -- return -EMSGSIZE; -- -- if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) || -- nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS, -- test_status)) -- goto nla_put_failure; -- -- nla_nest_end(skb, result_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(skb, result_attr); -- return -EMSGSIZE; --} -- --static int devlink_nl_cmd_selftests_run(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1]; -- struct devlink *devlink = info->user_ptr[0]; -- struct nlattr *attrs, *selftests; -- struct sk_buff *msg; -- void *hdr; -- int err; -- int i; -- -- if (!devlink->ops->selftest_run || !devlink->ops->selftest_check) -- return -EOPNOTSUPP; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS)) -- return -EINVAL; -- -- attrs = info->attrs[DEVLINK_ATTR_SELFTESTS]; -- -- err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs, -- devlink_selftest_nl_policy, info->extack); -- if (err < 0) -- return err; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = -EMSGSIZE; -- hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, -- &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN); -- if (!hdr) -- goto free_msg; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto genlmsg_cancel; -- -- selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); -- if (!selftests) -- goto genlmsg_cancel; -- -- for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; -- i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { -- enum devlink_selftest_status test_status; -- -- if (nla_get_flag(tb[i])) { -- if (!devlink->ops->selftest_check(devlink, i, -- info->extack)) { -- if (devlink_selftest_result_put(msg, i, -- DEVLINK_SELFTEST_STATUS_SKIP)) -- goto selftests_nest_cancel; -- continue; -- } -- -- test_status = devlink->ops->selftest_run(devlink, i, -- info->extack); -- if (devlink_selftest_result_put(msg, i, test_status)) -- goto selftests_nest_cancel; -- } -- } -- -- nla_nest_end(msg, selftests); -- genlmsg_end(msg, hdr); -- return genlmsg_reply(msg, info); -- --selftests_nest_cancel: -- nla_nest_cancel(msg, selftests); --genlmsg_cancel: -- genlmsg_cancel(msg, hdr); --free_msg: -- nlmsg_free(msg); -- return err; --} -- --static const struct devlink_param devlink_param_generic[] = { -- { -- .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET, -- .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME, -- .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS, -- .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME, -- .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, -- .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME, -- .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT, -- .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME, -- .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, -- .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME, -- .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX, -- .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME, -- .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN, -- .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME, -- .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY, -- .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME, -- .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE, -- .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME, -- .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, -- .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME, -- .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET, -- .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME, -- .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH, -- .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME, -- .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA, -- .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME, -- .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET, -- .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME, -- .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP, -- .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME, -- .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE, -- .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME, -- .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE, -- }, -- { -- .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE, -- .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME, -- .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE, -- }, --}; -- --static int devlink_param_generic_verify(const struct devlink_param *param) --{ -- /* verify it match generic parameter by id and name */ -- if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX) -- return -EINVAL; -- if (strcmp(param->name, devlink_param_generic[param->id].name)) -- return -ENOENT; -- -- WARN_ON(param->type != devlink_param_generic[param->id].type); -- -- return 0; --} -- --static int devlink_param_driver_verify(const struct devlink_param *param) --{ -- int i; -- -- if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX) -- return -EINVAL; -- /* verify no such name in generic params */ -- for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++) -- if (!strcmp(param->name, devlink_param_generic[i].name)) -- return -EEXIST; -- -- return 0; --} -- --static struct devlink_param_item * --devlink_param_find_by_name(struct list_head *param_list, -- const char *param_name) --{ -- struct devlink_param_item *param_item; -- -- list_for_each_entry(param_item, param_list, list) -- if (!strcmp(param_item->param->name, param_name)) -- return param_item; -- return NULL; --} -- --static struct devlink_param_item * --devlink_param_find_by_id(struct list_head *param_list, u32 param_id) --{ -- struct devlink_param_item *param_item; -- -- list_for_each_entry(param_item, param_list, list) -- if (param_item->param->id == param_id) -- return param_item; -- return NULL; --} -- --static bool --devlink_param_cmode_is_supported(const struct devlink_param *param, -- enum devlink_param_cmode cmode) --{ -- return test_bit(cmode, ¶m->supported_cmodes); --} -- --static int devlink_param_get(struct devlink *devlink, -- const struct devlink_param *param, -- struct devlink_param_gset_ctx *ctx) --{ -- if (!param->get || devlink->reload_failed) -- return -EOPNOTSUPP; -- return param->get(devlink, param->id, ctx); --} -- --static int devlink_param_set(struct devlink *devlink, -- const struct devlink_param *param, -- struct devlink_param_gset_ctx *ctx) --{ -- if (!param->set || devlink->reload_failed) -- return -EOPNOTSUPP; -- return param->set(devlink, param->id, ctx); --} -- --static int --devlink_param_type_to_nla_type(enum devlink_param_type param_type) --{ -- switch (param_type) { -- case DEVLINK_PARAM_TYPE_U8: -- return NLA_U8; -- case DEVLINK_PARAM_TYPE_U16: -- return NLA_U16; -- case DEVLINK_PARAM_TYPE_U32: -- return NLA_U32; -- case DEVLINK_PARAM_TYPE_STRING: -- return NLA_STRING; -- case DEVLINK_PARAM_TYPE_BOOL: -- return NLA_FLAG; -- default: -- return -EINVAL; -- } --} -- --static int --devlink_nl_param_value_fill_one(struct sk_buff *msg, -- enum devlink_param_type type, -- enum devlink_param_cmode cmode, -- union devlink_param_value val) --{ -- struct nlattr *param_value_attr; -- -- param_value_attr = nla_nest_start_noflag(msg, -- DEVLINK_ATTR_PARAM_VALUE); -- if (!param_value_attr) -- goto nla_put_failure; -- -- if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) -- goto value_nest_cancel; -- -- switch (type) { -- case DEVLINK_PARAM_TYPE_U8: -- if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8)) -- goto value_nest_cancel; -- break; -- case DEVLINK_PARAM_TYPE_U16: -- if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16)) -- goto value_nest_cancel; -- break; -- case DEVLINK_PARAM_TYPE_U32: -- if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32)) -- goto value_nest_cancel; -- break; -- case DEVLINK_PARAM_TYPE_STRING: -- if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, -- val.vstr)) -- goto value_nest_cancel; -- break; -- case DEVLINK_PARAM_TYPE_BOOL: -- if (val.vbool && -- nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA)) -- goto value_nest_cancel; -- break; -- } -- -- nla_nest_end(msg, param_value_attr); -- return 0; -- --value_nest_cancel: -- nla_nest_cancel(msg, param_value_attr); --nla_put_failure: -- return -EMSGSIZE; --} -- --static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, -- unsigned int port_index, -- struct devlink_param_item *param_item, -- enum devlink_command cmd, -- u32 portid, u32 seq, int flags) --{ -- union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; -- bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; -- const struct devlink_param *param = param_item->param; -- struct devlink_param_gset_ctx ctx; -- struct nlattr *param_values_list; -- struct nlattr *param_attr; -- int nla_type; -- void *hdr; -- int err; -- int i; -- -- /* Get value from driver part to driverinit configuration mode */ -- for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { -- if (!devlink_param_cmode_is_supported(param, i)) -- continue; -- if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) { -- if (!param_item->driverinit_value_valid) -- return -EOPNOTSUPP; -- param_value[i] = param_item->driverinit_value; -- } else { -- ctx.cmode = i; -- err = devlink_param_get(devlink, param, &ctx); -- if (err) -- return err; -- param_value[i] = ctx.val; -- } -- param_value_set[i] = true; -- } -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto genlmsg_cancel; -- -- if (cmd == DEVLINK_CMD_PORT_PARAM_GET || -- cmd == DEVLINK_CMD_PORT_PARAM_NEW || -- cmd == DEVLINK_CMD_PORT_PARAM_DEL) -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index)) -- goto genlmsg_cancel; -- -- param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM); -- if (!param_attr) -- goto genlmsg_cancel; -- if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name)) -- goto param_nest_cancel; -- if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC)) -- goto param_nest_cancel; -- -- nla_type = devlink_param_type_to_nla_type(param->type); -- if (nla_type < 0) -- goto param_nest_cancel; -- if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type)) -- goto param_nest_cancel; -- -- param_values_list = nla_nest_start_noflag(msg, -- DEVLINK_ATTR_PARAM_VALUES_LIST); -- if (!param_values_list) -- goto param_nest_cancel; -- -- for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { -- if (!param_value_set[i]) -- continue; -- err = devlink_nl_param_value_fill_one(msg, param->type, -- i, param_value[i]); -- if (err) -- goto values_list_nest_cancel; -- } -- -- nla_nest_end(msg, param_values_list); -- nla_nest_end(msg, param_attr); -- genlmsg_end(msg, hdr); -- return 0; -- --values_list_nest_cancel: -- nla_nest_end(msg, param_values_list); --param_nest_cancel: -- nla_nest_cancel(msg, param_attr); --genlmsg_cancel: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static void devlink_param_notify(struct devlink *devlink, -- unsigned int port_index, -- struct devlink_param_item *param_item, -- enum devlink_command cmd) --{ -- struct sk_buff *msg; -- int err; -- -- WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL && -- cmd != DEVLINK_CMD_PORT_PARAM_NEW && -- cmd != DEVLINK_CMD_PORT_PARAM_DEL); -- ASSERT_DEVLINK_REGISTERED(devlink); -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd, -- 0, 0, 0); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -- msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink_param_item *param_item; -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err = 0; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- devl_lock(devlink); -- list_for_each_entry(param_item, &devlink->param_list, list) { -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_param_fill(msg, devlink, 0, param_item, -- DEVLINK_CMD_PARAM_GET, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI); -- if (err == -EOPNOTSUPP) { -- err = 0; -- } else if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- devl_unlock(devlink); -- devlink_put(devlink); -- } --out: -- if (err != -EMSGSIZE) -- return err; -- -- cb->args[0] = idx; -- return msg->len; --} -- --static int --devlink_param_type_get_from_info(struct genl_info *info, -- enum devlink_param_type *param_type) --{ -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE)) -- return -EINVAL; -- -- switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) { -- case NLA_U8: -- *param_type = DEVLINK_PARAM_TYPE_U8; -- break; -- case NLA_U16: -- *param_type = DEVLINK_PARAM_TYPE_U16; -- break; -- case NLA_U32: -- *param_type = DEVLINK_PARAM_TYPE_U32; -- break; -- case NLA_STRING: -- *param_type = DEVLINK_PARAM_TYPE_STRING; -- break; -- case NLA_FLAG: -- *param_type = DEVLINK_PARAM_TYPE_BOOL; -- break; -- default: -- return -EINVAL; -- } -- -- return 0; --} -- --static int --devlink_param_value_get_from_info(const struct devlink_param *param, -- struct genl_info *info, -- union devlink_param_value *value) --{ -- struct nlattr *param_data; -- int len; -- -- param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; -- -- if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data) -- return -EINVAL; -- -- switch (param->type) { -- case DEVLINK_PARAM_TYPE_U8: -- if (nla_len(param_data) != sizeof(u8)) -- return -EINVAL; -- value->vu8 = nla_get_u8(param_data); -- break; -- case DEVLINK_PARAM_TYPE_U16: -- if (nla_len(param_data) != sizeof(u16)) -- return -EINVAL; -- value->vu16 = nla_get_u16(param_data); -- break; -- case DEVLINK_PARAM_TYPE_U32: -- if (nla_len(param_data) != sizeof(u32)) -- return -EINVAL; -- value->vu32 = nla_get_u32(param_data); -- break; -- case DEVLINK_PARAM_TYPE_STRING: -- len = strnlen(nla_data(param_data), nla_len(param_data)); -- if (len == nla_len(param_data) || -- len >= __DEVLINK_PARAM_MAX_STRING_VALUE) -- return -EINVAL; -- strcpy(value->vstr, nla_data(param_data)); -- break; -- case DEVLINK_PARAM_TYPE_BOOL: -- if (param_data && nla_len(param_data)) -- return -EINVAL; -- value->vbool = nla_get_flag(param_data); -- break; -- } -- return 0; --} -- --static struct devlink_param_item * --devlink_param_get_from_info(struct list_head *param_list, -- struct genl_info *info) --{ -- char *param_name; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME)) -- return NULL; -- -- param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]); -- return devlink_param_find_by_name(param_list, param_name); --} -- --static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_param_item *param_item; -- struct sk_buff *msg; -- int err; -- -- param_item = devlink_param_get_from_info(&devlink->param_list, info); -- if (!param_item) -- return -EINVAL; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_param_fill(msg, devlink, 0, param_item, -- DEVLINK_CMD_PARAM_GET, -- info->snd_portid, info->snd_seq, 0); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, -- unsigned int port_index, -- struct list_head *param_list, -- struct genl_info *info, -- enum devlink_command cmd) --{ -- enum devlink_param_type param_type; -- struct devlink_param_gset_ctx ctx; -- enum devlink_param_cmode cmode; -- struct devlink_param_item *param_item; -- const struct devlink_param *param; -- union devlink_param_value value; -- int err = 0; -- -- param_item = devlink_param_get_from_info(param_list, info); -- if (!param_item) -- return -EINVAL; -- param = param_item->param; -- err = devlink_param_type_get_from_info(info, ¶m_type); -- if (err) -- return err; -- if (param_type != param->type) -- return -EINVAL; -- err = devlink_param_value_get_from_info(param, info, &value); -- if (err) -- return err; -- if (param->validate) { -- err = param->validate(devlink, param->id, value, info->extack); -- if (err) -- return err; -- } -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE)) -- return -EINVAL; -- cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); -- if (!devlink_param_cmode_is_supported(param, cmode)) -- return -EOPNOTSUPP; -- -- if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { -- if (param->type == DEVLINK_PARAM_TYPE_STRING) -- strcpy(param_item->driverinit_value.vstr, value.vstr); -- else -- param_item->driverinit_value = value; -- param_item->driverinit_value_valid = true; -- } else { -- if (!param->set) -- return -EOPNOTSUPP; -- ctx.val = value; -- ctx.cmode = cmode; -- err = devlink_param_set(devlink, param, &ctx); -- if (err) -- return err; -- } -- -- devlink_param_notify(devlink, port_index, param_item, cmd); -- return 0; --} -- --static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- -- return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list, -- info, DEVLINK_CMD_PARAM_NEW); --} -- --static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- NL_SET_ERR_MSG_MOD(cb->extack, "Port params are not supported"); -- return msg->len; --} -- --static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported"); -- return -EINVAL; --} -- --static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported"); -- return -EINVAL; --} -- --static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg, -- struct devlink *devlink, -- struct devlink_snapshot *snapshot) --{ -- struct nlattr *snap_attr; -- int err; -- -- snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT); -- if (!snap_attr) -- return -EINVAL; -- -- err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id); -- if (err) -- goto nla_put_failure; -- -- nla_nest_end(msg, snap_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, snap_attr); -- return err; --} -- --static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg, -- struct devlink *devlink, -- struct devlink_region *region) --{ -- struct devlink_snapshot *snapshot; -- struct nlattr *snapshots_attr; -- int err; -- -- snapshots_attr = nla_nest_start_noflag(msg, -- DEVLINK_ATTR_REGION_SNAPSHOTS); -- if (!snapshots_attr) -- return -EINVAL; -- -- list_for_each_entry(snapshot, ®ion->snapshot_list, list) { -- err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot); -- if (err) -- goto nla_put_failure; -- } -- -- nla_nest_end(msg, snapshots_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, snapshots_attr); -- return err; --} -- --static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink, -- enum devlink_command cmd, u32 portid, -- u32 seq, int flags, -- struct devlink_region *region) --{ -- void *hdr; -- int err; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- err = devlink_nl_put_handle(msg, devlink); -- if (err) -- goto nla_put_failure; -- -- if (region->port) { -- err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, -- region->port->index); -- if (err) -- goto nla_put_failure; -- } -- -- err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name); -- if (err) -- goto nla_put_failure; -- -- err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, -- region->size, -- DEVLINK_ATTR_PAD); -- if (err) -- goto nla_put_failure; -- -- err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS, -- region->max_snapshots); -- if (err) -- goto nla_put_failure; -- -- err = devlink_nl_region_snapshots_id_put(msg, devlink, region); -- if (err) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return err; --} -- --static struct sk_buff * --devlink_nl_region_notify_build(struct devlink_region *region, -- struct devlink_snapshot *snapshot, -- enum devlink_command cmd, u32 portid, u32 seq) --{ -- struct devlink *devlink = region->devlink; -- struct sk_buff *msg; -- void *hdr; -- int err; -- -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return ERR_PTR(-ENOMEM); -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd); -- if (!hdr) { -- err = -EMSGSIZE; -- goto out_free_msg; -- } -- -- err = devlink_nl_put_handle(msg, devlink); -- if (err) -- goto out_cancel_msg; -- -- if (region->port) { -- err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, -- region->port->index); -- if (err) -- goto out_cancel_msg; -- } -- -- err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, -- region->ops->name); -- if (err) -- goto out_cancel_msg; -- -- if (snapshot) { -- err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, -- snapshot->id); -- if (err) -- goto out_cancel_msg; -- } else { -- err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, -- region->size, DEVLINK_ATTR_PAD); -- if (err) -- goto out_cancel_msg; -- } -- genlmsg_end(msg, hdr); -- -- return msg; -- --out_cancel_msg: -- genlmsg_cancel(msg, hdr); --out_free_msg: -- nlmsg_free(msg); -- return ERR_PTR(err); --} -- --static void devlink_nl_region_notify(struct devlink_region *region, -- struct devlink_snapshot *snapshot, -- enum devlink_command cmd) --{ -- struct devlink *devlink = region->devlink; -- struct sk_buff *msg; -- -- WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL); -- if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -- return; -- -- msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); -- if (IS_ERR(msg)) -- return; -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, -- 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --/** -- * __devlink_snapshot_id_increment - Increment number of snapshots using an id -- * @devlink: devlink instance -- * @id: the snapshot id -- * -- * Track when a new snapshot begins using an id. Load the count for the -- * given id from the snapshot xarray, increment it, and store it back. -- * -- * Called when a new snapshot is created with the given id. -- * -- * The id *must* have been previously allocated by -- * devlink_region_snapshot_id_get(). -- * -- * Returns 0 on success, or an error on failure. -- */ --static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) --{ -- unsigned long count; -- void *p; -- int err; -- -- xa_lock(&devlink->snapshot_ids); -- p = xa_load(&devlink->snapshot_ids, id); -- if (WARN_ON(!p)) { -- err = -EINVAL; -- goto unlock; -- } -- -- if (WARN_ON(!xa_is_value(p))) { -- err = -EINVAL; -- goto unlock; -- } -- -- count = xa_to_value(p); -- count++; -- -- err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), -- GFP_ATOMIC)); --unlock: -- xa_unlock(&devlink->snapshot_ids); -- return err; --} -- --/** -- * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id -- * @devlink: devlink instance -- * @id: the snapshot id -- * -- * Track when a snapshot is deleted and stops using an id. Load the count -- * for the given id from the snapshot xarray, decrement it, and store it -- * back. -- * -- * If the count reaches zero, erase this id from the xarray, freeing it -- * up for future re-use by devlink_region_snapshot_id_get(). -- * -- * Called when a snapshot using the given id is deleted, and when the -- * initial allocator of the id is finished using it. -- */ --static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) --{ -- unsigned long count; -- void *p; -- -- xa_lock(&devlink->snapshot_ids); -- p = xa_load(&devlink->snapshot_ids, id); -- if (WARN_ON(!p)) -- goto unlock; -- -- if (WARN_ON(!xa_is_value(p))) -- goto unlock; -- -- count = xa_to_value(p); -- -- if (count > 1) { -- count--; -- __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), -- GFP_ATOMIC); -- } else { -- /* If this was the last user, we can erase this id */ -- __xa_erase(&devlink->snapshot_ids, id); -- } --unlock: -- xa_unlock(&devlink->snapshot_ids); --} -- --/** -- * __devlink_snapshot_id_insert - Insert a specific snapshot ID -- * @devlink: devlink instance -- * @id: the snapshot id -- * -- * Mark the given snapshot id as used by inserting a zero value into the -- * snapshot xarray. -- * -- * This must be called while holding the devlink instance lock. Unlike -- * devlink_snapshot_id_get, the initial reference count is zero, not one. -- * It is expected that the id will immediately be used before -- * releasing the devlink instance lock. -- * -- * Returns zero on success, or an error code if the snapshot id could not -- * be inserted. -- */ --static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) --{ -- int err; -- -- xa_lock(&devlink->snapshot_ids); -- if (xa_load(&devlink->snapshot_ids, id)) { -- xa_unlock(&devlink->snapshot_ids); -- return -EEXIST; -- } -- err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), -- GFP_ATOMIC)); -- xa_unlock(&devlink->snapshot_ids); -- return err; --} -- --/** -- * __devlink_region_snapshot_id_get - get snapshot ID -- * @devlink: devlink instance -- * @id: storage to return snapshot id -- * -- * Allocates a new snapshot id. Returns zero on success, or a negative -- * error on failure. Must be called while holding the devlink instance -- * lock. -- * -- * Snapshot IDs are tracked using an xarray which stores the number of -- * users of the snapshot id. -- * -- * Note that the caller of this function counts as a 'user', in order to -- * avoid race conditions. The caller must release its hold on the -- * snapshot by using devlink_region_snapshot_id_put. -- */ --static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) --{ -- return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), -- xa_limit_32b, GFP_KERNEL); --} -- --/** -- * __devlink_region_snapshot_create - create a new snapshot -- * This will add a new snapshot of a region. The snapshot -- * will be stored on the region struct and can be accessed -- * from devlink. This is useful for future analyses of snapshots. -- * Multiple snapshots can be created on a region. -- * The @snapshot_id should be obtained using the getter function. -- * -- * Must be called only while holding the region snapshot lock. -- * -- * @region: devlink region of the snapshot -- * @data: snapshot data -- * @snapshot_id: snapshot id to be created -- */ --static int --__devlink_region_snapshot_create(struct devlink_region *region, -- u8 *data, u32 snapshot_id) --{ -- struct devlink *devlink = region->devlink; -- struct devlink_snapshot *snapshot; -- int err; -- -- lockdep_assert_held(®ion->snapshot_lock); -- -- /* check if region can hold one more snapshot */ -- if (region->cur_snapshots == region->max_snapshots) -- return -ENOSPC; -- -- if (devlink_region_snapshot_get_by_id(region, snapshot_id)) -- return -EEXIST; -- -- snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL); -- if (!snapshot) -- return -ENOMEM; -- -- err = __devlink_snapshot_id_increment(devlink, snapshot_id); -- if (err) -- goto err_snapshot_id_increment; -- -- snapshot->id = snapshot_id; -- snapshot->region = region; -- snapshot->data = data; -- -- list_add_tail(&snapshot->list, ®ion->snapshot_list); -- -- region->cur_snapshots++; -- -- devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW); -- return 0; -- --err_snapshot_id_increment: -- kfree(snapshot); -- return err; --} -- --static void devlink_region_snapshot_del(struct devlink_region *region, -- struct devlink_snapshot *snapshot) --{ -- struct devlink *devlink = region->devlink; -- -- lockdep_assert_held(®ion->snapshot_lock); -- -- devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL); -- region->cur_snapshots--; -- list_del(&snapshot->list); -- region->ops->destructor(snapshot->data); -- __devlink_snapshot_id_decrement(devlink, snapshot->id); -- kfree(snapshot); --} -- --static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_port *port = NULL; -- struct devlink_region *region; -- const char *region_name; -- struct sk_buff *msg; -- unsigned int index; -- int err; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) -- return -EINVAL; -- -- if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -- index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -- -- port = devlink_port_get_by_index(devlink, index); -- if (!port) -- return -ENODEV; -- } -- -- region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); -- if (port) -- region = devlink_port_region_get_by_name(port, region_name); -- else -- region = devlink_region_get_by_name(devlink, region_name); -- -- if (!region) -- return -EINVAL; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET, -- info->snd_portid, info->snd_seq, 0, -- region); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb, -- struct devlink_port *port, -- int *idx, -- int start) --{ -- struct devlink_region *region; -- int err = 0; -- -- list_for_each_entry(region, &port->region_list, list) { -- if (*idx < start) { -- (*idx)++; -- continue; -- } -- err = devlink_nl_region_fill(msg, port->devlink, -- DEVLINK_CMD_REGION_GET, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI, region); -- if (err) -- goto out; -- (*idx)++; -- } -- --out: -- return err; --} -- --static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb, -- struct devlink *devlink, -- int *idx, -- int start) --{ -- struct devlink_region *region; -- struct devlink_port *port; -- int err = 0; -- -- devl_lock(devlink); -- list_for_each_entry(region, &devlink->region_list, list) { -- if (*idx < start) { -- (*idx)++; -- continue; -- } -- err = devlink_nl_region_fill(msg, devlink, -- DEVLINK_CMD_REGION_GET, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI, region); -- if (err) -- goto out; -- (*idx)++; -- } -- -- list_for_each_entry(port, &devlink->port_list, list) { -- err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx, -- start); -- if (err) -- goto out; -- } -- --out: -- devl_unlock(devlink); -- return err; --} -- --static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err = 0; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink, -- &idx, start); -- devlink_put(devlink); -- if (err) -- goto out; -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static int devlink_nl_cmd_region_del(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_snapshot *snapshot; -- struct devlink_port *port = NULL; -- struct devlink_region *region; -- const char *region_name; -- unsigned int index; -- u32 snapshot_id; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) || -- GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID)) -- return -EINVAL; -- -- region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); -- snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); -- -- if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -- index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -- -- port = devlink_port_get_by_index(devlink, index); -- if (!port) -- return -ENODEV; -- } -- -- if (port) -- region = devlink_port_region_get_by_name(port, region_name); -- else -- region = devlink_region_get_by_name(devlink, region_name); -- -- if (!region) -- return -EINVAL; -- -- mutex_lock(®ion->snapshot_lock); -- snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); -- if (!snapshot) { -- mutex_unlock(®ion->snapshot_lock); -- return -EINVAL; -- } -- -- devlink_region_snapshot_del(region, snapshot); -- mutex_unlock(®ion->snapshot_lock); -- return 0; --} -- --static int --devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_snapshot *snapshot; -- struct devlink_port *port = NULL; -- struct nlattr *snapshot_id_attr; -- struct devlink_region *region; -- const char *region_name; -- unsigned int index; -- u32 snapshot_id; -- u8 *data; -- int err; -- -- if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) { -- NL_SET_ERR_MSG_MOD(info->extack, "No region name provided"); -- return -EINVAL; -- } -- -- region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); -- -- if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -- index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -- -- port = devlink_port_get_by_index(devlink, index); -- if (!port) -- return -ENODEV; -- } -- -- if (port) -- region = devlink_port_region_get_by_name(port, region_name); -- else -- region = devlink_region_get_by_name(devlink, region_name); -- -- if (!region) { -- NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist"); -- return -EINVAL; -- } -- -- if (!region->ops->snapshot) { -- NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot"); -- return -EOPNOTSUPP; -- } -- -- mutex_lock(®ion->snapshot_lock); -- -- if (region->cur_snapshots == region->max_snapshots) { -- NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots"); -- err = -ENOSPC; -- goto unlock; -- } -- -- snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; -- if (snapshot_id_attr) { -- snapshot_id = nla_get_u32(snapshot_id_attr); -- -- if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { -- NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use"); -- err = -EEXIST; -- goto unlock; -- } -- -- err = __devlink_snapshot_id_insert(devlink, snapshot_id); -- if (err) -- goto unlock; -- } else { -- err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); -- if (err) { -- NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id"); -- goto unlock; -- } -- } -- -- if (port) -- err = region->port_ops->snapshot(port, region->port_ops, -- info->extack, &data); -- else -- err = region->ops->snapshot(devlink, region->ops, -- info->extack, &data); -- if (err) -- goto err_snapshot_capture; -- -- err = __devlink_region_snapshot_create(region, data, snapshot_id); -- if (err) -- goto err_snapshot_create; -- -- if (!snapshot_id_attr) { -- struct sk_buff *msg; -- -- snapshot = devlink_region_snapshot_get_by_id(region, -- snapshot_id); -- if (WARN_ON(!snapshot)) { -- err = -EINVAL; -- goto unlock; -- } -- -- msg = devlink_nl_region_notify_build(region, snapshot, -- DEVLINK_CMD_REGION_NEW, -- info->snd_portid, -- info->snd_seq); -- err = PTR_ERR_OR_ZERO(msg); -- if (err) -- goto err_notify; -- -- err = genlmsg_reply(msg, info); -- if (err) -- goto err_notify; -- } -- -- mutex_unlock(®ion->snapshot_lock); -- return 0; -- --err_snapshot_create: -- region->ops->destructor(data); --err_snapshot_capture: -- __devlink_snapshot_id_decrement(devlink, snapshot_id); -- mutex_unlock(®ion->snapshot_lock); -- return err; -- --err_notify: -- devlink_region_snapshot_del(region, snapshot); --unlock: -- mutex_unlock(®ion->snapshot_lock); -- return err; --} -- --static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg, -- struct devlink *devlink, -- u8 *chunk, u32 chunk_size, -- u64 addr) --{ -- struct nlattr *chunk_attr; -- int err; -- -- chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK); -- if (!chunk_attr) -- return -EINVAL; -- -- err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk); -- if (err) -- goto nla_put_failure; -- -- err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr, -- DEVLINK_ATTR_PAD); -- if (err) -- goto nla_put_failure; -- -- nla_nest_end(msg, chunk_attr); -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, chunk_attr); -- return err; --} -- --#define DEVLINK_REGION_READ_CHUNK_SIZE 256 -- --static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb, -- struct devlink *devlink, -- struct devlink_region *region, -- struct nlattr **attrs, -- u64 start_offset, -- u64 end_offset, -- u64 *new_offset) --{ -- struct devlink_snapshot *snapshot; -- u64 curr_offset = start_offset; -- u32 snapshot_id; -- int err = 0; -- -- *new_offset = start_offset; -- -- snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); -- snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); -- if (!snapshot) -- return -EINVAL; -- -- while (curr_offset < end_offset) { -- u32 data_size; -- u8 *data; -- -- if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE) -- data_size = end_offset - curr_offset; -- else -- data_size = DEVLINK_REGION_READ_CHUNK_SIZE; -- -- data = &snapshot->data[curr_offset]; -- err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink, -- data, data_size, -- curr_offset); -- if (err) -- break; -- -- curr_offset += data_size; -- } -- *new_offset = curr_offset; -- -- return err; --} -- --static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, -- struct netlink_callback *cb) --{ -- const struct genl_dumpit_info *info = genl_dumpit_info(cb); -- u64 ret_offset, start_offset, end_offset = U64_MAX; -- struct nlattr **attrs = info->attrs; -- struct devlink_port *port = NULL; -- struct devlink_region *region; -- struct nlattr *chunks_attr; -- const char *region_name; -- struct devlink *devlink; -- unsigned int index; -- void *hdr; -- int err; -- -- start_offset = *((u64 *)&cb->args[0]); -- -- devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); -- if (IS_ERR(devlink)) -- return PTR_ERR(devlink); -- -- devl_lock(devlink); -- -- if (!attrs[DEVLINK_ATTR_REGION_NAME] || -- !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) { -- err = -EINVAL; -- goto out_unlock; -- } -- -- if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -- index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -- -- port = devlink_port_get_by_index(devlink, index); -- if (!port) { -- err = -ENODEV; -- goto out_unlock; -- } -- } -- -- region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]); -- -- if (port) -- region = devlink_port_region_get_by_name(port, region_name); -- else -- region = devlink_region_get_by_name(devlink, region_name); -- -- if (!region) { -- err = -EINVAL; -- goto out_unlock; -- } -- -- if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && -- attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { -- if (!start_offset) -- start_offset = -- nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); -- -- end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); -- end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); -- } -- -- if (end_offset > region->size) -- end_offset = region->size; -- -- /* return 0 if there is no further data to read */ -- if (start_offset == end_offset) { -- err = 0; -- goto out_unlock; -- } -- -- hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, -- &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, -- DEVLINK_CMD_REGION_READ); -- if (!hdr) { -- err = -EMSGSIZE; -- goto out_unlock; -- } -- -- err = devlink_nl_put_handle(skb, devlink); -- if (err) -- goto nla_put_failure; -- -- if (region->port) { -- err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX, -- region->port->index); -- if (err) -- goto nla_put_failure; -- } -- -- err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name); -- if (err) -- goto nla_put_failure; -- -- chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS); -- if (!chunks_attr) { -- err = -EMSGSIZE; -- goto nla_put_failure; -- } -- -- err = devlink_nl_region_read_snapshot_fill(skb, devlink, -- region, attrs, -- start_offset, -- end_offset, &ret_offset); -- -- if (err && err != -EMSGSIZE) -- goto nla_put_failure; -- -- /* Check if there was any progress done to prevent infinite loop */ -- if (ret_offset == start_offset) { -- err = -EINVAL; -- goto nla_put_failure; -- } -- -- *((u64 *)&cb->args[0]) = ret_offset; -- -- nla_nest_end(skb, chunks_attr); -- genlmsg_end(skb, hdr); -- devl_unlock(devlink); -- devlink_put(devlink); -- return skb->len; -- --nla_put_failure: -- genlmsg_cancel(skb, hdr); --out_unlock: -- devl_unlock(devlink); -- devlink_put(devlink); -- return err; --} -- --int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name) --{ -- if (!req->msg) -- return 0; -- return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name); --} --EXPORT_SYMBOL_GPL(devlink_info_driver_name_put); -- --int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) --{ -- if (!req->msg) -- return 0; -- return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); --} --EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); -- --int devlink_info_board_serial_number_put(struct devlink_info_req *req, -- const char *bsn) --{ -- if (!req->msg) -- return 0; -- return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, -- bsn); --} --EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); -- --static int devlink_info_version_put(struct devlink_info_req *req, int attr, -- const char *version_name, -- const char *version_value, -- enum devlink_info_version_type version_type) --{ -- struct nlattr *nest; -- int err; -- -- if (req->version_cb) -- req->version_cb(version_name, version_type, -- req->version_cb_priv); -- -- if (!req->msg) -- return 0; -- -- nest = nla_nest_start_noflag(req->msg, attr); -- if (!nest) -- return -EMSGSIZE; -- -- err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, -- version_name); -- if (err) -- goto nla_put_failure; -- -- err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, -- version_value); -- if (err) -- goto nla_put_failure; -- -- nla_nest_end(req->msg, nest); -- -- return 0; -- --nla_put_failure: -- nla_nest_cancel(req->msg, nest); -- return err; --} -- --int devlink_info_version_fixed_put(struct devlink_info_req *req, -- const char *version_name, -- const char *version_value) --{ -- return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, -- version_name, version_value, -- DEVLINK_INFO_VERSION_TYPE_NONE); --} --EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); -- --int devlink_info_version_stored_put(struct devlink_info_req *req, -- const char *version_name, -- const char *version_value) --{ -- return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, -- version_name, version_value, -- DEVLINK_INFO_VERSION_TYPE_NONE); --} --EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); -- --int devlink_info_version_stored_put_ext(struct devlink_info_req *req, -- const char *version_name, -- const char *version_value, -- enum devlink_info_version_type version_type) --{ -- return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, -- version_name, version_value, -- version_type); --} --EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext); -- --int devlink_info_version_running_put(struct devlink_info_req *req, -- const char *version_name, -- const char *version_value) --{ -- return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, -- version_name, version_value, -- DEVLINK_INFO_VERSION_TYPE_NONE); --} --EXPORT_SYMBOL_GPL(devlink_info_version_running_put); -- --int devlink_info_version_running_put_ext(struct devlink_info_req *req, -- const char *version_name, -- const char *version_value, -- enum devlink_info_version_type version_type) --{ -- return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, -- version_name, version_value, -- version_type); --} --EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext); -- --static int --devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, -- enum devlink_command cmd, u32 portid, -- u32 seq, int flags, struct netlink_ext_ack *extack) --{ -- struct devlink_info_req req = {}; -- void *hdr; -- int err; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- err = -EMSGSIZE; -- if (devlink_nl_put_handle(msg, devlink)) -- goto err_cancel_msg; -- -- req.msg = msg; -- err = devlink->ops->info_get(devlink, &req, extack); -- if (err) -- goto err_cancel_msg; -- -- genlmsg_end(msg, hdr); -- return 0; -- --err_cancel_msg: -- genlmsg_cancel(msg, hdr); -- return err; --} -- --static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct sk_buff *msg; -- int err; -- -- if (!devlink->ops->info_get) -- return -EOPNOTSUPP; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, -- info->snd_portid, info->snd_seq, 0, -- info->extack); -- if (err) { -- nlmsg_free(msg); -- return err; -- } -- -- return genlmsg_reply(msg, info); --} -- --static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err = 0; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- if (idx < start || !devlink->ops->info_get) -- goto inc; -- -- devl_lock(devlink); -- err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, NLM_F_MULTI, -- cb->extack); -- devl_unlock(devlink); -- if (err == -EOPNOTSUPP) -- err = 0; -- else if (err) { -- devlink_put(devlink); -- break; -- } --inc: -- idx++; -- devlink_put(devlink); -- } -- -- if (err != -EMSGSIZE) -- return err; -- -- cb->args[0] = idx; -- return msg->len; --} -- --struct devlink_fmsg_item { -- struct list_head list; -- int attrtype; -- u8 nla_type; -- u16 len; -- int value[]; --}; -- --struct devlink_fmsg { -- struct list_head item_list; -- bool putting_binary; /* This flag forces enclosing of binary data -- * in an array brackets. It forces using -- * of designated API: -- * devlink_fmsg_binary_pair_nest_start() -- * devlink_fmsg_binary_pair_nest_end() -- */ --}; -- --static struct devlink_fmsg *devlink_fmsg_alloc(void) --{ -- struct devlink_fmsg *fmsg; -- -- fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL); -- if (!fmsg) -- return NULL; -- -- INIT_LIST_HEAD(&fmsg->item_list); -- -- return fmsg; --} -- --static void devlink_fmsg_free(struct devlink_fmsg *fmsg) --{ -- struct devlink_fmsg_item *item, *tmp; -- -- list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) { -- list_del(&item->list); -- kfree(item); -- } -- kfree(fmsg); --} -- --static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg, -- int attrtype) --{ -- struct devlink_fmsg_item *item; -- -- item = kzalloc(sizeof(*item), GFP_KERNEL); -- if (!item) -- return -ENOMEM; -- -- item->attrtype = attrtype; -- list_add_tail(&item->list, &fmsg->item_list); -- -- return 0; --} -- --int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START); --} --EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start); -- --static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END); --} -- --int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_nest_end(fmsg); --} --EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end); -- --#define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN) -- --static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name) --{ -- struct devlink_fmsg_item *item; -- -- if (fmsg->putting_binary) -- return -EINVAL; -- -- if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE) -- return -EMSGSIZE; -- -- item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL); -- if (!item) -- return -ENOMEM; -- -- item->nla_type = NLA_NUL_STRING; -- item->len = strlen(name) + 1; -- item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME; -- memcpy(&item->value, name, item->len); -- list_add_tail(&item->list, &fmsg->item_list); -- -- return 0; --} -- --int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name) --{ -- int err; -- -- if (fmsg->putting_binary) -- return -EINVAL; -- -- err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START); -- if (err) -- return err; -- -- err = devlink_fmsg_put_name(fmsg, name); -- if (err) -- return err; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start); -- --int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_nest_end(fmsg); --} --EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end); -- --int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg, -- const char *name) --{ -- int err; -- -- if (fmsg->putting_binary) -- return -EINVAL; -- -- err = devlink_fmsg_pair_nest_start(fmsg, name); -- if (err) -- return err; -- -- err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START); -- if (err) -- return err; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start); -- --int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg) --{ -- int err; -- -- if (fmsg->putting_binary) -- return -EINVAL; -- -- err = devlink_fmsg_nest_end(fmsg); -- if (err) -- return err; -- -- err = devlink_fmsg_nest_end(fmsg); -- if (err) -- return err; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end); -- --int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg, -- const char *name) --{ -- int err; -- -- err = devlink_fmsg_arr_pair_nest_start(fmsg, name); -- if (err) -- return err; -- -- fmsg->putting_binary = true; -- return err; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start); -- --int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg) --{ -- if (!fmsg->putting_binary) -- return -EINVAL; -- -- fmsg->putting_binary = false; -- return devlink_fmsg_arr_pair_nest_end(fmsg); --} --EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end); -- --static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg, -- const void *value, u16 value_len, -- u8 value_nla_type) --{ -- struct devlink_fmsg_item *item; -- -- if (value_len > DEVLINK_FMSG_MAX_SIZE) -- return -EMSGSIZE; -- -- item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL); -- if (!item) -- return -ENOMEM; -- -- item->nla_type = value_nla_type; -- item->len = value_len; -- item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; -- memcpy(&item->value, value, item->len); -- list_add_tail(&item->list, &fmsg->item_list); -- -- return 0; --} -- --static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG); --} -- --static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8); --} -- --int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32); --} --EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put); -- --static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64); --} -- --int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value) --{ -- if (fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1, -- NLA_NUL_STRING); --} --EXPORT_SYMBOL_GPL(devlink_fmsg_string_put); -- --int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value, -- u16 value_len) --{ -- if (!fmsg->putting_binary) -- return -EINVAL; -- -- return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY); --} --EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put); -- --int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name, -- bool value) --{ -- int err; -- -- err = devlink_fmsg_pair_nest_start(fmsg, name); -- if (err) -- return err; -- -- err = devlink_fmsg_bool_put(fmsg, value); -- if (err) -- return err; -- -- err = devlink_fmsg_pair_nest_end(fmsg); -- if (err) -- return err; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put); -- --int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name, -- u8 value) --{ -- int err; -- -- err = devlink_fmsg_pair_nest_start(fmsg, name); -- if (err) -- return err; -- -- err = devlink_fmsg_u8_put(fmsg, value); -- if (err) -- return err; -- -- err = devlink_fmsg_pair_nest_end(fmsg); -- if (err) -- return err; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put); -- --int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name, -- u32 value) --{ -- int err; -- -- err = devlink_fmsg_pair_nest_start(fmsg, name); -- if (err) -- return err; -- -- err = devlink_fmsg_u32_put(fmsg, value); -- if (err) -- return err; -- -- err = devlink_fmsg_pair_nest_end(fmsg); -- if (err) -- return err; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put); -- --int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name, -- u64 value) --{ -- int err; -- -- err = devlink_fmsg_pair_nest_start(fmsg, name); -- if (err) -- return err; -- -- err = devlink_fmsg_u64_put(fmsg, value); -- if (err) -- return err; -- -- err = devlink_fmsg_pair_nest_end(fmsg); -- if (err) -- return err; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put); -- --int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name, -- const char *value) --{ -- int err; -- -- err = devlink_fmsg_pair_nest_start(fmsg, name); -- if (err) -- return err; -- -- err = devlink_fmsg_string_put(fmsg, value); -- if (err) -- return err; -- -- err = devlink_fmsg_pair_nest_end(fmsg); -- if (err) -- return err; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put); -- --int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name, -- const void *value, u32 value_len) --{ -- u32 data_size; -- int end_err; -- u32 offset; -- int err; -- -- err = devlink_fmsg_binary_pair_nest_start(fmsg, name); -- if (err) -- return err; -- -- for (offset = 0; offset < value_len; offset += data_size) { -- data_size = value_len - offset; -- if (data_size > DEVLINK_FMSG_MAX_SIZE) -- data_size = DEVLINK_FMSG_MAX_SIZE; -- err = devlink_fmsg_binary_put(fmsg, value + offset, data_size); -- if (err) -- break; -- /* Exit from loop with a break (instead of -- * return) to make sure putting_binary is turned off in -- * devlink_fmsg_binary_pair_nest_end -- */ -- } -- -- end_err = devlink_fmsg_binary_pair_nest_end(fmsg); -- if (end_err) -- err = end_err; -- -- return err; --} --EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put); -- --static int --devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb) --{ -- switch (msg->nla_type) { -- case NLA_FLAG: -- case NLA_U8: -- case NLA_U32: -- case NLA_U64: -- case NLA_NUL_STRING: -- case NLA_BINARY: -- return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, -- msg->nla_type); -- default: -- return -EINVAL; -- } --} -- --static int --devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb) --{ -- int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; -- u8 tmp; -- -- switch (msg->nla_type) { -- case NLA_FLAG: -- /* Always provide flag data, regardless of its value */ -- tmp = *(bool *) msg->value; -- -- return nla_put_u8(skb, attrtype, tmp); -- case NLA_U8: -- return nla_put_u8(skb, attrtype, *(u8 *) msg->value); -- case NLA_U32: -- return nla_put_u32(skb, attrtype, *(u32 *) msg->value); -- case NLA_U64: -- return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value, -- DEVLINK_ATTR_PAD); -- case NLA_NUL_STRING: -- return nla_put_string(skb, attrtype, (char *) &msg->value); -- case NLA_BINARY: -- return nla_put(skb, attrtype, msg->len, (void *) &msg->value); -- default: -- return -EINVAL; -- } --} -- --static int --devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb, -- int *start) --{ -- struct devlink_fmsg_item *item; -- struct nlattr *fmsg_nlattr; -- int i = 0; -- int err; -- -- fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG); -- if (!fmsg_nlattr) -- return -EMSGSIZE; -- -- list_for_each_entry(item, &fmsg->item_list, list) { -- if (i < *start) { -- i++; -- continue; -- } -- -- switch (item->attrtype) { -- case DEVLINK_ATTR_FMSG_OBJ_NEST_START: -- case DEVLINK_ATTR_FMSG_PAIR_NEST_START: -- case DEVLINK_ATTR_FMSG_ARR_NEST_START: -- case DEVLINK_ATTR_FMSG_NEST_END: -- err = nla_put_flag(skb, item->attrtype); -- break; -- case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA: -- err = devlink_fmsg_item_fill_type(item, skb); -- if (err) -- break; -- err = devlink_fmsg_item_fill_data(item, skb); -- break; -- case DEVLINK_ATTR_FMSG_OBJ_NAME: -- err = nla_put_string(skb, item->attrtype, -- (char *) &item->value); -- break; -- default: -- err = -EINVAL; -- break; -- } -- if (!err) -- *start = ++i; -- else -- break; -- } -- -- nla_nest_end(skb, fmsg_nlattr); -- return err; --} -- --static int devlink_fmsg_snd(struct devlink_fmsg *fmsg, -- struct genl_info *info, -- enum devlink_command cmd, int flags) --{ -- struct nlmsghdr *nlh; -- struct sk_buff *skb; -- bool last = false; -- int index = 0; -- void *hdr; -- int err; -- -- while (!last) { -- int tmp_index = index; -- -- skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!skb) -- return -ENOMEM; -- -- hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, -- &devlink_nl_family, flags | NLM_F_MULTI, cmd); -- if (!hdr) { -- err = -EMSGSIZE; -- goto nla_put_failure; -- } -- -- err = devlink_fmsg_prepare_skb(fmsg, skb, &index); -- if (!err) -- last = true; -- else if (err != -EMSGSIZE || tmp_index == index) -- goto nla_put_failure; -- -- genlmsg_end(skb, hdr); -- err = genlmsg_reply(skb, info); -- if (err) -- return err; -- } -- -- skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!skb) -- return -ENOMEM; -- nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, -- NLMSG_DONE, 0, flags | NLM_F_MULTI); -- if (!nlh) { -- err = -EMSGSIZE; -- goto nla_put_failure; -- } -- -- return genlmsg_reply(skb, info); -- --nla_put_failure: -- nlmsg_free(skb); -- return err; --} -- --static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb, -- struct netlink_callback *cb, -- enum devlink_command cmd) --{ -- int index = cb->args[0]; -- int tmp_index = index; -- void *hdr; -- int err; -- -- hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, -- &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd); -- if (!hdr) { -- err = -EMSGSIZE; -- goto nla_put_failure; -- } -- -- err = devlink_fmsg_prepare_skb(fmsg, skb, &index); -- if ((err && err != -EMSGSIZE) || tmp_index == index) -- goto nla_put_failure; -- -- cb->args[0] = index; -- genlmsg_end(skb, hdr); -- return skb->len; -- --nla_put_failure: -- genlmsg_cancel(skb, hdr); -- return err; --} -- --struct devlink_health_reporter { -- struct list_head list; -- void *priv; -- const struct devlink_health_reporter_ops *ops; -- struct devlink *devlink; -- struct devlink_port *devlink_port; -- struct devlink_fmsg *dump_fmsg; -- struct mutex dump_lock; /* lock parallel read/write from dump buffers */ -- u64 graceful_period; -- bool auto_recover; -- bool auto_dump; -- u8 health_state; -- u64 dump_ts; -- u64 dump_real_ts; -- u64 error_count; -- u64 recovery_count; -- u64 last_recovery_ts; -- refcount_t refcount; --}; -- --void * --devlink_health_reporter_priv(struct devlink_health_reporter *reporter) --{ -- return reporter->priv; --} --EXPORT_SYMBOL_GPL(devlink_health_reporter_priv); -- --static struct devlink_health_reporter * --__devlink_health_reporter_find_by_name(struct list_head *reporter_list, -- struct mutex *list_lock, -- const char *reporter_name) --{ -- struct devlink_health_reporter *reporter; -- -- lockdep_assert_held(list_lock); -- list_for_each_entry(reporter, reporter_list, list) -- if (!strcmp(reporter->ops->name, reporter_name)) -- return reporter; -- return NULL; --} -- --static struct devlink_health_reporter * --devlink_health_reporter_find_by_name(struct devlink *devlink, -- const char *reporter_name) --{ -- return __devlink_health_reporter_find_by_name(&devlink->reporter_list, -- &devlink->reporters_lock, -- reporter_name); --} -- --static struct devlink_health_reporter * --devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port, -- const char *reporter_name) --{ -- return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list, -- &devlink_port->reporters_lock, -- reporter_name); --} -- --static struct devlink_health_reporter * --__devlink_health_reporter_create(struct devlink *devlink, -- const struct devlink_health_reporter_ops *ops, -- u64 graceful_period, void *priv) --{ -- struct devlink_health_reporter *reporter; -- -- if (WARN_ON(graceful_period && !ops->recover)) -- return ERR_PTR(-EINVAL); -- -- reporter = kzalloc(sizeof(*reporter), GFP_KERNEL); -- if (!reporter) -- return ERR_PTR(-ENOMEM); -- -- reporter->priv = priv; -- reporter->ops = ops; -- reporter->devlink = devlink; -- reporter->graceful_period = graceful_period; -- reporter->auto_recover = !!ops->recover; -- reporter->auto_dump = !!ops->dump; -- mutex_init(&reporter->dump_lock); -- refcount_set(&reporter->refcount, 1); -- return reporter; --} -- --/** -- * devlink_port_health_reporter_create - create devlink health reporter for -- * specified port instance -- * -- * @port: devlink_port which should contain the new reporter -- * @ops: ops -- * @graceful_period: to avoid recovery loops, in msecs -- * @priv: priv -- */ --struct devlink_health_reporter * --devlink_port_health_reporter_create(struct devlink_port *port, -- const struct devlink_health_reporter_ops *ops, -- u64 graceful_period, void *priv) --{ -- struct devlink_health_reporter *reporter; -- -- mutex_lock(&port->reporters_lock); -- if (__devlink_health_reporter_find_by_name(&port->reporter_list, -- &port->reporters_lock, ops->name)) { -- reporter = ERR_PTR(-EEXIST); -- goto unlock; -- } -- -- reporter = __devlink_health_reporter_create(port->devlink, ops, -- graceful_period, priv); -- if (IS_ERR(reporter)) -- goto unlock; -- -- reporter->devlink_port = port; -- list_add_tail(&reporter->list, &port->reporter_list); --unlock: -- mutex_unlock(&port->reporters_lock); -- return reporter; --} --EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create); -- --/** -- * devlink_health_reporter_create - create devlink health reporter -- * -- * @devlink: devlink -- * @ops: ops -- * @graceful_period: to avoid recovery loops, in msecs -- * @priv: priv -- */ --struct devlink_health_reporter * --devlink_health_reporter_create(struct devlink *devlink, -- const struct devlink_health_reporter_ops *ops, -- u64 graceful_period, void *priv) --{ -- struct devlink_health_reporter *reporter; -- -- mutex_lock(&devlink->reporters_lock); -- if (devlink_health_reporter_find_by_name(devlink, ops->name)) { -- reporter = ERR_PTR(-EEXIST); -- goto unlock; -- } -- -- reporter = __devlink_health_reporter_create(devlink, ops, -- graceful_period, priv); -- if (IS_ERR(reporter)) -- goto unlock; -- -- list_add_tail(&reporter->list, &devlink->reporter_list); --unlock: -- mutex_unlock(&devlink->reporters_lock); -- return reporter; --} --EXPORT_SYMBOL_GPL(devlink_health_reporter_create); -- --static void --devlink_health_reporter_free(struct devlink_health_reporter *reporter) --{ -- mutex_destroy(&reporter->dump_lock); -- if (reporter->dump_fmsg) -- devlink_fmsg_free(reporter->dump_fmsg); -- kfree(reporter); --} -- --static void --devlink_health_reporter_put(struct devlink_health_reporter *reporter) --{ -- if (refcount_dec_and_test(&reporter->refcount)) -- devlink_health_reporter_free(reporter); --} -- --static void --__devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) --{ -- list_del(&reporter->list); -- devlink_health_reporter_put(reporter); --} -- --/** -- * devlink_health_reporter_destroy - destroy devlink health reporter -- * -- * @reporter: devlink health reporter to destroy -- */ --void --devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) --{ -- struct mutex *lock = &reporter->devlink->reporters_lock; -- -- mutex_lock(lock); -- __devlink_health_reporter_destroy(reporter); -- mutex_unlock(lock); --} --EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy); -- --/** -- * devlink_port_health_reporter_destroy - destroy devlink port health reporter -- * -- * @reporter: devlink health reporter to destroy -- */ --void --devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter) --{ -- struct mutex *lock = &reporter->devlink_port->reporters_lock; -- -- mutex_lock(lock); -- __devlink_health_reporter_destroy(reporter); -- mutex_unlock(lock); --} --EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy); -- --static int --devlink_nl_health_reporter_fill(struct sk_buff *msg, -- struct devlink_health_reporter *reporter, -- enum devlink_command cmd, u32 portid, -- u32 seq, int flags) --{ -- struct devlink *devlink = reporter->devlink; -- struct nlattr *reporter_attr; -- void *hdr; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto genlmsg_cancel; -- -- if (reporter->devlink_port) { -- if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index)) -- goto genlmsg_cancel; -- } -- reporter_attr = nla_nest_start_noflag(msg, -- DEVLINK_ATTR_HEALTH_REPORTER); -- if (!reporter_attr) -- goto genlmsg_cancel; -- if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME, -- reporter->ops->name)) -- goto reporter_nest_cancel; -- if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE, -- reporter->health_state)) -- goto reporter_nest_cancel; -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT, -- reporter->error_count, DEVLINK_ATTR_PAD)) -- goto reporter_nest_cancel; -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT, -- reporter->recovery_count, DEVLINK_ATTR_PAD)) -- goto reporter_nest_cancel; -- if (reporter->ops->recover && -- nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, -- reporter->graceful_period, -- DEVLINK_ATTR_PAD)) -- goto reporter_nest_cancel; -- if (reporter->ops->recover && -- nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, -- reporter->auto_recover)) -- goto reporter_nest_cancel; -- if (reporter->dump_fmsg && -- nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS, -- jiffies_to_msecs(reporter->dump_ts), -- DEVLINK_ATTR_PAD)) -- goto reporter_nest_cancel; -- if (reporter->dump_fmsg && -- nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, -- reporter->dump_real_ts, DEVLINK_ATTR_PAD)) -- goto reporter_nest_cancel; -- if (reporter->ops->dump && -- nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, -- reporter->auto_dump)) -- goto reporter_nest_cancel; -- -- nla_nest_end(msg, reporter_attr); -- genlmsg_end(msg, hdr); -- return 0; -- --reporter_nest_cancel: -- nla_nest_end(msg, reporter_attr); --genlmsg_cancel: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static void devlink_recover_notify(struct devlink_health_reporter *reporter, -- enum devlink_command cmd) --{ -- struct devlink *devlink = reporter->devlink; -- struct sk_buff *msg; -- int err; -- -- WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER); -- WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)); -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, -- 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --void --devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter) --{ -- reporter->recovery_count++; -- reporter->last_recovery_ts = jiffies; --} --EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done); -- --static int --devlink_health_reporter_recover(struct devlink_health_reporter *reporter, -- void *priv_ctx, struct netlink_ext_ack *extack) --{ -- int err; -- -- if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY) -- return 0; -- -- if (!reporter->ops->recover) -- return -EOPNOTSUPP; -- -- err = reporter->ops->recover(reporter, priv_ctx, extack); -- if (err) -- return err; -- -- devlink_health_reporter_recovery_done(reporter); -- reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY; -- devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); -- -- return 0; --} -- --static void --devlink_health_dump_clear(struct devlink_health_reporter *reporter) --{ -- if (!reporter->dump_fmsg) -- return; -- devlink_fmsg_free(reporter->dump_fmsg); -- reporter->dump_fmsg = NULL; --} -- --static int devlink_health_do_dump(struct devlink_health_reporter *reporter, -- void *priv_ctx, -- struct netlink_ext_ack *extack) --{ -- int err; -- -- if (!reporter->ops->dump) -- return 0; -- -- if (reporter->dump_fmsg) -- return 0; -- -- reporter->dump_fmsg = devlink_fmsg_alloc(); -- if (!reporter->dump_fmsg) { -- err = -ENOMEM; -- return err; -- } -- -- err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg); -- if (err) -- goto dump_err; -- -- err = reporter->ops->dump(reporter, reporter->dump_fmsg, -- priv_ctx, extack); -- if (err) -- goto dump_err; -- -- err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg); -- if (err) -- goto dump_err; -- -- reporter->dump_ts = jiffies; -- reporter->dump_real_ts = ktime_get_real_ns(); -- -- return 0; -- --dump_err: -- devlink_health_dump_clear(reporter); -- return err; --} -- --int devlink_health_report(struct devlink_health_reporter *reporter, -- const char *msg, void *priv_ctx) --{ -- enum devlink_health_reporter_state prev_health_state; -- struct devlink *devlink = reporter->devlink; -- unsigned long recover_ts_threshold; -- int ret; -- -- /* write a log message of the current error */ -- WARN_ON(!msg); -- trace_devlink_health_report(devlink, reporter->ops->name, msg); -- reporter->error_count++; -- prev_health_state = reporter->health_state; -- reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; -- devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); -- -- /* abort if the previous error wasn't recovered */ -- recover_ts_threshold = reporter->last_recovery_ts + -- msecs_to_jiffies(reporter->graceful_period); -- if (reporter->auto_recover && -- (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY || -- (reporter->last_recovery_ts && reporter->recovery_count && -- time_is_after_jiffies(recover_ts_threshold)))) { -- trace_devlink_health_recover_aborted(devlink, -- reporter->ops->name, -- reporter->health_state, -- jiffies - -- reporter->last_recovery_ts); -- return -ECANCELED; -- } -- -- reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; -- -- if (reporter->auto_dump) { -- mutex_lock(&reporter->dump_lock); -- /* store current dump of current error, for later analysis */ -- devlink_health_do_dump(reporter, priv_ctx, NULL); -- mutex_unlock(&reporter->dump_lock); -- } -- -- if (!reporter->auto_recover) -- return 0; -- -- devl_lock(devlink); -- ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL); -- devl_unlock(devlink); -- -- return ret; --} --EXPORT_SYMBOL_GPL(devlink_health_report); -- --static struct devlink_health_reporter * --devlink_health_reporter_get_from_attrs(struct devlink *devlink, -- struct nlattr **attrs) --{ -- struct devlink_health_reporter *reporter; -- struct devlink_port *devlink_port; -- char *reporter_name; -- -- if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]) -- return NULL; -- -- reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]); -- devlink_port = devlink_port_get_from_attrs(devlink, attrs); -- if (IS_ERR(devlink_port)) { -- mutex_lock(&devlink->reporters_lock); -- reporter = devlink_health_reporter_find_by_name(devlink, reporter_name); -- if (reporter) -- refcount_inc(&reporter->refcount); -- mutex_unlock(&devlink->reporters_lock); -- } else { -- mutex_lock(&devlink_port->reporters_lock); -- reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name); -- if (reporter) -- refcount_inc(&reporter->refcount); -- mutex_unlock(&devlink_port->reporters_lock); -- } -- -- return reporter; --} -- --static struct devlink_health_reporter * --devlink_health_reporter_get_from_info(struct devlink *devlink, -- struct genl_info *info) --{ -- return devlink_health_reporter_get_from_attrs(devlink, info->attrs); --} -- --static struct devlink_health_reporter * --devlink_health_reporter_get_from_cb(struct netlink_callback *cb) --{ -- const struct genl_dumpit_info *info = genl_dumpit_info(cb); -- struct devlink_health_reporter *reporter; -- struct nlattr **attrs = info->attrs; -- struct devlink *devlink; -- -- devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); -- if (IS_ERR(devlink)) -- return NULL; -- -- reporter = devlink_health_reporter_get_from_attrs(devlink, attrs); -- devlink_put(devlink); -- return reporter; --} -- --void --devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, -- enum devlink_health_reporter_state state) --{ -- if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY && -- state != DEVLINK_HEALTH_REPORTER_STATE_ERROR)) -- return; -- -- if (reporter->health_state == state) -- return; -- -- reporter->health_state = state; -- trace_devlink_health_reporter_state_update(reporter->devlink, -- reporter->ops->name, state); -- devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); --} --EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update); -- --static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_health_reporter *reporter; -- struct sk_buff *msg; -- int err; -- -- reporter = devlink_health_reporter_get_from_info(devlink, info); -- if (!reporter) -- return -EINVAL; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) { -- err = -ENOMEM; -- goto out; -- } -- -- err = devlink_nl_health_reporter_fill(msg, reporter, -- DEVLINK_CMD_HEALTH_REPORTER_GET, -- info->snd_portid, info->snd_seq, -- 0); -- if (err) { -- nlmsg_free(msg); -- goto out; -- } -- -- err = genlmsg_reply(msg, info); --out: -- devlink_health_reporter_put(reporter); -- return err; --} -- --static int --devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink_health_reporter *reporter; -- struct devlink_port *port; -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- mutex_lock(&devlink->reporters_lock); -- list_for_each_entry(reporter, &devlink->reporter_list, -- list) { -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_health_reporter_fill( -- msg, reporter, DEVLINK_CMD_HEALTH_REPORTER_GET, -- NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, -- NLM_F_MULTI); -- if (err) { -- mutex_unlock(&devlink->reporters_lock); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- mutex_unlock(&devlink->reporters_lock); -- devlink_put(devlink); -- } -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- devl_lock(devlink); -- list_for_each_entry(port, &devlink->port_list, list) { -- mutex_lock(&port->reporters_lock); -- list_for_each_entry(reporter, &port->reporter_list, list) { -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_health_reporter_fill( -- msg, reporter, -- DEVLINK_CMD_HEALTH_REPORTER_GET, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, NLM_F_MULTI); -- if (err) { -- mutex_unlock(&port->reporters_lock); -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- mutex_unlock(&port->reporters_lock); -- } -- devl_unlock(devlink); -- devlink_put(devlink); -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static int --devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_health_reporter *reporter; -- int err; -- -- reporter = devlink_health_reporter_get_from_info(devlink, info); -- if (!reporter) -- return -EINVAL; -- -- if (!reporter->ops->recover && -- (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] || -- info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) { -- err = -EOPNOTSUPP; -- goto out; -- } -- if (!reporter->ops->dump && -- info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) { -- err = -EOPNOTSUPP; -- goto out; -- } -- -- if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]) -- reporter->graceful_period = -- nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]); -- -- if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]) -- reporter->auto_recover = -- nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]); -- -- if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) -- reporter->auto_dump = -- nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]); -- -- devlink_health_reporter_put(reporter); -- return 0; --out: -- devlink_health_reporter_put(reporter); -- return err; --} -- --static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_health_reporter *reporter; -- int err; -- -- reporter = devlink_health_reporter_get_from_info(devlink, info); -- if (!reporter) -- return -EINVAL; -- -- err = devlink_health_reporter_recover(reporter, NULL, info->extack); -- -- devlink_health_reporter_put(reporter); -- return err; --} -- --static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_health_reporter *reporter; -- struct devlink_fmsg *fmsg; -- int err; -- -- reporter = devlink_health_reporter_get_from_info(devlink, info); -- if (!reporter) -- return -EINVAL; -- -- if (!reporter->ops->diagnose) { -- devlink_health_reporter_put(reporter); -- return -EOPNOTSUPP; -- } -- -- fmsg = devlink_fmsg_alloc(); -- if (!fmsg) { -- devlink_health_reporter_put(reporter); -- return -ENOMEM; -- } -- -- err = devlink_fmsg_obj_nest_start(fmsg); -- if (err) -- goto out; -- -- err = reporter->ops->diagnose(reporter, fmsg, info->extack); -- if (err) -- goto out; -- -- err = devlink_fmsg_obj_nest_end(fmsg); -- if (err) -- goto out; -- -- err = devlink_fmsg_snd(fmsg, info, -- DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0); -- --out: -- devlink_fmsg_free(fmsg); -- devlink_health_reporter_put(reporter); -- return err; --} -- --static int --devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb, -- struct netlink_callback *cb) --{ -- struct devlink_health_reporter *reporter; -- u64 start = cb->args[0]; -- int err; -- -- reporter = devlink_health_reporter_get_from_cb(cb); -- if (!reporter) -- return -EINVAL; -- -- if (!reporter->ops->dump) { -- err = -EOPNOTSUPP; -- goto out; -- } -- mutex_lock(&reporter->dump_lock); -- if (!start) { -- err = devlink_health_do_dump(reporter, NULL, cb->extack); -- if (err) -- goto unlock; -- cb->args[1] = reporter->dump_ts; -- } -- if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) { -- NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry"); -- err = -EAGAIN; -- goto unlock; -- } -- -- err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb, -- DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET); --unlock: -- mutex_unlock(&reporter->dump_lock); --out: -- devlink_health_reporter_put(reporter); -- return err; --} -- --static int --devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_health_reporter *reporter; -- -- reporter = devlink_health_reporter_get_from_info(devlink, info); -- if (!reporter) -- return -EINVAL; -- -- if (!reporter->ops->dump) { -- devlink_health_reporter_put(reporter); -- return -EOPNOTSUPP; -- } -- -- mutex_lock(&reporter->dump_lock); -- devlink_health_dump_clear(reporter); -- mutex_unlock(&reporter->dump_lock); -- devlink_health_reporter_put(reporter); -- return 0; --} -- --static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_health_reporter *reporter; -- int err; -- -- reporter = devlink_health_reporter_get_from_info(devlink, info); -- if (!reporter) -- return -EINVAL; -- -- if (!reporter->ops->test) { -- devlink_health_reporter_put(reporter); -- return -EOPNOTSUPP; -- } -- -- err = reporter->ops->test(reporter, info->extack); -- -- devlink_health_reporter_put(reporter); -- return err; --} -- --struct devlink_stats { -- u64_stats_t rx_bytes; -- u64_stats_t rx_packets; -- struct u64_stats_sync syncp; --}; -- --/** -- * struct devlink_trap_policer_item - Packet trap policer attributes. -- * @policer: Immutable packet trap policer attributes. -- * @rate: Rate in packets / sec. -- * @burst: Burst size in packets. -- * @list: trap_policer_list member. -- * -- * Describes packet trap policer attributes. Created by devlink during trap -- * policer registration. -- */ --struct devlink_trap_policer_item { -- const struct devlink_trap_policer *policer; -- u64 rate; -- u64 burst; -- struct list_head list; --}; -- --/** -- * struct devlink_trap_group_item - Packet trap group attributes. -- * @group: Immutable packet trap group attributes. -- * @policer_item: Associated policer item. Can be NULL. -- * @list: trap_group_list member. -- * @stats: Trap group statistics. -- * -- * Describes packet trap group attributes. Created by devlink during trap -- * group registration. -- */ --struct devlink_trap_group_item { -- const struct devlink_trap_group *group; -- struct devlink_trap_policer_item *policer_item; -- struct list_head list; -- struct devlink_stats __percpu *stats; --}; -- --/** -- * struct devlink_trap_item - Packet trap attributes. -- * @trap: Immutable packet trap attributes. -- * @group_item: Associated group item. -- * @list: trap_list member. -- * @action: Trap action. -- * @stats: Trap statistics. -- * @priv: Driver private information. -- * -- * Describes both mutable and immutable packet trap attributes. Created by -- * devlink during trap registration and used for all trap related operations. -- */ --struct devlink_trap_item { -- const struct devlink_trap *trap; -- struct devlink_trap_group_item *group_item; -- struct list_head list; -- enum devlink_trap_action action; -- struct devlink_stats __percpu *stats; -- void *priv; --}; -- --static struct devlink_trap_policer_item * --devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id) --{ -- struct devlink_trap_policer_item *policer_item; -- -- list_for_each_entry(policer_item, &devlink->trap_policer_list, list) { -- if (policer_item->policer->id == id) -- return policer_item; -- } -- -- return NULL; --} -- --static struct devlink_trap_item * --devlink_trap_item_lookup(struct devlink *devlink, const char *name) --{ -- struct devlink_trap_item *trap_item; -- -- list_for_each_entry(trap_item, &devlink->trap_list, list) { -- if (!strcmp(trap_item->trap->name, name)) -- return trap_item; -- } -- -- return NULL; --} -- --static struct devlink_trap_item * --devlink_trap_item_get_from_info(struct devlink *devlink, -- struct genl_info *info) --{ -- struct nlattr *attr; -- -- if (!info->attrs[DEVLINK_ATTR_TRAP_NAME]) -- return NULL; -- attr = info->attrs[DEVLINK_ATTR_TRAP_NAME]; -- -- return devlink_trap_item_lookup(devlink, nla_data(attr)); --} -- --static int --devlink_trap_action_get_from_info(struct genl_info *info, -- enum devlink_trap_action *p_trap_action) --{ -- u8 val; -- -- val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]); -- switch (val) { -- case DEVLINK_TRAP_ACTION_DROP: -- case DEVLINK_TRAP_ACTION_TRAP: -- case DEVLINK_TRAP_ACTION_MIRROR: -- *p_trap_action = val; -- break; -- default: -- return -EINVAL; -- } -- -- return 0; --} -- --static int devlink_trap_metadata_put(struct sk_buff *msg, -- const struct devlink_trap *trap) --{ -- struct nlattr *attr; -- -- attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA); -- if (!attr) -- return -EMSGSIZE; -- -- if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) && -- nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT)) -- goto nla_put_failure; -- if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) && -- nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE)) -- goto nla_put_failure; -- -- nla_nest_end(msg, attr); -- -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, attr); -- return -EMSGSIZE; --} -- --static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats, -- struct devlink_stats *stats) --{ -- int i; -- -- memset(stats, 0, sizeof(*stats)); -- for_each_possible_cpu(i) { -- struct devlink_stats *cpu_stats; -- u64 rx_packets, rx_bytes; -- unsigned int start; -- -- cpu_stats = per_cpu_ptr(trap_stats, i); -- do { -- start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); -- rx_packets = u64_stats_read(&cpu_stats->rx_packets); -- rx_bytes = u64_stats_read(&cpu_stats->rx_bytes); -- } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); -- -- u64_stats_add(&stats->rx_packets, rx_packets); -- u64_stats_add(&stats->rx_bytes, rx_bytes); -- } --} -- --static int --devlink_trap_group_stats_put(struct sk_buff *msg, -- struct devlink_stats __percpu *trap_stats) --{ -- struct devlink_stats stats; -- struct nlattr *attr; -- -- devlink_trap_stats_read(trap_stats, &stats); -- -- attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); -- if (!attr) -- return -EMSGSIZE; -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, -- u64_stats_read(&stats.rx_packets), -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, -- u64_stats_read(&stats.rx_bytes), -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- nla_nest_end(msg, attr); -- -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, attr); -- return -EMSGSIZE; --} -- --static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink, -- const struct devlink_trap_item *trap_item) --{ -- struct devlink_stats stats; -- struct nlattr *attr; -- u64 drops = 0; -- int err; -- -- if (devlink->ops->trap_drop_counter_get) { -- err = devlink->ops->trap_drop_counter_get(devlink, -- trap_item->trap, -- &drops); -- if (err) -- return err; -- } -- -- devlink_trap_stats_read(trap_item->stats, &stats); -- -- attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); -- if (!attr) -- return -EMSGSIZE; -- -- if (devlink->ops->trap_drop_counter_get && -- nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, -- u64_stats_read(&stats.rx_packets), -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, -- u64_stats_read(&stats.rx_bytes), -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- nla_nest_end(msg, attr); -- -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, attr); -- return -EMSGSIZE; --} -- --static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink, -- const struct devlink_trap_item *trap_item, -- enum devlink_command cmd, u32 portid, u32 seq, -- int flags) --{ -- struct devlink_trap_group_item *group_item = trap_item->group_item; -- void *hdr; -- int err; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- -- if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, -- group_item->group->name)) -- goto nla_put_failure; -- -- if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name)) -- goto nla_put_failure; -- -- if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type)) -- goto nla_put_failure; -- -- if (trap_item->trap->generic && -- nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) -- goto nla_put_failure; -- -- if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action)) -- goto nla_put_failure; -- -- err = devlink_trap_metadata_put(msg, trap_item->trap); -- if (err) -- goto nla_put_failure; -- -- err = devlink_trap_stats_put(msg, devlink, trap_item); -- if (err) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct netlink_ext_ack *extack = info->extack; -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_trap_item *trap_item; -- struct sk_buff *msg; -- int err; -- -- if (list_empty(&devlink->trap_list)) -- return -EOPNOTSUPP; -- -- trap_item = devlink_trap_item_get_from_info(devlink, info); -- if (!trap_item) { -- NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); -- return -ENOENT; -- } -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_trap_fill(msg, devlink, trap_item, -- DEVLINK_CMD_TRAP_NEW, info->snd_portid, -- info->snd_seq, 0); -- if (err) -- goto err_trap_fill; -- -- return genlmsg_reply(msg, info); -- --err_trap_fill: -- nlmsg_free(msg); -- return err; --} -- --static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- struct devlink_trap_item *trap_item; -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- devl_lock(devlink); -- list_for_each_entry(trap_item, &devlink->trap_list, list) { -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_trap_fill(msg, devlink, trap_item, -- DEVLINK_CMD_TRAP_NEW, -- NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI); -- if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- devl_unlock(devlink); -- devlink_put(devlink); -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static int __devlink_trap_action_set(struct devlink *devlink, -- struct devlink_trap_item *trap_item, -- enum devlink_trap_action trap_action, -- struct netlink_ext_ack *extack) --{ -- int err; -- -- if (trap_item->action != trap_action && -- trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) { -- NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping"); -- return 0; -- } -- -- err = devlink->ops->trap_action_set(devlink, trap_item->trap, -- trap_action, extack); -- if (err) -- return err; -- -- trap_item->action = trap_action; -- -- return 0; --} -- --static int devlink_trap_action_set(struct devlink *devlink, -- struct devlink_trap_item *trap_item, -- struct genl_info *info) --{ -- enum devlink_trap_action trap_action; -- int err; -- -- if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) -- return 0; -- -- err = devlink_trap_action_get_from_info(info, &trap_action); -- if (err) { -- NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); -- return -EINVAL; -- } -- -- return __devlink_trap_action_set(devlink, trap_item, trap_action, -- info->extack); --} -- --static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct netlink_ext_ack *extack = info->extack; -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_trap_item *trap_item; -- -- if (list_empty(&devlink->trap_list)) -- return -EOPNOTSUPP; -- -- trap_item = devlink_trap_item_get_from_info(devlink, info); -- if (!trap_item) { -- NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); -- return -ENOENT; -- } -- -- return devlink_trap_action_set(devlink, trap_item, info); --} -- --static struct devlink_trap_group_item * --devlink_trap_group_item_lookup(struct devlink *devlink, const char *name) --{ -- struct devlink_trap_group_item *group_item; -- -- list_for_each_entry(group_item, &devlink->trap_group_list, list) { -- if (!strcmp(group_item->group->name, name)) -- return group_item; -- } -- -- return NULL; --} -- --static struct devlink_trap_group_item * --devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id) --{ -- struct devlink_trap_group_item *group_item; -- -- list_for_each_entry(group_item, &devlink->trap_group_list, list) { -- if (group_item->group->id == id) -- return group_item; -- } -- -- return NULL; --} -- --static struct devlink_trap_group_item * --devlink_trap_group_item_get_from_info(struct devlink *devlink, -- struct genl_info *info) --{ -- char *name; -- -- if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]) -- return NULL; -- name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]); -- -- return devlink_trap_group_item_lookup(devlink, name); --} -- --static int --devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink, -- const struct devlink_trap_group_item *group_item, -- enum devlink_command cmd, u32 portid, u32 seq, -- int flags) --{ -- void *hdr; -- int err; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- -- if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, -- group_item->group->name)) -- goto nla_put_failure; -- -- if (group_item->group->generic && -- nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) -- goto nla_put_failure; -- -- if (group_item->policer_item && -- nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, -- group_item->policer_item->policer->id)) -- goto nla_put_failure; -- -- err = devlink_trap_group_stats_put(msg, group_item->stats); -- if (err) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct netlink_ext_ack *extack = info->extack; -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_trap_group_item *group_item; -- struct sk_buff *msg; -- int err; -- -- if (list_empty(&devlink->trap_group_list)) -- return -EOPNOTSUPP; -- -- group_item = devlink_trap_group_item_get_from_info(devlink, info); -- if (!group_item) { -- NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); -- return -ENOENT; -- } -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_trap_group_fill(msg, devlink, group_item, -- DEVLINK_CMD_TRAP_GROUP_NEW, -- info->snd_portid, info->snd_seq, 0); -- if (err) -- goto err_trap_group_fill; -- -- return genlmsg_reply(msg, info); -- --err_trap_group_fill: -- nlmsg_free(msg); -- return err; --} -- --static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW; -- struct devlink_trap_group_item *group_item; -- u32 portid = NETLINK_CB(cb->skb).portid; -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- devl_lock(devlink); -- list_for_each_entry(group_item, &devlink->trap_group_list, -- list) { -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_trap_group_fill(msg, devlink, -- group_item, cmd, -- portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI); -- if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- devl_unlock(devlink); -- devlink_put(devlink); -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static int --__devlink_trap_group_action_set(struct devlink *devlink, -- struct devlink_trap_group_item *group_item, -- enum devlink_trap_action trap_action, -- struct netlink_ext_ack *extack) --{ -- const char *group_name = group_item->group->name; -- struct devlink_trap_item *trap_item; -- int err; -- -- if (devlink->ops->trap_group_action_set) { -- err = devlink->ops->trap_group_action_set(devlink, group_item->group, -- trap_action, extack); -- if (err) -- return err; -- -- list_for_each_entry(trap_item, &devlink->trap_list, list) { -- if (strcmp(trap_item->group_item->group->name, group_name)) -- continue; -- if (trap_item->action != trap_action && -- trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) -- continue; -- trap_item->action = trap_action; -- } -- -- return 0; -- } -- -- list_for_each_entry(trap_item, &devlink->trap_list, list) { -- if (strcmp(trap_item->group_item->group->name, group_name)) -- continue; -- err = __devlink_trap_action_set(devlink, trap_item, -- trap_action, extack); -- if (err) -- return err; -- } -- -- return 0; --} -- --static int --devlink_trap_group_action_set(struct devlink *devlink, -- struct devlink_trap_group_item *group_item, -- struct genl_info *info, bool *p_modified) --{ -- enum devlink_trap_action trap_action; -- int err; -- -- if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) -- return 0; -- -- err = devlink_trap_action_get_from_info(info, &trap_action); -- if (err) { -- NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); -- return -EINVAL; -- } -- -- err = __devlink_trap_group_action_set(devlink, group_item, trap_action, -- info->extack); -- if (err) -- return err; -- -- *p_modified = true; -- -- return 0; --} -- --static int devlink_trap_group_set(struct devlink *devlink, -- struct devlink_trap_group_item *group_item, -- struct genl_info *info) --{ -- struct devlink_trap_policer_item *policer_item; -- struct netlink_ext_ack *extack = info->extack; -- const struct devlink_trap_policer *policer; -- struct nlattr **attrs = info->attrs; -- int err; -- -- if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) -- return 0; -- -- if (!devlink->ops->trap_group_set) -- return -EOPNOTSUPP; -- -- policer_item = group_item->policer_item; -- if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) { -- u32 policer_id; -- -- policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); -- policer_item = devlink_trap_policer_item_lookup(devlink, -- policer_id); -- if (policer_id && !policer_item) { -- NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); -- return -ENOENT; -- } -- } -- policer = policer_item ? policer_item->policer : NULL; -- -- err = devlink->ops->trap_group_set(devlink, group_item->group, policer, -- extack); -- if (err) -- return err; -- -- group_item->policer_item = policer_item; -- -- return 0; --} -- --static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct netlink_ext_ack *extack = info->extack; -- struct devlink *devlink = info->user_ptr[0]; -- struct devlink_trap_group_item *group_item; -- bool modified = false; -- int err; -- -- if (list_empty(&devlink->trap_group_list)) -- return -EOPNOTSUPP; -- -- group_item = devlink_trap_group_item_get_from_info(devlink, info); -- if (!group_item) { -- NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); -- return -ENOENT; -- } -- -- err = devlink_trap_group_action_set(devlink, group_item, info, -- &modified); -- if (err) -- return err; -- -- err = devlink_trap_group_set(devlink, group_item, info); -- if (err) -- goto err_trap_group_set; -- -- return 0; -- --err_trap_group_set: -- if (modified) -- NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already"); -- return err; --} -- --static struct devlink_trap_policer_item * --devlink_trap_policer_item_get_from_info(struct devlink *devlink, -- struct genl_info *info) --{ -- u32 id; -- -- if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) -- return NULL; -- id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); -- -- return devlink_trap_policer_item_lookup(devlink, id); --} -- --static int --devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink, -- const struct devlink_trap_policer *policer) --{ -- struct nlattr *attr; -- u64 drops; -- int err; -- -- if (!devlink->ops->trap_policer_counter_get) -- return 0; -- -- err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops); -- if (err) -- return err; -- -- attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); -- if (!attr) -- return -EMSGSIZE; -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, -- DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- nla_nest_end(msg, attr); -- -- return 0; -- --nla_put_failure: -- nla_nest_cancel(msg, attr); -- return -EMSGSIZE; --} -- --static int --devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink, -- const struct devlink_trap_policer_item *policer_item, -- enum devlink_command cmd, u32 portid, u32 seq, -- int flags) --{ -- void *hdr; -- int err; -- -- hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -- if (!hdr) -- return -EMSGSIZE; -- -- if (devlink_nl_put_handle(msg, devlink)) -- goto nla_put_failure; -- -- if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, -- policer_item->policer->id)) -- goto nla_put_failure; -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE, -- policer_item->rate, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST, -- policer_item->burst, DEVLINK_ATTR_PAD)) -- goto nla_put_failure; -- -- err = devlink_trap_policer_stats_put(msg, devlink, -- policer_item->policer); -- if (err) -- goto nla_put_failure; -- -- genlmsg_end(msg, hdr); -- -- return 0; -- --nla_put_failure: -- genlmsg_cancel(msg, hdr); -- return -EMSGSIZE; --} -- --static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_trap_policer_item *policer_item; -- struct netlink_ext_ack *extack = info->extack; -- struct devlink *devlink = info->user_ptr[0]; -- struct sk_buff *msg; -- int err; -- -- if (list_empty(&devlink->trap_policer_list)) -- return -EOPNOTSUPP; -- -- policer_item = devlink_trap_policer_item_get_from_info(devlink, info); -- if (!policer_item) { -- NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); -- return -ENOENT; -- } -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return -ENOMEM; -- -- err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, -- DEVLINK_CMD_TRAP_POLICER_NEW, -- info->snd_portid, info->snd_seq, 0); -- if (err) -- goto err_trap_policer_fill; -- -- return genlmsg_reply(msg, info); -- --err_trap_policer_fill: -- nlmsg_free(msg); -- return err; --} -- --static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg, -- struct netlink_callback *cb) --{ -- enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW; -- struct devlink_trap_policer_item *policer_item; -- u32 portid = NETLINK_CB(cb->skb).portid; -- struct devlink *devlink; -- int start = cb->args[0]; -- unsigned long index; -- int idx = 0; -- int err; -- -- devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -- devl_lock(devlink); -- list_for_each_entry(policer_item, &devlink->trap_policer_list, -- list) { -- if (idx < start) { -- idx++; -- continue; -- } -- err = devlink_nl_trap_policer_fill(msg, devlink, -- policer_item, cmd, -- portid, -- cb->nlh->nlmsg_seq, -- NLM_F_MULTI); -- if (err) { -- devl_unlock(devlink); -- devlink_put(devlink); -- goto out; -- } -- idx++; -- } -- devl_unlock(devlink); -- devlink_put(devlink); -- } --out: -- cb->args[0] = idx; -- return msg->len; --} -- --static int --devlink_trap_policer_set(struct devlink *devlink, -- struct devlink_trap_policer_item *policer_item, -- struct genl_info *info) --{ -- struct netlink_ext_ack *extack = info->extack; -- struct nlattr **attrs = info->attrs; -- u64 rate, burst; -- int err; -- -- rate = policer_item->rate; -- burst = policer_item->burst; -- -- if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]) -- rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]); -- -- if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]) -- burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]); -- -- if (rate < policer_item->policer->min_rate) { -- NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit"); -- return -EINVAL; -- } -- -- if (rate > policer_item->policer->max_rate) { -- NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit"); -- return -EINVAL; -- } -- -- if (burst < policer_item->policer->min_burst) { -- NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit"); -- return -EINVAL; -- } -- -- if (burst > policer_item->policer->max_burst) { -- NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit"); -- return -EINVAL; -- } -- -- err = devlink->ops->trap_policer_set(devlink, policer_item->policer, -- rate, burst, info->extack); -- if (err) -- return err; -- -- policer_item->rate = rate; -- policer_item->burst = burst; -- -- return 0; --} -- --static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb, -- struct genl_info *info) --{ -- struct devlink_trap_policer_item *policer_item; -- struct netlink_ext_ack *extack = info->extack; -- struct devlink *devlink = info->user_ptr[0]; -- -- if (list_empty(&devlink->trap_policer_list)) -- return -EOPNOTSUPP; -- -- if (!devlink->ops->trap_policer_set) -- return -EOPNOTSUPP; -- -- policer_item = devlink_trap_policer_item_get_from_info(devlink, info); -- if (!policer_item) { -- NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); -- return -ENOENT; -- } -- -- return devlink_trap_policer_set(devlink, policer_item, info); --} -- --static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { -- [DEVLINK_ATTR_UNSPEC] = { .strict_start_type = -- DEVLINK_ATTR_TRAP_POLICER_ID }, -- [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO, -- DEVLINK_PORT_TYPE_IB), -- [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 }, -- [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, -- [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY, -- DEVLINK_ESWITCH_MODE_SWITCHDEV), -- [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, -- [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, -- [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 }, -- [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 }, -- [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 }, -- [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] = -- NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS), -- [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 }, -- [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 }, -- [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 }, -- [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED }, -- [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT, -- DEVLINK_RELOAD_ACTION_MAX), -- [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK), -- [DEVLINK_ATTR_PORT_FLAVOUR] = { .type = NLA_U16 }, -- [DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16 }, -- [DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_RATE_TYPE] = { .type = NLA_U16 }, -- [DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64 }, -- [DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64 }, -- [DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 }, -- [DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING }, -- [DEVLINK_ATTR_SELFTESTS] = { .type = NLA_NESTED }, --}; -- --static const struct genl_small_ops devlink_nl_ops[] = { -- { -- .cmd = DEVLINK_CMD_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_get_doit, -- .dumpit = devlink_nl_cmd_get_dumpit, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_PORT_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_port_get_doit, -- .dumpit = devlink_nl_cmd_port_get_dumpit, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_PORT_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_port_set_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_RATE_GET, -- .doit = devlink_nl_cmd_rate_get_doit, -- .dumpit = devlink_nl_cmd_rate_get_dumpit, -- .internal_flags = DEVLINK_NL_FLAG_NEED_RATE, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_RATE_SET, -- .doit = devlink_nl_cmd_rate_set_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_RATE, -- }, -- { -- .cmd = DEVLINK_CMD_RATE_NEW, -- .doit = devlink_nl_cmd_rate_new_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_RATE_DEL, -- .doit = devlink_nl_cmd_rate_del_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE, -- }, -- { -- .cmd = DEVLINK_CMD_PORT_SPLIT, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_port_split_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_PORT_UNSPLIT, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_port_unsplit_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_PORT_NEW, -- .doit = devlink_nl_cmd_port_new_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_PORT_DEL, -- .doit = devlink_nl_cmd_port_del_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_LINECARD_GET, -- .doit = devlink_nl_cmd_linecard_get_doit, -- .dumpit = devlink_nl_cmd_linecard_get_dumpit, -- .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_LINECARD_SET, -- .doit = devlink_nl_cmd_linecard_set_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD, -- }, -- { -- .cmd = DEVLINK_CMD_SB_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_get_doit, -- .dumpit = devlink_nl_cmd_sb_get_dumpit, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_SB_POOL_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_pool_get_doit, -- .dumpit = devlink_nl_cmd_sb_pool_get_dumpit, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_SB_POOL_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_pool_set_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_port_pool_get_doit, -- .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_port_pool_set_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, -- .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_occ_snapshot_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_sb_occ_max_clear_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_ESWITCH_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_eswitch_get_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_ESWITCH_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_eswitch_set_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_dpipe_table_get, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_dpipe_entries_get, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_dpipe_headers_get, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_dpipe_table_counters_set, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_RESOURCE_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_resource_set, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_RESOURCE_DUMP, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_resource_dump, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_RELOAD, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_reload, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_PARAM_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_param_get_doit, -- .dumpit = devlink_nl_cmd_param_get_dumpit, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_PARAM_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_param_set_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_PORT_PARAM_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_port_param_get_doit, -- .dumpit = devlink_nl_cmd_port_param_get_dumpit, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_PORT_PARAM_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_port_param_set_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_REGION_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_region_get_doit, -- .dumpit = devlink_nl_cmd_region_get_dumpit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_REGION_NEW, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_region_new, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_REGION_DEL, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_region_del, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_REGION_READ, -- .validate = GENL_DONT_VALIDATE_STRICT | -- GENL_DONT_VALIDATE_DUMP_STRICT, -- .dumpit = devlink_nl_cmd_region_read_dumpit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_INFO_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_info_get_doit, -- .dumpit = devlink_nl_cmd_info_get_dumpit, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_health_reporter_get_doit, -- .dumpit = devlink_nl_cmd_health_reporter_get_dumpit, -- .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_health_reporter_set_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_health_reporter_recover_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_health_reporter_diagnose_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, -- .validate = GENL_DONT_VALIDATE_STRICT | -- GENL_DONT_VALIDATE_DUMP_STRICT, -- .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_health_reporter_dump_clear_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_health_reporter_test_doit, -- .flags = GENL_ADMIN_PERM, -- .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -- }, -- { -- .cmd = DEVLINK_CMD_FLASH_UPDATE, -- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -- .doit = devlink_nl_cmd_flash_update, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_TRAP_GET, -- .doit = devlink_nl_cmd_trap_get_doit, -- .dumpit = devlink_nl_cmd_trap_get_dumpit, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_TRAP_SET, -- .doit = devlink_nl_cmd_trap_set_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_TRAP_GROUP_GET, -- .doit = devlink_nl_cmd_trap_group_get_doit, -- .dumpit = devlink_nl_cmd_trap_group_get_dumpit, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_TRAP_GROUP_SET, -- .doit = devlink_nl_cmd_trap_group_set_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_TRAP_POLICER_GET, -- .doit = devlink_nl_cmd_trap_policer_get_doit, -- .dumpit = devlink_nl_cmd_trap_policer_get_dumpit, -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_TRAP_POLICER_SET, -- .doit = devlink_nl_cmd_trap_policer_set_doit, -- .flags = GENL_ADMIN_PERM, -- }, -- { -- .cmd = DEVLINK_CMD_SELFTESTS_GET, -- .doit = devlink_nl_cmd_selftests_get_doit, -- .dumpit = devlink_nl_cmd_selftests_get_dumpit -- /* can be retrieved by unprivileged users */ -- }, -- { -- .cmd = DEVLINK_CMD_SELFTESTS_RUN, -- .doit = devlink_nl_cmd_selftests_run, -- .flags = GENL_ADMIN_PERM, -- }, --}; -- --static struct genl_family devlink_nl_family __ro_after_init = { -- .name = DEVLINK_GENL_NAME, -- .version = DEVLINK_GENL_VERSION, -- .maxattr = DEVLINK_ATTR_MAX, -- .policy = devlink_nl_policy, -- .netnsok = true, -- .parallel_ops = true, -- .pre_doit = devlink_nl_pre_doit, -- .post_doit = devlink_nl_post_doit, -- .module = THIS_MODULE, -- .small_ops = devlink_nl_ops, -- .n_small_ops = ARRAY_SIZE(devlink_nl_ops), -- .resv_start_op = DEVLINK_CMD_SELFTESTS_RUN + 1, -- .mcgrps = devlink_nl_mcgrps, -- .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), --}; -- --static bool devlink_reload_actions_valid(const struct devlink_ops *ops) --{ -- const struct devlink_reload_combination *comb; -- int i; -- -- if (!devlink_reload_supported(ops)) { -- if (WARN_ON(ops->reload_actions)) -- return false; -- return true; -- } -- -- if (WARN_ON(!ops->reload_actions || -- ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || -- ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) -- return false; -- -- if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || -- ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) -- return false; -- -- for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { -- comb = &devlink_reload_invalid_combinations[i]; -- if (ops->reload_actions == BIT(comb->action) && -- ops->reload_limits == BIT(comb->limit)) -- return false; -- } -- return true; --} -- --/** -- * devlink_set_features - Set devlink supported features -- * -- * @devlink: devlink -- * @features: devlink support features -- * -- * This interface allows us to set reload ops separatelly from -- * the devlink_alloc. -- */ --void devlink_set_features(struct devlink *devlink, u64 features) --{ -- ASSERT_DEVLINK_NOT_REGISTERED(devlink); -- -- WARN_ON(features & DEVLINK_F_RELOAD && -- !devlink_reload_supported(devlink->ops)); -- devlink->features = features; --} --EXPORT_SYMBOL_GPL(devlink_set_features); -- --/** -- * devlink_alloc_ns - Allocate new devlink instance resources -- * in specific namespace -- * -- * @ops: ops -- * @priv_size: size of user private data -- * @net: net namespace -- * @dev: parent device -- * -- * Allocate new devlink instance resources, including devlink index -- * and name. -- */ --struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, -- size_t priv_size, struct net *net, -- struct device *dev) --{ -- struct devlink *devlink; -- static u32 last_id; -- int ret; -- -- WARN_ON(!ops || !dev); -- if (!devlink_reload_actions_valid(ops)) -- return NULL; -- -- devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); -- if (!devlink) -- return NULL; -- -- ret = xa_alloc_cyclic(&devlinks, &devlink->index, devlink, xa_limit_31b, -- &last_id, GFP_KERNEL); -- if (ret < 0) { -- kfree(devlink); -- return NULL; -- } -- -- devlink->dev = dev; -- devlink->ops = ops; -- xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC); -- write_pnet(&devlink->_net, net); -- INIT_LIST_HEAD(&devlink->port_list); -- INIT_LIST_HEAD(&devlink->rate_list); -- INIT_LIST_HEAD(&devlink->linecard_list); -- INIT_LIST_HEAD(&devlink->sb_list); -- INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); -- INIT_LIST_HEAD(&devlink->resource_list); -- INIT_LIST_HEAD(&devlink->param_list); -- INIT_LIST_HEAD(&devlink->region_list); -- INIT_LIST_HEAD(&devlink->reporter_list); -- INIT_LIST_HEAD(&devlink->trap_list); -- INIT_LIST_HEAD(&devlink->trap_group_list); -- INIT_LIST_HEAD(&devlink->trap_policer_list); -- lockdep_register_key(&devlink->lock_key); -- mutex_init(&devlink->lock); -- lockdep_set_class(&devlink->lock, &devlink->lock_key); -- mutex_init(&devlink->reporters_lock); -- mutex_init(&devlink->linecards_lock); -- refcount_set(&devlink->refcount, 1); -- init_completion(&devlink->comp); -- -- return devlink; --} --EXPORT_SYMBOL_GPL(devlink_alloc_ns); -- --static void --devlink_trap_policer_notify(struct devlink *devlink, -- const struct devlink_trap_policer_item *policer_item, -- enum devlink_command cmd); --static void --devlink_trap_group_notify(struct devlink *devlink, -- const struct devlink_trap_group_item *group_item, -- enum devlink_command cmd); --static void devlink_trap_notify(struct devlink *devlink, -- const struct devlink_trap_item *trap_item, -- enum devlink_command cmd); -- --static void devlink_notify_register(struct devlink *devlink) --{ -- struct devlink_trap_policer_item *policer_item; -- struct devlink_trap_group_item *group_item; -- struct devlink_param_item *param_item; -- struct devlink_trap_item *trap_item; -- struct devlink_port *devlink_port; -- struct devlink_linecard *linecard; -- struct devlink_rate *rate_node; -- struct devlink_region *region; -- -- devlink_notify(devlink, DEVLINK_CMD_NEW); -- list_for_each_entry(linecard, &devlink->linecard_list, list) -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- -- list_for_each_entry(devlink_port, &devlink->port_list, list) -- devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); -- -- list_for_each_entry(policer_item, &devlink->trap_policer_list, list) -- devlink_trap_policer_notify(devlink, policer_item, -- DEVLINK_CMD_TRAP_POLICER_NEW); -- -- list_for_each_entry(group_item, &devlink->trap_group_list, list) -- devlink_trap_group_notify(devlink, group_item, -- DEVLINK_CMD_TRAP_GROUP_NEW); -- -- list_for_each_entry(trap_item, &devlink->trap_list, list) -- devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); -- -- list_for_each_entry(rate_node, &devlink->rate_list, list) -- devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); -- -- list_for_each_entry(region, &devlink->region_list, list) -- devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); -- -- list_for_each_entry(param_item, &devlink->param_list, list) -- devlink_param_notify(devlink, 0, param_item, -- DEVLINK_CMD_PARAM_NEW); --} -- --static void devlink_notify_unregister(struct devlink *devlink) --{ -- struct devlink_trap_policer_item *policer_item; -- struct devlink_trap_group_item *group_item; -- struct devlink_param_item *param_item; -- struct devlink_trap_item *trap_item; -- struct devlink_port *devlink_port; -- struct devlink_rate *rate_node; -- struct devlink_region *region; -- -- list_for_each_entry_reverse(param_item, &devlink->param_list, list) -- devlink_param_notify(devlink, 0, param_item, -- DEVLINK_CMD_PARAM_DEL); -- -- list_for_each_entry_reverse(region, &devlink->region_list, list) -- devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); -- -- list_for_each_entry_reverse(rate_node, &devlink->rate_list, list) -- devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); -- -- list_for_each_entry_reverse(trap_item, &devlink->trap_list, list) -- devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); -- -- list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list) -- devlink_trap_group_notify(devlink, group_item, -- DEVLINK_CMD_TRAP_GROUP_DEL); -- list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list, -- list) -- devlink_trap_policer_notify(devlink, policer_item, -- DEVLINK_CMD_TRAP_POLICER_DEL); -- -- list_for_each_entry_reverse(devlink_port, &devlink->port_list, list) -- devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); -- devlink_notify(devlink, DEVLINK_CMD_DEL); --} -- --/** -- * devlink_register - Register devlink instance -- * -- * @devlink: devlink -- */ --void devlink_register(struct devlink *devlink) --{ -- ASSERT_DEVLINK_NOT_REGISTERED(devlink); -- /* Make sure that we are in .probe() routine */ -- -- xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED); -- devlink_notify_register(devlink); --} --EXPORT_SYMBOL_GPL(devlink_register); -- --/** -- * devlink_unregister - Unregister devlink instance -- * -- * @devlink: devlink -- */ --void devlink_unregister(struct devlink *devlink) --{ -- ASSERT_DEVLINK_REGISTERED(devlink); -- /* Make sure that we are in .remove() routine */ -- -- xa_set_mark(&devlinks, devlink->index, DEVLINK_UNREGISTERING); -- devlink_put(devlink); -- wait_for_completion(&devlink->comp); -- -- devlink_notify_unregister(devlink); -- xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED); -- xa_clear_mark(&devlinks, devlink->index, DEVLINK_UNREGISTERING); --} --EXPORT_SYMBOL_GPL(devlink_unregister); -- --/** -- * devlink_free - Free devlink instance resources -- * -- * @devlink: devlink -- */ --void devlink_free(struct devlink *devlink) --{ -- ASSERT_DEVLINK_NOT_REGISTERED(devlink); -- -- mutex_destroy(&devlink->linecards_lock); -- mutex_destroy(&devlink->reporters_lock); -- mutex_destroy(&devlink->lock); -- lockdep_unregister_key(&devlink->lock_key); -- WARN_ON(!list_empty(&devlink->trap_policer_list)); -- WARN_ON(!list_empty(&devlink->trap_group_list)); -- WARN_ON(!list_empty(&devlink->trap_list)); -- WARN_ON(!list_empty(&devlink->reporter_list)); -- WARN_ON(!list_empty(&devlink->region_list)); -- WARN_ON(!list_empty(&devlink->param_list)); -- WARN_ON(!list_empty(&devlink->resource_list)); -- WARN_ON(!list_empty(&devlink->dpipe_table_list)); -- WARN_ON(!list_empty(&devlink->sb_list)); -- WARN_ON(!list_empty(&devlink->rate_list)); -- WARN_ON(!list_empty(&devlink->linecard_list)); -- WARN_ON(!list_empty(&devlink->port_list)); -- -- xa_destroy(&devlink->snapshot_ids); -- xa_erase(&devlinks, devlink->index); -- -- kfree(devlink); --} --EXPORT_SYMBOL_GPL(devlink_free); -- --static void devlink_port_type_warn(struct work_struct *work) --{ -- struct devlink_port *port = container_of(to_delayed_work(work), -- struct devlink_port, -- type_warn_dw); -- dev_warn(port->devlink->dev, "Type was not set for devlink port."); --} -- --static bool devlink_port_type_should_warn(struct devlink_port *devlink_port) --{ -- /* Ignore CPU and DSA flavours. */ -- return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU && -- devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA && -- devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED; --} -- --#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600) -- --static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port) --{ -- if (!devlink_port_type_should_warn(devlink_port)) -- return; -- /* Schedule a work to WARN in case driver does not set port -- * type within timeout. -- */ -- schedule_delayed_work(&devlink_port->type_warn_dw, -- DEVLINK_PORT_TYPE_WARN_TIMEOUT); --} -- --static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port) --{ -- if (!devlink_port_type_should_warn(devlink_port)) -- return; -- cancel_delayed_work_sync(&devlink_port->type_warn_dw); --} -- --/** -- * devlink_port_init() - Init devlink port -- * -- * @devlink: devlink -- * @devlink_port: devlink port -- * -- * Initialize essencial stuff that is needed for functions -- * that may be called before devlink port registration. -- * Call to this function is optional and not needed -- * in case the driver does not use such functions. -- */ --void devlink_port_init(struct devlink *devlink, -- struct devlink_port *devlink_port) --{ -- if (devlink_port->initialized) -- return; -- devlink_port->devlink = devlink; -- INIT_LIST_HEAD(&devlink_port->region_list); -- devlink_port->initialized = true; --} --EXPORT_SYMBOL_GPL(devlink_port_init); -- --/** -- * devlink_port_fini() - Deinitialize devlink port -- * -- * @devlink_port: devlink port -- * -- * Deinitialize essencial stuff that is in use for functions -- * that may be called after devlink port unregistration. -- * Call to this function is optional and not needed -- * in case the driver does not use such functions. -- */ --void devlink_port_fini(struct devlink_port *devlink_port) --{ -- WARN_ON(!list_empty(&devlink_port->region_list)); --} --EXPORT_SYMBOL_GPL(devlink_port_fini); -- --/** -- * devl_port_register() - Register devlink port -- * -- * @devlink: devlink -- * @devlink_port: devlink port -- * @port_index: driver-specific numerical identifier of the port -- * -- * Register devlink port with provided port index. User can use -- * any indexing, even hw-related one. devlink_port structure -- * is convenient to be embedded inside user driver private structure. -- * Note that the caller should take care of zeroing the devlink_port -- * structure. -- */ --int devl_port_register(struct devlink *devlink, -- struct devlink_port *devlink_port, -- unsigned int port_index) --{ -- devl_assert_locked(devlink); -- -- if (devlink_port_index_exists(devlink, port_index)) -- return -EEXIST; -- -- ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -- -- devlink_port_init(devlink, devlink_port); -- devlink_port->registered = true; -- devlink_port->index = port_index; -- spin_lock_init(&devlink_port->type_lock); -- INIT_LIST_HEAD(&devlink_port->reporter_list); -- mutex_init(&devlink_port->reporters_lock); -- list_add_tail(&devlink_port->list, &devlink->port_list); -- -- INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn); -- devlink_port_type_warn_schedule(devlink_port); -- devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); -- return 0; --} --EXPORT_SYMBOL_GPL(devl_port_register); -- --/** -- * devlink_port_register - Register devlink port -- * -- * @devlink: devlink -- * @devlink_port: devlink port -- * @port_index: driver-specific numerical identifier of the port -- * -- * Register devlink port with provided port index. User can use -- * any indexing, even hw-related one. devlink_port structure -- * is convenient to be embedded inside user driver private structure. -- * Note that the caller should take care of zeroing the devlink_port -- * structure. -- * -- * Context: Takes and release devlink->lock . -- */ --int devlink_port_register(struct devlink *devlink, -- struct devlink_port *devlink_port, -- unsigned int port_index) --{ -- int err; -- -- devl_lock(devlink); -- err = devl_port_register(devlink, devlink_port, port_index); -- devl_unlock(devlink); -- return err; --} --EXPORT_SYMBOL_GPL(devlink_port_register); -- --/** -- * devl_port_unregister() - Unregister devlink port -- * -- * @devlink_port: devlink port -- */ --void devl_port_unregister(struct devlink_port *devlink_port) --{ -- lockdep_assert_held(&devlink_port->devlink->lock); -- -- devlink_port_type_warn_cancel(devlink_port); -- devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); -- list_del(&devlink_port->list); -- WARN_ON(!list_empty(&devlink_port->reporter_list)); -- mutex_destroy(&devlink_port->reporters_lock); -- devlink_port->registered = false; --} --EXPORT_SYMBOL_GPL(devl_port_unregister); -- --/** -- * devlink_port_unregister - Unregister devlink port -- * -- * @devlink_port: devlink port -- * -- * Context: Takes and release devlink->lock . -- */ --void devlink_port_unregister(struct devlink_port *devlink_port) --{ -- struct devlink *devlink = devlink_port->devlink; -- -- devl_lock(devlink); -- devl_port_unregister(devlink_port); -- devl_unlock(devlink); --} --EXPORT_SYMBOL_GPL(devlink_port_unregister); -- --static void __devlink_port_type_set(struct devlink_port *devlink_port, -- enum devlink_port_type type, -- void *type_dev) --{ -- ASSERT_DEVLINK_PORT_REGISTERED(devlink_port); -- -- devlink_port_type_warn_cancel(devlink_port); -- spin_lock_bh(&devlink_port->type_lock); -- devlink_port->type = type; -- devlink_port->type_dev = type_dev; -- spin_unlock_bh(&devlink_port->type_lock); -- devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); --} -- --static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port, -- struct net_device *netdev) --{ -- const struct net_device_ops *ops = netdev->netdev_ops; -- -- /* If driver registers devlink port, it should set devlink port -- * attributes accordingly so the compat functions are called -- * and the original ops are not used. -- */ -- if (ops->ndo_get_phys_port_name) { -- /* Some drivers use the same set of ndos for netdevs -- * that have devlink_port registered and also for -- * those who don't. Make sure that ndo_get_phys_port_name -- * returns -EOPNOTSUPP here in case it is defined. -- * Warn if not. -- */ -- char name[IFNAMSIZ]; -- int err; -- -- err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name)); -- WARN_ON(err != -EOPNOTSUPP); -- } -- if (ops->ndo_get_port_parent_id) { -- /* Some drivers use the same set of ndos for netdevs -- * that have devlink_port registered and also for -- * those who don't. Make sure that ndo_get_port_parent_id -- * returns -EOPNOTSUPP here in case it is defined. -- * Warn if not. -- */ -- struct netdev_phys_item_id ppid; -- int err; -- -- err = ops->ndo_get_port_parent_id(netdev, &ppid); -- WARN_ON(err != -EOPNOTSUPP); -- } --} -- --/** -- * devlink_port_type_eth_set - Set port type to Ethernet -- * -- * @devlink_port: devlink port -- * @netdev: related netdevice -- */ --void devlink_port_type_eth_set(struct devlink_port *devlink_port, -- struct net_device *netdev) --{ -- if (netdev) -- devlink_port_type_netdev_checks(devlink_port, netdev); -- else -- dev_warn(devlink_port->devlink->dev, -- "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n", -- devlink_port->index); -- -- __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev); --} --EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); -- --/** -- * devlink_port_type_ib_set - Set port type to InfiniBand -- * -- * @devlink_port: devlink port -- * @ibdev: related IB device -- */ --void devlink_port_type_ib_set(struct devlink_port *devlink_port, -- struct ib_device *ibdev) --{ -- __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev); --} --EXPORT_SYMBOL_GPL(devlink_port_type_ib_set); -- --/** -- * devlink_port_type_clear - Clear port type -- * -- * @devlink_port: devlink port -- */ --void devlink_port_type_clear(struct devlink_port *devlink_port) --{ -- __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL); -- devlink_port_type_warn_schedule(devlink_port); --} --EXPORT_SYMBOL_GPL(devlink_port_type_clear); -- --static int __devlink_port_attrs_set(struct devlink_port *devlink_port, -- enum devlink_port_flavour flavour) --{ -- struct devlink_port_attrs *attrs = &devlink_port->attrs; -- -- devlink_port->attrs_set = true; -- attrs->flavour = flavour; -- if (attrs->switch_id.id_len) { -- devlink_port->switch_port = true; -- if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN)) -- attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN; -- } else { -- devlink_port->switch_port = false; -- } -- return 0; --} -- --/** -- * devlink_port_attrs_set - Set port attributes -- * -- * @devlink_port: devlink port -- * @attrs: devlink port attrs -- */ --void devlink_port_attrs_set(struct devlink_port *devlink_port, -- struct devlink_port_attrs *attrs) --{ -- int ret; -- -- ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -- -- devlink_port->attrs = *attrs; -- ret = __devlink_port_attrs_set(devlink_port, attrs->flavour); -- if (ret) -- return; -- WARN_ON(attrs->splittable && attrs->split); --} --EXPORT_SYMBOL_GPL(devlink_port_attrs_set); -- --/** -- * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes -- * -- * @devlink_port: devlink port -- * @controller: associated controller number for the devlink port instance -- * @pf: associated PF for the devlink port instance -- * @external: indicates if the port is for an external controller -- */ --void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller, -- u16 pf, bool external) --{ -- struct devlink_port_attrs *attrs = &devlink_port->attrs; -- int ret; -- -- ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -- -- ret = __devlink_port_attrs_set(devlink_port, -- DEVLINK_PORT_FLAVOUR_PCI_PF); -- if (ret) -- return; -- attrs->pci_pf.controller = controller; -- attrs->pci_pf.pf = pf; -- attrs->pci_pf.external = external; --} --EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set); -- --/** -- * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes -- * -- * @devlink_port: devlink port -- * @controller: associated controller number for the devlink port instance -- * @pf: associated PF for the devlink port instance -- * @vf: associated VF of a PF for the devlink port instance -- * @external: indicates if the port is for an external controller -- */ --void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller, -- u16 pf, u16 vf, bool external) --{ -- struct devlink_port_attrs *attrs = &devlink_port->attrs; -- int ret; -- -- ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -- -- ret = __devlink_port_attrs_set(devlink_port, -- DEVLINK_PORT_FLAVOUR_PCI_VF); -- if (ret) -- return; -- attrs->pci_vf.controller = controller; -- attrs->pci_vf.pf = pf; -- attrs->pci_vf.vf = vf; -- attrs->pci_vf.external = external; --} --EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set); -- --/** -- * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes -- * -- * @devlink_port: devlink port -- * @controller: associated controller number for the devlink port instance -- * @pf: associated PF for the devlink port instance -- * @sf: associated SF of a PF for the devlink port instance -- * @external: indicates if the port is for an external controller -- */ --void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller, -- u16 pf, u32 sf, bool external) --{ -- struct devlink_port_attrs *attrs = &devlink_port->attrs; -- int ret; -- -- ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -- -- ret = __devlink_port_attrs_set(devlink_port, -- DEVLINK_PORT_FLAVOUR_PCI_SF); -- if (ret) -- return; -- attrs->pci_sf.controller = controller; -- attrs->pci_sf.pf = pf; -- attrs->pci_sf.sf = sf; -- attrs->pci_sf.external = external; --} --EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set); -- --/** -- * devl_rate_leaf_create - create devlink rate leaf -- * @devlink_port: devlink port object to create rate object on -- * @priv: driver private data -- * -- * Create devlink rate object of type leaf on provided @devlink_port. -- */ --int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv) --{ -- struct devlink *devlink = devlink_port->devlink; -- struct devlink_rate *devlink_rate; -- -- devl_assert_locked(devlink_port->devlink); -- -- if (WARN_ON(devlink_port->devlink_rate)) -- return -EBUSY; -- -- devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL); -- if (!devlink_rate) -- return -ENOMEM; -- -- devlink_rate->type = DEVLINK_RATE_TYPE_LEAF; -- devlink_rate->devlink = devlink; -- devlink_rate->devlink_port = devlink_port; -- devlink_rate->priv = priv; -- list_add_tail(&devlink_rate->list, &devlink->rate_list); -- devlink_port->devlink_rate = devlink_rate; -- devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); -- -- return 0; --} --EXPORT_SYMBOL_GPL(devl_rate_leaf_create); -- --/** -- * devl_rate_leaf_destroy - destroy devlink rate leaf -- * -- * @devlink_port: devlink port linked to the rate object -- * -- * Destroy the devlink rate object of type leaf on provided @devlink_port. -- */ --void devl_rate_leaf_destroy(struct devlink_port *devlink_port) --{ -- struct devlink_rate *devlink_rate = devlink_port->devlink_rate; -- -- devl_assert_locked(devlink_port->devlink); -- if (!devlink_rate) -- return; -- -- devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL); -- if (devlink_rate->parent) -- refcount_dec(&devlink_rate->parent->refcnt); -- list_del(&devlink_rate->list); -- devlink_port->devlink_rate = NULL; -- kfree(devlink_rate); --} --EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy); -- --/** -- * devl_rate_nodes_destroy - destroy all devlink rate nodes on device -- * @devlink: devlink instance -- * -- * Unset parent for all rate objects and destroy all rate nodes -- * on specified device. -- */ --void devl_rate_nodes_destroy(struct devlink *devlink) --{ -- static struct devlink_rate *devlink_rate, *tmp; -- const struct devlink_ops *ops = devlink->ops; -- -- devl_assert_locked(devlink); -- -- list_for_each_entry(devlink_rate, &devlink->rate_list, list) { -- if (!devlink_rate->parent) -- continue; -- -- refcount_dec(&devlink_rate->parent->refcnt); -- if (devlink_rate_is_leaf(devlink_rate)) -- ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv, -- NULL, NULL); -- else if (devlink_rate_is_node(devlink_rate)) -- ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv, -- NULL, NULL); -- } -- list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) { -- if (devlink_rate_is_node(devlink_rate)) { -- ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL); -- list_del(&devlink_rate->list); -- kfree(devlink_rate->name); -- kfree(devlink_rate); -- } -- } --} --EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy); -- --/** -- * devlink_port_linecard_set - Link port with a linecard -- * -- * @devlink_port: devlink port -- * @linecard: devlink linecard -- */ --void devlink_port_linecard_set(struct devlink_port *devlink_port, -- struct devlink_linecard *linecard) --{ -- ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -- -- devlink_port->linecard = linecard; --} --EXPORT_SYMBOL_GPL(devlink_port_linecard_set); -- --static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, -- char *name, size_t len) --{ -- struct devlink_port_attrs *attrs = &devlink_port->attrs; -- int n = 0; -- -- if (!devlink_port->attrs_set) -- return -EOPNOTSUPP; -- -- switch (attrs->flavour) { -- case DEVLINK_PORT_FLAVOUR_PHYSICAL: -- if (devlink_port->linecard) -- n = snprintf(name, len, "l%u", -- devlink_port->linecard->index); -- if (n < len) -- n += snprintf(name + n, len - n, "p%u", -- attrs->phys.port_number); -- if (n < len && attrs->split) -- n += snprintf(name + n, len - n, "s%u", -- attrs->phys.split_subport_number); -- break; -- case DEVLINK_PORT_FLAVOUR_CPU: -- case DEVLINK_PORT_FLAVOUR_DSA: -- case DEVLINK_PORT_FLAVOUR_UNUSED: -- /* As CPU and DSA ports do not have a netdevice associated -- * case should not ever happen. -- */ -- WARN_ON(1); -- return -EINVAL; -- case DEVLINK_PORT_FLAVOUR_PCI_PF: -- if (attrs->pci_pf.external) { -- n = snprintf(name, len, "c%u", attrs->pci_pf.controller); -- if (n >= len) -- return -EINVAL; -- len -= n; -- name += n; -- } -- n = snprintf(name, len, "pf%u", attrs->pci_pf.pf); -- break; -- case DEVLINK_PORT_FLAVOUR_PCI_VF: -- if (attrs->pci_vf.external) { -- n = snprintf(name, len, "c%u", attrs->pci_vf.controller); -- if (n >= len) -- return -EINVAL; -- len -= n; -- name += n; -- } -- n = snprintf(name, len, "pf%uvf%u", -- attrs->pci_vf.pf, attrs->pci_vf.vf); -- break; -- case DEVLINK_PORT_FLAVOUR_PCI_SF: -- if (attrs->pci_sf.external) { -- n = snprintf(name, len, "c%u", attrs->pci_sf.controller); -- if (n >= len) -- return -EINVAL; -- len -= n; -- name += n; -- } -- n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf, -- attrs->pci_sf.sf); -- break; -- case DEVLINK_PORT_FLAVOUR_VIRTUAL: -- return -EOPNOTSUPP; -- } -- -- if (n >= len) -- return -EINVAL; -- -- return 0; --} -- --static int devlink_linecard_types_init(struct devlink_linecard *linecard) --{ -- struct devlink_linecard_type *linecard_type; -- unsigned int count; -- int i; -- -- count = linecard->ops->types_count(linecard, linecard->priv); -- linecard->types = kmalloc_array(count, sizeof(*linecard_type), -- GFP_KERNEL); -- if (!linecard->types) -- return -ENOMEM; -- linecard->types_count = count; -- -- for (i = 0; i < count; i++) { -- linecard_type = &linecard->types[i]; -- linecard->ops->types_get(linecard, linecard->priv, i, -- &linecard_type->type, -- &linecard_type->priv); -- } -- return 0; --} -- --static void devlink_linecard_types_fini(struct devlink_linecard *linecard) --{ -- kfree(linecard->types); --} -- --/** -- * devlink_linecard_create - Create devlink linecard -- * -- * @devlink: devlink -- * @linecard_index: driver-specific numerical identifier of the linecard -- * @ops: linecards ops -- * @priv: user priv pointer -- * -- * Create devlink linecard instance with provided linecard index. -- * Caller can use any indexing, even hw-related one. -- * -- * Return: Line card structure or an ERR_PTR() encoded error code. -- */ --struct devlink_linecard * --devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index, -- const struct devlink_linecard_ops *ops, void *priv) --{ -- struct devlink_linecard *linecard; -- int err; -- -- if (WARN_ON(!ops || !ops->provision || !ops->unprovision || -- !ops->types_count || !ops->types_get)) -- return ERR_PTR(-EINVAL); -- -- mutex_lock(&devlink->linecards_lock); -- if (devlink_linecard_index_exists(devlink, linecard_index)) { -- mutex_unlock(&devlink->linecards_lock); -- return ERR_PTR(-EEXIST); -- } -- -- linecard = kzalloc(sizeof(*linecard), GFP_KERNEL); -- if (!linecard) { -- mutex_unlock(&devlink->linecards_lock); -- return ERR_PTR(-ENOMEM); -- } -- -- linecard->devlink = devlink; -- linecard->index = linecard_index; -- linecard->ops = ops; -- linecard->priv = priv; -- linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -- mutex_init(&linecard->state_lock); -- -- err = devlink_linecard_types_init(linecard); -- if (err) { -- mutex_destroy(&linecard->state_lock); -- kfree(linecard); -- mutex_unlock(&devlink->linecards_lock); -- return ERR_PTR(err); -- } -- -- list_add_tail(&linecard->list, &devlink->linecard_list); -- refcount_set(&linecard->refcount, 1); -- mutex_unlock(&devlink->linecards_lock); -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- return linecard; --} --EXPORT_SYMBOL_GPL(devlink_linecard_create); -- --/** -- * devlink_linecard_destroy - Destroy devlink linecard -- * -- * @linecard: devlink linecard -- */ --void devlink_linecard_destroy(struct devlink_linecard *linecard) --{ -- struct devlink *devlink = linecard->devlink; -- -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL); -- mutex_lock(&devlink->linecards_lock); -- list_del(&linecard->list); -- devlink_linecard_types_fini(linecard); -- mutex_unlock(&devlink->linecards_lock); -- devlink_linecard_put(linecard); --} --EXPORT_SYMBOL_GPL(devlink_linecard_destroy); -- --/** -- * devlink_linecard_provision_set - Set provisioning on linecard -- * -- * @linecard: devlink linecard -- * @type: linecard type -- * -- * This is either called directly from the provision() op call or -- * as a result of the provision() op call asynchronously. -- */ --void devlink_linecard_provision_set(struct devlink_linecard *linecard, -- const char *type) --{ -- mutex_lock(&linecard->state_lock); -- WARN_ON(linecard->type && strcmp(linecard->type, type)); -- linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED; -- linecard->type = type; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); --} --EXPORT_SYMBOL_GPL(devlink_linecard_provision_set); -- --/** -- * devlink_linecard_provision_clear - Clear provisioning on linecard -- * -- * @linecard: devlink linecard -- * -- * This is either called directly from the unprovision() op call or -- * as a result of the unprovision() op call asynchronously. -- */ --void devlink_linecard_provision_clear(struct devlink_linecard *linecard) --{ -- mutex_lock(&linecard->state_lock); -- WARN_ON(linecard->nested_devlink); -- linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -- linecard->type = NULL; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); --} --EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear); -- --/** -- * devlink_linecard_provision_fail - Fail provisioning on linecard -- * -- * @linecard: devlink linecard -- * -- * This is either called directly from the provision() op call or -- * as a result of the provision() op call asynchronously. -- */ --void devlink_linecard_provision_fail(struct devlink_linecard *linecard) --{ -- mutex_lock(&linecard->state_lock); -- WARN_ON(linecard->nested_devlink); -- linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); --} --EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail); -- --/** -- * devlink_linecard_activate - Set linecard active -- * -- * @linecard: devlink linecard -- */ --void devlink_linecard_activate(struct devlink_linecard *linecard) --{ -- mutex_lock(&linecard->state_lock); -- WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED); -- linecard->state = DEVLINK_LINECARD_STATE_ACTIVE; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); --} --EXPORT_SYMBOL_GPL(devlink_linecard_activate); -- --/** -- * devlink_linecard_deactivate - Set linecard inactive -- * -- * @linecard: devlink linecard -- */ --void devlink_linecard_deactivate(struct devlink_linecard *linecard) --{ -- mutex_lock(&linecard->state_lock); -- switch (linecard->state) { -- case DEVLINK_LINECARD_STATE_ACTIVE: -- linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- break; -- case DEVLINK_LINECARD_STATE_UNPROVISIONING: -- /* Line card is being deactivated as part -- * of unprovisioning flow. -- */ -- break; -- default: -- WARN_ON(1); -- break; -- } -- mutex_unlock(&linecard->state_lock); --} --EXPORT_SYMBOL_GPL(devlink_linecard_deactivate); -- --/** -- * devlink_linecard_nested_dl_set - Attach/detach nested devlink -- * instance to linecard. -- * -- * @linecard: devlink linecard -- * @nested_devlink: devlink instance to attach or NULL to detach -- */ --void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard, -- struct devlink *nested_devlink) --{ -- mutex_lock(&linecard->state_lock); -- linecard->nested_devlink = nested_devlink; -- devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -- mutex_unlock(&linecard->state_lock); --} --EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set); -- --int devl_sb_register(struct devlink *devlink, unsigned int sb_index, -- u32 size, u16 ingress_pools_count, -- u16 egress_pools_count, u16 ingress_tc_count, -- u16 egress_tc_count) --{ -- struct devlink_sb *devlink_sb; -- -- lockdep_assert_held(&devlink->lock); -- -- if (devlink_sb_index_exists(devlink, sb_index)) -- return -EEXIST; -- -- devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); -- if (!devlink_sb) -- return -ENOMEM; -- devlink_sb->index = sb_index; -- devlink_sb->size = size; -- devlink_sb->ingress_pools_count = ingress_pools_count; -- devlink_sb->egress_pools_count = egress_pools_count; -- devlink_sb->ingress_tc_count = ingress_tc_count; -- devlink_sb->egress_tc_count = egress_tc_count; -- list_add_tail(&devlink_sb->list, &devlink->sb_list); -- return 0; --} --EXPORT_SYMBOL_GPL(devl_sb_register); -- --int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, -- u32 size, u16 ingress_pools_count, -- u16 egress_pools_count, u16 ingress_tc_count, -- u16 egress_tc_count) --{ -- int err; -- -- devl_lock(devlink); -- err = devl_sb_register(devlink, sb_index, size, ingress_pools_count, -- egress_pools_count, ingress_tc_count, -- egress_tc_count); -- devl_unlock(devlink); -- return err; --} --EXPORT_SYMBOL_GPL(devlink_sb_register); -- --void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index) --{ -- struct devlink_sb *devlink_sb; -- -- lockdep_assert_held(&devlink->lock); -- -- devlink_sb = devlink_sb_get_by_index(devlink, sb_index); -- WARN_ON(!devlink_sb); -- list_del(&devlink_sb->list); -- kfree(devlink_sb); --} --EXPORT_SYMBOL_GPL(devl_sb_unregister); -- --void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index) --{ -- devl_lock(devlink); -- devl_sb_unregister(devlink, sb_index); -- devl_unlock(devlink); --} --EXPORT_SYMBOL_GPL(devlink_sb_unregister); -- --/** -- * devl_dpipe_headers_register - register dpipe headers -- * -- * @devlink: devlink -- * @dpipe_headers: dpipe header array -- * -- * Register the headers supported by hardware. -- */ --void devl_dpipe_headers_register(struct devlink *devlink, -- struct devlink_dpipe_headers *dpipe_headers) --{ -- lockdep_assert_held(&devlink->lock); -- -- devlink->dpipe_headers = dpipe_headers; --} --EXPORT_SYMBOL_GPL(devl_dpipe_headers_register); -- --/** -- * devl_dpipe_headers_unregister - unregister dpipe headers -- * -- * @devlink: devlink -- * -- * Unregister the headers supported by hardware. -- */ --void devl_dpipe_headers_unregister(struct devlink *devlink) --{ -- lockdep_assert_held(&devlink->lock); -- -- devlink->dpipe_headers = NULL; --} --EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister); -- --/** -- * devlink_dpipe_table_counter_enabled - check if counter allocation -- * required -- * @devlink: devlink -- * @table_name: tables name -- * -- * Used by driver to check if counter allocation is required. -- * After counter allocation is turned on the table entries -- * are updated to include counter statistics. -- * -- * After that point on the driver must respect the counter -- * state so that each entry added to the table is added -- * with a counter. -- */ --bool devlink_dpipe_table_counter_enabled(struct devlink *devlink, -- const char *table_name) --{ -- struct devlink_dpipe_table *table; -- bool enabled; -- -- rcu_read_lock(); -- table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -- table_name, devlink); -- enabled = false; -- if (table) -- enabled = table->counters_enabled; -- rcu_read_unlock(); -- return enabled; --} --EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); -- --/** -- * devl_dpipe_table_register - register dpipe table -- * -- * @devlink: devlink -- * @table_name: table name -- * @table_ops: table ops -- * @priv: priv -- * @counter_control_extern: external control for counters -- */ --int devl_dpipe_table_register(struct devlink *devlink, -- const char *table_name, -- struct devlink_dpipe_table_ops *table_ops, -- void *priv, bool counter_control_extern) --{ -- struct devlink_dpipe_table *table; -- -- lockdep_assert_held(&devlink->lock); -- -- if (WARN_ON(!table_ops->size_get)) -- return -EINVAL; -- -- if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name, -- devlink)) -- return -EEXIST; -- -- table = kzalloc(sizeof(*table), GFP_KERNEL); -- if (!table) -- return -ENOMEM; -- -- table->name = table_name; -- table->table_ops = table_ops; -- table->priv = priv; -- table->counter_control_extern = counter_control_extern; -- -- list_add_tail_rcu(&table->list, &devlink->dpipe_table_list); -- -- return 0; --} --EXPORT_SYMBOL_GPL(devl_dpipe_table_register); -- --/** -- * devl_dpipe_table_unregister - unregister dpipe table -- * -- * @devlink: devlink -- * @table_name: table name -- */ --void devl_dpipe_table_unregister(struct devlink *devlink, -- const char *table_name) --{ -- struct devlink_dpipe_table *table; -- -- lockdep_assert_held(&devlink->lock); -- -- table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -- table_name, devlink); -- if (!table) -- return; -- list_del_rcu(&table->list); -- kfree_rcu(table, rcu); --} --EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister); -- --/** -- * devl_resource_register - devlink resource register -- * -- * @devlink: devlink -- * @resource_name: resource's name -- * @resource_size: resource's size -- * @resource_id: resource's id -- * @parent_resource_id: resource's parent id -- * @size_params: size parameters -- * -- * Generic resources should reuse the same names across drivers. -- * Please see the generic resources list at: -- * Documentation/networking/devlink/devlink-resource.rst -- */ --int devl_resource_register(struct devlink *devlink, -- const char *resource_name, -- u64 resource_size, -- u64 resource_id, -- u64 parent_resource_id, -- const struct devlink_resource_size_params *size_params) --{ -- struct devlink_resource *resource; -- struct list_head *resource_list; -- bool top_hierarchy; -- -- lockdep_assert_held(&devlink->lock); -- -- top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP; -- -- resource = devlink_resource_find(devlink, NULL, resource_id); -- if (resource) -- return -EINVAL; -- -- resource = kzalloc(sizeof(*resource), GFP_KERNEL); -- if (!resource) -- return -ENOMEM; -- -- if (top_hierarchy) { -- resource_list = &devlink->resource_list; -- } else { -- struct devlink_resource *parent_resource; -- -- parent_resource = devlink_resource_find(devlink, NULL, -- parent_resource_id); -- if (parent_resource) { -- resource_list = &parent_resource->resource_list; -- resource->parent = parent_resource; -- } else { -- kfree(resource); -- return -EINVAL; -- } -- } -- -- resource->name = resource_name; -- resource->size = resource_size; -- resource->size_new = resource_size; -- resource->id = resource_id; -- resource->size_valid = true; -- memcpy(&resource->size_params, size_params, -- sizeof(resource->size_params)); -- INIT_LIST_HEAD(&resource->resource_list); -- list_add_tail(&resource->list, resource_list); -- -- return 0; --} --EXPORT_SYMBOL_GPL(devl_resource_register); -- --/** -- * devlink_resource_register - devlink resource register -- * -- * @devlink: devlink -- * @resource_name: resource's name -- * @resource_size: resource's size -- * @resource_id: resource's id -- * @parent_resource_id: resource's parent id -- * @size_params: size parameters -- * -- * Generic resources should reuse the same names across drivers. -- * Please see the generic resources list at: -- * Documentation/networking/devlink/devlink-resource.rst -- * -- * Context: Takes and release devlink->lock . -- */ --int devlink_resource_register(struct devlink *devlink, -- const char *resource_name, -- u64 resource_size, -- u64 resource_id, -- u64 parent_resource_id, -- const struct devlink_resource_size_params *size_params) --{ -- int err; -- -- devl_lock(devlink); -- err = devl_resource_register(devlink, resource_name, resource_size, -- resource_id, parent_resource_id, size_params); -- devl_unlock(devlink); -- return err; --} --EXPORT_SYMBOL_GPL(devlink_resource_register); -- --static void devlink_resource_unregister(struct devlink *devlink, -- struct devlink_resource *resource) --{ -- struct devlink_resource *tmp, *child_resource; -- -- list_for_each_entry_safe(child_resource, tmp, &resource->resource_list, -- list) { -- devlink_resource_unregister(devlink, child_resource); -- list_del(&child_resource->list); -- kfree(child_resource); -- } --} -- --/** -- * devl_resources_unregister - free all resources -- * -- * @devlink: devlink -- */ --void devl_resources_unregister(struct devlink *devlink) --{ -- struct devlink_resource *tmp, *child_resource; -- -- lockdep_assert_held(&devlink->lock); -- -- list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list, -- list) { -- devlink_resource_unregister(devlink, child_resource); -- list_del(&child_resource->list); -- kfree(child_resource); -- } --} --EXPORT_SYMBOL_GPL(devl_resources_unregister); -- --/** -- * devlink_resources_unregister - free all resources -- * -- * @devlink: devlink -- * -- * Context: Takes and release devlink->lock . -- */ --void devlink_resources_unregister(struct devlink *devlink) --{ -- devl_lock(devlink); -- devl_resources_unregister(devlink); -- devl_unlock(devlink); --} --EXPORT_SYMBOL_GPL(devlink_resources_unregister); -- --/** -- * devl_resource_size_get - get and update size -- * -- * @devlink: devlink -- * @resource_id: the requested resource id -- * @p_resource_size: ptr to update -- */ --int devl_resource_size_get(struct devlink *devlink, -- u64 resource_id, -- u64 *p_resource_size) --{ -- struct devlink_resource *resource; -- -- lockdep_assert_held(&devlink->lock); -- -- resource = devlink_resource_find(devlink, NULL, resource_id); -- if (!resource) -- return -EINVAL; -- *p_resource_size = resource->size_new; -- resource->size = resource->size_new; -- return 0; --} --EXPORT_SYMBOL_GPL(devl_resource_size_get); -- --/** -- * devl_dpipe_table_resource_set - set the resource id -- * -- * @devlink: devlink -- * @table_name: table name -- * @resource_id: resource id -- * @resource_units: number of resource's units consumed per table's entry -- */ --int devl_dpipe_table_resource_set(struct devlink *devlink, -- const char *table_name, u64 resource_id, -- u64 resource_units) --{ -- struct devlink_dpipe_table *table; -- -- table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -- table_name, devlink); -- if (!table) -- return -EINVAL; -- -- table->resource_id = resource_id; -- table->resource_units = resource_units; -- table->resource_valid = true; -- return 0; --} --EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set); -- --/** -- * devl_resource_occ_get_register - register occupancy getter -- * -- * @devlink: devlink -- * @resource_id: resource id -- * @occ_get: occupancy getter callback -- * @occ_get_priv: occupancy getter callback priv -- */ --void devl_resource_occ_get_register(struct devlink *devlink, -- u64 resource_id, -- devlink_resource_occ_get_t *occ_get, -- void *occ_get_priv) --{ -- struct devlink_resource *resource; -- -- lockdep_assert_held(&devlink->lock); -- -- resource = devlink_resource_find(devlink, NULL, resource_id); -- if (WARN_ON(!resource)) -- return; -- WARN_ON(resource->occ_get); -- -- resource->occ_get = occ_get; -- resource->occ_get_priv = occ_get_priv; --} --EXPORT_SYMBOL_GPL(devl_resource_occ_get_register); -- --/** -- * devlink_resource_occ_get_register - register occupancy getter -- * -- * @devlink: devlink -- * @resource_id: resource id -- * @occ_get: occupancy getter callback -- * @occ_get_priv: occupancy getter callback priv -- * -- * Context: Takes and release devlink->lock . -- */ --void devlink_resource_occ_get_register(struct devlink *devlink, -- u64 resource_id, -- devlink_resource_occ_get_t *occ_get, -- void *occ_get_priv) --{ -- devl_lock(devlink); -- devl_resource_occ_get_register(devlink, resource_id, -- occ_get, occ_get_priv); -- devl_unlock(devlink); --} --EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register); -- --/** -- * devl_resource_occ_get_unregister - unregister occupancy getter -- * -- * @devlink: devlink -- * @resource_id: resource id -- */ --void devl_resource_occ_get_unregister(struct devlink *devlink, -- u64 resource_id) --{ -- struct devlink_resource *resource; -- -- lockdep_assert_held(&devlink->lock); -- -- resource = devlink_resource_find(devlink, NULL, resource_id); -- if (WARN_ON(!resource)) -- return; -- WARN_ON(!resource->occ_get); -- -- resource->occ_get = NULL; -- resource->occ_get_priv = NULL; --} --EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister); -- --/** -- * devlink_resource_occ_get_unregister - unregister occupancy getter -- * -- * @devlink: devlink -- * @resource_id: resource id -- * -- * Context: Takes and release devlink->lock . -- */ --void devlink_resource_occ_get_unregister(struct devlink *devlink, -- u64 resource_id) --{ -- devl_lock(devlink); -- devl_resource_occ_get_unregister(devlink, resource_id); -- devl_unlock(devlink); --} --EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister); -- --static int devlink_param_verify(const struct devlink_param *param) --{ -- if (!param || !param->name || !param->supported_cmodes) -- return -EINVAL; -- if (param->generic) -- return devlink_param_generic_verify(param); -- else -- return devlink_param_driver_verify(param); --} -- --/** -- * devlink_params_register - register configuration parameters -- * -- * @devlink: devlink -- * @params: configuration parameters array -- * @params_count: number of parameters provided -- * -- * Register the configuration parameters supported by the driver. -- */ --int devlink_params_register(struct devlink *devlink, -- const struct devlink_param *params, -- size_t params_count) --{ -- const struct devlink_param *param = params; -- int i, err; -- -- ASSERT_DEVLINK_NOT_REGISTERED(devlink); -- -- for (i = 0; i < params_count; i++, param++) { -- err = devlink_param_register(devlink, param); -- if (err) -- goto rollback; -- } -- return 0; -- --rollback: -- if (!i) -- return err; -- -- for (param--; i > 0; i--, param--) -- devlink_param_unregister(devlink, param); -- return err; --} --EXPORT_SYMBOL_GPL(devlink_params_register); -- --/** -- * devlink_params_unregister - unregister configuration parameters -- * @devlink: devlink -- * @params: configuration parameters to unregister -- * @params_count: number of parameters provided -- */ --void devlink_params_unregister(struct devlink *devlink, -- const struct devlink_param *params, -- size_t params_count) --{ -- const struct devlink_param *param = params; -- int i; -- -- ASSERT_DEVLINK_NOT_REGISTERED(devlink); -- -- for (i = 0; i < params_count; i++, param++) -- devlink_param_unregister(devlink, param); --} --EXPORT_SYMBOL_GPL(devlink_params_unregister); -- --/** -- * devlink_param_register - register one configuration parameter -- * -- * @devlink: devlink -- * @param: one configuration parameter -- * -- * Register the configuration parameter supported by the driver. -- * Return: returns 0 on successful registration or error code otherwise. -- */ --int devlink_param_register(struct devlink *devlink, -- const struct devlink_param *param) --{ -- struct devlink_param_item *param_item; -- -- ASSERT_DEVLINK_NOT_REGISTERED(devlink); -- -- WARN_ON(devlink_param_verify(param)); -- WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name)); -- -- if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) -- WARN_ON(param->get || param->set); -- else -- WARN_ON(!param->get || !param->set); -- -- param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); -- if (!param_item) -- return -ENOMEM; -- -- param_item->param = param; -- -- list_add_tail(¶m_item->list, &devlink->param_list); -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_param_register); -- --/** -- * devlink_param_unregister - unregister one configuration parameter -- * @devlink: devlink -- * @param: configuration parameter to unregister -- */ --void devlink_param_unregister(struct devlink *devlink, -- const struct devlink_param *param) --{ -- struct devlink_param_item *param_item; -- -- ASSERT_DEVLINK_NOT_REGISTERED(devlink); -- -- param_item = -- devlink_param_find_by_name(&devlink->param_list, param->name); -- WARN_ON(!param_item); -- list_del(¶m_item->list); -- kfree(param_item); --} --EXPORT_SYMBOL_GPL(devlink_param_unregister); -- --/** -- * devlink_param_driverinit_value_get - get configuration parameter -- * value for driver initializing -- * -- * @devlink: devlink -- * @param_id: parameter ID -- * @init_val: value of parameter in driverinit configuration mode -- * -- * This function should be used by the driver to get driverinit -- * configuration for initialization after reload command. -- */ --int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, -- union devlink_param_value *init_val) --{ -- struct devlink_param_item *param_item; -- -- if (!devlink_reload_supported(devlink->ops)) -- return -EOPNOTSUPP; -- -- param_item = devlink_param_find_by_id(&devlink->param_list, param_id); -- if (!param_item) -- return -EINVAL; -- -- if (!param_item->driverinit_value_valid || -- !devlink_param_cmode_is_supported(param_item->param, -- DEVLINK_PARAM_CMODE_DRIVERINIT)) -- return -EOPNOTSUPP; -- -- if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) -- strcpy(init_val->vstr, param_item->driverinit_value.vstr); -- else -- *init_val = param_item->driverinit_value; -- -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get); -- --/** -- * devlink_param_driverinit_value_set - set value of configuration -- * parameter for driverinit -- * configuration mode -- * -- * @devlink: devlink -- * @param_id: parameter ID -- * @init_val: value of parameter to set for driverinit configuration mode -- * -- * This function should be used by the driver to set driverinit -- * configuration mode default value. -- */ --int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, -- union devlink_param_value init_val) --{ -- struct devlink_param_item *param_item; -- -- ASSERT_DEVLINK_NOT_REGISTERED(devlink); -- -- param_item = devlink_param_find_by_id(&devlink->param_list, param_id); -- if (!param_item) -- return -EINVAL; -- -- if (!devlink_param_cmode_is_supported(param_item->param, -- DEVLINK_PARAM_CMODE_DRIVERINIT)) -- return -EOPNOTSUPP; -- -- if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) -- strcpy(param_item->driverinit_value.vstr, init_val.vstr); -- else -- param_item->driverinit_value = init_val; -- param_item->driverinit_value_valid = true; -- return 0; --} --EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set); -- --/** -- * devlink_param_value_changed - notify devlink on a parameter's value -- * change. Should be called by the driver -- * right after the change. -- * -- * @devlink: devlink -- * @param_id: parameter ID -- * -- * This function should be used by the driver to notify devlink on value -- * change, excluding driverinit configuration mode. -- * For driverinit configuration mode driver should use the function -- */ --void devlink_param_value_changed(struct devlink *devlink, u32 param_id) --{ -- struct devlink_param_item *param_item; -- -- param_item = devlink_param_find_by_id(&devlink->param_list, param_id); -- WARN_ON(!param_item); -- -- devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); --} --EXPORT_SYMBOL_GPL(devlink_param_value_changed); -- --/** -- * devl_region_create - create a new address region -- * -- * @devlink: devlink -- * @ops: region operations and name -- * @region_max_snapshots: Maximum supported number of snapshots for region -- * @region_size: size of region -- */ --struct devlink_region *devl_region_create(struct devlink *devlink, -- const struct devlink_region_ops *ops, -- u32 region_max_snapshots, -- u64 region_size) --{ -- struct devlink_region *region; -- -- devl_assert_locked(devlink); -- -- if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) -- return ERR_PTR(-EINVAL); -- -- if (devlink_region_get_by_name(devlink, ops->name)) -- return ERR_PTR(-EEXIST); -- -- region = kzalloc(sizeof(*region), GFP_KERNEL); -- if (!region) -- return ERR_PTR(-ENOMEM); -- -- region->devlink = devlink; -- region->max_snapshots = region_max_snapshots; -- region->ops = ops; -- region->size = region_size; -- INIT_LIST_HEAD(®ion->snapshot_list); -- mutex_init(®ion->snapshot_lock); -- list_add_tail(®ion->list, &devlink->region_list); -- devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); -- -- return region; --} --EXPORT_SYMBOL_GPL(devl_region_create); -- --/** -- * devlink_region_create - create a new address region -- * -- * @devlink: devlink -- * @ops: region operations and name -- * @region_max_snapshots: Maximum supported number of snapshots for region -- * @region_size: size of region -- * -- * Context: Takes and release devlink->lock . -- */ --struct devlink_region * --devlink_region_create(struct devlink *devlink, -- const struct devlink_region_ops *ops, -- u32 region_max_snapshots, u64 region_size) --{ -- struct devlink_region *region; -- -- devl_lock(devlink); -- region = devl_region_create(devlink, ops, region_max_snapshots, -- region_size); -- devl_unlock(devlink); -- return region; --} --EXPORT_SYMBOL_GPL(devlink_region_create); -- --/** -- * devlink_port_region_create - create a new address region for a port -- * -- * @port: devlink port -- * @ops: region operations and name -- * @region_max_snapshots: Maximum supported number of snapshots for region -- * @region_size: size of region -- * -- * Context: Takes and release devlink->lock . -- */ --struct devlink_region * --devlink_port_region_create(struct devlink_port *port, -- const struct devlink_port_region_ops *ops, -- u32 region_max_snapshots, u64 region_size) --{ -- struct devlink *devlink = port->devlink; -- struct devlink_region *region; -- int err = 0; -- -- ASSERT_DEVLINK_PORT_INITIALIZED(port); -- -- if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) -- return ERR_PTR(-EINVAL); -- -- devl_lock(devlink); -- -- if (devlink_port_region_get_by_name(port, ops->name)) { -- err = -EEXIST; -- goto unlock; -- } -- -- region = kzalloc(sizeof(*region), GFP_KERNEL); -- if (!region) { -- err = -ENOMEM; -- goto unlock; -- } -- -- region->devlink = devlink; -- region->port = port; -- region->max_snapshots = region_max_snapshots; -- region->port_ops = ops; -- region->size = region_size; -- INIT_LIST_HEAD(®ion->snapshot_list); -- mutex_init(®ion->snapshot_lock); -- list_add_tail(®ion->list, &port->region_list); -- devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); -- -- devl_unlock(devlink); -- return region; -- --unlock: -- devl_unlock(devlink); -- return ERR_PTR(err); --} --EXPORT_SYMBOL_GPL(devlink_port_region_create); -- --/** -- * devl_region_destroy - destroy address region -- * -- * @region: devlink region to destroy -- */ --void devl_region_destroy(struct devlink_region *region) --{ -- struct devlink *devlink = region->devlink; -- struct devlink_snapshot *snapshot, *ts; -- -- devl_assert_locked(devlink); -- -- /* Free all snapshots of region */ -- mutex_lock(®ion->snapshot_lock); -- list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list) -- devlink_region_snapshot_del(region, snapshot); -- mutex_unlock(®ion->snapshot_lock); -- -- list_del(®ion->list); -- mutex_destroy(®ion->snapshot_lock); -- -- devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); -- kfree(region); --} --EXPORT_SYMBOL_GPL(devl_region_destroy); -- --/** -- * devlink_region_destroy - destroy address region -- * -- * @region: devlink region to destroy -- * -- * Context: Takes and release devlink->lock . -- */ --void devlink_region_destroy(struct devlink_region *region) --{ -- struct devlink *devlink = region->devlink; -- -- devl_lock(devlink); -- devl_region_destroy(region); -- devl_unlock(devlink); --} --EXPORT_SYMBOL_GPL(devlink_region_destroy); -- --/** -- * devlink_region_snapshot_id_get - get snapshot ID -- * -- * This callback should be called when adding a new snapshot, -- * Driver should use the same id for multiple snapshots taken -- * on multiple regions at the same time/by the same trigger. -- * -- * The caller of this function must use devlink_region_snapshot_id_put -- * when finished creating regions using this id. -- * -- * Returns zero on success, or a negative error code on failure. -- * -- * @devlink: devlink -- * @id: storage to return id -- */ --int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) --{ -- return __devlink_region_snapshot_id_get(devlink, id); --} --EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); -- --/** -- * devlink_region_snapshot_id_put - put snapshot ID reference -- * -- * This should be called by a driver after finishing creating snapshots -- * with an id. Doing so ensures that the ID can later be released in the -- * event that all snapshots using it have been destroyed. -- * -- * @devlink: devlink -- * @id: id to release reference on -- */ --void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) --{ -- __devlink_snapshot_id_decrement(devlink, id); --} --EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); -- --/** -- * devlink_region_snapshot_create - create a new snapshot -- * This will add a new snapshot of a region. The snapshot -- * will be stored on the region struct and can be accessed -- * from devlink. This is useful for future analyses of snapshots. -- * Multiple snapshots can be created on a region. -- * The @snapshot_id should be obtained using the getter function. -- * -- * @region: devlink region of the snapshot -- * @data: snapshot data -- * @snapshot_id: snapshot id to be created -- */ --int devlink_region_snapshot_create(struct devlink_region *region, -- u8 *data, u32 snapshot_id) --{ -- int err; -- -- mutex_lock(®ion->snapshot_lock); -- err = __devlink_region_snapshot_create(region, data, snapshot_id); -- mutex_unlock(®ion->snapshot_lock); -- return err; --} --EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); -- --#define DEVLINK_TRAP(_id, _type) \ -- { \ -- .type = DEVLINK_TRAP_TYPE_##_type, \ -- .id = DEVLINK_TRAP_GENERIC_ID_##_id, \ -- .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \ -- } -- --static const struct devlink_trap devlink_trap_generic[] = { -- DEVLINK_TRAP(SMAC_MC, DROP), -- DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP), -- DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP), -- DEVLINK_TRAP(INGRESS_STP_FILTER, DROP), -- DEVLINK_TRAP(EMPTY_TX_LIST, DROP), -- DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP), -- DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP), -- DEVLINK_TRAP(TTL_ERROR, EXCEPTION), -- DEVLINK_TRAP(TAIL_DROP, DROP), -- DEVLINK_TRAP(NON_IP_PACKET, DROP), -- DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP), -- DEVLINK_TRAP(DIP_LB, DROP), -- DEVLINK_TRAP(SIP_MC, DROP), -- DEVLINK_TRAP(SIP_LB, DROP), -- DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP), -- DEVLINK_TRAP(IPV4_SIP_BC, DROP), -- DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP), -- DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP), -- DEVLINK_TRAP(MTU_ERROR, EXCEPTION), -- DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION), -- DEVLINK_TRAP(RPF, EXCEPTION), -- DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION), -- DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION), -- DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION), -- DEVLINK_TRAP(NON_ROUTABLE, DROP), -- DEVLINK_TRAP(DECAP_ERROR, EXCEPTION), -- DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP), -- DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP), -- DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP), -- DEVLINK_TRAP(STP, CONTROL), -- DEVLINK_TRAP(LACP, CONTROL), -- DEVLINK_TRAP(LLDP, CONTROL), -- DEVLINK_TRAP(IGMP_QUERY, CONTROL), -- DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL), -- DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL), -- DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL), -- DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL), -- DEVLINK_TRAP(MLD_QUERY, CONTROL), -- DEVLINK_TRAP(MLD_V1_REPORT, CONTROL), -- DEVLINK_TRAP(MLD_V2_REPORT, CONTROL), -- DEVLINK_TRAP(MLD_V1_DONE, CONTROL), -- DEVLINK_TRAP(IPV4_DHCP, CONTROL), -- DEVLINK_TRAP(IPV6_DHCP, CONTROL), -- DEVLINK_TRAP(ARP_REQUEST, CONTROL), -- DEVLINK_TRAP(ARP_RESPONSE, CONTROL), -- DEVLINK_TRAP(ARP_OVERLAY, CONTROL), -- DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL), -- DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL), -- DEVLINK_TRAP(IPV4_BFD, CONTROL), -- DEVLINK_TRAP(IPV6_BFD, CONTROL), -- DEVLINK_TRAP(IPV4_OSPF, CONTROL), -- DEVLINK_TRAP(IPV6_OSPF, CONTROL), -- DEVLINK_TRAP(IPV4_BGP, CONTROL), -- DEVLINK_TRAP(IPV6_BGP, CONTROL), -- DEVLINK_TRAP(IPV4_VRRP, CONTROL), -- DEVLINK_TRAP(IPV6_VRRP, CONTROL), -- DEVLINK_TRAP(IPV4_PIM, CONTROL), -- DEVLINK_TRAP(IPV6_PIM, CONTROL), -- DEVLINK_TRAP(UC_LB, CONTROL), -- DEVLINK_TRAP(LOCAL_ROUTE, CONTROL), -- DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL), -- DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL), -- DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL), -- DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL), -- DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL), -- DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL), -- DEVLINK_TRAP(IPV6_REDIRECT, CONTROL), -- DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL), -- DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL), -- DEVLINK_TRAP(PTP_EVENT, CONTROL), -- DEVLINK_TRAP(PTP_GENERAL, CONTROL), -- DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL), -- DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL), -- DEVLINK_TRAP(EARLY_DROP, DROP), -- DEVLINK_TRAP(VXLAN_PARSING, DROP), -- DEVLINK_TRAP(LLC_SNAP_PARSING, DROP), -- DEVLINK_TRAP(VLAN_PARSING, DROP), -- DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP), -- DEVLINK_TRAP(MPLS_PARSING, DROP), -- DEVLINK_TRAP(ARP_PARSING, DROP), -- DEVLINK_TRAP(IP_1_PARSING, DROP), -- DEVLINK_TRAP(IP_N_PARSING, DROP), -- DEVLINK_TRAP(GRE_PARSING, DROP), -- DEVLINK_TRAP(UDP_PARSING, DROP), -- DEVLINK_TRAP(TCP_PARSING, DROP), -- DEVLINK_TRAP(IPSEC_PARSING, DROP), -- DEVLINK_TRAP(SCTP_PARSING, DROP), -- DEVLINK_TRAP(DCCP_PARSING, DROP), -- DEVLINK_TRAP(GTP_PARSING, DROP), -- DEVLINK_TRAP(ESP_PARSING, DROP), -- DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP), -- DEVLINK_TRAP(DMAC_FILTER, DROP), --}; -- --#define DEVLINK_TRAP_GROUP(_id) \ -- { \ -- .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \ -- .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \ -- } -- --static const struct devlink_trap_group devlink_trap_group_generic[] = { -- DEVLINK_TRAP_GROUP(L2_DROPS), -- DEVLINK_TRAP_GROUP(L3_DROPS), -- DEVLINK_TRAP_GROUP(L3_EXCEPTIONS), -- DEVLINK_TRAP_GROUP(BUFFER_DROPS), -- DEVLINK_TRAP_GROUP(TUNNEL_DROPS), -- DEVLINK_TRAP_GROUP(ACL_DROPS), -- DEVLINK_TRAP_GROUP(STP), -- DEVLINK_TRAP_GROUP(LACP), -- DEVLINK_TRAP_GROUP(LLDP), -- DEVLINK_TRAP_GROUP(MC_SNOOPING), -- DEVLINK_TRAP_GROUP(DHCP), -- DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY), -- DEVLINK_TRAP_GROUP(BFD), -- DEVLINK_TRAP_GROUP(OSPF), -- DEVLINK_TRAP_GROUP(BGP), -- DEVLINK_TRAP_GROUP(VRRP), -- DEVLINK_TRAP_GROUP(PIM), -- DEVLINK_TRAP_GROUP(UC_LB), -- DEVLINK_TRAP_GROUP(LOCAL_DELIVERY), -- DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY), -- DEVLINK_TRAP_GROUP(IPV6), -- DEVLINK_TRAP_GROUP(PTP_EVENT), -- DEVLINK_TRAP_GROUP(PTP_GENERAL), -- DEVLINK_TRAP_GROUP(ACL_SAMPLE), -- DEVLINK_TRAP_GROUP(ACL_TRAP), -- DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS), --}; -- --static int devlink_trap_generic_verify(const struct devlink_trap *trap) --{ -- if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX) -- return -EINVAL; -- -- if (strcmp(trap->name, devlink_trap_generic[trap->id].name)) -- return -EINVAL; -- -- if (trap->type != devlink_trap_generic[trap->id].type) -- return -EINVAL; -- -- return 0; --} -- --static int devlink_trap_driver_verify(const struct devlink_trap *trap) --{ -- int i; -- -- if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX) -- return -EINVAL; -- -- for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) { -- if (!strcmp(trap->name, devlink_trap_generic[i].name)) -- return -EEXIST; -- } -- -- return 0; --} -- --static int devlink_trap_verify(const struct devlink_trap *trap) --{ -- if (!trap || !trap->name) -- return -EINVAL; -- -- if (trap->generic) -- return devlink_trap_generic_verify(trap); -- else -- return devlink_trap_driver_verify(trap); --} -- --static int --devlink_trap_group_generic_verify(const struct devlink_trap_group *group) --{ -- if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) -- return -EINVAL; -- -- if (strcmp(group->name, devlink_trap_group_generic[group->id].name)) -- return -EINVAL; -- -- return 0; --} -- --static int --devlink_trap_group_driver_verify(const struct devlink_trap_group *group) --{ -- int i; -- -- if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) -- return -EINVAL; -- -- for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) { -- if (!strcmp(group->name, devlink_trap_group_generic[i].name)) -- return -EEXIST; -- } -- -- return 0; --} -- --static int devlink_trap_group_verify(const struct devlink_trap_group *group) --{ -- if (group->generic) -- return devlink_trap_group_generic_verify(group); -- else -- return devlink_trap_group_driver_verify(group); --} -- --static void --devlink_trap_group_notify(struct devlink *devlink, -- const struct devlink_trap_group_item *group_item, -- enum devlink_command cmd) --{ -- struct sk_buff *msg; -- int err; -- -- WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW && -- cmd != DEVLINK_CMD_TRAP_GROUP_DEL); -- if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -- return; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0, -- 0); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -- msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --static int --devlink_trap_item_group_link(struct devlink *devlink, -- struct devlink_trap_item *trap_item) --{ -- u16 group_id = trap_item->trap->init_group_id; -- struct devlink_trap_group_item *group_item; -- -- group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id); -- if (WARN_ON_ONCE(!group_item)) -- return -EINVAL; -- -- trap_item->group_item = group_item; -- -- return 0; --} -- --static void devlink_trap_notify(struct devlink *devlink, -- const struct devlink_trap_item *trap_item, -- enum devlink_command cmd) --{ -- struct sk_buff *msg; -- int err; -- -- WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW && -- cmd != DEVLINK_CMD_TRAP_DEL); -- if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -- return; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -- msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --static int --devlink_trap_register(struct devlink *devlink, -- const struct devlink_trap *trap, void *priv) --{ -- struct devlink_trap_item *trap_item; -- int err; -- -- if (devlink_trap_item_lookup(devlink, trap->name)) -- return -EEXIST; -- -- trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL); -- if (!trap_item) -- return -ENOMEM; -- -- trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); -- if (!trap_item->stats) { -- err = -ENOMEM; -- goto err_stats_alloc; -- } -- -- trap_item->trap = trap; -- trap_item->action = trap->init_action; -- trap_item->priv = priv; -- -- err = devlink_trap_item_group_link(devlink, trap_item); -- if (err) -- goto err_group_link; -- -- err = devlink->ops->trap_init(devlink, trap, trap_item); -- if (err) -- goto err_trap_init; -- -- list_add_tail(&trap_item->list, &devlink->trap_list); -- devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); -- -- return 0; -- --err_trap_init: --err_group_link: -- free_percpu(trap_item->stats); --err_stats_alloc: -- kfree(trap_item); -- return err; --} -- --static void devlink_trap_unregister(struct devlink *devlink, -- const struct devlink_trap *trap) --{ -- struct devlink_trap_item *trap_item; -- -- trap_item = devlink_trap_item_lookup(devlink, trap->name); -- if (WARN_ON_ONCE(!trap_item)) -- return; -- -- devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); -- list_del(&trap_item->list); -- if (devlink->ops->trap_fini) -- devlink->ops->trap_fini(devlink, trap, trap_item); -- free_percpu(trap_item->stats); -- kfree(trap_item); --} -- --static void devlink_trap_disable(struct devlink *devlink, -- const struct devlink_trap *trap) --{ -- struct devlink_trap_item *trap_item; -- -- trap_item = devlink_trap_item_lookup(devlink, trap->name); -- if (WARN_ON_ONCE(!trap_item)) -- return; -- -- devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP, -- NULL); -- trap_item->action = DEVLINK_TRAP_ACTION_DROP; --} -- --/** -- * devl_traps_register - Register packet traps with devlink. -- * @devlink: devlink. -- * @traps: Packet traps. -- * @traps_count: Count of provided packet traps. -- * @priv: Driver private information. -- * -- * Return: Non-zero value on failure. -- */ --int devl_traps_register(struct devlink *devlink, -- const struct devlink_trap *traps, -- size_t traps_count, void *priv) --{ -- int i, err; -- -- if (!devlink->ops->trap_init || !devlink->ops->trap_action_set) -- return -EINVAL; -- -- devl_assert_locked(devlink); -- for (i = 0; i < traps_count; i++) { -- const struct devlink_trap *trap = &traps[i]; -- -- err = devlink_trap_verify(trap); -- if (err) -- goto err_trap_verify; -- -- err = devlink_trap_register(devlink, trap, priv); -- if (err) -- goto err_trap_register; -- } -- -- return 0; -- --err_trap_register: --err_trap_verify: -- for (i--; i >= 0; i--) -- devlink_trap_unregister(devlink, &traps[i]); -- return err; --} --EXPORT_SYMBOL_GPL(devl_traps_register); -- --/** -- * devlink_traps_register - Register packet traps with devlink. -- * @devlink: devlink. -- * @traps: Packet traps. -- * @traps_count: Count of provided packet traps. -- * @priv: Driver private information. -- * -- * Context: Takes and release devlink->lock . -- * -- * Return: Non-zero value on failure. -- */ --int devlink_traps_register(struct devlink *devlink, -- const struct devlink_trap *traps, -- size_t traps_count, void *priv) --{ -- int err; -- -- devl_lock(devlink); -- err = devl_traps_register(devlink, traps, traps_count, priv); -- devl_unlock(devlink); -- return err; --} --EXPORT_SYMBOL_GPL(devlink_traps_register); -- --/** -- * devl_traps_unregister - Unregister packet traps from devlink. -- * @devlink: devlink. -- * @traps: Packet traps. -- * @traps_count: Count of provided packet traps. -- */ --void devl_traps_unregister(struct devlink *devlink, -- const struct devlink_trap *traps, -- size_t traps_count) --{ -- int i; -- -- devl_assert_locked(devlink); -- /* Make sure we do not have any packets in-flight while unregistering -- * traps by disabling all of them and waiting for a grace period. -- */ -- for (i = traps_count - 1; i >= 0; i--) -- devlink_trap_disable(devlink, &traps[i]); -- synchronize_rcu(); -- for (i = traps_count - 1; i >= 0; i--) -- devlink_trap_unregister(devlink, &traps[i]); --} --EXPORT_SYMBOL_GPL(devl_traps_unregister); -- --/** -- * devlink_traps_unregister - Unregister packet traps from devlink. -- * @devlink: devlink. -- * @traps: Packet traps. -- * @traps_count: Count of provided packet traps. -- * -- * Context: Takes and release devlink->lock . -- */ --void devlink_traps_unregister(struct devlink *devlink, -- const struct devlink_trap *traps, -- size_t traps_count) --{ -- devl_lock(devlink); -- devl_traps_unregister(devlink, traps, traps_count); -- devl_unlock(devlink); --} --EXPORT_SYMBOL_GPL(devlink_traps_unregister); -- --static void --devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats, -- size_t skb_len) --{ -- struct devlink_stats *stats; -- -- stats = this_cpu_ptr(trap_stats); -- u64_stats_update_begin(&stats->syncp); -- u64_stats_add(&stats->rx_bytes, skb_len); -- u64_stats_inc(&stats->rx_packets); -- u64_stats_update_end(&stats->syncp); --} -- --static void --devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata, -- const struct devlink_trap_item *trap_item, -- struct devlink_port *in_devlink_port, -- const struct flow_action_cookie *fa_cookie) --{ -- metadata->trap_name = trap_item->trap->name; -- metadata->trap_group_name = trap_item->group_item->group->name; -- metadata->fa_cookie = fa_cookie; -- metadata->trap_type = trap_item->trap->type; -- -- spin_lock(&in_devlink_port->type_lock); -- if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH) -- metadata->input_dev = in_devlink_port->type_dev; -- spin_unlock(&in_devlink_port->type_lock); --} -- --/** -- * devlink_trap_report - Report trapped packet to drop monitor. -- * @devlink: devlink. -- * @skb: Trapped packet. -- * @trap_ctx: Trap context. -- * @in_devlink_port: Input devlink port. -- * @fa_cookie: Flow action cookie. Could be NULL. -- */ --void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, -- void *trap_ctx, struct devlink_port *in_devlink_port, -- const struct flow_action_cookie *fa_cookie) -- --{ -- struct devlink_trap_item *trap_item = trap_ctx; -- -- devlink_trap_stats_update(trap_item->stats, skb->len); -- devlink_trap_stats_update(trap_item->group_item->stats, skb->len); -- -- if (trace_devlink_trap_report_enabled()) { -- struct devlink_trap_metadata metadata = {}; -- -- devlink_trap_report_metadata_set(&metadata, trap_item, -- in_devlink_port, fa_cookie); -- trace_devlink_trap_report(devlink, skb, &metadata); -- } --} --EXPORT_SYMBOL_GPL(devlink_trap_report); -- --/** -- * devlink_trap_ctx_priv - Trap context to driver private information. -- * @trap_ctx: Trap context. -- * -- * Return: Driver private information passed during registration. -- */ --void *devlink_trap_ctx_priv(void *trap_ctx) --{ -- struct devlink_trap_item *trap_item = trap_ctx; -- -- return trap_item->priv; --} --EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv); -- --static int --devlink_trap_group_item_policer_link(struct devlink *devlink, -- struct devlink_trap_group_item *group_item) --{ -- u32 policer_id = group_item->group->init_policer_id; -- struct devlink_trap_policer_item *policer_item; -- -- if (policer_id == 0) -- return 0; -- -- policer_item = devlink_trap_policer_item_lookup(devlink, policer_id); -- if (WARN_ON_ONCE(!policer_item)) -- return -EINVAL; -- -- group_item->policer_item = policer_item; -- -- return 0; --} -- --static int --devlink_trap_group_register(struct devlink *devlink, -- const struct devlink_trap_group *group) --{ -- struct devlink_trap_group_item *group_item; -- int err; -- -- if (devlink_trap_group_item_lookup(devlink, group->name)) -- return -EEXIST; -- -- group_item = kzalloc(sizeof(*group_item), GFP_KERNEL); -- if (!group_item) -- return -ENOMEM; -- -- group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); -- if (!group_item->stats) { -- err = -ENOMEM; -- goto err_stats_alloc; -- } -- -- group_item->group = group; -- -- err = devlink_trap_group_item_policer_link(devlink, group_item); -- if (err) -- goto err_policer_link; -- -- if (devlink->ops->trap_group_init) { -- err = devlink->ops->trap_group_init(devlink, group); -- if (err) -- goto err_group_init; -- } -- -- list_add_tail(&group_item->list, &devlink->trap_group_list); -- devlink_trap_group_notify(devlink, group_item, -- DEVLINK_CMD_TRAP_GROUP_NEW); -- -- return 0; -- --err_group_init: --err_policer_link: -- free_percpu(group_item->stats); --err_stats_alloc: -- kfree(group_item); -- return err; --} -- --static void --devlink_trap_group_unregister(struct devlink *devlink, -- const struct devlink_trap_group *group) --{ -- struct devlink_trap_group_item *group_item; -- -- group_item = devlink_trap_group_item_lookup(devlink, group->name); -- if (WARN_ON_ONCE(!group_item)) -- return; -- -- devlink_trap_group_notify(devlink, group_item, -- DEVLINK_CMD_TRAP_GROUP_DEL); -- list_del(&group_item->list); -- free_percpu(group_item->stats); -- kfree(group_item); --} -- --/** -- * devl_trap_groups_register - Register packet trap groups with devlink. -- * @devlink: devlink. -- * @groups: Packet trap groups. -- * @groups_count: Count of provided packet trap groups. -- * -- * Return: Non-zero value on failure. -- */ --int devl_trap_groups_register(struct devlink *devlink, -- const struct devlink_trap_group *groups, -- size_t groups_count) --{ -- int i, err; -- -- devl_assert_locked(devlink); -- for (i = 0; i < groups_count; i++) { -- const struct devlink_trap_group *group = &groups[i]; -- -- err = devlink_trap_group_verify(group); -- if (err) -- goto err_trap_group_verify; -- -- err = devlink_trap_group_register(devlink, group); -- if (err) -- goto err_trap_group_register; -- } -- -- return 0; -- --err_trap_group_register: --err_trap_group_verify: -- for (i--; i >= 0; i--) -- devlink_trap_group_unregister(devlink, &groups[i]); -- return err; --} --EXPORT_SYMBOL_GPL(devl_trap_groups_register); -- --/** -- * devlink_trap_groups_register - Register packet trap groups with devlink. -- * @devlink: devlink. -- * @groups: Packet trap groups. -- * @groups_count: Count of provided packet trap groups. -- * -- * Context: Takes and release devlink->lock . -- * -- * Return: Non-zero value on failure. -- */ --int devlink_trap_groups_register(struct devlink *devlink, -- const struct devlink_trap_group *groups, -- size_t groups_count) --{ -- int err; -- -- devl_lock(devlink); -- err = devl_trap_groups_register(devlink, groups, groups_count); -- devl_unlock(devlink); -- return err; --} --EXPORT_SYMBOL_GPL(devlink_trap_groups_register); -- --/** -- * devl_trap_groups_unregister - Unregister packet trap groups from devlink. -- * @devlink: devlink. -- * @groups: Packet trap groups. -- * @groups_count: Count of provided packet trap groups. -- */ --void devl_trap_groups_unregister(struct devlink *devlink, -- const struct devlink_trap_group *groups, -- size_t groups_count) --{ -- int i; -- -- devl_assert_locked(devlink); -- for (i = groups_count - 1; i >= 0; i--) -- devlink_trap_group_unregister(devlink, &groups[i]); --} --EXPORT_SYMBOL_GPL(devl_trap_groups_unregister); -- --/** -- * devlink_trap_groups_unregister - Unregister packet trap groups from devlink. -- * @devlink: devlink. -- * @groups: Packet trap groups. -- * @groups_count: Count of provided packet trap groups. -- * -- * Context: Takes and release devlink->lock . -- */ --void devlink_trap_groups_unregister(struct devlink *devlink, -- const struct devlink_trap_group *groups, -- size_t groups_count) --{ -- devl_lock(devlink); -- devl_trap_groups_unregister(devlink, groups, groups_count); -- devl_unlock(devlink); --} --EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister); -- --static void --devlink_trap_policer_notify(struct devlink *devlink, -- const struct devlink_trap_policer_item *policer_item, -- enum devlink_command cmd) --{ -- struct sk_buff *msg; -- int err; -- -- WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW && -- cmd != DEVLINK_CMD_TRAP_POLICER_DEL); -- if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -- return; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0, -- 0, 0); -- if (err) { -- nlmsg_free(msg); -- return; -- } -- -- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -- msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); --} -- --static int --devlink_trap_policer_register(struct devlink *devlink, -- const struct devlink_trap_policer *policer) --{ -- struct devlink_trap_policer_item *policer_item; -- int err; -- -- if (devlink_trap_policer_item_lookup(devlink, policer->id)) -- return -EEXIST; -- -- policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL); -- if (!policer_item) -- return -ENOMEM; -- -- policer_item->policer = policer; -- policer_item->rate = policer->init_rate; -- policer_item->burst = policer->init_burst; -- -- if (devlink->ops->trap_policer_init) { -- err = devlink->ops->trap_policer_init(devlink, policer); -- if (err) -- goto err_policer_init; -- } -- -- list_add_tail(&policer_item->list, &devlink->trap_policer_list); -- devlink_trap_policer_notify(devlink, policer_item, -- DEVLINK_CMD_TRAP_POLICER_NEW); -- -- return 0; -- --err_policer_init: -- kfree(policer_item); -- return err; --} -- --static void --devlink_trap_policer_unregister(struct devlink *devlink, -- const struct devlink_trap_policer *policer) --{ -- struct devlink_trap_policer_item *policer_item; -- -- policer_item = devlink_trap_policer_item_lookup(devlink, policer->id); -- if (WARN_ON_ONCE(!policer_item)) -- return; -- -- devlink_trap_policer_notify(devlink, policer_item, -- DEVLINK_CMD_TRAP_POLICER_DEL); -- list_del(&policer_item->list); -- if (devlink->ops->trap_policer_fini) -- devlink->ops->trap_policer_fini(devlink, policer); -- kfree(policer_item); --} -- --/** -- * devl_trap_policers_register - Register packet trap policers with devlink. -- * @devlink: devlink. -- * @policers: Packet trap policers. -- * @policers_count: Count of provided packet trap policers. -- * -- * Return: Non-zero value on failure. -- */ --int --devl_trap_policers_register(struct devlink *devlink, -- const struct devlink_trap_policer *policers, -- size_t policers_count) --{ -- int i, err; -- -- devl_assert_locked(devlink); -- for (i = 0; i < policers_count; i++) { -- const struct devlink_trap_policer *policer = &policers[i]; -- -- if (WARN_ON(policer->id == 0 || -- policer->max_rate < policer->min_rate || -- policer->max_burst < policer->min_burst)) { -- err = -EINVAL; -- goto err_trap_policer_verify; -- } -- -- err = devlink_trap_policer_register(devlink, policer); -- if (err) -- goto err_trap_policer_register; -- } -- return 0; -- --err_trap_policer_register: --err_trap_policer_verify: -- for (i--; i >= 0; i--) -- devlink_trap_policer_unregister(devlink, &policers[i]); -- return err; --} --EXPORT_SYMBOL_GPL(devl_trap_policers_register); -- --/** -- * devl_trap_policers_unregister - Unregister packet trap policers from devlink. -- * @devlink: devlink. -- * @policers: Packet trap policers. -- * @policers_count: Count of provided packet trap policers. -- */ --void --devl_trap_policers_unregister(struct devlink *devlink, -- const struct devlink_trap_policer *policers, -- size_t policers_count) --{ -- int i; -- -- devl_assert_locked(devlink); -- for (i = policers_count - 1; i >= 0; i--) -- devlink_trap_policer_unregister(devlink, &policers[i]); --} --EXPORT_SYMBOL_GPL(devl_trap_policers_unregister); -- --static void __devlink_compat_running_version(struct devlink *devlink, -- char *buf, size_t len) --{ -- struct devlink_info_req req = {}; -- const struct nlattr *nlattr; -- struct sk_buff *msg; -- int rem, err; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -- if (!msg) -- return; -- -- req.msg = msg; -- err = devlink->ops->info_get(devlink, &req, NULL); -- if (err) -- goto free_msg; -- -- nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) { -- const struct nlattr *kv; -- int rem_kv; -- -- if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING) -- continue; -- -- nla_for_each_nested(kv, nlattr, rem_kv) { -- if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE) -- continue; -- -- strlcat(buf, nla_data(kv), len); -- strlcat(buf, " ", len); -- } -- } --free_msg: -- nlmsg_free(msg); --} -- --static struct devlink_port *netdev_to_devlink_port(struct net_device *dev) --{ -- if (!dev->netdev_ops->ndo_get_devlink_port) -- return NULL; -- -- return dev->netdev_ops->ndo_get_devlink_port(dev); --} -- --void devlink_compat_running_version(struct devlink *devlink, -- char *buf, size_t len) --{ -- if (!devlink->ops->info_get) -- return; -- -- devl_lock(devlink); -- __devlink_compat_running_version(devlink, buf, len); -- devl_unlock(devlink); --} -- --int devlink_compat_flash_update(struct devlink *devlink, const char *file_name) --{ -- struct devlink_flash_update_params params = {}; -- int ret; -- -- if (!devlink->ops->flash_update) -- return -EOPNOTSUPP; -- -- ret = request_firmware(¶ms.fw, file_name, devlink->dev); -- if (ret) -- return ret; -- -- devl_lock(devlink); -- devlink_flash_update_begin_notify(devlink); -- ret = devlink->ops->flash_update(devlink, ¶ms, NULL); -- devlink_flash_update_end_notify(devlink); -- devl_unlock(devlink); -- -- release_firmware(params.fw); -- -- return ret; --} -- --int devlink_compat_phys_port_name_get(struct net_device *dev, -- char *name, size_t len) --{ -- struct devlink_port *devlink_port; -- -- /* RTNL mutex is held here which ensures that devlink_port -- * instance cannot disappear in the middle. No need to take -- * any devlink lock as only permanent values are accessed. -- */ -- ASSERT_RTNL(); -- -- devlink_port = netdev_to_devlink_port(dev); -- if (!devlink_port) -- return -EOPNOTSUPP; -- -- return __devlink_port_phys_port_name_get(devlink_port, name, len); --} -- --int devlink_compat_switch_id_get(struct net_device *dev, -- struct netdev_phys_item_id *ppid) --{ -- struct devlink_port *devlink_port; -- -- /* Caller must hold RTNL mutex or reference to dev, which ensures that -- * devlink_port instance cannot disappear in the middle. No need to take -- * any devlink lock as only permanent values are accessed. -- */ -- devlink_port = netdev_to_devlink_port(dev); -- if (!devlink_port || !devlink_port->switch_port) -- return -EOPNOTSUPP; -- -- memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid)); -- -- return 0; --} -- --static void __net_exit devlink_pernet_pre_exit(struct net *net) --{ -- struct devlink *devlink; -- u32 actions_performed; -- unsigned long index; -- int err; -- -- /* In case network namespace is getting destroyed, reload -- * all devlink instances from this namespace into init_net. -- */ -- devlinks_xa_for_each_registered_get(net, index, devlink) { -- WARN_ON(!(devlink->features & DEVLINK_F_RELOAD)); -- mutex_lock(&devlink->lock); -- err = devlink_reload(devlink, &init_net, -- DEVLINK_RELOAD_ACTION_DRIVER_REINIT, -- DEVLINK_RELOAD_LIMIT_UNSPEC, -- &actions_performed, NULL); -- mutex_unlock(&devlink->lock); -- if (err && err != -EOPNOTSUPP) -- pr_warn("Failed to reload devlink instance into init_net\n"); -- devlink_put(devlink); -- } --} -- --static struct pernet_operations devlink_pernet_ops __net_initdata = { -- .pre_exit = devlink_pernet_pre_exit, --}; -- --static int __init devlink_init(void) --{ -- int err; -- -- err = genl_register_family(&devlink_nl_family); -- if (err) -- goto out; -- err = register_pernet_subsys(&devlink_pernet_ops); -- --out: -- WARN_ON(err); -- return err; --} -- --subsys_initcall(devlink_init); -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 2758b3f7c0214..9d4507aa736b7 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -2220,13 +2220,27 @@ out_err: - return err; - } - --int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len, -- struct netlink_ext_ack *exterr) -+int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer, -+ struct netlink_ext_ack *exterr) - { -- return nla_parse_deprecated(tb, IFLA_MAX, head, len, ifla_policy, -+ const struct ifinfomsg *ifmp; -+ const struct nlattr *attrs; -+ size_t len; -+ -+ ifmp = nla_data(nla_peer); -+ attrs = nla_data(nla_peer) + sizeof(struct ifinfomsg); -+ len = nla_len(nla_peer) - sizeof(struct ifinfomsg); -+ -+ if (ifmp->ifi_index < 0) { -+ NL_SET_ERR_MSG_ATTR(exterr, nla_peer, -+ "ifindex can't be negative"); -+ return -EINVAL; -+ } -+ -+ return nla_parse_deprecated(tb, IFLA_MAX, attrs, len, ifla_policy, - exterr); - } --EXPORT_SYMBOL(rtnl_nla_parse_ifla); -+EXPORT_SYMBOL(rtnl_nla_parse_ifinfomsg); - - struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) - { -@@ -3451,6 +3465,9 @@ replay: - if (ifm->ifi_index > 0) { - link_specified = true; - dev = __dev_get_by_index(net, ifm->ifi_index); -+ } else if (ifm->ifi_index < 0) { -+ NL_SET_ERR_MSG(extack, "ifindex can't be negative"); -+ return -EINVAL; - } else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) { - link_specified = true; - dev = rtnl_dev_get(net, tb); -diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c -index b780827f5e0a5..bfececa9e244e 100644 ---- a/net/dccp/ipv4.c -+++ b/net/dccp/ipv4.c -@@ -130,7 +130,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) - inet->inet_daddr, - inet->inet_sport, - inet->inet_dport); -- inet->inet_id = get_random_u16(); -+ atomic_set(&inet->inet_id, get_random_u16()); - - err = dccp_connect(sk); - rt = NULL; -@@ -430,7 +430,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, - RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt)); - newinet->mc_index = inet_iif(skb); - newinet->mc_ttl = ip_hdr(skb)->ttl; -- newinet->inet_id = get_random_u16(); -+ atomic_set(&newinet->inet_id, get_random_u16()); - - if (dst == NULL && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL) - goto put_and_exit; -diff --git a/net/dccp/proto.c b/net/dccp/proto.c -index abc02d25edc14..c522c76a9f89f 100644 ---- a/net/dccp/proto.c -+++ b/net/dccp/proto.c -@@ -312,11 +312,15 @@ EXPORT_SYMBOL_GPL(dccp_disconnect); - __poll_t dccp_poll(struct file *file, struct socket *sock, - poll_table *wait) - { -- __poll_t mask; - struct sock *sk = sock->sk; -+ __poll_t mask; -+ u8 shutdown; -+ int state; - - sock_poll_wait(file, sock, wait); -- if (sk->sk_state == DCCP_LISTEN) -+ -+ state = inet_sk_state_load(sk); -+ if (state == DCCP_LISTEN) - return inet_csk_listen_poll(sk); - - /* Socket is not locked. We are protected from async events -@@ -325,20 +329,21 @@ __poll_t dccp_poll(struct file *file, struct socket *sock, - */ - - mask = 0; -- if (sk->sk_err) -+ if (READ_ONCE(sk->sk_err)) - mask = EPOLLERR; -+ shutdown = READ_ONCE(sk->sk_shutdown); - -- if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED) -+ if (shutdown == SHUTDOWN_MASK || state == DCCP_CLOSED) - mask |= EPOLLHUP; -- if (sk->sk_shutdown & RCV_SHUTDOWN) -+ if (shutdown & RCV_SHUTDOWN) - mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; - - /* Connected? */ -- if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) { -+ if ((1 << state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) { - if (atomic_read(&sk->sk_rmem_alloc) > 0) - mask |= EPOLLIN | EPOLLRDNORM; - -- if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { -+ if (!(shutdown & SEND_SHUTDOWN)) { - if (sk_stream_is_writeable(sk)) { - mask |= EPOLLOUT | EPOLLWRNORM; - } else { /* send SIGIO later */ -@@ -356,7 +361,6 @@ __poll_t dccp_poll(struct file *file, struct socket *sock, - } - return mask; - } -- - EXPORT_SYMBOL_GPL(dccp_poll); - - int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) -diff --git a/net/devlink/Makefile b/net/devlink/Makefile -new file mode 100644 -index 0000000000000..3a60959f71eea ---- /dev/null -+++ b/net/devlink/Makefile -@@ -0,0 +1,3 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+obj-y := leftover.o -diff --git a/net/devlink/leftover.c b/net/devlink/leftover.c -new file mode 100644 -index 0000000000000..63188d6a50fe9 ---- /dev/null -+++ b/net/devlink/leftover.c -@@ -0,0 +1,12550 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * net/core/devlink.c - Network physical/parent device Netlink interface -+ * -+ * Heavily inspired by net/wireless/ -+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved. -+ * Copyright (c) 2016 Jiri Pirko -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#define CREATE_TRACE_POINTS -+#include -+ -+#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \ -+ (__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX) -+ -+struct devlink_dev_stats { -+ u32 reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; -+ u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; -+}; -+ -+struct devlink { -+ u32 index; -+ struct list_head port_list; -+ struct list_head rate_list; -+ struct list_head sb_list; -+ struct list_head dpipe_table_list; -+ struct list_head resource_list; -+ struct list_head param_list; -+ struct list_head region_list; -+ struct list_head reporter_list; -+ struct mutex reporters_lock; /* protects reporter_list */ -+ struct devlink_dpipe_headers *dpipe_headers; -+ struct list_head trap_list; -+ struct list_head trap_group_list; -+ struct list_head trap_policer_list; -+ struct list_head linecard_list; -+ struct mutex linecards_lock; /* protects linecard_list */ -+ const struct devlink_ops *ops; -+ u64 features; -+ struct xarray snapshot_ids; -+ struct devlink_dev_stats stats; -+ struct device *dev; -+ possible_net_t _net; -+ /* Serializes access to devlink instance specific objects such as -+ * port, sb, dpipe, resource, params, region, traps and more. -+ */ -+ struct mutex lock; -+ struct lock_class_key lock_key; -+ u8 reload_failed:1; -+ refcount_t refcount; -+ struct completion comp; -+ struct rcu_head rcu; -+ char priv[] __aligned(NETDEV_ALIGN); -+}; -+ -+struct devlink_linecard_ops; -+struct devlink_linecard_type; -+ -+struct devlink_linecard { -+ struct list_head list; -+ struct devlink *devlink; -+ unsigned int index; -+ refcount_t refcount; -+ const struct devlink_linecard_ops *ops; -+ void *priv; -+ enum devlink_linecard_state state; -+ struct mutex state_lock; /* Protects state */ -+ const char *type; -+ struct devlink_linecard_type *types; -+ unsigned int types_count; -+ struct devlink *nested_devlink; -+}; -+ -+/** -+ * struct devlink_resource - devlink resource -+ * @name: name of the resource -+ * @id: id, per devlink instance -+ * @size: size of the resource -+ * @size_new: updated size of the resource, reload is needed -+ * @size_valid: valid in case the total size of the resource is valid -+ * including its children -+ * @parent: parent resource -+ * @size_params: size parameters -+ * @list: parent list -+ * @resource_list: list of child resources -+ * @occ_get: occupancy getter callback -+ * @occ_get_priv: occupancy getter callback priv -+ */ -+struct devlink_resource { -+ const char *name; -+ u64 id; -+ u64 size; -+ u64 size_new; -+ bool size_valid; -+ struct devlink_resource *parent; -+ struct devlink_resource_size_params size_params; -+ struct list_head list; -+ struct list_head resource_list; -+ devlink_resource_occ_get_t *occ_get; -+ void *occ_get_priv; -+}; -+ -+void *devlink_priv(struct devlink *devlink) -+{ -+ return &devlink->priv; -+} -+EXPORT_SYMBOL_GPL(devlink_priv); -+ -+struct devlink *priv_to_devlink(void *priv) -+{ -+ return container_of(priv, struct devlink, priv); -+} -+EXPORT_SYMBOL_GPL(priv_to_devlink); -+ -+struct device *devlink_to_dev(const struct devlink *devlink) -+{ -+ return devlink->dev; -+} -+EXPORT_SYMBOL_GPL(devlink_to_dev); -+ -+static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = { -+ { -+ .name = "destination mac", -+ .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC, -+ .bitwidth = 48, -+ }, -+}; -+ -+struct devlink_dpipe_header devlink_dpipe_header_ethernet = { -+ .name = "ethernet", -+ .id = DEVLINK_DPIPE_HEADER_ETHERNET, -+ .fields = devlink_dpipe_fields_ethernet, -+ .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet), -+ .global = true, -+}; -+EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet); -+ -+static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = { -+ { -+ .name = "destination ip", -+ .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP, -+ .bitwidth = 32, -+ }, -+}; -+ -+struct devlink_dpipe_header devlink_dpipe_header_ipv4 = { -+ .name = "ipv4", -+ .id = DEVLINK_DPIPE_HEADER_IPV4, -+ .fields = devlink_dpipe_fields_ipv4, -+ .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4), -+ .global = true, -+}; -+EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4); -+ -+static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = { -+ { -+ .name = "destination ip", -+ .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP, -+ .bitwidth = 128, -+ }, -+}; -+ -+struct devlink_dpipe_header devlink_dpipe_header_ipv6 = { -+ .name = "ipv6", -+ .id = DEVLINK_DPIPE_HEADER_IPV6, -+ .fields = devlink_dpipe_fields_ipv6, -+ .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6), -+ .global = true, -+}; -+EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6); -+ -+EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg); -+EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr); -+EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report); -+ -+static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = { -+ [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY }, -+ [DEVLINK_PORT_FN_ATTR_STATE] = -+ NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE, -+ DEVLINK_PORT_FN_STATE_ACTIVE), -+}; -+ -+static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = { -+ [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG }, -+}; -+ -+static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC); -+#define DEVLINK_REGISTERED XA_MARK_1 -+#define DEVLINK_UNREGISTERING XA_MARK_2 -+ -+/* devlink instances are open to the access from the user space after -+ * devlink_register() call. Such logical barrier allows us to have certain -+ * expectations related to locking. -+ * -+ * Before *_register() - we are in initialization stage and no parallel -+ * access possible to the devlink instance. All drivers perform that phase -+ * by implicitly holding device_lock. -+ * -+ * After *_register() - users and driver can access devlink instance at -+ * the same time. -+ */ -+#define ASSERT_DEVLINK_REGISTERED(d) \ -+ WARN_ON_ONCE(!xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED)) -+#define ASSERT_DEVLINK_NOT_REGISTERED(d) \ -+ WARN_ON_ONCE(xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED)) -+ -+struct net *devlink_net(const struct devlink *devlink) -+{ -+ return read_pnet(&devlink->_net); -+} -+EXPORT_SYMBOL_GPL(devlink_net); -+ -+static void __devlink_put_rcu(struct rcu_head *head) -+{ -+ struct devlink *devlink = container_of(head, struct devlink, rcu); -+ -+ complete(&devlink->comp); -+} -+ -+void devlink_put(struct devlink *devlink) -+{ -+ if (refcount_dec_and_test(&devlink->refcount)) -+ /* Make sure unregister operation that may await the completion -+ * is unblocked only after all users are after the end of -+ * RCU grace period. -+ */ -+ call_rcu(&devlink->rcu, __devlink_put_rcu); -+} -+ -+struct devlink *__must_check devlink_try_get(struct devlink *devlink) -+{ -+ if (refcount_inc_not_zero(&devlink->refcount)) -+ return devlink; -+ return NULL; -+} -+ -+void devl_assert_locked(struct devlink *devlink) -+{ -+ lockdep_assert_held(&devlink->lock); -+} -+EXPORT_SYMBOL_GPL(devl_assert_locked); -+ -+#ifdef CONFIG_LOCKDEP -+/* For use in conjunction with LOCKDEP only e.g. rcu_dereference_protected() */ -+bool devl_lock_is_held(struct devlink *devlink) -+{ -+ return lockdep_is_held(&devlink->lock); -+} -+EXPORT_SYMBOL_GPL(devl_lock_is_held); -+#endif -+ -+void devl_lock(struct devlink *devlink) -+{ -+ mutex_lock(&devlink->lock); -+} -+EXPORT_SYMBOL_GPL(devl_lock); -+ -+int devl_trylock(struct devlink *devlink) -+{ -+ return mutex_trylock(&devlink->lock); -+} -+EXPORT_SYMBOL_GPL(devl_trylock); -+ -+void devl_unlock(struct devlink *devlink) -+{ -+ mutex_unlock(&devlink->lock); -+} -+EXPORT_SYMBOL_GPL(devl_unlock); -+ -+static struct devlink * -+devlinks_xa_find_get(struct net *net, unsigned long *indexp, xa_mark_t filter, -+ void * (*xa_find_fn)(struct xarray *, unsigned long *, -+ unsigned long, xa_mark_t)) -+{ -+ struct devlink *devlink; -+ -+ rcu_read_lock(); -+retry: -+ devlink = xa_find_fn(&devlinks, indexp, ULONG_MAX, DEVLINK_REGISTERED); -+ if (!devlink) -+ goto unlock; -+ -+ /* In case devlink_unregister() was already called and "unregistering" -+ * mark was set, do not allow to get a devlink reference here. -+ * This prevents live-lock of devlink_unregister() wait for completion. -+ */ -+ if (xa_get_mark(&devlinks, *indexp, DEVLINK_UNREGISTERING)) -+ goto retry; -+ -+ /* For a possible retry, the xa_find_after() should be always used */ -+ xa_find_fn = xa_find_after; -+ if (!devlink_try_get(devlink)) -+ goto retry; -+ if (!net_eq(devlink_net(devlink), net)) { -+ devlink_put(devlink); -+ goto retry; -+ } -+unlock: -+ rcu_read_unlock(); -+ return devlink; -+} -+ -+static struct devlink *devlinks_xa_find_get_first(struct net *net, -+ unsigned long *indexp, -+ xa_mark_t filter) -+{ -+ return devlinks_xa_find_get(net, indexp, filter, xa_find); -+} -+ -+static struct devlink *devlinks_xa_find_get_next(struct net *net, -+ unsigned long *indexp, -+ xa_mark_t filter) -+{ -+ return devlinks_xa_find_get(net, indexp, filter, xa_find_after); -+} -+ -+/* Iterate over devlink pointers which were possible to get reference to. -+ * devlink_put() needs to be called for each iterated devlink pointer -+ * in loop body in order to release the reference. -+ */ -+#define devlinks_xa_for_each_get(net, index, devlink, filter) \ -+ for (index = 0, \ -+ devlink = devlinks_xa_find_get_first(net, &index, filter); \ -+ devlink; devlink = devlinks_xa_find_get_next(net, &index, filter)) -+ -+#define devlinks_xa_for_each_registered_get(net, index, devlink) \ -+ devlinks_xa_for_each_get(net, index, devlink, DEVLINK_REGISTERED) -+ -+static struct devlink *devlink_get_from_attrs(struct net *net, -+ struct nlattr **attrs) -+{ -+ struct devlink *devlink; -+ unsigned long index; -+ char *busname; -+ char *devname; -+ -+ if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME]) -+ return ERR_PTR(-EINVAL); -+ -+ busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]); -+ devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); -+ -+ devlinks_xa_for_each_registered_get(net, index, devlink) { -+ if (strcmp(devlink->dev->bus->name, busname) == 0 && -+ strcmp(dev_name(devlink->dev), devname) == 0) -+ return devlink; -+ devlink_put(devlink); -+ } -+ -+ return ERR_PTR(-ENODEV); -+} -+ -+#define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port) \ -+ WARN_ON_ONCE(!(devlink_port)->registered) -+#define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port) \ -+ WARN_ON_ONCE((devlink_port)->registered) -+#define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port) \ -+ WARN_ON_ONCE(!(devlink_port)->initialized) -+ -+static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink, -+ unsigned int port_index) -+{ -+ struct devlink_port *devlink_port; -+ -+ list_for_each_entry(devlink_port, &devlink->port_list, list) { -+ if (devlink_port->index == port_index) -+ return devlink_port; -+ } -+ return NULL; -+} -+ -+static bool devlink_port_index_exists(struct devlink *devlink, -+ unsigned int port_index) -+{ -+ return devlink_port_get_by_index(devlink, port_index); -+} -+ -+static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink, -+ struct nlattr **attrs) -+{ -+ if (attrs[DEVLINK_ATTR_PORT_INDEX]) { -+ u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); -+ struct devlink_port *devlink_port; -+ -+ devlink_port = devlink_port_get_by_index(devlink, port_index); -+ if (!devlink_port) -+ return ERR_PTR(-ENODEV); -+ return devlink_port; -+ } -+ return ERR_PTR(-EINVAL); -+} -+ -+static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink, -+ struct genl_info *info) -+{ -+ return devlink_port_get_from_attrs(devlink, info->attrs); -+} -+ -+static inline bool -+devlink_rate_is_leaf(struct devlink_rate *devlink_rate) -+{ -+ return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF; -+} -+ -+static inline bool -+devlink_rate_is_node(struct devlink_rate *devlink_rate) -+{ -+ return devlink_rate->type == DEVLINK_RATE_TYPE_NODE; -+} -+ -+static struct devlink_rate * -+devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info) -+{ -+ struct devlink_rate *devlink_rate; -+ struct devlink_port *devlink_port; -+ -+ devlink_port = devlink_port_get_from_attrs(devlink, info->attrs); -+ if (IS_ERR(devlink_port)) -+ return ERR_CAST(devlink_port); -+ devlink_rate = devlink_port->devlink_rate; -+ return devlink_rate ?: ERR_PTR(-ENODEV); -+} -+ -+static struct devlink_rate * -+devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name) -+{ -+ static struct devlink_rate *devlink_rate; -+ -+ list_for_each_entry(devlink_rate, &devlink->rate_list, list) { -+ if (devlink_rate_is_node(devlink_rate) && -+ !strcmp(node_name, devlink_rate->name)) -+ return devlink_rate; -+ } -+ return ERR_PTR(-ENODEV); -+} -+ -+static struct devlink_rate * -+devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs) -+{ -+ const char *rate_node_name; -+ size_t len; -+ -+ if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME]) -+ return ERR_PTR(-EINVAL); -+ rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]); -+ len = strlen(rate_node_name); -+ /* Name cannot be empty or decimal number */ -+ if (!len || strspn(rate_node_name, "0123456789") == len) -+ return ERR_PTR(-EINVAL); -+ -+ return devlink_rate_node_get_by_name(devlink, rate_node_name); -+} -+ -+static struct devlink_rate * -+devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info) -+{ -+ return devlink_rate_node_get_from_attrs(devlink, info->attrs); -+} -+ -+static struct devlink_rate * -+devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info) -+{ -+ struct nlattr **attrs = info->attrs; -+ -+ if (attrs[DEVLINK_ATTR_PORT_INDEX]) -+ return devlink_rate_leaf_get_from_info(devlink, info); -+ else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME]) -+ return devlink_rate_node_get_from_info(devlink, info); -+ else -+ return ERR_PTR(-EINVAL); -+} -+ -+static struct devlink_linecard * -+devlink_linecard_get_by_index(struct devlink *devlink, -+ unsigned int linecard_index) -+{ -+ struct devlink_linecard *devlink_linecard; -+ -+ list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) { -+ if (devlink_linecard->index == linecard_index) -+ return devlink_linecard; -+ } -+ return NULL; -+} -+ -+static bool devlink_linecard_index_exists(struct devlink *devlink, -+ unsigned int linecard_index) -+{ -+ return devlink_linecard_get_by_index(devlink, linecard_index); -+} -+ -+static struct devlink_linecard * -+devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs) -+{ -+ if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) { -+ u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]); -+ struct devlink_linecard *linecard; -+ -+ mutex_lock(&devlink->linecards_lock); -+ linecard = devlink_linecard_get_by_index(devlink, linecard_index); -+ if (linecard) -+ refcount_inc(&linecard->refcount); -+ mutex_unlock(&devlink->linecards_lock); -+ if (!linecard) -+ return ERR_PTR(-ENODEV); -+ return linecard; -+ } -+ return ERR_PTR(-EINVAL); -+} -+ -+static struct devlink_linecard * -+devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info) -+{ -+ return devlink_linecard_get_from_attrs(devlink, info->attrs); -+} -+ -+static void devlink_linecard_put(struct devlink_linecard *linecard) -+{ -+ if (refcount_dec_and_test(&linecard->refcount)) { -+ mutex_destroy(&linecard->state_lock); -+ kfree(linecard); -+ } -+} -+ -+struct devlink_sb { -+ struct list_head list; -+ unsigned int index; -+ u32 size; -+ u16 ingress_pools_count; -+ u16 egress_pools_count; -+ u16 ingress_tc_count; -+ u16 egress_tc_count; -+}; -+ -+static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb) -+{ -+ return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count; -+} -+ -+static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink, -+ unsigned int sb_index) -+{ -+ struct devlink_sb *devlink_sb; -+ -+ list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -+ if (devlink_sb->index == sb_index) -+ return devlink_sb; -+ } -+ return NULL; -+} -+ -+static bool devlink_sb_index_exists(struct devlink *devlink, -+ unsigned int sb_index) -+{ -+ return devlink_sb_get_by_index(devlink, sb_index); -+} -+ -+static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink, -+ struct nlattr **attrs) -+{ -+ if (attrs[DEVLINK_ATTR_SB_INDEX]) { -+ u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]); -+ struct devlink_sb *devlink_sb; -+ -+ devlink_sb = devlink_sb_get_by_index(devlink, sb_index); -+ if (!devlink_sb) -+ return ERR_PTR(-ENODEV); -+ return devlink_sb; -+ } -+ return ERR_PTR(-EINVAL); -+} -+ -+static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink, -+ struct genl_info *info) -+{ -+ return devlink_sb_get_from_attrs(devlink, info->attrs); -+} -+ -+static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb, -+ struct nlattr **attrs, -+ u16 *p_pool_index) -+{ -+ u16 val; -+ -+ if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX]) -+ return -EINVAL; -+ -+ val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]); -+ if (val >= devlink_sb_pool_count(devlink_sb)) -+ return -EINVAL; -+ *p_pool_index = val; -+ return 0; -+} -+ -+static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb, -+ struct genl_info *info, -+ u16 *p_pool_index) -+{ -+ return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs, -+ p_pool_index); -+} -+ -+static int -+devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs, -+ enum devlink_sb_pool_type *p_pool_type) -+{ -+ u8 val; -+ -+ if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE]) -+ return -EINVAL; -+ -+ val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]); -+ if (val != DEVLINK_SB_POOL_TYPE_INGRESS && -+ val != DEVLINK_SB_POOL_TYPE_EGRESS) -+ return -EINVAL; -+ *p_pool_type = val; -+ return 0; -+} -+ -+static int -+devlink_sb_pool_type_get_from_info(struct genl_info *info, -+ enum devlink_sb_pool_type *p_pool_type) -+{ -+ return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type); -+} -+ -+static int -+devlink_sb_th_type_get_from_attrs(struct nlattr **attrs, -+ enum devlink_sb_threshold_type *p_th_type) -+{ -+ u8 val; -+ -+ if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]) -+ return -EINVAL; -+ -+ val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]); -+ if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC && -+ val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC) -+ return -EINVAL; -+ *p_th_type = val; -+ return 0; -+} -+ -+static int -+devlink_sb_th_type_get_from_info(struct genl_info *info, -+ enum devlink_sb_threshold_type *p_th_type) -+{ -+ return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type); -+} -+ -+static int -+devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb, -+ struct nlattr **attrs, -+ enum devlink_sb_pool_type pool_type, -+ u16 *p_tc_index) -+{ -+ u16 val; -+ -+ if (!attrs[DEVLINK_ATTR_SB_TC_INDEX]) -+ return -EINVAL; -+ -+ val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]); -+ if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS && -+ val >= devlink_sb->ingress_tc_count) -+ return -EINVAL; -+ if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS && -+ val >= devlink_sb->egress_tc_count) -+ return -EINVAL; -+ *p_tc_index = val; -+ return 0; -+} -+ -+static int -+devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb, -+ struct genl_info *info, -+ enum devlink_sb_pool_type pool_type, -+ u16 *p_tc_index) -+{ -+ return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs, -+ pool_type, p_tc_index); -+} -+ -+struct devlink_region { -+ struct devlink *devlink; -+ struct devlink_port *port; -+ struct list_head list; -+ union { -+ const struct devlink_region_ops *ops; -+ const struct devlink_port_region_ops *port_ops; -+ }; -+ struct mutex snapshot_lock; /* protects snapshot_list, -+ * max_snapshots and cur_snapshots -+ * consistency. -+ */ -+ struct list_head snapshot_list; -+ u32 max_snapshots; -+ u32 cur_snapshots; -+ u64 size; -+}; -+ -+struct devlink_snapshot { -+ struct list_head list; -+ struct devlink_region *region; -+ u8 *data; -+ u32 id; -+}; -+ -+static struct devlink_region * -+devlink_region_get_by_name(struct devlink *devlink, const char *region_name) -+{ -+ struct devlink_region *region; -+ -+ list_for_each_entry(region, &devlink->region_list, list) -+ if (!strcmp(region->ops->name, region_name)) -+ return region; -+ -+ return NULL; -+} -+ -+static struct devlink_region * -+devlink_port_region_get_by_name(struct devlink_port *port, -+ const char *region_name) -+{ -+ struct devlink_region *region; -+ -+ list_for_each_entry(region, &port->region_list, list) -+ if (!strcmp(region->ops->name, region_name)) -+ return region; -+ -+ return NULL; -+} -+ -+static struct devlink_snapshot * -+devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id) -+{ -+ struct devlink_snapshot *snapshot; -+ -+ list_for_each_entry(snapshot, ®ion->snapshot_list, list) -+ if (snapshot->id == id) -+ return snapshot; -+ -+ return NULL; -+} -+ -+#define DEVLINK_NL_FLAG_NEED_PORT BIT(0) -+#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1) -+#define DEVLINK_NL_FLAG_NEED_RATE BIT(2) -+#define DEVLINK_NL_FLAG_NEED_RATE_NODE BIT(3) -+#define DEVLINK_NL_FLAG_NEED_LINECARD BIT(4) -+ -+static int devlink_nl_pre_doit(const struct genl_ops *ops, -+ struct sk_buff *skb, struct genl_info *info) -+{ -+ struct devlink_linecard *linecard; -+ struct devlink_port *devlink_port; -+ struct devlink *devlink; -+ int err; -+ -+ devlink = devlink_get_from_attrs(genl_info_net(info), info->attrs); -+ if (IS_ERR(devlink)) -+ return PTR_ERR(devlink); -+ devl_lock(devlink); -+ info->user_ptr[0] = devlink; -+ if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) { -+ devlink_port = devlink_port_get_from_info(devlink, info); -+ if (IS_ERR(devlink_port)) { -+ err = PTR_ERR(devlink_port); -+ goto unlock; -+ } -+ info->user_ptr[1] = devlink_port; -+ } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) { -+ devlink_port = devlink_port_get_from_info(devlink, info); -+ if (!IS_ERR(devlink_port)) -+ info->user_ptr[1] = devlink_port; -+ } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE) { -+ struct devlink_rate *devlink_rate; -+ -+ devlink_rate = devlink_rate_get_from_info(devlink, info); -+ if (IS_ERR(devlink_rate)) { -+ err = PTR_ERR(devlink_rate); -+ goto unlock; -+ } -+ info->user_ptr[1] = devlink_rate; -+ } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE_NODE) { -+ struct devlink_rate *rate_node; -+ -+ rate_node = devlink_rate_node_get_from_info(devlink, info); -+ if (IS_ERR(rate_node)) { -+ err = PTR_ERR(rate_node); -+ goto unlock; -+ } -+ info->user_ptr[1] = rate_node; -+ } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) { -+ linecard = devlink_linecard_get_from_info(devlink, info); -+ if (IS_ERR(linecard)) { -+ err = PTR_ERR(linecard); -+ goto unlock; -+ } -+ info->user_ptr[1] = linecard; -+ } -+ return 0; -+ -+unlock: -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ return err; -+} -+ -+static void devlink_nl_post_doit(const struct genl_ops *ops, -+ struct sk_buff *skb, struct genl_info *info) -+{ -+ struct devlink_linecard *linecard; -+ struct devlink *devlink; -+ -+ devlink = info->user_ptr[0]; -+ if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) { -+ linecard = info->user_ptr[1]; -+ devlink_linecard_put(linecard); -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+} -+ -+static struct genl_family devlink_nl_family; -+ -+enum devlink_multicast_groups { -+ DEVLINK_MCGRP_CONFIG, -+}; -+ -+static const struct genl_multicast_group devlink_nl_mcgrps[] = { -+ [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME }, -+}; -+ -+static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink) -+{ -+ if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name)) -+ return -EMSGSIZE; -+ if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev))) -+ return -EMSGSIZE; -+ return 0; -+} -+ -+static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink) -+{ -+ struct nlattr *nested_attr; -+ -+ nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK); -+ if (!nested_attr) -+ return -EMSGSIZE; -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ -+ nla_nest_end(msg, nested_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, nested_attr); -+ return -EMSGSIZE; -+} -+ -+struct devlink_reload_combination { -+ enum devlink_reload_action action; -+ enum devlink_reload_limit limit; -+}; -+ -+static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = { -+ { -+ /* can't reinitialize driver with no down time */ -+ .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT, -+ .limit = DEVLINK_RELOAD_LIMIT_NO_RESET, -+ }, -+}; -+ -+static bool -+devlink_reload_combination_is_invalid(enum devlink_reload_action action, -+ enum devlink_reload_limit limit) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) -+ if (devlink_reload_invalid_combinations[i].action == action && -+ devlink_reload_invalid_combinations[i].limit == limit) -+ return true; -+ return false; -+} -+ -+static bool -+devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action) -+{ -+ return test_bit(action, &devlink->ops->reload_actions); -+} -+ -+static bool -+devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit) -+{ -+ return test_bit(limit, &devlink->ops->reload_limits); -+} -+ -+static int devlink_reload_stat_put(struct sk_buff *msg, -+ enum devlink_reload_limit limit, u32 value) -+{ -+ struct nlattr *reload_stats_entry; -+ -+ reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY); -+ if (!reload_stats_entry) -+ return -EMSGSIZE; -+ -+ if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || -+ nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) -+ goto nla_put_failure; -+ nla_nest_end(msg, reload_stats_entry); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, reload_stats_entry); -+ return -EMSGSIZE; -+} -+ -+static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) -+{ -+ struct nlattr *reload_stats_attr, *act_info, *act_stats; -+ int i, j, stat_idx; -+ u32 value; -+ -+ if (!is_remote) -+ reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS); -+ else -+ reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS); -+ -+ if (!reload_stats_attr) -+ return -EMSGSIZE; -+ -+ for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { -+ if ((!is_remote && -+ !devlink_reload_action_is_supported(devlink, i)) || -+ i == DEVLINK_RELOAD_ACTION_UNSPEC) -+ continue; -+ act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); -+ if (!act_info) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) -+ goto action_info_nest_cancel; -+ act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); -+ if (!act_stats) -+ goto action_info_nest_cancel; -+ -+ for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { -+ /* Remote stats are shown even if not locally supported. -+ * Stats of actions with unspecified limit are shown -+ * though drivers don't need to register unspecified -+ * limit. -+ */ -+ if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && -+ !devlink_reload_limit_is_supported(devlink, j)) || -+ devlink_reload_combination_is_invalid(i, j)) -+ continue; -+ -+ stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i; -+ if (!is_remote) -+ value = devlink->stats.reload_stats[stat_idx]; -+ else -+ value = devlink->stats.remote_reload_stats[stat_idx]; -+ if (devlink_reload_stat_put(msg, j, value)) -+ goto action_stats_nest_cancel; -+ } -+ nla_nest_end(msg, act_stats); -+ nla_nest_end(msg, act_info); -+ } -+ nla_nest_end(msg, reload_stats_attr); -+ return 0; -+ -+action_stats_nest_cancel: -+ nla_nest_cancel(msg, act_stats); -+action_info_nest_cancel: -+ nla_nest_cancel(msg, act_info); -+nla_put_failure: -+ nla_nest_cancel(msg, reload_stats_attr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink, -+ enum devlink_command cmd, u32 portid, -+ u32 seq, int flags) -+{ -+ struct nlattr *dev_stats; -+ void *hdr; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed)) -+ goto nla_put_failure; -+ -+ dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS); -+ if (!dev_stats) -+ goto nla_put_failure; -+ -+ if (devlink_reload_stats_put(msg, devlink, false)) -+ goto dev_stats_nest_cancel; -+ if (devlink_reload_stats_put(msg, devlink, true)) -+ goto dev_stats_nest_cancel; -+ -+ nla_nest_end(msg, dev_stats); -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+dev_stats_nest_cancel: -+ nla_nest_cancel(msg, dev_stats); -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static void devlink_notify(struct devlink *devlink, enum devlink_command cmd) -+{ -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL); -+ WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)); -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -+ msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+static int devlink_nl_port_attrs_put(struct sk_buff *msg, -+ struct devlink_port *devlink_port) -+{ -+ struct devlink_port_attrs *attrs = &devlink_port->attrs; -+ -+ if (!devlink_port->attrs_set) -+ return 0; -+ if (attrs->lanes) { -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes)) -+ return -EMSGSIZE; -+ } -+ if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable)) -+ return -EMSGSIZE; -+ if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour)) -+ return -EMSGSIZE; -+ switch (devlink_port->attrs.flavour) { -+ case DEVLINK_PORT_FLAVOUR_PCI_PF: -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, -+ attrs->pci_pf.controller) || -+ nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf)) -+ return -EMSGSIZE; -+ if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external)) -+ return -EMSGSIZE; -+ break; -+ case DEVLINK_PORT_FLAVOUR_PCI_VF: -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, -+ attrs->pci_vf.controller) || -+ nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) || -+ nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf)) -+ return -EMSGSIZE; -+ if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external)) -+ return -EMSGSIZE; -+ break; -+ case DEVLINK_PORT_FLAVOUR_PCI_SF: -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, -+ attrs->pci_sf.controller) || -+ nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, -+ attrs->pci_sf.pf) || -+ nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER, -+ attrs->pci_sf.sf)) -+ return -EMSGSIZE; -+ break; -+ case DEVLINK_PORT_FLAVOUR_PHYSICAL: -+ case DEVLINK_PORT_FLAVOUR_CPU: -+ case DEVLINK_PORT_FLAVOUR_DSA: -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, -+ attrs->phys.port_number)) -+ return -EMSGSIZE; -+ if (!attrs->split) -+ return 0; -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, -+ attrs->phys.port_number)) -+ return -EMSGSIZE; -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER, -+ attrs->phys.split_subport_number)) -+ return -EMSGSIZE; -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops, -+ struct devlink_port *port, -+ struct sk_buff *msg, -+ struct netlink_ext_ack *extack, -+ bool *msg_updated) -+{ -+ u8 hw_addr[MAX_ADDR_LEN]; -+ int hw_addr_len; -+ int err; -+ -+ if (!ops->port_function_hw_addr_get) -+ return 0; -+ -+ err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len, -+ extack); -+ if (err) { -+ if (err == -EOPNOTSUPP) -+ return 0; -+ return err; -+ } -+ err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr); -+ if (err) -+ return err; -+ *msg_updated = true; -+ return 0; -+} -+ -+static int devlink_nl_rate_fill(struct sk_buff *msg, -+ struct devlink_rate *devlink_rate, -+ enum devlink_command cmd, u32 portid, u32 seq, -+ int flags, struct netlink_ext_ack *extack) -+{ -+ struct devlink *devlink = devlink_rate->devlink; -+ void *hdr; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ -+ if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type)) -+ goto nla_put_failure; -+ -+ if (devlink_rate_is_leaf(devlink_rate)) { -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, -+ devlink_rate->devlink_port->index)) -+ goto nla_put_failure; -+ } else if (devlink_rate_is_node(devlink_rate)) { -+ if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME, -+ devlink_rate->name)) -+ goto nla_put_failure; -+ } -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE, -+ devlink_rate->tx_share, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX, -+ devlink_rate->tx_max, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ if (devlink_rate->parent) -+ if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME, -+ devlink_rate->parent->name)) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static bool -+devlink_port_fn_state_valid(enum devlink_port_fn_state state) -+{ -+ return state == DEVLINK_PORT_FN_STATE_INACTIVE || -+ state == DEVLINK_PORT_FN_STATE_ACTIVE; -+} -+ -+static bool -+devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate) -+{ -+ return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED || -+ opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED; -+} -+ -+static int devlink_port_fn_state_fill(const struct devlink_ops *ops, -+ struct devlink_port *port, -+ struct sk_buff *msg, -+ struct netlink_ext_ack *extack, -+ bool *msg_updated) -+{ -+ enum devlink_port_fn_opstate opstate; -+ enum devlink_port_fn_state state; -+ int err; -+ -+ if (!ops->port_fn_state_get) -+ return 0; -+ -+ err = ops->port_fn_state_get(port, &state, &opstate, extack); -+ if (err) { -+ if (err == -EOPNOTSUPP) -+ return 0; -+ return err; -+ } -+ if (!devlink_port_fn_state_valid(state)) { -+ WARN_ON_ONCE(1); -+ NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver"); -+ return -EINVAL; -+ } -+ if (!devlink_port_fn_opstate_valid(opstate)) { -+ WARN_ON_ONCE(1); -+ NL_SET_ERR_MSG_MOD(extack, -+ "Invalid operational state read from driver"); -+ return -EINVAL; -+ } -+ if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) || -+ nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate)) -+ return -EMSGSIZE; -+ *msg_updated = true; -+ return 0; -+} -+ -+static int -+devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port, -+ struct netlink_ext_ack *extack) -+{ -+ const struct devlink_ops *ops; -+ struct nlattr *function_attr; -+ bool msg_updated = false; -+ int err; -+ -+ function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION); -+ if (!function_attr) -+ return -EMSGSIZE; -+ -+ ops = port->devlink->ops; -+ err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack, -+ &msg_updated); -+ if (err) -+ goto out; -+ err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated); -+out: -+ if (err || !msg_updated) -+ nla_nest_cancel(msg, function_attr); -+ else -+ nla_nest_end(msg, function_attr); -+ return err; -+} -+ -+static int devlink_nl_port_fill(struct sk_buff *msg, -+ struct devlink_port *devlink_port, -+ enum devlink_command cmd, u32 portid, u32 seq, -+ int flags, struct netlink_ext_ack *extack) -+{ -+ struct devlink *devlink = devlink_port->devlink; -+ void *hdr; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) -+ goto nla_put_failure; -+ -+ /* Hold rtnl lock while accessing port's netdev attributes. */ -+ rtnl_lock(); -+ spin_lock_bh(&devlink_port->type_lock); -+ if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type)) -+ goto nla_put_failure_type_locked; -+ if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET && -+ nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE, -+ devlink_port->desired_type)) -+ goto nla_put_failure_type_locked; -+ if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) { -+ struct net *net = devlink_net(devlink_port->devlink); -+ struct net_device *netdev = devlink_port->type_dev; -+ -+ if (netdev && net_eq(net, dev_net(netdev)) && -+ (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX, -+ netdev->ifindex) || -+ nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME, -+ netdev->name))) -+ goto nla_put_failure_type_locked; -+ } -+ if (devlink_port->type == DEVLINK_PORT_TYPE_IB) { -+ struct ib_device *ibdev = devlink_port->type_dev; -+ -+ if (ibdev && -+ nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME, -+ ibdev->name)) -+ goto nla_put_failure_type_locked; -+ } -+ spin_unlock_bh(&devlink_port->type_lock); -+ rtnl_unlock(); -+ if (devlink_nl_port_attrs_put(msg, devlink_port)) -+ goto nla_put_failure; -+ if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack)) -+ goto nla_put_failure; -+ if (devlink_port->linecard && -+ nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, -+ devlink_port->linecard->index)) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure_type_locked: -+ spin_unlock_bh(&devlink_port->type_lock); -+ rtnl_unlock(); -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static void devlink_port_notify(struct devlink_port *devlink_port, -+ enum devlink_command cmd) -+{ -+ struct devlink *devlink = devlink_port->devlink; -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL); -+ -+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -+ return; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, -+ 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+static void devlink_rate_notify(struct devlink_rate *devlink_rate, -+ enum devlink_command cmd) -+{ -+ struct devlink *devlink = devlink_rate->devlink; -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL); -+ -+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -+ return; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, -+ 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink_rate *devlink_rate; -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err = 0; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ devl_lock(devlink); -+ list_for_each_entry(devlink_rate, &devlink->rate_list, list) { -+ enum devlink_command cmd = DEVLINK_CMD_RATE_NEW; -+ u32 id = NETLINK_CB(cb->skb).portid; -+ -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI, NULL); -+ if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ } -+out: -+ if (err != -EMSGSIZE) -+ return err; -+ -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_rate *devlink_rate = info->user_ptr[1]; -+ struct sk_buff *msg; -+ int err; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW, -+ info->snd_portid, info->snd_seq, 0, -+ info->extack); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static bool -+devlink_rate_is_parent_node(struct devlink_rate *devlink_rate, -+ struct devlink_rate *parent) -+{ -+ while (parent) { -+ if (parent == devlink_rate) -+ return true; -+ parent = parent->parent; -+ } -+ return false; -+} -+ -+static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct sk_buff *msg; -+ int err; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, -+ info->snd_portid, info->snd_seq, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ if (idx < start) { -+ idx++; -+ devlink_put(devlink); -+ continue; -+ } -+ -+ devl_lock(devlink); -+ err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, NLM_F_MULTI); -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ -+ if (err) -+ goto out; -+ idx++; -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port = info->user_ptr[1]; -+ struct sk_buff *msg; -+ int err; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW, -+ info->snd_portid, info->snd_seq, 0, -+ info->extack); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ struct devlink_port *devlink_port; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ devl_lock(devlink); -+ list_for_each_entry(devlink_port, &devlink->port_list, list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_port_fill(msg, devlink_port, -+ DEVLINK_CMD_NEW, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI, cb->extack); -+ if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_port_type_set(struct devlink_port *devlink_port, -+ enum devlink_port_type port_type) -+ -+{ -+ int err; -+ -+ if (!devlink_port->devlink->ops->port_type_set) -+ return -EOPNOTSUPP; -+ -+ if (port_type == devlink_port->type) -+ return 0; -+ -+ err = devlink_port->devlink->ops->port_type_set(devlink_port, -+ port_type); -+ if (err) -+ return err; -+ -+ devlink_port->desired_type = port_type; -+ devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); -+ return 0; -+} -+ -+static int devlink_port_function_hw_addr_set(struct devlink_port *port, -+ const struct nlattr *attr, -+ struct netlink_ext_ack *extack) -+{ -+ const struct devlink_ops *ops = port->devlink->ops; -+ const u8 *hw_addr; -+ int hw_addr_len; -+ -+ hw_addr = nla_data(attr); -+ hw_addr_len = nla_len(attr); -+ if (hw_addr_len > MAX_ADDR_LEN) { -+ NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long"); -+ return -EINVAL; -+ } -+ if (port->type == DEVLINK_PORT_TYPE_ETH) { -+ if (hw_addr_len != ETH_ALEN) { -+ NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device"); -+ return -EINVAL; -+ } -+ if (!is_unicast_ether_addr(hw_addr)) { -+ NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported"); -+ return -EINVAL; -+ } -+ } -+ -+ if (!ops->port_function_hw_addr_set) { -+ NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes"); -+ return -EOPNOTSUPP; -+ } -+ -+ return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len, -+ extack); -+} -+ -+static int devlink_port_fn_state_set(struct devlink_port *port, -+ const struct nlattr *attr, -+ struct netlink_ext_ack *extack) -+{ -+ enum devlink_port_fn_state state; -+ const struct devlink_ops *ops; -+ -+ state = nla_get_u8(attr); -+ ops = port->devlink->ops; -+ if (!ops->port_fn_state_set) { -+ NL_SET_ERR_MSG_MOD(extack, -+ "Function does not support state setting"); -+ return -EOPNOTSUPP; -+ } -+ return ops->port_fn_state_set(port, state, extack); -+} -+ -+static int devlink_port_function_set(struct devlink_port *port, -+ const struct nlattr *attr, -+ struct netlink_ext_ack *extack) -+{ -+ struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1]; -+ int err; -+ -+ err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr, -+ devlink_function_nl_policy, extack); -+ if (err < 0) { -+ NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes"); -+ return err; -+ } -+ -+ attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR]; -+ if (attr) { -+ err = devlink_port_function_hw_addr_set(port, attr, extack); -+ if (err) -+ return err; -+ } -+ /* Keep this as the last function attribute set, so that when -+ * multiple port function attributes are set along with state, -+ * Those can be applied first before activating the state. -+ */ -+ attr = tb[DEVLINK_PORT_FN_ATTR_STATE]; -+ if (attr) -+ err = devlink_port_fn_state_set(port, attr, extack); -+ -+ if (!err) -+ devlink_port_notify(port, DEVLINK_CMD_PORT_NEW); -+ return err; -+} -+ -+static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port = info->user_ptr[1]; -+ int err; -+ -+ if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) { -+ enum devlink_port_type port_type; -+ -+ port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]); -+ err = devlink_port_type_set(devlink_port, port_type); -+ if (err) -+ return err; -+ } -+ -+ if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) { -+ struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION]; -+ struct netlink_ext_ack *extack = info->extack; -+ -+ err = devlink_port_function_set(devlink_port, attr, extack); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port = info->user_ptr[1]; -+ struct devlink *devlink = info->user_ptr[0]; -+ u32 count; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT)) -+ return -EINVAL; -+ if (!devlink->ops->port_split) -+ return -EOPNOTSUPP; -+ -+ count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); -+ -+ if (!devlink_port->attrs.splittable) { -+ /* Split ports cannot be split. */ -+ if (devlink_port->attrs.split) -+ NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further"); -+ else -+ NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split"); -+ return -EINVAL; -+ } -+ -+ if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count"); -+ return -EINVAL; -+ } -+ -+ return devlink->ops->port_split(devlink, devlink_port, count, -+ info->extack); -+} -+ -+static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port = info->user_ptr[1]; -+ struct devlink *devlink = info->user_ptr[0]; -+ -+ if (!devlink->ops->port_unsplit) -+ return -EOPNOTSUPP; -+ return devlink->ops->port_unsplit(devlink, devlink_port, info->extack); -+} -+ -+static int devlink_port_new_notify(struct devlink *devlink, -+ unsigned int port_index, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port; -+ struct sk_buff *msg; -+ int err; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ lockdep_assert_held(&devlink->lock); -+ devlink_port = devlink_port_get_by_index(devlink, port_index); -+ if (!devlink_port) { -+ err = -ENODEV; -+ goto out; -+ } -+ -+ err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW, -+ info->snd_portid, info->snd_seq, 0, NULL); -+ if (err) -+ goto out; -+ -+ return genlmsg_reply(msg, info); -+ -+out: -+ nlmsg_free(msg); -+ return err; -+} -+ -+static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct netlink_ext_ack *extack = info->extack; -+ struct devlink_port_new_attrs new_attrs = {}; -+ struct devlink *devlink = info->user_ptr[0]; -+ unsigned int new_port_index; -+ int err; -+ -+ if (!devlink->ops->port_new || !devlink->ops->port_del) -+ return -EOPNOTSUPP; -+ -+ if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] || -+ !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) { -+ NL_SET_ERR_MSG_MOD(extack, "Port flavour or PCI PF are not specified"); -+ return -EINVAL; -+ } -+ new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]); -+ new_attrs.pfnum = -+ nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]); -+ -+ if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -+ /* Port index of the new port being created by driver. */ -+ new_attrs.port_index = -+ nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -+ new_attrs.port_index_valid = true; -+ } -+ if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) { -+ new_attrs.controller = -+ nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]); -+ new_attrs.controller_valid = true; -+ } -+ if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF && -+ info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) { -+ new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]); -+ new_attrs.sfnum_valid = true; -+ } -+ -+ err = devlink->ops->port_new(devlink, &new_attrs, extack, -+ &new_port_index); -+ if (err) -+ return err; -+ -+ err = devlink_port_new_notify(devlink, new_port_index, info); -+ if (err && err != -ENODEV) { -+ /* Fail to send the response; destroy newly created port. */ -+ devlink->ops->port_del(devlink, new_port_index, extack); -+ } -+ return err; -+} -+ -+static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct netlink_ext_ack *extack = info->extack; -+ struct devlink *devlink = info->user_ptr[0]; -+ unsigned int port_index; -+ -+ if (!devlink->ops->port_del) -+ return -EOPNOTSUPP; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) { -+ NL_SET_ERR_MSG_MOD(extack, "Port index is not specified"); -+ return -EINVAL; -+ } -+ port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -+ -+ return devlink->ops->port_del(devlink, port_index, extack); -+} -+ -+static int -+devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate, -+ struct genl_info *info, -+ struct nlattr *nla_parent) -+{ -+ struct devlink *devlink = devlink_rate->devlink; -+ const char *parent_name = nla_data(nla_parent); -+ const struct devlink_ops *ops = devlink->ops; -+ size_t len = strlen(parent_name); -+ struct devlink_rate *parent; -+ int err = -EOPNOTSUPP; -+ -+ parent = devlink_rate->parent; -+ if (parent && len) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Rate object already has parent."); -+ return -EBUSY; -+ } else if (parent && !len) { -+ if (devlink_rate_is_leaf(devlink_rate)) -+ err = ops->rate_leaf_parent_set(devlink_rate, NULL, -+ devlink_rate->priv, NULL, -+ info->extack); -+ else if (devlink_rate_is_node(devlink_rate)) -+ err = ops->rate_node_parent_set(devlink_rate, NULL, -+ devlink_rate->priv, NULL, -+ info->extack); -+ if (err) -+ return err; -+ -+ refcount_dec(&parent->refcnt); -+ devlink_rate->parent = NULL; -+ } else if (!parent && len) { -+ parent = devlink_rate_node_get_by_name(devlink, parent_name); -+ if (IS_ERR(parent)) -+ return -ENODEV; -+ -+ if (parent == devlink_rate) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed"); -+ return -EINVAL; -+ } -+ -+ if (devlink_rate_is_node(devlink_rate) && -+ devlink_rate_is_parent_node(devlink_rate, parent->parent)) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Node is already a parent of parent node."); -+ return -EEXIST; -+ } -+ -+ if (devlink_rate_is_leaf(devlink_rate)) -+ err = ops->rate_leaf_parent_set(devlink_rate, parent, -+ devlink_rate->priv, parent->priv, -+ info->extack); -+ else if (devlink_rate_is_node(devlink_rate)) -+ err = ops->rate_node_parent_set(devlink_rate, parent, -+ devlink_rate->priv, parent->priv, -+ info->extack); -+ if (err) -+ return err; -+ -+ refcount_inc(&parent->refcnt); -+ devlink_rate->parent = parent; -+ } -+ -+ return 0; -+} -+ -+static int devlink_nl_rate_set(struct devlink_rate *devlink_rate, -+ const struct devlink_ops *ops, -+ struct genl_info *info) -+{ -+ struct nlattr *nla_parent, **attrs = info->attrs; -+ int err = -EOPNOTSUPP; -+ u64 rate; -+ -+ if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) { -+ rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]); -+ if (devlink_rate_is_leaf(devlink_rate)) -+ err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv, -+ rate, info->extack); -+ else if (devlink_rate_is_node(devlink_rate)) -+ err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv, -+ rate, info->extack); -+ if (err) -+ return err; -+ devlink_rate->tx_share = rate; -+ } -+ -+ if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) { -+ rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]); -+ if (devlink_rate_is_leaf(devlink_rate)) -+ err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv, -+ rate, info->extack); -+ else if (devlink_rate_is_node(devlink_rate)) -+ err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv, -+ rate, info->extack); -+ if (err) -+ return err; -+ devlink_rate->tx_max = rate; -+ } -+ -+ nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME]; -+ if (nla_parent) { -+ err = devlink_nl_rate_parent_node_set(devlink_rate, info, -+ nla_parent); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops, -+ struct genl_info *info, -+ enum devlink_rate_type type) -+{ -+ struct nlattr **attrs = info->attrs; -+ -+ if (type == DEVLINK_RATE_TYPE_LEAF) { -+ if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) { -+ NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the leafs"); -+ return false; -+ } -+ if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) { -+ NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the leafs"); -+ return false; -+ } -+ if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] && -+ !ops->rate_leaf_parent_set) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs"); -+ return false; -+ } -+ } else if (type == DEVLINK_RATE_TYPE_NODE) { -+ if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) { -+ NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes"); -+ return false; -+ } -+ if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) { -+ NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the nodes"); -+ return false; -+ } -+ if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] && -+ !ops->rate_node_parent_set) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes"); -+ return false; -+ } -+ } else { -+ WARN(1, "Unknown type of rate object"); -+ return false; -+ } -+ -+ return true; -+} -+ -+static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_rate *devlink_rate = info->user_ptr[1]; -+ struct devlink *devlink = devlink_rate->devlink; -+ const struct devlink_ops *ops = devlink->ops; -+ int err; -+ -+ if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type)) -+ return -EOPNOTSUPP; -+ -+ err = devlink_nl_rate_set(devlink_rate, ops, info); -+ -+ if (!err) -+ devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); -+ return err; -+} -+ -+static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_rate *rate_node; -+ const struct devlink_ops *ops; -+ int err; -+ -+ ops = devlink->ops; -+ if (!ops || !ops->rate_node_new || !ops->rate_node_del) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Rate nodes aren't supported"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE)) -+ return -EOPNOTSUPP; -+ -+ rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs); -+ if (!IS_ERR(rate_node)) -+ return -EEXIST; -+ else if (rate_node == ERR_PTR(-EINVAL)) -+ return -EINVAL; -+ -+ rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL); -+ if (!rate_node) -+ return -ENOMEM; -+ -+ rate_node->devlink = devlink; -+ rate_node->type = DEVLINK_RATE_TYPE_NODE; -+ rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL); -+ if (!rate_node->name) { -+ err = -ENOMEM; -+ goto err_strdup; -+ } -+ -+ err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack); -+ if (err) -+ goto err_node_new; -+ -+ err = devlink_nl_rate_set(rate_node, ops, info); -+ if (err) -+ goto err_rate_set; -+ -+ refcount_set(&rate_node->refcnt, 1); -+ list_add(&rate_node->list, &devlink->rate_list); -+ devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); -+ return 0; -+ -+err_rate_set: -+ ops->rate_node_del(rate_node, rate_node->priv, info->extack); -+err_node_new: -+ kfree(rate_node->name); -+err_strdup: -+ kfree(rate_node); -+ return err; -+} -+ -+static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_rate *rate_node = info->user_ptr[1]; -+ struct devlink *devlink = rate_node->devlink; -+ const struct devlink_ops *ops = devlink->ops; -+ int err; -+ -+ if (refcount_read(&rate_node->refcnt) > 1) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node."); -+ return -EBUSY; -+ } -+ -+ devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); -+ err = ops->rate_node_del(rate_node, rate_node->priv, info->extack); -+ if (rate_node->parent) -+ refcount_dec(&rate_node->parent->refcnt); -+ list_del(&rate_node->list); -+ kfree(rate_node->name); -+ kfree(rate_node); -+ return err; -+} -+ -+struct devlink_linecard_type { -+ const char *type; -+ const void *priv; -+}; -+ -+static int devlink_nl_linecard_fill(struct sk_buff *msg, -+ struct devlink *devlink, -+ struct devlink_linecard *linecard, -+ enum devlink_command cmd, u32 portid, -+ u32 seq, int flags, -+ struct netlink_ext_ack *extack) -+{ -+ struct devlink_linecard_type *linecard_type; -+ struct nlattr *attr; -+ void *hdr; -+ int i; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state)) -+ goto nla_put_failure; -+ if (linecard->type && -+ nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type)) -+ goto nla_put_failure; -+ -+ if (linecard->types_count) { -+ attr = nla_nest_start(msg, -+ DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES); -+ if (!attr) -+ goto nla_put_failure; -+ for (i = 0; i < linecard->types_count; i++) { -+ linecard_type = &linecard->types[i]; -+ if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, -+ linecard_type->type)) { -+ nla_nest_cancel(msg, attr); -+ goto nla_put_failure; -+ } -+ } -+ nla_nest_end(msg, attr); -+ } -+ -+ if (linecard->nested_devlink && -+ devlink_nl_put_nested_handle(msg, linecard->nested_devlink)) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static void devlink_linecard_notify(struct devlink_linecard *linecard, -+ enum devlink_command cmd) -+{ -+ struct devlink *devlink = linecard->devlink; -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW && -+ cmd != DEVLINK_CMD_LINECARD_DEL); -+ -+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -+ return; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0, -+ NULL); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -+ msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_linecard *linecard = info->user_ptr[1]; -+ struct devlink *devlink = linecard->devlink; -+ struct sk_buff *msg; -+ int err; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ mutex_lock(&linecard->state_lock); -+ err = devlink_nl_linecard_fill(msg, devlink, linecard, -+ DEVLINK_CMD_LINECARD_NEW, -+ info->snd_portid, info->snd_seq, 0, -+ info->extack); -+ mutex_unlock(&linecard->state_lock); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink_linecard *linecard; -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ mutex_lock(&devlink->linecards_lock); -+ list_for_each_entry(linecard, &devlink->linecard_list, list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ mutex_lock(&linecard->state_lock); -+ err = devlink_nl_linecard_fill(msg, devlink, linecard, -+ DEVLINK_CMD_LINECARD_NEW, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI, -+ cb->extack); -+ mutex_unlock(&linecard->state_lock); -+ if (err) { -+ mutex_unlock(&devlink->linecards_lock); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ mutex_unlock(&devlink->linecards_lock); -+ devlink_put(devlink); -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static struct devlink_linecard_type * -+devlink_linecard_type_lookup(struct devlink_linecard *linecard, -+ const char *type) -+{ -+ struct devlink_linecard_type *linecard_type; -+ int i; -+ -+ for (i = 0; i < linecard->types_count; i++) { -+ linecard_type = &linecard->types[i]; -+ if (!strcmp(type, linecard_type->type)) -+ return linecard_type; -+ } -+ return NULL; -+} -+ -+static int devlink_linecard_type_set(struct devlink_linecard *linecard, -+ const char *type, -+ struct netlink_ext_ack *extack) -+{ -+ const struct devlink_linecard_ops *ops = linecard->ops; -+ struct devlink_linecard_type *linecard_type; -+ int err; -+ -+ mutex_lock(&linecard->state_lock); -+ if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) { -+ NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned"); -+ err = -EBUSY; -+ goto out; -+ } -+ if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) { -+ NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned"); -+ err = -EBUSY; -+ goto out; -+ } -+ -+ linecard_type = devlink_linecard_type_lookup(linecard, type); -+ if (!linecard_type) { -+ NL_SET_ERR_MSG_MOD(extack, "Unsupported line card type provided"); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED && -+ linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) { -+ NL_SET_ERR_MSG_MOD(extack, "Line card already provisioned"); -+ err = -EBUSY; -+ /* Check if the line card is provisioned in the same -+ * way the user asks. In case it is, make the operation -+ * to return success. -+ */ -+ if (ops->same_provision && -+ ops->same_provision(linecard, linecard->priv, -+ linecard_type->type, -+ linecard_type->priv)) -+ err = 0; -+ goto out; -+ } -+ -+ linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING; -+ linecard->type = linecard_type->type; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+ err = ops->provision(linecard, linecard->priv, linecard_type->type, -+ linecard_type->priv, extack); -+ if (err) { -+ /* Provisioning failed. Assume the linecard is unprovisioned -+ * for future operations. -+ */ -+ mutex_lock(&linecard->state_lock); -+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -+ linecard->type = NULL; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+ } -+ return err; -+ -+out: -+ mutex_unlock(&linecard->state_lock); -+ return err; -+} -+ -+static int devlink_linecard_type_unset(struct devlink_linecard *linecard, -+ struct netlink_ext_ack *extack) -+{ -+ int err; -+ -+ mutex_lock(&linecard->state_lock); -+ if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) { -+ NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned"); -+ err = -EBUSY; -+ goto out; -+ } -+ if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) { -+ NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned"); -+ err = -EBUSY; -+ goto out; -+ } -+ if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) { -+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -+ linecard->type = NULL; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ err = 0; -+ goto out; -+ } -+ -+ if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) { -+ NL_SET_ERR_MSG_MOD(extack, "Line card is not provisioned"); -+ err = 0; -+ goto out; -+ } -+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+ err = linecard->ops->unprovision(linecard, linecard->priv, -+ extack); -+ if (err) { -+ /* Unprovisioning failed. Assume the linecard is unprovisioned -+ * for future operations. -+ */ -+ mutex_lock(&linecard->state_lock); -+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -+ linecard->type = NULL; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+ } -+ return err; -+ -+out: -+ mutex_unlock(&linecard->state_lock); -+ return err; -+} -+ -+static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_linecard *linecard = info->user_ptr[1]; -+ struct netlink_ext_ack *extack = info->extack; -+ int err; -+ -+ if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) { -+ const char *type; -+ -+ type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]); -+ if (strcmp(type, "")) { -+ err = devlink_linecard_type_set(linecard, type, extack); -+ if (err) -+ return err; -+ } else { -+ err = devlink_linecard_type_unset(linecard, extack); -+ if (err) -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ -+static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink, -+ struct devlink_sb *devlink_sb, -+ enum devlink_command cmd, u32 portid, -+ u32 seq, int flags) -+{ -+ void *hdr; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT, -+ devlink_sb->ingress_pools_count)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT, -+ devlink_sb->egress_pools_count)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT, -+ devlink_sb->ingress_tc_count)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT, -+ devlink_sb->egress_tc_count)) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_sb *devlink_sb; -+ struct sk_buff *msg; -+ int err; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_sb_fill(msg, devlink, devlink_sb, -+ DEVLINK_CMD_SB_NEW, -+ info->snd_portid, info->snd_seq, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ struct devlink_sb *devlink_sb; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ devl_lock(devlink); -+ list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_sb_fill(msg, devlink, devlink_sb, -+ DEVLINK_CMD_SB_NEW, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI); -+ if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink, -+ struct devlink_sb *devlink_sb, -+ u16 pool_index, enum devlink_command cmd, -+ u32 portid, u32 seq, int flags) -+{ -+ struct devlink_sb_pool_info pool_info; -+ void *hdr; -+ int err; -+ -+ err = devlink->ops->sb_pool_get(devlink, devlink_sb->index, -+ pool_index, &pool_info); -+ if (err) -+ return err; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE, -+ pool_info.threshold_type)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE, -+ pool_info.cell_size)) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_sb *devlink_sb; -+ struct sk_buff *msg; -+ u16 pool_index; -+ int err; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -+ &pool_index); -+ if (err) -+ return err; -+ -+ if (!devlink->ops->sb_pool_get) -+ return -EOPNOTSUPP; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index, -+ DEVLINK_CMD_SB_POOL_NEW, -+ info->snd_portid, info->snd_seq, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, -+ struct devlink *devlink, -+ struct devlink_sb *devlink_sb, -+ u32 portid, u32 seq) -+{ -+ u16 pool_count = devlink_sb_pool_count(devlink_sb); -+ u16 pool_index; -+ int err; -+ -+ for (pool_index = 0; pool_index < pool_count; pool_index++) { -+ if (*p_idx < start) { -+ (*p_idx)++; -+ continue; -+ } -+ err = devlink_nl_sb_pool_fill(msg, devlink, -+ devlink_sb, -+ pool_index, -+ DEVLINK_CMD_SB_POOL_NEW, -+ portid, seq, NLM_F_MULTI); -+ if (err) -+ return err; -+ (*p_idx)++; -+ } -+ return 0; -+} -+ -+static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ struct devlink_sb *devlink_sb; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err = 0; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ if (!devlink->ops->sb_pool_get) -+ goto retry; -+ -+ devl_lock(devlink); -+ list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -+ err = __sb_pool_get_dumpit(msg, start, &idx, devlink, -+ devlink_sb, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq); -+ if (err == -EOPNOTSUPP) { -+ err = 0; -+ } else if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ } -+ devl_unlock(devlink); -+retry: -+ devlink_put(devlink); -+ } -+out: -+ if (err != -EMSGSIZE) -+ return err; -+ -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index, -+ u16 pool_index, u32 size, -+ enum devlink_sb_threshold_type threshold_type, -+ struct netlink_ext_ack *extack) -+ -+{ -+ const struct devlink_ops *ops = devlink->ops; -+ -+ if (ops->sb_pool_set) -+ return ops->sb_pool_set(devlink, sb_index, pool_index, -+ size, threshold_type, extack); -+ return -EOPNOTSUPP; -+} -+ -+static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ enum devlink_sb_threshold_type threshold_type; -+ struct devlink_sb *devlink_sb; -+ u16 pool_index; -+ u32 size; -+ int err; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -+ &pool_index); -+ if (err) -+ return err; -+ -+ err = devlink_sb_th_type_get_from_info(info, &threshold_type); -+ if (err) -+ return err; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE)) -+ return -EINVAL; -+ -+ size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]); -+ return devlink_sb_pool_set(devlink, devlink_sb->index, -+ pool_index, size, threshold_type, -+ info->extack); -+} -+ -+static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg, -+ struct devlink *devlink, -+ struct devlink_port *devlink_port, -+ struct devlink_sb *devlink_sb, -+ u16 pool_index, -+ enum devlink_command cmd, -+ u32 portid, u32 seq, int flags) -+{ -+ const struct devlink_ops *ops = devlink->ops; -+ u32 threshold; -+ void *hdr; -+ int err; -+ -+ err = ops->sb_port_pool_get(devlink_port, devlink_sb->index, -+ pool_index, &threshold); -+ if (err) -+ return err; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) -+ goto nla_put_failure; -+ -+ if (ops->sb_occ_port_pool_get) { -+ u32 cur; -+ u32 max; -+ -+ err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index, -+ pool_index, &cur, &max); -+ if (err && err != -EOPNOTSUPP) -+ goto sb_occ_get_failure; -+ if (!err) { -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) -+ goto nla_put_failure; -+ } -+ } -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ err = -EMSGSIZE; -+sb_occ_get_failure: -+ genlmsg_cancel(msg, hdr); -+ return err; -+} -+ -+static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port = info->user_ptr[1]; -+ struct devlink *devlink = devlink_port->devlink; -+ struct devlink_sb *devlink_sb; -+ struct sk_buff *msg; -+ u16 pool_index; -+ int err; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -+ &pool_index); -+ if (err) -+ return err; -+ -+ if (!devlink->ops->sb_port_pool_get) -+ return -EOPNOTSUPP; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port, -+ devlink_sb, pool_index, -+ DEVLINK_CMD_SB_PORT_POOL_NEW, -+ info->snd_portid, info->snd_seq, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, -+ struct devlink *devlink, -+ struct devlink_sb *devlink_sb, -+ u32 portid, u32 seq) -+{ -+ struct devlink_port *devlink_port; -+ u16 pool_count = devlink_sb_pool_count(devlink_sb); -+ u16 pool_index; -+ int err; -+ -+ list_for_each_entry(devlink_port, &devlink->port_list, list) { -+ for (pool_index = 0; pool_index < pool_count; pool_index++) { -+ if (*p_idx < start) { -+ (*p_idx)++; -+ continue; -+ } -+ err = devlink_nl_sb_port_pool_fill(msg, devlink, -+ devlink_port, -+ devlink_sb, -+ pool_index, -+ DEVLINK_CMD_SB_PORT_POOL_NEW, -+ portid, seq, -+ NLM_F_MULTI); -+ if (err) -+ return err; -+ (*p_idx)++; -+ } -+ } -+ return 0; -+} -+ -+static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ struct devlink_sb *devlink_sb; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err = 0; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ if (!devlink->ops->sb_port_pool_get) -+ goto retry; -+ -+ devl_lock(devlink); -+ list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -+ err = __sb_port_pool_get_dumpit(msg, start, &idx, -+ devlink, devlink_sb, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq); -+ if (err == -EOPNOTSUPP) { -+ err = 0; -+ } else if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ } -+ devl_unlock(devlink); -+retry: -+ devlink_put(devlink); -+ } -+out: -+ if (err != -EMSGSIZE) -+ return err; -+ -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_sb_port_pool_set(struct devlink_port *devlink_port, -+ unsigned int sb_index, u16 pool_index, -+ u32 threshold, -+ struct netlink_ext_ack *extack) -+ -+{ -+ const struct devlink_ops *ops = devlink_port->devlink->ops; -+ -+ if (ops->sb_port_pool_set) -+ return ops->sb_port_pool_set(devlink_port, sb_index, -+ pool_index, threshold, extack); -+ return -EOPNOTSUPP; -+} -+ -+static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port = info->user_ptr[1]; -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_sb *devlink_sb; -+ u16 pool_index; -+ u32 threshold; -+ int err; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -+ &pool_index); -+ if (err) -+ return err; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD)) -+ return -EINVAL; -+ -+ threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); -+ return devlink_sb_port_pool_set(devlink_port, devlink_sb->index, -+ pool_index, threshold, info->extack); -+} -+ -+static int -+devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink, -+ struct devlink_port *devlink_port, -+ struct devlink_sb *devlink_sb, u16 tc_index, -+ enum devlink_sb_pool_type pool_type, -+ enum devlink_command cmd, -+ u32 portid, u32 seq, int flags) -+{ -+ const struct devlink_ops *ops = devlink->ops; -+ u16 pool_index; -+ u32 threshold; -+ void *hdr; -+ int err; -+ -+ err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index, -+ tc_index, pool_type, -+ &pool_index, &threshold); -+ if (err) -+ return err; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) -+ goto nla_put_failure; -+ -+ if (ops->sb_occ_tc_port_bind_get) { -+ u32 cur; -+ u32 max; -+ -+ err = ops->sb_occ_tc_port_bind_get(devlink_port, -+ devlink_sb->index, -+ tc_index, pool_type, -+ &cur, &max); -+ if (err && err != -EOPNOTSUPP) -+ return err; -+ if (!err) { -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max)) -+ goto nla_put_failure; -+ } -+ } -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port = info->user_ptr[1]; -+ struct devlink *devlink = devlink_port->devlink; -+ struct devlink_sb *devlink_sb; -+ struct sk_buff *msg; -+ enum devlink_sb_pool_type pool_type; -+ u16 tc_index; -+ int err; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ err = devlink_sb_pool_type_get_from_info(info, &pool_type); -+ if (err) -+ return err; -+ -+ err = devlink_sb_tc_index_get_from_info(devlink_sb, info, -+ pool_type, &tc_index); -+ if (err) -+ return err; -+ -+ if (!devlink->ops->sb_tc_pool_bind_get) -+ return -EOPNOTSUPP; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port, -+ devlink_sb, tc_index, pool_type, -+ DEVLINK_CMD_SB_TC_POOL_BIND_NEW, -+ info->snd_portid, -+ info->snd_seq, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, -+ int start, int *p_idx, -+ struct devlink *devlink, -+ struct devlink_sb *devlink_sb, -+ u32 portid, u32 seq) -+{ -+ struct devlink_port *devlink_port; -+ u16 tc_index; -+ int err; -+ -+ list_for_each_entry(devlink_port, &devlink->port_list, list) { -+ for (tc_index = 0; -+ tc_index < devlink_sb->ingress_tc_count; tc_index++) { -+ if (*p_idx < start) { -+ (*p_idx)++; -+ continue; -+ } -+ err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, -+ devlink_port, -+ devlink_sb, -+ tc_index, -+ DEVLINK_SB_POOL_TYPE_INGRESS, -+ DEVLINK_CMD_SB_TC_POOL_BIND_NEW, -+ portid, seq, -+ NLM_F_MULTI); -+ if (err) -+ return err; -+ (*p_idx)++; -+ } -+ for (tc_index = 0; -+ tc_index < devlink_sb->egress_tc_count; tc_index++) { -+ if (*p_idx < start) { -+ (*p_idx)++; -+ continue; -+ } -+ err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, -+ devlink_port, -+ devlink_sb, -+ tc_index, -+ DEVLINK_SB_POOL_TYPE_EGRESS, -+ DEVLINK_CMD_SB_TC_POOL_BIND_NEW, -+ portid, seq, -+ NLM_F_MULTI); -+ if (err) -+ return err; -+ (*p_idx)++; -+ } -+ } -+ return 0; -+} -+ -+static int -+devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ struct devlink_sb *devlink_sb; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err = 0; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ if (!devlink->ops->sb_tc_pool_bind_get) -+ goto retry; -+ -+ devl_lock(devlink); -+ list_for_each_entry(devlink_sb, &devlink->sb_list, list) { -+ err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx, -+ devlink, -+ devlink_sb, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq); -+ if (err == -EOPNOTSUPP) { -+ err = 0; -+ } else if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ } -+ devl_unlock(devlink); -+retry: -+ devlink_put(devlink); -+ } -+out: -+ if (err != -EMSGSIZE) -+ return err; -+ -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, -+ unsigned int sb_index, u16 tc_index, -+ enum devlink_sb_pool_type pool_type, -+ u16 pool_index, u32 threshold, -+ struct netlink_ext_ack *extack) -+ -+{ -+ const struct devlink_ops *ops = devlink_port->devlink->ops; -+ -+ if (ops->sb_tc_pool_bind_set) -+ return ops->sb_tc_pool_bind_set(devlink_port, sb_index, -+ tc_index, pool_type, -+ pool_index, threshold, extack); -+ return -EOPNOTSUPP; -+} -+ -+static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_port *devlink_port = info->user_ptr[1]; -+ struct devlink *devlink = info->user_ptr[0]; -+ enum devlink_sb_pool_type pool_type; -+ struct devlink_sb *devlink_sb; -+ u16 tc_index; -+ u16 pool_index; -+ u32 threshold; -+ int err; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ err = devlink_sb_pool_type_get_from_info(info, &pool_type); -+ if (err) -+ return err; -+ -+ err = devlink_sb_tc_index_get_from_info(devlink_sb, info, -+ pool_type, &tc_index); -+ if (err) -+ return err; -+ -+ err = devlink_sb_pool_index_get_from_info(devlink_sb, info, -+ &pool_index); -+ if (err) -+ return err; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD)) -+ return -EINVAL; -+ -+ threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]); -+ return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index, -+ tc_index, pool_type, -+ pool_index, threshold, info->extack); -+} -+ -+static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ const struct devlink_ops *ops = devlink->ops; -+ struct devlink_sb *devlink_sb; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ if (ops->sb_occ_snapshot) -+ return ops->sb_occ_snapshot(devlink, devlink_sb->index); -+ return -EOPNOTSUPP; -+} -+ -+static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ const struct devlink_ops *ops = devlink->ops; -+ struct devlink_sb *devlink_sb; -+ -+ devlink_sb = devlink_sb_get_from_info(devlink, info); -+ if (IS_ERR(devlink_sb)) -+ return PTR_ERR(devlink_sb); -+ -+ if (ops->sb_occ_max_clear) -+ return ops->sb_occ_max_clear(devlink, devlink_sb->index); -+ return -EOPNOTSUPP; -+} -+ -+static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, -+ enum devlink_command cmd, u32 portid, -+ u32 seq, int flags) -+{ -+ const struct devlink_ops *ops = devlink->ops; -+ enum devlink_eswitch_encap_mode encap_mode; -+ u8 inline_mode; -+ void *hdr; -+ int err = 0; -+ u16 mode; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ err = devlink_nl_put_handle(msg, devlink); -+ if (err) -+ goto nla_put_failure; -+ -+ if (ops->eswitch_mode_get) { -+ err = ops->eswitch_mode_get(devlink, &mode); -+ if (err) -+ goto nla_put_failure; -+ err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); -+ if (err) -+ goto nla_put_failure; -+ } -+ -+ if (ops->eswitch_inline_mode_get) { -+ err = ops->eswitch_inline_mode_get(devlink, &inline_mode); -+ if (err) -+ goto nla_put_failure; -+ err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, -+ inline_mode); -+ if (err) -+ goto nla_put_failure; -+ } -+ -+ if (ops->eswitch_encap_mode_get) { -+ err = ops->eswitch_encap_mode_get(devlink, &encap_mode); -+ if (err) -+ goto nla_put_failure; -+ err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); -+ if (err) -+ goto nla_put_failure; -+ } -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return err; -+} -+ -+static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct sk_buff *msg; -+ int err; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, -+ info->snd_portid, info->snd_seq, 0); -+ -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode, -+ struct netlink_ext_ack *extack) -+{ -+ struct devlink_rate *devlink_rate; -+ -+ list_for_each_entry(devlink_rate, &devlink->rate_list, list) -+ if (devlink_rate_is_node(devlink_rate)) { -+ NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists."); -+ return -EBUSY; -+ } -+ return 0; -+} -+ -+static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ const struct devlink_ops *ops = devlink->ops; -+ enum devlink_eswitch_encap_mode encap_mode; -+ u8 inline_mode; -+ int err = 0; -+ u16 mode; -+ -+ if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { -+ if (!ops->eswitch_mode_set) -+ return -EOPNOTSUPP; -+ mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); -+ err = devlink_rate_nodes_check(devlink, mode, info->extack); -+ if (err) -+ return err; -+ err = ops->eswitch_mode_set(devlink, mode, info->extack); -+ if (err) -+ return err; -+ } -+ -+ if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { -+ if (!ops->eswitch_inline_mode_set) -+ return -EOPNOTSUPP; -+ inline_mode = nla_get_u8( -+ info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); -+ err = ops->eswitch_inline_mode_set(devlink, inline_mode, -+ info->extack); -+ if (err) -+ return err; -+ } -+ -+ if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { -+ if (!ops->eswitch_encap_mode_set) -+ return -EOPNOTSUPP; -+ encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); -+ err = ops->eswitch_encap_mode_set(devlink, encap_mode, -+ info->extack); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+int devlink_dpipe_match_put(struct sk_buff *skb, -+ struct devlink_dpipe_match *match) -+{ -+ struct devlink_dpipe_header *header = match->header; -+ struct devlink_dpipe_field *field = &header->fields[match->field_id]; -+ struct nlattr *match_attr; -+ -+ match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH); -+ if (!match_attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || -+ nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, match_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(skb, match_attr); -+ return -EMSGSIZE; -+} -+EXPORT_SYMBOL_GPL(devlink_dpipe_match_put); -+ -+static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table, -+ struct sk_buff *skb) -+{ -+ struct nlattr *matches_attr; -+ -+ matches_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_DPIPE_TABLE_MATCHES); -+ if (!matches_attr) -+ return -EMSGSIZE; -+ -+ if (table->table_ops->matches_dump(table->priv, skb)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, matches_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(skb, matches_attr); -+ return -EMSGSIZE; -+} -+ -+int devlink_dpipe_action_put(struct sk_buff *skb, -+ struct devlink_dpipe_action *action) -+{ -+ struct devlink_dpipe_header *header = action->header; -+ struct devlink_dpipe_field *field = &header->fields[action->field_id]; -+ struct nlattr *action_attr; -+ -+ action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION); -+ if (!action_attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || -+ nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, action_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(skb, action_attr); -+ return -EMSGSIZE; -+} -+EXPORT_SYMBOL_GPL(devlink_dpipe_action_put); -+ -+static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table, -+ struct sk_buff *skb) -+{ -+ struct nlattr *actions_attr; -+ -+ actions_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_DPIPE_TABLE_ACTIONS); -+ if (!actions_attr) -+ return -EMSGSIZE; -+ -+ if (table->table_ops->actions_dump(table->priv, skb)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, actions_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(skb, actions_attr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_dpipe_table_put(struct sk_buff *skb, -+ struct devlink_dpipe_table *table) -+{ -+ struct nlattr *table_attr; -+ u64 table_size; -+ -+ table_size = table->table_ops->size_get(table->priv); -+ table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE); -+ if (!table_attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) || -+ nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size, -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, -+ table->counters_enabled)) -+ goto nla_put_failure; -+ -+ if (table->resource_valid) { -+ if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID, -+ table->resource_id, DEVLINK_ATTR_PAD) || -+ nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS, -+ table->resource_units, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ } -+ if (devlink_dpipe_matches_put(table, skb)) -+ goto nla_put_failure; -+ -+ if (devlink_dpipe_actions_put(table, skb)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, table_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(skb, table_attr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb, -+ struct genl_info *info) -+{ -+ int err; -+ -+ if (*pskb) { -+ err = genlmsg_reply(*pskb, info); -+ if (err) -+ return err; -+ } -+ *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!*pskb) -+ return -ENOMEM; -+ return 0; -+} -+ -+static int devlink_dpipe_tables_fill(struct genl_info *info, -+ enum devlink_command cmd, int flags, -+ struct list_head *dpipe_tables, -+ const char *table_name) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_dpipe_table *table; -+ struct nlattr *tables_attr; -+ struct sk_buff *skb = NULL; -+ struct nlmsghdr *nlh; -+ bool incomplete; -+ void *hdr; -+ int i; -+ int err; -+ -+ table = list_first_entry(dpipe_tables, -+ struct devlink_dpipe_table, list); -+start_again: -+ err = devlink_dpipe_send_and_alloc_skb(&skb, info); -+ if (err) -+ return err; -+ -+ hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, -+ &devlink_nl_family, NLM_F_MULTI, cmd); -+ if (!hdr) { -+ nlmsg_free(skb); -+ return -EMSGSIZE; -+ } -+ -+ if (devlink_nl_put_handle(skb, devlink)) -+ goto nla_put_failure; -+ tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES); -+ if (!tables_attr) -+ goto nla_put_failure; -+ -+ i = 0; -+ incomplete = false; -+ list_for_each_entry_from(table, dpipe_tables, list) { -+ if (!table_name) { -+ err = devlink_dpipe_table_put(skb, table); -+ if (err) { -+ if (!i) -+ goto err_table_put; -+ incomplete = true; -+ break; -+ } -+ } else { -+ if (!strcmp(table->name, table_name)) { -+ err = devlink_dpipe_table_put(skb, table); -+ if (err) -+ break; -+ } -+ } -+ i++; -+ } -+ -+ nla_nest_end(skb, tables_attr); -+ genlmsg_end(skb, hdr); -+ if (incomplete) -+ goto start_again; -+ -+send_done: -+ nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, -+ NLMSG_DONE, 0, flags | NLM_F_MULTI); -+ if (!nlh) { -+ err = devlink_dpipe_send_and_alloc_skb(&skb, info); -+ if (err) -+ return err; -+ goto send_done; -+ } -+ -+ return genlmsg_reply(skb, info); -+ -+nla_put_failure: -+ err = -EMSGSIZE; -+err_table_put: -+ nlmsg_free(skb); -+ return err; -+} -+ -+static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ const char *table_name = NULL; -+ -+ if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]) -+ table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); -+ -+ return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0, -+ &devlink->dpipe_table_list, -+ table_name); -+} -+ -+static int devlink_dpipe_value_put(struct sk_buff *skb, -+ struct devlink_dpipe_value *value) -+{ -+ if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE, -+ value->value_size, value->value)) -+ return -EMSGSIZE; -+ if (value->mask) -+ if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK, -+ value->value_size, value->mask)) -+ return -EMSGSIZE; -+ if (value->mapping_valid) -+ if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING, -+ value->mapping_value)) -+ return -EMSGSIZE; -+ return 0; -+} -+ -+static int devlink_dpipe_action_value_put(struct sk_buff *skb, -+ struct devlink_dpipe_value *value) -+{ -+ if (!value->action) -+ return -EINVAL; -+ if (devlink_dpipe_action_put(skb, value->action)) -+ return -EMSGSIZE; -+ if (devlink_dpipe_value_put(skb, value)) -+ return -EMSGSIZE; -+ return 0; -+} -+ -+static int devlink_dpipe_action_values_put(struct sk_buff *skb, -+ struct devlink_dpipe_value *values, -+ unsigned int values_count) -+{ -+ struct nlattr *action_attr; -+ int i; -+ int err; -+ -+ for (i = 0; i < values_count; i++) { -+ action_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_DPIPE_ACTION_VALUE); -+ if (!action_attr) -+ return -EMSGSIZE; -+ err = devlink_dpipe_action_value_put(skb, &values[i]); -+ if (err) -+ goto err_action_value_put; -+ nla_nest_end(skb, action_attr); -+ } -+ return 0; -+ -+err_action_value_put: -+ nla_nest_cancel(skb, action_attr); -+ return err; -+} -+ -+static int devlink_dpipe_match_value_put(struct sk_buff *skb, -+ struct devlink_dpipe_value *value) -+{ -+ if (!value->match) -+ return -EINVAL; -+ if (devlink_dpipe_match_put(skb, value->match)) -+ return -EMSGSIZE; -+ if (devlink_dpipe_value_put(skb, value)) -+ return -EMSGSIZE; -+ return 0; -+} -+ -+static int devlink_dpipe_match_values_put(struct sk_buff *skb, -+ struct devlink_dpipe_value *values, -+ unsigned int values_count) -+{ -+ struct nlattr *match_attr; -+ int i; -+ int err; -+ -+ for (i = 0; i < values_count; i++) { -+ match_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_DPIPE_MATCH_VALUE); -+ if (!match_attr) -+ return -EMSGSIZE; -+ err = devlink_dpipe_match_value_put(skb, &values[i]); -+ if (err) -+ goto err_match_value_put; -+ nla_nest_end(skb, match_attr); -+ } -+ return 0; -+ -+err_match_value_put: -+ nla_nest_cancel(skb, match_attr); -+ return err; -+} -+ -+static int devlink_dpipe_entry_put(struct sk_buff *skb, -+ struct devlink_dpipe_entry *entry) -+{ -+ struct nlattr *entry_attr, *matches_attr, *actions_attr; -+ int err; -+ -+ entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY); -+ if (!entry_attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index, -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ if (entry->counter_valid) -+ if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, -+ entry->counter, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ matches_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES); -+ if (!matches_attr) -+ goto nla_put_failure; -+ -+ err = devlink_dpipe_match_values_put(skb, entry->match_values, -+ entry->match_values_count); -+ if (err) { -+ nla_nest_cancel(skb, matches_attr); -+ goto err_match_values_put; -+ } -+ nla_nest_end(skb, matches_attr); -+ -+ actions_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES); -+ if (!actions_attr) -+ goto nla_put_failure; -+ -+ err = devlink_dpipe_action_values_put(skb, entry->action_values, -+ entry->action_values_count); -+ if (err) { -+ nla_nest_cancel(skb, actions_attr); -+ goto err_action_values_put; -+ } -+ nla_nest_end(skb, actions_attr); -+ -+ nla_nest_end(skb, entry_attr); -+ return 0; -+ -+nla_put_failure: -+ err = -EMSGSIZE; -+err_match_values_put: -+err_action_values_put: -+ nla_nest_cancel(skb, entry_attr); -+ return err; -+} -+ -+static struct devlink_dpipe_table * -+devlink_dpipe_table_find(struct list_head *dpipe_tables, -+ const char *table_name, struct devlink *devlink) -+{ -+ struct devlink_dpipe_table *table; -+ list_for_each_entry_rcu(table, dpipe_tables, list, -+ lockdep_is_held(&devlink->lock)) { -+ if (!strcmp(table->name, table_name)) -+ return table; -+ } -+ return NULL; -+} -+ -+int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx) -+{ -+ struct devlink *devlink; -+ int err; -+ -+ err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb, -+ dump_ctx->info); -+ if (err) -+ return err; -+ -+ dump_ctx->hdr = genlmsg_put(dump_ctx->skb, -+ dump_ctx->info->snd_portid, -+ dump_ctx->info->snd_seq, -+ &devlink_nl_family, NLM_F_MULTI, -+ dump_ctx->cmd); -+ if (!dump_ctx->hdr) -+ goto nla_put_failure; -+ -+ devlink = dump_ctx->info->user_ptr[0]; -+ if (devlink_nl_put_handle(dump_ctx->skb, devlink)) -+ goto nla_put_failure; -+ dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb, -+ DEVLINK_ATTR_DPIPE_ENTRIES); -+ if (!dump_ctx->nest) -+ goto nla_put_failure; -+ return 0; -+ -+nla_put_failure: -+ nlmsg_free(dump_ctx->skb); -+ return -EMSGSIZE; -+} -+EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare); -+ -+int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx, -+ struct devlink_dpipe_entry *entry) -+{ -+ return devlink_dpipe_entry_put(dump_ctx->skb, entry); -+} -+EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append); -+ -+int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx) -+{ -+ nla_nest_end(dump_ctx->skb, dump_ctx->nest); -+ genlmsg_end(dump_ctx->skb, dump_ctx->hdr); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close); -+ -+void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry) -+ -+{ -+ unsigned int value_count, value_index; -+ struct devlink_dpipe_value *value; -+ -+ value = entry->action_values; -+ value_count = entry->action_values_count; -+ for (value_index = 0; value_index < value_count; value_index++) { -+ kfree(value[value_index].value); -+ kfree(value[value_index].mask); -+ } -+ -+ value = entry->match_values; -+ value_count = entry->match_values_count; -+ for (value_index = 0; value_index < value_count; value_index++) { -+ kfree(value[value_index].value); -+ kfree(value[value_index].mask); -+ } -+} -+EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear); -+ -+static int devlink_dpipe_entries_fill(struct genl_info *info, -+ enum devlink_command cmd, int flags, -+ struct devlink_dpipe_table *table) -+{ -+ struct devlink_dpipe_dump_ctx dump_ctx; -+ struct nlmsghdr *nlh; -+ int err; -+ -+ dump_ctx.skb = NULL; -+ dump_ctx.cmd = cmd; -+ dump_ctx.info = info; -+ -+ err = table->table_ops->entries_dump(table->priv, -+ table->counters_enabled, -+ &dump_ctx); -+ if (err) -+ return err; -+ -+send_done: -+ nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq, -+ NLMSG_DONE, 0, flags | NLM_F_MULTI); -+ if (!nlh) { -+ err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info); -+ if (err) -+ return err; -+ goto send_done; -+ } -+ return genlmsg_reply(dump_ctx.skb, info); -+} -+ -+static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_dpipe_table *table; -+ const char *table_name; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME)) -+ return -EINVAL; -+ -+ table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); -+ table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -+ table_name, devlink); -+ if (!table) -+ return -EINVAL; -+ -+ if (!table->table_ops->entries_dump) -+ return -EINVAL; -+ -+ return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET, -+ 0, table); -+} -+ -+static int devlink_dpipe_fields_put(struct sk_buff *skb, -+ const struct devlink_dpipe_header *header) -+{ -+ struct devlink_dpipe_field *field; -+ struct nlattr *field_attr; -+ int i; -+ -+ for (i = 0; i < header->fields_count; i++) { -+ field = &header->fields[i]; -+ field_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_DPIPE_FIELD); -+ if (!field_attr) -+ return -EMSGSIZE; -+ if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type)) -+ goto nla_put_failure; -+ nla_nest_end(skb, field_attr); -+ } -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(skb, field_attr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_dpipe_header_put(struct sk_buff *skb, -+ struct devlink_dpipe_header *header) -+{ -+ struct nlattr *fields_attr, *header_attr; -+ int err; -+ -+ header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER); -+ if (!header_attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) || -+ nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) || -+ nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global)) -+ goto nla_put_failure; -+ -+ fields_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_DPIPE_HEADER_FIELDS); -+ if (!fields_attr) -+ goto nla_put_failure; -+ -+ err = devlink_dpipe_fields_put(skb, header); -+ if (err) { -+ nla_nest_cancel(skb, fields_attr); -+ goto nla_put_failure; -+ } -+ nla_nest_end(skb, fields_attr); -+ nla_nest_end(skb, header_attr); -+ return 0; -+ -+nla_put_failure: -+ err = -EMSGSIZE; -+ nla_nest_cancel(skb, header_attr); -+ return err; -+} -+ -+static int devlink_dpipe_headers_fill(struct genl_info *info, -+ enum devlink_command cmd, int flags, -+ struct devlink_dpipe_headers * -+ dpipe_headers) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct nlattr *headers_attr; -+ struct sk_buff *skb = NULL; -+ struct nlmsghdr *nlh; -+ void *hdr; -+ int i, j; -+ int err; -+ -+ i = 0; -+start_again: -+ err = devlink_dpipe_send_and_alloc_skb(&skb, info); -+ if (err) -+ return err; -+ -+ hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, -+ &devlink_nl_family, NLM_F_MULTI, cmd); -+ if (!hdr) { -+ nlmsg_free(skb); -+ return -EMSGSIZE; -+ } -+ -+ if (devlink_nl_put_handle(skb, devlink)) -+ goto nla_put_failure; -+ headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS); -+ if (!headers_attr) -+ goto nla_put_failure; -+ -+ j = 0; -+ for (; i < dpipe_headers->headers_count; i++) { -+ err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]); -+ if (err) { -+ if (!j) -+ goto err_table_put; -+ break; -+ } -+ j++; -+ } -+ nla_nest_end(skb, headers_attr); -+ genlmsg_end(skb, hdr); -+ if (i != dpipe_headers->headers_count) -+ goto start_again; -+ -+send_done: -+ nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, -+ NLMSG_DONE, 0, flags | NLM_F_MULTI); -+ if (!nlh) { -+ err = devlink_dpipe_send_and_alloc_skb(&skb, info); -+ if (err) -+ return err; -+ goto send_done; -+ } -+ return genlmsg_reply(skb, info); -+ -+nla_put_failure: -+ err = -EMSGSIZE; -+err_table_put: -+ nlmsg_free(skb); -+ return err; -+} -+ -+static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ -+ if (!devlink->dpipe_headers) -+ return -EOPNOTSUPP; -+ return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET, -+ 0, devlink->dpipe_headers); -+} -+ -+static int devlink_dpipe_table_counters_set(struct devlink *devlink, -+ const char *table_name, -+ bool enable) -+{ -+ struct devlink_dpipe_table *table; -+ -+ table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -+ table_name, devlink); -+ if (!table) -+ return -EINVAL; -+ -+ if (table->counter_control_extern) -+ return -EOPNOTSUPP; -+ -+ if (!(table->counters_enabled ^ enable)) -+ return 0; -+ -+ table->counters_enabled = enable; -+ if (table->table_ops->counters_set_update) -+ table->table_ops->counters_set_update(table->priv, enable); -+ return 0; -+} -+ -+static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ const char *table_name; -+ bool counters_enable; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) || -+ GENL_REQ_ATTR_CHECK(info, -+ DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED)) -+ return -EINVAL; -+ -+ table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]); -+ counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]); -+ -+ return devlink_dpipe_table_counters_set(devlink, table_name, -+ counters_enable); -+} -+ -+static struct devlink_resource * -+devlink_resource_find(struct devlink *devlink, -+ struct devlink_resource *resource, u64 resource_id) -+{ -+ struct list_head *resource_list; -+ -+ if (resource) -+ resource_list = &resource->resource_list; -+ else -+ resource_list = &devlink->resource_list; -+ -+ list_for_each_entry(resource, resource_list, list) { -+ struct devlink_resource *child_resource; -+ -+ if (resource->id == resource_id) -+ return resource; -+ -+ child_resource = devlink_resource_find(devlink, resource, -+ resource_id); -+ if (child_resource) -+ return child_resource; -+ } -+ return NULL; -+} -+ -+static void -+devlink_resource_validate_children(struct devlink_resource *resource) -+{ -+ struct devlink_resource *child_resource; -+ bool size_valid = true; -+ u64 parts_size = 0; -+ -+ if (list_empty(&resource->resource_list)) -+ goto out; -+ -+ list_for_each_entry(child_resource, &resource->resource_list, list) -+ parts_size += child_resource->size_new; -+ -+ if (parts_size > resource->size_new) -+ size_valid = false; -+out: -+ resource->size_valid = size_valid; -+} -+ -+static int -+devlink_resource_validate_size(struct devlink_resource *resource, u64 size, -+ struct netlink_ext_ack *extack) -+{ -+ u64 reminder; -+ int err = 0; -+ -+ if (size > resource->size_params.size_max) { -+ NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum"); -+ err = -EINVAL; -+ } -+ -+ if (size < resource->size_params.size_min) { -+ NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum"); -+ err = -EINVAL; -+ } -+ -+ div64_u64_rem(size, resource->size_params.size_granularity, &reminder); -+ if (reminder) { -+ NL_SET_ERR_MSG_MOD(extack, "Wrong granularity"); -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+static int devlink_nl_cmd_resource_set(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_resource *resource; -+ u64 resource_id; -+ u64 size; -+ int err; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) || -+ GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE)) -+ return -EINVAL; -+ resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]); -+ -+ resource = devlink_resource_find(devlink, NULL, resource_id); -+ if (!resource) -+ return -EINVAL; -+ -+ size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]); -+ err = devlink_resource_validate_size(resource, size, info->extack); -+ if (err) -+ return err; -+ -+ resource->size_new = size; -+ devlink_resource_validate_children(resource); -+ if (resource->parent) -+ devlink_resource_validate_children(resource->parent); -+ return 0; -+} -+ -+static int -+devlink_resource_size_params_put(struct devlink_resource *resource, -+ struct sk_buff *skb) -+{ -+ struct devlink_resource_size_params *size_params; -+ -+ size_params = &resource->size_params; -+ if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN, -+ size_params->size_granularity, DEVLINK_ATTR_PAD) || -+ nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX, -+ size_params->size_max, DEVLINK_ATTR_PAD) || -+ nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN, -+ size_params->size_min, DEVLINK_ATTR_PAD) || -+ nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit)) -+ return -EMSGSIZE; -+ return 0; -+} -+ -+static int devlink_resource_occ_put(struct devlink_resource *resource, -+ struct sk_buff *skb) -+{ -+ if (!resource->occ_get) -+ return 0; -+ return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC, -+ resource->occ_get(resource->occ_get_priv), -+ DEVLINK_ATTR_PAD); -+} -+ -+static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb, -+ struct devlink_resource *resource) -+{ -+ struct devlink_resource *child_resource; -+ struct nlattr *child_resource_attr; -+ struct nlattr *resource_attr; -+ -+ resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE); -+ if (!resource_attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) || -+ nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size, -+ DEVLINK_ATTR_PAD) || -+ nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id, -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ if (resource->size != resource->size_new) -+ nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW, -+ resource->size_new, DEVLINK_ATTR_PAD); -+ if (devlink_resource_occ_put(resource, skb)) -+ goto nla_put_failure; -+ if (devlink_resource_size_params_put(resource, skb)) -+ goto nla_put_failure; -+ if (list_empty(&resource->resource_list)) -+ goto out; -+ -+ if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID, -+ resource->size_valid)) -+ goto nla_put_failure; -+ -+ child_resource_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_RESOURCE_LIST); -+ if (!child_resource_attr) -+ goto nla_put_failure; -+ -+ list_for_each_entry(child_resource, &resource->resource_list, list) { -+ if (devlink_resource_put(devlink, skb, child_resource)) -+ goto resource_put_failure; -+ } -+ -+ nla_nest_end(skb, child_resource_attr); -+out: -+ nla_nest_end(skb, resource_attr); -+ return 0; -+ -+resource_put_failure: -+ nla_nest_cancel(skb, child_resource_attr); -+nla_put_failure: -+ nla_nest_cancel(skb, resource_attr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_resource_fill(struct genl_info *info, -+ enum devlink_command cmd, int flags) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_resource *resource; -+ struct nlattr *resources_attr; -+ struct sk_buff *skb = NULL; -+ struct nlmsghdr *nlh; -+ bool incomplete; -+ void *hdr; -+ int i; -+ int err; -+ -+ resource = list_first_entry(&devlink->resource_list, -+ struct devlink_resource, list); -+start_again: -+ err = devlink_dpipe_send_and_alloc_skb(&skb, info); -+ if (err) -+ return err; -+ -+ hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, -+ &devlink_nl_family, NLM_F_MULTI, cmd); -+ if (!hdr) { -+ nlmsg_free(skb); -+ return -EMSGSIZE; -+ } -+ -+ if (devlink_nl_put_handle(skb, devlink)) -+ goto nla_put_failure; -+ -+ resources_attr = nla_nest_start_noflag(skb, -+ DEVLINK_ATTR_RESOURCE_LIST); -+ if (!resources_attr) -+ goto nla_put_failure; -+ -+ incomplete = false; -+ i = 0; -+ list_for_each_entry_from(resource, &devlink->resource_list, list) { -+ err = devlink_resource_put(devlink, skb, resource); -+ if (err) { -+ if (!i) -+ goto err_resource_put; -+ incomplete = true; -+ break; -+ } -+ i++; -+ } -+ nla_nest_end(skb, resources_attr); -+ genlmsg_end(skb, hdr); -+ if (incomplete) -+ goto start_again; -+send_done: -+ nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, -+ NLMSG_DONE, 0, flags | NLM_F_MULTI); -+ if (!nlh) { -+ err = devlink_dpipe_send_and_alloc_skb(&skb, info); -+ if (err) -+ return err; -+ goto send_done; -+ } -+ return genlmsg_reply(skb, info); -+ -+nla_put_failure: -+ err = -EMSGSIZE; -+err_resource_put: -+ nlmsg_free(skb); -+ return err; -+} -+ -+static int devlink_nl_cmd_resource_dump(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ -+ if (list_empty(&devlink->resource_list)) -+ return -EOPNOTSUPP; -+ -+ return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); -+} -+ -+static int -+devlink_resources_validate(struct devlink *devlink, -+ struct devlink_resource *resource, -+ struct genl_info *info) -+{ -+ struct list_head *resource_list; -+ int err = 0; -+ -+ if (resource) -+ resource_list = &resource->resource_list; -+ else -+ resource_list = &devlink->resource_list; -+ -+ list_for_each_entry(resource, resource_list, list) { -+ if (!resource->size_valid) -+ return -EINVAL; -+ err = devlink_resources_validate(devlink, resource, info); -+ if (err) -+ return err; -+ } -+ return err; -+} -+ -+static struct net *devlink_netns_get(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID]; -+ struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD]; -+ struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID]; -+ struct net *net; -+ -+ if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) { -+ NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ if (netns_pid_attr) { -+ net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr)); -+ } else if (netns_fd_attr) { -+ net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr)); -+ } else if (netns_id_attr) { -+ net = get_net_ns_by_id(sock_net(skb->sk), -+ nla_get_u32(netns_id_attr)); -+ if (!net) -+ net = ERR_PTR(-EINVAL); -+ } else { -+ WARN_ON(1); -+ net = ERR_PTR(-EINVAL); -+ } -+ if (IS_ERR(net)) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace"); -+ return ERR_PTR(-EINVAL); -+ } -+ if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { -+ put_net(net); -+ return ERR_PTR(-EPERM); -+ } -+ return net; -+} -+ -+static void devlink_param_notify(struct devlink *devlink, -+ unsigned int port_index, -+ struct devlink_param_item *param_item, -+ enum devlink_command cmd); -+ -+static void devlink_ns_change_notify(struct devlink *devlink, -+ struct net *dest_net, struct net *curr_net, -+ bool new) -+{ -+ struct devlink_param_item *param_item; -+ enum devlink_command cmd; -+ -+ /* Userspace needs to be notified about devlink objects -+ * removed from original and entering new network namespace. -+ * The rest of the devlink objects are re-created during -+ * reload process so the notifications are generated separatelly. -+ */ -+ -+ if (!dest_net || net_eq(dest_net, curr_net)) -+ return; -+ -+ if (new) -+ devlink_notify(devlink, DEVLINK_CMD_NEW); -+ -+ cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL; -+ list_for_each_entry(param_item, &devlink->param_list, list) -+ devlink_param_notify(devlink, 0, param_item, cmd); -+ -+ if (!new) -+ devlink_notify(devlink, DEVLINK_CMD_DEL); -+} -+ -+static bool devlink_reload_supported(const struct devlink_ops *ops) -+{ -+ return ops->reload_down && ops->reload_up; -+} -+ -+static void devlink_reload_failed_set(struct devlink *devlink, -+ bool reload_failed) -+{ -+ if (devlink->reload_failed == reload_failed) -+ return; -+ devlink->reload_failed = reload_failed; -+ devlink_notify(devlink, DEVLINK_CMD_NEW); -+} -+ -+bool devlink_is_reload_failed(const struct devlink *devlink) -+{ -+ return devlink->reload_failed; -+} -+EXPORT_SYMBOL_GPL(devlink_is_reload_failed); -+ -+static void -+__devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats, -+ enum devlink_reload_limit limit, u32 actions_performed) -+{ -+ unsigned long actions = actions_performed; -+ int stat_idx; -+ int action; -+ -+ for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) { -+ stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action; -+ reload_stats[stat_idx]++; -+ } -+ devlink_notify(devlink, DEVLINK_CMD_NEW); -+} -+ -+static void -+devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit, -+ u32 actions_performed) -+{ -+ __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit, -+ actions_performed); -+} -+ -+/** -+ * devlink_remote_reload_actions_performed - Update devlink on reload actions -+ * performed which are not a direct result of devlink reload call. -+ * -+ * This should be called by a driver after performing reload actions in case it was not -+ * a result of devlink reload call. For example fw_activate was performed as a result -+ * of devlink reload triggered fw_activate on another host. -+ * The motivation for this function is to keep data on reload actions performed on this -+ * function whether it was done due to direct devlink reload call or not. -+ * -+ * @devlink: devlink -+ * @limit: reload limit -+ * @actions_performed: bitmask of actions performed -+ */ -+void devlink_remote_reload_actions_performed(struct devlink *devlink, -+ enum devlink_reload_limit limit, -+ u32 actions_performed) -+{ -+ if (WARN_ON(!actions_performed || -+ actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || -+ actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) || -+ limit > DEVLINK_RELOAD_LIMIT_MAX)) -+ return; -+ -+ __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit, -+ actions_performed); -+} -+EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed); -+ -+static int devlink_reload(struct devlink *devlink, struct net *dest_net, -+ enum devlink_reload_action action, enum devlink_reload_limit limit, -+ u32 *actions_performed, struct netlink_ext_ack *extack) -+{ -+ u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; -+ struct net *curr_net; -+ int err; -+ -+ memcpy(remote_reload_stats, devlink->stats.remote_reload_stats, -+ sizeof(remote_reload_stats)); -+ -+ curr_net = devlink_net(devlink); -+ devlink_ns_change_notify(devlink, dest_net, curr_net, false); -+ err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack); -+ if (err) -+ return err; -+ -+ if (dest_net && !net_eq(dest_net, curr_net)) -+ write_pnet(&devlink->_net, dest_net); -+ -+ err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack); -+ devlink_reload_failed_set(devlink, !!err); -+ if (err) -+ return err; -+ -+ devlink_ns_change_notify(devlink, dest_net, curr_net, true); -+ WARN_ON(!(*actions_performed & BIT(action))); -+ /* Catch driver on updating the remote action within devlink reload */ -+ WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats, -+ sizeof(remote_reload_stats))); -+ devlink_reload_stats_update(devlink, limit, *actions_performed); -+ return 0; -+} -+ -+static int -+devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed, -+ enum devlink_command cmd, struct genl_info *info) -+{ -+ struct sk_buff *msg; -+ void *hdr; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd); -+ if (!hdr) -+ goto free_msg; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ -+ if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed, -+ actions_performed)) -+ goto nla_put_failure; -+ genlmsg_end(msg, hdr); -+ -+ return genlmsg_reply(msg, info); -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+free_msg: -+ nlmsg_free(msg); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ enum devlink_reload_action action; -+ enum devlink_reload_limit limit; -+ struct net *dest_net = NULL; -+ u32 actions_performed; -+ int err; -+ -+ if (!(devlink->features & DEVLINK_F_RELOAD)) -+ return -EOPNOTSUPP; -+ -+ err = devlink_resources_validate(devlink, NULL, info); -+ if (err) { -+ NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed"); -+ return err; -+ } -+ -+ if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION]) -+ action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]); -+ else -+ action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT; -+ -+ if (!devlink_reload_action_is_supported(devlink, action)) { -+ NL_SET_ERR_MSG_MOD(info->extack, -+ "Requested reload action is not supported by the driver"); -+ return -EOPNOTSUPP; -+ } -+ -+ limit = DEVLINK_RELOAD_LIMIT_UNSPEC; -+ if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) { -+ struct nla_bitfield32 limits; -+ u32 limits_selected; -+ -+ limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]); -+ limits_selected = limits.value & limits.selector; -+ if (!limits_selected) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected"); -+ return -EINVAL; -+ } -+ for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++) -+ if (limits_selected & BIT(limit)) -+ break; -+ /* UAPI enables multiselection, but currently it is not used */ -+ if (limits_selected != BIT(limit)) { -+ NL_SET_ERR_MSG_MOD(info->extack, -+ "Multiselection of limit is not supported"); -+ return -EOPNOTSUPP; -+ } -+ if (!devlink_reload_limit_is_supported(devlink, limit)) { -+ NL_SET_ERR_MSG_MOD(info->extack, -+ "Requested limit is not supported by the driver"); -+ return -EOPNOTSUPP; -+ } -+ if (devlink_reload_combination_is_invalid(action, limit)) { -+ NL_SET_ERR_MSG_MOD(info->extack, -+ "Requested limit is invalid for this action"); -+ return -EINVAL; -+ } -+ } -+ if (info->attrs[DEVLINK_ATTR_NETNS_PID] || -+ info->attrs[DEVLINK_ATTR_NETNS_FD] || -+ info->attrs[DEVLINK_ATTR_NETNS_ID]) { -+ dest_net = devlink_netns_get(skb, info); -+ if (IS_ERR(dest_net)) -+ return PTR_ERR(dest_net); -+ } -+ -+ err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); -+ -+ if (dest_net) -+ put_net(dest_net); -+ -+ if (err) -+ return err; -+ /* For backward compatibility generate reply only if attributes used by user */ -+ if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) -+ return 0; -+ -+ return devlink_nl_reload_actions_performed_snd(devlink, actions_performed, -+ DEVLINK_CMD_RELOAD, info); -+} -+ -+static int devlink_nl_flash_update_fill(struct sk_buff *msg, -+ struct devlink *devlink, -+ enum devlink_command cmd, -+ struct devlink_flash_notify *params) -+{ -+ void *hdr; -+ -+ hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ -+ if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS) -+ goto out; -+ -+ if (params->status_msg && -+ nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, -+ params->status_msg)) -+ goto nla_put_failure; -+ if (params->component && -+ nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, -+ params->component)) -+ goto nla_put_failure; -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, -+ params->done, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, -+ params->total, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, -+ params->timeout, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+out: -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static void __devlink_flash_update_notify(struct devlink *devlink, -+ enum devlink_command cmd, -+ struct devlink_flash_notify *params) -+{ -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE && -+ cmd != DEVLINK_CMD_FLASH_UPDATE_END && -+ cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS); -+ -+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -+ return; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_flash_update_fill(msg, devlink, cmd, params); -+ if (err) -+ goto out_free_msg; -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -+ msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+ return; -+ -+out_free_msg: -+ nlmsg_free(msg); -+} -+ -+static void devlink_flash_update_begin_notify(struct devlink *devlink) -+{ -+ struct devlink_flash_notify params = {}; -+ -+ __devlink_flash_update_notify(devlink, -+ DEVLINK_CMD_FLASH_UPDATE, -+ ¶ms); -+} -+ -+static void devlink_flash_update_end_notify(struct devlink *devlink) -+{ -+ struct devlink_flash_notify params = {}; -+ -+ __devlink_flash_update_notify(devlink, -+ DEVLINK_CMD_FLASH_UPDATE_END, -+ ¶ms); -+} -+ -+void devlink_flash_update_status_notify(struct devlink *devlink, -+ const char *status_msg, -+ const char *component, -+ unsigned long done, -+ unsigned long total) -+{ -+ struct devlink_flash_notify params = { -+ .status_msg = status_msg, -+ .component = component, -+ .done = done, -+ .total = total, -+ }; -+ -+ __devlink_flash_update_notify(devlink, -+ DEVLINK_CMD_FLASH_UPDATE_STATUS, -+ ¶ms); -+} -+EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); -+ -+void devlink_flash_update_timeout_notify(struct devlink *devlink, -+ const char *status_msg, -+ const char *component, -+ unsigned long timeout) -+{ -+ struct devlink_flash_notify params = { -+ .status_msg = status_msg, -+ .component = component, -+ .timeout = timeout, -+ }; -+ -+ __devlink_flash_update_notify(devlink, -+ DEVLINK_CMD_FLASH_UPDATE_STATUS, -+ ¶ms); -+} -+EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); -+ -+struct devlink_info_req { -+ struct sk_buff *msg; -+ void (*version_cb)(const char *version_name, -+ enum devlink_info_version_type version_type, -+ void *version_cb_priv); -+ void *version_cb_priv; -+}; -+ -+struct devlink_flash_component_lookup_ctx { -+ const char *lookup_name; -+ bool lookup_name_found; -+}; -+ -+static void -+devlink_flash_component_lookup_cb(const char *version_name, -+ enum devlink_info_version_type version_type, -+ void *version_cb_priv) -+{ -+ struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv; -+ -+ if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT || -+ lookup_ctx->lookup_name_found) -+ return; -+ -+ lookup_ctx->lookup_name_found = -+ !strcmp(lookup_ctx->lookup_name, version_name); -+} -+ -+static int devlink_flash_component_get(struct devlink *devlink, -+ struct nlattr *nla_component, -+ const char **p_component, -+ struct netlink_ext_ack *extack) -+{ -+ struct devlink_flash_component_lookup_ctx lookup_ctx = {}; -+ struct devlink_info_req req = {}; -+ const char *component; -+ int ret; -+ -+ if (!nla_component) -+ return 0; -+ -+ component = nla_data(nla_component); -+ -+ if (!devlink->ops->info_get) { -+ NL_SET_ERR_MSG_ATTR(extack, nla_component, -+ "component update is not supported by this device"); -+ return -EOPNOTSUPP; -+ } -+ -+ lookup_ctx.lookup_name = component; -+ req.version_cb = devlink_flash_component_lookup_cb; -+ req.version_cb_priv = &lookup_ctx; -+ -+ ret = devlink->ops->info_get(devlink, &req, NULL); -+ if (ret) -+ return ret; -+ -+ if (!lookup_ctx.lookup_name_found) { -+ NL_SET_ERR_MSG_ATTR(extack, nla_component, -+ "selected component is not supported by this device"); -+ return -EINVAL; -+ } -+ *p_component = component; -+ return 0; -+} -+ -+static int devlink_nl_cmd_flash_update(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct nlattr *nla_overwrite_mask, *nla_file_name; -+ struct devlink_flash_update_params params = {}; -+ struct devlink *devlink = info->user_ptr[0]; -+ const char *file_name; -+ u32 supported_params; -+ int ret; -+ -+ if (!devlink->ops->flash_update) -+ return -EOPNOTSUPP; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME)) -+ return -EINVAL; -+ -+ ret = devlink_flash_component_get(devlink, -+ info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT], -+ ¶ms.component, info->extack); -+ if (ret) -+ return ret; -+ -+ supported_params = devlink->ops->supported_flash_update_params; -+ -+ nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; -+ if (nla_overwrite_mask) { -+ struct nla_bitfield32 sections; -+ -+ if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { -+ NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, -+ "overwrite settings are not supported by this device"); -+ return -EOPNOTSUPP; -+ } -+ sections = nla_get_bitfield32(nla_overwrite_mask); -+ params.overwrite_mask = sections.value & sections.selector; -+ } -+ -+ nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]; -+ file_name = nla_data(nla_file_name); -+ ret = request_firmware(¶ms.fw, file_name, devlink->dev); -+ if (ret) { -+ NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file"); -+ return ret; -+ } -+ -+ devlink_flash_update_begin_notify(devlink); -+ ret = devlink->ops->flash_update(devlink, ¶ms, info->extack); -+ devlink_flash_update_end_notify(devlink); -+ -+ release_firmware(params.fw); -+ -+ return ret; -+} -+ -+static int -+devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink, -+ u32 portid, u32 seq, int flags, -+ struct netlink_ext_ack *extack) -+{ -+ struct nlattr *selftests; -+ void *hdr; -+ int err; -+ int i; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, -+ DEVLINK_CMD_SELFTESTS_GET); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ err = -EMSGSIZE; -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto err_cancel_msg; -+ -+ selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); -+ if (!selftests) -+ goto err_cancel_msg; -+ -+ for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; -+ i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { -+ if (devlink->ops->selftest_check(devlink, i, extack)) { -+ err = nla_put_flag(msg, i); -+ if (err) -+ goto err_cancel_msg; -+ } -+ } -+ -+ nla_nest_end(msg, selftests); -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+err_cancel_msg: -+ genlmsg_cancel(msg, hdr); -+ return err; -+} -+ -+static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct sk_buff *msg; -+ int err; -+ -+ if (!devlink->ops->selftest_check) -+ return -EOPNOTSUPP; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid, -+ info->snd_seq, 0, info->extack); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int devlink_nl_cmd_selftests_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err = 0; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ if (idx < start || !devlink->ops->selftest_check) -+ goto inc; -+ -+ devl_lock(devlink); -+ err = devlink_nl_selftests_fill(msg, devlink, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, NLM_F_MULTI, -+ cb->extack); -+ devl_unlock(devlink); -+ if (err) { -+ devlink_put(devlink); -+ break; -+ } -+inc: -+ idx++; -+ devlink_put(devlink); -+ } -+ -+ if (err != -EMSGSIZE) -+ return err; -+ -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, -+ enum devlink_selftest_status test_status) -+{ -+ struct nlattr *result_attr; -+ -+ result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT); -+ if (!result_attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) || -+ nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS, -+ test_status)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, result_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(skb, result_attr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_cmd_selftests_run(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1]; -+ struct devlink *devlink = info->user_ptr[0]; -+ struct nlattr *attrs, *selftests; -+ struct sk_buff *msg; -+ void *hdr; -+ int err; -+ int i; -+ -+ if (!devlink->ops->selftest_run || !devlink->ops->selftest_check) -+ return -EOPNOTSUPP; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS)) -+ return -EINVAL; -+ -+ attrs = info->attrs[DEVLINK_ATTR_SELFTESTS]; -+ -+ err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs, -+ devlink_selftest_nl_policy, info->extack); -+ if (err < 0) -+ return err; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = -EMSGSIZE; -+ hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, -+ &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN); -+ if (!hdr) -+ goto free_msg; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto genlmsg_cancel; -+ -+ selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); -+ if (!selftests) -+ goto genlmsg_cancel; -+ -+ for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; -+ i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { -+ enum devlink_selftest_status test_status; -+ -+ if (nla_get_flag(tb[i])) { -+ if (!devlink->ops->selftest_check(devlink, i, -+ info->extack)) { -+ if (devlink_selftest_result_put(msg, i, -+ DEVLINK_SELFTEST_STATUS_SKIP)) -+ goto selftests_nest_cancel; -+ continue; -+ } -+ -+ test_status = devlink->ops->selftest_run(devlink, i, -+ info->extack); -+ if (devlink_selftest_result_put(msg, i, test_status)) -+ goto selftests_nest_cancel; -+ } -+ } -+ -+ nla_nest_end(msg, selftests); -+ genlmsg_end(msg, hdr); -+ return genlmsg_reply(msg, info); -+ -+selftests_nest_cancel: -+ nla_nest_cancel(msg, selftests); -+genlmsg_cancel: -+ genlmsg_cancel(msg, hdr); -+free_msg: -+ nlmsg_free(msg); -+ return err; -+} -+ -+static const struct devlink_param devlink_param_generic[] = { -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET, -+ .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME, -+ .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS, -+ .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME, -+ .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, -+ .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME, -+ .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT, -+ .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME, -+ .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, -+ .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME, -+ .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX, -+ .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME, -+ .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN, -+ .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME, -+ .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY, -+ .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME, -+ .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE, -+ .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME, -+ .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, -+ .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME, -+ .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET, -+ .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME, -+ .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH, -+ .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME, -+ .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA, -+ .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME, -+ .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET, -+ .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME, -+ .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP, -+ .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME, -+ .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE, -+ .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME, -+ .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE, -+ }, -+ { -+ .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE, -+ .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME, -+ .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE, -+ }, -+}; -+ -+static int devlink_param_generic_verify(const struct devlink_param *param) -+{ -+ /* verify it match generic parameter by id and name */ -+ if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX) -+ return -EINVAL; -+ if (strcmp(param->name, devlink_param_generic[param->id].name)) -+ return -ENOENT; -+ -+ WARN_ON(param->type != devlink_param_generic[param->id].type); -+ -+ return 0; -+} -+ -+static int devlink_param_driver_verify(const struct devlink_param *param) -+{ -+ int i; -+ -+ if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX) -+ return -EINVAL; -+ /* verify no such name in generic params */ -+ for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++) -+ if (!strcmp(param->name, devlink_param_generic[i].name)) -+ return -EEXIST; -+ -+ return 0; -+} -+ -+static struct devlink_param_item * -+devlink_param_find_by_name(struct list_head *param_list, -+ const char *param_name) -+{ -+ struct devlink_param_item *param_item; -+ -+ list_for_each_entry(param_item, param_list, list) -+ if (!strcmp(param_item->param->name, param_name)) -+ return param_item; -+ return NULL; -+} -+ -+static struct devlink_param_item * -+devlink_param_find_by_id(struct list_head *param_list, u32 param_id) -+{ -+ struct devlink_param_item *param_item; -+ -+ list_for_each_entry(param_item, param_list, list) -+ if (param_item->param->id == param_id) -+ return param_item; -+ return NULL; -+} -+ -+static bool -+devlink_param_cmode_is_supported(const struct devlink_param *param, -+ enum devlink_param_cmode cmode) -+{ -+ return test_bit(cmode, ¶m->supported_cmodes); -+} -+ -+static int devlink_param_get(struct devlink *devlink, -+ const struct devlink_param *param, -+ struct devlink_param_gset_ctx *ctx) -+{ -+ if (!param->get || devlink->reload_failed) -+ return -EOPNOTSUPP; -+ return param->get(devlink, param->id, ctx); -+} -+ -+static int devlink_param_set(struct devlink *devlink, -+ const struct devlink_param *param, -+ struct devlink_param_gset_ctx *ctx) -+{ -+ if (!param->set || devlink->reload_failed) -+ return -EOPNOTSUPP; -+ return param->set(devlink, param->id, ctx); -+} -+ -+static int -+devlink_param_type_to_nla_type(enum devlink_param_type param_type) -+{ -+ switch (param_type) { -+ case DEVLINK_PARAM_TYPE_U8: -+ return NLA_U8; -+ case DEVLINK_PARAM_TYPE_U16: -+ return NLA_U16; -+ case DEVLINK_PARAM_TYPE_U32: -+ return NLA_U32; -+ case DEVLINK_PARAM_TYPE_STRING: -+ return NLA_STRING; -+ case DEVLINK_PARAM_TYPE_BOOL: -+ return NLA_FLAG; -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int -+devlink_nl_param_value_fill_one(struct sk_buff *msg, -+ enum devlink_param_type type, -+ enum devlink_param_cmode cmode, -+ union devlink_param_value val) -+{ -+ struct nlattr *param_value_attr; -+ -+ param_value_attr = nla_nest_start_noflag(msg, -+ DEVLINK_ATTR_PARAM_VALUE); -+ if (!param_value_attr) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode)) -+ goto value_nest_cancel; -+ -+ switch (type) { -+ case DEVLINK_PARAM_TYPE_U8: -+ if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8)) -+ goto value_nest_cancel; -+ break; -+ case DEVLINK_PARAM_TYPE_U16: -+ if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16)) -+ goto value_nest_cancel; -+ break; -+ case DEVLINK_PARAM_TYPE_U32: -+ if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32)) -+ goto value_nest_cancel; -+ break; -+ case DEVLINK_PARAM_TYPE_STRING: -+ if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, -+ val.vstr)) -+ goto value_nest_cancel; -+ break; -+ case DEVLINK_PARAM_TYPE_BOOL: -+ if (val.vbool && -+ nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA)) -+ goto value_nest_cancel; -+ break; -+ } -+ -+ nla_nest_end(msg, param_value_attr); -+ return 0; -+ -+value_nest_cancel: -+ nla_nest_cancel(msg, param_value_attr); -+nla_put_failure: -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink, -+ unsigned int port_index, -+ struct devlink_param_item *param_item, -+ enum devlink_command cmd, -+ u32 portid, u32 seq, int flags) -+{ -+ union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1]; -+ bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {}; -+ const struct devlink_param *param = param_item->param; -+ struct devlink_param_gset_ctx ctx; -+ struct nlattr *param_values_list; -+ struct nlattr *param_attr; -+ int nla_type; -+ void *hdr; -+ int err; -+ int i; -+ -+ /* Get value from driver part to driverinit configuration mode */ -+ for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { -+ if (!devlink_param_cmode_is_supported(param, i)) -+ continue; -+ if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) { -+ if (!param_item->driverinit_value_valid) -+ return -EOPNOTSUPP; -+ param_value[i] = param_item->driverinit_value; -+ } else { -+ ctx.cmode = i; -+ err = devlink_param_get(devlink, param, &ctx); -+ if (err) -+ return err; -+ param_value[i] = ctx.val; -+ } -+ param_value_set[i] = true; -+ } -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto genlmsg_cancel; -+ -+ if (cmd == DEVLINK_CMD_PORT_PARAM_GET || -+ cmd == DEVLINK_CMD_PORT_PARAM_NEW || -+ cmd == DEVLINK_CMD_PORT_PARAM_DEL) -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index)) -+ goto genlmsg_cancel; -+ -+ param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM); -+ if (!param_attr) -+ goto genlmsg_cancel; -+ if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name)) -+ goto param_nest_cancel; -+ if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC)) -+ goto param_nest_cancel; -+ -+ nla_type = devlink_param_type_to_nla_type(param->type); -+ if (nla_type < 0) -+ goto param_nest_cancel; -+ if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type)) -+ goto param_nest_cancel; -+ -+ param_values_list = nla_nest_start_noflag(msg, -+ DEVLINK_ATTR_PARAM_VALUES_LIST); -+ if (!param_values_list) -+ goto param_nest_cancel; -+ -+ for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) { -+ if (!param_value_set[i]) -+ continue; -+ err = devlink_nl_param_value_fill_one(msg, param->type, -+ i, param_value[i]); -+ if (err) -+ goto values_list_nest_cancel; -+ } -+ -+ nla_nest_end(msg, param_values_list); -+ nla_nest_end(msg, param_attr); -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+values_list_nest_cancel: -+ nla_nest_end(msg, param_values_list); -+param_nest_cancel: -+ nla_nest_cancel(msg, param_attr); -+genlmsg_cancel: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static void devlink_param_notify(struct devlink *devlink, -+ unsigned int port_index, -+ struct devlink_param_item *param_item, -+ enum devlink_command cmd) -+{ -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL && -+ cmd != DEVLINK_CMD_PORT_PARAM_NEW && -+ cmd != DEVLINK_CMD_PORT_PARAM_DEL); -+ ASSERT_DEVLINK_REGISTERED(devlink); -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd, -+ 0, 0, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -+ msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink_param_item *param_item; -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err = 0; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ devl_lock(devlink); -+ list_for_each_entry(param_item, &devlink->param_list, list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_param_fill(msg, devlink, 0, param_item, -+ DEVLINK_CMD_PARAM_GET, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI); -+ if (err == -EOPNOTSUPP) { -+ err = 0; -+ } else if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ } -+out: -+ if (err != -EMSGSIZE) -+ return err; -+ -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int -+devlink_param_type_get_from_info(struct genl_info *info, -+ enum devlink_param_type *param_type) -+{ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE)) -+ return -EINVAL; -+ -+ switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) { -+ case NLA_U8: -+ *param_type = DEVLINK_PARAM_TYPE_U8; -+ break; -+ case NLA_U16: -+ *param_type = DEVLINK_PARAM_TYPE_U16; -+ break; -+ case NLA_U32: -+ *param_type = DEVLINK_PARAM_TYPE_U32; -+ break; -+ case NLA_STRING: -+ *param_type = DEVLINK_PARAM_TYPE_STRING; -+ break; -+ case NLA_FLAG: -+ *param_type = DEVLINK_PARAM_TYPE_BOOL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+devlink_param_value_get_from_info(const struct devlink_param *param, -+ struct genl_info *info, -+ union devlink_param_value *value) -+{ -+ struct nlattr *param_data; -+ int len; -+ -+ param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; -+ -+ if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data) -+ return -EINVAL; -+ -+ switch (param->type) { -+ case DEVLINK_PARAM_TYPE_U8: -+ if (nla_len(param_data) != sizeof(u8)) -+ return -EINVAL; -+ value->vu8 = nla_get_u8(param_data); -+ break; -+ case DEVLINK_PARAM_TYPE_U16: -+ if (nla_len(param_data) != sizeof(u16)) -+ return -EINVAL; -+ value->vu16 = nla_get_u16(param_data); -+ break; -+ case DEVLINK_PARAM_TYPE_U32: -+ if (nla_len(param_data) != sizeof(u32)) -+ return -EINVAL; -+ value->vu32 = nla_get_u32(param_data); -+ break; -+ case DEVLINK_PARAM_TYPE_STRING: -+ len = strnlen(nla_data(param_data), nla_len(param_data)); -+ if (len == nla_len(param_data) || -+ len >= __DEVLINK_PARAM_MAX_STRING_VALUE) -+ return -EINVAL; -+ strcpy(value->vstr, nla_data(param_data)); -+ break; -+ case DEVLINK_PARAM_TYPE_BOOL: -+ if (param_data && nla_len(param_data)) -+ return -EINVAL; -+ value->vbool = nla_get_flag(param_data); -+ break; -+ } -+ return 0; -+} -+ -+static struct devlink_param_item * -+devlink_param_get_from_info(struct list_head *param_list, -+ struct genl_info *info) -+{ -+ char *param_name; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME)) -+ return NULL; -+ -+ param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]); -+ return devlink_param_find_by_name(param_list, param_name); -+} -+ -+static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_param_item *param_item; -+ struct sk_buff *msg; -+ int err; -+ -+ param_item = devlink_param_get_from_info(&devlink->param_list, info); -+ if (!param_item) -+ return -EINVAL; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_param_fill(msg, devlink, 0, param_item, -+ DEVLINK_CMD_PARAM_GET, -+ info->snd_portid, info->snd_seq, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink, -+ unsigned int port_index, -+ struct list_head *param_list, -+ struct genl_info *info, -+ enum devlink_command cmd) -+{ -+ enum devlink_param_type param_type; -+ struct devlink_param_gset_ctx ctx; -+ enum devlink_param_cmode cmode; -+ struct devlink_param_item *param_item; -+ const struct devlink_param *param; -+ union devlink_param_value value; -+ int err = 0; -+ -+ param_item = devlink_param_get_from_info(param_list, info); -+ if (!param_item) -+ return -EINVAL; -+ param = param_item->param; -+ err = devlink_param_type_get_from_info(info, ¶m_type); -+ if (err) -+ return err; -+ if (param_type != param->type) -+ return -EINVAL; -+ err = devlink_param_value_get_from_info(param, info, &value); -+ if (err) -+ return err; -+ if (param->validate) { -+ err = param->validate(devlink, param->id, value, info->extack); -+ if (err) -+ return err; -+ } -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE)) -+ return -EINVAL; -+ cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]); -+ if (!devlink_param_cmode_is_supported(param, cmode)) -+ return -EOPNOTSUPP; -+ -+ if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { -+ if (param->type == DEVLINK_PARAM_TYPE_STRING) -+ strcpy(param_item->driverinit_value.vstr, value.vstr); -+ else -+ param_item->driverinit_value = value; -+ param_item->driverinit_value_valid = true; -+ } else { -+ if (!param->set) -+ return -EOPNOTSUPP; -+ ctx.val = value; -+ ctx.cmode = cmode; -+ err = devlink_param_set(devlink, param, &ctx); -+ if (err) -+ return err; -+ } -+ -+ devlink_param_notify(devlink, port_index, param_item, cmd); -+ return 0; -+} -+ -+static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ -+ return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list, -+ info, DEVLINK_CMD_PARAM_NEW); -+} -+ -+static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ NL_SET_ERR_MSG_MOD(cb->extack, "Port params are not supported"); -+ return msg->len; -+} -+ -+static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported"); -+ return -EINVAL; -+} -+ -+static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported"); -+ return -EINVAL; -+} -+ -+static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg, -+ struct devlink *devlink, -+ struct devlink_snapshot *snapshot) -+{ -+ struct nlattr *snap_attr; -+ int err; -+ -+ snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT); -+ if (!snap_attr) -+ return -EINVAL; -+ -+ err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id); -+ if (err) -+ goto nla_put_failure; -+ -+ nla_nest_end(msg, snap_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, snap_attr); -+ return err; -+} -+ -+static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg, -+ struct devlink *devlink, -+ struct devlink_region *region) -+{ -+ struct devlink_snapshot *snapshot; -+ struct nlattr *snapshots_attr; -+ int err; -+ -+ snapshots_attr = nla_nest_start_noflag(msg, -+ DEVLINK_ATTR_REGION_SNAPSHOTS); -+ if (!snapshots_attr) -+ return -EINVAL; -+ -+ list_for_each_entry(snapshot, ®ion->snapshot_list, list) { -+ err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot); -+ if (err) -+ goto nla_put_failure; -+ } -+ -+ nla_nest_end(msg, snapshots_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, snapshots_attr); -+ return err; -+} -+ -+static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink, -+ enum devlink_command cmd, u32 portid, -+ u32 seq, int flags, -+ struct devlink_region *region) -+{ -+ void *hdr; -+ int err; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ err = devlink_nl_put_handle(msg, devlink); -+ if (err) -+ goto nla_put_failure; -+ -+ if (region->port) { -+ err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, -+ region->port->index); -+ if (err) -+ goto nla_put_failure; -+ } -+ -+ err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name); -+ if (err) -+ goto nla_put_failure; -+ -+ err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, -+ region->size, -+ DEVLINK_ATTR_PAD); -+ if (err) -+ goto nla_put_failure; -+ -+ err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS, -+ region->max_snapshots); -+ if (err) -+ goto nla_put_failure; -+ -+ err = devlink_nl_region_snapshots_id_put(msg, devlink, region); -+ if (err) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return err; -+} -+ -+static struct sk_buff * -+devlink_nl_region_notify_build(struct devlink_region *region, -+ struct devlink_snapshot *snapshot, -+ enum devlink_command cmd, u32 portid, u32 seq) -+{ -+ struct devlink *devlink = region->devlink; -+ struct sk_buff *msg; -+ void *hdr; -+ int err; -+ -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return ERR_PTR(-ENOMEM); -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd); -+ if (!hdr) { -+ err = -EMSGSIZE; -+ goto out_free_msg; -+ } -+ -+ err = devlink_nl_put_handle(msg, devlink); -+ if (err) -+ goto out_cancel_msg; -+ -+ if (region->port) { -+ err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, -+ region->port->index); -+ if (err) -+ goto out_cancel_msg; -+ } -+ -+ err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, -+ region->ops->name); -+ if (err) -+ goto out_cancel_msg; -+ -+ if (snapshot) { -+ err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, -+ snapshot->id); -+ if (err) -+ goto out_cancel_msg; -+ } else { -+ err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, -+ region->size, DEVLINK_ATTR_PAD); -+ if (err) -+ goto out_cancel_msg; -+ } -+ genlmsg_end(msg, hdr); -+ -+ return msg; -+ -+out_cancel_msg: -+ genlmsg_cancel(msg, hdr); -+out_free_msg: -+ nlmsg_free(msg); -+ return ERR_PTR(err); -+} -+ -+static void devlink_nl_region_notify(struct devlink_region *region, -+ struct devlink_snapshot *snapshot, -+ enum devlink_command cmd) -+{ -+ struct devlink *devlink = region->devlink; -+ struct sk_buff *msg; -+ -+ WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL); -+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -+ return; -+ -+ msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); -+ if (IS_ERR(msg)) -+ return; -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, -+ 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+/** -+ * __devlink_snapshot_id_increment - Increment number of snapshots using an id -+ * @devlink: devlink instance -+ * @id: the snapshot id -+ * -+ * Track when a new snapshot begins using an id. Load the count for the -+ * given id from the snapshot xarray, increment it, and store it back. -+ * -+ * Called when a new snapshot is created with the given id. -+ * -+ * The id *must* have been previously allocated by -+ * devlink_region_snapshot_id_get(). -+ * -+ * Returns 0 on success, or an error on failure. -+ */ -+static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) -+{ -+ unsigned long count; -+ void *p; -+ int err; -+ -+ xa_lock(&devlink->snapshot_ids); -+ p = xa_load(&devlink->snapshot_ids, id); -+ if (WARN_ON(!p)) { -+ err = -EINVAL; -+ goto unlock; -+ } -+ -+ if (WARN_ON(!xa_is_value(p))) { -+ err = -EINVAL; -+ goto unlock; -+ } -+ -+ count = xa_to_value(p); -+ count++; -+ -+ err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), -+ GFP_ATOMIC)); -+unlock: -+ xa_unlock(&devlink->snapshot_ids); -+ return err; -+} -+ -+/** -+ * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id -+ * @devlink: devlink instance -+ * @id: the snapshot id -+ * -+ * Track when a snapshot is deleted and stops using an id. Load the count -+ * for the given id from the snapshot xarray, decrement it, and store it -+ * back. -+ * -+ * If the count reaches zero, erase this id from the xarray, freeing it -+ * up for future re-use by devlink_region_snapshot_id_get(). -+ * -+ * Called when a snapshot using the given id is deleted, and when the -+ * initial allocator of the id is finished using it. -+ */ -+static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) -+{ -+ unsigned long count; -+ void *p; -+ -+ xa_lock(&devlink->snapshot_ids); -+ p = xa_load(&devlink->snapshot_ids, id); -+ if (WARN_ON(!p)) -+ goto unlock; -+ -+ if (WARN_ON(!xa_is_value(p))) -+ goto unlock; -+ -+ count = xa_to_value(p); -+ -+ if (count > 1) { -+ count--; -+ __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), -+ GFP_ATOMIC); -+ } else { -+ /* If this was the last user, we can erase this id */ -+ __xa_erase(&devlink->snapshot_ids, id); -+ } -+unlock: -+ xa_unlock(&devlink->snapshot_ids); -+} -+ -+/** -+ * __devlink_snapshot_id_insert - Insert a specific snapshot ID -+ * @devlink: devlink instance -+ * @id: the snapshot id -+ * -+ * Mark the given snapshot id as used by inserting a zero value into the -+ * snapshot xarray. -+ * -+ * This must be called while holding the devlink instance lock. Unlike -+ * devlink_snapshot_id_get, the initial reference count is zero, not one. -+ * It is expected that the id will immediately be used before -+ * releasing the devlink instance lock. -+ * -+ * Returns zero on success, or an error code if the snapshot id could not -+ * be inserted. -+ */ -+static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) -+{ -+ int err; -+ -+ xa_lock(&devlink->snapshot_ids); -+ if (xa_load(&devlink->snapshot_ids, id)) { -+ xa_unlock(&devlink->snapshot_ids); -+ return -EEXIST; -+ } -+ err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), -+ GFP_ATOMIC)); -+ xa_unlock(&devlink->snapshot_ids); -+ return err; -+} -+ -+/** -+ * __devlink_region_snapshot_id_get - get snapshot ID -+ * @devlink: devlink instance -+ * @id: storage to return snapshot id -+ * -+ * Allocates a new snapshot id. Returns zero on success, or a negative -+ * error on failure. Must be called while holding the devlink instance -+ * lock. -+ * -+ * Snapshot IDs are tracked using an xarray which stores the number of -+ * users of the snapshot id. -+ * -+ * Note that the caller of this function counts as a 'user', in order to -+ * avoid race conditions. The caller must release its hold on the -+ * snapshot by using devlink_region_snapshot_id_put. -+ */ -+static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) -+{ -+ return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), -+ xa_limit_32b, GFP_KERNEL); -+} -+ -+/** -+ * __devlink_region_snapshot_create - create a new snapshot -+ * This will add a new snapshot of a region. The snapshot -+ * will be stored on the region struct and can be accessed -+ * from devlink. This is useful for future analyses of snapshots. -+ * Multiple snapshots can be created on a region. -+ * The @snapshot_id should be obtained using the getter function. -+ * -+ * Must be called only while holding the region snapshot lock. -+ * -+ * @region: devlink region of the snapshot -+ * @data: snapshot data -+ * @snapshot_id: snapshot id to be created -+ */ -+static int -+__devlink_region_snapshot_create(struct devlink_region *region, -+ u8 *data, u32 snapshot_id) -+{ -+ struct devlink *devlink = region->devlink; -+ struct devlink_snapshot *snapshot; -+ int err; -+ -+ lockdep_assert_held(®ion->snapshot_lock); -+ -+ /* check if region can hold one more snapshot */ -+ if (region->cur_snapshots == region->max_snapshots) -+ return -ENOSPC; -+ -+ if (devlink_region_snapshot_get_by_id(region, snapshot_id)) -+ return -EEXIST; -+ -+ snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL); -+ if (!snapshot) -+ return -ENOMEM; -+ -+ err = __devlink_snapshot_id_increment(devlink, snapshot_id); -+ if (err) -+ goto err_snapshot_id_increment; -+ -+ snapshot->id = snapshot_id; -+ snapshot->region = region; -+ snapshot->data = data; -+ -+ list_add_tail(&snapshot->list, ®ion->snapshot_list); -+ -+ region->cur_snapshots++; -+ -+ devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW); -+ return 0; -+ -+err_snapshot_id_increment: -+ kfree(snapshot); -+ return err; -+} -+ -+static void devlink_region_snapshot_del(struct devlink_region *region, -+ struct devlink_snapshot *snapshot) -+{ -+ struct devlink *devlink = region->devlink; -+ -+ lockdep_assert_held(®ion->snapshot_lock); -+ -+ devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL); -+ region->cur_snapshots--; -+ list_del(&snapshot->list); -+ region->ops->destructor(snapshot->data); -+ __devlink_snapshot_id_decrement(devlink, snapshot->id); -+ kfree(snapshot); -+} -+ -+static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_port *port = NULL; -+ struct devlink_region *region; -+ const char *region_name; -+ struct sk_buff *msg; -+ unsigned int index; -+ int err; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) -+ return -EINVAL; -+ -+ if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -+ index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -+ -+ port = devlink_port_get_by_index(devlink, index); -+ if (!port) -+ return -ENODEV; -+ } -+ -+ region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); -+ if (port) -+ region = devlink_port_region_get_by_name(port, region_name); -+ else -+ region = devlink_region_get_by_name(devlink, region_name); -+ -+ if (!region) -+ return -EINVAL; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET, -+ info->snd_portid, info->snd_seq, 0, -+ region); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb, -+ struct devlink_port *port, -+ int *idx, -+ int start) -+{ -+ struct devlink_region *region; -+ int err = 0; -+ -+ list_for_each_entry(region, &port->region_list, list) { -+ if (*idx < start) { -+ (*idx)++; -+ continue; -+ } -+ err = devlink_nl_region_fill(msg, port->devlink, -+ DEVLINK_CMD_REGION_GET, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI, region); -+ if (err) -+ goto out; -+ (*idx)++; -+ } -+ -+out: -+ return err; -+} -+ -+static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb, -+ struct devlink *devlink, -+ int *idx, -+ int start) -+{ -+ struct devlink_region *region; -+ struct devlink_port *port; -+ int err = 0; -+ -+ devl_lock(devlink); -+ list_for_each_entry(region, &devlink->region_list, list) { -+ if (*idx < start) { -+ (*idx)++; -+ continue; -+ } -+ err = devlink_nl_region_fill(msg, devlink, -+ DEVLINK_CMD_REGION_GET, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI, region); -+ if (err) -+ goto out; -+ (*idx)++; -+ } -+ -+ list_for_each_entry(port, &devlink->port_list, list) { -+ err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx, -+ start); -+ if (err) -+ goto out; -+ } -+ -+out: -+ devl_unlock(devlink); -+ return err; -+} -+ -+static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err = 0; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink, -+ &idx, start); -+ devlink_put(devlink); -+ if (err) -+ goto out; -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int devlink_nl_cmd_region_del(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_snapshot *snapshot; -+ struct devlink_port *port = NULL; -+ struct devlink_region *region; -+ const char *region_name; -+ unsigned int index; -+ u32 snapshot_id; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) || -+ GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID)) -+ return -EINVAL; -+ -+ region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); -+ snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); -+ -+ if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -+ index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -+ -+ port = devlink_port_get_by_index(devlink, index); -+ if (!port) -+ return -ENODEV; -+ } -+ -+ if (port) -+ region = devlink_port_region_get_by_name(port, region_name); -+ else -+ region = devlink_region_get_by_name(devlink, region_name); -+ -+ if (!region) -+ return -EINVAL; -+ -+ mutex_lock(®ion->snapshot_lock); -+ snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); -+ if (!snapshot) { -+ mutex_unlock(®ion->snapshot_lock); -+ return -EINVAL; -+ } -+ -+ devlink_region_snapshot_del(region, snapshot); -+ mutex_unlock(®ion->snapshot_lock); -+ return 0; -+} -+ -+static int -+devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_snapshot *snapshot; -+ struct devlink_port *port = NULL; -+ struct nlattr *snapshot_id_attr; -+ struct devlink_region *region; -+ const char *region_name; -+ unsigned int index; -+ u32 snapshot_id; -+ u8 *data; -+ int err; -+ -+ if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) { -+ NL_SET_ERR_MSG_MOD(info->extack, "No region name provided"); -+ return -EINVAL; -+ } -+ -+ region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); -+ -+ if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -+ index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -+ -+ port = devlink_port_get_by_index(devlink, index); -+ if (!port) -+ return -ENODEV; -+ } -+ -+ if (port) -+ region = devlink_port_region_get_by_name(port, region_name); -+ else -+ region = devlink_region_get_by_name(devlink, region_name); -+ -+ if (!region) { -+ NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist"); -+ return -EINVAL; -+ } -+ -+ if (!region->ops->snapshot) { -+ NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot"); -+ return -EOPNOTSUPP; -+ } -+ -+ mutex_lock(®ion->snapshot_lock); -+ -+ if (region->cur_snapshots == region->max_snapshots) { -+ NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots"); -+ err = -ENOSPC; -+ goto unlock; -+ } -+ -+ snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; -+ if (snapshot_id_attr) { -+ snapshot_id = nla_get_u32(snapshot_id_attr); -+ -+ if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { -+ NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use"); -+ err = -EEXIST; -+ goto unlock; -+ } -+ -+ err = __devlink_snapshot_id_insert(devlink, snapshot_id); -+ if (err) -+ goto unlock; -+ } else { -+ err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); -+ if (err) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id"); -+ goto unlock; -+ } -+ } -+ -+ if (port) -+ err = region->port_ops->snapshot(port, region->port_ops, -+ info->extack, &data); -+ else -+ err = region->ops->snapshot(devlink, region->ops, -+ info->extack, &data); -+ if (err) -+ goto err_snapshot_capture; -+ -+ err = __devlink_region_snapshot_create(region, data, snapshot_id); -+ if (err) -+ goto err_snapshot_create; -+ -+ if (!snapshot_id_attr) { -+ struct sk_buff *msg; -+ -+ snapshot = devlink_region_snapshot_get_by_id(region, -+ snapshot_id); -+ if (WARN_ON(!snapshot)) { -+ err = -EINVAL; -+ goto unlock; -+ } -+ -+ msg = devlink_nl_region_notify_build(region, snapshot, -+ DEVLINK_CMD_REGION_NEW, -+ info->snd_portid, -+ info->snd_seq); -+ err = PTR_ERR_OR_ZERO(msg); -+ if (err) -+ goto err_notify; -+ -+ err = genlmsg_reply(msg, info); -+ if (err) -+ goto err_notify; -+ } -+ -+ mutex_unlock(®ion->snapshot_lock); -+ return 0; -+ -+err_snapshot_create: -+ region->ops->destructor(data); -+err_snapshot_capture: -+ __devlink_snapshot_id_decrement(devlink, snapshot_id); -+ mutex_unlock(®ion->snapshot_lock); -+ return err; -+ -+err_notify: -+ devlink_region_snapshot_del(region, snapshot); -+unlock: -+ mutex_unlock(®ion->snapshot_lock); -+ return err; -+} -+ -+static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg, -+ struct devlink *devlink, -+ u8 *chunk, u32 chunk_size, -+ u64 addr) -+{ -+ struct nlattr *chunk_attr; -+ int err; -+ -+ chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK); -+ if (!chunk_attr) -+ return -EINVAL; -+ -+ err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk); -+ if (err) -+ goto nla_put_failure; -+ -+ err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr, -+ DEVLINK_ATTR_PAD); -+ if (err) -+ goto nla_put_failure; -+ -+ nla_nest_end(msg, chunk_attr); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, chunk_attr); -+ return err; -+} -+ -+#define DEVLINK_REGION_READ_CHUNK_SIZE 256 -+ -+static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb, -+ struct devlink *devlink, -+ struct devlink_region *region, -+ struct nlattr **attrs, -+ u64 start_offset, -+ u64 end_offset, -+ u64 *new_offset) -+{ -+ struct devlink_snapshot *snapshot; -+ u64 curr_offset = start_offset; -+ u32 snapshot_id; -+ int err = 0; -+ -+ *new_offset = start_offset; -+ -+ snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); -+ snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); -+ if (!snapshot) -+ return -EINVAL; -+ -+ while (curr_offset < end_offset) { -+ u32 data_size; -+ u8 *data; -+ -+ if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE) -+ data_size = end_offset - curr_offset; -+ else -+ data_size = DEVLINK_REGION_READ_CHUNK_SIZE; -+ -+ data = &snapshot->data[curr_offset]; -+ err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink, -+ data, data_size, -+ curr_offset); -+ if (err) -+ break; -+ -+ curr_offset += data_size; -+ } -+ *new_offset = curr_offset; -+ -+ return err; -+} -+ -+static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, -+ struct netlink_callback *cb) -+{ -+ const struct genl_dumpit_info *info = genl_dumpit_info(cb); -+ u64 ret_offset, start_offset, end_offset = U64_MAX; -+ struct nlattr **attrs = info->attrs; -+ struct devlink_port *port = NULL; -+ struct devlink_region *region; -+ struct nlattr *chunks_attr; -+ const char *region_name; -+ struct devlink *devlink; -+ unsigned int index; -+ void *hdr; -+ int err; -+ -+ start_offset = *((u64 *)&cb->args[0]); -+ -+ devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); -+ if (IS_ERR(devlink)) -+ return PTR_ERR(devlink); -+ -+ devl_lock(devlink); -+ -+ if (!attrs[DEVLINK_ATTR_REGION_NAME] || -+ !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) { -+ err = -EINVAL; -+ goto out_unlock; -+ } -+ -+ if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { -+ index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); -+ -+ port = devlink_port_get_by_index(devlink, index); -+ if (!port) { -+ err = -ENODEV; -+ goto out_unlock; -+ } -+ } -+ -+ region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]); -+ -+ if (port) -+ region = devlink_port_region_get_by_name(port, region_name); -+ else -+ region = devlink_region_get_by_name(devlink, region_name); -+ -+ if (!region) { -+ err = -EINVAL; -+ goto out_unlock; -+ } -+ -+ if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && -+ attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { -+ if (!start_offset) -+ start_offset = -+ nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); -+ -+ end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); -+ end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); -+ } -+ -+ if (end_offset > region->size) -+ end_offset = region->size; -+ -+ /* return 0 if there is no further data to read */ -+ if (start_offset == end_offset) { -+ err = 0; -+ goto out_unlock; -+ } -+ -+ hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, -+ &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, -+ DEVLINK_CMD_REGION_READ); -+ if (!hdr) { -+ err = -EMSGSIZE; -+ goto out_unlock; -+ } -+ -+ err = devlink_nl_put_handle(skb, devlink); -+ if (err) -+ goto nla_put_failure; -+ -+ if (region->port) { -+ err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX, -+ region->port->index); -+ if (err) -+ goto nla_put_failure; -+ } -+ -+ err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name); -+ if (err) -+ goto nla_put_failure; -+ -+ chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS); -+ if (!chunks_attr) { -+ err = -EMSGSIZE; -+ goto nla_put_failure; -+ } -+ -+ err = devlink_nl_region_read_snapshot_fill(skb, devlink, -+ region, attrs, -+ start_offset, -+ end_offset, &ret_offset); -+ -+ if (err && err != -EMSGSIZE) -+ goto nla_put_failure; -+ -+ /* Check if there was any progress done to prevent infinite loop */ -+ if (ret_offset == start_offset) { -+ err = -EINVAL; -+ goto nla_put_failure; -+ } -+ -+ *((u64 *)&cb->args[0]) = ret_offset; -+ -+ nla_nest_end(skb, chunks_attr); -+ genlmsg_end(skb, hdr); -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ return skb->len; -+ -+nla_put_failure: -+ genlmsg_cancel(skb, hdr); -+out_unlock: -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ return err; -+} -+ -+int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name) -+{ -+ if (!req->msg) -+ return 0; -+ return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name); -+} -+EXPORT_SYMBOL_GPL(devlink_info_driver_name_put); -+ -+int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) -+{ -+ if (!req->msg) -+ return 0; -+ return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); -+} -+EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); -+ -+int devlink_info_board_serial_number_put(struct devlink_info_req *req, -+ const char *bsn) -+{ -+ if (!req->msg) -+ return 0; -+ return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, -+ bsn); -+} -+EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); -+ -+static int devlink_info_version_put(struct devlink_info_req *req, int attr, -+ const char *version_name, -+ const char *version_value, -+ enum devlink_info_version_type version_type) -+{ -+ struct nlattr *nest; -+ int err; -+ -+ if (req->version_cb) -+ req->version_cb(version_name, version_type, -+ req->version_cb_priv); -+ -+ if (!req->msg) -+ return 0; -+ -+ nest = nla_nest_start_noflag(req->msg, attr); -+ if (!nest) -+ return -EMSGSIZE; -+ -+ err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, -+ version_name); -+ if (err) -+ goto nla_put_failure; -+ -+ err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, -+ version_value); -+ if (err) -+ goto nla_put_failure; -+ -+ nla_nest_end(req->msg, nest); -+ -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(req->msg, nest); -+ return err; -+} -+ -+int devlink_info_version_fixed_put(struct devlink_info_req *req, -+ const char *version_name, -+ const char *version_value) -+{ -+ return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, -+ version_name, version_value, -+ DEVLINK_INFO_VERSION_TYPE_NONE); -+} -+EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); -+ -+int devlink_info_version_stored_put(struct devlink_info_req *req, -+ const char *version_name, -+ const char *version_value) -+{ -+ return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, -+ version_name, version_value, -+ DEVLINK_INFO_VERSION_TYPE_NONE); -+} -+EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); -+ -+int devlink_info_version_stored_put_ext(struct devlink_info_req *req, -+ const char *version_name, -+ const char *version_value, -+ enum devlink_info_version_type version_type) -+{ -+ return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, -+ version_name, version_value, -+ version_type); -+} -+EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext); -+ -+int devlink_info_version_running_put(struct devlink_info_req *req, -+ const char *version_name, -+ const char *version_value) -+{ -+ return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, -+ version_name, version_value, -+ DEVLINK_INFO_VERSION_TYPE_NONE); -+} -+EXPORT_SYMBOL_GPL(devlink_info_version_running_put); -+ -+int devlink_info_version_running_put_ext(struct devlink_info_req *req, -+ const char *version_name, -+ const char *version_value, -+ enum devlink_info_version_type version_type) -+{ -+ return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, -+ version_name, version_value, -+ version_type); -+} -+EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext); -+ -+static int -+devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, -+ enum devlink_command cmd, u32 portid, -+ u32 seq, int flags, struct netlink_ext_ack *extack) -+{ -+ struct devlink_info_req req = {}; -+ void *hdr; -+ int err; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ err = -EMSGSIZE; -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto err_cancel_msg; -+ -+ req.msg = msg; -+ err = devlink->ops->info_get(devlink, &req, extack); -+ if (err) -+ goto err_cancel_msg; -+ -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+err_cancel_msg: -+ genlmsg_cancel(msg, hdr); -+ return err; -+} -+ -+static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct sk_buff *msg; -+ int err; -+ -+ if (!devlink->ops->info_get) -+ return -EOPNOTSUPP; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, -+ info->snd_portid, info->snd_seq, 0, -+ info->extack); -+ if (err) { -+ nlmsg_free(msg); -+ return err; -+ } -+ -+ return genlmsg_reply(msg, info); -+} -+ -+static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err = 0; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ if (idx < start || !devlink->ops->info_get) -+ goto inc; -+ -+ devl_lock(devlink); -+ err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, NLM_F_MULTI, -+ cb->extack); -+ devl_unlock(devlink); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ else if (err) { -+ devlink_put(devlink); -+ break; -+ } -+inc: -+ idx++; -+ devlink_put(devlink); -+ } -+ -+ if (err != -EMSGSIZE) -+ return err; -+ -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+struct devlink_fmsg_item { -+ struct list_head list; -+ int attrtype; -+ u8 nla_type; -+ u16 len; -+ int value[]; -+}; -+ -+struct devlink_fmsg { -+ struct list_head item_list; -+ bool putting_binary; /* This flag forces enclosing of binary data -+ * in an array brackets. It forces using -+ * of designated API: -+ * devlink_fmsg_binary_pair_nest_start() -+ * devlink_fmsg_binary_pair_nest_end() -+ */ -+}; -+ -+static struct devlink_fmsg *devlink_fmsg_alloc(void) -+{ -+ struct devlink_fmsg *fmsg; -+ -+ fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL); -+ if (!fmsg) -+ return NULL; -+ -+ INIT_LIST_HEAD(&fmsg->item_list); -+ -+ return fmsg; -+} -+ -+static void devlink_fmsg_free(struct devlink_fmsg *fmsg) -+{ -+ struct devlink_fmsg_item *item, *tmp; -+ -+ list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) { -+ list_del(&item->list); -+ kfree(item); -+ } -+ kfree(fmsg); -+} -+ -+static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg, -+ int attrtype) -+{ -+ struct devlink_fmsg_item *item; -+ -+ item = kzalloc(sizeof(*item), GFP_KERNEL); -+ if (!item) -+ return -ENOMEM; -+ -+ item->attrtype = attrtype; -+ list_add_tail(&item->list, &fmsg->item_list); -+ -+ return 0; -+} -+ -+int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START); -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start); -+ -+static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END); -+} -+ -+int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_nest_end(fmsg); -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end); -+ -+#define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN) -+ -+static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name) -+{ -+ struct devlink_fmsg_item *item; -+ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE) -+ return -EMSGSIZE; -+ -+ item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL); -+ if (!item) -+ return -ENOMEM; -+ -+ item->nla_type = NLA_NUL_STRING; -+ item->len = strlen(name) + 1; -+ item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME; -+ memcpy(&item->value, name, item->len); -+ list_add_tail(&item->list, &fmsg->item_list); -+ -+ return 0; -+} -+ -+int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name) -+{ -+ int err; -+ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_put_name(fmsg, name); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start); -+ -+int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_nest_end(fmsg); -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end); -+ -+int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg, -+ const char *name) -+{ -+ int err; -+ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ err = devlink_fmsg_pair_nest_start(fmsg, name); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start); -+ -+int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg) -+{ -+ int err; -+ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ err = devlink_fmsg_nest_end(fmsg); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_nest_end(fmsg); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end); -+ -+int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg, -+ const char *name) -+{ -+ int err; -+ -+ err = devlink_fmsg_arr_pair_nest_start(fmsg, name); -+ if (err) -+ return err; -+ -+ fmsg->putting_binary = true; -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start); -+ -+int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg) -+{ -+ if (!fmsg->putting_binary) -+ return -EINVAL; -+ -+ fmsg->putting_binary = false; -+ return devlink_fmsg_arr_pair_nest_end(fmsg); -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end); -+ -+static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg, -+ const void *value, u16 value_len, -+ u8 value_nla_type) -+{ -+ struct devlink_fmsg_item *item; -+ -+ if (value_len > DEVLINK_FMSG_MAX_SIZE) -+ return -EMSGSIZE; -+ -+ item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL); -+ if (!item) -+ return -ENOMEM; -+ -+ item->nla_type = value_nla_type; -+ item->len = value_len; -+ item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; -+ memcpy(&item->value, value, item->len); -+ list_add_tail(&item->list, &fmsg->item_list); -+ -+ return 0; -+} -+ -+static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG); -+} -+ -+static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8); -+} -+ -+int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32); -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put); -+ -+static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64); -+} -+ -+int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value) -+{ -+ if (fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1, -+ NLA_NUL_STRING); -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_string_put); -+ -+int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value, -+ u16 value_len) -+{ -+ if (!fmsg->putting_binary) -+ return -EINVAL; -+ -+ return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY); -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put); -+ -+int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name, -+ bool value) -+{ -+ int err; -+ -+ err = devlink_fmsg_pair_nest_start(fmsg, name); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_bool_put(fmsg, value); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_pair_nest_end(fmsg); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put); -+ -+int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name, -+ u8 value) -+{ -+ int err; -+ -+ err = devlink_fmsg_pair_nest_start(fmsg, name); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_u8_put(fmsg, value); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_pair_nest_end(fmsg); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put); -+ -+int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name, -+ u32 value) -+{ -+ int err; -+ -+ err = devlink_fmsg_pair_nest_start(fmsg, name); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_u32_put(fmsg, value); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_pair_nest_end(fmsg); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put); -+ -+int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name, -+ u64 value) -+{ -+ int err; -+ -+ err = devlink_fmsg_pair_nest_start(fmsg, name); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_u64_put(fmsg, value); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_pair_nest_end(fmsg); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put); -+ -+int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name, -+ const char *value) -+{ -+ int err; -+ -+ err = devlink_fmsg_pair_nest_start(fmsg, name); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_string_put(fmsg, value); -+ if (err) -+ return err; -+ -+ err = devlink_fmsg_pair_nest_end(fmsg); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put); -+ -+int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name, -+ const void *value, u32 value_len) -+{ -+ u32 data_size; -+ int end_err; -+ u32 offset; -+ int err; -+ -+ err = devlink_fmsg_binary_pair_nest_start(fmsg, name); -+ if (err) -+ return err; -+ -+ for (offset = 0; offset < value_len; offset += data_size) { -+ data_size = value_len - offset; -+ if (data_size > DEVLINK_FMSG_MAX_SIZE) -+ data_size = DEVLINK_FMSG_MAX_SIZE; -+ err = devlink_fmsg_binary_put(fmsg, value + offset, data_size); -+ if (err) -+ break; -+ /* Exit from loop with a break (instead of -+ * return) to make sure putting_binary is turned off in -+ * devlink_fmsg_binary_pair_nest_end -+ */ -+ } -+ -+ end_err = devlink_fmsg_binary_pair_nest_end(fmsg); -+ if (end_err) -+ err = end_err; -+ -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put); -+ -+static int -+devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb) -+{ -+ switch (msg->nla_type) { -+ case NLA_FLAG: -+ case NLA_U8: -+ case NLA_U32: -+ case NLA_U64: -+ case NLA_NUL_STRING: -+ case NLA_BINARY: -+ return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, -+ msg->nla_type); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int -+devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb) -+{ -+ int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA; -+ u8 tmp; -+ -+ switch (msg->nla_type) { -+ case NLA_FLAG: -+ /* Always provide flag data, regardless of its value */ -+ tmp = *(bool *) msg->value; -+ -+ return nla_put_u8(skb, attrtype, tmp); -+ case NLA_U8: -+ return nla_put_u8(skb, attrtype, *(u8 *) msg->value); -+ case NLA_U32: -+ return nla_put_u32(skb, attrtype, *(u32 *) msg->value); -+ case NLA_U64: -+ return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value, -+ DEVLINK_ATTR_PAD); -+ case NLA_NUL_STRING: -+ return nla_put_string(skb, attrtype, (char *) &msg->value); -+ case NLA_BINARY: -+ return nla_put(skb, attrtype, msg->len, (void *) &msg->value); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int -+devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb, -+ int *start) -+{ -+ struct devlink_fmsg_item *item; -+ struct nlattr *fmsg_nlattr; -+ int i = 0; -+ int err; -+ -+ fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG); -+ if (!fmsg_nlattr) -+ return -EMSGSIZE; -+ -+ list_for_each_entry(item, &fmsg->item_list, list) { -+ if (i < *start) { -+ i++; -+ continue; -+ } -+ -+ switch (item->attrtype) { -+ case DEVLINK_ATTR_FMSG_OBJ_NEST_START: -+ case DEVLINK_ATTR_FMSG_PAIR_NEST_START: -+ case DEVLINK_ATTR_FMSG_ARR_NEST_START: -+ case DEVLINK_ATTR_FMSG_NEST_END: -+ err = nla_put_flag(skb, item->attrtype); -+ break; -+ case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA: -+ err = devlink_fmsg_item_fill_type(item, skb); -+ if (err) -+ break; -+ err = devlink_fmsg_item_fill_data(item, skb); -+ break; -+ case DEVLINK_ATTR_FMSG_OBJ_NAME: -+ err = nla_put_string(skb, item->attrtype, -+ (char *) &item->value); -+ break; -+ default: -+ err = -EINVAL; -+ break; -+ } -+ if (!err) -+ *start = ++i; -+ else -+ break; -+ } -+ -+ nla_nest_end(skb, fmsg_nlattr); -+ return err; -+} -+ -+static int devlink_fmsg_snd(struct devlink_fmsg *fmsg, -+ struct genl_info *info, -+ enum devlink_command cmd, int flags) -+{ -+ struct nlmsghdr *nlh; -+ struct sk_buff *skb; -+ bool last = false; -+ int index = 0; -+ void *hdr; -+ int err; -+ -+ while (!last) { -+ int tmp_index = index; -+ -+ skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ -+ hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, -+ &devlink_nl_family, flags | NLM_F_MULTI, cmd); -+ if (!hdr) { -+ err = -EMSGSIZE; -+ goto nla_put_failure; -+ } -+ -+ err = devlink_fmsg_prepare_skb(fmsg, skb, &index); -+ if (!err) -+ last = true; -+ else if (err != -EMSGSIZE || tmp_index == index) -+ goto nla_put_failure; -+ -+ genlmsg_end(skb, hdr); -+ err = genlmsg_reply(skb, info); -+ if (err) -+ return err; -+ } -+ -+ skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, -+ NLMSG_DONE, 0, flags | NLM_F_MULTI); -+ if (!nlh) { -+ err = -EMSGSIZE; -+ goto nla_put_failure; -+ } -+ -+ return genlmsg_reply(skb, info); -+ -+nla_put_failure: -+ nlmsg_free(skb); -+ return err; -+} -+ -+static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb, -+ struct netlink_callback *cb, -+ enum devlink_command cmd) -+{ -+ int index = cb->args[0]; -+ int tmp_index = index; -+ void *hdr; -+ int err; -+ -+ hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, -+ &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd); -+ if (!hdr) { -+ err = -EMSGSIZE; -+ goto nla_put_failure; -+ } -+ -+ err = devlink_fmsg_prepare_skb(fmsg, skb, &index); -+ if ((err && err != -EMSGSIZE) || tmp_index == index) -+ goto nla_put_failure; -+ -+ cb->args[0] = index; -+ genlmsg_end(skb, hdr); -+ return skb->len; -+ -+nla_put_failure: -+ genlmsg_cancel(skb, hdr); -+ return err; -+} -+ -+struct devlink_health_reporter { -+ struct list_head list; -+ void *priv; -+ const struct devlink_health_reporter_ops *ops; -+ struct devlink *devlink; -+ struct devlink_port *devlink_port; -+ struct devlink_fmsg *dump_fmsg; -+ struct mutex dump_lock; /* lock parallel read/write from dump buffers */ -+ u64 graceful_period; -+ bool auto_recover; -+ bool auto_dump; -+ u8 health_state; -+ u64 dump_ts; -+ u64 dump_real_ts; -+ u64 error_count; -+ u64 recovery_count; -+ u64 last_recovery_ts; -+ refcount_t refcount; -+}; -+ -+void * -+devlink_health_reporter_priv(struct devlink_health_reporter *reporter) -+{ -+ return reporter->priv; -+} -+EXPORT_SYMBOL_GPL(devlink_health_reporter_priv); -+ -+static struct devlink_health_reporter * -+__devlink_health_reporter_find_by_name(struct list_head *reporter_list, -+ struct mutex *list_lock, -+ const char *reporter_name) -+{ -+ struct devlink_health_reporter *reporter; -+ -+ lockdep_assert_held(list_lock); -+ list_for_each_entry(reporter, reporter_list, list) -+ if (!strcmp(reporter->ops->name, reporter_name)) -+ return reporter; -+ return NULL; -+} -+ -+static struct devlink_health_reporter * -+devlink_health_reporter_find_by_name(struct devlink *devlink, -+ const char *reporter_name) -+{ -+ return __devlink_health_reporter_find_by_name(&devlink->reporter_list, -+ &devlink->reporters_lock, -+ reporter_name); -+} -+ -+static struct devlink_health_reporter * -+devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port, -+ const char *reporter_name) -+{ -+ return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list, -+ &devlink_port->reporters_lock, -+ reporter_name); -+} -+ -+static struct devlink_health_reporter * -+__devlink_health_reporter_create(struct devlink *devlink, -+ const struct devlink_health_reporter_ops *ops, -+ u64 graceful_period, void *priv) -+{ -+ struct devlink_health_reporter *reporter; -+ -+ if (WARN_ON(graceful_period && !ops->recover)) -+ return ERR_PTR(-EINVAL); -+ -+ reporter = kzalloc(sizeof(*reporter), GFP_KERNEL); -+ if (!reporter) -+ return ERR_PTR(-ENOMEM); -+ -+ reporter->priv = priv; -+ reporter->ops = ops; -+ reporter->devlink = devlink; -+ reporter->graceful_period = graceful_period; -+ reporter->auto_recover = !!ops->recover; -+ reporter->auto_dump = !!ops->dump; -+ mutex_init(&reporter->dump_lock); -+ refcount_set(&reporter->refcount, 1); -+ return reporter; -+} -+ -+/** -+ * devlink_port_health_reporter_create - create devlink health reporter for -+ * specified port instance -+ * -+ * @port: devlink_port which should contain the new reporter -+ * @ops: ops -+ * @graceful_period: to avoid recovery loops, in msecs -+ * @priv: priv -+ */ -+struct devlink_health_reporter * -+devlink_port_health_reporter_create(struct devlink_port *port, -+ const struct devlink_health_reporter_ops *ops, -+ u64 graceful_period, void *priv) -+{ -+ struct devlink_health_reporter *reporter; -+ -+ mutex_lock(&port->reporters_lock); -+ if (__devlink_health_reporter_find_by_name(&port->reporter_list, -+ &port->reporters_lock, ops->name)) { -+ reporter = ERR_PTR(-EEXIST); -+ goto unlock; -+ } -+ -+ reporter = __devlink_health_reporter_create(port->devlink, ops, -+ graceful_period, priv); -+ if (IS_ERR(reporter)) -+ goto unlock; -+ -+ reporter->devlink_port = port; -+ list_add_tail(&reporter->list, &port->reporter_list); -+unlock: -+ mutex_unlock(&port->reporters_lock); -+ return reporter; -+} -+EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create); -+ -+/** -+ * devlink_health_reporter_create - create devlink health reporter -+ * -+ * @devlink: devlink -+ * @ops: ops -+ * @graceful_period: to avoid recovery loops, in msecs -+ * @priv: priv -+ */ -+struct devlink_health_reporter * -+devlink_health_reporter_create(struct devlink *devlink, -+ const struct devlink_health_reporter_ops *ops, -+ u64 graceful_period, void *priv) -+{ -+ struct devlink_health_reporter *reporter; -+ -+ mutex_lock(&devlink->reporters_lock); -+ if (devlink_health_reporter_find_by_name(devlink, ops->name)) { -+ reporter = ERR_PTR(-EEXIST); -+ goto unlock; -+ } -+ -+ reporter = __devlink_health_reporter_create(devlink, ops, -+ graceful_period, priv); -+ if (IS_ERR(reporter)) -+ goto unlock; -+ -+ list_add_tail(&reporter->list, &devlink->reporter_list); -+unlock: -+ mutex_unlock(&devlink->reporters_lock); -+ return reporter; -+} -+EXPORT_SYMBOL_GPL(devlink_health_reporter_create); -+ -+static void -+devlink_health_reporter_free(struct devlink_health_reporter *reporter) -+{ -+ mutex_destroy(&reporter->dump_lock); -+ if (reporter->dump_fmsg) -+ devlink_fmsg_free(reporter->dump_fmsg); -+ kfree(reporter); -+} -+ -+static void -+devlink_health_reporter_put(struct devlink_health_reporter *reporter) -+{ -+ if (refcount_dec_and_test(&reporter->refcount)) -+ devlink_health_reporter_free(reporter); -+} -+ -+static void -+__devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) -+{ -+ list_del(&reporter->list); -+ devlink_health_reporter_put(reporter); -+} -+ -+/** -+ * devlink_health_reporter_destroy - destroy devlink health reporter -+ * -+ * @reporter: devlink health reporter to destroy -+ */ -+void -+devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) -+{ -+ struct mutex *lock = &reporter->devlink->reporters_lock; -+ -+ mutex_lock(lock); -+ __devlink_health_reporter_destroy(reporter); -+ mutex_unlock(lock); -+} -+EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy); -+ -+/** -+ * devlink_port_health_reporter_destroy - destroy devlink port health reporter -+ * -+ * @reporter: devlink health reporter to destroy -+ */ -+void -+devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter) -+{ -+ struct mutex *lock = &reporter->devlink_port->reporters_lock; -+ -+ mutex_lock(lock); -+ __devlink_health_reporter_destroy(reporter); -+ mutex_unlock(lock); -+} -+EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy); -+ -+static int -+devlink_nl_health_reporter_fill(struct sk_buff *msg, -+ struct devlink_health_reporter *reporter, -+ enum devlink_command cmd, u32 portid, -+ u32 seq, int flags) -+{ -+ struct devlink *devlink = reporter->devlink; -+ struct nlattr *reporter_attr; -+ void *hdr; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto genlmsg_cancel; -+ -+ if (reporter->devlink_port) { -+ if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index)) -+ goto genlmsg_cancel; -+ } -+ reporter_attr = nla_nest_start_noflag(msg, -+ DEVLINK_ATTR_HEALTH_REPORTER); -+ if (!reporter_attr) -+ goto genlmsg_cancel; -+ if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME, -+ reporter->ops->name)) -+ goto reporter_nest_cancel; -+ if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE, -+ reporter->health_state)) -+ goto reporter_nest_cancel; -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT, -+ reporter->error_count, DEVLINK_ATTR_PAD)) -+ goto reporter_nest_cancel; -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT, -+ reporter->recovery_count, DEVLINK_ATTR_PAD)) -+ goto reporter_nest_cancel; -+ if (reporter->ops->recover && -+ nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, -+ reporter->graceful_period, -+ DEVLINK_ATTR_PAD)) -+ goto reporter_nest_cancel; -+ if (reporter->ops->recover && -+ nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, -+ reporter->auto_recover)) -+ goto reporter_nest_cancel; -+ if (reporter->dump_fmsg && -+ nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS, -+ jiffies_to_msecs(reporter->dump_ts), -+ DEVLINK_ATTR_PAD)) -+ goto reporter_nest_cancel; -+ if (reporter->dump_fmsg && -+ nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, -+ reporter->dump_real_ts, DEVLINK_ATTR_PAD)) -+ goto reporter_nest_cancel; -+ if (reporter->ops->dump && -+ nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, -+ reporter->auto_dump)) -+ goto reporter_nest_cancel; -+ -+ nla_nest_end(msg, reporter_attr); -+ genlmsg_end(msg, hdr); -+ return 0; -+ -+reporter_nest_cancel: -+ nla_nest_end(msg, reporter_attr); -+genlmsg_cancel: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static void devlink_recover_notify(struct devlink_health_reporter *reporter, -+ enum devlink_command cmd) -+{ -+ struct devlink *devlink = reporter->devlink; -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER); -+ WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)); -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, -+ 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+void -+devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter) -+{ -+ reporter->recovery_count++; -+ reporter->last_recovery_ts = jiffies; -+} -+EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done); -+ -+static int -+devlink_health_reporter_recover(struct devlink_health_reporter *reporter, -+ void *priv_ctx, struct netlink_ext_ack *extack) -+{ -+ int err; -+ -+ if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY) -+ return 0; -+ -+ if (!reporter->ops->recover) -+ return -EOPNOTSUPP; -+ -+ err = reporter->ops->recover(reporter, priv_ctx, extack); -+ if (err) -+ return err; -+ -+ devlink_health_reporter_recovery_done(reporter); -+ reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY; -+ devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); -+ -+ return 0; -+} -+ -+static void -+devlink_health_dump_clear(struct devlink_health_reporter *reporter) -+{ -+ if (!reporter->dump_fmsg) -+ return; -+ devlink_fmsg_free(reporter->dump_fmsg); -+ reporter->dump_fmsg = NULL; -+} -+ -+static int devlink_health_do_dump(struct devlink_health_reporter *reporter, -+ void *priv_ctx, -+ struct netlink_ext_ack *extack) -+{ -+ int err; -+ -+ if (!reporter->ops->dump) -+ return 0; -+ -+ if (reporter->dump_fmsg) -+ return 0; -+ -+ reporter->dump_fmsg = devlink_fmsg_alloc(); -+ if (!reporter->dump_fmsg) { -+ err = -ENOMEM; -+ return err; -+ } -+ -+ err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg); -+ if (err) -+ goto dump_err; -+ -+ err = reporter->ops->dump(reporter, reporter->dump_fmsg, -+ priv_ctx, extack); -+ if (err) -+ goto dump_err; -+ -+ err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg); -+ if (err) -+ goto dump_err; -+ -+ reporter->dump_ts = jiffies; -+ reporter->dump_real_ts = ktime_get_real_ns(); -+ -+ return 0; -+ -+dump_err: -+ devlink_health_dump_clear(reporter); -+ return err; -+} -+ -+int devlink_health_report(struct devlink_health_reporter *reporter, -+ const char *msg, void *priv_ctx) -+{ -+ enum devlink_health_reporter_state prev_health_state; -+ struct devlink *devlink = reporter->devlink; -+ unsigned long recover_ts_threshold; -+ int ret; -+ -+ /* write a log message of the current error */ -+ WARN_ON(!msg); -+ trace_devlink_health_report(devlink, reporter->ops->name, msg); -+ reporter->error_count++; -+ prev_health_state = reporter->health_state; -+ reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; -+ devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); -+ -+ /* abort if the previous error wasn't recovered */ -+ recover_ts_threshold = reporter->last_recovery_ts + -+ msecs_to_jiffies(reporter->graceful_period); -+ if (reporter->auto_recover && -+ (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY || -+ (reporter->last_recovery_ts && reporter->recovery_count && -+ time_is_after_jiffies(recover_ts_threshold)))) { -+ trace_devlink_health_recover_aborted(devlink, -+ reporter->ops->name, -+ reporter->health_state, -+ jiffies - -+ reporter->last_recovery_ts); -+ return -ECANCELED; -+ } -+ -+ reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; -+ -+ if (reporter->auto_dump) { -+ mutex_lock(&reporter->dump_lock); -+ /* store current dump of current error, for later analysis */ -+ devlink_health_do_dump(reporter, priv_ctx, NULL); -+ mutex_unlock(&reporter->dump_lock); -+ } -+ -+ if (!reporter->auto_recover) -+ return 0; -+ -+ devl_lock(devlink); -+ ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL); -+ devl_unlock(devlink); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(devlink_health_report); -+ -+static struct devlink_health_reporter * -+devlink_health_reporter_get_from_attrs(struct devlink *devlink, -+ struct nlattr **attrs) -+{ -+ struct devlink_health_reporter *reporter; -+ struct devlink_port *devlink_port; -+ char *reporter_name; -+ -+ if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]) -+ return NULL; -+ -+ reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]); -+ devlink_port = devlink_port_get_from_attrs(devlink, attrs); -+ if (IS_ERR(devlink_port)) { -+ mutex_lock(&devlink->reporters_lock); -+ reporter = devlink_health_reporter_find_by_name(devlink, reporter_name); -+ if (reporter) -+ refcount_inc(&reporter->refcount); -+ mutex_unlock(&devlink->reporters_lock); -+ } else { -+ mutex_lock(&devlink_port->reporters_lock); -+ reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name); -+ if (reporter) -+ refcount_inc(&reporter->refcount); -+ mutex_unlock(&devlink_port->reporters_lock); -+ } -+ -+ return reporter; -+} -+ -+static struct devlink_health_reporter * -+devlink_health_reporter_get_from_info(struct devlink *devlink, -+ struct genl_info *info) -+{ -+ return devlink_health_reporter_get_from_attrs(devlink, info->attrs); -+} -+ -+static struct devlink_health_reporter * -+devlink_health_reporter_get_from_cb(struct netlink_callback *cb) -+{ -+ const struct genl_dumpit_info *info = genl_dumpit_info(cb); -+ struct devlink_health_reporter *reporter; -+ struct nlattr **attrs = info->attrs; -+ struct devlink *devlink; -+ -+ devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); -+ if (IS_ERR(devlink)) -+ return NULL; -+ -+ reporter = devlink_health_reporter_get_from_attrs(devlink, attrs); -+ devlink_put(devlink); -+ return reporter; -+} -+ -+void -+devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, -+ enum devlink_health_reporter_state state) -+{ -+ if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY && -+ state != DEVLINK_HEALTH_REPORTER_STATE_ERROR)) -+ return; -+ -+ if (reporter->health_state == state) -+ return; -+ -+ reporter->health_state = state; -+ trace_devlink_health_reporter_state_update(reporter->devlink, -+ reporter->ops->name, state); -+ devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); -+} -+EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update); -+ -+static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_health_reporter *reporter; -+ struct sk_buff *msg; -+ int err; -+ -+ reporter = devlink_health_reporter_get_from_info(devlink, info); -+ if (!reporter) -+ return -EINVAL; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ err = devlink_nl_health_reporter_fill(msg, reporter, -+ DEVLINK_CMD_HEALTH_REPORTER_GET, -+ info->snd_portid, info->snd_seq, -+ 0); -+ if (err) { -+ nlmsg_free(msg); -+ goto out; -+ } -+ -+ err = genlmsg_reply(msg, info); -+out: -+ devlink_health_reporter_put(reporter); -+ return err; -+} -+ -+static int -+devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink_health_reporter *reporter; -+ struct devlink_port *port; -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ mutex_lock(&devlink->reporters_lock); -+ list_for_each_entry(reporter, &devlink->reporter_list, -+ list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_health_reporter_fill( -+ msg, reporter, DEVLINK_CMD_HEALTH_REPORTER_GET, -+ NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, -+ NLM_F_MULTI); -+ if (err) { -+ mutex_unlock(&devlink->reporters_lock); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ mutex_unlock(&devlink->reporters_lock); -+ devlink_put(devlink); -+ } -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ devl_lock(devlink); -+ list_for_each_entry(port, &devlink->port_list, list) { -+ mutex_lock(&port->reporters_lock); -+ list_for_each_entry(reporter, &port->reporter_list, list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_health_reporter_fill( -+ msg, reporter, -+ DEVLINK_CMD_HEALTH_REPORTER_GET, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, NLM_F_MULTI); -+ if (err) { -+ mutex_unlock(&port->reporters_lock); -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ mutex_unlock(&port->reporters_lock); -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int -+devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_health_reporter *reporter; -+ int err; -+ -+ reporter = devlink_health_reporter_get_from_info(devlink, info); -+ if (!reporter) -+ return -EINVAL; -+ -+ if (!reporter->ops->recover && -+ (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] || -+ info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ if (!reporter->ops->dump && -+ info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]) -+ reporter->graceful_period = -+ nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]); -+ -+ if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]) -+ reporter->auto_recover = -+ nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]); -+ -+ if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) -+ reporter->auto_dump = -+ nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]); -+ -+ devlink_health_reporter_put(reporter); -+ return 0; -+out: -+ devlink_health_reporter_put(reporter); -+ return err; -+} -+ -+static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_health_reporter *reporter; -+ int err; -+ -+ reporter = devlink_health_reporter_get_from_info(devlink, info); -+ if (!reporter) -+ return -EINVAL; -+ -+ err = devlink_health_reporter_recover(reporter, NULL, info->extack); -+ -+ devlink_health_reporter_put(reporter); -+ return err; -+} -+ -+static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_health_reporter *reporter; -+ struct devlink_fmsg *fmsg; -+ int err; -+ -+ reporter = devlink_health_reporter_get_from_info(devlink, info); -+ if (!reporter) -+ return -EINVAL; -+ -+ if (!reporter->ops->diagnose) { -+ devlink_health_reporter_put(reporter); -+ return -EOPNOTSUPP; -+ } -+ -+ fmsg = devlink_fmsg_alloc(); -+ if (!fmsg) { -+ devlink_health_reporter_put(reporter); -+ return -ENOMEM; -+ } -+ -+ err = devlink_fmsg_obj_nest_start(fmsg); -+ if (err) -+ goto out; -+ -+ err = reporter->ops->diagnose(reporter, fmsg, info->extack); -+ if (err) -+ goto out; -+ -+ err = devlink_fmsg_obj_nest_end(fmsg); -+ if (err) -+ goto out; -+ -+ err = devlink_fmsg_snd(fmsg, info, -+ DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0); -+ -+out: -+ devlink_fmsg_free(fmsg); -+ devlink_health_reporter_put(reporter); -+ return err; -+} -+ -+static int -+devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb, -+ struct netlink_callback *cb) -+{ -+ struct devlink_health_reporter *reporter; -+ u64 start = cb->args[0]; -+ int err; -+ -+ reporter = devlink_health_reporter_get_from_cb(cb); -+ if (!reporter) -+ return -EINVAL; -+ -+ if (!reporter->ops->dump) { -+ err = -EOPNOTSUPP; -+ goto out; -+ } -+ mutex_lock(&reporter->dump_lock); -+ if (!start) { -+ err = devlink_health_do_dump(reporter, NULL, cb->extack); -+ if (err) -+ goto unlock; -+ cb->args[1] = reporter->dump_ts; -+ } -+ if (!reporter->dump_fmsg || cb->args[1] != reporter->dump_ts) { -+ NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry"); -+ err = -EAGAIN; -+ goto unlock; -+ } -+ -+ err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb, -+ DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET); -+unlock: -+ mutex_unlock(&reporter->dump_lock); -+out: -+ devlink_health_reporter_put(reporter); -+ return err; -+} -+ -+static int -+devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_health_reporter *reporter; -+ -+ reporter = devlink_health_reporter_get_from_info(devlink, info); -+ if (!reporter) -+ return -EINVAL; -+ -+ if (!reporter->ops->dump) { -+ devlink_health_reporter_put(reporter); -+ return -EOPNOTSUPP; -+ } -+ -+ mutex_lock(&reporter->dump_lock); -+ devlink_health_dump_clear(reporter); -+ mutex_unlock(&reporter->dump_lock); -+ devlink_health_reporter_put(reporter); -+ return 0; -+} -+ -+static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_health_reporter *reporter; -+ int err; -+ -+ reporter = devlink_health_reporter_get_from_info(devlink, info); -+ if (!reporter) -+ return -EINVAL; -+ -+ if (!reporter->ops->test) { -+ devlink_health_reporter_put(reporter); -+ return -EOPNOTSUPP; -+ } -+ -+ err = reporter->ops->test(reporter, info->extack); -+ -+ devlink_health_reporter_put(reporter); -+ return err; -+} -+ -+struct devlink_stats { -+ u64_stats_t rx_bytes; -+ u64_stats_t rx_packets; -+ struct u64_stats_sync syncp; -+}; -+ -+/** -+ * struct devlink_trap_policer_item - Packet trap policer attributes. -+ * @policer: Immutable packet trap policer attributes. -+ * @rate: Rate in packets / sec. -+ * @burst: Burst size in packets. -+ * @list: trap_policer_list member. -+ * -+ * Describes packet trap policer attributes. Created by devlink during trap -+ * policer registration. -+ */ -+struct devlink_trap_policer_item { -+ const struct devlink_trap_policer *policer; -+ u64 rate; -+ u64 burst; -+ struct list_head list; -+}; -+ -+/** -+ * struct devlink_trap_group_item - Packet trap group attributes. -+ * @group: Immutable packet trap group attributes. -+ * @policer_item: Associated policer item. Can be NULL. -+ * @list: trap_group_list member. -+ * @stats: Trap group statistics. -+ * -+ * Describes packet trap group attributes. Created by devlink during trap -+ * group registration. -+ */ -+struct devlink_trap_group_item { -+ const struct devlink_trap_group *group; -+ struct devlink_trap_policer_item *policer_item; -+ struct list_head list; -+ struct devlink_stats __percpu *stats; -+}; -+ -+/** -+ * struct devlink_trap_item - Packet trap attributes. -+ * @trap: Immutable packet trap attributes. -+ * @group_item: Associated group item. -+ * @list: trap_list member. -+ * @action: Trap action. -+ * @stats: Trap statistics. -+ * @priv: Driver private information. -+ * -+ * Describes both mutable and immutable packet trap attributes. Created by -+ * devlink during trap registration and used for all trap related operations. -+ */ -+struct devlink_trap_item { -+ const struct devlink_trap *trap; -+ struct devlink_trap_group_item *group_item; -+ struct list_head list; -+ enum devlink_trap_action action; -+ struct devlink_stats __percpu *stats; -+ void *priv; -+}; -+ -+static struct devlink_trap_policer_item * -+devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id) -+{ -+ struct devlink_trap_policer_item *policer_item; -+ -+ list_for_each_entry(policer_item, &devlink->trap_policer_list, list) { -+ if (policer_item->policer->id == id) -+ return policer_item; -+ } -+ -+ return NULL; -+} -+ -+static struct devlink_trap_item * -+devlink_trap_item_lookup(struct devlink *devlink, const char *name) -+{ -+ struct devlink_trap_item *trap_item; -+ -+ list_for_each_entry(trap_item, &devlink->trap_list, list) { -+ if (!strcmp(trap_item->trap->name, name)) -+ return trap_item; -+ } -+ -+ return NULL; -+} -+ -+static struct devlink_trap_item * -+devlink_trap_item_get_from_info(struct devlink *devlink, -+ struct genl_info *info) -+{ -+ struct nlattr *attr; -+ -+ if (!info->attrs[DEVLINK_ATTR_TRAP_NAME]) -+ return NULL; -+ attr = info->attrs[DEVLINK_ATTR_TRAP_NAME]; -+ -+ return devlink_trap_item_lookup(devlink, nla_data(attr)); -+} -+ -+static int -+devlink_trap_action_get_from_info(struct genl_info *info, -+ enum devlink_trap_action *p_trap_action) -+{ -+ u8 val; -+ -+ val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]); -+ switch (val) { -+ case DEVLINK_TRAP_ACTION_DROP: -+ case DEVLINK_TRAP_ACTION_TRAP: -+ case DEVLINK_TRAP_ACTION_MIRROR: -+ *p_trap_action = val; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int devlink_trap_metadata_put(struct sk_buff *msg, -+ const struct devlink_trap *trap) -+{ -+ struct nlattr *attr; -+ -+ attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA); -+ if (!attr) -+ return -EMSGSIZE; -+ -+ if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) && -+ nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT)) -+ goto nla_put_failure; -+ if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) && -+ nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE)) -+ goto nla_put_failure; -+ -+ nla_nest_end(msg, attr); -+ -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, attr); -+ return -EMSGSIZE; -+} -+ -+static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats, -+ struct devlink_stats *stats) -+{ -+ int i; -+ -+ memset(stats, 0, sizeof(*stats)); -+ for_each_possible_cpu(i) { -+ struct devlink_stats *cpu_stats; -+ u64 rx_packets, rx_bytes; -+ unsigned int start; -+ -+ cpu_stats = per_cpu_ptr(trap_stats, i); -+ do { -+ start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); -+ rx_packets = u64_stats_read(&cpu_stats->rx_packets); -+ rx_bytes = u64_stats_read(&cpu_stats->rx_bytes); -+ } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); -+ -+ u64_stats_add(&stats->rx_packets, rx_packets); -+ u64_stats_add(&stats->rx_bytes, rx_bytes); -+ } -+} -+ -+static int -+devlink_trap_group_stats_put(struct sk_buff *msg, -+ struct devlink_stats __percpu *trap_stats) -+{ -+ struct devlink_stats stats; -+ struct nlattr *attr; -+ -+ devlink_trap_stats_read(trap_stats, &stats); -+ -+ attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); -+ if (!attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, -+ u64_stats_read(&stats.rx_packets), -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, -+ u64_stats_read(&stats.rx_bytes), -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ nla_nest_end(msg, attr); -+ -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, attr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink, -+ const struct devlink_trap_item *trap_item) -+{ -+ struct devlink_stats stats; -+ struct nlattr *attr; -+ u64 drops = 0; -+ int err; -+ -+ if (devlink->ops->trap_drop_counter_get) { -+ err = devlink->ops->trap_drop_counter_get(devlink, -+ trap_item->trap, -+ &drops); -+ if (err) -+ return err; -+ } -+ -+ devlink_trap_stats_read(trap_item->stats, &stats); -+ -+ attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); -+ if (!attr) -+ return -EMSGSIZE; -+ -+ if (devlink->ops->trap_drop_counter_get && -+ nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS, -+ u64_stats_read(&stats.rx_packets), -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES, -+ u64_stats_read(&stats.rx_bytes), -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ nla_nest_end(msg, attr); -+ -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, attr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink, -+ const struct devlink_trap_item *trap_item, -+ enum devlink_command cmd, u32 portid, u32 seq, -+ int flags) -+{ -+ struct devlink_trap_group_item *group_item = trap_item->group_item; -+ void *hdr; -+ int err; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ -+ if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, -+ group_item->group->name)) -+ goto nla_put_failure; -+ -+ if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type)) -+ goto nla_put_failure; -+ -+ if (trap_item->trap->generic && -+ nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action)) -+ goto nla_put_failure; -+ -+ err = devlink_trap_metadata_put(msg, trap_item->trap); -+ if (err) -+ goto nla_put_failure; -+ -+ err = devlink_trap_stats_put(msg, devlink, trap_item); -+ if (err) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct netlink_ext_ack *extack = info->extack; -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_trap_item *trap_item; -+ struct sk_buff *msg; -+ int err; -+ -+ if (list_empty(&devlink->trap_list)) -+ return -EOPNOTSUPP; -+ -+ trap_item = devlink_trap_item_get_from_info(devlink, info); -+ if (!trap_item) { -+ NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); -+ return -ENOENT; -+ } -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_trap_fill(msg, devlink, trap_item, -+ DEVLINK_CMD_TRAP_NEW, info->snd_portid, -+ info->snd_seq, 0); -+ if (err) -+ goto err_trap_fill; -+ -+ return genlmsg_reply(msg, info); -+ -+err_trap_fill: -+ nlmsg_free(msg); -+ return err; -+} -+ -+static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ struct devlink_trap_item *trap_item; -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ devl_lock(devlink); -+ list_for_each_entry(trap_item, &devlink->trap_list, list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_trap_fill(msg, devlink, trap_item, -+ DEVLINK_CMD_TRAP_NEW, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI); -+ if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int __devlink_trap_action_set(struct devlink *devlink, -+ struct devlink_trap_item *trap_item, -+ enum devlink_trap_action trap_action, -+ struct netlink_ext_ack *extack) -+{ -+ int err; -+ -+ if (trap_item->action != trap_action && -+ trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) { -+ NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping"); -+ return 0; -+ } -+ -+ err = devlink->ops->trap_action_set(devlink, trap_item->trap, -+ trap_action, extack); -+ if (err) -+ return err; -+ -+ trap_item->action = trap_action; -+ -+ return 0; -+} -+ -+static int devlink_trap_action_set(struct devlink *devlink, -+ struct devlink_trap_item *trap_item, -+ struct genl_info *info) -+{ -+ enum devlink_trap_action trap_action; -+ int err; -+ -+ if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) -+ return 0; -+ -+ err = devlink_trap_action_get_from_info(info, &trap_action); -+ if (err) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); -+ return -EINVAL; -+ } -+ -+ return __devlink_trap_action_set(devlink, trap_item, trap_action, -+ info->extack); -+} -+ -+static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct netlink_ext_ack *extack = info->extack; -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_trap_item *trap_item; -+ -+ if (list_empty(&devlink->trap_list)) -+ return -EOPNOTSUPP; -+ -+ trap_item = devlink_trap_item_get_from_info(devlink, info); -+ if (!trap_item) { -+ NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap"); -+ return -ENOENT; -+ } -+ -+ return devlink_trap_action_set(devlink, trap_item, info); -+} -+ -+static struct devlink_trap_group_item * -+devlink_trap_group_item_lookup(struct devlink *devlink, const char *name) -+{ -+ struct devlink_trap_group_item *group_item; -+ -+ list_for_each_entry(group_item, &devlink->trap_group_list, list) { -+ if (!strcmp(group_item->group->name, name)) -+ return group_item; -+ } -+ -+ return NULL; -+} -+ -+static struct devlink_trap_group_item * -+devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id) -+{ -+ struct devlink_trap_group_item *group_item; -+ -+ list_for_each_entry(group_item, &devlink->trap_group_list, list) { -+ if (group_item->group->id == id) -+ return group_item; -+ } -+ -+ return NULL; -+} -+ -+static struct devlink_trap_group_item * -+devlink_trap_group_item_get_from_info(struct devlink *devlink, -+ struct genl_info *info) -+{ -+ char *name; -+ -+ if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]) -+ return NULL; -+ name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]); -+ -+ return devlink_trap_group_item_lookup(devlink, name); -+} -+ -+static int -+devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink, -+ const struct devlink_trap_group_item *group_item, -+ enum devlink_command cmd, u32 portid, u32 seq, -+ int flags) -+{ -+ void *hdr; -+ int err; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ -+ if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME, -+ group_item->group->name)) -+ goto nla_put_failure; -+ -+ if (group_item->group->generic && -+ nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC)) -+ goto nla_put_failure; -+ -+ if (group_item->policer_item && -+ nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, -+ group_item->policer_item->policer->id)) -+ goto nla_put_failure; -+ -+ err = devlink_trap_group_stats_put(msg, group_item->stats); -+ if (err) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct netlink_ext_ack *extack = info->extack; -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_trap_group_item *group_item; -+ struct sk_buff *msg; -+ int err; -+ -+ if (list_empty(&devlink->trap_group_list)) -+ return -EOPNOTSUPP; -+ -+ group_item = devlink_trap_group_item_get_from_info(devlink, info); -+ if (!group_item) { -+ NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); -+ return -ENOENT; -+ } -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_trap_group_fill(msg, devlink, group_item, -+ DEVLINK_CMD_TRAP_GROUP_NEW, -+ info->snd_portid, info->snd_seq, 0); -+ if (err) -+ goto err_trap_group_fill; -+ -+ return genlmsg_reply(msg, info); -+ -+err_trap_group_fill: -+ nlmsg_free(msg); -+ return err; -+} -+ -+static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW; -+ struct devlink_trap_group_item *group_item; -+ u32 portid = NETLINK_CB(cb->skb).portid; -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ devl_lock(devlink); -+ list_for_each_entry(group_item, &devlink->trap_group_list, -+ list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_trap_group_fill(msg, devlink, -+ group_item, cmd, -+ portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI); -+ if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int -+__devlink_trap_group_action_set(struct devlink *devlink, -+ struct devlink_trap_group_item *group_item, -+ enum devlink_trap_action trap_action, -+ struct netlink_ext_ack *extack) -+{ -+ const char *group_name = group_item->group->name; -+ struct devlink_trap_item *trap_item; -+ int err; -+ -+ if (devlink->ops->trap_group_action_set) { -+ err = devlink->ops->trap_group_action_set(devlink, group_item->group, -+ trap_action, extack); -+ if (err) -+ return err; -+ -+ list_for_each_entry(trap_item, &devlink->trap_list, list) { -+ if (strcmp(trap_item->group_item->group->name, group_name)) -+ continue; -+ if (trap_item->action != trap_action && -+ trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) -+ continue; -+ trap_item->action = trap_action; -+ } -+ -+ return 0; -+ } -+ -+ list_for_each_entry(trap_item, &devlink->trap_list, list) { -+ if (strcmp(trap_item->group_item->group->name, group_name)) -+ continue; -+ err = __devlink_trap_action_set(devlink, trap_item, -+ trap_action, extack); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int -+devlink_trap_group_action_set(struct devlink *devlink, -+ struct devlink_trap_group_item *group_item, -+ struct genl_info *info, bool *p_modified) -+{ -+ enum devlink_trap_action trap_action; -+ int err; -+ -+ if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION]) -+ return 0; -+ -+ err = devlink_trap_action_get_from_info(info, &trap_action); -+ if (err) { -+ NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action"); -+ return -EINVAL; -+ } -+ -+ err = __devlink_trap_group_action_set(devlink, group_item, trap_action, -+ info->extack); -+ if (err) -+ return err; -+ -+ *p_modified = true; -+ -+ return 0; -+} -+ -+static int devlink_trap_group_set(struct devlink *devlink, -+ struct devlink_trap_group_item *group_item, -+ struct genl_info *info) -+{ -+ struct devlink_trap_policer_item *policer_item; -+ struct netlink_ext_ack *extack = info->extack; -+ const struct devlink_trap_policer *policer; -+ struct nlattr **attrs = info->attrs; -+ int err; -+ -+ if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) -+ return 0; -+ -+ if (!devlink->ops->trap_group_set) -+ return -EOPNOTSUPP; -+ -+ policer_item = group_item->policer_item; -+ if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) { -+ u32 policer_id; -+ -+ policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); -+ policer_item = devlink_trap_policer_item_lookup(devlink, -+ policer_id); -+ if (policer_id && !policer_item) { -+ NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); -+ return -ENOENT; -+ } -+ } -+ policer = policer_item ? policer_item->policer : NULL; -+ -+ err = devlink->ops->trap_group_set(devlink, group_item->group, policer, -+ extack); -+ if (err) -+ return err; -+ -+ group_item->policer_item = policer_item; -+ -+ return 0; -+} -+ -+static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct netlink_ext_ack *extack = info->extack; -+ struct devlink *devlink = info->user_ptr[0]; -+ struct devlink_trap_group_item *group_item; -+ bool modified = false; -+ int err; -+ -+ if (list_empty(&devlink->trap_group_list)) -+ return -EOPNOTSUPP; -+ -+ group_item = devlink_trap_group_item_get_from_info(devlink, info); -+ if (!group_item) { -+ NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group"); -+ return -ENOENT; -+ } -+ -+ err = devlink_trap_group_action_set(devlink, group_item, info, -+ &modified); -+ if (err) -+ return err; -+ -+ err = devlink_trap_group_set(devlink, group_item, info); -+ if (err) -+ goto err_trap_group_set; -+ -+ return 0; -+ -+err_trap_group_set: -+ if (modified) -+ NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already"); -+ return err; -+} -+ -+static struct devlink_trap_policer_item * -+devlink_trap_policer_item_get_from_info(struct devlink *devlink, -+ struct genl_info *info) -+{ -+ u32 id; -+ -+ if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) -+ return NULL; -+ id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]); -+ -+ return devlink_trap_policer_item_lookup(devlink, id); -+} -+ -+static int -+devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink, -+ const struct devlink_trap_policer *policer) -+{ -+ struct nlattr *attr; -+ u64 drops; -+ int err; -+ -+ if (!devlink->ops->trap_policer_counter_get) -+ return 0; -+ -+ err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops); -+ if (err) -+ return err; -+ -+ attr = nla_nest_start(msg, DEVLINK_ATTR_STATS); -+ if (!attr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops, -+ DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ nla_nest_end(msg, attr); -+ -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, attr); -+ return -EMSGSIZE; -+} -+ -+static int -+devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink, -+ const struct devlink_trap_policer_item *policer_item, -+ enum devlink_command cmd, u32 portid, u32 seq, -+ int flags) -+{ -+ void *hdr; -+ int err; -+ -+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); -+ if (!hdr) -+ return -EMSGSIZE; -+ -+ if (devlink_nl_put_handle(msg, devlink)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID, -+ policer_item->policer->id)) -+ goto nla_put_failure; -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE, -+ policer_item->rate, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST, -+ policer_item->burst, DEVLINK_ATTR_PAD)) -+ goto nla_put_failure; -+ -+ err = devlink_trap_policer_stats_put(msg, devlink, -+ policer_item->policer); -+ if (err) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ -+ return 0; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_trap_policer_item *policer_item; -+ struct netlink_ext_ack *extack = info->extack; -+ struct devlink *devlink = info->user_ptr[0]; -+ struct sk_buff *msg; -+ int err; -+ -+ if (list_empty(&devlink->trap_policer_list)) -+ return -EOPNOTSUPP; -+ -+ policer_item = devlink_trap_policer_item_get_from_info(devlink, info); -+ if (!policer_item) { -+ NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); -+ return -ENOENT; -+ } -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return -ENOMEM; -+ -+ err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, -+ DEVLINK_CMD_TRAP_POLICER_NEW, -+ info->snd_portid, info->snd_seq, 0); -+ if (err) -+ goto err_trap_policer_fill; -+ -+ return genlmsg_reply(msg, info); -+ -+err_trap_policer_fill: -+ nlmsg_free(msg); -+ return err; -+} -+ -+static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg, -+ struct netlink_callback *cb) -+{ -+ enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW; -+ struct devlink_trap_policer_item *policer_item; -+ u32 portid = NETLINK_CB(cb->skb).portid; -+ struct devlink *devlink; -+ int start = cb->args[0]; -+ unsigned long index; -+ int idx = 0; -+ int err; -+ -+ devlinks_xa_for_each_registered_get(sock_net(msg->sk), index, devlink) { -+ devl_lock(devlink); -+ list_for_each_entry(policer_item, &devlink->trap_policer_list, -+ list) { -+ if (idx < start) { -+ idx++; -+ continue; -+ } -+ err = devlink_nl_trap_policer_fill(msg, devlink, -+ policer_item, cmd, -+ portid, -+ cb->nlh->nlmsg_seq, -+ NLM_F_MULTI); -+ if (err) { -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ goto out; -+ } -+ idx++; -+ } -+ devl_unlock(devlink); -+ devlink_put(devlink); -+ } -+out: -+ cb->args[0] = idx; -+ return msg->len; -+} -+ -+static int -+devlink_trap_policer_set(struct devlink *devlink, -+ struct devlink_trap_policer_item *policer_item, -+ struct genl_info *info) -+{ -+ struct netlink_ext_ack *extack = info->extack; -+ struct nlattr **attrs = info->attrs; -+ u64 rate, burst; -+ int err; -+ -+ rate = policer_item->rate; -+ burst = policer_item->burst; -+ -+ if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]) -+ rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]); -+ -+ if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]) -+ burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]); -+ -+ if (rate < policer_item->policer->min_rate) { -+ NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit"); -+ return -EINVAL; -+ } -+ -+ if (rate > policer_item->policer->max_rate) { -+ NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit"); -+ return -EINVAL; -+ } -+ -+ if (burst < policer_item->policer->min_burst) { -+ NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit"); -+ return -EINVAL; -+ } -+ -+ if (burst > policer_item->policer->max_burst) { -+ NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit"); -+ return -EINVAL; -+ } -+ -+ err = devlink->ops->trap_policer_set(devlink, policer_item->policer, -+ rate, burst, info->extack); -+ if (err) -+ return err; -+ -+ policer_item->rate = rate; -+ policer_item->burst = burst; -+ -+ return 0; -+} -+ -+static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ struct devlink_trap_policer_item *policer_item; -+ struct netlink_ext_ack *extack = info->extack; -+ struct devlink *devlink = info->user_ptr[0]; -+ -+ if (list_empty(&devlink->trap_policer_list)) -+ return -EOPNOTSUPP; -+ -+ if (!devlink->ops->trap_policer_set) -+ return -EOPNOTSUPP; -+ -+ policer_item = devlink_trap_policer_item_get_from_info(devlink, info); -+ if (!policer_item) { -+ NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer"); -+ return -ENOENT; -+ } -+ -+ return devlink_trap_policer_set(devlink, policer_item, info); -+} -+ -+static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { -+ [DEVLINK_ATTR_UNSPEC] = { .strict_start_type = -+ DEVLINK_ATTR_TRAP_POLICER_ID }, -+ [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_PORT_TYPE_AUTO, -+ DEVLINK_PORT_TYPE_IB), -+ [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 }, -+ [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 }, -+ [DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_RANGE(NLA_U16, DEVLINK_ESWITCH_MODE_LEGACY, -+ DEVLINK_ESWITCH_MODE_SWITCHDEV), -+ [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, -+ [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, -+ [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 }, -+ [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 }, -+ [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 }, -+ [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] = -+ NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS), -+ [DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_NETNS_FD] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_NETNS_ID] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .type = NLA_U8 }, -+ [DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 }, -+ [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 }, -+ [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED }, -+ [DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT, -+ DEVLINK_RELOAD_ACTION_MAX), -+ [DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK), -+ [DEVLINK_ATTR_PORT_FLAVOUR] = { .type = NLA_U16 }, -+ [DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16 }, -+ [DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_RATE_TYPE] = { .type = NLA_U16 }, -+ [DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64 }, -+ [DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64 }, -+ [DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 }, -+ [DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING }, -+ [DEVLINK_ATTR_SELFTESTS] = { .type = NLA_NESTED }, -+}; -+ -+static const struct genl_small_ops devlink_nl_ops[] = { -+ { -+ .cmd = DEVLINK_CMD_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_get_doit, -+ .dumpit = devlink_nl_cmd_get_dumpit, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_PORT_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_port_get_doit, -+ .dumpit = devlink_nl_cmd_port_get_dumpit, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_PORT_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_port_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_RATE_GET, -+ .doit = devlink_nl_cmd_rate_get_doit, -+ .dumpit = devlink_nl_cmd_rate_get_dumpit, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_RATE, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_RATE_SET, -+ .doit = devlink_nl_cmd_rate_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_RATE, -+ }, -+ { -+ .cmd = DEVLINK_CMD_RATE_NEW, -+ .doit = devlink_nl_cmd_rate_new_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_RATE_DEL, -+ .doit = devlink_nl_cmd_rate_del_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE, -+ }, -+ { -+ .cmd = DEVLINK_CMD_PORT_SPLIT, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_port_split_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_PORT_UNSPLIT, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_port_unsplit_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_PORT_NEW, -+ .doit = devlink_nl_cmd_port_new_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_PORT_DEL, -+ .doit = devlink_nl_cmd_port_del_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_LINECARD_GET, -+ .doit = devlink_nl_cmd_linecard_get_doit, -+ .dumpit = devlink_nl_cmd_linecard_get_dumpit, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_LINECARD_SET, -+ .doit = devlink_nl_cmd_linecard_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD, -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_get_doit, -+ .dumpit = devlink_nl_cmd_sb_get_dumpit, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_POOL_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_pool_get_doit, -+ .dumpit = devlink_nl_cmd_sb_pool_get_dumpit, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_POOL_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_pool_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_PORT_POOL_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_port_pool_get_doit, -+ .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_PORT_POOL_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_port_pool_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, -+ .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_occ_snapshot_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_sb_occ_max_clear_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_ESWITCH_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_eswitch_get_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_ESWITCH_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_eswitch_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_DPIPE_TABLE_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_dpipe_table_get, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_dpipe_entries_get, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_dpipe_headers_get, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_dpipe_table_counters_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_RESOURCE_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_resource_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_RESOURCE_DUMP, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_resource_dump, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_RELOAD, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_reload, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_PARAM_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_param_get_doit, -+ .dumpit = devlink_nl_cmd_param_get_dumpit, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_PARAM_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_param_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_PORT_PARAM_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_port_param_get_doit, -+ .dumpit = devlink_nl_cmd_port_param_get_dumpit, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_PORT_PARAM_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_port_param_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_REGION_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_region_get_doit, -+ .dumpit = devlink_nl_cmd_region_get_dumpit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_REGION_NEW, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_region_new, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_REGION_DEL, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_region_del, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_REGION_READ, -+ .validate = GENL_DONT_VALIDATE_STRICT | -+ GENL_DONT_VALIDATE_DUMP_STRICT, -+ .dumpit = devlink_nl_cmd_region_read_dumpit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_INFO_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_info_get_doit, -+ .dumpit = devlink_nl_cmd_info_get_dumpit, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_health_reporter_get_doit, -+ .dumpit = devlink_nl_cmd_health_reporter_get_dumpit, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_health_reporter_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_health_reporter_recover_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_health_reporter_diagnose_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, -+ .validate = GENL_DONT_VALIDATE_STRICT | -+ GENL_DONT_VALIDATE_DUMP_STRICT, -+ .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_health_reporter_dump_clear_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_health_reporter_test_doit, -+ .flags = GENL_ADMIN_PERM, -+ .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT, -+ }, -+ { -+ .cmd = DEVLINK_CMD_FLASH_UPDATE, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = devlink_nl_cmd_flash_update, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_TRAP_GET, -+ .doit = devlink_nl_cmd_trap_get_doit, -+ .dumpit = devlink_nl_cmd_trap_get_dumpit, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_TRAP_SET, -+ .doit = devlink_nl_cmd_trap_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_TRAP_GROUP_GET, -+ .doit = devlink_nl_cmd_trap_group_get_doit, -+ .dumpit = devlink_nl_cmd_trap_group_get_dumpit, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_TRAP_GROUP_SET, -+ .doit = devlink_nl_cmd_trap_group_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_TRAP_POLICER_GET, -+ .doit = devlink_nl_cmd_trap_policer_get_doit, -+ .dumpit = devlink_nl_cmd_trap_policer_get_dumpit, -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_TRAP_POLICER_SET, -+ .doit = devlink_nl_cmd_trap_policer_set_doit, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = DEVLINK_CMD_SELFTESTS_GET, -+ .doit = devlink_nl_cmd_selftests_get_doit, -+ .dumpit = devlink_nl_cmd_selftests_get_dumpit -+ /* can be retrieved by unprivileged users */ -+ }, -+ { -+ .cmd = DEVLINK_CMD_SELFTESTS_RUN, -+ .doit = devlink_nl_cmd_selftests_run, -+ .flags = GENL_ADMIN_PERM, -+ }, -+}; -+ -+static struct genl_family devlink_nl_family __ro_after_init = { -+ .name = DEVLINK_GENL_NAME, -+ .version = DEVLINK_GENL_VERSION, -+ .maxattr = DEVLINK_ATTR_MAX, -+ .policy = devlink_nl_policy, -+ .netnsok = true, -+ .parallel_ops = true, -+ .pre_doit = devlink_nl_pre_doit, -+ .post_doit = devlink_nl_post_doit, -+ .module = THIS_MODULE, -+ .small_ops = devlink_nl_ops, -+ .n_small_ops = ARRAY_SIZE(devlink_nl_ops), -+ .resv_start_op = DEVLINK_CMD_SELFTESTS_RUN + 1, -+ .mcgrps = devlink_nl_mcgrps, -+ .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), -+}; -+ -+static bool devlink_reload_actions_valid(const struct devlink_ops *ops) -+{ -+ const struct devlink_reload_combination *comb; -+ int i; -+ -+ if (!devlink_reload_supported(ops)) { -+ if (WARN_ON(ops->reload_actions)) -+ return false; -+ return true; -+ } -+ -+ if (WARN_ON(!ops->reload_actions || -+ ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || -+ ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) -+ return false; -+ -+ if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || -+ ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) -+ return false; -+ -+ for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { -+ comb = &devlink_reload_invalid_combinations[i]; -+ if (ops->reload_actions == BIT(comb->action) && -+ ops->reload_limits == BIT(comb->limit)) -+ return false; -+ } -+ return true; -+} -+ -+/** -+ * devlink_set_features - Set devlink supported features -+ * -+ * @devlink: devlink -+ * @features: devlink support features -+ * -+ * This interface allows us to set reload ops separatelly from -+ * the devlink_alloc. -+ */ -+void devlink_set_features(struct devlink *devlink, u64 features) -+{ -+ ASSERT_DEVLINK_NOT_REGISTERED(devlink); -+ -+ WARN_ON(features & DEVLINK_F_RELOAD && -+ !devlink_reload_supported(devlink->ops)); -+ devlink->features = features; -+} -+EXPORT_SYMBOL_GPL(devlink_set_features); -+ -+/** -+ * devlink_alloc_ns - Allocate new devlink instance resources -+ * in specific namespace -+ * -+ * @ops: ops -+ * @priv_size: size of user private data -+ * @net: net namespace -+ * @dev: parent device -+ * -+ * Allocate new devlink instance resources, including devlink index -+ * and name. -+ */ -+struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, -+ size_t priv_size, struct net *net, -+ struct device *dev) -+{ -+ struct devlink *devlink; -+ static u32 last_id; -+ int ret; -+ -+ WARN_ON(!ops || !dev); -+ if (!devlink_reload_actions_valid(ops)) -+ return NULL; -+ -+ devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); -+ if (!devlink) -+ return NULL; -+ -+ ret = xa_alloc_cyclic(&devlinks, &devlink->index, devlink, xa_limit_31b, -+ &last_id, GFP_KERNEL); -+ if (ret < 0) { -+ kfree(devlink); -+ return NULL; -+ } -+ -+ devlink->dev = dev; -+ devlink->ops = ops; -+ xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC); -+ write_pnet(&devlink->_net, net); -+ INIT_LIST_HEAD(&devlink->port_list); -+ INIT_LIST_HEAD(&devlink->rate_list); -+ INIT_LIST_HEAD(&devlink->linecard_list); -+ INIT_LIST_HEAD(&devlink->sb_list); -+ INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); -+ INIT_LIST_HEAD(&devlink->resource_list); -+ INIT_LIST_HEAD(&devlink->param_list); -+ INIT_LIST_HEAD(&devlink->region_list); -+ INIT_LIST_HEAD(&devlink->reporter_list); -+ INIT_LIST_HEAD(&devlink->trap_list); -+ INIT_LIST_HEAD(&devlink->trap_group_list); -+ INIT_LIST_HEAD(&devlink->trap_policer_list); -+ lockdep_register_key(&devlink->lock_key); -+ mutex_init(&devlink->lock); -+ lockdep_set_class(&devlink->lock, &devlink->lock_key); -+ mutex_init(&devlink->reporters_lock); -+ mutex_init(&devlink->linecards_lock); -+ refcount_set(&devlink->refcount, 1); -+ init_completion(&devlink->comp); -+ -+ return devlink; -+} -+EXPORT_SYMBOL_GPL(devlink_alloc_ns); -+ -+static void -+devlink_trap_policer_notify(struct devlink *devlink, -+ const struct devlink_trap_policer_item *policer_item, -+ enum devlink_command cmd); -+static void -+devlink_trap_group_notify(struct devlink *devlink, -+ const struct devlink_trap_group_item *group_item, -+ enum devlink_command cmd); -+static void devlink_trap_notify(struct devlink *devlink, -+ const struct devlink_trap_item *trap_item, -+ enum devlink_command cmd); -+ -+static void devlink_notify_register(struct devlink *devlink) -+{ -+ struct devlink_trap_policer_item *policer_item; -+ struct devlink_trap_group_item *group_item; -+ struct devlink_param_item *param_item; -+ struct devlink_trap_item *trap_item; -+ struct devlink_port *devlink_port; -+ struct devlink_linecard *linecard; -+ struct devlink_rate *rate_node; -+ struct devlink_region *region; -+ -+ devlink_notify(devlink, DEVLINK_CMD_NEW); -+ list_for_each_entry(linecard, &devlink->linecard_list, list) -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ -+ list_for_each_entry(devlink_port, &devlink->port_list, list) -+ devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); -+ -+ list_for_each_entry(policer_item, &devlink->trap_policer_list, list) -+ devlink_trap_policer_notify(devlink, policer_item, -+ DEVLINK_CMD_TRAP_POLICER_NEW); -+ -+ list_for_each_entry(group_item, &devlink->trap_group_list, list) -+ devlink_trap_group_notify(devlink, group_item, -+ DEVLINK_CMD_TRAP_GROUP_NEW); -+ -+ list_for_each_entry(trap_item, &devlink->trap_list, list) -+ devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); -+ -+ list_for_each_entry(rate_node, &devlink->rate_list, list) -+ devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); -+ -+ list_for_each_entry(region, &devlink->region_list, list) -+ devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); -+ -+ list_for_each_entry(param_item, &devlink->param_list, list) -+ devlink_param_notify(devlink, 0, param_item, -+ DEVLINK_CMD_PARAM_NEW); -+} -+ -+static void devlink_notify_unregister(struct devlink *devlink) -+{ -+ struct devlink_trap_policer_item *policer_item; -+ struct devlink_trap_group_item *group_item; -+ struct devlink_param_item *param_item; -+ struct devlink_trap_item *trap_item; -+ struct devlink_port *devlink_port; -+ struct devlink_linecard *linecard; -+ struct devlink_rate *rate_node; -+ struct devlink_region *region; -+ -+ list_for_each_entry_reverse(param_item, &devlink->param_list, list) -+ devlink_param_notify(devlink, 0, param_item, -+ DEVLINK_CMD_PARAM_DEL); -+ -+ list_for_each_entry_reverse(region, &devlink->region_list, list) -+ devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); -+ -+ list_for_each_entry_reverse(rate_node, &devlink->rate_list, list) -+ devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); -+ -+ list_for_each_entry_reverse(trap_item, &devlink->trap_list, list) -+ devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); -+ -+ list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list) -+ devlink_trap_group_notify(devlink, group_item, -+ DEVLINK_CMD_TRAP_GROUP_DEL); -+ list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list, -+ list) -+ devlink_trap_policer_notify(devlink, policer_item, -+ DEVLINK_CMD_TRAP_POLICER_DEL); -+ -+ list_for_each_entry_reverse(devlink_port, &devlink->port_list, list) -+ devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); -+ list_for_each_entry_reverse(linecard, &devlink->linecard_list, list) -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL); -+ devlink_notify(devlink, DEVLINK_CMD_DEL); -+} -+ -+/** -+ * devlink_register - Register devlink instance -+ * -+ * @devlink: devlink -+ */ -+void devlink_register(struct devlink *devlink) -+{ -+ ASSERT_DEVLINK_NOT_REGISTERED(devlink); -+ /* Make sure that we are in .probe() routine */ -+ -+ xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED); -+ devlink_notify_register(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_register); -+ -+/** -+ * devlink_unregister - Unregister devlink instance -+ * -+ * @devlink: devlink -+ */ -+void devlink_unregister(struct devlink *devlink) -+{ -+ ASSERT_DEVLINK_REGISTERED(devlink); -+ /* Make sure that we are in .remove() routine */ -+ -+ xa_set_mark(&devlinks, devlink->index, DEVLINK_UNREGISTERING); -+ devlink_put(devlink); -+ wait_for_completion(&devlink->comp); -+ -+ devlink_notify_unregister(devlink); -+ xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED); -+ xa_clear_mark(&devlinks, devlink->index, DEVLINK_UNREGISTERING); -+} -+EXPORT_SYMBOL_GPL(devlink_unregister); -+ -+/** -+ * devlink_free - Free devlink instance resources -+ * -+ * @devlink: devlink -+ */ -+void devlink_free(struct devlink *devlink) -+{ -+ ASSERT_DEVLINK_NOT_REGISTERED(devlink); -+ -+ mutex_destroy(&devlink->linecards_lock); -+ mutex_destroy(&devlink->reporters_lock); -+ mutex_destroy(&devlink->lock); -+ lockdep_unregister_key(&devlink->lock_key); -+ WARN_ON(!list_empty(&devlink->trap_policer_list)); -+ WARN_ON(!list_empty(&devlink->trap_group_list)); -+ WARN_ON(!list_empty(&devlink->trap_list)); -+ WARN_ON(!list_empty(&devlink->reporter_list)); -+ WARN_ON(!list_empty(&devlink->region_list)); -+ WARN_ON(!list_empty(&devlink->param_list)); -+ WARN_ON(!list_empty(&devlink->resource_list)); -+ WARN_ON(!list_empty(&devlink->dpipe_table_list)); -+ WARN_ON(!list_empty(&devlink->sb_list)); -+ WARN_ON(!list_empty(&devlink->rate_list)); -+ WARN_ON(!list_empty(&devlink->linecard_list)); -+ WARN_ON(!list_empty(&devlink->port_list)); -+ -+ xa_destroy(&devlink->snapshot_ids); -+ xa_erase(&devlinks, devlink->index); -+ -+ kfree(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_free); -+ -+static void devlink_port_type_warn(struct work_struct *work) -+{ -+ struct devlink_port *port = container_of(to_delayed_work(work), -+ struct devlink_port, -+ type_warn_dw); -+ dev_warn(port->devlink->dev, "Type was not set for devlink port."); -+} -+ -+static bool devlink_port_type_should_warn(struct devlink_port *devlink_port) -+{ -+ /* Ignore CPU and DSA flavours. */ -+ return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU && -+ devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA && -+ devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED; -+} -+ -+#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600) -+ -+static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port) -+{ -+ if (!devlink_port_type_should_warn(devlink_port)) -+ return; -+ /* Schedule a work to WARN in case driver does not set port -+ * type within timeout. -+ */ -+ schedule_delayed_work(&devlink_port->type_warn_dw, -+ DEVLINK_PORT_TYPE_WARN_TIMEOUT); -+} -+ -+static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port) -+{ -+ if (!devlink_port_type_should_warn(devlink_port)) -+ return; -+ cancel_delayed_work_sync(&devlink_port->type_warn_dw); -+} -+ -+/** -+ * devlink_port_init() - Init devlink port -+ * -+ * @devlink: devlink -+ * @devlink_port: devlink port -+ * -+ * Initialize essencial stuff that is needed for functions -+ * that may be called before devlink port registration. -+ * Call to this function is optional and not needed -+ * in case the driver does not use such functions. -+ */ -+void devlink_port_init(struct devlink *devlink, -+ struct devlink_port *devlink_port) -+{ -+ if (devlink_port->initialized) -+ return; -+ devlink_port->devlink = devlink; -+ INIT_LIST_HEAD(&devlink_port->region_list); -+ devlink_port->initialized = true; -+} -+EXPORT_SYMBOL_GPL(devlink_port_init); -+ -+/** -+ * devlink_port_fini() - Deinitialize devlink port -+ * -+ * @devlink_port: devlink port -+ * -+ * Deinitialize essencial stuff that is in use for functions -+ * that may be called after devlink port unregistration. -+ * Call to this function is optional and not needed -+ * in case the driver does not use such functions. -+ */ -+void devlink_port_fini(struct devlink_port *devlink_port) -+{ -+ WARN_ON(!list_empty(&devlink_port->region_list)); -+} -+EXPORT_SYMBOL_GPL(devlink_port_fini); -+ -+/** -+ * devl_port_register() - Register devlink port -+ * -+ * @devlink: devlink -+ * @devlink_port: devlink port -+ * @port_index: driver-specific numerical identifier of the port -+ * -+ * Register devlink port with provided port index. User can use -+ * any indexing, even hw-related one. devlink_port structure -+ * is convenient to be embedded inside user driver private structure. -+ * Note that the caller should take care of zeroing the devlink_port -+ * structure. -+ */ -+int devl_port_register(struct devlink *devlink, -+ struct devlink_port *devlink_port, -+ unsigned int port_index) -+{ -+ devl_assert_locked(devlink); -+ -+ if (devlink_port_index_exists(devlink, port_index)) -+ return -EEXIST; -+ -+ ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -+ -+ devlink_port_init(devlink, devlink_port); -+ devlink_port->registered = true; -+ devlink_port->index = port_index; -+ spin_lock_init(&devlink_port->type_lock); -+ INIT_LIST_HEAD(&devlink_port->reporter_list); -+ mutex_init(&devlink_port->reporters_lock); -+ list_add_tail(&devlink_port->list, &devlink->port_list); -+ -+ INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn); -+ devlink_port_type_warn_schedule(devlink_port); -+ devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devl_port_register); -+ -+/** -+ * devlink_port_register - Register devlink port -+ * -+ * @devlink: devlink -+ * @devlink_port: devlink port -+ * @port_index: driver-specific numerical identifier of the port -+ * -+ * Register devlink port with provided port index. User can use -+ * any indexing, even hw-related one. devlink_port structure -+ * is convenient to be embedded inside user driver private structure. -+ * Note that the caller should take care of zeroing the devlink_port -+ * structure. -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+int devlink_port_register(struct devlink *devlink, -+ struct devlink_port *devlink_port, -+ unsigned int port_index) -+{ -+ int err; -+ -+ devl_lock(devlink); -+ err = devl_port_register(devlink, devlink_port, port_index); -+ devl_unlock(devlink); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_port_register); -+ -+/** -+ * devl_port_unregister() - Unregister devlink port -+ * -+ * @devlink_port: devlink port -+ */ -+void devl_port_unregister(struct devlink_port *devlink_port) -+{ -+ lockdep_assert_held(&devlink_port->devlink->lock); -+ -+ devlink_port_type_warn_cancel(devlink_port); -+ devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL); -+ list_del(&devlink_port->list); -+ WARN_ON(!list_empty(&devlink_port->reporter_list)); -+ mutex_destroy(&devlink_port->reporters_lock); -+ devlink_port->registered = false; -+} -+EXPORT_SYMBOL_GPL(devl_port_unregister); -+ -+/** -+ * devlink_port_unregister - Unregister devlink port -+ * -+ * @devlink_port: devlink port -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+void devlink_port_unregister(struct devlink_port *devlink_port) -+{ -+ struct devlink *devlink = devlink_port->devlink; -+ -+ devl_lock(devlink); -+ devl_port_unregister(devlink_port); -+ devl_unlock(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_port_unregister); -+ -+static void __devlink_port_type_set(struct devlink_port *devlink_port, -+ enum devlink_port_type type, -+ void *type_dev) -+{ -+ ASSERT_DEVLINK_PORT_REGISTERED(devlink_port); -+ -+ devlink_port_type_warn_cancel(devlink_port); -+ spin_lock_bh(&devlink_port->type_lock); -+ devlink_port->type = type; -+ devlink_port->type_dev = type_dev; -+ spin_unlock_bh(&devlink_port->type_lock); -+ devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); -+} -+ -+static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port, -+ struct net_device *netdev) -+{ -+ const struct net_device_ops *ops = netdev->netdev_ops; -+ -+ /* If driver registers devlink port, it should set devlink port -+ * attributes accordingly so the compat functions are called -+ * and the original ops are not used. -+ */ -+ if (ops->ndo_get_phys_port_name) { -+ /* Some drivers use the same set of ndos for netdevs -+ * that have devlink_port registered and also for -+ * those who don't. Make sure that ndo_get_phys_port_name -+ * returns -EOPNOTSUPP here in case it is defined. -+ * Warn if not. -+ */ -+ char name[IFNAMSIZ]; -+ int err; -+ -+ err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name)); -+ WARN_ON(err != -EOPNOTSUPP); -+ } -+ if (ops->ndo_get_port_parent_id) { -+ /* Some drivers use the same set of ndos for netdevs -+ * that have devlink_port registered and also for -+ * those who don't. Make sure that ndo_get_port_parent_id -+ * returns -EOPNOTSUPP here in case it is defined. -+ * Warn if not. -+ */ -+ struct netdev_phys_item_id ppid; -+ int err; -+ -+ err = ops->ndo_get_port_parent_id(netdev, &ppid); -+ WARN_ON(err != -EOPNOTSUPP); -+ } -+} -+ -+/** -+ * devlink_port_type_eth_set - Set port type to Ethernet -+ * -+ * @devlink_port: devlink port -+ * @netdev: related netdevice -+ */ -+void devlink_port_type_eth_set(struct devlink_port *devlink_port, -+ struct net_device *netdev) -+{ -+ if (netdev) -+ devlink_port_type_netdev_checks(devlink_port, netdev); -+ else -+ dev_warn(devlink_port->devlink->dev, -+ "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n", -+ devlink_port->index); -+ -+ __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev); -+} -+EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); -+ -+/** -+ * devlink_port_type_ib_set - Set port type to InfiniBand -+ * -+ * @devlink_port: devlink port -+ * @ibdev: related IB device -+ */ -+void devlink_port_type_ib_set(struct devlink_port *devlink_port, -+ struct ib_device *ibdev) -+{ -+ __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev); -+} -+EXPORT_SYMBOL_GPL(devlink_port_type_ib_set); -+ -+/** -+ * devlink_port_type_clear - Clear port type -+ * -+ * @devlink_port: devlink port -+ */ -+void devlink_port_type_clear(struct devlink_port *devlink_port) -+{ -+ __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL); -+ devlink_port_type_warn_schedule(devlink_port); -+} -+EXPORT_SYMBOL_GPL(devlink_port_type_clear); -+ -+static int __devlink_port_attrs_set(struct devlink_port *devlink_port, -+ enum devlink_port_flavour flavour) -+{ -+ struct devlink_port_attrs *attrs = &devlink_port->attrs; -+ -+ devlink_port->attrs_set = true; -+ attrs->flavour = flavour; -+ if (attrs->switch_id.id_len) { -+ devlink_port->switch_port = true; -+ if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN)) -+ attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN; -+ } else { -+ devlink_port->switch_port = false; -+ } -+ return 0; -+} -+ -+/** -+ * devlink_port_attrs_set - Set port attributes -+ * -+ * @devlink_port: devlink port -+ * @attrs: devlink port attrs -+ */ -+void devlink_port_attrs_set(struct devlink_port *devlink_port, -+ struct devlink_port_attrs *attrs) -+{ -+ int ret; -+ -+ ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -+ -+ devlink_port->attrs = *attrs; -+ ret = __devlink_port_attrs_set(devlink_port, attrs->flavour); -+ if (ret) -+ return; -+ WARN_ON(attrs->splittable && attrs->split); -+} -+EXPORT_SYMBOL_GPL(devlink_port_attrs_set); -+ -+/** -+ * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes -+ * -+ * @devlink_port: devlink port -+ * @controller: associated controller number for the devlink port instance -+ * @pf: associated PF for the devlink port instance -+ * @external: indicates if the port is for an external controller -+ */ -+void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller, -+ u16 pf, bool external) -+{ -+ struct devlink_port_attrs *attrs = &devlink_port->attrs; -+ int ret; -+ -+ ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -+ -+ ret = __devlink_port_attrs_set(devlink_port, -+ DEVLINK_PORT_FLAVOUR_PCI_PF); -+ if (ret) -+ return; -+ attrs->pci_pf.controller = controller; -+ attrs->pci_pf.pf = pf; -+ attrs->pci_pf.external = external; -+} -+EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set); -+ -+/** -+ * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes -+ * -+ * @devlink_port: devlink port -+ * @controller: associated controller number for the devlink port instance -+ * @pf: associated PF for the devlink port instance -+ * @vf: associated VF of a PF for the devlink port instance -+ * @external: indicates if the port is for an external controller -+ */ -+void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller, -+ u16 pf, u16 vf, bool external) -+{ -+ struct devlink_port_attrs *attrs = &devlink_port->attrs; -+ int ret; -+ -+ ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -+ -+ ret = __devlink_port_attrs_set(devlink_port, -+ DEVLINK_PORT_FLAVOUR_PCI_VF); -+ if (ret) -+ return; -+ attrs->pci_vf.controller = controller; -+ attrs->pci_vf.pf = pf; -+ attrs->pci_vf.vf = vf; -+ attrs->pci_vf.external = external; -+} -+EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set); -+ -+/** -+ * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes -+ * -+ * @devlink_port: devlink port -+ * @controller: associated controller number for the devlink port instance -+ * @pf: associated PF for the devlink port instance -+ * @sf: associated SF of a PF for the devlink port instance -+ * @external: indicates if the port is for an external controller -+ */ -+void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller, -+ u16 pf, u32 sf, bool external) -+{ -+ struct devlink_port_attrs *attrs = &devlink_port->attrs; -+ int ret; -+ -+ ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -+ -+ ret = __devlink_port_attrs_set(devlink_port, -+ DEVLINK_PORT_FLAVOUR_PCI_SF); -+ if (ret) -+ return; -+ attrs->pci_sf.controller = controller; -+ attrs->pci_sf.pf = pf; -+ attrs->pci_sf.sf = sf; -+ attrs->pci_sf.external = external; -+} -+EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set); -+ -+/** -+ * devl_rate_leaf_create - create devlink rate leaf -+ * @devlink_port: devlink port object to create rate object on -+ * @priv: driver private data -+ * -+ * Create devlink rate object of type leaf on provided @devlink_port. -+ */ -+int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv) -+{ -+ struct devlink *devlink = devlink_port->devlink; -+ struct devlink_rate *devlink_rate; -+ -+ devl_assert_locked(devlink_port->devlink); -+ -+ if (WARN_ON(devlink_port->devlink_rate)) -+ return -EBUSY; -+ -+ devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL); -+ if (!devlink_rate) -+ return -ENOMEM; -+ -+ devlink_rate->type = DEVLINK_RATE_TYPE_LEAF; -+ devlink_rate->devlink = devlink; -+ devlink_rate->devlink_port = devlink_port; -+ devlink_rate->priv = priv; -+ list_add_tail(&devlink_rate->list, &devlink->rate_list); -+ devlink_port->devlink_rate = devlink_rate; -+ devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devl_rate_leaf_create); -+ -+/** -+ * devl_rate_leaf_destroy - destroy devlink rate leaf -+ * -+ * @devlink_port: devlink port linked to the rate object -+ * -+ * Destroy the devlink rate object of type leaf on provided @devlink_port. -+ */ -+void devl_rate_leaf_destroy(struct devlink_port *devlink_port) -+{ -+ struct devlink_rate *devlink_rate = devlink_port->devlink_rate; -+ -+ devl_assert_locked(devlink_port->devlink); -+ if (!devlink_rate) -+ return; -+ -+ devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL); -+ if (devlink_rate->parent) -+ refcount_dec(&devlink_rate->parent->refcnt); -+ list_del(&devlink_rate->list); -+ devlink_port->devlink_rate = NULL; -+ kfree(devlink_rate); -+} -+EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy); -+ -+/** -+ * devl_rate_nodes_destroy - destroy all devlink rate nodes on device -+ * @devlink: devlink instance -+ * -+ * Unset parent for all rate objects and destroy all rate nodes -+ * on specified device. -+ */ -+void devl_rate_nodes_destroy(struct devlink *devlink) -+{ -+ static struct devlink_rate *devlink_rate, *tmp; -+ const struct devlink_ops *ops = devlink->ops; -+ -+ devl_assert_locked(devlink); -+ -+ list_for_each_entry(devlink_rate, &devlink->rate_list, list) { -+ if (!devlink_rate->parent) -+ continue; -+ -+ refcount_dec(&devlink_rate->parent->refcnt); -+ if (devlink_rate_is_leaf(devlink_rate)) -+ ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv, -+ NULL, NULL); -+ else if (devlink_rate_is_node(devlink_rate)) -+ ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv, -+ NULL, NULL); -+ } -+ list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) { -+ if (devlink_rate_is_node(devlink_rate)) { -+ ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL); -+ list_del(&devlink_rate->list); -+ kfree(devlink_rate->name); -+ kfree(devlink_rate); -+ } -+ } -+} -+EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy); -+ -+/** -+ * devlink_port_linecard_set - Link port with a linecard -+ * -+ * @devlink_port: devlink port -+ * @linecard: devlink linecard -+ */ -+void devlink_port_linecard_set(struct devlink_port *devlink_port, -+ struct devlink_linecard *linecard) -+{ -+ ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port); -+ -+ devlink_port->linecard = linecard; -+} -+EXPORT_SYMBOL_GPL(devlink_port_linecard_set); -+ -+static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, -+ char *name, size_t len) -+{ -+ struct devlink_port_attrs *attrs = &devlink_port->attrs; -+ int n = 0; -+ -+ if (!devlink_port->attrs_set) -+ return -EOPNOTSUPP; -+ -+ switch (attrs->flavour) { -+ case DEVLINK_PORT_FLAVOUR_PHYSICAL: -+ if (devlink_port->linecard) -+ n = snprintf(name, len, "l%u", -+ devlink_port->linecard->index); -+ if (n < len) -+ n += snprintf(name + n, len - n, "p%u", -+ attrs->phys.port_number); -+ if (n < len && attrs->split) -+ n += snprintf(name + n, len - n, "s%u", -+ attrs->phys.split_subport_number); -+ break; -+ case DEVLINK_PORT_FLAVOUR_CPU: -+ case DEVLINK_PORT_FLAVOUR_DSA: -+ case DEVLINK_PORT_FLAVOUR_UNUSED: -+ /* As CPU and DSA ports do not have a netdevice associated -+ * case should not ever happen. -+ */ -+ WARN_ON(1); -+ return -EINVAL; -+ case DEVLINK_PORT_FLAVOUR_PCI_PF: -+ if (attrs->pci_pf.external) { -+ n = snprintf(name, len, "c%u", attrs->pci_pf.controller); -+ if (n >= len) -+ return -EINVAL; -+ len -= n; -+ name += n; -+ } -+ n = snprintf(name, len, "pf%u", attrs->pci_pf.pf); -+ break; -+ case DEVLINK_PORT_FLAVOUR_PCI_VF: -+ if (attrs->pci_vf.external) { -+ n = snprintf(name, len, "c%u", attrs->pci_vf.controller); -+ if (n >= len) -+ return -EINVAL; -+ len -= n; -+ name += n; -+ } -+ n = snprintf(name, len, "pf%uvf%u", -+ attrs->pci_vf.pf, attrs->pci_vf.vf); -+ break; -+ case DEVLINK_PORT_FLAVOUR_PCI_SF: -+ if (attrs->pci_sf.external) { -+ n = snprintf(name, len, "c%u", attrs->pci_sf.controller); -+ if (n >= len) -+ return -EINVAL; -+ len -= n; -+ name += n; -+ } -+ n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf, -+ attrs->pci_sf.sf); -+ break; -+ case DEVLINK_PORT_FLAVOUR_VIRTUAL: -+ return -EOPNOTSUPP; -+ } -+ -+ if (n >= len) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int devlink_linecard_types_init(struct devlink_linecard *linecard) -+{ -+ struct devlink_linecard_type *linecard_type; -+ unsigned int count; -+ int i; -+ -+ count = linecard->ops->types_count(linecard, linecard->priv); -+ linecard->types = kmalloc_array(count, sizeof(*linecard_type), -+ GFP_KERNEL); -+ if (!linecard->types) -+ return -ENOMEM; -+ linecard->types_count = count; -+ -+ for (i = 0; i < count; i++) { -+ linecard_type = &linecard->types[i]; -+ linecard->ops->types_get(linecard, linecard->priv, i, -+ &linecard_type->type, -+ &linecard_type->priv); -+ } -+ return 0; -+} -+ -+static void devlink_linecard_types_fini(struct devlink_linecard *linecard) -+{ -+ kfree(linecard->types); -+} -+ -+/** -+ * devlink_linecard_create - Create devlink linecard -+ * -+ * @devlink: devlink -+ * @linecard_index: driver-specific numerical identifier of the linecard -+ * @ops: linecards ops -+ * @priv: user priv pointer -+ * -+ * Create devlink linecard instance with provided linecard index. -+ * Caller can use any indexing, even hw-related one. -+ * -+ * Return: Line card structure or an ERR_PTR() encoded error code. -+ */ -+struct devlink_linecard * -+devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index, -+ const struct devlink_linecard_ops *ops, void *priv) -+{ -+ struct devlink_linecard *linecard; -+ int err; -+ -+ if (WARN_ON(!ops || !ops->provision || !ops->unprovision || -+ !ops->types_count || !ops->types_get)) -+ return ERR_PTR(-EINVAL); -+ -+ mutex_lock(&devlink->linecards_lock); -+ if (devlink_linecard_index_exists(devlink, linecard_index)) { -+ mutex_unlock(&devlink->linecards_lock); -+ return ERR_PTR(-EEXIST); -+ } -+ -+ linecard = kzalloc(sizeof(*linecard), GFP_KERNEL); -+ if (!linecard) { -+ mutex_unlock(&devlink->linecards_lock); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ linecard->devlink = devlink; -+ linecard->index = linecard_index; -+ linecard->ops = ops; -+ linecard->priv = priv; -+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -+ mutex_init(&linecard->state_lock); -+ -+ err = devlink_linecard_types_init(linecard); -+ if (err) { -+ mutex_destroy(&linecard->state_lock); -+ kfree(linecard); -+ mutex_unlock(&devlink->linecards_lock); -+ return ERR_PTR(err); -+ } -+ -+ list_add_tail(&linecard->list, &devlink->linecard_list); -+ refcount_set(&linecard->refcount, 1); -+ mutex_unlock(&devlink->linecards_lock); -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ return linecard; -+} -+EXPORT_SYMBOL_GPL(devlink_linecard_create); -+ -+/** -+ * devlink_linecard_destroy - Destroy devlink linecard -+ * -+ * @linecard: devlink linecard -+ */ -+void devlink_linecard_destroy(struct devlink_linecard *linecard) -+{ -+ struct devlink *devlink = linecard->devlink; -+ -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL); -+ mutex_lock(&devlink->linecards_lock); -+ list_del(&linecard->list); -+ devlink_linecard_types_fini(linecard); -+ mutex_unlock(&devlink->linecards_lock); -+ devlink_linecard_put(linecard); -+} -+EXPORT_SYMBOL_GPL(devlink_linecard_destroy); -+ -+/** -+ * devlink_linecard_provision_set - Set provisioning on linecard -+ * -+ * @linecard: devlink linecard -+ * @type: linecard type -+ * -+ * This is either called directly from the provision() op call or -+ * as a result of the provision() op call asynchronously. -+ */ -+void devlink_linecard_provision_set(struct devlink_linecard *linecard, -+ const char *type) -+{ -+ mutex_lock(&linecard->state_lock); -+ WARN_ON(linecard->type && strcmp(linecard->type, type)); -+ linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED; -+ linecard->type = type; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+} -+EXPORT_SYMBOL_GPL(devlink_linecard_provision_set); -+ -+/** -+ * devlink_linecard_provision_clear - Clear provisioning on linecard -+ * -+ * @linecard: devlink linecard -+ * -+ * This is either called directly from the unprovision() op call or -+ * as a result of the unprovision() op call asynchronously. -+ */ -+void devlink_linecard_provision_clear(struct devlink_linecard *linecard) -+{ -+ mutex_lock(&linecard->state_lock); -+ WARN_ON(linecard->nested_devlink); -+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED; -+ linecard->type = NULL; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+} -+EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear); -+ -+/** -+ * devlink_linecard_provision_fail - Fail provisioning on linecard -+ * -+ * @linecard: devlink linecard -+ * -+ * This is either called directly from the provision() op call or -+ * as a result of the provision() op call asynchronously. -+ */ -+void devlink_linecard_provision_fail(struct devlink_linecard *linecard) -+{ -+ mutex_lock(&linecard->state_lock); -+ WARN_ON(linecard->nested_devlink); -+ linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+} -+EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail); -+ -+/** -+ * devlink_linecard_activate - Set linecard active -+ * -+ * @linecard: devlink linecard -+ */ -+void devlink_linecard_activate(struct devlink_linecard *linecard) -+{ -+ mutex_lock(&linecard->state_lock); -+ WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED); -+ linecard->state = DEVLINK_LINECARD_STATE_ACTIVE; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+} -+EXPORT_SYMBOL_GPL(devlink_linecard_activate); -+ -+/** -+ * devlink_linecard_deactivate - Set linecard inactive -+ * -+ * @linecard: devlink linecard -+ */ -+void devlink_linecard_deactivate(struct devlink_linecard *linecard) -+{ -+ mutex_lock(&linecard->state_lock); -+ switch (linecard->state) { -+ case DEVLINK_LINECARD_STATE_ACTIVE: -+ linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ break; -+ case DEVLINK_LINECARD_STATE_UNPROVISIONING: -+ /* Line card is being deactivated as part -+ * of unprovisioning flow. -+ */ -+ break; -+ default: -+ WARN_ON(1); -+ break; -+ } -+ mutex_unlock(&linecard->state_lock); -+} -+EXPORT_SYMBOL_GPL(devlink_linecard_deactivate); -+ -+/** -+ * devlink_linecard_nested_dl_set - Attach/detach nested devlink -+ * instance to linecard. -+ * -+ * @linecard: devlink linecard -+ * @nested_devlink: devlink instance to attach or NULL to detach -+ */ -+void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard, -+ struct devlink *nested_devlink) -+{ -+ mutex_lock(&linecard->state_lock); -+ linecard->nested_devlink = nested_devlink; -+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW); -+ mutex_unlock(&linecard->state_lock); -+} -+EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set); -+ -+int devl_sb_register(struct devlink *devlink, unsigned int sb_index, -+ u32 size, u16 ingress_pools_count, -+ u16 egress_pools_count, u16 ingress_tc_count, -+ u16 egress_tc_count) -+{ -+ struct devlink_sb *devlink_sb; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ if (devlink_sb_index_exists(devlink, sb_index)) -+ return -EEXIST; -+ -+ devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); -+ if (!devlink_sb) -+ return -ENOMEM; -+ devlink_sb->index = sb_index; -+ devlink_sb->size = size; -+ devlink_sb->ingress_pools_count = ingress_pools_count; -+ devlink_sb->egress_pools_count = egress_pools_count; -+ devlink_sb->ingress_tc_count = ingress_tc_count; -+ devlink_sb->egress_tc_count = egress_tc_count; -+ list_add_tail(&devlink_sb->list, &devlink->sb_list); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devl_sb_register); -+ -+int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, -+ u32 size, u16 ingress_pools_count, -+ u16 egress_pools_count, u16 ingress_tc_count, -+ u16 egress_tc_count) -+{ -+ int err; -+ -+ devl_lock(devlink); -+ err = devl_sb_register(devlink, sb_index, size, ingress_pools_count, -+ egress_pools_count, ingress_tc_count, -+ egress_tc_count); -+ devl_unlock(devlink); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_sb_register); -+ -+void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index) -+{ -+ struct devlink_sb *devlink_sb; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ devlink_sb = devlink_sb_get_by_index(devlink, sb_index); -+ WARN_ON(!devlink_sb); -+ list_del(&devlink_sb->list); -+ kfree(devlink_sb); -+} -+EXPORT_SYMBOL_GPL(devl_sb_unregister); -+ -+void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index) -+{ -+ devl_lock(devlink); -+ devl_sb_unregister(devlink, sb_index); -+ devl_unlock(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_sb_unregister); -+ -+/** -+ * devl_dpipe_headers_register - register dpipe headers -+ * -+ * @devlink: devlink -+ * @dpipe_headers: dpipe header array -+ * -+ * Register the headers supported by hardware. -+ */ -+void devl_dpipe_headers_register(struct devlink *devlink, -+ struct devlink_dpipe_headers *dpipe_headers) -+{ -+ lockdep_assert_held(&devlink->lock); -+ -+ devlink->dpipe_headers = dpipe_headers; -+} -+EXPORT_SYMBOL_GPL(devl_dpipe_headers_register); -+ -+/** -+ * devl_dpipe_headers_unregister - unregister dpipe headers -+ * -+ * @devlink: devlink -+ * -+ * Unregister the headers supported by hardware. -+ */ -+void devl_dpipe_headers_unregister(struct devlink *devlink) -+{ -+ lockdep_assert_held(&devlink->lock); -+ -+ devlink->dpipe_headers = NULL; -+} -+EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister); -+ -+/** -+ * devlink_dpipe_table_counter_enabled - check if counter allocation -+ * required -+ * @devlink: devlink -+ * @table_name: tables name -+ * -+ * Used by driver to check if counter allocation is required. -+ * After counter allocation is turned on the table entries -+ * are updated to include counter statistics. -+ * -+ * After that point on the driver must respect the counter -+ * state so that each entry added to the table is added -+ * with a counter. -+ */ -+bool devlink_dpipe_table_counter_enabled(struct devlink *devlink, -+ const char *table_name) -+{ -+ struct devlink_dpipe_table *table; -+ bool enabled; -+ -+ rcu_read_lock(); -+ table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -+ table_name, devlink); -+ enabled = false; -+ if (table) -+ enabled = table->counters_enabled; -+ rcu_read_unlock(); -+ return enabled; -+} -+EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled); -+ -+/** -+ * devl_dpipe_table_register - register dpipe table -+ * -+ * @devlink: devlink -+ * @table_name: table name -+ * @table_ops: table ops -+ * @priv: priv -+ * @counter_control_extern: external control for counters -+ */ -+int devl_dpipe_table_register(struct devlink *devlink, -+ const char *table_name, -+ struct devlink_dpipe_table_ops *table_ops, -+ void *priv, bool counter_control_extern) -+{ -+ struct devlink_dpipe_table *table; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ if (WARN_ON(!table_ops->size_get)) -+ return -EINVAL; -+ -+ if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name, -+ devlink)) -+ return -EEXIST; -+ -+ table = kzalloc(sizeof(*table), GFP_KERNEL); -+ if (!table) -+ return -ENOMEM; -+ -+ table->name = table_name; -+ table->table_ops = table_ops; -+ table->priv = priv; -+ table->counter_control_extern = counter_control_extern; -+ -+ list_add_tail_rcu(&table->list, &devlink->dpipe_table_list); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devl_dpipe_table_register); -+ -+/** -+ * devl_dpipe_table_unregister - unregister dpipe table -+ * -+ * @devlink: devlink -+ * @table_name: table name -+ */ -+void devl_dpipe_table_unregister(struct devlink *devlink, -+ const char *table_name) -+{ -+ struct devlink_dpipe_table *table; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -+ table_name, devlink); -+ if (!table) -+ return; -+ list_del_rcu(&table->list); -+ kfree_rcu(table, rcu); -+} -+EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister); -+ -+/** -+ * devl_resource_register - devlink resource register -+ * -+ * @devlink: devlink -+ * @resource_name: resource's name -+ * @resource_size: resource's size -+ * @resource_id: resource's id -+ * @parent_resource_id: resource's parent id -+ * @size_params: size parameters -+ * -+ * Generic resources should reuse the same names across drivers. -+ * Please see the generic resources list at: -+ * Documentation/networking/devlink/devlink-resource.rst -+ */ -+int devl_resource_register(struct devlink *devlink, -+ const char *resource_name, -+ u64 resource_size, -+ u64 resource_id, -+ u64 parent_resource_id, -+ const struct devlink_resource_size_params *size_params) -+{ -+ struct devlink_resource *resource; -+ struct list_head *resource_list; -+ bool top_hierarchy; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP; -+ -+ resource = devlink_resource_find(devlink, NULL, resource_id); -+ if (resource) -+ return -EINVAL; -+ -+ resource = kzalloc(sizeof(*resource), GFP_KERNEL); -+ if (!resource) -+ return -ENOMEM; -+ -+ if (top_hierarchy) { -+ resource_list = &devlink->resource_list; -+ } else { -+ struct devlink_resource *parent_resource; -+ -+ parent_resource = devlink_resource_find(devlink, NULL, -+ parent_resource_id); -+ if (parent_resource) { -+ resource_list = &parent_resource->resource_list; -+ resource->parent = parent_resource; -+ } else { -+ kfree(resource); -+ return -EINVAL; -+ } -+ } -+ -+ resource->name = resource_name; -+ resource->size = resource_size; -+ resource->size_new = resource_size; -+ resource->id = resource_id; -+ resource->size_valid = true; -+ memcpy(&resource->size_params, size_params, -+ sizeof(resource->size_params)); -+ INIT_LIST_HEAD(&resource->resource_list); -+ list_add_tail(&resource->list, resource_list); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devl_resource_register); -+ -+/** -+ * devlink_resource_register - devlink resource register -+ * -+ * @devlink: devlink -+ * @resource_name: resource's name -+ * @resource_size: resource's size -+ * @resource_id: resource's id -+ * @parent_resource_id: resource's parent id -+ * @size_params: size parameters -+ * -+ * Generic resources should reuse the same names across drivers. -+ * Please see the generic resources list at: -+ * Documentation/networking/devlink/devlink-resource.rst -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+int devlink_resource_register(struct devlink *devlink, -+ const char *resource_name, -+ u64 resource_size, -+ u64 resource_id, -+ u64 parent_resource_id, -+ const struct devlink_resource_size_params *size_params) -+{ -+ int err; -+ -+ devl_lock(devlink); -+ err = devl_resource_register(devlink, resource_name, resource_size, -+ resource_id, parent_resource_id, size_params); -+ devl_unlock(devlink); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_resource_register); -+ -+static void devlink_resource_unregister(struct devlink *devlink, -+ struct devlink_resource *resource) -+{ -+ struct devlink_resource *tmp, *child_resource; -+ -+ list_for_each_entry_safe(child_resource, tmp, &resource->resource_list, -+ list) { -+ devlink_resource_unregister(devlink, child_resource); -+ list_del(&child_resource->list); -+ kfree(child_resource); -+ } -+} -+ -+/** -+ * devl_resources_unregister - free all resources -+ * -+ * @devlink: devlink -+ */ -+void devl_resources_unregister(struct devlink *devlink) -+{ -+ struct devlink_resource *tmp, *child_resource; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list, -+ list) { -+ devlink_resource_unregister(devlink, child_resource); -+ list_del(&child_resource->list); -+ kfree(child_resource); -+ } -+} -+EXPORT_SYMBOL_GPL(devl_resources_unregister); -+ -+/** -+ * devlink_resources_unregister - free all resources -+ * -+ * @devlink: devlink -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+void devlink_resources_unregister(struct devlink *devlink) -+{ -+ devl_lock(devlink); -+ devl_resources_unregister(devlink); -+ devl_unlock(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_resources_unregister); -+ -+/** -+ * devl_resource_size_get - get and update size -+ * -+ * @devlink: devlink -+ * @resource_id: the requested resource id -+ * @p_resource_size: ptr to update -+ */ -+int devl_resource_size_get(struct devlink *devlink, -+ u64 resource_id, -+ u64 *p_resource_size) -+{ -+ struct devlink_resource *resource; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ resource = devlink_resource_find(devlink, NULL, resource_id); -+ if (!resource) -+ return -EINVAL; -+ *p_resource_size = resource->size_new; -+ resource->size = resource->size_new; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devl_resource_size_get); -+ -+/** -+ * devl_dpipe_table_resource_set - set the resource id -+ * -+ * @devlink: devlink -+ * @table_name: table name -+ * @resource_id: resource id -+ * @resource_units: number of resource's units consumed per table's entry -+ */ -+int devl_dpipe_table_resource_set(struct devlink *devlink, -+ const char *table_name, u64 resource_id, -+ u64 resource_units) -+{ -+ struct devlink_dpipe_table *table; -+ -+ table = devlink_dpipe_table_find(&devlink->dpipe_table_list, -+ table_name, devlink); -+ if (!table) -+ return -EINVAL; -+ -+ table->resource_id = resource_id; -+ table->resource_units = resource_units; -+ table->resource_valid = true; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set); -+ -+/** -+ * devl_resource_occ_get_register - register occupancy getter -+ * -+ * @devlink: devlink -+ * @resource_id: resource id -+ * @occ_get: occupancy getter callback -+ * @occ_get_priv: occupancy getter callback priv -+ */ -+void devl_resource_occ_get_register(struct devlink *devlink, -+ u64 resource_id, -+ devlink_resource_occ_get_t *occ_get, -+ void *occ_get_priv) -+{ -+ struct devlink_resource *resource; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ resource = devlink_resource_find(devlink, NULL, resource_id); -+ if (WARN_ON(!resource)) -+ return; -+ WARN_ON(resource->occ_get); -+ -+ resource->occ_get = occ_get; -+ resource->occ_get_priv = occ_get_priv; -+} -+EXPORT_SYMBOL_GPL(devl_resource_occ_get_register); -+ -+/** -+ * devlink_resource_occ_get_register - register occupancy getter -+ * -+ * @devlink: devlink -+ * @resource_id: resource id -+ * @occ_get: occupancy getter callback -+ * @occ_get_priv: occupancy getter callback priv -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+void devlink_resource_occ_get_register(struct devlink *devlink, -+ u64 resource_id, -+ devlink_resource_occ_get_t *occ_get, -+ void *occ_get_priv) -+{ -+ devl_lock(devlink); -+ devl_resource_occ_get_register(devlink, resource_id, -+ occ_get, occ_get_priv); -+ devl_unlock(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register); -+ -+/** -+ * devl_resource_occ_get_unregister - unregister occupancy getter -+ * -+ * @devlink: devlink -+ * @resource_id: resource id -+ */ -+void devl_resource_occ_get_unregister(struct devlink *devlink, -+ u64 resource_id) -+{ -+ struct devlink_resource *resource; -+ -+ lockdep_assert_held(&devlink->lock); -+ -+ resource = devlink_resource_find(devlink, NULL, resource_id); -+ if (WARN_ON(!resource)) -+ return; -+ WARN_ON(!resource->occ_get); -+ -+ resource->occ_get = NULL; -+ resource->occ_get_priv = NULL; -+} -+EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister); -+ -+/** -+ * devlink_resource_occ_get_unregister - unregister occupancy getter -+ * -+ * @devlink: devlink -+ * @resource_id: resource id -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+void devlink_resource_occ_get_unregister(struct devlink *devlink, -+ u64 resource_id) -+{ -+ devl_lock(devlink); -+ devl_resource_occ_get_unregister(devlink, resource_id); -+ devl_unlock(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister); -+ -+static int devlink_param_verify(const struct devlink_param *param) -+{ -+ if (!param || !param->name || !param->supported_cmodes) -+ return -EINVAL; -+ if (param->generic) -+ return devlink_param_generic_verify(param); -+ else -+ return devlink_param_driver_verify(param); -+} -+ -+/** -+ * devlink_params_register - register configuration parameters -+ * -+ * @devlink: devlink -+ * @params: configuration parameters array -+ * @params_count: number of parameters provided -+ * -+ * Register the configuration parameters supported by the driver. -+ */ -+int devlink_params_register(struct devlink *devlink, -+ const struct devlink_param *params, -+ size_t params_count) -+{ -+ const struct devlink_param *param = params; -+ int i, err; -+ -+ ASSERT_DEVLINK_NOT_REGISTERED(devlink); -+ -+ for (i = 0; i < params_count; i++, param++) { -+ err = devlink_param_register(devlink, param); -+ if (err) -+ goto rollback; -+ } -+ return 0; -+ -+rollback: -+ if (!i) -+ return err; -+ -+ for (param--; i > 0; i--, param--) -+ devlink_param_unregister(devlink, param); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_params_register); -+ -+/** -+ * devlink_params_unregister - unregister configuration parameters -+ * @devlink: devlink -+ * @params: configuration parameters to unregister -+ * @params_count: number of parameters provided -+ */ -+void devlink_params_unregister(struct devlink *devlink, -+ const struct devlink_param *params, -+ size_t params_count) -+{ -+ const struct devlink_param *param = params; -+ int i; -+ -+ ASSERT_DEVLINK_NOT_REGISTERED(devlink); -+ -+ for (i = 0; i < params_count; i++, param++) -+ devlink_param_unregister(devlink, param); -+} -+EXPORT_SYMBOL_GPL(devlink_params_unregister); -+ -+/** -+ * devlink_param_register - register one configuration parameter -+ * -+ * @devlink: devlink -+ * @param: one configuration parameter -+ * -+ * Register the configuration parameter supported by the driver. -+ * Return: returns 0 on successful registration or error code otherwise. -+ */ -+int devlink_param_register(struct devlink *devlink, -+ const struct devlink_param *param) -+{ -+ struct devlink_param_item *param_item; -+ -+ ASSERT_DEVLINK_NOT_REGISTERED(devlink); -+ -+ WARN_ON(devlink_param_verify(param)); -+ WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name)); -+ -+ if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT)) -+ WARN_ON(param->get || param->set); -+ else -+ WARN_ON(!param->get || !param->set); -+ -+ param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); -+ if (!param_item) -+ return -ENOMEM; -+ -+ param_item->param = param; -+ -+ list_add_tail(¶m_item->list, &devlink->param_list); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_param_register); -+ -+/** -+ * devlink_param_unregister - unregister one configuration parameter -+ * @devlink: devlink -+ * @param: configuration parameter to unregister -+ */ -+void devlink_param_unregister(struct devlink *devlink, -+ const struct devlink_param *param) -+{ -+ struct devlink_param_item *param_item; -+ -+ ASSERT_DEVLINK_NOT_REGISTERED(devlink); -+ -+ param_item = -+ devlink_param_find_by_name(&devlink->param_list, param->name); -+ WARN_ON(!param_item); -+ list_del(¶m_item->list); -+ kfree(param_item); -+} -+EXPORT_SYMBOL_GPL(devlink_param_unregister); -+ -+/** -+ * devlink_param_driverinit_value_get - get configuration parameter -+ * value for driver initializing -+ * -+ * @devlink: devlink -+ * @param_id: parameter ID -+ * @init_val: value of parameter in driverinit configuration mode -+ * -+ * This function should be used by the driver to get driverinit -+ * configuration for initialization after reload command. -+ */ -+int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, -+ union devlink_param_value *init_val) -+{ -+ struct devlink_param_item *param_item; -+ -+ if (!devlink_reload_supported(devlink->ops)) -+ return -EOPNOTSUPP; -+ -+ param_item = devlink_param_find_by_id(&devlink->param_list, param_id); -+ if (!param_item) -+ return -EINVAL; -+ -+ if (!param_item->driverinit_value_valid || -+ !devlink_param_cmode_is_supported(param_item->param, -+ DEVLINK_PARAM_CMODE_DRIVERINIT)) -+ return -EOPNOTSUPP; -+ -+ if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) -+ strcpy(init_val->vstr, param_item->driverinit_value.vstr); -+ else -+ *init_val = param_item->driverinit_value; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get); -+ -+/** -+ * devlink_param_driverinit_value_set - set value of configuration -+ * parameter for driverinit -+ * configuration mode -+ * -+ * @devlink: devlink -+ * @param_id: parameter ID -+ * @init_val: value of parameter to set for driverinit configuration mode -+ * -+ * This function should be used by the driver to set driverinit -+ * configuration mode default value. -+ */ -+int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, -+ union devlink_param_value init_val) -+{ -+ struct devlink_param_item *param_item; -+ -+ ASSERT_DEVLINK_NOT_REGISTERED(devlink); -+ -+ param_item = devlink_param_find_by_id(&devlink->param_list, param_id); -+ if (!param_item) -+ return -EINVAL; -+ -+ if (!devlink_param_cmode_is_supported(param_item->param, -+ DEVLINK_PARAM_CMODE_DRIVERINIT)) -+ return -EOPNOTSUPP; -+ -+ if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) -+ strcpy(param_item->driverinit_value.vstr, init_val.vstr); -+ else -+ param_item->driverinit_value = init_val; -+ param_item->driverinit_value_valid = true; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set); -+ -+/** -+ * devlink_param_value_changed - notify devlink on a parameter's value -+ * change. Should be called by the driver -+ * right after the change. -+ * -+ * @devlink: devlink -+ * @param_id: parameter ID -+ * -+ * This function should be used by the driver to notify devlink on value -+ * change, excluding driverinit configuration mode. -+ * For driverinit configuration mode driver should use the function -+ */ -+void devlink_param_value_changed(struct devlink *devlink, u32 param_id) -+{ -+ struct devlink_param_item *param_item; -+ -+ param_item = devlink_param_find_by_id(&devlink->param_list, param_id); -+ WARN_ON(!param_item); -+ -+ devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW); -+} -+EXPORT_SYMBOL_GPL(devlink_param_value_changed); -+ -+/** -+ * devl_region_create - create a new address region -+ * -+ * @devlink: devlink -+ * @ops: region operations and name -+ * @region_max_snapshots: Maximum supported number of snapshots for region -+ * @region_size: size of region -+ */ -+struct devlink_region *devl_region_create(struct devlink *devlink, -+ const struct devlink_region_ops *ops, -+ u32 region_max_snapshots, -+ u64 region_size) -+{ -+ struct devlink_region *region; -+ -+ devl_assert_locked(devlink); -+ -+ if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) -+ return ERR_PTR(-EINVAL); -+ -+ if (devlink_region_get_by_name(devlink, ops->name)) -+ return ERR_PTR(-EEXIST); -+ -+ region = kzalloc(sizeof(*region), GFP_KERNEL); -+ if (!region) -+ return ERR_PTR(-ENOMEM); -+ -+ region->devlink = devlink; -+ region->max_snapshots = region_max_snapshots; -+ region->ops = ops; -+ region->size = region_size; -+ INIT_LIST_HEAD(®ion->snapshot_list); -+ mutex_init(®ion->snapshot_lock); -+ list_add_tail(®ion->list, &devlink->region_list); -+ devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); -+ -+ return region; -+} -+EXPORT_SYMBOL_GPL(devl_region_create); -+ -+/** -+ * devlink_region_create - create a new address region -+ * -+ * @devlink: devlink -+ * @ops: region operations and name -+ * @region_max_snapshots: Maximum supported number of snapshots for region -+ * @region_size: size of region -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+struct devlink_region * -+devlink_region_create(struct devlink *devlink, -+ const struct devlink_region_ops *ops, -+ u32 region_max_snapshots, u64 region_size) -+{ -+ struct devlink_region *region; -+ -+ devl_lock(devlink); -+ region = devl_region_create(devlink, ops, region_max_snapshots, -+ region_size); -+ devl_unlock(devlink); -+ return region; -+} -+EXPORT_SYMBOL_GPL(devlink_region_create); -+ -+/** -+ * devlink_port_region_create - create a new address region for a port -+ * -+ * @port: devlink port -+ * @ops: region operations and name -+ * @region_max_snapshots: Maximum supported number of snapshots for region -+ * @region_size: size of region -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+struct devlink_region * -+devlink_port_region_create(struct devlink_port *port, -+ const struct devlink_port_region_ops *ops, -+ u32 region_max_snapshots, u64 region_size) -+{ -+ struct devlink *devlink = port->devlink; -+ struct devlink_region *region; -+ int err = 0; -+ -+ ASSERT_DEVLINK_PORT_INITIALIZED(port); -+ -+ if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) -+ return ERR_PTR(-EINVAL); -+ -+ devl_lock(devlink); -+ -+ if (devlink_port_region_get_by_name(port, ops->name)) { -+ err = -EEXIST; -+ goto unlock; -+ } -+ -+ region = kzalloc(sizeof(*region), GFP_KERNEL); -+ if (!region) { -+ err = -ENOMEM; -+ goto unlock; -+ } -+ -+ region->devlink = devlink; -+ region->port = port; -+ region->max_snapshots = region_max_snapshots; -+ region->port_ops = ops; -+ region->size = region_size; -+ INIT_LIST_HEAD(®ion->snapshot_list); -+ mutex_init(®ion->snapshot_lock); -+ list_add_tail(®ion->list, &port->region_list); -+ devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); -+ -+ devl_unlock(devlink); -+ return region; -+ -+unlock: -+ devl_unlock(devlink); -+ return ERR_PTR(err); -+} -+EXPORT_SYMBOL_GPL(devlink_port_region_create); -+ -+/** -+ * devl_region_destroy - destroy address region -+ * -+ * @region: devlink region to destroy -+ */ -+void devl_region_destroy(struct devlink_region *region) -+{ -+ struct devlink *devlink = region->devlink; -+ struct devlink_snapshot *snapshot, *ts; -+ -+ devl_assert_locked(devlink); -+ -+ /* Free all snapshots of region */ -+ mutex_lock(®ion->snapshot_lock); -+ list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list) -+ devlink_region_snapshot_del(region, snapshot); -+ mutex_unlock(®ion->snapshot_lock); -+ -+ list_del(®ion->list); -+ mutex_destroy(®ion->snapshot_lock); -+ -+ devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); -+ kfree(region); -+} -+EXPORT_SYMBOL_GPL(devl_region_destroy); -+ -+/** -+ * devlink_region_destroy - destroy address region -+ * -+ * @region: devlink region to destroy -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+void devlink_region_destroy(struct devlink_region *region) -+{ -+ struct devlink *devlink = region->devlink; -+ -+ devl_lock(devlink); -+ devl_region_destroy(region); -+ devl_unlock(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_region_destroy); -+ -+/** -+ * devlink_region_snapshot_id_get - get snapshot ID -+ * -+ * This callback should be called when adding a new snapshot, -+ * Driver should use the same id for multiple snapshots taken -+ * on multiple regions at the same time/by the same trigger. -+ * -+ * The caller of this function must use devlink_region_snapshot_id_put -+ * when finished creating regions using this id. -+ * -+ * Returns zero on success, or a negative error code on failure. -+ * -+ * @devlink: devlink -+ * @id: storage to return id -+ */ -+int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) -+{ -+ return __devlink_region_snapshot_id_get(devlink, id); -+} -+EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); -+ -+/** -+ * devlink_region_snapshot_id_put - put snapshot ID reference -+ * -+ * This should be called by a driver after finishing creating snapshots -+ * with an id. Doing so ensures that the ID can later be released in the -+ * event that all snapshots using it have been destroyed. -+ * -+ * @devlink: devlink -+ * @id: id to release reference on -+ */ -+void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) -+{ -+ __devlink_snapshot_id_decrement(devlink, id); -+} -+EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); -+ -+/** -+ * devlink_region_snapshot_create - create a new snapshot -+ * This will add a new snapshot of a region. The snapshot -+ * will be stored on the region struct and can be accessed -+ * from devlink. This is useful for future analyses of snapshots. -+ * Multiple snapshots can be created on a region. -+ * The @snapshot_id should be obtained using the getter function. -+ * -+ * @region: devlink region of the snapshot -+ * @data: snapshot data -+ * @snapshot_id: snapshot id to be created -+ */ -+int devlink_region_snapshot_create(struct devlink_region *region, -+ u8 *data, u32 snapshot_id) -+{ -+ int err; -+ -+ mutex_lock(®ion->snapshot_lock); -+ err = __devlink_region_snapshot_create(region, data, snapshot_id); -+ mutex_unlock(®ion->snapshot_lock); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); -+ -+#define DEVLINK_TRAP(_id, _type) \ -+ { \ -+ .type = DEVLINK_TRAP_TYPE_##_type, \ -+ .id = DEVLINK_TRAP_GENERIC_ID_##_id, \ -+ .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \ -+ } -+ -+static const struct devlink_trap devlink_trap_generic[] = { -+ DEVLINK_TRAP(SMAC_MC, DROP), -+ DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP), -+ DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP), -+ DEVLINK_TRAP(INGRESS_STP_FILTER, DROP), -+ DEVLINK_TRAP(EMPTY_TX_LIST, DROP), -+ DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP), -+ DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP), -+ DEVLINK_TRAP(TTL_ERROR, EXCEPTION), -+ DEVLINK_TRAP(TAIL_DROP, DROP), -+ DEVLINK_TRAP(NON_IP_PACKET, DROP), -+ DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP), -+ DEVLINK_TRAP(DIP_LB, DROP), -+ DEVLINK_TRAP(SIP_MC, DROP), -+ DEVLINK_TRAP(SIP_LB, DROP), -+ DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP), -+ DEVLINK_TRAP(IPV4_SIP_BC, DROP), -+ DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP), -+ DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP), -+ DEVLINK_TRAP(MTU_ERROR, EXCEPTION), -+ DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION), -+ DEVLINK_TRAP(RPF, EXCEPTION), -+ DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION), -+ DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION), -+ DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION), -+ DEVLINK_TRAP(NON_ROUTABLE, DROP), -+ DEVLINK_TRAP(DECAP_ERROR, EXCEPTION), -+ DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP), -+ DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP), -+ DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP), -+ DEVLINK_TRAP(STP, CONTROL), -+ DEVLINK_TRAP(LACP, CONTROL), -+ DEVLINK_TRAP(LLDP, CONTROL), -+ DEVLINK_TRAP(IGMP_QUERY, CONTROL), -+ DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL), -+ DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL), -+ DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL), -+ DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL), -+ DEVLINK_TRAP(MLD_QUERY, CONTROL), -+ DEVLINK_TRAP(MLD_V1_REPORT, CONTROL), -+ DEVLINK_TRAP(MLD_V2_REPORT, CONTROL), -+ DEVLINK_TRAP(MLD_V1_DONE, CONTROL), -+ DEVLINK_TRAP(IPV4_DHCP, CONTROL), -+ DEVLINK_TRAP(IPV6_DHCP, CONTROL), -+ DEVLINK_TRAP(ARP_REQUEST, CONTROL), -+ DEVLINK_TRAP(ARP_RESPONSE, CONTROL), -+ DEVLINK_TRAP(ARP_OVERLAY, CONTROL), -+ DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL), -+ DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL), -+ DEVLINK_TRAP(IPV4_BFD, CONTROL), -+ DEVLINK_TRAP(IPV6_BFD, CONTROL), -+ DEVLINK_TRAP(IPV4_OSPF, CONTROL), -+ DEVLINK_TRAP(IPV6_OSPF, CONTROL), -+ DEVLINK_TRAP(IPV4_BGP, CONTROL), -+ DEVLINK_TRAP(IPV6_BGP, CONTROL), -+ DEVLINK_TRAP(IPV4_VRRP, CONTROL), -+ DEVLINK_TRAP(IPV6_VRRP, CONTROL), -+ DEVLINK_TRAP(IPV4_PIM, CONTROL), -+ DEVLINK_TRAP(IPV6_PIM, CONTROL), -+ DEVLINK_TRAP(UC_LB, CONTROL), -+ DEVLINK_TRAP(LOCAL_ROUTE, CONTROL), -+ DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL), -+ DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL), -+ DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL), -+ DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL), -+ DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL), -+ DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL), -+ DEVLINK_TRAP(IPV6_REDIRECT, CONTROL), -+ DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL), -+ DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL), -+ DEVLINK_TRAP(PTP_EVENT, CONTROL), -+ DEVLINK_TRAP(PTP_GENERAL, CONTROL), -+ DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL), -+ DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL), -+ DEVLINK_TRAP(EARLY_DROP, DROP), -+ DEVLINK_TRAP(VXLAN_PARSING, DROP), -+ DEVLINK_TRAP(LLC_SNAP_PARSING, DROP), -+ DEVLINK_TRAP(VLAN_PARSING, DROP), -+ DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP), -+ DEVLINK_TRAP(MPLS_PARSING, DROP), -+ DEVLINK_TRAP(ARP_PARSING, DROP), -+ DEVLINK_TRAP(IP_1_PARSING, DROP), -+ DEVLINK_TRAP(IP_N_PARSING, DROP), -+ DEVLINK_TRAP(GRE_PARSING, DROP), -+ DEVLINK_TRAP(UDP_PARSING, DROP), -+ DEVLINK_TRAP(TCP_PARSING, DROP), -+ DEVLINK_TRAP(IPSEC_PARSING, DROP), -+ DEVLINK_TRAP(SCTP_PARSING, DROP), -+ DEVLINK_TRAP(DCCP_PARSING, DROP), -+ DEVLINK_TRAP(GTP_PARSING, DROP), -+ DEVLINK_TRAP(ESP_PARSING, DROP), -+ DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP), -+ DEVLINK_TRAP(DMAC_FILTER, DROP), -+}; -+ -+#define DEVLINK_TRAP_GROUP(_id) \ -+ { \ -+ .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \ -+ .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \ -+ } -+ -+static const struct devlink_trap_group devlink_trap_group_generic[] = { -+ DEVLINK_TRAP_GROUP(L2_DROPS), -+ DEVLINK_TRAP_GROUP(L3_DROPS), -+ DEVLINK_TRAP_GROUP(L3_EXCEPTIONS), -+ DEVLINK_TRAP_GROUP(BUFFER_DROPS), -+ DEVLINK_TRAP_GROUP(TUNNEL_DROPS), -+ DEVLINK_TRAP_GROUP(ACL_DROPS), -+ DEVLINK_TRAP_GROUP(STP), -+ DEVLINK_TRAP_GROUP(LACP), -+ DEVLINK_TRAP_GROUP(LLDP), -+ DEVLINK_TRAP_GROUP(MC_SNOOPING), -+ DEVLINK_TRAP_GROUP(DHCP), -+ DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY), -+ DEVLINK_TRAP_GROUP(BFD), -+ DEVLINK_TRAP_GROUP(OSPF), -+ DEVLINK_TRAP_GROUP(BGP), -+ DEVLINK_TRAP_GROUP(VRRP), -+ DEVLINK_TRAP_GROUP(PIM), -+ DEVLINK_TRAP_GROUP(UC_LB), -+ DEVLINK_TRAP_GROUP(LOCAL_DELIVERY), -+ DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY), -+ DEVLINK_TRAP_GROUP(IPV6), -+ DEVLINK_TRAP_GROUP(PTP_EVENT), -+ DEVLINK_TRAP_GROUP(PTP_GENERAL), -+ DEVLINK_TRAP_GROUP(ACL_SAMPLE), -+ DEVLINK_TRAP_GROUP(ACL_TRAP), -+ DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS), -+}; -+ -+static int devlink_trap_generic_verify(const struct devlink_trap *trap) -+{ -+ if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX) -+ return -EINVAL; -+ -+ if (strcmp(trap->name, devlink_trap_generic[trap->id].name)) -+ return -EINVAL; -+ -+ if (trap->type != devlink_trap_generic[trap->id].type) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int devlink_trap_driver_verify(const struct devlink_trap *trap) -+{ -+ int i; -+ -+ if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX) -+ return -EINVAL; -+ -+ for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) { -+ if (!strcmp(trap->name, devlink_trap_generic[i].name)) -+ return -EEXIST; -+ } -+ -+ return 0; -+} -+ -+static int devlink_trap_verify(const struct devlink_trap *trap) -+{ -+ if (!trap || !trap->name) -+ return -EINVAL; -+ -+ if (trap->generic) -+ return devlink_trap_generic_verify(trap); -+ else -+ return devlink_trap_driver_verify(trap); -+} -+ -+static int -+devlink_trap_group_generic_verify(const struct devlink_trap_group *group) -+{ -+ if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) -+ return -EINVAL; -+ -+ if (strcmp(group->name, devlink_trap_group_generic[group->id].name)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int -+devlink_trap_group_driver_verify(const struct devlink_trap_group *group) -+{ -+ int i; -+ -+ if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX) -+ return -EINVAL; -+ -+ for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) { -+ if (!strcmp(group->name, devlink_trap_group_generic[i].name)) -+ return -EEXIST; -+ } -+ -+ return 0; -+} -+ -+static int devlink_trap_group_verify(const struct devlink_trap_group *group) -+{ -+ if (group->generic) -+ return devlink_trap_group_generic_verify(group); -+ else -+ return devlink_trap_group_driver_verify(group); -+} -+ -+static void -+devlink_trap_group_notify(struct devlink *devlink, -+ const struct devlink_trap_group_item *group_item, -+ enum devlink_command cmd) -+{ -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW && -+ cmd != DEVLINK_CMD_TRAP_GROUP_DEL); -+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -+ return; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0, -+ 0); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -+ msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+static int -+devlink_trap_item_group_link(struct devlink *devlink, -+ struct devlink_trap_item *trap_item) -+{ -+ u16 group_id = trap_item->trap->init_group_id; -+ struct devlink_trap_group_item *group_item; -+ -+ group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id); -+ if (WARN_ON_ONCE(!group_item)) -+ return -EINVAL; -+ -+ trap_item->group_item = group_item; -+ -+ return 0; -+} -+ -+static void devlink_trap_notify(struct devlink *devlink, -+ const struct devlink_trap_item *trap_item, -+ enum devlink_command cmd) -+{ -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW && -+ cmd != DEVLINK_CMD_TRAP_DEL); -+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -+ return; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -+ msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+static int -+devlink_trap_register(struct devlink *devlink, -+ const struct devlink_trap *trap, void *priv) -+{ -+ struct devlink_trap_item *trap_item; -+ int err; -+ -+ if (devlink_trap_item_lookup(devlink, trap->name)) -+ return -EEXIST; -+ -+ trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL); -+ if (!trap_item) -+ return -ENOMEM; -+ -+ trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); -+ if (!trap_item->stats) { -+ err = -ENOMEM; -+ goto err_stats_alloc; -+ } -+ -+ trap_item->trap = trap; -+ trap_item->action = trap->init_action; -+ trap_item->priv = priv; -+ -+ err = devlink_trap_item_group_link(devlink, trap_item); -+ if (err) -+ goto err_group_link; -+ -+ err = devlink->ops->trap_init(devlink, trap, trap_item); -+ if (err) -+ goto err_trap_init; -+ -+ list_add_tail(&trap_item->list, &devlink->trap_list); -+ devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW); -+ -+ return 0; -+ -+err_trap_init: -+err_group_link: -+ free_percpu(trap_item->stats); -+err_stats_alloc: -+ kfree(trap_item); -+ return err; -+} -+ -+static void devlink_trap_unregister(struct devlink *devlink, -+ const struct devlink_trap *trap) -+{ -+ struct devlink_trap_item *trap_item; -+ -+ trap_item = devlink_trap_item_lookup(devlink, trap->name); -+ if (WARN_ON_ONCE(!trap_item)) -+ return; -+ -+ devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL); -+ list_del(&trap_item->list); -+ if (devlink->ops->trap_fini) -+ devlink->ops->trap_fini(devlink, trap, trap_item); -+ free_percpu(trap_item->stats); -+ kfree(trap_item); -+} -+ -+static void devlink_trap_disable(struct devlink *devlink, -+ const struct devlink_trap *trap) -+{ -+ struct devlink_trap_item *trap_item; -+ -+ trap_item = devlink_trap_item_lookup(devlink, trap->name); -+ if (WARN_ON_ONCE(!trap_item)) -+ return; -+ -+ devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP, -+ NULL); -+ trap_item->action = DEVLINK_TRAP_ACTION_DROP; -+} -+ -+/** -+ * devl_traps_register - Register packet traps with devlink. -+ * @devlink: devlink. -+ * @traps: Packet traps. -+ * @traps_count: Count of provided packet traps. -+ * @priv: Driver private information. -+ * -+ * Return: Non-zero value on failure. -+ */ -+int devl_traps_register(struct devlink *devlink, -+ const struct devlink_trap *traps, -+ size_t traps_count, void *priv) -+{ -+ int i, err; -+ -+ if (!devlink->ops->trap_init || !devlink->ops->trap_action_set) -+ return -EINVAL; -+ -+ devl_assert_locked(devlink); -+ for (i = 0; i < traps_count; i++) { -+ const struct devlink_trap *trap = &traps[i]; -+ -+ err = devlink_trap_verify(trap); -+ if (err) -+ goto err_trap_verify; -+ -+ err = devlink_trap_register(devlink, trap, priv); -+ if (err) -+ goto err_trap_register; -+ } -+ -+ return 0; -+ -+err_trap_register: -+err_trap_verify: -+ for (i--; i >= 0; i--) -+ devlink_trap_unregister(devlink, &traps[i]); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devl_traps_register); -+ -+/** -+ * devlink_traps_register - Register packet traps with devlink. -+ * @devlink: devlink. -+ * @traps: Packet traps. -+ * @traps_count: Count of provided packet traps. -+ * @priv: Driver private information. -+ * -+ * Context: Takes and release devlink->lock . -+ * -+ * Return: Non-zero value on failure. -+ */ -+int devlink_traps_register(struct devlink *devlink, -+ const struct devlink_trap *traps, -+ size_t traps_count, void *priv) -+{ -+ int err; -+ -+ devl_lock(devlink); -+ err = devl_traps_register(devlink, traps, traps_count, priv); -+ devl_unlock(devlink); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_traps_register); -+ -+/** -+ * devl_traps_unregister - Unregister packet traps from devlink. -+ * @devlink: devlink. -+ * @traps: Packet traps. -+ * @traps_count: Count of provided packet traps. -+ */ -+void devl_traps_unregister(struct devlink *devlink, -+ const struct devlink_trap *traps, -+ size_t traps_count) -+{ -+ int i; -+ -+ devl_assert_locked(devlink); -+ /* Make sure we do not have any packets in-flight while unregistering -+ * traps by disabling all of them and waiting for a grace period. -+ */ -+ for (i = traps_count - 1; i >= 0; i--) -+ devlink_trap_disable(devlink, &traps[i]); -+ synchronize_rcu(); -+ for (i = traps_count - 1; i >= 0; i--) -+ devlink_trap_unregister(devlink, &traps[i]); -+} -+EXPORT_SYMBOL_GPL(devl_traps_unregister); -+ -+/** -+ * devlink_traps_unregister - Unregister packet traps from devlink. -+ * @devlink: devlink. -+ * @traps: Packet traps. -+ * @traps_count: Count of provided packet traps. -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+void devlink_traps_unregister(struct devlink *devlink, -+ const struct devlink_trap *traps, -+ size_t traps_count) -+{ -+ devl_lock(devlink); -+ devl_traps_unregister(devlink, traps, traps_count); -+ devl_unlock(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_traps_unregister); -+ -+static void -+devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats, -+ size_t skb_len) -+{ -+ struct devlink_stats *stats; -+ -+ stats = this_cpu_ptr(trap_stats); -+ u64_stats_update_begin(&stats->syncp); -+ u64_stats_add(&stats->rx_bytes, skb_len); -+ u64_stats_inc(&stats->rx_packets); -+ u64_stats_update_end(&stats->syncp); -+} -+ -+static void -+devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata, -+ const struct devlink_trap_item *trap_item, -+ struct devlink_port *in_devlink_port, -+ const struct flow_action_cookie *fa_cookie) -+{ -+ metadata->trap_name = trap_item->trap->name; -+ metadata->trap_group_name = trap_item->group_item->group->name; -+ metadata->fa_cookie = fa_cookie; -+ metadata->trap_type = trap_item->trap->type; -+ -+ spin_lock(&in_devlink_port->type_lock); -+ if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH) -+ metadata->input_dev = in_devlink_port->type_dev; -+ spin_unlock(&in_devlink_port->type_lock); -+} -+ -+/** -+ * devlink_trap_report - Report trapped packet to drop monitor. -+ * @devlink: devlink. -+ * @skb: Trapped packet. -+ * @trap_ctx: Trap context. -+ * @in_devlink_port: Input devlink port. -+ * @fa_cookie: Flow action cookie. Could be NULL. -+ */ -+void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb, -+ void *trap_ctx, struct devlink_port *in_devlink_port, -+ const struct flow_action_cookie *fa_cookie) -+ -+{ -+ struct devlink_trap_item *trap_item = trap_ctx; -+ -+ devlink_trap_stats_update(trap_item->stats, skb->len); -+ devlink_trap_stats_update(trap_item->group_item->stats, skb->len); -+ -+ if (trace_devlink_trap_report_enabled()) { -+ struct devlink_trap_metadata metadata = {}; -+ -+ devlink_trap_report_metadata_set(&metadata, trap_item, -+ in_devlink_port, fa_cookie); -+ trace_devlink_trap_report(devlink, skb, &metadata); -+ } -+} -+EXPORT_SYMBOL_GPL(devlink_trap_report); -+ -+/** -+ * devlink_trap_ctx_priv - Trap context to driver private information. -+ * @trap_ctx: Trap context. -+ * -+ * Return: Driver private information passed during registration. -+ */ -+void *devlink_trap_ctx_priv(void *trap_ctx) -+{ -+ struct devlink_trap_item *trap_item = trap_ctx; -+ -+ return trap_item->priv; -+} -+EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv); -+ -+static int -+devlink_trap_group_item_policer_link(struct devlink *devlink, -+ struct devlink_trap_group_item *group_item) -+{ -+ u32 policer_id = group_item->group->init_policer_id; -+ struct devlink_trap_policer_item *policer_item; -+ -+ if (policer_id == 0) -+ return 0; -+ -+ policer_item = devlink_trap_policer_item_lookup(devlink, policer_id); -+ if (WARN_ON_ONCE(!policer_item)) -+ return -EINVAL; -+ -+ group_item->policer_item = policer_item; -+ -+ return 0; -+} -+ -+static int -+devlink_trap_group_register(struct devlink *devlink, -+ const struct devlink_trap_group *group) -+{ -+ struct devlink_trap_group_item *group_item; -+ int err; -+ -+ if (devlink_trap_group_item_lookup(devlink, group->name)) -+ return -EEXIST; -+ -+ group_item = kzalloc(sizeof(*group_item), GFP_KERNEL); -+ if (!group_item) -+ return -ENOMEM; -+ -+ group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats); -+ if (!group_item->stats) { -+ err = -ENOMEM; -+ goto err_stats_alloc; -+ } -+ -+ group_item->group = group; -+ -+ err = devlink_trap_group_item_policer_link(devlink, group_item); -+ if (err) -+ goto err_policer_link; -+ -+ if (devlink->ops->trap_group_init) { -+ err = devlink->ops->trap_group_init(devlink, group); -+ if (err) -+ goto err_group_init; -+ } -+ -+ list_add_tail(&group_item->list, &devlink->trap_group_list); -+ devlink_trap_group_notify(devlink, group_item, -+ DEVLINK_CMD_TRAP_GROUP_NEW); -+ -+ return 0; -+ -+err_group_init: -+err_policer_link: -+ free_percpu(group_item->stats); -+err_stats_alloc: -+ kfree(group_item); -+ return err; -+} -+ -+static void -+devlink_trap_group_unregister(struct devlink *devlink, -+ const struct devlink_trap_group *group) -+{ -+ struct devlink_trap_group_item *group_item; -+ -+ group_item = devlink_trap_group_item_lookup(devlink, group->name); -+ if (WARN_ON_ONCE(!group_item)) -+ return; -+ -+ devlink_trap_group_notify(devlink, group_item, -+ DEVLINK_CMD_TRAP_GROUP_DEL); -+ list_del(&group_item->list); -+ free_percpu(group_item->stats); -+ kfree(group_item); -+} -+ -+/** -+ * devl_trap_groups_register - Register packet trap groups with devlink. -+ * @devlink: devlink. -+ * @groups: Packet trap groups. -+ * @groups_count: Count of provided packet trap groups. -+ * -+ * Return: Non-zero value on failure. -+ */ -+int devl_trap_groups_register(struct devlink *devlink, -+ const struct devlink_trap_group *groups, -+ size_t groups_count) -+{ -+ int i, err; -+ -+ devl_assert_locked(devlink); -+ for (i = 0; i < groups_count; i++) { -+ const struct devlink_trap_group *group = &groups[i]; -+ -+ err = devlink_trap_group_verify(group); -+ if (err) -+ goto err_trap_group_verify; -+ -+ err = devlink_trap_group_register(devlink, group); -+ if (err) -+ goto err_trap_group_register; -+ } -+ -+ return 0; -+ -+err_trap_group_register: -+err_trap_group_verify: -+ for (i--; i >= 0; i--) -+ devlink_trap_group_unregister(devlink, &groups[i]); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devl_trap_groups_register); -+ -+/** -+ * devlink_trap_groups_register - Register packet trap groups with devlink. -+ * @devlink: devlink. -+ * @groups: Packet trap groups. -+ * @groups_count: Count of provided packet trap groups. -+ * -+ * Context: Takes and release devlink->lock . -+ * -+ * Return: Non-zero value on failure. -+ */ -+int devlink_trap_groups_register(struct devlink *devlink, -+ const struct devlink_trap_group *groups, -+ size_t groups_count) -+{ -+ int err; -+ -+ devl_lock(devlink); -+ err = devl_trap_groups_register(devlink, groups, groups_count); -+ devl_unlock(devlink); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devlink_trap_groups_register); -+ -+/** -+ * devl_trap_groups_unregister - Unregister packet trap groups from devlink. -+ * @devlink: devlink. -+ * @groups: Packet trap groups. -+ * @groups_count: Count of provided packet trap groups. -+ */ -+void devl_trap_groups_unregister(struct devlink *devlink, -+ const struct devlink_trap_group *groups, -+ size_t groups_count) -+{ -+ int i; -+ -+ devl_assert_locked(devlink); -+ for (i = groups_count - 1; i >= 0; i--) -+ devlink_trap_group_unregister(devlink, &groups[i]); -+} -+EXPORT_SYMBOL_GPL(devl_trap_groups_unregister); -+ -+/** -+ * devlink_trap_groups_unregister - Unregister packet trap groups from devlink. -+ * @devlink: devlink. -+ * @groups: Packet trap groups. -+ * @groups_count: Count of provided packet trap groups. -+ * -+ * Context: Takes and release devlink->lock . -+ */ -+void devlink_trap_groups_unregister(struct devlink *devlink, -+ const struct devlink_trap_group *groups, -+ size_t groups_count) -+{ -+ devl_lock(devlink); -+ devl_trap_groups_unregister(devlink, groups, groups_count); -+ devl_unlock(devlink); -+} -+EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister); -+ -+static void -+devlink_trap_policer_notify(struct devlink *devlink, -+ const struct devlink_trap_policer_item *policer_item, -+ enum devlink_command cmd) -+{ -+ struct sk_buff *msg; -+ int err; -+ -+ WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW && -+ cmd != DEVLINK_CMD_TRAP_POLICER_DEL); -+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) -+ return; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0, -+ 0, 0); -+ if (err) { -+ nlmsg_free(msg); -+ return; -+ } -+ -+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), -+ msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); -+} -+ -+static int -+devlink_trap_policer_register(struct devlink *devlink, -+ const struct devlink_trap_policer *policer) -+{ -+ struct devlink_trap_policer_item *policer_item; -+ int err; -+ -+ if (devlink_trap_policer_item_lookup(devlink, policer->id)) -+ return -EEXIST; -+ -+ policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL); -+ if (!policer_item) -+ return -ENOMEM; -+ -+ policer_item->policer = policer; -+ policer_item->rate = policer->init_rate; -+ policer_item->burst = policer->init_burst; -+ -+ if (devlink->ops->trap_policer_init) { -+ err = devlink->ops->trap_policer_init(devlink, policer); -+ if (err) -+ goto err_policer_init; -+ } -+ -+ list_add_tail(&policer_item->list, &devlink->trap_policer_list); -+ devlink_trap_policer_notify(devlink, policer_item, -+ DEVLINK_CMD_TRAP_POLICER_NEW); -+ -+ return 0; -+ -+err_policer_init: -+ kfree(policer_item); -+ return err; -+} -+ -+static void -+devlink_trap_policer_unregister(struct devlink *devlink, -+ const struct devlink_trap_policer *policer) -+{ -+ struct devlink_trap_policer_item *policer_item; -+ -+ policer_item = devlink_trap_policer_item_lookup(devlink, policer->id); -+ if (WARN_ON_ONCE(!policer_item)) -+ return; -+ -+ devlink_trap_policer_notify(devlink, policer_item, -+ DEVLINK_CMD_TRAP_POLICER_DEL); -+ list_del(&policer_item->list); -+ if (devlink->ops->trap_policer_fini) -+ devlink->ops->trap_policer_fini(devlink, policer); -+ kfree(policer_item); -+} -+ -+/** -+ * devl_trap_policers_register - Register packet trap policers with devlink. -+ * @devlink: devlink. -+ * @policers: Packet trap policers. -+ * @policers_count: Count of provided packet trap policers. -+ * -+ * Return: Non-zero value on failure. -+ */ -+int -+devl_trap_policers_register(struct devlink *devlink, -+ const struct devlink_trap_policer *policers, -+ size_t policers_count) -+{ -+ int i, err; -+ -+ devl_assert_locked(devlink); -+ for (i = 0; i < policers_count; i++) { -+ const struct devlink_trap_policer *policer = &policers[i]; -+ -+ if (WARN_ON(policer->id == 0 || -+ policer->max_rate < policer->min_rate || -+ policer->max_burst < policer->min_burst)) { -+ err = -EINVAL; -+ goto err_trap_policer_verify; -+ } -+ -+ err = devlink_trap_policer_register(devlink, policer); -+ if (err) -+ goto err_trap_policer_register; -+ } -+ return 0; -+ -+err_trap_policer_register: -+err_trap_policer_verify: -+ for (i--; i >= 0; i--) -+ devlink_trap_policer_unregister(devlink, &policers[i]); -+ return err; -+} -+EXPORT_SYMBOL_GPL(devl_trap_policers_register); -+ -+/** -+ * devl_trap_policers_unregister - Unregister packet trap policers from devlink. -+ * @devlink: devlink. -+ * @policers: Packet trap policers. -+ * @policers_count: Count of provided packet trap policers. -+ */ -+void -+devl_trap_policers_unregister(struct devlink *devlink, -+ const struct devlink_trap_policer *policers, -+ size_t policers_count) -+{ -+ int i; -+ -+ devl_assert_locked(devlink); -+ for (i = policers_count - 1; i >= 0; i--) -+ devlink_trap_policer_unregister(devlink, &policers[i]); -+} -+EXPORT_SYMBOL_GPL(devl_trap_policers_unregister); -+ -+static void __devlink_compat_running_version(struct devlink *devlink, -+ char *buf, size_t len) -+{ -+ struct devlink_info_req req = {}; -+ const struct nlattr *nlattr; -+ struct sk_buff *msg; -+ int rem, err; -+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -+ -+ req.msg = msg; -+ err = devlink->ops->info_get(devlink, &req, NULL); -+ if (err) -+ goto free_msg; -+ -+ nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) { -+ const struct nlattr *kv; -+ int rem_kv; -+ -+ if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING) -+ continue; -+ -+ nla_for_each_nested(kv, nlattr, rem_kv) { -+ if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE) -+ continue; -+ -+ strlcat(buf, nla_data(kv), len); -+ strlcat(buf, " ", len); -+ } -+ } -+free_msg: -+ nlmsg_free(msg); -+} -+ -+static struct devlink_port *netdev_to_devlink_port(struct net_device *dev) -+{ -+ if (!dev->netdev_ops->ndo_get_devlink_port) -+ return NULL; -+ -+ return dev->netdev_ops->ndo_get_devlink_port(dev); -+} -+ -+void devlink_compat_running_version(struct devlink *devlink, -+ char *buf, size_t len) -+{ -+ if (!devlink->ops->info_get) -+ return; -+ -+ devl_lock(devlink); -+ __devlink_compat_running_version(devlink, buf, len); -+ devl_unlock(devlink); -+} -+ -+int devlink_compat_flash_update(struct devlink *devlink, const char *file_name) -+{ -+ struct devlink_flash_update_params params = {}; -+ int ret; -+ -+ if (!devlink->ops->flash_update) -+ return -EOPNOTSUPP; -+ -+ ret = request_firmware(¶ms.fw, file_name, devlink->dev); -+ if (ret) -+ return ret; -+ -+ devl_lock(devlink); -+ devlink_flash_update_begin_notify(devlink); -+ ret = devlink->ops->flash_update(devlink, ¶ms, NULL); -+ devlink_flash_update_end_notify(devlink); -+ devl_unlock(devlink); -+ -+ release_firmware(params.fw); -+ -+ return ret; -+} -+ -+int devlink_compat_phys_port_name_get(struct net_device *dev, -+ char *name, size_t len) -+{ -+ struct devlink_port *devlink_port; -+ -+ /* RTNL mutex is held here which ensures that devlink_port -+ * instance cannot disappear in the middle. No need to take -+ * any devlink lock as only permanent values are accessed. -+ */ -+ ASSERT_RTNL(); -+ -+ devlink_port = netdev_to_devlink_port(dev); -+ if (!devlink_port) -+ return -EOPNOTSUPP; -+ -+ return __devlink_port_phys_port_name_get(devlink_port, name, len); -+} -+ -+int devlink_compat_switch_id_get(struct net_device *dev, -+ struct netdev_phys_item_id *ppid) -+{ -+ struct devlink_port *devlink_port; -+ -+ /* Caller must hold RTNL mutex or reference to dev, which ensures that -+ * devlink_port instance cannot disappear in the middle. No need to take -+ * any devlink lock as only permanent values are accessed. -+ */ -+ devlink_port = netdev_to_devlink_port(dev); -+ if (!devlink_port || !devlink_port->switch_port) -+ return -EOPNOTSUPP; -+ -+ memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid)); -+ -+ return 0; -+} -+ -+static void __net_exit devlink_pernet_pre_exit(struct net *net) -+{ -+ struct devlink *devlink; -+ u32 actions_performed; -+ unsigned long index; -+ int err; -+ -+ /* In case network namespace is getting destroyed, reload -+ * all devlink instances from this namespace into init_net. -+ */ -+ devlinks_xa_for_each_registered_get(net, index, devlink) { -+ WARN_ON(!(devlink->features & DEVLINK_F_RELOAD)); -+ mutex_lock(&devlink->lock); -+ err = devlink_reload(devlink, &init_net, -+ DEVLINK_RELOAD_ACTION_DRIVER_REINIT, -+ DEVLINK_RELOAD_LIMIT_UNSPEC, -+ &actions_performed, NULL); -+ mutex_unlock(&devlink->lock); -+ if (err && err != -EOPNOTSUPP) -+ pr_warn("Failed to reload devlink instance into init_net\n"); -+ devlink_put(devlink); -+ } -+} -+ -+static struct pernet_operations devlink_pernet_ops __net_initdata = { -+ .pre_exit = devlink_pernet_pre_exit, -+}; -+ -+static int __init devlink_init(void) -+{ -+ int err; -+ -+ err = genl_register_family(&devlink_nl_family); -+ if (err) -+ goto out; -+ err = register_pernet_subsys(&devlink_pernet_ops); -+ -+out: -+ WARN_ON(err); -+ return err; -+} -+ -+subsys_initcall(devlink_init); -diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index ebb737ac9e894..04853c83c85c4 100644 ---- a/net/ipv4/af_inet.c -+++ b/net/ipv4/af_inet.c -@@ -340,7 +340,7 @@ lookup_protocol: - else - inet->pmtudisc = IP_PMTUDISC_WANT; - -- inet->inet_id = 0; -+ atomic_set(&inet->inet_id, 0); - - sock_init_data(sock, sk); - -diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c -index 4d1af0cd7d99e..cb5dbee9e018f 100644 ---- a/net/ipv4/datagram.c -+++ b/net/ipv4/datagram.c -@@ -73,7 +73,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len - reuseport_has_conns_set(sk); - sk->sk_state = TCP_ESTABLISHED; - sk_set_txhash(sk); -- inet->inet_id = get_random_u16(); -+ atomic_set(&inet->inet_id, get_random_u16()); - - sk_dst_set(sk, &rt->dst); - err = 0; -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index 08921b96f9728..f9b8a4a1d2edc 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -312,7 +312,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) - inet->inet_daddr)); - } - -- inet->inet_id = get_random_u16(); -+ atomic_set(&inet->inet_id, get_random_u16()); - - if (tcp_fastopen_defer_connect(sk, &err)) - return err; -@@ -1539,7 +1539,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, - inet_csk(newsk)->icsk_ext_hdr_len = 0; - if (inet_opt) - inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen; -- newinet->inet_id = get_random_u16(); -+ atomic_set(&newinet->inet_id, get_random_u16()); - - /* Set ToS of the new socket based upon the value of incoming SYN. - * ECT bits are set later in tcp_init_transfer(). -diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c -index 0f81492da0b46..55dc0610e8633 100644 ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -1102,7 +1102,8 @@ static inline bool ieee80211_rx_reorder_ready(struct tid_ampdu_rx *tid_agg_rx, - struct sk_buff *tail = skb_peek_tail(frames); - struct ieee80211_rx_status *status; - -- if (tid_agg_rx->reorder_buf_filtered & BIT_ULL(index)) -+ if (tid_agg_rx->reorder_buf_filtered && -+ tid_agg_rx->reorder_buf_filtered & BIT_ULL(index)) - return true; - - if (!tail) -@@ -1143,7 +1144,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, - } - - no_frame: -- tid_agg_rx->reorder_buf_filtered &= ~BIT_ULL(index); -+ if (tid_agg_rx->reorder_buf_filtered) -+ tid_agg_rx->reorder_buf_filtered &= ~BIT_ULL(index); - tid_agg_rx->head_seq_num = ieee80211_sn_inc(tid_agg_rx->head_seq_num); - } - -@@ -4162,6 +4164,7 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid, - u16 ssn, u64 filtered, - u16 received_mpdus) - { -+ struct ieee80211_local *local; - struct sta_info *sta; - struct tid_ampdu_rx *tid_agg_rx; - struct sk_buff_head frames; -@@ -4179,6 +4182,11 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid, - - sta = container_of(pubsta, struct sta_info, sta); - -+ local = sta->sdata->local; -+ WARN_ONCE(local->hw.max_rx_aggregation_subframes > 64, -+ "RX BA marker can't support max_rx_aggregation_subframes %u > 64\n", -+ local->hw.max_rx_aggregation_subframes); -+ - if (!ieee80211_rx_data_set_sta(&rx, sta, -1)) - return; - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 4c2df7af73f76..3c5cac9bd9b70 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -10509,7 +10509,7 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event, - deleted = 0; - mutex_lock(&nft_net->commit_mutex); - if (!list_empty(&nf_tables_destroy_list)) -- rcu_barrier(); -+ nf_tables_trans_destroy_flush_work(); - again: - list_for_each_entry(table, &nft_net->tables, list) { - if (nft_table_has_owner(table) && -diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c -index 32cfd0a84b0e2..8c16681884b7e 100644 ---- a/net/netfilter/nft_set_pipapo.c -+++ b/net/netfilter/nft_set_pipapo.c -@@ -901,12 +901,14 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f) - static int pipapo_insert(struct nft_pipapo_field *f, const uint8_t *k, - int mask_bits) - { -- int rule = f->rules++, group, ret, bit_offset = 0; -+ int rule = f->rules, group, ret, bit_offset = 0; - -- ret = pipapo_resize(f, f->rules - 1, f->rules); -+ ret = pipapo_resize(f, f->rules, f->rules + 1); - if (ret) - return ret; - -+ f->rules++; -+ - for (group = 0; group < f->groups; group++) { - int i, v; - u8 mask; -@@ -1051,7 +1053,9 @@ static int pipapo_expand(struct nft_pipapo_field *f, - step++; - if (step >= len) { - if (!masks) { -- pipapo_insert(f, base, 0); -+ err = pipapo_insert(f, base, 0); -+ if (err < 0) -+ return err; - masks = 1; - } - goto out; -@@ -1234,6 +1238,9 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set, - else - ret = pipapo_expand(f, start, end, f->groups * f->bb); - -+ if (ret < 0) -+ return ret; -+ - if (f->bsize > bsize_max) - bsize_max = f->bsize; - -diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c -index 01d07e6a68119..e8f988e1c7e64 100644 ---- a/net/sched/sch_api.c -+++ b/net/sched/sch_api.c -@@ -1550,10 +1550,28 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, - return 0; - } - -+static bool req_create_or_replace(struct nlmsghdr *n) -+{ -+ return (n->nlmsg_flags & NLM_F_CREATE && -+ n->nlmsg_flags & NLM_F_REPLACE); -+} -+ -+static bool req_create_exclusive(struct nlmsghdr *n) -+{ -+ return (n->nlmsg_flags & NLM_F_CREATE && -+ n->nlmsg_flags & NLM_F_EXCL); -+} -+ -+static bool req_change(struct nlmsghdr *n) -+{ -+ return (!(n->nlmsg_flags & NLM_F_CREATE) && -+ !(n->nlmsg_flags & NLM_F_REPLACE) && -+ !(n->nlmsg_flags & NLM_F_EXCL)); -+} -+ - /* - * Create/change qdisc. - */ -- - static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, - struct netlink_ext_ack *extack) - { -@@ -1647,27 +1665,35 @@ replay: - * - * We know, that some child q is already - * attached to this parent and have choice: -- * either to change it or to create/graft new one. -+ * 1) change it or 2) create/graft new one. -+ * If the requested qdisc kind is different -+ * than the existing one, then we choose graft. -+ * If they are the same then this is "change" -+ * operation - just let it fallthrough.. - * - * 1. We are allowed to create/graft only -- * if CREATE and REPLACE flags are set. -+ * if the request is explicitly stating -+ * "please create if it doesn't exist". - * -- * 2. If EXCL is set, requestor wanted to say, -- * that qdisc tcm_handle is not expected -+ * 2. If the request is to exclusive create -+ * then the qdisc tcm_handle is not expected - * to exist, so that we choose create/graft too. - * - * 3. The last case is when no flags are set. -+ * This will happen when for example tc -+ * utility issues a "change" command. - * Alas, it is sort of hole in API, we - * cannot decide what to do unambiguously. -- * For now we select create/graft, if -- * user gave KIND, which does not match existing. -+ * For now we select create/graft. - */ -- if ((n->nlmsg_flags & NLM_F_CREATE) && -- (n->nlmsg_flags & NLM_F_REPLACE) && -- ((n->nlmsg_flags & NLM_F_EXCL) || -- (tca[TCA_KIND] && -- nla_strcmp(tca[TCA_KIND], q->ops->id)))) -- goto create_n_graft; -+ if (tca[TCA_KIND] && -+ nla_strcmp(tca[TCA_KIND], q->ops->id)) { -+ if (req_create_or_replace(n) || -+ req_create_exclusive(n)) -+ goto create_n_graft; -+ else if (req_change(n)) -+ goto create_n_graft2; -+ } - } - } - } else { -@@ -1701,6 +1727,7 @@ create_n_graft: - NL_SET_ERR_MSG(extack, "Qdisc not found. To create specify NLM_F_CREATE flag"); - return -ENOENT; - } -+create_n_graft2: - if (clid == TC_H_INGRESS) { - if (dev_ingress_queue(dev)) { - q = qdisc_create(dev, dev_ingress_queue(dev), -diff --git a/net/sctp/socket.c b/net/sctp/socket.c -index c806d272107ac..a11b0d903514c 100644 ---- a/net/sctp/socket.c -+++ b/net/sctp/socket.c -@@ -98,7 +98,7 @@ struct percpu_counter sctp_sockets_allocated; - - static void sctp_enter_memory_pressure(struct sock *sk) - { -- sctp_memory_pressure = 1; -+ WRITE_ONCE(sctp_memory_pressure, 1); - } - - -@@ -9472,7 +9472,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, - newinet->inet_rcv_saddr = inet->inet_rcv_saddr; - newinet->inet_dport = htons(asoc->peer.port); - newinet->pmtudisc = inet->pmtudisc; -- newinet->inet_id = get_random_u16(); -+ atomic_set(&newinet->inet_id, get_random_u16()); - - newinet->uc_ttl = inet->uc_ttl; - newinet->mc_loop = 1; -diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c -index b098fde373abf..28c0771c4e8c3 100644 ---- a/net/sunrpc/xprtrdma/verbs.c -+++ b/net/sunrpc/xprtrdma/verbs.c -@@ -935,9 +935,6 @@ struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt, - if (!rep->rr_rdmabuf) - goto out_free; - -- if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf)) -- goto out_free_regbuf; -- - rep->rr_cid.ci_completion_id = - atomic_inc_return(&r_xprt->rx_ep->re_completion_ids); - -@@ -956,8 +953,6 @@ struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt, - spin_unlock(&buf->rb_lock); - return rep; - --out_free_regbuf: -- rpcrdma_regbuf_free(rep->rr_rdmabuf); - out_free: - kfree(rep); - out: -@@ -1363,6 +1358,10 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp) - rep = rpcrdma_rep_create(r_xprt, temp); - if (!rep) - break; -+ if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf)) { -+ rpcrdma_rep_put(buf, rep); -+ break; -+ } - - rep->rr_cid.ci_queue_id = ep->re_attr.recv_cq->res.id; - trace_xprtrdma_post_recv(rep); -diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c -index adcfb63b3550d..6f9ff4643dcbc 100644 ---- a/security/selinux/ss/policydb.c -+++ b/security/selinux/ss/policydb.c -@@ -2005,6 +2005,7 @@ static int filename_trans_read_helper(struct policydb *p, void *fp) - if (!datum) - goto out; - -+ datum->next = NULL; - *dst = datum; - - /* ebitmap_read() will at least init the bitmap */ -@@ -2017,7 +2018,6 @@ static int filename_trans_read_helper(struct policydb *p, void *fp) - goto out; - - datum->otype = le32_to_cpu(buf[0]); -- datum->next = NULL; - - dst = &datum->next; - } -diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c -index 82d4e0fda91be..d62a0e2ddf609 100644 ---- a/sound/pci/ymfpci/ymfpci.c -+++ b/sound/pci/ymfpci/ymfpci.c -@@ -150,8 +150,8 @@ static inline int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, i - void snd_ymfpci_free_gameport(struct snd_ymfpci *chip) { } - #endif /* SUPPORT_JOYSTICK */ - --static int snd_card_ymfpci_probe(struct pci_dev *pci, -- const struct pci_device_id *pci_id) -+static int __snd_card_ymfpci_probe(struct pci_dev *pci, -+ const struct pci_device_id *pci_id) - { - static int dev; - struct snd_card *card; -@@ -333,6 +333,12 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, - return 0; - } - -+static int snd_card_ymfpci_probe(struct pci_dev *pci, -+ const struct pci_device_id *pci_id) -+{ -+ return snd_card_free_on_error(&pci->dev, __snd_card_ymfpci_probe(pci, pci_id)); -+} -+ - static struct pci_driver ymfpci_driver = { - .name = KBUILD_MODNAME, - .id_table = snd_ymfpci_ids, -diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig -index 3968c478c9381..44d4e6e51a358 100644 ---- a/sound/soc/amd/Kconfig -+++ b/sound/soc/amd/Kconfig -@@ -71,6 +71,7 @@ config SND_SOC_AMD_RENOIR_MACH - config SND_SOC_AMD_ACP5x - tristate "AMD Audio Coprocessor-v5.x I2S support" - depends on X86 && PCI -+ select SND_AMD_ACP_CONFIG - help - This option enables ACP v5.x support on AMD platform - -diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c -index c1ca3ceac5f2f..9a9571c3f08c0 100644 ---- a/sound/soc/amd/yc/acp6x-mach.c -+++ b/sound/soc/amd/yc/acp6x-mach.c -@@ -217,7 +217,7 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - .driver_data = &acp6x_card, - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -- DMI_MATCH(DMI_PRODUCT_NAME, "82"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82V2"), - } - }, - { -@@ -248,6 +248,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c -index f2b5032daa6ae..2f4b0ee93aced 100644 ---- a/sound/soc/codecs/cs35l41.c -+++ b/sound/soc/codecs/cs35l41.c -@@ -167,7 +167,7 @@ static int cs35l41_get_fs_mon_config_index(int freq) - static const DECLARE_TLV_DB_RANGE(dig_vol_tlv, - 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), - 1, 913, TLV_DB_MINMAX_ITEM(-10200, 1200)); --static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1); -+static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 50, 100, 0); - - static const struct snd_kcontrol_new dre_ctrl = - SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0); -diff --git a/tools/testing/selftests/drivers/net/bonding/bond-break-lacpdu-tx.sh b/tools/testing/selftests/drivers/net/bonding/bond-break-lacpdu-tx.sh -index 47ab90596acb2..6358df5752f90 100755 ---- a/tools/testing/selftests/drivers/net/bonding/bond-break-lacpdu-tx.sh -+++ b/tools/testing/selftests/drivers/net/bonding/bond-break-lacpdu-tx.sh -@@ -57,8 +57,8 @@ ip link add name veth2-bond type veth peer name veth2-end - - # add ports - ip link set fbond master fab-br0 --ip link set veth1-bond down master fbond --ip link set veth2-bond down master fbond -+ip link set veth1-bond master fbond -+ip link set veth2-bond master fbond - - # bring up - ip link set veth1-end up -diff --git a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh -index 7d9e73a43a49b..0c47faff9274b 100755 ---- a/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh -+++ b/tools/testing/selftests/drivers/net/mlxsw/sharedbuffer.sh -@@ -98,12 +98,12 @@ sb_occ_etc_check() - - port_pool_test() - { -- local exp_max_occ=288 -+ local exp_max_occ=$(devlink_cell_size_get) - local max_occ - - devlink sb occupancy clearmax $DEVLINK_DEV - -- $MZ $h1 -c 1 -p 160 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ -+ $MZ $h1 -c 1 -p 10 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ - -t ip -q - - devlink sb occupancy snapshot $DEVLINK_DEV -@@ -126,12 +126,12 @@ port_pool_test() - - port_tc_ip_test() - { -- local exp_max_occ=288 -+ local exp_max_occ=$(devlink_cell_size_get) - local max_occ - - devlink sb occupancy clearmax $DEVLINK_DEV - -- $MZ $h1 -c 1 -p 160 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ -+ $MZ $h1 -c 1 -p 10 -a $h1mac -b $h2mac -A 192.0.1.1 -B 192.0.1.2 \ - -t ip -q - - devlink sb occupancy snapshot $DEVLINK_DEV -@@ -154,16 +154,12 @@ port_tc_ip_test() - - port_tc_arp_test() - { -- local exp_max_occ=96 -+ local exp_max_occ=$(devlink_cell_size_get) - local max_occ - -- if [[ $MLXSW_CHIP != "mlxsw_spectrum" ]]; then -- exp_max_occ=144 -- fi -- - devlink sb occupancy clearmax $DEVLINK_DEV - -- $MZ $h1 -c 1 -p 160 -a $h1mac -A 192.0.1.1 -t arp -q -+ $MZ $h1 -c 1 -p 10 -a $h1mac -A 192.0.1.1 -t arp -q - - devlink sb occupancy snapshot $DEVLINK_DEV - -diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile -index 69c58362c0edf..48d1a68be1d52 100644 ---- a/tools/testing/selftests/net/Makefile -+++ b/tools/testing/selftests/net/Makefile -@@ -71,14 +71,60 @@ TEST_GEN_FILES += bind_bhash - TEST_GEN_PROGS += sk_bind_sendto_listen - TEST_GEN_PROGS += sk_connect_zero_addr - TEST_PROGS += test_ingress_egress_chaining.sh -+TEST_GEN_FILES += nat6to4.o - - TEST_FILES := settings - - include ../lib.mk - --include bpf/Makefile -- - $(OUTPUT)/reuseport_bpf_numa: LDLIBS += -lnuma - $(OUTPUT)/tcp_mmap: LDLIBS += -lpthread - $(OUTPUT)/tcp_inq: LDLIBS += -lpthread - $(OUTPUT)/bind_bhash: LDLIBS += -lpthread -+ -+# Rules to generate bpf obj nat6to4.o -+CLANG ?= clang -+SCRATCH_DIR := $(OUTPUT)/tools -+BUILD_DIR := $(SCRATCH_DIR)/build -+BPFDIR := $(abspath ../../../lib/bpf) -+APIDIR := $(abspath ../../../include/uapi) -+ -+CCINCLUDE += -I../bpf -+CCINCLUDE += -I../../../../usr/include/ -+CCINCLUDE += -I$(SCRATCH_DIR)/include -+ -+BPFOBJ := $(BUILD_DIR)/libbpf/libbpf.a -+ -+MAKE_DIRS := $(BUILD_DIR)/libbpf -+$(MAKE_DIRS): -+ mkdir -p $@ -+ -+# Get Clang's default includes on this system, as opposed to those seen by -+# '-target bpf'. This fixes "missing" files on some architectures/distros, -+# such as asm/byteorder.h, asm/socket.h, asm/sockios.h, sys/cdefs.h etc. -+# -+# Use '-idirafter': Don't interfere with include mechanics except where the -+# build would have failed anyways. -+define get_sys_includes -+$(shell $(1) $(2) -v -E - &1 \ -+ | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \ -+$(shell $(1) $(2) -dM -E - --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- -- --#include -- --#include --#include -- --#define IP_DF 0x4000 // Flag: "Don't Fragment" -- --SEC("schedcls/ingress6/nat_6") --int sched_cls_ingress6_nat_6_prog(struct __sk_buff *skb) --{ -- const int l2_header_size = sizeof(struct ethhdr); -- void *data = (void *)(long)skb->data; -- const void *data_end = (void *)(long)skb->data_end; -- const struct ethhdr * const eth = data; // used iff is_ethernet -- const struct ipv6hdr * const ip6 = (void *)(eth + 1); -- -- // Require ethernet dst mac address to be our unicast address. -- if (skb->pkt_type != PACKET_HOST) -- return TC_ACT_OK; -- -- // Must be meta-ethernet IPv6 frame -- if (skb->protocol != bpf_htons(ETH_P_IPV6)) -- return TC_ACT_OK; -- -- // Must have (ethernet and) ipv6 header -- if (data + l2_header_size + sizeof(*ip6) > data_end) -- return TC_ACT_OK; -- -- // Ethertype - if present - must be IPv6 -- if (eth->h_proto != bpf_htons(ETH_P_IPV6)) -- return TC_ACT_OK; -- -- // IP version must be 6 -- if (ip6->version != 6) -- return TC_ACT_OK; -- // Maximum IPv6 payload length that can be translated to IPv4 -- if (bpf_ntohs(ip6->payload_len) > 0xFFFF - sizeof(struct iphdr)) -- return TC_ACT_OK; -- switch (ip6->nexthdr) { -- case IPPROTO_TCP: // For TCP & UDP the checksum neutrality of the chosen IPv6 -- case IPPROTO_UDP: // address means there is no need to update their checksums. -- case IPPROTO_GRE: // We do not need to bother looking at GRE/ESP headers, -- case IPPROTO_ESP: // since there is never a checksum to update. -- break; -- default: // do not know how to handle anything else -- return TC_ACT_OK; -- } -- -- struct ethhdr eth2; // used iff is_ethernet -- -- eth2 = *eth; // Copy over the ethernet header (src/dst mac) -- eth2.h_proto = bpf_htons(ETH_P_IP); // But replace the ethertype -- -- struct iphdr ip = { -- .version = 4, // u4 -- .ihl = sizeof(struct iphdr) / sizeof(__u32), // u4 -- .tos = (ip6->priority << 4) + (ip6->flow_lbl[0] >> 4), // u8 -- .tot_len = bpf_htons(bpf_ntohs(ip6->payload_len) + sizeof(struct iphdr)), // u16 -- .id = 0, // u16 -- .frag_off = bpf_htons(IP_DF), // u16 -- .ttl = ip6->hop_limit, // u8 -- .protocol = ip6->nexthdr, // u8 -- .check = 0, // u16 -- .saddr = 0x0201a8c0, // u32 -- .daddr = 0x0101a8c0, // u32 -- }; -- -- // Calculate the IPv4 one's complement checksum of the IPv4 header. -- __wsum sum4 = 0; -- -- for (int i = 0; i < sizeof(ip) / sizeof(__u16); ++i) -- sum4 += ((__u16 *)&ip)[i]; -- -- // Note that sum4 is guaranteed to be non-zero by virtue of ip.version == 4 -- sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse u32 into range 1 .. 0x1FFFE -- sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse any potential carry into u16 -- ip.check = (__u16)~sum4; // sum4 cannot be zero, so this is never 0xFFFF -- -- // Calculate the *negative* IPv6 16-bit one's complement checksum of the IPv6 header. -- __wsum sum6 = 0; -- // We'll end up with a non-zero sum due to ip6->version == 6 (which has '0' bits) -- for (int i = 0; i < sizeof(*ip6) / sizeof(__u16); ++i) -- sum6 += ~((__u16 *)ip6)[i]; // note the bitwise negation -- -- // Note that there is no L4 checksum update: we are relying on the checksum neutrality -- // of the ipv6 address chosen by netd's ClatdController. -- -- // Packet mutations begin - point of no return, but if this first modification fails -- // the packet is probably still pristine, so let clatd handle it. -- if (bpf_skb_change_proto(skb, bpf_htons(ETH_P_IP), 0)) -- return TC_ACT_OK; -- bpf_csum_update(skb, sum6); -- -- data = (void *)(long)skb->data; -- data_end = (void *)(long)skb->data_end; -- if (data + l2_header_size + sizeof(struct iphdr) > data_end) -- return TC_ACT_SHOT; -- -- struct ethhdr *new_eth = data; -- -- // Copy over the updated ethernet header -- *new_eth = eth2; -- -- // Copy over the new ipv4 header. -- *(struct iphdr *)(new_eth + 1) = ip; -- return bpf_redirect(skb->ifindex, BPF_F_INGRESS); --} -- --SEC("schedcls/egress4/snat4") --int sched_cls_egress4_snat4_prog(struct __sk_buff *skb) --{ -- const int l2_header_size = sizeof(struct ethhdr); -- void *data = (void *)(long)skb->data; -- const void *data_end = (void *)(long)skb->data_end; -- const struct ethhdr *const eth = data; // used iff is_ethernet -- const struct iphdr *const ip4 = (void *)(eth + 1); -- -- // Must be meta-ethernet IPv4 frame -- if (skb->protocol != bpf_htons(ETH_P_IP)) -- return TC_ACT_OK; -- -- // Must have ipv4 header -- if (data + l2_header_size + sizeof(struct ipv6hdr) > data_end) -- return TC_ACT_OK; -- -- // Ethertype - if present - must be IPv4 -- if (eth->h_proto != bpf_htons(ETH_P_IP)) -- return TC_ACT_OK; -- -- // IP version must be 4 -- if (ip4->version != 4) -- return TC_ACT_OK; -- -- // We cannot handle IP options, just standard 20 byte == 5 dword minimal IPv4 header -- if (ip4->ihl != 5) -- return TC_ACT_OK; -- -- // Maximum IPv6 payload length that can be translated to IPv4 -- if (bpf_htons(ip4->tot_len) > 0xFFFF - sizeof(struct ipv6hdr)) -- return TC_ACT_OK; -- -- // Calculate the IPv4 one's complement checksum of the IPv4 header. -- __wsum sum4 = 0; -- -- for (int i = 0; i < sizeof(*ip4) / sizeof(__u16); ++i) -- sum4 += ((__u16 *)ip4)[i]; -- -- // Note that sum4 is guaranteed to be non-zero by virtue of ip4->version == 4 -- sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse u32 into range 1 .. 0x1FFFE -- sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse any potential carry into u16 -- // for a correct checksum we should get *a* zero, but sum4 must be positive, ie 0xFFFF -- if (sum4 != 0xFFFF) -- return TC_ACT_OK; -- -- // Minimum IPv4 total length is the size of the header -- if (bpf_ntohs(ip4->tot_len) < sizeof(*ip4)) -- return TC_ACT_OK; -- -- // We are incapable of dealing with IPv4 fragments -- if (ip4->frag_off & ~bpf_htons(IP_DF)) -- return TC_ACT_OK; -- -- switch (ip4->protocol) { -- case IPPROTO_TCP: // For TCP & UDP the checksum neutrality of the chosen IPv6 -- case IPPROTO_GRE: // address means there is no need to update their checksums. -- case IPPROTO_ESP: // We do not need to bother looking at GRE/ESP headers, -- break; // since there is never a checksum to update. -- -- case IPPROTO_UDP: // See above comment, but must also have UDP header... -- if (data + sizeof(*ip4) + sizeof(struct udphdr) > data_end) -- return TC_ACT_OK; -- const struct udphdr *uh = (const struct udphdr *)(ip4 + 1); -- // If IPv4/UDP checksum is 0 then fallback to clatd so it can calculate the -- // checksum. Otherwise the network or more likely the NAT64 gateway might -- // drop the packet because in most cases IPv6/UDP packets with a zero checksum -- // are invalid. See RFC 6935. TODO: calculate checksum via bpf_csum_diff() -- if (!uh->check) -- return TC_ACT_OK; -- break; -- -- default: // do not know how to handle anything else -- return TC_ACT_OK; -- } -- struct ethhdr eth2; // used iff is_ethernet -- -- eth2 = *eth; // Copy over the ethernet header (src/dst mac) -- eth2.h_proto = bpf_htons(ETH_P_IPV6); // But replace the ethertype -- -- struct ipv6hdr ip6 = { -- .version = 6, // __u8:4 -- .priority = ip4->tos >> 4, // __u8:4 -- .flow_lbl = {(ip4->tos & 0xF) << 4, 0, 0}, // __u8[3] -- .payload_len = bpf_htons(bpf_ntohs(ip4->tot_len) - 20), // __be16 -- .nexthdr = ip4->protocol, // __u8 -- .hop_limit = ip4->ttl, // __u8 -- }; -- ip6.saddr.in6_u.u6_addr32[0] = bpf_htonl(0x20010db8); -- ip6.saddr.in6_u.u6_addr32[1] = 0; -- ip6.saddr.in6_u.u6_addr32[2] = 0; -- ip6.saddr.in6_u.u6_addr32[3] = bpf_htonl(1); -- ip6.daddr.in6_u.u6_addr32[0] = bpf_htonl(0x20010db8); -- ip6.daddr.in6_u.u6_addr32[1] = 0; -- ip6.daddr.in6_u.u6_addr32[2] = 0; -- ip6.daddr.in6_u.u6_addr32[3] = bpf_htonl(2); -- -- // Calculate the IPv6 16-bit one's complement checksum of the IPv6 header. -- __wsum sum6 = 0; -- // We'll end up with a non-zero sum due to ip6.version == 6 -- for (int i = 0; i < sizeof(ip6) / sizeof(__u16); ++i) -- sum6 += ((__u16 *)&ip6)[i]; -- -- // Packet mutations begin - point of no return, but if this first modification fails -- // the packet is probably still pristine, so let clatd handle it. -- if (bpf_skb_change_proto(skb, bpf_htons(ETH_P_IPV6), 0)) -- return TC_ACT_OK; -- -- // This takes care of updating the skb->csum field for a CHECKSUM_COMPLETE packet. -- // In such a case, skb->csum is a 16-bit one's complement sum of the entire payload, -- // thus we need to subtract out the ipv4 header's sum, and add in the ipv6 header's sum. -- // However, we've already verified the ipv4 checksum is correct and thus 0. -- // Thus we only need to add the ipv6 header's sum. -- // -- // bpf_csum_update() always succeeds if the skb is CHECKSUM_COMPLETE and returns an error -- // (-ENOTSUPP) if it isn't. So we just ignore the return code (see above for more details). -- bpf_csum_update(skb, sum6); -- -- // bpf_skb_change_proto() invalidates all pointers - reload them. -- data = (void *)(long)skb->data; -- data_end = (void *)(long)skb->data_end; -- -- // I cannot think of any valid way for this error condition to trigger, however I do -- // believe the explicit check is required to keep the in kernel ebpf verifier happy. -- if (data + l2_header_size + sizeof(ip6) > data_end) -- return TC_ACT_SHOT; -- -- struct ethhdr *new_eth = data; -- -- // Copy over the updated ethernet header -- *new_eth = eth2; -- // Copy over the new ipv4 header. -- *(struct ipv6hdr *)(new_eth + 1) = ip6; -- return TC_ACT_OK; --} -- --char _license[] SEC("license") = ("GPL"); -diff --git a/tools/testing/selftests/net/nat6to4.c b/tools/testing/selftests/net/nat6to4.c -new file mode 100644 -index 0000000000000..ac54c36b25fc8 ---- /dev/null -+++ b/tools/testing/selftests/net/nat6to4.c -@@ -0,0 +1,285 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * This code is taken from the Android Open Source Project and the author -+ * (Maciej Å»enczykowski) has gave permission to relicense it under the -+ * GPLv2. Therefore this program is free software; -+ * You can redistribute it and/or modify it under the terms of the GNU -+ * General Public License version 2 as published by the Free Software -+ * Foundation -+ -+ * The original headers, including the original license headers, are -+ * included below for completeness. -+ * -+ * Copyright (C) 2019 The Android Open Source Project -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#include -+ -+#include -+#include -+ -+#define IP_DF 0x4000 // Flag: "Don't Fragment" -+ -+SEC("schedcls/ingress6/nat_6") -+int sched_cls_ingress6_nat_6_prog(struct __sk_buff *skb) -+{ -+ const int l2_header_size = sizeof(struct ethhdr); -+ void *data = (void *)(long)skb->data; -+ const void *data_end = (void *)(long)skb->data_end; -+ const struct ethhdr * const eth = data; // used iff is_ethernet -+ const struct ipv6hdr * const ip6 = (void *)(eth + 1); -+ -+ // Require ethernet dst mac address to be our unicast address. -+ if (skb->pkt_type != PACKET_HOST) -+ return TC_ACT_OK; -+ -+ // Must be meta-ethernet IPv6 frame -+ if (skb->protocol != bpf_htons(ETH_P_IPV6)) -+ return TC_ACT_OK; -+ -+ // Must have (ethernet and) ipv6 header -+ if (data + l2_header_size + sizeof(*ip6) > data_end) -+ return TC_ACT_OK; -+ -+ // Ethertype - if present - must be IPv6 -+ if (eth->h_proto != bpf_htons(ETH_P_IPV6)) -+ return TC_ACT_OK; -+ -+ // IP version must be 6 -+ if (ip6->version != 6) -+ return TC_ACT_OK; -+ // Maximum IPv6 payload length that can be translated to IPv4 -+ if (bpf_ntohs(ip6->payload_len) > 0xFFFF - sizeof(struct iphdr)) -+ return TC_ACT_OK; -+ switch (ip6->nexthdr) { -+ case IPPROTO_TCP: // For TCP & UDP the checksum neutrality of the chosen IPv6 -+ case IPPROTO_UDP: // address means there is no need to update their checksums. -+ case IPPROTO_GRE: // We do not need to bother looking at GRE/ESP headers, -+ case IPPROTO_ESP: // since there is never a checksum to update. -+ break; -+ default: // do not know how to handle anything else -+ return TC_ACT_OK; -+ } -+ -+ struct ethhdr eth2; // used iff is_ethernet -+ -+ eth2 = *eth; // Copy over the ethernet header (src/dst mac) -+ eth2.h_proto = bpf_htons(ETH_P_IP); // But replace the ethertype -+ -+ struct iphdr ip = { -+ .version = 4, // u4 -+ .ihl = sizeof(struct iphdr) / sizeof(__u32), // u4 -+ .tos = (ip6->priority << 4) + (ip6->flow_lbl[0] >> 4), // u8 -+ .tot_len = bpf_htons(bpf_ntohs(ip6->payload_len) + sizeof(struct iphdr)), // u16 -+ .id = 0, // u16 -+ .frag_off = bpf_htons(IP_DF), // u16 -+ .ttl = ip6->hop_limit, // u8 -+ .protocol = ip6->nexthdr, // u8 -+ .check = 0, // u16 -+ .saddr = 0x0201a8c0, // u32 -+ .daddr = 0x0101a8c0, // u32 -+ }; -+ -+ // Calculate the IPv4 one's complement checksum of the IPv4 header. -+ __wsum sum4 = 0; -+ -+ for (int i = 0; i < sizeof(ip) / sizeof(__u16); ++i) -+ sum4 += ((__u16 *)&ip)[i]; -+ -+ // Note that sum4 is guaranteed to be non-zero by virtue of ip.version == 4 -+ sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse u32 into range 1 .. 0x1FFFE -+ sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse any potential carry into u16 -+ ip.check = (__u16)~sum4; // sum4 cannot be zero, so this is never 0xFFFF -+ -+ // Calculate the *negative* IPv6 16-bit one's complement checksum of the IPv6 header. -+ __wsum sum6 = 0; -+ // We'll end up with a non-zero sum due to ip6->version == 6 (which has '0' bits) -+ for (int i = 0; i < sizeof(*ip6) / sizeof(__u16); ++i) -+ sum6 += ~((__u16 *)ip6)[i]; // note the bitwise negation -+ -+ // Note that there is no L4 checksum update: we are relying on the checksum neutrality -+ // of the ipv6 address chosen by netd's ClatdController. -+ -+ // Packet mutations begin - point of no return, but if this first modification fails -+ // the packet is probably still pristine, so let clatd handle it. -+ if (bpf_skb_change_proto(skb, bpf_htons(ETH_P_IP), 0)) -+ return TC_ACT_OK; -+ bpf_csum_update(skb, sum6); -+ -+ data = (void *)(long)skb->data; -+ data_end = (void *)(long)skb->data_end; -+ if (data + l2_header_size + sizeof(struct iphdr) > data_end) -+ return TC_ACT_SHOT; -+ -+ struct ethhdr *new_eth = data; -+ -+ // Copy over the updated ethernet header -+ *new_eth = eth2; -+ -+ // Copy over the new ipv4 header. -+ *(struct iphdr *)(new_eth + 1) = ip; -+ return bpf_redirect(skb->ifindex, BPF_F_INGRESS); -+} -+ -+SEC("schedcls/egress4/snat4") -+int sched_cls_egress4_snat4_prog(struct __sk_buff *skb) -+{ -+ const int l2_header_size = sizeof(struct ethhdr); -+ void *data = (void *)(long)skb->data; -+ const void *data_end = (void *)(long)skb->data_end; -+ const struct ethhdr *const eth = data; // used iff is_ethernet -+ const struct iphdr *const ip4 = (void *)(eth + 1); -+ -+ // Must be meta-ethernet IPv4 frame -+ if (skb->protocol != bpf_htons(ETH_P_IP)) -+ return TC_ACT_OK; -+ -+ // Must have ipv4 header -+ if (data + l2_header_size + sizeof(struct ipv6hdr) > data_end) -+ return TC_ACT_OK; -+ -+ // Ethertype - if present - must be IPv4 -+ if (eth->h_proto != bpf_htons(ETH_P_IP)) -+ return TC_ACT_OK; -+ -+ // IP version must be 4 -+ if (ip4->version != 4) -+ return TC_ACT_OK; -+ -+ // We cannot handle IP options, just standard 20 byte == 5 dword minimal IPv4 header -+ if (ip4->ihl != 5) -+ return TC_ACT_OK; -+ -+ // Maximum IPv6 payload length that can be translated to IPv4 -+ if (bpf_htons(ip4->tot_len) > 0xFFFF - sizeof(struct ipv6hdr)) -+ return TC_ACT_OK; -+ -+ // Calculate the IPv4 one's complement checksum of the IPv4 header. -+ __wsum sum4 = 0; -+ -+ for (int i = 0; i < sizeof(*ip4) / sizeof(__u16); ++i) -+ sum4 += ((__u16 *)ip4)[i]; -+ -+ // Note that sum4 is guaranteed to be non-zero by virtue of ip4->version == 4 -+ sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse u32 into range 1 .. 0x1FFFE -+ sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse any potential carry into u16 -+ // for a correct checksum we should get *a* zero, but sum4 must be positive, ie 0xFFFF -+ if (sum4 != 0xFFFF) -+ return TC_ACT_OK; -+ -+ // Minimum IPv4 total length is the size of the header -+ if (bpf_ntohs(ip4->tot_len) < sizeof(*ip4)) -+ return TC_ACT_OK; -+ -+ // We are incapable of dealing with IPv4 fragments -+ if (ip4->frag_off & ~bpf_htons(IP_DF)) -+ return TC_ACT_OK; -+ -+ switch (ip4->protocol) { -+ case IPPROTO_TCP: // For TCP & UDP the checksum neutrality of the chosen IPv6 -+ case IPPROTO_GRE: // address means there is no need to update their checksums. -+ case IPPROTO_ESP: // We do not need to bother looking at GRE/ESP headers, -+ break; // since there is never a checksum to update. -+ -+ case IPPROTO_UDP: // See above comment, but must also have UDP header... -+ if (data + sizeof(*ip4) + sizeof(struct udphdr) > data_end) -+ return TC_ACT_OK; -+ const struct udphdr *uh = (const struct udphdr *)(ip4 + 1); -+ // If IPv4/UDP checksum is 0 then fallback to clatd so it can calculate the -+ // checksum. Otherwise the network or more likely the NAT64 gateway might -+ // drop the packet because in most cases IPv6/UDP packets with a zero checksum -+ // are invalid. See RFC 6935. TODO: calculate checksum via bpf_csum_diff() -+ if (!uh->check) -+ return TC_ACT_OK; -+ break; -+ -+ default: // do not know how to handle anything else -+ return TC_ACT_OK; -+ } -+ struct ethhdr eth2; // used iff is_ethernet -+ -+ eth2 = *eth; // Copy over the ethernet header (src/dst mac) -+ eth2.h_proto = bpf_htons(ETH_P_IPV6); // But replace the ethertype -+ -+ struct ipv6hdr ip6 = { -+ .version = 6, // __u8:4 -+ .priority = ip4->tos >> 4, // __u8:4 -+ .flow_lbl = {(ip4->tos & 0xF) << 4, 0, 0}, // __u8[3] -+ .payload_len = bpf_htons(bpf_ntohs(ip4->tot_len) - 20), // __be16 -+ .nexthdr = ip4->protocol, // __u8 -+ .hop_limit = ip4->ttl, // __u8 -+ }; -+ ip6.saddr.in6_u.u6_addr32[0] = bpf_htonl(0x20010db8); -+ ip6.saddr.in6_u.u6_addr32[1] = 0; -+ ip6.saddr.in6_u.u6_addr32[2] = 0; -+ ip6.saddr.in6_u.u6_addr32[3] = bpf_htonl(1); -+ ip6.daddr.in6_u.u6_addr32[0] = bpf_htonl(0x20010db8); -+ ip6.daddr.in6_u.u6_addr32[1] = 0; -+ ip6.daddr.in6_u.u6_addr32[2] = 0; -+ ip6.daddr.in6_u.u6_addr32[3] = bpf_htonl(2); -+ -+ // Calculate the IPv6 16-bit one's complement checksum of the IPv6 header. -+ __wsum sum6 = 0; -+ // We'll end up with a non-zero sum due to ip6.version == 6 -+ for (int i = 0; i < sizeof(ip6) / sizeof(__u16); ++i) -+ sum6 += ((__u16 *)&ip6)[i]; -+ -+ // Packet mutations begin - point of no return, but if this first modification fails -+ // the packet is probably still pristine, so let clatd handle it. -+ if (bpf_skb_change_proto(skb, bpf_htons(ETH_P_IPV6), 0)) -+ return TC_ACT_OK; -+ -+ // This takes care of updating the skb->csum field for a CHECKSUM_COMPLETE packet. -+ // In such a case, skb->csum is a 16-bit one's complement sum of the entire payload, -+ // thus we need to subtract out the ipv4 header's sum, and add in the ipv6 header's sum. -+ // However, we've already verified the ipv4 checksum is correct and thus 0. -+ // Thus we only need to add the ipv6 header's sum. -+ // -+ // bpf_csum_update() always succeeds if the skb is CHECKSUM_COMPLETE and returns an error -+ // (-ENOTSUPP) if it isn't. So we just ignore the return code (see above for more details). -+ bpf_csum_update(skb, sum6); -+ -+ // bpf_skb_change_proto() invalidates all pointers - reload them. -+ data = (void *)(long)skb->data; -+ data_end = (void *)(long)skb->data_end; -+ -+ // I cannot think of any valid way for this error condition to trigger, however I do -+ // believe the explicit check is required to keep the in kernel ebpf verifier happy. -+ if (data + l2_header_size + sizeof(ip6) > data_end) -+ return TC_ACT_SHOT; -+ -+ struct ethhdr *new_eth = data; -+ -+ // Copy over the updated ethernet header -+ *new_eth = eth2; -+ // Copy over the new ipv4 header. -+ *(struct ipv6hdr *)(new_eth + 1) = ip6; -+ return TC_ACT_OK; -+} -+ -+char _license[] SEC("license") = ("GPL"); -diff --git a/tools/testing/selftests/net/udpgro_frglist.sh b/tools/testing/selftests/net/udpgro_frglist.sh -index c9c4b9d658390..0a6359bed0b92 100755 ---- a/tools/testing/selftests/net/udpgro_frglist.sh -+++ b/tools/testing/selftests/net/udpgro_frglist.sh -@@ -40,8 +40,8 @@ run_one() { - - ip -n "${PEER_NS}" link set veth1 xdp object ${BPF_FILE} section xdp - tc -n "${PEER_NS}" qdisc add dev veth1 clsact -- tc -n "${PEER_NS}" filter add dev veth1 ingress prio 4 protocol ipv6 bpf object-file ../bpf/nat6to4.o section schedcls/ingress6/nat_6 direct-action -- tc -n "${PEER_NS}" filter add dev veth1 egress prio 4 protocol ip bpf object-file ../bpf/nat6to4.o section schedcls/egress4/snat4 direct-action -+ tc -n "${PEER_NS}" filter add dev veth1 ingress prio 4 protocol ipv6 bpf object-file nat6to4.o section schedcls/ingress6/nat_6 direct-action -+ tc -n "${PEER_NS}" filter add dev veth1 egress prio 4 protocol ip bpf object-file nat6to4.o section schedcls/egress4/snat4 direct-action - echo ${rx_args} - ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r & - -@@ -88,8 +88,8 @@ if [ ! -f ${BPF_FILE} ]; then - exit -1 - fi - --if [ ! -f bpf/nat6to4.o ]; then -- echo "Missing nat6to4 helper. Build bpfnat6to4.o selftest first" -+if [ ! -f nat6to4.o ]; then -+ echo "Missing nat6to4 helper. Build bpf nat6to4.o selftest first" - exit -1 - fi - diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.50-51.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.50-51.patch deleted file mode 100644 index 1b1e4e607bed..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.50-51.patch +++ /dev/null @@ -1,550 +0,0 @@ -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 882b6198dd0d1..31af352b4762d 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -6164,10 +6164,6 @@ - -1: disable all critical trip points in all thermal zones - : override all critical trip points - -- thermal.nocrt= [HW,ACPI] -- Set to disable actions on ACPI thermal zone -- critical and hot trip points. -- - thermal.off= [HW,ACPI] - 1: disable ACPI thermal control - -diff --git a/Makefile b/Makefile -index e5e1fdeef8bf0..e7c344d5af156 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 50 -+SUBLEVEL = 51 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c -index 1fc309b41f944..8d809724cde52 100644 ---- a/arch/arm/kernel/module-plts.c -+++ b/arch/arm/kernel/module-plts.c -@@ -256,7 +256,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, - /* sort by type and symbol index */ - sort(rels, numrels, sizeof(Elf32_Rel), cmp_rel, NULL); - -- if (strncmp(secstrings + dstsec->sh_name, ".init", 5) != 0) -+ if (!module_init_layout_section(secstrings + dstsec->sh_name)) - core_plts += count_plts(syms, dstsec->sh_addr, rels, - numrels, s->sh_info); - else -diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c -index 5a0a8f552a610..c703b5db8eb11 100644 ---- a/arch/arm64/kernel/module-plts.c -+++ b/arch/arm64/kernel/module-plts.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - #include - - static struct plt_entry __get_adrp_add_pair(u64 dst, u64 pc, -@@ -343,7 +344,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, - if (nents) - sort(rels, nents, sizeof(Elf64_Rela), cmp_rela, NULL); - -- if (!str_has_prefix(secstrings + dstsec->sh_name, ".init")) -+ if (!module_init_layout_section(secstrings + dstsec->sh_name)) - core_plts += count_plts(syms, rels, numrels, - sechdrs[i].sh_info, dstsec); - else -diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c -index 09a34b07f02e6..9915062d5243c 100644 ---- a/arch/parisc/kernel/sys_parisc.c -+++ b/arch/parisc/kernel/sys_parisc.c -@@ -24,32 +24,28 @@ - #include - #include - #include -+#include - --/* we construct an artificial offset for the mapping based on the physical -- * address of the kernel mapping variable */ --#define GET_LAST_MMAP(filp) \ -- (filp ? ((unsigned long) filp->f_mapping) >> 8 : 0UL) --#define SET_LAST_MMAP(filp, val) \ -- { /* nothing */ } -- --static int get_offset(unsigned int last_mmap) --{ -- return (last_mmap & (SHM_COLOUR-1)) >> PAGE_SHIFT; --} -+/* -+ * Construct an artificial page offset for the mapping based on the physical -+ * address of the kernel file mapping variable. -+ */ -+#define GET_FILP_PGOFF(filp) \ -+ (filp ? (((unsigned long) filp->f_mapping) >> 8) \ -+ & ((SHM_COLOUR-1) >> PAGE_SHIFT) : 0UL) - --static unsigned long shared_align_offset(unsigned int last_mmap, -+static unsigned long shared_align_offset(unsigned long filp_pgoff, - unsigned long pgoff) - { -- return (get_offset(last_mmap) + pgoff) << PAGE_SHIFT; -+ return (filp_pgoff + pgoff) << PAGE_SHIFT; - } - - static inline unsigned long COLOR_ALIGN(unsigned long addr, -- unsigned int last_mmap, unsigned long pgoff) -+ unsigned long filp_pgoff, unsigned long pgoff) - { - unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1); - unsigned long off = (SHM_COLOUR-1) & -- (shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT); -- -+ shared_align_offset(filp_pgoff, pgoff); - return base + off; - } - -@@ -98,126 +94,91 @@ static unsigned long mmap_upper_limit(struct rlimit *rlim_stack) - return PAGE_ALIGN(STACK_TOP - stack_base); - } - -+enum mmap_allocation_direction {UP, DOWN}; - --unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, -- unsigned long len, unsigned long pgoff, unsigned long flags) -+static unsigned long arch_get_unmapped_area_common(struct file *filp, -+ unsigned long addr, unsigned long len, unsigned long pgoff, -+ unsigned long flags, enum mmap_allocation_direction dir) - { - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma, *prev; -- unsigned long task_size = TASK_SIZE; -- int do_color_align, last_mmap; -+ unsigned long filp_pgoff; -+ int do_color_align; - struct vm_unmapped_area_info info; - -- if (len > task_size) -+ if (unlikely(len > TASK_SIZE)) - return -ENOMEM; - - do_color_align = 0; - if (filp || (flags & MAP_SHARED)) - do_color_align = 1; -- last_mmap = GET_LAST_MMAP(filp); -+ filp_pgoff = GET_FILP_PGOFF(filp); - - if (flags & MAP_FIXED) { -- if ((flags & MAP_SHARED) && last_mmap && -- (addr - shared_align_offset(last_mmap, pgoff)) -+ /* Even MAP_FIXED mappings must reside within TASK_SIZE */ -+ if (TASK_SIZE - len < addr) -+ return -EINVAL; -+ -+ if ((flags & MAP_SHARED) && filp && -+ (addr - shared_align_offset(filp_pgoff, pgoff)) - & (SHM_COLOUR - 1)) - return -EINVAL; -- goto found_addr; -+ return addr; - } - - if (addr) { -- if (do_color_align && last_mmap) -- addr = COLOR_ALIGN(addr, last_mmap, pgoff); -+ if (do_color_align) -+ addr = COLOR_ALIGN(addr, filp_pgoff, pgoff); - else - addr = PAGE_ALIGN(addr); - - vma = find_vma_prev(mm, addr, &prev); -- if (task_size - len >= addr && -+ if (TASK_SIZE - len >= addr && - (!vma || addr + len <= vm_start_gap(vma)) && - (!prev || addr >= vm_end_gap(prev))) -- goto found_addr; -+ return addr; - } - -- info.flags = 0; - info.length = len; -+ info.align_mask = do_color_align ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0; -+ info.align_offset = shared_align_offset(filp_pgoff, pgoff); -+ -+ if (dir == DOWN) { -+ info.flags = VM_UNMAPPED_AREA_TOPDOWN; -+ info.low_limit = PAGE_SIZE; -+ info.high_limit = mm->mmap_base; -+ addr = vm_unmapped_area(&info); -+ if (!(addr & ~PAGE_MASK)) -+ return addr; -+ VM_BUG_ON(addr != -ENOMEM); -+ -+ /* -+ * A failed mmap() very likely causes application failure, -+ * so fall back to the bottom-up function here. This scenario -+ * can happen with large stack limits and large mmap() -+ * allocations. -+ */ -+ } -+ -+ info.flags = 0; - info.low_limit = mm->mmap_legacy_base; - info.high_limit = mmap_upper_limit(NULL); -- info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0; -- info.align_offset = shared_align_offset(last_mmap, pgoff); -- addr = vm_unmapped_area(&info); -- --found_addr: -- if (do_color_align && !last_mmap && !(addr & ~PAGE_MASK)) -- SET_LAST_MMAP(filp, addr - (pgoff << PAGE_SHIFT)); -- -- return addr; -+ return vm_unmapped_area(&info); - } - --unsigned long --arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, -- const unsigned long len, const unsigned long pgoff, -- const unsigned long flags) -+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, -+ unsigned long len, unsigned long pgoff, unsigned long flags) - { -- struct vm_area_struct *vma, *prev; -- struct mm_struct *mm = current->mm; -- unsigned long addr = addr0; -- int do_color_align, last_mmap; -- struct vm_unmapped_area_info info; -- -- /* requested length too big for entire address space */ -- if (len > TASK_SIZE) -- return -ENOMEM; -- -- do_color_align = 0; -- if (filp || (flags & MAP_SHARED)) -- do_color_align = 1; -- last_mmap = GET_LAST_MMAP(filp); -- -- if (flags & MAP_FIXED) { -- if ((flags & MAP_SHARED) && last_mmap && -- (addr - shared_align_offset(last_mmap, pgoff)) -- & (SHM_COLOUR - 1)) -- return -EINVAL; -- goto found_addr; -- } -- -- /* requesting a specific address */ -- if (addr) { -- if (do_color_align && last_mmap) -- addr = COLOR_ALIGN(addr, last_mmap, pgoff); -- else -- addr = PAGE_ALIGN(addr); -- -- vma = find_vma_prev(mm, addr, &prev); -- if (TASK_SIZE - len >= addr && -- (!vma || addr + len <= vm_start_gap(vma)) && -- (!prev || addr >= vm_end_gap(prev))) -- goto found_addr; -- } -- -- info.flags = VM_UNMAPPED_AREA_TOPDOWN; -- info.length = len; -- info.low_limit = PAGE_SIZE; -- info.high_limit = mm->mmap_base; -- info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0; -- info.align_offset = shared_align_offset(last_mmap, pgoff); -- addr = vm_unmapped_area(&info); -- if (!(addr & ~PAGE_MASK)) -- goto found_addr; -- VM_BUG_ON(addr != -ENOMEM); -- -- /* -- * A failed mmap() very likely causes application failure, -- * so fall back to the bottom-up function here. This scenario -- * can happen with large stack limits and large mmap() -- * allocations. -- */ -- return arch_get_unmapped_area(filp, addr0, len, pgoff, flags); -- --found_addr: -- if (do_color_align && !last_mmap && !(addr & ~PAGE_MASK)) -- SET_LAST_MMAP(filp, addr - (pgoff << PAGE_SHIFT)); -+ return arch_get_unmapped_area_common(filp, -+ addr, len, pgoff, flags, UP); -+} - -- return addr; -+unsigned long arch_get_unmapped_area_topdown(struct file *filp, -+ unsigned long addr, unsigned long len, unsigned long pgoff, -+ unsigned long flags) -+{ -+ return arch_get_unmapped_area_common(filp, -+ addr, len, pgoff, flags, DOWN); - } - - static int mmap_is_legacy(void) -@@ -379,7 +340,7 @@ asmlinkage long parisc_fallocate(int fd, int mode, u32 offhi, u32 offlo, - ((u64)lenhi << 32) | lenlo); - } - --long parisc_personality(unsigned long personality) -+asmlinkage long parisc_personality(unsigned long personality) - { - long err; - -diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h -index a6e8373a5170f..3fa87e5e11aba 100644 ---- a/arch/x86/include/asm/sections.h -+++ b/arch/x86/include/asm/sections.h -@@ -2,8 +2,6 @@ - #ifndef _ASM_X86_SECTIONS_H - #define _ASM_X86_SECTIONS_H - --#define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed -- - #include - #include - -@@ -18,20 +16,4 @@ extern char __end_of_kernel_reserve[]; - - extern unsigned long _brk_start, _brk_end; - --static inline bool arch_is_kernel_initmem_freed(unsigned long addr) --{ -- /* -- * If _brk_start has not been cleared, brk allocation is incomplete, -- * and we can not make assumptions about its use. -- */ -- if (_brk_start) -- return 0; -- -- /* -- * After brk allocation is complete, space between _brk_end and _end -- * is available for allocation. -- */ -- return addr >= _brk_end && addr < (unsigned long)&_end; --} -- - #endif /* _ASM_X86_SECTIONS_H */ -diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c -index 40b07057983e0..40ecb55b52f8c 100644 ---- a/drivers/acpi/thermal.c -+++ b/drivers/acpi/thermal.c -@@ -59,10 +59,6 @@ static int tzp; - module_param(tzp, int, 0444); - MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); - --static int nocrt; --module_param(nocrt, int, 0); --MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points."); -- - static int off; - module_param(off, int, 0); - MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); -@@ -1128,7 +1124,7 @@ static int thermal_act(const struct dmi_system_id *d) { - static int thermal_nocrt(const struct dmi_system_id *d) { - pr_notice("%s detected: disabling all critical thermal trip point actions.\n", - d->ident); -- nocrt = 1; -+ crt = -1; - return 0; - } - static int thermal_tzp(const struct dmi_system_id *d) { -diff --git a/drivers/thunderbolt/tmu.c b/drivers/thunderbolt/tmu.c -index d9544600b3867..49146f97bb16e 100644 ---- a/drivers/thunderbolt/tmu.c -+++ b/drivers/thunderbolt/tmu.c -@@ -416,6 +416,7 @@ int tb_switch_tmu_disable(struct tb_switch *sw) - * mode. - */ - ret = tb_switch_tmu_rate_write(sw, TB_SWITCH_TMU_RATE_OFF); -+ if (ret) - return ret; - - tb_port_tmu_time_sync_disable(up); -diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h -index 9e09d11ffe5b3..1322652a9d0d9 100644 ---- a/include/linux/moduleloader.h -+++ b/include/linux/moduleloader.h -@@ -39,6 +39,11 @@ bool module_init_section(const char *name); - */ - bool module_exit_section(const char *name); - -+/* Describes whether within_module_init() will consider this an init section -+ * or not. This behaviour changes with CONFIG_MODULE_UNLOAD. -+ */ -+bool module_init_layout_section(const char *sname); -+ - /* - * Apply the given relocation to the (simplified) ELF. Return -error - * or 0. -diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c -index ed8e9deae284a..b0e47fe1eb4bb 100644 ---- a/io_uring/io_uring.c -+++ b/io_uring/io_uring.c -@@ -72,6 +72,7 @@ - #include - #include - #include -+#include - - #define CREATE_TRACE_POINTS - #include -@@ -3110,6 +3111,49 @@ static __cold int io_uring_mmap(struct file *file, struct vm_area_struct *vma) - return remap_pfn_range(vma, vma->vm_start, pfn, sz, vma->vm_page_prot); - } - -+static unsigned long io_uring_mmu_get_unmapped_area(struct file *filp, -+ unsigned long addr, unsigned long len, -+ unsigned long pgoff, unsigned long flags) -+{ -+ void *ptr; -+ -+ /* -+ * Do not allow to map to user-provided address to avoid breaking the -+ * aliasing rules. Userspace is not able to guess the offset address of -+ * kernel kmalloc()ed memory area. -+ */ -+ if (addr) -+ return -EINVAL; -+ -+ ptr = io_uring_validate_mmap_request(filp, pgoff, len); -+ if (IS_ERR(ptr)) -+ return -ENOMEM; -+ -+ /* -+ * Some architectures have strong cache aliasing requirements. -+ * For such architectures we need a coherent mapping which aliases -+ * kernel memory *and* userspace memory. To achieve that: -+ * - use a NULL file pointer to reference physical memory, and -+ * - use the kernel virtual address of the shared io_uring context -+ * (instead of the userspace-provided address, which has to be 0UL -+ * anyway). -+ * - use the same pgoff which the get_unmapped_area() uses to -+ * calculate the page colouring. -+ * For architectures without such aliasing requirements, the -+ * architecture will return any suitable mapping because addr is 0. -+ */ -+ filp = NULL; -+ flags |= MAP_SHARED; -+ pgoff = 0; /* has been translated to ptr above */ -+#ifdef SHM_COLOUR -+ addr = (uintptr_t) ptr; -+ pgoff = addr >> PAGE_SHIFT; -+#else -+ addr = 0UL; -+#endif -+ return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags); -+} -+ - #else /* !CONFIG_MMU */ - - static int io_uring_mmap(struct file *file, struct vm_area_struct *vma) -@@ -3324,6 +3368,8 @@ static const struct file_operations io_uring_fops = { - #ifndef CONFIG_MMU - .get_unmapped_area = io_uring_nommu_get_unmapped_area, - .mmap_capabilities = io_uring_nommu_mmap_capabilities, -+#else -+ .get_unmapped_area = io_uring_mmu_get_unmapped_area, - #endif - .poll = io_uring_poll, - #ifdef CONFIG_PROC_FS -diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c -index 676328a7c8c75..ad3cccb0970f8 100644 ---- a/kernel/kallsyms.c -+++ b/kernel/kallsyms.c -@@ -188,16 +188,13 @@ static bool cleanup_symbol_name(char *s) - - static int compare_symbol_name(const char *name, char *namebuf) - { -- int ret; -- -- ret = strcmp(name, namebuf); -- if (!ret) -- return ret; -- -- if (cleanup_symbol_name(namebuf) && !strcmp(name, namebuf)) -- return 0; -- -- return ret; -+ /* The kallsyms_seqs_of_names is sorted based on names after -+ * cleanup_symbol_name() (see scripts/kallsyms.c) if clang lto is enabled. -+ * To ensure correct bisection in kallsyms_lookup_names(), do -+ * cleanup_symbol_name(namebuf) before comparing name and namebuf. -+ */ -+ cleanup_symbol_name(namebuf); -+ return strcmp(name, namebuf); - } - - static int kallsyms_lookup_names(const char *name, -diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index 50d4863974e7a..0224b0329d011 100644 ---- a/kernel/locking/lockdep.c -+++ b/kernel/locking/lockdep.c -@@ -817,34 +817,26 @@ static int very_verbose(struct lock_class *class) - * Is this the address of a static object: - */ - #ifdef __KERNEL__ --/* -- * Check if an address is part of freed initmem. After initmem is freed, -- * memory can be allocated from it, and such allocations would then have -- * addresses within the range [_stext, _end]. -- */ --#ifndef arch_is_kernel_initmem_freed --static int arch_is_kernel_initmem_freed(unsigned long addr) --{ -- if (system_state < SYSTEM_FREEING_INITMEM) -- return 0; -- -- return init_section_contains((void *)addr, 1); --} --#endif -- - static int static_obj(const void *obj) - { -- unsigned long start = (unsigned long) &_stext, -- end = (unsigned long) &_end, -- addr = (unsigned long) obj; -+ unsigned long addr = (unsigned long) obj; - -- if (arch_is_kernel_initmem_freed(addr)) -- return 0; -+ if (is_kernel_core_data(addr)) -+ return 1; -+ -+ /* -+ * keys are allowed in the __ro_after_init section. -+ */ -+ if (is_kernel_rodata(addr)) -+ return 1; - - /* -- * static variable? -+ * in initdata section and used during bootup only? -+ * NOTE: On some platforms the initdata section is -+ * outside of the _stext ... _end range. - */ -- if ((addr >= start) && (addr < end)) -+ if (system_state < SYSTEM_FREEING_INITMEM && -+ init_section_contains((void *)addr, 1)) - return 1; - - /* -diff --git a/kernel/module/main.c b/kernel/module/main.c -index 7a627345d4fd9..7a6f43d2b7757 100644 ---- a/kernel/module/main.c -+++ b/kernel/module/main.c -@@ -1401,7 +1401,7 @@ long module_get_offset(struct module *mod, unsigned int *size, - return ret; - } - --static bool module_init_layout_section(const char *sname) -+bool module_init_layout_section(const char *sname) - { - #ifndef CONFIG_MODULE_UNLOAD - if (module_exit_section(sname)) diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.51-52.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.51-52.patch deleted file mode 100644 index 11ad11750fc7..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.51-52.patch +++ /dev/null @@ -1,957 +0,0 @@ -diff --git a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt -index 0fa8e3e43bf80..1a7e4bff0456f 100644 ---- a/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt -+++ b/Documentation/devicetree/bindings/serial/nxp,sc16is7xx.txt -@@ -23,6 +23,9 @@ Optional properties: - 1 = active low. - - irda-mode-ports: An array that lists the indices of the port that - should operate in IrDA mode. -+- nxp,modem-control-line-ports: An array that lists the indices of the port that -+ should have shared GPIO lines configured as -+ modem control lines. - - Example: - sc16is750: sc16is750@51 { -@@ -35,6 +38,26 @@ Example: - #gpio-cells = <2>; - }; - -+ sc16is752: sc16is752@53 { -+ compatible = "nxp,sc16is752"; -+ reg = <0x53>; -+ clocks = <&clk20m>; -+ interrupt-parent = <&gpio3>; -+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>; -+ nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ -+ gpio-controller; /* Port 0 as GPIOs */ -+ #gpio-cells = <2>; -+ }; -+ -+ sc16is752: sc16is752@54 { -+ compatible = "nxp,sc16is752"; -+ reg = <0x54>; -+ clocks = <&clk20m>; -+ interrupt-parent = <&gpio3>; -+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>; -+ nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ -+ }; -+ - * spi as bus - - Required properties: -@@ -59,6 +82,9 @@ Optional properties: - 1 = active low. - - irda-mode-ports: An array that lists the indices of the port that - should operate in IrDA mode. -+- nxp,modem-control-line-ports: An array that lists the indices of the port that -+ should have shared GPIO lines configured as -+ modem control lines. - - Example: - sc16is750: sc16is750@0 { -@@ -70,3 +96,23 @@ Example: - gpio-controller; - #gpio-cells = <2>; - }; -+ -+ sc16is752: sc16is752@1 { -+ compatible = "nxp,sc16is752"; -+ reg = <1>; -+ clocks = <&clk20m>; -+ interrupt-parent = <&gpio3>; -+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>; -+ nxp,modem-control-line-ports = <1>; /* Port 1 as modem control lines */ -+ gpio-controller; /* Port 0 as GPIOs */ -+ #gpio-cells = <2>; -+ }; -+ -+ sc16is752: sc16is752@2 { -+ compatible = "nxp,sc16is752"; -+ reg = <2>; -+ clocks = <&clk20m>; -+ interrupt-parent = <&gpio3>; -+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>; -+ nxp,modem-control-line-ports = <0 1>; /* Ports 0 and 1 as modem control lines */ -+ }; -diff --git a/Makefile b/Makefile -index e7c344d5af156..82aaa3ae7395b 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 51 -+SUBLEVEL = 52 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c -index a829baf8d9226..05c0a0f6fe630 100644 ---- a/arch/arm/mach-pxa/sharpsl_pm.c -+++ b/arch/arm/mach-pxa/sharpsl_pm.c -@@ -220,8 +220,6 @@ void sharpsl_battery_kick(void) - { - schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125)); - } --EXPORT_SYMBOL(sharpsl_battery_kick); -- - - static void sharpsl_battery_thread(struct work_struct *private_) - { -diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c -index 9964729cd428f..937f56bbaf6c6 100644 ---- a/arch/arm/mach-pxa/spitz.c -+++ b/arch/arm/mach-pxa/spitz.c -@@ -9,7 +9,6 @@ - */ - - #include --#include /* symbol_get ; symbol_put */ - #include - #include - #include -@@ -510,17 +509,6 @@ static struct ads7846_platform_data spitz_ads7846_info = { - .wait_for_sync = spitz_ads7846_wait_for_hsync, - }; - --static void spitz_bl_kick_battery(void) --{ -- void (*kick_batt)(void); -- -- kick_batt = symbol_get(sharpsl_battery_kick); -- if (kick_batt) { -- kick_batt(); -- symbol_put(sharpsl_battery_kick); -- } --} -- - static struct gpiod_lookup_table spitz_lcdcon_gpio_table = { - .dev_id = "spi2.1", - .table = { -@@ -548,7 +536,7 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = { - .max_intensity = 0x2f, - .default_intensity = 0x1f, - .limit_mask = 0x0b, -- .kick_battery = spitz_bl_kick_battery, -+ .kick_battery = sharpsl_battery_kick, - }; - - static struct spi_board_info spitz_spi_devices[] = { -diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c -index 2c52ee27b4f25..50de86eb8784c 100644 ---- a/arch/mips/alchemy/devboards/db1000.c -+++ b/arch/mips/alchemy/devboards/db1000.c -@@ -14,7 +14,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -167,12 +166,7 @@ static struct platform_device db1x00_audio_dev = { - - static irqreturn_t db1100_mmc_cd(int irq, void *ptr) - { -- void (*mmc_cd)(struct mmc_host *, unsigned long); -- /* link against CONFIG_MMC=m */ -- mmc_cd = symbol_get(mmc_detect_change); -- mmc_cd(ptr, msecs_to_jiffies(500)); -- symbol_put(mmc_detect_change); -- -+ mmc_detect_change(ptr, msecs_to_jiffies(500)); - return IRQ_HANDLED; - } - -diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c -index 1864eb935ca57..76080c71a2a7b 100644 ---- a/arch/mips/alchemy/devboards/db1200.c -+++ b/arch/mips/alchemy/devboards/db1200.c -@@ -10,7 +10,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -340,14 +339,7 @@ static irqreturn_t db1200_mmc_cd(int irq, void *ptr) - - static irqreturn_t db1200_mmc_cdfn(int irq, void *ptr) - { -- void (*mmc_cd)(struct mmc_host *, unsigned long); -- -- /* link against CONFIG_MMC=m */ -- mmc_cd = symbol_get(mmc_detect_change); -- if (mmc_cd) { -- mmc_cd(ptr, msecs_to_jiffies(200)); -- symbol_put(mmc_detect_change); -- } -+ mmc_detect_change(ptr, msecs_to_jiffies(200)); - - msleep(100); /* debounce */ - if (irq == DB1200_SD0_INSERT_INT) -@@ -431,14 +423,7 @@ static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr) - - static irqreturn_t pb1200_mmc1_cdfn(int irq, void *ptr) - { -- void (*mmc_cd)(struct mmc_host *, unsigned long); -- -- /* link against CONFIG_MMC=m */ -- mmc_cd = symbol_get(mmc_detect_change); -- if (mmc_cd) { -- mmc_cd(ptr, msecs_to_jiffies(200)); -- symbol_put(mmc_detect_change); -- } -+ mmc_detect_change(ptr, msecs_to_jiffies(200)); - - msleep(100); /* debounce */ - if (irq == PB1200_SD1_INSERT_INT) -diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c -index e70e529ddd914..ff61901329c62 100644 ---- a/arch/mips/alchemy/devboards/db1300.c -+++ b/arch/mips/alchemy/devboards/db1300.c -@@ -17,7 +17,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -459,14 +458,7 @@ static irqreturn_t db1300_mmc_cd(int irq, void *ptr) - - static irqreturn_t db1300_mmc_cdfn(int irq, void *ptr) - { -- void (*mmc_cd)(struct mmc_host *, unsigned long); -- -- /* link against CONFIG_MMC=m. We can only be called once MMC core has -- * initialized the controller, so symbol_get() should always succeed. -- */ -- mmc_cd = symbol_get(mmc_detect_change); -- mmc_cd(ptr, msecs_to_jiffies(200)); -- symbol_put(mmc_detect_change); -+ mmc_detect_change(ptr, msecs_to_jiffies(200)); - - msleep(100); /* debounce */ - if (irq == DB1300_SD1_INSERT_INT) -diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c -index 795be33f2892d..f19d31ee37ea8 100644 ---- a/drivers/bluetooth/btsdio.c -+++ b/drivers/bluetooth/btsdio.c -@@ -357,6 +357,7 @@ static void btsdio_remove(struct sdio_func *func) - if (!data) - return; - -+ cancel_work_sync(&data->work); - hdev = data->hdev; - - sdio_set_drvdata(func, NULL); -diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c -index 2d674126160fe..cab11af28c231 100644 ---- a/drivers/firmware/stratix10-svc.c -+++ b/drivers/firmware/stratix10-svc.c -@@ -756,7 +756,7 @@ svc_create_memory_pool(struct platform_device *pdev, - paddr = begin; - size = end - begin; - va = devm_memremap(dev, paddr, size, MEMREMAP_WC); -- if (!va) { -+ if (IS_ERR(va)) { - dev_err(dev, "fail to remap shared memory\n"); - return ERR_PTR(-EINVAL); - } -diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c -index 5f608ef8b53ca..cde281ec89d7b 100644 ---- a/drivers/fsi/fsi-master-ast-cf.c -+++ b/drivers/fsi/fsi-master-ast-cf.c -@@ -1441,3 +1441,4 @@ static struct platform_driver fsi_master_acf = { - - module_platform_driver(fsi_master_acf); - MODULE_LICENSE("GPL"); -+MODULE_FIRMWARE(FW_FILE_NAME); -diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h -index 4da50e19808ef..166a76c9bcad3 100644 ---- a/drivers/hid/wacom.h -+++ b/drivers/hid/wacom.h -@@ -150,6 +150,7 @@ struct wacom_remote { - struct input_dev *input; - bool registered; - struct wacom_battery battery; -+ ktime_t active_time; - } remotes[WACOM_MAX_REMOTES]; - }; - -diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c -index aff4a21a46b6a..af163e8dfec07 100644 ---- a/drivers/hid/wacom_sys.c -+++ b/drivers/hid/wacom_sys.c -@@ -2527,6 +2527,18 @@ fail: - return; - } - -+static void wacom_remote_destroy_battery(struct wacom *wacom, int index) -+{ -+ struct wacom_remote *remote = wacom->remote; -+ -+ if (remote->remotes[index].battery.battery) { -+ devres_release_group(&wacom->hdev->dev, -+ &remote->remotes[index].battery.bat_desc); -+ remote->remotes[index].battery.battery = NULL; -+ remote->remotes[index].active_time = 0; -+ } -+} -+ - static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) - { - struct wacom_remote *remote = wacom->remote; -@@ -2541,9 +2553,7 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) - remote->remotes[i].registered = false; - spin_unlock_irqrestore(&remote->remote_lock, flags); - -- if (remote->remotes[i].battery.battery) -- devres_release_group(&wacom->hdev->dev, -- &remote->remotes[i].battery.bat_desc); -+ wacom_remote_destroy_battery(wacom, i); - - if (remote->remotes[i].group.name) - devres_release_group(&wacom->hdev->dev, -@@ -2551,7 +2561,6 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) - - remote->remotes[i].serial = 0; - remote->remotes[i].group.name = NULL; -- remote->remotes[i].battery.battery = NULL; - wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN; - } - } -@@ -2636,6 +2645,9 @@ static int wacom_remote_attach_battery(struct wacom *wacom, int index) - if (remote->remotes[index].battery.battery) - return 0; - -+ if (!remote->remotes[index].active_time) -+ return 0; -+ - if (wacom->led.groups[index].select == WACOM_STATUS_UNKNOWN) - return 0; - -@@ -2651,6 +2663,7 @@ static void wacom_remote_work(struct work_struct *work) - { - struct wacom *wacom = container_of(work, struct wacom, remote_work); - struct wacom_remote *remote = wacom->remote; -+ ktime_t kt = ktime_get(); - struct wacom_remote_data data; - unsigned long flags; - unsigned int count; -@@ -2677,6 +2690,10 @@ static void wacom_remote_work(struct work_struct *work) - serial = data.remote[i].serial; - if (data.remote[i].connected) { - -+ if (kt - remote->remotes[i].active_time > WACOM_REMOTE_BATTERY_TIMEOUT -+ && remote->remotes[i].active_time != 0) -+ wacom_remote_destroy_battery(wacom, i); -+ - if (remote->remotes[i].serial == serial) { - wacom_remote_attach_battery(wacom, i); - continue; -diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c -index 15cd0cabee2a9..c1270db121784 100644 ---- a/drivers/hid/wacom_wac.c -+++ b/drivers/hid/wacom_wac.c -@@ -1129,6 +1129,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) - if (index < 0 || !remote->remotes[index].registered) - goto out; - -+ remote->remotes[i].active_time = ktime_get(); - input = remote->remotes[index].input; - - input_report_key(input, BTN_0, (data[9] & 0x01)); -diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h -index ee21bb260f22f..2e7cc5e7a0cb7 100644 ---- a/drivers/hid/wacom_wac.h -+++ b/drivers/hid/wacom_wac.h -@@ -13,6 +13,7 @@ - #define WACOM_NAME_MAX 64 - #define WACOM_MAX_REMOTES 5 - #define WACOM_STATUS_UNKNOWN 255 -+#define WACOM_REMOTE_BATTERY_TIMEOUT 21000000000ll - - /* packet length for individual models */ - #define WACOM_PKGLEN_BBFUN 9 -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index fb1062a6394c1..9b5a2cb110b3e 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -528,11 +528,12 @@ config MMC_ALCOR - of Alcor Micro PCI-E card reader - - config MMC_AU1X -- tristate "Alchemy AU1XX0 MMC Card Interface support" -+ bool "Alchemy AU1XX0 MMC Card Interface support" - depends on MIPS_ALCHEMY -+ depends on MMC=y - help - This selects the AMD Alchemy(R) Multimedia card interface. -- If you have a Alchemy platform with a MMC slot, say Y or M here. -+ If you have a Alchemy platform with a MMC slot, say Y here. - - If unsure, say N. - -diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c -index 17c097cef7d45..5243fc0310589 100644 ---- a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c -@@ -8,7 +8,7 @@ - #include "enetc.h" - - int enetc_phc_index = -1; --EXPORT_SYMBOL(enetc_phc_index); -+EXPORT_SYMBOL_GPL(enetc_phc_index); - - static struct ptp_clock_info enetc_ptp_caps = { - .owner = THIS_MODULE, -diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c -index 68511597599e3..f7d392fce8c28 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c -+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c -@@ -465,6 +465,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, - BSS_CHANGED_BEACON_ENABLED)); - bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | - BSS_CHANGED_FILS_DISCOVERY)); -+ bool amsdu_en = wcid->amsdu; - - if (vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; -@@ -524,12 +525,14 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, - txwi[4] = 0; - - val = FIELD_PREP(MT_TXD5_PID, pid); -- if (pid >= MT_PACKET_ID_FIRST) -+ if (pid >= MT_PACKET_ID_FIRST) { - val |= MT_TXD5_TX_STATUS_HOST; -+ amsdu_en = amsdu_en && !is_mt7921(dev); -+ } - - txwi[5] = cpu_to_le32(val); - txwi[6] = 0; -- txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; -+ txwi[7] = amsdu_en ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; - - if (is_8023) - mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid); -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c -index 60fbbd1ac2f78..172ba7199485d 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c -@@ -1280,7 +1280,7 @@ mt7921_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) - return -EINVAL; - - if ((BIT(hweight8(tx_ant)) - 1) != tx_ant) -- tx_ant = BIT(ffs(tx_ant) - 1) - 1; -+ return -EINVAL; - - mt7921_mutex_acquire(dev); - -diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c -index be6838c252f09..2b6d996e393e0 100644 ---- a/drivers/pinctrl/pinctrl-amd.c -+++ b/drivers/pinctrl/pinctrl-amd.c -@@ -748,7 +748,7 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev, - break; - - default: -- dev_err(&gpio_dev->pdev->dev, "Invalid config param %04x\n", -+ dev_dbg(&gpio_dev->pdev->dev, "Invalid config param %04x\n", - param); - return -ENOTSUPP; - } -@@ -798,7 +798,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, - break; - - default: -- dev_err(&gpio_dev->pdev->dev, -+ dev_dbg(&gpio_dev->pdev->dev, - "Invalid config param %04x\n", param); - ret = -ENOTSUPP; - } -diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c -index 5db9c737c022f..db7216f14164e 100644 ---- a/drivers/rtc/rtc-ds1685.c -+++ b/drivers/rtc/rtc-ds1685.c -@@ -1434,7 +1434,7 @@ ds1685_rtc_poweroff(struct platform_device *pdev) - unreachable(); - } - } --EXPORT_SYMBOL(ds1685_rtc_poweroff); -+EXPORT_SYMBOL_GPL(ds1685_rtc_poweroff); - /* ----------------------------------------------------------------------- */ - - -diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c -index 003e972051240..3ea70d042f9a0 100644 ---- a/drivers/staging/rtl8712/os_intfs.c -+++ b/drivers/staging/rtl8712/os_intfs.c -@@ -323,6 +323,7 @@ int r8712_init_drv_sw(struct _adapter *padapter) - mp871xinit(padapter); - init_default_value(padapter); - r8712_InitSwLeds(padapter); -+ mutex_init(&padapter->mutex_start); - return ret; - } - -diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c -index 37364d3101e21..df05213f922f4 100644 ---- a/drivers/staging/rtl8712/usb_intf.c -+++ b/drivers/staging/rtl8712/usb_intf.c -@@ -567,7 +567,6 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, - if (rtl871x_load_fw(padapter)) - goto deinit_drv_sw; - init_completion(&padapter->rx_filter_ready); -- mutex_init(&padapter->mutex_start); - return 0; - - deinit_drv_sw: -diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c -index 6f6c4e9b77435..d6f682ed15811 100644 ---- a/drivers/tty/serial/qcom_geni_serial.c -+++ b/drivers/tty/serial/qcom_geni_serial.c -@@ -129,6 +129,7 @@ struct qcom_geni_serial_port { - u32 tx_fifo_width; - u32 rx_fifo_depth; - bool setup; -+ unsigned long clk_rate; - int (*handle_rx)(struct uart_port *uport, u32 bytes, bool drop); - unsigned int baud; - void *rx_fifo; -@@ -1061,6 +1062,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, - baud * sampling_rate, clk_rate, clk_div); - - uport->uartclk = clk_rate; -+ port->clk_rate = clk_rate; - dev_pm_opp_set_rate(uport->dev, clk_rate); - ser_clk_cfg = SER_CLK_EN; - ser_clk_cfg |= clk_div << CLK_DIV_SHFT; -@@ -1330,10 +1332,13 @@ static void qcom_geni_serial_pm(struct uart_port *uport, - - if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) { - geni_icc_enable(&port->se); -+ if (port->clk_rate) -+ dev_pm_opp_set_rate(uport->dev, port->clk_rate); - geni_se_resources_on(&port->se); - } else if (new_state == UART_PM_STATE_OFF && - old_state == UART_PM_STATE_ON) { - geni_se_resources_off(&port->se); -+ dev_pm_opp_set_rate(uport->dev, 0); - geni_icc_disable(&port->se); - } - } -diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c -index 93cf5f7888172..8411a0f312db0 100644 ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -1345,9 +1345,18 @@ static int sc16is7xx_gpio_direction_output(struct gpio_chip *chip, - state |= BIT(offset); - else - state &= ~BIT(offset); -- sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state); -+ -+ /* -+ * If we write IOSTATE first, and then IODIR, the output value is not -+ * transferred to the corresponding I/O pin. -+ * The datasheet states that each register bit will be transferred to -+ * the corresponding I/O pin programmed as output when writing to -+ * IOSTATE. Therefore, configure direction first with IODIR, and then -+ * set value after with IOSTATE. -+ */ - sc16is7xx_port_update(port, SC16IS7XX_IODIR_REG, BIT(offset), - BIT(offset)); -+ sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state); - - return 0; - } -@@ -1439,6 +1448,12 @@ static int sc16is7xx_probe(struct device *dev, - s->p[i].port.fifosize = SC16IS7XX_FIFO_SIZE; - s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; - s->p[i].port.iobase = i; -+ /* -+ * Use all ones as membase to make sure uart_configure_port() in -+ * serial_core.c does not abort for SPI/I2C devices where the -+ * membase address is not applicable. -+ */ -+ s->p[i].port.membase = (void __iomem *)~0; - s->p[i].port.iotype = UPIO_PORT; - s->p[i].port.uartclk = freq; - s->p[i].port.rs485_config = sc16is7xx_config_rs485; -diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c -index 60b4de0a4f76d..caa91117ba429 100644 ---- a/drivers/usb/chipidea/ci_hdrc_imx.c -+++ b/drivers/usb/chipidea/ci_hdrc_imx.c -@@ -175,10 +175,12 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) - if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) - data->ulpi = 1; - -- of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control", -- &data->emp_curr_control); -- of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust", -- &data->dc_vol_level_adjust); -+ if (of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control", -+ &data->emp_curr_control)) -+ data->emp_curr_control = -1; -+ if (of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust", -+ &data->dc_vol_level_adjust)) -+ data->dc_vol_level_adjust = -1; - - return data; - } -diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c -index 2318c7906acdb..a2cb4f48c84c6 100644 ---- a/drivers/usb/chipidea/usbmisc_imx.c -+++ b/drivers/usb/chipidea/usbmisc_imx.c -@@ -657,13 +657,15 @@ static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) - usbmisc->base + MX7D_USBNC_USB_CTRL2); - /* PHY tuning for signal quality */ - reg = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG1); -- if (data->emp_curr_control && data->emp_curr_control <= -+ if (data->emp_curr_control >= 0 && -+ data->emp_curr_control <= - (TXPREEMPAMPTUNE0_MASK >> TXPREEMPAMPTUNE0_BIT)) { - reg &= ~TXPREEMPAMPTUNE0_MASK; - reg |= (data->emp_curr_control << TXPREEMPAMPTUNE0_BIT); - } - -- if (data->dc_vol_level_adjust && data->dc_vol_level_adjust <= -+ if (data->dc_vol_level_adjust >= 0 && -+ data->dc_vol_level_adjust <= - (TXVREFTUNE0_MASK >> TXVREFTUNE0_BIT)) { - reg &= ~TXVREFTUNE0_MASK; - reg |= (data->dc_vol_level_adjust << TXVREFTUNE0_BIT); -diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c -index eaea944ebd2ce..10298b91731eb 100644 ---- a/drivers/usb/dwc3/dwc3-meson-g12a.c -+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c -@@ -938,6 +938,12 @@ static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev) - return ret; - } - -+ if (priv->drvdata->usb_post_init) { -+ ret = priv->drvdata->usb_post_init(priv); -+ if (ret) -+ return ret; -+ } -+ - return 0; - } - -diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c -index 119641761c3b4..f13930b4534c1 100644 ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -259,6 +259,7 @@ static void option_instat_callback(struct urb *urb); - #define QUECTEL_PRODUCT_EM05G 0x030a - #define QUECTEL_PRODUCT_EM060K 0x030b - #define QUECTEL_PRODUCT_EM05G_CS 0x030c -+#define QUECTEL_PRODUCT_EM05GV2 0x030e - #define QUECTEL_PRODUCT_EM05CN_SG 0x0310 - #define QUECTEL_PRODUCT_EM05G_SG 0x0311 - #define QUECTEL_PRODUCT_EM05CN 0x0312 -@@ -1190,6 +1191,8 @@ static const struct usb_device_id option_ids[] = { - .driver_info = RSVD(6) | ZLP }, - { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_GR, 0xff), - .driver_info = RSVD(6) | ZLP }, -+ { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05GV2, 0xff), -+ .driver_info = RSVD(4) | ZLP }, - { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_CS, 0xff), - .driver_info = RSVD(6) | ZLP }, - { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_RS, 0xff), -@@ -2232,6 +2235,10 @@ static const struct usb_device_id option_ids[] = { - .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, - { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0db, 0xff), /* Foxconn T99W265 MBIM */ - .driver_info = RSVD(3) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0ee, 0xff), /* Foxconn T99W368 MBIM */ -+ .driver_info = RSVD(3) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0f0, 0xff), /* Foxconn T99W373 MBIM */ -+ .driver_info = RSVD(3) }, - { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ - .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, - { USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */ -diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c -index 72f8d1e876004..816945913ed0d 100644 ---- a/drivers/usb/typec/tcpm/tcpci.c -+++ b/drivers/usb/typec/tcpm/tcpci.c -@@ -593,6 +593,10 @@ static int tcpci_init(struct tcpc_dev *tcpc) - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - -+ ret = tcpci_write16(tcpci, TCPC_FAULT_STATUS, TCPC_FAULT_STATUS_ALL_REG_RST_TO_DEFAULT); -+ if (ret < 0) -+ return ret; -+ - /* Handle vendor init */ - if (tcpci->data->init) { - ret = tcpci->data->init(tcpci, tcpci->data); -diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c -index d5950ef9d1f35..5f45b82dd1914 100644 ---- a/drivers/usb/typec/tcpm/tcpm.c -+++ b/drivers/usb/typec/tcpm/tcpm.c -@@ -2747,6 +2747,13 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, - port->sink_cap_done = true; - tcpm_set_state(port, ready_state(port), 0); - break; -+ /* -+ * Some port partners do not support GET_STATUS, avoid soft reset the link to -+ * prevent redundant power re-negotiation -+ */ -+ case GET_STATUS_SEND: -+ tcpm_set_state(port, ready_state(port), 0); -+ break; - case SRC_READY: - case SNK_READY: - if (port->vdm_state > VDM_STATE_READY) { -diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c -index 361f3c29897e8..1b91ac5be9610 100644 ---- a/fs/erofs/zdata.c -+++ b/fs/erofs/zdata.c -@@ -869,6 +869,8 @@ hitted: - cur = end - min_t(erofs_off_t, offset + end - map->m_la, end); - if (!(map->m_flags & EROFS_MAP_MAPPED)) { - zero_user_segment(page, cur, end); -+ ++spiltted; -+ tight = false; - goto next_part; - } - if (map->m_flags & EROFS_MAP_FRAGMENT) { -diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c -index 6ce8617b562d5..7342de296ec3c 100644 ---- a/fs/nilfs2/alloc.c -+++ b/fs/nilfs2/alloc.c -@@ -205,7 +205,8 @@ static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff, - int ret; - - spin_lock(lock); -- if (prev->bh && blkoff == prev->blkoff) { -+ if (prev->bh && blkoff == prev->blkoff && -+ likely(buffer_uptodate(prev->bh))) { - get_bh(prev->bh); - *bhp = prev->bh; - spin_unlock(lock); -diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c -index d4c0895a88116..f625872321cca 100644 ---- a/fs/nilfs2/inode.c -+++ b/fs/nilfs2/inode.c -@@ -1025,7 +1025,7 @@ int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh) - int err; - - spin_lock(&nilfs->ns_inode_lock); -- if (ii->i_bh == NULL) { -+ if (ii->i_bh == NULL || unlikely(!buffer_uptodate(ii->i_bh))) { - spin_unlock(&nilfs->ns_inode_lock); - err = nilfs_ifile_get_inode_block(ii->i_root->ifile, - inode->i_ino, pbh); -@@ -1034,7 +1034,10 @@ int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh) - spin_lock(&nilfs->ns_inode_lock); - if (ii->i_bh == NULL) - ii->i_bh = *pbh; -- else { -+ else if (unlikely(!buffer_uptodate(ii->i_bh))) { -+ __brelse(ii->i_bh); -+ ii->i_bh = *pbh; -+ } else { - brelse(*pbh); - *pbh = ii->i_bh; - } -diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c -index 21e8260112c8f..a4a147a983e0a 100644 ---- a/fs/nilfs2/segment.c -+++ b/fs/nilfs2/segment.c -@@ -725,6 +725,11 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, - struct page *page = pvec.pages[i]; - - lock_page(page); -+ if (unlikely(page->mapping != mapping)) { -+ /* Exclude pages removed from the address space */ -+ unlock_page(page); -+ continue; -+ } - if (!page_has_buffers(page)) - create_empty_buffers(page, i_blocksize(inode), 0); - unlock_page(page); -diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c -index 5e5e120edcc22..15e5684e328c1 100644 ---- a/fs/smb/server/auth.c -+++ b/fs/smb/server/auth.c -@@ -355,6 +355,9 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob, - if (blob_len < (u64)sess_key_off + sess_key_len) - return -EINVAL; - -+ if (sess_key_len > CIFS_KEY_SIZE) -+ return -EINVAL; -+ - ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL); - if (!ctx_arc4) - return -ENOMEM; -diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c -index 4b210cdd75569..c81aee9ce7ec4 100644 ---- a/fs/smb/server/oplock.c -+++ b/fs/smb/server/oplock.c -@@ -1492,7 +1492,7 @@ struct create_context *smb2_find_context_vals(void *open_req, const char *tag, i - name_len < 4 || - name_off + name_len > cc_len || - (value_off & 0x7) != 0 || -- (value_off && (value_off < name_off + name_len)) || -+ (value_len && value_off < name_off + (name_len < 8 ? 8 : name_len)) || - ((u64)value_off + value_len > cc_len)) - return ERR_PTR(-EINVAL); - -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index f8ca44622d909..9b621fd993bb7 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -4322,7 +4322,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, - if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) - name_len -= XATTR_USER_PREFIX_LEN; - -- ptr = (char *)(&eainfo->name + name_len + 1); -+ ptr = eainfo->name + name_len + 1; - buf_free_len -= (offsetof(struct smb2_ea_info, name) + - name_len + 1); - /* bailout if xattr can't fit in buf_free_len */ -diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h -index dd10f8031606b..665a837378540 100644 ---- a/fs/smb/server/smb2pdu.h -+++ b/fs/smb/server/smb2pdu.h -@@ -410,7 +410,7 @@ struct smb2_ea_info { - __u8 Flags; - __u8 EaNameLength; - __le16 EaValueLength; -- char name[1]; -+ char name[]; - /* optionally followed by value */ - } __packed; /* level 15 Query */ - -diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c -index c06efc020bd95..7578200f63b1d 100644 ---- a/fs/smb/server/transport_rdma.c -+++ b/fs/smb/server/transport_rdma.c -@@ -1366,24 +1366,35 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, - LIST_HEAD(msg_list); - char *desc_buf; - int credits_needed; -- unsigned int desc_buf_len; -- size_t total_length = 0; -+ unsigned int desc_buf_len, desc_num = 0; - - if (t->status != SMB_DIRECT_CS_CONNECTED) - return -ENOTCONN; - -+ if (buf_len > t->max_rdma_rw_size) -+ return -EINVAL; -+ - /* calculate needed credits */ - credits_needed = 0; - desc_buf = buf; - for (i = 0; i < desc_len / sizeof(*desc); i++) { -+ if (!buf_len) -+ break; -+ - desc_buf_len = le32_to_cpu(desc[i].length); -+ if (!desc_buf_len) -+ return -EINVAL; -+ -+ if (desc_buf_len > buf_len) { -+ desc_buf_len = buf_len; -+ desc[i].length = cpu_to_le32(desc_buf_len); -+ buf_len = 0; -+ } - - credits_needed += calc_rw_credits(t, desc_buf, desc_buf_len); - desc_buf += desc_buf_len; -- total_length += desc_buf_len; -- if (desc_buf_len == 0 || total_length > buf_len || -- total_length > t->max_rdma_rw_size) -- return -EINVAL; -+ buf_len -= desc_buf_len; -+ desc_num++; - } - - ksmbd_debug(RDMA, "RDMA %s, len %#x, needed credits %#x\n", -@@ -1395,7 +1406,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, - - /* build rdma_rw_ctx for each descriptor */ - desc_buf = buf; -- for (i = 0; i < desc_len / sizeof(*desc); i++) { -+ for (i = 0; i < desc_num; i++) { - msg = kzalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) + - sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL); - if (!msg) { -diff --git a/include/linux/usb/tcpci.h b/include/linux/usb/tcpci.h -index 17657451c762c..77eb40b918d7d 100644 ---- a/include/linux/usb/tcpci.h -+++ b/include/linux/usb/tcpci.h -@@ -103,6 +103,7 @@ - #define TCPC_POWER_STATUS_SINKING_VBUS BIT(0) - - #define TCPC_FAULT_STATUS 0x1f -+#define TCPC_FAULT_STATUS_ALL_REG_RST_TO_DEFAULT BIT(7) - - #define TCPC_ALERT_EXTENDED 0x21 - -diff --git a/kernel/module/main.c b/kernel/module/main.c -index 7a6f43d2b7757..7a376e26de85b 100644 ---- a/kernel/module/main.c -+++ b/kernel/module/main.c -@@ -1214,12 +1214,20 @@ void *__symbol_get(const char *symbol) - }; - - preempt_disable(); -- if (!find_symbol(&fsa) || strong_try_module_get(fsa.owner)) { -- preempt_enable(); -- return NULL; -+ if (!find_symbol(&fsa)) -+ goto fail; -+ if (fsa.license != GPL_ONLY) { -+ pr_warn("failing symbol_get of non-GPLONLY symbol %s.\n", -+ symbol); -+ goto fail; - } -+ if (strong_try_module_get(fsa.owner)) -+ goto fail; - preempt_enable(); - return (void *)kernel_symbol_value(fsa.sym); -+fail: -+ preempt_enable(); -+ return NULL; - } - EXPORT_SYMBOL_GPL(__symbol_get); - -diff --git a/sound/usb/stream.c b/sound/usb/stream.c -index f10f4e6d3fb85..3d4add94e367d 100644 ---- a/sound/usb/stream.c -+++ b/sound/usb/stream.c -@@ -1093,6 +1093,7 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip, - int i, altno, err, stream; - struct audioformat *fp = NULL; - struct snd_usb_power_domain *pd = NULL; -+ bool set_iface_first; - int num, protocol; - - dev = chip->dev; -@@ -1223,11 +1224,19 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip, - return err; - } - -+ set_iface_first = false; -+ if (protocol == UAC_VERSION_1 || -+ (chip->quirk_flags & QUIRK_FLAG_SET_IFACE_FIRST)) -+ set_iface_first = true; -+ - /* try to set the interface... */ - usb_set_interface(chip->dev, iface_no, 0); -+ if (set_iface_first) -+ usb_set_interface(chip->dev, iface_no, altno); - snd_usb_init_pitch(chip, fp); - snd_usb_init_sample_rate(chip, fp, fp->rate_max); -- usb_set_interface(chip->dev, iface_no, altno); -+ if (!set_iface_first) -+ usb_set_interface(chip->dev, iface_no, altno); - } - return 0; - } diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.52-53.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.52-53.patch deleted file mode 100644 index 29b394b8d6f4..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.52-53.patch +++ /dev/null @@ -1,23057 +0,0 @@ -diff --git a/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo b/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo -index 531fe9d6b40aa..c7393b4dd2d88 100644 ---- a/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo -+++ b/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo -@@ -5,6 +5,6 @@ Description: - Indicates whether or not this SBE device has experienced a - timeout; i.e. the SBE did not respond within the time allotted - by the driver. A value of 1 indicates that a timeout has -- ocurred and no transfers have completed since the timeout. A -- value of 0 indicates that no timeout has ocurred, or if one -- has, more recent transfers have completed successful. -+ occurred and no transfers have completed since the timeout. A -+ value of 0 indicates that no timeout has occurred, or if one -+ has, more recent transfers have completed successfully. -diff --git a/Documentation/ABI/testing/sysfs-driver-chromeos-acpi b/Documentation/ABI/testing/sysfs-driver-chromeos-acpi -index c308926e1568a..7c8e129fc1005 100644 ---- a/Documentation/ABI/testing/sysfs-driver-chromeos-acpi -+++ b/Documentation/ABI/testing/sysfs-driver-chromeos-acpi -@@ -134,4 +134,4 @@ KernelVersion: 5.19 - Description: - Returns the verified boot data block shared between the - firmware verification step and the kernel verification step -- (binary). -+ (hex dump). -diff --git a/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml -index 1289605456408..55800fb0221d0 100644 ---- a/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml -+++ b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml -@@ -23,6 +23,7 @@ properties: - - connector: - $ref: /schemas/connector/usb-connector.yaml# -+ unevaluatedProperties: false - - ports: - $ref: /schemas/graph.yaml#/properties/ports -diff --git a/Documentation/scsi/scsi_mid_low_api.rst b/Documentation/scsi/scsi_mid_low_api.rst -index a8c5bd15a4400..edfd179b9c7cc 100644 ---- a/Documentation/scsi/scsi_mid_low_api.rst -+++ b/Documentation/scsi/scsi_mid_low_api.rst -@@ -1190,11 +1190,11 @@ Members of interest: - - pointer to scsi_device object that this command is - associated with. - resid -- - an LLD should set this signed integer to the requested -+ - an LLD should set this unsigned integer to the requested - transfer length (i.e. 'request_bufflen') less the number - of bytes that are actually transferred. 'resid' is - preset to 0 so an LLD can ignore it if it cannot detect -- underruns (overruns should be rare). If possible an LLD -+ underruns (overruns should not be reported). An LLD - should set 'resid' prior to invoking 'done'. The most - interesting case is data transfers from a SCSI target - device (e.g. READs) that underrun. -diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst -index cd33857d947d3..0ef49647c90bd 100644 ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst -@@ -2923,6 +2923,13 @@ This structure contains all loop filter related parameters. See sections - - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - - PocLtCurr as described in section 8.3.2 "Decoding process for reference - picture set": provides the index of the long term references in DPB array. -+ * - __u8 -+ - ``num_delta_pocs_of_ref_rps_idx`` -+ - When the short_term_ref_pic_set_sps_flag in the slice header is equal to 0, -+ it is the same as the derived value NumDeltaPocs[RefRpsIdx]. It can be used to parse -+ the RPS data in slice headers instead of skipping it with @short_term_ref_pic_set_size. -+ When the value of short_term_ref_pic_set_sps_flag in the slice header is -+ equal to 1, num_delta_pocs_of_ref_rps_idx shall be set to 0. - * - struct :c:type:`v4l2_hevc_dpb_entry` - - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - - The decoded picture buffer, for meta-data about reference frames. -diff --git a/Makefile b/Makefile -index 82aaa3ae7395b..35fc0d62898dc 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 52 -+SUBLEVEL = 53 - EXTRAVERSION = - NAME = Curry Ramen - -@@ -1291,7 +1291,7 @@ prepare0: archprepare - # All the preparing.. - prepare: prepare0 - ifdef CONFIG_RUST -- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v -+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh - $(Q)$(MAKE) $(build)=rust - endif - -@@ -1817,7 +1817,7 @@ $(DOC_TARGETS): - # "Is Rust available?" target - PHONY += rustavailable - rustavailable: -- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v && echo "Rust is available!" -+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh && echo "Rust is available!" - - # Documentation target - # -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 6aa7dc4db2fc8..df6d905eeb877 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -331,6 +331,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \ - kirkwood-iconnect.dtb \ - kirkwood-iomega_ix2_200.dtb \ - kirkwood-is2.dtb \ -+ kirkwood-km_fixedeth.dtb \ - kirkwood-km_kirkwood.dtb \ - kirkwood-l-50.dtb \ - kirkwood-laplug.dtb \ -@@ -861,7 +862,10 @@ dtb-$(CONFIG_ARCH_OMAP3) += \ - am3517-craneboard.dtb \ - am3517-evm.dtb \ - am3517_mt_ventoux.dtb \ -+ logicpd-torpedo-35xx-devkit.dtb \ - logicpd-torpedo-37xx-devkit.dtb \ -+ logicpd-torpedo-37xx-devkit-28.dtb \ -+ logicpd-som-lv-35xx-devkit.dtb \ - logicpd-som-lv-37xx-devkit.dtb \ - omap3430-sdp.dtb \ - omap3-beagle.dtb \ -@@ -1527,6 +1531,8 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ - armada-388-helios4.dtb \ - armada-388-rd.dtb - dtb-$(CONFIG_MACH_ARMADA_39X) += \ -+ armada-390-db.dtb \ -+ armada-395-gp.dtb \ - armada-398-db.dtb - dtb-$(CONFIG_MACH_ARMADA_XP) += \ - armada-xp-axpwifiap.dtb \ -@@ -1556,6 +1562,7 @@ dtb-$(CONFIG_MACH_DOVE) += \ - dtb-$(CONFIG_ARCH_MEDIATEK) += \ - mt2701-evb.dtb \ - mt6580-evbp1.dtb \ -+ mt6582-prestigio-pmt5008-3g.dtb \ - mt6589-aquaris5.dtb \ - mt6589-fairphone-fp1.dtb \ - mt6592-evb.dtb \ -@@ -1608,6 +1615,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ - aspeed-bmc-intel-s2600wf.dtb \ - aspeed-bmc-inspur-fp5280g2.dtb \ - aspeed-bmc-inspur-nf5280m6.dtb \ -+ aspeed-bmc-inspur-on5263m5.dtb \ - aspeed-bmc-lenovo-hr630.dtb \ - aspeed-bmc-lenovo-hr855xg2.dtb \ - aspeed-bmc-microsoft-olympus.dtb \ -diff --git a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts -index e20b6d2eb274a..1e23e0a807819 100644 ---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts -+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts -@@ -46,3 +46,16 @@ - }; - }; - }; -+ -+&gmac0 { -+ phy-mode = "rgmii"; -+ phy-handle = <&bcm54210e>; -+ -+ mdio { -+ /delete-node/ switch@1e; -+ -+ bcm54210e: ethernet-phy@0 { -+ reg = <0>; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts -index 9d863570fcf3a..5dbb950c8113e 100644 ---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts -+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts -@@ -83,3 +83,16 @@ - }; - }; - }; -+ -+&gmac0 { -+ phy-mode = "rgmii"; -+ phy-handle = <&bcm54210e>; -+ -+ mdio { -+ /delete-node/ switch@1e; -+ -+ bcm54210e: ethernet-phy@0 { -+ reg = <0>; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts -index 55b92645b0f1f..b7c7bf0be76f4 100644 ---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts -+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts -@@ -135,8 +135,8 @@ - label = "lan4"; - }; - -- port@5 { -- reg = <5>; -+ port@8 { -+ reg = <8>; - label = "cpu"; - ethernet = <&gmac0>; - }; -diff --git a/arch/arm/boot/dts/bcm53573.dtsi b/arch/arm/boot/dts/bcm53573.dtsi -index 3f03a381db0f2..eed1a6147f0bf 100644 ---- a/arch/arm/boot/dts/bcm53573.dtsi -+++ b/arch/arm/boot/dts/bcm53573.dtsi -@@ -127,6 +127,9 @@ - - pcie0: pcie@2000 { - reg = <0x00002000 0x1000>; -+ -+ #address-cells = <3>; -+ #size-cells = <2>; - }; - - usb2: usb2@4000 { -@@ -156,8 +159,6 @@ - }; - - ohci: usb@d000 { -- #usb-cells = <0>; -- - compatible = "generic-ohci"; - reg = <0xd000 0x1000>; - interrupt-parent = <&gic>; -diff --git a/arch/arm/boot/dts/bcm947189acdbmr.dts b/arch/arm/boot/dts/bcm947189acdbmr.dts -index 16e70a264faf5..458bb6e2f5728 100644 ---- a/arch/arm/boot/dts/bcm947189acdbmr.dts -+++ b/arch/arm/boot/dts/bcm947189acdbmr.dts -@@ -60,9 +60,9 @@ - spi { - compatible = "spi-gpio"; - num-chipselects = <1>; -- gpio-sck = <&chipcommon 21 0>; -- gpio-miso = <&chipcommon 22 0>; -- gpio-mosi = <&chipcommon 23 0>; -+ sck-gpios = <&chipcommon 21 0>; -+ miso-gpios = <&chipcommon 22 0>; -+ mosi-gpios = <&chipcommon 23 0>; - cs-gpios = <&chipcommon 24 0>; - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi -index 11b9321badc51..667568aa4326a 100644 ---- a/arch/arm/boot/dts/imx7s.dtsi -+++ b/arch/arm/boot/dts/imx7s.dtsi -@@ -1184,6 +1184,8 @@ - <&clks IMX7D_USDHC1_ROOT_CLK>; - clock-names = "ipg", "ahb", "per"; - bus-width = <4>; -+ fsl,tuning-step = <2>; -+ fsl,tuning-start-tap = <20>; - status = "disabled"; - }; - -@@ -1196,6 +1198,8 @@ - <&clks IMX7D_USDHC2_ROOT_CLK>; - clock-names = "ipg", "ahb", "per"; - bus-width = <4>; -+ fsl,tuning-step = <2>; -+ fsl,tuning-start-tap = <20>; - status = "disabled"; - }; - -@@ -1208,6 +1212,8 @@ - <&clks IMX7D_USDHC3_ROOT_CLK>; - clock-names = "ipg", "ahb", "per"; - bus-width = <4>; -+ fsl,tuning-step = <2>; -+ fsl,tuning-start-tap = <20>; - status = "disabled"; - }; - -diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi -index 02e13d8c222a0..b5e0ed4923b59 100644 ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -228,9 +228,12 @@ - interrupts = , ; - interrupt-names = "hc_irq", "pwr_irq"; - bus-width = <8>; -- clocks = <&gcc GCC_SDCC1_AHB_CLK>, <&gcc GCC_SDCC1_APPS_CLK>, -- <&gcc GCC_DCD_XO_CLK>; -- clock-names = "iface", "core", "xo"; -+ clocks = <&gcc GCC_SDCC1_AHB_CLK>, -+ <&gcc GCC_SDCC1_APPS_CLK>, -+ <&xo>; -+ clock-names = "iface", -+ "core", -+ "xo"; - status = "disabled"; - }; - -diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts -index 17097da36f5ed..0b07b3c319604 100644 ---- a/arch/arm/boot/dts/s3c6410-mini6410.dts -+++ b/arch/arm/boot/dts/s3c6410-mini6410.dts -@@ -51,7 +51,7 @@ - - ethernet@18000000 { - compatible = "davicom,dm9000"; -- reg = <0x18000000 0x2 0x18000004 0x2>; -+ reg = <0x18000000 0x2>, <0x18000004 0x2>; - interrupt-parent = <&gpn>; - interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; - davicom,no-eeprom; -diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts -index fbae768d65e27..901e7197b1368 100644 ---- a/arch/arm/boot/dts/s5pv210-smdkv210.dts -+++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts -@@ -41,7 +41,7 @@ - - ethernet@a8000000 { - compatible = "davicom,dm9000"; -- reg = <0xA8000000 0x2 0xA8000002 0x2>; -+ reg = <0xa8000000 0x2>, <0xa8000002 0x2>; - interrupt-parent = <&gph1>; - interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; - local-mac-address = [00 00 de ad be ef]; -@@ -55,6 +55,14 @@ - default-brightness-level = <6>; - pinctrl-names = "default"; - pinctrl-0 = <&pwm3_out>; -+ power-supply = <&dc5v_reg>; -+ }; -+ -+ dc5v_reg: regulator-0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "DC5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; - }; - }; - -diff --git a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi -index d540550f7da26..fd89542c69c93 100644 ---- a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi -+++ b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi -@@ -68,11 +68,6 @@ - reg = <0x38000000 0x10000>; - no-map; - }; -- -- gpu_reserved: gpu@dc000000 { -- reg = <0xdc000000 0x4000000>; -- no-map; -- }; - }; - - led: gpio_leds { -@@ -102,9 +97,11 @@ - adc1: adc@0 { - pinctrl-names = "default"; - pinctrl-0 = <&adc1_in6_pins_a>; -- st,min-sample-time-nsecs = <5000>; -- st,adc-channels = <6>; - status = "disabled"; -+ channel@6 { -+ reg = <6>; -+ st,min-sample-time-ns = <5000>; -+ }; - }; - - adc2: adc@100 { -@@ -173,7 +170,7 @@ - phy-handle = <&phy0>; - st,eth-ref-clk-sel; - -- mdio0 { -+ mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; -@@ -183,10 +180,6 @@ - }; - }; - --&gpu { -- contiguous-area = <&gpu_reserved>; --}; -- - &hash1 { - status = "okay"; - }; -@@ -375,8 +368,8 @@ - &m4_rproc { - memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, - <&vdev0vring1>, <&vdev0buffer>; -- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; -- mbox-names = "vq0", "vq1", "shutdown"; -+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; -+ mbox-names = "vq0", "vq1", "shutdown", "detach"; - interrupt-parent = <&exti>; - interrupts = <68 1>; - interrupt-names = "wdg"; -diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts b/arch/arm/boot/dts/stm32mp157c-ev1.dts -index 050c3c27a4203..b72d5e8aa4669 100644 ---- a/arch/arm/boot/dts/stm32mp157c-ev1.dts -+++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts -@@ -144,7 +144,7 @@ - max-speed = <1000>; - phy-handle = <&phy0>; - -- mdio0 { -+ mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; -diff --git a/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts b/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts -index e8d2ec41d5374..cb00ce7cec8b1 100644 ---- a/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts -+++ b/arch/arm/boot/dts/stm32mp157c-lxa-mc1.dts -@@ -112,7 +112,7 @@ - phy-handle = <ðphy>; - status = "okay"; - -- mdio0 { -+ mdio { - compatible = "snps,dwmac-mdio"; - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi -index 2d9461006810c..cf74852514906 100644 ---- a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi -+++ b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi -@@ -62,11 +62,6 @@ - reg = <0x38000000 0x10000>; - no-map; - }; -- -- gpu_reserved: gpu@d4000000 { -- reg = <0xd4000000 0x4000000>; -- no-map; -- }; - }; - - led { -@@ -80,11 +75,6 @@ - }; - }; - --&gpu { -- contiguous-area = <&gpu_reserved>; -- status = "okay"; --}; -- - &i2c2 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c2_pins_a>; -@@ -240,8 +230,8 @@ - &m4_rproc { - memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, - <&vdev0vring1>, <&vdev0buffer>; -- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; -- mbox-names = "vq0", "vq1", "shutdown"; -+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; -+ mbox-names = "vq0", "vq1", "shutdown", "detach"; - interrupt-parent = <&exti>; - interrupts = <68 1>; - status = "okay"; -diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts -index ed66d25b8bf3d..a8b3f7a547036 100644 ---- a/arch/arm/boot/dts/stm32mp157c-odyssey.dts -+++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts -@@ -41,7 +41,7 @@ - assigned-clock-rates = <125000000>; /* Clock PLL4 to 750Mhz in ATF/U-Boot */ - st,eth-clk-sel; - -- mdio0 { -+ mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; -diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi -index d3b85a8764d74..74a11ccc5333f 100644 ---- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi -+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi -@@ -80,17 +80,19 @@ - vdda-supply = <&vdda>; - vref-supply = <&vdda>; - status = "okay"; -+}; - -- adc1: adc@0 { -- st,min-sample-time-nsecs = <5000>; -- st,adc-channels = <0>; -- status = "okay"; -+&adc1 { -+ channel@0 { -+ reg = <0>; -+ st,min-sample-time-ns = <5000>; - }; -+}; - -- adc2: adc@100 { -- st,adc-channels = <1>; -- st,min-sample-time-nsecs = <5000>; -- status = "okay"; -+&adc2 { -+ channel@1 { -+ reg = <1>; -+ st,min-sample-time-ns = <5000>; - }; - }; - -@@ -125,7 +127,7 @@ - max-speed = <100>; - phy-handle = <&phy0>; - -- mdio0 { -+ mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; -@@ -414,8 +416,8 @@ - &m4_rproc { - memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, - <&vdev0vring1>, <&vdev0buffer>; -- mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; -- mbox-names = "vq0", "vq1", "shutdown"; -+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; -+ mbox-names = "vq0", "vq1", "shutdown", "detach"; - interrupt-parent = <&exti>; - interrupts = <68 1>; - status = "okay"; -diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi -index f068e4fcc404f..b7ba43865514d 100644 ---- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi -+++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi -@@ -112,17 +112,39 @@ - vdda-supply = <&vdda>; - vref-supply = <&vdda>; - status = "okay"; -+}; - -- adc1: adc@0 { -- st,adc-channels = <0 1 6>; -- st,min-sample-time-nsecs = <5000>; -- status = "okay"; -+&adc1 { -+ channel@0 { -+ reg = <0>; -+ st,min-sample-time-ns = <5000>; - }; - -- adc2: adc@100 { -- st,adc-channels = <0 1 2>; -- st,min-sample-time-nsecs = <5000>; -- status = "okay"; -+ channel@1 { -+ reg = <1>; -+ st,min-sample-time-ns = <5000>; -+ }; -+ -+ channel@6 { -+ reg = <6>; -+ st,min-sample-time-ns = <5000>; -+ }; -+}; -+ -+&adc2 { -+ channel@0 { -+ reg = <0>; -+ st,min-sample-time-ns = <5000>; -+ }; -+ -+ channel@1 { -+ reg = <1>; -+ st,min-sample-time-ns = <5000>; -+ }; -+ -+ channel@2 { -+ reg = <2>; -+ st,min-sample-time-ns = <5000>; - }; - }; - -@@ -151,7 +173,7 @@ - max-speed = <1000>; - phy-handle = <&phy0>; - -- mdio0 { -+ mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; -diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi -index bb4ac6c13cbd3..39af79dc654cc 100644 ---- a/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi -+++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-drc-compact.dtsi -@@ -78,7 +78,7 @@ - max-speed = <1000>; - phy-handle = <&phy0>; - -- mdio0 { -+ mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; -diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi -index fdc48536e97d1..73a6a7b278b90 100644 ---- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi -+++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi -@@ -141,7 +141,7 @@ - max-speed = <1000>; - phy-handle = <&phy0>; - -- mdio0 { -+ mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "snps,dwmac-mdio"; -diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h -index dfeed440254a8..fe4326d938c18 100644 ---- a/arch/arm/include/asm/syscall.h -+++ b/arch/arm/include/asm/syscall.h -@@ -25,6 +25,9 @@ static inline int syscall_get_nr(struct task_struct *task, - if (IS_ENABLED(CONFIG_AEABI) && !IS_ENABLED(CONFIG_OABI_COMPAT)) - return task_thread_info(task)->abi_syscall; - -+ if (task_thread_info(task)->abi_syscall == -1) -+ return -1; -+ - return task_thread_info(task)->abi_syscall & __NR_SYSCALL_MASK; - } - -diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S -index 405a607b754f4..b413b541c3c71 100644 ---- a/arch/arm/kernel/entry-common.S -+++ b/arch/arm/kernel/entry-common.S -@@ -103,6 +103,7 @@ slow_work_pending: - cmp r0, #0 - beq no_work_pending - movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE) -+ str scno, [tsk, #TI_ABI_SYSCALL] @ make sure tracers see update - ldmia sp, {r0 - r6} @ have to reload r0 - r6 - b local_restart @ ... and off we go - ENDPROC(ret_fast_syscall) -diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c -index bfe88c6e60d58..cef106913ab7b 100644 ---- a/arch/arm/kernel/ptrace.c -+++ b/arch/arm/kernel/ptrace.c -@@ -785,8 +785,9 @@ long arch_ptrace(struct task_struct *child, long request, - break; - - case PTRACE_SET_SYSCALL: -- task_thread_info(child)->abi_syscall = data & -- __NR_SYSCALL_MASK; -+ if (data != -1) -+ data &= __NR_SYSCALL_MASK; -+ task_thread_info(child)->abi_syscall = data; - ret = 0; - break; - -diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c -index 2d747f6cffe8e..0eca44fc11926 100644 ---- a/arch/arm/mach-omap2/powerdomain.c -+++ b/arch/arm/mach-omap2/powerdomain.c -@@ -174,7 +174,7 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) - break; - case PWRDM_STATE_PREV: - prev = pwrdm_read_prev_pwrst(pwrdm); -- if (pwrdm->state != prev) -+ if (prev >= 0 && pwrdm->state != prev) - pwrdm->state_counter[prev]++; - if (prev == PWRDM_POWER_RET) - _update_logic_membank_counters(pwrdm); -diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts -index 7c569695b7052..2b4dbfac84a70 100644 ---- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts -+++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts -@@ -1312,6 +1312,7 @@ - - uartd: serial@70006300 { - compatible = "nvidia,tegra30-hsuart"; -+ reset-names = "serial"; - status = "okay"; - - bluetooth { -diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts -index 57ab753288144..f094011be9ed9 100644 ---- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts -+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts -@@ -2004,6 +2004,7 @@ - - serial@3100000 { - compatible = "nvidia,tegra194-hsuart"; -+ reset-names = "serial"; - status = "okay"; - }; - -diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -index e3e90ad92cc59..9650ae70c8723 100644 ---- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -@@ -289,9 +289,9 @@ - clock-names = "xclk"; - clock-frequency = <23880000>; - -- vdddo-supply = <&camera_vdddo_1v8>; -- vdda-supply = <&camera_vdda_2v8>; -- vddd-supply = <&camera_vddd_1v5>; -+ DOVDD-supply = <&camera_vdddo_1v8>; -+ AVDD-supply = <&camera_vdda_2v8>; -+ DVDD-supply = <&camera_vddd_1v5>; - - /* No camera mezzanine by default */ - status = "disabled"; -diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts -index d85e7f7c0835a..75f7b4f35fe82 100644 ---- a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts -+++ b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts -@@ -163,7 +163,7 @@ - pinctrl-0 = <&light_int_default>; - - vdd-supply = <&pm8916_l17>; -- vio-supply = <&pm8916_l6>; -+ vddio-supply = <&pm8916_l6>; - }; - - gyroscope@68 { -diff --git a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts -index 4e5264f4116a0..3bbafb68ba5c5 100644 ---- a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts -+++ b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts -@@ -81,7 +81,7 @@ - #size-cells = <0>; - interrupt-parent = <&tlmm>; - interrupts = <125 IRQ_TYPE_LEVEL_LOW>; -- vdda-supply = <&vreg_l6a_1p8>; -+ vio-supply = <&vreg_l6a_1p8>; - vdd-supply = <&vdd_3v2_tp>; - reset-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; - -diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi -index 9d6ec59d1cd3a..9de2248a385a5 100644 ---- a/arch/arm64/boot/dts/qcom/msm8996.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi -@@ -1063,7 +1063,7 @@ - reg-names = "dsi_ctrl"; - - interrupt-parent = <&mdss>; -- interrupts = <4>; -+ interrupts = <5>; - - clocks = <&mmcc MDSS_MDP_CLK>, - <&mmcc MDSS_BYTE1_CLK>, -@@ -3292,6 +3292,9 @@ - #size-cells = <1>; - ranges; - -+ interrupts = ; -+ interrupt-names = "hs_phy_irq"; -+ - clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>, - <&gcc GCC_USB20_MASTER_CLK>, - <&gcc GCC_USB20_MOCK_UTMI_CLK>, -diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi -index 29c60bb56ed5f..b00b8164c4aa2 100644 ---- a/arch/arm64/boot/dts/qcom/msm8998.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi -@@ -2418,10 +2418,10 @@ - - clocks = <&mmcc MNOC_AHB_CLK>, - <&mmcc BIMC_SMMU_AHB_CLK>, -- <&rpmcc RPM_SMD_MMAXI_CLK>, - <&mmcc BIMC_SMMU_AXI_CLK>; -- clock-names = "iface-mm", "iface-smmu", -- "bus-mm", "bus-smmu"; -+ clock-names = "iface-mm", -+ "iface-smmu", -+ "bus-smmu"; - - #global-interrupts = <0>; - interrupts = -@@ -2445,6 +2445,8 @@ - , - , - ; -+ -+ power-domains = <&mmcc BIMC_SMMU_GDSC>; - }; - - remoteproc_adsp: remoteproc@17300000 { -diff --git a/arch/arm64/boot/dts/qcom/pm6150l.dtsi b/arch/arm64/boot/dts/qcom/pm6150l.dtsi -index f02c223ef4485..06d729ff65a9d 100644 ---- a/arch/arm64/boot/dts/qcom/pm6150l.dtsi -+++ b/arch/arm64/boot/dts/qcom/pm6150l.dtsi -@@ -75,8 +75,9 @@ - pm6150l_wled: leds@d800 { - compatible = "qcom,pm6150l-wled"; - reg = <0xd800>, <0xd900>; -- interrupts = <0x5 0xd8 0x1 IRQ_TYPE_EDGE_RISING>; -- interrupt-names = "ovp"; -+ interrupts = <0x5 0xd8 0x1 IRQ_TYPE_EDGE_RISING>, -+ <0x5 0xd8 0x2 IRQ_TYPE_EDGE_RISING>; -+ interrupt-names = "ovp", "short"; - label = "backlight"; - - status = "disabled"; -diff --git a/arch/arm64/boot/dts/qcom/pm660l.dtsi b/arch/arm64/boot/dts/qcom/pm660l.dtsi -index 8aa0a5078772b..88606b996d690 100644 ---- a/arch/arm64/boot/dts/qcom/pm660l.dtsi -+++ b/arch/arm64/boot/dts/qcom/pm660l.dtsi -@@ -74,8 +74,9 @@ - pm660l_wled: leds@d800 { - compatible = "qcom,pm660l-wled"; - reg = <0xd800>, <0xd900>; -- interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>; -- interrupt-names = "ovp"; -+ interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>, -+ <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>; -+ interrupt-names = "ovp", "short"; - label = "backlight"; - - status = "disabled"; -diff --git a/arch/arm64/boot/dts/qcom/pm8350.dtsi b/arch/arm64/boot/dts/qcom/pm8350.dtsi -index 2dfeb99300d74..9ed9ba23e81e4 100644 ---- a/arch/arm64/boot/dts/qcom/pm8350.dtsi -+++ b/arch/arm64/boot/dts/qcom/pm8350.dtsi -@@ -8,7 +8,7 @@ - - / { - thermal-zones { -- pm8350_thermal: pm8350c-thermal { -+ pm8350_thermal: pm8350-thermal { - polling-delay-passive = <100>; - polling-delay = <0>; - thermal-sensors = <&pm8350_temp_alarm>; -diff --git a/arch/arm64/boot/dts/qcom/pm8350b.dtsi b/arch/arm64/boot/dts/qcom/pm8350b.dtsi -index f1c7bd9d079c2..05c1058988927 100644 ---- a/arch/arm64/boot/dts/qcom/pm8350b.dtsi -+++ b/arch/arm64/boot/dts/qcom/pm8350b.dtsi -@@ -8,7 +8,7 @@ - - / { - thermal-zones { -- pm8350b_thermal: pm8350c-thermal { -+ pm8350b_thermal: pm8350b-thermal { - polling-delay-passive = <100>; - polling-delay = <0>; - thermal-sensors = <&pm8350b_temp_alarm>; -diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi -index 82b60e988d0f5..49902a3e161d9 100644 ---- a/arch/arm64/boot/dts/qcom/pmi8994.dtsi -+++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi -@@ -54,8 +54,9 @@ - pmi8994_wled: wled@d800 { - compatible = "qcom,pmi8994-wled"; - reg = <0xd800>, <0xd900>; -- interrupts = <3 0xd8 0x02 IRQ_TYPE_EDGE_RISING>; -- interrupt-names = "short"; -+ interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>, -+ <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>; -+ interrupt-names = "ovp", "short"; - qcom,cabc; - qcom,external-pfet; - status = "disabled"; -diff --git a/arch/arm64/boot/dts/qcom/pmk8350.dtsi b/arch/arm64/boot/dts/qcom/pmk8350.dtsi -index f0d256d99e62e..29cfb6fca9bf7 100644 ---- a/arch/arm64/boot/dts/qcom/pmk8350.dtsi -+++ b/arch/arm64/boot/dts/qcom/pmk8350.dtsi -@@ -44,7 +44,7 @@ - }; - - pmk8350_adc_tm: adc-tm@3400 { -- compatible = "qcom,adc-tm7"; -+ compatible = "qcom,spmi-adc-tm5-gen2"; - reg = <0x3400>; - interrupts = <0x0 0x34 0x0 IRQ_TYPE_EDGE_RISING>; - #address-cells = <1>; -diff --git a/arch/arm64/boot/dts/qcom/pmr735b.dtsi b/arch/arm64/boot/dts/qcom/pmr735b.dtsi -index ec24c4478005a..f7473e2473224 100644 ---- a/arch/arm64/boot/dts/qcom/pmr735b.dtsi -+++ b/arch/arm64/boot/dts/qcom/pmr735b.dtsi -@@ -8,7 +8,7 @@ - - / { - thermal-zones { -- pmr735a_thermal: pmr735a-thermal { -+ pmr735b_thermal: pmr735b-thermal { - polling-delay-passive = <100>; - polling-delay = <0>; - thermal-sensors = <&pmr735b_temp_alarm>; -diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts -index 5e30349efd204..38ec8acb7c40d 100644 ---- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts -+++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts -@@ -57,7 +57,7 @@ - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - -- gpio = <&pmc8280_1_gpios 1 GPIO_ACTIVE_HIGH>; -+ gpio = <&pmc8280_1_gpios 2 GPIO_ACTIVE_HIGH>; - enable-active-high; - - pinctrl-names = "default"; -@@ -364,7 +364,7 @@ - }; - - misc_3p3_reg_en: misc-3p3-reg-en-state { -- pins = "gpio1"; -+ pins = "gpio2"; - function = "normal"; - }; - }; -diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts -index b2b744bb8a538..49d15432aeabf 100644 ---- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts -+++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts -@@ -347,7 +347,7 @@ - }; - - &tlmm { -- gpio-reserved-ranges = <70 2>, <74 6>, <83 4>, <125 2>, <128 2>, <154 7>; -+ gpio-reserved-ranges = <70 2>, <74 6>, <125 2>, <128 2>, <154 4>; - - kybd_default: kybd-default-state { - disable { -diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi -index 1afc960bab5c9..405835ad28bcd 100644 ---- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi -@@ -396,6 +396,7 @@ - firmware { - scm: scm { - compatible = "qcom,scm-sc8280xp", "qcom,scm"; -+ interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>; - }; - }; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi -index 51ee42e3c995c..d6918e6d19799 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi -@@ -14,6 +14,15 @@ - qcom,msm-id = <321 0x20001>; /* SDM845 v2.1 */ - qcom,board-id = <8 0>; - -+ aliases { -+ serial0 = &uart6; -+ serial1 = &uart9; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ - gpio-keys { - compatible = "gpio-keys"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi -index b7ba70857d0ad..52c9f5639f8a2 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi -@@ -1099,6 +1099,7 @@ - #clock-cells = <1>; - #reset-cells = <1>; - #power-domain-cells = <1>; -+ power-domains = <&rpmhpd SDM845_CX>; - }; - - qfprom@784000 { -@@ -2520,7 +2521,7 @@ - <0 0>, - <0 0>, - <0 0>, -- <0 300000000>; -+ <75000000 300000000>; - - status = "disabled"; - }; -diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi -index 35f621ef9da54..34c8de4f43fba 100644 ---- a/arch/arm64/boot/dts/qcom/sm6350.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi -@@ -306,11 +306,6 @@ - no-map; - }; - -- pil_gpu_mem: memory@8b715400 { -- reg = <0 0x8b715400 0 0x2000>; -- no-map; -- }; -- - pil_modem_mem: memory@8b800000 { - reg = <0 0x8b800000 0 0xf800000>; - no-map; -@@ -331,6 +326,11 @@ - no-map; - }; - -+ pil_gpu_mem: memory@f0d00000 { -+ reg = <0 0xf0d00000 0 0x1000>; -+ no-map; -+ }; -+ - debug_region: memory@ffb00000 { - reg = <0 0xffb00000 0 0xc0000>; - no-map; -diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi -index 78ae4b9eaa106..f049fb42e3ca8 100644 ---- a/arch/arm64/boot/dts/qcom/sm8150.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi -@@ -1196,7 +1196,7 @@ - dma-names = "tx", "rx"; - pinctrl-names = "default"; - pinctrl-0 = <&qup_i2c7_default>; -- interrupts = ; -+ interrupts = ; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; -diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts -index 356a81698731a..62590c6bd3067 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts -+++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts -@@ -14,3 +14,236 @@ - }; - - /delete-node/ &vreg_l7f_1p8; -+ -+&pm8009_gpios { -+ gpio-line-names = "NC", /* GPIO_1 */ -+ "CAM_PWR_LD_EN", -+ "WIDEC_PWR_EN", -+ "NC"; -+}; -+ -+&pm8150_gpios { -+ gpio-line-names = "VOL_DOWN_N", /* GPIO_1 */ -+ "OPTION_2", -+ "NC", -+ "PM_SLP_CLK_IN", -+ "OPTION_1", -+ "NC", -+ "NC", -+ "SP_ARI_PWR_ALARM", -+ "NC", -+ "NC"; /* GPIO_10 */ -+}; -+ -+&pm8150b_gpios { -+ gpio-line-names = "SNAPSHOT_N", /* GPIO_1 */ -+ "FOCUS_N", -+ "NC", -+ "NC", -+ "RF_LCD_ID_EN", -+ "NC", -+ "NC", -+ "LCD_ID", -+ "NC", -+ "WLC_EN_N", /* GPIO_10 */ -+ "NC", -+ "RF_ID"; -+}; -+ -+&pm8150l_gpios { -+ gpio-line-names = "NC", /* GPIO_1 */ -+ "PM3003A_EN", -+ "NC", -+ "NC", -+ "NC", -+ "AUX2_THERM", -+ "BB_HP_EN", -+ "FP_LDO_EN", -+ "PMX_RESET_N", -+ "AUX3_THERM", /* GPIO_10 */ -+ "DTV_PWR_EN", -+ "PM3003A_MODE"; -+}; -+ -+&tlmm { -+ gpio-line-names = "AP_CTI_IN", /* GPIO_0 */ -+ "MDM2AP_ERR_FATAL", -+ "AP_CTI_OUT", -+ "MDM2AP_STATUS", -+ "NFC_I2C_SDA", -+ "NFC_I2C_SCL", -+ "NFC_EN", -+ "NFC_CLK_REQ", -+ "NFC_ESE_PWR_REQ", -+ "DVDT_WRT_DET_AND", -+ "SPK_AMP_RESET_N", /* GPIO_10 */ -+ "SPK_AMP_INT_N", -+ "APPS_I2C_1_SDA", -+ "APPS_I2C_1_SCL", -+ "NC", -+ "TX_GTR_THRES_IN", -+ "HST_BT_UART_CTS", -+ "HST_BT_UART_RFR", -+ "HST_BT_UART_TX", -+ "HST_BT_UART_RX", -+ "HST_WLAN_EN", /* GPIO_20 */ -+ "HST_BT_EN", -+ "RGBC_IR_PWR_EN", -+ "FP_INT_N", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "NFC_ESE_SPI_MISO", -+ "NFC_ESE_SPI_MOSI", -+ "NFC_ESE_SPI_SCLK", /* GPIO_30 */ -+ "NFC_ESE_SPI_CS_N", -+ "WCD_RST_N", -+ "NC", -+ "SDM_DEBUG_UART_TX", -+ "SDM_DEBUG_UART_RX", -+ "TS_I2C_SDA", -+ "TS_I2C_SCL", -+ "TS_INT_N", -+ "FP_SPI_MISO", /* GPIO_40 */ -+ "FP_SPI_MOSI", -+ "FP_SPI_SCLK", -+ "FP_SPI_CS_N", -+ "APPS_I2C_0_SDA", -+ "APPS_I2C_0_SCL", -+ "DISP_ERR_FG", -+ "UIM2_DETECT_EN", -+ "NC", -+ "NC", -+ "NC", /* GPIO_50 */ -+ "NC", -+ "MDM_UART_CTS", -+ "MDM_UART_RFR", -+ "MDM_UART_TX", -+ "MDM_UART_RX", -+ "AP2MDM_STATUS", -+ "AP2MDM_ERR_FATAL", -+ "MDM_IPC_HS_UART_TX", -+ "MDM_IPC_HS_UART_RX", -+ "NC", /* GPIO_60 */ -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "USB_CC_DIR", -+ "DISP_VSYNC", -+ "NC", -+ "NC", -+ "CAM_PWR_B_CS", -+ "NC", /* GPIO_70 */ -+ "CAM_PWR_A_CS", -+ "SBU_SW_SEL", -+ "SBU_SW_OE", -+ "FP_RESET_N", -+ "FP_RESET_N", -+ "DISP_RESET_N", -+ "DEBUG_GPIO0", -+ "TRAY_DET", -+ "CAM2_RST_N", -+ "PCIE0_RST_N", -+ "PCIE0_CLK_REQ_N", /* GPIO_80 */ -+ "PCIE0_WAKE_N", -+ "DVDT_ENABLE", -+ "DVDT_WRT_DET_OR", -+ "NC", -+ "PCIE2_RST_N", -+ "PCIE2_CLK_REQ_N", -+ "PCIE2_WAKE_N", -+ "MDM_VFR_IRQ0", -+ "MDM_VFR_IRQ1", -+ "SW_SERVICE", /* GPIO_90 */ -+ "CAM_SOF", -+ "CAM1_RST_N", -+ "CAM0_RST_N", -+ "CAM0_MCLK", -+ "CAM1_MCLK", -+ "CAM2_MCLK", -+ "CAM3_MCLK", -+ "CAM4_MCLK", -+ "TOF_RST_N", -+ "NC", /* GPIO_100 */ -+ "CCI0_I2C_SDA", -+ "CCI0_I2C_SCL", -+ "CCI1_I2C_SDA", -+ "CCI1_I2C_SCL_", -+ "CCI2_I2C_SDA", -+ "CCI2_I2C_SCL", -+ "CCI3_I2C_SDA", -+ "CCI3_I2C_SCL", -+ "CAM3_RST_N", -+ "NFC_DWL_REQ", /* GPIO_110 */ -+ "NFC_IRQ", -+ "XVS", -+ "NC", -+ "RF_ID_EXTENSION", -+ "SPK_AMP_I2C_SDA", -+ "SPK_AMP_I2C_SCL", -+ "NC", -+ "NC", -+ "WLC_I2C_SDA", -+ "WLC_I2C_SCL", /* GPIO_120 */ -+ "ACC_COVER_OPEN", -+ "ALS_PROX_INT_N", -+ "ACCEL_INT", -+ "WLAN_SW_CTRL", -+ "CAMSENSOR_I2C_SDA", -+ "CAMSENSOR_I2C_SCL", -+ "UDON_SWITCH_SEL", -+ "WDOG_DISABLE", -+ "BAROMETER_INT", -+ "NC", /* GPIO_130 */ -+ "NC", -+ "FORCED_USB_BOOT", -+ "NC", -+ "NC", -+ "WLC_INT_N", -+ "NC", -+ "NC", -+ "RGBC_IR_INT", -+ "NC", -+ "NC", /* GPIO_140 */ -+ "NC", -+ "BT_SLIMBUS_CLK", -+ "BT_SLIMBUS_DATA", -+ "HW_ID_0", -+ "HW_ID_1", -+ "WCD_SWR_TX_CLK", -+ "WCD_SWR_TX_DATA0", -+ "WCD_SWR_TX_DATA1", -+ "WCD_SWR_RX_CLK", -+ "WCD_SWR_RX_DATA0", /* GPIO_150 */ -+ "WCD_SWR_RX_DATA1", -+ "SDM_DMIC_CLK1", -+ "SDM_DMIC_DATA1", -+ "SDM_DMIC_CLK2", -+ "SDM_DMIC_DATA2", -+ "SPK_AMP_I2S_CLK", -+ "SPK_AMP_I2S_WS", -+ "SPK_AMP_I2S_ASP_DIN", -+ "SPK_AMP_I2S_ASP_DOUT", -+ "COMPASS_I2C_SDA", /* GPIO_160 */ -+ "COMPASS_I2C_SCL", -+ "NC", -+ "NC", -+ "SSC_SPI_1_MISO", -+ "SSC_SPI_1_MOSI", -+ "SSC_SPI_1_CLK", -+ "SSC_SPI_1_CS_N", -+ "NC", -+ "NC", -+ "SSC_SENSOR_I2C_SDA", /* GPIO_170 */ -+ "SSC_SENSOR_I2C_SCL", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "HST_BLE_SNS_UART6_TX", -+ "HST_BLE_SNS_UART6_RX", -+ "HST_WLAN_UART_TX", -+ "HST_WLAN_UART_RX"; -+}; -diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts -index 5ecf7dafb2ec4..0e50661c1b4c1 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts -+++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts -@@ -20,6 +20,8 @@ - }; - - &gpio_keys { -+ pinctrl-0 = <&focus_n &snapshot_n &vol_down_n &g_assist_n>; -+ - g-assist-key { - label = "Google Assistant Key"; - linux,code = ; -@@ -30,6 +32,247 @@ - }; - }; - -+&pm8009_gpios { -+ gpio-line-names = "NC", /* GPIO_1 */ -+ "NC", -+ "WIDEC_PWR_EN", -+ "NC"; -+}; -+ -+&pm8150_gpios { -+ gpio-line-names = "VOL_DOWN_N", /* GPIO_1 */ -+ "OPTION_2", -+ "NC", -+ "PM_SLP_CLK_IN", -+ "OPTION_1", -+ "G_ASSIST_N", -+ "NC", -+ "SP_ARI_PWR_ALARM", -+ "NC", -+ "NC"; /* GPIO_10 */ -+ -+ g_assist_n: g-assist-n-state { -+ pins = "gpio6"; -+ function = "normal"; -+ power-source = <1>; -+ bias-pull-up; -+ input-enable; -+ }; -+}; -+ -+&pm8150b_gpios { -+ gpio-line-names = "SNAPSHOT_N", /* GPIO_1 */ -+ "FOCUS_N", -+ "NC", -+ "NC", -+ "RF_LCD_ID_EN", -+ "NC", -+ "NC", -+ "LCD_ID", -+ "NC", -+ "NC", /* GPIO_10 */ -+ "NC", -+ "RF_ID"; -+}; -+ -+&pm8150l_gpios { -+ gpio-line-names = "NC", /* GPIO_1 */ -+ "PM3003A_EN", -+ "NC", -+ "NC", -+ "NC", -+ "AUX2_THERM", -+ "BB_HP_EN", -+ "FP_LDO_EN", -+ "PMX_RESET_N", -+ "NC", /* GPIO_10 */ -+ "NC", -+ "PM3003A_MODE"; -+}; -+ -+&tlmm { -+ gpio-line-names = "AP_CTI_IN", /* GPIO_0 */ -+ "MDM2AP_ERR_FATAL", -+ "AP_CTI_OUT", -+ "MDM2AP_STATUS", -+ "NFC_I2C_SDA", -+ "NFC_I2C_SCL", -+ "NFC_EN", -+ "NFC_CLK_REQ", -+ "NFC_ESE_PWR_REQ", -+ "DVDT_WRT_DET_AND", -+ "SPK_AMP_RESET_N", /* GPIO_10 */ -+ "SPK_AMP_INT_N", -+ "APPS_I2C_1_SDA", -+ "APPS_I2C_1_SCL", -+ "NC", -+ "TX_GTR_THRES_IN", -+ "HST_BT_UART_CTS", -+ "HST_BT_UART_RFR", -+ "HST_BT_UART_TX", -+ "HST_BT_UART_RX", -+ "HST_WLAN_EN", /* GPIO_20 */ -+ "HST_BT_EN", -+ "RGBC_IR_PWR_EN", -+ "FP_INT_N", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "NFC_ESE_SPI_MISO", -+ "NFC_ESE_SPI_MOSI", -+ "NFC_ESE_SPI_SCLK", /* GPIO_30 */ -+ "NFC_ESE_SPI_CS_N", -+ "WCD_RST_N", -+ "NC", -+ "SDM_DEBUG_UART_TX", -+ "SDM_DEBUG_UART_RX", -+ "TS_I2C_SDA", -+ "TS_I2C_SCL", -+ "TS_INT_N", -+ "FP_SPI_MISO", /* GPIO_40 */ -+ "FP_SPI_MOSI", -+ "FP_SPI_SCLK", -+ "FP_SPI_CS_N", -+ "APPS_I2C_0_SDA", -+ "APPS_I2C_0_SCL", -+ "DISP_ERR_FG", -+ "UIM2_DETECT_EN", -+ "NC", -+ "NC", -+ "NC", /* GPIO_50 */ -+ "NC", -+ "MDM_UART_CTS", -+ "MDM_UART_RFR", -+ "MDM_UART_TX", -+ "MDM_UART_RX", -+ "AP2MDM_STATUS", -+ "AP2MDM_ERR_FATAL", -+ "MDM_IPC_HS_UART_TX", -+ "MDM_IPC_HS_UART_RX", -+ "NC", /* GPIO_60 */ -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "USB_CC_DIR", -+ "DISP_VSYNC", -+ "NC", -+ "NC", -+ "CAM_PWR_B_CS", -+ "NC", /* GPIO_70 */ -+ "FRONTC_PWR_EN", -+ "SBU_SW_SEL", -+ "SBU_SW_OE", -+ "FP_RESET_N", -+ "FP_RESET_N", -+ "DISP_RESET_N", -+ "DEBUG_GPIO0", -+ "TRAY_DET", -+ "CAM2_RST_N", -+ "PCIE0_RST_N", -+ "PCIE0_CLK_REQ_N", /* GPIO_80 */ -+ "PCIE0_WAKE_N", -+ "DVDT_ENABLE", -+ "DVDT_WRT_DET_OR", -+ "NC", -+ "PCIE2_RST_N", -+ "PCIE2_CLK_REQ_N", -+ "PCIE2_WAKE_N", -+ "MDM_VFR_IRQ0", -+ "MDM_VFR_IRQ1", -+ "SW_SERVICE", /* GPIO_90 */ -+ "CAM_SOF", -+ "CAM1_RST_N", -+ "CAM0_RST_N", -+ "CAM0_MCLK", -+ "CAM1_MCLK", -+ "CAM2_MCLK", -+ "CAM3_MCLK", -+ "NC", -+ "NC", -+ "NC", /* GPIO_100 */ -+ "CCI0_I2C_SDA", -+ "CCI0_I2C_SCL", -+ "CCI1_I2C_SDA", -+ "CCI1_I2C_SCL_", -+ "CCI2_I2C_SDA", -+ "CCI2_I2C_SCL", -+ "CCI3_I2C_SDA", -+ "CCI3_I2C_SCL", -+ "CAM3_RST_N", -+ "NFC_DWL_REQ", /* GPIO_110 */ -+ "NFC_IRQ", -+ "XVS", -+ "NC", -+ "RF_ID_EXTENSION", -+ "SPK_AMP_I2C_SDA", -+ "SPK_AMP_I2C_SCL", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "ACC_COVER_OPEN", -+ "ALS_PROX_INT_N", -+ "ACCEL_INT", -+ "WLAN_SW_CTRL", -+ "CAMSENSOR_I2C_SDA", -+ "CAMSENSOR_I2C_SCL", -+ "UDON_SWITCH_SEL", -+ "WDOG_DISABLE", -+ "BAROMETER_INT", -+ "NC", /* GPIO_130 */ -+ "NC", -+ "FORCED_USB_BOOT", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "RGBC_IR_INT", -+ "NC", -+ "NC", /* GPIO_140 */ -+ "NC", -+ "BT_SLIMBUS_CLK", -+ "BT_SLIMBUS_DATA", -+ "HW_ID_0", -+ "HW_ID_1", -+ "WCD_SWR_TX_CLK", -+ "WCD_SWR_TX_DATA0", -+ "WCD_SWR_TX_DATA1", -+ "WCD_SWR_RX_CLK", -+ "WCD_SWR_RX_DATA0", /* GPIO_150 */ -+ "WCD_SWR_RX_DATA1", -+ "SDM_DMIC_CLK1", -+ "SDM_DMIC_DATA1", -+ "SDM_DMIC_CLK2", -+ "SDM_DMIC_DATA2", -+ "SPK_AMP_I2S_CLK", -+ "SPK_AMP_I2S_WS", -+ "SPK_AMP_I2S_ASP_DIN", -+ "SPK_AMP_I2S_ASP_DOUT", -+ "COMPASS_I2C_SDA", /* GPIO_160 */ -+ "COMPASS_I2C_SCL", -+ "NC", -+ "NC", -+ "SSC_SPI_1_MISO", -+ "SSC_SPI_1_MOSI", -+ "SSC_SPI_1_CLK", -+ "SSC_SPI_1_CS_N", -+ "NC", -+ "NC", -+ "SSC_SENSOR_I2C_SDA", /* GPIO_170 */ -+ "SSC_SENSOR_I2C_SCL", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "HST_BLE_SNS_UART6_TX", -+ "HST_BLE_SNS_UART6_RX", -+ "HST_WLAN_UART_TX", -+ "HST_WLAN_UART_RX"; -+}; -+ - &vreg_l2f_1p3 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; -diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi -index 390b90a8ddf70..3b710c6a326a5 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi -@@ -51,12 +51,26 @@ - gpio_keys: gpio-keys { - compatible = "gpio-keys"; - -- /* -- * Camera focus (light press) and camera snapshot (full press) -- * seem not to work properly.. Adding the former one stalls the CPU -- * and the latter kills the volume down key for whatever reason. In any -- * case, they are both on &pm8150b_gpios: camera focus(2), camera snapshot(1). -- */ -+ pinctrl-0 = <&focus_n &snapshot_n &vol_down_n>; -+ pinctrl-names = "default"; -+ -+ key-camera-focus { -+ label = "Camera Focus"; -+ linux,code = ; -+ gpios = <&pm8150b_gpios 2 GPIO_ACTIVE_LOW>; -+ debounce-interval = <15>; -+ linux,can-disable; -+ wakeup-source; -+ }; -+ -+ key-camera-snapshot { -+ label = "Camera Snapshot"; -+ linux,code = ; -+ gpios = <&pm8150b_gpios 1 GPIO_ACTIVE_LOW>; -+ debounce-interval = <15>; -+ linux,can-disable; -+ wakeup-source; -+ }; - - key-vol-down { - label = "Volume Down"; -@@ -546,6 +560,34 @@ - vdda-pll-supply = <&vreg_l9a_1p2>; - }; - -+&pm8150_gpios { -+ vol_down_n: vol-down-n-state { -+ pins = "gpio1"; -+ function = "normal"; -+ power-source = <0>; -+ bias-pull-up; -+ input-enable; -+ }; -+}; -+ -+&pm8150b_gpios { -+ snapshot_n: snapshot-n-state { -+ pins = "gpio1"; -+ function = "normal"; -+ power-source = <0>; -+ bias-pull-up; -+ input-enable; -+ }; -+ -+ focus_n: focus-n-state { -+ pins = "gpio2"; -+ function = "normal"; -+ power-source = <0>; -+ bias-pull-up; -+ input-enable; -+ }; -+}; -+ - &pon_pwrkey { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi -index e93955525a107..4d9b30f0b2841 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi -@@ -99,7 +99,7 @@ - reg = <0x0 0x0>; - enable-method = "psci"; - capacity-dmips-mhz = <448>; -- dynamic-power-coefficient = <205>; -+ dynamic-power-coefficient = <105>; - next-level-cache = <&L2_0>; - power-domains = <&CPU_PD0>; - power-domain-names = "psci"; -@@ -123,7 +123,7 @@ - reg = <0x0 0x100>; - enable-method = "psci"; - capacity-dmips-mhz = <448>; -- dynamic-power-coefficient = <205>; -+ dynamic-power-coefficient = <105>; - next-level-cache = <&L2_100>; - power-domains = <&CPU_PD1>; - power-domain-names = "psci"; -@@ -144,7 +144,7 @@ - reg = <0x0 0x200>; - enable-method = "psci"; - capacity-dmips-mhz = <448>; -- dynamic-power-coefficient = <205>; -+ dynamic-power-coefficient = <105>; - next-level-cache = <&L2_200>; - power-domains = <&CPU_PD2>; - power-domain-names = "psci"; -@@ -165,7 +165,7 @@ - reg = <0x0 0x300>; - enable-method = "psci"; - capacity-dmips-mhz = <448>; -- dynamic-power-coefficient = <205>; -+ dynamic-power-coefficient = <105>; - next-level-cache = <&L2_300>; - power-domains = <&CPU_PD3>; - power-domain-names = "psci"; -@@ -1862,6 +1862,7 @@ - - pinctrl-names = "default"; - pinctrl-0 = <&pcie0_default_state>; -+ dma-coherent; - - status = "disabled"; - }; -@@ -1968,6 +1969,7 @@ - - pinctrl-names = "default"; - pinctrl-0 = <&pcie1_default_state>; -+ dma-coherent; - - status = "disabled"; - }; -@@ -2076,6 +2078,7 @@ - - pinctrl-names = "default"; - pinctrl-0 = <&pcie2_default_state>; -+ dma-coherent; - - status = "disabled"; - }; -diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi -index 7fd1c3f71c0f8..b3245b13b2611 100644 ---- a/arch/arm64/boot/dts/qcom/sm8350.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi -@@ -63,7 +63,7 @@ - - CPU0: cpu@0 { - device_type = "cpu"; -- compatible = "qcom,kryo685"; -+ compatible = "arm,cortex-a55"; - reg = <0x0 0x0>; - enable-method = "psci"; - next-level-cache = <&L2_0>; -@@ -82,7 +82,7 @@ - - CPU1: cpu@100 { - device_type = "cpu"; -- compatible = "qcom,kryo685"; -+ compatible = "arm,cortex-a55"; - reg = <0x0 0x100>; - enable-method = "psci"; - next-level-cache = <&L2_100>; -@@ -98,7 +98,7 @@ - - CPU2: cpu@200 { - device_type = "cpu"; -- compatible = "qcom,kryo685"; -+ compatible = "arm,cortex-a55"; - reg = <0x0 0x200>; - enable-method = "psci"; - next-level-cache = <&L2_200>; -@@ -114,7 +114,7 @@ - - CPU3: cpu@300 { - device_type = "cpu"; -- compatible = "qcom,kryo685"; -+ compatible = "arm,cortex-a55"; - reg = <0x0 0x300>; - enable-method = "psci"; - next-level-cache = <&L2_300>; -@@ -130,7 +130,7 @@ - - CPU4: cpu@400 { - device_type = "cpu"; -- compatible = "qcom,kryo685"; -+ compatible = "arm,cortex-a78"; - reg = <0x0 0x400>; - enable-method = "psci"; - next-level-cache = <&L2_400>; -@@ -146,7 +146,7 @@ - - CPU5: cpu@500 { - device_type = "cpu"; -- compatible = "qcom,kryo685"; -+ compatible = "arm,cortex-a78"; - reg = <0x0 0x500>; - enable-method = "psci"; - next-level-cache = <&L2_500>; -@@ -163,7 +163,7 @@ - - CPU6: cpu@600 { - device_type = "cpu"; -- compatible = "qcom,kryo685"; -+ compatible = "arm,cortex-a78"; - reg = <0x0 0x600>; - enable-method = "psci"; - next-level-cache = <&L2_600>; -@@ -179,7 +179,7 @@ - - CPU7: cpu@700 { - device_type = "cpu"; -- compatible = "qcom,kryo685"; -+ compatible = "arm,cortex-x1"; - reg = <0x0 0x700>; - enable-method = "psci"; - next-level-cache = <&L2_700>; -@@ -236,8 +236,8 @@ - compatible = "arm,idle-state"; - idle-state-name = "silver-rail-power-collapse"; - arm,psci-suspend-param = <0x40000004>; -- entry-latency-us = <355>; -- exit-latency-us = <909>; -+ entry-latency-us = <360>; -+ exit-latency-us = <531>; - min-residency-us = <3934>; - local-timer-stop; - }; -@@ -246,8 +246,8 @@ - compatible = "arm,idle-state"; - idle-state-name = "gold-rail-power-collapse"; - arm,psci-suspend-param = <0x40000004>; -- entry-latency-us = <241>; -- exit-latency-us = <1461>; -+ entry-latency-us = <702>; -+ exit-latency-us = <1061>; - min-residency-us = <4488>; - local-timer-stop; - }; -@@ -2072,6 +2072,13 @@ - <0 0x18593000 0 0x1000>; - reg-names = "freq-domain0", "freq-domain1", "freq-domain2"; - -+ interrupts = , -+ , -+ ; -+ interrupt-names = "dcvsh-irq-0", -+ "dcvsh-irq-1", -+ "dcvsh-irq-2"; -+ - clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; - clock-names = "xo", "alternate"; - -diff --git a/arch/arm64/include/asm/sdei.h b/arch/arm64/include/asm/sdei.h -index 4292d9bafb9d2..484cb6972e99a 100644 ---- a/arch/arm64/include/asm/sdei.h -+++ b/arch/arm64/include/asm/sdei.h -@@ -17,6 +17,9 @@ - - #include - -+DECLARE_PER_CPU(struct sdei_registered_event *, sdei_active_normal_event); -+DECLARE_PER_CPU(struct sdei_registered_event *, sdei_active_critical_event); -+ - extern unsigned long sdei_exit_mode; - - /* Software Delegated Exception entry point from firmware*/ -@@ -29,6 +32,9 @@ asmlinkage void __sdei_asm_entry_trampoline(unsigned long event_num, - unsigned long pc, - unsigned long pstate); - -+/* Abort a running handler. Context is discarded. */ -+void __sdei_handler_abort(void); -+ - /* - * The above entry point does the minimum to call C code. This function does - * anything else, before calling the driver. -diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S -index 3671d9521d4f5..beb4db21c89c1 100644 ---- a/arch/arm64/kernel/entry.S -+++ b/arch/arm64/kernel/entry.S -@@ -993,9 +993,13 @@ SYM_CODE_START(__sdei_asm_handler) - - mov x19, x1 - --#if defined(CONFIG_VMAP_STACK) || defined(CONFIG_SHADOW_CALL_STACK) -+ /* Store the registered-event for crash_smp_send_stop() */ - ldrb w4, [x19, #SDEI_EVENT_PRIORITY] --#endif -+ cbnz w4, 1f -+ adr_this_cpu dst=x5, sym=sdei_active_normal_event, tmp=x6 -+ b 2f -+1: adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6 -+2: str x19, [x5] - - #ifdef CONFIG_VMAP_STACK - /* -@@ -1062,6 +1066,14 @@ SYM_CODE_START(__sdei_asm_handler) - - ldr_l x2, sdei_exit_mode - -+ /* Clear the registered-event seen by crash_smp_send_stop() */ -+ ldrb w3, [x4, #SDEI_EVENT_PRIORITY] -+ cbnz w3, 1f -+ adr_this_cpu dst=x5, sym=sdei_active_normal_event, tmp=x6 -+ b 2f -+1: adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6 -+2: str xzr, [x5] -+ - alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0 - sdei_handler_exit exit_mode=x2 - alternative_else_nop_endif -@@ -1072,4 +1084,15 @@ alternative_else_nop_endif - #endif - SYM_CODE_END(__sdei_asm_handler) - NOKPROBE(__sdei_asm_handler) -+ -+SYM_CODE_START(__sdei_handler_abort) -+ mov_q x0, SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME -+ adr x1, 1f -+ ldr_l x2, sdei_exit_mode -+ sdei_handler_exit exit_mode=x2 -+ // exit the handler and jump to the next instruction. -+ // Exit will stomp x0-x17, PSTATE, ELR_ELx, and SPSR_ELx. -+1: ret -+SYM_CODE_END(__sdei_handler_abort) -+NOKPROBE(__sdei_handler_abort) - #endif /* CONFIG_ARM_SDE_INTERFACE */ -diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c -index 8cd59d387b90b..8c226d79abdfc 100644 ---- a/arch/arm64/kernel/fpsimd.c -+++ b/arch/arm64/kernel/fpsimd.c -@@ -1133,9 +1133,6 @@ void sve_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p) - */ - u64 read_zcr_features(void) - { -- u64 zcr; -- unsigned int vq_max; -- - /* - * Set the maximum possible VL, and write zeroes to all other - * bits to see if they stick. -@@ -1143,12 +1140,8 @@ u64 read_zcr_features(void) - sve_kernel_enable(NULL); - write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL1); - -- zcr = read_sysreg_s(SYS_ZCR_EL1); -- zcr &= ~(u64)ZCR_ELx_LEN_MASK; /* find sticky 1s outside LEN field */ -- vq_max = sve_vq_from_vl(sve_get_vl()); -- zcr |= vq_max - 1; /* set LEN field to maximum effective value */ -- -- return zcr; -+ /* Return LEN value that would be written to get the maximum VL */ -+ return sve_vq_from_vl(sve_get_vl()) - 1; - } - - void __init sve_setup(void) -@@ -1292,11 +1285,7 @@ void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p) - */ - u64 read_smcr_features(void) - { -- u64 smcr; -- unsigned int vq_max; -- - sme_kernel_enable(NULL); -- sme_smstart_sm(); - - /* - * Set the maximum possible VL. -@@ -1304,14 +1293,8 @@ u64 read_smcr_features(void) - write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK, - SYS_SMCR_EL1); - -- smcr = read_sysreg_s(SYS_SMCR_EL1); -- smcr &= ~(u64)SMCR_ELx_LEN_MASK; /* Only the LEN field */ -- vq_max = sve_vq_from_vl(sve_get_vl()); -- smcr |= vq_max - 1; /* set LEN field to maximum effective value */ -- -- sme_smstop_sm(); -- -- return smcr; -+ /* Return LEN value that would be written to get the maximum VL */ -+ return sve_vq_from_vl(sme_get_vl()) - 1; - } - - void __init sme_setup(void) -diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c -index f606c942f514e..e1f6366b7ccdf 100644 ---- a/arch/arm64/kernel/ptrace.c -+++ b/arch/arm64/kernel/ptrace.c -@@ -896,7 +896,8 @@ static int sve_set_common(struct task_struct *target, - break; - default: - WARN_ON_ONCE(1); -- return -EINVAL; -+ ret = -EINVAL; -+ goto out; - } - - /* -diff --git a/arch/arm64/kernel/sdei.c b/arch/arm64/kernel/sdei.c -index d56e170e1ca7c..48c6457b67db8 100644 ---- a/arch/arm64/kernel/sdei.c -+++ b/arch/arm64/kernel/sdei.c -@@ -47,6 +47,9 @@ DEFINE_PER_CPU(unsigned long *, sdei_shadow_call_stack_normal_ptr); - DEFINE_PER_CPU(unsigned long *, sdei_shadow_call_stack_critical_ptr); - #endif - -+DEFINE_PER_CPU(struct sdei_registered_event *, sdei_active_normal_event); -+DEFINE_PER_CPU(struct sdei_registered_event *, sdei_active_critical_event); -+ - static void _free_sdei_stack(unsigned long * __percpu *ptr, int cpu) - { - unsigned long *p; -diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c -index ffc5d76cf6955..d323621d14a59 100644 ---- a/arch/arm64/kernel/smp.c -+++ b/arch/arm64/kernel/smp.c -@@ -1047,10 +1047,8 @@ void crash_smp_send_stop(void) - * If this cpu is the only one alive at this point in time, online or - * not, there are no stop messages to be sent around, so just back out. - */ -- if (num_other_online_cpus() == 0) { -- sdei_mask_local_cpu(); -- return; -- } -+ if (num_other_online_cpus() == 0) -+ goto skip_ipi; - - cpumask_copy(&mask, cpu_online_mask); - cpumask_clear_cpu(smp_processor_id(), &mask); -@@ -1069,7 +1067,9 @@ void crash_smp_send_stop(void) - pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", - cpumask_pr_args(&mask)); - -+skip_ipi: - sdei_mask_local_cpu(); -+ sdei_handler_abort(); - } - - bool smp_crash_stop_failed(void) -diff --git a/arch/arm64/lib/csum.c b/arch/arm64/lib/csum.c -index 78b87a64ca0a3..2432683e48a61 100644 ---- a/arch/arm64/lib/csum.c -+++ b/arch/arm64/lib/csum.c -@@ -24,7 +24,7 @@ unsigned int __no_sanitize_address do_csum(const unsigned char *buff, int len) - const u64 *ptr; - u64 data, sum64 = 0; - -- if (unlikely(len == 0)) -+ if (unlikely(len <= 0)) - return 0; - - offset = (unsigned long)buff & 7; -diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c -index 35e9a468d13e6..134dcf6bc650c 100644 ---- a/arch/arm64/mm/hugetlbpage.c -+++ b/arch/arm64/mm/hugetlbpage.c -@@ -236,7 +236,7 @@ static void clear_flush(struct mm_struct *mm, - unsigned long i, saddr = addr; - - for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) -- pte_clear(mm, addr, ptep); -+ ptep_clear(mm, addr, ptep); - - flush_tlb_range(&vma, saddr, addr); - } -diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h -index 62835d84a647d..3d15fa5bef37d 100644 ---- a/arch/loongarch/include/asm/loongarch.h -+++ b/arch/loongarch/include/asm/loongarch.h -@@ -1488,7 +1488,7 @@ __BUILD_CSR_OP(tlbidx) - #define write_fcsr(dest, val) \ - do { \ - __asm__ __volatile__( \ -- " movgr2fcsr %0, "__stringify(dest)" \n" \ -+ " movgr2fcsr "__stringify(dest)", %0 \n" \ - : : "r" (val)); \ - } while (0) - -diff --git a/arch/loongarch/include/asm/pgtable-bits.h b/arch/loongarch/include/asm/pgtable-bits.h -index 3d1e0a69975a5..5f2ebcea509cd 100644 ---- a/arch/loongarch/include/asm/pgtable-bits.h -+++ b/arch/loongarch/include/asm/pgtable-bits.h -@@ -21,12 +21,14 @@ - #define _PAGE_HGLOBAL_SHIFT 12 /* HGlobal is a PMD bit */ - #define _PAGE_PFN_SHIFT 12 - #define _PAGE_PFN_END_SHIFT 48 -+#define _PAGE_PRESENT_INVALID_SHIFT 60 - #define _PAGE_NO_READ_SHIFT 61 - #define _PAGE_NO_EXEC_SHIFT 62 - #define _PAGE_RPLV_SHIFT 63 - - /* Used by software */ - #define _PAGE_PRESENT (_ULCAST_(1) << _PAGE_PRESENT_SHIFT) -+#define _PAGE_PRESENT_INVALID (_ULCAST_(1) << _PAGE_PRESENT_INVALID_SHIFT) - #define _PAGE_WRITE (_ULCAST_(1) << _PAGE_WRITE_SHIFT) - #define _PAGE_ACCESSED (_ULCAST_(1) << _PAGE_ACCESSED_SHIFT) - #define _PAGE_MODIFIED (_ULCAST_(1) << _PAGE_MODIFIED_SHIFT) -diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h -index 79d5bfd913e0f..f991e678ca4b7 100644 ---- a/arch/loongarch/include/asm/pgtable.h -+++ b/arch/loongarch/include/asm/pgtable.h -@@ -208,7 +208,7 @@ static inline int pmd_bad(pmd_t pmd) - static inline int pmd_present(pmd_t pmd) - { - if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) -- return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE)); -+ return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PRESENT_INVALID)); - - return pmd_val(pmd) != (unsigned long)invalid_pte_table; - } -@@ -525,6 +525,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) - - static inline pmd_t pmd_mkinvalid(pmd_t pmd) - { -+ pmd_val(pmd) |= _PAGE_PRESENT_INVALID; - pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY | _PAGE_PROTNONE); - - return pmd; -@@ -559,6 +560,9 @@ static inline long pmd_protnone(pmd_t pmd) - } - #endif /* CONFIG_NUMA_BALANCING */ - -+#define pmd_leaf(pmd) ((pmd_val(pmd) & _PAGE_HUGE) != 0) -+#define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0) -+ - /* - * We provide our own get_unmapped area to cope with the virtual aliasing - * constraints placed on us by the cache architecture. -diff --git a/arch/m68k/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S -index 439395aa6fb42..081922c72daaa 100644 ---- a/arch/m68k/fpsp040/skeleton.S -+++ b/arch/m68k/fpsp040/skeleton.S -@@ -499,13 +499,13 @@ in_ea: - dbf %d0,morein - rts - -- .section .fixup,#alloc,#execinstr -+ .section .fixup,"ax" - .even - 1: - jbsr fpsp040_die - jbra .Lnotkern - -- .section __ex_table,#alloc -+ .section __ex_table,"a" - .align 4 - - .long in_ea,1b -diff --git a/arch/m68k/ifpsp060/os.S b/arch/m68k/ifpsp060/os.S -index 7a0d6e4280665..89e2ec224ab6c 100644 ---- a/arch/m68k/ifpsp060/os.S -+++ b/arch/m68k/ifpsp060/os.S -@@ -379,11 +379,11 @@ _060_real_access: - - - | Execption handling for movs access to illegal memory -- .section .fixup,#alloc,#execinstr -+ .section .fixup,"ax" - .even - 1: moveq #-1,%d1 - rts --.section __ex_table,#alloc -+.section __ex_table,"a" - .align 4 - .long dmrbuae,1b - .long dmrwuae,1b -diff --git a/arch/m68k/kernel/relocate_kernel.S b/arch/m68k/kernel/relocate_kernel.S -index ab0f1e7d46535..f7667079e08e9 100644 ---- a/arch/m68k/kernel/relocate_kernel.S -+++ b/arch/m68k/kernel/relocate_kernel.S -@@ -26,7 +26,7 @@ ENTRY(relocate_new_kernel) - lea %pc@(.Lcopy),%a4 - 2: addl #0x00000000,%a4 /* virt_to_phys() */ - -- .section ".m68k_fixup","aw" -+ .section .m68k_fixup,"aw" - .long M68K_FIXUP_MEMOFFSET, 2b+2 - .previous - -@@ -49,7 +49,7 @@ ENTRY(relocate_new_kernel) - lea %pc@(.Lcont040),%a4 - 5: addl #0x00000000,%a4 /* virt_to_phys() */ - -- .section ".m68k_fixup","aw" -+ .section .m68k_fixup,"aw" - .long M68K_FIXUP_MEMOFFSET, 5b+2 - .previous - -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index cf1fbf4eaa8a0..0e62f5edaee2e 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -83,7 +83,6 @@ config MIPS - select HAVE_LD_DEAD_CODE_DATA_ELIMINATION - select HAVE_MOD_ARCH_SPECIFIC - select HAVE_NMI -- select HAVE_PATA_PLATFORM - select HAVE_PERF_EVENTS - select HAVE_PERF_REGS - select HAVE_PERF_USER_STACK_DUMP -diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c -index dddaaa6e7a825..1f6c776d80813 100644 ---- a/arch/parisc/kernel/processor.c -+++ b/arch/parisc/kernel/processor.c -@@ -372,10 +372,18 @@ int - show_cpuinfo (struct seq_file *m, void *v) - { - unsigned long cpu; -+ char cpu_name[60], *p; -+ -+ /* strip PA path from CPU name to not confuse lscpu */ -+ strlcpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name)); -+ p = strrchr(cpu_name, '['); -+ if (p) -+ *(--p) = 0; - - for_each_online_cpu(cpu) { -- const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); - #ifdef CONFIG_SMP -+ const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); -+ - if (0 == cpuinfo->hpa) - continue; - #endif -@@ -420,8 +428,7 @@ show_cpuinfo (struct seq_file *m, void *v) - - seq_printf(m, "model\t\t: %s - %s\n", - boot_cpu_data.pdc.sys_model_name, -- cpuinfo->dev ? -- cpuinfo->dev->name : "Unknown"); -+ cpu_name); - - seq_printf(m, "hversion\t: 0x%08x\n" - "sversion\t: 0x%08x\n", -diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile -index 13fad4f0a6d8f..b13324b1a1696 100644 ---- a/arch/powerpc/boot/Makefile -+++ b/arch/powerpc/boot/Makefile -@@ -34,8 +34,6 @@ endif - - BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ - -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \ -- $(call cc-option,-mno-prefixed) $(call cc-option,-mno-pcrel) \ -- $(call cc-option,-mno-mma) \ - $(call cc-option,-mno-spe) $(call cc-option,-mspe=no) \ - -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ - $(LINUXINCLUDE) -@@ -71,6 +69,10 @@ BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc - - BOOTARFLAGS := -crD - -+BOOTCFLAGS += $(call cc-option,-mno-prefixed) \ -+ $(call cc-option,-mno-pcrel) \ -+ $(call cc-option,-mno-mma) -+ - ifdef CONFIG_CC_IS_CLANG - BOOTCFLAGS += $(CLANG_FLAGS) - BOOTAFLAGS += $(CLANG_FLAGS) -diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h -index 34d44cb17c874..ee1488d38fdc1 100644 ---- a/arch/powerpc/include/asm/lppaca.h -+++ b/arch/powerpc/include/asm/lppaca.h -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - - /* - * The lppaca is the "virtual processor area" registered with the hypervisor, -@@ -127,13 +128,23 @@ struct lppaca { - */ - #define LPPACA_OLD_SHARED_PROC 2 - --static inline bool lppaca_shared_proc(struct lppaca *l) -+#ifdef CONFIG_PPC_PSERIES -+/* -+ * All CPUs should have the same shared proc value, so directly access the PACA -+ * to avoid false positives from DEBUG_PREEMPT. -+ */ -+static inline bool lppaca_shared_proc(void) - { -+ struct lppaca *l = local_paca->lppaca_ptr; -+ - if (!firmware_has_feature(FW_FEATURE_SPLPAR)) - return false; - return !!(l->__old_status & LPPACA_OLD_SHARED_PROC); - } - -+#define get_lppaca() (get_paca()->lppaca_ptr) -+#endif -+ - /* - * SLB shadow buffer structure as defined in the PAPR. The save_area - * contains adjacent ESID and VSID pairs for each shadowed SLB. The -diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h -index 0ab3511a47d77..183b5a251804c 100644 ---- a/arch/powerpc/include/asm/paca.h -+++ b/arch/powerpc/include/asm/paca.h -@@ -15,7 +15,6 @@ - #include - #include - #include --#include - #include - #include - #ifdef CONFIG_PPC_BOOK3E_64 -@@ -47,14 +46,11 @@ extern unsigned int debug_smp_processor_id(void); /* from linux/smp.h */ - #define get_paca() local_paca - #endif - --#ifdef CONFIG_PPC_PSERIES --#define get_lppaca() (get_paca()->lppaca_ptr) --#endif -- - #define get_slb_shadow() (get_paca()->slb_shadow_ptr) - - struct task_struct; - struct rtas_args; -+struct lppaca; - - /* - * Defines the layout of the paca. -diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h -index f5ba1a3c41f8e..e08513d731193 100644 ---- a/arch/powerpc/include/asm/paravirt.h -+++ b/arch/powerpc/include/asm/paravirt.h -@@ -6,6 +6,7 @@ - #include - #ifdef CONFIG_PPC64 - #include -+#include - #include - #endif - -diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h -index 8239c0af5eb2b..fe3d0ea0058ac 100644 ---- a/arch/powerpc/include/asm/plpar_wrappers.h -+++ b/arch/powerpc/include/asm/plpar_wrappers.h -@@ -9,6 +9,7 @@ - - #include - #include -+#include - #include - - static inline long poll_pending(void) -diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c -index ea0a073abd969..3ff2da7b120b5 100644 ---- a/arch/powerpc/kernel/fadump.c -+++ b/arch/powerpc/kernel/fadump.c -@@ -654,6 +654,7 @@ int __init fadump_reserve_mem(void) - return ret; - error_out: - fw_dump.fadump_enabled = 0; -+ fw_dump.reserve_dump_area_size = 0; - return 0; - } - -diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c -index b8b7a189cd3ce..a612abe4bfd57 100644 ---- a/arch/powerpc/kernel/iommu.c -+++ b/arch/powerpc/kernel/iommu.c -@@ -171,17 +171,28 @@ static int fail_iommu_bus_notify(struct notifier_block *nb, - return 0; - } - --static struct notifier_block fail_iommu_bus_notifier = { -+/* -+ * PCI and VIO buses need separate notifier_block structs, since they're linked -+ * list nodes. Sharing a notifier_block would mean that any notifiers later -+ * registered for PCI buses would also get called by VIO buses and vice versa. -+ */ -+static struct notifier_block fail_iommu_pci_bus_notifier = { - .notifier_call = fail_iommu_bus_notify - }; - -+#ifdef CONFIG_IBMVIO -+static struct notifier_block fail_iommu_vio_bus_notifier = { -+ .notifier_call = fail_iommu_bus_notify -+}; -+#endif -+ - static int __init fail_iommu_setup(void) - { - #ifdef CONFIG_PCI -- bus_register_notifier(&pci_bus_type, &fail_iommu_bus_notifier); -+ bus_register_notifier(&pci_bus_type, &fail_iommu_pci_bus_notifier); - #endif - #ifdef CONFIG_IBMVIO -- bus_register_notifier(&vio_bus_type, &fail_iommu_bus_notifier); -+ bus_register_notifier(&vio_bus_type, &fail_iommu_vio_bus_notifier); - #endif - - return 0; -diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c -index ccfd969656306..82be6d87514b7 100644 ---- a/arch/powerpc/kvm/book3s_hv_ras.c -+++ b/arch/powerpc/kvm/book3s_hv_ras.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c -index 6d7a1ef723e69..a8ba04dcb20fa 100644 ---- a/arch/powerpc/mm/book3s64/radix_tlb.c -+++ b/arch/powerpc/mm/book3s64/radix_tlb.c -@@ -127,21 +127,6 @@ static __always_inline void __tlbie_pid(unsigned long pid, unsigned long ric) - trace_tlbie(0, 0, rb, rs, ric, prs, r); - } - --static __always_inline void __tlbie_pid_lpid(unsigned long pid, -- unsigned long lpid, -- unsigned long ric) --{ -- unsigned long rb, rs, prs, r; -- -- rb = PPC_BIT(53); /* IS = 1 */ -- rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31))); -- prs = 1; /* process scoped */ -- r = 1; /* radix format */ -- -- asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) -- : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); -- trace_tlbie(0, 0, rb, rs, ric, prs, r); --} - static __always_inline void __tlbie_lpid(unsigned long lpid, unsigned long ric) - { - unsigned long rb,rs,prs,r; -@@ -202,23 +187,6 @@ static __always_inline void __tlbie_va(unsigned long va, unsigned long pid, - trace_tlbie(0, 0, rb, rs, ric, prs, r); - } - --static __always_inline void __tlbie_va_lpid(unsigned long va, unsigned long pid, -- unsigned long lpid, -- unsigned long ap, unsigned long ric) --{ -- unsigned long rb, rs, prs, r; -- -- rb = va & ~(PPC_BITMASK(52, 63)); -- rb |= ap << PPC_BITLSHIFT(58); -- rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31))); -- prs = 1; /* process scoped */ -- r = 1; /* radix format */ -- -- asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) -- : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); -- trace_tlbie(0, 0, rb, rs, ric, prs, r); --} -- - static __always_inline void __tlbie_lpid_va(unsigned long va, unsigned long lpid, - unsigned long ap, unsigned long ric) - { -@@ -264,22 +232,6 @@ static inline void fixup_tlbie_va_range(unsigned long va, unsigned long pid, - } - } - --static inline void fixup_tlbie_va_range_lpid(unsigned long va, -- unsigned long pid, -- unsigned long lpid, -- unsigned long ap) --{ -- if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) { -- asm volatile("ptesync" : : : "memory"); -- __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB); -- } -- -- if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) { -- asm volatile("ptesync" : : : "memory"); -- __tlbie_va_lpid(va, pid, lpid, ap, RIC_FLUSH_TLB); -- } --} -- - static inline void fixup_tlbie_pid(unsigned long pid) - { - /* -@@ -299,26 +251,6 @@ static inline void fixup_tlbie_pid(unsigned long pid) - } - } - --static inline void fixup_tlbie_pid_lpid(unsigned long pid, unsigned long lpid) --{ -- /* -- * We can use any address for the invalidation, pick one which is -- * probably unused as an optimisation. -- */ -- unsigned long va = ((1UL << 52) - 1); -- -- if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) { -- asm volatile("ptesync" : : : "memory"); -- __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB); -- } -- -- if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) { -- asm volatile("ptesync" : : : "memory"); -- __tlbie_va_lpid(va, pid, lpid, mmu_get_ap(MMU_PAGE_64K), -- RIC_FLUSH_TLB); -- } --} -- - static inline void fixup_tlbie_lpid_va(unsigned long va, unsigned long lpid, - unsigned long ap) - { -@@ -416,31 +348,6 @@ static inline void _tlbie_pid(unsigned long pid, unsigned long ric) - asm volatile("eieio; tlbsync; ptesync": : :"memory"); - } - --static inline void _tlbie_pid_lpid(unsigned long pid, unsigned long lpid, -- unsigned long ric) --{ -- asm volatile("ptesync" : : : "memory"); -- -- /* -- * Workaround the fact that the "ric" argument to __tlbie_pid -- * must be a compile-time contraint to match the "i" constraint -- * in the asm statement. -- */ -- switch (ric) { -- case RIC_FLUSH_TLB: -- __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_TLB); -- fixup_tlbie_pid_lpid(pid, lpid); -- break; -- case RIC_FLUSH_PWC: -- __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC); -- break; -- case RIC_FLUSH_ALL: -- default: -- __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_ALL); -- fixup_tlbie_pid_lpid(pid, lpid); -- } -- asm volatile("eieio; tlbsync; ptesync" : : : "memory"); --} - struct tlbiel_pid { - unsigned long pid; - unsigned long ric; -@@ -566,20 +473,6 @@ static inline void __tlbie_va_range(unsigned long start, unsigned long end, - fixup_tlbie_va_range(addr - page_size, pid, ap); - } - --static inline void __tlbie_va_range_lpid(unsigned long start, unsigned long end, -- unsigned long pid, unsigned long lpid, -- unsigned long page_size, -- unsigned long psize) --{ -- unsigned long addr; -- unsigned long ap = mmu_get_ap(psize); -- -- for (addr = start; addr < end; addr += page_size) -- __tlbie_va_lpid(addr, pid, lpid, ap, RIC_FLUSH_TLB); -- -- fixup_tlbie_va_range_lpid(addr - page_size, pid, lpid, ap); --} -- - static __always_inline void _tlbie_va(unsigned long va, unsigned long pid, - unsigned long psize, unsigned long ric) - { -@@ -660,18 +553,6 @@ static inline void _tlbie_va_range(unsigned long start, unsigned long end, - asm volatile("eieio; tlbsync; ptesync": : :"memory"); - } - --static inline void _tlbie_va_range_lpid(unsigned long start, unsigned long end, -- unsigned long pid, unsigned long lpid, -- unsigned long page_size, -- unsigned long psize, bool also_pwc) --{ -- asm volatile("ptesync" : : : "memory"); -- if (also_pwc) -- __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC); -- __tlbie_va_range_lpid(start, end, pid, lpid, page_size, psize); -- asm volatile("eieio; tlbsync; ptesync" : : : "memory"); --} -- - static inline void _tlbiel_va_range_multicast(struct mm_struct *mm, - unsigned long start, unsigned long end, - unsigned long pid, unsigned long page_size, -@@ -1476,6 +1357,127 @@ void radix__flush_tlb_all(void) - } - - #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE -+static __always_inline void __tlbie_pid_lpid(unsigned long pid, -+ unsigned long lpid, -+ unsigned long ric) -+{ -+ unsigned long rb, rs, prs, r; -+ -+ rb = PPC_BIT(53); /* IS = 1 */ -+ rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31))); -+ prs = 1; /* process scoped */ -+ r = 1; /* radix format */ -+ -+ asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) -+ : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); -+ trace_tlbie(0, 0, rb, rs, ric, prs, r); -+} -+ -+static __always_inline void __tlbie_va_lpid(unsigned long va, unsigned long pid, -+ unsigned long lpid, -+ unsigned long ap, unsigned long ric) -+{ -+ unsigned long rb, rs, prs, r; -+ -+ rb = va & ~(PPC_BITMASK(52, 63)); -+ rb |= ap << PPC_BITLSHIFT(58); -+ rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31))); -+ prs = 1; /* process scoped */ -+ r = 1; /* radix format */ -+ -+ asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) -+ : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); -+ trace_tlbie(0, 0, rb, rs, ric, prs, r); -+} -+ -+static inline void fixup_tlbie_pid_lpid(unsigned long pid, unsigned long lpid) -+{ -+ /* -+ * We can use any address for the invalidation, pick one which is -+ * probably unused as an optimisation. -+ */ -+ unsigned long va = ((1UL << 52) - 1); -+ -+ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) { -+ asm volatile("ptesync" : : : "memory"); -+ __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB); -+ } -+ -+ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) { -+ asm volatile("ptesync" : : : "memory"); -+ __tlbie_va_lpid(va, pid, lpid, mmu_get_ap(MMU_PAGE_64K), -+ RIC_FLUSH_TLB); -+ } -+} -+ -+static inline void _tlbie_pid_lpid(unsigned long pid, unsigned long lpid, -+ unsigned long ric) -+{ -+ asm volatile("ptesync" : : : "memory"); -+ -+ /* -+ * Workaround the fact that the "ric" argument to __tlbie_pid -+ * must be a compile-time contraint to match the "i" constraint -+ * in the asm statement. -+ */ -+ switch (ric) { -+ case RIC_FLUSH_TLB: -+ __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_TLB); -+ fixup_tlbie_pid_lpid(pid, lpid); -+ break; -+ case RIC_FLUSH_PWC: -+ __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC); -+ break; -+ case RIC_FLUSH_ALL: -+ default: -+ __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_ALL); -+ fixup_tlbie_pid_lpid(pid, lpid); -+ } -+ asm volatile("eieio; tlbsync; ptesync" : : : "memory"); -+} -+ -+static inline void fixup_tlbie_va_range_lpid(unsigned long va, -+ unsigned long pid, -+ unsigned long lpid, -+ unsigned long ap) -+{ -+ if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) { -+ asm volatile("ptesync" : : : "memory"); -+ __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB); -+ } -+ -+ if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) { -+ asm volatile("ptesync" : : : "memory"); -+ __tlbie_va_lpid(va, pid, lpid, ap, RIC_FLUSH_TLB); -+ } -+} -+ -+static inline void __tlbie_va_range_lpid(unsigned long start, unsigned long end, -+ unsigned long pid, unsigned long lpid, -+ unsigned long page_size, -+ unsigned long psize) -+{ -+ unsigned long addr; -+ unsigned long ap = mmu_get_ap(psize); -+ -+ for (addr = start; addr < end; addr += page_size) -+ __tlbie_va_lpid(addr, pid, lpid, ap, RIC_FLUSH_TLB); -+ -+ fixup_tlbie_va_range_lpid(addr - page_size, pid, lpid, ap); -+} -+ -+static inline void _tlbie_va_range_lpid(unsigned long start, unsigned long end, -+ unsigned long pid, unsigned long lpid, -+ unsigned long page_size, -+ unsigned long psize, bool also_pwc) -+{ -+ asm volatile("ptesync" : : : "memory"); -+ if (also_pwc) -+ __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC); -+ __tlbie_va_range_lpid(start, end, pid, lpid, page_size, psize); -+ asm volatile("eieio; tlbsync; ptesync" : : : "memory"); -+} -+ - /* - * Performs process-scoped invalidations for a given LPID - * as part of H_RPT_INVALIDATE hcall. -diff --git a/arch/powerpc/mm/book3s64/slb.c b/arch/powerpc/mm/book3s64/slb.c -index 6956f637a38c1..f2708c8629a52 100644 ---- a/arch/powerpc/mm/book3s64/slb.c -+++ b/arch/powerpc/mm/book3s64/slb.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c -index ee721f420a7ba..1a53ab08447cb 100644 ---- a/arch/powerpc/perf/core-fsl-emb.c -+++ b/arch/powerpc/perf/core-fsl-emb.c -@@ -645,7 +645,6 @@ static void perf_event_interrupt(struct pt_regs *regs) - struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); - struct perf_event *event; - unsigned long val; -- int found = 0; - - for (i = 0; i < ppmu->n_counter; ++i) { - event = cpuhw->event[i]; -@@ -654,7 +653,6 @@ static void perf_event_interrupt(struct pt_regs *regs) - if ((int)val < 0) { - if (event) { - /* event has overflowed */ -- found = 1; - record_and_restart(event, val, regs); - } else { - /* -@@ -672,11 +670,13 @@ static void perf_event_interrupt(struct pt_regs *regs) - isync(); - } - --void hw_perf_event_setup(int cpu) -+static int fsl_emb_pmu_prepare_cpu(unsigned int cpu) - { - struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); - - memset(cpuhw, 0, sizeof(*cpuhw)); -+ -+ return 0; - } - - int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu) -@@ -689,6 +689,8 @@ int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu) - pmu->name); - - perf_pmu_register(&fsl_emb_pmu, "cpu", PERF_TYPE_RAW); -+ cpuhp_setup_state(CPUHP_PERF_POWER, "perf/powerpc:prepare", -+ fsl_emb_pmu_prepare_cpu, NULL); - - return 0; - } -diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c -index 4c5790aff1b54..8633891b7aa58 100644 ---- a/arch/powerpc/platforms/powermac/time.c -+++ b/arch/powerpc/platforms/powermac/time.c -@@ -26,8 +26,8 @@ - #include - #include - -+#include - #include --#include - #include - #include - #include -@@ -182,7 +182,7 @@ static int __init via_calibrate_decr(void) - return 0; - } - of_node_put(vias); -- via = ioremap(rsrc.start, resource_size(&rsrc)); -+ via = early_ioremap(rsrc.start, resource_size(&rsrc)); - if (via == NULL) { - printk(KERN_ERR "Failed to map VIA for timer calibration !\n"); - return 0; -@@ -207,7 +207,7 @@ static int __init via_calibrate_decr(void) - - ppc_tb_freq = (dstart - dend) * 100 / 6; - -- iounmap(via); -+ early_iounmap((void *)via, resource_size(&rsrc)); - - return 1; - } -diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S -index 762eb15d3bd42..fc50b9c27c1ba 100644 ---- a/arch/powerpc/platforms/pseries/hvCall.S -+++ b/arch/powerpc/platforms/pseries/hvCall.S -@@ -89,6 +89,7 @@ BEGIN_FTR_SECTION; \ - b 1f; \ - END_FTR_SECTION(0, 1); \ - LOAD_REG_ADDR(r12, hcall_tracepoint_refcount) ; \ -+ ld r12,0(r12); \ - std r12,32(r1); \ - cmpdi r12,0; \ - bne- LABEL; \ -diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c -index 97ef6499e5019..2c2812a87d470 100644 ---- a/arch/powerpc/platforms/pseries/lpar.c -+++ b/arch/powerpc/platforms/pseries/lpar.c -@@ -638,16 +638,8 @@ static const struct proc_ops vcpudispatch_stats_freq_proc_ops = { - - static int __init vcpudispatch_stats_procfs_init(void) - { -- /* -- * Avoid smp_processor_id while preemptible. All CPUs should have -- * the same value for lppaca_shared_proc. -- */ -- preempt_disable(); -- if (!lppaca_shared_proc(get_lppaca())) { -- preempt_enable(); -+ if (!lppaca_shared_proc()) - return 0; -- } -- preempt_enable(); - - if (!proc_create("powerpc/vcpudispatch_stats", 0600, NULL, - &vcpudispatch_stats_proc_ops)) -diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c -index 63fd925ccbb83..ca10a3682c46e 100644 ---- a/arch/powerpc/platforms/pseries/lparcfg.c -+++ b/arch/powerpc/platforms/pseries/lparcfg.c -@@ -205,7 +205,7 @@ static void parse_ppp_data(struct seq_file *m) - ppp_data.active_system_procs); - - /* pool related entries are appropriate for shared configs */ -- if (lppaca_shared_proc(get_lppaca())) { -+ if (lppaca_shared_proc()) { - unsigned long pool_idle_time, pool_procs; - - seq_printf(m, "pool=%d\n", ppp_data.pool_num); -@@ -616,7 +616,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) - partition_potential_processors); - - seq_printf(m, "shared_processor_mode=%d\n", -- lppaca_shared_proc(get_lppaca())); -+ lppaca_shared_proc()); - - #ifdef CONFIG_PPC_64S_HASH_MMU - if (!radix_enabled()) -diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c -index 8ef3270515a9b..a0701dbdb1348 100644 ---- a/arch/powerpc/platforms/pseries/setup.c -+++ b/arch/powerpc/platforms/pseries/setup.c -@@ -846,7 +846,7 @@ static void __init pSeries_setup_arch(void) - if (firmware_has_feature(FW_FEATURE_LPAR)) { - vpa_init(boot_cpuid); - -- if (lppaca_shared_proc(get_lppaca())) { -+ if (lppaca_shared_proc()) { - static_branch_enable(&shared_processor); - pv_spinlocks_init(); - #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING -diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c b/arch/powerpc/sysdev/mpc5xxx_clocks.c -index c5bf7e1b37804..58cee28e23992 100644 ---- a/arch/powerpc/sysdev/mpc5xxx_clocks.c -+++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c -@@ -25,8 +25,10 @@ unsigned long mpc5xxx_fwnode_get_bus_frequency(struct fwnode_handle *fwnode) - - fwnode_for_each_parent_node(fwnode, parent) { - ret = fwnode_property_read_u32(parent, "bus-frequency", &bus_freq); -- if (!ret) -+ if (!ret) { -+ fwnode_handle_put(parent); - return bus_freq; -+ } - } - - return 0; -diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c -index bd8e80936f44d..cd692f399cd18 100644 ---- a/arch/powerpc/xmon/xmon.c -+++ b/arch/powerpc/xmon/xmon.c -@@ -58,6 +58,7 @@ - #ifdef CONFIG_PPC64 - #include - #include -+#include - #endif - - #include "nonstdio.h" -diff --git a/arch/s390/crypto/paes_s390.c b/arch/s390/crypto/paes_s390.c -index a279b7d23a5e2..621322eb0e681 100644 ---- a/arch/s390/crypto/paes_s390.c -+++ b/arch/s390/crypto/paes_s390.c -@@ -35,7 +35,7 @@ - * and padding is also possible, the limits need to be generous. - */ - #define PAES_MIN_KEYSIZE 16 --#define PAES_MAX_KEYSIZE 320 -+#define PAES_MAX_KEYSIZE MAXEP11AESKEYBLOBSIZE - - static u8 *ctrblk; - static DEFINE_MUTEX(ctrblk_lock); -diff --git a/arch/s390/include/uapi/asm/pkey.h b/arch/s390/include/uapi/asm/pkey.h -index 924b876f992c1..29c6fd369761e 100644 ---- a/arch/s390/include/uapi/asm/pkey.h -+++ b/arch/s390/include/uapi/asm/pkey.h -@@ -26,7 +26,7 @@ - #define MAXCLRKEYSIZE 32 /* a clear key value may be up to 32 bytes */ - #define MAXAESCIPHERKEYSIZE 136 /* our aes cipher keys have always 136 bytes */ - #define MINEP11AESKEYBLOBSIZE 256 /* min EP11 AES key blob size */ --#define MAXEP11AESKEYBLOBSIZE 320 /* max EP11 AES key blob size */ -+#define MAXEP11AESKEYBLOBSIZE 336 /* max EP11 AES key blob size */ - - /* Minimum size of a key blob */ - #define MINKEYBLOBSIZE SECKEYBLOBSIZE -diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c -index 325cbf69ebbde..df5d2ec737d80 100644 ---- a/arch/s390/kernel/ipl.c -+++ b/arch/s390/kernel/ipl.c -@@ -503,6 +503,8 @@ static struct attribute_group ipl_ccw_attr_group_lpar = { - - static struct attribute *ipl_unknown_attrs[] = { - &sys_ipl_type_attr.attr, -+ &sys_ipl_secure_attr.attr, -+ &sys_ipl_has_secure_attr.attr, - NULL, - }; - -diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig -index c0162286d68b7..c33a6880a437a 100644 ---- a/arch/um/configs/i386_defconfig -+++ b/arch/um/configs/i386_defconfig -@@ -35,6 +35,7 @@ CONFIG_TTY_CHAN=y - CONFIG_XTERM_CHAN=y - CONFIG_CON_CHAN="pts" - CONFIG_SSL_CHAN="pts" -+CONFIG_SOUND=m - CONFIG_UML_SOUND=m - CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y -diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig -index bec6e5d956873..df29f282b6ac2 100644 ---- a/arch/um/configs/x86_64_defconfig -+++ b/arch/um/configs/x86_64_defconfig -@@ -33,6 +33,7 @@ CONFIG_TTY_CHAN=y - CONFIG_XTERM_CHAN=y - CONFIG_CON_CHAN="pts" - CONFIG_SSL_CHAN="pts" -+CONFIG_SOUND=m - CONFIG_UML_SOUND=m - CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y -diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig -index 5903e2b598aae..fe0210eaf9bb6 100644 ---- a/arch/um/drivers/Kconfig -+++ b/arch/um/drivers/Kconfig -@@ -111,24 +111,14 @@ config SSL_CHAN - - config UML_SOUND - tristate "Sound support" -+ depends on SOUND -+ select SOUND_OSS_CORE - help - This option enables UML sound support. If enabled, it will pull in -- soundcore and the UML hostaudio relay, which acts as a intermediary -+ the UML hostaudio relay, which acts as a intermediary - between the host's dsp and mixer devices and the UML sound system. - It is safe to say 'Y' here. - --config SOUND -- tristate -- default UML_SOUND -- --config SOUND_OSS_CORE -- bool -- default UML_SOUND -- --config HOSTAUDIO -- tristate -- default UML_SOUND -- - endmenu - - menu "UML Network Devices" -diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile -index 65b449c992d2c..079556ec044b8 100644 ---- a/arch/um/drivers/Makefile -+++ b/arch/um/drivers/Makefile -@@ -54,7 +54,7 @@ obj-$(CONFIG_UML_NET) += net.o - obj-$(CONFIG_MCONSOLE) += mconsole.o - obj-$(CONFIG_MMAPPER) += mmapper_kern.o - obj-$(CONFIG_BLK_DEV_UBD) += ubd.o --obj-$(CONFIG_HOSTAUDIO) += hostaudio.o -+obj-$(CONFIG_UML_SOUND) += hostaudio.o - obj-$(CONFIG_NULL_CHAN) += null.o - obj-$(CONFIG_PORT_CHAN) += port.o - obj-$(CONFIG_PTY_CHAN) += pty.o -diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S -index d33f060900d23..b4bd6df29116f 100644 ---- a/arch/x86/boot/compressed/head_64.S -+++ b/arch/x86/boot/compressed/head_64.S -@@ -485,11 +485,25 @@ SYM_CODE_START(startup_64) - /* Save the trampoline address in RCX */ - movq %rax, %rcx - -+ /* Set up 32-bit addressable stack */ -+ leaq TRAMPOLINE_32BIT_STACK_END(%rcx), %rsp -+ -+ /* -+ * Preserve live 64-bit registers on the stack: this is necessary -+ * because the architecture does not guarantee that GPRs will retain -+ * their full 64-bit values across a 32-bit mode switch. -+ */ -+ pushq %rbp -+ pushq %rbx -+ pushq %rsi -+ - /* -- * Load the address of trampoline_return() into RDI. -- * It will be used by the trampoline to return to the main code. -+ * Push the 64-bit address of trampoline_return() onto the new stack. -+ * It will be used by the trampoline to return to the main code. Due to -+ * the 32-bit mode switch, it cannot be kept it in a register either. - */ - leaq trampoline_return(%rip), %rdi -+ pushq %rdi - - /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */ - pushq $__KERNEL32_CS -@@ -497,6 +511,11 @@ SYM_CODE_START(startup_64) - pushq %rax - lretq - trampoline_return: -+ /* Restore live 64-bit registers */ -+ popq %rsi -+ popq %rbx -+ popq %rbp -+ - /* Restore the stack, the 32-bit trampoline uses its own stack */ - leaq rva(boot_stack_end)(%rbx), %rsp - -@@ -606,7 +625,7 @@ SYM_FUNC_END(.Lrelocated) - /* - * This is the 32-bit trampoline that will be copied over to low memory. - * -- * RDI contains the return address (might be above 4G). -+ * Return address is at the top of the stack (might be above 4G). - * ECX contains the base address of the trampoline memory. - * Non zero RDX means trampoline needs to enable 5-level paging. - */ -@@ -616,9 +635,6 @@ SYM_CODE_START(trampoline_32bit_src) - movl %eax, %ds - movl %eax, %ss - -- /* Set up new stack */ -- leal TRAMPOLINE_32BIT_STACK_END(%ecx), %esp -- - /* Disable paging */ - movl %cr0, %eax - btrl $X86_CR0_PG_BIT, %eax -@@ -695,7 +711,7 @@ SYM_CODE_END(trampoline_32bit_src) - .code64 - SYM_FUNC_START_LOCAL_NOALIGN(.Lpaging_enabled) - /* Return from the trampoline */ -- jmp *%rdi -+ retq - SYM_FUNC_END(.Lpaging_enabled) - - /* -diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c -index 935081ddf60bc..9b5859812f4fb 100644 ---- a/arch/x86/events/intel/uncore_snbep.c -+++ b/arch/x86/events/intel/uncore_snbep.c -@@ -6078,8 +6078,18 @@ void spr_uncore_cpu_init(void) - - type = uncore_find_type_by_id(uncore_msr_uncores, UNCORE_SPR_CHA); - if (type) { -+ /* -+ * The value from the discovery table (stored in the type->num_boxes -+ * of UNCORE_SPR_CHA) is incorrect on some SPR variants because of a -+ * firmware bug. Using the value from SPR_MSR_UNC_CBO_CONFIG to replace it. -+ */ - rdmsrl(SPR_MSR_UNC_CBO_CONFIG, num_cbo); -- type->num_boxes = num_cbo; -+ /* -+ * The MSR doesn't work on the EMR XCC, but the firmware bug doesn't impact -+ * the EMR XCC. Don't let the value from the MSR replace the existing value. -+ */ -+ if (num_cbo) -+ type->num_boxes = num_cbo; - } - spr_uncore_iio_free_running.num_boxes = uncore_type_max_boxes(uncore_msr_uncores, UNCORE_SPR_IIO); - } -diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h -index 8f513372cd8d4..c91326593e741 100644 ---- a/arch/x86/include/asm/mem_encrypt.h -+++ b/arch/x86/include/asm/mem_encrypt.h -@@ -50,8 +50,8 @@ void __init sme_enable(struct boot_params *bp); - - int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size); - int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size); --void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, -- bool enc); -+void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, -+ unsigned long size, bool enc); - - void __init mem_encrypt_free_decrypted_mem(void); - -@@ -84,7 +84,7 @@ early_set_memory_decrypted(unsigned long vaddr, unsigned long size) { return 0; - static inline int __init - early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0; } - static inline void __init --early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) {} -+early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) {} - - static inline void mem_encrypt_free_decrypted_mem(void) { } - -diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h -index aa174fed3a71c..f6116b66f2892 100644 ---- a/arch/x86/include/asm/pgtable_types.h -+++ b/arch/x86/include/asm/pgtable_types.h -@@ -125,11 +125,12 @@ - * instance, and is *not* included in this mask since - * pte_modify() does modify it. - */ --#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ -- _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \ -- _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \ -- _PAGE_UFFD_WP) --#define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE) -+#define _COMMON_PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ -+ _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY |\ -+ _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \ -+ _PAGE_UFFD_WP) -+#define _PAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PAT) -+#define _HPAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_PAT_LARGE) - - /* - * The cache modes defined here are used to translate between pure SW usage -diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c -index 60e330cdbd175..6e38188633a4d 100644 ---- a/arch/x86/kernel/apm_32.c -+++ b/arch/x86/kernel/apm_32.c -@@ -238,12 +238,6 @@ - extern int (*console_blank_hook)(int); - #endif - --/* -- * The apm_bios device is one of the misc char devices. -- * This is its minor number. -- */ --#define APM_MINOR_DEV 134 -- - /* - * Various options can be changed at boot time as follows: - * (We allow underscores for compatibility with the modules code) -diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c -index d38ae25e7c01f..b723368dbc644 100644 ---- a/arch/x86/kernel/cpu/common.c -+++ b/arch/x86/kernel/cpu/common.c -@@ -1259,11 +1259,11 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { - VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS), - VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), - VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), -- VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), - VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), -- VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), -- VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), -- VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), -+ VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), -+ VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), -+ VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), -+ VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), - VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED), - VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), - VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS), -diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c -index e228d58ee2645..f1a748da5fabb 100644 ---- a/arch/x86/kernel/cpu/mce/core.c -+++ b/arch/x86/kernel/cpu/mce/core.c -@@ -856,6 +856,26 @@ static noinstr bool quirk_skylake_repmov(void) - return false; - } - -+/* -+ * Some Zen-based Instruction Fetch Units set EIPV=RIPV=0 on poison consumption -+ * errors. This means mce_gather_info() will not save the "ip" and "cs" registers. -+ * -+ * However, the context is still valid, so save the "cs" register for later use. -+ * -+ * The "ip" register is truly unknown, so don't save it or fixup EIPV/RIPV. -+ * -+ * The Instruction Fetch Unit is at MCA bank 1 for all affected systems. -+ */ -+static __always_inline void quirk_zen_ifu(int bank, struct mce *m, struct pt_regs *regs) -+{ -+ if (bank != 1) -+ return; -+ if (!(m->status & MCI_STATUS_POISON)) -+ return; -+ -+ m->cs = regs->cs; -+} -+ - /* - * Do a quick check if any of the events requires a panic. - * This decides if we keep the events around or clear them. -@@ -875,6 +895,9 @@ static __always_inline int mce_no_way_out(struct mce *m, char **msg, unsigned lo - if (mce_flags.snb_ifu_quirk) - quirk_sandybridge_ifu(i, m, regs); - -+ if (mce_flags.zen_ifu_quirk) -+ quirk_zen_ifu(i, m, regs); -+ - m->bank = i; - if (mce_severity(m, regs, &tmp, true) >= MCE_PANIC_SEVERITY) { - mce_read_aux(m, i); -@@ -1852,6 +1875,9 @@ static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) - if (c->x86 == 0x15 && c->x86_model <= 0xf) - mce_flags.overflow_recov = 1; - -+ if (c->x86 >= 0x17 && c->x86 <= 0x1A) -+ mce_flags.zen_ifu_quirk = 1; -+ - } - - if (c->x86_vendor == X86_VENDOR_INTEL) { -diff --git a/arch/x86/kernel/cpu/mce/internal.h b/arch/x86/kernel/cpu/mce/internal.h -index 7e03f5b7f6bd7..0bed57ac86c51 100644 ---- a/arch/x86/kernel/cpu/mce/internal.h -+++ b/arch/x86/kernel/cpu/mce/internal.h -@@ -157,6 +157,9 @@ struct mce_vendor_flags { - */ - smca : 1, - -+ /* Zen IFU quirk */ -+ zen_ifu_quirk : 1, -+ - /* AMD-style error thresholding banks present. */ - amd_threshold : 1, - -@@ -172,7 +175,7 @@ struct mce_vendor_flags { - /* Skylake, Cascade Lake, Cooper Lake REP;MOVS* quirk */ - skx_repmov_quirk : 1, - -- __reserved_0 : 56; -+ __reserved_0 : 55; - }; - - extern struct mce_vendor_flags mce_flags; -diff --git a/arch/x86/kernel/cpu/sgx/virt.c b/arch/x86/kernel/cpu/sgx/virt.c -index 6a77a14eee38c..f5549704ac4cb 100644 ---- a/arch/x86/kernel/cpu/sgx/virt.c -+++ b/arch/x86/kernel/cpu/sgx/virt.c -@@ -204,6 +204,7 @@ static int sgx_vepc_release(struct inode *inode, struct file *file) - continue; - - xa_erase(&vepc->page_array, index); -+ cond_resched(); - } - - /* -@@ -222,6 +223,7 @@ static int sgx_vepc_release(struct inode *inode, struct file *file) - list_add_tail(&epc_page->list, &secs_pages); - - xa_erase(&vepc->page_array, index); -+ cond_resched(); - } - - /* -@@ -243,6 +245,7 @@ static int sgx_vepc_release(struct inode *inode, struct file *file) - - if (sgx_vepc_free_page(epc_page)) - list_add_tail(&epc_page->list, &secs_pages); -+ cond_resched(); - } - - if (!list_empty(&secs_pages)) -diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c -index d4e48b4a438b2..796e2f9e87619 100644 ---- a/arch/x86/kernel/kvm.c -+++ b/arch/x86/kernel/kvm.c -@@ -972,10 +972,8 @@ static void __init kvm_init_platform(void) - * Ensure that _bss_decrypted section is marked as decrypted in the - * shared pages list. - */ -- nr_pages = DIV_ROUND_UP(__end_bss_decrypted - __start_bss_decrypted, -- PAGE_SIZE); - early_set_mem_enc_dec_hypercall((unsigned long)__start_bss_decrypted, -- nr_pages, 0); -+ __end_bss_decrypted - __start_bss_decrypted, 0); - - /* - * If not booted using EFI, enable Live migration support. -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index beca03556379d..7a6df4b62c1bd 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -55,6 +56,8 @@ - - extern bool itlb_multihit_kvm_mitigation; - -+static bool nx_hugepage_mitigation_hard_disabled; -+ - int __read_mostly nx_huge_pages = -1; - static uint __read_mostly nx_huge_pages_recovery_period_ms; - #ifdef CONFIG_PREEMPT_RT -@@ -64,12 +67,13 @@ static uint __read_mostly nx_huge_pages_recovery_ratio = 0; - static uint __read_mostly nx_huge_pages_recovery_ratio = 60; - #endif - -+static int get_nx_huge_pages(char *buffer, const struct kernel_param *kp); - static int set_nx_huge_pages(const char *val, const struct kernel_param *kp); - static int set_nx_huge_pages_recovery_param(const char *val, const struct kernel_param *kp); - - static const struct kernel_param_ops nx_huge_pages_ops = { - .set = set_nx_huge_pages, -- .get = param_get_bool, -+ .get = get_nx_huge_pages, - }; - - static const struct kernel_param_ops nx_huge_pages_recovery_param_ops = { -@@ -6644,6 +6648,14 @@ static void mmu_destroy_caches(void) - kmem_cache_destroy(mmu_page_header_cache); - } - -+static int get_nx_huge_pages(char *buffer, const struct kernel_param *kp) -+{ -+ if (nx_hugepage_mitigation_hard_disabled) -+ return sprintf(buffer, "never\n"); -+ -+ return param_get_bool(buffer, kp); -+} -+ - static bool get_nx_auto_mode(void) - { - /* Return true when CPU has the bug, and mitigations are ON */ -@@ -6660,15 +6672,29 @@ static int set_nx_huge_pages(const char *val, const struct kernel_param *kp) - bool old_val = nx_huge_pages; - bool new_val; - -+ if (nx_hugepage_mitigation_hard_disabled) -+ return -EPERM; -+ - /* In "auto" mode deploy workaround only if CPU has the bug. */ -- if (sysfs_streq(val, "off")) -+ if (sysfs_streq(val, "off")) { - new_val = 0; -- else if (sysfs_streq(val, "force")) -+ } else if (sysfs_streq(val, "force")) { - new_val = 1; -- else if (sysfs_streq(val, "auto")) -+ } else if (sysfs_streq(val, "auto")) { - new_val = get_nx_auto_mode(); -- else if (strtobool(val, &new_val) < 0) -+ } else if (sysfs_streq(val, "never")) { -+ new_val = 0; -+ -+ mutex_lock(&kvm_lock); -+ if (!list_empty(&vm_list)) { -+ mutex_unlock(&kvm_lock); -+ return -EBUSY; -+ } -+ nx_hugepage_mitigation_hard_disabled = true; -+ mutex_unlock(&kvm_lock); -+ } else if (kstrtobool(val, &new_val) < 0) { - return -EINVAL; -+ } - - __set_nx_huge_pages(new_val); - -@@ -6799,6 +6825,9 @@ static int set_nx_huge_pages_recovery_param(const char *val, const struct kernel - uint old_period, new_period; - int err; - -+ if (nx_hugepage_mitigation_hard_disabled) -+ return -EPERM; -+ - was_recovery_enabled = calc_nx_huge_pages_recovery_period(&old_period); - - err = param_set_uint(val, kp); -@@ -6922,6 +6951,9 @@ int kvm_mmu_post_init_vm(struct kvm *kvm) - { - int err; - -+ if (nx_hugepage_mitigation_hard_disabled) -+ return 0; -+ - err = kvm_vm_create_worker_thread(kvm, kvm_nx_lpage_recovery_worker, 0, - "kvm-nx-lpage-recovery", - &kvm->arch.nx_lpage_recovery_thread); -diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c -index ff6c0462beee7..3ea0f763540a4 100644 ---- a/arch/x86/mm/mem_encrypt_amd.c -+++ b/arch/x86/mm/mem_encrypt_amd.c -@@ -288,11 +288,10 @@ static bool amd_enc_cache_flush_required(void) - return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT); - } - --static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) -+static void enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) - { - #ifdef CONFIG_PARAVIRT -- unsigned long sz = npages << PAGE_SHIFT; -- unsigned long vaddr_end = vaddr + sz; -+ unsigned long vaddr_end = vaddr + size; - - while (vaddr < vaddr_end) { - int psize, pmask, level; -@@ -342,7 +341,7 @@ static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool e - snp_set_memory_private(vaddr, npages); - - if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) -- enc_dec_hypercall(vaddr, npages, enc); -+ enc_dec_hypercall(vaddr, npages << PAGE_SHIFT, enc); - - return true; - } -@@ -466,7 +465,7 @@ static int __init early_set_memory_enc_dec(unsigned long vaddr, - - ret = 0; - -- early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc); -+ early_set_mem_enc_dec_hypercall(start, size, enc); - out: - __flush_tlb_all(); - return ret; -@@ -482,9 +481,9 @@ int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size) - return early_set_memory_enc_dec(vaddr, size, true); - } - --void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) -+void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) - { -- enc_dec_hypercall(vaddr, npages, enc); -+ enc_dec_hypercall(vaddr, size, enc); - } - - void __init sme_early_init(void) -diff --git a/arch/xtensa/include/asm/core.h b/arch/xtensa/include/asm/core.h -index f856d2bcb9f36..7cef85ad9741a 100644 ---- a/arch/xtensa/include/asm/core.h -+++ b/arch/xtensa/include/asm/core.h -@@ -44,4 +44,13 @@ - #define XTENSA_STACK_ALIGNMENT 16 - #endif - -+#ifndef XCHAL_HW_MIN_VERSION -+#if defined(XCHAL_HW_MIN_VERSION_MAJOR) && defined(XCHAL_HW_MIN_VERSION_MINOR) -+#define XCHAL_HW_MIN_VERSION (XCHAL_HW_MIN_VERSION_MAJOR * 100 + \ -+ XCHAL_HW_MIN_VERSION_MINOR) -+#else -+#define XCHAL_HW_MIN_VERSION 0 -+#endif -+#endif -+ - #endif -diff --git a/arch/xtensa/kernel/perf_event.c b/arch/xtensa/kernel/perf_event.c -index a0d05c8598d0f..183618090d05b 100644 ---- a/arch/xtensa/kernel/perf_event.c -+++ b/arch/xtensa/kernel/perf_event.c -@@ -13,17 +13,26 @@ - #include - #include - -+#include - #include - #include - -+#define XTENSA_HWVERSION_RG_2015_0 260000 -+ -+#if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RG_2015_0 -+#define XTENSA_PMU_ERI_BASE 0x00101000 -+#else -+#define XTENSA_PMU_ERI_BASE 0x00001000 -+#endif -+ - /* Global control/status for all perf counters */ --#define XTENSA_PMU_PMG 0x1000 -+#define XTENSA_PMU_PMG XTENSA_PMU_ERI_BASE - /* Perf counter values */ --#define XTENSA_PMU_PM(i) (0x1080 + (i) * 4) -+#define XTENSA_PMU_PM(i) (XTENSA_PMU_ERI_BASE + 0x80 + (i) * 4) - /* Perf counter control registers */ --#define XTENSA_PMU_PMCTRL(i) (0x1100 + (i) * 4) -+#define XTENSA_PMU_PMCTRL(i) (XTENSA_PMU_ERI_BASE + 0x100 + (i) * 4) - /* Perf counter status registers */ --#define XTENSA_PMU_PMSTAT(i) (0x1180 + (i) * 4) -+#define XTENSA_PMU_PMSTAT(i) (XTENSA_PMU_ERI_BASE + 0x180 + (i) * 4) - - #define XTENSA_PMU_PMG_PMEN 0x1 - -diff --git a/block/blk-settings.c b/block/blk-settings.c -index 291cf9df7fc29..86ff375c00ce4 100644 ---- a/block/blk-settings.c -+++ b/block/blk-settings.c -@@ -824,10 +824,13 @@ EXPORT_SYMBOL(blk_set_queue_depth); - */ - void blk_queue_write_cache(struct request_queue *q, bool wc, bool fua) - { -- if (wc) -+ if (wc) { -+ blk_queue_flag_set(QUEUE_FLAG_HW_WC, q); - blk_queue_flag_set(QUEUE_FLAG_WC, q); -- else -+ } else { -+ blk_queue_flag_clear(QUEUE_FLAG_HW_WC, q); - blk_queue_flag_clear(QUEUE_FLAG_WC, q); -+ } - if (fua) - blk_queue_flag_set(QUEUE_FLAG_FUA, q); - else -diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c -index e71b3b43927c0..a582ea0da74f5 100644 ---- a/block/blk-sysfs.c -+++ b/block/blk-sysfs.c -@@ -528,21 +528,16 @@ static ssize_t queue_wc_show(struct request_queue *q, char *page) - static ssize_t queue_wc_store(struct request_queue *q, const char *page, - size_t count) - { -- int set = -1; -- -- if (!strncmp(page, "write back", 10)) -- set = 1; -- else if (!strncmp(page, "write through", 13) || -- !strncmp(page, "none", 4)) -- set = 0; -- -- if (set == -1) -- return -EINVAL; -- -- if (set) -+ if (!strncmp(page, "write back", 10)) { -+ if (!test_bit(QUEUE_FLAG_HW_WC, &q->queue_flags)) -+ return -EINVAL; - blk_queue_flag_set(QUEUE_FLAG_WC, q); -- else -+ } else if (!strncmp(page, "write through", 13) || -+ !strncmp(page, "none", 4)) { - blk_queue_flag_clear(QUEUE_FLAG_WC, q); -+ } else { -+ return -EINVAL; -+ } - - return count; - } -diff --git a/block/ioctl.c b/block/ioctl.c -index 9c5f637ff153f..3c475e4166e9f 100644 ---- a/block/ioctl.c -+++ b/block/ioctl.c -@@ -20,6 +20,8 @@ static int blkpg_do_ioctl(struct block_device *bdev, - struct blkpg_partition p; - long long start, length; - -+ if (disk->flags & GENHD_FL_NO_PART) -+ return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (copy_from_user(&p, upart, sizeof(struct blkpg_partition))) -diff --git a/block/mq-deadline.c b/block/mq-deadline.c -index f10c2a0d18d41..55e26065c2e27 100644 ---- a/block/mq-deadline.c -+++ b/block/mq-deadline.c -@@ -622,8 +622,9 @@ static void dd_depth_updated(struct blk_mq_hw_ctx *hctx) - struct request_queue *q = hctx->queue; - struct deadline_data *dd = q->elevator->elevator_data; - struct blk_mq_tags *tags = hctx->sched_tags; -+ unsigned int shift = tags->bitmap_tags.sb.shift; - -- dd->async_depth = max(1UL, 3 * q->nr_requests / 4); -+ dd->async_depth = max(1U, 3 * (1U << shift) / 4); - - sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, dd->async_depth); - } -diff --git a/crypto/algapi.c b/crypto/algapi.c -index 8c3a869cc43a9..5dc9ccdd5a510 100644 ---- a/crypto/algapi.c -+++ b/crypto/algapi.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - #include "internal.h" - -@@ -74,15 +75,26 @@ static void crypto_free_instance(struct crypto_instance *inst) - inst->alg.cra_type->free(inst); - } - --static void crypto_destroy_instance(struct crypto_alg *alg) -+static void crypto_destroy_instance_workfn(struct work_struct *w) - { -- struct crypto_instance *inst = (void *)alg; -+ struct crypto_instance *inst = container_of(w, struct crypto_instance, -+ free_work); - struct crypto_template *tmpl = inst->tmpl; - - crypto_free_instance(inst); - crypto_tmpl_put(tmpl); - } - -+static void crypto_destroy_instance(struct crypto_alg *alg) -+{ -+ struct crypto_instance *inst = container_of(alg, -+ struct crypto_instance, -+ alg); -+ -+ INIT_WORK(&inst->free_work, crypto_destroy_instance_workfn); -+ schedule_work(&inst->free_work); -+} -+ - /* - * This function adds a spawn to the list secondary_spawns which - * will be used at the end of crypto_remove_spawns to unregister -diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c -index 0b4943a4592b7..1815024bead38 100644 ---- a/crypto/asymmetric_keys/x509_public_key.c -+++ b/crypto/asymmetric_keys/x509_public_key.c -@@ -117,6 +117,11 @@ int x509_check_for_self_signed(struct x509_certificate *cert) - goto out; - } - -+ if (cert->unsupported_sig) { -+ ret = 0; -+ goto out; -+ } -+ - ret = public_key_verify_signature(cert->pub, cert->sig); - if (ret < 0) { - if (ret == -ENOPKG) { -diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c -index 3237b50baf3c5..1cf267bc6f9ea 100644 ---- a/crypto/rsa-pkcs1pad.c -+++ b/crypto/rsa-pkcs1pad.c -@@ -575,6 +575,10 @@ static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm) - return PTR_ERR(child_tfm); - - ctx->child = child_tfm; -+ -+ akcipher_set_reqsize(tfm, sizeof(struct pkcs1pad_request) + -+ crypto_akcipher_reqsize(child_tfm)); -+ - return 0; - } - -@@ -670,7 +674,6 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) - inst->alg.set_pub_key = pkcs1pad_set_pub_key; - inst->alg.set_priv_key = pkcs1pad_set_priv_key; - inst->alg.max_size = pkcs1pad_get_max_size; -- inst->alg.reqsize = sizeof(struct pkcs1pad_request) + rsa_alg->reqsize; - - inst->free = pkcs1pad_free; - -diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c -index e499c60c45791..ec84da6cc1bff 100644 ---- a/drivers/acpi/x86/s2idle.c -+++ b/drivers/acpi/x86/s2idle.c -@@ -122,17 +122,16 @@ static void lpi_device_get_constraints_amd(void) - acpi_handle_debug(lps0_device_handle, - "LPI: constraints list begin:\n"); - -- for (j = 0; j < package->package.count; ++j) { -+ for (j = 0; j < package->package.count; j++) { - union acpi_object *info_obj = &package->package.elements[j]; - struct lpi_device_constraint_amd dev_info = {}; - struct lpi_constraints *list; - acpi_status status; - -- for (k = 0; k < info_obj->package.count; ++k) { -- union acpi_object *obj = &info_obj->package.elements[k]; -+ list = &lpi_constraints_table[lpi_constraints_table_size]; - -- list = &lpi_constraints_table[lpi_constraints_table_size]; -- list->min_dstate = -1; -+ for (k = 0; k < info_obj->package.count; k++) { -+ union acpi_object *obj = &info_obj->package.elements[k]; - - switch (k) { - case 0: -@@ -148,27 +147,21 @@ static void lpi_device_get_constraints_amd(void) - dev_info.min_dstate = obj->integer.value; - break; - } -+ } - -- if (!dev_info.enabled || !dev_info.name || -- !dev_info.min_dstate) -- continue; -+ if (!dev_info.enabled || !dev_info.name || -+ !dev_info.min_dstate) -+ continue; - -- status = acpi_get_handle(NULL, dev_info.name, -- &list->handle); -- if (ACPI_FAILURE(status)) -- continue; -+ status = acpi_get_handle(NULL, dev_info.name, &list->handle); -+ if (ACPI_FAILURE(status)) -+ continue; - -- acpi_handle_debug(lps0_device_handle, -- "Name:%s\n", dev_info.name); -+ acpi_handle_debug(lps0_device_handle, -+ "Name:%s\n", dev_info.name); - -- list->min_dstate = dev_info.min_dstate; -+ list->min_dstate = dev_info.min_dstate; - -- if (list->min_dstate < 0) { -- acpi_handle_debug(lps0_device_handle, -- "Incomplete constraint defined\n"); -- continue; -- } -- } - lpi_constraints_table_size++; - } - } -@@ -213,7 +206,7 @@ static void lpi_device_get_constraints(void) - if (!package) - continue; - -- for (j = 0; j < package->package.count; ++j) { -+ for (j = 0; j < package->package.count; j++) { - union acpi_object *element = - &(package->package.elements[j]); - -@@ -245,7 +238,7 @@ static void lpi_device_get_constraints(void) - - constraint->min_dstate = -1; - -- for (j = 0; j < package_count; ++j) { -+ for (j = 0; j < package_count; j++) { - union acpi_object *info_obj = &info.package[j]; - union acpi_object *cnstr_pkg; - union acpi_object *obj; -diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c -index 110a535648d2e..0aa2d3111ae6e 100644 ---- a/drivers/amba/bus.c -+++ b/drivers/amba/bus.c -@@ -534,6 +534,7 @@ static void amba_device_release(struct device *dev) - { - struct amba_device *d = to_amba_device(dev); - -+ of_node_put(d->dev.of_node); - if (d->res.parent) - release_resource(&d->res); - mutex_destroy(&d->periphid_lock); -diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c -index e89617ed9175b..46588fc829432 100644 ---- a/drivers/ata/pata_arasan_cf.c -+++ b/drivers/ata/pata_arasan_cf.c -@@ -529,7 +529,8 @@ static void data_xfer(struct work_struct *work) - /* dma_request_channel may sleep, so calling from process context */ - acdev->dma_chan = dma_request_chan(acdev->host->dev, "data"); - if (IS_ERR(acdev->dma_chan)) { -- dev_err(acdev->host->dev, "Unable to get dma_chan\n"); -+ dev_err_probe(acdev->host->dev, PTR_ERR(acdev->dma_chan), -+ "Unable to get dma_chan\n"); - acdev->dma_chan = NULL; - goto chan_request_fail; - } -diff --git a/drivers/base/core.c b/drivers/base/core.c -index e30223c2672fc..af90bfb0cc3d8 100644 ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -3855,6 +3855,17 @@ void device_del(struct device *dev) - device_platform_notify_remove(dev); - device_links_purge(dev); - -+ /* -+ * If a device does not have a driver attached, we need to clean -+ * up any managed resources. We do this in device_release(), but -+ * it's never called (and we leak the device) if a managed -+ * resource holds a reference to the device. So release all -+ * managed resources here, like we do in driver_detach(). We -+ * still need to do so again in device_release() in case someone -+ * adds a new resource after this point, though. -+ */ -+ devres_release_all(dev); -+ - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->p->bus_notifier, - BUS_NOTIFY_REMOVED_DEVICE, dev); -diff --git a/drivers/base/dd.c b/drivers/base/dd.c -index 97ab1468a8760..380a53b6aee81 100644 ---- a/drivers/base/dd.c -+++ b/drivers/base/dd.c -@@ -674,6 +674,8 @@ re_probe: - - device_remove(dev); - driver_sysfs_remove(dev); -+ if (dev->bus && dev->bus->dma_cleanup) -+ dev->bus->dma_cleanup(dev); - device_unbind_cleanup(dev); - - goto re_probe; -diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c -index fabf87058d80b..ae6b8788d5f3f 100644 ---- a/drivers/base/regmap/regcache-rbtree.c -+++ b/drivers/base/regmap/regcache-rbtree.c -@@ -277,7 +277,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map, - - blk = krealloc(rbnode->block, - blklen * map->cache_word_size, -- GFP_KERNEL); -+ map->alloc_flags); - if (!blk) - return -ENOMEM; - -@@ -286,7 +286,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map, - if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) { - present = krealloc(rbnode->cache_present, - BITS_TO_LONGS(blklen) * sizeof(*present), -- GFP_KERNEL); -+ map->alloc_flags); - if (!present) - return -ENOMEM; - -@@ -320,7 +320,7 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg) - const struct regmap_range *range; - int i; - -- rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL); -+ rbnode = kzalloc(sizeof(*rbnode), map->alloc_flags); - if (!rbnode) - return NULL; - -@@ -346,13 +346,13 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg) - } - - rbnode->block = kmalloc_array(rbnode->blklen, map->cache_word_size, -- GFP_KERNEL); -+ map->alloc_flags); - if (!rbnode->block) - goto err_free; - - rbnode->cache_present = kcalloc(BITS_TO_LONGS(rbnode->blklen), - sizeof(*rbnode->cache_present), -- GFP_KERNEL); -+ map->alloc_flags); - if (!rbnode->cache_present) - goto err_free_block; - -diff --git a/drivers/base/test/test_async_driver_probe.c b/drivers/base/test/test_async_driver_probe.c -index 929410d0dd6fe..3465800baa6c8 100644 ---- a/drivers/base/test/test_async_driver_probe.c -+++ b/drivers/base/test/test_async_driver_probe.c -@@ -84,7 +84,7 @@ test_platform_device_register_node(char *name, int id, int nid) - - pdev = platform_device_alloc(name, id); - if (!pdev) -- return NULL; -+ return ERR_PTR(-ENOMEM); - - if (nid != NUMA_NO_NODE) - set_dev_node(&pdev->dev, nid); -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index d6f405763c56f..f2062c2a28da8 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -1984,7 +1984,7 @@ static int btusb_switch_alt_setting(struct hci_dev *hdev, int new_alts) - * alternate setting. - */ - spin_lock_irqsave(&data->rxlock, flags); -- kfree_skb(data->sco_skb); -+ dev_kfree_skb_irq(data->sco_skb); - data->sco_skb = NULL; - spin_unlock_irqrestore(&data->rxlock, flags); - -diff --git a/drivers/bluetooth/hci_nokia.c b/drivers/bluetooth/hci_nokia.c -index 05f7f6de6863d..97da0b2bfd17e 100644 ---- a/drivers/bluetooth/hci_nokia.c -+++ b/drivers/bluetooth/hci_nokia.c -@@ -734,7 +734,11 @@ static int nokia_bluetooth_serdev_probe(struct serdev_device *serdev) - return err; - } - -- clk_prepare_enable(sysclk); -+ err = clk_prepare_enable(sysclk); -+ if (err) { -+ dev_err(dev, "could not enable sysclk: %d", err); -+ return err; -+ } - btdev->sysclk_speed = clk_get_rate(sysclk); - clk_disable_unprepare(sysclk); - -diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c -index 55d917bd1f3f8..64f9eacd1b38d 100644 ---- a/drivers/bus/imx-weim.c -+++ b/drivers/bus/imx-weim.c -@@ -331,6 +331,12 @@ static int of_weim_notify(struct notifier_block *nb, unsigned long action, - "Failed to setup timing for '%pOF'\n", rd->dn); - - if (!of_node_check_flag(rd->dn, OF_POPULATED)) { -+ /* -+ * Clear the flag before adding the device so that -+ * fw_devlink doesn't skip adding consumers to this -+ * device. -+ */ -+ rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; - if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) { - dev_err(&pdev->dev, - "Failed to create child device '%pOF'\n", -diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c -index 9b7268bae66ab..ac36b01cf6d5d 100644 ---- a/drivers/bus/ti-sysc.c -+++ b/drivers/bus/ti-sysc.c -@@ -3125,7 +3125,7 @@ static int sysc_init_static_data(struct sysc *ddata) - - match = soc_device_match(sysc_soc_match); - if (match && match->data) -- sysc_soc->soc = (int)match->data; -+ sysc_soc->soc = (enum sysc_soc)(uintptr_t)match->data; - - /* - * Check and warn about possible old incomplete dtb. We now want to see -diff --git a/drivers/char/hw_random/iproc-rng200.c b/drivers/char/hw_random/iproc-rng200.c -index 06bc060534d81..c0df053cbe4b2 100644 ---- a/drivers/char/hw_random/iproc-rng200.c -+++ b/drivers/char/hw_random/iproc-rng200.c -@@ -182,6 +182,8 @@ static int iproc_rng200_probe(struct platform_device *pdev) - return PTR_ERR(priv->base); - } - -+ dev_set_drvdata(dev, priv); -+ - priv->rng.name = "iproc-rng200"; - priv->rng.read = iproc_rng200_read; - priv->rng.init = iproc_rng200_init; -@@ -199,6 +201,28 @@ static int iproc_rng200_probe(struct platform_device *pdev) - return 0; - } - -+static int __maybe_unused iproc_rng200_suspend(struct device *dev) -+{ -+ struct iproc_rng200_dev *priv = dev_get_drvdata(dev); -+ -+ iproc_rng200_cleanup(&priv->rng); -+ -+ return 0; -+} -+ -+static int __maybe_unused iproc_rng200_resume(struct device *dev) -+{ -+ struct iproc_rng200_dev *priv = dev_get_drvdata(dev); -+ -+ iproc_rng200_init(&priv->rng); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops iproc_rng200_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(iproc_rng200_suspend, iproc_rng200_resume) -+}; -+ - static const struct of_device_id iproc_rng200_of_match[] = { - { .compatible = "brcm,bcm2711-rng200", }, - { .compatible = "brcm,bcm7211-rng200", }, -@@ -212,6 +236,7 @@ static struct platform_driver iproc_rng200_driver = { - .driver = { - .name = "iproc-rng200", - .of_match_table = iproc_rng200_of_match, -+ .pm = &iproc_rng200_pm_ops, - }, - .probe = iproc_rng200_probe, - }; -diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c -index e8f9621e79541..3774adf903a83 100644 ---- a/drivers/char/hw_random/nomadik-rng.c -+++ b/drivers/char/hw_random/nomadik-rng.c -@@ -13,8 +13,6 @@ - #include - #include - --static struct clk *rng_clk; -- - static int nmk_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) - { - void __iomem *base = (void __iomem *)rng->priv; -@@ -36,21 +34,20 @@ static struct hwrng nmk_rng = { - - static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id) - { -+ struct clk *rng_clk; - void __iomem *base; - int ret; - -- rng_clk = devm_clk_get(&dev->dev, NULL); -+ rng_clk = devm_clk_get_enabled(&dev->dev, NULL); - if (IS_ERR(rng_clk)) { - dev_err(&dev->dev, "could not get rng clock\n"); - ret = PTR_ERR(rng_clk); - return ret; - } - -- clk_prepare_enable(rng_clk); -- - ret = amba_request_regions(dev, dev->dev.init_name); - if (ret) -- goto out_clk; -+ return ret; - ret = -ENOMEM; - base = devm_ioremap(&dev->dev, dev->res.start, - resource_size(&dev->res)); -@@ -64,15 +61,12 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id) - - out_release: - amba_release_regions(dev); --out_clk: -- clk_disable_unprepare(rng_clk); - return ret; - } - - static void nmk_rng_remove(struct amba_device *dev) - { - amba_release_regions(dev); -- clk_disable_unprepare(rng_clk); - } - - static const struct amba_id nmk_rng_ids[] = { -diff --git a/drivers/char/hw_random/pic32-rng.c b/drivers/char/hw_random/pic32-rng.c -index 99c8bd0859a14..e04a054e89307 100644 ---- a/drivers/char/hw_random/pic32-rng.c -+++ b/drivers/char/hw_random/pic32-rng.c -@@ -36,7 +36,6 @@ - struct pic32_rng { - void __iomem *base; - struct hwrng rng; -- struct clk *clk; - }; - - /* -@@ -70,6 +69,7 @@ static int pic32_rng_read(struct hwrng *rng, void *buf, size_t max, - static int pic32_rng_probe(struct platform_device *pdev) - { - struct pic32_rng *priv; -+ struct clk *clk; - u32 v; - int ret; - -@@ -81,13 +81,9 @@ static int pic32_rng_probe(struct platform_device *pdev) - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - -- priv->clk = devm_clk_get(&pdev->dev, NULL); -- if (IS_ERR(priv->clk)) -- return PTR_ERR(priv->clk); -- -- ret = clk_prepare_enable(priv->clk); -- if (ret) -- return ret; -+ clk = devm_clk_get_enabled(&pdev->dev, NULL); -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); - - /* enable TRNG in enhanced mode */ - v = TRNGEN | TRNGMOD; -@@ -98,15 +94,11 @@ static int pic32_rng_probe(struct platform_device *pdev) - - ret = devm_hwrng_register(&pdev->dev, &priv->rng); - if (ret) -- goto err_register; -+ return ret; - - platform_set_drvdata(pdev, priv); - - return 0; -- --err_register: -- clk_disable_unprepare(priv->clk); -- return ret; - } - - static int pic32_rng_remove(struct platform_device *pdev) -@@ -114,7 +106,6 @@ static int pic32_rng_remove(struct platform_device *pdev) - struct pic32_rng *rng = platform_get_drvdata(pdev); - - writel(0, rng->base + RNGCON); -- clk_disable_unprepare(rng->clk); - return 0; - } - -diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c -index abddd7e43a9a6..5cd031f3fc970 100644 ---- a/drivers/char/ipmi/ipmi_si_intf.c -+++ b/drivers/char/ipmi/ipmi_si_intf.c -@@ -2082,6 +2082,11 @@ static int try_smi_init(struct smi_info *new_smi) - new_smi->io.io_cleanup = NULL; - } - -+ if (rv && new_smi->si_sm) { -+ kfree(new_smi->si_sm); -+ new_smi->si_sm = NULL; -+ } -+ - return rv; - } - -diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c -index d48061ec27dd9..248459f97c67b 100644 ---- a/drivers/char/ipmi/ipmi_ssif.c -+++ b/drivers/char/ipmi/ipmi_ssif.c -@@ -1403,7 +1403,7 @@ static struct ssif_addr_info *ssif_info_find(unsigned short addr, - restart: - list_for_each_entry(info, &ssif_infos, link) { - if (info->binfo.addr == addr) { -- if (info->addr_src == SI_SMBIOS) -+ if (info->addr_src == SI_SMBIOS && !info->adapter_name) - info->adapter_name = kstrdup(adapter_name, - GFP_KERNEL); - -@@ -1603,6 +1603,11 @@ static int ssif_add_infos(struct i2c_client *client) - info->addr_src = SI_ACPI; - info->client = client; - info->adapter_name = kstrdup(client->adapter->name, GFP_KERNEL); -+ if (!info->adapter_name) { -+ kfree(info); -+ return -ENOMEM; -+ } -+ - info->binfo.addr = client->addr; - list_add_tail(&info->link, &ssif_infos); - return 0; -diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c -index 7f7f3bded4535..db0b774207d35 100644 ---- a/drivers/char/tpm/tpm_crb.c -+++ b/drivers/char/tpm/tpm_crb.c -@@ -463,28 +463,6 @@ static bool crb_req_canceled(struct tpm_chip *chip, u8 status) - return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE; - } - --static int crb_check_flags(struct tpm_chip *chip) --{ -- u32 val; -- int ret; -- -- ret = crb_request_locality(chip, 0); -- if (ret) -- return ret; -- -- ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val, NULL); -- if (ret) -- goto release; -- -- if (val == 0x414D4400U /* AMD */) -- chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED; -- --release: -- crb_relinquish_locality(chip, 0); -- -- return ret; --} -- - static const struct tpm_class_ops tpm_crb = { - .flags = TPM_OPS_AUTO_STARTUP, - .status = crb_status, -@@ -826,9 +804,14 @@ static int crb_acpi_add(struct acpi_device *device) - if (rc) - goto out; - -- rc = crb_check_flags(chip); -- if (rc) -- goto out; -+#ifdef CONFIG_X86 -+ /* A quirk for https://www.amd.com/en/support/kb/faq/pa-410 */ -+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && -+ priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) { -+ dev_info(dev, "Disabling hwrng\n"); -+ chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED; -+ } -+#endif /* CONFIG_X86 */ - - rc = tpm_chip_register(chip); - -diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig -index 5da82f2bdd211..a5dcc7293a836 100644 ---- a/drivers/clk/Kconfig -+++ b/drivers/clk/Kconfig -@@ -427,6 +427,7 @@ config COMMON_CLK_BD718XX - config COMMON_CLK_FIXED_MMIO - bool "Clock driver for Memory Mapped Fixed values" - depends on COMMON_CLK && OF -+ depends on HAS_IOMEM - help - Support for Memory Mapped IO Fixed clocks - -diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c -index cbf0d7955a00a..3e9a092e136c1 100644 ---- a/drivers/clk/imx/clk-composite-8m.c -+++ b/drivers/clk/imx/clk-composite-8m.c -@@ -97,7 +97,7 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, - int prediv_value; - int div_value; - int ret; -- u32 val; -+ u32 orig, val; - - ret = imx8m_clk_composite_compute_dividers(rate, parent_rate, - &prediv_value, &div_value); -@@ -106,13 +106,15 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, - - spin_lock_irqsave(divider->lock, flags); - -- val = readl(divider->reg); -- val &= ~((clk_div_mask(divider->width) << divider->shift) | -- (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT)); -+ orig = readl(divider->reg); -+ val = orig & ~((clk_div_mask(divider->width) << divider->shift) | -+ (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT)); - - val |= (u32)(prediv_value - 1) << divider->shift; - val |= (u32)(div_value - 1) << PCG_DIV_SHIFT; -- writel(val, divider->reg); -+ -+ if (val != orig) -+ writel(val, divider->reg); - - spin_unlock_irqrestore(divider->lock, flags); - -diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c -index 05c02f4e2a143..3d0d8f2c02dc1 100644 ---- a/drivers/clk/imx/clk-imx8mp.c -+++ b/drivers/clk/imx/clk-imx8mp.c -@@ -177,10 +177,6 @@ static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "au - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", - "clk_ext3", "clk_ext4", }; - --static const char * const imx8mp_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", -- "video_pll1_out", "sys_pll1_133m", "osc_hdmi", -- "clk_ext1", "clk_ext2", }; -- - static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", - "clk_ext2", "clk_ext3", }; -@@ -566,7 +562,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) - hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580); - hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600); - hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680); -- hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700); - hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780); - hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800); - hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880); -diff --git a/drivers/clk/imx/clk-imx8ulp.c b/drivers/clk/imx/clk-imx8ulp.c -index ca0e4a3aa454e..fa9121b3cf36a 100644 ---- a/drivers/clk/imx/clk-imx8ulp.c -+++ b/drivers/clk/imx/clk-imx8ulp.c -@@ -167,7 +167,7 @@ static int imx8ulp_clk_cgc1_init(struct platform_device *pdev) - clks[IMX8ULP_CLK_SPLL2_PRE_SEL] = imx_clk_hw_mux_flags("spll2_pre_sel", base + 0x510, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); - clks[IMX8ULP_CLK_SPLL3_PRE_SEL] = imx_clk_hw_mux_flags("spll3_pre_sel", base + 0x610, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); - -- clks[IMX8ULP_CLK_SPLL2] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll2", "spll2_pre_sel", base + 0x500); -+ clks[IMX8ULP_CLK_SPLL2] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP_1GHZ, "spll2", "spll2_pre_sel", base + 0x500); - clks[IMX8ULP_CLK_SPLL3] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll3", "spll3_pre_sel", base + 0x600); - clks[IMX8ULP_CLK_SPLL3_VCODIV] = imx_clk_hw_divider("spll3_vcodiv", "spll3", base + 0x604, 0, 6); - -diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c -index 6e7e34571fc8d..9b136c951762c 100644 ---- a/drivers/clk/imx/clk-pllv4.c -+++ b/drivers/clk/imx/clk-pllv4.c -@@ -44,11 +44,15 @@ struct clk_pllv4 { - u32 cfg_offset; - u32 num_offset; - u32 denom_offset; -+ bool use_mult_range; - }; - - /* Valid PLL MULT Table */ - static const int pllv4_mult_table[] = {33, 27, 22, 20, 17, 16}; - -+/* Valid PLL MULT range, (max, min) */ -+static const int pllv4_mult_range[] = {54, 27}; -+ - #define to_clk_pllv4(__hw) container_of(__hw, struct clk_pllv4, hw) - - #define LOCK_TIMEOUT_US USEC_PER_MSEC -@@ -94,17 +98,30 @@ static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw, - static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) - { -+ struct clk_pllv4 *pll = to_clk_pllv4(hw); - unsigned long parent_rate = *prate; - unsigned long round_rate, i; - u32 mfn, mfd = DEFAULT_MFD; - bool found = false; - u64 temp64; -- -- for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { -- round_rate = parent_rate * pllv4_mult_table[i]; -- if (rate >= round_rate) { -+ u32 mult; -+ -+ if (pll->use_mult_range) { -+ temp64 = (u64)rate; -+ do_div(temp64, parent_rate); -+ mult = temp64; -+ if (mult >= pllv4_mult_range[1] && -+ mult <= pllv4_mult_range[0]) { -+ round_rate = parent_rate * mult; - found = true; -- break; -+ } -+ } else { -+ for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { -+ round_rate = parent_rate * pllv4_mult_table[i]; -+ if (rate >= round_rate) { -+ found = true; -+ break; -+ } - } - } - -@@ -138,14 +155,20 @@ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, - return round_rate + (u32)temp64; - } - --static bool clk_pllv4_is_valid_mult(unsigned int mult) -+static bool clk_pllv4_is_valid_mult(struct clk_pllv4 *pll, unsigned int mult) - { - int i; - - /* check if mult is in valid MULT table */ -- for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { -- if (pllv4_mult_table[i] == mult) -+ if (pll->use_mult_range) { -+ if (mult >= pllv4_mult_range[1] && -+ mult <= pllv4_mult_range[0]) - return true; -+ } else { -+ for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { -+ if (pllv4_mult_table[i] == mult) -+ return true; -+ } - } - - return false; -@@ -160,7 +183,7 @@ static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate, - - mult = rate / parent_rate; - -- if (!clk_pllv4_is_valid_mult(mult)) -+ if (!clk_pllv4_is_valid_mult(pll, mult)) - return -EINVAL; - - if (parent_rate <= MAX_MFD) -@@ -227,10 +250,13 @@ struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, - - pll->base = base; - -- if (type == IMX_PLLV4_IMX8ULP) { -+ if (type == IMX_PLLV4_IMX8ULP || -+ type == IMX_PLLV4_IMX8ULP_1GHZ) { - pll->cfg_offset = IMX8ULP_PLL_CFG_OFFSET; - pll->num_offset = IMX8ULP_PLL_NUM_OFFSET; - pll->denom_offset = IMX8ULP_PLL_DENOM_OFFSET; -+ if (type == IMX_PLLV4_IMX8ULP_1GHZ) -+ pll->use_mult_range = true; - } else { - pll->cfg_offset = PLL_CFG_OFFSET; - pll->num_offset = PLL_NUM_OFFSET; -diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h -index dd49f90110e8b..fb59131395f03 100644 ---- a/drivers/clk/imx/clk.h -+++ b/drivers/clk/imx/clk.h -@@ -46,6 +46,7 @@ enum imx_pll14xx_type { - enum imx_pllv4_type { - IMX_PLLV4_IMX7ULP, - IMX_PLLV4_IMX8ULP, -+ IMX_PLLV4_IMX8ULP_1GHZ, - }; - - enum imx_pfdv2_type { -diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c -index d59a7621bb204..ee5c72369334f 100644 ---- a/drivers/clk/keystone/pll.c -+++ b/drivers/clk/keystone/pll.c -@@ -209,7 +209,7 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl) - } - - clk = clk_register_pll(NULL, node->name, parent_name, pll_data); -- if (clk) { -+ if (!IS_ERR_OR_NULL(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - return; - } -diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c -index 2d3980251e78e..5822db4f4f358 100644 ---- a/drivers/clk/qcom/gcc-sc7180.c -+++ b/drivers/clk/qcom/gcc-sc7180.c -@@ -667,6 +667,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { - .name = "gcc_sdcc2_apps_clk_src", - .parent_data = gcc_parent_data_5, - .num_parents = ARRAY_SIZE(gcc_parent_data_5), -+ .flags = CLK_OPS_PARENT_ENABLE, - .ops = &clk_rcg2_floor_ops, - }, - }; -diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c -index b3198784e1c3d..57bbd609151cd 100644 ---- a/drivers/clk/qcom/gcc-sc8280xp.c -+++ b/drivers/clk/qcom/gcc-sc8280xp.c -@@ -6760,7 +6760,7 @@ static struct gdsc pcie_0_tunnel_gdsc = { - .name = "pcie_0_tunnel_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -- .flags = VOTABLE, -+ .flags = VOTABLE | RETAIN_FF_ENABLE, - }; - - static struct gdsc pcie_1_tunnel_gdsc = { -@@ -6771,7 +6771,7 @@ static struct gdsc pcie_1_tunnel_gdsc = { - .name = "pcie_1_tunnel_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -- .flags = VOTABLE, -+ .flags = VOTABLE | RETAIN_FF_ENABLE, - }; - - /* -@@ -6786,7 +6786,7 @@ static struct gdsc pcie_2a_gdsc = { - .name = "pcie_2a_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -- .flags = VOTABLE | ALWAYS_ON, -+ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, - }; - - static struct gdsc pcie_2b_gdsc = { -@@ -6797,7 +6797,7 @@ static struct gdsc pcie_2b_gdsc = { - .name = "pcie_2b_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -- .flags = VOTABLE | ALWAYS_ON, -+ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, - }; - - static struct gdsc pcie_3a_gdsc = { -@@ -6808,7 +6808,7 @@ static struct gdsc pcie_3a_gdsc = { - .name = "pcie_3a_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -- .flags = VOTABLE | ALWAYS_ON, -+ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, - }; - - static struct gdsc pcie_3b_gdsc = { -@@ -6819,7 +6819,7 @@ static struct gdsc pcie_3b_gdsc = { - .name = "pcie_3b_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -- .flags = VOTABLE | ALWAYS_ON, -+ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, - }; - - static struct gdsc pcie_4_gdsc = { -@@ -6830,7 +6830,7 @@ static struct gdsc pcie_4_gdsc = { - .name = "pcie_4_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -- .flags = VOTABLE | ALWAYS_ON, -+ .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, - }; - - static struct gdsc ufs_card_gdsc = { -@@ -6839,6 +6839,7 @@ static struct gdsc ufs_card_gdsc = { - .name = "ufs_card_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -+ .flags = RETAIN_FF_ENABLE, - }; - - static struct gdsc ufs_phy_gdsc = { -@@ -6847,6 +6848,7 @@ static struct gdsc ufs_phy_gdsc = { - .name = "ufs_phy_gdsc", - }, - .pwrsts = PWRSTS_OFF_ON, -+ .flags = RETAIN_FF_ENABLE, - }; - - static struct gdsc usb30_mp_gdsc = { -@@ -6855,6 +6857,7 @@ static struct gdsc usb30_mp_gdsc = { - .name = "usb30_mp_gdsc", - }, - .pwrsts = PWRSTS_RET_ON, -+ .flags = RETAIN_FF_ENABLE, - }; - - static struct gdsc usb30_prim_gdsc = { -@@ -6863,6 +6866,7 @@ static struct gdsc usb30_prim_gdsc = { - .name = "usb30_prim_gdsc", - }, - .pwrsts = PWRSTS_RET_ON, -+ .flags = RETAIN_FF_ENABLE, - }; - - static struct gdsc usb30_sec_gdsc = { -@@ -6871,6 +6875,115 @@ static struct gdsc usb30_sec_gdsc = { - .name = "usb30_sec_gdsc", - }, - .pwrsts = PWRSTS_RET_ON, -+ .flags = RETAIN_FF_ENABLE, -+}; -+ -+static struct gdsc emac_0_gdsc = { -+ .gdscr = 0xaa004, -+ .pd = { -+ .name = "emac_0_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = RETAIN_FF_ENABLE, -+}; -+ -+static struct gdsc emac_1_gdsc = { -+ .gdscr = 0xba004, -+ .pd = { -+ .name = "emac_1_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = RETAIN_FF_ENABLE, -+}; -+ -+static struct gdsc usb4_1_gdsc = { -+ .gdscr = 0xb8004, -+ .pd = { -+ .name = "usb4_1_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = RETAIN_FF_ENABLE, -+}; -+ -+static struct gdsc usb4_gdsc = { -+ .gdscr = 0x2a004, -+ .pd = { -+ .name = "usb4_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = RETAIN_FF_ENABLE, -+}; -+ -+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { -+ .gdscr = 0x7d050, -+ .pd = { -+ .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = VOTABLE, -+}; -+ -+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = { -+ .gdscr = 0x7d058, -+ .pd = { -+ .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = VOTABLE, -+}; -+ -+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc = { -+ .gdscr = 0x7d054, -+ .pd = { -+ .name = "hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = VOTABLE, -+}; -+ -+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc = { -+ .gdscr = 0x7d06c, -+ .pd = { -+ .name = "hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = VOTABLE, -+}; -+ -+static struct gdsc hlos1_vote_turing_mmu_tbu0_gdsc = { -+ .gdscr = 0x7d05c, -+ .pd = { -+ .name = "hlos1_vote_turing_mmu_tbu0_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = VOTABLE, -+}; -+ -+static struct gdsc hlos1_vote_turing_mmu_tbu1_gdsc = { -+ .gdscr = 0x7d060, -+ .pd = { -+ .name = "hlos1_vote_turing_mmu_tbu1_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = VOTABLE, -+}; -+ -+static struct gdsc hlos1_vote_turing_mmu_tbu2_gdsc = { -+ .gdscr = 0x7d0a0, -+ .pd = { -+ .name = "hlos1_vote_turing_mmu_tbu2_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = VOTABLE, -+}; -+ -+static struct gdsc hlos1_vote_turing_mmu_tbu3_gdsc = { -+ .gdscr = 0x7d0a4, -+ .pd = { -+ .name = "hlos1_vote_turing_mmu_tbu3_gdsc", -+ }, -+ .pwrsts = PWRSTS_OFF_ON, -+ .flags = VOTABLE, - }; - - static struct clk_regmap *gcc_sc8280xp_clocks[] = { -@@ -7351,6 +7464,18 @@ static struct gdsc *gcc_sc8280xp_gdscs[] = { - [USB30_MP_GDSC] = &usb30_mp_gdsc, - [USB30_PRIM_GDSC] = &usb30_prim_gdsc, - [USB30_SEC_GDSC] = &usb30_sec_gdsc, -+ [EMAC_0_GDSC] = &emac_0_gdsc, -+ [EMAC_1_GDSC] = &emac_1_gdsc, -+ [USB4_1_GDSC] = &usb4_1_gdsc, -+ [USB4_GDSC] = &usb4_gdsc, -+ [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc, -+ [HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc, -+ [HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc, -+ [HLOS1_VOTE_MMNOC_MMU_TBU_SF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc, -+ [HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = &hlos1_vote_turing_mmu_tbu0_gdsc, -+ [HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = &hlos1_vote_turing_mmu_tbu1_gdsc, -+ [HLOS1_VOTE_TURING_MMU_TBU2_GDSC] = &hlos1_vote_turing_mmu_tbu2_gdsc, -+ [HLOS1_VOTE_TURING_MMU_TBU3_GDSC] = &hlos1_vote_turing_mmu_tbu3_gdsc, - }; - - static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { -diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c -index 9b4e4bb059635..cf4a7b6e0b23a 100644 ---- a/drivers/clk/qcom/gcc-sm6350.c -+++ b/drivers/clk/qcom/gcc-sm6350.c -@@ -641,6 +641,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { - .name = "gcc_sdcc2_apps_clk_src", - .parent_data = gcc_parent_data_8, - .num_parents = ARRAY_SIZE(gcc_parent_data_8), -+ .flags = CLK_OPS_PARENT_ENABLE, - .ops = &clk_rcg2_floor_ops, - }, - }; -diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c -index a0ba37656b07b..30bd561461074 100644 ---- a/drivers/clk/qcom/gcc-sm8250.c -+++ b/drivers/clk/qcom/gcc-sm8250.c -@@ -721,6 +721,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { - .name = "gcc_sdcc2_apps_clk_src", - .parent_data = gcc_parent_data_4, - .num_parents = ARRAY_SIZE(gcc_parent_data_4), -+ .flags = CLK_OPS_PARENT_ENABLE, - .ops = &clk_rcg2_floor_ops, - }, - }; -diff --git a/drivers/clk/qcom/gcc-sm8450.c b/drivers/clk/qcom/gcc-sm8450.c -index 666efa5ff9780..59c567e76d656 100644 ---- a/drivers/clk/qcom/gcc-sm8450.c -+++ b/drivers/clk/qcom/gcc-sm8450.c -@@ -904,7 +904,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { - .parent_data = gcc_parent_data_7, - .num_parents = ARRAY_SIZE(gcc_parent_data_7), - .flags = CLK_SET_RATE_PARENT, -- .ops = &clk_rcg2_ops, -+ .ops = &clk_rcg2_floor_ops, - }, - }; - -@@ -926,7 +926,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .flags = CLK_SET_RATE_PARENT, -- .ops = &clk_rcg2_ops, -+ .ops = &clk_rcg2_floor_ops, - }, - }; - -diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c -index ef15185a99c31..0bcbba2a29436 100644 ---- a/drivers/clk/qcom/gpucc-sm6350.c -+++ b/drivers/clk/qcom/gpucc-sm6350.c -@@ -24,6 +24,12 @@ - #define CX_GMU_CBCR_WAKE_MASK 0xF - #define CX_GMU_CBCR_WAKE_SHIFT 8 - -+enum { -+ DT_BI_TCXO, -+ DT_GPLL0_OUT_MAIN, -+ DT_GPLL0_OUT_MAIN_DIV, -+}; -+ - enum { - P_BI_TCXO, - P_GPLL0_OUT_MAIN, -@@ -61,6 +67,7 @@ static struct clk_alpha_pll gpu_cc_pll0 = { - .hw.init = &(struct clk_init_data){ - .name = "gpu_cc_pll0", - .parent_data = &(const struct clk_parent_data){ -+ .index = DT_BI_TCXO, - .fw_name = "bi_tcxo", - }, - .num_parents = 1, -@@ -104,6 +111,7 @@ static struct clk_alpha_pll gpu_cc_pll1 = { - .hw.init = &(struct clk_init_data){ - .name = "gpu_cc_pll1", - .parent_data = &(const struct clk_parent_data){ -+ .index = DT_BI_TCXO, - .fw_name = "bi_tcxo", - }, - .num_parents = 1, -@@ -121,11 +129,11 @@ static const struct parent_map gpu_cc_parent_map_0[] = { - }; - - static const struct clk_parent_data gpu_cc_parent_data_0[] = { -- { .fw_name = "bi_tcxo" }, -+ { .index = DT_BI_TCXO, .fw_name = "bi_tcxo" }, - { .hw = &gpu_cc_pll0.clkr.hw }, - { .hw = &gpu_cc_pll1.clkr.hw }, -- { .fw_name = "gcc_gpu_gpll0_clk" }, -- { .fw_name = "gcc_gpu_gpll0_div_clk" }, -+ { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk_src" }, -+ { .index = DT_GPLL0_OUT_MAIN_DIV, .fw_name = "gcc_gpu_gpll0_div_clk_src" }, - }; - - static const struct parent_map gpu_cc_parent_map_1[] = { -@@ -138,12 +146,12 @@ static const struct parent_map gpu_cc_parent_map_1[] = { - }; - - static const struct clk_parent_data gpu_cc_parent_data_1[] = { -- { .fw_name = "bi_tcxo" }, -+ { .index = DT_BI_TCXO, .fw_name = "bi_tcxo" }, - { .hw = &crc_div.hw }, - { .hw = &gpu_cc_pll0.clkr.hw }, - { .hw = &gpu_cc_pll1.clkr.hw }, - { .hw = &gpu_cc_pll1.clkr.hw }, -- { .fw_name = "gcc_gpu_gpll0_clk" }, -+ { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk_src" }, - }; - - static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { -diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c -index 0e914ec7aeae1..e45e32804d2c7 100644 ---- a/drivers/clk/qcom/reset.c -+++ b/drivers/clk/qcom/reset.c -@@ -16,7 +16,8 @@ static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id) - struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev); - - rcdev->ops->assert(rcdev, id); -- udelay(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */ -+ fsleep(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */ -+ - rcdev->ops->deassert(rcdev, id); - return 0; - } -diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c -index f85902e2590c7..2f54f630c8b65 100644 ---- a/drivers/clk/rockchip/clk-rk3568.c -+++ b/drivers/clk/rockchip/clk-rk3568.c -@@ -81,7 +81,7 @@ static struct rockchip_pll_rate_table rk3568_pll_rates[] = { - RK3036_PLL_RATE(108000000, 2, 45, 5, 1, 1, 0), - RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), - RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0), -- RK3036_PLL_RATE(78750000, 1, 96, 6, 4, 1, 0), -+ RK3036_PLL_RATE(78750000, 4, 315, 6, 4, 1, 0), - RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0), - { /* sentinel */ }, - }; -diff --git a/drivers/clk/sunxi-ng/ccu_mmc_timing.c b/drivers/clk/sunxi-ng/ccu_mmc_timing.c -index de33414fc5c28..c6a6ce98ca03a 100644 ---- a/drivers/clk/sunxi-ng/ccu_mmc_timing.c -+++ b/drivers/clk/sunxi-ng/ccu_mmc_timing.c -@@ -43,7 +43,7 @@ int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode) - EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode); - - /** -- * sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode -+ * sunxi_ccu_get_mmc_timing_mode: Get the current MMC clock timing mode - * @clk: clock to query - * - * Returns 0 if the clock is in old timing mode, > 0 if it is in -diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c -index e4a5b4d90f833..b448c8d6a16dd 100644 ---- a/drivers/cpufreq/amd-pstate-ut.c -+++ b/drivers/cpufreq/amd-pstate-ut.c -@@ -64,27 +64,9 @@ static struct amd_pstate_ut_struct amd_pstate_ut_cases[] = { - static bool get_shared_mem(void) - { - bool result = false; -- char path[] = "/sys/module/amd_pstate/parameters/shared_mem"; -- char buf[5] = {0}; -- struct file *filp = NULL; -- loff_t pos = 0; -- ssize_t ret; -- -- if (!boot_cpu_has(X86_FEATURE_CPPC)) { -- filp = filp_open(path, O_RDONLY, 0); -- if (IS_ERR(filp)) -- pr_err("%s unable to open %s file!\n", __func__, path); -- else { -- ret = kernel_read(filp, &buf, sizeof(buf), &pos); -- if (ret < 0) -- pr_err("%s read %s file fail ret=%ld!\n", -- __func__, path, (long)ret); -- filp_close(filp, NULL); -- } - -- if ('Y' == *buf) -- result = true; -- } -+ if (!boot_cpu_has(X86_FEATURE_CPPC)) -+ result = true; - - return result; - } -@@ -158,7 +140,7 @@ static void amd_pstate_ut_check_perf(u32 index) - if (ret) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; - pr_err("%s cppc_get_perf_caps ret=%d error!\n", __func__, ret); -- return; -+ goto skip_test; - } - - nominal_perf = cppc_perf.nominal_perf; -@@ -169,7 +151,7 @@ static void amd_pstate_ut_check_perf(u32 index) - if (ret) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; - pr_err("%s read CPPC_CAP1 ret=%d error!\n", __func__, ret); -- return; -+ goto skip_test; - } - - nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1); -@@ -187,7 +169,7 @@ static void amd_pstate_ut_check_perf(u32 index) - nominal_perf, cpudata->nominal_perf, - lowest_nonlinear_perf, cpudata->lowest_nonlinear_perf, - lowest_perf, cpudata->lowest_perf); -- return; -+ goto skip_test; - } - - if (!((highest_perf >= nominal_perf) && -@@ -198,11 +180,15 @@ static void amd_pstate_ut_check_perf(u32 index) - pr_err("%s cpu%d highest=%d >= nominal=%d > lowest_nonlinear=%d > lowest=%d > 0, the formula is incorrect!\n", - __func__, cpu, highest_perf, nominal_perf, - lowest_nonlinear_perf, lowest_perf); -- return; -+ goto skip_test; - } -+ cpufreq_cpu_put(policy); - } - - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; -+ return; -+skip_test: -+ cpufreq_cpu_put(policy); - } - - /* -@@ -230,14 +216,14 @@ static void amd_pstate_ut_check_freq(u32 index) - pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n", - __func__, cpu, cpudata->max_freq, cpudata->nominal_freq, - cpudata->lowest_nonlinear_freq, cpudata->min_freq); -- return; -+ goto skip_test; - } - - if (cpudata->min_freq != policy->min) { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; - pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d, they should be equal!\n", - __func__, cpu, cpudata->min_freq, policy->min); -- return; -+ goto skip_test; - } - - if (cpudata->boost_supported) { -@@ -249,16 +235,20 @@ static void amd_pstate_ut_check_freq(u32 index) - pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n", - __func__, cpu, policy->max, cpudata->max_freq, - cpudata->nominal_freq); -- return; -+ goto skip_test; - } - } else { - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; - pr_err("%s cpu%d must support boost!\n", __func__, cpu); -- return; -+ goto skip_test; - } -+ cpufreq_cpu_put(policy); - } - - amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; -+ return; -+skip_test: -+ cpufreq_cpu_put(policy); - } - - static int __init amd_pstate_ut_init(void) -diff --git a/drivers/cpufreq/brcmstb-avs-cpufreq.c b/drivers/cpufreq/brcmstb-avs-cpufreq.c -index 4153150e20db5..f644c5e325fb2 100644 ---- a/drivers/cpufreq/brcmstb-avs-cpufreq.c -+++ b/drivers/cpufreq/brcmstb-avs-cpufreq.c -@@ -434,7 +434,11 @@ brcm_avs_get_freq_table(struct device *dev, struct private_data *priv) - if (ret) - return ERR_PTR(ret); - -- table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1, sizeof(*table), -+ /* -+ * We allocate space for the 5 different P-STATES AVS, -+ * plus extra space for a terminating element. -+ */ -+ table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1 + 1, sizeof(*table), - GFP_KERNEL); - if (!table) - return ERR_PTR(-ENOMEM); -diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c -index 285ba51b31f60..c8912756fc06d 100644 ---- a/drivers/cpufreq/cpufreq.c -+++ b/drivers/cpufreq/cpufreq.c -@@ -450,8 +450,10 @@ void cpufreq_freq_transition_end(struct cpufreq_policy *policy, - policy->cur, - policy->cpuinfo.max_freq); - -+ spin_lock(&policy->transition_lock); - policy->transition_ongoing = false; - policy->transition_task = NULL; -+ spin_unlock(&policy->transition_lock); - - wake_up(&policy->transition_wait); - } -diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c -index d51f90f55c05c..fbe3a40987438 100644 ---- a/drivers/cpufreq/intel_pstate.c -+++ b/drivers/cpufreq/intel_pstate.c -@@ -2574,6 +2574,11 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) - intel_pstate_clear_update_util_hook(policy->cpu); - intel_pstate_hwp_set(policy->cpu); - } -+ /* -+ * policy->cur is never updated with the intel_pstate driver, but it -+ * is used as a stale frequency value. So, keep it within limits. -+ */ -+ policy->cur = policy->min; - - mutex_unlock(&intel_pstate_limits_lock); - -diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c -index d289036beff23..b10f7a1b77f11 100644 ---- a/drivers/cpufreq/powernow-k8.c -+++ b/drivers/cpufreq/powernow-k8.c -@@ -1101,7 +1101,8 @@ static int powernowk8_cpu_exit(struct cpufreq_policy *pol) - - kfree(data->powernow_table); - kfree(data); -- for_each_cpu(cpu, pol->cpus) -+ /* pol->cpus will be empty here, use related_cpus instead. */ -+ for_each_cpu(cpu, pol->related_cpus) - per_cpu(powernow_data, cpu) = NULL; - - return 0; -diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c -index 7e7ab5597d7ac..0590001db6532 100644 ---- a/drivers/cpuidle/cpuidle-pseries.c -+++ b/drivers/cpuidle/cpuidle-pseries.c -@@ -410,13 +410,7 @@ static int __init pseries_idle_probe(void) - return -ENODEV; - - if (firmware_has_feature(FW_FEATURE_SPLPAR)) { -- /* -- * Use local_paca instead of get_lppaca() since -- * preemption is not disabled, and it is not required in -- * fact, since lppaca_ptr does not need to be the value -- * associated to the current CPU, it can be from any CPU. -- */ -- if (lppaca_shared_proc(local_paca->lppaca_ptr)) { -+ if (lppaca_shared_proc()) { - cpuidle_state_table = shared_states; - max_idle_state = ARRAY_SIZE(shared_states); - } else { -diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c -index 8867275767101..51b48b57266a6 100644 ---- a/drivers/crypto/caam/caampkc.c -+++ b/drivers/crypto/caam/caampkc.c -@@ -223,7 +223,9 @@ static int caam_rsa_count_leading_zeros(struct scatterlist *sgl, - if (len && *buff) - break; - -- sg_miter_next(&miter); -+ if (!sg_miter_next(&miter)) -+ break; -+ - buff = miter.addr; - len = miter.length; - -diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pm.h b/drivers/crypto/qat/qat_common/adf_gen4_pm.h -index f8f8a9ee29e5b..db4326933d1c0 100644 ---- a/drivers/crypto/qat/qat_common/adf_gen4_pm.h -+++ b/drivers/crypto/qat/qat_common/adf_gen4_pm.h -@@ -35,7 +35,7 @@ - #define ADF_GEN4_PM_MSG_PENDING BIT(0) - #define ADF_GEN4_PM_MSG_PAYLOAD_BIT_MASK GENMASK(28, 1) - --#define ADF_GEN4_PM_DEFAULT_IDLE_FILTER (0x0) -+#define ADF_GEN4_PM_DEFAULT_IDLE_FILTER (0x6) - #define ADF_GEN4_PM_MAX_IDLE_FILTER (0x7) - - int adf_gen4_enable_pm(struct adf_accel_dev *accel_dev); -diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c -index d33006d43f761..4df5330afaa1d 100644 ---- a/drivers/crypto/stm32/stm32-hash.c -+++ b/drivers/crypto/stm32/stm32-hash.c -@@ -565,9 +565,9 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev) - } - - for_each_sg(rctx->sg, tsg, rctx->nents, i) { -+ sg[0] = *tsg; - len = sg->length; - -- sg[0] = *tsg; - if (sg_is_last(sg)) { - if (hdev->dma_mode == 1) { - len = (ALIGN(sg->length, 16) - 16); -@@ -1566,9 +1566,7 @@ static int stm32_hash_remove(struct platform_device *pdev) - if (!hdev) - return -ENODEV; - -- ret = pm_runtime_resume_and_get(hdev->dev); -- if (ret < 0) -- return ret; -+ ret = pm_runtime_get_sync(hdev->dev); - - stm32_hash_unregister_algs(hdev); - -@@ -1584,7 +1582,8 @@ static int stm32_hash_remove(struct platform_device *pdev) - pm_runtime_disable(hdev->dev); - pm_runtime_put_noidle(hdev->dev); - -- clk_disable_unprepare(hdev->clk); -+ if (ret >= 0) -+ clk_disable_unprepare(hdev->clk); - - return 0; - } -diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c -index 8c5f6f7fca112..fe6644f998872 100644 ---- a/drivers/devfreq/devfreq.c -+++ b/drivers/devfreq/devfreq.c -@@ -763,6 +763,7 @@ static void devfreq_dev_release(struct device *dev) - dev_pm_opp_put_opp_table(devfreq->opp_table); - - mutex_destroy(&devfreq->lock); -+ srcu_cleanup_notifier_head(&devfreq->transition_notifier_list); - kfree(devfreq); - } - -diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index b64ae02c26f8c..81de833ccd041 100644 ---- a/drivers/dma/Kconfig -+++ b/drivers/dma/Kconfig -@@ -210,6 +210,7 @@ config FSL_DMA - config FSL_EDMA - tristate "Freescale eDMA engine support" - depends on OF -+ depends on HAS_IOMEM - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS - help -@@ -279,6 +280,7 @@ config IMX_SDMA - - config INTEL_IDMA64 - tristate "Intel integrated DMA 64-bit support" -+ depends on HAS_IOMEM - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS - help -diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c -index 18cd8151dee02..6e1e14b376e65 100644 ---- a/drivers/dma/idxd/sysfs.c -+++ b/drivers/dma/idxd/sysfs.c -@@ -1426,7 +1426,7 @@ static ssize_t pasid_enabled_show(struct device *dev, - { - struct idxd_device *idxd = confdev_to_idxd(dev); - -- return sysfs_emit(buf, "%u\n", device_pasid_enabled(idxd)); -+ return sysfs_emit(buf, "%u\n", device_user_pasid_enabled(idxd)); - } - static DEVICE_ATTR_RO(pasid_enabled); - -diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c -index f093e08c23b16..3b09fdc507e04 100644 ---- a/drivers/dma/ste_dma40.c -+++ b/drivers/dma/ste_dma40.c -@@ -3597,6 +3597,10 @@ static int __init d40_probe(struct platform_device *pdev) - spin_lock_init(&base->lcla_pool.lock); - - base->irq = platform_get_irq(pdev, 0); -+ if (base->irq < 0) { -+ ret = base->irq; -+ goto destroy_cache; -+ } - - ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base); - if (ret) { -diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c -index a07bbfd075d06..8ec70da8d84fe 100644 ---- a/drivers/edac/igen6_edac.c -+++ b/drivers/edac/igen6_edac.c -@@ -27,7 +27,7 @@ - #include "edac_mc.h" - #include "edac_module.h" - --#define IGEN6_REVISION "v2.5" -+#define IGEN6_REVISION "v2.5.1" - - #define EDAC_MOD_STR "igen6_edac" - #define IGEN6_NMI_NAME "igen6_ibecc" -@@ -1216,9 +1216,6 @@ static int igen6_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - INIT_WORK(&ecclog_work, ecclog_work_cb); - init_irq_work(&ecclog_irq_work, ecclog_irq_work_cb); - -- /* Check if any pending errors before registering the NMI handler */ -- ecclog_handler(); -- - rc = register_err_handler(); - if (rc) - goto fail3; -@@ -1230,6 +1227,9 @@ static int igen6_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - goto fail4; - } - -+ /* Check if any pending errors before/during the registration of the error handler */ -+ ecclog_handler(); -+ - igen6_debug_setup(); - return 0; - fail4: -diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig -index 290186e44e6bd..4dd52a6a5b48d 100644 ---- a/drivers/extcon/Kconfig -+++ b/drivers/extcon/Kconfig -@@ -62,6 +62,7 @@ config EXTCON_INTEL_CHT_WC - tristate "Intel Cherrytrail Whiskey Cove PMIC extcon driver" - depends on INTEL_SOC_PMIC_CHTWC - depends on USB_SUPPORT -+ depends on POWER_SUPPLY - select USB_ROLE_SWITCH - help - Say Y here to enable extcon support for charger detection / control -diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c -index f9040bd610812..285fe7ad490d1 100644 ---- a/drivers/firmware/arm_sdei.c -+++ b/drivers/firmware/arm_sdei.c -@@ -1095,3 +1095,22 @@ int sdei_event_handler(struct pt_regs *regs, - return err; - } - NOKPROBE_SYMBOL(sdei_event_handler); -+ -+void sdei_handler_abort(void) -+{ -+ /* -+ * If the crash happened in an SDEI event handler then we need to -+ * finish the handler with the firmware so that we can have working -+ * interrupts in the crash kernel. -+ */ -+ if (__this_cpu_read(sdei_active_critical_event)) { -+ pr_warn("still in SDEI critical event context, attempting to finish handler.\n"); -+ __sdei_handler_abort(); -+ __this_cpu_write(sdei_active_critical_event, NULL); -+ } -+ if (__this_cpu_read(sdei_active_normal_event)) { -+ pr_warn("still in SDEI normal event context, attempting to finish handler.\n"); -+ __sdei_handler_abort(); -+ __this_cpu_write(sdei_active_normal_event, NULL); -+ } -+} -diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c -index 81cc3d0f6eec1..81c5f94b1be11 100644 ---- a/drivers/firmware/cirrus/cs_dsp.c -+++ b/drivers/firmware/cirrus/cs_dsp.c -@@ -939,7 +939,8 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, - ctl->alg_region.alg == alg_region->alg && - ctl->alg_region.type == alg_region->type) { - if ((!subname && !ctl->subname) || -- (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { -+ (subname && (ctl->subname_len == subname_len) && -+ !strncmp(ctl->subname, subname, ctl->subname_len))) { - if (!ctl->enabled) - ctl->enabled = 1; - return 0; -diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c -index 33a7811e12c65..4f0152b11a890 100644 ---- a/drivers/firmware/efi/libstub/x86-stub.c -+++ b/drivers/firmware/efi/libstub/x86-stub.c -@@ -61,7 +61,7 @@ preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom) - rom->data.type = SETUP_PCI; - rom->data.len = size - sizeof(struct setup_data); - rom->data.next = 0; -- rom->pcilen = pci->romsize; -+ rom->pcilen = romsize; - *__rom = rom; - - status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16, -diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c -index 77aa5c6398aa6..d081a6312627b 100644 ---- a/drivers/firmware/meson/meson_sm.c -+++ b/drivers/firmware/meson/meson_sm.c -@@ -292,6 +292,8 @@ static int __init meson_sm_probe(struct platform_device *pdev) - return -ENOMEM; - - chip = of_match_device(meson_sm_ids, dev)->data; -+ if (!chip) -+ return -EINVAL; - - if (chip->cmd_shmem_in_base) { - fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base, -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 6281e7153b475..4c550cfbc086c 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -97,7 +97,6 @@ struct ti_sci_desc { - * @node: list head - * @host_id: Host ID - * @users: Number of users of this instance -- * @is_suspending: Flag set to indicate in suspend path. - */ - struct ti_sci_info { - struct device *dev; -@@ -116,7 +115,6 @@ struct ti_sci_info { - u8 host_id; - /* protected by ti_sci_list_mutex */ - int users; -- bool is_suspending; - }; - - #define cl_to_ti_sci_info(c) container_of(c, struct ti_sci_info, cl) -@@ -418,14 +416,14 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info, - - ret = 0; - -- if (!info->is_suspending) { -+ if (system_state <= SYSTEM_RUNNING) { - /* And we wait for the response. */ - timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms); - if (!wait_for_completion_timeout(&xfer->done, timeout)) - ret = -ETIMEDOUT; - } else { - /* -- * If we are suspending, we cannot use wait_for_completion_timeout -+ * If we are !running, we cannot use wait_for_completion_timeout - * during noirq phase, so we must manually poll the completion. - */ - ret = read_poll_timeout_atomic(try_wait_for_completion, done_state, -@@ -3282,35 +3280,6 @@ static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode, - return NOTIFY_BAD; - } - --static void ti_sci_set_is_suspending(struct ti_sci_info *info, bool is_suspending) --{ -- info->is_suspending = is_suspending; --} -- --static int ti_sci_suspend(struct device *dev) --{ -- struct ti_sci_info *info = dev_get_drvdata(dev); -- /* -- * We must switch operation to polled mode now as drivers and the genpd -- * layer may make late TI SCI calls to change clock and device states -- * from the noirq phase of suspend. -- */ -- ti_sci_set_is_suspending(info, true); -- -- return 0; --} -- --static int ti_sci_resume(struct device *dev) --{ -- struct ti_sci_info *info = dev_get_drvdata(dev); -- -- ti_sci_set_is_suspending(info, false); -- -- return 0; --} -- --static DEFINE_SIMPLE_DEV_PM_OPS(ti_sci_pm_ops, ti_sci_suspend, ti_sci_resume); -- - /* Description for K2G */ - static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = { - .default_host_id = 2, -@@ -3519,7 +3488,6 @@ static struct platform_driver ti_sci_driver = { - .driver = { - .name = "ti-sci", - .of_match_table = of_match_ptr(ti_sci_of_match), -- .pm = &ti_sci_pm_ops, - }, - }; - module_platform_driver(ti_sci_driver); -diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c -index 7cec1772820d3..5eccab175e86b 100644 ---- a/drivers/fsi/fsi-master-aspeed.c -+++ b/drivers/fsi/fsi-master-aspeed.c -@@ -454,6 +454,8 @@ static ssize_t cfam_reset_store(struct device *dev, struct device_attribute *att - gpiod_set_value(aspeed->cfam_reset_gpio, 1); - usleep_range(900, 1000); - gpiod_set_value(aspeed->cfam_reset_gpio, 0); -+ usleep_range(900, 1000); -+ opb_writel(aspeed, ctrl_base + FSI_MRESP0, cpu_to_be32(FSI_MRESP_RST_ALL_MASTER)); - mutex_unlock(&aspeed->lock); - trace_fsi_master_aspeed_cfam_reset(false); - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index e6427a00cf6d6..9aac9e755609d 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -1212,6 +1212,9 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) - u16 cmd; - int r; - -+ if (!IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT)) -+ return 0; -+ - /* Bypass for VF */ - if (amdgpu_sriov_vf(adev)) - return 0; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -index 4e42dcb1950f7..9e3313dd956ae 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -@@ -554,6 +554,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) - crtc = (struct drm_crtc *)minfo->crtcs[i]; - if (crtc && crtc->base.id == info->mode_crtc.id) { - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); -+ - ui32 = amdgpu_crtc->crtc_id; - found = 1; - break; -@@ -572,7 +573,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) - if (ret) - return ret; - -- ret = copy_to_user(out, &ip, min((size_t)size, sizeof(ip))); -+ ret = copy_to_user(out, &ip, min_t(size_t, size, sizeof(ip))); - return ret ? -EFAULT : 0; - } - case AMDGPU_INFO_HW_IP_COUNT: { -@@ -718,17 +719,18 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) - ? -EFAULT : 0; - } - case AMDGPU_INFO_READ_MMR_REG: { -- unsigned n, alloc_size; -+ unsigned int n, alloc_size; - uint32_t *regs; -- unsigned se_num = (info->read_mmr_reg.instance >> -+ unsigned int se_num = (info->read_mmr_reg.instance >> - AMDGPU_INFO_MMR_SE_INDEX_SHIFT) & - AMDGPU_INFO_MMR_SE_INDEX_MASK; -- unsigned sh_num = (info->read_mmr_reg.instance >> -+ unsigned int sh_num = (info->read_mmr_reg.instance >> - AMDGPU_INFO_MMR_SH_INDEX_SHIFT) & - AMDGPU_INFO_MMR_SH_INDEX_MASK; - - /* set full masks if the userspace set all bits -- * in the bitfields */ -+ * in the bitfields -+ */ - if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) - se_num = 0xffffffff; - else if (se_num >= AMDGPU_GFX_MAX_SE) -@@ -852,7 +854,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) - return ret; - } - case AMDGPU_INFO_VCE_CLOCK_TABLE: { -- unsigned i; -+ unsigned int i; - struct drm_amdgpu_info_vce_clock_table vce_clk_table = {}; - struct amd_vce_state *vce_state; - -diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c -index de6d10390ab2f..9be6da37032a7 100644 ---- a/drivers/gpu/drm/amd/amdgpu/cik.c -+++ b/drivers/gpu/drm/amd/amdgpu/cik.c -@@ -1574,17 +1574,8 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) - u16 bridge_cfg2, gpu_cfg2; - u32 max_lw, current_lw, tmp; - -- pcie_capability_read_word(root, PCI_EXP_LNKCTL, -- &bridge_cfg); -- pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL, -- &gpu_cfg); -- -- tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; -- pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16); -- -- tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; -- pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL, -- tmp16); -+ pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); -+ pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); - - tmp = RREG32_PCIE(ixPCIE_LC_STATUS1); - max_lw = (tmp & PCIE_LC_STATUS1__LC_DETECTED_LINK_WIDTH_MASK) >> -@@ -1637,21 +1628,14 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) - msleep(100); - - /* linkctl */ -- pcie_capability_read_word(root, PCI_EXP_LNKCTL, -- &tmp16); -- tmp16 &= ~PCI_EXP_LNKCTL_HAWD; -- tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); -- pcie_capability_write_word(root, PCI_EXP_LNKCTL, -- tmp16); -- -- pcie_capability_read_word(adev->pdev, -- PCI_EXP_LNKCTL, -- &tmp16); -- tmp16 &= ~PCI_EXP_LNKCTL_HAWD; -- tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); -- pcie_capability_write_word(adev->pdev, -- PCI_EXP_LNKCTL, -- tmp16); -+ pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_HAWD, -+ bridge_cfg & -+ PCI_EXP_LNKCTL_HAWD); -+ pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_HAWD, -+ gpu_cfg & -+ PCI_EXP_LNKCTL_HAWD); - - /* linkctl2 */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL2, -diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c -index 8c5fa4b7b68a2..c7cb30efe43de 100644 ---- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c -@@ -147,14 +147,15 @@ static int psp_v13_0_wait_for_bootloader(struct psp_context *psp) - int ret; - int retry_loop; - -+ /* 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++) { -- /* Wait for bootloader to signify that is -- ready having bit 31 of C2PMSG_35 set to 1 */ -- ret = psp_wait_for(psp, -- SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), -- 0x80000000, -- 0x80000000, -- false); -+ ret = psp_wait_for( -+ psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), -+ 0x80000000, 0xffffffff, false); - - if (ret == 0) - return 0; -diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c -index 7f99e130acd06..fd34c2100bd96 100644 ---- a/drivers/gpu/drm/amd/amdgpu/si.c -+++ b/drivers/gpu/drm/amd/amdgpu/si.c -@@ -2276,17 +2276,8 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) - u16 bridge_cfg2, gpu_cfg2; - u32 max_lw, current_lw, tmp; - -- pcie_capability_read_word(root, PCI_EXP_LNKCTL, -- &bridge_cfg); -- pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL, -- &gpu_cfg); -- -- tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; -- pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16); -- -- tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; -- pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL, -- tmp16); -+ pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); -+ pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); - - tmp = RREG32_PCIE(PCIE_LC_STATUS1); - max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; -@@ -2331,21 +2322,14 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) - - mdelay(100); - -- pcie_capability_read_word(root, PCI_EXP_LNKCTL, -- &tmp16); -- tmp16 &= ~PCI_EXP_LNKCTL_HAWD; -- tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); -- pcie_capability_write_word(root, PCI_EXP_LNKCTL, -- tmp16); -- -- pcie_capability_read_word(adev->pdev, -- PCI_EXP_LNKCTL, -- &tmp16); -- tmp16 &= ~PCI_EXP_LNKCTL_HAWD; -- tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); -- pcie_capability_write_word(adev->pdev, -- PCI_EXP_LNKCTL, -- tmp16); -+ pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_HAWD, -+ bridge_cfg & -+ PCI_EXP_LNKCTL_HAWD); -+ pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_HAWD, -+ gpu_cfg & -+ PCI_EXP_LNKCTL_HAWD); - - pcie_capability_read_word(root, PCI_EXP_LNKCTL2, - &tmp16); -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 249b269e2cc53..c8e562dcd99d0 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5921,8 +5921,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, - */ - DRM_DEBUG_DRIVER("No preferred mode found\n"); - } else { -- recalculate_timing = amdgpu_freesync_vid_mode && -- is_freesync_video_mode(&mode, aconnector); -+ recalculate_timing = is_freesync_video_mode(&mode, aconnector); - if (recalculate_timing) { - freesync_mode = get_highest_refresh_rate_mode(aconnector, false); - drm_mode_copy(&saved_mode, &mode); -@@ -7016,7 +7015,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect - struct amdgpu_dm_connector *amdgpu_dm_connector = - to_amdgpu_dm_connector(connector); - -- if (!(amdgpu_freesync_vid_mode && edid)) -+ if (!edid) - return; - - if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10) -@@ -7859,10 +7858,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, - * fast updates. - */ - if (crtc->state->async_flip && -- acrtc_state->update_type != UPDATE_TYPE_FAST) -+ (acrtc_state->update_type != UPDATE_TYPE_FAST || -+ get_mem_type(old_plane_state->fb) != get_mem_type(fb))) - drm_warn_once(state->dev, - "[PLANE:%d:%s] async flip with non-fast update\n", - plane->base.id, plane->name); -+ - bundle->flip_addrs[planes_count].flip_immediate = - crtc->state->async_flip && - acrtc_state->update_type == UPDATE_TYPE_FAST && -@@ -9022,8 +9023,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, - * TODO: Refactor this function to allow this check to work - * in all conditions. - */ -- if (amdgpu_freesync_vid_mode && -- dm_new_crtc_state->stream && -+ if (dm_new_crtc_state->stream && - is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state)) - goto skip_modeset; - -@@ -9063,7 +9063,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, - } - - /* Now check if we should set freesync video mode */ -- if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream && -+ if (dm_new_crtc_state->stream && - dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && - dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream) && - is_timing_unchanged_for_freesync(new_crtc_state, -@@ -9076,7 +9076,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, - set_freesync_fixed_config(dm_new_crtc_state); - - goto skip_modeset; -- } else if (amdgpu_freesync_vid_mode && aconnector && -+ } else if (aconnector && - is_freesync_video_mode(&new_crtc_state->mode, - aconnector)) { - struct drm_display_mode *high_mode; -@@ -9815,6 +9815,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, - - /* Remove exiting planes if they are modified */ - for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { -+ if (old_plane_state->fb && new_plane_state->fb && -+ get_mem_type(old_plane_state->fb) != -+ get_mem_type(new_plane_state->fb)) -+ lock_and_validation_needed = true; -+ - ret = dm_update_plane_state(dc, state, plane, - old_plane_state, - new_plane_state, -@@ -10066,9 +10071,20 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, - struct dm_crtc_state *dm_new_crtc_state = - to_dm_crtc_state(new_crtc_state); - -+ /* -+ * Only allow async flips for fast updates that don't change -+ * the FB pitch, the DCC state, rotation, etc. -+ */ -+ if (new_crtc_state->async_flip && lock_and_validation_needed) { -+ drm_dbg_atomic(crtc->dev, -+ "[CRTC:%d:%s] async flips are only supported for fast updates\n", -+ crtc->base.id, crtc->name); -+ ret = -EINVAL; -+ goto fail; -+ } -+ - dm_new_crtc_state->update_type = lock_and_validation_needed ? -- UPDATE_TYPE_FULL : -- UPDATE_TYPE_FAST; -+ UPDATE_TYPE_FULL : UPDATE_TYPE_FAST; - } - - /* Must be success */ -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -index b9b70f4562c72..1ec643a0d00d2 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -@@ -406,18 +406,6 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, - return -EINVAL; - } - -- /* -- * Only allow async flips for fast updates that don't change the FB -- * pitch, the DCC state, rotation, etc. -- */ -- if (crtc_state->async_flip && -- dm_crtc_state->update_type != UPDATE_TYPE_FAST) { -- drm_dbg_atomic(crtc->dev, -- "[CRTC:%d:%s] async flips are only supported for fast updates\n", -- crtc->base.id, crtc->name); -- return -EINVAL; -- } -- - /* In some use cases, like reset, no stream is attached */ - if (!dm_crtc_state->stream) - return 0; -diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c -index 925d6e13620ec..1bbf85defd611 100644 ---- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c -+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c -@@ -32,6 +32,7 @@ - - #define MAX_INSTANCE 6 - #define MAX_SEGMENT 6 -+#define SMU_REGISTER_WRITE_RETRY_COUNT 5 - - struct IP_BASE_INSTANCE - { -@@ -134,6 +135,8 @@ static int dcn315_smu_send_msg_with_param( - unsigned int msg_id, unsigned int param) - { - uint32_t result; -+ uint32_t i = 0; -+ uint32_t read_back_data; - - result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000); - -@@ -150,10 +153,19 @@ static int dcn315_smu_send_msg_with_param( - /* Set the parameter register for the SMU message, unit is Mhz */ - REG_WRITE(MP1_SMN_C2PMSG_37, param); - -- /* Trigger the message transaction by writing the message ID */ -- generic_write_indirect_reg(CTX, -- REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA), -- mmMP1_C2PMSG_3, msg_id); -+ for (i = 0; i < SMU_REGISTER_WRITE_RETRY_COUNT; i++) { -+ /* Trigger the message transaction by writing the message ID */ -+ generic_write_indirect_reg(CTX, -+ REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA), -+ mmMP1_C2PMSG_3, msg_id); -+ read_back_data = generic_read_indirect_reg(CTX, -+ REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA), -+ mmMP1_C2PMSG_3); -+ if (read_back_data == msg_id) -+ break; -+ udelay(2); -+ smu_print("SMU msg id write fail %x times. \n", i + 1); -+ } - - result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000); - -diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c -index d260eaa1509ed..9378c98d02cfe 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c -+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c -@@ -1813,10 +1813,13 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) - hws->funcs.edp_backlight_control(edp_link_with_sink, false); - } - /*resume from S3, no vbios posting, no need to power down again*/ -+ clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); -+ - power_down_all_hw_blocks(dc); - disable_vga_and_power_gate_all_controllers(dc); - if (edp_link_with_sink && !keep_edp_vdd_on) - dc->hwss.edp_power_control(edp_link_with_sink, false); -+ clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); - } - bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1); - } -diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c -index 6192851c59ed8..51265a812bdc8 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c -@@ -75,6 +75,7 @@ static const struct hw_sequencer_funcs dcn301_funcs = { - .get_hw_state = dcn10_get_hw_state, - .clear_status_bits = dcn10_clear_status_bits, - .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, -+ .edp_backlight_control = dce110_edp_backlight_control, - .edp_power_control = dce110_edp_power_control, - .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, - .set_cursor_position = dcn10_set_cursor_position, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c -index cef32a1f91cdc..b735e548e26dc 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c -@@ -84,7 +84,8 @@ static enum phyd32clk_clock_source get_phy_mux_symclk( - struct dcn_dccg *dccg_dcn, - enum phyd32clk_clock_source src) - { -- if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { -+ if (dccg_dcn->base.ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && -+ dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { - if (src == PHYD32CLKC) - src = PHYD32CLKF; - if (src == PHYD32CLKD) -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c -index 8a88605827a84..551a63f7064bb 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c -@@ -32,7 +32,7 @@ - #include "dml/display_mode_vba.h" - - struct _vcs_dpi_ip_params_st dcn3_14_ip = { -- .VBlankNomDefaultUS = 800, -+ .VBlankNomDefaultUS = 668, - .gpuvm_enable = 1, - .gpuvm_max_page_table_levels = 1, - .hostvm_enable = 1, -diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c -index 7d613118cb713..8472013ff38a2 100644 ---- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c -+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c -@@ -2072,15 +2072,19 @@ static int amdgpu_device_attr_create(struct amdgpu_device *adev, - uint32_t mask, struct list_head *attr_list) - { - int ret = 0; -- struct device_attribute *dev_attr = &attr->dev_attr; -- const char *name = dev_attr->attr.name; - enum amdgpu_device_attr_states attr_states = ATTR_STATE_SUPPORTED; - struct amdgpu_device_attr_entry *attr_entry; -+ struct device_attribute *dev_attr; -+ const char *name; - - int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, - uint32_t mask, enum amdgpu_device_attr_states *states) = default_attr_update; - -- BUG_ON(!attr); -+ if (!attr) -+ return -EINVAL; -+ -+ dev_attr = &attr->dev_attr; -+ name = dev_attr->attr.name; - - attr_update = attr->attr_update ? attr->attr_update : default_attr_update; - -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c -index f7ac488a3da20..503e844baede2 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c -@@ -1305,7 +1305,7 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, - gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency; - gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency; - -- gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK]; -+ gpu_metrics->current_gfxclk = gpu_metrics->average_gfxclk_frequency; - gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK]; - gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK]; - gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0]; -diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c -index f21eb8fb76d87..3b9bd8ecda137 100644 ---- a/drivers/gpu/drm/armada/armada_overlay.c -+++ b/drivers/gpu/drm/armada/armada_overlay.c -@@ -4,6 +4,8 @@ - * Rewritten from the dovefb driver, and Armada510 manuals. - */ - -+#include -+ - #include - #include - #include -@@ -445,8 +447,8 @@ static int armada_overlay_get_property(struct drm_plane *plane, - drm_to_overlay_state(state)->colorkey_ug, - drm_to_overlay_state(state)->colorkey_vb, 0); - } else if (property == priv->colorkey_mode_prop) { -- *val = (drm_to_overlay_state(state)->colorkey_mode & -- CFG_CKMODE_MASK) >> ffs(CFG_CKMODE_MASK); -+ *val = FIELD_GET(CFG_CKMODE_MASK, -+ drm_to_overlay_state(state)->colorkey_mode); - } else if (property == priv->brightness_prop) { - *val = drm_to_overlay_state(state)->brightness + 256; - } else if (property == priv->contrast_prop) { -diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c -index 78b72739e5c3e..9f9874acfb2b7 100644 ---- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c -+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c -@@ -786,8 +786,13 @@ static void adv7511_mode_set(struct adv7511 *adv7511, - else - low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; - -- regmap_update_bits(adv7511->regmap, 0xfb, -- 0x6, low_refresh_rate << 1); -+ if (adv7511->type == ADV7511) -+ regmap_update_bits(adv7511->regmap, 0xfb, -+ 0x6, low_refresh_rate << 1); -+ else -+ regmap_update_bits(adv7511->regmap, 0x4a, -+ 0xc, low_refresh_rate << 2); -+ - regmap_update_bits(adv7511->regmap, 0x17, - 0x60, (vsync_polarity << 6) | (hsync_polarity << 5)); - -diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c -index 213263ad6a064..cf86cc05b7fca 100644 ---- a/drivers/gpu/drm/bridge/analogix/anx7625.c -+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c -@@ -874,11 +874,11 @@ static int anx7625_hdcp_enable(struct anx7625_data *ctx) - } - - /* Read downstream capability */ -- ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_READ, 0x68028, 1, &bcap); -+ ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_READ, DP_AUX_HDCP_BCAPS, 1, &bcap); - if (ret < 0) - return ret; - -- if (!(bcap & 0x01)) { -+ if (!(bcap & DP_BCAPS_HDCP_CAPABLE)) { - pr_warn("downstream not support HDCP 1.4, cap(%x).\n", bcap); - return 0; - } -@@ -933,8 +933,8 @@ static void anx7625_dp_start(struct anx7625_data *ctx) - - dev_dbg(dev, "set downstream sink into normal\n"); - /* Downstream sink enter into normal mode */ -- data = 1; -- ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, 0x000600, 1, &data); -+ data = DP_SET_POWER_D0; -+ ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, DP_SET_POWER, 1, &data); - if (ret < 0) - dev_err(dev, "IO error : set sink into normal mode fail\n"); - -@@ -973,8 +973,8 @@ static void anx7625_dp_stop(struct anx7625_data *ctx) - - dev_dbg(dev, "notify downstream enter into standby\n"); - /* Downstream monitor enter into standby mode */ -- data = 2; -- ret |= anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, 0x000600, 1, &data); -+ data = DP_SET_POWER_D3; -+ ret |= anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, DP_SET_POWER, 1, &data); - if (ret < 0) - DRM_DEV_ERROR(dev, "IO error : mute video fail\n"); - -diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c -index 53259c12d7778..e0f583a88789d 100644 ---- a/drivers/gpu/drm/bridge/tc358764.c -+++ b/drivers/gpu/drm/bridge/tc358764.c -@@ -176,7 +176,7 @@ static void tc358764_read(struct tc358764 *ctx, u16 addr, u32 *val) - if (ret >= 0) - le32_to_cpus(val); - -- dev_dbg(ctx->dev, "read: %d, addr: %d\n", addr, *val); -+ dev_dbg(ctx->dev, "read: addr=0x%04x data=0x%08x\n", addr, *val); - } - - static void tc358764_write(struct tc358764 *ctx, u16 addr, u32 val) -diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c -index f418e0b75772e..0edcf8ceb4a78 100644 ---- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c -+++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c -@@ -125,9 +125,9 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit) - return; - etnaviv_dump_core = false; - -- mutex_lock(&gpu->mmu_context->lock); -+ mutex_lock(&submit->mmu_context->lock); - -- mmu_size = etnaviv_iommu_dump_size(gpu->mmu_context); -+ mmu_size = etnaviv_iommu_dump_size(submit->mmu_context); - - /* We always dump registers, mmu, ring, hanging cmdbuf and end marker */ - n_obj = 5; -@@ -157,7 +157,7 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit) - iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN | - __GFP_NORETRY); - if (!iter.start) { -- mutex_unlock(&gpu->mmu_context->lock); -+ mutex_unlock(&submit->mmu_context->lock); - dev_warn(gpu->dev, "failed to allocate devcoredump file\n"); - return; - } -@@ -169,18 +169,18 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit) - memset(iter.hdr, 0, iter.data - iter.start); - - etnaviv_core_dump_registers(&iter, gpu); -- etnaviv_core_dump_mmu(&iter, gpu->mmu_context, mmu_size); -+ etnaviv_core_dump_mmu(&iter, submit->mmu_context, mmu_size); - etnaviv_core_dump_mem(&iter, ETDUMP_BUF_RING, gpu->buffer.vaddr, - gpu->buffer.size, - etnaviv_cmdbuf_get_va(&gpu->buffer, -- &gpu->mmu_context->cmdbuf_mapping)); -+ &submit->mmu_context->cmdbuf_mapping)); - - etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD, - submit->cmdbuf.vaddr, submit->cmdbuf.size, - etnaviv_cmdbuf_get_va(&submit->cmdbuf, -- &gpu->mmu_context->cmdbuf_mapping)); -+ &submit->mmu_context->cmdbuf_mapping)); - -- mutex_unlock(&gpu->mmu_context->lock); -+ mutex_unlock(&submit->mmu_context->lock); - - /* Reserve space for the bomap */ - if (n_bomap_pages) { -diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -index 29ee0814bccc8..68050409dd26c 100644 ---- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -+++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c -index 007af69e5026f..4c249939a6c3b 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dp.c -+++ b/drivers/gpu/drm/mediatek/mtk_dp.c -@@ -1588,7 +1588,9 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp) - u8 val; - ssize_t ret; - -- drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap); -+ ret = drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap); -+ if (ret < 0) -+ return ret; - - if (drm_dp_tps4_supported(mtk_dp->rx_cap)) - mtk_dp->train_info.channel_eq_pattern = DP_TRAINING_PATTERN_4; -@@ -1615,10 +1617,13 @@ static int mtk_dp_parse_capabilities(struct mtk_dp *mtk_dp) - return ret == 0 ? -EIO : ret; - } - -- if (val) -- drm_dp_dpcd_writeb(&mtk_dp->aux, -- DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, -- val); -+ if (val) { -+ ret = drm_dp_dpcd_writeb(&mtk_dp->aux, -+ DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, -+ val); -+ if (ret < 0) -+ return ret; -+ } - } - - return 0; -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -index 5071f1263216b..14ddfe3a6be77 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -@@ -115,10 +115,9 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt * - dma_addr_t dma_addr; - - pkt->va_base = kzalloc(size, GFP_KERNEL); -- if (!pkt->va_base) { -- kfree(pkt); -+ if (!pkt->va_base) - return -ENOMEM; -- } -+ - pkt->buf_size = size; - pkt->cl = (void *)client; - -@@ -128,7 +127,6 @@ static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt * - if (dma_mapping_error(dev, dma_addr)) { - dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size); - kfree(pkt->va_base); -- kfree(pkt); - return -ENOMEM; - } - -@@ -144,7 +142,6 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt) - dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size, - DMA_TO_DEVICE); - kfree(pkt->va_base); -- kfree(pkt); - } - #endif - -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c -index 6c204ccfb9ece..1d0374a577a5e 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c -@@ -242,7 +242,11 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) - - mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, - pgprot_writecombine(PAGE_KERNEL)); -- -+ if (!mtk_gem->kvaddr) { -+ kfree(sgt); -+ kfree(mtk_gem->pages); -+ return -ENOMEM; -+ } - out: - kfree(sgt); - iosys_map_set_vaddr(map, mtk_gem->kvaddr); -diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c -index 6c9a747eb4ad5..2428d6ac5fe96 100644 ---- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c -+++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c -@@ -521,6 +521,10 @@ struct msm_gpu *a2xx_gpu_init(struct drm_device *dev) - gpu->perfcntrs = perfcntrs; - gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs); - -+ ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); -+ if (ret) -+ goto fail; -+ - if (adreno_is_a20x(adreno_gpu)) - adreno_gpu->registers = a200_registers; - else if (adreno_is_a225(adreno_gpu)) -@@ -528,10 +532,6 @@ struct msm_gpu *a2xx_gpu_init(struct drm_device *dev) - else - adreno_gpu->registers = a220_registers; - -- ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); -- if (ret) -- goto fail; -- - if (!gpu->aspace) { - dev_err(dev->dev, "No memory protection without MMU\n"); - if (!allow_vram_carveout) { -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c -index 62f6ff6abf410..42c7e378d504d 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c -@@ -460,7 +460,8 @@ static int dpu_encoder_phys_wb_wait_for_commit_done( - wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt; - wait_info.timeout_ms = KICKOFF_TIMEOUT_MS; - -- ret = dpu_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_WB_DONE, -+ ret = dpu_encoder_helper_wait_for_irq(phys_enc, -+ phys_enc->irq[INTR_IDX_WB_DONE], - dpu_encoder_phys_wb_done_irq, &wait_info); - if (ret == -ETIMEDOUT) - _dpu_encoder_phys_wb_handle_wbdone_timeout(phys_enc); -diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c -index bd2c4ac456017..0d5ff03cb0910 100644 ---- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c -+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c -@@ -130,8 +130,7 @@ static void mdp5_plane_destroy_state(struct drm_plane *plane, - { - struct mdp5_plane_state *pstate = to_mdp5_plane_state(state); - -- if (state->fb) -- drm_framebuffer_put(state->fb); -+ __drm_atomic_helper_plane_destroy_state(state); - - kfree(pstate); - } -diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c -index acfe1b31e0792..add72bbc28b17 100644 ---- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c -+++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c -@@ -192,5 +192,5 @@ void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len, - new_blk->base_addr = base_addr; - - msm_disp_state_dump_regs(&new_blk->state, new_blk->size, base_addr); -- list_add(&new_blk->node, &disp_state->blocks); -+ list_add_tail(&new_blk->node, &disp_state->blocks); - } -diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c -index 5e067ba7e5fba..0e8622ccd3a0f 100644 ---- a/drivers/gpu/drm/panel/panel-simple.c -+++ b/drivers/gpu/drm/panel/panel-simple.c -@@ -1159,7 +1159,9 @@ static const struct panel_desc auo_t215hvn01 = { - .delay = { - .disable = 5, - .unprepare = 1000, -- } -+ }, -+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, -+ .connector_type = DRM_MODE_CONNECTOR_LVDS, - }; - - static const struct drm_display_mode avic_tm070ddh03_mode = { -diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c -index 5819737c21c67..a6f3c811ceb8e 100644 ---- a/drivers/gpu/drm/radeon/cik.c -+++ b/drivers/gpu/drm/radeon/cik.c -@@ -9534,17 +9534,8 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) - u16 bridge_cfg2, gpu_cfg2; - u32 max_lw, current_lw, tmp; - -- pcie_capability_read_word(root, PCI_EXP_LNKCTL, -- &bridge_cfg); -- pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL, -- &gpu_cfg); -- -- tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; -- pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16); -- -- tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; -- pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL, -- tmp16); -+ pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); -+ pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); - - tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1); - max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; -@@ -9591,21 +9582,14 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev) - msleep(100); - - /* linkctl */ -- pcie_capability_read_word(root, PCI_EXP_LNKCTL, -- &tmp16); -- tmp16 &= ~PCI_EXP_LNKCTL_HAWD; -- tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); -- pcie_capability_write_word(root, PCI_EXP_LNKCTL, -- tmp16); -- -- pcie_capability_read_word(rdev->pdev, -- PCI_EXP_LNKCTL, -- &tmp16); -- tmp16 &= ~PCI_EXP_LNKCTL_HAWD; -- tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); -- pcie_capability_write_word(rdev->pdev, -- PCI_EXP_LNKCTL, -- tmp16); -+ pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_HAWD, -+ bridge_cfg & -+ PCI_EXP_LNKCTL_HAWD); -+ pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_HAWD, -+ gpu_cfg & -+ PCI_EXP_LNKCTL_HAWD); - - /* linkctl2 */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL2, -diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c -index 8d5e4b25609d5..a91012447b56e 100644 ---- a/drivers/gpu/drm/radeon/si.c -+++ b/drivers/gpu/drm/radeon/si.c -@@ -7131,17 +7131,8 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev) - u16 bridge_cfg2, gpu_cfg2; - u32 max_lw, current_lw, tmp; - -- pcie_capability_read_word(root, PCI_EXP_LNKCTL, -- &bridge_cfg); -- pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL, -- &gpu_cfg); -- -- tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; -- pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16); -- -- tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; -- pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL, -- tmp16); -+ pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); -+ pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); - - tmp = RREG32_PCIE(PCIE_LC_STATUS1); - max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; -@@ -7188,22 +7179,14 @@ static void si_pcie_gen3_enable(struct radeon_device *rdev) - msleep(100); - - /* linkctl */ -- pcie_capability_read_word(root, PCI_EXP_LNKCTL, -- &tmp16); -- tmp16 &= ~PCI_EXP_LNKCTL_HAWD; -- tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); -- pcie_capability_write_word(root, -- PCI_EXP_LNKCTL, -- tmp16); -- -- pcie_capability_read_word(rdev->pdev, -- PCI_EXP_LNKCTL, -- &tmp16); -- tmp16 &= ~PCI_EXP_LNKCTL_HAWD; -- tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); -- pcie_capability_write_word(rdev->pdev, -- PCI_EXP_LNKCTL, -- tmp16); -+ pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_HAWD, -+ bridge_cfg & -+ PCI_EXP_LNKCTL_HAWD); -+ pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_HAWD, -+ gpu_cfg & -+ PCI_EXP_LNKCTL_HAWD); - - /* linkctl2 */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL2, -diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c -index 7dc681e2ee90b..d773ef4854188 100644 ---- a/drivers/gpu/drm/tegra/dpaux.c -+++ b/drivers/gpu/drm/tegra/dpaux.c -@@ -468,7 +468,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev) - - dpaux->irq = platform_get_irq(pdev, 0); - if (dpaux->irq < 0) -- return -ENXIO; -+ return dpaux->irq; - - if (!pdev->dev.pm_domain) { - dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux"); -diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c -index e62f4d16b2c6b..7e2b0e2241358 100644 ---- a/drivers/gpu/drm/tiny/repaper.c -+++ b/drivers/gpu/drm/tiny/repaper.c -@@ -533,7 +533,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb) - DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id, - epd->factored_stage_time); - -- buf = kmalloc_array(fb->width, fb->height, GFP_KERNEL); -+ buf = kmalloc(fb->width * fb->height / 8, GFP_KERNEL); - if (!buf) { - ret = -ENOMEM; - goto out_exit; -diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c -index 1de2d927c32b0..fcaa958d841c9 100644 ---- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c -+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c -@@ -201,7 +201,9 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev) - dpsub->dev = &pdev->dev; - platform_set_drvdata(pdev, dpsub); - -- dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT)); -+ ret = dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT)); -+ if (ret) -+ return ret; - - /* Try the reserved memory. Proceed if there's none. */ - of_reserved_mem_device_init(&pdev->dev); -diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c -index 3acaaca888acd..77ee5e01e6111 100644 ---- a/drivers/hid/hid-input.c -+++ b/drivers/hid/hid-input.c -@@ -961,6 +961,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - return; - - case 0x3c: /* Invert */ -+ device->quirks &= ~HID_QUIRK_NOINVERT; - map_key_clear(BTN_TOOL_RUBBER); - break; - -@@ -986,9 +987,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - case 0x45: /* ERASER */ - /* - * This event is reported when eraser tip touches the surface. -- * Actual eraser (BTN_TOOL_RUBBER) is set by Invert usage when -- * tool gets in proximity. -+ * Actual eraser (BTN_TOOL_RUBBER) is set and released either -+ * by Invert if tool reports proximity or by Eraser directly. - */ -+ if (!test_bit(BTN_TOOL_RUBBER, input->keybit)) { -+ device->quirks |= HID_QUIRK_NOINVERT; -+ set_bit(BTN_TOOL_RUBBER, input->keybit); -+ } - map_key_clear(BTN_TOUCH); - break; - -@@ -1532,6 +1537,15 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct - else if (report->tool != BTN_TOOL_RUBBER) - /* value is off, tool is not rubber, ignore */ - return; -+ else if (*quirks & HID_QUIRK_NOINVERT && -+ !test_bit(BTN_TOUCH, input->key)) { -+ /* -+ * There is no invert to release the tool, let hid_input -+ * send BTN_TOUCH with scancode and release the tool after. -+ */ -+ hid_report_release_tool(report, input, BTN_TOOL_RUBBER); -+ return; -+ } - - /* let hid-input set BTN_TOUCH */ - break; -diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c -index c358778e070bc..08768e5accedc 100644 ---- a/drivers/hid/hid-logitech-dj.c -+++ b/drivers/hid/hid-logitech-dj.c -@@ -1285,6 +1285,9 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, - * 50 msec should gives enough time to the receiver to be ready. - */ - msleep(50); -+ -+ if (retval) -+ return retval; - } - - /* -@@ -1306,7 +1309,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, - buf[5] = 0x09; - buf[6] = 0x00; - -- hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf, -+ retval = hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf, - HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT, - HID_REQ_SET_REPORT); - -diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c -index e31be0cb8b850..521b2ffb42449 100644 ---- a/drivers/hid/hid-multitouch.c -+++ b/drivers/hid/hid-multitouch.c -@@ -1594,7 +1594,6 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app) - static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) - { - struct mt_device *td = hid_get_drvdata(hdev); -- char *name; - const char *suffix = NULL; - struct mt_report_data *rdata; - struct mt_application *mt_application = NULL; -@@ -1645,15 +1644,9 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) - break; - } - -- if (suffix) { -- name = devm_kzalloc(&hi->input->dev, -- strlen(hdev->name) + strlen(suffix) + 2, -- GFP_KERNEL); -- if (name) { -- sprintf(name, "%s %s", hdev->name, suffix); -- hi->input->name = name; -- } -- } -+ if (suffix) -+ hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, -+ "%s %s", hdev->name, suffix); - - return 0; - } -diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c -index bfbb51f8b5beb..39114d5c55a0e 100644 ---- a/drivers/hid/hid-uclogic-core.c -+++ b/drivers/hid/hid-uclogic-core.c -@@ -85,10 +85,8 @@ static int uclogic_input_configured(struct hid_device *hdev, - { - struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); - struct uclogic_params *params = &drvdata->params; -- char *name; - const char *suffix = NULL; - struct hid_field *field; -- size_t len; - size_t i; - const struct uclogic_params_frame *frame; - -@@ -146,14 +144,9 @@ static int uclogic_input_configured(struct hid_device *hdev, - } - } - -- if (suffix) { -- len = strlen(hdev->name) + 2 + strlen(suffix); -- name = devm_kzalloc(&hi->input->dev, len, GFP_KERNEL); -- if (name) { -- snprintf(name, len, "%s %s", hdev->name, suffix); -- hi->input->name = name; -- } -- } -+ if (suffix) -+ hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, -+ "%s %s", hdev->name, suffix); - - return 0; - } -diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c -index b03cb7ae7fd38..e9c3f1e826baa 100644 ---- a/drivers/hv/vmbus_drv.c -+++ b/drivers/hv/vmbus_drv.c -@@ -2452,7 +2452,8 @@ static int vmbus_acpi_add(struct acpi_device *device) - * Some ancestor of the vmbus acpi device (Gen1 or Gen2 - * firmware) is the VMOD that has the mmio ranges. Get that. - */ -- for (ancestor = acpi_dev_parent(device); ancestor; -+ for (ancestor = acpi_dev_parent(device); -+ ancestor && ancestor->handle != ACPI_ROOT_OBJECT; - ancestor = acpi_dev_parent(ancestor)) { - result = acpi_walk_resources(ancestor->handle, METHOD_NAME__CRS, - vmbus_walk_resources, NULL); -diff --git a/drivers/hwmon/tmp513.c b/drivers/hwmon/tmp513.c -index 7d5f7441aceb1..b9a93ee9c2364 100644 ---- a/drivers/hwmon/tmp513.c -+++ b/drivers/hwmon/tmp513.c -@@ -434,7 +434,7 @@ static umode_t tmp51x_is_visible(const void *_data, - - switch (type) { - case hwmon_temp: -- if (data->id == tmp512 && channel == 4) -+ if (data->id == tmp512 && channel == 3) - return 0; - switch (attr) { - case hwmon_temp_input: -diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c -index 4c4cbd1f72584..3f207999377f0 100644 ---- a/drivers/hwtracing/coresight/coresight-tmc-etf.c -+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c -@@ -428,7 +428,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev, - return -EINVAL; - - /* wrap head around to the amount of space we have */ -- head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1); -+ head = handle->head & (((unsigned long)buf->nr_pages << PAGE_SHIFT) - 1); - - /* find the page to write to */ - buf->cur = head / PAGE_SIZE; -diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c -index 368f2e5a86278..1be0e5e0e80b2 100644 ---- a/drivers/hwtracing/coresight/coresight-tmc-etr.c -+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c -@@ -45,7 +45,8 @@ struct etr_perf_buffer { - }; - - /* Convert the perf index to an offset within the ETR buffer */ --#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT)) -+#define PERF_IDX2OFF(idx, buf) \ -+ ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT)) - - /* Lower limit for ETR hardware buffer */ - #define TMC_ETR_PERF_MIN_BUF_SIZE SZ_1M -@@ -1249,7 +1250,7 @@ alloc_etr_buf(struct tmc_drvdata *drvdata, struct perf_event *event, - * than the size requested via sysfs. - */ - if ((nr_pages << PAGE_SHIFT) > drvdata->size) { -- etr_buf = tmc_alloc_etr_buf(drvdata, (nr_pages << PAGE_SHIFT), -+ etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT), - 0, node, NULL); - if (!IS_ERR(etr_buf)) - goto done; -diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h -index 66959557cf398..946aab12f9807 100644 ---- a/drivers/hwtracing/coresight/coresight-tmc.h -+++ b/drivers/hwtracing/coresight/coresight-tmc.h -@@ -325,7 +325,7 @@ ssize_t tmc_sg_table_get_data(struct tmc_sg_table *sg_table, - static inline unsigned long - tmc_sg_table_buf_size(struct tmc_sg_table *sg_table) - { -- return sg_table->data_pages.nr_pages << PAGE_SHIFT; -+ return (unsigned long)sg_table->data_pages.nr_pages << PAGE_SHIFT; - } - - struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata); -diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c -index 1fc4fd79a1c69..925f6c9cecff4 100644 ---- a/drivers/hwtracing/coresight/coresight-trbe.c -+++ b/drivers/hwtracing/coresight/coresight-trbe.c -@@ -1223,6 +1223,16 @@ static void arm_trbe_enable_cpu(void *info) - enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE); - } - -+static void arm_trbe_disable_cpu(void *info) -+{ -+ struct trbe_drvdata *drvdata = info; -+ struct trbe_cpudata *cpudata = this_cpu_ptr(drvdata->cpudata); -+ -+ disable_percpu_irq(drvdata->irq); -+ trbe_reset_local(cpudata); -+} -+ -+ - static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cpu) - { - struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu); -@@ -1324,18 +1334,12 @@ cpu_clear: - cpumask_clear_cpu(cpu, &drvdata->supported_cpus); - } - --static void arm_trbe_remove_coresight_cpu(void *info) -+static void arm_trbe_remove_coresight_cpu(struct trbe_drvdata *drvdata, int cpu) - { -- int cpu = smp_processor_id(); -- struct trbe_drvdata *drvdata = info; -- struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu); - struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu); - -- disable_percpu_irq(drvdata->irq); -- trbe_reset_local(cpudata); - if (trbe_csdev) { - coresight_unregister(trbe_csdev); -- cpudata->drvdata = NULL; - coresight_set_percpu_sink(cpu, NULL); - } - } -@@ -1364,8 +1368,10 @@ static int arm_trbe_remove_coresight(struct trbe_drvdata *drvdata) - { - int cpu; - -- for_each_cpu(cpu, &drvdata->supported_cpus) -- smp_call_function_single(cpu, arm_trbe_remove_coresight_cpu, drvdata, 1); -+ for_each_cpu(cpu, &drvdata->supported_cpus) { -+ smp_call_function_single(cpu, arm_trbe_disable_cpu, drvdata, 1); -+ arm_trbe_remove_coresight_cpu(drvdata, cpu); -+ } - free_percpu(drvdata->cpudata); - return 0; - } -@@ -1404,12 +1410,8 @@ static int arm_trbe_cpu_teardown(unsigned int cpu, struct hlist_node *node) - { - struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node); - -- if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) { -- struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu); -- -- disable_percpu_irq(drvdata->irq); -- trbe_reset_local(cpudata); -- } -+ if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) -+ arm_trbe_disable_cpu(drvdata); - return 0; - } - -diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c -index 3ed74aa4b44bb..1073f82d5dd47 100644 ---- a/drivers/i2c/i2c-core-of.c -+++ b/drivers/i2c/i2c-core-of.c -@@ -244,6 +244,11 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action, - return NOTIFY_OK; - } - -+ /* -+ * Clear the flag before adding the device so that fw_devlink -+ * doesn't skip adding consumers to this device. -+ */ -+ rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; - client = of_i2c_register_device(adap, rd->dn); - if (IS_ERR(client)) { - dev_err(&adap->dev, "failed to create client for '%pOF'\n", -diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c -index d47360f8a1f36..4eebf15f685a3 100644 ---- a/drivers/i3c/master/svc-i3c-master.c -+++ b/drivers/i3c/master/svc-i3c-master.c -@@ -782,6 +782,10 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master, - */ - break; - } else if (SVC_I3C_MSTATUS_NACKED(reg)) { -+ /* No I3C devices attached */ -+ if (dev_nb == 0) -+ break; -+ - /* - * A slave device nacked the address, this is - * allowed only once, DAA will be stopped and -@@ -1251,11 +1255,17 @@ static int svc_i3c_master_send_ccc_cmd(struct i3c_master_controller *m, - { - struct svc_i3c_master *master = to_svc_i3c_master(m); - bool broadcast = cmd->id < 0x80; -+ int ret; - - if (broadcast) -- return svc_i3c_master_send_bdcast_ccc_cmd(master, cmd); -+ ret = svc_i3c_master_send_bdcast_ccc_cmd(master, cmd); - else -- return svc_i3c_master_send_direct_ccc_cmd(master, cmd); -+ ret = svc_i3c_master_send_direct_ccc_cmd(master, cmd); -+ -+ if (ret) -+ cmd->err = I3C_ERROR_M2; -+ -+ return ret; - } - - static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev, -diff --git a/drivers/iio/accel/adxl313_i2c.c b/drivers/iio/accel/adxl313_i2c.c -index 99cc7fc294882..68785bd3ef2f0 100644 ---- a/drivers/iio/accel/adxl313_i2c.c -+++ b/drivers/iio/accel/adxl313_i2c.c -@@ -40,8 +40,8 @@ static const struct regmap_config adxl31x_i2c_regmap_config[] = { - - static const struct i2c_device_id adxl313_i2c_id[] = { - { .name = "adxl312", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] }, -- { .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] }, -- { .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] }, -+ { .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL313] }, -+ { .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL314] }, - { } - }; - -diff --git a/drivers/infiniband/core/uverbs_std_types_counters.c b/drivers/infiniband/core/uverbs_std_types_counters.c -index 999da9c798668..381aa57976417 100644 ---- a/drivers/infiniband/core/uverbs_std_types_counters.c -+++ b/drivers/infiniband/core/uverbs_std_types_counters.c -@@ -107,6 +107,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_READ)( - return ret; - - uattr = uverbs_attr_get(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF); -+ if (IS_ERR(uattr)) -+ return PTR_ERR(uattr); - read_attr.ncounters = uattr->ptr_attr.len / sizeof(u64); - read_attr.counters_buff = uverbs_zalloc( - attrs, array_size(read_attr.ncounters, sizeof(u64))); -diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c -index f9526a4c75b26..90d5f1a96f3e5 100644 ---- a/drivers/infiniband/hw/efa/efa_verbs.c -+++ b/drivers/infiniband/hw/efa/efa_verbs.c -@@ -443,12 +443,12 @@ int efa_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) - - ibdev_dbg(&dev->ibdev, "Destroy qp[%u]\n", ibqp->qp_num); - -- efa_qp_user_mmap_entries_remove(qp); -- - err = efa_destroy_qp_handle(dev, qp->qp_handle); - if (err) - return err; - -+ efa_qp_user_mmap_entries_remove(qp); -+ - if (qp->rq_cpu_addr) { - ibdev_dbg(&dev->ibdev, - "qp->cpu_addr[0x%p] freed: size[%lu], dma[%pad]\n", -@@ -1007,8 +1007,8 @@ int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) - "Destroy cq[%d] virt[0x%p] freed: size[%lu], dma[%pad]\n", - cq->cq_idx, cq->cpu_addr, cq->size, &cq->dma_addr); - -- efa_cq_user_mmap_entries_remove(cq); - efa_destroy_cq_idx(dev, cq->cq_idx); -+ efa_cq_user_mmap_entries_remove(cq); - if (cq->eq) { - xa_erase(&dev->cqs_xa, cq->cq_idx); - synchronize_irq(cq->eq->irq.irqn); -diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h -index f701cc86896b3..1112afa0af552 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_device.h -+++ b/drivers/infiniband/hw/hns/hns_roce_device.h -@@ -97,6 +97,7 @@ - #define HNS_ROCE_CQ_BANK_NUM 4 - - #define CQ_BANKID_SHIFT 2 -+#define CQ_BANKID_MASK GENMASK(1, 0) - - enum { - SERV_TYPE_RC, -diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -index 34a270b6891a9..33980485ef5ba 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -@@ -757,7 +757,8 @@ out: - qp->sq.head += nreq; - qp->next_sge = sge_idx; - -- if (nreq == 1 && (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE)) -+ if (nreq == 1 && !ret && -+ (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE)) - write_dwqe(hr_dev, qp, wqe); - else - update_sq_db(hr_dev, qp); -@@ -6864,14 +6865,14 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) - ret = hns_roce_init(hr_dev); - if (ret) { - dev_err(hr_dev->dev, "RoCE Engine init failed!\n"); -- goto error_failed_cfg; -+ goto error_failed_roce_init; - } - - if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) { - ret = free_mr_init(hr_dev); - if (ret) { - dev_err(hr_dev->dev, "failed to init free mr!\n"); -- goto error_failed_roce_init; -+ goto error_failed_free_mr_init; - } - } - -@@ -6879,10 +6880,10 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) - - return 0; - --error_failed_roce_init: -+error_failed_free_mr_init: - hns_roce_exit(hr_dev); - --error_failed_cfg: -+error_failed_roce_init: - kfree(hr_dev->priv); - - error_failed_kzalloc: -diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c -index 946ba1109e878..da1b33d818d82 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_main.c -+++ b/drivers/infiniband/hw/hns/hns_roce_main.c -@@ -219,6 +219,7 @@ static int hns_roce_query_port(struct ib_device *ib_dev, u32 port_num, - unsigned long flags; - enum ib_mtu mtu; - u32 port; -+ int ret; - - port = port_num - 1; - -@@ -231,8 +232,10 @@ static int hns_roce_query_port(struct ib_device *ib_dev, u32 port_num, - IB_PORT_BOOT_MGMT_SUP; - props->max_msg_sz = HNS_ROCE_MAX_MSG_LEN; - props->pkey_tbl_len = 1; -- props->active_width = IB_WIDTH_4X; -- props->active_speed = 1; -+ ret = ib_get_eth_speed(ib_dev, port_num, &props->active_speed, -+ &props->active_width); -+ if (ret) -+ ibdev_warn(ib_dev, "failed to get speed, ret = %d.\n", ret); - - spin_lock_irqsave(&hr_dev->iboe.lock, flags); - -diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c -index 0ae335fb205ca..7a95f8677a02c 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_qp.c -+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c -@@ -170,14 +170,29 @@ static void hns_roce_ib_qp_event(struct hns_roce_qp *hr_qp, - } - } - --static u8 get_least_load_bankid_for_qp(struct hns_roce_bank *bank) -+static u8 get_affinity_cq_bank(u8 qp_bank) - { -- u32 least_load = bank[0].inuse; -+ return (qp_bank >> 1) & CQ_BANKID_MASK; -+} -+ -+static u8 get_least_load_bankid_for_qp(struct ib_qp_init_attr *init_attr, -+ struct hns_roce_bank *bank) -+{ -+#define INVALID_LOAD_QPNUM 0xFFFFFFFF -+ struct ib_cq *scq = init_attr->send_cq; -+ u32 least_load = INVALID_LOAD_QPNUM; -+ unsigned long cqn = 0; - u8 bankid = 0; - u32 bankcnt; - u8 i; - -- for (i = 1; i < HNS_ROCE_QP_BANK_NUM; i++) { -+ if (scq) -+ cqn = to_hr_cq(scq)->cqn; -+ -+ for (i = 0; i < HNS_ROCE_QP_BANK_NUM; i++) { -+ if (scq && (get_affinity_cq_bank(i) != (cqn & CQ_BANKID_MASK))) -+ continue; -+ - bankcnt = bank[i].inuse; - if (bankcnt < least_load) { - least_load = bankcnt; -@@ -209,7 +224,8 @@ static int alloc_qpn_with_bankid(struct hns_roce_bank *bank, u8 bankid, - - return 0; - } --static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) -+static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, -+ struct ib_qp_init_attr *init_attr) - { - struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; - unsigned long num = 0; -@@ -220,7 +236,7 @@ static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) - num = 1; - } else { - mutex_lock(&qp_table->bank_mutex); -- bankid = get_least_load_bankid_for_qp(qp_table->bank); -+ bankid = get_least_load_bankid_for_qp(init_attr, qp_table->bank); - - ret = alloc_qpn_with_bankid(&qp_table->bank[bankid], bankid, - &num); -@@ -1146,7 +1162,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, - goto err_buf; - } - -- ret = alloc_qpn(hr_dev, hr_qp); -+ ret = alloc_qpn(hr_dev, hr_qp, init_attr); - if (ret) { - ibdev_err(ibdev, "failed to alloc QPN, ret = %d.\n", ret); - goto err_qpn; -diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c -index 6544c9c60b7db..d98bfb83c3b4b 100644 ---- a/drivers/infiniband/hw/irdma/ctrl.c -+++ b/drivers/infiniband/hw/irdma/ctrl.c -@@ -1061,6 +1061,9 @@ static int irdma_sc_alloc_stag(struct irdma_sc_dev *dev, - u64 hdr; - enum irdma_page_size page_size; - -+ if (!info->total_len && !info->all_memory) -+ return -EINVAL; -+ - if (info->page_size == 0x40000000) - page_size = IRDMA_PAGE_SIZE_1G; - else if (info->page_size == 0x200000) -@@ -1126,6 +1129,9 @@ static int irdma_sc_mr_reg_non_shared(struct irdma_sc_dev *dev, - u8 addr_type; - enum irdma_page_size page_size; - -+ if (!info->total_len && !info->all_memory) -+ return -EINVAL; -+ - if (info->page_size == 0x40000000) - page_size = IRDMA_PAGE_SIZE_1G; - else if (info->page_size == 0x200000) -diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h -index e64205839d039..9cbe64311f985 100644 ---- a/drivers/infiniband/hw/irdma/main.h -+++ b/drivers/infiniband/hw/irdma/main.h -@@ -236,7 +236,7 @@ struct irdma_qv_info { - - struct irdma_qvlist_info { - u32 num_vectors; -- struct irdma_qv_info qv_info[1]; -+ struct irdma_qv_info qv_info[]; - }; - - struct irdma_gen_ops { -diff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h -index d6cb94dc744c5..1c7cbf7c67bed 100644 ---- a/drivers/infiniband/hw/irdma/type.h -+++ b/drivers/infiniband/hw/irdma/type.h -@@ -1015,6 +1015,7 @@ struct irdma_allocate_stag_info { - bool remote_access:1; - bool use_hmc_fcn_index:1; - bool use_pf_rid:1; -+ bool all_memory:1; - u8 hmc_fcn_index; - }; - -@@ -1042,6 +1043,7 @@ struct irdma_reg_ns_stag_info { - bool use_hmc_fcn_index:1; - u8 hmc_fcn_index; - bool use_pf_rid:1; -+ bool all_memory:1; - }; - - struct irdma_fast_reg_stag_info { -diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c -index 6a8bb6ed4bf43..3b8b2341981ea 100644 ---- a/drivers/infiniband/hw/irdma/verbs.c -+++ b/drivers/infiniband/hw/irdma/verbs.c -@@ -2557,7 +2557,8 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, - struct irdma_mr *iwmr) - { - struct irdma_allocate_stag_info *info; -- struct irdma_pd *iwpd = to_iwpd(iwmr->ibmr.pd); -+ struct ib_pd *pd = iwmr->ibmr.pd; -+ struct irdma_pd *iwpd = to_iwpd(pd); - int status; - struct irdma_cqp_request *cqp_request; - struct cqp_cmds_info *cqp_info; -@@ -2573,6 +2574,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, - info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S; - info->pd_id = iwpd->sc_pd.pd_id; - info->total_len = iwmr->len; -+ info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; - info->remote_access = true; - cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG; - cqp_info->post_sq = 1; -@@ -2620,6 +2622,8 @@ static struct ib_mr *irdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, - iwmr->type = IRDMA_MEMREG_TYPE_MEM; - palloc = &iwpbl->pble_alloc; - iwmr->page_cnt = max_num_sg; -+ /* Use system PAGE_SIZE as the sg page sizes are unknown at this point */ -+ iwmr->len = max_num_sg * PAGE_SIZE; - err_code = irdma_get_pble(iwdev->rf->pble_rsrc, palloc, iwmr->page_cnt, - false); - if (err_code) -@@ -2699,7 +2703,8 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, - { - struct irdma_pbl *iwpbl = &iwmr->iwpbl; - struct irdma_reg_ns_stag_info *stag_info; -- struct irdma_pd *iwpd = to_iwpd(iwmr->ibmr.pd); -+ struct ib_pd *pd = iwmr->ibmr.pd; -+ struct irdma_pd *iwpd = to_iwpd(pd); - struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc; - struct irdma_cqp_request *cqp_request; - struct cqp_cmds_info *cqp_info; -@@ -2718,6 +2723,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, - stag_info->total_len = iwmr->len; - stag_info->access_rights = irdma_get_mr_access(access); - stag_info->pd_id = iwpd->sc_pd.pd_id; -+ stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; - if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED) - stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED; - else -@@ -4354,7 +4360,6 @@ static int irdma_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) - ah_attr->grh.traffic_class = ah->sc_ah.ah_info.tc_tos; - ah_attr->grh.hop_limit = ah->sc_ah.ah_info.hop_ttl; - ah_attr->grh.sgid_index = ah->sgid_index; -- ah_attr->grh.sgid_index = ah->sgid_index; - memcpy(&ah_attr->grh.dgid, &ah->dgid, - sizeof(ah_attr->grh.dgid)); - } -diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c -index fb0c008af78cc..d2a2501236174 100644 ---- a/drivers/infiniband/sw/rxe/rxe_comp.c -+++ b/drivers/infiniband/sw/rxe/rxe_comp.c -@@ -118,7 +118,7 @@ void retransmit_timer(struct timer_list *t) - - if (qp->valid) { - qp->comp.timeout = 1; -- rxe_run_task(&qp->comp.task, 1); -+ rxe_sched_task(&qp->comp.task); - } - } - -@@ -132,7 +132,10 @@ void rxe_comp_queue_pkt(struct rxe_qp *qp, struct sk_buff *skb) - if (must_sched != 0) - rxe_counter_inc(SKB_TO_PKT(skb)->rxe, RXE_CNT_COMPLETER_SCHED); - -- rxe_run_task(&qp->comp.task, must_sched); -+ if (must_sched) -+ rxe_sched_task(&qp->comp.task); -+ else -+ rxe_run_task(&qp->comp.task); - } - - static inline enum comp_state get_wqe(struct rxe_qp *qp, -@@ -305,7 +308,7 @@ static inline enum comp_state check_ack(struct rxe_qp *qp, - qp->comp.psn = pkt->psn; - if (qp->req.wait_psn) { - qp->req.wait_psn = 0; -- rxe_run_task(&qp->req.task, 0); -+ rxe_run_task(&qp->req.task); - } - } - return COMPST_ERROR_RETRY; -@@ -452,7 +455,7 @@ static void do_complete(struct rxe_qp *qp, struct rxe_send_wqe *wqe) - */ - if (qp->req.wait_fence) { - qp->req.wait_fence = 0; -- rxe_run_task(&qp->req.task, 0); -+ rxe_run_task(&qp->req.task); - } - } - -@@ -466,7 +469,7 @@ static inline enum comp_state complete_ack(struct rxe_qp *qp, - if (qp->req.need_rd_atomic) { - qp->comp.timeout_retry = 0; - qp->req.need_rd_atomic = 0; -- rxe_run_task(&qp->req.task, 0); -+ rxe_run_task(&qp->req.task); - } - } - -@@ -512,7 +515,7 @@ static inline enum comp_state complete_wqe(struct rxe_qp *qp, - - if (qp->req.wait_psn) { - qp->req.wait_psn = 0; -- rxe_run_task(&qp->req.task, 1); -+ rxe_sched_task(&qp->req.task); - } - } - -@@ -646,7 +649,7 @@ int rxe_completer(void *arg) - - if (qp->req.wait_psn) { - qp->req.wait_psn = 0; -- rxe_run_task(&qp->req.task, 1); -+ rxe_sched_task(&qp->req.task); - } - - state = COMPST_DONE; -@@ -714,7 +717,7 @@ int rxe_completer(void *arg) - RXE_CNT_COMP_RETRY); - qp->req.need_retry = 1; - qp->comp.started_retry = 1; -- rxe_run_task(&qp->req.task, 0); -+ rxe_run_task(&qp->req.task); - } - goto done; - -diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c -index 65d16024b3bf6..719432808a063 100644 ---- a/drivers/infiniband/sw/rxe/rxe_net.c -+++ b/drivers/infiniband/sw/rxe/rxe_net.c -@@ -348,7 +348,7 @@ static void rxe_skb_tx_dtor(struct sk_buff *skb) - - if (unlikely(qp->need_req_skb && - skb_out < RXE_INFLIGHT_SKBS_PER_QP_LOW)) -- rxe_run_task(&qp->req.task, 1); -+ rxe_sched_task(&qp->req.task); - - rxe_put(qp); - } -@@ -435,7 +435,7 @@ int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, - if ((qp_type(qp) != IB_QPT_RC) && - (pkt->mask & RXE_END_MASK)) { - pkt->wqe->state = wqe_state_done; -- rxe_run_task(&qp->comp.task, 1); -+ rxe_sched_task(&qp->comp.task); - } - - rxe_counter_inc(rxe, RXE_CNT_SENT_PKTS); -diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c -index 59b2024b34ef4..709c63e9773c5 100644 ---- a/drivers/infiniband/sw/rxe/rxe_qp.c -+++ b/drivers/infiniband/sw/rxe/rxe_qp.c -@@ -539,10 +539,10 @@ static void rxe_qp_drain(struct rxe_qp *qp) - if (qp->req.state != QP_STATE_DRAINED) { - qp->req.state = QP_STATE_DRAIN; - if (qp_type(qp) == IB_QPT_RC) -- rxe_run_task(&qp->comp.task, 1); -+ rxe_sched_task(&qp->comp.task); - else - __rxe_do_task(&qp->comp.task); -- rxe_run_task(&qp->req.task, 1); -+ rxe_sched_task(&qp->req.task); - } - } - } -@@ -556,13 +556,13 @@ void rxe_qp_error(struct rxe_qp *qp) - qp->attr.qp_state = IB_QPS_ERR; - - /* drain work and packet queues */ -- rxe_run_task(&qp->resp.task, 1); -+ rxe_sched_task(&qp->resp.task); - - if (qp_type(qp) == IB_QPT_RC) -- rxe_run_task(&qp->comp.task, 1); -+ rxe_sched_task(&qp->comp.task); - else - __rxe_do_task(&qp->comp.task); -- rxe_run_task(&qp->req.task, 1); -+ rxe_sched_task(&qp->req.task); - } - - /* called by the modify qp verb */ -diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c -index f637712079705..2ace1007a4195 100644 ---- a/drivers/infiniband/sw/rxe/rxe_req.c -+++ b/drivers/infiniband/sw/rxe/rxe_req.c -@@ -105,7 +105,7 @@ void rnr_nak_timer(struct timer_list *t) - /* request a send queue retry */ - qp->req.need_retry = 1; - qp->req.wait_for_rnr_timer = 0; -- rxe_run_task(&qp->req.task, 1); -+ rxe_sched_task(&qp->req.task); - } - - static struct rxe_send_wqe *req_next_wqe(struct rxe_qp *qp) -@@ -529,10 +529,11 @@ static void save_state(struct rxe_send_wqe *wqe, - struct rxe_send_wqe *rollback_wqe, - u32 *rollback_psn) - { -- rollback_wqe->state = wqe->state; -+ rollback_wqe->state = wqe->state; - rollback_wqe->first_psn = wqe->first_psn; -- rollback_wqe->last_psn = wqe->last_psn; -- *rollback_psn = qp->req.psn; -+ rollback_wqe->last_psn = wqe->last_psn; -+ rollback_wqe->dma = wqe->dma; -+ *rollback_psn = qp->req.psn; - } - - static void rollback_state(struct rxe_send_wqe *wqe, -@@ -540,10 +541,11 @@ static void rollback_state(struct rxe_send_wqe *wqe, - struct rxe_send_wqe *rollback_wqe, - u32 rollback_psn) - { -- wqe->state = rollback_wqe->state; -+ wqe->state = rollback_wqe->state; - wqe->first_psn = rollback_wqe->first_psn; -- wqe->last_psn = rollback_wqe->last_psn; -- qp->req.psn = rollback_psn; -+ wqe->last_psn = rollback_wqe->last_psn; -+ wqe->dma = rollback_wqe->dma; -+ qp->req.psn = rollback_psn; - } - - static void update_state(struct rxe_qp *qp, struct rxe_pkt_info *pkt) -@@ -608,7 +610,7 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe) - * which can lead to a deadlock. So go ahead and complete - * it now. - */ -- rxe_run_task(&qp->comp.task, 1); -+ rxe_sched_task(&qp->comp.task); - - return 0; - } -@@ -733,7 +735,7 @@ int rxe_requester(void *arg) - qp->req.wqe_index); - wqe->state = wqe_state_done; - wqe->status = IB_WC_SUCCESS; -- rxe_run_task(&qp->comp.task, 0); -+ rxe_run_task(&qp->comp.task); - goto done; - } - payload = mtu; -@@ -746,6 +748,9 @@ int rxe_requester(void *arg) - pkt.mask = rxe_opcode[opcode].mask; - pkt.wqe = wqe; - -+ /* save wqe state before we build and send packet */ -+ save_state(wqe, qp, &rollback_wqe, &rollback_psn); -+ - av = rxe_get_av(&pkt, &ah); - if (unlikely(!av)) { - pr_err("qp#%d Failed no address vector\n", qp_num(qp)); -@@ -778,29 +783,29 @@ int rxe_requester(void *arg) - if (ah) - rxe_put(ah); - -- /* -- * To prevent a race on wqe access between requester and completer, -- * wqe members state and psn need to be set before calling -- * rxe_xmit_packet(). -- * Otherwise, completer might initiate an unjustified retry flow. -- */ -- save_state(wqe, qp, &rollback_wqe, &rollback_psn); -+ /* update wqe state as though we had sent it */ - update_wqe_state(qp, wqe, &pkt); - update_wqe_psn(qp, wqe, &pkt, payload); - - err = rxe_xmit_packet(qp, &pkt, skb); - if (err) { -- qp->need_req_skb = 1; -+ if (err != -EAGAIN) { -+ wqe->status = IB_WC_LOC_QP_OP_ERR; -+ goto err; -+ } - -+ /* the packet was dropped so reset wqe to the state -+ * before we sent it so we can try to resend -+ */ - rollback_state(wqe, qp, &rollback_wqe, rollback_psn); - -- if (err == -EAGAIN) { -- rxe_run_task(&qp->req.task, 1); -- goto exit; -- } -+ /* force a delay until the dropped packet is freed and -+ * the send queue is drained below the low water mark -+ */ -+ qp->need_req_skb = 1; - -- wqe->status = IB_WC_LOC_QP_OP_ERR; -- goto err; -+ rxe_sched_task(&qp->req.task); -+ goto exit; - } - - update_state(qp, &pkt); -@@ -817,7 +822,7 @@ err: - qp->req.wqe_index = queue_next_index(qp->sq.queue, qp->req.wqe_index); - wqe->state = wqe_state_error; - qp->req.state = QP_STATE_ERROR; -- rxe_run_task(&qp->comp.task, 0); -+ rxe_run_task(&qp->comp.task); - exit: - ret = -EAGAIN; - out: -diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c -index 9f65c346d8432..a45202cecf2d7 100644 ---- a/drivers/infiniband/sw/rxe/rxe_resp.c -+++ b/drivers/infiniband/sw/rxe/rxe_resp.c -@@ -91,7 +91,10 @@ void rxe_resp_queue_pkt(struct rxe_qp *qp, struct sk_buff *skb) - must_sched = (pkt->opcode == IB_OPCODE_RC_RDMA_READ_REQUEST) || - (skb_queue_len(&qp->req_pkts) > 1); - -- rxe_run_task(&qp->resp.task, must_sched); -+ if (must_sched) -+ rxe_sched_task(&qp->resp.task); -+ else -+ rxe_run_task(&qp->resp.task); - } - - static inline enum resp_states get_req(struct rxe_qp *qp, -diff --git a/drivers/infiniband/sw/rxe/rxe_task.c b/drivers/infiniband/sw/rxe/rxe_task.c -index 182d0532a8ab9..446ee2c3d3813 100644 ---- a/drivers/infiniband/sw/rxe/rxe_task.c -+++ b/drivers/infiniband/sw/rxe/rxe_task.c -@@ -127,15 +127,20 @@ void rxe_cleanup_task(struct rxe_task *task) - tasklet_kill(&task->tasklet); - } - --void rxe_run_task(struct rxe_task *task, int sched) -+void rxe_run_task(struct rxe_task *task) - { - if (task->destroyed) - return; - -- if (sched) -- tasklet_schedule(&task->tasklet); -- else -- rxe_do_task(&task->tasklet); -+ rxe_do_task(&task->tasklet); -+} -+ -+void rxe_sched_task(struct rxe_task *task) -+{ -+ if (task->destroyed) -+ return; -+ -+ tasklet_schedule(&task->tasklet); - } - - void rxe_disable_task(struct rxe_task *task) -diff --git a/drivers/infiniband/sw/rxe/rxe_task.h b/drivers/infiniband/sw/rxe/rxe_task.h -index b3dfd970d1dc6..590b1c1d7e7ca 100644 ---- a/drivers/infiniband/sw/rxe/rxe_task.h -+++ b/drivers/infiniband/sw/rxe/rxe_task.h -@@ -52,10 +52,9 @@ int __rxe_do_task(struct rxe_task *task); - */ - void rxe_do_task(struct tasklet_struct *t); - --/* run a task, else schedule it to run as a tasklet, The decision -- * to run or schedule tasklet is based on the parameter sched. -- */ --void rxe_run_task(struct rxe_task *task, int sched); -+void rxe_run_task(struct rxe_task *task); -+ -+void rxe_sched_task(struct rxe_task *task); - - /* keep a task from scheduling */ - void rxe_disable_task(struct rxe_task *task); -diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c -index be13bcb4cc406..065717c11cba5 100644 ---- a/drivers/infiniband/sw/rxe/rxe_verbs.c -+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c -@@ -678,9 +678,9 @@ static int rxe_post_send_kernel(struct rxe_qp *qp, const struct ib_send_wr *wr, - wr = next; - } - -- rxe_run_task(&qp->req.task, 1); -+ rxe_sched_task(&qp->req.task); - if (unlikely(qp->req.state == QP_STATE_ERROR)) -- rxe_run_task(&qp->comp.task, 1); -+ rxe_sched_task(&qp->comp.task); - - return err; - } -@@ -702,7 +702,7 @@ static int rxe_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, - - if (qp->is_user) { - /* Utilize process context to do protocol processing */ -- rxe_run_task(&qp->req.task, 0); -+ rxe_run_task(&qp->req.task); - return 0; - } else - return rxe_post_send_kernel(qp, wr, bad_wr); -@@ -740,7 +740,7 @@ static int rxe_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr, - spin_unlock_irqrestore(&rq->producer_lock, flags); - - if (qp->resp.state == QP_STATE_ERROR) -- rxe_run_task(&qp->resp.task, 1); -+ rxe_sched_task(&qp->resp.task); - - return err; - } -diff --git a/drivers/infiniband/sw/siw/siw.h b/drivers/infiniband/sw/siw/siw.h -index 2f3a9cda3850f..8b4a710b82bc1 100644 ---- a/drivers/infiniband/sw/siw/siw.h -+++ b/drivers/infiniband/sw/siw/siw.h -@@ -74,6 +74,7 @@ struct siw_device { - - u32 vendor_part_id; - int numa_node; -+ char raw_gid[ETH_ALEN]; - - /* physical port state (only one port per device) */ - enum ib_port_state state; -diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c -index f88d2971c2c63..552d8271e423b 100644 ---- a/drivers/infiniband/sw/siw/siw_cm.c -+++ b/drivers/infiniband/sw/siw/siw_cm.c -@@ -1496,7 +1496,6 @@ error: - - cep->cm_id = NULL; - id->rem_ref(id); -- siw_cep_put(cep); - - qp->cep = NULL; - siw_cep_put(cep); -diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c -index 65b5cda5457ba..f45600d169ae7 100644 ---- a/drivers/infiniband/sw/siw/siw_main.c -+++ b/drivers/infiniband/sw/siw/siw_main.c -@@ -75,8 +75,7 @@ static int siw_device_register(struct siw_device *sdev, const char *name) - return rv; - } - -- siw_dbg(base_dev, "HWaddr=%pM\n", sdev->netdev->dev_addr); -- -+ siw_dbg(base_dev, "HWaddr=%pM\n", sdev->raw_gid); - return 0; - } - -@@ -313,24 +312,19 @@ static struct siw_device *siw_device_create(struct net_device *netdev) - return NULL; - - base_dev = &sdev->base_dev; -- - sdev->netdev = netdev; - -- if (netdev->type != ARPHRD_LOOPBACK && netdev->type != ARPHRD_NONE) { -- addrconf_addr_eui48((unsigned char *)&base_dev->node_guid, -- netdev->dev_addr); -+ if (netdev->addr_len) { -+ memcpy(sdev->raw_gid, netdev->dev_addr, -+ min_t(unsigned int, netdev->addr_len, ETH_ALEN)); - } else { - /* -- * This device does not have a HW address, -- * but connection mangagement lib expects gid != 0 -+ * This device does not have a HW address, but -+ * connection mangagement requires a unique gid. - */ -- size_t len = min_t(size_t, strlen(base_dev->name), 6); -- char addr[6] = { }; -- -- memcpy(addr, base_dev->name, len); -- addrconf_addr_eui48((unsigned char *)&base_dev->node_guid, -- addr); -+ eth_random_addr(sdev->raw_gid); - } -+ addrconf_addr_eui48((u8 *)&base_dev->node_guid, sdev->raw_gid); - - base_dev->uverbs_cmd_mask |= BIT_ULL(IB_USER_VERBS_CMD_POST_SEND); - -diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c -index 906fde1a2a0de..193f7d58d3845 100644 ---- a/drivers/infiniband/sw/siw/siw_verbs.c -+++ b/drivers/infiniband/sw/siw/siw_verbs.c -@@ -157,7 +157,7 @@ int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr, - attr->vendor_part_id = sdev->vendor_part_id; - - addrconf_addr_eui48((u8 *)&attr->sys_image_guid, -- sdev->netdev->dev_addr); -+ sdev->raw_gid); - - return 0; - } -@@ -218,7 +218,7 @@ int siw_query_gid(struct ib_device *base_dev, u32 port, int idx, - - /* subnet_prefix == interface_id == 0; */ - memset(gid, 0, sizeof(*gid)); -- memcpy(&gid->raw[0], sdev->netdev->dev_addr, 6); -+ memcpy(gid->raw, sdev->raw_gid, ETH_ALEN); - - return 0; - } -@@ -1494,7 +1494,7 @@ int siw_map_mr_sg(struct ib_mr *base_mr, struct scatterlist *sl, int num_sle, - - if (pbl->max_buf < num_sle) { - siw_dbg_mem(mem, "too many SGE's: %d > %d\n", -- mem->pbl->max_buf, num_sle); -+ num_sle, pbl->max_buf); - return -ENOMEM; - } - for_each_sg(sl, slp, num_sle, i) { -diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c -index a7fef3ea77fe3..a02a3caeaa4e7 100644 ---- a/drivers/infiniband/ulp/isert/ib_isert.c -+++ b/drivers/infiniband/ulp/isert/ib_isert.c -@@ -2571,6 +2571,8 @@ static void isert_wait_conn(struct iscsit_conn *conn) - isert_put_unsol_pending_cmds(conn); - isert_wait4cmds(conn); - isert_wait4logout(isert_conn); -+ -+ queue_work(isert_release_wq, &isert_conn->release_work); - } - - static void isert_free_conn(struct iscsit_conn *conn) -diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c -index b4d6a4a5ae81e..a7580c4855fec 100644 ---- a/drivers/infiniband/ulp/srp/ib_srp.c -+++ b/drivers/infiniband/ulp/srp/ib_srp.c -@@ -1984,12 +1984,8 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp) - - if (unlikely(rsp->flags & SRP_RSP_FLAG_DIUNDER)) - scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); -- else if (unlikely(rsp->flags & SRP_RSP_FLAG_DIOVER)) -- scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_in_res_cnt)); - else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOUNDER)) - scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt)); -- else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOOVER)) -- scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_out_res_cnt)); - - srp_free_req(ch, req, scmnd, - be32_to_cpu(rsp->req_lim_delta)); -diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h -index 028e45bd050bf..1724d6cb8649d 100644 ---- a/drivers/input/serio/i8042-acpipnpio.h -+++ b/drivers/input/serio/i8042-acpipnpio.h -@@ -1281,6 +1281,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { - .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | - SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) - }, -+ /* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */ -+ { -+ .matches = { -+ DMI_MATCH(DMI_BOARD_NAME, "PD5x_7xPNP_PNR_PNN_PNT"), -+ }, -+ .driver_data = (void *)(SERIO_QUIRK_NOAUX) -+ }, - { - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "X170SM"), -diff --git a/drivers/interconnect/qcom/bcm-voter.c b/drivers/interconnect/qcom/bcm-voter.c -index d5f2a6b5376bd..a2d437a05a11f 100644 ---- a/drivers/interconnect/qcom/bcm-voter.c -+++ b/drivers/interconnect/qcom/bcm-voter.c -@@ -58,6 +58,36 @@ static u64 bcm_div(u64 num, u32 base) - return num; - } - -+/* BCMs with enable_mask use one-hot-encoding for on/off signaling */ -+static void bcm_aggregate_mask(struct qcom_icc_bcm *bcm) -+{ -+ struct qcom_icc_node *node; -+ int bucket, i; -+ -+ for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS; bucket++) { -+ bcm->vote_x[bucket] = 0; -+ bcm->vote_y[bucket] = 0; -+ -+ for (i = 0; i < bcm->num_nodes; i++) { -+ node = bcm->nodes[i]; -+ -+ /* If any vote in this bucket exists, keep the BCM enabled */ -+ if (node->sum_avg[bucket] || node->max_peak[bucket]) { -+ bcm->vote_x[bucket] = 0; -+ bcm->vote_y[bucket] = bcm->enable_mask; -+ break; -+ } -+ } -+ } -+ -+ if (bcm->keepalive) { -+ bcm->vote_x[QCOM_ICC_BUCKET_AMC] = bcm->enable_mask; -+ bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = bcm->enable_mask; -+ bcm->vote_y[QCOM_ICC_BUCKET_AMC] = bcm->enable_mask; -+ bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = bcm->enable_mask; -+ } -+} -+ - static void bcm_aggregate(struct qcom_icc_bcm *bcm) - { - struct qcom_icc_node *node; -@@ -83,11 +113,6 @@ static void bcm_aggregate(struct qcom_icc_bcm *bcm) - - temp = agg_peak[bucket] * bcm->vote_scale; - bcm->vote_y[bucket] = bcm_div(temp, bcm->aux_data.unit); -- -- if (bcm->enable_mask && (bcm->vote_x[bucket] || bcm->vote_y[bucket])) { -- bcm->vote_x[bucket] = 0; -- bcm->vote_y[bucket] = bcm->enable_mask; -- } - } - - if (bcm->keepalive && bcm->vote_x[QCOM_ICC_BUCKET_AMC] == 0 && -@@ -260,8 +285,12 @@ int qcom_icc_bcm_voter_commit(struct bcm_voter *voter) - return 0; - - mutex_lock(&voter->lock); -- list_for_each_entry(bcm, &voter->commit_list, list) -- bcm_aggregate(bcm); -+ list_for_each_entry(bcm, &voter->commit_list, list) { -+ if (bcm->enable_mask) -+ bcm_aggregate_mask(bcm); -+ else -+ bcm_aggregate(bcm); -+ } - - /* - * Pre sort the BCMs based on VCD for ease of generating a command list -diff --git a/drivers/interconnect/qcom/qcm2290.c b/drivers/interconnect/qcom/qcm2290.c -index a29cdb4fac03f..82a2698ad66b1 100644 ---- a/drivers/interconnect/qcom/qcm2290.c -+++ b/drivers/interconnect/qcom/qcm2290.c -@@ -1355,6 +1355,7 @@ static struct platform_driver qcm2290_noc_driver = { - .driver = { - .name = "qnoc-qcm2290", - .of_match_table = qcm2290_noc_of_match, -+ .sync_state = icc_sync_state, - }, - }; - module_platform_driver(qcm2290_noc_driver); -diff --git a/drivers/interconnect/qcom/sm8450.c b/drivers/interconnect/qcom/sm8450.c -index e64c214b40209..d6e582a02e628 100644 ---- a/drivers/interconnect/qcom/sm8450.c -+++ b/drivers/interconnect/qcom/sm8450.c -@@ -1886,6 +1886,7 @@ static struct platform_driver qnoc_driver = { - .driver = { - .name = "qnoc-sm8450", - .of_match_table = qnoc_of_match, -+ .sync_state = icc_sync_state, - }, - }; - -diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c -index 75355ddca6575..4caa023048a08 100644 ---- a/drivers/iommu/amd/iommu_v2.c -+++ b/drivers/iommu/amd/iommu_v2.c -@@ -262,8 +262,8 @@ static void put_pasid_state(struct pasid_state *pasid_state) - - static void put_pasid_state_wait(struct pasid_state *pasid_state) - { -- refcount_dec(&pasid_state->count); -- wait_event(pasid_state->wq, !refcount_read(&pasid_state->count)); -+ if (!refcount_dec_and_test(&pasid_state->count)) -+ wait_event(pasid_state->wq, !refcount_read(&pasid_state->count)); - free_pasid_state(pasid_state); - } - -diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c -index 3869c3ecda8cd..5b9cb9fcc352b 100644 ---- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c -+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c -@@ -273,6 +273,13 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, - ctx->secure_init = true; - } - -+ /* Disable context bank before programming */ -+ iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0); -+ -+ /* Clear context bank fault address fault status registers */ -+ iommu_writel(ctx, ARM_SMMU_CB_FAR, 0); -+ iommu_writel(ctx, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT); -+ - /* TTBRs */ - iommu_writeq(ctx, ARM_SMMU_CB_TTBR0, - pgtbl_cfg.arm_lpae_s1_cfg.ttbr | -diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c -index a39aab66a01b1..3f03039e5cce5 100644 ---- a/drivers/iommu/intel/pasid.c -+++ b/drivers/iommu/intel/pasid.c -@@ -127,7 +127,7 @@ int intel_pasid_alloc_table(struct device *dev) - info->pasid_table = pasid_table; - - if (!ecap_coherent(info->iommu->ecap)) -- clflush_cache_range(pasid_table->table, size); -+ clflush_cache_range(pasid_table->table, (1 << order) * PAGE_SIZE); - - return 0; - } -diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c -index 2ae5a6058a34a..9673cd60c84fc 100644 ---- a/drivers/iommu/mtk_iommu.c -+++ b/drivers/iommu/mtk_iommu.c -@@ -223,10 +223,9 @@ struct mtk_iommu_data { - struct device *smicomm_dev; - - struct mtk_iommu_bank_data *bank; -+ struct mtk_iommu_domain *share_dom; /* For 2 HWs share pgtable */ - -- struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */ - struct regmap *pericfg; -- - struct mutex mutex; /* Protect m4u_group/m4u_dom above */ - - /* -@@ -577,15 +576,14 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, - struct mtk_iommu_data *data, - unsigned int region_id) - { -+ struct mtk_iommu_domain *share_dom = data->share_dom; - const struct mtk_iommu_iova_region *region; -- struct mtk_iommu_domain *m4u_dom; -- -- /* Always use bank0 in sharing pgtable case */ -- m4u_dom = data->bank[0].m4u_dom; -- if (m4u_dom) { -- dom->iop = m4u_dom->iop; -- dom->cfg = m4u_dom->cfg; -- dom->domain.pgsize_bitmap = m4u_dom->cfg.pgsize_bitmap; -+ -+ /* Always use share domain in sharing pgtable case */ -+ if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE) && share_dom) { -+ dom->iop = share_dom->iop; -+ dom->cfg = share_dom->cfg; -+ dom->domain.pgsize_bitmap = share_dom->cfg.pgsize_bitmap; - goto update_iova_region; - } - -@@ -615,6 +613,9 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, - /* Update our support page sizes bitmap */ - dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap; - -+ if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) -+ data->share_dom = dom; -+ - update_iova_region: - /* Update the iova region for this domain */ - region = data->plat_data->iova_region + region_id; -@@ -665,7 +666,9 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, - /* Data is in the frstdata in sharing pgtable case. */ - frstdata = mtk_iommu_get_frst_data(hw_list); - -+ mutex_lock(&frstdata->mutex); - ret = mtk_iommu_domain_finalise(dom, frstdata, region_id); -+ mutex_unlock(&frstdata->mutex); - if (ret) { - mutex_unlock(&dom->mutex); - return -ENODEV; -diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c -index f7e9b56be174f..43bb577a26e59 100644 ---- a/drivers/iommu/rockchip-iommu.c -+++ b/drivers/iommu/rockchip-iommu.c -@@ -98,8 +98,6 @@ struct rk_iommu_ops { - phys_addr_t (*pt_address)(u32 dte); - u32 (*mk_dtentries)(dma_addr_t pt_dma); - u32 (*mk_ptentries)(phys_addr_t page, int prot); -- phys_addr_t (*dte_addr_phys)(u32 addr); -- u32 (*dma_addr_dte)(dma_addr_t dt_dma); - u64 dma_bit_mask; - }; - -@@ -277,8 +275,8 @@ static u32 rk_mk_pte(phys_addr_t page, int prot) - /* - * In v2: - * 31:12 - Page address bit 31:0 -- * 11:9 - Page address bit 34:32 -- * 8:4 - Page address bit 39:35 -+ * 11: 8 - Page address bit 35:32 -+ * 7: 4 - Page address bit 39:36 - * 3 - Security - * 2 - Writable - * 1 - Readable -@@ -505,7 +503,7 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu) - - /* - * Check if register DTE_ADDR is working by writing DTE_ADDR_DUMMY -- * and verifying that upper 5 nybbles are read back. -+ * and verifying that upper 5 (v1) or 7 (v2) nybbles are read back. - */ - for (i = 0; i < iommu->num_mmu; i++) { - dte_addr = rk_ops->pt_address(DTE_ADDR_DUMMY); -@@ -530,33 +528,6 @@ static int rk_iommu_force_reset(struct rk_iommu *iommu) - return 0; - } - --static inline phys_addr_t rk_dte_addr_phys(u32 addr) --{ -- return (phys_addr_t)addr; --} -- --static inline u32 rk_dma_addr_dte(dma_addr_t dt_dma) --{ -- return dt_dma; --} -- --#define DT_HI_MASK GENMASK_ULL(39, 32) --#define DTE_BASE_HI_MASK GENMASK(11, 4) --#define DT_SHIFT 28 -- --static inline phys_addr_t rk_dte_addr_phys_v2(u32 addr) --{ -- u64 addr64 = addr; -- return (phys_addr_t)(addr64 & RK_DTE_PT_ADDRESS_MASK) | -- ((addr64 & DTE_BASE_HI_MASK) << DT_SHIFT); --} -- --static inline u32 rk_dma_addr_dte_v2(dma_addr_t dt_dma) --{ -- return (dt_dma & RK_DTE_PT_ADDRESS_MASK) | -- ((dt_dma & DT_HI_MASK) >> DT_SHIFT); --} -- - static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova) - { - void __iomem *base = iommu->bases[index]; -@@ -576,7 +547,7 @@ static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova) - page_offset = rk_iova_page_offset(iova); - - mmu_dte_addr = rk_iommu_read(base, RK_MMU_DTE_ADDR); -- mmu_dte_addr_phys = rk_ops->dte_addr_phys(mmu_dte_addr); -+ mmu_dte_addr_phys = rk_ops->pt_address(mmu_dte_addr); - - dte_addr_phys = mmu_dte_addr_phys + (4 * dte_index); - dte_addr = phys_to_virt(dte_addr_phys); -@@ -966,7 +937,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu) - - for (i = 0; i < iommu->num_mmu; i++) { - rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, -- rk_ops->dma_addr_dte(rk_domain->dt_dma)); -+ rk_ops->mk_dtentries(rk_domain->dt_dma)); - rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE); - rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK); - } -@@ -1373,8 +1344,6 @@ static struct rk_iommu_ops iommu_data_ops_v1 = { - .pt_address = &rk_dte_pt_address, - .mk_dtentries = &rk_mk_dte, - .mk_ptentries = &rk_mk_pte, -- .dte_addr_phys = &rk_dte_addr_phys, -- .dma_addr_dte = &rk_dma_addr_dte, - .dma_bit_mask = DMA_BIT_MASK(32), - }; - -@@ -1382,8 +1351,6 @@ static struct rk_iommu_ops iommu_data_ops_v2 = { - .pt_address = &rk_dte_pt_address_v2, - .mk_dtentries = &rk_mk_dte_v2, - .mk_ptentries = &rk_mk_pte_v2, -- .dte_addr_phys = &rk_dte_addr_phys_v2, -- .dma_addr_dte = &rk_dma_addr_dte_v2, - .dma_bit_mask = DMA_BIT_MASK(40), - }; - -diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c -index fadd2c907222b..8261066de07d7 100644 ---- a/drivers/iommu/sprd-iommu.c -+++ b/drivers/iommu/sprd-iommu.c -@@ -147,6 +147,7 @@ static struct iommu_domain *sprd_iommu_domain_alloc(unsigned int domain_type) - - dom->domain.geometry.aperture_start = 0; - dom->domain.geometry.aperture_end = SZ_256M - 1; -+ dom->domain.geometry.force_aperture = true; - - return &dom->domain; - } -diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c -index ac04aeaa2d308..3d99b8bdd8ef1 100644 ---- a/drivers/irqchip/irq-loongson-eiointc.c -+++ b/drivers/irqchip/irq-loongson-eiointc.c -@@ -145,7 +145,7 @@ static int eiointc_router_init(unsigned int cpu) - int i, bit; - uint32_t data; - uint32_t node = cpu_to_eio_node(cpu); -- uint32_t index = eiointc_index(node); -+ int index = eiointc_index(node); - - if (index < 0) { - pr_err("Error: invalid nodemap!\n"); -diff --git a/drivers/leds/led-class-multicolor.c b/drivers/leds/led-class-multicolor.c -index e317408583df9..ec62a48116135 100644 ---- a/drivers/leds/led-class-multicolor.c -+++ b/drivers/leds/led-class-multicolor.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -19,9 +20,10 @@ int led_mc_calc_color_components(struct led_classdev_mc *mcled_cdev, - int i; - - for (i = 0; i < mcled_cdev->num_colors; i++) -- mcled_cdev->subled_info[i].brightness = brightness * -- mcled_cdev->subled_info[i].intensity / -- led_cdev->max_brightness; -+ mcled_cdev->subled_info[i].brightness = -+ DIV_ROUND_CLOSEST(brightness * -+ mcled_cdev->subled_info[i].intensity, -+ led_cdev->max_brightness); - - return 0; - } -diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c -index 4a97cb7457888..aad8bc44459fe 100644 ---- a/drivers/leds/led-core.c -+++ b/drivers/leds/led-core.c -@@ -419,15 +419,15 @@ int led_compose_name(struct device *dev, struct led_init_data *init_data, - struct fwnode_handle *fwnode = init_data->fwnode; - const char *devicename = init_data->devicename; - -- /* We want to label LEDs that can produce full range of colors -- * as RGB, not multicolor */ -- BUG_ON(props.color == LED_COLOR_ID_MULTI); -- - if (!led_classdev_name) - return -EINVAL; - - led_parse_fwnode_props(dev, fwnode, &props); - -+ /* We want to label LEDs that can produce full range of colors -+ * as RGB, not multicolor */ -+ BUG_ON(props.color == LED_COLOR_ID_MULTI); -+ - if (props.label) { - /* - * If init_data.devicename is NULL, then it indicates that -diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c -index 6832180c1c54f..cc892ecd52408 100644 ---- a/drivers/leds/leds-pwm.c -+++ b/drivers/leds/leds-pwm.c -@@ -146,7 +146,7 @@ static int led_pwm_create_fwnode(struct device *dev, struct led_pwm_priv *priv) - led.name = to_of_node(fwnode)->name; - - if (!led.name) { -- ret = EINVAL; -+ ret = -EINVAL; - goto err_child_out; - } - -diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c -index f62db7e520b52..8ae0d2d284aff 100644 ---- a/drivers/leds/trigger/ledtrig-tty.c -+++ b/drivers/leds/trigger/ledtrig-tty.c -@@ -7,6 +7,8 @@ - #include - #include - -+#define LEDTRIG_TTY_INTERVAL 50 -+ - struct ledtrig_tty_data { - struct led_classdev *led_cdev; - struct delayed_work dwork; -@@ -122,17 +124,19 @@ static void ledtrig_tty_work(struct work_struct *work) - - if (icount.rx != trigger_data->rx || - icount.tx != trigger_data->tx) { -- led_set_brightness_sync(trigger_data->led_cdev, LED_ON); -+ unsigned long interval = LEDTRIG_TTY_INTERVAL; -+ -+ led_blink_set_oneshot(trigger_data->led_cdev, &interval, -+ &interval, 0); - - trigger_data->rx = icount.rx; - trigger_data->tx = icount.tx; -- } else { -- led_set_brightness_sync(trigger_data->led_cdev, LED_OFF); - } - - out: - mutex_unlock(&trigger_data->mutex); -- schedule_delayed_work(&trigger_data->dwork, msecs_to_jiffies(100)); -+ schedule_delayed_work(&trigger_data->dwork, -+ msecs_to_jiffies(LEDTRIG_TTY_INTERVAL * 2)); - } - - static struct attribute *ledtrig_tty_attrs[] = { -diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c -index 8bbeeec70905c..5200bba63708e 100644 ---- a/drivers/md/md-bitmap.c -+++ b/drivers/md/md-bitmap.c -@@ -2481,6 +2481,10 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len) - if (backlog > COUNTER_MAX) - return -EINVAL; - -+ rv = mddev_lock(mddev); -+ if (rv) -+ return rv; -+ - /* - * Without write mostly device, it doesn't make sense to set - * backlog for max_write_behind. -@@ -2494,6 +2498,7 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len) - if (!has_write_mostly) { - pr_warn_ratelimited("%s: can't set backlog, no write mostly device available\n", - mdname(mddev)); -+ mddev_unlock(mddev); - return -EINVAL; - } - -@@ -2504,13 +2509,13 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len) - mddev_destroy_serial_pool(mddev, NULL, false); - } else if (backlog && !mddev->serial_info_pool) { - /* serial_info_pool is needed since backlog is not zero */ -- struct md_rdev *rdev; -- - rdev_for_each(rdev, mddev) - mddev_create_serial_pool(mddev, rdev, false); - } - if (old_mwb != backlog) - md_bitmap_update_sb(mddev->bitmap); -+ -+ mddev_unlock(mddev); - return len; - } - -diff --git a/drivers/md/md-linear.c b/drivers/md/md-linear.c -index 6e7797b4e7381..4eb72b9dd9336 100644 ---- a/drivers/md/md-linear.c -+++ b/drivers/md/md-linear.c -@@ -223,7 +223,8 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio) - bio_sector < start_sector)) - goto out_of_bounds; - -- if (unlikely(is_mddev_broken(tmp_dev->rdev, "linear"))) { -+ if (unlikely(is_rdev_broken(tmp_dev->rdev))) { -+ md_error(mddev, tmp_dev->rdev); - bio_io_error(bio); - return true; - } -@@ -270,6 +271,16 @@ static void linear_status (struct seq_file *seq, struct mddev *mddev) - seq_printf(seq, " %dk rounding", mddev->chunk_sectors / 2); - } - -+static void linear_error(struct mddev *mddev, struct md_rdev *rdev) -+{ -+ if (!test_and_set_bit(MD_BROKEN, &mddev->flags)) { -+ char *md_name = mdname(mddev); -+ -+ pr_crit("md/linear%s: Disk failure on %pg detected, failing array.\n", -+ md_name, rdev->bdev); -+ } -+} -+ - static void linear_quiesce(struct mddev *mddev, int state) - { - } -@@ -286,6 +297,7 @@ static struct md_personality linear_personality = - .hot_add_disk = linear_add, - .size = linear_size, - .quiesce = linear_quiesce, -+ .error_handler = linear_error, - }; - - static int __init linear_init (void) -diff --git a/drivers/md/md.c b/drivers/md/md.c -index 45daba0eb9310..86b2acfba1a7f 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -368,6 +368,10 @@ EXPORT_SYMBOL_GPL(md_new_event); - static LIST_HEAD(all_mddevs); - static DEFINE_SPINLOCK(all_mddevs_lock); - -+static bool is_md_suspended(struct mddev *mddev) -+{ -+ return percpu_ref_is_dying(&mddev->active_io); -+} - /* Rather than calling directly into the personality make_request function, - * IO requests come here first so that we can check if the device is - * being suspended pending a reconfiguration. -@@ -377,7 +381,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock); - */ - static bool is_suspended(struct mddev *mddev, struct bio *bio) - { -- if (mddev->suspended) -+ if (is_md_suspended(mddev)) - return true; - if (bio_data_dir(bio) != WRITE) - return false; -@@ -393,12 +397,10 @@ static bool is_suspended(struct mddev *mddev, struct bio *bio) - void md_handle_request(struct mddev *mddev, struct bio *bio) - { - check_suspended: -- rcu_read_lock(); - if (is_suspended(mddev, bio)) { - DEFINE_WAIT(__wait); - /* Bail out if REQ_NOWAIT is set for the bio */ - if (bio->bi_opf & REQ_NOWAIT) { -- rcu_read_unlock(); - bio_wouldblock_error(bio); - return; - } -@@ -407,23 +409,19 @@ check_suspended: - TASK_UNINTERRUPTIBLE); - if (!is_suspended(mddev, bio)) - break; -- rcu_read_unlock(); - schedule(); -- rcu_read_lock(); - } - finish_wait(&mddev->sb_wait, &__wait); - } -- atomic_inc(&mddev->active_io); -- rcu_read_unlock(); -+ if (!percpu_ref_tryget_live(&mddev->active_io)) -+ goto check_suspended; - - if (!mddev->pers->make_request(mddev, bio)) { -- atomic_dec(&mddev->active_io); -- wake_up(&mddev->sb_wait); -+ percpu_ref_put(&mddev->active_io); - goto check_suspended; - } - -- if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) -- wake_up(&mddev->sb_wait); -+ percpu_ref_put(&mddev->active_io); - } - EXPORT_SYMBOL(md_handle_request); - -@@ -471,11 +469,10 @@ void mddev_suspend(struct mddev *mddev) - lockdep_assert_held(&mddev->reconfig_mutex); - if (mddev->suspended++) - return; -- synchronize_rcu(); - wake_up(&mddev->sb_wait); - set_bit(MD_ALLOW_SB_UPDATE, &mddev->flags); -- smp_mb__after_atomic(); -- wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); -+ percpu_ref_kill(&mddev->active_io); -+ wait_event(mddev->sb_wait, percpu_ref_is_zero(&mddev->active_io)); - mddev->pers->quiesce(mddev, 1); - clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags); - wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags)); -@@ -488,11 +485,14 @@ EXPORT_SYMBOL_GPL(mddev_suspend); - - void mddev_resume(struct mddev *mddev) - { -- /* entred the memalloc scope from mddev_suspend() */ -- memalloc_noio_restore(mddev->noio_flag); - lockdep_assert_held(&mddev->reconfig_mutex); - if (--mddev->suspended) - return; -+ -+ /* entred the memalloc scope from mddev_suspend() */ -+ memalloc_noio_restore(mddev->noio_flag); -+ -+ percpu_ref_resurrect(&mddev->active_io); - wake_up(&mddev->sb_wait); - mddev->pers->quiesce(mddev, 0); - -@@ -671,7 +671,6 @@ void mddev_init(struct mddev *mddev) - timer_setup(&mddev->safemode_timer, md_safemode_timeout, 0); - atomic_set(&mddev->active, 1); - atomic_set(&mddev->openers, 0); -- atomic_set(&mddev->active_io, 0); - spin_lock_init(&mddev->lock); - atomic_set(&mddev->flush_pending, 0); - init_waitqueue_head(&mddev->sb_wait); -@@ -5779,6 +5778,12 @@ static void md_safemode_timeout(struct timer_list *t) - } - - static int start_dirty_degraded; -+static void active_io_release(struct percpu_ref *ref) -+{ -+ struct mddev *mddev = container_of(ref, struct mddev, active_io); -+ -+ wake_up(&mddev->sb_wait); -+} - - int md_run(struct mddev *mddev) - { -@@ -5859,10 +5864,15 @@ int md_run(struct mddev *mddev) - nowait = nowait && bdev_nowait(rdev->bdev); - } - -+ err = percpu_ref_init(&mddev->active_io, active_io_release, -+ PERCPU_REF_ALLOW_REINIT, GFP_KERNEL); -+ if (err) -+ return err; -+ - if (!bioset_initialized(&mddev->bio_set)) { - err = bioset_init(&mddev->bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); - if (err) -- return err; -+ goto exit_active_io; - } - if (!bioset_initialized(&mddev->sync_set)) { - err = bioset_init(&mddev->sync_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); -@@ -6050,6 +6060,8 @@ abort: - bioset_exit(&mddev->sync_set); - exit_bio_set: - bioset_exit(&mddev->bio_set); -+exit_active_io: -+ percpu_ref_exit(&mddev->active_io); - return err; - } - EXPORT_SYMBOL_GPL(md_run); -@@ -6238,7 +6250,7 @@ EXPORT_SYMBOL_GPL(md_stop_writes); - static void mddev_detach(struct mddev *mddev) - { - md_bitmap_wait_behind_writes(mddev); -- if (mddev->pers && mddev->pers->quiesce && !mddev->suspended) { -+ if (mddev->pers && mddev->pers->quiesce && !is_md_suspended(mddev)) { - mddev->pers->quiesce(mddev, 1); - mddev->pers->quiesce(mddev, 0); - } -@@ -6265,6 +6277,10 @@ static void __md_stop(struct mddev *mddev) - mddev->to_remove = &md_redundancy_group; - module_put(pers->owner); - clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); -+ -+ percpu_ref_exit(&mddev->active_io); -+ bioset_exit(&mddev->bio_set); -+ bioset_exit(&mddev->sync_set); - } - - void md_stop(struct mddev *mddev) -@@ -6276,8 +6292,7 @@ void md_stop(struct mddev *mddev) - */ - __md_stop_writes(mddev); - __md_stop(mddev); -- bioset_exit(&mddev->bio_set); -- bioset_exit(&mddev->sync_set); -+ percpu_ref_exit(&mddev->writes_pending); - } - - EXPORT_SYMBOL_GPL(md_stop); -@@ -7845,9 +7860,6 @@ static void md_free_disk(struct gendisk *disk) - struct mddev *mddev = disk->private_data; - - percpu_ref_exit(&mddev->writes_pending); -- bioset_exit(&mddev->bio_set); -- bioset_exit(&mddev->sync_set); -- - mddev_free(mddev); - } - -@@ -7978,6 +7990,9 @@ void md_error(struct mddev *mddev, struct md_rdev *rdev) - return; - mddev->pers->error_handler(mddev, rdev); - -+ if (mddev->pers->level == 0 || mddev->pers->level == LEVEL_LINEAR) -+ return; -+ - if (mddev->degraded && !test_bit(MD_BROKEN, &mddev->flags)) - set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); - sysfs_notify_dirent_safe(rdev->sysfs_state); -@@ -8548,7 +8563,7 @@ bool md_write_start(struct mddev *mddev, struct bio *bi) - return true; - wait_event(mddev->sb_wait, - !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) || -- mddev->suspended); -+ is_md_suspended(mddev)); - if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) { - percpu_ref_put(&mddev->writes_pending); - return false; -@@ -9276,7 +9291,7 @@ void md_check_recovery(struct mddev *mddev) - wake_up(&mddev->sb_wait); - } - -- if (mddev->suspended) -+ if (is_md_suspended(mddev)) - return; - - if (mddev->bitmap) -diff --git a/drivers/md/md.h b/drivers/md/md.h -index b4e2d8b87b611..4f0b480974552 100644 ---- a/drivers/md/md.h -+++ b/drivers/md/md.h -@@ -315,7 +315,7 @@ struct mddev { - unsigned long sb_flags; - - int suspended; -- atomic_t active_io; -+ struct percpu_ref active_io; - int ro; - int sysfs_active; /* set when sysfs deletes - * are happening, so run/ -@@ -790,15 +790,9 @@ extern void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev, - struct md_rdev *md_find_rdev_nr_rcu(struct mddev *mddev, int nr); - struct md_rdev *md_find_rdev_rcu(struct mddev *mddev, dev_t dev); - --static inline bool is_mddev_broken(struct md_rdev *rdev, const char *md_type) -+static inline bool is_rdev_broken(struct md_rdev *rdev) - { -- if (!disk_live(rdev->bdev->bd_disk)) { -- if (!test_and_set_bit(MD_BROKEN, &rdev->mddev->flags)) -- pr_warn("md: %s: %s array has a missing/failed member\n", -- mdname(rdev->mddev), md_type); -- return true; -- } -- return false; -+ return !disk_live(rdev->bdev->bd_disk); - } - - static inline void rdev_dec_pending(struct md_rdev *rdev, struct mddev *mddev) -diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c -index 0f7c3b3c62b25..7c6a0b4437d8f 100644 ---- a/drivers/md/raid0.c -+++ b/drivers/md/raid0.c -@@ -557,14 +557,50 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) - bio_endio(bio); - } - --static bool raid0_make_request(struct mddev *mddev, struct bio *bio) -+static void raid0_map_submit_bio(struct mddev *mddev, struct bio *bio) - { - struct r0conf *conf = mddev->private; - struct strip_zone *zone; - struct md_rdev *tmp_dev; -- sector_t bio_sector; -+ sector_t bio_sector = bio->bi_iter.bi_sector; -+ sector_t sector = bio_sector; -+ -+ md_account_bio(mddev, &bio); -+ -+ zone = find_zone(mddev->private, §or); -+ switch (conf->layout) { -+ case RAID0_ORIG_LAYOUT: -+ tmp_dev = map_sector(mddev, zone, bio_sector, §or); -+ break; -+ case RAID0_ALT_MULTIZONE_LAYOUT: -+ tmp_dev = map_sector(mddev, zone, sector, §or); -+ break; -+ default: -+ WARN(1, "md/raid0:%s: Invalid layout\n", mdname(mddev)); -+ bio_io_error(bio); -+ return; -+ } -+ -+ if (unlikely(is_rdev_broken(tmp_dev))) { -+ bio_io_error(bio); -+ md_error(mddev, tmp_dev); -+ return; -+ } -+ -+ bio_set_dev(bio, tmp_dev->bdev); -+ bio->bi_iter.bi_sector = sector + zone->dev_start + -+ tmp_dev->data_offset; -+ -+ if (mddev->gendisk) -+ trace_block_bio_remap(bio, disk_devt(mddev->gendisk), -+ bio_sector); -+ mddev_check_write_zeroes(mddev, bio); -+ submit_bio_noacct(bio); -+} -+ -+static bool raid0_make_request(struct mddev *mddev, struct bio *bio) -+{ - sector_t sector; -- sector_t orig_sector; - unsigned chunk_sects; - unsigned sectors; - -@@ -577,8 +613,7 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio) - return true; - } - -- bio_sector = bio->bi_iter.bi_sector; -- sector = bio_sector; -+ sector = bio->bi_iter.bi_sector; - chunk_sects = mddev->chunk_sectors; - - sectors = chunk_sects - -@@ -586,49 +621,15 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio) - ? (sector & (chunk_sects-1)) - : sector_div(sector, chunk_sects)); - -- /* Restore due to sector_div */ -- sector = bio_sector; -- - if (sectors < bio_sectors(bio)) { - struct bio *split = bio_split(bio, sectors, GFP_NOIO, - &mddev->bio_set); - bio_chain(split, bio); -- submit_bio_noacct(bio); -+ raid0_map_submit_bio(mddev, bio); - bio = split; - } - -- if (bio->bi_pool != &mddev->bio_set) -- md_account_bio(mddev, &bio); -- -- orig_sector = sector; -- zone = find_zone(mddev->private, §or); -- switch (conf->layout) { -- case RAID0_ORIG_LAYOUT: -- tmp_dev = map_sector(mddev, zone, orig_sector, §or); -- break; -- case RAID0_ALT_MULTIZONE_LAYOUT: -- tmp_dev = map_sector(mddev, zone, sector, §or); -- break; -- default: -- WARN(1, "md/raid0:%s: Invalid layout\n", mdname(mddev)); -- bio_io_error(bio); -- return true; -- } -- -- if (unlikely(is_mddev_broken(tmp_dev, "raid0"))) { -- bio_io_error(bio); -- return true; -- } -- -- bio_set_dev(bio, tmp_dev->bdev); -- bio->bi_iter.bi_sector = sector + zone->dev_start + -- tmp_dev->data_offset; -- -- if (mddev->gendisk) -- trace_block_bio_remap(bio, disk_devt(mddev->gendisk), -- bio_sector); -- mddev_check_write_zeroes(mddev, bio); -- submit_bio_noacct(bio); -+ raid0_map_submit_bio(mddev, bio); - return true; - } - -@@ -638,6 +639,16 @@ static void raid0_status(struct seq_file *seq, struct mddev *mddev) - return; - } - -+static void raid0_error(struct mddev *mddev, struct md_rdev *rdev) -+{ -+ if (!test_and_set_bit(MD_BROKEN, &mddev->flags)) { -+ char *md_name = mdname(mddev); -+ -+ pr_crit("md/raid0%s: Disk failure on %pg detected, failing array.\n", -+ md_name, rdev->bdev); -+ } -+} -+ - static void *raid0_takeover_raid45(struct mddev *mddev) - { - struct md_rdev *rdev; -@@ -813,6 +824,7 @@ static struct md_personality raid0_personality= - .size = raid0_size, - .takeover = raid0_takeover, - .quiesce = raid0_quiesce, -+ .error_handler = raid0_error, - }; - - static int __init raid0_init (void) -diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c -index d2098fcd6a270..7b318e7e8d459 100644 ---- a/drivers/md/raid10.c -+++ b/drivers/md/raid10.c -@@ -1317,6 +1317,25 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio, - } - } - -+static struct md_rdev *dereference_rdev_and_rrdev(struct raid10_info *mirror, -+ struct md_rdev **prrdev) -+{ -+ struct md_rdev *rdev, *rrdev; -+ -+ rrdev = rcu_dereference(mirror->replacement); -+ /* -+ * Read replacement first to prevent reading both rdev and -+ * replacement as NULL during replacement replace rdev. -+ */ -+ smp_mb(); -+ rdev = rcu_dereference(mirror->rdev); -+ if (rdev == rrdev) -+ rrdev = NULL; -+ -+ *prrdev = rrdev; -+ return rdev; -+} -+ - static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio) - { - int i; -@@ -1327,11 +1346,9 @@ retry_wait: - blocked_rdev = NULL; - rcu_read_lock(); - for (i = 0; i < conf->copies; i++) { -- struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev); -- struct md_rdev *rrdev = rcu_dereference( -- conf->mirrors[i].replacement); -- if (rdev == rrdev) -- rrdev = NULL; -+ struct md_rdev *rdev, *rrdev; -+ -+ rdev = dereference_rdev_and_rrdev(&conf->mirrors[i], &rrdev); - if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { - atomic_inc(&rdev->nr_pending); - blocked_rdev = rdev; -@@ -1460,15 +1477,7 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio, - int d = r10_bio->devs[i].devnum; - struct md_rdev *rdev, *rrdev; - -- rrdev = rcu_dereference(conf->mirrors[d].replacement); -- /* -- * Read replacement first to prevent reading both rdev and -- * replacement as NULL during replacement replace rdev. -- */ -- smp_mb(); -- rdev = rcu_dereference(conf->mirrors[d].rdev); -- if (rdev == rrdev) -- rrdev = NULL; -+ rdev = dereference_rdev_and_rrdev(&conf->mirrors[d], &rrdev); - if (rdev && (test_bit(Faulty, &rdev->flags))) - rdev = NULL; - if (rrdev && (test_bit(Faulty, &rrdev->flags))) -@@ -1775,10 +1784,9 @@ retry_discard: - */ - rcu_read_lock(); - for (disk = 0; disk < geo->raid_disks; disk++) { -- struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev); -- struct md_rdev *rrdev = rcu_dereference( -- conf->mirrors[disk].replacement); -+ struct md_rdev *rdev, *rrdev; - -+ rdev = dereference_rdev_and_rrdev(&conf->mirrors[disk], &rrdev); - r10_bio->devs[disk].bio = NULL; - r10_bio->devs[disk].repl_bio = NULL; - -diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c -index 832d8566e1656..eb66d0bfe39d2 100644 ---- a/drivers/md/raid5-cache.c -+++ b/drivers/md/raid5-cache.c -@@ -1260,14 +1260,13 @@ static void r5l_log_flush_endio(struct bio *bio) - - if (bio->bi_status) - md_error(log->rdev->mddev, log->rdev); -+ bio_uninit(bio); - - spin_lock_irqsave(&log->io_list_lock, flags); - list_for_each_entry(io, &log->flushing_ios, log_sibling) - r5l_io_run_stripes(io); - list_splice_tail_init(&log->flushing_ios, &log->finished_ios); - spin_unlock_irqrestore(&log->io_list_lock, flags); -- -- bio_uninit(bio); - } - - /* -@@ -3166,12 +3165,15 @@ void r5l_exit_log(struct r5conf *conf) - { - struct r5l_log *log = conf->log; - -- /* Ensure disable_writeback_work wakes up and exits */ -- wake_up(&conf->mddev->sb_wait); -- flush_work(&log->disable_writeback_work); - md_unregister_thread(&log->reclaim_thread); - -+ /* -+ * 'reconfig_mutex' is held by caller, set 'confg->log' to NULL to -+ * ensure disable_writeback_work wakes up and exits. -+ */ - conf->log = NULL; -+ wake_up(&conf->mddev->sb_wait); -+ flush_work(&log->disable_writeback_work); - - mempool_exit(&log->meta_pool); - bioset_exit(&log->bs); -diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c -index b1512f9c5895c..4bc2a705029e6 100644 ---- a/drivers/media/cec/core/cec-adap.c -+++ b/drivers/media/cec/core/cec-adap.c -@@ -385,8 +385,8 @@ static void cec_data_cancel(struct cec_data *data, u8 tx_status, u8 rx_status) - cec_queue_msg_monitor(adap, &data->msg, 1); - - if (!data->blocking && data->msg.sequence) -- /* Allow drivers to process the message first */ -- call_op(adap, received, &data->msg); -+ /* Allow drivers to react to a canceled transmit */ -+ call_void_op(adap, adap_nb_transmit_canceled, &data->msg); - - cec_data_completed(data); - } -@@ -1345,7 +1345,7 @@ static void cec_adap_unconfigure(struct cec_adapter *adap) - cec_flush(adap); - wake_up_interruptible(&adap->kthread_waitq); - cec_post_state_event(adap); -- call_void_op(adap, adap_configured, false); -+ call_void_op(adap, adap_unconfigured); - } - - /* -@@ -1536,7 +1536,7 @@ configured: - adap->kthread_config = NULL; - complete(&adap->config_completion); - mutex_unlock(&adap->lock); -- call_void_op(adap, adap_configured, true); -+ call_void_op(adap, configured); - return 0; - - unconfigure: -diff --git a/drivers/media/cec/usb/pulse8/pulse8-cec.c b/drivers/media/cec/usb/pulse8/pulse8-cec.c -index 04b13cdc38d2c..ba67587bd43ec 100644 ---- a/drivers/media/cec/usb/pulse8/pulse8-cec.c -+++ b/drivers/media/cec/usb/pulse8/pulse8-cec.c -@@ -809,8 +809,11 @@ static void pulse8_ping_eeprom_work_handler(struct work_struct *work) - - mutex_lock(&pulse8->lock); - cmd = MSGCODE_PING; -- pulse8_send_and_wait(pulse8, &cmd, 1, -- MSGCODE_COMMAND_ACCEPTED, 0); -+ if (pulse8_send_and_wait(pulse8, &cmd, 1, -+ MSGCODE_COMMAND_ACCEPTED, 0)) { -+ dev_warn(pulse8->dev, "failed to ping EEPROM\n"); -+ goto unlock; -+ } - - if (pulse8->vers < 2) - goto unlock; -diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c -index 9b00b56230b61..cf8e5f1bd1018 100644 ---- a/drivers/media/dvb-frontends/ascot2e.c -+++ b/drivers/media/dvb-frontends/ascot2e.c -@@ -533,7 +533,7 @@ struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe, - priv->i2c_address, priv->i2c); - return fe; - } --EXPORT_SYMBOL(ascot2e_attach); -+EXPORT_SYMBOL_GPL(ascot2e_attach); - - MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver"); - MODULE_AUTHOR("info@netup.ru"); -diff --git a/drivers/media/dvb-frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c -index bdd16b9c58244..778c865085bf9 100644 ---- a/drivers/media/dvb-frontends/atbm8830.c -+++ b/drivers/media/dvb-frontends/atbm8830.c -@@ -489,7 +489,7 @@ error_out: - return NULL; - - } --EXPORT_SYMBOL(atbm8830_attach); -+EXPORT_SYMBOL_GPL(atbm8830_attach); - - MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver"); - MODULE_AUTHOR("David T. L. Wong "); -diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c -index 78cafdf279618..230436bf6cbd9 100644 ---- a/drivers/media/dvb-frontends/au8522_dig.c -+++ b/drivers/media/dvb-frontends/au8522_dig.c -@@ -879,7 +879,7 @@ error: - au8522_release_state(state); - return NULL; - } --EXPORT_SYMBOL(au8522_attach); -+EXPORT_SYMBOL_GPL(au8522_attach); - - static const struct dvb_frontend_ops au8522_ops = { - .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, -diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c -index 68b92b4419cff..b3f5c49accafd 100644 ---- a/drivers/media/dvb-frontends/bcm3510.c -+++ b/drivers/media/dvb-frontends/bcm3510.c -@@ -835,7 +835,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(bcm3510_attach); -+EXPORT_SYMBOL_GPL(bcm3510_attach); - - static const struct dvb_frontend_ops bcm3510_ops = { - .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, -diff --git a/drivers/media/dvb-frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c -index b39ff516271b2..1d04c0a652b26 100644 ---- a/drivers/media/dvb-frontends/cx22700.c -+++ b/drivers/media/dvb-frontends/cx22700.c -@@ -432,4 +432,4 @@ MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver"); - MODULE_AUTHOR("Holger Waechtler"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(cx22700_attach); -+EXPORT_SYMBOL_GPL(cx22700_attach); -diff --git a/drivers/media/dvb-frontends/cx22702.c b/drivers/media/dvb-frontends/cx22702.c -index cc6acbf6393d4..61ad34b7004b5 100644 ---- a/drivers/media/dvb-frontends/cx22702.c -+++ b/drivers/media/dvb-frontends/cx22702.c -@@ -604,7 +604,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(cx22702_attach); -+EXPORT_SYMBOL_GPL(cx22702_attach); - - static const struct dvb_frontend_ops cx22702_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c -index 6f99d6a27be2d..9aeea089756fe 100644 ---- a/drivers/media/dvb-frontends/cx24110.c -+++ b/drivers/media/dvb-frontends/cx24110.c -@@ -653,4 +653,4 @@ MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver"); - MODULE_AUTHOR("Peter Hettkamp"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(cx24110_attach); -+EXPORT_SYMBOL_GPL(cx24110_attach); -diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c -index dd55d314bf9af..203cb6b3f941b 100644 ---- a/drivers/media/dvb-frontends/cx24113.c -+++ b/drivers/media/dvb-frontends/cx24113.c -@@ -590,7 +590,7 @@ error: - - return NULL; - } --EXPORT_SYMBOL(cx24113_attach); -+EXPORT_SYMBOL_GPL(cx24113_attach); - - module_param(debug, int, 0644); - MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); -diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c -index ea8264ccbb4e8..8b978a9f74a4e 100644 ---- a/drivers/media/dvb-frontends/cx24116.c -+++ b/drivers/media/dvb-frontends/cx24116.c -@@ -1133,7 +1133,7 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, - state->frontend.demodulator_priv = state; - return &state->frontend; - } --EXPORT_SYMBOL(cx24116_attach); -+EXPORT_SYMBOL_GPL(cx24116_attach); - - /* - * Initialise or wake up device -diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c -index d8acd582c7111..44515fdbe91d4 100644 ---- a/drivers/media/dvb-frontends/cx24120.c -+++ b/drivers/media/dvb-frontends/cx24120.c -@@ -305,7 +305,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(cx24120_attach); -+EXPORT_SYMBOL_GPL(cx24120_attach); - - static int cx24120_test_rom(struct cx24120_state *state) - { -@@ -973,7 +973,9 @@ static void cx24120_set_clock_ratios(struct dvb_frontend *fe) - cmd.arg[8] = (clock_ratios_table[idx].rate >> 8) & 0xff; - cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff; - -- cx24120_message_send(state, &cmd); -+ ret = cx24120_message_send(state, &cmd); -+ if (ret != 0) -+ return; - - /* Calculate ber window rates for stat work */ - cx24120_calculate_ber_window(state, clock_ratios_table[idx].rate); -diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c -index 3d84ee17e54c6..539889e638ccc 100644 ---- a/drivers/media/dvb-frontends/cx24123.c -+++ b/drivers/media/dvb-frontends/cx24123.c -@@ -1096,7 +1096,7 @@ error: - - return NULL; - } --EXPORT_SYMBOL(cx24123_attach); -+EXPORT_SYMBOL_GPL(cx24123_attach); - - static const struct dvb_frontend_ops cx24123_ops = { - .delsys = { SYS_DVBS }, -diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c -index 5d98222f9df09..8870aeac2872f 100644 ---- a/drivers/media/dvb-frontends/cxd2820r_core.c -+++ b/drivers/media/dvb-frontends/cxd2820r_core.c -@@ -536,7 +536,7 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *config, - - return pdata.get_dvb_frontend(client); - } --EXPORT_SYMBOL(cxd2820r_attach); -+EXPORT_SYMBOL_GPL(cxd2820r_attach); - - static struct dvb_frontend *cxd2820r_get_dvb_frontend(struct i2c_client *client) - { -diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c -index 5431f922f55e4..e9d1eef40c627 100644 ---- a/drivers/media/dvb-frontends/cxd2841er.c -+++ b/drivers/media/dvb-frontends/cxd2841er.c -@@ -3930,14 +3930,14 @@ struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg, - { - return cxd2841er_attach(cfg, i2c, SYS_DVBS); - } --EXPORT_SYMBOL(cxd2841er_attach_s); -+EXPORT_SYMBOL_GPL(cxd2841er_attach_s); - - struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg, - struct i2c_adapter *i2c) - { - return cxd2841er_attach(cfg, i2c, 0); - } --EXPORT_SYMBOL(cxd2841er_attach_t_c); -+EXPORT_SYMBOL_GPL(cxd2841er_attach_t_c); - - static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { - .delsys = { SYS_DVBS, SYS_DVBS2 }, -diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c -index d5b1b3788e392..09d31c368741d 100644 ---- a/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c -+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c -@@ -1950,7 +1950,7 @@ struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(cxd2880_attach); -+EXPORT_SYMBOL_GPL(cxd2880_attach); - - MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver"); - MODULE_AUTHOR("Sony Semiconductor Solutions Corporation"); -diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c -index cafb41dba861c..9a8e7cdd2a247 100644 ---- a/drivers/media/dvb-frontends/dib0070.c -+++ b/drivers/media/dvb-frontends/dib0070.c -@@ -762,7 +762,7 @@ free_mem: - fe->tuner_priv = NULL; - return NULL; - } --EXPORT_SYMBOL(dib0070_attach); -+EXPORT_SYMBOL_GPL(dib0070_attach); - - MODULE_AUTHOR("Patrick Boettcher "); - MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner"); -diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c -index 903da33642dff..c958bcff026ec 100644 ---- a/drivers/media/dvb-frontends/dib0090.c -+++ b/drivers/media/dvb-frontends/dib0090.c -@@ -2634,7 +2634,7 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte - return NULL; - } - --EXPORT_SYMBOL(dib0090_register); -+EXPORT_SYMBOL_GPL(dib0090_register); - - struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) - { -@@ -2660,7 +2660,7 @@ free_mem: - fe->tuner_priv = NULL; - return NULL; - } --EXPORT_SYMBOL(dib0090_fw_register); -+EXPORT_SYMBOL_GPL(dib0090_fw_register); - - MODULE_AUTHOR("Patrick Boettcher "); - MODULE_AUTHOR("Olivier Grenie "); -diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c -index a6c2fc4586eb3..c598b2a633256 100644 ---- a/drivers/media/dvb-frontends/dib3000mb.c -+++ b/drivers/media/dvb-frontends/dib3000mb.c -@@ -815,4 +815,4 @@ MODULE_AUTHOR(DRIVER_AUTHOR); - MODULE_DESCRIPTION(DRIVER_DESC); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(dib3000mb_attach); -+EXPORT_SYMBOL_GPL(dib3000mb_attach); -diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c -index 2e11a246aae0d..c2fca8289abae 100644 ---- a/drivers/media/dvb-frontends/dib3000mc.c -+++ b/drivers/media/dvb-frontends/dib3000mc.c -@@ -935,7 +935,7 @@ error: - kfree(st); - return NULL; - } --EXPORT_SYMBOL(dib3000mc_attach); -+EXPORT_SYMBOL_GPL(dib3000mc_attach); - - static const struct dvb_frontend_ops dib3000mc_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c -index 97ce97789c9e3..fdb22f32e3a11 100644 ---- a/drivers/media/dvb-frontends/dib7000m.c -+++ b/drivers/media/dvb-frontends/dib7000m.c -@@ -1434,7 +1434,7 @@ error: - kfree(st); - return NULL; - } --EXPORT_SYMBOL(dib7000m_attach); -+EXPORT_SYMBOL_GPL(dib7000m_attach); - - static const struct dvb_frontend_ops dib7000m_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c -index a90d2f51868ff..d1e53de5206ae 100644 ---- a/drivers/media/dvb-frontends/dib7000p.c -+++ b/drivers/media/dvb-frontends/dib7000p.c -@@ -497,7 +497,7 @@ static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth - prediv = reg_1856 & 0x3f; - loopdiv = (reg_1856 >> 6) & 0x3f; - -- if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) { -+ if (loopdiv && bw && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) { - dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio); - reg_1856 &= 0xf000; - reg_1857 = dib7000p_read_word(state, 1857); -@@ -2822,7 +2822,7 @@ void *dib7000p_attach(struct dib7000p_ops *ops) - - return ops; - } --EXPORT_SYMBOL(dib7000p_attach); -+EXPORT_SYMBOL_GPL(dib7000p_attach); - - static const struct dvb_frontend_ops dib7000p_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c -index fe19d127abb3f..301d8eca7a6f9 100644 ---- a/drivers/media/dvb-frontends/dib8000.c -+++ b/drivers/media/dvb-frontends/dib8000.c -@@ -4527,7 +4527,7 @@ void *dib8000_attach(struct dib8000_ops *ops) - - return ops; - } --EXPORT_SYMBOL(dib8000_attach); -+EXPORT_SYMBOL_GPL(dib8000_attach); - - MODULE_AUTHOR("Olivier Grenie "); - MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator"); -diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c -index 914ca820c174b..6f81890b31eeb 100644 ---- a/drivers/media/dvb-frontends/dib9000.c -+++ b/drivers/media/dvb-frontends/dib9000.c -@@ -2546,7 +2546,7 @@ error: - kfree(st); - return NULL; - } --EXPORT_SYMBOL(dib9000_attach); -+EXPORT_SYMBOL_GPL(dib9000_attach); - - static const struct dvb_frontend_ops dib9000_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c -index bf9e4ef35684b..88860d08f9c12 100644 ---- a/drivers/media/dvb-frontends/drx39xyj/drxj.c -+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c -@@ -12368,7 +12368,7 @@ error: - - return NULL; - } --EXPORT_SYMBOL(drx39xxj_attach); -+EXPORT_SYMBOL_GPL(drx39xxj_attach); - - static const struct dvb_frontend_ops drx39xxj_ops = { - .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, -diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c -index 9860cae65f1cf..6a531937f4bbb 100644 ---- a/drivers/media/dvb-frontends/drxd_hard.c -+++ b/drivers/media/dvb-frontends/drxd_hard.c -@@ -2939,7 +2939,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(drxd_attach); -+EXPORT_SYMBOL_GPL(drxd_attach); - - MODULE_DESCRIPTION("DRXD driver"); - MODULE_AUTHOR("Micronas"); -diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c -index 9807f54119965..ff864c9bb7743 100644 ---- a/drivers/media/dvb-frontends/drxk_hard.c -+++ b/drivers/media/dvb-frontends/drxk_hard.c -@@ -6833,7 +6833,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(drxk_attach); -+EXPORT_SYMBOL_GPL(drxk_attach); - - MODULE_DESCRIPTION("DRX-K driver"); - MODULE_AUTHOR("Ralph Metzler"); -diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c -index 20fcf31af1658..515aa7c7baf2a 100644 ---- a/drivers/media/dvb-frontends/ds3000.c -+++ b/drivers/media/dvb-frontends/ds3000.c -@@ -859,7 +859,7 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, - ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF); - return &state->frontend; - } --EXPORT_SYMBOL(ds3000_attach); -+EXPORT_SYMBOL_GPL(ds3000_attach); - - static int ds3000_set_carrier_offset(struct dvb_frontend *fe, - s32 carrier_offset_khz) -diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c -index baf2a378e565f..fcf322ff82356 100644 ---- a/drivers/media/dvb-frontends/dvb-pll.c -+++ b/drivers/media/dvb-frontends/dvb-pll.c -@@ -866,7 +866,7 @@ out: - - return NULL; - } --EXPORT_SYMBOL(dvb_pll_attach); -+EXPORT_SYMBOL_GPL(dvb_pll_attach); - - - static int -diff --git a/drivers/media/dvb-frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c -index 03bd80666cf83..2ad0a3c2f7567 100644 ---- a/drivers/media/dvb-frontends/ec100.c -+++ b/drivers/media/dvb-frontends/ec100.c -@@ -299,7 +299,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(ec100_attach); -+EXPORT_SYMBOL_GPL(ec100_attach); - - static const struct dvb_frontend_ops ec100_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c -index 8c1310c6b0bc2..c299d31dc7d27 100644 ---- a/drivers/media/dvb-frontends/helene.c -+++ b/drivers/media/dvb-frontends/helene.c -@@ -1025,7 +1025,7 @@ struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe, - priv->i2c_address, priv->i2c); - return fe; - } --EXPORT_SYMBOL(helene_attach_s); -+EXPORT_SYMBOL_GPL(helene_attach_s); - - struct dvb_frontend *helene_attach(struct dvb_frontend *fe, - const struct helene_config *config, -@@ -1061,7 +1061,7 @@ struct dvb_frontend *helene_attach(struct dvb_frontend *fe, - priv->i2c_address, priv->i2c); - return fe; - } --EXPORT_SYMBOL(helene_attach); -+EXPORT_SYMBOL_GPL(helene_attach); - - static int helene_probe(struct i2c_client *client, - const struct i2c_device_id *id) -diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c -index 24bf5cbcc1846..0330b78a5b3f2 100644 ---- a/drivers/media/dvb-frontends/horus3a.c -+++ b/drivers/media/dvb-frontends/horus3a.c -@@ -395,7 +395,7 @@ struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe, - priv->i2c_address, priv->i2c); - return fe; - } --EXPORT_SYMBOL(horus3a_attach); -+EXPORT_SYMBOL_GPL(horus3a_attach); - - MODULE_DESCRIPTION("Sony HORUS3A satellite tuner driver"); - MODULE_AUTHOR("Sergey Kozlov "); -diff --git a/drivers/media/dvb-frontends/isl6405.c b/drivers/media/dvb-frontends/isl6405.c -index 2cd69b4ff82cb..7d28a743f97eb 100644 ---- a/drivers/media/dvb-frontends/isl6405.c -+++ b/drivers/media/dvb-frontends/isl6405.c -@@ -141,7 +141,7 @@ struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter - - return fe; - } --EXPORT_SYMBOL(isl6405_attach); -+EXPORT_SYMBOL_GPL(isl6405_attach); - - MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405"); - MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss"); -diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c -index 43b0dfc6f453e..2e9f6f12f849e 100644 ---- a/drivers/media/dvb-frontends/isl6421.c -+++ b/drivers/media/dvb-frontends/isl6421.c -@@ -213,7 +213,7 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter - - return fe; - } --EXPORT_SYMBOL(isl6421_attach); -+EXPORT_SYMBOL_GPL(isl6421_attach); - - MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); - MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); -diff --git a/drivers/media/dvb-frontends/isl6423.c b/drivers/media/dvb-frontends/isl6423.c -index 8cd1bb88ce6e7..a0d0a38340574 100644 ---- a/drivers/media/dvb-frontends/isl6423.c -+++ b/drivers/media/dvb-frontends/isl6423.c -@@ -289,7 +289,7 @@ exit: - fe->sec_priv = NULL; - return NULL; - } --EXPORT_SYMBOL(isl6423_attach); -+EXPORT_SYMBOL_GPL(isl6423_attach); - - MODULE_DESCRIPTION("ISL6423 SEC"); - MODULE_AUTHOR("Manu Abraham"); -diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c -index 1b33478653d16..f8f362f50e78d 100644 ---- a/drivers/media/dvb-frontends/itd1000.c -+++ b/drivers/media/dvb-frontends/itd1000.c -@@ -389,7 +389,7 @@ struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter - - return fe; - } --EXPORT_SYMBOL(itd1000_attach); -+EXPORT_SYMBOL_GPL(itd1000_attach); - - MODULE_AUTHOR("Patrick Boettcher "); - MODULE_DESCRIPTION("Integrant ITD1000 driver"); -diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c -index 73f27105c139d..3212e333d472b 100644 ---- a/drivers/media/dvb-frontends/ix2505v.c -+++ b/drivers/media/dvb-frontends/ix2505v.c -@@ -302,7 +302,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(ix2505v_attach); -+EXPORT_SYMBOL_GPL(ix2505v_attach); - - module_param_named(debug, ix2505v_debug, int, 0644); - MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c -index c5106a1ea1cd0..fe5af2453d559 100644 ---- a/drivers/media/dvb-frontends/l64781.c -+++ b/drivers/media/dvb-frontends/l64781.c -@@ -593,4 +593,4 @@ MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver"); - MODULE_AUTHOR("Holger Waechtler, Marko Kohtala"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(l64781_attach); -+EXPORT_SYMBOL_GPL(l64781_attach); -diff --git a/drivers/media/dvb-frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c -index f343066c297e2..fe700aa56bff3 100644 ---- a/drivers/media/dvb-frontends/lg2160.c -+++ b/drivers/media/dvb-frontends/lg2160.c -@@ -1426,7 +1426,7 @@ struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, - - return &state->frontend; - } --EXPORT_SYMBOL(lg2160_attach); -+EXPORT_SYMBOL_GPL(lg2160_attach); - - MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver"); - MODULE_AUTHOR("Michael Krufky "); -diff --git a/drivers/media/dvb-frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c -index 62d7439889196..60a97f1cc74e5 100644 ---- a/drivers/media/dvb-frontends/lgdt3305.c -+++ b/drivers/media/dvb-frontends/lgdt3305.c -@@ -1148,7 +1148,7 @@ fail: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(lgdt3305_attach); -+EXPORT_SYMBOL_GPL(lgdt3305_attach); - - static const struct dvb_frontend_ops lgdt3304_ops = { - .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, -diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c -index 424311afb2bfa..6dfa8b18ed671 100644 ---- a/drivers/media/dvb-frontends/lgdt3306a.c -+++ b/drivers/media/dvb-frontends/lgdt3306a.c -@@ -1859,7 +1859,7 @@ fail: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(lgdt3306a_attach); -+EXPORT_SYMBOL_GPL(lgdt3306a_attach); - - #ifdef DBG_DUMP - -diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c -index ea9ae22fd2016..cb07869ea2fb3 100644 ---- a/drivers/media/dvb-frontends/lgdt330x.c -+++ b/drivers/media/dvb-frontends/lgdt330x.c -@@ -928,7 +928,7 @@ struct dvb_frontend *lgdt330x_attach(const struct lgdt330x_config *_config, - - return lgdt330x_get_dvb_frontend(client); - } --EXPORT_SYMBOL(lgdt330x_attach); -+EXPORT_SYMBOL_GPL(lgdt330x_attach); - - static const struct dvb_frontend_ops lgdt3302_ops = { - .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, -diff --git a/drivers/media/dvb-frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c -index 30014979b985b..ffaf60e16ecd4 100644 ---- a/drivers/media/dvb-frontends/lgs8gxx.c -+++ b/drivers/media/dvb-frontends/lgs8gxx.c -@@ -1043,7 +1043,7 @@ error_out: - return NULL; - - } --EXPORT_SYMBOL(lgs8gxx_attach); -+EXPORT_SYMBOL_GPL(lgs8gxx_attach); - - MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver"); - MODULE_AUTHOR("David T. L. Wong "); -diff --git a/drivers/media/dvb-frontends/lnbh25.c b/drivers/media/dvb-frontends/lnbh25.c -index 9ffe06cd787dd..41bec050642b5 100644 ---- a/drivers/media/dvb-frontends/lnbh25.c -+++ b/drivers/media/dvb-frontends/lnbh25.c -@@ -173,7 +173,7 @@ struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, - __func__, priv->i2c_address); - return fe; - } --EXPORT_SYMBOL(lnbh25_attach); -+EXPORT_SYMBOL_GPL(lnbh25_attach); - - MODULE_DESCRIPTION("ST LNBH25 driver"); - MODULE_AUTHOR("info@netup.ru"); -diff --git a/drivers/media/dvb-frontends/lnbp21.c b/drivers/media/dvb-frontends/lnbp21.c -index e564974162d65..32593b1f75a38 100644 ---- a/drivers/media/dvb-frontends/lnbp21.c -+++ b/drivers/media/dvb-frontends/lnbp21.c -@@ -155,7 +155,7 @@ struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, - return lnbx2x_attach(fe, i2c, override_set, override_clear, - i2c_addr, LNBH24_TTX); - } --EXPORT_SYMBOL(lnbh24_attach); -+EXPORT_SYMBOL_GPL(lnbh24_attach); - - struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 override_set, -@@ -164,7 +164,7 @@ struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, - return lnbx2x_attach(fe, i2c, override_set, override_clear, - 0x08, LNBP21_ISEL); - } --EXPORT_SYMBOL(lnbp21_attach); -+EXPORT_SYMBOL_GPL(lnbp21_attach); - - MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24"); - MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin"); -diff --git a/drivers/media/dvb-frontends/lnbp22.c b/drivers/media/dvb-frontends/lnbp22.c -index b8c7145d4cefe..cb4ea5d3fad4a 100644 ---- a/drivers/media/dvb-frontends/lnbp22.c -+++ b/drivers/media/dvb-frontends/lnbp22.c -@@ -125,7 +125,7 @@ struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(lnbp22_attach); -+EXPORT_SYMBOL_GPL(lnbp22_attach); - - MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp22"); - MODULE_AUTHOR("Dominik Kuhlen"); -diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c -index 4e844b2ef5971..9a0d43c7ba9e0 100644 ---- a/drivers/media/dvb-frontends/m88ds3103.c -+++ b/drivers/media/dvb-frontends/m88ds3103.c -@@ -1695,7 +1695,7 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, - *tuner_i2c_adapter = pdata.get_i2c_adapter(client); - return pdata.get_dvb_frontend(client); - } --EXPORT_SYMBOL(m88ds3103_attach); -+EXPORT_SYMBOL_GPL(m88ds3103_attach); - - static const struct dvb_frontend_ops m88ds3103_ops = { - .delsys = {SYS_DVBS, SYS_DVBS2}, -diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c -index b294ba87e934f..2aa98203cd659 100644 ---- a/drivers/media/dvb-frontends/m88rs2000.c -+++ b/drivers/media/dvb-frontends/m88rs2000.c -@@ -808,7 +808,7 @@ error: - - return NULL; - } --EXPORT_SYMBOL(m88rs2000_attach); -+EXPORT_SYMBOL_GPL(m88rs2000_attach); - - MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver"); - MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); -diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c -index 2505f1e5794e7..ed08e0c2cf512 100644 ---- a/drivers/media/dvb-frontends/mb86a16.c -+++ b/drivers/media/dvb-frontends/mb86a16.c -@@ -1848,6 +1848,6 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(mb86a16_attach); -+EXPORT_SYMBOL_GPL(mb86a16_attach); - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Manu Abraham"); -diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c -index b74b9afed9a2e..9f5c61d4f23c5 100644 ---- a/drivers/media/dvb-frontends/mb86a20s.c -+++ b/drivers/media/dvb-frontends/mb86a20s.c -@@ -2081,7 +2081,7 @@ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, - dev_info(&i2c->dev, "Detected a Fujitsu mb86a20s frontend\n"); - return &state->frontend; - } --EXPORT_SYMBOL(mb86a20s_attach); -+EXPORT_SYMBOL_GPL(mb86a20s_attach); - - static const struct dvb_frontend_ops mb86a20s_ops = { - .delsys = { SYS_ISDBT }, -diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c -index d43a67045dbe7..fb867dd8a26be 100644 ---- a/drivers/media/dvb-frontends/mt312.c -+++ b/drivers/media/dvb-frontends/mt312.c -@@ -827,7 +827,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(mt312_attach); -+EXPORT_SYMBOL_GPL(mt312_attach); - - module_param(debug, int, 0644); - MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -diff --git a/drivers/media/dvb-frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c -index 399d5c519027e..1b2889f5cf67d 100644 ---- a/drivers/media/dvb-frontends/mt352.c -+++ b/drivers/media/dvb-frontends/mt352.c -@@ -593,4 +593,4 @@ MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver"); - MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(mt352_attach); -+EXPORT_SYMBOL_GPL(mt352_attach); -diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c -index 200b6dbc75f81..1c549ada6ebf9 100644 ---- a/drivers/media/dvb-frontends/nxt200x.c -+++ b/drivers/media/dvb-frontends/nxt200x.c -@@ -1216,5 +1216,5 @@ MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulat - MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(nxt200x_attach); -+EXPORT_SYMBOL_GPL(nxt200x_attach); - -diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c -index 136918f82dda0..e8d4940370ddf 100644 ---- a/drivers/media/dvb-frontends/nxt6000.c -+++ b/drivers/media/dvb-frontends/nxt6000.c -@@ -621,4 +621,4 @@ MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver"); - MODULE_AUTHOR("Florian Schirmer"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(nxt6000_attach); -+EXPORT_SYMBOL_GPL(nxt6000_attach); -diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c -index 24de1b1151583..144a1f25dec0a 100644 ---- a/drivers/media/dvb-frontends/or51132.c -+++ b/drivers/media/dvb-frontends/or51132.c -@@ -605,4 +605,4 @@ MODULE_AUTHOR("Kirk Lapray"); - MODULE_AUTHOR("Trent Piepho"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(or51132_attach); -+EXPORT_SYMBOL_GPL(or51132_attach); -diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c -index ddcaea5c9941f..dc60482162c54 100644 ---- a/drivers/media/dvb-frontends/or51211.c -+++ b/drivers/media/dvb-frontends/or51211.c -@@ -551,5 +551,5 @@ MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver"); - MODULE_AUTHOR("Kirk Lapray"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(or51211_attach); -+EXPORT_SYMBOL_GPL(or51211_attach); - -diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c -index 3089cc174a6f5..28b1dca077ead 100644 ---- a/drivers/media/dvb-frontends/s5h1409.c -+++ b/drivers/media/dvb-frontends/s5h1409.c -@@ -981,7 +981,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(s5h1409_attach); -+EXPORT_SYMBOL_GPL(s5h1409_attach); - - static const struct dvb_frontend_ops s5h1409_ops = { - .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, -diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c -index 2563a72e98b70..fc48e659c2d8a 100644 ---- a/drivers/media/dvb-frontends/s5h1411.c -+++ b/drivers/media/dvb-frontends/s5h1411.c -@@ -900,7 +900,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(s5h1411_attach); -+EXPORT_SYMBOL_GPL(s5h1411_attach); - - static const struct dvb_frontend_ops s5h1411_ops = { - .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, -diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c -index 6bdec2898bc81..d700de1ea6c24 100644 ---- a/drivers/media/dvb-frontends/s5h1420.c -+++ b/drivers/media/dvb-frontends/s5h1420.c -@@ -918,7 +918,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(s5h1420_attach); -+EXPORT_SYMBOL_GPL(s5h1420_attach); - - static const struct dvb_frontend_ops s5h1420_ops = { - .delsys = { SYS_DVBS }, -diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c -index 956e8ee4b388e..ff5d3bdf3bc67 100644 ---- a/drivers/media/dvb-frontends/s5h1432.c -+++ b/drivers/media/dvb-frontends/s5h1432.c -@@ -355,7 +355,7 @@ struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, - - return &state->frontend; - } --EXPORT_SYMBOL(s5h1432_attach); -+EXPORT_SYMBOL_GPL(s5h1432_attach); - - static const struct dvb_frontend_ops s5h1432_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c -index f118d8e641030..7e461ac159fc1 100644 ---- a/drivers/media/dvb-frontends/s921.c -+++ b/drivers/media/dvb-frontends/s921.c -@@ -495,7 +495,7 @@ struct dvb_frontend *s921_attach(const struct s921_config *config, - - return &state->frontend; - } --EXPORT_SYMBOL(s921_attach); -+EXPORT_SYMBOL_GPL(s921_attach); - - static const struct dvb_frontend_ops s921_ops = { - .delsys = { SYS_ISDBT }, -diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c -index 2d29d2c4d434c..210ccd356e2bf 100644 ---- a/drivers/media/dvb-frontends/si21xx.c -+++ b/drivers/media/dvb-frontends/si21xx.c -@@ -937,7 +937,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(si21xx_attach); -+EXPORT_SYMBOL_GPL(si21xx_attach); - - module_param(debug, int, 0644); - MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c -index 146e7f2dd3c5e..f59c0f96416b5 100644 ---- a/drivers/media/dvb-frontends/sp887x.c -+++ b/drivers/media/dvb-frontends/sp887x.c -@@ -624,4 +624,4 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(sp887x_attach); -+EXPORT_SYMBOL_GPL(sp887x_attach); -diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c -index 4ee6c1e1e9f7d..2f4d8fb400cd6 100644 ---- a/drivers/media/dvb-frontends/stb0899_drv.c -+++ b/drivers/media/dvb-frontends/stb0899_drv.c -@@ -1638,7 +1638,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(stb0899_attach); -+EXPORT_SYMBOL_GPL(stb0899_attach); - MODULE_PARM_DESC(verbose, "Set Verbosity level"); - MODULE_AUTHOR("Manu Abraham"); - MODULE_DESCRIPTION("STB0899 Multi-Std frontend"); -diff --git a/drivers/media/dvb-frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c -index 8c9800d577e03..d74e34677b925 100644 ---- a/drivers/media/dvb-frontends/stb6000.c -+++ b/drivers/media/dvb-frontends/stb6000.c -@@ -232,7 +232,7 @@ struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, - - return fe; - } --EXPORT_SYMBOL(stb6000_attach); -+EXPORT_SYMBOL_GPL(stb6000_attach); - - module_param(debug, int, 0644); - MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c -index 698866c4f15a7..c5818a15a0d70 100644 ---- a/drivers/media/dvb-frontends/stb6100.c -+++ b/drivers/media/dvb-frontends/stb6100.c -@@ -557,7 +557,7 @@ static void stb6100_release(struct dvb_frontend *fe) - kfree(state); - } - --EXPORT_SYMBOL(stb6100_attach); -+EXPORT_SYMBOL_GPL(stb6100_attach); - MODULE_PARM_DESC(verbose, "Set Verbosity level"); - - MODULE_AUTHOR("Manu Abraham"); -diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c -index 3ae1f3a2f1420..a5581bd60f9e8 100644 ---- a/drivers/media/dvb-frontends/stv0288.c -+++ b/drivers/media/dvb-frontends/stv0288.c -@@ -590,7 +590,7 @@ error: - - return NULL; - } --EXPORT_SYMBOL(stv0288_attach); -+EXPORT_SYMBOL_GPL(stv0288_attach); - - module_param(debug_legacy_dish_switch, int, 0444); - MODULE_PARM_DESC(debug_legacy_dish_switch, -diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c -index 6d5962d5697ac..9d4dbd99a5a79 100644 ---- a/drivers/media/dvb-frontends/stv0297.c -+++ b/drivers/media/dvb-frontends/stv0297.c -@@ -710,4 +710,4 @@ MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver"); - MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(stv0297_attach); -+EXPORT_SYMBOL_GPL(stv0297_attach); -diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c -index b5263a0ee5aa5..da7ff2c2e8e55 100644 ---- a/drivers/media/dvb-frontends/stv0299.c -+++ b/drivers/media/dvb-frontends/stv0299.c -@@ -752,4 +752,4 @@ MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); - MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(stv0299_attach); -+EXPORT_SYMBOL_GPL(stv0299_attach); -diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c -index 95e376f23506f..04556b77c16c9 100644 ---- a/drivers/media/dvb-frontends/stv0367.c -+++ b/drivers/media/dvb-frontends/stv0367.c -@@ -1750,7 +1750,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(stv0367ter_attach); -+EXPORT_SYMBOL_GPL(stv0367ter_attach); - - static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable) - { -@@ -2919,7 +2919,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(stv0367cab_attach); -+EXPORT_SYMBOL_GPL(stv0367cab_attach); - - /* - * Functions for operation on Digital Devices hardware -@@ -3340,7 +3340,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(stv0367ddb_attach); -+EXPORT_SYMBOL_GPL(stv0367ddb_attach); - - MODULE_PARM_DESC(debug, "Set debug"); - MODULE_PARM_DESC(i2c_debug, "Set i2c debug"); -diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c -index 212312d20ff62..e7b9b9b11d7df 100644 ---- a/drivers/media/dvb-frontends/stv0900_core.c -+++ b/drivers/media/dvb-frontends/stv0900_core.c -@@ -1957,7 +1957,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(stv0900_attach); -+EXPORT_SYMBOL_GPL(stv0900_attach); - - MODULE_PARM_DESC(debug, "Set debug"); - -diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c -index 0a600c1d7d1b1..aba64162dac45 100644 ---- a/drivers/media/dvb-frontends/stv090x.c -+++ b/drivers/media/dvb-frontends/stv090x.c -@@ -5072,7 +5072,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(stv090x_attach); -+EXPORT_SYMBOL_GPL(stv090x_attach); - - static const struct i2c_device_id stv090x_id_table[] = { - {"stv090x", 0}, -diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c -index 963f6a896102a..1cf9c095dbff0 100644 ---- a/drivers/media/dvb-frontends/stv6110.c -+++ b/drivers/media/dvb-frontends/stv6110.c -@@ -427,7 +427,7 @@ struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(stv6110_attach); -+EXPORT_SYMBOL_GPL(stv6110_attach); - - module_param(debug, int, 0644); - MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c -index fbc4dbd62151d..6ab2001215917 100644 ---- a/drivers/media/dvb-frontends/stv6110x.c -+++ b/drivers/media/dvb-frontends/stv6110x.c -@@ -468,7 +468,7 @@ const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, - dev_info(&stv6110x->i2c->dev, "Attaching STV6110x\n"); - return stv6110x->devctl; - } --EXPORT_SYMBOL(stv6110x_attach); -+EXPORT_SYMBOL_GPL(stv6110x_attach); - - static const struct i2c_device_id stv6110x_id_table[] = { - {"stv6110x", 0}, -diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c -index faa6e54b33729..462e12ab6bd14 100644 ---- a/drivers/media/dvb-frontends/tda10021.c -+++ b/drivers/media/dvb-frontends/tda10021.c -@@ -523,4 +523,4 @@ MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver"); - MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(tda10021_attach); -+EXPORT_SYMBOL_GPL(tda10021_attach); -diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c -index 8f32edf6b700e..4c2541ecd7433 100644 ---- a/drivers/media/dvb-frontends/tda10023.c -+++ b/drivers/media/dvb-frontends/tda10023.c -@@ -594,4 +594,4 @@ MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver"); - MODULE_AUTHOR("Georg Acher, Hartmut Birr"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(tda10023_attach); -+EXPORT_SYMBOL_GPL(tda10023_attach); -diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c -index 0b3f6999515e3..f6d8a64762b99 100644 ---- a/drivers/media/dvb-frontends/tda10048.c -+++ b/drivers/media/dvb-frontends/tda10048.c -@@ -1138,7 +1138,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(tda10048_attach); -+EXPORT_SYMBOL_GPL(tda10048_attach); - - static const struct dvb_frontend_ops tda10048_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c -index 83a798ca9b002..6f306db6c615f 100644 ---- a/drivers/media/dvb-frontends/tda1004x.c -+++ b/drivers/media/dvb-frontends/tda1004x.c -@@ -1378,5 +1378,5 @@ MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator"); - MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(tda10045_attach); --EXPORT_SYMBOL(tda10046_attach); -+EXPORT_SYMBOL_GPL(tda10045_attach); -+EXPORT_SYMBOL_GPL(tda10046_attach); -diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c -index cdcf97664bba8..b449514ae5854 100644 ---- a/drivers/media/dvb-frontends/tda10086.c -+++ b/drivers/media/dvb-frontends/tda10086.c -@@ -764,4 +764,4 @@ MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator"); - MODULE_AUTHOR("Andrew de Quincey"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(tda10086_attach); -+EXPORT_SYMBOL_GPL(tda10086_attach); -diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c -index 13e8969da7f89..346be5011fb73 100644 ---- a/drivers/media/dvb-frontends/tda665x.c -+++ b/drivers/media/dvb-frontends/tda665x.c -@@ -227,7 +227,7 @@ struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(tda665x_attach); -+EXPORT_SYMBOL_GPL(tda665x_attach); - - MODULE_DESCRIPTION("TDA665x driver"); - MODULE_AUTHOR("Manu Abraham"); -diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c -index e3e1c3db2c856..44f53624557bc 100644 ---- a/drivers/media/dvb-frontends/tda8083.c -+++ b/drivers/media/dvb-frontends/tda8083.c -@@ -481,4 +481,4 @@ MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator"); - MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(tda8083_attach); -+EXPORT_SYMBOL_GPL(tda8083_attach); -diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c -index 0d576d41c67d8..8b06f92745dca 100644 ---- a/drivers/media/dvb-frontends/tda8261.c -+++ b/drivers/media/dvb-frontends/tda8261.c -@@ -188,7 +188,7 @@ exit: - return NULL; - } - --EXPORT_SYMBOL(tda8261_attach); -+EXPORT_SYMBOL_GPL(tda8261_attach); - - MODULE_AUTHOR("Manu Abraham"); - MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner"); -diff --git a/drivers/media/dvb-frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c -index f9703a1dd758c..eafcf5f7da3dc 100644 ---- a/drivers/media/dvb-frontends/tda826x.c -+++ b/drivers/media/dvb-frontends/tda826x.c -@@ -164,7 +164,7 @@ struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2 - - return fe; - } --EXPORT_SYMBOL(tda826x_attach); -+EXPORT_SYMBOL_GPL(tda826x_attach); - - module_param(debug, int, 0644); - MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c -index 02338256b974f..2f64f1a8bc233 100644 ---- a/drivers/media/dvb-frontends/ts2020.c -+++ b/drivers/media/dvb-frontends/ts2020.c -@@ -525,7 +525,7 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(ts2020_attach); -+EXPORT_SYMBOL_GPL(ts2020_attach); - - /* - * We implement own regmap locking due to legacy DVB attach which uses frontend -diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c -index 2483f614d0e7d..41dd9b6d31908 100644 ---- a/drivers/media/dvb-frontends/tua6100.c -+++ b/drivers/media/dvb-frontends/tua6100.c -@@ -186,7 +186,7 @@ struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2 - fe->tuner_priv = priv; - return fe; - } --EXPORT_SYMBOL(tua6100_attach); -+EXPORT_SYMBOL_GPL(tua6100_attach); - - MODULE_DESCRIPTION("DVB tua6100 driver"); - MODULE_AUTHOR("Andrew de Quincey"); -diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c -index 9df14d0be1c1a..ee5620e731e9b 100644 ---- a/drivers/media/dvb-frontends/ves1820.c -+++ b/drivers/media/dvb-frontends/ves1820.c -@@ -434,4 +434,4 @@ MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver"); - MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(ves1820_attach); -+EXPORT_SYMBOL_GPL(ves1820_attach); -diff --git a/drivers/media/dvb-frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c -index b747272863025..c60e21d26b881 100644 ---- a/drivers/media/dvb-frontends/ves1x93.c -+++ b/drivers/media/dvb-frontends/ves1x93.c -@@ -540,4 +540,4 @@ MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver"); - MODULE_AUTHOR("Ralph Metzler"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(ves1x93_attach); -+EXPORT_SYMBOL_GPL(ves1x93_attach); -diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c -index d392c7cce2ce0..7ba575e9c55f4 100644 ---- a/drivers/media/dvb-frontends/zl10036.c -+++ b/drivers/media/dvb-frontends/zl10036.c -@@ -496,7 +496,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(zl10036_attach); -+EXPORT_SYMBOL_GPL(zl10036_attach); - - module_param_named(debug, zl10036_debug, int, 0644); - MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c -index 1335bf78d5b7f..a3e4d219400ce 100644 ---- a/drivers/media/dvb-frontends/zl10039.c -+++ b/drivers/media/dvb-frontends/zl10039.c -@@ -295,7 +295,7 @@ error: - kfree(state); - return NULL; - } --EXPORT_SYMBOL(zl10039_attach); -+EXPORT_SYMBOL_GPL(zl10039_attach); - - module_param(debug, int, 0644); - MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c -index 2a2cf20a73d61..8849d05475c27 100644 ---- a/drivers/media/dvb-frontends/zl10353.c -+++ b/drivers/media/dvb-frontends/zl10353.c -@@ -665,4 +665,4 @@ MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver"); - MODULE_AUTHOR("Chris Pascoe"); - MODULE_LICENSE("GPL"); - --EXPORT_SYMBOL(zl10353_attach); -+EXPORT_SYMBOL_GPL(zl10353_attach); -diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig -index 7806d4b81716e..a34afb5217ebc 100644 ---- a/drivers/media/i2c/Kconfig -+++ b/drivers/media/i2c/Kconfig -@@ -25,8 +25,15 @@ config VIDEO_IR_I2C - # V4L2 I2C drivers that are related with Camera support - # - --menu "Camera sensor devices" -- visible if MEDIA_CAMERA_SUPPORT -+menuconfig VIDEO_CAMERA_SENSOR -+ bool "Camera sensor devices" -+ depends on MEDIA_CAMERA_SUPPORT && I2C -+ select MEDIA_CONTROLLER -+ select V4L2_FWNODE -+ select VIDEO_V4L2_SUBDEV_API -+ default y -+ -+if VIDEO_CAMERA_SENSOR - - config VIDEO_APTINA_PLL - tristate -@@ -783,7 +790,7 @@ source "drivers/media/i2c/ccs/Kconfig" - source "drivers/media/i2c/et8ek8/Kconfig" - source "drivers/media/i2c/m5mols/Kconfig" - --endmenu -+endif - - menu "Lens drivers" - visible if MEDIA_CAMERA_SUPPORT -diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c -index a12fedcc3a1ce..088c29c4e2529 100644 ---- a/drivers/media/i2c/ad5820.c -+++ b/drivers/media/i2c/ad5820.c -@@ -356,7 +356,6 @@ static void ad5820_remove(struct i2c_client *client) - static const struct i2c_device_id ad5820_id_table[] = { - { "ad5820", 0 }, - { "ad5821", 0 }, -- { "ad5823", 0 }, - { } - }; - MODULE_DEVICE_TABLE(i2c, ad5820_id_table); -@@ -364,7 +363,6 @@ MODULE_DEVICE_TABLE(i2c, ad5820_id_table); - static const struct of_device_id ad5820_of_table[] = { - { .compatible = "adi,ad5820" }, - { .compatible = "adi,ad5821" }, -- { .compatible = "adi,ad5823" }, - { } - }; - MODULE_DEVICE_TABLE(of, ad5820_of_table); -diff --git a/drivers/media/i2c/ccs/ccs-data.c b/drivers/media/i2c/ccs/ccs-data.c -index 45f2b2f55ec5c..08400edf77ced 100644 ---- a/drivers/media/i2c/ccs/ccs-data.c -+++ b/drivers/media/i2c/ccs/ccs-data.c -@@ -464,8 +464,7 @@ static int ccs_data_parse_rules(struct bin_container *bin, - rule_payload = __rule_type + 1; - rule_plen2 = rule_plen - sizeof(*__rule_type); - -- switch (*__rule_type) { -- case CCS_DATA_BLOCK_RULE_ID_IF: { -+ if (*__rule_type == CCS_DATA_BLOCK_RULE_ID_IF) { - const struct __ccs_data_block_rule_if *__if_rules = - rule_payload; - const size_t __num_if_rules = -@@ -514,49 +513,61 @@ static int ccs_data_parse_rules(struct bin_container *bin, - rules->if_rules = if_rule; - rules->num_if_rules = __num_if_rules; - } -- break; -- } -- case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS: -- rval = ccs_data_parse_reg_rules(bin, &rules->read_only_regs, -- &rules->num_read_only_regs, -- rule_payload, -- rule_payload + rule_plen2, -- dev); -- if (rval) -- return rval; -- break; -- case CCS_DATA_BLOCK_RULE_ID_FFD: -- rval = ccs_data_parse_ffd(bin, &rules->frame_format, -- rule_payload, -- rule_payload + rule_plen2, -- dev); -- if (rval) -- return rval; -- break; -- case CCS_DATA_BLOCK_RULE_ID_MSR: -- rval = ccs_data_parse_reg_rules(bin, -- &rules->manufacturer_regs, -- &rules->num_manufacturer_regs, -- rule_payload, -- rule_payload + rule_plen2, -- dev); -- if (rval) -- return rval; -- break; -- case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT: -- rval = ccs_data_parse_pdaf_readout(bin, -- &rules->pdaf_readout, -- rule_payload, -- rule_payload + rule_plen2, -- dev); -- if (rval) -- return rval; -- break; -- default: -- dev_dbg(dev, -- "Don't know how to handle rule type %u!\n", -- *__rule_type); -- return -EINVAL; -+ } else { -+ /* Check there was an if rule before any other rules */ -+ if (bin->base && !rules) -+ return -EINVAL; -+ -+ switch (*__rule_type) { -+ case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS: -+ rval = ccs_data_parse_reg_rules(bin, -+ rules ? -+ &rules->read_only_regs : NULL, -+ rules ? -+ &rules->num_read_only_regs : NULL, -+ rule_payload, -+ rule_payload + rule_plen2, -+ dev); -+ if (rval) -+ return rval; -+ break; -+ case CCS_DATA_BLOCK_RULE_ID_FFD: -+ rval = ccs_data_parse_ffd(bin, rules ? -+ &rules->frame_format : NULL, -+ rule_payload, -+ rule_payload + rule_plen2, -+ dev); -+ if (rval) -+ return rval; -+ break; -+ case CCS_DATA_BLOCK_RULE_ID_MSR: -+ rval = ccs_data_parse_reg_rules(bin, -+ rules ? -+ &rules->manufacturer_regs : NULL, -+ rules ? -+ &rules->num_manufacturer_regs : NULL, -+ rule_payload, -+ rule_payload + rule_plen2, -+ dev); -+ if (rval) -+ return rval; -+ break; -+ case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT: -+ rval = ccs_data_parse_pdaf_readout(bin, -+ rules ? -+ &rules->pdaf_readout : NULL, -+ rule_payload, -+ rule_payload + rule_plen2, -+ dev); -+ if (rval) -+ return rval; -+ break; -+ default: -+ dev_dbg(dev, -+ "Don't know how to handle rule type %u!\n", -+ *__rule_type); -+ return -EINVAL; -+ } - } - __next_rule = __next_rule + rule_hlen + rule_plen; - } -diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c -index de66d3395a4dd..8943e4e78a0df 100644 ---- a/drivers/media/i2c/ov2680.c -+++ b/drivers/media/i2c/ov2680.c -@@ -54,6 +54,9 @@ - #define OV2680_WIDTH_MAX 1600 - #define OV2680_HEIGHT_MAX 1200 - -+#define OV2680_DEFAULT_WIDTH 800 -+#define OV2680_DEFAULT_HEIGHT 600 -+ - enum ov2680_mode_id { - OV2680_MODE_QUXGA_800_600, - OV2680_MODE_720P_1280_720, -@@ -85,15 +88,8 @@ struct ov2680_mode_info { - - struct ov2680_ctrls { - struct v4l2_ctrl_handler handler; -- struct { -- struct v4l2_ctrl *auto_exp; -- struct v4l2_ctrl *exposure; -- }; -- struct { -- struct v4l2_ctrl *auto_gain; -- struct v4l2_ctrl *gain; -- }; -- -+ struct v4l2_ctrl *exposure; -+ struct v4l2_ctrl *gain; - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vflip; - struct v4l2_ctrl *test_pattern; -@@ -143,6 +139,7 @@ static const struct reg_value ov2680_setting_30fps_QUXGA_800_600[] = { - {0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04}, - {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0xc0}, {0x4008, 0x00}, - {0x4009, 0x03}, {0x4837, 0x1e}, {0x3501, 0x4e}, {0x3502, 0xe0}, -+ {0x3503, 0x03}, - }; - - static const struct reg_value ov2680_setting_30fps_720P_1280_720[] = { -@@ -321,70 +318,62 @@ static void ov2680_power_down(struct ov2680_dev *sensor) - usleep_range(5000, 10000); - } - --static int ov2680_bayer_order(struct ov2680_dev *sensor) -+static void ov2680_set_bayer_order(struct ov2680_dev *sensor, -+ struct v4l2_mbus_framefmt *fmt) - { -- u32 format1; -- u32 format2; -- u32 hv_flip; -- int ret; -- -- ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT1, &format1); -- if (ret < 0) -- return ret; -- -- ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT2, &format2); -- if (ret < 0) -- return ret; -+ int hv_flip = 0; - -- hv_flip = (format2 & BIT(2) << 1) | (format1 & BIT(2)); -+ if (sensor->ctrls.vflip && sensor->ctrls.vflip->val) -+ hv_flip += 1; - -- sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip]; -+ if (sensor->ctrls.hflip && sensor->ctrls.hflip->val) -+ hv_flip += 2; - -- return 0; -+ fmt->code = ov2680_hv_flip_bayer_order[hv_flip]; - } - --static int ov2680_vflip_enable(struct ov2680_dev *sensor) -+static void ov2680_fill_format(struct ov2680_dev *sensor, -+ struct v4l2_mbus_framefmt *fmt, -+ unsigned int width, unsigned int height) - { -- int ret; -- -- ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(2)); -- if (ret < 0) -- return ret; -- -- return ov2680_bayer_order(sensor); -+ memset(fmt, 0, sizeof(*fmt)); -+ fmt->width = width; -+ fmt->height = height; -+ fmt->field = V4L2_FIELD_NONE; -+ fmt->colorspace = V4L2_COLORSPACE_SRGB; -+ ov2680_set_bayer_order(sensor, fmt); - } - --static int ov2680_vflip_disable(struct ov2680_dev *sensor) -+static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) - { - int ret; - -- ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(0)); -- if (ret < 0) -- return ret; -- -- return ov2680_bayer_order(sensor); --} -- --static int ov2680_hflip_enable(struct ov2680_dev *sensor) --{ -- int ret; -+ if (sensor->is_streaming) -+ return -EBUSY; - -- ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(2)); -+ ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, -+ BIT(2), val ? BIT(2) : 0); - if (ret < 0) - return ret; - -- return ov2680_bayer_order(sensor); -+ ov2680_set_bayer_order(sensor, &sensor->fmt); -+ return 0; - } - --static int ov2680_hflip_disable(struct ov2680_dev *sensor) -+static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) - { - int ret; - -- ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(0)); -+ if (sensor->is_streaming) -+ return -EBUSY; -+ -+ ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, -+ BIT(2), val ? BIT(2) : 0); - if (ret < 0) - return ret; - -- return ov2680_bayer_order(sensor); -+ ov2680_set_bayer_order(sensor, &sensor->fmt); -+ return 0; - } - - static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) -@@ -405,69 +394,15 @@ static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) - return 0; - } - --static int ov2680_gain_set(struct ov2680_dev *sensor, bool auto_gain) -+static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain) - { -- struct ov2680_ctrls *ctrls = &sensor->ctrls; -- u32 gain; -- int ret; -- -- ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1), -- auto_gain ? 0 : BIT(1)); -- if (ret < 0) -- return ret; -- -- if (auto_gain || !ctrls->gain->is_new) -- return 0; -- -- gain = ctrls->gain->val; -- -- ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); -- -- return 0; --} -- --static int ov2680_gain_get(struct ov2680_dev *sensor) --{ -- u32 gain; -- int ret; -- -- ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, &gain); -- if (ret) -- return ret; -- -- return gain; --} -- --static int ov2680_exposure_set(struct ov2680_dev *sensor, bool auto_exp) --{ -- struct ov2680_ctrls *ctrls = &sensor->ctrls; -- u32 exp; -- int ret; -- -- ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(0), -- auto_exp ? 0 : BIT(0)); -- if (ret < 0) -- return ret; -- -- if (auto_exp || !ctrls->exposure->is_new) -- return 0; -- -- exp = (u32)ctrls->exposure->val; -- exp <<= 4; -- -- return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, exp); -+ return ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); - } - --static int ov2680_exposure_get(struct ov2680_dev *sensor) -+static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) - { -- int ret; -- u32 exp; -- -- ret = ov2680_read_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, &exp); -- if (ret) -- return ret; -- -- return exp >> 4; -+ return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, -+ exp << 4); - } - - static int ov2680_stream_enable(struct ov2680_dev *sensor) -@@ -482,33 +417,17 @@ static int ov2680_stream_disable(struct ov2680_dev *sensor) - - static int ov2680_mode_set(struct ov2680_dev *sensor) - { -- struct ov2680_ctrls *ctrls = &sensor->ctrls; - int ret; - -- ret = ov2680_gain_set(sensor, false); -- if (ret < 0) -- return ret; -- -- ret = ov2680_exposure_set(sensor, false); -+ ret = ov2680_load_regs(sensor, sensor->current_mode); - if (ret < 0) - return ret; - -- ret = ov2680_load_regs(sensor, sensor->current_mode); -+ /* Restore value of all ctrls */ -+ ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); - if (ret < 0) - return ret; - -- if (ctrls->auto_gain->val) { -- ret = ov2680_gain_set(sensor, true); -- if (ret < 0) -- return ret; -- } -- -- if (ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO) { -- ret = ov2680_exposure_set(sensor, true); -- if (ret < 0) -- return ret; -- } -- - sensor->mode_pending_changes = false; - - return 0; -@@ -556,7 +475,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor) - ret = ov2680_write_reg(sensor, OV2680_REG_SOFT_RESET, 0x01); - if (ret != 0) { - dev_err(dev, "sensor soft reset failed\n"); -- return ret; -+ goto err_disable_regulators; - } - usleep_range(1000, 2000); - } else { -@@ -566,7 +485,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor) - - ret = clk_prepare_enable(sensor->xvclk); - if (ret < 0) -- return ret; -+ goto err_disable_regulators; - - sensor->is_enabled = true; - -@@ -576,6 +495,10 @@ static int ov2680_power_on(struct ov2680_dev *sensor) - ov2680_stream_disable(sensor); - - return 0; -+ -+err_disable_regulators: -+ regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies); -+ return ret; - } - - static int ov2680_s_power(struct v4l2_subdev *sd, int on) -@@ -590,15 +513,10 @@ static int ov2680_s_power(struct v4l2_subdev *sd, int on) - else - ret = ov2680_power_off(sensor); - -- mutex_unlock(&sensor->lock); -- -- if (on && ret == 0) { -- ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler); -- if (ret < 0) -- return ret; -- -+ if (on && ret == 0) - ret = ov2680_mode_restore(sensor); -- } -+ -+ mutex_unlock(&sensor->lock); - - return ret; - } -@@ -664,7 +582,6 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, - { - struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct v4l2_mbus_framefmt *fmt = NULL; -- int ret = 0; - - if (format->pad != 0) - return -EINVAL; -@@ -672,22 +589,17 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, - mutex_lock(&sensor->lock); - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, - format->pad); --#else -- ret = -EINVAL; --#endif - } else { - fmt = &sensor->fmt; - } - -- if (fmt) -- format->format = *fmt; -+ format->format = *fmt; - - mutex_unlock(&sensor->lock); - -- return ret; -+ return 0; - } - - static int ov2680_set_fmt(struct v4l2_subdev *sd, -@@ -695,43 +607,35 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_format *format) - { - struct ov2680_dev *sensor = to_ov2680_dev(sd); -- struct v4l2_mbus_framefmt *fmt = &format->format; --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - struct v4l2_mbus_framefmt *try_fmt; --#endif - const struct ov2680_mode_info *mode; - int ret = 0; - - if (format->pad != 0) - return -EINVAL; - -- mutex_lock(&sensor->lock); -- -- if (sensor->is_streaming) { -- ret = -EBUSY; -- goto unlock; -- } -- - mode = v4l2_find_nearest_size(ov2680_mode_data, -- ARRAY_SIZE(ov2680_mode_data), width, -- height, fmt->width, fmt->height); -- if (!mode) { -- ret = -EINVAL; -- goto unlock; -- } -+ ARRAY_SIZE(ov2680_mode_data), -+ width, height, -+ format->format.width, -+ format->format.height); -+ if (!mode) -+ return -EINVAL; -+ -+ ov2680_fill_format(sensor, &format->format, mode->width, mode->height); - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); -- format->format = *try_fmt; --#endif -- goto unlock; -+ *try_fmt = format->format; -+ return 0; - } - -- fmt->width = mode->width; -- fmt->height = mode->height; -- fmt->code = sensor->fmt.code; -- fmt->colorspace = sensor->fmt.colorspace; -+ mutex_lock(&sensor->lock); -+ -+ if (sensor->is_streaming) { -+ ret = -EBUSY; -+ goto unlock; -+ } - - sensor->current_mode = mode; - sensor->fmt = format->format; -@@ -746,16 +650,11 @@ unlock: - static int ov2680_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state) - { -- struct v4l2_subdev_format fmt = { -- .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY -- : V4L2_SUBDEV_FORMAT_ACTIVE, -- .format = { -- .width = 800, -- .height = 600, -- } -- }; -+ struct ov2680_dev *sensor = to_ov2680_dev(sd); - -- return ov2680_set_fmt(sd, sd_state, &fmt); -+ ov2680_fill_format(sensor, &sd_state->pads[0].try_fmt, -+ OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); -+ return 0; - } - - static int ov2680_enum_frame_size(struct v4l2_subdev *sd, -@@ -794,66 +693,23 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd, - return 0; - } - --static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl) --{ -- struct v4l2_subdev *sd = ctrl_to_sd(ctrl); -- struct ov2680_dev *sensor = to_ov2680_dev(sd); -- struct ov2680_ctrls *ctrls = &sensor->ctrls; -- int val; -- -- if (!sensor->is_enabled) -- return 0; -- -- switch (ctrl->id) { -- case V4L2_CID_GAIN: -- val = ov2680_gain_get(sensor); -- if (val < 0) -- return val; -- ctrls->gain->val = val; -- break; -- case V4L2_CID_EXPOSURE: -- val = ov2680_exposure_get(sensor); -- if (val < 0) -- return val; -- ctrls->exposure->val = val; -- break; -- } -- -- return 0; --} -- - static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) - { - struct v4l2_subdev *sd = ctrl_to_sd(ctrl); - struct ov2680_dev *sensor = to_ov2680_dev(sd); -- struct ov2680_ctrls *ctrls = &sensor->ctrls; - - if (!sensor->is_enabled) - return 0; - - switch (ctrl->id) { -- case V4L2_CID_AUTOGAIN: -- return ov2680_gain_set(sensor, !!ctrl->val); - case V4L2_CID_GAIN: -- return ov2680_gain_set(sensor, !!ctrls->auto_gain->val); -- case V4L2_CID_EXPOSURE_AUTO: -- return ov2680_exposure_set(sensor, !!ctrl->val); -+ return ov2680_gain_set(sensor, ctrl->val); - case V4L2_CID_EXPOSURE: -- return ov2680_exposure_set(sensor, !!ctrls->auto_exp->val); -+ return ov2680_exposure_set(sensor, ctrl->val); - case V4L2_CID_VFLIP: -- if (sensor->is_streaming) -- return -EBUSY; -- if (ctrl->val) -- return ov2680_vflip_enable(sensor); -- else -- return ov2680_vflip_disable(sensor); -+ return ov2680_set_vflip(sensor, ctrl->val); - case V4L2_CID_HFLIP: -- if (sensor->is_streaming) -- return -EBUSY; -- if (ctrl->val) -- return ov2680_hflip_enable(sensor); -- else -- return ov2680_hflip_disable(sensor); -+ return ov2680_set_hflip(sensor, ctrl->val); - case V4L2_CID_TEST_PATTERN: - return ov2680_test_pattern_set(sensor, ctrl->val); - default: -@@ -864,7 +720,6 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) - } - - static const struct v4l2_ctrl_ops ov2680_ctrl_ops = { -- .g_volatile_ctrl = ov2680_g_volatile_ctrl, - .s_ctrl = ov2680_s_ctrl, - }; - -@@ -898,11 +753,8 @@ static int ov2680_mode_init(struct ov2680_dev *sensor) - const struct ov2680_mode_info *init_mode; - - /* set initial mode */ -- sensor->fmt.code = MEDIA_BUS_FMT_SBGGR10_1X10; -- sensor->fmt.width = 800; -- sensor->fmt.height = 600; -- sensor->fmt.field = V4L2_FIELD_NONE; -- sensor->fmt.colorspace = V4L2_COLORSPACE_SRGB; -+ ov2680_fill_format(sensor, &sensor->fmt, -+ OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); - - sensor->frame_interval.denominator = OV2680_FRAME_RATE; - sensor->frame_interval.numerator = 1; -@@ -926,9 +778,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) - v4l2_i2c_subdev_init(&sensor->sd, sensor->i2c_client, - &ov2680_subdev_ops); - --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; --#endif - sensor->pad.flags = MEDIA_PAD_FL_SOURCE; - sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - -@@ -936,7 +786,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) - if (ret < 0) - return ret; - -- v4l2_ctrl_handler_init(hdl, 7); -+ v4l2_ctrl_handler_init(hdl, 5); - - hdl->lock = &sensor->lock; - -@@ -948,16 +798,9 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) - ARRAY_SIZE(test_pattern_menu) - 1, - 0, 0, test_pattern_menu); - -- ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops, -- V4L2_CID_EXPOSURE_AUTO, -- V4L2_EXPOSURE_MANUAL, 0, -- V4L2_EXPOSURE_AUTO); -- - ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, - 0, 32767, 1, 0); - -- ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, -- 0, 1, 1, 1); - ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 2047, 1, 0); - - if (hdl->error) { -@@ -965,11 +808,8 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) - goto cleanup_entity; - } - -- ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; -- ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; -- -- v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true); -- v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true); -+ ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; -+ ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - - sensor->sd.ctrl_handler = hdl; - -diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c -index 267f514023e72..2ee832426736d 100644 ---- a/drivers/media/i2c/ov5640.c -+++ b/drivers/media/i2c/ov5640.c -@@ -557,9 +557,7 @@ static const struct reg_value ov5640_init_setting[] = { - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0}, - {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0}, - {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0}, -- {0x501f, 0x00, 0, 0}, {0x4407, 0x04, 0, 0}, -- {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, -- {0x4837, 0x0a, 0, 0}, {0x3824, 0x02, 0, 0}, -+ {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x4837, 0x0a, 0, 0}, - {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, - {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, - {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, -@@ -623,7 +621,8 @@ static const struct reg_value ov5640_setting_low_res[] = { - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, -- {0x4407, 0x04, 0, 0}, {0x5001, 0xa3, 0, 0}, -+ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, -+ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, - }; - - static const struct reg_value ov5640_setting_720P_1280_720[] = { -@@ -2442,16 +2441,13 @@ static void ov5640_power(struct ov5640_dev *sensor, bool enable) - static void ov5640_powerup_sequence(struct ov5640_dev *sensor) - { - if (sensor->pwdn_gpio) { -- gpiod_set_value_cansleep(sensor->reset_gpio, 0); -+ gpiod_set_value_cansleep(sensor->reset_gpio, 1); - - /* camera power cycle */ - ov5640_power(sensor, false); -- usleep_range(5000, 10000); -+ usleep_range(5000, 10000); /* t2 */ - ov5640_power(sensor, true); -- usleep_range(5000, 10000); -- -- gpiod_set_value_cansleep(sensor->reset_gpio, 1); -- usleep_range(1000, 2000); -+ usleep_range(1000, 2000); /* t3 */ - - gpiod_set_value_cansleep(sensor->reset_gpio, 0); - } else { -@@ -2459,7 +2455,7 @@ static void ov5640_powerup_sequence(struct ov5640_dev *sensor) - ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, - OV5640_REG_SYS_CTRL0_SW_RST); - } -- usleep_range(20000, 25000); -+ usleep_range(20000, 25000); /* t4 */ - - /* - * software standby: allows registers programming; -@@ -2532,9 +2528,9 @@ static int ov5640_set_power_mipi(struct ov5640_dev *sensor, bool on) - * "ov5640_set_stream_mipi()") - * [4] = 0 : Power up MIPI HS Tx - * [3] = 0 : Power up MIPI LS Rx -- * [2] = 0 : MIPI interface disabled -+ * [2] = 1 : MIPI interface enabled - */ -- ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x40); -+ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x44); - if (ret) - return ret; - -diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c -index 9ccc56c30d3b0..d269c541ebe4c 100644 ---- a/drivers/media/i2c/rdacm21.c -+++ b/drivers/media/i2c/rdacm21.c -@@ -351,7 +351,7 @@ static void ov10640_power_up(struct rdacm21_device *dev) - static int ov10640_check_id(struct rdacm21_device *dev) - { - unsigned int i; -- u8 val; -+ u8 val = 0; - - /* Read OV10640 ID to test communications. */ - for (i = 0; i < OV10640_PID_TIMEOUT; ++i) { -diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c -index 859f1cb2fa744..84f87c016f9b5 100644 ---- a/drivers/media/i2c/tvp5150.c -+++ b/drivers/media/i2c/tvp5150.c -@@ -2068,6 +2068,10 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np) - tvpc->ent.name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", - v4l2c->name, v4l2c->label ? - v4l2c->label : ""); -+ if (!tvpc->ent.name) { -+ ret = -ENOMEM; -+ goto err_free; -+ } - } - - ep_np = of_graph_get_endpoint_by_regs(np, TVP5150_PAD_VID_OUT, 0); -diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c -index 3e52a51982d76..110651e478314 100644 ---- a/drivers/media/pci/bt8xx/dst.c -+++ b/drivers/media/pci/bt8xx/dst.c -@@ -1722,7 +1722,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad - return state; /* Manu (DST is a card not a frontend) */ - } - --EXPORT_SYMBOL(dst_attach); -+EXPORT_SYMBOL_GPL(dst_attach); - - static const struct dvb_frontend_ops dst_dvbt_ops = { - .delsys = { SYS_DVBT }, -diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c -index 85fcdc59f0d18..571392d80ccc6 100644 ---- a/drivers/media/pci/bt8xx/dst_ca.c -+++ b/drivers/media/pci/bt8xx/dst_ca.c -@@ -668,7 +668,7 @@ struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_ - return NULL; - } - --EXPORT_SYMBOL(dst_ca_attach); -+EXPORT_SYMBOL_GPL(dst_ca_attach); - - MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver"); - MODULE_AUTHOR("Manu Abraham"); -diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c -index 8fd5b6ef24282..7551ca4a322a4 100644 ---- a/drivers/media/pci/cx23885/cx23885-dvb.c -+++ b/drivers/media/pci/cx23885/cx23885-dvb.c -@@ -2459,16 +2459,10 @@ static int dvb_register(struct cx23885_tsport *port) - request_module("%s", info.type); - client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); - if (!i2c_client_has_driver(client_tuner)) { -- module_put(client_demod->dev.driver->owner); -- i2c_unregister_device(client_demod); -- port->i2c_client_demod = NULL; - goto frontend_detach; - } - if (!try_module_get(client_tuner->dev.driver->owner)) { - i2c_unregister_device(client_tuner); -- module_put(client_demod->dev.driver->owner); -- i2c_unregister_device(client_demod); -- port->i2c_client_demod = NULL; - goto frontend_detach; - } - port->i2c_client_tuner = client_tuner; -@@ -2505,16 +2499,10 @@ static int dvb_register(struct cx23885_tsport *port) - request_module("%s", info.type); - client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); - if (!i2c_client_has_driver(client_tuner)) { -- module_put(client_demod->dev.driver->owner); -- i2c_unregister_device(client_demod); -- port->i2c_client_demod = NULL; - goto frontend_detach; - } - if (!try_module_get(client_tuner->dev.driver->owner)) { - i2c_unregister_device(client_tuner); -- module_put(client_demod->dev.driver->owner); -- i2c_unregister_device(client_demod); -- port->i2c_client_demod = NULL; - goto frontend_detach; - } - port->i2c_client_tuner = client_tuner; -diff --git a/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c b/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c -index 6868a0c4fc82a..520ebd16b0c44 100644 ---- a/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c -+++ b/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c -@@ -112,7 +112,7 @@ struct dvb_frontend *ddbridge_dummy_fe_qam_attach(void) - state->frontend.demodulator_priv = state; - return &state->frontend; - } --EXPORT_SYMBOL(ddbridge_dummy_fe_qam_attach); -+EXPORT_SYMBOL_GPL(ddbridge_dummy_fe_qam_attach); - - static const struct dvb_frontend_ops ddbridge_dummy_fe_qam_ops = { - .delsys = { SYS_DVBC_ANNEX_A }, -diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c -index c08b5a2bfc1df..dc35a87e628ec 100644 ---- a/drivers/media/platform/amphion/vdec.c -+++ b/drivers/media/platform/amphion/vdec.c -@@ -249,7 +249,8 @@ static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, - vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE; - - if (inst->state != pre_state) -- vpu_trace(inst->dev, "[%d] %d -> %d\n", inst->id, pre_state, inst->state); -+ vpu_trace(inst->dev, "[%d] %s -> %s\n", inst->id, -+ vpu_codec_state_name(pre_state), vpu_codec_state_name(inst->state)); - - if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) - vdec_handle_resolution_change(inst); -@@ -956,6 +957,7 @@ static int vdec_response_frame_abnormal(struct vpu_inst *inst) - { - struct vdec_t *vdec = inst->priv; - struct vpu_fs_info info; -+ int ret; - - if (!vdec->req_frame_count) - return 0; -@@ -963,7 +965,9 @@ static int vdec_response_frame_abnormal(struct vpu_inst *inst) - memset(&info, 0, sizeof(info)); - info.type = MEM_RES_FRAME; - info.tag = vdec->seq_tag + 0xf0; -- vpu_session_alloc_fs(inst, &info); -+ ret = vpu_session_alloc_fs(inst, &info); -+ if (ret) -+ return ret; - vdec->req_frame_count--; - - return 0; -@@ -994,8 +998,8 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb - return -EINVAL; - } - -- dev_dbg(inst->dev, "[%d] state = %d, alloc fs %d, tag = 0x%x\n", -- inst->id, inst->state, vbuf->vb2_buf.index, vdec->seq_tag); -+ dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n", -+ inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag); - vpu_buf = to_vpu_vb2_buffer(vbuf); - - memset(&info, 0, sizeof(info)); -@@ -1354,7 +1358,7 @@ static void vdec_abort(struct vpu_inst *inst) - struct vpu_rpc_buffer_desc desc; - int ret; - -- vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state); -+ vpu_trace(inst->dev, "[%d] state = %s\n", inst->id, vpu_codec_state_name(inst->state)); - - vdec->aborting = true; - vpu_iface_add_scode(inst, SCODE_PADDING_ABORT); -@@ -1407,9 +1411,7 @@ static void vdec_release(struct vpu_inst *inst) - { - if (inst->id != VPU_INST_NULL_ID) - vpu_trace(inst->dev, "[%d]\n", inst->id); -- vpu_inst_lock(inst); - vdec_stop(inst, true); -- vpu_inst_unlock(inst); - } - - static void vdec_cleanup(struct vpu_inst *inst) -diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c -index e8cb22da938e6..1df2b35c1a240 100644 ---- a/drivers/media/platform/amphion/venc.c -+++ b/drivers/media/platform/amphion/venc.c -@@ -278,7 +278,7 @@ static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm - { - struct vpu_inst *inst = to_inst(file); - struct venc_t *venc = inst->priv; -- struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe; -+ struct v4l2_fract *timeperframe; - - if (!parm) - return -EINVAL; -@@ -289,6 +289,7 @@ static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm - if (!vpu_helper_check_type(inst, parm->type)) - return -EINVAL; - -+ timeperframe = &parm->parm.capture.timeperframe; - parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; - parm->parm.capture.readbuffers = 0; - timeperframe->numerator = venc->params.frame_rate.numerator; -@@ -301,7 +302,7 @@ static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm - { - struct vpu_inst *inst = to_inst(file); - struct venc_t *venc = inst->priv; -- struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe; -+ struct v4l2_fract *timeperframe; - unsigned long n, d; - - if (!parm) -@@ -313,6 +314,7 @@ static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm - if (!vpu_helper_check_type(inst, parm->type)) - return -EINVAL; - -+ timeperframe = &parm->parm.capture.timeperframe; - if (!timeperframe->numerator) - timeperframe->numerator = venc->params.frame_rate.numerator; - if (!timeperframe->denominator) -diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h -index 048c23c2bf4db..deb2288d42904 100644 ---- a/drivers/media/platform/amphion/vpu.h -+++ b/drivers/media/platform/amphion/vpu.h -@@ -353,6 +353,9 @@ void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow); - int vpu_core_driver_init(void); - void vpu_core_driver_exit(void); - -+const char *vpu_id_name(u32 id); -+const char *vpu_codec_state_name(enum vpu_codec_state state); -+ - extern bool debug; - #define vpu_trace(dev, fmt, arg...) \ - do { \ -diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c -index fa581ba6bab2d..235b71398d403 100644 ---- a/drivers/media/platform/amphion/vpu_cmds.c -+++ b/drivers/media/platform/amphion/vpu_cmds.c -@@ -98,7 +98,7 @@ static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data - cmd->id = id; - ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data); - if (ret) { -- dev_err(inst->dev, "iface pack cmd(%d) fail\n", id); -+ dev_err(inst->dev, "iface pack cmd %s fail\n", vpu_id_name(id)); - vfree(cmd->pkt); - vfree(cmd); - return NULL; -@@ -125,14 +125,14 @@ static int vpu_session_process_cmd(struct vpu_inst *inst, struct vpu_cmd_t *cmd) - { - int ret; - -- dev_dbg(inst->dev, "[%d]send cmd(0x%x)\n", inst->id, cmd->id); -+ dev_dbg(inst->dev, "[%d]send cmd %s\n", inst->id, vpu_id_name(cmd->id)); - vpu_iface_pre_send_cmd(inst); - ret = vpu_cmd_send(inst->core, cmd->pkt); - if (!ret) { - vpu_iface_post_send_cmd(inst); - vpu_inst_record_flow(inst, cmd->id); - } else { -- dev_err(inst->dev, "[%d] iface send cmd(0x%x) fail\n", inst->id, cmd->id); -+ dev_err(inst->dev, "[%d] iface send cmd %s fail\n", inst->id, vpu_id_name(cmd->id)); - } - - return ret; -@@ -149,7 +149,8 @@ static void vpu_process_cmd_request(struct vpu_inst *inst) - list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) { - list_del_init(&cmd->list); - if (vpu_session_process_cmd(inst, cmd)) -- dev_err(inst->dev, "[%d] process cmd(%d) fail\n", inst->id, cmd->id); -+ dev_err(inst->dev, "[%d] process cmd %s fail\n", -+ inst->id, vpu_id_name(cmd->id)); - if (cmd->request) { - inst->pending = (void *)cmd; - break; -@@ -305,7 +306,8 @@ static void vpu_core_keep_active(struct vpu_core *core) - - dev_dbg(core->dev, "try to wake up\n"); - mutex_lock(&core->cmd_lock); -- vpu_cmd_send(core, &pkt); -+ if (vpu_cmd_send(core, &pkt)) -+ dev_err(core->dev, "fail to keep active\n"); - mutex_unlock(&core->cmd_lock); - } - -@@ -313,7 +315,7 @@ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data) - { - unsigned long key; - int sync = false; -- int ret = -EINVAL; -+ int ret; - - if (inst->id < 0) - return -EINVAL; -@@ -339,7 +341,7 @@ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data) - - exit: - if (ret) -- dev_err(inst->dev, "[%d] send cmd(0x%x) fail\n", inst->id, id); -+ dev_err(inst->dev, "[%d] send cmd %s fail\n", inst->id, vpu_id_name(id)); - - return ret; - } -diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c -index be80410682681..9add73b9b45f9 100644 ---- a/drivers/media/platform/amphion/vpu_core.c -+++ b/drivers/media/platform/amphion/vpu_core.c -@@ -88,6 +88,8 @@ static int vpu_core_boot_done(struct vpu_core *core) - - core->supported_instance_count = min(core->supported_instance_count, count); - } -+ if (core->supported_instance_count >= BITS_PER_TYPE(core->instance_mask)) -+ core->supported_instance_count = BITS_PER_TYPE(core->instance_mask); - core->fw_version = fw_version; - vpu_core_set_state(core, VPU_CORE_ACTIVE); - -diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c -index 260f1c4b8f8dc..f105da82d92f9 100644 ---- a/drivers/media/platform/amphion/vpu_dbg.c -+++ b/drivers/media/platform/amphion/vpu_dbg.c -@@ -50,6 +50,13 @@ static char *vpu_stat_name[] = { - [VPU_BUF_STATE_ERROR] = "error", - }; - -+static inline const char *to_vpu_stat_name(int state) -+{ -+ if (state <= VPU_BUF_STATE_ERROR) -+ return vpu_stat_name[state]; -+ return "unknown"; -+} -+ - static int vpu_dbg_instance(struct seq_file *s, void *data) - { - struct vpu_inst *inst = s->private; -@@ -67,7 +74,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) - num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid); - if (seq_write(s, str, num)) - return 0; -- num = scnprintf(str, sizeof(str), "state = %d\n", inst->state); -+ num = scnprintf(str, sizeof(str), "state = %s\n", vpu_codec_state_name(inst->state)); - if (seq_write(s, str, num)) - return 0; - num = scnprintf(str, sizeof(str), -@@ -141,7 +148,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) - num = scnprintf(str, sizeof(str), - "output [%2d] state = %10s, %8s\n", - i, vb2_stat_name[vb->state], -- vpu_stat_name[vpu_get_buffer_state(vbuf)]); -+ to_vpu_stat_name(vpu_get_buffer_state(vbuf))); - if (seq_write(s, str, num)) - return 0; - } -@@ -156,7 +163,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) - num = scnprintf(str, sizeof(str), - "capture[%2d] state = %10s, %8s\n", - i, vb2_stat_name[vb->state], -- vpu_stat_name[vpu_get_buffer_state(vbuf)]); -+ to_vpu_stat_name(vpu_get_buffer_state(vbuf))); - if (seq_write(s, str, num)) - return 0; - } -@@ -188,9 +195,9 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) - - if (!inst->flows[idx]) - continue; -- num = scnprintf(str, sizeof(str), "\t[%s]0x%x\n", -+ num = scnprintf(str, sizeof(str), "\t[%s] %s\n", - inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C", -- inst->flows[idx]); -+ vpu_id_name(inst->flows[idx])); - if (seq_write(s, str, num)) { - mutex_unlock(&inst->core->cmd_lock); - return 0; -diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c -index e9aeb3453dfcb..2e78666322f02 100644 ---- a/drivers/media/platform/amphion/vpu_helpers.c -+++ b/drivers/media/platform/amphion/vpu_helpers.c -@@ -11,6 +11,7 @@ - #include - #include - #include "vpu.h" -+#include "vpu_defs.h" - #include "vpu_core.h" - #include "vpu_rpc.h" - #include "vpu_helpers.h" -@@ -412,3 +413,63 @@ int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst) - - return -EINVAL; - } -+ -+const char *vpu_id_name(u32 id) -+{ -+ switch (id) { -+ case VPU_CMD_ID_NOOP: return "noop"; -+ case VPU_CMD_ID_CONFIGURE_CODEC: return "configure codec"; -+ case VPU_CMD_ID_START: return "start"; -+ case VPU_CMD_ID_STOP: return "stop"; -+ case VPU_CMD_ID_ABORT: return "abort"; -+ case VPU_CMD_ID_RST_BUF: return "reset buf"; -+ case VPU_CMD_ID_SNAPSHOT: return "snapshot"; -+ case VPU_CMD_ID_FIRM_RESET: return "reset firmware"; -+ case VPU_CMD_ID_UPDATE_PARAMETER: return "update parameter"; -+ case VPU_CMD_ID_FRAME_ENCODE: return "encode frame"; -+ case VPU_CMD_ID_SKIP: return "skip"; -+ case VPU_CMD_ID_FS_ALLOC: return "alloc fb"; -+ case VPU_CMD_ID_FS_RELEASE: return "release fb"; -+ case VPU_CMD_ID_TIMESTAMP: return "timestamp"; -+ case VPU_CMD_ID_DEBUG: return "debug"; -+ case VPU_MSG_ID_RESET_DONE: return "reset done"; -+ case VPU_MSG_ID_START_DONE: return "start done"; -+ case VPU_MSG_ID_STOP_DONE: return "stop done"; -+ case VPU_MSG_ID_ABORT_DONE: return "abort done"; -+ case VPU_MSG_ID_BUF_RST: return "buf reset done"; -+ case VPU_MSG_ID_MEM_REQUEST: return "mem request"; -+ case VPU_MSG_ID_PARAM_UPD_DONE: return "param upd done"; -+ case VPU_MSG_ID_FRAME_INPUT_DONE: return "frame input done"; -+ case VPU_MSG_ID_ENC_DONE: return "encode done"; -+ case VPU_MSG_ID_DEC_DONE: return "frame display"; -+ case VPU_MSG_ID_FRAME_REQ: return "fb request"; -+ case VPU_MSG_ID_FRAME_RELEASE: return "fb release"; -+ case VPU_MSG_ID_SEQ_HDR_FOUND: return "seq hdr found"; -+ case VPU_MSG_ID_RES_CHANGE: return "resolution change"; -+ case VPU_MSG_ID_PIC_HDR_FOUND: return "pic hdr found"; -+ case VPU_MSG_ID_PIC_DECODED: return "picture decoded"; -+ case VPU_MSG_ID_PIC_EOS: return "eos"; -+ case VPU_MSG_ID_FIFO_LOW: return "fifo low"; -+ case VPU_MSG_ID_BS_ERROR: return "bs error"; -+ case VPU_MSG_ID_UNSUPPORTED: return "unsupported"; -+ case VPU_MSG_ID_FIRMWARE_XCPT: return "exception"; -+ case VPU_MSG_ID_PIC_SKIPPED: return "skipped"; -+ } -+ return ""; -+} -+ -+const char *vpu_codec_state_name(enum vpu_codec_state state) -+{ -+ switch (state) { -+ case VPU_CODEC_STATE_DEINIT: return "initialization"; -+ case VPU_CODEC_STATE_CONFIGURED: return "configured"; -+ case VPU_CODEC_STATE_START: return "start"; -+ case VPU_CODEC_STATE_STARTED: return "started"; -+ case VPU_CODEC_STATE_ACTIVE: return "active"; -+ case VPU_CODEC_STATE_SEEK: return "seek"; -+ case VPU_CODEC_STATE_STOP: return "stop"; -+ case VPU_CODEC_STATE_DRAIN: return "drain"; -+ case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE: return "resolution change"; -+ } -+ return ""; -+} -diff --git a/drivers/media/platform/amphion/vpu_mbox.c b/drivers/media/platform/amphion/vpu_mbox.c -index bf759eb2fd46d..b6d5b4844f672 100644 ---- a/drivers/media/platform/amphion/vpu_mbox.c -+++ b/drivers/media/platform/amphion/vpu_mbox.c -@@ -46,11 +46,10 @@ static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox) - cl->rx_callback = vpu_mbox_rx_callback; - - ch = mbox_request_channel_byname(cl, mbox->name); -- if (IS_ERR(ch)) { -- dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n", -- mbox->name, PTR_ERR(ch)); -- return PTR_ERR(ch); -- } -+ if (IS_ERR(ch)) -+ return dev_err_probe(dev, PTR_ERR(ch), -+ "Failed to request mbox chan %s\n", -+ mbox->name); - - mbox->ch = ch; - return 0; -diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c -index 92672a802b492..d0ead051f7d18 100644 ---- a/drivers/media/platform/amphion/vpu_msgs.c -+++ b/drivers/media/platform/amphion/vpu_msgs.c -@@ -32,7 +32,7 @@ static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_ - - static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt) - { -- struct vpu_pkt_mem_req_data req_data; -+ struct vpu_pkt_mem_req_data req_data = { 0 }; - - vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data); - vpu_trace(inst->dev, "[%d] %d:%d %d:%d %d:%d\n", -@@ -80,7 +80,7 @@ static void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct v - - static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) - { -- struct vpu_enc_pic_info info; -+ struct vpu_enc_pic_info info = { 0 }; - - vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); - dev_dbg(inst->dev, "[%d] frame id = %d, wptr = 0x%x, size = %d\n", -@@ -90,7 +90,7 @@ static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_ - - static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt) - { -- struct vpu_fs_info fs; -+ struct vpu_fs_info fs = { 0 }; - - vpu_iface_unpack_msg_data(inst->core, pkt, &fs); - call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs); -@@ -107,7 +107,7 @@ static void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_r - info.type = inst->out_format.type; - call_void_vop(inst, buf_done, &info); - } else if (inst->core->type == VPU_CORE_TYPE_DEC) { -- struct vpu_fs_info fs; -+ struct vpu_fs_info fs = { 0 }; - - vpu_iface_unpack_msg_data(inst->core, pkt, &fs); - call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs); -@@ -122,7 +122,7 @@ static void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_ - - static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt) - { -- struct vpu_dec_pic_info info; -+ struct vpu_dec_pic_info info = { 0 }; - - vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); - call_void_vop(inst, get_one_frame, &info); -@@ -130,7 +130,7 @@ static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc - - static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) - { -- struct vpu_dec_pic_info info; -+ struct vpu_dec_pic_info info = { 0 }; - struct vpu_frame_info frame; - - memset(&frame, 0, sizeof(frame)); -@@ -210,7 +210,7 @@ static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *m - return -EINVAL; - - msg_id = ret; -- dev_dbg(inst->dev, "[%d] receive event(0x%x)\n", inst->id, msg_id); -+ dev_dbg(inst->dev, "[%d] receive event(%s)\n", inst->id, vpu_id_name(msg_id)); - - for (i = 0; i < ARRAY_SIZE(handlers); i++) { - if (handlers[i].id == msg_id) { -diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c -index a74953191c221..e5c8e1a753ccd 100644 ---- a/drivers/media/platform/amphion/vpu_v4l2.c -+++ b/drivers/media/platform/amphion/vpu_v4l2.c -@@ -404,6 +404,11 @@ static int vpu_vb2_queue_setup(struct vb2_queue *vq, - for (i = 0; i < cur_fmt->num_planes; i++) - psize[i] = cur_fmt->sizeimage[i]; - -+ if (V4L2_TYPE_IS_OUTPUT(vq->type) && inst->state == VPU_CODEC_STATE_SEEK) { -+ vpu_trace(inst->dev, "reinit when VIDIOC_REQBUFS(OUTPUT, 0)\n"); -+ call_void_vop(inst, release); -+ } -+ - return 0; - } - -@@ -688,9 +693,9 @@ int vpu_v4l2_close(struct file *file) - v4l2_m2m_ctx_release(inst->fh.m2m_ctx); - inst->fh.m2m_ctx = NULL; - } -+ call_void_vop(inst, release); - vpu_inst_unlock(inst); - -- call_void_vop(inst, release); - vpu_inst_unregister(inst); - vpu_inst_put(inst); - -diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c -index 3071b61946c3b..e9a4f8abd21c5 100644 ---- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c -+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c -@@ -1412,6 +1412,7 @@ static int mtk_jpeg_remove(struct platform_device *pdev) - { - struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev); - -+ cancel_delayed_work_sync(&jpeg->job_timeout_work); - pm_runtime_disable(&pdev->dev); - video_unregister_device(jpeg->vdev); - v4l2_m2m_release(jpeg->m2m_dev); -diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c -index 70b8383f7c8ec..a27a109d8d144 100644 ---- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c -+++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c -@@ -226,10 +226,11 @@ static struct vdec_fb *vp9_rm_from_fb_use_list(struct vdec_vp9_inst - if (fb->base_y.va == addr) { - list_move_tail(&node->list, - &inst->available_fb_node_list); -- break; -+ return fb; - } - } -- return fb; -+ -+ return NULL; - } - - static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst, -diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c -index 03f8d7cd8eddc..a81212c0ade9d 100644 ---- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c -+++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c -@@ -246,6 +246,7 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, - mtk_vcodec_mem_free(ctx, mem); - - kfree(lat_buf->private_data); -+ lat_buf->private_data = NULL; - } - } - -@@ -312,6 +313,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue, - err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr); - if (err) { - mtk_v4l2_err("failed to allocate wdma_addr buf"); -+ msg_queue->wdma_addr.size = 0; - return -ENOMEM; - } - msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr; -diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c -index 2ad40b3945b0b..8fc8f46dc3908 100644 ---- a/drivers/media/platform/qcom/venus/hfi_venus.c -+++ b/drivers/media/platform/qcom/venus/hfi_venus.c -@@ -131,7 +131,6 @@ struct venus_hfi_device { - - static bool venus_pkt_debug; - int venus_fw_debug = HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL; --static bool venus_sys_idle_indicator; - static bool venus_fw_low_power_mode = true; - static int venus_hw_rsp_timeout = 1000; - static bool venus_fw_coverage; -@@ -454,7 +453,6 @@ static int venus_boot_core(struct venus_hfi_device *hdev) - void __iomem *wrapper_base = hdev->core->wrapper_base; - int ret = 0; - -- writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT); - if (IS_V6(hdev->core)) { - mask_val = readl(wrapper_base + WRAPPER_INTR_MASK); - mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BASK_V6 | -@@ -465,6 +463,7 @@ static int venus_boot_core(struct venus_hfi_device *hdev) - writel(mask_val, wrapper_base + WRAPPER_INTR_MASK); - writel(1, cpu_cs_base + CPU_CS_SCIACMDARG3); - -+ writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT); - while (!ctrl_status && count < max_tries) { - ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0); - if ((ctrl_status & CPU_CS_SCIACMDARG0_ERROR_STATUS_MASK) == 4) { -@@ -947,17 +946,12 @@ static int venus_sys_set_default_properties(struct venus_hfi_device *hdev) - if (ret) - dev_warn(dev, "setting fw debug msg ON failed (%d)\n", ret); - -- /* -- * Idle indicator is disabled by default on some 4xx firmware versions, -- * enable it explicitly in order to make suspend functional by checking -- * WFI (wait-for-interrupt) bit. -- */ -- if (IS_V4(hdev->core) || IS_V6(hdev->core)) -- venus_sys_idle_indicator = true; -- -- ret = venus_sys_set_idle_message(hdev, venus_sys_idle_indicator); -- if (ret) -- dev_warn(dev, "setting idle response ON failed (%d)\n", ret); -+ /* HFI_PROPERTY_SYS_IDLE_INDICATOR is not supported beyond 8916 (HFI V1) */ -+ if (IS_V1(hdev->core)) { -+ ret = venus_sys_set_idle_message(hdev, false); -+ if (ret) -+ dev_warn(dev, "setting idle response ON failed (%d)\n", ret); -+ } - - ret = venus_sys_set_power_control(hdev, venus_fw_low_power_mode); - if (ret) -diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c -index eaa3bbc903d7e..3d3b54be29557 100644 ---- a/drivers/media/tuners/fc0011.c -+++ b/drivers/media/tuners/fc0011.c -@@ -499,7 +499,7 @@ struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(fc0011_attach); -+EXPORT_SYMBOL_GPL(fc0011_attach); - - MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver"); - MODULE_AUTHOR("Michael Buesch "); -diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c -index 4429d5e8c5796..81e65acbdb170 100644 ---- a/drivers/media/tuners/fc0012.c -+++ b/drivers/media/tuners/fc0012.c -@@ -495,7 +495,7 @@ err: - - return fe; - } --EXPORT_SYMBOL(fc0012_attach); -+EXPORT_SYMBOL_GPL(fc0012_attach); - - MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver"); - MODULE_AUTHOR("Hans-Frieder Vogt "); -diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c -index 29dd9b55ff333..1006a2798eefc 100644 ---- a/drivers/media/tuners/fc0013.c -+++ b/drivers/media/tuners/fc0013.c -@@ -608,7 +608,7 @@ struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(fc0013_attach); -+EXPORT_SYMBOL_GPL(fc0013_attach); - - MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver"); - MODULE_AUTHOR("Hans-Frieder Vogt "); -diff --git a/drivers/media/tuners/max2165.c b/drivers/media/tuners/max2165.c -index 1c746bed51fee..1575ab94e1c8b 100644 ---- a/drivers/media/tuners/max2165.c -+++ b/drivers/media/tuners/max2165.c -@@ -410,7 +410,7 @@ struct dvb_frontend *max2165_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(max2165_attach); -+EXPORT_SYMBOL_GPL(max2165_attach); - - MODULE_AUTHOR("David T. L. Wong "); - MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver"); -diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c -index 0c9161516abdf..ed8bdf7ebd99d 100644 ---- a/drivers/media/tuners/mc44s803.c -+++ b/drivers/media/tuners/mc44s803.c -@@ -356,7 +356,7 @@ error: - kfree(priv); - return NULL; - } --EXPORT_SYMBOL(mc44s803_attach); -+EXPORT_SYMBOL_GPL(mc44s803_attach); - - MODULE_AUTHOR("Jochen Friedrich"); - MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver"); -diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c -index 322c806228a5a..da7e23c2689b8 100644 ---- a/drivers/media/tuners/mt2060.c -+++ b/drivers/media/tuners/mt2060.c -@@ -440,7 +440,7 @@ struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter - - return fe; - } --EXPORT_SYMBOL(mt2060_attach); -+EXPORT_SYMBOL_GPL(mt2060_attach); - - static int mt2060_probe(struct i2c_client *client, - const struct i2c_device_id *id) -diff --git a/drivers/media/tuners/mt2131.c b/drivers/media/tuners/mt2131.c -index 37f50ff6c0bd2..eebc060883414 100644 ---- a/drivers/media/tuners/mt2131.c -+++ b/drivers/media/tuners/mt2131.c -@@ -274,7 +274,7 @@ struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe, - fe->tuner_priv = priv; - return fe; - } --EXPORT_SYMBOL(mt2131_attach); -+EXPORT_SYMBOL_GPL(mt2131_attach); - - MODULE_AUTHOR("Steven Toth"); - MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver"); -diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c -index 6136f20fa9b7f..2e92885a6bcb9 100644 ---- a/drivers/media/tuners/mt2266.c -+++ b/drivers/media/tuners/mt2266.c -@@ -336,7 +336,7 @@ struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter - mt2266_calibrate(priv); - return fe; - } --EXPORT_SYMBOL(mt2266_attach); -+EXPORT_SYMBOL_GPL(mt2266_attach); - - MODULE_AUTHOR("Olivier DANET"); - MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver"); -diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c -index ab4c43df9d180..2a8b0ea5d0cd3 100644 ---- a/drivers/media/tuners/mxl5005s.c -+++ b/drivers/media/tuners/mxl5005s.c -@@ -4116,7 +4116,7 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, - fe->tuner_priv = state; - return fe; - } --EXPORT_SYMBOL(mxl5005s_attach); -+EXPORT_SYMBOL_GPL(mxl5005s_attach); - - MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver"); - MODULE_AUTHOR("Steven Toth"); -diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c -index 3853a3d43d4f2..60931367b82ca 100644 ---- a/drivers/media/tuners/qt1010.c -+++ b/drivers/media/tuners/qt1010.c -@@ -440,7 +440,7 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, - fe->tuner_priv = priv; - return fe; - } --EXPORT_SYMBOL(qt1010_attach); -+EXPORT_SYMBOL_GPL(qt1010_attach); - - MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver"); - MODULE_AUTHOR("Antti Palosaari "); -diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c -index 4ed94646116fa..7d8d84dcb2459 100644 ---- a/drivers/media/tuners/tda18218.c -+++ b/drivers/media/tuners/tda18218.c -@@ -336,7 +336,7 @@ struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, - - return fe; - } --EXPORT_SYMBOL(tda18218_attach); -+EXPORT_SYMBOL_GPL(tda18218_attach); - - MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver"); - MODULE_AUTHOR("Antti Palosaari "); -diff --git a/drivers/media/tuners/xc2028.c b/drivers/media/tuners/xc2028.c -index 69c2e1b99bf17..5a967edceca93 100644 ---- a/drivers/media/tuners/xc2028.c -+++ b/drivers/media/tuners/xc2028.c -@@ -1512,7 +1512,7 @@ fail: - return NULL; - } - --EXPORT_SYMBOL(xc2028_attach); -+EXPORT_SYMBOL_GPL(xc2028_attach); - - MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver"); - MODULE_AUTHOR("Michel Ludwig "); -diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c -index d59b4ab774302..57ded9ff3f043 100644 ---- a/drivers/media/tuners/xc4000.c -+++ b/drivers/media/tuners/xc4000.c -@@ -1742,7 +1742,7 @@ fail2: - xc4000_release(fe); - return NULL; - } --EXPORT_SYMBOL(xc4000_attach); -+EXPORT_SYMBOL_GPL(xc4000_attach); - - MODULE_AUTHOR("Steven Toth, Davide Ferri"); - MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver"); -diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c -index 7b7d9fe4f9453..2182e5b7b6064 100644 ---- a/drivers/media/tuners/xc5000.c -+++ b/drivers/media/tuners/xc5000.c -@@ -1460,7 +1460,7 @@ fail: - xc5000_release(fe); - return NULL; - } --EXPORT_SYMBOL(xc5000_attach); -+EXPORT_SYMBOL_GPL(xc5000_attach); - - MODULE_AUTHOR("Steven Toth"); - MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver"); -diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c -index 548199cd86f60..11f4f0455f155 100644 ---- a/drivers/media/usb/dvb-usb/m920x.c -+++ b/drivers/media/usb/dvb-usb/m920x.c -@@ -277,7 +277,6 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu - char *read = kmalloc(1, GFP_KERNEL); - if (!read) { - ret = -ENOMEM; -- kfree(read); - goto unlock; - } - -@@ -288,8 +287,10 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu - - if ((ret = m920x_read(d->udev, M9206_I2C, 0x0, - 0x20 | stop, -- read, 1)) != 0) -+ read, 1)) != 0) { -+ kfree(read); - goto unlock; -+ } - msg[i].buf[j] = read[0]; - } - -diff --git a/drivers/media/usb/go7007/go7007-i2c.c b/drivers/media/usb/go7007/go7007-i2c.c -index 38339dd2f83f7..2880370e45c8b 100644 ---- a/drivers/media/usb/go7007/go7007-i2c.c -+++ b/drivers/media/usb/go7007/go7007-i2c.c -@@ -165,8 +165,6 @@ static int go7007_i2c_master_xfer(struct i2c_adapter *adapter, - } else if (msgs[i].len == 3) { - if (msgs[i].flags & I2C_M_RD) - return -EIO; -- if (msgs[i].len != 3) -- return -EIO; - if (go7007_i2c_xfer(go, msgs[i].addr, 0, - (msgs[i].buf[0] << 8) | msgs[i].buf[1], - 0x01, &msgs[i].buf[2]) < 0) -diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c -index 640737d3b8aeb..8a39cac76c585 100644 ---- a/drivers/media/usb/siano/smsusb.c -+++ b/drivers/media/usb/siano/smsusb.c -@@ -455,12 +455,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) - rc = smscore_register_device(¶ms, &dev->coredev, 0, mdev); - if (rc < 0) { - pr_err("smscore_register_device(...) failed, rc %d\n", rc); -- smsusb_term_device(intf); --#ifdef CONFIG_MEDIA_CONTROLLER_DVB -- media_device_unregister(mdev); --#endif -- kfree(mdev); -- return rc; -+ goto err_unregister_device; - } - - smscore_set_board_id(dev->coredev, board_id); -@@ -477,8 +472,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) - rc = smsusb_start_streaming(dev); - if (rc < 0) { - pr_err("smsusb_start_streaming(...) failed\n"); -- smsusb_term_device(intf); -- return rc; -+ goto err_unregister_device; - } - - dev->state = SMSUSB_ACTIVE; -@@ -486,13 +480,20 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) - rc = smscore_start_device(dev->coredev); - if (rc < 0) { - pr_err("smscore_start_device(...) failed\n"); -- smsusb_term_device(intf); -- return rc; -+ goto err_unregister_device; - } - - pr_debug("device 0x%p created\n", dev); - - return rc; -+ -+err_unregister_device: -+ smsusb_term_device(intf); -+#ifdef CONFIG_MEDIA_CONTROLLER_DVB -+ media_device_unregister(mdev); -+#endif -+ kfree(mdev); -+ return rc; - } - - static int smsusb_probe(struct usb_interface *intf, -diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c -index 3d85a8600f576..69c8b3b656860 100644 ---- a/drivers/media/v4l2-core/v4l2-fwnode.c -+++ b/drivers/media/v4l2-core/v4l2-fwnode.c -@@ -551,19 +551,29 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode, - link->local_id = fwep.id; - link->local_port = fwep.port; - link->local_node = fwnode_graph_get_port_parent(fwnode); -+ if (!link->local_node) -+ return -ENOLINK; - - fwnode = fwnode_graph_get_remote_endpoint(fwnode); -- if (!fwnode) { -- fwnode_handle_put(fwnode); -- return -ENOLINK; -- } -+ if (!fwnode) -+ goto err_put_local_node; - - fwnode_graph_parse_endpoint(fwnode, &fwep); - link->remote_id = fwep.id; - link->remote_port = fwep.port; - link->remote_node = fwnode_graph_get_port_parent(fwnode); -+ if (!link->remote_node) -+ goto err_put_remote_endpoint; - - return 0; -+ -+err_put_remote_endpoint: -+ fwnode_handle_put(fwnode); -+ -+err_put_local_node: -+ fwnode_handle_put(link->local_node); -+ -+ return -ENOLINK; - } - EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link); - -diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c -index e38d0e8b8e0ed..7572c5714b469 100644 ---- a/drivers/mmc/host/renesas_sdhi_core.c -+++ b/drivers/mmc/host/renesas_sdhi_core.c -@@ -1006,6 +1006,8 @@ int renesas_sdhi_probe(struct platform_device *pdev, - host->sdcard_irq_setbit_mask = TMIO_STAT_ALWAYS_SET_27; - host->sdcard_irq_mask_all = TMIO_MASK_ALL_RCAR2; - host->reset = renesas_sdhi_reset; -+ } else { -+ host->sdcard_irq_mask_all = TMIO_MASK_ALL; - } - - /* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */ -@@ -1102,9 +1104,7 @@ int renesas_sdhi_probe(struct platform_device *pdev, - host->ops.hs400_complete = renesas_sdhi_hs400_complete; - } - -- ret = tmio_mmc_host_probe(host); -- if (ret < 0) -- goto edisclk; -+ sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask_all); - - num_irqs = platform_irq_count(pdev); - if (num_irqs < 0) { -@@ -1131,6 +1131,10 @@ int renesas_sdhi_probe(struct platform_device *pdev, - goto eirq; - } - -+ ret = tmio_mmc_host_probe(host); -+ if (ret < 0) -+ goto edisclk; -+ - dev_info(&pdev->dev, "%s base at %pa, max clock rate %u MHz\n", - mmc_hostname(host->mmc), &res->start, host->mmc->f_max / 1000000); - -diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -index 2e9c2e2d9c9f7..d8418d7fcc372 100644 ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -2612,6 +2612,8 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) - struct nand_chip *chip = &host->chip; - const struct nand_ecc_props *requirements = - nanddev_get_ecc_requirements(&chip->base); -+ struct nand_memory_organization *memorg = -+ nanddev_get_memorg(&chip->base); - struct brcmnand_controller *ctrl = host->ctrl; - struct brcmnand_cfg *cfg = &host->hwcfg; - char msg[128]; -@@ -2633,10 +2635,11 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) - if (cfg->spare_area_size > ctrl->max_oob) - cfg->spare_area_size = ctrl->max_oob; - /* -- * Set oobsize to be consistent with controller's spare_area_size, as -- * the rest is inaccessible. -+ * Set mtd and memorg oobsize to be consistent with controller's -+ * spare_area_size, as the rest is inaccessible. - */ - mtd->oobsize = cfg->spare_area_size * (mtd->writesize >> FC_SHIFT); -+ memorg->oobsize = mtd->oobsize; - - cfg->device_size = mtd->size; - cfg->block_size = mtd->erasesize; -diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c -index 6b2bda815b880..17786e1331e6d 100644 ---- a/drivers/mtd/nand/raw/fsmc_nand.c -+++ b/drivers/mtd/nand/raw/fsmc_nand.c -@@ -1202,9 +1202,14 @@ static int fsmc_nand_suspend(struct device *dev) - static int fsmc_nand_resume(struct device *dev) - { - struct fsmc_nand_data *host = dev_get_drvdata(dev); -+ int ret; - - if (host) { -- clk_prepare_enable(host->clk); -+ ret = clk_prepare_enable(host->clk); -+ if (ret) { -+ dev_err(dev, "failed to enable clk\n"); -+ return ret; -+ } - if (host->dev_timings) - fsmc_nand_setup(host, host->dev_timings); - nand_reset(&host->nand, 0); -diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c -index dc4d86ceee447..a9000b0ebe690 100644 ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -770,21 +770,22 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1) - ret = spi_nor_read_cr(nor, &sr_cr[1]); - if (ret) - return ret; -- } else if (nor->params->quad_enable) { -+ } else if (spi_nor_get_protocol_width(nor->read_proto) == 4 && -+ spi_nor_get_protocol_width(nor->write_proto) == 4 && -+ nor->params->quad_enable) { - /* - * If the Status Register 2 Read command (35h) is not - * supported, we should at least be sure we don't - * change the value of the SR2 Quad Enable bit. - * -- * We can safely assume that when the Quad Enable method is -- * set, the value of the QE bit is one, as a consequence of the -- * nor->params->quad_enable() call. -+ * When the Quad Enable method is set and the buswidth is 4, we -+ * can safely assume that the value of the QE bit is one, as a -+ * consequence of the nor->params->quad_enable() call. - * -- * We can safely assume that the Quad Enable bit is present in -- * the Status Register 2 at BIT(1). According to the JESD216 -- * revB standard, BFPT DWORDS[15], bits 22:20, the 16-bit -- * Write Status (01h) command is available just for the cases -- * in which the QE bit is described in SR2 at BIT(1). -+ * According to the JESD216 revB standard, BFPT DWORDS[15], -+ * bits 22:20, the 16-bit Write Status (01h) command is -+ * available just for the cases in which the QE bit is -+ * described in SR2 at BIT(1). - */ - sr_cr[1] = SR2_QUAD_EN_BIT1; - } else { -diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c -index 1bad1866ae462..a48220f91a2df 100644 ---- a/drivers/net/arcnet/arcnet.c -+++ b/drivers/net/arcnet/arcnet.c -@@ -468,7 +468,7 @@ static void arcnet_reply_tasklet(struct tasklet_struct *t) - - ret = sock_queue_err_skb(sk, ackskb); - if (ret) -- kfree_skb(ackskb); -+ dev_kfree_skb_irq(ackskb); - - local_irq_enable(); - }; -diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c -index 5858cbafbc965..264a0f764e011 100644 ---- a/drivers/net/can/usb/gs_usb.c -+++ b/drivers/net/can/usb/gs_usb.c -@@ -626,6 +626,9 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) - } - - if (hf->flags & GS_CAN_FLAG_OVERFLOW) { -+ stats->rx_over_errors++; -+ stats->rx_errors++; -+ - skb = alloc_can_err_skb(netdev, &cf); - if (!skb) - goto resubmit_urb; -@@ -633,8 +636,6 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) - cf->can_id |= CAN_ERR_CRTL; - cf->len = CAN_ERR_DLC; - cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; -- stats->rx_over_errors++; -- stats->rx_errors++; - netif_rx(skb); - } - -diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c -index 8c492d56d2c36..dc9eea3c8ab16 100644 ---- a/drivers/net/dsa/microchip/ksz_common.c -+++ b/drivers/net/dsa/microchip/ksz_common.c -@@ -590,10 +590,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { - regmap_reg_range(0x1030, 0x1030), - regmap_reg_range(0x1100, 0x1115), - regmap_reg_range(0x111a, 0x111f), -- regmap_reg_range(0x1122, 0x1127), -- regmap_reg_range(0x112a, 0x112b), -- regmap_reg_range(0x1136, 0x1139), -- regmap_reg_range(0x113e, 0x113f), -+ regmap_reg_range(0x1120, 0x112b), -+ regmap_reg_range(0x1134, 0x113b), -+ regmap_reg_range(0x113c, 0x113f), - regmap_reg_range(0x1400, 0x1401), - regmap_reg_range(0x1403, 0x1403), - regmap_reg_range(0x1410, 0x1417), -@@ -624,10 +623,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { - regmap_reg_range(0x2030, 0x2030), - regmap_reg_range(0x2100, 0x2115), - regmap_reg_range(0x211a, 0x211f), -- regmap_reg_range(0x2122, 0x2127), -- regmap_reg_range(0x212a, 0x212b), -- regmap_reg_range(0x2136, 0x2139), -- regmap_reg_range(0x213e, 0x213f), -+ regmap_reg_range(0x2120, 0x212b), -+ regmap_reg_range(0x2134, 0x213b), -+ regmap_reg_range(0x213c, 0x213f), - regmap_reg_range(0x2400, 0x2401), - regmap_reg_range(0x2403, 0x2403), - regmap_reg_range(0x2410, 0x2417), -@@ -658,10 +656,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { - regmap_reg_range(0x3030, 0x3030), - regmap_reg_range(0x3100, 0x3115), - regmap_reg_range(0x311a, 0x311f), -- regmap_reg_range(0x3122, 0x3127), -- regmap_reg_range(0x312a, 0x312b), -- regmap_reg_range(0x3136, 0x3139), -- regmap_reg_range(0x313e, 0x313f), -+ regmap_reg_range(0x3120, 0x312b), -+ regmap_reg_range(0x3134, 0x313b), -+ regmap_reg_range(0x313c, 0x313f), - regmap_reg_range(0x3400, 0x3401), - regmap_reg_range(0x3403, 0x3403), - regmap_reg_range(0x3410, 0x3417), -@@ -692,10 +689,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { - regmap_reg_range(0x4030, 0x4030), - regmap_reg_range(0x4100, 0x4115), - regmap_reg_range(0x411a, 0x411f), -- regmap_reg_range(0x4122, 0x4127), -- regmap_reg_range(0x412a, 0x412b), -- regmap_reg_range(0x4136, 0x4139), -- regmap_reg_range(0x413e, 0x413f), -+ regmap_reg_range(0x4120, 0x412b), -+ regmap_reg_range(0x4134, 0x413b), -+ regmap_reg_range(0x413c, 0x413f), - regmap_reg_range(0x4400, 0x4401), - regmap_reg_range(0x4403, 0x4403), - regmap_reg_range(0x4410, 0x4417), -@@ -726,10 +722,9 @@ static const struct regmap_range ksz9477_valid_regs[] = { - regmap_reg_range(0x5030, 0x5030), - regmap_reg_range(0x5100, 0x5115), - regmap_reg_range(0x511a, 0x511f), -- regmap_reg_range(0x5122, 0x5127), -- regmap_reg_range(0x512a, 0x512b), -- regmap_reg_range(0x5136, 0x5139), -- regmap_reg_range(0x513e, 0x513f), -+ regmap_reg_range(0x5120, 0x512b), -+ regmap_reg_range(0x5134, 0x513b), -+ regmap_reg_range(0x513c, 0x513f), - regmap_reg_range(0x5400, 0x5401), - regmap_reg_range(0x5403, 0x5403), - regmap_reg_range(0x5410, 0x5417), -diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -index 40c781695d581..7762e532c6a4f 100644 ---- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -@@ -2104,8 +2104,11 @@ static int atl1c_tso_csum(struct atl1c_adapter *adapter, - real_len = (((unsigned char *)ip_hdr(skb) - skb->data) - + ntohs(ip_hdr(skb)->tot_len)); - -- if (real_len < skb->len) -- pskb_trim(skb, real_len); -+ if (real_len < skb->len) { -+ err = pskb_trim(skb, real_len); -+ if (err) -+ return err; -+ } - - hdr_len = skb_tcp_all_headers(skb); - if (unlikely(skb->len == hdr_len)) { -diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c -index 51b1690fd0459..a1783faf4fe99 100644 ---- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c -+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c -@@ -14312,11 +14312,16 @@ static void bnx2x_io_resume(struct pci_dev *pdev) - bp->fw_seq = SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK; - -- if (netif_running(dev)) -- bnx2x_nic_load(bp, LOAD_NORMAL); -+ if (netif_running(dev)) { -+ if (bnx2x_nic_load(bp, LOAD_NORMAL)) { -+ netdev_err(bp->dev, "Error during driver initialization, try unloading/reloading the driver\n"); -+ goto done; -+ } -+ } - - netif_device_attach(dev); - -+done: - rtnl_unlock(); - } - -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -index 6af2273f227c2..84ecd8b9be48c 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -@@ -10936,9 +10936,12 @@ int hclge_cfg_flowctrl(struct hclge_dev *hdev) - u32 rx_pause, tx_pause; - u8 flowctl; - -- if (!phydev->link || !phydev->autoneg) -+ if (!phydev->link) - return 0; - -+ if (!phydev->autoneg) -+ return hclge_mac_pause_setup_hw(hdev); -+ - local_advertising = linkmode_adv_to_lcl_adv_t(phydev->advertising); - - if (phydev->pause) -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c -index 150f146fa24fb..8b40c6b4ee53e 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c -@@ -1549,7 +1549,7 @@ static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc) - return 0; - } - --static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) -+int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) - { - bool tx_en, rx_en; - -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h -index dd6f1fd486cf2..251e808456208 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h -@@ -242,6 +242,7 @@ int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, - u8 pfc_bitmap); - int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); - int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); -+int hclge_mac_pause_setup_hw(struct hclge_dev *hdev); - void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); - void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); - int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate); -diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c -index 7a00d297be3a9..3f98781e74b28 100644 ---- a/drivers/net/ethernet/intel/ice/ice_main.c -+++ b/drivers/net/ethernet/intel/ice/ice_main.c -@@ -1356,6 +1356,7 @@ int ice_aq_wait_for_event(struct ice_pf *pf, u16 opcode, unsigned long timeout, - static void ice_aq_check_events(struct ice_pf *pf, u16 opcode, - struct ice_rq_event_info *event) - { -+ struct ice_rq_event_info *task_ev; - struct ice_aq_task *task; - bool found = false; - -@@ -1364,15 +1365,15 @@ static void ice_aq_check_events(struct ice_pf *pf, u16 opcode, - if (task->state || task->opcode != opcode) - continue; - -- memcpy(&task->event->desc, &event->desc, sizeof(event->desc)); -- task->event->msg_len = event->msg_len; -+ task_ev = task->event; -+ memcpy(&task_ev->desc, &event->desc, sizeof(event->desc)); -+ task_ev->msg_len = event->msg_len; - - /* Only copy the data buffer if a destination was set */ -- if (task->event->msg_buf && -- task->event->buf_len > event->buf_len) { -- memcpy(task->event->msg_buf, event->msg_buf, -+ if (task_ev->msg_buf && task_ev->buf_len >= event->buf_len) { -+ memcpy(task_ev->msg_buf, event->msg_buf, - event->buf_len); -- task->event->buf_len = event->buf_len; -+ task_ev->buf_len = event->buf_len; - } - - task->state = ICE_AQ_TASK_COMPLETE; -diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c -index 772b1f566d6ed..813acd6a4b469 100644 ---- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c -+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c -@@ -131,6 +131,8 @@ static void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) - case READ_TIME: - cmd_val |= GLTSYN_CMD_READ_TIME; - break; -+ case ICE_PTP_NOP: -+ break; - } - - wr32(hw, GLTSYN_CMD, cmd_val); -@@ -1200,18 +1202,18 @@ ice_ptp_read_port_capture(struct ice_hw *hw, u8 port, u64 *tx_ts, u64 *rx_ts) - } - - /** -- * ice_ptp_one_port_cmd - Prepare a single PHY port for a timer command -+ * ice_ptp_write_port_cmd_e822 - Prepare a single PHY port for a timer command - * @hw: pointer to HW struct - * @port: Port to which cmd has to be sent - * @cmd: Command to be sent to the port - * - * Prepare the requested port for an upcoming timer sync command. - * -- * Note there is no equivalent of this operation on E810, as that device -- * always handles all external PHYs internally. -+ * Do not use this function directly. If you want to configure exactly one -+ * port, use ice_ptp_one_port_cmd() instead. - */ - static int --ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd) -+ice_ptp_write_port_cmd_e822(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd) - { - u32 cmd_val, val; - u8 tmr_idx; -@@ -1235,6 +1237,8 @@ ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd) - case ADJ_TIME_AT_TIME: - cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME; - break; -+ case ICE_PTP_NOP: -+ break; - } - - /* Tx case */ -@@ -1280,6 +1284,39 @@ ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd) - return 0; - } - -+/** -+ * ice_ptp_one_port_cmd - Prepare one port for a timer command -+ * @hw: pointer to the HW struct -+ * @configured_port: the port to configure with configured_cmd -+ * @configured_cmd: timer command to prepare on the configured_port -+ * -+ * Prepare the configured_port for the configured_cmd, and prepare all other -+ * ports for ICE_PTP_NOP. This causes the configured_port to execute the -+ * desired command while all other ports perform no operation. -+ */ -+static int -+ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port, -+ enum ice_ptp_tmr_cmd configured_cmd) -+{ -+ u8 port; -+ -+ for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) { -+ enum ice_ptp_tmr_cmd cmd; -+ int err; -+ -+ if (port == configured_port) -+ cmd = configured_cmd; -+ else -+ cmd = ICE_PTP_NOP; -+ -+ err = ice_ptp_write_port_cmd_e822(hw, port, cmd); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ - /** - * ice_ptp_port_cmd_e822 - Prepare all ports for a timer command - * @hw: pointer to the HW struct -@@ -1296,7 +1333,7 @@ ice_ptp_port_cmd_e822(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) - for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) { - int err; - -- err = ice_ptp_one_port_cmd(hw, port, cmd); -+ err = ice_ptp_write_port_cmd_e822(hw, port, cmd); - if (err) - return err; - } -@@ -2245,6 +2282,9 @@ static int ice_sync_phy_timer_e822(struct ice_hw *hw, u8 port) - if (err) - goto err_unlock; - -+ /* Do not perform any action on the main timer */ -+ ice_ptp_src_cmd(hw, ICE_PTP_NOP); -+ - /* Issue the sync to activate the time adjustment */ - ice_ptp_exec_tmr_cmd(hw); - -@@ -2371,6 +2411,9 @@ ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass) - if (err) - return err; - -+ /* Do not perform any action on the main timer */ -+ ice_ptp_src_cmd(hw, ICE_PTP_NOP); -+ - ice_ptp_exec_tmr_cmd(hw); - - err = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val); -@@ -2914,6 +2957,8 @@ static int ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) - case ADJ_TIME_AT_TIME: - cmd_val = GLTSYN_CMD_ADJ_INIT_TIME; - break; -+ case ICE_PTP_NOP: -+ return 0; - } - - /* Read, modify, write */ -diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h -index 2bda64c76abc3..071f545aa85e8 100644 ---- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h -+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h -@@ -9,7 +9,8 @@ enum ice_ptp_tmr_cmd { - INIT_INCVAL, - ADJ_TIME, - ADJ_TIME_AT_TIME, -- READ_TIME -+ READ_TIME, -+ ICE_PTP_NOP, - }; - - enum ice_ptp_serdes { -diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c -index 3e0444354632d..d0ead18ec0266 100644 ---- a/drivers/net/ethernet/intel/igb/igb_main.c -+++ b/drivers/net/ethernet/intel/igb/igb_main.c -@@ -4758,6 +4758,10 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, - static void igb_set_rx_buffer_len(struct igb_adapter *adapter, - struct igb_ring *rx_ring) - { -+#if (PAGE_SIZE < 8192) -+ struct e1000_hw *hw = &adapter->hw; -+#endif -+ - /* set build_skb and buffer size flags */ - clear_ring_build_skb_enabled(rx_ring); - clear_ring_uses_large_buffer(rx_ring); -@@ -4768,10 +4772,9 @@ static void igb_set_rx_buffer_len(struct igb_adapter *adapter, - set_ring_build_skb_enabled(rx_ring); - - #if (PAGE_SIZE < 8192) -- if (adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB) -- return; -- -- set_ring_uses_large_buffer(rx_ring); -+ if (adapter->max_frame_size > IGB_MAX_FRAME_BUILD_SKB || -+ rd32(E1000_RCTL) & E1000_RCTL_SBP) -+ set_ring_uses_large_buffer(rx_ring); - #endif - } - -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -index 5541e284cd3f0..c85e0180d96da 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -@@ -1691,6 +1691,42 @@ exit: - return true; - } - -+static void nix_reset_tx_schedule(struct rvu *rvu, int blkaddr, -+ int lvl, int schq) -+{ -+ u64 tlx_parent = 0, tlx_schedule = 0; -+ -+ switch (lvl) { -+ case NIX_TXSCH_LVL_TL2: -+ tlx_parent = NIX_AF_TL2X_PARENT(schq); -+ tlx_schedule = NIX_AF_TL2X_SCHEDULE(schq); -+ break; -+ case NIX_TXSCH_LVL_TL3: -+ tlx_parent = NIX_AF_TL3X_PARENT(schq); -+ tlx_schedule = NIX_AF_TL3X_SCHEDULE(schq); -+ break; -+ case NIX_TXSCH_LVL_TL4: -+ tlx_parent = NIX_AF_TL4X_PARENT(schq); -+ tlx_schedule = NIX_AF_TL4X_SCHEDULE(schq); -+ break; -+ case NIX_TXSCH_LVL_MDQ: -+ /* no need to reset SMQ_CFG as HW clears this CSR -+ * on SMQ flush -+ */ -+ tlx_parent = NIX_AF_MDQX_PARENT(schq); -+ tlx_schedule = NIX_AF_MDQX_SCHEDULE(schq); -+ break; -+ default: -+ return; -+ } -+ -+ if (tlx_parent) -+ rvu_write64(rvu, blkaddr, tlx_parent, 0x0); -+ -+ if (tlx_schedule) -+ rvu_write64(rvu, blkaddr, tlx_schedule, 0x0); -+} -+ - /* Disable shaping of pkts by a scheduler queue - * at a given scheduler level. - */ -@@ -2040,6 +2076,7 @@ int rvu_mbox_handler_nix_txsch_alloc(struct rvu *rvu, - pfvf_map[schq] = TXSCH_MAP(pcifunc, 0); - nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq); - nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq); -+ nix_reset_tx_schedule(rvu, blkaddr, lvl, schq); - } - - for (idx = 0; idx < req->schq[lvl]; idx++) { -@@ -2049,6 +2086,7 @@ int rvu_mbox_handler_nix_txsch_alloc(struct rvu *rvu, - pfvf_map[schq] = TXSCH_MAP(pcifunc, 0); - nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq); - nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq); -+ nix_reset_tx_schedule(rvu, blkaddr, lvl, schq); - } - } - -@@ -2137,6 +2175,7 @@ static int nix_txschq_free(struct rvu *rvu, u16 pcifunc) - continue; - nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq); - nix_clear_tx_xoff(rvu, blkaddr, lvl, schq); -+ nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq); - } - } - nix_clear_tx_xoff(rvu, blkaddr, NIX_TXSCH_LVL_TL1, -@@ -2175,6 +2214,7 @@ static int nix_txschq_free(struct rvu *rvu, u16 pcifunc) - for (schq = 0; schq < txsch->schq.max; schq++) { - if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc) - continue; -+ nix_reset_tx_schedule(rvu, blkaddr, lvl, schq); - rvu_free_rsrc(&txsch->schq, schq); - txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE); - } -@@ -2234,6 +2274,9 @@ static int nix_txschq_free_one(struct rvu *rvu, - */ - nix_clear_tx_xoff(rvu, blkaddr, lvl, schq); - -+ nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq); -+ nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq); -+ - /* Flush if it is a SMQ. Onus of disabling - * TL2/3 queue links before SMQ flush is on user - */ -@@ -2243,6 +2286,8 @@ static int nix_txschq_free_one(struct rvu *rvu, - goto err; - } - -+ nix_reset_tx_schedule(rvu, blkaddr, lvl, schq); -+ - /* Free the resource */ - rvu_free_rsrc(&txsch->schq, schq); - txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE); -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -index 8a41ad8ca04f1..011355e73696e 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -@@ -716,7 +716,8 @@ EXPORT_SYMBOL(otx2_smq_flush); - int otx2_txsch_alloc(struct otx2_nic *pfvf) - { - struct nix_txsch_alloc_req *req; -- int lvl; -+ struct nix_txsch_alloc_rsp *rsp; -+ int lvl, schq, rc; - - /* Get memory to put this msg */ - req = otx2_mbox_alloc_msg_nix_txsch_alloc(&pfvf->mbox); -@@ -726,33 +727,69 @@ int otx2_txsch_alloc(struct otx2_nic *pfvf) - /* Request one schq per level */ - for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) - req->schq[lvl] = 1; -+ rc = otx2_sync_mbox_msg(&pfvf->mbox); -+ if (rc) -+ return rc; - -- return otx2_sync_mbox_msg(&pfvf->mbox); -+ rsp = (struct nix_txsch_alloc_rsp *) -+ otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr); -+ if (IS_ERR(rsp)) -+ return PTR_ERR(rsp); -+ -+ /* Setup transmit scheduler list */ -+ for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) -+ for (schq = 0; schq < rsp->schq[lvl]; schq++) -+ pfvf->hw.txschq_list[lvl][schq] = -+ rsp->schq_list[lvl][schq]; -+ -+ pfvf->hw.txschq_link_cfg_lvl = rsp->link_cfg_lvl; -+ -+ return 0; - } - --int otx2_txschq_stop(struct otx2_nic *pfvf) -+void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq) - { - struct nix_txsch_free_req *free_req; -- int lvl, schq, err; -+ int err; - - mutex_lock(&pfvf->mbox.lock); -- /* Free the transmit schedulers */ -+ - free_req = otx2_mbox_alloc_msg_nix_txsch_free(&pfvf->mbox); - if (!free_req) { - mutex_unlock(&pfvf->mbox.lock); -- return -ENOMEM; -+ netdev_err(pfvf->netdev, -+ "Failed alloc txschq free req\n"); -+ return; - } - -- free_req->flags = TXSCHQ_FREE_ALL; -+ free_req->schq_lvl = lvl; -+ free_req->schq = schq; -+ - err = otx2_sync_mbox_msg(&pfvf->mbox); -+ if (err) { -+ netdev_err(pfvf->netdev, -+ "Failed stop txschq %d at level %d\n", schq, lvl); -+ } -+ - mutex_unlock(&pfvf->mbox.lock); -+} -+EXPORT_SYMBOL(otx2_txschq_free_one); -+ -+void otx2_txschq_stop(struct otx2_nic *pfvf) -+{ -+ int lvl, schq; -+ -+ /* free non QOS TLx nodes */ -+ for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) -+ otx2_txschq_free_one(pfvf, lvl, -+ pfvf->hw.txschq_list[lvl][0]); - - /* Clear the txschq list */ - for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) { - for (schq = 0; schq < MAX_TXSCHQ_PER_FUNC; schq++) - pfvf->hw.txschq_list[lvl][schq] = 0; - } -- return err; -+ - } - - void otx2_sqb_flush(struct otx2_nic *pfvf) -@@ -1629,21 +1666,6 @@ void mbox_handler_cgx_fec_stats(struct otx2_nic *pfvf, - pfvf->hw.cgx_fec_uncorr_blks += rsp->fec_uncorr_blks; - } - --void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf, -- struct nix_txsch_alloc_rsp *rsp) --{ -- int lvl, schq; -- -- /* Setup transmit scheduler list */ -- for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) -- for (schq = 0; schq < rsp->schq[lvl]; schq++) -- pf->hw.txschq_list[lvl][schq] = -- rsp->schq_list[lvl][schq]; -- -- pf->hw.txschq_link_cfg_lvl = rsp->link_cfg_lvl; --} --EXPORT_SYMBOL(mbox_handler_nix_txsch_alloc); -- - void mbox_handler_npa_lf_alloc(struct otx2_nic *pfvf, - struct npa_lf_alloc_rsp *rsp) - { -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -index 241016ca64d05..8a9793b06769f 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -@@ -917,7 +917,8 @@ int otx2_config_nix(struct otx2_nic *pfvf); - int otx2_config_nix_queues(struct otx2_nic *pfvf); - int otx2_txschq_config(struct otx2_nic *pfvf, int lvl, int prio, bool pfc_en); - int otx2_txsch_alloc(struct otx2_nic *pfvf); --int otx2_txschq_stop(struct otx2_nic *pfvf); -+void otx2_txschq_stop(struct otx2_nic *pfvf); -+void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq); - void otx2_sqb_flush(struct otx2_nic *pfvf); - int __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, - dma_addr_t *dma); -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c -index ccaf97bb1ce03..bfddbff7bcdfb 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c -@@ -70,7 +70,7 @@ static int otx2_pfc_txschq_alloc_one(struct otx2_nic *pfvf, u8 prio) - * link config level. These rest of the scheduler can be - * same as hw.txschq_list. - */ -- for (lvl = 0; lvl < pfvf->hw.txschq_link_cfg_lvl; lvl++) -+ for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++) - req->schq[lvl] = 1; - - rc = otx2_sync_mbox_msg(&pfvf->mbox); -@@ -83,7 +83,7 @@ static int otx2_pfc_txschq_alloc_one(struct otx2_nic *pfvf, u8 prio) - return PTR_ERR(rsp); - - /* Setup transmit scheduler list */ -- for (lvl = 0; lvl < pfvf->hw.txschq_link_cfg_lvl; lvl++) { -+ for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++) { - if (!rsp->schq[lvl]) - return -ENOSPC; - -@@ -125,19 +125,12 @@ int otx2_pfc_txschq_alloc(struct otx2_nic *pfvf) - - static int otx2_pfc_txschq_stop_one(struct otx2_nic *pfvf, u8 prio) - { -- struct nix_txsch_free_req *free_req; -+ int lvl; - -- mutex_lock(&pfvf->mbox.lock); - /* free PFC TLx nodes */ -- free_req = otx2_mbox_alloc_msg_nix_txsch_free(&pfvf->mbox); -- if (!free_req) { -- mutex_unlock(&pfvf->mbox.lock); -- return -ENOMEM; -- } -- -- free_req->flags = TXSCHQ_FREE_ALL; -- otx2_sync_mbox_msg(&pfvf->mbox); -- mutex_unlock(&pfvf->mbox.lock); -+ for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++) -+ otx2_txschq_free_one(pfvf, lvl, -+ pfvf->pfc_schq_list[lvl][prio]); - - pfvf->pfc_alloc_status[prio] = false; - return 0; -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -index c236dba80ff1a..17e546d0d7e55 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -@@ -791,10 +791,6 @@ static void otx2_process_pfaf_mbox_msg(struct otx2_nic *pf, - case MBOX_MSG_NIX_LF_ALLOC: - mbox_handler_nix_lf_alloc(pf, (struct nix_lf_alloc_rsp *)msg); - break; -- case MBOX_MSG_NIX_TXSCH_ALLOC: -- mbox_handler_nix_txsch_alloc(pf, -- (struct nix_txsch_alloc_rsp *)msg); -- break; - case MBOX_MSG_NIX_BP_ENABLE: - mbox_handler_nix_bp_enable(pf, (struct nix_bp_cfg_rsp *)msg); - break; -@@ -1517,8 +1513,7 @@ err_free_nix_queues: - otx2_free_cq_res(pf); - otx2_ctx_disable(mbox, NIX_AQ_CTYPE_RQ, false); - err_free_txsch: -- if (otx2_txschq_stop(pf)) -- dev_err(pf->dev, "%s failed to stop TX schedulers\n", __func__); -+ otx2_txschq_stop(pf); - err_free_sq_ptrs: - otx2_sq_free_sqbs(pf); - err_free_rq_ptrs: -@@ -1553,15 +1548,13 @@ static void otx2_free_hw_resources(struct otx2_nic *pf) - struct mbox *mbox = &pf->mbox; - struct otx2_cq_queue *cq; - struct msg_req *req; -- int qidx, err; -+ int qidx; - - /* Ensure all SQE are processed */ - otx2_sqb_flush(pf); - - /* Stop transmission */ -- err = otx2_txschq_stop(pf); -- if (err) -- dev_err(pf->dev, "RVUPF: Failed to stop/free TX schedulers\n"); -+ otx2_txschq_stop(pf); - - #ifdef CONFIG_DCB - if (pf->pfc_en) -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -index 53366dbfbf27c..f8f0c01f62a14 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -@@ -70,10 +70,6 @@ static void otx2vf_process_vfaf_mbox_msg(struct otx2_nic *vf, - case MBOX_MSG_NIX_LF_ALLOC: - mbox_handler_nix_lf_alloc(vf, (struct nix_lf_alloc_rsp *)msg); - break; -- case MBOX_MSG_NIX_TXSCH_ALLOC: -- mbox_handler_nix_txsch_alloc(vf, -- (struct nix_txsch_alloc_rsp *)msg); -- break; - case MBOX_MSG_NIX_BP_ENABLE: - mbox_handler_nix_bp_enable(vf, (struct nix_bp_cfg_rsp *)msg); - break; -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c -index d219f8417d93a..dec1492da74de 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c -@@ -319,16 +319,11 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev) - pci_cfg_access_lock(sdev); - } - /* PCI link toggle */ -- err = pci_read_config_word(bridge, cap + PCI_EXP_LNKCTL, ®16); -- if (err) -- return err; -- reg16 |= PCI_EXP_LNKCTL_LD; -- err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16); -+ err = pcie_capability_set_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD); - if (err) - return err; - msleep(500); -- reg16 &= ~PCI_EXP_LNKCTL_LD; -- err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16); -+ err = pcie_capability_clear_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD); - if (err) - return err; - -diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c -index 70735068cf292..0fd290d776ffe 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c -@@ -405,7 +405,8 @@ mlxsw_hwmon_module_temp_label_show(struct device *dev, - container_of(attr, struct mlxsw_hwmon_attr, dev_attr); - - return sprintf(buf, "front panel %03u\n", -- mlxsw_hwmon_attr->type_index); -+ mlxsw_hwmon_attr->type_index + 1 - -+ mlxsw_hwmon_attr->mlxsw_hwmon_dev->sensor_count); - } - - static ssize_t -diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c -index f5f5f8dc3d190..3beefc167da91 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c -@@ -48,6 +48,7 @@ - #define MLXSW_I2C_MBOX_SIZE_BITS 12 - #define MLXSW_I2C_ADDR_BUF_SIZE 4 - #define MLXSW_I2C_BLK_DEF 32 -+#define MLXSW_I2C_BLK_MAX 100 - #define MLXSW_I2C_RETRY 5 - #define MLXSW_I2C_TIMEOUT_MSECS 5000 - #define MLXSW_I2C_MAX_DATA_SIZE 256 -@@ -444,7 +445,7 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size, - } else { - /* No input mailbox is case of initialization query command. */ - reg_size = MLXSW_I2C_MAX_DATA_SIZE; -- num = reg_size / mlxsw_i2c->block_size; -+ num = DIV_ROUND_UP(reg_size, mlxsw_i2c->block_size); - - if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) { - dev_err(&client->dev, "Could not acquire lock"); -@@ -653,7 +654,7 @@ static int mlxsw_i2c_probe(struct i2c_client *client, - return -EOPNOTSUPP; - } - -- mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF, -+ mlxsw_i2c->block_size = min_t(u16, MLXSW_I2C_BLK_MAX, - min_t(u16, quirks->max_read_len, - quirks->max_write_len)); - } else { -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index cabed1b7b45ed..a9a0dca0c0305 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5201,13 +5201,9 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - - /* Disable ASPM L1 as that cause random device stop working - * problems as well as full system hangs for some PCIe devices users. -- * Chips from RTL8168h partially have issues with L1.2, but seem -- * to work fine with L1 and L1.1. - */ - if (rtl_aspm_is_safe(tp)) - rc = 0; -- else if (tp->mac_version >= RTL_GIGA_MAC_VER_46) -- rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1_2); - else - rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1); - tp->aspm_manageable = !rc; -diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c -index eaef4a15008a3..692c7f132e9f9 100644 ---- a/drivers/net/ethernet/sfc/ptp.c -+++ b/drivers/net/ethernet/sfc/ptp.c -@@ -1387,7 +1387,8 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx) - goto fail; - - rc = efx_ptp_insert_eth_filter(efx); -- if (rc < 0) -+ /* Not all firmware variants support this filter */ -+ if (rc < 0 && rc != -EPROTONOSUPPORT) - goto fail; - } - -diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c -index 6a7965ed63001..578f470e9fad9 100644 ---- a/drivers/net/macsec.c -+++ b/drivers/net/macsec.c -@@ -1331,8 +1331,7 @@ static struct crypto_aead *macsec_alloc_tfm(char *key, int key_len, int icv_len) - struct crypto_aead *tfm; - int ret; - -- /* Pick a sync gcm(aes) cipher to ensure order is preserved. */ -- tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); -+ tfm = crypto_alloc_aead("gcm(aes)", 0, 0); - - if (IS_ERR(tfm)) - return tfm; -diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c -index daac293e8edec..1865e3dbdfad0 100644 ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -254,6 +254,16 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, - switch (id->base.extended_cc) { - case SFF8024_ECC_UNSPEC: - break; -+ case SFF8024_ECC_100G_25GAUI_C2M_AOC: -+ if (br_min <= 28000 && br_max >= 25000) { -+ /* 25GBASE-R, possibly with FEC */ -+ __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces); -+ /* There is currently no link mode for 25000base -+ * with unspecified range, reuse SR. -+ */ -+ phylink_set(modes, 25000baseSR_Full); -+ } -+ break; - case SFF8024_ECC_100GBASE_SR4_25GBASE_SR: - phylink_set(modes, 100000baseSR4_Full); - phylink_set(modes, 25000baseSR_Full); -diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c -index 68829a5a93d3e..4fb981b8732ef 100644 ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -1422,6 +1422,7 @@ static const struct usb_device_id products[] = { - {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */ - {QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)}, /* Quectel EG95 */ - {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ -+ {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ - {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ - {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ - {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ -diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c -index 728d607289c36..522691ba4c5d2 100644 ---- a/drivers/net/wireless/ath/ath10k/pci.c -+++ b/drivers/net/wireless/ath/ath10k/pci.c -@@ -1963,8 +1963,9 @@ static int ath10k_pci_hif_start(struct ath10k *ar) - ath10k_pci_irq_enable(ar); - ath10k_pci_rx_post(ar); - -- pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, -- ar_pci->link_ctl); -+ pcie_capability_clear_and_set_word(ar_pci->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_ASPMC, -+ ar_pci->link_ctl & PCI_EXP_LNKCTL_ASPMC); - - return 0; - } -@@ -2821,8 +2822,8 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar, - - pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL, - &ar_pci->link_ctl); -- pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, -- ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC); -+ pcie_capability_clear_word(ar_pci->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_ASPMC); - - /* - * Bring the target up cleanly. -diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c -index 3c6005ab9a717..3953ebd551bf8 100644 ---- a/drivers/net/wireless/ath/ath11k/pci.c -+++ b/drivers/net/wireless/ath/ath11k/pci.c -@@ -582,8 +582,8 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci) - u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1)); - - /* disable L0s and L1 */ -- pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, -- ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC); -+ pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_ASPMC); - - set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags); - } -@@ -591,8 +591,10 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci) - static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci) - { - if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) -- pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, -- ab_pci->link_ctl); -+ pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_ASPMC, -+ ab_pci->link_ctl & -+ PCI_EXP_LNKCTL_ASPMC); - } - - static int ath11k_pci_power_up(struct ath11k_base *ab) -diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile -index a75bfa9fd1cfd..dc2b3b46781e1 100644 ---- a/drivers/net/wireless/ath/ath6kl/Makefile -+++ b/drivers/net/wireless/ath/ath6kl/Makefile -@@ -36,11 +36,6 @@ ath6kl_core-y += wmi.o - ath6kl_core-y += core.o - ath6kl_core-y += recovery.o - --# FIXME: temporarily silence -Wdangling-pointer on non W=1+ builds --ifndef KBUILD_EXTRA_WARN --CFLAGS_htc_mbox.o += $(call cc-disable-warning, dangling-pointer) --endif -- - ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o - ath6kl_core-$(CONFIG_ATH6KL_TRACING) += trace.o - -diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c -index b3ed65e5c4da8..c55aab01fff5d 100644 ---- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c -@@ -491,7 +491,7 @@ int ath9k_htc_init_debug(struct ath_hw *ah) - - priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, - priv->hw->wiphy->debugfsdir); -- if (!priv->debug.debugfs_phy) -+ if (IS_ERR(priv->debug.debugfs_phy)) - return -ENOMEM; - - ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); -diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c -index d652c647d56b5..1476b42b52a91 100644 ---- a/drivers/net/wireless/ath/ath9k/wmi.c -+++ b/drivers/net/wireless/ath/ath9k/wmi.c -@@ -242,10 +242,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, - spin_unlock_irqrestore(&wmi->wmi_lock, flags); - goto free_skb; - } -- spin_unlock_irqrestore(&wmi->wmi_lock, flags); - - /* WMI command response */ - ath9k_wmi_rsp_callback(wmi, skb); -+ spin_unlock_irqrestore(&wmi->wmi_lock, flags); - - free_skb: - kfree_skb(skb); -@@ -283,7 +283,8 @@ int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi, - - static int ath9k_wmi_cmd_issue(struct wmi *wmi, - struct sk_buff *skb, -- enum wmi_cmd_id cmd, u16 len) -+ enum wmi_cmd_id cmd, u16 len, -+ u8 *rsp_buf, u32 rsp_len) - { - struct wmi_cmd_hdr *hdr; - unsigned long flags; -@@ -293,6 +294,11 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, - hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); - - spin_lock_irqsave(&wmi->wmi_lock, flags); -+ -+ /* record the rsp buffer and length */ -+ wmi->cmd_rsp_buf = rsp_buf; -+ wmi->cmd_rsp_len = rsp_len; -+ - wmi->last_seq_id = wmi->tx_seq_id; - spin_unlock_irqrestore(&wmi->wmi_lock, flags); - -@@ -308,8 +314,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, - struct ath_common *common = ath9k_hw_common(ah); - u16 headroom = sizeof(struct htc_frame_hdr) + - sizeof(struct wmi_cmd_hdr); -+ unsigned long time_left, flags; - struct sk_buff *skb; -- unsigned long time_left; - int ret = 0; - - if (ah->ah_flags & AH_UNPLUGGED) -@@ -333,11 +339,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, - goto out; - } - -- /* record the rsp buffer and length */ -- wmi->cmd_rsp_buf = rsp_buf; -- wmi->cmd_rsp_len = rsp_len; -- -- ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); -+ ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len, rsp_buf, rsp_len); - if (ret) - goto out; - -@@ -345,7 +347,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, - if (!time_left) { - ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n", - wmi_cmd_to_name(cmd_id)); -+ spin_lock_irqsave(&wmi->wmi_lock, flags); - wmi->last_seq_id = 0; -+ spin_unlock_irqrestore(&wmi->wmi_lock, flags); - mutex_unlock(&wmi->op_mutex); - return -ETIMEDOUT; - } -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h -index f518e025d6e46..a8d88aedc4227 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h -@@ -383,7 +383,12 @@ struct brcmf_scan_params_le { - * fixed parameter portion is assumed, otherwise - * ssid in the fixed portion is ignored - */ -- __le16 channel_list[1]; /* list of chanspecs */ -+ union { -+ __le16 padding; /* Reserve space for at least 1 entry for abort -+ * which uses an on stack brcmf_scan_params_le -+ */ -+ DECLARE_FLEX_ARRAY(__le16, channel_list); /* chanspecs */ -+ }; - }; - - struct brcmf_scan_results { -diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c -index bda53cb91f376..63f232c723374 100644 ---- a/drivers/net/wireless/marvell/mwifiex/debugfs.c -+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c -@@ -253,8 +253,11 @@ mwifiex_histogram_read(struct file *file, char __user *ubuf, - if (!p) - return -ENOMEM; - -- if (!priv || !priv->hist_data) -- return -EFAULT; -+ if (!priv || !priv->hist_data) { -+ ret = -EFAULT; -+ goto free_and_exit; -+ } -+ - phist_data = priv->hist_data; - - p += sprintf(p, "\n" -@@ -309,6 +312,8 @@ mwifiex_histogram_read(struct file *file, char __user *ubuf, - ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page, - (unsigned long)p - page); - -+free_and_exit: -+ free_page(page); - return ret; - } - -diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c -index 9a698a16a8f38..6697132ecc977 100644 ---- a/drivers/net/wireless/marvell/mwifiex/pcie.c -+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c -@@ -189,6 +189,8 @@ static int mwifiex_pcie_probe_of(struct device *dev) - } - - static void mwifiex_pcie_work(struct work_struct *work); -+static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter); -+static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter); - - static int - mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, -@@ -792,14 +794,15 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) - if (!skb) { - mwifiex_dbg(adapter, ERROR, - "Unable to allocate skb for RX ring.\n"); -- kfree(card->rxbd_ring_vbase); - return -ENOMEM; - } - - if (mwifiex_map_pci_memory(adapter, skb, - MWIFIEX_RX_DATA_BUF_SIZE, -- DMA_FROM_DEVICE)) -- return -1; -+ DMA_FROM_DEVICE)) { -+ kfree_skb(skb); -+ return -ENOMEM; -+ } - - buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); - -@@ -849,7 +852,6 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) - if (!skb) { - mwifiex_dbg(adapter, ERROR, - "Unable to allocate skb for EVENT buf.\n"); -- kfree(card->evtbd_ring_vbase); - return -ENOMEM; - } - skb_put(skb, MAX_EVENT_SIZE); -@@ -857,8 +859,7 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) - if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, - DMA_FROM_DEVICE)) { - kfree_skb(skb); -- kfree(card->evtbd_ring_vbase); -- return -1; -+ return -ENOMEM; - } - - buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); -@@ -1058,6 +1059,7 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) - */ - static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) - { -+ int ret; - struct pcie_service_card *card = adapter->card; - const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - -@@ -1096,7 +1098,10 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) - (u32)((u64)card->rxbd_ring_pbase >> 32), - card->rxbd_ring_size); - -- return mwifiex_init_rxq_ring(adapter); -+ ret = mwifiex_init_rxq_ring(adapter); -+ if (ret) -+ mwifiex_pcie_delete_rxbd_ring(adapter); -+ return ret; - } - - /* -@@ -1127,6 +1132,7 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) - */ - static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) - { -+ int ret; - struct pcie_service_card *card = adapter->card; - const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - -@@ -1161,7 +1167,10 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) - (u32)((u64)card->evtbd_ring_pbase >> 32), - card->evtbd_ring_size); - -- return mwifiex_pcie_init_evt_ring(adapter); -+ ret = mwifiex_pcie_init_evt_ring(adapter); -+ if (ret) -+ mwifiex_pcie_delete_evtbd_ring(adapter); -+ return ret; - } - - /* -diff --git a/drivers/net/wireless/marvell/mwifiex/sta_rx.c b/drivers/net/wireless/marvell/mwifiex/sta_rx.c -index 13659b02ba882..65420ad674167 100644 ---- a/drivers/net/wireless/marvell/mwifiex/sta_rx.c -+++ b/drivers/net/wireless/marvell/mwifiex/sta_rx.c -@@ -86,6 +86,15 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv, - rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length); - rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off; - -+ if (sizeof(*rx_pkt_hdr) + rx_pkt_off > skb->len) { -+ mwifiex_dbg(priv->adapter, ERROR, -+ "wrong rx packet offset: len=%d, rx_pkt_off=%d\n", -+ skb->len, rx_pkt_off); -+ priv->stats.rx_dropped++; -+ dev_kfree_skb_any(skb); -+ return -1; -+ } -+ - if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, - sizeof(bridge_tunnel_header))) || - (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, -@@ -194,7 +203,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv, - - rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_offset; - -- if ((rx_pkt_offset + rx_pkt_length) > (u16) skb->len) { -+ if ((rx_pkt_offset + rx_pkt_length) > skb->len || -+ sizeof(rx_pkt_hdr->eth803_hdr) + rx_pkt_offset > skb->len) { - mwifiex_dbg(adapter, ERROR, - "wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n", - skb->len, rx_pkt_offset, rx_pkt_length); -diff --git a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c -index e495f7eaea033..b8b9a0fcb19cd 100644 ---- a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c -+++ b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c -@@ -103,6 +103,16 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, - return; - } - -+ if (sizeof(*rx_pkt_hdr) + -+ le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) { -+ mwifiex_dbg(adapter, ERROR, -+ "wrong rx packet offset: len=%d,rx_pkt_offset=%d\n", -+ skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset)); -+ priv->stats.rx_dropped++; -+ dev_kfree_skb_any(skb); -+ return; -+ } -+ - if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, - sizeof(bridge_tunnel_header))) || - (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, -@@ -243,7 +253,15 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, - - if (is_multicast_ether_addr(ra)) { - skb_uap = skb_copy(skb, GFP_ATOMIC); -- mwifiex_uap_queue_bridged_pkt(priv, skb_uap); -+ if (likely(skb_uap)) { -+ mwifiex_uap_queue_bridged_pkt(priv, skb_uap); -+ } else { -+ mwifiex_dbg(adapter, ERROR, -+ "failed to copy skb for uAP\n"); -+ priv->stats.rx_dropped++; -+ dev_kfree_skb_any(skb); -+ return -1; -+ } - } else { - if (mwifiex_get_sta_entry(priv, ra)) { - /* Requeue Intra-BSS packet */ -@@ -367,6 +385,16 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, - rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); - rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); - -+ if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) + -+ sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) { -+ mwifiex_dbg(adapter, ERROR, -+ "wrong rx packet for struct ethhdr: len=%d, offset=%d\n", -+ skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset)); -+ priv->stats.rx_dropped++; -+ dev_kfree_skb_any(skb); -+ return 0; -+ } -+ - ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source); - - if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) + -diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c -index 94c2d219835da..745b1d925b217 100644 ---- a/drivers/net/wireless/marvell/mwifiex/util.c -+++ b/drivers/net/wireless/marvell/mwifiex/util.c -@@ -393,11 +393,15 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv, - } - - rx_pd = (struct rxpd *)skb->data; -+ pkt_len = le16_to_cpu(rx_pd->rx_pkt_length); -+ if (pkt_len < sizeof(struct ieee80211_hdr) + sizeof(pkt_len)) { -+ mwifiex_dbg(priv->adapter, ERROR, "invalid rx_pkt_length"); -+ return -1; -+ } - - skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset)); - skb_pull(skb, sizeof(pkt_len)); -- -- pkt_len = le16_to_cpu(rx_pd->rx_pkt_length); -+ pkt_len -= sizeof(pkt_len); - - ieee_hdr = (void *)skb->data; - if (ieee80211_is_mgmt(ieee_hdr->frame_control)) { -@@ -410,7 +414,7 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv, - skb->data + sizeof(struct ieee80211_hdr), - pkt_len - sizeof(struct ieee80211_hdr)); - -- pkt_len -= ETH_ALEN + sizeof(pkt_len); -+ pkt_len -= ETH_ALEN; - rx_pd->rx_pkt_length = cpu_to_le16(pkt_len); - - cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq, -diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c -index bda26bd62412e..3280843ea8566 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c -@@ -455,7 +455,8 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) - ieee80211_wake_queues(hw); - } - -- if (changed & IEEE80211_CONF_CHANGE_POWER) { -+ if (changed & (IEEE80211_CONF_CHANGE_POWER | -+ IEEE80211_CONF_CHANGE_CHANNEL)) { - ret = mt7915_mcu_set_txpower_sku(phy); - if (ret) - return ret; -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c -index 4ad66b3443838..c997b8d3ea590 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c -@@ -80,7 +80,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw) - wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID; - wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH; - wiphy->max_sched_scan_reqs = 1; -- wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; -+ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH | -+ WIPHY_FLAG_SPLIT_SCAN_6GHZ; - wiphy->reg_notifier = mt7921_regd_notifier; - - wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | -diff --git a/drivers/net/wireless/mediatek/mt76/testmode.c b/drivers/net/wireless/mediatek/mt76/testmode.c -index 0accc71a91c9a..4644dace9bb34 100644 ---- a/drivers/net/wireless/mediatek/mt76/testmode.c -+++ b/drivers/net/wireless/mediatek/mt76/testmode.c -@@ -8,6 +8,7 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = { - [MT76_TM_ATTR_RESET] = { .type = NLA_FLAG }, - [MT76_TM_ATTR_STATE] = { .type = NLA_U8 }, - [MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 }, -+ [MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 }, - [MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 }, - [MT76_TM_ATTR_TX_RATE_NSS] = { .type = NLA_U8 }, - [MT76_TM_ATTR_TX_RATE_IDX] = { .type = NLA_U8 }, -diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c -index ec0af903961f0..3a8fe60d0bb7b 100644 ---- a/drivers/net/wireless/realtek/rtw89/debug.c -+++ b/drivers/net/wireless/realtek/rtw89/debug.c -@@ -2302,12 +2302,14 @@ static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp, - struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - struct rtw89_btc *btc = &rtwdev->btc; - bool btc_manual; -+ int ret; - -- if (kstrtobool_from_user(user_buf, count, &btc_manual)) -- goto out; -+ ret = kstrtobool_from_user(user_buf, count, &btc_manual); -+ if (ret) -+ return ret; - - btc->ctrl.manual = btc_manual; --out: -+ - return count; - } - -diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c -index 2abd2235bbcab..9532108d2dce1 100644 ---- a/drivers/ntb/ntb_transport.c -+++ b/drivers/ntb/ntb_transport.c -@@ -909,7 +909,7 @@ static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw, - return 0; - } - --static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) -+static void ntb_qp_link_context_reset(struct ntb_transport_qp *qp) - { - qp->link_is_up = false; - qp->active = false; -@@ -932,6 +932,13 @@ static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) - qp->tx_async = 0; - } - -+static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) -+{ -+ ntb_qp_link_context_reset(qp); -+ if (qp->remote_rx_info) -+ qp->remote_rx_info->entry = qp->rx_max_entry - 1; -+} -+ - static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp) - { - struct ntb_transport_ctx *nt = qp->transport; -@@ -1174,7 +1181,7 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt, - qp->ndev = nt->ndev; - qp->client_ready = false; - qp->event_handler = NULL; -- ntb_qp_link_down_reset(qp); -+ ntb_qp_link_context_reset(qp); - - if (mw_num < qp_count % mw_count) - num_qps_mw = qp_count / mw_count + 1; -@@ -2276,9 +2283,13 @@ int ntb_transport_tx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data, - struct ntb_queue_entry *entry; - int rc; - -- if (!qp || !qp->link_is_up || !len) -+ if (!qp || !len) - return -EINVAL; - -+ /* If the qp link is down already, just ignore. */ -+ if (!qp->link_is_up) -+ return 0; -+ - entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q); - if (!entry) { - qp->tx_err_no_buf++; -@@ -2418,7 +2429,7 @@ unsigned int ntb_transport_tx_free_entry(struct ntb_transport_qp *qp) - unsigned int head = qp->tx_index; - unsigned int tail = qp->remote_rx_info->entry; - -- return tail > head ? tail - head : qp->tx_max_entry + tail - head; -+ return tail >= head ? tail - head : qp->tx_max_entry + tail - head; - } - EXPORT_SYMBOL_GPL(ntb_transport_tx_free_entry); - -diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c -index 433bbb68ae641..2b6dc80d8fb5b 100644 ---- a/drivers/nvdimm/nd_perf.c -+++ b/drivers/nvdimm/nd_perf.c -@@ -308,8 +308,8 @@ int register_nvdimm_pmu(struct nvdimm_pmu *nd_pmu, struct platform_device *pdev) - - rc = perf_pmu_register(&nd_pmu->pmu, nd_pmu->pmu.name, -1); - if (rc) { -- kfree(nd_pmu->pmu.attr_groups); - nvdimm_pmu_free_hotplug_memory(nd_pmu); -+ kfree(nd_pmu->pmu.attr_groups); - return rc; - } - -@@ -324,6 +324,7 @@ void unregister_nvdimm_pmu(struct nvdimm_pmu *nd_pmu) - { - perf_pmu_unregister(&nd_pmu->pmu); - nvdimm_pmu_free_hotplug_memory(nd_pmu); -+ kfree(nd_pmu->pmu.attr_groups); - kfree(nd_pmu); - } - EXPORT_SYMBOL_GPL(unregister_nvdimm_pmu); -diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index 4e436f2d13aeb..95501b77ef314 100644 ---- a/drivers/of/dynamic.c -+++ b/drivers/of/dynamic.c -@@ -225,6 +225,7 @@ static void __of_attach_node(struct device_node *np) - np->sibling = np->parent->child; - np->parent->child = np; - of_node_clear_flag(np, OF_DETACHED); -+ np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE; - } - - /** -diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c -index 5289975bad708..4402871b5c0c0 100644 ---- a/drivers/of/overlay.c -+++ b/drivers/of/overlay.c -@@ -752,8 +752,6 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs) - if (!of_node_is_root(ovcs->overlay_root)) - pr_debug("%s() ovcs->overlay_root is not root\n", __func__); - -- of_changeset_init(&ovcs->cset); -- - cnt = 0; - - /* fragment nodes */ -@@ -1013,6 +1011,7 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size, - - INIT_LIST_HEAD(&ovcs->ovcs_list); - list_add_tail(&ovcs->ovcs_list, &ovcs_list); -+ of_changeset_init(&ovcs->cset); - - /* - * Must create permanent copy of FDT because of_fdt_unflatten_tree() -diff --git a/drivers/of/platform.c b/drivers/of/platform.c -index e181c3f50f1da..bf96862cb7003 100644 ---- a/drivers/of/platform.c -+++ b/drivers/of/platform.c -@@ -741,6 +741,11 @@ static int of_platform_notify(struct notifier_block *nb, - if (of_node_check_flag(rd->dn, OF_POPULATED)) - return NOTIFY_OK; - -+ /* -+ * Clear the flag before adding the device so that fw_devlink -+ * doesn't skip adding consumers to this device. -+ */ -+ rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; - /* pdev_parent may be NULL when no bus platform device */ - pdev_parent = of_find_device_by_node(rd->dn->parent); - pdev = of_platform_device_create(rd->dn, NULL, -diff --git a/drivers/of/property.c b/drivers/of/property.c -index 134cfc980b70b..b636777e6f7c8 100644 ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -1062,20 +1062,6 @@ of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, - return of_device_get_match_data(dev); - } - --static bool of_is_ancestor_of(struct device_node *test_ancestor, -- struct device_node *child) --{ -- of_node_get(child); -- while (child) { -- if (child == test_ancestor) { -- of_node_put(child); -- return true; -- } -- child = of_get_next_parent(child); -- } -- return false; --} -- - static struct device_node *of_get_compat_node(struct device_node *np) - { - of_node_get(np); -@@ -1106,71 +1092,27 @@ static struct device_node *of_get_compat_node_parent(struct device_node *np) - return node; - } - --/** -- * of_link_to_phandle - Add fwnode link to supplier from supplier phandle -- * @con_np: consumer device tree node -- * @sup_np: supplier device tree node -- * -- * Given a phandle to a supplier device tree node (@sup_np), this function -- * finds the device that owns the supplier device tree node and creates a -- * device link from @dev consumer device to the supplier device. This function -- * doesn't create device links for invalid scenarios such as trying to create a -- * link with a parent device as the consumer of its child device. In such -- * cases, it returns an error. -- * -- * Returns: -- * - 0 if fwnode link successfully created to supplier -- * - -EINVAL if the supplier link is invalid and should not be created -- * - -ENODEV if struct device will never be create for supplier -- */ --static int of_link_to_phandle(struct device_node *con_np, -+static void of_link_to_phandle(struct device_node *con_np, - struct device_node *sup_np) - { -- struct device *sup_dev; -- struct device_node *tmp_np = sup_np; -+ struct device_node *tmp_np = of_node_get(sup_np); - -- /* -- * Find the device node that contains the supplier phandle. It may be -- * @sup_np or it may be an ancestor of @sup_np. -- */ -- sup_np = of_get_compat_node(sup_np); -- if (!sup_np) { -- pr_debug("Not linking %pOFP to %pOFP - No device\n", -- con_np, tmp_np); -- return -ENODEV; -- } -+ /* Check that sup_np and its ancestors are available. */ -+ while (tmp_np) { -+ if (of_fwnode_handle(tmp_np)->dev) { -+ of_node_put(tmp_np); -+ break; -+ } - -- /* -- * Don't allow linking a device node as a consumer of one of its -- * descendant nodes. By definition, a child node can't be a functional -- * dependency for the parent node. -- */ -- if (of_is_ancestor_of(con_np, sup_np)) { -- pr_debug("Not linking %pOFP to %pOFP - is descendant\n", -- con_np, sup_np); -- of_node_put(sup_np); -- return -EINVAL; -- } -+ if (!of_device_is_available(tmp_np)) { -+ of_node_put(tmp_np); -+ return; -+ } - -- /* -- * Don't create links to "early devices" that won't have struct devices -- * created for them. -- */ -- sup_dev = get_dev_from_fwnode(&sup_np->fwnode); -- if (!sup_dev && -- (of_node_check_flag(sup_np, OF_POPULATED) || -- sup_np->fwnode.flags & FWNODE_FLAG_NOT_DEVICE)) { -- pr_debug("Not linking %pOFP to %pOFP - No struct device\n", -- con_np, sup_np); -- of_node_put(sup_np); -- return -ENODEV; -+ tmp_np = of_get_next_parent(tmp_np); - } -- put_device(sup_dev); - - fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np)); -- of_node_put(sup_np); -- -- return 0; - } - - /** -@@ -1324,6 +1266,7 @@ DEFINE_SIMPLE_PROP(pwms, "pwms", "#pwm-cells") - DEFINE_SIMPLE_PROP(resets, "resets", "#reset-cells") - DEFINE_SIMPLE_PROP(leds, "leds", NULL) - DEFINE_SIMPLE_PROP(backlight, "backlight", NULL) -+DEFINE_SIMPLE_PROP(panel, "panel", NULL) - DEFINE_SUFFIX_PROP(regulators, "-supply", NULL) - DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells") - -@@ -1412,6 +1355,7 @@ static const struct supplier_bindings of_supplier_bindings[] = { - { .parse_prop = parse_resets, }, - { .parse_prop = parse_leds, }, - { .parse_prop = parse_backlight, }, -+ { .parse_prop = parse_panel, }, - { .parse_prop = parse_gpio_compat, }, - { .parse_prop = parse_interrupts, }, - { .parse_prop = parse_regulators, }, -diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index 9be6ed47a1ce4..edd2342598e49 100644 ---- a/drivers/of/unittest.c -+++ b/drivers/of/unittest.c -@@ -70,7 +70,7 @@ static void __init of_unittest_find_node_by_name(void) - - np = of_find_node_by_path("/testcase-data"); - name = kasprintf(GFP_KERNEL, "%pOF", np); -- unittest(np && !strcmp("/testcase-data", name), -+ unittest(np && name && !strcmp("/testcase-data", name), - "find /testcase-data failed\n"); - of_node_put(np); - kfree(name); -@@ -81,14 +81,14 @@ static void __init of_unittest_find_node_by_name(void) - - np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); - name = kasprintf(GFP_KERNEL, "%pOF", np); -- unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), -+ unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name), - "find /testcase-data/phandle-tests/consumer-a failed\n"); - of_node_put(np); - kfree(name); - - np = of_find_node_by_path("testcase-alias"); - name = kasprintf(GFP_KERNEL, "%pOF", np); -- unittest(np && !strcmp("/testcase-data", name), -+ unittest(np && name && !strcmp("/testcase-data", name), - "find testcase-alias failed\n"); - of_node_put(np); - kfree(name); -@@ -99,7 +99,7 @@ static void __init of_unittest_find_node_by_name(void) - - np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a"); - name = kasprintf(GFP_KERNEL, "%pOF", np); -- unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), -+ unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name), - "find testcase-alias/phandle-tests/consumer-a failed\n"); - of_node_put(np); - kfree(name); -@@ -1379,6 +1379,8 @@ static void attach_node_and_children(struct device_node *np) - const char *full_name; - - full_name = kasprintf(GFP_KERNEL, "%pOF", np); -+ if (!full_name) -+ return; - - if (!strcmp(full_name, "/__local_fixups__") || - !strcmp(full_name, "/__fixups__")) { -@@ -2060,7 +2062,7 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr, - of_unittest_untrack_overlay(save_ovcs_id); - - /* unittest device must be again in before state */ -- if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) { -+ if (of_unittest_device_exists(unittest_nr, ovtype) != before) { - unittest(0, "%s with device @\"%s\" %s\n", - overlay_name_from_nr(overlay_nr), - unittest_path(unittest_nr, ovtype), -diff --git a/drivers/opp/core.c b/drivers/opp/core.c -index d707214069ca9..f0d70ecc0271b 100644 ---- a/drivers/opp/core.c -+++ b/drivers/opp/core.c -@@ -2372,7 +2372,7 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev, - - virt_dev = dev_pm_domain_attach_by_name(dev, *name); - if (IS_ERR_OR_NULL(virt_dev)) { -- ret = PTR_ERR(virt_dev) ? : -ENODEV; -+ ret = virt_dev ? PTR_ERR(virt_dev) : -ENODEV; - dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret); - goto err; - } -diff --git a/drivers/pci/access.c b/drivers/pci/access.c -index 708c7529647fd..3d20f9c51efe7 100644 ---- a/drivers/pci/access.c -+++ b/drivers/pci/access.c -@@ -491,8 +491,8 @@ int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) - } - EXPORT_SYMBOL(pcie_capability_write_dword); - --int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, -- u16 clear, u16 set) -+int pcie_capability_clear_and_set_word_unlocked(struct pci_dev *dev, int pos, -+ u16 clear, u16 set) - { - int ret; - u16 val; -@@ -506,7 +506,21 @@ int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, - - return ret; - } --EXPORT_SYMBOL(pcie_capability_clear_and_set_word); -+EXPORT_SYMBOL(pcie_capability_clear_and_set_word_unlocked); -+ -+int pcie_capability_clear_and_set_word_locked(struct pci_dev *dev, int pos, -+ u16 clear, u16 set) -+{ -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&dev->pcie_cap_lock, flags); -+ ret = pcie_capability_clear_and_set_word_unlocked(dev, pos, clear, set); -+ spin_unlock_irqrestore(&dev->pcie_cap_lock, flags); -+ -+ return ret; -+} -+EXPORT_SYMBOL(pcie_capability_clear_and_set_word_locked); - - int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, - u32 clear, u32 set) -diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c -index 6d0d1b759ca24..d4c566c1c8725 100644 ---- a/drivers/pci/controller/dwc/pcie-qcom-ep.c -+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c -@@ -410,7 +410,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) - /* Gate Master AXI clock to MHI bus during L1SS */ - val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); - val &= ~PARF_MSTR_AXI_CLK_EN; -- val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); -+ writel_relaxed(val, pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); - - dw_pcie_ep_init_notify(&pcie_ep->pci.ep); - -diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c -index 528e73ccfa43e..2241029537a03 100644 ---- a/drivers/pci/controller/dwc/pcie-tegra194.c -+++ b/drivers/pci/controller/dwc/pcie-tegra194.c -@@ -879,11 +879,6 @@ static int tegra_pcie_dw_host_init(struct dw_pcie_rp *pp) - pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, - PCI_CAP_ID_EXP); - -- val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL); -- val_16 &= ~PCI_EXP_DEVCTL_PAYLOAD; -- val_16 |= PCI_EXP_DEVCTL_PAYLOAD_256B; -- dw_pcie_writew_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL, val_16); -- - val = dw_pcie_readl_dbi(pci, PCI_IO_BASE); - val &= ~(IO_BASE_IO_DECODE | IO_BASE_IO_DECODE_BIT8); - dw_pcie_writel_dbi(pci, PCI_IO_BASE, val); -@@ -1872,11 +1867,6 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie) - pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, - PCI_CAP_ID_EXP); - -- val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL); -- val_16 &= ~PCI_EXP_DEVCTL_PAYLOAD; -- val_16 |= PCI_EXP_DEVCTL_PAYLOAD_256B; -- dw_pcie_writew_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL, val_16); -- - /* Clear Slot Clock Configuration bit if SRNS configuration */ - if (pcie->enable_srns) { - val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + -diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c -index 3351863352d36..9693bab59bf7c 100644 ---- a/drivers/pci/controller/pci-hyperv.c -+++ b/drivers/pci/controller/pci-hyperv.c -@@ -3930,6 +3930,9 @@ static int hv_pci_restore_msi_msg(struct pci_dev *pdev, void *arg) - struct msi_desc *entry; - int ret = 0; - -+ if (!pdev->msi_enabled && !pdev->msix_enabled) -+ return 0; -+ - msi_lock_descs(&pdev->dev); - msi_for_each_desc(entry, &pdev->dev, MSI_DESC_ASSOCIATED) { - irq_data = irq_get_irq_data(entry->irq); -diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c -index 66f37e403a09c..2340dab6cd5bd 100644 ---- a/drivers/pci/controller/pcie-apple.c -+++ b/drivers/pci/controller/pcie-apple.c -@@ -783,6 +783,10 @@ static int apple_pcie_init(struct pci_config_window *cfg) - cfg->priv = pcie; - INIT_LIST_HEAD(&pcie->ports); - -+ ret = apple_msi_init(pcie); -+ if (ret) -+ return ret; -+ - for_each_child_of_node(dev->of_node, of_port) { - ret = apple_pcie_setup_port(pcie, of_port); - if (ret) { -@@ -792,7 +796,7 @@ static int apple_pcie_init(struct pci_config_window *cfg) - } - } - -- return apple_msi_init(pcie); -+ return 0; - } - - static int apple_pcie_probe(struct platform_device *pdev) -diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c -index 7263d175b5adb..5ba101efd9326 100644 ---- a/drivers/pci/controller/pcie-microchip-host.c -+++ b/drivers/pci/controller/pcie-microchip-host.c -@@ -167,12 +167,12 @@ - #define EVENT_PCIE_DLUP_EXIT 2 - #define EVENT_SEC_TX_RAM_SEC_ERR 3 - #define EVENT_SEC_RX_RAM_SEC_ERR 4 --#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 5 --#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 6 -+#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 5 -+#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 6 - #define EVENT_DED_TX_RAM_DED_ERR 7 - #define EVENT_DED_RX_RAM_DED_ERR 8 --#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 9 --#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 10 -+#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 9 -+#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 10 - #define EVENT_LOCAL_DMA_END_ENGINE_0 11 - #define EVENT_LOCAL_DMA_END_ENGINE_1 12 - #define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13 -diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h -index fe0333778fd93..6111de35f84ca 100644 ---- a/drivers/pci/controller/pcie-rockchip.h -+++ b/drivers/pci/controller/pcie-rockchip.h -@@ -158,7 +158,9 @@ - #define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274) - #define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20) - --#define PCIE_ADDR_MASK 0xffffff00 -+#define MAX_AXI_IB_ROOTPORT_REGION_NUM 3 -+#define MIN_AXI_ADDR_BITS_PASSED 8 -+#define PCIE_ADDR_MASK GENMASK_ULL(63, MIN_AXI_ADDR_BITS_PASSED) - #define PCIE_CORE_AXI_CONF_BASE 0xc00000 - #define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0) - #define PCIE_CORE_OB_REGION_ADDR0_NUM_BITS 0x3f -@@ -185,8 +187,6 @@ - #define AXI_WRAPPER_TYPE1_CFG 0xb - #define AXI_WRAPPER_NOR_MSG 0xc - --#define MAX_AXI_IB_ROOTPORT_REGION_NUM 3 --#define MIN_AXI_ADDR_BITS_PASSED 8 - #define PCIE_RC_SEND_PME_OFF 0x11960 - #define ROCKCHIP_VENDOR_ID 0x1d87 - #define PCIE_LINK_IS_L2(x) \ -diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c -index e5e9b287b9766..c1776f82b7fce 100644 ---- a/drivers/pci/doe.c -+++ b/drivers/pci/doe.c -@@ -223,8 +223,8 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas - static void signal_task_complete(struct pci_doe_task *task, int rv) - { - task->rv = rv; -- task->complete(task); - destroy_work_on_stack(&task->work); -+ task->complete(task); - } - - static void signal_task_abort(struct pci_doe_task *task, int rv) -diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c -index 112c8f401ac4e..358f077284cbe 100644 ---- a/drivers/pci/hotplug/pciehp_hpc.c -+++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -332,17 +332,11 @@ int pciehp_check_link_status(struct controller *ctrl) - static int __pciehp_link_set(struct controller *ctrl, bool enable) - { - struct pci_dev *pdev = ctrl_dev(ctrl); -- u16 lnk_ctrl; - -- pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnk_ctrl); -+ pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_LD, -+ enable ? 0 : PCI_EXP_LNKCTL_LD); - -- if (enable) -- lnk_ctrl &= ~PCI_EXP_LNKCTL_LD; -- else -- lnk_ctrl |= PCI_EXP_LNKCTL_LD; -- -- pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnk_ctrl); -- ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl); - return 0; - } - -diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c -index ba38fc47d35e9..dd0d9d9bc5097 100644 ---- a/drivers/pci/pci-sysfs.c -+++ b/drivers/pci/pci-sysfs.c -@@ -756,6 +756,13 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj, - if (ret) - return ret; - -+ if (resource_is_exclusive(&dev->driver_exclusive_resource, off, -+ count)) { -+ pci_warn_once(dev, "%s: Unexpected write to kernel-exclusive config offset %llx", -+ current->comm, off); -+ add_taint(TAINT_USER, LOCKDEP_STILL_OK); -+ } -+ - if (off > dev->cfg_size) - return 0; - if (off + count > dev->cfg_size) { -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index 88c4372499825..835e9ea14b3a1 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -1193,6 +1193,10 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) - * - * On success, return 0 or 1, depending on whether or not it is necessary to - * restore the device's BARs subsequently (1 is returned in that case). -+ * -+ * On failure, return a negative error code. Always return failure if @dev -+ * lacks a Power Management Capability, even if the platform was able to -+ * put the device in D0 via non-PCI means. - */ - int pci_power_up(struct pci_dev *dev) - { -@@ -1209,9 +1213,6 @@ int pci_power_up(struct pci_dev *dev) - else - dev->current_state = state; - -- if (state == PCI_D0) -- return 0; -- - return -EIO; - } - -@@ -1269,8 +1270,12 @@ static int pci_set_full_power_state(struct pci_dev *dev) - int ret; - - ret = pci_power_up(dev); -- if (ret < 0) -+ if (ret < 0) { -+ if (dev->current_state == PCI_D0) -+ return 0; -+ - return ret; -+ } - - pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); - dev->current_state = pmcsr & PCI_PM_CTRL_STATE_MASK; -diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c -index 07166a4ec27ad..7e89cdbd446fc 100644 ---- a/drivers/pci/pcie/aspm.c -+++ b/drivers/pci/pcie/aspm.c -@@ -250,7 +250,7 @@ static int pcie_retrain_link(struct pcie_link_state *link) - static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) - { - int same_clock = 1; -- u16 reg16, parent_reg, child_reg[8]; -+ u16 reg16, ccc, parent_old_ccc, child_old_ccc[8]; - struct pci_dev *child, *parent = link->pdev; - struct pci_bus *linkbus = parent->subordinate; - /* -@@ -272,6 +272,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) - - /* Port might be already in common clock mode */ - pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); -+ parent_old_ccc = reg16 & PCI_EXP_LNKCTL_CCC; - if (same_clock && (reg16 & PCI_EXP_LNKCTL_CCC)) { - bool consistent = true; - -@@ -288,34 +289,29 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) - pci_info(parent, "ASPM: current common clock configuration is inconsistent, reconfiguring\n"); - } - -+ ccc = same_clock ? PCI_EXP_LNKCTL_CCC : 0; - /* Configure downstream component, all functions */ - list_for_each_entry(child, &linkbus->devices, bus_list) { - pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16); -- child_reg[PCI_FUNC(child->devfn)] = reg16; -- if (same_clock) -- reg16 |= PCI_EXP_LNKCTL_CCC; -- else -- reg16 &= ~PCI_EXP_LNKCTL_CCC; -- pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16); -+ child_old_ccc[PCI_FUNC(child->devfn)] = reg16 & PCI_EXP_LNKCTL_CCC; -+ pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_CCC, ccc); - } - - /* Configure upstream component */ -- pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); -- parent_reg = reg16; -- if (same_clock) -- reg16 |= PCI_EXP_LNKCTL_CCC; -- else -- reg16 &= ~PCI_EXP_LNKCTL_CCC; -- pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); -+ pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_CCC, ccc); - - if (pcie_retrain_link(link)) { - - /* Training failed. Restore common clock configurations */ - pci_err(parent, "ASPM: Could not configure common clock\n"); - list_for_each_entry(child, &linkbus->devices, bus_list) -- pcie_capability_write_word(child, PCI_EXP_LNKCTL, -- child_reg[PCI_FUNC(child->devfn)]); -- pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); -+ pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_CCC, -+ child_old_ccc[PCI_FUNC(child->devfn)]); -+ pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_CCC, parent_old_ccc); - } - } - -diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c -index 7170516298b0b..0945f50fe94ff 100644 ---- a/drivers/pci/probe.c -+++ b/drivers/pci/probe.c -@@ -996,6 +996,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge) - res = window->res; - if (!res->flags && !res->start && !res->end) { - release_resource(res); -+ resource_list_destroy_entry(window); - continue; - } - -@@ -2306,6 +2307,13 @@ struct pci_dev *pci_alloc_dev(struct pci_bus *bus) - INIT_LIST_HEAD(&dev->bus_list); - dev->dev.type = &pci_dev_type; - dev->bus = pci_bus_get(bus); -+ dev->driver_exclusive_resource = (struct resource) { -+ .name = "PCI Exclusive", -+ .start = 0, -+ .end = -1, -+ }; -+ -+ spin_lock_init(&dev->pcie_cap_lock); - #ifdef CONFIG_PCI_MSI - raw_spin_lock_init(&dev->msi_lock); - #endif -diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c -index 8e058e08fe810..cd4ce2b4906d1 100644 ---- a/drivers/perf/fsl_imx8_ddr_perf.c -+++ b/drivers/perf/fsl_imx8_ddr_perf.c -@@ -102,6 +102,7 @@ struct ddr_pmu { - const struct fsl_ddr_devtype_data *devtype_data; - int irq; - int id; -+ int active_counter; - }; - - static ssize_t ddr_perf_identifier_show(struct device *dev, -@@ -496,6 +497,10 @@ static void ddr_perf_event_start(struct perf_event *event, int flags) - - ddr_perf_counter_enable(pmu, event->attr.config, counter, true); - -+ if (!pmu->active_counter++) -+ ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID, -+ EVENT_CYCLES_COUNTER, true); -+ - hwc->state = 0; - } - -@@ -550,6 +555,10 @@ static void ddr_perf_event_stop(struct perf_event *event, int flags) - ddr_perf_counter_enable(pmu, event->attr.config, counter, false); - ddr_perf_event_update(event); - -+ if (!--pmu->active_counter) -+ ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID, -+ EVENT_CYCLES_COUNTER, false); -+ - hwc->state |= PERF_HES_STOPPED; - } - -@@ -568,25 +577,10 @@ static void ddr_perf_event_del(struct perf_event *event, int flags) - - static void ddr_perf_pmu_enable(struct pmu *pmu) - { -- struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu); -- -- /* enable cycle counter if cycle is not active event list */ -- if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL) -- ddr_perf_counter_enable(ddr_pmu, -- EVENT_CYCLES_ID, -- EVENT_CYCLES_COUNTER, -- true); - } - - static void ddr_perf_pmu_disable(struct pmu *pmu) - { -- struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu); -- -- if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL) -- ddr_perf_counter_enable(ddr_pmu, -- EVENT_CYCLES_ID, -- EVENT_CYCLES_COUNTER, -- false); - } - - static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base, -diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c -index 6170f8fd118e2..d0319bee01c0f 100644 ---- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c -+++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c -@@ -214,8 +214,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_suspend(struct device *dev) - if (!hsphy->phy_initialized) - return 0; - -- qcom_snps_hsphy_suspend(hsphy); -- return 0; -+ return qcom_snps_hsphy_suspend(hsphy); - } - - static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) -@@ -225,8 +224,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) - if (!hsphy->phy_initialized) - return 0; - -- qcom_snps_hsphy_resume(hsphy); -- return 0; -+ return qcom_snps_hsphy_resume(hsphy); - } - - static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode, -diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -index 80acca4e9e146..2556caf475c0c 100644 ---- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c -@@ -745,10 +745,12 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, - do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); - } - -- inno->pixclock = vco; -- dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock); -+ inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000; - -- return vco; -+ dev_dbg(inno->dev, "%s rate %lu vco %llu\n", -+ __func__, inno->pixclock, vco); -+ -+ return inno->pixclock; - } - - static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, -@@ -790,8 +792,8 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, - RK3328_PRE_PLL_POWER_DOWN); - - /* Configure pre-pll */ -- inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK, -- RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); -+ inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK, -+ RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); - inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv)); - - val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE; -@@ -1021,9 +1023,10 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno, - - inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv)); - if (cfg->postdiv == 1) { -- inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS); - inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | - RK3328_POST_PLL_PRE_DIV(cfg->prediv)); -+ inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS | -+ RK3328_POST_PLL_POWER_DOWN); - } else { - v = (cfg->postdiv / 2) - 1; - v &= RK3328_POST_PLL_POST_DIV_MASK; -@@ -1031,7 +1034,8 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno, - inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | - RK3328_POST_PLL_PRE_DIV(cfg->prediv)); - inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE | -- RK3328_POST_PLL_REFCLK_SEL_TMDS); -+ RK3328_POST_PLL_REFCLK_SEL_TMDS | -+ RK3328_POST_PLL_POWER_DOWN); - } - - for (v = 0; v < 14; v++) -diff --git a/drivers/pinctrl/pinctrl-mcp23s08_spi.c b/drivers/pinctrl/pinctrl-mcp23s08_spi.c -index 9ae10318f6f35..ea059b9c5542e 100644 ---- a/drivers/pinctrl/pinctrl-mcp23s08_spi.c -+++ b/drivers/pinctrl/pinctrl-mcp23s08_spi.c -@@ -91,18 +91,28 @@ static int mcp23s08_spi_regmap_init(struct mcp23s08 *mcp, struct device *dev, - mcp->reg_shift = 0; - mcp->chip.ngpio = 8; - mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s08.%d", addr); -+ if (!mcp->chip.label) -+ return -ENOMEM; - - config = &mcp23x08_regmap; - name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr); -+ if (!name) -+ return -ENOMEM; -+ - break; - - case MCP_TYPE_S17: - mcp->reg_shift = 1; - mcp->chip.ngpio = 16; - mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s17.%d", addr); -+ if (!mcp->chip.label) -+ return -ENOMEM; - - config = &mcp23x17_regmap; - name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr); -+ if (!name) -+ return -ENOMEM; -+ - break; - - case MCP_TYPE_S18: -diff --git a/drivers/platform/chrome/chromeos_acpi.c b/drivers/platform/chrome/chromeos_acpi.c -index 50d8a4d4352d6..1312aaaa8750b 100644 ---- a/drivers/platform/chrome/chromeos_acpi.c -+++ b/drivers/platform/chrome/chromeos_acpi.c -@@ -90,7 +90,36 @@ static int chromeos_acpi_handle_package(struct device *dev, union acpi_object *o - case ACPI_TYPE_STRING: - return sysfs_emit(buf, "%s\n", element->string.pointer); - case ACPI_TYPE_BUFFER: -- return sysfs_emit(buf, "%s\n", element->buffer.pointer); -+ { -+ int i, r, at, room_left; -+ const int byte_per_line = 16; -+ -+ at = 0; -+ room_left = PAGE_SIZE - 1; -+ for (i = 0; i < element->buffer.length && room_left; i += byte_per_line) { -+ r = hex_dump_to_buffer(element->buffer.pointer + i, -+ element->buffer.length - i, -+ byte_per_line, 1, buf + at, room_left, -+ false); -+ if (r > room_left) -+ goto truncating; -+ at += r; -+ room_left -= r; -+ -+ r = sysfs_emit_at(buf, at, "\n"); -+ if (!r) -+ goto truncating; -+ at += r; -+ room_left -= r; -+ } -+ -+ buf[at] = 0; -+ return at; -+truncating: -+ dev_info_once(dev, "truncating sysfs content for %s\n", name); -+ sysfs_emit_at(buf, PAGE_SIZE - 4, "..\n"); -+ return PAGE_SIZE - 1; -+ } - default: - dev_err(dev, "element type %d not supported\n", element->type); - return -EINVAL; -diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c -index b2e19f30a928b..d31fe7eed38df 100644 ---- a/drivers/platform/mellanox/mlxbf-tmfifo.c -+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c -@@ -868,6 +868,7 @@ static bool mlxbf_tmfifo_virtio_notify(struct virtqueue *vq) - tm_vdev = fifo->vdev[VIRTIO_ID_CONSOLE]; - mlxbf_tmfifo_console_output(tm_vdev, vring); - spin_unlock_irqrestore(&fifo->spin_lock[0], flags); -+ set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events); - } else if (test_and_set_bit(MLXBF_TM_TX_LWM_IRQ, - &fifo->pend_events)) { - return true; -diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c -index 8a38cd94a605d..d10c097380c56 100644 ---- a/drivers/platform/x86/amd/pmf/core.c -+++ b/drivers/platform/x86/amd/pmf/core.c -@@ -322,7 +322,8 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev) - - static void amd_pmf_deinit_features(struct amd_pmf_dev *dev) - { -- if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { -+ if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR) || -+ is_apmf_func_supported(dev, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { - power_supply_unreg_notifier(&dev->pwr_src_notifier); - amd_pmf_deinit_sps(dev); - } -diff --git a/drivers/platform/x86/amd/pmf/sps.c b/drivers/platform/x86/amd/pmf/sps.c -index fd448844de206..b2cf62937227c 100644 ---- a/drivers/platform/x86/amd/pmf/sps.c -+++ b/drivers/platform/x86/amd/pmf/sps.c -@@ -121,7 +121,8 @@ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf) - - int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev) - { -- u8 mode, flag = 0; -+ u8 flag = 0; -+ int mode; - int src; - - mode = amd_pmf_get_pprof_modes(dev); -diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 02bf286924183..36effe04c6f33 100644 ---- a/drivers/platform/x86/asus-wmi.c -+++ b/drivers/platform/x86/asus-wmi.c -@@ -738,13 +738,23 @@ static ssize_t kbd_rgb_mode_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) - { -- u32 cmd, mode, r, g, b, speed; -+ u32 cmd, mode, r, g, b, speed; - int err; - - if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6) - return -EINVAL; - -- cmd = !!cmd; -+ /* B3 is set and B4 is save to BIOS */ -+ switch (cmd) { -+ case 0: -+ cmd = 0xb3; -+ break; -+ case 1: -+ cmd = 0xb4; -+ break; -+ default: -+ return -EINVAL; -+ } - - /* These are the known usable modes across all TUF/ROG */ - if (mode >= 12 || mode == 9) -diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c -index 0a6411a8a104c..b2406a595be9a 100644 ---- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c -+++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c -@@ -396,6 +396,7 @@ static int init_bios_attributes(int attr_type, const char *guid) - struct kobject *attr_name_kobj; //individual attribute names - union acpi_object *obj = NULL; - union acpi_object *elements; -+ struct kobject *duplicate; - struct kset *tmp_set; - int min_elements; - -@@ -454,9 +455,11 @@ static int init_bios_attributes(int attr_type, const char *guid) - else - tmp_set = wmi_priv.main_dir_kset; - -- if (kset_find_obj(tmp_set, elements[ATTR_NAME].string.pointer)) { -- pr_debug("duplicate attribute name found - %s\n", -- elements[ATTR_NAME].string.pointer); -+ duplicate = kset_find_obj(tmp_set, elements[ATTR_NAME].string.pointer); -+ if (duplicate) { -+ pr_debug("Duplicate attribute name found - %s\n", -+ elements[ATTR_NAME].string.pointer); -+ kobject_put(duplicate); - goto nextobj; - } - -diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c -index b85050e4a0d65..ae5daecff1771 100644 ---- a/drivers/platform/x86/huawei-wmi.c -+++ b/drivers/platform/x86/huawei-wmi.c -@@ -86,6 +86,8 @@ static const struct key_entry huawei_wmi_keymap[] = { - { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, - { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, - { KE_IGNORE, 0x295, { KEY_KBDILLUMUP } }, -+ // Ignore Ambient Light Sensoring -+ { KE_KEY, 0x2c1, { KEY_RESERVED } }, - { KE_END, 0 } - }; - -diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c -index b6313ecd190c0..b96ef0eb82aff 100644 ---- a/drivers/platform/x86/intel/hid.c -+++ b/drivers/platform/x86/intel/hid.c -@@ -131,6 +131,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go"), - }, - }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "HP"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite Dragonfly G2 Notebook PC"), -+ }, -+ }, - { } - }; - -@@ -601,7 +607,7 @@ static bool button_array_present(struct platform_device *device) - static int intel_hid_probe(struct platform_device *device) - { - acpi_handle handle = ACPI_HANDLE(&device->dev); -- unsigned long long mode; -+ unsigned long long mode, dummy; - struct intel_hid_priv *priv; - acpi_status status; - int err; -@@ -666,18 +672,15 @@ static int intel_hid_probe(struct platform_device *device) - if (err) - goto err_remove_notify; - -- if (priv->array) { -- unsigned long long dummy; -+ intel_button_array_enable(&device->dev, true); - -- intel_button_array_enable(&device->dev, true); -- -- /* Call button load method to enable HID power button */ -- if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, -- &dummy)) { -- dev_warn(&device->dev, -- "failed to enable HID power button\n"); -- } -- } -+ /* -+ * Call button load method to enable HID power button -+ * Always do this since it activates events on some devices without -+ * a button array too. -+ */ -+ if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, &dummy)) -+ dev_warn(&device->dev, "failed to enable HID power button\n"); - - device_init_wakeup(&device->dev, true); - /* -diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c -index 3cbb92b6c5215..f6290221d139d 100644 ---- a/drivers/platform/x86/think-lmi.c -+++ b/drivers/platform/x86/think-lmi.c -@@ -719,12 +719,12 @@ static ssize_t cert_to_password_store(struct kobject *kobj, - /* Format: 'Password,Signature' */ - auth_str = kasprintf(GFP_KERNEL, "%s,%s", passwd, setting->signature); - if (!auth_str) { -- kfree(passwd); -+ kfree_sensitive(passwd); - return -ENOMEM; - } - ret = tlmi_simple_call(LENOVO_CERT_TO_PASSWORD_GUID, auth_str); - kfree(auth_str); -- kfree(passwd); -+ kfree_sensitive(passwd); - - return ret ?: count; - } -diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c -index 67e7664efb0dc..cb8f65c1d4e3b 100644 ---- a/drivers/rpmsg/qcom_glink_native.c -+++ b/drivers/rpmsg/qcom_glink_native.c -@@ -224,6 +224,10 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink, - - channel->glink = glink; - channel->name = kstrdup(name, GFP_KERNEL); -+ if (!channel->name) { -+ kfree(channel); -+ return ERR_PTR(-ENOMEM); -+ } - - init_completion(&channel->open_req); - init_completion(&channel->open_ack); -diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c -index bce3422d85640..04d9b1d4b1ba9 100644 ---- a/drivers/s390/block/dasd.c -+++ b/drivers/s390/block/dasd.c -@@ -2926,41 +2926,32 @@ static void _dasd_wake_block_flush_cb(struct dasd_ccw_req *cqr, void *data) - * Requeue a request back to the block request queue - * only works for block requests - */ --static int _dasd_requeue_request(struct dasd_ccw_req *cqr) -+static void _dasd_requeue_request(struct dasd_ccw_req *cqr) - { -- struct dasd_block *block = cqr->block; - struct request *req; - -- if (!block) -- return -EINVAL; - /* - * If the request is an ERP request there is nothing to requeue. - * This will be done with the remaining original request. - */ - if (cqr->refers) -- return 0; -+ return; - spin_lock_irq(&cqr->dq->lock); - req = (struct request *) cqr->callback_data; - blk_mq_requeue_request(req, true); - spin_unlock_irq(&cqr->dq->lock); - -- return 0; -+ return; - } - --/* -- * Go through all request on the dasd_block request queue, cancel them -- * on the respective dasd_device, and return them to the generic -- * block layer. -- */ --static int dasd_flush_block_queue(struct dasd_block *block) -+static int _dasd_requests_to_flushqueue(struct dasd_block *block, -+ struct list_head *flush_queue) - { - struct dasd_ccw_req *cqr, *n; -- int rc, i; -- struct list_head flush_queue; - unsigned long flags; -+ int rc, i; - -- INIT_LIST_HEAD(&flush_queue); -- spin_lock_bh(&block->queue_lock); -+ spin_lock_irqsave(&block->queue_lock, flags); - rc = 0; - restart: - list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) { -@@ -2975,13 +2966,32 @@ restart: - * is returned from the dasd_device layer. - */ - cqr->callback = _dasd_wake_block_flush_cb; -- for (i = 0; cqr != NULL; cqr = cqr->refers, i++) -- list_move_tail(&cqr->blocklist, &flush_queue); -+ for (i = 0; cqr; cqr = cqr->refers, i++) -+ list_move_tail(&cqr->blocklist, flush_queue); - if (i > 1) - /* moved more than one request - need to restart */ - goto restart; - } -- spin_unlock_bh(&block->queue_lock); -+ spin_unlock_irqrestore(&block->queue_lock, flags); -+ -+ return rc; -+} -+ -+/* -+ * Go through all request on the dasd_block request queue, cancel them -+ * on the respective dasd_device, and return them to the generic -+ * block layer. -+ */ -+static int dasd_flush_block_queue(struct dasd_block *block) -+{ -+ struct dasd_ccw_req *cqr, *n; -+ struct list_head flush_queue; -+ unsigned long flags; -+ int rc; -+ -+ INIT_LIST_HEAD(&flush_queue); -+ rc = _dasd_requests_to_flushqueue(block, &flush_queue); -+ - /* Now call the callback function of flushed requests */ - restart_cb: - list_for_each_entry_safe(cqr, n, &flush_queue, blocklist) { -@@ -3864,75 +3874,36 @@ EXPORT_SYMBOL_GPL(dasd_generic_space_avail); - */ - int dasd_generic_requeue_all_requests(struct dasd_device *device) - { -+ struct dasd_block *block = device->block; - struct list_head requeue_queue; - struct dasd_ccw_req *cqr, *n; -- struct dasd_ccw_req *refers; - int rc; - -- INIT_LIST_HEAD(&requeue_queue); -- spin_lock_irq(get_ccwdev_lock(device->cdev)); -- rc = 0; -- list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) { -- /* Check status and move request to flush_queue */ -- if (cqr->status == DASD_CQR_IN_IO) { -- rc = device->discipline->term_IO(cqr); -- if (rc) { -- /* unable to terminate requeust */ -- dev_err(&device->cdev->dev, -- "Unable to terminate request %p " -- "on suspend\n", cqr); -- spin_unlock_irq(get_ccwdev_lock(device->cdev)); -- dasd_put_device(device); -- return rc; -- } -- } -- list_move_tail(&cqr->devlist, &requeue_queue); -- } -- spin_unlock_irq(get_ccwdev_lock(device->cdev)); -- -- list_for_each_entry_safe(cqr, n, &requeue_queue, devlist) { -- wait_event(dasd_flush_wq, -- (cqr->status != DASD_CQR_CLEAR_PENDING)); -+ if (!block) -+ return 0; - -- /* -- * requeue requests to blocklayer will only work -- * for block device requests -- */ -- if (_dasd_requeue_request(cqr)) -- continue; -+ INIT_LIST_HEAD(&requeue_queue); -+ rc = _dasd_requests_to_flushqueue(block, &requeue_queue); - -- /* remove requests from device and block queue */ -- list_del_init(&cqr->devlist); -- while (cqr->refers != NULL) { -- refers = cqr->refers; -- /* remove the request from the block queue */ -- list_del(&cqr->blocklist); -- /* free the finished erp request */ -- dasd_free_erp_request(cqr, cqr->memdev); -- cqr = refers; -+ /* Now call the callback function of flushed requests */ -+restart_cb: -+ list_for_each_entry_safe(cqr, n, &requeue_queue, blocklist) { -+ wait_event(dasd_flush_wq, (cqr->status < DASD_CQR_QUEUED)); -+ /* Process finished ERP request. */ -+ if (cqr->refers) { -+ spin_lock_bh(&block->queue_lock); -+ __dasd_process_erp(block->base, cqr); -+ spin_unlock_bh(&block->queue_lock); -+ /* restart list_for_xx loop since dasd_process_erp -+ * might remove multiple elements -+ */ -+ goto restart_cb; - } -- -- /* -- * _dasd_requeue_request already checked for a valid -- * blockdevice, no need to check again -- * all erp requests (cqr->refers) have a cqr->block -- * pointer copy from the original cqr -- */ -+ _dasd_requeue_request(cqr); - list_del_init(&cqr->blocklist); - cqr->block->base->discipline->free_cp( - cqr, (struct request *) cqr->callback_data); - } -- -- /* -- * if requests remain then they are internal request -- * and go back to the device queue -- */ -- if (!list_empty(&requeue_queue)) { -- /* move freeze_queue to start of the ccw_queue */ -- spin_lock_irq(get_ccwdev_lock(device->cdev)); -- list_splice_tail(&requeue_queue, &device->ccw_queue); -- spin_unlock_irq(get_ccwdev_lock(device->cdev)); -- } - dasd_schedule_device_bh(device); - return rc; - } -diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c -index d030fe2e29643..91cb9d52a4250 100644 ---- a/drivers/s390/block/dasd_3990_erp.c -+++ b/drivers/s390/block/dasd_3990_erp.c -@@ -2441,7 +2441,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) - erp->block = cqr->block; - erp->magic = cqr->magic; - erp->expires = cqr->expires; -- erp->retries = 256; -+ erp->retries = device->default_retries; - erp->buildclk = get_tod_clock(); - erp->status = DASD_CQR_FILLED; - -diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c -index df17f0f9cb0fc..b2a4c34330573 100644 ---- a/drivers/s390/block/dasd_devmap.c -+++ b/drivers/s390/block/dasd_devmap.c -@@ -1377,16 +1377,12 @@ static ssize_t dasd_vendor_show(struct device *dev, - - static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL); - --#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\ -- /* SSID */ 4 + 1 + /* unit addr */ 2 + 1 +\ -- /* vduit */ 32 + 1) -- - static ssize_t - dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) - { -+ char uid_string[DASD_UID_STRLEN]; - struct dasd_device *device; - struct dasd_uid uid; -- char uid_string[UID_STRLEN]; - char ua_string[3]; - - device = dasd_device_from_cdev(to_ccwdev(dev)); -diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c -index 792e5d245bc38..c5619751a0658 100644 ---- a/drivers/s390/block/dasd_eckd.c -+++ b/drivers/s390/block/dasd_eckd.c -@@ -1079,12 +1079,12 @@ static void dasd_eckd_get_uid_string(struct dasd_conf *conf, - - create_uid(conf, &uid); - if (strlen(uid.vduit) > 0) -- snprintf(print_uid, sizeof(*print_uid), -+ snprintf(print_uid, DASD_UID_STRLEN, - "%s.%s.%04x.%02x.%s", - uid.vendor, uid.serial, uid.ssid, - uid.real_unit_addr, uid.vduit); - else -- snprintf(print_uid, sizeof(*print_uid), -+ snprintf(print_uid, DASD_UID_STRLEN, - "%s.%s.%04x.%02x", - uid.vendor, uid.serial, uid.ssid, - uid.real_unit_addr); -@@ -1093,8 +1093,8 @@ static void dasd_eckd_get_uid_string(struct dasd_conf *conf, - static int dasd_eckd_check_cabling(struct dasd_device *device, - void *conf_data, __u8 lpm) - { -+ char print_path_uid[DASD_UID_STRLEN], print_device_uid[DASD_UID_STRLEN]; - struct dasd_eckd_private *private = device->private; -- char print_path_uid[60], print_device_uid[60]; - struct dasd_conf path_conf; - - path_conf.data = conf_data; -@@ -1293,9 +1293,9 @@ static void dasd_eckd_path_available_action(struct dasd_device *device, - __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; - __u8 lpm, opm, npm, ppm, epm, hpfpm, cablepm; - struct dasd_conf_data *conf_data; -+ char print_uid[DASD_UID_STRLEN]; - struct dasd_conf path_conf; - unsigned long flags; -- char print_uid[60]; - int rc, pos; - - opm = 0; -@@ -5856,8 +5856,8 @@ static void dasd_eckd_dump_sense(struct dasd_device *device, - static int dasd_eckd_reload_device(struct dasd_device *device) - { - struct dasd_eckd_private *private = device->private; -+ char print_uid[DASD_UID_STRLEN]; - int rc, old_base; -- char print_uid[60]; - struct dasd_uid uid; - unsigned long flags; - -diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h -index 97adc8a7ae6b1..f50932518f83a 100644 ---- a/drivers/s390/block/dasd_int.h -+++ b/drivers/s390/block/dasd_int.h -@@ -259,6 +259,10 @@ struct dasd_uid { - char vduit[33]; - }; - -+#define DASD_UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 + \ -+ /* SSID */ 4 + 1 + /* unit addr */ 2 + 1 + \ -+ /* vduit */ 32 + 1) -+ - /* - * PPRC Status data - */ -diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c -index c0f85ffb2b62d..735ee0ca4a13b 100644 ---- a/drivers/s390/block/dcssblk.c -+++ b/drivers/s390/block/dcssblk.c -@@ -411,6 +411,7 @@ removeseg: - } - list_del(&dev_info->lh); - -+ dax_remove_host(dev_info->gd); - kill_dax(dev_info->dax_dev); - put_dax(dev_info->dax_dev); - del_gendisk(dev_info->gd); -@@ -706,9 +707,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char - goto out; - - out_dax_host: -+ put_device(&dev_info->dev); - dax_remove_host(dev_info->gd); - out_dax: -- put_device(&dev_info->dev); - kill_dax(dev_info->dax_dev); - put_dax(dev_info->dax_dev); - put_dev: -@@ -788,6 +789,7 @@ dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const ch - } - - list_del(&dev_info->lh); -+ dax_remove_host(dev_info->gd); - kill_dax(dev_info->dax_dev); - put_dax(dev_info->dax_dev); - del_gendisk(dev_info->gd); -diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c -index a8def50c149bd..2b92ec20ed68e 100644 ---- a/drivers/s390/crypto/pkey_api.c -+++ b/drivers/s390/crypto/pkey_api.c -@@ -565,6 +565,11 @@ static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns, - if (*keybufsize < MINEP11AESKEYBLOBSIZE) - return -EINVAL; - break; -+ case PKEY_TYPE_EP11_AES: -+ if (*keybufsize < (sizeof(struct ep11kblob_header) + -+ MINEP11AESKEYBLOBSIZE)) -+ return -EINVAL; -+ break; - default: - return -EINVAL; - } -@@ -581,9 +586,10 @@ static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns, - for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { - card = apqns[i].card; - dom = apqns[i].domain; -- if (ktype == PKEY_TYPE_EP11) { -+ if (ktype == PKEY_TYPE_EP11 || -+ ktype == PKEY_TYPE_EP11_AES) { - rc = ep11_genaeskey(card, dom, ksize, kflags, -- keybuf, keybufsize); -+ keybuf, keybufsize, ktype); - } else if (ktype == PKEY_TYPE_CCA_DATA) { - rc = cca_genseckey(card, dom, ksize, keybuf); - *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); -@@ -747,7 +753,7 @@ static int pkey_verifykey2(const u8 *key, size_t keylen, - if (ktype) - *ktype = PKEY_TYPE_EP11; - if (ksize) -- *ksize = kb->head.keybitlen; -+ *ksize = kb->head.bitlen; - - rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, - ZCRYPT_CEX7, EP11_API_V, kb->wkvp); -@@ -1313,7 +1319,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, - apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries); - if (IS_ERR(apqns)) - return PTR_ERR(apqns); -- kkey = kmalloc(klen, GFP_KERNEL); -+ kkey = kzalloc(klen, GFP_KERNEL); - if (!kkey) { - kfree(apqns); - return -ENOMEM; -@@ -1941,7 +1947,7 @@ static struct attribute_group ccacipher_attr_group = { - * (i.e. off != 0 or count < key blob size) -EINVAL is returned. - * This function and the sysfs attributes using it provide EP11 key blobs - * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently -- * 320 bytes. -+ * 336 bytes. - */ - static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits, - bool is_xts, char *buf, loff_t off, -@@ -1969,7 +1975,8 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits, - for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { - card = apqns[i] >> 16; - dom = apqns[i] & 0xFFFF; -- rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize); -+ rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize, -+ PKEY_TYPE_EP11_AES); - if (rc == 0) - break; - } -@@ -1979,7 +1986,8 @@ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits, - if (is_xts) { - keysize = MAXEP11AESKEYBLOBSIZE; - buf += MAXEP11AESKEYBLOBSIZE; -- rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize); -+ rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize, -+ PKEY_TYPE_EP11_AES); - if (rc == 0) - return 2 * MAXEP11AESKEYBLOBSIZE; - } -diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c -index b1c29017be5bc..20bbeec1a1a22 100644 ---- a/drivers/s390/crypto/zcrypt_ep11misc.c -+++ b/drivers/s390/crypto/zcrypt_ep11misc.c -@@ -113,6 +113,50 @@ static void __exit card_cache_free(void) - spin_unlock_bh(&card_list_lock); - } - -+static int ep11_kb_split(const u8 *kb, size_t kblen, u32 kbver, -+ struct ep11kblob_header **kbhdr, size_t *kbhdrsize, -+ u8 **kbpl, size_t *kbplsize) -+{ -+ struct ep11kblob_header *hdr = NULL; -+ size_t hdrsize, plsize = 0; -+ int rc = -EINVAL; -+ u8 *pl = NULL; -+ -+ if (kblen < sizeof(struct ep11kblob_header)) -+ goto out; -+ hdr = (struct ep11kblob_header *)kb; -+ -+ switch (kbver) { -+ case TOKVER_EP11_AES: -+ /* header overlays the payload */ -+ hdrsize = 0; -+ break; -+ case TOKVER_EP11_ECC_WITH_HEADER: -+ case TOKVER_EP11_AES_WITH_HEADER: -+ /* payload starts after the header */ -+ hdrsize = sizeof(struct ep11kblob_header); -+ break; -+ default: -+ goto out; -+ } -+ -+ plsize = kblen - hdrsize; -+ pl = (u8 *)kb + hdrsize; -+ -+ if (kbhdr) -+ *kbhdr = hdr; -+ if (kbhdrsize) -+ *kbhdrsize = hdrsize; -+ if (kbpl) -+ *kbpl = pl; -+ if (kbplsize) -+ *kbplsize = plsize; -+ -+ rc = 0; -+out: -+ return rc; -+} -+ - /* - * Simple check if the key blob is a valid EP11 AES key blob with header. - */ -@@ -664,8 +708,9 @@ EXPORT_SYMBOL(ep11_get_domain_info); - */ - #define KEY_ATTR_DEFAULTS 0x00200c00 - --int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, -- u8 *keybuf, size_t *keybufsize) -+static int _ep11_genaeskey(u16 card, u16 domain, -+ u32 keybitsize, u32 keygenflags, -+ u8 *keybuf, size_t *keybufsize) - { - struct keygen_req_pl { - struct pl_head head; -@@ -701,7 +746,6 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - struct ep11_cprb *req = NULL, *rep = NULL; - struct ep11_target_dev target; - struct ep11_urb *urb = NULL; -- struct ep11keyblob *kb; - int api, rc = -ENOMEM; - - switch (keybitsize) { -@@ -780,14 +824,9 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - goto out; - } - -- /* copy key blob and set header values */ -+ /* copy key blob */ - memcpy(keybuf, rep_pl->data, rep_pl->data_len); - *keybufsize = rep_pl->data_len; -- kb = (struct ep11keyblob *)keybuf; -- kb->head.type = TOKTYPE_NON_CCA; -- kb->head.len = rep_pl->data_len; -- kb->head.version = TOKVER_EP11_AES; -- kb->head.keybitlen = keybitsize; - - out: - kfree(req); -@@ -795,6 +834,43 @@ out: - kfree(urb); - return rc; - } -+ -+int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, -+ u8 *keybuf, size_t *keybufsize, u32 keybufver) -+{ -+ struct ep11kblob_header *hdr; -+ size_t hdr_size, pl_size; -+ u8 *pl; -+ int rc; -+ -+ switch (keybufver) { -+ case TOKVER_EP11_AES: -+ case TOKVER_EP11_AES_WITH_HEADER: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ rc = ep11_kb_split(keybuf, *keybufsize, keybufver, -+ &hdr, &hdr_size, &pl, &pl_size); -+ if (rc) -+ return rc; -+ -+ rc = _ep11_genaeskey(card, domain, keybitsize, keygenflags, -+ pl, &pl_size); -+ if (rc) -+ return rc; -+ -+ *keybufsize = hdr_size + pl_size; -+ -+ /* update header information */ -+ hdr->type = TOKTYPE_NON_CCA; -+ hdr->len = *keybufsize; -+ hdr->version = keybufver; -+ hdr->bitlen = keybitsize; -+ -+ return 0; -+} - EXPORT_SYMBOL(ep11_genaeskey); - - static int ep11_cryptsingle(u16 card, u16 domain, -@@ -1055,7 +1131,7 @@ static int ep11_unwrapkey(u16 card, u16 domain, - kb->head.type = TOKTYPE_NON_CCA; - kb->head.len = rep_pl->data_len; - kb->head.version = TOKVER_EP11_AES; -- kb->head.keybitlen = keybitsize; -+ kb->head.bitlen = keybitsize; - - out: - kfree(req); -@@ -1201,7 +1277,6 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - const u8 *clrkey, u8 *keybuf, size_t *keybufsize) - { - int rc; -- struct ep11keyblob *kb; - u8 encbuf[64], *kek = NULL; - size_t clrkeylen, keklen, encbuflen = sizeof(encbuf); - -@@ -1223,17 +1298,15 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - } - - /* Step 1: generate AES 256 bit random kek key */ -- rc = ep11_genaeskey(card, domain, 256, -- 0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */ -- kek, &keklen); -+ rc = _ep11_genaeskey(card, domain, 256, -+ 0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */ -+ kek, &keklen); - if (rc) { - DEBUG_ERR( - "%s generate kek key failed, rc=%d\n", - __func__, rc); - goto out; - } -- kb = (struct ep11keyblob *)kek; -- memset(&kb->head, 0, sizeof(kb->head)); - - /* Step 2: encrypt clear key value with the kek key */ - rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen, -diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h -index 07445041869fe..ed328c354bade 100644 ---- a/drivers/s390/crypto/zcrypt_ep11misc.h -+++ b/drivers/s390/crypto/zcrypt_ep11misc.h -@@ -29,14 +29,7 @@ struct ep11keyblob { - union { - u8 session[32]; - /* only used for PKEY_TYPE_EP11: */ -- struct { -- u8 type; /* 0x00 (TOKTYPE_NON_CCA) */ -- u8 res0; /* unused */ -- u16 len; /* total length in bytes of this blob */ -- u8 version; /* 0x03 (TOKVER_EP11_AES) */ -- u8 res1; /* unused */ -- u16 keybitlen; /* clear key bit len, 0 for unknown */ -- } head; -+ struct ep11kblob_header head; - }; - u8 wkvp[16]; /* wrapping key verification pattern */ - u64 attr; /* boolean key attributes */ -@@ -114,7 +107,7 @@ int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info); - * Generate (random) EP11 AES secure key. - */ - int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, -- u8 *keybuf, size_t *keybufsize); -+ u8 *keybuf, size_t *keybufsize, u32 keybufver); - - /* - * Generate EP11 AES secure key with given clear key value. -diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h -index 5e115e8b2ba46..7c6efde75da66 100644 ---- a/drivers/scsi/aacraid/aacraid.h -+++ b/drivers/scsi/aacraid/aacraid.h -@@ -1678,6 +1678,7 @@ struct aac_dev - u32 handle_pci_error; - bool init_reset; - u8 soft_reset_support; -+ u8 use_map_queue; - }; - - #define aac_adapter_interrupt(dev) \ -diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c -index deb32c9f4b3e6..3f062e4013ab6 100644 ---- a/drivers/scsi/aacraid/commsup.c -+++ b/drivers/scsi/aacraid/commsup.c -@@ -223,8 +223,12 @@ int aac_fib_setup(struct aac_dev * dev) - struct fib *aac_fib_alloc_tag(struct aac_dev *dev, struct scsi_cmnd *scmd) - { - struct fib *fibptr; -+ u32 blk_tag; -+ int i; - -- fibptr = &dev->fibs[scsi_cmd_to_rq(scmd)->tag]; -+ blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); -+ i = blk_mq_unique_tag_to_tag(blk_tag); -+ fibptr = &dev->fibs[i]; - /* - * Null out fields that depend on being zero at the start of - * each I/O -diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c -index 5ba5c18b77b46..bff49b8ab057d 100644 ---- a/drivers/scsi/aacraid/linit.c -+++ b/drivers/scsi/aacraid/linit.c -@@ -19,6 +19,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -505,6 +506,15 @@ common_config: - return 0; - } - -+static void aac_map_queues(struct Scsi_Host *shost) -+{ -+ struct aac_dev *aac = (struct aac_dev *)shost->hostdata; -+ -+ blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], -+ aac->pdev, 0); -+ aac->use_map_queue = true; -+} -+ - /** - * aac_change_queue_depth - alter queue depths - * @sdev: SCSI device we are considering -@@ -1489,6 +1499,7 @@ static struct scsi_host_template aac_driver_template = { - .bios_param = aac_biosparm, - .shost_groups = aac_host_groups, - .slave_configure = aac_slave_configure, -+ .map_queues = aac_map_queues, - .change_queue_depth = aac_change_queue_depth, - .sdev_groups = aac_dev_groups, - .eh_abort_handler = aac_eh_abort, -@@ -1776,6 +1787,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) - shost->max_lun = AAC_MAX_LUN; - - pci_set_drvdata(pdev, shost); -+ shost->nr_hw_queues = aac->max_msix; -+ shost->host_tagset = 1; - - error = scsi_add_host(shost, &pdev->dev); - if (error) -@@ -1908,6 +1921,7 @@ static void aac_remove_one(struct pci_dev *pdev) - struct aac_dev *aac = (struct aac_dev *)shost->hostdata; - - aac_cancel_rescan_worker(aac); -+ aac->use_map_queue = false; - scsi_remove_host(shost); - - __aac_shutdown(aac); -diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c -index 11ef58204e96f..61949f3741886 100644 ---- a/drivers/scsi/aacraid/src.c -+++ b/drivers/scsi/aacraid/src.c -@@ -493,6 +493,10 @@ static int aac_src_deliver_message(struct fib *fib) - #endif - - u16 vector_no; -+ struct scsi_cmnd *scmd; -+ u32 blk_tag; -+ struct Scsi_Host *shost = dev->scsi_host_ptr; -+ struct blk_mq_queue_map *qmap; - - atomic_inc(&q->numpending); - -@@ -505,8 +509,25 @@ static int aac_src_deliver_message(struct fib *fib) - if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) - && dev->sa_firmware) - vector_no = aac_get_vector(dev); -- else -- vector_no = fib->vector_no; -+ else { -+ if (!fib->vector_no || !fib->callback_data) { -+ if (shost && dev->use_map_queue) { -+ qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; -+ vector_no = qmap->mq_map[raw_smp_processor_id()]; -+ } -+ /* -+ * We hardcode the vector_no for -+ * reserved commands as a valid shost is -+ * absent during the init -+ */ -+ else -+ vector_no = 0; -+ } else { -+ scmd = (struct scsi_cmnd *)fib->callback_data; -+ blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); -+ vector_no = blk_mq_unique_tag_to_hwq(blk_tag); -+ } -+ } - - if (native_hba) { - if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) { -diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c -index 8aeaddc93b167..8d374ae863ba2 100644 ---- a/drivers/scsi/be2iscsi/be_iscsi.c -+++ b/drivers/scsi/be2iscsi/be_iscsi.c -@@ -450,6 +450,10 @@ int beiscsi_iface_set_param(struct Scsi_Host *shost, - } - - nla_for_each_attr(attrib, data, dt_len, rm_len) { -+ /* ignore nla_type as it is never used */ -+ if (nla_len(attrib) < sizeof(*iface_param)) -+ return -EINVAL; -+ - iface_param = nla_data(attrib); - - if (iface_param->param_type != ISCSI_NET_PARAM) -diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c -index ddc048069af25..8a4124e7d2043 100644 ---- a/drivers/scsi/fcoe/fcoe_ctlr.c -+++ b/drivers/scsi/fcoe/fcoe_ctlr.c -@@ -319,16 +319,17 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) - { - struct fcoe_fcf *sel; - struct fcoe_fcf *fcf; -+ unsigned long flags; - - mutex_lock(&fip->ctlr_mutex); -- spin_lock_bh(&fip->ctlr_lock); -+ spin_lock_irqsave(&fip->ctlr_lock, flags); - - kfree_skb(fip->flogi_req); - fip->flogi_req = NULL; - list_for_each_entry(fcf, &fip->fcfs, list) - fcf->flogi_sent = 0; - -- spin_unlock_bh(&fip->ctlr_lock); -+ spin_unlock_irqrestore(&fip->ctlr_lock, flags); - sel = fip->sel_fcf; - - if (sel && ether_addr_equal(sel->fcf_mac, fip->dest_addr)) -@@ -699,6 +700,7 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, - { - struct fc_frame *fp; - struct fc_frame_header *fh; -+ unsigned long flags; - u16 old_xid; - u8 op; - u8 mac[ETH_ALEN]; -@@ -732,11 +734,11 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, - op = FIP_DT_FLOGI; - if (fip->mode == FIP_MODE_VN2VN) - break; -- spin_lock_bh(&fip->ctlr_lock); -+ spin_lock_irqsave(&fip->ctlr_lock, flags); - kfree_skb(fip->flogi_req); - fip->flogi_req = skb; - fip->flogi_req_send = 1; -- spin_unlock_bh(&fip->ctlr_lock); -+ spin_unlock_irqrestore(&fip->ctlr_lock, flags); - schedule_work(&fip->timer_work); - return -EINPROGRESS; - case ELS_FDISC: -@@ -1705,10 +1707,11 @@ static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip) - static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) - { - struct fcoe_fcf *fcf; -+ unsigned long flags; - int error; - - mutex_lock(&fip->ctlr_mutex); -- spin_lock_bh(&fip->ctlr_lock); -+ spin_lock_irqsave(&fip->ctlr_lock, flags); - LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n"); - fcf = fcoe_ctlr_select(fip); - if (!fcf || fcf->flogi_sent) { -@@ -1719,7 +1722,7 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) - fcoe_ctlr_solicit(fip, NULL); - error = fcoe_ctlr_flogi_send_locked(fip); - } -- spin_unlock_bh(&fip->ctlr_lock); -+ spin_unlock_irqrestore(&fip->ctlr_lock, flags); - mutex_unlock(&fip->ctlr_mutex); - return error; - } -@@ -1736,8 +1739,9 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) - static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) - { - struct fcoe_fcf *fcf; -+ unsigned long flags; - -- spin_lock_bh(&fip->ctlr_lock); -+ spin_lock_irqsave(&fip->ctlr_lock, flags); - fcf = fip->sel_fcf; - if (!fcf || !fip->flogi_req_send) - goto unlock; -@@ -1764,7 +1768,7 @@ static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) - } else /* XXX */ - LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n"); - unlock: -- spin_unlock_bh(&fip->ctlr_lock); -+ spin_unlock_irqrestore(&fip->ctlr_lock, flags); - } - - /** -diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c -index 02575d81afca2..50697672146ad 100644 ---- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c -+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c -@@ -2026,6 +2026,11 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, - u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type); - u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type); - u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type); -+ struct hisi_sas_complete_v2_hdr *complete_queue = -+ hisi_hba->complete_hdr[slot->cmplt_queue]; -+ struct hisi_sas_complete_v2_hdr *complete_hdr = -+ &complete_queue[slot->cmplt_queue_slot]; -+ u32 dw0 = le32_to_cpu(complete_hdr->dw0); - int error = -1; - - if (err_phase == 1) { -@@ -2310,7 +2315,8 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba, - break; - } - } -- hisi_sas_sata_done(task, slot); -+ if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) -+ hisi_sas_sata_done(task, slot); - } - break; - default: -@@ -2443,7 +2449,8 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba, - case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: - { - ts->stat = SAS_SAM_STAT_GOOD; -- hisi_sas_sata_done(task, slot); -+ if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) -+ hisi_sas_sata_done(task, slot); - break; - } - default: -diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -index e8a3511040af2..c0e74d768716d 100644 ---- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -@@ -2163,6 +2163,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, - u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type); - u16 sipc_rx_err_type = le16_to_cpu(record->sipc_rx_err_type); - u32 dw3 = le32_to_cpu(complete_hdr->dw3); -+ u32 dw0 = le32_to_cpu(complete_hdr->dw0); - - switch (task->task_proto) { - case SAS_PROTOCOL_SSP: -@@ -2172,8 +2173,8 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, - * but I/O information has been written to the host memory, we examine - * response IU. - */ -- if (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && -- (complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)) -+ if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && -+ (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)) - return false; - - ts->residual = trans_tx_fail_type; -@@ -2189,7 +2190,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, - case SAS_PROTOCOL_SATA: - case SAS_PROTOCOL_STP: - case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: -- if ((complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && -+ if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && - (sipc_rx_err_type & RX_FIS_STATUS_ERR_MSK)) { - ts->stat = SAS_PROTO_RESPONSE; - } else if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { -@@ -2202,7 +2203,8 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - } -- hisi_sas_sata_done(task, slot); -+ if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) -+ hisi_sas_sata_done(task, slot); - break; - case SAS_PROTOCOL_SMP: - ts->stat = SAS_SAM_STAT_CHECK_CONDITION; -@@ -2329,7 +2331,8 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, - case SAS_PROTOCOL_STP: - case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: - ts->stat = SAS_SAM_STAT_GOOD; -- hisi_sas_sata_done(task, slot); -+ if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) -+ hisi_sas_sata_done(task, slot); - break; - default: - ts->stat = SAS_SAM_STAT_CHECK_CONDITION; -diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c -index 45a2fd6584d16..8b825364baade 100644 ---- a/drivers/scsi/hosts.c -+++ b/drivers/scsi/hosts.c -@@ -535,7 +535,7 @@ EXPORT_SYMBOL(scsi_host_alloc); - static int __scsi_host_match(struct device *dev, const void *data) - { - struct Scsi_Host *p; -- const unsigned short *hostnum = data; -+ const unsigned int *hostnum = data; - - p = class_to_shost(dev); - return p->host_no == *hostnum; -@@ -552,7 +552,7 @@ static int __scsi_host_match(struct device *dev, const void *data) - * that scsi_host_get() took. The put_device() below dropped - * the reference from class_find_device(). - **/ --struct Scsi_Host *scsi_host_lookup(unsigned short hostnum) -+struct Scsi_Host *scsi_host_lookup(unsigned int hostnum) - { - struct device *cdev; - struct Scsi_Host *shost = NULL; -diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c -index 852b025e2fecf..b54fafb486e06 100644 ---- a/drivers/scsi/lpfc/lpfc_bsg.c -+++ b/drivers/scsi/lpfc/lpfc_bsg.c -@@ -889,7 +889,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, - struct lpfc_iocbq *piocbq) - { - uint32_t evt_req_id = 0; -- uint32_t cmd; -+ u16 cmd; - struct lpfc_dmabuf *dmabuf = NULL; - struct lpfc_bsg_event *evt; - struct event_data *evt_dat = NULL; -@@ -915,7 +915,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, - - ct_req = (struct lpfc_sli_ct_request *)bdeBuf1->virt; - evt_req_id = ct_req->FsType; -- cmd = ct_req->CommandResponse.bits.CmdRsp; -+ cmd = be16_to_cpu(ct_req->CommandResponse.bits.CmdRsp); - - spin_lock_irqsave(&phba->ct_ev_lock, flags); - list_for_each_entry(evt, &phba->ct_ev_waiters, node) { -@@ -3186,8 +3186,8 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job) - ctreq->RevisionId.bits.InId = 0; - ctreq->FsType = SLI_CT_ELX_LOOPBACK; - ctreq->FsSubType = 0; -- ctreq->CommandResponse.bits.CmdRsp = ELX_LOOPBACK_DATA; -- ctreq->CommandResponse.bits.Size = size; -+ ctreq->CommandResponse.bits.CmdRsp = cpu_to_be16(ELX_LOOPBACK_DATA); -+ ctreq->CommandResponse.bits.Size = cpu_to_be16(size); - segment_offset = ELX_LOOPBACK_HEADER_SZ; - } else - segment_offset = 0; -diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c -index 7a1563564df7f..7aac9fc719675 100644 ---- a/drivers/scsi/lpfc/lpfc_scsi.c -+++ b/drivers/scsi/lpfc/lpfc_scsi.c -@@ -109,8 +109,6 @@ lpfc_sli4_set_rsp_sgl_last(struct lpfc_hba *phba, - } - } - --#define LPFC_INVALID_REFTAG ((u32)-1) -- - /** - * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread - * @phba: The Hba for which this call is being executed. -@@ -978,8 +976,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, - - sgpe = scsi_prot_sglist(sc); - lba = scsi_prot_ref_tag(sc); -- if (lba == LPFC_INVALID_REFTAG) -- return 0; - - /* First check if we need to match the LBA */ - if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) { -@@ -1560,8 +1556,6 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, - - /* extract some info from the scsi command for pde*/ - reftag = scsi_prot_ref_tag(sc); -- if (reftag == LPFC_INVALID_REFTAG) -- goto out; - - #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); -@@ -1723,8 +1717,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, - /* extract some info from the scsi command */ - blksize = scsi_prot_interval(sc); - reftag = scsi_prot_ref_tag(sc); -- if (reftag == LPFC_INVALID_REFTAG) -- goto out; - - #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); -@@ -1954,8 +1946,6 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, - - /* extract some info from the scsi command for pde*/ - reftag = scsi_prot_ref_tag(sc); -- if (reftag == LPFC_INVALID_REFTAG) -- goto out; - - #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); -@@ -2155,8 +2145,6 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, - /* extract some info from the scsi command */ - blksize = scsi_prot_interval(sc); - reftag = scsi_prot_ref_tag(sc); -- if (reftag == LPFC_INVALID_REFTAG) -- goto out; - - #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); -@@ -2748,8 +2736,6 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) - - src = (struct scsi_dif_tuple *)sg_virt(sgpe); - start_ref_tag = scsi_prot_ref_tag(cmd); -- if (start_ref_tag == LPFC_INVALID_REFTAG) -- goto out; - start_app_tag = src->app_tag; - len = sgpe->length; - while (src && protsegcnt) { -@@ -3495,11 +3481,11 @@ err: - scsi_cmnd->sc_data_direction); - - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, -- "9084 Cannot setup S/G List for HBA" -- "IO segs %d/%d SGL %d SCSI %d: %d %d\n", -+ "9084 Cannot setup S/G List for HBA " -+ "IO segs %d/%d SGL %d SCSI %d: %d %d %d\n", - lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt, - phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt, -- prot_group_type, num_sge); -+ prot_group_type, num_sge, ret); - - lpfc_cmd->seg_cnt = 0; - lpfc_cmd->prot_seg_cnt = 0; -diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c -index 14ae0a9c5d3d8..2093888f154e0 100644 ---- a/drivers/scsi/mpt3sas/mpt3sas_base.c -+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c -@@ -139,6 +139,9 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc); - static void - _base_clear_outstanding_commands(struct MPT3SAS_ADAPTER *ioc); - -+static u32 -+_base_readl_ext_retry(const volatile void __iomem *addr); -+ - /** - * mpt3sas_base_check_cmd_timeout - Function - * to check timeout and command termination due -@@ -214,6 +217,20 @@ _base_readl_aero(const volatile void __iomem *addr) - return ret_val; - } - -+static u32 -+_base_readl_ext_retry(const volatile void __iomem *addr) -+{ -+ u32 i, ret_val; -+ -+ for (i = 0 ; i < 30 ; i++) { -+ ret_val = readl(addr); -+ if (ret_val == 0) -+ continue; -+ } -+ -+ return ret_val; -+} -+ - static inline u32 - _base_readl(const volatile void __iomem *addr) - { -@@ -941,7 +958,7 @@ mpt3sas_halt_firmware(struct MPT3SAS_ADAPTER *ioc) - - dump_stack(); - -- doorbell = ioc->base_readl(&ioc->chip->Doorbell); -+ doorbell = ioc->base_readl_ext_retry(&ioc->chip->Doorbell); - if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { - mpt3sas_print_fault_code(ioc, doorbell & - MPI2_DOORBELL_DATA_MASK); -@@ -6697,7 +6714,7 @@ mpt3sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked) - { - u32 s, sc; - -- s = ioc->base_readl(&ioc->chip->Doorbell); -+ s = ioc->base_readl_ext_retry(&ioc->chip->Doorbell); - sc = s & MPI2_IOC_STATE_MASK; - return cooked ? sc : s; - } -@@ -6842,7 +6859,7 @@ _base_wait_for_doorbell_ack(struct MPT3SAS_ADAPTER *ioc, int timeout) - __func__, count, timeout)); - return 0; - } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { -- doorbell = ioc->base_readl(&ioc->chip->Doorbell); -+ doorbell = ioc->base_readl_ext_retry(&ioc->chip->Doorbell); - if ((doorbell & MPI2_IOC_STATE_MASK) == - MPI2_IOC_STATE_FAULT) { - mpt3sas_print_fault_code(ioc, doorbell); -@@ -6882,7 +6899,7 @@ _base_wait_for_doorbell_not_used(struct MPT3SAS_ADAPTER *ioc, int timeout) - count = 0; - cntdn = 1000 * timeout; - do { -- doorbell_reg = ioc->base_readl(&ioc->chip->Doorbell); -+ doorbell_reg = ioc->base_readl_ext_retry(&ioc->chip->Doorbell); - if (!(doorbell_reg & MPI2_DOORBELL_USED)) { - dhsprintk(ioc, - ioc_info(ioc, "%s: successful count(%d), timeout(%d)\n", -@@ -7030,7 +7047,7 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes, - __le32 *mfp; - - /* make sure doorbell is not in use */ -- if ((ioc->base_readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { -+ if ((ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { - ioc_err(ioc, "doorbell is in use (line=%d)\n", __LINE__); - return -EFAULT; - } -@@ -7079,7 +7096,7 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes, - } - - /* read the first two 16-bits, it gives the total length of the reply */ -- reply[0] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell) -+ reply[0] = le16_to_cpu(ioc->base_readl_ext_retry(&ioc->chip->Doorbell) - & MPI2_DOORBELL_DATA_MASK); - writel(0, &ioc->chip->HostInterruptStatus); - if ((_base_wait_for_doorbell_int(ioc, 5))) { -@@ -7087,7 +7104,7 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes, - __LINE__); - return -EFAULT; - } -- reply[1] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell) -+ reply[1] = le16_to_cpu(ioc->base_readl_ext_retry(&ioc->chip->Doorbell) - & MPI2_DOORBELL_DATA_MASK); - writel(0, &ioc->chip->HostInterruptStatus); - -@@ -7098,10 +7115,10 @@ _base_handshake_req_reply_wait(struct MPT3SAS_ADAPTER *ioc, int request_bytes, - return -EFAULT; - } - if (i >= reply_bytes/2) /* overflow case */ -- ioc->base_readl(&ioc->chip->Doorbell); -+ ioc->base_readl_ext_retry(&ioc->chip->Doorbell); - else - reply[i] = le16_to_cpu( -- ioc->base_readl(&ioc->chip->Doorbell) -+ ioc->base_readl_ext_retry(&ioc->chip->Doorbell) - & MPI2_DOORBELL_DATA_MASK); - writel(0, &ioc->chip->HostInterruptStatus); - } -@@ -7960,7 +7977,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) - goto out; - } - -- host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic); -+ host_diagnostic = ioc->base_readl_ext_retry(&ioc->chip->HostDiagnostic); - drsprintk(ioc, - ioc_info(ioc, "wrote magic sequence: count(%d), host_diagnostic(0x%08x)\n", - count, host_diagnostic)); -@@ -7980,7 +7997,7 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) - for (count = 0; count < (300000000 / - MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) { - -- host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic); -+ host_diagnostic = ioc->base_readl_ext_retry(&ioc->chip->HostDiagnostic); - - if (host_diagnostic == 0xFFFFFFFF) { - ioc_info(ioc, -@@ -8370,10 +8387,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) - ioc->rdpq_array_enable_assigned = 0; - ioc->use_32bit_dma = false; - ioc->dma_mask = 64; -- if (ioc->is_aero_ioc) -+ if (ioc->is_aero_ioc) { - ioc->base_readl = &_base_readl_aero; -- else -+ ioc->base_readl_ext_retry = &_base_readl_ext_retry; -+ } else { - ioc->base_readl = &_base_readl; -+ ioc->base_readl_ext_retry = &_base_readl; -+ } - r = mpt3sas_base_map_resources(ioc); - if (r) - goto out_free_resources; -diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h -index 05364aa15ecdb..10055c7e4a9f7 100644 ---- a/drivers/scsi/mpt3sas/mpt3sas_base.h -+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h -@@ -1618,6 +1618,7 @@ struct MPT3SAS_ADAPTER { - u8 diag_trigger_active; - u8 atomic_desc_capable; - BASE_READ_REG base_readl; -+ BASE_READ_REG base_readl_ext_retry; - struct SL_WH_MASTER_TRIGGER_T diag_trigger_master; - struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event; - struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi; -diff --git a/drivers/scsi/qedf/qedf_dbg.h b/drivers/scsi/qedf/qedf_dbg.h -index f4d81127239eb..5ec2b817c694a 100644 ---- a/drivers/scsi/qedf/qedf_dbg.h -+++ b/drivers/scsi/qedf/qedf_dbg.h -@@ -59,6 +59,8 @@ extern uint qedf_debug; - #define QEDF_LOG_NOTICE 0x40000000 /* Notice logs */ - #define QEDF_LOG_WARN 0x80000000 /* Warning logs */ - -+#define QEDF_DEBUGFS_LOG_LEN (2 * PAGE_SIZE) -+ - /* Debug context structure */ - struct qedf_dbg_ctx { - unsigned int host_no; -diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c -index a3ed681c8ce3f..451fd236bfd05 100644 ---- a/drivers/scsi/qedf/qedf_debugfs.c -+++ b/drivers/scsi/qedf/qedf_debugfs.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - #include "qedf.h" - #include "qedf_dbg.h" -@@ -98,7 +99,9 @@ static ssize_t - qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count, - loff_t *ppos) - { -+ ssize_t ret; - size_t cnt = 0; -+ char *cbuf; - int id; - struct qedf_fastpath *fp = NULL; - struct qedf_dbg_ctx *qedf_dbg = -@@ -108,19 +111,25 @@ qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count, - - QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n"); - -- cnt = sprintf(buffer, "\nFastpath I/O completions\n\n"); -+ cbuf = vmalloc(QEDF_DEBUGFS_LOG_LEN); -+ if (!cbuf) -+ return 0; -+ -+ cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, "\nFastpath I/O completions\n\n"); - - for (id = 0; id < qedf->num_queues; id++) { - fp = &(qedf->fp_array[id]); - if (fp->sb_id == QEDF_SB_ID_NULL) - continue; -- cnt += sprintf((buffer + cnt), "#%d: %lu\n", id, -- fp->completions); -+ cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, -+ "#%d: %lu\n", id, fp->completions); - } - -- cnt = min_t(int, count, cnt - *ppos); -- *ppos += cnt; -- return cnt; -+ ret = simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); -+ -+ vfree(cbuf); -+ -+ return ret; - } - - static ssize_t -@@ -138,15 +147,14 @@ qedf_dbg_debug_cmd_read(struct file *filp, char __user *buffer, size_t count, - loff_t *ppos) - { - int cnt; -+ char cbuf[32]; - struct qedf_dbg_ctx *qedf_dbg = - (struct qedf_dbg_ctx *)filp->private_data; - - QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "debug mask=0x%x\n", qedf_debug); -- cnt = sprintf(buffer, "debug mask = 0x%x\n", qedf_debug); -+ cnt = scnprintf(cbuf, sizeof(cbuf), "debug mask = 0x%x\n", qedf_debug); - -- cnt = min_t(int, count, cnt - *ppos); -- *ppos += cnt; -- return cnt; -+ return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); - } - - static ssize_t -@@ -185,18 +193,17 @@ qedf_dbg_stop_io_on_error_cmd_read(struct file *filp, char __user *buffer, - size_t count, loff_t *ppos) - { - int cnt; -+ char cbuf[7]; - struct qedf_dbg_ctx *qedf_dbg = - (struct qedf_dbg_ctx *)filp->private_data; - struct qedf_ctx *qedf = container_of(qedf_dbg, - struct qedf_ctx, dbg_ctx); - - QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n"); -- cnt = sprintf(buffer, "%s\n", -+ cnt = scnprintf(cbuf, sizeof(cbuf), "%s\n", - qedf->stop_io_on_error ? "true" : "false"); - -- cnt = min_t(int, count, cnt - *ppos); -- *ppos += cnt; -- return cnt; -+ return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); - } - - static ssize_t -diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c -index 9fd68d362698f..2ee109fb65616 100644 ---- a/drivers/scsi/qedi/qedi_main.c -+++ b/drivers/scsi/qedi/qedi_main.c -@@ -1977,8 +1977,9 @@ static int qedi_cpu_offline(unsigned int cpu) - struct qedi_percpu_s *p = this_cpu_ptr(&qedi_percpu); - struct qedi_work *work, *tmp; - struct task_struct *thread; -+ unsigned long flags; - -- spin_lock_bh(&p->p_work_lock); -+ spin_lock_irqsave(&p->p_work_lock, flags); - thread = p->iothread; - p->iothread = NULL; - -@@ -1989,7 +1990,7 @@ static int qedi_cpu_offline(unsigned int cpu) - kfree(work); - } - -- spin_unlock_bh(&p->p_work_lock); -+ spin_unlock_irqrestore(&p->p_work_lock, flags); - if (thread) - kthread_stop(thread); - return 0; -diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c -index b597c782b95ee..30bbf33e3a6aa 100644 ---- a/drivers/scsi/qla2xxx/qla_init.c -+++ b/drivers/scsi/qla2xxx/qla_init.c -@@ -5571,7 +5571,7 @@ static void qla_get_login_template(scsi_qla_host_t *vha) - __be32 *q; - - memset(ha->init_cb, 0, ha->init_cb_size); -- sz = min_t(int, sizeof(struct fc_els_csp), ha->init_cb_size); -+ sz = min_t(int, sizeof(struct fc_els_flogi), ha->init_cb_size); - rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma, - ha->init_cb, sz); - if (rval != QLA_SUCCESS) { -diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c -index 9e849f6b0d0f7..3f2f9734ee42e 100644 ---- a/drivers/scsi/qla4xxx/ql4_os.c -+++ b/drivers/scsi/qla4xxx/ql4_os.c -@@ -968,6 +968,11 @@ static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void *data, int len) - memset(&chap_rec, 0, sizeof(chap_rec)); - - nla_for_each_attr(attr, data, len, rem) { -+ if (nla_len(attr) < sizeof(*param_info)) { -+ rc = -EINVAL; -+ goto exit_set_chap; -+ } -+ - param_info = nla_data(attr); - - switch (param_info->param) { -@@ -2750,6 +2755,11 @@ qla4xxx_iface_set_param(struct Scsi_Host *shost, void *data, uint32_t len) - } - - nla_for_each_attr(attr, data, len, rem) { -+ if (nla_len(attr) < sizeof(*iface_param)) { -+ rval = -EINVAL; -+ goto exit_init_fw_cb; -+ } -+ - iface_param = nla_data(attr); - - if (iface_param->param_type == ISCSI_NET_PARAM) { -@@ -8104,6 +8114,11 @@ qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess, - - memset((void *)&chap_tbl, 0, sizeof(chap_tbl)); - nla_for_each_attr(attr, data, len, rem) { -+ if (nla_len(attr) < sizeof(*fnode_param)) { -+ rc = -EINVAL; -+ goto exit_set_param; -+ } -+ - fnode_param = nla_data(attr); - - switch (fnode_param->param) { -diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c -index bf834e72595a3..49dbcd67579aa 100644 ---- a/drivers/scsi/scsi_transport_iscsi.c -+++ b/drivers/scsi/scsi_transport_iscsi.c -@@ -3013,14 +3013,15 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev - } - - static int --iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) -+iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen) - { - char *data = (char*)ev + sizeof(*ev); - struct iscsi_cls_conn *conn; - struct iscsi_cls_session *session; - int err = 0, value = 0, state; - -- if (ev->u.set_param.len > PAGE_SIZE) -+ if (ev->u.set_param.len > rlen || -+ ev->u.set_param.len > PAGE_SIZE) - return -EINVAL; - - session = iscsi_session_lookup(ev->u.set_param.sid); -@@ -3028,6 +3029,10 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) - if (!conn || !session) - return -EINVAL; - -+ /* data will be regarded as NULL-ended string, do length check */ -+ if (strlen(data) > ev->u.set_param.len) -+ return -EINVAL; -+ - switch (ev->u.set_param.param) { - case ISCSI_PARAM_SESS_RECOVERY_TMO: - sscanf(data, "%d", &value); -@@ -3117,7 +3122,7 @@ put_ep: - - static int - iscsi_if_transport_ep(struct iscsi_transport *transport, -- struct iscsi_uevent *ev, int msg_type) -+ struct iscsi_uevent *ev, int msg_type, u32 rlen) - { - struct iscsi_endpoint *ep; - int rc = 0; -@@ -3125,7 +3130,10 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, - switch (msg_type) { - case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST: - case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: -- rc = iscsi_if_ep_connect(transport, ev, msg_type); -+ if (rlen < sizeof(struct sockaddr)) -+ rc = -EINVAL; -+ else -+ rc = iscsi_if_ep_connect(transport, ev, msg_type); - break; - case ISCSI_UEVENT_TRANSPORT_EP_POLL: - if (!transport->ep_poll) -@@ -3149,12 +3157,15 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, - - static int - iscsi_tgt_dscvr(struct iscsi_transport *transport, -- struct iscsi_uevent *ev) -+ struct iscsi_uevent *ev, u32 rlen) - { - struct Scsi_Host *shost; - struct sockaddr *dst_addr; - int err; - -+ if (rlen < sizeof(*dst_addr)) -+ return -EINVAL; -+ - if (!transport->tgt_dscvr) - return -EINVAL; - -@@ -3175,7 +3186,7 @@ iscsi_tgt_dscvr(struct iscsi_transport *transport, - - static int - iscsi_set_host_param(struct iscsi_transport *transport, -- struct iscsi_uevent *ev) -+ struct iscsi_uevent *ev, u32 rlen) - { - char *data = (char*)ev + sizeof(*ev); - struct Scsi_Host *shost; -@@ -3184,7 +3195,8 @@ iscsi_set_host_param(struct iscsi_transport *transport, - if (!transport->set_host_param) - return -ENOSYS; - -- if (ev->u.set_host_param.len > PAGE_SIZE) -+ if (ev->u.set_host_param.len > rlen || -+ ev->u.set_host_param.len > PAGE_SIZE) - return -EINVAL; - - shost = scsi_host_lookup(ev->u.set_host_param.host_no); -@@ -3194,6 +3206,10 @@ iscsi_set_host_param(struct iscsi_transport *transport, - return -ENODEV; - } - -+ /* see similar check in iscsi_if_set_param() */ -+ if (strlen(data) > ev->u.set_host_param.len) -+ return -EINVAL; -+ - err = transport->set_host_param(shost, ev->u.set_host_param.param, - data, ev->u.set_host_param.len); - scsi_host_put(shost); -@@ -3201,12 +3217,15 @@ iscsi_set_host_param(struct iscsi_transport *transport, - } - - static int --iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev) -+iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen) - { - struct Scsi_Host *shost; - struct iscsi_path *params; - int err; - -+ if (rlen < sizeof(*params)) -+ return -EINVAL; -+ - if (!transport->set_path) - return -ENOSYS; - -@@ -3266,12 +3285,15 @@ iscsi_set_iface_params(struct iscsi_transport *transport, - } - - static int --iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev) -+iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen) - { - struct Scsi_Host *shost; - struct sockaddr *dst_addr; - int err; - -+ if (rlen < sizeof(*dst_addr)) -+ return -EINVAL; -+ - if (!transport->send_ping) - return -ENOSYS; - -@@ -3769,13 +3791,12 @@ exit_host_stats: - } - - static int iscsi_if_transport_conn(struct iscsi_transport *transport, -- struct nlmsghdr *nlh) -+ struct nlmsghdr *nlh, u32 pdu_len) - { - struct iscsi_uevent *ev = nlmsg_data(nlh); - struct iscsi_cls_session *session; - struct iscsi_cls_conn *conn = NULL; - struct iscsi_endpoint *ep; -- uint32_t pdu_len; - int err = 0; - - switch (nlh->nlmsg_type) { -@@ -3860,8 +3881,6 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport, - - break; - case ISCSI_UEVENT_SEND_PDU: -- pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev); -- - if ((ev->u.send_pdu.hdr_size > pdu_len) || - (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) { - err = -EINVAL; -@@ -3891,6 +3910,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) - struct iscsi_internal *priv; - struct iscsi_cls_session *session; - struct iscsi_endpoint *ep = NULL; -+ u32 rlen; - - if (!netlink_capable(skb, CAP_SYS_ADMIN)) - return -EPERM; -@@ -3910,6 +3930,13 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) - - portid = NETLINK_CB(skb).portid; - -+ /* -+ * Even though the remaining payload may not be regarded as nlattr, -+ * (like address or something else), calculate the remaining length -+ * here to ease following length checks. -+ */ -+ rlen = nlmsg_attrlen(nlh, sizeof(*ev)); -+ - switch (nlh->nlmsg_type) { - case ISCSI_UEVENT_CREATE_SESSION: - err = iscsi_if_create_session(priv, ep, ev, -@@ -3966,7 +3993,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) - err = -EINVAL; - break; - case ISCSI_UEVENT_SET_PARAM: -- err = iscsi_set_param(transport, ev); -+ err = iscsi_if_set_param(transport, ev, rlen); - break; - case ISCSI_UEVENT_CREATE_CONN: - case ISCSI_UEVENT_DESTROY_CONN: -@@ -3974,7 +4001,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) - case ISCSI_UEVENT_START_CONN: - case ISCSI_UEVENT_BIND_CONN: - case ISCSI_UEVENT_SEND_PDU: -- err = iscsi_if_transport_conn(transport, nlh); -+ err = iscsi_if_transport_conn(transport, nlh, rlen); - break; - case ISCSI_UEVENT_GET_STATS: - err = iscsi_if_get_stats(transport, nlh); -@@ -3983,23 +4010,22 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) - case ISCSI_UEVENT_TRANSPORT_EP_POLL: - case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: - case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST: -- err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); -+ err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type, rlen); - break; - case ISCSI_UEVENT_TGT_DSCVR: -- err = iscsi_tgt_dscvr(transport, ev); -+ err = iscsi_tgt_dscvr(transport, ev, rlen); - break; - case ISCSI_UEVENT_SET_HOST_PARAM: -- err = iscsi_set_host_param(transport, ev); -+ err = iscsi_set_host_param(transport, ev, rlen); - break; - case ISCSI_UEVENT_PATH_UPDATE: -- err = iscsi_set_path(transport, ev); -+ err = iscsi_set_path(transport, ev, rlen); - break; - case ISCSI_UEVENT_SET_IFACE_PARAMS: -- err = iscsi_set_iface_params(transport, ev, -- nlmsg_attrlen(nlh, sizeof(*ev))); -+ err = iscsi_set_iface_params(transport, ev, rlen); - break; - case ISCSI_UEVENT_PING: -- err = iscsi_send_ping(transport, ev); -+ err = iscsi_send_ping(transport, ev, rlen); - break; - case ISCSI_UEVENT_GET_CHAP: - err = iscsi_get_chap(transport, nlh); -@@ -4008,13 +4034,10 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) - err = iscsi_delete_chap(transport, ev); - break; - case ISCSI_UEVENT_SET_FLASHNODE_PARAMS: -- err = iscsi_set_flashnode_param(transport, ev, -- nlmsg_attrlen(nlh, -- sizeof(*ev))); -+ err = iscsi_set_flashnode_param(transport, ev, rlen); - break; - case ISCSI_UEVENT_NEW_FLASHNODE: -- err = iscsi_new_flashnode(transport, ev, -- nlmsg_attrlen(nlh, sizeof(*ev))); -+ err = iscsi_new_flashnode(transport, ev, rlen); - break; - case ISCSI_UEVENT_DEL_FLASHNODE: - err = iscsi_del_flashnode(transport, ev); -@@ -4029,8 +4052,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) - err = iscsi_logout_flashnode_sid(transport, ev); - break; - case ISCSI_UEVENT_SET_CHAP: -- err = iscsi_set_chap(transport, ev, -- nlmsg_attrlen(nlh, sizeof(*ev))); -+ err = iscsi_set_chap(transport, ev, rlen); - break; - case ISCSI_UEVENT_GET_HOST_STATS: - err = iscsi_get_host_stats(transport, nlh); -diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c -index 83d09c2009280..7a1dc5c7c49ee 100644 ---- a/drivers/scsi/storvsc_drv.c -+++ b/drivers/scsi/storvsc_drv.c -@@ -1568,6 +1568,8 @@ static int storvsc_device_configure(struct scsi_device *sdevice) - { - blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ)); - -+ /* storvsc devices don't support MAINTENANCE_IN SCSI cmd */ -+ sdevice->no_report_opcodes = 1; - sdevice->no_write_same = 1; - - /* -diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c -index c92d26b73e6fc..27c668eac9647 100644 ---- a/drivers/soc/qcom/ocmem.c -+++ b/drivers/soc/qcom/ocmem.c -@@ -76,8 +76,12 @@ struct ocmem { - #define OCMEM_REG_GFX_MPU_START 0x00001004 - #define OCMEM_REG_GFX_MPU_END 0x00001008 - --#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_PREP(0x0000000f, (val)) --#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_PREP(0x00003f00, (val)) -+#define OCMEM_HW_VERSION_MAJOR(val) FIELD_GET(GENMASK(31, 28), val) -+#define OCMEM_HW_VERSION_MINOR(val) FIELD_GET(GENMASK(27, 16), val) -+#define OCMEM_HW_VERSION_STEP(val) FIELD_GET(GENMASK(15, 0), val) -+ -+#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_GET(0x0000000f, (val)) -+#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_GET(0x00003f00, (val)) - - #define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE 0x00010000 - #define OCMEM_HW_PROFILE_INTERLEAVING 0x00020000 -@@ -355,6 +359,12 @@ static int ocmem_dev_probe(struct platform_device *pdev) - } - } - -+ reg = ocmem_read(ocmem, OCMEM_REG_HW_VERSION); -+ dev_dbg(dev, "OCMEM hardware version: %lu.%lu.%lu\n", -+ OCMEM_HW_VERSION_MAJOR(reg), -+ OCMEM_HW_VERSION_MINOR(reg), -+ OCMEM_HW_VERSION_STEP(reg)); -+ - reg = ocmem_read(ocmem, OCMEM_REG_HW_PROFILE); - ocmem->num_ports = OCMEM_HW_PROFILE_NUM_PORTS(reg); - ocmem->num_macros = OCMEM_HW_PROFILE_NUM_MACROS(reg); -diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c -index 4f163d62942c1..af8d90efd91fa 100644 ---- a/drivers/soc/qcom/smem.c -+++ b/drivers/soc/qcom/smem.c -@@ -723,7 +723,7 @@ EXPORT_SYMBOL(qcom_smem_get_free_space); - - static bool addr_in_range(void __iomem *base, size_t size, void *addr) - { -- return base && (addr >= base && addr < base + size); -+ return base && ((void __iomem *)addr >= base && (void __iomem *)addr < base + size); - } - - /** -diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c -index 220ee08c4a06c..d4bebb4314172 100644 ---- a/drivers/spi/spi-tegra20-sflash.c -+++ b/drivers/spi/spi-tegra20-sflash.c -@@ -455,7 +455,11 @@ static int tegra_sflash_probe(struct platform_device *pdev) - goto exit_free_master; - } - -- tsd->irq = platform_get_irq(pdev, 0); -+ ret = platform_get_irq(pdev, 0); -+ if (ret < 0) -+ goto exit_free_master; -+ tsd->irq = ret; -+ - ret = request_irq(tsd->irq, tegra_sflash_isr, 0, - dev_name(&pdev->dev), tsd); - if (ret < 0) { -diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c -index 5f9aedd1f0b65..151fef199c380 100644 ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -4370,6 +4370,11 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action, - return NOTIFY_OK; - } - -+ /* -+ * Clear the flag before adding the device so that fw_devlink -+ * doesn't skip adding consumers to this device. -+ */ -+ rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; - spi = of_register_spi_device(ctlr, rd->dn); - put_device(&ctlr->dev); - -diff --git a/drivers/staging/fbtft/fb_ili9341.c b/drivers/staging/fbtft/fb_ili9341.c -index 9ccd0823c3ab3..47e72b87d76d9 100644 ---- a/drivers/staging/fbtft/fb_ili9341.c -+++ b/drivers/staging/fbtft/fb_ili9341.c -@@ -145,7 +145,7 @@ static struct fbtft_display display = { - }, - }; - --FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9341", &display); -+FBTFT_REGISTER_SPI_DRIVER(DRVNAME, "ilitek", "ili9341", &display); - - MODULE_ALIAS("spi:" DRVNAME); - MODULE_ALIAS("platform:" DRVNAME); -diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index 82806f198074a..a9bd1e71ea487 100644 ---- a/drivers/staging/media/rkvdec/rkvdec.c -+++ b/drivers/staging/media/rkvdec/rkvdec.c -@@ -120,7 +120,7 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = { - .max_width = 4096, - .step_width = 16, - .min_height = 48, -- .max_height = 2304, -+ .max_height = 2560, - .step_height = 16, - }, - .ctrls = &rkvdec_h264_ctrls, -diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c -index aacba30bc10c1..762d1990180bf 100644 ---- a/drivers/thermal/thermal_of.c -+++ b/drivers/thermal/thermal_of.c -@@ -409,13 +409,13 @@ static int __thermal_of_unbind(struct device_node *map_np, int index, int trip_i - ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells", - index, &cooling_spec); - -- of_node_put(cooling_spec.np); -- - if (ret < 0) { - pr_err("Invalid cooling-device entry\n"); - return ret; - } - -+ of_node_put(cooling_spec.np); -+ - if (cooling_spec.args_count < 2) { - pr_err("wrong reference to cooling device, missing limits\n"); - return -EINVAL; -@@ -442,13 +442,13 @@ static int __thermal_of_bind(struct device_node *map_np, int index, int trip_id, - ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells", - index, &cooling_spec); - -- of_node_put(cooling_spec.np); -- - if (ret < 0) { - pr_err("Invalid cooling-device entry\n"); - return ret; - } - -+ of_node_put(cooling_spec.np); -+ - if (cooling_spec.args_count < 2) { - pr_err("wrong reference to cooling device, missing limits\n"); - return -EINVAL; -diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c -index 8411a0f312db0..21145eb8f2a9c 100644 ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -236,7 +236,8 @@ - - /* IOControl register bits (Only 750/760) */ - #define SC16IS7XX_IOCONTROL_LATCH_BIT (1 << 0) /* Enable input latching */ --#define SC16IS7XX_IOCONTROL_MODEM_BIT (1 << 1) /* Enable GPIO[7:4] as modem pins */ -+#define SC16IS7XX_IOCONTROL_MODEM_A_BIT (1 << 1) /* Enable GPIO[7:4] as modem A pins */ -+#define SC16IS7XX_IOCONTROL_MODEM_B_BIT (1 << 2) /* Enable GPIO[3:0] as modem B pins */ - #define SC16IS7XX_IOCONTROL_SRESET_BIT (1 << 3) /* Software Reset */ - - /* EFCR register bits */ -@@ -301,12 +302,12 @@ - /* Misc definitions */ - #define SC16IS7XX_FIFO_SIZE (64) - #define SC16IS7XX_REG_SHIFT 2 -+#define SC16IS7XX_GPIOS_PER_BANK 4 - - struct sc16is7xx_devtype { - char name[10]; - int nr_gpio; - int nr_uart; -- int has_mctrl; - }; - - #define SC16IS7XX_RECONF_MD (1 << 0) -@@ -336,7 +337,9 @@ struct sc16is7xx_port { - struct clk *clk; - #ifdef CONFIG_GPIOLIB - struct gpio_chip gpio; -+ unsigned long gpio_valid_mask; - #endif -+ u8 mctrl_mask; - unsigned char buf[SC16IS7XX_FIFO_SIZE]; - struct kthread_worker kworker; - struct task_struct *kworker_task; -@@ -447,35 +450,30 @@ static const struct sc16is7xx_devtype sc16is74x_devtype = { - .name = "SC16IS74X", - .nr_gpio = 0, - .nr_uart = 1, -- .has_mctrl = 0, - }; - - static const struct sc16is7xx_devtype sc16is750_devtype = { - .name = "SC16IS750", -- .nr_gpio = 4, -+ .nr_gpio = 8, - .nr_uart = 1, -- .has_mctrl = 1, - }; - - static const struct sc16is7xx_devtype sc16is752_devtype = { - .name = "SC16IS752", -- .nr_gpio = 0, -+ .nr_gpio = 8, - .nr_uart = 2, -- .has_mctrl = 1, - }; - - static const struct sc16is7xx_devtype sc16is760_devtype = { - .name = "SC16IS760", -- .nr_gpio = 4, -+ .nr_gpio = 8, - .nr_uart = 1, -- .has_mctrl = 1, - }; - - static const struct sc16is7xx_devtype sc16is762_devtype = { - .name = "SC16IS762", -- .nr_gpio = 0, -+ .nr_gpio = 8, - .nr_uart = 2, -- .has_mctrl = 1, - }; - - static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg) -@@ -1360,8 +1358,98 @@ static int sc16is7xx_gpio_direction_output(struct gpio_chip *chip, - - return 0; - } -+ -+static int sc16is7xx_gpio_init_valid_mask(struct gpio_chip *chip, -+ unsigned long *valid_mask, -+ unsigned int ngpios) -+{ -+ struct sc16is7xx_port *s = gpiochip_get_data(chip); -+ -+ *valid_mask = s->gpio_valid_mask; -+ -+ return 0; -+} -+ -+static int sc16is7xx_setup_gpio_chip(struct sc16is7xx_port *s) -+{ -+ struct device *dev = s->p[0].port.dev; -+ -+ if (!s->devtype->nr_gpio) -+ return 0; -+ -+ switch (s->mctrl_mask) { -+ case 0: -+ s->gpio_valid_mask = GENMASK(7, 0); -+ break; -+ case SC16IS7XX_IOCONTROL_MODEM_A_BIT: -+ s->gpio_valid_mask = GENMASK(3, 0); -+ break; -+ case SC16IS7XX_IOCONTROL_MODEM_B_BIT: -+ s->gpio_valid_mask = GENMASK(7, 4); -+ break; -+ default: -+ break; -+ } -+ -+ if (s->gpio_valid_mask == 0) -+ return 0; -+ -+ s->gpio.owner = THIS_MODULE; -+ s->gpio.parent = dev; -+ s->gpio.label = dev_name(dev); -+ s->gpio.init_valid_mask = sc16is7xx_gpio_init_valid_mask; -+ s->gpio.direction_input = sc16is7xx_gpio_direction_input; -+ s->gpio.get = sc16is7xx_gpio_get; -+ s->gpio.direction_output = sc16is7xx_gpio_direction_output; -+ s->gpio.set = sc16is7xx_gpio_set; -+ s->gpio.base = -1; -+ s->gpio.ngpio = s->devtype->nr_gpio; -+ s->gpio.can_sleep = 1; -+ -+ return gpiochip_add_data(&s->gpio, s); -+} - #endif - -+/* -+ * Configure ports designated to operate as modem control lines. -+ */ -+static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s) -+{ -+ int i; -+ int ret; -+ int count; -+ u32 mctrl_port[2]; -+ struct device *dev = s->p[0].port.dev; -+ -+ count = device_property_count_u32(dev, "nxp,modem-control-line-ports"); -+ if (count < 0 || count > ARRAY_SIZE(mctrl_port)) -+ return 0; -+ -+ ret = device_property_read_u32_array(dev, "nxp,modem-control-line-ports", -+ mctrl_port, count); -+ if (ret) -+ return ret; -+ -+ s->mctrl_mask = 0; -+ -+ for (i = 0; i < count; i++) { -+ /* Use GPIO lines as modem control lines */ -+ if (mctrl_port[i] == 0) -+ s->mctrl_mask |= SC16IS7XX_IOCONTROL_MODEM_A_BIT; -+ else if (mctrl_port[i] == 1) -+ s->mctrl_mask |= SC16IS7XX_IOCONTROL_MODEM_B_BIT; -+ } -+ -+ if (s->mctrl_mask) -+ regmap_update_bits( -+ s->regmap, -+ SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT, -+ SC16IS7XX_IOCONTROL_MODEM_A_BIT | -+ SC16IS7XX_IOCONTROL_MODEM_B_BIT, s->mctrl_mask); -+ -+ return 0; -+} -+ - static const struct serial_rs485 sc16is7xx_rs485_supported = { - .flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, - .delay_rts_before_send = 1, -@@ -1474,12 +1562,6 @@ static int sc16is7xx_probe(struct device *dev, - SC16IS7XX_EFCR_RXDISABLE_BIT | - SC16IS7XX_EFCR_TXDISABLE_BIT); - -- /* Use GPIO lines as modem status registers */ -- if (devtype->has_mctrl) -- sc16is7xx_port_write(&s->p[i].port, -- SC16IS7XX_IOCONTROL_REG, -- SC16IS7XX_IOCONTROL_MODEM_BIT); -- - /* Initialize kthread work structs */ - kthread_init_work(&s->p[i].tx_work, sc16is7xx_tx_proc); - kthread_init_work(&s->p[i].reg_work, sc16is7xx_reg_proc); -@@ -1517,23 +1599,14 @@ static int sc16is7xx_probe(struct device *dev, - s->p[u].irda_mode = true; - } - -+ ret = sc16is7xx_setup_mctrl_ports(s); -+ if (ret) -+ goto out_ports; -+ - #ifdef CONFIG_GPIOLIB -- if (devtype->nr_gpio) { -- /* Setup GPIO cotroller */ -- s->gpio.owner = THIS_MODULE; -- s->gpio.parent = dev; -- s->gpio.label = dev_name(dev); -- s->gpio.direction_input = sc16is7xx_gpio_direction_input; -- s->gpio.get = sc16is7xx_gpio_get; -- s->gpio.direction_output = sc16is7xx_gpio_direction_output; -- s->gpio.set = sc16is7xx_gpio_set; -- s->gpio.base = -1; -- s->gpio.ngpio = devtype->nr_gpio; -- s->gpio.can_sleep = 1; -- ret = gpiochip_add_data(&s->gpio, s); -- if (ret) -- goto out_thread; -- } -+ ret = sc16is7xx_setup_gpio_chip(s); -+ if (ret) -+ goto out_ports; - #endif - - /* -@@ -1556,10 +1629,8 @@ static int sc16is7xx_probe(struct device *dev, - return 0; - - #ifdef CONFIG_GPIOLIB -- if (devtype->nr_gpio) -+ if (s->gpio_valid_mask) - gpiochip_remove(&s->gpio); -- --out_thread: - #endif - - out_ports: -@@ -1582,7 +1653,7 @@ static void sc16is7xx_remove(struct device *dev) - int i; - - #ifdef CONFIG_GPIOLIB -- if (s->devtype->nr_gpio) -+ if (s->gpio_valid_mask) - gpiochip_remove(&s->gpio); - #endif - -diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c -index c08360212aa20..7aa2b5b67001d 100644 ---- a/drivers/tty/serial/serial-tegra.c -+++ b/drivers/tty/serial/serial-tegra.c -@@ -999,7 +999,11 @@ static int tegra_uart_hw_init(struct tegra_uart_port *tup) - tup->ier_shadow = 0; - tup->current_baud = 0; - -- clk_prepare_enable(tup->uart_clk); -+ ret = clk_prepare_enable(tup->uart_clk); -+ if (ret) { -+ dev_err(tup->uport.dev, "could not enable clk\n"); -+ return ret; -+ } - - /* Reset the UART controller to clear all previous status.*/ - reset_control_assert(tup->rst); -diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c -index 342a879676315..9c7f71993e945 100644 ---- a/drivers/tty/serial/sprd_serial.c -+++ b/drivers/tty/serial/sprd_serial.c -@@ -367,7 +367,7 @@ static void sprd_rx_free_buf(struct sprd_uart_port *sp) - if (sp->rx_dma.virt) - dma_free_coherent(sp->port.dev, SPRD_UART_RX_SIZE, - sp->rx_dma.virt, sp->rx_dma.phys_addr); -- -+ sp->rx_dma.virt = NULL; - } - - static int sprd_rx_dma_config(struct uart_port *port, u32 burst) -@@ -1132,7 +1132,7 @@ static bool sprd_uart_is_console(struct uart_port *uport) - static int sprd_clk_init(struct uart_port *uport) - { - struct clk *clk_uart, *clk_parent; -- struct sprd_uart_port *u = sprd_port[uport->line]; -+ struct sprd_uart_port *u = container_of(uport, struct sprd_uart_port, port); - - clk_uart = devm_clk_get(uport->dev, "uart"); - if (IS_ERR(clk_uart)) { -@@ -1175,22 +1175,22 @@ static int sprd_probe(struct platform_device *pdev) - { - struct resource *res; - struct uart_port *up; -+ struct sprd_uart_port *sport; - int irq; - int index; - int ret; - - index = of_alias_get_id(pdev->dev.of_node, "serial"); -- if (index < 0 || index >= ARRAY_SIZE(sprd_port)) { -+ if (index < 0 || index >= UART_NR_MAX) { - dev_err(&pdev->dev, "got a wrong serial alias id %d\n", index); - return -EINVAL; - } - -- sprd_port[index] = devm_kzalloc(&pdev->dev, sizeof(*sprd_port[index]), -- GFP_KERNEL); -- if (!sprd_port[index]) -+ sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); -+ if (!sport) - return -ENOMEM; - -- up = &sprd_port[index]->port; -+ up = &sport->port; - up->dev = &pdev->dev; - up->line = index; - up->type = PORT_SPRD; -@@ -1221,7 +1221,7 @@ static int sprd_probe(struct platform_device *pdev) - * Allocate one dma buffer to prepare for receive transfer, in case - * memory allocation failure at runtime. - */ -- ret = sprd_rx_alloc_buf(sprd_port[index]); -+ ret = sprd_rx_alloc_buf(sport); - if (ret) - return ret; - -@@ -1229,17 +1229,27 @@ static int sprd_probe(struct platform_device *pdev) - ret = uart_register_driver(&sprd_uart_driver); - if (ret < 0) { - pr_err("Failed to register SPRD-UART driver\n"); -- return ret; -+ goto free_rx_buf; - } - } -+ - sprd_ports_num++; -+ sprd_port[index] = sport; - - ret = uart_add_one_port(&sprd_uart_driver, up); - if (ret) -- sprd_remove(pdev); -+ goto clean_port; - - platform_set_drvdata(pdev, up); - -+ return 0; -+ -+clean_port: -+ sprd_port[index] = NULL; -+ if (--sprd_ports_num == 0) -+ uart_unregister_driver(&sprd_uart_driver); -+free_rx_buf: -+ sprd_rx_free_buf(sport); - return ret; - } - -diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c -index 977bd4b9dd0b4..36437d39b93c8 100644 ---- a/drivers/ufs/core/ufshcd.c -+++ b/drivers/ufs/core/ufshcd.c -@@ -8830,9 +8830,11 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, - for (retries = 3; retries > 0; --retries) { - ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, - HZ, 0, 0, RQF_PM, NULL); -- if (!scsi_status_is_check_condition(ret) || -- !scsi_sense_valid(&sshdr) || -- sshdr.sense_key != UNIT_ATTENTION) -+ /* -+ * scsi_execute() only returns a negative value if the request -+ * queue is dying. -+ */ -+ if (ret <= 0) - break; - } - if (ret) { -diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c -index 8300baedafd20..6af0a31ff1475 100644 ---- a/drivers/usb/core/hcd.c -+++ b/drivers/usb/core/hcd.c -@@ -983,6 +983,7 @@ static int register_root_hub(struct usb_hcd *hcd) - { - struct device *parent_dev = hcd->self.controller; - struct usb_device *usb_dev = hcd->self.root_hub; -+ struct usb_device_descriptor *descr; - const int devnum = 1; - int retval; - -@@ -994,13 +995,16 @@ static int register_root_hub(struct usb_hcd *hcd) - mutex_lock(&usb_bus_idr_lock); - - usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); -- retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); -- if (retval != sizeof usb_dev->descriptor) { -+ descr = usb_get_device_descriptor(usb_dev); -+ if (IS_ERR(descr)) { -+ retval = PTR_ERR(descr); - mutex_unlock(&usb_bus_idr_lock); - dev_dbg (parent_dev, "can't read %s device descriptor %d\n", - dev_name(&usb_dev->dev), retval); -- return (retval < 0) ? retval : -EMSGSIZE; -+ return retval; - } -+ usb_dev->descriptor = *descr; -+ kfree(descr); - - if (le16_to_cpu(usb_dev->descriptor.bcdUSB) >= 0x0201) { - retval = usb_get_bos_descriptor(usb_dev); -diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 1abe43ddb75f0..0069a24bd216c 100644 ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -2656,12 +2656,17 @@ int usb_authorize_device(struct usb_device *usb_dev) - } - - if (usb_dev->wusb) { -- result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor)); -- if (result < 0) { -+ struct usb_device_descriptor *descr; -+ -+ descr = usb_get_device_descriptor(usb_dev); -+ if (IS_ERR(descr)) { -+ result = PTR_ERR(descr); - dev_err(&usb_dev->dev, "can't re-read device descriptor for " - "authorization: %d\n", result); - goto error_device_descriptor; - } -+ usb_dev->descriptor = *descr; -+ kfree(descr); - } - - usb_dev->authorized = 1; -@@ -4661,6 +4666,67 @@ static int hub_enable_device(struct usb_device *udev) - return hcd->driver->enable_device(hcd, udev); - } - -+/* -+ * Get the bMaxPacketSize0 value during initialization by reading the -+ * device's device descriptor. Since we don't already know this value, -+ * the transfer is unsafe and it ignores I/O errors, only testing for -+ * reasonable received values. -+ * -+ * For "old scheme" initialization, size will be 8 so we read just the -+ * start of the device descriptor, which should work okay regardless of -+ * the actual bMaxPacketSize0 value. For "new scheme" initialization, -+ * size will be 64 (and buf will point to a sufficiently large buffer), -+ * which might not be kosher according to the USB spec but it's what -+ * Windows does and what many devices expect. -+ * -+ * Returns: bMaxPacketSize0 or a negative error code. -+ */ -+static int get_bMaxPacketSize0(struct usb_device *udev, -+ struct usb_device_descriptor *buf, int size, bool first_time) -+{ -+ int i, rc; -+ -+ /* -+ * Retry on all errors; some devices are flakey. -+ * 255 is for WUSB devices, we actually need to use -+ * 512 (WUSB1.0[4.8.1]). -+ */ -+ for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) { -+ /* Start with invalid values in case the transfer fails */ -+ buf->bDescriptorType = buf->bMaxPacketSize0 = 0; -+ rc = usb_control_msg(udev, usb_rcvaddr0pipe(), -+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, -+ USB_DT_DEVICE << 8, 0, -+ buf, size, -+ initial_descriptor_timeout); -+ switch (buf->bMaxPacketSize0) { -+ case 8: case 16: case 32: case 64: case 9: -+ if (buf->bDescriptorType == USB_DT_DEVICE) { -+ rc = buf->bMaxPacketSize0; -+ break; -+ } -+ fallthrough; -+ default: -+ if (rc >= 0) -+ rc = -EPROTO; -+ break; -+ } -+ -+ /* -+ * Some devices time out if they are powered on -+ * when already connected. They need a second -+ * reset, so return early. But only on the first -+ * attempt, lest we get into a time-out/reset loop. -+ */ -+ if (rc > 0 || (rc == -ETIMEDOUT && first_time && -+ udev->speed > USB_SPEED_FULL)) -+ break; -+ } -+ return rc; -+} -+ -+#define GET_DESCRIPTOR_BUFSIZE 64 -+ - /* Reset device, (re)assign address, get device descriptor. - * Device connection must be stable, no more debouncing needed. - * Returns device in USB_STATE_ADDRESS, except on error. -@@ -4670,10 +4736,17 @@ static int hub_enable_device(struct usb_device *udev) - * the port lock. For a newly detected device that is not accessible - * through any global pointers, it's not necessary to lock the device, - * but it is still necessary to lock the port. -+ * -+ * For a newly detected device, @dev_descr must be NULL. The device -+ * descriptor retrieved from the device will then be stored in -+ * @udev->descriptor. For an already existing device, @dev_descr -+ * must be non-NULL. The device descriptor will be stored there, -+ * not in @udev->descriptor, because descriptors for registered -+ * devices are meant to be immutable. - */ - static int - hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, -- int retry_counter) -+ int retry_counter, struct usb_device_descriptor *dev_descr) - { - struct usb_device *hdev = hub->hdev; - struct usb_hcd *hcd = bus_to_hcd(hdev->bus); -@@ -4685,6 +4758,13 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - int devnum = udev->devnum; - const char *driver_name; - bool do_new_scheme; -+ const bool initial = !dev_descr; -+ int maxp0; -+ struct usb_device_descriptor *buf, *descr; -+ -+ buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); -+ if (!buf) -+ return -ENOMEM; - - /* root hub ports have a slightly longer reset period - * (from USB 2.0 spec, section 7.1.7.5) -@@ -4717,32 +4797,34 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - } - oldspeed = udev->speed; - -- /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... -- * it's fixed size except for full speed devices. -- * For Wireless USB devices, ep0 max packet is always 512 (tho -- * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. -- */ -- switch (udev->speed) { -- case USB_SPEED_SUPER_PLUS: -- case USB_SPEED_SUPER: -- case USB_SPEED_WIRELESS: /* fixed at 512 */ -- udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); -- break; -- case USB_SPEED_HIGH: /* fixed at 64 */ -- udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); -- break; -- case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ -- /* to determine the ep0 maxpacket size, try to read -- * the device descriptor to get bMaxPacketSize0 and -- * then correct our initial guess. -+ if (initial) { -+ /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... -+ * it's fixed size except for full speed devices. -+ * For Wireless USB devices, ep0 max packet is always 512 (tho -+ * reported as 0xff in the device descriptor). WUSB1.0[4.8.1]. - */ -- udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); -- break; -- case USB_SPEED_LOW: /* fixed at 8 */ -- udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); -- break; -- default: -- goto fail; -+ switch (udev->speed) { -+ case USB_SPEED_SUPER_PLUS: -+ case USB_SPEED_SUPER: -+ case USB_SPEED_WIRELESS: /* fixed at 512 */ -+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); -+ break; -+ case USB_SPEED_HIGH: /* fixed at 64 */ -+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); -+ break; -+ case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ -+ /* to determine the ep0 maxpacket size, try to read -+ * the device descriptor to get bMaxPacketSize0 and -+ * then correct our initial guess. -+ */ -+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); -+ break; -+ case USB_SPEED_LOW: /* fixed at 8 */ -+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); -+ break; -+ default: -+ goto fail; -+ } - } - - if (udev->speed == USB_SPEED_WIRELESS) -@@ -4765,22 +4847,24 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - if (udev->speed < USB_SPEED_SUPER) - dev_info(&udev->dev, - "%s %s USB device number %d using %s\n", -- (udev->config) ? "reset" : "new", speed, -+ (initial ? "new" : "reset"), speed, - devnum, driver_name); - -- /* Set up TT records, if needed */ -- if (hdev->tt) { -- udev->tt = hdev->tt; -- udev->ttport = hdev->ttport; -- } else if (udev->speed != USB_SPEED_HIGH -- && hdev->speed == USB_SPEED_HIGH) { -- if (!hub->tt.hub) { -- dev_err(&udev->dev, "parent hub has no TT\n"); -- retval = -EINVAL; -- goto fail; -+ if (initial) { -+ /* Set up TT records, if needed */ -+ if (hdev->tt) { -+ udev->tt = hdev->tt; -+ udev->ttport = hdev->ttport; -+ } else if (udev->speed != USB_SPEED_HIGH -+ && hdev->speed == USB_SPEED_HIGH) { -+ if (!hub->tt.hub) { -+ dev_err(&udev->dev, "parent hub has no TT\n"); -+ retval = -EINVAL; -+ goto fail; -+ } -+ udev->tt = &hub->tt; -+ udev->ttport = port1; - } -- udev->tt = &hub->tt; -- udev->ttport = port1; - } - - /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way? -@@ -4799,9 +4883,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - - for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) { - if (do_new_scheme) { -- struct usb_device_descriptor *buf; -- int r = 0; -- - retval = hub_enable_device(udev); - if (retval < 0) { - dev_err(&udev->dev, -@@ -4810,52 +4891,14 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - goto fail; - } - --#define GET_DESCRIPTOR_BUFSIZE 64 -- buf = kmalloc(GET_DESCRIPTOR_BUFSIZE, GFP_NOIO); -- if (!buf) { -- retval = -ENOMEM; -- continue; -- } -- -- /* Retry on all errors; some devices are flakey. -- * 255 is for WUSB devices, we actually need to use -- * 512 (WUSB1.0[4.8.1]). -- */ -- for (operations = 0; operations < GET_MAXPACKET0_TRIES; -- ++operations) { -- buf->bMaxPacketSize0 = 0; -- r = usb_control_msg(udev, usb_rcvaddr0pipe(), -- USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, -- USB_DT_DEVICE << 8, 0, -- buf, GET_DESCRIPTOR_BUFSIZE, -- initial_descriptor_timeout); -- switch (buf->bMaxPacketSize0) { -- case 8: case 16: case 32: case 64: case 255: -- if (buf->bDescriptorType == -- USB_DT_DEVICE) { -- r = 0; -- break; -- } -- fallthrough; -- default: -- if (r == 0) -- r = -EPROTO; -- break; -- } -- /* -- * Some devices time out if they are powered on -- * when already connected. They need a second -- * reset. But only on the first attempt, -- * lest we get into a time out/reset loop -- */ -- if (r == 0 || (r == -ETIMEDOUT && -- retries == 0 && -- udev->speed > USB_SPEED_FULL)) -- break; -+ maxp0 = get_bMaxPacketSize0(udev, buf, -+ GET_DESCRIPTOR_BUFSIZE, retries == 0); -+ if (maxp0 > 0 && !initial && -+ maxp0 != udev->descriptor.bMaxPacketSize0) { -+ dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n"); -+ retval = -ENODEV; -+ goto fail; - } -- udev->descriptor.bMaxPacketSize0 = -- buf->bMaxPacketSize0; -- kfree(buf); - - retval = hub_port_reset(hub, port1, udev, delay, false); - if (retval < 0) /* error or disconnect */ -@@ -4866,14 +4909,13 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - retval = -ENODEV; - goto fail; - } -- if (r) { -- if (r != -ENODEV) -+ if (maxp0 < 0) { -+ if (maxp0 != -ENODEV) - dev_err(&udev->dev, "device descriptor read/64, error %d\n", -- r); -- retval = -EMSGSIZE; -+ maxp0); -+ retval = maxp0; - continue; - } --#undef GET_DESCRIPTOR_BUFSIZE - } - - /* -@@ -4919,18 +4961,22 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - break; - } - -- retval = usb_get_device_descriptor(udev, 8); -- if (retval < 8) { -+ /* !do_new_scheme || wusb */ -+ maxp0 = get_bMaxPacketSize0(udev, buf, 8, retries == 0); -+ if (maxp0 < 0) { -+ retval = maxp0; - if (retval != -ENODEV) - dev_err(&udev->dev, - "device descriptor read/8, error %d\n", - retval); -- if (retval >= 0) -- retval = -EMSGSIZE; - } else { - u32 delay; - -- retval = 0; -+ if (!initial && maxp0 != udev->descriptor.bMaxPacketSize0) { -+ dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n"); -+ retval = -ENODEV; -+ goto fail; -+ } - - delay = udev->parent->hub_delay; - udev->hub_delay = min_t(u32, delay, -@@ -4949,48 +4995,61 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, - goto fail; - - /* -- * Some superspeed devices have finished the link training process -- * and attached to a superspeed hub port, but the device descriptor -- * got from those devices show they aren't superspeed devices. Warm -- * reset the port attached by the devices can fix them. -+ * Check the ep0 maxpacket guess and correct it if necessary. -+ * maxp0 is the value stored in the device descriptor; -+ * i is the value it encodes (logarithmic for SuperSpeed or greater). - */ -- if ((udev->speed >= USB_SPEED_SUPER) && -- (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { -- dev_err(&udev->dev, "got a wrong device descriptor, " -- "warm reset device\n"); -- hub_port_reset(hub, port1, udev, -- HUB_BH_RESET_TIME, true); -- retval = -EINVAL; -- goto fail; -- } -- -- if (udev->descriptor.bMaxPacketSize0 == 0xff || -- udev->speed >= USB_SPEED_SUPER) -- i = 512; -- else -- i = udev->descriptor.bMaxPacketSize0; -- if (usb_endpoint_maxp(&udev->ep0.desc) != i) { -- if (udev->speed == USB_SPEED_LOW || -- !(i == 8 || i == 16 || i == 32 || i == 64)) { -- dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); -- retval = -EMSGSIZE; -- goto fail; -- } -+ i = maxp0; -+ if (udev->speed >= USB_SPEED_SUPER) { -+ if (maxp0 <= 16) -+ i = 1 << maxp0; -+ else -+ i = 0; /* Invalid */ -+ } -+ if (usb_endpoint_maxp(&udev->ep0.desc) == i) { -+ ; /* Initial ep0 maxpacket guess is right */ -+ } else if ((udev->speed == USB_SPEED_FULL || -+ udev->speed == USB_SPEED_HIGH) && -+ (i == 8 || i == 16 || i == 32 || i == 64)) { -+ /* Initial guess is wrong; use the descriptor's value */ - if (udev->speed == USB_SPEED_FULL) - dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); - else - dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i); - udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i); - usb_ep0_reinit(udev); -+ } else { -+ /* Initial guess is wrong and descriptor's value is invalid */ -+ dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", maxp0); -+ retval = -EMSGSIZE; -+ goto fail; - } - -- retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE); -- if (retval < (signed)sizeof(udev->descriptor)) { -+ descr = usb_get_device_descriptor(udev); -+ if (IS_ERR(descr)) { -+ retval = PTR_ERR(descr); - if (retval != -ENODEV) - dev_err(&udev->dev, "device descriptor read/all, error %d\n", - retval); -- if (retval >= 0) -- retval = -ENOMSG; -+ goto fail; -+ } -+ if (initial) -+ udev->descriptor = *descr; -+ else -+ *dev_descr = *descr; -+ kfree(descr); -+ -+ /* -+ * Some superspeed devices have finished the link training process -+ * and attached to a superspeed hub port, but the device descriptor -+ * got from those devices show they aren't superspeed devices. Warm -+ * reset the port attached by the devices can fix them. -+ */ -+ if ((udev->speed >= USB_SPEED_SUPER) && -+ (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { -+ dev_err(&udev->dev, "got a wrong device descriptor, warm reset device\n"); -+ hub_port_reset(hub, port1, udev, HUB_BH_RESET_TIME, true); -+ retval = -EINVAL; - goto fail; - } - -@@ -5016,6 +5075,7 @@ fail: - hub_port_disable(hub, port1, 0); - update_devnum(udev, devnum); /* for disconnect processing */ - } -+ kfree(buf); - return retval; - } - -@@ -5096,7 +5156,7 @@ hub_power_remaining(struct usb_hub *hub) - - - static int descriptors_changed(struct usb_device *udev, -- struct usb_device_descriptor *old_device_descriptor, -+ struct usb_device_descriptor *new_device_descriptor, - struct usb_host_bos *old_bos) - { - int changed = 0; -@@ -5107,8 +5167,8 @@ static int descriptors_changed(struct usb_device *udev, - int length; - char *buf; - -- if (memcmp(&udev->descriptor, old_device_descriptor, -- sizeof(*old_device_descriptor)) != 0) -+ if (memcmp(&udev->descriptor, new_device_descriptor, -+ sizeof(*new_device_descriptor)) != 0) - return 1; - - if ((old_bos && !udev->bos) || (!old_bos && udev->bos)) -@@ -5281,7 +5341,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, - } - - /* reset (non-USB 3.0 devices) and get descriptor */ -- status = hub_port_init(hub, udev, port1, i); -+ status = hub_port_init(hub, udev, port1, i, NULL); - if (status < 0) - goto loop; - -@@ -5428,9 +5488,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, - { - struct usb_port *port_dev = hub->ports[port1 - 1]; - struct usb_device *udev = port_dev->child; -- struct usb_device_descriptor descriptor; -+ struct usb_device_descriptor *descr; - int status = -ENODEV; -- int retval; - - dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n", portstatus, - portchange, portspeed(hub, portstatus)); -@@ -5457,23 +5516,20 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, - * changed device descriptors before resuscitating the - * device. - */ -- descriptor = udev->descriptor; -- retval = usb_get_device_descriptor(udev, -- sizeof(udev->descriptor)); -- if (retval < 0) { -+ descr = usb_get_device_descriptor(udev); -+ if (IS_ERR(descr)) { - dev_dbg(&udev->dev, -- "can't read device descriptor %d\n", -- retval); -+ "can't read device descriptor %ld\n", -+ PTR_ERR(descr)); - } else { -- if (descriptors_changed(udev, &descriptor, -+ if (descriptors_changed(udev, descr, - udev->bos)) { - dev_dbg(&udev->dev, - "device descriptor has changed\n"); -- /* for disconnect() calls */ -- udev->descriptor = descriptor; - } else { - status = 0; /* Nothing to do */ - } -+ kfree(descr); - } - #ifdef CONFIG_PM - } else if (udev->state == USB_STATE_SUSPENDED && -@@ -5911,7 +5967,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) - struct usb_device *parent_hdev = udev->parent; - struct usb_hub *parent_hub; - struct usb_hcd *hcd = bus_to_hcd(udev->bus); -- struct usb_device_descriptor descriptor = udev->descriptor; -+ struct usb_device_descriptor descriptor; - struct usb_host_bos *bos; - int i, j, ret = 0; - int port1 = udev->portnum; -@@ -5943,7 +5999,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) - /* ep0 maxpacket size may change; let the HCD know about it. - * Other endpoints will be handled by re-enumeration. */ - usb_ep0_reinit(udev); -- ret = hub_port_init(parent_hub, udev, port1, i); -+ ret = hub_port_init(parent_hub, udev, port1, i, &descriptor); - if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV) - break; - } -@@ -5955,7 +6011,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev) - /* Device might have changed firmware (DFU or similar) */ - if (descriptors_changed(udev, &descriptor, bos)) { - dev_info(&udev->dev, "device firmware changed\n"); -- udev->descriptor = descriptor; /* for disconnect() calls */ - goto re_enumerate; - } - -diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c -index 4d59d927ae3e3..1673e5d089263 100644 ---- a/drivers/usb/core/message.c -+++ b/drivers/usb/core/message.c -@@ -1039,40 +1039,35 @@ char *usb_cache_string(struct usb_device *udev, int index) - } - - /* -- * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) -- * @dev: the device whose device descriptor is being updated -- * @size: how much of the descriptor to read -+ * usb_get_device_descriptor - read the device descriptor -+ * @udev: the device whose device descriptor should be read - * - * Context: task context, might sleep. - * -- * Updates the copy of the device descriptor stored in the device structure, -- * which dedicates space for this purpose. -- * - * Not exported, only for use by the core. If drivers really want to read - * the device descriptor directly, they can call usb_get_descriptor() with - * type = USB_DT_DEVICE and index = 0. - * -- * This call is synchronous, and may not be used in an interrupt context. -- * -- * Return: The number of bytes received on success, or else the status code -- * returned by the underlying usb_control_msg() call. -+ * Returns: a pointer to a dynamically allocated usb_device_descriptor -+ * structure (which the caller must deallocate), or an ERR_PTR value. - */ --int usb_get_device_descriptor(struct usb_device *dev, unsigned int size) -+struct usb_device_descriptor *usb_get_device_descriptor(struct usb_device *udev) - { - struct usb_device_descriptor *desc; - int ret; - -- if (size > sizeof(*desc)) -- return -EINVAL; - desc = kmalloc(sizeof(*desc), GFP_NOIO); - if (!desc) -- return -ENOMEM; -+ return ERR_PTR(-ENOMEM); -+ -+ ret = usb_get_descriptor(udev, USB_DT_DEVICE, 0, desc, sizeof(*desc)); -+ if (ret == sizeof(*desc)) -+ return desc; - -- ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size); - if (ret >= 0) -- memcpy(&dev->descriptor, desc, size); -+ ret = -EMSGSIZE; - kfree(desc); -- return ret; -+ return ERR_PTR(ret); - } - - /* -diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h -index 82538daac8b89..3bb2e1db42b5d 100644 ---- a/drivers/usb/core/usb.h -+++ b/drivers/usb/core/usb.h -@@ -42,8 +42,8 @@ extern bool usb_endpoint_is_ignored(struct usb_device *udev, - struct usb_endpoint_descriptor *epd); - extern int usb_remove_device(struct usb_device *udev); - --extern int usb_get_device_descriptor(struct usb_device *dev, -- unsigned int size); -+extern struct usb_device_descriptor *usb_get_device_descriptor( -+ struct usb_device *udev); - extern int usb_set_isoch_delay(struct usb_device *dev); - extern int usb_get_bos_descriptor(struct usb_device *dev); - extern void usb_release_bos_descriptor(struct usb_device *dev); -diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c -index 3abf7f586e2af..7b9a4cf9b100c 100644 ---- a/drivers/usb/gadget/function/f_mass_storage.c -+++ b/drivers/usb/gadget/function/f_mass_storage.c -@@ -926,7 +926,7 @@ static void invalidate_sub(struct fsg_lun *curlun) - { - struct file *filp = curlun->filp; - struct inode *inode = file_inode(filp); -- unsigned long rc; -+ unsigned long __maybe_unused rc; - - rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); - VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc); -diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c -index 316e9cc3987be..1c0c61e8ba696 100644 ---- a/drivers/usb/gadget/udc/core.c -+++ b/drivers/usb/gadget/udc/core.c -@@ -40,6 +40,7 @@ static struct bus_type gadget_bus_type; - * @allow_connect: Indicates whether UDC is allowed to be pulled up. - * Set/cleared by gadget_(un)bind_driver() after gadget driver is bound or - * unbound. -+ * @vbus_work: work routine to handle VBUS status change notifications. - * @connect_lock: protects udc->started, gadget->connect, - * gadget->allow_connect and gadget->deactivate. The routines - * usb_gadget_connect_locked(), usb_gadget_disconnect_locked(), -diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c -index d2836ef5d15c7..9299df53eb9df 100644 ---- a/drivers/usb/phy/phy-mxs-usb.c -+++ b/drivers/usb/phy/phy-mxs-usb.c -@@ -388,14 +388,8 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect) - - static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy) - { -- void __iomem *base = mxs_phy->phy.io_priv; -- u32 phyctrl = readl(base + HW_USBPHY_CTRL); -- -- if (IS_ENABLED(CONFIG_USB_OTG) && -- !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE)) -- return true; -- -- return false; -+ return IS_ENABLED(CONFIG_USB_OTG) && -+ mxs_phy->phy.last_event == USB_EVENT_ID; - } - - static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) -diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c -index 31c2a3130cadb..69442a8135856 100644 ---- a/drivers/usb/typec/bus.c -+++ b/drivers/usb/typec/bus.c -@@ -154,12 +154,20 @@ EXPORT_SYMBOL_GPL(typec_altmode_exit); - * - * Notifies the partner of @adev about Attention command. - */ --void typec_altmode_attention(struct typec_altmode *adev, u32 vdo) -+int typec_altmode_attention(struct typec_altmode *adev, u32 vdo) - { -- struct typec_altmode *pdev = &to_altmode(adev)->partner->adev; -+ struct altmode *partner = to_altmode(adev)->partner; -+ struct typec_altmode *pdev; -+ -+ if (!partner) -+ return -ENODEV; -+ -+ pdev = &partner->adev; - - if (pdev->ops && pdev->ops->attention) - pdev->ops->attention(pdev, vdo); -+ -+ return 0; - } - EXPORT_SYMBOL_GPL(typec_altmode_attention); - -diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c -index 5f45b82dd1914..ad4d0314d27fa 100644 ---- a/drivers/usb/typec/tcpm/tcpm.c -+++ b/drivers/usb/typec/tcpm/tcpm.c -@@ -1871,7 +1871,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, - } - break; - case ADEV_ATTENTION: -- typec_altmode_attention(adev, p[1]); -+ if (typec_altmode_attention(adev, p[1])) -+ tcpm_log(port, "typec_altmode_attention no port partner altmode"); - break; - } - } -@@ -3929,6 +3930,29 @@ static enum typec_cc_status tcpm_pwr_opmode_to_rp(enum typec_pwr_opmode opmode) - } - } - -+static void tcpm_set_initial_svdm_version(struct tcpm_port *port) -+{ -+ switch (port->negotiated_rev) { -+ case PD_REV30: -+ break; -+ /* -+ * 6.4.4.2.3 Structured VDM Version -+ * 2.0 states "At this time, there is only one version (1.0) defined. -+ * This field Shall be set to zero to indicate Version 1.0." -+ * 3.0 states "This field Shall be set to 01b to indicate Version 2.0." -+ * To ensure that we follow the Power Delivery revision we are currently -+ * operating on, downgrade the SVDM version to the highest one supported -+ * by the Power Delivery revision. -+ */ -+ case PD_REV20: -+ typec_partner_set_svdm_version(port->partner, SVDM_VER_1_0); -+ break; -+ default: -+ typec_partner_set_svdm_version(port->partner, SVDM_VER_1_0); -+ break; -+ } -+} -+ - static void run_state_machine(struct tcpm_port *port) - { - int ret; -@@ -4153,10 +4177,12 @@ static void run_state_machine(struct tcpm_port *port) - * For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using - * port->explicit_contract to decide whether to send the command. - */ -- if (port->explicit_contract) -+ if (port->explicit_contract) { -+ tcpm_set_initial_svdm_version(port); - mod_send_discover_delayed_work(port, 0); -- else -+ } else { - port->send_discover = false; -+ } - - /* - * 6.3.5 -@@ -4439,10 +4465,12 @@ static void run_state_machine(struct tcpm_port *port) - * For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using - * port->explicit_contract. - */ -- if (port->explicit_contract) -+ if (port->explicit_contract) { -+ tcpm_set_initial_svdm_version(port); - mod_send_discover_delayed_work(port, 0); -- else -+ } else { - port->send_discover = false; -+ } - - power_supply_changed(port->psy); - break; -diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c -index 009ba186652ac..18a2dbbc77799 100644 ---- a/drivers/vfio/vfio_iommu_type1.c -+++ b/drivers/vfio/vfio_iommu_type1.c -@@ -2822,7 +2822,7 @@ static int vfio_iommu_iova_build_caps(struct vfio_iommu *iommu, - static int vfio_iommu_migration_build_caps(struct vfio_iommu *iommu, - struct vfio_info_cap *caps) - { -- struct vfio_iommu_type1_info_cap_migration cap_mig; -+ struct vfio_iommu_type1_info_cap_migration cap_mig = {}; - - cap_mig.header.id = VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION; - cap_mig.header.version = 1; -diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c -index a506872d43963..94fe628dd88c0 100644 ---- a/drivers/video/backlight/bd6107.c -+++ b/drivers/video/backlight/bd6107.c -@@ -104,7 +104,7 @@ static int bd6107_backlight_check_fb(struct backlight_device *backlight, - { - struct bd6107 *bd = bl_get_data(backlight); - -- return bd->pdata->fbdev == NULL || bd->pdata->fbdev == info->dev; -+ return bd->pdata->fbdev == NULL || bd->pdata->fbdev == info->device; - } - - static const struct backlight_ops bd6107_backlight_ops = { -diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c -index 6f78d928f054a..5c5c99f7979e3 100644 ---- a/drivers/video/backlight/gpio_backlight.c -+++ b/drivers/video/backlight/gpio_backlight.c -@@ -35,7 +35,7 @@ static int gpio_backlight_check_fb(struct backlight_device *bl, - { - struct gpio_backlight *gbl = bl_get_data(bl); - -- return gbl->fbdev == NULL || gbl->fbdev == info->dev; -+ return gbl->fbdev == NULL || gbl->fbdev == info->device; - } - - static const struct backlight_ops gpio_backlight_ops = { -diff --git a/drivers/video/backlight/lv5207lp.c b/drivers/video/backlight/lv5207lp.c -index 767b800d79faf..8a027a5ea552b 100644 ---- a/drivers/video/backlight/lv5207lp.c -+++ b/drivers/video/backlight/lv5207lp.c -@@ -67,7 +67,7 @@ static int lv5207lp_backlight_check_fb(struct backlight_device *backlight, - { - struct lv5207lp *lv = bl_get_data(backlight); - -- return lv->pdata->fbdev == NULL || lv->pdata->fbdev == info->dev; -+ return lv->pdata->fbdev == NULL || lv->pdata->fbdev == info->device; - } - - static const struct backlight_ops lv5207lp_backlight_ops = { -diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c -index 90d514c141794..7d320f799ca1e 100644 ---- a/drivers/virtio/virtio_ring.c -+++ b/drivers/virtio/virtio_ring.c -@@ -1449,7 +1449,7 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq, - } - } - -- if (i < head) -+ if (i <= head) - vq->packed.avail_wrap_counter ^= 1; - - /* We're using some buffers from the free list. */ -diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c -index 739e7d55c9e3d..1bf5c51a4c23b 100644 ---- a/fs/dlm/plock.c -+++ b/fs/dlm/plock.c -@@ -455,7 +455,8 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, - } - } else { - list_for_each_entry(iter, &recv_list, list) { -- if (!iter->info.wait) { -+ if (!iter->info.wait && -+ iter->info.fsid == info.fsid) { - op = iter; - break; - } -@@ -467,8 +468,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, - if (info.wait) - WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK); - else -- WARN_ON(op->info.fsid != info.fsid || -- op->info.number != info.number || -+ WARN_ON(op->info.number != info.number || - op->info.owner != info.owner || - op->info.optype != info.optype); - -diff --git a/fs/eventfd.c b/fs/eventfd.c -index 249ca6c0b7843..4a60ea932e3d9 100644 ---- a/fs/eventfd.c -+++ b/fs/eventfd.c -@@ -189,7 +189,7 @@ void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt) - { - lockdep_assert_held(&ctx->wqh.lock); - -- *cnt = (ctx->flags & EFD_SEMAPHORE) ? 1 : ctx->count; -+ *cnt = ((ctx->flags & EFD_SEMAPHORE) && ctx->count) ? 1 : ctx->count; - ctx->count -= *cnt; - } - EXPORT_SYMBOL_GPL(eventfd_ctx_do_read); -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 88ed64ebae3e7..016925b1a0908 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -966,8 +966,9 @@ static inline int should_optimize_scan(struct ext4_allocation_context *ac) - * Return next linear group for allocation. If linear traversal should not be - * performed, this function just returns the same group - */ --static int --next_linear_group(struct ext4_allocation_context *ac, int group, int ngroups) -+static ext4_group_t -+next_linear_group(struct ext4_allocation_context *ac, ext4_group_t group, -+ ext4_group_t ngroups) - { - if (!should_optimize_scan(ac)) - goto inc_and_return; -@@ -2401,7 +2402,7 @@ static bool ext4_mb_good_group(struct ext4_allocation_context *ac, - - BUG_ON(cr < 0 || cr >= 4); - -- if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(grp) || !grp)) -+ if (unlikely(!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp))) - return false; - - free = grp->bb_free; -diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c -index 0e1aeb9cb4a7c..6a08fc31a66de 100644 ---- a/fs/ext4/namei.c -+++ b/fs/ext4/namei.c -@@ -2799,6 +2799,7 @@ static int ext4_add_nondir(handle_t *handle, - return err; - } - drop_nlink(inode); -+ ext4_mark_inode_dirty(handle, inode); - ext4_orphan_add(handle, inode); - unlock_new_inode(inode); - return err; -@@ -3436,6 +3437,7 @@ retry: - - err_drop_inode: - clear_nlink(inode); -+ ext4_mark_inode_dirty(handle, inode); - ext4_orphan_add(handle, inode); - unlock_new_inode(inode); - if (handle) -@@ -4021,6 +4023,7 @@ end_rename: - ext4_resetent(handle, &old, - old.inode->i_ino, old_file_type); - drop_nlink(whiteout); -+ ext4_mark_inode_dirty(handle, whiteout); - ext4_orphan_add(handle, whiteout); - } - unlock_new_inode(whiteout); -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 4d1e48c676fab..c2b7d09238941 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -4453,7 +4453,8 @@ static inline bool f2fs_low_mem_mode(struct f2fs_sb_info *sbi) - static inline bool f2fs_may_compress(struct inode *inode) - { - if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) || -- f2fs_is_atomic_file(inode) || f2fs_has_inline_data(inode)) -+ f2fs_is_atomic_file(inode) || f2fs_has_inline_data(inode) || -+ f2fs_is_mmap_file(inode)) - return false; - return S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode); - } -diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c -index 7b94f047cbf79..746c71716bead 100644 ---- a/fs/f2fs/file.c -+++ b/fs/f2fs/file.c -@@ -530,7 +530,11 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma) - - file_accessed(file); - vma->vm_ops = &f2fs_file_vm_ops; -+ -+ f2fs_down_read(&F2FS_I(inode)->i_sem); - set_inode_flag(inode, FI_MMAP_FILE); -+ f2fs_up_read(&F2FS_I(inode)->i_sem); -+ - return 0; - } - -@@ -1927,12 +1931,19 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask) - int err = f2fs_convert_inline_inode(inode); - if (err) - return err; -- if (!f2fs_may_compress(inode)) -- return -EINVAL; -- if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode)) -+ -+ f2fs_down_write(&F2FS_I(inode)->i_sem); -+ if (!f2fs_may_compress(inode) || -+ (S_ISREG(inode->i_mode) && -+ F2FS_HAS_BLOCKS(inode))) { -+ f2fs_up_write(&F2FS_I(inode)->i_sem); - return -EINVAL; -- if (set_compress_context(inode)) -- return -EOPNOTSUPP; -+ } -+ err = set_compress_context(inode); -+ f2fs_up_write(&F2FS_I(inode)->i_sem); -+ -+ if (err) -+ return err; - } - } - -@@ -3958,6 +3969,7 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg) - file_start_write(filp); - inode_lock(inode); - -+ f2fs_down_write(&F2FS_I(inode)->i_sem); - if (f2fs_is_mmap_file(inode) || get_dirty_pages(inode)) { - ret = -EBUSY; - goto out; -@@ -3977,6 +3989,7 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg) - f2fs_warn(sbi, "compression algorithm is successfully set, " - "but current kernel doesn't support this algorithm."); - out: -+ f2fs_up_write(&F2FS_I(inode)->i_sem); - inode_unlock(inode); - file_end_write(filp); - -diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c -index aab3b8b3ab0a7..1fc7760499f10 100644 ---- a/fs/f2fs/inode.c -+++ b/fs/f2fs/inode.c -@@ -397,6 +397,12 @@ static int do_read_inode(struct inode *inode) - fi->i_inline_xattr_size = 0; - } - -+ if (!sanity_check_inode(inode, node_page)) { -+ f2fs_put_page(node_page, 1); -+ f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); -+ return -EFSCORRUPTED; -+ } -+ - /* check data exist */ - if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) - __recover_inline_status(inode, node_page); -@@ -459,12 +465,6 @@ static int do_read_inode(struct inode *inode) - /* Need all the flag bits */ - f2fs_init_read_extent_tree(inode, node_page); - -- if (!sanity_check_inode(inode, node_page)) { -- f2fs_put_page(node_page, 1); -- f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); -- return -EFSCORRUPTED; -- } -- - if (!sanity_check_extent_cache(inode)) { - f2fs_put_page(node_page, 1); - f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index b6dad389fa144..2046f633fe57a 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -858,11 +858,6 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) - if (!name) - return -ENOMEM; - if (!strcmp(name, "adaptive")) { -- if (f2fs_sb_has_blkzoned(sbi)) { -- f2fs_warn(sbi, "adaptive mode is not allowed with zoned block device feature"); -- kfree(name); -- return -EINVAL; -- } - F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE; - } else if (!strcmp(name, "lfs")) { - F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; -@@ -1285,19 +1280,23 @@ default_check: - * zone alignment optimization. This is optional for host-aware - * devices, but mandatory for host-managed zoned block devices. - */ --#ifndef CONFIG_BLK_DEV_ZONED -- if (f2fs_sb_has_blkzoned(sbi)) { -- f2fs_err(sbi, "Zoned block device support is not enabled"); -- return -EINVAL; -- } --#endif - if (f2fs_sb_has_blkzoned(sbi)) { -+#ifdef CONFIG_BLK_DEV_ZONED - if (F2FS_OPTION(sbi).discard_unit != - DISCARD_UNIT_SECTION) { - f2fs_info(sbi, "Zoned block device doesn't need small discard, set discard_unit=section by default"); - F2FS_OPTION(sbi).discard_unit = - DISCARD_UNIT_SECTION; - } -+ -+ if (F2FS_OPTION(sbi).fs_mode != FS_MODE_LFS) { -+ f2fs_info(sbi, "Only lfs mode is allowed with zoned block device feature"); -+ return -EINVAL; -+ } -+#else -+ f2fs_err(sbi, "Zoned block device support is not enabled"); -+ return -EINVAL; -+#endif - } - - #ifdef CONFIG_F2FS_FS_COMPRESSION -diff --git a/fs/fs_context.c b/fs/fs_context.c -index 851214d1d013d..375023e40161d 100644 ---- a/fs/fs_context.c -+++ b/fs/fs_context.c -@@ -315,10 +315,31 @@ struct fs_context *fs_context_for_reconfigure(struct dentry *dentry, - } - EXPORT_SYMBOL(fs_context_for_reconfigure); - -+/** -+ * fs_context_for_submount: allocate a new fs_context for a submount -+ * @type: file_system_type of the new context -+ * @reference: reference dentry from which to copy relevant info -+ * -+ * Allocate a new fs_context suitable for a submount. This also ensures that -+ * the fc->security object is inherited from @reference (if needed). -+ */ - struct fs_context *fs_context_for_submount(struct file_system_type *type, - struct dentry *reference) - { -- return alloc_fs_context(type, reference, 0, 0, FS_CONTEXT_FOR_SUBMOUNT); -+ struct fs_context *fc; -+ int ret; -+ -+ fc = alloc_fs_context(type, reference, 0, 0, FS_CONTEXT_FOR_SUBMOUNT); -+ if (IS_ERR(fc)) -+ return fc; -+ -+ ret = security_fs_context_submount(fc, reference->d_sb); -+ if (ret) { -+ put_fs_context(fc); -+ return ERR_PTR(ret); -+ } -+ -+ return fc; - } - EXPORT_SYMBOL(fs_context_for_submount); - -diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c -index 91ee0b308e13d..a0a4d8de82cad 100644 ---- a/fs/iomap/buffered-io.c -+++ b/fs/iomap/buffered-io.c -@@ -488,11 +488,6 @@ void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len) - WARN_ON_ONCE(folio_test_writeback(folio)); - folio_cancel_dirty(folio); - iomap_page_release(folio); -- } else if (folio_test_large(folio)) { -- /* Must release the iop so the page can be split */ -- WARN_ON_ONCE(!folio_test_uptodate(folio) && -- folio_test_dirty(folio)); -- iomap_page_release(folio); - } - } - EXPORT_SYMBOL_GPL(iomap_invalidate_folio); -diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c -index ae99a7e232eeb..a82751e6c47f9 100644 ---- a/fs/jfs/jfs_extent.c -+++ b/fs/jfs/jfs_extent.c -@@ -311,6 +311,11 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) - * blocks in the map. in that case, we'll start off with the - * maximum free. - */ -+ -+ /* give up if no space left */ -+ if (bmp->db_maxfreebud == -1) -+ return -ENOSPC; -+ - max = (s64) 1 << bmp->db_maxfreebud; - if (*nblocks >= max && *nblocks > nbperpage) - nb = nblks = (max > nbperpage) ? max : nbperpage; -diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c -index 1d9488cf05348..87a0f207df0b9 100644 ---- a/fs/lockd/mon.c -+++ b/fs/lockd/mon.c -@@ -276,6 +276,9 @@ static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap, - { - struct nsm_handle *new; - -+ if (!hostname) -+ return NULL; -+ - new = kzalloc(sizeof(*new) + hostname_len + 1, GFP_KERNEL); - if (unlikely(new == NULL)) - return NULL; -diff --git a/fs/namei.c b/fs/namei.c -index 5b3865ad9d052..4248647f1ab24 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2859,7 +2859,7 @@ int path_pts(struct path *path) - dput(path->dentry); - path->dentry = parent; - child = d_hash_and_lookup(parent, &this); -- if (!child) -+ if (IS_ERR_OR_NULL(child)) - return -ENOENT; - - path->dentry = child; -diff --git a/fs/nfs/blocklayout/dev.c b/fs/nfs/blocklayout/dev.c -index fea5f8821da5e..ce2ea62397972 100644 ---- a/fs/nfs/blocklayout/dev.c -+++ b/fs/nfs/blocklayout/dev.c -@@ -402,7 +402,7 @@ bl_parse_concat(struct nfs_server *server, struct pnfs_block_dev *d, - int ret, i; - - d->children = kcalloc(v->concat.volumes_count, -- sizeof(struct pnfs_block_dev), GFP_KERNEL); -+ sizeof(struct pnfs_block_dev), gfp_mask); - if (!d->children) - return -ENOMEM; - -@@ -431,7 +431,7 @@ bl_parse_stripe(struct nfs_server *server, struct pnfs_block_dev *d, - int ret, i; - - d->children = kcalloc(v->stripe.volumes_count, -- sizeof(struct pnfs_block_dev), GFP_KERNEL); -+ sizeof(struct pnfs_block_dev), gfp_mask); - if (!d->children) - return -ENOMEM; - -diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h -index ae7d4a8c728c2..4b07a0508f9d8 100644 ---- a/fs/nfs/internal.h -+++ b/fs/nfs/internal.h -@@ -484,6 +484,7 @@ struct nfs_pgio_completion_ops; - extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, - struct inode *inode, bool force_mds, - const struct nfs_pgio_completion_ops *compl_ops); -+extern bool nfs_read_alloc_scratch(struct nfs_pgio_header *hdr, size_t size); - extern void nfs_read_prepare(struct rpc_task *task, void *calldata); - extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio); - -diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c -index 05c3b4b2b3dd8..c190938142960 100644 ---- a/fs/nfs/nfs2xdr.c -+++ b/fs/nfs/nfs2xdr.c -@@ -949,7 +949,7 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, - - error = decode_filename_inline(xdr, &entry->name, &entry->len); - if (unlikely(error)) -- return -EAGAIN; -+ return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN; - - /* - * The type (size and byte order) of nfscookie isn't defined in -diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c -index 3b0b650c9c5ab..60f032be805ae 100644 ---- a/fs/nfs/nfs3xdr.c -+++ b/fs/nfs/nfs3xdr.c -@@ -1991,7 +1991,7 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, - - error = decode_inline_filename3(xdr, &entry->name, &entry->len); - if (unlikely(error)) -- return -EAGAIN; -+ return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN; - - error = decode_cookie3(xdr, &new_cookie); - if (unlikely(error)) -diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h -index 0fe5aacbcfdf1..b59876b01a1e3 100644 ---- a/fs/nfs/nfs42.h -+++ b/fs/nfs/nfs42.h -@@ -13,6 +13,7 @@ - * more? Need to consider not to pre-alloc too much for a compound. - */ - #define PNFS_LAYOUTSTATS_MAXDEV (4) -+#define READ_PLUS_SCRATCH_SIZE (16) - - /* nfs4.2proc.c */ - #ifdef CONFIG_NFS_V4_2 -diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c -index 7c33bba179d2f..d903ea10410c2 100644 ---- a/fs/nfs/nfs42proc.c -+++ b/fs/nfs/nfs42proc.c -@@ -470,8 +470,9 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, - continue; - } - break; -- } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) { -- args.sync = true; -+ } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && -+ args.sync != res.synchronous) { -+ args.sync = res.synchronous; - dst_exception.retry = 1; - continue; - } else if ((err == -ESTALE || -diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c -index 2fd465cab631d..20aa5e746497d 100644 ---- a/fs/nfs/nfs42xdr.c -+++ b/fs/nfs/nfs42xdr.c -@@ -47,13 +47,20 @@ - #define decode_deallocate_maxsz (op_decode_hdr_maxsz) - #define encode_read_plus_maxsz (op_encode_hdr_maxsz + \ - encode_stateid_maxsz + 3) --#define NFS42_READ_PLUS_SEGMENT_SIZE (1 /* data_content4 */ + \ -+#define NFS42_READ_PLUS_DATA_SEGMENT_SIZE \ -+ (1 /* data_content4 */ + \ -+ 2 /* data_info4.di_offset */ + \ -+ 1 /* data_info4.di_length */) -+#define NFS42_READ_PLUS_HOLE_SEGMENT_SIZE \ -+ (1 /* data_content4 */ + \ - 2 /* data_info4.di_offset */ + \ - 2 /* data_info4.di_length */) -+#define READ_PLUS_SEGMENT_SIZE_DIFF (NFS42_READ_PLUS_HOLE_SEGMENT_SIZE - \ -+ NFS42_READ_PLUS_DATA_SEGMENT_SIZE) - #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \ - 1 /* rpr_eof */ + \ - 1 /* rpr_contents count */ + \ -- 2 * NFS42_READ_PLUS_SEGMENT_SIZE) -+ NFS42_READ_PLUS_HOLE_SEGMENT_SIZE) - #define encode_seek_maxsz (op_encode_hdr_maxsz + \ - encode_stateid_maxsz + \ - 2 /* offset */ + \ -@@ -780,8 +787,8 @@ static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req, - encode_putfh(xdr, args->fh, &hdr); - encode_read_plus(xdr, args, &hdr); - -- rpc_prepare_reply_pages(req, args->pages, args->pgbase, -- args->count, hdr.replen); -+ rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->count, -+ hdr.replen - READ_PLUS_SEGMENT_SIZE_DIFF); - encode_nops(&hdr); - } - -@@ -1121,7 +1128,6 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) - uint32_t segments; - struct read_plus_segment *segs; - int status, i; -- char scratch_buf[16]; - __be32 *p; - - status = decode_op_hdr(xdr, OP_READ_PLUS); -@@ -1136,14 +1142,12 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) - res->eof = be32_to_cpup(p++); - segments = be32_to_cpup(p++); - if (segments == 0) -- return status; -+ return 0; - - segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL); - if (!segs) - return -ENOMEM; - -- xdr_set_scratch_buffer(xdr, &scratch_buf, sizeof(scratch_buf)); -- status = -EIO; - for (i = 0; i < segments; i++) { - status = decode_read_plus_segment(xdr, &segs[i]); - if (status < 0) -@@ -1347,6 +1351,8 @@ static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp, - struct compound_hdr hdr; - int status; - -+ xdr_set_scratch_buffer(xdr, res->scratch, READ_PLUS_SCRATCH_SIZE); -+ - status = decode_compound_hdr(xdr, &hdr); - if (status) - goto out; -diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index 1044305e77996..2dec0fed1ba16 100644 ---- a/fs/nfs/nfs4proc.c -+++ b/fs/nfs/nfs4proc.c -@@ -5459,17 +5459,21 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) - } - - #if defined CONFIG_NFS_V4_2 && defined CONFIG_NFS_V4_2_READ_PLUS --static void nfs42_read_plus_support(struct nfs_pgio_header *hdr, -+static bool nfs42_read_plus_support(struct nfs_pgio_header *hdr, - struct rpc_message *msg) - { - /* Note: We don't use READ_PLUS with pNFS yet */ -- if (nfs_server_capable(hdr->inode, NFS_CAP_READ_PLUS) && !hdr->ds_clp) -+ if (nfs_server_capable(hdr->inode, NFS_CAP_READ_PLUS) && !hdr->ds_clp) { - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS]; -+ return nfs_read_alloc_scratch(hdr, READ_PLUS_SCRATCH_SIZE); -+ } -+ return false; - } - #else --static void nfs42_read_plus_support(struct nfs_pgio_header *hdr, -+static bool nfs42_read_plus_support(struct nfs_pgio_header *hdr, - struct rpc_message *msg) - { -+ return false; - } - #endif /* CONFIG_NFS_V4_2 */ - -@@ -5479,8 +5483,8 @@ static void nfs4_proc_read_setup(struct nfs_pgio_header *hdr, - hdr->timestamp = jiffies; - if (!hdr->pgio_done_cb) - hdr->pgio_done_cb = nfs4_read_done_cb; -- msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; -- nfs42_read_plus_support(hdr, msg); -+ if (!nfs42_read_plus_support(hdr, msg)) -+ msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; - nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0); - } - -diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c -index 5d035dd2d7bf0..47a8da3f5c9ff 100644 ---- a/fs/nfs/pnfs_nfs.c -+++ b/fs/nfs/pnfs_nfs.c -@@ -943,7 +943,7 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, - * Test this address for session trunking and - * add as an alias - */ -- xprtdata.cred = nfs4_get_clid_cred(clp), -+ xprtdata.cred = nfs4_get_clid_cred(clp); - rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, - rpc_clnt_setup_test_and_add_xprt, - &rpcdata); -diff --git a/fs/nfs/read.c b/fs/nfs/read.c -index cd970ce62786b..6aad42fbf797a 100644 ---- a/fs/nfs/read.c -+++ b/fs/nfs/read.c -@@ -47,6 +47,8 @@ static struct nfs_pgio_header *nfs_readhdr_alloc(void) - - static void nfs_readhdr_free(struct nfs_pgio_header *rhdr) - { -+ if (rhdr->res.scratch != NULL) -+ kfree(rhdr->res.scratch); - kmem_cache_free(nfs_rdata_cachep, rhdr); - } - -@@ -109,6 +111,14 @@ void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio) - } - EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds); - -+bool nfs_read_alloc_scratch(struct nfs_pgio_header *hdr, size_t size) -+{ -+ WARN_ON(hdr->res.scratch != NULL); -+ hdr->res.scratch = kmalloc(size, GFP_KERNEL); -+ return hdr->res.scratch != NULL; -+} -+EXPORT_SYMBOL_GPL(nfs_read_alloc_scratch); -+ - static void nfs_readpage_release(struct nfs_page *req, int error) - { - struct inode *inode = d_inode(nfs_req_openctx(req)->dentry); -diff --git a/fs/nfsd/blocklayoutxdr.c b/fs/nfsd/blocklayoutxdr.c -index 442543304930b..2455dc8be18a8 100644 ---- a/fs/nfsd/blocklayoutxdr.c -+++ b/fs/nfsd/blocklayoutxdr.c -@@ -82,6 +82,15 @@ nfsd4_block_encode_getdeviceinfo(struct xdr_stream *xdr, - int len = sizeof(__be32), ret, i; - __be32 *p; - -+ /* -+ * See paragraph 5 of RFC 8881 S18.40.3. -+ */ -+ if (!gdp->gd_maxcount) { -+ if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT) -+ return nfserr_resource; -+ return nfs_ok; -+ } -+ - p = xdr_reserve_space(xdr, len + sizeof(__be32)); - if (!p) - return nfserr_resource; -diff --git a/fs/nfsd/flexfilelayoutxdr.c b/fs/nfsd/flexfilelayoutxdr.c -index e81d2a5cf381e..bb205328e043d 100644 ---- a/fs/nfsd/flexfilelayoutxdr.c -+++ b/fs/nfsd/flexfilelayoutxdr.c -@@ -85,6 +85,15 @@ nfsd4_ff_encode_getdeviceinfo(struct xdr_stream *xdr, - int addr_len; - __be32 *p; - -+ /* -+ * See paragraph 5 of RFC 8881 S18.40.3. -+ */ -+ if (!gdp->gd_maxcount) { -+ if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT) -+ return nfserr_resource; -+ return nfs_ok; -+ } -+ - /* len + padding for two strings */ - addr_len = 16 + da->netaddr.netid_len + da->netaddr.addr_len; - ver_len = 20; -diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c -index 8f90a87ee9ca0..89a579be042e5 100644 ---- a/fs/nfsd/nfs4xdr.c -+++ b/fs/nfsd/nfs4xdr.c -@@ -4571,20 +4571,17 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr, - - *p++ = cpu_to_be32(gdev->gd_layout_type); - -- /* If maxcount is 0 then just update notifications */ -- if (gdev->gd_maxcount != 0) { -- ops = nfsd4_layout_ops[gdev->gd_layout_type]; -- nfserr = ops->encode_getdeviceinfo(xdr, gdev); -- if (nfserr) { -- /* -- * We don't bother to burden the layout drivers with -- * enforcing gd_maxcount, just tell the client to -- * come back with a bigger buffer if it's not enough. -- */ -- if (xdr->buf->len + 4 > gdev->gd_maxcount) -- goto toosmall; -- return nfserr; -- } -+ ops = nfsd4_layout_ops[gdev->gd_layout_type]; -+ nfserr = ops->encode_getdeviceinfo(xdr, gdev); -+ if (nfserr) { -+ /* -+ * We don't bother to burden the layout drivers with -+ * enforcing gd_maxcount, just tell the client to -+ * come back with a bigger buffer if it's not enough. -+ */ -+ if (xdr->buf->len + 4 > gdev->gd_maxcount) -+ goto toosmall; -+ return nfserr; - } - - if (gdev->gd_notify_types) { -diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c -index 52ccd34b1e792..a026dbd3593f6 100644 ---- a/fs/nls/nls_base.c -+++ b/fs/nls/nls_base.c -@@ -272,7 +272,7 @@ int unregister_nls(struct nls_table * nls) - return -EINVAL; - } - --static struct nls_table *find_nls(char *charset) -+static struct nls_table *find_nls(const char *charset) - { - struct nls_table *nls; - spin_lock(&nls_lock); -@@ -288,7 +288,7 @@ static struct nls_table *find_nls(char *charset) - return nls; - } - --struct nls_table *load_nls(char *charset) -+struct nls_table *load_nls(const char *charset) - { - return try_then_request_module(find_nls(charset), "nls_%s", charset); - } -diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c -index 1c7ac433667df..04a8505bd97af 100644 ---- a/fs/ocfs2/namei.c -+++ b/fs/ocfs2/namei.c -@@ -1535,6 +1535,10 @@ static int ocfs2_rename(struct user_namespace *mnt_userns, - status = ocfs2_add_entry(handle, new_dentry, old_inode, - OCFS2_I(old_inode)->ip_blkno, - new_dir_bh, &target_insert); -+ if (status < 0) { -+ mlog_errno(status); -+ goto bail; -+ } - } - - old_inode->i_ctime = current_time(old_inode); -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index 51eec4a8e82b2..08d3a1f34ac6c 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -2155,7 +2155,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) - ovl_trusted_xattr_handlers; - sb->s_fs_info = ofs; - sb->s_flags |= SB_POSIXACL; -- sb->s_iflags |= SB_I_SKIP_SYNC; -+ sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE; - - err = -ENOMEM; - root_dentry = ovl_get_root(sb, upperpath.dentry, oe); -diff --git a/fs/proc/base.c b/fs/proc/base.c -index 9e479d7d202b1..74442e01793f3 100644 ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -3581,7 +3581,8 @@ static int proc_tid_comm_permission(struct user_namespace *mnt_userns, - } - - static const struct inode_operations proc_tid_comm_inode_operations = { -- .permission = proc_tid_comm_permission, -+ .setattr = proc_setattr, -+ .permission = proc_tid_comm_permission, - }; - - /* -diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c -index 2384de1c2d187..1e755d093d921 100644 ---- a/fs/pstore/ram_core.c -+++ b/fs/pstore/ram_core.c -@@ -518,7 +518,7 @@ static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig, - sig ^= PERSISTENT_RAM_SIG; - - if (prz->buffer->sig == sig) { -- if (buffer_size(prz) == 0) { -+ if (buffer_size(prz) == 0 && buffer_start(prz) == 0) { - pr_debug("found existing empty buffer\n"); - return 0; - } -diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c -index 46dca88d89c36..53b65c5300fde 100644 ---- a/fs/quota/dquot.c -+++ b/fs/quota/dquot.c -@@ -225,13 +225,22 @@ static void put_quota_format(struct quota_format_type *fmt) - - /* - * Dquot List Management: -- * The quota code uses four lists for dquot management: the inuse_list, -- * free_dquots, dqi_dirty_list, and dquot_hash[] array. A single dquot -- * structure may be on some of those lists, depending on its current state. -+ * The quota code uses five lists for dquot management: the inuse_list, -+ * releasing_dquots, free_dquots, dqi_dirty_list, and dquot_hash[] array. -+ * A single dquot structure may be on some of those lists, depending on -+ * its current state. - * - * All dquots are placed to the end of inuse_list when first created, and this - * list is used for invalidate operation, which must look at every dquot. - * -+ * When the last reference of a dquot will be dropped, the dquot will be -+ * added to releasing_dquots. We'd then queue work item which would call -+ * synchronize_srcu() and after that perform the final cleanup of all the -+ * dquots on the list. Both releasing_dquots and free_dquots use the -+ * dq_free list_head in the dquot struct. When a dquot is removed from -+ * releasing_dquots, a reference count is always subtracted, and if -+ * dq_count == 0 at that point, the dquot will be added to the free_dquots. -+ * - * Unused dquots (dq_count == 0) are added to the free_dquots list when freed, - * and this list is searched whenever we need an available dquot. Dquots are - * removed from the list as soon as they are used again, and -@@ -250,6 +259,7 @@ static void put_quota_format(struct quota_format_type *fmt) - - static LIST_HEAD(inuse_list); - static LIST_HEAD(free_dquots); -+static LIST_HEAD(releasing_dquots); - static unsigned int dq_hash_bits, dq_hash_mask; - static struct hlist_head *dquot_hash; - -@@ -260,6 +270,9 @@ static qsize_t inode_get_rsv_space(struct inode *inode); - static qsize_t __inode_get_rsv_space(struct inode *inode); - static int __dquot_initialize(struct inode *inode, int type); - -+static void quota_release_workfn(struct work_struct *work); -+static DECLARE_DELAYED_WORK(quota_release_work, quota_release_workfn); -+ - static inline unsigned int - hashfn(const struct super_block *sb, struct kqid qid) - { -@@ -305,12 +318,18 @@ static inline void put_dquot_last(struct dquot *dquot) - dqstats_inc(DQST_FREE_DQUOTS); - } - -+static inline void put_releasing_dquots(struct dquot *dquot) -+{ -+ list_add_tail(&dquot->dq_free, &releasing_dquots); -+} -+ - static inline void remove_free_dquot(struct dquot *dquot) - { - if (list_empty(&dquot->dq_free)) - return; - list_del_init(&dquot->dq_free); -- dqstats_dec(DQST_FREE_DQUOTS); -+ if (!atomic_read(&dquot->dq_count)) -+ dqstats_dec(DQST_FREE_DQUOTS); - } - - static inline void put_inuse(struct dquot *dquot) -@@ -336,6 +355,11 @@ static void wait_on_dquot(struct dquot *dquot) - mutex_unlock(&dquot->dq_lock); - } - -+static inline int dquot_active(struct dquot *dquot) -+{ -+ return test_bit(DQ_ACTIVE_B, &dquot->dq_flags); -+} -+ - static inline int dquot_dirty(struct dquot *dquot) - { - return test_bit(DQ_MOD_B, &dquot->dq_flags); -@@ -351,14 +375,14 @@ int dquot_mark_dquot_dirty(struct dquot *dquot) - { - int ret = 1; - -- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) -+ if (!dquot_active(dquot)) - return 0; - - if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY) - return test_and_set_bit(DQ_MOD_B, &dquot->dq_flags); - - /* If quota is dirty already, we don't have to acquire dq_list_lock */ -- if (test_bit(DQ_MOD_B, &dquot->dq_flags)) -+ if (dquot_dirty(dquot)) - return 1; - - spin_lock(&dq_list_lock); -@@ -440,7 +464,7 @@ int dquot_acquire(struct dquot *dquot) - smp_mb__before_atomic(); - set_bit(DQ_READ_B, &dquot->dq_flags); - /* Instantiate dquot if needed */ -- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { -+ if (!dquot_active(dquot) && !dquot->dq_off) { - ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); - /* Write the info if needed */ - if (info_dirty(&dqopt->info[dquot->dq_id.type])) { -@@ -482,7 +506,7 @@ int dquot_commit(struct dquot *dquot) - goto out_lock; - /* Inactive dquot can be only if there was error during read/init - * => we have better not writing it */ -- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) -+ if (dquot_active(dquot)) - ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); - else - ret = -EIO; -@@ -547,6 +571,8 @@ static void invalidate_dquots(struct super_block *sb, int type) - struct dquot *dquot, *tmp; - - restart: -+ flush_delayed_work("a_release_work); -+ - spin_lock(&dq_list_lock); - list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { - if (dquot->dq_sb != sb) -@@ -555,6 +581,12 @@ restart: - continue; - /* Wait for dquot users */ - if (atomic_read(&dquot->dq_count)) { -+ /* dquot in releasing_dquots, flush and retry */ -+ if (!list_empty(&dquot->dq_free)) { -+ spin_unlock(&dq_list_lock); -+ goto restart; -+ } -+ - atomic_inc(&dquot->dq_count); - spin_unlock(&dq_list_lock); - /* -@@ -597,7 +629,7 @@ int dquot_scan_active(struct super_block *sb, - - spin_lock(&dq_list_lock); - list_for_each_entry(dquot, &inuse_list, dq_inuse) { -- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) -+ if (!dquot_active(dquot)) - continue; - if (dquot->dq_sb != sb) - continue; -@@ -612,7 +644,7 @@ int dquot_scan_active(struct super_block *sb, - * outstanding call and recheck the DQ_ACTIVE_B after that. - */ - wait_on_dquot(dquot); -- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { -+ if (dquot_active(dquot)) { - ret = fn(dquot, priv); - if (ret < 0) - goto out; -@@ -628,6 +660,18 @@ out: - } - EXPORT_SYMBOL(dquot_scan_active); - -+static inline int dquot_write_dquot(struct dquot *dquot) -+{ -+ int ret = dquot->dq_sb->dq_op->write_dquot(dquot); -+ if (ret < 0) { -+ quota_error(dquot->dq_sb, "Can't write quota structure " -+ "(error %d). Quota may get out of sync!", ret); -+ /* Clear dirty bit anyway to avoid infinite loop. */ -+ clear_dquot_dirty(dquot); -+ } -+ return ret; -+} -+ - /* Write all dquot structures to quota files */ - int dquot_writeback_dquots(struct super_block *sb, int type) - { -@@ -651,23 +695,16 @@ int dquot_writeback_dquots(struct super_block *sb, int type) - dquot = list_first_entry(&dirty, struct dquot, - dq_dirty); - -- WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)); -+ WARN_ON(!dquot_active(dquot)); - - /* Now we have active dquot from which someone is - * holding reference so we can safely just increase - * use count */ - dqgrab(dquot); - spin_unlock(&dq_list_lock); -- err = sb->dq_op->write_dquot(dquot); -- if (err) { -- /* -- * Clear dirty bit anyway to avoid infinite -- * loop here. -- */ -- clear_dquot_dirty(dquot); -- if (!ret) -- ret = err; -- } -+ err = dquot_write_dquot(dquot); -+ if (err && !ret) -+ ret = err; - dqput(dquot); - spin_lock(&dq_list_lock); - } -@@ -760,13 +797,54 @@ static struct shrinker dqcache_shrinker = { - .seeks = DEFAULT_SEEKS, - }; - -+/* -+ * Safely release dquot and put reference to dquot. -+ */ -+static void quota_release_workfn(struct work_struct *work) -+{ -+ struct dquot *dquot; -+ struct list_head rls_head; -+ -+ spin_lock(&dq_list_lock); -+ /* Exchange the list head to avoid livelock. */ -+ list_replace_init(&releasing_dquots, &rls_head); -+ spin_unlock(&dq_list_lock); -+ -+restart: -+ synchronize_srcu(&dquot_srcu); -+ spin_lock(&dq_list_lock); -+ while (!list_empty(&rls_head)) { -+ dquot = list_first_entry(&rls_head, struct dquot, dq_free); -+ /* Dquot got used again? */ -+ if (atomic_read(&dquot->dq_count) > 1) { -+ remove_free_dquot(dquot); -+ atomic_dec(&dquot->dq_count); -+ continue; -+ } -+ if (dquot_dirty(dquot)) { -+ spin_unlock(&dq_list_lock); -+ /* Commit dquot before releasing */ -+ dquot_write_dquot(dquot); -+ goto restart; -+ } -+ if (dquot_active(dquot)) { -+ spin_unlock(&dq_list_lock); -+ dquot->dq_sb->dq_op->release_dquot(dquot); -+ goto restart; -+ } -+ /* Dquot is inactive and clean, now move it to free list */ -+ remove_free_dquot(dquot); -+ atomic_dec(&dquot->dq_count); -+ put_dquot_last(dquot); -+ } -+ spin_unlock(&dq_list_lock); -+} -+ - /* - * Put reference to dquot - */ - void dqput(struct dquot *dquot) - { -- int ret; -- - if (!dquot) - return; - #ifdef CONFIG_QUOTA_DEBUG -@@ -778,7 +856,7 @@ void dqput(struct dquot *dquot) - } - #endif - dqstats_inc(DQST_DROPS); --we_slept: -+ - spin_lock(&dq_list_lock); - if (atomic_read(&dquot->dq_count) > 1) { - /* We have more than one user... nothing to do */ -@@ -790,35 +868,15 @@ we_slept: - spin_unlock(&dq_list_lock); - return; - } -+ - /* Need to release dquot? */ -- if (dquot_dirty(dquot)) { -- spin_unlock(&dq_list_lock); -- /* Commit dquot before releasing */ -- ret = dquot->dq_sb->dq_op->write_dquot(dquot); -- if (ret < 0) { -- quota_error(dquot->dq_sb, "Can't write quota structure" -- " (error %d). Quota may get out of sync!", -- ret); -- /* -- * We clear dirty bit anyway, so that we avoid -- * infinite loop here -- */ -- clear_dquot_dirty(dquot); -- } -- goto we_slept; -- } -- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { -- spin_unlock(&dq_list_lock); -- dquot->dq_sb->dq_op->release_dquot(dquot); -- goto we_slept; -- } -- atomic_dec(&dquot->dq_count); - #ifdef CONFIG_QUOTA_DEBUG - /* sanity check */ - BUG_ON(!list_empty(&dquot->dq_free)); - #endif -- put_dquot_last(dquot); -+ put_releasing_dquots(dquot); - spin_unlock(&dq_list_lock); -+ queue_delayed_work(system_unbound_wq, "a_release_work, 1); - } - EXPORT_SYMBOL(dqput); - -@@ -908,7 +966,7 @@ we_slept: - * already finished or it will be canceled due to dq_count > 1 test */ - wait_on_dquot(dquot); - /* Read the dquot / allocate space in quota file */ -- if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { -+ if (!dquot_active(dquot)) { - int err; - - err = sb->dq_op->acquire_dquot(dquot); -@@ -1425,7 +1483,7 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space) - return QUOTA_NL_NOWARN; - } - --static int dquot_active(const struct inode *inode) -+static int inode_quota_active(const struct inode *inode) - { - struct super_block *sb = inode->i_sb; - -@@ -1448,7 +1506,7 @@ static int __dquot_initialize(struct inode *inode, int type) - qsize_t rsv; - int ret = 0; - -- if (!dquot_active(inode)) -+ if (!inode_quota_active(inode)) - return 0; - - dquots = i_dquot(inode); -@@ -1556,7 +1614,7 @@ bool dquot_initialize_needed(struct inode *inode) - struct dquot **dquots; - int i; - -- if (!dquot_active(inode)) -+ if (!inode_quota_active(inode)) - return false; - - dquots = i_dquot(inode); -@@ -1667,7 +1725,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) - int reserve = flags & DQUOT_SPACE_RESERVE; - struct dquot **dquots; - -- if (!dquot_active(inode)) { -+ if (!inode_quota_active(inode)) { - if (reserve) { - spin_lock(&inode->i_lock); - *inode_reserved_space(inode) += number; -@@ -1737,7 +1795,7 @@ int dquot_alloc_inode(struct inode *inode) - struct dquot_warn warn[MAXQUOTAS]; - struct dquot * const *dquots; - -- if (!dquot_active(inode)) -+ if (!inode_quota_active(inode)) - return 0; - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - warn[cnt].w_type = QUOTA_NL_NOWARN; -@@ -1780,7 +1838,7 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) - struct dquot **dquots; - int cnt, index; - -- if (!dquot_active(inode)) { -+ if (!inode_quota_active(inode)) { - spin_lock(&inode->i_lock); - *inode_reserved_space(inode) -= number; - __inode_add_bytes(inode, number); -@@ -1822,7 +1880,7 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) - struct dquot **dquots; - int cnt, index; - -- if (!dquot_active(inode)) { -+ if (!inode_quota_active(inode)) { - spin_lock(&inode->i_lock); - *inode_reserved_space(inode) += number; - __inode_sub_bytes(inode, number); -@@ -1866,7 +1924,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) - struct dquot **dquots; - int reserve = flags & DQUOT_SPACE_RESERVE, index; - -- if (!dquot_active(inode)) { -+ if (!inode_quota_active(inode)) { - if (reserve) { - spin_lock(&inode->i_lock); - *inode_reserved_space(inode) -= number; -@@ -1921,7 +1979,7 @@ void dquot_free_inode(struct inode *inode) - struct dquot * const *dquots; - int index; - -- if (!dquot_active(inode)) -+ if (!inode_quota_active(inode)) - return; - - dquots = i_dquot(inode); -@@ -2093,7 +2151,7 @@ int dquot_transfer(struct user_namespace *mnt_userns, struct inode *inode, - struct super_block *sb = inode->i_sb; - int ret; - -- if (!dquot_active(inode)) -+ if (!inode_quota_active(inode)) - return 0; - - if (i_uid_needs_update(mnt_userns, iattr, inode)) { -diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c -index 9f62da7471c9e..eb81b4170cb51 100644 ---- a/fs/reiserfs/journal.c -+++ b/fs/reiserfs/journal.c -@@ -2326,7 +2326,7 @@ static struct buffer_head *reiserfs_breada(struct block_device *dev, - int i, j; - - bh = __getblk(dev, block, bufsize); -- if (buffer_uptodate(bh)) -+ if (!bh || buffer_uptodate(bh)) - return (bh); - - if (block + BUFNR > max_block) { -@@ -2336,6 +2336,8 @@ static struct buffer_head *reiserfs_breada(struct block_device *dev, - j = 1; - for (i = 1; i < blocks; i++) { - bh = __getblk(dev, block + i, bufsize); -+ if (!bh) -+ break; - if (buffer_uptodate(bh)) { - brelse(bh); - break; -diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h -index a37afbb7e399f..4a092cc5a3936 100644 ---- a/fs/smb/client/cifsglob.h -+++ b/fs/smb/client/cifsglob.h -@@ -970,43 +970,6 @@ release_iface(struct kref *ref) - kfree(iface); - } - --/* -- * compare two interfaces a and b -- * return 0 if everything matches. -- * return 1 if a has higher link speed, or rdma capable, or rss capable -- * return -1 otherwise. -- */ --static inline int --iface_cmp(struct cifs_server_iface *a, struct cifs_server_iface *b) --{ -- int cmp_ret = 0; -- -- WARN_ON(!a || !b); -- if (a->speed == b->speed) { -- if (a->rdma_capable == b->rdma_capable) { -- if (a->rss_capable == b->rss_capable) { -- cmp_ret = memcmp(&a->sockaddr, &b->sockaddr, -- sizeof(a->sockaddr)); -- if (!cmp_ret) -- return 0; -- else if (cmp_ret > 0) -- return 1; -- else -- return -1; -- } else if (a->rss_capable > b->rss_capable) -- return 1; -- else -- return -1; -- } else if (a->rdma_capable > b->rdma_capable) -- return 1; -- else -- return -1; -- } else if (a->speed > b->speed) -- return 1; -- else -- return -1; --} -- - struct cifs_chan { - unsigned int in_reconnect : 1; /* if session setup in progress for this channel */ - struct TCP_Server_Info *server; -diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h -index 98513f5af3f96..a914b88ca51a1 100644 ---- a/fs/smb/client/cifsproto.h -+++ b/fs/smb/client/cifsproto.h -@@ -85,6 +85,7 @@ extern int cifs_handle_standard(struct TCP_Server_Info *server, - struct mid_q_entry *mid); - extern int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx); - extern int smb3_parse_opt(const char *options, const char *key, char **val); -+extern int cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs); - extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs); - extern int cifs_discard_remaining_data(struct TCP_Server_Info *server); - extern int cifs_call_async(struct TCP_Server_Info *server, -diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c -index cbe08948baf4a..9cd282960c0bb 100644 ---- a/fs/smb/client/connect.c -+++ b/fs/smb/client/connect.c -@@ -1343,6 +1343,56 @@ next_pdu: - module_put_and_kthread_exit(0); - } - -+int -+cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs) -+{ -+ struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr; -+ struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs; -+ struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr; -+ struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs; -+ -+ switch (srcaddr->sa_family) { -+ case AF_UNSPEC: -+ switch (rhs->sa_family) { -+ case AF_UNSPEC: -+ return 0; -+ case AF_INET: -+ case AF_INET6: -+ return 1; -+ default: -+ return -1; -+ } -+ case AF_INET: { -+ switch (rhs->sa_family) { -+ case AF_UNSPEC: -+ return -1; -+ case AF_INET: -+ return memcmp(saddr4, vaddr4, -+ sizeof(struct sockaddr_in)); -+ case AF_INET6: -+ return 1; -+ default: -+ return -1; -+ } -+ } -+ case AF_INET6: { -+ switch (rhs->sa_family) { -+ case AF_UNSPEC: -+ case AF_INET: -+ return -1; -+ case AF_INET6: -+ return memcmp(saddr6, -+ vaddr6, -+ sizeof(struct sockaddr_in6)); -+ default: -+ return -1; -+ } -+ } -+ default: -+ return -1; /* don't expect to be here */ -+ } -+} -+ - /* - * Returns true if srcaddr isn't specified and rhs isn't specified, or - * if srcaddr is specified and matches the IP address of the rhs argument -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index e6a191a7499e8..6b020d80bb949 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -34,6 +34,8 @@ static int - change_conf(struct TCP_Server_Info *server) - { - server->credits += server->echo_credits + server->oplock_credits; -+ if (server->credits > server->max_credits) -+ server->credits = server->max_credits; - server->oplock_credits = server->echo_credits = 0; - switch (server->credits) { - case 0: -@@ -511,6 +513,43 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) - return rsize; - } - -+/* -+ * compare two interfaces a and b -+ * return 0 if everything matches. -+ * return 1 if a is rdma capable, or rss capable, or has higher link speed -+ * return -1 otherwise. -+ */ -+static int -+iface_cmp(struct cifs_server_iface *a, struct cifs_server_iface *b) -+{ -+ int cmp_ret = 0; -+ -+ WARN_ON(!a || !b); -+ if (a->rdma_capable == b->rdma_capable) { -+ if (a->rss_capable == b->rss_capable) { -+ if (a->speed == b->speed) { -+ cmp_ret = cifs_ipaddr_cmp((struct sockaddr *) &a->sockaddr, -+ (struct sockaddr *) &b->sockaddr); -+ if (!cmp_ret) -+ return 0; -+ else if (cmp_ret > 0) -+ return 1; -+ else -+ return -1; -+ } else if (a->speed > b->speed) -+ return 1; -+ else -+ return -1; -+ } else if (a->rss_capable > b->rss_capable) -+ return 1; -+ else -+ return -1; -+ } else if (a->rdma_capable > b->rdma_capable) -+ return 1; -+ else -+ return -1; -+} -+ - static int - parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, - size_t buf_len, struct cifs_ses *ses, bool in_mount) -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index ba46156e32680..ae17d78f6ba17 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -1312,7 +1312,12 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data) - } - - /* enough to enable echos and oplocks and one max size write */ -- req->hdr.CreditRequest = cpu_to_le16(130); -+ if (server->credits >= server->max_credits) -+ req->hdr.CreditRequest = cpu_to_le16(0); -+ else -+ req->hdr.CreditRequest = cpu_to_le16( -+ min_t(int, server->max_credits - -+ server->credits, 130)); - - /* only one of SMB2 signing flags may be set in SMB2 request */ - if (server->sign) -@@ -1907,7 +1912,12 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, - rqst.rq_nvec = 2; - - /* Need 64 for max size write so ask for more in case not there yet */ -- req->hdr.CreditRequest = cpu_to_le16(64); -+ if (server->credits >= server->max_credits) -+ req->hdr.CreditRequest = cpu_to_le16(0); -+ else -+ req->hdr.CreditRequest = cpu_to_le16( -+ min_t(int, server->max_credits - -+ server->credits, 64)); - - rc = cifs_send_recv(xid, ses, server, - &rqst, &resp_buftype, flags, &rsp_iov); -@@ -4291,6 +4301,7 @@ smb2_async_readv(struct cifs_readdata *rdata) - struct TCP_Server_Info *server; - struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); - unsigned int total_len; -+ int credit_request; - - cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n", - __func__, rdata->offset, rdata->bytes); -@@ -4322,7 +4333,13 @@ smb2_async_readv(struct cifs_readdata *rdata) - if (rdata->credits.value > 0) { - shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes, - SMB2_MAX_BUFFER_SIZE)); -- shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8); -+ credit_request = le16_to_cpu(shdr->CreditCharge) + 8; -+ if (server->credits >= server->max_credits) -+ shdr->CreditRequest = cpu_to_le16(0); -+ else -+ shdr->CreditRequest = cpu_to_le16( -+ min_t(int, server->max_credits - -+ server->credits, credit_request)); - - rc = adjust_credits(server, &rdata->credits, rdata->bytes); - if (rc) -@@ -4532,6 +4549,7 @@ smb2_async_writev(struct cifs_writedata *wdata, - unsigned int total_len; - struct cifs_io_parms _io_parms; - struct cifs_io_parms *io_parms = NULL; -+ int credit_request; - - if (!wdata->server) - server = wdata->server = cifs_pick_channel(tcon->ses); -@@ -4649,7 +4667,13 @@ smb2_async_writev(struct cifs_writedata *wdata, - if (wdata->credits.value > 0) { - shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes, - SMB2_MAX_BUFFER_SIZE)); -- shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8); -+ credit_request = le16_to_cpu(shdr->CreditCharge) + 8; -+ if (server->credits >= server->max_credits) -+ shdr->CreditRequest = cpu_to_le16(0); -+ else -+ shdr->CreditRequest = cpu_to_le16( -+ min_t(int, server->max_credits - -+ server->credits, credit_request)); - - rc = adjust_credits(server, &wdata->credits, io_parms->length); - if (rc) -diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c -index 847ee62afb8a1..9804cabe72a84 100644 ---- a/fs/smb/server/server.c -+++ b/fs/smb/server/server.c -@@ -286,6 +286,7 @@ static void handle_ksmbd_work(struct work_struct *wk) - static int queue_ksmbd_work(struct ksmbd_conn *conn) - { - struct ksmbd_work *work; -+ int err; - - work = ksmbd_alloc_work_struct(); - if (!work) { -@@ -297,7 +298,11 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn) - work->request_buf = conn->request_buf; - conn->request_buf = NULL; - -- ksmbd_init_smb_server(work); -+ err = ksmbd_init_smb_server(work); -+ if (err) { -+ ksmbd_free_work_struct(work); -+ return 0; -+ } - - ksmbd_conn_enqueue_request(work); - atomic_inc(&conn->r_count); -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index 9b621fd993bb7..f6fd5cf976a50 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -86,9 +86,9 @@ struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn - */ - int smb2_get_ksmbd_tcon(struct ksmbd_work *work) - { -- struct smb2_hdr *req_hdr = smb2_get_msg(work->request_buf); -+ struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); - unsigned int cmd = le16_to_cpu(req_hdr->Command); -- int tree_id; -+ unsigned int tree_id; - - if (cmd == SMB2_TREE_CONNECT_HE || - cmd == SMB2_CANCEL_HE || -@@ -113,7 +113,7 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work) - pr_err("The first operation in the compound does not have tcon\n"); - return -EINVAL; - } -- if (work->tcon->id != tree_id) { -+ if (tree_id != UINT_MAX && work->tcon->id != tree_id) { - pr_err("tree id(%u) is different with id(%u) in first operation\n", - tree_id, work->tcon->id); - return -EINVAL; -@@ -565,9 +565,9 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work) - */ - int smb2_check_user_session(struct ksmbd_work *work) - { -- struct smb2_hdr *req_hdr = smb2_get_msg(work->request_buf); -+ struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); - struct ksmbd_conn *conn = work->conn; -- unsigned int cmd = conn->ops->get_cmd_val(work); -+ unsigned int cmd = le16_to_cpu(req_hdr->Command); - unsigned long long sess_id; - - /* -@@ -593,7 +593,7 @@ int smb2_check_user_session(struct ksmbd_work *work) - pr_err("The first operation in the compound does not have sess\n"); - return -EINVAL; - } -- if (work->sess->id != sess_id) { -+ if (sess_id != ULLONG_MAX && work->sess->id != sess_id) { - pr_err("session id(%llu) is different with the first operation(%lld)\n", - sess_id, work->sess->id); - return -EINVAL; -@@ -6314,6 +6314,11 @@ int smb2_read(struct ksmbd_work *work) - unsigned int max_read_size = conn->vals->max_read_size; - - WORK_BUFFERS(work, req, rsp); -+ if (work->next_smb2_rcv_hdr_off) { -+ work->send_no_response = 1; -+ err = -EOPNOTSUPP; -+ goto out; -+ } - - if (test_share_config_flag(work->tcon->share_conf, - KSMBD_SHARE_FLAG_PIPE)) { -@@ -8713,7 +8718,8 @@ int smb3_decrypt_req(struct ksmbd_work *work) - struct smb2_transform_hdr *tr_hdr = smb2_get_msg(buf); - int rc = 0; - -- if (buf_data_size < sizeof(struct smb2_hdr)) { -+ if (pdu_length < sizeof(struct smb2_transform_hdr) || -+ buf_data_size < sizeof(struct smb2_hdr)) { - pr_err("Transform message is too small (%u)\n", - pdu_length); - return -ECONNABORTED; -diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c -index d937e2f45c829..a4421d9458d90 100644 ---- a/fs/smb/server/smb_common.c -+++ b/fs/smb/server/smb_common.c -@@ -388,26 +388,29 @@ static struct smb_version_cmds smb1_server_cmds[1] = { - [SMB_COM_NEGOTIATE_EX] = { .proc = smb1_negotiate, }, - }; - --static void init_smb1_server(struct ksmbd_conn *conn) -+static int init_smb1_server(struct ksmbd_conn *conn) - { - conn->ops = &smb1_server_ops; - conn->cmds = smb1_server_cmds; - conn->max_cmds = ARRAY_SIZE(smb1_server_cmds); -+ return 0; - } - --void ksmbd_init_smb_server(struct ksmbd_work *work) -+int ksmbd_init_smb_server(struct ksmbd_work *work) - { - struct ksmbd_conn *conn = work->conn; - __le32 proto; - -- if (conn->need_neg == false) -- return; -- - proto = *(__le32 *)((struct smb_hdr *)work->request_buf)->Protocol; -+ if (conn->need_neg == false) { -+ if (proto == SMB1_PROTO_NUMBER) -+ return -EINVAL; -+ return 0; -+ } -+ - if (proto == SMB1_PROTO_NUMBER) -- init_smb1_server(conn); -- else -- init_smb3_11_server(conn); -+ return init_smb1_server(conn); -+ return init_smb3_11_server(conn); - } - - int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, -diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h -index e63d2a4f466b5..1cbb492cdefec 100644 ---- a/fs/smb/server/smb_common.h -+++ b/fs/smb/server/smb_common.h -@@ -427,7 +427,7 @@ bool ksmbd_smb_request(struct ksmbd_conn *conn); - - int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count); - --void ksmbd_init_smb_server(struct ksmbd_work *work); -+int ksmbd_init_smb_server(struct ksmbd_work *work); - - struct ksmbd_kstat; - int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, -diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c -index 8e597db4d9710..f416b7fe092fc 100644 ---- a/fs/udf/balloc.c -+++ b/fs/udf/balloc.c -@@ -36,18 +36,41 @@ static int read_block_bitmap(struct super_block *sb, - unsigned long bitmap_nr) - { - struct buffer_head *bh = NULL; -- int retval = 0; -+ int i; -+ int max_bits, off, count; - struct kernel_lb_addr loc; - - loc.logicalBlockNum = bitmap->s_extPosition; - loc.partitionReferenceNum = UDF_SB(sb)->s_partition; - - bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block)); -+ bitmap->s_block_bitmap[bitmap_nr] = bh; - if (!bh) -- retval = -EIO; -+ return -EIO; - -- bitmap->s_block_bitmap[bitmap_nr] = bh; -- return retval; -+ /* Check consistency of Space Bitmap buffer. */ -+ max_bits = sb->s_blocksize * 8; -+ if (!bitmap_nr) { -+ off = sizeof(struct spaceBitmapDesc) << 3; -+ count = min(max_bits - off, bitmap->s_nr_groups); -+ } else { -+ /* -+ * Rough check if bitmap number is too big to have any bitmap -+ * blocks reserved. -+ */ -+ if (bitmap_nr > -+ (bitmap->s_nr_groups >> (sb->s_blocksize_bits + 3)) + 2) -+ return 0; -+ off = 0; -+ count = bitmap->s_nr_groups - bitmap_nr * max_bits + -+ (sizeof(struct spaceBitmapDesc) << 3); -+ count = min(count, max_bits); -+ } -+ -+ for (i = 0; i < count; i++) -+ if (udf_test_bit(i + off, bh->b_data)) -+ return -EFSCORRUPTED; -+ return 0; - } - - static int __load_block_bitmap(struct super_block *sb, -diff --git a/fs/udf/inode.c b/fs/udf/inode.c -index a4e875b61f895..b574c2a9ce7ba 100644 ---- a/fs/udf/inode.c -+++ b/fs/udf/inode.c -@@ -57,15 +57,15 @@ static int udf_update_inode(struct inode *, int); - static int udf_sync_inode(struct inode *inode); - static int udf_alloc_i_data(struct inode *inode, size_t size); - static sector_t inode_getblk(struct inode *, sector_t, int *, int *); --static int8_t udf_insert_aext(struct inode *, struct extent_position, -- struct kernel_lb_addr, uint32_t); -+static int udf_insert_aext(struct inode *, struct extent_position, -+ struct kernel_lb_addr, uint32_t); - static void udf_split_extents(struct inode *, int *, int, udf_pblk_t, - struct kernel_long_ad *, int *); - static void udf_prealloc_extents(struct inode *, int, int, - struct kernel_long_ad *, int *); - static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *); --static void udf_update_extents(struct inode *, struct kernel_long_ad *, int, -- int, struct extent_position *); -+static int udf_update_extents(struct inode *, struct kernel_long_ad *, int, -+ int, struct extent_position *); - static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); - - static void __udf_clear_extent_cache(struct inode *inode) -@@ -696,7 +696,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, - struct kernel_lb_addr eloc, tmpeloc; - int c = 1; - loff_t lbcount = 0, b_off = 0; -- udf_pblk_t newblocknum, newblock; -+ udf_pblk_t newblocknum, newblock = 0; - sector_t offset = 0; - int8_t etype; - struct udf_inode_info *iinfo = UDF_I(inode); -@@ -799,7 +799,6 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, - ret = udf_do_extend_file(inode, &prev_epos, laarr, hole_len); - if (ret < 0) { - *err = ret; -- newblock = 0; - goto out_free; - } - c = 0; -@@ -862,7 +861,6 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, - goal, err); - if (!newblocknum) { - *err = -ENOSPC; -- newblock = 0; - goto out_free; - } - if (isBeyondEOF) -@@ -888,7 +886,9 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, - /* write back the new extents, inserting new extents if the new number - * of extents is greater than the old number, and deleting extents if - * the new number of extents is less than the old number */ -- udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); -+ *err = udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); -+ if (*err < 0) -+ goto out_free; - - newblock = udf_get_pblock(inode->i_sb, newblocknum, - iinfo->i_location.partitionReferenceNum, 0); -@@ -1156,21 +1156,30 @@ static void udf_merge_extents(struct inode *inode, struct kernel_long_ad *laarr, - } - } - --static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, -- int startnum, int endnum, -- struct extent_position *epos) -+static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, -+ int startnum, int endnum, -+ struct extent_position *epos) - { - int start = 0, i; - struct kernel_lb_addr tmploc; - uint32_t tmplen; -+ int err; - - if (startnum > endnum) { - for (i = 0; i < (startnum - endnum); i++) - udf_delete_aext(inode, *epos); - } else if (startnum < endnum) { - for (i = 0; i < (endnum - startnum); i++) { -- udf_insert_aext(inode, *epos, laarr[i].extLocation, -- laarr[i].extLength); -+ err = udf_insert_aext(inode, *epos, -+ laarr[i].extLocation, -+ laarr[i].extLength); -+ /* -+ * If we fail here, we are likely corrupting the extent -+ * list and leaking blocks. At least stop early to -+ * limit the damage. -+ */ -+ if (err < 0) -+ return err; - udf_next_aext(inode, epos, &laarr[i].extLocation, - &laarr[i].extLength, 1); - start++; -@@ -1182,6 +1191,7 @@ static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr - udf_write_aext(inode, epos, &laarr[i].extLocation, - laarr[i].extLength, 1); - } -+ return 0; - } - - struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block, -@@ -2210,12 +2220,13 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos, - return etype; - } - --static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, -- struct kernel_lb_addr neloc, uint32_t nelen) -+static int udf_insert_aext(struct inode *inode, struct extent_position epos, -+ struct kernel_lb_addr neloc, uint32_t nelen) - { - struct kernel_lb_addr oeloc; - uint32_t oelen; - int8_t etype; -+ int err; - - if (epos.bh) - get_bh(epos.bh); -@@ -2225,10 +2236,10 @@ static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, - neloc = oeloc; - nelen = (etype << 30) | oelen; - } -- udf_add_aext(inode, &epos, &neloc, nelen, 1); -+ err = udf_add_aext(inode, &epos, &neloc, nelen, 1); - brelse(epos.bh); - -- return (nelen >> 30); -+ return err; - } - - int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) -diff --git a/fs/verity/signature.c b/fs/verity/signature.c -index 143a530a80088..b59de03055e1e 100644 ---- a/fs/verity/signature.c -+++ b/fs/verity/signature.c -@@ -54,6 +54,22 @@ int fsverity_verify_signature(const struct fsverity_info *vi, - return 0; - } - -+ if (fsverity_keyring->keys.nr_leaves_on_tree == 0) { -+ /* -+ * The ".fs-verity" keyring is empty, due to builtin signatures -+ * being supported by the kernel but not actually being used. -+ * In this case, verify_pkcs7_signature() would always return an -+ * error, usually ENOKEY. It could also be EBADMSG if the -+ * PKCS#7 is malformed, but that isn't very important to -+ * distinguish. So, just skip to ENOKEY to avoid the attack -+ * surface of the PKCS#7 parser, which would otherwise be -+ * reachable by any task able to execute FS_IOC_ENABLE_VERITY. -+ */ -+ fsverity_err(inode, -+ "fs-verity keyring is empty, rejecting signed file!"); -+ return -ENOKEY; -+ } -+ - d = kzalloc(sizeof(*d) + hash_alg->digest_size, GFP_KERNEL); - if (!d) - return -ENOMEM; -diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h -index 224b860647083..939a3196bf002 100644 ---- a/include/crypto/algapi.h -+++ b/include/crypto/algapi.h -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #include - -@@ -60,6 +61,8 @@ struct crypto_instance { - struct crypto_spawn *spawns; - }; - -+ struct work_struct free_work; -+ - void *__ctx[] CRYPTO_MINALIGN_ATTR; - }; - -diff --git a/include/dt-bindings/clock/qcom,gcc-sc8280xp.h b/include/dt-bindings/clock/qcom,gcc-sc8280xp.h -index cb2fb638825ca..8454915917849 100644 ---- a/include/dt-bindings/clock/qcom,gcc-sc8280xp.h -+++ b/include/dt-bindings/clock/qcom,gcc-sc8280xp.h -@@ -492,5 +492,17 @@ - #define USB30_MP_GDSC 9 - #define USB30_PRIM_GDSC 10 - #define USB30_SEC_GDSC 11 -+#define EMAC_0_GDSC 12 -+#define EMAC_1_GDSC 13 -+#define USB4_1_GDSC 14 -+#define USB4_GDSC 15 -+#define HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC 16 -+#define HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC 17 -+#define HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC 18 -+#define HLOS1_VOTE_MMNOC_MMU_TBU_SF1_GDSC 19 -+#define HLOS1_VOTE_TURING_MMU_TBU0_GDSC 20 -+#define HLOS1_VOTE_TURING_MMU_TBU1_GDSC 21 -+#define HLOS1_VOTE_TURING_MMU_TBU2_GDSC 22 -+#define HLOS1_VOTE_TURING_MMU_TBU3_GDSC 23 - - #endif -diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h -index 14dc461b0e829..255701e1251b4 100644 ---- a/include/linux/arm_sdei.h -+++ b/include/linux/arm_sdei.h -@@ -47,10 +47,12 @@ int sdei_unregister_ghes(struct ghes *ghes); - int sdei_mask_local_cpu(void); - int sdei_unmask_local_cpu(void); - void __init sdei_init(void); -+void sdei_handler_abort(void); - #else - static inline int sdei_mask_local_cpu(void) { return 0; } - static inline int sdei_unmask_local_cpu(void) { return 0; } - static inline void sdei_init(void) { } -+static inline void sdei_handler_abort(void) { } - #endif /* CONFIG_ARM_SDE_INTERFACE */ - - -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index 427e79ac72194..57674b3c58774 100644 ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -565,6 +565,7 @@ struct request_queue { - #define QUEUE_FLAG_NOXMERGES 9 /* No extended merges */ - #define QUEUE_FLAG_ADD_RANDOM 10 /* Contributes to random pool */ - #define QUEUE_FLAG_SAME_FORCE 12 /* force complete on same CPU */ -+#define QUEUE_FLAG_HW_WC 18 /* Write back caching supported */ - #define QUEUE_FLAG_INIT_DONE 14 /* queue is initialized */ - #define QUEUE_FLAG_STABLE_WRITES 15 /* don't modify blks until WB is done */ - #define QUEUE_FLAG_POLL 16 /* IO polling enabled if set */ -diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h -index 267cd06b54a01..aefb06373720f 100644 ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -1361,7 +1361,13 @@ struct clk_hw_onecell_data { - struct clk_hw *hws[]; - }; - --#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn) -+#define CLK_OF_DECLARE(name, compat, fn) \ -+ static void __init __##name##_of_clk_init_declare(struct device_node *np) \ -+ { \ -+ fn(np); \ -+ fwnode_dev_initialized(of_fwnode_handle(np), true); \ -+ } \ -+ OF_DECLARE_1(clk, name, compat, __##name##_of_clk_init_declare) - - /* - * Use this macro when you have a driver that requires two initialization -diff --git a/include/linux/hid.h b/include/linux/hid.h -index 0a1ccc68e798a..784dd6b6046eb 100644 ---- a/include/linux/hid.h -+++ b/include/linux/hid.h -@@ -357,6 +357,7 @@ struct hid_item { - #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18) - #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19) - #define HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE BIT(20) -+#define HID_QUIRK_NOINVERT BIT(21) - #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28) - #define HID_QUIRK_NO_INIT_REPORTS BIT(29) - #define HID_QUIRK_NO_IGNORE BIT(30) -diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h -index 1ed52441972f9..10a1e81434cb9 100644 ---- a/include/linux/if_arp.h -+++ b/include/linux/if_arp.h -@@ -53,6 +53,10 @@ static inline bool dev_is_mac_header_xmit(const struct net_device *dev) - case ARPHRD_NONE: - case ARPHRD_RAWIP: - case ARPHRD_PIMREG: -+ /* PPP adds its l2 header automatically in ppp_start_xmit(). -+ * This makes it look like an l3 device to __bpf_redirect() and tcf_mirred_init(). -+ */ -+ case ARPHRD_PPP: - return false; - default: - return true; -diff --git a/include/linux/ioport.h b/include/linux/ioport.h -index 27642ca15d932..4ae3c541ea6f4 100644 ---- a/include/linux/ioport.h -+++ b/include/linux/ioport.h -@@ -318,6 +318,8 @@ extern void __devm_release_region(struct device *dev, struct resource *parent, - resource_size_t start, resource_size_t n); - extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size); - extern bool iomem_is_exclusive(u64 addr); -+extern bool resource_is_exclusive(struct resource *resource, u64 addr, -+ resource_size_t size); - - extern int - walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, -diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h -index 73f5c120def88..2a36f3218b510 100644 ---- a/include/linux/kernfs.h -+++ b/include/linux/kernfs.h -@@ -550,6 +550,10 @@ static inline int kernfs_setattr(struct kernfs_node *kn, - const struct iattr *iattr) - { return -ENOSYS; } - -+static inline __poll_t kernfs_generic_poll(struct kernfs_open_file *of, -+ struct poll_table_struct *pt) -+{ return -ENOSYS; } -+ - static inline void kernfs_notify(struct kernfs_node *kn) { } - - static inline int kernfs_xattr_get(struct kernfs_node *kn, const char *name, -diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h -index ec119da1d89b4..4a97a6db9bcec 100644 ---- a/include/linux/lsm_hook_defs.h -+++ b/include/linux/lsm_hook_defs.h -@@ -54,6 +54,7 @@ LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, struct file *f - LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm) - LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, struct linux_binprm *bprm) - LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, struct linux_binprm *bprm) -+LSM_HOOK(int, 0, fs_context_submount, struct fs_context *fc, struct super_block *reference) - LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc, - struct fs_context *src_sc) - LSM_HOOK(int, -ENOPARAM, fs_context_parse_param, struct fs_context *fc, -diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h -index e039763029563..099521835cd14 100644 ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -283,6 +283,11 @@ struct mem_cgroup { - atomic_long_t memory_events[MEMCG_NR_MEMORY_EVENTS]; - atomic_long_t memory_events_local[MEMCG_NR_MEMORY_EVENTS]; - -+ /* -+ * Hint of reclaim pressure for socket memroy management. Note -+ * that this indicator should NOT be used in legacy cgroup mode -+ * where socket memory is accounted/charged separately. -+ */ - unsigned long socket_pressure; - - /* Legacy tcp memory accounting */ -@@ -1704,8 +1709,8 @@ void mem_cgroup_sk_alloc(struct sock *sk); - void mem_cgroup_sk_free(struct sock *sk); - static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) - { -- if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && memcg->tcpmem_pressure) -- return true; -+ if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) -+ return !!memcg->tcpmem_pressure; - do { - if (time_before(jiffies, READ_ONCE(memcg->socket_pressure))) - return true; -diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h -index e86cf6642d212..2fd973d188c47 100644 ---- a/include/linux/nfs_xdr.h -+++ b/include/linux/nfs_xdr.h -@@ -670,6 +670,7 @@ struct nfs_pgio_res { - struct { - unsigned int replen; /* used by read */ - int eof; /* used by read */ -+ void * scratch; /* used by read */ - }; - struct { - struct nfs_writeverf * verf; /* used by write */ -diff --git a/include/linux/nls.h b/include/linux/nls.h -index 499e486b3722d..e0bf8367b274a 100644 ---- a/include/linux/nls.h -+++ b/include/linux/nls.h -@@ -47,7 +47,7 @@ enum utf16_endian { - /* nls_base.c */ - extern int __register_nls(struct nls_table *, struct module *); - extern int unregister_nls(struct nls_table *); --extern struct nls_table *load_nls(char *); -+extern struct nls_table *load_nls(const char *charset); - extern void unload_nls(struct nls_table *); - extern struct nls_table *load_nls_default(void); - #define register_nls(nls) __register_nls((nls), THIS_MODULE) -diff --git a/include/linux/pci.h b/include/linux/pci.h -index 9f617ffdb863f..eccaf1abea79d 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -409,6 +409,7 @@ struct pci_dev { - */ - unsigned int irq; - struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ -+ struct resource driver_exclusive_resource; /* driver exclusive resource ranges */ - - bool match_driver; /* Skip attaching driver */ - -@@ -465,6 +466,7 @@ struct pci_dev { - pci_dev_flags_t dev_flags; - atomic_t enable_cnt; /* pci_enable_device has been called */ - -+ spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */ - u32 saved_config_space[16]; /* Config space saved at suspend time */ - struct hlist_head saved_cap_space; - int rom_attr_enabled; /* Display of ROM attribute enabled? */ -@@ -1208,11 +1210,40 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val); - int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val); - int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val); - int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val); --int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, -- u16 clear, u16 set); -+int pcie_capability_clear_and_set_word_unlocked(struct pci_dev *dev, int pos, -+ u16 clear, u16 set); -+int pcie_capability_clear_and_set_word_locked(struct pci_dev *dev, int pos, -+ u16 clear, u16 set); - int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, - u32 clear, u32 set); - -+/** -+ * pcie_capability_clear_and_set_word - RMW accessor for PCI Express Capability Registers -+ * @dev: PCI device structure of the PCI Express device -+ * @pos: PCI Express Capability Register -+ * @clear: Clear bitmask -+ * @set: Set bitmask -+ * -+ * Perform a Read-Modify-Write (RMW) operation using @clear and @set -+ * bitmasks on PCI Express Capability Register at @pos. Certain PCI Express -+ * Capability Registers are accessed concurrently in RMW fashion, hence -+ * require locking which is handled transparently to the caller. -+ */ -+static inline int pcie_capability_clear_and_set_word(struct pci_dev *dev, -+ int pos, -+ u16 clear, u16 set) -+{ -+ switch (pos) { -+ case PCI_EXP_LNKCTL: -+ case PCI_EXP_RTCTL: -+ return pcie_capability_clear_and_set_word_locked(dev, pos, -+ clear, set); -+ default: -+ return pcie_capability_clear_and_set_word_unlocked(dev, pos, -+ clear, set); -+ } -+} -+ - static inline int pcie_capability_set_word(struct pci_dev *dev, int pos, - u16 set) - { -@@ -1408,6 +1439,21 @@ int pci_request_selected_regions(struct pci_dev *, int, const char *); - int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *); - void pci_release_selected_regions(struct pci_dev *, int); - -+static inline __must_check struct resource * -+pci_request_config_region_exclusive(struct pci_dev *pdev, unsigned int offset, -+ unsigned int len, const char *name) -+{ -+ return __request_region(&pdev->driver_exclusive_resource, offset, len, -+ name, IORESOURCE_EXCLUSIVE); -+} -+ -+static inline void pci_release_config_region(struct pci_dev *pdev, -+ unsigned int offset, -+ unsigned int len) -+{ -+ __release_region(&pdev->driver_exclusive_resource, offset, len); -+} -+ - /* drivers/pci/bus.c */ - void pci_add_resource(struct list_head *resources, struct resource *res); - void pci_add_resource_offset(struct list_head *resources, struct resource *res, -@@ -2487,6 +2533,7 @@ void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type); - #define pci_crit(pdev, fmt, arg...) dev_crit(&(pdev)->dev, fmt, ##arg) - #define pci_err(pdev, fmt, arg...) dev_err(&(pdev)->dev, fmt, ##arg) - #define pci_warn(pdev, fmt, arg...) dev_warn(&(pdev)->dev, fmt, ##arg) -+#define pci_warn_once(pdev, fmt, arg...) dev_warn_once(&(pdev)->dev, fmt, ##arg) - #define pci_notice(pdev, fmt, arg...) dev_notice(&(pdev)->dev, fmt, ##arg) - #define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg) - #define pci_dbg(pdev, fmt, arg...) dev_dbg(&(pdev)->dev, fmt, ##arg) -diff --git a/include/linux/security.h b/include/linux/security.h -index ca1b7109c0dbb..a6c97cc57caa0 100644 ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -293,6 +293,7 @@ int security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file); - int security_bprm_check(struct linux_binprm *bprm); - void security_bprm_committing_creds(struct linux_binprm *bprm); - void security_bprm_committed_creds(struct linux_binprm *bprm); -+int security_fs_context_submount(struct fs_context *fc, struct super_block *reference); - int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc); - int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param); - int security_sb_alloc(struct super_block *sb); -@@ -625,6 +626,11 @@ static inline void security_bprm_committed_creds(struct linux_binprm *bprm) - { - } - -+static inline int security_fs_context_submount(struct fs_context *fc, -+ struct super_block *reference) -+{ -+ return 0; -+} - static inline int security_fs_context_dup(struct fs_context *fc, - struct fs_context *src_fc) - { -diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h -index 04c59f8d801f1..422f4ca656cf9 100644 ---- a/include/linux/trace_events.h -+++ b/include/linux/trace_events.h -@@ -863,7 +863,8 @@ extern int perf_uprobe_init(struct perf_event *event, - extern void perf_uprobe_destroy(struct perf_event *event); - extern int bpf_get_uprobe_info(const struct perf_event *event, - u32 *fd_type, const char **filename, -- u64 *probe_offset, bool perf_type_tracepoint); -+ u64 *probe_offset, u64 *probe_addr, -+ bool perf_type_tracepoint); - #endif - extern int ftrace_profile_set_filter(struct perf_event *event, int event_id, - char *filter_str); -diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h -index 350d49012659b..28aeef8f9e7b5 100644 ---- a/include/linux/usb/typec_altmode.h -+++ b/include/linux/usb/typec_altmode.h -@@ -67,7 +67,7 @@ struct typec_altmode_ops { - - int typec_altmode_enter(struct typec_altmode *altmode, u32 *vdo); - int typec_altmode_exit(struct typec_altmode *altmode); --void typec_altmode_attention(struct typec_altmode *altmode, u32 vdo); -+int typec_altmode_attention(struct typec_altmode *altmode, u32 vdo); - int typec_altmode_vdm(struct typec_altmode *altmode, - const u32 header, const u32 *vdo, int count); - int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf, -diff --git a/include/media/cec.h b/include/media/cec.h -index abee41ae02d0e..9c007f83569aa 100644 ---- a/include/media/cec.h -+++ b/include/media/cec.h -@@ -113,22 +113,25 @@ struct cec_fh { - #define CEC_FREE_TIME_TO_USEC(ft) ((ft) * 2400) - - struct cec_adap_ops { -- /* Low-level callbacks */ -+ /* Low-level callbacks, called with adap->lock held */ - int (*adap_enable)(struct cec_adapter *adap, bool enable); - int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); - int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable); - int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); -- void (*adap_configured)(struct cec_adapter *adap, bool configured); -+ void (*adap_unconfigured)(struct cec_adapter *adap); - int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, - u32 signal_free_time, struct cec_msg *msg); -+ void (*adap_nb_transmit_canceled)(struct cec_adapter *adap, -+ const struct cec_msg *msg); - void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); - void (*adap_free)(struct cec_adapter *adap); - -- /* Error injection callbacks */ -+ /* Error injection callbacks, called without adap->lock held */ - int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf); - bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line); - -- /* High-level CEC message callback */ -+ /* High-level CEC message callback, called without adap->lock held */ -+ void (*configured)(struct cec_adapter *adap); - int (*received)(struct cec_adapter *adap, struct cec_msg *msg); - }; - -diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h -index 6f15e6fa154e6..53bd2d02a4f0d 100644 ---- a/include/net/lwtunnel.h -+++ b/include/net/lwtunnel.h -@@ -16,9 +16,12 @@ - #define LWTUNNEL_STATE_INPUT_REDIRECT BIT(1) - #define LWTUNNEL_STATE_XMIT_REDIRECT BIT(2) - -+/* LWTUNNEL_XMIT_CONTINUE should be distinguishable from dst_output return -+ * values (NET_XMIT_xxx and NETDEV_TX_xxx in linux/netdevice.h) for safety. -+ */ - enum { - LWTUNNEL_XMIT_DONE, -- LWTUNNEL_XMIT_CONTINUE, -+ LWTUNNEL_XMIT_CONTINUE = 0x100, - }; - - -diff --git a/include/net/mac80211.h b/include/net/mac80211.h -index 8a338c33118f9..43173204d6d5e 100644 ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -1141,9 +1141,11 @@ struct ieee80211_tx_info { - u8 ampdu_ack_len; - u8 ampdu_len; - u8 antenna; -+ u8 pad; - u16 tx_time; - u8 flags; -- void *status_driver_data[18 / sizeof(void *)]; -+ u8 pad2; -+ void *status_driver_data[16 / sizeof(void *)]; - } status; - struct { - struct ieee80211_tx_rate driver_rates[ -diff --git a/include/net/tcp.h b/include/net/tcp.h -index e9c8f88f47696..5fd69f2342a44 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -355,7 +355,6 @@ ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, - struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp, - bool force_schedule); - --void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks); - static inline void tcp_dec_quickack_mode(struct sock *sk, - const unsigned int pkts) - { -diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h -index fcf25f1642a3a..d27d9fb7174c8 100644 ---- a/include/scsi/scsi_host.h -+++ b/include/scsi/scsi_host.h -@@ -757,7 +757,7 @@ extern void scsi_remove_host(struct Scsi_Host *); - extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); - extern int scsi_host_busy(struct Scsi_Host *shost); - extern void scsi_host_put(struct Scsi_Host *t); --extern struct Scsi_Host *scsi_host_lookup(unsigned short); -+extern struct Scsi_Host *scsi_host_lookup(unsigned int hostnum); - extern const char *scsi_host_state_name(enum scsi_host_state); - extern void scsi_host_complete_all_commands(struct Scsi_Host *shost, - enum scsi_host_status status); -diff --git a/include/uapi/linux/sync_file.h b/include/uapi/linux/sync_file.h -index ee2dcfb3d6602..d7f7c04a6e0c1 100644 ---- a/include/uapi/linux/sync_file.h -+++ b/include/uapi/linux/sync_file.h -@@ -52,7 +52,7 @@ struct sync_fence_info { - * @name: name of fence - * @status: status of fence. 1: signaled 0:active <0:error - * @flags: sync_file_info flags -- * @num_fences number of fences in the sync_file -+ * @num_fences: number of fences in the sync_file - * @pad: padding for 64-bit alignment, should always be zero - * @sync_fence_info: pointer to array of structs sync_fence_info with all - * fences in the sync_file -diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h -index b5e7d082b8adf..d4a4e3cab3c2a 100644 ---- a/include/uapi/linux/v4l2-controls.h -+++ b/include/uapi/linux/v4l2-controls.h -@@ -2411,6 +2411,9 @@ struct v4l2_ctrl_hevc_slice_params { - * @poc_st_curr_after: provides the index of the short term after references - * in DPB array - * @poc_lt_curr: provides the index of the long term references in DPB array -+ * @num_delta_pocs_of_ref_rps_idx: same as the derived value NumDeltaPocs[RefRpsIdx], -+ * can be used to parse the RPS data in slice headers -+ * instead of skipping it with @short_term_ref_pic_set_size. - * @reserved: padding field. Should be zeroed by applications. - * @dpb: the decoded picture buffer, for meta-data about reference frames - * @flags: see V4L2_HEVC_DECODE_PARAM_FLAG_{} -@@ -2426,7 +2429,8 @@ struct v4l2_ctrl_hevc_decode_params { - __u8 poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; -- __u8 reserved[4]; -+ __u8 num_delta_pocs_of_ref_rps_idx; -+ __u8 reserved[3]; - struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u64 flags; - }; -diff --git a/init/Kconfig b/init/Kconfig -index 2028ed4d50f5b..de255842f5d09 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -627,6 +627,7 @@ config TASK_IO_ACCOUNTING - - config PSI - bool "Pressure stall information tracking" -+ select KERNFS - help - Collect metrics that indicate how overcommitted the CPU, memory, - and IO capacity are in the system. -diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c -index b0e47fe1eb4bb..6d455e2428b90 100644 ---- a/io_uring/io_uring.c -+++ b/io_uring/io_uring.c -@@ -1457,6 +1457,9 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, long min) - break; - nr_events += ret; - ret = 0; -+ -+ if (task_sigpending(current)) -+ return -EINTR; - } while (nr_events < min && !need_resched()); - - return ret; -@@ -2240,7 +2243,9 @@ static const struct io_uring_sqe *io_get_sqe(struct io_ring_ctx *ctx) - } - - /* drop invalid entries */ -+ spin_lock(&ctx->completion_lock); - ctx->cq_extra--; -+ spin_unlock(&ctx->completion_lock); - WRITE_ONCE(ctx->rings->sq_dropped, - READ_ONCE(ctx->rings->sq_dropped) + 1); - return NULL; -diff --git a/kernel/auditsc.c b/kernel/auditsc.c -index 9f8c05228d6d6..a2240f54fc224 100644 ---- a/kernel/auditsc.c -+++ b/kernel/auditsc.c -@@ -2456,6 +2456,8 @@ void __audit_inode_child(struct inode *parent, - } - } - -+ cond_resched(); -+ - /* is there a matching child entry? */ - list_for_each_entry(n, &context->names_list, list) { - /* can only match entries that have a name */ -diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c -index fb78bb26786fc..7582ec4fd4131 100644 ---- a/kernel/bpf/btf.c -+++ b/kernel/bpf/btf.c -@@ -5788,7 +5788,7 @@ error: - * that also allows using an array of int as a scratch - * space. e.g. skb->cb[]. - */ -- if (off + size > mtrue_end) { -+ if (off + size > mtrue_end && !(*flag & PTR_UNTRUSTED)) { - bpf_log(log, - "access beyond the end of member %s (mend:%u) in struct %s with off %u size %u\n", - mname, mtrue_end, tname, off, size); -diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c -index 3c414e0ac819e..3052680201e57 100644 ---- a/kernel/bpf/verifier.c -+++ b/kernel/bpf/verifier.c -@@ -10401,6 +10401,12 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, - return -EINVAL; - } - -+ /* check src2 operand */ -+ err = check_reg_arg(env, insn->dst_reg, SRC_OP); -+ if (err) -+ return err; -+ -+ dst_reg = ®s[insn->dst_reg]; - if (BPF_SRC(insn->code) == BPF_X) { - if (insn->imm != 0) { - verbose(env, "BPF_JMP/JMP32 uses reserved fields\n"); -@@ -10412,12 +10418,13 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, - if (err) - return err; - -- if (is_pointer_value(env, insn->src_reg)) { -+ src_reg = ®s[insn->src_reg]; -+ if (!(reg_is_pkt_pointer_any(dst_reg) && reg_is_pkt_pointer_any(src_reg)) && -+ is_pointer_value(env, insn->src_reg)) { - verbose(env, "R%d pointer comparison prohibited\n", - insn->src_reg); - return -EACCES; - } -- src_reg = ®s[insn->src_reg]; - } else { - if (insn->src_reg != BPF_REG_0) { - verbose(env, "BPF_JMP/JMP32 uses reserved fields\n"); -@@ -10425,12 +10432,6 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, - } - } - -- /* check src2 operand */ -- err = check_reg_arg(env, insn->dst_reg, SRC_OP); -- if (err) -- return err; -- -- dst_reg = ®s[insn->dst_reg]; - is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32; - - if (BPF_SRC(insn->code) == BPF_K) { -diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c -index db3e05b6b4dd2..79e6a5d4c29a1 100644 ---- a/kernel/cgroup/cpuset.c -+++ b/kernel/cgroup/cpuset.c -@@ -1606,11 +1606,16 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp, - } - - /* -- * Skip the whole subtree if the cpumask remains the same -- * and has no partition root state and force flag not set. -+ * Skip the whole subtree if -+ * 1) the cpumask remains the same, -+ * 2) has no partition root state, -+ * 3) force flag not set, and -+ * 4) for v2 load balance state same as its parent. - */ - if (!cp->partition_root_state && !force && -- cpumask_equal(tmp->new_cpus, cp->effective_cpus)) { -+ cpumask_equal(tmp->new_cpus, cp->effective_cpus) && -+ (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) || -+ (is_sched_load_balance(parent) == is_sched_load_balance(cp)))) { - pos_css = css_rightmost_descendant(pos_css); - continue; - } -@@ -1693,6 +1698,20 @@ update_parent_subparts: - - update_tasks_cpumask(cp, tmp->new_cpus); - -+ /* -+ * On default hierarchy, inherit the CS_SCHED_LOAD_BALANCE -+ * from parent if current cpuset isn't a valid partition root -+ * and their load balance states differ. -+ */ -+ if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && -+ !is_partition_valid(cp) && -+ (is_sched_load_balance(parent) != is_sched_load_balance(cp))) { -+ if (is_sched_load_balance(parent)) -+ set_bit(CS_SCHED_LOAD_BALANCE, &cp->flags); -+ else -+ clear_bit(CS_SCHED_LOAD_BALANCE, &cp->flags); -+ } -+ - /* - * On legacy hierarchy, if the effective cpumask of any non- - * empty cpuset is changed, we need to rebuild sched domains. -@@ -3213,6 +3232,14 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) - cs->use_parent_ecpus = true; - parent->child_ecpus_count++; - } -+ -+ /* -+ * For v2, clear CS_SCHED_LOAD_BALANCE if parent is isolated -+ */ -+ if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && -+ !is_sched_load_balance(parent)) -+ clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); -+ - spin_unlock_irq(&callback_lock); - - if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags)) -diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c -index 0d5c29879a50b..144a464e45c66 100644 ---- a/kernel/cgroup/namespace.c -+++ b/kernel/cgroup/namespace.c -@@ -149,9 +149,3 @@ const struct proc_ns_operations cgroupns_operations = { - .install = cgroupns_install, - .owner = cgroupns_owner, - }; -- --static __init int cgroup_namespaces_init(void) --{ -- return 0; --} --subsys_initcall(cgroup_namespaces_init); -diff --git a/kernel/cpu.c b/kernel/cpu.c -index 98a7a7b1471b7..f8eb1825f704f 100644 ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -1215,8 +1215,22 @@ out: - return ret; - } - -+struct cpu_down_work { -+ unsigned int cpu; -+ enum cpuhp_state target; -+}; -+ -+static long __cpu_down_maps_locked(void *arg) -+{ -+ struct cpu_down_work *work = arg; -+ -+ return _cpu_down(work->cpu, 0, work->target); -+} -+ - static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target) - { -+ struct cpu_down_work work = { .cpu = cpu, .target = target, }; -+ - /* - * If the platform does not support hotplug, report it explicitly to - * differentiate it from a transient offlining failure. -@@ -1225,7 +1239,15 @@ static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target) - return -EOPNOTSUPP; - if (cpu_hotplug_disabled) - return -EBUSY; -- return _cpu_down(cpu, 0, target); -+ -+ /* -+ * Ensure that the control task does not run on the to be offlined -+ * CPU to prevent a deadlock against cfs_b->period_timer. -+ */ -+ cpu = cpumask_any_but(cpu_online_mask, cpu); -+ if (cpu >= nr_cpu_ids) -+ return -EBUSY; -+ return work_on_cpu(cpu, __cpu_down_maps_locked, &work); - } - - static int cpu_down(unsigned int cpu, enum cpuhp_state target) -diff --git a/kernel/kprobes.c b/kernel/kprobes.c -index 00e177de91ccd..3da9726232ff9 100644 ---- a/kernel/kprobes.c -+++ b/kernel/kprobes.c -@@ -1545,6 +1545,17 @@ static int check_ftrace_location(struct kprobe *p) - return 0; - } - -+static bool is_cfi_preamble_symbol(unsigned long addr) -+{ -+ char symbuf[KSYM_NAME_LEN]; -+ -+ if (lookup_symbol_name(addr, symbuf)) -+ return false; -+ -+ return str_has_prefix("__cfi_", symbuf) || -+ str_has_prefix("__pfx_", symbuf); -+} -+ - static int check_kprobe_address_safe(struct kprobe *p, - struct module **probed_mod) - { -@@ -1563,7 +1574,8 @@ static int check_kprobe_address_safe(struct kprobe *p, - within_kprobe_blacklist((unsigned long) p->addr) || - jump_label_text_reserved(p->addr, p->addr) || - static_call_text_reserved(p->addr, p->addr) || -- find_bug((unsigned long)p->addr)) { -+ find_bug((unsigned long)p->addr) || -+ is_cfi_preamble_symbol((unsigned long)p->addr)) { - ret = -EINVAL; - goto out; - } -diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringbuffer.c -index 2b7b6ddab4f70..0bbcd1344f218 100644 ---- a/kernel/printk/printk_ringbuffer.c -+++ b/kernel/printk/printk_ringbuffer.c -@@ -1735,7 +1735,7 @@ static bool copy_data(struct prb_data_ring *data_ring, - if (!buf || !buf_size) - return true; - -- data_size = min_t(u16, buf_size, len); -+ data_size = min_t(unsigned int, buf_size, len); - - memcpy(&buf[0], data, data_size); /* LMM(copy_data:A) */ - return true; -diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c -index d49a9d66e0000..3a93c53f615f0 100644 ---- a/kernel/rcu/refscale.c -+++ b/kernel/rcu/refscale.c -@@ -867,12 +867,11 @@ ref_scale_init(void) - VERBOSE_SCALEOUT("Starting %d reader threads", nreaders); - - for (i = 0; i < nreaders; i++) { -+ init_waitqueue_head(&reader_tasks[i].wq); - firsterr = torture_create_kthread(ref_scale_reader, (void *)i, - reader_tasks[i].task); - if (torture_init_error(firsterr)) - goto unwind; -- -- init_waitqueue_head(&(reader_tasks[i].wq)); - } - - // Main Task -diff --git a/kernel/resource.c b/kernel/resource.c -index 1aeeededdd4c8..8f52f88009652 100644 ---- a/kernel/resource.c -+++ b/kernel/resource.c -@@ -1693,18 +1693,15 @@ static int strict_iomem_checks; - * - * Returns true if exclusive to the kernel, otherwise returns false. - */ --bool iomem_is_exclusive(u64 addr) -+bool resource_is_exclusive(struct resource *root, u64 addr, resource_size_t size) - { - const unsigned int exclusive_system_ram = IORESOURCE_SYSTEM_RAM | - IORESOURCE_EXCLUSIVE; - bool skip_children = false, err = false; -- int size = PAGE_SIZE; - struct resource *p; - -- addr = addr & PAGE_MASK; -- - read_lock(&resource_lock); -- for_each_resource(&iomem_resource, p, skip_children) { -+ for_each_resource(root, p, skip_children) { - if (p->start >= addr + size) - break; - if (p->end < addr) { -@@ -1743,6 +1740,12 @@ bool iomem_is_exclusive(u64 addr) - return err; - } - -+bool iomem_is_exclusive(u64 addr) -+{ -+ return resource_is_exclusive(&iomem_resource, addr & PAGE_MASK, -+ PAGE_SIZE); -+} -+ - struct resource_entry *resource_list_create_entry(struct resource *res, - size_t extra_size) - { -diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c -index 4f5796dd26a56..576eb2f51f043 100644 ---- a/kernel/sched/rt.c -+++ b/kernel/sched/rt.c -@@ -25,7 +25,7 @@ unsigned int sysctl_sched_rt_period = 1000000; - int sysctl_sched_rt_runtime = 950000; - - #ifdef CONFIG_SYSCTL --static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC / HZ) * RR_TIMESLICE; -+static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC * RR_TIMESLICE) / HZ; - static int sched_rt_handler(struct ctl_table *table, int write, void *buffer, - size_t *lenp, loff_t *ppos); - static int sched_rr_handler(struct ctl_table *table, int write, void *buffer, -diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c -index 1ad89eec2a55f..798e1841d2863 100644 ---- a/kernel/time/tick-sched.c -+++ b/kernel/time/tick-sched.c -@@ -1050,7 +1050,7 @@ static bool report_idle_softirq(void) - return false; - - /* On RT, softirqs handling may be waiting on some lock */ -- if (!local_bh_blocked()) -+ if (local_bh_blocked()) - return false; - - pr_warn("NOHZ tick-stop error: local softirq work is pending, handler #%02x!!!\n", -diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c -index ad04390883ada..9fc5db194027b 100644 ---- a/kernel/trace/bpf_trace.c -+++ b/kernel/trace/bpf_trace.c -@@ -2390,7 +2390,7 @@ int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, - #ifdef CONFIG_UPROBE_EVENTS - if (flags & TRACE_EVENT_FL_UPROBE) - err = bpf_get_uprobe_info(event, fd_type, buf, -- probe_offset, -+ probe_offset, probe_addr, - event->attr.type == PERF_TYPE_TRACEPOINT); - #endif - } -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 1a87cb70f1eb5..54ccdca395311 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -6616,10 +6616,36 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, - - #endif - -+static int open_pipe_on_cpu(struct trace_array *tr, int cpu) -+{ -+ if (cpu == RING_BUFFER_ALL_CPUS) { -+ if (cpumask_empty(tr->pipe_cpumask)) { -+ cpumask_setall(tr->pipe_cpumask); -+ return 0; -+ } -+ } else if (!cpumask_test_cpu(cpu, tr->pipe_cpumask)) { -+ cpumask_set_cpu(cpu, tr->pipe_cpumask); -+ return 0; -+ } -+ return -EBUSY; -+} -+ -+static void close_pipe_on_cpu(struct trace_array *tr, int cpu) -+{ -+ if (cpu == RING_BUFFER_ALL_CPUS) { -+ WARN_ON(!cpumask_full(tr->pipe_cpumask)); -+ cpumask_clear(tr->pipe_cpumask); -+ } else { -+ WARN_ON(!cpumask_test_cpu(cpu, tr->pipe_cpumask)); -+ cpumask_clear_cpu(cpu, tr->pipe_cpumask); -+ } -+} -+ - static int tracing_open_pipe(struct inode *inode, struct file *filp) - { - struct trace_array *tr = inode->i_private; - struct trace_iterator *iter; -+ int cpu; - int ret; - - ret = tracing_check_open_get_tr(tr); -@@ -6627,13 +6653,16 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) - return ret; - - mutex_lock(&trace_types_lock); -+ cpu = tracing_get_cpu(inode); -+ ret = open_pipe_on_cpu(tr, cpu); -+ if (ret) -+ goto fail_pipe_on_cpu; - - /* create a buffer to store the information to pass to userspace */ - iter = kzalloc(sizeof(*iter), GFP_KERNEL); - if (!iter) { - ret = -ENOMEM; -- __trace_array_put(tr); -- goto out; -+ goto fail_alloc_iter; - } - - trace_seq_init(&iter->seq); -@@ -6656,7 +6685,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) - - iter->tr = tr; - iter->array_buffer = &tr->array_buffer; -- iter->cpu_file = tracing_get_cpu(inode); -+ iter->cpu_file = cpu; - mutex_init(&iter->mutex); - filp->private_data = iter; - -@@ -6666,12 +6695,15 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) - nonseekable_open(inode, filp); - - tr->trace_ref++; --out: -+ - mutex_unlock(&trace_types_lock); - return ret; - - fail: - kfree(iter); -+fail_alloc_iter: -+ close_pipe_on_cpu(tr, cpu); -+fail_pipe_on_cpu: - __trace_array_put(tr); - mutex_unlock(&trace_types_lock); - return ret; -@@ -6688,7 +6720,7 @@ static int tracing_release_pipe(struct inode *inode, struct file *file) - - if (iter->trace->pipe_close) - iter->trace->pipe_close(iter); -- -+ close_pipe_on_cpu(tr, iter->cpu_file); - mutex_unlock(&trace_types_lock); - - free_cpumask_var(iter->started); -@@ -7484,6 +7516,11 @@ out: - return ret; - } - -+static void tracing_swap_cpu_buffer(void *tr) -+{ -+ update_max_tr_single((struct trace_array *)tr, current, smp_processor_id()); -+} -+ - static ssize_t - tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, - loff_t *ppos) -@@ -7542,13 +7579,15 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, - ret = tracing_alloc_snapshot_instance(tr); - if (ret < 0) - break; -- local_irq_disable(); - /* Now, we're going to swap */ -- if (iter->cpu_file == RING_BUFFER_ALL_CPUS) -+ if (iter->cpu_file == RING_BUFFER_ALL_CPUS) { -+ local_irq_disable(); - update_max_tr(tr, current, smp_processor_id(), NULL); -- else -- update_max_tr_single(tr, current, iter->cpu_file); -- local_irq_enable(); -+ local_irq_enable(); -+ } else { -+ smp_call_function_single(iter->cpu_file, tracing_swap_cpu_buffer, -+ (void *)tr, 1); -+ } - break; - default: - if (tr->allocated_snapshot) { -@@ -9356,6 +9395,9 @@ static struct trace_array *trace_array_create(const char *name) - if (!alloc_cpumask_var(&tr->tracing_cpumask, GFP_KERNEL)) - goto out_free_tr; - -+ if (!zalloc_cpumask_var(&tr->pipe_cpumask, GFP_KERNEL)) -+ goto out_free_tr; -+ - tr->trace_flags = global_trace.trace_flags & ~ZEROED_TRACE_FLAGS; - - cpumask_copy(tr->tracing_cpumask, cpu_all_mask); -@@ -9397,6 +9439,7 @@ static struct trace_array *trace_array_create(const char *name) - out_free_tr: - ftrace_free_ftrace_ops(tr); - free_trace_buffers(tr); -+ free_cpumask_var(tr->pipe_cpumask); - free_cpumask_var(tr->tracing_cpumask); - kfree(tr->name); - kfree(tr); -@@ -9499,6 +9542,7 @@ static int __remove_instance(struct trace_array *tr) - } - kfree(tr->topts); - -+ free_cpumask_var(tr->pipe_cpumask); - free_cpumask_var(tr->tracing_cpumask); - kfree(tr->name); - kfree(tr); -@@ -10223,12 +10267,14 @@ __init static int tracer_alloc_buffers(void) - if (trace_create_savedcmd() < 0) - goto out_free_temp_buffer; - -+ if (!zalloc_cpumask_var(&global_trace.pipe_cpumask, GFP_KERNEL)) -+ goto out_free_savedcmd; -+ - /* TODO: make the number of buffers hot pluggable with CPUS */ - if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) { - MEM_FAIL(1, "tracer: failed to allocate ring buffer!\n"); -- goto out_free_savedcmd; -+ goto out_free_pipe_cpumask; - } -- - if (global_trace.buffer_disabled) - tracing_off(); - -@@ -10281,6 +10327,8 @@ __init static int tracer_alloc_buffers(void) - - return 0; - -+out_free_pipe_cpumask: -+ free_cpumask_var(global_trace.pipe_cpumask); - out_free_savedcmd: - free_saved_cmdlines_buffer(savedcmd); - out_free_temp_buffer: -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 3d3505286aa7f..dbb86b0dd3b7b 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -366,6 +366,8 @@ struct trace_array { - struct list_head events; - struct trace_event_file *trace_marker_file; - cpumask_var_t tracing_cpumask; /* only trace on set CPUs */ -+ /* one per_cpu trace_pipe can be opened by only one user */ -+ cpumask_var_t pipe_cpumask; - int ref; - int trace_ref; - #ifdef CONFIG_FUNCTION_TRACER -diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c -index 2f37a6e68aa9f..b791524a6536a 100644 ---- a/kernel/trace/trace_hwlat.c -+++ b/kernel/trace/trace_hwlat.c -@@ -635,7 +635,7 @@ static int s_mode_show(struct seq_file *s, void *v) - else - seq_printf(s, "%s", thread_mode_str[mode]); - -- if (mode != MODE_MAX) -+ if (mode < MODE_MAX - 1) /* if mode is any but last */ - seq_puts(s, " "); - - return 0; -diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c -index 2ac06a642863a..127c78aec17db 100644 ---- a/kernel/trace/trace_uprobe.c -+++ b/kernel/trace/trace_uprobe.c -@@ -1418,7 +1418,7 @@ static void uretprobe_perf_func(struct trace_uprobe *tu, unsigned long func, - - int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type, - const char **filename, u64 *probe_offset, -- bool perf_type_tracepoint) -+ u64 *probe_addr, bool perf_type_tracepoint) - { - const char *pevent = trace_event_name(event->tp_event); - const char *group = event->tp_event->class->system; -@@ -1435,6 +1435,7 @@ int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type, - : BPF_FD_TYPE_UPROBE; - *filename = tu->filename; - *probe_offset = tu->offset; -+ *probe_addr = 0; - return 0; - } - #endif /* CONFIG_PERF_EVENTS */ -diff --git a/lib/xarray.c b/lib/xarray.c -index ea9ce1f0b3863..e9bd29826e8b0 100644 ---- a/lib/xarray.c -+++ b/lib/xarray.c -@@ -204,7 +204,7 @@ static void *xas_descend(struct xa_state *xas, struct xa_node *node) - void *entry = xa_entry(xas->xa, node, offset); - - xas->xa_node = node; -- if (xa_is_sibling(entry)) { -+ while (xa_is_sibling(entry)) { - offset = xa_to_sibling(entry); - entry = xa_entry(xas->xa, node, offset); - if (node->shift && xa_is_node(entry)) -diff --git a/mm/shmem.c b/mm/shmem.c -index 10365ced5b1fc..806741bbe4a68 100644 ---- a/mm/shmem.c -+++ b/mm/shmem.c -@@ -3485,6 +3485,8 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) - unsigned long long size; - char *rest; - int opt; -+ kuid_t kuid; -+ kgid_t kgid; - - opt = fs_parse(fc, shmem_fs_parameters, param, &result); - if (opt < 0) -@@ -3520,14 +3522,32 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) - ctx->mode = result.uint_32 & 07777; - break; - case Opt_uid: -- ctx->uid = make_kuid(current_user_ns(), result.uint_32); -- if (!uid_valid(ctx->uid)) -+ kuid = make_kuid(current_user_ns(), result.uint_32); -+ if (!uid_valid(kuid)) - goto bad_value; -+ -+ /* -+ * The requested uid must be representable in the -+ * filesystem's idmapping. -+ */ -+ if (!kuid_has_mapping(fc->user_ns, kuid)) -+ goto bad_value; -+ -+ ctx->uid = kuid; - break; - case Opt_gid: -- ctx->gid = make_kgid(current_user_ns(), result.uint_32); -- if (!gid_valid(ctx->gid)) -+ kgid = make_kgid(current_user_ns(), result.uint_32); -+ if (!gid_valid(kgid)) - goto bad_value; -+ -+ /* -+ * The requested gid must be representable in the -+ * filesystem's idmapping. -+ */ -+ if (!kgid_has_mapping(fc->user_ns, kgid)) -+ goto bad_value; -+ -+ ctx->gid = kgid; - break; - case Opt_huge: - ctx->huge = result.uint_32; -diff --git a/mm/util.c b/mm/util.c -index 12984e76767eb..ce3bb17c97b9d 100644 ---- a/mm/util.c -+++ b/mm/util.c -@@ -1127,7 +1127,9 @@ void mem_dump_obj(void *object) - if (vmalloc_dump_obj(object)) - return; - -- if (virt_addr_valid(object)) -+ if (is_vmalloc_addr(object)) -+ type = "vmalloc memory"; -+ else if (virt_addr_valid(object)) - type = "non-slab/vmalloc memory"; - else if (object == NULL) - type = "NULL pointer"; -diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index 80bd104a4d42e..67a10a04df041 100644 ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -4041,14 +4041,32 @@ void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms) - #ifdef CONFIG_PRINTK - bool vmalloc_dump_obj(void *object) - { -- struct vm_struct *vm; - void *objp = (void *)PAGE_ALIGN((unsigned long)object); -+ const void *caller; -+ struct vm_struct *vm; -+ struct vmap_area *va; -+ unsigned long addr; -+ unsigned int nr_pages; -+ -+ if (!spin_trylock(&vmap_area_lock)) -+ return false; -+ va = __find_vmap_area((unsigned long)objp, &vmap_area_root); -+ if (!va) { -+ spin_unlock(&vmap_area_lock); -+ return false; -+ } - -- vm = find_vm_area(objp); -- if (!vm) -+ vm = va->vm; -+ if (!vm) { -+ spin_unlock(&vmap_area_lock); - return false; -+ } -+ addr = (unsigned long)vm->addr; -+ caller = vm->caller; -+ nr_pages = vm->nr_pages; -+ spin_unlock(&vmap_area_lock); - pr_cont(" %u-page vmalloc region starting at %#lx allocated at %pS\n", -- vm->nr_pages, (unsigned long)vm->addr, vm->caller); -+ nr_pages, addr, caller); - return true; - } - #endif -diff --git a/mm/vmpressure.c b/mm/vmpressure.c -index b52644771cc43..22c6689d93027 100644 ---- a/mm/vmpressure.c -+++ b/mm/vmpressure.c -@@ -244,6 +244,14 @@ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, - if (mem_cgroup_disabled()) - return; - -+ /* -+ * The in-kernel users only care about the reclaim efficiency -+ * for this @memcg rather than the whole subtree, and there -+ * isn't and won't be any in-kernel user in a legacy cgroup. -+ */ -+ if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && !tree) -+ return; -+ - vmpr = memcg_to_vmpressure(memcg); - - /* -diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c -index 3f3eb03cda7d6..3cf660d8a0a7b 100644 ---- a/net/9p/trans_virtio.c -+++ b/net/9p/trans_virtio.c -@@ -385,7 +385,7 @@ static void handle_rerror(struct p9_req_t *req, int in_hdr_len, - void *to = req->rc.sdata + in_hdr_len; - - // Fits entirely into the static data? Nothing to do. -- if (req->rc.size < in_hdr_len) -+ if (req->rc.size < in_hdr_len || !pages) - return; - - // Really long error message? Tough, truncate the reply. Might get -@@ -429,7 +429,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, - struct page **in_pages = NULL, **out_pages = NULL; - struct virtio_chan *chan = client->trans; - struct scatterlist *sgs[4]; -- size_t offs; -+ size_t offs = 0; - int need_drop = 0; - int kicked = 0; - -diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c -index d034bf2a999e1..146553c0054f6 100644 ---- a/net/bluetooth/hci_core.c -+++ b/net/bluetooth/hci_core.c -@@ -1074,9 +1074,9 @@ void hci_uuids_clear(struct hci_dev *hdev) - - void hci_link_keys_clear(struct hci_dev *hdev) - { -- struct link_key *key; -+ struct link_key *key, *tmp; - -- list_for_each_entry(key, &hdev->link_keys, list) { -+ list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) { - list_del_rcu(&key->list); - kfree_rcu(key, rcu); - } -@@ -1084,9 +1084,9 @@ void hci_link_keys_clear(struct hci_dev *hdev) - - void hci_smp_ltks_clear(struct hci_dev *hdev) - { -- struct smp_ltk *k; -+ struct smp_ltk *k, *tmp; - -- list_for_each_entry(k, &hdev->long_term_keys, list) { -+ list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { - list_del_rcu(&k->list); - kfree_rcu(k, rcu); - } -@@ -1094,9 +1094,9 @@ void hci_smp_ltks_clear(struct hci_dev *hdev) - - void hci_smp_irks_clear(struct hci_dev *hdev) - { -- struct smp_irk *k; -+ struct smp_irk *k, *tmp; - -- list_for_each_entry(k, &hdev->identity_resolving_keys, list) { -+ list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { - list_del_rcu(&k->list); - kfree_rcu(k, rcu); - } -@@ -1104,9 +1104,9 @@ void hci_smp_irks_clear(struct hci_dev *hdev) - - void hci_blocked_keys_clear(struct hci_dev *hdev) - { -- struct blocked_key *b; -+ struct blocked_key *b, *tmp; - -- list_for_each_entry(b, &hdev->blocked_keys, list) { -+ list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) { - list_del_rcu(&b->list); - kfree_rcu(b, rcu); - } -@@ -1949,15 +1949,15 @@ int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) - - switch (hci_get_adv_monitor_offload_ext(hdev)) { - case HCI_ADV_MONITOR_EXT_NONE: -- bt_dev_dbg(hdev, "%s add monitor %d status %d", hdev->name, -+ bt_dev_dbg(hdev, "add monitor %d status %d", - monitor->handle, status); - /* Message was not forwarded to controller - not an error */ - break; - - case HCI_ADV_MONITOR_EXT_MSFT: - status = msft_add_monitor_pattern(hdev, monitor); -- bt_dev_dbg(hdev, "%s add monitor %d msft status %d", hdev->name, -- monitor->handle, status); -+ bt_dev_dbg(hdev, "add monitor %d msft status %d", -+ handle, status); - break; - } - -@@ -1976,15 +1976,15 @@ static int hci_remove_adv_monitor(struct hci_dev *hdev, - - switch (hci_get_adv_monitor_offload_ext(hdev)) { - case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ -- bt_dev_dbg(hdev, "%s remove monitor %d status %d", hdev->name, -+ bt_dev_dbg(hdev, "remove monitor %d status %d", - monitor->handle, status); - goto free_monitor; - - case HCI_ADV_MONITOR_EXT_MSFT: - handle = monitor->handle; - status = msft_remove_monitor(hdev, monitor); -- bt_dev_dbg(hdev, "%s remove monitor %d msft status %d", -- hdev->name, handle, status); -+ bt_dev_dbg(hdev, "remove monitor %d msft status %d", -+ handle, status); - break; - } - -diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c -index 699e4f400df29..5cd2e775915be 100644 ---- a/net/bluetooth/iso.c -+++ b/net/bluetooth/iso.c -@@ -1394,7 +1394,7 @@ static int iso_sock_release(struct socket *sock) - - iso_sock_close(sk); - -- if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && -+ if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) && - !(current->flags & PF_EXITING)) { - lock_sock(sk); - err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); -diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c -index 1755f91a66f6a..6d4168cfeb563 100644 ---- a/net/bluetooth/sco.c -+++ b/net/bluetooth/sco.c -@@ -1255,7 +1255,7 @@ static int sco_sock_release(struct socket *sock) - - sco_sock_close(sk); - -- if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && -+ if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) && - !(current->flags & PF_EXITING)) { - lock_sock(sk); - err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index b65962682771f..75204d36d7f90 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -201,9 +201,6 @@ int br_stp_set_enabled(struct net_bridge *br, unsigned long val, - { - ASSERT_RTNL(); - -- if (!net_eq(dev_net(br->dev), &init_net)) -- NL_SET_ERR_MSG_MOD(extack, "STP does not work in non-root netns"); -- - if (br_mrp_enabled(br)) { - NL_SET_ERR_MSG_MOD(extack, - "STP can't be enabled if MRP is already enabled"); -diff --git a/net/core/filter.c b/net/core/filter.c -index 419ce7c61bd6b..9fd7c88b5db4e 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -7259,6 +7259,8 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags) - return -ENETUNREACH; - if (unlikely(sk_fullsock(sk) && sk->sk_reuseport)) - return -ESOCKTNOSUPPORT; -+ if (sk_unhashed(sk)) -+ return -EOPNOTSUPP; - if (sk_is_refcounted(sk) && - unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) - return -ENOENT; -diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c -index 8b6b5e72b2179..4a0797f0a154b 100644 ---- a/net/core/lwt_bpf.c -+++ b/net/core/lwt_bpf.c -@@ -60,9 +60,8 @@ static int run_lwt_bpf(struct sk_buff *skb, struct bpf_lwt_prog *lwt, - ret = BPF_OK; - } else { - skb_reset_mac_header(skb); -- ret = skb_do_redirect(skb); -- if (ret == 0) -- ret = BPF_REDIRECT; -+ skb_do_redirect(skb); -+ ret = BPF_REDIRECT; - } - break; - -@@ -255,7 +254,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb) - - err = dst_output(dev_net(skb_dst(skb)->dev), skb->sk, skb); - if (unlikely(err)) -- return err; -+ return net_xmit_errno(err); - - /* ip[6]_finish_output2 understand LWTUNNEL_XMIT_DONE */ - return LWTUNNEL_XMIT_DONE; -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index b6c16db86c719..24bf4aa222d27 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -4135,21 +4135,20 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, - struct sk_buff *segs = NULL; - struct sk_buff *tail = NULL; - struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list; -- skb_frag_t *frag = skb_shinfo(head_skb)->frags; - unsigned int mss = skb_shinfo(head_skb)->gso_size; - unsigned int doffset = head_skb->data - skb_mac_header(head_skb); -- struct sk_buff *frag_skb = head_skb; - unsigned int offset = doffset; - unsigned int tnl_hlen = skb_tnl_header_len(head_skb); - unsigned int partial_segs = 0; - unsigned int headroom; - unsigned int len = head_skb->len; -+ struct sk_buff *frag_skb; -+ skb_frag_t *frag; - __be16 proto; - bool csum, sg; -- int nfrags = skb_shinfo(head_skb)->nr_frags; - int err = -ENOMEM; - int i = 0; -- int pos; -+ int nfrags, pos; - - if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) && - mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) { -@@ -4226,6 +4225,13 @@ normal: - headroom = skb_headroom(head_skb); - pos = skb_headlen(head_skb); - -+ if (skb_orphan_frags(head_skb, GFP_ATOMIC)) -+ return ERR_PTR(-ENOMEM); -+ -+ nfrags = skb_shinfo(head_skb)->nr_frags; -+ frag = skb_shinfo(head_skb)->frags; -+ frag_skb = head_skb; -+ - do { - struct sk_buff *nskb; - skb_frag_t *nskb_frag; -@@ -4246,6 +4252,10 @@ normal: - (skb_headlen(list_skb) == len || sg)) { - BUG_ON(skb_headlen(list_skb) > len); - -+ nskb = skb_clone(list_skb, GFP_ATOMIC); -+ if (unlikely(!nskb)) -+ goto err; -+ - i = 0; - nfrags = skb_shinfo(list_skb)->nr_frags; - frag = skb_shinfo(list_skb)->frags; -@@ -4264,12 +4274,8 @@ normal: - frag++; - } - -- nskb = skb_clone(list_skb, GFP_ATOMIC); - list_skb = list_skb->next; - -- if (unlikely(!nskb)) -- goto err; -- - if (unlikely(pskb_trim(nskb, len))) { - kfree_skb(nskb); - goto err; -@@ -4345,12 +4351,16 @@ normal: - skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags & - SKBFL_SHARED_FRAG; - -- if (skb_orphan_frags(frag_skb, GFP_ATOMIC) || -- skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC)) -+ if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC)) - goto err; - - while (pos < offset + len) { - if (i >= nfrags) { -+ if (skb_orphan_frags(list_skb, GFP_ATOMIC) || -+ skb_zerocopy_clone(nskb, list_skb, -+ GFP_ATOMIC)) -+ goto err; -+ - i = 0; - nfrags = skb_shinfo(list_skb)->nr_frags; - frag = skb_shinfo(list_skb)->frags; -@@ -4364,10 +4374,6 @@ normal: - i--; - frag--; - } -- if (skb_orphan_frags(frag_skb, GFP_ATOMIC) || -- skb_zerocopy_clone(nskb, frag_skb, -- GFP_ATOMIC)) -- goto err; - - list_skb = list_skb->next; - } -diff --git a/net/core/sock.c b/net/core/sock.c -index 509773919d302..fc475845c94d5 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -425,6 +425,7 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen, - { - struct __kernel_sock_timeval tv; - int err = sock_copy_user_timeval(&tv, optval, optlen, old_timeval); -+ long val; - - if (err) - return err; -@@ -435,7 +436,7 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen, - if (tv.tv_sec < 0) { - static int warned __read_mostly; - -- *timeo_p = 0; -+ WRITE_ONCE(*timeo_p, 0); - if (warned < 10 && net_ratelimit()) { - warned++; - pr_info("%s: `%s' (pid %d) tries to set negative timeout\n", -@@ -443,11 +444,12 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen, - } - return 0; - } -- *timeo_p = MAX_SCHEDULE_TIMEOUT; -- if (tv.tv_sec == 0 && tv.tv_usec == 0) -- return 0; -- if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1)) -- *timeo_p = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec, USEC_PER_SEC / HZ); -+ val = MAX_SCHEDULE_TIMEOUT; -+ if ((tv.tv_sec || tv.tv_usec) && -+ (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1))) -+ val = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec, -+ USEC_PER_SEC / HZ); -+ WRITE_ONCE(*timeo_p, val); - return 0; - } - -@@ -791,7 +793,7 @@ EXPORT_SYMBOL(sock_set_reuseport); - void sock_no_linger(struct sock *sk) - { - lock_sock(sk); -- sk->sk_lingertime = 0; -+ WRITE_ONCE(sk->sk_lingertime, 0); - sock_set_flag(sk, SOCK_LINGER); - release_sock(sk); - } -@@ -809,9 +811,9 @@ void sock_set_sndtimeo(struct sock *sk, s64 secs) - { - lock_sock(sk); - if (secs && secs < MAX_SCHEDULE_TIMEOUT / HZ - 1) -- sk->sk_sndtimeo = secs * HZ; -+ WRITE_ONCE(sk->sk_sndtimeo, secs * HZ); - else -- sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; -+ WRITE_ONCE(sk->sk_sndtimeo, MAX_SCHEDULE_TIMEOUT); - release_sock(sk); - } - EXPORT_SYMBOL(sock_set_sndtimeo); -@@ -1217,15 +1219,15 @@ set_sndbuf: - ret = -EFAULT; - break; - } -- if (!ling.l_onoff) -+ if (!ling.l_onoff) { - sock_reset_flag(sk, SOCK_LINGER); -- else { --#if (BITS_PER_LONG == 32) -- if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ) -- sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT; -+ } else { -+ unsigned long t_sec = ling.l_linger; -+ -+ if (t_sec >= MAX_SCHEDULE_TIMEOUT / HZ) -+ WRITE_ONCE(sk->sk_lingertime, MAX_SCHEDULE_TIMEOUT); - else --#endif -- sk->sk_lingertime = (unsigned int)ling.l_linger * HZ; -+ WRITE_ONCE(sk->sk_lingertime, t_sec * HZ); - sock_set_flag(sk, SOCK_LINGER); - } - break; -@@ -1676,7 +1678,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - case SO_LINGER: - lv = sizeof(v.ling); - v.ling.l_onoff = sock_flag(sk, SOCK_LINGER); -- v.ling.l_linger = sk->sk_lingertime / HZ; -+ v.ling.l_linger = READ_ONCE(sk->sk_lingertime) / HZ; - break; - - case SO_BSDCOMPAT: -@@ -1708,12 +1710,14 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - - case SO_RCVTIMEO_OLD: - case SO_RCVTIMEO_NEW: -- lv = sock_get_timeout(sk->sk_rcvtimeo, &v, SO_RCVTIMEO_OLD == optname); -+ lv = sock_get_timeout(READ_ONCE(sk->sk_rcvtimeo), &v, -+ SO_RCVTIMEO_OLD == optname); - break; - - case SO_SNDTIMEO_OLD: - case SO_SNDTIMEO_NEW: -- lv = sock_get_timeout(sk->sk_sndtimeo, &v, SO_SNDTIMEO_OLD == optname); -+ lv = sock_get_timeout(READ_ONCE(sk->sk_sndtimeo), &v, -+ SO_SNDTIMEO_OLD == optname); - break; - - case SO_RCVLOWAT: -diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c -index bfececa9e244e..8f5d3c0881118 100644 ---- a/net/dccp/ipv4.c -+++ b/net/dccp/ipv4.c -@@ -255,12 +255,17 @@ static int dccp_v4_err(struct sk_buff *skb, u32 info) - int err; - struct net *net = dev_net(skb->dev); - -- /* Only need dccph_dport & dccph_sport which are the first -- * 4 bytes in dccp header. -+ /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, -+ * which is in byte 7 of the dccp header. - * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. -+ * -+ * Later on, we want to access the sequence number fields, which are -+ * beyond 8 bytes, so we have to pskb_may_pull() ourselves. - */ -- BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); -- BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); -+ dh = (struct dccp_hdr *)(skb->data + offset); -+ if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) -+ return -EINVAL; -+ iph = (struct iphdr *)skb->data; - dh = (struct dccp_hdr *)(skb->data + offset); - - sk = __inet_lookup_established(net, &dccp_hashinfo, -diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c -index b51ce6f8ceba0..2b09e2644b13f 100644 ---- a/net/dccp/ipv6.c -+++ b/net/dccp/ipv6.c -@@ -74,7 +74,7 @@ static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) - static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, - u8 type, u8 code, int offset, __be32 info) - { -- const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; -+ const struct ipv6hdr *hdr; - const struct dccp_hdr *dh; - struct dccp_sock *dp; - struct ipv6_pinfo *np; -@@ -83,12 +83,17 @@ static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, - __u64 seq; - struct net *net = dev_net(skb->dev); - -- /* Only need dccph_dport & dccph_sport which are the first -- * 4 bytes in dccp header. -+ /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, -+ * which is in byte 7 of the dccp header. - * Our caller (icmpv6_notify()) already pulled 8 bytes for us. -+ * -+ * Later on, we want to access the sequence number fields, which are -+ * beyond 8 bytes, so we have to pskb_may_pull() ourselves. - */ -- BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); -- BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); -+ dh = (struct dccp_hdr *)(skb->data + offset); -+ if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) -+ return -EINVAL; -+ hdr = (const struct ipv6hdr *)skb->data; - dh = (struct dccp_hdr *)(skb->data + offset); - - sk = __inet6_lookup_established(net, &dccp_hashinfo, -diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c -index 81be3e0f0e704..cbc4816ed7d83 100644 ---- a/net/ipv4/igmp.c -+++ b/net/ipv4/igmp.c -@@ -353,8 +353,9 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) - struct flowi4 fl4; - int hlen = LL_RESERVED_SPACE(dev); - int tlen = dev->needed_tailroom; -- unsigned int size = mtu; -+ unsigned int size; - -+ size = min(mtu, IP_MAX_MTU); - while (1) { - skb = alloc_skb(size + hlen + tlen, - GFP_ATOMIC | __GFP_NOWARN); -diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c -index acfe58d2f1dd7..ebd2cea5b7d7a 100644 ---- a/net/ipv4/ip_output.c -+++ b/net/ipv4/ip_output.c -@@ -214,7 +214,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s - if (lwtunnel_xmit_redirect(dst->lwtstate)) { - int res = lwtunnel_xmit(skb); - -- if (res < 0 || res == LWTUNNEL_XMIT_DONE) -+ if (res != LWTUNNEL_XMIT_CONTINUE) - return res; - } - -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index e2d3ea2e34561..c697836f2b5b4 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -287,7 +287,7 @@ static void tcp_incr_quickack(struct sock *sk, unsigned int max_quickacks) - icsk->icsk_ack.quick = quickacks; - } - --void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks) -+static void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks) - { - struct inet_connection_sock *icsk = inet_csk(sk); - -@@ -295,7 +295,6 @@ void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks) - inet_csk_exit_pingpong_mode(sk); - icsk->icsk_ack.ato = TCP_ATO_MIN; - } --EXPORT_SYMBOL(tcp_enter_quickack_mode); - - /* Send ACKs quickly, if "quick" count is not exhausted - * and the session is not interactive. -diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c -index cf354c29ec123..44b49f7d1a9e6 100644 ---- a/net/ipv4/tcp_timer.c -+++ b/net/ipv4/tcp_timer.c -@@ -441,6 +441,22 @@ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req) - req->timeout << req->num_timeout, TCP_RTO_MAX); - } - -+static bool tcp_rtx_probe0_timed_out(const struct sock *sk, -+ const struct sk_buff *skb) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ const int timeout = TCP_RTO_MAX * 2; -+ u32 rcv_delta, rtx_delta; -+ -+ rcv_delta = inet_csk(sk)->icsk_timeout - tp->rcv_tstamp; -+ if (rcv_delta <= timeout) -+ return false; -+ -+ rtx_delta = (u32)msecs_to_jiffies(tcp_time_stamp(tp) - -+ (tp->retrans_stamp ?: tcp_skb_timestamp(skb))); -+ -+ return rtx_delta > timeout; -+} - - /** - * tcp_retransmit_timer() - The TCP retransmit timeout handler -@@ -506,7 +522,7 @@ void tcp_retransmit_timer(struct sock *sk) - tp->snd_una, tp->snd_nxt); - } - #endif -- if (tcp_jiffies32 - tp->rcv_tstamp > TCP_RTO_MAX) { -+ if (tcp_rtx_probe0_timed_out(sk, skb)) { - tcp_write_err(sk); - goto out; - } -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 956d6797c76f3..42c1f7d9a980a 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -445,14 +445,24 @@ static struct sock *udp4_lib_lookup2(struct net *net, - score = compute_score(sk, net, saddr, sport, - daddr, hnum, dif, sdif); - if (score > badness) { -- result = lookup_reuseport(net, sk, skb, -- saddr, sport, daddr, hnum); -+ badness = score; -+ result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ if (!result) { -+ result = sk; -+ continue; -+ } -+ - /* Fall back to scoring if group has connections */ -- if (result && !reuseport_has_conns(sk)) -+ if (!reuseport_has_conns(sk)) - return result; - -- result = result ? : sk; -- badness = score; -+ /* Reuseport logic returned an error, keep original score. */ -+ if (IS_ERR(result)) -+ continue; -+ -+ badness = compute_score(result, net, saddr, sport, -+ daddr, hnum, dif, sdif); -+ - } - } - return result; -diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c -index 95a55c6630add..34192f7a166fb 100644 ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -112,7 +112,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * - if (lwtunnel_xmit_redirect(dst->lwtstate)) { - int res = lwtunnel_xmit(skb); - -- if (res < 0 || res == LWTUNNEL_XMIT_DONE) -+ if (res != LWTUNNEL_XMIT_CONTINUE) - return res; - } - -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 27348172b25b9..64b36c2ba774a 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -193,14 +193,23 @@ static struct sock *udp6_lib_lookup2(struct net *net, - score = compute_score(sk, net, saddr, sport, - daddr, hnum, dif, sdif); - if (score > badness) { -- result = lookup_reuseport(net, sk, skb, -- saddr, sport, daddr, hnum); -+ badness = score; -+ result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); -+ if (!result) { -+ result = sk; -+ continue; -+ } -+ - /* Fall back to scoring if group has connections */ -- if (result && !reuseport_has_conns(sk)) -+ if (!reuseport_has_conns(sk)) - return result; - -- result = result ? : sk; -- badness = score; -+ /* Reuseport logic returned an error, keep original score. */ -+ if (IS_ERR(result)) -+ continue; -+ -+ badness = compute_score(sk, net, saddr, sport, -+ daddr, hnum, dif, sdif); - } - } - return result; -diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c -index 763cefd0cc268..2f9e1abdf375d 100644 ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -4391,7 +4391,7 @@ static void ieee80211_mlo_multicast_tx(struct net_device *dev, - struct sk_buff *skb) - { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -- unsigned long links = sdata->vif.valid_links; -+ unsigned long links = sdata->vif.active_links; - unsigned int link; - u32 ctrl_flags = IEEE80211_TX_CTRL_MCAST_MLO_FIRST_TX; - -@@ -5827,7 +5827,7 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, - rcu_read_unlock(); - - if (WARN_ON_ONCE(link == ARRAY_SIZE(sdata->vif.link_conf))) -- link = ffs(sdata->vif.valid_links) - 1; -+ link = ffs(sdata->vif.active_links) - 1; - } - - IEEE80211_SKB_CB(skb)->control.flags |= -@@ -5863,7 +5863,7 @@ void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, - band = chanctx_conf->def.chan->band; - } else { - WARN_ON(link_id >= 0 && -- !(sdata->vif.valid_links & BIT(link_id))); -+ !(sdata->vif.active_links & BIT(link_id))); - /* MLD transmissions must not rely on the band */ - band = 0; - } -diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c -index 005a7ce87217e..bf4f91b78e1dc 100644 ---- a/net/netfilter/ipset/ip_set_hash_netportnet.c -+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c -@@ -36,6 +36,7 @@ MODULE_ALIAS("ip_set_hash:net,port,net"); - #define IP_SET_HASH_WITH_PROTO - #define IP_SET_HASH_WITH_NETS - #define IPSET_NET_COUNT 2 -+#define IP_SET_HASH_WITH_NET0 - - /* IPv4 variant */ - -diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c -index a67ea9c3ae57d..c307c57a93e57 100644 ---- a/net/netfilter/nft_exthdr.c -+++ b/net/netfilter/nft_exthdr.c -@@ -238,7 +238,12 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr, - if (!tcph) - goto err; - -+ if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len)) -+ goto err; -+ -+ tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt)); - opt = (u8 *)tcph; -+ - for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { - union { - __be16 v16; -@@ -253,15 +258,6 @@ static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr, - if (i + optl > tcphdr_len || priv->len + priv->offset > optl) - goto err; - -- if (skb_ensure_writable(pkt->skb, -- nft_thoff(pkt) + i + priv->len)) -- goto err; -- -- tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, -- &tcphdr_len); -- if (!tcph) -- goto err; -- - offset = i + priv->offset; - - switch (priv->len) { -@@ -325,9 +321,9 @@ static void nft_exthdr_tcp_strip_eval(const struct nft_expr *expr, - if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len)) - goto drop; - -- opt = (u8 *)nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len); -- if (!opt) -- goto err; -+ tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt)); -+ opt = (u8 *)tcph; -+ - for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { - unsigned int j; - -diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c -index 680015ba7cb6e..d4bf089c9e3f9 100644 ---- a/net/netfilter/xt_sctp.c -+++ b/net/netfilter/xt_sctp.c -@@ -150,6 +150,8 @@ static int sctp_mt_check(const struct xt_mtchk_param *par) - { - const struct xt_sctp_info *info = par->matchinfo; - -+ if (info->flag_count > ARRAY_SIZE(info->flag_info)) -+ return -EINVAL; - if (info->flags & ~XT_SCTP_VALID_FLAGS) - return -EINVAL; - if (info->invflags & ~XT_SCTP_VALID_FLAGS) -diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c -index 177b40d08098b..117d4615d6684 100644 ---- a/net/netfilter/xt_u32.c -+++ b/net/netfilter/xt_u32.c -@@ -96,11 +96,32 @@ static bool u32_mt(const struct sk_buff *skb, struct xt_action_param *par) - return ret ^ data->invert; - } - -+static int u32_mt_checkentry(const struct xt_mtchk_param *par) -+{ -+ const struct xt_u32 *data = par->matchinfo; -+ const struct xt_u32_test *ct; -+ unsigned int i; -+ -+ if (data->ntests > ARRAY_SIZE(data->tests)) -+ return -EINVAL; -+ -+ for (i = 0; i < data->ntests; ++i) { -+ ct = &data->tests[i]; -+ -+ if (ct->nnums > ARRAY_SIZE(ct->location) || -+ ct->nvalues > ARRAY_SIZE(ct->value)) -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - static struct xt_match xt_u32_mt_reg __read_mostly = { - .name = "u32", - .revision = 0, - .family = NFPROTO_UNSPEC, - .match = u32_mt, -+ .checkentry = u32_mt_checkentry, - .matchsize = sizeof(struct xt_u32), - .me = THIS_MODULE, - }; -diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c -index 54c0830039470..27511c90a26f4 100644 ---- a/net/netlabel/netlabel_kapi.c -+++ b/net/netlabel/netlabel_kapi.c -@@ -857,7 +857,8 @@ int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap, - - offset -= iter->startbit; - idx = offset / NETLBL_CATMAP_MAPSIZE; -- iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE); -+ iter->bitmap[idx] |= (NETLBL_CATMAP_MAPTYPE)bitmap -+ << (offset % NETLBL_CATMAP_MAPSIZE); - - return 0; - } -diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c -index 5a4cb796150f5..ec5747969f964 100644 ---- a/net/netrom/af_netrom.c -+++ b/net/netrom/af_netrom.c -@@ -660,6 +660,11 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, - goto out_release; - } - -+ if (sock->state == SS_CONNECTING) { -+ err = -EALREADY; -+ goto out_release; -+ } -+ - sk->sk_state = TCP_CLOSE; - sock->state = SS_UNCONNECTED; - -diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c -index 49bae3d5006b0..6f2f135aab676 100644 ---- a/net/sched/em_meta.c -+++ b/net/sched/em_meta.c -@@ -502,7 +502,7 @@ META_COLLECTOR(int_sk_lingertime) - *err = -1; - return; - } -- dst->value = sk->sk_lingertime / HZ; -+ dst->value = READ_ONCE(sk->sk_lingertime) / HZ; - } - - META_COLLECTOR(int_sk_err_qlen) -@@ -568,7 +568,7 @@ META_COLLECTOR(int_sk_rcvtimeo) - *err = -1; - return; - } -- dst->value = sk->sk_rcvtimeo / HZ; -+ dst->value = READ_ONCE(sk->sk_rcvtimeo) / HZ; - } - - META_COLLECTOR(int_sk_sndtimeo) -@@ -579,7 +579,7 @@ META_COLLECTOR(int_sk_sndtimeo) - *err = -1; - return; - } -- dst->value = sk->sk_sndtimeo / HZ; -+ dst->value = READ_ONCE(sk->sk_sndtimeo) / HZ; - } - - META_COLLECTOR(int_sk_sendmsg_off) -diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c -index 70b0c5873d326..61d52594ff6d8 100644 ---- a/net/sched/sch_hfsc.c -+++ b/net/sched/sch_hfsc.c -@@ -1012,6 +1012,10 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, - if (parent == NULL) - return -ENOENT; - } -+ if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) { -+ NL_SET_ERR_MSG(extack, "Invalid parent - parent class must have FSC"); -+ return -EINVAL; -+ } - - if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0) - return -EINVAL; -diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c -index 463c4a58d2c36..970c6a486a9b0 100644 ---- a/net/sctp/sm_sideeffect.c -+++ b/net/sctp/sm_sideeffect.c -@@ -1251,7 +1251,10 @@ static int sctp_side_effects(enum sctp_event_type event_type, - default: - pr_err("impossible disposition %d in state %d, event_type %d, event_id %d\n", - status, state, event_type, subtype.chunk); -- BUG(); -+ error = status; -+ if (error >= 0) -+ error = -EINVAL; -+ WARN_ON_ONCE(1); - break; - } - -diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c -index 84219c5121bc2..f774d840759d6 100644 ---- a/net/smc/af_smc.c -+++ b/net/smc/af_smc.c -@@ -1807,7 +1807,7 @@ void smc_close_non_accepted(struct sock *sk) - lock_sock(sk); - if (!sk->sk_lingertime) - /* wait for peer closing */ -- sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT; -+ WRITE_ONCE(sk->sk_lingertime, SMC_MAX_STREAM_WAIT_TIMEOUT); - __smc_release(smc); - release_sock(sk); - sock_put(sk); /* sock_hold above */ -diff --git a/net/socket.c b/net/socket.c -index c2e0a22f16d9b..d281a7ef4b1d3 100644 ---- a/net/socket.c -+++ b/net/socket.c -@@ -3507,7 +3507,11 @@ EXPORT_SYMBOL(kernel_accept); - int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, - int flags) - { -- return sock->ops->connect(sock, addr, addrlen, flags); -+ struct sockaddr_storage address; -+ -+ memcpy(&address, addr, addrlen); -+ -+ return sock->ops->connect(sock, (struct sockaddr *)&address, addrlen, flags); - } - EXPORT_SYMBOL(kernel_connect); - -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index c2363d44a1ffc..12c7c89d5be1d 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -323,6 +323,7 @@ nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = { - [NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG }, - [NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG }, - [NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK] = { .type = NLA_FLAG }, -+ [NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR] = { .type = NLA_U8 }, - }; - - static const struct nla_policy -diff --git a/net/wireless/util.c b/net/wireless/util.c -index 39680e7bad45a..f433f3fdd9e94 100644 ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -5,7 +5,7 @@ - * Copyright 2007-2009 Johannes Berg - * Copyright 2013-2014 Intel Mobile Communications GmbH - * Copyright 2017 Intel Deutschland GmbH -- * Copyright (C) 2018-2022 Intel Corporation -+ * Copyright (C) 2018-2023 Intel Corporation - */ - #include - #include -@@ -2479,6 +2479,13 @@ void cfg80211_remove_links(struct wireless_dev *wdev) - { - unsigned int link_id; - -+ /* -+ * links are controlled by upper layers (userspace/cfg) -+ * only for AP mode, so only remove them here for AP -+ */ -+ if (wdev->iftype != NL80211_IFTYPE_AP) -+ return; -+ - wdev_lock(wdev); - if (wdev->valid_links) { - for_each_valid_link(wdev, link_id) -diff --git a/samples/bpf/tracex3_kern.c b/samples/bpf/tracex3_kern.c -index bde6591cb20c5..af235bd6615b1 100644 ---- a/samples/bpf/tracex3_kern.c -+++ b/samples/bpf/tracex3_kern.c -@@ -11,6 +11,12 @@ - #include - #include - -+struct start_key { -+ dev_t dev; -+ u32 _pad; -+ sector_t sector; -+}; -+ - struct { - __uint(type, BPF_MAP_TYPE_HASH); - __type(key, long); -@@ -18,16 +24,17 @@ struct { - __uint(max_entries, 4096); - } my_map SEC(".maps"); - --/* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe -- * example will no longer be meaningful -- */ --SEC("kprobe/blk_mq_start_request") --int bpf_prog1(struct pt_regs *ctx) -+/* from /sys/kernel/tracing/events/block/block_io_start/format */ -+SEC("tracepoint/block/block_io_start") -+int bpf_prog1(struct trace_event_raw_block_rq *ctx) - { -- long rq = PT_REGS_PARM1(ctx); - u64 val = bpf_ktime_get_ns(); -+ struct start_key key = { -+ .dev = ctx->dev, -+ .sector = ctx->sector -+ }; - -- bpf_map_update_elem(&my_map, &rq, &val, BPF_ANY); -+ bpf_map_update_elem(&my_map, &key, &val, BPF_ANY); - return 0; - } - -@@ -49,21 +56,26 @@ struct { - __uint(max_entries, SLOTS); - } lat_map SEC(".maps"); - --SEC("kprobe/__blk_account_io_done") --int bpf_prog2(struct pt_regs *ctx) -+/* from /sys/kernel/tracing/events/block/block_io_done/format */ -+SEC("tracepoint/block/block_io_done") -+int bpf_prog2(struct trace_event_raw_block_rq *ctx) - { -- long rq = PT_REGS_PARM1(ctx); -+ struct start_key key = { -+ .dev = ctx->dev, -+ .sector = ctx->sector -+ }; -+ - u64 *value, l, base; - u32 index; - -- value = bpf_map_lookup_elem(&my_map, &rq); -+ value = bpf_map_lookup_elem(&my_map, &key); - if (!value) - return 0; - - u64 cur_time = bpf_ktime_get_ns(); - u64 delta = cur_time - *value; - -- bpf_map_delete_elem(&my_map, &rq); -+ bpf_map_delete_elem(&my_map, &key); - - /* the lines below are computing index = log10(delta)*10 - * using integer arithmetic -diff --git a/samples/bpf/tracex6_kern.c b/samples/bpf/tracex6_kern.c -index acad5712d8b4f..fd602c2774b8b 100644 ---- a/samples/bpf/tracex6_kern.c -+++ b/samples/bpf/tracex6_kern.c -@@ -2,6 +2,8 @@ - #include - #include - #include -+#include -+#include - - struct { - __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); -@@ -45,13 +47,24 @@ int bpf_prog1(struct pt_regs *ctx) - return 0; - } - --SEC("kprobe/htab_map_lookup_elem") --int bpf_prog2(struct pt_regs *ctx) -+/* -+ * Since *_map_lookup_elem can't be expected to trigger bpf programs -+ * due to potential deadlocks (bpf_disable_instrumentation), this bpf -+ * program will be attached to bpf_map_copy_value (which is called -+ * from map_lookup_elem) and will only filter the hashtable type. -+ */ -+SEC("kprobe/bpf_map_copy_value") -+int BPF_KPROBE(bpf_prog2, struct bpf_map *map) - { - u32 key = bpf_get_smp_processor_id(); - struct bpf_perf_event_value *val, buf; -+ enum bpf_map_type type; - int error; - -+ type = BPF_CORE_READ(map, map_type); -+ if (type != BPF_MAP_TYPE_HASH) -+ return 0; -+ - error = bpf_perf_event_read_value(&counters, key, &buf, sizeof(buf)); - if (error) - return 0; -diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh -index aebbf19139709..7a925d2b20fc7 100755 ---- a/scripts/rust_is_available.sh -+++ b/scripts/rust_is_available.sh -@@ -2,8 +2,6 @@ - # SPDX-License-Identifier: GPL-2.0 - # - # Tests whether a suitable Rust toolchain is available. --# --# Pass `-v` for human output and more checks (as warnings). - - set -e - -@@ -23,21 +21,17 @@ get_canonical_version() - - # Check that the Rust compiler exists. - if ! command -v "$RUSTC" >/dev/null; then -- if [ "$1" = -v ]; then -- echo >&2 "***" -- echo >&2 "*** Rust compiler '$RUSTC' could not be found." -- echo >&2 "***" -- fi -+ echo >&2 "***" -+ echo >&2 "*** Rust compiler '$RUSTC' could not be found." -+ echo >&2 "***" - exit 1 - fi - - # Check that the Rust bindings generator exists. - if ! command -v "$BINDGEN" >/dev/null; then -- if [ "$1" = -v ]; then -- echo >&2 "***" -- echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found." -- echo >&2 "***" -- fi -+ echo >&2 "***" -+ echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found." -+ echo >&2 "***" - exit 1 - fi - -@@ -53,16 +47,14 @@ rust_compiler_min_version=$($min_tool_version rustc) - rust_compiler_cversion=$(get_canonical_version $rust_compiler_version) - rust_compiler_min_cversion=$(get_canonical_version $rust_compiler_min_version) - if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then -- if [ "$1" = -v ]; then -- echo >&2 "***" -- echo >&2 "*** Rust compiler '$RUSTC' is too old." -- echo >&2 "*** Your version: $rust_compiler_version" -- echo >&2 "*** Minimum version: $rust_compiler_min_version" -- echo >&2 "***" -- fi -+ echo >&2 "***" -+ echo >&2 "*** Rust compiler '$RUSTC' is too old." -+ echo >&2 "*** Your version: $rust_compiler_version" -+ echo >&2 "*** Minimum version: $rust_compiler_min_version" -+ echo >&2 "***" - exit 1 - fi --if [ "$1" = -v ] && [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then -+if [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then - echo >&2 "***" - echo >&2 "*** Rust compiler '$RUSTC' is too new. This may or may not work." - echo >&2 "*** Your version: $rust_compiler_version" -@@ -82,16 +74,14 @@ rust_bindings_generator_min_version=$($min_tool_version bindgen) - rust_bindings_generator_cversion=$(get_canonical_version $rust_bindings_generator_version) - rust_bindings_generator_min_cversion=$(get_canonical_version $rust_bindings_generator_min_version) - if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cversion" ]; then -- if [ "$1" = -v ]; then -- echo >&2 "***" -- echo >&2 "*** Rust bindings generator '$BINDGEN' is too old." -- echo >&2 "*** Your version: $rust_bindings_generator_version" -- echo >&2 "*** Minimum version: $rust_bindings_generator_min_version" -- echo >&2 "***" -- fi -+ echo >&2 "***" -+ echo >&2 "*** Rust bindings generator '$BINDGEN' is too old." -+ echo >&2 "*** Your version: $rust_bindings_generator_version" -+ echo >&2 "*** Minimum version: $rust_bindings_generator_min_version" -+ echo >&2 "***" - exit 1 - fi --if [ "$1" = -v ] && [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then -+if [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then - echo >&2 "***" - echo >&2 "*** Rust bindings generator '$BINDGEN' is too new. This may or may not work." - echo >&2 "*** Your version: $rust_bindings_generator_version" -@@ -100,23 +90,39 @@ if [ "$1" = -v ] && [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_ge - fi - - # Check that the `libclang` used by the Rust bindings generator is suitable. -+# -+# In order to do that, first invoke `bindgen` to get the `libclang` version -+# found by `bindgen`. This step may already fail if, for instance, `libclang` -+# is not found, thus inform the user in such a case. -+bindgen_libclang_output=$( \ -+ LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null -+) || bindgen_libclang_code=$? -+if [ -n "$bindgen_libclang_code" ]; then -+ echo >&2 "***" -+ echo >&2 "*** Running '$BINDGEN' to check the libclang version (used by the Rust" -+ echo >&2 "*** bindings generator) failed with code $bindgen_libclang_code. This may be caused by" -+ echo >&2 "*** a failure to locate libclang. See output and docs below for details:" -+ echo >&2 "***" -+ echo >&2 "$bindgen_libclang_output" -+ echo >&2 "***" -+ exit 1 -+fi -+ -+# `bindgen` returned successfully, thus use the output to check that the version -+# of the `libclang` found by the Rust bindings generator is suitable. - bindgen_libclang_version=$( \ -- LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null \ -- | grep -F 'clang version ' \ -- | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \ -- | head -n 1 \ -+ echo "$bindgen_libclang_output" \ -+ | sed -nE 's:.*clang version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p' - ) - bindgen_libclang_min_version=$($min_tool_version llvm) - bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version) - bindgen_libclang_min_cversion=$(get_canonical_version $bindgen_libclang_min_version) - if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then -- if [ "$1" = -v ]; then -- echo >&2 "***" -- echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old." -- echo >&2 "*** Your version: $bindgen_libclang_version" -- echo >&2 "*** Minimum version: $bindgen_libclang_min_version" -- echo >&2 "***" -- fi -+ echo >&2 "***" -+ echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old." -+ echo >&2 "*** Your version: $bindgen_libclang_version" -+ echo >&2 "*** Minimum version: $bindgen_libclang_min_version" -+ echo >&2 "***" - exit 1 - fi - -@@ -125,21 +131,19 @@ fi - # - # In the future, we might be able to perform a full version check, see - # https://github.com/rust-lang/rust-bindgen/issues/2138. --if [ "$1" = -v ]; then -- cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ') -- if [ "$cc_name" = Clang ]; then -- clang_version=$( \ -- LC_ALL=C "$CC" --version 2>/dev/null \ -- | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p' -- ) -- if [ "$clang_version" != "$bindgen_libclang_version" ]; then -- echo >&2 "***" -- echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')" -- echo >&2 "*** version does not match Clang's. This may be a problem." -- echo >&2 "*** libclang version: $bindgen_libclang_version" -- echo >&2 "*** Clang version: $clang_version" -- echo >&2 "***" -- fi -+cc_name=$($(dirname $0)/cc-version.sh $CC | cut -f1 -d' ') -+if [ "$cc_name" = Clang ]; then -+ clang_version=$( \ -+ LC_ALL=C $CC --version 2>/dev/null \ -+ | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p' -+ ) -+ if [ "$clang_version" != "$bindgen_libclang_version" ]; then -+ echo >&2 "***" -+ echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')" -+ echo >&2 "*** version does not match Clang's. This may be a problem." -+ echo >&2 "*** libclang version: $bindgen_libclang_version" -+ echo >&2 "*** Clang version: $clang_version" -+ echo >&2 "***" - fi - fi - -@@ -150,11 +154,9 @@ rustc_sysroot=$("$RUSTC" $KRUSTFLAGS --print sysroot) - rustc_src=${RUST_LIB_SRC:-"$rustc_sysroot/lib/rustlib/src/rust/library"} - rustc_src_core="$rustc_src/core/src/lib.rs" - if [ ! -e "$rustc_src_core" ]; then -- if [ "$1" = -v ]; then -- echo >&2 "***" -- echo >&2 "*** Source code for the 'core' standard library could not be found" -- echo >&2 "*** at '$rustc_src_core'." -- echo >&2 "***" -- fi -+ echo >&2 "***" -+ echo >&2 "*** Source code for the 'core' standard library could not be found" -+ echo >&2 "*** at '$rustc_src_core'." -+ echo >&2 "***" - exit 1 - fi -diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig -index 60a511c6b583e..c17660bf5f347 100644 ---- a/security/integrity/ima/Kconfig -+++ b/security/integrity/ima/Kconfig -@@ -248,18 +248,6 @@ config IMA_APPRAISE_MODSIG - The modsig keyword can be used in the IMA policy to allow a hook - to accept such signatures. - --config IMA_TRUSTED_KEYRING -- bool "Require all keys on the .ima keyring be signed (deprecated)" -- depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING -- depends on INTEGRITY_ASYMMETRIC_KEYS -- select INTEGRITY_TRUSTED_KEYRING -- default y -- help -- This option requires that all keys added to the .ima -- keyring be signed by a key on the system trusted keyring. -- -- This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING -- - config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY - bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)" - depends on SYSTEM_TRUSTED_KEYRING -diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c -index d54f73c558f72..19be69fa4d052 100644 ---- a/security/keys/keyctl.c -+++ b/security/keys/keyctl.c -@@ -980,14 +980,19 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) - ret = -EACCES; - down_write(&key->sem); - -- if (!capable(CAP_SYS_ADMIN)) { -+ { -+ bool is_privileged_op = false; -+ - /* only the sysadmin can chown a key to some other UID */ - if (user != (uid_t) -1 && !uid_eq(key->uid, uid)) -- goto error_put; -+ is_privileged_op = true; - - /* only the sysadmin can set the key's GID to a group other - * than one of those that the current process subscribes to */ - if (group != (gid_t) -1 && !gid_eq(gid, key->gid) && !in_group_p(gid)) -+ is_privileged_op = true; -+ -+ if (is_privileged_op && !capable(CAP_SYS_ADMIN)) - goto error_put; - } - -@@ -1088,7 +1093,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) - down_write(&key->sem); - - /* if we're not the sysadmin, we can only change a key that we own */ -- if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) { -+ if (uid_eq(key->uid, current_fsuid()) || capable(CAP_SYS_ADMIN)) { - key->perm = perm; - notify_key(key, NOTIFY_KEY_SETATTR, 0); - ret = 0; -diff --git a/security/security.c b/security/security.c -index 75dc0947ee0cf..5fa286ae9908d 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -882,6 +882,20 @@ void security_bprm_committed_creds(struct linux_binprm *bprm) - call_void_hook(bprm_committed_creds, bprm); - } - -+/** -+ * security_fs_context_submount() - Initialise fc->security -+ * @fc: new filesystem context -+ * @reference: dentry reference for submount/remount -+ * -+ * Fill out the ->security field for a new fs_context. -+ * -+ * Return: Returns 0 on success or negative error code on failure. -+ */ -+int security_fs_context_submount(struct fs_context *fc, struct super_block *reference) -+{ -+ return call_int_hook(fs_context_submount, 0, fc, reference); -+} -+ - int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) - { - return call_int_hook(fs_context_dup, 0, fc, src_fc); -diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c -index f553c370397ee..26c9e4da4efcf 100644 ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2766,6 +2766,27 @@ static int selinux_umount(struct vfsmount *mnt, int flags) - FILESYSTEM__UNMOUNT, NULL); - } - -+static int selinux_fs_context_submount(struct fs_context *fc, -+ struct super_block *reference) -+{ -+ const struct superblock_security_struct *sbsec; -+ struct selinux_mnt_opts *opts; -+ -+ opts = kzalloc(sizeof(*opts), GFP_KERNEL); -+ if (!opts) -+ return -ENOMEM; -+ -+ sbsec = selinux_superblock(reference); -+ if (sbsec->flags & FSCONTEXT_MNT) -+ opts->fscontext_sid = sbsec->sid; -+ if (sbsec->flags & CONTEXT_MNT) -+ opts->context_sid = sbsec->mntpoint_sid; -+ if (sbsec->flags & DEFCONTEXT_MNT) -+ opts->defcontext_sid = sbsec->def_sid; -+ fc->security = opts; -+ return 0; -+} -+ - static int selinux_fs_context_dup(struct fs_context *fc, - struct fs_context *src_fc) - { -@@ -7263,6 +7284,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { - /* - * PUT "CLONING" (ACCESSING + ALLOCATING) HOOKS HERE - */ -+ LSM_HOOK_INIT(fs_context_submount, selinux_fs_context_submount), - LSM_HOOK_INIT(fs_context_dup, selinux_fs_context_dup), - LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), - LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), -diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c -index b6306d71c9088..67dcd31cd3f3d 100644 ---- a/security/smack/smack_lsm.c -+++ b/security/smack/smack_lsm.c -@@ -611,6 +611,56 @@ out_opt_err: - return -EINVAL; - } - -+/** -+ * smack_fs_context_submount - Initialise security data for a filesystem context -+ * @fc: The filesystem context. -+ * @reference: reference superblock -+ * -+ * Returns 0 on success or -ENOMEM on error. -+ */ -+static int smack_fs_context_submount(struct fs_context *fc, -+ struct super_block *reference) -+{ -+ struct superblock_smack *sbsp; -+ struct smack_mnt_opts *ctx; -+ struct inode_smack *isp; -+ -+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); -+ if (!ctx) -+ return -ENOMEM; -+ fc->security = ctx; -+ -+ sbsp = smack_superblock(reference); -+ isp = smack_inode(reference->s_root->d_inode); -+ -+ if (sbsp->smk_default) { -+ ctx->fsdefault = kstrdup(sbsp->smk_default->smk_known, GFP_KERNEL); -+ if (!ctx->fsdefault) -+ return -ENOMEM; -+ } -+ -+ if (sbsp->smk_floor) { -+ ctx->fsfloor = kstrdup(sbsp->smk_floor->smk_known, GFP_KERNEL); -+ if (!ctx->fsfloor) -+ return -ENOMEM; -+ } -+ -+ if (sbsp->smk_hat) { -+ ctx->fshat = kstrdup(sbsp->smk_hat->smk_known, GFP_KERNEL); -+ if (!ctx->fshat) -+ return -ENOMEM; -+ } -+ -+ if (isp->smk_flags & SMK_INODE_TRANSMUTE) { -+ if (sbsp->smk_root) { -+ ctx->fstransmute = kstrdup(sbsp->smk_root->smk_known, GFP_KERNEL); -+ if (!ctx->fstransmute) -+ return -ENOMEM; -+ } -+ } -+ return 0; -+} -+ - /** - * smack_fs_context_dup - Duplicate the security data on fs_context duplication - * @fc: The new filesystem context. -@@ -4792,6 +4842,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { - LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), - LSM_HOOK_INIT(syslog, smack_syslog), - -+ LSM_HOOK_INIT(fs_context_submount, smack_fs_context_submount), - LSM_HOOK_INIT(fs_context_dup, smack_fs_context_dup), - LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param), - -diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c -index 4b58526450d49..da7db9e22ce7c 100644 ---- a/security/smack/smackfs.c -+++ b/security/smack/smackfs.c -@@ -896,7 +896,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, - } - - ret = sscanf(rule, "%d", &catlen); -- if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) -+ if (ret != 1 || catlen < 0 || catlen > SMACK_CIPSO_MAXCATNUM) - goto out; - - if (format == SMK_FIXED24_FMT && -diff --git a/sound/Kconfig b/sound/Kconfig -index e56d96d2b11ca..1903c35d799e1 100644 ---- a/sound/Kconfig -+++ b/sound/Kconfig -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - menuconfig SOUND - tristate "Sound card support" -- depends on HAS_IOMEM -+ depends on HAS_IOMEM || UML - help - If you have a sound card in your computer, i.e. if it can say more - than an occasional beep, say Y. -diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c -index 42c2ada8e8887..c96483091f30a 100644 ---- a/sound/core/pcm_compat.c -+++ b/sound/core/pcm_compat.c -@@ -253,10 +253,14 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream, - goto error; - } - -- if (refine) -+ if (refine) { - err = snd_pcm_hw_refine(substream, data); -- else -+ if (err < 0) -+ goto error; -+ err = fixup_unreferenced_params(substream, data); -+ } else { - err = snd_pcm_hw_params(substream, data); -+ } - if (err < 0) - goto error; - if (copy_to_user(data32, data, sizeof(*data32)) || -diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c -index 07efb38f58ac1..f2940b29595f0 100644 ---- a/sound/core/seq/oss/seq_oss_midi.c -+++ b/sound/core/seq/oss/seq_oss_midi.c -@@ -37,6 +37,7 @@ struct seq_oss_midi { - struct snd_midi_event *coder; /* MIDI event coder */ - struct seq_oss_devinfo *devinfo; /* assigned OSSseq device */ - snd_use_lock_t use_lock; -+ struct mutex open_mutex; - }; - - -@@ -172,6 +173,7 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) - mdev->flags = pinfo->capability; - mdev->opened = 0; - snd_use_lock_init(&mdev->use_lock); -+ mutex_init(&mdev->open_mutex); - - /* copy and truncate the name of synth device */ - strscpy(mdev->name, pinfo->name, sizeof(mdev->name)); -@@ -322,15 +324,17 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode) - int perm; - struct seq_oss_midi *mdev; - struct snd_seq_port_subscribe subs; -+ int err; - - mdev = get_mididev(dp, dev); - if (!mdev) - return -ENODEV; - -+ mutex_lock(&mdev->open_mutex); - /* already used? */ - if (mdev->opened && mdev->devinfo != dp) { -- snd_use_lock_free(&mdev->use_lock); -- return -EBUSY; -+ err = -EBUSY; -+ goto unlock; - } - - perm = 0; -@@ -340,14 +344,14 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode) - perm |= PERM_READ; - perm &= mdev->flags; - if (perm == 0) { -- snd_use_lock_free(&mdev->use_lock); -- return -ENXIO; -+ err = -ENXIO; -+ goto unlock; - } - - /* already opened? */ - if ((mdev->opened & perm) == perm) { -- snd_use_lock_free(&mdev->use_lock); -- return 0; -+ err = 0; -+ goto unlock; - } - - perm &= ~mdev->opened; -@@ -372,13 +376,17 @@ snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode) - } - - if (! mdev->opened) { -- snd_use_lock_free(&mdev->use_lock); -- return -ENXIO; -+ err = -ENXIO; -+ goto unlock; - } - - mdev->devinfo = dp; -+ err = 0; -+ -+ unlock: -+ mutex_unlock(&mdev->open_mutex); - snd_use_lock_free(&mdev->use_lock); -- return 0; -+ return err; - } - - /* -@@ -393,10 +401,9 @@ snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev) - mdev = get_mididev(dp, dev); - if (!mdev) - return -ENODEV; -- if (! mdev->opened || mdev->devinfo != dp) { -- snd_use_lock_free(&mdev->use_lock); -- return 0; -- } -+ mutex_lock(&mdev->open_mutex); -+ if (!mdev->opened || mdev->devinfo != dp) -+ goto unlock; - - memset(&subs, 0, sizeof(subs)); - if (mdev->opened & PERM_WRITE) { -@@ -415,6 +422,8 @@ snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev) - mdev->opened = 0; - mdev->devinfo = NULL; - -+ unlock: -+ mutex_unlock(&mdev->open_mutex); - snd_use_lock_free(&mdev->use_lock); - return 0; - } -diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c -index 534ea7a256ec3..606b318f34e56 100644 ---- a/sound/pci/ac97/ac97_codec.c -+++ b/sound/pci/ac97/ac97_codec.c -@@ -2070,10 +2070,9 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, - .dev_disconnect = snd_ac97_dev_disconnect, - }; - -- if (!rac97) -- return -EINVAL; -- if (snd_BUG_ON(!bus || !template)) -+ if (snd_BUG_ON(!bus || !template || !rac97)) - return -EINVAL; -+ *rac97 = NULL; - if (snd_BUG_ON(template->num >= 4)) - return -EINVAL; - if (bus->codec[template->num]) -diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c -index 0ba1fbcbb21e4..627899959ffe8 100644 ---- a/sound/pci/hda/patch_cs8409.c -+++ b/sound/pci/hda/patch_cs8409.c -@@ -888,7 +888,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42) - - /* Initialize CS42L42 companion codec */ - cs8409_i2c_bulk_write(cs42l42, cs42l42->init_seq, cs42l42->init_seq_num); -- usleep_range(30000, 35000); -+ msleep(CS42L42_INIT_TIMEOUT_MS); - - /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); -diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h -index 2a8dfb4ff046b..937e9387abdc7 100644 ---- a/sound/pci/hda/patch_cs8409.h -+++ b/sound/pci/hda/patch_cs8409.h -@@ -229,6 +229,7 @@ enum cs8409_coefficient_index_registers { - #define CS42L42_I2C_SLEEP_US (2000) - #define CS42L42_PDN_TIMEOUT_US (250000) - #define CS42L42_PDN_SLEEP_US (2000) -+#define CS42L42_INIT_TIMEOUT_MS (45) - #define CS42L42_FULL_SCALE_VOL_MASK (2) - #define CS42L42_FULL_SCALE_VOL_0DB (1) - #define CS42L42_FULL_SCALE_VOL_MINUS6DB (0) -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index aa475154c582f..f70e0ad81607e 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9591,7 +9591,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8b8a, "HP", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b8b, "HP", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b8d, "HP", ALC236_FIXUP_HP_GPIO_LED), -- SND_PCI_QUIRK(0x103c, 0x8b8f, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8b8f, "HP", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8b97, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), -diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c -index 425d66edbf867..5e43ff0b537a3 100644 ---- a/sound/soc/atmel/atmel-i2s.c -+++ b/sound/soc/atmel/atmel-i2s.c -@@ -163,11 +163,14 @@ struct atmel_i2s_gck_param { - - #define I2S_MCK_12M288 12288000UL - #define I2S_MCK_11M2896 11289600UL -+#define I2S_MCK_6M144 6144000UL - - /* mck = (32 * (imckfs+1) / (imckdiv+1)) * fs */ - static const struct atmel_i2s_gck_param gck_params[] = { -+ /* mck = 6.144Mhz */ -+ { 8000, I2S_MCK_6M144, 1, 47}, /* mck = 768 fs */ -+ - /* mck = 12.288MHz */ -- { 8000, I2S_MCK_12M288, 0, 47}, /* mck = 1536 fs */ - { 16000, I2S_MCK_12M288, 1, 47}, /* mck = 768 fs */ - { 24000, I2S_MCK_12M288, 3, 63}, /* mck = 512 fs */ - { 32000, I2S_MCK_12M288, 3, 47}, /* mck = 384 fs */ -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 965ae55fa1607..0904827e2f3db 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -1552,6 +1552,7 @@ config SND_SOC_STA529 - config SND_SOC_STAC9766 - tristate - depends on SND_SOC_AC97_BUS -+ select REGMAP_AC97 - - config SND_SOC_STI_SAS - tristate "codec Audio support for STI SAS codec" -diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h -index 1dd8936743132..90e8895275e77 100644 ---- a/sound/soc/codecs/cs43130.h -+++ b/sound/soc/codecs/cs43130.h -@@ -381,88 +381,88 @@ struct cs43130_clk_gen { - - /* frm_size = 16 */ - static const struct cs43130_clk_gen cs43130_16_clk_gen[] = { -- { 22579200, 32000, .v = { 441, 10, }, }, -- { 22579200, 44100, .v = { 32, 1, }, }, -- { 22579200, 48000, .v = { 147, 5, }, }, -- { 22579200, 88200, .v = { 16, 1, }, }, -- { 22579200, 96000, .v = { 147, 10, }, }, -- { 22579200, 176400, .v = { 8, 1, }, }, -- { 22579200, 192000, .v = { 147, 20, }, }, -- { 22579200, 352800, .v = { 4, 1, }, }, -- { 22579200, 384000, .v = { 147, 40, }, }, -- { 24576000, 32000, .v = { 48, 1, }, }, -- { 24576000, 44100, .v = { 5120, 147, }, }, -- { 24576000, 48000, .v = { 32, 1, }, }, -- { 24576000, 88200, .v = { 2560, 147, }, }, -- { 24576000, 96000, .v = { 16, 1, }, }, -- { 24576000, 176400, .v = { 1280, 147, }, }, -- { 24576000, 192000, .v = { 8, 1, }, }, -- { 24576000, 352800, .v = { 640, 147, }, }, -- { 24576000, 384000, .v = { 4, 1, }, }, -+ { 22579200, 32000, .v = { 10, 441, }, }, -+ { 22579200, 44100, .v = { 1, 32, }, }, -+ { 22579200, 48000, .v = { 5, 147, }, }, -+ { 22579200, 88200, .v = { 1, 16, }, }, -+ { 22579200, 96000, .v = { 10, 147, }, }, -+ { 22579200, 176400, .v = { 1, 8, }, }, -+ { 22579200, 192000, .v = { 20, 147, }, }, -+ { 22579200, 352800, .v = { 1, 4, }, }, -+ { 22579200, 384000, .v = { 40, 147, }, }, -+ { 24576000, 32000, .v = { 1, 48, }, }, -+ { 24576000, 44100, .v = { 147, 5120, }, }, -+ { 24576000, 48000, .v = { 1, 32, }, }, -+ { 24576000, 88200, .v = { 147, 2560, }, }, -+ { 24576000, 96000, .v = { 1, 16, }, }, -+ { 24576000, 176400, .v = { 147, 1280, }, }, -+ { 24576000, 192000, .v = { 1, 8, }, }, -+ { 24576000, 352800, .v = { 147, 640, }, }, -+ { 24576000, 384000, .v = { 1, 4, }, }, - }; - - /* frm_size = 32 */ - static const struct cs43130_clk_gen cs43130_32_clk_gen[] = { -- { 22579200, 32000, .v = { 441, 20, }, }, -- { 22579200, 44100, .v = { 16, 1, }, }, -- { 22579200, 48000, .v = { 147, 10, }, }, -- { 22579200, 88200, .v = { 8, 1, }, }, -- { 22579200, 96000, .v = { 147, 20, }, }, -- { 22579200, 176400, .v = { 4, 1, }, }, -- { 22579200, 192000, .v = { 147, 40, }, }, -- { 22579200, 352800, .v = { 2, 1, }, }, -- { 22579200, 384000, .v = { 147, 80, }, }, -- { 24576000, 32000, .v = { 24, 1, }, }, -- { 24576000, 44100, .v = { 2560, 147, }, }, -- { 24576000, 48000, .v = { 16, 1, }, }, -- { 24576000, 88200, .v = { 1280, 147, }, }, -- { 24576000, 96000, .v = { 8, 1, }, }, -- { 24576000, 176400, .v = { 640, 147, }, }, -- { 24576000, 192000, .v = { 4, 1, }, }, -- { 24576000, 352800, .v = { 320, 147, }, }, -- { 24576000, 384000, .v = { 2, 1, }, }, -+ { 22579200, 32000, .v = { 20, 441, }, }, -+ { 22579200, 44100, .v = { 1, 16, }, }, -+ { 22579200, 48000, .v = { 10, 147, }, }, -+ { 22579200, 88200, .v = { 1, 8, }, }, -+ { 22579200, 96000, .v = { 20, 147, }, }, -+ { 22579200, 176400, .v = { 1, 4, }, }, -+ { 22579200, 192000, .v = { 40, 147, }, }, -+ { 22579200, 352800, .v = { 1, 2, }, }, -+ { 22579200, 384000, .v = { 80, 147, }, }, -+ { 24576000, 32000, .v = { 1, 24, }, }, -+ { 24576000, 44100, .v = { 147, 2560, }, }, -+ { 24576000, 48000, .v = { 1, 16, }, }, -+ { 24576000, 88200, .v = { 147, 1280, }, }, -+ { 24576000, 96000, .v = { 1, 8, }, }, -+ { 24576000, 176400, .v = { 147, 640, }, }, -+ { 24576000, 192000, .v = { 1, 4, }, }, -+ { 24576000, 352800, .v = { 147, 320, }, }, -+ { 24576000, 384000, .v = { 1, 2, }, }, - }; - - /* frm_size = 48 */ - static const struct cs43130_clk_gen cs43130_48_clk_gen[] = { -- { 22579200, 32000, .v = { 147, 100, }, }, -- { 22579200, 44100, .v = { 32, 3, }, }, -- { 22579200, 48000, .v = { 49, 5, }, }, -- { 22579200, 88200, .v = { 16, 3, }, }, -- { 22579200, 96000, .v = { 49, 10, }, }, -- { 22579200, 176400, .v = { 8, 3, }, }, -- { 22579200, 192000, .v = { 49, 20, }, }, -- { 22579200, 352800, .v = { 4, 3, }, }, -- { 22579200, 384000, .v = { 49, 40, }, }, -- { 24576000, 32000, .v = { 16, 1, }, }, -- { 24576000, 44100, .v = { 5120, 441, }, }, -- { 24576000, 48000, .v = { 32, 3, }, }, -- { 24576000, 88200, .v = { 2560, 441, }, }, -- { 24576000, 96000, .v = { 16, 3, }, }, -- { 24576000, 176400, .v = { 1280, 441, }, }, -- { 24576000, 192000, .v = { 8, 3, }, }, -- { 24576000, 352800, .v = { 640, 441, }, }, -- { 24576000, 384000, .v = { 4, 3, }, }, -+ { 22579200, 32000, .v = { 100, 147, }, }, -+ { 22579200, 44100, .v = { 3, 32, }, }, -+ { 22579200, 48000, .v = { 5, 49, }, }, -+ { 22579200, 88200, .v = { 3, 16, }, }, -+ { 22579200, 96000, .v = { 10, 49, }, }, -+ { 22579200, 176400, .v = { 3, 8, }, }, -+ { 22579200, 192000, .v = { 20, 49, }, }, -+ { 22579200, 352800, .v = { 3, 4, }, }, -+ { 22579200, 384000, .v = { 40, 49, }, }, -+ { 24576000, 32000, .v = { 1, 16, }, }, -+ { 24576000, 44100, .v = { 441, 5120, }, }, -+ { 24576000, 48000, .v = { 3, 32, }, }, -+ { 24576000, 88200, .v = { 441, 2560, }, }, -+ { 24576000, 96000, .v = { 3, 16, }, }, -+ { 24576000, 176400, .v = { 441, 1280, }, }, -+ { 24576000, 192000, .v = { 3, 8, }, }, -+ { 24576000, 352800, .v = { 441, 640, }, }, -+ { 24576000, 384000, .v = { 3, 4, }, }, - }; - - /* frm_size = 64 */ - static const struct cs43130_clk_gen cs43130_64_clk_gen[] = { -- { 22579200, 32000, .v = { 441, 40, }, }, -- { 22579200, 44100, .v = { 8, 1, }, }, -- { 22579200, 48000, .v = { 147, 20, }, }, -- { 22579200, 88200, .v = { 4, 1, }, }, -- { 22579200, 96000, .v = { 147, 40, }, }, -- { 22579200, 176400, .v = { 2, 1, }, }, -- { 22579200, 192000, .v = { 147, 80, }, }, -+ { 22579200, 32000, .v = { 40, 441, }, }, -+ { 22579200, 44100, .v = { 1, 8, }, }, -+ { 22579200, 48000, .v = { 20, 147, }, }, -+ { 22579200, 88200, .v = { 1, 4, }, }, -+ { 22579200, 96000, .v = { 40, 147, }, }, -+ { 22579200, 176400, .v = { 1, 2, }, }, -+ { 22579200, 192000, .v = { 80, 147, }, }, - { 22579200, 352800, .v = { 1, 1, }, }, -- { 24576000, 32000, .v = { 12, 1, }, }, -- { 24576000, 44100, .v = { 1280, 147, }, }, -- { 24576000, 48000, .v = { 8, 1, }, }, -- { 24576000, 88200, .v = { 640, 147, }, }, -- { 24576000, 96000, .v = { 4, 1, }, }, -- { 24576000, 176400, .v = { 320, 147, }, }, -- { 24576000, 192000, .v = { 2, 1, }, }, -- { 24576000, 352800, .v = { 160, 147, }, }, -+ { 24576000, 32000, .v = { 1, 12, }, }, -+ { 24576000, 44100, .v = { 147, 1280, }, }, -+ { 24576000, 48000, .v = { 1, 8, }, }, -+ { 24576000, 88200, .v = { 147, 640, }, }, -+ { 24576000, 96000, .v = { 1, 4, }, }, -+ { 24576000, 176400, .v = { 147, 320, }, }, -+ { 24576000, 192000, .v = { 1, 2, }, }, -+ { 24576000, 352800, .v = { 147, 160, }, }, - { 24576000, 384000, .v = { 1, 1, }, }, - }; - -diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c -index bba73c44c219f..9251490548e8c 100644 ---- a/sound/soc/codecs/da7219-aad.c -+++ b/sound/soc/codecs/da7219-aad.c -@@ -353,11 +353,15 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data) - struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); - u8 events[DA7219_AAD_IRQ_REG_MAX]; - u8 statusa; -- int i, report = 0, mask = 0; -+ int i, ret, report = 0, mask = 0; - - /* Read current IRQ events */ -- regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, -- events, DA7219_AAD_IRQ_REG_MAX); -+ ret = regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, -+ events, DA7219_AAD_IRQ_REG_MAX); -+ if (ret) { -+ dev_warn_ratelimited(component->dev, "Failed to read IRQ events: %d\n", ret); -+ return IRQ_NONE; -+ } - - if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B]) - return IRQ_NONE; -@@ -863,6 +867,8 @@ void da7219_aad_suspend(struct snd_soc_component *component) - } - } - } -+ -+ synchronize_irq(da7219_aad->irq); - } - - void da7219_aad_resume(struct snd_soc_component *component) -diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c -index 87775378362e7..c4e4ab93fdb6d 100644 ---- a/sound/soc/codecs/es8316.c -+++ b/sound/soc/codecs/es8316.c -@@ -153,7 +153,7 @@ static const char * const es8316_dmic_txt[] = { - "dmic data at high level", - "dmic data at low level", - }; --static const unsigned int es8316_dmic_values[] = { 0, 1, 2 }; -+static const unsigned int es8316_dmic_values[] = { 0, 2, 3 }; - static const struct soc_enum es8316_dmic_src_enum = - SOC_VALUE_ENUM_SINGLE(ES8316_ADC_DMIC, 0, 3, - ARRAY_SIZE(es8316_dmic_txt), -diff --git a/sound/soc/codecs/nau8821.c b/sound/soc/codecs/nau8821.c -index 4a72b94e84104..efd92656a060d 100644 ---- a/sound/soc/codecs/nau8821.c -+++ b/sound/soc/codecs/nau8821.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -25,6 +26,13 @@ - #include - #include "nau8821.h" - -+#define NAU8821_JD_ACTIVE_HIGH BIT(0) -+ -+static int nau8821_quirk; -+static int quirk_override = -1; -+module_param_named(quirk, quirk_override, uint, 0444); -+MODULE_PARM_DESC(quirk, "Board-specific quirk override"); -+ - #define NAU_FREF_MAX 13500000 - #define NAU_FVCO_MAX 100000000 - #define NAU_FVCO_MIN 90000000 -@@ -1696,6 +1704,33 @@ static int nau8821_setup_irq(struct nau8821 *nau8821) - return 0; - } - -+/* Please keep this list alphabetically sorted */ -+static const struct dmi_system_id nau8821_quirk_table[] = { -+ { -+ /* Positivo CW14Q01P-V2 */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"), -+ DMI_MATCH(DMI_BOARD_NAME, "CW14Q01P-V2"), -+ }, -+ .driver_data = (void *)(NAU8821_JD_ACTIVE_HIGH), -+ }, -+ {} -+}; -+ -+static void nau8821_check_quirks(void) -+{ -+ const struct dmi_system_id *dmi_id; -+ -+ if (quirk_override != -1) { -+ nau8821_quirk = quirk_override; -+ return; -+ } -+ -+ dmi_id = dmi_first_match(nau8821_quirk_table); -+ if (dmi_id) -+ nau8821_quirk = (unsigned long)dmi_id->driver_data; -+} -+ - static int nau8821_i2c_probe(struct i2c_client *i2c) - { - struct device *dev = &i2c->dev; -@@ -1716,6 +1751,12 @@ static int nau8821_i2c_probe(struct i2c_client *i2c) - - nau8821->dev = dev; - nau8821->irq = i2c->irq; -+ -+ nau8821_check_quirks(); -+ -+ if (nau8821_quirk & NAU8821_JD_ACTIVE_HIGH) -+ nau8821->jkdet_polarity = 0; -+ - nau8821_print_device_properties(nau8821); - - nau8821_reset_chip(nau8821->regmap); -diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c -index c1a94229dc7e3..868a61c8b0608 100644 ---- a/sound/soc/codecs/rt5682-sdw.c -+++ b/sound/soc/codecs/rt5682-sdw.c -@@ -786,8 +786,15 @@ static int __maybe_unused rt5682_dev_resume(struct device *dev) - if (!rt5682->first_hw_init) - return 0; - -- if (!slave->unattach_request) -+ if (!slave->unattach_request) { -+ if (rt5682->disable_irq == true) { -+ mutex_lock(&rt5682->disable_irq_lock); -+ sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF); -+ rt5682->disable_irq = false; -+ mutex_unlock(&rt5682->disable_irq_lock); -+ } - goto regmap_sync; -+ } - - time = wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(RT5682_PROBE_TIMEOUT)); -diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c -index e23cec4c457de..487d3010ddc19 100644 ---- a/sound/soc/codecs/rt711-sdca-sdw.c -+++ b/sound/soc/codecs/rt711-sdca-sdw.c -@@ -442,8 +442,16 @@ static int __maybe_unused rt711_sdca_dev_resume(struct device *dev) - if (!rt711->first_hw_init) - return 0; - -- if (!slave->unattach_request) -+ if (!slave->unattach_request) { -+ if (rt711->disable_irq == true) { -+ mutex_lock(&rt711->disable_irq_lock); -+ sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK1, SDW_SCP_SDCA_INTMASK_SDCA_0); -+ sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK2, SDW_SCP_SDCA_INTMASK_SDCA_8); -+ rt711->disable_irq = false; -+ mutex_unlock(&rt711->disable_irq_lock); -+ } - goto regmap_sync; -+ } - - time = wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(RT711_PROBE_TIMEOUT)); -diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c -index 4fe68bcf2a7c2..9545b8a7eb192 100644 ---- a/sound/soc/codecs/rt711-sdw.c -+++ b/sound/soc/codecs/rt711-sdw.c -@@ -541,8 +541,15 @@ static int __maybe_unused rt711_dev_resume(struct device *dev) - if (!rt711->first_hw_init) - return 0; - -- if (!slave->unattach_request) -+ if (!slave->unattach_request) { -+ if (rt711->disable_irq == true) { -+ mutex_lock(&rt711->disable_irq_lock); -+ sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF); -+ rt711->disable_irq = false; -+ mutex_unlock(&rt711->disable_irq_lock); -+ } - goto regmap_sync; -+ } - - time = wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(RT711_PROBE_TIMEOUT)); -diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c -index 8afd67ba1e5a3..f8d2372a758f4 100644 ---- a/sound/soc/sof/amd/acp.c -+++ b/sound/soc/sof/amd/acp.c -@@ -349,9 +349,9 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id) - unsigned int val; - - val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET); -- if (val) { -- val |= ACP_DSP_TO_HOST_IRQ; -- snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET, val); -+ if (val & ACP_DSP_TO_HOST_IRQ) { -+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET, -+ ACP_DSP_TO_HOST_IRQ); - return IRQ_WAKE_THREAD; - } - -diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c -index f4bd1e8ae4b6c..23260aa1919d3 100644 ---- a/sound/usb/mixer_maps.c -+++ b/sound/usb/mixer_maps.c -@@ -374,6 +374,15 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = { - { 0 } - }; - -+/* Microsoft USB Link headset */ -+/* a guess work: raw playback volume values are from 2 to 129 */ -+static const struct usbmix_dB_map ms_usb_link_dB = { -3225, 0, true }; -+static const struct usbmix_name_map ms_usb_link_map[] = { -+ { 9, NULL, .dB = &ms_usb_link_dB }, -+ { 10, NULL }, /* Headset Capture volume; seems non-working, disabled */ -+ { 0 } /* terminator */ -+}; -+ - /* ASUS ROG Zenith II with Realtek ALC1220-VB */ - static const struct usbmix_name_map asus_zenith_ii_map[] = { - { 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */ -@@ -668,6 +677,11 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { - .id = USB_ID(0x1395, 0x0025), - .map = sennheiser_pc8_map, - }, -+ { -+ /* Microsoft USB Link headset */ -+ .id = USB_ID(0x045e, 0x083c), -+ .map = ms_usb_link_map, -+ }, - { 0 } /* terminator */ - }; - -diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c -index 6cf55b7f7a041..4667d543f7481 100644 ---- a/sound/usb/quirks.c -+++ b/sound/usb/quirks.c -@@ -1874,8 +1874,10 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, - - /* XMOS based USB DACs */ - switch (chip->usb_id) { -- case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */ -- case USB_ID(0x21ed, 0xd75a): /* Accuphase DAC-60 option card */ -+ case USB_ID(0x139f, 0x5504): /* Nagra DAC */ -+ case USB_ID(0x20b1, 0x3089): /* Mola-Mola DAC */ -+ case USB_ID(0x2522, 0x0007): /* LH Labs Geek Out 1V5 */ -+ case USB_ID(0x2522, 0x0009): /* LH Labs Geek Pulse X Inifinity 2V0 */ - case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */ - case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ - if (fp->altsetting == 2) -@@ -1885,14 +1887,18 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, - case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ - case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */ - case USB_ID(0x16d0, 0x06b2): /* NuPrime DAC-10 */ -- case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ -+ case USB_ID(0x16d0, 0x06b4): /* NuPrime Audio HD-AVP/AVA */ - case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */ -+ case USB_ID(0x16d0, 0x09d8): /* NuPrime IDA-8 */ - case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ -+ case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ - case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */ -+ case USB_ID(0x20a0, 0x4143): /* WaveIO USB Audio 2.0 */ - case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */ - case USB_ID(0x249c, 0x9326): /* M2Tech Young MkIII */ - case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */ - case USB_ID(0x2622, 0x0041): /* Audiolab M-DAC+ */ -+ case USB_ID(0x278b, 0x5100): /* Rotel RC-1590 */ - case USB_ID(0x27f7, 0x3002): /* W4S DAC-2v2SE */ - case USB_ID(0x29a2, 0x0086): /* Mutec MC3+ USB */ - case USB_ID(0x6b42, 0x0042): /* MSB Technology */ -@@ -1902,9 +1908,6 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, - - /* Amanero Combo384 USB based DACs with native DSD support */ - case USB_ID(0x16d0, 0x071a): /* Amanero - Combo384 */ -- case USB_ID(0x2ab6, 0x0004): /* T+A DAC8DSD-V2.0, MP1000E-V2.0, MP2000R-V2.0, MP2500R-V2.0, MP3100HV-V2.0 */ -- case USB_ID(0x2ab6, 0x0005): /* T+A USB HD Audio 1 */ -- case USB_ID(0x2ab6, 0x0006): /* T+A USB HD Audio 2 */ - if (fp->altsetting == 2) { - switch (le16_to_cpu(chip->dev->descriptor.bcdDevice)) { - case 0x199: -@@ -2011,6 +2014,9 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_IGNORE_CTL_ERROR), - DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */ - QUIRK_FLAG_GET_SAMPLE_RATE), -+ DEVICE_FLG(0x045e, 0x083c, /* MS USB Link headset */ -+ QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY | -+ QUIRK_FLAG_DISABLE_AUTOSUSPEND), - DEVICE_FLG(0x046d, 0x084c, /* Logitech ConferenceCam Connect */ - QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY_1M), - DEVICE_FLG(0x046d, 0x0991, /* Logitech QuickCam Pro */ -@@ -2046,6 +2052,9 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_IFACE_DELAY), - DEVICE_FLG(0x0644, 0x805f, /* TEAC Model 12 */ - QUIRK_FLAG_FORCE_IFACE_RESET), -+ DEVICE_FLG(0x0644, 0x806b, /* TEAC UD-701 */ -+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | -+ QUIRK_FLAG_IFACE_DELAY), - DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */ - QUIRK_FLAG_IGNORE_CTL_ERROR), - DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */ -@@ -2084,6 +2093,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), - DEVICE_FLG(0x154e, 0x3006, /* Marantz SA-14S1 */ - QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), -+ DEVICE_FLG(0x154e, 0x300b, /* Marantz SA-KI RUBY / SA-12 */ -+ QUIRK_FLAG_DSD_RAW), - DEVICE_FLG(0x154e, 0x500e, /* Denon DN-X1600 */ - QUIRK_FLAG_IGNORE_CLOCK_SOURCE), - DEVICE_FLG(0x1686, 0x00dd, /* Zoom R16/24 */ -@@ -2128,6 +2139,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), - DEVICE_FLG(0x21b4, 0x0081, /* AudioQuest DragonFly */ - QUIRK_FLAG_GET_SAMPLE_RATE), -+ DEVICE_FLG(0x21b4, 0x0230, /* Ayre QB-9 Twenty */ -+ QUIRK_FLAG_DSD_RAW), -+ DEVICE_FLG(0x21b4, 0x0232, /* Ayre QX-5 Twenty */ -+ QUIRK_FLAG_DSD_RAW), - DEVICE_FLG(0x2522, 0x0007, /* LH Labs Geek Out HD Audio 1V5 */ - QUIRK_FLAG_SET_IFACE_FIRST), - DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */ -@@ -2170,12 +2185,18 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_VALIDATE_RATES), - VENDOR_FLG(0x1235, /* Focusrite Novation */ - QUIRK_FLAG_VALIDATE_RATES), -+ VENDOR_FLG(0x1511, /* AURALiC */ -+ QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x152a, /* Thesycon devices */ - QUIRK_FLAG_DSD_RAW), -+ VENDOR_FLG(0x18d1, /* iBasso devices */ -+ QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x1de7, /* Phoenix Audio */ - QUIRK_FLAG_GET_SAMPLE_RATE), - VENDOR_FLG(0x20b1, /* XMOS based devices */ - QUIRK_FLAG_DSD_RAW), -+ VENDOR_FLG(0x21ed, /* Accuphase Laboratory */ -+ QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x22d9, /* Oppo */ - QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x23ba, /* Playback Design */ -@@ -2191,10 +2212,14 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x2ab6, /* T+A devices */ - QUIRK_FLAG_DSD_RAW), -+ VENDOR_FLG(0x2d87, /* Cayin device */ -+ QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x3336, /* HEM devices */ - QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x3353, /* Khadas devices */ - QUIRK_FLAG_DSD_RAW), -+ VENDOR_FLG(0x35f4, /* MSB Technology */ -+ QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x3842, /* EVGA */ - QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0xc502, /* HiBy devices */ -diff --git a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c -index eb05ea53afb12..26004f0c5a6ae 100644 ---- a/tools/bpf/bpftool/skeleton/pid_iter.bpf.c -+++ b/tools/bpf/bpftool/skeleton/pid_iter.bpf.c -@@ -15,6 +15,19 @@ enum bpf_obj_type { - BPF_OBJ_BTF, - }; - -+struct bpf_perf_link___local { -+ struct bpf_link link; -+ struct file *perf_file; -+} __attribute__((preserve_access_index)); -+ -+struct perf_event___local { -+ u64 bpf_cookie; -+} __attribute__((preserve_access_index)); -+ -+enum bpf_link_type___local { -+ BPF_LINK_TYPE_PERF_EVENT___local = 7, -+}; -+ - extern const void bpf_link_fops __ksym; - extern const void bpf_map_fops __ksym; - extern const void bpf_prog_fops __ksym; -@@ -41,10 +54,10 @@ static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type) - /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */ - static __u64 get_bpf_cookie(struct bpf_link *link) - { -- struct bpf_perf_link *perf_link; -- struct perf_event *event; -+ struct bpf_perf_link___local *perf_link; -+ struct perf_event___local *event; - -- perf_link = container_of(link, struct bpf_perf_link, link); -+ perf_link = container_of(link, struct bpf_perf_link___local, link); - event = BPF_CORE_READ(perf_link, perf_file, private_data); - return BPF_CORE_READ(event, bpf_cookie); - } -@@ -84,10 +97,13 @@ int iter(struct bpf_iter__task_file *ctx) - e.pid = task->tgid; - e.id = get_obj_id(file->private_data, obj_type); - -- if (obj_type == BPF_OBJ_LINK) { -+ if (obj_type == BPF_OBJ_LINK && -+ bpf_core_enum_value_exists(enum bpf_link_type___local, -+ BPF_LINK_TYPE_PERF_EVENT___local)) { - struct bpf_link *link = (struct bpf_link *) file->private_data; - -- if (BPF_CORE_READ(link, type) == BPF_LINK_TYPE_PERF_EVENT) { -+ if (link->type == bpf_core_enum_value(enum bpf_link_type___local, -+ BPF_LINK_TYPE_PERF_EVENT___local)) { - e.has_bpf_cookie = true; - e.bpf_cookie = get_bpf_cookie(link); - } -diff --git a/tools/bpf/bpftool/skeleton/profiler.bpf.c b/tools/bpf/bpftool/skeleton/profiler.bpf.c -index ce5b65e07ab10..2f80edc682f11 100644 ---- a/tools/bpf/bpftool/skeleton/profiler.bpf.c -+++ b/tools/bpf/bpftool/skeleton/profiler.bpf.c -@@ -4,6 +4,12 @@ - #include - #include - -+struct bpf_perf_event_value___local { -+ __u64 counter; -+ __u64 enabled; -+ __u64 running; -+} __attribute__((preserve_access_index)); -+ - /* map of perf event fds, num_cpu * num_metric entries */ - struct { - __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); -@@ -15,14 +21,14 @@ struct { - struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __uint(key_size, sizeof(u32)); -- __uint(value_size, sizeof(struct bpf_perf_event_value)); -+ __uint(value_size, sizeof(struct bpf_perf_event_value___local)); - } fentry_readings SEC(".maps"); - - /* accumulated readings */ - struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __uint(key_size, sizeof(u32)); -- __uint(value_size, sizeof(struct bpf_perf_event_value)); -+ __uint(value_size, sizeof(struct bpf_perf_event_value___local)); - } accum_readings SEC(".maps"); - - /* sample counts, one per cpu */ -@@ -39,7 +45,7 @@ const volatile __u32 num_metric = 1; - SEC("fentry/XXX") - int BPF_PROG(fentry_XXX) - { -- struct bpf_perf_event_value *ptrs[MAX_NUM_MATRICS]; -+ struct bpf_perf_event_value___local *ptrs[MAX_NUM_MATRICS]; - u32 key = bpf_get_smp_processor_id(); - u32 i; - -@@ -53,10 +59,10 @@ int BPF_PROG(fentry_XXX) - } - - for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) { -- struct bpf_perf_event_value reading; -+ struct bpf_perf_event_value___local reading; - int err; - -- err = bpf_perf_event_read_value(&events, key, &reading, -+ err = bpf_perf_event_read_value(&events, key, (void *)&reading, - sizeof(reading)); - if (err) - return 0; -@@ -68,14 +74,14 @@ int BPF_PROG(fentry_XXX) - } - - static inline void --fexit_update_maps(u32 id, struct bpf_perf_event_value *after) -+fexit_update_maps(u32 id, struct bpf_perf_event_value___local *after) - { -- struct bpf_perf_event_value *before, diff; -+ struct bpf_perf_event_value___local *before, diff; - - before = bpf_map_lookup_elem(&fentry_readings, &id); - /* only account samples with a valid fentry_reading */ - if (before && before->counter) { -- struct bpf_perf_event_value *accum; -+ struct bpf_perf_event_value___local *accum; - - diff.counter = after->counter - before->counter; - diff.enabled = after->enabled - before->enabled; -@@ -93,7 +99,7 @@ fexit_update_maps(u32 id, struct bpf_perf_event_value *after) - SEC("fexit/XXX") - int BPF_PROG(fexit_XXX) - { -- struct bpf_perf_event_value readings[MAX_NUM_MATRICS]; -+ struct bpf_perf_event_value___local readings[MAX_NUM_MATRICS]; - u32 cpu = bpf_get_smp_processor_id(); - u32 i, zero = 0; - int err; -@@ -102,7 +108,8 @@ int BPF_PROG(fexit_XXX) - /* read all events before updating the maps, to reduce error */ - for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) { - err = bpf_perf_event_read_value(&events, cpu + i * num_cpu, -- readings + i, sizeof(*readings)); -+ (void *)(readings + i), -+ sizeof(*readings)); - if (err) - return 0; - } -diff --git a/tools/bpf/resolve_btfids/Build b/tools/bpf/resolve_btfids/Build -index ae82da03f9bf9..077de3829c722 100644 ---- a/tools/bpf/resolve_btfids/Build -+++ b/tools/bpf/resolve_btfids/Build -@@ -1,3 +1,5 @@ -+hostprogs := resolve_btfids -+ - resolve_btfids-y += main.o - resolve_btfids-y += rbtree.o - resolve_btfids-y += zalloc.o -@@ -7,4 +9,4 @@ resolve_btfids-y += str_error_r.o - - $(OUTPUT)%.o: ../../lib/%.c FORCE - $(call rule_mkdir) -- $(call if_changed_dep,cc_o_c) -+ $(call if_changed_dep,host_cc_o_c) -diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile -index 19a3112e271ac..4b8079f294f65 100644 ---- a/tools/bpf/resolve_btfids/Makefile -+++ b/tools/bpf/resolve_btfids/Makefile -@@ -17,15 +17,15 @@ else - MAKEFLAGS=--no-print-directory - endif - --# always use the host compiler --AR = $(HOSTAR) --CC = $(HOSTCC) --LD = $(HOSTLD) --ARCH = $(HOSTARCH) -+# Overrides for the prepare step libraries. -+HOST_OVERRIDES := AR="$(HOSTAR)" CC="$(HOSTCC)" LD="$(HOSTLD)" ARCH="$(HOSTARCH)" \ -+ CROSS_COMPILE="" EXTRA_CFLAGS="$(HOSTCFLAGS)" -+ - RM ?= rm -+HOSTCC ?= gcc -+HOSTLD ?= ld -+HOSTAR ?= ar - CROSS_COMPILE = --CFLAGS := $(KBUILD_HOSTCFLAGS) --LDFLAGS := $(KBUILD_HOSTLDFLAGS) - - OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/ - -@@ -35,51 +35,64 @@ SUBCMD_SRC := $(srctree)/tools/lib/subcmd/ - BPFOBJ := $(OUTPUT)/libbpf/libbpf.a - LIBBPF_OUT := $(abspath $(dir $(BPFOBJ)))/ - SUBCMDOBJ := $(OUTPUT)/libsubcmd/libsubcmd.a -+SUBCMD_OUT := $(abspath $(dir $(SUBCMDOBJ)))/ - - LIBBPF_DESTDIR := $(LIBBPF_OUT) - LIBBPF_INCLUDE := $(LIBBPF_DESTDIR)include - -+SUBCMD_DESTDIR := $(SUBCMD_OUT) -+SUBCMD_INCLUDE := $(SUBCMD_DESTDIR)include -+ - BINARY := $(OUTPUT)/resolve_btfids - BINARY_IN := $(BINARY)-in.o - - all: $(BINARY) - -+prepare: $(BPFOBJ) $(SUBCMDOBJ) -+ - $(OUTPUT) $(OUTPUT)/libsubcmd $(LIBBPF_OUT): - $(call msg,MKDIR,,$@) - $(Q)mkdir -p $(@) - - $(SUBCMDOBJ): fixdep FORCE | $(OUTPUT)/libsubcmd -- $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(abspath $(dir $@))/ $(abspath $@) -+ $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(SUBCMD_OUT) \ -+ DESTDIR=$(SUBCMD_DESTDIR) $(HOST_OVERRIDES) prefix= subdir= \ -+ $(abspath $@) install_headers - - $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUT) - $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(LIBBPF_OUT) \ -- DESTDIR=$(LIBBPF_DESTDIR) prefix= EXTRA_CFLAGS="$(CFLAGS)" \ -+ DESTDIR=$(LIBBPF_DESTDIR) $(HOST_OVERRIDES) prefix= subdir= \ - $(abspath $@) install_headers - --CFLAGS += -g \ -+LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null) -+LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf) -+ -+HOSTCFLAGS_resolve_btfids += -g \ - -I$(srctree)/tools/include \ - -I$(srctree)/tools/include/uapi \ - -I$(LIBBPF_INCLUDE) \ -- -I$(SUBCMD_SRC) -+ -I$(SUBCMD_INCLUDE) \ -+ $(LIBELF_FLAGS) - --LIBS = -lelf -lz -+LIBS = $(LIBELF_LIBS) -lz - --export srctree OUTPUT CFLAGS Q -+export srctree OUTPUT HOSTCFLAGS_resolve_btfids Q HOSTCC HOSTLD HOSTAR - include $(srctree)/tools/build/Makefile.include - --$(BINARY_IN): $(BPFOBJ) fixdep FORCE | $(OUTPUT) -+$(BINARY_IN): fixdep FORCE prepare | $(OUTPUT) - $(Q)$(MAKE) $(build)=resolve_btfids - - $(BINARY): $(BPFOBJ) $(SUBCMDOBJ) $(BINARY_IN) - $(call msg,LINK,$@) -- $(Q)$(CC) $(BINARY_IN) $(LDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS) -+ $(Q)$(HOSTCC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS) - - clean_objects := $(wildcard $(OUTPUT)/*.o \ - $(OUTPUT)/.*.o.cmd \ - $(OUTPUT)/.*.o.d \ - $(LIBBPF_OUT) \ - $(LIBBPF_DESTDIR) \ -- $(OUTPUT)/libsubcmd \ -+ $(SUBCMD_OUT) \ -+ $(SUBCMD_DESTDIR) \ - $(OUTPUT)/resolve_btfids) - - ifneq ($(clean_objects),) -@@ -96,4 +109,4 @@ tags: - - FORCE: - --.PHONY: all FORCE clean tags -+.PHONY: all FORCE clean tags prepare -diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c -index 80cd7843c6778..77058174082d7 100644 ---- a/tools/bpf/resolve_btfids/main.c -+++ b/tools/bpf/resolve_btfids/main.c -@@ -75,7 +75,7 @@ - #include - #include - #include --#include -+#include - - #define BTF_IDS_SECTION ".BTF_ids" - #define BTF_ID "__BTF_ID__" -diff --git a/tools/hv/vmbus_testing b/tools/hv/vmbus_testing -index e7212903dd1d9..4467979d8f699 100755 ---- a/tools/hv/vmbus_testing -+++ b/tools/hv/vmbus_testing -@@ -164,7 +164,7 @@ def recursive_file_lookup(path, file_map): - def get_all_devices_test_status(file_map): - - for device in file_map: -- if (get_test_state(locate_state(device, file_map)) is 1): -+ if (get_test_state(locate_state(device, file_map)) == 1): - print("Testing = ON for: {}" - .format(device.split("/")[5])) - else: -@@ -203,7 +203,7 @@ def write_test_files(path, value): - def set_test_state(state_path, state_value, quiet): - - write_test_files(state_path, state_value) -- if (get_test_state(state_path) is 1): -+ if (get_test_state(state_path) == 1): - if (not quiet): - print("Testing = ON for device: {}" - .format(state_path.split("/")[5])) -diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c -index b9a29d1053765..eeb2693128d8a 100644 ---- a/tools/lib/bpf/libbpf.c -+++ b/tools/lib/bpf/libbpf.c -@@ -6063,7 +6063,11 @@ static int append_subprog_relos(struct bpf_program *main_prog, struct bpf_progra - if (main_prog == subprog) - return 0; - relos = libbpf_reallocarray(main_prog->reloc_desc, new_cnt, sizeof(*relos)); -- if (!relos) -+ /* if new count is zero, reallocarray can return a valid NULL result; -+ * in this case the previous pointer will be freed, so we *have to* -+ * reassign old pointer to the new value (even if it's NULL) -+ */ -+ if (!relos && new_cnt) - return -ENOMEM; - if (subprog->nr_reloc) - memcpy(relos + main_prog->nr_reloc, subprog->reloc_desc, -@@ -8345,7 +8349,8 @@ int bpf_program__set_insns(struct bpf_program *prog, - return -EBUSY; - - insns = libbpf_reallocarray(prog->insns, new_insn_cnt, sizeof(*insns)); -- if (!insns) { -+ /* NULL is a valid return from reallocarray if the new count is zero */ -+ if (!insns && new_insn_cnt) { - pr_warn("prog '%s': failed to realloc prog code\n", prog->name); - return -ENOMEM; - } -@@ -8640,7 +8645,11 @@ int libbpf_unregister_prog_handler(int handler_id) - - /* try to shrink the array, but it's ok if we couldn't */ - sec_defs = libbpf_reallocarray(custom_sec_defs, custom_sec_def_cnt, sizeof(*sec_defs)); -- if (sec_defs) -+ /* if new count is zero, reallocarray can return a valid NULL result; -+ * in this case the previous pointer will be freed, so we *have to* -+ * reassign old pointer to the new value (even if it's NULL) -+ */ -+ if (sec_defs || custom_sec_def_cnt == 0) - custom_sec_defs = sec_defs; - - return 0; -diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c -index 49f3c3b7f6095..af1cb30556b46 100644 ---- a/tools/lib/bpf/usdt.c -+++ b/tools/lib/bpf/usdt.c -@@ -852,8 +852,11 @@ static int bpf_link_usdt_detach(struct bpf_link *link) - * system is so exhausted on memory, it's the least of user's - * concerns, probably. - * So just do our best here to return those IDs to usdt_manager. -+ * Another edge case when we can legitimately get NULL is when -+ * new_cnt is zero, which can happen in some edge cases, so we -+ * need to be careful about that. - */ -- if (new_free_ids) { -+ if (new_free_ids || new_cnt == 0) { - memcpy(new_free_ids + man->free_spec_cnt, usdt_link->spec_ids, - usdt_link->spec_cnt * sizeof(*usdt_link->spec_ids)); - man->free_spec_ids = new_free_ids; -diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile -index 8f1a09cdfd17e..b87213263a5e0 100644 ---- a/tools/lib/subcmd/Makefile -+++ b/tools/lib/subcmd/Makefile -@@ -17,6 +17,15 @@ RM = rm -f - - MAKEFLAGS += --no-print-directory - -+INSTALL = install -+ -+# Use DESTDIR for installing into a different root directory. -+# This is useful for building a package. The program will be -+# installed in this directory as if it was the root directory. -+# Then the build tool can move it later. -+DESTDIR ?= -+DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' -+ - LIBFILE = $(OUTPUT)libsubcmd.a - - CFLAGS := -ggdb3 -Wall -Wextra -std=gnu99 -fPIC -@@ -48,6 +57,18 @@ CFLAGS += $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) - - SUBCMD_IN := $(OUTPUT)libsubcmd-in.o - -+ifeq ($(LP64), 1) -+ libdir_relative = lib64 -+else -+ libdir_relative = lib -+endif -+ -+prefix ?= -+libdir = $(prefix)/$(libdir_relative) -+ -+# Shell quotes -+libdir_SQ = $(subst ','\'',$(libdir)) -+ - all: - - export srctree OUTPUT CC LD CFLAGS V -@@ -61,6 +82,37 @@ $(SUBCMD_IN): FORCE - $(LIBFILE): $(SUBCMD_IN) - $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(SUBCMD_IN) - -+define do_install_mkdir -+ if [ ! -d '$(DESTDIR_SQ)$1' ]; then \ -+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \ -+ fi -+endef -+ -+define do_install -+ if [ ! -d '$2' ]; then \ -+ $(INSTALL) -d -m 755 '$2'; \ -+ fi; \ -+ $(INSTALL) $1 $(if $3,-m $3,) '$2' -+endef -+ -+install_lib: $(LIBFILE) -+ $(call QUIET_INSTALL, $(LIBFILE)) \ -+ $(call do_install_mkdir,$(libdir_SQ)); \ -+ cp -fpR $(LIBFILE) $(DESTDIR)$(libdir_SQ) -+ -+HDRS := exec-cmd.h help.h pager.h parse-options.h run-command.h -+INSTALL_HDRS_PFX := $(DESTDIR)$(prefix)/include/subcmd -+INSTALL_HDRS := $(addprefix $(INSTALL_HDRS_PFX)/, $(HDRS)) -+ -+$(INSTALL_HDRS): $(INSTALL_HDRS_PFX)/%.h: %.h -+ $(call QUIET_INSTALL, $@) \ -+ $(call do_install,$<,$(INSTALL_HDRS_PFX)/,644) -+ -+install_headers: $(INSTALL_HDRS) -+ $(call QUIET_INSTALL, libsubcmd_headers) -+ -+install: install_lib install_headers -+ - clean: - $(call QUIET_CLEAN, libsubcmd) $(RM) $(LIBFILE); \ - find $(or $(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM) -diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c -index e00520cc63498..cffaf2245d4f1 100644 ---- a/tools/testing/radix-tree/multiorder.c -+++ b/tools/testing/radix-tree/multiorder.c -@@ -159,7 +159,7 @@ void multiorder_tagged_iteration(struct xarray *xa) - item_kill_tree(xa); - } - --bool stop_iteration = false; -+bool stop_iteration; - - static void *creator_func(void *ptr) - { -@@ -201,6 +201,7 @@ static void multiorder_iteration_race(struct xarray *xa) - pthread_t worker_thread[num_threads]; - int i; - -+ stop_iteration = false; - pthread_create(&worker_thread[0], NULL, &creator_func, xa); - for (i = 1; i < num_threads; i++) - pthread_create(&worker_thread[i], NULL, &iterator_func, xa); -@@ -211,6 +212,61 @@ static void multiorder_iteration_race(struct xarray *xa) - item_kill_tree(xa); - } - -+static void *load_creator(void *ptr) -+{ -+ /* 'order' is set up to ensure we have sibling entries */ -+ unsigned int order; -+ struct radix_tree_root *tree = ptr; -+ int i; -+ -+ rcu_register_thread(); -+ item_insert_order(tree, 3 << RADIX_TREE_MAP_SHIFT, 0); -+ item_insert_order(tree, 2 << RADIX_TREE_MAP_SHIFT, 0); -+ for (i = 0; i < 10000; i++) { -+ for (order = 1; order < RADIX_TREE_MAP_SHIFT; order++) { -+ unsigned long index = (3 << RADIX_TREE_MAP_SHIFT) - -+ (1 << order); -+ item_insert_order(tree, index, order); -+ item_delete_rcu(tree, index); -+ } -+ } -+ rcu_unregister_thread(); -+ -+ stop_iteration = true; -+ return NULL; -+} -+ -+static void *load_worker(void *ptr) -+{ -+ unsigned long index = (3 << RADIX_TREE_MAP_SHIFT) - 1; -+ -+ rcu_register_thread(); -+ while (!stop_iteration) { -+ struct item *item = xa_load(ptr, index); -+ assert(!xa_is_internal(item)); -+ } -+ rcu_unregister_thread(); -+ -+ return NULL; -+} -+ -+static void load_race(struct xarray *xa) -+{ -+ const int num_threads = sysconf(_SC_NPROCESSORS_ONLN) * 4; -+ pthread_t worker_thread[num_threads]; -+ int i; -+ -+ stop_iteration = false; -+ pthread_create(&worker_thread[0], NULL, &load_creator, xa); -+ for (i = 1; i < num_threads; i++) -+ pthread_create(&worker_thread[i], NULL, &load_worker, xa); -+ -+ for (i = 0; i < num_threads; i++) -+ pthread_join(worker_thread[i], NULL); -+ -+ item_kill_tree(xa); -+} -+ - static DEFINE_XARRAY(array); - - void multiorder_checks(void) -@@ -218,12 +274,20 @@ void multiorder_checks(void) - multiorder_iteration(&array); - multiorder_tagged_iteration(&array); - multiorder_iteration_race(&array); -+ load_race(&array); - - radix_tree_cpu_dead(0); - } - --int __weak main(void) -+int __weak main(int argc, char **argv) - { -+ int opt; -+ -+ while ((opt = getopt(argc, argv, "ls:v")) != -1) { -+ if (opt == 'v') -+ test_verbose++; -+ } -+ - rcu_register_thread(); - radix_tree_init(); - multiorder_checks(); -diff --git a/tools/testing/selftests/bpf/benchs/run_bench_rename.sh b/tools/testing/selftests/bpf/benchs/run_bench_rename.sh -index 16f774b1cdbed..7b281dbe41656 100755 ---- a/tools/testing/selftests/bpf/benchs/run_bench_rename.sh -+++ b/tools/testing/selftests/bpf/benchs/run_bench_rename.sh -@@ -2,7 +2,7 @@ - - set -eufo pipefail - --for i in base kprobe kretprobe rawtp fentry fexit fmodret -+for i in base kprobe kretprobe rawtp fentry fexit - do - summary=$(sudo ./bench -w2 -d5 -a rename-$i | tail -n1 | cut -d'(' -f1 | cut -d' ' -f3-) - printf "%-10s: %s\n" $i "$summary" -diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c -index 8a838ea8bdf3b..b2998896f9f7b 100644 ---- a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c -+++ b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c -@@ -123,12 +123,13 @@ static void test_bpf_nf_ct(int mode) - ASSERT_EQ(skel->data->test_snat_addr, 0, "Test for source natting"); - ASSERT_EQ(skel->data->test_dnat_addr, 0, "Test for destination natting"); - end: -- if (srv_client_fd != -1) -- close(srv_client_fd); - if (client_fd != -1) - close(client_fd); -+ if (srv_client_fd != -1) -+ close(srv_client_fd); - if (srv_fd != -1) - close(srv_fd); -+ - snprintf(cmd, sizeof(cmd), iptables, "-D"); - system(cmd); - test_bpf_nf__destroy(skel); -diff --git a/tools/testing/selftests/bpf/prog_tests/kfunc_call.c b/tools/testing/selftests/bpf/prog_tests/kfunc_call.c -index 5af1ee8f0e6ee..36071f3f15ba1 100644 ---- a/tools/testing/selftests/bpf/prog_tests/kfunc_call.c -+++ b/tools/testing/selftests/bpf/prog_tests/kfunc_call.c -@@ -171,8 +171,8 @@ static void verify_fail(struct kfunc_test_params *param) - case tc_test: - topts.data_in = &pkt_v4; - topts.data_size_in = sizeof(pkt_v4); -- break; - topts.repeat = 1; -+ break; - } - - skel = kfunc_call_fail__open_opts(&opts); -diff --git a/tools/testing/selftests/bpf/progs/test_cls_redirect.h b/tools/testing/selftests/bpf/progs/test_cls_redirect.h -index 76eab0aacba0c..233b089d1fbac 100644 ---- a/tools/testing/selftests/bpf/progs/test_cls_redirect.h -+++ b/tools/testing/selftests/bpf/progs/test_cls_redirect.h -@@ -12,6 +12,15 @@ - #include - #include - -+/* offsetof() is used in static asserts, and the libbpf-redefined CO-RE -+ * friendly version breaks compilation for older clang versions <= 15 -+ * when invoked in a static assert. Restore original here. -+ */ -+#ifdef offsetof -+#undef offsetof -+#define offsetof(type, member) __builtin_offsetof(type, member) -+#endif -+ - struct gre_base_hdr { - uint16_t flags; - uint16_t protocol; -diff --git a/tools/testing/selftests/futex/functional/futex_wait_timeout.c b/tools/testing/selftests/futex/functional/futex_wait_timeout.c -index 3651ce17beeb9..d183f878360bc 100644 ---- a/tools/testing/selftests/futex/functional/futex_wait_timeout.c -+++ b/tools/testing/selftests/futex/functional/futex_wait_timeout.c -@@ -24,6 +24,7 @@ - - static long timeout_ns = 100000; /* 100us default timeout */ - static futex_t futex_pi; -+static pthread_barrier_t barrier; - - void usage(char *prog) - { -@@ -48,6 +49,8 @@ void *get_pi_lock(void *arg) - if (ret != 0) - error("futex_lock_pi failed\n", ret); - -+ pthread_barrier_wait(&barrier); -+ - /* Blocks forever */ - ret = futex_wait(&lock, 0, NULL, 0); - error("futex_wait failed\n", ret); -@@ -130,6 +133,7 @@ int main(int argc, char *argv[]) - basename(argv[0])); - ksft_print_msg("\tArguments: timeout=%ldns\n", timeout_ns); - -+ pthread_barrier_init(&barrier, NULL, 2); - pthread_create(&thread, NULL, get_pi_lock, NULL); - - /* initialize relative timeout */ -@@ -163,6 +167,9 @@ int main(int argc, char *argv[]) - res = futex_wait_requeue_pi(&f1, f1, &futex_pi, &to, 0); - test_timeout(res, &ret, "futex_wait_requeue_pi monotonic", ETIMEDOUT); - -+ /* Wait until the other thread calls futex_lock_pi() */ -+ pthread_barrier_wait(&barrier); -+ pthread_barrier_destroy(&barrier); - /* - * FUTEX_LOCK_PI with CLOCK_REALTIME - * Due to historical reasons, FUTEX_LOCK_PI supports only realtime -diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h -index 25f4d54067c0e..584687c3286dd 100644 ---- a/tools/testing/selftests/kselftest_harness.h -+++ b/tools/testing/selftests/kselftest_harness.h -@@ -937,7 +937,11 @@ void __wait_for_test(struct __test_metadata *t) - fprintf(TH_LOG_STREAM, - "# %s: Test terminated by timeout\n", t->name); - } else if (WIFEXITED(status)) { -- if (t->termsig != -1) { -+ if (WEXITSTATUS(status) == 255) { -+ /* SKIP */ -+ t->passed = 1; -+ t->skip = 1; -+ } else if (t->termsig != -1) { - t->passed = 0; - fprintf(TH_LOG_STREAM, - "# %s: Test exited normally instead of by signal (code: %d)\n", -@@ -949,11 +953,6 @@ void __wait_for_test(struct __test_metadata *t) - case 0: - t->passed = 1; - break; -- /* SKIP */ -- case 255: -- t->passed = 1; -- t->skip = 1; -- break; - /* Other failure, assume step report. */ - default: - t->passed = 0; -diff --git a/tools/testing/selftests/resctrl/Makefile b/tools/testing/selftests/resctrl/Makefile -index 73d53257df42f..5073dbc961258 100644 ---- a/tools/testing/selftests/resctrl/Makefile -+++ b/tools/testing/selftests/resctrl/Makefile -@@ -7,4 +7,4 @@ TEST_GEN_PROGS := resctrl_tests - - include ../lib.mk - --$(OUTPUT)/resctrl_tests: $(wildcard *.c) -+$(OUTPUT)/resctrl_tests: $(wildcard *.[ch]) -diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c -index 0485863a169f2..338f714453935 100644 ---- a/tools/testing/selftests/resctrl/cache.c -+++ b/tools/testing/selftests/resctrl/cache.c -@@ -89,21 +89,19 @@ static int reset_enable_llc_perf(pid_t pid, int cpu_no) - static int get_llc_perf(unsigned long *llc_perf_miss) - { - __u64 total_misses; -+ int ret; - - /* Stop counters after one span to get miss rate */ - - ioctl(fd_lm, PERF_EVENT_IOC_DISABLE, 0); - -- if (read(fd_lm, &rf_cqm, sizeof(struct read_format)) == -1) { -+ ret = read(fd_lm, &rf_cqm, sizeof(struct read_format)); -+ if (ret == -1) { - perror("Could not get llc misses through perf"); -- - return -1; - } - - total_misses = rf_cqm.values[0].value; -- -- close(fd_lm); -- - *llc_perf_miss = total_misses; - - return 0; -@@ -258,19 +256,25 @@ int cat_val(struct resctrl_val_param *param) - memflush, operation, resctrl_val)) { - fprintf(stderr, "Error-running fill buffer\n"); - ret = -1; -- break; -+ goto pe_close; - } - - sleep(1); - ret = measure_cache_vals(param, bm_pid); - if (ret) -- break; -+ goto pe_close; -+ -+ close(fd_lm); - } else { - break; - } - } - - return ret; -+ -+pe_close: -+ close(fd_lm); -+ return ret; - } - - /* -diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c -index c20d0a7ecbe63..ab1d91328d67b 100644 ---- a/tools/testing/selftests/resctrl/fill_buf.c -+++ b/tools/testing/selftests/resctrl/fill_buf.c -@@ -184,12 +184,13 @@ fill_cache(unsigned long long buf_size, int malloc_and_init, int memflush, - else - ret = fill_cache_write(start_ptr, end_ptr, resctrl_val); - -+ free(startptr); -+ - if (ret) { - printf("\n Error in fill cache read/write...\n"); - return -1; - } - -- free(startptr); - - return 0; - } -diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h -index f44fa2de4d986..dbe5cfb545585 100644 ---- a/tools/testing/selftests/resctrl/resctrl.h -+++ b/tools/testing/selftests/resctrl/resctrl.h -@@ -43,6 +43,7 @@ - do { \ - perror(err_msg); \ - kill(ppid, SIGKILL); \ -+ umount_resctrlfs(); \ - exit(EXIT_FAILURE); \ - } while (0) - -diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c -index 9584eb57e0eda..365d30779768a 100644 ---- a/virt/kvm/vfio.c -+++ b/virt/kvm/vfio.c -@@ -21,7 +21,7 @@ - #include - #endif - --struct kvm_vfio_group { -+struct kvm_vfio_file { - struct list_head node; - struct file *file; - #ifdef CONFIG_SPAPR_TCE_IOMMU -@@ -30,7 +30,7 @@ struct kvm_vfio_group { - }; - - struct kvm_vfio { -- struct list_head group_list; -+ struct list_head file_list; - struct mutex lock; - bool noncoherent; - }; -@@ -98,34 +98,35 @@ static struct iommu_group *kvm_vfio_file_iommu_group(struct file *file) - } - - static void kvm_spapr_tce_release_vfio_group(struct kvm *kvm, -- struct kvm_vfio_group *kvg) -+ struct kvm_vfio_file *kvf) - { -- if (WARN_ON_ONCE(!kvg->iommu_group)) -+ if (WARN_ON_ONCE(!kvf->iommu_group)) - return; - -- kvm_spapr_tce_release_iommu_group(kvm, kvg->iommu_group); -- iommu_group_put(kvg->iommu_group); -- kvg->iommu_group = NULL; -+ kvm_spapr_tce_release_iommu_group(kvm, kvf->iommu_group); -+ iommu_group_put(kvf->iommu_group); -+ kvf->iommu_group = NULL; - } - #endif - - /* -- * Groups can use the same or different IOMMU domains. If the same then -- * adding a new group may change the coherency of groups we've previously -- * been told about. We don't want to care about any of that so we retest -- * each group and bail as soon as we find one that's noncoherent. This -- * means we only ever [un]register_noncoherent_dma once for the whole device. -+ * Groups/devices can use the same or different IOMMU domains. If the same -+ * then adding a new group/device may change the coherency of groups/devices -+ * we've previously been told about. We don't want to care about any of -+ * that so we retest each group/device and bail as soon as we find one that's -+ * noncoherent. This means we only ever [un]register_noncoherent_dma once -+ * for the whole device. - */ - static void kvm_vfio_update_coherency(struct kvm_device *dev) - { - struct kvm_vfio *kv = dev->private; - bool noncoherent = false; -- struct kvm_vfio_group *kvg; -+ struct kvm_vfio_file *kvf; - - mutex_lock(&kv->lock); - -- list_for_each_entry(kvg, &kv->group_list, node) { -- if (!kvm_vfio_file_enforced_coherent(kvg->file)) { -+ list_for_each_entry(kvf, &kv->file_list, node) { -+ if (!kvm_vfio_file_enforced_coherent(kvf->file)) { - noncoherent = true; - break; - } -@@ -143,10 +144,10 @@ static void kvm_vfio_update_coherency(struct kvm_device *dev) - mutex_unlock(&kv->lock); - } - --static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd) -+static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd) - { - struct kvm_vfio *kv = dev->private; -- struct kvm_vfio_group *kvg; -+ struct kvm_vfio_file *kvf; - struct file *filp; - int ret; - -@@ -162,27 +163,27 @@ static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd) - - mutex_lock(&kv->lock); - -- list_for_each_entry(kvg, &kv->group_list, node) { -- if (kvg->file == filp) { -+ list_for_each_entry(kvf, &kv->file_list, node) { -+ if (kvf->file == filp) { - ret = -EEXIST; - goto err_unlock; - } - } - -- kvg = kzalloc(sizeof(*kvg), GFP_KERNEL_ACCOUNT); -- if (!kvg) { -+ kvf = kzalloc(sizeof(*kvf), GFP_KERNEL_ACCOUNT); -+ if (!kvf) { - ret = -ENOMEM; - goto err_unlock; - } - -- kvg->file = filp; -- list_add_tail(&kvg->node, &kv->group_list); -+ kvf->file = filp; -+ list_add_tail(&kvf->node, &kv->file_list); - - kvm_arch_start_assignment(dev->kvm); -+ kvm_vfio_file_set_kvm(kvf->file, dev->kvm); - - mutex_unlock(&kv->lock); - -- kvm_vfio_file_set_kvm(kvg->file, dev->kvm); - kvm_vfio_update_coherency(dev); - - return 0; -@@ -193,10 +194,10 @@ err_fput: - return ret; - } - --static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd) -+static int kvm_vfio_file_del(struct kvm_device *dev, unsigned int fd) - { - struct kvm_vfio *kv = dev->private; -- struct kvm_vfio_group *kvg; -+ struct kvm_vfio_file *kvf; - struct fd f; - int ret; - -@@ -208,18 +209,18 @@ static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd) - - mutex_lock(&kv->lock); - -- list_for_each_entry(kvg, &kv->group_list, node) { -- if (kvg->file != f.file) -+ list_for_each_entry(kvf, &kv->file_list, node) { -+ if (kvf->file != f.file) - continue; - -- list_del(&kvg->node); -+ list_del(&kvf->node); - kvm_arch_end_assignment(dev->kvm); - #ifdef CONFIG_SPAPR_TCE_IOMMU -- kvm_spapr_tce_release_vfio_group(dev->kvm, kvg); -+ kvm_spapr_tce_release_vfio_group(dev->kvm, kvf); - #endif -- kvm_vfio_file_set_kvm(kvg->file, NULL); -- fput(kvg->file); -- kfree(kvg); -+ kvm_vfio_file_set_kvm(kvf->file, NULL); -+ fput(kvf->file); -+ kfree(kvf); - ret = 0; - break; - } -@@ -234,12 +235,12 @@ static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd) - } - - #ifdef CONFIG_SPAPR_TCE_IOMMU --static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev, -- void __user *arg) -+static int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev, -+ void __user *arg) - { - struct kvm_vfio_spapr_tce param; - struct kvm_vfio *kv = dev->private; -- struct kvm_vfio_group *kvg; -+ struct kvm_vfio_file *kvf; - struct fd f; - int ret; - -@@ -254,20 +255,20 @@ static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev, - - mutex_lock(&kv->lock); - -- list_for_each_entry(kvg, &kv->group_list, node) { -- if (kvg->file != f.file) -+ list_for_each_entry(kvf, &kv->file_list, node) { -+ if (kvf->file != f.file) - continue; - -- if (!kvg->iommu_group) { -- kvg->iommu_group = kvm_vfio_file_iommu_group(kvg->file); -- if (WARN_ON_ONCE(!kvg->iommu_group)) { -+ if (!kvf->iommu_group) { -+ kvf->iommu_group = kvm_vfio_file_iommu_group(kvf->file); -+ if (WARN_ON_ONCE(!kvf->iommu_group)) { - ret = -EIO; - goto err_fdput; - } - } - - ret = kvm_spapr_tce_attach_iommu_group(dev->kvm, param.tablefd, -- kvg->iommu_group); -+ kvf->iommu_group); - break; - } - -@@ -278,8 +279,8 @@ err_fdput: - } - #endif - --static int kvm_vfio_set_group(struct kvm_device *dev, long attr, -- void __user *arg) -+static int kvm_vfio_set_file(struct kvm_device *dev, long attr, -+ void __user *arg) - { - int32_t __user *argp = arg; - int32_t fd; -@@ -288,16 +289,16 @@ static int kvm_vfio_set_group(struct kvm_device *dev, long attr, - case KVM_DEV_VFIO_GROUP_ADD: - if (get_user(fd, argp)) - return -EFAULT; -- return kvm_vfio_group_add(dev, fd); -+ return kvm_vfio_file_add(dev, fd); - - case KVM_DEV_VFIO_GROUP_DEL: - if (get_user(fd, argp)) - return -EFAULT; -- return kvm_vfio_group_del(dev, fd); -+ return kvm_vfio_file_del(dev, fd); - - #ifdef CONFIG_SPAPR_TCE_IOMMU - case KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE: -- return kvm_vfio_group_set_spapr_tce(dev, arg); -+ return kvm_vfio_file_set_spapr_tce(dev, arg); - #endif - } - -@@ -309,8 +310,8 @@ static int kvm_vfio_set_attr(struct kvm_device *dev, - { - switch (attr->group) { - case KVM_DEV_VFIO_GROUP: -- return kvm_vfio_set_group(dev, attr->attr, -- u64_to_user_ptr(attr->addr)); -+ return kvm_vfio_set_file(dev, attr->attr, -+ u64_to_user_ptr(attr->addr)); - } - - return -ENXIO; -@@ -339,16 +340,16 @@ static int kvm_vfio_has_attr(struct kvm_device *dev, - static void kvm_vfio_release(struct kvm_device *dev) - { - struct kvm_vfio *kv = dev->private; -- struct kvm_vfio_group *kvg, *tmp; -+ struct kvm_vfio_file *kvf, *tmp; - -- list_for_each_entry_safe(kvg, tmp, &kv->group_list, node) { -+ list_for_each_entry_safe(kvf, tmp, &kv->file_list, node) { - #ifdef CONFIG_SPAPR_TCE_IOMMU -- kvm_spapr_tce_release_vfio_group(dev->kvm, kvg); -+ kvm_spapr_tce_release_vfio_group(dev->kvm, kvf); - #endif -- kvm_vfio_file_set_kvm(kvg->file, NULL); -- fput(kvg->file); -- list_del(&kvg->node); -- kfree(kvg); -+ kvm_vfio_file_set_kvm(kvf->file, NULL); -+ fput(kvf->file); -+ list_del(&kvf->node); -+ kfree(kvf); - kvm_arch_end_assignment(dev->kvm); - } - -@@ -382,7 +383,7 @@ static int kvm_vfio_create(struct kvm_device *dev, u32 type) - if (!kv) - return -ENOMEM; - -- INIT_LIST_HEAD(&kv->group_list); -+ INIT_LIST_HEAD(&kv->file_list); - mutex_init(&kv->lock); - - dev->private = kv; diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.53-54.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.53-54.patch deleted file mode 100644 index 7f7a5319d6d1..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.53-54.patch +++ /dev/null @@ -1,9258 +0,0 @@ -diff --git a/Documentation/admin-guide/cgroup-v1/memory.rst b/Documentation/admin-guide/cgroup-v1/memory.rst -index 2524061836acc..34911ce5e4b50 100644 ---- a/Documentation/admin-guide/cgroup-v1/memory.rst -+++ b/Documentation/admin-guide/cgroup-v1/memory.rst -@@ -91,8 +91,6 @@ Brief summary of control files. - memory.oom_control set/show oom controls. - memory.numa_stat show the number of memory usage per numa - node -- memory.kmem.limit_in_bytes This knob is deprecated and writing to -- it will return -ENOTSUPP. - memory.kmem.usage_in_bytes show current kernel memory allocation - memory.kmem.failcnt show the number of kernel memory usage - hits limits -diff --git a/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml b/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml -index 229af98b1d305..7cd88bc3a67d7 100644 ---- a/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml -+++ b/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml -@@ -16,8 +16,6 @@ description: | - reads required input clock frequencies from the devicetree and acts as clock - provider for all clock consumers of PS clocks. - --select: false -- - properties: - compatible: - const: xlnx,versal-clk -diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst -index d7062c6a89464..d8f721f98868a 100644 ---- a/Documentation/mm/multigen_lru.rst -+++ b/Documentation/mm/multigen_lru.rst -@@ -89,15 +89,15 @@ variables are monotonically increasing. - - Generation numbers are truncated into ``order_base_2(MAX_NR_GENS+1)`` - bits in order to fit into the gen counter in ``folio->flags``. Each --truncated generation number is an index to ``lrugen->lists[]``. The -+truncated generation number is an index to ``lrugen->folios[]``. The - sliding window technique is used to track at least ``MIN_NR_GENS`` and - at most ``MAX_NR_GENS`` generations. The gen counter stores a value - within ``[1, MAX_NR_GENS]`` while a page is on one of --``lrugen->lists[]``; otherwise it stores zero. -+``lrugen->folios[]``; otherwise it stores zero. - - Each generation is divided into multiple tiers. A page accessed ``N`` - times through file descriptors is in tier ``order_base_2(N)``. Unlike --generations, tiers do not have dedicated ``lrugen->lists[]``. In -+generations, tiers do not have dedicated ``lrugen->folios[]``. In - contrast to moving across generations, which requires the LRU lock, - moving across tiers only involves atomic operations on - ``folio->flags`` and therefore has a negligible cost. A feedback loop -@@ -127,7 +127,7 @@ page mapped by this PTE to ``(max_seq%MAX_NR_GENS)+1``. - Eviction - -------- - The eviction consumes old generations. Given an ``lruvec``, it --increments ``min_seq`` when ``lrugen->lists[]`` indexed by -+increments ``min_seq`` when ``lrugen->folios[]`` indexed by - ``min_seq%MAX_NR_GENS`` becomes empty. To select a type and a tier to - evict from, it first compares ``min_seq[]`` to select the older type. - If both types are equally old, it selects the one whose first tier has -diff --git a/Makefile b/Makefile -index 35fc0d62898dc..844afa653fdda 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 53 -+SUBLEVEL = 54 - EXTRAVERSION = - NAME = Curry Ramen - -@@ -1939,7 +1939,9 @@ quiet_cmd_depmod = DEPMOD $(MODLIB) - - modules_install: - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst -+ifndef modules_sign_only - $(call cmd,depmod) -+endif - - else # CONFIG_MODULES - -diff --git a/arch/arc/include/asm/atomic-llsc.h b/arch/arc/include/asm/atomic-llsc.h -index 1b0ffaeee16d0..5258cb81a16b4 100644 ---- a/arch/arc/include/asm/atomic-llsc.h -+++ b/arch/arc/include/asm/atomic-llsc.h -@@ -18,7 +18,7 @@ static inline void arch_atomic_##op(int i, atomic_t *v) \ - : [val] "=&r" (val) /* Early clobber to prevent reg reuse */ \ - : [ctr] "r" (&v->counter), /* Not "m": llock only supports reg direct addr mode */ \ - [i] "ir" (i) \ -- : "cc"); \ -+ : "cc", "memory"); \ - } \ - - #define ATOMIC_OP_RETURN(op, asm_op) \ -@@ -34,7 +34,7 @@ static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \ - : [val] "=&r" (val) \ - : [ctr] "r" (&v->counter), \ - [i] "ir" (i) \ -- : "cc"); \ -+ : "cc", "memory"); \ - \ - return val; \ - } -@@ -56,7 +56,7 @@ static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \ - [orig] "=&r" (orig) \ - : [ctr] "r" (&v->counter), \ - [i] "ir" (i) \ -- : "cc"); \ -+ : "cc", "memory"); \ - \ - return orig; \ - } -diff --git a/arch/arc/include/asm/atomic64-arcv2.h b/arch/arc/include/asm/atomic64-arcv2.h -index c5a8010fdc97d..9089f34baac3b 100644 ---- a/arch/arc/include/asm/atomic64-arcv2.h -+++ b/arch/arc/include/asm/atomic64-arcv2.h -@@ -60,7 +60,7 @@ static inline void arch_atomic64_##op(s64 a, atomic64_t *v) \ - " bnz 1b \n" \ - : "=&r"(val) \ - : "r"(&v->counter), "ir"(a) \ -- : "cc"); \ -+ : "cc", "memory"); \ - } \ - - #define ATOMIC64_OP_RETURN(op, op1, op2) \ -@@ -77,7 +77,7 @@ static inline s64 arch_atomic64_##op##_return_relaxed(s64 a, atomic64_t *v) \ - " bnz 1b \n" \ - : [val] "=&r"(val) \ - : "r"(&v->counter), "ir"(a) \ -- : "cc"); /* memory clobber comes from smp_mb() */ \ -+ : "cc", "memory"); \ - \ - return val; \ - } -@@ -99,7 +99,7 @@ static inline s64 arch_atomic64_fetch_##op##_relaxed(s64 a, atomic64_t *v) \ - " bnz 1b \n" \ - : "=&r"(orig), "=&r"(val) \ - : "r"(&v->counter), "ir"(a) \ -- : "cc"); /* memory clobber comes from smp_mb() */ \ -+ : "cc", "memory"); \ - \ - return orig; \ - } -diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi -index c4faff0923800..fee53c25fc808 100644 ---- a/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi -+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi -@@ -100,7 +100,7 @@ - rxc-skew-psec = <2400>; - txc-skew-psec = <2400>; - rxdv-skew-psec = <0>; -- txdv-skew-psec = <0>; -+ txen-skew-psec = <0>; - rxd0-skew-psec = <0>; - rxd1-skew-psec = <0>; - rxd2-skew-psec = <0>; -@@ -128,7 +128,7 @@ - rxc-skew-psec = <2400>; - txc-skew-psec = <2400>; - rxdv-skew-psec = <0>; -- txdv-skew-psec = <0>; -+ txen-skew-psec = <0>; - rxd0-skew-psec = <0>; - rxd1-skew-psec = <0>; - rxd2-skew-psec = <0>; -diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi -index 78e6e2376b015..5ff66aa6f8ba4 100644 ---- a/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi -+++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi -@@ -77,7 +77,7 @@ - rxc-skew-psec = <2400>; - txc-skew-psec = <2400>; - rxdv-skew-psec = <0>; -- txdv-skew-psec = <0>; -+ txen-skew-psec = <0>; - rxd0-skew-psec = <0>; - rxd1-skew-psec = <0>; - rxd2-skew-psec = <0>; -diff --git a/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi -index 2a0feb53f0dcb..b62973bc2f0dd 100644 ---- a/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi -+++ b/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi -@@ -80,7 +80,7 @@ - rxc-skew-psec = <2400>; - txc-skew-psec = <2400>; - rxdv-skew-psec = <0>; -- txdv-skew-psec = <0>; -+ txen-skew-psec = <0>; - rxd0-skew-psec = <0>; - rxd1-skew-psec = <0>; - rxd2-skew-psec = <0>; -@@ -107,7 +107,7 @@ - rxc-skew-psec = <2400>; - txc-skew-psec = <2400>; - rxdv-skew-psec = <0>; -- txdv-skew-psec = <0>; -+ txen-skew-psec = <0>; - rxd0-skew-psec = <0>; - rxd1-skew-psec = <0>; - rxd2-skew-psec = <0>; -diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c -index 14134fd34ff79..0ce5f13eabb1b 100644 ---- a/arch/arm64/net/bpf_jit_comp.c -+++ b/arch/arm64/net/bpf_jit_comp.c -@@ -1655,13 +1655,8 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l, - struct bpf_prog *p = l->link.prog; - int cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie); - -- if (p->aux->sleepable) { -- enter_prog = (u64)__bpf_prog_enter_sleepable; -- exit_prog = (u64)__bpf_prog_exit_sleepable; -- } else { -- enter_prog = (u64)__bpf_prog_enter; -- exit_prog = (u64)__bpf_prog_exit; -- } -+ enter_prog = (u64)bpf_trampoline_enter(p); -+ exit_prog = (u64)bpf_trampoline_exit(p); - - if (l->cookie == 0) { - /* if cookie is zero, one instruction is enough to store it */ -diff --git a/arch/mips/Makefile b/arch/mips/Makefile -index fe64ad43ba882..ee8f47aef98b3 100644 ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -308,8 +308,8 @@ ifdef CONFIG_64BIT - endif - endif - -- ifeq ($(KBUILD_SYM32)$(call cc-option-yn,-msym32), yy) -- cflags-y += -msym32 -DKBUILD_64BIT_SYM32 -+ ifeq ($(KBUILD_SYM32), y) -+ cflags-$(KBUILD_SYM32) += -msym32 -DKBUILD_64BIT_SYM32 - else - ifeq ($(CONFIG_CPU_DADDI_WORKAROUNDS), y) - $(error CONFIG_CPU_DADDI_WORKAROUNDS unsupported without -msym32) -@@ -350,7 +350,7 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables - - KBUILD_LDFLAGS += -m $(ld-emul) - --ifdef CONFIG_MIPS -+ifdef need-compiler - CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ - egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ - sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') -diff --git a/arch/parisc/include/asm/led.h b/arch/parisc/include/asm/led.h -index 6de13d08a3886..b70b9094fb7cd 100644 ---- a/arch/parisc/include/asm/led.h -+++ b/arch/parisc/include/asm/led.h -@@ -11,8 +11,8 @@ - #define LED1 0x02 - #define LED0 0x01 /* bottom (or furthest left) LED */ - --#define LED_LAN_TX LED0 /* for LAN transmit activity */ --#define LED_LAN_RCV LED1 /* for LAN receive activity */ -+#define LED_LAN_RCV LED0 /* for LAN receive activity */ -+#define LED_LAN_TX LED1 /* for LAN transmit activity */ - #define LED_DISK_IO LED2 /* for disk activity */ - #define LED_HEARTBEAT LED3 /* heartbeat */ - -diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c -index c77b5f00a66a3..d8f8dca4d7968 100644 ---- a/arch/sh/boards/mach-ap325rxa/setup.c -+++ b/arch/sh/boards/mach-ap325rxa/setup.c -@@ -530,7 +530,7 @@ static int __init ap325rxa_devices_setup(void) - device_initialize(&ap325rxa_ceu_device.dev); - dma_declare_coherent_memory(&ap325rxa_ceu_device.dev, - ceu_dma_membase, ceu_dma_membase, -- ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); -+ CEU_BUFFER_MEMORY_SIZE); - - platform_device_add(&ap325rxa_ceu_device); - -diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c -index 674da7ebd8b7f..7ec03d4a4edf0 100644 ---- a/arch/sh/boards/mach-ecovec24/setup.c -+++ b/arch/sh/boards/mach-ecovec24/setup.c -@@ -1454,15 +1454,13 @@ static int __init arch_setup(void) - device_initialize(&ecovec_ceu_devices[0]->dev); - dma_declare_coherent_memory(&ecovec_ceu_devices[0]->dev, - ceu0_dma_membase, ceu0_dma_membase, -- ceu0_dma_membase + -- CEU_BUFFER_MEMORY_SIZE - 1); -+ CEU_BUFFER_MEMORY_SIZE); - platform_device_add(ecovec_ceu_devices[0]); - - device_initialize(&ecovec_ceu_devices[1]->dev); - dma_declare_coherent_memory(&ecovec_ceu_devices[1]->dev, - ceu1_dma_membase, ceu1_dma_membase, -- ceu1_dma_membase + -- CEU_BUFFER_MEMORY_SIZE - 1); -+ CEU_BUFFER_MEMORY_SIZE); - platform_device_add(ecovec_ceu_devices[1]); - - gpiod_add_lookup_table(&cn12_power_gpiod_table); -diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c -index 20f4db778ed6a..c6d556dfbbbe6 100644 ---- a/arch/sh/boards/mach-kfr2r09/setup.c -+++ b/arch/sh/boards/mach-kfr2r09/setup.c -@@ -603,7 +603,7 @@ static int __init kfr2r09_devices_setup(void) - device_initialize(&kfr2r09_ceu_device.dev); - dma_declare_coherent_memory(&kfr2r09_ceu_device.dev, - ceu_dma_membase, ceu_dma_membase, -- ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); -+ CEU_BUFFER_MEMORY_SIZE); - - platform_device_add(&kfr2r09_ceu_device); - -diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c -index f60061283c482..773ee767d0c4e 100644 ---- a/arch/sh/boards/mach-migor/setup.c -+++ b/arch/sh/boards/mach-migor/setup.c -@@ -604,7 +604,7 @@ static int __init migor_devices_setup(void) - device_initialize(&migor_ceu_device.dev); - dma_declare_coherent_memory(&migor_ceu_device.dev, - ceu_dma_membase, ceu_dma_membase, -- ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); -+ CEU_BUFFER_MEMORY_SIZE); - - platform_device_add(&migor_ceu_device); - -diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c -index b60a2626e18b2..6495f93540654 100644 ---- a/arch/sh/boards/mach-se/7724/setup.c -+++ b/arch/sh/boards/mach-se/7724/setup.c -@@ -940,15 +940,13 @@ static int __init devices_setup(void) - device_initialize(&ms7724se_ceu_devices[0]->dev); - dma_declare_coherent_memory(&ms7724se_ceu_devices[0]->dev, - ceu0_dma_membase, ceu0_dma_membase, -- ceu0_dma_membase + -- CEU_BUFFER_MEMORY_SIZE - 1); -+ CEU_BUFFER_MEMORY_SIZE); - platform_device_add(ms7724se_ceu_devices[0]); - - device_initialize(&ms7724se_ceu_devices[1]->dev); - dma_declare_coherent_memory(&ms7724se_ceu_devices[1]->dev, - ceu1_dma_membase, ceu1_dma_membase, -- ceu1_dma_membase + -- CEU_BUFFER_MEMORY_SIZE - 1); -+ CEU_BUFFER_MEMORY_SIZE); - platform_device_add(ms7724se_ceu_devices[1]); - - return platform_add_devices(ms7724se_devices, -diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h -index 3b12e6b994123..6c2e3ff3cb28f 100644 ---- a/arch/x86/include/asm/virtext.h -+++ b/arch/x86/include/asm/virtext.h -@@ -101,12 +101,6 @@ static inline int cpu_has_svm(const char **msg) - return 0; - } - -- if (boot_cpu_data.extended_cpuid_level < SVM_CPUID_FUNC) { -- if (msg) -- *msg = "can't execute cpuid_8000000a"; -- return 0; -- } -- - if (!boot_cpu_has(X86_FEATURE_SVM)) { - if (msg) - *msg = "svm not available"; -diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c -index e910ec5a0cc0b..d3e66740c7c68 100644 ---- a/arch/x86/kvm/svm/avic.c -+++ b/arch/x86/kvm/svm/avic.c -@@ -810,6 +810,7 @@ static int svm_ir_list_add(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi) - int ret = 0; - unsigned long flags; - struct amd_svm_iommu_ir *ir; -+ u64 entry; - - /** - * In some cases, the existing irte is updated and re-set, -@@ -843,6 +844,18 @@ static int svm_ir_list_add(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi) - ir->data = pi->ir_data; - - spin_lock_irqsave(&svm->ir_list_lock, flags); -+ -+ /* -+ * Update the target pCPU for IOMMU doorbells if the vCPU is running. -+ * If the vCPU is NOT running, i.e. is blocking or scheduled out, KVM -+ * will update the pCPU info when the vCPU awkened and/or scheduled in. -+ * See also avic_vcpu_load(). -+ */ -+ entry = READ_ONCE(*(svm->avic_physical_id_cache)); -+ if (entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK) -+ amd_iommu_update_ga(entry & AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK, -+ true, pi->ir_data); -+ - list_add(&ir->node, &svm->ir_list); - spin_unlock_irqrestore(&svm->ir_list_lock, flags); - out: -@@ -1022,10 +1035,11 @@ static inline int - avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, bool r) - { - int ret = 0; -- unsigned long flags; - struct amd_svm_iommu_ir *ir; - struct vcpu_svm *svm = to_svm(vcpu); - -+ lockdep_assert_held(&svm->ir_list_lock); -+ - if (!kvm_arch_has_assigned_device(vcpu->kvm)) - return 0; - -@@ -1033,19 +1047,15 @@ avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, bool r) - * Here, we go through the per-vcpu ir_list to update all existing - * interrupt remapping table entry targeting this vcpu. - */ -- spin_lock_irqsave(&svm->ir_list_lock, flags); -- - if (list_empty(&svm->ir_list)) -- goto out; -+ return 0; - - list_for_each_entry(ir, &svm->ir_list, node) { - ret = amd_iommu_update_ga(cpu, r, ir->data); - if (ret) -- break; -+ return ret; - } --out: -- spin_unlock_irqrestore(&svm->ir_list_lock, flags); -- return ret; -+ return 0; - } - - void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) -@@ -1053,6 +1063,7 @@ void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) - u64 entry; - int h_physical_id = kvm_cpu_get_apicid(cpu); - struct vcpu_svm *svm = to_svm(vcpu); -+ unsigned long flags; - - lockdep_assert_preemption_disabled(); - -@@ -1069,6 +1080,15 @@ void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) - if (kvm_vcpu_is_blocking(vcpu)) - return; - -+ /* -+ * Grab the per-vCPU interrupt remapping lock even if the VM doesn't -+ * _currently_ have assigned devices, as that can change. Holding -+ * ir_list_lock ensures that either svm_ir_list_add() will consume -+ * up-to-date entry information, or that this task will wait until -+ * svm_ir_list_add() completes to set the new target pCPU. -+ */ -+ spin_lock_irqsave(&svm->ir_list_lock, flags); -+ - entry = READ_ONCE(*(svm->avic_physical_id_cache)); - - entry &= ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK; -@@ -1077,25 +1097,48 @@ void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) - - WRITE_ONCE(*(svm->avic_physical_id_cache), entry); - avic_update_iommu_vcpu_affinity(vcpu, h_physical_id, true); -+ -+ spin_unlock_irqrestore(&svm->ir_list_lock, flags); - } - - void avic_vcpu_put(struct kvm_vcpu *vcpu) - { - u64 entry; - struct vcpu_svm *svm = to_svm(vcpu); -+ unsigned long flags; - - lockdep_assert_preemption_disabled(); - -+ /* -+ * Note, reading the Physical ID entry outside of ir_list_lock is safe -+ * as only the pCPU that has loaded (or is loading) the vCPU is allowed -+ * to modify the entry, and preemption is disabled. I.e. the vCPU -+ * can't be scheduled out and thus avic_vcpu_{put,load}() can't run -+ * recursively. -+ */ - entry = READ_ONCE(*(svm->avic_physical_id_cache)); - - /* Nothing to do if IsRunning == '0' due to vCPU blocking. */ - if (!(entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK)) - return; - -+ /* -+ * Take and hold the per-vCPU interrupt remapping lock while updating -+ * the Physical ID entry even though the lock doesn't protect against -+ * multiple writers (see above). Holding ir_list_lock ensures that -+ * either svm_ir_list_add() will consume up-to-date entry information, -+ * or that this task will wait until svm_ir_list_add() completes to -+ * mark the vCPU as not running. -+ */ -+ spin_lock_irqsave(&svm->ir_list_lock, flags); -+ - avic_update_iommu_vcpu_affinity(vcpu, -1, 0); - - entry &= ~AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK; - WRITE_ONCE(*(svm->avic_physical_id_cache), entry); -+ -+ spin_unlock_irqrestore(&svm->ir_list_lock, flags); -+ - } - - void avic_refresh_virtual_apic_mode(struct kvm_vcpu *vcpu) -diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c -index 92268645a5fed..8053974af326c 100644 ---- a/arch/x86/kvm/svm/nested.c -+++ b/arch/x86/kvm/svm/nested.c -@@ -660,10 +660,9 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, - - vmcb02->control.tsc_offset = vcpu->arch.tsc_offset; - -- if (svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio) { -- WARN_ON(!svm->tsc_scaling_enabled); -+ if (svm->tsc_scaling_enabled && -+ svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio) - nested_svm_update_tsc_ratio_msr(vcpu); -- } - - vmcb02->control.int_ctl = - (svm->nested.ctl.int_ctl & int_ctl_vmcb12_bits) | -@@ -1022,8 +1021,8 @@ int nested_svm_vmexit(struct vcpu_svm *svm) - vmcb_mark_dirty(vmcb01, VMCB_INTERCEPTS); - } - -- if (svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio) { -- WARN_ON(!svm->tsc_scaling_enabled); -+ if (kvm_caps.has_tsc_control && -+ vcpu->arch.tsc_scaling_ratio != vcpu->arch.l1_tsc_scaling_ratio) { - vcpu->arch.tsc_scaling_ratio = vcpu->arch.l1_tsc_scaling_ratio; - __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); - } -diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c -index e0437acb5cf75..d08d5e085649f 100644 ---- a/arch/x86/kvm/svm/sev.c -+++ b/arch/x86/kvm/svm/sev.c -@@ -1723,7 +1723,7 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm) - * Note, the source is not required to have the same number of - * vCPUs as the destination when migrating a vanilla SEV VM. - */ -- src_vcpu = kvm_get_vcpu(dst_kvm, i); -+ src_vcpu = kvm_get_vcpu(src_kvm, i); - src_svm = to_svm(src_vcpu); - - /* -@@ -2951,9 +2951,12 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm) - /* - * An SEV-ES guest requires a VMSA area that is a separate from the - * VMCB page. Do not include the encryption mask on the VMSA physical -- * address since hardware will access it using the guest key. -+ * address since hardware will access it using the guest key. Note, -+ * the VMSA will be NULL if this vCPU is the destination for intrahost -+ * migration, and will be copied later. - */ -- svm->vmcb->control.vmsa_pa = __pa(svm->sev_es.vmsa); -+ if (svm->sev_es.vmsa) -+ svm->vmcb->control.vmsa_pa = __pa(svm->sev_es.vmsa); - - /* Can't intercept CR register access, HV can't modify CR registers */ - svm_clr_intercept(svm, INTERCEPT_CR0_READ); -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index a96f9a17e8b5d..7e4d66be18ef5 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -366,6 +366,8 @@ static void svm_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) - svm->vmcb->control.int_state |= SVM_INTERRUPT_SHADOW_MASK; - - } -+static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type, -+ void *insn, int insn_len); - - static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, - bool commit_side_effects) -@@ -386,6 +388,14 @@ static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, - } - - if (!svm->next_rip) { -+ /* -+ * FIXME: Drop this when kvm_emulate_instruction() does the -+ * right thing and treats "can't emulate" as outright failure -+ * for EMULTYPE_SKIP. -+ */ -+ if (!svm_can_emulate_instruction(vcpu, EMULTYPE_SKIP, NULL, 0)) -+ return 0; -+ - if (unlikely(!commit_side_effects)) - old_rflags = svm->vmcb->save.rflags; - -@@ -4592,16 +4602,25 @@ static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type, - * and cannot be decrypted by KVM, i.e. KVM would read cyphertext and - * decode garbage. - * -- * Inject #UD if KVM reached this point without an instruction buffer. -- * In practice, this path should never be hit by a well-behaved guest, -- * e.g. KVM doesn't intercept #UD or #GP for SEV guests, but this path -- * is still theoretically reachable, e.g. via unaccelerated fault-like -- * AVIC access, and needs to be handled by KVM to avoid putting the -- * guest into an infinite loop. Injecting #UD is somewhat arbitrary, -- * but its the least awful option given lack of insight into the guest. -+ * If KVM is NOT trying to simply skip an instruction, inject #UD if -+ * KVM reached this point without an instruction buffer. In practice, -+ * this path should never be hit by a well-behaved guest, e.g. KVM -+ * doesn't intercept #UD or #GP for SEV guests, but this path is still -+ * theoretically reachable, e.g. via unaccelerated fault-like AVIC -+ * access, and needs to be handled by KVM to avoid putting the guest -+ * into an infinite loop. Injecting #UD is somewhat arbitrary, but -+ * its the least awful option given lack of insight into the guest. -+ * -+ * If KVM is trying to skip an instruction, simply resume the guest. -+ * If a #NPF occurs while the guest is vectoring an INT3/INTO, then KVM -+ * will attempt to re-inject the INT3/INTO and skip the instruction. -+ * In that scenario, retrying the INT3/INTO and hoping the guest will -+ * make forward progress is the only option that has a chance of -+ * success (and in practice it will work the vast majority of the time). - */ - if (unlikely(!insn)) { -- kvm_queue_exception(vcpu, UD_VECTOR); -+ if (!(emul_type & EMULTYPE_SKIP)) -+ kvm_queue_exception(vcpu, UD_VECTOR); - return false; - } - -diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c -index db6053a22e866..5e680e039d0e1 100644 ---- a/arch/x86/net/bpf_jit_comp.c -+++ b/arch/x86/net/bpf_jit_comp.c -@@ -1813,10 +1813,6 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, - struct bpf_tramp_link *l, int stack_size, - int run_ctx_off, bool save_ret) - { -- void (*exit)(struct bpf_prog *prog, u64 start, -- struct bpf_tramp_run_ctx *run_ctx) = __bpf_prog_exit; -- u64 (*enter)(struct bpf_prog *prog, -- struct bpf_tramp_run_ctx *run_ctx) = __bpf_prog_enter; - u8 *prog = *pprog; - u8 *jmp_insn; - int ctx_cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie); -@@ -1835,23 +1831,12 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, - */ - emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_1, -run_ctx_off + ctx_cookie_off); - -- if (p->aux->sleepable) { -- enter = __bpf_prog_enter_sleepable; -- exit = __bpf_prog_exit_sleepable; -- } else if (p->type == BPF_PROG_TYPE_STRUCT_OPS) { -- enter = __bpf_prog_enter_struct_ops; -- exit = __bpf_prog_exit_struct_ops; -- } else if (p->expected_attach_type == BPF_LSM_CGROUP) { -- enter = __bpf_prog_enter_lsm_cgroup; -- exit = __bpf_prog_exit_lsm_cgroup; -- } -- - /* arg1: mov rdi, progs[i] */ - emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, (u32) (long) p); - /* arg2: lea rsi, [rbp - ctx_cookie_off] */ - EMIT4(0x48, 0x8D, 0x75, -run_ctx_off); - -- if (emit_call(&prog, enter, prog)) -+ if (emit_call(&prog, bpf_trampoline_enter(p), prog)) - return -EINVAL; - /* remember prog start time returned by __bpf_prog_enter */ - emit_mov_reg(&prog, true, BPF_REG_6, BPF_REG_0); -@@ -1896,7 +1881,7 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, - emit_mov_reg(&prog, true, BPF_REG_2, BPF_REG_6); - /* arg3: lea rdx, [rbp - run_ctx_off] */ - EMIT4(0x48, 0x8D, 0x55, -run_ctx_off); -- if (emit_call(&prog, exit, prog)) -+ if (emit_call(&prog, bpf_trampoline_exit(p), prog)) - return -EINVAL; - - *pprog = prog; -diff --git a/block/blk-throttle.c b/block/blk-throttle.c -index f1bc600c4ded6..1007f80278579 100644 ---- a/block/blk-throttle.c -+++ b/block/blk-throttle.c -@@ -697,11 +697,41 @@ static bool throtl_slice_used(struct throtl_grp *tg, bool rw) - return true; - } - -+static unsigned int calculate_io_allowed(u32 iops_limit, -+ unsigned long jiffy_elapsed) -+{ -+ unsigned int io_allowed; -+ u64 tmp; -+ -+ /* -+ * jiffy_elapsed should not be a big value as minimum iops can be -+ * 1 then at max jiffy elapsed should be equivalent of 1 second as we -+ * will allow dispatch after 1 second and after that slice should -+ * have been trimmed. -+ */ -+ -+ tmp = (u64)iops_limit * jiffy_elapsed; -+ do_div(tmp, HZ); -+ -+ if (tmp > UINT_MAX) -+ io_allowed = UINT_MAX; -+ else -+ io_allowed = tmp; -+ -+ return io_allowed; -+} -+ -+static u64 calculate_bytes_allowed(u64 bps_limit, unsigned long jiffy_elapsed) -+{ -+ return mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed, (u64)HZ); -+} -+ - /* Trim the used slices and adjust slice start accordingly */ - static inline void throtl_trim_slice(struct throtl_grp *tg, bool rw) - { -- unsigned long nr_slices, time_elapsed, io_trim; -- u64 bytes_trim, tmp; -+ unsigned long time_elapsed; -+ long long bytes_trim; -+ int io_trim; - - BUG_ON(time_before(tg->slice_end[rw], tg->slice_start[rw])); - -@@ -723,67 +753,38 @@ static inline void throtl_trim_slice(struct throtl_grp *tg, bool rw) - - throtl_set_slice_end(tg, rw, jiffies + tg->td->throtl_slice); - -- time_elapsed = jiffies - tg->slice_start[rw]; -- -- nr_slices = time_elapsed / tg->td->throtl_slice; -- -- if (!nr_slices) -+ time_elapsed = rounddown(jiffies - tg->slice_start[rw], -+ tg->td->throtl_slice); -+ if (!time_elapsed) - return; -- tmp = tg_bps_limit(tg, rw) * tg->td->throtl_slice * nr_slices; -- do_div(tmp, HZ); -- bytes_trim = tmp; - -- io_trim = (tg_iops_limit(tg, rw) * tg->td->throtl_slice * nr_slices) / -- HZ; -- -- if (!bytes_trim && !io_trim) -+ bytes_trim = calculate_bytes_allowed(tg_bps_limit(tg, rw), -+ time_elapsed) + -+ tg->carryover_bytes[rw]; -+ io_trim = calculate_io_allowed(tg_iops_limit(tg, rw), time_elapsed) + -+ tg->carryover_ios[rw]; -+ if (bytes_trim <= 0 && io_trim <= 0) - return; - -- if (tg->bytes_disp[rw] >= bytes_trim) -+ tg->carryover_bytes[rw] = 0; -+ if ((long long)tg->bytes_disp[rw] >= bytes_trim) - tg->bytes_disp[rw] -= bytes_trim; - else - tg->bytes_disp[rw] = 0; - -- if (tg->io_disp[rw] >= io_trim) -+ tg->carryover_ios[rw] = 0; -+ if ((int)tg->io_disp[rw] >= io_trim) - tg->io_disp[rw] -= io_trim; - else - tg->io_disp[rw] = 0; - -- tg->slice_start[rw] += nr_slices * tg->td->throtl_slice; -+ tg->slice_start[rw] += time_elapsed; - - throtl_log(&tg->service_queue, -- "[%c] trim slice nr=%lu bytes=%llu io=%lu start=%lu end=%lu jiffies=%lu", -- rw == READ ? 'R' : 'W', nr_slices, bytes_trim, io_trim, -- tg->slice_start[rw], tg->slice_end[rw], jiffies); --} -- --static unsigned int calculate_io_allowed(u32 iops_limit, -- unsigned long jiffy_elapsed) --{ -- unsigned int io_allowed; -- u64 tmp; -- -- /* -- * jiffy_elapsed should not be a big value as minimum iops can be -- * 1 then at max jiffy elapsed should be equivalent of 1 second as we -- * will allow dispatch after 1 second and after that slice should -- * have been trimmed. -- */ -- -- tmp = (u64)iops_limit * jiffy_elapsed; -- do_div(tmp, HZ); -- -- if (tmp > UINT_MAX) -- io_allowed = UINT_MAX; -- else -- io_allowed = tmp; -- -- return io_allowed; --} -- --static u64 calculate_bytes_allowed(u64 bps_limit, unsigned long jiffy_elapsed) --{ -- return mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed, (u64)HZ); -+ "[%c] trim slice nr=%lu bytes=%lld io=%d start=%lu end=%lu jiffies=%lu", -+ rw == READ ? 'R' : 'W', time_elapsed / tg->td->throtl_slice, -+ bytes_trim, io_trim, tg->slice_start[rw], tg->slice_end[rw], -+ jiffies); - } - - static void __tg_update_carryover(struct throtl_grp *tg, bool rw) -diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c -index 53ab2306da009..1645335b8d2df 100644 ---- a/drivers/ata/ahci.c -+++ b/drivers/ata/ahci.c -@@ -422,6 +422,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { - { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_low_power }, /* Ice Lake LP AHCI */ - { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_low_power }, /* Comet Lake PCH-U AHCI */ - { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */ -+ /* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */ -+ { PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI */ - - /* JMicron 360/1/3/5/6, match class to avoid IDE function */ - { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, -diff --git a/drivers/ata/pata_falcon.c b/drivers/ata/pata_falcon.c -index 823c88622e34a..ffdd12e722c99 100644 ---- a/drivers/ata/pata_falcon.c -+++ b/drivers/ata/pata_falcon.c -@@ -123,8 +123,8 @@ static int __init pata_falcon_init_one(struct platform_device *pdev) - struct resource *base_res, *ctl_res, *irq_res; - struct ata_host *host; - struct ata_port *ap; -- void __iomem *base; -- int irq = 0; -+ void __iomem *base, *ctl_base; -+ int irq = 0, io_offset = 1, reg_shift = 2; /* Falcon defaults */ - - dev_info(&pdev->dev, "Atari Falcon and Q40/Q60 PATA controller\n"); - -@@ -165,26 +165,34 @@ static int __init pata_falcon_init_one(struct platform_device *pdev) - ap->pio_mask = ATA_PIO4; - ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY; - -- base = (void __iomem *)base_mem_res->start; - /* N.B. this assumes data_addr will be used for word-sized I/O only */ -- ap->ioaddr.data_addr = base + 0 + 0 * 4; -- ap->ioaddr.error_addr = base + 1 + 1 * 4; -- ap->ioaddr.feature_addr = base + 1 + 1 * 4; -- ap->ioaddr.nsect_addr = base + 1 + 2 * 4; -- ap->ioaddr.lbal_addr = base + 1 + 3 * 4; -- ap->ioaddr.lbam_addr = base + 1 + 4 * 4; -- ap->ioaddr.lbah_addr = base + 1 + 5 * 4; -- ap->ioaddr.device_addr = base + 1 + 6 * 4; -- ap->ioaddr.status_addr = base + 1 + 7 * 4; -- ap->ioaddr.command_addr = base + 1 + 7 * 4; -- -- base = (void __iomem *)ctl_mem_res->start; -- ap->ioaddr.altstatus_addr = base + 1; -- ap->ioaddr.ctl_addr = base + 1; -- -- ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", -- (unsigned long)base_mem_res->start, -- (unsigned long)ctl_mem_res->start); -+ ap->ioaddr.data_addr = (void __iomem *)base_mem_res->start; -+ -+ if (base_res) { /* only Q40 has IO resources */ -+ io_offset = 0x10000; -+ reg_shift = 0; -+ base = (void __iomem *)base_res->start; -+ ctl_base = (void __iomem *)ctl_res->start; -+ } else { -+ base = (void __iomem *)base_mem_res->start; -+ ctl_base = (void __iomem *)ctl_mem_res->start; -+ } -+ -+ ap->ioaddr.error_addr = base + io_offset + (1 << reg_shift); -+ ap->ioaddr.feature_addr = base + io_offset + (1 << reg_shift); -+ ap->ioaddr.nsect_addr = base + io_offset + (2 << reg_shift); -+ ap->ioaddr.lbal_addr = base + io_offset + (3 << reg_shift); -+ ap->ioaddr.lbam_addr = base + io_offset + (4 << reg_shift); -+ ap->ioaddr.lbah_addr = base + io_offset + (5 << reg_shift); -+ ap->ioaddr.device_addr = base + io_offset + (6 << reg_shift); -+ ap->ioaddr.status_addr = base + io_offset + (7 << reg_shift); -+ ap->ioaddr.command_addr = base + io_offset + (7 << reg_shift); -+ -+ ap->ioaddr.altstatus_addr = ctl_base + io_offset; -+ ap->ioaddr.ctl_addr = ctl_base + io_offset; -+ -+ ata_port_desc(ap, "cmd %px ctl %px data %px", -+ base, ctl_base, ap->ioaddr.data_addr); - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (irq_res && irq_res->start > 0) { -diff --git a/drivers/ata/pata_ftide010.c b/drivers/ata/pata_ftide010.c -index 0117df0fe3c59..092ba6f87aa31 100644 ---- a/drivers/ata/pata_ftide010.c -+++ b/drivers/ata/pata_ftide010.c -@@ -567,6 +567,7 @@ static struct platform_driver pata_ftide010_driver = { - }; - module_platform_driver(pata_ftide010_driver); - -+MODULE_DESCRIPTION("low level driver for Faraday Technology FTIDE010"); - MODULE_AUTHOR("Linus Walleij "); - MODULE_LICENSE("GPL"); - MODULE_ALIAS("platform:" DRV_NAME); -diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c -index b729e9919bb0c..c96fcf9ee3c07 100644 ---- a/drivers/ata/sata_gemini.c -+++ b/drivers/ata/sata_gemini.c -@@ -428,6 +428,7 @@ static struct platform_driver gemini_sata_driver = { - }; - module_platform_driver(gemini_sata_driver); - -+MODULE_DESCRIPTION("low level driver for Cortina Systems Gemini SATA bridge"); - MODULE_AUTHOR("Linus Walleij "); - MODULE_LICENSE("GPL"); - MODULE_ALIAS("platform:" DRV_NAME); -diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c -index e8cb914223cdf..e9f38eba2f133 100644 ---- a/drivers/block/null_blk/main.c -+++ b/drivers/block/null_blk/main.c -@@ -1585,9 +1585,12 @@ static int null_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) - struct nullb_queue *nq = hctx->driver_data; - LIST_HEAD(list); - int nr = 0; -+ struct request *rq; - - spin_lock(&nq->poll_lock); - list_splice_init(&nq->poll_list, &list); -+ list_for_each_entry(rq, &list, queuelist) -+ blk_mq_set_request_complete(rq); - spin_unlock(&nq->poll_lock); - - while (!list_empty(&list)) { -@@ -1613,16 +1616,21 @@ static enum blk_eh_timer_return null_timeout_rq(struct request *rq) - struct blk_mq_hw_ctx *hctx = rq->mq_hctx; - struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq); - -- pr_info("rq %p timed out\n", rq); -- - if (hctx->type == HCTX_TYPE_POLL) { - struct nullb_queue *nq = hctx->driver_data; - - spin_lock(&nq->poll_lock); -+ /* The request may have completed meanwhile. */ -+ if (blk_mq_request_completed(rq)) { -+ spin_unlock(&nq->poll_lock); -+ return BLK_EH_DONE; -+ } - list_del_init(&rq->queuelist); - spin_unlock(&nq->poll_lock); - } - -+ pr_info("rq %p timed out\n", rq); -+ - /* - * If the device is marked as blocking (i.e. memory backed or zoned - * device), the submission path may be blocked waiting for resources -diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c -index 083459028a4b8..8a4362d75fc43 100644 ---- a/drivers/bus/mhi/host/pm.c -+++ b/drivers/bus/mhi/host/pm.c -@@ -470,6 +470,10 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) - - /* Trigger MHI RESET so that the device will not access host memory */ - if (!MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) { -+ /* Skip MHI RESET if in RDDM state */ -+ if (mhi_cntrl->rddm_image && mhi_get_exec_env(mhi_cntrl) == MHI_EE_RDDM) -+ goto skip_mhi_reset; -+ - dev_dbg(dev, "Triggering MHI Reset in device\n"); - mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); - -@@ -495,6 +499,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) - } - } - -+skip_mhi_reset: - dev_dbg(dev, - "Waiting for all pending event ring processing to complete\n"); - mhi_event = mhi_cntrl->mhi_event; -diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c -index db0b774207d35..f45239e73c4ca 100644 ---- a/drivers/char/tpm/tpm_crb.c -+++ b/drivers/char/tpm/tpm_crb.c -@@ -775,12 +775,13 @@ static int crb_acpi_add(struct acpi_device *device) - FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n", - buf->header.length, - ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON); -- return -EINVAL; -+ rc = -EINVAL; -+ goto out; - } - crb_pluton = ACPI_ADD_PTR(struct tpm2_crb_pluton, buf, sizeof(*buf)); - rc = crb_map_pluton(dev, priv, buf, crb_pluton); - if (rc) -- return rc; -+ goto out; - } - - priv->sm = sm; -diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c -index 1d0f79e9c3467..416d582a9e8e0 100644 ---- a/drivers/clk/imx/clk-pll14xx.c -+++ b/drivers/clk/imx/clk-pll14xx.c -@@ -62,8 +62,6 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), - PLL_1443X_RATE(594000000U, 198, 2, 2, 0), - PLL_1443X_RATE(519750000U, 173, 2, 2, 16384), -- PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), -- PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), - }; - - struct imx_pll14xx_clk imx_1443x_pll = { -@@ -137,11 +135,10 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat - /* - * Fractional PLL constrains: - * -- * a) 6MHz <= prate <= 25MHz -- * b) 1 <= p <= 63 (1 <= p <= 4 prate = 24MHz) -- * c) 64 <= m <= 1023 -- * d) 0 <= s <= 6 -- * e) -32768 <= k <= 32767 -+ * a) 1 <= p <= 63 -+ * b) 64 <= m <= 1023 -+ * c) 0 <= s <= 6 -+ * d) -32768 <= k <= 32767 - * - * fvco = (m * 65536 + k) * prate / (p * 65536) - */ -@@ -184,7 +181,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat - } - - /* Finally calculate best values */ -- for (pdiv = 1; pdiv <= 7; pdiv++) { -+ for (pdiv = 1; pdiv <= 63; pdiv++) { - for (sdiv = 0; sdiv <= 6; sdiv++) { - /* calc mdiv = round(rate * pdiv * 2^sdiv) / prate) */ - mdiv = DIV_ROUND_CLOSEST(rate * (pdiv << sdiv), prate); -diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c -index 8a4ba7a19ed12..6f56bdbf02047 100644 ---- a/drivers/clk/qcom/camcc-sc7180.c -+++ b/drivers/clk/qcom/camcc-sc7180.c -@@ -1664,7 +1664,7 @@ static int cam_cc_sc7180_probe(struct platform_device *pdev) - return ret; - } - -- ret = pm_runtime_get(&pdev->dev); -+ ret = pm_runtime_resume_and_get(&pdev->dev); - if (ret) - return ret; - -diff --git a/drivers/clk/qcom/dispcc-sm8450.c b/drivers/clk/qcom/dispcc-sm8450.c -index 0cd7ebe90301c..64626f620a01b 100644 ---- a/drivers/clk/qcom/dispcc-sm8450.c -+++ b/drivers/clk/qcom/dispcc-sm8450.c -@@ -1783,8 +1783,10 @@ static int disp_cc_sm8450_probe(struct platform_device *pdev) - return ret; - - regmap = qcom_cc_map(pdev, &disp_cc_sm8450_desc); -- if (IS_ERR(regmap)) -- return PTR_ERR(regmap); -+ if (IS_ERR(regmap)) { -+ ret = PTR_ERR(regmap); -+ goto err_put_rpm; -+ } - - clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); - clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config); -@@ -1799,9 +1801,16 @@ static int disp_cc_sm8450_probe(struct platform_device *pdev) - regmap_update_bits(regmap, 0xe05c, BIT(0), BIT(0)); - - ret = qcom_cc_really_probe(pdev, &disp_cc_sm8450_desc, regmap); -+ if (ret) -+ goto err_put_rpm; - - pm_runtime_put(&pdev->dev); - -+ return 0; -+ -+err_put_rpm: -+ pm_runtime_put_sync(&pdev->dev); -+ - return ret; - } - -diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c -index 8bed02a748aba..470a277603a92 100644 ---- a/drivers/clk/qcom/gcc-mdm9615.c -+++ b/drivers/clk/qcom/gcc-mdm9615.c -@@ -58,7 +58,7 @@ static struct clk_regmap pll0_vote = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "pll0_vote", -- .parent_names = (const char *[]){ "pll8" }, -+ .parent_names = (const char *[]){ "pll0" }, - .num_parents = 1, - .ops = &clk_pll_vote_ops, - }, -diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c -index 8486d7135ab10..113146835902b 100644 ---- a/drivers/clk/qcom/lpasscc-sc7280.c -+++ b/drivers/clk/qcom/lpasscc-sc7280.c -@@ -115,9 +115,13 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev) - ret = pm_clk_add(&pdev->dev, "iface"); - if (ret < 0) { - dev_err(&pdev->dev, "failed to acquire iface clock\n"); -- goto destroy_pm_clk; -+ goto err_destroy_pm_clk; - } - -+ ret = pm_runtime_resume_and_get(&pdev->dev); -+ if (ret) -+ goto err_destroy_pm_clk; -+ - if (!of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) { - lpass_regmap_config.name = "qdsp6ss"; - lpass_regmap_config.max_register = 0x3f; -@@ -125,7 +129,7 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev) - - ret = qcom_cc_probe_by_index(pdev, 0, desc); - if (ret) -- goto destroy_pm_clk; -+ goto err_put_rpm; - } - - lpass_regmap_config.name = "top_cc"; -@@ -134,11 +138,15 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev) - - ret = qcom_cc_probe_by_index(pdev, 1, desc); - if (ret) -- goto destroy_pm_clk; -+ goto err_put_rpm; -+ -+ pm_runtime_put(&pdev->dev); - - return 0; - --destroy_pm_clk: -+err_put_rpm: -+ pm_runtime_put_sync(&pdev->dev); -+err_destroy_pm_clk: - pm_clk_destroy(&pdev->dev); - - disable_pm_runtime: -diff --git a/drivers/clk/qcom/mss-sc7180.c b/drivers/clk/qcom/mss-sc7180.c -index 5a14074406623..d106bc65470e1 100644 ---- a/drivers/clk/qcom/mss-sc7180.c -+++ b/drivers/clk/qcom/mss-sc7180.c -@@ -87,11 +87,22 @@ static int mss_sc7180_probe(struct platform_device *pdev) - return ret; - } - -+ ret = pm_runtime_resume_and_get(&pdev->dev); -+ if (ret) -+ return ret; -+ - ret = qcom_cc_probe(pdev, &mss_sc7180_desc); - if (ret < 0) -- return ret; -+ goto err_put_rpm; -+ -+ pm_runtime_put(&pdev->dev); - - return 0; -+ -+err_put_rpm: -+ pm_runtime_put_sync(&pdev->dev); -+ -+ return ret; - } - - static const struct dev_pm_ops mss_sc7180_pm_ops = { -diff --git a/drivers/clk/qcom/q6sstop-qcs404.c b/drivers/clk/qcom/q6sstop-qcs404.c -index 780074e05841b..26e2d63614ac3 100644 ---- a/drivers/clk/qcom/q6sstop-qcs404.c -+++ b/drivers/clk/qcom/q6sstop-qcs404.c -@@ -174,21 +174,32 @@ static int q6sstopcc_qcs404_probe(struct platform_device *pdev) - return ret; - } - -+ ret = pm_runtime_resume_and_get(&pdev->dev); -+ if (ret) -+ return ret; -+ - q6sstop_regmap_config.name = "q6sstop_tcsr"; - desc = &tcsr_qcs404_desc; - - ret = qcom_cc_probe_by_index(pdev, 1, desc); - if (ret) -- return ret; -+ goto err_put_rpm; - - q6sstop_regmap_config.name = "q6sstop_cc"; - desc = &q6sstop_qcs404_desc; - - ret = qcom_cc_probe_by_index(pdev, 0, desc); - if (ret) -- return ret; -+ goto err_put_rpm; -+ -+ pm_runtime_put(&pdev->dev); - - return 0; -+ -+err_put_rpm: -+ pm_runtime_put_sync(&pdev->dev); -+ -+ return ret; - } - - static const struct dev_pm_ops q6sstopcc_pm_ops = { -diff --git a/drivers/clk/qcom/turingcc-qcs404.c b/drivers/clk/qcom/turingcc-qcs404.c -index 43184459228fd..2cd288d6c3e4d 100644 ---- a/drivers/clk/qcom/turingcc-qcs404.c -+++ b/drivers/clk/qcom/turingcc-qcs404.c -@@ -125,11 +125,22 @@ static int turingcc_probe(struct platform_device *pdev) - return ret; - } - -+ ret = pm_runtime_resume_and_get(&pdev->dev); -+ if (ret) -+ return ret; -+ - ret = qcom_cc_probe(pdev, &turingcc_desc); - if (ret < 0) -- return ret; -+ goto err_put_rpm; -+ -+ pm_runtime_put(&pdev->dev); - - return 0; -+ -+err_put_rpm: -+ pm_runtime_put_sync(&pdev->dev); -+ -+ return ret; - } - - static const struct dev_pm_ops turingcc_pm_ops = { -diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c -index 933bb960490d0..239c70ac120e8 100644 ---- a/drivers/clocksource/arm_arch_timer.c -+++ b/drivers/clocksource/arm_arch_timer.c -@@ -773,6 +773,13 @@ static __always_inline void set_next_event_mem(const int access, unsigned long e - u64 cnt; - - ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); -+ -+ /* Timer must be disabled before programming CVAL */ -+ if (ctrl & ARCH_TIMER_CTRL_ENABLE) { -+ ctrl &= ~ARCH_TIMER_CTRL_ENABLE; -+ arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); -+ } -+ - ctrl |= ARCH_TIMER_CTRL_ENABLE; - ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; - -diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c -index 476847a4916b9..2967141f4e7b2 100644 ---- a/drivers/dma/sh/rz-dmac.c -+++ b/drivers/dma/sh/rz-dmac.c -@@ -9,6 +9,7 @@ - * Copyright 2012 Javier Martin, Vista Silicon - */ - -+#include - #include - #include - #include -@@ -145,8 +146,8 @@ struct rz_dmac { - #define CHCFG_REQD BIT(3) - #define CHCFG_SEL(bits) ((bits) & 0x07) - #define CHCFG_MEM_COPY (0x80400008) --#define CHCFG_FILL_DDS(a) (((a) << 16) & GENMASK(19, 16)) --#define CHCFG_FILL_SDS(a) (((a) << 12) & GENMASK(15, 12)) -+#define CHCFG_FILL_DDS_MASK GENMASK(19, 16) -+#define CHCFG_FILL_SDS_MASK GENMASK(15, 12) - #define CHCFG_FILL_TM(a) (((a) & BIT(5)) << 22) - #define CHCFG_FILL_AM(a) (((a) & GENMASK(4, 2)) << 6) - #define CHCFG_FILL_LVL(a) (((a) & BIT(1)) << 5) -@@ -609,13 +610,15 @@ static int rz_dmac_config(struct dma_chan *chan, - if (val == CHCFG_DS_INVALID) - return -EINVAL; - -- channel->chcfg |= CHCFG_FILL_DDS(val); -+ channel->chcfg &= ~CHCFG_FILL_DDS_MASK; -+ channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val); - - val = rz_dmac_ds_to_val_mapping(config->src_addr_width); - if (val == CHCFG_DS_INVALID) - return -EINVAL; - -- channel->chcfg |= CHCFG_FILL_SDS(val); -+ channel->chcfg &= ~CHCFG_FILL_SDS_MASK; -+ channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val); - - return 0; - } -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index dd6f9ae6fbe9f..2fced451f0aea 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -38,6 +38,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -493,11 +495,29 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, - return true; - } - -+static int amdgpu_dirtyfb(struct drm_framebuffer *fb, struct drm_file *file, -+ unsigned int flags, unsigned int color, -+ struct drm_clip_rect *clips, unsigned int num_clips) -+{ -+ -+ if (file) -+ return -ENOSYS; -+ -+ return drm_atomic_helper_dirtyfb(fb, file, flags, color, clips, -+ num_clips); -+} -+ - static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { - .destroy = drm_gem_fb_destroy, - .create_handle = drm_gem_fb_create_handle, - }; - -+static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = { -+ .destroy = drm_gem_fb_destroy, -+ .create_handle = drm_gem_fb_create_handle, -+ .dirty = amdgpu_dirtyfb -+}; -+ - uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, - uint64_t bo_flags) - { -@@ -1100,7 +1120,11 @@ static int amdgpu_display_gem_fb_verify_and_init(struct drm_device *dev, - if (ret) - goto err; - -- ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); -+ if (drm_drv_uses_atomic_modeset(dev)) -+ ret = drm_framebuffer_init(dev, &rfb->base, -+ &amdgpu_fb_funcs_atomic); -+ else -+ ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); - - if (ret) - goto err; -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index 3c50b3ff79541..cd6e99cf74a06 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1269,6 +1269,13 @@ void handle_cursor_update(struct drm_plane *plane, - attributes.rotation_angle = 0; - attributes.attribute_flags.value = 0; - -+ /* Enable cursor degamma ROM on DCN3+ for implicit sRGB degamma in DRM -+ * legacy gamma setup. -+ */ -+ if (crtc_state->cm_is_degamma_srgb && -+ adev->dm.dc->caps.color.dpp.gamma_corr) -+ attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1; -+ - attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0]; - - if (crtc_state->stream) { -diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile -index b9effadfc4bb7..89da06033332b 100644 ---- a/drivers/gpu/drm/amd/display/dc/Makefile -+++ b/drivers/gpu/drm/amd/display/dc/Makefile -@@ -82,3 +82,4 @@ DC_EDID += dc_edid_parser.o - AMD_DISPLAY_DMUB = $(addprefix $(AMDDALPATH)/dc/,$(DC_DMUB)) - AMD_DISPLAY_EDID = $(addprefix $(AMDDALPATH)/dc/,$(DC_EDID)) - AMD_DISPLAY_FILES += $(AMD_DISPLAY_DMUB) $(AMD_DISPLAY_EDID) -+ -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c -index 674ab6d9b31e4..16c05a24ac7aa 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c -@@ -1977,12 +1977,12 @@ enum dc_status dc_commit_streams(struct dc *dc, - } - } - -- /* Check for case where we are going from odm 2:1 to max -- * pipe scenario. For these cases, we will call -- * commit_minimal_transition_state() to exit out of odm 2:1 -- * first before processing new streams -+ /* ODM Combine 2:1 power optimization is only applied for single stream -+ * scenario, it uses extra pipes than needed to reduce power consumption -+ * We need to switch off this feature to make room for new streams. - */ -- if (stream_count == dc->res_pool->pipe_count) { -+ if (stream_count > dc->current_state->stream_count && -+ dc->current_state->stream_count == 1) { - for (i = 0; i < dc->res_pool->pipe_count; i++) { - pipe = &dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe->next_odm_pipe) -@@ -3361,6 +3361,45 @@ void dc_dmub_update_dirty_rect(struct dc *dc, - } - } - -+static void wait_for_outstanding_hw_updates(struct dc *dc, const struct dc_state *dc_context) -+{ -+/* -+ * This function calls HWSS to wait for any potentially double buffered -+ * operations to complete. It should be invoked as a pre-amble prior -+ * to full update programming before asserting any HW locks. -+ */ -+ int pipe_idx; -+ int opp_inst; -+ int opp_count = dc->res_pool->pipe_count; -+ struct hubp *hubp; -+ int mpcc_inst; -+ const struct pipe_ctx *pipe_ctx; -+ -+ for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) { -+ pipe_ctx = &dc_context->res_ctx.pipe_ctx[pipe_idx]; -+ -+ if (!pipe_ctx->stream) -+ continue; -+ -+ if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear) -+ pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg); -+ -+ hubp = pipe_ctx->plane_res.hubp; -+ if (!hubp) -+ continue; -+ -+ mpcc_inst = hubp->inst; -+ // MPCC inst is equal to pipe index in practice -+ for (opp_inst = 0; opp_inst < opp_count; opp_inst++) { -+ if (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst]) { -+ dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst); -+ dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false; -+ break; -+ } -+ } -+ } -+} -+ - static void commit_planes_for_stream(struct dc *dc, - struct dc_surface_update *srf_updates, - int surface_count, -@@ -3378,24 +3417,9 @@ static void commit_planes_for_stream(struct dc *dc, - // dc->current_state anymore, so we have to cache it before we apply - // the new SubVP context - subvp_prev_use = false; -- -- - dc_z10_restore(dc); -- -- if (update_type == UPDATE_TYPE_FULL) { -- /* wait for all double-buffer activity to clear on all pipes */ -- int pipe_idx; -- -- for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) { -- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; -- -- if (!pipe_ctx->stream) -- continue; -- -- if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear) -- pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg); -- } -- } -+ if (update_type == UPDATE_TYPE_FULL) -+ wait_for_outstanding_hw_updates(dc, context); - - if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) { - /* Optimize seamless boot flag keeps clocks and watermarks high until -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c -index 8e9384094f6d6..f2f55565e98a4 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c -@@ -212,8 +212,9 @@ struct mpcc *mpc1_insert_plane( - /* check insert_above_mpcc exist in tree->opp_list */ - struct mpcc *temp_mpcc = tree->opp_list; - -- while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc) -- temp_mpcc = temp_mpcc->mpcc_bot; -+ if (temp_mpcc != insert_above_mpcc) -+ while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc) -+ temp_mpcc = temp_mpcc->mpcc_bot; - if (temp_mpcc == NULL) - return NULL; - } -diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -index 4ef632864948e..fbc188812ccc9 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -@@ -1515,17 +1515,6 @@ static void dcn20_update_dchubp_dpp( - || plane_state->update_flags.bits.global_alpha_change - || plane_state->update_flags.bits.per_pixel_alpha_change) { - // MPCC inst is equal to pipe index in practice -- int mpcc_inst = hubp->inst; -- int opp_inst; -- int opp_count = dc->res_pool->pipe_count; -- -- for (opp_inst = 0; opp_inst < opp_count; opp_inst++) { -- if (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst]) { -- dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst); -- dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false; -- break; -- } -- } - hws->funcs.update_mpcc(dc, pipe_ctx); - } - -diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c -index 0f39ab9dc5b41..9e74b6e8b5732 100644 ---- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c -+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c -@@ -338,7 +338,9 @@ static void apply_below_the_range(struct core_freesync *core_freesync, - * - Delta for CEIL: delta_from_mid_point_in_us_1 - * - Delta for FLOOR: delta_from_mid_point_in_us_2 - */ -- if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) { -+ if (mid_point_frames_ceil && -+ (last_render_time_in_us / mid_point_frames_ceil) < -+ in_out_vrr->min_duration_in_us) { - /* Check for out of range. - * If using CEIL produces a value that is out of range, - * then we are forced to use FLOOR. -@@ -385,8 +387,9 @@ static void apply_below_the_range(struct core_freesync *core_freesync, - /* Either we've calculated the number of frames to insert, - * or we need to insert min duration frames - */ -- if (last_render_time_in_us / frames_to_insert < -- in_out_vrr->min_duration_in_us){ -+ if (frames_to_insert && -+ (last_render_time_in_us / frames_to_insert) < -+ in_out_vrr->min_duration_in_us){ - frames_to_insert -= (frames_to_insert > 1) ? - 1 : 0; - } -diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c -index 82fd3c8adee13..5b2c2b7745bf0 100644 ---- a/drivers/gpu/drm/ast/ast_post.c -+++ b/drivers/gpu/drm/ast/ast_post.c -@@ -291,7 +291,7 @@ static void ast_init_dram_reg(struct drm_device *dev) - ; - } while (ast_read32(ast, 0x10100) != 0xa8); - } else {/* AST2100/1100 */ -- if (ast->chip == AST2100 || ast->chip == 2200) -+ if (ast->chip == AST2100 || ast->chip == AST2200) - dram_reg_info = ast2100_dram_table_data; - else - dram_reg_info = ast1100_dram_table_data; -diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h -index 6b5d4ea22b673..107f465a27b9e 100644 ---- a/drivers/gpu/drm/i915/gt/intel_engine_types.h -+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h -@@ -56,6 +56,7 @@ struct intel_breadcrumbs; - - typedef u32 intel_engine_mask_t; - #define ALL_ENGINES ((intel_engine_mask_t)~0ul) -+#define VIRTUAL_ENGINES BIT(BITS_PER_TYPE(intel_engine_mask_t) - 1) - - struct intel_hw_status_page { - struct list_head timelines; -diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c -index 0ec07dad1dcf1..fecdc7ea78ebd 100644 ---- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c -+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c -@@ -5111,6 +5111,9 @@ guc_create_virtual(struct intel_engine_cs **siblings, unsigned int count, - - ve->base.flags = I915_ENGINE_IS_VIRTUAL; - -+ BUILD_BUG_ON(ilog2(VIRTUAL_ENGINES) < I915_NUM_ENGINES); -+ ve->base.mask = VIRTUAL_ENGINES; -+ - intel_context_init(&ve->context, &ve->base); - - for (n = 0; n < count; n++) { -diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c -index 80c60754a5c1c..79bf1be68d8cf 100644 ---- a/drivers/gpu/drm/i915/gvt/gtt.c -+++ b/drivers/gpu/drm/i915/gvt/gtt.c -@@ -1179,6 +1179,7 @@ static int is_2MB_gtt_possible(struct intel_vgpu *vgpu, - { - const struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; - kvm_pfn_t pfn; -+ int ret; - - if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M)) - return 0; -@@ -1188,7 +1189,13 @@ static int is_2MB_gtt_possible(struct intel_vgpu *vgpu, - pfn = gfn_to_pfn(vgpu->vfio_device.kvm, ops->get_pfn(entry)); - if (is_error_noslot_pfn(pfn)) - return -EINVAL; -- return PageTransHuge(pfn_to_page(pfn)); -+ -+ if (!pfn_valid(pfn)) -+ return -EINVAL; -+ -+ ret = PageTransHuge(pfn_to_page(pfn)); -+ kvm_release_pfn_clean(pfn); -+ return ret; - } - - static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, -@@ -2880,24 +2887,6 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old) - ggtt_invalidate(gvt->gt); - } - --/** -- * intel_vgpu_reset_gtt - reset the all GTT related status -- * @vgpu: a vGPU -- * -- * This function is called from vfio core to reset reset all -- * GTT related status, including GGTT, PPGTT, scratch page. -- * -- */ --void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu) --{ -- /* Shadow pages are only created when there is no page -- * table tracking data, so remove page tracking data after -- * removing the shadow pages. -- */ -- intel_vgpu_destroy_all_ppgtt_mm(vgpu); -- intel_vgpu_reset_ggtt(vgpu, true); --} -- - /** - * intel_gvt_restore_ggtt - restore all vGPU's ggtt entries - * @gvt: intel gvt device -diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h -index a3b0f59ec8bd9..4cb183e06e95a 100644 ---- a/drivers/gpu/drm/i915/gvt/gtt.h -+++ b/drivers/gpu/drm/i915/gvt/gtt.h -@@ -224,7 +224,6 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old); - void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu); - - int intel_gvt_init_gtt(struct intel_gvt *gvt); --void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu); - void intel_gvt_clean_gtt(struct intel_gvt *gvt); - - struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu, -diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c -index 803cd2ad4deb5..7ce126a01cbf6 100644 ---- a/drivers/gpu/drm/i915/i915_request.c -+++ b/drivers/gpu/drm/i915/i915_request.c -@@ -134,9 +134,7 @@ static void i915_fence_release(struct dma_fence *fence) - i915_sw_fence_fini(&rq->semaphore); - - /* -- * Keep one request on each engine for reserved use under mempressure -- * do not use with virtual engines as this really is only needed for -- * kernel contexts. -+ * Keep one request on each engine for reserved use under mempressure. - * - * We do not hold a reference to the engine here and so have to be - * very careful in what rq->engine we poke. The virtual engine is -@@ -166,8 +164,7 @@ static void i915_fence_release(struct dma_fence *fence) - * know that if the rq->execution_mask is a single bit, rq->engine - * can be a physical engine with the exact corresponding mask. - */ -- if (!intel_engine_is_virtual(rq->engine) && -- is_power_of_2(rq->execution_mask) && -+ if (is_power_of_2(rq->execution_mask) && - !cmpxchg(&rq->engine->request_pool, NULL, rq)) - return; - -diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c -index 3bcc9c0f20193..7ed2516b6de05 100644 ---- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c -+++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c -@@ -611,6 +611,14 @@ static void mxsfb_plane_overlay_atomic_update(struct drm_plane *plane, - writel(ctrl, mxsfb->base + LCDC_AS_CTRL); - } - -+static void mxsfb_plane_overlay_atomic_disable(struct drm_plane *plane, -+ struct drm_atomic_state *state) -+{ -+ struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(plane->dev); -+ -+ writel(0, mxsfb->base + LCDC_AS_CTRL); -+} -+ - static bool mxsfb_format_mod_supported(struct drm_plane *plane, - uint32_t format, - uint64_t modifier) -@@ -626,6 +634,7 @@ static const struct drm_plane_helper_funcs mxsfb_plane_primary_helper_funcs = { - static const struct drm_plane_helper_funcs mxsfb_plane_overlay_helper_funcs = { - .atomic_check = mxsfb_plane_atomic_check, - .atomic_update = mxsfb_plane_overlay_atomic_update, -+ .atomic_disable = mxsfb_plane_overlay_atomic_disable, - }; - - static const struct drm_plane_funcs mxsfb_plane_funcs = { -diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c -index da45215a933d0..bc8c1e9a845fd 100644 ---- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c -+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c -@@ -43,13 +43,9 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev, - struct virtio_gpu_fence *fence, - uint32_t ring_idx) - { -- struct virtio_gpu_fpriv *vfpriv = file->driver_priv; - struct virtio_gpu_fence_event *e = NULL; - int ret; - -- if (!(vfpriv->ring_idx_mask & BIT_ULL(ring_idx))) -- return 0; -- - e = kzalloc(sizeof(*e), GFP_KERNEL); - if (!e) - return -ENOMEM; -@@ -121,6 +117,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, - struct virtio_gpu_device *vgdev = dev->dev_private; - struct virtio_gpu_fpriv *vfpriv = file->driver_priv; - struct virtio_gpu_fence *out_fence; -+ bool drm_fence_event; - int ret; - uint32_t *bo_handles = NULL; - void __user *user_bo_handles = NULL; -@@ -216,15 +213,24 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, - goto out_memdup; - } - -- out_fence = virtio_gpu_fence_alloc(vgdev, fence_ctx, ring_idx); -- if(!out_fence) { -- ret = -ENOMEM; -- goto out_unresv; -- } -+ if ((exbuf->flags & VIRTGPU_EXECBUF_RING_IDX) && -+ (vfpriv->ring_idx_mask & BIT_ULL(ring_idx))) -+ drm_fence_event = true; -+ else -+ drm_fence_event = false; - -- ret = virtio_gpu_fence_event_create(dev, file, out_fence, ring_idx); -- if (ret) -- goto out_unresv; -+ if ((exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_OUT) || -+ exbuf->num_bo_handles || -+ drm_fence_event) -+ out_fence = virtio_gpu_fence_alloc(vgdev, fence_ctx, ring_idx); -+ else -+ out_fence = NULL; -+ -+ if (drm_fence_event) { -+ ret = virtio_gpu_fence_event_create(dev, file, out_fence, ring_idx); -+ if (ret) -+ goto out_unresv; -+ } - - if (out_fence_fd >= 0) { - sync_file = sync_file_create(&out_fence->f); -diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c -index 9cf186362ae2f..3f08cd4a5c280 100644 ---- a/drivers/hwspinlock/qcom_hwspinlock.c -+++ b/drivers/hwspinlock/qcom_hwspinlock.c -@@ -69,9 +69,18 @@ static const struct hwspinlock_ops qcom_hwspinlock_ops = { - .unlock = qcom_hwspinlock_unlock, - }; - -+static const struct regmap_config sfpb_mutex_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = 0x100, -+ .fast_io = true, -+}; -+ - static const struct qcom_hwspinlock_of_data of_sfpb_mutex = { - .offset = 0x4, - .stride = 0x4, -+ .regmap_config = &sfpb_mutex_config, - }; - - static const struct regmap_config tcsr_msm8226_mutex_config = { -diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c -index afcdfbb002ff3..9c1489c0dae13 100644 ---- a/drivers/input/keyboard/tca6416-keypad.c -+++ b/drivers/input/keyboard/tca6416-keypad.c -@@ -148,7 +148,7 @@ static int tca6416_keys_open(struct input_dev *dev) - if (chip->use_polling) - schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100)); - else -- enable_irq(chip->irqnum); -+ enable_irq(chip->client->irq); - - return 0; - } -@@ -160,7 +160,7 @@ static void tca6416_keys_close(struct input_dev *dev) - if (chip->use_polling) - cancel_delayed_work_sync(&chip->dwork); - else -- disable_irq(chip->irqnum); -+ disable_irq(chip->client->irq); - } - - static int tca6416_setup_registers(struct tca6416_keypad_chip *chip) -@@ -266,12 +266,7 @@ static int tca6416_keypad_probe(struct i2c_client *client, - goto fail1; - - if (!chip->use_polling) { -- if (pdata->irq_is_gpio) -- chip->irqnum = gpio_to_irq(client->irq); -- else -- chip->irqnum = client->irq; -- -- error = request_threaded_irq(chip->irqnum, NULL, -+ error = request_threaded_irq(client->irq, NULL, - tca6416_keys_isr, - IRQF_TRIGGER_FALLING | - IRQF_ONESHOT | IRQF_NO_AUTOEN, -@@ -279,7 +274,7 @@ static int tca6416_keypad_probe(struct i2c_client *client, - if (error) { - dev_dbg(&client->dev, - "Unable to claim irq %d; error %d\n", -- chip->irqnum, error); -+ client->irq, error); - goto fail1; - } - } -@@ -297,10 +292,8 @@ static int tca6416_keypad_probe(struct i2c_client *client, - return 0; - - fail2: -- if (!chip->use_polling) { -- free_irq(chip->irqnum, chip); -- enable_irq(chip->irqnum); -- } -+ if (!chip->use_polling) -+ free_irq(client->irq, chip); - fail1: - input_free_device(input); - kfree(chip); -@@ -311,10 +304,8 @@ static void tca6416_keypad_remove(struct i2c_client *client) - { - struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); - -- if (!chip->use_polling) { -- free_irq(chip->irqnum, chip); -- enable_irq(chip->irqnum); -- } -+ if (!chip->use_polling) -+ free_irq(client->irq, chip); - - input_unregister_device(chip->input); - kfree(chip); -@@ -324,10 +315,9 @@ static void tca6416_keypad_remove(struct i2c_client *client) - static int tca6416_keypad_suspend(struct device *dev) - { - struct i2c_client *client = to_i2c_client(dev); -- struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); - - if (device_may_wakeup(dev)) -- enable_irq_wake(chip->irqnum); -+ enable_irq_wake(client->irq); - - return 0; - } -@@ -335,10 +325,9 @@ static int tca6416_keypad_suspend(struct device *dev) - static int tca6416_keypad_resume(struct device *dev) - { - struct i2c_client *client = to_i2c_client(dev); -- struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); - - if (device_may_wakeup(dev)) -- disable_irq_wake(chip->irqnum); -+ disable_irq_wake(client->irq); - - return 0; - } -diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c -index e47ab6c1177f5..f24b174c72667 100644 ---- a/drivers/input/misc/iqs7222.c -+++ b/drivers/input/misc/iqs7222.c -@@ -1381,9 +1381,6 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222) - if (error) - return error; - -- sys_setup &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK; -- sys_setup &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK; -- - for (i = 0; i < IQS7222_NUM_RETRIES; i++) { - /* - * Trigger ATI from streaming and normal-power modes so that -@@ -1561,8 +1558,11 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir) - return error; - } - -- if (dir == READ) -+ if (dir == READ) { -+ iqs7222->sys_setup[0] &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK; -+ iqs7222->sys_setup[0] &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK; - return 0; -+ } - - return iqs7222_ati_trigger(iqs7222); - } -diff --git a/drivers/mailbox/qcom-ipcc.c b/drivers/mailbox/qcom-ipcc.c -index 7e27acf6c0cca..f597a1bd56847 100644 ---- a/drivers/mailbox/qcom-ipcc.c -+++ b/drivers/mailbox/qcom-ipcc.c -@@ -227,10 +227,8 @@ static int qcom_ipcc_setup_mbox(struct qcom_ipcc *ipcc, - ret = of_parse_phandle_with_args(client_dn, "mboxes", - "#mbox-cells", j, &curr_ph); - of_node_put(curr_ph.np); -- if (!ret && curr_ph.np == controller_dn) { -+ if (!ret && curr_ph.np == controller_dn) - ipcc->num_chans++; -- break; -- } - } - } - -diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -index d8418d7fcc372..39661e23d7d4f 100644 ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -272,6 +272,7 @@ struct brcmnand_controller { - const unsigned int *page_sizes; - unsigned int page_size_shift; - unsigned int max_oob; -+ u32 ecc_level_shift; - u32 features; - - /* for low-power standby/resume only */ -@@ -596,6 +597,34 @@ enum { - INTFC_CTLR_READY = BIT(31), - }; - -+/*********************************************************************** -+ * NAND ACC CONTROL bitfield -+ * -+ * Some bits have remained constant throughout hardware revision, while -+ * others have shifted around. -+ ***********************************************************************/ -+ -+/* Constant for all versions (where supported) */ -+enum { -+ /* See BRCMNAND_HAS_CACHE_MODE */ -+ ACC_CONTROL_CACHE_MODE = BIT(22), -+ -+ /* See BRCMNAND_HAS_PREFETCH */ -+ ACC_CONTROL_PREFETCH = BIT(23), -+ -+ ACC_CONTROL_PAGE_HIT = BIT(24), -+ ACC_CONTROL_WR_PREEMPT = BIT(25), -+ ACC_CONTROL_PARTIAL_PAGE = BIT(26), -+ ACC_CONTROL_RD_ERASED = BIT(27), -+ ACC_CONTROL_FAST_PGM_RDIN = BIT(28), -+ ACC_CONTROL_WR_ECC = BIT(30), -+ ACC_CONTROL_RD_ECC = BIT(31), -+}; -+ -+#define ACC_CONTROL_ECC_SHIFT 16 -+/* Only for v7.2 */ -+#define ACC_CONTROL_ECC_EXT_SHIFT 13 -+ - static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) - { - #if IS_ENABLED(CONFIG_MTD_NAND_BRCMNAND_BCMA) -@@ -737,6 +766,12 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl) - else if (of_property_read_bool(ctrl->dev->of_node, "brcm,nand-has-wp")) - ctrl->features |= BRCMNAND_HAS_WP; - -+ /* v7.2 has different ecc level shift in the acc register */ -+ if (ctrl->nand_version == 0x0702) -+ ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT; -+ else -+ ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT; -+ - return 0; - } - -@@ -931,30 +966,6 @@ static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl) - return 0; - } - --/*********************************************************************** -- * NAND ACC CONTROL bitfield -- * -- * Some bits have remained constant throughout hardware revision, while -- * others have shifted around. -- ***********************************************************************/ -- --/* Constant for all versions (where supported) */ --enum { -- /* See BRCMNAND_HAS_CACHE_MODE */ -- ACC_CONTROL_CACHE_MODE = BIT(22), -- -- /* See BRCMNAND_HAS_PREFETCH */ -- ACC_CONTROL_PREFETCH = BIT(23), -- -- ACC_CONTROL_PAGE_HIT = BIT(24), -- ACC_CONTROL_WR_PREEMPT = BIT(25), -- ACC_CONTROL_PARTIAL_PAGE = BIT(26), -- ACC_CONTROL_RD_ERASED = BIT(27), -- ACC_CONTROL_FAST_PGM_RDIN = BIT(28), -- ACC_CONTROL_WR_ECC = BIT(30), -- ACC_CONTROL_RD_ECC = BIT(31), --}; -- - static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl) - { - if (ctrl->nand_version == 0x0702) -@@ -967,18 +978,15 @@ static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl) - return GENMASK(4, 0); - } - --#define NAND_ACC_CONTROL_ECC_SHIFT 16 --#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13 -- - static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl) - { - u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f; - -- mask <<= NAND_ACC_CONTROL_ECC_SHIFT; -+ mask <<= ACC_CONTROL_ECC_SHIFT; - - /* v7.2 includes additional ECC levels */ -- if (ctrl->nand_version >= 0x0702) -- mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT; -+ if (ctrl->nand_version == 0x0702) -+ mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT; - - return mask; - } -@@ -992,8 +1000,8 @@ static void brcmnand_set_ecc_enabled(struct brcmnand_host *host, int en) - - if (en) { - acc_control |= ecc_flags; /* enable RD/WR ECC */ -- acc_control |= host->hwcfg.ecc_level -- << NAND_ACC_CONTROL_ECC_SHIFT; -+ acc_control &= ~brcmnand_ecc_level_mask(ctrl); -+ acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift; - } else { - acc_control &= ~ecc_flags; /* disable RD/WR ECC */ - acc_control &= ~brcmnand_ecc_level_mask(ctrl); -@@ -1072,6 +1080,14 @@ static int bcmnand_ctrl_poll_status(struct brcmnand_controller *ctrl, - cpu_relax(); - } while (time_after(limit, jiffies)); - -+ /* -+ * do a final check after time out in case the CPU was busy and the driver -+ * did not get enough time to perform the polling to avoid false alarms -+ */ -+ val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); -+ if ((val & mask) == expected_val) -+ return 0; -+ - dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n", - expected_val, val & mask); - -@@ -1461,19 +1477,33 @@ static int write_oob_to_regs(struct brcmnand_controller *ctrl, int i, - const u8 *oob, int sas, int sector_1k) - { - int tbytes = sas << sector_1k; -- int j; -+ int j, k = 0; -+ u32 last = 0xffffffff; -+ u8 *plast = (u8 *)&last; - - /* Adjust OOB values for 1K sector size */ - if (sector_1k && (i & 0x01)) - tbytes = max(0, tbytes - (int)ctrl->max_oob); - tbytes = min_t(int, tbytes, ctrl->max_oob); - -- for (j = 0; j < tbytes; j += 4) -+ /* -+ * tbytes may not be multiple of words. Make sure we don't read out of -+ * the boundary and stop at last word. -+ */ -+ for (j = 0; (j + 3) < tbytes; j += 4) - oob_reg_write(ctrl, j, - (oob[j + 0] << 24) | - (oob[j + 1] << 16) | - (oob[j + 2] << 8) | - (oob[j + 3] << 0)); -+ -+ /* handle the remaing bytes */ -+ while (j < tbytes) -+ plast[k++] = oob[j++]; -+ -+ if (tbytes & 0x3) -+ oob_reg_write(ctrl, (tbytes & ~0x3), (__force u32)cpu_to_be32(last)); -+ - return tbytes; - } - -@@ -1592,7 +1622,17 @@ static void brcmnand_send_cmd(struct brcmnand_host *host, int cmd) - - dev_dbg(ctrl->dev, "send native cmd %d addr 0x%llx\n", cmd, cmd_addr); - -- BUG_ON(ctrl->cmd_pending != 0); -+ /* -+ * If we came here through _panic_write and there is a pending -+ * command, try to wait for it. If it times out, rather than -+ * hitting BUG_ON, just return so we don't crash while crashing. -+ */ -+ if (oops_in_progress) { -+ if (ctrl->cmd_pending && -+ bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0)) -+ return; -+ } else -+ BUG_ON(ctrl->cmd_pending != 0); - ctrl->cmd_pending = cmd; - - ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0); -@@ -2561,7 +2601,7 @@ static int brcmnand_set_cfg(struct brcmnand_host *host, - tmp &= ~brcmnand_ecc_level_mask(ctrl); - tmp &= ~brcmnand_spare_area_mask(ctrl); - if (ctrl->nand_version >= 0x0302) { -- tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; -+ tmp |= cfg->ecc_level << ctrl->ecc_level_shift; - tmp |= cfg->spare_area_size; - } - nand_writereg(ctrl, acc_control_offs, tmp); -diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c -index ffaa240552598..b7c775b615e85 100644 ---- a/drivers/mtd/spi-nor/winbond.c -+++ b/drivers/mtd/spi-nor/winbond.c -@@ -120,8 +120,9 @@ static const struct flash_info winbond_nor_parts[] = { - NO_SFDP_FLAGS(SECT_4K) }, - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16) - NO_SFDP_FLAGS(SECT_4K) }, -- { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256) -- NO_SFDP_FLAGS(SECT_4K) }, -+ { "w25q128", INFO(0xef4018, 0, 0, 0) -+ PARSE_SFDP -+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, - { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) - .fixups = &w25q256_fixups }, -diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h -index fb3cd4c78faa8..06e0ebfe652a4 100644 ---- a/drivers/net/dsa/sja1105/sja1105.h -+++ b/drivers/net/dsa/sja1105/sja1105.h -@@ -132,6 +132,8 @@ struct sja1105_info { - int max_frame_mem; - int num_ports; - bool multiple_cascade_ports; -+ /* Every {port, TXQ} has its own CBS shaper */ -+ bool fixed_cbs_mapping; - enum dsa_tag_protocol tag_proto; - const struct sja1105_dynamic_table_ops *dyn_ops; - const struct sja1105_table_ops *static_ops; -@@ -262,6 +264,8 @@ struct sja1105_private { - * the switch doesn't confuse them with one another. - */ - struct mutex mgmt_lock; -+ /* Serializes accesses to the FDB */ -+ struct mutex fdb_lock; - /* PTP two-step TX timestamp ID, and its serialization lock */ - spinlock_t ts_id_lock; - u8 ts_id; -diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c -index 7729d3f8b7f50..984c0e604e8de 100644 ---- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c -+++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c -@@ -1175,18 +1175,15 @@ const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = { - - static int - sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, -- struct sja1105_dyn_cmd *cmd, -- const struct sja1105_dynamic_table_ops *ops) -+ const struct sja1105_dynamic_table_ops *ops, -+ void *entry, bool check_valident, -+ bool check_errors) - { - u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {}; -+ struct sja1105_dyn_cmd cmd = {}; - int rc; - -- /* We don't _need_ to read the full entry, just the command area which -- * is a fixed SJA1105_SIZE_DYN_CMD. But our cmd_packing() API expects a -- * buffer that contains the full entry too. Additionally, our API -- * doesn't really know how many bytes into the buffer does the command -- * area really begin. So just read back the whole entry. -- */ -+ /* Read back the whole entry + command structure. */ - rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf, - ops->packed_size); - if (rc) -@@ -1195,11 +1192,25 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, - /* Unpack the command structure, and return it to the caller in case it - * needs to perform further checks on it (VALIDENT). - */ -- memset(cmd, 0, sizeof(*cmd)); -- ops->cmd_packing(packed_buf, cmd, UNPACK); -+ ops->cmd_packing(packed_buf, &cmd, UNPACK); - - /* Hardware hasn't cleared VALID => still working on it */ -- return cmd->valid ? -EAGAIN : 0; -+ if (cmd.valid) -+ return -EAGAIN; -+ -+ if (check_valident && !cmd.valident && !(ops->access & OP_VALID_ANYWAY)) -+ return -ENOENT; -+ -+ if (check_errors && cmd.errors) -+ return -EINVAL; -+ -+ /* Don't dereference possibly NULL pointer - maybe caller -+ * only wanted to see whether the entry existed or not. -+ */ -+ if (entry) -+ ops->entry_packing(packed_buf, entry, UNPACK); -+ -+ return 0; - } - - /* Poll the dynamic config entry's control area until the hardware has -@@ -1208,16 +1219,19 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, - */ - static int - sja1105_dynamic_config_wait_complete(struct sja1105_private *priv, -- struct sja1105_dyn_cmd *cmd, -- const struct sja1105_dynamic_table_ops *ops) -+ const struct sja1105_dynamic_table_ops *ops, -+ void *entry, bool check_valident, -+ bool check_errors) - { -- int rc; -- -- return read_poll_timeout(sja1105_dynamic_config_poll_valid, -- rc, rc != -EAGAIN, -- SJA1105_DYNAMIC_CONFIG_SLEEP_US, -- SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, -- false, priv, cmd, ops); -+ int err, rc; -+ -+ err = read_poll_timeout(sja1105_dynamic_config_poll_valid, -+ rc, rc != -EAGAIN, -+ SJA1105_DYNAMIC_CONFIG_SLEEP_US, -+ SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, -+ false, priv, ops, entry, check_valident, -+ check_errors); -+ return err < 0 ? err : rc; - } - - /* Provides read access to the settings through the dynamic interface -@@ -1286,25 +1300,14 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv, - mutex_lock(&priv->dynamic_config_lock); - rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, - ops->packed_size); -- if (rc < 0) { -- mutex_unlock(&priv->dynamic_config_lock); -- return rc; -- } -- -- rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); -- mutex_unlock(&priv->dynamic_config_lock); - if (rc < 0) -- return rc; -+ goto out; - -- if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY)) -- return -ENOENT; -+ rc = sja1105_dynamic_config_wait_complete(priv, ops, entry, true, false); -+out: -+ mutex_unlock(&priv->dynamic_config_lock); - -- /* Don't dereference possibly NULL pointer - maybe caller -- * only wanted to see whether the entry existed or not. -- */ -- if (entry) -- ops->entry_packing(packed_buf, entry, UNPACK); -- return 0; -+ return rc; - } - - int sja1105_dynamic_config_write(struct sja1105_private *priv, -@@ -1356,22 +1359,14 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv, - mutex_lock(&priv->dynamic_config_lock); - rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, - ops->packed_size); -- if (rc < 0) { -- mutex_unlock(&priv->dynamic_config_lock); -- return rc; -- } -- -- rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); -- mutex_unlock(&priv->dynamic_config_lock); - if (rc < 0) -- return rc; -+ goto out; - -- cmd = (struct sja1105_dyn_cmd) {0}; -- ops->cmd_packing(packed_buf, &cmd, UNPACK); -- if (cmd.errors) -- return -EINVAL; -+ rc = sja1105_dynamic_config_wait_complete(priv, ops, NULL, false, true); -+out: -+ mutex_unlock(&priv->dynamic_config_lock); - -- return 0; -+ return rc; - } - - static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly) -diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c -index 947e8f7c09880..f1f1368e8146f 100644 ---- a/drivers/net/dsa/sja1105/sja1105_main.c -+++ b/drivers/net/dsa/sja1105/sja1105_main.c -@@ -1805,6 +1805,7 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port, - struct dsa_db db) - { - struct sja1105_private *priv = ds->priv; -+ int rc; - - if (!vid) { - switch (db.type) { -@@ -1819,12 +1820,16 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port, - } - } - -- return priv->info->fdb_add_cmd(ds, port, addr, vid); -+ mutex_lock(&priv->fdb_lock); -+ rc = priv->info->fdb_add_cmd(ds, port, addr, vid); -+ mutex_unlock(&priv->fdb_lock); -+ -+ return rc; - } - --static int sja1105_fdb_del(struct dsa_switch *ds, int port, -- const unsigned char *addr, u16 vid, -- struct dsa_db db) -+static int __sja1105_fdb_del(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db) - { - struct sja1105_private *priv = ds->priv; - -@@ -1844,6 +1849,20 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port, - return priv->info->fdb_del_cmd(ds, port, addr, vid); - } - -+static int sja1105_fdb_del(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db) -+{ -+ struct sja1105_private *priv = ds->priv; -+ int rc; -+ -+ mutex_lock(&priv->fdb_lock); -+ rc = __sja1105_fdb_del(ds, port, addr, vid, db); -+ mutex_unlock(&priv->fdb_lock); -+ -+ return rc; -+} -+ - static int sja1105_fdb_dump(struct dsa_switch *ds, int port, - dsa_fdb_dump_cb_t *cb, void *data) - { -@@ -1875,13 +1894,14 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port, - if (!(l2_lookup.destports & BIT(port))) - continue; - -- /* We need to hide the FDB entry for unknown multicast */ -- if (l2_lookup.macaddr == SJA1105_UNKNOWN_MULTICAST && -- l2_lookup.mask_macaddr == SJA1105_UNKNOWN_MULTICAST) -- continue; -- - u64_to_ether_addr(l2_lookup.macaddr, macaddr); - -+ /* Hardware FDB is shared for fdb and mdb, "bridge fdb show" -+ * only wants to see unicast -+ */ -+ if (is_multicast_ether_addr(macaddr)) -+ continue; -+ - /* We need to hide the dsa_8021q VLANs from the user. */ - if (vid_is_dsa_8021q(l2_lookup.vlanid)) - l2_lookup.vlanid = 0; -@@ -1905,6 +1925,8 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) - }; - int i; - -+ mutex_lock(&priv->fdb_lock); -+ - for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) { - struct sja1105_l2_lookup_entry l2_lookup = {0}; - u8 macaddr[ETH_ALEN]; -@@ -1918,7 +1940,7 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) - if (rc) { - dev_err(ds->dev, "Failed to read FDB: %pe\n", - ERR_PTR(rc)); -- return; -+ break; - } - - if (!(l2_lookup.destports & BIT(port))) -@@ -1930,14 +1952,16 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) - - u64_to_ether_addr(l2_lookup.macaddr, macaddr); - -- rc = sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db); -+ rc = __sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db); - if (rc) { - dev_err(ds->dev, - "Failed to delete FDB entry %pM vid %lld: %pe\n", - macaddr, l2_lookup.vlanid, ERR_PTR(rc)); -- return; -+ break; - } - } -+ -+ mutex_unlock(&priv->fdb_lock); - } - - static int sja1105_mdb_add(struct dsa_switch *ds, int port, -@@ -2122,11 +2146,36 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port, - } - - #define BYTES_PER_KBIT (1000LL / 8) -+/* Port 0 (the uC port) does not have CBS shapers */ -+#define SJA1110_FIXED_CBS(port, prio) ((((port) - 1) * SJA1105_NUM_TC) + (prio)) -+ -+static int sja1105_find_cbs_shaper(struct sja1105_private *priv, -+ int port, int prio) -+{ -+ int i; -+ -+ if (priv->info->fixed_cbs_mapping) { -+ i = SJA1110_FIXED_CBS(port, prio); -+ if (i >= 0 && i < priv->info->num_cbs_shapers) -+ return i; -+ -+ return -1; -+ } -+ -+ for (i = 0; i < priv->info->num_cbs_shapers; i++) -+ if (priv->cbs[i].port == port && priv->cbs[i].prio == prio) -+ return i; -+ -+ return -1; -+} - - static int sja1105_find_unused_cbs_shaper(struct sja1105_private *priv) - { - int i; - -+ if (priv->info->fixed_cbs_mapping) -+ return -1; -+ - for (i = 0; i < priv->info->num_cbs_shapers; i++) - if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope) - return i; -@@ -2157,14 +2206,20 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port, - { - struct sja1105_private *priv = ds->priv; - struct sja1105_cbs_entry *cbs; -+ s64 port_transmit_rate_kbps; - int index; - - if (!offload->enable) - return sja1105_delete_cbs_shaper(priv, port, offload->queue); - -- index = sja1105_find_unused_cbs_shaper(priv); -- if (index < 0) -- return -ENOSPC; -+ /* The user may be replacing an existing shaper */ -+ index = sja1105_find_cbs_shaper(priv, port, offload->queue); -+ if (index < 0) { -+ /* That isn't the case - see if we can allocate a new one */ -+ index = sja1105_find_unused_cbs_shaper(priv); -+ if (index < 0) -+ return -ENOSPC; -+ } - - cbs = &priv->cbs[index]; - cbs->port = port; -@@ -2174,9 +2229,17 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port, - */ - cbs->credit_hi = offload->hicredit; - cbs->credit_lo = abs(offload->locredit); -- /* User space is in kbits/sec, hardware in bytes/sec */ -- cbs->idle_slope = offload->idleslope * BYTES_PER_KBIT; -- cbs->send_slope = abs(offload->sendslope * BYTES_PER_KBIT); -+ /* User space is in kbits/sec, while the hardware in bytes/sec times -+ * link speed. Since the given offload->sendslope is good only for the -+ * current link speed anyway, and user space is likely to reprogram it -+ * when that changes, don't even bother to track the port's link speed, -+ * but deduce the port transmit rate from idleslope - sendslope. -+ */ -+ port_transmit_rate_kbps = offload->idleslope - offload->sendslope; -+ cbs->idle_slope = div_s64(offload->idleslope * BYTES_PER_KBIT, -+ port_transmit_rate_kbps); -+ cbs->send_slope = div_s64(abs(offload->sendslope * BYTES_PER_KBIT), -+ port_transmit_rate_kbps); - /* Convert the negative values from 64-bit 2's complement - * to 32-bit 2's complement (for the case of 0x80000000 whose - * negative is still negative). -@@ -2241,6 +2304,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, - int rc, i; - s64 now; - -+ mutex_lock(&priv->fdb_lock); - mutex_lock(&priv->mgmt_lock); - - mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; -@@ -2355,6 +2419,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, - goto out; - out: - mutex_unlock(&priv->mgmt_lock); -+ mutex_unlock(&priv->fdb_lock); - - return rc; - } -@@ -2924,7 +2989,9 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, - { - struct sja1105_l2_lookup_entry *l2_lookup; - struct sja1105_table *table; -- int match; -+ int match, rc; -+ -+ mutex_lock(&priv->fdb_lock); - - table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; - l2_lookup = table->entries; -@@ -2937,7 +3004,8 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, - if (match == table->entry_count) { - NL_SET_ERR_MSG_MOD(extack, - "Could not find FDB entry for unknown multicast"); -- return -ENOSPC; -+ rc = -ENOSPC; -+ goto out; - } - - if (flags.val & BR_MCAST_FLOOD) -@@ -2945,10 +3013,13 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, - else - l2_lookup[match].destports &= ~BIT(to); - -- return sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, -- l2_lookup[match].index, -- &l2_lookup[match], -- true); -+ rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, -+ l2_lookup[match].index, -+ &l2_lookup[match], true); -+out: -+ mutex_unlock(&priv->fdb_lock); -+ -+ return rc; - } - - static int sja1105_port_pre_bridge_flags(struct dsa_switch *ds, int port, -@@ -3318,6 +3389,7 @@ static int sja1105_probe(struct spi_device *spi) - mutex_init(&priv->ptp_data.lock); - mutex_init(&priv->dynamic_config_lock); - mutex_init(&priv->mgmt_lock); -+ mutex_init(&priv->fdb_lock); - spin_lock_init(&priv->ts_id_lock); - - rc = sja1105_parse_dt(priv); -diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c -index d3c9ad6d39d46..e6b61aef4127c 100644 ---- a/drivers/net/dsa/sja1105/sja1105_spi.c -+++ b/drivers/net/dsa/sja1105/sja1105_spi.c -@@ -781,6 +781,7 @@ const struct sja1105_info sja1110a_info = { - .tag_proto = DSA_TAG_PROTO_SJA1110, - .can_limit_mcast_flood = true, - .multiple_cascade_ports = true, -+ .fixed_cbs_mapping = true, - .ptp_ts_bits = 32, - .ptpegr_ts_bytes = 8, - .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, -@@ -831,6 +832,7 @@ const struct sja1105_info sja1110b_info = { - .tag_proto = DSA_TAG_PROTO_SJA1110, - .can_limit_mcast_flood = true, - .multiple_cascade_ports = true, -+ .fixed_cbs_mapping = true, - .ptp_ts_bits = 32, - .ptpegr_ts_bytes = 8, - .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, -@@ -881,6 +883,7 @@ const struct sja1105_info sja1110c_info = { - .tag_proto = DSA_TAG_PROTO_SJA1110, - .can_limit_mcast_flood = true, - .multiple_cascade_ports = true, -+ .fixed_cbs_mapping = true, - .ptp_ts_bits = 32, - .ptpegr_ts_bytes = 8, - .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, -@@ -931,6 +934,7 @@ const struct sja1105_info sja1110d_info = { - .tag_proto = DSA_TAG_PROTO_SJA1110, - .can_limit_mcast_flood = true, - .multiple_cascade_ports = true, -+ .fixed_cbs_mapping = true, - .ptp_ts_bits = 32, - .ptpegr_ts_bytes = 8, - .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, -diff --git a/drivers/net/ethernet/adi/adin1110.c b/drivers/net/ethernet/adi/adin1110.c -index ecce5f7a549f2..ed2863ed6a5bb 100644 ---- a/drivers/net/ethernet/adi/adin1110.c -+++ b/drivers/net/ethernet/adi/adin1110.c -@@ -740,7 +740,7 @@ static int adin1110_broadcasts_filter(struct adin1110_port_priv *port_priv, - u32 port_rules = 0; - u8 mask[ETH_ALEN]; - -- memset(mask, 0xFF, ETH_ALEN); -+ eth_broadcast_addr(mask); - - if (accept_broadcast && port_priv->state == BR_STATE_FORWARDING) - port_rules = adin1110_port_rules(port_priv, true, true); -@@ -761,7 +761,7 @@ static int adin1110_set_mac_address(struct net_device *netdev, - return -EADDRNOTAVAIL; - - eth_hw_addr_set(netdev, dev_addr); -- memset(mask, 0xFF, ETH_ALEN); -+ eth_broadcast_addr(mask); - - mac_slot = (!port_priv->nr) ? ADIN_MAC_P1_ADDR_SLOT : ADIN_MAC_P2_ADDR_SLOT; - port_rules = adin1110_port_rules(port_priv, true, false); -@@ -1251,7 +1251,7 @@ static int adin1110_port_set_blocking_state(struct adin1110_port_priv *port_priv - goto out; - - /* Allow only BPDUs to be passed to the CPU */ -- memset(mask, 0xFF, ETH_ALEN); -+ eth_broadcast_addr(mask); - port_rules = adin1110_port_rules(port_priv, true, false); - ret = adin1110_write_mac_address(port_priv, mac_slot, mac, - mask, port_rules); -@@ -1365,8 +1365,8 @@ static int adin1110_fdb_add(struct adin1110_port_priv *port_priv, - return -ENOMEM; - - other_port = priv->ports[!port_priv->nr]; -- port_rules = adin1110_port_rules(port_priv, false, true); -- memset(mask, 0xFF, ETH_ALEN); -+ port_rules = adin1110_port_rules(other_port, false, true); -+ eth_broadcast_addr(mask); - - return adin1110_write_mac_address(other_port, mac_nr, (u8 *)fdb->addr, - mask, port_rules); -diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h -index 9c410f93a1039..1aa578c1ca4ad 100644 ---- a/drivers/net/ethernet/cadence/macb.h -+++ b/drivers/net/ethernet/cadence/macb.h -@@ -95,6 +95,8 @@ - #define GEM_SA4B 0x00A0 /* Specific4 Bottom */ - #define GEM_SA4T 0x00A4 /* Specific4 Top */ - #define GEM_WOL 0x00b8 /* Wake on LAN */ -+#define GEM_RXPTPUNI 0x00D4 /* PTP RX Unicast address */ -+#define GEM_TXPTPUNI 0x00D8 /* PTP TX Unicast address */ - #define GEM_EFTSH 0x00e8 /* PTP Event Frame Transmitted Seconds Register 47:32 */ - #define GEM_EFRSH 0x00ec /* PTP Event Frame Received Seconds Register 47:32 */ - #define GEM_PEFTSH 0x00f0 /* PTP Peer Event Frame Transmitted Seconds Register 47:32 */ -@@ -245,6 +247,8 @@ - #define MACB_TZQ_OFFSET 12 /* Transmit zero quantum pause frame */ - #define MACB_TZQ_SIZE 1 - #define MACB_SRTSM_OFFSET 15 /* Store Receive Timestamp to Memory */ -+#define MACB_PTPUNI_OFFSET 20 /* PTP Unicast packet enable */ -+#define MACB_PTPUNI_SIZE 1 - #define MACB_OSSMODE_OFFSET 24 /* Enable One Step Synchro Mode */ - #define MACB_OSSMODE_SIZE 1 - #define MACB_MIIONRGMII_OFFSET 28 /* MII Usage on RGMII Interface */ -diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c -index 5fb991835078a..54b032a46b48a 100644 ---- a/drivers/net/ethernet/cadence/macb_main.c -+++ b/drivers/net/ethernet/cadence/macb_main.c -@@ -288,6 +288,11 @@ static void macb_set_hwaddr(struct macb *bp) - top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); - macb_or_gem_writel(bp, SA1T, top); - -+ if (gem_has_ptp(bp)) { -+ gem_writel(bp, RXPTPUNI, bottom); -+ gem_writel(bp, TXPTPUNI, bottom); -+ } -+ - /* Clear unused address register sets */ - macb_or_gem_writel(bp, SA2B, 0); - macb_or_gem_writel(bp, SA2T, 0); -@@ -700,8 +705,6 @@ static void macb_mac_link_up(struct phylink_config *config, - if (rx_pause) - ctrl |= MACB_BIT(PAE); - -- macb_set_tx_clk(bp, speed); -- - /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down - * cleared the pipeline and control registers. - */ -@@ -721,8 +724,15 @@ static void macb_mac_link_up(struct phylink_config *config, - - spin_unlock_irqrestore(&bp->lock, flags); - -- /* Enable Rx and Tx */ -- macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(RE) | MACB_BIT(TE)); -+ if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) -+ macb_set_tx_clk(bp, speed); -+ -+ /* Enable Rx and Tx; Enable PTP unicast */ -+ ctrl = macb_readl(bp, NCR); -+ if (gem_has_ptp(bp)) -+ ctrl |= MACB_BIT(PTPUNI); -+ -+ macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE)); - - netif_tx_wake_all_queues(ndev); - } -diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c -index 2e6461b0ea8bc..a9409e3721ad7 100644 ---- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c -+++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c -@@ -492,7 +492,10 @@ static int gve_rx_append_frags(struct napi_struct *napi, - if (!skb) - return -1; - -- skb_shinfo(rx->ctx.skb_tail)->frag_list = skb; -+ if (rx->ctx.skb_tail == rx->ctx.skb_head) -+ skb_shinfo(rx->ctx.skb_head)->frag_list = skb; -+ else -+ rx->ctx.skb_tail->next = skb; - rx->ctx.skb_tail = skb; - num_frags = 0; - } -diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h -index fcb8b6dc5ab92..c693bb701ba3e 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h -+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h -@@ -797,6 +797,7 @@ struct hnae3_tc_info { - u8 max_tc; /* Total number of TCs */ - u8 num_tc; /* Total number of enabled TCs */ - bool mqprio_active; -+ bool dcb_ets_active; - }; - - #define HNAE3_MAX_DSCP 64 -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -index 69d1549e63a98..00eed9835cb55 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -@@ -1406,9 +1406,9 @@ int hns3_dbg_init(struct hnae3_handle *handle) - return 0; - - out: -- mutex_destroy(&handle->dbgfs_lock); - debugfs_remove_recursive(handle->hnae3_dbgfs); - handle->hnae3_dbgfs = NULL; -+ mutex_destroy(&handle->dbgfs_lock); - return ret; - } - -@@ -1416,6 +1416,9 @@ void hns3_dbg_uninit(struct hnae3_handle *handle) - { - u32 i; - -+ debugfs_remove_recursive(handle->hnae3_dbgfs); -+ handle->hnae3_dbgfs = NULL; -+ - for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) - if (handle->dbgfs_buf[i]) { - kvfree(handle->dbgfs_buf[i]); -@@ -1423,8 +1426,6 @@ void hns3_dbg_uninit(struct hnae3_handle *handle) - } - - mutex_destroy(&handle->dbgfs_lock); -- debugfs_remove_recursive(handle->hnae3_dbgfs); -- handle->hnae3_dbgfs = NULL; - } - - void hns3_dbg_register_debugfs(const char *debugfs_dir_name) -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -index 61f833d61f583..8aae179554a81 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -@@ -2102,8 +2102,12 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num, - */ - if (test_bit(HNS3_NIC_STATE_TX_PUSH_ENABLE, &priv->state) && num && - !ring->pending_buf && num <= HNS3_MAX_PUSH_BD_NUM && doorbell) { -+ /* This smp_store_release() pairs with smp_load_aquire() in -+ * hns3_nic_reclaim_desc(). Ensure that the BD valid bit -+ * is updated. -+ */ -+ smp_store_release(&ring->last_to_use, ring->next_to_use); - hns3_tx_push_bd(ring, num); -- WRITE_ONCE(ring->last_to_use, ring->next_to_use); - return; - } - -@@ -2114,6 +2118,11 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num, - return; - } - -+ /* This smp_store_release() pairs with smp_load_aquire() in -+ * hns3_nic_reclaim_desc(). Ensure that the BD valid bit is updated. -+ */ -+ smp_store_release(&ring->last_to_use, ring->next_to_use); -+ - if (ring->tqp->mem_base) - hns3_tx_mem_doorbell(ring); - else -@@ -2121,7 +2130,6 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num, - ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG); - - ring->pending_buf = 0; -- WRITE_ONCE(ring->last_to_use, ring->next_to_use); - } - - static void hns3_tsyn(struct net_device *netdev, struct sk_buff *skb, -@@ -3307,8 +3315,6 @@ static void hns3_set_default_feature(struct net_device *netdev) - - netdev->priv_flags |= IFF_UNICAST_FLT; - -- netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM; -- - netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | - NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | -@@ -3562,9 +3568,8 @@ static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i) - static bool hns3_nic_reclaim_desc(struct hns3_enet_ring *ring, - int *bytes, int *pkts, int budget) - { -- /* pair with ring->last_to_use update in hns3_tx_doorbell(), -- * smp_store_release() is not used in hns3_tx_doorbell() because -- * the doorbell operation already have the needed barrier operation. -+ /* This smp_load_acquire() pairs with smp_store_release() in -+ * hns3_tx_doorbell(). - */ - int ltu = smp_load_acquire(&ring->last_to_use); - int ntc = ring->next_to_clean; -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c -index cdf76fb58d45e..e22835ae8a941 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c -@@ -776,7 +776,9 @@ static int hns3_get_link_ksettings(struct net_device *netdev, - hns3_get_ksettings(h, cmd); - break; - case HNAE3_MEDIA_TYPE_FIBER: -- if (module_type == HNAE3_MODULE_TYPE_CR) -+ if (module_type == HNAE3_MODULE_TYPE_UNKNOWN) -+ cmd->base.port = PORT_OTHER; -+ else if (module_type == HNAE3_MODULE_TYPE_CR) - cmd->base.port = PORT_DA; - else - cmd->base.port = PORT_FIBRE; -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c -index 09362823140d5..2740f0d703e4f 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c -@@ -251,7 +251,7 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets) - int ret; - - if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) || -- hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE) -+ h->kinfo.tc_info.mqprio_active) - return -EINVAL; - - ret = hclge_ets_validate(hdev, ets, &num_tc, &map_changed); -@@ -267,10 +267,7 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets) - } - - hclge_tm_schd_info_update(hdev, num_tc); -- if (num_tc > 1) -- hdev->flag |= HCLGE_FLAG_DCB_ENABLE; -- else -- hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; -+ h->kinfo.tc_info.dcb_ets_active = num_tc > 1; - - ret = hclge_ieee_ets_to_tm_info(hdev, ets); - if (ret) -@@ -463,7 +460,7 @@ static u8 hclge_getdcbx(struct hnae3_handle *h) - struct hclge_vport *vport = hclge_get_vport(h); - struct hclge_dev *hdev = vport->back; - -- if (hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE) -+ if (h->kinfo.tc_info.mqprio_active) - return 0; - - return hdev->dcbx_cap; -@@ -587,7 +584,8 @@ static int hclge_setup_tc(struct hnae3_handle *h, - if (!test_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state)) - return -EBUSY; - -- if (hdev->flag & HCLGE_FLAG_DCB_ENABLE) -+ kinfo = &vport->nic.kinfo; -+ if (kinfo->tc_info.dcb_ets_active) - return -EINVAL; - - ret = hclge_mqprio_qopt_check(hdev, mqprio_qopt); -@@ -601,7 +599,6 @@ static int hclge_setup_tc(struct hnae3_handle *h, - if (ret) - return ret; - -- kinfo = &vport->nic.kinfo; - memcpy(&old_tc_info, &kinfo->tc_info, sizeof(old_tc_info)); - hclge_sync_mqprio_qopt(&kinfo->tc_info, mqprio_qopt); - kinfo->tc_info.mqprio_active = tc > 0; -@@ -610,13 +607,6 @@ static int hclge_setup_tc(struct hnae3_handle *h, - if (ret) - goto err_out; - -- hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; -- -- if (tc > 1) -- hdev->flag |= HCLGE_FLAG_MQPRIO_ENABLE; -- else -- hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE; -- - return hclge_notify_init_up(hdev); - - err_out: -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c -index 5cb8f1818e51c..a1c59f4aae988 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c -@@ -1517,7 +1517,7 @@ static int hclge_dbg_fd_tcam_read(struct hclge_dev *hdev, bool sel_x, - struct hclge_desc desc[3]; - int pos = 0; - int ret, i; -- u32 *req; -+ __le32 *req; - - hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_FD_TCAM_OP, true); - desc[0].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); -@@ -1542,22 +1542,22 @@ static int hclge_dbg_fd_tcam_read(struct hclge_dev *hdev, bool sel_x, - tcam_msg.loc); - - /* tcam_data0 ~ tcam_data1 */ -- req = (u32 *)req1->tcam_data; -+ req = (__le32 *)req1->tcam_data; - for (i = 0; i < 2; i++) - pos += scnprintf(tcam_buf + pos, HCLGE_DBG_TCAM_BUF_SIZE - pos, -- "%08x\n", *req++); -+ "%08x\n", le32_to_cpu(*req++)); - - /* tcam_data2 ~ tcam_data7 */ -- req = (u32 *)req2->tcam_data; -+ req = (__le32 *)req2->tcam_data; - for (i = 0; i < 6; i++) - pos += scnprintf(tcam_buf + pos, HCLGE_DBG_TCAM_BUF_SIZE - pos, -- "%08x\n", *req++); -+ "%08x\n", le32_to_cpu(*req++)); - - /* tcam_data8 ~ tcam_data12 */ -- req = (u32 *)req3->tcam_data; -+ req = (__le32 *)req3->tcam_data; - for (i = 0; i < 5; i++) - pos += scnprintf(tcam_buf + pos, HCLGE_DBG_TCAM_BUF_SIZE - pos, -- "%08x\n", *req++); -+ "%08x\n", le32_to_cpu(*req++)); - - return ret; - } -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -index 84ecd8b9be48c..884e45fb6b72e 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -@@ -11132,6 +11132,7 @@ static void hclge_get_mdix_mode(struct hnae3_handle *handle, - - static void hclge_info_show(struct hclge_dev *hdev) - { -+ struct hnae3_handle *handle = &hdev->vport->nic; - struct device *dev = &hdev->pdev->dev; - - dev_info(dev, "PF info begin:\n"); -@@ -11148,9 +11149,9 @@ static void hclge_info_show(struct hclge_dev *hdev) - dev_info(dev, "This is %s PF\n", - hdev->flag & HCLGE_FLAG_MAIN ? "main" : "not main"); - dev_info(dev, "DCB %s\n", -- hdev->flag & HCLGE_FLAG_DCB_ENABLE ? "enable" : "disable"); -+ handle->kinfo.tc_info.dcb_ets_active ? "enable" : "disable"); - dev_info(dev, "MQPRIO %s\n", -- hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE ? "enable" : "disable"); -+ handle->kinfo.tc_info.mqprio_active ? "enable" : "disable"); - dev_info(dev, "Default tx spare buffer size: %u\n", - hdev->tx_spare_buf_size); - -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h -index 13f23d606e77b..f6fef790e16c1 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h -@@ -916,8 +916,6 @@ struct hclge_dev { - - #define HCLGE_FLAG_MAIN BIT(0) - #define HCLGE_FLAG_DCB_CAPABLE BIT(1) --#define HCLGE_FLAG_DCB_ENABLE BIT(2) --#define HCLGE_FLAG_MQPRIO_ENABLE BIT(3) - u32 flag; - - u32 pkt_buf_size; /* Total pf buf size for tx/rx */ -diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h -index 015b781441149..a2b759531cb7b 100644 ---- a/drivers/net/ethernet/intel/igb/igb.h -+++ b/drivers/net/ethernet/intel/igb/igb.h -@@ -34,11 +34,11 @@ struct igb_adapter; - /* TX/RX descriptor defines */ - #define IGB_DEFAULT_TXD 256 - #define IGB_DEFAULT_TX_WORK 128 --#define IGB_MIN_TXD 80 -+#define IGB_MIN_TXD 64 - #define IGB_MAX_TXD 4096 - - #define IGB_DEFAULT_RXD 256 --#define IGB_MIN_RXD 80 -+#define IGB_MIN_RXD 64 - #define IGB_MAX_RXD 4096 - - #define IGB_DEFAULT_ITR 3 /* dynamic */ -diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c -index d0ead18ec0266..45ce4ed16146e 100644 ---- a/drivers/net/ethernet/intel/igb/igb_main.c -+++ b/drivers/net/ethernet/intel/igb/igb_main.c -@@ -3877,8 +3877,9 @@ static void igb_probe_vfs(struct igb_adapter *adapter) - struct pci_dev *pdev = adapter->pdev; - struct e1000_hw *hw = &adapter->hw; - -- /* Virtualization features not supported on i210 family. */ -- if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) -+ /* Virtualization features not supported on i210 and 82580 family. */ -+ if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211) || -+ (hw->mac.type == e1000_82580)) - return; - - /* Of the below we really only want the effect of getting -diff --git a/drivers/net/ethernet/intel/igbvf/igbvf.h b/drivers/net/ethernet/intel/igbvf/igbvf.h -index 57d39ee00b585..7b83678ba83a6 100644 ---- a/drivers/net/ethernet/intel/igbvf/igbvf.h -+++ b/drivers/net/ethernet/intel/igbvf/igbvf.h -@@ -39,11 +39,11 @@ enum latency_range { - /* Tx/Rx descriptor defines */ - #define IGBVF_DEFAULT_TXD 256 - #define IGBVF_MAX_TXD 4096 --#define IGBVF_MIN_TXD 80 -+#define IGBVF_MIN_TXD 64 - - #define IGBVF_DEFAULT_RXD 256 - #define IGBVF_MAX_RXD 4096 --#define IGBVF_MIN_RXD 80 -+#define IGBVF_MIN_RXD 64 - - #define IGBVF_MIN_ITR_USECS 10 /* 100000 irq/sec */ - #define IGBVF_MAX_ITR_USECS 10000 /* 100 irq/sec */ -diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h -index f83cbc4a1afa8..d3b17aa1d1a83 100644 ---- a/drivers/net/ethernet/intel/igc/igc.h -+++ b/drivers/net/ethernet/intel/igc/igc.h -@@ -354,11 +354,11 @@ static inline u32 igc_rss_type(const union igc_adv_rx_desc *rx_desc) - /* TX/RX descriptor defines */ - #define IGC_DEFAULT_TXD 256 - #define IGC_DEFAULT_TX_WORK 128 --#define IGC_MIN_TXD 80 -+#define IGC_MIN_TXD 64 - #define IGC_MAX_TXD 4096 - - #define IGC_DEFAULT_RXD 256 --#define IGC_MIN_RXD 80 -+#define IGC_MIN_RXD 64 - #define IGC_MAX_RXD 4096 - - /* Supported Rx Buffer Sizes */ -diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c -index f8605f57bd067..75e1383263c1e 100644 ---- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c -+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c -@@ -995,6 +995,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, - u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; - u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; - u32 tsync_rx_mtrl = PTP_EV_PORT << 16; -+ u32 aflags = adapter->flags; - bool is_l2 = false; - u32 regval; - -@@ -1012,20 +1013,20 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, - case HWTSTAMP_FILTER_NONE: - tsync_rx_ctl = 0; - tsync_rx_mtrl = 0; -- adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -- IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); -+ aflags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -+ IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); - break; - case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; - tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; -- adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -- IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); -+ aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -+ IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); - break; - case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; - tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; -- adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -- IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); -+ aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -+ IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); - break; - case HWTSTAMP_FILTER_PTP_V2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: -@@ -1039,8 +1040,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; - is_l2 = true; - config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; -- adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -- IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); -+ aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -+ IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); - break; - case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: - case HWTSTAMP_FILTER_NTP_ALL: -@@ -1051,7 +1052,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, - if (hw->mac.type >= ixgbe_mac_X550) { - tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; - config->rx_filter = HWTSTAMP_FILTER_ALL; -- adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; -+ aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; - break; - } - fallthrough; -@@ -1062,8 +1063,6 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, - * Delay_Req messages and hardware does not support - * timestamping all packets => return error - */ -- adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | -- IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); - config->rx_filter = HWTSTAMP_FILTER_NONE; - return -ERANGE; - } -@@ -1095,8 +1094,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, - IXGBE_TSYNCRXCTL_TYPE_ALL | - IXGBE_TSYNCRXCTL_TSIP_UT_EN; - config->rx_filter = HWTSTAMP_FILTER_ALL; -- adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; -- adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; -+ aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; -+ aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; - is_l2 = true; - break; - default: -@@ -1129,6 +1128,9 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, - - IXGBE_WRITE_FLUSH(hw); - -+ /* configure adapter flags only when HW is actually configured */ -+ adapter->flags = aflags; -+ - /* clear TX/RX time stamp registers, just to be sure */ - ixgbe_ptp_clear_tx_timestamp(adapter); - IXGBE_READ_REG(hw, IXGBE_RXSTMPH); -diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -index b399bdb1ca362..f936640cca4e6 100644 ---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -@@ -5578,6 +5578,11 @@ static int mvpp2_ethtool_get_rxnfc(struct net_device *dev, - break; - case ETHTOOL_GRXCLSRLALL: - for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) { -+ if (loc == info->rule_cnt) { -+ ret = -EMSGSIZE; -+ break; -+ } -+ - if (port->rfs_rules[i]) - rules[loc++] = i; - } -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -index c85e0180d96da..1f3a8cf42765e 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -@@ -834,6 +834,21 @@ static int nix_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block, - return 0; - } - -+static void nix_get_aq_req_smq(struct rvu *rvu, struct nix_aq_enq_req *req, -+ u16 *smq, u16 *smq_mask) -+{ -+ struct nix_cn10k_aq_enq_req *aq_req; -+ -+ if (!is_rvu_otx2(rvu)) { -+ aq_req = (struct nix_cn10k_aq_enq_req *)req; -+ *smq = aq_req->sq.smq; -+ *smq_mask = aq_req->sq_mask.smq; -+ } else { -+ *smq = req->sq.smq; -+ *smq_mask = req->sq_mask.smq; -+ } -+} -+ - static int rvu_nix_blk_aq_enq_inst(struct rvu *rvu, struct nix_hw *nix_hw, - struct nix_aq_enq_req *req, - struct nix_aq_enq_rsp *rsp) -@@ -845,6 +860,7 @@ static int rvu_nix_blk_aq_enq_inst(struct rvu *rvu, struct nix_hw *nix_hw, - struct rvu_block *block; - struct admin_queue *aq; - struct rvu_pfvf *pfvf; -+ u16 smq, smq_mask; - void *ctx, *mask; - bool ena; - u64 cfg; -@@ -916,13 +932,14 @@ static int rvu_nix_blk_aq_enq_inst(struct rvu *rvu, struct nix_hw *nix_hw, - if (rc) - return rc; - -+ nix_get_aq_req_smq(rvu, req, &smq, &smq_mask); - /* Check if SQ pointed SMQ belongs to this PF/VF or not */ - if (req->ctype == NIX_AQ_CTYPE_SQ && - ((req->op == NIX_AQ_INSTOP_INIT && req->sq.ena) || - (req->op == NIX_AQ_INSTOP_WRITE && -- req->sq_mask.ena && req->sq_mask.smq && req->sq.ena))) { -+ req->sq_mask.ena && req->sq.ena && smq_mask))) { - if (!is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_SMQ, -- pcifunc, req->sq.smq)) -+ pcifunc, smq)) - return NIX_AF_ERR_AQ_ENQUEUE; - } - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 7e318133423a9..0ac5ae16308f6 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2698,6 +2698,9 @@ static int mtk_hwlro_get_fdir_all(struct net_device *dev, - int i; - - for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { -+ if (cnt == cmd->rule_cnt) -+ return -EMSGSIZE; -+ - if (mac->hwlro_ip[i]) { - rule_locs[cnt] = i; - cnt++; -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c -index 72b61f66df37a..cd15d36b1507e 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c -@@ -97,7 +97,6 @@ int mlx5e_tc_set_attr_rx_tun(struct mlx5e_tc_flow *flow, - #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) - else if (ip_version == 6) { - int ipv6_size = MLX5_FLD_SZ_BYTES(ipv6_layout, ipv6); -- struct in6_addr zerov6 = {}; - - daddr = MLX5_ADDR_OF(fte_match_param, spec->match_value, - outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6); -@@ -105,8 +104,8 @@ int mlx5e_tc_set_attr_rx_tun(struct mlx5e_tc_flow *flow, - outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6); - memcpy(&tun_attr->dst_ip.v6, daddr, ipv6_size); - memcpy(&tun_attr->src_ip.v6, saddr, ipv6_size); -- if (!memcmp(&tun_attr->dst_ip.v6, &zerov6, sizeof(zerov6)) || -- !memcmp(&tun_attr->src_ip.v6, &zerov6, sizeof(zerov6))) -+ if (ipv6_addr_any(&tun_attr->dst_ip.v6) || -+ ipv6_addr_any(&tun_attr->src_ip.v6)) - return 0; - } - #endif -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -index 5e0f7d96aac51..d136360ac6a98 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -@@ -123,18 +123,32 @@ out: - return ret; - } - --static void irq_release(struct mlx5_irq *irq) -+/* mlx5_system_free_irq - Free an IRQ -+ * @irq: IRQ to free -+ * -+ * Free the IRQ and other resources such as rmap from the system. -+ * BUT doesn't free or remove reference from mlx5. -+ * This function is very important for the shutdown flow, where we need to -+ * cleanup system resoruces but keep mlx5 objects alive, -+ * see mlx5_irq_table_free_irqs(). -+ */ -+static void mlx5_system_free_irq(struct mlx5_irq *irq) - { -- struct mlx5_irq_pool *pool = irq->pool; -- -- xa_erase(&pool->irqs, irq->index); - /* free_irq requires that affinity_hint and rmap will be cleared - * before calling it. This is why there is asymmetry with set_rmap - * which should be called after alloc_irq but before request_irq. - */ - irq_update_affinity_hint(irq->irqn, NULL); -- free_cpumask_var(irq->mask); - free_irq(irq->irqn, &irq->nh); -+} -+ -+static void irq_release(struct mlx5_irq *irq) -+{ -+ struct mlx5_irq_pool *pool = irq->pool; -+ -+ xa_erase(&pool->irqs, irq->index); -+ mlx5_system_free_irq(irq); -+ free_cpumask_var(irq->mask); - kfree(irq); - } - -@@ -597,7 +611,7 @@ static void mlx5_irq_pool_free_irqs(struct mlx5_irq_pool *pool) - unsigned long index; - - xa_for_each(&pool->irqs, index, irq) -- free_irq(irq->irqn, &irq->nh); -+ mlx5_system_free_irq(irq); - } - - static void mlx5_irq_pools_free_irqs(struct mlx5_irq_table *table) -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index a07bcb2f5d2e2..1559a4dafd413 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -2692,9 +2692,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) - - /* We still have pending packets, let's call for a new scheduling */ - if (tx_q->dirty_tx != tx_q->cur_tx) -- hrtimer_start(&tx_q->txtimer, -- STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), -- HRTIMER_MODE_REL); -+ stmmac_tx_timer_arm(priv, queue); - - __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue)); - -@@ -2975,9 +2973,13 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) - static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue) - { - struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; -+ u32 tx_coal_timer = priv->tx_coal_timer[queue]; -+ -+ if (!tx_coal_timer) -+ return; - - hrtimer_start(&tx_q->txtimer, -- STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), -+ STMMAC_COAL_TIMER(tx_coal_timer), - HRTIMER_MODE_REL); - } - -diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c -index 059d610901d84..fc1458f96e170 100644 ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -2628,6 +2628,9 @@ static int r8152_poll(struct napi_struct *napi, int budget) - struct r8152 *tp = container_of(napi, struct r8152, napi); - int work_done; - -+ if (!budget) -+ return 0; -+ - work_done = rx_bottom(tp, budget); - - if (work_done < budget) { -diff --git a/drivers/net/veth.c b/drivers/net/veth.c -index 727b9278b9fe5..36c5a41f84e44 100644 ---- a/drivers/net/veth.c -+++ b/drivers/net/veth.c -@@ -313,6 +313,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct veth_priv *rcv_priv, *priv = netdev_priv(dev); - struct veth_rq *rq = NULL; -+ int ret = NETDEV_TX_OK; - struct net_device *rcv; - int length = skb->len; - bool use_napi = false; -@@ -345,6 +346,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) - } else { - drop: - atomic64_inc(&priv->dropped); -+ ret = NET_XMIT_DROP; - } - - if (use_napi) -@@ -352,7 +354,7 @@ drop: - - rcu_read_unlock(); - -- return NETDEV_TX_OK; -+ return ret; - } - - static u64 veth_stats_tx(struct net_device *dev, u64 *packets, u64 *bytes) -diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c -index 8bdc5e043831c..3737c1021f88b 100644 ---- a/drivers/parisc/led.c -+++ b/drivers/parisc/led.c -@@ -56,8 +56,8 @@ - static int led_type __read_mostly = -1; - static unsigned char lastleds; /* LED state from most recent update */ - static unsigned int led_heartbeat __read_mostly = 1; --static unsigned int led_diskio __read_mostly = 1; --static unsigned int led_lanrxtx __read_mostly = 1; -+static unsigned int led_diskio __read_mostly; -+static unsigned int led_lanrxtx __read_mostly; - static char lcd_text[32] __read_mostly; - static char lcd_text_default[32] __read_mostly; - static int lcd_no_led_support __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */ -diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c -index 0d6b5fab2f7e4..de07b0837a04f 100644 ---- a/drivers/pinctrl/intel/pinctrl-cherryview.c -+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c -@@ -1698,7 +1698,6 @@ static int chv_pinctrl_probe(struct platform_device *pdev) - struct intel_community_context *cctx; - struct intel_community *community; - struct device *dev = &pdev->dev; -- struct acpi_device *adev = ACPI_COMPANION(dev); - struct intel_pinctrl *pctrl; - acpi_status status; - unsigned int i; -@@ -1766,7 +1765,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev) - if (ret) - return ret; - -- status = acpi_install_address_space_handler(adev->handle, -+ status = acpi_install_address_space_handler(ACPI_HANDLE(dev), - community->acpi_space_id, - chv_pinctrl_mmio_access_handler, - NULL, pctrl); -@@ -1783,7 +1782,7 @@ static int chv_pinctrl_remove(struct platform_device *pdev) - struct intel_pinctrl *pctrl = platform_get_drvdata(pdev); - const struct intel_community *community = &pctrl->communities[0]; - -- acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev), -+ acpi_remove_address_space_handler(ACPI_HANDLE(&pdev->dev), - community->acpi_space_id, - chv_pinctrl_mmio_access_handler); - -diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig -index 382793e73a60a..30b50920b278c 100644 ---- a/drivers/platform/mellanox/Kconfig -+++ b/drivers/platform/mellanox/Kconfig -@@ -80,8 +80,8 @@ config MLXBF_PMC - - config NVSW_SN2201 - tristate "Nvidia SN2201 platform driver support" -- depends on HWMON -- depends on I2C -+ depends on HWMON && I2C -+ depends on ACPI || COMPILE_TEST - select REGMAP_I2C - help - This driver provides support for the Nvidia SN2201 platform. -diff --git a/drivers/platform/mellanox/mlxbf-pmc.c b/drivers/platform/mellanox/mlxbf-pmc.c -index be967d797c28e..2d4bbe99959ef 100644 ---- a/drivers/platform/mellanox/mlxbf-pmc.c -+++ b/drivers/platform/mellanox/mlxbf-pmc.c -@@ -191,6 +191,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_smgen_events[] = { - }; - - static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = { -+ { 0x0, "DISABLE" }, - { 0xa0, "TPIO_DATA_BEAT" }, - { 0xa1, "TDMA_DATA_BEAT" }, - { 0xa2, "MAP_DATA_BEAT" }, -@@ -214,6 +215,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = { - }; - - static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = { -+ { 0x0, "DISABLE" }, - { 0xa0, "TPIO_DATA_BEAT" }, - { 0xa1, "TDMA_DATA_BEAT" }, - { 0xa2, "MAP_DATA_BEAT" }, -@@ -246,6 +248,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = { - }; - - static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = { -+ { 0x0, "DISABLE" }, - { 0x100, "ECC_SINGLE_ERROR_CNT" }, - { 0x104, "ECC_DOUBLE_ERROR_CNT" }, - { 0x114, "SERR_INJ" }, -@@ -258,6 +261,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = { - }; - - static const struct mlxbf_pmc_events mlxbf_pmc_mss_events[] = { -+ { 0x0, "DISABLE" }, - { 0xc0, "RXREQ_MSS" }, - { 0xc1, "RXDAT_MSS" }, - { 0xc2, "TXRSP_MSS" }, -@@ -265,6 +269,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_mss_events[] = { - }; - - static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = { -+ { 0x0, "DISABLE" }, - { 0x45, "HNF_REQUESTS" }, - { 0x46, "HNF_REJECTS" }, - { 0x47, "ALL_BUSY" }, -@@ -323,6 +328,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = { - }; - - static const struct mlxbf_pmc_events mlxbf_pmc_hnfnet_events[] = { -+ { 0x0, "DISABLE" }, - { 0x12, "CDN_REQ" }, - { 0x13, "DDN_REQ" }, - { 0x14, "NDN_REQ" }, -@@ -892,7 +898,7 @@ static int mlxbf_pmc_read_event(int blk_num, uint32_t cnt_num, bool is_l3, - uint64_t *result) - { - uint32_t perfcfg_offset, perfval_offset; -- uint64_t perfmon_cfg, perfevt, perfctl; -+ uint64_t perfmon_cfg, perfevt; - - if (cnt_num >= pmc->block[blk_num].counters) - return -EINVAL; -@@ -904,25 +910,6 @@ static int mlxbf_pmc_read_event(int blk_num, uint32_t cnt_num, bool is_l3, - perfval_offset = perfcfg_offset + - pmc->block[blk_num].counters * MLXBF_PMC_REG_SIZE; - -- /* Set counter in "read" mode */ -- perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR, -- MLXBF_PMC_PERFCTL); -- perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_STROBE, 1); -- perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_WR_R_B, 0); -- -- if (mlxbf_pmc_write(pmc->block[blk_num].mmio_base + perfcfg_offset, -- MLXBF_PMC_WRITE_REG_64, perfmon_cfg)) -- return -EFAULT; -- -- /* Check if the counter is enabled */ -- -- if (mlxbf_pmc_read(pmc->block[blk_num].mmio_base + perfval_offset, -- MLXBF_PMC_READ_REG_64, &perfctl)) -- return -EFAULT; -- -- if (!FIELD_GET(MLXBF_PMC_PERFCTL_EN0, perfctl)) -- return -EINVAL; -- - /* Set counter in "read" mode */ - perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR, - MLXBF_PMC_PERFEVT); -@@ -1008,7 +995,7 @@ static ssize_t mlxbf_pmc_counter_show(struct device *dev, - } else - return -EINVAL; - -- return sprintf(buf, "0x%llx\n", value); -+ return sysfs_emit(buf, "0x%llx\n", value); - } - - /* Store function for "counter" sysfs files */ -@@ -1078,13 +1065,13 @@ static ssize_t mlxbf_pmc_event_show(struct device *dev, - - err = mlxbf_pmc_read_event(blk_num, cnt_num, is_l3, &evt_num); - if (err) -- return sprintf(buf, "No event being monitored\n"); -+ return sysfs_emit(buf, "No event being monitored\n"); - - evt_name = mlxbf_pmc_get_event_name(pmc->block_name[blk_num], evt_num); - if (!evt_name) - return -EINVAL; - -- return sprintf(buf, "0x%llx: %s\n", evt_num, evt_name); -+ return sysfs_emit(buf, "0x%llx: %s\n", evt_num, evt_name); - } - - /* Store function for "event" sysfs files */ -@@ -1139,9 +1126,9 @@ static ssize_t mlxbf_pmc_event_list_show(struct device *dev, - return -EINVAL; - - for (i = 0, buf[0] = '\0'; i < size; ++i) { -- len += sprintf(e_info, "0x%x: %s\n", events[i].evt_num, -- events[i].evt_name); -- if (len > PAGE_SIZE) -+ len += snprintf(e_info, sizeof(e_info), "0x%x: %s\n", -+ events[i].evt_num, events[i].evt_name); -+ if (len >= PAGE_SIZE) - break; - strcat(buf, e_info); - ret = len; -@@ -1168,7 +1155,7 @@ static ssize_t mlxbf_pmc_enable_show(struct device *dev, - - value = FIELD_GET(MLXBF_PMC_L3C_PERF_CNT_CFG_EN, perfcnt_cfg); - -- return sprintf(buf, "%d\n", value); -+ return sysfs_emit(buf, "%d\n", value); - } - - /* Store function for "enable" sysfs files - only for l3cache */ -diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c -index d31fe7eed38df..a04ff89a7ec44 100644 ---- a/drivers/platform/mellanox/mlxbf-tmfifo.c -+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c -@@ -56,6 +56,7 @@ struct mlxbf_tmfifo; - * @vq: pointer to the virtio virtqueue - * @desc: current descriptor of the pending packet - * @desc_head: head descriptor of the pending packet -+ * @drop_desc: dummy desc for packet dropping - * @cur_len: processed length of the current descriptor - * @rem_len: remaining length of the pending packet - * @pkt_len: total length of the pending packet -@@ -72,6 +73,7 @@ struct mlxbf_tmfifo_vring { - struct virtqueue *vq; - struct vring_desc *desc; - struct vring_desc *desc_head; -+ struct vring_desc drop_desc; - int cur_len; - int rem_len; - u32 pkt_len; -@@ -83,6 +85,14 @@ struct mlxbf_tmfifo_vring { - struct mlxbf_tmfifo *fifo; - }; - -+/* Check whether vring is in drop mode. */ -+#define IS_VRING_DROP(_r) ({ \ -+ typeof(_r) (r) = (_r); \ -+ (r->desc_head == &r->drop_desc ? true : false); }) -+ -+/* A stub length to drop maximum length packet. */ -+#define VRING_DROP_DESC_MAX_LEN GENMASK(15, 0) -+ - /* Interrupt types. */ - enum { - MLXBF_TM_RX_LWM_IRQ, -@@ -195,7 +205,7 @@ static u8 mlxbf_tmfifo_net_default_mac[ETH_ALEN] = { - static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr"; - - /* Maximum L2 header length. */ --#define MLXBF_TMFIFO_NET_L2_OVERHEAD 36 -+#define MLXBF_TMFIFO_NET_L2_OVERHEAD (ETH_HLEN + VLAN_HLEN) - - /* Supported virtio-net features. */ - #define MLXBF_TMFIFO_NET_FEATURES \ -@@ -243,6 +253,7 @@ static int mlxbf_tmfifo_alloc_vrings(struct mlxbf_tmfifo *fifo, - vring->align = SMP_CACHE_BYTES; - vring->index = i; - vring->vdev_id = tm_vdev->vdev.id.device; -+ vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN; - dev = &tm_vdev->vdev.dev; - - size = vring_size(vring->num, vring->align); -@@ -348,7 +359,7 @@ static u32 mlxbf_tmfifo_get_pkt_len(struct mlxbf_tmfifo_vring *vring, - return len; - } - --static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring) -+static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring) - { - struct vring_desc *desc_head; - u32 len = 0; -@@ -577,19 +588,25 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring, - - if (vring->cur_len + sizeof(u64) <= len) { - /* The whole word. */ -- if (is_rx) -- memcpy(addr + vring->cur_len, &data, sizeof(u64)); -- else -- memcpy(&data, addr + vring->cur_len, sizeof(u64)); -+ if (!IS_VRING_DROP(vring)) { -+ if (is_rx) -+ memcpy(addr + vring->cur_len, &data, -+ sizeof(u64)); -+ else -+ memcpy(&data, addr + vring->cur_len, -+ sizeof(u64)); -+ } - vring->cur_len += sizeof(u64); - } else { - /* Leftover bytes. */ -- if (is_rx) -- memcpy(addr + vring->cur_len, &data, -- len - vring->cur_len); -- else -- memcpy(&data, addr + vring->cur_len, -- len - vring->cur_len); -+ if (!IS_VRING_DROP(vring)) { -+ if (is_rx) -+ memcpy(addr + vring->cur_len, &data, -+ len - vring->cur_len); -+ else -+ memcpy(&data, addr + vring->cur_len, -+ len - vring->cur_len); -+ } - vring->cur_len = len; - } - -@@ -606,13 +623,14 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring, - * flag is set. - */ - static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, -- struct vring_desc *desc, -+ struct vring_desc **desc, - bool is_rx, bool *vring_change) - { - struct mlxbf_tmfifo *fifo = vring->fifo; - struct virtio_net_config *config; - struct mlxbf_tmfifo_msg_hdr hdr; - int vdev_id, hdr_len; -+ bool drop_rx = false; - - /* Read/Write packet header. */ - if (is_rx) { -@@ -632,8 +650,8 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, - if (ntohs(hdr.len) > - __virtio16_to_cpu(virtio_legacy_is_little_endian(), - config->mtu) + -- MLXBF_TMFIFO_NET_L2_OVERHEAD) -- return; -+ MLXBF_TMFIFO_NET_L2_OVERHEAD) -+ drop_rx = true; - } else { - vdev_id = VIRTIO_ID_CONSOLE; - hdr_len = 0; -@@ -648,16 +666,25 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, - - if (!tm_dev2) - return; -- vring->desc = desc; -+ vring->desc = *desc; - vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX]; - *vring_change = true; - } -+ -+ if (drop_rx && !IS_VRING_DROP(vring)) { -+ if (vring->desc_head) -+ mlxbf_tmfifo_release_pkt(vring); -+ *desc = &vring->drop_desc; -+ vring->desc_head = *desc; -+ vring->desc = *desc; -+ } -+ - vring->pkt_len = ntohs(hdr.len) + hdr_len; - } else { - /* Network virtio has an extra header. */ - hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ? - sizeof(struct virtio_net_hdr) : 0; -- vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, desc); -+ vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, *desc); - hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ? - VIRTIO_ID_NET : VIRTIO_ID_CONSOLE; - hdr.len = htons(vring->pkt_len - hdr_len); -@@ -690,15 +717,23 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring, - /* Get the descriptor of the next packet. */ - if (!vring->desc) { - desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx); -- if (!desc) -- return false; -+ if (!desc) { -+ /* Drop next Rx packet to avoid stuck. */ -+ if (is_rx) { -+ desc = &vring->drop_desc; -+ vring->desc_head = desc; -+ vring->desc = desc; -+ } else { -+ return false; -+ } -+ } - } else { - desc = vring->desc; - } - - /* Beginning of a packet. Start to Rx/Tx packet header. */ - if (vring->pkt_len == 0) { -- mlxbf_tmfifo_rxtx_header(vring, desc, is_rx, &vring_change); -+ mlxbf_tmfifo_rxtx_header(vring, &desc, is_rx, &vring_change); - (*avail)--; - - /* Return if new packet is for another ring. */ -@@ -724,17 +759,24 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring, - vring->rem_len -= len; - - /* Get the next desc on the chain. */ -- if (vring->rem_len > 0 && -+ if (!IS_VRING_DROP(vring) && vring->rem_len > 0 && - (virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) { - idx = virtio16_to_cpu(vdev, desc->next); - desc = &vr->desc[idx]; - goto mlxbf_tmfifo_desc_done; - } - -- /* Done and release the pending packet. */ -- mlxbf_tmfifo_release_pending_pkt(vring); -+ /* Done and release the packet. */ - desc = NULL; - fifo->vring[is_rx] = NULL; -+ if (!IS_VRING_DROP(vring)) { -+ mlxbf_tmfifo_release_pkt(vring); -+ } else { -+ vring->pkt_len = 0; -+ vring->desc_head = NULL; -+ vring->desc = NULL; -+ return false; -+ } - - /* - * Make sure the load/store are in order before -@@ -914,7 +956,7 @@ static void mlxbf_tmfifo_virtio_del_vqs(struct virtio_device *vdev) - - /* Release the pending packet. */ - if (vring->desc) -- mlxbf_tmfifo_release_pending_pkt(vring); -+ mlxbf_tmfifo_release_pkt(vring); - vq = vring->vq; - if (vq) { - vring->vq = NULL; -diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c -index 2837b4ce8053c..2826fc216d291 100644 ---- a/drivers/pwm/pwm-atmel-tcb.c -+++ b/drivers/pwm/pwm-atmel-tcb.c -@@ -422,13 +422,14 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) - struct atmel_tcb_pwm_chip *tcbpwm; - const struct atmel_tcb_config *config; - struct device_node *np = pdev->dev.of_node; -- struct regmap *regmap; -- struct clk *clk, *gclk = NULL; -- struct clk *slow_clk; - char clk_name[] = "t0_clk"; - int err; - int channel; - -+ tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL); -+ if (tcbpwm == NULL) -+ return -ENOMEM; -+ - err = of_property_read_u32(np, "reg", &channel); - if (err < 0) { - dev_err(&pdev->dev, -@@ -437,49 +438,43 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) - return err; - } - -- regmap = syscon_node_to_regmap(np->parent); -- if (IS_ERR(regmap)) -- return PTR_ERR(regmap); -+ tcbpwm->regmap = syscon_node_to_regmap(np->parent); -+ if (IS_ERR(tcbpwm->regmap)) -+ return PTR_ERR(tcbpwm->regmap); - -- slow_clk = of_clk_get_by_name(np->parent, "slow_clk"); -- if (IS_ERR(slow_clk)) -- return PTR_ERR(slow_clk); -+ tcbpwm->slow_clk = of_clk_get_by_name(np->parent, "slow_clk"); -+ if (IS_ERR(tcbpwm->slow_clk)) -+ return PTR_ERR(tcbpwm->slow_clk); - - clk_name[1] += channel; -- clk = of_clk_get_by_name(np->parent, clk_name); -- if (IS_ERR(clk)) -- clk = of_clk_get_by_name(np->parent, "t0_clk"); -- if (IS_ERR(clk)) -- return PTR_ERR(clk); -+ tcbpwm->clk = of_clk_get_by_name(np->parent, clk_name); -+ if (IS_ERR(tcbpwm->clk)) -+ tcbpwm->clk = of_clk_get_by_name(np->parent, "t0_clk"); -+ if (IS_ERR(tcbpwm->clk)) { -+ err = PTR_ERR(tcbpwm->clk); -+ goto err_slow_clk; -+ } - - match = of_match_node(atmel_tcb_of_match, np->parent); - config = match->data; - - if (config->has_gclk) { -- gclk = of_clk_get_by_name(np->parent, "gclk"); -- if (IS_ERR(gclk)) -- return PTR_ERR(gclk); -- } -- -- tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL); -- if (tcbpwm == NULL) { -- err = -ENOMEM; -- goto err_slow_clk; -+ tcbpwm->gclk = of_clk_get_by_name(np->parent, "gclk"); -+ if (IS_ERR(tcbpwm->gclk)) { -+ err = PTR_ERR(tcbpwm->gclk); -+ goto err_clk; -+ } - } - - tcbpwm->chip.dev = &pdev->dev; - tcbpwm->chip.ops = &atmel_tcb_pwm_ops; - tcbpwm->chip.npwm = NPWM; - tcbpwm->channel = channel; -- tcbpwm->regmap = regmap; -- tcbpwm->clk = clk; -- tcbpwm->gclk = gclk; -- tcbpwm->slow_clk = slow_clk; - tcbpwm->width = config->counter_width; - -- err = clk_prepare_enable(slow_clk); -+ err = clk_prepare_enable(tcbpwm->slow_clk); - if (err) -- goto err_slow_clk; -+ goto err_gclk; - - spin_lock_init(&tcbpwm->lock); - -@@ -494,23 +489,28 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) - err_disable_clk: - clk_disable_unprepare(tcbpwm->slow_clk); - -+err_gclk: -+ clk_put(tcbpwm->gclk); -+ -+err_clk: -+ clk_put(tcbpwm->clk); -+ - err_slow_clk: -- clk_put(slow_clk); -+ clk_put(tcbpwm->slow_clk); - - return err; - } - --static int atmel_tcb_pwm_remove(struct platform_device *pdev) -+static void atmel_tcb_pwm_remove(struct platform_device *pdev) - { - struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev); - - pwmchip_remove(&tcbpwm->chip); - - clk_disable_unprepare(tcbpwm->slow_clk); -- clk_put(tcbpwm->slow_clk); -+ clk_put(tcbpwm->gclk); - clk_put(tcbpwm->clk); -- -- return 0; -+ clk_put(tcbpwm->slow_clk); - } - - static const struct of_device_id atmel_tcb_pwm_dt_ids[] = { -@@ -564,7 +564,7 @@ static struct platform_driver atmel_tcb_pwm_driver = { - .pm = &atmel_tcb_pwm_pm_ops, - }, - .probe = atmel_tcb_pwm_probe, -- .remove = atmel_tcb_pwm_remove, -+ .remove_new = atmel_tcb_pwm_remove, - }; - module_platform_driver(atmel_tcb_pwm_driver); - -diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c -index 86a0ea0f6955c..806f0bb3ad6d8 100644 ---- a/drivers/pwm/pwm-lpc32xx.c -+++ b/drivers/pwm/pwm-lpc32xx.c -@@ -51,10 +51,10 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - if (duty_cycles > 255) - duty_cycles = 255; - -- val = readl(lpc32xx->base + (pwm->hwpwm << 2)); -+ val = readl(lpc32xx->base); - val &= ~0xFFFF; - val |= (period_cycles << 8) | duty_cycles; -- writel(val, lpc32xx->base + (pwm->hwpwm << 2)); -+ writel(val, lpc32xx->base); - - return 0; - } -@@ -69,9 +69,9 @@ static int lpc32xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) - if (ret) - return ret; - -- val = readl(lpc32xx->base + (pwm->hwpwm << 2)); -+ val = readl(lpc32xx->base); - val |= PWM_ENABLE; -- writel(val, lpc32xx->base + (pwm->hwpwm << 2)); -+ writel(val, lpc32xx->base); - - return 0; - } -@@ -81,9 +81,9 @@ static void lpc32xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) - struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip); - u32 val; - -- val = readl(lpc32xx->base + (pwm->hwpwm << 2)); -+ val = readl(lpc32xx->base); - val &= ~PWM_ENABLE; -- writel(val, lpc32xx->base + (pwm->hwpwm << 2)); -+ writel(val, lpc32xx->base); - - clk_disable_unprepare(lpc32xx->clk); - } -@@ -141,9 +141,9 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) - lpc32xx->chip.npwm = 1; - - /* If PWM is disabled, configure the output to the default value */ -- val = readl(lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2)); -+ val = readl(lpc32xx->base); - val &= ~PWM_PIN_LEVEL; -- writel(val, lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2)); -+ writel(val, lpc32xx->base); - - ret = devm_pwmchip_add(&pdev->dev, &lpc32xx->chip); - if (ret < 0) { -diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c -index f94b43ce9a658..28e34d155334b 100644 ---- a/drivers/s390/crypto/zcrypt_api.c -+++ b/drivers/s390/crypto/zcrypt_api.c -@@ -441,6 +441,7 @@ static int zcdn_create(const char *name) - ZCRYPT_NAME "_%d", (int)MINOR(devt)); - nodename[sizeof(nodename) - 1] = '\0'; - if (dev_set_name(&zcdndev->device, nodename)) { -+ kfree(zcdndev); - rc = -EINVAL; - goto unlockout; - } -diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c -index 64734d6e8ccb1..07fbaa452d8a1 100644 ---- a/drivers/scsi/qla2xxx/qla_attr.c -+++ b/drivers/scsi/qla2xxx/qla_attr.c -@@ -3093,8 +3093,6 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) - vha->flags.difdix_supported = 1; - ql_dbg(ql_dbg_user, vha, 0x7082, - "Registered for DIF/DIX type 1 and 3 protection.\n"); -- if (ql2xenabledif == 1) -- prot = SHOST_DIX_TYPE0_PROTECTION; - scsi_host_set_prot(vha->host, - prot | SHOST_DIF_TYPE1_PROTECTION - | SHOST_DIF_TYPE2_PROTECTION -diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c -index d7e8454304cee..ab637324262ff 100644 ---- a/drivers/scsi/qla2xxx/qla_dbg.c -+++ b/drivers/scsi/qla2xxx/qla_dbg.c -@@ -18,7 +18,7 @@ - * | Queue Command and IO tracing | 0x3074 | 0x300b | - * | | | 0x3027-0x3028 | - * | | | 0x303d-0x3041 | -- * | | | 0x302d,0x3033 | -+ * | | | 0x302e,0x3033 | - * | | | 0x3036,0x3038 | - * | | | 0x303a | - * | DPC Thread | 0x4023 | 0x4002,0x4013 | -diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h -index 5a2f629d18e69..7d282906598f3 100644 ---- a/drivers/scsi/qla2xxx/qla_def.h -+++ b/drivers/scsi/qla2xxx/qla_def.h -@@ -458,6 +458,7 @@ static inline be_id_t port_id_to_be_id(port_id_t port_id) - } - - struct tmf_arg { -+ struct list_head tmf_elem; - struct qla_qpair *qpair; - struct fc_port *fcport; - struct scsi_qla_host *vha; -@@ -2534,7 +2535,6 @@ enum rscn_addr_format { - typedef struct fc_port { - struct list_head list; - struct scsi_qla_host *vha; -- struct list_head tmf_pending; - - unsigned int conf_compl_supported:1; - unsigned int deleted:2; -@@ -2555,9 +2555,6 @@ typedef struct fc_port { - unsigned int do_prli_nvme:1; - - uint8_t nvme_flag; -- uint8_t active_tmf; --#define MAX_ACTIVE_TMF 8 -- - uint8_t node_name[WWN_SIZE]; - uint8_t port_name[WWN_SIZE]; - port_id_t d_id; -@@ -3743,6 +3740,16 @@ struct qla_fw_resources { - u16 pad; - }; - -+struct qla_fw_res { -+ u16 iocb_total; -+ u16 iocb_limit; -+ atomic_t iocb_used; -+ -+ u16 exch_total; -+ u16 exch_limit; -+ atomic_t exch_used; -+}; -+ - #define QLA_IOCB_PCT_LIMIT 95 - - /*Queue pair data structure */ -@@ -4370,7 +4377,6 @@ struct qla_hw_data { - uint8_t aen_mbx_count; - atomic_t num_pend_mbx_stage1; - atomic_t num_pend_mbx_stage2; -- atomic_t num_pend_mbx_stage3; - uint16_t frame_payload_size; - - uint32_t login_retry_count; -@@ -4640,6 +4646,8 @@ struct qla_hw_data { - uint32_t flt_region_aux_img_status_sec; - }; - uint8_t active_image; -+ uint8_t active_tmf; -+#define MAX_ACTIVE_TMF 8 - - /* Needed for BEACON */ - uint16_t beacon_blink_led; -@@ -4654,6 +4662,8 @@ struct qla_hw_data { - - struct qla_msix_entry *msix_entries; - -+ struct list_head tmf_pending; -+ struct list_head tmf_active; - struct list_head vp_list; /* list of VP */ - unsigned long vp_idx_map[(MAX_MULTI_ID_FABRIC / 8) / - sizeof(unsigned long)]; -@@ -4782,6 +4792,7 @@ struct qla_hw_data { - spinlock_t sadb_lock; /* protects list */ - struct els_reject elsrej; - u8 edif_post_stop_cnt_down; -+ struct qla_fw_res fwres ____cacheline_aligned; - }; - - #define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES)) -diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c -index 1925cc6897b68..f060e593685de 100644 ---- a/drivers/scsi/qla2xxx/qla_dfs.c -+++ b/drivers/scsi/qla2xxx/qla_dfs.c -@@ -276,6 +276,16 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) - - seq_printf(s, "estimate exchange used[%d] high water limit [%d] n", - exch_used, ha->base_qpair->fwres.exch_limit); -+ -+ if (ql2xenforce_iocb_limit == 2) { -+ iocbs_used = atomic_read(&ha->fwres.iocb_used); -+ exch_used = atomic_read(&ha->fwres.exch_used); -+ seq_printf(s, " estimate iocb2 used [%d] high water limit [%d]\n", -+ iocbs_used, ha->fwres.iocb_limit); -+ -+ seq_printf(s, " estimate exchange2 used[%d] high water limit [%d] \n", -+ exch_used, ha->fwres.exch_limit); -+ } - } - - return 0; -diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h -index 316122709b0e6..2e4537f9e5b50 100644 ---- a/drivers/scsi/qla2xxx/qla_gbl.h -+++ b/drivers/scsi/qla2xxx/qla_gbl.h -@@ -143,6 +143,7 @@ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess); - void qla_edif_clear_appdata(struct scsi_qla_host *vha, - struct fc_port *fcport); - const char *sc_to_str(uint16_t cmd); -+void qla_adjust_iocb_limit(scsi_qla_host_t *vha); - - /* - * Global Data in qla_os.c source file. -diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c -index 30bbf33e3a6aa..36abdb0de1694 100644 ---- a/drivers/scsi/qla2xxx/qla_init.c -+++ b/drivers/scsi/qla2xxx/qla_init.c -@@ -502,6 +502,7 @@ static - void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea) - { - struct fc_port *fcport = ea->fcport; -+ unsigned long flags; - - ql_dbg(ql_dbg_disc, vha, 0x20d2, - "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n", -@@ -516,9 +517,15 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea) - ql_dbg(ql_dbg_disc, vha, 0x2066, - "%s %8phC: adisc fail: post delete\n", - __func__, ea->fcport->port_name); -+ -+ spin_lock_irqsave(&vha->work_lock, flags); - /* deleted = 0 & logout_on_delete = force fw cleanup */ -- fcport->deleted = 0; -+ if (fcport->deleted == QLA_SESS_DELETED) -+ fcport->deleted = 0; -+ - fcport->logout_on_delete = 1; -+ spin_unlock_irqrestore(&vha->work_lock, flags); -+ - qlt_schedule_sess_for_deletion(ea->fcport); - return; - } -@@ -1128,7 +1135,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) - u16 *mb; - - if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) -- return rval; -+ goto done; - - ql_dbg(ql_dbg_disc, vha, 0x20d9, - "Async-gnlist WWPN %8phC \n", fcport->port_name); -@@ -1182,8 +1189,9 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) - done_free_sp: - /* ref: INIT */ - kref_put(&sp->cmd_kref, qla2x00_sp_release); -+ fcport->flags &= ~(FCF_ASYNC_SENT); - done: -- fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT); -+ fcport->flags &= ~(FCF_ASYNC_ACTIVE); - return rval; - } - -@@ -1440,7 +1448,6 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) - - spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); - ea->fcport->login_gen++; -- ea->fcport->deleted = 0; - ea->fcport->logout_on_delete = 1; - - if (!ea->fcport->login_succ && !IS_SW_RESV_ADDR(ea->fcport->d_id)) { -@@ -1997,12 +2004,11 @@ qla2x00_tmf_iocb_timeout(void *data) - int rc, h; - unsigned long flags; - -- if (sp->type == SRB_MARKER) { -- complete(&tmf->u.tmf.comp); -- return; -- } -+ if (sp->type == SRB_MARKER) -+ rc = QLA_FUNCTION_FAILED; -+ else -+ rc = qla24xx_async_abort_cmd(sp, false); - -- rc = qla24xx_async_abort_cmd(sp, false); - if (rc) { - spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); - for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { -@@ -2033,10 +2039,14 @@ static void qla_marker_sp_done(srb_t *sp, int res) - complete(&tmf->u.tmf.comp); - } - --#define START_SP_W_RETRIES(_sp, _rval) \ -+#define START_SP_W_RETRIES(_sp, _rval, _chip_gen, _login_gen) \ - {\ - int cnt = 5; \ - do { \ -+ if (_chip_gen != sp->vha->hw->chip_reset || _login_gen != sp->fcport->login_gen) {\ -+ _rval = EINVAL; \ -+ break; \ -+ } \ - _rval = qla2x00_start_sp(_sp); \ - if (_rval == EAGAIN) \ - msleep(1); \ -@@ -2059,6 +2069,7 @@ qla26xx_marker(struct tmf_arg *arg) - srb_t *sp; - int rval = QLA_FUNCTION_FAILED; - fc_port_t *fcport = arg->fcport; -+ u32 chip_gen, login_gen; - - if (TMF_NOT_READY(arg->fcport)) { - ql_dbg(ql_dbg_taskm, vha, 0x8039, -@@ -2068,6 +2079,9 @@ qla26xx_marker(struct tmf_arg *arg) - return QLA_SUSPENDED; - } - -+ chip_gen = vha->hw->chip_reset; -+ login_gen = fcport->login_gen; -+ - /* ref: INIT */ - sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL); - if (!sp) -@@ -2085,7 +2099,7 @@ qla26xx_marker(struct tmf_arg *arg) - tm_iocb->u.tmf.loop_id = fcport->loop_id; - tm_iocb->u.tmf.vp_index = vha->vp_idx; - -- START_SP_W_RETRIES(sp, rval); -+ START_SP_W_RETRIES(sp, rval, chip_gen, login_gen); - - ql_dbg(ql_dbg_taskm, vha, 0x8006, - "Async-marker hdl=%x loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d rval %d.\n", -@@ -2124,6 +2138,17 @@ static void qla2x00_tmf_sp_done(srb_t *sp, int res) - complete(&tmf->u.tmf.comp); - } - -+static int qla_tmf_wait(struct tmf_arg *arg) -+{ -+ /* there are only 2 types of error handling that reaches here, lun or target reset */ -+ if (arg->flags & (TCF_LUN_RESET | TCF_ABORT_TASK_SET | TCF_CLEAR_TASK_SET)) -+ return qla2x00_eh_wait_for_pending_commands(arg->vha, -+ arg->fcport->d_id.b24, arg->lun, WAIT_LUN); -+ else -+ return qla2x00_eh_wait_for_pending_commands(arg->vha, -+ arg->fcport->d_id.b24, arg->lun, WAIT_TARGET); -+} -+ - static int - __qla2x00_async_tm_cmd(struct tmf_arg *arg) - { -@@ -2131,8 +2156,9 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg) - struct srb_iocb *tm_iocb; - srb_t *sp; - int rval = QLA_FUNCTION_FAILED; -- - fc_port_t *fcport = arg->fcport; -+ u32 chip_gen, login_gen; -+ u64 jif; - - if (TMF_NOT_READY(arg->fcport)) { - ql_dbg(ql_dbg_taskm, vha, 0x8032, -@@ -2142,6 +2168,9 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg) - return QLA_SUSPENDED; - } - -+ chip_gen = vha->hw->chip_reset; -+ login_gen = fcport->login_gen; -+ - /* ref: INIT */ - sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL); - if (!sp) -@@ -2159,7 +2188,7 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg) - tm_iocb->u.tmf.flags = arg->flags; - tm_iocb->u.tmf.lun = arg->lun; - -- START_SP_W_RETRIES(sp, rval); -+ START_SP_W_RETRIES(sp, rval, chip_gen, login_gen); - - ql_dbg(ql_dbg_taskm, vha, 0x802f, - "Async-tmf hdl=%x loop-id=%x portid=%06x ctrl=%x lun=%lld qp=%d rval=%x.\n", -@@ -2177,8 +2206,26 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg) - "TM IOCB failed (%x).\n", rval); - } - -- if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) -- rval = qla26xx_marker(arg); -+ if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) { -+ jif = jiffies; -+ if (qla_tmf_wait(arg)) { -+ ql_log(ql_log_info, vha, 0x803e, -+ "Waited %u ms Nexus=%ld:%06x:%llu.\n", -+ jiffies_to_msecs(jiffies - jif), vha->host_no, -+ fcport->d_id.b24, arg->lun); -+ } -+ -+ if (chip_gen == vha->hw->chip_reset && login_gen == fcport->login_gen) { -+ rval = qla26xx_marker(arg); -+ } else { -+ ql_log(ql_log_info, vha, 0x803e, -+ "Skip Marker due to disruption. Nexus=%ld:%06x:%llu.\n", -+ vha->host_no, fcport->d_id.b24, arg->lun); -+ rval = QLA_FUNCTION_FAILED; -+ } -+ } -+ if (tm_iocb->u.tmf.data) -+ rval = tm_iocb->u.tmf.data; - - done_free_sp: - /* ref: INIT */ -@@ -2187,30 +2234,42 @@ done: - return rval; - } - --static void qla_put_tmf(fc_port_t *fcport) -+static void qla_put_tmf(struct tmf_arg *arg) - { -- struct scsi_qla_host *vha = fcport->vha; -+ struct scsi_qla_host *vha = arg->vha; - struct qla_hw_data *ha = vha->hw; - unsigned long flags; - - spin_lock_irqsave(&ha->tgt.sess_lock, flags); -- fcport->active_tmf--; -+ ha->active_tmf--; -+ list_del(&arg->tmf_elem); - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); - } - - static --int qla_get_tmf(fc_port_t *fcport) -+int qla_get_tmf(struct tmf_arg *arg) - { -- struct scsi_qla_host *vha = fcport->vha; -+ struct scsi_qla_host *vha = arg->vha; - struct qla_hw_data *ha = vha->hw; - unsigned long flags; -+ fc_port_t *fcport = arg->fcport; - int rc = 0; -- LIST_HEAD(tmf_elem); -+ struct tmf_arg *t; - - spin_lock_irqsave(&ha->tgt.sess_lock, flags); -- list_add_tail(&tmf_elem, &fcport->tmf_pending); -+ list_for_each_entry(t, &ha->tmf_active, tmf_elem) { -+ if (t->fcport == arg->fcport && t->lun == arg->lun) { -+ /* reject duplicate TMF */ -+ ql_log(ql_log_warn, vha, 0x802c, -+ "found duplicate TMF. Nexus=%ld:%06x:%llu.\n", -+ vha->host_no, fcport->d_id.b24, arg->lun); -+ spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); -+ return -EINVAL; -+ } -+ } - -- while (fcport->active_tmf >= MAX_ACTIVE_TMF) { -+ list_add_tail(&arg->tmf_elem, &ha->tmf_pending); -+ while (ha->active_tmf >= MAX_ACTIVE_TMF) { - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); - - msleep(1); -@@ -2222,15 +2281,17 @@ int qla_get_tmf(fc_port_t *fcport) - rc = EIO; - break; - } -- if (fcport->active_tmf < MAX_ACTIVE_TMF && -- list_is_first(&tmf_elem, &fcport->tmf_pending)) -+ if (ha->active_tmf < MAX_ACTIVE_TMF && -+ list_is_first(&arg->tmf_elem, &ha->tmf_pending)) - break; - } - -- list_del(&tmf_elem); -+ list_del(&arg->tmf_elem); - -- if (!rc) -- fcport->active_tmf++; -+ if (!rc) { -+ ha->active_tmf++; -+ list_add_tail(&arg->tmf_elem, &ha->tmf_active); -+ } - - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); - -@@ -2242,9 +2303,8 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun, - uint32_t tag) - { - struct scsi_qla_host *vha = fcport->vha; -- struct qla_qpair *qpair; - struct tmf_arg a; -- int i, rval = QLA_SUCCESS; -+ int rval = QLA_SUCCESS; - - if (TMF_NOT_READY(fcport)) - return QLA_SUSPENDED; -@@ -2252,47 +2312,22 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun, - a.vha = fcport->vha; - a.fcport = fcport; - a.lun = lun; -+ a.flags = flags; -+ INIT_LIST_HEAD(&a.tmf_elem); -+ - if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) { - a.modifier = MK_SYNC_ID_LUN; -- -- if (qla_get_tmf(fcport)) -- return QLA_FUNCTION_FAILED; - } else { - a.modifier = MK_SYNC_ID; - } - -- if (vha->hw->mqenable) { -- for (i = 0; i < vha->hw->num_qpairs; i++) { -- qpair = vha->hw->queue_pair_map[i]; -- if (!qpair) -- continue; -- -- if (TMF_NOT_READY(fcport)) { -- ql_log(ql_log_warn, vha, 0x8026, -- "Unable to send TM due to disruption.\n"); -- rval = QLA_SUSPENDED; -- break; -- } -- -- a.qpair = qpair; -- a.flags = flags|TCF_NOTMCMD_TO_TARGET; -- rval = __qla2x00_async_tm_cmd(&a); -- if (rval) -- break; -- } -- } -- -- if (rval) -- goto bailout; -+ if (qla_get_tmf(&a)) -+ return QLA_FUNCTION_FAILED; - - a.qpair = vha->hw->base_qpair; -- a.flags = flags; - rval = __qla2x00_async_tm_cmd(&a); - --bailout: -- if (a.modifier == MK_SYNC_ID_LUN) -- qla_put_tmf(fcport); -- -+ qla_put_tmf(&a); - return rval; - } - -@@ -4148,39 +4183,61 @@ out: - return ha->flags.lr_detected; - } - --void qla_init_iocb_limit(scsi_qla_host_t *vha) -+static void __qla_adjust_iocb_limit(struct qla_qpair *qpair) - { -- u16 i, num_qps; -- u32 limit; -- struct qla_hw_data *ha = vha->hw; -+ u8 num_qps; -+ u16 limit; -+ struct qla_hw_data *ha = qpair->vha->hw; - - num_qps = ha->num_qpairs + 1; - limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100; - -- ha->base_qpair->fwres.iocbs_total = ha->orig_fw_iocb_count; -- ha->base_qpair->fwres.iocbs_limit = limit; -- ha->base_qpair->fwres.iocbs_qp_limit = limit / num_qps; -- ha->base_qpair->fwres.iocbs_used = 0; -+ qpair->fwres.iocbs_total = ha->orig_fw_iocb_count; -+ qpair->fwres.iocbs_limit = limit; -+ qpair->fwres.iocbs_qp_limit = limit / num_qps; -+ -+ qpair->fwres.exch_total = ha->orig_fw_xcb_count; -+ qpair->fwres.exch_limit = (ha->orig_fw_xcb_count * -+ QLA_IOCB_PCT_LIMIT) / 100; -+} -+ -+void qla_init_iocb_limit(scsi_qla_host_t *vha) -+{ -+ u8 i; -+ struct qla_hw_data *ha = vha->hw; - -- ha->base_qpair->fwres.exch_total = ha->orig_fw_xcb_count; -- ha->base_qpair->fwres.exch_limit = (ha->orig_fw_xcb_count * -- QLA_IOCB_PCT_LIMIT) / 100; -+ __qla_adjust_iocb_limit(ha->base_qpair); -+ ha->base_qpair->fwres.iocbs_used = 0; - ha->base_qpair->fwres.exch_used = 0; - - for (i = 0; i < ha->max_qpairs; i++) { - if (ha->queue_pair_map[i]) { -- ha->queue_pair_map[i]->fwres.iocbs_total = -- ha->orig_fw_iocb_count; -- ha->queue_pair_map[i]->fwres.iocbs_limit = limit; -- ha->queue_pair_map[i]->fwres.iocbs_qp_limit = -- limit / num_qps; -+ __qla_adjust_iocb_limit(ha->queue_pair_map[i]); - ha->queue_pair_map[i]->fwres.iocbs_used = 0; -- ha->queue_pair_map[i]->fwres.exch_total = ha->orig_fw_xcb_count; -- ha->queue_pair_map[i]->fwres.exch_limit = -- (ha->orig_fw_xcb_count * QLA_IOCB_PCT_LIMIT) / 100; - ha->queue_pair_map[i]->fwres.exch_used = 0; - } - } -+ -+ ha->fwres.iocb_total = ha->orig_fw_iocb_count; -+ ha->fwres.iocb_limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100; -+ ha->fwres.exch_total = ha->orig_fw_xcb_count; -+ ha->fwres.exch_limit = (ha->orig_fw_xcb_count * QLA_IOCB_PCT_LIMIT) / 100; -+ -+ atomic_set(&ha->fwres.iocb_used, 0); -+ atomic_set(&ha->fwres.exch_used, 0); -+} -+ -+void qla_adjust_iocb_limit(scsi_qla_host_t *vha) -+{ -+ u8 i; -+ struct qla_hw_data *ha = vha->hw; -+ -+ __qla_adjust_iocb_limit(ha->base_qpair); -+ -+ for (i = 0; i < ha->max_qpairs; i++) { -+ if (ha->queue_pair_map[i]) -+ __qla_adjust_iocb_limit(ha->queue_pair_map[i]); -+ } - } - - /** -@@ -4778,15 +4835,16 @@ qla2x00_init_rings(scsi_qla_host_t *vha) - if (ha->flags.edif_enabled) - mid_init_cb->init_cb.frame_payload_size = cpu_to_le16(ELS_MAX_PAYLOAD); - -+ QLA_FW_STARTED(ha); - rval = qla2x00_init_firmware(vha, ha->init_cb_size); - next_check: - if (rval) { -+ QLA_FW_STOPPED(ha); - ql_log(ql_log_fatal, vha, 0x00d2, - "Init Firmware **** FAILED ****.\n"); - } else { - ql_dbg(ql_dbg_init, vha, 0x00d3, - "Init Firmware -- success.\n"); -- QLA_FW_STARTED(ha); - vha->u_ql2xexchoffld = vha->u_ql2xiniexchg = 0; - } - -@@ -5528,7 +5586,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) - INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); - INIT_LIST_HEAD(&fcport->gnl_entry); - INIT_LIST_HEAD(&fcport->list); -- INIT_LIST_HEAD(&fcport->tmf_pending); - - INIT_LIST_HEAD(&fcport->sess_cmd_list); - spin_lock_init(&fcport->sess_cmd_lock); -@@ -6116,6 +6173,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) - void - qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) - { -+ unsigned long flags; -+ - if (IS_SW_RESV_ADDR(fcport->d_id)) - return; - -@@ -6125,7 +6184,11 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) - qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); - fcport->login_retry = vha->hw->login_retry_count; - fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); -+ -+ spin_lock_irqsave(&vha->work_lock, flags); - fcport->deleted = 0; -+ spin_unlock_irqrestore(&vha->work_lock, flags); -+ - if (vha->hw->current_topology == ISP_CFG_NL) - fcport->logout_on_delete = 0; - else -@@ -7391,14 +7454,15 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) - } - - /* purge MBox commands */ -- if (atomic_read(&ha->num_pend_mbx_stage3)) { -+ spin_lock_irqsave(&ha->hardware_lock, flags); -+ if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) { - clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); - complete(&ha->mbx_intr_comp); - } -+ spin_unlock_irqrestore(&ha->hardware_lock, flags); - - i = 0; -- while (atomic_read(&ha->num_pend_mbx_stage3) || -- atomic_read(&ha->num_pend_mbx_stage2) || -+ while (atomic_read(&ha->num_pend_mbx_stage2) || - atomic_read(&ha->num_pend_mbx_stage1)) { - msleep(20); - i++; -diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h -index a034699e58ae9..a7b5d11146827 100644 ---- a/drivers/scsi/qla2xxx/qla_inline.h -+++ b/drivers/scsi/qla2xxx/qla_inline.h -@@ -386,6 +386,7 @@ enum { - RESOURCE_IOCB = BIT_0, - RESOURCE_EXCH = BIT_1, /* exchange */ - RESOURCE_FORCE = BIT_2, -+ RESOURCE_HA = BIT_3, - }; - - static inline int -@@ -393,7 +394,7 @@ qla_get_fw_resources(struct qla_qpair *qp, struct iocb_resource *iores) - { - u16 iocbs_used, i; - u16 exch_used; -- struct qla_hw_data *ha = qp->vha->hw; -+ struct qla_hw_data *ha = qp->hw; - - if (!ql2xenforce_iocb_limit) { - iores->res_type = RESOURCE_NONE; -@@ -428,15 +429,69 @@ qla_get_fw_resources(struct qla_qpair *qp, struct iocb_resource *iores) - return -ENOSPC; - } - } -+ -+ if (ql2xenforce_iocb_limit == 2) { -+ if ((iores->iocb_cnt + atomic_read(&ha->fwres.iocb_used)) >= -+ ha->fwres.iocb_limit) { -+ iores->res_type = RESOURCE_NONE; -+ return -ENOSPC; -+ } -+ -+ if (iores->res_type & RESOURCE_EXCH) { -+ if ((iores->exch_cnt + atomic_read(&ha->fwres.exch_used)) >= -+ ha->fwres.exch_limit) { -+ iores->res_type = RESOURCE_NONE; -+ return -ENOSPC; -+ } -+ } -+ } -+ - force: - qp->fwres.iocbs_used += iores->iocb_cnt; - qp->fwres.exch_used += iores->exch_cnt; -+ if (ql2xenforce_iocb_limit == 2) { -+ atomic_add(iores->iocb_cnt, &ha->fwres.iocb_used); -+ atomic_add(iores->exch_cnt, &ha->fwres.exch_used); -+ iores->res_type |= RESOURCE_HA; -+ } - return 0; - } - -+/* -+ * decrement to zero. This routine will not decrement below zero -+ * @v: pointer of type atomic_t -+ * @amount: amount to decrement from v -+ */ -+static void qla_atomic_dtz(atomic_t *v, int amount) -+{ -+ int c, old, dec; -+ -+ c = atomic_read(v); -+ for (;;) { -+ dec = c - amount; -+ if (unlikely(dec < 0)) -+ dec = 0; -+ -+ old = atomic_cmpxchg((v), c, dec); -+ if (likely(old == c)) -+ break; -+ c = old; -+ } -+} -+ - static inline void - qla_put_fw_resources(struct qla_qpair *qp, struct iocb_resource *iores) - { -+ struct qla_hw_data *ha = qp->hw; -+ -+ if (iores->res_type & RESOURCE_HA) { -+ if (iores->res_type & RESOURCE_IOCB) -+ qla_atomic_dtz(&ha->fwres.iocb_used, iores->iocb_cnt); -+ -+ if (iores->res_type & RESOURCE_EXCH) -+ qla_atomic_dtz(&ha->fwres.exch_used, iores->exch_cnt); -+ } -+ - if (iores->res_type & RESOURCE_IOCB) { - if (qp->fwres.iocbs_used >= iores->iocb_cnt) { - qp->fwres.iocbs_used -= iores->iocb_cnt; -diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c -index c9a686f06d29d..9e524d52dc862 100644 ---- a/drivers/scsi/qla2xxx/qla_iocb.c -+++ b/drivers/scsi/qla2xxx/qla_iocb.c -@@ -3887,6 +3887,7 @@ qla_marker_iocb(srb_t *sp, struct mrk_entry_24xx *mrk) - { - mrk->entry_type = MARKER_TYPE; - mrk->modifier = sp->u.iocb_cmd.u.tmf.modifier; -+ mrk->handle = make_handle(sp->qpair->req->id, sp->handle); - if (sp->u.iocb_cmd.u.tmf.modifier != MK_SYNC_ALL) { - mrk->nport_handle = cpu_to_le16(sp->u.iocb_cmd.u.tmf.loop_id); - int_to_scsilun(sp->u.iocb_cmd.u.tmf.lun, (struct scsi_lun *)&mrk->lun); -diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c -index b41d604ca9bc8..0111249cc8774 100644 ---- a/drivers/scsi/qla2xxx/qla_isr.c -+++ b/drivers/scsi/qla2xxx/qla_isr.c -@@ -1121,8 +1121,12 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) - unsigned long flags; - fc_port_t *fcport = NULL; - -- if (!vha->hw->flags.fw_started) -+ if (!vha->hw->flags.fw_started) { -+ ql_log(ql_log_warn, vha, 0x50ff, -+ "Dropping AEN - %04x %04x %04x %04x.\n", -+ mb[0], mb[1], mb[2], mb[3]); - return; -+ } - - /* Setup to process RIO completion. */ - handle_cnt = 0; -@@ -2539,7 +2543,6 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) - case CS_PORT_BUSY: - case CS_INCOMPLETE: - case CS_PORT_UNAVAILABLE: -- case CS_TIMEOUT: - case CS_RESET: - if (atomic_read(&fcport->state) == FCS_ONLINE) { - ql_dbg(ql_dbg_disc, fcport->vha, 0x3021, -diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c -index 359595a64664c..f794f4363a38c 100644 ---- a/drivers/scsi/qla2xxx/qla_mbx.c -+++ b/drivers/scsi/qla2xxx/qla_mbx.c -@@ -273,7 +273,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - wait_time = jiffies; -- atomic_inc(&ha->num_pend_mbx_stage3); - if (!wait_for_completion_timeout(&ha->mbx_intr_comp, - mcp->tov * HZ)) { - ql_dbg(ql_dbg_mbx, vha, 0x117a, -@@ -290,7 +289,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) - spin_unlock_irqrestore(&ha->hardware_lock, - flags); - atomic_dec(&ha->num_pend_mbx_stage2); -- atomic_dec(&ha->num_pend_mbx_stage3); - rval = QLA_ABORTED; - goto premature_exit; - } -@@ -302,11 +300,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) - ha->flags.mbox_busy = 0; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - atomic_dec(&ha->num_pend_mbx_stage2); -- atomic_dec(&ha->num_pend_mbx_stage3); - rval = QLA_ABORTED; - goto premature_exit; - } -- atomic_dec(&ha->num_pend_mbx_stage3); - - if (time_after(jiffies, wait_time + 5 * HZ)) - ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n", -@@ -2213,6 +2209,9 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states) - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054, - "Entered %s.\n", __func__); - -+ if (!ha->flags.fw_started) -+ return QLA_FUNCTION_FAILED; -+ - mcp->mb[0] = MBC_GET_FIRMWARE_STATE; - mcp->out_mb = MBX_0; - if (IS_FWI2_CAPABLE(vha->hw)) -diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c -index 57545d5e82b9d..c9a6fc882a801 100644 ---- a/drivers/scsi/qla2xxx/qla_nvme.c -+++ b/drivers/scsi/qla2xxx/qla_nvme.c -@@ -132,6 +132,7 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport, - "Failed to allocate qpair\n"); - return -EINVAL; - } -+ qla_adjust_iocb_limit(vha); - } - *handle = qpair; - -@@ -663,7 +664,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, - - rval = qla2x00_start_nvme_mq(sp); - if (rval != QLA_SUCCESS) { -- ql_log(ql_log_warn, vha, 0x212d, -+ ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x212d, - "qla2x00_start_nvme_mq failed = %d\n", rval); - sp->priv = NULL; - priv->sp = NULL; -diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c -index ed70eb8847864..78f7cd16967fa 100644 ---- a/drivers/scsi/qla2xxx/qla_os.c -+++ b/drivers/scsi/qla2xxx/qla_os.c -@@ -44,10 +44,11 @@ module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR); - MODULE_PARM_DESC(ql2xfulldump_on_mpifail, - "Set this to take full dump on MPI hang."); - --int ql2xenforce_iocb_limit = 1; -+int ql2xenforce_iocb_limit = 2; - module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR); - MODULE_PARM_DESC(ql2xenforce_iocb_limit, -- "Enforce IOCB throttling, to avoid FW congestion. (default: 1)"); -+ "Enforce IOCB throttling, to avoid FW congestion. (default: 2) " -+ "1: track usage per queue, 2: track usage per adapter"); - - /* - * CT6 CTX allocation cache -@@ -1478,8 +1479,9 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) - goto eh_reset_failed; - } - err = 3; -- if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id, -- sdev->lun, WAIT_LUN) != QLA_SUCCESS) { -+ if (qla2x00_eh_wait_for_pending_commands(vha, fcport->d_id.b24, -+ cmd->device->lun, -+ WAIT_LUN) != QLA_SUCCESS) { - ql_log(ql_log_warn, vha, 0x800d, - "wait for pending cmds failed for cmd=%p.\n", cmd); - goto eh_reset_failed; -@@ -1545,8 +1547,8 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) - goto eh_reset_failed; - } - err = 3; -- if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id, -- 0, WAIT_TARGET) != QLA_SUCCESS) { -+ if (qla2x00_eh_wait_for_pending_commands(vha, fcport->d_id.b24, 0, -+ WAIT_TARGET) != QLA_SUCCESS) { - ql_log(ql_log_warn, vha, 0x800d, - "wait for pending cmds failed for cmd=%p.\n", cmd); - goto eh_reset_failed; -@@ -2999,9 +3001,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) - ha->max_exchg = FW_MAX_EXCHANGES_CNT; - atomic_set(&ha->num_pend_mbx_stage1, 0); - atomic_set(&ha->num_pend_mbx_stage2, 0); -- atomic_set(&ha->num_pend_mbx_stage3, 0); - atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD); - ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD; -+ INIT_LIST_HEAD(&ha->tmf_pending); -+ INIT_LIST_HEAD(&ha->tmf_active); - - /* Assign ISP specific operations. */ - if (IS_QLA2100(ha)) { -@@ -3278,6 +3281,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) - host->max_id = ha->max_fibre_devices; - host->cmd_per_lun = 3; - host->unique_id = host->host_no; -+ -+ if (ql2xenabledif && ql2xenabledif != 2) { -+ ql_log(ql_log_warn, base_vha, 0x302d, -+ "Invalid value for ql2xenabledif, resetting it to default (2)\n"); -+ ql2xenabledif = 2; -+ } -+ - if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) - host->max_cmd_len = 32; - else -@@ -3515,8 +3525,6 @@ skip_dpc: - base_vha->flags.difdix_supported = 1; - ql_dbg(ql_dbg_init, base_vha, 0x00f1, - "Registering for DIF/DIX type 1 and 3 protection.\n"); -- if (ql2xenabledif == 1) -- prot = SHOST_DIX_TYPE0_PROTECTION; - if (ql2xprotmask) - scsi_host_set_prot(host, ql2xprotmask); - else -diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c -index bb754a9508023..545473a0ffc84 100644 ---- a/drivers/scsi/qla2xxx/qla_target.c -+++ b/drivers/scsi/qla2xxx/qla_target.c -@@ -1085,10 +1085,6 @@ void qlt_free_session_done(struct work_struct *work) - (struct imm_ntfy_from_isp *)sess->iocb, SRB_NACK_LOGO); - } - -- spin_lock_irqsave(&vha->work_lock, flags); -- sess->flags &= ~FCF_ASYNC_SENT; -- spin_unlock_irqrestore(&vha->work_lock, flags); -- - spin_lock_irqsave(&ha->tgt.sess_lock, flags); - if (sess->se_sess) { - sess->se_sess = NULL; -@@ -1098,7 +1094,6 @@ void qlt_free_session_done(struct work_struct *work) - - qla2x00_set_fcport_disc_state(sess, DSC_DELETED); - sess->fw_login_state = DSC_LS_PORT_UNAVAIL; -- sess->deleted = QLA_SESS_DELETED; - - if (sess->login_succ && !IS_SW_RESV_ADDR(sess->d_id)) { - vha->fcport_count--; -@@ -1150,10 +1145,15 @@ void qlt_free_session_done(struct work_struct *work) - - sess->explicit_logout = 0; - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); -- sess->free_pending = 0; - - qla2x00_dfs_remove_rport(vha, sess); - -+ spin_lock_irqsave(&vha->work_lock, flags); -+ sess->flags &= ~FCF_ASYNC_SENT; -+ sess->deleted = QLA_SESS_DELETED; -+ sess->free_pending = 0; -+ spin_unlock_irqrestore(&vha->work_lock, flags); -+ - ql_dbg(ql_dbg_disc, vha, 0xf001, - "Unregistration of sess %p %8phC finished fcp_cnt %d\n", - sess, sess->port_name, vha->fcport_count); -@@ -1202,12 +1202,12 @@ void qlt_unreg_sess(struct fc_port *sess) - * management from being sent. - */ - sess->flags |= FCF_ASYNC_SENT; -+ sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; - spin_unlock_irqrestore(&sess->vha->work_lock, flags); - - if (sess->se_sess) - vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); - -- sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; - qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); - sess->last_rscn_gen = sess->rscn_gen; - sess->last_login_gen = sess->login_gen; -diff --git a/drivers/soc/qcom/qmi_encdec.c b/drivers/soc/qcom/qmi_encdec.c -index b7158e3c3a0bd..5c7161b18b724 100644 ---- a/drivers/soc/qcom/qmi_encdec.c -+++ b/drivers/soc/qcom/qmi_encdec.c -@@ -534,8 +534,8 @@ static int qmi_decode_string_elem(const struct qmi_elem_info *ei_array, - decoded_bytes += rc; - } - -- if (string_len > temp_ei->elem_len) { -- pr_err("%s: String len %d > Max Len %d\n", -+ if (string_len >= temp_ei->elem_len) { -+ pr_err("%s: String len %d >= Max Len %d\n", - __func__, string_len, temp_ei->elem_len); - return -ETOOSMALL; - } else if (string_len > tlv_len) { -diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c -index 5c5c99f7979e3..30ec5b6845335 100644 ---- a/drivers/video/backlight/gpio_backlight.c -+++ b/drivers/video/backlight/gpio_backlight.c -@@ -87,8 +87,7 @@ static int gpio_backlight_probe(struct platform_device *pdev) - /* Not booted with device tree or no phandle link to the node */ - bl->props.power = def_value ? FB_BLANK_UNBLANK - : FB_BLANK_POWERDOWN; -- else if (gpiod_get_direction(gbl->gpiod) == 0 && -- gpiod_get_value_cansleep(gbl->gpiod) == 0) -+ else if (gpiod_get_value_cansleep(gbl->gpiod) == 0) - bl->props.power = FB_BLANK_POWERDOWN; - else - bl->props.power = FB_BLANK_UNBLANK; -diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c -index 305f1587bd898..8b2bc4adc50f7 100644 ---- a/drivers/video/fbdev/ep93xx-fb.c -+++ b/drivers/video/fbdev/ep93xx-fb.c -@@ -474,7 +474,6 @@ static int ep93xxfb_probe(struct platform_device *pdev) - if (!info) - return -ENOMEM; - -- info->dev = &pdev->dev; - platform_set_drvdata(pdev, info); - fbi = info->par; - fbi->mach_info = mach_info; -diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c -index 9b2173f765c8c..fb7fae750181b 100644 ---- a/drivers/watchdog/intel-mid_wdt.c -+++ b/drivers/watchdog/intel-mid_wdt.c -@@ -203,3 +203,4 @@ module_platform_driver(mid_wdt_driver); - MODULE_AUTHOR("David Cohen "); - MODULE_DESCRIPTION("Watchdog Driver for Intel MID platform"); - MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:intel_mid_wdt"); -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 96369c44863a1..64daae693afd1 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -2721,11 +2721,10 @@ int btrfs_validate_super(struct btrfs_fs_info *fs_info, - ret = -EINVAL; - } - -- if (memcmp(fs_info->fs_devices->fsid, fs_info->super_copy->fsid, -- BTRFS_FSID_SIZE)) { -+ if (memcmp(fs_info->fs_devices->fsid, sb->fsid, BTRFS_FSID_SIZE) != 0) { - btrfs_err(fs_info, - "superblock fsid doesn't match fsid of fs_devices: %pU != %pU", -- fs_info->super_copy->fsid, fs_info->fs_devices->fsid); -+ sb->fsid, fs_info->fs_devices->fsid); - ret = -EINVAL; - } - -diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c -index f2ee70c03f0d5..0640ef59fe660 100644 ---- a/fs/btrfs/extent-tree.c -+++ b/fs/btrfs/extent-tree.c -@@ -3810,7 +3810,8 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group, - fs_info->data_reloc_bg == 0); - - if (block_group->ro || -- test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags)) { -+ (!ffe_ctl->for_data_reloc && -+ test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags))) { - ret = 1; - goto out; - } -@@ -3853,8 +3854,26 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group, - if (ffe_ctl->for_treelog && !fs_info->treelog_bg) - fs_info->treelog_bg = block_group->start; - -- if (ffe_ctl->for_data_reloc && !fs_info->data_reloc_bg) -- fs_info->data_reloc_bg = block_group->start; -+ if (ffe_ctl->for_data_reloc) { -+ if (!fs_info->data_reloc_bg) -+ fs_info->data_reloc_bg = block_group->start; -+ /* -+ * Do not allow allocations from this block group, unless it is -+ * for data relocation. Compared to increasing the ->ro, setting -+ * the ->zoned_data_reloc_ongoing flag still allows nocow -+ * writers to come in. See btrfs_inc_nocow_writers(). -+ * -+ * We need to disable an allocation to avoid an allocation of -+ * regular (non-relocation data) extent. With mix of relocation -+ * extents and regular extents, we can dispatch WRITE commands -+ * (for relocation extents) and ZONE APPEND commands (for -+ * regular extents) at the same time to the same zone, which -+ * easily break the write pointer. -+ * -+ * Also, this flag avoids this block group to be zone finished. -+ */ -+ set_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags); -+ } - - ffe_ctl->found_offset = start + block_group->alloc_offset; - block_group->alloc_offset += num_bytes; -@@ -3872,24 +3891,8 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group, - out: - if (ret && ffe_ctl->for_treelog) - fs_info->treelog_bg = 0; -- if (ret && ffe_ctl->for_data_reloc && -- fs_info->data_reloc_bg == block_group->start) { -- /* -- * Do not allow further allocations from this block group. -- * Compared to increasing the ->ro, setting the -- * ->zoned_data_reloc_ongoing flag still allows nocow -- * writers to come in. See btrfs_inc_nocow_writers(). -- * -- * We need to disable an allocation to avoid an allocation of -- * regular (non-relocation data) extent. With mix of relocation -- * extents and regular extents, we can dispatch WRITE commands -- * (for relocation extents) and ZONE APPEND commands (for -- * regular extents) at the same time to the same zone, which -- * easily break the write pointer. -- */ -- set_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags); -+ if (ret && ffe_ctl->for_data_reloc) - fs_info->data_reloc_bg = 0; -- } - spin_unlock(&fs_info->relocation_bg_lock); - spin_unlock(&fs_info->treelog_bg_lock); - spin_unlock(&block_group->lock); -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 28bcba2e05908..222068bf80031 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -3393,6 +3393,13 @@ out: - btrfs_free_reserved_extent(fs_info, - ordered_extent->disk_bytenr, - ordered_extent->disk_num_bytes, 1); -+ /* -+ * Actually free the qgroup rsv which was released when -+ * the ordered extent was created. -+ */ -+ btrfs_qgroup_free_refroot(fs_info, inode->root->root_key.objectid, -+ ordered_extent->qgroup_rsv, -+ BTRFS_QGROUP_RSV_DATA); - } - } - -diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c -index d3591c7f166ad..d2bdcc2cce498 100644 ---- a/fs/btrfs/relocation.c -+++ b/fs/btrfs/relocation.c -@@ -2985,9 +2985,6 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, - if (!page) - return -ENOMEM; - } -- ret = set_page_extent_mapped(page); -- if (ret < 0) -- goto release_page; - - if (PageReadahead(page)) - page_cache_async_readahead(inode->i_mapping, ra, NULL, -@@ -3003,6 +3000,15 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, - } - } - -+ /* -+ * We could have lost page private when we dropped the lock to read the -+ * page above, make sure we set_page_extent_mapped here so we have any -+ * of the subpage blocksize stuff we need in place. -+ */ -+ ret = set_page_extent_mapped(page); -+ if (ret < 0) -+ goto release_page; -+ - page_start = page_offset(page); - page_end = page_start + PAGE_SIZE - 1; - -diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c -index c7642c00a65d0..2635fb4bffa06 100644 ---- a/fs/btrfs/space-info.c -+++ b/fs/btrfs/space-info.c -@@ -404,11 +404,7 @@ int btrfs_can_overcommit(struct btrfs_fs_info *fs_info, - return 0; - - used = btrfs_space_info_used(space_info, true); -- if (test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &fs_info->flags) && -- (space_info->flags & BTRFS_BLOCK_GROUP_METADATA)) -- avail = 0; -- else -- avail = calc_available_free_space(fs_info, space_info, flush); -+ avail = calc_available_free_space(fs_info, space_info, flush); - - if (used + bytes < writable_total_bytes(fs_info, space_info) + avail) - return 1; -diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c -index 2b776fce1c0ff..a555567594418 100644 ---- a/fs/btrfs/transaction.c -+++ b/fs/btrfs/transaction.c -@@ -279,10 +279,11 @@ loop: - spin_unlock(&fs_info->trans_lock); - - /* -- * If we are ATTACH, we just want to catch the current transaction, -- * and commit it. If there is no transaction, just return ENOENT. -+ * If we are ATTACH or TRANS_JOIN_NOSTART, we just want to catch the -+ * current transaction, and commit it. If there is no transaction, just -+ * return ENOENT. - */ -- if (type == TRANS_ATTACH) -+ if (type == TRANS_ATTACH || type == TRANS_JOIN_NOSTART) - return -ENOENT; - - /* -@@ -580,8 +581,13 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, - u64 delayed_refs_bytes = 0; - - qgroup_reserved = num_items * fs_info->nodesize; -- ret = btrfs_qgroup_reserve_meta_pertrans(root, qgroup_reserved, -- enforce_qgroups); -+ /* -+ * Use prealloc for now, as there might be a currently running -+ * transaction that could free this reserved space prematurely -+ * by committing. -+ */ -+ ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserved, -+ enforce_qgroups, false); - if (ret) - return ERR_PTR(ret); - -@@ -693,6 +699,14 @@ again: - h->reloc_reserved = reloc_reserved; - } - -+ /* -+ * Now that we have found a transaction to be a part of, convert the -+ * qgroup reservation from prealloc to pertrans. A different transaction -+ * can't race in and free our pertrans out from under us. -+ */ -+ if (qgroup_reserved) -+ btrfs_qgroup_convert_reserved_meta(root, qgroup_reserved); -+ - got_it: - if (!current->journal_info) - current->journal_info = h; -@@ -740,7 +754,7 @@ alloc_fail: - btrfs_block_rsv_release(fs_info, &fs_info->trans_block_rsv, - num_bytes, NULL); - reserve_fail: -- btrfs_qgroup_free_meta_pertrans(root, qgroup_reserved); -+ btrfs_qgroup_free_meta_prealloc(root, qgroup_reserved); - return ERR_PTR(ret); - } - -diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c -index 9bc7ac06c5177..675dbed075d8e 100644 ---- a/fs/btrfs/zoned.c -+++ b/fs/btrfs/zoned.c -@@ -2009,6 +2009,10 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ - * and block_group->meta_write_pointer for metadata. - */ - if (!fully_written) { -+ if (test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags)) { -+ spin_unlock(&block_group->lock); -+ return -EAGAIN; -+ } - spin_unlock(&block_group->lock); - - ret = btrfs_inc_block_group_ro(block_group, false); -@@ -2037,7 +2041,9 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ - return 0; - } - -- if (block_group->reserved) { -+ if (block_group->reserved || -+ test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, -+ &block_group->runtime_flags)) { - spin_unlock(&block_group->lock); - btrfs_dec_block_group_ro(block_group); - return -EAGAIN; -@@ -2268,7 +2274,10 @@ void btrfs_zoned_release_data_reloc_bg(struct btrfs_fs_info *fs_info, u64 logica - - /* All relocation extents are written. */ - if (block_group->start + block_group->alloc_offset == logical + length) { -- /* Now, release this block group for further allocations. */ -+ /* -+ * Now, release this block group for further allocations and -+ * zone finish. -+ */ - clear_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, - &block_group->runtime_flags); - } -@@ -2292,7 +2301,8 @@ int btrfs_zone_finish_one_bg(struct btrfs_fs_info *fs_info) - - spin_lock(&block_group->lock); - if (block_group->reserved || block_group->alloc_offset == 0 || -- (block_group->flags & BTRFS_BLOCK_GROUP_SYSTEM)) { -+ (block_group->flags & BTRFS_BLOCK_GROUP_SYSTEM) || -+ test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags)) { - spin_unlock(&block_group->lock); - continue; - } -diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c -index 8e83b51e3c68a..fbd0329cf254e 100644 ---- a/fs/ext4/balloc.c -+++ b/fs/ext4/balloc.c -@@ -910,11 +910,11 @@ unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group) - } - - /* -- * This function returns the number of file system metadata clusters at -+ * This function returns the number of file system metadata blocks at - * the beginning of a block group, including the reserved gdt blocks. - */ --static unsigned ext4_num_base_meta_clusters(struct super_block *sb, -- ext4_group_t block_group) -+unsigned int ext4_num_base_meta_blocks(struct super_block *sb, -+ ext4_group_t block_group) - { - struct ext4_sb_info *sbi = EXT4_SB(sb); - unsigned num; -@@ -932,8 +932,15 @@ static unsigned ext4_num_base_meta_clusters(struct super_block *sb, - } else { /* For META_BG_BLOCK_GROUPS */ - num += ext4_bg_num_gdb(sb, block_group); - } -- return EXT4_NUM_B2C(sbi, num); -+ return num; - } -+ -+static unsigned int ext4_num_base_meta_clusters(struct super_block *sb, -+ ext4_group_t block_group) -+{ -+ return EXT4_NUM_B2C(EXT4_SB(sb), ext4_num_base_meta_blocks(sb, block_group)); -+} -+ - /** - * ext4_inode_to_goal_block - return a hint for block allocation - * @inode: inode for block allocation -diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c -index 5504f72bbbbe7..6fe3c941b5651 100644 ---- a/fs/ext4/block_validity.c -+++ b/fs/ext4/block_validity.c -@@ -215,7 +215,6 @@ int ext4_setup_system_zone(struct super_block *sb) - struct ext4_system_blocks *system_blks; - struct ext4_group_desc *gdp; - ext4_group_t i; -- int flex_size = ext4_flex_bg_size(sbi); - int ret; - - system_blks = kzalloc(sizeof(*system_blks), GFP_KERNEL); -@@ -223,12 +222,13 @@ int ext4_setup_system_zone(struct super_block *sb) - return -ENOMEM; - - for (i=0; i < ngroups; i++) { -+ unsigned int meta_blks = ext4_num_base_meta_blocks(sb, i); -+ - cond_resched(); -- if (ext4_bg_has_super(sb, i) && -- ((i < 5) || ((i % flex_size) == 0))) { -+ if (meta_blks != 0) { - ret = add_system_zone(system_blks, - ext4_group_first_block_no(sb, i), -- ext4_bg_num_gdb(sb, i) + 1, 0); -+ meta_blks, 0); - if (ret) - goto err; - } -diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c -index e20ac0654b3f2..453d4da5de520 100644 ---- a/fs/ext4/crypto.c -+++ b/fs/ext4/crypto.c -@@ -33,6 +33,8 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname, - - #if IS_ENABLED(CONFIG_UNICODE) - err = ext4_fname_setup_ci_filename(dir, iname, fname); -+ if (err) -+ ext4_fname_free_filename(fname); - #endif - return err; - } -@@ -51,6 +53,8 @@ int ext4_fname_prepare_lookup(struct inode *dir, struct dentry *dentry, - - #if IS_ENABLED(CONFIG_UNICODE) - err = ext4_fname_setup_ci_filename(dir, &dentry->d_name, fname); -+ if (err) -+ ext4_fname_free_filename(fname); - #endif - return err; - } -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 0ea3960cb83ee..72abb8d6caf75 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -3096,6 +3096,8 @@ extern const char *ext4_decode_error(struct super_block *sb, int errno, - extern void ext4_mark_group_bitmap_corrupted(struct super_block *sb, - ext4_group_t block_group, - unsigned int flags); -+extern unsigned int ext4_num_base_meta_blocks(struct super_block *sb, -+ ext4_group_t block_group); - - extern __printf(7, 8) - void __ext4_error(struct super_block *, const char *, unsigned int, bool, -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index c2b7d09238941..37dca728ff967 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -2160,15 +2160,6 @@ static inline int f2fs_down_read_trylock(struct f2fs_rwsem *sem) - return down_read_trylock(&sem->internal_rwsem); - } - --#ifdef CONFIG_DEBUG_LOCK_ALLOC --static inline void f2fs_down_read_nested(struct f2fs_rwsem *sem, int subclass) --{ -- down_read_nested(&sem->internal_rwsem, subclass); --} --#else --#define f2fs_down_read_nested(sem, subclass) f2fs_down_read(sem) --#endif -- - static inline void f2fs_up_read(struct f2fs_rwsem *sem) - { - up_read(&sem->internal_rwsem); -@@ -2179,6 +2170,21 @@ static inline void f2fs_down_write(struct f2fs_rwsem *sem) - down_write(&sem->internal_rwsem); - } - -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+static inline void f2fs_down_read_nested(struct f2fs_rwsem *sem, int subclass) -+{ -+ down_read_nested(&sem->internal_rwsem, subclass); -+} -+ -+static inline void f2fs_down_write_nested(struct f2fs_rwsem *sem, int subclass) -+{ -+ down_write_nested(&sem->internal_rwsem, subclass); -+} -+#else -+#define f2fs_down_read_nested(sem, subclass) f2fs_down_read(sem) -+#define f2fs_down_write_nested(sem, subclass) f2fs_down_write(sem) -+#endif -+ - static inline int f2fs_down_write_trylock(struct f2fs_rwsem *sem) - { - return down_write_trylock(&sem->internal_rwsem); -diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c -index 7e867dff681dc..8747eec3d0a34 100644 ---- a/fs/f2fs/inline.c -+++ b/fs/f2fs/inline.c -@@ -642,7 +642,8 @@ int f2fs_add_inline_entry(struct inode *dir, const struct f2fs_filename *fname, - } - - if (inode) { -- f2fs_down_write(&F2FS_I(inode)->i_sem); -+ f2fs_down_write_nested(&F2FS_I(inode)->i_sem, -+ SINGLE_DEPTH_NESTING); - page = f2fs_init_inode_metadata(inode, dir, fname, ipage); - if (IS_ERR(page)) { - err = PTR_ERR(page); -diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c -index cbbf95b995414..16bf9d5c8d4f9 100644 ---- a/fs/f2fs/segment.c -+++ b/fs/f2fs/segment.c -@@ -204,6 +204,8 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean) - f2fs_i_size_write(inode, fi->original_i_size); - fi->original_i_size = 0; - } -+ /* avoid stale dirty inode during eviction */ -+ sync_inode_metadata(inode, 0); - } - - static int __replace_atomic_write_block(struct inode *inode, pgoff_t index, -diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c -index e8deaacf1832a..f40bc51fa5316 100644 ---- a/fs/fuse/readdir.c -+++ b/fs/fuse/readdir.c -@@ -243,8 +243,16 @@ retry: - dput(dentry); - dentry = alias; - } -- if (IS_ERR(dentry)) -+ if (IS_ERR(dentry)) { -+ if (!IS_ERR(inode)) { -+ struct fuse_inode *fi = get_fuse_inode(inode); -+ -+ spin_lock(&fi->lock); -+ fi->nlookup--; -+ spin_unlock(&fi->lock); -+ } - return PTR_ERR(dentry); -+ } - } - if (fc->readdirplus_auto) - set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state); -diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c -index 2f04c0ff7470b..1e9fa26f04fe1 100644 ---- a/fs/gfs2/aops.c -+++ b/fs/gfs2/aops.c -@@ -182,13 +182,13 @@ static int gfs2_writepages(struct address_space *mapping, - int ret; - - /* -- * Even if we didn't write any pages here, we might still be holding -+ * Even if we didn't write enough pages here, we might still be holding - * dirty pages in the ail. We forcibly flush the ail because we don't - * want balance_dirty_pages() to loop indefinitely trying to write out - * pages held in the ail that it can't find. - */ - ret = iomap_writepages(mapping, wbc, &wpc, &gfs2_writeback_ops); -- if (ret == 0) -+ if (ret == 0 && wbc->nr_to_write > 0) - set_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags); - return ret; - } -diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c -index 61323deb80bc7..e021d5f50c231 100644 ---- a/fs/gfs2/log.c -+++ b/fs/gfs2/log.c -@@ -1285,9 +1285,6 @@ static inline int gfs2_ail_flush_reqd(struct gfs2_sbd *sdp) - { - unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); - -- if (test_and_clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags)) -- return 1; -- - return used_blocks + atomic_read(&sdp->sd_log_blks_needed) >= - atomic_read(&sdp->sd_log_thresh2); - } -@@ -1304,7 +1301,6 @@ int gfs2_logd(void *data) - { - struct gfs2_sbd *sdp = data; - unsigned long t = 1; -- DEFINE_WAIT(wait); - - while (!kthread_should_stop()) { - -@@ -1329,7 +1325,9 @@ int gfs2_logd(void *data) - GFS2_LFC_LOGD_JFLUSH_REQD); - } - -- if (gfs2_ail_flush_reqd(sdp)) { -+ if (test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) || -+ gfs2_ail_flush_reqd(sdp)) { -+ clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags); - gfs2_ail1_start(sdp); - gfs2_ail1_wait(sdp); - gfs2_ail1_empty(sdp, 0); -@@ -1341,17 +1339,12 @@ int gfs2_logd(void *data) - - try_to_freeze(); - -- do { -- prepare_to_wait(&sdp->sd_logd_waitq, &wait, -- TASK_INTERRUPTIBLE); -- if (!gfs2_ail_flush_reqd(sdp) && -- !gfs2_jrnl_flush_reqd(sdp) && -- !kthread_should_stop()) -- t = schedule_timeout(t); -- } while(t && !gfs2_ail_flush_reqd(sdp) && -- !gfs2_jrnl_flush_reqd(sdp) && -- !kthread_should_stop()); -- finish_wait(&sdp->sd_logd_waitq, &wait); -+ t = wait_event_interruptible_timeout(sdp->sd_logd_waitq, -+ test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) || -+ gfs2_ail_flush_reqd(sdp) || -+ gfs2_jrnl_flush_reqd(sdp) || -+ kthread_should_stop(), -+ t); - } - - return 0; -diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c -index 9ec91017a7f3c..f033ac807013c 100644 ---- a/fs/jbd2/checkpoint.c -+++ b/fs/jbd2/checkpoint.c -@@ -349,6 +349,8 @@ int jbd2_cleanup_journal_tail(journal_t *journal) - - /* Checkpoint list management */ - -+enum shrink_type {SHRINK_DESTROY, SHRINK_BUSY_STOP, SHRINK_BUSY_SKIP}; -+ - /* - * journal_shrink_one_cp_list - * -@@ -360,7 +362,8 @@ int jbd2_cleanup_journal_tail(journal_t *journal) - * Called with j_list_lock held. - */ - static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, -- bool destroy, bool *released) -+ enum shrink_type type, -+ bool *released) - { - struct journal_head *last_jh; - struct journal_head *next_jh = jh; -@@ -376,12 +379,15 @@ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, - jh = next_jh; - next_jh = jh->b_cpnext; - -- if (destroy) { -+ if (type == SHRINK_DESTROY) { - ret = __jbd2_journal_remove_checkpoint(jh); - } else { - ret = jbd2_journal_try_remove_checkpoint(jh); -- if (ret < 0) -- continue; -+ if (ret < 0) { -+ if (type == SHRINK_BUSY_SKIP) -+ continue; -+ break; -+ } - } - - nr_freed++; -@@ -445,7 +451,7 @@ again: - tid = transaction->t_tid; - - freed = journal_shrink_one_cp_list(transaction->t_checkpoint_list, -- false, &released); -+ SHRINK_BUSY_SKIP, &released); - nr_freed += freed; - (*nr_to_scan) -= min(*nr_to_scan, freed); - if (*nr_to_scan == 0) -@@ -485,19 +491,21 @@ out: - void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) - { - transaction_t *transaction, *last_transaction, *next_transaction; -+ enum shrink_type type; - bool released; - - transaction = journal->j_checkpoint_transactions; - if (!transaction) - return; - -+ type = destroy ? SHRINK_DESTROY : SHRINK_BUSY_STOP; - last_transaction = transaction->t_cpprev; - next_transaction = transaction; - do { - transaction = next_transaction; - next_transaction = transaction->t_cpnext; - journal_shrink_one_cp_list(transaction->t_checkpoint_list, -- destroy, &released); -+ type, &released); - /* - * This function only frees up some memory if possible so we - * dont have an obligation to finish processing. Bail out if -@@ -631,6 +639,8 @@ int jbd2_journal_try_remove_checkpoint(struct journal_head *jh) - { - struct buffer_head *bh = jh2bh(jh); - -+ if (jh->b_transaction) -+ return -EBUSY; - if (!trylock_buffer(bh)) - return -EBUSY; - if (buffer_dirty(bh)) { -diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c -index 8286a9ec122fe..357a3f7632e39 100644 ---- a/fs/jbd2/recovery.c -+++ b/fs/jbd2/recovery.c -@@ -229,12 +229,8 @@ static int count_tags(journal_t *journal, struct buffer_head *bh) - /* Make sure we wrap around the log correctly! */ - #define wrap(journal, var) \ - do { \ -- unsigned long _wrap_last = \ -- jbd2_has_feature_fast_commit(journal) ? \ -- (journal)->j_fc_last : (journal)->j_last; \ -- \ -- if (var >= _wrap_last) \ -- var -= (_wrap_last - (journal)->j_first); \ -+ if (var >= (journal)->j_last) \ -+ var -= ((journal)->j_last - (journal)->j_first); \ - } while (0) - - static int fc_do_one_pass(journal_t *journal, -@@ -517,9 +513,7 @@ static int do_one_pass(journal_t *journal, - break; - - jbd2_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", -- next_commit_ID, next_log_block, -- jbd2_has_feature_fast_commit(journal) ? -- journal->j_fc_last : journal->j_last); -+ next_commit_ID, next_log_block, journal->j_last); - - /* Skip over each chunk of the transaction looking - * either the next descriptor block or the final commit -diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c -index cf34d0c309459..3bb530d4bb5ce 100644 ---- a/fs/nfs/direct.c -+++ b/fs/nfs/direct.c -@@ -474,13 +474,31 @@ out: - return result; - } - -+static void nfs_direct_add_page_head(struct list_head *list, -+ struct nfs_page *req) -+{ -+ struct nfs_page *head = req->wb_head; -+ -+ if (!list_empty(&head->wb_list) || !nfs_lock_request(head)) -+ return; -+ if (!list_empty(&head->wb_list)) { -+ nfs_unlock_request(head); -+ return; -+ } -+ list_add(&head->wb_list, list); -+ kref_get(&head->wb_kref); -+ kref_get(&head->wb_kref); -+} -+ - static void nfs_direct_join_group(struct list_head *list, struct inode *inode) - { - struct nfs_page *req, *subreq; - - list_for_each_entry(req, list, wb_list) { -- if (req->wb_head != req) -+ if (req->wb_head != req) { -+ nfs_direct_add_page_head(&req->wb_list, req); - continue; -+ } - subreq = req->wb_this_page; - if (subreq == req) - continue; -diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c -index ddbbf4fcda867..178001c90156f 100644 ---- a/fs/nfs/pnfs_dev.c -+++ b/fs/nfs/pnfs_dev.c -@@ -154,7 +154,7 @@ nfs4_get_device_info(struct nfs_server *server, - set_bit(NFS_DEVICEID_NOCACHE, &d->flags); - - out_free_pages: -- for (i = 0; i < max_pages; i++) -+ while (--i >= 0) - __free_page(pages[i]); - kfree(pages); - out_free_pdev: -diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c -index bfc964b36c72e..5a132c1e6f6c4 100644 ---- a/fs/smb/client/cached_dir.c -+++ b/fs/smb/client/cached_dir.c -@@ -218,7 +218,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, - .tcon = tcon, - .path = path, - .create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE), -- .desired_access = FILE_READ_ATTRIBUTES, -+ .desired_access = FILE_READ_DATA | FILE_READ_ATTRIBUTES, - .disposition = FILE_OPEN, - .fid = pfid, - }; -diff --git a/fs/smb/client/cifs_dfs_ref.c b/fs/smb/client/cifs_dfs_ref.c -index b0864da9ef434..020e71fe1454e 100644 ---- a/fs/smb/client/cifs_dfs_ref.c -+++ b/fs/smb/client/cifs_dfs_ref.c -@@ -258,61 +258,23 @@ compose_mount_options_err: - goto compose_mount_options_out; - } - --/** -- * cifs_dfs_do_mount - mounts specified path using DFS full path -- * -- * Always pass down @fullpath to smb3_do_mount() so we can use the root server -- * to perform failover in case we failed to connect to the first target in the -- * referral. -- * -- * @mntpt: directory entry for the path we are trying to automount -- * @cifs_sb: parent/root superblock -- * @fullpath: full path in UNC format -- */ --static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt, -- struct cifs_sb_info *cifs_sb, -- const char *fullpath) --{ -- struct vfsmount *mnt; -- char *mountdata; -- char *devname; -- -- devname = kstrdup(fullpath, GFP_KERNEL); -- if (!devname) -- return ERR_PTR(-ENOMEM); -- -- convert_delimiter(devname, '/'); -- -- /* TODO: change to call fs_context_for_mount(), fill in context directly, call fc_mount */ -- -- /* See afs_mntpt_do_automount in fs/afs/mntpt.c for an example */ -- -- /* strip first '\' from fullpath */ -- mountdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options, -- fullpath + 1, NULL, NULL); -- if (IS_ERR(mountdata)) { -- kfree(devname); -- return (struct vfsmount *)mountdata; -- } -- -- mnt = vfs_submount(mntpt, &cifs_fs_type, devname, mountdata); -- kfree(mountdata); -- kfree(devname); -- return mnt; --} -- - /* - * Create a vfsmount that we can automount - */ --static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) -+static struct vfsmount *cifs_dfs_do_automount(struct path *path) - { -+ int rc; -+ struct dentry *mntpt = path->dentry; -+ struct fs_context *fc; - struct cifs_sb_info *cifs_sb; -- void *page; -+ void *page = NULL; -+ struct smb3_fs_context *ctx, *cur_ctx; -+ struct smb3_fs_context tmp; - char *full_path; - struct vfsmount *mnt; - -- cifs_dbg(FYI, "in %s\n", __func__); -- BUG_ON(IS_ROOT(mntpt)); -+ if (IS_ROOT(mntpt)) -+ return ERR_PTR(-ESTALE); - - /* - * The MSDFS spec states that paths in DFS referral requests and -@@ -321,29 +283,47 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) - * gives us the latter, so we must adjust the result. - */ - cifs_sb = CIFS_SB(mntpt->d_sb); -- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) { -- mnt = ERR_PTR(-EREMOTE); -- goto cdda_exit; -- } -+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) -+ return ERR_PTR(-EREMOTE); -+ -+ cur_ctx = cifs_sb->ctx; -+ -+ fc = fs_context_for_submount(path->mnt->mnt_sb->s_type, mntpt); -+ if (IS_ERR(fc)) -+ return ERR_CAST(fc); -+ -+ ctx = smb3_fc2context(fc); - - page = alloc_dentry_path(); - /* always use tree name prefix */ - full_path = build_path_from_dentry_optional_prefix(mntpt, page, true); - if (IS_ERR(full_path)) { - mnt = ERR_CAST(full_path); -- goto free_full_path; -+ goto out; - } - -- convert_delimiter(full_path, '\\'); -+ convert_delimiter(full_path, '/'); - cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path); - -- mnt = cifs_dfs_do_mount(mntpt, cifs_sb, full_path); -- cifs_dbg(FYI, "%s: cifs_dfs_do_mount:%s , mnt:%p\n", __func__, full_path + 1, mnt); -+ tmp = *cur_ctx; -+ tmp.source = full_path; -+ tmp.UNC = tmp.prepath = NULL; -+ -+ rc = smb3_fs_context_dup(ctx, &tmp); -+ if (rc) { -+ mnt = ERR_PTR(rc); -+ goto out; -+ } -+ -+ rc = smb3_parse_devname(full_path, ctx); -+ if (!rc) -+ mnt = fc_mount(fc); -+ else -+ mnt = ERR_PTR(rc); - --free_full_path: -+out: -+ put_fs_context(fc); - free_dentry_path(page); --cdda_exit: -- cifs_dbg(FYI, "leaving %s\n" , __func__); - return mnt; - } - -@@ -354,9 +334,9 @@ struct vfsmount *cifs_dfs_d_automount(struct path *path) - { - struct vfsmount *newmnt; - -- cifs_dbg(FYI, "in %s\n", __func__); -+ cifs_dbg(FYI, "%s: %pd\n", __func__, path->dentry); - -- newmnt = cifs_dfs_do_automount(path->dentry); -+ newmnt = cifs_dfs_do_automount(path); - if (IS_ERR(newmnt)) { - cifs_dbg(FYI, "leaving %s [automount failed]\n" , __func__); - return newmnt; -diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h -index 4a092cc5a3936..03f34ec63e10d 100644 ---- a/fs/smb/client/cifsglob.h -+++ b/fs/smb/client/cifsglob.h -@@ -734,6 +734,7 @@ struct TCP_Server_Info { - */ - #define CIFS_SERVER_IS_CHAN(server) (!!(server)->primary_server) - struct TCP_Server_Info *primary_server; -+ __u16 channel_sequence_num; /* incremented on primary channel on each chan reconnect */ - - #ifdef CONFIG_CIFS_SWN_UPCALL - bool use_swn_dstaddr; -diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c -index 9cd282960c0bb..57da4f23c1e43 100644 ---- a/fs/smb/client/connect.c -+++ b/fs/smb/client/connect.c -@@ -1725,6 +1725,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, - ctx->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); - tcp_ses->session_estab = false; - tcp_ses->sequence_number = 0; -+ tcp_ses->channel_sequence_num = 0; /* only tracked for primary channel */ - tcp_ses->reconnect_instance = 1; - tcp_ses->lstrp = jiffies; - tcp_ses->compress_algorithm = cpu_to_le16(ctx->compression); -diff --git a/fs/smb/client/fscache.c b/fs/smb/client/fscache.c -index f6f3a6b75601b..e73625b5d0cc6 100644 ---- a/fs/smb/client/fscache.c -+++ b/fs/smb/client/fscache.c -@@ -48,7 +48,7 @@ int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) - sharename = extract_sharename(tcon->tree_name); - if (IS_ERR(sharename)) { - cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__); -- return -EINVAL; -+ return PTR_ERR(sharename); - } - - slen = strlen(sharename); -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index 6b020d80bb949..1387d5126f53b 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -167,8 +167,17 @@ smb2_set_credits(struct TCP_Server_Info *server, const int val) - - spin_lock(&server->req_lock); - server->credits = val; -- if (val == 1) -+ if (val == 1) { - server->reconnect_instance++; -+ /* -+ * ChannelSequence updated for all channels in primary channel so that consistent -+ * across SMB3 requests sent on any channel. See MS-SMB2 3.2.4.1 and 3.2.7.1 -+ */ -+ if (CIFS_SERVER_IS_CHAN(server)) -+ server->primary_server->channel_sequence_num++; -+ else -+ server->channel_sequence_num++; -+ } - scredits = server->credits; - in_flight = server->in_flight; - spin_unlock(&server->req_lock); -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index ae17d78f6ba17..847d69d327c2a 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -88,9 +88,20 @@ smb2_hdr_assemble(struct smb2_hdr *shdr, __le16 smb2_cmd, - const struct cifs_tcon *tcon, - struct TCP_Server_Info *server) - { -+ struct smb3_hdr_req *smb3_hdr; - shdr->ProtocolId = SMB2_PROTO_NUMBER; - shdr->StructureSize = cpu_to_le16(64); - shdr->Command = smb2_cmd; -+ if (server->dialect >= SMB30_PROT_ID) { -+ /* After reconnect SMB3 must set ChannelSequence on subsequent reqs */ -+ smb3_hdr = (struct smb3_hdr_req *)shdr; -+ /* if primary channel is not set yet, use default channel for chan sequence num */ -+ if (CIFS_SERVER_IS_CHAN(server)) -+ smb3_hdr->ChannelSequence = -+ cpu_to_le16(server->primary_server->channel_sequence_num); -+ else -+ smb3_hdr->ChannelSequence = cpu_to_le16(server->channel_sequence_num); -+ } - if (server) { - spin_lock(&server->req_lock); - /* Request up to 10 credits but don't go over the limit. */ -diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h -index 7d605db3bb3b9..9619015d78f29 100644 ---- a/fs/smb/common/smb2pdu.h -+++ b/fs/smb/common/smb2pdu.h -@@ -153,6 +153,28 @@ struct smb2_hdr { - __u8 Signature[16]; - } __packed; - -+struct smb3_hdr_req { -+ __le32 ProtocolId; /* 0xFE 'S' 'M' 'B' */ -+ __le16 StructureSize; /* 64 */ -+ __le16 CreditCharge; /* MBZ */ -+ __le16 ChannelSequence; /* See MS-SMB2 3.2.4.1 and 3.2.7.1 */ -+ __le16 Reserved; -+ __le16 Command; -+ __le16 CreditRequest; /* CreditResponse */ -+ __le32 Flags; -+ __le32 NextCommand; -+ __le64 MessageId; -+ union { -+ struct { -+ __le32 ProcessId; -+ __le32 TreeId; -+ } __packed SyncId; -+ __le64 AsyncId; -+ } __packed Id; -+ __le64 SessionId; -+ __u8 Signature[16]; -+} __packed; -+ - struct smb2_pdu { - struct smb2_hdr hdr; - __le16 StructureSize2; /* size of wct area (varies, request specific) */ -diff --git a/include/linux/bpf.h b/include/linux/bpf.h -index 8cef9ec3a89c2..b3d3aa8437dce 100644 ---- a/include/linux/bpf.h -+++ b/include/linux/bpf.h -@@ -862,22 +862,18 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *i - const struct btf_func_model *m, u32 flags, - struct bpf_tramp_links *tlinks, - void *orig_call); --/* these two functions are called from generated trampoline */ --u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx); --void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_run_ctx *run_ctx); --u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx); --void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, -- struct bpf_tramp_run_ctx *run_ctx); --u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, -- struct bpf_tramp_run_ctx *run_ctx); --void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, -- struct bpf_tramp_run_ctx *run_ctx); --u64 notrace __bpf_prog_enter_struct_ops(struct bpf_prog *prog, -- struct bpf_tramp_run_ctx *run_ctx); --void notrace __bpf_prog_exit_struct_ops(struct bpf_prog *prog, u64 start, -- struct bpf_tramp_run_ctx *run_ctx); -+u64 notrace __bpf_prog_enter_sleepable_recur(struct bpf_prog *prog, -+ struct bpf_tramp_run_ctx *run_ctx); -+void notrace __bpf_prog_exit_sleepable_recur(struct bpf_prog *prog, u64 start, -+ struct bpf_tramp_run_ctx *run_ctx); - void notrace __bpf_tramp_enter(struct bpf_tramp_image *tr); - void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr); -+typedef u64 (*bpf_trampoline_enter_t)(struct bpf_prog *prog, -+ struct bpf_tramp_run_ctx *run_ctx); -+typedef void (*bpf_trampoline_exit_t)(struct bpf_prog *prog, u64 start, -+ struct bpf_tramp_run_ctx *run_ctx); -+bpf_trampoline_enter_t bpf_trampoline_enter(const struct bpf_prog *prog); -+bpf_trampoline_exit_t bpf_trampoline_exit(const struct bpf_prog *prog); - - struct bpf_ksym { - unsigned long start; -diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h -index 0eb8f035b3d9f..1a32baa78ce26 100644 ---- a/include/linux/bpf_verifier.h -+++ b/include/linux/bpf_verifier.h -@@ -648,4 +648,17 @@ static inline enum bpf_prog_type resolve_prog_type(const struct bpf_prog *prog) - prog->aux->dst_prog->type : prog->type; - } - -+static inline bool bpf_prog_check_recur(const struct bpf_prog *prog) -+{ -+ switch (resolve_prog_type(prog)) { -+ case BPF_PROG_TYPE_TRACING: -+ return prog->expected_attach_type != BPF_TRACE_ITER; -+ case BPF_PROG_TYPE_STRUCT_OPS: -+ case BPF_PROG_TYPE_LSM: -+ return false; -+ default: -+ return true; -+ } -+} -+ - #endif /* _LINUX_BPF_VERIFIER_H */ -diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h -index 37dfdcfcdd542..15d7529ac9534 100644 ---- a/include/linux/ipv6.h -+++ b/include/linux/ipv6.h -@@ -146,6 +146,7 @@ struct inet6_skb_parm { - #define IP6SKB_JUMBOGRAM 128 - #define IP6SKB_SEG6 256 - #define IP6SKB_FAKEJUMBO 512 -+#define IP6SKB_MULTIPATH 1024 - }; - - #if defined(CONFIG_NET_L3_MASTER_DEV) -diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h -index 1f7c33b2f5a3f..e164facb0f363 100644 ---- a/include/linux/micrel_phy.h -+++ b/include/linux/micrel_phy.h -@@ -38,9 +38,9 @@ - #define PHY_ID_KSZ9477 0x00221631 - - /* struct phy_device dev_flags definitions */ --#define MICREL_PHY_50MHZ_CLK 0x00000001 --#define MICREL_PHY_FXEN 0x00000002 --#define MICREL_KSZ8_P1_ERRATA 0x00000003 -+#define MICREL_PHY_50MHZ_CLK BIT(0) -+#define MICREL_PHY_FXEN BIT(1) -+#define MICREL_KSZ8_P1_ERRATA BIT(2) - - #define MICREL_KSZ9021_EXTREG_CTRL 0xB - #define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC -diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h -index e8ed225d8f7ca..4ef6c09cc2eec 100644 ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -256,9 +256,9 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, - lru_gen_update_size(lruvec, folio, -1, gen); - /* for folio_rotate_reclaimable() */ - if (reclaiming) -- list_add_tail(&folio->lru, &lrugen->lists[gen][type][zone]); -+ list_add_tail(&folio->lru, &lrugen->folios[gen][type][zone]); - else -- list_add(&folio->lru, &lrugen->lists[gen][type][zone]); -+ list_add(&folio->lru, &lrugen->folios[gen][type][zone]); - - return true; - } -diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h -index 5f74891556f33..323ee36df683e 100644 ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -312,7 +312,7 @@ enum lruvec_flags { - * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An - * offset within MAX_NR_GENS, i.e., gen, indexes the LRU list of the - * corresponding generation. The gen counter in folio->flags stores gen+1 while -- * a page is on one of lrugen->lists[]. Otherwise it stores 0. -+ * a page is on one of lrugen->folios[]. Otherwise it stores 0. - * - * A page is added to the youngest generation on faulting. The aging needs to - * check the accessed bit at least twice before handing this page over to the -@@ -324,8 +324,8 @@ enum lruvec_flags { - * rest of generations, if they exist, are considered inactive. See - * lru_gen_is_active(). - * -- * PG_active is always cleared while a page is on one of lrugen->lists[] so that -- * the aging needs not to worry about it. And it's set again when a page -+ * PG_active is always cleared while a page is on one of lrugen->folios[] so -+ * that the aging needs not to worry about it. And it's set again when a page - * considered active is isolated for non-reclaiming purposes, e.g., migration. - * See lru_gen_add_folio() and lru_gen_del_folio(). - * -@@ -412,7 +412,7 @@ struct lru_gen_struct { - /* the birth time of each generation in jiffies */ - unsigned long timestamps[MAX_NR_GENS]; - /* the multi-gen LRU lists, lazily sorted on eviction */ -- struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ struct list_head folios[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; - /* the multi-gen LRU sizes, eventually consistent */ - long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; - /* the exponential moving average of refaulted */ -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index cc5ed2cf25f65..2feee144fc0ef 100644 ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -261,6 +261,14 @@ - #define SKB_DATA_ALIGN(X) ALIGN(X, SMP_CACHE_BYTES) - #define SKB_WITH_OVERHEAD(X) \ - ((X) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) -+ -+/* For X bytes available in skb->head, what is the minimal -+ * allocation needed, knowing struct skb_shared_info needs -+ * to be aligned. -+ */ -+#define SKB_HEAD_ALIGN(X) (SKB_DATA_ALIGN(X) + \ -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) -+ - #define SKB_MAX_ORDER(X, ORDER) \ - SKB_WITH_OVERHEAD((PAGE_SIZE << (ORDER)) - (X)) - #define SKB_MAX_HEAD(X) (SKB_MAX_ORDER((X), 0)) -diff --git a/include/linux/tca6416_keypad.h b/include/linux/tca6416_keypad.h -index b0d36a9934ccd..5cf6f6f82aa70 100644 ---- a/include/linux/tca6416_keypad.h -+++ b/include/linux/tca6416_keypad.h -@@ -25,7 +25,6 @@ struct tca6416_keys_platform_data { - unsigned int rep:1; /* enable input subsystem auto repeat */ - uint16_t pinmask; - uint16_t invert; -- int irq_is_gpio; - int use_polling; /* use polling if Interrupt is not connected*/ - }; - #endif -diff --git a/include/net/ip.h b/include/net/ip.h -index 1872f570abeda..c286344628dba 100644 ---- a/include/net/ip.h -+++ b/include/net/ip.h -@@ -57,6 +57,7 @@ struct inet_skb_parm { - #define IPSKB_FRAG_PMTU BIT(6) - #define IPSKB_L3SLAVE BIT(7) - #define IPSKB_NOPOLICY BIT(8) -+#define IPSKB_MULTIPATH BIT(9) - - u16 frag_max_size; - }; -diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h -index 6268963d95994..fa4e6af382e2a 100644 ---- a/include/net/ip6_fib.h -+++ b/include/net/ip6_fib.h -@@ -472,13 +472,10 @@ void rt6_get_prefsrc(const struct rt6_info *rt, struct in6_addr *addr) - rcu_read_lock(); - - from = rcu_dereference(rt->from); -- if (from) { -+ if (from) - *addr = from->fib6_prefsrc.addr; -- } else { -- struct in6_addr in6_zero = {}; -- -- *addr = in6_zero; -- } -+ else -+ *addr = in6addr_any; - - rcu_read_unlock(); - } -@@ -610,7 +607,10 @@ static inline bool fib6_rules_early_flow_dissect(struct net *net, - if (!net->ipv6.fib6_rules_require_fldissect) - return false; - -- skb_flow_dissect_flow_keys(skb, flkeys, flag); -+ memset(flkeys, 0, sizeof(*flkeys)); -+ __skb_flow_dissect(net, skb, &flow_keys_dissector, -+ flkeys, NULL, 0, 0, 0, flag); -+ - fl6->fl6_sport = flkeys->ports.src; - fl6->fl6_dport = flkeys->ports.dst; - fl6->flowi6_proto = flkeys->basic.ip_proto; -diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h -index a378eff827c74..f0c13864180e2 100644 ---- a/include/net/ip_fib.h -+++ b/include/net/ip_fib.h -@@ -418,7 +418,10 @@ static inline bool fib4_rules_early_flow_dissect(struct net *net, - if (!net->ipv4.fib_rules_require_fldissect) - return false; - -- skb_flow_dissect_flow_keys(skb, flkeys, flag); -+ memset(flkeys, 0, sizeof(*flkeys)); -+ __skb_flow_dissect(net, skb, &flow_keys_dissector, -+ flkeys, NULL, 0, 0, 0, flag); -+ - fl4->fl4_sport = flkeys->ports.src; - fl4->fl4_dport = flkeys->ports.dst; - fl4->flowi4_proto = flkeys->basic.ip_proto; -diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h -index fca3576798166..bca80522f95c8 100644 ---- a/include/net/ip_tunnels.h -+++ b/include/net/ip_tunnels.h -@@ -473,15 +473,14 @@ static inline void iptunnel_xmit_stats(struct net_device *dev, int pkt_len) - u64_stats_inc(&tstats->tx_packets); - u64_stats_update_end(&tstats->syncp); - put_cpu_ptr(tstats); -+ return; -+ } -+ -+ if (pkt_len < 0) { -+ DEV_STATS_INC(dev, tx_errors); -+ DEV_STATS_INC(dev, tx_aborted_errors); - } else { -- struct net_device_stats *err_stats = &dev->stats; -- -- if (pkt_len < 0) { -- err_stats->tx_errors++; -- err_stats->tx_aborted_errors++; -- } else { -- err_stats->tx_dropped++; -- } -+ DEV_STATS_INC(dev, tx_dropped); - } - } - -diff --git a/include/net/ipv6.h b/include/net/ipv6.h -index e4ceef687c1c2..517bdae78614b 100644 ---- a/include/net/ipv6.h -+++ b/include/net/ipv6.h -@@ -750,6 +750,11 @@ static inline bool ipv6_addr_v4mapped(const struct in6_addr *a) - cpu_to_be32(0x0000ffff))) == 0UL; - } - -+static inline bool ipv6_addr_v4mapped_any(const struct in6_addr *a) -+{ -+ return ipv6_addr_v4mapped(a) && ipv4_is_zeronet(a->s6_addr32[3]); -+} -+ - static inline bool ipv6_addr_v4mapped_loopback(const struct in6_addr *a) - { - return ipv6_addr_v4mapped(a) && ipv4_is_loopback(a->s6_addr32[3]); -@@ -1322,7 +1327,7 @@ static inline int __ip6_sock_set_addr_preferences(struct sock *sk, int val) - return 0; - } - --static inline int ip6_sock_set_addr_preferences(struct sock *sk, bool val) -+static inline int ip6_sock_set_addr_preferences(struct sock *sk, int val) - { - int ret; - -diff --git a/include/net/sock.h b/include/net/sock.h -index d1f936ed97556..fe695e8bfe289 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -1049,6 +1049,12 @@ static inline void sk_wmem_queued_add(struct sock *sk, int val) - WRITE_ONCE(sk->sk_wmem_queued, sk->sk_wmem_queued + val); - } - -+static inline void sk_forward_alloc_add(struct sock *sk, int val) -+{ -+ /* Paired with lockless reads of sk->sk_forward_alloc */ -+ WRITE_ONCE(sk->sk_forward_alloc, sk->sk_forward_alloc + val); -+} -+ - void sk_stream_write_space(struct sock *sk); - - /* OOB backlog add */ -@@ -1401,7 +1407,7 @@ static inline int sk_forward_alloc_get(const struct sock *sk) - if (sk->sk_prot->forward_alloc_get) - return sk->sk_prot->forward_alloc_get(sk); - #endif -- return sk->sk_forward_alloc; -+ return READ_ONCE(sk->sk_forward_alloc); - } - - static inline bool __sk_stream_memory_free(const struct sock *sk, int wake) -@@ -1697,14 +1703,14 @@ static inline void sk_mem_charge(struct sock *sk, int size) - { - if (!sk_has_account(sk)) - return; -- sk->sk_forward_alloc -= size; -+ sk_forward_alloc_add(sk, -size); - } - - static inline void sk_mem_uncharge(struct sock *sk, int size) - { - if (!sk_has_account(sk)) - return; -- sk->sk_forward_alloc += size; -+ sk_forward_alloc_add(sk, size); - sk_mem_reclaim(sk); - } - -diff --git a/include/trace/events/fib.h b/include/trace/events/fib.h -index c2300c407f583..76297ecd4935c 100644 ---- a/include/trace/events/fib.h -+++ b/include/trace/events/fib.h -@@ -36,7 +36,6 @@ TRACE_EVENT(fib_table_lookup, - ), - - TP_fast_assign( -- struct in6_addr in6_zero = {}; - struct net_device *dev; - struct in6_addr *in6; - __be32 *p32; -@@ -74,7 +73,7 @@ TRACE_EVENT(fib_table_lookup, - *p32 = nhc->nhc_gw.ipv4; - - in6 = (struct in6_addr *)__entry->gw6; -- *in6 = in6_zero; -+ *in6 = in6addr_any; - } else if (nhc->nhc_gw_family == AF_INET6) { - p32 = (__be32 *) __entry->gw4; - *p32 = 0; -@@ -87,7 +86,7 @@ TRACE_EVENT(fib_table_lookup, - *p32 = 0; - - in6 = (struct in6_addr *)__entry->gw6; -- *in6 = in6_zero; -+ *in6 = in6addr_any; - } - ), - -diff --git a/include/trace/events/fib6.h b/include/trace/events/fib6.h -index 6e821eb794503..4d3e607b3cdec 100644 ---- a/include/trace/events/fib6.h -+++ b/include/trace/events/fib6.h -@@ -68,11 +68,8 @@ TRACE_EVENT(fib6_table_lookup, - strcpy(__entry->name, "-"); - } - if (res->f6i == net->ipv6.fib6_null_entry) { -- struct in6_addr in6_zero = {}; -- - in6 = (struct in6_addr *)__entry->gw; -- *in6 = in6_zero; -- -+ *in6 = in6addr_any; - } else if (res->nh) { - in6 = (struct in6_addr *)__entry->gw; - *in6 = res->nh->fib_nh_gw6; -diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c -index 411bb2d1acd45..98ac9dbcec2f5 100644 ---- a/io_uring/io-wq.c -+++ b/io_uring/io-wq.c -@@ -181,6 +181,16 @@ static void io_worker_ref_put(struct io_wq *wq) - complete(&wq->worker_done); - } - -+bool io_wq_worker_stopped(void) -+{ -+ struct io_worker *worker = current->worker_private; -+ -+ if (WARN_ON_ONCE(!io_wq_current_is_worker())) -+ return true; -+ -+ return test_bit(IO_WQ_BIT_EXIT, &worker->wqe->wq->state); -+} -+ - static void io_worker_cancel_cb(struct io_worker *worker) - { - struct io_wqe_acct *acct = io_wqe_get_acct(worker); -@@ -1340,13 +1350,16 @@ static int io_wq_cpu_offline(unsigned int cpu, struct hlist_node *node) - return __io_wq_cpu_online(wq, cpu, false); - } - --int io_wq_cpu_affinity(struct io_wq *wq, cpumask_var_t mask) -+int io_wq_cpu_affinity(struct io_uring_task *tctx, cpumask_var_t mask) - { - int i; - -+ if (!tctx || !tctx->io_wq) -+ return -EINVAL; -+ - rcu_read_lock(); - for_each_node(i) { -- struct io_wqe *wqe = wq->wqes[i]; -+ struct io_wqe *wqe = tctx->io_wq->wqes[i]; - - if (mask) - cpumask_copy(wqe->cpu_mask, mask); -diff --git a/io_uring/io-wq.h b/io_uring/io-wq.h -index 31228426d1924..2b2a6406dd8ee 100644 ---- a/io_uring/io-wq.h -+++ b/io_uring/io-wq.h -@@ -50,8 +50,9 @@ void io_wq_put_and_exit(struct io_wq *wq); - void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work); - void io_wq_hash_work(struct io_wq_work *work, void *val); - --int io_wq_cpu_affinity(struct io_wq *wq, cpumask_var_t mask); -+int io_wq_cpu_affinity(struct io_uring_task *tctx, cpumask_var_t mask); - int io_wq_max_workers(struct io_wq *wq, int *new_count); -+bool io_wq_worker_stopped(void); - - static inline bool io_wq_is_hashed(struct io_wq_work *work) - { -diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c -index 6d455e2428b90..f413ebed81ab3 100644 ---- a/io_uring/io_uring.c -+++ b/io_uring/io_uring.c -@@ -1823,6 +1823,8 @@ fail: - if (!needs_poll) { - if (!(req->ctx->flags & IORING_SETUP_IOPOLL)) - break; -+ if (io_wq_worker_stopped()) -+ break; - cond_resched(); - continue; - } -@@ -3833,16 +3835,28 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx) - return 0; - } - -+static __cold int __io_register_iowq_aff(struct io_ring_ctx *ctx, -+ cpumask_var_t new_mask) -+{ -+ int ret; -+ -+ if (!(ctx->flags & IORING_SETUP_SQPOLL)) { -+ ret = io_wq_cpu_affinity(current->io_uring, new_mask); -+ } else { -+ mutex_unlock(&ctx->uring_lock); -+ ret = io_sqpoll_wq_cpu_affinity(ctx, new_mask); -+ mutex_lock(&ctx->uring_lock); -+ } -+ -+ return ret; -+} -+ - static __cold int io_register_iowq_aff(struct io_ring_ctx *ctx, - void __user *arg, unsigned len) - { -- struct io_uring_task *tctx = current->io_uring; - cpumask_var_t new_mask; - int ret; - -- if (!tctx || !tctx->io_wq) -- return -EINVAL; -- - if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) - return -ENOMEM; - -@@ -3863,19 +3877,14 @@ static __cold int io_register_iowq_aff(struct io_ring_ctx *ctx, - return -EFAULT; - } - -- ret = io_wq_cpu_affinity(tctx->io_wq, new_mask); -+ ret = __io_register_iowq_aff(ctx, new_mask); - free_cpumask_var(new_mask); - return ret; - } - - static __cold int io_unregister_iowq_aff(struct io_ring_ctx *ctx) - { -- struct io_uring_task *tctx = current->io_uring; -- -- if (!tctx || !tctx->io_wq) -- return -EINVAL; -- -- return io_wq_cpu_affinity(tctx->io_wq, NULL); -+ return __io_register_iowq_aff(ctx, NULL); - } - - static __cold int io_register_iowq_max_workers(struct io_ring_ctx *ctx, -diff --git a/io_uring/net.c b/io_uring/net.c -index 2b44126a876ef..7245218fdbe2b 100644 ---- a/io_uring/net.c -+++ b/io_uring/net.c -@@ -1337,12 +1337,12 @@ retry: - return IOU_OK; - } - -- if (ret >= 0 && -- io_post_aux_cqe(ctx, req->cqe.user_data, ret, IORING_CQE_F_MORE, false)) -+ if (ret < 0) -+ return ret; -+ if (io_post_aux_cqe(ctx, req->cqe.user_data, ret, IORING_CQE_F_MORE, false)) - goto retry; - -- io_req_set_res(req, ret, 0); -- return (issue_flags & IO_URING_F_MULTISHOT) ? IOU_STOP_MULTISHOT : IOU_OK; -+ return -ECANCELED; - } - - int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) -diff --git a/io_uring/poll.c b/io_uring/poll.c -index 869e1d2a44139..a4084acaff911 100644 ---- a/io_uring/poll.c -+++ b/io_uring/poll.c -@@ -360,11 +360,12 @@ static void io_apoll_task_func(struct io_kiocb *req, bool *locked) - if (ret == IOU_POLL_NO_ACTION) - return; - -+ io_tw_lock(req->ctx, locked); - io_poll_remove_entries(req); - io_poll_tw_hash_eject(req, locked); - - if (ret == IOU_POLL_REMOVE_POLL_USE_RES) -- io_req_complete_post(req); -+ io_req_task_complete(req, locked); - else if (ret == IOU_POLL_DONE || ret == IOU_POLL_REISSUE) - io_req_task_submit(req, locked); - else -diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c -index 6ffa5cf1bbb86..7b6facf529b8d 100644 ---- a/io_uring/sqpoll.c -+++ b/io_uring/sqpoll.c -@@ -423,3 +423,20 @@ err: - io_sq_thread_finish(ctx); - return ret; - } -+ -+__cold int io_sqpoll_wq_cpu_affinity(struct io_ring_ctx *ctx, -+ cpumask_var_t mask) -+{ -+ struct io_sq_data *sqd = ctx->sq_data; -+ int ret = -EINVAL; -+ -+ if (sqd) { -+ io_sq_thread_park(sqd); -+ /* Don't set affinity for a dying thread */ -+ if (sqd->thread) -+ ret = io_wq_cpu_affinity(sqd->thread->io_uring, mask); -+ io_sq_thread_unpark(sqd); -+ } -+ -+ return ret; -+} -diff --git a/io_uring/sqpoll.h b/io_uring/sqpoll.h -index 0c3fbcd1f583f..36245f1afa5ee 100644 ---- a/io_uring/sqpoll.h -+++ b/io_uring/sqpoll.h -@@ -27,3 +27,4 @@ void io_sq_thread_park(struct io_sq_data *sqd); - void io_sq_thread_unpark(struct io_sq_data *sqd); - void io_put_sq_data(struct io_sq_data *sqd); - int io_sqpoll_wait_sq(struct io_ring_ctx *ctx); -+int io_sqpoll_wq_cpu_affinity(struct io_ring_ctx *ctx, cpumask_var_t mask); -diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c -index 0c44a716f0a24..0c8b7733573ee 100644 ---- a/kernel/bpf/syscall.c -+++ b/kernel/bpf/syscall.c -@@ -5135,14 +5135,15 @@ int kern_sys_bpf(int cmd, union bpf_attr *attr, unsigned int size) - } - - run_ctx.bpf_cookie = 0; -- run_ctx.saved_run_ctx = NULL; -- if (!__bpf_prog_enter_sleepable(prog, &run_ctx)) { -+ if (!__bpf_prog_enter_sleepable_recur(prog, &run_ctx)) { - /* recursion detected */ -+ __bpf_prog_exit_sleepable_recur(prog, 0, &run_ctx); - bpf_prog_put(prog); - return -EBUSY; - } - attr->test.retval = bpf_prog_run(prog, (void *) (long) attr->test.ctx_in); -- __bpf_prog_exit_sleepable(prog, 0 /* bpf_prog_run does runtime stats */, &run_ctx); -+ __bpf_prog_exit_sleepable_recur(prog, 0 /* bpf_prog_run does runtime stats */, -+ &run_ctx); - bpf_prog_put(prog); - return 0; - #endif -diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c -index 30af8f66e17b4..c4381dfcd6b09 100644 ---- a/kernel/bpf/trampoline.c -+++ b/kernel/bpf/trampoline.c -@@ -874,7 +874,7 @@ static __always_inline u64 notrace bpf_prog_start_time(void) - * [2..MAX_U64] - execute bpf prog and record execution time. - * This is start time. - */ --u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx) -+static u64 notrace __bpf_prog_enter_recur(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx) - __acquires(RCU) - { - rcu_read_lock(); -@@ -911,7 +911,8 @@ static void notrace update_prog_stats(struct bpf_prog *prog, - } - } - --void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_run_ctx *run_ctx) -+static void notrace __bpf_prog_exit_recur(struct bpf_prog *prog, u64 start, -+ struct bpf_tramp_run_ctx *run_ctx) - __releases(RCU) - { - bpf_reset_run_ctx(run_ctx->saved_run_ctx); -@@ -922,8 +923,8 @@ void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_ - rcu_read_unlock(); - } - --u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, -- struct bpf_tramp_run_ctx *run_ctx) -+static u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, -+ struct bpf_tramp_run_ctx *run_ctx) - __acquires(RCU) - { - /* Runtime stats are exported via actual BPF_LSM_CGROUP -@@ -937,8 +938,8 @@ u64 notrace __bpf_prog_enter_lsm_cgroup(struct bpf_prog *prog, - return NO_START_TIME; - } - --void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, -- struct bpf_tramp_run_ctx *run_ctx) -+static void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, -+ struct bpf_tramp_run_ctx *run_ctx) - __releases(RCU) - { - bpf_reset_run_ctx(run_ctx->saved_run_ctx); -@@ -947,35 +948,57 @@ void notrace __bpf_prog_exit_lsm_cgroup(struct bpf_prog *prog, u64 start, - rcu_read_unlock(); - } - --u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_run_ctx *run_ctx) -+u64 notrace __bpf_prog_enter_sleepable_recur(struct bpf_prog *prog, -+ struct bpf_tramp_run_ctx *run_ctx) - { - rcu_read_lock_trace(); - migrate_disable(); - might_fault(); - -+ run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx); -+ - if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) { - bpf_prog_inc_misses_counter(prog); - return 0; - } -+ return bpf_prog_start_time(); -+} -+ -+void notrace __bpf_prog_exit_sleepable_recur(struct bpf_prog *prog, u64 start, -+ struct bpf_tramp_run_ctx *run_ctx) -+{ -+ bpf_reset_run_ctx(run_ctx->saved_run_ctx); -+ -+ update_prog_stats(prog, start); -+ this_cpu_dec(*(prog->active)); -+ migrate_enable(); -+ rcu_read_unlock_trace(); -+} -+ -+static u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, -+ struct bpf_tramp_run_ctx *run_ctx) -+{ -+ rcu_read_lock_trace(); -+ migrate_disable(); -+ might_fault(); - - run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx); - - return bpf_prog_start_time(); - } - --void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, -- struct bpf_tramp_run_ctx *run_ctx) -+static void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start, -+ struct bpf_tramp_run_ctx *run_ctx) - { - bpf_reset_run_ctx(run_ctx->saved_run_ctx); - - update_prog_stats(prog, start); -- this_cpu_dec(*(prog->active)); - migrate_enable(); - rcu_read_unlock_trace(); - } - --u64 notrace __bpf_prog_enter_struct_ops(struct bpf_prog *prog, -- struct bpf_tramp_run_ctx *run_ctx) -+static u64 notrace __bpf_prog_enter(struct bpf_prog *prog, -+ struct bpf_tramp_run_ctx *run_ctx) - __acquires(RCU) - { - rcu_read_lock(); -@@ -986,8 +1009,8 @@ u64 notrace __bpf_prog_enter_struct_ops(struct bpf_prog *prog, - return bpf_prog_start_time(); - } - --void notrace __bpf_prog_exit_struct_ops(struct bpf_prog *prog, u64 start, -- struct bpf_tramp_run_ctx *run_ctx) -+static void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, -+ struct bpf_tramp_run_ctx *run_ctx) - __releases(RCU) - { - bpf_reset_run_ctx(run_ctx->saved_run_ctx); -@@ -1007,6 +1030,36 @@ void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr) - percpu_ref_put(&tr->pcref); - } - -+bpf_trampoline_enter_t bpf_trampoline_enter(const struct bpf_prog *prog) -+{ -+ bool sleepable = prog->aux->sleepable; -+ -+ if (bpf_prog_check_recur(prog)) -+ return sleepable ? __bpf_prog_enter_sleepable_recur : -+ __bpf_prog_enter_recur; -+ -+ if (resolve_prog_type(prog) == BPF_PROG_TYPE_LSM && -+ prog->expected_attach_type == BPF_LSM_CGROUP) -+ return __bpf_prog_enter_lsm_cgroup; -+ -+ return sleepable ? __bpf_prog_enter_sleepable : __bpf_prog_enter; -+} -+ -+bpf_trampoline_exit_t bpf_trampoline_exit(const struct bpf_prog *prog) -+{ -+ bool sleepable = prog->aux->sleepable; -+ -+ if (bpf_prog_check_recur(prog)) -+ return sleepable ? __bpf_prog_exit_sleepable_recur : -+ __bpf_prog_exit_recur; -+ -+ if (resolve_prog_type(prog) == BPF_PROG_TYPE_LSM && -+ prog->expected_attach_type == BPF_LSM_CGROUP) -+ return __bpf_prog_exit_lsm_cgroup; -+ -+ return sleepable ? __bpf_prog_exit_sleepable : __bpf_prog_exit; -+} -+ - int __weak - arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end, - const struct btf_func_model *m, u32 flags, -diff --git a/lib/idr.c b/lib/idr.c -index 7ecdfdb5309e7..13f2758c23773 100644 ---- a/lib/idr.c -+++ b/lib/idr.c -@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(idr_alloc); - * @end: The maximum ID (exclusive). - * @gfp: Memory allocation flags. - * -- * Allocates an unused ID in the range specified by @nextid and @end. If -+ * Allocates an unused ID in the range specified by @start and @end. If - * @end is <= 0, it is treated as one larger than %INT_MAX. This allows - * callers to use @start + N as @end as long as N is within integer range. - * The search for an unused ID will start at the last ID allocated and will -diff --git a/lib/kunit/test.c b/lib/kunit/test.c -index 184df6f701b48..a90bd265d73db 100644 ---- a/lib/kunit/test.c -+++ b/lib/kunit/test.c -@@ -667,12 +667,13 @@ static int kunit_module_notify(struct notifier_block *nb, unsigned long val, - - switch (val) { - case MODULE_STATE_LIVE: -- kunit_module_init(mod); - break; - case MODULE_STATE_GOING: - kunit_module_exit(mod); - break; - case MODULE_STATE_COMING: -+ kunit_module_init(mod); -+ break; - case MODULE_STATE_UNFORMED: - break; - } -diff --git a/lib/test_meminit.c b/lib/test_meminit.c -index 60e1984c060fa..0ae35223d7733 100644 ---- a/lib/test_meminit.c -+++ b/lib/test_meminit.c -@@ -93,7 +93,7 @@ static int __init test_pages(int *total_failures) - int failures = 0, num_tests = 0; - int i; - -- for (i = 0; i < 10; i++) -+ for (i = 0; i <= MAX_ORDER; i++) - num_tests += do_alloc_pages_order(i, &failures); - - REPORT_FAILURES_IN_FN(); -diff --git a/lib/test_scanf.c b/lib/test_scanf.c -index b620cf7de5035..a2707af2951ab 100644 ---- a/lib/test_scanf.c -+++ b/lib/test_scanf.c -@@ -606,7 +606,7 @@ static void __init numbers_slice(void) - #define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn) \ - do { \ - const T expect[2] = { expect0, expect1 }; \ -- T result[2] = {~expect[0], ~expect[1]}; \ -+ T result[2] = { (T)~expect[0], (T)~expect[1] }; \ - \ - _test(fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]); \ - } while (0) -diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c -index 4962dd1ba4a68..c04214055229b 100644 ---- a/mm/hugetlb_vmemmap.c -+++ b/mm/hugetlb_vmemmap.c -@@ -36,14 +36,22 @@ struct vmemmap_remap_walk { - struct list_head *vmemmap_pages; - }; - --static int __split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) -+static int split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) - { - pmd_t __pmd; - int i; - unsigned long addr = start; -- struct page *page = pmd_page(*pmd); -- pte_t *pgtable = pte_alloc_one_kernel(&init_mm); -+ struct page *head; -+ pte_t *pgtable; -+ -+ spin_lock(&init_mm.page_table_lock); -+ head = pmd_leaf(*pmd) ? pmd_page(*pmd) : NULL; -+ spin_unlock(&init_mm.page_table_lock); - -+ if (!head) -+ return 0; -+ -+ pgtable = pte_alloc_one_kernel(&init_mm); - if (!pgtable) - return -ENOMEM; - -@@ -53,7 +61,7 @@ static int __split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) - pte_t entry, *pte; - pgprot_t pgprot = PAGE_KERNEL; - -- entry = mk_pte(page + i, pgprot); -+ entry = mk_pte(head + i, pgprot); - pte = pte_offset_kernel(&__pmd, addr); - set_pte_at(&init_mm, addr, pte, entry); - } -@@ -65,8 +73,8 @@ static int __split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) - * be treated as indepdenent small pages (as they can be freed - * individually). - */ -- if (!PageReserved(page)) -- split_page(page, get_order(PMD_SIZE)); -+ if (!PageReserved(head)) -+ split_page(head, get_order(PMD_SIZE)); - - /* Make pte visible before pmd. See comment in pmd_install(). */ - smp_wmb(); -@@ -80,20 +88,6 @@ static int __split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) - return 0; - } - --static int split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) --{ -- int leaf; -- -- spin_lock(&init_mm.page_table_lock); -- leaf = pmd_leaf(*pmd); -- spin_unlock(&init_mm.page_table_lock); -- -- if (!leaf) -- return 0; -- -- return __split_vmemmap_huge_pmd(pmd, start); --} -- - static void vmemmap_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, - struct vmemmap_remap_walk *walk) -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 67b6d8238b3ed..0a403b241718e 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -3841,10 +3841,6 @@ static ssize_t mem_cgroup_write(struct kernfs_open_file *of, - case _MEMSWAP: - ret = mem_cgroup_resize_max(memcg, nr_pages, true); - break; -- case _KMEM: -- /* kmem.limit_in_bytes is deprecated. */ -- ret = -EOPNOTSUPP; -- break; - case _TCP: - ret = memcg_update_tcp_max(memcg, nr_pages); - break; -@@ -5055,12 +5051,6 @@ static struct cftype mem_cgroup_legacy_files[] = { - .seq_show = memcg_numa_stat_show, - }, - #endif -- { -- .name = "kmem.limit_in_bytes", -- .private = MEMFILE_PRIVATE(_KMEM, RES_LIMIT), -- .write = mem_cgroup_write, -- .read_u64 = mem_cgroup_read_u64, -- }, - { - .name = "kmem.usage_in_bytes", - .private = MEMFILE_PRIVATE(_KMEM, RES_USAGE), -diff --git a/mm/vmscan.c b/mm/vmscan.c -index d18296109aa7e..93d6f27dd40b4 100644 ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4258,7 +4258,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap) - - /* prevent cold/hot inversion if force_scan is true */ - for (zone = 0; zone < MAX_NR_ZONES; zone++) { -- struct list_head *head = &lrugen->lists[old_gen][type][zone]; -+ struct list_head *head = &lrugen->folios[old_gen][type][zone]; - - while (!list_empty(head)) { - struct folio *folio = lru_to_folio(head); -@@ -4269,7 +4269,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap) - VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio); - - new_gen = folio_inc_gen(lruvec, folio, false); -- list_move_tail(&folio->lru, &lrugen->lists[new_gen][type][zone]); -+ list_move_tail(&folio->lru, &lrugen->folios[new_gen][type][zone]); - - if (!--remaining) - return false; -@@ -4297,7 +4297,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap) - gen = lru_gen_from_seq(min_seq[type]); - - for (zone = 0; zone < MAX_NR_ZONES; zone++) { -- if (!list_empty(&lrugen->lists[gen][type][zone])) -+ if (!list_empty(&lrugen->folios[gen][type][zone])) - goto next; - } - -@@ -4331,6 +4331,7 @@ static void inc_max_seq(struct lruvec *lruvec, bool can_swap, bool force_scan) - int type, zone; - struct lru_gen_struct *lrugen = &lruvec->lrugen; - -+restart: - spin_lock_irq(&lruvec->lru_lock); - - VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -@@ -4341,11 +4342,12 @@ static void inc_max_seq(struct lruvec *lruvec, bool can_swap, bool force_scan) - - VM_WARN_ON_ONCE(!force_scan && (type == LRU_GEN_FILE || can_swap)); - -- while (!inc_min_seq(lruvec, type, can_swap)) { -- spin_unlock_irq(&lruvec->lru_lock); -- cond_resched(); -- spin_lock_irq(&lruvec->lru_lock); -- } -+ if (inc_min_seq(lruvec, type, can_swap)) -+ continue; -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ cond_resched(); -+ goto restart; - } - - /* -@@ -4728,7 +4730,8 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) - * the eviction - ******************************************************************************/ - --static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx) -+static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_control *sc, -+ int tier_idx) - { - bool success; - int gen = folio_lru_gen(folio); -@@ -4762,7 +4765,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx) - - /* promoted */ - if (gen != lru_gen_from_seq(lrugen->min_seq[type])) { -- list_move(&folio->lru, &lrugen->lists[gen][type][zone]); -+ list_move(&folio->lru, &lrugen->folios[gen][type][zone]); - return true; - } - -@@ -4771,7 +4774,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx) - int hist = lru_hist_from_seq(lrugen->min_seq[type]); - - gen = folio_inc_gen(lruvec, folio, false); -- list_move_tail(&folio->lru, &lrugen->lists[gen][type][zone]); -+ list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); - - WRITE_ONCE(lrugen->protected[hist][type][tier - 1], - lrugen->protected[hist][type][tier - 1] + delta); -@@ -4779,11 +4782,18 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx) - return true; - } - -+ /* ineligible */ -+ if (zone > sc->reclaim_idx) { -+ gen = folio_inc_gen(lruvec, folio, false); -+ list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); -+ return true; -+ } -+ - /* waiting for writeback */ - if (folio_test_locked(folio) || folio_test_writeback(folio) || - (type == LRU_GEN_FILE && folio_test_dirty(folio))) { - gen = folio_inc_gen(lruvec, folio, true); -- list_move(&folio->lru, &lrugen->lists[gen][type][zone]); -+ list_move(&folio->lru, &lrugen->folios[gen][type][zone]); - return true; - } - -@@ -4831,7 +4841,8 @@ static bool isolate_folio(struct lruvec *lruvec, struct folio *folio, struct sca - static int scan_folios(struct lruvec *lruvec, struct scan_control *sc, - int type, int tier, struct list_head *list) - { -- int gen, zone; -+ int i; -+ int gen; - enum vm_event_item item; - int sorted = 0; - int scanned = 0; -@@ -4847,10 +4858,11 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc, - - gen = lru_gen_from_seq(lrugen->min_seq[type]); - -- for (zone = sc->reclaim_idx; zone >= 0; zone--) { -+ for (i = MAX_NR_ZONES; i > 0; i--) { - LIST_HEAD(moved); - int skipped = 0; -- struct list_head *head = &lrugen->lists[gen][type][zone]; -+ int zone = (sc->reclaim_idx + i) % MAX_NR_ZONES; -+ struct list_head *head = &lrugen->folios[gen][type][zone]; - - while (!list_empty(head)) { - struct folio *folio = lru_to_folio(head); -@@ -4863,7 +4875,7 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc, - - scanned += delta; - -- if (sort_folio(lruvec, folio, tier)) -+ if (sort_folio(lruvec, folio, sc, tier)) - sorted += delta; - else if (isolate_folio(lruvec, folio, sc)) { - list_add(&folio->lru, list); -@@ -5250,7 +5262,7 @@ static bool __maybe_unused state_is_valid(struct lruvec *lruvec) - int gen, type, zone; - - for_each_gen_type_zone(gen, type, zone) { -- if (!list_empty(&lrugen->lists[gen][type][zone])) -+ if (!list_empty(&lrugen->folios[gen][type][zone])) - return false; - } - } -@@ -5295,7 +5307,7 @@ static bool drain_evictable(struct lruvec *lruvec) - int remaining = MAX_LRU_BATCH; - - for_each_gen_type_zone(gen, type, zone) { -- struct list_head *head = &lruvec->lrugen.lists[gen][type][zone]; -+ struct list_head *head = &lruvec->lrugen.folios[gen][type][zone]; - - while (!list_empty(head)) { - bool success; -@@ -5832,7 +5844,7 @@ void lru_gen_init_lruvec(struct lruvec *lruvec) - lrugen->timestamps[i] = jiffies; - - for_each_gen_type_zone(gen, type, zone) -- INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -+ INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]); - - lruvec->mm_state.seq = MIN_NR_GENS; - init_waitqueue_head(&lruvec->mm_state.wait); -diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c -index 007730412947d..3288490590f27 100644 ---- a/net/core/flow_dissector.c -+++ b/net/core/flow_dissector.c -@@ -1738,8 +1738,7 @@ u32 __skb_get_hash_symmetric(const struct sk_buff *skb) - - memset(&keys, 0, sizeof(keys)); - __skb_flow_dissect(NULL, skb, &flow_keys_dissector_symmetric, -- &keys, NULL, 0, 0, 0, -- FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); -+ &keys, NULL, 0, 0, 0, 0); - - return __flow_hash_from_keys(&keys, &hashrnd); - } -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 24bf4aa222d27..8dca4a7ca4a1f 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -424,17 +424,26 @@ EXPORT_SYMBOL(napi_build_skb); - * may be used. Otherwise, the packet data may be discarded until enough - * memory is free - */ --static void *kmalloc_reserve(size_t size, gfp_t flags, int node, -+static void *kmalloc_reserve(unsigned int *size, gfp_t flags, int node, - bool *pfmemalloc) - { -- void *obj; - bool ret_pfmemalloc = false; -+ size_t obj_size; -+ void *obj; -+ -+ obj_size = SKB_HEAD_ALIGN(*size); -+ -+ obj_size = kmalloc_size_roundup(obj_size); -+ /* The following cast might truncate high-order bits of obj_size, this -+ * is harmless because kmalloc(obj_size >= 2^32) will fail anyway. -+ */ -+ *size = (unsigned int)obj_size; - - /* - * Try a regular allocation, when that fails and we're not entitled - * to the reserves, fail. - */ -- obj = kmalloc_node_track_caller(size, -+ obj = kmalloc_node_track_caller(obj_size, - flags | __GFP_NOMEMALLOC | __GFP_NOWARN, - node); - if (obj || !(gfp_pfmemalloc_allowed(flags))) -@@ -442,7 +451,7 @@ static void *kmalloc_reserve(size_t size, gfp_t flags, int node, - - /* Try again but now we are using pfmemalloc reserves */ - ret_pfmemalloc = true; -- obj = kmalloc_node_track_caller(size, flags, node); -+ obj = kmalloc_node_track_caller(obj_size, flags, node); - - out: - if (pfmemalloc) -@@ -479,7 +488,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, - { - struct kmem_cache *cache; - struct sk_buff *skb; -- unsigned int osize; - bool pfmemalloc; - u8 *data; - -@@ -504,18 +512,14 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, - * aligned memory blocks, unless SLUB/SLAB debug is enabled. - * Both skb->head and skb_shared_info are cache line aligned. - */ -- size = SKB_DATA_ALIGN(size); -- size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -- osize = kmalloc_size_roundup(size); -- data = kmalloc_reserve(osize, gfp_mask, node, &pfmemalloc); -+ data = kmalloc_reserve(&size, gfp_mask, node, &pfmemalloc); - if (unlikely(!data)) - goto nodata; - /* kmalloc_size_roundup() might give us more room than requested. - * Put skb_shared_info exactly at the end of allocated zone, - * to allow max possible filling before reallocation. - */ -- size = SKB_WITH_OVERHEAD(osize); -- prefetchw(data + size); -+ prefetchw(data + SKB_WITH_OVERHEAD(size)); - - /* - * Only clear those fields we need to clear, not those that we will -@@ -523,7 +527,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, - * the tail pointer in struct sk_buff! - */ - memset(skb, 0, offsetof(struct sk_buff, tail)); -- __build_skb_around(skb, data, osize); -+ __build_skb_around(skb, data, size); - skb->pfmemalloc = pfmemalloc; - - if (flags & SKB_ALLOC_FCLONE) { -@@ -578,8 +582,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, - goto skb_success; - } - -- len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -- len = SKB_DATA_ALIGN(len); -+ len = SKB_HEAD_ALIGN(len); - - if (sk_memalloc_socks()) - gfp_mask |= __GFP_MEMALLOC; -@@ -678,8 +681,7 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, - data = page_frag_alloc_1k(&nc->page_small, gfp_mask); - pfmemalloc = NAPI_SMALL_PAGE_PFMEMALLOC(nc->page_small); - } else { -- len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -- len = SKB_DATA_ALIGN(len); -+ len = SKB_HEAD_ALIGN(len); - - data = page_frag_alloc(&nc->page, len, gfp_mask); - pfmemalloc = nc->page.pfmemalloc; -@@ -1837,10 +1839,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, - if (skb_pfmemalloc(skb)) - gfp_mask |= __GFP_MEMALLOC; - -- size = SKB_DATA_ALIGN(size); -- size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -- size = kmalloc_size_roundup(size); -- data = kmalloc_reserve(size, gfp_mask, NUMA_NO_NODE, NULL); -+ data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); - if (!data) - goto nodata; - size = SKB_WITH_OVERHEAD(size); -@@ -6204,10 +6203,7 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off, - if (skb_pfmemalloc(skb)) - gfp_mask |= __GFP_MEMALLOC; - -- size = SKB_DATA_ALIGN(size); -- size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -- size = kmalloc_size_roundup(size); -- data = kmalloc_reserve(size, gfp_mask, NUMA_NO_NODE, NULL); -+ data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); - if (!data) - return -ENOMEM; - size = SKB_WITH_OVERHEAD(size); -@@ -6323,10 +6319,7 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off, - if (skb_pfmemalloc(skb)) - gfp_mask |= __GFP_MEMALLOC; - -- size = SKB_DATA_ALIGN(size); -- size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -- size = kmalloc_size_roundup(size); -- data = kmalloc_reserve(size, gfp_mask, NUMA_NO_NODE, NULL); -+ data = kmalloc_reserve(&size, gfp_mask, NUMA_NO_NODE, NULL); - if (!data) - return -ENOMEM; - size = SKB_WITH_OVERHEAD(size); -diff --git a/net/core/skmsg.c b/net/core/skmsg.c -index 296e45b6c3c0d..a5c1f67dc96ec 100644 ---- a/net/core/skmsg.c -+++ b/net/core/skmsg.c -@@ -611,12 +611,18 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb - static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb, - u32 off, u32 len, bool ingress) - { -+ int err = 0; -+ - if (!ingress) { - if (!sock_writeable(psock->sk)) - return -EAGAIN; - return skb_send_sock(psock->sk, skb, off, len); - } -- return sk_psock_skb_ingress(psock, skb, off, len); -+ skb_get(skb); -+ err = sk_psock_skb_ingress(psock, skb, off, len); -+ if (err < 0) -+ kfree_skb(skb); -+ return err; - } - - static void sk_psock_skb_state(struct sk_psock *psock, -@@ -684,9 +690,7 @@ static void sk_psock_backlog(struct work_struct *work) - } while (len); - - skb = skb_dequeue(&psock->ingress_skb); -- if (!ingress) { -- kfree_skb(skb); -- } -+ kfree_skb(skb); - } - end: - mutex_unlock(&psock->work_mutex); -diff --git a/net/core/sock.c b/net/core/sock.c -index fc475845c94d5..e5858fa5d6d57 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -761,7 +761,8 @@ bool sk_mc_loop(struct sock *sk) - return false; - if (!sk) - return true; -- switch (sk->sk_family) { -+ /* IPV6_ADDRFORM can change sk->sk_family under us. */ -+ switch (READ_ONCE(sk->sk_family)) { - case AF_INET: - return inet_sk(sk)->mc_loop; - #if IS_ENABLED(CONFIG_IPV6) -@@ -1033,7 +1034,7 @@ static int sock_reserve_memory(struct sock *sk, int bytes) - mem_cgroup_uncharge_skmem(sk->sk_memcg, pages); - return -ENOMEM; - } -- sk->sk_forward_alloc += pages << PAGE_SHIFT; -+ sk_forward_alloc_add(sk, pages << PAGE_SHIFT); - - WRITE_ONCE(sk->sk_reserved_mem, - sk->sk_reserved_mem + (pages << PAGE_SHIFT)); -@@ -2689,9 +2690,9 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo) - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); - if (refcount_read(&sk->sk_wmem_alloc) < READ_ONCE(sk->sk_sndbuf)) - break; -- if (sk->sk_shutdown & SEND_SHUTDOWN) -+ if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) - break; -- if (sk->sk_err) -+ if (READ_ONCE(sk->sk_err)) - break; - timeo = schedule_timeout(timeo); - } -@@ -2719,7 +2720,7 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, - goto failure; - - err = -EPIPE; -- if (sk->sk_shutdown & SEND_SHUTDOWN) -+ if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) - goto failure; - - if (sk_wmem_alloc_get(sk) < READ_ONCE(sk->sk_sndbuf)) -@@ -3081,10 +3082,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) - { - int ret, amt = sk_mem_pages(size); - -- sk->sk_forward_alloc += amt << PAGE_SHIFT; -+ sk_forward_alloc_add(sk, amt << PAGE_SHIFT); - ret = __sk_mem_raise_allocated(sk, size, amt, kind); - if (!ret) -- sk->sk_forward_alloc -= amt << PAGE_SHIFT; -+ sk_forward_alloc_add(sk, -(amt << PAGE_SHIFT)); - return ret; - } - EXPORT_SYMBOL(__sk_mem_schedule); -@@ -3116,7 +3117,7 @@ void __sk_mem_reduce_allocated(struct sock *sk, int amount) - void __sk_mem_reclaim(struct sock *sk, int amount) - { - amount >>= PAGE_SHIFT; -- sk->sk_forward_alloc -= amount << PAGE_SHIFT; -+ sk_forward_alloc_add(sk, -(amount << PAGE_SHIFT)); - __sk_mem_reduce_allocated(sk, amount); - } - EXPORT_SYMBOL(__sk_mem_reclaim); -@@ -3714,7 +3715,7 @@ void sk_get_meminfo(const struct sock *sk, u32 *mem) - mem[SK_MEMINFO_RCVBUF] = READ_ONCE(sk->sk_rcvbuf); - mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk); - mem[SK_MEMINFO_SNDBUF] = READ_ONCE(sk->sk_sndbuf); -- mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; -+ mem[SK_MEMINFO_FWD_ALLOC] = sk_forward_alloc_get(sk); - mem[SK_MEMINFO_WMEM_QUEUED] = READ_ONCE(sk->sk_wmem_queued); - mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); - mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len); -diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c -index 940c0e27be735..e31d1247b9f08 100644 ---- a/net/ethtool/ioctl.c -+++ b/net/ethtool/ioctl.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -3090,7 +3091,6 @@ struct ethtool_rx_flow_rule * - ethtool_rx_flow_rule_create(const struct ethtool_rx_flow_spec_input *input) - { - const struct ethtool_rx_flow_spec *fs = input->fs; -- static struct in6_addr zero_addr = {}; - struct ethtool_rx_flow_match *match; - struct ethtool_rx_flow_rule *flow; - struct flow_action_entry *act; -@@ -3196,20 +3196,20 @@ ethtool_rx_flow_rule_create(const struct ethtool_rx_flow_spec_input *input) - - v6_spec = &fs->h_u.tcp_ip6_spec; - v6_m_spec = &fs->m_u.tcp_ip6_spec; -- if (memcmp(v6_m_spec->ip6src, &zero_addr, sizeof(zero_addr))) { -+ if (!ipv6_addr_any((struct in6_addr *)v6_m_spec->ip6src)) { - memcpy(&match->key.ipv6.src, v6_spec->ip6src, - sizeof(match->key.ipv6.src)); - memcpy(&match->mask.ipv6.src, v6_m_spec->ip6src, - sizeof(match->mask.ipv6.src)); - } -- if (memcmp(v6_m_spec->ip6dst, &zero_addr, sizeof(zero_addr))) { -+ if (!ipv6_addr_any((struct in6_addr *)v6_m_spec->ip6dst)) { - memcpy(&match->key.ipv6.dst, v6_spec->ip6dst, - sizeof(match->key.ipv6.dst)); - memcpy(&match->mask.ipv6.dst, v6_m_spec->ip6dst, - sizeof(match->mask.ipv6.dst)); - } -- if (memcmp(v6_m_spec->ip6src, &zero_addr, sizeof(zero_addr)) || -- memcmp(v6_m_spec->ip6dst, &zero_addr, sizeof(zero_addr))) { -+ if (!ipv6_addr_any((struct in6_addr *)v6_m_spec->ip6src) || -+ !ipv6_addr_any((struct in6_addr *)v6_m_spec->ip6dst)) { - match->dissector.used_keys |= - BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS); - match->dissector.offset[FLOW_DISSECTOR_KEY_IPV6_ADDRS] = -diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c -index 629daacc96071..b71dab630a873 100644 ---- a/net/hsr/hsr_forward.c -+++ b/net/hsr/hsr_forward.c -@@ -594,6 +594,7 @@ static int fill_frame_info(struct hsr_frame_info *frame, - proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; - /* FIXME: */ - netdev_warn_once(skb->dev, "VLAN not yet supported"); -+ return -EINVAL; - } - - frame->is_from_san = false; -diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c -index e8b9a9202fecd..35d6e74be8406 100644 ---- a/net/ipv4/devinet.c -+++ b/net/ipv4/devinet.c -@@ -354,14 +354,14 @@ static void __inet_del_ifa(struct in_device *in_dev, - { - struct in_ifaddr *promote = NULL; - struct in_ifaddr *ifa, *ifa1; -- struct in_ifaddr *last_prim; -+ struct in_ifaddr __rcu **last_prim; - struct in_ifaddr *prev_prom = NULL; - int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev); - - ASSERT_RTNL(); - - ifa1 = rtnl_dereference(*ifap); -- last_prim = rtnl_dereference(in_dev->ifa_list); -+ last_prim = ifap; - if (in_dev->dead) - goto no_promotions; - -@@ -375,7 +375,7 @@ static void __inet_del_ifa(struct in_device *in_dev, - while ((ifa = rtnl_dereference(*ifap1)) != NULL) { - if (!(ifa->ifa_flags & IFA_F_SECONDARY) && - ifa1->ifa_scope <= ifa->ifa_scope) -- last_prim = ifa; -+ last_prim = &ifa->ifa_next; - - if (!(ifa->ifa_flags & IFA_F_SECONDARY) || - ifa1->ifa_mask != ifa->ifa_mask || -@@ -439,9 +439,9 @@ no_promotions: - - rcu_assign_pointer(prev_prom->ifa_next, next_sec); - -- last_sec = rtnl_dereference(last_prim->ifa_next); -+ last_sec = rtnl_dereference(*last_prim); - rcu_assign_pointer(promote->ifa_next, last_sec); -- rcu_assign_pointer(last_prim->ifa_next, promote); -+ rcu_assign_pointer(*last_prim, promote); - } - - promote->ifa_flags &= ~IFA_F_SECONDARY; -diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c -index 3bb890a40ed73..3b6e6bc80dc1c 100644 ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -278,7 +278,8 @@ void fib_release_info(struct fib_info *fi) - hlist_del(&nexthop_nh->nh_hash); - } endfor_nexthops(fi) - } -- fi->fib_dead = 1; -+ /* Paired with READ_ONCE() from fib_table_lookup() */ -+ WRITE_ONCE(fi->fib_dead, 1); - fib_info_put(fi); - } - spin_unlock_bh(&fib_info_lock); -@@ -1581,6 +1582,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, - link_it: - ofi = fib_find_info(fi); - if (ofi) { -+ /* fib_table_lookup() should not see @fi yet. */ - fi->fib_dead = 1; - free_fib_info(fi); - refcount_inc(&ofi->fib_treeref); -@@ -1619,6 +1621,7 @@ err_inval: - - failure: - if (fi) { -+ /* fib_table_lookup() should not see @fi yet. */ - fi->fib_dead = 1; - free_fib_info(fi); - } -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index 74d403dbd2b4e..d13fb9e76b971 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -1582,7 +1582,8 @@ found: - if (fa->fa_dscp && - inet_dscp_to_dsfield(fa->fa_dscp) != flp->flowi4_tos) - continue; -- if (fi->fib_dead) -+ /* Paired with WRITE_ONCE() in fib_release_info() */ -+ if (READ_ONCE(fi->fib_dead)) - continue; - if (fa->fa_info->fib_scope < flp->flowi4_scope) - continue; -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index c19b462662ad0..d79de4b95186b 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -795,43 +795,45 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb, - const struct net *net, unsigned short port, - int l3mdev, const struct sock *sk) - { -+ if (!net_eq(ib2_net(tb), net) || tb->port != port || -+ tb->l3mdev != l3mdev) -+ return false; -+ - #if IS_ENABLED(CONFIG_IPV6) -- if (sk->sk_family != tb->family) -+ if (sk->sk_family != tb->family) { -+ if (sk->sk_family == AF_INET) -+ return ipv6_addr_v4mapped(&tb->v6_rcv_saddr) && -+ tb->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; -+ - return false; -+ } - - if (sk->sk_family == AF_INET6) -- return net_eq(ib2_net(tb), net) && tb->port == port && -- tb->l3mdev == l3mdev && -- ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); -- else -+ return ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); - #endif -- return net_eq(ib2_net(tb), net) && tb->port == port && -- tb->l3mdev == l3mdev && tb->rcv_saddr == sk->sk_rcv_saddr; -+ return tb->rcv_saddr == sk->sk_rcv_saddr; - } - - bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const struct net *net, - unsigned short port, int l3mdev, const struct sock *sk) - { --#if IS_ENABLED(CONFIG_IPV6) -- struct in6_addr addr_any = {}; -+ if (!net_eq(ib2_net(tb), net) || tb->port != port || -+ tb->l3mdev != l3mdev) -+ return false; - -+#if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family != tb->family) { - if (sk->sk_family == AF_INET) -- return net_eq(ib2_net(tb), net) && tb->port == port && -- tb->l3mdev == l3mdev && -- ipv6_addr_equal(&tb->v6_rcv_saddr, &addr_any); -+ return ipv6_addr_any(&tb->v6_rcv_saddr) || -+ ipv6_addr_v4mapped_any(&tb->v6_rcv_saddr); - - return false; - } - - if (sk->sk_family == AF_INET6) -- return net_eq(ib2_net(tb), net) && tb->port == port && -- tb->l3mdev == l3mdev && -- ipv6_addr_equal(&tb->v6_rcv_saddr, &addr_any); -- else -+ return ipv6_addr_any(&tb->v6_rcv_saddr); - #endif -- return net_eq(ib2_net(tb), net) && tb->port == port && -- tb->l3mdev == l3mdev && tb->rcv_saddr == 0; -+ return tb->rcv_saddr == 0; - } - - /* The socket's bhash2 hashbucket spinlock must be held when this is called */ -@@ -853,11 +855,10 @@ inet_bhash2_addr_any_hashbucket(const struct sock *sk, const struct net *net, in - { - struct inet_hashinfo *hinfo = tcp_or_dccp_get_hashinfo(sk); - u32 hash; --#if IS_ENABLED(CONFIG_IPV6) -- struct in6_addr addr_any = {}; - -+#if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family == AF_INET6) -- hash = ipv6_portaddr_hash(net, &addr_any, port); -+ hash = ipv6_portaddr_hash(net, &in6addr_any, port); - else - #endif - hash = ipv4_portaddr_hash(net, 0, port); -diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c -index e880ce77322aa..e7196ecffafc6 100644 ---- a/net/ipv4/ip_input.c -+++ b/net/ipv4/ip_input.c -@@ -584,7 +584,8 @@ static void ip_sublist_rcv_finish(struct list_head *head) - static struct sk_buff *ip_extract_route_hint(const struct net *net, - struct sk_buff *skb, int rt_type) - { -- if (fib4_has_custom_rules(net) || rt_type == RTN_BROADCAST) -+ if (fib4_has_custom_rules(net) || rt_type == RTN_BROADCAST || -+ IPCB(skb)->flags & IPSKB_MULTIPATH) - return NULL; - - return skb; -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 51bd9a50a1d1d..a04ffc128e22b 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -2146,6 +2146,7 @@ static int ip_mkroute_input(struct sk_buff *skb, - int h = fib_multipath_hash(res->fi->fib_net, NULL, skb, hkeys); - - fib_select_multipath(res, h); -+ IPCB(skb)->flags |= IPSKB_MULTIPATH; - } - #endif - -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index 26bd039f9296f..dc3166e56169f 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -3380,7 +3380,7 @@ void sk_forced_mem_schedule(struct sock *sk, int size) - if (delta <= 0) - return; - amt = sk_mem_pages(delta); -- sk->sk_forward_alloc += amt << PAGE_SHIFT; -+ sk_forward_alloc_add(sk, amt << PAGE_SHIFT); - sk_memory_allocated_add(sk, amt); - - if (mem_cgroup_sockets_enabled && sk->sk_memcg) -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 42c1f7d9a980a..b2aa7777521f6 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -1474,9 +1474,9 @@ static void udp_rmem_release(struct sock *sk, int size, int partial, - spin_lock(&sk_queue->lock); - - -- sk->sk_forward_alloc += size; -+ sk_forward_alloc_add(sk, size); - amt = (sk->sk_forward_alloc - partial) & ~(PAGE_SIZE - 1); -- sk->sk_forward_alloc -= amt; -+ sk_forward_alloc_add(sk, -amt); - - if (amt) - __sk_mem_reduce_allocated(sk, amt >> PAGE_SHIFT); -@@ -1582,7 +1582,7 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb) - sk->sk_forward_alloc += delta; - } - -- sk->sk_forward_alloc -= size; -+ sk_forward_alloc_add(sk, -size); - - /* no need to setup a destructor, we will explicitly release the - * forward allocated memory on dequeue -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 48a6486951cd6..83be842198244 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -1368,7 +1368,7 @@ retry: - * idev->desync_factor if it's larger - */ - cnf_temp_preferred_lft = READ_ONCE(idev->cnf.temp_prefered_lft); -- max_desync_factor = min_t(__u32, -+ max_desync_factor = min_t(long, - idev->cnf.max_desync_factor, - cnf_temp_preferred_lft - regen_advance); - -diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c -index d94041bb42872..b8378814532ce 100644 ---- a/net/ipv6/ip6_input.c -+++ b/net/ipv6/ip6_input.c -@@ -99,7 +99,8 @@ static bool ip6_can_use_hint(const struct sk_buff *skb, - static struct sk_buff *ip6_extract_route_hint(const struct net *net, - struct sk_buff *skb) - { -- if (fib6_routes_require_src(net) || fib6_has_custom_rules(net)) -+ if (fib6_routes_require_src(net) || fib6_has_custom_rules(net) || -+ IP6CB(skb)->flags & IP6SKB_MULTIPATH) - return NULL; - - return skb; -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 960ab43a49c46..93957b20fccce 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -425,6 +425,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res, - if (match->nh && have_oif_match && res->nh) - return; - -+ if (skb) -+ IP6CB(skb)->flags |= IP6SKB_MULTIPATH; -+ - /* We might have already computed the hash for ICMPv6 errors. In such - * case it will always be non-zero. Otherwise now is the time to do it. - */ -diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c -index 890a2423f559e..65845c59c0655 100644 ---- a/net/kcm/kcmsock.c -+++ b/net/kcm/kcmsock.c -@@ -1065,15 +1065,18 @@ partial_message: - out_error: - kcm_push(kcm); - -- if (copied && sock->type == SOCK_SEQPACKET) { -+ if (sock->type == SOCK_SEQPACKET) { - /* Wrote some bytes before encountering an - * error, return partial success. - */ -- goto partial_message; -- } -- -- if (head != kcm->seq_skb) -+ if (copied) -+ goto partial_message; -+ if (head != kcm->seq_skb) -+ kfree_skb(head); -+ } else { - kfree_skb(head); -+ kcm->seq_skb = NULL; -+ } - - err = sk_stream_error(sk, msg->msg_flags, err); - -@@ -1981,6 +1984,8 @@ static __net_exit void kcm_exit_net(struct net *net) - * that all multiplexors and psocks have been destroyed. - */ - WARN_ON(!list_empty(&knet->mux_list)); -+ -+ mutex_destroy(&knet->mutex); - } - - static struct pernet_operations kcm_net_ops = { -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index 61fefa1a82db2..6dd880d6b0518 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -131,9 +131,15 @@ static void mptcp_drop(struct sock *sk, struct sk_buff *skb) - __kfree_skb(skb); - } - -+static void mptcp_rmem_fwd_alloc_add(struct sock *sk, int size) -+{ -+ WRITE_ONCE(mptcp_sk(sk)->rmem_fwd_alloc, -+ mptcp_sk(sk)->rmem_fwd_alloc + size); -+} -+ - static void mptcp_rmem_charge(struct sock *sk, int size) - { -- mptcp_sk(sk)->rmem_fwd_alloc -= size; -+ mptcp_rmem_fwd_alloc_add(sk, -size); - } - - static bool mptcp_try_coalesce(struct sock *sk, struct sk_buff *to, -@@ -174,7 +180,7 @@ static bool mptcp_ooo_try_coalesce(struct mptcp_sock *msk, struct sk_buff *to, - static void __mptcp_rmem_reclaim(struct sock *sk, int amount) - { - amount >>= PAGE_SHIFT; -- mptcp_sk(sk)->rmem_fwd_alloc -= amount << PAGE_SHIFT; -+ mptcp_rmem_charge(sk, amount << PAGE_SHIFT); - __sk_mem_reduce_allocated(sk, amount); - } - -@@ -183,7 +189,7 @@ static void mptcp_rmem_uncharge(struct sock *sk, int size) - struct mptcp_sock *msk = mptcp_sk(sk); - int reclaimable; - -- msk->rmem_fwd_alloc += size; -+ mptcp_rmem_fwd_alloc_add(sk, size); - reclaimable = msk->rmem_fwd_alloc - sk_unused_reserved_mem(sk); - - /* see sk_mem_uncharge() for the rationale behind the following schema */ -@@ -338,7 +344,7 @@ static bool mptcp_rmem_schedule(struct sock *sk, struct sock *ssk, int size) - if (!__sk_mem_raise_allocated(sk, size, amt, SK_MEM_RECV)) - return false; - -- msk->rmem_fwd_alloc += amount; -+ mptcp_rmem_fwd_alloc_add(sk, amount); - return true; - } - -@@ -1802,7 +1808,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - } - - /* data successfully copied into the write queue */ -- sk->sk_forward_alloc -= total_ts; -+ sk_forward_alloc_add(sk, -total_ts); - copied += psize; - dfrag->data_len += psize; - frag_truesize += psize; -@@ -3278,8 +3284,8 @@ void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags) - /* move all the rx fwd alloc into the sk_mem_reclaim_final in - * inet_sock_destruct() will dispose it - */ -- sk->sk_forward_alloc += msk->rmem_fwd_alloc; -- msk->rmem_fwd_alloc = 0; -+ sk_forward_alloc_add(sk, msk->rmem_fwd_alloc); -+ WRITE_ONCE(msk->rmem_fwd_alloc, 0); - mptcp_token_destroy(msk); - mptcp_pm_free_anno_list(msk); - mptcp_free_local_addr_list(msk); -@@ -3562,7 +3568,8 @@ static void mptcp_shutdown(struct sock *sk, int how) - - static int mptcp_forward_alloc_get(const struct sock *sk) - { -- return sk->sk_forward_alloc + mptcp_sk(sk)->rmem_fwd_alloc; -+ return READ_ONCE(sk->sk_forward_alloc) + -+ READ_ONCE(mptcp_sk(sk)->rmem_fwd_alloc); - } - - static int mptcp_ioctl_outq(const struct mptcp_sock *msk, u64 v) -diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c -index 8f1bfa6ccc2d9..50723ba082890 100644 ---- a/net/netfilter/nfnetlink_osf.c -+++ b/net/netfilter/nfnetlink_osf.c -@@ -315,6 +315,14 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, - - f = nla_data(osf_attrs[OSF_ATTR_FINGER]); - -+ if (f->opt_num > ARRAY_SIZE(f->opt)) -+ return -EINVAL; -+ -+ if (!memchr(f->genre, 0, MAXGENRELEN) || -+ !memchr(f->subtype, 0, MAXGENRELEN) || -+ !memchr(f->version, 0, MAXGENRELEN)) -+ return -EINVAL; -+ - kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL); - if (!kf) - return -ENOMEM; -diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c -index c307c57a93e57..efb50c2b41f32 100644 ---- a/net/netfilter/nft_exthdr.c -+++ b/net/netfilter/nft_exthdr.c -@@ -35,6 +35,14 @@ static unsigned int optlen(const u8 *opt, unsigned int offset) - return opt[offset + 1]; - } - -+static int nft_skb_copy_to_reg(const struct sk_buff *skb, int offset, u32 *dest, unsigned int len) -+{ -+ if (len % NFT_REG32_SIZE) -+ dest[len / NFT_REG32_SIZE] = 0; -+ -+ return skb_copy_bits(skb, offset, dest, len); -+} -+ - static void nft_exthdr_ipv6_eval(const struct nft_expr *expr, - struct nft_regs *regs, - const struct nft_pktinfo *pkt) -@@ -56,8 +64,7 @@ static void nft_exthdr_ipv6_eval(const struct nft_expr *expr, - } - offset += priv->offset; - -- dest[priv->len / NFT_REG32_SIZE] = 0; -- if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0) -+ if (nft_skb_copy_to_reg(pkt->skb, offset, dest, priv->len) < 0) - goto err; - return; - err: -@@ -153,8 +160,7 @@ static void nft_exthdr_ipv4_eval(const struct nft_expr *expr, - } - offset += priv->offset; - -- dest[priv->len / NFT_REG32_SIZE] = 0; -- if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0) -+ if (nft_skb_copy_to_reg(pkt->skb, offset, dest, priv->len) < 0) - goto err; - return; - err: -@@ -210,7 +216,8 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr, - if (priv->flags & NFT_EXTHDR_F_PRESENT) { - *dest = 1; - } else { -- dest[priv->len / NFT_REG32_SIZE] = 0; -+ if (priv->len % NFT_REG32_SIZE) -+ dest[priv->len / NFT_REG32_SIZE] = 0; - memcpy(dest, opt + offset, priv->len); - } - -@@ -388,9 +395,8 @@ static void nft_exthdr_sctp_eval(const struct nft_expr *expr, - offset + ntohs(sch->length) > pkt->skb->len) - break; - -- dest[priv->len / NFT_REG32_SIZE] = 0; -- if (skb_copy_bits(pkt->skb, offset + priv->offset, -- dest, priv->len) < 0) -+ if (nft_skb_copy_to_reg(pkt->skb, offset + priv->offset, -+ dest, priv->len) < 0) - break; - return; - } -diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c -index 591d87d5e5c0f..68e6acd0f130d 100644 ---- a/net/sched/sch_fq_pie.c -+++ b/net/sched/sch_fq_pie.c -@@ -61,6 +61,7 @@ struct fq_pie_sched_data { - struct pie_params p_params; - u32 ecn_prob; - u32 flows_cnt; -+ u32 flows_cursor; - u32 quantum; - u32 memory_limit; - u32 new_flow_count; -@@ -375,22 +376,32 @@ flow_error: - static void fq_pie_timer(struct timer_list *t) - { - struct fq_pie_sched_data *q = from_timer(q, t, adapt_timer); -+ unsigned long next, tupdate; - struct Qdisc *sch = q->sch; - spinlock_t *root_lock; /* to lock qdisc for probability calculations */ -- u32 idx; -+ int max_cnt, i; - - rcu_read_lock(); - root_lock = qdisc_lock(qdisc_root_sleeping(sch)); - spin_lock(root_lock); - -- for (idx = 0; idx < q->flows_cnt; idx++) -- pie_calculate_probability(&q->p_params, &q->flows[idx].vars, -- q->flows[idx].backlog); -- -- /* reset the timer to fire after 'tupdate' jiffies. */ -- if (q->p_params.tupdate) -- mod_timer(&q->adapt_timer, jiffies + q->p_params.tupdate); -+ /* Limit this expensive loop to 2048 flows per round. */ -+ max_cnt = min_t(int, q->flows_cnt - q->flows_cursor, 2048); -+ for (i = 0; i < max_cnt; i++) { -+ pie_calculate_probability(&q->p_params, -+ &q->flows[q->flows_cursor].vars, -+ q->flows[q->flows_cursor].backlog); -+ q->flows_cursor++; -+ } - -+ tupdate = q->p_params.tupdate; -+ next = 0; -+ if (q->flows_cursor >= q->flows_cnt) { -+ q->flows_cursor = 0; -+ next = tupdate; -+ } -+ if (tupdate) -+ mod_timer(&q->adapt_timer, jiffies + next); - spin_unlock(root_lock); - rcu_read_unlock(); - } -diff --git a/net/sched/sch_plug.c b/net/sched/sch_plug.c -index ea8c4a7174bba..35f49edf63dbf 100644 ---- a/net/sched/sch_plug.c -+++ b/net/sched/sch_plug.c -@@ -207,7 +207,7 @@ static struct Qdisc_ops plug_qdisc_ops __read_mostly = { - .priv_size = sizeof(struct plug_sched_data), - .enqueue = plug_enqueue, - .dequeue = plug_dequeue, -- .peek = qdisc_peek_head, -+ .peek = qdisc_peek_dequeued, - .init = plug_init, - .change = plug_change, - .reset = qdisc_reset_queue, -diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c -index e150d08f182d8..ed01634af82c2 100644 ---- a/net/sched/sch_qfq.c -+++ b/net/sched/sch_qfq.c -@@ -973,10 +973,13 @@ static void qfq_update_eligible(struct qfq_sched *q) - } - - /* Dequeue head packet of the head class in the DRR queue of the aggregate. */ --static void agg_dequeue(struct qfq_aggregate *agg, -- struct qfq_class *cl, unsigned int len) -+static struct sk_buff *agg_dequeue(struct qfq_aggregate *agg, -+ struct qfq_class *cl, unsigned int len) - { -- qdisc_dequeue_peeked(cl->qdisc); -+ struct sk_buff *skb = qdisc_dequeue_peeked(cl->qdisc); -+ -+ if (!skb) -+ return NULL; - - cl->deficit -= (int) len; - -@@ -986,6 +989,8 @@ static void agg_dequeue(struct qfq_aggregate *agg, - cl->deficit += agg->lmax; - list_move_tail(&cl->alist, &agg->active); - } -+ -+ return skb; - } - - static inline struct sk_buff *qfq_peek_skb(struct qfq_aggregate *agg, -@@ -1131,11 +1136,18 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch) - if (!skb) - return NULL; - -- qdisc_qstats_backlog_dec(sch, skb); - sch->q.qlen--; -+ -+ skb = agg_dequeue(in_serv_agg, cl, len); -+ -+ if (!skb) { -+ sch->q.qlen++; -+ return NULL; -+ } -+ -+ qdisc_qstats_backlog_dec(sch, skb); - qdisc_bstats_update(sch, skb); - -- agg_dequeue(in_serv_agg, cl, len); - /* If lmax is lowered, through qfq_change_class, for a class - * owning pending packets with larger size than the new value - * of lmax, then the following condition may hold. -diff --git a/net/sctp/proc.c b/net/sctp/proc.c -index f13d6a34f32f2..ec00ee75d59a6 100644 ---- a/net/sctp/proc.c -+++ b/net/sctp/proc.c -@@ -282,7 +282,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) - assoc->init_retries, assoc->shutdown_retries, - assoc->rtx_data_chunks, - refcount_read(&sk->sk_wmem_alloc), -- sk->sk_wmem_queued, -+ READ_ONCE(sk->sk_wmem_queued), - sk->sk_sndbuf, - sk->sk_rcvbuf); - seq_printf(seq, "\n"); -diff --git a/net/sctp/socket.c b/net/sctp/socket.c -index a11b0d903514c..32e3669adf146 100644 ---- a/net/sctp/socket.c -+++ b/net/sctp/socket.c -@@ -68,7 +68,7 @@ - #include - - /* Forward declarations for internal helper functions. */ --static bool sctp_writeable(struct sock *sk); -+static bool sctp_writeable(const struct sock *sk); - static void sctp_wfree(struct sk_buff *skb); - static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, - size_t msg_len); -@@ -139,7 +139,7 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk) - - refcount_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); - asoc->sndbuf_used += chunk->skb->truesize + sizeof(struct sctp_chunk); -- sk->sk_wmem_queued += chunk->skb->truesize + sizeof(struct sctp_chunk); -+ sk_wmem_queued_add(sk, chunk->skb->truesize + sizeof(struct sctp_chunk)); - sk_mem_charge(sk, chunk->skb->truesize); - } - -@@ -9139,7 +9139,7 @@ static void sctp_wfree(struct sk_buff *skb) - struct sock *sk = asoc->base.sk; - - sk_mem_uncharge(sk, skb->truesize); -- sk->sk_wmem_queued -= skb->truesize + sizeof(struct sctp_chunk); -+ sk_wmem_queued_add(sk, -(skb->truesize + sizeof(struct sctp_chunk))); - asoc->sndbuf_used -= skb->truesize + sizeof(struct sctp_chunk); - WARN_ON(refcount_sub_and_test(sizeof(struct sctp_chunk), - &sk->sk_wmem_alloc)); -@@ -9292,9 +9292,9 @@ void sctp_write_space(struct sock *sk) - * UDP-style sockets or TCP-style sockets, this code should work. - * - Daisy - */ --static bool sctp_writeable(struct sock *sk) -+static bool sctp_writeable(const struct sock *sk) - { -- return sk->sk_sndbuf > sk->sk_wmem_queued; -+ return READ_ONCE(sk->sk_sndbuf) > READ_ONCE(sk->sk_wmem_queued); - } - - /* Wait for an association to go into ESTABLISHED state. If timeout is 0, -diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c -index c676d92af7b7d..64b6dd439938e 100644 ---- a/net/smc/smc_core.c -+++ b/net/smc/smc_core.c -@@ -1650,6 +1650,7 @@ void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport) - { - struct smc_link_group *lgr, *n; - -+ spin_lock_bh(&smc_lgr_list.lock); - list_for_each_entry_safe(lgr, n, &smc_lgr_list.list, list) { - struct smc_link *link; - -@@ -1665,6 +1666,7 @@ void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport) - if (link) - smc_llc_add_link_local(link); - } -+ spin_unlock_bh(&smc_lgr_list.lock); - } - - /* link is down - switch connections to alternate link, -diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c -index 96b4545ea700f..9be00ebbb2341 100644 ---- a/net/tls/tls_sw.c -+++ b/net/tls/tls_sw.c -@@ -802,7 +802,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, - psock = sk_psock_get(sk); - if (!psock || !policy) { - err = tls_push_record(sk, flags, record_type); -- if (err && sk->sk_err == EBADMSG) { -+ if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) { - *copied -= sk_msg_free(sk, msg); - tls_free_open_rec(sk); - err = -sk->sk_err; -@@ -831,7 +831,7 @@ more_data: - switch (psock->eval) { - case __SK_PASS: - err = tls_push_record(sk, flags, record_type); -- if (err && sk->sk_err == EBADMSG) { -+ if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) { - *copied -= sk_msg_free(sk, msg); - tls_free_open_rec(sk); - err = -sk->sk_err; -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index ca31847a6c70c..310952f4c68f7 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -667,7 +667,7 @@ static void unix_release_sock(struct sock *sk, int embrion) - * What the above comment does talk about? --ANK(980817) - */ - -- if (unix_tot_inflight) -+ if (READ_ONCE(unix_tot_inflight)) - unix_gc(); /* Garbage collect fds */ - } - -diff --git a/net/unix/scm.c b/net/unix/scm.c -index aa27a02478dc1..e8e2a00bb0f58 100644 ---- a/net/unix/scm.c -+++ b/net/unix/scm.c -@@ -63,7 +63,7 @@ void unix_inflight(struct user_struct *user, struct file *fp) - /* Paired with READ_ONCE() in wait_for_unix_gc() */ - WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1); - } -- user->unix_inflight++; -+ WRITE_ONCE(user->unix_inflight, user->unix_inflight + 1); - spin_unlock(&unix_gc_lock); - } - -@@ -84,7 +84,7 @@ void unix_notinflight(struct user_struct *user, struct file *fp) - /* Paired with READ_ONCE() in wait_for_unix_gc() */ - WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1); - } -- user->unix_inflight--; -+ WRITE_ONCE(user->unix_inflight, user->unix_inflight - 1); - spin_unlock(&unix_gc_lock); - } - -@@ -98,7 +98,7 @@ static inline bool too_many_unix_fds(struct task_struct *p) - { - struct user_struct *user = current_user(); - -- if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE))) -+ if (unlikely(READ_ONCE(user->unix_inflight) > task_rlimit(p, RLIMIT_NOFILE))) - return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN); - return false; - } -diff --git a/net/xdp/xsk_diag.c b/net/xdp/xsk_diag.c -index c014217f5fa7d..22b36c8143cfd 100644 ---- a/net/xdp/xsk_diag.c -+++ b/net/xdp/xsk_diag.c -@@ -111,6 +111,9 @@ static int xsk_diag_fill(struct sock *sk, struct sk_buff *nlskb, - sock_diag_save_cookie(sk, msg->xdiag_cookie); - - mutex_lock(&xs->mutex); -+ if (READ_ONCE(xs->state) == XSK_UNBOUND) -+ goto out_nlmsg_trim; -+ - if ((req->xdiag_show & XDP_SHOW_INFO) && xsk_diag_put_info(xs, nlskb)) - goto out_nlmsg_trim; - -diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c -index 748da578b418c..d1f5bcff4b62d 100644 ---- a/scripts/kconfig/preprocess.c -+++ b/scripts/kconfig/preprocess.c -@@ -396,6 +396,9 @@ static char *eval_clause(const char *str, size_t len, int argc, char *argv[]) - - p++; - } -+ -+ if (new_argc >= FUNCTION_MAX_ARGS) -+ pperror("too many function arguments"); - new_argv[new_argc++] = prev; - - /* -diff --git a/scripts/package/mkspec b/scripts/package/mkspec -index 70392fd2fd29c..f892cf8e37f03 100755 ---- a/scripts/package/mkspec -+++ b/scripts/package/mkspec -@@ -51,7 +51,7 @@ $S Source: kernel-$__KERNELRELEASE.tar.gz - Provides: $PROVIDES - # $UTS_MACHINE as a fallback of _arch in case - # /usr/lib/rpm/platform/*/macros was not included. -- %define _arch %{?_arch:$UTS_MACHINE} -+ %{!?_arch: %define _arch $UTS_MACHINE} - %define __spec_install_post /usr/lib/rpm/brp-compress || : - %define debug_package %{nil} - -diff --git a/sound/soc/tegra/tegra210_sfc.c b/sound/soc/tegra/tegra210_sfc.c -index 368f077e7bee7..5d2125aa61229 100644 ---- a/sound/soc/tegra/tegra210_sfc.c -+++ b/sound/soc/tegra/tegra210_sfc.c -@@ -2,7 +2,7 @@ - // - // tegra210_sfc.c - Tegra210 SFC driver - // --// Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved. -+// Copyright (c) 2021-2023 NVIDIA CORPORATION. All rights reserved. - - #include - #include -@@ -42,6 +42,7 @@ static const int tegra210_sfc_rates[TEGRA210_SFC_NUM_RATES] = { - 32000, - 44100, - 48000, -+ 64000, - 88200, - 96000, - 176400, -@@ -2857,6 +2858,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_8to32, - coef_8to44, - coef_8to48, -+ UNSUPP_CONV, - coef_8to88, - coef_8to96, - UNSUPP_CONV, -@@ -2872,6 +2874,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_11to32, - coef_11to44, - coef_11to48, -+ UNSUPP_CONV, - coef_11to88, - coef_11to96, - UNSUPP_CONV, -@@ -2887,6 +2890,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_16to32, - coef_16to44, - coef_16to48, -+ UNSUPP_CONV, - coef_16to88, - coef_16to96, - coef_16to176, -@@ -2902,6 +2906,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_22to32, - coef_22to44, - coef_22to48, -+ UNSUPP_CONV, - coef_22to88, - coef_22to96, - coef_22to176, -@@ -2917,6 +2922,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_24to32, - coef_24to44, - coef_24to48, -+ UNSUPP_CONV, - coef_24to88, - coef_24to96, - coef_24to176, -@@ -2932,6 +2938,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - BYPASS_CONV, - coef_32to44, - coef_32to48, -+ UNSUPP_CONV, - coef_32to88, - coef_32to96, - coef_32to176, -@@ -2947,6 +2954,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_44to32, - BYPASS_CONV, - coef_44to48, -+ UNSUPP_CONV, - coef_44to88, - coef_44to96, - coef_44to176, -@@ -2962,11 +2970,28 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_48to32, - coef_48to44, - BYPASS_CONV, -+ UNSUPP_CONV, - coef_48to88, - coef_48to96, - coef_48to176, - coef_48to192, - }, -+ /* Convertions from 64 kHz */ -+ { -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ UNSUPP_CONV, -+ }, - /* Convertions from 88.2 kHz */ - { - coef_88to8, -@@ -2977,6 +3002,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_88to32, - coef_88to44, - coef_88to48, -+ UNSUPP_CONV, - BYPASS_CONV, - coef_88to96, - coef_88to176, -@@ -2991,6 +3017,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_96to32, - coef_96to44, - coef_96to48, -+ UNSUPP_CONV, - coef_96to88, - BYPASS_CONV, - coef_96to176, -@@ -3006,6 +3033,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_176to32, - coef_176to44, - coef_176to48, -+ UNSUPP_CONV, - coef_176to88, - coef_176to96, - BYPASS_CONV, -@@ -3021,6 +3049,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { - coef_192to32, - coef_192to44, - coef_192to48, -+ UNSUPP_CONV, - coef_192to88, - coef_192to96, - coef_192to176, -diff --git a/sound/soc/tegra/tegra210_sfc.h b/sound/soc/tegra/tegra210_sfc.h -index 5a6b66e297d8f..a4c993d79403a 100644 ---- a/sound/soc/tegra/tegra210_sfc.h -+++ b/sound/soc/tegra/tegra210_sfc.h -@@ -2,7 +2,7 @@ - /* - * tegra210_sfc.h - Definitions for Tegra210 SFC driver - * -- * Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved. -+ * Copyright (c) 2021-2023 NVIDIA CORPORATION. All rights reserved. - * - */ - -@@ -47,7 +47,7 @@ - #define TEGRA210_SFC_EN_SHIFT 0 - #define TEGRA210_SFC_EN (1 << TEGRA210_SFC_EN_SHIFT) - --#define TEGRA210_SFC_NUM_RATES 12 -+#define TEGRA210_SFC_NUM_RATES 13 - - /* Fields in TEGRA210_SFC_COEF_RAM */ - #define TEGRA210_SFC_COEF_RAM_EN BIT(0) -diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c -index 4b3ff7687236e..f9917848cdad0 100644 ---- a/tools/perf/builtin-top.c -+++ b/tools/perf/builtin-top.c -@@ -1751,6 +1751,7 @@ int cmd_top(int argc, const char **argv) - top.session = perf_session__new(NULL, NULL); - if (IS_ERR(top.session)) { - status = PTR_ERR(top.session); -+ top.session = NULL; - goto out_delete_evlist; - } - -diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c -index 97b17f8941dc0..93dab6423a048 100644 ---- a/tools/perf/builtin-trace.c -+++ b/tools/perf/builtin-trace.c -@@ -2293,7 +2293,7 @@ static void syscall__exit(struct syscall *sc) - if (!sc) - return; - -- free(sc->arg_fmt); -+ zfree(&sc->arg_fmt); - } - - static int trace__sys_enter(struct trace *trace, struct evsel *evsel, -@@ -3124,13 +3124,8 @@ static void evlist__free_syscall_tp_fields(struct evlist *evlist) - struct evsel *evsel; - - evlist__for_each_entry(evlist, evsel) { -- struct evsel_trace *et = evsel->priv; -- -- if (!et || !evsel->tp_format || strcmp(evsel->tp_format->system, "syscalls")) -- continue; -- -- free(et->fmt); -- free(et); -+ evsel_trace__delete(evsel->priv); -+ evsel->priv = NULL; - } - } - -@@ -4765,11 +4760,11 @@ static void trace__exit(struct trace *trace) - int i; - - strlist__delete(trace->ev_qualifier); -- free(trace->ev_qualifier_ids.entries); -+ zfree(&trace->ev_qualifier_ids.entries); - if (trace->syscalls.table) { - for (i = 0; i <= trace->sctbl->syscalls.max_id; i++) - syscall__exit(&trace->syscalls.table[i]); -- free(trace->syscalls.table); -+ zfree(&trace->syscalls.table); - } - syscalltbl__delete(trace->sctbl); - zfree(&trace->perfconfig_events); -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/cache.json b/tools/perf/pmu-events/arch/powerpc/power10/cache.json -index 605be14f441c8..9cb929bb64afd 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/cache.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/cache.json -@@ -17,7 +17,7 @@ - { - "EventCode": "0x34056", - "EventName": "PM_EXEC_STALL_LOAD_FINISH", -- "BriefDescription": "Cycles in which the oldest instruction in the pipeline was finishing a load after its data was reloaded from a data source beyond the local L1; cycles in which the LSU was processing an L1-hit; cycles in which the NTF instruction merged with another load in the LMQ; cycles in which the NTF instruction is waiting for a data reload for a load miss, but the data comes back with a non-NTF instruction." -+ "BriefDescription": "Cycles in which the oldest instruction in the pipeline was finishing a load after its data was reloaded from a data source beyond the local L1; cycles in which the LSU was processing an L1-hit; cycles in which the next-to-finish (NTF) instruction merged with another load in the LMQ; cycles in which the NTF instruction is waiting for a data reload for a load miss, but the data comes back with a non-NTF instruction." - }, - { - "EventCode": "0x3006C", -@@ -27,7 +27,7 @@ - { - "EventCode": "0x300F4", - "EventName": "PM_RUN_INST_CMPL_CONC", -- "BriefDescription": "PowerPC instructions completed by this thread when all threads in the core had the run-latch set." -+ "BriefDescription": "PowerPC instruction completed by this thread when all threads in the core had the run-latch set." - }, - { - "EventCode": "0x4C016", -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/floating_point.json b/tools/perf/pmu-events/arch/powerpc/power10/floating_point.json -deleted file mode 100644 -index 54acb55e2c8c6..0000000000000 ---- a/tools/perf/pmu-events/arch/powerpc/power10/floating_point.json -+++ /dev/null -@@ -1,7 +0,0 @@ --[ -- { -- "EventCode": "0x4016E", -- "EventName": "PM_THRESH_NOT_MET", -- "BriefDescription": "Threshold counter did not meet threshold." -- } --] -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/frontend.json b/tools/perf/pmu-events/arch/powerpc/power10/frontend.json -index 558f9530f54ec..61e9e0222c873 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/frontend.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/frontend.json -@@ -7,7 +7,7 @@ - { - "EventCode": "0x10006", - "EventName": "PM_DISP_STALL_HELD_OTHER_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch for any other reason." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch for any other reason." - }, - { - "EventCode": "0x10010", -@@ -32,12 +32,12 @@ - { - "EventCode": "0x1D05E", - "EventName": "PM_DISP_STALL_HELD_HALT_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because of power management." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because of power management." - }, - { - "EventCode": "0x1E050", - "EventName": "PM_DISP_STALL_HELD_STF_MAPPER_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because the STF mapper/SRB was full. Includes GPR (count, link, tar), VSR, VMR, FPR." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because the STF mapper/SRB was full. Includes GPR (count, link, tar), VSR, VMR, FPR." - }, - { - "EventCode": "0x1F054", -@@ -67,7 +67,7 @@ - { - "EventCode": "0x100F6", - "EventName": "PM_IERAT_MISS", -- "BriefDescription": "IERAT Reloaded to satisfy an IERAT miss. All page sizes are counted by this event." -+ "BriefDescription": "IERAT Reloaded to satisfy an IERAT miss. All page sizes are counted by this event. This event only counts instruction demand access." - }, - { - "EventCode": "0x100F8", -@@ -77,7 +77,7 @@ - { - "EventCode": "0x20006", - "EventName": "PM_DISP_STALL_HELD_ISSQ_FULL_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch due to Issue queue full. Includes issue queue and branch queue." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch due to Issue queue full. Includes issue queue and branch queue." - }, - { - "EventCode": "0x20114", -@@ -102,7 +102,7 @@ - { - "EventCode": "0x2D01A", - "EventName": "PM_DISP_STALL_IC_MISS", -- "BriefDescription": "Cycles when dispatch was stalled for this thread due to an Icache Miss." -+ "BriefDescription": "Cycles when dispatch was stalled for this thread due to an instruction cache miss." - }, - { - "EventCode": "0x2E018", -@@ -112,7 +112,7 @@ - { - "EventCode": "0x2E01A", - "EventName": "PM_DISP_STALL_HELD_XVFC_MAPPER_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because the XVFC mapper/SRB was full." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because the XVFC mapper/SRB was full." - }, - { - "EventCode": "0x2C142", -@@ -137,7 +137,7 @@ - { - "EventCode": "0x30004", - "EventName": "PM_DISP_STALL_FLUSH", -- "BriefDescription": "Cycles when dispatch was stalled because of a flush that happened to an instruction(s) that was not yet NTC. PM_EXEC_STALL_NTC_FLUSH only includes instructions that were flushed after becoming NTC." -+ "BriefDescription": "Cycles when dispatch was stalled because of a flush that happened to an instruction(s) that was not yet next-to-complete (NTC). PM_EXEC_STALL_NTC_FLUSH only includes instructions that were flushed after becoming NTC." - }, - { - "EventCode": "0x3000A", -@@ -157,7 +157,7 @@ - { - "EventCode": "0x30018", - "EventName": "PM_DISP_STALL_HELD_SCOREBOARD_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch while waiting on the Scoreboard. This event combines VSCR and FPSCR together." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch while waiting on the Scoreboard. This event combines VSCR and FPSCR together." - }, - { - "EventCode": "0x30026", -@@ -182,7 +182,7 @@ - { - "EventCode": "0x3D05C", - "EventName": "PM_DISP_STALL_HELD_RENAME_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because the mapper/SRB was full. Includes GPR (count, link, tar), VSR, VMR, FPR and XVFC." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because the mapper/SRB was full. Includes GPR (count, link, tar), VSR, VMR, FPR and XVFC." - }, - { - "EventCode": "0x3E052", -@@ -192,7 +192,7 @@ - { - "EventCode": "0x3E054", - "EventName": "PM_LD_MISS_L1", -- "BriefDescription": "Load Missed L1, counted at execution time (can be greater than loads finished). LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load." -+ "BriefDescription": "Load missed L1, counted at finish time. LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load." - }, - { - "EventCode": "0x301EA", -@@ -202,7 +202,7 @@ - { - "EventCode": "0x300FA", - "EventName": "PM_INST_FROM_L3MISS", -- "BriefDescription": "The processor's instruction cache was reloaded from a source other than the local core's L1, L2, or L3 due to a demand miss." -+ "BriefDescription": "The processor's instruction cache was reloaded from beyond the local core's L3 due to a demand miss." - }, - { - "EventCode": "0x40006", -@@ -232,16 +232,16 @@ - { - "EventCode": "0x4E01A", - "EventName": "PM_DISP_STALL_HELD_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch for any reason." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch for any reason." - }, - { - "EventCode": "0x4003C", - "EventName": "PM_DISP_STALL_HELD_SYNC_CYC", -- "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because of a synchronizing instruction that requires the ICT to be empty before dispatch." -+ "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because of a synchronizing instruction that requires the ICT to be empty before dispatch." - }, - { - "EventCode": "0x44056", - "EventName": "PM_VECTOR_ST_CMPL", -- "BriefDescription": "Vector store instructions completed." -+ "BriefDescription": "Vector store instruction completed." - } - ] -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/marked.json b/tools/perf/pmu-events/arch/powerpc/power10/marked.json -index 58b5dfe3a2731..f2436fc5537ce 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/marked.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/marked.json -@@ -19,11 +19,6 @@ - "EventName": "PM_MRK_BR_TAKEN_CMPL", - "BriefDescription": "Marked Branch Taken instruction completed." - }, -- { -- "EventCode": "0x20112", -- "EventName": "PM_MRK_NTF_FIN", -- "BriefDescription": "The marked instruction became the oldest in the pipeline before it finished. It excludes instructions that finish at dispatch." -- }, - { - "EventCode": "0x2C01C", - "EventName": "PM_EXEC_STALL_DMISS_OFF_CHIP", -@@ -62,17 +57,12 @@ - { - "EventCode": "0x200FD", - "EventName": "PM_L1_ICACHE_MISS", -- "BriefDescription": "Demand iCache Miss." -- }, -- { -- "EventCode": "0x30130", -- "EventName": "PM_MRK_INST_FIN", -- "BriefDescription": "marked instruction finished. Excludes instructions that finish at dispatch. Note that stores always finish twice since the address gets issued to the LSU and the data gets issued to the VSU." -+ "BriefDescription": "Demand instruction cache miss." - }, - { - "EventCode": "0x34146", - "EventName": "PM_MRK_LD_CMPL", -- "BriefDescription": "Marked loads completed." -+ "BriefDescription": "Marked load instruction completed." - }, - { - "EventCode": "0x3E158", -@@ -82,12 +72,12 @@ - { - "EventCode": "0x3E15A", - "EventName": "PM_MRK_ST_FIN", -- "BriefDescription": "The marked instruction was a store of any kind." -+ "BriefDescription": "Marked store instruction finished." - }, - { - "EventCode": "0x30068", - "EventName": "PM_L1_ICACHE_RELOADED_PREF", -- "BriefDescription": "Counts all Icache prefetch reloads ( includes demand turned into prefetch)." -+ "BriefDescription": "Counts all instruction cache prefetch reloads (includes demand turned into prefetch)." - }, - { - "EventCode": "0x301E4", -@@ -102,12 +92,12 @@ - { - "EventCode": "0x300FE", - "EventName": "PM_DATA_FROM_L3MISS", -- "BriefDescription": "The processor's data cache was reloaded from a source other than the local core's L1, L2, or L3 due to a demand miss." -+ "BriefDescription": "The processor's L1 data cache was reloaded from beyond the local core's L3 due to a demand miss." - }, - { - "EventCode": "0x40012", - "EventName": "PM_L1_ICACHE_RELOADED_ALL", -- "BriefDescription": "Counts all Icache reloads includes demand, prefetch, prefetch turned into demand and demand turned into prefetch." -+ "BriefDescription": "Counts all instruction cache reloads includes demand, prefetch, prefetch turned into demand and demand turned into prefetch." - }, - { - "EventCode": "0x40134", -@@ -117,22 +107,22 @@ - { - "EventCode": "0x4505A", - "EventName": "PM_SP_FLOP_CMPL", -- "BriefDescription": "Single Precision floating point instructions completed." -+ "BriefDescription": "Single Precision floating point instruction completed." - }, - { - "EventCode": "0x4D058", - "EventName": "PM_VECTOR_FLOP_CMPL", -- "BriefDescription": "Vector floating point instructions completed." -+ "BriefDescription": "Vector floating point instruction completed." - }, - { - "EventCode": "0x4D05A", - "EventName": "PM_NON_MATH_FLOP_CMPL", -- "BriefDescription": "Non Math instructions completed." -+ "BriefDescription": "Non Math instruction completed." - }, - { - "EventCode": "0x401E0", - "EventName": "PM_MRK_INST_CMPL", -- "BriefDescription": "marked instruction completed." -+ "BriefDescription": "Marked instruction completed." - }, - { - "EventCode": "0x400FE", -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/memory.json b/tools/perf/pmu-events/arch/powerpc/power10/memory.json -index 843b51f531e95..c4c10ca98cad7 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/memory.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/memory.json -@@ -47,7 +47,7 @@ - { - "EventCode": "0x10062", - "EventName": "PM_LD_L3MISS_PEND_CYC", -- "BriefDescription": "Cycles L3 miss was pending for this thread." -+ "BriefDescription": "Cycles in which an L3 miss was pending for this thread." - }, - { - "EventCode": "0x20010", -@@ -132,7 +132,7 @@ - { - "EventCode": "0x300FC", - "EventName": "PM_DTLB_MISS", -- "BriefDescription": "The DPTEG required for the load/store instruction in execution was missing from the TLB. It includes pages of all sizes for demand and prefetch activity." -+ "BriefDescription": "The DPTEG required for the load/store instruction in execution was missing from the TLB. This event only counts for demand misses." - }, - { - "EventCode": "0x4D02C", -@@ -142,7 +142,7 @@ - { - "EventCode": "0x4003E", - "EventName": "PM_LD_CMPL", -- "BriefDescription": "Loads completed." -+ "BriefDescription": "Load instruction completed." - }, - { - "EventCode": "0x4C040", -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/metrics.json b/tools/perf/pmu-events/arch/powerpc/power10/metrics.json -index b57526fa44f2d..6e76f65c314ce 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/metrics.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/metrics.json -@@ -453,12 +453,6 @@ - "MetricGroup": "General", - "MetricName": "LOADS_PER_INST" - }, -- { -- "BriefDescription": "Average number of finished stores per completed instruction", -- "MetricExpr": "PM_ST_FIN / PM_RUN_INST_CMPL", -- "MetricGroup": "General", -- "MetricName": "STORES_PER_INST" -- }, - { - "BriefDescription": "Percentage of demand loads that reloaded from beyond the L2 per completed instruction", - "MetricExpr": "PM_DATA_FROM_L2MISS / PM_RUN_INST_CMPL * 100", -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/others.json b/tools/perf/pmu-events/arch/powerpc/power10/others.json -index 7d0de1a2860b4..36c5bbc64c3be 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/others.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/others.json -@@ -2,12 +2,12 @@ - { - "EventCode": "0x10016", - "EventName": "PM_VSU0_ISSUE", -- "BriefDescription": "VSU instructions issued to VSU pipe 0." -+ "BriefDescription": "VSU instruction issued to VSU pipe 0." - }, - { - "EventCode": "0x1001C", - "EventName": "PM_ULTRAVISOR_INST_CMPL", -- "BriefDescription": "PowerPC instructions that completed while the thread was in ultravisor state." -+ "BriefDescription": "PowerPC instruction completed while the thread was in ultravisor state." - }, - { - "EventCode": "0x100F0", -@@ -17,23 +17,18 @@ - { - "EventCode": "0x10134", - "EventName": "PM_MRK_ST_DONE_L2", -- "BriefDescription": "Marked stores completed in L2 (RC machine done)." -+ "BriefDescription": "Marked store completed in L2." - }, - { - "EventCode": "0x1505E", - "EventName": "PM_LD_HIT_L1", -- "BriefDescription": "Loads that finished without experiencing an L1 miss." -+ "BriefDescription": "Load finished without experiencing an L1 miss." - }, - { - "EventCode": "0x1F056", - "EventName": "PM_DISP_SS0_2_INSTR_CYC", - "BriefDescription": "Cycles in which Superslice 0 dispatches either 1 or 2 instructions." - }, -- { -- "EventCode": "0x1F15C", -- "EventName": "PM_MRK_STCX_L2_CYC", -- "BriefDescription": "Cycles spent in the nest portion of a marked Stcx instruction. It starts counting when the operation starts to drain to the L2 and it stops counting when the instruction retires from the Instruction Completion Table (ICT) in the Instruction Sequencing Unit (ISU)." -- }, - { - "EventCode": "0x10066", - "EventName": "PM_ADJUNCT_CYC", -@@ -42,7 +37,7 @@ - { - "EventCode": "0x101E4", - "EventName": "PM_MRK_L1_ICACHE_MISS", -- "BriefDescription": "Marked Instruction suffered an icache Miss." -+ "BriefDescription": "Marked instruction suffered an instruction cache miss." - }, - { - "EventCode": "0x101EA", -@@ -72,7 +67,7 @@ - { - "EventCode": "0x2E010", - "EventName": "PM_ADJUNCT_INST_CMPL", -- "BriefDescription": "PowerPC instructions that completed while the thread is in Adjunct state." -+ "BriefDescription": "PowerPC instruction completed while the thread was in Adjunct state." - }, - { - "EventCode": "0x2E014", -@@ -122,7 +117,7 @@ - { - "EventCode": "0x201E4", - "EventName": "PM_MRK_DATA_FROM_L3MISS", -- "BriefDescription": "The processor's data cache was reloaded from a source other than the local core's L1, L2, or L3 due to a demand miss for a marked load." -+ "BriefDescription": "The processor's L1 data cache was reloaded from beyond the local core's L3 due to a demand miss for a marked instruction." - }, - { - "EventCode": "0x201E8", -@@ -132,17 +127,17 @@ - { - "EventCode": "0x200F2", - "EventName": "PM_INST_DISP", -- "BriefDescription": "PowerPC instructions dispatched." -+ "BriefDescription": "PowerPC instruction dispatched." - }, - { - "EventCode": "0x30132", - "EventName": "PM_MRK_VSU_FIN", -- "BriefDescription": "VSU marked instructions finished. Excludes simple FX instructions issued to the Store Unit." -+ "BriefDescription": "VSU marked instruction finished. Excludes simple FX instructions issued to the Store Unit." - }, - { - "EventCode": "0x30038", - "EventName": "PM_EXEC_STALL_DMISS_LMEM", -- "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from the local memory, local OpenCapp cache, or local OpenCapp memory." -+ "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from the local memory, local OpenCAPI cache, or local OpenCAPI memory." - }, - { - "EventCode": "0x3F04A", -@@ -152,12 +147,12 @@ - { - "EventCode": "0x3405A", - "EventName": "PM_PRIVILEGED_INST_CMPL", -- "BriefDescription": "PowerPC Instructions that completed while the thread is in Privileged state." -+ "BriefDescription": "PowerPC instruction completed while the thread was in Privileged state." - }, - { - "EventCode": "0x3F150", - "EventName": "PM_MRK_ST_DRAIN_CYC", -- "BriefDescription": "cycles to drain st from core to L2." -+ "BriefDescription": "Cycles in which the marked store drained from the core to the L2." - }, - { - "EventCode": "0x3F054", -@@ -182,7 +177,7 @@ - { - "EventCode": "0x4001C", - "EventName": "PM_VSU_FIN", -- "BriefDescription": "VSU instructions finished." -+ "BriefDescription": "VSU instruction finished." - }, - { - "EventCode": "0x4C01A", -@@ -197,7 +192,7 @@ - { - "EventCode": "0x4D022", - "EventName": "PM_HYPERVISOR_INST_CMPL", -- "BriefDescription": "PowerPC instructions that completed while the thread is in hypervisor state." -+ "BriefDescription": "PowerPC instruction completed while the thread was in hypervisor state." - }, - { - "EventCode": "0x4D026", -@@ -212,32 +207,32 @@ - { - "EventCode": "0x40030", - "EventName": "PM_INST_FIN", -- "BriefDescription": "Instructions finished." -+ "BriefDescription": "Instruction finished." - }, - { - "EventCode": "0x44146", - "EventName": "PM_MRK_STCX_CORE_CYC", -- "BriefDescription": "Cycles spent in the core portion of a marked Stcx instruction. It starts counting when the instruction is decoded and stops counting when it drains into the L2." -+ "BriefDescription": "Cycles spent in the core portion of a marked STCX instruction. It starts counting when the instruction is decoded and stops counting when it drains into the L2." - }, - { - "EventCode": "0x44054", - "EventName": "PM_VECTOR_LD_CMPL", -- "BriefDescription": "Vector load instructions completed." -+ "BriefDescription": "Vector load instruction completed." - }, - { - "EventCode": "0x45054", - "EventName": "PM_FMA_CMPL", -- "BriefDescription": "Two floating point instructions completed (FMA class of instructions: fmadd, fnmadd, fmsub, fnmsub). Scalar instructions only." -+ "BriefDescription": "Two floating point instruction completed (FMA class of instructions: fmadd, fnmadd, fmsub, fnmsub). Scalar instructions only." - }, - { - "EventCode": "0x45056", - "EventName": "PM_SCALAR_FLOP_CMPL", -- "BriefDescription": "Scalar floating point instructions completed." -+ "BriefDescription": "Scalar floating point instruction completed." - }, - { - "EventCode": "0x4505C", - "EventName": "PM_MATH_FLOP_CMPL", -- "BriefDescription": "Math floating point instructions completed." -+ "BriefDescription": "Math floating point instruction completed." - }, - { - "EventCode": "0x4D05E", -@@ -252,21 +247,21 @@ - { - "EventCode": "0x401E6", - "EventName": "PM_MRK_INST_FROM_L3MISS", -- "BriefDescription": "The processor's instruction cache was reloaded from a source other than the local core's L1, L2, or L3 due to a demand miss for a marked instruction." -+ "BriefDescription": "The processor's instruction cache was reloaded from beyond the local core's L3 due to a demand miss for a marked instruction." - }, - { - "EventCode": "0x401E8", - "EventName": "PM_MRK_DATA_FROM_L2MISS", -- "BriefDescription": "The processor's data cache was reloaded from a source other than the local core's L1 or L2 due to a demand miss for a marked load." -+ "BriefDescription": "The processor's L1 data cache was reloaded from a source beyond the local core's L2 due to a demand miss for a marked instruction." - }, - { - "EventCode": "0x400F0", - "EventName": "PM_LD_DEMAND_MISS_L1_FIN", -- "BriefDescription": "Load Missed L1, counted at finish time." -+ "BriefDescription": "Load missed L1, counted at finish time." - }, - { - "EventCode": "0x400FA", - "EventName": "PM_RUN_INST_CMPL", -- "BriefDescription": "Completed PowerPC instructions gated by the run latch." -+ "BriefDescription": "PowerPC instruction completed while the run latch is set." - } - ] -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/pipeline.json b/tools/perf/pmu-events/arch/powerpc/power10/pipeline.json -index b8aded6045faa..799893c56f32b 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/pipeline.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/pipeline.json -@@ -2,7 +2,7 @@ - { - "EventCode": "0x100FE", - "EventName": "PM_INST_CMPL", -- "BriefDescription": "PowerPC instructions completed." -+ "BriefDescription": "PowerPC instruction completed." - }, - { - "EventCode": "0x1000C", -@@ -12,7 +12,7 @@ - { - "EventCode": "0x1000E", - "EventName": "PM_MMA_ISSUED", -- "BriefDescription": "MMA instructions issued." -+ "BriefDescription": "MMA instruction issued." - }, - { - "EventCode": "0x10012", -@@ -107,7 +107,7 @@ - { - "EventCode": "0x2D012", - "EventName": "PM_VSU1_ISSUE", -- "BriefDescription": "VSU instructions issued to VSU pipe 1." -+ "BriefDescription": "VSU instruction issued to VSU pipe 1." - }, - { - "EventCode": "0x2D018", -@@ -122,7 +122,7 @@ - { - "EventCode": "0x2E01E", - "EventName": "PM_EXEC_STALL_NTC_FLUSH", -- "BriefDescription": "Cycles in which the oldest instruction in the pipeline was executing in any unit before it was flushed. Note that if the flush of the oldest instruction happens after finish, the cycles from dispatch to issue will be included in PM_DISP_STALL and the cycles from issue to finish will be included in PM_EXEC_STALL and its corresponding children. This event will also count cycles when the previous NTF instruction is still completing and the new NTF instruction is stalled at dispatch." -+ "BriefDescription": "Cycles in which the oldest instruction in the pipeline was executing in any unit before it was flushed. Note that if the flush of the oldest instruction happens after finish, the cycles from dispatch to issue will be included in PM_DISP_STALL and the cycles from issue to finish will be included in PM_EXEC_STALL and its corresponding children. This event will also count cycles when the previous next-to-finish (NTF) instruction is still completing and the new NTF instruction is stalled at dispatch." - }, - { - "EventCode": "0x2013C", -@@ -137,7 +137,7 @@ - { - "EventCode": "0x201E2", - "EventName": "PM_MRK_LD_MISS_L1", -- "BriefDescription": "Marked DL1 Demand Miss counted at finish time." -+ "BriefDescription": "Marked demand data load miss counted at finish time." - }, - { - "EventCode": "0x200F4", -@@ -172,7 +172,7 @@ - { - "EventCode": "0x30028", - "EventName": "PM_CMPL_STALL_MEM_ECC", -- "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for the non-speculative finish of either a stcx waiting for its result or a load waiting for non-critical sectors of data and ECC." -+ "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for the non-speculative finish of either a STCX waiting for its result or a load waiting for non-critical sectors of data and ECC." - }, - { - "EventCode": "0x30036", -@@ -187,17 +187,12 @@ - { - "EventCode": "0x3F044", - "EventName": "PM_VSU2_ISSUE", -- "BriefDescription": "VSU instructions issued to VSU pipe 2." -+ "BriefDescription": "VSU instruction issued to VSU pipe 2." - }, - { - "EventCode": "0x30058", - "EventName": "PM_TLBIE_FIN", -- "BriefDescription": "TLBIE instructions finished in the LSU. Two TLBIEs can finish each cycle. All will be counted." -- }, -- { -- "EventCode": "0x3D058", -- "EventName": "PM_SCALAR_FSQRT_FDIV_ISSUE", -- "BriefDescription": "Scalar versions of four floating point operations: fdiv,fsqrt (xvdivdp, xvdivsp, xvsqrtdp, xvsqrtsp)." -+ "BriefDescription": "TLBIE instruction finished in the LSU. Two TLBIEs can finish each cycle. All will be counted." - }, - { - "EventCode": "0x30066", -@@ -252,7 +247,7 @@ - { - "EventCode": "0x4E012", - "EventName": "PM_EXEC_STALL_UNKNOWN", -- "BriefDescription": "Cycles in which the oldest instruction in the pipeline completed without an ntf_type pulse. The ntf_pulse was missed by the ISU because the NTF finishes and completions came too close together." -+ "BriefDescription": "Cycles in which the oldest instruction in the pipeline completed without an ntf_type pulse. The ntf_pulse was missed by the ISU because the next-to-finish (NTF) instruction finishes and completions came too close together." - }, - { - "EventCode": "0x4D020", -@@ -267,12 +262,7 @@ - { - "EventCode": "0x45058", - "EventName": "PM_IC_MISS_CMPL", -- "BriefDescription": "Non-speculative icache miss, counted at completion." -- }, -- { -- "EventCode": "0x4D050", -- "EventName": "PM_VSU_NON_FLOP_CMPL", -- "BriefDescription": "Non-floating point VSU instructions completed." -+ "BriefDescription": "Non-speculative instruction cache miss, counted at completion." - }, - { - "EventCode": "0x4D052", -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/pmc.json b/tools/perf/pmu-events/arch/powerpc/power10/pmc.json -index b5d1bd39cfb22..364fedbfb490b 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/pmc.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/pmc.json -@@ -12,11 +12,11 @@ - { - "EventCode": "0x45052", - "EventName": "PM_4FLOP_CMPL", -- "BriefDescription": "Four floating point instructions completed (fadd, fmul, fsub, fcmp, fsel, fabs, fnabs, fres, fsqrte, fneg)." -+ "BriefDescription": "Four floating point instruction completed (fadd, fmul, fsub, fcmp, fsel, fabs, fnabs, fres, fsqrte, fneg)." - }, - { - "EventCode": "0x4D054", - "EventName": "PM_8FLOP_CMPL", -- "BriefDescription": "Four Double Precision vector instructions completed." -+ "BriefDescription": "Four Double Precision vector instruction completed." - } - ] -diff --git a/tools/perf/pmu-events/arch/powerpc/power10/translation.json b/tools/perf/pmu-events/arch/powerpc/power10/translation.json -index db3766dca07c5..961e2491e73f6 100644 ---- a/tools/perf/pmu-events/arch/powerpc/power10/translation.json -+++ b/tools/perf/pmu-events/arch/powerpc/power10/translation.json -@@ -4,11 +4,6 @@ - "EventName": "PM_MRK_START_PROBE_NOP_CMPL", - "BriefDescription": "Marked Start probe nop (AND R0,R0,R0) completed." - }, -- { -- "EventCode": "0x20016", -- "EventName": "PM_ST_FIN", -- "BriefDescription": "Store finish count. Includes speculative activity." -- }, - { - "EventCode": "0x20018", - "EventName": "PM_ST_FWD", -@@ -17,7 +12,7 @@ - { - "EventCode": "0x2011C", - "EventName": "PM_MRK_NTF_CYC", -- "BriefDescription": "Cycles during which the marked instruction is the oldest in the pipeline (NTF or NTC)." -+ "BriefDescription": "Cycles in which the marked instruction is the oldest in the pipeline (next-to-finish or next-to-complete)." - }, - { - "EventCode": "0x2E01C", -@@ -37,7 +32,7 @@ - { - "EventCode": "0x200FE", - "EventName": "PM_DATA_FROM_L2MISS", -- "BriefDescription": "The processor's data cache was reloaded from a source other than the local core's L1 or L2 due to a demand miss." -+ "BriefDescription": "The processor's L1 data cache was reloaded from a source beyond the local core's L2 due to a demand miss." - }, - { - "EventCode": "0x30010", -@@ -52,6 +47,6 @@ - { - "EventCode": "0x4D05C", - "EventName": "PM_DPP_FLOP_CMPL", -- "BriefDescription": "Double-Precision or Quad-Precision instructions completed." -+ "BriefDescription": "Double-Precision or Quad-Precision instruction completed." - } - ] -diff --git a/tools/perf/tests/shell/stat_bpf_counters.sh b/tools/perf/tests/shell/stat_bpf_counters.sh -index 13473aeba489c..6bf24b85294c7 100755 ---- a/tools/perf/tests/shell/stat_bpf_counters.sh -+++ b/tools/perf/tests/shell/stat_bpf_counters.sh -@@ -22,10 +22,10 @@ compare_number() - } - - # skip if --bpf-counters is not supported --if ! perf stat --bpf-counters true > /dev/null 2>&1; then -+if ! perf stat -e cycles --bpf-counters true > /dev/null 2>&1; then - if [ "$1" = "-v" ]; then - echo "Skipping: --bpf-counters not supported" -- perf --no-pager stat --bpf-counters true || true -+ perf --no-pager stat -e cycles --bpf-counters true || true - fi - exit 2 - fi -diff --git a/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh b/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh -index d724855d097c2..e75d0780dc788 100755 ---- a/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh -+++ b/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh -@@ -25,22 +25,22 @@ check_bpf_counter() - find_cgroups() - { - # try usual systemd slices first -- if [ -d /sys/fs/cgroup/system.slice -a -d /sys/fs/cgroup/user.slice ]; then -+ if [ -d /sys/fs/cgroup/system.slice ] && [ -d /sys/fs/cgroup/user.slice ]; then - test_cgroups="system.slice,user.slice" - return - fi - - # try root and self cgroups -- local self_cgrp=$(grep perf_event /proc/self/cgroup | cut -d: -f3) -- if [ -z ${self_cgrp} ]; then -+ find_cgroups_self_cgrp=$(grep perf_event /proc/self/cgroup | cut -d: -f3) -+ if [ -z ${find_cgroups_self_cgrp} ]; then - # cgroup v2 doesn't specify perf_event -- self_cgrp=$(grep ^0: /proc/self/cgroup | cut -d: -f3) -+ find_cgroups_self_cgrp=$(grep ^0: /proc/self/cgroup | cut -d: -f3) - fi - -- if [ -z ${self_cgrp} ]; then -+ if [ -z ${find_cgroups_self_cgrp} ]; then - test_cgroups="/" - else -- test_cgroups="/,${self_cgrp}" -+ test_cgroups="/,${find_cgroups_self_cgrp}" - fi - } - -@@ -48,13 +48,11 @@ find_cgroups() - # Just check if it runs without failure and has non-zero results. - check_system_wide_counted() - { -- local output -- -- output=$(perf stat -a --bpf-counters --for-each-cgroup ${test_cgroups} -e cpu-clock -x, sleep 1 2>&1) -- if echo ${output} | grep -q -F "&1) -+ if echo ${check_system_wide_counted_output} | grep -q -F "&1) -- if echo ${output} | grep -q -F "&1) -+ if echo ${check_cpu_list_counted_output} | grep -q -F "has_children; - } - --static bool hist_browser__he_selection_unfolded(struct hist_browser *browser) --{ -- return browser->he_selection ? browser->he_selection->unfolded : false; --} -- - static bool hist_browser__selection_unfolded(struct hist_browser *browser) - { - struct hist_entry *he = browser->he_selection; -@@ -584,8 +579,8 @@ static int hierarchy_set_folding(struct hist_browser *hb, struct hist_entry *he, - return n; - } - --static void __hist_entry__set_folding(struct hist_entry *he, -- struct hist_browser *hb, bool unfold) -+static void hist_entry__set_folding(struct hist_entry *he, -+ struct hist_browser *hb, bool unfold) - { - hist_entry__init_have_children(he); - he->unfolded = unfold ? he->has_children : false; -@@ -603,34 +598,12 @@ static void __hist_entry__set_folding(struct hist_entry *he, - he->nr_rows = 0; - } - --static void hist_entry__set_folding(struct hist_entry *he, -- struct hist_browser *browser, bool unfold) --{ -- double percent; -- -- percent = hist_entry__get_percent_limit(he); -- if (he->filtered || percent < browser->min_pcnt) -- return; -- -- __hist_entry__set_folding(he, browser, unfold); -- -- if (!he->depth || unfold) -- browser->nr_hierarchy_entries++; -- if (he->leaf) -- browser->nr_callchain_rows += he->nr_rows; -- else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { -- browser->nr_hierarchy_entries++; -- he->has_no_entry = true; -- he->nr_rows = 1; -- } else -- he->has_no_entry = false; --} -- - static void - __hist_browser__set_folding(struct hist_browser *browser, bool unfold) - { - struct rb_node *nd; - struct hist_entry *he; -+ double percent; - - nd = rb_first_cached(&browser->hists->entries); - while (nd) { -@@ -640,6 +613,21 @@ __hist_browser__set_folding(struct hist_browser *browser, bool unfold) - nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD); - - hist_entry__set_folding(he, browser, unfold); -+ -+ percent = hist_entry__get_percent_limit(he); -+ if (he->filtered || percent < browser->min_pcnt) -+ continue; -+ -+ if (!he->depth || unfold) -+ browser->nr_hierarchy_entries++; -+ if (he->leaf) -+ browser->nr_callchain_rows += he->nr_rows; -+ else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { -+ browser->nr_hierarchy_entries++; -+ he->has_no_entry = true; -+ he->nr_rows = 1; -+ } else -+ he->has_no_entry = false; - } - } - -@@ -659,8 +647,10 @@ static void hist_browser__set_folding_selected(struct hist_browser *browser, boo - if (!browser->he_selection) - return; - -- hist_entry__set_folding(browser->he_selection, browser, unfold); -- browser->b.nr_entries = hist_browser__nr_entries(browser); -+ if (unfold == browser->he_selection->unfolded) -+ return; -+ -+ hist_browser__toggle_fold(browser); - } - - static void ui_browser__warn_lost_events(struct ui_browser *browser) -@@ -732,8 +722,8 @@ static int hist_browser__handle_hotkey(struct hist_browser *browser, bool warn_l - hist_browser__set_folding(browser, true); - break; - case 'e': -- /* Expand the selected entry. */ -- hist_browser__set_folding_selected(browser, !hist_browser__he_selection_unfolded(browser)); -+ /* Toggle expand/collapse the selected entry. */ -+ hist_browser__toggle_fold(browser); - break; - case 'H': - browser->show_headers = !browser->show_headers; -@@ -1779,7 +1769,7 @@ static void hists_browser__hierarchy_headers(struct hist_browser *browser) - hists_browser__scnprintf_hierarchy_headers(browser, headers, - sizeof(headers)); - -- ui_browser__gotorc(&browser->b, 0, 0); -+ ui_browser__gotorc_title(&browser->b, 0, 0); - ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); - ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); - } -diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c -index db475e44f42fa..a9122ea3b44c4 100644 ---- a/tools/perf/util/annotate.c -+++ b/tools/perf/util/annotate.c -@@ -1756,8 +1756,11 @@ static int symbol__disassemble_bpf(struct symbol *sym, - perf_exe(tpath, sizeof(tpath)); - - bfdf = bfd_openr(tpath, NULL); -- assert(bfdf); -- assert(bfd_check_format(bfdf, bfd_object)); -+ if (bfdf == NULL) -+ abort(); -+ -+ if (!bfd_check_format(bfdf, bfd_object)) -+ abort(); - - s = open_memstream(&buf, &buf_size); - if (!s) { -@@ -1805,7 +1808,8 @@ static int symbol__disassemble_bpf(struct symbol *sym, - #else - disassemble = disassembler(bfdf); - #endif -- assert(disassemble); -+ if (disassemble == NULL) -+ abort(); - - fflush(s); - do { -diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c -index 98dfaf84bd137..9e2dce70b1300 100644 ---- a/tools/perf/util/header.c -+++ b/tools/perf/util/header.c -@@ -4331,7 +4331,8 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, - union perf_event *event, - struct evlist **pevlist) - { -- u32 i, ids, n_ids; -+ u32 i, n_ids; -+ u64 *ids; - struct evsel *evsel; - struct evlist *evlist = *pevlist; - -@@ -4347,9 +4348,8 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, - - evlist__add(evlist, evsel); - -- ids = event->header.size; -- ids -= (void *)&event->attr.id - (void *)event; -- n_ids = ids / sizeof(u64); -+ n_ids = event->header.size - sizeof(event->header) - event->attr.attr.size; -+ n_ids = n_ids / sizeof(u64); - /* - * We don't have the cpu and thread maps on the header, so - * for allocating the perf_sample_id table we fake 1 cpu and -@@ -4358,8 +4358,9 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused, - if (perf_evsel__alloc_id(&evsel->core, 1, n_ids)) - return -ENOMEM; - -+ ids = (void *)&event->attr.attr + event->attr.attr.size; - for (i = 0; i < n_ids; i++) { -- perf_evlist__id_add(&evlist->core, &evsel->core, 0, i, event->attr.id[i]); -+ perf_evlist__id_add(&evlist->core, &evsel->core, 0, i, ids[i]); - } - - return 0; -diff --git a/tools/testing/selftests/kselftest/runner.sh b/tools/testing/selftests/kselftest/runner.sh -index 294619ade49fe..1333ab1eda708 100644 ---- a/tools/testing/selftests/kselftest/runner.sh -+++ b/tools/testing/selftests/kselftest/runner.sh -@@ -35,7 +35,8 @@ tap_timeout() - { - # Make sure tests will time out if utility is available. - if [ -x /usr/bin/timeout ] ; then -- /usr/bin/timeout --foreground "$kselftest_timeout" $1 -+ /usr/bin/timeout --foreground "$kselftest_timeout" \ -+ /usr/bin/timeout "$kselftest_timeout" $1 - else - $1 - fi -diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk -index 05400462c7799..aa646e0661f36 100644 ---- a/tools/testing/selftests/lib.mk -+++ b/tools/testing/selftests/lib.mk -@@ -72,7 +72,7 @@ endef - run_tests: all - ifdef building_out_of_srctree - @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ -- rsync -aLq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ -+ rsync -aq --copy-unsafe-links $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ - fi - @if [ "X$(TEST_PROGS)" != "X" ]; then \ - $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \ -@@ -86,7 +86,7 @@ endif - - define INSTALL_SINGLE_RULE - $(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH)) -- $(if $(INSTALL_LIST),rsync -aL $(INSTALL_LIST) $(INSTALL_PATH)/) -+ $(if $(INSTALL_LIST),rsync -a --copy-unsafe-links $(INSTALL_LIST) $(INSTALL_PATH)/) - endef - - define INSTALL_RULE diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.54-55.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.54-55.patch deleted file mode 100644 index b9b1e43fa94b..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.54-55.patch +++ /dev/null @@ -1,6107 +0,0 @@ -diff --git a/Documentation/admin-guide/cgroup-v1/memory.rst b/Documentation/admin-guide/cgroup-v1/memory.rst -index 34911ce5e4b50..2524061836acc 100644 ---- a/Documentation/admin-guide/cgroup-v1/memory.rst -+++ b/Documentation/admin-guide/cgroup-v1/memory.rst -@@ -91,6 +91,8 @@ Brief summary of control files. - memory.oom_control set/show oom controls. - memory.numa_stat show the number of memory usage per numa - node -+ memory.kmem.limit_in_bytes This knob is deprecated and writing to -+ it will return -ENOTSUPP. - memory.kmem.usage_in_bytes show current kernel memory allocation - memory.kmem.failcnt show the number of kernel memory usage - hits limits -diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst -index b3c8ac6a2c385..9000640f7f7a0 100644 ---- a/Documentation/arm64/silicon-errata.rst -+++ b/Documentation/arm64/silicon-errata.rst -@@ -193,6 +193,9 @@ stable kernels. - +----------------+-----------------+-----------------+-----------------------------+ - | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A | - +----------------+-----------------+-----------------+-----------------------------+ -+| Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A | -+| | Hip09 SMMU PMCG | | | -++----------------+-----------------+-----------------+-----------------------------+ - +----------------+-----------------+-----------------+-----------------------------+ - | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | - +----------------+-----------------+-----------------+-----------------------------+ -diff --git a/Makefile b/Makefile -index 844afa653fdda..3d839824a7224 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 54 -+SUBLEVEL = 55 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c -index 054e9199f30db..dc0fb7a813715 100644 ---- a/arch/arm/kernel/hw_breakpoint.c -+++ b/arch/arm/kernel/hw_breakpoint.c -@@ -626,7 +626,7 @@ int hw_breakpoint_arch_parse(struct perf_event *bp, - hw->address &= ~alignment_mask; - hw->ctrl.len <<= offset; - -- if (is_default_overflow_handler(bp)) { -+ if (uses_default_overflow_handler(bp)) { - /* - * Mismatch breakpoints are required for single-stepping - * breakpoints. -@@ -798,7 +798,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, - * Otherwise, insert a temporary mismatch breakpoint so that - * we can single-step over the watchpoint trigger. - */ -- if (!is_default_overflow_handler(wp)) -+ if (!uses_default_overflow_handler(wp)) - continue; - step: - enable_single_step(wp, instruction_pointer(regs)); -@@ -811,7 +811,7 @@ step: - info->trigger = addr; - pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); - perf_bp_event(wp, regs); -- if (is_default_overflow_handler(wp)) -+ if (uses_default_overflow_handler(wp)) - enable_single_step(wp, instruction_pointer(regs)); - } - -@@ -886,7 +886,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) - info->trigger = addr; - pr_debug("breakpoint fired: address = 0x%x\n", addr); - perf_bp_event(bp, regs); -- if (is_default_overflow_handler(bp)) -+ if (uses_default_overflow_handler(bp)) - enable_single_step(bp, addr); - goto unlock; - } -diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c -index f567032a09c0b..6d1938d1b4df7 100644 ---- a/arch/arm/kernel/machine_kexec.c -+++ b/arch/arm/kernel/machine_kexec.c -@@ -92,16 +92,28 @@ void machine_crash_nonpanic_core(void *unused) - } - } - -+static DEFINE_PER_CPU(call_single_data_t, cpu_stop_csd) = -+ CSD_INIT(machine_crash_nonpanic_core, NULL); -+ - void crash_smp_send_stop(void) - { - static int cpus_stopped; - unsigned long msecs; -+ call_single_data_t *csd; -+ int cpu, this_cpu = raw_smp_processor_id(); - - if (cpus_stopped) - return; - - atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); -- smp_call_function(machine_crash_nonpanic_core, NULL, false); -+ for_each_online_cpu(cpu) { -+ if (cpu == this_cpu) -+ continue; -+ -+ csd = &per_cpu(cpu_stop_csd, cpu); -+ smp_call_function_single_async(cpu, csd); -+ } -+ - msecs = 1000; /* Wait at most a second for the other cpus to stop */ - while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { - mdelay(1); -diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts -index e1ab5b5189949..4a77b650c0d8d 100644 ---- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts -+++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts -@@ -73,7 +73,7 @@ - reg = <0x0 0xffc40000 0x0 0xc0000>; - record-size = <0x1000>; - console-size = <0x40000>; -- msg-size = <0x20000 0x20000>; -+ pmsg-size = <0x20000>; - }; - - cmdline_mem: memory@ffd00000 { -diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi -index 34c8de4f43fba..cea7ca3f326fc 100644 ---- a/arch/arm64/boot/dts/qcom/sm6350.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi -@@ -346,7 +346,7 @@ - reg = <0 0xffc00000 0 0x100000>; - record-size = <0x1000>; - console-size = <0x40000>; -- msg-size = <0x20000 0x20000>; -+ pmsg-size = <0x20000>; - ecc-size = <16>; - no-map; - }; -diff --git a/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi -index 04c71f74ab72d..c9aa7764fc59a 100644 ---- a/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi -@@ -127,7 +127,7 @@ - reg = <0x0 0xffc00000 0x0 0x100000>; - record-size = <0x1000>; - console-size = <0x40000>; -- msg-size = <0x20000 0x20000>; -+ pmsg-size = <0x20000>; - ecc-size = <16>; - no-map; - }; -diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi -index 3b710c6a326a5..3b306dfb91e0d 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi -@@ -126,7 +126,7 @@ - reg = <0x0 0xffc00000 0x0 0x100000>; - record-size = <0x1000>; - console-size = <0x40000>; -- msg-size = <0x20000 0x20000>; -+ pmsg-size = <0x20000>; - ecc-size = <16>; - no-map; - }; -diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c -index b29a311bb0552..9659a9555c63a 100644 ---- a/arch/arm64/kernel/hw_breakpoint.c -+++ b/arch/arm64/kernel/hw_breakpoint.c -@@ -654,7 +654,7 @@ static int breakpoint_handler(unsigned long unused, unsigned long esr, - perf_bp_event(bp, regs); - - /* Do we need to handle the stepping? */ -- if (is_default_overflow_handler(bp)) -+ if (uses_default_overflow_handler(bp)) - step = 1; - unlock: - rcu_read_unlock(); -@@ -733,7 +733,7 @@ static u64 get_distance_from_watchpoint(unsigned long addr, u64 val, - static int watchpoint_report(struct perf_event *wp, unsigned long addr, - struct pt_regs *regs) - { -- int step = is_default_overflow_handler(wp); -+ int step = uses_default_overflow_handler(wp); - struct arch_hw_breakpoint *info = counter_arch_bp(wp); - - info->trigger = addr; -diff --git a/arch/mips/Makefile b/arch/mips/Makefile -index ee8f47aef98b3..dd6486097e1dc 100644 ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -352,7 +352,7 @@ KBUILD_LDFLAGS += -m $(ld-emul) - - ifdef need-compiler - CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ -- egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ -+ grep -E -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ - sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') - endif - -diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile -index f72658b3a53f7..1f7d5c6c10b08 100644 ---- a/arch/mips/vdso/Makefile -+++ b/arch/mips/vdso/Makefile -@@ -71,7 +71,7 @@ KCOV_INSTRUMENT := n - - # Check that we don't have PIC 'jalr t9' calls left - quiet_cmd_vdso_mips_check = VDSOCHK $@ -- cmd_vdso_mips_check = if $(OBJDUMP) --disassemble $@ | egrep -h "jalr.*t9" > /dev/null; \ -+ cmd_vdso_mips_check = if $(OBJDUMP) --disassemble $@ | grep -E -h "jalr.*t9" > /dev/null; \ - then (echo >&2 "$@: PIC 'jalr t9' calls are not supported"; \ - rm -f $@; /bin/false); fi - -diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c -index a870cada7acd2..ed5fc70b7353a 100644 ---- a/arch/powerpc/platforms/pseries/ibmebus.c -+++ b/arch/powerpc/platforms/pseries/ibmebus.c -@@ -455,6 +455,7 @@ static int __init ibmebus_bus_init(void) - if (err) { - printk(KERN_WARNING "%s: device_register returned %i\n", - __func__, err); -+ put_device(&ibmebus_bus_device); - bus_unregister(&ibmebus_bus_type); - - return err; -diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c -index c08bb5c3b3857..b3b96ff46d193 100644 ---- a/arch/riscv/kernel/elf_kexec.c -+++ b/arch/riscv/kernel/elf_kexec.c -@@ -98,7 +98,13 @@ static int elf_find_pbase(struct kimage *image, unsigned long kernel_len, - kbuf.image = image; - kbuf.buf_min = lowest_paddr; - kbuf.buf_max = ULONG_MAX; -- kbuf.buf_align = PAGE_SIZE; -+ -+ /* -+ * Current riscv boot protocol requires 2MB alignment for -+ * RV64 and 4MB alignment for RV32 -+ * -+ */ -+ kbuf.buf_align = PMD_SIZE; - kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; - kbuf.memsz = ALIGN(kernel_len, PAGE_SIZE); - kbuf.top_down = false; -diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c -index 321a5011042d4..b4155273df891 100644 ---- a/arch/x86/boot/compressed/ident_map_64.c -+++ b/arch/x86/boot/compressed/ident_map_64.c -@@ -67,6 +67,14 @@ static void *alloc_pgt_page(void *context) - return NULL; - } - -+ /* Consumed more tables than expected? */ -+ if (pages->pgt_buf_offset == BOOT_PGT_SIZE_WARN) { -+ debug_putstr("pgt_buf running low in " __FILE__ "\n"); -+ debug_putstr("Need to raise BOOT_PGT_SIZE?\n"); -+ debug_putaddr(pages->pgt_buf_offset); -+ debug_putaddr(pages->pgt_buf_size); -+ } -+ - entry = pages->pgt_buf + pages->pgt_buf_offset; - pages->pgt_buf_offset += PAGE_SIZE; - -diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h -index 9191280d9ea31..215d37f7dde8a 100644 ---- a/arch/x86/include/asm/boot.h -+++ b/arch/x86/include/asm/boot.h -@@ -40,23 +40,40 @@ - #ifdef CONFIG_X86_64 - # define BOOT_STACK_SIZE 0x4000 - -+/* -+ * Used by decompressor's startup_32() to allocate page tables for identity -+ * mapping of the 4G of RAM in 4-level paging mode: -+ * - 1 level4 table; -+ * - 1 level3 table; -+ * - 4 level2 table that maps everything with 2M pages; -+ * -+ * The additional level5 table needed for 5-level paging is allocated from -+ * trampoline_32bit memory. -+ */ - # define BOOT_INIT_PGT_SIZE (6*4096) --# ifdef CONFIG_RANDOMIZE_BASE -+ - /* -- * Assuming all cross the 512GB boundary: -- * 1 page for level4 -- * (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel -- * 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). -- * Total is 19 pages. -+ * Total number of page tables kernel_add_identity_map() can allocate, -+ * including page tables consumed by startup_32(). -+ * -+ * Worst-case scenario: -+ * - 5-level paging needs 1 level5 table; -+ * - KASLR needs to map kernel, boot_params, cmdline and randomized kernel, -+ * assuming all of them cross 256T boundary: -+ * + 4*2 level4 table; -+ * + 4*2 level3 table; -+ * + 4*2 level2 table; -+ * - X86_VERBOSE_BOOTUP needs to map the first 2M (video RAM): -+ * + 1 level4 table; -+ * + 1 level3 table; -+ * + 1 level2 table; -+ * Total: 28 tables -+ * -+ * Add 4 spare table in case decompressor touches anything beyond what is -+ * accounted above. Warn if it happens. - */ --# ifdef CONFIG_X86_VERBOSE_BOOTUP --# define BOOT_PGT_SIZE (19*4096) --# else /* !CONFIG_X86_VERBOSE_BOOTUP */ --# define BOOT_PGT_SIZE (17*4096) --# endif --# else /* !CONFIG_RANDOMIZE_BASE */ --# define BOOT_PGT_SIZE BOOT_INIT_PGT_SIZE --# endif -+# define BOOT_PGT_SIZE_WARN (28*4096) -+# define BOOT_PGT_SIZE (32*4096) - - #else /* !CONFIG_X86_64 */ - # define BOOT_STACK_SIZE 0x1000 -diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h -index f484d656d34ee..3a0282a6a55df 100644 ---- a/arch/x86/include/asm/linkage.h -+++ b/arch/x86/include/asm/linkage.h -@@ -8,6 +8,14 @@ - #undef notrace - #define notrace __attribute__((no_instrument_function)) - -+#ifdef CONFIG_64BIT -+/* -+ * The generic version tends to create spurious ENDBR instructions under -+ * certain conditions. -+ */ -+#define _THIS_IP_ ({ unsigned long __here; asm ("lea 0(%%rip), %0" : "=r" (__here)); __here; }) -+#endif -+ - #ifdef CONFIG_X86_32 - #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) - #endif /* CONFIG_X86_32 */ -diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile -index 42abd6af11984..d28e0987aa85b 100644 ---- a/arch/x86/purgatory/Makefile -+++ b/arch/x86/purgatory/Makefile -@@ -19,6 +19,10 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS - # optimization flags. - KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS)) - -+# When LTO is enabled, llvm emits many text sections, which is not supported -+# by kexec. Remove -flto=* flags. -+KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS)) -+ - # When linking purgatory.ro with -r unresolved symbols are not checked, - # also link a purgatory.chk binary without -r to check for unresolved symbols. - PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib -diff --git a/block/bio-integrity.c b/block/bio-integrity.c -index 91ffee6fc8cb4..4533eb4916610 100644 ---- a/block/bio-integrity.c -+++ b/block/bio-integrity.c -@@ -124,23 +124,18 @@ int bio_integrity_add_page(struct bio *bio, struct page *page, - unsigned int len, unsigned int offset) - { - struct bio_integrity_payload *bip = bio_integrity(bio); -- struct bio_vec *iv; - - if (bip->bip_vcnt >= bip->bip_max_vcnt) { - printk(KERN_ERR "%s: bip_vec full\n", __func__); - return 0; - } - -- iv = bip->bip_vec + bip->bip_vcnt; -- - if (bip->bip_vcnt && - bvec_gap_to_prev(&bdev_get_queue(bio->bi_bdev)->limits, - &bip->bip_vec[bip->bip_vcnt - 1], offset)) - return 0; - -- iv->bv_page = page; -- iv->bv_len = len; -- iv->bv_offset = offset; -+ bvec_set_page(&bip->bip_vec[bip->bip_vcnt], page, len, offset); - bip->bip_vcnt++; - - return len; -diff --git a/block/bio.c b/block/bio.c -index d5cd825d6efc0..9ec72a78f1149 100644 ---- a/block/bio.c -+++ b/block/bio.c -@@ -976,10 +976,7 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio, - if (bio->bi_vcnt >= queue_max_segments(q)) - return 0; - -- bvec = &bio->bi_io_vec[bio->bi_vcnt]; -- bvec->bv_page = page; -- bvec->bv_len = len; -- bvec->bv_offset = offset; -+ bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, offset); - bio->bi_vcnt++; - bio->bi_iter.bi_size += len; - return len; -@@ -1055,15 +1052,10 @@ EXPORT_SYMBOL_GPL(bio_add_zone_append_page); - void __bio_add_page(struct bio *bio, struct page *page, - unsigned int len, unsigned int off) - { -- struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt]; -- - WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)); - WARN_ON_ONCE(bio_full(bio, len)); - -- bv->bv_page = page; -- bv->bv_offset = off; -- bv->bv_len = len; -- -+ bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, off); - bio->bi_iter.bi_size += len; - bio->bi_vcnt++; - } -diff --git a/crypto/lrw.c b/crypto/lrw.c -index 8d59a66b65255..fb8892ed179f5 100644 ---- a/crypto/lrw.c -+++ b/crypto/lrw.c -@@ -357,10 +357,10 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb) - * cipher name. - */ - if (!strncmp(cipher_name, "ecb(", 4)) { -- unsigned len; -+ int len; - -- len = strlcpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); -- if (len < 2 || len >= sizeof(ecb_name)) -+ len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); -+ if (len < 2) - goto err_free_inst; - - if (ecb_name[len - 1] != ')') -diff --git a/crypto/xts.c b/crypto/xts.c -index de6cbcf69bbd6..b05020657cdc8 100644 ---- a/crypto/xts.c -+++ b/crypto/xts.c -@@ -396,10 +396,10 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb) - * cipher name. - */ - if (!strncmp(cipher_name, "ecb(", 4)) { -- unsigned len; -+ int len; - -- len = strlcpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); -- if (len < 2 || len >= sizeof(ctx->name)) -+ len = strscpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); -+ if (len < 2) - goto err_free_inst; - - if (ctx->name[len - 1] != ')') -diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c -index bef69e87a0a29..8c34c0ffb1d93 100644 ---- a/drivers/acpi/acpica/psopcode.c -+++ b/drivers/acpi/acpica/psopcode.c -@@ -603,7 +603,7 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { - - /* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, - AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, -- AML_FLAGS_EXEC_0A_0T_1R), -+ AML_FLAGS_EXEC_0A_0T_1R | AML_NO_OPERAND_RESOLVE), - - /* ACPI 5.0 opcodes */ - -diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c -index 2e1cae53536f5..3a6cf5675e607 100644 ---- a/drivers/acpi/arm64/iort.c -+++ b/drivers/acpi/arm64/iort.c -@@ -1699,7 +1699,10 @@ static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res, - static struct acpi_platform_list pmcg_plat_info[] __initdata = { - /* HiSilicon Hip08 Platform */ - {"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal, -- "Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08}, -+ "Erratum #162001800, Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP08}, -+ /* HiSilicon Hip09 Platform */ -+ {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal, -+ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, - { } - }; - -diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c -index 707d6811615b8..073d26ddb6c21 100644 ---- a/drivers/acpi/video_detect.c -+++ b/drivers/acpi/video_detect.c -@@ -443,6 +443,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { - DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"), - }, - }, -+ { -+ /* https://bugzilla.suse.com/show_bug.cgi?id=1208724 */ -+ .callback = video_detect_force_native, -+ /* Lenovo Ideapad Z470 */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Z470"), -+ }, -+ }, - { - /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */ - .callback = video_detect_force_native, -diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c -index ec84da6cc1bff..5510657d4be81 100644 ---- a/drivers/acpi/x86/s2idle.c -+++ b/drivers/acpi/x86/s2idle.c -@@ -112,6 +112,12 @@ static void lpi_device_get_constraints_amd(void) - union acpi_object *package = &out_obj->package.elements[i]; - - if (package->type == ACPI_TYPE_PACKAGE) { -+ if (lpi_constraints_table) { -+ acpi_handle_err(lps0_device_handle, -+ "Duplicate constraints list\n"); -+ goto free_acpi_buffer; -+ } -+ - lpi_constraints_table = kcalloc(package->package.count, - sizeof(*lpi_constraints_table), - GFP_KERNEL); -diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c -index 1645335b8d2df..805645efb3ccf 100644 ---- a/drivers/ata/ahci.c -+++ b/drivers/ata/ahci.c -@@ -1884,6 +1884,15 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - else - dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n"); - -+ if (!(hpriv->cap & HOST_CAP_PART)) -+ host->flags |= ATA_HOST_NO_PART; -+ -+ if (!(hpriv->cap & HOST_CAP_SSC)) -+ host->flags |= ATA_HOST_NO_SSC; -+ -+ if (!(hpriv->cap2 & HOST_CAP2_SDS)) -+ host->flags |= ATA_HOST_NO_DEVSLP; -+ - if (pi.flags & ATA_FLAG_EM) - ahci_reset_em(host); - -diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c -index 954386a2b5002..1b1671c027cd3 100644 ---- a/drivers/ata/libahci.c -+++ b/drivers/ata/libahci.c -@@ -1255,6 +1255,26 @@ static ssize_t ahci_activity_show(struct ata_device *dev, char *buf) - return sprintf(buf, "%d\n", emp->blink_policy); - } - -+static void ahci_port_clear_pending_irq(struct ata_port *ap) -+{ -+ struct ahci_host_priv *hpriv = ap->host->private_data; -+ void __iomem *port_mmio = ahci_port_base(ap); -+ u32 tmp; -+ -+ /* clear SError */ -+ tmp = readl(port_mmio + PORT_SCR_ERR); -+ dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp); -+ writel(tmp, port_mmio + PORT_SCR_ERR); -+ -+ /* clear port IRQ */ -+ tmp = readl(port_mmio + PORT_IRQ_STAT); -+ dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp); -+ if (tmp) -+ writel(tmp, port_mmio + PORT_IRQ_STAT); -+ -+ writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT); -+} -+ - static void ahci_port_init(struct device *dev, struct ata_port *ap, - int port_no, void __iomem *mmio, - void __iomem *port_mmio) -@@ -1269,18 +1289,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap, - if (rc) - dev_warn(dev, "%s (%d)\n", emsg, rc); - -- /* clear SError */ -- tmp = readl(port_mmio + PORT_SCR_ERR); -- dev_dbg(dev, "PORT_SCR_ERR 0x%x\n", tmp); -- writel(tmp, port_mmio + PORT_SCR_ERR); -- -- /* clear port IRQ */ -- tmp = readl(port_mmio + PORT_IRQ_STAT); -- dev_dbg(dev, "PORT_IRQ_STAT 0x%x\n", tmp); -- if (tmp) -- writel(tmp, port_mmio + PORT_IRQ_STAT); -- -- writel(1 << port_no, mmio + HOST_IRQ_STAT); -+ ahci_port_clear_pending_irq(ap); - - /* mark esata ports */ - tmp = readl(port_mmio + PORT_CMD); -@@ -1601,6 +1610,8 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class, - tf.status = ATA_BUSY; - ata_tf_to_fis(&tf, 0, 0, d2h_fis); - -+ ahci_port_clear_pending_irq(ap); -+ - rc = sata_link_hardreset(link, timing, deadline, online, - ahci_check_ready); - -diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c -index fd4dccc253896..71a00842eb5ee 100644 ---- a/drivers/ata/libata-sata.c -+++ b/drivers/ata/libata-sata.c -@@ -394,10 +394,23 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, - case ATA_LPM_MED_POWER_WITH_DIPM: - case ATA_LPM_MIN_POWER_WITH_PARTIAL: - case ATA_LPM_MIN_POWER: -- if (ata_link_nr_enabled(link) > 0) -- /* no restrictions on LPM transitions */ -+ if (ata_link_nr_enabled(link) > 0) { -+ /* assume no restrictions on LPM transitions */ - scontrol &= ~(0x7 << 8); -- else { -+ -+ /* -+ * If the controller does not support partial, slumber, -+ * or devsleep, then disallow these transitions. -+ */ -+ if (link->ap->host->flags & ATA_HOST_NO_PART) -+ scontrol |= (0x1 << 8); -+ -+ if (link->ap->host->flags & ATA_HOST_NO_SSC) -+ scontrol |= (0x2 << 8); -+ -+ if (link->ap->host->flags & ATA_HOST_NO_DEVSLP) -+ scontrol |= (0x4 << 8); -+ } else { - /* empty port, power off */ - scontrol &= ~0xf; - scontrol |= (0x1 << 2); -diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c -index ac36b01cf6d5d..ddde1427c90c7 100644 ---- a/drivers/bus/ti-sysc.c -+++ b/drivers/bus/ti-sysc.c -@@ -1548,6 +1548,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), - SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), -+ SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, -+ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), - - /* Quirks that need to be set based on the module address */ - SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, -diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c -index 44f71f2c8cfa0..5889d9edaf940 100644 ---- a/drivers/char/tpm/tpm_tis_core.c -+++ b/drivers/char/tpm/tpm_tis_core.c -@@ -498,10 +498,17 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len) - int rc; - u32 ordinal; - unsigned long dur; -+ unsigned int try; - -- rc = tpm_tis_send_data(chip, buf, len); -- if (rc < 0) -- return rc; -+ for (try = 0; try < TPM_RETRY; try++) { -+ rc = tpm_tis_send_data(chip, buf, len); -+ if (rc >= 0) -+ /* Data transfer done successfully */ -+ break; -+ else if (rc != -EIO) -+ /* Data transfer failed, not recoverable */ -+ return rc; -+ } - - rc = tpm_tis_verify_crc(priv, len, buf); - if (rc < 0) { -diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c -index eb6b59363c4f5..3d58514d04826 100644 ---- a/drivers/dma-buf/dma-buf.c -+++ b/drivers/dma-buf/dma-buf.c -@@ -1105,6 +1105,34 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, - } - EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, DMA_BUF); - -+/** -+ * dma_buf_map_attachment_unlocked - Returns the scatterlist table of the attachment; -+ * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the -+ * dma_buf_ops. -+ * @attach: [in] attachment whose scatterlist is to be returned -+ * @direction: [in] direction of DMA transfer -+ * -+ * Unlocked variant of dma_buf_map_attachment(). -+ */ -+struct sg_table * -+dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach, -+ enum dma_data_direction direction) -+{ -+ struct sg_table *sg_table; -+ -+ might_sleep(); -+ -+ if (WARN_ON(!attach || !attach->dmabuf)) -+ return ERR_PTR(-EINVAL); -+ -+ dma_resv_lock(attach->dmabuf->resv, NULL); -+ sg_table = dma_buf_map_attachment(attach, direction); -+ dma_resv_unlock(attach->dmabuf->resv); -+ -+ return sg_table; -+} -+EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, DMA_BUF); -+ - /** - * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might - * deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of -@@ -1141,6 +1169,31 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, - } - EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, DMA_BUF); - -+/** -+ * dma_buf_unmap_attachment_unlocked - unmaps and decreases usecount of the buffer;might -+ * deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of -+ * dma_buf_ops. -+ * @attach: [in] attachment to unmap buffer from -+ * @sg_table: [in] scatterlist info of the buffer to unmap -+ * @direction: [in] direction of DMA transfer -+ * -+ * Unlocked variant of dma_buf_unmap_attachment(). -+ */ -+void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach, -+ struct sg_table *sg_table, -+ enum dma_data_direction direction) -+{ -+ might_sleep(); -+ -+ if (WARN_ON(!attach || !attach->dmabuf || !sg_table)) -+ return; -+ -+ dma_resv_lock(attach->dmabuf->resv, NULL); -+ dma_buf_unmap_attachment(attach, sg_table, direction); -+ dma_resv_unlock(attach->dmabuf->resv); -+} -+EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment_unlocked, DMA_BUF); -+ - /** - * dma_buf_move_notify - notify attachments that DMA-buf is moving - * -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -index 0c962f996aff5..c46c6fbd235e8 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h -@@ -1266,7 +1266,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, - void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); - int amdgpu_device_pci_reset(struct amdgpu_device *adev); - bool amdgpu_device_need_post(struct amdgpu_device *adev); --bool amdgpu_sg_display_supported(struct amdgpu_device *adev); - bool amdgpu_device_pcie_dynamic_switching_supported(void); - bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev); - bool amdgpu_device_aspm_support_quirk(void); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -index 02a112d00d413..4624160315648 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -@@ -120,7 +120,6 @@ static int amdgpu_cs_p1_user_fence(struct amdgpu_cs_parser *p, - struct drm_gem_object *gobj; - struct amdgpu_bo *bo; - unsigned long size; -- int r; - - gobj = drm_gem_object_lookup(p->filp, data->handle); - if (gobj == NULL) -@@ -132,23 +131,14 @@ static int amdgpu_cs_p1_user_fence(struct amdgpu_cs_parser *p, - drm_gem_object_put(gobj); - - size = amdgpu_bo_size(bo); -- if (size != PAGE_SIZE || (data->offset + 8) > size) { -- r = -EINVAL; -- goto error_unref; -- } -+ if (size != PAGE_SIZE || data->offset > (size - 8)) -+ return -EINVAL; - -- if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) { -- r = -EINVAL; -- goto error_unref; -- } -+ if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) -+ return -EINVAL; - - *offset = data->offset; -- - return 0; -- --error_unref: -- amdgpu_bo_unref(&bo); -- return r; - } - - static int amdgpu_cs_p1_bo_handles(struct amdgpu_cs_parser *p, -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index 9aac9e755609d..5f5999cea7d2c 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -1336,32 +1336,6 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev) - return true; - } - --/* -- * On APUs with >= 64GB white flickering has been observed w/ SG enabled. -- * Disable S/G on such systems until we have a proper fix. -- * https://gitlab.freedesktop.org/drm/amd/-/issues/2354 -- * https://gitlab.freedesktop.org/drm/amd/-/issues/2735 -- */ --bool amdgpu_sg_display_supported(struct amdgpu_device *adev) --{ -- switch (amdgpu_sg_display) { -- case -1: -- break; -- case 0: -- return false; -- case 1: -- return true; -- default: -- return false; -- } -- if ((totalram_pages() << (PAGE_SHIFT - 10)) + -- (adev->gmc.real_vram_size / 1024) >= 64000000) { -- DRM_WARN("Disabling S/G due to >=64GB RAM\n"); -- return false; -- } -- return true; --} -- - /* - * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic - * speed switching. Until we have confirmation from Intel that a specific host -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index c8e562dcd99d0..18274ff5082ad 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -1265,11 +1265,15 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ - - pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); - -- page_table_start.high_part = (u32)(adev->gmc.gart_start >> 44) & 0xF; -- page_table_start.low_part = (u32)(adev->gmc.gart_start >> 12); -- page_table_end.high_part = (u32)(adev->gmc.gart_end >> 44) & 0xF; -- page_table_end.low_part = (u32)(adev->gmc.gart_end >> 12); -- page_table_base.high_part = upper_32_bits(pt_base) & 0xF; -+ page_table_start.high_part = upper_32_bits(adev->gmc.gart_start >> -+ AMDGPU_GPU_PAGE_SHIFT); -+ page_table_start.low_part = lower_32_bits(adev->gmc.gart_start >> -+ AMDGPU_GPU_PAGE_SHIFT); -+ page_table_end.high_part = upper_32_bits(adev->gmc.gart_end >> -+ AMDGPU_GPU_PAGE_SHIFT); -+ page_table_end.low_part = lower_32_bits(adev->gmc.gart_end >> -+ AMDGPU_GPU_PAGE_SHIFT); -+ page_table_base.high_part = upper_32_bits(pt_base); - page_table_base.low_part = lower_32_bits(pt_base); - - pa_config->system_aperture.start_addr = (uint64_t)logical_addr_low << 18; -@@ -1634,8 +1638,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) - } - break; - } -- if (init_data.flags.gpu_vm_support) -- init_data.flags.gpu_vm_support = amdgpu_sg_display_supported(adev); -+ if (init_data.flags.gpu_vm_support && -+ (amdgpu_sg_display == 0)) -+ init_data.flags.gpu_vm_support = false; - - if (init_data.flags.gpu_vm_support) - adev->mode_info.gpu_vm_support = true; -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c -index ffbb739d85b69..8496ff4a25e35 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c -@@ -290,7 +290,8 @@ static void dccg32_set_dpstreamclk( - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - /* set the dtbclk_p source */ -- dccg32_set_dtbclk_p_src(dccg, src, otg_inst); -+ /* always program refclk as DTBCLK. No use-case expected to require DPREFCLK as refclk */ -+ dccg32_set_dtbclk_p_src(dccg, DTBCLK0, otg_inst); - - /* enabled to select one of the DTBCLKs for pipe */ - switch (dp_hpo_inst) { -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c -index ebc04b72b284b..9c84561ff3bc4 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c -@@ -4133,7 +4133,9 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l - } - if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN31_MAX_FMT_420_BUFFER_WIDTH - && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) { -- if (v->HActive[k] / 2 > DCN31_MAX_FMT_420_BUFFER_WIDTH) { -+ if (v->Output[k] == dm_hdmi) { -+ FMTBufferExceeded = true; -+ } else if (v->HActive[k] / 2 > DCN31_MAX_FMT_420_BUFFER_WIDTH) { - v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1; - v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1; - -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c -index 4998b211ccac7..5b47ccde64241 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c -@@ -4225,7 +4225,9 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_ - } - if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN314_MAX_FMT_420_BUFFER_WIDTH - && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) { -- if (v->HActive[k] / 2 > DCN314_MAX_FMT_420_BUFFER_WIDTH) { -+ if (v->Output[k] == dm_hdmi) { -+ FMTBufferExceeded = true; -+ } else if (v->HActive[k] / 2 > DCN314_MAX_FMT_420_BUFFER_WIDTH) { - v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1; - v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1; - -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c -index b53feeaf5cf11..23e4be2ad63f9 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c -@@ -3454,6 +3454,7 @@ bool dml32_CalculatePrefetchSchedule( - double TimeForFetchingMetaPTE = 0; - double TimeForFetchingRowInVBlank = 0; - double LinesToRequestPrefetchPixelData = 0; -+ double LinesForPrefetchBandwidth = 0; - unsigned int HostVMDynamicLevelsTrips; - double trip_to_mem; - double Tvm_trips; -@@ -3883,11 +3884,15 @@ bool dml32_CalculatePrefetchSchedule( - TimeForFetchingMetaPTE = Tvm_oto; - TimeForFetchingRowInVBlank = Tr0_oto; - *PrefetchBandwidth = prefetch_bw_oto; -+ /* Clamp to oto for bandwidth calculation */ -+ LinesForPrefetchBandwidth = dst_y_prefetch_oto; - } else { - *DestinationLinesForPrefetch = dst_y_prefetch_equ; - TimeForFetchingMetaPTE = Tvm_equ; - TimeForFetchingRowInVBlank = Tr0_equ; - *PrefetchBandwidth = prefetch_bw_equ; -+ /* Clamp to equ for bandwidth calculation */ -+ LinesForPrefetchBandwidth = dst_y_prefetch_equ; - } - - *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0; -@@ -3895,7 +3900,7 @@ bool dml32_CalculatePrefetchSchedule( - *DestinationLinesToRequestRowInVBlank = - dml_ceil(4.0 * TimeForFetchingRowInVBlank / LineTime, 1.0) / 4.0; - -- LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch - -+ LinesToRequestPrefetchPixelData = LinesForPrefetchBandwidth - - *DestinationLinesToRequestVMInVBlank - 2 * *DestinationLinesToRequestRowInVBlank; - - #ifdef __DML_VBA_DEBUG__ -diff --git a/drivers/gpu/drm/bridge/tc358762.c b/drivers/gpu/drm/bridge/tc358762.c -index 7f4fce1aa9988..8db981e7759b9 100644 ---- a/drivers/gpu/drm/bridge/tc358762.c -+++ b/drivers/gpu/drm/bridge/tc358762.c -@@ -216,7 +216,7 @@ static int tc358762_probe(struct mipi_dsi_device *dsi) - dsi->lanes = 1; - dsi->format = MIPI_DSI_FMT_RGB888; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | -- MIPI_DSI_MODE_LPM; -+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_VIDEO_HSE; - - ret = tc358762_parse_dt(ctx); - if (ret < 0) -diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c -index 739e0d40cca61..5ed77e3361fd7 100644 ---- a/drivers/gpu/drm/drm_edid.c -+++ b/drivers/gpu/drm/drm_edid.c -@@ -231,6 +231,7 @@ static const struct edid_quirk { - - /* OSVR HDK and HDK2 VR Headsets */ - EDID_QUIRK('S', 'V', 'R', 0x1019, EDID_QUIRK_NON_DESKTOP), -+ EDID_QUIRK('A', 'U', 'O', 0x1111, EDID_QUIRK_NON_DESKTOP), - }; - - /* -diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c -index 4153f302de7c4..d19e796c20613 100644 ---- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c -+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c -@@ -39,13 +39,12 @@ static void exynos_drm_crtc_atomic_disable(struct drm_crtc *crtc, - if (exynos_crtc->ops->atomic_disable) - exynos_crtc->ops->atomic_disable(exynos_crtc); - -+ spin_lock_irq(&crtc->dev->event_lock); - if (crtc->state->event && !crtc->state->active) { -- spin_lock_irq(&crtc->dev->event_lock); - drm_crtc_send_vblank_event(crtc, crtc->state->event); -- spin_unlock_irq(&crtc->dev->event_lock); -- - crtc->state->event = NULL; - } -+ spin_unlock_irq(&crtc->dev->event_lock); - } - - static int exynos_crtc_atomic_check(struct drm_crtc *crtc, -diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c -index 4c249939a6c3b..395a190274cfb 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dp.c -+++ b/drivers/gpu/drm/mediatek/mtk_dp.c -@@ -847,7 +847,7 @@ static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd, - u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) & - AUX_RX_PHY_STATE_AUX_TX_P0_MASK; - if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) { -- drm_err(mtk_dp->drm_dev, -+ dev_err(mtk_dp->dev, - "AUX Rx Aux hang, need SW reset\n"); - return -EIO; - } -@@ -2062,7 +2062,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux, - is_read = true; - break; - default: -- drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n", -+ dev_err(mtk_dp->dev, "invalid aux cmd = %d\n", - msg->request); - ret = -EINVAL; - goto err; -@@ -2078,7 +2078,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux, - to_access, &msg->reply); - - if (ret) { -- drm_info(mtk_dp->drm_dev, -+ dev_info(mtk_dp->dev, - "Failed to do AUX transfer: %d\n", ret); - goto err; - } -diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c -index 7441d992a5d7a..8b0a9059d3fdd 100644 ---- a/drivers/gpu/drm/tiny/gm12u320.c -+++ b/drivers/gpu/drm/tiny/gm12u320.c -@@ -69,10 +69,10 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)"); - #define READ_STATUS_SIZE 13 - #define MISC_VALUE_SIZE 4 - --#define CMD_TIMEOUT msecs_to_jiffies(200) --#define DATA_TIMEOUT msecs_to_jiffies(1000) --#define IDLE_TIMEOUT msecs_to_jiffies(2000) --#define FIRST_FRAME_TIMEOUT msecs_to_jiffies(2000) -+#define CMD_TIMEOUT 200 -+#define DATA_TIMEOUT 1000 -+#define IDLE_TIMEOUT 2000 -+#define FIRST_FRAME_TIMEOUT 2000 - - #define MISC_REQ_GET_SET_ECO_A 0xff - #define MISC_REQ_GET_SET_ECO_B 0x35 -@@ -388,7 +388,7 @@ static void gm12u320_fb_update_work(struct work_struct *work) - * switches back to showing its logo. - */ - queue_delayed_work(system_long_wq, &gm12u320->fb_update.work, -- IDLE_TIMEOUT); -+ msecs_to_jiffies(IDLE_TIMEOUT)); - - return; - err: -diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index c64c381b69b7f..866c52afb8b0a 100644 ---- a/drivers/i2c/busses/i2c-aspeed.c -+++ b/drivers/i2c/busses/i2c-aspeed.c -@@ -698,13 +698,16 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap, - - if (time_left == 0) { - /* -- * If timed out and bus is still busy in a multi master -- * environment, attempt recovery at here. -+ * In a multi-master setup, if a timeout occurs, attempt -+ * recovery. But if the bus is idle, we still need to reset the -+ * i2c controller to clear the remaining interrupts. - */ - if (bus->multi_master && - (readl(bus->base + ASPEED_I2C_CMD_REG) & - ASPEED_I2CD_BUS_BUSY_STS)) - aspeed_i2c_recover_bus(bus); -+ else -+ aspeed_i2c_reset(bus); - - /* - * If timed out and the state is still pending, drop the pending -diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c -index cfa52c6369d05..e4b2d9ef61b4d 100644 ---- a/drivers/interconnect/core.c -+++ b/drivers/interconnect/core.c -@@ -29,6 +29,7 @@ static LIST_HEAD(icc_providers); - static int providers_count; - static bool synced_state; - static DEFINE_MUTEX(icc_lock); -+static DEFINE_MUTEX(icc_bw_lock); - static struct dentry *icc_debugfs_dir; - - static void icc_summary_show_one(struct seq_file *s, struct icc_node *n) -@@ -632,7 +633,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw) - if (WARN_ON(IS_ERR(path) || !path->num_nodes)) - return -EINVAL; - -- mutex_lock(&icc_lock); -+ mutex_lock(&icc_bw_lock); - - old_avg = path->reqs[0].avg_bw; - old_peak = path->reqs[0].peak_bw; -@@ -664,7 +665,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw) - apply_constraints(path); - } - -- mutex_unlock(&icc_lock); -+ mutex_unlock(&icc_bw_lock); - - trace_icc_set_bw_end(path, ret); - -@@ -967,6 +968,7 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider) - return; - - mutex_lock(&icc_lock); -+ mutex_lock(&icc_bw_lock); - - node->provider = provider; - list_add_tail(&node->node_list, &provider->nodes); -@@ -992,6 +994,7 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider) - node->avg_bw = 0; - node->peak_bw = 0; - -+ mutex_unlock(&icc_bw_lock); - mutex_unlock(&icc_lock); - } - EXPORT_SYMBOL_GPL(icc_node_add); -@@ -1129,6 +1132,7 @@ void icc_sync_state(struct device *dev) - return; - - mutex_lock(&icc_lock); -+ mutex_lock(&icc_bw_lock); - synced_state = true; - list_for_each_entry(p, &icc_providers, provider_list) { - dev_dbg(p->dev, "interconnect provider is in synced state\n"); -@@ -1141,13 +1145,21 @@ void icc_sync_state(struct device *dev) - } - } - } -+ mutex_unlock(&icc_bw_lock); - mutex_unlock(&icc_lock); - } - EXPORT_SYMBOL_GPL(icc_sync_state); - - static int __init icc_init(void) - { -- struct device_node *root = of_find_node_by_path("/"); -+ struct device_node *root; -+ -+ /* Teach lockdep about lock ordering wrt. shrinker: */ -+ fs_reclaim_acquire(GFP_KERNEL); -+ might_lock(&icc_bw_lock); -+ fs_reclaim_release(GFP_KERNEL); -+ -+ root = of_find_node_by_path("/"); - - providers_count = of_count_icc_providers(root); - of_node_put(root); -diff --git a/drivers/md/dm.c b/drivers/md/dm.c -index acf7e7551c941..0ec85d159bcde 100644 ---- a/drivers/md/dm.c -+++ b/drivers/md/dm.c -@@ -707,24 +707,6 @@ static void dm_put_live_table_fast(struct mapped_device *md) __releases(RCU) - rcu_read_unlock(); - } - --static inline struct dm_table *dm_get_live_table_bio(struct mapped_device *md, -- int *srcu_idx, blk_opf_t bio_opf) --{ -- if (bio_opf & REQ_NOWAIT) -- return dm_get_live_table_fast(md); -- else -- return dm_get_live_table(md, srcu_idx); --} -- --static inline void dm_put_live_table_bio(struct mapped_device *md, int srcu_idx, -- blk_opf_t bio_opf) --{ -- if (bio_opf & REQ_NOWAIT) -- dm_put_live_table_fast(md); -- else -- dm_put_live_table(md, srcu_idx); --} -- - static char *_dm_claim_ptr = "I belong to device-mapper"; - - /* -@@ -1805,9 +1787,8 @@ static void dm_submit_bio(struct bio *bio) - struct mapped_device *md = bio->bi_bdev->bd_disk->private_data; - int srcu_idx; - struct dm_table *map; -- blk_opf_t bio_opf = bio->bi_opf; - -- map = dm_get_live_table_bio(md, &srcu_idx, bio_opf); -+ map = dm_get_live_table(md, &srcu_idx); - - /* If suspended, or map not yet available, queue this IO for later */ - if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) || -@@ -1823,7 +1804,7 @@ static void dm_submit_bio(struct bio *bio) - - dm_split_and_process_bio(md, map, bio); - out: -- dm_put_live_table_bio(md, srcu_idx, bio_opf); -+ dm_put_live_table(md, srcu_idx); - } - - static bool dm_poll_dm_io(struct dm_io *io, struct io_comp_batch *iob, -diff --git a/drivers/md/md.c b/drivers/md/md.c -index 86b2acfba1a7f..e87507d29895e 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -8228,7 +8228,7 @@ static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos) - spin_unlock(&all_mddevs_lock); - - if (to_put) -- mddev_put(mddev); -+ mddev_put(to_put); - return next_mddev; - - } -diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c -index ac64c587191b9..30f906a67def4 100644 ---- a/drivers/md/raid1.c -+++ b/drivers/md/raid1.c -@@ -1828,6 +1828,9 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev) - int number = rdev->raid_disk; - struct raid1_info *p = conf->mirrors + number; - -+ if (unlikely(number >= conf->raid_disks)) -+ goto abort; -+ - if (rdev != p->rdev) - p = conf->mirrors + conf->raid_disks + number; - -diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c -index 671fc0588e431..9af2c5596121c 100644 ---- a/drivers/media/pci/cx23885/cx23885-video.c -+++ b/drivers/media/pci/cx23885/cx23885-video.c -@@ -413,7 +413,7 @@ static int buffer_prepare(struct vb2_buffer *vb) - dev->height >> 1); - break; - default: -- BUG(); -+ return -EINVAL; /* should not happen */ - } - dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp 0x%08x - dma=0x%08lx\n", - buf, buf->vb.vb2_buf.index, -diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c -index 3b76a9d0383a8..1bbe58b24d99d 100644 ---- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c -+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c -@@ -354,7 +354,7 @@ static int cio2_hw_init(struct cio2_device *cio2, struct cio2_queue *q) - void __iomem *const base = cio2->base; - u8 lanes, csi2bus = q->csi2.port; - u8 sensor_vc = SENSOR_VIR_CH_DFLT; -- struct cio2_csi2_timing timing; -+ struct cio2_csi2_timing timing = { 0 }; - int i, r; - - fmt = cio2_find_format(NULL, &q->subdev_fmt.code); -diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c -index 7bc05f42a23c1..9a3f46c1f6ba3 100644 ---- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c -+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c -@@ -775,11 +775,13 @@ static int mdp_get_subsys_id(struct device *dev, struct device_node *node, - ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index); - if (ret != 0) { - dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n"); -+ put_device(&comp_pdev->dev); - return -EINVAL; - } - - comp->subsys_id = cmdq_reg.subsys; - dev_dbg(&comp_pdev->dev, "subsys id=%d\n", cmdq_reg.subsys); -+ put_device(&comp_pdev->dev); - - return 0; - } -diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c -index 60931367b82ca..48fc79cd40273 100644 ---- a/drivers/media/tuners/qt1010.c -+++ b/drivers/media/tuners/qt1010.c -@@ -345,11 +345,12 @@ static int qt1010_init(struct dvb_frontend *fe) - else - valptr = &tmpval; - -- BUG_ON(i >= ARRAY_SIZE(i2c_data) - 1); -- -- err = qt1010_init_meas1(priv, i2c_data[i+1].reg, -- i2c_data[i].reg, -- i2c_data[i].val, valptr); -+ if (i >= ARRAY_SIZE(i2c_data) - 1) -+ err = -EIO; -+ else -+ err = qt1010_init_meas1(priv, i2c_data[i + 1].reg, -+ i2c_data[i].reg, -+ i2c_data[i].val, valptr); - i++; - break; - } -diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c -index 1e9c8d01523be..cd6f5374414d4 100644 ---- a/drivers/media/usb/dvb-usb-v2/af9035.c -+++ b/drivers/media/usb/dvb-usb-v2/af9035.c -@@ -270,6 +270,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, - struct dvb_usb_device *d = i2c_get_adapdata(adap); - struct state *state = d_to_priv(d); - int ret; -+ u32 reg; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; -@@ -322,8 +323,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, - ret = -EOPNOTSUPP; - } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || - (msg[0].addr == state->af9033_i2c_addr[1])) { -+ if (msg[0].len < 3 || msg[1].len < 1) -+ return -EOPNOTSUPP; - /* demod access via firmware interface */ -- u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | -+ reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | - msg[0].buf[2]; - - if (msg[0].addr == state->af9033_i2c_addr[1]) -@@ -381,17 +384,16 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, - ret = -EOPNOTSUPP; - } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || - (msg[0].addr == state->af9033_i2c_addr[1])) { -+ if (msg[0].len < 3) -+ return -EOPNOTSUPP; - /* demod access via firmware interface */ -- u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | -+ reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | - msg[0].buf[2]; - - if (msg[0].addr == state->af9033_i2c_addr[1]) - reg |= 0x100000; - -- ret = (msg[0].len >= 3) ? af9035_wr_regs(d, reg, -- &msg[0].buf[3], -- msg[0].len - 3) -- : -EOPNOTSUPP; -+ ret = af9035_wr_regs(d, reg, &msg[0].buf[3], msg[0].len - 3); - } else { - /* I2C write */ - u8 buf[MAX_XFER_SIZE]; -diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c -index aa45b5d263f6b..a1235d0cce92f 100644 ---- a/drivers/media/usb/dvb-usb-v2/anysee.c -+++ b/drivers/media/usb/dvb-usb-v2/anysee.c -@@ -202,7 +202,7 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, - - while (i < num) { - if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { -- if (msg[i].len > 2 || msg[i+1].len > 60) { -+ if (msg[i].len != 2 || msg[i + 1].len > 60) { - ret = -EOPNOTSUPP; - break; - } -diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c -index 7524c90f5da61..6cbfe75791c21 100644 ---- a/drivers/media/usb/dvb-usb-v2/az6007.c -+++ b/drivers/media/usb/dvb-usb-v2/az6007.c -@@ -788,6 +788,10 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], - if (az6007_xfer_debug) - printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n", - addr, msgs[i].len); -+ if (msgs[i].len < 1) { -+ ret = -EIO; -+ goto err; -+ } - req = AZ6007_I2C_WR; - index = msgs[i].buf[0]; - value = addr | (1 << 8); -@@ -802,6 +806,10 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], - if (az6007_xfer_debug) - printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n", - addr, msgs[i].len); -+ if (msgs[i].len < 1) { -+ ret = -EIO; -+ goto err; -+ } - req = AZ6007_I2C_RD; - index = msgs[i].buf[0]; - value = addr; -diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c -index 0c434259c36f1..c71e7b93476de 100644 ---- a/drivers/media/usb/dvb-usb-v2/gl861.c -+++ b/drivers/media/usb/dvb-usb-v2/gl861.c -@@ -120,7 +120,7 @@ static int gl861_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - } else if (num == 2 && !(msg[0].flags & I2C_M_RD) && - (msg[1].flags & I2C_M_RD)) { - /* I2C write + read */ -- if (msg[0].len > 1 || msg[1].len > sizeof(ctx->buf)) { -+ if (msg[0].len != 1 || msg[1].len > sizeof(ctx->buf)) { - ret = -EOPNOTSUPP; - goto err; - } -diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c -index 0827bf3d4e8c7..13604e6acdb83 100644 ---- a/drivers/media/usb/dvb-usb/af9005.c -+++ b/drivers/media/usb/dvb-usb/af9005.c -@@ -422,6 +422,10 @@ static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - if (ret == 0) - ret = 2; - } else { -+ if (msg[0].len < 2) { -+ ret = -EOPNOTSUPP; -+ goto unlock; -+ } - /* write one or more registers */ - reg = msg[0].buf[0]; - addr = msg[0].addr; -@@ -431,6 +435,7 @@ static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - ret = 1; - } - -+unlock: - mutex_unlock(&d->i2c_mutex); - return ret; - } -diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c -index 8747960e61461..356fc728d59a8 100644 ---- a/drivers/media/usb/dvb-usb/dw2102.c -+++ b/drivers/media/usb/dvb-usb/dw2102.c -@@ -128,6 +128,10 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - - switch (num) { - case 2: -+ if (msg[0].len < 1) { -+ num = -EOPNOTSUPP; -+ break; -+ } - /* read stv0299 register */ - value = msg[0].buf[0];/* register */ - for (i = 0; i < msg[1].len; i++) { -@@ -139,6 +143,10 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - case 1: - switch (msg[0].addr) { - case 0x68: -+ if (msg[0].len < 2) { -+ num = -EOPNOTSUPP; -+ break; -+ } - /* write to stv0299 register */ - buf6[0] = 0x2a; - buf6[1] = msg[0].buf[0]; -@@ -148,6 +156,10 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - break; - case 0x60: - if (msg[0].flags == 0) { -+ if (msg[0].len < 4) { -+ num = -EOPNOTSUPP; -+ break; -+ } - /* write to tuner pll */ - buf6[0] = 0x2c; - buf6[1] = 5; -@@ -159,6 +171,10 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 7, DW210X_WRITE_MSG); - } else { -+ if (msg[0].len < 1) { -+ num = -EOPNOTSUPP; -+ break; -+ } - /* read from tuner */ - dw210x_op_rw(d->udev, 0xb5, 0, 0, - buf6, 1, DW210X_READ_MSG); -@@ -166,12 +182,20 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - } - break; - case (DW2102_RC_QUERY): -+ if (msg[0].len < 2) { -+ num = -EOPNOTSUPP; -+ break; -+ } - dw210x_op_rw(d->udev, 0xb8, 0, 0, - buf6, 2, DW210X_READ_MSG); - msg[0].buf[0] = buf6[0]; - msg[0].buf[1] = buf6[1]; - break; - case (DW2102_VOLTAGE_CTRL): -+ if (msg[0].len < 1) { -+ num = -EOPNOTSUPP; -+ break; -+ } - buf6[0] = 0x30; - buf6[1] = msg[0].buf[0]; - dw210x_op_rw(d->udev, 0xb2, 0, 0, -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 358ad56f65245..0cef98319f0e5 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -474,6 +474,7 @@ config HISI_HIKEY_USB - config OPEN_DICE - tristate "Open Profile for DICE driver" - depends on OF_RESERVED_MEM -+ depends on HAS_IOMEM - help - This driver exposes a DICE reserved memory region to userspace via - a character device. The memory region contains Compound Device -diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c -index 13518cac076c7..4c51d216f3d43 100644 ---- a/drivers/misc/fastrpc.c -+++ b/drivers/misc/fastrpc.c -@@ -310,8 +310,8 @@ static void fastrpc_free_map(struct kref *ref) - return; - } - } -- dma_buf_unmap_attachment(map->attach, map->table, -- DMA_BIDIRECTIONAL); -+ dma_buf_unmap_attachment_unlocked(map->attach, map->table, -+ DMA_BIDIRECTIONAL); - dma_buf_detach(map->buf, map->attach); - dma_buf_put(map->buf); - } -@@ -711,6 +711,7 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, - { - struct fastrpc_session_ctx *sess = fl->sctx; - struct fastrpc_map *map = NULL; -+ struct sg_table *table; - int err = 0; - - if (!fastrpc_map_lookup(fl, fd, ppmap, true)) -@@ -736,11 +737,12 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, - goto attach_err; - } - -- map->table = dma_buf_map_attachment(map->attach, DMA_BIDIRECTIONAL); -- if (IS_ERR(map->table)) { -- err = PTR_ERR(map->table); -+ table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL); -+ if (IS_ERR(table)) { -+ err = PTR_ERR(table); - goto map_err; - } -+ map->table = table; - - map->phys = sg_dma_address(map->table->sgl); - map->phys += ((u64)fl->sctx->sid << 32); -diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c -index b63cf1f9e8fb9..3c7b32c0d3f3f 100644 ---- a/drivers/mmc/host/sdhci-esdhc-imx.c -+++ b/drivers/mmc/host/sdhci-esdhc-imx.c -@@ -171,8 +171,8 @@ - #define ESDHC_FLAG_HS400 BIT(9) - /* - * The IP has errata ERR010450 -- * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't -- * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. -+ * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card -+ * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. - */ - #define ESDHC_FLAG_ERR010450 BIT(10) - /* The IP supports HS400ES mode */ -@@ -932,7 +932,8 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host, - | ESDHC_CLOCK_MASK); - sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); - -- if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) { -+ if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) && -+ (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) { - unsigned int max_clock; - - max_clock = imx_data->is_ddr ? 45000000 : 150000000; -diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig -index 3048ad77edb35..8236aabebb394 100644 ---- a/drivers/net/can/Kconfig -+++ b/drivers/net/can/Kconfig -@@ -174,10 +174,10 @@ config CAN_SLCAN - - config CAN_SUN4I - tristate "Allwinner A10 CAN controller" -- depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST -+ depends on MACH_SUN4I || MACH_SUN7I || RISCV || COMPILE_TEST - help - Say Y here if you want to use CAN controller found on Allwinner -- A10/A20 SoCs. -+ A10/A20/D1 SoCs. - - To compile this driver as a module, choose M here: the module will - be called sun4i_can. -diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c -index 2b78f9197681b..c3a6b028ea4d6 100644 ---- a/drivers/net/can/sun4i_can.c -+++ b/drivers/net/can/sun4i_can.c -@@ -91,6 +91,8 @@ - #define SUN4I_REG_BUF12_ADDR 0x0070 /* CAN Tx/Rx Buffer 12 */ - #define SUN4I_REG_ACPC_ADDR 0x0040 /* CAN Acceptance Code 0 */ - #define SUN4I_REG_ACPM_ADDR 0x0044 /* CAN Acceptance Mask 0 */ -+#define SUN4I_REG_ACPC_ADDR_D1 0x0028 /* CAN Acceptance Code 0 on the D1 */ -+#define SUN4I_REG_ACPM_ADDR_D1 0x002C /* CAN Acceptance Mask 0 on the D1 */ - #define SUN4I_REG_RBUF_RBACK_START_ADDR 0x0180 /* CAN transmit buffer start */ - #define SUN4I_REG_RBUF_RBACK_END_ADDR 0x01b0 /* CAN transmit buffer end */ - -@@ -205,9 +207,11 @@ - * struct sun4ican_quirks - Differences between SoC variants. - * - * @has_reset: SoC needs reset deasserted. -+ * @acp_offset: Offset of ACPC and ACPM registers - */ - struct sun4ican_quirks { - bool has_reset; -+ int acp_offset; - }; - - struct sun4ican_priv { -@@ -216,6 +220,7 @@ struct sun4ican_priv { - struct clk *clk; - struct reset_control *reset; - spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */ -+ int acp_offset; - }; - - static const struct can_bittiming_const sun4ican_bittiming_const = { -@@ -338,8 +343,8 @@ static int sun4i_can_start(struct net_device *dev) - } - - /* set filters - we accept all */ -- writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR); -- writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR); -+ writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR + priv->acp_offset); -+ writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR + priv->acp_offset); - - /* clear error counters and error code capture */ - writel(0, priv->base + SUN4I_REG_ERRC_ADDR); -@@ -768,10 +773,17 @@ static const struct ethtool_ops sun4ican_ethtool_ops = { - - static const struct sun4ican_quirks sun4ican_quirks_a10 = { - .has_reset = false, -+ .acp_offset = 0, - }; - - static const struct sun4ican_quirks sun4ican_quirks_r40 = { - .has_reset = true, -+ .acp_offset = 0, -+}; -+ -+static const struct sun4ican_quirks sun4ican_quirks_d1 = { -+ .has_reset = true, -+ .acp_offset = (SUN4I_REG_ACPC_ADDR_D1 - SUN4I_REG_ACPC_ADDR), - }; - - static const struct of_device_id sun4ican_of_match[] = { -@@ -784,6 +796,9 @@ static const struct of_device_id sun4ican_of_match[] = { - }, { - .compatible = "allwinner,sun8i-r40-can", - .data = &sun4ican_quirks_r40 -+ }, { -+ .compatible = "allwinner,sun20i-d1-can", -+ .data = &sun4ican_quirks_d1 - }, { - /* sentinel */ - }, -@@ -872,6 +887,7 @@ static int sun4ican_probe(struct platform_device *pdev) - priv->base = addr; - priv->clk = clk; - priv->reset = reset; -+ priv->acp_offset = quirks->acp_offset; - spin_lock_init(&priv->cmdreg_lock); - - platform_set_drvdata(pdev, dev); -@@ -909,4 +925,4 @@ module_platform_driver(sun4i_can_driver); - MODULE_AUTHOR("Peter Chen "); - MODULE_AUTHOR("Gerhard Bertelsmann "); - MODULE_LICENSE("Dual BSD/GPL"); --MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20)"); -+MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20/D1)"); -diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c -index b716adacd8159..7f6b69a523676 100644 ---- a/drivers/net/ethernet/atheros/alx/ethtool.c -+++ b/drivers/net/ethernet/atheros/alx/ethtool.c -@@ -292,9 +292,8 @@ static void alx_get_ethtool_stats(struct net_device *netdev, - spin_lock(&alx->stats_lock); - - alx_update_hw_stats(hw); -- BUILD_BUG_ON(sizeof(hw->stats) - offsetof(struct alx_hw_stats, rx_ok) < -- ALX_NUM_STATS * sizeof(u64)); -- memcpy(data, &hw->stats.rx_ok, ALX_NUM_STATS * sizeof(u64)); -+ BUILD_BUG_ON(sizeof(hw->stats) != ALX_NUM_STATS * sizeof(u64)); -+ memcpy(data, &hw->stats, sizeof(hw->stats)); - - spin_unlock(&alx->stats_lock); - } -diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c -index 2ffe5708a045b..7de4a8a4b563c 100644 ---- a/drivers/net/ethernet/intel/ice/ice_eswitch.c -+++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c -@@ -361,6 +361,9 @@ ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev) - np = netdev_priv(netdev); - vsi = np->vsi; - -+ if (!vsi || !ice_is_switchdev_running(vsi->back)) -+ return NETDEV_TX_BUSY; -+ - if (ice_is_reset_in_progress(vsi->back->state) || - test_bit(ICE_VF_DIS, vsi->back->state)) - return NETDEV_TX_BUSY; -diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c -index 9cd12b20b18d8..9bfaadfa6c009 100644 ---- a/drivers/net/wireless/ath/ath9k/ahb.c -+++ b/drivers/net/wireless/ath/ath9k/ahb.c -@@ -132,8 +132,8 @@ static int ath_ahb_probe(struct platform_device *pdev) - - ah = sc->sc_ah; - ath9k_hw_name(ah, hw_name, sizeof(hw_name)); -- wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", -- hw_name, (unsigned long)mem, irq); -+ wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n", -+ hw_name, mem, irq); - - return 0; - -diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h -index af44b33814ddc..f03d792732da7 100644 ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -115,8 +115,10 @@ struct ath_tx_status { - u8 qid; - u16 desc_id; - u8 tid; -- u32 ba_low; -- u32 ba_high; -+ struct_group(ba, -+ u32 ba_low; -+ u32 ba_high; -+ ); - u32 evm0; - u32 evm1; - u32 evm2; -diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c -index a074e23013c58..f0e3901e8182a 100644 ---- a/drivers/net/wireless/ath/ath9k/pci.c -+++ b/drivers/net/wireless/ath/ath9k/pci.c -@@ -988,8 +988,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) - sc->sc_ah->msi_reg = 0; - - ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); -- wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", -- hw_name, (unsigned long)sc->mem, pdev->irq); -+ wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n", -+ hw_name, sc->mem, pdev->irq); - - return 0; - -diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c -index ba271a10d4ab1..eeabdd67fbccd 100644 ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -462,7 +462,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, - isaggr = bf_isaggr(bf); - if (isaggr) { - seq_st = ts->ts_seqnum; -- memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); -+ memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3); - } - - while (bf) { -@@ -545,7 +545,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, - if (isaggr && txok) { - if (ts->ts_flags & ATH9K_TX_BA) { - seq_st = ts->ts_seqnum; -- memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); -+ memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3); - } else { - /* - * AR5416 can become deaf/mute when BA -diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c -index 237cbd5c5060b..f29ac6de71399 100644 ---- a/drivers/net/wireless/ath/wil6210/txrx.c -+++ b/drivers/net/wireless/ath/wil6210/txrx.c -@@ -666,7 +666,7 @@ static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb) - struct wil_tid_crypto_rx *c = mc ? &s->group_crypto_rx : - &s->tid_crypto_rx[tid]; - struct wil_tid_crypto_rx_single *cc = &c->key_id[key_id]; -- const u8 *pn = (u8 *)&d->mac.pn_15_0; -+ const u8 *pn = (u8 *)&d->mac.pn; - - if (!cc->key_set) { - wil_err_ratelimited(wil, -diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h -index 1ae1bec1b97f1..689f68d89a440 100644 ---- a/drivers/net/wireless/ath/wil6210/txrx.h -+++ b/drivers/net/wireless/ath/wil6210/txrx.h -@@ -343,8 +343,10 @@ struct vring_rx_mac { - u32 d0; - u32 d1; - u16 w4; -- u16 pn_15_0; -- u32 pn_47_16; -+ struct_group_attr(pn, __packed, -+ u16 pn_15_0; -+ u32 pn_47_16; -+ ); - } __packed; - - /* Rx descriptor - DMA part -diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c -index 201c8c35e0c9e..1ba1f21ebea26 100644 ---- a/drivers/net/wireless/ath/wil6210/txrx_edma.c -+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c -@@ -548,7 +548,7 @@ static int wil_rx_crypto_check_edma(struct wil6210_priv *wil, - s = &wil->sta[cid]; - c = mc ? &s->group_crypto_rx : &s->tid_crypto_rx[tid]; - cc = &c->key_id[key_id]; -- pn = (u8 *)&st->ext.pn_15_0; -+ pn = (u8 *)&st->ext.pn; - - if (!cc->key_set) { - wil_err_ratelimited(wil, -diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h -index c736f7413a35f..ee90e225bb050 100644 ---- a/drivers/net/wireless/ath/wil6210/txrx_edma.h -+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h -@@ -330,8 +330,10 @@ struct wil_rx_status_extension { - u32 d0; - u32 d1; - __le16 seq_num; /* only lower 12 bits */ -- u16 pn_15_0; -- u32 pn_47_16; -+ struct_group_attr(pn, __packed, -+ u16 pn_15_0; -+ u32 pn_47_16; -+ ); - } __packed; - - struct wil_rx_status_extended { -diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c -index da5c355405f68..db70cef854bc4 100644 ---- a/drivers/net/wireless/mac80211_hwsim.c -+++ b/drivers/net/wireless/mac80211_hwsim.c -@@ -4906,14 +4906,15 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, - frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]); - frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]); - -+ if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) || -+ frame_data_len > IEEE80211_MAX_DATA_LEN) -+ goto err; -+ - /* Allocate new skb here */ - skb = alloc_skb(frame_data_len, GFP_KERNEL); - if (skb == NULL) - goto err; - -- if (frame_data_len > IEEE80211_MAX_DATA_LEN) -- goto err; -- - /* Copy the data */ - skb_put_data(skb, frame_data, frame_data_len); - -diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c -index 97bb87c3676bb..6c60621b6cccb 100644 ---- a/drivers/net/wireless/marvell/mwifiex/tdls.c -+++ b/drivers/net/wireless/marvell/mwifiex/tdls.c -@@ -735,6 +735,7 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, - int ret; - u16 capab; - struct ieee80211_ht_cap *ht_cap; -+ unsigned int extra; - u8 radio, *pos; - - capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; -@@ -753,7 +754,10 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, - - switch (action_code) { - case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -- skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1); -+ /* See the layout of 'struct ieee80211_mgmt'. */ -+ extra = sizeof(mgmt->u.action.u.tdls_discover_resp) + -+ sizeof(mgmt->u.action.category); -+ skb_put(skb, extra); - mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; - mgmt->u.action.u.tdls_discover_resp.action_code = - WLAN_PUB_ACTION_TDLS_DISCOVER_RES; -@@ -762,8 +766,7 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, - mgmt->u.action.u.tdls_discover_resp.capability = - cpu_to_le16(capab); - /* move back for addr4 */ -- memmove(pos + ETH_ALEN, &mgmt->u.action.category, -- sizeof(mgmt->u.action.u.tdls_discover_resp)); -+ memmove(pos + ETH_ALEN, &mgmt->u.action, extra); - /* init address 4 */ - eth_broadcast_addr(pos); - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -index 1c0d8cf19b8eb..49ddca84f7862 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c -@@ -1167,6 +1167,10 @@ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, - if (unlikely(tx_info->skb->len <= ETH_HLEN)) - return -EINVAL; - -+ err = skb_cow_head(skb, MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE); -+ if (err) -+ return err; -+ - if (!wcid) - wcid = &dev->mt76.global_wcid; - -diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c -index fd73db8a535d8..25ddfabc58f73 100644 ---- a/drivers/nvme/host/core.c -+++ b/drivers/nvme/host/core.c -@@ -2368,25 +2368,8 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) - else - ctrl->ctrl_config = NVME_CC_CSS_NVM; - -- if (ctrl->cap & NVME_CAP_CRMS_CRWMS) { -- u32 crto; -- -- ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto); -- if (ret) { -- dev_err(ctrl->device, "Reading CRTO failed (%d)\n", -- ret); -- return ret; -- } -- -- if (ctrl->cap & NVME_CAP_CRMS_CRIMS) { -- ctrl->ctrl_config |= NVME_CC_CRIME; -- timeout = NVME_CRTO_CRIMT(crto); -- } else { -- timeout = NVME_CRTO_CRWMT(crto); -- } -- } else { -- timeout = NVME_CAP_TIMEOUT(ctrl->cap); -- } -+ if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS) -+ ctrl->ctrl_config |= NVME_CC_CRIME; - - ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; - ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; -@@ -2400,6 +2383,39 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) - if (ret) - return ret; - -+ /* CAP value may change after initial CC write */ -+ ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &ctrl->cap); -+ if (ret) -+ return ret; -+ -+ timeout = NVME_CAP_TIMEOUT(ctrl->cap); -+ if (ctrl->cap & NVME_CAP_CRMS_CRWMS) { -+ u32 crto, ready_timeout; -+ -+ ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto); -+ if (ret) { -+ dev_err(ctrl->device, "Reading CRTO failed (%d)\n", -+ ret); -+ return ret; -+ } -+ -+ /* -+ * CRTO should always be greater or equal to CAP.TO, but some -+ * devices are known to get this wrong. Use the larger of the -+ * two values. -+ */ -+ if (ctrl->ctrl_config & NVME_CC_CRIME) -+ ready_timeout = NVME_CRTO_CRIMT(crto); -+ else -+ ready_timeout = NVME_CRTO_CRWMT(crto); -+ -+ if (ready_timeout < timeout) -+ dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n", -+ crto, ctrl->cap); -+ else -+ timeout = ready_timeout; -+ } -+ - ctrl->ctrl_config |= NVME_CC_ENABLE; - ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config); - if (ret) -diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c -index 871c4f32f443f..2d068439b129c 100644 ---- a/drivers/nvme/target/io-cmd-file.c -+++ b/drivers/nvme/target/io-cmd-file.c -@@ -73,13 +73,6 @@ err: - return ret; - } - --static void nvmet_file_init_bvec(struct bio_vec *bv, struct scatterlist *sg) --{ -- bv->bv_page = sg_page(sg); -- bv->bv_offset = sg->offset; -- bv->bv_len = sg->length; --} -- - static ssize_t nvmet_file_submit_bvec(struct nvmet_req *req, loff_t pos, - unsigned long nr_segs, size_t count, int ki_flags) - { -@@ -146,7 +139,8 @@ static bool nvmet_file_execute_io(struct nvmet_req *req, int ki_flags) - - memset(&req->f.iocb, 0, sizeof(struct kiocb)); - for_each_sg(req->sg, sg, req->sg_cnt, i) { -- nvmet_file_init_bvec(&req->f.bvec[bv_cnt], sg); -+ bvec_set_page(&req->f.bvec[bv_cnt], sg_page(sg), sg->length, -+ sg->offset); - len += req->f.bvec[bv_cnt].bv_len; - total_len += req->f.bvec[bv_cnt].bv_len; - bv_cnt++; -diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c -index cc05c094de221..5e29da94f72d6 100644 ---- a/drivers/nvme/target/tcp.c -+++ b/drivers/nvme/target/tcp.c -@@ -321,9 +321,8 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd) - while (length) { - u32 iov_len = min_t(u32, length, sg->length - sg_offset); - -- iov->bv_page = sg_page(sg); -- iov->bv_len = sg->length; -- iov->bv_offset = sg->offset + sg_offset; -+ bvec_set_page(iov, sg_page(sg), iov_len, -+ sg->offset + sg_offset); - - length -= iov_len; - sg = sg_next(sg); -diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c -index 47db2d20568ef..388354a8e31cf 100644 ---- a/drivers/pci/controller/dwc/pci-imx6.c -+++ b/drivers/pci/controller/dwc/pci-imx6.c -@@ -999,6 +999,7 @@ static void imx6_pcie_host_exit(struct dw_pcie_rp *pp) - - static const struct dw_pcie_host_ops imx6_pcie_host_ops = { - .host_init = imx6_pcie_host_init, -+ .host_deinit = imx6_pcie_host_exit, - }; - - static const struct dw_pcie_ops dw_pcie_ops = { -diff --git a/drivers/pci/controller/dwc/pcie-fu740.c b/drivers/pci/controller/dwc/pcie-fu740.c -index 0c90583c078bf..1e9b44b8bba48 100644 ---- a/drivers/pci/controller/dwc/pcie-fu740.c -+++ b/drivers/pci/controller/dwc/pcie-fu740.c -@@ -299,6 +299,7 @@ static int fu740_pcie_probe(struct platform_device *pdev) - pci->dev = dev; - pci->ops = &dw_pcie_ops; - pci->pp.ops = &fu740_pcie_host_ops; -+ pci->pp.num_vectors = MAX_MSI_IRQS; - - /* SiFive specific region: mgmt */ - afp->mgmt_base = devm_platform_ioremap_resource_byname(pdev, "mgmt"); -diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c -index d1eb17e3f1474..d4c9b888a79d7 100644 ---- a/drivers/pci/controller/vmd.c -+++ b/drivers/pci/controller/vmd.c -@@ -526,8 +526,23 @@ static void vmd_domain_reset(struct vmd_dev *vmd) - PCI_CLASS_BRIDGE_PCI)) - continue; - -- memset_io(base + PCI_IO_BASE, 0, -- PCI_ROM_ADDRESS1 - PCI_IO_BASE); -+ /* -+ * Temporarily disable the I/O range before updating -+ * PCI_IO_BASE. -+ */ -+ writel(0x0000ffff, base + PCI_IO_BASE_UPPER16); -+ /* Update lower 16 bits of I/O base/limit */ -+ writew(0x00f0, base + PCI_IO_BASE); -+ /* Update upper 16 bits of I/O base/limit */ -+ writel(0, base + PCI_IO_BASE_UPPER16); -+ -+ /* MMIO Base/Limit */ -+ writel(0x0000fff0, base + PCI_MEMORY_BASE); -+ -+ /* Prefetchable MMIO Base/Limit */ -+ writel(0, base + PCI_PREF_LIMIT_UPPER32); -+ writel(0x0000fff0, base + PCI_PREF_MEMORY_BASE); -+ writel(0xffffffff, base + PCI_PREF_BASE_UPPER32); - } - } - } -diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c -index 25a269d431e45..0e17c57ddb876 100644 ---- a/drivers/perf/arm_smmuv3_pmu.c -+++ b/drivers/perf/arm_smmuv3_pmu.c -@@ -115,6 +115,7 @@ - #define SMMU_PMCG_PA_SHIFT 12 - - #define SMMU_PMCG_EVCNTR_RDONLY BIT(0) -+#define SMMU_PMCG_HARDEN_DISABLE BIT(1) - - static int cpuhp_state_num; - -@@ -159,6 +160,20 @@ static inline void smmu_pmu_enable(struct pmu *pmu) - writel(SMMU_PMCG_CR_ENABLE, smmu_pmu->reg_base + SMMU_PMCG_CR); - } - -+static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu, -+ struct perf_event *event, int idx); -+ -+static inline void smmu_pmu_enable_quirk_hip08_09(struct pmu *pmu) -+{ -+ struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); -+ unsigned int idx; -+ -+ for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters) -+ smmu_pmu_apply_event_filter(smmu_pmu, smmu_pmu->events[idx], idx); -+ -+ smmu_pmu_enable(pmu); -+} -+ - static inline void smmu_pmu_disable(struct pmu *pmu) - { - struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); -@@ -167,6 +182,22 @@ static inline void smmu_pmu_disable(struct pmu *pmu) - writel(0, smmu_pmu->reg_base + SMMU_PMCG_IRQ_CTRL); - } - -+static inline void smmu_pmu_disable_quirk_hip08_09(struct pmu *pmu) -+{ -+ struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); -+ unsigned int idx; -+ -+ /* -+ * The global disable of PMU sometimes fail to stop the counting. -+ * Harden this by writing an invalid event type to each used counter -+ * to forcibly stop counting. -+ */ -+ for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters) -+ writel(0xffff, smmu_pmu->reg_base + SMMU_PMCG_EVTYPER(idx)); -+ -+ smmu_pmu_disable(pmu); -+} -+ - static inline void smmu_pmu_counter_set_value(struct smmu_pmu *smmu_pmu, - u32 idx, u64 value) - { -@@ -765,7 +796,10 @@ static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu) - switch (model) { - case IORT_SMMU_V3_PMCG_HISI_HIP08: - /* HiSilicon Erratum 162001800 */ -- smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY; -+ smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY | SMMU_PMCG_HARDEN_DISABLE; -+ break; -+ case IORT_SMMU_V3_PMCG_HISI_HIP09: -+ smmu_pmu->options |= SMMU_PMCG_HARDEN_DISABLE; - break; - } - -@@ -890,6 +924,16 @@ static int smmu_pmu_probe(struct platform_device *pdev) - if (!dev->of_node) - smmu_pmu_get_acpi_options(smmu_pmu); - -+ /* -+ * For platforms suffer this quirk, the PMU disable sometimes fails to -+ * stop the counters. This will leads to inaccurate or error counting. -+ * Forcibly disable the counters with these quirk handler. -+ */ -+ if (smmu_pmu->options & SMMU_PMCG_HARDEN_DISABLE) { -+ smmu_pmu->pmu.pmu_enable = smmu_pmu_enable_quirk_hip08_09; -+ smmu_pmu->pmu.pmu_disable = smmu_pmu_disable_quirk_hip08_09; -+ } -+ - /* Pick one CPU to be the preferred one to use */ - smmu_pmu->on_cpu = raw_smp_processor_id(); - WARN_ON(irq_set_affinity(smmu_pmu->irq, cpumask_of(smmu_pmu->on_cpu))); -diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c -index cd4ce2b4906d1..a4cda73b81c9f 100644 ---- a/drivers/perf/fsl_imx8_ddr_perf.c -+++ b/drivers/perf/fsl_imx8_ddr_perf.c -@@ -28,6 +28,8 @@ - #define CNTL_CLEAR_MASK 0xFFFFFFFD - #define CNTL_OVER_MASK 0xFFFFFFFE - -+#define CNTL_CP_SHIFT 16 -+#define CNTL_CP_MASK (0xFF << CNTL_CP_SHIFT) - #define CNTL_CSV_SHIFT 24 - #define CNTL_CSV_MASK (0xFFU << CNTL_CSV_SHIFT) - -@@ -35,6 +37,8 @@ - #define EVENT_CYCLES_COUNTER 0 - #define NUM_COUNTERS 4 - -+/* For removing bias if cycle counter CNTL.CP is set to 0xf0 */ -+#define CYCLES_COUNTER_MASK 0x0FFFFFFF - #define AXI_MASKING_REVERT 0xffff0000 /* AXI_MASKING(MSB 16bits) + AXI_ID(LSB 16bits) */ - - #define to_ddr_pmu(p) container_of(p, struct ddr_pmu, pmu) -@@ -429,6 +433,17 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config, - writel(0, pmu->base + reg); - val = CNTL_EN | CNTL_CLEAR; - val |= FIELD_PREP(CNTL_CSV_MASK, config); -+ -+ /* -+ * On i.MX8MP we need to bias the cycle counter to overflow more often. -+ * We do this by initializing bits [23:16] of the counter value via the -+ * COUNTER_CTRL Counter Parameter (CP) field. -+ */ -+ if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) { -+ if (counter == EVENT_CYCLES_COUNTER) -+ val |= FIELD_PREP(CNTL_CP_MASK, 0xf0); -+ } -+ - writel(val, pmu->base + reg); - } else { - /* Disable counter */ -@@ -468,6 +483,12 @@ static void ddr_perf_event_update(struct perf_event *event) - int ret; - - new_raw_count = ddr_perf_read_counter(pmu, counter); -+ /* Remove the bias applied in ddr_perf_counter_enable(). */ -+ if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) { -+ if (counter == EVENT_CYCLES_COUNTER) -+ new_raw_count &= CYCLES_COUNTER_MASK; -+ } -+ - local64_add(new_raw_count, &event->count); - - /* -diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h -index 9ad233b40a9e2..664ac3069c4be 100644 ---- a/drivers/scsi/lpfc/lpfc.h -+++ b/drivers/scsi/lpfc/lpfc.h -@@ -895,6 +895,7 @@ enum lpfc_irq_chann_mode { - enum lpfc_hba_bit_flags { - FABRIC_COMANDS_BLOCKED, - HBA_PCI_ERR, -+ MBX_TMO_ERR, - }; - - struct lpfc_hba { -diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c -index 3e365e5e194a2..250d423710ca4 100644 ---- a/drivers/scsi/lpfc/lpfc_debugfs.c -+++ b/drivers/scsi/lpfc/lpfc_debugfs.c -@@ -6069,7 +6069,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) - phba->hba_debugfs_root, - phba, - &lpfc_debugfs_op_multixripools); -- if (!phba->debug_multixri_pools) { -+ if (IS_ERR(phba->debug_multixri_pools)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0527 Cannot create debugfs multixripools\n"); - goto debug_failed; -@@ -6081,7 +6081,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) - debugfs_create_file(name, S_IFREG | 0644, - phba->hba_debugfs_root, - phba, &lpfc_cgn_buffer_op); -- if (!phba->debug_cgn_buffer) { -+ if (IS_ERR(phba->debug_cgn_buffer)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "6527 Cannot create debugfs " - "cgn_buffer\n"); -@@ -6094,7 +6094,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) - debugfs_create_file(name, S_IFREG | 0644, - phba->hba_debugfs_root, - phba, &lpfc_rx_monitor_op); -- if (!phba->debug_rx_monitor) { -+ if (IS_ERR(phba->debug_rx_monitor)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "6528 Cannot create debugfs " - "rx_monitor\n"); -@@ -6107,7 +6107,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) - debugfs_create_file(name, 0644, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_ras_log); -- if (!phba->debug_ras_log) { -+ if (IS_ERR(phba->debug_ras_log)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "6148 Cannot create debugfs" - " ras_log\n"); -@@ -6128,7 +6128,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) - debugfs_create_file(name, S_IFREG | 0644, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_lockstat); -- if (!phba->debug_lockstat) { -+ if (IS_ERR(phba->debug_lockstat)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "4610 Can't create debugfs lockstat\n"); - goto debug_failed; -@@ -6354,7 +6354,7 @@ nvmeio_off: - debugfs_create_file(name, 0644, - vport->vport_debugfs_root, - vport, &lpfc_debugfs_op_scsistat); -- if (!vport->debug_scsistat) { -+ if (IS_ERR(vport->debug_scsistat)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "4611 Cannot create debugfs scsistat\n"); - goto debug_failed; -@@ -6365,7 +6365,7 @@ nvmeio_off: - debugfs_create_file(name, 0644, - vport->vport_debugfs_root, - vport, &lpfc_debugfs_op_ioktime); -- if (!vport->debug_ioktime) { -+ if (IS_ERR(vport->debug_ioktime)) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0815 Cannot create debugfs ioktime\n"); - goto debug_failed; -diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c -index 43ebb41ded593..6b5ce9869e6b4 100644 ---- a/drivers/scsi/lpfc/lpfc_els.c -+++ b/drivers/scsi/lpfc/lpfc_els.c -@@ -9410,11 +9410,13 @@ void - lpfc_els_flush_cmd(struct lpfc_vport *vport) - { - LIST_HEAD(abort_list); -+ LIST_HEAD(cancel_list); - struct lpfc_hba *phba = vport->phba; - struct lpfc_sli_ring *pring; - struct lpfc_iocbq *tmp_iocb, *piocb; - u32 ulp_command; - unsigned long iflags = 0; -+ bool mbx_tmo_err; - - lpfc_fabric_abort_vport(vport); - -@@ -9436,15 +9438,16 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) - if (phba->sli_rev == LPFC_SLI_REV4) - spin_lock(&pring->ring_lock); - -+ mbx_tmo_err = test_bit(MBX_TMO_ERR, &phba->bit_flags); - /* First we need to issue aborts to outstanding cmds on txcmpl */ - list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { -- if (piocb->cmd_flag & LPFC_IO_LIBDFC) -+ if (piocb->cmd_flag & LPFC_IO_LIBDFC && !mbx_tmo_err) - continue; - - if (piocb->vport != vport) - continue; - -- if (piocb->cmd_flag & LPFC_DRIVER_ABORTED) -+ if (piocb->cmd_flag & LPFC_DRIVER_ABORTED && !mbx_tmo_err) - continue; - - /* On the ELS ring we can have ELS_REQUESTs or -@@ -9463,8 +9466,8 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) - */ - if (phba->link_state == LPFC_LINK_DOWN) - piocb->cmd_cmpl = lpfc_cmpl_els_link_down; -- } -- if (ulp_command == CMD_GEN_REQUEST64_CR) -+ } else if (ulp_command == CMD_GEN_REQUEST64_CR || -+ mbx_tmo_err) - list_add_tail(&piocb->dlist, &abort_list); - } - -@@ -9476,11 +9479,19 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) - list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) { - spin_lock_irqsave(&phba->hbalock, iflags); - list_del_init(&piocb->dlist); -- lpfc_sli_issue_abort_iotag(phba, pring, piocb, NULL); -+ if (mbx_tmo_err) -+ list_move_tail(&piocb->list, &cancel_list); -+ else -+ lpfc_sli_issue_abort_iotag(phba, pring, piocb, NULL); -+ - spin_unlock_irqrestore(&phba->hbalock, iflags); - } -- /* Make sure HBA is alive */ -- lpfc_issue_hb_tmo(phba); -+ if (!list_empty(&cancel_list)) -+ lpfc_sli_cancel_iocbs(phba, &cancel_list, IOSTAT_LOCAL_REJECT, -+ IOERR_SLI_ABORTED); -+ else -+ /* Make sure HBA is alive */ -+ lpfc_issue_hb_tmo(phba); - - if (!list_empty(&abort_list)) - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, -diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c -index d54fd153cb115..f59de61803dc8 100644 ---- a/drivers/scsi/lpfc/lpfc_init.c -+++ b/drivers/scsi/lpfc/lpfc_init.c -@@ -7563,6 +7563,8 @@ lpfc_disable_pci_dev(struct lpfc_hba *phba) - void - lpfc_reset_hba(struct lpfc_hba *phba) - { -+ int rc = 0; -+ - /* If resets are disabled then set error state and return. */ - if (!phba->cfg_enable_hba_reset) { - phba->link_state = LPFC_HBA_ERROR; -@@ -7573,13 +7575,25 @@ lpfc_reset_hba(struct lpfc_hba *phba) - if (phba->sli.sli_flag & LPFC_SLI_ACTIVE) { - lpfc_offline_prep(phba, LPFC_MBX_WAIT); - } else { -+ if (test_bit(MBX_TMO_ERR, &phba->bit_flags)) { -+ /* Perform a PCI function reset to start from clean */ -+ rc = lpfc_pci_function_reset(phba); -+ lpfc_els_flush_all_cmd(phba); -+ } - lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); - lpfc_sli_flush_io_rings(phba); - } - lpfc_offline(phba); -- lpfc_sli_brdrestart(phba); -- lpfc_online(phba); -- lpfc_unblock_mgmt_io(phba); -+ clear_bit(MBX_TMO_ERR, &phba->bit_flags); -+ if (unlikely(rc)) { -+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, -+ "8888 PCI function reset failed rc %x\n", -+ rc); -+ } else { -+ lpfc_sli_brdrestart(phba); -+ lpfc_online(phba); -+ lpfc_unblock_mgmt_io(phba); -+ } - } - - /** -diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c -index b44bb3ae22ad9..427a6ac803e50 100644 ---- a/drivers/scsi/lpfc/lpfc_sli.c -+++ b/drivers/scsi/lpfc/lpfc_sli.c -@@ -3919,6 +3919,8 @@ void lpfc_poll_eratt(struct timer_list *t) - uint64_t sli_intr, cnt; - - phba = from_timer(phba, t, eratt_poll); -+ if (!(phba->hba_flag & HBA_SETUP)) -+ return; - - /* Here we will also keep track of interrupts per sec of the hba */ - sli_intr = phba->sli.slistat.sli_intr; -@@ -7712,7 +7714,9 @@ lpfc_sli4_repost_sgl_list(struct lpfc_hba *phba, - spin_unlock_irq(&phba->hbalock); - } else { - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, -- "3161 Failure to post sgl to port.\n"); -+ "3161 Failure to post sgl to port,status %x " -+ "blkcnt %d totalcnt %d postcnt %d\n", -+ status, block_cnt, total_cnt, post_cnt); - return -EIO; - } - -@@ -8495,6 +8499,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) - spin_unlock_irq(&phba->hbalock); - } - } -+ phba->hba_flag &= ~HBA_SETUP; - - lpfc_sli4_dip(phba); - -@@ -9317,6 +9322,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) - * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing - * it to fail all outstanding SCSI IO. - */ -+ set_bit(MBX_TMO_ERR, &phba->bit_flags); - spin_lock_irq(&phba->pport->work_port_lock); - phba->pport->work_port_events &= ~WORKER_MBOX_TMO; - spin_unlock_irq(&phba->pport->work_port_lock); -diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h -index 2ef9d41fc6f42..e5215db9ee4d1 100644 ---- a/drivers/scsi/megaraid/megaraid_sas.h -+++ b/drivers/scsi/megaraid/megaraid_sas.h -@@ -2332,7 +2332,7 @@ struct megasas_instance { - u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */ - bool use_seqnum_jbod_fp; /* Added for PD sequence */ - bool smp_affinity_enable; -- spinlock_t crashdump_lock; -+ struct mutex crashdump_lock; - - struct megasas_register_set __iomem *reg_set; - u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; -diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c -index 13ee8e4c4f570..e392a984c7b87 100644 ---- a/drivers/scsi/megaraid/megaraid_sas_base.c -+++ b/drivers/scsi/megaraid/megaraid_sas_base.c -@@ -3272,14 +3272,13 @@ fw_crash_buffer_store(struct device *cdev, - struct megasas_instance *instance = - (struct megasas_instance *) shost->hostdata; - int val = 0; -- unsigned long flags; - - if (kstrtoint(buf, 0, &val) != 0) - return -EINVAL; - -- spin_lock_irqsave(&instance->crashdump_lock, flags); -+ mutex_lock(&instance->crashdump_lock); - instance->fw_crash_buffer_offset = val; -- spin_unlock_irqrestore(&instance->crashdump_lock, flags); -+ mutex_unlock(&instance->crashdump_lock); - return strlen(buf); - } - -@@ -3294,24 +3293,23 @@ fw_crash_buffer_show(struct device *cdev, - unsigned long dmachunk = CRASH_DMA_BUF_SIZE; - unsigned long chunk_left_bytes; - unsigned long src_addr; -- unsigned long flags; - u32 buff_offset; - -- spin_lock_irqsave(&instance->crashdump_lock, flags); -+ mutex_lock(&instance->crashdump_lock); - buff_offset = instance->fw_crash_buffer_offset; - if (!instance->crash_dump_buf || - !((instance->fw_crash_state == AVAILABLE) || - (instance->fw_crash_state == COPYING))) { - dev_err(&instance->pdev->dev, - "Firmware crash dump is not available\n"); -- spin_unlock_irqrestore(&instance->crashdump_lock, flags); -+ mutex_unlock(&instance->crashdump_lock); - return -EINVAL; - } - - if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) { - dev_err(&instance->pdev->dev, - "Firmware crash dump offset is out of range\n"); -- spin_unlock_irqrestore(&instance->crashdump_lock, flags); -+ mutex_unlock(&instance->crashdump_lock); - return 0; - } - -@@ -3323,7 +3321,7 @@ fw_crash_buffer_show(struct device *cdev, - src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] + - (buff_offset % dmachunk); - memcpy(buf, (void *)src_addr, size); -- spin_unlock_irqrestore(&instance->crashdump_lock, flags); -+ mutex_unlock(&instance->crashdump_lock); - - return size; - } -@@ -3348,7 +3346,6 @@ fw_crash_state_store(struct device *cdev, - struct megasas_instance *instance = - (struct megasas_instance *) shost->hostdata; - int val = 0; -- unsigned long flags; - - if (kstrtoint(buf, 0, &val) != 0) - return -EINVAL; -@@ -3362,9 +3359,9 @@ fw_crash_state_store(struct device *cdev, - instance->fw_crash_state = val; - - if ((val == COPIED) || (val == COPY_ERROR)) { -- spin_lock_irqsave(&instance->crashdump_lock, flags); -+ mutex_lock(&instance->crashdump_lock); - megasas_free_host_crash_buffer(instance); -- spin_unlock_irqrestore(&instance->crashdump_lock, flags); -+ mutex_unlock(&instance->crashdump_lock); - if (val == COPY_ERROR) - dev_info(&instance->pdev->dev, "application failed to " - "copy Firmware crash dump\n"); -@@ -7423,7 +7420,7 @@ static inline void megasas_init_ctrl_params(struct megasas_instance *instance) - init_waitqueue_head(&instance->int_cmd_wait_q); - init_waitqueue_head(&instance->abort_cmd_wait_q); - -- spin_lock_init(&instance->crashdump_lock); -+ mutex_init(&instance->crashdump_lock); - spin_lock_init(&instance->mfi_pool_lock); - spin_lock_init(&instance->hba_lock); - spin_lock_init(&instance->stream_lock); -diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c -index 7a7d63aa90e21..da65234add432 100644 ---- a/drivers/scsi/pm8001/pm8001_init.c -+++ b/drivers/scsi/pm8001/pm8001_init.c -@@ -274,7 +274,6 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id) - return ret; - } - --static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha); - static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha); - - /** -@@ -295,13 +294,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, - pm8001_dbg(pm8001_ha, INIT, "pm8001_alloc: PHY:%x\n", - pm8001_ha->chip->n_phy); - -- /* Setup Interrupt */ -- rc = pm8001_setup_irq(pm8001_ha); -- if (rc) { -- pm8001_dbg(pm8001_ha, FAIL, -- "pm8001_setup_irq failed [ret: %d]\n", rc); -- goto err_out; -- } - /* Request Interrupt */ - rc = pm8001_request_irq(pm8001_ha); - if (rc) -@@ -1021,47 +1013,38 @@ static u32 pm8001_request_msix(struct pm8001_hba_info *pm8001_ha) - } - #endif - --static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha) --{ -- struct pci_dev *pdev; -- -- pdev = pm8001_ha->pdev; -- --#ifdef PM8001_USE_MSIX -- if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) -- return pm8001_setup_msix(pm8001_ha); -- pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); --#endif -- return 0; --} -- - /** - * pm8001_request_irq - register interrupt - * @pm8001_ha: our ha struct. - */ - static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) - { -- struct pci_dev *pdev; -+ struct pci_dev *pdev = pm8001_ha->pdev; -+#ifdef PM8001_USE_MSIX - int rc; - -- pdev = pm8001_ha->pdev; -+ if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { -+ rc = pm8001_setup_msix(pm8001_ha); -+ if (rc) { -+ pm8001_dbg(pm8001_ha, FAIL, -+ "pm8001_setup_irq failed [ret: %d]\n", rc); -+ return rc; -+ } - --#ifdef PM8001_USE_MSIX -- if (pdev->msix_cap && pci_msi_enabled()) -- return pm8001_request_msix(pm8001_ha); -- else { -- pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); -- goto intx; -+ if (pdev->msix_cap && pci_msi_enabled()) -+ return pm8001_request_msix(pm8001_ha); - } -+ -+ pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); - #endif - --intx: - /* initialize the INT-X interrupt */ - pm8001_ha->irq_vector[0].irq_id = 0; - pm8001_ha->irq_vector[0].drv_inst = pm8001_ha; -- rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED, -- pm8001_ha->name, SHOST_TO_SAS_HA(pm8001_ha->shost)); -- return rc; -+ -+ return request_irq(pdev->irq, pm8001_interrupt_handler_intx, -+ IRQF_SHARED, pm8001_ha->name, -+ SHOST_TO_SAS_HA(pm8001_ha->shost)); - } - - /** -diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c -index f060e593685de..a7a364760b800 100644 ---- a/drivers/scsi/qla2xxx/qla_dfs.c -+++ b/drivers/scsi/qla2xxx/qla_dfs.c -@@ -116,7 +116,7 @@ qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp) - - sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name)); - fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root); -- if (!fp->dfs_rport_dir) -+ if (IS_ERR(fp->dfs_rport_dir)) - return; - if (NVME_TARGET(vha->hw, fp)) - debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir, -@@ -708,14 +708,14 @@ create_nodes: - if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) { - ha->tgt.dfs_naqp = debugfs_create_file("naqp", - 0400, ha->dfs_dir, vha, &dfs_naqp_ops); -- if (!ha->tgt.dfs_naqp) { -+ if (IS_ERR(ha->tgt.dfs_naqp)) { - ql_log(ql_log_warn, vha, 0xd011, - "Unable to create debugFS naqp node.\n"); - goto out; - } - } - vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir); -- if (!vha->dfs_rport_root) { -+ if (IS_ERR(vha->dfs_rport_root)) { - ql_log(ql_log_warn, vha, 0xd012, - "Unable to create debugFS rports node.\n"); - goto out; -diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c -index 5d0f51822414e..c142a67dc7cc2 100644 ---- a/drivers/target/iscsi/iscsi_target_configfs.c -+++ b/drivers/target/iscsi/iscsi_target_configfs.c -@@ -533,102 +533,102 @@ static ssize_t lio_target_nacl_info_show(struct config_item *item, char *page) - spin_lock_bh(&se_nacl->nacl_sess_lock); - se_sess = se_nacl->nacl_sess; - if (!se_sess) { -- rb += sprintf(page+rb, "No active iSCSI Session for Initiator" -+ rb += sysfs_emit_at(page, rb, "No active iSCSI Session for Initiator" - " Endpoint: %s\n", se_nacl->initiatorname); - } else { - sess = se_sess->fabric_sess_ptr; - -- rb += sprintf(page+rb, "InitiatorName: %s\n", -+ rb += sysfs_emit_at(page, rb, "InitiatorName: %s\n", - sess->sess_ops->InitiatorName); -- rb += sprintf(page+rb, "InitiatorAlias: %s\n", -+ rb += sysfs_emit_at(page, rb, "InitiatorAlias: %s\n", - sess->sess_ops->InitiatorAlias); - -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "LIO Session ID: %u ISID: 0x%6ph TSIH: %hu ", - sess->sid, sess->isid, sess->tsih); -- rb += sprintf(page+rb, "SessionType: %s\n", -+ rb += sysfs_emit_at(page, rb, "SessionType: %s\n", - (sess->sess_ops->SessionType) ? - "Discovery" : "Normal"); -- rb += sprintf(page+rb, "Session State: "); -+ rb += sysfs_emit_at(page, rb, "Session State: "); - switch (sess->session_state) { - case TARG_SESS_STATE_FREE: -- rb += sprintf(page+rb, "TARG_SESS_FREE\n"); -+ rb += sysfs_emit_at(page, rb, "TARG_SESS_FREE\n"); - break; - case TARG_SESS_STATE_ACTIVE: -- rb += sprintf(page+rb, "TARG_SESS_STATE_ACTIVE\n"); -+ rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_ACTIVE\n"); - break; - case TARG_SESS_STATE_LOGGED_IN: -- rb += sprintf(page+rb, "TARG_SESS_STATE_LOGGED_IN\n"); -+ rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_LOGGED_IN\n"); - break; - case TARG_SESS_STATE_FAILED: -- rb += sprintf(page+rb, "TARG_SESS_STATE_FAILED\n"); -+ rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_FAILED\n"); - break; - case TARG_SESS_STATE_IN_CONTINUE: -- rb += sprintf(page+rb, "TARG_SESS_STATE_IN_CONTINUE\n"); -+ rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_IN_CONTINUE\n"); - break; - default: -- rb += sprintf(page+rb, "ERROR: Unknown Session" -+ rb += sysfs_emit_at(page, rb, "ERROR: Unknown Session" - " State!\n"); - break; - } - -- rb += sprintf(page+rb, "---------------------[iSCSI Session" -+ rb += sysfs_emit_at(page, rb, "---------------------[iSCSI Session" - " Values]-----------------------\n"); -- rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN" -+ rb += sysfs_emit_at(page, rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN" - " : MaxCmdSN : ITT : TTT\n"); - max_cmd_sn = (u32) atomic_read(&sess->max_cmd_sn); -- rb += sprintf(page+rb, " 0x%08x 0x%08x 0x%08x 0x%08x" -+ rb += sysfs_emit_at(page, rb, " 0x%08x 0x%08x 0x%08x 0x%08x" - " 0x%08x 0x%08x\n", - sess->cmdsn_window, - (max_cmd_sn - sess->exp_cmd_sn) + 1, - sess->exp_cmd_sn, max_cmd_sn, - sess->init_task_tag, sess->targ_xfer_tag); -- rb += sprintf(page+rb, "----------------------[iSCSI" -+ rb += sysfs_emit_at(page, rb, "----------------------[iSCSI" - " Connections]-------------------------\n"); - - spin_lock(&sess->conn_lock); - list_for_each_entry(conn, &sess->sess_conn_list, conn_list) { -- rb += sprintf(page+rb, "CID: %hu Connection" -+ rb += sysfs_emit_at(page, rb, "CID: %hu Connection" - " State: ", conn->cid); - switch (conn->conn_state) { - case TARG_CONN_STATE_FREE: -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "TARG_CONN_STATE_FREE\n"); - break; - case TARG_CONN_STATE_XPT_UP: -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "TARG_CONN_STATE_XPT_UP\n"); - break; - case TARG_CONN_STATE_IN_LOGIN: -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "TARG_CONN_STATE_IN_LOGIN\n"); - break; - case TARG_CONN_STATE_LOGGED_IN: -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "TARG_CONN_STATE_LOGGED_IN\n"); - break; - case TARG_CONN_STATE_IN_LOGOUT: -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "TARG_CONN_STATE_IN_LOGOUT\n"); - break; - case TARG_CONN_STATE_LOGOUT_REQUESTED: -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "TARG_CONN_STATE_LOGOUT_REQUESTED\n"); - break; - case TARG_CONN_STATE_CLEANUP_WAIT: -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "TARG_CONN_STATE_CLEANUP_WAIT\n"); - break; - default: -- rb += sprintf(page+rb, -+ rb += sysfs_emit_at(page, rb, - "ERROR: Unknown Connection State!\n"); - break; - } - -- rb += sprintf(page+rb, " Address %pISc %s", &conn->login_sockaddr, -+ rb += sysfs_emit_at(page, rb, " Address %pISc %s", &conn->login_sockaddr, - (conn->network_transport == ISCSI_TCP) ? - "TCP" : "SCTP"); -- rb += sprintf(page+rb, " StatSN: 0x%08x\n", -+ rb += sysfs_emit_at(page, rb, " StatSN: 0x%08x\n", - conn->stat_sn); - } - spin_unlock(&sess->conn_lock); -diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c -index 687adc9e086ca..0686882bcbda3 100644 ---- a/drivers/target/target_core_transport.c -+++ b/drivers/target/target_core_transport.c -@@ -264,6 +264,7 @@ void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt) - percpu_ref_put(&cmd_cnt->refcnt); - - percpu_ref_exit(&cmd_cnt->refcnt); -+ kfree(cmd_cnt); - } - EXPORT_SYMBOL_GPL(target_free_cmd_counter); - -diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c -index b4369ed45ae2d..bb25691f50007 100644 ---- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c -+++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c -@@ -1257,19 +1257,14 @@ static void cpm_uart_console_write(struct console *co, const char *s, - { - struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; - unsigned long flags; -- int nolock = oops_in_progress; - -- if (unlikely(nolock)) { -+ if (unlikely(oops_in_progress)) { - local_irq_save(flags); -- } else { -- spin_lock_irqsave(&pinfo->port.lock, flags); -- } -- -- cpm_uart_early_write(pinfo, s, count, true); -- -- if (unlikely(nolock)) { -+ cpm_uart_early_write(pinfo, s, count, true); - local_irq_restore(flags); - } else { -+ spin_lock_irqsave(&pinfo->port.lock, flags); -+ cpm_uart_early_write(pinfo, s, count, true); - spin_unlock_irqrestore(&pinfo->port.lock, flags); - } - } -diff --git a/drivers/usb/cdns3/cdns3-plat.c b/drivers/usb/cdns3/cdns3-plat.c -index 2bc5d094548b6..726b2e4f67e4d 100644 ---- a/drivers/usb/cdns3/cdns3-plat.c -+++ b/drivers/usb/cdns3/cdns3-plat.c -@@ -256,9 +256,10 @@ static int cdns3_controller_resume(struct device *dev, pm_message_t msg) - cdns3_set_platform_suspend(cdns->dev, false, false); - - spin_lock_irqsave(&cdns->lock, flags); -- cdns_resume(cdns, !PMSG_IS_AUTO(msg)); -+ cdns_resume(cdns); - cdns->in_lpm = false; - spin_unlock_irqrestore(&cdns->lock, flags); -+ cdns_set_active(cdns, !PMSG_IS_AUTO(msg)); - if (cdns->wakeup_pending) { - cdns->wakeup_pending = false; - enable_irq(cdns->wakeup_irq); -diff --git a/drivers/usb/cdns3/cdnsp-pci.c b/drivers/usb/cdns3/cdnsp-pci.c -index 29f433c5a6f3f..a85db23fa19f2 100644 ---- a/drivers/usb/cdns3/cdnsp-pci.c -+++ b/drivers/usb/cdns3/cdnsp-pci.c -@@ -210,8 +210,9 @@ static int __maybe_unused cdnsp_pci_resume(struct device *dev) - int ret; - - spin_lock_irqsave(&cdns->lock, flags); -- ret = cdns_resume(cdns, 1); -+ ret = cdns_resume(cdns); - spin_unlock_irqrestore(&cdns->lock, flags); -+ cdns_set_active(cdns, 1); - - return ret; - } -diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c -index dbcdf3b24b477..7b20d2d5c262e 100644 ---- a/drivers/usb/cdns3/core.c -+++ b/drivers/usb/cdns3/core.c -@@ -522,9 +522,8 @@ int cdns_suspend(struct cdns *cdns) - } - EXPORT_SYMBOL_GPL(cdns_suspend); - --int cdns_resume(struct cdns *cdns, u8 set_active) -+int cdns_resume(struct cdns *cdns) - { -- struct device *dev = cdns->dev; - enum usb_role real_role; - bool role_changed = false; - int ret = 0; -@@ -556,15 +555,23 @@ int cdns_resume(struct cdns *cdns, u8 set_active) - if (cdns->roles[cdns->role]->resume) - cdns->roles[cdns->role]->resume(cdns, cdns_power_is_lost(cdns)); - -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cdns_resume); -+ -+void cdns_set_active(struct cdns *cdns, u8 set_active) -+{ -+ struct device *dev = cdns->dev; -+ - if (set_active) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } - -- return 0; -+ return; - } --EXPORT_SYMBOL_GPL(cdns_resume); -+EXPORT_SYMBOL_GPL(cdns_set_active); - #endif /* CONFIG_PM_SLEEP */ - - MODULE_AUTHOR("Peter Chen "); -diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h -index 2d332a788871e..4a4dbc2c15615 100644 ---- a/drivers/usb/cdns3/core.h -+++ b/drivers/usb/cdns3/core.h -@@ -125,10 +125,13 @@ int cdns_init(struct cdns *cdns); - int cdns_remove(struct cdns *cdns); - - #ifdef CONFIG_PM_SLEEP --int cdns_resume(struct cdns *cdns, u8 set_active); -+int cdns_resume(struct cdns *cdns); - int cdns_suspend(struct cdns *cdns); -+void cdns_set_active(struct cdns *cdns, u8 set_active); - #else /* CONFIG_PM_SLEEP */ --static inline int cdns_resume(struct cdns *cdns, u8 set_active) -+static inline int cdns_resume(struct cdns *cdns) -+{ return 0; } -+static inline int cdns_set_active(struct cdns *cdns, u8 set_active) - { return 0; } - static inline int cdns_suspend(struct cdns *cdns) - { return 0; } -diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h -index 85a803c135ab3..2ff83911219f8 100644 ---- a/drivers/usb/chipidea/ci.h -+++ b/drivers/usb/chipidea/ci.h -@@ -253,6 +253,7 @@ struct ci_hdrc { - bool id_event; - bool b_sess_valid_event; - bool imx28_write_fix; -+ bool has_portsc_pec_bug; - bool supports_runtime_pm; - bool in_lpm; - bool wakeup_int; -diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c -index caa91117ba429..984087bbf3e2b 100644 ---- a/drivers/usb/chipidea/ci_hdrc_imx.c -+++ b/drivers/usb/chipidea/ci_hdrc_imx.c -@@ -67,11 +67,13 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = { - - static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = { - .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | -+ CI_HDRC_HAS_PORTSC_PEC_MISSED | - CI_HDRC_PMQOS, - }; - - static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = { -- .flags = CI_HDRC_SUPPORTS_RUNTIME_PM, -+ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | -+ CI_HDRC_HAS_PORTSC_PEC_MISSED, - }; - - static const struct of_device_id ci_hdrc_imx_dt_ids[] = { -diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c -index 71f172ecfaabc..b9227f41cf1c0 100644 ---- a/drivers/usb/chipidea/core.c -+++ b/drivers/usb/chipidea/core.c -@@ -1038,6 +1038,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) - CI_HDRC_IMX28_WRITE_FIX); - ci->supports_runtime_pm = !!(ci->platdata->flags & - CI_HDRC_SUPPORTS_RUNTIME_PM); -+ ci->has_portsc_pec_bug = !!(ci->platdata->flags & -+ CI_HDRC_HAS_PORTSC_PEC_MISSED); - platform_set_drvdata(pdev, ci); - - ret = hw_device_init(ci, base); -diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c -index bc3634a54c6b7..3b08c5e811707 100644 ---- a/drivers/usb/chipidea/host.c -+++ b/drivers/usb/chipidea/host.c -@@ -151,6 +151,7 @@ static int host_start(struct ci_hdrc *ci) - ehci->has_hostpc = ci->hw_bank.lpm; - ehci->has_tdi_phy_lpm = ci->hw_bank.lpm; - ehci->imx28_write_fix = ci->imx28_write_fix; -+ ehci->has_ci_pec_bug = ci->has_portsc_pec_bug; - - priv = (struct ehci_ci_priv *)ehci->priv; - priv->reg_vbus = NULL; -diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c -index 3b1cc8fa30c83..72b6d74b34982 100644 ---- a/drivers/usb/gadget/udc/fsl_qe_udc.c -+++ b/drivers/usb/gadget/udc/fsl_qe_udc.c -@@ -1959,9 +1959,13 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value, - } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { - /* Get endpoint status */ - int pipe = index & USB_ENDPOINT_NUMBER_MASK; -- struct qe_ep *target_ep = &udc->eps[pipe]; -+ struct qe_ep *target_ep; - u16 usep; - -+ if (pipe >= USB_MAX_ENDPOINTS) -+ goto stall; -+ target_ep = &udc->eps[pipe]; -+ - /* stall if endpoint doesn't exist */ - if (!target_ep->ep.desc) - goto stall; -diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c -index a1930db0da1c3..802bfafb1012b 100644 ---- a/drivers/usb/host/ehci-hcd.c -+++ b/drivers/usb/host/ehci-hcd.c -@@ -755,10 +755,14 @@ restart: - - /* normal [4.15.1.2] or error [4.15.1.1] completion */ - if (likely ((status & (STS_INT|STS_ERR)) != 0)) { -- if (likely ((status & STS_ERR) == 0)) -+ if (likely ((status & STS_ERR) == 0)) { - INCR(ehci->stats.normal); -- else -+ } else { -+ /* Force to check port status */ -+ if (ehci->has_ci_pec_bug) -+ status |= STS_PCD; - INCR(ehci->stats.error); -+ } - bh = 1; - } - -diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c -index efe30e3be22f7..1aee392e84927 100644 ---- a/drivers/usb/host/ehci-hub.c -+++ b/drivers/usb/host/ehci-hub.c -@@ -674,7 +674,8 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) - - if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend) - || (ehci->reset_done[i] && time_after_eq( -- jiffies, ehci->reset_done[i]))) { -+ jiffies, ehci->reset_done[i])) -+ || ehci_has_ci_pec_bug(ehci, temp)) { - if (i < 7) - buf [0] |= 1 << (i + 1); - else -@@ -875,6 +876,13 @@ int ehci_hub_control( - if (temp & PORT_PEC) - status |= USB_PORT_STAT_C_ENABLE << 16; - -+ if (ehci_has_ci_pec_bug(ehci, temp)) { -+ status |= USB_PORT_STAT_C_ENABLE << 16; -+ ehci_info(ehci, -+ "PE is cleared by HW port:%d PORTSC:%08x\n", -+ wIndex + 1, temp); -+ } -+ - if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){ - status |= USB_PORT_STAT_C_OVERCURRENT << 16; - -diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h -index ad3f13a3eaf1b..5c0e25742e179 100644 ---- a/drivers/usb/host/ehci.h -+++ b/drivers/usb/host/ehci.h -@@ -207,6 +207,7 @@ struct ehci_hcd { /* one per controller */ - unsigned has_fsl_port_bug:1; /* FreeScale */ - unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */ - unsigned has_fsl_susp_errata:1; /* NXP SUSP quirk */ -+ unsigned has_ci_pec_bug:1; /* ChipIdea PEC bug */ - unsigned big_endian_mmio:1; - unsigned big_endian_desc:1; - unsigned big_endian_capbase:1; -@@ -707,6 +708,15 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) - */ - #define ehci_has_fsl_susp_errata(e) ((e)->has_fsl_susp_errata) - -+/* -+ * Some Freescale/NXP processors using ChipIdea IP have a bug in which -+ * disabling the port (PE is cleared) does not cause PEC to be asserted -+ * when frame babble is detected. -+ */ -+#define ehci_has_ci_pec_bug(e, portsc) \ -+ ((e)->has_ci_pec_bug && ((e)->command & CMD_PSE) \ -+ && !(portsc & PORT_PEC) && !(portsc & PORT_PE)) -+ - /* - * While most USB host controllers implement their registers in - * little-endian format, a minority (celleb companion chip) implement -diff --git a/fs/attr.c b/fs/attr.c -index 9b9a70e0cc54f..3172f57f71f8d 100644 ---- a/fs/attr.c -+++ b/fs/attr.c -@@ -394,9 +394,25 @@ int notify_change(struct user_namespace *mnt_userns, struct dentry *dentry, - return error; - - if ((ia_valid & ATTR_MODE)) { -- umode_t amode = attr->ia_mode; -+ /* -+ * Don't allow changing the mode of symlinks: -+ * -+ * (1) The vfs doesn't take the mode of symlinks into account -+ * during permission checking. -+ * (2) This has never worked correctly. Most major filesystems -+ * did return EOPNOTSUPP due to interactions with POSIX ACLs -+ * but did still updated the mode of the symlink. -+ * This inconsistency led system call wrapper providers such -+ * as libc to block changing the mode of symlinks with -+ * EOPNOTSUPP already. -+ * (3) To even do this in the first place one would have to use -+ * specific file descriptors and quite some effort. -+ */ -+ if (S_ISLNK(inode->i_mode)) -+ return -EOPNOTSUPP; -+ - /* Flag setting protected by i_mutex */ -- if (is_sxid(amode)) -+ if (is_sxid(attr->ia_mode)) - inode->i_flags &= ~S_NOSEC; - } - -diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c -index 54c1f8b8b0757..efdc76732faed 100644 ---- a/fs/autofs/waitq.c -+++ b/fs/autofs/waitq.c -@@ -32,8 +32,9 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi) - wq->status = -ENOENT; /* Magic is gone - report failure */ - kfree(wq->name.name - wq->offset); - wq->name.name = NULL; -- wq->wait_ctr--; - wake_up_interruptible(&wq->queue); -+ if (!--wq->wait_ctr) -+ kfree(wq); - wq = nwq; - } - fput(sbi->pipe); /* Close the pipe */ -diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c -index cac5169eaf8de..d2cbb7733c7d6 100644 ---- a/fs/btrfs/delayed-inode.c -+++ b/fs/btrfs/delayed-inode.c -@@ -1148,20 +1148,33 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, int nr) - ret = __btrfs_commit_inode_delayed_items(trans, path, - curr_node); - if (ret) { -- btrfs_release_delayed_node(curr_node); -- curr_node = NULL; - btrfs_abort_transaction(trans, ret); - break; - } - - prev_node = curr_node; - curr_node = btrfs_next_delayed_node(curr_node); -+ /* -+ * See the comment below about releasing path before releasing -+ * node. If the commit of delayed items was successful the path -+ * should always be released, but in case of an error, it may -+ * point to locked extent buffers (a leaf at the very least). -+ */ -+ ASSERT(path->nodes[0] == NULL); - btrfs_release_delayed_node(prev_node); - } - -+ /* -+ * Release the path to avoid a potential deadlock and lockdep splat when -+ * releasing the delayed node, as that requires taking the delayed node's -+ * mutex. If another task starts running delayed items before we take -+ * the mutex, it will first lock the mutex and then it may try to lock -+ * the same btree path (leaf). -+ */ -+ btrfs_free_path(path); -+ - if (curr_node) - btrfs_release_delayed_node(curr_node); -- btrfs_free_path(path); - trans->block_rsv = block_rsv; - - return ret; -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index 64daae693afd1..d1dae29a3d012 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -859,6 +859,7 @@ static bool btree_dirty_folio(struct address_space *mapping, - struct folio *folio) - { - struct btrfs_fs_info *fs_info = btrfs_sb(mapping->host->i_sb); -+ struct btrfs_subpage_info *spi = fs_info->subpage_info; - struct btrfs_subpage *subpage; - struct extent_buffer *eb; - int cur_bit = 0; -@@ -872,18 +873,19 @@ static bool btree_dirty_folio(struct address_space *mapping, - btrfs_assert_tree_write_locked(eb); - return filemap_dirty_folio(mapping, folio); - } -+ -+ ASSERT(spi); - subpage = folio_get_private(folio); - -- ASSERT(subpage->dirty_bitmap); -- while (cur_bit < BTRFS_SUBPAGE_BITMAP_SIZE) { -+ for (cur_bit = spi->dirty_offset; -+ cur_bit < spi->dirty_offset + spi->bitmap_nr_bits; -+ cur_bit++) { - unsigned long flags; - u64 cur; -- u16 tmp = (1 << cur_bit); - - spin_lock_irqsave(&subpage->lock, flags); -- if (!(tmp & subpage->dirty_bitmap)) { -+ if (!test_bit(cur_bit, subpage->bitmaps)) { - spin_unlock_irqrestore(&subpage->lock, flags); -- cur_bit++; - continue; - } - spin_unlock_irqrestore(&subpage->lock, flags); -@@ -896,7 +898,7 @@ static bool btree_dirty_folio(struct address_space *mapping, - btrfs_assert_tree_write_locked(eb); - free_extent_buffer(eb); - -- cur_bit += (fs_info->nodesize >> fs_info->sectorsize_bits); -+ cur_bit += (fs_info->nodesize >> fs_info->sectorsize_bits) - 1; - } - return filemap_dirty_folio(mapping, folio); - } -@@ -2728,13 +2730,11 @@ int btrfs_validate_super(struct btrfs_fs_info *fs_info, - ret = -EINVAL; - } - -- if (btrfs_fs_incompat(fs_info, METADATA_UUID) && -- memcmp(fs_info->fs_devices->metadata_uuid, -- fs_info->super_copy->metadata_uuid, BTRFS_FSID_SIZE)) { -+ if (memcmp(fs_info->fs_devices->metadata_uuid, btrfs_sb_fsid_ptr(sb), -+ BTRFS_FSID_SIZE) != 0) { - btrfs_err(fs_info, - "superblock metadata_uuid doesn't match metadata uuid of fs_devices: %pU != %pU", -- fs_info->super_copy->metadata_uuid, -- fs_info->fs_devices->metadata_uuid); -+ btrfs_sb_fsid_ptr(sb), fs_info->fs_devices->metadata_uuid); - ret = -EINVAL; - } - -diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c -index 0640ef59fe660..08ff10a81cb90 100644 ---- a/fs/btrfs/extent-tree.c -+++ b/fs/btrfs/extent-tree.c -@@ -863,6 +863,11 @@ again: - err = -ENOENT; - goto out; - } else if (WARN_ON(ret)) { -+ btrfs_print_leaf(path->nodes[0]); -+ btrfs_err(fs_info, -+"extent item not found for insert, bytenr %llu num_bytes %llu parent %llu root_objectid %llu owner %llu offset %llu", -+ bytenr, num_bytes, parent, root_objectid, owner, -+ offset); - err = -EIO; - goto out; - } -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index 9de647e48e7eb..2e29fafe0e7d9 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -2850,6 +2850,13 @@ static int btrfs_search_path_in_tree_user(struct user_namespace *mnt_userns, - goto out_put; - } - -+ /* -+ * We don't need the path anymore, so release it and -+ * avoid deadlocks and lockdep warnings in case -+ * btrfs_iget() needs to lookup the inode from its root -+ * btree and lock the same leaf. -+ */ -+ btrfs_release_path(path); - temp_inode = btrfs_iget(sb, key2.objectid, root); - if (IS_ERR(temp_inode)) { - ret = PTR_ERR(temp_inode); -@@ -2870,7 +2877,6 @@ static int btrfs_search_path_in_tree_user(struct user_namespace *mnt_userns, - goto out_put; - } - -- btrfs_release_path(path); - key.objectid = key.offset; - key.offset = (u64)-1; - dirid = key.objectid; -diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c -index e54f8280031fa..bd0c7157e3878 100644 ---- a/fs/btrfs/ordered-data.c -+++ b/fs/btrfs/ordered-data.c -@@ -580,7 +580,7 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode, - refcount_inc(&trans->use_count); - spin_unlock(&fs_info->trans_lock); - -- ASSERT(trans); -+ ASSERT(trans || BTRFS_FS_ERROR(fs_info)); - if (trans) { - if (atomic_dec_and_test(&trans->pending_ordered)) - wake_up(&trans->pending_wait); -diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c -index 567c5c010f931..a40ebd2321d01 100644 ---- a/fs/btrfs/volumes.c -+++ b/fs/btrfs/volumes.c -@@ -663,6 +663,14 @@ error_free_page: - return -EINVAL; - } - -+u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb) -+{ -+ bool has_metadata_uuid = (btrfs_super_incompat_flags(sb) & -+ BTRFS_FEATURE_INCOMPAT_METADATA_UUID); -+ -+ return has_metadata_uuid ? sb->metadata_uuid : sb->fsid; -+} -+ - /* - * Handle scanned device having its CHANGING_FSID_V2 flag set and the fs_devices - * being created with a disk that has already completed its fsid change. Such -diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h -index 099def5613b87..ec2260177038e 100644 ---- a/fs/btrfs/volumes.h -+++ b/fs/btrfs/volumes.h -@@ -757,5 +757,6 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info); - bool btrfs_repair_one_zone(struct btrfs_fs_info *fs_info, u64 logical); - - bool btrfs_pinned_by_swapfile(struct btrfs_fs_info *fs_info, void *ptr); -+u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb); - - #endif -diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c -index 641abfa4b718a..2f89b1073307b 100644 ---- a/fs/ext2/xattr.c -+++ b/fs/ext2/xattr.c -@@ -744,10 +744,10 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, - /* We need to allocate a new block */ - ext2_fsblk_t goal = ext2_group_first_block_no(sb, - EXT2_I(inode)->i_block_group); -- int block = ext2_new_block(inode, goal, &error); -+ ext2_fsblk_t block = ext2_new_block(inode, goal, &error); - if (error) - goto cleanup; -- ea_idebug(inode, "creating block %d", block); -+ ea_idebug(inode, "creating block %lu", block); - - new_bh = sb_getblk(sb, block); - if (unlikely(!new_bh)) { -diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c -index 6a08fc31a66de..bbfb37390723c 100644 ---- a/fs/ext4/namei.c -+++ b/fs/ext4/namei.c -@@ -343,17 +343,17 @@ static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode, - struct buffer_head *bh) - { - struct ext4_dir_entry_tail *t; -+ int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); - - #ifdef PARANOID - struct ext4_dir_entry *d, *top; - - d = (struct ext4_dir_entry *)bh->b_data; - top = (struct ext4_dir_entry *)(bh->b_data + -- (EXT4_BLOCK_SIZE(inode->i_sb) - -- sizeof(struct ext4_dir_entry_tail))); -- while (d < top && d->rec_len) -+ (blocksize - sizeof(struct ext4_dir_entry_tail))); -+ while (d < top && ext4_rec_len_from_disk(d->rec_len, blocksize)) - d = (struct ext4_dir_entry *)(((void *)d) + -- le16_to_cpu(d->rec_len)); -+ ext4_rec_len_from_disk(d->rec_len, blocksize)); - - if (d != top) - return NULL; -@@ -364,7 +364,8 @@ static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode, - #endif - - if (t->det_reserved_zero1 || -- le16_to_cpu(t->det_rec_len) != sizeof(struct ext4_dir_entry_tail) || -+ (ext4_rec_len_from_disk(t->det_rec_len, blocksize) != -+ sizeof(struct ext4_dir_entry_tail)) || - t->det_reserved_zero2 || - t->det_reserved_ft != EXT4_FT_DIR_CSUM) - return NULL; -@@ -445,13 +446,14 @@ static struct dx_countlimit *get_dx_countlimit(struct inode *inode, - struct ext4_dir_entry *dp; - struct dx_root_info *root; - int count_offset; -+ int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); -+ unsigned int rlen = ext4_rec_len_from_disk(dirent->rec_len, blocksize); - -- if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)) -+ if (rlen == blocksize) - count_offset = 8; -- else if (le16_to_cpu(dirent->rec_len) == 12) { -+ else if (rlen == 12) { - dp = (struct ext4_dir_entry *)(((void *)dirent) + 12); -- if (le16_to_cpu(dp->rec_len) != -- EXT4_BLOCK_SIZE(inode->i_sb) - 12) -+ if (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12) - return NULL; - root = (struct dx_root_info *)(((void *)dp + 12)); - if (root->reserved_zero || -@@ -1315,6 +1317,7 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh, - unsigned int buflen = bh->b_size; - char *base = bh->b_data; - struct dx_hash_info h = *hinfo; -+ int blocksize = EXT4_BLOCK_SIZE(dir->i_sb); - - if (ext4_has_metadata_csum(dir->i_sb)) - buflen -= sizeof(struct ext4_dir_entry_tail); -@@ -1335,11 +1338,12 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh, - map_tail--; - map_tail->hash = h.hash; - map_tail->offs = ((char *) de - base)>>2; -- map_tail->size = le16_to_cpu(de->rec_len); -+ map_tail->size = ext4_rec_len_from_disk(de->rec_len, -+ blocksize); - count++; - cond_resched(); - } -- de = ext4_next_entry(de, dir->i_sb->s_blocksize); -+ de = ext4_next_entry(de, blocksize); - } - return count; - } -diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c -index bd4ef43b02033..e9d075cbd71ad 100644 ---- a/fs/jfs/jfs_dmap.c -+++ b/fs/jfs/jfs_dmap.c -@@ -269,6 +269,7 @@ int dbUnmount(struct inode *ipbmap, int mounterror) - - /* free the memory for the in-memory bmap. */ - kfree(bmp); -+ JFS_SBI(ipbmap->i_sb)->bmap = NULL; - - return (0); - } -diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c -index 799d3837e7c2b..4899663996d81 100644 ---- a/fs/jfs/jfs_imap.c -+++ b/fs/jfs/jfs_imap.c -@@ -193,6 +193,7 @@ int diUnmount(struct inode *ipimap, int mounterror) - * free in-memory control structure - */ - kfree(imap); -+ JFS_IP(ipimap)->i_imap = NULL; - - return (0); - } -diff --git a/fs/locks.c b/fs/locks.c -index 240b9309ed6d5..1047ab2b15e96 100644 ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -1300,6 +1300,7 @@ retry: - out: - spin_unlock(&ctx->flc_lock); - percpu_up_read(&file_rwsem); -+ trace_posix_lock_inode(inode, request, error); - /* - * Free any unused locks. - */ -@@ -1308,7 +1309,6 @@ retry: - if (new_fl2) - locks_free_lock(new_fl2); - locks_dispose_list(&dispose); -- trace_posix_lock_inode(inode, request, error); - - return error; - } -diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c -index a90e792a94d77..a9105e95b59c5 100644 ---- a/fs/nfsd/nfs4proc.c -+++ b/fs/nfsd/nfs4proc.c -@@ -1029,8 +1029,8 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - rename->rn_tname, rename->rn_tnamelen); - if (status) - return status; -- set_change_info(&rename->rn_sinfo, &cstate->current_fh); -- set_change_info(&rename->rn_tinfo, &cstate->save_fh); -+ set_change_info(&rename->rn_sinfo, &cstate->save_fh); -+ set_change_info(&rename->rn_tinfo, &cstate->current_fh); - return nfs_ok; - } - -diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c -index edc1ebff33f5a..e6d711f42607b 100644 ---- a/fs/overlayfs/copy_up.c -+++ b/fs/overlayfs/copy_up.c -@@ -580,7 +580,8 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp) - if (err) - return err; - -- if (inode->i_flags & OVL_COPY_I_FLAGS_MASK) { -+ if (inode->i_flags & OVL_COPY_I_FLAGS_MASK && -+ (S_ISREG(c->stat.mode) || S_ISDIR(c->stat.mode))) { - /* - * Copy the fileattr inode flags that are the source of already - * copied i_flags -diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c -index 6011f955436ba..cc0c077165bde 100644 ---- a/fs/overlayfs/file.c -+++ b/fs/overlayfs/file.c -@@ -19,7 +19,6 @@ struct ovl_aio_req { - struct kiocb iocb; - refcount_t ref; - struct kiocb *orig_iocb; -- struct fd fd; - }; - - static struct kmem_cache *ovl_aio_request_cachep; -@@ -260,7 +259,7 @@ static rwf_t ovl_iocb_to_rwf(int ifl) - static inline void ovl_aio_put(struct ovl_aio_req *aio_req) - { - if (refcount_dec_and_test(&aio_req->ref)) { -- fdput(aio_req->fd); -+ fput(aio_req->iocb.ki_filp); - kmem_cache_free(ovl_aio_request_cachep, aio_req); - } - } -@@ -325,10 +324,9 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter) - if (!aio_req) - goto out; - -- aio_req->fd = real; - real.flags = 0; - aio_req->orig_iocb = iocb; -- kiocb_clone(&aio_req->iocb, iocb, real.file); -+ kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); - aio_req->iocb.ki_complete = ovl_aio_rw_complete; - refcount_set(&aio_req->ref, 2); - ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter); -@@ -396,10 +394,9 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) - /* Pacify lockdep, same trick as done in aio_write() */ - __sb_writers_release(file_inode(real.file)->i_sb, - SB_FREEZE_WRITE); -- aio_req->fd = real; - real.flags = 0; - aio_req->orig_iocb = iocb; -- kiocb_clone(&aio_req->iocb, iocb, real.file); -+ kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); - aio_req->iocb.ki_flags = ifl; - aio_req->iocb.ki_complete = ovl_aio_rw_complete; - refcount_set(&aio_req->ref, 2); -diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c -index da85b39791957..6541d917e15e1 100644 ---- a/fs/tracefs/inode.c -+++ b/fs/tracefs/inode.c -@@ -556,6 +556,9 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, - */ - struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) - { -+ if (security_locked_down(LOCKDOWN_TRACEFS)) -+ return NULL; -+ - return __create_dir(name, parent, &simple_dir_inode_operations); - } - -diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h -index b43be0987b19e..a2a51fafa3550 100644 ---- a/include/linux/acpi_iort.h -+++ b/include/linux/acpi_iort.h -@@ -21,6 +21,7 @@ - */ - #define IORT_SMMU_V3_PMCG_GENERIC 0x00000000 /* Generic SMMUv3 PMCG */ - #define IORT_SMMU_V3_PMCG_HISI_HIP08 0x00000001 /* HiSilicon HIP08 PMCG */ -+#define IORT_SMMU_V3_PMCG_HISI_HIP09 0x00000002 /* HiSilicon HIP09 PMCG */ - - int iort_register_domain_token(int trans_id, phys_addr_t base, - struct fwnode_handle *fw_node); -diff --git a/include/linux/bvec.h b/include/linux/bvec.h -index 35c25dff651a5..9e3dac51eb26b 100644 ---- a/include/linux/bvec.h -+++ b/include/linux/bvec.h -@@ -35,6 +35,21 @@ struct bio_vec { - unsigned int bv_offset; - }; - -+/** -+ * bvec_set_page - initialize a bvec based off a struct page -+ * @bv: bvec to initialize -+ * @page: page the bvec should point to -+ * @len: length of the bvec -+ * @offset: offset into the page -+ */ -+static inline void bvec_set_page(struct bio_vec *bv, struct page *page, -+ unsigned int len, unsigned int offset) -+{ -+ bv->bv_page = page; -+ bv->bv_len = len; -+ bv->bv_offset = offset; -+} -+ - struct bvec_iter { - sector_t bi_sector; /* device address in 512 byte - sectors */ -diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h -index 71731796c8c3a..9c31f1f430d8e 100644 ---- a/include/linux/dma-buf.h -+++ b/include/linux/dma-buf.h -@@ -627,6 +627,12 @@ int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, - enum dma_data_direction dir); - int dma_buf_end_cpu_access(struct dma_buf *dma_buf, - enum dma_data_direction dir); -+struct sg_table * -+dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach, -+ enum dma_data_direction direction); -+void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach, -+ struct sg_table *sg_table, -+ enum dma_data_direction direction); - - int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, - unsigned long); -diff --git a/include/linux/instruction_pointer.h b/include/linux/instruction_pointer.h -index cda1f706eaeb1..aa0b3ffea9353 100644 ---- a/include/linux/instruction_pointer.h -+++ b/include/linux/instruction_pointer.h -@@ -2,7 +2,12 @@ - #ifndef _LINUX_INSTRUCTION_POINTER_H - #define _LINUX_INSTRUCTION_POINTER_H - -+#include -+ - #define _RET_IP_ (unsigned long)__builtin_return_address(0) -+ -+#ifndef _THIS_IP_ - #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) -+#endif - - #endif /* _LINUX_INSTRUCTION_POINTER_H */ -diff --git a/include/linux/libata.h b/include/linux/libata.h -index 9713f4d8f15f4..4c9b322bb3d88 100644 ---- a/include/linux/libata.h -+++ b/include/linux/libata.h -@@ -216,6 +216,10 @@ enum { - ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */ - ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on this host. */ - -+ ATA_HOST_NO_PART = (1 << 4), /* Host does not support partial */ -+ ATA_HOST_NO_SSC = (1 << 5), /* Host does not support slumber */ -+ ATA_HOST_NO_DEVSLP = (1 << 6), /* Host does not support devslp */ -+ - /* bits 24:31 of host->flags are reserved for LLD specific flags */ - - /* various lengths of time */ -diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h -index 0031f7b4d9aba..63fae3c7ae430 100644 ---- a/include/linux/perf_event.h -+++ b/include/linux/perf_event.h -@@ -1139,15 +1139,31 @@ extern int perf_event_output(struct perf_event *event, - struct pt_regs *regs); - - static inline bool --is_default_overflow_handler(struct perf_event *event) -+__is_default_overflow_handler(perf_overflow_handler_t overflow_handler) - { -- if (likely(event->overflow_handler == perf_event_output_forward)) -+ if (likely(overflow_handler == perf_event_output_forward)) - return true; -- if (unlikely(event->overflow_handler == perf_event_output_backward)) -+ if (unlikely(overflow_handler == perf_event_output_backward)) - return true; - return false; - } - -+#define is_default_overflow_handler(event) \ -+ __is_default_overflow_handler((event)->overflow_handler) -+ -+#ifdef CONFIG_BPF_SYSCALL -+static inline bool uses_default_overflow_handler(struct perf_event *event) -+{ -+ if (likely(is_default_overflow_handler(event))) -+ return true; -+ -+ return __is_default_overflow_handler(event->orig_overflow_handler); -+} -+#else -+#define uses_default_overflow_handler(event) \ -+ is_default_overflow_handler(event) -+#endif -+ - extern void - perf_event_header__init_id(struct perf_event_header *header, - struct perf_sample_data *data, -diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h -index 357e0068497c1..7291fb6399d2a 100644 ---- a/include/linux/sched/task.h -+++ b/include/linux/sched/task.h -@@ -112,10 +112,36 @@ static inline struct task_struct *get_task_struct(struct task_struct *t) - } - - extern void __put_task_struct(struct task_struct *t); -+extern void __put_task_struct_rcu_cb(struct rcu_head *rhp); - - static inline void put_task_struct(struct task_struct *t) - { -- if (refcount_dec_and_test(&t->usage)) -+ if (!refcount_dec_and_test(&t->usage)) -+ return; -+ -+ /* -+ * under PREEMPT_RT, we can't call put_task_struct -+ * in atomic context because it will indirectly -+ * acquire sleeping locks. -+ * -+ * call_rcu() will schedule delayed_put_task_struct_rcu() -+ * to be called in process context. -+ * -+ * __put_task_struct() is called when -+ * refcount_dec_and_test(&t->usage) succeeds. -+ * -+ * This means that it can't "conflict" with -+ * put_task_struct_rcu_user() which abuses ->rcu the same -+ * way; rcu_users has a reference so task->usage can't be -+ * zero after rcu_users 1 -> 0 transition. -+ * -+ * delayed_free_task() also uses ->rcu, but it is only called -+ * when it fails to fork a process. Therefore, there is no -+ * way it can conflict with put_task_struct(). -+ */ -+ if (IS_ENABLED(CONFIG_PREEMPT_RT) && !preemptible()) -+ call_rcu(&t->rcu, __put_task_struct_rcu_cb); -+ else - __put_task_struct(t); - } - -diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h -index ee38835ed77cc..0b4f2d5faa080 100644 ---- a/include/linux/usb/chipidea.h -+++ b/include/linux/usb/chipidea.h -@@ -63,6 +63,7 @@ struct ci_hdrc_platform_data { - #define CI_HDRC_IMX_IS_HSIC BIT(14) - #define CI_HDRC_PMQOS BIT(15) - #define CI_HDRC_PHY_VBUS_CONTROL BIT(16) -+#define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17) - enum usb_dr_mode dr_mode; - #define CI_HDRC_CONTROLLER_RESET_EVENT 0 - #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 -diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h -index a494cf43a7552..b0caad82b6937 100644 ---- a/include/uapi/linux/netfilter_bridge/ebtables.h -+++ b/include/uapi/linux/netfilter_bridge/ebtables.h -@@ -182,12 +182,14 @@ struct ebt_entry { - unsigned char sourcemsk[ETH_ALEN]; - unsigned char destmac[ETH_ALEN]; - unsigned char destmsk[ETH_ALEN]; -- /* sizeof ebt_entry + matches */ -- unsigned int watchers_offset; -- /* sizeof ebt_entry + matches + watchers */ -- unsigned int target_offset; -- /* sizeof ebt_entry + matches + watchers + target */ -- unsigned int next_offset; -+ __struct_group(/* no tag */, offsets, /* no attrs */, -+ /* sizeof ebt_entry + matches */ -+ unsigned int watchers_offset; -+ /* sizeof ebt_entry + matches + watchers */ -+ unsigned int target_offset; -+ /* sizeof ebt_entry + matches + watchers + target */ -+ unsigned int next_offset; -+ ); - unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); - }; - -diff --git a/io_uring/net.c b/io_uring/net.c -index 7245218fdbe2b..9fe1aada3ad00 100644 ---- a/io_uring/net.c -+++ b/io_uring/net.c -@@ -170,6 +170,10 @@ static int io_setup_async_msg(struct io_kiocb *req, - memcpy(async_msg, kmsg, sizeof(*kmsg)); - if (async_msg->msg.msg_name) - async_msg->msg.msg_name = &async_msg->addr; -+ -+ if ((req->flags & REQ_F_BUFFER_SELECT) && !async_msg->msg.msg_iter.nr_segs) -+ return -EAGAIN; -+ - /* if were using fast_iov, set it to the new one */ - if (!kmsg->free_iov) { - size_t fast_idx = kmsg->msg.msg_iter.iov - kmsg->fast_iov; -@@ -529,6 +533,7 @@ static int io_recvmsg_copy_hdr(struct io_kiocb *req, - struct io_async_msghdr *iomsg) - { - iomsg->msg.msg_name = &iomsg->addr; -+ iomsg->msg.msg_iter.nr_segs = 0; - - #ifdef CONFIG_COMPAT - if (req->ctx->compat) -diff --git a/kernel/fork.c b/kernel/fork.c -index 41950ff90aa34..85617928041cf 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -852,6 +852,14 @@ void __put_task_struct(struct task_struct *tsk) - } - EXPORT_SYMBOL_GPL(__put_task_struct); - -+void __put_task_struct_rcu_cb(struct rcu_head *rhp) -+{ -+ struct task_struct *task = container_of(rhp, struct task_struct, rcu); -+ -+ __put_task_struct(task); -+} -+EXPORT_SYMBOL_GPL(__put_task_struct_rcu_cb); -+ - void __init __weak arch_task_cache_init(void) { } - - /* -diff --git a/kernel/panic.c b/kernel/panic.c -index ca5452afb456d..63e94f3bd8dcd 100644 ---- a/kernel/panic.c -+++ b/kernel/panic.c -@@ -695,6 +695,7 @@ void warn_slowpath_fmt(const char *file, int line, unsigned taint, - if (!fmt) { - __warn(file, line, __builtin_return_address(0), taint, - NULL, NULL); -+ warn_rcu_exit(rcu); - return; - } - -diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index e4f1e7478b521..cc53fb77f77cc 100644 ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -2269,7 +2269,11 @@ asmlinkage int vprintk_emit(int facility, int level, - preempt_enable(); - } - -- wake_up_klogd(); -+ if (in_sched) -+ defer_console_output(); -+ else -+ wake_up_klogd(); -+ - return printed_len; - } - EXPORT_SYMBOL(vprintk_emit); -@@ -2552,6 +2556,25 @@ static int console_cpu_notify(unsigned int cpu) - return 0; - } - -+/* -+ * Return true when this CPU should unlock console_sem without pushing all -+ * messages to the console. This reduces the chance that the console is -+ * locked when the panic CPU tries to use it. -+ */ -+static bool abandon_console_lock_in_panic(void) -+{ -+ if (!panic_in_progress()) -+ return false; -+ -+ /* -+ * We can use raw_smp_processor_id() here because it is impossible for -+ * the task to be migrated to the panic_cpu, or away from it. If -+ * panic_cpu has already been set, and we're not currently executing on -+ * that CPU, then we never will be. -+ */ -+ return atomic_read(&panic_cpu) != raw_smp_processor_id(); -+} -+ - /** - * console_lock - lock the console system for exclusive use. - * -@@ -2564,6 +2587,10 @@ void console_lock(void) - { - might_sleep(); - -+ /* On panic, the console_lock must be left to the panic cpu. */ -+ while (abandon_console_lock_in_panic()) -+ msleep(1000); -+ - down_console_sem(); - if (console_suspended) - return; -@@ -2582,6 +2609,9 @@ EXPORT_SYMBOL(console_lock); - */ - int console_trylock(void) - { -+ /* On panic, the console_lock must be left to the panic cpu. */ -+ if (abandon_console_lock_in_panic()) -+ return 0; - if (down_trylock_console_sem()) - return 0; - if (console_suspended) { -@@ -2600,25 +2630,6 @@ int is_console_locked(void) - } - EXPORT_SYMBOL(is_console_locked); - --/* -- * Return true when this CPU should unlock console_sem without pushing all -- * messages to the console. This reduces the chance that the console is -- * locked when the panic CPU tries to use it. -- */ --static bool abandon_console_lock_in_panic(void) --{ -- if (!panic_in_progress()) -- return false; -- -- /* -- * We can use raw_smp_processor_id() here because it is impossible for -- * the task to be migrated to the panic_cpu, or away from it. If -- * panic_cpu has already been set, and we're not currently executing on -- * that CPU, then we never will be. -- */ -- return atomic_read(&panic_cpu) != raw_smp_processor_id(); --} -- - /* - * Check if the given console is currently capable and allowed to print - * records. -@@ -3483,11 +3494,33 @@ static void __wake_up_klogd(int val) - preempt_enable(); - } - -+/** -+ * wake_up_klogd - Wake kernel logging daemon -+ * -+ * Use this function when new records have been added to the ringbuffer -+ * and the console printing of those records has already occurred or is -+ * known to be handled by some other context. This function will only -+ * wake the logging daemon. -+ * -+ * Context: Any context. -+ */ - void wake_up_klogd(void) - { - __wake_up_klogd(PRINTK_PENDING_WAKEUP); - } - -+/** -+ * defer_console_output - Wake kernel logging daemon and trigger -+ * console printing in a deferred context -+ * -+ * Use this function when new records have been added to the ringbuffer, -+ * this context is responsible for console printing those records, but -+ * the current context is not allowed to perform the console printing. -+ * Trigger an irq_work context to perform the console printing. This -+ * function also wakes the logging daemon. -+ * -+ * Context: Any context. -+ */ - void defer_console_output(void) - { - /* -@@ -3504,12 +3537,7 @@ void printk_trigger_flush(void) - - int vprintk_deferred(const char *fmt, va_list args) - { -- int r; -- -- r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); -- defer_console_output(); -- -- return r; -+ return vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); - } - - int _printk_deferred(const char *fmt, ...) -diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c -index ef0f9a2044da1..6d10927a07d83 100644 ---- a/kernel/printk/printk_safe.c -+++ b/kernel/printk/printk_safe.c -@@ -38,13 +38,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) - * Use the main logbuf even in NMI. But avoid calling console - * drivers that might have their own locks. - */ -- if (this_cpu_read(printk_context) || in_nmi()) { -- int len; -- -- len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, fmt, args); -- defer_console_output(); -- return len; -- } -+ if (this_cpu_read(printk_context) || in_nmi()) -+ return vprintk_deferred(fmt, args); - - /* No obstacles. */ - return vprintk_default(fmt, args); -diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c -index 7854dc3226e1b..0b88d96511adc 100644 ---- a/kernel/rcu/rcuscale.c -+++ b/kernel/rcu/rcuscale.c -@@ -423,7 +423,7 @@ rcu_scale_writer(void *arg) - sched_set_fifo_low(current); - - if (holdoff) -- schedule_timeout_uninterruptible(holdoff * HZ); -+ schedule_timeout_idle(holdoff * HZ); - - /* - * Wait until rcu_end_inkernel_boot() is called for normal GP tests -diff --git a/kernel/scftorture.c b/kernel/scftorture.c -index 5d113aa59e773..83c33ba0ca7e0 100644 ---- a/kernel/scftorture.c -+++ b/kernel/scftorture.c -@@ -171,7 +171,8 @@ static void scf_torture_stats_print(void) - scfs.n_all_wait += scf_stats_p[i].n_all_wait; - } - if (atomic_read(&n_errs) || atomic_read(&n_mb_in_errs) || -- atomic_read(&n_mb_out_errs) || atomic_read(&n_alloc_errs)) -+ atomic_read(&n_mb_out_errs) || -+ (!IS_ENABLED(CONFIG_KASAN) && atomic_read(&n_alloc_errs))) - bangstr = "!!! "; - pr_alert("%s %sscf_invoked_count %s: %lld resched: %lld single: %lld/%lld single_ofl: %lld/%lld single_rpc: %lld single_rpc_ofl: %lld many: %lld/%lld all: %lld/%lld ", - SCFTORT_FLAG, bangstr, isdone ? "VER" : "ver", invoked_count, scfs.n_resched, -@@ -323,7 +324,8 @@ static void scftorture_invoke_one(struct scf_statistics *scfp, struct torture_ra - preempt_disable(); - if (scfsp->scfs_prim == SCF_PRIM_SINGLE || scfsp->scfs_wait) { - scfcp = kmalloc(sizeof(*scfcp), GFP_ATOMIC); -- if (WARN_ON_ONCE(!scfcp)) { -+ if (!scfcp) { -+ WARN_ON_ONCE(!IS_ENABLED(CONFIG_KASAN)); - atomic_inc(&n_alloc_errs); - } else { - scfcp->scfc_cpu = -1; -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 54ccdca395311..9db92a6e14636 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -1729,7 +1729,7 @@ static void trace_create_maxlat_file(struct trace_array *tr, - init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq); - tr->d_max_latency = trace_create_file("tracing_max_latency", - TRACE_MODE_WRITE, -- d_tracer, &tr->max_latency, -+ d_tracer, tr, - &tracing_max_lat_fops); - } - -@@ -1762,7 +1762,7 @@ void latency_fsnotify(struct trace_array *tr) - - #define trace_create_maxlat_file(tr, d_tracer) \ - trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, \ -- d_tracer, &tr->max_latency, &tracing_max_lat_fops) -+ d_tracer, tr, &tracing_max_lat_fops) - - #endif - -@@ -4899,6 +4899,33 @@ int tracing_open_generic_tr(struct inode *inode, struct file *filp) - return 0; - } - -+/* -+ * The private pointer of the inode is the trace_event_file. -+ * Update the tr ref count associated to it. -+ */ -+int tracing_open_file_tr(struct inode *inode, struct file *filp) -+{ -+ struct trace_event_file *file = inode->i_private; -+ int ret; -+ -+ ret = tracing_check_open_get_tr(file->tr); -+ if (ret) -+ return ret; -+ -+ filp->private_data = inode->i_private; -+ -+ return 0; -+} -+ -+int tracing_release_file_tr(struct inode *inode, struct file *filp) -+{ -+ struct trace_event_file *file = inode->i_private; -+ -+ trace_array_put(file->tr); -+ -+ return 0; -+} -+ - static int tracing_mark_open(struct inode *inode, struct file *filp) - { - stream_open(inode, filp); -@@ -6604,14 +6631,18 @@ static ssize_t - tracing_max_lat_read(struct file *filp, char __user *ubuf, - size_t cnt, loff_t *ppos) - { -- return tracing_nsecs_read(filp->private_data, ubuf, cnt, ppos); -+ struct trace_array *tr = filp->private_data; -+ -+ return tracing_nsecs_read(&tr->max_latency, ubuf, cnt, ppos); - } - - static ssize_t - tracing_max_lat_write(struct file *filp, const char __user *ubuf, - size_t cnt, loff_t *ppos) - { -- return tracing_nsecs_write(filp->private_data, ubuf, cnt, ppos); -+ struct trace_array *tr = filp->private_data; -+ -+ return tracing_nsecs_write(&tr->max_latency, ubuf, cnt, ppos); - } - - #endif -@@ -7668,18 +7699,20 @@ static const struct file_operations tracing_thresh_fops = { - - #ifdef CONFIG_TRACER_MAX_TRACE - static const struct file_operations tracing_max_lat_fops = { -- .open = tracing_open_generic, -+ .open = tracing_open_generic_tr, - .read = tracing_max_lat_read, - .write = tracing_max_lat_write, - .llseek = generic_file_llseek, -+ .release = tracing_release_generic_tr, - }; - #endif - - static const struct file_operations set_tracer_fops = { -- .open = tracing_open_generic, -+ .open = tracing_open_generic_tr, - .read = tracing_set_trace_read, - .write = tracing_set_trace_write, - .llseek = generic_file_llseek, -+ .release = tracing_release_generic_tr, - }; - - static const struct file_operations tracing_pipe_fops = { -@@ -8872,12 +8905,33 @@ trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt, - return cnt; - } - -+static int tracing_open_options(struct inode *inode, struct file *filp) -+{ -+ struct trace_option_dentry *topt = inode->i_private; -+ int ret; -+ -+ ret = tracing_check_open_get_tr(topt->tr); -+ if (ret) -+ return ret; -+ -+ filp->private_data = inode->i_private; -+ return 0; -+} -+ -+static int tracing_release_options(struct inode *inode, struct file *file) -+{ -+ struct trace_option_dentry *topt = file->private_data; -+ -+ trace_array_put(topt->tr); -+ return 0; -+} - - static const struct file_operations trace_options_fops = { -- .open = tracing_open_generic, -+ .open = tracing_open_options, - .read = trace_options_read, - .write = trace_options_write, - .llseek = generic_file_llseek, -+ .release = tracing_release_options, - }; - - /* -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index dbb86b0dd3b7b..7e6d5101bdb05 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -590,6 +590,8 @@ void tracing_reset_all_online_cpus(void); - void tracing_reset_all_online_cpus_unlocked(void); - int tracing_open_generic(struct inode *inode, struct file *filp); - int tracing_open_generic_tr(struct inode *inode, struct file *filp); -+int tracing_open_file_tr(struct inode *inode, struct file *filp); -+int tracing_release_file_tr(struct inode *inode, struct file *filp); - bool tracing_is_disabled(void); - bool tracer_tracing_is_on(struct trace_array *tr); - void tracer_tracing_on(struct trace_array *tr); -diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c -index 0447c46ef4d71..9da418442a063 100644 ---- a/kernel/trace/trace_events.c -+++ b/kernel/trace/trace_events.c -@@ -2101,9 +2101,10 @@ static const struct file_operations ftrace_set_event_notrace_pid_fops = { - }; - - static const struct file_operations ftrace_enable_fops = { -- .open = tracing_open_generic, -+ .open = tracing_open_file_tr, - .read = event_enable_read, - .write = event_enable_write, -+ .release = tracing_release_file_tr, - .llseek = default_llseek, - }; - -@@ -2120,9 +2121,10 @@ static const struct file_operations ftrace_event_id_fops = { - }; - - static const struct file_operations ftrace_event_filter_fops = { -- .open = tracing_open_generic, -+ .open = tracing_open_file_tr, - .read = event_filter_read, - .write = event_filter_write, -+ .release = tracing_release_file_tr, - .llseek = default_llseek, - }; - -diff --git a/kernel/trace/trace_events_inject.c b/kernel/trace/trace_events_inject.c -index d6b4935a78c08..dbecfbb73d237 100644 ---- a/kernel/trace/trace_events_inject.c -+++ b/kernel/trace/trace_events_inject.c -@@ -328,7 +328,8 @@ event_inject_read(struct file *file, char __user *buf, size_t size, - } - - const struct file_operations event_inject_fops = { -- .open = tracing_open_generic, -+ .open = tracing_open_file_tr, - .read = event_inject_read, - .write = event_inject_write, -+ .release = tracing_release_file_tr, - }; -diff --git a/lib/kobject.c b/lib/kobject.c -index aa375a5d94419..207fd22ad3bde 100644 ---- a/lib/kobject.c -+++ b/lib/kobject.c -@@ -850,6 +850,11 @@ int kset_register(struct kset *k) - if (!k) - return -EINVAL; - -+ if (!k->kobj.ktype) { -+ pr_err("must have a ktype to be initialized properly!\n"); -+ return -EINVAL; -+ } -+ - kset_init(k); - err = kobject_add_internal(&k->kobj); - if (err) -diff --git a/lib/mpi/mpi-cmp.c b/lib/mpi/mpi-cmp.c -index c4cfa3ff05818..0835b6213235e 100644 ---- a/lib/mpi/mpi-cmp.c -+++ b/lib/mpi/mpi-cmp.c -@@ -25,8 +25,12 @@ int mpi_cmp_ui(MPI u, unsigned long v) - mpi_limb_t limb = v; - - mpi_normalize(u); -- if (!u->nlimbs && !limb) -- return 0; -+ if (u->nlimbs == 0) { -+ if (v == 0) -+ return 0; -+ else -+ return -1; -+ } - if (u->sign) - return -1; - if (u->nlimbs > 1) -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 0a403b241718e..67b6d8238b3ed 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -3841,6 +3841,10 @@ static ssize_t mem_cgroup_write(struct kernfs_open_file *of, - case _MEMSWAP: - ret = mem_cgroup_resize_max(memcg, nr_pages, true); - break; -+ case _KMEM: -+ /* kmem.limit_in_bytes is deprecated. */ -+ ret = -EOPNOTSUPP; -+ break; - case _TCP: - ret = memcg_update_tcp_max(memcg, nr_pages); - break; -@@ -5051,6 +5055,12 @@ static struct cftype mem_cgroup_legacy_files[] = { - .seq_show = memcg_numa_stat_show, - }, - #endif -+ { -+ .name = "kmem.limit_in_bytes", -+ .private = MEMFILE_PRIVATE(_KMEM, RES_LIMIT), -+ .write = mem_cgroup_write, -+ .read_u64 = mem_cgroup_read_u64, -+ }, - { - .name = "kmem.usage_in_bytes", - .private = MEMFILE_PRIVATE(_KMEM, RES_USAGE), -diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c -index 146553c0054f6..fa4dd5fab0d44 100644 ---- a/net/bluetooth/hci_core.c -+++ b/net/bluetooth/hci_core.c -@@ -2436,6 +2436,9 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, - if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) - return NOTIFY_DONE; - -+ /* To avoid a potential race with hci_unregister_dev. */ -+ hci_dev_hold(hdev); -+ - if (action == PM_SUSPEND_PREPARE) - ret = hci_suspend_dev(hdev); - else if (action == PM_POST_SUSPEND) -@@ -2445,6 +2448,7 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, - bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", - action, ret); - -+ hci_dev_put(hdev); - return NOTIFY_DONE; - } - -diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c -index 757ec46fc45a0..aa23479b20b2a 100644 ---- a/net/bridge/netfilter/ebtables.c -+++ b/net/bridge/netfilter/ebtables.c -@@ -2115,8 +2115,7 @@ static int size_entry_mwt(const struct ebt_entry *entry, const unsigned char *ba - return ret; - - offsets[0] = sizeof(struct ebt_entry); /* matches come first */ -- memcpy(&offsets[1], &entry->watchers_offset, -- sizeof(offsets) - sizeof(offsets[0])); -+ memcpy(&offsets[1], &entry->offsets, sizeof(entry->offsets)); - - if (state->buf_kern_start) { - buf_start = state->buf_kern_start + state->buf_kern_offset; -diff --git a/net/core/sock.c b/net/core/sock.c -index e5858fa5d6d57..0ee2e33bbe5f8 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -1774,14 +1774,14 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - - case SO_PEERNAME: - { -- char address[128]; -+ struct sockaddr_storage address; - -- lv = sock->ops->getname(sock, (struct sockaddr *)address, 2); -+ lv = sock->ops->getname(sock, (struct sockaddr *)&address, 2); - if (lv < 0) - return -ENOTCONN; - if (lv < len) - return -EINVAL; -- if (copy_to_sockptr(optval, address, len)) -+ if (copy_to_sockptr(optval, &address, len)) - return -EFAULT; - goto lenout; - } -diff --git a/net/devlink/leftover.c b/net/devlink/leftover.c -index 63188d6a50fe9..032c7af065cd9 100644 ---- a/net/devlink/leftover.c -+++ b/net/devlink/leftover.c -@@ -5218,7 +5218,7 @@ static int devlink_param_get(struct devlink *devlink, - const struct devlink_param *param, - struct devlink_param_gset_ctx *ctx) - { -- if (!param->get || devlink->reload_failed) -+ if (!param->get) - return -EOPNOTSUPP; - return param->get(devlink, param->id, ctx); - } -@@ -5227,7 +5227,7 @@ static int devlink_param_set(struct devlink *devlink, - const struct devlink_param *param, - struct devlink_param_gset_ctx *ctx) - { -- if (!param->set || devlink->reload_failed) -+ if (!param->set) - return -EOPNOTSUPP; - return param->set(devlink, param->id, ctx); - } -diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c -index ebd2cea5b7d7a..66908ce2dd116 100644 ---- a/net/ipv4/ip_output.c -+++ b/net/ipv4/ip_output.c -@@ -234,7 +234,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s - net_dbg_ratelimited("%s: No header cache and no neighbour!\n", - __func__); - kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL); -- return -EINVAL; -+ return PTR_ERR(neigh); - } - - static int ip_finish_output_gso(struct net *net, struct sock *sk, -diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c -index 23a44edcb11f7..cf3453b532d67 100644 ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -3991,19 +3991,20 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, - mutex_lock(&local->mtx); - - rcu_read_lock(); -+ sta = sta_info_get_bss(sdata, peer); -+ if (!sta) { -+ ret = -ENOLINK; -+ goto unlock; -+ } -+ -+ qos = sta->sta.wme; -+ - chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - ret = -EINVAL; - goto unlock; - } - band = chanctx_conf->def.chan->band; -- sta = sta_info_get_bss(sdata, peer); -- if (sta) { -- qos = sta->sta.wme; -- } else { -- ret = -ENOLINK; -- goto unlock; -- } - - if (qos) { - fc = cpu_to_le16(IEEE80211_FTYPE_DATA | -diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c -index 55dc0610e8633..c4c80037df91d 100644 ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -3625,6 +3625,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) - break; - goto queue; - case WLAN_CATEGORY_S1G: -+ if (len < offsetofend(typeof(*mgmt), -+ u.action.u.s1g.action_code)) -+ break; -+ - switch (mgmt->u.action.u.s1g.action_code) { - case WLAN_S1G_TWT_SETUP: - case WLAN_S1G_TWT_TEARDOWN: -diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c -index ed123cf462afe..387e430a35ccc 100644 ---- a/net/netlink/af_netlink.c -+++ b/net/netlink/af_netlink.c -@@ -84,7 +84,7 @@ struct listeners { - - static inline int netlink_is_kernel(struct sock *sk) - { -- return nlk_sk(sk)->flags & NETLINK_F_KERNEL_SOCKET; -+ return nlk_test_bit(KERNEL_SOCKET, sk); - } - - struct netlink_table *nl_table __read_mostly; -@@ -349,9 +349,7 @@ static void netlink_deliver_tap_kernel(struct sock *dst, struct sock *src, - - static void netlink_overrun(struct sock *sk) - { -- struct netlink_sock *nlk = nlk_sk(sk); -- -- if (!(nlk->flags & NETLINK_F_RECV_NO_ENOBUFS)) { -+ if (!nlk_test_bit(RECV_NO_ENOBUFS, sk)) { - if (!test_and_set_bit(NETLINK_S_CONGESTED, - &nlk_sk(sk)->state)) { - sk->sk_err = ENOBUFS; -@@ -1391,9 +1389,7 @@ EXPORT_SYMBOL_GPL(netlink_has_listeners); - - bool netlink_strict_get_check(struct sk_buff *skb) - { -- const struct netlink_sock *nlk = nlk_sk(NETLINK_CB(skb).sk); -- -- return nlk->flags & NETLINK_F_STRICT_CHK; -+ return nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk); - } - EXPORT_SYMBOL_GPL(netlink_strict_get_check); - -@@ -1437,7 +1433,7 @@ static void do_one_broadcast(struct sock *sk, - return; - - if (!net_eq(sock_net(sk), p->net)) { -- if (!(nlk->flags & NETLINK_F_LISTEN_ALL_NSID)) -+ if (!nlk_test_bit(LISTEN_ALL_NSID, sk)) - return; - - if (!peernet_has_id(sock_net(sk), p->net)) -@@ -1470,7 +1466,7 @@ static void do_one_broadcast(struct sock *sk, - netlink_overrun(sk); - /* Clone failed. Notify ALL listeners. */ - p->failure = 1; -- if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) -+ if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) - p->delivery_failure = 1; - goto out; - } -@@ -1485,7 +1481,7 @@ static void do_one_broadcast(struct sock *sk, - val = netlink_broadcast_deliver(sk, p->skb2); - if (val < 0) { - netlink_overrun(sk); -- if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) -+ if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) - p->delivery_failure = 1; - } else { - p->congested |= val; -@@ -1565,7 +1561,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) - !test_bit(p->group - 1, nlk->groups)) - goto out; - -- if (p->code == ENOBUFS && nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) { -+ if (p->code == ENOBUFS && nlk_test_bit(RECV_NO_ENOBUFS, sk)) { - ret = 1; - goto out; - } -@@ -1632,7 +1628,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, - struct sock *sk = sock->sk; - struct netlink_sock *nlk = nlk_sk(sk); - unsigned int val = 0; -- int err; -+ int nr = -1; - - if (level != SOL_NETLINK) - return -ENOPROTOOPT; -@@ -1643,14 +1639,12 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, - - switch (optname) { - case NETLINK_PKTINFO: -- if (val) -- nlk->flags |= NETLINK_F_RECV_PKTINFO; -- else -- nlk->flags &= ~NETLINK_F_RECV_PKTINFO; -- err = 0; -+ nr = NETLINK_F_RECV_PKTINFO; - break; - case NETLINK_ADD_MEMBERSHIP: - case NETLINK_DROP_MEMBERSHIP: { -+ int err; -+ - if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) - return -EPERM; - err = netlink_realloc_groups(sk); -@@ -1670,61 +1664,38 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, - if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) - nlk->netlink_unbind(sock_net(sk), val); - -- err = 0; - break; - } - case NETLINK_BROADCAST_ERROR: -- if (val) -- nlk->flags |= NETLINK_F_BROADCAST_SEND_ERROR; -- else -- nlk->flags &= ~NETLINK_F_BROADCAST_SEND_ERROR; -- err = 0; -+ nr = NETLINK_F_BROADCAST_SEND_ERROR; - break; - case NETLINK_NO_ENOBUFS: -+ assign_bit(NETLINK_F_RECV_NO_ENOBUFS, &nlk->flags, val); - if (val) { -- nlk->flags |= NETLINK_F_RECV_NO_ENOBUFS; - clear_bit(NETLINK_S_CONGESTED, &nlk->state); - wake_up_interruptible(&nlk->wait); -- } else { -- nlk->flags &= ~NETLINK_F_RECV_NO_ENOBUFS; - } -- err = 0; - break; - case NETLINK_LISTEN_ALL_NSID: - if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_BROADCAST)) - return -EPERM; -- -- if (val) -- nlk->flags |= NETLINK_F_LISTEN_ALL_NSID; -- else -- nlk->flags &= ~NETLINK_F_LISTEN_ALL_NSID; -- err = 0; -+ nr = NETLINK_F_LISTEN_ALL_NSID; - break; - case NETLINK_CAP_ACK: -- if (val) -- nlk->flags |= NETLINK_F_CAP_ACK; -- else -- nlk->flags &= ~NETLINK_F_CAP_ACK; -- err = 0; -+ nr = NETLINK_F_CAP_ACK; - break; - case NETLINK_EXT_ACK: -- if (val) -- nlk->flags |= NETLINK_F_EXT_ACK; -- else -- nlk->flags &= ~NETLINK_F_EXT_ACK; -- err = 0; -+ nr = NETLINK_F_EXT_ACK; - break; - case NETLINK_GET_STRICT_CHK: -- if (val) -- nlk->flags |= NETLINK_F_STRICT_CHK; -- else -- nlk->flags &= ~NETLINK_F_STRICT_CHK; -- err = 0; -+ nr = NETLINK_F_STRICT_CHK; - break; - default: -- err = -ENOPROTOOPT; -+ return -ENOPROTOOPT; - } -- return err; -+ if (nr >= 0) -+ assign_bit(nr, &nlk->flags, val); -+ return 0; - } - - static int netlink_getsockopt(struct socket *sock, int level, int optname, -@@ -1791,7 +1762,7 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, - return -EINVAL; - - len = sizeof(int); -- val = nlk->flags & flag ? 1 : 0; -+ val = test_bit(flag, &nlk->flags); - - if (put_user(len, optlen) || - copy_to_user(optval, &val, len)) -@@ -1968,9 +1939,9 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, - msg->msg_namelen = sizeof(*addr); - } - -- if (nlk->flags & NETLINK_F_RECV_PKTINFO) -+ if (nlk_test_bit(RECV_PKTINFO, sk)) - netlink_cmsg_recv_pktinfo(msg, skb); -- if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID) -+ if (nlk_test_bit(LISTEN_ALL_NSID, sk)) - netlink_cmsg_listen_all_nsid(sk, msg, skb); - - memset(&scm, 0, sizeof(scm)); -@@ -2047,7 +2018,7 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module, - goto out_sock_release; - - nlk = nlk_sk(sk); -- nlk->flags |= NETLINK_F_KERNEL_SOCKET; -+ set_bit(NETLINK_F_KERNEL_SOCKET, &nlk->flags); - - netlink_table_grab(); - if (!nl_table[unit].registered) { -@@ -2183,7 +2154,7 @@ static int netlink_dump_done(struct netlink_sock *nlk, struct sk_buff *skb, - nl_dump_check_consistent(cb, nlh); - memcpy(nlmsg_data(nlh), &nlk->dump_done_errno, sizeof(nlk->dump_done_errno)); - -- if (extack->_msg && nlk->flags & NETLINK_F_EXT_ACK) { -+ if (extack->_msg && test_bit(NETLINK_F_EXT_ACK, &nlk->flags)) { - nlh->nlmsg_flags |= NLM_F_ACK_TLVS; - if (!nla_put_string(skb, NLMSGERR_ATTR_MSG, extack->_msg)) - nlmsg_end(skb, nlh); -@@ -2312,8 +2283,8 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, - const struct nlmsghdr *nlh, - struct netlink_dump_control *control) - { -- struct netlink_sock *nlk, *nlk2; - struct netlink_callback *cb; -+ struct netlink_sock *nlk; - struct sock *sk; - int ret; - -@@ -2348,8 +2319,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, - cb->min_dump_alloc = control->min_dump_alloc; - cb->skb = skb; - -- nlk2 = nlk_sk(NETLINK_CB(skb).sk); -- cb->strict_check = !!(nlk2->flags & NETLINK_F_STRICT_CHK); -+ cb->strict_check = nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk); - - if (control->start) { - ret = control->start(cb); -@@ -2391,7 +2361,7 @@ netlink_ack_tlv_len(struct netlink_sock *nlk, int err, - { - size_t tlvlen; - -- if (!extack || !(nlk->flags & NETLINK_F_EXT_ACK)) -+ if (!extack || !test_bit(NETLINK_F_EXT_ACK, &nlk->flags)) - return 0; - - tlvlen = 0; -@@ -2463,7 +2433,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, - * requests to cap the error message, and get extra error data if - * requested. - */ -- if (err && !(nlk->flags & NETLINK_F_CAP_ACK)) -+ if (err && !test_bit(NETLINK_F_CAP_ACK, &nlk->flags)) - payload += nlmsg_len(nlh); - else - flags |= NLM_F_CAPPED; -diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h -index 5f454c8de6a4d..b30b8fc760f71 100644 ---- a/net/netlink/af_netlink.h -+++ b/net/netlink/af_netlink.h -@@ -8,14 +8,16 @@ - #include - - /* flags */ --#define NETLINK_F_KERNEL_SOCKET 0x1 --#define NETLINK_F_RECV_PKTINFO 0x2 --#define NETLINK_F_BROADCAST_SEND_ERROR 0x4 --#define NETLINK_F_RECV_NO_ENOBUFS 0x8 --#define NETLINK_F_LISTEN_ALL_NSID 0x10 --#define NETLINK_F_CAP_ACK 0x20 --#define NETLINK_F_EXT_ACK 0x40 --#define NETLINK_F_STRICT_CHK 0x80 -+enum { -+ NETLINK_F_KERNEL_SOCKET, -+ NETLINK_F_RECV_PKTINFO, -+ NETLINK_F_BROADCAST_SEND_ERROR, -+ NETLINK_F_RECV_NO_ENOBUFS, -+ NETLINK_F_LISTEN_ALL_NSID, -+ NETLINK_F_CAP_ACK, -+ NETLINK_F_EXT_ACK, -+ NETLINK_F_STRICT_CHK, -+}; - - #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) - #define NLGRPLONGS(x) (NLGRPSZ(x)/sizeof(unsigned long)) -@@ -23,10 +25,10 @@ - struct netlink_sock { - /* struct sock has to be the first member of netlink_sock */ - struct sock sk; -+ unsigned long flags; - u32 portid; - u32 dst_portid; - u32 dst_group; -- u32 flags; - u32 subscriptions; - u32 ngroups; - unsigned long *groups; -@@ -54,6 +56,8 @@ static inline struct netlink_sock *nlk_sk(struct sock *sk) - return container_of(sk, struct netlink_sock, sk); - } - -+#define nlk_test_bit(nr, sk) test_bit(NETLINK_F_##nr, &nlk_sk(sk)->flags) -+ - struct netlink_table { - struct rhashtable hash; - struct hlist_head mc_list; -diff --git a/net/netlink/diag.c b/net/netlink/diag.c -index e4f21b1067bcc..9c4f231be2757 100644 ---- a/net/netlink/diag.c -+++ b/net/netlink/diag.c -@@ -27,15 +27,15 @@ static int sk_diag_put_flags(struct sock *sk, struct sk_buff *skb) - - if (nlk->cb_running) - flags |= NDIAG_FLAG_CB_RUNNING; -- if (nlk->flags & NETLINK_F_RECV_PKTINFO) -+ if (nlk_test_bit(RECV_PKTINFO, sk)) - flags |= NDIAG_FLAG_PKTINFO; -- if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) -+ if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) - flags |= NDIAG_FLAG_BROADCAST_ERROR; -- if (nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) -+ if (nlk_test_bit(RECV_NO_ENOBUFS, sk)) - flags |= NDIAG_FLAG_NO_ENOBUFS; -- if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID) -+ if (nlk_test_bit(LISTEN_ALL_NSID, sk)) - flags |= NDIAG_FLAG_LISTEN_ALL_NSID; -- if (nlk->flags & NETLINK_F_CAP_ACK) -+ if (nlk_test_bit(CAP_ACK, sk)) - flags |= NDIAG_FLAG_CAP_ACK; - - return nla_put_u32(skb, NETLINK_DIAG_FLAGS, flags); -diff --git a/net/sched/Kconfig b/net/sched/Kconfig -index bcdd6e925343f..24cf0bf7c80e5 100644 ---- a/net/sched/Kconfig -+++ b/net/sched/Kconfig -@@ -548,34 +548,6 @@ config CLS_U32_MARK - help - Say Y here to be able to use netfilter marks as u32 key. - --config NET_CLS_RSVP -- tristate "IPv4 Resource Reservation Protocol (RSVP)" -- select NET_CLS -- help -- The Resource Reservation Protocol (RSVP) permits end systems to -- request a minimum and maximum data flow rate for a connection; this -- is important for real time data such as streaming sound or video. -- -- Say Y here if you want to be able to classify outgoing packets based -- on their RSVP requests. -- -- To compile this code as a module, choose M here: the -- module will be called cls_rsvp. -- --config NET_CLS_RSVP6 -- tristate "IPv6 Resource Reservation Protocol (RSVP6)" -- select NET_CLS -- help -- The Resource Reservation Protocol (RSVP) permits end systems to -- request a minimum and maximum data flow rate for a connection; this -- is important for real time data such as streaming sound or video. -- -- Say Y here if you want to be able to classify outgoing packets based -- on their RSVP requests and you are using the IPv6 protocol. -- -- To compile this code as a module, choose M here: the -- module will be called cls_rsvp6. -- - config NET_CLS_FLOW - tristate "Flow classifier" - select NET_CLS -diff --git a/net/sched/Makefile b/net/sched/Makefile -index b7dbac5c519f6..8a33a35fc50d5 100644 ---- a/net/sched/Makefile -+++ b/net/sched/Makefile -@@ -69,8 +69,6 @@ obj-$(CONFIG_NET_SCH_TAPRIO) += sch_taprio.o - obj-$(CONFIG_NET_CLS_U32) += cls_u32.o - obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o - obj-$(CONFIG_NET_CLS_FW) += cls_fw.o --obj-$(CONFIG_NET_CLS_RSVP) += cls_rsvp.o --obj-$(CONFIG_NET_CLS_RSVP6) += cls_rsvp6.o - obj-$(CONFIG_NET_CLS_BASIC) += cls_basic.o - obj-$(CONFIG_NET_CLS_FLOW) += cls_flow.o - obj-$(CONFIG_NET_CLS_CGROUP) += cls_cgroup.o -diff --git a/net/sched/cls_rsvp.c b/net/sched/cls_rsvp.c -deleted file mode 100644 -index de1c1d4da5977..0000000000000 ---- a/net/sched/cls_rsvp.c -+++ /dev/null -@@ -1,24 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * net/sched/cls_rsvp.c Special RSVP packet classifier for IPv4. -- * -- * Authors: Alexey Kuznetsov, -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define RSVP_DST_LEN 1 --#define RSVP_ID "rsvp" --#define RSVP_OPS cls_rsvp_ops -- --#include "cls_rsvp.h" --MODULE_LICENSE("GPL"); -diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h -deleted file mode 100644 -index b00a7dbd05874..0000000000000 ---- a/net/sched/cls_rsvp.h -+++ /dev/null -@@ -1,764 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-or-later */ --/* -- * net/sched/cls_rsvp.h Template file for RSVPv[46] classifiers. -- * -- * Authors: Alexey Kuznetsov, -- */ -- --/* -- Comparing to general packet classification problem, -- RSVP needs only several relatively simple rules: -- -- * (dst, protocol) are always specified, -- so that we are able to hash them. -- * src may be exact, or may be wildcard, so that -- we can keep a hash table plus one wildcard entry. -- * source port (or flow label) is important only if src is given. -- -- IMPLEMENTATION. -- -- We use a two level hash table: The top level is keyed by -- destination address and protocol ID, every bucket contains a list -- of "rsvp sessions", identified by destination address, protocol and -- DPI(="Destination Port ID"): triple (key, mask, offset). -- -- Every bucket has a smaller hash table keyed by source address -- (cf. RSVP flowspec) and one wildcard entry for wildcard reservations. -- Every bucket is again a list of "RSVP flows", selected by -- source address and SPI(="Source Port ID" here rather than -- "security parameter index"): triple (key, mask, offset). -- -- -- NOTE 1. All the packets with IPv6 extension headers (but AH and ESP) -- and all fragmented packets go to the best-effort traffic class. -- -- -- NOTE 2. Two "port id"'s seems to be redundant, rfc2207 requires -- only one "Generalized Port Identifier". So that for classic -- ah, esp (and udp,tcp) both *pi should coincide or one of them -- should be wildcard. -- -- At first sight, this redundancy is just a waste of CPU -- resources. But DPI and SPI add the possibility to assign different -- priorities to GPIs. Look also at note 4 about tunnels below. -- -- -- NOTE 3. One complication is the case of tunneled packets. -- We implement it as following: if the first lookup -- matches a special session with "tunnelhdr" value not zero, -- flowid doesn't contain the true flow ID, but the tunnel ID (1...255). -- In this case, we pull tunnelhdr bytes and restart lookup -- with tunnel ID added to the list of keys. Simple and stupid 8)8) -- It's enough for PIMREG and IPIP. -- -- -- NOTE 4. Two GPIs make it possible to parse even GRE packets. -- F.e. DPI can select ETH_P_IP (and necessary flags to make -- tunnelhdr correct) in GRE protocol field and SPI matches -- GRE key. Is it not nice? 8)8) -- -- -- Well, as result, despite its simplicity, we get a pretty -- powerful classification engine. */ -- -- --struct rsvp_head { -- u32 tmap[256/32]; -- u32 hgenerator; -- u8 tgenerator; -- struct rsvp_session __rcu *ht[256]; -- struct rcu_head rcu; --}; -- --struct rsvp_session { -- struct rsvp_session __rcu *next; -- __be32 dst[RSVP_DST_LEN]; -- struct tc_rsvp_gpi dpi; -- u8 protocol; -- u8 tunnelid; -- /* 16 (src,sport) hash slots, and one wildcard source slot */ -- struct rsvp_filter __rcu *ht[16 + 1]; -- struct rcu_head rcu; --}; -- -- --struct rsvp_filter { -- struct rsvp_filter __rcu *next; -- __be32 src[RSVP_DST_LEN]; -- struct tc_rsvp_gpi spi; -- u8 tunnelhdr; -- -- struct tcf_result res; -- struct tcf_exts exts; -- -- u32 handle; -- struct rsvp_session *sess; -- struct rcu_work rwork; --}; -- --static inline unsigned int hash_dst(__be32 *dst, u8 protocol, u8 tunnelid) --{ -- unsigned int h = (__force __u32)dst[RSVP_DST_LEN - 1]; -- -- h ^= h>>16; -- h ^= h>>8; -- return (h ^ protocol ^ tunnelid) & 0xFF; --} -- --static inline unsigned int hash_src(__be32 *src) --{ -- unsigned int h = (__force __u32)src[RSVP_DST_LEN-1]; -- -- h ^= h>>16; -- h ^= h>>8; -- h ^= h>>4; -- return h & 0xF; --} -- --#define RSVP_APPLY_RESULT() \ --{ \ -- int r = tcf_exts_exec(skb, &f->exts, res); \ -- if (r < 0) \ -- continue; \ -- else if (r > 0) \ -- return r; \ --} -- --static int rsvp_classify(struct sk_buff *skb, const struct tcf_proto *tp, -- struct tcf_result *res) --{ -- struct rsvp_head *head = rcu_dereference_bh(tp->root); -- struct rsvp_session *s; -- struct rsvp_filter *f; -- unsigned int h1, h2; -- __be32 *dst, *src; -- u8 protocol; -- u8 tunnelid = 0; -- u8 *xprt; --#if RSVP_DST_LEN == 4 -- struct ipv6hdr *nhptr; -- -- if (!pskb_network_may_pull(skb, sizeof(*nhptr))) -- return -1; -- nhptr = ipv6_hdr(skb); --#else -- struct iphdr *nhptr; -- -- if (!pskb_network_may_pull(skb, sizeof(*nhptr))) -- return -1; -- nhptr = ip_hdr(skb); --#endif --restart: -- --#if RSVP_DST_LEN == 4 -- src = &nhptr->saddr.s6_addr32[0]; -- dst = &nhptr->daddr.s6_addr32[0]; -- protocol = nhptr->nexthdr; -- xprt = ((u8 *)nhptr) + sizeof(struct ipv6hdr); --#else -- src = &nhptr->saddr; -- dst = &nhptr->daddr; -- protocol = nhptr->protocol; -- xprt = ((u8 *)nhptr) + (nhptr->ihl<<2); -- if (ip_is_fragment(nhptr)) -- return -1; --#endif -- -- h1 = hash_dst(dst, protocol, tunnelid); -- h2 = hash_src(src); -- -- for (s = rcu_dereference_bh(head->ht[h1]); s; -- s = rcu_dereference_bh(s->next)) { -- if (dst[RSVP_DST_LEN-1] == s->dst[RSVP_DST_LEN - 1] && -- protocol == s->protocol && -- !(s->dpi.mask & -- (*(u32 *)(xprt + s->dpi.offset) ^ s->dpi.key)) && --#if RSVP_DST_LEN == 4 -- dst[0] == s->dst[0] && -- dst[1] == s->dst[1] && -- dst[2] == s->dst[2] && --#endif -- tunnelid == s->tunnelid) { -- -- for (f = rcu_dereference_bh(s->ht[h2]); f; -- f = rcu_dereference_bh(f->next)) { -- if (src[RSVP_DST_LEN-1] == f->src[RSVP_DST_LEN - 1] && -- !(f->spi.mask & (*(u32 *)(xprt + f->spi.offset) ^ f->spi.key)) --#if RSVP_DST_LEN == 4 -- && -- src[0] == f->src[0] && -- src[1] == f->src[1] && -- src[2] == f->src[2] --#endif -- ) { -- *res = f->res; -- RSVP_APPLY_RESULT(); -- --matched: -- if (f->tunnelhdr == 0) -- return 0; -- -- tunnelid = f->res.classid; -- nhptr = (void *)(xprt + f->tunnelhdr - sizeof(*nhptr)); -- goto restart; -- } -- } -- -- /* And wildcard bucket... */ -- for (f = rcu_dereference_bh(s->ht[16]); f; -- f = rcu_dereference_bh(f->next)) { -- *res = f->res; -- RSVP_APPLY_RESULT(); -- goto matched; -- } -- return -1; -- } -- } -- return -1; --} -- --static void rsvp_replace(struct tcf_proto *tp, struct rsvp_filter *n, u32 h) --{ -- struct rsvp_head *head = rtnl_dereference(tp->root); -- struct rsvp_session *s; -- struct rsvp_filter __rcu **ins; -- struct rsvp_filter *pins; -- unsigned int h1 = h & 0xFF; -- unsigned int h2 = (h >> 8) & 0xFF; -- -- for (s = rtnl_dereference(head->ht[h1]); s; -- s = rtnl_dereference(s->next)) { -- for (ins = &s->ht[h2], pins = rtnl_dereference(*ins); ; -- ins = &pins->next, pins = rtnl_dereference(*ins)) { -- if (pins->handle == h) { -- RCU_INIT_POINTER(n->next, pins->next); -- rcu_assign_pointer(*ins, n); -- return; -- } -- } -- } -- -- /* Something went wrong if we are trying to replace a non-existent -- * node. Mind as well halt instead of silently failing. -- */ -- BUG_ON(1); --} -- --static void *rsvp_get(struct tcf_proto *tp, u32 handle) --{ -- struct rsvp_head *head = rtnl_dereference(tp->root); -- struct rsvp_session *s; -- struct rsvp_filter *f; -- unsigned int h1 = handle & 0xFF; -- unsigned int h2 = (handle >> 8) & 0xFF; -- -- if (h2 > 16) -- return NULL; -- -- for (s = rtnl_dereference(head->ht[h1]); s; -- s = rtnl_dereference(s->next)) { -- for (f = rtnl_dereference(s->ht[h2]); f; -- f = rtnl_dereference(f->next)) { -- if (f->handle == handle) -- return f; -- } -- } -- return NULL; --} -- --static int rsvp_init(struct tcf_proto *tp) --{ -- struct rsvp_head *data; -- -- data = kzalloc(sizeof(struct rsvp_head), GFP_KERNEL); -- if (data) { -- rcu_assign_pointer(tp->root, data); -- return 0; -- } -- return -ENOBUFS; --} -- --static void __rsvp_delete_filter(struct rsvp_filter *f) --{ -- tcf_exts_destroy(&f->exts); -- tcf_exts_put_net(&f->exts); -- kfree(f); --} -- --static void rsvp_delete_filter_work(struct work_struct *work) --{ -- struct rsvp_filter *f = container_of(to_rcu_work(work), -- struct rsvp_filter, -- rwork); -- rtnl_lock(); -- __rsvp_delete_filter(f); -- rtnl_unlock(); --} -- --static void rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f) --{ -- tcf_unbind_filter(tp, &f->res); -- /* all classifiers are required to call tcf_exts_destroy() after rcu -- * grace period, since converted-to-rcu actions are relying on that -- * in cleanup() callback -- */ -- if (tcf_exts_get_net(&f->exts)) -- tcf_queue_work(&f->rwork, rsvp_delete_filter_work); -- else -- __rsvp_delete_filter(f); --} -- --static void rsvp_destroy(struct tcf_proto *tp, bool rtnl_held, -- struct netlink_ext_ack *extack) --{ -- struct rsvp_head *data = rtnl_dereference(tp->root); -- int h1, h2; -- -- if (data == NULL) -- return; -- -- for (h1 = 0; h1 < 256; h1++) { -- struct rsvp_session *s; -- -- while ((s = rtnl_dereference(data->ht[h1])) != NULL) { -- RCU_INIT_POINTER(data->ht[h1], s->next); -- -- for (h2 = 0; h2 <= 16; h2++) { -- struct rsvp_filter *f; -- -- while ((f = rtnl_dereference(s->ht[h2])) != NULL) { -- rcu_assign_pointer(s->ht[h2], f->next); -- rsvp_delete_filter(tp, f); -- } -- } -- kfree_rcu(s, rcu); -- } -- } -- kfree_rcu(data, rcu); --} -- --static int rsvp_delete(struct tcf_proto *tp, void *arg, bool *last, -- bool rtnl_held, struct netlink_ext_ack *extack) --{ -- struct rsvp_head *head = rtnl_dereference(tp->root); -- struct rsvp_filter *nfp, *f = arg; -- struct rsvp_filter __rcu **fp; -- unsigned int h = f->handle; -- struct rsvp_session __rcu **sp; -- struct rsvp_session *nsp, *s = f->sess; -- int i, h1; -- -- fp = &s->ht[(h >> 8) & 0xFF]; -- for (nfp = rtnl_dereference(*fp); nfp; -- fp = &nfp->next, nfp = rtnl_dereference(*fp)) { -- if (nfp == f) { -- RCU_INIT_POINTER(*fp, f->next); -- rsvp_delete_filter(tp, f); -- -- /* Strip tree */ -- -- for (i = 0; i <= 16; i++) -- if (s->ht[i]) -- goto out; -- -- /* OK, session has no flows */ -- sp = &head->ht[h & 0xFF]; -- for (nsp = rtnl_dereference(*sp); nsp; -- sp = &nsp->next, nsp = rtnl_dereference(*sp)) { -- if (nsp == s) { -- RCU_INIT_POINTER(*sp, s->next); -- kfree_rcu(s, rcu); -- goto out; -- } -- } -- -- break; -- } -- } -- --out: -- *last = true; -- for (h1 = 0; h1 < 256; h1++) { -- if (rcu_access_pointer(head->ht[h1])) { -- *last = false; -- break; -- } -- } -- -- return 0; --} -- --static unsigned int gen_handle(struct tcf_proto *tp, unsigned salt) --{ -- struct rsvp_head *data = rtnl_dereference(tp->root); -- int i = 0xFFFF; -- -- while (i-- > 0) { -- u32 h; -- -- if ((data->hgenerator += 0x10000) == 0) -- data->hgenerator = 0x10000; -- h = data->hgenerator|salt; -- if (!rsvp_get(tp, h)) -- return h; -- } -- return 0; --} -- --static int tunnel_bts(struct rsvp_head *data) --{ -- int n = data->tgenerator >> 5; -- u32 b = 1 << (data->tgenerator & 0x1F); -- -- if (data->tmap[n] & b) -- return 0; -- data->tmap[n] |= b; -- return 1; --} -- --static void tunnel_recycle(struct rsvp_head *data) --{ -- struct rsvp_session __rcu **sht = data->ht; -- u32 tmap[256/32]; -- int h1, h2; -- -- memset(tmap, 0, sizeof(tmap)); -- -- for (h1 = 0; h1 < 256; h1++) { -- struct rsvp_session *s; -- for (s = rtnl_dereference(sht[h1]); s; -- s = rtnl_dereference(s->next)) { -- for (h2 = 0; h2 <= 16; h2++) { -- struct rsvp_filter *f; -- -- for (f = rtnl_dereference(s->ht[h2]); f; -- f = rtnl_dereference(f->next)) { -- if (f->tunnelhdr == 0) -- continue; -- data->tgenerator = f->res.classid; -- tunnel_bts(data); -- } -- } -- } -- } -- -- memcpy(data->tmap, tmap, sizeof(tmap)); --} -- --static u32 gen_tunnel(struct rsvp_head *data) --{ -- int i, k; -- -- for (k = 0; k < 2; k++) { -- for (i = 255; i > 0; i--) { -- if (++data->tgenerator == 0) -- data->tgenerator = 1; -- if (tunnel_bts(data)) -- return data->tgenerator; -- } -- tunnel_recycle(data); -- } -- return 0; --} -- --static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = { -- [TCA_RSVP_CLASSID] = { .type = NLA_U32 }, -- [TCA_RSVP_DST] = { .len = RSVP_DST_LEN * sizeof(u32) }, -- [TCA_RSVP_SRC] = { .len = RSVP_DST_LEN * sizeof(u32) }, -- [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, --}; -- --static int rsvp_change(struct net *net, struct sk_buff *in_skb, -- struct tcf_proto *tp, unsigned long base, -- u32 handle, struct nlattr **tca, -- void **arg, u32 flags, -- struct netlink_ext_ack *extack) --{ -- struct rsvp_head *data = rtnl_dereference(tp->root); -- struct rsvp_filter *f, *nfp; -- struct rsvp_filter __rcu **fp; -- struct rsvp_session *nsp, *s; -- struct rsvp_session __rcu **sp; -- struct tc_rsvp_pinfo *pinfo = NULL; -- struct nlattr *opt = tca[TCA_OPTIONS]; -- struct nlattr *tb[TCA_RSVP_MAX + 1]; -- struct tcf_exts e; -- unsigned int h1, h2; -- __be32 *dst; -- int err; -- -- if (opt == NULL) -- return handle ? -EINVAL : 0; -- -- err = nla_parse_nested_deprecated(tb, TCA_RSVP_MAX, opt, rsvp_policy, -- NULL); -- if (err < 0) -- return err; -- -- err = tcf_exts_init(&e, net, TCA_RSVP_ACT, TCA_RSVP_POLICE); -- if (err < 0) -- return err; -- err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, flags, -- extack); -- if (err < 0) -- goto errout2; -- -- f = *arg; -- if (f) { -- /* Node exists: adjust only classid */ -- struct rsvp_filter *n; -- -- if (f->handle != handle && handle) -- goto errout2; -- -- n = kmemdup(f, sizeof(*f), GFP_KERNEL); -- if (!n) { -- err = -ENOMEM; -- goto errout2; -- } -- -- err = tcf_exts_init(&n->exts, net, TCA_RSVP_ACT, -- TCA_RSVP_POLICE); -- if (err < 0) { -- kfree(n); -- goto errout2; -- } -- -- if (tb[TCA_RSVP_CLASSID]) { -- n->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID]); -- tcf_bind_filter(tp, &n->res, base); -- } -- -- tcf_exts_change(&n->exts, &e); -- rsvp_replace(tp, n, handle); -- return 0; -- } -- -- /* Now more serious part... */ -- err = -EINVAL; -- if (handle) -- goto errout2; -- if (tb[TCA_RSVP_DST] == NULL) -- goto errout2; -- -- err = -ENOBUFS; -- f = kzalloc(sizeof(struct rsvp_filter), GFP_KERNEL); -- if (f == NULL) -- goto errout2; -- -- err = tcf_exts_init(&f->exts, net, TCA_RSVP_ACT, TCA_RSVP_POLICE); -- if (err < 0) -- goto errout; -- h2 = 16; -- if (tb[TCA_RSVP_SRC]) { -- memcpy(f->src, nla_data(tb[TCA_RSVP_SRC]), sizeof(f->src)); -- h2 = hash_src(f->src); -- } -- if (tb[TCA_RSVP_PINFO]) { -- pinfo = nla_data(tb[TCA_RSVP_PINFO]); -- f->spi = pinfo->spi; -- f->tunnelhdr = pinfo->tunnelhdr; -- } -- if (tb[TCA_RSVP_CLASSID]) -- f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID]); -- -- dst = nla_data(tb[TCA_RSVP_DST]); -- h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0); -- -- err = -ENOMEM; -- if ((f->handle = gen_handle(tp, h1 | (h2<<8))) == 0) -- goto errout; -- -- if (f->tunnelhdr) { -- err = -EINVAL; -- if (f->res.classid > 255) -- goto errout; -- -- err = -ENOMEM; -- if (f->res.classid == 0 && -- (f->res.classid = gen_tunnel(data)) == 0) -- goto errout; -- } -- -- for (sp = &data->ht[h1]; -- (s = rtnl_dereference(*sp)) != NULL; -- sp = &s->next) { -- if (dst[RSVP_DST_LEN-1] == s->dst[RSVP_DST_LEN-1] && -- pinfo && pinfo->protocol == s->protocol && -- memcmp(&pinfo->dpi, &s->dpi, sizeof(s->dpi)) == 0 && --#if RSVP_DST_LEN == 4 -- dst[0] == s->dst[0] && -- dst[1] == s->dst[1] && -- dst[2] == s->dst[2] && --#endif -- pinfo->tunnelid == s->tunnelid) { -- --insert: -- /* OK, we found appropriate session */ -- -- fp = &s->ht[h2]; -- -- f->sess = s; -- if (f->tunnelhdr == 0) -- tcf_bind_filter(tp, &f->res, base); -- -- tcf_exts_change(&f->exts, &e); -- -- fp = &s->ht[h2]; -- for (nfp = rtnl_dereference(*fp); nfp; -- fp = &nfp->next, nfp = rtnl_dereference(*fp)) { -- __u32 mask = nfp->spi.mask & f->spi.mask; -- -- if (mask != f->spi.mask) -- break; -- } -- RCU_INIT_POINTER(f->next, nfp); -- rcu_assign_pointer(*fp, f); -- -- *arg = f; -- return 0; -- } -- } -- -- /* No session found. Create new one. */ -- -- err = -ENOBUFS; -- s = kzalloc(sizeof(struct rsvp_session), GFP_KERNEL); -- if (s == NULL) -- goto errout; -- memcpy(s->dst, dst, sizeof(s->dst)); -- -- if (pinfo) { -- s->dpi = pinfo->dpi; -- s->protocol = pinfo->protocol; -- s->tunnelid = pinfo->tunnelid; -- } -- sp = &data->ht[h1]; -- for (nsp = rtnl_dereference(*sp); nsp; -- sp = &nsp->next, nsp = rtnl_dereference(*sp)) { -- if ((nsp->dpi.mask & s->dpi.mask) != s->dpi.mask) -- break; -- } -- RCU_INIT_POINTER(s->next, nsp); -- rcu_assign_pointer(*sp, s); -- -- goto insert; -- --errout: -- tcf_exts_destroy(&f->exts); -- kfree(f); --errout2: -- tcf_exts_destroy(&e); -- return err; --} -- --static void rsvp_walk(struct tcf_proto *tp, struct tcf_walker *arg, -- bool rtnl_held) --{ -- struct rsvp_head *head = rtnl_dereference(tp->root); -- unsigned int h, h1; -- -- if (arg->stop) -- return; -- -- for (h = 0; h < 256; h++) { -- struct rsvp_session *s; -- -- for (s = rtnl_dereference(head->ht[h]); s; -- s = rtnl_dereference(s->next)) { -- for (h1 = 0; h1 <= 16; h1++) { -- struct rsvp_filter *f; -- -- for (f = rtnl_dereference(s->ht[h1]); f; -- f = rtnl_dereference(f->next)) { -- if (!tc_cls_stats_dump(tp, arg, f)) -- return; -- } -- } -- } -- } --} -- --static int rsvp_dump(struct net *net, struct tcf_proto *tp, void *fh, -- struct sk_buff *skb, struct tcmsg *t, bool rtnl_held) --{ -- struct rsvp_filter *f = fh; -- struct rsvp_session *s; -- struct nlattr *nest; -- struct tc_rsvp_pinfo pinfo; -- -- if (f == NULL) -- return skb->len; -- s = f->sess; -- -- t->tcm_handle = f->handle; -- -- nest = nla_nest_start_noflag(skb, TCA_OPTIONS); -- if (nest == NULL) -- goto nla_put_failure; -- -- if (nla_put(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst)) -- goto nla_put_failure; -- pinfo.dpi = s->dpi; -- pinfo.spi = f->spi; -- pinfo.protocol = s->protocol; -- pinfo.tunnelid = s->tunnelid; -- pinfo.tunnelhdr = f->tunnelhdr; -- pinfo.pad = 0; -- if (nla_put(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo)) -- goto nla_put_failure; -- if (f->res.classid && -- nla_put_u32(skb, TCA_RSVP_CLASSID, f->res.classid)) -- goto nla_put_failure; -- if (((f->handle >> 8) & 0xFF) != 16 && -- nla_put(skb, TCA_RSVP_SRC, sizeof(f->src), f->src)) -- goto nla_put_failure; -- -- if (tcf_exts_dump(skb, &f->exts) < 0) -- goto nla_put_failure; -- -- nla_nest_end(skb, nest); -- -- if (tcf_exts_dump_stats(skb, &f->exts) < 0) -- goto nla_put_failure; -- return skb->len; -- --nla_put_failure: -- nla_nest_cancel(skb, nest); -- return -1; --} -- --static void rsvp_bind_class(void *fh, u32 classid, unsigned long cl, void *q, -- unsigned long base) --{ -- struct rsvp_filter *f = fh; -- -- tc_cls_bind_class(classid, cl, q, &f->res, base); --} -- --static struct tcf_proto_ops RSVP_OPS __read_mostly = { -- .kind = RSVP_ID, -- .classify = rsvp_classify, -- .init = rsvp_init, -- .destroy = rsvp_destroy, -- .get = rsvp_get, -- .change = rsvp_change, -- .delete = rsvp_delete, -- .walk = rsvp_walk, -- .dump = rsvp_dump, -- .bind_class = rsvp_bind_class, -- .owner = THIS_MODULE, --}; -- --static int __init init_rsvp(void) --{ -- return register_tcf_proto_ops(&RSVP_OPS); --} -- --static void __exit exit_rsvp(void) --{ -- unregister_tcf_proto_ops(&RSVP_OPS); --} -- --module_init(init_rsvp) --module_exit(exit_rsvp) -diff --git a/net/sched/cls_rsvp6.c b/net/sched/cls_rsvp6.c -deleted file mode 100644 -index 64078846000ef..0000000000000 ---- a/net/sched/cls_rsvp6.c -+++ /dev/null -@@ -1,24 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * net/sched/cls_rsvp6.c Special RSVP packet classifier for IPv6. -- * -- * Authors: Alexey Kuznetsov, -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define RSVP_DST_LEN 4 --#define RSVP_ID "rsvp6" --#define RSVP_OPS cls_rsvp6_ops -- --#include "cls_rsvp.h" --MODULE_LICENSE("GPL"); -diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c -index d2ee566343083..b0258507b236c 100644 ---- a/net/sunrpc/clnt.c -+++ b/net/sunrpc/clnt.c -@@ -2710,7 +2710,7 @@ out_unparsable: - - out_verifier: - trace_rpc_bad_verifier(task); -- goto out_err; -+ goto out_garbage; - - out_msg_denied: - error = -EACCES; -diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c -index 581df7f4c5240..e7fa0608341d8 100644 ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -277,6 +277,11 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, - ether_addr_equal(req->bss->bssid, wdev->u.client.connected_addr)) - return -EALREADY; - -+ if (ether_addr_equal(req->bss->bssid, dev->dev_addr) || -+ (req->link_id >= 0 && -+ ether_addr_equal(req->ap_mld_addr, dev->dev_addr))) -+ return -EINVAL; -+ - return rdev_auth(rdev, dev, req); - } - -@@ -331,6 +336,9 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, - if (req->links[i].bss == req->links[j].bss) - return -EINVAL; - } -+ -+ if (ether_addr_equal(req->links[i].bss->bssid, dev->dev_addr)) -+ return -EINVAL; - } - - if (wdev->connected && -@@ -338,6 +346,11 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, - !ether_addr_equal(wdev->u.client.connected_addr, req->prev_bssid))) - return -EALREADY; - -+ if ((req->bss && ether_addr_equal(req->bss->bssid, dev->dev_addr)) || -+ (req->link_id >= 0 && -+ ether_addr_equal(req->ap_mld_addr, dev->dev_addr))) -+ return -EINVAL; -+ - cfg80211_oper_and_ht_capa(&req->ht_capa_mask, - rdev->wiphy.ht_capa_mod_mask); - cfg80211_oper_and_vht_capa(&req->vht_capa_mask, -diff --git a/net/wireless/ocb.c b/net/wireless/ocb.c -index 27a1732264f95..29afaf3da54f3 100644 ---- a/net/wireless/ocb.c -+++ b/net/wireless/ocb.c -@@ -68,6 +68,9 @@ int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, - if (!rdev->ops->leave_ocb) - return -EOPNOTSUPP; - -+ if (!wdev->u.ocb.chandef.chan) -+ return -ENOTCONN; -+ - err = rdev_leave_ocb(rdev, dev); - if (!err) - memset(&wdev->u.ocb.chandef, 0, sizeof(wdev->u.ocb.chandef)); -diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c -index 418c46fe5ffc3..b99322f188e59 100644 ---- a/samples/hw_breakpoint/data_breakpoint.c -+++ b/samples/hw_breakpoint/data_breakpoint.c -@@ -70,7 +70,9 @@ fail: - static void __exit hw_break_module_exit(void) - { - unregister_wide_hw_breakpoint(sample_hbp); -- symbol_put(ksym_name); -+#ifdef CONFIG_MODULE_UNLOAD -+ __symbol_put(ksym_name); -+#endif - printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name); - } - -diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c -index 26c9e4da4efcf..d88c399b0e86b 100644 ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2769,14 +2769,20 @@ static int selinux_umount(struct vfsmount *mnt, int flags) - static int selinux_fs_context_submount(struct fs_context *fc, - struct super_block *reference) - { -- const struct superblock_security_struct *sbsec; -+ const struct superblock_security_struct *sbsec = selinux_superblock(reference); - struct selinux_mnt_opts *opts; - -+ /* -+ * Ensure that fc->security remains NULL when no options are set -+ * as expected by selinux_set_mnt_opts(). -+ */ -+ if (!(sbsec->flags & (FSCONTEXT_MNT|CONTEXT_MNT|DEFCONTEXT_MNT))) -+ return 0; -+ - opts = kzalloc(sizeof(*opts), GFP_KERNEL); - if (!opts) - return -ENOMEM; - -- sbsec = selinux_superblock(reference); - if (sbsec->flags & FSCONTEXT_MNT) - opts->fscontext_sid = sbsec->sid; - if (sbsec->flags & CONTEXT_MNT) -diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c -index 317bdf6dcbef4..2873420c9aca8 100644 ---- a/sound/hda/intel-dsp-config.c -+++ b/sound/hda/intel-dsp-config.c -@@ -481,6 +481,14 @@ static const struct config_entry config_table[] = { - }, - #endif - -+/* Lunar Lake */ -+#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE) -+ /* Lunarlake-P */ -+ { -+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, -+ .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P, -+ }, -+#endif - }; - - static const struct config_entry *snd_intel_dsp_find_config -diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c -index 064b6feb76167..414ac90273810 100644 ---- a/sound/soc/intel/boards/sof_sdw.c -+++ b/sound/soc/intel/boards/sof_sdw.c -@@ -388,7 +388,9 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { - DMI_MATCH(DMI_SYS_VENDOR, "Google"), - DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), - }, -- .driver_data = (void *)(SOF_SDW_PCH_DMIC), -+ .driver_data = (void *)(SOF_SDW_PCH_DMIC | -+ SOF_BT_OFFLOAD_SSP(1) | -+ SOF_SSP_BT_OFFLOAD_PRESENT), - }, - /* LunarLake devices */ - { -diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c -index 872e44408298f..e7305ce57ea1f 100644 ---- a/sound/soc/sof/topology.c -+++ b/sound/soc/sof/topology.c -@@ -1086,16 +1086,17 @@ static void sof_disconnect_dai_widget(struct snd_soc_component *scomp, - { - struct snd_soc_card *card = scomp->card; - struct snd_soc_pcm_runtime *rtd; -+ const char *sname = w->sname; - struct snd_soc_dai *cpu_dai; - int i; - -- if (!w->sname) -+ if (!sname) - return; - - list_for_each_entry(rtd, &card->rtd_list, list) { - /* does stream match DAI link ? */ - if (!rtd->dai_link->stream_name || -- strcmp(w->sname, rtd->dai_link->stream_name)) -+ strcmp(sname, rtd->dai_link->stream_name)) - continue; - - switch (w->id) { -diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c -index f8deae4e26a15..44bbf80f0cfdd 100644 ---- a/tools/iio/iio_generic_buffer.c -+++ b/tools/iio/iio_generic_buffer.c -@@ -51,9 +51,9 @@ enum autochan { - * Has the side effect of filling the channels[i].location values used - * in processing the buffer output. - **/ --static int size_from_channelarray(struct iio_channel_info *channels, int num_channels) -+static unsigned int size_from_channelarray(struct iio_channel_info *channels, int num_channels) - { -- int bytes = 0; -+ unsigned int bytes = 0; - int i = 0; - - while (i < num_channels) { -@@ -348,7 +348,7 @@ int main(int argc, char **argv) - ssize_t read_size; - int dev_num = -1, trig_num = -1; - char *buffer_access = NULL; -- int scan_size; -+ unsigned int scan_size; - int noevents = 0; - int notrigger = 0; - char *dummy; -@@ -674,7 +674,16 @@ int main(int argc, char **argv) - } - - scan_size = size_from_channelarray(channels, num_channels); -- data = malloc(scan_size * buf_len); -+ -+ size_t total_buf_len = scan_size * buf_len; -+ -+ if (scan_size > 0 && total_buf_len / scan_size != buf_len) { -+ ret = -EFAULT; -+ perror("Integer overflow happened when calculate scan_size * buf_len"); -+ goto error; -+ } -+ -+ data = malloc(total_buf_len); - if (!data) { - ret = -ENOMEM; - goto error; -diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c -index eeb2693128d8a..10f15a3e3a95e 100644 ---- a/tools/lib/bpf/libbpf.c -+++ b/tools/lib/bpf/libbpf.c -@@ -8173,6 +8173,7 @@ void bpf_object__close(struct bpf_object *obj) - bpf_object__elf_finish(obj); - bpf_object_unload(obj); - btf__free(obj->btf); -+ btf__free(obj->btf_vmlinux); - btf_ext__free(obj->btf_ext); - - for (i = 0; i < obj->nr_maps; i++) -diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest -index c3311c8c40890..ef0edb7a71e37 100755 ---- a/tools/testing/selftests/ftrace/ftracetest -+++ b/tools/testing/selftests/ftrace/ftracetest -@@ -30,6 +30,9 @@ err_ret=1 - # kselftest skip code is 4 - err_skip=4 - -+# umount required -+UMOUNT_DIR="" -+ - # cgroup RT scheduling prevents chrt commands from succeeding, which - # induces failures in test wakeup tests. Disable for the duration of - # the tests. -@@ -44,6 +47,9 @@ setup() { - - cleanup() { - echo $sched_rt_runtime_orig > $sched_rt_runtime -+ if [ -n "${UMOUNT_DIR}" ]; then -+ umount ${UMOUNT_DIR} ||: -+ fi - } - - errexit() { # message -@@ -155,11 +161,13 @@ if [ -z "$TRACING_DIR" ]; then - mount -t tracefs nodev /sys/kernel/tracing || - errexit "Failed to mount /sys/kernel/tracing" - TRACING_DIR="/sys/kernel/tracing" -+ UMOUNT_DIR=${TRACING_DIR} - # If debugfs exists, then so does /sys/kernel/debug - elif [ -d "/sys/kernel/debug" ]; then - mount -t debugfs nodev /sys/kernel/debug || - errexit "Failed to mount /sys/kernel/debug" - TRACING_DIR="/sys/kernel/debug/tracing" -+ UMOUNT_DIR=${TRACING_DIR} - else - err_ret=$err_skip - errexit "debugfs and tracefs are not configured in this kernel" -diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c -index 78bced95ac630..f8e8e8d2a5e18 100644 ---- a/tools/testing/selftests/nolibc/nolibc-test.c -+++ b/tools/testing/selftests/nolibc/nolibc-test.c -@@ -630,6 +630,35 @@ static struct test test_names[] = { - { 0 } - }; - -+int is_setting_valid(char *test) -+{ -+ int idx, len, test_len, valid = 0; -+ char delimiter; -+ -+ if (!test) -+ return valid; -+ -+ test_len = strlen(test); -+ -+ for (idx = 0; test_names[idx].name; idx++) { -+ len = strlen(test_names[idx].name); -+ if (test_len < len) -+ continue; -+ -+ if (strncmp(test, test_names[idx].name, len) != 0) -+ continue; -+ -+ delimiter = test[len]; -+ if (delimiter != ':' && delimiter != ',' && delimiter != '\0') -+ continue; -+ -+ valid = 1; -+ break; -+ } -+ -+ return valid; -+} -+ - int main(int argc, char **argv, char **envp) - { - int min = 0; -@@ -655,10 +684,10 @@ int main(int argc, char **argv, char **envp) - * syscall:5-15[:.*],stdlib:8-10 - */ - test = argv[1]; -- if (!test) -+ if (!is_setting_valid(test)) - test = getenv("NOLIBC_TEST"); - -- if (test) { -+ if (is_setting_valid(test)) { - char *comma, *colon, *dash, *value; - - do { -diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/rsvp.json b/tools/testing/selftests/tc-testing/tc-tests/filters/rsvp.json -deleted file mode 100644 -index bdcbaa4c5663d..0000000000000 ---- a/tools/testing/selftests/tc-testing/tc-tests/filters/rsvp.json -+++ /dev/null -@@ -1,203 +0,0 @@ --[ -- { -- "id": "2141", -- "name": "Add rsvp filter with tcp proto and specific IP address", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress" -- ], -- "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto tcp session 198.168.10.64", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "^filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh 0x.*session 198.168.10.64 ipproto tcp", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- }, -- { -- "id": "5267", -- "name": "Add rsvp filter with udp proto and specific IP address", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress" -- ], -- "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto udp session 1.1.1.1", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "^filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh 0x.*session 1.1.1.1 ipproto udp", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- }, -- { -- "id": "2819", -- "name": "Add rsvp filter with src ip and src port", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress" -- ], -- "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto udp session 1.1.1.1 sender 2.2.2.2/5021 classid 1:1", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "^filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh 0x.*flowid 1:1 session 1.1.1.1 ipproto udp sender 2.2.2.2/5021", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- }, -- { -- "id": "c967", -- "name": "Add rsvp filter with tunnelid and continue action", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress" -- ], -- "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto udp session 1.1.1.1 tunnelid 2 classid 1:1 action continue", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "^filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh 0x.*flowid 1:1 session 1.1.1.1 ipproto udp tunnelid 2.*action order [0-9]+: gact action continue", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- }, -- { -- "id": "5463", -- "name": "Add rsvp filter with tunnel and pipe action", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress" -- ], -- "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto udp session 1.1.1.1 tunnel 2 skip 1 action pipe", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "^filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh 0x.*tunnel 2 skip 1 session 1.1.1.1 ipproto udp.*action order [0-9]+: gact action pipe", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- }, -- { -- "id": "2332", -- "name": "Add rsvp filter with miltiple actions", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress" -- ], -- "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 7 rsvp ipproto udp session 1.1.1.1 classid 1:1 action skbedit mark 7 pipe action gact drop", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "^filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh 0x.*flowid 1:1 session 1.1.1.1 ipproto udp.*action order [0-9]+: skbedit mark 7 pipe.*action order [0-9]+: gact action drop", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- }, -- { -- "id": "8879", -- "name": "Add rsvp filter with tunnel and skp flag", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress" -- ], -- "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto udp session 1.1.1.1 tunnel 2 skip 1 action pipe", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "^filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh 0x.*tunnel 2 skip 1 session 1.1.1.1 ipproto udp.*action order [0-9]+: gact action pipe", -- "matchCount": "1", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- }, -- { -- "id": "8261", -- "name": "List rsvp filters", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress", -- "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto udp session 1.1.1.1/1234 classid 1:1", -- "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto tcp session 2.2.2.2/1234 classid 2:1" -- ], -- "cmdUnderTest": "$TC filter show dev $DEV1 parent ffff:", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "^filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh", -- "matchCount": "2", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- }, -- { -- "id": "8989", -- "name": "Delete rsvp filter", -- "category": [ -- "filter", -- "rsvp" -- ], -- "plugins": { -- "requires": "nsPlugin" -- }, -- "setup": [ -- "$TC qdisc add dev $DEV1 ingress", -- "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto udp session 1.1.1.1/1234 tunnelid 9 classid 2:1" -- ], -- "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: protocol ip prio 1 rsvp ipproto udp session 1.1.1.1/1234 tunnelid 9 classid 2:1", -- "expExitCode": "0", -- "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", -- "matchPattern": "filter protocol ip pref [0-9]+ rsvp chain [0-9]+ fh 0x.*flowid 2:1 session 1.1.1.1/1234 ipproto udp tunnelid 9", -- "matchCount": "0", -- "teardown": [ -- "$TC qdisc del dev $DEV1 ingress" -- ] -- } --] diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.55-56.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.55-56.patch deleted file mode 100644 index c67d69e59521..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.55-56.patch +++ /dev/null @@ -1,11323 +0,0 @@ -diff --git a/Documentation/admin-guide/cgroup-v1/memory.rst b/Documentation/admin-guide/cgroup-v1/memory.rst -index 2524061836acc..40164f2881e17 100644 ---- a/Documentation/admin-guide/cgroup-v1/memory.rst -+++ b/Documentation/admin-guide/cgroup-v1/memory.rst -@@ -91,8 +91,13 @@ Brief summary of control files. - memory.oom_control set/show oom controls. - memory.numa_stat show the number of memory usage per numa - node -- memory.kmem.limit_in_bytes This knob is deprecated and writing to -- it will return -ENOTSUPP. -+ memory.kmem.limit_in_bytes Deprecated knob to set and read the kernel -+ memory hard limit. Kernel hard limit is not -+ supported since 5.16. Writing any value to -+ do file will not have any effect same as if -+ nokmem kernel parameter was specified. -+ Kernel memory is still charged and reported -+ by memory.kmem.usage_in_bytes. - memory.kmem.usage_in_bytes show current kernel memory allocation - memory.kmem.failcnt show the number of kernel memory usage - hits limits -diff --git a/Makefile b/Makefile -index 3d839824a7224..9ceda3dad5eb7 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 55 -+SUBLEVEL = 56 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/am335x-guardian.dts b/arch/arm/boot/dts/am335x-guardian.dts -index f6356266564c8..b357364e93f99 100644 ---- a/arch/arm/boot/dts/am335x-guardian.dts -+++ b/arch/arm/boot/dts/am335x-guardian.dts -@@ -103,8 +103,9 @@ - - }; - -- guardian_beeper: dmtimer-pwm@7 { -+ guardian_beeper: pwm-7 { - compatible = "ti,omap-dmtimer-pwm"; -+ #pwm-cells = <3>; - ti,timers = <&timer7>; - pinctrl-names = "default"; - pinctrl-0 = <&guardian_beeper_pins>; -diff --git a/arch/arm/boot/dts/am3517-evm.dts b/arch/arm/boot/dts/am3517-evm.dts -index 35b653014f2b0..7bab0a9dadb30 100644 ---- a/arch/arm/boot/dts/am3517-evm.dts -+++ b/arch/arm/boot/dts/am3517-evm.dts -@@ -150,7 +150,7 @@ - enable-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* gpio_182 */ - }; - -- pwm11: dmtimer-pwm@11 { -+ pwm11: pwm-11 { - compatible = "ti,omap-dmtimer-pwm"; - pinctrl-names = "default"; - pinctrl-0 = <&pwm_pins>; -diff --git a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts -index f1412ba83defb..0454423fe166c 100644 ---- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts -+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts -@@ -19,7 +19,8 @@ - - memory@0 { - device_type = "memory"; -- reg = <0x00000000 0x08000000>; -+ reg = <0x00000000 0x08000000>, -+ <0x88000000 0x08000000>; - }; - - gpio-keys { -diff --git a/arch/arm/boot/dts/exynos4210-i9100.dts b/arch/arm/boot/dts/exynos4210-i9100.dts -index bba85011ecc93..53e023fc1cacf 100644 ---- a/arch/arm/boot/dts/exynos4210-i9100.dts -+++ b/arch/arm/boot/dts/exynos4210-i9100.dts -@@ -201,8 +201,8 @@ - power-on-delay = <10>; - reset-delay = <10>; - -- panel-width-mm = <90>; -- panel-height-mm = <154>; -+ panel-width-mm = <56>; -+ panel-height-mm = <93>; - - display-timings { - timing { -diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi -index d3da8b1b473b8..e0cbac500e172 100644 ---- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi -+++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi -@@ -59,7 +59,7 @@ - }; - }; - -- pwm10: dmtimer-pwm { -+ pwm10: pwm-10 { - compatible = "ti,omap-dmtimer-pwm"; - pinctrl-names = "default"; - pinctrl-0 = <&pwm_pins>; -diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi -index c7a1f3ffc48ca..d69f0f4b4990d 100644 ---- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi -+++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi -@@ -133,7 +133,7 @@ - dais = <&mcbsp2_port>, <&mcbsp3_port>; - }; - -- pwm8: dmtimer-pwm-8 { -+ pwm8: pwm-8 { - pinctrl-names = "default"; - pinctrl-0 = <&vibrator_direction_pin>; - -@@ -143,7 +143,7 @@ - ti,clock-source = <0x01>; - }; - -- pwm9: dmtimer-pwm-9 { -+ pwm9: pwm-9 { - pinctrl-names = "default"; - pinctrl-0 = <&vibrator_enable_pin>; - -@@ -352,13 +352,13 @@ - &omap4_pmx_core { - - /* hdmi_hpd.gpio_63 */ -- hdmi_hpd_gpio: pinmux_hdmi_hpd_pins { -+ hdmi_hpd_gpio: hdmi-hpd-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3) - >; - }; - -- hdq_pins: pinmux_hdq_pins { -+ hdq_pins: hdq-pins { - pinctrl-single,pins = < - /* 0x4a100120 hdq_sio.hdq_sio aa27 */ - OMAP4_IOPAD(0x120, PIN_INPUT | MUX_MODE0) -@@ -366,7 +366,7 @@ - }; - - /* hdmi_cec.hdmi_cec, hdmi_scl.hdmi_scl, hdmi_sda.hdmi_sda */ -- dss_hdmi_pins: pinmux_dss_hdmi_pins { -+ dss_hdmi_pins: dss-hdmi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) - OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) -@@ -380,7 +380,7 @@ - * devices. Off mode value should be tested if we have off mode working - * later on. - */ -- mmc3_pins: pinmux_mmc3_pins { -+ mmc3_pins: mmc3-pins { - pinctrl-single,pins = < - /* 0x4a10008e gpmc_wait2.gpio_100 d23 */ - OMAP4_IOPAD(0x08e, PIN_INPUT | MUX_MODE3) -@@ -406,40 +406,40 @@ - }; - - /* gpmc_ncs0.gpio_50 */ -- poweroff_gpio: pinmux_poweroff_pins { -+ poweroff_gpio: poweroff-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x074, PIN_OUTPUT_PULLUP | MUX_MODE3) - >; - }; - - /* kpd_row0.gpio_178 */ -- tmp105_irq: pinmux_tmp105_irq { -+ tmp105_irq: tmp105-irq-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x18e, PIN_INPUT_PULLUP | MUX_MODE3) - >; - }; - -- usb_gpio_mux_sel1: pinmux_usb_gpio_mux_sel1_pins { -+ usb_gpio_mux_sel1: usb-gpio-mux-sel1-pins { - /* gpio_60 */ - pinctrl-single,pins = < - OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3) - >; - }; - -- touchscreen_pins: pinmux_touchscreen_pins { -+ touchscreen_pins: touchscreen-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x180, PIN_OUTPUT | MUX_MODE3) - OMAP4_IOPAD(0x1a0, PIN_INPUT_PULLUP | MUX_MODE3) - >; - }; - -- als_proximity_pins: pinmux_als_proximity_pins { -+ als_proximity_pins: als-proximity-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x18c, PIN_INPUT_PULLUP | MUX_MODE3) - >; - }; - -- usb_mdm6600_pins: pinmux_usb_mdm6600_pins { -+ usb_mdm6600_pins: usb-mdm6600-pins { - pinctrl-single,pins = < - /* enable 0x4a1000d8 usbb1_ulpitll_dat7.gpio_95 ag16 */ - OMAP4_IOPAD(0x0d8, PIN_INPUT | MUX_MODE3) -@@ -476,7 +476,7 @@ - >; - }; - -- usb_ulpi_pins: pinmux_usb_ulpi_pins { -+ usb_ulpi_pins: usb-ulpi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x196, MUX_MODE7) - OMAP4_IOPAD(0x198, MUX_MODE7) -@@ -496,7 +496,7 @@ - }; - - /* usb0_otg_dp and usb0_otg_dm */ -- usb_utmi_pins: pinmux_usb_utmi_pins { -+ usb_utmi_pins: usb-utmi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x196, PIN_INPUT | MUX_MODE0) - OMAP4_IOPAD(0x198, PIN_INPUT | MUX_MODE0) -@@ -521,7 +521,7 @@ - * when not used. If needed, we can add rts pin remux later based - * on power measurements. - */ -- uart1_pins: pinmux_uart1_pins { -+ uart1_pins: uart1-pins { - pinctrl-single,pins = < - /* 0x4a10013c mcspi1_cs2.uart1_cts ag23 */ - OMAP4_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE1) -@@ -538,7 +538,7 @@ - }; - - /* uart3_tx_irtx and uart3_rx_irrx */ -- uart3_pins: pinmux_uart3_pins { -+ uart3_pins: uart3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x196, MUX_MODE7) - OMAP4_IOPAD(0x198, MUX_MODE7) -@@ -557,7 +557,7 @@ - >; - }; - -- uart4_pins: pinmux_uart4_pins { -+ uart4_pins: uart4-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0) /* uart4_rx */ - OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0) /* uart4_tx */ -@@ -566,7 +566,7 @@ - >; - }; - -- mcbsp2_pins: pinmux_mcbsp2_pins { -+ mcbsp2_pins: mcbsp2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_clkx */ - OMAP4_IOPAD(0x0f8, PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_dr */ -@@ -575,7 +575,7 @@ - >; - }; - -- mcbsp3_pins: pinmux_mcbsp3_pins { -+ mcbsp3_pins: mcbsp3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x106, PIN_INPUT | MUX_MODE1) /* abe_mcbsp3_dr */ - OMAP4_IOPAD(0x108, PIN_OUTPUT | MUX_MODE1) /* abe_mcbsp3_dx */ -@@ -584,13 +584,13 @@ - >; - }; - -- vibrator_direction_pin: pinmux_vibrator_direction_pin { -+ vibrator_direction_pin: vibrator-direction-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x1ce, PIN_OUTPUT | MUX_MODE1) /* dmtimer8_pwm_evt (gpio_27) */ - >; - }; - -- vibrator_enable_pin: pinmux_vibrator_enable_pin { -+ vibrator_enable_pin: vibrator-enable-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0X1d0, PIN_OUTPUT | MUX_MODE1) /* dmtimer9_pwm_evt (gpio_28) */ - >; -@@ -598,7 +598,7 @@ - }; - - &omap4_pmx_wkup { -- usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins { -+ usb_gpio_mux_sel2: usb-gpio-mux-sel2-pins { - /* gpio_wk0 */ - pinctrl-single,pins = < - OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3) -@@ -614,12 +614,12 @@ - /* Configure pwm clock source for timers 8 & 9 */ - &timer8 { - assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>; -- assigned-clock-parents = <&sys_clkin_ck>; -+ assigned-clock-parents = <&sys_32k_ck>; - }; - - &timer9 { - assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>; -- assigned-clock-parents = <&sys_clkin_ck>; -+ assigned-clock-parents = <&sys_32k_ck>; - }; - - /* -diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi -index ce6c235f68ec6..3046ec572632d 100644 ---- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi -+++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi -@@ -8,9 +8,9 @@ - - / { - vddvario: regulator-vddvario { -- compatible = "regulator-fixed"; -- regulator-name = "vddvario"; -- regulator-always-on; -+ compatible = "regulator-fixed"; -+ regulator-name = "vddvario"; -+ regulator-always-on; - }; - - vdd33a: regulator-vdd33a { -diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi -index e7534fe9c53cf..bc8961f3690f0 100644 ---- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi -+++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi -@@ -12,9 +12,9 @@ - - / { - vddvario: regulator-vddvario { -- compatible = "regulator-fixed"; -- regulator-name = "vddvario"; -- regulator-always-on; -+ compatible = "regulator-fixed"; -+ regulator-name = "vddvario"; -+ regulator-always-on; - }; - - vdd33a: regulator-vdd33a { -diff --git a/arch/arm/boot/dts/omap3-cm-t3517.dts b/arch/arm/boot/dts/omap3-cm-t3517.dts -index 3b8349094baa6..f25c0a84a190c 100644 ---- a/arch/arm/boot/dts/omap3-cm-t3517.dts -+++ b/arch/arm/boot/dts/omap3-cm-t3517.dts -@@ -11,12 +11,12 @@ - model = "CompuLab CM-T3517"; - compatible = "compulab,omap3-cm-t3517", "ti,am3517", "ti,omap3"; - -- vmmc: regulator-vmmc { -- compatible = "regulator-fixed"; -- regulator-name = "vmmc"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- }; -+ vmmc: regulator-vmmc { -+ compatible = "regulator-fixed"; -+ regulator-name = "vmmc"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; - - wl12xx_vmmc2: wl12xx_vmmc2 { - compatible = "regulator-fixed"; -diff --git a/arch/arm/boot/dts/omap3-cpu-thermal.dtsi b/arch/arm/boot/dts/omap3-cpu-thermal.dtsi -index 0da759f8e2c2d..7dd2340bc5e45 100644 ---- a/arch/arm/boot/dts/omap3-cpu-thermal.dtsi -+++ b/arch/arm/boot/dts/omap3-cpu-thermal.dtsi -@@ -12,8 +12,7 @@ cpu_thermal: cpu-thermal { - polling-delay = <1000>; /* milliseconds */ - coefficients = <0 20000>; - -- /* sensor ID */ -- thermal-sensors = <&bandgap 0>; -+ thermal-sensors = <&bandgap>; - - cpu_trips: trips { - cpu_alert0: cpu_alert { -diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi -index 2dbee248a126f..e0be0fb23f80f 100644 ---- a/arch/arm/boot/dts/omap3-gta04.dtsi -+++ b/arch/arm/boot/dts/omap3-gta04.dtsi -@@ -147,7 +147,7 @@ - pinctrl-0 = <&backlight_pins>; - }; - -- pwm11: dmtimer-pwm { -+ pwm11: pwm-11 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer11>; - #pwm-cells = <3>; -@@ -332,7 +332,7 @@ - OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */ - OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */ - >; -- }; -+ }; - - gps_pins: pinmux_gps_pins { - pinctrl-single,pins = < -@@ -869,8 +869,8 @@ - }; - - &hdqw1w { -- pinctrl-names = "default"; -- pinctrl-0 = <&hdq_pins>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdq_pins>; - }; - - /* image signal processor within OMAP3 SoC */ -diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts -index 36fc8805e0c15..85f33bbb566f9 100644 ---- a/arch/arm/boot/dts/omap3-ldp.dts -+++ b/arch/arm/boot/dts/omap3-ldp.dts -@@ -301,5 +301,5 @@ - - &vaux1 { - /* Needed for ads7846 */ -- regulator-name = "vcc"; -+ regulator-name = "vcc"; - }; -diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts -index dd79715564498..89ab08d83261a 100644 ---- a/arch/arm/boot/dts/omap3-n900.dts -+++ b/arch/arm/boot/dts/omap3-n900.dts -@@ -156,7 +156,7 @@ - io-channel-names = "temp", "bsi", "vbat"; - }; - -- pwm9: dmtimer-pwm { -+ pwm9: pwm-9 { - compatible = "ti,omap-dmtimer-pwm"; - #pwm-cells = <3>; - ti,timers = <&timer9>; -@@ -236,27 +236,27 @@ - pinctrl-single,pins = < - - /* address lines */ -- OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0) /* gpmc_a1.gpmc_a1 */ -- OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0) /* gpmc_a2.gpmc_a2 */ -- OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0) /* gpmc_a3.gpmc_a3 */ -+ OMAP3_CORE1_IOPAD(0x207a, PIN_OUTPUT | MUX_MODE0) /* gpmc_a1.gpmc_a1 */ -+ OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE0) /* gpmc_a2.gpmc_a2 */ -+ OMAP3_CORE1_IOPAD(0x207e, PIN_OUTPUT | MUX_MODE0) /* gpmc_a3.gpmc_a3 */ - - /* data lines, gpmc_d0..d7 not muxable according to TRM */ -- OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0) /* gpmc_d8.gpmc_d8 */ -- OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0) /* gpmc_d9.gpmc_d9 */ -- OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0) /* gpmc_d10.gpmc_d10 */ -- OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0) /* gpmc_d11.gpmc_d11 */ -- OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0) /* gpmc_d12.gpmc_d12 */ -- OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0) /* gpmc_d13.gpmc_d13 */ -- OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0) /* gpmc_d14.gpmc_d14 */ -- OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0) /* gpmc_d15.gpmc_d15 */ -+ OMAP3_CORE1_IOPAD(0x209e, PIN_INPUT | MUX_MODE0) /* gpmc_d8.gpmc_d8 */ -+ OMAP3_CORE1_IOPAD(0x20a0, PIN_INPUT | MUX_MODE0) /* gpmc_d9.gpmc_d9 */ -+ OMAP3_CORE1_IOPAD(0x20a2, PIN_INPUT | MUX_MODE0) /* gpmc_d10.gpmc_d10 */ -+ OMAP3_CORE1_IOPAD(0x20a4, PIN_INPUT | MUX_MODE0) /* gpmc_d11.gpmc_d11 */ -+ OMAP3_CORE1_IOPAD(0x20a6, PIN_INPUT | MUX_MODE0) /* gpmc_d12.gpmc_d12 */ -+ OMAP3_CORE1_IOPAD(0x20a8, PIN_INPUT | MUX_MODE0) /* gpmc_d13.gpmc_d13 */ -+ OMAP3_CORE1_IOPAD(0x20aa, PIN_INPUT | MUX_MODE0) /* gpmc_d14.gpmc_d14 */ -+ OMAP3_CORE1_IOPAD(0x20ac, PIN_INPUT | MUX_MODE0) /* gpmc_d15.gpmc_d15 */ - - /* - * gpmc_ncs0, gpmc_nadv_ale, gpmc_noe, gpmc_nwe, gpmc_wait0 not muxable - * according to TRM. OneNAND seems to require PIN_INPUT on clock. - */ -- OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs1.gpmc_ncs1 */ -- OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */ -- >; -+ OMAP3_CORE1_IOPAD(0x20b0, PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs1.gpmc_ncs1 */ -+ OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */ -+ >; - }; - - i2c1_pins: pinmux_i2c1_pins { -@@ -738,12 +738,12 @@ - - si4713: si4713@63 { - compatible = "silabs,si4713"; -- reg = <0x63>; -+ reg = <0x63>; - -- interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */ -- reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */ -- vio-supply = <&vio>; -- vdd-supply = <&vaux1>; -+ interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */ -+ reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */ -+ vio-supply = <&vio>; -+ vdd-supply = <&vaux1>; - }; - - bq24150a: bq24150a@6b { -diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts -index 0482676d18306..ce58b1f208e81 100644 ---- a/arch/arm/boot/dts/omap3-zoom3.dts -+++ b/arch/arm/boot/dts/omap3-zoom3.dts -@@ -23,9 +23,9 @@ - }; - - vddvario: regulator-vddvario { -- compatible = "regulator-fixed"; -- regulator-name = "vddvario"; -- regulator-always-on; -+ compatible = "regulator-fixed"; -+ regulator-name = "vddvario"; -+ regulator-always-on; - }; - - vdd33a: regulator-vdd33a { -@@ -84,28 +84,28 @@ - - uart1_pins: pinmux_uart1_pins { - pinctrl-single,pins = < -- OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0) /* uart1_cts.uart1_cts */ -- OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0) /* uart1_rts.uart1_rts */ -- OMAP3_CORE1_IOPAD(0x2182, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */ -- OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */ -+ OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT | MUX_MODE0) /* uart1_cts.uart1_cts */ -+ OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE0) /* uart1_rts.uart1_rts */ -+ OMAP3_CORE1_IOPAD(0x2182, WAKEUP_EN | PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */ -+ OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */ - >; - }; - - uart2_pins: pinmux_uart2_pins { - pinctrl-single,pins = < -- OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ -- OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ -- OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */ -- OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */ -+ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ -+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ -+ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */ -+ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */ - >; - }; - - uart3_pins: pinmux_uart3_pins { - pinctrl-single,pins = < -- OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ -- OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ -- OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ -- OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */ -+ OMAP3_CORE1_IOPAD(0x219a, PIN_INPUT_PULLDOWN | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ -+ OMAP3_CORE1_IOPAD(0x219c, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ -+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ -+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */ - >; - }; - -@@ -205,22 +205,22 @@ - }; - - &uart1 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart1_pins>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; - }; - - &uart2 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart2_pins>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins>; - }; - - &uart3 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart3_pins>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins>; - }; - - &uart4 { -- status = "disabled"; -+ status = "disabled"; - }; - - &usb_otg_hs { -diff --git a/arch/arm/boot/dts/omap4-cpu-thermal.dtsi b/arch/arm/boot/dts/omap4-cpu-thermal.dtsi -index 4d7eeb133dadd..d484ec1e4fd86 100644 ---- a/arch/arm/boot/dts/omap4-cpu-thermal.dtsi -+++ b/arch/arm/boot/dts/omap4-cpu-thermal.dtsi -@@ -12,21 +12,24 @@ cpu_thermal: cpu_thermal { - polling-delay-passive = <250>; /* milliseconds */ - polling-delay = <1000>; /* milliseconds */ - -- /* sensor ID */ -- thermal-sensors = <&bandgap 0>; -+ /* -+ * See 44xx files for single sensor addressing, omap5 and dra7 need -+ * also sensor ID for addressing. -+ */ -+ thermal-sensors = <&bandgap 0>; - - cpu_trips: trips { -- cpu_alert0: cpu_alert { -- temperature = <100000>; /* millicelsius */ -- hysteresis = <2000>; /* millicelsius */ -- type = "passive"; -- }; -- cpu_crit: cpu_crit { -- temperature = <125000>; /* millicelsius */ -- hysteresis = <2000>; /* millicelsius */ -- type = "critical"; -- }; -- }; -+ cpu_alert0: cpu_alert { -+ temperature = <100000>; /* millicelsius */ -+ hysteresis = <2000>; /* millicelsius */ -+ type = "passive"; -+ }; -+ cpu_crit: cpu_crit { -+ temperature = <125000>; /* millicelsius */ -+ hysteresis = <2000>; /* millicelsius */ -+ type = "critical"; -+ }; -+ }; - - cpu_cooling_maps: cooling-maps { - map0 { -diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts -index b294c22177cbf..6d1beb453234e 100644 ---- a/arch/arm/boot/dts/omap4-duovero-parlor.dts -+++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts -@@ -62,33 +62,33 @@ - &smsc_pins - >; - -- led_pins: pinmux_led_pins { -+ led_pins: led-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x116, PIN_OUTPUT | MUX_MODE3) /* abe_dmic_din3.gpio_122 */ - >; - }; - -- button_pins: pinmux_button_pins { -+ button_pins: button-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x114, PIN_INPUT_PULLUP | MUX_MODE3) /* abe_dmic_din2.gpio_121 */ - >; - }; - -- i2c2_pins: pinmux_i2c2_pins { -+ i2c2_pins: i2c2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ - OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ - >; - }; - -- i2c3_pins: pinmux_i2c3_pins { -+ i2c3_pins: i2c3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ - OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ - >; - }; - -- smsc_pins: pinmux_smsc_pins { -+ smsc_pins: smsc-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x068, PIN_INPUT | MUX_MODE3) /* gpmc_a20.gpio_44: IRQ */ - OMAP4_IOPAD(0x06a, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a21.gpio_45: nReset */ -@@ -96,7 +96,7 @@ - >; - }; - -- dss_hdmi_pins: pinmux_dss_hdmi_pins { -+ dss_hdmi_pins: dss-hdmi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3) /* hdmi_hpd.gpio_63 */ - OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ -diff --git a/arch/arm/boot/dts/omap4-duovero.dtsi b/arch/arm/boot/dts/omap4-duovero.dtsi -index 805dfd40030dc..b8af455b411a9 100644 ---- a/arch/arm/boot/dts/omap4-duovero.dtsi -+++ b/arch/arm/boot/dts/omap4-duovero.dtsi -@@ -73,14 +73,14 @@ - &hsusbb1_pins - >; - -- twl6040_pins: pinmux_twl6040_pins { -+ twl6040_pins: twl6040-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x166, PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_nxt.gpio_160 */ - OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */ - >; - }; - -- mcbsp1_pins: pinmux_mcbsp1_pins { -+ mcbsp1_pins: mcbsp1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */ - OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */ -@@ -89,7 +89,7 @@ - >; - }; - -- hsusbb1_pins: pinmux_hsusbb1_pins { -+ hsusbb1_pins: hsusbb1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */ - OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */ -@@ -106,34 +106,34 @@ - >; - }; - -- hsusb1phy_pins: pinmux_hsusb1phy_pins { -+ hsusb1phy_pins: hsusb1phy-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x08c, PIN_OUTPUT | MUX_MODE3) /* gpmc_wait1.gpio_62 */ - >; - }; - -- w2cbw0015_pins: pinmux_w2cbw0015_pins { -+ w2cbw0015_pins: w2cbw0015-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 */ - OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */ - >; - }; - -- i2c1_pins: pinmux_i2c1_pins { -+ i2c1_pins: i2c1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ - OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ - >; - }; - -- i2c4_pins: pinmux_i2c4_pins { -+ i2c4_pins: i2c4-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ - OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ - >; - }; - -- mmc1_pins: pinmux_mmc1_pins { -+ mmc1_pins: mmc1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0e2, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */ - OMAP4_IOPAD(0x0e4, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmcc1_cmd */ -@@ -144,7 +144,7 @@ - >; - }; - -- mmc5_pins: pinmux_mmc5_pins { -+ mmc5_pins: mmc5-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk */ - OMAP4_IOPAD(0x14a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmcc5_cmd */ -diff --git a/arch/arm/boot/dts/omap4-kc1.dts b/arch/arm/boot/dts/omap4-kc1.dts -index e59d17b25a1d9..c6b79ba8bbc91 100644 ---- a/arch/arm/boot/dts/omap4-kc1.dts -+++ b/arch/arm/boot/dts/omap4-kc1.dts -@@ -35,42 +35,42 @@ - &omap4_pmx_core { - pinctrl-names = "default"; - -- uart3_pins: pinmux_uart3_pins { -+ uart3_pins: uart3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x144, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx */ - OMAP4_IOPAD(0x146, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx */ - >; - }; - -- i2c1_pins: pinmux_i2c1_pins { -+ i2c1_pins: i2c1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ - OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ - >; - }; - -- i2c2_pins: pinmux_i2c2_pins { -+ i2c2_pins: i2c2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ - OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ - >; - }; - -- i2c3_pins: pinmux_i2c3_pins { -+ i2c3_pins: i2c3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ - OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ - >; - }; - -- i2c4_pins: pinmux_i2c4_pins { -+ i2c4_pins: i2c4-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ - OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ - >; - }; - -- mmc2_pins: pinmux_mmc2_pins { -+ mmc2_pins: mmc2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x040, PIN_INPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat0 */ - OMAP4_IOPAD(0x042, PIN_INPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat1 */ -@@ -85,7 +85,7 @@ - >; - }; - -- usb_otg_hs_pins: pinmux_usb_otg_hs_pins { -+ usb_otg_hs_pins: usb-otg-hs-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x194, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* usba0_otg_ce */ - OMAP4_IOPAD(0x196, PIN_INPUT | MUX_MODE0) /* usba0_otg_dp */ -diff --git a/arch/arm/boot/dts/omap4-mcpdm.dtsi b/arch/arm/boot/dts/omap4-mcpdm.dtsi -index 915a9b31a33b4..03ade47431fbe 100644 ---- a/arch/arm/boot/dts/omap4-mcpdm.dtsi -+++ b/arch/arm/boot/dts/omap4-mcpdm.dtsi -@@ -7,7 +7,7 @@ - */ - - &omap4_pmx_core { -- mcpdm_pins: pinmux_mcpdm_pins { -+ mcpdm_pins: mcpdm-pins { - pinctrl-single,pins = < - /* 0x4a100106 abe_pdm_ul_data.abe_pdm_ul_data ag25 */ - OMAP4_IOPAD(0x106, PIN_INPUT_PULLDOWN | MUX_MODE0) -diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi -index 518652a599bd7..53b99004b19cf 100644 ---- a/arch/arm/boot/dts/omap4-panda-common.dtsi -+++ b/arch/arm/boot/dts/omap4-panda-common.dtsi -@@ -237,14 +237,14 @@ - &hsusbb1_pins - >; - -- twl6040_pins: pinmux_twl6040_pins { -+ twl6040_pins: twl6040-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x120, PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */ - OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */ - >; - }; - -- mcbsp1_pins: pinmux_mcbsp1_pins { -+ mcbsp1_pins: mcbsp1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */ - OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */ -@@ -253,7 +253,7 @@ - >; - }; - -- dss_dpi_pins: pinmux_dss_dpi_pins { -+ dss_dpi_pins: dss-dpi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x162, PIN_OUTPUT | MUX_MODE5) /* dispc2_data23 */ - OMAP4_IOPAD(0x164, PIN_OUTPUT | MUX_MODE5) /* dispc2_data22 */ -@@ -288,13 +288,13 @@ - >; - }; - -- tfp410_pins: pinmux_tfp410_pins { -+ tfp410_pins: tfp410-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x184, PIN_OUTPUT | MUX_MODE3) /* gpio_0 */ - >; - }; - -- dss_hdmi_pins: pinmux_dss_hdmi_pins { -+ dss_hdmi_pins: dss-hdmi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ - OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ -@@ -302,7 +302,7 @@ - >; - }; - -- tpd12s015_pins: pinmux_tpd12s015_pins { -+ tpd12s015_pins: tpd12s015-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x062, PIN_OUTPUT | MUX_MODE3) /* gpmc_a17.gpio_41 */ - OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3) /* gpmc_nbe1.gpio_60 */ -@@ -310,7 +310,7 @@ - >; - }; - -- hsusbb1_pins: pinmux_hsusbb1_pins { -+ hsusbb1_pins: hsusbb1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */ - OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */ -@@ -327,28 +327,28 @@ - >; - }; - -- i2c1_pins: pinmux_i2c1_pins { -+ i2c1_pins: i2c1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ - OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ - >; - }; - -- i2c2_pins: pinmux_i2c2_pins { -+ i2c2_pins: i2c2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ - OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ - >; - }; - -- i2c3_pins: pinmux_i2c3_pins { -+ i2c3_pins: i2c3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ - OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ - >; - }; - -- i2c4_pins: pinmux_i2c4_pins { -+ i2c4_pins: i2c4-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ - OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ -@@ -359,7 +359,7 @@ - * wl12xx GPIO outputs for WLAN_EN, BT_EN, FM_EN, BT_WAKEUP - * REVISIT: Are the pull-ups needed for GPIO 48 and 49? - */ -- wl12xx_gpio: pinmux_wl12xx_gpio { -+ wl12xx_gpio: wl12xx-gpio-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 */ - OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3) /* gpmc_a22.gpio_46 */ -@@ -369,7 +369,7 @@ - }; - - /* wl12xx GPIO inputs and SDIO pins */ -- wl12xx_pins: pinmux_wl12xx_pins { -+ wl12xx_pins: wl12xx-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x078, PIN_INPUT | MUX_MODE3) /* gpmc_ncs2.gpio_52 */ - OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */ -@@ -382,7 +382,7 @@ - >; - }; - -- button_pins: pinmux_button_pins { -+ button_pins: button-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x114, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_121 */ - >; -@@ -390,7 +390,7 @@ - }; - - &omap4_pmx_wkup { -- led_wkgpio_pins: pinmux_leds_wkpins { -+ led_wkgpio_pins: leds-wkpins-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x05a, PIN_OUTPUT | MUX_MODE3) /* gpio_wk7 */ - OMAP4_IOPAD(0x05c, PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */ -diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts -index 7c6886cd738f0..6c08dff58beae 100644 ---- a/arch/arm/boot/dts/omap4-panda-es.dts -+++ b/arch/arm/boot/dts/omap4-panda-es.dts -@@ -38,26 +38,26 @@ - }; - - &omap4_pmx_core { -- led_gpio_pins: gpio_led_pmx { -+ led_gpio_pins: gpio-led-pmx-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0f6, PIN_OUTPUT | MUX_MODE3) /* gpio_110 */ - >; - }; - -- button_pins: pinmux_button_pins { -+ button_pins: button-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0fc, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ - >; - }; - -- bt_pins: pinmux_bt_pins { -+ bt_pins: bt-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3) /* gpmc_a22.gpio_46 - BTEN */ - OMAP4_IOPAD(0x072, PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_a25.gpio_49 - BTWAKEUP */ - >; - }; - -- uart2_pins: pinmux_uart2_pins { -+ uart2_pins: uart2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts - HCI */ - OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ -diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts -index 9e976140f34a6..b2cb93edbc3a6 100644 ---- a/arch/arm/boot/dts/omap4-sdp.dts -+++ b/arch/arm/boot/dts/omap4-sdp.dts -@@ -214,7 +214,7 @@ - &tpd12s015_pins - >; - -- uart2_pins: pinmux_uart2_pins { -+ uart2_pins: uart2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ - OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ -@@ -223,7 +223,7 @@ - >; - }; - -- uart3_pins: pinmux_uart3_pins { -+ uart3_pins: uart3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x140, PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ - OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ -@@ -232,21 +232,21 @@ - >; - }; - -- uart4_pins: pinmux_uart4_pins { -+ uart4_pins: uart4-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0) /* uart4_rx.uart4_rx */ - OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0) /* uart4_tx.uart4_tx */ - >; - }; - -- twl6040_pins: pinmux_twl6040_pins { -+ twl6040_pins: twl6040-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x120, PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */ - OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */ - >; - }; - -- dmic_pins: pinmux_dmic_pins { -+ dmic_pins: dmic-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x110, PIN_OUTPUT | MUX_MODE0) /* abe_dmic_clk1.abe_dmic_clk1 */ - OMAP4_IOPAD(0x112, PIN_INPUT | MUX_MODE0) /* abe_dmic_din1.abe_dmic_din1 */ -@@ -255,7 +255,7 @@ - >; - }; - -- mcbsp1_pins: pinmux_mcbsp1_pins { -+ mcbsp1_pins: mcbsp1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */ - OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */ -@@ -264,7 +264,7 @@ - >; - }; - -- mcbsp2_pins: pinmux_mcbsp2_pins { -+ mcbsp2_pins: mcbsp2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_clkx.abe_mcbsp2_clkx */ - OMAP4_IOPAD(0x0f8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp2_dr.abe_mcbsp2_dr */ -@@ -273,7 +273,7 @@ - >; - }; - -- mcspi1_pins: pinmux_mcspi1_pins { -+ mcspi1_pins: mcspi1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x132, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */ - OMAP4_IOPAD(0x134, PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */ -@@ -282,7 +282,7 @@ - >; - }; - -- dss_hdmi_pins: pinmux_dss_hdmi_pins { -+ dss_hdmi_pins: dss-hdmi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ - OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ -@@ -290,7 +290,7 @@ - >; - }; - -- tpd12s015_pins: pinmux_tpd12s015_pins { -+ tpd12s015_pins: tpd12s015-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x062, PIN_OUTPUT | MUX_MODE3) /* gpmc_a17.gpio_41 */ - OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3) /* gpmc_nbe1.gpio_60 */ -@@ -298,28 +298,28 @@ - >; - }; - -- i2c1_pins: pinmux_i2c1_pins { -+ i2c1_pins: i2c1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ - OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ - >; - }; - -- i2c2_pins: pinmux_i2c2_pins { -+ i2c2_pins: i2c2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ - OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ - >; - }; - -- i2c3_pins: pinmux_i2c3_pins { -+ i2c3_pins: i2c3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ - OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ - >; - }; - -- i2c4_pins: pinmux_i2c4_pins { -+ i2c4_pins: i2c4-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ - OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ -@@ -327,14 +327,14 @@ - }; - - /* wl12xx GPIO output for WLAN_EN */ -- wl12xx_gpio: pinmux_wl12xx_gpio { -+ wl12xx_gpio: wl12xx-gpio-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x07c, PIN_OUTPUT | MUX_MODE3) /* gpmc_nwp.gpio_54 */ - >; - }; - - /* wl12xx GPIO inputs and SDIO pins */ -- wl12xx_pins: pinmux_wl12xx_pins { -+ wl12xx_pins: wl12xx-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */ - OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */ -@@ -347,13 +347,13 @@ - }; - - /* gpio_48 for ENET_ENABLE */ -- enet_enable_gpio: pinmux_enet_enable_gpio { -+ enet_enable_gpio: enet-enable-gpio-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x070, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* gpmc_a24.gpio_48 */ - >; - }; - -- ks8851_pins: pinmux_ks8851_pins { -+ ks8851_pins: ks8851-pins { - pinctrl-single,pins = < - /* ENET_INT */ - OMAP4_IOPAD(0x054, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad10.gpio_34 */ -diff --git a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi -index 458cb53dd3d18..cadc7e02592bf 100644 ---- a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi -+++ b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi -@@ -60,7 +60,7 @@ - }; - - &omap4_pmx_core { -- uart1_pins: pinmux_uart1_pins { -+ uart1_pins: uart1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi1_cs2.uart1_cts */ - OMAP4_IOPAD(0x13e, PIN_OUTPUT | MUX_MODE1) /* mcspi1_cs3.uart1_rts */ -@@ -69,7 +69,7 @@ - >; - }; - -- mcspi1_pins: pinmux_mcspi1_pins { -+ mcspi1_pins: mcspi1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x132, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */ - OMAP4_IOPAD(0x134, PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */ -@@ -78,13 +78,13 @@ - >; - }; - -- mcasp_pins: pinmux_mcsasp_pins { -+ mcasp_pins: mcsasp-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0f8, PIN_OUTPUT | MUX_MODE2) /* mcbsp2_dr.abe_mcasp_axr */ - >; - }; - -- dss_dpi_pins: pinmux_dss_dpi_pins { -+ dss_dpi_pins: dss-dpi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x162, PIN_OUTPUT | MUX_MODE5) /* dispc2_data23 */ - OMAP4_IOPAD(0x164, PIN_OUTPUT | MUX_MODE5) /* dispc2_data22 */ -@@ -117,7 +117,7 @@ - >; - }; - -- dss_hdmi_pins: pinmux_dss_hdmi_pins { -+ dss_hdmi_pins: dss-hdmi-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ - OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ -@@ -125,14 +125,14 @@ - >; - }; - -- i2c4_pins: pinmux_i2c4_pins { -+ i2c4_pins: i2c4-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ - OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ - >; - }; - -- mmc5_pins: pinmux_mmc5_pins { -+ mmc5_pins: mmc5-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE3) /* abe_mcbsp2_clkx.gpio_110 */ - OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */ -@@ -144,32 +144,32 @@ - >; - }; - -- gpio_led_pins: pinmux_gpio_led_pins { -+ gpio_led_pins: gpio-led-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x17e, PIN_OUTPUT | MUX_MODE3) /* kpd_col4.gpio_172 */ - OMAP4_IOPAD(0x180, PIN_OUTPUT | MUX_MODE3) /* kpd_col5.gpio_173 */ - >; - }; - -- gpio_key_pins: pinmux_gpio_key_pins { -+ gpio_key_pins: gpio-key-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x1a2, PIN_INPUT | MUX_MODE3) /* sys_boot0.gpio_184 */ - >; - }; - -- ks8851_irq_pins: pinmux_ks8851_irq_pins { -+ ks8851_irq_pins: ks8851-irq-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x17c, PIN_INPUT_PULLUP | MUX_MODE3) /* kpd_col3.gpio_171 */ - >; - }; - -- hdmi_hpd_pins: pinmux_hdmi_hpd_pins { -+ hdmi_hpd_pins: hdmi-hpd-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x098, PIN_INPUT_PULLDOWN | MUX_MODE3) /* hdmi_hpd.gpio_63 */ - >; - }; - -- backlight_pins: pinmux_backlight_pins { -+ backlight_pins: backlight-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x116, PIN_OUTPUT | MUX_MODE3) /* abe_dmic_din3.gpio_122 */ - >; -diff --git a/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi b/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi -index d0032213101e6..de779d2d7c3e9 100644 ---- a/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi -+++ b/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi -@@ -19,7 +19,7 @@ - }; - - &omap4_pmx_core { -- uart2_pins: pinmux_uart2_pins { -+ uart2_pins: uart2-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ - OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ -@@ -28,7 +28,7 @@ - >; - }; - -- wl12xx_ctrl_pins: pinmux_wl12xx_ctrl_pins { -+ wl12xx_ctrl_pins: wl12xx-ctrl-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x062, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a17.gpio_41 (WLAN_IRQ) */ - OMAP4_IOPAD(0x064, PIN_OUTPUT | MUX_MODE3) /* gpmc_a18.gpio_42 (BT_EN) */ -@@ -36,7 +36,7 @@ - >; - }; - -- mmc4_pins: pinmux_mmc4_pins { -+ mmc4_pins: mmc4-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x154, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi4_clk.sdmmc4_clk */ - OMAP4_IOPAD(0x156, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi4_simo.sdmmc4_cmd */ -diff --git a/arch/arm/boot/dts/omap4-var-som-om44.dtsi b/arch/arm/boot/dts/omap4-var-som-om44.dtsi -index 334cbbaa5b8b0..37d56b3010cff 100644 ---- a/arch/arm/boot/dts/omap4-var-som-om44.dtsi -+++ b/arch/arm/boot/dts/omap4-var-som-om44.dtsi -@@ -65,21 +65,21 @@ - &hsusbb1_pins - >; - -- twl6040_pins: pinmux_twl6040_pins { -+ twl6040_pins: twl6040-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x19c, PIN_OUTPUT | MUX_MODE3) /* fref_clk2_out.gpio_182 */ - OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */ - >; - }; - -- tsc2004_pins: pinmux_tsc2004_pins { -+ tsc2004_pins: tsc2004-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x090, PIN_INPUT | MUX_MODE3) /* gpmc_ncs4.gpio_101 (irq) */ - OMAP4_IOPAD(0x092, PIN_OUTPUT | MUX_MODE3) /* gpmc_ncs5.gpio_102 (rst) */ - >; - }; - -- uart3_pins: pinmux_uart3_pins { -+ uart3_pins: uart3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x140, PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ - OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ -@@ -88,7 +88,7 @@ - >; - }; - -- hsusbb1_pins: pinmux_hsusbb1_pins { -+ hsusbb1_pins: hsusbb1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */ - OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */ -@@ -105,27 +105,27 @@ - >; - }; - -- hsusbb1_phy_rst_pins: pinmux_hsusbb1_phy_rst_pins { -+ hsusbb1_phy_rst_pins: hsusbb1-phy-rst-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x18c, PIN_OUTPUT | MUX_MODE3) /* kpd_row2.gpio_177 */ - >; - }; - -- i2c1_pins: pinmux_i2c1_pins { -+ i2c1_pins: i2c1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ - OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ - >; - }; - -- i2c3_pins: pinmux_i2c3_pins { -+ i2c3_pins: i2c3-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ - OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ - >; - }; - -- mmc1_pins: pinmux_mmc1_pins { -+ mmc1_pins: mmc1-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x0e2, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ - OMAP4_IOPAD(0x0e4, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */ -@@ -144,19 +144,19 @@ - &lan7500_rst_pins - >; - -- hsusbb1_phy_clk_pins: pinmux_hsusbb1_phy_clk_pins { -+ hsusbb1_phy_clk_pins: hsusbb1-phy-clk-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x058, PIN_OUTPUT | MUX_MODE0) /* fref_clk3_out */ - >; - }; - -- hsusbb1_hub_rst_pins: pinmux_hsusbb1_hub_rst_pins { -+ hsusbb1_hub_rst_pins: hsusbb1-hub-rst-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x042, PIN_OUTPUT | MUX_MODE3) /* gpio_wk1 */ - >; - }; - -- lan7500_rst_pins: pinmux_lan7500_rst_pins { -+ lan7500_rst_pins: lan7500-rst-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x040, PIN_OUTPUT | MUX_MODE3) /* gpio_wk0 */ - >; -diff --git a/arch/arm/boot/dts/omap443x.dtsi b/arch/arm/boot/dts/omap443x.dtsi -index 238aceb799f89..2104170fe2cd7 100644 ---- a/arch/arm/boot/dts/omap443x.dtsi -+++ b/arch/arm/boot/dts/omap443x.dtsi -@@ -69,6 +69,7 @@ - }; - - &cpu_thermal { -+ thermal-sensors = <&bandgap>; - coefficients = <0 20000>; - }; - -diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi -index 1b27a862ae810..a6764750d4476 100644 ---- a/arch/arm/boot/dts/omap4460.dtsi -+++ b/arch/arm/boot/dts/omap4460.dtsi -@@ -79,6 +79,7 @@ - }; - - &cpu_thermal { -+ thermal-sensors = <&bandgap>; - coefficients = <348 (-9301)>; - }; - -diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts -index e62ea8b6d53fd..af288d63a26a4 100644 ---- a/arch/arm/boot/dts/omap5-cm-t54.dts -+++ b/arch/arm/boot/dts/omap5-cm-t54.dts -@@ -84,36 +84,36 @@ - }; - - lcd0: display { -- compatible = "startek,startek-kd050c", "panel-dpi"; -- label = "lcd"; -- -- pinctrl-names = "default"; -- pinctrl-0 = <&lcd_pins>; -- -- enable-gpios = <&gpio8 3 GPIO_ACTIVE_HIGH>; -- -- panel-timing { -- clock-frequency = <33000000>; -- hactive = <800>; -- vactive = <480>; -- hfront-porch = <40>; -- hback-porch = <40>; -- hsync-len = <43>; -- vback-porch = <29>; -- vfront-porch = <13>; -- vsync-len = <3>; -- hsync-active = <0>; -- vsync-active = <0>; -- de-active = <1>; -- pixelclk-active = <1>; -- }; -- -- port { -- lcd_in: endpoint { -- remote-endpoint = <&dpi_lcd_out>; -- }; -- }; -- }; -+ compatible = "startek,startek-kd050c", "panel-dpi"; -+ label = "lcd"; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lcd_pins>; -+ -+ enable-gpios = <&gpio8 3 GPIO_ACTIVE_HIGH>; -+ -+ panel-timing { -+ clock-frequency = <33000000>; -+ hactive = <800>; -+ vactive = <480>; -+ hfront-porch = <40>; -+ hback-porch = <40>; -+ hsync-len = <43>; -+ vback-porch = <29>; -+ vfront-porch = <13>; -+ vsync-len = <3>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ de-active = <1>; -+ pixelclk-active = <1>; -+ }; -+ -+ port { -+ lcd_in: endpoint { -+ remote-endpoint = <&dpi_lcd_out>; -+ }; -+ }; -+ }; - - hdmi0: connector0 { - compatible = "hdmi-connector"; -@@ -644,8 +644,8 @@ - }; - - &usb3 { -- extcon = <&extcon_usb3>; -- vbus-supply = <&smps10_out1_reg>; -+ extcon = <&extcon_usb3>; -+ vbus-supply = <&smps10_out1_reg>; - }; - - &cpu0 { -diff --git a/arch/arm/boot/dts/qcom-msm8974pro-sony-xperia-shinano-castor.dts b/arch/arm/boot/dts/qcom-msm8974pro-sony-xperia-shinano-castor.dts -index 3f45f5c5d37b5..cc49bb777df8a 100644 ---- a/arch/arm/boot/dts/qcom-msm8974pro-sony-xperia-shinano-castor.dts -+++ b/arch/arm/boot/dts/qcom-msm8974pro-sony-xperia-shinano-castor.dts -@@ -124,15 +124,15 @@ - - syna,startup-delay-ms = <10>; - -- rmi-f01@1 { -+ rmi4-f01@1 { - reg = <0x1>; -- syna,nosleep = <1>; -+ syna,nosleep-mode = <1>; - }; - -- rmi-f11@11 { -+ rmi4-f11@11 { - reg = <0x11>; -- syna,f11-flip-x = <1>; - syna,sensor-type = <1>; -+ touchscreen-inverted-x; - }; - }; - }; -diff --git a/arch/arm/boot/dts/twl6030_omap4.dtsi b/arch/arm/boot/dts/twl6030_omap4.dtsi -index 5730e46b00677..64e38c7c8be70 100644 ---- a/arch/arm/boot/dts/twl6030_omap4.dtsi -+++ b/arch/arm/boot/dts/twl6030_omap4.dtsi -@@ -19,7 +19,7 @@ - }; - - &omap4_pmx_wkup { -- twl6030_wkup_pins: pinmux_twl6030_wkup_pins { -+ twl6030_wkup_pins: twl6030-wkup-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x054, PIN_OUTPUT | MUX_MODE2) /* fref_clk0_out.sys_drm_msecure */ - >; -@@ -27,7 +27,7 @@ - }; - - &omap4_pmx_core { -- twl6030_pins: pinmux_twl6030_pins { -+ twl6030_pins: twl6030-pins { - pinctrl-single,pins = < - OMAP4_IOPAD(0x19e, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1.sys_nirq1 */ - >; -diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile -index 3ea9edc87909a..ac6f780dc1914 100644 ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -62,6 +62,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-kontron-bl-osm-s.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mm-mx8menlo.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb -+dtb-$(CONFIG_ARCH_MXC) += imx8mm-prt8mm.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb -diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -index c289bf0903b45..c9efcb894a52f 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -@@ -100,6 +100,14 @@ - }; - }; - -+ reserved-memory { -+ /* Cont splash region set up by the bootloader */ -+ cont_splash_mem: framebuffer@9d400000 { -+ reg = <0x0 0x9d400000 0x0 0x2400000>; -+ no-map; -+ }; -+ }; -+ - lt9611_1v8: lt9611-vdd18-regulator { - compatible = "regulator-fixed"; - regulator-name = "LT9611_1V8"; -@@ -512,6 +520,7 @@ - }; - - &mdss { -+ memory-region = <&cont_splash_mem>; - status = "okay"; - }; - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index 0b6af3348e791..623e9f308f38a 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -1050,7 +1050,6 @@ CONFIG_COMMON_CLK_FSL_SAI=y - CONFIG_COMMON_CLK_S2MPS11=y - CONFIG_COMMON_CLK_PWM=y - CONFIG_COMMON_CLK_VC5=y --CONFIG_COMMON_CLK_NPCM8XX=y - CONFIG_COMMON_CLK_BD718XX=m - CONFIG_CLK_RASPBERRYPI=m - CONFIG_CLK_IMX8MM=y -diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h -index 7af0cebf28d73..b9a4ab54285c1 100644 ---- a/arch/loongarch/include/asm/elf.h -+++ b/arch/loongarch/include/asm/elf.h -@@ -111,6 +111,15 @@ - #define R_LARCH_TLS_GD_HI20 98 - #define R_LARCH_32_PCREL 99 - #define R_LARCH_RELAX 100 -+#define R_LARCH_DELETE 101 -+#define R_LARCH_ALIGN 102 -+#define R_LARCH_PCREL20_S2 103 -+#define R_LARCH_CFA 104 -+#define R_LARCH_ADD6 105 -+#define R_LARCH_SUB6 106 -+#define R_LARCH_ADD_ULEB128 107 -+#define R_LARCH_SUB_ULEB128 108 -+#define R_LARCH_64_PCREL 109 - - #ifndef ELF_ARCH - -diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c -index 4a4107a6a9651..aed901c57fb43 100644 ---- a/arch/loongarch/kernel/mem.c -+++ b/arch/loongarch/kernel/mem.c -@@ -50,7 +50,6 @@ void __init memblock_init(void) - } - - memblock_set_current_limit(PFN_PHYS(max_low_pfn)); -- memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); - - /* Reserve the first 2MB */ - memblock_reserve(PHYS_OFFSET, 0x200000); -@@ -58,4 +57,7 @@ void __init memblock_init(void) - /* Reserve the kernel text/data/bss */ - memblock_reserve(__pa_symbol(&_text), - __pa_symbol(&_end) - __pa_symbol(&_text)); -+ -+ memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); -+ memblock_set_node(0, PHYS_ADDR_MAX, &memblock.reserved, 0); - } -diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c -index 097595b2fc14b..4f1e6e55dc026 100644 ---- a/arch/loongarch/kernel/module.c -+++ b/arch/loongarch/kernel/module.c -@@ -376,7 +376,7 @@ typedef int (*reloc_rela_handler)(struct module *mod, u32 *location, Elf_Addr v, - - /* The handlers for known reloc types */ - static reloc_rela_handler reloc_rela_handlers[] = { -- [R_LARCH_NONE ... R_LARCH_RELAX] = apply_r_larch_error, -+ [R_LARCH_NONE ... R_LARCH_64_PCREL] = apply_r_larch_error, - - [R_LARCH_NONE] = apply_r_larch_none, - [R_LARCH_32] = apply_r_larch_32, -diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c -index a13f92593cfda..f7ffce170213e 100644 ---- a/arch/loongarch/kernel/numa.c -+++ b/arch/loongarch/kernel/numa.c -@@ -453,7 +453,7 @@ void __init paging_init(void) - - void __init mem_init(void) - { -- high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); -+ high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); - memblock_free_all(); - setup_zero_pages(); /* This comes from node 0 */ - } -diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c -index 50de86eb8784c..3183df60ad337 100644 ---- a/arch/mips/alchemy/devboards/db1000.c -+++ b/arch/mips/alchemy/devboards/db1000.c -@@ -164,6 +164,7 @@ static struct platform_device db1x00_audio_dev = { - - /******************************************************************************/ - -+#ifdef CONFIG_MMC_AU1X - static irqreturn_t db1100_mmc_cd(int irq, void *ptr) - { - mmc_detect_change(ptr, msecs_to_jiffies(500)); -@@ -369,6 +370,7 @@ static struct platform_device db1100_mmc1_dev = { - .num_resources = ARRAY_SIZE(au1100_mmc1_res), - .resource = au1100_mmc1_res, - }; -+#endif /* CONFIG_MMC_AU1X */ - - /******************************************************************************/ - -@@ -432,8 +434,10 @@ static struct platform_device *db1x00_devs[] = { - - static struct platform_device *db1100_devs[] = { - &au1100_lcd_device, -+#ifdef CONFIG_MMC_AU1X - &db1100_mmc0_dev, - &db1100_mmc1_dev, -+#endif - }; - - int __init db1000_dev_setup(void) -diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c -index 76080c71a2a7b..f521874ebb07b 100644 ---- a/arch/mips/alchemy/devboards/db1200.c -+++ b/arch/mips/alchemy/devboards/db1200.c -@@ -326,6 +326,7 @@ static struct platform_device db1200_ide_dev = { - - /**********************************************************************/ - -+#ifdef CONFIG_MMC_AU1X - /* SD carddetects: they're supposed to be edge-triggered, but ack - * doesn't seem to work (CPLD Rev 2). Instead, the screaming one - * is disabled and its counterpart enabled. The 200ms timeout is -@@ -584,6 +585,7 @@ static struct platform_device pb1200_mmc1_dev = { - .num_resources = ARRAY_SIZE(au1200_mmc1_res), - .resource = au1200_mmc1_res, - }; -+#endif /* CONFIG_MMC_AU1X */ - - /**********************************************************************/ - -@@ -751,7 +753,9 @@ static struct platform_device db1200_audiodma_dev = { - static struct platform_device *db1200_devs[] __initdata = { - NULL, /* PSC0, selected by S6.8 */ - &db1200_ide_dev, -+#ifdef CONFIG_MMC_AU1X - &db1200_mmc0_dev, -+#endif - &au1200_lcd_dev, - &db1200_eth_dev, - &db1200_nand_dev, -@@ -762,7 +766,9 @@ static struct platform_device *db1200_devs[] __initdata = { - }; - - static struct platform_device *pb1200_devs[] __initdata = { -+#ifdef CONFIG_MMC_AU1X - &pb1200_mmc1_dev, -+#endif - }; - - /* Some peripheral base addresses differ on the PB1200 */ -diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c -index ff61901329c62..d377e043b49f8 100644 ---- a/arch/mips/alchemy/devboards/db1300.c -+++ b/arch/mips/alchemy/devboards/db1300.c -@@ -450,6 +450,7 @@ static struct platform_device db1300_ide_dev = { - - /**********************************************************************/ - -+#ifdef CONFIG_MMC_AU1X - static irqreturn_t db1300_mmc_cd(int irq, void *ptr) - { - disable_irq_nosync(irq); -@@ -632,6 +633,7 @@ static struct platform_device db1300_sd0_dev = { - .resource = au1300_sd0_res, - .num_resources = ARRAY_SIZE(au1300_sd0_res), - }; -+#endif /* CONFIG_MMC_AU1X */ - - /**********************************************************************/ - -@@ -767,8 +769,10 @@ static struct platform_device *db1300_dev[] __initdata = { - &db1300_5waysw_dev, - &db1300_nand_dev, - &db1300_ide_dev, -+#ifdef CONFIG_MMC_AU1X - &db1300_sd0_dev, - &db1300_sd1_dev, -+#endif - &db1300_lcd_dev, - &db1300_ac97_dev, - &db1300_i2s_dev, -diff --git a/arch/parisc/include/asm/ropes.h b/arch/parisc/include/asm/ropes.h -index 8e51c775c80a6..62399c7ea94a1 100644 ---- a/arch/parisc/include/asm/ropes.h -+++ b/arch/parisc/include/asm/ropes.h -@@ -86,6 +86,9 @@ struct sba_device { - struct ioc ioc[MAX_IOC]; - }; - -+/* list of SBA's in system, see drivers/parisc/sba_iommu.c */ -+extern struct sba_device *sba_list; -+ - #define ASTRO_RUNWAY_PORT 0x582 - #define IKE_MERCED_PORT 0x803 - #define REO_MERCED_PORT 0x804 -diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c -index e7ee0c0c91d35..8f12b9f318ae6 100644 ---- a/arch/parisc/kernel/drivers.c -+++ b/arch/parisc/kernel/drivers.c -@@ -924,9 +924,9 @@ static __init void qemu_header(void) - pr_info("#define PARISC_MODEL \"%s\"\n\n", - boot_cpu_data.pdc.sys_model_name); - -+ #define p ((unsigned long *)&boot_cpu_data.pdc.model) - pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, " - "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n", -- #define p ((unsigned long *)&boot_cpu_data.pdc.model) - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); - #undef p - -diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c -index b05055f3ba4b8..9ddb2e3970589 100644 ---- a/arch/parisc/kernel/irq.c -+++ b/arch/parisc/kernel/irq.c -@@ -368,7 +368,7 @@ union irq_stack_union { - volatile unsigned int lock[1]; - }; - --DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { -+static DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { - .slock = { 1,1,1,1 }, - }; - #endif -diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c -index 8db1a15d7acbe..02436f80e60e2 100644 ---- a/arch/powerpc/kernel/hw_breakpoint.c -+++ b/arch/powerpc/kernel/hw_breakpoint.c -@@ -505,11 +505,13 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) - struct arch_hw_breakpoint *info; - int i; - -+ preempt_disable(); -+ - for (i = 0; i < nr_wp_slots(); i++) { - if (unlikely(tsk->thread.last_hit_ubp[i])) - goto reset; - } -- return; -+ goto out; - - reset: - regs_set_return_msr(regs, regs->msr & ~MSR_SE); -@@ -518,6 +520,9 @@ reset: - __set_breakpoint(i, info); - tsk->thread.last_hit_ubp[i] = NULL; - } -+ -+out: -+ preempt_enable(); - } - - static bool is_larx_stcx_instr(int type) -@@ -632,6 +637,11 @@ static void handle_p10dd1_spurious_exception(struct arch_hw_breakpoint **info, - } - } - -+/* -+ * Handle a DABR or DAWR exception. -+ * -+ * Called in atomic context. -+ */ - int hw_breakpoint_handler(struct die_args *args) - { - bool err = false; -@@ -758,6 +768,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler); - - /* - * Handle single-step exceptions following a DABR hit. -+ * -+ * Called in atomic context. - */ - static int single_step_dabr_instruction(struct die_args *args) - { -@@ -815,6 +827,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction); - - /* - * Handle debug exception notifications. -+ * -+ * Called in atomic context. - */ - int hw_breakpoint_exceptions_notify( - struct notifier_block *unused, unsigned long val, void *data) -diff --git a/arch/powerpc/kernel/hw_breakpoint_constraints.c b/arch/powerpc/kernel/hw_breakpoint_constraints.c -index a74623025f3ab..9e51801c49152 100644 ---- a/arch/powerpc/kernel/hw_breakpoint_constraints.c -+++ b/arch/powerpc/kernel/hw_breakpoint_constraints.c -@@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr, - int *type, int *size, unsigned long *ea) - { - struct instruction_op op; -+ int err; - -- if (__get_user_instr(*instr, (void __user *)regs->nip)) -+ pagefault_disable(); -+ err = __get_user_instr(*instr, (void __user *)regs->nip); -+ pagefault_enable(); -+ -+ if (err) - return; - - analyse_instr(&op, regs, *instr); -diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c -index 33c23225fd545..7dda59923ed6a 100644 ---- a/arch/powerpc/perf/hv-24x7.c -+++ b/arch/powerpc/perf/hv-24x7.c -@@ -1431,7 +1431,7 @@ static int h_24x7_event_init(struct perf_event *event) - } - - domain = event_get_domain(event); -- if (domain >= HV_PERF_DOMAIN_MAX) { -+ if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) { - pr_devel("invalid domain %d\n", domain); - return -EINVAL; - } -diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h -index 19a771085781a..7d2675bb71611 100644 ---- a/arch/riscv/include/asm/errata_list.h -+++ b/arch/riscv/include/asm/errata_list.h -@@ -100,7 +100,7 @@ asm volatile(ALTERNATIVE( \ - * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | - * 0000001 01001 rs1 000 00000 0001011 - * dcache.cva rs1 (clean, virtual address) -- * 0000001 00100 rs1 000 00000 0001011 -+ * 0000001 00101 rs1 000 00000 0001011 - * - * dcache.cipa rs1 (clean then invalidate, physical address) - * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | -@@ -113,7 +113,7 @@ asm volatile(ALTERNATIVE( \ - * 0000000 11001 00000 000 00000 0001011 - */ - #define THEAD_inval_A0 ".long 0x0265000b" --#define THEAD_clean_A0 ".long 0x0245000b" -+#define THEAD_clean_A0 ".long 0x0255000b" - #define THEAD_flush_A0 ".long 0x0275000b" - #define THEAD_SYNC_S ".long 0x0190000b" - -diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h -index a3760ca796aa2..256eee99afc8f 100644 ---- a/arch/x86/include/asm/kexec.h -+++ b/arch/x86/include/asm/kexec.h -@@ -208,8 +208,6 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image); - #endif - #endif - --typedef void crash_vmclear_fn(void); --extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; - extern void kdump_nmi_shootdown_cpus(void); - - #endif /* __ASSEMBLY__ */ -diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h -index bc5b4d788c08d..2551baec927d2 100644 ---- a/arch/x86/include/asm/reboot.h -+++ b/arch/x86/include/asm/reboot.h -@@ -25,6 +25,8 @@ void __noreturn machine_real_restart(unsigned int type); - #define MRR_BIOS 0 - #define MRR_APM 1 - -+typedef void crash_vmclear_fn(void); -+extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; - void cpu_emergency_disable_virtualization(void); - - typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); -diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c -index 3a893ab398a01..263df737d5cd5 100644 ---- a/arch/x86/kernel/cpu/bugs.c -+++ b/arch/x86/kernel/cpu/bugs.c -@@ -2414,7 +2414,7 @@ static void __init srso_select_mitigation(void) - - switch (srso_cmd) { - case SRSO_CMD_OFF: -- return; -+ goto pred_cmd; - - case SRSO_CMD_MICROCODE: - if (has_microcode) { -@@ -2692,7 +2692,7 @@ static ssize_t srso_show_state(char *buf) - - return sysfs_emit(buf, "%s%s\n", - srso_strings[srso_mitigation], -- (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); -+ boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode"); - } - - static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, -diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c -index b723368dbc644..454cdf3418624 100644 ---- a/arch/x86/kernel/cpu/common.c -+++ b/arch/x86/kernel/cpu/common.c -@@ -1282,7 +1282,7 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { - VULNBL_AMD(0x15, RETBLEED), - VULNBL_AMD(0x16, RETBLEED), - VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), -- VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), -+ VULNBL_HYGON(0x18, RETBLEED | SMT_RSB | SRSO), - VULNBL_AMD(0x19, SRSO), - {} - }; -diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c -index 2c258255a6296..d5f76b996795f 100644 ---- a/arch/x86/kernel/cpu/sgx/encl.c -+++ b/arch/x86/kernel/cpu/sgx/encl.c -@@ -235,6 +235,21 @@ static struct sgx_epc_page *sgx_encl_eldu(struct sgx_encl_page *encl_page, - return epc_page; - } - -+/* -+ * Ensure the SECS page is not swapped out. Must be called with encl->lock -+ * to protect the enclave states including SECS and ensure the SECS page is -+ * not swapped out again while being used. -+ */ -+static struct sgx_epc_page *sgx_encl_load_secs(struct sgx_encl *encl) -+{ -+ struct sgx_epc_page *epc_page = encl->secs.epc_page; -+ -+ if (!epc_page) -+ epc_page = sgx_encl_eldu(&encl->secs, NULL); -+ -+ return epc_page; -+} -+ - static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, - struct sgx_encl_page *entry) - { -@@ -248,11 +263,9 @@ static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, - return entry; - } - -- if (!(encl->secs.epc_page)) { -- epc_page = sgx_encl_eldu(&encl->secs, NULL); -- if (IS_ERR(epc_page)) -- return ERR_CAST(epc_page); -- } -+ epc_page = sgx_encl_load_secs(encl); -+ if (IS_ERR(epc_page)) -+ return ERR_CAST(epc_page); - - epc_page = sgx_encl_eldu(entry, encl->secs.epc_page); - if (IS_ERR(epc_page)) -@@ -339,6 +352,13 @@ static vm_fault_t sgx_encl_eaug_page(struct vm_area_struct *vma, - - mutex_lock(&encl->lock); - -+ epc_page = sgx_encl_load_secs(encl); -+ if (IS_ERR(epc_page)) { -+ if (PTR_ERR(epc_page) == -EBUSY) -+ vmret = VM_FAULT_NOPAGE; -+ goto err_out_unlock; -+ } -+ - epc_page = sgx_alloc_epc_page(encl_page, false); - if (IS_ERR(epc_page)) { - if (PTR_ERR(epc_page) == -EBUSY) -diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c -index cdd92ab43cda4..54cd959cb3160 100644 ---- a/arch/x86/kernel/crash.c -+++ b/arch/x86/kernel/crash.c -@@ -48,38 +48,12 @@ struct crash_memmap_data { - unsigned int type; - }; - --/* -- * This is used to VMCLEAR all VMCSs loaded on the -- * processor. And when loading kvm_intel module, the -- * callback function pointer will be assigned. -- * -- * protected by rcu. -- */ --crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss = NULL; --EXPORT_SYMBOL_GPL(crash_vmclear_loaded_vmcss); -- --static inline void cpu_crash_vmclear_loaded_vmcss(void) --{ -- crash_vmclear_fn *do_vmclear_operation = NULL; -- -- rcu_read_lock(); -- do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss); -- if (do_vmclear_operation) -- do_vmclear_operation(); -- rcu_read_unlock(); --} -- - #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) - - static void kdump_nmi_callback(int cpu, struct pt_regs *regs) - { - crash_save_cpu(regs, cpu); - -- /* -- * VMCLEAR VMCSs loaded on all cpus if needed. -- */ -- cpu_crash_vmclear_loaded_vmcss(); -- - /* - * Disable Intel PT to stop its logging - */ -@@ -133,11 +107,6 @@ void native_machine_crash_shutdown(struct pt_regs *regs) - - crash_smp_send_stop(); - -- /* -- * VMCLEAR VMCSs loaded on this cpu if needed. -- */ -- cpu_crash_vmclear_loaded_vmcss(); -- - cpu_emergency_disable_virtualization(); - - /* -diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c -index d03c551defccf..299b970e5f829 100644 ---- a/arch/x86/kernel/reboot.c -+++ b/arch/x86/kernel/reboot.c -@@ -787,6 +787,26 @@ void machine_crash_shutdown(struct pt_regs *regs) - } - #endif - -+/* -+ * This is used to VMCLEAR all VMCSs loaded on the -+ * processor. And when loading kvm_intel module, the -+ * callback function pointer will be assigned. -+ * -+ * protected by rcu. -+ */ -+crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; -+EXPORT_SYMBOL_GPL(crash_vmclear_loaded_vmcss); -+ -+static inline void cpu_crash_vmclear_loaded_vmcss(void) -+{ -+ crash_vmclear_fn *do_vmclear_operation = NULL; -+ -+ rcu_read_lock(); -+ do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss); -+ if (do_vmclear_operation) -+ do_vmclear_operation(); -+ rcu_read_unlock(); -+} - - /* This is the CPU performing the emergency shutdown work. */ - int crashing_cpu = -1; -@@ -798,6 +818,8 @@ int crashing_cpu = -1; - */ - void cpu_emergency_disable_virtualization(void) - { -+ cpu_crash_vmclear_loaded_vmcss(); -+ - cpu_emergency_vmxoff(); - cpu_emergency_svm_disable(); - } -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 892609cde4a20..804a252382da7 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -363,15 +363,11 @@ static void __init add_early_ima_buffer(u64 phys_addr) - #if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE) - int __init ima_free_kexec_buffer(void) - { -- int rc; -- - if (!ima_kexec_buffer_size) - return -ENOENT; - -- rc = memblock_phys_free(ima_kexec_buffer_phys, -- ima_kexec_buffer_size); -- if (rc) -- return rc; -+ memblock_free_late(ima_kexec_buffer_phys, -+ ima_kexec_buffer_size); - - ima_kexec_buffer_phys = 0; - ima_kexec_buffer_size = 0; -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 7a6df4b62c1bd..2a6fec4e2d196 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -6079,7 +6079,6 @@ static bool kvm_rmap_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_e - void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) - { - bool flush; -- int i; - - if (WARN_ON_ONCE(gfn_end <= gfn_start)) - return; -@@ -6090,11 +6089,8 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) - - flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end); - -- if (is_tdp_mmu_enabled(kvm)) { -- for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) -- flush = kvm_tdp_mmu_zap_leafs(kvm, i, gfn_start, -- gfn_end, true, flush); -- } -+ if (is_tdp_mmu_enabled(kvm)) -+ flush = kvm_tdp_mmu_zap_leafs(kvm, gfn_start, gfn_end, flush); - - if (flush) - kvm_flush_remote_tlbs_with_address(kvm, gfn_start, -diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c -index 70945f00ec412..9b9fc4e834d09 100644 ---- a/arch/x86/kvm/mmu/tdp_mmu.c -+++ b/arch/x86/kvm/mmu/tdp_mmu.c -@@ -222,8 +222,12 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, - #define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \ - __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true) - --#define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id) \ -- __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, false, false) -+#define for_each_tdp_mmu_root_yield_safe(_kvm, _root) \ -+ for (_root = tdp_mmu_next_root(_kvm, NULL, false, false); \ -+ _root; \ -+ _root = tdp_mmu_next_root(_kvm, _root, false, false)) \ -+ if (!kvm_lockdep_assert_mmu_lock_held(_kvm, false)) { \ -+ } else - - /* - * Iterate over all TDP MMU roots. Requires that mmu_lock be held for write, -@@ -955,13 +959,12 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root, - * true if a TLB flush is needed before releasing the MMU lock, i.e. if one or - * more SPTEs were zapped since the MMU lock was last acquired. - */ --bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end, -- bool can_yield, bool flush) -+bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush) - { - struct kvm_mmu_page *root; - -- for_each_tdp_mmu_root_yield_safe(kvm, root, as_id) -- flush = tdp_mmu_zap_leafs(kvm, root, start, end, can_yield, flush); -+ for_each_tdp_mmu_root_yield_safe(kvm, root) -+ flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush); - - return flush; - } -@@ -969,7 +972,6 @@ bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end, - void kvm_tdp_mmu_zap_all(struct kvm *kvm) - { - struct kvm_mmu_page *root; -- int i; - - /* - * Zap all roots, including invalid roots, as all SPTEs must be dropped -@@ -983,10 +985,8 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) - * is being destroyed or the userspace VMM has exited. In both cases, - * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request. - */ -- for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { -- for_each_tdp_mmu_root_yield_safe(kvm, root, i) -- tdp_mmu_zap_root(kvm, root, false); -- } -+ for_each_tdp_mmu_root_yield_safe(kvm, root) -+ tdp_mmu_zap_root(kvm, root, false); - } - - /* -@@ -1221,8 +1221,13 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) - bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range, - bool flush) - { -- return kvm_tdp_mmu_zap_leafs(kvm, range->slot->as_id, range->start, -- range->end, range->may_block, flush); -+ struct kvm_mmu_page *root; -+ -+ __for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id, false, false) -+ flush = tdp_mmu_zap_leafs(kvm, root, range->start, range->end, -+ range->may_block, flush); -+ -+ return flush; - } - - typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter, -diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h -index c163f7cc23ca5..d0a9fe0770fdd 100644 ---- a/arch/x86/kvm/mmu/tdp_mmu.h -+++ b/arch/x86/kvm/mmu/tdp_mmu.h -@@ -15,8 +15,7 @@ __must_check static inline bool kvm_tdp_mmu_get_root(struct kvm_mmu_page *root) - void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, - bool shared); - --bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, -- gfn_t end, bool can_yield, bool flush); -+bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush); - bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp); - void kvm_tdp_mmu_zap_all(struct kvm *kvm); - void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm); -diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c -index d08d5e085649f..3060fe4e9731a 100644 ---- a/arch/x86/kvm/svm/sev.c -+++ b/arch/x86/kvm/svm/sev.c -@@ -2941,6 +2941,32 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) - count, in); - } - -+static void sev_es_vcpu_after_set_cpuid(struct vcpu_svm *svm) -+{ -+ struct kvm_vcpu *vcpu = &svm->vcpu; -+ -+ if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) { -+ bool v_tsc_aux = guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP) || -+ guest_cpuid_has(vcpu, X86_FEATURE_RDPID); -+ -+ set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, v_tsc_aux, v_tsc_aux); -+ } -+} -+ -+void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm) -+{ -+ struct kvm_vcpu *vcpu = &svm->vcpu; -+ struct kvm_cpuid_entry2 *best; -+ -+ /* For sev guests, the memory encryption bit is not reserved in CR3. */ -+ best = kvm_find_cpuid_entry(vcpu, 0x8000001F); -+ if (best) -+ vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); -+ -+ if (sev_es_guest(svm->vcpu.kvm)) -+ sev_es_vcpu_after_set_cpuid(svm); -+} -+ - static void sev_es_init_vmcb(struct vcpu_svm *svm) - { - struct kvm_vcpu *vcpu = &svm->vcpu; -@@ -2987,14 +3013,6 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm) - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); -- -- if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && -- (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP) || -- guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDPID))) { -- set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, 1, 1); -- if (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP)) -- svm_clr_intercept(svm, INTERCEPT_RDTSCP); -- } - } - - void sev_init_vmcb(struct vcpu_svm *svm) -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index 7e4d66be18ef5..c871a6d6364ca 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -4173,7 +4173,6 @@ static bool svm_has_emulated_msr(struct kvm *kvm, u32 index) - static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) - { - struct vcpu_svm *svm = to_svm(vcpu); -- struct kvm_cpuid_entry2 *best; - - vcpu->arch.xsaves_enabled = guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) && - boot_cpu_has(X86_FEATURE_XSAVE) && -@@ -4198,12 +4197,8 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) - - svm_recalc_instruction_intercepts(vcpu, svm); - -- /* For sev guests, the memory encryption bit is not reserved in CR3. */ -- if (sev_guest(vcpu->kvm)) { -- best = kvm_find_cpuid_entry(vcpu, 0x8000001F); -- if (best) -- vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); -- } -+ if (sev_guest(vcpu->kvm)) -+ sev_vcpu_after_set_cpuid(svm); - - init_vmcb_after_set_cpuid(vcpu); - } -diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h -index 62f87492763e0..4cb1425900c6d 100644 ---- a/arch/x86/kvm/svm/svm.h -+++ b/arch/x86/kvm/svm/svm.h -@@ -677,6 +677,7 @@ void __init sev_hardware_setup(void); - void sev_hardware_unsetup(void); - int sev_cpu_init(struct svm_cpu_data *sd); - void sev_init_vmcb(struct vcpu_svm *svm); -+void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm); - void sev_free_vcpu(struct kvm_vcpu *vcpu); - int sev_handle_vmgexit(struct kvm_vcpu *vcpu); - int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); -diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c -index 4e972b9b68e59..31a10d774df6d 100644 ---- a/arch/x86/kvm/vmx/vmx.c -+++ b/arch/x86/kvm/vmx/vmx.c -@@ -40,7 +40,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include -@@ -702,7 +702,6 @@ static int vmx_set_guest_uret_msr(struct vcpu_vmx *vmx, - return ret; - } - --#ifdef CONFIG_KEXEC_CORE - static void crash_vmclear_local_loaded_vmcss(void) - { - int cpu = raw_smp_processor_id(); -@@ -712,7 +711,6 @@ static void crash_vmclear_local_loaded_vmcss(void) - loaded_vmcss_on_cpu_link) - vmcs_clear(v->vmcs); - } --#endif /* CONFIG_KEXEC_CORE */ - - static void __loaded_vmcs_clear(void *arg) - { -@@ -8522,10 +8520,9 @@ static void __vmx_exit(void) - { - allow_smaller_maxphyaddr = false; - --#ifdef CONFIG_KEXEC_CORE - RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); - synchronize_rcu(); --#endif -+ - vmx_cleanup_l1d_flush(); - } - -@@ -8598,10 +8595,9 @@ static int __init vmx_init(void) - pi_init_cpu(cpu); - } - --#ifdef CONFIG_KEXEC_CORE - rcu_assign_pointer(crash_vmclear_loaded_vmcss, - crash_vmclear_local_loaded_vmcss); --#endif -+ - vmx_check_vmcs12_offsets(); - - /* -diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile -index a65b7a9ebff28..d8b0fadf429a9 100644 ---- a/arch/xtensa/boot/Makefile -+++ b/arch/xtensa/boot/Makefile -@@ -9,8 +9,7 @@ - - - # KBUILD_CFLAGS used when building rest of boot (takes effect recursively) --KBUILD_CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include --HOSTFLAGS += -Iarch/$(ARCH)/boot/include -+KBUILD_CFLAGS += -fno-builtin - - subdir-y := lib - targets += vmlinux.bin vmlinux.bin.gz -diff --git a/arch/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c -index e3ecd743c5153..b89189355122a 100644 ---- a/arch/xtensa/boot/lib/zmem.c -+++ b/arch/xtensa/boot/lib/zmem.c -@@ -4,13 +4,14 @@ - /* bits taken from ppc */ - - extern void *avail_ram, *end_avail; -+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); - --void exit (void) -+static void exit(void) - { - for (;;); - } - --void *zalloc(unsigned size) -+static void *zalloc(unsigned int size) - { - void *p = avail_ram; - -diff --git a/arch/xtensa/include/asm/core.h b/arch/xtensa/include/asm/core.h -index 7cef85ad9741a..25293269e1edd 100644 ---- a/arch/xtensa/include/asm/core.h -+++ b/arch/xtensa/include/asm/core.h -@@ -6,6 +6,10 @@ - - #include - -+#ifndef XCHAL_HAVE_DIV32 -+#define XCHAL_HAVE_DIV32 0 -+#endif -+ - #ifndef XCHAL_HAVE_EXCLUSIVE - #define XCHAL_HAVE_EXCLUSIVE 0 - #endif -diff --git a/arch/xtensa/lib/umulsidi3.S b/arch/xtensa/lib/umulsidi3.S -index 1360816479427..4d9ba2387de0f 100644 ---- a/arch/xtensa/lib/umulsidi3.S -+++ b/arch/xtensa/lib/umulsidi3.S -@@ -3,7 +3,9 @@ - #include - #include - --#if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16 -+#if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32 || XCHAL_HAVE_MAC16 -+#define XCHAL_NO_MUL 0 -+#else - #define XCHAL_NO_MUL 1 - #endif - -diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c -index 119345eeb04c9..bea539f9039a2 100644 ---- a/arch/xtensa/platforms/iss/network.c -+++ b/arch/xtensa/platforms/iss/network.c -@@ -201,7 +201,7 @@ static int tuntap_write(struct iss_net_private *lp, struct sk_buff **skb) - return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); - } - --unsigned short tuntap_protocol(struct sk_buff *skb) -+static unsigned short tuntap_protocol(struct sk_buff *skb) - { - return eth_type_trans(skb, skb->dev); - } -@@ -441,7 +441,7 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu) - return -EINVAL; - } - --void iss_net_user_timer_expire(struct timer_list *unused) -+static void iss_net_user_timer_expire(struct timer_list *unused) - { - } - -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index 0ba0c3d1613f1..25b9bdf2fc380 100644 ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -4981,17 +4981,19 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, - struct ata_link *link; - unsigned long flags; - -- /* Previous resume operation might still be in -- * progress. Wait for PM_PENDING to clear. -+ spin_lock_irqsave(ap->lock, flags); -+ -+ /* -+ * A previous PM operation might still be in progress. Wait for -+ * ATA_PFLAG_PM_PENDING to clear. - */ - if (ap->pflags & ATA_PFLAG_PM_PENDING) { -+ spin_unlock_irqrestore(ap->lock, flags); - ata_port_wait_eh(ap); -- WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); -+ spin_lock_irqsave(ap->lock, flags); - } - -- /* request PM ops to EH */ -- spin_lock_irqsave(ap->lock, flags); -- -+ /* Request PM operation to EH */ - ap->pm_mesg = mesg; - ap->pflags |= ATA_PFLAG_PM_PENDING; - ata_for_each_link(link, ap, HOST_FIRST) { -@@ -5003,10 +5005,8 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, - - spin_unlock_irqrestore(ap->lock, flags); - -- if (!async) { -+ if (!async) - ata_port_wait_eh(ap); -- WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); -- } - } - - /* -@@ -5173,7 +5173,7 @@ EXPORT_SYMBOL_GPL(ata_host_resume); - #endif - - const struct device_type ata_port_type = { -- .name = "ata_port", -+ .name = ATA_PORT_TYPE_NAME, - #ifdef CONFIG_PM - .pm = &ata_port_pm_ops, - #endif -@@ -5906,11 +5906,30 @@ static void ata_port_detach(struct ata_port *ap) - if (!ap->ops->error_handler) - goto skip_eh; - -- /* tell EH we're leaving & flush EH */ -+ /* Wait for any ongoing EH */ -+ ata_port_wait_eh(ap); -+ -+ mutex_lock(&ap->scsi_scan_mutex); - spin_lock_irqsave(ap->lock, flags); -+ -+ /* Remove scsi devices */ -+ ata_for_each_link(link, ap, HOST_FIRST) { -+ ata_for_each_dev(dev, link, ALL) { -+ if (dev->sdev) { -+ spin_unlock_irqrestore(ap->lock, flags); -+ scsi_remove_device(dev->sdev); -+ spin_lock_irqsave(ap->lock, flags); -+ dev->sdev = NULL; -+ } -+ } -+ } -+ -+ /* Tell EH to disable all devices */ - ap->pflags |= ATA_PFLAG_UNLOADING; - ata_port_schedule_eh(ap); -+ - spin_unlock_irqrestore(ap->lock, flags); -+ mutex_unlock(&ap->scsi_scan_mutex); - - /* wait till EH commits suicide */ - ata_port_wait_eh(ap); -diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c -index a3ae5fc2a42fc..6d4c80b6daaef 100644 ---- a/drivers/ata/libata-eh.c -+++ b/drivers/ata/libata-eh.c -@@ -2704,18 +2704,11 @@ int ata_eh_reset(struct ata_link *link, int classify, - } - } - -- /* -- * Some controllers can't be frozen very well and may set spurious -- * error conditions during reset. Clear accumulated error -- * information and re-thaw the port if frozen. As reset is the -- * final recovery action and we cross check link onlineness against -- * device classification later, no hotplug event is lost by this. -- */ -+ /* clear cached SError */ - spin_lock_irqsave(link->ap->lock, flags); -- memset(&link->eh_info, 0, sizeof(link->eh_info)); -+ link->eh_info.serror = 0; - if (slave) -- memset(&slave->eh_info, 0, sizeof(link->eh_info)); -- ap->pflags &= ~ATA_PFLAG_EH_PENDING; -+ slave->eh_info.serror = 0; - spin_unlock_irqrestore(link->ap->lock, flags); - - if (ap->pflags & ATA_PFLAG_FROZEN) -diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c -index 9c0052d28078a..d28628b964e29 100644 ---- a/drivers/ata/libata-scsi.c -+++ b/drivers/ata/libata-scsi.c -@@ -1113,6 +1113,42 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) - return 0; - } - -+/** -+ * ata_scsi_slave_alloc - Early setup of SCSI device -+ * @sdev: SCSI device to examine -+ * -+ * This is called from scsi_alloc_sdev() when the scsi device -+ * associated with an ATA device is scanned on a port. -+ * -+ * LOCKING: -+ * Defined by SCSI layer. We don't really care. -+ */ -+ -+int ata_scsi_slave_alloc(struct scsi_device *sdev) -+{ -+ struct ata_port *ap = ata_shost_to_port(sdev->host); -+ struct device_link *link; -+ -+ ata_scsi_sdev_config(sdev); -+ -+ /* -+ * Create a link from the ata_port device to the scsi device to ensure -+ * that PM does suspend/resume in the correct order: the scsi device is -+ * consumer (child) and the ata port the supplier (parent). -+ */ -+ link = device_link_add(&sdev->sdev_gendev, &ap->tdev, -+ DL_FLAG_STATELESS | -+ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); -+ if (!link) { -+ ata_port_err(ap, "Failed to create link to scsi device %s\n", -+ dev_name(&sdev->sdev_gendev)); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(ata_scsi_slave_alloc); -+ - /** - * ata_scsi_slave_config - Set SCSI device attributes - * @sdev: SCSI device to examine -@@ -1129,14 +1165,11 @@ int ata_scsi_slave_config(struct scsi_device *sdev) - { - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); -- int rc = 0; -- -- ata_scsi_sdev_config(sdev); - - if (dev) -- rc = ata_scsi_dev_config(sdev, dev); -+ return ata_scsi_dev_config(sdev, dev); - -- return rc; -+ return 0; - } - EXPORT_SYMBOL_GPL(ata_scsi_slave_config); - -@@ -1163,6 +1196,8 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) - if (!ap->ops->error_handler) - return; - -+ device_link_remove(&sdev->sdev_gendev, &ap->tdev); -+ - spin_lock_irqsave(ap->lock, flags); - dev = __ata_scsi_find_dev(ap, sdev); - if (dev && dev->sdev) { -@@ -4192,7 +4227,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) - break; - - case MAINTENANCE_IN: -- if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES) -+ if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES) - ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); - else - ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); -diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c -index e4fb9d1b9b398..3e49a877500e1 100644 ---- a/drivers/ata/libata-transport.c -+++ b/drivers/ata/libata-transport.c -@@ -266,6 +266,10 @@ void ata_tport_delete(struct ata_port *ap) - put_device(dev); - } - -+static const struct device_type ata_port_sas_type = { -+ .name = ATA_PORT_TYPE_NAME, -+}; -+ - /** ata_tport_add - initialize a transport ATA port structure - * - * @parent: parent device -@@ -283,7 +287,10 @@ int ata_tport_add(struct device *parent, - struct device *dev = &ap->tdev; - - device_initialize(dev); -- dev->type = &ata_port_type; -+ if (ap->flags & ATA_FLAG_SAS_HOST) -+ dev->type = &ata_port_sas_type; -+ else -+ dev->type = &ata_port_type; - - dev->parent = parent; - ata_host_get(ap->host); -diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h -index 2c5c8273af017..e5ec197aed303 100644 ---- a/drivers/ata/libata.h -+++ b/drivers/ata/libata.h -@@ -30,6 +30,8 @@ enum { - ATA_DNXFER_QUIET = (1 << 31), - }; - -+#define ATA_PORT_TYPE_NAME "ata_port" -+ - extern atomic_t ata_print_id; - extern int atapi_passthru16; - extern int libata_fua; -diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c -index e3cff01201b80..17f9062b0eaa5 100644 ---- a/drivers/ata/sata_mv.c -+++ b/drivers/ata/sata_mv.c -@@ -1255,8 +1255,8 @@ static void mv_dump_mem(struct device *dev, void __iomem *start, unsigned bytes) - - for (b = 0; b < bytes; ) { - for (w = 0, o = 0; b < bytes && w < 4; w++) { -- o += snprintf(linebuf + o, sizeof(linebuf) - o, -- "%08x ", readl(start + b)); -+ o += scnprintf(linebuf + o, sizeof(linebuf) - o, -+ "%08x ", readl(start + b)); - b += sizeof(u32); - } - dev_dbg(dev, "%s: %p: %s\n", -diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c -index ddde1427c90c7..59a2fe2448f17 100644 ---- a/drivers/bus/ti-sysc.c -+++ b/drivers/bus/ti-sysc.c -@@ -38,6 +38,7 @@ enum sysc_soc { - SOC_2420, - SOC_2430, - SOC_3430, -+ SOC_AM35, - SOC_3630, - SOC_4430, - SOC_4460, -@@ -1119,6 +1120,11 @@ static int sysc_enable_module(struct device *dev) - if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | - SYSC_QUIRK_SWSUP_SIDLE_ACT)) { - best_mode = SYSC_IDLE_NO; -+ -+ /* Clear WAKEUP */ -+ if (regbits->enwkup_shift >= 0 && -+ ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) -+ reg &= ~BIT(regbits->enwkup_shift); - } else { - best_mode = fls(ddata->cfg.sidlemodes) - 1; - if (best_mode > SYSC_IDLE_MASK) { -@@ -1246,6 +1252,13 @@ set_sidle: - } - } - -+ if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT) { -+ /* Set WAKEUP */ -+ if (regbits->enwkup_shift >= 0 && -+ ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) -+ reg |= BIT(regbits->enwkup_shift); -+ } -+ - reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); - reg |= best_mode << regbits->sidle_shift; - if (regbits->autoidle_shift >= 0 && -@@ -1540,16 +1553,16 @@ struct sysc_revision_quirk { - static const struct sysc_revision_quirk sysc_revision_quirks[] = { - /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ - SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, -- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), -+ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), - SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, -- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), -+ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), - /* Uarts on omap4 and later */ - SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, -- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), -+ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), - SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, -- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), -+ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), - SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, -- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), -+ SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), - - /* Quirks that need to be set based on the module address */ - SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, -@@ -1878,7 +1891,7 @@ static void sysc_pre_reset_quirk_dss(struct sysc *ddata) - dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n", - __func__, val, irq_mask); - -- if (sysc_soc->soc == SOC_3430) { -+ if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) { - /* Clear DSS_SDI_CONTROL */ - sysc_write(ddata, 0x44, 0); - -@@ -2166,8 +2179,7 @@ static int sysc_reset(struct sysc *ddata) - } - - if (ddata->cfg.srst_udelay) -- usleep_range(ddata->cfg.srst_udelay, -- ddata->cfg.srst_udelay * 2); -+ fsleep(ddata->cfg.srst_udelay); - - if (ddata->post_reset_quirk) - ddata->post_reset_quirk(ddata); -@@ -3043,6 +3055,7 @@ static void ti_sysc_idle(struct work_struct *work) - static const struct soc_device_attribute sysc_soc_match[] = { - SOC_FLAG("OMAP242*", SOC_2420), - SOC_FLAG("OMAP243*", SOC_2430), -+ SOC_FLAG("AM35*", SOC_AM35), - SOC_FLAG("OMAP3[45]*", SOC_3430), - SOC_FLAG("OMAP3[67]*", SOC_3630), - SOC_FLAG("OMAP443*", SOC_4430), -@@ -3249,7 +3262,7 @@ static int sysc_check_active_timer(struct sysc *ddata) - * can be dropped if we stop supporting old beagleboard revisions - * A to B4 at some point. - */ -- if (sysc_soc->soc == SOC_3430) -+ if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) - error = -ENXIO; - else - error = -EBUSY; -diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c -index 514f9f287a781..c6f181702b9a7 100644 ---- a/drivers/char/agp/parisc-agp.c -+++ b/drivers/char/agp/parisc-agp.c -@@ -394,8 +394,6 @@ find_quicksilver(struct device *dev, void *data) - static int __init - parisc_agp_init(void) - { -- extern struct sba_device *sba_list; -- - int err = -1; - struct parisc_device *sba = NULL, *lba = NULL; - struct lba_device *lbadev = NULL; -diff --git a/drivers/clk/sprd/ums512-clk.c b/drivers/clk/sprd/ums512-clk.c -index fc25bdd85e4ea..f43bb10bd5ae2 100644 ---- a/drivers/clk/sprd/ums512-clk.c -+++ b/drivers/clk/sprd/ums512-clk.c -@@ -800,7 +800,7 @@ static SPRD_MUX_CLK_DATA(uart1_clk, "uart1-clk", uart_parents, - 0x250, 0, 3, UMS512_MUX_FLAG); - - static const struct clk_parent_data thm_parents[] = { -- { .fw_name = "ext-32m" }, -+ { .fw_name = "ext-32k" }, - { .hw = &clk_250k.hw }, - }; - static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents, -diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c -index d82a71f10c2c1..39241662a412a 100644 ---- a/drivers/clk/tegra/clk-bpmp.c -+++ b/drivers/clk/tegra/clk-bpmp.c -@@ -159,7 +159,7 @@ static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw, - - err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); - if (err < 0) -- return err; -+ return 0; - - return response.rate; - } -diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c -index c37e823590055..21481fc05800f 100644 ---- a/drivers/firmware/arm_ffa/driver.c -+++ b/drivers/firmware/arm_ffa/driver.c -@@ -478,6 +478,19 @@ static u32 ffa_get_num_pages_sg(struct scatterlist *sg) - return num_pages; - } - -+static u8 ffa_memory_attributes_get(u32 func_id) -+{ -+ /* -+ * For the memory lend or donate operation, if the receiver is a PE or -+ * a proxy endpoint, the owner/sender must not specify the attributes -+ */ -+ if (func_id == FFA_FN_NATIVE(MEM_LEND) || -+ func_id == FFA_MEM_LEND) -+ return 0; -+ -+ return FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | FFA_MEM_INNER_SHAREABLE; -+} -+ - static int - ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, - struct ffa_mem_ops_args *args) -@@ -494,8 +507,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, - mem_region->tag = args->tag; - mem_region->flags = args->flags; - mem_region->sender_id = drv_info->vm_id; -- mem_region->attributes = FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | -- FFA_MEM_INNER_SHAREABLE; -+ mem_region->attributes = ffa_memory_attributes_get(func_id); - ep_mem_access = &mem_region->ep_mem_access[0]; - - for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) { -diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c -index ecf5c4de851b7..431bda9165c3d 100644 ---- a/drivers/firmware/arm_scmi/perf.c -+++ b/drivers/firmware/arm_scmi/perf.c -@@ -139,7 +139,7 @@ struct perf_dom_info { - - struct scmi_perf_info { - u32 version; -- int num_domains; -+ u16 num_domains; - enum scmi_power_scale power_scale; - u64 stats_addr; - u32 stats_size; -@@ -356,11 +356,26 @@ static int scmi_perf_mb_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, - u32 domain, u32 max_perf, u32 min_perf) - { - struct scmi_perf_info *pi = ph->get_priv(ph); -- struct perf_dom_info *dom = pi->dom_info + domain; -+ struct perf_dom_info *dom; -+ -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return PTR_ERR(dom); - - if (PROTOCOL_REV_MAJOR(pi->version) >= 0x3 && !max_perf && !min_perf) - return -EINVAL; -@@ -408,8 +423,11 @@ static int scmi_perf_mb_limits_get(const struct scmi_protocol_handle *ph, - static int scmi_perf_limits_get(const struct scmi_protocol_handle *ph, - u32 domain, u32 *max_perf, u32 *min_perf) - { -- struct scmi_perf_info *pi = ph->get_priv(ph); -- struct perf_dom_info *dom = pi->dom_info + domain; -+ struct perf_dom_info *dom; -+ -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return PTR_ERR(dom); - - if (dom->fc_info && dom->fc_info[PERF_FC_LIMIT].get_addr) { - struct scmi_fc_info *fci = &dom->fc_info[PERF_FC_LIMIT]; -@@ -449,8 +467,11 @@ static int scmi_perf_mb_level_set(const struct scmi_protocol_handle *ph, - static int scmi_perf_level_set(const struct scmi_protocol_handle *ph, - u32 domain, u32 level, bool poll) - { -- struct scmi_perf_info *pi = ph->get_priv(ph); -- struct perf_dom_info *dom = pi->dom_info + domain; -+ struct perf_dom_info *dom; -+ -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return PTR_ERR(dom); - - if (dom->fc_info && dom->fc_info[PERF_FC_LEVEL].set_addr) { - struct scmi_fc_info *fci = &dom->fc_info[PERF_FC_LEVEL]; -@@ -490,8 +511,11 @@ static int scmi_perf_mb_level_get(const struct scmi_protocol_handle *ph, - static int scmi_perf_level_get(const struct scmi_protocol_handle *ph, - u32 domain, u32 *level, bool poll) - { -- struct scmi_perf_info *pi = ph->get_priv(ph); -- struct perf_dom_info *dom = pi->dom_info + domain; -+ struct perf_dom_info *dom; -+ -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return PTR_ERR(dom); - - if (dom->fc_info && dom->fc_info[PERF_FC_LEVEL].get_addr) { - *level = ioread32(dom->fc_info[PERF_FC_LEVEL].get_addr); -@@ -574,13 +598,14 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph, - unsigned long freq; - struct scmi_opp *opp; - struct perf_dom_info *dom; -- struct scmi_perf_info *pi = ph->get_priv(ph); - - domain = scmi_dev_domain_id(dev); - if (domain < 0) -- return domain; -+ return -EINVAL; - -- dom = pi->dom_info + domain; -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return PTR_ERR(dom); - - for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) { - freq = opp->perf * dom->mult_factor; -@@ -603,14 +628,17 @@ static int - scmi_dvfs_transition_latency_get(const struct scmi_protocol_handle *ph, - struct device *dev) - { -+ int domain; - struct perf_dom_info *dom; -- struct scmi_perf_info *pi = ph->get_priv(ph); -- int domain = scmi_dev_domain_id(dev); - -+ domain = scmi_dev_domain_id(dev); - if (domain < 0) -- return domain; -+ return -EINVAL; -+ -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return PTR_ERR(dom); - -- dom = pi->dom_info + domain; - /* uS to nS */ - return dom->opp[dom->opp_count - 1].trans_latency_us * 1000; - } -@@ -618,8 +646,11 @@ scmi_dvfs_transition_latency_get(const struct scmi_protocol_handle *ph, - static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain, - unsigned long freq, bool poll) - { -- struct scmi_perf_info *pi = ph->get_priv(ph); -- struct perf_dom_info *dom = pi->dom_info + domain; -+ struct perf_dom_info *dom; -+ -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return PTR_ERR(dom); - - return scmi_perf_level_set(ph, domain, freq / dom->mult_factor, poll); - } -@@ -630,11 +661,14 @@ static int scmi_dvfs_freq_get(const struct scmi_protocol_handle *ph, u32 domain, - int ret; - u32 level; - struct scmi_perf_info *pi = ph->get_priv(ph); -- struct perf_dom_info *dom = pi->dom_info + domain; - - ret = scmi_perf_level_get(ph, domain, &level, poll); -- if (!ret) -+ if (!ret) { -+ struct perf_dom_info *dom = pi->dom_info + domain; -+ -+ /* Note domain is validated implicitly by scmi_perf_level_get */ - *freq = level * dom->mult_factor; -+ } - - return ret; - } -@@ -643,15 +677,14 @@ static int scmi_dvfs_est_power_get(const struct scmi_protocol_handle *ph, - u32 domain, unsigned long *freq, - unsigned long *power) - { -- struct scmi_perf_info *pi = ph->get_priv(ph); - struct perf_dom_info *dom; - unsigned long opp_freq; - int idx, ret = -EINVAL; - struct scmi_opp *opp; - -- dom = pi->dom_info + domain; -- if (!dom) -- return -EIO; -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return PTR_ERR(dom); - - for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) { - opp_freq = opp->perf * dom->mult_factor; -@@ -670,10 +703,16 @@ static int scmi_dvfs_est_power_get(const struct scmi_protocol_handle *ph, - static bool scmi_fast_switch_possible(const struct scmi_protocol_handle *ph, - struct device *dev) - { -+ int domain; - struct perf_dom_info *dom; -- struct scmi_perf_info *pi = ph->get_priv(ph); - -- dom = pi->dom_info + scmi_dev_domain_id(dev); -+ domain = scmi_dev_domain_id(dev); -+ if (domain < 0) -+ return false; -+ -+ dom = scmi_perf_domain_lookup(ph, domain); -+ if (IS_ERR(dom)) -+ return false; - - return dom->fc_info && dom->fc_info[PERF_FC_LEVEL].set_addr; - } -@@ -819,6 +858,8 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) - if (!pinfo) - return -ENOMEM; - -+ pinfo->version = version; -+ - ret = scmi_perf_attributes_get(ph, pinfo); - if (ret) - return ret; -@@ -838,8 +879,6 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) - scmi_perf_domain_init_fc(ph, domain, &dom->fc_info); - } - -- pinfo->version = version; -- - return ph->set_priv(ph, pinfo); - } - -diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c -index 81c5f94b1be11..64ed9d3f5d5d8 100644 ---- a/drivers/firmware/cirrus/cs_dsp.c -+++ b/drivers/firmware/cirrus/cs_dsp.c -@@ -1821,15 +1821,15 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) - return PTR_ERR(adsp2_alg); - - for (i = 0; i < n_algs; i++) { -- cs_dsp_info(dsp, -- "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", -- i, be32_to_cpu(adsp2_alg[i].alg.id), -- (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, -- (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, -- be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, -- be32_to_cpu(adsp2_alg[i].xm), -- be32_to_cpu(adsp2_alg[i].ym), -- be32_to_cpu(adsp2_alg[i].zm)); -+ cs_dsp_dbg(dsp, -+ "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", -+ i, be32_to_cpu(adsp2_alg[i].alg.id), -+ (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, -+ (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, -+ be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, -+ be32_to_cpu(adsp2_alg[i].xm), -+ be32_to_cpu(adsp2_alg[i].ym), -+ be32_to_cpu(adsp2_alg[i].zm)); - - alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, - adsp2_alg[i].alg.id, -@@ -1954,14 +1954,14 @@ static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) - return PTR_ERR(halo_alg); - - for (i = 0; i < n_algs; i++) { -- cs_dsp_info(dsp, -- "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", -- i, be32_to_cpu(halo_alg[i].alg.id), -- (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, -- (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, -- be32_to_cpu(halo_alg[i].alg.ver) & 0xff, -- be32_to_cpu(halo_alg[i].xm_base), -- be32_to_cpu(halo_alg[i].ym_base)); -+ cs_dsp_dbg(dsp, -+ "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", -+ i, be32_to_cpu(halo_alg[i].alg.id), -+ (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, -+ (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, -+ be32_to_cpu(halo_alg[i].alg.ver) & 0xff, -+ be32_to_cpu(halo_alg[i].xm_base), -+ be32_to_cpu(halo_alg[i].ym_base)); - - ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, - halo_alg[i].alg.ver, -diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c -index a6c06d7476c32..1f410809d3ee4 100644 ---- a/drivers/firmware/imx/imx-dsp.c -+++ b/drivers/firmware/imx/imx-dsp.c -@@ -115,6 +115,7 @@ static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) - dsp_chan->idx = i % 2; - dsp_chan->ch = mbox_request_channel_byname(cl, chan_name); - if (IS_ERR(dsp_chan->ch)) { -+ kfree(dsp_chan->name); - ret = PTR_ERR(dsp_chan->ch); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to request mbox chan %s ret %d\n", -diff --git a/drivers/gpio/gpio-pmic-eic-sprd.c b/drivers/gpio/gpio-pmic-eic-sprd.c -index e518490c4b681..ebbbcb54270d1 100644 ---- a/drivers/gpio/gpio-pmic-eic-sprd.c -+++ b/drivers/gpio/gpio-pmic-eic-sprd.c -@@ -337,6 +337,7 @@ static int sprd_pmic_eic_probe(struct platform_device *pdev) - pmic_eic->chip.set_config = sprd_pmic_eic_set_config; - pmic_eic->chip.set = sprd_pmic_eic_set; - pmic_eic->chip.get = sprd_pmic_eic_get; -+ pmic_eic->chip.can_sleep = true; - - pmic_eic->intc.name = dev_name(&pdev->dev); - pmic_eic->intc.irq_mask = sprd_pmic_eic_irq_mask; -diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c -index de6afa3f97168..05357473d2a11 100644 ---- a/drivers/gpio/gpio-tb10x.c -+++ b/drivers/gpio/gpio-tb10x.c -@@ -195,7 +195,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev) - handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, - IRQ_GC_INIT_MASK_CACHE); - if (ret) -- return ret; -+ goto err_remove_domain; - - gc = tb10x_gpio->domain->gc->gc[0]; - gc->reg_base = tb10x_gpio->base; -@@ -209,6 +209,10 @@ static int tb10x_gpio_probe(struct platform_device *pdev) - } - - return 0; -+ -+err_remove_domain: -+ irq_domain_remove(tb10x_gpio->domain); -+ return ret; - } - - static int tb10x_gpio_remove(struct platform_device *pdev) -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -index 9e3313dd956ae..24b4bd6bb2771 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c -@@ -896,12 +896,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) - struct atom_context *atom_context; - - atom_context = adev->mode_info.atom_context; -- memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name)); -- memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn)); -- vbios_info.version = atom_context->version; -- memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, -- sizeof(atom_context->vbios_ver_str)); -- memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date)); -+ if (atom_context) { -+ memcpy(vbios_info.name, atom_context->name, -+ sizeof(atom_context->name)); -+ memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, -+ sizeof(atom_context->vbios_pn)); -+ vbios_info.version = atom_context->version; -+ memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, -+ sizeof(atom_context->vbios_ver_str)); -+ memcpy(vbios_info.date, atom_context->date, -+ sizeof(atom_context->date)); -+ } - - return copy_to_user(out, &vbios_info, - min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0; -diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c -index 09fdcd20cb919..c52a378396af1 100644 ---- a/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c -+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c -@@ -344,6 +344,9 @@ static void nbio_v4_3_init_registers(struct amdgpu_device *adev) - data &= ~RCC_DEV0_EPF2_STRAP2__STRAP_NO_SOFT_RESET_DEV0_F2_MASK; - WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2, data); - } -+ if (amdgpu_sriov_vf(adev)) -+ adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, -+ regBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; - } - - static u32 nbio_v4_3_get_rom_offset(struct amdgpu_device *adev) -diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c -index d150a90daa403..56af7b5abac14 100644 ---- a/drivers/gpu/drm/amd/amdgpu/soc21.c -+++ b/drivers/gpu/drm/amd/amdgpu/soc21.c -@@ -755,7 +755,7 @@ static int soc21_common_hw_init(void *handle) - * for the purpose of expose those registers - * to process space - */ -- if (adev->nbio.funcs->remap_hdp_registers) -+ if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) - adev->nbio.funcs->remap_hdp_registers(adev); - /* enable the doorbell aperture */ - soc21_enable_doorbell_aperture(adev, true); -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 c06ada0844ba1..0b87034d9dd51 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c -@@ -201,7 +201,7 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q, - - if (q->wptr_bo) { - wptr_addr_off = (uint64_t)q->properties.write_ptr & (PAGE_SIZE - 1); -- queue_input.wptr_mc_addr = ((uint64_t)q->wptr_bo->tbo.resource->start << PAGE_SHIFT) + wptr_addr_off; -+ queue_input.wptr_mc_addr = amdgpu_bo_gpu_offset(q->wptr_bo) + wptr_addr_off; - } - - queue_input.is_kfd_process = 1; -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h -index 6d6588b9beed7..ec8a576ac5a9e 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h -@@ -1349,9 +1349,8 @@ void kfd_flush_tlb(struct kfd_process_device *pdd, enum TLB_FLUSH_TYPE type); - - static inline bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev) - { -- return KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2) || -- (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) && -- dev->adev->sdma.instance[0].fw_version >= 18) || -+ return KFD_GC_VERSION(dev) > IP_VERSION(9, 4, 2) || -+ (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) && dev->sdma_fw_version >= 18) || - KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 0); - } - -diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c -index 9378c98d02cfe..508f5fe268484 100644 ---- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c -+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c -@@ -973,7 +973,9 @@ void dce110_edp_backlight_control( - return; - } - -- if (link->panel_cntl) { -+ if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled || -+ link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || -+ link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { - bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); - - if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { -diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c -index 55efd3eb66723..3f43b44145a89 100644 ---- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c -+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c -@@ -655,7 +655,9 @@ static int sn65dsi83_host_attach(struct sn65dsi83 *ctx) - - dsi->lanes = dsi_lanes; - dsi->format = MIPI_DSI_FMT_RGB888; -- dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; -+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | -+ MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | -+ MIPI_DSI_MODE_VIDEO_NO_HSA | MIPI_DSI_MODE_NO_EOT_PACKET; - - ret = devm_mipi_dsi_attach(dev, dsi); - if (ret < 0) { -diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c -index b458547e1fc6e..07967adce16aa 100644 ---- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c -+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c -@@ -541,7 +541,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, - DRIVER_CAPS(i915)->has_logical_contexts = true; - - ewma__engine_latency_init(&engine->latency); -- seqcount_init(&engine->stats.execlists.lock); - - ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier); - -diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c -index fc4a846289855..f903ee1ce06e7 100644 ---- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c -+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c -@@ -3546,6 +3546,8 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine) - logical_ring_default_vfuncs(engine); - logical_ring_default_irqs(engine); - -+ seqcount_init(&engine->stats.execlists.lock); -+ - if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) - rcs_submission_override(engine); - -diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c -index 2049a00417afa..a6d0463b18d91 100644 ---- a/drivers/gpu/drm/i915/gt/intel_ggtt.c -+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c -@@ -500,20 +500,31 @@ void intel_ggtt_unbind_vma(struct i915_address_space *vm, - vm->clear_range(vm, vma_res->start, vma_res->vma_size); - } - -+/* -+ * Reserve the top of the GuC address space for firmware images. Addresses -+ * beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC, -+ * which makes for a suitable range to hold GuC/HuC firmware images if the -+ * size of the GGTT is 4G. However, on a 32-bit platform the size of the GGTT -+ * is limited to 2G, which is less than GUC_GGTT_TOP, but we reserve a chunk -+ * of the same size anyway, which is far more than needed, to keep the logic -+ * in uc_fw_ggtt_offset() simple. -+ */ -+#define GUC_TOP_RESERVE_SIZE (SZ_4G - GUC_GGTT_TOP) -+ - static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt) - { -- u64 size; -+ u64 offset; - int ret; - - if (!intel_uc_uses_guc(&ggtt->vm.gt->uc)) - return 0; - -- GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP); -- size = ggtt->vm.total - GUC_GGTT_TOP; -+ GEM_BUG_ON(ggtt->vm.total <= GUC_TOP_RESERVE_SIZE); -+ offset = ggtt->vm.total - GUC_TOP_RESERVE_SIZE; - -- ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size, -- GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE, -- PIN_NOEVICT); -+ ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, -+ GUC_TOP_RESERVE_SIZE, offset, -+ I915_COLOR_UNEVICTABLE, PIN_NOEVICT); - if (ret) - drm_dbg(&ggtt->vm.i915->drm, - "Failed to reserve top of GGTT for GuC\n"); -diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c -index 53231bfdf7e24..b14e6e507c61b 100644 ---- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c -+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c -@@ -332,6 +332,8 @@ static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge, - return; - - cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); -+ -+ kfree(edid); - } else - cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); - } -diff --git a/drivers/gpu/drm/tests/drm_mm_test.c b/drivers/gpu/drm/tests/drm_mm_test.c -index c4b66eeae2039..13fa4a18a11b2 100644 ---- a/drivers/gpu/drm/tests/drm_mm_test.c -+++ b/drivers/gpu/drm/tests/drm_mm_test.c -@@ -939,7 +939,7 @@ static void drm_test_mm_insert_range(struct kunit *test) - KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max - 1)); - KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max / 2)); - KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, -- max / 2, max / 2)); -+ max / 2, max)); - KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, - max / 4 + 1, 3 * max / 4 - 1)); - -diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c -index 1fda1eaa6d6ab..da1f6b60f9c9a 100644 ---- a/drivers/i2c/busses/i2c-i801.c -+++ b/drivers/i2c/busses/i2c-i801.c -@@ -1754,6 +1754,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) - "SMBus I801 adapter at %04lx", priv->smba); - err = i2c_add_adapter(&priv->adapter); - if (err) { -+ platform_device_unregister(priv->tco_pdev); - i801_acpi_remove(priv); - return err; - } -diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c -index 83457359ec450..767dd15b3c881 100644 ---- a/drivers/i2c/busses/i2c-npcm7xx.c -+++ b/drivers/i2c/busses/i2c-npcm7xx.c -@@ -696,6 +696,7 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, - { - struct i2c_msg *msgs; - int msgs_num; -+ bool do_complete = false; - - msgs = bus->msgs; - msgs_num = bus->msgs_num; -@@ -724,23 +725,17 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, - msgs[1].flags & I2C_M_RD) - msgs[1].len = info; - } -- if (completion_done(&bus->cmd_complete) == false) -- complete(&bus->cmd_complete); -- break; -- -+ do_complete = true; -+ break; - case I2C_NACK_IND: - /* MASTER transmit got a NACK before tx all bytes */ - bus->cmd_err = -ENXIO; -- if (bus->master_or_slave == I2C_MASTER) -- complete(&bus->cmd_complete); -- -+ do_complete = true; - break; - case I2C_BUS_ERR_IND: - /* Bus error */ - bus->cmd_err = -EAGAIN; -- if (bus->master_or_slave == I2C_MASTER) -- complete(&bus->cmd_complete); -- -+ do_complete = true; - break; - case I2C_WAKE_UP_IND: - /* I2C wake up */ -@@ -754,6 +749,8 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, - if (bus->slave) - bus->master_or_slave = I2C_SLAVE; - #endif -+ if (do_complete) -+ complete(&bus->cmd_complete); - } - - static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus) -diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c -index b41a6709e47f2..b27bfc7765993 100644 ---- a/drivers/i2c/busses/i2c-xiic.c -+++ b/drivers/i2c/busses/i2c-xiic.c -@@ -420,7 +420,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) - * reset the IP instead of just flush fifos - */ - ret = xiic_reinit(i2c); -- if (!ret) -+ if (ret < 0) - dev_dbg(i2c->adap.dev.parent, "reinit failed\n"); - - if (i2c->rx_msg) { -diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c -index f7a7405d4350a..8e8688e8de0fb 100644 ---- a/drivers/i2c/muxes/i2c-demux-pinctrl.c -+++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c -@@ -243,6 +243,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) - - props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); - props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); -+ if (!props[i].name || !props[i].value) { -+ err = -ENOMEM; -+ goto err_rollback; -+ } - props[i].length = 3; - - of_changeset_init(&priv->chan[i].chgset); -diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c -index 73a23e117ebec..0930a51c8c7c0 100644 ---- a/drivers/i2c/muxes/i2c-mux-gpio.c -+++ b/drivers/i2c/muxes/i2c-mux-gpio.c -@@ -105,8 +105,10 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux, - - } else if (is_acpi_node(child)) { - rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i); -- if (rc) -+ if (rc) { -+ fwnode_handle_put(child); - return dev_err_probe(dev, rc, "Cannot get address\n"); -+ } - } - - i++; -diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c -index 5968a568aae2a..ffba8ce93ff88 100644 ---- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c -+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c -@@ -186,6 +186,15 @@ static void arm_smmu_free_shared_cd(struct arm_smmu_ctx_desc *cd) - } - } - -+/* -+ * Cloned from the MAX_TLBI_OPS in arch/arm64/include/asm/tlbflush.h, this -+ * is used as a threshold to replace per-page TLBI commands to issue in the -+ * command queue with an address-space TLBI command, when SMMU w/o a range -+ * invalidation feature handles too many per-page TLBI commands, which will -+ * otherwise result in a soft lockup. -+ */ -+#define CMDQ_MAX_TLBI_OPS (1 << (PAGE_SHIFT - 3)) -+ - static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn, - struct mm_struct *mm, - unsigned long start, unsigned long end) -@@ -200,10 +209,22 @@ static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn, - * range. So do a simple translation here by calculating size correctly. - */ - size = end - start; -+ if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_RANGE_INV)) { -+ if (size >= CMDQ_MAX_TLBI_OPS * PAGE_SIZE) -+ size = 0; -+ } -+ -+ if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) { -+ if (!size) -+ arm_smmu_tlb_inv_asid(smmu_domain->smmu, -+ smmu_mn->cd->asid); -+ else -+ arm_smmu_tlb_inv_range_asid(start, size, -+ smmu_mn->cd->asid, -+ PAGE_SIZE, false, -+ smmu_domain); -+ } - -- if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) -- arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid, -- PAGE_SIZE, false, smmu_domain); - arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, start, size); - } - -diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h -index 28c641352de9b..71dcd8fd4050a 100644 ---- a/drivers/md/dm-core.h -+++ b/drivers/md/dm-core.h -@@ -214,6 +214,7 @@ struct dm_table { - - /* a list of devices used by this table */ - struct list_head devices; -+ struct rw_semaphore devices_lock; - - /* events get handed up using this callback */ - void (*event_fn)(void *); -diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c -index 2afd2d2a0f407..206e6ce554dc7 100644 ---- a/drivers/md/dm-ioctl.c -+++ b/drivers/md/dm-ioctl.c -@@ -1566,6 +1566,8 @@ static void retrieve_deps(struct dm_table *table, - struct dm_dev_internal *dd; - struct dm_target_deps *deps; - -+ down_read(&table->devices_lock); -+ - deps = get_result_buffer(param, param_size, &len); - - /* -@@ -1580,7 +1582,7 @@ static void retrieve_deps(struct dm_table *table, - needed = struct_size(deps, dev, count); - if (len < needed) { - param->flags |= DM_BUFFER_FULL_FLAG; -- return; -+ goto out; - } - - /* -@@ -1592,6 +1594,9 @@ static void retrieve_deps(struct dm_table *table, - deps->dev[count++] = huge_encode_dev(dd->dm_dev->bdev->bd_dev); - - param->data_size = param->data_start + needed; -+ -+out: -+ up_read(&table->devices_lock); - } - - static int table_deps(struct file *filp, struct dm_ioctl *param, size_t param_size) -diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c -index 288f600ee56dc..dac6a5f25f2be 100644 ---- a/drivers/md/dm-table.c -+++ b/drivers/md/dm-table.c -@@ -134,6 +134,7 @@ int dm_table_create(struct dm_table **result, fmode_t mode, - return -ENOMEM; - - INIT_LIST_HEAD(&t->devices); -+ init_rwsem(&t->devices_lock); - - if (!num_targets) - num_targets = KEYS_PER_NODE; -@@ -362,15 +363,19 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, - return -ENODEV; - } - -+ down_write(&t->devices_lock); -+ - dd = find_device(&t->devices, dev); - if (!dd) { - dd = kmalloc(sizeof(*dd), GFP_KERNEL); -- if (!dd) -- return -ENOMEM; -+ if (!dd) { -+ r = -ENOMEM; -+ goto unlock_ret_r; -+ } - - if ((r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev))) { - kfree(dd); -- return r; -+ goto unlock_ret_r; - } - - refcount_set(&dd->count, 1); -@@ -380,12 +385,17 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, - } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { - r = upgrade_mode(dd, mode, t->md); - if (r) -- return r; -+ goto unlock_ret_r; - } - refcount_inc(&dd->count); - out: -+ up_write(&t->devices_lock); - *result = dd->dm_dev; - return 0; -+ -+unlock_ret_r: -+ up_write(&t->devices_lock); -+ return r; - } - EXPORT_SYMBOL(dm_get_device); - -@@ -421,9 +431,12 @@ static int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, - void dm_put_device(struct dm_target *ti, struct dm_dev *d) - { - int found = 0; -- struct list_head *devices = &ti->table->devices; -+ struct dm_table *t = ti->table; -+ struct list_head *devices = &t->devices; - struct dm_dev_internal *dd; - -+ down_write(&t->devices_lock); -+ - list_for_each_entry(dd, devices, list) { - if (dd->dm_dev == d) { - found = 1; -@@ -432,14 +445,17 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d) - } - if (!found) { - DMERR("%s: device %s not in table devices list", -- dm_device_name(ti->table->md), d->name); -- return; -+ dm_device_name(t->md), d->name); -+ goto unlock_ret; - } - if (refcount_dec_and_test(&dd->count)) { -- dm_put_table_device(ti->table->md, d); -+ dm_put_table_device(t->md, d); - list_del(&dd->list); - kfree(dd); - } -+ -+unlock_ret: -+ up_write(&t->devices_lock); - } - EXPORT_SYMBOL(dm_put_device); - -diff --git a/drivers/media/common/videobuf2/frame_vector.c b/drivers/media/common/videobuf2/frame_vector.c -index 144027035892a..07ebe4424df3a 100644 ---- a/drivers/media/common/videobuf2/frame_vector.c -+++ b/drivers/media/common/videobuf2/frame_vector.c -@@ -30,6 +30,10 @@ - * different type underlying the specified range of virtual addresses. - * When the function isn't able to map a single page, it returns error. - * -+ * Note that get_vaddr_frames() cannot follow VM_IO mappings. It used -+ * to be able to do that, but that could (racily) return non-refcounted -+ * pfns. -+ * - * This function takes care of grabbing mmap_lock as necessary. - */ - int get_vaddr_frames(unsigned long start, unsigned int nr_frames, -@@ -55,8 +59,6 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, - if (likely(ret > 0)) - return ret; - -- /* This used to (racily) return non-refcounted pfns. Let people know */ -- WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping"); - vec->nr_frames = 0; - return ret ? ret : -EFAULT; - } -diff --git a/drivers/media/platform/marvell/Kconfig b/drivers/media/platform/marvell/Kconfig -index ec1a16734a280..d6499ffe30e8b 100644 ---- a/drivers/media/platform/marvell/Kconfig -+++ b/drivers/media/platform/marvell/Kconfig -@@ -7,7 +7,7 @@ config VIDEO_CAFE_CCIC - depends on V4L_PLATFORM_DRIVERS - depends on PCI && I2C && VIDEO_DEV - depends on COMMON_CLK -- select VIDEO_OV7670 -+ select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR - select VIDEOBUF2_VMALLOC - select VIDEOBUF2_DMA_CONTIG - select VIDEOBUF2_DMA_SG -@@ -22,7 +22,7 @@ config VIDEO_MMP_CAMERA - depends on I2C && VIDEO_DEV - depends on ARCH_MMP || COMPILE_TEST - depends on COMMON_CLK -- select VIDEO_OV7670 -+ select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR - select I2C_GPIO - select VIDEOBUF2_VMALLOC - select VIDEOBUF2_DMA_CONTIG -diff --git a/drivers/media/platform/via/Kconfig b/drivers/media/platform/via/Kconfig -index 8926eb0803b27..6e603c0382487 100644 ---- a/drivers/media/platform/via/Kconfig -+++ b/drivers/media/platform/via/Kconfig -@@ -7,7 +7,7 @@ config VIDEO_VIA_CAMERA - depends on V4L_PLATFORM_DRIVERS - depends on FB_VIA && VIDEO_DEV - select VIDEOBUF2_DMA_SG -- select VIDEO_OV7670 -+ select VIDEO_OV7670 if VIDEO_CAMERA_SENSOR - help - Driver support for the integrated camera controller in VIA - Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems -diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig -index b3c472b8c5a96..cb61fd6cc6c61 100644 ---- a/drivers/media/usb/em28xx/Kconfig -+++ b/drivers/media/usb/em28xx/Kconfig -@@ -12,8 +12,8 @@ config VIDEO_EM28XX_V4L2 - select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT -- select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT -- select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT -+ select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR -+ select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR - help - This is a video4linux driver for Empia 28xx based TV cards. - -diff --git a/drivers/media/usb/go7007/Kconfig b/drivers/media/usb/go7007/Kconfig -index 4ff79940ad8d4..b2a15d9fb1f33 100644 ---- a/drivers/media/usb/go7007/Kconfig -+++ b/drivers/media/usb/go7007/Kconfig -@@ -12,8 +12,8 @@ config VIDEO_GO7007 - select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT -- select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT - select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT -+ select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR - help - This is a video4linux driver for the WIS GO7007 MPEG - encoder chip. -diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c -index 067b43a1cb3eb..6d7535efc09de 100644 ---- a/drivers/media/usb/uvc/uvc_ctrl.c -+++ b/drivers/media/usb/uvc/uvc_ctrl.c -@@ -1347,6 +1347,9 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, - query_menu->id = id; - query_menu->index = index; - -+ if (index >= BITS_PER_TYPE(mapping->menu_mask)) -+ return -EINVAL; -+ - ret = mutex_lock_interruptible(&chain->ctrl_mutex); - if (ret < 0) - return -ERESTARTSYS; -diff --git a/drivers/misc/cardreader/rts5227.c b/drivers/misc/cardreader/rts5227.c -index 3dae5e3a16976..cd512284bfb39 100644 ---- a/drivers/misc/cardreader/rts5227.c -+++ b/drivers/misc/cardreader/rts5227.c -@@ -83,63 +83,20 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr) - - static void rts5227_init_from_cfg(struct rtsx_pcr *pcr) - { -- struct pci_dev *pdev = pcr->pci; -- int l1ss; -- u32 lval; - struct rtsx_cr_option *option = &pcr->option; - -- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); -- if (!l1ss) -- return; -- -- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); -- - if (CHK_PCI_PID(pcr, 0x522A)) { -- if (0 == (lval & 0x0F)) -- rtsx_pci_enable_oobs_polling(pcr); -- else -+ if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -+ | PM_L1_1_EN | PM_L1_2_EN)) - rtsx_pci_disable_oobs_polling(pcr); -+ else -+ rtsx_pci_enable_oobs_polling(pcr); - } - -- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) -- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); -- else -- rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) -- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); -- else -- rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) -- rtsx_set_dev_flag(pcr, PM_L1_1_EN); -- else -- rtsx_clear_dev_flag(pcr, PM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) -- rtsx_set_dev_flag(pcr, PM_L1_2_EN); -- else -- rtsx_clear_dev_flag(pcr, PM_L1_2_EN); -- - if (option->ltr_en) { -- u16 val; -- -- pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); -- if (val & PCI_EXP_DEVCTL2_LTR_EN) { -- option->ltr_enabled = true; -- option->ltr_active = true; -+ if (option->ltr_enabled) - rtsx_set_ltr_latency(pcr, option->ltr_active_latency); -- } else { -- option->ltr_enabled = false; -- } - } -- -- if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -- | PM_L1_1_EN | PM_L1_2_EN)) -- option->force_clkreq_0 = false; -- else -- option->force_clkreq_0 = true; -- - } - - static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) -@@ -195,7 +152,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) - } - } - -- if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) -+ if (option->force_clkreq_0) - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, - FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); - else -diff --git a/drivers/misc/cardreader/rts5228.c b/drivers/misc/cardreader/rts5228.c -index f4ab09439da70..0c7f10bcf6f12 100644 ---- a/drivers/misc/cardreader/rts5228.c -+++ b/drivers/misc/cardreader/rts5228.c -@@ -386,59 +386,25 @@ static void rts5228_process_ocp(struct rtsx_pcr *pcr) - - static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) - { -- struct pci_dev *pdev = pcr->pci; -- int l1ss; -- u32 lval; - struct rtsx_cr_option *option = &pcr->option; - -- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); -- if (!l1ss) -- return; -- -- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); -- -- if (0 == (lval & 0x0F)) -- rtsx_pci_enable_oobs_polling(pcr); -- else -+ if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -+ | PM_L1_1_EN | PM_L1_2_EN)) - rtsx_pci_disable_oobs_polling(pcr); -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) -- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); -- else -- rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) -- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); -- else -- rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) -- rtsx_set_dev_flag(pcr, PM_L1_1_EN); - else -- rtsx_clear_dev_flag(pcr, PM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) -- rtsx_set_dev_flag(pcr, PM_L1_2_EN); -- else -- rtsx_clear_dev_flag(pcr, PM_L1_2_EN); -+ rtsx_pci_enable_oobs_polling(pcr); - - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); -- if (option->ltr_en) { -- u16 val; - -- pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); -- if (val & PCI_EXP_DEVCTL2_LTR_EN) { -- option->ltr_enabled = true; -- option->ltr_active = true; -+ if (option->ltr_en) { -+ if (option->ltr_enabled) - rtsx_set_ltr_latency(pcr, option->ltr_active_latency); -- } else { -- option->ltr_enabled = false; -- } - } - } - - static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) - { -+ struct rtsx_cr_option *option = &pcr->option; - - rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, - CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); -@@ -469,6 +435,17 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) - else - rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); - -+ /* -+ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -+ * to drive low, and we forcibly request clock. -+ */ -+ if (option->force_clkreq_0) -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -+ else -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -+ - rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); - - if (pcr->rtd3_en) { -diff --git a/drivers/misc/cardreader/rts5249.c b/drivers/misc/cardreader/rts5249.c -index 47ab72a43256b..6c81040e18bef 100644 ---- a/drivers/misc/cardreader/rts5249.c -+++ b/drivers/misc/cardreader/rts5249.c -@@ -86,64 +86,22 @@ static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) - - static void rts5249_init_from_cfg(struct rtsx_pcr *pcr) - { -- struct pci_dev *pdev = pcr->pci; -- int l1ss; - struct rtsx_cr_option *option = &(pcr->option); -- u32 lval; -- -- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); -- if (!l1ss) -- return; -- -- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); - - if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { -- if (0 == (lval & 0x0F)) -- rtsx_pci_enable_oobs_polling(pcr); -- else -+ if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -+ | PM_L1_1_EN | PM_L1_2_EN)) - rtsx_pci_disable_oobs_polling(pcr); -+ else -+ rtsx_pci_enable_oobs_polling(pcr); - } - -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) -- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) -- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) -- rtsx_set_dev_flag(pcr, PM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) -- rtsx_set_dev_flag(pcr, PM_L1_2_EN); -- - if (option->ltr_en) { -- u16 val; -- -- pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); -- if (val & PCI_EXP_DEVCTL2_LTR_EN) { -- option->ltr_enabled = true; -- option->ltr_active = true; -+ if (option->ltr_enabled) - rtsx_set_ltr_latency(pcr, option->ltr_active_latency); -- } else { -- option->ltr_enabled = false; -- } - } - } - --static int rts5249_init_from_hw(struct rtsx_pcr *pcr) --{ -- struct rtsx_cr_option *option = &(pcr->option); -- -- if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -- | PM_L1_1_EN | PM_L1_2_EN)) -- option->force_clkreq_0 = false; -- else -- option->force_clkreq_0 = true; -- -- return 0; --} -- - static void rts52xa_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime) - { - /* Set relink_time to 0 */ -@@ -276,7 +234,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) - struct rtsx_cr_option *option = &(pcr->option); - - rts5249_init_from_cfg(pcr); -- rts5249_init_from_hw(pcr); - - rtsx_pci_init_cmd(pcr); - -@@ -327,11 +284,12 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) - } - } - -+ - /* - * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced - * to drive low, and we forcibly request clock. - */ -- if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) -+ if (option->force_clkreq_0) - rtsx_pci_write_register(pcr, PETXCFG, - FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); - else -diff --git a/drivers/misc/cardreader/rts5260.c b/drivers/misc/cardreader/rts5260.c -index 79b18f6f73a8a..d2d3a6ccb8f7d 100644 ---- a/drivers/misc/cardreader/rts5260.c -+++ b/drivers/misc/cardreader/rts5260.c -@@ -480,47 +480,19 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr) - - static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) - { -- struct pci_dev *pdev = pcr->pci; -- int l1ss; - struct rtsx_cr_option *option = &pcr->option; -- u32 lval; -- -- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); -- if (!l1ss) -- return; -- -- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) -- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) -- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) -- rtsx_set_dev_flag(pcr, PM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) -- rtsx_set_dev_flag(pcr, PM_L1_2_EN); - - rts5260_pwr_saving_setting(pcr); - - if (option->ltr_en) { -- u16 val; -- -- pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); -- if (val & PCI_EXP_DEVCTL2_LTR_EN) { -- option->ltr_enabled = true; -- option->ltr_active = true; -+ if (option->ltr_enabled) - rtsx_set_ltr_latency(pcr, option->ltr_active_latency); -- } else { -- option->ltr_enabled = false; -- } - } - } - - static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) - { -+ struct rtsx_cr_option *option = &pcr->option; - - /* Set mcu_cnt to 7 to ensure data can be sampled properly */ - rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); -@@ -539,6 +511,17 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) - - rts5260_init_hw(pcr); - -+ /* -+ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -+ * to drive low, and we forcibly request clock. -+ */ -+ if (option->force_clkreq_0) -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -+ else -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -+ - rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); - - return 0; -diff --git a/drivers/misc/cardreader/rts5261.c b/drivers/misc/cardreader/rts5261.c -index 94af6bf8a25a6..67252512a1329 100644 ---- a/drivers/misc/cardreader/rts5261.c -+++ b/drivers/misc/cardreader/rts5261.c -@@ -454,54 +454,17 @@ static void rts5261_init_from_hw(struct rtsx_pcr *pcr) - - static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) - { -- struct pci_dev *pdev = pcr->pci; -- int l1ss; -- u32 lval; - struct rtsx_cr_option *option = &pcr->option; - -- l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); -- if (!l1ss) -- return; -- -- pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_1) -- rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); -- else -- rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_ASPM_L1_2) -- rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); -- else -- rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) -- rtsx_set_dev_flag(pcr, PM_L1_1_EN); -- else -- rtsx_clear_dev_flag(pcr, PM_L1_1_EN); -- -- if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) -- rtsx_set_dev_flag(pcr, PM_L1_2_EN); -- else -- rtsx_clear_dev_flag(pcr, PM_L1_2_EN); -- -- rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); - if (option->ltr_en) { -- u16 val; -- -- pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); -- if (val & PCI_EXP_DEVCTL2_LTR_EN) { -- option->ltr_enabled = true; -- option->ltr_active = true; -+ if (option->ltr_enabled) - rtsx_set_ltr_latency(pcr, option->ltr_active_latency); -- } else { -- option->ltr_enabled = false; -- } - } - } - - static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) - { -+ struct rtsx_cr_option *option = &pcr->option; - u32 val; - - rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, -@@ -547,6 +510,17 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) - else - rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); - -+ /* -+ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -+ * to drive low, and we forcibly request clock. -+ */ -+ if (option->force_clkreq_0) -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -+ else -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -+ - rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); - - if (pcr->rtd3_en) { -diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c -index a3f4b52bb159f..a30751ad37330 100644 ---- a/drivers/misc/cardreader/rtsx_pcr.c -+++ b/drivers/misc/cardreader/rtsx_pcr.c -@@ -1326,11 +1326,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) - return err; - } - -- if (pcr->aspm_mode == ASPM_MODE_REG) { -+ if (pcr->aspm_mode == ASPM_MODE_REG) - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); -- rtsx_pci_write_register(pcr, PETXCFG, -- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -- } - - /* No CD interrupt if probing driver with card inserted. - * So we need to initialize pcr->card_exist here. -@@ -1345,7 +1342,9 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) - - static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) - { -- int err; -+ struct rtsx_cr_option *option = &(pcr->option); -+ int err, l1ss; -+ u32 lval; - u16 cfg_val; - u8 val; - -@@ -1430,6 +1429,48 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) - pcr->aspm_enabled = true; - } - -+ l1ss = pci_find_ext_capability(pcr->pci, PCI_EXT_CAP_ID_L1SS); -+ if (l1ss) { -+ pci_read_config_dword(pcr->pci, l1ss + PCI_L1SS_CTL1, &lval); -+ -+ if (lval & PCI_L1SS_CTL1_ASPM_L1_1) -+ rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); -+ else -+ rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); -+ -+ if (lval & PCI_L1SS_CTL1_ASPM_L1_2) -+ rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); -+ else -+ rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); -+ -+ if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) -+ rtsx_set_dev_flag(pcr, PM_L1_1_EN); -+ else -+ rtsx_clear_dev_flag(pcr, PM_L1_1_EN); -+ -+ if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) -+ rtsx_set_dev_flag(pcr, PM_L1_2_EN); -+ else -+ rtsx_clear_dev_flag(pcr, PM_L1_2_EN); -+ -+ pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cfg_val); -+ if (cfg_val & PCI_EXP_DEVCTL2_LTR_EN) { -+ option->ltr_enabled = true; -+ option->ltr_active = true; -+ } else { -+ option->ltr_enabled = false; -+ } -+ -+ if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN -+ | PM_L1_1_EN | PM_L1_2_EN)) -+ option->force_clkreq_0 = false; -+ else -+ option->force_clkreq_0 = true; -+ } else { -+ option->ltr_enabled = false; -+ option->force_clkreq_0 = true; -+ } -+ - if (pcr->ops->fetch_vendor_settings) - pcr->ops->fetch_vendor_settings(pcr); - -diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c -index 5ce01ac72637e..42a66b74c1e5b 100644 ---- a/drivers/net/ethernet/amazon/ena/ena_netdev.c -+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c -@@ -1778,6 +1778,9 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, - return work_done; - - error: -+ if (xdp_flags & ENA_XDP_REDIRECT) -+ xdp_do_flush(); -+ - adapter = netdev_priv(rx_ring->netdev); - - if (rc == -ENOSPC) { -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -index 969db3c45d176..e81cb825dff4c 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -@@ -2654,6 +2654,7 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) - struct rx_cmp_ext *rxcmp1; - u32 cp_cons, tmp_raw_cons; - u32 raw_cons = cpr->cp_raw_cons; -+ bool flush_xdp = false; - u32 rx_pkts = 0; - u8 event = 0; - -@@ -2688,6 +2689,8 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) - rx_pkts++; - else if (rc == -EBUSY) /* partial completion */ - break; -+ if (event & BNXT_REDIRECT_EVENT) -+ flush_xdp = true; - } else if (unlikely(TX_CMP_TYPE(txcmp) == - CMPL_BASE_TYPE_HWRM_DONE)) { - bnxt_hwrm_handler(bp, txcmp); -@@ -2707,6 +2710,8 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) - - if (event & BNXT_AGG_EVENT) - bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); -+ if (flush_xdp) -+ xdp_do_flush(); - - if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) { - napi_complete_done(napi, rx_pkts); -diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c -index 6bf3cc11d2121..2be518db04270 100644 ---- a/drivers/net/ethernet/engleder/tsnep_main.c -+++ b/drivers/net/ethernet/engleder/tsnep_main.c -@@ -65,8 +65,11 @@ static irqreturn_t tsnep_irq(int irq, void *arg) - - /* handle TX/RX queue 0 interrupt */ - if ((active & adapter->queue[0].irq_mask) != 0) { -- tsnep_disable_irq(adapter, adapter->queue[0].irq_mask); -- napi_schedule(&adapter->queue[0].napi); -+ if (napi_schedule_prep(&adapter->queue[0].napi)) { -+ tsnep_disable_irq(adapter, adapter->queue[0].irq_mask); -+ /* schedule after masking to avoid races */ -+ __napi_schedule(&adapter->queue[0].napi); -+ } - } - - return IRQ_HANDLED; -@@ -77,8 +80,11 @@ static irqreturn_t tsnep_irq_txrx(int irq, void *arg) - struct tsnep_queue *queue = arg; - - /* handle TX/RX queue interrupt */ -- tsnep_disable_irq(queue->adapter, queue->irq_mask); -- napi_schedule(&queue->napi); -+ if (napi_schedule_prep(&queue->napi)) { -+ tsnep_disable_irq(queue->adapter, queue->irq_mask); -+ /* schedule after masking to avoid races */ -+ __napi_schedule(&queue->napi); -+ } - - return IRQ_HANDLED; - } -@@ -924,6 +930,10 @@ static int tsnep_poll(struct napi_struct *napi, int budget) - if (queue->tx) - complete = tsnep_tx_poll(queue->tx, budget); - -+ /* handle case where we are called by netpoll with a budget of 0 */ -+ if (unlikely(budget <= 0)) -+ return budget; -+ - if (queue->rx) { - done = tsnep_rx_poll(queue->rx, napi, budget); - if (done >= budget) -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -index 8aae179554a81..04c9baca1b0f8 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -@@ -3352,6 +3352,15 @@ static void hns3_set_default_feature(struct net_device *netdev) - NETIF_F_HW_TC); - - netdev->hw_enc_features |= netdev->vlan_features | NETIF_F_TSO_MANGLEID; -+ -+ /* The device_version V3 hardware can't offload the checksum for IP in -+ * GRE packets, but can do it for NvGRE. So default to disable the -+ * checksum and GSO offload for GRE. -+ */ -+ if (ae_dev->dev_version > HNAE3_DEVICE_VERSION_V2) { -+ netdev->features &= ~NETIF_F_GSO_GRE; -+ netdev->features &= ~NETIF_F_GSO_GRE_CSUM; -+ } - } - - static int hns3_alloc_buffer(struct hns3_enet_ring *ring, -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -index 884e45fb6b72e..3e1d202d60ce1 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -@@ -3662,9 +3662,14 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) - static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, - u32 regclr) - { -+#define HCLGE_IMP_RESET_DELAY 5 -+ - switch (event_type) { - case HCLGE_VECTOR0_EVENT_PTP: - case HCLGE_VECTOR0_EVENT_RST: -+ if (regclr == BIT(HCLGE_VECTOR0_IMPRESET_INT_B)) -+ mdelay(HCLGE_IMP_RESET_DELAY); -+ - hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); - break; - case HCLGE_VECTOR0_EVENT_MBX: -@@ -7454,6 +7459,12 @@ static int hclge_del_cls_flower(struct hnae3_handle *handle, - ret = hclge_fd_tcam_config(hdev, HCLGE_FD_STAGE_1, true, rule->location, - NULL, false); - if (ret) { -+ /* if tcam config fail, set rule state to TO_DEL, -+ * so the rule will be deleted when periodic -+ * task being scheduled. -+ */ -+ hclge_update_fd_list(hdev, HCLGE_FD_TO_DEL, rule->location, NULL); -+ set_bit(HCLGE_STATE_FD_TBL_CHANGED, &hdev->state); - spin_unlock_bh(&hdev->fd_rule_lock); - return ret; - } -@@ -8930,7 +8941,7 @@ static void hclge_update_overflow_flags(struct hclge_vport *vport, - if (mac_type == HCLGE_MAC_ADDR_UC) { - if (is_all_added) - vport->overflow_promisc_flags &= ~HNAE3_OVERFLOW_UPE; -- else -+ else if (hclge_is_umv_space_full(vport, true)) - vport->overflow_promisc_flags |= HNAE3_OVERFLOW_UPE; - } else { - if (is_all_added) -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c -index b1b14850e958f..72cf5145e15a2 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c -@@ -1909,7 +1909,8 @@ static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev) - unsigned long delta = round_jiffies_relative(HZ); - struct hnae3_handle *handle = &hdev->nic; - -- if (test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) -+ if (test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state) || -+ test_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state)) - return; - - if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) { -diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -index cb7cf672f6971..547e67d9470b7 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -@@ -4397,9 +4397,7 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, - goto error_pvid; - - i40e_vlan_stripping_enable(vsi); -- i40e_vc_reset_vf(vf, true); -- /* During reset the VF got a new VSI, so refresh a pointer. */ -- vsi = pf->vsi[vf->lan_vsi_idx]; -+ - /* Locked once because multiple functions below iterate list */ - spin_lock_bh(&vsi->mac_filter_hash_lock); - -@@ -4485,6 +4483,10 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, - */ - vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); - -+ i40e_vc_reset_vf(vf, true); -+ /* During reset the VF got a new VSI, so refresh a pointer. */ -+ vsi = pf->vsi[vf->lan_vsi_idx]; -+ - ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni); - if (ret) { - dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n"); -diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h -index 543931c06bb17..06cfd567866c2 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf.h -+++ b/drivers/net/ethernet/intel/iavf/iavf.h -@@ -521,7 +521,7 @@ void iavf_down(struct iavf_adapter *adapter); - int iavf_process_config(struct iavf_adapter *adapter); - int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter); - void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags); --void iavf_schedule_request_stats(struct iavf_adapter *adapter); -+void iavf_schedule_aq_request(struct iavf_adapter *adapter, u64 flags); - void iavf_schedule_finish_config(struct iavf_adapter *adapter); - void iavf_reset(struct iavf_adapter *adapter); - void iavf_set_ethtool_ops(struct net_device *netdev); -diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -index fe912b1c468ef..c13b4fa659ee9 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -@@ -362,7 +362,7 @@ static void iavf_get_ethtool_stats(struct net_device *netdev, - unsigned int i; - - /* Explicitly request stats refresh */ -- iavf_schedule_request_stats(adapter); -+ iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_REQUEST_STATS); - - iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats); - -diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c -index 22bc57ee24228..a39f7f0d6ab0b 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_main.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c -@@ -322,15 +322,13 @@ void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags) - } - - /** -- * iavf_schedule_request_stats - Set the flags and schedule statistics request -+ * iavf_schedule_aq_request - Set the flags and schedule aq request - * @adapter: board private structure -- * -- * Sets IAVF_FLAG_AQ_REQUEST_STATS flag so iavf_watchdog_task() will explicitly -- * request and refresh ethtool stats -+ * @flags: requested aq flags - **/ --void iavf_schedule_request_stats(struct iavf_adapter *adapter) -+void iavf_schedule_aq_request(struct iavf_adapter *adapter, u64 flags) - { -- adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_STATS; -+ adapter->aq_required |= flags; - mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); - } - -@@ -831,7 +829,7 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter, - list_add_tail(&f->list, &adapter->vlan_filter_list); - f->state = IAVF_VLAN_ADD; - adapter->num_vlan_filters++; -- adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER; -+ iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_ADD_VLAN_FILTER); - } - - clearout: -@@ -853,7 +851,7 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan) - f = iavf_find_vlan(adapter, vlan); - if (f) { - f->state = IAVF_VLAN_REMOVE; -- adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER; -+ iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_DEL_VLAN_FILTER); - } - - spin_unlock_bh(&adapter->mac_vlan_list_lock); -@@ -1433,7 +1431,8 @@ void iavf_down(struct iavf_adapter *adapter) - iavf_clear_fdir_filters(adapter); - iavf_clear_adv_rss_conf(adapter); - -- if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) { -+ if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) && -+ !(test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))) { - /* cancel any current operation */ - adapter->current_op = VIRTCHNL_OP_UNKNOWN; - /* Schedule operations to close down the HW. Don't wait -diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c -index 511fc3f412087..9166fde40c772 100644 ---- a/drivers/net/ethernet/intel/igc/igc_ethtool.c -+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c -@@ -867,6 +867,18 @@ static void igc_ethtool_get_stats(struct net_device *netdev, - spin_unlock(&adapter->stats64_lock); - } - -+static int igc_ethtool_get_previous_rx_coalesce(struct igc_adapter *adapter) -+{ -+ return (adapter->rx_itr_setting <= 3) ? -+ adapter->rx_itr_setting : adapter->rx_itr_setting >> 2; -+} -+ -+static int igc_ethtool_get_previous_tx_coalesce(struct igc_adapter *adapter) -+{ -+ return (adapter->tx_itr_setting <= 3) ? -+ adapter->tx_itr_setting : adapter->tx_itr_setting >> 2; -+} -+ - static int igc_ethtool_get_coalesce(struct net_device *netdev, - struct ethtool_coalesce *ec, - struct kernel_ethtool_coalesce *kernel_coal, -@@ -874,17 +886,8 @@ static int igc_ethtool_get_coalesce(struct net_device *netdev, - { - struct igc_adapter *adapter = netdev_priv(netdev); - -- if (adapter->rx_itr_setting <= 3) -- ec->rx_coalesce_usecs = adapter->rx_itr_setting; -- else -- ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2; -- -- if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS)) { -- if (adapter->tx_itr_setting <= 3) -- ec->tx_coalesce_usecs = adapter->tx_itr_setting; -- else -- ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2; -- } -+ ec->rx_coalesce_usecs = igc_ethtool_get_previous_rx_coalesce(adapter); -+ ec->tx_coalesce_usecs = igc_ethtool_get_previous_tx_coalesce(adapter); - - return 0; - } -@@ -909,8 +912,12 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev, - ec->tx_coalesce_usecs == 2) - return -EINVAL; - -- if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs) -+ if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && -+ ec->tx_coalesce_usecs != igc_ethtool_get_previous_tx_coalesce(adapter)) { -+ NL_SET_ERR_MSG_MOD(extack, -+ "Queue Pair mode enabled, both Rx and Tx coalescing controlled by rx-usecs"); - return -EINVAL; -+ } - - /* If ITR is disabled, disable DMAC */ - if (ec->rx_coalesce_usecs == 0) { -diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c -index 2f3947cf513bd..1ac836a55cd31 100644 ---- a/drivers/net/ethernet/intel/igc/igc_main.c -+++ b/drivers/net/ethernet/intel/igc/igc_main.c -@@ -6322,7 +6322,7 @@ static int igc_xdp_xmit(struct net_device *dev, int num_frames, - struct igc_ring *ring; - int i, drops; - -- if (unlikely(test_bit(__IGC_DOWN, &adapter->state))) -+ if (unlikely(!netif_carrier_ok(dev))) - return -ENETDOWN; - - if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) -diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -index d4ec46d1c8cfb..61354f7985035 100644 ---- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -@@ -726,13 +726,13 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb, - dma_map_sg_err: - if (si > 0) { - dma_unmap_single(iq->dev, sglist[0].dma_ptr[0], -- sglist[0].len[0], DMA_TO_DEVICE); -- sglist[0].len[0] = 0; -+ sglist[0].len[3], DMA_TO_DEVICE); -+ sglist[0].len[3] = 0; - } - while (si > 1) { - dma_unmap_page(iq->dev, sglist[si >> 2].dma_ptr[si & 3], -- sglist[si >> 2].len[si & 3], DMA_TO_DEVICE); -- sglist[si >> 2].len[si & 3] = 0; -+ sglist[si >> 2].len[3 - (si & 3)], DMA_TO_DEVICE); -+ sglist[si >> 2].len[3 - (si & 3)] = 0; - si--; - } - tx_buffer->gather = 0; -diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c -index 5a520d37bea02..d0adb82d65c31 100644 ---- a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c -+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c -@@ -69,12 +69,12 @@ int octep_iq_process_completions(struct octep_iq *iq, u16 budget) - compl_sg++; - - dma_unmap_single(iq->dev, tx_buffer->sglist[0].dma_ptr[0], -- tx_buffer->sglist[0].len[0], DMA_TO_DEVICE); -+ tx_buffer->sglist[0].len[3], DMA_TO_DEVICE); - - i = 1; /* entry 0 is main skb, unmapped above */ - while (frags--) { - dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3], -- tx_buffer->sglist[i >> 2].len[i & 3], DMA_TO_DEVICE); -+ tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE); - i++; - } - -@@ -131,13 +131,13 @@ static void octep_iq_free_pending(struct octep_iq *iq) - - dma_unmap_single(iq->dev, - tx_buffer->sglist[0].dma_ptr[0], -- tx_buffer->sglist[0].len[0], -+ tx_buffer->sglist[0].len[3], - DMA_TO_DEVICE); - - i = 1; /* entry 0 is main skb, unmapped above */ - while (frags--) { - dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3], -- tx_buffer->sglist[i >> 2].len[i & 3], DMA_TO_DEVICE); -+ tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE); - i++; - } - -diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h -index 2ef57980eb47b..21e75ff9f5e71 100644 ---- a/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h -+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h -@@ -17,7 +17,21 @@ - #define TX_BUFTYPE_NET_SG 2 - #define NUM_TX_BUFTYPES 3 - --/* Hardware format for Scatter/Gather list */ -+/* Hardware format for Scatter/Gather list -+ * -+ * 63 48|47 32|31 16|15 0 -+ * ----------------------------------------- -+ * | Len 0 | Len 1 | Len 2 | Len 3 | -+ * ----------------------------------------- -+ * | Ptr 0 | -+ * ----------------------------------------- -+ * | Ptr 1 | -+ * ----------------------------------------- -+ * | Ptr 2 | -+ * ----------------------------------------- -+ * | Ptr 3 | -+ * ----------------------------------------- -+ */ - struct octep_tx_sglist_desc { - u16 len[4]; - dma_addr_t dma_ptr[4]; -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -index 7af223b0a37f5..5704fb75fa477 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -@@ -29,7 +29,8 @@ - static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, - struct bpf_prog *prog, - struct nix_cqe_rx_s *cqe, -- struct otx2_cq_queue *cq); -+ struct otx2_cq_queue *cq, -+ bool *need_xdp_flush); - - static int otx2_nix_cq_op_status(struct otx2_nic *pfvf, - struct otx2_cq_queue *cq) -@@ -340,7 +341,7 @@ static bool otx2_check_rcv_errors(struct otx2_nic *pfvf, - static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf, - struct napi_struct *napi, - struct otx2_cq_queue *cq, -- struct nix_cqe_rx_s *cqe) -+ struct nix_cqe_rx_s *cqe, bool *need_xdp_flush) - { - struct nix_rx_parse_s *parse = &cqe->parse; - struct nix_rx_sg_s *sg = &cqe->sg; -@@ -356,7 +357,7 @@ static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf, - } - - if (pfvf->xdp_prog) -- if (otx2_xdp_rcv_pkt_handler(pfvf, pfvf->xdp_prog, cqe, cq)) -+ if (otx2_xdp_rcv_pkt_handler(pfvf, pfvf->xdp_prog, cqe, cq, need_xdp_flush)) - return; - - skb = napi_get_frags(napi); -@@ -389,6 +390,7 @@ static int otx2_rx_napi_handler(struct otx2_nic *pfvf, - struct napi_struct *napi, - struct otx2_cq_queue *cq, int budget) - { -+ bool need_xdp_flush = false; - struct nix_cqe_rx_s *cqe; - int processed_cqe = 0; - -@@ -410,13 +412,15 @@ process_cqe: - cq->cq_head++; - cq->cq_head &= (cq->cqe_cnt - 1); - -- otx2_rcv_pkt_handler(pfvf, napi, cq, cqe); -+ otx2_rcv_pkt_handler(pfvf, napi, cq, cqe, &need_xdp_flush); - - cqe->hdr.cqe_type = NIX_XQE_TYPE_INVALID; - cqe->sg.seg_addr = 0x00; - processed_cqe++; - cq->pend_cqe--; - } -+ if (need_xdp_flush) -+ xdp_do_flush(); - - /* Free CQEs to HW */ - otx2_write64(pfvf, NIX_LF_CQ_OP_DOOR, -@@ -1323,7 +1327,8 @@ bool otx2_xdp_sq_append_pkt(struct otx2_nic *pfvf, u64 iova, int len, u16 qidx) - static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, - struct bpf_prog *prog, - struct nix_cqe_rx_s *cqe, -- struct otx2_cq_queue *cq) -+ struct otx2_cq_queue *cq, -+ bool *need_xdp_flush) - { - unsigned char *hard_start, *data; - int qidx = cq->cq_idx; -@@ -1360,8 +1365,10 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, - - otx2_dma_unmap_page(pfvf, iova, pfvf->rbsize, - DMA_FROM_DEVICE); -- if (!err) -+ if (!err) { -+ *need_xdp_flush = true; - return true; -+ } - put_page(page); - break; - default: -diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h -index ad8a2a4453b76..93a4258421667 100644 ---- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h -+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h -@@ -180,6 +180,7 @@ typedef void (*ionic_desc_cb)(struct ionic_queue *q, - struct ionic_desc_info *desc_info, - struct ionic_cq_info *cq_info, void *cb_arg); - -+#define IONIC_MAX_BUF_LEN ((u16)-1) - #define IONIC_PAGE_SIZE PAGE_SIZE - #define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2) - #define IONIC_PAGE_GFP_MASK (GFP_ATOMIC | __GFP_NOWARN |\ -diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c -index f8f5eb1307681..4684b9f194a68 100644 ---- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c -+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c -@@ -207,7 +207,8 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q, - return NULL; - } - -- frag_len = min_t(u16, len, IONIC_PAGE_SIZE - buf_info->page_offset); -+ frag_len = min_t(u16, len, min_t(u32, IONIC_MAX_BUF_LEN, -+ IONIC_PAGE_SIZE - buf_info->page_offset)); - len -= frag_len; - - dma_sync_single_for_cpu(dev, -@@ -444,7 +445,8 @@ void ionic_rx_fill(struct ionic_queue *q) - - /* fill main descriptor - buf[0] */ - desc->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); -- frag_len = min_t(u16, len, IONIC_PAGE_SIZE - buf_info->page_offset); -+ frag_len = min_t(u16, len, min_t(u32, IONIC_MAX_BUF_LEN, -+ IONIC_PAGE_SIZE - buf_info->page_offset)); - desc->len = cpu_to_le16(frag_len); - remain_len -= frag_len; - buf_info++; -@@ -463,7 +465,9 @@ void ionic_rx_fill(struct ionic_queue *q) - } - - sg_elem->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); -- frag_len = min_t(u16, remain_len, IONIC_PAGE_SIZE - buf_info->page_offset); -+ frag_len = min_t(u16, remain_len, min_t(u32, IONIC_MAX_BUF_LEN, -+ IONIC_PAGE_SIZE - -+ buf_info->page_offset)); - sg_elem->len = cpu_to_le16(frag_len); - remain_len -= frag_len; - buf_info++; -diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c -index 921ca59822b0f..556b2d1cd2aca 100644 ---- a/drivers/net/team/team.c -+++ b/drivers/net/team/team.c -@@ -2127,7 +2127,12 @@ static const struct ethtool_ops team_ethtool_ops = { - static void team_setup_by_port(struct net_device *dev, - struct net_device *port_dev) - { -- dev->header_ops = port_dev->header_ops; -+ struct team *team = netdev_priv(dev); -+ -+ if (port_dev->type == ARPHRD_ETHER) -+ dev->header_ops = team->header_ops_cache; -+ else -+ dev->header_ops = port_dev->header_ops; - dev->type = port_dev->type; - dev->hard_header_len = port_dev->hard_header_len; - dev->needed_headroom = port_dev->needed_headroom; -@@ -2174,8 +2179,11 @@ static int team_dev_type_check_change(struct net_device *dev, - - static void team_setup(struct net_device *dev) - { -+ struct team *team = netdev_priv(dev); -+ - ether_setup(dev); - dev->max_mtu = ETH_MAX_MTU; -+ team->header_ops_cache = dev->header_ops; - - dev->netdev_ops = &team_netdev_ops; - dev->ethtool_ops = &team_ethtool_ops; -diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c -index 6312f67f260e0..5966e36875def 100644 ---- a/drivers/net/thunderbolt.c -+++ b/drivers/net/thunderbolt.c -@@ -1005,12 +1005,11 @@ static bool tbnet_xmit_csum_and_map(struct tbnet *net, struct sk_buff *skb, - *tucso = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, - ip_hdr(skb)->daddr, 0, - ip_hdr(skb)->protocol, 0); -- } else if (skb_is_gso_v6(skb)) { -+ } else if (skb_is_gso(skb) && skb_is_gso_v6(skb)) { - tucso = dest + ((void *)&(tcp_hdr(skb)->check) - data); - *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, 0, - IPPROTO_TCP, 0); -- return false; - } else if (protocol == htons(ETH_P_IPV6)) { - tucso = dest + skb_checksum_start_offset(skb) + skb->csum_offset; - *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, -diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h -index be9eafc872b3b..232fd2e638bf6 100644 ---- a/drivers/net/wireless/ath/ath11k/dp.h -+++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -303,12 +303,16 @@ struct ath11k_dp { - - #define HTT_TX_WBM_COMP_STATUS_OFFSET 8 - -+#define HTT_INVALID_PEER_ID 0xffff -+ - /* HTT tx completion is overlaid in wbm_release_ring */ - #define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(12, 9) - #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13) - #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13) - - #define HTT_TX_WBM_COMP_INFO1_ACK_RSSI GENMASK(31, 24) -+#define HTT_TX_WBM_COMP_INFO2_SW_PEER_ID GENMASK(15, 0) -+#define HTT_TX_WBM_COMP_INFO2_VALID BIT(21) - - struct htt_tx_wbm_completion { - u32 info0; -diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c -index 8afbba2369354..cd24488612454 100644 ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -316,10 +316,12 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab, - struct dp_tx_ring *tx_ring, - struct ath11k_dp_htt_wbm_tx_status *ts) - { -+ struct ieee80211_tx_status status = { 0 }; - struct sk_buff *msdu; - struct ieee80211_tx_info *info; - struct ath11k_skb_cb *skb_cb; - struct ath11k *ar; -+ struct ath11k_peer *peer; - - spin_lock(&tx_ring->tx_idr_lock); - msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); -@@ -341,6 +343,11 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab, - - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); - -+ if (!skb_cb->vif) { -+ ieee80211_free_txskb(ar->hw, msdu); -+ return; -+ } -+ - memset(&info->status, 0, sizeof(info->status)); - - if (ts->acked) { -@@ -355,7 +362,23 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab, - } - } - -- ieee80211_tx_status(ar->hw, msdu); -+ spin_lock_bh(&ab->base_lock); -+ peer = ath11k_peer_find_by_id(ab, ts->peer_id); -+ if (!peer || !peer->sta) { -+ ath11k_dbg(ab, ATH11K_DBG_DATA, -+ "dp_tx: failed to find the peer with peer_id %d\n", -+ ts->peer_id); -+ spin_unlock_bh(&ab->base_lock); -+ ieee80211_free_txskb(ar->hw, msdu); -+ return; -+ } -+ spin_unlock_bh(&ab->base_lock); -+ -+ status.sta = peer->sta; -+ status.info = info; -+ status.skb = msdu; -+ -+ ieee80211_tx_status_ext(ar->hw, &status); - } - - static void -@@ -379,7 +402,15 @@ ath11k_dp_tx_process_htt_tx_complete(struct ath11k_base *ab, - ts.msdu_id = msdu_id; - ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI, - status_desc->info1); -+ -+ if (FIELD_GET(HTT_TX_WBM_COMP_INFO2_VALID, status_desc->info2)) -+ ts.peer_id = FIELD_GET(HTT_TX_WBM_COMP_INFO2_SW_PEER_ID, -+ status_desc->info2); -+ else -+ ts.peer_id = HTT_INVALID_PEER_ID; -+ - ath11k_dp_tx_htt_tx_complete_buf(ab, tx_ring, &ts); -+ - break; - case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: - case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: -@@ -535,12 +566,12 @@ static void ath11k_dp_tx_complete_msdu(struct ath11k *ar, - dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); - - if (unlikely(!rcu_access_pointer(ab->pdevs_active[ar->pdev_idx]))) { -- dev_kfree_skb_any(msdu); -+ ieee80211_free_txskb(ar->hw, msdu); - return; - } - - if (unlikely(!skb_cb->vif)) { -- dev_kfree_skb_any(msdu); -+ ieee80211_free_txskb(ar->hw, msdu); - return; - } - -@@ -593,7 +624,7 @@ static void ath11k_dp_tx_complete_msdu(struct ath11k *ar, - "dp_tx: failed to find the peer with peer_id %d\n", - ts->peer_id); - spin_unlock_bh(&ab->base_lock); -- dev_kfree_skb_any(msdu); -+ ieee80211_free_txskb(ar->hw, msdu); - return; - } - arsta = (struct ath11k_sta *)peer->sta->drv_priv; -diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h -index e87d65bfbf06e..68a21ea9b9346 100644 ---- a/drivers/net/wireless/ath/ath11k/dp_tx.h -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h -@@ -13,6 +13,7 @@ struct ath11k_dp_htt_wbm_tx_status { - u32 msdu_id; - bool acked; - int ack_rssi; -+ u16 peer_id; - }; - - void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts); -diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c -index 6c3d469eed7e3..177a365b8ec55 100644 ---- a/drivers/nvme/host/fc.c -+++ b/drivers/nvme/host/fc.c -@@ -1911,7 +1911,7 @@ char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req) - struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req); - struct request *rq = op->rq; - -- if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq->bio) -+ if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq || !rq->bio) - return NULL; - return blkcg_get_fc_appid(rq->bio); - } -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index b30269f5e68fb..64990a2cfd0a7 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -392,14 +392,6 @@ static int nvme_pci_npages_sgl(void) - NVME_CTRL_PAGE_SIZE); - } - --static size_t nvme_pci_iod_alloc_size(void) --{ -- size_t npages = max(nvme_pci_npages_prp(), nvme_pci_npages_sgl()); -- -- return sizeof(__le64 *) * npages + -- sizeof(struct scatterlist) * NVME_MAX_SEGS; --} -- - static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, - unsigned int hctx_idx) - { -@@ -2775,6 +2767,22 @@ static void nvme_release_prp_pools(struct nvme_dev *dev) - dma_pool_destroy(dev->prp_small_pool); - } - -+static int nvme_pci_alloc_iod_mempool(struct nvme_dev *dev) -+{ -+ size_t npages = max(nvme_pci_npages_prp(), nvme_pci_npages_sgl()); -+ size_t alloc_size = sizeof(__le64 *) * npages + -+ sizeof(struct scatterlist) * NVME_MAX_SEGS; -+ -+ WARN_ON_ONCE(alloc_size > PAGE_SIZE); -+ dev->iod_mempool = mempool_create_node(1, -+ mempool_kmalloc, mempool_kfree, -+ (void *)alloc_size, GFP_KERNEL, -+ dev_to_node(dev->dev)); -+ if (!dev->iod_mempool) -+ return -ENOMEM; -+ return 0; -+} -+ - static void nvme_free_tagset(struct nvme_dev *dev) - { - if (dev->tagset.tags) -@@ -2782,6 +2790,7 @@ static void nvme_free_tagset(struct nvme_dev *dev) - dev->ctrl.tagset = NULL; - } - -+/* pairs with nvme_pci_alloc_dev */ - static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl) - { - struct nvme_dev *dev = to_nvme_dev(ctrl); -@@ -3098,20 +3107,20 @@ static void nvme_async_probe(void *data, async_cookie_t cookie) - nvme_put_ctrl(&dev->ctrl); - } - --static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) -+static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, -+ const struct pci_device_id *id) - { -- int node, result = -ENOMEM; -- struct nvme_dev *dev; - unsigned long quirks = id->driver_data; -- size_t alloc_size; -- -- node = dev_to_node(&pdev->dev); -- if (node == NUMA_NO_NODE) -- set_dev_node(&pdev->dev, first_memory_node); -+ int node = dev_to_node(&pdev->dev); -+ struct nvme_dev *dev; -+ int ret = -ENOMEM; - - dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node); - if (!dev) -- return -ENOMEM; -+ return ERR_PTR(-ENOMEM); -+ INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work); -+ INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work); -+ mutex_init(&dev->shutdown_lock); - - dev->nr_write_queues = write_queues; - dev->nr_poll_queues = poll_queues; -@@ -3119,25 +3128,11 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) - dev->queues = kcalloc_node(dev->nr_allocated_queues, - sizeof(struct nvme_queue), GFP_KERNEL, node); - if (!dev->queues) -- goto free; -+ goto out_free_dev; - - dev->dev = get_device(&pdev->dev); -- pci_set_drvdata(pdev, dev); -- -- result = nvme_dev_map(dev); -- if (result) -- goto put_pci; -- -- INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work); -- INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work); -- mutex_init(&dev->shutdown_lock); -- -- result = nvme_setup_prp_pools(dev); -- if (result) -- goto unmap; - - quirks |= check_vendor_combination_bug(pdev); -- - if (!noacpi && acpi_storage_d3(&pdev->dev)) { - /* - * Some systems use a bios work around to ask for D3 on -@@ -3147,46 +3142,54 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) - "platform quirk: setting simple suspend\n"); - quirks |= NVME_QUIRK_SIMPLE_SUSPEND; - } -+ ret = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops, -+ quirks); -+ if (ret) -+ goto out_put_device; -+ return dev; - -- /* -- * Double check that our mempool alloc size will cover the biggest -- * command we support. -- */ -- alloc_size = nvme_pci_iod_alloc_size(); -- WARN_ON_ONCE(alloc_size > PAGE_SIZE); -+out_put_device: -+ put_device(dev->dev); -+ kfree(dev->queues); -+out_free_dev: -+ kfree(dev); -+ return ERR_PTR(ret); -+} - -- dev->iod_mempool = mempool_create_node(1, mempool_kmalloc, -- mempool_kfree, -- (void *) alloc_size, -- GFP_KERNEL, node); -- if (!dev->iod_mempool) { -- result = -ENOMEM; -- goto release_pools; -- } -+static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ struct nvme_dev *dev; -+ int result = -ENOMEM; -+ -+ dev = nvme_pci_alloc_dev(pdev, id); -+ if (IS_ERR(dev)) -+ return PTR_ERR(dev); -+ -+ result = nvme_dev_map(dev); -+ if (result) -+ goto out_uninit_ctrl; -+ -+ result = nvme_setup_prp_pools(dev); -+ if (result) -+ goto out_dev_unmap; - -- result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops, -- quirks); -+ result = nvme_pci_alloc_iod_mempool(dev); - if (result) -- goto release_mempool; -+ goto out_release_prp_pools; - - dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev)); -+ pci_set_drvdata(pdev, dev); - - nvme_reset_ctrl(&dev->ctrl); - async_schedule(nvme_async_probe, dev); -- - return 0; - -- release_mempool: -- mempool_destroy(dev->iod_mempool); -- release_pools: -+out_release_prp_pools: - nvme_release_prp_pools(dev); -- unmap: -+out_dev_unmap: - nvme_dev_unmap(dev); -- put_pci: -- put_device(dev->dev); -- free: -- kfree(dev->queues); -- kfree(dev); -+out_uninit_ctrl: -+ nvme_uninit_ctrl(&dev->ctrl); - return result; - } - -diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c -index bcc1dae007803..890c3c0f3d140 100644 ---- a/drivers/parisc/iosapic.c -+++ b/drivers/parisc/iosapic.c -@@ -202,9 +202,9 @@ static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 va - - static DEFINE_SPINLOCK(iosapic_lock); - --static inline void iosapic_eoi(void __iomem *addr, unsigned int data) -+static inline void iosapic_eoi(__le32 __iomem *addr, __le32 data) - { -- __raw_writel(data, addr); -+ __raw_writel((__force u32)data, addr); - } - - /* -diff --git a/drivers/parisc/iosapic_private.h b/drivers/parisc/iosapic_private.h -index 73ecc657ad954..bd8ff40162b4b 100644 ---- a/drivers/parisc/iosapic_private.h -+++ b/drivers/parisc/iosapic_private.h -@@ -118,8 +118,8 @@ struct iosapic_irt { - struct vector_info { - struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */ - struct irt_entry *irte; /* IRT entry */ -- u32 __iomem *eoi_addr; /* precalculate EOI reg address */ -- u32 eoi_data; /* IA64: ? PA: swapped txn_data */ -+ __le32 __iomem *eoi_addr; /* precalculate EOI reg address */ -+ __le32 eoi_data; /* IA64: ? PA: swapped txn_data */ - int txn_irq; /* virtual IRQ number for processor */ - ulong txn_addr; /* IA64: id_eid PA: partial HPA */ - u32 txn_data; /* CPU interrupt bit */ -diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig -index 30b50920b278c..f7dfa0e785fd6 100644 ---- a/drivers/platform/mellanox/Kconfig -+++ b/drivers/platform/mellanox/Kconfig -@@ -60,6 +60,7 @@ config MLXBF_BOOTCTL - tristate "Mellanox BlueField Firmware Boot Control driver" - depends on ARM64 - depends on ACPI -+ depends on NET - help - The Mellanox BlueField firmware implements functionality to - request swapping the primary and alternate eMMC boot partition, -diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c -index fdf7da06af306..d85d895fee894 100644 ---- a/drivers/platform/x86/asus-nb-wmi.c -+++ b/drivers/platform/x86/asus-nb-wmi.c -@@ -478,6 +478,15 @@ static const struct dmi_system_id asus_quirks[] = { - }, - .driver_data = &quirk_asus_tablet_mode, - }, -+ { -+ .callback = dmi_matched, -+ .ident = "ASUS ROG FLOW X16", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "GV601V"), -+ }, -+ .driver_data = &quirk_asus_tablet_mode, -+ }, - { - .callback = dmi_matched, - .ident = "ASUS VivoBook E410MA", -diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c -index e7a3e34028178..189c5460edd81 100644 ---- a/drivers/platform/x86/intel_scu_ipc.c -+++ b/drivers/platform/x86/intel_scu_ipc.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -232,19 +233,15 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset) - /* Wait till scu status is busy */ - static inline int busy_loop(struct intel_scu_ipc_dev *scu) - { -- unsigned long end = jiffies + IPC_TIMEOUT; -- -- do { -- u32 status; -- -- status = ipc_read_status(scu); -- if (!(status & IPC_STATUS_BUSY)) -- return (status & IPC_STATUS_ERR) ? -EIO : 0; -+ u8 status; -+ int err; - -- usleep_range(50, 100); -- } while (time_before(jiffies, end)); -+ err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY), -+ 100, jiffies_to_usecs(IPC_TIMEOUT)); -+ if (err) -+ return err; - -- return -ETIMEDOUT; -+ return (status & IPC_STATUS_ERR) ? -EIO : 0; - } - - /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */ -@@ -252,10 +249,12 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu) - { - int status; - -- if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) -- return -ETIMEDOUT; -+ wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT); - - status = ipc_read_status(scu); -+ if (status & IPC_STATUS_BUSY) -+ return -ETIMEDOUT; -+ - if (status & IPC_STATUS_ERR) - return -EIO; - -@@ -267,6 +266,24 @@ static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu) - return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu); - } - -+static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu) -+{ -+ u8 status; -+ -+ if (!scu) -+ scu = ipcdev; -+ if (!scu) -+ return ERR_PTR(-ENODEV); -+ -+ status = ipc_read_status(scu); -+ if (status & IPC_STATUS_BUSY) { -+ dev_dbg(&scu->dev, "device is busy\n"); -+ return ERR_PTR(-EBUSY); -+ } -+ -+ return scu; -+} -+ - /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ - static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, - u32 count, u32 op, u32 id) -@@ -280,11 +297,10 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, - memset(cbuf, 0, sizeof(cbuf)); - - mutex_lock(&ipclock); -- if (!scu) -- scu = ipcdev; -- if (!scu) { -+ scu = intel_scu_ipc_get(scu); -+ if (IS_ERR(scu)) { - mutex_unlock(&ipclock); -- return -ENODEV; -+ return PTR_ERR(scu); - } - - for (nc = 0; nc < count; nc++, offset += 2) { -@@ -439,13 +455,12 @@ int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd, - int err; - - mutex_lock(&ipclock); -- if (!scu) -- scu = ipcdev; -- if (!scu) { -+ scu = intel_scu_ipc_get(scu); -+ if (IS_ERR(scu)) { - mutex_unlock(&ipclock); -- return -ENODEV; -+ return PTR_ERR(scu); - } -- scu = ipcdev; -+ - cmdval = sub << 12 | cmd; - ipc_command(scu, cmdval); - err = intel_scu_ipc_check_status(scu); -@@ -485,11 +500,10 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd, - return -EINVAL; - - mutex_lock(&ipclock); -- if (!scu) -- scu = ipcdev; -- if (!scu) { -+ scu = intel_scu_ipc_get(scu); -+ if (IS_ERR(scu)) { - mutex_unlock(&ipclock); -- return -ENODEV; -+ return PTR_ERR(scu); - } - - memcpy(inbuf, in, inlen); -diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c -index 6f83e99d2eb72..ce36d6ca34226 100644 ---- a/drivers/power/supply/ab8500_btemp.c -+++ b/drivers/power/supply/ab8500_btemp.c -@@ -115,7 +115,6 @@ struct ab8500_btemp { - static enum power_supply_property ab8500_btemp_props[] = { - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_ONLINE, -- POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_TEMP, - }; - -@@ -532,12 +531,6 @@ static int ab8500_btemp_get_property(struct power_supply *psy, - else - val->intval = 1; - break; -- case POWER_SUPPLY_PROP_TECHNOLOGY: -- if (di->bm->bi) -- val->intval = di->bm->bi->technology; -- else -- val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; -- break; - case POWER_SUPPLY_PROP_TEMP: - val->intval = ab8500_btemp_get_temp(di); - break; -@@ -662,7 +655,7 @@ static char *supply_interface[] = { - - static const struct power_supply_desc ab8500_btemp_desc = { - .name = "ab8500_btemp", -- .type = POWER_SUPPLY_TYPE_BATTERY, -+ .type = POWER_SUPPLY_TYPE_UNKNOWN, - .properties = ab8500_btemp_props, - .num_properties = ARRAY_SIZE(ab8500_btemp_props), - .get_property = ab8500_btemp_get_property, -diff --git a/drivers/power/supply/ab8500_chargalg.c b/drivers/power/supply/ab8500_chargalg.c -index ea4ad61d4c7e2..2205ea0834a61 100644 ---- a/drivers/power/supply/ab8500_chargalg.c -+++ b/drivers/power/supply/ab8500_chargalg.c -@@ -1720,7 +1720,7 @@ static char *supply_interface[] = { - - static const struct power_supply_desc ab8500_chargalg_desc = { - .name = "ab8500_chargalg", -- .type = POWER_SUPPLY_TYPE_BATTERY, -+ .type = POWER_SUPPLY_TYPE_UNKNOWN, - .properties = ab8500_chargalg_props, - .num_properties = ARRAY_SIZE(ab8500_chargalg_props), - .get_property = ab8500_chargalg_get_property, -diff --git a/drivers/power/supply/mt6370-charger.c b/drivers/power/supply/mt6370-charger.c -index f27dae5043f5b..a9641bd3d8cf8 100644 ---- a/drivers/power/supply/mt6370-charger.c -+++ b/drivers/power/supply/mt6370-charger.c -@@ -324,7 +324,7 @@ static int mt6370_chg_toggle_cfo(struct mt6370_priv *priv) - - if (fl_strobe) { - dev_err(priv->dev, "Flash led is still in strobe mode\n"); -- return ret; -+ return -EINVAL; - } - - /* cfo off */ -diff --git a/drivers/power/supply/rk817_charger.c b/drivers/power/supply/rk817_charger.c -index f1b431aa0e4f2..c04b96edcf595 100644 ---- a/drivers/power/supply/rk817_charger.c -+++ b/drivers/power/supply/rk817_charger.c -@@ -1058,6 +1058,13 @@ static void rk817_charging_monitor(struct work_struct *work) - queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000)); - } - -+static void rk817_cleanup_node(void *data) -+{ -+ struct device_node *node = data; -+ -+ of_node_put(node); -+} -+ - static int rk817_charger_probe(struct platform_device *pdev) - { - struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); -@@ -1074,11 +1081,13 @@ static int rk817_charger_probe(struct platform_device *pdev) - if (!node) - return -ENODEV; - -+ ret = devm_add_action_or_reset(&pdev->dev, rk817_cleanup_node, node); -+ if (ret) -+ return ret; -+ - charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); -- if (!charger) { -- of_node_put(node); -+ if (!charger) - return -ENOMEM; -- } - - charger->rk808 = rk808; - -@@ -1224,3 +1233,4 @@ MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC"); - MODULE_AUTHOR("Maya Matuszczyk "); - MODULE_AUTHOR("Chris Morgan "); - MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:rk817-charger"); -diff --git a/drivers/power/supply/ucs1002_power.c b/drivers/power/supply/ucs1002_power.c -index ef673ec3db568..332cb50d9fb4f 100644 ---- a/drivers/power/supply/ucs1002_power.c -+++ b/drivers/power/supply/ucs1002_power.c -@@ -384,7 +384,8 @@ static int ucs1002_get_property(struct power_supply *psy, - case POWER_SUPPLY_PROP_USB_TYPE: - return ucs1002_get_usb_type(info, val); - case POWER_SUPPLY_PROP_HEALTH: -- return val->intval = info->health; -+ val->intval = info->health; -+ return 0; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = info->present; - return 0; -diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c -index 2b92ec20ed68e..df0f19e6d9235 100644 ---- a/drivers/s390/crypto/pkey_api.c -+++ b/drivers/s390/crypto/pkey_api.c -@@ -212,7 +212,8 @@ static int pkey_clr2ep11key(const u8 *clrkey, size_t clrkeylen, - card = apqns[i] >> 16; - dom = apqns[i] & 0xFFFF; - rc = ep11_clr2keyblob(card, dom, clrkeylen * 8, -- 0, clrkey, keybuf, keybuflen); -+ 0, clrkey, keybuf, keybuflen, -+ PKEY_TYPE_EP11); - if (rc == 0) - break; - } -@@ -627,6 +628,11 @@ static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns, - if (*keybufsize < MINEP11AESKEYBLOBSIZE) - return -EINVAL; - break; -+ case PKEY_TYPE_EP11_AES: -+ if (*keybufsize < (sizeof(struct ep11kblob_header) + -+ MINEP11AESKEYBLOBSIZE)) -+ return -EINVAL; -+ break; - default: - return -EINVAL; - } -@@ -645,9 +651,11 @@ static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns, - for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { - card = apqns[i].card; - dom = apqns[i].domain; -- if (ktype == PKEY_TYPE_EP11) { -+ if (ktype == PKEY_TYPE_EP11 || -+ ktype == PKEY_TYPE_EP11_AES) { - rc = ep11_clr2keyblob(card, dom, ksize, kflags, -- clrkey, keybuf, keybufsize); -+ clrkey, keybuf, keybufsize, -+ ktype); - } else if (ktype == PKEY_TYPE_CCA_DATA) { - rc = cca_clr2seckey(card, dom, ksize, - clrkey, keybuf); -@@ -1361,7 +1369,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, - apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries); - if (IS_ERR(apqns)) - return PTR_ERR(apqns); -- kkey = kmalloc(klen, GFP_KERNEL); -+ kkey = kzalloc(klen, GFP_KERNEL); - if (!kkey) { - kfree(apqns); - return -ENOMEM; -diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c -index 20bbeec1a1a22..77e1ffaafaea1 100644 ---- a/drivers/s390/crypto/zcrypt_ep11misc.c -+++ b/drivers/s390/crypto/zcrypt_ep11misc.c -@@ -1000,12 +1000,12 @@ out: - return rc; - } - --static int ep11_unwrapkey(u16 card, u16 domain, -- const u8 *kek, size_t keksize, -- const u8 *enckey, size_t enckeysize, -- u32 mech, const u8 *iv, -- u32 keybitsize, u32 keygenflags, -- u8 *keybuf, size_t *keybufsize) -+static int _ep11_unwrapkey(u16 card, u16 domain, -+ const u8 *kek, size_t keksize, -+ const u8 *enckey, size_t enckeysize, -+ u32 mech, const u8 *iv, -+ u32 keybitsize, u32 keygenflags, -+ u8 *keybuf, size_t *keybufsize) - { - struct uw_req_pl { - struct pl_head head; -@@ -1042,7 +1042,6 @@ static int ep11_unwrapkey(u16 card, u16 domain, - struct ep11_cprb *req = NULL, *rep = NULL; - struct ep11_target_dev target; - struct ep11_urb *urb = NULL; -- struct ep11keyblob *kb; - size_t req_pl_size; - int api, rc = -ENOMEM; - u8 *p; -@@ -1124,14 +1123,9 @@ static int ep11_unwrapkey(u16 card, u16 domain, - goto out; - } - -- /* copy key blob and set header values */ -+ /* copy key blob */ - memcpy(keybuf, rep_pl->data, rep_pl->data_len); - *keybufsize = rep_pl->data_len; -- kb = (struct ep11keyblob *)keybuf; -- kb->head.type = TOKTYPE_NON_CCA; -- kb->head.len = rep_pl->data_len; -- kb->head.version = TOKVER_EP11_AES; -- kb->head.bitlen = keybitsize; - - out: - kfree(req); -@@ -1140,6 +1134,42 @@ out: - return rc; - } - -+static int ep11_unwrapkey(u16 card, u16 domain, -+ const u8 *kek, size_t keksize, -+ const u8 *enckey, size_t enckeysize, -+ u32 mech, const u8 *iv, -+ u32 keybitsize, u32 keygenflags, -+ u8 *keybuf, size_t *keybufsize, -+ u8 keybufver) -+{ -+ struct ep11kblob_header *hdr; -+ size_t hdr_size, pl_size; -+ u8 *pl; -+ int rc; -+ -+ rc = ep11_kb_split(keybuf, *keybufsize, keybufver, -+ &hdr, &hdr_size, &pl, &pl_size); -+ if (rc) -+ return rc; -+ -+ rc = _ep11_unwrapkey(card, domain, kek, keksize, enckey, enckeysize, -+ mech, iv, keybitsize, keygenflags, -+ pl, &pl_size); -+ if (rc) -+ return rc; -+ -+ *keybufsize = hdr_size + pl_size; -+ -+ /* update header information */ -+ hdr = (struct ep11kblob_header *)keybuf; -+ hdr->type = TOKTYPE_NON_CCA; -+ hdr->len = *keybufsize; -+ hdr->version = keybufver; -+ hdr->bitlen = keybitsize; -+ -+ return 0; -+} -+ - static int ep11_wrapkey(u16 card, u16 domain, - const u8 *key, size_t keysize, - u32 mech, const u8 *iv, -@@ -1274,7 +1304,8 @@ out: - } - - int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, -- const u8 *clrkey, u8 *keybuf, size_t *keybufsize) -+ const u8 *clrkey, u8 *keybuf, size_t *keybufsize, -+ u32 keytype) - { - int rc; - u8 encbuf[64], *kek = NULL; -@@ -1321,7 +1352,7 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - /* Step 3: import the encrypted key value as a new key */ - rc = ep11_unwrapkey(card, domain, kek, keklen, - encbuf, encbuflen, 0, def_iv, -- keybitsize, 0, keybuf, keybufsize); -+ keybitsize, 0, keybuf, keybufsize, keytype); - if (rc) { - DEBUG_ERR( - "%s importing key value as new key failed,, rc=%d\n", -diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h -index ed328c354bade..b7f9cbe3d58de 100644 ---- a/drivers/s390/crypto/zcrypt_ep11misc.h -+++ b/drivers/s390/crypto/zcrypt_ep11misc.h -@@ -113,7 +113,8 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - * Generate EP11 AES secure key with given clear key value. - */ - int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, -- const u8 *clrkey, u8 *keybuf, size_t *keybufsize); -+ const u8 *clrkey, u8 *keybuf, size_t *keybufsize, -+ u32 keytype); - - /* - * Build a list of ep11 apqns meeting the following constrains: -diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c -index 8009eab3b7bee..56ade46309707 100644 ---- a/drivers/scsi/iscsi_tcp.c -+++ b/drivers/scsi/iscsi_tcp.c -@@ -724,6 +724,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session, - return -EEXIST; - } - -+ err = -EINVAL; -+ if (!sk_is_tcp(sock->sk)) -+ goto free_socket; -+ - err = iscsi_conn_bind(cls_session, cls_conn, is_leading); - if (err) - goto free_socket; -diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c -index 628b08ba6770b..e2c52c2d00b33 100644 ---- a/drivers/scsi/pm8001/pm8001_hwi.c -+++ b/drivers/scsi/pm8001/pm8001_hwi.c -@@ -4313,7 +4313,7 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) - payload.sas_identify.dev_type = SAS_END_DEVICE; - payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; - memcpy(payload.sas_identify.sas_addr, -- pm8001_ha->sas_addr, SAS_ADDR_SIZE); -+ &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE); - payload.sas_identify.phy_id = phy_id; - - return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload, -diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c -index f8b8624458f73..2bf293e8f7472 100644 ---- a/drivers/scsi/pm8001/pm80xx_hwi.c -+++ b/drivers/scsi/pm8001/pm80xx_hwi.c -@@ -3750,10 +3750,12 @@ static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha, - (struct set_ctrl_cfg_resp *)(piomb + 4); - u32 status = le32_to_cpu(pPayload->status); - u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd); -+ u32 tag = le32_to_cpu(pPayload->tag); - - pm8001_dbg(pm8001_ha, MSG, - "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", - status, err_qlfr_pgcd); -+ pm8001_tag_free(pm8001_ha, tag); - - return 0; - } -@@ -4803,7 +4805,7 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) - payload.sas_identify.dev_type = SAS_END_DEVICE; - payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; - memcpy(payload.sas_identify.sas_addr, -- &pm8001_ha->sas_addr, SAS_ADDR_SIZE); -+ &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE); - payload.sas_identify.phy_id = phy_id; - - return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload, -diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c -index 4750ec5789a80..10fe3383855c0 100644 ---- a/drivers/scsi/qedf/qedf_io.c -+++ b/drivers/scsi/qedf/qedf_io.c -@@ -1904,6 +1904,7 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) - goto drop_rdata_kref; - } - -+ spin_lock_irqsave(&fcport->rport_lock, flags); - if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || - test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || - test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { -@@ -1911,17 +1912,20 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) - "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n", - io_req->xid, io_req->sc_cmd); - rc = 1; -+ spin_unlock_irqrestore(&fcport->rport_lock, flags); - goto drop_rdata_kref; - } - -+ /* Set the command type to abort */ -+ io_req->cmd_type = QEDF_ABTS; -+ spin_unlock_irqrestore(&fcport->rport_lock, flags); -+ - kref_get(&io_req->refcount); - - xid = io_req->xid; - qedf->control_requests++; - qedf->packet_aborts++; - -- /* Set the command type to abort */ -- io_req->cmd_type = QEDF_ABTS; - io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; - - set_bit(QEDF_CMD_IN_ABORT, &io_req->flags); -@@ -2210,7 +2214,9 @@ process_els: - refcount, fcport, fcport->rdata->ids.port_id); - - /* Cleanup cmds re-use the same TID as the original I/O */ -+ spin_lock_irqsave(&fcport->rport_lock, flags); - io_req->cmd_type = QEDF_CLEANUP; -+ spin_unlock_irqrestore(&fcport->rport_lock, flags); - io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; - - init_completion(&io_req->cleanup_done); -diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c -index c4f293d39f228..d969b0dc97326 100644 ---- a/drivers/scsi/qedf/qedf_main.c -+++ b/drivers/scsi/qedf/qedf_main.c -@@ -2807,6 +2807,8 @@ void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe) - struct qedf_ioreq *io_req; - struct qedf_rport *fcport; - u32 comp_type; -+ u8 io_comp_type; -+ unsigned long flags; - - comp_type = (cqe->cqe_data >> FCOE_CQE_CQE_TYPE_SHIFT) & - FCOE_CQE_CQE_TYPE_MASK; -@@ -2840,11 +2842,14 @@ void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe) - return; - } - -+ spin_lock_irqsave(&fcport->rport_lock, flags); -+ io_comp_type = io_req->cmd_type; -+ spin_unlock_irqrestore(&fcport->rport_lock, flags); - - switch (comp_type) { - case FCOE_GOOD_COMPLETION_CQE_TYPE: - atomic_inc(&fcport->free_sqes); -- switch (io_req->cmd_type) { -+ switch (io_comp_type) { - case QEDF_SCSI_CMD: - qedf_scsi_completion(qedf, cqe, io_req); - break; -diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h -index 7d282906598f3..1713588f671f3 100644 ---- a/drivers/scsi/qla2xxx/qla_def.h -+++ b/drivers/scsi/qla2xxx/qla_def.h -@@ -3475,6 +3475,7 @@ struct qla_msix_entry { - int have_irq; - int in_use; - uint32_t vector; -+ uint32_t vector_base0; - uint16_t entry; - char name[30]; - void *handle; -@@ -3804,6 +3805,7 @@ struct qla_qpair { - uint64_t retry_term_jiff; - struct qla_tgt_counters tgt_counters; - uint16_t cpuid; -+ bool cpu_mapped; - struct qla_fw_resources fwres ____cacheline_aligned; - u32 cmd_cnt; - u32 cmd_completion_cnt; -@@ -4133,6 +4135,7 @@ struct qla_hw_data { - struct req_que **req_q_map; - struct rsp_que **rsp_q_map; - struct qla_qpair **queue_pair_map; -+ struct qla_qpair **qp_cpu_map; - unsigned long req_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)]; - unsigned long rsp_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)]; - unsigned long qpair_qid_map[(QLA_MAX_QUEUES / 8) -diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c -index 36abdb0de1694..884ed77259f85 100644 ---- a/drivers/scsi/qla2xxx/qla_init.c -+++ b/drivers/scsi/qla2xxx/qla_init.c -@@ -9758,8 +9758,9 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, - qpair->req = ha->req_q_map[req_id]; - qpair->rsp->req = qpair->req; - qpair->rsp->qpair = qpair; -- /* init qpair to this cpu. Will adjust at run time. */ -- qla_cpu_update(qpair, raw_smp_processor_id()); -+ -+ if (!qpair->cpu_mapped) -+ qla_cpu_update(qpair, raw_smp_processor_id()); - - if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { - if (ha->fw_attributes & BIT_4) -diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h -index a7b5d11146827..a4a56ab0ba747 100644 ---- a/drivers/scsi/qla2xxx/qla_inline.h -+++ b/drivers/scsi/qla2xxx/qla_inline.h -@@ -573,3 +573,61 @@ fcport_is_bigger(fc_port_t *fcport) - { - return !fcport_is_smaller(fcport); - } -+ -+static inline struct qla_qpair * -+qla_mapq_nvme_select_qpair(struct qla_hw_data *ha, struct qla_qpair *qpair) -+{ -+ int cpuid = raw_smp_processor_id(); -+ -+ if (qpair->cpuid != cpuid && -+ ha->qp_cpu_map[cpuid]) { -+ qpair = ha->qp_cpu_map[cpuid]; -+ } -+ return qpair; -+} -+ -+static inline void -+qla_mapq_init_qp_cpu_map(struct qla_hw_data *ha, -+ struct qla_msix_entry *msix, -+ struct qla_qpair *qpair) -+{ -+ const struct cpumask *mask; -+ unsigned int cpu; -+ -+ if (!ha->qp_cpu_map) -+ return; -+ mask = pci_irq_get_affinity(ha->pdev, msix->vector_base0); -+ if (!mask) -+ return; -+ qpair->cpuid = cpumask_first(mask); -+ for_each_cpu(cpu, mask) { -+ ha->qp_cpu_map[cpu] = qpair; -+ } -+ msix->cpuid = qpair->cpuid; -+ qpair->cpu_mapped = true; -+} -+ -+static inline void -+qla_mapq_free_qp_cpu_map(struct qla_hw_data *ha) -+{ -+ if (ha->qp_cpu_map) { -+ kfree(ha->qp_cpu_map); -+ ha->qp_cpu_map = NULL; -+ } -+} -+ -+static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha) -+{ -+ scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); -+ -+ if (!ha->qp_cpu_map) { -+ ha->qp_cpu_map = kcalloc(NR_CPUS, sizeof(struct qla_qpair *), -+ GFP_KERNEL); -+ if (!ha->qp_cpu_map) { -+ ql_log(ql_log_fatal, vha, 0x0180, -+ "Unable to allocate memory for qp_cpu_map ptrs.\n"); -+ return -1; -+ } -+ } -+ return 0; -+} -diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c -index 0111249cc8774..db65dbab3a9fa 100644 ---- a/drivers/scsi/qla2xxx/qla_isr.c -+++ b/drivers/scsi/qla2xxx/qla_isr.c -@@ -3817,9 +3817,11 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, - if (!ha->flags.fw_started) - return; - -- if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) { -+ if (rsp->qpair->cpuid != raw_smp_processor_id() || !rsp->qpair->rcv_intr) { - rsp->qpair->rcv_intr = 1; -- qla_cpu_update(rsp->qpair, smp_processor_id()); -+ -+ if (!rsp->qpair->cpu_mapped) -+ qla_cpu_update(rsp->qpair, raw_smp_processor_id()); - } - - #define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in) \ -@@ -4306,7 +4308,7 @@ qla2xxx_msix_rsp_q(int irq, void *dev_id) - } - ha = qpair->hw; - -- queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); -+ queue_work(ha->wq, &qpair->q_work); - - return IRQ_HANDLED; - } -@@ -4332,7 +4334,7 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id) - wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - -- queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); -+ queue_work(ha->wq, &qpair->q_work); - - return IRQ_HANDLED; - } -@@ -4425,6 +4427,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) - for (i = 0; i < ha->msix_count; i++) { - qentry = &ha->msix_entries[i]; - qentry->vector = pci_irq_vector(ha->pdev, i); -+ qentry->vector_base0 = i; - qentry->entry = i; - qentry->have_irq = 0; - qentry->in_use = 0; -@@ -4652,5 +4655,6 @@ int qla25xx_request_irq(struct qla_hw_data *ha, struct qla_qpair *qpair, - } - msix->have_irq = 1; - msix->handle = qpair; -+ qla_mapq_init_qp_cpu_map(ha, msix, qpair); - return ret; - } -diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c -index c9a6fc882a801..9941b38eac93c 100644 ---- a/drivers/scsi/qla2xxx/qla_nvme.c -+++ b/drivers/scsi/qla2xxx/qla_nvme.c -@@ -609,6 +609,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, - fc_port_t *fcport; - struct srb_iocb *nvme; - struct scsi_qla_host *vha; -+ struct qla_hw_data *ha; - int rval; - srb_t *sp; - struct qla_qpair *qpair = hw_queue_handle; -@@ -629,6 +630,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, - return -ENODEV; - - vha = fcport->vha; -+ ha = vha->hw; - - if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) - return -EBUSY; -@@ -643,6 +645,8 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, - if (fcport->nvme_flag & NVME_FLAG_RESETTING) - return -EBUSY; - -+ qpair = qla_mapq_nvme_select_qpair(ha, qpair); -+ - /* Alloc SRB structure */ - sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC); - if (!sp) -diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c -index 78f7cd16967fa..b33ffec1cb75e 100644 ---- a/drivers/scsi/qla2xxx/qla_os.c -+++ b/drivers/scsi/qla2xxx/qla_os.c -@@ -480,6 +480,11 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, - "Unable to allocate memory for queue pair ptrs.\n"); - goto fail_qpair_map; - } -+ if (qla_mapq_alloc_qp_cpu_map(ha) != 0) { -+ kfree(ha->queue_pair_map); -+ ha->queue_pair_map = NULL; -+ goto fail_qpair_map; -+ } - } - - /* -@@ -554,6 +559,7 @@ static void qla2x00_free_queues(struct qla_hw_data *ha) - ha->base_qpair = NULL; - } - -+ qla_mapq_free_qp_cpu_map(ha); - spin_lock_irqsave(&ha->hardware_lock, flags); - for (cnt = 0; cnt < ha->max_req_queues; cnt++) { - if (!test_bit(cnt, ha->req_qid_map)) -diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c -index 545473a0ffc84..5a5beb41786ed 100644 ---- a/drivers/scsi/qla2xxx/qla_target.c -+++ b/drivers/scsi/qla2xxx/qla_target.c -@@ -4442,8 +4442,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, - queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &cmd->work); - } else if (ha->msix_count) { - if (cmd->atio.u.isp24.fcp_cmnd.rddata) -- queue_work_on(smp_processor_id(), qla_tgt_wq, -- &cmd->work); -+ queue_work(qla_tgt_wq, &cmd->work); - else - queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, - &cmd->work); -diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c -index 8fa0056b56ddb..e54ee6770e79f 100644 ---- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c -+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c -@@ -310,7 +310,7 @@ static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd) - cmd->trc_flags |= TRC_CMD_DONE; - - INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free); -- queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); -+ queue_work(tcm_qla2xxx_free_wq, &cmd->work); - } - - /* -@@ -557,7 +557,7 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) - cmd->trc_flags |= TRC_DATA_IN; - cmd->cmd_in_wq = 1; - INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work); -- queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); -+ queue_work(tcm_qla2xxx_free_wq, &cmd->work); - } - - static int tcm_qla2xxx_chk_dif_tags(uint32_t tag) -diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c -index 32ed9dc88e455..08197b03955dd 100644 ---- a/drivers/soc/imx/soc-imx8m.c -+++ b/drivers/soc/imx/soc-imx8m.c -@@ -100,6 +100,7 @@ static void __init imx8mm_soc_uid(void) - { - void __iomem *ocotp_base; - struct device_node *np; -+ struct clk *clk; - u32 offset = of_machine_is_compatible("fsl,imx8mp") ? - IMX8MP_OCOTP_UID_OFFSET : 0; - -@@ -109,11 +110,20 @@ static void __init imx8mm_soc_uid(void) - - ocotp_base = of_iomap(np, 0); - WARN_ON(!ocotp_base); -+ clk = of_clk_get_by_name(np, NULL); -+ if (IS_ERR(clk)) { -+ WARN_ON(IS_ERR(clk)); -+ return; -+ } -+ -+ clk_prepare_enable(clk); - - soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset); - soc_uid <<= 32; - soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset); - -+ clk_disable_unprepare(clk); -+ clk_put(clk); - iounmap(ocotp_base); - of_node_put(np); - } -diff --git a/drivers/spi/spi-gxp.c b/drivers/spi/spi-gxp.c -index c900c2f39b578..21b07e2518513 100644 ---- a/drivers/spi/spi-gxp.c -+++ b/drivers/spi/spi-gxp.c -@@ -195,7 +195,7 @@ static ssize_t gxp_spi_write(struct gxp_spi_chip *chip, const struct spi_mem_op - return ret; - } - -- return write_len; -+ return 0; - } - - static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) -diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c -index f0d532ea40e82..b718a74fa3edc 100644 ---- a/drivers/spi/spi-intel-pci.c -+++ b/drivers/spi/spi-intel-pci.c -@@ -72,6 +72,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { - { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info }, - { PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info }, - { PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info }, -+ { PCI_VDEVICE(INTEL, 0x5794), (unsigned long)&cnl_info }, - { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info }, - { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, - { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info }, -diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c -index d6a65a989ef80..c7a4a3606547e 100644 ---- a/drivers/spi/spi-nxp-fspi.c -+++ b/drivers/spi/spi-nxp-fspi.c -@@ -1029,6 +1029,13 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f) - fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT, - base + FSPI_AHBCR); - -+ /* Reset the FLSHxCR1 registers. */ -+ reg = FSPI_FLSHXCR1_TCSH(0x3) | FSPI_FLSHXCR1_TCSS(0x3); -+ fspi_writel(f, reg, base + FSPI_FLSHA1CR1); -+ fspi_writel(f, reg, base + FSPI_FLSHA2CR1); -+ fspi_writel(f, reg, base + FSPI_FLSHB1CR1); -+ fspi_writel(f, reg, base + FSPI_FLSHB2CR1); -+ - /* AHB Read - Set lut sequence ID for all CS. */ - fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2); - fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2); -diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c -index def09cf0dc147..12241815510d4 100644 ---- a/drivers/spi/spi-stm32.c -+++ b/drivers/spi/spi-stm32.c -@@ -268,6 +268,7 @@ struct stm32_spi_cfg { - * @fifo_size: size of the embedded fifo in bytes - * @cur_midi: master inter-data idleness in ns - * @cur_speed: speed configured in Hz -+ * @cur_half_period: time of a half bit in us - * @cur_bpw: number of bits in a single SPI data frame - * @cur_fthlv: fifo threshold level (data frames in a single data packet) - * @cur_comm: SPI communication mode -@@ -294,6 +295,7 @@ struct stm32_spi { - - unsigned int cur_midi; - unsigned int cur_speed; -+ unsigned int cur_half_period; - unsigned int cur_bpw; - unsigned int cur_fthlv; - unsigned int cur_comm; -@@ -454,6 +456,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz, - - spi->cur_speed = spi->clk_rate / (1 << mbrdiv); - -+ spi->cur_half_period = DIV_ROUND_CLOSEST(USEC_PER_SEC, 2 * spi->cur_speed); -+ - return mbrdiv - 1; - } - -@@ -695,6 +699,10 @@ static void stm32h7_spi_disable(struct stm32_spi *spi) - return; - } - -+ /* Add a delay to make sure that transmission is ended. */ -+ if (spi->cur_half_period) -+ udelay(spi->cur_half_period); -+ - if (spi->cur_usedma && spi->dma_tx) - dmaengine_terminate_all(spi->dma_tx); - if (spi->cur_usedma && spi->dma_rx) -diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c -index 23ad052528dbe..d79853ba7792a 100644 ---- a/drivers/spi/spi-sun6i.c -+++ b/drivers/spi/spi-sun6i.c -@@ -95,6 +95,7 @@ struct sun6i_spi { - struct reset_control *rstc; - - struct completion done; -+ struct completion dma_rx_done; - - const u8 *tx_buf; - u8 *rx_buf; -@@ -189,6 +190,13 @@ static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) - return SUN6I_MAX_XFER_SIZE - 1; - } - -+static void sun6i_spi_dma_rx_cb(void *param) -+{ -+ struct sun6i_spi *sspi = param; -+ -+ complete(&sspi->dma_rx_done); -+} -+ - static int sun6i_spi_prepare_dma(struct sun6i_spi *sspi, - struct spi_transfer *tfr) - { -@@ -200,7 +208,7 @@ static int sun6i_spi_prepare_dma(struct sun6i_spi *sspi, - struct dma_slave_config rxconf = { - .direction = DMA_DEV_TO_MEM, - .src_addr = sspi->dma_addr_rx, -- .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, -+ .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, - .src_maxburst = 8, - }; - -@@ -213,6 +221,8 @@ static int sun6i_spi_prepare_dma(struct sun6i_spi *sspi, - DMA_PREP_INTERRUPT); - if (!rxdesc) - return -EINVAL; -+ rxdesc->callback_param = sspi; -+ rxdesc->callback = sun6i_spi_dma_rx_cb; - } - - txdesc = NULL; -@@ -268,6 +278,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master, - return -EINVAL; - - reinit_completion(&sspi->done); -+ reinit_completion(&sspi->dma_rx_done); - sspi->tx_buf = tfr->tx_buf; - sspi->rx_buf = tfr->rx_buf; - sspi->len = tfr->len; -@@ -426,6 +437,22 @@ static int sun6i_spi_transfer_one(struct spi_master *master, - start = jiffies; - timeout = wait_for_completion_timeout(&sspi->done, - msecs_to_jiffies(tx_time)); -+ -+ if (!use_dma) { -+ sun6i_spi_drain_fifo(sspi); -+ } else { -+ if (timeout && rx_len) { -+ /* -+ * Even though RX on the peripheral side has finished -+ * RX DMA might still be in flight -+ */ -+ timeout = wait_for_completion_timeout(&sspi->dma_rx_done, -+ timeout); -+ if (!timeout) -+ dev_warn(&master->dev, "RX DMA timeout\n"); -+ } -+ } -+ - end = jiffies; - if (!timeout) { - dev_warn(&master->dev, -@@ -453,7 +480,6 @@ static irqreturn_t sun6i_spi_handler(int irq, void *dev_id) - /* Transfer complete */ - if (status & SUN6I_INT_CTL_TC) { - sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC); -- sun6i_spi_drain_fifo(sspi); - complete(&sspi->done); - return IRQ_HANDLED; - } -@@ -611,6 +637,7 @@ static int sun6i_spi_probe(struct platform_device *pdev) - } - - init_completion(&sspi->done); -+ init_completion(&sspi->dma_rx_done); - - sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (IS_ERR(sspi->rstc)) { -diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c -index 762d1990180bf..4104743dbc17e 100644 ---- a/drivers/thermal/thermal_of.c -+++ b/drivers/thermal/thermal_of.c -@@ -149,8 +149,10 @@ static int of_find_trip_id(struct device_node *np, struct device_node *trip) - */ - for_each_child_of_node(trips, t) { - -- if (t == trip) -+ if (t == trip) { -+ of_node_put(t); - goto out; -+ } - i++; - } - -@@ -519,8 +521,10 @@ static int thermal_of_for_each_cooling_maps(struct thermal_zone_device *tz, - - for_each_child_of_node(cm_np, child) { - ret = thermal_of_for_each_cooling_device(tz_np, child, tz, cdev, action); -- if (ret) -+ if (ret) { -+ of_node_put(child); - break; -+ } - } - - of_node_put(cm_np); -diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c -index c1fa20a4e3420..4b43589304704 100644 ---- a/drivers/tty/n_gsm.c -+++ b/drivers/tty/n_gsm.c -@@ -2509,10 +2509,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) - gsm->has_devices = false; - } - for (i = NUM_DLCI - 1; i >= 0; i--) -- if (gsm->dlci[i]) { -+ if (gsm->dlci[i]) - gsm_dlci_release(gsm->dlci[i]); -- gsm->dlci[i] = NULL; -- } - mutex_unlock(&gsm->mutex); - /* Now wipe the queues */ - tty_ldisc_flush(gsm->tty); -diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c -index 38760bd6e0c29..8efe31448df3c 100644 ---- a/drivers/tty/serial/8250/8250_port.c -+++ b/drivers/tty/serial/8250/8250_port.c -@@ -1953,7 +1953,10 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) - skip_rx = true; - - if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { -- if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) -+ struct irq_data *d; -+ -+ d = irq_get_irq_data(port->irq); -+ if (d && irqd_is_wakeup_set(d)) - pm_wakeup_event(tport->tty->dev, 0); - if (!up->dma || handle_rx_dma(up, iir)) - status = serial8250_rx_chars(up, status); -diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c -index 36437d39b93c8..b4e3f14b9a3d7 100644 ---- a/drivers/ufs/core/ufshcd.c -+++ b/drivers/ufs/core/ufshcd.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2254,7 +2255,11 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba) - */ - static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba) - { -- return ufshcd_readl(hba, REG_CONTROLLER_STATUS) & UIC_COMMAND_READY; -+ u32 val; -+ int ret = read_poll_timeout(ufshcd_readl, val, val & UIC_COMMAND_READY, -+ 500, UIC_CMD_TIMEOUT * 1000, false, hba, -+ REG_CONTROLLER_STATUS); -+ return ret == 0 ? true : false; - } - - /** -@@ -2346,7 +2351,6 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd, - bool completion) - { - lockdep_assert_held(&hba->uic_cmd_mutex); -- lockdep_assert_held(hba->host->host_lock); - - if (!ufshcd_ready_for_uic_cmd(hba)) { - dev_err(hba->dev, -@@ -2373,7 +2377,6 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd, - int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) - { - int ret; -- unsigned long flags; - - if (hba->quirks & UFSHCD_QUIRK_BROKEN_UIC_CMD) - return 0; -@@ -2382,9 +2385,7 @@ int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) - mutex_lock(&hba->uic_cmd_mutex); - ufshcd_add_delay_before_dme_cmd(hba); - -- spin_lock_irqsave(hba->host->host_lock, flags); - ret = __ufshcd_send_uic_cmd(hba, uic_cmd, true); -- spin_unlock_irqrestore(hba->host->host_lock, flags); - if (!ret) - ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd); - -@@ -4076,8 +4077,8 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) - wmb(); - reenable_intr = true; - } -- ret = __ufshcd_send_uic_cmd(hba, cmd, false); - spin_unlock_irqrestore(hba->host->host_lock, flags); -+ ret = __ufshcd_send_uic_cmd(hba, cmd, false); - if (ret) { - dev_err(hba->dev, - "pwr ctrl cmd 0x%x with mode 0x%x uic error %d\n", -diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c -index abe3359dd477f..16b007c6bbb56 100644 ---- a/drivers/vfio/mdev/mdev_sysfs.c -+++ b/drivers/vfio/mdev/mdev_sysfs.c -@@ -233,7 +233,8 @@ int parent_create_sysfs_files(struct mdev_parent *parent) - out_err: - while (--i >= 0) - mdev_type_remove(parent->types[i]); -- return 0; -+ kset_unregister(parent->mdev_types_kset); -+ return ret; - } - - static ssize_t remove_store(struct device *dev, struct device_attribute *attr, -diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index 974e862cd20d6..ff95f19224901 100644 ---- a/drivers/video/fbdev/Kconfig -+++ b/drivers/video/fbdev/Kconfig -@@ -2015,7 +2015,7 @@ config FB_COBALT - - config FB_SH7760 - bool "SH7760/SH7763/SH7720/SH7721 LCDC support" -- depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ -+ depends on FB=y && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ - || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA -diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c -index 069f12cc7634c..2aecd4ffb13b3 100644 ---- a/fs/binfmt_elf_fdpic.c -+++ b/fs/binfmt_elf_fdpic.c -@@ -345,10 +345,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) - /* there's now no turning back... the old userspace image is dead, - * defunct, deceased, etc. - */ -+ SET_PERSONALITY(exec_params.hdr); - if (elf_check_fdpic(&exec_params.hdr)) -- set_personality(PER_LINUX_FDPIC); -- else -- set_personality(PER_LINUX); -+ current->personality |= PER_LINUX_FDPIC; - if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) - current->personality |= READ_IMPLIES_EXEC; - -diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c -index d2cbb7733c7d6..1331e56e8e84f 100644 ---- a/fs/btrfs/delayed-inode.c -+++ b/fs/btrfs/delayed-inode.c -@@ -407,6 +407,7 @@ static void finish_one_item(struct btrfs_delayed_root *delayed_root) - - static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) - { -+ struct btrfs_delayed_node *delayed_node = delayed_item->delayed_node; - struct rb_root_cached *root; - struct btrfs_delayed_root *delayed_root; - -@@ -414,18 +415,21 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) - if (RB_EMPTY_NODE(&delayed_item->rb_node)) - return; - -- delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root; -+ /* If it's in a rbtree, then we need to have delayed node locked. */ -+ lockdep_assert_held(&delayed_node->mutex); -+ -+ delayed_root = delayed_node->root->fs_info->delayed_root; - - BUG_ON(!delayed_root); - - if (delayed_item->type == BTRFS_DELAYED_INSERTION_ITEM) -- root = &delayed_item->delayed_node->ins_root; -+ root = &delayed_node->ins_root; - else -- root = &delayed_item->delayed_node->del_root; -+ root = &delayed_node->del_root; - - rb_erase_cached(&delayed_item->rb_node, root); - RB_CLEAR_NODE(&delayed_item->rb_node); -- delayed_item->delayed_node->count--; -+ delayed_node->count--; - - finish_one_item(delayed_root); - } -@@ -1421,7 +1425,29 @@ void btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info) - btrfs_wq_run_delayed_node(delayed_root, fs_info, BTRFS_DELAYED_BATCH); - } - --/* Will return 0 or -ENOMEM */ -+static void btrfs_release_dir_index_item_space(struct btrfs_trans_handle *trans) -+{ -+ struct btrfs_fs_info *fs_info = trans->fs_info; -+ const u64 bytes = btrfs_calc_insert_metadata_size(fs_info, 1); -+ -+ if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) -+ return; -+ -+ /* -+ * Adding the new dir index item does not require touching another -+ * leaf, so we can release 1 unit of metadata that was previously -+ * reserved when starting the transaction. This applies only to -+ * the case where we had a transaction start and excludes the -+ * transaction join case (when replaying log trees). -+ */ -+ trace_btrfs_space_reservation(fs_info, "transaction", -+ trans->transid, bytes, 0); -+ btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL); -+ ASSERT(trans->bytes_reserved >= bytes); -+ trans->bytes_reserved -= bytes; -+} -+ -+/* Will return 0, -ENOMEM or -EEXIST (index number collision, unexpected). */ - int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, - const char *name, int name_len, - struct btrfs_inode *dir, -@@ -1463,6 +1489,27 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, - - mutex_lock(&delayed_node->mutex); - -+ /* -+ * First attempt to insert the delayed item. This is to make the error -+ * handling path simpler in case we fail (-EEXIST). There's no risk of -+ * any other task coming in and running the delayed item before we do -+ * the metadata space reservation below, because we are holding the -+ * delayed node's mutex and that mutex must also be locked before the -+ * node's delayed items can be run. -+ */ -+ ret = __btrfs_add_delayed_item(delayed_node, delayed_item); -+ if (unlikely(ret)) { -+ btrfs_err(trans->fs_info, -+"error adding delayed dir index item, name: %.*s, index: %llu, root: %llu, dir: %llu, dir->index_cnt: %llu, delayed_node->index_cnt: %llu, error: %d", -+ name_len, name, index, btrfs_root_id(delayed_node->root), -+ delayed_node->inode_id, dir->index_cnt, -+ delayed_node->index_cnt, ret); -+ btrfs_release_delayed_item(delayed_item); -+ btrfs_release_dir_index_item_space(trans); -+ mutex_unlock(&delayed_node->mutex); -+ goto release_node; -+ } -+ - if (delayed_node->index_item_leaves == 0 || - delayed_node->curr_index_batch_size + data_len > leaf_data_size) { - delayed_node->curr_index_batch_size = data_len; -@@ -1480,36 +1527,14 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, - * impossible. - */ - if (WARN_ON(ret)) { -- mutex_unlock(&delayed_node->mutex); - btrfs_release_delayed_item(delayed_item); -+ mutex_unlock(&delayed_node->mutex); - goto release_node; - } - - delayed_node->index_item_leaves++; -- } else if (!test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) { -- const u64 bytes = btrfs_calc_insert_metadata_size(fs_info, 1); -- -- /* -- * Adding the new dir index item does not require touching another -- * leaf, so we can release 1 unit of metadata that was previously -- * reserved when starting the transaction. This applies only to -- * the case where we had a transaction start and excludes the -- * transaction join case (when replaying log trees). -- */ -- trace_btrfs_space_reservation(fs_info, "transaction", -- trans->transid, bytes, 0); -- btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL); -- ASSERT(trans->bytes_reserved >= bytes); -- trans->bytes_reserved -= bytes; -- } -- -- ret = __btrfs_add_delayed_item(delayed_node, delayed_item); -- if (unlikely(ret)) { -- btrfs_err(trans->fs_info, -- "err add delayed dir index item(name: %.*s) into the insertion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)", -- name_len, name, delayed_node->root->root_key.objectid, -- delayed_node->inode_id, ret); -- BUG(); -+ } else { -+ btrfs_release_dir_index_item_space(trans); - } - mutex_unlock(&delayed_node->mutex); - -diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c -index 0ad69041954ff..afcc96a1f4276 100644 ---- a/fs/btrfs/extent_io.c -+++ b/fs/btrfs/extent_io.c -@@ -5184,8 +5184,14 @@ void read_extent_buffer(const struct extent_buffer *eb, void *dstv, - char *dst = (char *)dstv; - unsigned long i = get_eb_page_index(start); - -- if (check_eb_range(eb, start, len)) -+ if (check_eb_range(eb, start, len)) { -+ /* -+ * Invalid range hit, reset the memory, so callers won't get -+ * some random garbage for their uninitialzed memory. -+ */ -+ memset(dstv, 0, len); - return; -+ } - - offset = get_eb_offset_in_page(eb, start); - -diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c -index 6438300fa2461..582b71b7fa779 100644 ---- a/fs/btrfs/super.c -+++ b/fs/btrfs/super.c -@@ -2418,7 +2418,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) - * calculated f_bavail. - */ - if (!mixed && block_rsv->space_info->full && -- total_free_meta - thresh < block_rsv->size) -+ (total_free_meta < thresh || total_free_meta - thresh < block_rsv->size)) - buf->f_bavail = 0; - - buf->f_type = BTRFS_SUPER_MAGIC; -diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c -index 4a9ad5ff726d4..36052a3626830 100644 ---- a/fs/ceph/caps.c -+++ b/fs/ceph/caps.c -@@ -4100,6 +4100,9 @@ void ceph_handle_caps(struct ceph_mds_session *session, - - dout("handle_caps from mds%d\n", session->s_mds); - -+ if (!ceph_inc_mds_stopping_blocker(mdsc, session)) -+ return; -+ - /* decode */ - end = msg->front.iov_base + msg->front.iov_len; - if (msg->front.iov_len < sizeof(*h)) -@@ -4196,7 +4199,6 @@ void ceph_handle_caps(struct ceph_mds_session *session, - vino.snap, inode); - - mutex_lock(&session->s_mutex); -- inc_session_sequence(session); - dout(" mds%d seq %lld cap seq %u\n", session->s_mds, session->s_seq, - (unsigned)seq); - -@@ -4299,6 +4301,8 @@ done: - done_unlocked: - iput(inode); - out: -+ ceph_dec_mds_stopping_blocker(mdsc); -+ - ceph_put_string(extra_info.pool_ns); - - /* Defer closing the sessions after s_mutex lock being released */ -diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c -index 5399a9ea5b4f1..f6a7fd47efd7a 100644 ---- a/fs/ceph/mds_client.c -+++ b/fs/ceph/mds_client.c -@@ -4546,6 +4546,9 @@ static void handle_lease(struct ceph_mds_client *mdsc, - - dout("handle_lease from mds%d\n", mds); - -+ if (!ceph_inc_mds_stopping_blocker(mdsc, session)) -+ return; -+ - /* decode */ - if (msg->front.iov_len < sizeof(*h) + sizeof(u32)) - goto bad; -@@ -4564,8 +4567,6 @@ static void handle_lease(struct ceph_mds_client *mdsc, - dname.len, dname.name); - - mutex_lock(&session->s_mutex); -- inc_session_sequence(session); -- - if (!inode) { - dout("handle_lease no inode %llx\n", vino.ino); - goto release; -@@ -4627,9 +4628,13 @@ release: - out: - mutex_unlock(&session->s_mutex); - iput(inode); -+ -+ ceph_dec_mds_stopping_blocker(mdsc); - return; - - bad: -+ ceph_dec_mds_stopping_blocker(mdsc); -+ - pr_err("corrupt lease message\n"); - ceph_msg_dump(msg); - } -@@ -4825,6 +4830,9 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) - } - - init_completion(&mdsc->safe_umount_waiters); -+ spin_lock_init(&mdsc->stopping_lock); -+ atomic_set(&mdsc->stopping_blockers, 0); -+ init_completion(&mdsc->stopping_waiter); - init_waitqueue_head(&mdsc->session_close_wq); - INIT_LIST_HEAD(&mdsc->waiting_for_map); - mdsc->quotarealms_inodes = RB_ROOT; -diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h -index 9a80658f41679..0913959ccfa64 100644 ---- a/fs/ceph/mds_client.h -+++ b/fs/ceph/mds_client.h -@@ -381,8 +381,9 @@ struct cap_wait { - }; - - enum { -- CEPH_MDSC_STOPPING_BEGIN = 1, -- CEPH_MDSC_STOPPING_FLUSHED = 2, -+ CEPH_MDSC_STOPPING_BEGIN = 1, -+ CEPH_MDSC_STOPPING_FLUSHING = 2, -+ CEPH_MDSC_STOPPING_FLUSHED = 3, - }; - - /* -@@ -401,7 +402,11 @@ struct ceph_mds_client { - struct ceph_mds_session **sessions; /* NULL for mds if no session */ - atomic_t num_sessions; - int max_sessions; /* len of sessions array */ -- int stopping; /* true if shutting down */ -+ -+ spinlock_t stopping_lock; /* protect snap_empty */ -+ int stopping; /* the stage of shutting down */ -+ atomic_t stopping_blockers; -+ struct completion stopping_waiter; - - atomic64_t quotarealms_count; /* # realms with quota */ - /* -diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c -index 64592adfe48fb..f7fcf7f08ec64 100644 ---- a/fs/ceph/quota.c -+++ b/fs/ceph/quota.c -@@ -47,25 +47,23 @@ void ceph_handle_quota(struct ceph_mds_client *mdsc, - struct inode *inode; - struct ceph_inode_info *ci; - -+ if (!ceph_inc_mds_stopping_blocker(mdsc, session)) -+ return; -+ - if (msg->front.iov_len < sizeof(*h)) { - pr_err("%s corrupt message mds%d len %d\n", __func__, - session->s_mds, (int)msg->front.iov_len); - ceph_msg_dump(msg); -- return; -+ goto out; - } - -- /* increment msg sequence number */ -- mutex_lock(&session->s_mutex); -- inc_session_sequence(session); -- mutex_unlock(&session->s_mutex); -- - /* lookup inode */ - vino.ino = le64_to_cpu(h->ino); - vino.snap = CEPH_NOSNAP; - inode = ceph_find_inode(sb, vino); - if (!inode) { - pr_warn("Failed to find inode %llu\n", vino.ino); -- return; -+ goto out; - } - ci = ceph_inode(inode); - -@@ -78,6 +76,8 @@ void ceph_handle_quota(struct ceph_mds_client *mdsc, - spin_unlock(&ci->i_ceph_lock); - - iput(inode); -+out: -+ ceph_dec_mds_stopping_blocker(mdsc); - } - - static struct ceph_quotarealm_inode * -diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c -index 2e73ba62bd7aa..82f7592e1747b 100644 ---- a/fs/ceph/snap.c -+++ b/fs/ceph/snap.c -@@ -1012,6 +1012,9 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, - int locked_rwsem = 0; - bool close_sessions = false; - -+ if (!ceph_inc_mds_stopping_blocker(mdsc, session)) -+ return; -+ - /* decode */ - if (msg->front.iov_len < sizeof(*h)) - goto bad; -@@ -1027,10 +1030,6 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, - dout("%s from mds%d op %s split %llx tracelen %d\n", __func__, - mds, ceph_snap_op_name(op), split, trace_len); - -- mutex_lock(&session->s_mutex); -- inc_session_sequence(session); -- mutex_unlock(&session->s_mutex); -- - down_write(&mdsc->snap_rwsem); - locked_rwsem = 1; - -@@ -1148,6 +1147,7 @@ skip_inode: - up_write(&mdsc->snap_rwsem); - - flush_snaps(mdsc); -+ ceph_dec_mds_stopping_blocker(mdsc); - return; - - bad: -@@ -1157,6 +1157,8 @@ out: - if (locked_rwsem) - up_write(&mdsc->snap_rwsem); - -+ ceph_dec_mds_stopping_blocker(mdsc); -+ - if (close_sessions) - ceph_mdsc_close_sessions(mdsc); - return; -diff --git a/fs/ceph/super.c b/fs/ceph/super.c -index a5f52013314d6..281b493fdac8e 100644 ---- a/fs/ceph/super.c -+++ b/fs/ceph/super.c -@@ -1365,25 +1365,90 @@ nomem: - return -ENOMEM; - } - -+/* -+ * Return true if it successfully increases the blocker counter, -+ * or false if the mdsc is in stopping and flushed state. -+ */ -+static bool __inc_stopping_blocker(struct ceph_mds_client *mdsc) -+{ -+ spin_lock(&mdsc->stopping_lock); -+ if (mdsc->stopping >= CEPH_MDSC_STOPPING_FLUSHING) { -+ spin_unlock(&mdsc->stopping_lock); -+ return false; -+ } -+ atomic_inc(&mdsc->stopping_blockers); -+ spin_unlock(&mdsc->stopping_lock); -+ return true; -+} -+ -+static void __dec_stopping_blocker(struct ceph_mds_client *mdsc) -+{ -+ spin_lock(&mdsc->stopping_lock); -+ if (!atomic_dec_return(&mdsc->stopping_blockers) && -+ mdsc->stopping >= CEPH_MDSC_STOPPING_FLUSHING) -+ complete_all(&mdsc->stopping_waiter); -+ spin_unlock(&mdsc->stopping_lock); -+} -+ -+/* For metadata IO requests */ -+bool ceph_inc_mds_stopping_blocker(struct ceph_mds_client *mdsc, -+ struct ceph_mds_session *session) -+{ -+ mutex_lock(&session->s_mutex); -+ inc_session_sequence(session); -+ mutex_unlock(&session->s_mutex); -+ -+ return __inc_stopping_blocker(mdsc); -+} -+ -+void ceph_dec_mds_stopping_blocker(struct ceph_mds_client *mdsc) -+{ -+ __dec_stopping_blocker(mdsc); -+} -+ - static void ceph_kill_sb(struct super_block *s) - { - struct ceph_fs_client *fsc = ceph_sb_to_client(s); -+ struct ceph_mds_client *mdsc = fsc->mdsc; -+ bool wait; - - dout("kill_sb %p\n", s); - -- ceph_mdsc_pre_umount(fsc->mdsc); -+ ceph_mdsc_pre_umount(mdsc); - flush_fs_workqueues(fsc); - - /* - * Though the kill_anon_super() will finally trigger the -- * sync_filesystem() anyway, we still need to do it here -- * and then bump the stage of shutdown to stop the work -- * queue as earlier as possible. -+ * sync_filesystem() anyway, we still need to do it here and -+ * then bump the stage of shutdown. This will allow us to -+ * drop any further message, which will increase the inodes' -+ * i_count reference counters but makes no sense any more, -+ * from MDSs. -+ * -+ * Without this when evicting the inodes it may fail in the -+ * kill_anon_super(), which will trigger a warning when -+ * destroying the fscrypt keyring and then possibly trigger -+ * a further crash in ceph module when the iput() tries to -+ * evict the inodes later. - */ - sync_filesystem(s); - -- fsc->mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHED; -+ spin_lock(&mdsc->stopping_lock); -+ mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHING; -+ wait = !!atomic_read(&mdsc->stopping_blockers); -+ spin_unlock(&mdsc->stopping_lock); -+ -+ if (wait && atomic_read(&mdsc->stopping_blockers)) { -+ long timeleft = wait_for_completion_killable_timeout( -+ &mdsc->stopping_waiter, -+ fsc->client->options->mount_timeout); -+ if (!timeleft) /* timed out */ -+ pr_warn("umount timed out, %ld\n", timeleft); -+ else if (timeleft < 0) /* killed */ -+ pr_warn("umount was killed, %ld\n", timeleft); -+ } - -+ mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHED; - kill_anon_super(s); - - fsc->client->extra_mon_dispatch = NULL; -diff --git a/fs/ceph/super.h b/fs/ceph/super.h -index 562f42f4a77d7..7ca74f5f70be5 100644 ---- a/fs/ceph/super.h -+++ b/fs/ceph/super.h -@@ -1374,4 +1374,7 @@ extern bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, - struct kstatfs *buf); - extern void ceph_cleanup_quotarealms_inodes(struct ceph_mds_client *mdsc); - -+bool ceph_inc_mds_stopping_blocker(struct ceph_mds_client *mdsc, -+ struct ceph_mds_session *session); -+void ceph_dec_mds_stopping_blocker(struct ceph_mds_client *mdsc); - #endif /* _FS_CEPH_SUPER_H */ -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 016925b1a0908..3c8300e08f412 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - - /* -@@ -6420,6 +6421,21 @@ __acquires(bitlock) - return ret; - } - -+static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb, -+ ext4_group_t grp) -+{ -+ if (grp < ext4_get_groups_count(sb)) -+ return EXT4_CLUSTERS_PER_GROUP(sb) - 1; -+ return (ext4_blocks_count(EXT4_SB(sb)->s_es) - -+ ext4_group_first_block_no(sb, grp) - 1) >> -+ EXT4_CLUSTER_BITS(sb); -+} -+ -+static bool ext4_trim_interrupted(void) -+{ -+ return fatal_signal_pending(current) || freezing(current); -+} -+ - static int ext4_try_to_trim_range(struct super_block *sb, - struct ext4_buddy *e4b, ext4_grpblk_t start, - ext4_grpblk_t max, ext4_grpblk_t minblocks) -@@ -6427,11 +6443,13 @@ __acquires(ext4_group_lock_ptr(sb, e4b->bd_group)) - __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) - { - ext4_grpblk_t next, count, free_count; -+ bool set_trimmed = false; - void *bitmap; - - bitmap = e4b->bd_bitmap; -- start = (e4b->bd_info->bb_first_free > start) ? -- e4b->bd_info->bb_first_free : start; -+ if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) -+ set_trimmed = true; -+ start = max(e4b->bd_info->bb_first_free, start); - count = 0; - free_count = 0; - -@@ -6445,16 +6463,14 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) - int ret = ext4_trim_extent(sb, start, next - start, e4b); - - if (ret && ret != -EOPNOTSUPP) -- break; -+ return count; - count += next - start; - } - free_count += next - start; - start = next + 1; - -- if (fatal_signal_pending(current)) { -- count = -ERESTARTSYS; -- break; -- } -+ if (ext4_trim_interrupted()) -+ return count; - - if (need_resched()) { - ext4_unlock_group(sb, e4b->bd_group); -@@ -6466,6 +6482,9 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) - break; - } - -+ if (set_trimmed) -+ EXT4_MB_GRP_SET_TRIMMED(e4b->bd_info); -+ - return count; - } - -@@ -6476,7 +6495,6 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) - * @start: first group block to examine - * @max: last group block to examine - * @minblocks: minimum extent block count -- * @set_trimmed: set the trimmed flag if at least one block is trimmed - * - * ext4_trim_all_free walks through group's block bitmap searching for free - * extents. When the free extent is found, mark it as used in group buddy -@@ -6486,7 +6504,7 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) - static ext4_grpblk_t - ext4_trim_all_free(struct super_block *sb, ext4_group_t group, - ext4_grpblk_t start, ext4_grpblk_t max, -- ext4_grpblk_t minblocks, bool set_trimmed) -+ ext4_grpblk_t minblocks) - { - struct ext4_buddy e4b; - int ret; -@@ -6503,13 +6521,10 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, - ext4_lock_group(sb, group); - - if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) || -- minblocks < EXT4_SB(sb)->s_last_trim_minblks) { -+ minblocks < EXT4_SB(sb)->s_last_trim_minblks) - ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks); -- if (ret >= 0 && set_trimmed) -- EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); -- } else { -+ else - ret = 0; -- } - - ext4_unlock_group(sb, group); - ext4_mb_unload_buddy(&e4b); -@@ -6542,7 +6557,6 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) - ext4_fsblk_t first_data_blk = - le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); - ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es); -- bool whole_group, eof = false; - int ret = 0; - - start = range->start >> sb->s_blocksize_bits; -@@ -6561,10 +6575,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) - if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) - goto out; - } -- if (end >= max_blks - 1) { -+ if (end >= max_blks - 1) - end = max_blks - 1; -- eof = true; -- } - if (end <= first_data_blk) - goto out; - if (start < first_data_blk) -@@ -6578,9 +6590,10 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) - - /* end now represents the last cluster to discard in this group */ - end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; -- whole_group = true; - - for (group = first_group; group <= last_group; group++) { -+ if (ext4_trim_interrupted()) -+ break; - grp = ext4_get_group_info(sb, group); - if (!grp) - continue; -@@ -6597,13 +6610,11 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) - * change it for the last group, note that last_cluster is - * already computed earlier by ext4_get_group_no_and_offset() - */ -- if (group == last_group) { -+ if (group == last_group) - end = last_cluster; -- whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1; -- } - if (grp->bb_free >= minlen) { - cnt = ext4_trim_all_free(sb, group, first_cluster, -- end, minlen, whole_group); -+ end, minlen); - if (cnt < 0) { - ret = cnt; - break; -@@ -6648,8 +6659,7 @@ ext4_mballoc_query_range( - - ext4_lock_group(sb, group); - -- start = (e4b.bd_info->bb_first_free > start) ? -- e4b.bd_info->bb_first_free : start; -+ start = max(e4b.bd_info->bb_first_free, start); - if (end >= EXT4_CLUSTERS_PER_GROUP(sb)) - end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; - -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index c230824ab5e6e..a982f91b71eb2 100644 ---- a/fs/f2fs/data.c -+++ b/fs/f2fs/data.c -@@ -1212,7 +1212,8 @@ int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index) - } - - struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index, -- blk_opf_t op_flags, bool for_write) -+ blk_opf_t op_flags, bool for_write, -+ pgoff_t *next_pgofs) - { - struct address_space *mapping = inode->i_mapping; - struct dnode_of_data dn; -@@ -1238,12 +1239,17 @@ struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index, - - set_new_dnode(&dn, inode, NULL, NULL, 0); - err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE); -- if (err) -+ if (err) { -+ if (err == -ENOENT && next_pgofs) -+ *next_pgofs = f2fs_get_next_page_offset(&dn, index); - goto put_err; -+ } - f2fs_put_dnode(&dn); - - if (unlikely(dn.data_blkaddr == NULL_ADDR)) { - err = -ENOENT; -+ if (next_pgofs) -+ *next_pgofs = index + 1; - goto put_err; - } - if (dn.data_blkaddr != NEW_ADDR && -@@ -1287,7 +1293,8 @@ put_err: - return ERR_PTR(err); - } - --struct page *f2fs_find_data_page(struct inode *inode, pgoff_t index) -+struct page *f2fs_find_data_page(struct inode *inode, pgoff_t index, -+ pgoff_t *next_pgofs) - { - struct address_space *mapping = inode->i_mapping; - struct page *page; -@@ -1297,7 +1304,7 @@ struct page *f2fs_find_data_page(struct inode *inode, pgoff_t index) - return page; - f2fs_put_page(page, 0); - -- page = f2fs_get_read_data_page(inode, index, 0, false); -+ page = f2fs_get_read_data_page(inode, index, 0, false, next_pgofs); - if (IS_ERR(page)) - return page; - -@@ -1322,18 +1329,14 @@ struct page *f2fs_get_lock_data_page(struct inode *inode, pgoff_t index, - { - struct address_space *mapping = inode->i_mapping; - struct page *page; --repeat: -- page = f2fs_get_read_data_page(inode, index, 0, for_write); -+ -+ page = f2fs_get_read_data_page(inode, index, 0, for_write, NULL); - if (IS_ERR(page)) - return page; - - /* wait for read completion */ - lock_page(page); -- if (unlikely(page->mapping != mapping)) { -- f2fs_put_page(page, 1); -- goto repeat; -- } -- if (unlikely(!PageUptodate(page))) { -+ if (unlikely(page->mapping != mapping || !PageUptodate(page))) { - f2fs_put_page(page, 1); - return ERR_PTR(-EIO); - } -diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c -index bf5ba75b75d24..8373eba3a1337 100644 ---- a/fs/f2fs/dir.c -+++ b/fs/f2fs/dir.c -@@ -340,6 +340,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, - unsigned int bidx, end_block; - struct page *dentry_page; - struct f2fs_dir_entry *de = NULL; -+ pgoff_t next_pgofs; - bool room = false; - int max_slots; - -@@ -350,12 +351,13 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, - le32_to_cpu(fname->hash) % nbucket); - end_block = bidx + nblock; - -- for (; bidx < end_block; bidx++) { -+ while (bidx < end_block) { - /* no need to allocate new dentry pages to all the indices */ -- dentry_page = f2fs_find_data_page(dir, bidx); -+ dentry_page = f2fs_find_data_page(dir, bidx, &next_pgofs); - if (IS_ERR(dentry_page)) { - if (PTR_ERR(dentry_page) == -ENOENT) { - room = true; -+ bidx = next_pgofs; - continue; - } else { - *res_page = dentry_page; -@@ -376,6 +378,8 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, - if (max_slots >= s) - room = true; - f2fs_put_page(dentry_page, 0); -+ -+ bidx++; - } - - if (!de && room && F2FS_I(dir)->chash != fname->hash) { -@@ -963,7 +967,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, - - bool f2fs_empty_dir(struct inode *dir) - { -- unsigned long bidx; -+ unsigned long bidx = 0; - struct page *dentry_page; - unsigned int bit_pos; - struct f2fs_dentry_block *dentry_blk; -@@ -972,13 +976,17 @@ bool f2fs_empty_dir(struct inode *dir) - if (f2fs_has_inline_dentry(dir)) - return f2fs_empty_inline_dir(dir); - -- for (bidx = 0; bidx < nblock; bidx++) { -- dentry_page = f2fs_get_lock_data_page(dir, bidx, false); -+ while (bidx < nblock) { -+ pgoff_t next_pgofs; -+ -+ dentry_page = f2fs_find_data_page(dir, bidx, &next_pgofs); - if (IS_ERR(dentry_page)) { -- if (PTR_ERR(dentry_page) == -ENOENT) -+ if (PTR_ERR(dentry_page) == -ENOENT) { -+ bidx = next_pgofs; - continue; -- else -+ } else { - return false; -+ } - } - - dentry_blk = page_address(dentry_page); -@@ -990,10 +998,12 @@ bool f2fs_empty_dir(struct inode *dir) - NR_DENTRY_IN_BLOCK, - bit_pos); - -- f2fs_put_page(dentry_page, 1); -+ f2fs_put_page(dentry_page, 0); - - if (bit_pos < NR_DENTRY_IN_BLOCK) - return false; -+ -+ bidx++; - } - return true; - } -@@ -1111,7 +1121,8 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) - goto out_free; - } - -- for (; n < npages; n++, ctx->pos = n * NR_DENTRY_IN_BLOCK) { -+ for (; n < npages; ctx->pos = n * NR_DENTRY_IN_BLOCK) { -+ pgoff_t next_pgofs; - - /* allow readdir() to be interrupted */ - if (fatal_signal_pending(current)) { -@@ -1125,11 +1136,12 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) - page_cache_sync_readahead(inode->i_mapping, ra, file, n, - min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES)); - -- dentry_page = f2fs_find_data_page(inode, n); -+ dentry_page = f2fs_find_data_page(inode, n, &next_pgofs); - if (IS_ERR(dentry_page)) { - err = PTR_ERR(dentry_page); - if (err == -ENOENT) { - err = 0; -+ n = next_pgofs; - continue; - } else { - goto out_free; -@@ -1148,6 +1160,8 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) - } - - f2fs_put_page(dentry_page, 0); -+ -+ n++; - } - out_free: - fscrypt_fname_free_buffer(&fstr); -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 37dca728ff967..f56abb39601ac 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -3784,8 +3784,9 @@ int f2fs_reserve_new_block(struct dnode_of_data *dn); - int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index); - int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index); - struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index, -- blk_opf_t op_flags, bool for_write); --struct page *f2fs_find_data_page(struct inode *inode, pgoff_t index); -+ blk_opf_t op_flags, bool for_write, pgoff_t *next_pgofs); -+struct page *f2fs_find_data_page(struct inode *inode, pgoff_t index, -+ pgoff_t *next_pgofs); - struct page *f2fs_get_lock_data_page(struct inode *inode, pgoff_t index, - bool for_write); - struct page *f2fs_get_new_data_page(struct inode *inode, -diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c -index aa4d513daa8f8..ec7212f7a9b73 100644 ---- a/fs/f2fs/gc.c -+++ b/fs/f2fs/gc.c -@@ -1600,8 +1600,8 @@ next_step: - continue; - } - -- data_page = f2fs_get_read_data_page(inode, -- start_bidx, REQ_RAHEAD, true); -+ data_page = f2fs_get_read_data_page(inode, start_bidx, -+ REQ_RAHEAD, true, NULL); - f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - if (IS_ERR(data_page)) { - iput(inode); -diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c -index 7679a68e81930..caa0a053e8a9d 100644 ---- a/fs/netfs/buffered_read.c -+++ b/fs/netfs/buffered_read.c -@@ -47,12 +47,14 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq) - xas_for_each(&xas, folio, last_page) { - loff_t pg_end; - bool pg_failed = false; -+ bool folio_started; - - if (xas_retry(&xas, folio)) - continue; - - pg_end = folio_pos(folio) + folio_size(folio) - 1; - -+ folio_started = false; - for (;;) { - loff_t sreq_end; - -@@ -60,8 +62,10 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq) - pg_failed = true; - break; - } -- if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) -+ if (!folio_started && test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) { - folio_start_fscache(folio); -+ folio_started = true; -+ } - pg_failed |= subreq_failed; - sreq_end = subreq->start + subreq->len - 1; - if (pg_end < sreq_end) -diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c -index 3bb530d4bb5ce..5a976fa343df1 100644 ---- a/fs/nfs/direct.c -+++ b/fs/nfs/direct.c -@@ -93,12 +93,10 @@ nfs_direct_handle_truncated(struct nfs_direct_req *dreq, - dreq->max_count = dreq_len; - if (dreq->count > dreq_len) - dreq->count = dreq_len; -- -- if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) -- dreq->error = hdr->error; -- else /* Clear outstanding error if this is EOF */ -- dreq->error = 0; - } -+ -+ if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && !dreq->error) -+ dreq->error = hdr->error; - } - - static void -@@ -120,6 +118,18 @@ nfs_direct_count_bytes(struct nfs_direct_req *dreq, - dreq->count = dreq_len; - } - -+static void nfs_direct_truncate_request(struct nfs_direct_req *dreq, -+ struct nfs_page *req) -+{ -+ loff_t offs = req_offset(req); -+ size_t req_start = (size_t)(offs - dreq->io_start); -+ -+ if (req_start < dreq->max_count) -+ dreq->max_count = req_start; -+ if (req_start < dreq->count) -+ dreq->count = req_start; -+} -+ - /** - * nfs_swap_rw - NFS address space operation for swap I/O - * @iocb: target I/O control block -@@ -490,7 +500,9 @@ static void nfs_direct_add_page_head(struct list_head *list, - kref_get(&head->wb_kref); - } - --static void nfs_direct_join_group(struct list_head *list, struct inode *inode) -+static void nfs_direct_join_group(struct list_head *list, -+ struct nfs_commit_info *cinfo, -+ struct inode *inode) - { - struct nfs_page *req, *subreq; - -@@ -512,7 +524,7 @@ static void nfs_direct_join_group(struct list_head *list, struct inode *inode) - nfs_release_request(subreq); - } - } while ((subreq = subreq->wb_this_page) != req); -- nfs_join_page_group(req, inode); -+ nfs_join_page_group(req, cinfo, inode); - } - } - -@@ -530,20 +542,15 @@ nfs_direct_write_scan_commit_list(struct inode *inode, - static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) - { - struct nfs_pageio_descriptor desc; -- struct nfs_page *req, *tmp; -+ struct nfs_page *req; - LIST_HEAD(reqs); - struct nfs_commit_info cinfo; -- LIST_HEAD(failed); - - nfs_init_cinfo_from_dreq(&cinfo, dreq); - nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); - -- nfs_direct_join_group(&reqs, dreq->inode); -+ nfs_direct_join_group(&reqs, &cinfo, dreq->inode); - -- dreq->count = 0; -- dreq->max_count = 0; -- list_for_each_entry(req, &reqs, wb_list) -- dreq->max_count += req->wb_bytes; - nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); - get_dreq(dreq); - -@@ -551,27 +558,40 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) - &nfs_direct_write_completion_ops); - desc.pg_dreq = dreq; - -- list_for_each_entry_safe(req, tmp, &reqs, wb_list) { -+ while (!list_empty(&reqs)) { -+ req = nfs_list_entry(reqs.next); - /* Bump the transmission count */ - req->wb_nio++; - if (!nfs_pageio_add_request(&desc, req)) { -- nfs_list_move_request(req, &failed); -- spin_lock(&cinfo.inode->i_lock); -- dreq->flags = 0; -- if (desc.pg_error < 0) -+ spin_lock(&dreq->lock); -+ if (dreq->error < 0) { -+ desc.pg_error = dreq->error; -+ } else if (desc.pg_error != -EAGAIN) { -+ dreq->flags = 0; -+ if (!desc.pg_error) -+ desc.pg_error = -EIO; - dreq->error = desc.pg_error; -- else -- dreq->error = -EIO; -- spin_unlock(&cinfo.inode->i_lock); -+ } else -+ dreq->flags = NFS_ODIRECT_RESCHED_WRITES; -+ spin_unlock(&dreq->lock); -+ break; - } - nfs_release_request(req); - } - nfs_pageio_complete(&desc); - -- while (!list_empty(&failed)) { -- req = nfs_list_entry(failed.next); -+ while (!list_empty(&reqs)) { -+ req = nfs_list_entry(reqs.next); - nfs_list_remove_request(req); - nfs_unlock_and_release_request(req); -+ if (desc.pg_error == -EAGAIN) { -+ nfs_mark_request_commit(req, NULL, &cinfo, 0); -+ } else { -+ spin_lock(&dreq->lock); -+ nfs_direct_truncate_request(dreq, req); -+ spin_unlock(&dreq->lock); -+ nfs_release_request(req); -+ } - } - - if (put_dreq(dreq)) -@@ -591,8 +611,6 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) - if (status < 0) { - /* Errors in commit are fatal */ - dreq->error = status; -- dreq->max_count = 0; -- dreq->count = 0; - dreq->flags = NFS_ODIRECT_DONE; - } else { - status = dreq->error; -@@ -603,7 +621,12 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) - while (!list_empty(&data->pages)) { - req = nfs_list_entry(data->pages.next); - nfs_list_remove_request(req); -- if (status >= 0 && !nfs_write_match_verf(verf, req)) { -+ if (status < 0) { -+ spin_lock(&dreq->lock); -+ nfs_direct_truncate_request(dreq, req); -+ spin_unlock(&dreq->lock); -+ nfs_release_request(req); -+ } else if (!nfs_write_match_verf(verf, req)) { - dreq->flags = NFS_ODIRECT_RESCHED_WRITES; - /* - * Despite the reboot, the write was successful, -@@ -611,7 +634,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) - */ - req->wb_nio = 0; - nfs_mark_request_commit(req, NULL, &cinfo, 0); -- } else /* Error or match */ -+ } else - nfs_release_request(req); - nfs_unlock_and_release_request(req); - } -@@ -664,6 +687,7 @@ static void nfs_direct_write_clear_reqs(struct nfs_direct_req *dreq) - while (!list_empty(&reqs)) { - req = nfs_list_entry(reqs.next); - nfs_list_remove_request(req); -+ nfs_direct_truncate_request(dreq, req); - nfs_release_request(req); - nfs_unlock_and_release_request(req); - } -@@ -713,7 +737,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) - } - - nfs_direct_count_bytes(dreq, hdr); -- if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags)) { -+ if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags) && -+ !test_bit(NFS_IOHDR_ERROR, &hdr->flags)) { - if (!dreq->flags) - dreq->flags = NFS_ODIRECT_DO_COMMIT; - flags = dreq->flags; -@@ -757,18 +782,23 @@ static void nfs_write_sync_pgio_error(struct list_head *head, int error) - static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) - { - struct nfs_direct_req *dreq = hdr->dreq; -+ struct nfs_page *req; -+ struct nfs_commit_info cinfo; - - trace_nfs_direct_write_reschedule_io(dreq); - -+ nfs_init_cinfo_from_dreq(&cinfo, dreq); - spin_lock(&dreq->lock); -- if (dreq->error == 0) { -+ if (dreq->error == 0) - dreq->flags = NFS_ODIRECT_RESCHED_WRITES; -- /* fake unstable write to let common nfs resend pages */ -- hdr->verf.committed = NFS_UNSTABLE; -- hdr->good_bytes = hdr->args.offset + hdr->args.count - -- hdr->io_start; -- } -+ set_bit(NFS_IOHDR_REDO, &hdr->flags); - spin_unlock(&dreq->lock); -+ while (!list_empty(&hdr->pages)) { -+ req = nfs_list_entry(hdr->pages.next); -+ nfs_list_remove_request(req); -+ nfs_unlock_request(req); -+ nfs_mark_request_commit(req, NULL, &cinfo, 0); -+ } - } - - static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { -@@ -796,9 +826,11 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, - { - struct nfs_pageio_descriptor desc; - struct inode *inode = dreq->inode; -+ struct nfs_commit_info cinfo; - ssize_t result = 0; - size_t requested_bytes = 0; - size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE); -+ bool defer = false; - - trace_nfs_direct_write_schedule_iovec(dreq); - -@@ -839,19 +871,39 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, - break; - } - -+ pgbase = 0; -+ bytes -= req_len; -+ requested_bytes += req_len; -+ pos += req_len; -+ dreq->bytes_left -= req_len; -+ -+ if (defer) { -+ nfs_mark_request_commit(req, NULL, &cinfo, 0); -+ continue; -+ } -+ - nfs_lock_request(req); - req->wb_index = pos >> PAGE_SHIFT; - req->wb_offset = pos & ~PAGE_MASK; -- if (!nfs_pageio_add_request(&desc, req)) { -+ if (nfs_pageio_add_request(&desc, req)) -+ continue; -+ -+ /* Exit on hard errors */ -+ if (desc.pg_error < 0 && desc.pg_error != -EAGAIN) { - result = desc.pg_error; - nfs_unlock_and_release_request(req); - break; - } -- pgbase = 0; -- bytes -= req_len; -- requested_bytes += req_len; -- pos += req_len; -- dreq->bytes_left -= req_len; -+ -+ /* If the error is soft, defer remaining requests */ -+ nfs_init_cinfo_from_dreq(&cinfo, dreq); -+ spin_lock(&dreq->lock); -+ dreq->flags = NFS_ODIRECT_RESCHED_WRITES; -+ spin_unlock(&dreq->lock); -+ nfs_unlock_request(req); -+ nfs_mark_request_commit(req, NULL, &cinfo, 0); -+ desc.pg_error = 0; -+ defer = true; - } - nfs_direct_release_pages(pagevec, npages); - kvfree(pagevec); -diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c -index 1ec79ccf89ad2..5c69a6e9ab3e1 100644 ---- a/fs/nfs/flexfilelayout/flexfilelayout.c -+++ b/fs/nfs/flexfilelayout/flexfilelayout.c -@@ -1235,6 +1235,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg, - case -EPFNOSUPPORT: - case -EPROTONOSUPPORT: - case -EOPNOTSUPP: -+ case -EINVAL: - case -ECONNREFUSED: - case -ECONNRESET: - case -EHOSTDOWN: -diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c -index d3051b051a564..84b345efcec00 100644 ---- a/fs/nfs/nfs4client.c -+++ b/fs/nfs/nfs4client.c -@@ -231,6 +231,8 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) - __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); - __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags); - -+ if (test_bit(NFS_CS_DS, &cl_init->init_flags)) -+ __set_bit(NFS_CS_DS, &clp->cl_flags); - /* - * Set up the connection to the server before we add add to the - * global list. -@@ -414,6 +416,8 @@ static void nfs4_add_trunk(struct nfs_client *clp, struct nfs_client *old) - .net = old->cl_net, - .servername = old->cl_hostname, - }; -+ int max_connect = test_bit(NFS_CS_PNFS, &clp->cl_flags) ? -+ clp->cl_max_connect : old->cl_max_connect; - - if (clp->cl_proto != old->cl_proto) - return; -@@ -427,7 +431,7 @@ static void nfs4_add_trunk(struct nfs_client *clp, struct nfs_client *old) - xprt_args.addrlen = clp_salen; - - rpc_clnt_add_xprt(old->cl_rpcclient, &xprt_args, -- rpc_clnt_test_and_add_xprt, NULL); -+ rpc_clnt_test_and_add_xprt, &max_connect); - } - - /** -@@ -993,6 +997,9 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, - if (mds_srv->flags & NFS_MOUNT_NORESVPORT) - __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); - -+ __set_bit(NFS_CS_DS, &cl_init.init_flags); -+ __set_bit(NFS_CS_PNFS, &cl_init.init_flags); -+ cl_init.max_connect = NFS_MAX_TRANSPORTS; - /* - * Set an authflavor equual to the MDS value. Use the MDS nfs_client - * cl_ipaddr so as to use the same EXCHANGE_ID co_ownerid as the MDS -diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index 2dec0fed1ba16..be570c65ae154 100644 ---- a/fs/nfs/nfs4proc.c -+++ b/fs/nfs/nfs4proc.c -@@ -2708,8 +2708,12 @@ static int _nfs4_proc_open(struct nfs4_opendata *data, - return status; - } - if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) { -+ struct nfs_fh *fh = &o_res->fh; -+ - nfs4_sequence_free_slot(&o_res->seq_res); -- nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, NULL); -+ if (o_arg->claim == NFS4_OPEN_CLAIM_FH) -+ fh = NFS_FH(d_inode(data->dentry)); -+ nfs4_proc_getattr(server, fh, o_res->f_attr, NULL); - } - return 0; - } -@@ -8794,6 +8798,8 @@ nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred, - #ifdef CONFIG_NFS_V4_1_MIGRATION - calldata->args.flags |= EXCHGID4_FLAG_SUPP_MOVED_MIGR; - #endif -+ if (test_bit(NFS_CS_DS, &clp->cl_flags)) -+ calldata->args.flags |= EXCHGID4_FLAG_USE_PNFS_DS; - msg.rpc_argp = &calldata->args; - msg.rpc_resp = &calldata->res; - task_setup_data.callback_data = calldata; -@@ -8871,6 +8877,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre - /* Save the EXCHANGE_ID verifier session trunk tests */ - memcpy(clp->cl_confirm.data, argp->verifier.data, - sizeof(clp->cl_confirm.data)); -+ if (resp->flags & EXCHGID4_FLAG_USE_PNFS_DS) -+ set_bit(NFS_CS_DS, &clp->cl_flags); - out: - trace_nfs4_exchange_id(clp, status); - rpc_put_task(task); -diff --git a/fs/nfs/write.c b/fs/nfs/write.c -index f41d24b54fd1f..0a8aed0ac9945 100644 ---- a/fs/nfs/write.c -+++ b/fs/nfs/write.c -@@ -58,7 +58,8 @@ static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; - static const struct nfs_commit_completion_ops nfs_commit_completion_ops; - static const struct nfs_rw_ops nfs_rw_write_ops; - static void nfs_inode_remove_request(struct nfs_page *req); --static void nfs_clear_request_commit(struct nfs_page *req); -+static void nfs_clear_request_commit(struct nfs_commit_info *cinfo, -+ struct nfs_page *req); - static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo, - struct inode *inode); - static struct nfs_page * -@@ -502,8 +503,8 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, - * the (former) group. All subrequests are removed from any write or commit - * lists, unlinked from the group and destroyed. - */ --void --nfs_join_page_group(struct nfs_page *head, struct inode *inode) -+void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo, -+ struct inode *inode) - { - struct nfs_page *subreq; - struct nfs_page *destroy_list = NULL; -@@ -533,7 +534,7 @@ nfs_join_page_group(struct nfs_page *head, struct inode *inode) - * Commit list removal accounting is done after locks are dropped */ - subreq = head; - do { -- nfs_clear_request_commit(subreq); -+ nfs_clear_request_commit(cinfo, subreq); - subreq = subreq->wb_this_page; - } while (subreq != head); - -@@ -567,8 +568,10 @@ nfs_lock_and_join_requests(struct page *page) - { - struct inode *inode = page_file_mapping(page)->host; - struct nfs_page *head; -+ struct nfs_commit_info cinfo; - int ret; - -+ nfs_init_cinfo_from_inode(&cinfo, inode); - /* - * A reference is taken only on the head request which acts as a - * reference to the whole page group - the group will not be destroyed -@@ -585,7 +588,7 @@ nfs_lock_and_join_requests(struct page *page) - return ERR_PTR(ret); - } - -- nfs_join_page_group(head, inode); -+ nfs_join_page_group(head, &cinfo, inode); - - return head; - } -@@ -956,18 +959,16 @@ nfs_clear_page_commit(struct page *page) - } - - /* Called holding the request lock on @req */ --static void --nfs_clear_request_commit(struct nfs_page *req) -+static void nfs_clear_request_commit(struct nfs_commit_info *cinfo, -+ struct nfs_page *req) - { - if (test_bit(PG_CLEAN, &req->wb_flags)) { - struct nfs_open_context *ctx = nfs_req_openctx(req); - struct inode *inode = d_inode(ctx->dentry); -- struct nfs_commit_info cinfo; - -- nfs_init_cinfo_from_inode(&cinfo, inode); - mutex_lock(&NFS_I(inode)->commit_mutex); -- if (!pnfs_clear_request_commit(req, &cinfo)) { -- nfs_request_remove_commit_list(req, &cinfo); -+ if (!pnfs_clear_request_commit(req, cinfo)) { -+ nfs_request_remove_commit_list(req, cinfo); - } - mutex_unlock(&NFS_I(inode)->commit_mutex); - nfs_clear_page_commit(req->wb_page); -diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c -index b0d22ff24b674..fcd13da5d0125 100644 ---- a/fs/nilfs2/gcinode.c -+++ b/fs/nilfs2/gcinode.c -@@ -73,10 +73,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, - struct the_nilfs *nilfs = inode->i_sb->s_fs_info; - - err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); -- if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */ -- brelse(bh); -+ if (unlikely(err)) /* -EIO, -ENOMEM, -ENOENT */ - goto failed; -- } - } - - lock_buffer(bh); -@@ -102,6 +100,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, - failed: - unlock_page(bh->b_page); - put_page(bh->b_page); -+ if (unlikely(err)) -+ brelse(bh); - return err; - } - -diff --git a/fs/proc/internal.h b/fs/proc/internal.h -index b701d0207edf0..6b921826d85b6 100644 ---- a/fs/proc/internal.h -+++ b/fs/proc/internal.h -@@ -289,9 +289,7 @@ struct proc_maps_private { - struct inode *inode; - struct task_struct *task; - struct mm_struct *mm; --#ifdef CONFIG_MMU - struct vma_iterator iter; --#endif - #ifdef CONFIG_NUMA - struct mempolicy *task_mempolicy; - #endif -diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c -index 2fd06f52b6a44..dc05780f93e13 100644 ---- a/fs/proc/task_nommu.c -+++ b/fs/proc/task_nommu.c -@@ -188,15 +188,28 @@ static int show_map(struct seq_file *m, void *_p) - return nommu_vma_show(m, _p); - } - --static void *m_start(struct seq_file *m, loff_t *pos) -+static struct vm_area_struct *proc_get_vma(struct proc_maps_private *priv, -+ loff_t *ppos) -+{ -+ struct vm_area_struct *vma = vma_next(&priv->iter); -+ -+ if (vma) { -+ *ppos = vma->vm_start; -+ } else { -+ *ppos = -1UL; -+ } -+ -+ return vma; -+} -+ -+static void *m_start(struct seq_file *m, loff_t *ppos) - { - struct proc_maps_private *priv = m->private; -+ unsigned long last_addr = *ppos; - struct mm_struct *mm; -- struct vm_area_struct *vma; -- unsigned long addr = *pos; - -- /* See m_next(). Zero at the start or after lseek. */ -- if (addr == -1UL) -+ /* See proc_get_vma(). Zero at the start or after lseek. */ -+ if (last_addr == -1UL) - return NULL; - - /* pin the task and mm whilst we play with them */ -@@ -205,44 +218,41 @@ static void *m_start(struct seq_file *m, loff_t *pos) - return ERR_PTR(-ESRCH); - - mm = priv->mm; -- if (!mm || !mmget_not_zero(mm)) -+ if (!mm || !mmget_not_zero(mm)) { -+ put_task_struct(priv->task); -+ priv->task = NULL; - return NULL; -+ } - - if (mmap_read_lock_killable(mm)) { - mmput(mm); -+ put_task_struct(priv->task); -+ priv->task = NULL; - return ERR_PTR(-EINTR); - } - -- /* start the next element from addr */ -- vma = find_vma(mm, addr); -- if (vma) -- return vma; -+ vma_iter_init(&priv->iter, mm, last_addr); - -- mmap_read_unlock(mm); -- mmput(mm); -- return NULL; -+ return proc_get_vma(priv, ppos); - } - --static void m_stop(struct seq_file *m, void *_vml) -+static void m_stop(struct seq_file *m, void *v) - { - struct proc_maps_private *priv = m->private; -+ struct mm_struct *mm = priv->mm; - -- if (!IS_ERR_OR_NULL(_vml)) { -- mmap_read_unlock(priv->mm); -- mmput(priv->mm); -- } -- if (priv->task) { -- put_task_struct(priv->task); -- priv->task = NULL; -- } -+ if (!priv->task) -+ return; -+ -+ mmap_read_unlock(mm); -+ mmput(mm); -+ put_task_struct(priv->task); -+ priv->task = NULL; - } - --static void *m_next(struct seq_file *m, void *_p, loff_t *pos) -+static void *m_next(struct seq_file *m, void *_p, loff_t *ppos) - { -- struct vm_area_struct *vma = _p; -- -- *pos = vma->vm_end; -- return find_vma(vma->vm_mm, vma->vm_end); -+ return proc_get_vma(m->private, ppos); - } - - static const struct seq_operations proc_pid_maps_ops = { -diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h -index 03f34ec63e10d..39602f39aea8f 100644 ---- a/fs/smb/client/cifsglob.h -+++ b/fs/smb/client/cifsglob.h -@@ -1776,6 +1776,7 @@ static inline bool is_retryable_error(int error) - #define MID_RETRY_NEEDED 8 /* session closed while this request out */ - #define MID_RESPONSE_MALFORMED 0x10 - #define MID_SHUTDOWN 0x20 -+#define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */ - - /* Flags */ - #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ -diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c -index e2e2ef0fa9a0f..f4818599c00a2 100644 ---- a/fs/smb/client/fs_context.c -+++ b/fs/smb/client/fs_context.c -@@ -1487,6 +1487,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, - - cifs_parse_mount_err: - kfree_sensitive(ctx->password); -+ ctx->password = NULL; - return -EINVAL; - } - -diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c -index 92c1ed9304be7..9531ea2430899 100644 ---- a/fs/smb/client/inode.c -+++ b/fs/smb/client/inode.c -@@ -2605,7 +2605,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, - } - - cifsFileInfo_put(cfile); -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - } - - int cifs_truncate_page(struct address_space *mapping, loff_t from) -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index 1387d5126f53b..efff7137412b4 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -292,7 +292,7 @@ smb2_adjust_credits(struct TCP_Server_Info *server, - cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)", - credits->value, new_val); - -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - } - - spin_lock(&server->req_lock); -@@ -1155,7 +1155,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, - /* Use a fudge factor of 256 bytes in case we collide - * with a different set_EAs command. - */ -- if(CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - -+ if (CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - - MAX_SMB2_CLOSE_RESPONSE_SIZE - 256 < - used_len + ea_name_len + ea_value_len + 1) { - rc = -ENOSPC; -@@ -4721,7 +4721,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, - - if (shdr->Command != SMB2_READ) { - cifs_server_dbg(VFS, "only big read responses are supported\n"); -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - } - - if (server->ops->is_session_expired && -diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c -index e03ffcf7e201c..87aea456ee903 100644 ---- a/fs/smb/client/transport.c -+++ b/fs/smb/client/transport.c -@@ -35,6 +35,8 @@ - void - cifs_wake_up_task(struct mid_q_entry *mid) - { -+ if (mid->mid_state == MID_RESPONSE_RECEIVED) -+ mid->mid_state = MID_RESPONSE_READY; - wake_up_process(mid->callback_data); - } - -@@ -87,7 +89,8 @@ static void __release_mid(struct kref *refcount) - struct TCP_Server_Info *server = midEntry->server; - - if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && -- midEntry->mid_state == MID_RESPONSE_RECEIVED && -+ (midEntry->mid_state == MID_RESPONSE_RECEIVED || -+ midEntry->mid_state == MID_RESPONSE_READY) && - server->ops->handle_cancelled_mid) - server->ops->handle_cancelled_mid(midEntry, server); - -@@ -759,7 +762,8 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ) - int error; - - error = wait_event_state(server->response_q, -- midQ->mid_state != MID_REQUEST_SUBMITTED, -+ midQ->mid_state != MID_REQUEST_SUBMITTED && -+ midQ->mid_state != MID_RESPONSE_RECEIVED, - (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE)); - if (error < 0) - return -ERESTARTSYS; -@@ -912,7 +916,7 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) - - spin_lock(&server->mid_lock); - switch (mid->mid_state) { -- case MID_RESPONSE_RECEIVED: -+ case MID_RESPONSE_READY: - spin_unlock(&server->mid_lock); - return rc; - case MID_RETRY_NEEDED: -@@ -1011,6 +1015,9 @@ cifs_compound_callback(struct mid_q_entry *mid) - credits.instance = server->reconnect_instance; - - add_credits(server, &credits, mid->optype); -+ -+ if (mid->mid_state == MID_RESPONSE_RECEIVED) -+ mid->mid_state = MID_RESPONSE_READY; - } - - static void -@@ -1206,7 +1213,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, - send_cancel(server, &rqst[i], midQ[i]); - spin_lock(&server->mid_lock); - midQ[i]->mid_flags |= MID_WAIT_CANCELLED; -- if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { -+ if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED || -+ midQ[i]->mid_state == MID_RESPONSE_RECEIVED) { - midQ[i]->callback = cifs_cancelled_callback; - cancelled_mid[i] = true; - credits[i].value = 0; -@@ -1227,7 +1235,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, - } - - if (!midQ[i]->resp_buf || -- midQ[i]->mid_state != MID_RESPONSE_RECEIVED) { -+ midQ[i]->mid_state != MID_RESPONSE_READY) { - rc = -EIO; - cifs_dbg(FYI, "Bad MID state?\n"); - goto out; -@@ -1414,7 +1422,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, - if (rc != 0) { - send_cancel(server, &rqst, midQ); - spin_lock(&server->mid_lock); -- if (midQ->mid_state == MID_REQUEST_SUBMITTED) { -+ if (midQ->mid_state == MID_REQUEST_SUBMITTED || -+ midQ->mid_state == MID_RESPONSE_RECEIVED) { - /* no longer considered to be "in-flight" */ - midQ->callback = release_mid; - spin_unlock(&server->mid_lock); -@@ -1431,7 +1440,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, - } - - if (!midQ->resp_buf || !out_buf || -- midQ->mid_state != MID_RESPONSE_RECEIVED) { -+ midQ->mid_state != MID_RESPONSE_READY) { - rc = -EIO; - cifs_server_dbg(VFS, "Bad MID state?\n"); - goto out; -@@ -1555,14 +1564,16 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, - - /* Wait for a reply - allow signals to interrupt. */ - rc = wait_event_interruptible(server->response_q, -- (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) || -+ (!(midQ->mid_state == MID_REQUEST_SUBMITTED || -+ midQ->mid_state == MID_RESPONSE_RECEIVED)) || - ((server->tcpStatus != CifsGood) && - (server->tcpStatus != CifsNew))); - - /* Were we interrupted by a signal ? */ - spin_lock(&server->srv_lock); - if ((rc == -ERESTARTSYS) && -- (midQ->mid_state == MID_REQUEST_SUBMITTED) && -+ (midQ->mid_state == MID_REQUEST_SUBMITTED || -+ midQ->mid_state == MID_RESPONSE_RECEIVED) && - ((server->tcpStatus == CifsGood) || - (server->tcpStatus == CifsNew))) { - spin_unlock(&server->srv_lock); -@@ -1593,7 +1604,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, - if (rc) { - send_cancel(server, &rqst, midQ); - spin_lock(&server->mid_lock); -- if (midQ->mid_state == MID_REQUEST_SUBMITTED) { -+ if (midQ->mid_state == MID_REQUEST_SUBMITTED || -+ midQ->mid_state == MID_RESPONSE_RECEIVED) { - /* no longer considered to be "in-flight" */ - midQ->callback = release_mid; - spin_unlock(&server->mid_lock); -@@ -1613,7 +1625,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, - return rc; - - /* rcvd frame is ok */ -- if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) { -+ if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) { - rc = -EIO; - cifs_tcon_dbg(VFS, "Bad MID state?\n"); - goto out; -diff --git a/include/linux/bpf.h b/include/linux/bpf.h -index b3d3aa8437dce..1ed2ec035e779 100644 ---- a/include/linux/bpf.h -+++ b/include/linux/bpf.h -@@ -301,7 +301,7 @@ static inline void bpf_long_memcpy(void *dst, const void *src, u32 size) - - size /= sizeof(long); - while (size--) -- *ldst++ = *lsrc++; -+ data_race(*ldst++ = *lsrc++); - } - - /* copy everything but bpf_spin_lock, bpf_timer, and kptrs. There could be one of each. */ -diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h -index 2b98720084285..0f02bbb205735 100644 ---- a/include/linux/btf_ids.h -+++ b/include/linux/btf_ids.h -@@ -49,7 +49,7 @@ word \ - ____BTF_ID(symbol, word) - - #define __ID(prefix) \ -- __PASTE(prefix, __COUNTER__) -+ __PASTE(__PASTE(prefix, __COUNTER__), __LINE__) - - /* - * The BTF_ID defines unique symbol for each ID pointing -diff --git a/include/linux/if_team.h b/include/linux/if_team.h -index 8de6b6e678295..34bcba5a70677 100644 ---- a/include/linux/if_team.h -+++ b/include/linux/if_team.h -@@ -189,6 +189,8 @@ struct team { - struct net_device *dev; /* associated netdevice */ - struct team_pcpu_stats __percpu *pcpu_stats; - -+ const struct header_ops *header_ops_cache; -+ - struct mutex lock; /* used for overall locking, e.g. port lists write */ - - /* -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index a92bce40b04b3..4a1dc88ddbff9 100644 ---- a/include/linux/interrupt.h -+++ b/include/linux/interrupt.h -@@ -569,8 +569,12 @@ enum - * 2) rcu_report_dead() reports the final quiescent states. - * - * _ IRQ_POLL: irq_poll_cpu_dead() migrates the queue -+ * -+ * _ (HR)TIMER_SOFTIRQ: (hr)timers_dead_cpu() migrates the queue - */ --#define SOFTIRQ_HOTPLUG_SAFE_MASK (BIT(RCU_SOFTIRQ) | BIT(IRQ_POLL_SOFTIRQ)) -+#define SOFTIRQ_HOTPLUG_SAFE_MASK (BIT(TIMER_SOFTIRQ) | BIT(IRQ_POLL_SOFTIRQ) |\ -+ BIT(HRTIMER_SOFTIRQ) | BIT(RCU_SOFTIRQ)) -+ - - /* map softirq index to softirq name. update 'softirq_to_name' in - * kernel/softirq.c when adding a new softirq. -diff --git a/include/linux/libata.h b/include/linux/libata.h -index 4c9b322bb3d88..a9ec8d97a715b 100644 ---- a/include/linux/libata.h -+++ b/include/linux/libata.h -@@ -253,7 +253,7 @@ enum { - * advised to wait only for the following duration before - * doing SRST. - */ -- ATA_TMOUT_PMP_SRST_WAIT = 5000, -+ ATA_TMOUT_PMP_SRST_WAIT = 10000, - - /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might - * be a spurious PHY event, so ignore the first PHY event that -@@ -1136,6 +1136,7 @@ extern int ata_std_bios_param(struct scsi_device *sdev, - struct block_device *bdev, - sector_t capacity, int geom[]); - extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); -+extern int ata_scsi_slave_alloc(struct scsi_device *sdev); - extern int ata_scsi_slave_config(struct scsi_device *sdev); - extern void ata_scsi_slave_destroy(struct scsi_device *sdev); - extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, -@@ -1384,6 +1385,7 @@ extern const struct attribute_group *ata_common_sdev_groups[]; - .this_id = ATA_SHT_THIS_ID, \ - .emulated = ATA_SHT_EMULATED, \ - .proc_name = drv_name, \ -+ .slave_alloc = ata_scsi_slave_alloc, \ - .slave_destroy = ata_scsi_slave_destroy, \ - .bios_param = ata_std_bios_param, \ - .unlock_native_capacity = ata_scsi_unlock_native_capacity,\ -diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h -index 099521835cd14..50a078a31734c 100644 ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -902,7 +902,7 @@ unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec, - return READ_ONCE(mz->lru_zone_size[zone_idx][lru]); - } - --void mem_cgroup_handle_over_high(void); -+void mem_cgroup_handle_over_high(gfp_t gfp_mask); - - unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); - -@@ -1437,7 +1437,7 @@ static inline void mem_cgroup_unlock_pages(void) - rcu_read_unlock(); - } - --static inline void mem_cgroup_handle_over_high(void) -+static inline void mem_cgroup_handle_over_high(gfp_t gfp_mask) - { - } - -diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h -index ea2f7e6b1b0b5..ef8ba5fbc6503 100644 ---- a/include/linux/nfs_fs_sb.h -+++ b/include/linux/nfs_fs_sb.h -@@ -48,6 +48,7 @@ struct nfs_client { - #define NFS_CS_NOPING 6 /* - don't ping on connect */ - #define NFS_CS_DS 7 /* - Server is a DS */ - #define NFS_CS_REUSEPORT 8 /* - reuse src port on reconnect */ -+#define NFS_CS_PNFS 9 /* - Server used for pnfs */ - struct sockaddr_storage cl_addr; /* server identifier */ - size_t cl_addrlen; - char * cl_hostname; /* hostname of server */ -diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h -index ba7e2e4b09264..e39a8cf8b1797 100644 ---- a/include/linux/nfs_page.h -+++ b/include/linux/nfs_page.h -@@ -145,7 +145,9 @@ extern void nfs_unlock_request(struct nfs_page *req); - extern void nfs_unlock_and_release_request(struct nfs_page *); - extern struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req); - extern int nfs_page_group_lock_subrequests(struct nfs_page *head); --extern void nfs_join_page_group(struct nfs_page *head, struct inode *inode); -+extern void nfs_join_page_group(struct nfs_page *head, -+ struct nfs_commit_info *cinfo, -+ struct inode *inode); - extern int nfs_page_group_lock(struct nfs_page *); - extern void nfs_page_group_unlock(struct nfs_page *); - extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); -diff --git a/include/linux/resume_user_mode.h b/include/linux/resume_user_mode.h -index 2851894544496..f8f3e958e9cf2 100644 ---- a/include/linux/resume_user_mode.h -+++ b/include/linux/resume_user_mode.h -@@ -55,7 +55,7 @@ static inline void resume_user_mode_work(struct pt_regs *regs) - } - #endif - -- mem_cgroup_handle_over_high(); -+ mem_cgroup_handle_over_high(GFP_KERNEL); - blkcg_maybe_throttle_current(); - - rseq_handle_notify_resume(NULL, regs); -diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h -index 3926e90279477..d778af83c8f36 100644 ---- a/include/linux/seqlock.h -+++ b/include/linux/seqlock.h -@@ -512,8 +512,8 @@ do { \ - - static inline void do_write_seqcount_begin_nested(seqcount_t *s, int subclass) - { -- do_raw_write_seqcount_begin(s); - seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_); -+ do_raw_write_seqcount_begin(s); - } - - /** -diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h -index c752b6f509791..d1f81a6d7773b 100644 ---- a/include/net/netfilter/nf_tables.h -+++ b/include/net/netfilter/nf_tables.h -@@ -507,6 +507,7 @@ struct nft_set_elem_expr { - * - * @list: table set list node - * @bindings: list of set bindings -+ * @refs: internal refcounting for async set destruction - * @table: table this set belongs to - * @net: netnamespace this set belongs to - * @name: name of the set -@@ -528,6 +529,7 @@ struct nft_set_elem_expr { - * @expr: stateful expression - * @ops: set ops - * @flags: set flags -+ * @dead: set will be freed, never cleared - * @genmask: generation mask - * @klen: key length - * @dlen: data length -@@ -536,6 +538,7 @@ struct nft_set_elem_expr { - struct nft_set { - struct list_head list; - struct list_head bindings; -+ refcount_t refs; - struct nft_table *table; - possible_net_t net; - char *name; -@@ -557,7 +560,8 @@ struct nft_set { - struct list_head pending_update; - /* runtime data below here */ - const struct nft_set_ops *ops ____cacheline_aligned; -- u16 flags:14, -+ u16 flags:13, -+ dead:1, - genmask:2; - u8 klen; - u8 dlen; -@@ -578,6 +582,11 @@ static inline void *nft_set_priv(const struct nft_set *set) - return (void *)set->data; - } - -+static inline bool nft_set_gc_is_pending(const struct nft_set *s) -+{ -+ return refcount_read(&s->refs) != 1; -+} -+ - static inline struct nft_set *nft_set_container_of(const void *priv) - { - return (void *)priv - offsetof(struct nft_set, data); -@@ -591,7 +600,6 @@ struct nft_set *nft_set_lookup_global(const struct net *net, - - struct nft_set_ext *nft_set_catchall_lookup(const struct net *net, - const struct nft_set *set); --void *nft_set_catchall_gc(const struct nft_set *set); - - static inline unsigned long nft_set_gc_interval(const struct nft_set *set) - { -@@ -808,62 +816,6 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem, - void nf_tables_set_elem_destroy(const struct nft_ctx *ctx, - const struct nft_set *set, void *elem); - --/** -- * struct nft_set_gc_batch_head - nf_tables set garbage collection batch -- * -- * @rcu: rcu head -- * @set: set the elements belong to -- * @cnt: count of elements -- */ --struct nft_set_gc_batch_head { -- struct rcu_head rcu; -- const struct nft_set *set; -- unsigned int cnt; --}; -- --#define NFT_SET_GC_BATCH_SIZE ((PAGE_SIZE - \ -- sizeof(struct nft_set_gc_batch_head)) / \ -- sizeof(void *)) -- --/** -- * struct nft_set_gc_batch - nf_tables set garbage collection batch -- * -- * @head: GC batch head -- * @elems: garbage collection elements -- */ --struct nft_set_gc_batch { -- struct nft_set_gc_batch_head head; -- void *elems[NFT_SET_GC_BATCH_SIZE]; --}; -- --struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set, -- gfp_t gfp); --void nft_set_gc_batch_release(struct rcu_head *rcu); -- --static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb) --{ -- if (gcb != NULL) -- call_rcu(&gcb->head.rcu, nft_set_gc_batch_release); --} -- --static inline struct nft_set_gc_batch * --nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb, -- gfp_t gfp) --{ -- if (gcb != NULL) { -- if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems)) -- return gcb; -- nft_set_gc_batch_complete(gcb); -- } -- return nft_set_gc_batch_alloc(set, gfp); --} -- --static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb, -- void *elem) --{ -- gcb->elems[gcb->head.cnt++] = elem; --} -- - struct nft_expr_ops; - /** - * struct nft_expr_type - nf_tables expression type -@@ -1542,39 +1494,30 @@ static inline void nft_set_elem_change_active(const struct net *net, - - #endif /* IS_ENABLED(CONFIG_NF_TABLES) */ - --/* -- * We use a free bit in the genmask field to indicate the element -- * is busy, meaning it is currently being processed either by -- * the netlink API or GC. -- * -- * Even though the genmask is only a single byte wide, this works -- * because the extension structure if fully constant once initialized, -- * so there are no non-atomic write accesses unless it is already -- * marked busy. -- */ --#define NFT_SET_ELEM_BUSY_MASK (1 << 2) -+#define NFT_SET_ELEM_DEAD_MASK (1 << 2) - - #if defined(__LITTLE_ENDIAN_BITFIELD) --#define NFT_SET_ELEM_BUSY_BIT 2 -+#define NFT_SET_ELEM_DEAD_BIT 2 - #elif defined(__BIG_ENDIAN_BITFIELD) --#define NFT_SET_ELEM_BUSY_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2) -+#define NFT_SET_ELEM_DEAD_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2) - #else - #error - #endif - --static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext) -+static inline void nft_set_elem_dead(struct nft_set_ext *ext) - { - unsigned long *word = (unsigned long *)ext; - - BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0); -- return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word); -+ set_bit(NFT_SET_ELEM_DEAD_BIT, word); - } - --static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext) -+static inline int nft_set_elem_is_dead(const struct nft_set_ext *ext) - { - unsigned long *word = (unsigned long *)ext; - -- clear_bit(NFT_SET_ELEM_BUSY_BIT, word); -+ BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0); -+ return test_bit(NFT_SET_ELEM_DEAD_BIT, word); - } - - /** -@@ -1708,6 +1651,39 @@ struct nft_trans_flowtable { - #define nft_trans_flowtable_flags(trans) \ - (((struct nft_trans_flowtable *)trans->data)->flags) - -+#define NFT_TRANS_GC_BATCHCOUNT 256 -+ -+struct nft_trans_gc { -+ struct list_head list; -+ struct net *net; -+ struct nft_set *set; -+ u32 seq; -+ u16 count; -+ void *priv[NFT_TRANS_GC_BATCHCOUNT]; -+ struct rcu_head rcu; -+}; -+ -+struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set, -+ unsigned int gc_seq, gfp_t gfp); -+void nft_trans_gc_destroy(struct nft_trans_gc *trans); -+ -+struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc, -+ unsigned int gc_seq, gfp_t gfp); -+void nft_trans_gc_queue_async_done(struct nft_trans_gc *gc); -+ -+struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp); -+void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans); -+ -+void nft_trans_gc_elem_add(struct nft_trans_gc *gc, void *priv); -+ -+struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc, -+ unsigned int gc_seq); -+struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc); -+ -+void nft_setelem_data_deactivate(const struct net *net, -+ const struct nft_set *set, -+ struct nft_set_elem *elem); -+ - int __init nft_chain_filter_init(void); - void nft_chain_filter_fini(void); - -@@ -1735,6 +1711,7 @@ struct nftables_pernet { - u64 table_handle; - unsigned int base_seq; - u8 validate_state; -+ unsigned int gc_seq; - }; - - extern unsigned int nf_tables_net_id; -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index 51b9aa640ad2a..53bc487947197 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -1837,7 +1837,9 @@ union bpf_attr { - * performed again, if the helper is used in combination with - * direct packet access. - * Return -- * 0 on success, or a negative error in case of failure. -+ * 0 on success, or a negative error in case of failure. Positive -+ * error indicates a potential drop or congestion in the target -+ * device. The particular positive error codes are not defined. - * - * u64 bpf_get_current_pid_tgid(void) - * Description -diff --git a/io_uring/fs.c b/io_uring/fs.c -index 7100c293c13a8..27676e0150049 100644 ---- a/io_uring/fs.c -+++ b/io_uring/fs.c -@@ -243,7 +243,7 @@ int io_linkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) - struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link); - const char __user *oldf, *newf; - -- if (sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in) -+ if (sqe->buf_index || sqe->splice_fd_in) - return -EINVAL; - if (unlikely(req->flags & REQ_F_FIXED_FILE)) - return -EBADF; -diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c -index 8a5e060de63bc..a8fe640318c6c 100644 ---- a/kernel/bpf/queue_stack_maps.c -+++ b/kernel/bpf/queue_stack_maps.c -@@ -102,7 +102,12 @@ static int __queue_map_get(struct bpf_map *map, void *value, bool delete) - int err = 0; - void *ptr; - -- raw_spin_lock_irqsave(&qs->lock, flags); -+ if (in_nmi()) { -+ if (!raw_spin_trylock_irqsave(&qs->lock, flags)) -+ return -EBUSY; -+ } else { -+ raw_spin_lock_irqsave(&qs->lock, flags); -+ } - - if (queue_stack_map_is_empty(qs)) { - memset(value, 0, qs->map.value_size); -@@ -132,7 +137,12 @@ static int __stack_map_get(struct bpf_map *map, void *value, bool delete) - void *ptr; - u32 index; - -- raw_spin_lock_irqsave(&qs->lock, flags); -+ if (in_nmi()) { -+ if (!raw_spin_trylock_irqsave(&qs->lock, flags)) -+ return -EBUSY; -+ } else { -+ raw_spin_lock_irqsave(&qs->lock, flags); -+ } - - if (queue_stack_map_is_empty(qs)) { - memset(value, 0, qs->map.value_size); -@@ -197,7 +207,12 @@ static int queue_stack_map_push_elem(struct bpf_map *map, void *value, - if (flags & BPF_NOEXIST || flags > BPF_EXIST) - return -EINVAL; - -- raw_spin_lock_irqsave(&qs->lock, irq_flags); -+ if (in_nmi()) { -+ if (!raw_spin_trylock_irqsave(&qs->lock, irq_flags)) -+ return -EBUSY; -+ } else { -+ raw_spin_lock_irqsave(&qs->lock, irq_flags); -+ } - - if (queue_stack_map_is_full(qs)) { - if (!replace) { -diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c -index 18c93c2276cae..3ff7089d11a92 100644 ---- a/kernel/dma/debug.c -+++ b/kernel/dma/debug.c -@@ -603,15 +603,19 @@ static struct dma_debug_entry *__dma_entry_alloc(void) - return entry; - } - --static void __dma_entry_alloc_check_leak(void) -+/* -+ * This should be called outside of free_entries_lock scope to avoid potential -+ * deadlocks with serial consoles that use DMA. -+ */ -+static void __dma_entry_alloc_check_leak(u32 nr_entries) - { -- u32 tmp = nr_total_entries % nr_prealloc_entries; -+ u32 tmp = nr_entries % nr_prealloc_entries; - - /* Shout each time we tick over some multiple of the initial pool */ - if (tmp < DMA_DEBUG_DYNAMIC_ENTRIES) { - pr_info("dma_debug_entry pool grown to %u (%u00%%)\n", -- nr_total_entries, -- (nr_total_entries / nr_prealloc_entries)); -+ nr_entries, -+ (nr_entries / nr_prealloc_entries)); - } - } - -@@ -622,8 +626,10 @@ static void __dma_entry_alloc_check_leak(void) - */ - static struct dma_debug_entry *dma_entry_alloc(void) - { -+ bool alloc_check_leak = false; - struct dma_debug_entry *entry; - unsigned long flags; -+ u32 nr_entries; - - spin_lock_irqsave(&free_entries_lock, flags); - if (num_free_entries == 0) { -@@ -633,13 +639,17 @@ static struct dma_debug_entry *dma_entry_alloc(void) - pr_err("debugging out of memory - disabling\n"); - return NULL; - } -- __dma_entry_alloc_check_leak(); -+ alloc_check_leak = true; -+ nr_entries = nr_total_entries; - } - - entry = __dma_entry_alloc(); - - spin_unlock_irqrestore(&free_entries_lock, flags); - -+ if (alloc_check_leak) -+ __dma_entry_alloc_check_leak(nr_entries); -+ - #ifdef CONFIG_STACKTRACE - entry->stack_len = stack_trace_save(entry->stack_entries, - ARRAY_SIZE(entry->stack_entries), -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 0f6a92737c912..55d13980e29fd 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -9019,7 +9019,7 @@ void __init init_idle(struct task_struct *idle, int cpu) - * PF_KTHREAD should already be set at this point; regardless, make it - * look like a proper per-CPU kthread. - */ -- idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY; -+ idle->flags |= PF_KTHREAD | PF_NO_SETAFFINITY; - kthread_set_per_cpu(idle, cpu); - - #ifdef CONFIG_SMP -diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c -index a286e726eb4b8..42c40cfdf8363 100644 ---- a/kernel/sched/cpupri.c -+++ b/kernel/sched/cpupri.c -@@ -101,6 +101,7 @@ static inline int __cpupri_find(struct cpupri *cp, struct task_struct *p, - - if (lowest_mask) { - cpumask_and(lowest_mask, &p->cpus_mask, vec->mask); -+ cpumask_and(lowest_mask, lowest_mask, cpu_active_mask); - - /* - * We have to ensure that we have at least one bit -diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c -index f26ab2675f7d7..200a0fac03b8e 100644 ---- a/kernel/sched/idle.c -+++ b/kernel/sched/idle.c -@@ -394,6 +394,7 @@ EXPORT_SYMBOL_GPL(play_idle_precise); - - void cpu_startup_entry(enum cpuhp_state state) - { -+ current->flags |= PF_IDLE; - arch_cpu_idle_prepare(); - cpuhp_online_idle(state); - while (1) -diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c -index 9fc5db194027b..8c77c54e6348b 100644 ---- a/kernel/trace/bpf_trace.c -+++ b/kernel/trace/bpf_trace.c -@@ -2684,6 +2684,17 @@ static void symbols_swap_r(void *a, void *b, int size, const void *priv) - } - } - -+static int addrs_check_error_injection_list(unsigned long *addrs, u32 cnt) -+{ -+ u32 i; -+ -+ for (i = 0; i < cnt; i++) { -+ if (!within_error_injection_list(addrs[i])) -+ return -EINVAL; -+ } -+ return 0; -+} -+ - int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) - { - struct bpf_kprobe_multi_link *link = NULL; -@@ -2761,6 +2772,11 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr - goto error; - } - -+ if (prog->kprobe_override && addrs_check_error_injection_list(addrs, cnt)) { -+ err = -EINVAL; -+ goto error; -+ } -+ - link = kzalloc(sizeof(*link), GFP_KERNEL); - if (!link) { - err = -ENOMEM; -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index de55107aef5d5..2f562cf961e0a 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -1142,6 +1142,9 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu, - if (full) { - poll_wait(filp, &work->full_waiters, poll_table); - work->full_waiters_pending = true; -+ if (!cpu_buffer->shortest_full || -+ cpu_buffer->shortest_full > full) -+ cpu_buffer->shortest_full = full; - } else { - poll_wait(filp, &work->waiters, poll_table); - work->waiters_pending = true; -@@ -2212,6 +2215,8 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, - err = -ENOMEM; - goto out_err; - } -+ -+ cond_resched(); - } - - cpus_read_lock(); -@@ -2386,6 +2391,11 @@ rb_iter_head_event(struct ring_buffer_iter *iter) - */ - commit = rb_page_commit(iter_head_page); - smp_rmb(); -+ -+ /* An event needs to be at least 8 bytes in size */ -+ if (iter->head > commit - 8) -+ goto reset; -+ - event = __rb_page_index(iter_head_page, iter->head); - length = rb_event_length(event); - -diff --git a/mm/damon/vaddr-test.h b/mm/damon/vaddr-test.h -index bce37c4875402..e939598aff94b 100644 ---- a/mm/damon/vaddr-test.h -+++ b/mm/damon/vaddr-test.h -@@ -140,6 +140,8 @@ static void damon_do_test_apply_three_regions(struct kunit *test, - KUNIT_EXPECT_EQ(test, r->ar.start, expected[i * 2]); - KUNIT_EXPECT_EQ(test, r->ar.end, expected[i * 2 + 1]); - } -+ -+ damon_destroy_target(t); - } - - /* -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index 67b6d8238b3ed..dacbaf4f7b2c4 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -2545,7 +2545,7 @@ static unsigned long calculate_high_delay(struct mem_cgroup *memcg, - * Scheduled by try_charge() to be executed from the userland return path - * and reclaims memory over the high limit. - */ --void mem_cgroup_handle_over_high(void) -+void mem_cgroup_handle_over_high(gfp_t gfp_mask) - { - unsigned long penalty_jiffies; - unsigned long pflags; -@@ -2573,7 +2573,7 @@ retry_reclaim: - */ - nr_reclaimed = reclaim_high(memcg, - in_retry ? SWAP_CLUSTER_MAX : nr_pages, -- GFP_KERNEL); -+ gfp_mask); - - /* - * memory.high is breached and reclaim is unable to keep up. Throttle -@@ -2809,7 +2809,7 @@ done_restock: - if (current->memcg_nr_pages_over_high > MEMCG_CHARGE_BATCH && - !(current->flags & PF_MEMALLOC) && - gfpflags_allow_blocking(gfp_mask)) { -- mem_cgroup_handle_over_high(); -+ mem_cgroup_handle_over_high(gfp_mask); - } - return 0; - } -@@ -3842,8 +3842,11 @@ static ssize_t mem_cgroup_write(struct kernfs_open_file *of, - ret = mem_cgroup_resize_max(memcg, nr_pages, true); - break; - case _KMEM: -- /* kmem.limit_in_bytes is deprecated. */ -- ret = -EOPNOTSUPP; -+ pr_warn_once("kmem.limit_in_bytes is deprecated and will be removed. " -+ "Writing any value to this file has no effect. " -+ "Please report your usecase to linux-mm@kvack.org if you " -+ "depend on this functionality.\n"); -+ ret = 0; - break; - case _TCP: - ret = memcg_update_tcp_max(memcg, nr_pages); -diff --git a/mm/slab_common.c b/mm/slab_common.c -index 0042fb2730d1e..4736c0e6093fa 100644 ---- a/mm/slab_common.c -+++ b/mm/slab_common.c -@@ -474,7 +474,7 @@ void slab_kmem_cache_release(struct kmem_cache *s) - - void kmem_cache_destroy(struct kmem_cache *s) - { -- int refcnt; -+ int err = -EBUSY; - bool rcu_set; - - if (unlikely(!s) || !kasan_check_byte(s)) -@@ -485,17 +485,17 @@ void kmem_cache_destroy(struct kmem_cache *s) - - rcu_set = s->flags & SLAB_TYPESAFE_BY_RCU; - -- refcnt = --s->refcount; -- if (refcnt) -+ s->refcount--; -+ if (s->refcount) - goto out_unlock; - -- WARN(shutdown_cache(s), -- "%s %s: Slab cache still has objects when called from %pS", -+ err = shutdown_cache(s); -+ WARN(err, "%s %s: Slab cache still has objects when called from %pS", - __func__, s->name, (void *)_RET_IP_); - out_unlock: - mutex_unlock(&slab_mutex); - cpus_read_unlock(); -- if (!refcnt && !rcu_set) -+ if (!err && !rcu_set) - kmem_cache_release(s); - } - EXPORT_SYMBOL(kmem_cache_destroy); -diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c -index bd54f17e3c3d8..4e3394a7d7d45 100644 ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -124,7 +124,7 @@ static int deliver_clone(const struct net_bridge_port *prev, - - skb = skb_clone(skb, GFP_ATOMIC); - if (!skb) { -- dev->stats.tx_dropped++; -+ DEV_STATS_INC(dev, tx_dropped); - return -ENOMEM; - } - -@@ -263,7 +263,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, - - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) { -- dev->stats.tx_dropped++; -+ DEV_STATS_INC(dev, tx_dropped); - return; - } - -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 68b3e850bcb9d..6bb272894c960 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -164,12 +164,12 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb - if ((mdst && mdst->host_joined) || - br_multicast_is_router(brmctx, skb)) { - local_rcv = true; -- br->dev->stats.multicast++; -+ DEV_STATS_INC(br->dev, multicast); - } - mcast_hit = true; - } else { - local_rcv = true; -- br->dev->stats.multicast++; -+ DEV_STATS_INC(br->dev, multicast); - } - break; - case BR_PKT_UNICAST: -diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c -index 3288490590f27..0c85c8a9e752f 100644 ---- a/net/core/flow_dissector.c -+++ b/net/core/flow_dissector.c -@@ -1366,7 +1366,7 @@ proto_again: - break; - } - -- nhoff += ntohs(hdr->message_length); -+ nhoff += sizeof(struct ptp_header); - fdret = FLOW_DISSECT_RET_OUT_GOOD; - break; - } -diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c -index 8f5d3c0881118..247179d4c8865 100644 ---- a/net/dccp/ipv4.c -+++ b/net/dccp/ipv4.c -@@ -255,13 +255,8 @@ static int dccp_v4_err(struct sk_buff *skb, u32 info) - int err; - struct net *net = dev_net(skb->dev); - -- /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, -- * which is in byte 7 of the dccp header. -- * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. -- * -- * Later on, we want to access the sequence number fields, which are -- * beyond 8 bytes, so we have to pskb_may_pull() ourselves. -- */ -+ if (!pskb_may_pull(skb, offset + sizeof(*dh))) -+ return -EINVAL; - dh = (struct dccp_hdr *)(skb->data + offset); - if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) - return -EINVAL; -diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c -index 2b09e2644b13f..6fb34eaf1237a 100644 ---- a/net/dccp/ipv6.c -+++ b/net/dccp/ipv6.c -@@ -83,13 +83,8 @@ static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, - __u64 seq; - struct net *net = dev_net(skb->dev); - -- /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, -- * which is in byte 7 of the dccp header. -- * Our caller (icmpv6_notify()) already pulled 8 bytes for us. -- * -- * Later on, we want to access the sequence number fields, which are -- * beyond 8 bytes, so we have to pskb_may_pull() ourselves. -- */ -+ if (!pskb_may_pull(skb, offset + sizeof(*dh))) -+ return -EINVAL; - dh = (struct dccp_hdr *)(skb->data + offset); - if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) - return -EINVAL; -diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c -index a16f0445023aa..0b01998780952 100644 ---- a/net/hsr/hsr_framereg.c -+++ b/net/hsr/hsr_framereg.c -@@ -295,13 +295,13 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame) - - /* And leave the HSR tag. */ - if (ethhdr->h_proto == htons(ETH_P_HSR)) { -- pull_size = sizeof(struct ethhdr); -+ pull_size = sizeof(struct hsr_tag); - skb_pull(skb, pull_size); - total_pull_size += pull_size; - } - - /* And leave the HSR sup tag. */ -- pull_size = sizeof(struct hsr_tag); -+ pull_size = sizeof(struct hsr_sup_tag); - skb_pull(skb, pull_size); - total_pull_size += pull_size; - -diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h -index 16ae9fb09ccd2..58a5a8b3891ff 100644 ---- a/net/hsr/hsr_main.h -+++ b/net/hsr/hsr_main.h -@@ -83,7 +83,7 @@ struct hsr_vlan_ethhdr { - struct hsr_sup_tlv { - u8 HSR_TLV_type; - u8 HSR_TLV_length; --}; -+} __packed; - - /* HSR/PRP Supervision Frame data types. - * Field names as defined in the IEC:2010 standard for HSR. -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index a04ffc128e22b..84a0a71a6f4e7 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -1213,6 +1213,7 @@ EXPORT_INDIRECT_CALLABLE(ipv4_dst_check); - - static void ipv4_send_dest_unreach(struct sk_buff *skb) - { -+ struct net_device *dev; - struct ip_options opt; - int res; - -@@ -1230,7 +1231,8 @@ static void ipv4_send_dest_unreach(struct sk_buff *skb) - opt.optlen = ip_hdr(skb)->ihl * 4 - sizeof(struct iphdr); - - rcu_read_lock(); -- res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); -+ dev = skb->dev ? skb->dev : skb_rtable(skb)->dst.dev; -+ res = __ip_options_compile(dev_net(dev), &opt, skb, NULL); - rcu_read_unlock(); - - if (res) -diff --git a/net/mptcp/options.c b/net/mptcp/options.c -index 6b2ef3bb53a3d..0c786ceda5ee6 100644 ---- a/net/mptcp/options.c -+++ b/net/mptcp/options.c -@@ -1248,12 +1248,13 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) - - if (rcv_wnd == rcv_wnd_old) - break; -- if (before64(rcv_wnd_new, rcv_wnd)) { -+ -+ rcv_wnd_old = rcv_wnd; -+ if (before64(rcv_wnd_new, rcv_wnd_old)) { - MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICTUPDATE); - goto raise_win; - } - MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICT); -- rcv_wnd_old = rcv_wnd; - } - return; - } -diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c -index 62fb1031763d1..f8854bff286cb 100644 ---- a/net/ncsi/ncsi-aen.c -+++ b/net/ncsi/ncsi-aen.c -@@ -89,6 +89,11 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp, - if ((had_link == has_link) || chained) - return 0; - -+ if (had_link) -+ netif_carrier_off(ndp->ndev.dev); -+ else -+ netif_carrier_on(ndp->ndev.dev); -+ - if (!ndp->multi_package && !nc->package->multi_channel) { - if (had_link) { - ndp->flags |= NCSI_DEV_RESHUFFLE; -diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c -index 9a6b64779e644..20eede37d5228 100644 ---- a/net/netfilter/ipset/ip_set_core.c -+++ b/net/netfilter/ipset/ip_set_core.c -@@ -682,6 +682,14 @@ __ip_set_put(struct ip_set *set) - /* set->ref can be swapped out by ip_set_swap, netlink events (like dump) need - * a separate reference counter - */ -+static void -+__ip_set_get_netlink(struct ip_set *set) -+{ -+ write_lock_bh(&ip_set_ref_lock); -+ set->ref_netlink++; -+ write_unlock_bh(&ip_set_ref_lock); -+} -+ - static void - __ip_set_put_netlink(struct ip_set *set) - { -@@ -1695,11 +1703,11 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb, - - do { - if (retried) { -- __ip_set_get(set); -+ __ip_set_get_netlink(set); - nfnl_unlock(NFNL_SUBSYS_IPSET); - cond_resched(); - nfnl_lock(NFNL_SUBSYS_IPSET); -- __ip_set_put(set); -+ __ip_set_put_netlink(set); - } - - ip_set_lock(set); -diff --git a/net/netfilter/nf_conntrack_bpf.c b/net/netfilter/nf_conntrack_bpf.c -index 8639e7efd0e22..816283f0aa593 100644 ---- a/net/netfilter/nf_conntrack_bpf.c -+++ b/net/netfilter/nf_conntrack_bpf.c -@@ -384,6 +384,8 @@ struct nf_conn *bpf_ct_insert_entry(struct nf_conn___init *nfct_i) - struct nf_conn *nfct = (struct nf_conn *)nfct_i; - int err; - -+ if (!nf_ct_is_confirmed(nfct)) -+ nfct->timeout += nfct_time_stamp; - nfct->status |= IPS_CONFIRMED; - err = nf_conntrack_hash_check_insert(nfct); - if (err < 0) { -diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c -index 0b513f7bf9f39..dd62cc12e7750 100644 ---- a/net/netfilter/nf_conntrack_extend.c -+++ b/net/netfilter/nf_conntrack_extend.c -@@ -40,10 +40,10 @@ static const u8 nf_ct_ext_type_len[NF_CT_EXT_NUM] = { - [NF_CT_EXT_ECACHE] = sizeof(struct nf_conntrack_ecache), - #endif - #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP -- [NF_CT_EXT_TSTAMP] = sizeof(struct nf_conn_acct), -+ [NF_CT_EXT_TSTAMP] = sizeof(struct nf_conn_tstamp), - #endif - #ifdef CONFIG_NF_CONNTRACK_TIMEOUT -- [NF_CT_EXT_TIMEOUT] = sizeof(struct nf_conn_tstamp), -+ [NF_CT_EXT_TIMEOUT] = sizeof(struct nf_conn_timeout), - #endif - #ifdef CONFIG_NF_CONNTRACK_LABELS - [NF_CT_EXT_LABELS] = sizeof(struct nf_conn_labels), -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 3c5cac9bd9b70..52b81dc1fcf5b 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -31,7 +31,9 @@ static LIST_HEAD(nf_tables_expressions); - static LIST_HEAD(nf_tables_objects); - static LIST_HEAD(nf_tables_flowtables); - static LIST_HEAD(nf_tables_destroy_list); -+static LIST_HEAD(nf_tables_gc_list); - static DEFINE_SPINLOCK(nf_tables_destroy_list_lock); -+static DEFINE_SPINLOCK(nf_tables_gc_list_lock); - - enum { - NFT_VALIDATE_SKIP = 0, -@@ -122,6 +124,9 @@ static void nft_validate_state_update(struct net *net, u8 new_validate_state) - static void nf_tables_trans_destroy_work(struct work_struct *w); - static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work); - -+static void nft_trans_gc_work(struct work_struct *work); -+static DECLARE_WORK(trans_gc_work, nft_trans_gc_work); -+ - static void nft_ctx_init(struct nft_ctx *ctx, - struct net *net, - const struct sk_buff *skb, -@@ -583,10 +588,6 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type, - return __nft_trans_set_add(ctx, msg_type, set, NULL); - } - --static void nft_setelem_data_deactivate(const struct net *net, -- const struct nft_set *set, -- struct nft_set_elem *elem); -- - static int nft_mapelem_deactivate(const struct nft_ctx *ctx, - struct nft_set *set, - const struct nft_set_iter *iter, -@@ -1210,6 +1211,10 @@ static int nf_tables_updtable(struct nft_ctx *ctx) - flags & NFT_TABLE_F_OWNER)) - return -EOPNOTSUPP; - -+ /* No dormant off/on/off/on games in single transaction */ -+ if (ctx->table->flags & __NFT_TABLE_F_UPDATE) -+ return -EINVAL; -+ - trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE, - sizeof(struct nft_trans_table)); - if (trans == NULL) -@@ -1422,7 +1427,7 @@ static int nft_flush_table(struct nft_ctx *ctx) - if (!nft_is_active_next(ctx->net, chain)) - continue; - -- if (nft_chain_is_bound(chain)) -+ if (nft_chain_binding(chain)) - continue; - - ctx->chain = chain; -@@ -1436,8 +1441,7 @@ static int nft_flush_table(struct nft_ctx *ctx) - if (!nft_is_active_next(ctx->net, set)) - continue; - -- if (nft_set_is_anonymous(set) && -- !list_empty(&set->bindings)) -+ if (nft_set_is_anonymous(set)) - continue; - - err = nft_delset(ctx, set); -@@ -1467,7 +1471,7 @@ static int nft_flush_table(struct nft_ctx *ctx) - if (!nft_is_active_next(ctx->net, chain)) - continue; - -- if (nft_chain_is_bound(chain)) -+ if (nft_chain_binding(chain)) - continue; - - ctx->chain = chain; -@@ -2788,6 +2792,9 @@ static int nf_tables_delchain(struct sk_buff *skb, const struct nfnl_info *info, - return PTR_ERR(chain); - } - -+ if (nft_chain_binding(chain)) -+ return -EOPNOTSUPP; -+ - if (info->nlh->nlmsg_flags & NLM_F_NONREC && - chain->use > 0) - return -EBUSY; -@@ -3767,6 +3774,11 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, - } - - if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { -+ if (nft_chain_binding(chain)) { -+ err = -EOPNOTSUPP; -+ goto err_destroy_flow_rule; -+ } -+ - err = nft_delrule(&ctx, old_rule); - if (err < 0) - goto err_destroy_flow_rule; -@@ -3870,7 +3882,7 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info, - NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]); - return PTR_ERR(chain); - } -- if (nft_chain_is_bound(chain)) -+ if (nft_chain_binding(chain)) - return -EOPNOTSUPP; - } - -@@ -3900,7 +3912,7 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info, - list_for_each_entry(chain, &table->chains, list) { - if (!nft_is_active_next(net, chain)) - continue; -- if (nft_chain_is_bound(chain)) -+ if (nft_chain_binding(chain)) - continue; - - ctx.chain = chain; -@@ -4854,6 +4866,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, - - INIT_LIST_HEAD(&set->bindings); - INIT_LIST_HEAD(&set->catchall_list); -+ refcount_set(&set->refs, 1); - set->table = table; - write_pnet(&set->net, net); - set->ops = ops; -@@ -4921,6 +4934,14 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx, - } - } - -+static void nft_set_put(struct nft_set *set) -+{ -+ if (refcount_dec_and_test(&set->refs)) { -+ kfree(set->name); -+ kvfree(set); -+ } -+} -+ - static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set) - { - int i; -@@ -4933,8 +4954,7 @@ static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set) - - set->ops->destroy(ctx, set); - nft_set_catchall_destroy(ctx, set); -- kfree(set->name); -- kvfree(set); -+ nft_set_put(set); - } - - static int nf_tables_delset(struct sk_buff *skb, const struct nfnl_info *info, -@@ -5386,8 +5406,12 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx, - const struct nft_set_iter *iter, - struct nft_set_elem *elem) - { -+ const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); - struct nft_set_dump_args *args; - -+ if (nft_set_elem_expired(ext)) -+ return 0; -+ - args = container_of(iter, struct nft_set_dump_args, iter); - return nf_tables_fill_setelem(args->skb, set, elem); - } -@@ -6047,7 +6071,8 @@ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net, - list_for_each_entry_rcu(catchall, &set->catchall_list, list) { - ext = nft_set_elem_ext(set, catchall->elem); - if (nft_set_elem_active(ext, genmask) && -- !nft_set_elem_expired(ext)) -+ !nft_set_elem_expired(ext) && -+ !nft_set_elem_is_dead(ext)) - return ext; - } - -@@ -6055,29 +6080,6 @@ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net, - } - EXPORT_SYMBOL_GPL(nft_set_catchall_lookup); - --void *nft_set_catchall_gc(const struct nft_set *set) --{ -- struct nft_set_elem_catchall *catchall, *next; -- struct nft_set_ext *ext; -- void *elem = NULL; -- -- list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { -- ext = nft_set_elem_ext(set, catchall->elem); -- -- if (!nft_set_elem_expired(ext) || -- nft_set_elem_mark_busy(ext)) -- continue; -- -- elem = catchall->elem; -- list_del_rcu(&catchall->list); -- kfree_rcu(catchall, rcu); -- break; -- } -- -- return elem; --} --EXPORT_SYMBOL_GPL(nft_set_catchall_gc); -- - static int nft_setelem_catchall_insert(const struct net *net, - struct nft_set *set, - const struct nft_set_elem *elem, -@@ -6139,7 +6141,6 @@ static void nft_setelem_activate(struct net *net, struct nft_set *set, - - if (nft_setelem_is_catchall(set, elem)) { - nft_set_elem_change_active(net, set, ext); -- nft_set_elem_clear_busy(ext); - } else { - set->ops->activate(net, set, elem); - } -@@ -6154,8 +6155,7 @@ static int nft_setelem_catchall_deactivate(const struct net *net, - - list_for_each_entry(catchall, &set->catchall_list, list) { - ext = nft_set_elem_ext(set, catchall->elem); -- if (!nft_is_active(net, ext) || -- nft_set_elem_mark_busy(ext)) -+ if (!nft_is_active(net, ext)) - continue; - - kfree(elem->priv); -@@ -6550,7 +6550,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, - goto err_elem_free; - } - -- ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK; -+ ext->genmask = nft_genmask_cur(ctx->net); - - err = nft_setelem_insert(ctx->net, set, &elem, &ext2, flags); - if (err) { -@@ -6700,9 +6700,9 @@ static void nft_setelem_data_activate(const struct net *net, - nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use); - } - --static void nft_setelem_data_deactivate(const struct net *net, -- const struct nft_set *set, -- struct nft_set_elem *elem) -+void nft_setelem_data_deactivate(const struct net *net, -+ const struct nft_set *set, -+ struct nft_set_elem *elem) - { - const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); - -@@ -6866,8 +6866,7 @@ static int nft_set_catchall_flush(const struct nft_ctx *ctx, - - list_for_each_entry_rcu(catchall, &set->catchall_list, list) { - ext = nft_set_elem_ext(set, catchall->elem); -- if (!nft_set_elem_active(ext, genmask) || -- nft_set_elem_mark_busy(ext)) -+ if (!nft_set_elem_active(ext, genmask)) - continue; - - elem.priv = catchall->elem; -@@ -6919,8 +6918,10 @@ static int nf_tables_delsetelem(struct sk_buff *skb, - if (IS_ERR(set)) - return PTR_ERR(set); - -- if (!list_empty(&set->bindings) && -- (set->flags & (NFT_SET_CONSTANT | NFT_SET_ANONYMOUS))) -+ if (nft_set_is_anonymous(set)) -+ return -EOPNOTSUPP; -+ -+ if (!list_empty(&set->bindings) && (set->flags & NFT_SET_CONSTANT)) - return -EBUSY; - - nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); -@@ -6938,29 +6939,6 @@ static int nf_tables_delsetelem(struct sk_buff *skb, - return err; - } - --void nft_set_gc_batch_release(struct rcu_head *rcu) --{ -- struct nft_set_gc_batch *gcb; -- unsigned int i; -- -- gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu); -- for (i = 0; i < gcb->head.cnt; i++) -- nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true); -- kfree(gcb); --} -- --struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set, -- gfp_t gfp) --{ -- struct nft_set_gc_batch *gcb; -- -- gcb = kzalloc(sizeof(*gcb), gfp); -- if (gcb == NULL) -- return gcb; -- gcb->head.set = set; -- return gcb; --} -- - /* - * Stateful objects - */ -@@ -9089,6 +9067,234 @@ void nft_chain_del(struct nft_chain *chain) - list_del_rcu(&chain->list); - } - -+static void nft_trans_gc_setelem_remove(struct nft_ctx *ctx, -+ struct nft_trans_gc *trans) -+{ -+ void **priv = trans->priv; -+ unsigned int i; -+ -+ for (i = 0; i < trans->count; i++) { -+ struct nft_set_elem elem = { -+ .priv = priv[i], -+ }; -+ -+ nft_setelem_data_deactivate(ctx->net, trans->set, &elem); -+ nft_setelem_remove(ctx->net, trans->set, &elem); -+ } -+} -+ -+void nft_trans_gc_destroy(struct nft_trans_gc *trans) -+{ -+ nft_set_put(trans->set); -+ put_net(trans->net); -+ kfree(trans); -+} -+ -+static void nft_trans_gc_trans_free(struct rcu_head *rcu) -+{ -+ struct nft_set_elem elem = {}; -+ struct nft_trans_gc *trans; -+ struct nft_ctx ctx = {}; -+ unsigned int i; -+ -+ trans = container_of(rcu, struct nft_trans_gc, rcu); -+ ctx.net = read_pnet(&trans->set->net); -+ -+ for (i = 0; i < trans->count; i++) { -+ elem.priv = trans->priv[i]; -+ if (!nft_setelem_is_catchall(trans->set, &elem)) -+ atomic_dec(&trans->set->nelems); -+ -+ nf_tables_set_elem_destroy(&ctx, trans->set, elem.priv); -+ } -+ -+ nft_trans_gc_destroy(trans); -+} -+ -+static bool nft_trans_gc_work_done(struct nft_trans_gc *trans) -+{ -+ struct nftables_pernet *nft_net; -+ struct nft_ctx ctx = {}; -+ -+ nft_net = nft_pernet(trans->net); -+ -+ mutex_lock(&nft_net->commit_mutex); -+ -+ /* Check for race with transaction, otherwise this batch refers to -+ * stale objects that might not be there anymore. Skip transaction if -+ * set has been destroyed from control plane transaction in case gc -+ * worker loses race. -+ */ -+ if (READ_ONCE(nft_net->gc_seq) != trans->seq || trans->set->dead) { -+ mutex_unlock(&nft_net->commit_mutex); -+ return false; -+ } -+ -+ ctx.net = trans->net; -+ ctx.table = trans->set->table; -+ -+ nft_trans_gc_setelem_remove(&ctx, trans); -+ mutex_unlock(&nft_net->commit_mutex); -+ -+ return true; -+} -+ -+static void nft_trans_gc_work(struct work_struct *work) -+{ -+ struct nft_trans_gc *trans, *next; -+ LIST_HEAD(trans_gc_list); -+ -+ spin_lock(&nf_tables_gc_list_lock); -+ list_splice_init(&nf_tables_gc_list, &trans_gc_list); -+ spin_unlock(&nf_tables_gc_list_lock); -+ -+ list_for_each_entry_safe(trans, next, &trans_gc_list, list) { -+ list_del(&trans->list); -+ if (!nft_trans_gc_work_done(trans)) { -+ nft_trans_gc_destroy(trans); -+ continue; -+ } -+ call_rcu(&trans->rcu, nft_trans_gc_trans_free); -+ } -+} -+ -+struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set, -+ unsigned int gc_seq, gfp_t gfp) -+{ -+ struct net *net = read_pnet(&set->net); -+ struct nft_trans_gc *trans; -+ -+ trans = kzalloc(sizeof(*trans), gfp); -+ if (!trans) -+ return NULL; -+ -+ trans->net = maybe_get_net(net); -+ if (!trans->net) { -+ kfree(trans); -+ return NULL; -+ } -+ -+ refcount_inc(&set->refs); -+ trans->set = set; -+ trans->seq = gc_seq; -+ -+ return trans; -+} -+ -+void nft_trans_gc_elem_add(struct nft_trans_gc *trans, void *priv) -+{ -+ trans->priv[trans->count++] = priv; -+} -+ -+static void nft_trans_gc_queue_work(struct nft_trans_gc *trans) -+{ -+ spin_lock(&nf_tables_gc_list_lock); -+ list_add_tail(&trans->list, &nf_tables_gc_list); -+ spin_unlock(&nf_tables_gc_list_lock); -+ -+ schedule_work(&trans_gc_work); -+} -+ -+static int nft_trans_gc_space(struct nft_trans_gc *trans) -+{ -+ return NFT_TRANS_GC_BATCHCOUNT - trans->count; -+} -+ -+struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc, -+ unsigned int gc_seq, gfp_t gfp) -+{ -+ struct nft_set *set; -+ -+ if (nft_trans_gc_space(gc)) -+ return gc; -+ -+ set = gc->set; -+ nft_trans_gc_queue_work(gc); -+ -+ return nft_trans_gc_alloc(set, gc_seq, gfp); -+} -+ -+void nft_trans_gc_queue_async_done(struct nft_trans_gc *trans) -+{ -+ if (trans->count == 0) { -+ nft_trans_gc_destroy(trans); -+ return; -+ } -+ -+ nft_trans_gc_queue_work(trans); -+} -+ -+struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp) -+{ -+ struct nft_set *set; -+ -+ if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net))) -+ return NULL; -+ -+ if (nft_trans_gc_space(gc)) -+ return gc; -+ -+ set = gc->set; -+ call_rcu(&gc->rcu, nft_trans_gc_trans_free); -+ -+ return nft_trans_gc_alloc(set, 0, gfp); -+} -+ -+void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans) -+{ -+ WARN_ON_ONCE(!lockdep_commit_lock_is_held(trans->net)); -+ -+ if (trans->count == 0) { -+ nft_trans_gc_destroy(trans); -+ return; -+ } -+ -+ call_rcu(&trans->rcu, nft_trans_gc_trans_free); -+} -+ -+static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, -+ unsigned int gc_seq, -+ bool sync) -+{ -+ struct nft_set_elem_catchall *catchall; -+ const struct nft_set *set = gc->set; -+ struct nft_set_ext *ext; -+ -+ list_for_each_entry_rcu(catchall, &set->catchall_list, list) { -+ ext = nft_set_elem_ext(set, catchall->elem); -+ -+ if (!nft_set_elem_expired(ext)) -+ continue; -+ if (nft_set_elem_is_dead(ext)) -+ goto dead_elem; -+ -+ nft_set_elem_dead(ext); -+dead_elem: -+ if (sync) -+ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); -+ else -+ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); -+ -+ if (!gc) -+ return NULL; -+ -+ nft_trans_gc_elem_add(gc, catchall->elem); -+ } -+ -+ return gc; -+} -+ -+struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc, -+ unsigned int gc_seq) -+{ -+ return nft_trans_gc_catchall(gc, gc_seq, false); -+} -+ -+struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc) -+{ -+ return nft_trans_gc_catchall(gc, 0, true); -+} -+ - static void nf_tables_module_autoload_cleanup(struct net *net) - { - struct nftables_pernet *nft_net = nft_pernet(net); -@@ -9247,15 +9453,31 @@ static void nft_set_commit_update(struct list_head *set_update_list) - } - } - -+static unsigned int nft_gc_seq_begin(struct nftables_pernet *nft_net) -+{ -+ unsigned int gc_seq; -+ -+ /* Bump gc counter, it becomes odd, this is the busy mark. */ -+ gc_seq = READ_ONCE(nft_net->gc_seq); -+ WRITE_ONCE(nft_net->gc_seq, ++gc_seq); -+ -+ return gc_seq; -+} -+ -+static void nft_gc_seq_end(struct nftables_pernet *nft_net, unsigned int gc_seq) -+{ -+ WRITE_ONCE(nft_net->gc_seq, ++gc_seq); -+} -+ - static int nf_tables_commit(struct net *net, struct sk_buff *skb) - { - struct nftables_pernet *nft_net = nft_pernet(net); - struct nft_trans *trans, *next; -+ unsigned int base_seq, gc_seq; - LIST_HEAD(set_update_list); - struct nft_trans_elem *te; - struct nft_chain *chain; - struct nft_table *table; -- unsigned int base_seq; - LIST_HEAD(adl); - int err; - -@@ -9332,6 +9554,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - - WRITE_ONCE(nft_net->base_seq, base_seq); - -+ gc_seq = nft_gc_seq_begin(nft_net); -+ - /* step 3. Start new generation, rules_gen_X now in use. */ - net->nft.gencursor = nft_gencursor_next(net); - -@@ -9420,6 +9644,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - nft_trans_destroy(trans); - break; - case NFT_MSG_DELSET: -+ nft_trans_set(trans)->dead = 1; - list_del_rcu(&nft_trans_set(trans)->list); - nf_tables_set_notify(&trans->ctx, nft_trans_set(trans), - NFT_MSG_DELSET, GFP_KERNEL); -@@ -9519,6 +9744,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - nft_commit_notify(net, NETLINK_CB(skb).portid); - nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN); - nf_tables_commit_audit_log(&adl, nft_net->base_seq); -+ -+ nft_gc_seq_end(nft_net, gc_seq); - nf_tables_commit_release(net); - - return 0; -@@ -9777,7 +10004,12 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb, - enum nfnl_abort_action action) - { - struct nftables_pernet *nft_net = nft_pernet(net); -- int ret = __nf_tables_abort(net, action); -+ unsigned int gc_seq; -+ int ret; -+ -+ gc_seq = nft_gc_seq_begin(nft_net); -+ ret = __nf_tables_abort(net, action); -+ nft_gc_seq_end(nft_net, gc_seq); - - mutex_unlock(&nft_net->commit_mutex); - -@@ -10440,7 +10672,7 @@ static void __nft_release_table(struct net *net, struct nft_table *table) - ctx.family = table->family; - ctx.table = table; - list_for_each_entry(chain, &table->chains, list) { -- if (nft_chain_is_bound(chain)) -+ if (nft_chain_binding(chain)) - continue; - - ctx.chain = chain; -@@ -10501,6 +10733,7 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event, - struct net *net = n->net; - unsigned int deleted; - bool restart = false; -+ unsigned int gc_seq; - - if (event != NETLINK_URELEASE || n->protocol != NETLINK_NETFILTER) - return NOTIFY_DONE; -@@ -10508,6 +10741,9 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event, - nft_net = nft_pernet(net); - deleted = 0; - mutex_lock(&nft_net->commit_mutex); -+ -+ gc_seq = nft_gc_seq_begin(nft_net); -+ - if (!list_empty(&nf_tables_destroy_list)) - nf_tables_trans_destroy_flush_work(); - again: -@@ -10530,6 +10766,8 @@ again: - if (restart) - goto again; - } -+ nft_gc_seq_end(nft_net, gc_seq); -+ - mutex_unlock(&nft_net->commit_mutex); - - return NOTIFY_DONE; -@@ -10551,6 +10789,7 @@ static int __net_init nf_tables_init_net(struct net *net) - mutex_init(&nft_net->commit_mutex); - nft_net->base_seq = 1; - nft_net->validate_state = NFT_VALIDATE_SKIP; -+ nft_net->gc_seq = 0; - - return 0; - } -@@ -10567,22 +10806,36 @@ static void __net_exit nf_tables_pre_exit_net(struct net *net) - static void __net_exit nf_tables_exit_net(struct net *net) - { - struct nftables_pernet *nft_net = nft_pernet(net); -+ unsigned int gc_seq; - - mutex_lock(&nft_net->commit_mutex); -+ -+ gc_seq = nft_gc_seq_begin(nft_net); -+ - if (!list_empty(&nft_net->commit_list) || - !list_empty(&nft_net->module_list)) - __nf_tables_abort(net, NFNL_ABORT_NONE); -+ - __nft_release_tables(net); -+ -+ nft_gc_seq_end(nft_net, gc_seq); -+ - mutex_unlock(&nft_net->commit_mutex); - WARN_ON_ONCE(!list_empty(&nft_net->tables)); - WARN_ON_ONCE(!list_empty(&nft_net->module_list)); - WARN_ON_ONCE(!list_empty(&nft_net->notify_list)); - } - -+static void nf_tables_exit_batch(struct list_head *net_exit_list) -+{ -+ flush_work(&trans_gc_work); -+} -+ - static struct pernet_operations nf_tables_net_ops = { - .init = nf_tables_init_net, - .pre_exit = nf_tables_pre_exit_net, - .exit = nf_tables_exit_net, -+ .exit_batch = nf_tables_exit_batch, - .id = &nf_tables_net_id, - .size = sizeof(struct nftables_pernet), - }; -@@ -10654,6 +10907,7 @@ static void __exit nf_tables_module_exit(void) - nft_chain_filter_fini(); - nft_chain_route_fini(); - unregister_pernet_subsys(&nf_tables_net_ops); -+ cancel_work_sync(&trans_gc_work); - cancel_work_sync(&trans_destroy_work); - rcu_barrier(); - rhltable_destroy(&nft_objname_ht); -diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c -index 0b73cb0e752f7..2013de934cef0 100644 ---- a/net/netfilter/nft_set_hash.c -+++ b/net/netfilter/nft_set_hash.c -@@ -59,6 +59,8 @@ static inline int nft_rhash_cmp(struct rhashtable_compare_arg *arg, - - if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen)) - return 1; -+ if (nft_set_elem_is_dead(&he->ext)) -+ return 1; - if (nft_set_elem_expired(&he->ext)) - return 1; - if (!nft_set_elem_active(&he->ext, x->genmask)) -@@ -188,7 +190,6 @@ static void nft_rhash_activate(const struct net *net, const struct nft_set *set, - struct nft_rhash_elem *he = elem->priv; - - nft_set_elem_change_active(net, set, &he->ext); -- nft_set_elem_clear_busy(&he->ext); - } - - static bool nft_rhash_flush(const struct net *net, -@@ -196,12 +197,9 @@ static bool nft_rhash_flush(const struct net *net, - { - struct nft_rhash_elem *he = priv; - -- if (!nft_set_elem_mark_busy(&he->ext) || -- !nft_is_active(net, &he->ext)) { -- nft_set_elem_change_active(net, set, &he->ext); -- return true; -- } -- return false; -+ nft_set_elem_change_active(net, set, &he->ext); -+ -+ return true; - } - - static void *nft_rhash_deactivate(const struct net *net, -@@ -218,9 +216,8 @@ static void *nft_rhash_deactivate(const struct net *net, - - rcu_read_lock(); - he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params); -- if (he != NULL && -- !nft_rhash_flush(net, set, he)) -- he = NULL; -+ if (he) -+ nft_set_elem_change_active(net, set, &he->ext); - - rcu_read_unlock(); - -@@ -252,7 +249,9 @@ static bool nft_rhash_delete(const struct nft_set *set, - if (he == NULL) - return false; - -- return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0; -+ nft_set_elem_dead(&he->ext); -+ -+ return true; - } - - static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set, -@@ -278,8 +277,6 @@ static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set, - - if (iter->count < iter->skip) - goto cont; -- if (nft_set_elem_expired(&he->ext)) -- goto cont; - if (!nft_set_elem_active(&he->ext, iter->genmask)) - goto cont; - -@@ -314,25 +311,48 @@ static bool nft_rhash_expr_needs_gc_run(const struct nft_set *set, - - static void nft_rhash_gc(struct work_struct *work) - { -+ struct nftables_pernet *nft_net; - struct nft_set *set; - struct nft_rhash_elem *he; - struct nft_rhash *priv; -- struct nft_set_gc_batch *gcb = NULL; - struct rhashtable_iter hti; -+ struct nft_trans_gc *gc; -+ struct net *net; -+ u32 gc_seq; - - priv = container_of(work, struct nft_rhash, gc_work.work); - set = nft_set_container_of(priv); -+ net = read_pnet(&set->net); -+ nft_net = nft_pernet(net); -+ gc_seq = READ_ONCE(nft_net->gc_seq); -+ -+ if (nft_set_gc_is_pending(set)) -+ goto done; -+ -+ gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL); -+ if (!gc) -+ goto done; - - rhashtable_walk_enter(&priv->ht, &hti); - rhashtable_walk_start(&hti); - - while ((he = rhashtable_walk_next(&hti))) { - if (IS_ERR(he)) { -- if (PTR_ERR(he) != -EAGAIN) -- break; -- continue; -+ nft_trans_gc_destroy(gc); -+ gc = NULL; -+ goto try_later; -+ } -+ -+ /* Ruleset has been updated, try later. */ -+ if (READ_ONCE(nft_net->gc_seq) != gc_seq) { -+ nft_trans_gc_destroy(gc); -+ gc = NULL; -+ goto try_later; - } - -+ if (nft_set_elem_is_dead(&he->ext)) -+ goto dead_elem; -+ - if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPRESSIONS) && - nft_rhash_expr_needs_gc_run(set, &he->ext)) - goto needs_gc_run; -@@ -340,26 +360,26 @@ static void nft_rhash_gc(struct work_struct *work) - if (!nft_set_elem_expired(&he->ext)) - continue; - needs_gc_run: -- if (nft_set_elem_mark_busy(&he->ext)) -- continue; -+ nft_set_elem_dead(&he->ext); -+dead_elem: -+ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); -+ if (!gc) -+ goto try_later; - -- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC); -- if (gcb == NULL) -- break; -- rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params); -- atomic_dec(&set->nelems); -- nft_set_gc_batch_add(gcb, he); -+ nft_trans_gc_elem_add(gc, he); - } -+ -+ gc = nft_trans_gc_catchall_async(gc, gc_seq); -+ -+try_later: -+ /* catchall list iteration requires rcu read side lock. */ - rhashtable_walk_stop(&hti); - rhashtable_walk_exit(&hti); - -- he = nft_set_catchall_gc(set); -- if (he) { -- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC); -- if (gcb) -- nft_set_gc_batch_add(gcb, he); -- } -- nft_set_gc_batch_complete(gcb); -+ if (gc) -+ nft_trans_gc_queue_async_done(gc); -+ -+done: - queue_delayed_work(system_power_efficient_wq, &priv->gc_work, - nft_set_gc_interval(set)); - } -@@ -394,7 +414,7 @@ static int nft_rhash_init(const struct nft_set *set, - return err; - - INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc); -- if (set->flags & NFT_SET_TIMEOUT) -+ if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL)) - nft_rhash_gc_init(set); - - return 0; -@@ -422,7 +442,6 @@ static void nft_rhash_destroy(const struct nft_ctx *ctx, - }; - - cancel_delayed_work_sync(&priv->gc_work); -- rcu_barrier(); - rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy, - (void *)&rhash_ctx); - } -diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c -index 8c16681884b7e..deea6196d9925 100644 ---- a/net/netfilter/nft_set_pipapo.c -+++ b/net/netfilter/nft_set_pipapo.c -@@ -566,8 +566,9 @@ next_match: - goto out; - - if (last) { -- if (nft_set_elem_expired(&f->mt[b].e->ext) || -- (genmask && -+ if (nft_set_elem_expired(&f->mt[b].e->ext)) -+ goto next_match; -+ if ((genmask && - !nft_set_elem_active(&f->mt[b].e->ext, genmask))) - goto next_match; - -@@ -602,7 +603,7 @@ static void *nft_pipapo_get(const struct net *net, const struct nft_set *set, - const struct nft_set_elem *elem, unsigned int flags) - { - return pipapo_get(net, set, (const u8 *)elem->key.val.data, -- nft_genmask_cur(net)); -+ nft_genmask_cur(net)); - } - - /** -@@ -1536,16 +1537,34 @@ static void pipapo_drop(struct nft_pipapo_match *m, - } - } - -+static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set, -+ struct nft_pipapo_elem *e) -+ -+{ -+ struct nft_set_elem elem = { -+ .priv = e, -+ }; -+ -+ nft_setelem_data_deactivate(net, set, &elem); -+} -+ - /** - * pipapo_gc() - Drop expired entries from set, destroy start and end elements -- * @set: nftables API set representation -+ * @_set: nftables API set representation - * @m: Matching data - */ --static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m) -+static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m) - { -+ struct nft_set *set = (struct nft_set *) _set; - struct nft_pipapo *priv = nft_set_priv(set); -+ struct net *net = read_pnet(&set->net); - int rules_f0, first_rule = 0; - struct nft_pipapo_elem *e; -+ struct nft_trans_gc *gc; -+ -+ gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL); -+ if (!gc) -+ return; - - while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) { - union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS]; -@@ -1569,13 +1588,20 @@ static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m) - f--; - i--; - e = f->mt[rulemap[i].to].e; -- if (nft_set_elem_expired(&e->ext) && -- !nft_set_elem_mark_busy(&e->ext)) { -+ -+ /* synchronous gc never fails, there is no need to set on -+ * NFT_SET_ELEM_DEAD_BIT. -+ */ -+ if (nft_set_elem_expired(&e->ext)) { - priv->dirty = true; -- pipapo_drop(m, rulemap); - -- rcu_barrier(); -- nft_set_elem_destroy(set, e, true); -+ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); -+ if (!gc) -+ return; -+ -+ nft_pipapo_gc_deactivate(net, set, e); -+ pipapo_drop(m, rulemap); -+ nft_trans_gc_elem_add(gc, e); - - /* And check again current first rule, which is now the - * first we haven't checked. -@@ -1585,11 +1611,11 @@ static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m) - } - } - -- e = nft_set_catchall_gc(set); -- if (e) -- nft_set_elem_destroy(set, e, true); -- -- priv->last_gc = jiffies; -+ gc = nft_trans_gc_catchall_sync(gc); -+ if (gc) { -+ nft_trans_gc_queue_sync_done(gc); -+ priv->last_gc = jiffies; -+ } - } - - /** -@@ -1718,14 +1744,9 @@ static void nft_pipapo_activate(const struct net *net, - const struct nft_set *set, - const struct nft_set_elem *elem) - { -- struct nft_pipapo_elem *e; -- -- e = pipapo_get(net, set, (const u8 *)elem->key.val.data, 0); -- if (IS_ERR(e)) -- return; -+ struct nft_pipapo_elem *e = elem->priv; - - nft_set_elem_change_active(net, set, &e->ext); -- nft_set_elem_clear_busy(&e->ext); - } - - /** -@@ -1937,10 +1958,6 @@ static void nft_pipapo_remove(const struct net *net, const struct nft_set *set, - - data = (const u8 *)nft_set_ext_key(&e->ext); - -- e = pipapo_get(net, set, data, 0); -- if (IS_ERR(e)) -- return; -- - while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) { - union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS]; - const u8 *match_start, *match_end; -@@ -2024,8 +2041,6 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set, - goto cont; - - e = f->mt[r].e; -- if (nft_set_elem_expired(&e->ext)) -- goto cont; - - elem.priv = e; - -diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c -index 8d73fffd2d09d..487572dcd6144 100644 ---- a/net/netfilter/nft_set_rbtree.c -+++ b/net/netfilter/nft_set_rbtree.c -@@ -46,6 +46,12 @@ static int nft_rbtree_cmp(const struct nft_set *set, - set->klen); - } - -+static bool nft_rbtree_elem_expired(const struct nft_rbtree_elem *rbe) -+{ -+ return nft_set_elem_expired(&rbe->ext) || -+ nft_set_elem_is_dead(&rbe->ext); -+} -+ - static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set, - const u32 *key, const struct nft_set_ext **ext, - unsigned int seq) -@@ -80,7 +86,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set - continue; - } - -- if (nft_set_elem_expired(&rbe->ext)) -+ if (nft_rbtree_elem_expired(rbe)) - return false; - - if (nft_rbtree_interval_end(rbe)) { -@@ -98,7 +104,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set - - if (set->flags & NFT_SET_INTERVAL && interval != NULL && - nft_set_elem_active(&interval->ext, genmask) && -- !nft_set_elem_expired(&interval->ext) && -+ !nft_rbtree_elem_expired(interval) && - nft_rbtree_interval_start(interval)) { - *ext = &interval->ext; - return true; -@@ -215,6 +221,18 @@ static void *nft_rbtree_get(const struct net *net, const struct nft_set *set, - return rbe; - } - -+static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set, -+ struct nft_rbtree *priv, -+ struct nft_rbtree_elem *rbe) -+{ -+ struct nft_set_elem elem = { -+ .priv = rbe, -+ }; -+ -+ nft_setelem_data_deactivate(net, set, &elem); -+ rb_erase(&rbe->node, &priv->root); -+} -+ - static int nft_rbtree_gc_elem(const struct nft_set *__set, - struct nft_rbtree *priv, - struct nft_rbtree_elem *rbe, -@@ -222,11 +240,12 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, - { - struct nft_set *set = (struct nft_set *)__set; - struct rb_node *prev = rb_prev(&rbe->node); -+ struct net *net = read_pnet(&set->net); - struct nft_rbtree_elem *rbe_prev; -- struct nft_set_gc_batch *gcb; -+ struct nft_trans_gc *gc; - -- gcb = nft_set_gc_batch_check(set, NULL, GFP_ATOMIC); -- if (!gcb) -+ gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC); -+ if (!gc) - return -ENOMEM; - - /* search for end interval coming before this element. -@@ -244,17 +263,28 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, - - if (prev) { - rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); -+ nft_rbtree_gc_remove(net, set, priv, rbe_prev); -+ -+ /* There is always room in this trans gc for this element, -+ * memory allocation never actually happens, hence, the warning -+ * splat in such case. No need to set NFT_SET_ELEM_DEAD_BIT, -+ * this is synchronous gc which never fails. -+ */ -+ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); -+ if (WARN_ON_ONCE(!gc)) -+ return -ENOMEM; - -- rb_erase(&rbe_prev->node, &priv->root); -- atomic_dec(&set->nelems); -- nft_set_gc_batch_add(gcb, rbe_prev); -+ nft_trans_gc_elem_add(gc, rbe_prev); - } - -- rb_erase(&rbe->node, &priv->root); -- atomic_dec(&set->nelems); -+ nft_rbtree_gc_remove(net, set, priv, rbe); -+ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); -+ if (WARN_ON_ONCE(!gc)) -+ return -ENOMEM; -+ -+ nft_trans_gc_elem_add(gc, rbe); - -- nft_set_gc_batch_add(gcb, rbe); -- nft_set_gc_batch_complete(gcb); -+ nft_trans_gc_queue_sync_done(gc); - - return 0; - } -@@ -282,6 +312,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, - struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL; - struct rb_node *node, *next, *parent, **p, *first = NULL; - struct nft_rbtree *priv = nft_set_priv(set); -+ u8 cur_genmask = nft_genmask_cur(net); - u8 genmask = nft_genmask_next(net); - int d, err; - -@@ -327,8 +358,11 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, - if (!nft_set_elem_active(&rbe->ext, genmask)) - continue; - -- /* perform garbage collection to avoid bogus overlap reports. */ -- if (nft_set_elem_expired(&rbe->ext)) { -+ /* perform garbage collection to avoid bogus overlap reports -+ * but skip new elements in this transaction. -+ */ -+ if (nft_set_elem_expired(&rbe->ext) && -+ nft_set_elem_active(&rbe->ext, cur_genmask)) { - err = nft_rbtree_gc_elem(set, priv, rbe, genmask); - if (err < 0) - return err; -@@ -482,7 +516,6 @@ static void nft_rbtree_activate(const struct net *net, - struct nft_rbtree_elem *rbe = elem->priv; - - nft_set_elem_change_active(net, set, &rbe->ext); -- nft_set_elem_clear_busy(&rbe->ext); - } - - static bool nft_rbtree_flush(const struct net *net, -@@ -490,12 +523,9 @@ static bool nft_rbtree_flush(const struct net *net, - { - struct nft_rbtree_elem *rbe = priv; - -- if (!nft_set_elem_mark_busy(&rbe->ext) || -- !nft_is_active(net, &rbe->ext)) { -- nft_set_elem_change_active(net, set, &rbe->ext); -- return true; -- } -- return false; -+ nft_set_elem_change_active(net, set, &rbe->ext); -+ -+ return true; - } - - static void *nft_rbtree_deactivate(const struct net *net, -@@ -552,8 +582,6 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx, - - if (iter->count < iter->skip) - goto cont; -- if (nft_set_elem_expired(&rbe->ext)) -- goto cont; - if (!nft_set_elem_active(&rbe->ext, iter->genmask)) - goto cont; - -@@ -572,26 +600,42 @@ cont: - - static void nft_rbtree_gc(struct work_struct *work) - { -- struct nft_rbtree_elem *rbe, *rbe_end = NULL, *rbe_prev = NULL; -- struct nft_set_gc_batch *gcb = NULL; -+ struct nft_rbtree_elem *rbe, *rbe_end = NULL; -+ struct nftables_pernet *nft_net; - struct nft_rbtree *priv; -+ struct nft_trans_gc *gc; - struct rb_node *node; - struct nft_set *set; -+ unsigned int gc_seq; - struct net *net; -- u8 genmask; - - priv = container_of(work, struct nft_rbtree, gc_work.work); - set = nft_set_container_of(priv); - net = read_pnet(&set->net); -- genmask = nft_genmask_cur(net); -+ nft_net = nft_pernet(net); -+ gc_seq = READ_ONCE(nft_net->gc_seq); - -- write_lock_bh(&priv->lock); -- write_seqcount_begin(&priv->count); -+ if (nft_set_gc_is_pending(set)) -+ goto done; -+ -+ gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL); -+ if (!gc) -+ goto done; -+ -+ read_lock_bh(&priv->lock); - for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) { -+ -+ /* Ruleset has been updated, try later. */ -+ if (READ_ONCE(nft_net->gc_seq) != gc_seq) { -+ nft_trans_gc_destroy(gc); -+ gc = NULL; -+ goto try_later; -+ } -+ - rbe = rb_entry(node, struct nft_rbtree_elem, node); - -- if (!nft_set_elem_active(&rbe->ext, genmask)) -- continue; -+ if (nft_set_elem_is_dead(&rbe->ext)) -+ goto dead_elem; - - /* elements are reversed in the rbtree for historical reasons, - * from highest to lowest value, that is why end element is -@@ -604,46 +648,35 @@ static void nft_rbtree_gc(struct work_struct *work) - if (!nft_set_elem_expired(&rbe->ext)) - continue; - -- if (nft_set_elem_mark_busy(&rbe->ext)) { -- rbe_end = NULL; -+ nft_set_elem_dead(&rbe->ext); -+ -+ if (!rbe_end) - continue; -- } - -- if (rbe_prev) { -- rb_erase(&rbe_prev->node, &priv->root); -- rbe_prev = NULL; -- } -- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC); -- if (!gcb) -- break; -+ nft_set_elem_dead(&rbe_end->ext); - -- atomic_dec(&set->nelems); -- nft_set_gc_batch_add(gcb, rbe); -- rbe_prev = rbe; -+ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); -+ if (!gc) -+ goto try_later; - -- if (rbe_end) { -- atomic_dec(&set->nelems); -- nft_set_gc_batch_add(gcb, rbe_end); -- rb_erase(&rbe_end->node, &priv->root); -- rbe_end = NULL; -- } -- node = rb_next(node); -- if (!node) -- break; -- } -- if (rbe_prev) -- rb_erase(&rbe_prev->node, &priv->root); -- write_seqcount_end(&priv->count); -- write_unlock_bh(&priv->lock); -+ nft_trans_gc_elem_add(gc, rbe_end); -+ rbe_end = NULL; -+dead_elem: -+ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); -+ if (!gc) -+ goto try_later; - -- rbe = nft_set_catchall_gc(set); -- if (rbe) { -- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC); -- if (gcb) -- nft_set_gc_batch_add(gcb, rbe); -+ nft_trans_gc_elem_add(gc, rbe); - } -- nft_set_gc_batch_complete(gcb); - -+ gc = nft_trans_gc_catchall_async(gc, gc_seq); -+ -+try_later: -+ read_unlock_bh(&priv->lock); -+ -+ if (gc) -+ nft_trans_gc_queue_async_done(gc); -+done: - queue_delayed_work(system_power_efficient_wq, &priv->gc_work, - nft_set_gc_interval(set)); - } -diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c -index d36f3f6b43510..b15cf316b23a2 100644 ---- a/net/rds/rdma_transport.c -+++ b/net/rds/rdma_transport.c -@@ -86,11 +86,13 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id, - break; - - case RDMA_CM_EVENT_ADDR_RESOLVED: -- rdma_set_service_type(cm_id, conn->c_tos); -- rdma_set_min_rnr_timer(cm_id, IB_RNR_TIMER_000_32); -- /* XXX do we need to clean up if this fails? */ -- ret = rdma_resolve_route(cm_id, -- RDS_RDMA_RESOLVE_TIMEOUT_MS); -+ if (conn) { -+ rdma_set_service_type(cm_id, conn->c_tos); -+ rdma_set_min_rnr_timer(cm_id, IB_RNR_TIMER_000_32); -+ /* XXX do we need to clean up if this fails? */ -+ ret = rdma_resolve_route(cm_id, -+ RDS_RDMA_RESOLVE_TIMEOUT_MS); -+ } - break; - - case RDMA_CM_EVENT_ROUTE_RESOLVED: -diff --git a/net/smc/smc_stats.h b/net/smc/smc_stats.h -index 84b7ecd8c05ca..4dbc237b7c19e 100644 ---- a/net/smc/smc_stats.h -+++ b/net/smc/smc_stats.h -@@ -244,8 +244,9 @@ while (0) - #define SMC_STAT_SERV_SUCC_INC(net, _ini) \ - do { \ - typeof(_ini) i = (_ini); \ -- bool is_v2 = (i->smcd_version & SMC_V2); \ - bool is_smcd = (i->is_smcd); \ -+ u8 version = is_smcd ? i->smcd_version : i->smcr_version; \ -+ bool is_v2 = (version & SMC_V2); \ - typeof(net->smc.smc_stats) smc_stats = (net)->smc.smc_stats; \ - if (is_v2 && is_smcd) \ - this_cpu_inc(smc_stats->smc[SMC_TYPE_D].srv_v2_succ_cnt); \ -diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c -index b0258507b236c..2b803383c7b31 100644 ---- a/net/sunrpc/clnt.c -+++ b/net/sunrpc/clnt.c -@@ -2462,8 +2462,7 @@ call_status(struct rpc_task *task) - goto out_exit; - } - task->tk_action = call_encode; -- if (status != -ECONNRESET && status != -ECONNABORTED) -- rpc_check_timeout(task); -+ rpc_check_timeout(task); - return; - out_exit: - rpc_call_rpcerror(task, status); -@@ -2736,6 +2735,7 @@ out_msg_denied: - case rpc_autherr_rejectedverf: - case rpcsec_gsserr_credproblem: - case rpcsec_gsserr_ctxproblem: -+ rpcauth_invalcred(task); - if (!task->tk_cred_retry) - break; - task->tk_cred_retry--; -@@ -2889,19 +2889,22 @@ static const struct rpc_call_ops rpc_cb_add_xprt_call_ops = { - * @clnt: pointer to struct rpc_clnt - * @xps: pointer to struct rpc_xprt_switch, - * @xprt: pointer struct rpc_xprt -- * @dummy: unused -+ * @in_max_connect: pointer to the max_connect value for the passed in xprt transport - */ - int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, - struct rpc_xprt_switch *xps, struct rpc_xprt *xprt, -- void *dummy) -+ void *in_max_connect) - { - struct rpc_cb_add_xprt_calldata *data; - struct rpc_task *task; -+ int max_connect = clnt->cl_max_connect; - -- if (xps->xps_nunique_destaddr_xprts + 1 > clnt->cl_max_connect) { -+ if (in_max_connect) -+ max_connect = *(int *)in_max_connect; -+ if (xps->xps_nunique_destaddr_xprts + 1 > max_connect) { - rcu_read_lock(); - pr_warn("SUNRPC: reached max allowed number (%d) did not add " -- "transport to server: %s\n", clnt->cl_max_connect, -+ "transport to server: %s\n", max_connect, - rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR)); - rcu_read_unlock(); - return -EINVAL; -diff --git a/security/smack/smack.h b/security/smack/smack.h -index e2239be7bd60a..aa15ff56ed6e7 100644 ---- a/security/smack/smack.h -+++ b/security/smack/smack.h -@@ -120,6 +120,7 @@ struct inode_smack { - struct task_smack { - struct smack_known *smk_task; /* label for access control */ - struct smack_known *smk_forked; /* label when forked */ -+ struct smack_known *smk_transmuted;/* label when transmuted */ - struct list_head smk_rules; /* per task access rules */ - struct mutex smk_rules_lock; /* lock for the rules */ - struct list_head smk_relabel; /* transit allowed labels */ -diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c -index 67dcd31cd3f3d..cd6a03e945eb7 100644 ---- a/security/smack/smack_lsm.c -+++ b/security/smack/smack_lsm.c -@@ -999,8 +999,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, - const struct qstr *qstr, const char **name, - void **value, size_t *len) - { -+ struct task_smack *tsp = smack_cred(current_cred()); - struct inode_smack *issp = smack_inode(inode); -- struct smack_known *skp = smk_of_current(); -+ struct smack_known *skp = smk_of_task(tsp); - struct smack_known *isp = smk_of_inode(inode); - struct smack_known *dsp = smk_of_inode(dir); - int may; -@@ -1009,20 +1010,34 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, - *name = XATTR_SMACK_SUFFIX; - - if (value && len) { -- rcu_read_lock(); -- may = smk_access_entry(skp->smk_known, dsp->smk_known, -- &skp->smk_rules); -- rcu_read_unlock(); -+ /* -+ * If equal, transmuting already occurred in -+ * smack_dentry_create_files_as(). No need to check again. -+ */ -+ if (tsp->smk_task != tsp->smk_transmuted) { -+ rcu_read_lock(); -+ may = smk_access_entry(skp->smk_known, dsp->smk_known, -+ &skp->smk_rules); -+ rcu_read_unlock(); -+ } - - /* -- * If the access rule allows transmutation and -- * the directory requests transmutation then -- * by all means transmute. -+ * In addition to having smk_task equal to smk_transmuted, -+ * if the access rule allows transmutation and the directory -+ * requests transmutation then by all means transmute. - * Mark the inode as changed. - */ -- if (may > 0 && ((may & MAY_TRANSMUTE) != 0) && -- smk_inode_transmutable(dir)) { -- isp = dsp; -+ if ((tsp->smk_task == tsp->smk_transmuted) || -+ (may > 0 && ((may & MAY_TRANSMUTE) != 0) && -+ smk_inode_transmutable(dir))) { -+ /* -+ * The caller of smack_dentry_create_files_as() -+ * should have overridden the current cred, so the -+ * inode label was already set correctly in -+ * smack_inode_alloc_security(). -+ */ -+ if (tsp->smk_task != tsp->smk_transmuted) -+ isp = dsp; - issp->smk_flags |= SMK_INODE_CHANGED; - } - -@@ -1461,10 +1476,19 @@ static int smack_inode_getsecurity(struct user_namespace *mnt_userns, - struct super_block *sbp; - struct inode *ip = (struct inode *)inode; - struct smack_known *isp; -+ struct inode_smack *ispp; -+ size_t label_len; -+ char *label = NULL; - -- if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) -+ if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { - isp = smk_of_inode(inode); -- else { -+ } else if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) { -+ ispp = smack_inode(inode); -+ if (ispp->smk_flags & SMK_INODE_TRANSMUTE) -+ label = TRANS_TRUE; -+ else -+ label = ""; -+ } else { - /* - * The rest of the Smack xattrs are only on sockets. - */ -@@ -1486,13 +1510,18 @@ static int smack_inode_getsecurity(struct user_namespace *mnt_userns, - return -EOPNOTSUPP; - } - -+ if (!label) -+ label = isp->smk_known; -+ -+ label_len = strlen(label); -+ - if (alloc) { -- *buffer = kstrdup(isp->smk_known, GFP_KERNEL); -+ *buffer = kstrdup(label, GFP_KERNEL); - if (*buffer == NULL) - return -ENOMEM; - } - -- return strlen(isp->smk_known); -+ return label_len; - } - - -@@ -4750,8 +4779,10 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, - * providing access is transmuting use the containing - * directory label instead of the process label. - */ -- if (may > 0 && (may & MAY_TRANSMUTE)) -+ if (may > 0 && (may & MAY_TRANSMUTE)) { - ntsp->smk_task = isp->smk_inode; -+ ntsp->smk_transmuted = ntsp->smk_task; -+ } - } - return 0; - } -diff --git a/sound/hda/intel-sdw-acpi.c b/sound/hda/intel-sdw-acpi.c -index 5cb92f7ccbcac..b57d72ea4503f 100644 ---- a/sound/hda/intel-sdw-acpi.c -+++ b/sound/hda/intel-sdw-acpi.c -@@ -23,7 +23,7 @@ static int ctrl_link_mask; - module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444); - MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)"); - --static bool is_link_enabled(struct fwnode_handle *fw_node, int i) -+static bool is_link_enabled(struct fwnode_handle *fw_node, u8 idx) - { - struct fwnode_handle *link; - char name[32]; -@@ -31,7 +31,7 @@ static bool is_link_enabled(struct fwnode_handle *fw_node, int i) - - /* Find master handle */ - snprintf(name, sizeof(name), -- "mipi-sdw-link-%d-subproperties", i); -+ "mipi-sdw-link-%hhu-subproperties", idx); - - link = fwnode_get_named_child_node(fw_node, name); - if (!link) -@@ -51,8 +51,8 @@ static int - sdw_intel_scan_controller(struct sdw_intel_acpi_info *info) - { - struct acpi_device *adev = acpi_fetch_acpi_dev(info->handle); -- int ret, i; -- u8 count; -+ u8 count, i; -+ int ret; - - if (!adev) - return -EINVAL; -diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c -index 3226691ac923c..54f4b593a1158 100644 ---- a/sound/pci/hda/hda_intel.c -+++ b/sound/pci/hda/hda_intel.c -@@ -2208,6 +2208,7 @@ static const struct snd_pci_quirk power_save_denylist[] = { - SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0), - /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ - SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0), -+ SND_PCI_QUIRK(0x17aa, 0x316e, "Lenovo ThinkCentre M70q", 0), - /* https://bugzilla.redhat.com/show_bug.cgi?id=1689623 */ - SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0), - /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index f70e0ad81607e..57e07aa4e136c 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9657,7 +9657,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS ROG Strix G17 2023 (G713PV)", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), - SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), -- SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2), -+ SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), -+ SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2), - SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), - SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), -diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c -index 9a9571c3f08c0..533250efcbd83 100644 ---- a/sound/soc/amd/yc/acp6x-mach.c -+++ b/sound/soc/amd/yc/acp6x-mach.c -@@ -213,6 +213,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "21J6"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82TL"), -+ } -+ }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82QF"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -@@ -220,6 +234,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "82V2"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82UG"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c -index 2fefbcf7bd130..735061690ded0 100644 ---- a/sound/soc/codecs/cs42l42.c -+++ b/sound/soc/codecs/cs42l42.c -@@ -2280,6 +2280,16 @@ int cs42l42_common_probe(struct cs42l42_private *cs42l42, - - if (cs42l42->reset_gpio) { - dev_dbg(cs42l42->dev, "Found reset GPIO\n"); -+ -+ /* -+ * ACPI can override the default GPIO state we requested -+ * so ensure that we start with RESET low. -+ */ -+ gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); -+ -+ /* Ensure minimum reset pulse width */ -+ usleep_range(10, 500); -+ - gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); - } - usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); -diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c -index a7071d0a2562f..37ea4d854cb58 100644 ---- a/sound/soc/codecs/rt5640.c -+++ b/sound/soc/codecs/rt5640.c -@@ -2562,10 +2562,9 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component, - if (jack_data && jack_data->use_platform_clock) - rt5640->use_platform_clock = jack_data->use_platform_clock; - -- ret = devm_request_threaded_irq(component->dev, rt5640->irq, -- NULL, rt5640_irq, -- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, -- "rt5640", rt5640); -+ ret = request_irq(rt5640->irq, rt5640_irq, -+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, -+ "rt5640", rt5640); - if (ret) { - dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret); - rt5640_disable_jack_detect(component); -@@ -2618,14 +2617,14 @@ static void rt5640_enable_hda_jack_detect( - - rt5640->jack = jack; - -- ret = devm_request_threaded_irq(component->dev, rt5640->irq, -- NULL, rt5640_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT, -- "rt5640", rt5640); -+ ret = request_irq(rt5640->irq, rt5640_irq, -+ IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5640", rt5640); - if (ret) { - dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret); - rt5640->irq = -ENXIO; - return; - } -+ rt5640->irq_requested = true; - - /* sync initial jack state */ - queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); -diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c -index d8e99b263ab21..cbe24d5b4e46a 100644 ---- a/sound/soc/fsl/imx-audmix.c -+++ b/sound/soc/fsl/imx-audmix.c -@@ -320,7 +320,7 @@ static int imx_audmix_probe(struct platform_device *pdev) - if (IS_ERR(priv->cpu_mclk)) { - ret = PTR_ERR(priv->cpu_mclk); - dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret); -- return -EINVAL; -+ return ret; - } - - priv->audmix_pdev = audmix_pdev; -diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c -index 35049043e5322..933bac7ea1864 100644 ---- a/sound/soc/fsl/imx-pcm-rpmsg.c -+++ b/sound/soc/fsl/imx-pcm-rpmsg.c -@@ -19,6 +19,7 @@ - static struct snd_pcm_hardware imx_rpmsg_pcm_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | -+ SNDRV_PCM_INFO_BATCH | - SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | -diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c -index 4d99f4858a14f..76c6febf24990 100644 ---- a/sound/soc/fsl/imx-rpmsg.c -+++ b/sound/soc/fsl/imx-rpmsg.c -@@ -88,6 +88,14 @@ static int imx_rpmsg_probe(struct platform_device *pdev) - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC; - -+ /* -+ * i.MX rpmsg sound cards work on codec slave mode. MCLK will be -+ * disabled by CPU DAI driver in hw_free(). Some codec requires MCLK -+ * present at power up/down sequence. So need to set ignore_pmdown_time -+ * to power down codec immediately before MCLK is turned off. -+ */ -+ data->dai.ignore_pmdown_time = 1; -+ - /* Optional codec node */ - ret = of_parse_phandle_with_fixed_args(np, "audio-codec", 0, 0, &args); - if (ret) { -diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c -index 073663ba140d0..a65939f30ac47 100644 ---- a/sound/soc/intel/avs/boards/hdaudio.c -+++ b/sound/soc/intel/avs/boards/hdaudio.c -@@ -54,6 +54,9 @@ static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int - return -ENOMEM; - - dl[i].codecs->name = devm_kstrdup(dev, cname, GFP_KERNEL); -+ if (!dl[i].codecs->name) -+ return -ENOMEM; -+ - dl[i].codecs->dai_name = pcm->name; - dl[i].num_codecs = 1; - dl[i].num_cpus = 1; -diff --git a/sound/soc/meson/axg-spdifin.c b/sound/soc/meson/axg-spdifin.c -index e2cc4c4be7586..97e81ec4a78ce 100644 ---- a/sound/soc/meson/axg-spdifin.c -+++ b/sound/soc/meson/axg-spdifin.c -@@ -112,34 +112,6 @@ static int axg_spdifin_prepare(struct snd_pcm_substream *substream, - return 0; - } - --static int axg_spdifin_startup(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai) --{ -- struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); -- int ret; -- -- ret = clk_prepare_enable(priv->refclk); -- if (ret) { -- dev_err(dai->dev, -- "failed to enable spdifin reference clock\n"); -- return ret; -- } -- -- regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, -- SPDIFIN_CTRL0_EN); -- -- return 0; --} -- --static void axg_spdifin_shutdown(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai) --{ -- struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); -- -- regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); -- clk_disable_unprepare(priv->refclk); --} -- - static void axg_spdifin_write_mode_param(struct regmap *map, int mode, - unsigned int val, - unsigned int num_per_reg, -@@ -251,25 +223,38 @@ static int axg_spdifin_dai_probe(struct snd_soc_dai *dai) - ret = axg_spdifin_sample_mode_config(dai, priv); - if (ret) { - dev_err(dai->dev, "mode configuration failed\n"); -- clk_disable_unprepare(priv->pclk); -- return ret; -+ goto pclk_err; - } - -+ ret = clk_prepare_enable(priv->refclk); -+ if (ret) { -+ dev_err(dai->dev, -+ "failed to enable spdifin reference clock\n"); -+ goto pclk_err; -+ } -+ -+ regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, -+ SPDIFIN_CTRL0_EN); -+ - return 0; -+ -+pclk_err: -+ clk_disable_unprepare(priv->pclk); -+ return ret; - } - - static int axg_spdifin_dai_remove(struct snd_soc_dai *dai) - { - struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); - -+ regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); -+ clk_disable_unprepare(priv->refclk); - clk_disable_unprepare(priv->pclk); - return 0; - } - - static const struct snd_soc_dai_ops axg_spdifin_ops = { - .prepare = axg_spdifin_prepare, -- .startup = axg_spdifin_startup, -- .shutdown = axg_spdifin_shutdown, - }; - - static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol, -diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c -index 75a1e2c6539f2..eaa16755a2704 100644 ---- a/sound/soc/sof/core.c -+++ b/sound/soc/sof/core.c -@@ -461,10 +461,9 @@ int snd_sof_device_remove(struct device *dev) - snd_sof_ipc_free(sdev); - snd_sof_free_debug(sdev); - snd_sof_remove(sdev); -+ sof_ops_free(sdev); - } - -- sof_ops_free(sdev); -- - /* release firmware */ - snd_sof_fw_unload(sdev); - -diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c -index 10298532816fe..d7048f1d6a048 100644 ---- a/sound/soc/sof/intel/mtl.c -+++ b/sound/soc/sof/intel/mtl.c -@@ -453,7 +453,7 @@ static int mtl_dsp_cl_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_bo - /* step 3: wait for IPC DONE bit from ROM */ - ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, chip->ipc_ack, status, - ((status & chip->ipc_ack_mask) == chip->ipc_ack_mask), -- HDA_DSP_REG_POLL_INTERVAL_US, MTL_DSP_PURGE_TIMEOUT_US); -+ HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_INIT_TIMEOUT_US); - if (ret < 0) { - if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) - dev_err(sdev->dev, "timeout waiting for purge IPC done\n"); -diff --git a/sound/soc/sof/intel/mtl.h b/sound/soc/sof/intel/mtl.h -index 788bf0e3ea879..00e3526889d3d 100644 ---- a/sound/soc/sof/intel/mtl.h -+++ b/sound/soc/sof/intel/mtl.h -@@ -54,7 +54,6 @@ - #define MTL_DSP_IRQSTS_IPC BIT(0) - #define MTL_DSP_IRQSTS_SDW BIT(6) - --#define MTL_DSP_PURGE_TIMEOUT_US 20000000 /* 20s */ - #define MTL_DSP_REG_POLL_INTERVAL_US 10 /* 10 us */ - - /* Memory windows */ -diff --git a/tools/include/linux/btf_ids.h b/tools/include/linux/btf_ids.h -index 71e54b1e37964..2f882d5cb30f5 100644 ---- a/tools/include/linux/btf_ids.h -+++ b/tools/include/linux/btf_ids.h -@@ -38,7 +38,7 @@ asm( \ - ____BTF_ID(symbol) - - #define __ID(prefix) \ -- __PASTE(prefix, __COUNTER__) -+ __PASTE(__PASTE(prefix, __COUNTER__), __LINE__) - - /* - * The BTF_ID defines unique symbol for each ID pointing -diff --git a/tools/include/linux/mm.h b/tools/include/linux/mm.h -index a03d9bba51514..43be27bcc897d 100644 ---- a/tools/include/linux/mm.h -+++ b/tools/include/linux/mm.h -@@ -11,8 +11,6 @@ - - #define PHYS_ADDR_MAX (~(phys_addr_t)0) - --#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) --#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) - #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) - #define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a)) - -diff --git a/tools/include/linux/seq_file.h b/tools/include/linux/seq_file.h -index 102fd9217f1f9..f6bc226af0c1d 100644 ---- a/tools/include/linux/seq_file.h -+++ b/tools/include/linux/seq_file.h -@@ -1,4 +1,6 @@ - #ifndef _TOOLS_INCLUDE_LINUX_SEQ_FILE_H - #define _TOOLS_INCLUDE_LINUX_SEQ_FILE_H - -+struct seq_file; -+ - #endif /* _TOOLS_INCLUDE_LINUX_SEQ_FILE_H */ -diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h -index 51b9aa640ad2a..53bc487947197 100644 ---- a/tools/include/uapi/linux/bpf.h -+++ b/tools/include/uapi/linux/bpf.h -@@ -1837,7 +1837,9 @@ union bpf_attr { - * performed again, if the helper is used in combination with - * direct packet access. - * Return -- * 0 on success, or a negative error in case of failure. -+ * 0 on success, or a negative error in case of failure. Positive -+ * error indicates a potential drop or congestion in the target -+ * device. The particular positive error codes are not defined. - * - * u64 bpf_get_current_pid_tgid(void) - * Description -diff --git a/tools/perf/util/Build b/tools/perf/util/Build -index e315ecaec3233..2c364a9087a22 100644 ---- a/tools/perf/util/Build -+++ b/tools/perf/util/Build -@@ -276,6 +276,12 @@ ifeq ($(BISON_GE_35),1) - else - bison_flags += -w - endif -+ -+BISON_LT_381 := $(shell expr $(shell $(BISON) --version | grep bison | sed -e 's/.\+ \([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/\1\2\3/g') \< 381) -+ifeq ($(BISON_LT_381),1) -+ bison_flags += -DYYNOMEM=YYABORT -+endif -+ - CFLAGS_parse-events-bison.o += $(bison_flags) - CFLAGS_pmu-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) - CFLAGS_expr-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) -diff --git a/tools/testing/memblock/tests/basic_api.c b/tools/testing/memblock/tests/basic_api.c -index a13a57ba0815f..7ce628e31a431 100644 ---- a/tools/testing/memblock/tests/basic_api.c -+++ b/tools/testing/memblock/tests/basic_api.c -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0-or-later -+#include "basic_api.h" - #include - #include --#include "basic_api.h" - - #define EXPECTED_MEMBLOCK_REGIONS 128 - #define FUNC_ADD "memblock_add" -diff --git a/tools/testing/memblock/tests/common.h b/tools/testing/memblock/tests/common.h -index d6bbbe63bfc36..4c33ce04c0645 100644 ---- a/tools/testing/memblock/tests/common.h -+++ b/tools/testing/memblock/tests/common.h -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc -index 0eb47fbb3f44d..42422e4251078 100644 ---- a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc -+++ b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc -@@ -39,7 +39,7 @@ instance_read() { - - instance_set() { - while :; do -- echo 1 > foo/events/sched/sched_switch -+ echo 1 > foo/events/sched/sched_switch/enable - done 2> /dev/null - } - -diff --git a/tools/testing/selftests/kselftest_deps.sh b/tools/testing/selftests/kselftest_deps.sh -index 708cb54296336..47a1281a3b702 100755 ---- a/tools/testing/selftests/kselftest_deps.sh -+++ b/tools/testing/selftests/kselftest_deps.sh -@@ -46,11 +46,11 @@ fi - print_targets=0 - - while getopts "p" arg; do -- case $arg in -- p) -+ case $arg in -+ p) - print_targets=1 - shift;; -- esac -+ esac - done - - if [ $# -eq 0 ] -@@ -92,6 +92,10 @@ pass_cnt=0 - # Get all TARGETS from selftests Makefile - targets=$(egrep "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) - -+# Initially, in LDLIBS related lines, the dep checker needs -+# to ignore lines containing the following strings: -+filter="\$(VAR_LDLIBS)\|pkg-config\|PKG_CONFIG\|IOURING_EXTRA_LIBS" -+ - # Single test case - if [ $# -eq 2 ] - then -@@ -100,6 +104,8 @@ then - l1_test $test - l2_test $test - l3_test $test -+ l4_test $test -+ l5_test $test - - print_results $1 $2 - exit $? -@@ -113,7 +119,7 @@ fi - # Append space at the end of the list to append more tests. - - l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ -- grep -v "VAR_LDLIBS" | awk -F: '{print $1}') -+ grep -v "$filter" | awk -F: '{print $1}' | uniq) - - # Level 2: LDLIBS set dynamically. - # -@@ -126,7 +132,7 @@ l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ - # Append space at the end of the list to append more tests. - - l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ -- grep -v "VAR_LDLIBS" | awk -F: '{print $1}') -+ grep -v "$filter" | awk -F: '{print $1}' | uniq) - - # Level 3 - # memfd and others use pkg-config to find mount and fuse libs -@@ -138,11 +144,32 @@ l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ - # VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) - - l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \ -- grep -v "pkg-config" | awk -F: '{print $1}') -+ grep -v "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq) - --#echo $l1_tests --#echo $l2_1_tests --#echo $l3_tests -+# Level 4 -+# some tests may fall back to default using `|| echo -l` -+# if pkg-config doesn't find the libs, instead of using VAR_LDLIBS -+# as per level 3 checks. -+# e.g: -+# netfilter/Makefile -+# LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) -+l4_tests=$(grep -r --include=Makefile "^LDLIBS" | \ -+ grep "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq) -+ -+# Level 5 -+# some tests may use IOURING_EXTRA_LIBS to add extra libs to LDLIBS, -+# which in turn may be defined in a sub-Makefile -+# e.g.: -+# mm/Makefile -+# $(OUTPUT)/gup_longterm: LDLIBS += $(IOURING_EXTRA_LIBS) -+l5_tests=$(grep -r --include=Makefile "LDLIBS +=.*\$(IOURING_EXTRA_LIBS)" | \ -+ awk -F: '{print $1}' | uniq) -+ -+#echo l1_tests $l1_tests -+#echo l2_tests $l2_tests -+#echo l3_tests $l3_tests -+#echo l4_tests $l4_tests -+#echo l5_tests $l5_tests - - all_tests - print_results $1 $2 -@@ -164,24 +191,32 @@ all_tests() - for test in $l3_tests; do - l3_test $test - done -+ -+ for test in $l4_tests; do -+ l4_test $test -+ done -+ -+ for test in $l5_tests; do -+ l5_test $test -+ done - } - - # Use same parsing used for l1_tests and pick libraries this time. - l1_test() - { - test_libs=$(grep --include=Makefile "^LDLIBS" $test | \ -- grep -v "VAR_LDLIBS" | \ -+ grep -v "$filter" | \ - sed -e 's/\:/ /' | \ - sed -e 's/+/ /' | cut -d "=" -f 2) - - check_libs $test $test_libs - } - --# Use same parsing used for l2__tests and pick libraries this time. -+# Use same parsing used for l2_tests and pick libraries this time. - l2_test() - { - test_libs=$(grep --include=Makefile ": LDLIBS" $test | \ -- grep -v "VAR_LDLIBS" | \ -+ grep -v "$filter" | \ - sed -e 's/\:/ /' | sed -e 's/+/ /' | \ - cut -d "=" -f 2) - -@@ -197,6 +232,24 @@ l3_test() - check_libs $test $test_libs - } - -+l4_test() -+{ -+ test_libs=$(grep --include=Makefile "^VAR_LDLIBS\|^LDLIBS" $test | \ -+ grep "\(pkg-config\|PKG_CONFIG\).*|| echo " | \ -+ sed -e 's/.*|| echo //' | sed -e 's/)$//') -+ -+ check_libs $test $test_libs -+} -+ -+l5_test() -+{ -+ tests=$(find $(dirname "$test") -type f -name "*.mk") -+ test_libs=$(grep "^IOURING_EXTRA_LIBS +\?=" $tests | \ -+ cut -d "=" -f 2) -+ -+ check_libs $test $test_libs -+} -+ - check_libs() - { - -diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c -index c0ad8385441f2..5b80fb155d549 100644 ---- a/tools/testing/selftests/net/tls.c -+++ b/tools/testing/selftests/net/tls.c -@@ -551,11 +551,11 @@ TEST_F(tls, sendmsg_large) - - msg.msg_iov = &vec; - msg.msg_iovlen = 1; -- EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len); -+ EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len); - } - - while (recvs++ < sends) { -- EXPECT_NE(recv(self->fd, mem, send_len, 0), -1); -+ EXPECT_NE(recv(self->cfd, mem, send_len, 0), -1); - } - - free(mem); -@@ -584,9 +584,9 @@ TEST_F(tls, sendmsg_multiple) - msg.msg_iov = vec; - msg.msg_iovlen = iov_len; - -- EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len); -+ EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len); - buf = malloc(total_len); -- EXPECT_NE(recv(self->fd, buf, total_len, 0), -1); -+ EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1); - for (i = 0; i < iov_len; i++) { - EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp, - strlen(test_strs[i])), -diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile -index 6ba95cd19e423..c8c085fa05b05 100644 ---- a/tools/testing/selftests/powerpc/Makefile -+++ b/tools/testing/selftests/powerpc/Makefile -@@ -45,28 +45,27 @@ $(SUB_DIRS): - include ../lib.mk - - override define RUN_TESTS -- @for TARGET in $(SUB_DIRS); do \ -+ +@for TARGET in $(SUB_DIRS); do \ - BUILD_TARGET=$(OUTPUT)/$$TARGET; \ - $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ - done; - endef - - override define INSTALL_RULE -- @for TARGET in $(SUB_DIRS); do \ -+ +@for TARGET in $(SUB_DIRS); do \ - BUILD_TARGET=$(OUTPUT)/$$TARGET; \ - $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\ - done; - endef - --override define EMIT_TESTS -- @for TARGET in $(SUB_DIRS); do \ -+emit_tests: -+ +@for TARGET in $(SUB_DIRS); do \ - BUILD_TARGET=$(OUTPUT)/$$TARGET; \ -- $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ -+ $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET $@;\ - done; --endef - - override define CLEAN -- @for TARGET in $(SUB_DIRS); do \ -+ +@for TARGET in $(SUB_DIRS); do \ - BUILD_TARGET=$(OUTPUT)/$$TARGET; \ - $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \ - done; -@@ -76,4 +75,4 @@ endef - tags: - find . -name '*.c' -o -name '*.h' | xargs ctags - --.PHONY: tags $(SUB_DIRS) -+.PHONY: tags $(SUB_DIRS) emit_tests -diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile -index 30803353bd7cc..a284fa874a9f1 100644 ---- a/tools/testing/selftests/powerpc/pmu/Makefile -+++ b/tools/testing/selftests/powerpc/pmu/Makefile -@@ -25,32 +25,36 @@ $(OUTPUT)/per_event_excludes: ../utils.c - DEFAULT_RUN_TESTS := $(RUN_TESTS) - override define RUN_TESTS - $(DEFAULT_RUN_TESTS) -- TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests -- TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests -- TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests -+ +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests -+ +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests -+ +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests - endef - --DEFAULT_EMIT_TESTS := $(EMIT_TESTS) --override define EMIT_TESTS -- $(DEFAULT_EMIT_TESTS) -- TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests -- TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests -- TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests --endef -+emit_tests: -+ for TEST in $(TEST_GEN_PROGS); do \ -+ BASENAME_TEST=`basename $$TEST`; \ -+ echo "$(COLLECTION):$$BASENAME_TEST"; \ -+ done -+ +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests -+ +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests -+ +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests - - DEFAULT_INSTALL_RULE := $(INSTALL_RULE) - override define INSTALL_RULE - $(DEFAULT_INSTALL_RULE) -- TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install -- TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install -- TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install -+ +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install -+ +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install -+ +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install - endef - --clean: -+DEFAULT_CLEAN := $(CLEAN) -+override define CLEAN -+ $(DEFAULT_CLEAN) - $(RM) $(TEST_GEN_PROGS) $(OUTPUT)/loop.o -- TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean -- TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean -- TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean -+ +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean -+ +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean -+ +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean -+endef - - ebb: - TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all -@@ -61,4 +65,4 @@ sampling_tests: - event_code_tests: - TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all - --.PHONY: all run_tests clean ebb sampling_tests event_code_tests -+.PHONY: all run_tests ebb sampling_tests event_code_tests emit_tests diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.56-57.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.56-57.patch deleted file mode 100644 index 455f1d719406..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.56-57.patch +++ /dev/null @@ -1,11235 +0,0 @@ -diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst -index 9000640f7f7a0..d9fce65b2f047 100644 ---- a/Documentation/arm64/silicon-errata.rst -+++ b/Documentation/arm64/silicon-errata.rst -@@ -63,6 +63,8 @@ stable kernels. - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A510 | #1902691 | ARM64_ERRATUM_1902691 | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-A520 | #2966298 | ARM64_ERRATUM_2966298 | -++----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 | -diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst -index 3301288a7c692..f5f7a464605f9 100644 ---- a/Documentation/networking/ip-sysctl.rst -+++ b/Documentation/networking/ip-sysctl.rst -@@ -2148,6 +2148,14 @@ accept_ra_min_hop_limit - INTEGER - - Default: 1 - -+accept_ra_min_lft - INTEGER -+ Minimum acceptable lifetime value in Router Advertisement. -+ -+ RA sections with a lifetime less than this value shall be -+ ignored. Zero lifetimes stay unaffected. -+ -+ Default: 0 -+ - accept_ra_pinfo - BOOLEAN - Learn Prefix Information in Router Advertisement. - -diff --git a/Makefile b/Makefile -index 9ceda3dad5eb7..b435b56594f0f 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 56 -+SUBLEVEL = 57 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index d5eb2fbab473e..9ee9e17eb2ca0 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -983,6 +983,19 @@ config ARM64_ERRATUM_2457168 - - If unsure, say Y. - -+config ARM64_ERRATUM_2966298 -+ bool "Cortex-A520: 2966298: workaround for speculatively executed unprivileged load" -+ default y -+ help -+ This option adds the workaround for ARM Cortex-A520 erratum 2966298. -+ -+ On an affected Cortex-A520 core, a speculatively executed unprivileged -+ load might leak data from a privileged level via a cache side channel. -+ -+ Work around this problem by executing a TLBI before returning to EL0. -+ -+ If unsure, say Y. -+ - config CAVIUM_ERRATUM_22375 - bool "Cavium erratum 22375, 24313" - default y -diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h -index f73f11b550425..a0badda3a8d1c 100644 ---- a/arch/arm64/include/asm/cpufeature.h -+++ b/arch/arm64/include/asm/cpufeature.h -@@ -670,7 +670,7 @@ static inline bool supports_clearbhb(int scope) - isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1); - - return cpuid_feature_extract_unsigned_field(isar2, -- ID_AA64ISAR2_EL1_BC_SHIFT); -+ ID_AA64ISAR2_EL1_CLRBHB_SHIFT); - } - - const struct cpumask *system_32bit_el0_cpumask(void); -@@ -863,7 +863,11 @@ static inline bool cpu_has_hw_af(void) - if (!IS_ENABLED(CONFIG_ARM64_HW_AFDBM)) - return false; - -- mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); -+ /* -+ * Use cached version to avoid emulated msr operation on KVM -+ * guests. -+ */ -+ mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); - return cpuid_feature_extract_unsigned_field(mmfr1, - ID_AA64MMFR1_EL1_HAFDBS_SHIFT); - } -diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h -index 65e53ef5a3960..357932938b5ab 100644 ---- a/arch/arm64/include/asm/cputype.h -+++ b/arch/arm64/include/asm/cputype.h -@@ -79,6 +79,7 @@ - #define ARM_CPU_PART_CORTEX_A78AE 0xD42 - #define ARM_CPU_PART_CORTEX_X1 0xD44 - #define ARM_CPU_PART_CORTEX_A510 0xD46 -+#define ARM_CPU_PART_CORTEX_A520 0xD80 - #define ARM_CPU_PART_CORTEX_A710 0xD47 - #define ARM_CPU_PART_CORTEX_X2 0xD48 - #define ARM_CPU_PART_NEOVERSE_N2 0xD49 -@@ -141,6 +142,7 @@ - #define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE) - #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) - #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) -+#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520) - #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) - #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) - #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) -diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c -index 8dbf3c21ea22a..3f917124684c5 100644 ---- a/arch/arm64/kernel/cpu_errata.c -+++ b/arch/arm64/kernel/cpu_errata.c -@@ -723,6 +723,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { - .cpu_enable = cpu_clear_bf16_from_user_emulation, - }, - #endif -+#ifdef CONFIG_ARM64_ERRATUM_2966298 -+ { -+ .desc = "ARM erratum 2966298", -+ .capability = ARM64_WORKAROUND_2966298, -+ /* Cortex-A520 r0p0 - r0p1 */ -+ ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A520, 0, 0, 1), -+ }, -+#endif - #ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38 - { - .desc = "AmpereOne erratum AC03_CPU_38", -diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index b3eb53847c96b..770a31c6ed81b 100644 ---- a/arch/arm64/kernel/cpufeature.c -+++ b/arch/arm64/kernel/cpufeature.c -@@ -212,7 +212,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { - }; - - static const struct arm64_ftr_bits ftr_id_aa64isar2[] = { -- ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), -+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CLRBHB_SHIFT, 4, 0), -+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), - FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), -diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S -index beb4db21c89c1..de16fa917e1b8 100644 ---- a/arch/arm64/kernel/entry.S -+++ b/arch/arm64/kernel/entry.S -@@ -419,6 +419,10 @@ alternative_else_nop_endif - ldp x28, x29, [sp, #16 * 14] - - .if \el == 0 -+alternative_if ARM64_WORKAROUND_2966298 -+ tlbi vale1, xzr -+ dsb nsh -+alternative_else_nop_endif - alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0 - ldr lr, [sp, #S_LR] - add sp, sp, #PT_REGS_SIZE // restore sp -diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps -index 14d31d1b2ff02..e73830d9f1367 100644 ---- a/arch/arm64/tools/cpucaps -+++ b/arch/arm64/tools/cpucaps -@@ -71,6 +71,7 @@ WORKAROUND_2064142 - WORKAROUND_2077057 - WORKAROUND_2457168 - WORKAROUND_2658417 -+WORKAROUND_2966298 - WORKAROUND_AMPERE_AC03_CPU_38 - WORKAROUND_TRBE_OVERWRITE_FILL_MODE - WORKAROUND_TSB_FLUSH_FAILURE -diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg -index 384757a7eda9e..11c3f7a7cec7b 100644 ---- a/arch/arm64/tools/sysreg -+++ b/arch/arm64/tools/sysreg -@@ -484,7 +484,11 @@ EndEnum - EndSysreg - - Sysreg ID_AA64ISAR2_EL1 3 0 0 6 2 --Res0 63:28 -+Res0 63:32 -+Enum 31:28 CLRBHB -+ 0b0000 NI -+ 0b0001 IMP -+EndEnum - Enum 27:24 PAC_frac - 0b0000 NI - 0b0001 IMP -diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h -index 6d28b5514699a..10a061d6899cd 100644 ---- a/arch/parisc/include/asm/ldcw.h -+++ b/arch/parisc/include/asm/ldcw.h -@@ -2,14 +2,28 @@ - #ifndef __PARISC_LDCW_H - #define __PARISC_LDCW_H - --#ifndef CONFIG_PA20 - /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, - and GCC only guarantees 8-byte alignment for stack locals, we can't - be assured of 16-byte alignment for atomic lock data even if we - specify "__attribute ((aligned(16)))" in the type declaration. So, - we use a struct containing an array of four ints for the atomic lock - type and dynamically select the 16-byte aligned int from the array -- for the semaphore. */ -+ for the semaphore. */ -+ -+/* From: "Jim Hull" -+ I've attached a summary of the change, but basically, for PA 2.0, as -+ long as the ",CO" (coherent operation) completer is implemented, then the -+ 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead -+ they only require "natural" alignment (4-byte for ldcw, 8-byte for -+ ldcd). -+ -+ Although the cache control hint is accepted by all PA 2.0 processors, -+ it is only implemented on PA8800/PA8900 CPUs. Prior PA8X00 CPUs still -+ require 16-byte alignment. If the address is unaligned, the operation -+ of the instruction is undefined. The ldcw instruction does not generate -+ unaligned data reference traps so misaligned accesses are not detected. -+ This hid the problem for years. So, restore the 16-byte alignment dropped -+ by Kyle McMartin in "Remove __ldcw_align for PA-RISC 2.0 processors". */ - - #define __PA_LDCW_ALIGNMENT 16 - #define __PA_LDCW_ALIGN_ORDER 4 -@@ -19,22 +33,12 @@ - & ~(__PA_LDCW_ALIGNMENT - 1); \ - (volatile unsigned int *) __ret; \ - }) --#define __LDCW "ldcw" - --#else /*CONFIG_PA20*/ --/* From: "Jim Hull" -- I've attached a summary of the change, but basically, for PA 2.0, as -- long as the ",CO" (coherent operation) completer is specified, then the -- 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead -- they only require "natural" alignment (4-byte for ldcw, 8-byte for -- ldcd). */ -- --#define __PA_LDCW_ALIGNMENT 4 --#define __PA_LDCW_ALIGN_ORDER 2 --#define __ldcw_align(a) (&(a)->slock) -+#ifdef CONFIG_PA20 - #define __LDCW "ldcw,co" -- --#endif /*!CONFIG_PA20*/ -+#else -+#define __LDCW "ldcw" -+#endif - - /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. - We don't explicitly expose that "*a" may be written as reload -diff --git a/arch/parisc/include/asm/spinlock_types.h b/arch/parisc/include/asm/spinlock_types.h -index ca39ee350c3f4..35c5086b74d70 100644 ---- a/arch/parisc/include/asm/spinlock_types.h -+++ b/arch/parisc/include/asm/spinlock_types.h -@@ -3,13 +3,8 @@ - #define __ASM_SPINLOCK_TYPES_H - - typedef struct { --#ifdef CONFIG_PA20 -- volatile unsigned int slock; --# define __ARCH_SPIN_LOCK_UNLOCKED { 1 } --#else - volatile unsigned int lock[4]; - # define __ARCH_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } --#endif - } arch_spinlock_t; - - -diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c -index 7dbd92cafae38..e37ec05487308 100644 ---- a/arch/parisc/kernel/smp.c -+++ b/arch/parisc/kernel/smp.c -@@ -443,7 +443,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) - if (cpu_online(cpu)) - return 0; - -- if (num_online_cpus() < setup_max_cpus && smp_boot_one_cpu(cpu, tidle)) -+ if (num_online_cpus() < nr_cpu_ids && -+ num_online_cpus() < setup_max_cpus && -+ smp_boot_one_cpu(cpu, tidle)) - return -EIO; - - return cpu_online(cpu) ? 0 : -EIO; -diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c -index 6672a3f05fc68..04f4b96dec6df 100644 ---- a/arch/x86/events/amd/core.c -+++ b/arch/x86/events/amd/core.c -@@ -534,8 +534,12 @@ static void amd_pmu_cpu_reset(int cpu) - /* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */ - wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0); - -- /* Clear overflow bits i.e. PerfCntrGLobalStatus.PerfCntrOvfl */ -- wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, amd_pmu_global_cntr_mask); -+ /* -+ * Clear freeze and overflow bits i.e. PerfCntrGLobalStatus.LbrFreeze -+ * and PerfCntrGLobalStatus.PerfCntrOvfl -+ */ -+ wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, -+ GLOBAL_STATUS_LBRS_FROZEN | amd_pmu_global_cntr_mask); - } - - static int amd_pmu_cpu_prepare(int cpu) -@@ -570,6 +574,7 @@ static void amd_pmu_cpu_starting(int cpu) - int i, nb_id; - - cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; -+ amd_pmu_cpu_reset(cpu); - - if (!x86_pmu.amd_nb_constraints) - return; -@@ -591,8 +596,6 @@ static void amd_pmu_cpu_starting(int cpu) - - cpuc->amd_nb->nb_id = nb_id; - cpuc->amd_nb->refcnt++; -- -- amd_pmu_cpu_reset(cpu); - } - - static void amd_pmu_cpu_dead(int cpu) -@@ -601,6 +604,7 @@ static void amd_pmu_cpu_dead(int cpu) - - kfree(cpuhw->lbr_sel); - cpuhw->lbr_sel = NULL; -+ amd_pmu_cpu_reset(cpu); - - if (!x86_pmu.amd_nb_constraints) - return; -@@ -613,8 +617,6 @@ static void amd_pmu_cpu_dead(int cpu) - - cpuhw->amd_nb = NULL; - } -- -- amd_pmu_cpu_reset(cpu); - } - - static inline void amd_pmu_set_global_ctl(u64 ctl) -@@ -884,7 +886,7 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs) - struct hw_perf_event *hwc; - struct perf_event *event; - int handled = 0, idx; -- u64 status, mask; -+ u64 reserved, status, mask; - bool pmu_enabled; - - /* -@@ -909,6 +911,14 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs) - status &= ~GLOBAL_STATUS_LBRS_FROZEN; - } - -+ reserved = status & ~amd_pmu_global_cntr_mask; -+ if (reserved) -+ pr_warn_once("Reserved PerfCntrGlobalStatus bits are set (0x%llx), please consider updating microcode\n", -+ reserved); -+ -+ /* Clear any reserved bits set by buggy microcode */ -+ status &= amd_pmu_global_cntr_mask; -+ - for (idx = 0; idx < x86_pmu.num_counters; idx++) { - if (!test_bit(idx, cpuc->active_mask)) - continue; -diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c -index 3a5b0c9c4fccc..7dce812ce2538 100644 ---- a/arch/x86/kernel/sev-shared.c -+++ b/arch/x86/kernel/sev-shared.c -@@ -253,7 +253,7 @@ static int __sev_cpuid_hv(u32 fn, int reg_idx, u32 *reg) - return 0; - } - --static int sev_cpuid_hv(struct cpuid_leaf *leaf) -+static int __sev_cpuid_hv_msr(struct cpuid_leaf *leaf) - { - int ret; - -@@ -276,6 +276,45 @@ static int sev_cpuid_hv(struct cpuid_leaf *leaf) - return ret; - } - -+static int __sev_cpuid_hv_ghcb(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) -+{ -+ u32 cr4 = native_read_cr4(); -+ int ret; -+ -+ ghcb_set_rax(ghcb, leaf->fn); -+ ghcb_set_rcx(ghcb, leaf->subfn); -+ -+ if (cr4 & X86_CR4_OSXSAVE) -+ /* Safe to read xcr0 */ -+ ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK)); -+ else -+ /* xgetbv will cause #UD - use reset value for xcr0 */ -+ ghcb_set_xcr0(ghcb, 1); -+ -+ ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_CPUID, 0, 0); -+ if (ret != ES_OK) -+ return ret; -+ -+ if (!(ghcb_rax_is_valid(ghcb) && -+ ghcb_rbx_is_valid(ghcb) && -+ ghcb_rcx_is_valid(ghcb) && -+ ghcb_rdx_is_valid(ghcb))) -+ return ES_VMM_ERROR; -+ -+ leaf->eax = ghcb->save.rax; -+ leaf->ebx = ghcb->save.rbx; -+ leaf->ecx = ghcb->save.rcx; -+ leaf->edx = ghcb->save.rdx; -+ -+ return ES_OK; -+} -+ -+static int sev_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) -+{ -+ return ghcb ? __sev_cpuid_hv_ghcb(ghcb, ctxt, leaf) -+ : __sev_cpuid_hv_msr(leaf); -+} -+ - /* - * This may be called early while still running on the initial identity - * mapping. Use RIP-relative addressing to obtain the correct address -@@ -385,19 +424,20 @@ snp_cpuid_get_validated_func(struct cpuid_leaf *leaf) - return false; - } - --static void snp_cpuid_hv(struct cpuid_leaf *leaf) -+static void snp_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) - { -- if (sev_cpuid_hv(leaf)) -+ if (sev_cpuid_hv(ghcb, ctxt, leaf)) - sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV); - } - --static int snp_cpuid_postprocess(struct cpuid_leaf *leaf) -+static int snp_cpuid_postprocess(struct ghcb *ghcb, struct es_em_ctxt *ctxt, -+ struct cpuid_leaf *leaf) - { - struct cpuid_leaf leaf_hv = *leaf; - - switch (leaf->fn) { - case 0x1: -- snp_cpuid_hv(&leaf_hv); -+ snp_cpuid_hv(ghcb, ctxt, &leaf_hv); - - /* initial APIC ID */ - leaf->ebx = (leaf_hv.ebx & GENMASK(31, 24)) | (leaf->ebx & GENMASK(23, 0)); -@@ -416,7 +456,7 @@ static int snp_cpuid_postprocess(struct cpuid_leaf *leaf) - break; - case 0xB: - leaf_hv.subfn = 0; -- snp_cpuid_hv(&leaf_hv); -+ snp_cpuid_hv(ghcb, ctxt, &leaf_hv); - - /* extended APIC ID */ - leaf->edx = leaf_hv.edx; -@@ -464,7 +504,7 @@ static int snp_cpuid_postprocess(struct cpuid_leaf *leaf) - } - break; - case 0x8000001E: -- snp_cpuid_hv(&leaf_hv); -+ snp_cpuid_hv(ghcb, ctxt, &leaf_hv); - - /* extended APIC ID */ - leaf->eax = leaf_hv.eax; -@@ -485,7 +525,7 @@ static int snp_cpuid_postprocess(struct cpuid_leaf *leaf) - * Returns -EOPNOTSUPP if feature not enabled. Any other non-zero return value - * should be treated as fatal by caller. - */ --static int snp_cpuid(struct cpuid_leaf *leaf) -+static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) - { - const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); - -@@ -519,7 +559,7 @@ static int snp_cpuid(struct cpuid_leaf *leaf) - return 0; - } - -- return snp_cpuid_postprocess(leaf); -+ return snp_cpuid_postprocess(ghcb, ctxt, leaf); - } - - /* -@@ -541,14 +581,14 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code) - leaf.fn = fn; - leaf.subfn = subfn; - -- ret = snp_cpuid(&leaf); -+ ret = snp_cpuid(NULL, NULL, &leaf); - if (!ret) - goto cpuid_done; - - if (ret != -EOPNOTSUPP) - goto fail; - -- if (sev_cpuid_hv(&leaf)) -+ if (__sev_cpuid_hv_msr(&leaf)) - goto fail; - - cpuid_done: -@@ -845,14 +885,15 @@ static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) - return ret; - } - --static int vc_handle_cpuid_snp(struct pt_regs *regs) -+static int vc_handle_cpuid_snp(struct ghcb *ghcb, struct es_em_ctxt *ctxt) - { -+ struct pt_regs *regs = ctxt->regs; - struct cpuid_leaf leaf; - int ret; - - leaf.fn = regs->ax; - leaf.subfn = regs->cx; -- ret = snp_cpuid(&leaf); -+ ret = snp_cpuid(ghcb, ctxt, &leaf); - if (!ret) { - regs->ax = leaf.eax; - regs->bx = leaf.ebx; -@@ -871,7 +912,7 @@ static enum es_result vc_handle_cpuid(struct ghcb *ghcb, - enum es_result ret; - int snp_cpuid_ret; - -- snp_cpuid_ret = vc_handle_cpuid_snp(regs); -+ snp_cpuid_ret = vc_handle_cpuid_snp(ghcb, ctxt); - if (!snp_cpuid_ret) - return ES_OK; - if (snp_cpuid_ret != -EOPNOTSUPP) -diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c -index a582ea0da74f5..a82bdec923b21 100644 ---- a/block/blk-sysfs.c -+++ b/block/blk-sysfs.c -@@ -737,6 +737,7 @@ static void blk_free_queue_rcu(struct rcu_head *rcu_head) - struct request_queue *q = container_of(rcu_head, struct request_queue, - rcu_head); - -+ percpu_ref_exit(&q->q_usage_counter); - kmem_cache_free(blk_get_queue_kmem_cache(blk_queue_has_srcu(q)), q); - } - -@@ -762,8 +763,6 @@ static void blk_release_queue(struct kobject *kobj) - - might_sleep(); - -- percpu_ref_exit(&q->q_usage_counter); -- - if (q->poll_stat) - blk_stat_remove_callback(q, q->poll_cb); - blk_stat_free_callback(q->poll_cb); -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index 25b9bdf2fc380..6a053cd0cf410 100644 ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -5022,11 +5022,27 @@ static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET - - static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg) - { -+ /* -+ * We are about to suspend the port, so we do not care about -+ * scsi_rescan_device() calls scheduled by previous resume operations. -+ * The next resume will schedule the rescan again. So cancel any rescan -+ * that is not done yet. -+ */ -+ cancel_delayed_work_sync(&ap->scsi_rescan_task); -+ - ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false); - } - - static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg) - { -+ /* -+ * We are about to suspend the port, so we do not care about -+ * scsi_rescan_device() calls scheduled by previous resume operations. -+ * The next resume will schedule the rescan again. So cancel any rescan -+ * that is not done yet. -+ */ -+ cancel_delayed_work_sync(&ap->scsi_rescan_task); -+ - ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true); - } - -diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c -index d28628b964e29..7b9c9264b9a72 100644 ---- a/drivers/ata/libata-scsi.c -+++ b/drivers/ata/libata-scsi.c -@@ -1081,7 +1081,15 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) - } - } else { - sdev->sector_size = ata_id_logical_sector_size(dev->id); -- sdev->manage_start_stop = 1; -+ /* -+ * Stop the drive on suspend but do not issue START STOP UNIT -+ * on resume as this is not necessary and may fail: the device -+ * will be woken up by ata_port_pm_resume() with a port reset -+ * and device revalidation. -+ */ -+ sdev->manage_system_start_stop = true; -+ sdev->manage_runtime_start_stop = true; -+ sdev->no_start_on_resume = 1; - } - - /* -@@ -4640,7 +4648,7 @@ void ata_scsi_dev_rescan(struct work_struct *work) - struct ata_link *link; - struct ata_device *dev; - unsigned long flags; -- bool delay_rescan = false; -+ int ret = 0; - - mutex_lock(&ap->scsi_scan_mutex); - spin_lock_irqsave(ap->lock, flags); -@@ -4649,37 +4657,34 @@ void ata_scsi_dev_rescan(struct work_struct *work) - ata_for_each_dev(dev, link, ENABLED) { - struct scsi_device *sdev = dev->sdev; - -+ /* -+ * If the port was suspended before this was scheduled, -+ * bail out. -+ */ -+ if (ap->pflags & ATA_PFLAG_SUSPENDED) -+ goto unlock; -+ - if (!sdev) - continue; - if (scsi_device_get(sdev)) - continue; - -- /* -- * If the rescan work was scheduled because of a resume -- * event, the port is already fully resumed, but the -- * SCSI device may not yet be fully resumed. In such -- * case, executing scsi_rescan_device() may cause a -- * deadlock with the PM code on device_lock(). Prevent -- * this by giving up and retrying rescan after a short -- * delay. -- */ -- delay_rescan = sdev->sdev_gendev.power.is_suspended; -- if (delay_rescan) { -- scsi_device_put(sdev); -- break; -- } -- - spin_unlock_irqrestore(ap->lock, flags); -- scsi_rescan_device(&(sdev->sdev_gendev)); -+ ret = scsi_rescan_device(sdev); - scsi_device_put(sdev); - spin_lock_irqsave(ap->lock, flags); -+ -+ if (ret) -+ goto unlock; - } - } - -+unlock: - spin_unlock_irqrestore(ap->lock, flags); - mutex_unlock(&ap->scsi_scan_mutex); - -- if (delay_rescan) -+ /* Reschedule with a delay if scsi_rescan_device() returned an error */ -+ if (ret) - schedule_delayed_work(&ap->scsi_rescan_task, - msecs_to_jiffies(5)); - } -diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c -index ae6b8788d5f3f..d65715b9e129e 100644 ---- a/drivers/base/regmap/regcache-rbtree.c -+++ b/drivers/base/regmap/regcache-rbtree.c -@@ -453,7 +453,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, - if (!rbnode) - return -ENOMEM; - regcache_rbtree_set_register(map, rbnode, -- reg - rbnode->base_reg, value); -+ (reg - rbnode->base_reg) / map->reg_stride, -+ value); - regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); - rbtree_ctx->cached_rbnode = rbnode; - } -diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c -index 74ef3da545361..afc92869cba42 100644 ---- a/drivers/block/rbd.c -+++ b/drivers/block/rbd.c -@@ -632,9 +632,8 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...) - static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); - - static int rbd_dev_refresh(struct rbd_device *rbd_dev); --static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev); --static int rbd_dev_header_info(struct rbd_device *rbd_dev); --static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev); -+static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, -+ struct rbd_image_header *header); - static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, - u64 snap_id); - static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, -@@ -995,15 +994,24 @@ static void rbd_init_layout(struct rbd_device *rbd_dev) - RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); - } - -+static void rbd_image_header_cleanup(struct rbd_image_header *header) -+{ -+ kfree(header->object_prefix); -+ ceph_put_snap_context(header->snapc); -+ kfree(header->snap_sizes); -+ kfree(header->snap_names); -+ -+ memset(header, 0, sizeof(*header)); -+} -+ - /* - * Fill an rbd image header with information from the given format 1 - * on-disk header. - */ --static int rbd_header_from_disk(struct rbd_device *rbd_dev, -- struct rbd_image_header_ondisk *ondisk) -+static int rbd_header_from_disk(struct rbd_image_header *header, -+ struct rbd_image_header_ondisk *ondisk, -+ bool first_time) - { -- struct rbd_image_header *header = &rbd_dev->header; -- bool first_time = header->object_prefix == NULL; - struct ceph_snap_context *snapc; - char *object_prefix = NULL; - char *snap_names = NULL; -@@ -1070,11 +1078,6 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev, - if (first_time) { - header->object_prefix = object_prefix; - header->obj_order = ondisk->options.order; -- rbd_init_layout(rbd_dev); -- } else { -- ceph_put_snap_context(header->snapc); -- kfree(header->snap_names); -- kfree(header->snap_sizes); - } - - /* The remaining fields always get updated (when we refresh) */ -@@ -4860,7 +4863,9 @@ out_req: - * return, the rbd_dev->header field will contain up-to-date - * information about the image. - */ --static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) -+static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev, -+ struct rbd_image_header *header, -+ bool first_time) - { - struct rbd_image_header_ondisk *ondisk = NULL; - u32 snap_count = 0; -@@ -4908,7 +4913,7 @@ static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) - snap_count = le32_to_cpu(ondisk->snap_count); - } while (snap_count != want_count); - -- ret = rbd_header_from_disk(rbd_dev, ondisk); -+ ret = rbd_header_from_disk(header, ondisk, first_time); - out: - kfree(ondisk); - -@@ -4932,39 +4937,6 @@ static void rbd_dev_update_size(struct rbd_device *rbd_dev) - } - } - --static int rbd_dev_refresh(struct rbd_device *rbd_dev) --{ -- u64 mapping_size; -- int ret; -- -- down_write(&rbd_dev->header_rwsem); -- mapping_size = rbd_dev->mapping.size; -- -- ret = rbd_dev_header_info(rbd_dev); -- if (ret) -- goto out; -- -- /* -- * If there is a parent, see if it has disappeared due to the -- * mapped image getting flattened. -- */ -- if (rbd_dev->parent) { -- ret = rbd_dev_v2_parent_info(rbd_dev); -- if (ret) -- goto out; -- } -- -- rbd_assert(!rbd_is_snap(rbd_dev)); -- rbd_dev->mapping.size = rbd_dev->header.image_size; -- --out: -- up_write(&rbd_dev->header_rwsem); -- if (!ret && mapping_size != rbd_dev->mapping.size) -- rbd_dev_update_size(rbd_dev); -- -- return ret; --} -- - static const struct blk_mq_ops rbd_mq_ops = { - .queue_rq = rbd_queue_rq, - }; -@@ -5504,17 +5476,12 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, - return 0; - } - --static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) --{ -- return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, -- &rbd_dev->header.obj_order, -- &rbd_dev->header.image_size); --} -- --static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) -+static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev, -+ char **pobject_prefix) - { - size_t size; - void *reply_buf; -+ char *object_prefix; - int ret; - void *p; - -@@ -5532,16 +5499,16 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) - goto out; - - p = reply_buf; -- rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, -- p + ret, NULL, GFP_NOIO); -+ object_prefix = ceph_extract_encoded_string(&p, p + ret, NULL, -+ GFP_NOIO); -+ if (IS_ERR(object_prefix)) { -+ ret = PTR_ERR(object_prefix); -+ goto out; -+ } - ret = 0; - -- if (IS_ERR(rbd_dev->header.object_prefix)) { -- ret = PTR_ERR(rbd_dev->header.object_prefix); -- rbd_dev->header.object_prefix = NULL; -- } else { -- dout(" object_prefix = %s\n", rbd_dev->header.object_prefix); -- } -+ *pobject_prefix = object_prefix; -+ dout(" object_prefix = %s\n", object_prefix); - out: - kfree(reply_buf); - -@@ -5592,13 +5559,6 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, - return 0; - } - --static int rbd_dev_v2_features(struct rbd_device *rbd_dev) --{ -- return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, -- rbd_is_ro(rbd_dev), -- &rbd_dev->header.features); --} -- - /* - * These are generic image flags, but since they are used only for - * object map, store them in rbd_dev->object_map_flags. -@@ -5635,6 +5595,14 @@ struct parent_image_info { - u64 overlap; - }; - -+static void rbd_parent_info_cleanup(struct parent_image_info *pii) -+{ -+ kfree(pii->pool_ns); -+ kfree(pii->image_id); -+ -+ memset(pii, 0, sizeof(*pii)); -+} -+ - /* - * The caller is responsible for @pii. - */ -@@ -5704,6 +5672,9 @@ static int __get_parent_info(struct rbd_device *rbd_dev, - if (pii->has_overlap) - ceph_decode_64_safe(&p, end, pii->overlap, e_inval); - -+ dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", -+ __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, -+ pii->has_overlap, pii->overlap); - return 0; - - e_inval: -@@ -5742,14 +5713,17 @@ static int __get_parent_info_legacy(struct rbd_device *rbd_dev, - pii->has_overlap = true; - ceph_decode_64_safe(&p, end, pii->overlap, e_inval); - -+ dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", -+ __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, -+ pii->has_overlap, pii->overlap); - return 0; - - e_inval: - return -EINVAL; - } - --static int get_parent_info(struct rbd_device *rbd_dev, -- struct parent_image_info *pii) -+static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev, -+ struct parent_image_info *pii) - { - struct page *req_page, *reply_page; - void *p; -@@ -5777,7 +5751,7 @@ static int get_parent_info(struct rbd_device *rbd_dev, - return ret; - } - --static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) -+static int rbd_dev_setup_parent(struct rbd_device *rbd_dev) - { - struct rbd_spec *parent_spec; - struct parent_image_info pii = { 0 }; -@@ -5787,37 +5761,12 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) - if (!parent_spec) - return -ENOMEM; - -- ret = get_parent_info(rbd_dev, &pii); -+ ret = rbd_dev_v2_parent_info(rbd_dev, &pii); - if (ret) - goto out_err; - -- dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", -- __func__, pii.pool_id, pii.pool_ns, pii.image_id, pii.snap_id, -- pii.has_overlap, pii.overlap); -- -- if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) { -- /* -- * Either the parent never existed, or we have -- * record of it but the image got flattened so it no -- * longer has a parent. When the parent of a -- * layered image disappears we immediately set the -- * overlap to 0. The effect of this is that all new -- * requests will be treated as if the image had no -- * parent. -- * -- * If !pii.has_overlap, the parent image spec is not -- * applicable. It's there to avoid duplication in each -- * snapshot record. -- */ -- if (rbd_dev->parent_overlap) { -- rbd_dev->parent_overlap = 0; -- rbd_dev_parent_put(rbd_dev); -- pr_info("%s: clone image has been flattened\n", -- rbd_dev->disk->disk_name); -- } -- -+ if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) - goto out; /* No parent? No problem. */ -- } - - /* The ceph file layout needs to fit pool id in 32 bits */ - -@@ -5829,58 +5778,46 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) - } - - /* -- * The parent won't change (except when the clone is -- * flattened, already handled that). So we only need to -- * record the parent spec we have not already done so. -+ * The parent won't change except when the clone is flattened, -+ * so we only need to record the parent image spec once. - */ -- if (!rbd_dev->parent_spec) { -- parent_spec->pool_id = pii.pool_id; -- if (pii.pool_ns && *pii.pool_ns) { -- parent_spec->pool_ns = pii.pool_ns; -- pii.pool_ns = NULL; -- } -- parent_spec->image_id = pii.image_id; -- pii.image_id = NULL; -- parent_spec->snap_id = pii.snap_id; -- -- rbd_dev->parent_spec = parent_spec; -- parent_spec = NULL; /* rbd_dev now owns this */ -+ parent_spec->pool_id = pii.pool_id; -+ if (pii.pool_ns && *pii.pool_ns) { -+ parent_spec->pool_ns = pii.pool_ns; -+ pii.pool_ns = NULL; - } -+ parent_spec->image_id = pii.image_id; -+ pii.image_id = NULL; -+ parent_spec->snap_id = pii.snap_id; -+ -+ rbd_assert(!rbd_dev->parent_spec); -+ rbd_dev->parent_spec = parent_spec; -+ parent_spec = NULL; /* rbd_dev now owns this */ - - /* -- * We always update the parent overlap. If it's zero we issue -- * a warning, as we will proceed as if there was no parent. -+ * Record the parent overlap. If it's zero, issue a warning as -+ * we will proceed as if there is no parent. - */ -- if (!pii.overlap) { -- if (parent_spec) { -- /* refresh, careful to warn just once */ -- if (rbd_dev->parent_overlap) -- rbd_warn(rbd_dev, -- "clone now standalone (overlap became 0)"); -- } else { -- /* initial probe */ -- rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); -- } -- } -+ if (!pii.overlap) -+ rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); - rbd_dev->parent_overlap = pii.overlap; - - out: - ret = 0; - out_err: -- kfree(pii.pool_ns); -- kfree(pii.image_id); -+ rbd_parent_info_cleanup(&pii); - rbd_spec_put(parent_spec); - return ret; - } - --static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) -+static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev, -+ u64 *stripe_unit, u64 *stripe_count) - { - struct { - __le64 stripe_unit; - __le64 stripe_count; - } __attribute__ ((packed)) striping_info_buf = { 0 }; - size_t size = sizeof (striping_info_buf); -- void *p; - int ret; - - ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, -@@ -5892,27 +5829,33 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) - if (ret < size) - return -ERANGE; - -- p = &striping_info_buf; -- rbd_dev->header.stripe_unit = ceph_decode_64(&p); -- rbd_dev->header.stripe_count = ceph_decode_64(&p); -+ *stripe_unit = le64_to_cpu(striping_info_buf.stripe_unit); -+ *stripe_count = le64_to_cpu(striping_info_buf.stripe_count); -+ dout(" stripe_unit = %llu stripe_count = %llu\n", *stripe_unit, -+ *stripe_count); -+ - return 0; - } - --static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) -+static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id) - { -- __le64 data_pool_id; -+ __le64 data_pool_buf; - int ret; - - ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, - &rbd_dev->header_oloc, "get_data_pool", -- NULL, 0, &data_pool_id, sizeof(data_pool_id)); -+ NULL, 0, &data_pool_buf, -+ sizeof(data_pool_buf)); -+ dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); - if (ret < 0) - return ret; -- if (ret < sizeof(data_pool_id)) -+ if (ret < sizeof(data_pool_buf)) - return -EBADMSG; - -- rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); -- WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); -+ *data_pool_id = le64_to_cpu(data_pool_buf); -+ dout(" data_pool_id = %lld\n", *data_pool_id); -+ WARN_ON(*data_pool_id == CEPH_NOPOOL); -+ - return 0; - } - -@@ -6104,7 +6047,8 @@ out_err: - return ret; - } - --static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) -+static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, -+ struct ceph_snap_context **psnapc) - { - size_t size; - int ret; -@@ -6165,9 +6109,7 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) - for (i = 0; i < snap_count; i++) - snapc->snaps[i] = ceph_decode_64(&p); - -- ceph_put_snap_context(rbd_dev->header.snapc); -- rbd_dev->header.snapc = snapc; -- -+ *psnapc = snapc; - dout(" snap context seq = %llu, snap_count = %u\n", - (unsigned long long)seq, (unsigned int)snap_count); - out: -@@ -6216,38 +6158,42 @@ out: - return snap_name; - } - --static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) -+static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev, -+ struct rbd_image_header *header, -+ bool first_time) - { -- bool first_time = rbd_dev->header.object_prefix == NULL; - int ret; - -- ret = rbd_dev_v2_image_size(rbd_dev); -+ ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, -+ first_time ? &header->obj_order : NULL, -+ &header->image_size); - if (ret) - return ret; - - if (first_time) { -- ret = rbd_dev_v2_header_onetime(rbd_dev); -+ ret = rbd_dev_v2_header_onetime(rbd_dev, header); - if (ret) - return ret; - } - -- ret = rbd_dev_v2_snap_context(rbd_dev); -- if (ret && first_time) { -- kfree(rbd_dev->header.object_prefix); -- rbd_dev->header.object_prefix = NULL; -- } -+ ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc); -+ if (ret) -+ return ret; - -- return ret; -+ return 0; - } - --static int rbd_dev_header_info(struct rbd_device *rbd_dev) -+static int rbd_dev_header_info(struct rbd_device *rbd_dev, -+ struct rbd_image_header *header, -+ bool first_time) - { - rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); -+ rbd_assert(!header->object_prefix && !header->snapc); - - if (rbd_dev->image_format == 1) -- return rbd_dev_v1_header_info(rbd_dev); -+ return rbd_dev_v1_header_info(rbd_dev, header, first_time); - -- return rbd_dev_v2_header_info(rbd_dev); -+ return rbd_dev_v2_header_info(rbd_dev, header, first_time); - } - - /* -@@ -6735,60 +6681,49 @@ out: - */ - static void rbd_dev_unprobe(struct rbd_device *rbd_dev) - { -- struct rbd_image_header *header; -- - rbd_dev_parent_put(rbd_dev); - rbd_object_map_free(rbd_dev); - rbd_dev_mapping_clear(rbd_dev); - - /* Free dynamic fields from the header, then zero it out */ - -- header = &rbd_dev->header; -- ceph_put_snap_context(header->snapc); -- kfree(header->snap_sizes); -- kfree(header->snap_names); -- kfree(header->object_prefix); -- memset(header, 0, sizeof (*header)); -+ rbd_image_header_cleanup(&rbd_dev->header); - } - --static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) -+static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, -+ struct rbd_image_header *header) - { - int ret; - -- ret = rbd_dev_v2_object_prefix(rbd_dev); -+ ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix); - if (ret) -- goto out_err; -+ return ret; - - /* - * Get the and check features for the image. Currently the - * features are assumed to never change. - */ -- ret = rbd_dev_v2_features(rbd_dev); -+ ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, -+ rbd_is_ro(rbd_dev), &header->features); - if (ret) -- goto out_err; -+ return ret; - - /* If the image supports fancy striping, get its parameters */ - -- if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { -- ret = rbd_dev_v2_striping_info(rbd_dev); -- if (ret < 0) -- goto out_err; -+ if (header->features & RBD_FEATURE_STRIPINGV2) { -+ ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit, -+ &header->stripe_count); -+ if (ret) -+ return ret; - } - -- if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { -- ret = rbd_dev_v2_data_pool(rbd_dev); -+ if (header->features & RBD_FEATURE_DATA_POOL) { -+ ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id); - if (ret) -- goto out_err; -+ return ret; - } - -- rbd_init_layout(rbd_dev); - return 0; -- --out_err: -- rbd_dev->header.features = 0; -- kfree(rbd_dev->header.object_prefix); -- rbd_dev->header.object_prefix = NULL; -- return ret; - } - - /* -@@ -6983,13 +6918,15 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) - if (!depth) - down_write(&rbd_dev->header_rwsem); - -- ret = rbd_dev_header_info(rbd_dev); -+ ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true); - if (ret) { - if (ret == -ENOENT && !need_watch) - rbd_print_dne(rbd_dev, false); - goto err_out_probe; - } - -+ rbd_init_layout(rbd_dev); -+ - /* - * If this image is the one being mapped, we have pool name and - * id, image name and id, and snap name - need to fill snap id. -@@ -7018,7 +6955,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) - } - - if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { -- ret = rbd_dev_v2_parent_info(rbd_dev); -+ ret = rbd_dev_setup_parent(rbd_dev); - if (ret) - goto err_out_probe; - } -@@ -7044,6 +6981,107 @@ err_out_format: - return ret; - } - -+static void rbd_dev_update_header(struct rbd_device *rbd_dev, -+ struct rbd_image_header *header) -+{ -+ rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); -+ rbd_assert(rbd_dev->header.object_prefix); /* !first_time */ -+ -+ if (rbd_dev->header.image_size != header->image_size) { -+ rbd_dev->header.image_size = header->image_size; -+ -+ if (!rbd_is_snap(rbd_dev)) { -+ rbd_dev->mapping.size = header->image_size; -+ rbd_dev_update_size(rbd_dev); -+ } -+ } -+ -+ ceph_put_snap_context(rbd_dev->header.snapc); -+ rbd_dev->header.snapc = header->snapc; -+ header->snapc = NULL; -+ -+ if (rbd_dev->image_format == 1) { -+ kfree(rbd_dev->header.snap_names); -+ rbd_dev->header.snap_names = header->snap_names; -+ header->snap_names = NULL; -+ -+ kfree(rbd_dev->header.snap_sizes); -+ rbd_dev->header.snap_sizes = header->snap_sizes; -+ header->snap_sizes = NULL; -+ } -+} -+ -+static void rbd_dev_update_parent(struct rbd_device *rbd_dev, -+ struct parent_image_info *pii) -+{ -+ if (pii->pool_id == CEPH_NOPOOL || !pii->has_overlap) { -+ /* -+ * Either the parent never existed, or we have -+ * record of it but the image got flattened so it no -+ * longer has a parent. When the parent of a -+ * layered image disappears we immediately set the -+ * overlap to 0. The effect of this is that all new -+ * requests will be treated as if the image had no -+ * parent. -+ * -+ * If !pii.has_overlap, the parent image spec is not -+ * applicable. It's there to avoid duplication in each -+ * snapshot record. -+ */ -+ if (rbd_dev->parent_overlap) { -+ rbd_dev->parent_overlap = 0; -+ rbd_dev_parent_put(rbd_dev); -+ pr_info("%s: clone has been flattened\n", -+ rbd_dev->disk->disk_name); -+ } -+ } else { -+ rbd_assert(rbd_dev->parent_spec); -+ -+ /* -+ * Update the parent overlap. If it became zero, issue -+ * a warning as we will proceed as if there is no parent. -+ */ -+ if (!pii->overlap && rbd_dev->parent_overlap) -+ rbd_warn(rbd_dev, -+ "clone has become standalone (overlap 0)"); -+ rbd_dev->parent_overlap = pii->overlap; -+ } -+} -+ -+static int rbd_dev_refresh(struct rbd_device *rbd_dev) -+{ -+ struct rbd_image_header header = { 0 }; -+ struct parent_image_info pii = { 0 }; -+ int ret; -+ -+ dout("%s rbd_dev %p\n", __func__, rbd_dev); -+ -+ ret = rbd_dev_header_info(rbd_dev, &header, false); -+ if (ret) -+ goto out; -+ -+ /* -+ * If there is a parent, see if it has disappeared due to the -+ * mapped image getting flattened. -+ */ -+ if (rbd_dev->parent) { -+ ret = rbd_dev_v2_parent_info(rbd_dev, &pii); -+ if (ret) -+ goto out; -+ } -+ -+ down_write(&rbd_dev->header_rwsem); -+ rbd_dev_update_header(rbd_dev, &header); -+ if (rbd_dev->parent) -+ rbd_dev_update_parent(rbd_dev, &pii); -+ up_write(&rbd_dev->header_rwsem); -+ -+out: -+ rbd_parent_info_cleanup(&pii); -+ rbd_image_header_cleanup(&header); -+ return ret; -+} -+ - static ssize_t do_rbd_add(struct bus_type *bus, - const char *buf, - size_t count) -diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c -index 60051c0cabeaa..e322a326546b5 100644 ---- a/drivers/firewire/sbp2.c -+++ b/drivers/firewire/sbp2.c -@@ -81,7 +81,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " - * - * - power condition - * Set the power condition field in the START STOP UNIT commands sent by -- * sd_mod on suspend, resume, and shutdown (if manage_start_stop is on). -+ * sd_mod on suspend, resume, and shutdown (if manage_system_start_stop or -+ * manage_runtime_start_stop is on). - * Some disks need this to spin down or to resume properly. - * - * - override internal blacklist -@@ -1517,8 +1518,10 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) - - sdev->use_10_for_rw = 1; - -- if (sbp2_param_exclusive_login) -- sdev->manage_start_stop = 1; -+ if (sbp2_param_exclusive_login) { -+ sdev->manage_system_start_stop = true; -+ sdev->manage_runtime_start_stop = true; -+ } - - if (sdev->type == TYPE_ROM) - sdev->use_10_for_ms = 1; -diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c -index 318a7d95a1a8b..42d3e1cf73528 100644 ---- a/drivers/gpio/gpio-aspeed.c -+++ b/drivers/gpio/gpio-aspeed.c -@@ -963,7 +963,7 @@ static int aspeed_gpio_set_config(struct gpio_chip *chip, unsigned int offset, - else if (param == PIN_CONFIG_BIAS_DISABLE || - param == PIN_CONFIG_BIAS_PULL_DOWN || - param == PIN_CONFIG_DRIVE_STRENGTH) -- return pinctrl_gpio_set_config(offset, config); -+ return pinctrl_gpio_set_config(chip->base + offset, config); - else if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN || - param == PIN_CONFIG_DRIVE_OPEN_SOURCE) - /* Return -ENOTSUPP to trigger emulation, as per datasheet */ -diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c -index 1198ab0305d03..b90357774dc04 100644 ---- a/drivers/gpio/gpio-pxa.c -+++ b/drivers/gpio/gpio-pxa.c -@@ -243,6 +243,7 @@ static bool pxa_gpio_has_pinctrl(void) - switch (gpio_type) { - case PXA3XX_GPIO: - case MMP2_GPIO: -+ case MMP_GPIO: - return false; - - default: -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index 5f5999cea7d2c..92fa2faf63e41 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -2179,7 +2179,7 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) - adev->flags |= AMD_IS_PX; - - if (!(adev->flags & AMD_IS_APU)) { -- parent = pci_upstream_bridge(adev->pdev); -+ parent = pcie_find_root_port(adev->pdev); - adev->has_pr3 = parent ? pci_pr3_present(parent) : false; - } - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 18274ff5082ad..339f1f5a08339 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -2344,14 +2344,62 @@ static int dm_late_init(void *handle) - return detect_mst_link_for_all_connectors(adev_to_drm(adev)); - } - -+static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr) -+{ -+ int ret; -+ u8 guid[16]; -+ u64 tmp64; -+ -+ mutex_lock(&mgr->lock); -+ if (!mgr->mst_primary) -+ goto out_fail; -+ -+ if (drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd) < 0) { -+ drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n"); -+ goto out_fail; -+ } -+ -+ ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, -+ DP_MST_EN | -+ DP_UP_REQ_EN | -+ DP_UPSTREAM_IS_SRC); -+ if (ret < 0) { -+ drm_dbg_kms(mgr->dev, "mst write failed - undocked during suspend?\n"); -+ goto out_fail; -+ } -+ -+ /* Some hubs forget their guids after they resume */ -+ ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); -+ if (ret != 16) { -+ drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n"); -+ goto out_fail; -+ } -+ -+ if (memchr_inv(guid, 0, 16) == NULL) { -+ tmp64 = get_jiffies_64(); -+ memcpy(&guid[0], &tmp64, sizeof(u64)); -+ memcpy(&guid[8], &tmp64, sizeof(u64)); -+ -+ ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, guid, 16); -+ -+ if (ret != 16) { -+ drm_dbg_kms(mgr->dev, "check mstb guid failed - undocked during suspend?\n"); -+ goto out_fail; -+ } -+ } -+ -+ memcpy(mgr->mst_primary->guid, guid, 16); -+ -+out_fail: -+ mutex_unlock(&mgr->lock); -+} -+ - static void s3_handle_mst(struct drm_device *dev, bool suspend) - { - struct amdgpu_dm_connector *aconnector; - struct drm_connector *connector; - struct drm_connector_list_iter iter; - struct drm_dp_mst_topology_mgr *mgr; -- int ret; -- bool need_hotplug = false; - - drm_connector_list_iter_begin(dev, &iter); - drm_for_each_connector_iter(connector, &iter) { -@@ -2373,18 +2421,15 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend) - if (!dp_is_lttpr_present(aconnector->dc_link)) - dc_link_aux_try_to_configure_timeout(aconnector->dc_link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD); - -- ret = drm_dp_mst_topology_mgr_resume(mgr, true); -- if (ret < 0) { -- dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx, -- aconnector->dc_link); -- need_hotplug = true; -- } -+ /* TODO: move resume_mst_branch_status() into drm mst resume again -+ * once topology probing work is pulled out from mst resume into mst -+ * resume 2nd step. mst resume 2nd step should be called after old -+ * state getting restored (i.e. drm_atomic_helper_resume()). -+ */ -+ resume_mst_branch_status(mgr); - } - } - drm_connector_list_iter_end(&iter); -- -- if (need_hotplug) -- drm_kms_helper_hotplug_event(dev); - } - - static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev) -@@ -2773,7 +2818,8 @@ static int dm_resume(void *handle) - struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state); - enum dc_connection_type new_connection_type = dc_connection_none; - struct dc_state *dc_state; -- int i, r, j; -+ int i, r, j, ret; -+ bool need_hotplug = false; - - if (amdgpu_in_reset(adev)) { - dc_state = dm->cached_dc_state; -@@ -2871,7 +2917,7 @@ static int dm_resume(void *handle) - continue; - - /* -- * this is the case when traversing through already created -+ * this is the case when traversing through already created end sink - * MST connectors, should be skipped - */ - if (aconnector && aconnector->mst_port) -@@ -2931,6 +2977,27 @@ static int dm_resume(void *handle) - - dm->cached_state = NULL; - -+ /* Do mst topology probing after resuming cached state*/ -+ drm_connector_list_iter_begin(ddev, &iter); -+ drm_for_each_connector_iter(connector, &iter) { -+ aconnector = to_amdgpu_dm_connector(connector); -+ if (aconnector->dc_link->type != dc_connection_mst_branch || -+ aconnector->mst_port) -+ continue; -+ -+ ret = drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr, true); -+ -+ if (ret < 0) { -+ dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx, -+ aconnector->dc_link); -+ need_hotplug = true; -+ } -+ } -+ drm_connector_list_iter_end(&iter); -+ -+ if (need_hotplug) -+ drm_kms_helper_hotplug_event(ddev); -+ - amdgpu_dm_irq_resume_late(adev); - - amdgpu_dm_smu_write_watermarks_table(adev); -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -index 839a812e0da32..fbc4d706748b7 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -@@ -2081,36 +2081,41 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context - return ret; - } - -+#define MAX(a, b) ((a) > (b) ? (a) : (b)) -+ - static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu, - uint32_t pcie_gen_cap, - uint32_t pcie_width_cap) - { - struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; - struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table; -- u32 smu_pcie_arg; -+ uint8_t *table_member1, *table_member2; -+ uint32_t min_gen_speed, max_gen_speed; -+ uint32_t min_lane_width, max_lane_width; -+ uint32_t smu_pcie_arg; - int ret, i; - -- /* PCIE gen speed and lane width override */ -- if (!amdgpu_device_pcie_dynamic_switching_supported()) { -- if (pcie_table->pcie_gen[NUM_LINK_LEVELS - 1] < pcie_gen_cap) -- pcie_gen_cap = pcie_table->pcie_gen[NUM_LINK_LEVELS - 1]; -+ GET_PPTABLE_MEMBER(PcieGenSpeed, &table_member1); -+ GET_PPTABLE_MEMBER(PcieLaneCount, &table_member2); - -- if (pcie_table->pcie_lane[NUM_LINK_LEVELS - 1] < pcie_width_cap) -- pcie_width_cap = pcie_table->pcie_lane[NUM_LINK_LEVELS - 1]; -+ min_gen_speed = MAX(0, table_member1[0]); -+ max_gen_speed = MIN(pcie_gen_cap, table_member1[1]); -+ min_gen_speed = min_gen_speed > max_gen_speed ? -+ max_gen_speed : min_gen_speed; -+ min_lane_width = MAX(1, table_member2[0]); -+ max_lane_width = MIN(pcie_width_cap, table_member2[1]); -+ min_lane_width = min_lane_width > max_lane_width ? -+ max_lane_width : min_lane_width; - -- /* Force all levels to use the same settings */ -- for (i = 0; i < NUM_LINK_LEVELS; i++) { -- pcie_table->pcie_gen[i] = pcie_gen_cap; -- pcie_table->pcie_lane[i] = pcie_width_cap; -- } -+ if (!amdgpu_device_pcie_dynamic_switching_supported()) { -+ pcie_table->pcie_gen[0] = max_gen_speed; -+ pcie_table->pcie_lane[0] = max_lane_width; - } else { -- for (i = 0; i < NUM_LINK_LEVELS; i++) { -- if (pcie_table->pcie_gen[i] > pcie_gen_cap) -- pcie_table->pcie_gen[i] = pcie_gen_cap; -- if (pcie_table->pcie_lane[i] > pcie_width_cap) -- pcie_table->pcie_lane[i] = pcie_width_cap; -- } -+ pcie_table->pcie_gen[0] = min_gen_speed; -+ pcie_table->pcie_lane[0] = min_lane_width; - } -+ pcie_table->pcie_gen[1] = max_gen_speed; -+ pcie_table->pcie_lane[1] = max_lane_width; - - for (i = 0; i < NUM_LINK_LEVELS; i++) { - smu_pcie_arg = (i << 16 | -diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c -index 03691cdcfb8e1..f7f7252d839ee 100644 ---- a/drivers/hid/hid-sony.c -+++ b/drivers/hid/hid-sony.c -@@ -3074,6 +3074,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) - return ret; - - err: -+ usb_free_urb(sc->ghl_urb); -+ - hid_hw_stop(hdev); - return ret; - } -diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c -index 55cb25038e632..710fda5f19e1c 100644 ---- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c -+++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c -@@ -133,6 +133,14 @@ static int enable_gpe(struct device *dev) - } - wakeup = &adev->wakeup; - -+ /* -+ * Call acpi_disable_gpe(), so that reference count -+ * gpe_event_info->runtime_count doesn't overflow. -+ * When gpe_event_info->runtime_count = 0, the call -+ * to acpi_disable_gpe() simply return. -+ */ -+ acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); -+ - acpi_sts = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); - if (ACPI_FAILURE(acpi_sts)) { - dev_err(dev, "enable ose_gpe failed\n"); -diff --git a/drivers/hwmon/nzxt-smart2.c b/drivers/hwmon/nzxt-smart2.c -index 533f38b0b4e9b..a8e72d8fd0605 100644 ---- a/drivers/hwmon/nzxt-smart2.c -+++ b/drivers/hwmon/nzxt-smart2.c -@@ -791,6 +791,8 @@ static const struct hid_device_id nzxt_smart2_hid_id_table[] = { - { HID_USB_DEVICE(0x1e71, 0x2009) }, /* NZXT RGB & Fan Controller */ - { HID_USB_DEVICE(0x1e71, 0x200e) }, /* NZXT RGB & Fan Controller */ - { HID_USB_DEVICE(0x1e71, 0x2010) }, /* NZXT RGB & Fan Controller */ -+ { HID_USB_DEVICE(0x1e71, 0x2011) }, /* NZXT RGB & Fan Controller (6 RGB) */ -+ { HID_USB_DEVICE(0x1e71, 0x2019) }, /* NZXT RGB & Fan Controller (6 RGB) */ - {}, - }; - -diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c -index cfeb24d40d378..bb3d10099ba44 100644 ---- a/drivers/idle/intel_idle.c -+++ b/drivers/idle/intel_idle.c -@@ -1430,6 +1430,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { - X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &idle_cpu_adl_l), - X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &idle_cpu_adl_n), - X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &idle_cpu_spr), -+ X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &idle_cpu_spr), - X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl), - X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl), - X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt), -@@ -1862,6 +1863,7 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) - skx_idle_state_table_update(); - break; - case INTEL_FAM6_SAPPHIRERAPIDS_X: -+ case INTEL_FAM6_EMERALDRAPIDS_X: - spr_idle_state_table_update(); - break; - case INTEL_FAM6_ALDERLAKE: -diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c -index 4632b1833381a..0773ca7ace247 100644 ---- a/drivers/infiniband/core/cma.c -+++ b/drivers/infiniband/core/cma.c -@@ -4936,7 +4936,7 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv, - int err = 0; - struct sockaddr *addr = (struct sockaddr *)&mc->addr; - struct net_device *ndev = NULL; -- struct ib_sa_multicast ib; -+ struct ib_sa_multicast ib = {}; - enum ib_gid_type gid_type; - bool send_only; - -diff --git a/drivers/infiniband/core/cma_configfs.c b/drivers/infiniband/core/cma_configfs.c -index 7b68b3ea979f7..f2fb2d8a65970 100644 ---- a/drivers/infiniband/core/cma_configfs.c -+++ b/drivers/infiniband/core/cma_configfs.c -@@ -217,7 +217,7 @@ static int make_cma_ports(struct cma_dev_group *cma_dev_group, - return -ENOMEM; - - for (i = 0; i < ports_num; i++) { -- char port_str[10]; -+ char port_str[11]; - - ports[i].port_num = i + 1; - snprintf(port_str, sizeof(port_str), "%u", i + 1); -diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c -index 222733a83ddb7..1adf20198afd1 100644 ---- a/drivers/infiniband/core/nldev.c -+++ b/drivers/infiniband/core/nldev.c -@@ -2501,6 +2501,7 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = { - }, - [RDMA_NLDEV_CMD_SYS_SET] = { - .doit = nldev_set_sys_set_doit, -+ .flags = RDMA_NL_ADMIN_PERM, - }, - [RDMA_NLDEV_CMD_STAT_SET] = { - .doit = nldev_stat_set_doit, -diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c -index fa937cd268219..6fe825800494c 100644 ---- a/drivers/infiniband/core/uverbs_main.c -+++ b/drivers/infiniband/core/uverbs_main.c -@@ -535,7 +535,7 @@ static ssize_t verify_hdr(struct ib_uverbs_cmd_hdr *hdr, - if (hdr->in_words * 4 != count) - return -EINVAL; - -- if (count < method_elm->req_size + sizeof(hdr)) { -+ if (count < method_elm->req_size + sizeof(*hdr)) { - /* - * rdma-core v18 and v19 have a bug where they send DESTROY_CQ - * with a 16 byte write instead of 24. Old kernels didn't -diff --git a/drivers/infiniband/hw/mlx4/sysfs.c b/drivers/infiniband/hw/mlx4/sysfs.c -index 24ee79aa2122e..88f534cf690e9 100644 ---- a/drivers/infiniband/hw/mlx4/sysfs.c -+++ b/drivers/infiniband/hw/mlx4/sysfs.c -@@ -223,7 +223,7 @@ void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num, - static int add_port_entries(struct mlx4_ib_dev *device, int port_num) - { - int i; -- char buff[11]; -+ char buff[12]; - struct mlx4_ib_iov_port *port = NULL; - int ret = 0 ; - struct ib_port_attr attr; -diff --git a/drivers/infiniband/hw/mlx5/fs.c b/drivers/infiniband/hw/mlx5/fs.c -index 5a13d902b0641..1022cebd0a46e 100644 ---- a/drivers/infiniband/hw/mlx5/fs.c -+++ b/drivers/infiniband/hw/mlx5/fs.c -@@ -2471,8 +2471,8 @@ destroy_res: - mlx5_steering_anchor_destroy_res(ft_prio); - put_flow_table: - put_flow_table(dev, ft_prio, true); -- mutex_unlock(&dev->flow_db->lock); - free_obj: -+ mutex_unlock(&dev->flow_db->lock); - kfree(obj); - - return err; -diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c -index 3178df55c4d85..0baf3b5518b46 100644 ---- a/drivers/infiniband/hw/mlx5/main.c -+++ b/drivers/infiniband/hw/mlx5/main.c -@@ -2074,7 +2074,7 @@ static inline char *mmap_cmd2str(enum mlx5_ib_mmap_cmd cmd) - case MLX5_IB_MMAP_DEVICE_MEM: - return "Device Memory"; - default: -- return NULL; -+ return "Unknown"; - } - } - -diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c -index 552d8271e423b..dc679c34ceefa 100644 ---- a/drivers/infiniband/sw/siw/siw_cm.c -+++ b/drivers/infiniband/sw/siw/siw_cm.c -@@ -973,6 +973,7 @@ static void siw_accept_newconn(struct siw_cep *cep) - siw_cep_put(cep); - new_cep->listen_cep = NULL; - if (rv) { -+ siw_cancel_mpatimer(new_cep); - siw_cep_set_free(new_cep); - goto error; - } -@@ -1097,9 +1098,12 @@ static void siw_cm_work_handler(struct work_struct *w) - /* - * Socket close before MPA request received. - */ -- siw_dbg_cep(cep, "no mpareq: drop listener\n"); -- siw_cep_put(cep->listen_cep); -- cep->listen_cep = NULL; -+ if (cep->listen_cep) { -+ siw_dbg_cep(cep, -+ "no mpareq: drop listener\n"); -+ siw_cep_put(cep->listen_cep); -+ cep->listen_cep = NULL; -+ } - } - } - release_cep = 1; -@@ -1222,7 +1226,11 @@ static void siw_cm_llp_data_ready(struct sock *sk) - if (!cep) - goto out; - -- siw_dbg_cep(cep, "state: %d\n", cep->state); -+ siw_dbg_cep(cep, "cep state: %d, socket state %d\n", -+ cep->state, sk->sk_state); -+ -+ if (sk->sk_state != TCP_ESTABLISHED) -+ goto out; - - switch (cep->state) { - case SIW_EPSTATE_RDMA_MODE: -diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c -index a7580c4855fec..c4dcef76e9646 100644 ---- a/drivers/infiniband/ulp/srp/ib_srp.c -+++ b/drivers/infiniband/ulp/srp/ib_srp.c -@@ -2789,7 +2789,6 @@ static int srp_abort(struct scsi_cmnd *scmnd) - u32 tag; - u16 ch_idx; - struct srp_rdma_ch *ch; -- int ret; - - shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); - -@@ -2803,19 +2802,14 @@ static int srp_abort(struct scsi_cmnd *scmnd) - shost_printk(KERN_ERR, target->scsi_host, - "Sending SRP abort for tag %#x\n", tag); - if (srp_send_tsk_mgmt(ch, tag, scmnd->device->lun, -- SRP_TSK_ABORT_TASK, NULL) == 0) -- ret = SUCCESS; -- else if (target->rport->state == SRP_RPORT_LOST) -- ret = FAST_IO_FAIL; -- else -- ret = FAILED; -- if (ret == SUCCESS) { -+ SRP_TSK_ABORT_TASK, NULL) == 0) { - srp_free_req(ch, req, scmnd, 0); -- scmnd->result = DID_ABORT << 16; -- scsi_done(scmnd); -+ return SUCCESS; - } -+ if (target->rport->state == SRP_RPORT_LOST) -+ return FAST_IO_FAIL; - -- return ret; -+ return FAILED; - } - - static int srp_reset_device(struct scsi_cmnd *scmnd) -diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -index db33dc87f69ed..8966f7d5aab61 100644 ---- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -@@ -1886,13 +1886,23 @@ static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd, - /* Get the leaf page size */ - tg = __ffs(smmu_domain->domain.pgsize_bitmap); - -+ num_pages = size >> tg; -+ - /* Convert page size of 12,14,16 (log2) to 1,2,3 */ - cmd->tlbi.tg = (tg - 10) / 2; - -- /* Determine what level the granule is at */ -- cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3)); -- -- num_pages = size >> tg; -+ /* -+ * Determine what level the granule is at. For non-leaf, both -+ * io-pgtable and SVA pass a nominal last-level granule because -+ * they don't know what level(s) actually apply, so ignore that -+ * and leave TTL=0. However for various errata reasons we still -+ * want to use a range command, so avoid the SVA corner case -+ * where both scale and num could be 0 as well. -+ */ -+ if (cmd->tlbi.leaf) -+ cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3)); -+ else if ((num_pages & CMDQ_TLBI_RANGE_NUM_MAX) == 1) -+ num_pages++; - } - - cmds.num = 0; -diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c -index d4b5d20bd6dda..5c4f5aa8e87e4 100644 ---- a/drivers/iommu/intel/iommu.c -+++ b/drivers/iommu/intel/iommu.c -@@ -3163,13 +3163,6 @@ static int iommu_suspend(void) - struct intel_iommu *iommu = NULL; - unsigned long flag; - -- for_each_active_iommu(iommu, drhd) { -- iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32), -- GFP_KERNEL); -- if (!iommu->iommu_state) -- goto nomem; -- } -- - iommu_flush_all(); - - for_each_active_iommu(iommu, drhd) { -@@ -3189,12 +3182,6 @@ static int iommu_suspend(void) - raw_spin_unlock_irqrestore(&iommu->register_lock, flag); - } - return 0; -- --nomem: -- for_each_active_iommu(iommu, drhd) -- kfree(iommu->iommu_state); -- -- return -ENOMEM; - } - - static void iommu_resume(void) -@@ -3226,9 +3213,6 @@ static void iommu_resume(void) - - raw_spin_unlock_irqrestore(&iommu->register_lock, flag); - } -- -- for_each_active_iommu(iommu, drhd) -- kfree(iommu->iommu_state); - } - - static struct syscore_ops iommu_syscore_ops = { -diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h -index db9df7c3790cd..c99cb715bd9a2 100644 ---- a/drivers/iommu/intel/iommu.h -+++ b/drivers/iommu/intel/iommu.h -@@ -595,7 +595,7 @@ struct intel_iommu { - struct iopf_queue *iopf_queue; - unsigned char iopfq_name[16]; - struct q_inval *qi; /* Queued invalidation info */ -- u32 *iommu_state; /* Store iommu states between suspend and resume.*/ -+ u32 iommu_state[MAX_SR_DMAR_REGS]; /* Store iommu states between suspend and resume.*/ - - #ifdef CONFIG_IRQ_REMAP - struct ir_table *ir_table; /* Interrupt remapping info */ -diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c -index 9673cd60c84fc..0ba2a63a9538a 100644 ---- a/drivers/iommu/mtk_iommu.c -+++ b/drivers/iommu/mtk_iommu.c -@@ -223,7 +223,7 @@ struct mtk_iommu_data { - struct device *smicomm_dev; - - struct mtk_iommu_bank_data *bank; -- struct mtk_iommu_domain *share_dom; /* For 2 HWs share pgtable */ -+ struct mtk_iommu_domain *share_dom; - - struct regmap *pericfg; - struct mutex mutex; /* Protect m4u_group/m4u_dom above */ -@@ -579,8 +579,8 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, - struct mtk_iommu_domain *share_dom = data->share_dom; - const struct mtk_iommu_iova_region *region; - -- /* Always use share domain in sharing pgtable case */ -- if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE) && share_dom) { -+ /* Share pgtable when 2 MM IOMMU share the pgtable or one IOMMU use multiple iova ranges */ -+ if (share_dom) { - dom->iop = share_dom->iop; - dom->cfg = share_dom->cfg; - dom->domain.pgsize_bitmap = share_dom->cfg.pgsize_bitmap; -@@ -613,8 +613,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, - /* Update our support page sizes bitmap */ - dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap; - -- if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) -- data->share_dom = dom; -+ data->share_dom = dom; - - update_iova_region: - /* Update the iova region for this domain */ -diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c -index aad8bc44459fe..d94d60b526461 100644 ---- a/drivers/leds/led-core.c -+++ b/drivers/leds/led-core.c -@@ -424,10 +424,6 @@ int led_compose_name(struct device *dev, struct led_init_data *init_data, - - led_parse_fwnode_props(dev, fwnode, &props); - -- /* We want to label LEDs that can produce full range of colors -- * as RGB, not multicolor */ -- BUG_ON(props.color == LED_COLOR_ID_MULTI); -- - if (props.label) { - /* - * If init_data.devicename is NULL, then it indicates that -diff --git a/drivers/md/dm-zoned-target.c b/drivers/md/dm-zoned-target.c -index 95b132b52f332..4abe1e2f8ad81 100644 ---- a/drivers/md/dm-zoned-target.c -+++ b/drivers/md/dm-zoned-target.c -@@ -748,17 +748,16 @@ err: - /* - * Cleanup zoned device information. - */ --static void dmz_put_zoned_device(struct dm_target *ti) -+static void dmz_put_zoned_devices(struct dm_target *ti) - { - struct dmz_target *dmz = ti->private; - int i; - -- for (i = 0; i < dmz->nr_ddevs; i++) { -- if (dmz->ddev[i]) { -+ for (i = 0; i < dmz->nr_ddevs; i++) -+ if (dmz->ddev[i]) - dm_put_device(ti, dmz->ddev[i]); -- dmz->ddev[i] = NULL; -- } -- } -+ -+ kfree(dmz->ddev); - } - - static int dmz_fixup_devices(struct dm_target *ti) -@@ -948,7 +947,7 @@ err_bio: - err_meta: - dmz_dtr_metadata(dmz->metadata); - err_dev: -- dmz_put_zoned_device(ti); -+ dmz_put_zoned_devices(ti); - err: - kfree(dmz->dev); - kfree(dmz); -@@ -978,7 +977,7 @@ static void dmz_dtr(struct dm_target *ti) - - bioset_exit(&dmz->bio_set); - -- dmz_put_zoned_device(ti); -+ dmz_put_zoned_devices(ti); - - mutex_destroy(&dmz->chunk_lock); - -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index fbef3c9badb65..98d4e93efa31c 100644 ---- a/drivers/md/raid5.c -+++ b/drivers/md/raid5.c -@@ -854,6 +854,13 @@ struct stripe_head *raid5_get_active_stripe(struct r5conf *conf, - - set_bit(R5_INACTIVE_BLOCKED, &conf->cache_state); - r5l_wake_reclaim(conf->log, 0); -+ -+ /* release batch_last before wait to avoid risk of deadlock */ -+ if (ctx && ctx->batch_last) { -+ raid5_release_stripe(ctx->batch_last); -+ ctx->batch_last = NULL; -+ } -+ - wait_event_lock_irq(conf->wait_for_stripe, - is_inactive_blocked(conf, hash), - *(conf->hash_locks + hash)); -diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c -index 1662c12e24ada..6fbd77dc1d18f 100644 ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -893,6 +893,13 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, - return -EINVAL; - } - -+ /* UBI cannot work on flashes with zero erasesize. */ -+ if (!mtd->erasesize) { -+ pr_err("ubi: refuse attaching mtd%d - zero erasesize flash is not supported\n", -+ mtd->index); -+ return -EINVAL; -+ } -+ - if (ubi_num == UBI_DEV_NUM_AUTO) { - /* Search for an empty slot in the @ubi_devices array */ - for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) -diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c -index a73008b9e0b3c..ba906dfab055c 100644 ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3012,14 +3012,16 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip) - * from the wrong location resulting in the switch booting - * to wrong mode and inoperable. - */ -- mv88e6xxx_g1_wait_eeprom_done(chip); -+ if (chip->info->ops->get_eeprom) -+ mv88e6xxx_g2_eeprom_wait(chip); - - gpiod_set_value_cansleep(gpiod, 1); - usleep_range(10000, 20000); - gpiod_set_value_cansleep(gpiod, 0); - usleep_range(10000, 20000); - -- mv88e6xxx_g1_wait_eeprom_done(chip); -+ if (chip->info->ops->get_eeprom) -+ mv88e6xxx_g2_eeprom_wait(chip); - } - } - -diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c -index 5848112036b08..964928285782c 100644 ---- a/drivers/net/dsa/mv88e6xxx/global1.c -+++ b/drivers/net/dsa/mv88e6xxx/global1.c -@@ -75,37 +75,6 @@ static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip) - return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1); - } - --void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip) --{ -- const unsigned long timeout = jiffies + 1 * HZ; -- u16 val; -- int err; -- -- /* Wait up to 1 second for the switch to finish reading the -- * EEPROM. -- */ -- while (time_before(jiffies, timeout)) { -- err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val); -- if (err) { -- dev_err(chip->dev, "Error reading status"); -- return; -- } -- -- /* If the switch is still resetting, it may not -- * respond on the bus, and so MDIO read returns -- * 0xffff. Differentiate between that, and waiting for -- * the EEPROM to be done by bit 0 being set. -- */ -- if (val != 0xffff && -- val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE)) -- return; -- -- usleep_range(1000, 2000); -- } -- -- dev_err(chip->dev, "Timeout waiting for EEPROM done"); --} -- - /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 - * Offset 0x02: Switch MAC Address Register Bytes 2 & 3 - * Offset 0x03: Switch MAC Address Register Bytes 4 & 5 -diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h -index 65958b2a0d3a3..04b57a21f7868 100644 ---- a/drivers/net/dsa/mv88e6xxx/global1.h -+++ b/drivers/net/dsa/mv88e6xxx/global1.h -@@ -281,7 +281,6 @@ int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr); - int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip); - int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip); - int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip); --void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip); - - int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip); - int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip); -diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c -index ec49939968fac..ac302a935ce69 100644 ---- a/drivers/net/dsa/mv88e6xxx/global2.c -+++ b/drivers/net/dsa/mv88e6xxx/global2.c -@@ -340,7 +340,7 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip) - * Offset 0x15: EEPROM Addr (for 8-bit data access) - */ - --static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) -+int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) - { - int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY); - int err; -diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h -index c05fad5c9f19d..751a6c988de42 100644 ---- a/drivers/net/dsa/mv88e6xxx/global2.h -+++ b/drivers/net/dsa/mv88e6xxx/global2.h -@@ -359,6 +359,7 @@ int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip); - - int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, - int port); -+int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip); - - extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops; - extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops; -diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c -index 0b4ec6e41eb41..1d21a281222d9 100644 ---- a/drivers/net/ethernet/ibm/ibmveth.c -+++ b/drivers/net/ethernet/ibm/ibmveth.c -@@ -1308,24 +1308,23 @@ static void ibmveth_rx_csum_helper(struct sk_buff *skb, - * the user space for finding a flow. During this process, OVS computes - * checksum on the first packet when CHECKSUM_PARTIAL flag is set. - * -- * So, re-compute TCP pseudo header checksum when configured for -- * trunk mode. -+ * So, re-compute TCP pseudo header checksum. - */ -+ - if (iph_proto == IPPROTO_TCP) { - struct tcphdr *tcph = (struct tcphdr *)(skb->data + iphlen); -+ - if (tcph->check == 0x0000) { - /* Recompute TCP pseudo header checksum */ -- if (adapter->is_active_trunk) { -- tcphdrlen = skb->len - iphlen; -- if (skb_proto == ETH_P_IP) -- tcph->check = -- ~csum_tcpudp_magic(iph->saddr, -- iph->daddr, tcphdrlen, iph_proto, 0); -- else if (skb_proto == ETH_P_IPV6) -- tcph->check = -- ~csum_ipv6_magic(&iph6->saddr, -- &iph6->daddr, tcphdrlen, iph_proto, 0); -- } -+ tcphdrlen = skb->len - iphlen; -+ if (skb_proto == ETH_P_IP) -+ tcph->check = -+ ~csum_tcpudp_magic(iph->saddr, -+ iph->daddr, tcphdrlen, iph_proto, 0); -+ else if (skb_proto == ETH_P_IPV6) -+ tcph->check = -+ ~csum_ipv6_magic(&iph6->saddr, -+ &iph6->daddr, tcphdrlen, iph_proto, 0); - /* Setup SKB fields for checksum offload */ - skb_partial_csum_set(skb, iphlen, - offsetof(struct tcphdr, check)); -diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c -index ffea0c9c82f1e..97a9efe7b713e 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c -@@ -361,9 +361,9 @@ static int i40e_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) - 1000000ULL << 16); - - if (neg_adj) -- adj = I40E_PTP_40GB_INCVAL - diff; -+ adj = freq - diff; - else -- adj = I40E_PTP_40GB_INCVAL + diff; -+ adj = freq + diff; - - wr32(hw, I40E_PRTTSYN_INC_L, adj & 0xFFFFFFFF); - wr32(hw, I40E_PRTTSYN_INC_H, adj >> 32); -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 0ac5ae16308f6..17e6ac4445afc 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2862,8 +2862,8 @@ static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth) - - eth->rx_events++; - if (likely(napi_schedule_prep(ð->rx_napi))) { -- __napi_schedule(ð->rx_napi); - mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); -+ __napi_schedule(ð->rx_napi); - } - - return IRQ_HANDLED; -@@ -2875,8 +2875,8 @@ static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth) - - eth->tx_events++; - if (likely(napi_schedule_prep(ð->tx_napi))) { -- __napi_schedule(ð->tx_napi); - mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); -+ __napi_schedule(ð->tx_napi); - } - - return IRQ_HANDLED; -diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/drivers/net/ethernet/qlogic/qed/qed_ll2.h -index 0bfc375161ed6..a174c6fc626ac 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_ll2.h -+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.h -@@ -110,9 +110,9 @@ struct qed_ll2_info { - enum core_tx_dest tx_dest; - u8 tx_stats_en; - bool main_func_queue; -+ struct qed_ll2_cbs cbs; - struct qed_ll2_rx_queue rx_queue; - struct qed_ll2_tx_queue tx_queue; -- struct qed_ll2_cbs cbs; - }; - - extern const struct qed_ll2_ops qed_ll2_ops_pass; -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -index 2b38a499a4045..533f5245ad945 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c -@@ -105,6 +105,7 @@ struct stm32_ops { - int (*parse_data)(struct stm32_dwmac *dwmac, - struct device *dev); - u32 syscfg_eth_mask; -+ bool clk_rx_enable_in_suspend; - }; - - static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) -@@ -122,7 +123,8 @@ static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) - if (ret) - return ret; - -- if (!dwmac->dev->power.is_suspended) { -+ if (!dwmac->ops->clk_rx_enable_in_suspend || -+ !dwmac->dev->power.is_suspended) { - ret = clk_prepare_enable(dwmac->clk_rx); - if (ret) { - clk_disable_unprepare(dwmac->clk_tx); -@@ -515,7 +517,8 @@ static struct stm32_ops stm32mp1_dwmac_data = { - .suspend = stm32mp1_suspend, - .resume = stm32mp1_resume, - .parse_data = stm32mp1_parse_data, -- .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK -+ .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK, -+ .clk_rx_enable_in_suspend = true - }; - - static const struct of_device_id stm32_dwmac_match[] = { -diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c -index 25466cbdc16bd..9f2553799895d 100644 ---- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c -+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c -@@ -1614,6 +1614,7 @@ static int am65_cpsw_nuss_init_tx_chns(struct am65_cpsw_common *common) - if (tx_chn->irq <= 0) { - dev_err(dev, "Failed to get tx dma irq %d\n", - tx_chn->irq); -+ ret = tx_chn->irq ?: -ENXIO; - goto err; - } - -diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c -index 5d6454fedb3f1..78ad2da3ee29b 100644 ---- a/drivers/net/usb/smsc75xx.c -+++ b/drivers/net/usb/smsc75xx.c -@@ -90,7 +90,9 @@ static int __must_check __smsc75xx_read_reg(struct usbnet *dev, u32 index, - ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN - | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, &buf, 4); -- if (unlikely(ret < 0)) { -+ if (unlikely(ret < 4)) { -+ ret = ret < 0 ? ret : -ENODATA; -+ - netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", - index, ret); - return ret; -diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c -index f6dcec66f0a4b..208df4d419395 100644 ---- a/drivers/net/vrf.c -+++ b/drivers/net/vrf.c -@@ -664,7 +664,7 @@ static int vrf_finish_output6(struct net *net, struct sock *sk, - skb->protocol = htons(ETH_P_IPV6); - skb->dev = dev; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr); - neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop); - if (unlikely(!neigh)) -@@ -672,10 +672,10 @@ static int vrf_finish_output6(struct net *net, struct sock *sk, - if (!IS_ERR(neigh)) { - sock_confirm_neigh(skb, neigh); - ret = neigh_output(neigh, skb, false); -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - return ret; - } -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - IP6_INC_STATS(dev_net(dst->dev), - ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); -@@ -889,7 +889,7 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s - } - } - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - - neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); - if (!IS_ERR(neigh)) { -@@ -898,11 +898,11 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s - sock_confirm_neigh(skb, neigh); - /* if crossing protocols, can not use the cached header */ - ret = neigh_output(neigh, skb, is_v6gw); -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - return ret; - } - -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - vrf_tx_error(skb->dev, skb); - return -EINVAL; - } -diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c -index 0c3eb850fcb79..619dd71c9d75e 100644 ---- a/drivers/net/vxlan/vxlan_core.c -+++ b/drivers/net/vxlan/vxlan_core.c -@@ -1910,7 +1910,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) - struct vxlan_fdb *f; - struct sk_buff *reply; - -- if (!(n->nud_state & NUD_CONNECTED)) { -+ if (!(READ_ONCE(n->nud_state) & NUD_CONNECTED)) { - neigh_release(n); - goto out; - } -@@ -2074,7 +2074,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) - struct vxlan_fdb *f; - struct sk_buff *reply; - -- if (!(n->nud_state & NUD_CONNECTED)) { -+ if (!(READ_ONCE(n->nud_state) & NUD_CONNECTED)) { - neigh_release(n); - goto out; - } -diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c -index 1c53b55469270..5fec8abe8e1d3 100644 ---- a/drivers/net/wan/fsl_ucc_hdlc.c -+++ b/drivers/net/wan/fsl_ucc_hdlc.c -@@ -34,6 +34,8 @@ - #define TDM_PPPOHT_SLIC_MAXIN - #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S) - -+static int uhdlc_close(struct net_device *dev); -+ - static struct ucc_tdm_info utdm_primary_info = { - .uf_info = { - .tsa = 0, -@@ -708,6 +710,7 @@ static int uhdlc_open(struct net_device *dev) - hdlc_device *hdlc = dev_to_hdlc(dev); - struct ucc_hdlc_private *priv = hdlc->priv; - struct ucc_tdm *utdm = priv->utdm; -+ int rc = 0; - - if (priv->hdlc_busy != 1) { - if (request_irq(priv->ut_info->uf_info.irq, -@@ -731,10 +734,13 @@ static int uhdlc_open(struct net_device *dev) - napi_enable(&priv->napi); - netdev_reset_queue(dev); - netif_start_queue(dev); -- hdlc_open(dev); -+ -+ rc = hdlc_open(dev); -+ if (rc) -+ uhdlc_close(dev); - } - -- return 0; -+ return rc; - } - - static void uhdlc_memclean(struct ucc_hdlc_private *priv) -@@ -824,6 +830,8 @@ static int uhdlc_close(struct net_device *dev) - netdev_reset_queue(dev); - priv->hdlc_busy = 0; - -+ hdlc_close(dev); -+ - return 0; - } - -diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h -index c62576e442bdf..2d481849a9c23 100644 ---- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h -+++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h -@@ -295,9 +295,9 @@ struct iwl_fw_ini_fifo_hdr { - struct iwl_fw_ini_error_dump_range { - __le32 range_data_size; - union { -- __le32 internal_base_addr; -- __le64 dram_base_addr; -- __le32 page_num; -+ __le32 internal_base_addr __packed; -+ __le64 dram_base_addr __packed; -+ __le32 page_num __packed; - struct iwl_fw_ini_fifo_hdr fifo_hdr; - struct iwl_cmd_header fw_pkt_hdr; - }; -diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c -index 887d0789c96c3..2e3c98eaa400c 100644 ---- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c -@@ -796,7 +796,7 @@ out: - mvm->nvm_data->bands[0].n_channels = 1; - mvm->nvm_data->bands[0].n_bitrates = 1; - mvm->nvm_data->bands[0].bitrates = -- (void *)((u8 *)mvm->nvm_data->channels + 1); -+ (void *)(mvm->nvm_data->channels + 1); - mvm->nvm_data->bands[0].bitrates->hw_value = 10; - } - -diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -index a04b66284af4a..7351acac6932d 100644 ---- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -@@ -965,8 +965,8 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, - } - } - -- tlv_buf_left -= (sizeof(*tlv_rxba) + tlv_len); -- tmp = (u8 *)tlv_rxba + tlv_len + sizeof(*tlv_rxba); -+ tlv_buf_left -= (sizeof(tlv_rxba->header) + tlv_len); -+ tmp = (u8 *)tlv_rxba + sizeof(tlv_rxba->header) + tlv_len; - tlv_rxba = (struct mwifiex_ie_types_rxba_sync *)tmp; - } - } -diff --git a/drivers/net/wireless/marvell/mwifiex/sta_rx.c b/drivers/net/wireless/marvell/mwifiex/sta_rx.c -index 65420ad674167..257737137cd70 100644 ---- a/drivers/net/wireless/marvell/mwifiex/sta_rx.c -+++ b/drivers/net/wireless/marvell/mwifiex/sta_rx.c -@@ -86,7 +86,8 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv, - rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length); - rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off; - -- if (sizeof(*rx_pkt_hdr) + rx_pkt_off > skb->len) { -+ if (sizeof(rx_pkt_hdr->eth803_hdr) + sizeof(rfc1042_header) + -+ rx_pkt_off > skb->len) { - mwifiex_dbg(priv->adapter, ERROR, - "wrong rx packet offset: len=%d, rx_pkt_off=%d\n", - skb->len, rx_pkt_off); -@@ -95,12 +96,13 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv, - return -1; - } - -- if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, -- sizeof(bridge_tunnel_header))) || -- (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, -- sizeof(rfc1042_header)) && -- ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP && -- ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) { -+ if (sizeof(*rx_pkt_hdr) + rx_pkt_off <= skb->len && -+ ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, -+ sizeof(bridge_tunnel_header))) || -+ (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, -+ sizeof(rfc1042_header)) && -+ ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP && -+ ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX))) { - /* - * Replace the 803 header and rfc1042 header (llc/snap) with an - * EthernetII header, keep the src/dst and snap_type -diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c -index 0acabba2d1a50..5d402cf2951cb 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c -+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c -@@ -131,15 +131,8 @@ u8 mt76x02_get_lna_gain(struct mt76x02_dev *dev, - s8 *lna_2g, s8 *lna_5g, - struct ieee80211_channel *chan) - { -- u16 val; - u8 lna; - -- val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); -- if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G) -- *lna_2g = 0; -- if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G) -- memset(lna_5g, 0, sizeof(s8) * 3); -- - if (chan->band == NL80211_BAND_2GHZ) - lna = *lna_2g; - else if (chan->hw_value <= 64) -diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c -index c57e05a5c65e4..91807bf662dde 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c -+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c -@@ -256,7 +256,8 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev) - struct ieee80211_channel *chan = dev->mphy.chandef.chan; - int channel = chan->hw_value; - s8 lna_5g[3], lna_2g; -- u8 lna; -+ bool use_lna; -+ u8 lna = 0; - u16 val; - - if (chan->band == NL80211_BAND_2GHZ) -@@ -275,7 +276,15 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev) - dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; - dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; - -- lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); -+ val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); -+ if (chan->band == NL80211_BAND_2GHZ) -+ use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_2G); -+ else -+ use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_5G); -+ -+ if (use_lna) -+ lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); -+ - dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8); - } - EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); -diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index 95501b77ef314..0fbf331a748fd 100644 ---- a/drivers/of/dynamic.c -+++ b/drivers/of/dynamic.c -@@ -902,13 +902,13 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, - { - struct of_changeset_entry *ce; - -+ if (WARN_ON(action >= ARRAY_SIZE(action_names))) -+ return -EINVAL; -+ - ce = kzalloc(sizeof(*ce), GFP_KERNEL); - if (!ce) - return -ENOMEM; - -- if (WARN_ON(action >= ARRAY_SIZE(action_names))) -- return -EINVAL; -- - /* get a reference to the node */ - ce->action = action; - ce->np = of_node_get(np); -diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c -index d24712a76ba7c..0ccd92faf078a 100644 ---- a/drivers/pci/controller/dwc/pcie-qcom.c -+++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -40,7 +40,6 @@ - #define PARF_PHY_REFCLK 0x4c - #define PARF_CONFIG_BITS 0x50 - #define PARF_DBI_BASE_ADDR 0x168 --#define PARF_SLV_ADDR_SPACE_SIZE_2_3_3 0x16c /* Register offset specific to IP ver 2.3.3 */ - #define PARF_MHI_CLOCK_RESET_CTRL 0x174 - #define PARF_AXI_MSTR_WR_ADDR_HALT 0x178 - #define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8 -@@ -1148,8 +1147,7 @@ static int qcom_pcie_post_init_2_3_3(struct qcom_pcie *pcie) - u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); - u32 val; - -- writel(SLV_ADDR_SPACE_SZ, -- pcie->parf + PARF_SLV_ADDR_SPACE_SIZE_2_3_3); -+ writel(SLV_ADDR_SPACE_SZ, pcie->parf + PARF_SLV_ADDR_SPACE_SIZE); - - val = readl(pcie->parf + PARF_PHY_CTRL); - val &= ~BIT(0); -diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c -index a48d9b7d29217..8fee9b330b613 100644 ---- a/drivers/ptp/ptp_ocp.c -+++ b/drivers/ptp/ptp_ocp.c -@@ -3532,7 +3532,6 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev) - return 0; - - out: -- ptp_ocp_dev_release(&bp->dev); - put_device(&bp->dev); - return err; - } -diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c -index 351f0fd225b14..f6a95f72af18d 100644 ---- a/drivers/regulator/core.c -+++ b/drivers/regulator/core.c -@@ -5543,6 +5543,8 @@ regulator_register(struct device *dev, - goto rinse; - } - device_initialize(&rdev->dev); -+ dev_set_drvdata(&rdev->dev, rdev); -+ rdev->dev.class = ®ulator_class; - spin_lock_init(&rdev->err_lock); - - /* -@@ -5604,11 +5606,9 @@ regulator_register(struct device *dev, - rdev->supply_name = regulator_desc->supply_name; - - /* register with sysfs */ -- rdev->dev.class = ®ulator_class; - rdev->dev.parent = config->dev; - dev_set_name(&rdev->dev, "regulator.%lu", - (unsigned long) atomic_inc_return(®ulator_no)); -- dev_set_drvdata(&rdev->dev, rdev); - - /* set regulator constraints */ - if (init_data) -diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c -index 8a5ce990f1bf9..a0441b8086712 100644 ---- a/drivers/regulator/mt6358-regulator.c -+++ b/drivers/regulator/mt6358-regulator.c -@@ -35,19 +35,19 @@ struct mt6358_regulator_info { - }; - - #define MT6358_BUCK(match, vreg, min, max, step, \ -- volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask, \ -+ vosel_mask, _da_vsel_reg, _da_vsel_mask, \ - _modeset_reg, _modeset_shift) \ - [MT6358_ID_##vreg] = { \ - .desc = { \ - .name = #vreg, \ - .of_match = of_match_ptr(match), \ -- .ops = &mt6358_volt_range_ops, \ -+ .ops = &mt6358_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = MT6358_ID_##vreg, \ - .owner = THIS_MODULE, \ - .n_voltages = ((max) - (min)) / (step) + 1, \ -- .linear_ranges = volt_ranges, \ -- .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ -+ .min_uV = (min), \ -+ .uV_step = (step), \ - .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \ - .vsel_mask = vosel_mask, \ - .enable_reg = MT6358_BUCK_##vreg##_CON0, \ -@@ -87,7 +87,7 @@ struct mt6358_regulator_info { - } - - #define MT6358_LDO1(match, vreg, min, max, step, \ -- volt_ranges, _da_vsel_reg, _da_vsel_mask, \ -+ _da_vsel_reg, _da_vsel_mask, \ - vosel, vosel_mask) \ - [MT6358_ID_##vreg] = { \ - .desc = { \ -@@ -98,8 +98,8 @@ struct mt6358_regulator_info { - .id = MT6358_ID_##vreg, \ - .owner = THIS_MODULE, \ - .n_voltages = ((max) - (min)) / (step) + 1, \ -- .linear_ranges = volt_ranges, \ -- .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ -+ .min_uV = (min), \ -+ .uV_step = (step), \ - .vsel_reg = vosel, \ - .vsel_mask = vosel_mask, \ - .enable_reg = MT6358_LDO_##vreg##_CON0, \ -@@ -131,19 +131,19 @@ struct mt6358_regulator_info { - } - - #define MT6366_BUCK(match, vreg, min, max, step, \ -- volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask, \ -+ vosel_mask, _da_vsel_reg, _da_vsel_mask, \ - _modeset_reg, _modeset_shift) \ - [MT6366_ID_##vreg] = { \ - .desc = { \ - .name = #vreg, \ - .of_match = of_match_ptr(match), \ -- .ops = &mt6358_volt_range_ops, \ -+ .ops = &mt6358_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = MT6366_ID_##vreg, \ - .owner = THIS_MODULE, \ - .n_voltages = ((max) - (min)) / (step) + 1, \ -- .linear_ranges = volt_ranges, \ -- .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ -+ .min_uV = (min), \ -+ .uV_step = (step), \ - .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \ - .vsel_mask = vosel_mask, \ - .enable_reg = MT6358_BUCK_##vreg##_CON0, \ -@@ -183,7 +183,7 @@ struct mt6358_regulator_info { - } - - #define MT6366_LDO1(match, vreg, min, max, step, \ -- volt_ranges, _da_vsel_reg, _da_vsel_mask, \ -+ _da_vsel_reg, _da_vsel_mask, \ - vosel, vosel_mask) \ - [MT6366_ID_##vreg] = { \ - .desc = { \ -@@ -194,8 +194,8 @@ struct mt6358_regulator_info { - .id = MT6366_ID_##vreg, \ - .owner = THIS_MODULE, \ - .n_voltages = ((max) - (min)) / (step) + 1, \ -- .linear_ranges = volt_ranges, \ -- .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ -+ .min_uV = (min), \ -+ .uV_step = (step), \ - .vsel_reg = vosel, \ - .vsel_mask = vosel_mask, \ - .enable_reg = MT6358_LDO_##vreg##_CON0, \ -@@ -226,21 +226,6 @@ struct mt6358_regulator_info { - .qi = BIT(15), \ - } - --static const struct linear_range buck_volt_range1[] = { -- REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250), --}; -- --static const struct linear_range buck_volt_range2[] = { -- REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500), --}; -- --static const struct linear_range buck_volt_range3[] = { -- REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), --}; -- --static const struct linear_range buck_volt_range4[] = { -- REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500), --}; - - static const unsigned int vdram2_voltages[] = { - 600000, 1800000, -@@ -463,9 +448,9 @@ static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev) - } - } - --static const struct regulator_ops mt6358_volt_range_ops = { -- .list_voltage = regulator_list_voltage_linear_range, -- .map_voltage = regulator_map_voltage_linear_range, -+static const struct regulator_ops mt6358_buck_ops = { -+ .list_voltage = regulator_list_voltage_linear, -+ .map_voltage = regulator_map_voltage_linear, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = mt6358_get_buck_voltage_sel, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -@@ -477,6 +462,18 @@ static const struct regulator_ops mt6358_volt_range_ops = { - .get_mode = mt6358_regulator_get_mode, - }; - -+static const struct regulator_ops mt6358_volt_range_ops = { -+ .list_voltage = regulator_list_voltage_linear, -+ .map_voltage = regulator_map_voltage_linear, -+ .set_voltage_sel = regulator_set_voltage_sel_regmap, -+ .get_voltage_sel = mt6358_get_buck_voltage_sel, -+ .set_voltage_time_sel = regulator_set_voltage_time_sel, -+ .enable = regulator_enable_regmap, -+ .disable = regulator_disable_regmap, -+ .is_enabled = regulator_is_enabled_regmap, -+ .get_status = mt6358_get_status, -+}; -+ - static const struct regulator_ops mt6358_volt_table_ops = { - .list_voltage = regulator_list_voltage_table, - .map_voltage = regulator_map_voltage_iterate, -@@ -500,35 +497,23 @@ static const struct regulator_ops mt6358_volt_fixed_ops = { - /* The array is indexed by id(MT6358_ID_XXX) */ - static struct mt6358_regulator_info mt6358_regulators[] = { - MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500, -- buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, -- MT6358_VDRAM1_ANA_CON0, 8), -+ 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8), - MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, -- MT6358_VCORE_VGPU_ANA_CON0, 1), -- MT6358_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f, -- MT6358_VCORE_VGPU_ANA_CON0, 1), -+ 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1), - MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000, -- buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, -- MT6358_VPA_ANA_CON0, 3), -+ 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3), - MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, -- MT6358_VPROC_ANA_CON0, 1), -+ 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1), - MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, -- MT6358_VPROC_ANA_CON0, 2), -+ 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2), - MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, -- MT6358_VCORE_VGPU_ANA_CON0, 2), -+ 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2), - MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500, -- buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, -- MT6358_VS2_ANA_CON0, 8), -+ 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8), - MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, -- MT6358_VMODEM_ANA_CON0, 8), -+ 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8), - MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500, -- buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, -- MT6358_VS1_ANA_CON0, 8), -+ 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8), - MT6358_REG_FIXED("ldo_vrf12", VRF12, - MT6358_LDO_VRF12_CON0, 0, 1200000), - MT6358_REG_FIXED("ldo_vio18", VIO18, -@@ -582,55 +567,35 @@ static struct mt6358_regulator_info mt6358_regulators[] = { - MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx, - MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00), - MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250, -- buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, -- MT6358_LDO_VSRAM_CON0, 0x7f), -+ MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f), - MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250, -- buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, -- MT6358_LDO_VSRAM_CON2, 0x7f), -- MT6358_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000, -- 1293750, 6250, buck_volt_range1, -- MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f, -- MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f), -+ MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f), - MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250, -- buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, -- MT6358_LDO_VSRAM_CON3, 0x7f), -+ MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f), - MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250, -- buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, -- MT6358_LDO_VSRAM_CON1, 0x7f), -+ MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f), - }; - - /* The array is indexed by id(MT6366_ID_XXX) */ - static struct mt6358_regulator_info mt6366_regulators[] = { - MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500, -- buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, -- MT6358_VDRAM1_ANA_CON0, 8), -+ 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8), - MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, -- MT6358_VCORE_VGPU_ANA_CON0, 1), -- MT6366_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f, -- MT6358_VCORE_VGPU_ANA_CON0, 1), -+ 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1), - MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000, -- buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, -- MT6358_VPA_ANA_CON0, 3), -+ 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3), - MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, -- MT6358_VPROC_ANA_CON0, 1), -+ 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1), - MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, -- MT6358_VPROC_ANA_CON0, 2), -+ 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2), - MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, -- MT6358_VCORE_VGPU_ANA_CON0, 2), -+ 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2), - MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500, -- buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, -- MT6358_VS2_ANA_CON0, 8), -+ 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8), - MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250, -- buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, -- MT6358_VMODEM_ANA_CON0, 8), -+ 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8), - MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500, -- buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, -- MT6358_VS1_ANA_CON0, 8), -+ 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8), - MT6366_REG_FIXED("ldo_vrf12", VRF12, - MT6358_LDO_VRF12_CON0, 0, 1200000), - MT6366_REG_FIXED("ldo_vio18", VIO18, -@@ -673,21 +638,13 @@ static struct mt6358_regulator_info mt6366_regulators[] = { - MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx, - MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00), - MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250, -- buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, -- MT6358_LDO_VSRAM_CON0, 0x7f), -+ MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f), - MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250, -- buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, -- MT6358_LDO_VSRAM_CON2, 0x7f), -- MT6366_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000, -- 1293750, 6250, buck_volt_range1, -- MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f, -- MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f), -+ MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f), - MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250, -- buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, -- MT6358_LDO_VSRAM_CON3, 0x7f), -+ MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f), - MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250, -- buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, -- MT6358_LDO_VSRAM_CON1, 0x7f), -+ MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f), - }; - - static int mt6358_regulator_probe(struct platform_device *pdev) -diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c -index df782646e856f..ab2f35bc294da 100644 ---- a/drivers/s390/scsi/zfcp_aux.c -+++ b/drivers/s390/scsi/zfcp_aux.c -@@ -518,12 +518,12 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, - if (port) { - put_device(&port->dev); - retval = -EEXIST; -- goto err_out; -+ goto err_put; - } - - port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); - if (!port) -- goto err_out; -+ goto err_put; - - rwlock_init(&port->unit_list_lock); - INIT_LIST_HEAD(&port->unit_list); -@@ -546,7 +546,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, - - if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { - kfree(port); -- goto err_out; -+ goto err_put; - } - retval = -EINVAL; - -@@ -563,7 +563,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, - - return port; - --err_out: -+err_put: - zfcp_ccw_adapter_put(adapter); -+err_out: - return ERR_PTR(retval); - } -diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c -index 3f062e4013ab6..013a9a334972e 100644 ---- a/drivers/scsi/aacraid/commsup.c -+++ b/drivers/scsi/aacraid/commsup.c -@@ -1451,7 +1451,7 @@ retry_next: - #endif - break; - } -- scsi_rescan_device(&device->sdev_gendev); -+ scsi_rescan_device(device); - break; - - default: -diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c -index 05d3ce9b72dba..c4acf65379d20 100644 ---- a/drivers/scsi/mvumi.c -+++ b/drivers/scsi/mvumi.c -@@ -1500,7 +1500,7 @@ static void mvumi_rescan_devices(struct mvumi_hba *mhba, int id) - - sdev = scsi_device_lookup(mhba->shost, 0, id, 0); - if (sdev) { -- scsi_rescan_device(&sdev->sdev_gendev); -+ scsi_rescan_device(sdev); - scsi_device_put(sdev); - } - } -diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c -index fb6e9a7a7f58b..d25e1c2472538 100644 ---- a/drivers/scsi/scsi_lib.c -+++ b/drivers/scsi/scsi_lib.c -@@ -2445,7 +2445,7 @@ static void scsi_evt_emit(struct scsi_device *sdev, struct scsi_event *evt) - envp[idx++] = "SDEV_MEDIA_CHANGE=1"; - break; - case SDEV_EVT_INQUIRY_CHANGE_REPORTED: -- scsi_rescan_device(&sdev->sdev_gendev); -+ scsi_rescan_device(sdev); - envp[idx++] = "SDEV_UA=INQUIRY_DATA_HAS_CHANGED"; - break; - case SDEV_EVT_CAPACITY_CHANGE_REPORTED: -diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h -index c52de9a973e46..b14545acb40f5 100644 ---- a/drivers/scsi/scsi_priv.h -+++ b/drivers/scsi/scsi_priv.h -@@ -132,7 +132,6 @@ extern int scsi_complete_async_scans(void); - extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, - unsigned int, u64, enum scsi_scan_mode); - extern void scsi_forget_host(struct Scsi_Host *); --extern void scsi_rescan_device(struct device *); - - /* scsi_sysctl.c */ - #ifdef CONFIG_SYSCTL -diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c -index d12f2dcb4040a..ed26c52ed8474 100644 ---- a/drivers/scsi/scsi_scan.c -+++ b/drivers/scsi/scsi_scan.c -@@ -1611,12 +1611,24 @@ int scsi_add_device(struct Scsi_Host *host, uint channel, - } - EXPORT_SYMBOL(scsi_add_device); - --void scsi_rescan_device(struct device *dev) -+int scsi_rescan_device(struct scsi_device *sdev) - { -- struct scsi_device *sdev = to_scsi_device(dev); -+ struct device *dev = &sdev->sdev_gendev; -+ int ret = 0; - - device_lock(dev); - -+ /* -+ * Bail out if the device is not running. Otherwise, the rescan may -+ * block waiting for commands to be executed, with us holding the -+ * device lock. This can result in a potential deadlock in the power -+ * management core code when system resume is on-going. -+ */ -+ if (sdev->sdev_state != SDEV_RUNNING) { -+ ret = -EWOULDBLOCK; -+ goto unlock; -+ } -+ - scsi_attach_vpd(sdev); - - if (sdev->handler && sdev->handler->rescan) -@@ -1629,7 +1641,11 @@ void scsi_rescan_device(struct device *dev) - drv->rescan(dev); - module_put(dev->driver->owner); - } -+ -+unlock: - device_unlock(dev); -+ -+ return ret; - } - EXPORT_SYMBOL(scsi_rescan_device); - -diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c -index cac7c902cf70a..1f531063d6331 100644 ---- a/drivers/scsi/scsi_sysfs.c -+++ b/drivers/scsi/scsi_sysfs.c -@@ -762,7 +762,7 @@ static ssize_t - store_rescan_field (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) - { -- scsi_rescan_device(dev); -+ scsi_rescan_device(to_scsi_device(dev)); - return count; - } - static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field); -@@ -855,7 +855,7 @@ store_state_field(struct device *dev, struct device_attribute *attr, - * waiting for pending I/O to finish. - */ - blk_mq_run_hw_queues(sdev->request_queue, true); -- scsi_rescan_device(dev); -+ scsi_rescan_device(sdev); - } - - return ret == 0 ? count : -EINVAL; -diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index e934779bf05c8..30184f7b762c1 100644 ---- a/drivers/scsi/sd.c -+++ b/drivers/scsi/sd.c -@@ -213,18 +213,32 @@ cache_type_store(struct device *dev, struct device_attribute *attr, - } - - static ssize_t --manage_start_stop_show(struct device *dev, struct device_attribute *attr, -- char *buf) -+manage_start_stop_show(struct device *dev, -+ struct device_attribute *attr, char *buf) - { - struct scsi_disk *sdkp = to_scsi_disk(dev); - struct scsi_device *sdp = sdkp->device; - -- return sprintf(buf, "%u\n", sdp->manage_start_stop); -+ return sysfs_emit(buf, "%u\n", -+ sdp->manage_system_start_stop && -+ sdp->manage_runtime_start_stop); - } -+static DEVICE_ATTR_RO(manage_start_stop); - - static ssize_t --manage_start_stop_store(struct device *dev, struct device_attribute *attr, -- const char *buf, size_t count) -+manage_system_start_stop_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct scsi_disk *sdkp = to_scsi_disk(dev); -+ struct scsi_device *sdp = sdkp->device; -+ -+ return sysfs_emit(buf, "%u\n", sdp->manage_system_start_stop); -+} -+ -+static ssize_t -+manage_system_start_stop_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { - struct scsi_disk *sdkp = to_scsi_disk(dev); - struct scsi_device *sdp = sdkp->device; -@@ -236,11 +250,42 @@ manage_start_stop_store(struct device *dev, struct device_attribute *attr, - if (kstrtobool(buf, &v)) - return -EINVAL; - -- sdp->manage_start_stop = v; -+ sdp->manage_system_start_stop = v; - - return count; - } --static DEVICE_ATTR_RW(manage_start_stop); -+static DEVICE_ATTR_RW(manage_system_start_stop); -+ -+static ssize_t -+manage_runtime_start_stop_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct scsi_disk *sdkp = to_scsi_disk(dev); -+ struct scsi_device *sdp = sdkp->device; -+ -+ return sysfs_emit(buf, "%u\n", sdp->manage_runtime_start_stop); -+} -+ -+static ssize_t -+manage_runtime_start_stop_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct scsi_disk *sdkp = to_scsi_disk(dev); -+ struct scsi_device *sdp = sdkp->device; -+ bool v; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ if (kstrtobool(buf, &v)) -+ return -EINVAL; -+ -+ sdp->manage_runtime_start_stop = v; -+ -+ return count; -+} -+static DEVICE_ATTR_RW(manage_runtime_start_stop); - - static ssize_t - allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) -@@ -572,6 +617,8 @@ static struct attribute *sd_disk_attrs[] = { - &dev_attr_FUA.attr, - &dev_attr_allow_restart.attr, - &dev_attr_manage_start_stop.attr, -+ &dev_attr_manage_system_start_stop.attr, -+ &dev_attr_manage_runtime_start_stop.attr, - &dev_attr_protection_type.attr, - &dev_attr_protection_mode.attr, - &dev_attr_app_tag_own.attr, -@@ -3579,7 +3626,8 @@ static int sd_remove(struct device *dev) - - device_del(&sdkp->disk_dev); - del_gendisk(sdkp->disk); -- sd_shutdown(dev); -+ if (!sdkp->suspended) -+ sd_shutdown(dev); - - put_disk(sdkp->disk); - return 0; -@@ -3652,13 +3700,20 @@ static void sd_shutdown(struct device *dev) - sd_sync_cache(sdkp, NULL); - } - -- if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { -+ if (system_state != SYSTEM_RESTART && -+ sdkp->device->manage_system_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - sd_start_stop_device(sdkp, 0); - } - } - --static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) -+static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime) -+{ -+ return (sdev->manage_system_start_stop && !runtime) || -+ (sdev->manage_runtime_start_stop && runtime); -+} -+ -+static int sd_suspend_common(struct device *dev, bool runtime) - { - struct scsi_disk *sdkp = dev_get_drvdata(dev); - struct scsi_sense_hdr sshdr; -@@ -3690,15 +3745,18 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) - } - } - -- if (sdkp->device->manage_start_stop) { -+ if (sd_do_start_stop(sdkp->device, runtime)) { - if (!sdkp->device->silence_suspend) - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - /* an error is not worth aborting a system sleep */ - ret = sd_start_stop_device(sdkp, 0); -- if (ignore_stop_errors) -+ if (!runtime) - ret = 0; - } - -+ if (!ret) -+ sdkp->suspended = true; -+ - return ret; - } - -@@ -3707,29 +3765,37 @@ static int sd_suspend_system(struct device *dev) - if (pm_runtime_suspended(dev)) - return 0; - -- return sd_suspend_common(dev, true); -+ return sd_suspend_common(dev, false); - } - - static int sd_suspend_runtime(struct device *dev) - { -- return sd_suspend_common(dev, false); -+ return sd_suspend_common(dev, true); - } - --static int sd_resume(struct device *dev) -+static int sd_resume(struct device *dev, bool runtime) - { - struct scsi_disk *sdkp = dev_get_drvdata(dev); -- int ret; -+ int ret = 0; - - if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ - return 0; - -- if (!sdkp->device->manage_start_stop) -+ if (!sd_do_start_stop(sdkp->device, runtime)) { -+ sdkp->suspended = false; - return 0; -+ } - -- sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); -- ret = sd_start_stop_device(sdkp, 1); -- if (!ret) -+ if (!sdkp->device->no_start_on_resume) { -+ sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); -+ ret = sd_start_stop_device(sdkp, 1); -+ } -+ -+ if (!ret) { - opal_unlock_from_suspend(sdkp->opal_dev); -+ sdkp->suspended = false; -+ } -+ - return ret; - } - -@@ -3738,7 +3804,7 @@ static int sd_resume_system(struct device *dev) - if (pm_runtime_suspended(dev)) - return 0; - -- return sd_resume(dev); -+ return sd_resume(dev, false); - } - - static int sd_resume_runtime(struct device *dev) -@@ -3762,7 +3828,7 @@ static int sd_resume_runtime(struct device *dev) - "Failed to clear sense data\n"); - } - -- return sd_resume(dev); -+ return sd_resume(dev, true); - } - - /** -diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h -index 5eea762f84d18..409dda5350d10 100644 ---- a/drivers/scsi/sd.h -+++ b/drivers/scsi/sd.h -@@ -131,6 +131,7 @@ struct scsi_disk { - u8 provisioning_mode; - u8 zeroing_mode; - u8 nr_actuators; /* Number of actuators */ -+ bool suspended; /* Disk is suspended (stopped) */ - unsigned ATO : 1; /* state of disk ATO bit */ - unsigned cache_override : 1; /* temp override of WCE,RCD */ - unsigned WCE : 1; /* state of disk WCE bit */ -diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c -index 9f0f69c1ed665..47d487729635c 100644 ---- a/drivers/scsi/smartpqi/smartpqi_init.c -+++ b/drivers/scsi/smartpqi/smartpqi_init.c -@@ -2278,7 +2278,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, - device->advertised_queue_depth = device->queue_depth; - scsi_change_queue_depth(device->sdev, device->advertised_queue_depth); - if (device->rescan) { -- scsi_rescan_device(&device->sdev->sdev_gendev); -+ scsi_rescan_device(device->sdev); - device->rescan = false; - } - } -diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c -index 7a1dc5c7c49ee..c2d981d5a2dd5 100644 ---- a/drivers/scsi/storvsc_drv.c -+++ b/drivers/scsi/storvsc_drv.c -@@ -471,7 +471,7 @@ static void storvsc_device_scan(struct work_struct *work) - sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun); - if (!sdev) - goto done; -- scsi_rescan_device(&sdev->sdev_gendev); -+ scsi_rescan_device(sdev); - scsi_device_put(sdev); - - done: -diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c -index 2a79ab16134b1..3f8c553f3d91e 100644 ---- a/drivers/scsi/virtio_scsi.c -+++ b/drivers/scsi/virtio_scsi.c -@@ -325,7 +325,7 @@ static void virtscsi_handle_param_change(struct virtio_scsi *vscsi, - /* Handle "Parameters changed", "Mode parameters changed", and - "Capacity data has changed". */ - if (asc == 0x2a && (ascq == 0x00 || ascq == 0x01 || ascq == 0x09)) -- scsi_rescan_device(&sdev->sdev_gendev); -+ scsi_rescan_device(sdev); - - scsi_device_put(sdev); - } -diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c -index c760aac070e54..3b56d5e7080e1 100644 ---- a/drivers/spi/spi-zynqmp-gqspi.c -+++ b/drivers/spi/spi-zynqmp-gqspi.c -@@ -1218,9 +1218,9 @@ static int zynqmp_qspi_probe(struct platform_device *pdev) - return 0; - - clk_dis_all: -- pm_runtime_put_sync(&pdev->dev); -- pm_runtime_set_suspended(&pdev->dev); - pm_runtime_disable(&pdev->dev); -+ pm_runtime_put_noidle(&pdev->dev); -+ pm_runtime_set_suspended(&pdev->dev); - clk_disable_unprepare(xqspi->refclk); - clk_dis_pclk: - clk_disable_unprepare(xqspi->pclk); -@@ -1244,11 +1244,15 @@ static int zynqmp_qspi_remove(struct platform_device *pdev) - { - struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev); - -+ pm_runtime_get_sync(&pdev->dev); -+ - zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0); -+ -+ pm_runtime_disable(&pdev->dev); -+ pm_runtime_put_noidle(&pdev->dev); -+ pm_runtime_set_suspended(&pdev->dev); - clk_disable_unprepare(xqspi->refclk); - clk_disable_unprepare(xqspi->pclk); -- pm_runtime_set_suspended(&pdev->dev); -- pm_runtime_disable(&pdev->dev); - - return 0; - } -diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c -index d21f88de197c7..301fe376a1206 100644 ---- a/drivers/target/target_core_device.c -+++ b/drivers/target/target_core_device.c -@@ -883,7 +883,6 @@ sector_t target_to_linux_sector(struct se_device *dev, sector_t lb) - EXPORT_SYMBOL(target_to_linux_sector); - - struct devices_idr_iter { -- struct config_item *prev_item; - int (*fn)(struct se_device *dev, void *data); - void *data; - }; -@@ -893,11 +892,9 @@ static int target_devices_idr_iter(int id, void *p, void *data) - { - struct devices_idr_iter *iter = data; - struct se_device *dev = p; -+ struct config_item *item; - int ret; - -- config_item_put(iter->prev_item); -- iter->prev_item = NULL; -- - /* - * We add the device early to the idr, so it can be used - * by backend modules during configuration. We do not want -@@ -907,12 +904,13 @@ static int target_devices_idr_iter(int id, void *p, void *data) - if (!target_dev_configured(dev)) - return 0; - -- iter->prev_item = config_item_get_unless_zero(&dev->dev_group.cg_item); -- if (!iter->prev_item) -+ item = config_item_get_unless_zero(&dev->dev_group.cg_item); -+ if (!item) - return 0; - mutex_unlock(&device_mutex); - - ret = iter->fn(dev, iter->data); -+ config_item_put(item); - - mutex_lock(&device_mutex); - return ret; -@@ -935,7 +933,6 @@ int target_for_each_device(int (*fn)(struct se_device *dev, void *data), - mutex_lock(&device_mutex); - ret = idr_for_each(&devices_idr, target_devices_idr_iter, &iter); - mutex_unlock(&device_mutex); -- config_item_put(iter.prev_item); - return ret; - } - -diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c -index 33eb941fcf154..10bfc5f1c50d5 100644 ---- a/drivers/vhost/vringh.c -+++ b/drivers/vhost/vringh.c -@@ -123,8 +123,18 @@ static inline ssize_t vringh_iov_xfer(struct vringh *vrh, - done += partlen; - len -= partlen; - ptr += partlen; -+ iov->consumed += partlen; -+ iov->iov[iov->i].iov_len -= partlen; -+ iov->iov[iov->i].iov_base += partlen; - -- vringh_kiov_advance(iov, partlen); -+ if (!iov->iov[iov->i].iov_len) { -+ /* Fix up old iov element then increment. */ -+ iov->iov[iov->i].iov_len = iov->consumed; -+ iov->iov[iov->i].iov_base -= iov->consumed; -+ -+ iov->consumed = 0; -+ iov->i++; -+ } - } - return done; - } -diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c -index c443f04aaad77..80b46de14f413 100644 ---- a/drivers/xen/events/events_base.c -+++ b/drivers/xen/events/events_base.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -96,6 +97,7 @@ enum xen_irq_type { - struct irq_info { - struct list_head list; - struct list_head eoi_list; -+ struct rcu_work rwork; - short refcnt; - u8 spurious_cnt; - u8 is_accounted; -@@ -145,23 +147,13 @@ const struct evtchn_ops *evtchn_ops; - */ - static DEFINE_MUTEX(irq_mapping_update_lock); - --/* -- * Lock protecting event handling loop against removing event channels. -- * Adding of event channels is no issue as the associated IRQ becomes active -- * only after everything is setup (before request_[threaded_]irq() the handler -- * can't be entered for an event, as the event channel will be unmasked only -- * then). -- */ --static DEFINE_RWLOCK(evtchn_rwlock); -- - /* - * Lock hierarchy: - * - * irq_mapping_update_lock -- * evtchn_rwlock -- * IRQ-desc lock -- * percpu eoi_list_lock -- * irq_info->lock -+ * IRQ-desc lock -+ * percpu eoi_list_lock -+ * irq_info->lock - */ - - static LIST_HEAD(xen_irq_list_head); -@@ -305,6 +297,22 @@ static void channels_on_cpu_inc(struct irq_info *info) - info->is_accounted = 1; - } - -+static void delayed_free_irq(struct work_struct *work) -+{ -+ struct irq_info *info = container_of(to_rcu_work(work), struct irq_info, -+ rwork); -+ unsigned int irq = info->irq; -+ -+ /* Remove the info pointer only now, with no potential users left. */ -+ set_info_for_irq(irq, NULL); -+ -+ kfree(info); -+ -+ /* Legacy IRQ descriptors are managed by the arch. */ -+ if (irq >= nr_legacy_irqs()) -+ irq_free_desc(irq); -+} -+ - /* Constructors for packed IRQ information. */ - static int xen_irq_info_common_setup(struct irq_info *info, - unsigned irq, -@@ -667,33 +675,36 @@ static void xen_irq_lateeoi_worker(struct work_struct *work) - - eoi = container_of(to_delayed_work(work), struct lateeoi_work, delayed); - -- read_lock_irqsave(&evtchn_rwlock, flags); -+ rcu_read_lock(); - - while (true) { -- spin_lock(&eoi->eoi_list_lock); -+ spin_lock_irqsave(&eoi->eoi_list_lock, flags); - - info = list_first_entry_or_null(&eoi->eoi_list, struct irq_info, - eoi_list); - -- if (info == NULL || now < info->eoi_time) { -- spin_unlock(&eoi->eoi_list_lock); -+ if (info == NULL) -+ break; -+ -+ if (now < info->eoi_time) { -+ mod_delayed_work_on(info->eoi_cpu, system_wq, -+ &eoi->delayed, -+ info->eoi_time - now); - break; - } - - list_del_init(&info->eoi_list); - -- spin_unlock(&eoi->eoi_list_lock); -+ spin_unlock_irqrestore(&eoi->eoi_list_lock, flags); - - info->eoi_time = 0; - - xen_irq_lateeoi_locked(info, false); - } - -- if (info) -- mod_delayed_work_on(info->eoi_cpu, system_wq, -- &eoi->delayed, info->eoi_time - now); -+ spin_unlock_irqrestore(&eoi->eoi_list_lock, flags); - -- read_unlock_irqrestore(&evtchn_rwlock, flags); -+ rcu_read_unlock(); - } - - static void xen_cpu_init_eoi(unsigned int cpu) -@@ -708,16 +719,15 @@ static void xen_cpu_init_eoi(unsigned int cpu) - void xen_irq_lateeoi(unsigned int irq, unsigned int eoi_flags) - { - struct irq_info *info; -- unsigned long flags; - -- read_lock_irqsave(&evtchn_rwlock, flags); -+ rcu_read_lock(); - - info = info_for_irq(irq); - - if (info) - xen_irq_lateeoi_locked(info, eoi_flags & XEN_EOI_FLAG_SPURIOUS); - -- read_unlock_irqrestore(&evtchn_rwlock, flags); -+ rcu_read_unlock(); - } - EXPORT_SYMBOL_GPL(xen_irq_lateeoi); - -@@ -731,6 +741,7 @@ static void xen_irq_init(unsigned irq) - - info->type = IRQT_UNBOUND; - info->refcnt = -1; -+ INIT_RCU_WORK(&info->rwork, delayed_free_irq); - - set_info_for_irq(irq, info); - /* -@@ -788,31 +799,18 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi) - static void xen_free_irq(unsigned irq) - { - struct irq_info *info = info_for_irq(irq); -- unsigned long flags; - - if (WARN_ON(!info)) - return; - -- write_lock_irqsave(&evtchn_rwlock, flags); -- - if (!list_empty(&info->eoi_list)) - lateeoi_list_del(info); - - list_del(&info->list); - -- set_info_for_irq(irq, NULL); -- - WARN_ON(info->refcnt > 0); - -- write_unlock_irqrestore(&evtchn_rwlock, flags); -- -- kfree(info); -- -- /* Legacy IRQ descriptors are managed by the arch. */ -- if (irq < nr_legacy_irqs()) -- return; -- -- irq_free_desc(irq); -+ queue_rcu_work(system_wq, &info->rwork); - } - - static void xen_evtchn_close(evtchn_port_t port) -@@ -1716,7 +1714,14 @@ static void __xen_evtchn_do_upcall(void) - int cpu = smp_processor_id(); - struct evtchn_loop_ctrl ctrl = { 0 }; - -- read_lock(&evtchn_rwlock); -+ /* -+ * When closing an event channel the associated IRQ must not be freed -+ * until all cpus have left the event handling loop. This is ensured -+ * by taking the rcu_read_lock() while handling events, as freeing of -+ * the IRQ is handled via queue_rcu_work() _after_ closing the event -+ * channel. -+ */ -+ rcu_read_lock(); - - do { - vcpu_info->evtchn_upcall_pending = 0; -@@ -1729,7 +1734,7 @@ static void __xen_evtchn_do_upcall(void) - - } while (vcpu_info->evtchn_upcall_pending); - -- read_unlock(&evtchn_rwlock); -+ rcu_read_unlock(); - - /* - * Increment irq_epoch only now to defer EOIs only for -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index 3bcef0c4d6fc4..27d06bb5e5c05 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include "extent-io-tree.h" - #include "extent_io.h" - #include "extent_map.h" -@@ -3238,11 +3239,11 @@ static inline void btrfs_clear_sb_rdonly(struct super_block *sb) - - /* root-item.c */ - int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id, -- u64 ref_id, u64 dirid, u64 sequence, const char *name, -- int name_len); -+ u64 ref_id, u64 dirid, u64 sequence, -+ const struct fscrypt_str *name); - int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id, -- u64 ref_id, u64 dirid, u64 *sequence, const char *name, -- int name_len); -+ u64 ref_id, u64 dirid, u64 *sequence, -+ const struct fscrypt_str *name); - int btrfs_del_root(struct btrfs_trans_handle *trans, - const struct btrfs_key *key); - int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, -@@ -3271,25 +3272,23 @@ int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info); - - /* dir-item.c */ - int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir, -- const char *name, int name_len); --int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const char *name, -- int name_len, struct btrfs_inode *dir, -+ const struct fscrypt_str *name); -+int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, -+ const struct fscrypt_str *name, struct btrfs_inode *dir, - struct btrfs_key *location, u8 type, u64 index); - struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, u64 dir, -- const char *name, int name_len, -- int mod); -+ const struct fscrypt_str *name, int mod); - struct btrfs_dir_item * - btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, u64 dir, -- u64 index, const char *name, int name_len, -- int mod); -+ u64 index, const struct fscrypt_str *name, int mod); - struct btrfs_dir_item * - btrfs_search_dir_index_item(struct btrfs_root *root, - struct btrfs_path *path, u64 dirid, -- const char *name, int name_len); -+ const struct fscrypt_str *name); - int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, -@@ -3370,10 +3369,10 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry); - int btrfs_set_inode_index(struct btrfs_inode *dir, u64 *index); - int btrfs_unlink_inode(struct btrfs_trans_handle *trans, - struct btrfs_inode *dir, struct btrfs_inode *inode, -- const char *name, int name_len); -+ const struct fscrypt_str *name); - int btrfs_add_link(struct btrfs_trans_handle *trans, - struct btrfs_inode *parent_inode, struct btrfs_inode *inode, -- const char *name, int name_len, int add_backref, u64 index); -+ const struct fscrypt_str *name, int add_backref, u64 index); - int btrfs_delete_subvolume(struct inode *dir, struct dentry *dentry); - int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len, - int front); -@@ -3398,6 +3397,7 @@ struct btrfs_new_inode_args { - */ - struct posix_acl *default_acl; - struct posix_acl *acl; -+ struct fscrypt_name fname; - }; - int btrfs_new_inode_prepare(struct btrfs_new_inode_args *args, - unsigned int *trans_num_items); -diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c -index 72fb2c518a2b4..fdab48c1abb8a 100644 ---- a/fs/btrfs/dir-item.c -+++ b/fs/btrfs/dir-item.c -@@ -103,8 +103,8 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, - * to use for the second index (if one is created). - * Will return 0 or -ENOMEM - */ --int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const char *name, -- int name_len, struct btrfs_inode *dir, -+int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, -+ const struct fscrypt_str *name, struct btrfs_inode *dir, - struct btrfs_key *location, u8 type, u64 index) - { - int ret = 0; -@@ -120,7 +120,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const char *name, - - key.objectid = btrfs_ino(dir); - key.type = BTRFS_DIR_ITEM_KEY; -- key.offset = btrfs_name_hash(name, name_len); -+ key.offset = btrfs_name_hash(name->name, name->len); - - path = btrfs_alloc_path(); - if (!path) -@@ -128,9 +128,9 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const char *name, - - btrfs_cpu_key_to_disk(&disk_key, location); - -- data_size = sizeof(*dir_item) + name_len; -+ data_size = sizeof(*dir_item) + name->len; - dir_item = insert_with_overflow(trans, root, path, &key, data_size, -- name, name_len); -+ name->name, name->len); - if (IS_ERR(dir_item)) { - ret = PTR_ERR(dir_item); - if (ret == -EEXIST) -@@ -142,11 +142,11 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const char *name, - btrfs_set_dir_item_key(leaf, dir_item, &disk_key); - btrfs_set_dir_type(leaf, dir_item, type); - btrfs_set_dir_data_len(leaf, dir_item, 0); -- btrfs_set_dir_name_len(leaf, dir_item, name_len); -+ btrfs_set_dir_name_len(leaf, dir_item, name->len); - btrfs_set_dir_transid(leaf, dir_item, trans->transid); - name_ptr = (unsigned long)(dir_item + 1); - -- write_extent_buffer(leaf, name, name_ptr, name_len); -+ write_extent_buffer(leaf, name->name, name_ptr, name->len); - btrfs_mark_buffer_dirty(leaf); - - second_insert: -@@ -157,7 +157,7 @@ second_insert: - } - btrfs_release_path(path); - -- ret2 = btrfs_insert_delayed_dir_index(trans, name, name_len, dir, -+ ret2 = btrfs_insert_delayed_dir_index(trans, name->name, name->len, dir, - &disk_key, type, index); - out_free: - btrfs_free_path(path); -@@ -206,7 +206,7 @@ static struct btrfs_dir_item *btrfs_lookup_match_dir( - struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, u64 dir, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - int mod) - { - struct btrfs_key key; -@@ -214,9 +214,10 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, - - key.objectid = dir; - key.type = BTRFS_DIR_ITEM_KEY; -- key.offset = btrfs_name_hash(name, name_len); -+ key.offset = btrfs_name_hash(name->name, name->len); - -- di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod); -+ di = btrfs_lookup_match_dir(trans, root, path, &key, name->name, -+ name->len, mod); - if (IS_ERR(di) && PTR_ERR(di) == -ENOENT) - return NULL; - -@@ -224,7 +225,7 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, - } - - int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir, -- const char *name, int name_len) -+ const struct fscrypt_str *name) - { - int ret; - struct btrfs_key key; -@@ -240,9 +241,10 @@ int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir, - - key.objectid = dir; - key.type = BTRFS_DIR_ITEM_KEY; -- key.offset = btrfs_name_hash(name, name_len); -+ key.offset = btrfs_name_hash(name->name, name->len); - -- di = btrfs_lookup_match_dir(NULL, root, path, &key, name, name_len, 0); -+ di = btrfs_lookup_match_dir(NULL, root, path, &key, name->name, -+ name->len, 0); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - /* Nothing found, we're safe */ -@@ -262,11 +264,8 @@ int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir, - goto out; - } - -- /* -- * see if there is room in the item to insert this -- * name -- */ -- data_size = sizeof(*di) + name_len; -+ /* See if there is room in the item to insert this name. */ -+ data_size = sizeof(*di) + name->len; - leaf = path->nodes[0]; - slot = path->slots[0]; - if (data_size + btrfs_item_size(leaf, slot) + -@@ -303,8 +302,7 @@ struct btrfs_dir_item * - btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, u64 dir, -- u64 index, const char *name, int name_len, -- int mod) -+ u64 index, const struct fscrypt_str *name, int mod) - { - struct btrfs_dir_item *di; - struct btrfs_key key; -@@ -313,7 +311,8 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, - key.type = BTRFS_DIR_INDEX_KEY; - key.offset = index; - -- di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod); -+ di = btrfs_lookup_match_dir(trans, root, path, &key, name->name, -+ name->len, mod); - if (di == ERR_PTR(-ENOENT)) - return NULL; - -@@ -321,9 +320,8 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, - } - - struct btrfs_dir_item * --btrfs_search_dir_index_item(struct btrfs_root *root, -- struct btrfs_path *path, u64 dirid, -- const char *name, int name_len) -+btrfs_search_dir_index_item(struct btrfs_root *root, struct btrfs_path *path, -+ u64 dirid, const struct fscrypt_str *name) - { - struct btrfs_dir_item *di; - struct btrfs_key key; -@@ -338,7 +336,7 @@ btrfs_search_dir_index_item(struct btrfs_root *root, - break; - - di = btrfs_match_dir_item_name(root->fs_info, path, -- name, name_len); -+ name->name, name->len); - if (di) - return di; - } -diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c -index 77202addead83..0a46fff3dd067 100644 ---- a/fs/btrfs/file.c -+++ b/fs/btrfs/file.c -@@ -1458,8 +1458,13 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) - if (iocb->ki_flags & IOCB_NOWAIT) - ilock_flags |= BTRFS_ILOCK_TRY; - -- /* If the write DIO is within EOF, use a shared lock */ -- if (iocb->ki_pos + iov_iter_count(from) <= i_size_read(inode)) -+ /* -+ * If the write DIO is within EOF, use a shared lock and also only if -+ * security bits will likely not be dropped by file_remove_privs() called -+ * from btrfs_write_check(). Either will need to be rechecked after the -+ * lock was acquired. -+ */ -+ if (iocb->ki_pos + iov_iter_count(from) <= i_size_read(inode) && IS_NOSEC(inode)) - ilock_flags |= BTRFS_ILOCK_SHARED; - - relock: -@@ -1467,6 +1472,13 @@ relock: - if (err < 0) - return err; - -+ /* Shared lock cannot be used with security bits set. */ -+ if ((ilock_flags & BTRFS_ILOCK_SHARED) && !IS_NOSEC(inode)) { -+ btrfs_inode_unlock(inode, ilock_flags); -+ ilock_flags &= ~BTRFS_ILOCK_SHARED; -+ goto relock; -+ } -+ - err = generic_write_checks(iocb, from); - if (err <= 0) { - btrfs_inode_unlock(inode, ilock_flags); -diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c -index 0eeb5ea878948..5add022d3534f 100644 ---- a/fs/btrfs/inode-item.c -+++ b/fs/btrfs/inode-item.c -@@ -10,8 +10,8 @@ - #include "print-tree.h" - - struct btrfs_inode_ref *btrfs_find_name_in_backref(struct extent_buffer *leaf, -- int slot, const char *name, -- int name_len) -+ int slot, -+ const struct fscrypt_str *name) - { - struct btrfs_inode_ref *ref; - unsigned long ptr; -@@ -27,9 +27,10 @@ struct btrfs_inode_ref *btrfs_find_name_in_backref(struct extent_buffer *leaf, - len = btrfs_inode_ref_name_len(leaf, ref); - name_ptr = (unsigned long)(ref + 1); - cur_offset += len + sizeof(*ref); -- if (len != name_len) -+ if (len != name->len) - continue; -- if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) -+ if (memcmp_extent_buffer(leaf, name->name, name_ptr, -+ name->len) == 0) - return ref; - } - return NULL; -@@ -37,7 +38,7 @@ struct btrfs_inode_ref *btrfs_find_name_in_backref(struct extent_buffer *leaf, - - struct btrfs_inode_extref *btrfs_find_name_in_ext_backref( - struct extent_buffer *leaf, int slot, u64 ref_objectid, -- const char *name, int name_len) -+ const struct fscrypt_str *name) - { - struct btrfs_inode_extref *extref; - unsigned long ptr; -@@ -60,9 +61,10 @@ struct btrfs_inode_extref *btrfs_find_name_in_ext_backref( - name_ptr = (unsigned long)(&extref->name); - ref_name_len = btrfs_inode_extref_name_len(leaf, extref); - -- if (ref_name_len == name_len && -+ if (ref_name_len == name->len && - btrfs_inode_extref_parent(leaf, extref) == ref_objectid && -- (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)) -+ (memcmp_extent_buffer(leaf, name->name, name_ptr, -+ name->len) == 0)) - return extref; - - cur_offset += ref_name_len + sizeof(*extref); -@@ -75,7 +77,7 @@ struct btrfs_inode_extref * - btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - u64 inode_objectid, u64 ref_objectid, int ins_len, - int cow) - { -@@ -84,7 +86,7 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans, - - key.objectid = inode_objectid; - key.type = BTRFS_INODE_EXTREF_KEY; -- key.offset = btrfs_extref_hash(ref_objectid, name, name_len); -+ key.offset = btrfs_extref_hash(ref_objectid, name->name, name->len); - - ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); - if (ret < 0) -@@ -92,13 +94,13 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans, - if (ret > 0) - return NULL; - return btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0], -- ref_objectid, name, name_len); -+ ref_objectid, name); - - } - - static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - u64 inode_objectid, u64 ref_objectid, - u64 *index) - { -@@ -107,14 +109,14 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans, - struct btrfs_inode_extref *extref; - struct extent_buffer *leaf; - int ret; -- int del_len = name_len + sizeof(*extref); -+ int del_len = name->len + sizeof(*extref); - unsigned long ptr; - unsigned long item_start; - u32 item_size; - - key.objectid = inode_objectid; - key.type = BTRFS_INODE_EXTREF_KEY; -- key.offset = btrfs_extref_hash(ref_objectid, name, name_len); -+ key.offset = btrfs_extref_hash(ref_objectid, name->name, name->len); - - path = btrfs_alloc_path(); - if (!path) -@@ -132,7 +134,7 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans, - * readonly. - */ - extref = btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0], -- ref_objectid, name, name_len); -+ ref_objectid, name); - if (!extref) { - btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL); - ret = -EROFS; -@@ -168,8 +170,7 @@ out: - } - - int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, -- struct btrfs_root *root, -- const char *name, int name_len, -+ struct btrfs_root *root, const struct fscrypt_str *name, - u64 inode_objectid, u64 ref_objectid, u64 *index) - { - struct btrfs_path *path; -@@ -182,7 +183,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, - u32 sub_item_len; - int ret; - int search_ext_refs = 0; -- int del_len = name_len + sizeof(*ref); -+ int del_len = name->len + sizeof(*ref); - - key.objectid = inode_objectid; - key.offset = ref_objectid; -@@ -201,8 +202,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, - goto out; - } - -- ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0], name, -- name_len); -+ ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0], name); - if (!ref) { - ret = -ENOENT; - search_ext_refs = 1; -@@ -219,7 +219,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, - goto out; - } - ptr = (unsigned long)ref; -- sub_item_len = name_len + sizeof(*ref); -+ sub_item_len = name->len + sizeof(*ref); - item_start = btrfs_item_ptr_offset(leaf, path->slots[0]); - memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, - item_size - (ptr + sub_item_len - item_start)); -@@ -233,7 +233,7 @@ out: - * name in our ref array. Find and remove the extended - * inode ref then. - */ -- return btrfs_del_inode_extref(trans, root, name, name_len, -+ return btrfs_del_inode_extref(trans, root, name, - inode_objectid, ref_objectid, index); - } - -@@ -247,12 +247,13 @@ out: - */ - static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, -- const char *name, int name_len, -- u64 inode_objectid, u64 ref_objectid, u64 index) -+ const struct fscrypt_str *name, -+ u64 inode_objectid, u64 ref_objectid, -+ u64 index) - { - struct btrfs_inode_extref *extref; - int ret; -- int ins_len = name_len + sizeof(*extref); -+ int ins_len = name->len + sizeof(*extref); - unsigned long ptr; - struct btrfs_path *path; - struct btrfs_key key; -@@ -260,7 +261,7 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, - - key.objectid = inode_objectid; - key.type = BTRFS_INODE_EXTREF_KEY; -- key.offset = btrfs_extref_hash(ref_objectid, name, name_len); -+ key.offset = btrfs_extref_hash(ref_objectid, name->name, name->len); - - path = btrfs_alloc_path(); - if (!path) -@@ -272,7 +273,7 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, - if (btrfs_find_name_in_ext_backref(path->nodes[0], - path->slots[0], - ref_objectid, -- name, name_len)) -+ name)) - goto out; - - btrfs_extend_item(path, ins_len); -@@ -286,12 +287,12 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans, - ptr += btrfs_item_size(leaf, path->slots[0]) - ins_len; - extref = (struct btrfs_inode_extref *)ptr; - -- btrfs_set_inode_extref_name_len(path->nodes[0], extref, name_len); -+ btrfs_set_inode_extref_name_len(path->nodes[0], extref, name->len); - btrfs_set_inode_extref_index(path->nodes[0], extref, index); - btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid); - - ptr = (unsigned long)&extref->name; -- write_extent_buffer(path->nodes[0], name, ptr, name_len); -+ write_extent_buffer(path->nodes[0], name->name, ptr, name->len); - btrfs_mark_buffer_dirty(path->nodes[0]); - - out: -@@ -301,8 +302,7 @@ out: - - /* Will return 0, -ENOMEM, -EMLINK, or -EEXIST or anything from the CoW path */ - int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, -- struct btrfs_root *root, -- const char *name, int name_len, -+ struct btrfs_root *root, const struct fscrypt_str *name, - u64 inode_objectid, u64 ref_objectid, u64 index) - { - struct btrfs_fs_info *fs_info = root->fs_info; -@@ -311,7 +311,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, - struct btrfs_inode_ref *ref; - unsigned long ptr; - int ret; -- int ins_len = name_len + sizeof(*ref); -+ int ins_len = name->len + sizeof(*ref); - - key.objectid = inode_objectid; - key.offset = ref_objectid; -@@ -327,7 +327,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, - if (ret == -EEXIST) { - u32 old_size; - ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0], -- name, name_len); -+ name); - if (ref) - goto out; - -@@ -336,7 +336,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, - ref = btrfs_item_ptr(path->nodes[0], path->slots[0], - struct btrfs_inode_ref); - ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size); -- btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len); -+ btrfs_set_inode_ref_name_len(path->nodes[0], ref, name->len); - btrfs_set_inode_ref_index(path->nodes[0], ref, index); - ptr = (unsigned long)(ref + 1); - ret = 0; -@@ -344,7 +344,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, - if (ret == -EOVERFLOW) { - if (btrfs_find_name_in_backref(path->nodes[0], - path->slots[0], -- name, name_len)) -+ name)) - ret = -EEXIST; - else - ret = -EMLINK; -@@ -353,11 +353,11 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, - } else { - ref = btrfs_item_ptr(path->nodes[0], path->slots[0], - struct btrfs_inode_ref); -- btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len); -+ btrfs_set_inode_ref_name_len(path->nodes[0], ref, name->len); - btrfs_set_inode_ref_index(path->nodes[0], ref, index); - ptr = (unsigned long)(ref + 1); - } -- write_extent_buffer(path->nodes[0], name, ptr, name_len); -+ write_extent_buffer(path->nodes[0], name->name, ptr, name->len); - btrfs_mark_buffer_dirty(path->nodes[0]); - - out: -@@ -370,7 +370,6 @@ out: - if (btrfs_super_incompat_flags(disk_super) - & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF) - ret = btrfs_insert_inode_extref(trans, root, name, -- name_len, - inode_objectid, - ref_objectid, index); - } -diff --git a/fs/btrfs/inode-item.h b/fs/btrfs/inode-item.h -index a8fc16d0147f6..b80aeb7157010 100644 ---- a/fs/btrfs/inode-item.h -+++ b/fs/btrfs/inode-item.h -@@ -64,33 +64,31 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_truncate_control *control); - int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, -- struct btrfs_root *root, -- const char *name, int name_len, -+ struct btrfs_root *root, const struct fscrypt_str *name, - u64 inode_objectid, u64 ref_objectid, u64 index); - int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, -- struct btrfs_root *root, -- const char *name, int name_len, -- u64 inode_objectid, u64 ref_objectid, u64 *index); -+ struct btrfs_root *root, const struct fscrypt_str *name, -+ u64 inode_objectid, u64 ref_objectid, u64 *index); - int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, u64 objectid); --int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root -- *root, struct btrfs_path *path, -+int btrfs_lookup_inode(struct btrfs_trans_handle *trans, -+ struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *location, int mod); - - struct btrfs_inode_extref *btrfs_lookup_inode_extref( - struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - u64 inode_objectid, u64 ref_objectid, int ins_len, - int cow); - - struct btrfs_inode_ref *btrfs_find_name_in_backref(struct extent_buffer *leaf, -- int slot, const char *name, -- int name_len); -+ int slot, -+ const struct fscrypt_str *name); - struct btrfs_inode_extref *btrfs_find_name_in_ext_backref( - struct extent_buffer *leaf, int slot, u64 ref_objectid, -- const char *name, int name_len); -+ const struct fscrypt_str *name); - - #endif -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 222068bf80031..4063447217f92 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -3627,7 +3627,7 @@ void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info) - spin_unlock(&fs_info->delayed_iput_lock); - } - --/** -+/* - * Wait for flushing all delayed iputs - * - * @fs_info: the filesystem -@@ -4272,7 +4272,7 @@ int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans, - static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, - struct btrfs_inode *dir, - struct btrfs_inode *inode, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - struct btrfs_rename_ctx *rename_ctx) - { - struct btrfs_root *root = dir->root; -@@ -4290,8 +4290,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, - goto out; - } - -- di = btrfs_lookup_dir_item(trans, root, path, dir_ino, -- name, name_len, -1); -+ di = btrfs_lookup_dir_item(trans, root, path, dir_ino, name, -1); - if (IS_ERR_OR_NULL(di)) { - ret = di ? PTR_ERR(di) : -ENOENT; - goto err; -@@ -4319,12 +4318,11 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, - } - } - -- ret = btrfs_del_inode_ref(trans, root, name, name_len, ino, -- dir_ino, &index); -+ ret = btrfs_del_inode_ref(trans, root, name, ino, dir_ino, &index); - if (ret) { - btrfs_info(fs_info, - "failed to delete reference to %.*s, inode %llu parent %llu", -- name_len, name, ino, dir_ino); -+ name->len, name->name, ino, dir_ino); - btrfs_abort_transaction(trans, ret); - goto err; - } -@@ -4345,10 +4343,8 @@ skip_backref: - * operations on the log tree, increasing latency for applications. - */ - if (!rename_ctx) { -- btrfs_del_inode_ref_in_log(trans, root, name, name_len, inode, -- dir_ino); -- btrfs_del_dir_entries_in_log(trans, root, name, name_len, dir, -- index); -+ btrfs_del_inode_ref_in_log(trans, root, name, inode, dir_ino); -+ btrfs_del_dir_entries_in_log(trans, root, name, dir, index); - } - - /* -@@ -4366,7 +4362,7 @@ err: - if (ret) - goto out; - -- btrfs_i_size_write(dir, dir->vfs_inode.i_size - name_len * 2); -+ btrfs_i_size_write(dir, dir->vfs_inode.i_size - name->len * 2); - inode_inc_iversion(&inode->vfs_inode); - inode_inc_iversion(&dir->vfs_inode); - inode->vfs_inode.i_ctime = current_time(&inode->vfs_inode); -@@ -4379,10 +4375,11 @@ out: - - int btrfs_unlink_inode(struct btrfs_trans_handle *trans, - struct btrfs_inode *dir, struct btrfs_inode *inode, -- const char *name, int name_len) -+ const struct fscrypt_str *name) - { - int ret; -- ret = __btrfs_unlink_inode(trans, dir, inode, name, name_len, NULL); -+ -+ ret = __btrfs_unlink_inode(trans, dir, inode, name, NULL); - if (!ret) { - drop_nlink(&inode->vfs_inode); - ret = btrfs_update_inode(trans, inode->root, inode); -@@ -4418,29 +4415,39 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) - struct btrfs_trans_handle *trans; - struct inode *inode = d_inode(dentry); - int ret; -+ struct fscrypt_name fname; -+ -+ ret = fscrypt_setup_filename(dir, &dentry->d_name, 1, &fname); -+ if (ret) -+ return ret; -+ -+ /* This needs to handle no-key deletions later on */ - - trans = __unlink_start_trans(dir); -- if (IS_ERR(trans)) -- return PTR_ERR(trans); -+ if (IS_ERR(trans)) { -+ ret = PTR_ERR(trans); -+ goto fscrypt_free; -+ } - - btrfs_record_unlink_dir(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), - 0); - -- ret = btrfs_unlink_inode(trans, BTRFS_I(dir), -- BTRFS_I(d_inode(dentry)), dentry->d_name.name, -- dentry->d_name.len); -+ ret = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), -+ &fname.disk_name); - if (ret) -- goto out; -+ goto end_trans; - - if (inode->i_nlink == 0) { - ret = btrfs_orphan_add(trans, BTRFS_I(inode)); - if (ret) -- goto out; -+ goto end_trans; - } - --out: -+end_trans: - btrfs_end_transaction(trans); - btrfs_btree_balance_dirty(BTRFS_I(dir)->root->fs_info); -+fscrypt_free: -+ fscrypt_free_filename(&fname); - return ret; - } - -@@ -4453,12 +4460,17 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, - struct extent_buffer *leaf; - struct btrfs_dir_item *di; - struct btrfs_key key; -- const char *name = dentry->d_name.name; -- int name_len = dentry->d_name.len; - u64 index; - int ret; - u64 objectid; - u64 dir_ino = btrfs_ino(BTRFS_I(dir)); -+ struct fscrypt_name fname; -+ -+ ret = fscrypt_setup_filename(dir, &dentry->d_name, 1, &fname); -+ if (ret) -+ return ret; -+ -+ /* This needs to handle no-key deletions later on */ - - if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) { - objectid = inode->root->root_key.objectid; -@@ -4466,15 +4478,18 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, - objectid = inode->location.objectid; - } else { - WARN_ON(1); -+ fscrypt_free_filename(&fname); - return -EINVAL; - } - - path = btrfs_alloc_path(); -- if (!path) -- return -ENOMEM; -+ if (!path) { -+ ret = -ENOMEM; -+ goto out; -+ } - - di = btrfs_lookup_dir_item(trans, root, path, dir_ino, -- name, name_len, -1); -+ &fname.disk_name, -1); - if (IS_ERR_OR_NULL(di)) { - ret = di ? PTR_ERR(di) : -ENOENT; - goto out; -@@ -4500,8 +4515,7 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, - * call btrfs_del_root_ref, and it _shouldn't_ fail. - */ - if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) { -- di = btrfs_search_dir_index_item(root, path, dir_ino, -- name, name_len); -+ di = btrfs_search_dir_index_item(root, path, dir_ino, &fname.disk_name); - if (IS_ERR_OR_NULL(di)) { - if (!di) - ret = -ENOENT; -@@ -4518,7 +4532,7 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, - } else { - ret = btrfs_del_root_ref(trans, objectid, - root->root_key.objectid, dir_ino, -- &index, name, name_len); -+ &index, &fname.disk_name); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto out; -@@ -4531,7 +4545,7 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, - goto out; - } - -- btrfs_i_size_write(BTRFS_I(dir), dir->i_size - name_len * 2); -+ btrfs_i_size_write(BTRFS_I(dir), dir->i_size - fname.disk_name.len * 2); - inode_inc_iversion(dir); - dir->i_mtime = current_time(dir); - dir->i_ctime = dir->i_mtime; -@@ -4540,6 +4554,7 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, - btrfs_abort_transaction(trans, ret); - out: - btrfs_free_path(path); -+ fscrypt_free_filename(&fname); - return ret; - } - -@@ -4553,6 +4568,7 @@ static noinline int may_destroy_subvol(struct btrfs_root *root) - struct btrfs_path *path; - struct btrfs_dir_item *di; - struct btrfs_key key; -+ struct fscrypt_str name = FSTR_INIT("default", 7); - u64 dir_id; - int ret; - -@@ -4563,7 +4579,7 @@ static noinline int may_destroy_subvol(struct btrfs_root *root) - /* Make sure this root isn't set as the default subvol */ - dir_id = btrfs_super_root_dir(fs_info->super_copy); - di = btrfs_lookup_dir_item(NULL, fs_info->tree_root, path, -- dir_id, "default", 7, 0); -+ dir_id, &name, 0); - if (di && !IS_ERR(di)) { - btrfs_dir_item_key_to_cpu(path->nodes[0], di, &key); - if (key.objectid == root->root_key.objectid) { -@@ -4802,6 +4818,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) - int err = 0; - struct btrfs_trans_handle *trans; - u64 last_unlink_trans; -+ struct fscrypt_name fname; - - if (inode->i_size > BTRFS_EMPTY_DIR_SIZE) - return -ENOTEMPTY; -@@ -4814,9 +4831,17 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) - return btrfs_delete_subvolume(dir, dentry); - } - -+ err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &fname); -+ if (err) -+ return err; -+ -+ /* This needs to handle no-key deletions later on */ -+ - trans = __unlink_start_trans(dir); -- if (IS_ERR(trans)) -- return PTR_ERR(trans); -+ if (IS_ERR(trans)) { -+ err = PTR_ERR(trans); -+ goto out_notrans; -+ } - - if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { - err = btrfs_unlink_subvol(trans, dir, dentry); -@@ -4830,9 +4855,8 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) - last_unlink_trans = BTRFS_I(inode)->last_unlink_trans; - - /* now the directory is empty */ -- err = btrfs_unlink_inode(trans, BTRFS_I(dir), -- BTRFS_I(d_inode(dentry)), dentry->d_name.name, -- dentry->d_name.len); -+ err = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), -+ &fname.disk_name); - if (!err) { - btrfs_i_size_write(BTRFS_I(inode), 0); - /* -@@ -4851,7 +4875,9 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) - } - out: - btrfs_end_transaction(trans); -+out_notrans: - btrfs_btree_balance_dirty(fs_info); -+ fscrypt_free_filename(&fname); - - return err; - } -@@ -5532,19 +5558,24 @@ no_delete: - static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, - struct btrfs_key *location, u8 *type) - { -- const char *name = dentry->d_name.name; -- int namelen = dentry->d_name.len; - struct btrfs_dir_item *di; - struct btrfs_path *path; - struct btrfs_root *root = BTRFS_I(dir)->root; - int ret = 0; -+ struct fscrypt_name fname; - - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - -+ ret = fscrypt_setup_filename(dir, &dentry->d_name, 1, &fname); -+ if (ret) -+ goto out; -+ -+ /* This needs to handle no-key deletions later on */ -+ - di = btrfs_lookup_dir_item(NULL, root, path, btrfs_ino(BTRFS_I(dir)), -- name, namelen, 0); -+ &fname.disk_name, 0); - if (IS_ERR_OR_NULL(di)) { - ret = di ? PTR_ERR(di) : -ENOENT; - goto out; -@@ -5556,12 +5587,13 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, - ret = -EUCLEAN; - btrfs_warn(root->fs_info, - "%s gets something invalid in DIR_ITEM (name %s, directory ino %llu, location(%llu %u %llu))", -- __func__, name, btrfs_ino(BTRFS_I(dir)), -+ __func__, fname.disk_name.name, btrfs_ino(BTRFS_I(dir)), - location->objectid, location->type, location->offset); - } - if (!ret) - *type = btrfs_dir_type(path->nodes[0], di); - out: -+ fscrypt_free_filename(&fname); - btrfs_free_path(path); - return ret; - } -@@ -5584,6 +5616,11 @@ static int fixup_tree_root_location(struct btrfs_fs_info *fs_info, - struct btrfs_key key; - int ret; - int err = 0; -+ struct fscrypt_name fname; -+ -+ ret = fscrypt_setup_filename(dir, &dentry->d_name, 0, &fname); -+ if (ret) -+ return ret; - - path = btrfs_alloc_path(); - if (!path) { -@@ -5606,12 +5643,11 @@ static int fixup_tree_root_location(struct btrfs_fs_info *fs_info, - leaf = path->nodes[0]; - ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); - if (btrfs_root_ref_dirid(leaf, ref) != btrfs_ino(BTRFS_I(dir)) || -- btrfs_root_ref_name_len(leaf, ref) != dentry->d_name.len) -+ btrfs_root_ref_name_len(leaf, ref) != fname.disk_name.len) - goto out; - -- ret = memcmp_extent_buffer(leaf, dentry->d_name.name, -- (unsigned long)(ref + 1), -- dentry->d_name.len); -+ ret = memcmp_extent_buffer(leaf, fname.disk_name.name, -+ (unsigned long)(ref + 1), fname.disk_name.len); - if (ret) - goto out; - -@@ -5630,6 +5666,7 @@ static int fixup_tree_root_location(struct btrfs_fs_info *fs_info, - err = 0; - out: - btrfs_free_path(path); -+ fscrypt_free_filename(&fname); - return err; - } - -@@ -6238,9 +6275,18 @@ int btrfs_new_inode_prepare(struct btrfs_new_inode_args *args, - struct inode *inode = args->inode; - int ret; - -+ if (!args->orphan) { -+ ret = fscrypt_setup_filename(dir, &args->dentry->d_name, 0, -+ &args->fname); -+ if (ret) -+ return ret; -+ } -+ - ret = posix_acl_create(dir, &inode->i_mode, &args->default_acl, &args->acl); -- if (ret) -+ if (ret) { -+ fscrypt_free_filename(&args->fname); - return ret; -+ } - - /* 1 to add inode item */ - *trans_num_items = 1; -@@ -6280,6 +6326,7 @@ void btrfs_new_inode_args_destroy(struct btrfs_new_inode_args *args) - { - posix_acl_release(args->acl); - posix_acl_release(args->default_acl); -+ fscrypt_free_filename(&args->fname); - } - - /* -@@ -6315,8 +6362,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, - { - struct inode *dir = args->dir; - struct inode *inode = args->inode; -- const char *name = args->orphan ? NULL : args->dentry->d_name.name; -- int name_len = args->orphan ? 0 : args->dentry->d_name.len; -+ const struct fscrypt_str *name = args->orphan ? NULL : &args->fname.disk_name; - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); - struct btrfs_root *root; - struct btrfs_inode_item *inode_item; -@@ -6417,7 +6463,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, - sizes[1] = 2 + sizeof(*ref); - } else { - key[1].offset = btrfs_ino(BTRFS_I(dir)); -- sizes[1] = name_len + sizeof(*ref); -+ sizes[1] = name->len + sizeof(*ref); - } - } - -@@ -6456,10 +6502,12 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, - btrfs_set_inode_ref_index(path->nodes[0], ref, 0); - write_extent_buffer(path->nodes[0], "..", ptr, 2); - } else { -- btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len); -+ btrfs_set_inode_ref_name_len(path->nodes[0], ref, -+ name->len); - btrfs_set_inode_ref_index(path->nodes[0], ref, - BTRFS_I(inode)->dir_index); -- write_extent_buffer(path->nodes[0], name, ptr, name_len); -+ write_extent_buffer(path->nodes[0], name->name, ptr, -+ name->len); - } - } - -@@ -6520,7 +6568,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, - ret = btrfs_orphan_add(trans, BTRFS_I(inode)); - } else { - ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), name, -- name_len, 0, BTRFS_I(inode)->dir_index); -+ 0, BTRFS_I(inode)->dir_index); - } - if (ret) { - btrfs_abort_transaction(trans, ret); -@@ -6549,7 +6597,7 @@ out: - */ - int btrfs_add_link(struct btrfs_trans_handle *trans, - struct btrfs_inode *parent_inode, struct btrfs_inode *inode, -- const char *name, int name_len, int add_backref, u64 index) -+ const struct fscrypt_str *name, int add_backref, u64 index) - { - int ret = 0; - struct btrfs_key key; -@@ -6568,17 +6616,17 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, - if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) { - ret = btrfs_add_root_ref(trans, key.objectid, - root->root_key.objectid, parent_ino, -- index, name, name_len); -+ index, name); - } else if (add_backref) { -- ret = btrfs_insert_inode_ref(trans, root, name, name_len, ino, -- parent_ino, index); -+ ret = btrfs_insert_inode_ref(trans, root, name, -+ ino, parent_ino, index); - } - - /* Nothing to clean up yet */ - if (ret) - return ret; - -- ret = btrfs_insert_dir_item(trans, name, name_len, parent_inode, &key, -+ ret = btrfs_insert_dir_item(trans, name, parent_inode, &key, - btrfs_inode_type(&inode->vfs_inode), index); - if (ret == -EEXIST || ret == -EOVERFLOW) - goto fail_dir_item; -@@ -6588,7 +6636,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, - } - - btrfs_i_size_write(parent_inode, parent_inode->vfs_inode.i_size + -- name_len * 2); -+ name->len * 2); - inode_inc_iversion(&parent_inode->vfs_inode); - /* - * If we are replaying a log tree, we do not want to update the mtime -@@ -6613,15 +6661,15 @@ fail_dir_item: - int err; - err = btrfs_del_root_ref(trans, key.objectid, - root->root_key.objectid, parent_ino, -- &local_index, name, name_len); -+ &local_index, name); - if (err) - btrfs_abort_transaction(trans, err); - } else if (add_backref) { - u64 local_index; - int err; - -- err = btrfs_del_inode_ref(trans, root, name, name_len, -- ino, parent_ino, &local_index); -+ err = btrfs_del_inode_ref(trans, root, name, ino, parent_ino, -+ &local_index); - if (err) - btrfs_abort_transaction(trans, err); - } -@@ -6704,6 +6752,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, - struct btrfs_root *root = BTRFS_I(dir)->root; - struct inode *inode = d_inode(old_dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); -+ struct fscrypt_name fname; - u64 index; - int err; - int drop_inode = 0; -@@ -6715,6 +6764,10 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, - if (inode->i_nlink >= BTRFS_LINK_MAX) - return -EMLINK; - -+ err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &fname); -+ if (err) -+ goto fail; -+ - err = btrfs_set_inode_index(BTRFS_I(dir), &index); - if (err) - goto fail; -@@ -6741,7 +6794,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, - set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); - - err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), -- dentry->d_name.name, dentry->d_name.len, 1, index); -+ &fname.disk_name, 1, index); - - if (err) { - drop_inode = 1; -@@ -6765,6 +6818,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, - } - - fail: -+ fscrypt_free_filename(&fname); - if (trans) - btrfs_end_transaction(trans); - if (drop_inode) { -@@ -9037,6 +9091,8 @@ static int btrfs_rename_exchange(struct inode *old_dir, - int ret; - int ret2; - bool need_abort = false; -+ struct fscrypt_name old_fname, new_fname; -+ struct fscrypt_str *old_name, *new_name; - - /* - * For non-subvolumes allow exchange only within one subvolume, in the -@@ -9048,6 +9104,19 @@ static int btrfs_rename_exchange(struct inode *old_dir, - new_ino != BTRFS_FIRST_FREE_OBJECTID)) - return -EXDEV; - -+ ret = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &old_fname); -+ if (ret) -+ return ret; -+ -+ ret = fscrypt_setup_filename(new_dir, &new_dentry->d_name, 0, &new_fname); -+ if (ret) { -+ fscrypt_free_filename(&old_fname); -+ return ret; -+ } -+ -+ old_name = &old_fname.disk_name; -+ new_name = &new_fname.disk_name; -+ - /* close the race window with snapshot create/destroy ioctl */ - if (old_ino == BTRFS_FIRST_FREE_OBJECTID || - new_ino == BTRFS_FIRST_FREE_OBJECTID) -@@ -9115,10 +9184,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, - /* force full log commit if subvolume involved. */ - btrfs_set_log_full_commit(trans); - } else { -- ret = btrfs_insert_inode_ref(trans, dest, -- new_dentry->d_name.name, -- new_dentry->d_name.len, -- old_ino, -+ ret = btrfs_insert_inode_ref(trans, dest, new_name, old_ino, - btrfs_ino(BTRFS_I(new_dir)), - old_idx); - if (ret) -@@ -9131,10 +9197,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, - /* force full log commit if subvolume involved. */ - btrfs_set_log_full_commit(trans); - } else { -- ret = btrfs_insert_inode_ref(trans, root, -- old_dentry->d_name.name, -- old_dentry->d_name.len, -- new_ino, -+ ret = btrfs_insert_inode_ref(trans, root, old_name, new_ino, - btrfs_ino(BTRFS_I(old_dir)), - new_idx); - if (ret) { -@@ -9169,9 +9232,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, - } else { /* src is an inode */ - ret = __btrfs_unlink_inode(trans, BTRFS_I(old_dir), - BTRFS_I(old_dentry->d_inode), -- old_dentry->d_name.name, -- old_dentry->d_name.len, -- &old_rename_ctx); -+ old_name, &old_rename_ctx); - if (!ret) - ret = btrfs_update_inode(trans, root, BTRFS_I(old_inode)); - } -@@ -9186,9 +9247,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, - } else { /* dest is an inode */ - ret = __btrfs_unlink_inode(trans, BTRFS_I(new_dir), - BTRFS_I(new_dentry->d_inode), -- new_dentry->d_name.name, -- new_dentry->d_name.len, -- &new_rename_ctx); -+ new_name, &new_rename_ctx); - if (!ret) - ret = btrfs_update_inode(trans, dest, BTRFS_I(new_inode)); - } -@@ -9198,16 +9257,14 @@ static int btrfs_rename_exchange(struct inode *old_dir, - } - - ret = btrfs_add_link(trans, BTRFS_I(new_dir), BTRFS_I(old_inode), -- new_dentry->d_name.name, -- new_dentry->d_name.len, 0, old_idx); -+ new_name, 0, old_idx); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto out_fail; - } - - ret = btrfs_add_link(trans, BTRFS_I(old_dir), BTRFS_I(new_inode), -- old_dentry->d_name.name, -- old_dentry->d_name.len, 0, new_idx); -+ old_name, 0, new_idx); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto out_fail; -@@ -9250,6 +9307,8 @@ out_notrans: - old_ino == BTRFS_FIRST_FREE_OBJECTID) - up_read(&fs_info->subvol_sem); - -+ fscrypt_free_filename(&new_fname); -+ fscrypt_free_filename(&old_fname); - return ret; - } - -@@ -9289,6 +9348,7 @@ static int btrfs_rename(struct user_namespace *mnt_userns, - int ret; - int ret2; - u64 old_ino = btrfs_ino(BTRFS_I(old_inode)); -+ struct fscrypt_name old_fname, new_fname; - - if (btrfs_ino(BTRFS_I(new_dir)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) - return -EPERM; -@@ -9305,22 +9365,28 @@ static int btrfs_rename(struct user_namespace *mnt_userns, - new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) - return -ENOTEMPTY; - -+ ret = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &old_fname); -+ if (ret) -+ return ret; - -- /* check for collisions, even if the name isn't there */ -- ret = btrfs_check_dir_item_collision(dest, new_dir->i_ino, -- new_dentry->d_name.name, -- new_dentry->d_name.len); -+ ret = fscrypt_setup_filename(new_dir, &new_dentry->d_name, 0, &new_fname); -+ if (ret) { -+ fscrypt_free_filename(&old_fname); -+ return ret; -+ } - -+ /* check for collisions, even if the name isn't there */ -+ ret = btrfs_check_dir_item_collision(dest, new_dir->i_ino, &new_fname.disk_name); - if (ret) { - if (ret == -EEXIST) { - /* we shouldn't get - * eexist without a new_inode */ - if (WARN_ON(!new_inode)) { -- return ret; -+ goto out_fscrypt_names; - } - } else { - /* maybe -EOVERFLOW */ -- return ret; -+ goto out_fscrypt_names; - } - } - ret = 0; -@@ -9334,8 +9400,10 @@ static int btrfs_rename(struct user_namespace *mnt_userns, - - if (flags & RENAME_WHITEOUT) { - whiteout_args.inode = new_whiteout_inode(mnt_userns, old_dir); -- if (!whiteout_args.inode) -- return -ENOMEM; -+ if (!whiteout_args.inode) { -+ ret = -ENOMEM; -+ goto out_fscrypt_names; -+ } - ret = btrfs_new_inode_prepare(&whiteout_args, &trans_num_items); - if (ret) - goto out_whiteout_inode; -@@ -9403,11 +9471,9 @@ static int btrfs_rename(struct user_namespace *mnt_userns, - /* force full log commit if subvolume involved. */ - btrfs_set_log_full_commit(trans); - } else { -- ret = btrfs_insert_inode_ref(trans, dest, -- new_dentry->d_name.name, -- new_dentry->d_name.len, -- old_ino, -- btrfs_ino(BTRFS_I(new_dir)), index); -+ ret = btrfs_insert_inode_ref(trans, dest, &new_fname.disk_name, -+ old_ino, btrfs_ino(BTRFS_I(new_dir)), -+ index); - if (ret) - goto out_fail; - } -@@ -9429,10 +9495,8 @@ static int btrfs_rename(struct user_namespace *mnt_userns, - ret = btrfs_unlink_subvol(trans, old_dir, old_dentry); - } else { - ret = __btrfs_unlink_inode(trans, BTRFS_I(old_dir), -- BTRFS_I(d_inode(old_dentry)), -- old_dentry->d_name.name, -- old_dentry->d_name.len, -- &rename_ctx); -+ BTRFS_I(d_inode(old_dentry)), -+ &old_fname.disk_name, &rename_ctx); - if (!ret) - ret = btrfs_update_inode(trans, root, BTRFS_I(old_inode)); - } -@@ -9451,8 +9515,7 @@ static int btrfs_rename(struct user_namespace *mnt_userns, - } else { - ret = btrfs_unlink_inode(trans, BTRFS_I(new_dir), - BTRFS_I(d_inode(new_dentry)), -- new_dentry->d_name.name, -- new_dentry->d_name.len); -+ &new_fname.disk_name); - } - if (!ret && new_inode->i_nlink == 0) - ret = btrfs_orphan_add(trans, -@@ -9464,8 +9527,7 @@ static int btrfs_rename(struct user_namespace *mnt_userns, - } - - ret = btrfs_add_link(trans, BTRFS_I(new_dir), BTRFS_I(old_inode), -- new_dentry->d_name.name, -- new_dentry->d_name.len, 0, index); -+ &new_fname.disk_name, 0, index); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto out_fail; -@@ -9500,6 +9562,9 @@ out_notrans: - out_whiteout_inode: - if (flags & RENAME_WHITEOUT) - iput(whiteout_args.inode); -+out_fscrypt_names: -+ fscrypt_free_filename(&old_fname); -+ fscrypt_free_filename(&new_fname); - return ret; - } - -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index 2e29fafe0e7d9..9e323420c96d3 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -951,6 +951,7 @@ static noinline int btrfs_mksubvol(const struct path *parent, - struct inode *dir = d_inode(parent->dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); - struct dentry *dentry; -+ struct fscrypt_str name_str = FSTR_INIT((char *)name, namelen); - int error; - - error = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT); -@@ -971,8 +972,7 @@ static noinline int btrfs_mksubvol(const struct path *parent, - * check for them now when we can safely fail - */ - error = btrfs_check_dir_item_collision(BTRFS_I(dir)->root, -- dir->i_ino, name, -- namelen); -+ dir->i_ino, &name_str); - if (error) - goto out_dput; - -@@ -3782,6 +3782,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) - struct btrfs_trans_handle *trans; - struct btrfs_path *path = NULL; - struct btrfs_disk_key disk_key; -+ struct fscrypt_str name = FSTR_INIT("default", 7); - u64 objectid = 0; - u64 dir_id; - int ret; -@@ -3825,7 +3826,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) - - dir_id = btrfs_super_root_dir(fs_info->super_copy); - di = btrfs_lookup_dir_item(trans, fs_info->tree_root, path, -- dir_id, "default", 7, 1); -+ dir_id, &name, 1); - if (IS_ERR_OR_NULL(di)) { - btrfs_release_path(path); - btrfs_end_transaction(trans); -diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c -index e1f599d7a9164..7d783f0943068 100644 ---- a/fs/btrfs/root-tree.c -+++ b/fs/btrfs/root-tree.c -@@ -327,9 +327,8 @@ out: - } - - int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id, -- u64 ref_id, u64 dirid, u64 *sequence, const char *name, -- int name_len) -- -+ u64 ref_id, u64 dirid, u64 *sequence, -+ const struct fscrypt_str *name) - { - struct btrfs_root *tree_root = trans->fs_info->tree_root; - struct btrfs_path *path; -@@ -356,8 +355,8 @@ again: - struct btrfs_root_ref); - ptr = (unsigned long)(ref + 1); - if ((btrfs_root_ref_dirid(leaf, ref) != dirid) || -- (btrfs_root_ref_name_len(leaf, ref) != name_len) || -- memcmp_extent_buffer(leaf, name, ptr, name_len)) { -+ (btrfs_root_ref_name_len(leaf, ref) != name->len) || -+ memcmp_extent_buffer(leaf, name->name, ptr, name->len)) { - ret = -ENOENT; - goto out; - } -@@ -400,8 +399,8 @@ out: - * Will return 0, -ENOMEM, or anything from the CoW path - */ - int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id, -- u64 ref_id, u64 dirid, u64 sequence, const char *name, -- int name_len) -+ u64 ref_id, u64 dirid, u64 sequence, -+ const struct fscrypt_str *name) - { - struct btrfs_root *tree_root = trans->fs_info->tree_root; - struct btrfs_key key; -@@ -420,7 +419,7 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id, - key.offset = ref_id; - again: - ret = btrfs_insert_empty_item(trans, tree_root, path, &key, -- sizeof(*ref) + name_len); -+ sizeof(*ref) + name->len); - if (ret) { - btrfs_abort_transaction(trans, ret); - btrfs_free_path(path); -@@ -431,9 +430,9 @@ again: - ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); - btrfs_set_root_ref_dirid(leaf, ref, dirid); - btrfs_set_root_ref_sequence(leaf, ref, sequence); -- btrfs_set_root_ref_name_len(leaf, ref, name_len); -+ btrfs_set_root_ref_name_len(leaf, ref, name->len); - ptr = (unsigned long)(ref + 1); -- write_extent_buffer(leaf, name, ptr, name_len); -+ write_extent_buffer(leaf, name->name, ptr, name->len); - btrfs_mark_buffer_dirty(leaf); - - if (key.type == BTRFS_ROOT_BACKREF_KEY) { -diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c -index 35e889fe2a95d..547b5c2292186 100644 ---- a/fs/btrfs/send.c -+++ b/fs/btrfs/send.c -@@ -1596,13 +1596,17 @@ static int gen_unique_name(struct send_ctx *sctx, - return -ENOMEM; - - while (1) { -+ struct fscrypt_str tmp_name; -+ - len = snprintf(tmp, sizeof(tmp), "o%llu-%llu-%llu", - ino, gen, idx); - ASSERT(len < sizeof(tmp)); -+ tmp_name.name = tmp; -+ tmp_name.len = strlen(tmp); - - di = btrfs_lookup_dir_item(NULL, sctx->send_root, - path, BTRFS_FIRST_FREE_OBJECTID, -- tmp, strlen(tmp), 0); -+ &tmp_name, 0); - btrfs_release_path(path); - if (IS_ERR(di)) { - ret = PTR_ERR(di); -@@ -1622,7 +1626,7 @@ static int gen_unique_name(struct send_ctx *sctx, - - di = btrfs_lookup_dir_item(NULL, sctx->parent_root, - path, BTRFS_FIRST_FREE_OBJECTID, -- tmp, strlen(tmp), 0); -+ &tmp_name, 0); - btrfs_release_path(path); - if (IS_ERR(di)) { - ret = PTR_ERR(di); -@@ -1752,13 +1756,13 @@ static int lookup_dir_item_inode(struct btrfs_root *root, - struct btrfs_dir_item *di; - struct btrfs_key key; - struct btrfs_path *path; -+ struct fscrypt_str name_str = FSTR_INIT((char *)name, name_len); - - path = alloc_path_for_send(); - if (!path) - return -ENOMEM; - -- di = btrfs_lookup_dir_item(NULL, root, path, -- dir, name, name_len, 0); -+ di = btrfs_lookup_dir_item(NULL, root, path, dir, &name_str, 0); - if (IS_ERR_OR_NULL(di)) { - ret = di ? PTR_ERR(di) : -ENOENT; - goto out; -diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c -index 582b71b7fa779..2c562febd801e 100644 ---- a/fs/btrfs/super.c -+++ b/fs/btrfs/super.c -@@ -1398,6 +1398,7 @@ static int get_default_subvol_objectid(struct btrfs_fs_info *fs_info, u64 *objec - struct btrfs_dir_item *di; - struct btrfs_path *path; - struct btrfs_key location; -+ struct fscrypt_str name = FSTR_INIT("default", 7); - u64 dir_id; - - path = btrfs_alloc_path(); -@@ -1410,7 +1411,7 @@ static int get_default_subvol_objectid(struct btrfs_fs_info *fs_info, u64 *objec - * to mount. - */ - dir_id = btrfs_super_root_dir(fs_info->super_copy); -- di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); -+ di = btrfs_lookup_dir_item(NULL, root, path, dir_id, &name, 0); - if (IS_ERR(di)) { - btrfs_free_path(path); - return PTR_ERR(di); -diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c -index a555567594418..1193214ba8c10 100644 ---- a/fs/btrfs/transaction.c -+++ b/fs/btrfs/transaction.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1627,10 +1628,9 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - struct btrfs_root *root = pending->root; - struct btrfs_root *parent_root; - struct btrfs_block_rsv *rsv; -- struct inode *parent_inode; -+ struct inode *parent_inode = pending->dir; - struct btrfs_path *path; - struct btrfs_dir_item *dir_item; -- struct dentry *dentry; - struct extent_buffer *tmp; - struct extent_buffer *old; - struct timespec64 cur_time; -@@ -1639,6 +1639,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - u64 index = 0; - u64 objectid; - u64 root_flags; -+ unsigned int nofs_flags; -+ struct fscrypt_name fname; - - ASSERT(pending->path); - path = pending->path; -@@ -1646,9 +1648,22 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - ASSERT(pending->root_item); - new_root_item = pending->root_item; - -+ /* -+ * We're inside a transaction and must make sure that any potential -+ * allocations with GFP_KERNEL in fscrypt won't recurse back to -+ * filesystem. -+ */ -+ nofs_flags = memalloc_nofs_save(); -+ pending->error = fscrypt_setup_filename(parent_inode, -+ &pending->dentry->d_name, 0, -+ &fname); -+ memalloc_nofs_restore(nofs_flags); -+ if (pending->error) -+ goto free_pending; -+ - pending->error = btrfs_get_free_objectid(tree_root, &objectid); - if (pending->error) -- goto no_free_objectid; -+ goto free_fname; - - /* - * Make qgroup to skip current new snapshot's qgroupid, as it is -@@ -1677,8 +1692,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - trace_btrfs_space_reservation(fs_info, "transaction", - trans->transid, - trans->bytes_reserved, 1); -- dentry = pending->dentry; -- parent_inode = pending->dir; - parent_root = BTRFS_I(parent_inode)->root; - ret = record_root_in_trans(trans, parent_root, 0); - if (ret) -@@ -1694,8 +1707,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - /* check if there is a file/dir which has the same name. */ - dir_item = btrfs_lookup_dir_item(NULL, parent_root, path, - btrfs_ino(BTRFS_I(parent_inode)), -- dentry->d_name.name, -- dentry->d_name.len, 0); -+ &fname.disk_name, 0); - if (dir_item != NULL && !IS_ERR(dir_item)) { - pending->error = -EEXIST; - goto dir_item_existed; -@@ -1790,7 +1802,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - ret = btrfs_add_root_ref(trans, objectid, - parent_root->root_key.objectid, - btrfs_ino(BTRFS_I(parent_inode)), index, -- dentry->d_name.name, dentry->d_name.len); -+ &fname.disk_name); - if (ret) { - btrfs_abort_transaction(trans, ret); - goto fail; -@@ -1822,9 +1834,9 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - if (ret < 0) - goto fail; - -- ret = btrfs_insert_dir_item(trans, dentry->d_name.name, -- dentry->d_name.len, BTRFS_I(parent_inode), -- &key, BTRFS_FT_DIR, index); -+ ret = btrfs_insert_dir_item(trans, &fname.disk_name, -+ BTRFS_I(parent_inode), &key, BTRFS_FT_DIR, -+ index); - /* We have check then name at the beginning, so it is impossible. */ - BUG_ON(ret == -EEXIST || ret == -EOVERFLOW); - if (ret) { -@@ -1833,7 +1845,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, - } - - btrfs_i_size_write(BTRFS_I(parent_inode), parent_inode->i_size + -- dentry->d_name.len * 2); -+ fname.disk_name.len * 2); - parent_inode->i_mtime = current_time(parent_inode); - parent_inode->i_ctime = parent_inode->i_mtime; - ret = btrfs_update_inode_fallback(trans, parent_root, BTRFS_I(parent_inode)); -@@ -1865,7 +1877,9 @@ dir_item_existed: - trans->bytes_reserved = 0; - clear_skip_qgroup: - btrfs_clear_skip_qgroup(trans); --no_free_objectid: -+free_fname: -+ fscrypt_free_filename(&fname); -+free_pending: - kfree(new_root_item); - pending->root_item = NULL; - btrfs_free_path(path); -diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c -index 00be69ce7b90f..c03ff6a5a7f6b 100644 ---- a/fs/btrfs/tree-log.c -+++ b/fs/btrfs/tree-log.c -@@ -595,6 +595,21 @@ static int overwrite_item(struct btrfs_trans_handle *trans, - return do_overwrite_item(trans, root, path, eb, slot, key); - } - -+static int read_alloc_one_name(struct extent_buffer *eb, void *start, int len, -+ struct fscrypt_str *name) -+{ -+ char *buf; -+ -+ buf = kmalloc(len, GFP_NOFS); -+ if (!buf) -+ return -ENOMEM; -+ -+ read_extent_buffer(eb, buf, (unsigned long)start, len); -+ name->name = buf; -+ name->len = len; -+ return 0; -+} -+ - /* - * simple helper to read an inode off the disk from a given root - * This can only be called for subvolume roots and not for the log -@@ -901,12 +916,11 @@ out: - static int unlink_inode_for_log_replay(struct btrfs_trans_handle *trans, - struct btrfs_inode *dir, - struct btrfs_inode *inode, -- const char *name, -- int name_len) -+ const struct fscrypt_str *name) - { - int ret; - -- ret = btrfs_unlink_inode(trans, dir, inode, name, name_len); -+ ret = btrfs_unlink_inode(trans, dir, inode, name); - if (ret) - return ret; - /* -@@ -933,8 +947,7 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, - { - struct btrfs_root *root = dir->root; - struct inode *inode; -- char *name; -- int name_len; -+ struct fscrypt_str name; - struct extent_buffer *leaf; - struct btrfs_key location; - int ret; -@@ -942,12 +955,10 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, - leaf = path->nodes[0]; - - btrfs_dir_item_key_to_cpu(leaf, di, &location); -- name_len = btrfs_dir_name_len(leaf, di); -- name = kmalloc(name_len, GFP_NOFS); -- if (!name) -+ ret = read_alloc_one_name(leaf, di + 1, btrfs_dir_name_len(leaf, di), &name); -+ if (ret) - return -ENOMEM; - -- read_extent_buffer(leaf, name, (unsigned long)(di + 1), name_len); - btrfs_release_path(path); - - inode = read_one_inode(root, location.objectid); -@@ -960,10 +971,9 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, - if (ret) - goto out; - -- ret = unlink_inode_for_log_replay(trans, dir, BTRFS_I(inode), name, -- name_len); -+ ret = unlink_inode_for_log_replay(trans, dir, BTRFS_I(inode), &name); - out: -- kfree(name); -+ kfree(name.name); - iput(inode); - return ret; - } -@@ -978,14 +988,14 @@ out: - static noinline int inode_in_dir(struct btrfs_root *root, - struct btrfs_path *path, - u64 dirid, u64 objectid, u64 index, -- const char *name, int name_len) -+ struct fscrypt_str *name) - { - struct btrfs_dir_item *di; - struct btrfs_key location; - int ret = 0; - - di = btrfs_lookup_dir_index_item(NULL, root, path, dirid, -- index, name, name_len, 0); -+ index, name, 0); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; -@@ -998,7 +1008,7 @@ static noinline int inode_in_dir(struct btrfs_root *root, - } - - btrfs_release_path(path); -- di = btrfs_lookup_dir_item(NULL, root, path, dirid, name, name_len, 0); -+ di = btrfs_lookup_dir_item(NULL, root, path, dirid, name, 0); - if (IS_ERR(di)) { - ret = PTR_ERR(di); - goto out; -@@ -1025,7 +1035,7 @@ out: - static noinline int backref_in_log(struct btrfs_root *log, - struct btrfs_key *key, - u64 ref_objectid, -- const char *name, int namelen) -+ const struct fscrypt_str *name) - { - struct btrfs_path *path; - int ret; -@@ -1045,12 +1055,10 @@ static noinline int backref_in_log(struct btrfs_root *log, - if (key->type == BTRFS_INODE_EXTREF_KEY) - ret = !!btrfs_find_name_in_ext_backref(path->nodes[0], - path->slots[0], -- ref_objectid, -- name, namelen); -+ ref_objectid, name); - else - ret = !!btrfs_find_name_in_backref(path->nodes[0], -- path->slots[0], -- name, namelen); -+ path->slots[0], name); - out: - btrfs_free_path(path); - return ret; -@@ -1063,11 +1071,9 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, - struct btrfs_inode *dir, - struct btrfs_inode *inode, - u64 inode_objectid, u64 parent_objectid, -- u64 ref_index, char *name, int namelen) -+ u64 ref_index, struct fscrypt_str *name) - { - int ret; -- char *victim_name; -- int victim_name_len; - struct extent_buffer *leaf; - struct btrfs_dir_item *di; - struct btrfs_key search_key; -@@ -1099,43 +1105,40 @@ again: - ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); - ptr_end = ptr + btrfs_item_size(leaf, path->slots[0]); - while (ptr < ptr_end) { -- victim_ref = (struct btrfs_inode_ref *)ptr; -- victim_name_len = btrfs_inode_ref_name_len(leaf, -- victim_ref); -- victim_name = kmalloc(victim_name_len, GFP_NOFS); -- if (!victim_name) -- return -ENOMEM; -+ struct fscrypt_str victim_name; - -- read_extent_buffer(leaf, victim_name, -- (unsigned long)(victim_ref + 1), -- victim_name_len); -+ victim_ref = (struct btrfs_inode_ref *)ptr; -+ ret = read_alloc_one_name(leaf, (victim_ref + 1), -+ btrfs_inode_ref_name_len(leaf, victim_ref), -+ &victim_name); -+ if (ret) -+ return ret; - - ret = backref_in_log(log_root, &search_key, -- parent_objectid, victim_name, -- victim_name_len); -+ parent_objectid, &victim_name); - if (ret < 0) { -- kfree(victim_name); -+ kfree(victim_name.name); - return ret; - } else if (!ret) { - inc_nlink(&inode->vfs_inode); - btrfs_release_path(path); - - ret = unlink_inode_for_log_replay(trans, dir, inode, -- victim_name, victim_name_len); -- kfree(victim_name); -+ &victim_name); -+ kfree(victim_name.name); - if (ret) - return ret; - goto again; - } -- kfree(victim_name); -+ kfree(victim_name.name); - -- ptr = (unsigned long)(victim_ref + 1) + victim_name_len; -+ ptr = (unsigned long)(victim_ref + 1) + victim_name.len; - } - } - btrfs_release_path(path); - - /* Same search but for extended refs */ -- extref = btrfs_lookup_inode_extref(NULL, root, path, name, namelen, -+ extref = btrfs_lookup_inode_extref(NULL, root, path, name, - inode_objectid, parent_objectid, 0, - 0); - if (IS_ERR(extref)) { -@@ -1152,29 +1155,28 @@ again: - base = btrfs_item_ptr_offset(leaf, path->slots[0]); - - while (cur_offset < item_size) { -- extref = (struct btrfs_inode_extref *)(base + cur_offset); -+ struct fscrypt_str victim_name; - -- victim_name_len = btrfs_inode_extref_name_len(leaf, extref); -+ extref = (struct btrfs_inode_extref *)(base + cur_offset); - - if (btrfs_inode_extref_parent(leaf, extref) != parent_objectid) - goto next; - -- victim_name = kmalloc(victim_name_len, GFP_NOFS); -- if (!victim_name) -- return -ENOMEM; -- read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name, -- victim_name_len); -+ ret = read_alloc_one_name(leaf, &extref->name, -+ btrfs_inode_extref_name_len(leaf, extref), -+ &victim_name); -+ if (ret) -+ return ret; - - search_key.objectid = inode_objectid; - search_key.type = BTRFS_INODE_EXTREF_KEY; - search_key.offset = btrfs_extref_hash(parent_objectid, -- victim_name, -- victim_name_len); -+ victim_name.name, -+ victim_name.len); - ret = backref_in_log(log_root, &search_key, -- parent_objectid, victim_name, -- victim_name_len); -+ parent_objectid, &victim_name); - if (ret < 0) { -- kfree(victim_name); -+ kfree(victim_name.name); - return ret; - } else if (!ret) { - ret = -ENOENT; -@@ -1186,26 +1188,24 @@ again: - - ret = unlink_inode_for_log_replay(trans, - BTRFS_I(victim_parent), -- inode, -- victim_name, -- victim_name_len); -+ inode, &victim_name); - } - iput(victim_parent); -- kfree(victim_name); -+ kfree(victim_name.name); - if (ret) - return ret; - goto again; - } -- kfree(victim_name); -+ kfree(victim_name.name); - next: -- cur_offset += victim_name_len + sizeof(*extref); -+ cur_offset += victim_name.len + sizeof(*extref); - } - } - btrfs_release_path(path); - - /* look for a conflicting sequence number */ - di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir), -- ref_index, name, namelen, 0); -+ ref_index, name, 0); - if (IS_ERR(di)) { - return PTR_ERR(di); - } else if (di) { -@@ -1216,8 +1216,7 @@ next: - btrfs_release_path(path); - - /* look for a conflicting name */ -- di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir), -- name, namelen, 0); -+ di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir), name, 0); - if (IS_ERR(di)) { - return PTR_ERR(di); - } else if (di) { -@@ -1231,20 +1230,18 @@ next: - } - - static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr, -- u32 *namelen, char **name, u64 *index, -+ struct fscrypt_str *name, u64 *index, - u64 *parent_objectid) - { - struct btrfs_inode_extref *extref; -+ int ret; - - extref = (struct btrfs_inode_extref *)ref_ptr; - -- *namelen = btrfs_inode_extref_name_len(eb, extref); -- *name = kmalloc(*namelen, GFP_NOFS); -- if (*name == NULL) -- return -ENOMEM; -- -- read_extent_buffer(eb, *name, (unsigned long)&extref->name, -- *namelen); -+ ret = read_alloc_one_name(eb, &extref->name, -+ btrfs_inode_extref_name_len(eb, extref), name); -+ if (ret) -+ return ret; - - if (index) - *index = btrfs_inode_extref_index(eb, extref); -@@ -1255,18 +1252,17 @@ static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr, - } - - static int ref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr, -- u32 *namelen, char **name, u64 *index) -+ struct fscrypt_str *name, u64 *index) - { - struct btrfs_inode_ref *ref; -+ int ret; - - ref = (struct btrfs_inode_ref *)ref_ptr; - -- *namelen = btrfs_inode_ref_name_len(eb, ref); -- *name = kmalloc(*namelen, GFP_NOFS); -- if (*name == NULL) -- return -ENOMEM; -- -- read_extent_buffer(eb, *name, (unsigned long)(ref + 1), *namelen); -+ ret = read_alloc_one_name(eb, ref + 1, btrfs_inode_ref_name_len(eb, ref), -+ name); -+ if (ret) -+ return ret; - - if (index) - *index = btrfs_inode_ref_index(eb, ref); -@@ -1308,28 +1304,24 @@ again: - ref_ptr = btrfs_item_ptr_offset(eb, path->slots[0]); - ref_end = ref_ptr + btrfs_item_size(eb, path->slots[0]); - while (ref_ptr < ref_end) { -- char *name = NULL; -- int namelen; -+ struct fscrypt_str name; - u64 parent_id; - - if (key->type == BTRFS_INODE_EXTREF_KEY) { -- ret = extref_get_fields(eb, ref_ptr, &namelen, &name, -+ ret = extref_get_fields(eb, ref_ptr, &name, - NULL, &parent_id); - } else { - parent_id = key->offset; -- ret = ref_get_fields(eb, ref_ptr, &namelen, &name, -- NULL); -+ ret = ref_get_fields(eb, ref_ptr, &name, NULL); - } - if (ret) - goto out; - - if (key->type == BTRFS_INODE_EXTREF_KEY) - ret = !!btrfs_find_name_in_ext_backref(log_eb, log_slot, -- parent_id, name, -- namelen); -+ parent_id, &name); - else -- ret = !!btrfs_find_name_in_backref(log_eb, log_slot, -- name, namelen); -+ ret = !!btrfs_find_name_in_backref(log_eb, log_slot, &name); - - if (!ret) { - struct inode *dir; -@@ -1338,20 +1330,20 @@ again: - dir = read_one_inode(root, parent_id); - if (!dir) { - ret = -ENOENT; -- kfree(name); -+ kfree(name.name); - goto out; - } - ret = unlink_inode_for_log_replay(trans, BTRFS_I(dir), -- inode, name, namelen); -- kfree(name); -+ inode, &name); -+ kfree(name.name); - iput(dir); - if (ret) - goto out; - goto again; - } - -- kfree(name); -- ref_ptr += namelen; -+ kfree(name.name); -+ ref_ptr += name.len; - if (key->type == BTRFS_INODE_EXTREF_KEY) - ref_ptr += sizeof(struct btrfs_inode_extref); - else -@@ -1380,8 +1372,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, - struct inode *inode = NULL; - unsigned long ref_ptr; - unsigned long ref_end; -- char *name = NULL; -- int namelen; -+ struct fscrypt_str name; - int ret; - int log_ref_ver = 0; - u64 parent_objectid; -@@ -1425,7 +1416,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, - - while (ref_ptr < ref_end) { - if (log_ref_ver) { -- ret = extref_get_fields(eb, ref_ptr, &namelen, &name, -+ ret = extref_get_fields(eb, ref_ptr, &name, - &ref_index, &parent_objectid); - /* - * parent object can change from one array -@@ -1438,15 +1429,13 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, - goto out; - } - } else { -- ret = ref_get_fields(eb, ref_ptr, &namelen, &name, -- &ref_index); -+ ret = ref_get_fields(eb, ref_ptr, &name, &ref_index); - } - if (ret) - goto out; - - ret = inode_in_dir(root, path, btrfs_ino(BTRFS_I(dir)), -- btrfs_ino(BTRFS_I(inode)), ref_index, -- name, namelen); -+ btrfs_ino(BTRFS_I(inode)), ref_index, &name); - if (ret < 0) { - goto out; - } else if (ret == 0) { -@@ -1460,7 +1449,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, - ret = __add_inode_ref(trans, root, path, log, - BTRFS_I(dir), BTRFS_I(inode), - inode_objectid, parent_objectid, -- ref_index, name, namelen); -+ ref_index, &name); - if (ret) { - if (ret == 1) - ret = 0; -@@ -1469,7 +1458,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, - - /* insert our name */ - ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), -- name, namelen, 0, ref_index); -+ &name, 0, ref_index); - if (ret) - goto out; - -@@ -1479,9 +1468,9 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, - } - /* Else, ret == 1, we already have a perfect match, we're done. */ - -- ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen; -- kfree(name); -- name = NULL; -+ ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + name.len; -+ kfree(name.name); -+ name.name = NULL; - if (log_ref_ver) { - iput(dir); - dir = NULL; -@@ -1505,7 +1494,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, - ret = overwrite_item(trans, root, path, eb, slot, key); - out: - btrfs_release_path(path); -- kfree(name); -+ kfree(name.name); - iput(dir); - iput(inode); - return ret; -@@ -1777,7 +1766,7 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, - static noinline int insert_one_name(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - u64 dirid, u64 index, -- char *name, int name_len, -+ const struct fscrypt_str *name, - struct btrfs_key *location) - { - struct inode *inode; -@@ -1795,7 +1784,7 @@ static noinline int insert_one_name(struct btrfs_trans_handle *trans, - } - - ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), name, -- name_len, 1, index); -+ 1, index); - - /* FIXME, put inode into FIXUP list */ - -@@ -1855,8 +1844,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, - struct btrfs_dir_item *di, - struct btrfs_key *key) - { -- char *name; -- int name_len; -+ struct fscrypt_str name; - struct btrfs_dir_item *dir_dst_di; - struct btrfs_dir_item *index_dst_di; - bool dir_dst_matches = false; -@@ -1874,17 +1862,11 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, - if (!dir) - return -EIO; - -- name_len = btrfs_dir_name_len(eb, di); -- name = kmalloc(name_len, GFP_NOFS); -- if (!name) { -- ret = -ENOMEM; -+ ret = read_alloc_one_name(eb, di + 1, btrfs_dir_name_len(eb, di), &name); -+ if (ret) - goto out; -- } - - log_type = btrfs_dir_type(eb, di); -- read_extent_buffer(eb, name, (unsigned long)(di + 1), -- name_len); -- - btrfs_dir_item_key_to_cpu(eb, di, &log_key); - ret = btrfs_lookup_inode(trans, root, path, &log_key, 0); - btrfs_release_path(path); -@@ -1894,7 +1876,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, - ret = 0; - - dir_dst_di = btrfs_lookup_dir_item(trans, root, path, key->objectid, -- name, name_len, 1); -+ &name, 1); - if (IS_ERR(dir_dst_di)) { - ret = PTR_ERR(dir_dst_di); - goto out; -@@ -1911,7 +1893,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, - - index_dst_di = btrfs_lookup_dir_index_item(trans, root, path, - key->objectid, key->offset, -- name, name_len, 1); -+ &name, 1); - if (IS_ERR(index_dst_di)) { - ret = PTR_ERR(index_dst_di); - goto out; -@@ -1939,7 +1921,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, - search_key.objectid = log_key.objectid; - search_key.type = BTRFS_INODE_REF_KEY; - search_key.offset = key->objectid; -- ret = backref_in_log(root->log_root, &search_key, 0, name, name_len); -+ ret = backref_in_log(root->log_root, &search_key, 0, &name); - if (ret < 0) { - goto out; - } else if (ret) { -@@ -1952,8 +1934,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, - search_key.objectid = log_key.objectid; - search_key.type = BTRFS_INODE_EXTREF_KEY; - search_key.offset = key->objectid; -- ret = backref_in_log(root->log_root, &search_key, key->objectid, name, -- name_len); -+ ret = backref_in_log(root->log_root, &search_key, key->objectid, &name); - if (ret < 0) { - goto out; - } else if (ret) { -@@ -1964,7 +1945,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, - } - btrfs_release_path(path); - ret = insert_one_name(trans, root, key->objectid, key->offset, -- name, name_len, &log_key); -+ &name, &log_key); - if (ret && ret != -ENOENT && ret != -EEXIST) - goto out; - if (!ret) -@@ -1974,10 +1955,10 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, - - out: - if (!ret && update_size) { -- btrfs_i_size_write(BTRFS_I(dir), dir->i_size + name_len * 2); -+ btrfs_i_size_write(BTRFS_I(dir), dir->i_size + name.len * 2); - ret = btrfs_update_inode(trans, root, BTRFS_I(dir)); - } -- kfree(name); -+ kfree(name.name); - iput(dir); - if (!ret && name_added) - ret = 1; -@@ -2143,8 +2124,7 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, - struct extent_buffer *eb; - int slot; - struct btrfs_dir_item *di; -- int name_len; -- char *name; -+ struct fscrypt_str name; - struct inode *inode = NULL; - struct btrfs_key location; - -@@ -2159,22 +2139,16 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, - eb = path->nodes[0]; - slot = path->slots[0]; - di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item); -- name_len = btrfs_dir_name_len(eb, di); -- name = kmalloc(name_len, GFP_NOFS); -- if (!name) { -- ret = -ENOMEM; -+ ret = read_alloc_one_name(eb, di + 1, btrfs_dir_name_len(eb, di), &name); -+ if (ret) - goto out; -- } -- -- read_extent_buffer(eb, name, (unsigned long)(di + 1), name_len); - - if (log) { - struct btrfs_dir_item *log_di; - - log_di = btrfs_lookup_dir_index_item(trans, log, log_path, - dir_key->objectid, -- dir_key->offset, -- name, name_len, 0); -+ dir_key->offset, &name, 0); - if (IS_ERR(log_di)) { - ret = PTR_ERR(log_di); - goto out; -@@ -2200,7 +2174,7 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, - - inc_nlink(inode); - ret = unlink_inode_for_log_replay(trans, BTRFS_I(dir), BTRFS_I(inode), -- name, name_len); -+ &name); - /* - * Unlike dir item keys, dir index keys can only have one name (entry) in - * them, as there are no key collisions since each key has a unique offset -@@ -2209,7 +2183,7 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, - out: - btrfs_release_path(path); - btrfs_release_path(log_path); -- kfree(name); -+ kfree(name.name); - iput(inode); - return ret; - } -@@ -3443,7 +3417,7 @@ static int del_logged_dentry(struct btrfs_trans_handle *trans, - struct btrfs_root *log, - struct btrfs_path *path, - u64 dir_ino, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - u64 index) - { - struct btrfs_dir_item *di; -@@ -3453,7 +3427,7 @@ static int del_logged_dentry(struct btrfs_trans_handle *trans, - * for dir item keys. - */ - di = btrfs_lookup_dir_index_item(trans, log, path, dir_ino, -- index, name, name_len, -1); -+ index, name, -1); - if (IS_ERR(di)) - return PTR_ERR(di); - else if (!di) -@@ -3490,7 +3464,7 @@ static int del_logged_dentry(struct btrfs_trans_handle *trans, - */ - void btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, - struct btrfs_root *root, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - struct btrfs_inode *dir, u64 index) - { - struct btrfs_path *path; -@@ -3517,7 +3491,7 @@ void btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, - } - - ret = del_logged_dentry(trans, root->log_root, path, btrfs_ino(dir), -- name, name_len, index); -+ name, index); - btrfs_free_path(path); - out_unlock: - mutex_unlock(&dir->log_mutex); -@@ -3529,7 +3503,7 @@ out_unlock: - /* see comments for btrfs_del_dir_entries_in_log */ - void btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, - struct btrfs_root *root, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - struct btrfs_inode *inode, u64 dirid) - { - struct btrfs_root *log; -@@ -3550,7 +3524,7 @@ void btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, - log = root->log_root; - mutex_lock(&inode->log_mutex); - -- ret = btrfs_del_inode_ref(trans, log, name, name_len, btrfs_ino(inode), -+ ret = btrfs_del_inode_ref(trans, log, name, btrfs_ino(inode), - dirid, &index); - mutex_unlock(&inode->log_mutex); - if (ret < 0 && ret != -ENOENT) -@@ -5293,6 +5267,7 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb, - u32 this_len; - unsigned long name_ptr; - struct btrfs_dir_item *di; -+ struct fscrypt_str name_str; - - if (key->type == BTRFS_INODE_REF_KEY) { - struct btrfs_inode_ref *iref; -@@ -5326,8 +5301,11 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb, - } - - read_extent_buffer(eb, name, name_ptr, this_name_len); -+ -+ name_str.name = name; -+ name_str.len = this_name_len; - di = btrfs_lookup_dir_item(NULL, inode->root, search_path, -- parent, name, this_name_len, 0); -+ parent, &name_str, 0); - if (di && !IS_ERR(di)) { - struct btrfs_key di_key; - -@@ -7493,9 +7471,14 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans, - if (old_dir && old_dir->logged_trans == trans->transid) { - struct btrfs_root *log = old_dir->root->log_root; - struct btrfs_path *path; -+ struct fscrypt_name fname; - - ASSERT(old_dir_index >= BTRFS_DIR_START_INDEX); - -+ ret = fscrypt_setup_filename(&old_dir->vfs_inode, -+ &old_dentry->d_name, 0, &fname); -+ if (ret) -+ goto out; - /* - * We have two inodes to update in the log, the old directory and - * the inode that got renamed, so we must pin the log to prevent -@@ -7508,13 +7491,17 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans, - * not fail, but if it does, it's not serious, just bail out and - * mark the log for a full commit. - */ -- if (WARN_ON_ONCE(ret < 0)) -+ if (WARN_ON_ONCE(ret < 0)) { -+ fscrypt_free_filename(&fname); - goto out; -+ } -+ - log_pinned = true; - - path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; -+ fscrypt_free_filename(&fname); - goto out; - } - -@@ -7530,8 +7517,7 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans, - */ - mutex_lock(&old_dir->log_mutex); - ret = del_logged_dentry(trans, log, path, btrfs_ino(old_dir), -- old_dentry->d_name.name, -- old_dentry->d_name.len, old_dir_index); -+ &fname.disk_name, old_dir_index); - if (ret > 0) { - /* - * The dentry does not exist in the log, so record its -@@ -7545,6 +7531,7 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans, - mutex_unlock(&old_dir->log_mutex); - - btrfs_free_path(path); -+ fscrypt_free_filename(&fname); - if (ret < 0) - goto out; - } -diff --git a/fs/btrfs/tree-log.h b/fs/btrfs/tree-log.h -index bcca74128c3bb..8adebf4c9adaf 100644 ---- a/fs/btrfs/tree-log.h -+++ b/fs/btrfs/tree-log.h -@@ -84,11 +84,11 @@ int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans, - struct btrfs_log_ctx *ctx); - void btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, - struct btrfs_root *root, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - struct btrfs_inode *dir, u64 index); - void btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, - struct btrfs_root *root, -- const char *name, int name_len, -+ const struct fscrypt_str *name, - struct btrfs_inode *inode, u64 dirid); - void btrfs_end_log_trans(struct btrfs_root *root); - void btrfs_pin_log_trans(struct btrfs_root *root); -diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c -index 5cd612a8f8584..49addc345aebe 100644 ---- a/fs/erofs/decompressor_lzma.c -+++ b/fs/erofs/decompressor_lzma.c -@@ -217,9 +217,12 @@ again: - strm->buf.out_size = min_t(u32, outlen, - PAGE_SIZE - pageofs); - outlen -= strm->buf.out_size; -- if (!rq->out[no] && rq->fillgaps) /* deduped */ -+ if (!rq->out[no] && rq->fillgaps) { /* deduped */ - rq->out[no] = erofs_allocpage(pagepool, - GFP_KERNEL | __GFP_NOFAIL); -+ set_page_private(rq->out[no], -+ Z_EROFS_SHORTLIVED_PAGE); -+ } - if (rq->out[no]) - strm->buf.out = kmap(rq->out[no]) + pageofs; - pageofs = 0; -diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index be570c65ae154..e1297c6bcfbe2 100644 ---- a/fs/nfs/nfs4proc.c -+++ b/fs/nfs/nfs4proc.c -@@ -7157,7 +7157,6 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata) - { - struct nfs4_lockdata *data = calldata; - struct nfs4_lock_state *lsp = data->lsp; -- struct nfs_server *server = NFS_SERVER(d_inode(data->ctx->dentry)); - - if (!nfs4_sequence_done(task, &data->res.seq_res)) - return; -@@ -7165,7 +7164,8 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata) - data->rpc_status = task->tk_status; - switch (task->tk_status) { - case 0: -- renew_lease(server, data->timestamp); -+ renew_lease(NFS_SERVER(d_inode(data->ctx->dentry)), -+ data->timestamp); - if (data->arg.new_lock && !data->cancelled) { - data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS); - if (locks_lock_inode_wait(lsp->ls_state->inode, &data->fl) < 0) -@@ -7193,8 +7193,6 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata) - if (!nfs4_stateid_match(&data->arg.open_stateid, - &lsp->ls_state->open_stateid)) - goto out_restart; -- else if (nfs4_async_handle_error(task, server, lsp->ls_state, NULL) == -EAGAIN) -- goto out_restart; - } else if (!nfs4_stateid_match(&data->arg.lock_stateid, - &lsp->ls_stateid)) - goto out_restart; -@@ -10629,7 +10627,9 @@ static void nfs4_disable_swap(struct inode *inode) - */ - struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; - -- nfs4_schedule_state_manager(clp); -+ set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); -+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); -+ wake_up_var(&clp->cl_state); - } - - static const struct inode_operations nfs4_dir_inode_operations = { -diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c -index 5b49e5365bb30..457b2b2f804ab 100644 ---- a/fs/nfs/nfs4state.c -+++ b/fs/nfs/nfs4state.c -@@ -1209,17 +1209,23 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) - { - struct task_struct *task; - char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1]; -- struct rpc_clnt *cl = clp->cl_rpcclient; -- -- while (cl != cl->cl_parent) -- cl = cl->cl_parent; -+ struct rpc_clnt *clnt = clp->cl_rpcclient; -+ bool swapon = false; - - set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); -- if (test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) != 0) { -- wake_up_var(&clp->cl_state); -- return; -+ -+ if (atomic_read(&clnt->cl_swapper)) { -+ swapon = !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, -+ &clp->cl_state); -+ if (!swapon) { -+ wake_up_var(&clp->cl_state); -+ return; -+ } - } -- set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); -+ -+ if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) -+ return; -+ - __module_get(THIS_MODULE); - refcount_inc(&clp->cl_count); - -@@ -1236,8 +1242,9 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) - __func__, PTR_ERR(task)); - if (!nfs_client_init_is_complete(clp)) - nfs_mark_client_ready(clp, PTR_ERR(task)); -+ if (swapon) -+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); - nfs4_clear_state_manager_bit(clp); -- clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); - nfs_put_client(clp); - module_put(THIS_MODULE); - } -@@ -2703,6 +2710,13 @@ static void nfs4_state_manager(struct nfs_client *clp) - nfs4_end_drain_session(clp); - nfs4_clear_state_manager_bit(clp); - -+ if (test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) && -+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, -+ &clp->cl_state)) { -+ memflags = memalloc_nofs_save(); -+ continue; -+ } -+ - if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) { - if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { - nfs_client_return_marked_delegations(clp); -@@ -2741,22 +2755,25 @@ static int nfs4_run_state_manager(void *ptr) - - allow_signal(SIGKILL); - again: -- set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); - nfs4_state_manager(clp); -- if (atomic_read(&cl->cl_swapper)) { -+ -+ if (test_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) && -+ !test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) { - wait_var_event_interruptible(&clp->cl_state, - test_bit(NFS4CLNT_RUN_MANAGER, - &clp->cl_state)); -- if (atomic_read(&cl->cl_swapper) && -- test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state)) -+ if (!atomic_read(&cl->cl_swapper)) -+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); -+ if (refcount_read(&clp->cl_count) > 1 && !signalled() && -+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) - goto again; - /* Either no longer a swapper, or were signalled */ -+ clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); - } -- clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); - - if (refcount_read(&clp->cl_count) > 1 && !signalled() && - test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) && -- !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state)) -+ !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) - goto again; - - nfs_put_client(clp); -diff --git a/fs/nfs/sysfs.c b/fs/nfs/sysfs.c -index a6f7403669631..edb535a0ff973 100644 ---- a/fs/nfs/sysfs.c -+++ b/fs/nfs/sysfs.c -@@ -18,7 +18,7 @@ - #include "sysfs.h" - - struct kobject *nfs_client_kobj; --static struct kset *nfs_client_kset; -+static struct kset *nfs_kset; - - static void nfs_netns_object_release(struct kobject *kobj) - { -@@ -55,13 +55,13 @@ static struct kobject *nfs_netns_object_alloc(const char *name, - - int nfs_sysfs_init(void) - { -- nfs_client_kset = kset_create_and_add("nfs", NULL, fs_kobj); -- if (!nfs_client_kset) -+ nfs_kset = kset_create_and_add("nfs", NULL, fs_kobj); -+ if (!nfs_kset) - return -ENOMEM; -- nfs_client_kobj = nfs_netns_object_alloc("net", nfs_client_kset, NULL); -+ nfs_client_kobj = nfs_netns_object_alloc("net", nfs_kset, NULL); - if (!nfs_client_kobj) { -- kset_unregister(nfs_client_kset); -- nfs_client_kset = NULL; -+ kset_unregister(nfs_kset); -+ nfs_kset = NULL; - return -ENOMEM; - } - return 0; -@@ -70,7 +70,7 @@ int nfs_sysfs_init(void) - void nfs_sysfs_exit(void) - { - kobject_put(nfs_client_kobj); -- kset_unregister(nfs_client_kset); -+ kset_unregister(nfs_kset); - } - - static ssize_t nfs_netns_identifier_show(struct kobject *kobj, -@@ -159,7 +159,7 @@ static struct nfs_netns_client *nfs_netns_client_alloc(struct kobject *parent, - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (p) { - p->net = net; -- p->kobject.kset = nfs_client_kset; -+ p->kobject.kset = nfs_kset; - if (kobject_init_and_add(&p->kobject, &nfs_netns_client_type, - parent, "nfs_client") == 0) - return p; -diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c -index 57da4f23c1e43..acb8951eb7576 100644 ---- a/fs/smb/client/connect.c -+++ b/fs/smb/client/connect.c -@@ -2901,9 +2901,9 @@ bind_socket(struct TCP_Server_Info *server) - if (server->srcaddr.ss_family != AF_UNSPEC) { - /* Bind to the specified local IP address */ - struct socket *socket = server->ssocket; -- rc = socket->ops->bind(socket, -- (struct sockaddr *) &server->srcaddr, -- sizeof(server->srcaddr)); -+ rc = kernel_bind(socket, -+ (struct sockaddr *) &server->srcaddr, -+ sizeof(server->srcaddr)); - if (rc < 0) { - struct sockaddr_in *saddr4; - struct sockaddr_in6 *saddr6; -@@ -3050,8 +3050,8 @@ generic_ip_connect(struct TCP_Server_Info *server) - socket->sk->sk_sndbuf, - socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); - -- rc = socket->ops->connect(socket, saddr, slen, -- server->noblockcnt ? O_NONBLOCK : 0); -+ rc = kernel_connect(socket, saddr, slen, -+ server->noblockcnt ? O_NONBLOCK : 0); - /* - * When mounting SMB root file systems, we do not want to block in - * connect. Otherwise bail out and then let cifs_reconnect() perform -diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c -index e1d2be19cddfa..ff97cad8d5b45 100644 ---- a/fs/smb/server/connection.c -+++ b/fs/smb/server/connection.c -@@ -84,6 +84,8 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) - spin_lock_init(&conn->llist_lock); - INIT_LIST_HEAD(&conn->lock_list); - -+ init_rwsem(&conn->session_lock); -+ - down_write(&conn_list_lock); - list_add(&conn->conns_list, &conn_list); - up_write(&conn_list_lock); -diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h -index ad8dfaa48ffb3..335fdd714d595 100644 ---- a/fs/smb/server/connection.h -+++ b/fs/smb/server/connection.h -@@ -50,6 +50,7 @@ struct ksmbd_conn { - struct nls_table *local_nls; - struct unicode_map *um; - struct list_head conns_list; -+ struct rw_semaphore session_lock; - /* smb session 1 per user */ - struct xarray sessions; - unsigned long last_active; -diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c -index ea4b56d570fbb..cf6621e21ba36 100644 ---- a/fs/smb/server/mgmt/user_session.c -+++ b/fs/smb/server/mgmt/user_session.c -@@ -183,7 +183,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn) - unsigned long id; - struct ksmbd_session *sess; - -- down_write(&sessions_table_lock); -+ down_write(&conn->session_lock); - xa_for_each(&conn->sessions, id, sess) { - if (sess->state != SMB2_SESSION_VALID || - time_after(jiffies, -@@ -194,7 +194,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn) - continue; - } - } -- up_write(&sessions_table_lock); -+ up_write(&conn->session_lock); - } - - int ksmbd_session_register(struct ksmbd_conn *conn, -@@ -236,7 +236,9 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn) - } - } - } -+ up_write(&sessions_table_lock); - -+ down_write(&conn->session_lock); - xa_for_each(&conn->sessions, id, sess) { - unsigned long chann_id; - struct channel *chann; -@@ -253,7 +255,7 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn) - ksmbd_session_destroy(sess); - } - } -- up_write(&sessions_table_lock); -+ up_write(&conn->session_lock); - } - - struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, -@@ -261,9 +263,11 @@ struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, - { - struct ksmbd_session *sess; - -+ down_read(&conn->session_lock); - sess = xa_load(&conn->sessions, id); - if (sess) - sess->last_active = jiffies; -+ up_read(&conn->session_lock); - return sess; - } - -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index f6fd5cf976a50..683152007566c 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -8128,10 +8128,10 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) - goto err_out; - } - -- opinfo_put(opinfo); -- ksmbd_fd_put(work, fp); - opinfo->op_state = OPLOCK_STATE_NONE; - wake_up_interruptible_all(&opinfo->oplock_q); -+ opinfo_put(opinfo); -+ ksmbd_fd_put(work, fp); - - rsp->StructureSize = cpu_to_le16(24); - rsp->OplockLevel = rsp_oplevel; -diff --git a/include/linux/bpf.h b/include/linux/bpf.h -index 1ed2ec035e779..1fba826f0acef 100644 ---- a/include/linux/bpf.h -+++ b/include/linux/bpf.h -@@ -1065,7 +1065,7 @@ static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, - static inline struct bpf_trampoline *bpf_trampoline_get(u64 key, - struct bpf_attach_target_info *tgt_info) - { -- return ERR_PTR(-EOPNOTSUPP); -+ return NULL; - } - static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {} - #define DEFINE_BPF_DISPATCHER(name) -diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h -index 15d7529ac9534..9a44de45cc1f2 100644 ---- a/include/linux/ipv6.h -+++ b/include/linux/ipv6.h -@@ -33,6 +33,7 @@ struct ipv6_devconf { - __s32 accept_ra_defrtr; - __u32 ra_defrtr_metric; - __s32 accept_ra_min_hop_limit; -+ __s32 accept_ra_min_lft; - __s32 accept_ra_pinfo; - __s32 ignore_routes_with_linkdown; - #ifdef CONFIG_IPV6_ROUTER_PREF -diff --git a/include/linux/mm.h b/include/linux/mm.h -index 104ec00823da8..eefb0948110ae 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1906,6 +1906,8 @@ static inline bool can_do_mlock(void) { return false; } - extern int user_shm_lock(size_t, struct ucounts *); - extern void user_shm_unlock(size_t, struct ucounts *); - -+struct folio *vm_normal_folio(struct vm_area_struct *vma, unsigned long addr, -+ pte_t pte); - struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, - pte_t pte); - struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, -diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/linux/netfilter/nf_conntrack_sctp.h -index 625f491b95de8..fb31312825ae5 100644 ---- a/include/linux/netfilter/nf_conntrack_sctp.h -+++ b/include/linux/netfilter/nf_conntrack_sctp.h -@@ -9,6 +9,7 @@ struct ip_ct_sctp { - enum sctp_conntrack state; - - __be32 vtag[IP_CT_DIR_MAX]; -+ u8 init[IP_CT_DIR_MAX]; - u8 last_dir; - u8 flags; - }; -diff --git a/include/linux/regulator/mt6358-regulator.h b/include/linux/regulator/mt6358-regulator.h -index bdcf83cd719ef..be9f61e3e8e6d 100644 ---- a/include/linux/regulator/mt6358-regulator.h -+++ b/include/linux/regulator/mt6358-regulator.h -@@ -48,8 +48,6 @@ enum { - MT6358_ID_VLDO28, - MT6358_ID_VAUD28, - MT6358_ID_VSIM2, -- MT6358_ID_VCORE_SSHUB, -- MT6358_ID_VSRAM_OTHERS_SSHUB, - MT6358_ID_RG_MAX, - }; - -@@ -90,8 +88,6 @@ enum { - MT6366_ID_VMC, - MT6366_ID_VAUD28, - MT6366_ID_VSIM2, -- MT6366_ID_VCORE_SSHUB, -- MT6366_ID_VSRAM_OTHERS_SSHUB, - MT6366_ID_RG_MAX, - }; - -diff --git a/include/net/arp.h b/include/net/arp.h -index d7ef4ec71dfeb..e8747e0713c79 100644 ---- a/include/net/arp.h -+++ b/include/net/arp.h -@@ -38,11 +38,11 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 - { - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - n = __ipv4_neigh_lookup_noref(dev, key); - if (n && !refcount_inc_not_zero(&n->refcnt)) - n = NULL; -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - return n; - } -@@ -51,10 +51,10 @@ static inline void __ipv4_confirm_neigh(struct net_device *dev, u32 key) - { - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - n = __ipv4_neigh_lookup_noref(dev, key); - neigh_confirm(n); -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - } - - void arp_init(void); -diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h -index 5976545aa26b9..7a6c3059d50b5 100644 ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -5621,12 +5621,17 @@ struct cfg80211_cqm_config; - * wiphy_lock - lock the wiphy - * @wiphy: the wiphy to lock - * -- * This is mostly exposed so it can be done around registering and -- * unregistering netdevs that aren't created through cfg80211 calls, -- * since that requires locking in cfg80211 when the notifiers is -- * called, but that cannot differentiate which way it's called. -+ * This is needed around registering and unregistering netdevs that -+ * aren't created through cfg80211 calls, since that requires locking -+ * in cfg80211 when the notifiers is called, but that cannot -+ * differentiate which way it's called. -+ * -+ * It can also be used by drivers for their own purposes. - * - * When cfg80211 ops are called, the wiphy is already locked. -+ * -+ * Note that this makes sure that no workers that have been queued -+ * with wiphy_queue_work() are running. - */ - static inline void wiphy_lock(struct wiphy *wiphy) - __acquires(&wiphy->mtx) -@@ -5646,6 +5651,88 @@ static inline void wiphy_unlock(struct wiphy *wiphy) - mutex_unlock(&wiphy->mtx); - } - -+struct wiphy_work; -+typedef void (*wiphy_work_func_t)(struct wiphy *, struct wiphy_work *); -+ -+struct wiphy_work { -+ struct list_head entry; -+ wiphy_work_func_t func; -+}; -+ -+static inline void wiphy_work_init(struct wiphy_work *work, -+ wiphy_work_func_t func) -+{ -+ INIT_LIST_HEAD(&work->entry); -+ work->func = func; -+} -+ -+/** -+ * wiphy_work_queue - queue work for the wiphy -+ * @wiphy: the wiphy to queue for -+ * @work: the work item -+ * -+ * This is useful for work that must be done asynchronously, and work -+ * queued here has the special property that the wiphy mutex will be -+ * held as if wiphy_lock() was called, and that it cannot be running -+ * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can -+ * use just cancel_work() instead of cancel_work_sync(), it requires -+ * being in a section protected by wiphy_lock(). -+ */ -+void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work); -+ -+/** -+ * wiphy_work_cancel - cancel previously queued work -+ * @wiphy: the wiphy, for debug purposes -+ * @work: the work to cancel -+ * -+ * Cancel the work *without* waiting for it, this assumes being -+ * called under the wiphy mutex acquired by wiphy_lock(). -+ */ -+void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work); -+ -+struct wiphy_delayed_work { -+ struct wiphy_work work; -+ struct wiphy *wiphy; -+ struct timer_list timer; -+}; -+ -+void wiphy_delayed_work_timer(struct timer_list *t); -+ -+static inline void wiphy_delayed_work_init(struct wiphy_delayed_work *dwork, -+ wiphy_work_func_t func) -+{ -+ timer_setup(&dwork->timer, wiphy_delayed_work_timer, 0); -+ wiphy_work_init(&dwork->work, func); -+} -+ -+/** -+ * wiphy_delayed_work_queue - queue delayed work for the wiphy -+ * @wiphy: the wiphy to queue for -+ * @dwork: the delayable worker -+ * @delay: number of jiffies to wait before queueing -+ * -+ * This is useful for work that must be done asynchronously, and work -+ * queued here has the special property that the wiphy mutex will be -+ * held as if wiphy_lock() was called, and that it cannot be running -+ * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can -+ * use just cancel_work() instead of cancel_work_sync(), it requires -+ * being in a section protected by wiphy_lock(). -+ */ -+void wiphy_delayed_work_queue(struct wiphy *wiphy, -+ struct wiphy_delayed_work *dwork, -+ unsigned long delay); -+ -+/** -+ * wiphy_delayed_work_cancel - cancel previously queued delayed work -+ * @wiphy: the wiphy, for debug purposes -+ * @dwork: the delayed work to cancel -+ * -+ * Cancel the work *without* waiting for it, this assumes being -+ * called under the wiphy mutex acquired by wiphy_lock(). -+ */ -+void wiphy_delayed_work_cancel(struct wiphy *wiphy, -+ struct wiphy_delayed_work *dwork); -+ - /** - * struct wireless_dev - wireless device state - * -@@ -5718,6 +5805,7 @@ static inline void wiphy_unlock(struct wiphy *wiphy) - * @event_lock: (private) lock for event list - * @owner_nlportid: (private) owner socket port ID - * @nl_owner_dead: (private) owner socket went away -+ * @cqm_rssi_work: (private) CQM RSSI reporting work - * @cqm_config: (private) nl80211 RSSI monitor state - * @pmsr_list: (private) peer measurement requests - * @pmsr_lock: (private) peer measurements requests/results lock -@@ -5790,7 +5878,8 @@ struct wireless_dev { - } wext; - #endif - -- struct cfg80211_cqm_config *cqm_config; -+ struct wiphy_work cqm_rssi_work; -+ struct cfg80211_cqm_config __rcu *cqm_config; - - struct list_head pmsr_list; - spinlock_t pmsr_lock; -diff --git a/include/net/ndisc.h b/include/net/ndisc.h -index da7eec8669ec4..325a6fb65c896 100644 ---- a/include/net/ndisc.h -+++ b/include/net/ndisc.h -@@ -395,11 +395,11 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons - { - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - n = __ipv6_neigh_lookup_noref(dev, pkey); - if (n && !refcount_inc_not_zero(&n->refcnt)) - n = NULL; -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - return n; - } -@@ -409,10 +409,10 @@ static inline void __ipv6_confirm_neigh(struct net_device *dev, - { - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - n = __ipv6_neigh_lookup_noref(dev, pkey); - neigh_confirm(n); -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - } - - static inline void __ipv6_confirm_neigh_stub(struct net_device *dev, -@@ -420,10 +420,10 @@ static inline void __ipv6_confirm_neigh_stub(struct net_device *dev, - { - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - n = __ipv6_neigh_lookup_noref_stub(dev, pkey); - neigh_confirm(n); -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - } - - /* uses ipv6_stub and is meant for use outside of IPv6 core */ -diff --git a/include/net/neighbour.h b/include/net/neighbour.h -index 794e45981891a..ccc4a0f8b4ad8 100644 ---- a/include/net/neighbour.h -+++ b/include/net/neighbour.h -@@ -299,14 +299,14 @@ static inline struct neighbour *___neigh_lookup_noref( - const void *pkey, - struct net_device *dev) - { -- struct neigh_hash_table *nht = rcu_dereference_bh(tbl->nht); -+ struct neigh_hash_table *nht = rcu_dereference(tbl->nht); - struct neighbour *n; - u32 hash_val; - - hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); -- for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); -+ for (n = rcu_dereference(nht->hash_buckets[hash_val]); - n != NULL; -- n = rcu_dereference_bh(n->next)) { -+ n = rcu_dereference(n->next)) { - if (n->dev == dev && key_eq(n, pkey)) - return n; - } -@@ -464,7 +464,7 @@ static __always_inline int neigh_event_send_probe(struct neighbour *neigh, - - if (READ_ONCE(neigh->used) != now) - WRITE_ONCE(neigh->used, now); -- if (!(neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))) -+ if (!(READ_ONCE(neigh->nud_state) & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))) - return __neigh_event_send(neigh, skb, immediate_ok); - return 0; - } -@@ -541,7 +541,7 @@ static inline int neigh_output(struct neighbour *n, struct sk_buff *skb, - READ_ONCE(hh->hh_len)) - return neigh_hh_output(hh, skb); - -- return n->output(n, skb); -+ return READ_ONCE(n->output)(n, skb); - } - - static inline struct neighbour * -diff --git a/include/net/netlink.h b/include/net/netlink.h -index 6bfa972f2fbf2..a686c9041ddc0 100644 ---- a/include/net/netlink.h -+++ b/include/net/netlink.h -@@ -937,6 +937,27 @@ static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 se - return __nlmsg_put(skb, portid, seq, type, payload, flags); - } - -+/** -+ * nlmsg_append - Add more data to a nlmsg in a skb -+ * @skb: socket buffer to store message in -+ * @size: length of message payload -+ * -+ * Append data to an existing nlmsg, used when constructing a message -+ * with multiple fixed-format headers (which is rare). -+ * Returns NULL if the tailroom of the skb is insufficient to store -+ * the extra payload. -+ */ -+static inline void *nlmsg_append(struct sk_buff *skb, u32 size) -+{ -+ if (unlikely(skb_tailroom(skb) < NLMSG_ALIGN(size))) -+ return NULL; -+ -+ if (NLMSG_ALIGN(size) - size) -+ memset(skb_tail_pointer(skb) + size, 0, -+ NLMSG_ALIGN(size) - size); -+ return __skb_put(skb, NLMSG_ALIGN(size)); -+} -+ - /** - * nlmsg_put_answer - Add a new callback based netlink message to an skb - * @skb: socket buffer to store message in -diff --git a/include/net/nexthop.h b/include/net/nexthop.h -index 28085b995ddcf..2b12725de9c09 100644 ---- a/include/net/nexthop.h -+++ b/include/net/nexthop.h -@@ -497,29 +497,6 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) - return NULL; - } - --/* Variant of nexthop_fib6_nh(). -- * Caller should either hold rcu_read_lock_bh(), or RTNL. -- */ --static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh) --{ -- struct nh_info *nhi; -- -- if (nh->is_group) { -- struct nh_group *nh_grp; -- -- nh_grp = rcu_dereference_bh_rtnl(nh->nh_grp); -- nh = nexthop_mpath_select(nh_grp, 0); -- if (!nh) -- return NULL; -- } -- -- nhi = rcu_dereference_bh_rtnl(nh->nh_info); -- if (nhi->family == AF_INET6) -- return &nhi->fib6_nh; -- -- return NULL; --} -- - static inline struct net_device *fib6_info_nh_dev(struct fib6_info *f6i) - { - struct fib6_nh *fib6_nh; -diff --git a/include/net/tcp.h b/include/net/tcp.h -index 5fd69f2342a44..9ebb54122bb71 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -355,12 +355,14 @@ ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, - struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp, - bool force_schedule); - --static inline void tcp_dec_quickack_mode(struct sock *sk, -- const unsigned int pkts) -+static inline void tcp_dec_quickack_mode(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - - if (icsk->icsk_ack.quick) { -+ /* How many ACKs S/ACKing new data have we sent? */ -+ const unsigned int pkts = inet_csk_ack_scheduled(sk) ? 1 : 0; -+ - if (pkts >= icsk->icsk_ack.quick) { - icsk->icsk_ack.quick = 0; - /* Leaving quickack mode we deflate ATO. */ -diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h -index 006858ed04e8c..dc2cff18b68bd 100644 ---- a/include/scsi/scsi_device.h -+++ b/include/scsi/scsi_device.h -@@ -161,6 +161,10 @@ struct scsi_device { - * pass settings from slave_alloc to scsi - * core. */ - unsigned int eh_timeout; /* Error handling timeout */ -+ -+ bool manage_system_start_stop; /* Let HLD (sd) manage system start/stop */ -+ bool manage_runtime_start_stop; /* Let HLD (sd) manage runtime start/stop */ -+ - unsigned removable:1; - unsigned changed:1; /* Data invalid due to media change */ - unsigned busy:1; /* Used to prevent races */ -@@ -192,7 +196,7 @@ struct scsi_device { - unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ - unsigned no_start_on_add:1; /* do not issue start on add */ - unsigned allow_restart:1; /* issue START_UNIT in error handler */ -- unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ -+ unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */ - unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ - unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ - unsigned select_no_atn:1; -diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h -index d27d9fb7174c8..71def41b1ad78 100644 ---- a/include/scsi/scsi_host.h -+++ b/include/scsi/scsi_host.h -@@ -752,7 +752,7 @@ extern int __must_check scsi_add_host_with_dma(struct Scsi_Host *, - struct device *, - struct device *); - extern void scsi_scan_host(struct Scsi_Host *); --extern void scsi_rescan_device(struct device *); -+extern int scsi_rescan_device(struct scsi_device *sdev); - extern void scsi_remove_host(struct Scsi_Host *); - extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); - extern int scsi_host_busy(struct Scsi_Host *shost); -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index 53bc487947197..92dbe89dafbf5 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -3112,6 +3112,11 @@ union bpf_attr { - * **BPF_FIB_LOOKUP_OUTPUT** - * Perform lookup from an egress perspective (default is - * ingress). -+ * **BPF_FIB_LOOKUP_SKIP_NEIGH** -+ * Skip the neighbour table lookup. *params*->dmac -+ * and *params*->smac will not be set as output. A common -+ * use case is to call **bpf_redirect_neigh**\ () after -+ * doing **bpf_fib_lookup**\ (). - * - * *ctx* is either **struct xdp_md** for XDP programs or - * **struct sk_buff** tc cls_act programs. -@@ -6678,6 +6683,7 @@ struct bpf_raw_tracepoint_args { - enum { - BPF_FIB_LOOKUP_DIRECT = (1U << 0), - BPF_FIB_LOOKUP_OUTPUT = (1U << 1), -+ BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2), - }; - - enum { -diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h -index 53326dfc59ecb..4fa8511b1e355 100644 ---- a/include/uapi/linux/ipv6.h -+++ b/include/uapi/linux/ipv6.h -@@ -198,6 +198,7 @@ enum { - DEVCONF_IOAM6_ID_WIDE, - DEVCONF_NDISC_EVICT_NOCARRIER, - DEVCONF_ACCEPT_UNTRACKED_NA, -+ DEVCONF_ACCEPT_RA_MIN_LFT, - DEVCONF_MAX - }; - -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index 2f562cf961e0a..b7383358c4ea1 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -354,10 +354,11 @@ static void rb_init_page(struct buffer_data_page *bpage) - local_set(&bpage->commit, 0); - } - --/* -- * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing -- * this issue out. -- */ -+static __always_inline unsigned int rb_page_commit(struct buffer_page *bpage) -+{ -+ return local_read(&bpage->page->commit); -+} -+ - static void free_buffer_page(struct buffer_page *bpage) - { - free_page((unsigned long)bpage->page); -@@ -2024,7 +2025,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) - * Increment overrun to account for the lost events. - */ - local_add(page_entries, &cpu_buffer->overrun); -- local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); -+ local_sub(rb_page_commit(to_remove_page), &cpu_buffer->entries_bytes); - local_inc(&cpu_buffer->pages_lost); - } - -@@ -2368,11 +2369,6 @@ rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer) - cpu_buffer->reader_page->read); - } - --static __always_inline unsigned rb_page_commit(struct buffer_page *bpage) --{ -- return local_read(&bpage->page->commit); --} -- - static struct ring_buffer_event * - rb_iter_head_event(struct ring_buffer_iter *iter) - { -@@ -2518,7 +2514,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer, - * the counters. - */ - local_add(entries, &cpu_buffer->overrun); -- local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); -+ local_sub(rb_page_commit(next_page), &cpu_buffer->entries_bytes); - local_inc(&cpu_buffer->pages_lost); - - /* -@@ -2661,9 +2657,6 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, - - event = __rb_page_index(tail_page, tail); - -- /* account for padding bytes */ -- local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); -- - /* - * Save the original length to the meta data. - * This will be used by the reader to add lost event -@@ -2677,7 +2670,8 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, - * write counter enough to allow another writer to slip - * in on this page. - * We put in a discarded commit instead, to make sure -- * that this space is not used again. -+ * that this space is not used again, and this space will -+ * not be accounted into 'entries_bytes'. - * - * If we are less than the minimum size, we don't need to - * worry about it. -@@ -2702,6 +2696,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, - /* time delta must be non zero */ - event->time_delta = 1; - -+ /* account for padding bytes */ -+ local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); -+ - /* Make sure the padding is visible before the tail_page->write update */ - smp_wmb(); - -@@ -4219,7 +4216,7 @@ u64 ring_buffer_oldest_event_ts(struct trace_buffer *buffer, int cpu) - EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts); - - /** -- * ring_buffer_bytes_cpu - get the number of bytes consumed in a cpu buffer -+ * ring_buffer_bytes_cpu - get the number of bytes unconsumed in a cpu buffer - * @buffer: The ring buffer - * @cpu: The per CPU buffer to read from. - */ -@@ -4729,6 +4726,7 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer) - - length = rb_event_length(event); - cpu_buffer->reader_page->read += length; -+ cpu_buffer->read_bytes += length; - } - - static void rb_advance_iter(struct ring_buffer_iter *iter) -@@ -5824,7 +5822,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer, - } else { - /* update the entry counter */ - cpu_buffer->read += rb_page_entries(reader); -- cpu_buffer->read_bytes += BUF_PAGE_SIZE; -+ cpu_buffer->read_bytes += rb_page_commit(reader); - - /* swap the pages */ - rb_init_page(bpage); -diff --git a/mm/memory.c b/mm/memory.c -index 2083078cd0615..0d1b3ee8fcd7a 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -672,6 +672,16 @@ out: - return pfn_to_page(pfn); - } - -+struct folio *vm_normal_folio(struct vm_area_struct *vma, unsigned long addr, -+ pte_t pte) -+{ -+ struct page *page = vm_normal_page(vma, addr, pte); -+ -+ if (page) -+ return page_folio(page); -+ return NULL; -+} -+ - #ifdef CONFIG_TRANSPARENT_HUGEPAGE - struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, - pmd_t pmd) -diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index 7d36dd95d1fff..bfe2d1d50fbee 100644 ---- a/mm/mempolicy.c -+++ b/mm/mempolicy.c -@@ -414,7 +414,7 @@ static const struct mempolicy_operations mpol_ops[MPOL_MAX] = { - }, - }; - --static int migrate_page_add(struct page *page, struct list_head *pagelist, -+static int migrate_folio_add(struct folio *folio, struct list_head *foliolist, - unsigned long flags); - - struct queue_pages { -@@ -424,6 +424,7 @@ struct queue_pages { - unsigned long start; - unsigned long end; - struct vm_area_struct *first; -+ bool has_unmovable; - }; - - /* -@@ -442,21 +443,20 @@ static inline bool queue_pages_required(struct page *page, - } - - /* -- * queue_pages_pmd() has three possible return values: -- * 0 - pages are placed on the right node or queued successfully, or -- * special page is met, i.e. huge zero page. -- * 1 - there is unmovable page, and MPOL_MF_MOVE* & MPOL_MF_STRICT were -- * specified. -+ * queue_folios_pmd() has three possible return values: -+ * 0 - folios are placed on the right node or queued successfully, or -+ * special page is met, i.e. zero page, or unmovable page is found -+ * but continue walking (indicated by queue_pages.has_unmovable). - * -EIO - is migration entry or only MPOL_MF_STRICT was specified and an -- * existing page was already on a node that does not follow the -+ * existing folio was already on a node that does not follow the - * policy. - */ --static int queue_pages_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, -+static int queue_folios_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, - unsigned long end, struct mm_walk *walk) - __releases(ptl) - { - int ret = 0; -- struct page *page; -+ struct folio *folio; - struct queue_pages *qp = walk->private; - unsigned long flags; - -@@ -464,20 +464,20 @@ static int queue_pages_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, - ret = -EIO; - goto unlock; - } -- page = pmd_page(*pmd); -- if (is_huge_zero_page(page)) { -+ folio = pfn_folio(pmd_pfn(*pmd)); -+ if (is_huge_zero_page(&folio->page)) { - walk->action = ACTION_CONTINUE; - goto unlock; - } -- if (!queue_pages_required(page, qp)) -+ if (!queue_pages_required(&folio->page, qp)) - goto unlock; - - flags = qp->flags; -- /* go to thp migration */ -+ /* go to folio migration */ - if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { - if (!vma_migratable(walk->vma) || -- migrate_page_add(page, qp->pagelist, flags)) { -- ret = 1; -+ migrate_folio_add(folio, qp->pagelist, flags)) { -+ qp->has_unmovable = true; - goto unlock; - } - } else -@@ -491,28 +491,26 @@ unlock: - * Scan through pages checking if pages follow certain conditions, - * and move them to the pagelist if they do. - * -- * queue_pages_pte_range() has three possible return values: -- * 0 - pages are placed on the right node or queued successfully, or -- * special page is met, i.e. zero page. -- * 1 - there is unmovable page, and MPOL_MF_MOVE* & MPOL_MF_STRICT were -- * specified. -- * -EIO - only MPOL_MF_STRICT was specified and an existing page was already -+ * queue_folios_pte_range() has three possible return values: -+ * 0 - folios are placed on the right node or queued successfully, or -+ * special page is met, i.e. zero page, or unmovable page is found -+ * but continue walking (indicated by queue_pages.has_unmovable). -+ * -EIO - only MPOL_MF_STRICT was specified and an existing folio was already - * on a node that does not follow the policy. - */ --static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, -+static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, struct mm_walk *walk) - { - struct vm_area_struct *vma = walk->vma; -- struct page *page; -+ struct folio *folio; - struct queue_pages *qp = walk->private; - unsigned long flags = qp->flags; -- bool has_unmovable = false; - pte_t *pte, *mapped_pte; - spinlock_t *ptl; - - ptl = pmd_trans_huge_lock(pmd, vma); - if (ptl) -- return queue_pages_pmd(pmd, ptl, addr, end, walk); -+ return queue_folios_pmd(pmd, ptl, addr, end, walk); - - if (pmd_trans_unstable(pmd)) - return 0; -@@ -521,40 +519,38 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, - for (; addr != end; pte++, addr += PAGE_SIZE) { - if (!pte_present(*pte)) - continue; -- page = vm_normal_page(vma, addr, *pte); -- if (!page || is_zone_device_page(page)) -+ folio = vm_normal_folio(vma, addr, *pte); -+ if (!folio || folio_is_zone_device(folio)) - continue; - /* -- * vm_normal_page() filters out zero pages, but there might -- * still be PageReserved pages to skip, perhaps in a VDSO. -+ * vm_normal_folio() filters out zero pages, but there might -+ * still be reserved folios to skip, perhaps in a VDSO. - */ -- if (PageReserved(page)) -+ if (folio_test_reserved(folio)) - continue; -- if (!queue_pages_required(page, qp)) -+ if (!queue_pages_required(&folio->page, qp)) - continue; - if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { -- /* MPOL_MF_STRICT must be specified if we get here */ -- if (!vma_migratable(vma)) { -- has_unmovable = true; -- break; -- } -+ /* -+ * MPOL_MF_STRICT must be specified if we get here. -+ * Continue walking vmas due to MPOL_MF_MOVE* flags. -+ */ -+ if (!vma_migratable(vma)) -+ qp->has_unmovable = true; - - /* - * Do not abort immediately since there may be - * temporary off LRU pages in the range. Still - * need migrate other LRU pages. - */ -- if (migrate_page_add(page, qp->pagelist, flags)) -- has_unmovable = true; -+ if (migrate_folio_add(folio, qp->pagelist, flags)) -+ qp->has_unmovable = true; - } else - break; - } - pte_unmap_unlock(mapped_pte, ptl); - cond_resched(); - -- if (has_unmovable) -- return 1; -- - return addr != end ? -EIO : 0; - } - -@@ -594,7 +590,7 @@ static int queue_pages_hugetlb(pte_t *pte, unsigned long hmask, - * Detecting misplaced page but allow migrating pages which - * have been queued. - */ -- ret = 1; -+ qp->has_unmovable = true; - goto unlock; - } - -@@ -608,7 +604,7 @@ static int queue_pages_hugetlb(pte_t *pte, unsigned long hmask, - * Failed to isolate page but allow migrating pages - * which have been queued. - */ -- ret = 1; -+ qp->has_unmovable = true; - } - unlock: - spin_unlock(ptl); -@@ -705,7 +701,7 @@ static int queue_pages_test_walk(unsigned long start, unsigned long end, - - static const struct mm_walk_ops queue_pages_walk_ops = { - .hugetlb_entry = queue_pages_hugetlb, -- .pmd_entry = queue_pages_pte_range, -+ .pmd_entry = queue_folios_pte_range, - .test_walk = queue_pages_test_walk, - }; - -@@ -737,10 +733,13 @@ queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end, - .start = start, - .end = end, - .first = NULL, -+ .has_unmovable = false, - }; - - err = walk_page_range(mm, start, end, &queue_pages_walk_ops, &qp); - -+ if (qp.has_unmovable) -+ err = 1; - if (!qp.first) - /* whole range in hole */ - err = -EFAULT; -@@ -1012,27 +1011,28 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, - } - - #ifdef CONFIG_MIGRATION --/* -- * page migration, thp tail pages can be passed. -- */ --static int migrate_page_add(struct page *page, struct list_head *pagelist, -+static int migrate_folio_add(struct folio *folio, struct list_head *foliolist, - unsigned long flags) - { -- struct page *head = compound_head(page); - /* -- * Avoid migrating a page that is shared with others. -+ * We try to migrate only unshared folios. If it is shared it -+ * is likely not worth migrating. -+ * -+ * To check if the folio is shared, ideally we want to make sure -+ * every page is mapped to the same process. Doing that is very -+ * expensive, so check the estimated mapcount of the folio instead. - */ -- if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(head) == 1) { -- if (!isolate_lru_page(head)) { -- list_add_tail(&head->lru, pagelist); -- mod_node_page_state(page_pgdat(head), -- NR_ISOLATED_ANON + page_is_file_lru(head), -- thp_nr_pages(head)); -+ if ((flags & MPOL_MF_MOVE_ALL) || folio_estimated_sharers(folio) == 1) { -+ if (!folio_isolate_lru(folio)) { -+ list_add_tail(&folio->lru, foliolist); -+ node_stat_mod_folio(folio, -+ NR_ISOLATED_ANON + folio_is_file_lru(folio), -+ folio_nr_pages(folio)); - } else if (flags & MPOL_MF_STRICT) { - /* -- * Non-movable page may reach here. And, there may be -- * temporary off LRU pages or non-LRU movable pages. -- * Treat them as unmovable pages since they can't be -+ * Non-movable folio may reach here. And, there may be -+ * temporary off LRU folios or non-LRU movable folios. -+ * Treat them as unmovable folios since they can't be - * isolated, so they can't be moved at the moment. It - * should return -EIO for this case too. - */ -@@ -1224,7 +1224,7 @@ static struct page *new_page(struct page *page, unsigned long start) - } - #else - --static int migrate_page_add(struct page *page, struct list_head *pagelist, -+static int migrate_folio_add(struct folio *folio, struct list_head *foliolist, - unsigned long flags) - { - return -EIO; -@@ -1337,7 +1337,7 @@ static long do_mbind(unsigned long start, unsigned long len, - putback_movable_pages(&pagelist); - } - -- if ((ret > 0) || (nr_failed && (flags & MPOL_MF_STRICT))) -+ if (((ret > 0) || nr_failed) && (flags & MPOL_MF_STRICT)) - err = -EIO; - } else { - up_out: -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index 69668817fed37..ca017c6008b7c 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -170,21 +170,12 @@ static DEFINE_MUTEX(pcp_batch_high_lock); - _ret; \ - }) - --#define pcpu_spin_lock_irqsave(type, member, ptr, flags) \ -+#define pcpu_spin_trylock(type, member, ptr) \ - ({ \ - type *_ret; \ - pcpu_task_pin(); \ - _ret = this_cpu_ptr(ptr); \ -- spin_lock_irqsave(&_ret->member, flags); \ -- _ret; \ --}) -- --#define pcpu_spin_trylock_irqsave(type, member, ptr, flags) \ --({ \ -- type *_ret; \ -- pcpu_task_pin(); \ -- _ret = this_cpu_ptr(ptr); \ -- if (!spin_trylock_irqsave(&_ret->member, flags)) { \ -+ if (!spin_trylock(&_ret->member)) { \ - pcpu_task_unpin(); \ - _ret = NULL; \ - } \ -@@ -197,27 +188,16 @@ static DEFINE_MUTEX(pcp_batch_high_lock); - pcpu_task_unpin(); \ - }) - --#define pcpu_spin_unlock_irqrestore(member, ptr, flags) \ --({ \ -- spin_unlock_irqrestore(&ptr->member, flags); \ -- pcpu_task_unpin(); \ --}) -- - /* struct per_cpu_pages specific helpers. */ - #define pcp_spin_lock(ptr) \ - pcpu_spin_lock(struct per_cpu_pages, lock, ptr) - --#define pcp_spin_lock_irqsave(ptr, flags) \ -- pcpu_spin_lock_irqsave(struct per_cpu_pages, lock, ptr, flags) -- --#define pcp_spin_trylock_irqsave(ptr, flags) \ -- pcpu_spin_trylock_irqsave(struct per_cpu_pages, lock, ptr, flags) -+#define pcp_spin_trylock(ptr) \ -+ pcpu_spin_trylock(struct per_cpu_pages, lock, ptr) - - #define pcp_spin_unlock(ptr) \ - pcpu_spin_unlock(lock, ptr) - --#define pcp_spin_unlock_irqrestore(ptr, flags) \ -- pcpu_spin_unlock_irqrestore(lock, ptr, flags) - #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID - DEFINE_PER_CPU(int, numa_node); - EXPORT_PER_CPU_SYMBOL(numa_node); -@@ -1548,6 +1528,7 @@ static void free_pcppages_bulk(struct zone *zone, int count, - struct per_cpu_pages *pcp, - int pindex) - { -+ unsigned long flags; - int min_pindex = 0; - int max_pindex = NR_PCP_LISTS - 1; - unsigned int order; -@@ -1563,8 +1544,7 @@ static void free_pcppages_bulk(struct zone *zone, int count, - /* Ensure requested pindex is drained first. */ - pindex = pindex - 1; - -- /* Caller must hold IRQ-safe pcp->lock so IRQs are disabled. */ -- spin_lock(&zone->lock); -+ spin_lock_irqsave(&zone->lock, flags); - isolated_pageblocks = has_isolate_pageblock(zone); - - while (count > 0) { -@@ -1612,7 +1592,7 @@ static void free_pcppages_bulk(struct zone *zone, int count, - } while (count > 0 && !list_empty(list)); - } - -- spin_unlock(&zone->lock); -+ spin_unlock_irqrestore(&zone->lock, flags); - } - - static void free_one_page(struct zone *zone, -@@ -3126,10 +3106,10 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, - unsigned long count, struct list_head *list, - int migratetype, unsigned int alloc_flags) - { -+ unsigned long flags; - int i, allocated = 0; - -- /* Caller must hold IRQ-safe pcp->lock so IRQs are disabled. */ -- spin_lock(&zone->lock); -+ spin_lock_irqsave(&zone->lock, flags); - for (i = 0; i < count; ++i) { - struct page *page = __rmqueue(zone, order, migratetype, - alloc_flags); -@@ -3163,7 +3143,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, - * pages added to the pcp list. - */ - __mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order)); -- spin_unlock(&zone->lock); -+ spin_unlock_irqrestore(&zone->lock, flags); - return allocated; - } - -@@ -3180,16 +3160,9 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) - batch = READ_ONCE(pcp->batch); - to_drain = min(pcp->count, batch); - if (to_drain > 0) { -- unsigned long flags; -- -- /* -- * free_pcppages_bulk expects IRQs disabled for zone->lock -- * so even though pcp->lock is not intended to be IRQ-safe, -- * it's needed in this context. -- */ -- spin_lock_irqsave(&pcp->lock, flags); -+ spin_lock(&pcp->lock); - free_pcppages_bulk(zone, to_drain, pcp, 0); -- spin_unlock_irqrestore(&pcp->lock, flags); -+ spin_unlock(&pcp->lock); - } - } - #endif -@@ -3203,12 +3176,9 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone) - - pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu); - if (pcp->count) { -- unsigned long flags; -- -- /* See drain_zone_pages on why this is disabling IRQs */ -- spin_lock_irqsave(&pcp->lock, flags); -+ spin_lock(&pcp->lock); - free_pcppages_bulk(zone, pcp->count, pcp, 0); -- spin_unlock_irqrestore(&pcp->lock, flags); -+ spin_unlock(&pcp->lock); - } - } - -@@ -3474,12 +3444,11 @@ static void free_unref_page_commit(struct zone *zone, struct per_cpu_pages *pcp, - */ - void free_unref_page(struct page *page, unsigned int order) - { -- unsigned long flags; - unsigned long __maybe_unused UP_flags; - struct per_cpu_pages *pcp; - struct zone *zone; - unsigned long pfn = page_to_pfn(page); -- int migratetype; -+ int migratetype, pcpmigratetype; - - if (!free_unref_page_prepare(page, pfn, order)) - return; -@@ -3487,25 +3456,25 @@ void free_unref_page(struct page *page, unsigned int order) - /* - * We only track unmovable, reclaimable and movable on pcp lists. - * Place ISOLATE pages on the isolated list because they are being -- * offlined but treat HIGHATOMIC as movable pages so we can get those -- * areas back if necessary. Otherwise, we may have to free -+ * offlined but treat HIGHATOMIC and CMA as movable pages so we can -+ * get those areas back if necessary. Otherwise, we may have to free - * excessively into the page allocator - */ -- migratetype = get_pcppage_migratetype(page); -+ migratetype = pcpmigratetype = get_pcppage_migratetype(page); - if (unlikely(migratetype >= MIGRATE_PCPTYPES)) { - if (unlikely(is_migrate_isolate(migratetype))) { - free_one_page(page_zone(page), page, pfn, order, migratetype, FPI_NONE); - return; - } -- migratetype = MIGRATE_MOVABLE; -+ pcpmigratetype = MIGRATE_MOVABLE; - } - - zone = page_zone(page); - pcp_trylock_prepare(UP_flags); -- pcp = pcp_spin_trylock_irqsave(zone->per_cpu_pageset, flags); -+ pcp = pcp_spin_trylock(zone->per_cpu_pageset); - if (pcp) { -- free_unref_page_commit(zone, pcp, page, migratetype, order); -- pcp_spin_unlock_irqrestore(pcp, flags); -+ free_unref_page_commit(zone, pcp, page, pcpmigratetype, order); -+ pcp_spin_unlock(pcp); - } else { - free_one_page(zone, page, pfn, order, migratetype, FPI_NONE); - } -@@ -3517,10 +3486,10 @@ void free_unref_page(struct page *page, unsigned int order) - */ - void free_unref_page_list(struct list_head *list) - { -+ unsigned long __maybe_unused UP_flags; - struct page *page, *next; - struct per_cpu_pages *pcp = NULL; - struct zone *locked_zone = NULL; -- unsigned long flags; - int batch_count = 0; - int migratetype; - -@@ -3547,20 +3516,37 @@ void free_unref_page_list(struct list_head *list) - list_for_each_entry_safe(page, next, list, lru) { - struct zone *zone = page_zone(page); - -+ list_del(&page->lru); -+ migratetype = get_pcppage_migratetype(page); -+ - /* Different zone, different pcp lock. */ - if (zone != locked_zone) { -- if (pcp) -- pcp_spin_unlock_irqrestore(pcp, flags); -+ if (pcp) { -+ pcp_spin_unlock(pcp); -+ pcp_trylock_finish(UP_flags); -+ } - -+ /* -+ * trylock is necessary as pages may be getting freed -+ * from IRQ or SoftIRQ context after an IO completion. -+ */ -+ pcp_trylock_prepare(UP_flags); -+ pcp = pcp_spin_trylock(zone->per_cpu_pageset); -+ if (unlikely(!pcp)) { -+ pcp_trylock_finish(UP_flags); -+ free_one_page(zone, page, page_to_pfn(page), -+ 0, migratetype, FPI_NONE); -+ locked_zone = NULL; -+ continue; -+ } - locked_zone = zone; -- pcp = pcp_spin_lock_irqsave(locked_zone->per_cpu_pageset, flags); -+ batch_count = 0; - } - - /* - * Non-isolated types over MIGRATE_PCPTYPES get added - * to the MIGRATE_MOVABLE pcp list. - */ -- migratetype = get_pcppage_migratetype(page); - if (unlikely(migratetype >= MIGRATE_PCPTYPES)) - migratetype = MIGRATE_MOVABLE; - -@@ -3568,18 +3554,23 @@ void free_unref_page_list(struct list_head *list) - free_unref_page_commit(zone, pcp, page, migratetype, 0); - - /* -- * Guard against excessive IRQ disabled times when we get -- * a large list of pages to free. -+ * Guard against excessive lock hold times when freeing -+ * a large list of pages. Lock will be reacquired if -+ * necessary on the next iteration. - */ - if (++batch_count == SWAP_CLUSTER_MAX) { -- pcp_spin_unlock_irqrestore(pcp, flags); -+ pcp_spin_unlock(pcp); -+ pcp_trylock_finish(UP_flags); - batch_count = 0; -- pcp = pcp_spin_lock_irqsave(locked_zone->per_cpu_pageset, flags); -+ pcp = NULL; -+ locked_zone = NULL; - } - } - -- if (pcp) -- pcp_spin_unlock_irqrestore(pcp, flags); -+ if (pcp) { -+ pcp_spin_unlock(pcp); -+ pcp_trylock_finish(UP_flags); -+ } - } - - /* -@@ -3780,15 +3771,11 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, - struct per_cpu_pages *pcp; - struct list_head *list; - struct page *page; -- unsigned long flags; - unsigned long __maybe_unused UP_flags; - -- /* -- * spin_trylock may fail due to a parallel drain. In the future, the -- * trylock will also protect against IRQ reentrancy. -- */ -+ /* spin_trylock may fail due to a parallel drain or IRQ reentrancy. */ - pcp_trylock_prepare(UP_flags); -- pcp = pcp_spin_trylock_irqsave(zone->per_cpu_pageset, flags); -+ pcp = pcp_spin_trylock(zone->per_cpu_pageset); - if (!pcp) { - pcp_trylock_finish(UP_flags); - return NULL; -@@ -3802,7 +3789,7 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, - pcp->free_factor >>= 1; - list = &pcp->lists[order_to_pindex(migratetype, order)]; - page = __rmqueue_pcplist(zone, order, migratetype, alloc_flags, pcp, list); -- pcp_spin_unlock_irqrestore(pcp, flags); -+ pcp_spin_unlock(pcp); - pcp_trylock_finish(UP_flags); - if (page) { - __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); -@@ -5373,7 +5360,6 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid, - struct page **page_array) - { - struct page *page; -- unsigned long flags; - unsigned long __maybe_unused UP_flags; - struct zone *zone; - struct zoneref *z; -@@ -5455,9 +5441,9 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid, - if (unlikely(!zone)) - goto failed; - -- /* Is a parallel drain in progress? */ -+ /* spin_trylock may fail due to a parallel drain or IRQ reentrancy. */ - pcp_trylock_prepare(UP_flags); -- pcp = pcp_spin_trylock_irqsave(zone->per_cpu_pageset, flags); -+ pcp = pcp_spin_trylock(zone->per_cpu_pageset); - if (!pcp) - goto failed_irq; - -@@ -5476,7 +5462,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid, - if (unlikely(!page)) { - /* Try and allocate at least one page */ - if (!nr_account) { -- pcp_spin_unlock_irqrestore(pcp, flags); -+ pcp_spin_unlock(pcp); - goto failed_irq; - } - break; -@@ -5491,7 +5477,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid, - nr_populated++; - } - -- pcp_spin_unlock_irqrestore(pcp, flags); -+ pcp_spin_unlock(pcp); - pcp_trylock_finish(UP_flags); - - __count_zid_vm_events(PGALLOC, zone_idx(zone), nr_account); -diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c -index fa4dd5fab0d44..d13b498f148cc 100644 ---- a/net/bluetooth/hci_core.c -+++ b/net/bluetooth/hci_core.c -@@ -2783,6 +2783,7 @@ void hci_release_dev(struct hci_dev *hdev) - hci_conn_params_clear_all(hdev); - hci_discovery_filter_clear(hdev); - hci_blocked_keys_clear(hdev); -+ hci_codec_list_clear(&hdev->local_codecs); - hci_dev_unlock(hdev); - - ida_simple_remove(&hci_index_ida, hdev->id); -diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c -index 83eaf25ece465..e4d8857716eb7 100644 ---- a/net/bluetooth/hci_event.c -+++ b/net/bluetooth/hci_event.c -@@ -32,6 +32,7 @@ - - #include "hci_request.h" - #include "hci_debugfs.h" -+#include "hci_codec.h" - #include "a2mp.h" - #include "amp.h" - #include "smp.h" -diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h -index b9c5a98238374..0be75cf0efed8 100644 ---- a/net/bluetooth/hci_request.h -+++ b/net/bluetooth/hci_request.h -@@ -71,7 +71,5 @@ struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, - void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn); - void hci_req_add_le_passive_scan(struct hci_request *req); - --void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next); -- - void hci_request_setup(struct hci_dev *hdev); - void hci_request_cancel_all(struct hci_dev *hdev); -diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c -index 2ae038dfc39f7..5218c4dfe0a89 100644 ---- a/net/bluetooth/hci_sync.c -+++ b/net/bluetooth/hci_sync.c -@@ -412,11 +412,6 @@ static int hci_le_scan_restart_sync(struct hci_dev *hdev) - LE_SCAN_FILTER_DUP_ENABLE); - } - --static int le_scan_restart_sync(struct hci_dev *hdev, void *data) --{ -- return hci_le_scan_restart_sync(hdev); --} -- - static void le_scan_restart(struct work_struct *work) - { - struct hci_dev *hdev = container_of(work, struct hci_dev, -@@ -426,15 +421,15 @@ static void le_scan_restart(struct work_struct *work) - - bt_dev_dbg(hdev, ""); - -- hci_dev_lock(hdev); -- -- status = hci_cmd_sync_queue(hdev, le_scan_restart_sync, NULL, NULL); -+ status = hci_le_scan_restart_sync(hdev); - if (status) { - bt_dev_err(hdev, "failed to restart LE scan: status %d", - status); -- goto unlock; -+ return; - } - -+ hci_dev_lock(hdev); -+ - if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) || - !hdev->discovery.scan_start) - goto unlock; -@@ -5033,6 +5028,7 @@ int hci_dev_close_sync(struct hci_dev *hdev) - memset(hdev->eir, 0, sizeof(hdev->eir)); - memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); - bacpy(&hdev->random_addr, BDADDR_ANY); -+ hci_codec_list_clear(&hdev->local_codecs); - - hci_dev_put(hdev); - return err; -diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c -index 5cd2e775915be..91e990accbf20 100644 ---- a/net/bluetooth/iso.c -+++ b/net/bluetooth/iso.c -@@ -458,7 +458,7 @@ drop: - } - - /* -------- Socket interface ---------- */ --static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *ba) -+static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *src, bdaddr_t *dst) - { - struct sock *sk; - -@@ -466,7 +466,10 @@ static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *ba) - if (sk->sk_state != BT_LISTEN) - continue; - -- if (!bacmp(&iso_pi(sk)->src, ba)) -+ if (bacmp(&iso_pi(sk)->dst, dst)) -+ continue; -+ -+ if (!bacmp(&iso_pi(sk)->src, src)) - return sk; - } - -@@ -910,7 +913,7 @@ static int iso_listen_cis(struct sock *sk) - - write_lock(&iso_sk_list.lock); - -- if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src)) -+ if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src, &iso_pi(sk)->dst)) - err = -EADDRINUSE; - - write_unlock(&iso_sk_list.lock); -diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c -index e5e48c6e35d78..b45c00c01dea1 100644 ---- a/net/bridge/br_arp_nd_proxy.c -+++ b/net/bridge/br_arp_nd_proxy.c -@@ -192,7 +192,7 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br, - if (n) { - struct net_bridge_fdb_entry *f; - -- if (!(n->nud_state & NUD_VALID)) { -+ if (!(READ_ONCE(n->nud_state) & NUD_VALID)) { - neigh_release(n); - return; - } -@@ -452,7 +452,7 @@ void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br, - if (n) { - struct net_bridge_fdb_entry *f; - -- if (!(n->nud_state & NUD_VALID)) { -+ if (!(READ_ONCE(n->nud_state) & NUD_VALID)) { - neigh_release(n); - return; - } -diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c -index 812bd7e1750b6..01d690d9fe5f8 100644 ---- a/net/bridge/br_netfilter_hooks.c -+++ b/net/bridge/br_netfilter_hooks.c -@@ -277,7 +277,8 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_ - struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); - int ret; - -- if ((neigh->nud_state & NUD_CONNECTED) && neigh->hh.hh_len) { -+ if ((READ_ONCE(neigh->nud_state) & NUD_CONNECTED) && -+ READ_ONCE(neigh->hh.hh_len)) { - neigh_hh_bridge(&neigh->hh, skb); - skb->dev = nf_bridge->physindev; - ret = br_handle_frame_finish(net, sk, skb); -@@ -293,7 +294,7 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_ - /* tell br_dev_xmit to continue with forwarding */ - nf_bridge->bridged_dnat = 1; - /* FIXME Need to refragment */ -- ret = neigh->output(neigh, skb); -+ ret = READ_ONCE(neigh->output)(neigh, skb); - } - neigh_release(neigh); - return ret; -diff --git a/net/core/filter.c b/net/core/filter.c -index 9fd7c88b5db4e..adc327f4af1e9 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -2197,7 +2197,7 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb, - return -ENOMEM; - } - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - if (!nh) { - dst = skb_dst(skb); - nexthop = rt6_nexthop(container_of(dst, struct rt6_info, dst), -@@ -2210,10 +2210,12 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb, - int ret; - - sock_confirm_neigh(skb, neigh); -+ local_bh_disable(); - dev_xmit_recursion_inc(); - ret = neigh_output(neigh, skb, false); - dev_xmit_recursion_dec(); -- rcu_read_unlock_bh(); -+ local_bh_enable(); -+ rcu_read_unlock(); - return ret; - } - rcu_read_unlock_bh(); -@@ -2295,7 +2297,7 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb, - return -ENOMEM; - } - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - if (!nh) { - struct dst_entry *dst = skb_dst(skb); - struct rtable *rt = container_of(dst, struct rtable, dst); -@@ -2307,7 +2309,7 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb, - } else if (nh->nh_family == AF_INET) { - neigh = ip_neigh_gw4(dev, nh->ipv4_nh); - } else { -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - goto out_drop; - } - -@@ -2315,13 +2317,15 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb, - int ret; - - sock_confirm_neigh(skb, neigh); -+ local_bh_disable(); - dev_xmit_recursion_inc(); - ret = neigh_output(neigh, skb, is_v6gw); - dev_xmit_recursion_dec(); -- rcu_read_unlock_bh(); -+ local_bh_enable(); -+ rcu_read_unlock(); - return ret; - } -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - out_drop: - kfree_skb(skb); - return -ENETDOWN; -@@ -5674,12 +5678,8 @@ static const struct bpf_func_proto bpf_skb_get_xfrm_state_proto = { - #endif - - #if IS_ENABLED(CONFIG_INET) || IS_ENABLED(CONFIG_IPV6) --static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params, -- const struct neighbour *neigh, -- const struct net_device *dev, u32 mtu) -+static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params, u32 mtu) - { -- memcpy(params->dmac, neigh->ha, ETH_ALEN); -- memcpy(params->smac, dev->dev_addr, ETH_ALEN); - params->h_vlan_TCI = 0; - params->h_vlan_proto = 0; - if (mtu) -@@ -5790,21 +5790,29 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params, - if (likely(nhc->nhc_gw_family != AF_INET6)) { - if (nhc->nhc_gw_family) - params->ipv4_dst = nhc->nhc_gw.ipv4; -- -- neigh = __ipv4_neigh_lookup_noref(dev, -- (__force u32)params->ipv4_dst); - } else { - struct in6_addr *dst = (struct in6_addr *)params->ipv6_dst; - - params->family = AF_INET6; - *dst = nhc->nhc_gw.ipv6; -- neigh = __ipv6_neigh_lookup_noref_stub(dev, dst); - } - -- if (!neigh || !(neigh->nud_state & NUD_VALID)) -+ if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH) -+ goto set_fwd_params; -+ -+ if (likely(nhc->nhc_gw_family != AF_INET6)) -+ neigh = __ipv4_neigh_lookup_noref(dev, -+ (__force u32)params->ipv4_dst); -+ else -+ neigh = __ipv6_neigh_lookup_noref_stub(dev, params->ipv6_dst); -+ -+ if (!neigh || !(READ_ONCE(neigh->nud_state) & NUD_VALID)) - return BPF_FIB_LKUP_RET_NO_NEIGH; -+ memcpy(params->dmac, neigh->ha, ETH_ALEN); -+ memcpy(params->smac, dev->dev_addr, ETH_ALEN); - -- return bpf_fib_set_fwd_params(params, neigh, dev, mtu); -+set_fwd_params: -+ return bpf_fib_set_fwd_params(params, mtu); - } - #endif - -@@ -5912,24 +5920,33 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params, - params->rt_metric = res.f6i->fib6_metric; - params->ifindex = dev->ifindex; - -+ if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH) -+ goto set_fwd_params; -+ - /* xdp and cls_bpf programs are run in RCU-bh so rcu_read_lock_bh is - * not needed here. - */ - neigh = __ipv6_neigh_lookup_noref_stub(dev, dst); -- if (!neigh || !(neigh->nud_state & NUD_VALID)) -+ if (!neigh || !(READ_ONCE(neigh->nud_state) & NUD_VALID)) - return BPF_FIB_LKUP_RET_NO_NEIGH; -+ memcpy(params->dmac, neigh->ha, ETH_ALEN); -+ memcpy(params->smac, dev->dev_addr, ETH_ALEN); - -- return bpf_fib_set_fwd_params(params, neigh, dev, mtu); -+set_fwd_params: -+ return bpf_fib_set_fwd_params(params, mtu); - } - #endif - -+#define BPF_FIB_LOOKUP_MASK (BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT | \ -+ BPF_FIB_LOOKUP_SKIP_NEIGH) -+ - BPF_CALL_4(bpf_xdp_fib_lookup, struct xdp_buff *, ctx, - struct bpf_fib_lookup *, params, int, plen, u32, flags) - { - if (plen < sizeof(*params)) - return -EINVAL; - -- if (flags & ~(BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT)) -+ if (flags & ~BPF_FIB_LOOKUP_MASK) - return -EINVAL; - - switch (params->family) { -@@ -5967,7 +5984,7 @@ BPF_CALL_4(bpf_skb_fib_lookup, struct sk_buff *, skb, - if (plen < sizeof(*params)) - return -EINVAL; - -- if (flags & ~(BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT)) -+ if (flags & ~BPF_FIB_LOOKUP_MASK) - return -EINVAL; - - if (params->tot_len) -diff --git a/net/core/neighbour.c b/net/core/neighbour.c -index 6c0f2149f2c72..b20c9768d9f3f 100644 ---- a/net/core/neighbour.c -+++ b/net/core/neighbour.c -@@ -410,7 +410,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev, - */ - __skb_queue_purge(&n->arp_queue); - n->arp_queue_len_bytes = 0; -- n->output = neigh_blackhole; -+ WRITE_ONCE(n->output, neigh_blackhole); - if (n->nud_state & NUD_VALID) - n->nud_state = NUD_NOARP; - else -@@ -614,7 +614,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, - - NEIGH_CACHE_STAT_INC(tbl, lookups); - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - n = __neigh_lookup_noref(tbl, pkey, dev); - if (n) { - if (!refcount_inc_not_zero(&n->refcnt)) -@@ -622,7 +622,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, - NEIGH_CACHE_STAT_INC(tbl, hits); - } - -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - return n; - } - EXPORT_SYMBOL(neigh_lookup); -@@ -920,7 +920,7 @@ static void neigh_suspect(struct neighbour *neigh) - { - neigh_dbg(2, "neigh %p is suspected\n", neigh); - -- neigh->output = neigh->ops->output; -+ WRITE_ONCE(neigh->output, neigh->ops->output); - } - - /* Neighbour state is OK; -@@ -932,7 +932,7 @@ static void neigh_connect(struct neighbour *neigh) - { - neigh_dbg(2, "neigh %p is connected\n", neigh); - -- neigh->output = neigh->ops->connected_output; -+ WRITE_ONCE(neigh->output, neigh->ops->connected_output); - } - - static void neigh_periodic_work(struct work_struct *work) -@@ -988,7 +988,9 @@ static void neigh_periodic_work(struct work_struct *work) - (state == NUD_FAILED || - !time_in_range_open(jiffies, n->used, - n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { -- *np = n->next; -+ rcu_assign_pointer(*np, -+ rcu_dereference_protected(n->next, -+ lockdep_is_held(&tbl->lock))); - neigh_mark_dead(n); - write_unlock(&n->lock); - neigh_cleanup_and_release(n); -@@ -1093,13 +1095,13 @@ static void neigh_timer_handler(struct timer_list *t) - neigh->used + - NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) { - neigh_dbg(2, "neigh %p is delayed\n", neigh); -- neigh->nud_state = NUD_DELAY; -+ WRITE_ONCE(neigh->nud_state, NUD_DELAY); - neigh->updated = jiffies; - neigh_suspect(neigh); - next = now + NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME); - } else { - neigh_dbg(2, "neigh %p is suspected\n", neigh); -- neigh->nud_state = NUD_STALE; -+ WRITE_ONCE(neigh->nud_state, NUD_STALE); - neigh->updated = jiffies; - neigh_suspect(neigh); - notify = 1; -@@ -1109,14 +1111,14 @@ static void neigh_timer_handler(struct timer_list *t) - neigh->confirmed + - NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) { - neigh_dbg(2, "neigh %p is now reachable\n", neigh); -- neigh->nud_state = NUD_REACHABLE; -+ WRITE_ONCE(neigh->nud_state, NUD_REACHABLE); - neigh->updated = jiffies; - neigh_connect(neigh); - notify = 1; - next = neigh->confirmed + neigh->parms->reachable_time; - } else { - neigh_dbg(2, "neigh %p is probed\n", neigh); -- neigh->nud_state = NUD_PROBE; -+ WRITE_ONCE(neigh->nud_state, NUD_PROBE); - neigh->updated = jiffies; - atomic_set(&neigh->probes, 0); - notify = 1; -@@ -1130,7 +1132,7 @@ static void neigh_timer_handler(struct timer_list *t) - - if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && - atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { -- neigh->nud_state = NUD_FAILED; -+ WRITE_ONCE(neigh->nud_state, NUD_FAILED); - notify = 1; - neigh_invalidate(neigh); - goto out; -@@ -1179,7 +1181,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb, - atomic_set(&neigh->probes, - NEIGH_VAR(neigh->parms, UCAST_PROBES)); - neigh_del_timer(neigh); -- neigh->nud_state = NUD_INCOMPLETE; -+ WRITE_ONCE(neigh->nud_state, NUD_INCOMPLETE); - neigh->updated = now; - if (!immediate_ok) { - next = now + 1; -@@ -1191,7 +1193,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb, - } - neigh_add_timer(neigh, next); - } else { -- neigh->nud_state = NUD_FAILED; -+ WRITE_ONCE(neigh->nud_state, NUD_FAILED); - neigh->updated = jiffies; - write_unlock_bh(&neigh->lock); - -@@ -1201,7 +1203,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb, - } else if (neigh->nud_state & NUD_STALE) { - neigh_dbg(2, "neigh %p is delayed\n", neigh); - neigh_del_timer(neigh); -- neigh->nud_state = NUD_DELAY; -+ WRITE_ONCE(neigh->nud_state, NUD_DELAY); - neigh->updated = jiffies; - neigh_add_timer(neigh, jiffies + - NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME)); -@@ -1313,7 +1315,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr, - neigh_update_flags(neigh, flags, ¬ify, &gc_update, &managed_update); - if (flags & (NEIGH_UPDATE_F_USE | NEIGH_UPDATE_F_MANAGED)) { - new = old & ~NUD_PERMANENT; -- neigh->nud_state = new; -+ WRITE_ONCE(neigh->nud_state, new); - err = 0; - goto out; - } -@@ -1322,7 +1324,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr, - neigh_del_timer(neigh); - if (old & NUD_CONNECTED) - neigh_suspect(neigh); -- neigh->nud_state = new; -+ WRITE_ONCE(neigh->nud_state, new); - err = 0; - notify = old & NUD_VALID; - if ((old & (NUD_INCOMPLETE | NUD_PROBE)) && -@@ -1401,7 +1403,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr, - ((new & NUD_REACHABLE) ? - neigh->parms->reachable_time : - 0))); -- neigh->nud_state = new; -+ WRITE_ONCE(neigh->nud_state, new); - notify = 1; - } - -@@ -1447,7 +1449,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr, - if (n2) - n1 = n2; - } -- n1->output(n1, skb); -+ READ_ONCE(n1->output)(n1, skb); - if (n2) - neigh_release(n2); - rcu_read_unlock(); -@@ -1488,7 +1490,7 @@ void __neigh_set_probe_once(struct neighbour *neigh) - neigh->updated = jiffies; - if (!(neigh->nud_state & NUD_FAILED)) - return; -- neigh->nud_state = NUD_INCOMPLETE; -+ WRITE_ONCE(neigh->nud_state, NUD_INCOMPLETE); - atomic_set(&neigh->probes, neigh_max_probes(neigh)); - neigh_add_timer(neigh, - jiffies + max(NEIGH_VAR(neigh->parms, RETRANS_TIME), -@@ -2174,11 +2176,11 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, - .ndtc_proxy_qlen = tbl->proxy_queue.qlen, - }; - -- rcu_read_lock_bh(); -- nht = rcu_dereference_bh(tbl->nht); -+ rcu_read_lock(); -+ nht = rcu_dereference(tbl->nht); - ndc.ndtc_hash_rnd = nht->hash_rnd[0]; - ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1); -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc)) - goto nla_put_failure; -@@ -2693,15 +2695,15 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, - if (filter->dev_idx || filter->master_idx) - flags |= NLM_F_DUMP_FILTERED; - -- rcu_read_lock_bh(); -- nht = rcu_dereference_bh(tbl->nht); -+ rcu_read_lock(); -+ nht = rcu_dereference(tbl->nht); - - for (h = s_h; h < (1 << nht->hash_shift); h++) { - if (h > s_h) - s_idx = 0; -- for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0; -+ for (n = rcu_dereference(nht->hash_buckets[h]), idx = 0; - n != NULL; -- n = rcu_dereference_bh(n->next)) { -+ n = rcu_dereference(n->next)) { - if (idx < s_idx || !net_eq(dev_net(n->dev), net)) - goto next; - if (neigh_ifindex_filtered(n->dev, filter->dev_idx) || -@@ -2720,7 +2722,7 @@ next: - } - rc = skb->len; - out: -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - cb->args[1] = h; - cb->args[2] = idx; - return rc; -@@ -3065,20 +3067,20 @@ void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void - int chain; - struct neigh_hash_table *nht; - -- rcu_read_lock_bh(); -- nht = rcu_dereference_bh(tbl->nht); -+ rcu_read_lock(); -+ nht = rcu_dereference(tbl->nht); - -- read_lock(&tbl->lock); /* avoid resizes */ -+ read_lock_bh(&tbl->lock); /* avoid resizes */ - for (chain = 0; chain < (1 << nht->hash_shift); chain++) { - struct neighbour *n; - -- for (n = rcu_dereference_bh(nht->hash_buckets[chain]); -+ for (n = rcu_dereference(nht->hash_buckets[chain]); - n != NULL; -- n = rcu_dereference_bh(n->next)) -+ n = rcu_dereference(n->next)) - cb(n, cookie); - } -- read_unlock(&tbl->lock); -- rcu_read_unlock_bh(); -+ read_unlock_bh(&tbl->lock); -+ rcu_read_unlock(); - } - EXPORT_SYMBOL(neigh_for_each); - -@@ -3128,7 +3130,7 @@ int neigh_xmit(int index, struct net_device *dev, - tbl = neigh_tables[index]; - if (!tbl) - goto out; -- rcu_read_lock_bh(); -+ rcu_read_lock(); - if (index == NEIGH_ARP_TABLE) { - u32 key = *((u32 *)addr); - -@@ -3140,11 +3142,11 @@ int neigh_xmit(int index, struct net_device *dev, - neigh = __neigh_create(tbl, addr, dev, false); - err = PTR_ERR(neigh); - if (IS_ERR(neigh)) { -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - goto out_kfree_skb; - } -- err = neigh->output(neigh, skb); -- rcu_read_unlock_bh(); -+ err = READ_ONCE(neigh->output)(neigh, skb); -+ rcu_read_unlock(); - } - else if (index == NEIGH_LINK_TABLE) { - err = dev_hard_header(skb, dev, ntohs(skb->protocol), -@@ -3173,7 +3175,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) - - state->flags &= ~NEIGH_SEQ_IS_PNEIGH; - for (bucket = 0; bucket < (1 << nht->hash_shift); bucket++) { -- n = rcu_dereference_bh(nht->hash_buckets[bucket]); -+ n = rcu_dereference(nht->hash_buckets[bucket]); - - while (n) { - if (!net_eq(dev_net(n->dev), net)) -@@ -3188,10 +3190,10 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) - } - if (!(state->flags & NEIGH_SEQ_SKIP_NOARP)) - break; -- if (n->nud_state & ~NUD_NOARP) -+ if (READ_ONCE(n->nud_state) & ~NUD_NOARP) - break; - next: -- n = rcu_dereference_bh(n->next); -+ n = rcu_dereference(n->next); - } - - if (n) -@@ -3215,7 +3217,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, - if (v) - return n; - } -- n = rcu_dereference_bh(n->next); -+ n = rcu_dereference(n->next); - - while (1) { - while (n) { -@@ -3230,10 +3232,10 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, - if (!(state->flags & NEIGH_SEQ_SKIP_NOARP)) - break; - -- if (n->nud_state & ~NUD_NOARP) -+ if (READ_ONCE(n->nud_state) & ~NUD_NOARP) - break; - next: -- n = rcu_dereference_bh(n->next); -+ n = rcu_dereference(n->next); - } - - if (n) -@@ -3242,7 +3244,7 @@ next: - if (++state->bucket >= (1 << nht->hash_shift)) - break; - -- n = rcu_dereference_bh(nht->hash_buckets[state->bucket]); -+ n = rcu_dereference(nht->hash_buckets[state->bucket]); - } - - if (n && pos) -@@ -3344,7 +3346,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos) - - void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags) - __acquires(tbl->lock) -- __acquires(rcu_bh) -+ __acquires(rcu) - { - struct neigh_seq_state *state = seq->private; - -@@ -3352,9 +3354,9 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl - state->bucket = 0; - state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH); - -- rcu_read_lock_bh(); -- state->nht = rcu_dereference_bh(tbl->nht); -- read_lock(&tbl->lock); -+ rcu_read_lock(); -+ state->nht = rcu_dereference(tbl->nht); -+ read_lock_bh(&tbl->lock); - - return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN; - } -@@ -3389,13 +3391,13 @@ EXPORT_SYMBOL(neigh_seq_next); - - void neigh_seq_stop(struct seq_file *seq, void *v) - __releases(tbl->lock) -- __releases(rcu_bh) -+ __releases(rcu) - { - struct neigh_seq_state *state = seq->private; - struct neigh_table *tbl = state->tbl; - -- read_unlock(&tbl->lock); -- rcu_read_unlock_bh(); -+ read_unlock_bh(&tbl->lock); -+ rcu_read_unlock(); - } - EXPORT_SYMBOL(neigh_seq_stop); - -diff --git a/net/core/sock_map.c b/net/core/sock_map.c -index 96db7409baa12..38e01f82f2ef3 100644 ---- a/net/core/sock_map.c -+++ b/net/core/sock_map.c -@@ -670,6 +670,8 @@ BPF_CALL_4(bpf_msg_redirect_map, struct sk_msg *, msg, - sk = __sock_map_lookup_elem(map, key); - if (unlikely(!sk || !sock_map_redirect_allowed(sk))) - return SK_DROP; -+ if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk)) -+ return SK_DROP; - - msg->flags = flags; - msg->sk_redir = sk; -@@ -1262,6 +1264,8 @@ BPF_CALL_4(bpf_msg_redirect_hash, struct sk_msg *, msg, - sk = __sock_hash_lookup_elem(map, key); - if (unlikely(!sk || !sock_map_redirect_allowed(sk))) - return SK_DROP; -+ if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk)) -+ return SK_DROP; - - msg->flags = flags; - msg->sk_redir = sk; -diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c -index 4f7237661afb9..9456f5bb35e5d 100644 ---- a/net/ipv4/arp.c -+++ b/net/ipv4/arp.c -@@ -375,7 +375,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) - - probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES); - if (probes < 0) { -- if (!(neigh->nud_state & NUD_VALID)) -+ if (!(READ_ONCE(neigh->nud_state) & NUD_VALID)) - pr_debug("trying to ucast probe in NUD_INVALID\n"); - neigh_ha_snapshot(dst_ha, neigh, dev); - dst_hw = dst_ha; -@@ -1123,7 +1123,7 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) - - neigh = neigh_lookup(&arp_tbl, &ip, dev); - if (neigh) { -- if (!(neigh->nud_state & NUD_NOARP)) { -+ if (!(READ_ONCE(neigh->nud_state) & NUD_NOARP)) { - read_lock_bh(&neigh->lock); - memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len); - r->arp_flags = arp_state_to_flags(neigh); -@@ -1144,12 +1144,12 @@ int arp_invalidate(struct net_device *dev, __be32 ip, bool force) - struct neigh_table *tbl = &arp_tbl; - - if (neigh) { -- if ((neigh->nud_state & NUD_VALID) && !force) { -+ if ((READ_ONCE(neigh->nud_state) & NUD_VALID) && !force) { - neigh_release(neigh); - return 0; - } - -- if (neigh->nud_state & ~NUD_NOARP) -+ if (READ_ONCE(neigh->nud_state) & ~NUD_NOARP) - err = neigh_update(neigh, NULL, NUD_FAILED, - NEIGH_UPDATE_F_OVERRIDE| - NEIGH_UPDATE_F_ADMIN, 0); -diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c -index 3b6e6bc80dc1c..eafa4a0335157 100644 ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -564,7 +564,7 @@ static int fib_detect_death(struct fib_info *fi, int order, - n = NULL; - - if (n) { -- state = n->nud_state; -+ state = READ_ONCE(n->nud_state); - neigh_release(n); - } else { - return 0; -@@ -2194,7 +2194,7 @@ static bool fib_good_nh(const struct fib_nh *nh) - if (nh->fib_nh_scope == RT_SCOPE_LINK) { - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - - if (likely(nh->fib_nh_gw_family == AF_INET)) - n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev, -@@ -2205,9 +2205,9 @@ static bool fib_good_nh(const struct fib_nh *nh) - else - n = NULL; - if (n) -- state = n->nud_state; -+ state = READ_ONCE(n->nud_state); - -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - } - - return !!(state & NUD_VALID); -diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c -index 66908ce2dd116..493c679ea54f3 100644 ---- a/net/ipv4/ip_output.c -+++ b/net/ipv4/ip_output.c -@@ -218,7 +218,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s - return res; - } - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); - if (!IS_ERR(neigh)) { - int res; -@@ -226,10 +226,10 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s - sock_confirm_neigh(skb, neigh); - /* if crossing protocols, can not use the cached header */ - res = neigh_output(neigh, skb, is_v6gw); -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - return res; - } -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - net_dbg_ratelimited("%s: No header cache and no neighbour!\n", - __func__); -diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c -index 9cc2879024541..be5498f5dd319 100644 ---- a/net/ipv4/nexthop.c -+++ b/net/ipv4/nexthop.c -@@ -1124,13 +1124,13 @@ static bool ipv6_good_nh(const struct fib6_nh *nh) - int state = NUD_REACHABLE; - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - - n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6); - if (n) -- state = n->nud_state; -+ state = READ_ONCE(n->nud_state); - -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - return !!(state & NUD_VALID); - } -@@ -1140,14 +1140,14 @@ static bool ipv4_good_nh(const struct fib_nh *nh) - int state = NUD_REACHABLE; - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - - n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev, - (__force u32)nh->fib_nh_gw4); - if (n) -- state = n->nud_state; -+ state = READ_ONCE(n->nud_state); - -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - return !!(state & NUD_VALID); - } -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 84a0a71a6f4e7..9cbaae4f5ee71 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -408,7 +408,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, - struct net_device *dev = dst->dev; - struct neighbour *n; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - - if (likely(rt->rt_gw_family == AF_INET)) { - n = ip_neigh_gw4(dev, rt->rt_gw4); -@@ -424,7 +424,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, - if (!IS_ERR(n) && !refcount_inc_not_zero(&n->refcnt)) - n = NULL; - -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - return n; - } -@@ -784,7 +784,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow - if (!n) - n = neigh_create(&arp_tbl, &new_gw, rt->dst.dev); - if (!IS_ERR(n)) { -- if (!(n->nud_state & NUD_VALID)) { -+ if (!(READ_ONCE(n->nud_state) & NUD_VALID)) { - neigh_event_send(n, NULL); - } else { - if (fib_lookup(net, fl4, &res, 0) == 0) { -@@ -3421,6 +3421,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, - fa->fa_type == fri.type) { - fri.offload = READ_ONCE(fa->offload); - fri.trap = READ_ONCE(fa->trap); -+ fri.offload_failed = -+ READ_ONCE(fa->offload_failed); - break; - } - } -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index fab25d4f3a6f1..96fdde6e42b1b 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -1755,16 +1755,13 @@ EXPORT_SYMBOL(tcp_read_sock); - - int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) - { -- struct tcp_sock *tp = tcp_sk(sk); -- u32 seq = tp->copied_seq; - struct sk_buff *skb; - int copied = 0; -- u32 offset; - - if (sk->sk_state == TCP_LISTEN) - return -ENOTCONN; - -- while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { -+ while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) { - u8 tcp_flags; - int used; - -@@ -1777,13 +1774,10 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) - copied = used; - break; - } -- seq += used; - copied += used; - -- if (tcp_flags & TCPHDR_FIN) { -- ++seq; -+ if (tcp_flags & TCPHDR_FIN) - break; -- } - } - return copied; - } -diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c -index 5f93918c063c7..f53380fd89bcf 100644 ---- a/net/ipv4/tcp_bpf.c -+++ b/net/ipv4/tcp_bpf.c -@@ -217,6 +217,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk, - int *addr_len) - { - struct tcp_sock *tcp = tcp_sk(sk); -+ int peek = flags & MSG_PEEK; - u32 seq = tcp->copied_seq; - struct sk_psock *psock; - int copied = 0; -@@ -306,7 +307,8 @@ msg_bytes_ready: - copied = -EAGAIN; - } - out: -- WRITE_ONCE(tcp->copied_seq, seq); -+ if (!peek) -+ WRITE_ONCE(tcp->copied_seq, seq); - tcp_rcv_space_adjust(sk); - if (copied > 0) - __tcp_cleanup_rbuf(sk, copied); -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index c697836f2b5b4..068221e742425 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -243,6 +243,19 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb) - if (unlikely(len > icsk->icsk_ack.rcv_mss + - MAX_TCP_OPTION_SPACE)) - tcp_gro_dev_warn(sk, skb, len); -+ /* If the skb has a len of exactly 1*MSS and has the PSH bit -+ * set then it is likely the end of an application write. So -+ * more data may not be arriving soon, and yet the data sender -+ * may be waiting for an ACK if cwnd-bound or using TX zero -+ * copy. So we set ICSK_ACK_PUSHED here so that -+ * tcp_cleanup_rbuf() will send an ACK immediately if the app -+ * reads all of the data and is not ping-pong. If len > MSS -+ * then this logic does not matter (and does not hurt) because -+ * tcp_cleanup_rbuf() will always ACK immediately if the app -+ * reads data and there is more than an MSS of unACKed data. -+ */ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_PSH) -+ icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; - } else { - /* Otherwise, we make more careful check taking into account, - * that SACKs block is variable. -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index dc3166e56169f..5921b0f6f9f41 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -177,8 +177,7 @@ static void tcp_event_data_sent(struct tcp_sock *tp, - } - - /* Account for an ACK we sent. */ --static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts, -- u32 rcv_nxt) -+static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -192,7 +191,7 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts, - - if (unlikely(rcv_nxt != tp->rcv_nxt)) - return; /* Special ACK sent by DCTCP to reflect ECN */ -- tcp_dec_quickack_mode(sk, pkts); -+ tcp_dec_quickack_mode(sk); - inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); - } - -@@ -1373,7 +1372,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, - sk, skb); - - if (likely(tcb->tcp_flags & TCPHDR_ACK)) -- tcp_event_ack_sent(sk, tcp_skb_pcount(skb), rcv_nxt); -+ tcp_event_ack_sent(sk, rcv_nxt); - - if (skb->len != tcp_header_size) { - tcp_event_data_sent(tp, sk); -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 83be842198244..c63ccd39fc552 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -202,6 +202,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { - .ra_defrtr_metric = IP6_RT_PRIO_USER, - .accept_ra_from_local = 0, - .accept_ra_min_hop_limit= 1, -+ .accept_ra_min_lft = 0, - .accept_ra_pinfo = 1, - #ifdef CONFIG_IPV6_ROUTER_PREF - .accept_ra_rtr_pref = 1, -@@ -262,6 +263,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { - .ra_defrtr_metric = IP6_RT_PRIO_USER, - .accept_ra_from_local = 0, - .accept_ra_min_hop_limit= 1, -+ .accept_ra_min_lft = 0, - .accept_ra_pinfo = 1, - #ifdef CONFIG_IPV6_ROUTER_PREF - .accept_ra_rtr_pref = 1, -@@ -1033,7 +1035,7 @@ static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa) - unsigned int hash = inet6_addr_hash(net, &ifa->addr); - int err = 0; - -- spin_lock(&net->ipv6.addrconf_hash_lock); -+ spin_lock_bh(&net->ipv6.addrconf_hash_lock); - - /* Ignore adding duplicate addresses on an interface */ - if (ipv6_chk_same_addr(net, &ifa->addr, dev, hash)) { -@@ -1043,7 +1045,7 @@ static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa) - hlist_add_head_rcu(&ifa->addr_lst, &net->ipv6.inet6_addr_lst[hash]); - } - -- spin_unlock(&net->ipv6.addrconf_hash_lock); -+ spin_unlock_bh(&net->ipv6.addrconf_hash_lock); - - return err; - } -@@ -1138,15 +1140,15 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, - /* For caller */ - refcount_set(&ifa->refcnt, 1); - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - - err = ipv6_add_addr_hash(idev->dev, ifa); - if (err < 0) { -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - goto out; - } - -- write_lock(&idev->lock); -+ write_lock_bh(&idev->lock); - - /* Add to inet6_dev unicast addr list. */ - ipv6_link_dev_addr(idev, ifa); -@@ -1157,9 +1159,9 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, - } - - in6_ifa_hold(ifa); -- write_unlock(&idev->lock); -+ write_unlock_bh(&idev->lock); - -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - inet6addr_notifier_call_chain(NETDEV_UP, ifa); - out: -@@ -2731,6 +2733,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) - return; - } - -+ if (valid_lft != 0 && valid_lft < in6_dev->cnf.accept_ra_min_lft) -+ goto put; -+ - /* - * Two things going on here: - * 1) Add routes for on-link prefixes -@@ -5601,6 +5606,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, - array[DEVCONF_IOAM6_ID_WIDE] = cnf->ioam6_id_wide; - array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier; - array[DEVCONF_ACCEPT_UNTRACKED_NA] = cnf->accept_untracked_na; -+ array[DEVCONF_ACCEPT_RA_MIN_LFT] = cnf->accept_ra_min_lft; - } - - static inline size_t inet6_ifla6_size(void) -@@ -6794,6 +6800,13 @@ static const struct ctl_table addrconf_sysctl[] = { - .mode = 0644, - .proc_handler = proc_dointvec, - }, -+ { -+ .procname = "accept_ra_min_lft", -+ .data = &ipv6_devconf.accept_ra_min_lft, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = proc_dointvec, -+ }, - { - .procname = "accept_ra_pinfo", - .data = &ipv6_devconf.accept_ra_pinfo, -diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c -index 413f66781e50d..eb6640f9a7921 100644 ---- a/net/ipv6/ip6_fib.c -+++ b/net/ipv6/ip6_fib.c -@@ -2492,7 +2492,7 @@ static int ipv6_route_native_seq_show(struct seq_file *seq, void *v) - const struct net_device *dev; - - if (rt->nh) -- fib6_nh = nexthop_fib6_nh_bh(rt->nh); -+ fib6_nh = nexthop_fib6_nh(rt->nh); - - seq_printf(seq, "%pi6 %02x ", &rt->fib6_dst.addr, rt->fib6_dst.plen); - -@@ -2557,14 +2557,14 @@ static struct fib6_table *ipv6_route_seq_next_table(struct fib6_table *tbl, - - if (tbl) { - h = (tbl->tb6_id & (FIB6_TABLE_HASHSZ - 1)) + 1; -- node = rcu_dereference_bh(hlist_next_rcu(&tbl->tb6_hlist)); -+ node = rcu_dereference(hlist_next_rcu(&tbl->tb6_hlist)); - } else { - h = 0; - node = NULL; - } - - while (!node && h < FIB6_TABLE_HASHSZ) { -- node = rcu_dereference_bh( -+ node = rcu_dereference( - hlist_first_rcu(&net->ipv6.fib_table_hash[h++])); - } - return hlist_entry_safe(node, struct fib6_table, tb6_hlist); -@@ -2594,7 +2594,7 @@ static void *ipv6_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) - if (!v) - goto iter_table; - -- n = rcu_dereference_bh(((struct fib6_info *)v)->fib6_next); -+ n = rcu_dereference(((struct fib6_info *)v)->fib6_next); - if (n) - return n; - -@@ -2620,12 +2620,12 @@ iter_table: - } - - static void *ipv6_route_seq_start(struct seq_file *seq, loff_t *pos) -- __acquires(RCU_BH) -+ __acquires(RCU) - { - struct net *net = seq_file_net(seq); - struct ipv6_route_iter *iter = seq->private; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - iter->tbl = ipv6_route_seq_next_table(NULL, net); - iter->skip = *pos; - -@@ -2646,7 +2646,7 @@ static bool ipv6_route_iter_active(struct ipv6_route_iter *iter) - } - - static void ipv6_route_native_seq_stop(struct seq_file *seq, void *v) -- __releases(RCU_BH) -+ __releases(RCU) - { - struct net *net = seq_file_net(seq); - struct ipv6_route_iter *iter = seq->private; -@@ -2654,7 +2654,7 @@ static void ipv6_route_native_seq_stop(struct seq_file *seq, void *v) - if (ipv6_route_iter_active(iter)) - fib6_walker_unlink(net, &iter->w); - -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - } - - #if IS_BUILTIN(CONFIG_IPV6) && defined(CONFIG_BPF_SYSCALL) -diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c -index 34192f7a166fb..ce2c5e728745f 100644 ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -116,7 +116,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * - return res; - } - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - nexthop = rt6_nexthop((struct rt6_info *)dst, daddr); - neigh = __ipv6_neigh_lookup_noref(dev, nexthop); - -@@ -124,7 +124,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * - if (unlikely(!neigh)) - neigh = __neigh_create(&nd_tbl, nexthop, dev, false); - if (IS_ERR(neigh)) { -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTNOROUTES); - kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL); - return -EINVAL; -@@ -132,7 +132,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * - } - sock_confirm_neigh(skb, neigh); - ret = neigh_output(neigh, skb, false); -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - return ret; - } - -@@ -1150,11 +1150,11 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk, - * dst entry of the nexthop router - */ - rt = (struct rt6_info *) *dst; -- rcu_read_lock_bh(); -+ rcu_read_lock(); - n = __ipv6_neigh_lookup_noref(rt->dst.dev, - rt6_nexthop(rt, &fl6->daddr)); -- err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0; -- rcu_read_unlock_bh(); -+ err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0; -+ rcu_read_unlock(); - - if (err) { - struct inet6_ifaddr *ifp; -diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c -index a4d43eb45a9de..8c5a99fe68030 100644 ---- a/net/ipv6/ndisc.c -+++ b/net/ipv6/ndisc.c -@@ -746,7 +746,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) - saddr = &ipv6_hdr(skb)->saddr; - probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES); - if (probes < 0) { -- if (!(neigh->nud_state & NUD_VALID)) { -+ if (!(READ_ONCE(neigh->nud_state) & NUD_VALID)) { - ND_PRINTK(1, dbg, - "%s: trying to ucast probe in NUD_INVALID: %pI6\n", - __func__, target); -@@ -1092,7 +1092,7 @@ static void ndisc_recv_na(struct sk_buff *skb) - u8 old_flags = neigh->flags; - struct net *net = dev_net(dev); - -- if (neigh->nud_state & NUD_FAILED) -+ if (READ_ONCE(neigh->nud_state) & NUD_FAILED) - goto out; - - /* -@@ -1331,6 +1331,14 @@ static void ndisc_router_discovery(struct sk_buff *skb) - goto skip_defrtr; - } - -+ lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); -+ if (lifetime != 0 && lifetime < in6_dev->cnf.accept_ra_min_lft) { -+ ND_PRINTK(2, info, -+ "RA: router lifetime (%ds) is too short: %s\n", -+ lifetime, skb->dev->name); -+ goto skip_defrtr; -+ } -+ - /* Do not accept RA with source-addr found on local machine unless - * accept_ra_from_local is set to true. - */ -@@ -1343,8 +1351,6 @@ static void ndisc_router_discovery(struct sk_buff *skb) - goto skip_defrtr; - } - -- lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); -- - #ifdef CONFIG_IPV6_ROUTER_PREF - pref = ra_msg->icmph.icmp6_router_pref; - /* 10b is handled as if it were 00b (medium) */ -@@ -1519,6 +1525,9 @@ skip_linkparms: - if (ri->prefix_len == 0 && - !in6_dev->cnf.accept_ra_defrtr) - continue; -+ if (ri->lifetime != 0 && -+ ntohl(ri->lifetime) < in6_dev->cnf.accept_ra_min_lft) -+ continue; - if (ri->prefix_len < in6_dev->cnf.accept_ra_rt_info_min_plen) - continue; - if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 93957b20fccce..0bcdb675ba2c1 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -636,15 +636,15 @@ static void rt6_probe(struct fib6_nh *fib6_nh) - - nh_gw = &fib6_nh->fib_nh_gw6; - dev = fib6_nh->fib_nh_dev; -- rcu_read_lock_bh(); -+ rcu_read_lock(); - last_probe = READ_ONCE(fib6_nh->last_probe); - idev = __in6_dev_get(dev); - neigh = __ipv6_neigh_lookup_noref(dev, nh_gw); - if (neigh) { -- if (neigh->nud_state & NUD_VALID) -+ if (READ_ONCE(neigh->nud_state) & NUD_VALID) - goto out; - -- write_lock(&neigh->lock); -+ write_lock_bh(&neigh->lock); - if (!(neigh->nud_state & NUD_VALID) && - time_after(jiffies, - neigh->updated + idev->cnf.rtr_probe_interval)) { -@@ -652,7 +652,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh) - if (work) - __neigh_set_probe_once(neigh); - } -- write_unlock(&neigh->lock); -+ write_unlock_bh(&neigh->lock); - } else if (time_after(jiffies, last_probe + - idev->cnf.rtr_probe_interval)) { - work = kmalloc(sizeof(*work), GFP_ATOMIC); -@@ -670,7 +670,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh) - } - - out: -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - } - #else - static inline void rt6_probe(struct fib6_nh *fib6_nh) -@@ -686,25 +686,25 @@ static enum rt6_nud_state rt6_check_neigh(const struct fib6_nh *fib6_nh) - enum rt6_nud_state ret = RT6_NUD_FAIL_HARD; - struct neighbour *neigh; - -- rcu_read_lock_bh(); -+ rcu_read_lock(); - neigh = __ipv6_neigh_lookup_noref(fib6_nh->fib_nh_dev, - &fib6_nh->fib_nh_gw6); - if (neigh) { -- read_lock(&neigh->lock); -- if (neigh->nud_state & NUD_VALID) -+ u8 nud_state = READ_ONCE(neigh->nud_state); -+ -+ if (nud_state & NUD_VALID) - ret = RT6_NUD_SUCCEED; - #ifdef CONFIG_IPV6_ROUTER_PREF -- else if (!(neigh->nud_state & NUD_FAILED)) -+ else if (!(nud_state & NUD_FAILED)) - ret = RT6_NUD_SUCCEED; - else - ret = RT6_NUD_FAIL_PROBE; - #endif -- read_unlock(&neigh->lock); - } else { - ret = IS_ENABLED(CONFIG_IPV6_ROUTER_PREF) ? - RT6_NUD_SUCCEED : RT6_NUD_FAIL_DO_RR; - } -- rcu_read_unlock_bh(); -+ rcu_read_unlock(); - - return ret; - } -diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c -index 4bdd356bb5c46..7be89dcfd5fc5 100644 ---- a/net/ipv6/tcp_ipv6.c -+++ b/net/ipv6/tcp_ipv6.c -@@ -1644,9 +1644,12 @@ process: - struct sock *nsk; - - sk = req->rsk_listener; -- drop_reason = tcp_inbound_md5_hash(sk, skb, -- &hdr->saddr, &hdr->daddr, -- AF_INET6, dif, sdif); -+ if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) -+ drop_reason = SKB_DROP_REASON_XFRM_POLICY; -+ else -+ drop_reason = tcp_inbound_md5_hash(sk, skb, -+ &hdr->saddr, &hdr->daddr, -+ AF_INET6, dif, sdif); - if (drop_reason) { - sk_drops_add(sk, skb); - reqsk_put(req); -@@ -1693,6 +1696,7 @@ process: - } - goto discard_and_relse; - } -+ nf_reset_ct(skb); - if (nsk == sk) { - reqsk_put(req); - tcp_v6_restore_cb(skb); -diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c -index bce4132b0a5c8..314ec3a51e8de 100644 ---- a/net/l2tp/l2tp_ip6.c -+++ b/net/l2tp/l2tp_ip6.c -@@ -510,7 +510,6 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - */ - if (len > INT_MAX - transhdrlen) - return -EMSGSIZE; -- ulen = len + transhdrlen; - - /* Mirror BSD error message compatibility */ - if (msg->msg_flags & MSG_OOB) -@@ -631,6 +630,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - - back_from_confirm: - lock_sock(sk); -+ ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0; - err = ip6_append_data(sk, ip_generic_getfrag, msg, - ulen, transhdrlen, &ipc6, - &fl6, (struct rt6_info *)dst, -diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c -index cf3453b532d67..0167413d56972 100644 ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -566,6 +566,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, - } - - err = ieee80211_key_link(key, link, sta); -+ /* KRACK protection, shouldn't happen but just silently accept key */ -+ if (err == -EALREADY) -+ err = 0; - - out_unlock: - mutex_unlock(&local->sta_mtx); -diff --git a/net/mac80211/key.c b/net/mac80211/key.c -index e8f6c1e5eabfc..23bb24243c6e9 100644 ---- a/net/mac80211/key.c -+++ b/net/mac80211/key.c -@@ -901,7 +901,7 @@ int ieee80211_key_link(struct ieee80211_key *key, - */ - if (ieee80211_key_identical(sdata, old_key, key)) { - ieee80211_key_free_unused(key); -- ret = 0; -+ ret = -EALREADY; - goto out; - } - -diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c -index 9127a7fd5269c..5d845fcf3d09e 100644 ---- a/net/mptcp/pm_netlink.c -+++ b/net/mptcp/pm_netlink.c -@@ -2047,7 +2047,7 @@ static int mptcp_event_put_token_and_ssk(struct sk_buff *skb, - nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if)) - return -EMSGSIZE; - -- sk_err = ssk->sk_err; -+ sk_err = READ_ONCE(ssk->sk_err); - if (sk_err && sk->sk_state == TCP_ESTABLISHED && - nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err)) - return -EMSGSIZE; -diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c -index 8a2aa63caa51f..38cbdc66d8bff 100644 ---- a/net/mptcp/pm_userspace.c -+++ b/net/mptcp/pm_userspace.c -@@ -309,12 +309,6 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info) - goto create_err; - } - -- if (addr_l.id == 0) { -- NL_SET_ERR_MSG_ATTR(info->extack, laddr, "missing local addr id"); -- err = -EINVAL; -- goto create_err; -- } -- - err = mptcp_pm_parse_addr(raddr, info, &addr_r); - if (err < 0) { - NL_SET_ERR_MSG_ATTR(info->extack, raddr, "error parsing remote addr"); -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index 6dd880d6b0518..b6e0579e72644 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -401,7 +401,7 @@ drop: - return false; - } - --static void mptcp_stop_timer(struct sock *sk) -+static void mptcp_stop_rtx_timer(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - -@@ -765,6 +765,46 @@ static bool __mptcp_ofo_queue(struct mptcp_sock *msk) - return moved; - } - -+static bool __mptcp_subflow_error_report(struct sock *sk, struct sock *ssk) -+{ -+ int err = sock_error(ssk); -+ int ssk_state; -+ -+ if (!err) -+ return false; -+ -+ /* only propagate errors on fallen-back sockets or -+ * on MPC connect -+ */ -+ if (sk->sk_state != TCP_SYN_SENT && !__mptcp_check_fallback(mptcp_sk(sk))) -+ return false; -+ -+ /* We need to propagate only transition to CLOSE state. -+ * Orphaned socket will see such state change via -+ * subflow_sched_work_if_closed() and that path will properly -+ * destroy the msk as needed. -+ */ -+ ssk_state = inet_sk_state_load(ssk); -+ if (ssk_state == TCP_CLOSE && !sock_flag(sk, SOCK_DEAD)) -+ inet_sk_state_store(sk, ssk_state); -+ WRITE_ONCE(sk->sk_err, -err); -+ -+ /* This barrier is coupled with smp_rmb() in mptcp_poll() */ -+ smp_wmb(); -+ sk_error_report(sk); -+ return true; -+} -+ -+void __mptcp_error_report(struct sock *sk) -+{ -+ struct mptcp_subflow_context *subflow; -+ struct mptcp_sock *msk = mptcp_sk(sk); -+ -+ mptcp_for_each_subflow(msk, subflow) -+ if (__mptcp_subflow_error_report(sk, mptcp_subflow_tcp_sock(subflow))) -+ break; -+} -+ - /* In most cases we will be able to lock the mptcp socket. If its already - * owned, we need to defer to the work queue to avoid ABBA deadlock. - */ -@@ -846,6 +886,7 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk) - - mptcp_sockopt_sync_locked(msk, ssk); - mptcp_subflow_joined(msk, ssk); -+ mptcp_stop_tout_timer(sk); - return true; - } - -@@ -865,12 +906,12 @@ static void __mptcp_flush_join_list(struct sock *sk, struct list_head *join_list - } - } - --static bool mptcp_timer_pending(struct sock *sk) -+static bool mptcp_rtx_timer_pending(struct sock *sk) - { - return timer_pending(&inet_csk(sk)->icsk_retransmit_timer); - } - --static void mptcp_reset_timer(struct sock *sk) -+static void mptcp_reset_rtx_timer(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - unsigned long tout; -@@ -1054,10 +1095,10 @@ static void __mptcp_clean_una(struct sock *sk) - out: - if (snd_una == READ_ONCE(msk->snd_nxt) && - snd_una == READ_ONCE(msk->write_seq)) { -- if (mptcp_timer_pending(sk) && !mptcp_data_fin_enabled(msk)) -- mptcp_stop_timer(sk); -+ if (mptcp_rtx_timer_pending(sk) && !mptcp_data_fin_enabled(msk)) -+ mptcp_stop_rtx_timer(sk); - } else { -- mptcp_reset_timer(sk); -+ mptcp_reset_rtx_timer(sk); - } - } - -@@ -1606,8 +1647,8 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags) - - out: - /* ensure the rtx timer is running */ -- if (!mptcp_timer_pending(sk)) -- mptcp_reset_timer(sk); -+ if (!mptcp_rtx_timer_pending(sk)) -+ mptcp_reset_rtx_timer(sk); - if (do_check_data_fin) - mptcp_check_send_data_fin(sk); - } -@@ -1665,8 +1706,8 @@ out: - if (copied) { - tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle, - info.size_goal); -- if (!mptcp_timer_pending(sk)) -- mptcp_reset_timer(sk); -+ if (!mptcp_rtx_timer_pending(sk)) -+ mptcp_reset_rtx_timer(sk); - - if (msk->snd_data_fin_enable && - msk->snd_nxt + 1 == msk->write_seq) -@@ -2227,7 +2268,7 @@ static void mptcp_retransmit_timer(struct timer_list *t) - sock_put(sk); - } - --static void mptcp_timeout_timer(struct timer_list *t) -+static void mptcp_tout_timer(struct timer_list *t) - { - struct sock *sk = from_timer(sk, t, sk_timer); - -@@ -2349,18 +2390,14 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - bool dispose_it, need_push = false; - - /* If the first subflow moved to a close state before accept, e.g. due -- * to an incoming reset, mptcp either: -- * - if either the subflow or the msk are dead, destroy the context -- * (the subflow socket is deleted by inet_child_forget) and the msk -- * - otherwise do nothing at the moment and take action at accept and/or -- * listener shutdown - user-space must be able to accept() the closed -- * socket. -+ * to an incoming reset or listener shutdown, the subflow socket is -+ * already deleted by inet_child_forget() and the mptcp socket can't -+ * survive too. - */ -- if (msk->in_accept_queue && msk->first == ssk) { -- if (!sock_flag(sk, SOCK_DEAD) && !sock_flag(ssk, SOCK_DEAD)) -- return; -- -+ if (msk->in_accept_queue && msk->first == ssk && -+ (sock_flag(sk, SOCK_DEAD) || sock_flag(ssk, SOCK_DEAD))) { - /* ensure later check in mptcp_worker() will dispose the msk */ -+ mptcp_set_close_tout(sk, tcp_jiffies32 - (TCP_TIMEWAIT_LEN + 1)); - sock_set_flag(sk, SOCK_DEAD); - lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); - mptcp_subflow_drop_ctx(ssk); -@@ -2413,6 +2450,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - } - - out_release: -+ __mptcp_subflow_error_report(sk, ssk); - release_sock(ssk); - - sock_put(ssk); -@@ -2426,6 +2464,22 @@ out: - - if (need_push) - __mptcp_push_pending(sk, 0); -+ -+ /* Catch every 'all subflows closed' scenario, including peers silently -+ * closing them, e.g. due to timeout. -+ * For established sockets, allow an additional timeout before closing, -+ * as the protocol can still create more subflows. -+ */ -+ if (list_is_singular(&msk->conn_list) && msk->first && -+ inet_sk_state_load(msk->first) == TCP_CLOSE) { -+ if (sk->sk_state != TCP_ESTABLISHED || -+ msk->in_accept_queue || sock_flag(sk, SOCK_DEAD)) { -+ inet_sk_state_store(sk, TCP_CLOSE); -+ mptcp_close_wake_up(sk); -+ } else { -+ mptcp_start_tout_timer(sk); -+ } -+ } - } - - void mptcp_close_ssk(struct sock *sk, struct sock *ssk, -@@ -2469,23 +2523,14 @@ static void __mptcp_close_subflow(struct sock *sk) - - } - --static bool mptcp_should_close(const struct sock *sk) -+static bool mptcp_close_tout_expired(const struct sock *sk) - { -- s32 delta = tcp_jiffies32 - inet_csk(sk)->icsk_mtup.probe_timestamp; -- struct mptcp_subflow_context *subflow; -- -- if (delta >= TCP_TIMEWAIT_LEN || mptcp_sk(sk)->in_accept_queue) -- return true; -+ if (!inet_csk(sk)->icsk_mtup.probe_timestamp || -+ sk->sk_state == TCP_CLOSE) -+ return false; - -- /* if all subflows are in closed status don't bother with additional -- * timeout -- */ -- mptcp_for_each_subflow(mptcp_sk(sk), subflow) { -- if (inet_sk_state_load(mptcp_subflow_tcp_sock(subflow)) != -- TCP_CLOSE) -- return false; -- } -- return true; -+ return time_after32(tcp_jiffies32, -+ inet_csk(sk)->icsk_mtup.probe_timestamp + TCP_TIMEWAIT_LEN); - } - - static void mptcp_check_fastclose(struct mptcp_sock *msk) -@@ -2513,15 +2558,15 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk) - /* Mirror the tcp_reset() error propagation */ - switch (sk->sk_state) { - case TCP_SYN_SENT: -- sk->sk_err = ECONNREFUSED; -+ WRITE_ONCE(sk->sk_err, ECONNREFUSED); - break; - case TCP_CLOSE_WAIT: -- sk->sk_err = EPIPE; -+ WRITE_ONCE(sk->sk_err, EPIPE); - break; - case TCP_CLOSE: - return; - default: -- sk->sk_err = ECONNRESET; -+ WRITE_ONCE(sk->sk_err, ECONNRESET); - } - - inet_sk_state_store(sk, TCP_CLOSE); -@@ -2597,27 +2642,28 @@ static void __mptcp_retrans(struct sock *sk) - reset_timer: - mptcp_check_and_set_pending(sk); - -- if (!mptcp_timer_pending(sk)) -- mptcp_reset_timer(sk); -+ if (!mptcp_rtx_timer_pending(sk)) -+ mptcp_reset_rtx_timer(sk); - } - - /* schedule the timeout timer for the relevant event: either close timeout - * or mp_fail timeout. The close timeout takes precedence on the mp_fail one - */ --void mptcp_reset_timeout(struct mptcp_sock *msk, unsigned long fail_tout) -+void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout) - { - struct sock *sk = (struct sock *)msk; - unsigned long timeout, close_timeout; - -- if (!fail_tout && !sock_flag(sk, SOCK_DEAD)) -+ if (!fail_tout && !inet_csk(sk)->icsk_mtup.probe_timestamp) - return; - -- close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies + TCP_TIMEWAIT_LEN; -+ close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies + -+ TCP_TIMEWAIT_LEN; - - /* the close timeout takes precedence on the fail one, and here at least one of - * them is active - */ -- timeout = sock_flag(sk, SOCK_DEAD) ? close_timeout : fail_tout; -+ timeout = inet_csk(sk)->icsk_mtup.probe_timestamp ? close_timeout : fail_tout; - - sk_reset_timer(sk, &sk->sk_timer, timeout); - } -@@ -2636,8 +2682,6 @@ static void mptcp_mp_fail_no_response(struct mptcp_sock *msk) - mptcp_subflow_reset(ssk); - WRITE_ONCE(mptcp_subflow_ctx(ssk)->fail_tout, 0); - unlock_sock_fast(ssk, slow); -- -- mptcp_reset_timeout(msk, 0); - } - - static void mptcp_do_fastclose(struct sock *sk) -@@ -2676,19 +2720,15 @@ static void mptcp_worker(struct work_struct *work) - if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags)) - __mptcp_close_subflow(sk); - -- /* There is no point in keeping around an orphaned sk timedout or -- * closed, but we need the msk around to reply to incoming DATA_FIN, -- * even if it is orphaned and in FIN_WAIT2 state -- */ -- if (sock_flag(sk, SOCK_DEAD)) { -- if (mptcp_should_close(sk)) { -- inet_sk_state_store(sk, TCP_CLOSE); -- mptcp_do_fastclose(sk); -- } -- if (sk->sk_state == TCP_CLOSE) { -- __mptcp_destroy_sock(sk); -- goto unlock; -- } -+ if (mptcp_close_tout_expired(sk)) { -+ inet_sk_state_store(sk, TCP_CLOSE); -+ mptcp_do_fastclose(sk); -+ mptcp_close_wake_up(sk); -+ } -+ -+ if (sock_flag(sk, SOCK_DEAD) && sk->sk_state == TCP_CLOSE) { -+ __mptcp_destroy_sock(sk); -+ goto unlock; - } - - if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) -@@ -2728,7 +2768,7 @@ static int __mptcp_init_sock(struct sock *sk) - - /* re-use the csk retrans timer for MPTCP-level retrans */ - timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0); -- timer_setup(&sk->sk_timer, mptcp_timeout_timer, 0); -+ timer_setup(&sk->sk_timer, mptcp_tout_timer, 0); - - return 0; - } -@@ -2820,8 +2860,8 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how) - } else { - pr_debug("Sending DATA_FIN on subflow %p", ssk); - tcp_send_ack(ssk); -- if (!mptcp_timer_pending(sk)) -- mptcp_reset_timer(sk); -+ if (!mptcp_rtx_timer_pending(sk)) -+ mptcp_reset_rtx_timer(sk); - } - break; - } -@@ -2904,7 +2944,7 @@ static void __mptcp_destroy_sock(struct sock *sk) - - might_sleep(); - -- mptcp_stop_timer(sk); -+ mptcp_stop_rtx_timer(sk); - sk_stop_timer(sk, &sk->sk_timer); - msk->pm.status = 0; - -@@ -2984,7 +3024,6 @@ bool __mptcp_close(struct sock *sk, long timeout) - - cleanup: - /* orphan all the subflows */ -- inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32; - mptcp_for_each_subflow(msk, subflow) { - struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast_nested(ssk); -@@ -3021,7 +3060,7 @@ cleanup: - __mptcp_destroy_sock(sk); - do_cancel_work = true; - } else { -- mptcp_reset_timeout(msk, 0); -+ mptcp_start_tout_timer(sk); - } - - return do_cancel_work; -@@ -3084,8 +3123,8 @@ static int mptcp_disconnect(struct sock *sk, int flags) - mptcp_check_listen_stop(sk); - inet_sk_state_store(sk, TCP_CLOSE); - -- mptcp_stop_timer(sk); -- sk_stop_timer(sk, &sk->sk_timer); -+ mptcp_stop_rtx_timer(sk); -+ mptcp_stop_tout_timer(sk); - - if (mptcp_sk(sk)->token) - mptcp_event(MPTCP_EVENT_CLOSED, mptcp_sk(sk), NULL, GFP_KERNEL); -@@ -3895,7 +3934,7 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock, - - /* This barrier is coupled with smp_wmb() in __mptcp_error_report() */ - smp_rmb(); -- if (sk->sk_err) -+ if (READ_ONCE(sk->sk_err)) - mask |= EPOLLERR; - - return mask; -diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h -index d77b25636125b..91d89a0aeb586 100644 ---- a/net/mptcp/protocol.h -+++ b/net/mptcp/protocol.h -@@ -681,7 +681,29 @@ void mptcp_get_options(const struct sk_buff *skb, - - void mptcp_finish_connect(struct sock *sk); - void __mptcp_set_connected(struct sock *sk); --void mptcp_reset_timeout(struct mptcp_sock *msk, unsigned long fail_tout); -+void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout); -+ -+static inline void mptcp_stop_tout_timer(struct sock *sk) -+{ -+ if (!inet_csk(sk)->icsk_mtup.probe_timestamp) -+ return; -+ -+ sk_stop_timer(sk, &sk->sk_timer); -+ inet_csk(sk)->icsk_mtup.probe_timestamp = 0; -+} -+ -+static inline void mptcp_set_close_tout(struct sock *sk, unsigned long tout) -+{ -+ /* avoid 0 timestamp, as that means no close timeout */ -+ inet_csk(sk)->icsk_mtup.probe_timestamp = tout ? : 1; -+} -+ -+static inline void mptcp_start_tout_timer(struct sock *sk) -+{ -+ mptcp_set_close_tout(sk, tcp_jiffies32); -+ mptcp_reset_tout_timer(mptcp_sk(sk), 0); -+} -+ - static inline bool mptcp_is_fully_established(struct sock *sk) - { - return inet_sk_state_load(sk) == TCP_ESTABLISHED && -diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c -index 52a747a80e88e..b93b08a75017b 100644 ---- a/net/mptcp/subflow.c -+++ b/net/mptcp/subflow.c -@@ -1161,7 +1161,7 @@ static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk) - WRITE_ONCE(subflow->fail_tout, fail_tout); - tcp_send_ack(ssk); - -- mptcp_reset_timeout(msk, subflow->fail_tout); -+ mptcp_reset_tout_timer(msk, subflow->fail_tout); - } - - static bool subflow_check_data_avail(struct sock *ssk) -@@ -1248,7 +1248,7 @@ fallback: - subflow->reset_reason = MPTCP_RST_EMPTCP; - - reset: -- ssk->sk_err = EBADMSG; -+ WRITE_ONCE(ssk->sk_err, EBADMSG); - tcp_set_state(ssk, TCP_CLOSE); - while ((skb = skb_peek(&ssk->sk_receive_queue))) - sk_eat_skb(ssk, skb); -@@ -1305,42 +1305,6 @@ void mptcp_space(const struct sock *ssk, int *space, int *full_space) - *full_space = tcp_full_space(sk); - } - --void __mptcp_error_report(struct sock *sk) --{ -- struct mptcp_subflow_context *subflow; -- struct mptcp_sock *msk = mptcp_sk(sk); -- -- mptcp_for_each_subflow(msk, subflow) { -- struct sock *ssk = mptcp_subflow_tcp_sock(subflow); -- int err = sock_error(ssk); -- int ssk_state; -- -- if (!err) -- continue; -- -- /* only propagate errors on fallen-back sockets or -- * on MPC connect -- */ -- if (sk->sk_state != TCP_SYN_SENT && !__mptcp_check_fallback(msk)) -- continue; -- -- /* We need to propagate only transition to CLOSE state. -- * Orphaned socket will see such state change via -- * subflow_sched_work_if_closed() and that path will properly -- * destroy the msk as needed. -- */ -- ssk_state = inet_sk_state_load(ssk); -- if (ssk_state == TCP_CLOSE && !sock_flag(sk, SOCK_DEAD)) -- inet_sk_state_store(sk, ssk_state); -- sk->sk_err = -err; -- -- /* This barrier is coupled with smp_rmb() in mptcp_poll() */ -- smp_wmb(); -- sk_error_report(sk); -- break; -- } --} -- - static void subflow_error_report(struct sock *ssk) - { - struct sock *sk = mptcp_subflow_ctx(ssk)->conn; -@@ -1527,6 +1491,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, - mptcp_sock_graft(ssk, sk->sk_socket); - iput(SOCK_INODE(sf)); - WRITE_ONCE(msk->allow_infinite_fallback, false); -+ mptcp_stop_tout_timer(sk); - return 0; - - failed_unlink: -diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c -index d4fe7bb4f853a..6574f4e651b1a 100644 ---- a/net/netfilter/ipvs/ip_vs_sync.c -+++ b/net/netfilter/ipvs/ip_vs_sync.c -@@ -1507,8 +1507,8 @@ static int make_send_sock(struct netns_ipvs *ipvs, int id, - } - - get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->mcfg, id); -- result = sock->ops->connect(sock, (struct sockaddr *) &mcast_addr, -- salen, 0); -+ result = kernel_connect(sock, (struct sockaddr *)&mcast_addr, -+ salen, 0); - if (result < 0) { - pr_err("Error connecting to the multicast addr\n"); - goto error; -diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c -index 7247af51bdfc4..c94a9971d790c 100644 ---- a/net/netfilter/nf_conntrack_proto_sctp.c -+++ b/net/netfilter/nf_conntrack_proto_sctp.c -@@ -112,7 +112,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = { - /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA}, - /* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't have Stale cookie*/ - /* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL},/* 5.2.4 - Big TODO */ --/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */ -+/* cookie_ack */ {sCL, sCL, sCW, sES, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */ - /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL}, - /* heartbeat */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, - /* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, -@@ -126,7 +126,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = { - /* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV}, - /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV}, - /* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV}, --/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */ -+/* cookie_echo */ {sIV, sCL, sCE, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */ - /* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV}, - /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV}, - /* heartbeat */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, -@@ -426,6 +426,9 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, - /* (D) vtag must be same as init_vtag as found in INIT_ACK */ - if (sh->vtag != ct->proto.sctp.vtag[dir]) - goto out_unlock; -+ } else if (sch->type == SCTP_CID_COOKIE_ACK) { -+ ct->proto.sctp.init[dir] = 0; -+ ct->proto.sctp.init[!dir] = 0; - } else if (sch->type == SCTP_CID_HEARTBEAT) { - if (ct->proto.sctp.vtag[dir] == 0) { - pr_debug("Setting %d vtag %x for dir %d\n", sch->type, sh->vtag, dir); -@@ -474,16 +477,18 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, - } - - /* If it is an INIT or an INIT ACK note down the vtag */ -- if (sch->type == SCTP_CID_INIT || -- sch->type == SCTP_CID_INIT_ACK) { -- struct sctp_inithdr _inithdr, *ih; -+ if (sch->type == SCTP_CID_INIT) { -+ struct sctp_inithdr _ih, *ih; - -- ih = skb_header_pointer(skb, offset + sizeof(_sch), -- sizeof(_inithdr), &_inithdr); -- if (ih == NULL) -+ ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih); -+ if (!ih) - goto out_unlock; -- pr_debug("Setting vtag %x for dir %d\n", -- ih->init_tag, !dir); -+ -+ if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir]) -+ ct->proto.sctp.init[!dir] = 0; -+ ct->proto.sctp.init[dir] = 1; -+ -+ pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); - ct->proto.sctp.vtag[!dir] = ih->init_tag; - - /* don't renew timeout on init retransmit so -@@ -494,6 +499,24 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, - old_state == SCTP_CONNTRACK_CLOSED && - nf_ct_is_confirmed(ct)) - ignore = true; -+ } else if (sch->type == SCTP_CID_INIT_ACK) { -+ struct sctp_inithdr _ih, *ih; -+ __be32 vtag; -+ -+ ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih); -+ if (!ih) -+ goto out_unlock; -+ -+ vtag = ct->proto.sctp.vtag[!dir]; -+ if (!ct->proto.sctp.init[!dir] && vtag && vtag != ih->init_tag) -+ goto out_unlock; -+ /* collision */ -+ if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir] && -+ vtag != ih->init_tag) -+ goto out_unlock; -+ -+ pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); -+ ct->proto.sctp.vtag[!dir] = ih->init_tag; - } - - ct->proto.sctp.state = new_state; -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 52b81dc1fcf5b..5e3dbe2652dbd 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -7576,24 +7576,14 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info, - return nft_delobj(&ctx, obj); - } - --void nft_obj_notify(struct net *net, const struct nft_table *table, -- struct nft_object *obj, u32 portid, u32 seq, int event, -- u16 flags, int family, int report, gfp_t gfp) -+static void -+__nft_obj_notify(struct net *net, const struct nft_table *table, -+ struct nft_object *obj, u32 portid, u32 seq, int event, -+ u16 flags, int family, int report, gfp_t gfp) - { - struct nftables_pernet *nft_net = nft_pernet(net); - struct sk_buff *skb; - int err; -- char *buf = kasprintf(gfp, "%s:%u", -- table->name, nft_net->base_seq); -- -- audit_log_nfcfg(buf, -- family, -- obj->handle, -- event == NFT_MSG_NEWOBJ ? -- AUDIT_NFT_OP_OBJ_REGISTER : -- AUDIT_NFT_OP_OBJ_UNREGISTER, -- gfp); -- kfree(buf); - - if (!report && - !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) -@@ -7616,13 +7606,35 @@ void nft_obj_notify(struct net *net, const struct nft_table *table, - err: - nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS); - } -+ -+void nft_obj_notify(struct net *net, const struct nft_table *table, -+ struct nft_object *obj, u32 portid, u32 seq, int event, -+ u16 flags, int family, int report, gfp_t gfp) -+{ -+ struct nftables_pernet *nft_net = nft_pernet(net); -+ char *buf = kasprintf(gfp, "%s:%u", -+ table->name, nft_net->base_seq); -+ -+ audit_log_nfcfg(buf, -+ family, -+ obj->handle, -+ event == NFT_MSG_NEWOBJ ? -+ AUDIT_NFT_OP_OBJ_REGISTER : -+ AUDIT_NFT_OP_OBJ_UNREGISTER, -+ gfp); -+ kfree(buf); -+ -+ __nft_obj_notify(net, table, obj, portid, seq, event, -+ flags, family, report, gfp); -+} - EXPORT_SYMBOL_GPL(nft_obj_notify); - - static void nf_tables_obj_notify(const struct nft_ctx *ctx, - struct nft_object *obj, int event) - { -- nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, -- ctx->flags, ctx->family, ctx->report, GFP_KERNEL); -+ __nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, -+ ctx->seq, event, ctx->flags, ctx->family, -+ ctx->report, GFP_KERNEL); - } - - /* -diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c -index 487572dcd6144..2660ceab3759d 100644 ---- a/net/netfilter/nft_set_rbtree.c -+++ b/net/netfilter/nft_set_rbtree.c -@@ -233,10 +233,9 @@ static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set, - rb_erase(&rbe->node, &priv->root); - } - --static int nft_rbtree_gc_elem(const struct nft_set *__set, -- struct nft_rbtree *priv, -- struct nft_rbtree_elem *rbe, -- u8 genmask) -+static const struct nft_rbtree_elem * -+nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv, -+ struct nft_rbtree_elem *rbe, u8 genmask) - { - struct nft_set *set = (struct nft_set *)__set; - struct rb_node *prev = rb_prev(&rbe->node); -@@ -246,7 +245,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, - - gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC); - if (!gc) -- return -ENOMEM; -+ return ERR_PTR(-ENOMEM); - - /* search for end interval coming before this element. - * end intervals don't carry a timeout extension, they -@@ -261,6 +260,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, - prev = rb_prev(prev); - } - -+ rbe_prev = NULL; - if (prev) { - rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); - nft_rbtree_gc_remove(net, set, priv, rbe_prev); -@@ -272,7 +272,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, - */ - gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); - if (WARN_ON_ONCE(!gc)) -- return -ENOMEM; -+ return ERR_PTR(-ENOMEM); - - nft_trans_gc_elem_add(gc, rbe_prev); - } -@@ -280,13 +280,13 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, - nft_rbtree_gc_remove(net, set, priv, rbe); - gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); - if (WARN_ON_ONCE(!gc)) -- return -ENOMEM; -+ return ERR_PTR(-ENOMEM); - - nft_trans_gc_elem_add(gc, rbe); - - nft_trans_gc_queue_sync_done(gc); - -- return 0; -+ return rbe_prev; - } - - static bool nft_rbtree_update_first(const struct nft_set *set, -@@ -314,7 +314,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, - struct nft_rbtree *priv = nft_set_priv(set); - u8 cur_genmask = nft_genmask_cur(net); - u8 genmask = nft_genmask_next(net); -- int d, err; -+ int d; - - /* Descend the tree to search for an existing element greater than the - * key value to insert that is greater than the new element. This is the -@@ -363,9 +363,14 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, - */ - if (nft_set_elem_expired(&rbe->ext) && - nft_set_elem_active(&rbe->ext, cur_genmask)) { -- err = nft_rbtree_gc_elem(set, priv, rbe, genmask); -- if (err < 0) -- return err; -+ const struct nft_rbtree_elem *removed_end; -+ -+ removed_end = nft_rbtree_gc_elem(set, priv, rbe, genmask); -+ if (IS_ERR(removed_end)) -+ return PTR_ERR(removed_end); -+ -+ if (removed_end == rbe_le || removed_end == rbe_ge) -+ return -EAGAIN; - - continue; - } -@@ -486,11 +491,18 @@ static int nft_rbtree_insert(const struct net *net, const struct nft_set *set, - struct nft_rbtree_elem *rbe = elem->priv; - int err; - -- write_lock_bh(&priv->lock); -- write_seqcount_begin(&priv->count); -- err = __nft_rbtree_insert(net, set, rbe, ext); -- write_seqcount_end(&priv->count); -- write_unlock_bh(&priv->lock); -+ do { -+ if (fatal_signal_pending(current)) -+ return -EINTR; -+ -+ cond_resched(); -+ -+ write_lock_bh(&priv->lock); -+ write_seqcount_begin(&priv->count); -+ err = __nft_rbtree_insert(net, set, rbe, ext); -+ write_seqcount_end(&priv->count); -+ write_unlock_bh(&priv->lock); -+ } while (err == -EAGAIN); - - return err; - } -diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c -index 387e430a35ccc..cb833302270a6 100644 ---- a/net/netlink/af_netlink.c -+++ b/net/netlink/af_netlink.c -@@ -352,7 +352,7 @@ static void netlink_overrun(struct sock *sk) - if (!nlk_test_bit(RECV_NO_ENOBUFS, sk)) { - if (!test_and_set_bit(NETLINK_S_CONGESTED, - &nlk_sk(sk)->state)) { -- sk->sk_err = ENOBUFS; -+ WRITE_ONCE(sk->sk_err, ENOBUFS); - sk_error_report(sk); - } - } -@@ -1566,7 +1566,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) - goto out; - } - -- sk->sk_err = p->code; -+ WRITE_ONCE(sk->sk_err, p->code); - sk_error_report(sk); - out: - return ret; -@@ -1955,7 +1955,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, - atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { - ret = netlink_dump(sk); - if (ret) { -- sk->sk_err = -ret; -+ WRITE_ONCE(sk->sk_err, -ret); - sk_error_report(sk); - } - } -@@ -2443,19 +2443,24 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, - flags |= NLM_F_ACK_TLVS; - - skb = nlmsg_new(payload + tlvlen, GFP_KERNEL); -- if (!skb) { -- NETLINK_CB(in_skb).sk->sk_err = ENOBUFS; -- sk_error_report(NETLINK_CB(in_skb).sk); -- return; -- } -+ if (!skb) -+ goto err_skb; - - rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, -- NLMSG_ERROR, payload, flags); -+ NLMSG_ERROR, sizeof(*errmsg), flags); -+ if (!rep) -+ goto err_bad_put; - errmsg = nlmsg_data(rep); - errmsg->error = err; -- unsafe_memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) -- ? nlh->nlmsg_len : sizeof(*nlh), -- /* Bounds checked by the skb layer. */); -+ errmsg->msg = *nlh; -+ -+ if (!(flags & NLM_F_CAPPED)) { -+ if (!nlmsg_append(skb, nlmsg_len(nlh))) -+ goto err_bad_put; -+ -+ memcpy(nlmsg_data(&errmsg->msg), nlmsg_data(nlh), -+ nlmsg_len(nlh)); -+ } - - if (tlvlen) - netlink_ack_tlv_fill(in_skb, skb, nlh, err, extack); -@@ -2463,6 +2468,14 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, - nlmsg_end(skb, rep); - - nlmsg_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid); -+ -+ return; -+ -+err_bad_put: -+ nlmsg_free(skb); -+err_skb: -+ WRITE_ONCE(NETLINK_CB(in_skb).sk->sk_err, ENOBUFS); -+ sk_error_report(NETLINK_CB(in_skb).sk); - } - EXPORT_SYMBOL(netlink_ack); - -diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c -index f60e424e06076..6705bb895e239 100644 ---- a/net/nfc/llcp_core.c -+++ b/net/nfc/llcp_core.c -@@ -1636,7 +1636,9 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) - timer_setup(&local->sdreq_timer, nfc_llcp_sdreq_timer, 0); - INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work); - -+ spin_lock(&llcp_devices_lock); - list_add(&local->list, &llcp_devices); -+ spin_unlock(&llcp_devices_lock); - - return 0; - } -diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c -index f0c477c5d1db4..d788c6d28986f 100644 ---- a/net/rds/tcp_connect.c -+++ b/net/rds/tcp_connect.c -@@ -173,7 +173,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp) - * own the socket - */ - rds_tcp_set_callbacks(sock, cp); -- ret = sock->ops->connect(sock, addr, addrlen, O_NONBLOCK); -+ ret = kernel_connect(sock, addr, addrlen, O_NONBLOCK); - - rdsdebug("connect to address %pI6c returned %d\n", &conn->c_faddr, ret); - if (ret == -EINPROGRESS) -diff --git a/net/sctp/associola.c b/net/sctp/associola.c -index 3460abceba443..2965a12fe8aa2 100644 ---- a/net/sctp/associola.c -+++ b/net/sctp/associola.c -@@ -1161,8 +1161,7 @@ int sctp_assoc_update(struct sctp_association *asoc, - /* Add any peer addresses from the new association. */ - list_for_each_entry(trans, &new->peer.transport_addr_list, - transports) -- if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr) && -- !sctp_assoc_add_peer(asoc, &trans->ipaddr, -+ if (!sctp_assoc_add_peer(asoc, &trans->ipaddr, - GFP_ATOMIC, trans->state)) - return -ENOMEM; - -diff --git a/net/sctp/socket.c b/net/sctp/socket.c -index 32e3669adf146..e25dc17091311 100644 ---- a/net/sctp/socket.c -+++ b/net/sctp/socket.c -@@ -2449,6 +2449,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, - if (trans) { - trans->hbinterval = - msecs_to_jiffies(params->spp_hbinterval); -+ sctp_transport_reset_hb_timer(trans); - } else if (asoc) { - asoc->hbinterval = - msecs_to_jiffies(params->spp_hbinterval); -diff --git a/net/socket.c b/net/socket.c -index d281a7ef4b1d3..b0169168e3f4e 100644 ---- a/net/socket.c -+++ b/net/socket.c -@@ -720,6 +720,14 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) - return ret; - } - -+static int __sock_sendmsg(struct socket *sock, struct msghdr *msg) -+{ -+ int err = security_socket_sendmsg(sock, msg, -+ msg_data_left(msg)); -+ -+ return err ?: sock_sendmsg_nosec(sock, msg); -+} -+ - /** - * sock_sendmsg - send a message through @sock - * @sock: socket -@@ -730,10 +738,19 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) - */ - int sock_sendmsg(struct socket *sock, struct msghdr *msg) - { -- int err = security_socket_sendmsg(sock, msg, -- msg_data_left(msg)); -+ struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name; -+ struct sockaddr_storage address; -+ int ret; - -- return err ?: sock_sendmsg_nosec(sock, msg); -+ if (msg->msg_name) { -+ memcpy(&address, msg->msg_name, msg->msg_namelen); -+ msg->msg_name = &address; -+ } -+ -+ ret = __sock_sendmsg(sock, msg); -+ msg->msg_name = save_addr; -+ -+ return ret; - } - EXPORT_SYMBOL(sock_sendmsg); - -@@ -1110,7 +1127,7 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from) - if (sock->type == SOCK_SEQPACKET) - msg.msg_flags |= MSG_EOR; - -- res = sock_sendmsg(sock, &msg); -+ res = __sock_sendmsg(sock, &msg); - *from = msg.msg_iter; - return res; - } -@@ -2114,7 +2131,7 @@ int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags, - if (sock->file->f_flags & O_NONBLOCK) - flags |= MSG_DONTWAIT; - msg.msg_flags = flags; -- err = sock_sendmsg(sock, &msg); -+ err = __sock_sendmsg(sock, &msg); - - out_put: - fput_light(sock->file, fput_needed); -@@ -2479,7 +2496,7 @@ static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys, - err = sock_sendmsg_nosec(sock, msg_sys); - goto out_freectl; - } -- err = sock_sendmsg(sock, msg_sys); -+ err = __sock_sendmsg(sock, msg_sys); - /* - * If this is sendmmsg() and sending to current destination address was - * successful, remember it. -diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c -index 2b236d95a6469..65f59739a041a 100644 ---- a/net/tipc/crypto.c -+++ b/net/tipc/crypto.c -@@ -1441,14 +1441,14 @@ static int tipc_crypto_key_revoke(struct net *net, u8 tx_key) - struct tipc_crypto *tx = tipc_net(net)->crypto_tx; - struct tipc_key key; - -- spin_lock(&tx->lock); -+ spin_lock_bh(&tx->lock); - key = tx->key; - WARN_ON(!key.active || tx_key != key.active); - - /* Free the active key */ - tipc_crypto_key_set_state(tx, key.passive, 0, key.pending); - tipc_crypto_key_detach(tx->aead[key.active], &tx->lock); -- spin_unlock(&tx->lock); -+ spin_unlock_bh(&tx->lock); - - pr_warn("%s: key is revoked\n", tx->name); - return -EKEYREVOKED; -diff --git a/net/wireless/core.c b/net/wireless/core.c -index 609b79fe4a748..2c79604672062 100644 ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -408,6 +408,34 @@ static void cfg80211_propagate_cac_done_wk(struct work_struct *work) - rtnl_unlock(); - } - -+static void cfg80211_wiphy_work(struct work_struct *work) -+{ -+ struct cfg80211_registered_device *rdev; -+ struct wiphy_work *wk; -+ -+ rdev = container_of(work, struct cfg80211_registered_device, wiphy_work); -+ -+ wiphy_lock(&rdev->wiphy); -+ if (rdev->suspended) -+ goto out; -+ -+ spin_lock_irq(&rdev->wiphy_work_lock); -+ wk = list_first_entry_or_null(&rdev->wiphy_work_list, -+ struct wiphy_work, entry); -+ if (wk) { -+ list_del_init(&wk->entry); -+ if (!list_empty(&rdev->wiphy_work_list)) -+ schedule_work(work); -+ spin_unlock_irq(&rdev->wiphy_work_lock); -+ -+ wk->func(&rdev->wiphy, wk); -+ } else { -+ spin_unlock_irq(&rdev->wiphy_work_lock); -+ } -+out: -+ wiphy_unlock(&rdev->wiphy); -+} -+ - /* exported functions */ - - struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, -@@ -533,6 +561,9 @@ use_default_name: - return NULL; - } - -+ INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work); -+ INIT_LIST_HEAD(&rdev->wiphy_work_list); -+ spin_lock_init(&rdev->wiphy_work_lock); - INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); - INIT_WORK(&rdev->conn_work, cfg80211_conn_work); - INIT_WORK(&rdev->event_work, cfg80211_event_work); -@@ -1011,6 +1042,31 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy) - } - EXPORT_SYMBOL(wiphy_rfkill_start_polling); - -+void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev) -+{ -+ unsigned int runaway_limit = 100; -+ unsigned long flags; -+ -+ lockdep_assert_held(&rdev->wiphy.mtx); -+ -+ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); -+ while (!list_empty(&rdev->wiphy_work_list)) { -+ struct wiphy_work *wk; -+ -+ wk = list_first_entry(&rdev->wiphy_work_list, -+ struct wiphy_work, entry); -+ list_del_init(&wk->entry); -+ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); -+ -+ wk->func(&rdev->wiphy, wk); -+ -+ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); -+ if (WARN_ON(--runaway_limit == 0)) -+ INIT_LIST_HEAD(&rdev->wiphy_work_list); -+ } -+ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); -+} -+ - void wiphy_unregister(struct wiphy *wiphy) - { - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -@@ -1049,9 +1105,19 @@ void wiphy_unregister(struct wiphy *wiphy) - cfg80211_rdev_list_generation++; - device_del(&rdev->wiphy.dev); - -+#ifdef CONFIG_PM -+ if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) -+ rdev_set_wakeup(rdev, false); -+#endif -+ -+ /* surely nothing is reachable now, clean up work */ -+ cfg80211_process_wiphy_works(rdev); - wiphy_unlock(&rdev->wiphy); - rtnl_unlock(); - -+ /* this has nothing to do now but make sure it's gone */ -+ cancel_work_sync(&rdev->wiphy_work); -+ - flush_work(&rdev->scan_done_wk); - cancel_work_sync(&rdev->conn_work); - flush_work(&rdev->event_work); -@@ -1064,10 +1130,6 @@ void wiphy_unregister(struct wiphy *wiphy) - flush_work(&rdev->mgmt_registrations_update_wk); - flush_work(&rdev->background_cac_abort_wk); - --#ifdef CONFIG_PM -- if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) -- rdev_set_wakeup(rdev, false); --#endif - cfg80211_rdev_free_wowlan(rdev); - cfg80211_rdev_free_coalesce(rdev); - } -@@ -1114,16 +1176,11 @@ void wiphy_rfkill_set_hw_state_reason(struct wiphy *wiphy, bool blocked, - } - EXPORT_SYMBOL(wiphy_rfkill_set_hw_state_reason); - --void cfg80211_cqm_config_free(struct wireless_dev *wdev) --{ -- kfree(wdev->cqm_config); -- wdev->cqm_config = NULL; --} -- - static void _cfg80211_unregister_wdev(struct wireless_dev *wdev, - bool unregister_netdev) - { - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+ struct cfg80211_cqm_config *cqm_config; - unsigned int link_id; - - ASSERT_RTNL(); -@@ -1162,11 +1219,10 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev, - kfree_sensitive(wdev->wext.keys); - wdev->wext.keys = NULL; - #endif -- /* only initialized if we have a netdev */ -- if (wdev->netdev) -- flush_work(&wdev->disconnect_wk); -- -- cfg80211_cqm_config_free(wdev); -+ wiphy_work_cancel(wdev->wiphy, &wdev->cqm_rssi_work); -+ /* deleted from the list, so can't be found from nl80211 any more */ -+ cqm_config = rcu_access_pointer(wdev->cqm_config); -+ kfree_rcu(cqm_config, rcu_head); - - /* - * Ensure that all events have been processed and -@@ -1318,6 +1374,8 @@ void cfg80211_init_wdev(struct wireless_dev *wdev) - wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; - #endif - -+ wiphy_work_init(&wdev->cqm_rssi_work, cfg80211_cqm_rssi_notify_work); -+ - if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT) - wdev->ps = true; - else -@@ -1439,6 +1497,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, - cfg80211_leave(rdev, wdev); - cfg80211_remove_links(wdev); - wiphy_unlock(&rdev->wiphy); -+ /* since we just did cfg80211_leave() nothing to do there */ -+ cancel_work_sync(&wdev->disconnect_wk); - break; - case NETDEV_DOWN: - wiphy_lock(&rdev->wiphy); -@@ -1548,6 +1608,66 @@ static struct pernet_operations cfg80211_pernet_ops = { - .exit = cfg80211_pernet_exit, - }; - -+void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work) -+{ -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); -+ if (list_empty(&work->entry)) -+ list_add_tail(&work->entry, &rdev->wiphy_work_list); -+ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); -+ -+ schedule_work(&rdev->wiphy_work); -+} -+EXPORT_SYMBOL_GPL(wiphy_work_queue); -+ -+void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work) -+{ -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ unsigned long flags; -+ -+ lockdep_assert_held(&wiphy->mtx); -+ -+ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); -+ if (!list_empty(&work->entry)) -+ list_del_init(&work->entry); -+ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); -+} -+EXPORT_SYMBOL_GPL(wiphy_work_cancel); -+ -+void wiphy_delayed_work_timer(struct timer_list *t) -+{ -+ struct wiphy_delayed_work *dwork = from_timer(dwork, t, timer); -+ -+ wiphy_work_queue(dwork->wiphy, &dwork->work); -+} -+EXPORT_SYMBOL(wiphy_delayed_work_timer); -+ -+void wiphy_delayed_work_queue(struct wiphy *wiphy, -+ struct wiphy_delayed_work *dwork, -+ unsigned long delay) -+{ -+ if (!delay) { -+ wiphy_work_queue(wiphy, &dwork->work); -+ return; -+ } -+ -+ dwork->wiphy = wiphy; -+ mod_timer(&dwork->timer, jiffies + delay); -+} -+EXPORT_SYMBOL_GPL(wiphy_delayed_work_queue); -+ -+void wiphy_delayed_work_cancel(struct wiphy *wiphy, -+ struct wiphy_delayed_work *dwork) -+{ -+ lockdep_assert_held(&wiphy->mtx); -+ -+ del_timer_sync(&dwork->timer); -+ wiphy_work_cancel(wiphy, &dwork->work); -+} -+EXPORT_SYMBOL_GPL(wiphy_delayed_work_cancel); -+ - static int __init cfg80211_init(void) - { - int err; -diff --git a/net/wireless/core.h b/net/wireless/core.h -index 775e16cb99eda..86fd79912254d 100644 ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -108,6 +108,12 @@ struct cfg80211_registered_device { - /* lock for all wdev lists */ - spinlock_t mgmt_registrations_lock; - -+ struct work_struct wiphy_work; -+ struct list_head wiphy_work_list; -+ /* protects the list above */ -+ spinlock_t wiphy_work_lock; -+ bool suspended; -+ - /* must be last because of the way we do wiphy_priv(), - * and it should at least be aligned to NETDEV_ALIGN */ - struct wiphy wiphy __aligned(NETDEV_ALIGN); -@@ -287,12 +293,17 @@ struct cfg80211_beacon_registration { - }; - - struct cfg80211_cqm_config { -+ struct rcu_head rcu_head; - u32 rssi_hyst; - s32 last_rssi_event_value; -+ enum nl80211_cqm_rssi_threshold_event last_rssi_event_type; - int n_rssi_thresholds; - s32 rssi_thresholds[]; - }; - -+void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, -+ struct wiphy_work *work); -+ - void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev); - - /* free object */ -@@ -450,6 +461,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, - struct net_device *dev, enum nl80211_iftype ntype, - struct vif_params *params); - void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); -+void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev); - void cfg80211_process_wdev_events(struct wireless_dev *wdev); - - bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, -@@ -556,8 +568,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, - #define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; }) - #endif - --void cfg80211_cqm_config_free(struct wireless_dev *wdev); -- - void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid); - void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev); - void cfg80211_pmsr_free_wk(struct work_struct *work); -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index 12c7c89d5be1d..1d993a490ac4b 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -12565,7 +12565,8 @@ static int nl80211_set_cqm_txe(struct genl_info *info, - } - - static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, -- struct net_device *dev) -+ struct net_device *dev, -+ struct cfg80211_cqm_config *cqm_config) - { - struct wireless_dev *wdev = dev->ieee80211_ptr; - s32 last, low, high; -@@ -12574,7 +12575,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, - int err; - - /* RSSI reporting disabled? */ -- if (!wdev->cqm_config) -+ if (!cqm_config) - return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); - - /* -@@ -12583,7 +12584,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, - * connection is established and enough beacons received to calculate - * the average. - */ -- if (!wdev->cqm_config->last_rssi_event_value && -+ if (!cqm_config->last_rssi_event_value && - wdev->links[0].client.current_bss && - rdev->ops->get_station) { - struct station_info sinfo = {}; -@@ -12597,30 +12598,30 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, - - cfg80211_sinfo_release_content(&sinfo); - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG)) -- wdev->cqm_config->last_rssi_event_value = -+ cqm_config->last_rssi_event_value = - (s8) sinfo.rx_beacon_signal_avg; - } - -- last = wdev->cqm_config->last_rssi_event_value; -- hyst = wdev->cqm_config->rssi_hyst; -- n = wdev->cqm_config->n_rssi_thresholds; -+ last = cqm_config->last_rssi_event_value; -+ hyst = cqm_config->rssi_hyst; -+ n = cqm_config->n_rssi_thresholds; - - for (i = 0; i < n; i++) { - i = array_index_nospec(i, n); -- if (last < wdev->cqm_config->rssi_thresholds[i]) -+ if (last < cqm_config->rssi_thresholds[i]) - break; - } - - low_index = i - 1; - if (low_index >= 0) { - low_index = array_index_nospec(low_index, n); -- low = wdev->cqm_config->rssi_thresholds[low_index] - hyst; -+ low = cqm_config->rssi_thresholds[low_index] - hyst; - } else { - low = S32_MIN; - } - if (i < n) { - i = array_index_nospec(i, n); -- high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1; -+ high = cqm_config->rssi_thresholds[i] + hyst - 1; - } else { - high = S32_MAX; - } -@@ -12633,6 +12634,7 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - u32 hysteresis) - { - struct cfg80211_registered_device *rdev = info->user_ptr[0]; -+ struct cfg80211_cqm_config *cqm_config = NULL, *old; - struct net_device *dev = info->user_ptr[1]; - struct wireless_dev *wdev = dev->ieee80211_ptr; - int i, err; -@@ -12650,10 +12652,6 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) - return -EOPNOTSUPP; - -- wdev_lock(wdev); -- cfg80211_cqm_config_free(wdev); -- wdev_unlock(wdev); -- - if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) { - if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */ - return rdev_set_cqm_rssi_config(rdev, dev, 0, 0); -@@ -12670,9 +12668,10 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - n_thresholds = 0; - - wdev_lock(wdev); -- if (n_thresholds) { -- struct cfg80211_cqm_config *cqm_config; -+ old = rcu_dereference_protected(wdev->cqm_config, -+ lockdep_is_held(&wdev->mtx)); - -+ if (n_thresholds) { - cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, - n_thresholds), - GFP_KERNEL); -@@ -12687,11 +12686,18 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - flex_array_size(cqm_config, rssi_thresholds, - n_thresholds)); - -- wdev->cqm_config = cqm_config; -+ rcu_assign_pointer(wdev->cqm_config, cqm_config); -+ } else { -+ RCU_INIT_POINTER(wdev->cqm_config, NULL); - } - -- err = cfg80211_cqm_rssi_update(rdev, dev); -- -+ err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); -+ if (err) { -+ rcu_assign_pointer(wdev->cqm_config, old); -+ kfree_rcu(cqm_config, rcu_head); -+ } else { -+ kfree_rcu(old, rcu_head); -+ } - unlock: - wdev_unlock(wdev); - -@@ -18719,9 +18725,8 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, - enum nl80211_cqm_rssi_threshold_event rssi_event, - s32 rssi_level, gfp_t gfp) - { -- struct sk_buff *msg; - struct wireless_dev *wdev = dev->ieee80211_ptr; -- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+ struct cfg80211_cqm_config *cqm_config; - - trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level); - -@@ -18729,18 +18734,41 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, - rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)) - return; - -- if (wdev->cqm_config) { -- wdev->cqm_config->last_rssi_event_value = rssi_level; -+ rcu_read_lock(); -+ cqm_config = rcu_dereference(wdev->cqm_config); -+ if (cqm_config) { -+ cqm_config->last_rssi_event_value = rssi_level; -+ cqm_config->last_rssi_event_type = rssi_event; -+ wiphy_work_queue(wdev->wiphy, &wdev->cqm_rssi_work); -+ } -+ rcu_read_unlock(); -+} -+EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); -+ -+void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work) -+{ -+ struct wireless_dev *wdev = container_of(work, struct wireless_dev, -+ cqm_rssi_work); -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ enum nl80211_cqm_rssi_threshold_event rssi_event; -+ struct cfg80211_cqm_config *cqm_config; -+ struct sk_buff *msg; -+ s32 rssi_level; - -- cfg80211_cqm_rssi_update(rdev, dev); -+ wdev_lock(wdev); -+ cqm_config = rcu_dereference_protected(wdev->cqm_config, -+ lockdep_is_held(&wdev->mtx)); -+ if (!wdev->cqm_config) -+ goto unlock; - -- if (rssi_level == 0) -- rssi_level = wdev->cqm_config->last_rssi_event_value; -- } -+ cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); - -- msg = cfg80211_prepare_cqm(dev, NULL, gfp); -+ rssi_level = cqm_config->last_rssi_event_value; -+ rssi_event = cqm_config->last_rssi_event_type; -+ -+ msg = cfg80211_prepare_cqm(wdev->netdev, NULL, GFP_KERNEL); - if (!msg) -- return; -+ goto unlock; - - if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, - rssi_event)) -@@ -18750,14 +18778,15 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, - rssi_level)) - goto nla_put_failure; - -- cfg80211_send_cqm(msg, gfp); -+ cfg80211_send_cqm(msg, GFP_KERNEL); - -- return; -+ goto unlock; - - nla_put_failure: - nlmsg_free(msg); -+ unlock: -+ wdev_unlock(wdev); - } --EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); - - void cfg80211_cqm_txe_notify(struct net_device *dev, - const u8 *peer, u32 num_packets, -diff --git a/net/wireless/sme.c b/net/wireless/sme.c -index 6e87d2cd83456..b97834284baef 100644 ---- a/net/wireless/sme.c -+++ b/net/wireless/sme.c -@@ -5,7 +5,7 @@ - * (for nl80211's connect() and wext) - * - * Copyright 2009 Johannes Berg -- * Copyright (C) 2009, 2020, 2022 Intel Corporation. All rights reserved. -+ * Copyright (C) 2009, 2020, 2022-2023 Intel Corporation. All rights reserved. - * Copyright 2017 Intel Deutschland GmbH - */ - -@@ -1555,6 +1555,7 @@ void cfg80211_autodisconnect_wk(struct work_struct *work) - container_of(work, struct wireless_dev, disconnect_wk); - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); - -+ wiphy_lock(wdev->wiphy); - wdev_lock(wdev); - - if (wdev->conn_owner_nlportid) { -@@ -1593,4 +1594,5 @@ void cfg80211_autodisconnect_wk(struct work_struct *work) - } - - wdev_unlock(wdev); -+ wiphy_unlock(wdev->wiphy); - } -diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c -index 0c3f05c9be27a..4d3b658030105 100644 ---- a/net/wireless/sysfs.c -+++ b/net/wireless/sysfs.c -@@ -5,7 +5,7 @@ - * - * Copyright 2005-2006 Jiri Benc - * Copyright 2006 Johannes Berg -- * Copyright (C) 2020-2021 Intel Corporation -+ * Copyright (C) 2020-2021, 2023 Intel Corporation - */ - - #include -@@ -105,14 +105,18 @@ static int wiphy_suspend(struct device *dev) - cfg80211_leave_all(rdev); - cfg80211_process_rdev_events(rdev); - } -+ cfg80211_process_wiphy_works(rdev); - if (rdev->ops->suspend) - ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); - if (ret == 1) { - /* Driver refuse to configure wowlan */ - cfg80211_leave_all(rdev); - cfg80211_process_rdev_events(rdev); -+ cfg80211_process_wiphy_works(rdev); - ret = rdev_suspend(rdev, NULL); - } -+ if (ret == 0) -+ rdev->suspended = true; - } - wiphy_unlock(&rdev->wiphy); - rtnl_unlock(); -@@ -132,6 +136,8 @@ static int wiphy_resume(struct device *dev) - wiphy_lock(&rdev->wiphy); - if (rdev->wiphy.registered && rdev->ops->resume) - ret = rdev_resume(rdev); -+ rdev->suspended = false; -+ schedule_work(&rdev->wiphy_work); - wiphy_unlock(&rdev->wiphy); - - if (ret) -diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c -index 80d973144fded..111d5464c12df 100644 ---- a/scripts/mod/file2alias.c -+++ b/scripts/mod/file2alias.c -@@ -1577,7 +1577,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, - /* First handle the "special" cases */ - if (sym_is(name, namelen, "usb")) - do_usb_table(symval, sym->st_size, mod); -- if (sym_is(name, namelen, "of")) -+ else if (sym_is(name, namelen, "of")) - do_of_table(symval, sym->st_size, mod); - else if (sym_is(name, namelen, "pnp")) - do_pnp_device_entry(symval, sym->st_size, mod); -diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig -index c17660bf5f347..6ef7bde551263 100644 ---- a/security/integrity/ima/Kconfig -+++ b/security/integrity/ima/Kconfig -@@ -29,9 +29,11 @@ config IMA - to learn more about IMA. - If unsure, say N. - -+if IMA -+ - config IMA_KEXEC - bool "Enable carrying the IMA measurement list across a soft boot" -- depends on IMA && TCG_TPM && HAVE_IMA_KEXEC -+ depends on TCG_TPM && HAVE_IMA_KEXEC - default n - help - TPM PCRs are only reset on a hard reboot. In order to validate -@@ -43,7 +45,6 @@ config IMA_KEXEC - - config IMA_MEASURE_PCR_IDX - int -- depends on IMA - range 8 14 - default 10 - help -@@ -53,7 +54,7 @@ config IMA_MEASURE_PCR_IDX - - config IMA_LSM_RULES - bool -- depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR) -+ depends on AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR) - default y - help - Disabling this option will disregard LSM based policy rules. -@@ -61,7 +62,6 @@ config IMA_LSM_RULES - choice - prompt "Default template" - default IMA_NG_TEMPLATE -- depends on IMA - help - Select the default IMA measurement template. - -@@ -80,14 +80,12 @@ endchoice - - config IMA_DEFAULT_TEMPLATE - string -- depends on IMA - default "ima-ng" if IMA_NG_TEMPLATE - default "ima-sig" if IMA_SIG_TEMPLATE - - choice - prompt "Default integrity hash algorithm" - default IMA_DEFAULT_HASH_SHA1 -- depends on IMA - help - Select the default hash algorithm used for the measurement - list, integrity appraisal and audit log. The compiled default -@@ -117,7 +115,6 @@ endchoice - - config IMA_DEFAULT_HASH - string -- depends on IMA - default "sha1" if IMA_DEFAULT_HASH_SHA1 - default "sha256" if IMA_DEFAULT_HASH_SHA256 - default "sha512" if IMA_DEFAULT_HASH_SHA512 -@@ -126,7 +123,6 @@ config IMA_DEFAULT_HASH - - config IMA_WRITE_POLICY - bool "Enable multiple writes to the IMA policy" -- depends on IMA - default n - help - IMA policy can now be updated multiple times. The new rules get -@@ -137,7 +133,6 @@ config IMA_WRITE_POLICY - - config IMA_READ_POLICY - bool "Enable reading back the current IMA policy" -- depends on IMA - default y if IMA_WRITE_POLICY - default n if !IMA_WRITE_POLICY - help -@@ -147,7 +142,6 @@ config IMA_READ_POLICY - - config IMA_APPRAISE - bool "Appraise integrity measurements" -- depends on IMA - default n - help - This option enables local measurement integrity appraisal. -@@ -268,7 +262,7 @@ config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY - config IMA_BLACKLIST_KEYRING - bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)" - depends on SYSTEM_TRUSTED_KEYRING -- depends on IMA_TRUSTED_KEYRING -+ depends on INTEGRITY_TRUSTED_KEYRING - default n - help - This option creates an IMA blacklist keyring, which contains all -@@ -278,7 +272,7 @@ config IMA_BLACKLIST_KEYRING - - config IMA_LOAD_X509 - bool "Load X509 certificate onto the '.ima' trusted keyring" -- depends on IMA_TRUSTED_KEYRING -+ depends on INTEGRITY_TRUSTED_KEYRING - default n - help - File signature verification is based on the public keys -@@ -303,7 +297,6 @@ config IMA_APPRAISE_SIGNED_INIT - - config IMA_MEASURE_ASYMMETRIC_KEYS - bool -- depends on IMA - depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y - default y - -@@ -322,7 +315,8 @@ config IMA_SECURE_AND_OR_TRUSTED_BOOT - - config IMA_DISABLE_HTABLE - bool "Disable htable to allow measurement of duplicate records" -- depends on IMA - default n - help - This option disables htable to allow measurement of duplicate records. -+ -+endif -diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c -index a4dba0b751e76..1bbd1d077dfd9 100644 ---- a/sound/soc/soc-utils.c -+++ b/sound/soc/soc-utils.c -@@ -217,6 +217,7 @@ int snd_soc_dai_is_dummy(struct snd_soc_dai *dai) - return 1; - return 0; - } -+EXPORT_SYMBOL_GPL(snd_soc_dai_is_dummy); - - int snd_soc_component_is_dummy(struct snd_soc_component *component) - { -diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c -index 1f2c5018bf5ac..4737e776d3837 100644 ---- a/sound/soc/tegra/tegra_audio_graph_card.c -+++ b/sound/soc/tegra/tegra_audio_graph_card.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #define MAX_PLLA_OUT0_DIV 128 - -@@ -44,6 +45,21 @@ struct tegra_audio_cdata { - unsigned int plla_out0_rates[NUM_RATE_TYPE]; - }; - -+static bool need_clk_update(struct snd_soc_dai *dai) -+{ -+ if (snd_soc_dai_is_dummy(dai) || -+ !dai->driver->ops || -+ !dai->driver->name) -+ return false; -+ -+ if (strstr(dai->driver->name, "I2S") || -+ strstr(dai->driver->name, "DMIC") || -+ strstr(dai->driver->name, "DSPK")) -+ return true; -+ -+ return false; -+} -+ - /* Setup PLL clock as per the given sample rate */ - static int tegra_audio_graph_update_pll(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -@@ -140,19 +156,7 @@ static int tegra_audio_graph_hw_params(struct snd_pcm_substream *substream, - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int err; - -- /* -- * This gets called for each DAI link (FE or BE) when DPCM is used. -- * We may not want to update PLLA rate for each call. So PLLA update -- * must be restricted to external I/O links (I2S, DMIC or DSPK) since -- * they actually depend on it. I/O modules update their clocks in -- * hw_param() of their respective component driver and PLLA rate -- * update here helps them to derive appropriate rates. -- * -- * TODO: When more HW accelerators get added (like sample rate -- * converter, volume gain controller etc., which don't really -- * depend on PLLA) we need a better way to filter here. -- */ -- if (cpu_dai->driver->ops && rtd->dai_link->no_pcm) { -+ if (need_clk_update(cpu_dai)) { - err = tegra_audio_graph_update_pll(substream, params); - if (err) - return err; -diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h -index 53bc487947197..92dbe89dafbf5 100644 ---- a/tools/include/uapi/linux/bpf.h -+++ b/tools/include/uapi/linux/bpf.h -@@ -3112,6 +3112,11 @@ union bpf_attr { - * **BPF_FIB_LOOKUP_OUTPUT** - * Perform lookup from an egress perspective (default is - * ingress). -+ * **BPF_FIB_LOOKUP_SKIP_NEIGH** -+ * Skip the neighbour table lookup. *params*->dmac -+ * and *params*->smac will not be set as output. A common -+ * use case is to call **bpf_redirect_neigh**\ () after -+ * doing **bpf_fib_lookup**\ (). - * - * *ctx* is either **struct xdp_md** for XDP programs or - * **struct sk_buff** tc cls_act programs. -@@ -6678,6 +6683,7 @@ struct bpf_raw_tracepoint_args { - enum { - BPF_FIB_LOOKUP_DIRECT = (1U << 0), - BPF_FIB_LOOKUP_OUTPUT = (1U << 1), -+ BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2), - }; - - enum { -diff --git a/tools/testing/selftests/netfilter/.gitignore b/tools/testing/selftests/netfilter/.gitignore -index 4cb887b574138..4b2928e1c19d8 100644 ---- a/tools/testing/selftests/netfilter/.gitignore -+++ b/tools/testing/selftests/netfilter/.gitignore -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0-only - nf-queue - connect_close -+audit_logread -diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile -index 3686bfa6c58d7..321db8850da00 100644 ---- a/tools/testing/selftests/netfilter/Makefile -+++ b/tools/testing/selftests/netfilter/Makefile -@@ -6,13 +6,13 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \ - nft_concat_range.sh nft_conntrack_helper.sh \ - nft_queue.sh nft_meta.sh nf_nat_edemux.sh \ - ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ -- conntrack_vrf.sh nft_synproxy.sh rpath.sh -+ conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh - - HOSTPKG_CONFIG := pkg-config - - CFLAGS += $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null) - LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) - --TEST_GEN_FILES = nf-queue connect_close -+TEST_GEN_FILES = nf-queue connect_close audit_logread - - include ../lib.mk -diff --git a/tools/testing/selftests/netfilter/audit_logread.c b/tools/testing/selftests/netfilter/audit_logread.c -new file mode 100644 -index 0000000000000..a0a880fc2d9de ---- /dev/null -+++ b/tools/testing/selftests/netfilter/audit_logread.c -@@ -0,0 +1,165 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int fd; -+ -+#define MAX_AUDIT_MESSAGE_LENGTH 8970 -+struct audit_message { -+ struct nlmsghdr nlh; -+ union { -+ struct audit_status s; -+ char data[MAX_AUDIT_MESSAGE_LENGTH]; -+ } u; -+}; -+ -+int audit_recv(int fd, struct audit_message *rep) -+{ -+ struct sockaddr_nl addr; -+ socklen_t addrlen = sizeof(addr); -+ int ret; -+ -+ do { -+ ret = recvfrom(fd, rep, sizeof(*rep), 0, -+ (struct sockaddr *)&addr, &addrlen); -+ } while (ret < 0 && errno == EINTR); -+ -+ if (ret < 0 || -+ addrlen != sizeof(addr) || -+ addr.nl_pid != 0 || -+ rep->nlh.nlmsg_type == NLMSG_ERROR) /* short-cut for now */ -+ return -1; -+ -+ return ret; -+} -+ -+int audit_send(int fd, uint16_t type, uint32_t key, uint32_t val) -+{ -+ static int seq = 0; -+ struct audit_message msg = { -+ .nlh = { -+ .nlmsg_len = NLMSG_SPACE(sizeof(msg.u.s)), -+ .nlmsg_type = type, -+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, -+ .nlmsg_seq = ++seq, -+ }, -+ .u.s = { -+ .mask = key, -+ .enabled = key == AUDIT_STATUS_ENABLED ? val : 0, -+ .pid = key == AUDIT_STATUS_PID ? val : 0, -+ } -+ }; -+ struct sockaddr_nl addr = { -+ .nl_family = AF_NETLINK, -+ }; -+ int ret; -+ -+ do { -+ ret = sendto(fd, &msg, msg.nlh.nlmsg_len, 0, -+ (struct sockaddr *)&addr, sizeof(addr)); -+ } while (ret < 0 && errno == EINTR); -+ -+ if (ret != (int)msg.nlh.nlmsg_len) -+ return -1; -+ return 0; -+} -+ -+int audit_set(int fd, uint32_t key, uint32_t val) -+{ -+ struct audit_message rep = { 0 }; -+ int ret; -+ -+ ret = audit_send(fd, AUDIT_SET, key, val); -+ if (ret) -+ return ret; -+ -+ ret = audit_recv(fd, &rep); -+ if (ret < 0) -+ return ret; -+ return 0; -+} -+ -+int readlog(int fd) -+{ -+ struct audit_message rep = { 0 }; -+ int ret = audit_recv(fd, &rep); -+ const char *sep = ""; -+ char *k, *v; -+ -+ if (ret < 0) -+ return ret; -+ -+ if (rep.nlh.nlmsg_type != AUDIT_NETFILTER_CFG) -+ return 0; -+ -+ /* skip the initial "audit(...): " part */ -+ strtok(rep.u.data, " "); -+ -+ while ((k = strtok(NULL, "="))) { -+ v = strtok(NULL, " "); -+ -+ /* these vary and/or are uninteresting, ignore */ -+ if (!strcmp(k, "pid") || -+ !strcmp(k, "comm") || -+ !strcmp(k, "subj")) -+ continue; -+ -+ /* strip the varying sequence number */ -+ if (!strcmp(k, "table")) -+ *strchrnul(v, ':') = '\0'; -+ -+ printf("%s%s=%s", sep, k, v); -+ sep = " "; -+ } -+ if (*sep) { -+ printf("\n"); -+ fflush(stdout); -+ } -+ return 0; -+} -+ -+void cleanup(int sig) -+{ -+ audit_set(fd, AUDIT_STATUS_ENABLED, 0); -+ close(fd); -+ if (sig) -+ exit(0); -+} -+ -+int main(int argc, char **argv) -+{ -+ struct sigaction act = { -+ .sa_handler = cleanup, -+ }; -+ -+ fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT); -+ if (fd < 0) { -+ perror("Can't open netlink socket"); -+ return -1; -+ } -+ -+ if (sigaction(SIGTERM, &act, NULL) < 0 || -+ sigaction(SIGINT, &act, NULL) < 0) { -+ perror("Can't set signal handler"); -+ close(fd); -+ return -1; -+ } -+ -+ audit_set(fd, AUDIT_STATUS_ENABLED, 1); -+ audit_set(fd, AUDIT_STATUS_PID, getpid()); -+ -+ while (1) -+ readlog(fd); -+} -diff --git a/tools/testing/selftests/netfilter/config b/tools/testing/selftests/netfilter/config -index 4faf2ce021d90..7c42b1b2c69b4 100644 ---- a/tools/testing/selftests/netfilter/config -+++ b/tools/testing/selftests/netfilter/config -@@ -6,3 +6,4 @@ CONFIG_NFT_REDIR=m - CONFIG_NFT_MASQ=m - CONFIG_NFT_FLOW_OFFLOAD=m - CONFIG_NF_CT_NETLINK=m -+CONFIG_AUDIT=y -diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh -new file mode 100755 -index 0000000000000..bb34329e02a7f ---- /dev/null -+++ b/tools/testing/selftests/netfilter/nft_audit.sh -@@ -0,0 +1,193 @@ -+#!/bin/bash -+# SPDX-License-Identifier: GPL-2.0 -+# -+# Check that audit logs generated for nft commands are as expected. -+ -+SKIP_RC=4 -+RC=0 -+ -+nft --version >/dev/null 2>&1 || { -+ echo "SKIP: missing nft tool" -+ exit $SKIP_RC -+} -+ -+logfile=$(mktemp) -+rulefile=$(mktemp) -+echo "logging into $logfile" -+./audit_logread >"$logfile" & -+logread_pid=$! -+trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT -+exec 3<"$logfile" -+ -+do_test() { # (cmd, log) -+ echo -n "testing for cmd: $1 ... " -+ cat <&3 >/dev/null -+ $1 >/dev/null || exit 1 -+ sleep 0.1 -+ res=$(diff -a -u <(echo "$2") - <&3) -+ [ $? -eq 0 ] && { echo "OK"; return; } -+ echo "FAIL" -+ grep -v '^\(---\|+++\|@@\)' <<< "$res" -+ ((RC--)) -+} -+ -+nft flush ruleset -+ -+# adding tables, chains and rules -+ -+for table in t1 t2; do -+ do_test "nft add table $table" \ -+ "table=$table family=2 entries=1 op=nft_register_table" -+ -+ do_test "nft add chain $table c1" \ -+ "table=$table family=2 entries=1 op=nft_register_chain" -+ -+ do_test "nft add chain $table c2; add chain $table c3" \ -+ "table=$table family=2 entries=2 op=nft_register_chain" -+ -+ cmd="add rule $table c1 counter" -+ -+ do_test "nft $cmd" \ -+ "table=$table family=2 entries=1 op=nft_register_rule" -+ -+ do_test "nft $cmd; $cmd" \ -+ "table=$table family=2 entries=2 op=nft_register_rule" -+ -+ cmd="" -+ sep="" -+ for chain in c2 c3; do -+ for i in {1..3}; do -+ cmd+="$sep add rule $table $chain counter" -+ sep=";" -+ done -+ done -+ do_test "nft $cmd" \ -+ "table=$table family=2 entries=6 op=nft_register_rule" -+done -+ -+for ((i = 0; i < 500; i++)); do -+ echo "add rule t2 c3 counter accept comment \"rule $i\"" -+done >$rulefile -+do_test "nft -f $rulefile" \ -+'table=t2 family=2 entries=500 op=nft_register_rule' -+ -+# adding sets and elements -+ -+settype='type inet_service; counter' -+setelem='{ 22, 80, 443 }' -+setblock="{ $settype; elements = $setelem; }" -+do_test "nft add set t1 s $setblock" \ -+"table=t1 family=2 entries=4 op=nft_register_set" -+ -+do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \ -+"table=t1 family=2 entries=5 op=nft_register_set" -+ -+do_test "nft add element t1 s3 $setelem" \ -+"table=t1 family=2 entries=3 op=nft_register_setelem" -+ -+# adding counters -+ -+do_test 'nft add counter t1 c1' \ -+'table=t1 family=2 entries=1 op=nft_register_obj' -+ -+do_test 'nft add counter t2 c1; add counter t2 c2' \ -+'table=t2 family=2 entries=2 op=nft_register_obj' -+ -+# adding/updating quotas -+ -+do_test 'nft add quota t1 q1 { 10 bytes }' \ -+'table=t1 family=2 entries=1 op=nft_register_obj' -+ -+do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \ -+'table=t2 family=2 entries=2 op=nft_register_obj' -+ -+# changing the quota value triggers obj update path -+do_test 'nft add quota t1 q1 { 20 bytes }' \ -+'table=t1 family=2 entries=1 op=nft_register_obj' -+ -+# resetting rules -+ -+do_test 'nft reset rules t1 c2' \ -+'table=t1 family=2 entries=3 op=nft_reset_rule' -+ -+do_test 'nft reset rules table t1' \ -+'table=t1 family=2 entries=3 op=nft_reset_rule -+table=t1 family=2 entries=3 op=nft_reset_rule -+table=t1 family=2 entries=3 op=nft_reset_rule' -+ -+do_test 'nft reset rules t2 c3' \ -+'table=t2 family=2 entries=189 op=nft_reset_rule -+table=t2 family=2 entries=188 op=nft_reset_rule -+table=t2 family=2 entries=126 op=nft_reset_rule' -+ -+do_test 'nft reset rules t2' \ -+'table=t2 family=2 entries=3 op=nft_reset_rule -+table=t2 family=2 entries=3 op=nft_reset_rule -+table=t2 family=2 entries=186 op=nft_reset_rule -+table=t2 family=2 entries=188 op=nft_reset_rule -+table=t2 family=2 entries=129 op=nft_reset_rule' -+ -+do_test 'nft reset rules' \ -+'table=t1 family=2 entries=3 op=nft_reset_rule -+table=t1 family=2 entries=3 op=nft_reset_rule -+table=t1 family=2 entries=3 op=nft_reset_rule -+table=t2 family=2 entries=3 op=nft_reset_rule -+table=t2 family=2 entries=3 op=nft_reset_rule -+table=t2 family=2 entries=180 op=nft_reset_rule -+table=t2 family=2 entries=188 op=nft_reset_rule -+table=t2 family=2 entries=135 op=nft_reset_rule' -+ -+# resetting sets and elements -+ -+elem=(22 ,80 ,443) -+relem="" -+for i in {1..3}; do -+ relem+="${elem[((i - 1))]}" -+ do_test "nft reset element t1 s { $relem }" \ -+ "table=t1 family=2 entries=$i op=nft_reset_setelem" -+done -+ -+do_test 'nft reset set t1 s' \ -+'table=t1 family=2 entries=3 op=nft_reset_setelem' -+ -+# deleting rules -+ -+readarray -t handles < <(nft -a list chain t1 c1 | \ -+ sed -n 's/.*counter.* handle \(.*\)$/\1/p') -+ -+do_test "nft delete rule t1 c1 handle ${handles[0]}" \ -+'table=t1 family=2 entries=1 op=nft_unregister_rule' -+ -+cmd='delete rule t1 c1 handle' -+do_test "nft $cmd ${handles[1]}; $cmd ${handles[2]}" \ -+'table=t1 family=2 entries=2 op=nft_unregister_rule' -+ -+do_test 'nft flush chain t1 c2' \ -+'table=t1 family=2 entries=3 op=nft_unregister_rule' -+ -+do_test 'nft flush table t2' \ -+'table=t2 family=2 entries=509 op=nft_unregister_rule' -+ -+# deleting chains -+ -+do_test 'nft delete chain t2 c2' \ -+'table=t2 family=2 entries=1 op=nft_unregister_chain' -+ -+# deleting sets and elements -+ -+do_test 'nft delete element t1 s { 22 }' \ -+'table=t1 family=2 entries=1 op=nft_unregister_setelem' -+ -+do_test 'nft delete element t1 s { 80, 443 }' \ -+'table=t1 family=2 entries=2 op=nft_unregister_setelem' -+ -+do_test 'nft flush set t1 s2' \ -+'table=t1 family=2 entries=3 op=nft_unregister_setelem' -+ -+do_test 'nft delete set t1 s2' \ -+'table=t1 family=2 entries=1 op=nft_unregister_set' -+ -+do_test 'nft delete set t1 s3' \ -+'table=t1 family=2 entries=1 op=nft_unregister_set' -+ -+exit $RC diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.57-58.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.57-58.patch deleted file mode 100644 index b890875ff1ec..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.57-58.patch +++ /dev/null @@ -1,389 +0,0 @@ -diff --git a/Makefile b/Makefile -index b435b56594f0f..ce1eec0b5010d 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 57 -+SUBLEVEL = 58 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c -index 5a976fa343df1..3bb530d4bb5ce 100644 ---- a/fs/nfs/direct.c -+++ b/fs/nfs/direct.c -@@ -93,10 +93,12 @@ nfs_direct_handle_truncated(struct nfs_direct_req *dreq, - dreq->max_count = dreq_len; - if (dreq->count > dreq_len) - dreq->count = dreq_len; -- } - -- if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && !dreq->error) -- dreq->error = hdr->error; -+ if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) -+ dreq->error = hdr->error; -+ else /* Clear outstanding error if this is EOF */ -+ dreq->error = 0; -+ } - } - - static void -@@ -118,18 +120,6 @@ nfs_direct_count_bytes(struct nfs_direct_req *dreq, - dreq->count = dreq_len; - } - --static void nfs_direct_truncate_request(struct nfs_direct_req *dreq, -- struct nfs_page *req) --{ -- loff_t offs = req_offset(req); -- size_t req_start = (size_t)(offs - dreq->io_start); -- -- if (req_start < dreq->max_count) -- dreq->max_count = req_start; -- if (req_start < dreq->count) -- dreq->count = req_start; --} -- - /** - * nfs_swap_rw - NFS address space operation for swap I/O - * @iocb: target I/O control block -@@ -500,9 +490,7 @@ static void nfs_direct_add_page_head(struct list_head *list, - kref_get(&head->wb_kref); - } - --static void nfs_direct_join_group(struct list_head *list, -- struct nfs_commit_info *cinfo, -- struct inode *inode) -+static void nfs_direct_join_group(struct list_head *list, struct inode *inode) - { - struct nfs_page *req, *subreq; - -@@ -524,7 +512,7 @@ static void nfs_direct_join_group(struct list_head *list, - nfs_release_request(subreq); - } - } while ((subreq = subreq->wb_this_page) != req); -- nfs_join_page_group(req, cinfo, inode); -+ nfs_join_page_group(req, inode); - } - } - -@@ -542,15 +530,20 @@ nfs_direct_write_scan_commit_list(struct inode *inode, - static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) - { - struct nfs_pageio_descriptor desc; -- struct nfs_page *req; -+ struct nfs_page *req, *tmp; - LIST_HEAD(reqs); - struct nfs_commit_info cinfo; -+ LIST_HEAD(failed); - - nfs_init_cinfo_from_dreq(&cinfo, dreq); - nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); - -- nfs_direct_join_group(&reqs, &cinfo, dreq->inode); -+ nfs_direct_join_group(&reqs, dreq->inode); - -+ dreq->count = 0; -+ dreq->max_count = 0; -+ list_for_each_entry(req, &reqs, wb_list) -+ dreq->max_count += req->wb_bytes; - nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); - get_dreq(dreq); - -@@ -558,40 +551,27 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) - &nfs_direct_write_completion_ops); - desc.pg_dreq = dreq; - -- while (!list_empty(&reqs)) { -- req = nfs_list_entry(reqs.next); -+ list_for_each_entry_safe(req, tmp, &reqs, wb_list) { - /* Bump the transmission count */ - req->wb_nio++; - if (!nfs_pageio_add_request(&desc, req)) { -- spin_lock(&dreq->lock); -- if (dreq->error < 0) { -- desc.pg_error = dreq->error; -- } else if (desc.pg_error != -EAGAIN) { -- dreq->flags = 0; -- if (!desc.pg_error) -- desc.pg_error = -EIO; -+ nfs_list_move_request(req, &failed); -+ spin_lock(&cinfo.inode->i_lock); -+ dreq->flags = 0; -+ if (desc.pg_error < 0) - dreq->error = desc.pg_error; -- } else -- dreq->flags = NFS_ODIRECT_RESCHED_WRITES; -- spin_unlock(&dreq->lock); -- break; -+ else -+ dreq->error = -EIO; -+ spin_unlock(&cinfo.inode->i_lock); - } - nfs_release_request(req); - } - nfs_pageio_complete(&desc); - -- while (!list_empty(&reqs)) { -- req = nfs_list_entry(reqs.next); -+ while (!list_empty(&failed)) { -+ req = nfs_list_entry(failed.next); - nfs_list_remove_request(req); - nfs_unlock_and_release_request(req); -- if (desc.pg_error == -EAGAIN) { -- nfs_mark_request_commit(req, NULL, &cinfo, 0); -- } else { -- spin_lock(&dreq->lock); -- nfs_direct_truncate_request(dreq, req); -- spin_unlock(&dreq->lock); -- nfs_release_request(req); -- } - } - - if (put_dreq(dreq)) -@@ -611,6 +591,8 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) - if (status < 0) { - /* Errors in commit are fatal */ - dreq->error = status; -+ dreq->max_count = 0; -+ dreq->count = 0; - dreq->flags = NFS_ODIRECT_DONE; - } else { - status = dreq->error; -@@ -621,12 +603,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) - while (!list_empty(&data->pages)) { - req = nfs_list_entry(data->pages.next); - nfs_list_remove_request(req); -- if (status < 0) { -- spin_lock(&dreq->lock); -- nfs_direct_truncate_request(dreq, req); -- spin_unlock(&dreq->lock); -- nfs_release_request(req); -- } else if (!nfs_write_match_verf(verf, req)) { -+ if (status >= 0 && !nfs_write_match_verf(verf, req)) { - dreq->flags = NFS_ODIRECT_RESCHED_WRITES; - /* - * Despite the reboot, the write was successful, -@@ -634,7 +611,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) - */ - req->wb_nio = 0; - nfs_mark_request_commit(req, NULL, &cinfo, 0); -- } else -+ } else /* Error or match */ - nfs_release_request(req); - nfs_unlock_and_release_request(req); - } -@@ -687,7 +664,6 @@ static void nfs_direct_write_clear_reqs(struct nfs_direct_req *dreq) - while (!list_empty(&reqs)) { - req = nfs_list_entry(reqs.next); - nfs_list_remove_request(req); -- nfs_direct_truncate_request(dreq, req); - nfs_release_request(req); - nfs_unlock_and_release_request(req); - } -@@ -737,8 +713,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) - } - - nfs_direct_count_bytes(dreq, hdr); -- if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags) && -- !test_bit(NFS_IOHDR_ERROR, &hdr->flags)) { -+ if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags)) { - if (!dreq->flags) - dreq->flags = NFS_ODIRECT_DO_COMMIT; - flags = dreq->flags; -@@ -782,23 +757,18 @@ static void nfs_write_sync_pgio_error(struct list_head *head, int error) - static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) - { - struct nfs_direct_req *dreq = hdr->dreq; -- struct nfs_page *req; -- struct nfs_commit_info cinfo; - - trace_nfs_direct_write_reschedule_io(dreq); - -- nfs_init_cinfo_from_dreq(&cinfo, dreq); - spin_lock(&dreq->lock); -- if (dreq->error == 0) -+ if (dreq->error == 0) { - dreq->flags = NFS_ODIRECT_RESCHED_WRITES; -- set_bit(NFS_IOHDR_REDO, &hdr->flags); -- spin_unlock(&dreq->lock); -- while (!list_empty(&hdr->pages)) { -- req = nfs_list_entry(hdr->pages.next); -- nfs_list_remove_request(req); -- nfs_unlock_request(req); -- nfs_mark_request_commit(req, NULL, &cinfo, 0); -+ /* fake unstable write to let common nfs resend pages */ -+ hdr->verf.committed = NFS_UNSTABLE; -+ hdr->good_bytes = hdr->args.offset + hdr->args.count - -+ hdr->io_start; - } -+ spin_unlock(&dreq->lock); - } - - static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { -@@ -826,11 +796,9 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, - { - struct nfs_pageio_descriptor desc; - struct inode *inode = dreq->inode; -- struct nfs_commit_info cinfo; - ssize_t result = 0; - size_t requested_bytes = 0; - size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE); -- bool defer = false; - - trace_nfs_direct_write_schedule_iovec(dreq); - -@@ -871,39 +839,19 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, - break; - } - -- pgbase = 0; -- bytes -= req_len; -- requested_bytes += req_len; -- pos += req_len; -- dreq->bytes_left -= req_len; -- -- if (defer) { -- nfs_mark_request_commit(req, NULL, &cinfo, 0); -- continue; -- } -- - nfs_lock_request(req); - req->wb_index = pos >> PAGE_SHIFT; - req->wb_offset = pos & ~PAGE_MASK; -- if (nfs_pageio_add_request(&desc, req)) -- continue; -- -- /* Exit on hard errors */ -- if (desc.pg_error < 0 && desc.pg_error != -EAGAIN) { -+ if (!nfs_pageio_add_request(&desc, req)) { - result = desc.pg_error; - nfs_unlock_and_release_request(req); - break; - } -- -- /* If the error is soft, defer remaining requests */ -- nfs_init_cinfo_from_dreq(&cinfo, dreq); -- spin_lock(&dreq->lock); -- dreq->flags = NFS_ODIRECT_RESCHED_WRITES; -- spin_unlock(&dreq->lock); -- nfs_unlock_request(req); -- nfs_mark_request_commit(req, NULL, &cinfo, 0); -- desc.pg_error = 0; -- defer = true; -+ pgbase = 0; -+ bytes -= req_len; -+ requested_bytes += req_len; -+ pos += req_len; -+ dreq->bytes_left -= req_len; - } - nfs_direct_release_pages(pagevec, npages); - kvfree(pagevec); -diff --git a/fs/nfs/write.c b/fs/nfs/write.c -index 0a8aed0ac9945..f41d24b54fd1f 100644 ---- a/fs/nfs/write.c -+++ b/fs/nfs/write.c -@@ -58,8 +58,7 @@ static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; - static const struct nfs_commit_completion_ops nfs_commit_completion_ops; - static const struct nfs_rw_ops nfs_rw_write_ops; - static void nfs_inode_remove_request(struct nfs_page *req); --static void nfs_clear_request_commit(struct nfs_commit_info *cinfo, -- struct nfs_page *req); -+static void nfs_clear_request_commit(struct nfs_page *req); - static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo, - struct inode *inode); - static struct nfs_page * -@@ -503,8 +502,8 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, - * the (former) group. All subrequests are removed from any write or commit - * lists, unlinked from the group and destroyed. - */ --void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo, -- struct inode *inode) -+void -+nfs_join_page_group(struct nfs_page *head, struct inode *inode) - { - struct nfs_page *subreq; - struct nfs_page *destroy_list = NULL; -@@ -534,7 +533,7 @@ void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo, - * Commit list removal accounting is done after locks are dropped */ - subreq = head; - do { -- nfs_clear_request_commit(cinfo, subreq); -+ nfs_clear_request_commit(subreq); - subreq = subreq->wb_this_page; - } while (subreq != head); - -@@ -568,10 +567,8 @@ nfs_lock_and_join_requests(struct page *page) - { - struct inode *inode = page_file_mapping(page)->host; - struct nfs_page *head; -- struct nfs_commit_info cinfo; - int ret; - -- nfs_init_cinfo_from_inode(&cinfo, inode); - /* - * A reference is taken only on the head request which acts as a - * reference to the whole page group - the group will not be destroyed -@@ -588,7 +585,7 @@ nfs_lock_and_join_requests(struct page *page) - return ERR_PTR(ret); - } - -- nfs_join_page_group(head, &cinfo, inode); -+ nfs_join_page_group(head, inode); - - return head; - } -@@ -959,16 +956,18 @@ nfs_clear_page_commit(struct page *page) - } - - /* Called holding the request lock on @req */ --static void nfs_clear_request_commit(struct nfs_commit_info *cinfo, -- struct nfs_page *req) -+static void -+nfs_clear_request_commit(struct nfs_page *req) - { - if (test_bit(PG_CLEAN, &req->wb_flags)) { - struct nfs_open_context *ctx = nfs_req_openctx(req); - struct inode *inode = d_inode(ctx->dentry); -+ struct nfs_commit_info cinfo; - -+ nfs_init_cinfo_from_inode(&cinfo, inode); - mutex_lock(&NFS_I(inode)->commit_mutex); -- if (!pnfs_clear_request_commit(req, cinfo)) { -- nfs_request_remove_commit_list(req, cinfo); -+ if (!pnfs_clear_request_commit(req, &cinfo)) { -+ nfs_request_remove_commit_list(req, &cinfo); - } - mutex_unlock(&NFS_I(inode)->commit_mutex); - nfs_clear_page_commit(req->wb_page); -diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h -index e39a8cf8b1797..ba7e2e4b09264 100644 ---- a/include/linux/nfs_page.h -+++ b/include/linux/nfs_page.h -@@ -145,9 +145,7 @@ extern void nfs_unlock_request(struct nfs_page *req); - extern void nfs_unlock_and_release_request(struct nfs_page *); - extern struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req); - extern int nfs_page_group_lock_subrequests(struct nfs_page *head); --extern void nfs_join_page_group(struct nfs_page *head, -- struct nfs_commit_info *cinfo, -- struct inode *inode); -+extern void nfs_join_page_group(struct nfs_page *head, struct inode *inode); - extern int nfs_page_group_lock(struct nfs_page *); - extern void nfs_page_group_unlock(struct nfs_page *); - extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); -diff --git a/lib/test_meminit.c b/lib/test_meminit.c -index 0ae35223d7733..85d8dd8e01dc4 100644 ---- a/lib/test_meminit.c -+++ b/lib/test_meminit.c -@@ -93,7 +93,7 @@ static int __init test_pages(int *total_failures) - int failures = 0, num_tests = 0; - int i; - -- for (i = 0; i <= MAX_ORDER; i++) -+ for (i = 0; i < MAX_ORDER; i++) - num_tests += do_alloc_pages_order(i, &failures); - - REPORT_FAILURES_IN_FN(); diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.58-59.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.58-59.patch deleted file mode 100644 index 5d22b4125d43..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.58-59.patch +++ /dev/null @@ -1,4902 +0,0 @@ -diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml -index 33b90e975e33c..ea7db3618b23e 100644 ---- a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml -+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzg2l-irqc.yaml -@@ -31,8 +31,9 @@ properties: - - const: renesas,rzg2l-irqc - - '#interrupt-cells': -- description: The first cell should contain external interrupt number (IRQ0-7) and the -- second cell is used to specify the flag. -+ description: The first cell should contain a macro RZG2L_{NMI,IRQX} included in the -+ include/dt-bindings/interrupt-controller/irqc-rzg2l.h and the second -+ cell is used to specify the flag. - const: 2 - - '#address-cells': -diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst -index f5f7a464605f9..b47b3d0ce5596 100644 ---- a/Documentation/networking/ip-sysctl.rst -+++ b/Documentation/networking/ip-sysctl.rst -@@ -967,6 +967,21 @@ tcp_tw_reuse - INTEGER - tcp_window_scaling - BOOLEAN - Enable window scaling as defined in RFC1323. - -+tcp_shrink_window - BOOLEAN -+ This changes how the TCP receive window is calculated. -+ -+ RFC 7323, section 2.4, says there are instances when a retracted -+ window can be offered, and that TCP implementations MUST ensure -+ that they handle a shrinking window, as specified in RFC 1122. -+ -+ - 0 - Disabled. The window is never shrunk. -+ - 1 - Enabled. The window is shrunk when necessary to remain within -+ the memory limit set by autotuning (sk_rcvbuf). -+ This only occurs if a non-zero receive window -+ scaling factor is also in effect. -+ -+ Default: 0 -+ - tcp_wmem - vector of 3 INTEGERs: min, default, max - min: Amount of memory reserved for send buffers for TCP sockets. - Each TCP socket has rights to use it due to fact of its birth. -diff --git a/Makefile b/Makefile -index ce1eec0b5010d..4ad29c852e5f8 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 58 -+SUBLEVEL = 59 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts -index dec85d2548384..5117b2e7985af 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts -+++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts -@@ -48,7 +48,7 @@ - - memory@40000000 { - device_type = "memory"; -- reg = <0 0x40000000 0 0x80000000>; -+ reg = <0 0x40000000 0x2 0x00000000>; - }; - - reserved-memory { -@@ -56,13 +56,8 @@ - #size-cells = <2>; - ranges; - -- /* 2 MiB reserved for ARM Trusted Firmware (BL31) */ -- bl31_secmon_reserved: secmon@54600000 { -- no-map; -- reg = <0 0x54600000 0x0 0x200000>; -- }; -- -- /* 12 MiB reserved for OP-TEE (BL32) -+ /* -+ * 12 MiB reserved for OP-TEE (BL32) - * +-----------------------+ 0x43e0_0000 - * | SHMEM 2MiB | - * +-----------------------+ 0x43c0_0000 -@@ -75,6 +70,34 @@ - no-map; - reg = <0 0x43200000 0 0x00c00000>; - }; -+ -+ scp_mem: memory@50000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0 0x50000000 0 0x2900000>; -+ no-map; -+ }; -+ -+ vpu_mem: memory@53000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0 0x53000000 0 0x1400000>; /* 20 MB */ -+ }; -+ -+ /* 2 MiB reserved for ARM Trusted Firmware (BL31) */ -+ bl31_secmon_mem: memory@54600000 { -+ no-map; -+ reg = <0 0x54600000 0x0 0x200000>; -+ }; -+ -+ snd_dma_mem: memory@60000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0 0x60000000 0 0x1100000>; -+ no-map; -+ }; -+ -+ apu_mem: memory@62000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0 0x62000000 0 0x1400000>; /* 20 MB */ -+ }; - }; - }; - -diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi -index 2c2b946b614bf..ef2764a595eda 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi -@@ -229,6 +229,7 @@ - interrupts = ; - cpus = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>, - <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>; -+ status = "fail"; - }; - - dmic_codec: dmic-codec { -diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi -index f049fb42e3ca8..de794a5078dfc 100644 ---- a/arch/arm64/boot/dts/qcom/sm8150.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi -@@ -3701,7 +3701,7 @@ - - pdc: interrupt-controller@b220000 { - compatible = "qcom,sm8150-pdc", "qcom,pdc"; -- reg = <0 0x0b220000 0 0x400>; -+ reg = <0 0x0b220000 0 0x30000>; - qcom,pdc-ranges = <0 480 94>, <94 609 31>, - <125 63 1>; - #interrupt-cells = <2>; -diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h -index 1a89ebdc3acc9..0238e6bd0d6c1 100644 ---- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h -+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h -@@ -94,6 +94,13 @@ static inline pte_t pte_wrprotect(pte_t pte) - - #define pte_wrprotect pte_wrprotect - -+static inline int pte_read(pte_t pte) -+{ -+ return (pte_val(pte) & _PAGE_RO) != _PAGE_NA; -+} -+ -+#define pte_read pte_read -+ - static inline int pte_write(pte_t pte) - { - return !(pte_val(pte) & _PAGE_RO); -diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h -index 879e9a6e5a870..00a003d367523 100644 ---- a/arch/powerpc/include/asm/nohash/64/pgtable.h -+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h -@@ -197,7 +197,7 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm, - { - unsigned long old; - -- if (pte_young(*ptep)) -+ if (!pte_young(*ptep)) - return 0; - old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); - return (old & _PAGE_ACCESSED) != 0; -diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h -index d9067dfc531cc..3d7dce90863c2 100644 ---- a/arch/powerpc/include/asm/nohash/pgtable.h -+++ b/arch/powerpc/include/asm/nohash/pgtable.h -@@ -25,7 +25,9 @@ static inline int pte_write(pte_t pte) - return pte_val(pte) & _PAGE_RW; - } - #endif -+#ifndef pte_read - static inline int pte_read(pte_t pte) { return 1; } -+#endif - static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } - static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } - static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } -diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S -index 3fc7c9886bb70..d4fc546762db4 100644 ---- a/arch/powerpc/kernel/entry_32.S -+++ b/arch/powerpc/kernel/entry_32.S -@@ -135,8 +135,9 @@ ret_from_syscall: - lis r4,icache_44x_need_flush@ha - lwz r5,icache_44x_need_flush@l(r4) - cmplwi cr0,r5,0 -- bne- 2f -+ bne- .L44x_icache_flush - #endif /* CONFIG_PPC_47x */ -+.L44x_icache_flush_return: - kuep_unlock - lwz r4,_LINK(r1) - lwz r5,_CCR(r1) -@@ -170,10 +171,11 @@ syscall_exit_finish: - b 1b - - #ifdef CONFIG_44x --2: li r7,0 -+.L44x_icache_flush: -+ li r7,0 - iccci r0,r0 - stw r7,icache_44x_need_flush@l(r4) -- b 1b -+ b .L44x_icache_flush_return - #endif /* CONFIG_44x */ - - .globl ret_from_fork -diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c -index f2417ac54edd6..8f5d3c57d58ad 100644 ---- a/arch/riscv/net/bpf_jit_comp64.c -+++ b/arch/riscv/net/bpf_jit_comp64.c -@@ -236,7 +236,7 @@ static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx) - emit_addi(RV_REG_SP, RV_REG_SP, stack_adjust, ctx); - /* Set return value. */ - if (!is_tail_call) -- emit_mv(RV_REG_A0, RV_REG_A5, ctx); -+ emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx); - emit_jalr(RV_REG_ZERO, is_tail_call ? RV_REG_T3 : RV_REG_RA, - is_tail_call ? 4 : 0, /* skip TCC init */ - ctx); -@@ -428,12 +428,12 @@ static void emit_sext_32_rd(u8 *rd, struct rv_jit_context *ctx) - *rd = RV_REG_T2; - } - --static int emit_jump_and_link(u8 rd, s64 rvoff, bool force_jalr, -+static int emit_jump_and_link(u8 rd, s64 rvoff, bool fixed_addr, - struct rv_jit_context *ctx) - { - s64 upper, lower; - -- if (rvoff && is_21b_int(rvoff) && !force_jalr) { -+ if (rvoff && fixed_addr && is_21b_int(rvoff)) { - emit(rv_jal(rd, rvoff >> 1), ctx); - return 0; - } else if (in_auipc_jalr_range(rvoff)) { -@@ -454,24 +454,17 @@ static bool is_signed_bpf_cond(u8 cond) - cond == BPF_JSGE || cond == BPF_JSLE; - } - --static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx) -+static int emit_call(u64 addr, bool fixed_addr, struct rv_jit_context *ctx) - { - s64 off = 0; - u64 ip; -- u8 rd; -- int ret; - - if (addr && ctx->insns) { - ip = (u64)(long)(ctx->insns + ctx->ninsns); - off = addr - ip; - } - -- ret = emit_jump_and_link(RV_REG_RA, off, !fixed, ctx); -- if (ret) -- return ret; -- rd = bpf_to_rv_reg(BPF_REG_0, ctx); -- emit_mv(rd, RV_REG_A0, ctx); -- return 0; -+ return emit_jump_and_link(RV_REG_RA, off, fixed_addr, ctx); - } - - static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64, -@@ -913,7 +906,7 @@ out_be: - /* JUMP off */ - case BPF_JMP | BPF_JA: - rvoff = rv_offset(i, off, ctx); -- ret = emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx); -+ ret = emit_jump_and_link(RV_REG_ZERO, rvoff, true, ctx); - if (ret) - return ret; - break; -@@ -1032,17 +1025,21 @@ out_be: - /* function call */ - case BPF_JMP | BPF_CALL: - { -- bool fixed; -+ bool fixed_addr; - u64 addr; - - mark_call(ctx); -- ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, &addr, -- &fixed); -+ ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, -+ &addr, &fixed_addr); - if (ret < 0) - return ret; -- ret = emit_call(fixed, addr, ctx); -+ -+ ret = emit_call(addr, fixed_addr, ctx); - if (ret) - return ret; -+ -+ if (insn->src_reg != BPF_PSEUDO_CALL) -+ emit_mv(bpf_to_rv_reg(BPF_REG_0, ctx), RV_REG_A0, ctx); - break; - } - /* tail call */ -@@ -1057,7 +1054,7 @@ out_be: - break; - - rvoff = epilogue_offset(ctx); -- ret = emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx); -+ ret = emit_jump_and_link(RV_REG_ZERO, rvoff, true, ctx); - if (ret) - return ret; - break; -diff --git a/arch/x86/events/utils.c b/arch/x86/events/utils.c -index 76b1f8bb0fd5f..dab4ed199227f 100644 ---- a/arch/x86/events/utils.c -+++ b/arch/x86/events/utils.c -@@ -1,5 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0 - #include -+#include - - #include "perf_event.h" - -@@ -132,9 +133,9 @@ static int get_branch_type(unsigned long from, unsigned long to, int abort, - * The LBR logs any address in the IP, even if the IP just - * faulted. This means userspace can control the from address. - * Ensure we don't blindly read any address by validating it is -- * a known text address. -+ * a known text address and not a vsyscall address. - */ -- if (kernel_text_address(from)) { -+ if (kernel_text_address(from) && !in_gate_area_no_mm(from)) { - addr = (void *)from; - /* - * Assume we can get the maximum possible size -diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h -index 52d8c67d93081..016fb500b3a6f 100644 ---- a/arch/x86/include/asm/msr-index.h -+++ b/arch/x86/include/asm/msr-index.h -@@ -635,12 +635,17 @@ - /* AMD Last Branch Record MSRs */ - #define MSR_AMD64_LBR_SELECT 0xc000010e - --/* Fam 17h MSRs */ --#define MSR_F17H_IRPERF 0xc00000e9 -+/* Zen4 */ -+#define MSR_ZEN4_BP_CFG 0xc001102e -+#define MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT 5 - -+/* Zen 2 */ - #define MSR_ZEN2_SPECTRAL_CHICKEN 0xc00110e3 - #define MSR_ZEN2_SPECTRAL_CHICKEN_BIT BIT_ULL(1) - -+/* Fam 17h MSRs */ -+#define MSR_F17H_IRPERF 0xc00000e9 -+ - /* Fam 16h MSRs */ - #define MSR_F16H_L2I_PERF_CTL 0xc0010230 - #define MSR_F16H_L2I_PERF_CTR 0xc0010231 -diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c -index d1d92897ed6be..46b7ee0ab01a4 100644 ---- a/arch/x86/kernel/alternative.c -+++ b/arch/x86/kernel/alternative.c -@@ -270,6 +270,17 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start, - u8 insn_buff[MAX_PATCH_LEN]; - - DPRINTK("alt table %px, -> %px", start, end); -+ -+ /* -+ * In the case CONFIG_X86_5LEVEL=y, KASAN_SHADOW_START is defined using -+ * cpu_feature_enabled(X86_FEATURE_LA57) and is therefore patched here. -+ * During the process, KASAN becomes confused seeing partial LA57 -+ * conversion and triggers a false-positive out-of-bound report. -+ * -+ * Disable KASAN until the patching is complete. -+ */ -+ kasan_disable_current(); -+ - /* - * The scan order should be from start to end. A later scanned - * alternative code can overwrite previously scanned alternative code. -@@ -337,6 +348,8 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start, - next: - optimize_nops(instr, a->instrlen); - } -+ -+ kasan_enable_current(); - } - - static inline bool is_jcc32(struct insn *insn) -diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c -index f240c978d85e4..b66960358381b 100644 ---- a/arch/x86/kernel/cpu/amd.c -+++ b/arch/x86/kernel/cpu/amd.c -@@ -80,6 +80,10 @@ static const int amd_div0[] = - AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x00, 0x0, 0x2f, 0xf), - AMD_MODEL_RANGE(0x17, 0x50, 0x0, 0x5f, 0xf)); - -+static const int amd_erratum_1485[] = -+ AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x19, 0x10, 0x0, 0x1f, 0xf), -+ AMD_MODEL_RANGE(0x19, 0x60, 0x0, 0xaf, 0xf)); -+ - static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) - { - int osvw_id = *erratum++; -@@ -1125,6 +1129,10 @@ static void init_amd(struct cpuinfo_x86 *c) - pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n"); - setup_force_cpu_bug(X86_BUG_DIV0); - } -+ -+ if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && -+ cpu_has_amd_erratum(c, amd_erratum_1485)) -+ msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT); - } - - #ifdef CONFIG_X86_32 -diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c -index ee4c812c8f6cc..8bb233d2d1e48 100644 ---- a/drivers/acpi/ec.c -+++ b/drivers/acpi/ec.c -@@ -1886,6 +1886,17 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { - DMI_MATCH(DMI_PRODUCT_NAME, "HP 15-cx0041ur"), - }, - }, -+ { -+ /* -+ * HP Pavilion Gaming Laptop 15-dk1xxx -+ * https://github.com/systemd/systemd/issues/28942 -+ */ -+ .callback = ec_honor_dsdt_gpe, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "HP"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-dk1xxx"), -+ }, -+ }, - { - /* - * Samsung hardware -diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c -index a7f12bdbc5e25..af6fa801d1ed8 100644 ---- a/drivers/acpi/resource.c -+++ b/drivers/acpi/resource.c -@@ -439,6 +439,13 @@ static const struct dmi_system_id asus_laptop[] = { - DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"), - }, - }, -+ { -+ .ident = "Asus ExpertBook B1402CBA", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"), -+ }, -+ }, - { - .ident = "Asus ExpertBook B2402CBA", - .matches = { -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index 6a053cd0cf410..fbc231a3f7951 100644 ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -1943,6 +1943,96 @@ retry: - return rc; - } - -+/** -+ * ata_dev_power_set_standby - Set a device power mode to standby -+ * @dev: target device -+ * -+ * Issue a STANDBY IMMEDIATE command to set a device power mode to standby. -+ * For an HDD device, this spins down the disks. -+ * -+ * LOCKING: -+ * Kernel thread context (may sleep). -+ */ -+void ata_dev_power_set_standby(struct ata_device *dev) -+{ -+ unsigned long ap_flags = dev->link->ap->flags; -+ struct ata_taskfile tf; -+ unsigned int err_mask; -+ -+ /* Issue STANDBY IMMEDIATE command only if supported by the device */ -+ if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) -+ return; -+ -+ /* -+ * Some odd clown BIOSes issue spindown on power off (ACPI S4 or S5) -+ * causing some drives to spin up and down again. For these, do nothing -+ * if we are being called on shutdown. -+ */ -+ if ((ap_flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) && -+ system_state == SYSTEM_POWER_OFF) -+ return; -+ -+ if ((ap_flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && -+ system_entering_hibernation()) -+ return; -+ -+ ata_tf_init(dev, &tf); -+ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; -+ tf.protocol = ATA_PROT_NODATA; -+ tf.command = ATA_CMD_STANDBYNOW1; -+ -+ ata_dev_notice(dev, "Entering standby power mode\n"); -+ -+ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); -+ if (err_mask) -+ ata_dev_err(dev, "STANDBY IMMEDIATE failed (err_mask=0x%x)\n", -+ err_mask); -+} -+ -+/** -+ * ata_dev_power_set_active - Set a device power mode to active -+ * @dev: target device -+ * -+ * Issue a VERIFY command to enter to ensure that the device is in the -+ * active power mode. For a spun-down HDD (standby or idle power mode), -+ * the VERIFY command will complete after the disk spins up. -+ * -+ * LOCKING: -+ * Kernel thread context (may sleep). -+ */ -+void ata_dev_power_set_active(struct ata_device *dev) -+{ -+ struct ata_taskfile tf; -+ unsigned int err_mask; -+ -+ /* -+ * Issue READ VERIFY SECTORS command for 1 sector at lba=0 only -+ * if supported by the device. -+ */ -+ if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) -+ return; -+ -+ ata_tf_init(dev, &tf); -+ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; -+ tf.protocol = ATA_PROT_NODATA; -+ tf.command = ATA_CMD_VERIFY; -+ tf.nsect = 1; -+ if (dev->flags & ATA_DFLAG_LBA) { -+ tf.flags |= ATA_TFLAG_LBA; -+ tf.device |= ATA_LBA; -+ } else { -+ /* CHS */ -+ tf.lbal = 0x1; /* sect */ -+ } -+ -+ ata_dev_notice(dev, "Entering active power mode\n"); -+ -+ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); -+ if (err_mask) -+ ata_dev_err(dev, "VERIFY failed (err_mask=0x%x)\n", -+ err_mask); -+} -+ - /** - * ata_read_log_page - read a specific log page - * @dev: target device -diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c -index 6d4c80b6daaef..2a04dd36a4948 100644 ---- a/drivers/ata/libata-eh.c -+++ b/drivers/ata/libata-eh.c -@@ -106,6 +106,14 @@ static const unsigned int ata_eh_flush_timeouts[] = { - UINT_MAX, - }; - -+static const unsigned int ata_eh_pm_timeouts[] = { -+ 10000, /* most drives spin up by 10sec */ -+ 10000, /* > 99% working drives spin up before 20sec */ -+ 35000, /* give > 30 secs of idleness for outlier devices */ -+ 5000, /* and sweet one last chance */ -+ UINT_MAX, /* > 1 min has elapsed, give up */ -+}; -+ - static const unsigned int ata_eh_other_timeouts[] = { - 5000, /* same rationale as identify timeout */ - 10000, /* ditto */ -@@ -147,6 +155,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { - .timeouts = ata_eh_other_timeouts, }, - { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT), - .timeouts = ata_eh_flush_timeouts }, -+ { .commands = CMDS(ATA_CMD_VERIFY), -+ .timeouts = ata_eh_pm_timeouts }, - }; - #undef CMDS - -@@ -498,7 +508,19 @@ static void ata_eh_unload(struct ata_port *ap) - struct ata_device *dev; - unsigned long flags; - -- /* Restore SControl IPM and SPD for the next driver and -+ /* -+ * Unless we are restarting, transition all enabled devices to -+ * standby power mode. -+ */ -+ if (system_state != SYSTEM_RESTART) { -+ ata_for_each_link(link, ap, PMP_FIRST) { -+ ata_for_each_dev(dev, link, ENABLED) -+ ata_dev_power_set_standby(dev); -+ } -+ } -+ -+ /* -+ * Restore SControl IPM and SPD for the next driver and - * disable attached devices. - */ - ata_for_each_link(link, ap, PMP_FIRST) { -@@ -687,6 +709,10 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) - ehc->saved_xfer_mode[devno] = dev->xfer_mode; - if (ata_ncq_enabled(dev)) - ehc->saved_ncq_enabled |= 1 << devno; -+ -+ /* If we are resuming, wake up the device */ -+ if (ap->pflags & ATA_PFLAG_RESUMING) -+ ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE; - } - } - -@@ -750,6 +776,8 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) - /* clean up */ - spin_lock_irqsave(ap->lock, flags); - -+ ap->pflags &= ~ATA_PFLAG_RESUMING; -+ - if (ap->pflags & ATA_PFLAG_LOADING) - ap->pflags &= ~ATA_PFLAG_LOADING; - else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) && -@@ -1241,6 +1269,13 @@ void ata_eh_detach_dev(struct ata_device *dev) - struct ata_eh_context *ehc = &link->eh_context; - unsigned long flags; - -+ /* -+ * If the device is still enabled, transition it to standby power mode -+ * (i.e. spin down HDDs). -+ */ -+ if (ata_dev_enabled(dev)) -+ ata_dev_power_set_standby(dev); -+ - ata_dev_disable(dev); - - spin_lock_irqsave(ap->lock, flags); -@@ -2927,6 +2962,15 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, - if (ehc->i.flags & ATA_EHI_DID_RESET) - readid_flags |= ATA_READID_POSTRESET; - -+ /* -+ * When resuming, before executing any command, make sure to -+ * transition the device to the active power mode. -+ */ -+ if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) { -+ ata_dev_power_set_active(dev); -+ ata_eh_done(link, dev, ATA_EH_SET_ACTIVE); -+ } -+ - if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { - WARN_ON(dev->class == ATA_DEV_PMP); - -@@ -3886,6 +3930,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) - unsigned long flags; - int rc = 0; - struct ata_device *dev; -+ struct ata_link *link; - - /* are we suspending? */ - spin_lock_irqsave(ap->lock, flags); -@@ -3898,6 +3943,12 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) - - WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); - -+ /* Set all devices attached to the port in standby mode */ -+ ata_for_each_link(link, ap, HOST_FIRST) { -+ ata_for_each_dev(dev, link, ENABLED) -+ ata_dev_power_set_standby(dev); -+ } -+ - /* - * If we have a ZPODD attached, check its zero - * power ready status before the port is frozen. -@@ -3980,6 +4031,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) - /* update the flags */ - spin_lock_irqsave(ap->lock, flags); - ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); -+ ap->pflags |= ATA_PFLAG_RESUMING; - spin_unlock_irqrestore(ap->lock, flags); - } - #endif /* CONFIG_PM */ -diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c -index 7b9c9264b9a72..2b9676416b8e8 100644 ---- a/drivers/ata/libata-scsi.c -+++ b/drivers/ata/libata-scsi.c -@@ -1081,15 +1081,13 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) - } - } else { - sdev->sector_size = ata_id_logical_sector_size(dev->id); -+ - /* -- * Stop the drive on suspend but do not issue START STOP UNIT -- * on resume as this is not necessary and may fail: the device -- * will be woken up by ata_port_pm_resume() with a port reset -- * and device revalidation. -+ * Ask the sd driver to issue START STOP UNIT on runtime suspend -+ * and resume only. For system level suspend/resume, devices -+ * power state is handled directly by libata EH. - */ -- sdev->manage_system_start_stop = true; - sdev->manage_runtime_start_stop = true; -- sdev->no_start_on_resume = 1; - } - - /* -@@ -1265,7 +1263,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) - } - - if (cdb[4] & 0x1) { -- tf->nsect = 1; /* 1 sector, lba=0 */ -+ tf->nsect = 1; /* 1 sector, lba=0 */ - - if (qc->dev->flags & ATA_DFLAG_LBA) { - tf->flags |= ATA_TFLAG_LBA; -@@ -1281,7 +1279,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) - tf->lbah = 0x0; /* cyl high */ - } - -- tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ -+ tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ - } else { - /* Some odd clown BIOSen issue spindown on power off (ACPI S4 - * or S5) causing some drives to spin up and down again. -@@ -1291,7 +1289,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) - goto skip; - - if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && -- system_entering_hibernation()) -+ system_entering_hibernation()) - goto skip; - - /* Issue ATA STANDBY IMMEDIATE command */ -diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h -index e5ec197aed303..a5e0e676ed9a8 100644 ---- a/drivers/ata/libata.h -+++ b/drivers/ata/libata.h -@@ -62,6 +62,8 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags); - extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, - unsigned int readid_flags); - extern int ata_dev_configure(struct ata_device *dev); -+extern void ata_dev_power_set_standby(struct ata_device *dev); -+extern void ata_dev_power_set_active(struct ata_device *dev); - extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); - extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); - extern unsigned int ata_dev_set_feature(struct ata_device *dev, -diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c -index 80acdf62794a3..afc94d0062b17 100644 ---- a/drivers/counter/counter-chrdev.c -+++ b/drivers/counter/counter-chrdev.c -@@ -247,8 +247,8 @@ static int counter_get_ext(const struct counter_comp *const ext, - if (*id == component_id) - return 0; - -- if (ext->type == COUNTER_COMP_ARRAY) { -- element = ext->priv; -+ if (ext[*ext_idx].type == COUNTER_COMP_ARRAY) { -+ element = ext[*ext_idx].priv; - - if (component_id - *id < element->length) - return 0; -diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c -index e2d1dc6ca6682..c7af13aca36cf 100644 ---- a/drivers/counter/microchip-tcb-capture.c -+++ b/drivers/counter/microchip-tcb-capture.c -@@ -98,7 +98,7 @@ static int mchp_tc_count_function_write(struct counter_device *counter, - priv->qdec_mode = 0; - /* Set highest rate based on whether soc has gclk or not */ - bmr &= ~(ATMEL_TC_QDEN | ATMEL_TC_POSEN); -- if (priv->tc_cfg->has_gclk) -+ if (!priv->tc_cfg->has_gclk) - cmr |= ATMEL_TC_TIMER_CLOCK2; - else - cmr |= ATMEL_TC_TIMER_CLOCK1; -diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c -index c625bb2b5d563..628af51c81af3 100644 ---- a/drivers/dma-buf/dma-fence-unwrap.c -+++ b/drivers/dma-buf/dma-fence-unwrap.c -@@ -76,16 +76,11 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, - dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) { - if (!dma_fence_is_signaled(tmp)) { - ++count; -- } else if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, -- &tmp->flags)) { -- if (ktime_after(tmp->timestamp, timestamp)) -- timestamp = tmp->timestamp; - } else { -- /* -- * Use the current time if the fence is -- * currently signaling. -- */ -- timestamp = ktime_get(); -+ ktime_t t = dma_fence_timestamp(tmp); -+ -+ if (ktime_after(t, timestamp)) -+ timestamp = t; - } - } - } -diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c -index af57799c86cee..2e9a316c596a3 100644 ---- a/drivers/dma-buf/sync_file.c -+++ b/drivers/dma-buf/sync_file.c -@@ -268,13 +268,10 @@ static int sync_fill_fence_info(struct dma_fence *fence, - sizeof(info->driver_name)); - - info->status = dma_fence_get_status(fence); -- while (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) && -- !test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags)) -- cpu_relax(); - info->timestamp_ns = -- test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags) ? -- ktime_to_ns(fence->timestamp) : -- ktime_set(0, 0); -+ dma_fence_is_signaled(fence) ? -+ ktime_to_ns(dma_fence_timestamp(fence)) : -+ ktime_set(0, 0); - - return info->status; - } -diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c -index 3b4ad7739f9ee..188f6b8625f78 100644 ---- a/drivers/dma/idxd/device.c -+++ b/drivers/dma/idxd/device.c -@@ -495,6 +495,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, - union idxd_command_reg cmd; - DECLARE_COMPLETION_ONSTACK(done); - u32 stat; -+ unsigned long flags; - - if (idxd_device_is_halted(idxd)) { - dev_warn(&idxd->pdev->dev, "Device is HALTED!\n"); -@@ -508,7 +509,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, - cmd.operand = operand; - cmd.int_req = 1; - -- spin_lock(&idxd->cmd_lock); -+ spin_lock_irqsave(&idxd->cmd_lock, flags); - wait_event_lock_irq(idxd->cmd_waitq, - !test_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags), - idxd->cmd_lock); -@@ -525,7 +526,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, - * After command submitted, release lock and go to sleep until - * the command completes via interrupt. - */ -- spin_unlock(&idxd->cmd_lock); -+ spin_unlock_irqrestore(&idxd->cmd_lock, flags); - wait_for_completion(&done); - stat = ioread32(idxd->reg_base + IDXD_CMDSTS_OFFSET); - spin_lock(&idxd->cmd_lock); -diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c -index a1517ef1f4a01..0acf6a92a4ad3 100644 ---- a/drivers/dma/mediatek/mtk-uart-apdma.c -+++ b/drivers/dma/mediatek/mtk-uart-apdma.c -@@ -451,9 +451,8 @@ static int mtk_uart_apdma_device_pause(struct dma_chan *chan) - mtk_uart_apdma_write(c, VFF_EN, VFF_EN_CLR_B); - mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B); - -- synchronize_irq(c->irq); -- - spin_unlock_irqrestore(&c->vc.lock, flags); -+ synchronize_irq(c->irq); - - return 0; - } -diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c -index 37674029cb427..592d48ecf241f 100644 ---- a/drivers/dma/stm32-dma.c -+++ b/drivers/dma/stm32-dma.c -@@ -1113,8 +1113,10 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( - chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_PFCTRL; - - /* Activate Double Buffer Mode if DMA triggers STM32 MDMA and more than 1 sg */ -- if (chan->trig_mdma && sg_len > 1) -+ if (chan->trig_mdma && sg_len > 1) { - chan->chan_reg.dma_scr |= STM32_DMA_SCR_DBM; -+ chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_CT; -+ } - - for_each_sg(sgl, sg, sg_len, i) { - ret = stm32_dma_set_xfer_param(chan, direction, &buswidth, -@@ -1387,11 +1389,12 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan, - - residue = stm32_dma_get_remaining_bytes(chan); - -- if (chan->desc->cyclic && !stm32_dma_is_current_sg(chan)) { -+ if ((chan->desc->cyclic || chan->trig_mdma) && !stm32_dma_is_current_sg(chan)) { - n_sg++; - if (n_sg == chan->desc->num_sgs) - n_sg = 0; -- residue = sg_req->len; -+ if (!chan->trig_mdma) -+ residue = sg_req->len; - } - - /* -@@ -1401,7 +1404,7 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan, - * residue = remaining bytes from NDTR + remaining - * periods/sg to be transferred - */ -- if (!chan->desc->cyclic || n_sg != 0) -+ if ((!chan->desc->cyclic && !chan->trig_mdma) || n_sg != 0) - for (i = n_sg; i < desc->num_sgs; i++) - residue += desc->sg_req[i].len; - -diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c -index b9d4c843635fc..4e9bab61f4663 100644 ---- a/drivers/dma/stm32-mdma.c -+++ b/drivers/dma/stm32-mdma.c -@@ -778,8 +778,6 @@ static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan, - /* Enable interrupts */ - ccr &= ~STM32_MDMA_CCR_IRQ_MASK; - ccr |= STM32_MDMA_CCR_TEIE | STM32_MDMA_CCR_CTCIE; -- if (sg_len > 1) -- ccr |= STM32_MDMA_CCR_BTIE; - desc->ccr = ccr; - - return 0; -@@ -1237,6 +1235,10 @@ static int stm32_mdma_resume(struct dma_chan *c) - unsigned long flags; - u32 status, reg; - -+ /* Transfer can be terminated */ -+ if (!chan->desc || (stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & STM32_MDMA_CCR_EN)) -+ return -EPERM; -+ - hwdesc = chan->desc->node[chan->curr_hwdesc].hwdesc; - - spin_lock_irqsave(&chan->vchan.lock, flags); -@@ -1317,21 +1319,35 @@ static int stm32_mdma_slave_config(struct dma_chan *c, - - static size_t stm32_mdma_desc_residue(struct stm32_mdma_chan *chan, - struct stm32_mdma_desc *desc, -- u32 curr_hwdesc) -+ u32 curr_hwdesc, -+ struct dma_tx_state *state) - { - struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan); - struct stm32_mdma_hwdesc *hwdesc; -- u32 cbndtr, residue, modulo, burst_size; -+ u32 cisr, clar, cbndtr, residue, modulo, burst_size; - int i; - -+ cisr = stm32_mdma_read(dmadev, STM32_MDMA_CISR(chan->id)); -+ - residue = 0; -- for (i = curr_hwdesc + 1; i < desc->count; i++) { -+ /* Get the next hw descriptor to process from current transfer */ -+ clar = stm32_mdma_read(dmadev, STM32_MDMA_CLAR(chan->id)); -+ for (i = desc->count - 1; i >= 0; i--) { - hwdesc = desc->node[i].hwdesc; -+ -+ if (hwdesc->clar == clar) -+ break;/* Current transfer found, stop cumulating */ -+ -+ /* Cumulate residue of unprocessed hw descriptors */ - residue += STM32_MDMA_CBNDTR_BNDT(hwdesc->cbndtr); - } - cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); - residue += cbndtr & STM32_MDMA_CBNDTR_BNDT_MASK; - -+ state->in_flight_bytes = 0; -+ if (chan->chan_config.m2m_hw && (cisr & STM32_MDMA_CISR_CRQA)) -+ state->in_flight_bytes = cbndtr & STM32_MDMA_CBNDTR_BNDT_MASK; -+ - if (!chan->mem_burst) - return residue; - -@@ -1361,11 +1377,10 @@ static enum dma_status stm32_mdma_tx_status(struct dma_chan *c, - - vdesc = vchan_find_desc(&chan->vchan, cookie); - if (chan->desc && cookie == chan->desc->vdesc.tx.cookie) -- residue = stm32_mdma_desc_residue(chan, chan->desc, -- chan->curr_hwdesc); -+ residue = stm32_mdma_desc_residue(chan, chan->desc, chan->curr_hwdesc, state); - else if (vdesc) -- residue = stm32_mdma_desc_residue(chan, -- to_stm32_mdma_desc(vdesc), 0); -+ residue = stm32_mdma_desc_residue(chan, to_stm32_mdma_desc(vdesc), 0, state); -+ - dma_set_residue(state, residue); - - spin_unlock_irqrestore(&chan->vchan.lock, flags); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h -index 93207badf83f3..6dcd7bab42fbb 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h -@@ -220,7 +220,7 @@ static inline bool amdgpu_bo_in_cpu_visible_vram(struct amdgpu_bo *bo) - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); - struct amdgpu_res_cursor cursor; - -- if (bo->tbo.resource->mem_type != TTM_PL_VRAM) -+ if (!bo->tbo.resource || bo->tbo.resource->mem_type != TTM_PL_VRAM) - return false; - - amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor); -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c -index 16c05a24ac7aa..15d3caf3d6d72 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c -@@ -1183,6 +1183,9 @@ static void disable_vbios_mode_if_required( - if (stream == NULL) - continue; - -+ if (stream->apply_seamless_boot_optimization) -+ continue; -+ - // only looking for first odm pipe - if (pipe->prev_odm_pipe) - continue; -diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c -index 202a9990f4517..b097bff1cd18e 100644 ---- a/drivers/gpu/drm/drm_atomic_helper.c -+++ b/drivers/gpu/drm/drm_atomic_helper.c -@@ -290,7 +290,8 @@ static int - update_connector_routing(struct drm_atomic_state *state, - struct drm_connector *connector, - struct drm_connector_state *old_connector_state, -- struct drm_connector_state *new_connector_state) -+ struct drm_connector_state *new_connector_state, -+ bool added_by_user) - { - const struct drm_connector_helper_funcs *funcs; - struct drm_encoder *new_encoder; -@@ -339,9 +340,13 @@ update_connector_routing(struct drm_atomic_state *state, - * there's a chance the connector may have been destroyed during the - * process, but it's better to ignore that then cause - * drm_atomic_helper_resume() to fail. -+ * -+ * Last, we want to ignore connector registration when the connector -+ * was not pulled in the atomic state by user-space (ie, was pulled -+ * in by the driver, e.g. when updating a DP-MST stream). - */ - if (!state->duplicated && drm_connector_is_unregistered(connector) && -- crtc_state->active) { -+ added_by_user && crtc_state->active) { - drm_dbg_atomic(connector->dev, - "[CONNECTOR:%d:%s] is not registered\n", - connector->base.id, connector->name); -@@ -620,7 +625,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, - struct drm_connector *connector; - struct drm_connector_state *old_connector_state, *new_connector_state; - int i, ret; -- unsigned int connectors_mask = 0; -+ unsigned int connectors_mask = 0, user_connectors_mask = 0; -+ -+ for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) -+ user_connectors_mask |= BIT(i); - - for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - bool has_connectors = -@@ -685,7 +693,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, - */ - ret = update_connector_routing(state, connector, - old_connector_state, -- new_connector_state); -+ new_connector_state, -+ BIT(i) & user_connectors_mask); - if (ret) - return ret; - if (old_connector_state->crtc) { -diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -index cc84685368715..efc22f9b17f07 100644 ---- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c -@@ -235,8 +235,17 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) - u32 flags = 0; - u32 *cs; - -+ /* -+ * L3 fabric flush is needed for AUX CCS invalidation -+ * which happens as part of pipe-control so we can -+ * ignore PIPE_CONTROL_FLUSH_L3. Also PIPE_CONTROL_FLUSH_L3 -+ * deals with Protected Memory which is not needed for -+ * AUX CCS invalidation and lead to unwanted side effects. -+ */ -+ if (mode & EMIT_FLUSH) -+ flags |= PIPE_CONTROL_FLUSH_L3; -+ - flags |= PIPE_CONTROL_TILE_CACHE_FLUSH; -- flags |= PIPE_CONTROL_FLUSH_L3; - flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; - flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; - /* Wa_1409600907:tgl,adl-p */ -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c -index 3fbda2a1f77fc..62d48c0f905e4 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c -@@ -142,6 +142,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane, - const struct dpu_format *fmt = NULL; - struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); - int src_width, src_height, dst_height, fps; -+ u64 plane_pixel_rate, plane_bit_rate; - u64 plane_prefill_bw; - u64 plane_bw; - u32 hw_latency_lines; -@@ -164,13 +165,12 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane, - scale_factor = src_height > dst_height ? - mult_frac(src_height, 1, dst_height) : 1; - -- plane_bw = -- src_width * mode->vtotal * fps * fmt->bpp * -- scale_factor; -+ plane_pixel_rate = src_width * mode->vtotal * fps; -+ plane_bit_rate = plane_pixel_rate * fmt->bpp; - -- plane_prefill_bw = -- src_width * hw_latency_lines * fps * fmt->bpp * -- scale_factor * mode->vtotal; -+ plane_bw = plane_bit_rate * scale_factor; -+ -+ plane_prefill_bw = plane_bw * hw_latency_lines; - - if ((vbp+vpw) > hw_latency_lines) - do_div(plane_prefill_bw, (vbp+vpw)); -diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c -index dd26ca651a054..103eef9f059a0 100644 ---- a/drivers/gpu/drm/msm/dp/dp_ctrl.c -+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c -@@ -1711,13 +1711,6 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) - return rc; - - while (--link_train_max_retries) { -- rc = dp_ctrl_reinitialize_mainlink(ctrl); -- if (rc) { -- DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", -- rc); -- break; -- } -- - training_step = DP_TRAINING_NONE; - rc = dp_ctrl_setup_main_link(ctrl, &training_step); - if (rc == 0) { -@@ -1769,6 +1762,12 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) - /* stop link training before start re training */ - dp_ctrl_clear_training_pattern(ctrl); - } -+ -+ rc = dp_ctrl_reinitialize_mainlink(ctrl); -+ if (rc) { -+ DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc); -+ break; -+ } - } - - if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) -diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c -index 36bb6191d2f03..cb66d1126ea96 100644 ---- a/drivers/gpu/drm/msm/dp/dp_link.c -+++ b/drivers/gpu/drm/msm/dp/dp_link.c -@@ -1068,7 +1068,7 @@ int dp_link_process_request(struct dp_link *dp_link) - } - } - -- drm_dbg_dp(link->drm_dev, "sink request=%#x", -+ drm_dbg_dp(link->drm_dev, "sink request=%#x\n", - dp_link->sink_request); - return ret; - } -diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c -index b433ccfe4d7da..e20cd3dd2c6cc 100644 ---- a/drivers/gpu/drm/msm/dsi/dsi_host.c -+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c -@@ -1098,9 +1098,21 @@ static void dsi_wait4video_done(struct msm_dsi_host *msm_host) - - static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) - { -+ u32 data; -+ - if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)) - return; - -+ data = dsi_read(msm_host, REG_DSI_STATUS0); -+ -+ /* if video mode engine is not busy, its because -+ * either timing engine was not turned on or the -+ * DSI controller has finished transmitting the video -+ * data already, so no need to wait in those cases -+ */ -+ if (!(data & DSI_STATUS0_VIDEO_MODE_ENGINE_BUSY)) -+ return; -+ - if (msm_host->power_on && msm_host->enabled) { - dsi_wait4video_done(msm_host); - /* delay 4 ms to skip BLLP */ -@@ -1960,10 +1972,9 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) - } - - msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); -- if (msm_host->irq < 0) { -- ret = msm_host->irq; -- dev_err(&pdev->dev, "failed to get irq: %d\n", ret); -- return ret; -+ if (!msm_host->irq) { -+ dev_err(&pdev->dev, "failed to get irq\n"); -+ return -EINVAL; - } - - /* do not autoenable, will be enabled later */ -diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c -index e5a4ecde0063d..f138b3be1646f 100644 ---- a/drivers/gpu/drm/scheduler/sched_main.c -+++ b/drivers/gpu/drm/scheduler/sched_main.c -@@ -841,7 +841,7 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched) - - if (next) { - next->s_fence->scheduled.timestamp = -- job->s_fence->finished.timestamp; -+ dma_fence_timestamp(&job->s_fence->finished); - /* start TO timer for next job */ - drm_sched_start_timeout(sched); - } -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -index 58ca9adf09871..7e59469e1cb9f 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -@@ -1614,7 +1614,7 @@ static int vmw_cmd_tex_state(struct vmw_private *dev_priv, - { - VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetTextureState); - SVGA3dTextureState *last_state = (SVGA3dTextureState *) -- ((unsigned long) header + header->size + sizeof(header)); -+ ((unsigned long) header + header->size + sizeof(*header)); - SVGA3dTextureState *cur_state = (SVGA3dTextureState *) - ((unsigned long) header + sizeof(*cmd)); - struct vmw_resource *ctx; -diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c -index 97eefb77f6014..fb427391c3b86 100644 ---- a/drivers/hid/hid-logitech-hidpp.c -+++ b/drivers/hid/hid-logitech-hidpp.c -@@ -4275,7 +4275,8 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) - goto hid_hw_init_fail; - } - -- hidpp_connect_event(hidpp); -+ schedule_work(&hidpp->work); -+ flush_work(&hidpp->work); - - if (will_restart) { - /* Reset the HID node state */ -diff --git a/drivers/iio/adc/imx8qxp-adc.c b/drivers/iio/adc/imx8qxp-adc.c -index f5a0fc9e64c54..fff6e5a2d9569 100644 ---- a/drivers/iio/adc/imx8qxp-adc.c -+++ b/drivers/iio/adc/imx8qxp-adc.c -@@ -38,8 +38,8 @@ - #define IMX8QXP_ADR_ADC_FCTRL 0x30 - #define IMX8QXP_ADR_ADC_SWTRIG 0x34 - #define IMX8QXP_ADR_ADC_TCTRL(tid) (0xc0 + (tid) * 4) --#define IMX8QXP_ADR_ADC_CMDH(cid) (0x100 + (cid) * 8) --#define IMX8QXP_ADR_ADC_CMDL(cid) (0x104 + (cid) * 8) -+#define IMX8QXP_ADR_ADC_CMDL(cid) (0x100 + (cid) * 8) -+#define IMX8QXP_ADR_ADC_CMDH(cid) (0x104 + (cid) * 8) - #define IMX8QXP_ADR_ADC_RESFIFO 0x300 - #define IMX8QXP_ADR_ADC_TST 0xffc - -diff --git a/drivers/iio/addac/Kconfig b/drivers/iio/addac/Kconfig -index fcf6d2269bfc2..3507cd6ab4e54 100644 ---- a/drivers/iio/addac/Kconfig -+++ b/drivers/iio/addac/Kconfig -@@ -10,6 +10,8 @@ config AD74413R - depends on GPIOLIB && SPI - select REGMAP_SPI - select CRC8 -+ select IIO_BUFFER -+ select IIO_TRIGGERED_BUFFER - help - Say yes here to build support for Analog Devices AD74412R/AD74413R - quad-channel software configurable input/output solution. -diff --git a/drivers/iio/dac/ad3552r.c b/drivers/iio/dac/ad3552r.c -index d5ea1a1be1226..a492e8f2fc0fb 100644 ---- a/drivers/iio/dac/ad3552r.c -+++ b/drivers/iio/dac/ad3552r.c -@@ -140,8 +140,8 @@ enum ad3552r_ch_vref_select { - }; - - enum ad3542r_id { -- AD3542R_ID = 0x4008, -- AD3552R_ID = 0x4009, -+ AD3542R_ID = 0x4009, -+ AD3552R_ID = 0x4008, - }; - - enum ad3552r_ch_output_range { -diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c -index e6311213f3e89..d15b85377159b 100644 ---- a/drivers/iio/frequency/admv1013.c -+++ b/drivers/iio/frequency/admv1013.c -@@ -351,9 +351,9 @@ static int admv1013_update_mixer_vgate(struct admv1013_state *st) - if (vcm < 0) - return vcm; - -- if (vcm < 1800000) -+ if (vcm <= 1800000) - mixer_vgate = (2389 * vcm / 1000000 + 8100) / 100; -- else if (vcm > 1800000 && vcm < 2600000) -+ else if (vcm > 1800000 && vcm <= 2600000) - mixer_vgate = (2375 * vcm / 1000000 + 125) / 100; - else - return -EINVAL; -diff --git a/drivers/iio/imu/bno055/Kconfig b/drivers/iio/imu/bno055/Kconfig -index fa79b1ac4f85b..83e53acfbe880 100644 ---- a/drivers/iio/imu/bno055/Kconfig -+++ b/drivers/iio/imu/bno055/Kconfig -@@ -2,6 +2,8 @@ - - config BOSCH_BNO055 - tristate -+ select IIO_BUFFER -+ select IIO_TRIGGERED_BUFFER - - config BOSCH_BNO055_SERIAL - tristate "Bosch BNO055 attached via UART" -diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c -index c0aff78489b46..4c867157aa968 100644 ---- a/drivers/iio/pressure/bmp280-core.c -+++ b/drivers/iio/pressure/bmp280-core.c -@@ -1786,7 +1786,7 @@ int bmp280_common_probe(struct device *dev, - * however as it happens, the BMP085 shares the chip ID of BMP180 - * so we look for an IRQ if we have that. - */ -- if (irq > 0 || (chip_id == BMP180_CHIP_ID)) { -+ if (irq > 0 && (chip_id == BMP180_CHIP_ID)) { - ret = bmp085_fetch_eoc_irq(dev, name, irq, data); - if (ret) - return ret; -diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c -index 984a3f511a1ae..db1b1e48225aa 100644 ---- a/drivers/iio/pressure/dps310.c -+++ b/drivers/iio/pressure/dps310.c -@@ -57,8 +57,8 @@ - #define DPS310_RESET_MAGIC 0x09 - #define DPS310_COEF_BASE 0x10 - --/* Make sure sleep time is <= 20ms for usleep_range */ --#define DPS310_POLL_SLEEP_US(t) min(20000, (t) / 8) -+/* Make sure sleep time is <= 30ms for usleep_range */ -+#define DPS310_POLL_SLEEP_US(t) min(30000, (t) / 8) - /* Silently handle error in rate value here */ - #define DPS310_POLL_TIMEOUT_US(rc) ((rc) <= 0 ? 1000000 : 1000000 / (rc)) - -@@ -402,8 +402,8 @@ static int dps310_reset_wait(struct dps310_data *data) - if (rc) - return rc; - -- /* Wait for device chip access: 2.5ms in specification */ -- usleep_range(2500, 12000); -+ /* Wait for device chip access: 15ms in specification */ -+ usleep_range(15000, 55000); - return 0; - } - -diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c -index c564a1d6cafe8..44cfdbedcfaab 100644 ---- a/drivers/iio/pressure/ms5611_core.c -+++ b/drivers/iio/pressure/ms5611_core.c -@@ -76,7 +76,7 @@ static bool ms5611_prom_is_valid(u16 *prom, size_t len) - - crc = (crc >> 12) & 0x000F; - -- return crc_orig != 0x0000 && crc == crc_orig; -+ return crc == crc_orig; - } - - static int ms5611_read_prom(struct iio_dev *indio_dev) -diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c -index ced615b5ea096..040ba2224f9ff 100644 ---- a/drivers/infiniband/hw/cxgb4/cm.c -+++ b/drivers/infiniband/hw/cxgb4/cm.c -@@ -1965,6 +1965,9 @@ static int send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid) - int win; - - skb = get_skb(NULL, sizeof(*req), GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ - req = __skb_put_zero(skb, sizeof(*req)); - req->op_compl = htonl(WR_OP_V(FW_OFLD_CONNECTION_WR)); - req->len16_pkd = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*req), 16))); -diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c -index 76cbcca13c9e9..c19a4d2023805 100644 ---- a/drivers/input/joystick/xpad.c -+++ b/drivers/input/joystick/xpad.c -@@ -272,6 +272,7 @@ static const struct xpad_device { - { 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 }, - { 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 }, - { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 }, -+ { 0x11ff, 0x0511, "PXN V900", 0, XTYPE_XBOX360 }, - { 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 }, - { 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, - { 0x12ab, 0x0301, "PDP AFTERGLOW AX.1", 0, XTYPE_XBOX360 }, -@@ -474,6 +475,7 @@ static const struct usb_device_id xpad_table[] = { - XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */ - XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries Controllers */ - XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */ -+ XPAD_XBOX360_VENDOR(0x11ff), /* PXN V900 */ - XPAD_XBOX360_VENDOR(0x1209), /* Ardwiino Controllers */ - XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ - XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ -diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c -index c1c733a9cb890..db2ba89adaefa 100644 ---- a/drivers/input/misc/powermate.c -+++ b/drivers/input/misc/powermate.c -@@ -425,6 +425,7 @@ static void powermate_disconnect(struct usb_interface *intf) - pm->requires_update = 0; - usb_kill_urb(pm->irq); - input_unregister_device(pm->input); -+ usb_kill_urb(pm->config); - usb_free_urb(pm->irq); - usb_free_urb(pm->config); - powermate_free_buffers(interface_to_usbdev(intf), pm); -diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c -index 2118b2075f437..4e38229404b4b 100644 ---- a/drivers/input/mouse/elantech.c -+++ b/drivers/input/mouse/elantech.c -@@ -2114,6 +2114,7 @@ static int elantech_setup_ps2(struct psmouse *psmouse, - psmouse->protocol_handler = elantech_process_byte; - psmouse->disconnect = elantech_disconnect; - psmouse->reconnect = elantech_reconnect; -+ psmouse->fast_reconnect = NULL; - psmouse->pktsize = info->hw_version > 1 ? 6 : 4; - - return 0; -diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c -index fa021af8506e4..d2c9f4cbd00c6 100644 ---- a/drivers/input/mouse/synaptics.c -+++ b/drivers/input/mouse/synaptics.c -@@ -1623,6 +1623,7 @@ static int synaptics_init_ps2(struct psmouse *psmouse, - psmouse->set_rate = synaptics_set_rate; - psmouse->disconnect = synaptics_disconnect; - psmouse->reconnect = synaptics_reconnect; -+ psmouse->fast_reconnect = NULL; - psmouse->cleanup = synaptics_reset; - /* Synaptics can usually stay in sync without extra help */ - psmouse->resync_time = 0; -diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h -index 1724d6cb8649d..9c39553d30fa2 100644 ---- a/drivers/input/serio/i8042-acpipnpio.h -+++ b/drivers/input/serio/i8042-acpipnpio.h -@@ -618,6 +618,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { - }, - .driver_data = (void *)(SERIO_QUIRK_NOMUX) - }, -+ { -+ /* Fujitsu Lifebook E5411 */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU CLIENT COMPUTING LIMITED"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E5411"), -+ }, -+ .driver_data = (void *)(SERIO_QUIRK_NOAUX) -+ }, - { - /* Gigabyte M912 */ - .matches = { -diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c -index 25e575183dd18..3f0732db7bf5b 100644 ---- a/drivers/input/touchscreen/goodix.c -+++ b/drivers/input/touchscreen/goodix.c -@@ -900,6 +900,25 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) - dev_info(dev, "No ACPI GpioInt resource, assuming that the GPIO order is reset, int\n"); - ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; - gpio_mapping = acpi_goodix_int_last_gpios; -+ } else if (ts->gpio_count == 1 && ts->gpio_int_idx == 0) { -+ /* -+ * On newer devices there is only 1 GpioInt resource and _PS0 -+ * does the whole reset sequence for us. -+ */ -+ acpi_device_fix_up_power(ACPI_COMPANION(dev)); -+ -+ /* -+ * Before the _PS0 call the int GPIO may have been in output -+ * mode and the call should have put the int GPIO in input mode, -+ * but the GPIO subsys cached state may still think it is -+ * in output mode, causing gpiochip_lock_as_irq() failure. -+ * -+ * Add a mapping for the int GPIO to make the -+ * gpiod_int = gpiod_get(..., GPIOD_IN) call succeed, -+ * which will explicitly set the direction to input. -+ */ -+ ts->irq_pin_access_method = IRQ_PIN_ACCESS_NONE; -+ gpio_mapping = acpi_goodix_int_first_gpios; - } else { - dev_warn(dev, "Unexpected ACPI resources: gpio_count %d, gpio_int_idx %d\n", - ts->gpio_count, ts->gpio_int_idx); -diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c -index 25fd8ee66565b..10c3e85c90c23 100644 ---- a/drivers/irqchip/irq-renesas-rzg2l.c -+++ b/drivers/irqchip/irq-renesas-rzg2l.c -@@ -118,7 +118,7 @@ static void rzg2l_irqc_irq_disable(struct irq_data *d) - - raw_spin_lock(&priv->lock); - reg = readl_relaxed(priv->base + TSSR(tssr_index)); -- reg &= ~(TSSEL_MASK << tssr_offset); -+ reg &= ~(TSSEL_MASK << TSSEL_SHIFT(tssr_offset)); - writel_relaxed(reg, priv->base + TSSR(tssr_index)); - raw_spin_unlock(&priv->lock); - } -diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c -index b8ad4f16b4acd..e7b6989d8b4a8 100644 ---- a/drivers/mcb/mcb-core.c -+++ b/drivers/mcb/mcb-core.c -@@ -387,17 +387,13 @@ EXPORT_SYMBOL_NS_GPL(mcb_free_dev, MCB); - - static int __mcb_bus_add_devices(struct device *dev, void *data) - { -- struct mcb_device *mdev = to_mcb_device(dev); - int retval; - -- if (mdev->is_added) -- return 0; -- - retval = device_attach(dev); -- if (retval < 0) -+ if (retval < 0) { - dev_err(dev, "Error adding device (%d)\n", retval); -- -- mdev->is_added = true; -+ return retval; -+ } - - return 0; - } -diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c -index aa6938da0db85..c41cbacc75a2c 100644 ---- a/drivers/mcb/mcb-parse.c -+++ b/drivers/mcb/mcb-parse.c -@@ -99,8 +99,6 @@ static int chameleon_parse_gdd(struct mcb_bus *bus, - mdev->mem.end = mdev->mem.start + size - 1; - mdev->mem.flags = IORESOURCE_MEM; - -- mdev->is_added = false; -- - ret = mcb_device_register(bus, mdev); - if (ret < 0) - goto err; -diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig -index 8236aabebb394..e45b95a13157b 100644 ---- a/drivers/net/can/Kconfig -+++ b/drivers/net/can/Kconfig -@@ -174,7 +174,7 @@ config CAN_SLCAN - - config CAN_SUN4I - tristate "Allwinner A10 CAN controller" -- depends on MACH_SUN4I || MACH_SUN7I || RISCV || COMPILE_TEST -+ depends on MACH_SUN4I || MACH_SUN7I || (RISCV && ARCH_SUNXI) || COMPILE_TEST - help - Say Y here if you want to use CAN controller found on Allwinner - A10/A20/D1 SoCs. -diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c -index b3f7988668996..1e94ba1031ece 100644 ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -544,6 +544,15 @@ qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, - goto err_read_skb; - } - -+ /* It seems that accessing the switch's internal PHYs via management -+ * packets still uses the MDIO bus within the switch internally, and -+ * these accesses can conflict with external MDIO accesses to other -+ * devices on the MDIO bus. -+ * We therefore need to lock the MDIO bus onto which the switch is -+ * connected. -+ */ -+ mutex_lock(&priv->bus->mdio_lock); -+ - /* Actually start the request: - * 1. Send mdio master packet - * 2. Busy Wait for mdio master command -@@ -556,6 +565,7 @@ qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, - mgmt_master = priv->mgmt_master; - if (!mgmt_master) { - mutex_unlock(&mgmt_eth_data->mutex); -+ mutex_unlock(&priv->bus->mdio_lock); - ret = -EINVAL; - goto err_mgmt_master; - } -@@ -643,6 +653,7 @@ exit: - QCA8K_ETHERNET_TIMEOUT); - - mutex_unlock(&mgmt_eth_data->mutex); -+ mutex_unlock(&priv->bus->mdio_lock); - - return ret; - -diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c -index 29cc609880712..ea88ac04ab9ad 100644 ---- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c -+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c -@@ -28,6 +28,9 @@ static inline void ixgbe_alloc_vf_macvlans(struct ixgbe_adapter *adapter, - struct vf_macvlans *mv_list; - int num_vf_macvlans, i; - -+ /* Initialize list of VF macvlans */ -+ INIT_LIST_HEAD(&adapter->vf_mvs.l); -+ - num_vf_macvlans = hw->mac.num_rar_entries - - (IXGBE_MAX_PF_MACVLANS + 1 + num_vfs); - if (!num_vf_macvlans) -@@ -36,8 +39,6 @@ static inline void ixgbe_alloc_vf_macvlans(struct ixgbe_adapter *adapter, - mv_list = kcalloc(num_vf_macvlans, sizeof(struct vf_macvlans), - GFP_KERNEL); - if (mv_list) { -- /* Initialize list of VF macvlans */ -- INIT_LIST_HEAD(&adapter->vf_mvs.l); - for (i = 0; i < num_vf_macvlans; i++) { - mv_list[i].vf = -1; - mv_list[i].free = true; -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c -index 0f8f3ce35537d..a7832a0180ee6 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c -@@ -611,7 +611,7 @@ static int mlx5e_macsec_upd_txsa(struct macsec_context *ctx) - goto out; - } - -- if (tx_sa->next_pn != ctx_tx_sa->next_pn_halves.lower) { -+ if (ctx->sa.update_pn) { - netdev_err(netdev, "MACsec offload: update TX sa %d PN isn't supported\n", - assoc_num); - err = -EINVAL; -@@ -1016,7 +1016,7 @@ static int mlx5e_macsec_upd_rxsa(struct macsec_context *ctx) - goto out; - } - -- if (rx_sa->next_pn != ctx_rx_sa->next_pn_halves.lower) { -+ if (ctx->sa.update_pn) { - netdev_err(ctx->netdev, - "MACsec offload update RX sa %d PN isn't supported\n", - assoc_num); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -index 4e7daa382bc05..42e6f2fcf5f59 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -@@ -3862,13 +3862,14 @@ static int set_feature_rx_fcs(struct net_device *netdev, bool enable) - struct mlx5e_channels *chs = &priv->channels; - struct mlx5e_params new_params; - int err; -+ bool rx_ts_over_crc = !enable; - - mutex_lock(&priv->state_lock); - - new_params = chs->params; - new_params.scatter_fcs_en = enable; - err = mlx5e_safe_switch_params(priv, &new_params, mlx5e_set_rx_port_ts_wrap, -- &new_params.scatter_fcs_en, true); -+ &rx_ts_over_crc, true); - mutex_unlock(&priv->state_lock); - return err; - } -diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c -index d309b77a01944..cdd8818b49d0a 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c -@@ -308,8 +308,8 @@ const struct mlxsw_sp_nve_ops mlxsw_sp1_nve_vxlan_ops = { - .fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload, - }; - --static bool mlxsw_sp2_nve_vxlan_learning_set(struct mlxsw_sp *mlxsw_sp, -- bool learning_en) -+static int mlxsw_sp2_nve_vxlan_learning_set(struct mlxsw_sp *mlxsw_sp, -+ bool learning_en) - { - char tnpc_pl[MLXSW_REG_TNPC_LEN]; - -diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c -index 4f4204432aaa3..b751b03eddfb1 100644 ---- a/drivers/net/ethernet/microsoft/mana/mana_en.c -+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c -@@ -1003,17 +1003,21 @@ static void mana_poll_tx_cq(struct mana_cq *cq) - case CQE_TX_VPORT_IDX_OUT_OF_RANGE: - case CQE_TX_VPORT_DISABLED: - case CQE_TX_VLAN_TAGGING_VIOLATION: -- WARN_ONCE(1, "TX: CQE error %d: ignored.\n", -- cqe_oob->cqe_hdr.cqe_type); -+ if (net_ratelimit()) -+ netdev_err(ndev, "TX: CQE error %d\n", -+ cqe_oob->cqe_hdr.cqe_type); -+ - break; - - default: -- /* If the CQE type is unexpected, log an error, assert, -- * and go through the error path. -+ /* If the CQE type is unknown, log an error, -+ * and still free the SKB, update tail, etc. - */ -- WARN_ONCE(1, "TX: Unexpected CQE type %d: HW BUG?\n", -- cqe_oob->cqe_hdr.cqe_type); -- return; -+ if (net_ratelimit()) -+ netdev_err(ndev, "TX: unknown CQE type %d\n", -+ cqe_oob->cqe_hdr.cqe_type); -+ -+ break; - } - - if (WARN_ON_ONCE(txq->gdma_txq_id != completions[i].wq_num)) -diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c -index f21cf1f40f987..153533cd8f086 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c -+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c -@@ -210,6 +210,7 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb) - unsigned int msg_len = nfp_flower_cmsg_get_data_len(skb); - struct nfp_flower_cmsg_merge_hint *msg; - struct nfp_fl_payload *sub_flows[2]; -+ struct nfp_flower_priv *priv; - int err, i, flow_cnt; - - msg = nfp_flower_cmsg_get_data(skb); -@@ -228,14 +229,15 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb) - return; - } - -- rtnl_lock(); -+ priv = app->priv; -+ mutex_lock(&priv->nfp_fl_lock); - for (i = 0; i < flow_cnt; i++) { - u32 ctx = be32_to_cpu(msg->flow[i].host_ctx); - - sub_flows[i] = nfp_flower_get_fl_payload_from_ctx(app, ctx); - if (!sub_flows[i]) { - nfp_flower_cmsg_warn(app, "Invalid flow in merge hint\n"); -- goto err_rtnl_unlock; -+ goto err_mutex_unlock; - } - } - -@@ -244,8 +246,8 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb) - if (err == -ENOMEM) - nfp_flower_cmsg_warn(app, "Flow merge memory fail.\n"); - --err_rtnl_unlock: -- rtnl_unlock(); -+err_mutex_unlock: -+ mutex_unlock(&priv->nfp_fl_lock); - } - - static void -diff --git a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c -index f693119541d55..f7492be452aed 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c -+++ b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c -@@ -1971,8 +1971,6 @@ nfp_fl_ct_offload_nft_flow(struct nfp_fl_ct_zone_entry *zt, struct flow_cls_offl - struct nfp_fl_ct_flow_entry *ct_entry; - struct netlink_ext_ack *extack = NULL; - -- ASSERT_RTNL(); -- - extack = flow->common.extack; - switch (flow->command) { - case FLOW_CLS_REPLACE: -@@ -2015,9 +2013,13 @@ int nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data, void *cb - - switch (type) { - case TC_SETUP_CLSFLOWER: -- rtnl_lock(); -+ while (!mutex_trylock(&zt->priv->nfp_fl_lock)) { -+ if (!zt->nft) /* avoid deadlock */ -+ return err; -+ msleep(20); -+ } - err = nfp_fl_ct_offload_nft_flow(zt, flow); -- rtnl_unlock(); -+ mutex_unlock(&zt->priv->nfp_fl_lock); - break; - default: - return -EOPNOTSUPP; -@@ -2045,6 +2047,7 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent) - struct nfp_fl_ct_flow_entry *ct_entry; - struct nfp_fl_ct_zone_entry *zt; - struct rhashtable *m_table; -+ struct nf_flowtable *nft; - - if (!ct_map_ent) - return -ENOENT; -@@ -2061,8 +2064,12 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent) - nfp_fl_ct_clean_flow_entry(ct_entry); - kfree(ct_map_ent); - -- if (!zt->pre_ct_count) { -- zt->nft = NULL; -+ if (!zt->pre_ct_count && zt->nft) { -+ nft = zt->nft; -+ zt->nft = NULL; /* avoid deadlock */ -+ nf_flow_table_offload_del_cb(nft, -+ nfp_fl_ct_handle_nft_flow, -+ zt); - nfp_fl_ct_clean_nft_entries(zt); - } - break; -diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h -index cb799d18682d9..d0ab71ce3d84f 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/main.h -+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h -@@ -281,6 +281,7 @@ struct nfp_fl_internal_ports { - * @predt_list: List to keep track of decap pretun flows - * @neigh_table: Table to keep track of neighbor entries - * @predt_lock: Lock to serialise predt/neigh table updates -+ * @nfp_fl_lock: Lock to protect the flow offload operation - */ - struct nfp_flower_priv { - struct nfp_app *app; -@@ -323,6 +324,7 @@ struct nfp_flower_priv { - struct list_head predt_list; - struct rhashtable neigh_table; - spinlock_t predt_lock; /* Lock to serialise predt/neigh table updates */ -+ struct mutex nfp_fl_lock; /* Protect the flow operation */ - }; - - /** -diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c -index 0f06ef6e24bf4..80e4675582bfb 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c -+++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c -@@ -528,6 +528,8 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, - if (err) - goto err_free_stats_ctx_table; - -+ mutex_init(&priv->nfp_fl_lock); -+ - err = rhashtable_init(&priv->ct_zone_table, &nfp_zone_table_params); - if (err) - goto err_free_merge_table; -diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c -index 8593cafa63683..99165694f1367 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/offload.c -+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c -@@ -1009,8 +1009,6 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, - u64 parent_ctx = 0; - int err; - -- ASSERT_RTNL(); -- - if (sub_flow1 == sub_flow2 || - nfp_flower_is_merge_flow(sub_flow1) || - nfp_flower_is_merge_flow(sub_flow2)) -@@ -1727,19 +1725,30 @@ static int - nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, - struct flow_cls_offload *flower) - { -+ struct nfp_flower_priv *priv = app->priv; -+ int ret; -+ - if (!eth_proto_is_802_3(flower->common.protocol)) - return -EOPNOTSUPP; - -+ mutex_lock(&priv->nfp_fl_lock); - switch (flower->command) { - case FLOW_CLS_REPLACE: -- return nfp_flower_add_offload(app, netdev, flower); -+ ret = nfp_flower_add_offload(app, netdev, flower); -+ break; - case FLOW_CLS_DESTROY: -- return nfp_flower_del_offload(app, netdev, flower); -+ ret = nfp_flower_del_offload(app, netdev, flower); -+ break; - case FLOW_CLS_STATS: -- return nfp_flower_get_stats(app, netdev, flower); -+ ret = nfp_flower_get_stats(app, netdev, flower); -+ break; - default: -- return -EOPNOTSUPP; -+ ret = -EOPNOTSUPP; -+ break; - } -+ mutex_unlock(&priv->nfp_fl_lock); -+ -+ return ret; - } - - static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type, -@@ -1778,6 +1787,7 @@ static int nfp_flower_setup_tc_block(struct net_device *netdev, - repr_priv = repr->app_priv; - repr_priv->block_shared = f->block_shared; - f->driver_block_list = &nfp_block_cb_list; -+ f->unlocked_driver_cb = true; - - switch (f->command) { - case FLOW_BLOCK_BIND: -@@ -1876,6 +1886,8 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct Qdisc *sch, str - nfp_flower_internal_port_can_offload(app, netdev))) - return -EOPNOTSUPP; - -+ f->unlocked_driver_cb = true; -+ - switch (f->command) { - case FLOW_BLOCK_BIND: - cb_priv = nfp_flower_indr_block_cb_priv_lookup(app, netdev); -diff --git a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c -index 99052a925d9ec..e7180b4793c7d 100644 ---- a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c -+++ b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c -@@ -523,25 +523,31 @@ int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev, - { - struct netlink_ext_ack *extack = flow->common.extack; - struct nfp_flower_priv *fl_priv = app->priv; -+ int ret; - - if (!(fl_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)) { - NL_SET_ERR_MSG_MOD(extack, "unsupported offload: loaded firmware does not support qos rate limit offload"); - return -EOPNOTSUPP; - } - -+ mutex_lock(&fl_priv->nfp_fl_lock); - switch (flow->command) { - case TC_CLSMATCHALL_REPLACE: -- return nfp_flower_install_rate_limiter(app, netdev, flow, -- extack); -+ ret = nfp_flower_install_rate_limiter(app, netdev, flow, extack); -+ break; - case TC_CLSMATCHALL_DESTROY: -- return nfp_flower_remove_rate_limiter(app, netdev, flow, -- extack); -+ ret = nfp_flower_remove_rate_limiter(app, netdev, flow, extack); -+ break; - case TC_CLSMATCHALL_STATS: -- return nfp_flower_stats_rate_limiter(app, netdev, flow, -- extack); -+ ret = nfp_flower_stats_rate_limiter(app, netdev, flow, extack); -+ break; - default: -- return -EOPNOTSUPP; -+ ret = -EOPNOTSUPP; -+ break; - } -+ mutex_unlock(&fl_priv->nfp_fl_lock); -+ -+ return ret; - } - - /* Offload tc action, currently only for tc police */ -diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c -index 894e2690c6437..9a52283d77544 100644 ---- a/drivers/net/ethernet/renesas/ravb_main.c -+++ b/drivers/net/ethernet/renesas/ravb_main.c -@@ -2183,6 +2183,8 @@ static int ravb_close(struct net_device *ndev) - of_phy_deregister_fixed_link(np); - } - -+ cancel_work_sync(&priv->work); -+ - if (info->multi_irqs) { - free_irq(priv->tx_irqs[RAVB_NC], ndev); - free_irq(priv->rx_irqs[RAVB_NC], ndev); -@@ -2907,8 +2909,6 @@ static int ravb_remove(struct platform_device *pdev) - clk_disable_unprepare(priv->gptp_clk); - clk_disable_unprepare(priv->refclk); - -- dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat, -- priv->desc_bat_dma); - /* Set reset mode */ - ravb_write(ndev, CCC_OPC_RESET, CCC); - unregister_netdev(ndev); -@@ -2916,6 +2916,8 @@ static int ravb_remove(struct platform_device *pdev) - netif_napi_del(&priv->napi[RAVB_NC]); - netif_napi_del(&priv->napi[RAVB_BE]); - ravb_mdio_release(priv); -+ dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat, -+ priv->desc_bat_dma); - pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - reset_control_assert(priv->rstc); -diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c -index d0b5129439ed6..c2201e0adc46c 100644 ---- a/drivers/net/ieee802154/ca8210.c -+++ b/drivers/net/ieee802154/ca8210.c -@@ -2740,7 +2740,6 @@ static int ca8210_register_ext_clock(struct spi_device *spi) - struct device_node *np = spi->dev.of_node; - struct ca8210_priv *priv = spi_get_drvdata(spi); - struct ca8210_platform_data *pdata = spi->dev.platform_data; -- int ret = 0; - - if (!np) - return -EFAULT; -@@ -2757,18 +2756,8 @@ static int ca8210_register_ext_clock(struct spi_device *spi) - dev_crit(&spi->dev, "Failed to register external clk\n"); - return PTR_ERR(priv->clk); - } -- ret = of_clk_add_provider(np, of_clk_src_simple_get, priv->clk); -- if (ret) { -- clk_unregister(priv->clk); -- dev_crit( -- &spi->dev, -- "Failed to register external clock as clock provider\n" -- ); -- } else { -- dev_info(&spi->dev, "External clock set as clock provider\n"); -- } - -- return ret; -+ return of_clk_add_provider(np, of_clk_src_simple_get, priv->clk); - } - - /** -@@ -2780,8 +2769,8 @@ static void ca8210_unregister_ext_clock(struct spi_device *spi) - { - struct ca8210_priv *priv = spi_get_drvdata(spi); - -- if (!priv->clk) -- return -+ if (IS_ERR_OR_NULL(priv->clk)) -+ return; - - of_clk_del_provider(spi->dev.of_node); - clk_unregister(priv->clk); -diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c -index 578f470e9fad9..81453e84b6413 100644 ---- a/drivers/net/macsec.c -+++ b/drivers/net/macsec.c -@@ -2384,6 +2384,7 @@ static int macsec_upd_txsa(struct sk_buff *skb, struct genl_info *info) - - ctx.sa.assoc_num = assoc_num; - ctx.sa.tx_sa = tx_sa; -+ ctx.sa.update_pn = !!prev_pn.full64; - ctx.secy = secy; - - ret = macsec_offload(ops->mdo_upd_txsa, &ctx); -@@ -2477,6 +2478,7 @@ static int macsec_upd_rxsa(struct sk_buff *skb, struct genl_info *info) - - ctx.sa.assoc_num = assoc_num; - ctx.sa.rx_sa = rx_sa; -+ ctx.sa.update_pn = !!prev_pn.full64; - ctx.secy = secy; - - ret = macsec_offload(ops->mdo_upd_rxsa, &ctx); -diff --git a/drivers/net/phy/mscc/mscc_macsec.c b/drivers/net/phy/mscc/mscc_macsec.c -index f81b077618f40..81fd9bfef5271 100644 ---- a/drivers/net/phy/mscc/mscc_macsec.c -+++ b/drivers/net/phy/mscc/mscc_macsec.c -@@ -844,6 +844,9 @@ static int vsc8584_macsec_upd_rxsa(struct macsec_context *ctx) - struct macsec_flow *flow; - int ret; - -+ if (ctx->sa.update_pn) -+ return -EINVAL; -+ - flow = vsc8584_macsec_find_flow(ctx, MACSEC_INGR); - if (IS_ERR(flow)) - return PTR_ERR(flow); -@@ -897,6 +900,9 @@ static int vsc8584_macsec_upd_txsa(struct macsec_context *ctx) - struct macsec_flow *flow; - int ret; - -+ if (ctx->sa.update_pn) -+ return -EINVAL; -+ - flow = vsc8584_macsec_find_flow(ctx, MACSEC_EGR); - if (IS_ERR(flow)) - return PTR_ERR(flow); -diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c -index 48d7d278631e9..99ec1d4a972db 100644 ---- a/drivers/net/usb/dm9601.c -+++ b/drivers/net/usb/dm9601.c -@@ -222,13 +222,18 @@ static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc) - struct usbnet *dev = netdev_priv(netdev); - - __le16 res; -+ int err; - - if (phy_id) { - netdev_dbg(dev->net, "Only internal phy supported\n"); - return 0; - } - -- dm_read_shared_word(dev, 1, loc, &res); -+ err = dm_read_shared_word(dev, 1, loc, &res); -+ if (err < 0) { -+ netdev_err(dev->net, "MDIO read error: %d\n", err); -+ return err; -+ } - - netdev_dbg(dev->net, - "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", -diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c -index f3f2c07423a6a..fc3bb63b9ac3e 100644 ---- a/drivers/net/xen-netback/interface.c -+++ b/drivers/net/xen-netback/interface.c -@@ -41,8 +41,6 @@ - #include - #include - --#define XENVIF_QUEUE_LENGTH 32 -- - /* Number of bytes allowed on the internal guest Rx queue. */ - #define XENVIF_RX_QUEUE_BYTES (XEN_NETIF_RX_RING_SIZE/2 * PAGE_SIZE) - -@@ -530,8 +528,6 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, - dev->features = dev->hw_features | NETIF_F_RXCSUM; - dev->ethtool_ops = &xenvif_ethtool_ops; - -- dev->tx_queue_len = XENVIF_QUEUE_LENGTH; -- - dev->min_mtu = ETH_MIN_MTU; - dev->max_mtu = ETH_MAX_MTU - VLAN_ETH_HLEN; - -diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c -index 90008e24d1cc7..cfb36adf4eb80 100644 ---- a/drivers/perf/arm-cmn.c -+++ b/drivers/perf/arm-cmn.c -@@ -1822,7 +1822,7 @@ static irqreturn_t arm_cmn_handle_irq(int irq, void *dev_id) - u64 delta; - int i; - -- for (i = 0; i < CMN_DTM_NUM_COUNTERS; i++) { -+ for (i = 0; i < CMN_DT_NUM_COUNTERS; i++) { - if (status & (1U << i)) { - ret = IRQ_HANDLED; - if (WARN_ON(!dtc->counters[i])) -diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c -index 569f12af2aafa..0a8b40edc3f31 100644 ---- a/drivers/phy/freescale/phy-fsl-lynx-28g.c -+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c -@@ -126,6 +126,10 @@ struct lynx_28g_lane { - struct lynx_28g_priv { - void __iomem *base; - struct device *dev; -+ /* Serialize concurrent access to registers shared between lanes, -+ * like PCCn -+ */ -+ spinlock_t pcc_lock; - struct lynx_28g_pll pll[LYNX_28G_NUM_PLL]; - struct lynx_28g_lane lane[LYNX_28G_NUM_LANE]; - -@@ -396,6 +400,8 @@ static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode) - if (powered_up) - lynx_28g_power_off(phy); - -+ spin_lock(&priv->pcc_lock); -+ - switch (submode) { - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_1000BASEX: -@@ -412,6 +418,8 @@ static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode) - lane->interface = submode; - - out: -+ spin_unlock(&priv->pcc_lock); -+ - /* Power up the lane if necessary */ - if (powered_up) - lynx_28g_power_on(phy); -@@ -507,11 +515,12 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work) - for (i = 0; i < LYNX_28G_NUM_LANE; i++) { - lane = &priv->lane[i]; - -- if (!lane->init) -- continue; -+ mutex_lock(&lane->phy->mutex); - -- if (!lane->powered_up) -+ if (!lane->init || !lane->powered_up) { -+ mutex_unlock(&lane->phy->mutex); - continue; -+ } - - rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); - if (!(rrstctl & LYNX_28G_LNaRRSTCTL_CDR_LOCK)) { -@@ -520,6 +529,8 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work) - rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); - } while (!(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); - } -+ -+ mutex_unlock(&lane->phy->mutex); - } - queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, - msecs_to_jiffies(1000)); -@@ -592,6 +603,7 @@ static int lynx_28g_probe(struct platform_device *pdev) - - dev_set_drvdata(dev, priv); - -+ spin_lock_init(&priv->pcc_lock); - INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); - - queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, -@@ -603,6 +615,14 @@ static int lynx_28g_probe(struct platform_device *pdev) - return PTR_ERR_OR_ZERO(provider); - } - -+static void lynx_28g_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct lynx_28g_priv *priv = dev_get_drvdata(dev); -+ -+ cancel_delayed_work_sync(&priv->cdr_check); -+} -+ - static const struct of_device_id lynx_28g_of_match_table[] = { - { .compatible = "fsl,lynx-28g" }, - { }, -@@ -611,6 +631,7 @@ MODULE_DEVICE_TABLE(of, lynx_28g_of_match_table); - - static struct platform_driver lynx_28g_driver = { - .probe = lynx_28g_probe, -+ .remove_new = lynx_28g_remove, - .driver = { - .name = "lynx-28g", - .of_match_table = lynx_28g_of_match_table, -diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c -index 9e57f4c62e609..27e41873c04ff 100644 ---- a/drivers/pinctrl/core.c -+++ b/drivers/pinctrl/core.c -@@ -1007,17 +1007,20 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev, - - static struct pinctrl *find_pinctrl(struct device *dev) - { -- struct pinctrl *p; -+ struct pinctrl *entry, *p = NULL; - - mutex_lock(&pinctrl_list_mutex); -- list_for_each_entry(p, &pinctrl_list, node) -- if (p->dev == dev) { -- mutex_unlock(&pinctrl_list_mutex); -- return p; -+ -+ list_for_each_entry(entry, &pinctrl_list, node) { -+ if (entry->dev == dev) { -+ p = entry; -+ kref_get(&p->users); -+ break; - } -+ } - - mutex_unlock(&pinctrl_list_mutex); -- return NULL; -+ return p; - } - - static void pinctrl_free(struct pinctrl *p, bool inlist); -@@ -1126,7 +1129,6 @@ struct pinctrl *pinctrl_get(struct device *dev) - p = find_pinctrl(dev); - if (p) { - dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n"); -- kref_get(&p->users); - return p; - } - -diff --git a/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c b/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c -index 8193b92da4031..274e01d5212d5 100644 ---- a/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c -+++ b/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c -@@ -1041,13 +1041,13 @@ static int wpcm450_gpio_register(struct platform_device *pdev, - if (ret < 0) - return ret; - -- gpio = &pctrl->gpio_bank[reg]; -- gpio->pctrl = pctrl; -- - if (reg >= WPCM450_NUM_BANKS) - return dev_err_probe(dev, -EINVAL, - "GPIO index %d out of range!\n", reg); - -+ gpio = &pctrl->gpio_bank[reg]; -+ gpio->pctrl = pctrl; -+ - bank = &wpcm450_banks[reg]; - gpio->bank = bank; - -diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig -index 0903a0a418319..1ef8759802618 100644 ---- a/drivers/pinctrl/renesas/Kconfig -+++ b/drivers/pinctrl/renesas/Kconfig -@@ -240,6 +240,7 @@ config PINCTRL_RZN1 - depends on OF - depends on ARCH_RZN1 || COMPILE_TEST - select GENERIC_PINCONF -+ select PINMUX - help - This selects pinctrl driver for Renesas RZ/N1 devices. - -diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c -index 3bacee2b8d521..51f23ff1f2b05 100644 ---- a/drivers/platform/x86/hp/hp-wmi.c -+++ b/drivers/platform/x86/hp/hp-wmi.c -@@ -1399,7 +1399,13 @@ static const struct dev_pm_ops hp_wmi_pm_ops = { - .restore = hp_wmi_resume_handler, - }; - --static struct platform_driver hp_wmi_driver = { -+/* -+ * hp_wmi_bios_remove() lives in .exit.text. For drivers registered via -+ * module_platform_driver_probe() this is ok because they cannot get unbound at -+ * runtime. So mark the driver struct with __refdata to prevent modpost -+ * triggering a section mismatch warning. -+ */ -+static struct platform_driver hp_wmi_driver __refdata = { - .driver = { - .name = "hp-wmi", - .pm = &hp_wmi_pm_ops, -diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c -index f6290221d139d..6641f934f15bf 100644 ---- a/drivers/platform/x86/think-lmi.c -+++ b/drivers/platform/x86/think-lmi.c -@@ -1245,6 +1245,24 @@ static void tlmi_release_attr(void) - kset_unregister(tlmi_priv.authentication_kset); - } - -+static int tlmi_validate_setting_name(struct kset *attribute_kset, char *name) -+{ -+ struct kobject *duplicate; -+ -+ if (!strcmp(name, "Reserved")) -+ return -EINVAL; -+ -+ duplicate = kset_find_obj(attribute_kset, name); -+ if (duplicate) { -+ pr_debug("Duplicate attribute name found - %s\n", name); -+ /* kset_find_obj() returns a reference */ -+ kobject_put(duplicate); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ - static int tlmi_sysfs_init(void) - { - int i, ret; -@@ -1273,10 +1291,8 @@ static int tlmi_sysfs_init(void) - continue; - - /* check for duplicate or reserved values */ -- if (kset_find_obj(tlmi_priv.attribute_kset, tlmi_priv.setting[i]->display_name) || -- !strcmp(tlmi_priv.setting[i]->display_name, "Reserved")) { -- pr_debug("duplicate or reserved attribute name found - %s\n", -- tlmi_priv.setting[i]->display_name); -+ if (tlmi_validate_setting_name(tlmi_priv.attribute_kset, -+ tlmi_priv.setting[i]->display_name) < 0) { - kfree(tlmi_priv.setting[i]->possible_values); - kfree(tlmi_priv.setting[i]); - tlmi_priv.setting[i] = NULL; -diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c -index ed26c52ed8474..bab00b65bc9d1 100644 ---- a/drivers/scsi/scsi_scan.c -+++ b/drivers/scsi/scsi_scan.c -@@ -1619,12 +1619,13 @@ int scsi_rescan_device(struct scsi_device *sdev) - device_lock(dev); - - /* -- * Bail out if the device is not running. Otherwise, the rescan may -- * block waiting for commands to be executed, with us holding the -- * device lock. This can result in a potential deadlock in the power -- * management core code when system resume is on-going. -+ * Bail out if the device or its queue are not running. Otherwise, -+ * the rescan may block waiting for commands to be executed, with us -+ * holding the device lock. This can result in a potential deadlock -+ * in the power management core code when system resume is on-going. - */ -- if (sdev->sdev_state != SDEV_RUNNING) { -+ if (sdev->sdev_state != SDEV_RUNNING || -+ blk_queue_pm_only(sdev->request_queue)) { - ret = -EWOULDBLOCK; - goto unlock; - } -diff --git a/drivers/tee/amdtee/core.c b/drivers/tee/amdtee/core.c -index 372d64756ed64..3c15f6a9e91c0 100644 ---- a/drivers/tee/amdtee/core.c -+++ b/drivers/tee/amdtee/core.c -@@ -217,12 +217,12 @@ unlock: - return rc; - } - -+/* mutex must be held by caller */ - static void destroy_session(struct kref *ref) - { - struct amdtee_session *sess = container_of(ref, struct amdtee_session, - refcount); - -- mutex_lock(&session_list_mutex); - list_del(&sess->list_node); - mutex_unlock(&session_list_mutex); - kfree(sess); -@@ -272,7 +272,8 @@ int amdtee_open_session(struct tee_context *ctx, - if (arg->ret != TEEC_SUCCESS) { - pr_err("open_session failed %d\n", arg->ret); - handle_unload_ta(ta_handle); -- kref_put(&sess->refcount, destroy_session); -+ kref_put_mutex(&sess->refcount, destroy_session, -+ &session_list_mutex); - goto out; - } - -@@ -290,7 +291,8 @@ int amdtee_open_session(struct tee_context *ctx, - pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS); - handle_close_session(ta_handle, session_info); - handle_unload_ta(ta_handle); -- kref_put(&sess->refcount, destroy_session); -+ kref_put_mutex(&sess->refcount, destroy_session, -+ &session_list_mutex); - rc = -ENOMEM; - goto out; - } -@@ -331,7 +333,7 @@ int amdtee_close_session(struct tee_context *ctx, u32 session) - handle_close_session(ta_handle, session_info); - handle_unload_ta(ta_handle); - -- kref_put(&sess->refcount, destroy_session); -+ kref_put_mutex(&sess->refcount, destroy_session, &session_list_mutex); - - return 0; - } -diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c -index 86521ebb25794..69b2ca95fe37a 100644 ---- a/drivers/thunderbolt/icm.c -+++ b/drivers/thunderbolt/icm.c -@@ -41,6 +41,7 @@ - #define PHY_PORT_CS1_LINK_STATE_SHIFT 26 - - #define ICM_TIMEOUT 5000 /* ms */ -+#define ICM_RETRIES 3 - #define ICM_APPROVE_TIMEOUT 10000 /* ms */ - #define ICM_MAX_LINK 4 - -@@ -296,10 +297,9 @@ static bool icm_copy(struct tb_cfg_request *req, const struct ctl_pkg *pkg) - - static int icm_request(struct tb *tb, const void *request, size_t request_size, - void *response, size_t response_size, size_t npackets, -- unsigned int timeout_msec) -+ int retries, unsigned int timeout_msec) - { - struct icm *icm = tb_priv(tb); -- int retries = 3; - - do { - struct tb_cfg_request *req; -@@ -410,7 +410,7 @@ static int icm_fr_get_route(struct tb *tb, u8 link, u8 depth, u64 *route) - return -ENOMEM; - - ret = icm_request(tb, &request, sizeof(request), switches, -- sizeof(*switches), npackets, ICM_TIMEOUT); -+ sizeof(*switches), npackets, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - goto err_free; - -@@ -463,7 +463,7 @@ icm_fr_driver_ready(struct tb *tb, enum tb_security_level *security_level, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -488,7 +488,7 @@ static int icm_fr_approve_switch(struct tb *tb, struct tb_switch *sw) - memset(&reply, 0, sizeof(reply)); - /* Use larger timeout as establishing tunnels can take some time */ - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_APPROVE_TIMEOUT); -+ 1, ICM_RETRIES, ICM_APPROVE_TIMEOUT); - if (ret) - return ret; - -@@ -515,7 +515,7 @@ static int icm_fr_add_switch_key(struct tb *tb, struct tb_switch *sw) - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -543,7 +543,7 @@ static int icm_fr_challenge_switch_key(struct tb *tb, struct tb_switch *sw, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -577,7 +577,7 @@ static int icm_fr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1022,7 +1022,7 @@ icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, 20000); -+ 1, 10, 2000); - if (ret) - return ret; - -@@ -1055,7 +1055,7 @@ static int icm_tr_approve_switch(struct tb *tb, struct tb_switch *sw) - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_APPROVE_TIMEOUT); -+ 1, ICM_RETRIES, ICM_APPROVE_TIMEOUT); - if (ret) - return ret; - -@@ -1083,7 +1083,7 @@ static int icm_tr_add_switch_key(struct tb *tb, struct tb_switch *sw) - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1112,7 +1112,7 @@ static int icm_tr_challenge_switch_key(struct tb *tb, struct tb_switch *sw, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1146,7 +1146,7 @@ static int icm_tr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1172,7 +1172,7 @@ static int icm_tr_xdomain_tear_down(struct tb *tb, struct tb_xdomain *xd, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1498,7 +1498,7 @@ icm_ar_driver_ready(struct tb *tb, enum tb_security_level *security_level, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1524,7 +1524,7 @@ static int icm_ar_get_route(struct tb *tb, u8 link, u8 depth, u64 *route) - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1545,7 +1545,7 @@ static int icm_ar_get_boot_acl(struct tb *tb, uuid_t *uuids, size_t nuuids) - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1606,7 +1606,7 @@ static int icm_ar_set_boot_acl(struct tb *tb, const uuid_t *uuids, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -@@ -1628,7 +1628,7 @@ icm_icl_driver_ready(struct tb *tb, enum tb_security_level *security_level, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, 20000); -+ 1, ICM_RETRIES, 20000); - if (ret) - return ret; - -@@ -2300,7 +2300,7 @@ static int icm_usb4_switch_op(struct tb_switch *sw, u16 opcode, u32 *metadata, - - memset(&reply, 0, sizeof(reply)); - ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply), -- 1, ICM_TIMEOUT); -+ 1, ICM_RETRIES, ICM_TIMEOUT); - if (ret) - return ret; - -diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c -index 9699d167d522d..55698a0978f03 100644 ---- a/drivers/thunderbolt/switch.c -+++ b/drivers/thunderbolt/switch.c -@@ -2763,6 +2763,13 @@ int tb_switch_lane_bonding_enable(struct tb_switch *sw) - !tb_port_is_width_supported(down, 2)) - return 0; - -+ /* -+ * Both lanes need to be in CL0. Here we assume lane 0 already be in -+ * CL0 and check just for lane 1. -+ */ -+ if (tb_wait_for_port(down->dual_link_port, false) <= 0) -+ return -ENOTCONN; -+ - ret = tb_port_lane_bonding_enable(up); - if (ret) { - tb_port_warn(up, "failed to enable lane bonding\n"); -diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c -index 9a3c52f6b8c97..18e2ffd095a42 100644 ---- a/drivers/thunderbolt/xdomain.c -+++ b/drivers/thunderbolt/xdomain.c -@@ -704,6 +704,27 @@ out_unlock: - mutex_unlock(&xdomain_lock); - } - -+static void start_handshake(struct tb_xdomain *xd) -+{ -+ xd->state = XDOMAIN_STATE_INIT; -+ queue_delayed_work(xd->tb->wq, &xd->state_work, -+ msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT)); -+} -+ -+/* Can be called from state_work */ -+static void __stop_handshake(struct tb_xdomain *xd) -+{ -+ cancel_delayed_work_sync(&xd->properties_changed_work); -+ xd->properties_changed_retries = 0; -+ xd->state_retries = 0; -+} -+ -+static void stop_handshake(struct tb_xdomain *xd) -+{ -+ cancel_delayed_work_sync(&xd->state_work); -+ __stop_handshake(xd); -+} -+ - static void tb_xdp_handle_request(struct work_struct *work) - { - struct xdomain_request_work *xw = container_of(work, typeof(*xw), work); -@@ -766,6 +787,15 @@ static void tb_xdp_handle_request(struct work_struct *work) - case UUID_REQUEST: - tb_dbg(tb, "%llx: received XDomain UUID request\n", route); - ret = tb_xdp_uuid_response(ctl, route, sequence, uuid); -+ /* -+ * If we've stopped the discovery with an error such as -+ * timing out, we will restart the handshake now that we -+ * received UUID request from the remote host. -+ */ -+ if (!ret && xd && xd->state == XDOMAIN_STATE_ERROR) { -+ dev_dbg(&xd->dev, "restarting handshake\n"); -+ start_handshake(xd); -+ } - break; - - case LINK_STATE_STATUS_REQUEST: -@@ -1522,6 +1552,13 @@ static void tb_xdomain_queue_properties_changed(struct tb_xdomain *xd) - msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT)); - } - -+static void tb_xdomain_failed(struct tb_xdomain *xd) -+{ -+ xd->state = XDOMAIN_STATE_ERROR; -+ queue_delayed_work(xd->tb->wq, &xd->state_work, -+ msecs_to_jiffies(XDOMAIN_DEFAULT_TIMEOUT)); -+} -+ - static void tb_xdomain_state_work(struct work_struct *work) - { - struct tb_xdomain *xd = container_of(work, typeof(*xd), state_work.work); -@@ -1548,7 +1585,7 @@ static void tb_xdomain_state_work(struct work_struct *work) - if (ret) { - if (ret == -EAGAIN) - goto retry_state; -- xd->state = XDOMAIN_STATE_ERROR; -+ tb_xdomain_failed(xd); - } else { - tb_xdomain_queue_properties_changed(xd); - if (xd->bonding_possible) -@@ -1613,7 +1650,7 @@ static void tb_xdomain_state_work(struct work_struct *work) - if (ret) { - if (ret == -EAGAIN) - goto retry_state; -- xd->state = XDOMAIN_STATE_ERROR; -+ tb_xdomain_failed(xd); - } else { - xd->state = XDOMAIN_STATE_ENUMERATED; - } -@@ -1624,6 +1661,8 @@ static void tb_xdomain_state_work(struct work_struct *work) - break; - - case XDOMAIN_STATE_ERROR: -+ dev_dbg(&xd->dev, "discovery failed, stopping handshake\n"); -+ __stop_handshake(xd); - break; - - default: -@@ -1793,21 +1832,6 @@ static void tb_xdomain_release(struct device *dev) - kfree(xd); - } - --static void start_handshake(struct tb_xdomain *xd) --{ -- xd->state = XDOMAIN_STATE_INIT; -- queue_delayed_work(xd->tb->wq, &xd->state_work, -- msecs_to_jiffies(XDOMAIN_SHORT_TIMEOUT)); --} -- --static void stop_handshake(struct tb_xdomain *xd) --{ -- cancel_delayed_work_sync(&xd->properties_changed_work); -- cancel_delayed_work_sync(&xd->state_work); -- xd->properties_changed_retries = 0; -- xd->state_retries = 0; --} -- - static int __maybe_unused tb_xdomain_suspend(struct device *dev) - { - stop_handshake(tb_to_xdomain(dev)); -diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c -index b4e3f14b9a3d7..6ba4ef2c3949e 100644 ---- a/drivers/ufs/core/ufshcd.c -+++ b/drivers/ufs/core/ufshcd.c -@@ -6749,7 +6749,7 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag) - mask, 0, 1000, 1000); - - dev_err(hba->dev, "Clearing task management function with tag %d %s\n", -- tag, err ? "succeeded" : "failed"); -+ tag, err < 0 ? "failed" : "succeeded"); - - out: - return err; -diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c -index f9aa50ff14d42..0044897ee800d 100644 ---- a/drivers/usb/cdns3/cdnsp-gadget.c -+++ b/drivers/usb/cdns3/cdnsp-gadget.c -@@ -1125,6 +1125,9 @@ static int cdnsp_gadget_ep_dequeue(struct usb_ep *ep, - unsigned long flags; - int ret; - -+ if (request->status != -EINPROGRESS) -+ return 0; -+ - if (!pep->endpoint.desc) { - dev_err(pdev->dev, - "%s: can't dequeue to disabled endpoint\n", -diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h -index 4a4dbc2c15615..81a9c9d6be08b 100644 ---- a/drivers/usb/cdns3/core.h -+++ b/drivers/usb/cdns3/core.h -@@ -131,8 +131,7 @@ void cdns_set_active(struct cdns *cdns, u8 set_active); - #else /* CONFIG_PM_SLEEP */ - static inline int cdns_resume(struct cdns *cdns) - { return 0; } --static inline int cdns_set_active(struct cdns *cdns, u8 set_active) --{ return 0; } -+static inline void cdns_set_active(struct cdns *cdns, u8 set_active) { } - static inline int cdns_suspend(struct cdns *cdns) - { return 0; } - #endif /* CONFIG_PM_SLEEP */ -diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 0069a24bd216c..81c8f564cf878 100644 ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -151,6 +151,10 @@ int usb_device_supports_lpm(struct usb_device *udev) - if (udev->quirks & USB_QUIRK_NO_LPM) - return 0; - -+ /* Skip if the device BOS descriptor couldn't be read */ -+ if (!udev->bos) -+ return 0; -+ - /* USB 2.1 (and greater) devices indicate LPM support through - * their USB 2.0 Extended Capabilities BOS descriptor. - */ -@@ -327,6 +331,10 @@ static void usb_set_lpm_parameters(struct usb_device *udev) - if (!udev->lpm_capable || udev->speed < USB_SPEED_SUPER) - return; - -+ /* Skip if the device BOS descriptor couldn't be read */ -+ if (!udev->bos) -+ return; -+ - hub = usb_hub_to_struct_hub(udev->parent); - /* It doesn't take time to transition the roothub into U0, since it - * doesn't have an upstream link. -@@ -2705,13 +2713,17 @@ out_authorized: - static enum usb_ssp_rate get_port_ssp_rate(struct usb_device *hdev, - u32 ext_portstatus) - { -- struct usb_ssp_cap_descriptor *ssp_cap = hdev->bos->ssp_cap; -+ struct usb_ssp_cap_descriptor *ssp_cap; - u32 attr; - u8 speed_id; - u8 ssac; - u8 lanes; - int i; - -+ if (!hdev->bos) -+ goto out; -+ -+ ssp_cap = hdev->bos->ssp_cap; - if (!ssp_cap) - goto out; - -@@ -4187,8 +4199,15 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, - enum usb3_link_state state) - { - int timeout; -- __u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; -- __le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat; -+ __u8 u1_mel; -+ __le16 u2_mel; -+ -+ /* Skip if the device BOS descriptor couldn't be read */ -+ if (!udev->bos) -+ return; -+ -+ u1_mel = udev->bos->ss_cap->bU1devExitLat; -+ u2_mel = udev->bos->ss_cap->bU2DevExitLat; - - /* If the device says it doesn't have *any* exit latency to come out of - * U1 or U2, it's probably lying. Assume it doesn't implement that link -diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h -index b2925856b4cb4..bc66205ca52c3 100644 ---- a/drivers/usb/core/hub.h -+++ b/drivers/usb/core/hub.h -@@ -145,7 +145,7 @@ static inline int hub_is_superspeedplus(struct usb_device *hdev) - { - return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS && - le16_to_cpu(hdev->descriptor.bcdUSB) >= 0x0310 && -- hdev->bos->ssp_cap); -+ hdev->bos && hdev->bos->ssp_cap); - } - - static inline unsigned hub_power_on_good_delay(struct usb_hub *hub) -diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c -index 3ee70ffaf0035..57e2f4cc744f7 100644 ---- a/drivers/usb/dwc3/core.c -+++ b/drivers/usb/dwc3/core.c -@@ -279,9 +279,46 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) - * XHCI driver will reset the host block. If dwc3 was configured for - * host-only mode or current role is host, then we can return early. - */ -- if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) -+ if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) - return 0; - -+ /* -+ * If the dr_mode is host and the dwc->current_dr_role is not the -+ * corresponding DWC3_GCTL_PRTCAP_HOST, then the dwc3_core_init_mode -+ * isn't executed yet. Ensure the phy is ready before the controller -+ * updates the GCTL.PRTCAPDIR or other settings by soft-resetting -+ * the phy. -+ * -+ * Note: GUSB3PIPECTL[n] and GUSB2PHYCFG[n] are port settings where n -+ * is port index. If this is a multiport host, then we need to reset -+ * all active ports. -+ */ -+ if (dwc->dr_mode == USB_DR_MODE_HOST) { -+ u32 usb3_port; -+ u32 usb2_port; -+ -+ usb3_port = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); -+ usb3_port |= DWC3_GUSB3PIPECTL_PHYSOFTRST; -+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); -+ -+ usb2_port = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); -+ usb2_port |= DWC3_GUSB2PHYCFG_PHYSOFTRST; -+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); -+ -+ /* Small delay for phy reset assertion */ -+ usleep_range(1000, 2000); -+ -+ usb3_port &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; -+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); -+ -+ usb2_port &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; -+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); -+ -+ /* Wait for clock synchronization */ -+ msleep(50); -+ return 0; -+ } -+ - reg = dwc3_readl(dwc->regs, DWC3_DCTL); - reg |= DWC3_DCTL_CSFTRST; - reg &= ~DWC3_DCTL_RUN_STOP; -diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c -index 424bb3b666dbd..faf90a2174194 100644 ---- a/drivers/usb/gadget/function/f_ncm.c -+++ b/drivers/usb/gadget/function/f_ncm.c -@@ -1171,7 +1171,8 @@ static int ncm_unwrap_ntb(struct gether *port, - struct sk_buff_head *list) - { - struct f_ncm *ncm = func_to_ncm(&port->func); -- __le16 *tmp = (void *) skb->data; -+ unsigned char *ntb_ptr = skb->data; -+ __le16 *tmp; - unsigned index, index2; - int ndp_index; - unsigned dg_len, dg_len2; -@@ -1184,6 +1185,10 @@ static int ncm_unwrap_ntb(struct gether *port, - const struct ndp_parser_opts *opts = ncm->parser_opts; - unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; - int dgram_counter; -+ int to_process = skb->len; -+ -+parse_ntb: -+ tmp = (__le16 *)ntb_ptr; - - /* dwSignature */ - if (get_unaligned_le32(tmp) != opts->nth_sign) { -@@ -1230,7 +1235,7 @@ static int ncm_unwrap_ntb(struct gether *port, - * walk through NDP - * dwSignature - */ -- tmp = (void *)(skb->data + ndp_index); -+ tmp = (__le16 *)(ntb_ptr + ndp_index); - if (get_unaligned_le32(tmp) != ncm->ndp_sign) { - INFO(port->func.config->cdev, "Wrong NDP SIGN\n"); - goto err; -@@ -1287,11 +1292,11 @@ static int ncm_unwrap_ntb(struct gether *port, - if (ncm->is_crc) { - uint32_t crc, crc2; - -- crc = get_unaligned_le32(skb->data + -+ crc = get_unaligned_le32(ntb_ptr + - index + dg_len - - crc_len); - crc2 = ~crc32_le(~0, -- skb->data + index, -+ ntb_ptr + index, - dg_len - crc_len); - if (crc != crc2) { - INFO(port->func.config->cdev, -@@ -1318,7 +1323,7 @@ static int ncm_unwrap_ntb(struct gether *port, - dg_len - crc_len); - if (skb2 == NULL) - goto err; -- skb_put_data(skb2, skb->data + index, -+ skb_put_data(skb2, ntb_ptr + index, - dg_len - crc_len); - - skb_queue_tail(list, skb2); -@@ -1331,10 +1336,17 @@ static int ncm_unwrap_ntb(struct gether *port, - } while (ndp_len > 2 * (opts->dgram_item_len * 2)); - } while (ndp_index); - -- dev_consume_skb_any(skb); -- - VDBG(port->func.config->cdev, - "Parsed NTB with %d frames\n", dgram_counter); -+ -+ to_process -= block_len; -+ if (to_process != 0) { -+ ntb_ptr = (unsigned char *)(ntb_ptr + block_len); -+ goto parse_ntb; -+ } -+ -+ dev_consume_skb_any(skb); -+ - return 0; - err: - skb_queue_purge(list); -diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c -index 4827e3cd38340..4c7a4f7703c21 100644 ---- a/drivers/usb/gadget/udc/udc-xilinx.c -+++ b/drivers/usb/gadget/udc/udc-xilinx.c -@@ -499,11 +499,13 @@ static int xudc_eptxrx(struct xusb_ep *ep, struct xusb_req *req, - /* Get the Buffer address and copy the transmit data.*/ - eprambase = (u32 __force *)(udc->addr + ep->rambase); - if (ep->is_in) { -- memcpy(eprambase, bufferptr, bytestosend); -+ memcpy_toio((void __iomem *)eprambase, bufferptr, -+ bytestosend); - udc->write_fn(udc->addr, ep->offset + - XUSB_EP_BUF0COUNT_OFFSET, bufferlen); - } else { -- memcpy(bufferptr, eprambase, bytestosend); -+ memcpy_toio((void __iomem *)bufferptr, eprambase, -+ bytestosend); - } - /* - * Enable the buffer for transmission. -@@ -517,11 +519,13 @@ static int xudc_eptxrx(struct xusb_ep *ep, struct xusb_req *req, - eprambase = (u32 __force *)(udc->addr + ep->rambase + - ep->ep_usb.maxpacket); - if (ep->is_in) { -- memcpy(eprambase, bufferptr, bytestosend); -+ memcpy_toio((void __iomem *)eprambase, bufferptr, -+ bytestosend); - udc->write_fn(udc->addr, ep->offset + - XUSB_EP_BUF1COUNT_OFFSET, bufferlen); - } else { -- memcpy(bufferptr, eprambase, bytestosend); -+ memcpy_toio((void __iomem *)bufferptr, eprambase, -+ bytestosend); - } - /* - * Enable the buffer for transmission. -@@ -1023,7 +1027,7 @@ static int __xudc_ep0_queue(struct xusb_ep *ep0, struct xusb_req *req) - udc->addr); - length = req->usb_req.actual = min_t(u32, length, - EP0_MAX_PACKET); -- memcpy(corebuf, req->usb_req.buf, length); -+ memcpy_toio((void __iomem *)corebuf, req->usb_req.buf, length); - udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, length); - udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1); - } else { -@@ -1752,7 +1756,7 @@ static void xudc_handle_setup(struct xusb_udc *udc) - - /* Load up the chapter 9 command buffer.*/ - ep0rambase = (u32 __force *) (udc->addr + XUSB_SETUP_PKT_ADDR_OFFSET); -- memcpy(&setup, ep0rambase, 8); -+ memcpy_toio((void __iomem *)&setup, ep0rambase, 8); - - udc->setup = setup; - udc->setup.wValue = cpu_to_le16(setup.wValue); -@@ -1839,7 +1843,7 @@ static void xudc_ep0_out(struct xusb_udc *udc) - (ep0->rambase << 2)); - buffer = req->usb_req.buf + req->usb_req.actual; - req->usb_req.actual = req->usb_req.actual + bytes_to_rx; -- memcpy(buffer, ep0rambase, bytes_to_rx); -+ memcpy_toio((void __iomem *)buffer, ep0rambase, bytes_to_rx); - - if (req->usb_req.length == req->usb_req.actual) { - /* Data transfer completed get ready for Status stage */ -@@ -1915,7 +1919,7 @@ static void xudc_ep0_in(struct xusb_udc *udc) - (ep0->rambase << 2)); - buffer = req->usb_req.buf + req->usb_req.actual; - req->usb_req.actual = req->usb_req.actual + length; -- memcpy(ep0rambase, buffer, length); -+ memcpy_toio((void __iomem *)ep0rambase, buffer, length); - } - udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, count); - udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1); -diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c -index 281690c582cba..1239e06dfe411 100644 ---- a/drivers/usb/host/xhci-ring.c -+++ b/drivers/usb/host/xhci-ring.c -@@ -764,7 +764,7 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, - static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci, - struct xhci_ring *ring, struct xhci_td *td) - { -- struct device *dev = xhci_to_hcd(xhci)->self.controller; -+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev; - struct xhci_segment *seg = td->bounce_seg; - struct urb *urb = td->urb; - size_t len; -@@ -3455,7 +3455,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred, - static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len, - u32 *trb_buff_len, struct xhci_segment *seg) - { -- struct device *dev = xhci_to_hcd(xhci)->self.controller; -+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev; - unsigned int unalign; - unsigned int max_pkt; - u32 new_buff_len; -diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c -index 30a89aa8a3e7a..5401ae66894eb 100644 ---- a/drivers/usb/musb/musb_debugfs.c -+++ b/drivers/usb/musb/musb_debugfs.c -@@ -39,7 +39,7 @@ static const struct musb_register_map musb_regmap[] = { - { "IntrUsbE", MUSB_INTRUSBE, 8 }, - { "DevCtl", MUSB_DEVCTL, 8 }, - { "VControl", 0x68, 32 }, -- { "HWVers", 0x69, 16 }, -+ { "HWVers", MUSB_HWVERS, 16 }, - { "LinkInfo", MUSB_LINKINFO, 8 }, - { "VPLen", MUSB_VPLEN, 8 }, - { "HS_EOF1", MUSB_HS_EOF1, 8 }, -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index 9ff7d891b4b76..ef0b1589b10eb 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -321,10 +321,16 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, - musb_giveback(musb, urb, status); - qh->is_ready = ready; - -+ /* -+ * musb->lock had been unlocked in musb_giveback, so qh may -+ * be freed, need to get it again -+ */ -+ qh = musb_ep_get_qh(hw_ep, is_in); -+ - /* reclaim resources (and bandwidth) ASAP; deschedule it, and - * invalidate qh as soon as list_empty(&hep->urb_list) - */ -- if (list_empty(&qh->hep->urb_list)) { -+ if (qh && list_empty(&qh->hep->urb_list)) { - struct list_head *head; - struct dma_controller *dma = musb->dma_controller; - -@@ -2398,6 +2404,7 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) - * and its URB list has emptied, recycle this qh. - */ - if (ready && list_empty(&qh->hep->urb_list)) { -+ musb_ep_set_qh(qh->hw_ep, is_in, NULL); - qh->hep->hcpriv = NULL; - list_del(&qh->ring); - kfree(qh); -diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c -index 7a3caf556dae9..f564d0d471bbc 100644 ---- a/drivers/usb/typec/altmodes/displayport.c -+++ b/drivers/usb/typec/altmodes/displayport.c -@@ -301,6 +301,11 @@ static int dp_altmode_vdm(struct typec_altmode *alt, - case CMD_EXIT_MODE: - dp->data.status = 0; - dp->data.conf = 0; -+ if (dp->hpd) { -+ drm_connector_oob_hotplug_event(dp->connector_fwnode); -+ dp->hpd = false; -+ sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd"); -+ } - break; - case DP_CMD_STATUS_UPDATE: - dp->data.status = *vdo; -diff --git a/drivers/usb/typec/ucsi/psy.c b/drivers/usb/typec/ucsi/psy.c -index 384b42267f1fc..b35c6e07911e9 100644 ---- a/drivers/usb/typec/ucsi/psy.c -+++ b/drivers/usb/typec/ucsi/psy.c -@@ -37,6 +37,15 @@ static int ucsi_psy_get_scope(struct ucsi_connector *con, - struct device *dev = con->ucsi->dev; - - device_property_read_u8(dev, "scope", &scope); -+ if (scope == POWER_SUPPLY_SCOPE_UNKNOWN) { -+ u32 mask = UCSI_CAP_ATTR_POWER_AC_SUPPLY | -+ UCSI_CAP_ATTR_BATTERY_CHARGING; -+ -+ if (con->ucsi->cap.attributes & mask) -+ scope = POWER_SUPPLY_SCOPE_SYSTEM; -+ else -+ scope = POWER_SUPPLY_SCOPE_DEVICE; -+ } - val->intval = scope; - return 0; - } -diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c -index 47a2c73df3420..dc2dea3768fb6 100644 ---- a/drivers/usb/typec/ucsi/ucsi.c -+++ b/drivers/usb/typec/ucsi/ucsi.c -@@ -785,6 +785,7 @@ static void ucsi_handle_connector_change(struct work_struct *work) - if (ret < 0) { - dev_err(ucsi->dev, "%s: GET_CONNECTOR_STATUS failed (%d)\n", - __func__, ret); -+ clear_bit(EVENT_PENDING, &con->ucsi->flags); - goto out_unlock; - } - -diff --git a/fs/ceph/file.c b/fs/ceph/file.c -index 02414437d8abf..882eccfd67e84 100644 ---- a/fs/ceph/file.c -+++ b/fs/ceph/file.c -@@ -2498,7 +2498,7 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off, - ret = do_splice_direct(src_file, &src_off, dst_file, - &dst_off, src_objlen, flags); - /* Abort on short copies or on error */ -- if (ret < src_objlen) { -+ if (ret < (long)src_objlen) { - dout("Failed partial copy (%zd)\n", ret); - goto out; - } -diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c -index bad9eeb6a1a59..29384ec1a524c 100644 ---- a/fs/ceph/inode.c -+++ b/fs/ceph/inode.c -@@ -655,9 +655,7 @@ int ceph_fill_file_size(struct inode *inode, int issued, - ci->i_truncate_seq = truncate_seq; - - /* the MDS should have revoked these caps */ -- WARN_ON_ONCE(issued & (CEPH_CAP_FILE_EXCL | -- CEPH_CAP_FILE_RD | -- CEPH_CAP_FILE_WR | -+ WARN_ON_ONCE(issued & (CEPH_CAP_FILE_RD | - CEPH_CAP_FILE_LAZYIO)); - /* - * If we hold relevant caps, or in the case where we're -diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c -index 53b65c5300fde..f26ddfcaa5e61 100644 ---- a/fs/quota/dquot.c -+++ b/fs/quota/dquot.c -@@ -233,19 +233,18 @@ static void put_quota_format(struct quota_format_type *fmt) - * All dquots are placed to the end of inuse_list when first created, and this - * list is used for invalidate operation, which must look at every dquot. - * -- * When the last reference of a dquot will be dropped, the dquot will be -- * added to releasing_dquots. We'd then queue work item which would call -+ * When the last reference of a dquot is dropped, the dquot is added to -+ * releasing_dquots. We'll then queue work item which will call - * synchronize_srcu() and after that perform the final cleanup of all the -- * dquots on the list. Both releasing_dquots and free_dquots use the -- * dq_free list_head in the dquot struct. When a dquot is removed from -- * releasing_dquots, a reference count is always subtracted, and if -- * dq_count == 0 at that point, the dquot will be added to the free_dquots. -+ * dquots on the list. Each cleaned up dquot is moved to free_dquots list. -+ * Both releasing_dquots and free_dquots use the dq_free list_head in the dquot -+ * struct. - * -- * Unused dquots (dq_count == 0) are added to the free_dquots list when freed, -- * and this list is searched whenever we need an available dquot. Dquots are -- * removed from the list as soon as they are used again, and -- * dqstats.free_dquots gives the number of dquots on the list. When -- * dquot is invalidated it's completely released from memory. -+ * Unused and cleaned up dquots are in the free_dquots list and this list is -+ * searched whenever we need an available dquot. Dquots are removed from the -+ * list as soon as they are used again and dqstats.free_dquots gives the number -+ * of dquots on the list. When dquot is invalidated it's completely released -+ * from memory. - * - * Dirty dquots are added to the dqi_dirty_list of quota_info when mark - * dirtied, and this list is searched when writing dirty dquots back to -@@ -321,6 +320,7 @@ static inline void put_dquot_last(struct dquot *dquot) - static inline void put_releasing_dquots(struct dquot *dquot) - { - list_add_tail(&dquot->dq_free, &releasing_dquots); -+ set_bit(DQ_RELEASING_B, &dquot->dq_flags); - } - - static inline void remove_free_dquot(struct dquot *dquot) -@@ -328,8 +328,10 @@ static inline void remove_free_dquot(struct dquot *dquot) - if (list_empty(&dquot->dq_free)) - return; - list_del_init(&dquot->dq_free); -- if (!atomic_read(&dquot->dq_count)) -+ if (!test_bit(DQ_RELEASING_B, &dquot->dq_flags)) - dqstats_dec(DQST_FREE_DQUOTS); -+ else -+ clear_bit(DQ_RELEASING_B, &dquot->dq_flags); - } - - static inline void put_inuse(struct dquot *dquot) -@@ -581,12 +583,6 @@ restart: - continue; - /* Wait for dquot users */ - if (atomic_read(&dquot->dq_count)) { -- /* dquot in releasing_dquots, flush and retry */ -- if (!list_empty(&dquot->dq_free)) { -- spin_unlock(&dq_list_lock); -- goto restart; -- } -- - atomic_inc(&dquot->dq_count); - spin_unlock(&dq_list_lock); - /* -@@ -605,6 +601,15 @@ restart: - * restart. */ - goto restart; - } -+ /* -+ * The last user already dropped its reference but dquot didn't -+ * get fully cleaned up yet. Restart the scan which flushes the -+ * work cleaning up released dquots. -+ */ -+ if (test_bit(DQ_RELEASING_B, &dquot->dq_flags)) { -+ spin_unlock(&dq_list_lock); -+ goto restart; -+ } - /* - * Quota now has no users and it has been written on last - * dqput() -@@ -696,6 +701,13 @@ int dquot_writeback_dquots(struct super_block *sb, int type) - dq_dirty); - - WARN_ON(!dquot_active(dquot)); -+ /* If the dquot is releasing we should not touch it */ -+ if (test_bit(DQ_RELEASING_B, &dquot->dq_flags)) { -+ spin_unlock(&dq_list_lock); -+ flush_delayed_work("a_release_work); -+ spin_lock(&dq_list_lock); -+ continue; -+ } - - /* Now we have active dquot from which someone is - * holding reference so we can safely just increase -@@ -809,18 +821,18 @@ static void quota_release_workfn(struct work_struct *work) - /* Exchange the list head to avoid livelock. */ - list_replace_init(&releasing_dquots, &rls_head); - spin_unlock(&dq_list_lock); -+ synchronize_srcu(&dquot_srcu); - - restart: -- synchronize_srcu(&dquot_srcu); - spin_lock(&dq_list_lock); - while (!list_empty(&rls_head)) { - dquot = list_first_entry(&rls_head, struct dquot, dq_free); -- /* Dquot got used again? */ -- if (atomic_read(&dquot->dq_count) > 1) { -- remove_free_dquot(dquot); -- atomic_dec(&dquot->dq_count); -- continue; -- } -+ WARN_ON_ONCE(atomic_read(&dquot->dq_count)); -+ /* -+ * Note that DQ_RELEASING_B protects us from racing with -+ * invalidate_dquots() calls so we are safe to work with the -+ * dquot even after we drop dq_list_lock. -+ */ - if (dquot_dirty(dquot)) { - spin_unlock(&dq_list_lock); - /* Commit dquot before releasing */ -@@ -834,7 +846,6 @@ restart: - } - /* Dquot is inactive and clean, now move it to free list */ - remove_free_dquot(dquot); -- atomic_dec(&dquot->dq_count); - put_dquot_last(dquot); - } - spin_unlock(&dq_list_lock); -@@ -875,6 +886,7 @@ void dqput(struct dquot *dquot) - BUG_ON(!list_empty(&dquot->dq_free)); - #endif - put_releasing_dquots(dquot); -+ atomic_dec(&dquot->dq_count); - spin_unlock(&dq_list_lock); - queue_delayed_work(system_unbound_wq, "a_release_work, 1); - } -@@ -963,7 +975,7 @@ we_slept: - dqstats_inc(DQST_LOOKUPS); - } - /* Wait for dq_lock - after this we know that either dquot_release() is -- * already finished or it will be canceled due to dq_count > 1 test */ -+ * already finished or it will be canceled due to dq_count > 0 test */ - wait_on_dquot(dquot); - /* Read the dquot / allocate space in quota file */ - if (!dquot_active(dquot)) { -diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c -index 0ae5dd0829e92..6ec6c129465d3 100644 ---- a/fs/smb/server/vfs_cache.c -+++ b/fs/smb/server/vfs_cache.c -@@ -105,7 +105,7 @@ int ksmbd_query_inode_status(struct inode *inode) - ci = __ksmbd_inode_lookup(inode); - if (ci) { - ret = KSMBD_INODE_STATUS_OK; -- if (ci->m_flags & S_DEL_PENDING) -+ if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) - ret = KSMBD_INODE_STATUS_PENDING_DELETE; - atomic_dec(&ci->m_count); - } -@@ -115,7 +115,7 @@ int ksmbd_query_inode_status(struct inode *inode) - - bool ksmbd_inode_pending_delete(struct ksmbd_file *fp) - { -- return (fp->f_ci->m_flags & S_DEL_PENDING); -+ return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); - } - - void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp) -diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h -index be572c3a4dcdd..3dfb994312b1f 100644 ---- a/include/linux/dma-fence.h -+++ b/include/linux/dma-fence.h -@@ -548,6 +548,25 @@ static inline void dma_fence_set_error(struct dma_fence *fence, - fence->error = error; - } - -+/** -+ * dma_fence_timestamp - helper to get the completion timestamp of a fence -+ * @fence: fence to get the timestamp from. -+ * -+ * After a fence is signaled the timestamp is updated with the signaling time, -+ * but setting the timestamp can race with tasks waiting for the signaling. This -+ * helper busy waits for the correct timestamp to appear. -+ */ -+static inline ktime_t dma_fence_timestamp(struct dma_fence *fence) -+{ -+ if (WARN_ON(!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))) -+ return ktime_get(); -+ -+ while (!test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags)) -+ cpu_relax(); -+ -+ return fence->timestamp; -+} -+ - signed long dma_fence_wait_timeout(struct dma_fence *, - bool intr, signed long timeout); - signed long dma_fence_wait_any_timeout(struct dma_fence **fences, -diff --git a/include/linux/libata.h b/include/linux/libata.h -index a9ec8d97a715b..45910aebc3778 100644 ---- a/include/linux/libata.h -+++ b/include/linux/libata.h -@@ -189,6 +189,7 @@ enum { - ATA_PFLAG_UNLOADING = (1 << 9), /* driver is being unloaded */ - ATA_PFLAG_UNLOADED = (1 << 10), /* driver is unloaded */ - -+ ATA_PFLAG_RESUMING = (1 << 16), /* port is being resumed */ - ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ - ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ - ATA_PFLAG_INIT_GTM_VALID = (1 << 19), /* initial gtm data valid */ -@@ -311,8 +312,10 @@ enum { - ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, - ATA_EH_ENABLE_LINK = (1 << 3), - ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */ -+ ATA_EH_SET_ACTIVE = (1 << 6), /* Set a device to active power mode */ - -- ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK, -+ ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK | -+ ATA_EH_SET_ACTIVE, - ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET | - ATA_EH_ENABLE_LINK, - -@@ -350,7 +353,7 @@ enum { - /* This should match the actual table size of - * ata_eh_cmd_timeout_table in libata-eh.c. - */ -- ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 7, -+ ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 8, - - /* Horkage types. May be set by libata or controller on drives - (some horkage may be drive/controller pair dependent */ -diff --git a/include/linux/mcb.h b/include/linux/mcb.h -index f6efb16f9d1b4..91ec9a83149e8 100644 ---- a/include/linux/mcb.h -+++ b/include/linux/mcb.h -@@ -63,7 +63,6 @@ static inline struct mcb_bus *to_mcb_bus(struct device *dev) - struct mcb_device { - struct device dev; - struct mcb_bus *bus; -- bool is_added; - struct mcb_driver *driver; - u16 id; - int inst; -diff --git a/include/linux/quota.h b/include/linux/quota.h -index fd692b4a41d5f..07071e64abf3d 100644 ---- a/include/linux/quota.h -+++ b/include/linux/quota.h -@@ -285,7 +285,9 @@ static inline void dqstats_dec(unsigned int type) - #define DQ_FAKE_B 3 /* no limits only usage */ - #define DQ_READ_B 4 /* dquot was read into memory */ - #define DQ_ACTIVE_B 5 /* dquot is active (dquot_release not called) */ --#define DQ_LASTSET_B 6 /* Following 6 bits (see QIF_) are reserved\ -+#define DQ_RELEASING_B 6 /* dquot is in releasing_dquots list waiting -+ * to be cleaned up */ -+#define DQ_LASTSET_B 7 /* Following 6 bits (see QIF_) are reserved\ - * for the mask of entries set via SETQUOTA\ - * quotactl. They are set under dq_data_lock\ - * and the quota format handling dquot can\ -diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h -index 0d8625d717339..3abd249ec3373 100644 ---- a/include/linux/quotaops.h -+++ b/include/linux/quotaops.h -@@ -57,7 +57,7 @@ static inline bool dquot_is_busy(struct dquot *dquot) - { - if (test_bit(DQ_MOD_B, &dquot->dq_flags)) - return true; -- if (atomic_read(&dquot->dq_count) > 1) -+ if (atomic_read(&dquot->dq_count) > 0) - return true; - return false; - } -diff --git a/include/net/macsec.h b/include/net/macsec.h -index 5b9c61c4d3a62..65c93959c2dc5 100644 ---- a/include/net/macsec.h -+++ b/include/net/macsec.h -@@ -257,6 +257,7 @@ struct macsec_context { - struct macsec_secy *secy; - struct macsec_rx_sc *rx_sc; - struct { -+ bool update_pn; - unsigned char assoc_num; - u8 key[MACSEC_MAX_KEY_LEN]; - union { -diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h -index 1b80046794451..ede2ff1da53a3 100644 ---- a/include/net/netns/ipv4.h -+++ b/include/net/netns/ipv4.h -@@ -64,6 +64,7 @@ struct netns_ipv4 { - #endif - bool fib_has_custom_local_routes; - bool fib_offload_disabled; -+ u8 sysctl_tcp_shrink_window; - #ifdef CONFIG_IP_ROUTE_CLASSID - atomic_t fib_num_tclassid_users; - #endif -diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c -index 3052680201e57..eb3f52be115d6 100644 ---- a/kernel/bpf/verifier.c -+++ b/kernel/bpf/verifier.c -@@ -10778,7 +10778,7 @@ static int check_return_code(struct bpf_verifier_env *env) - struct tnum enforce_attach_type_range = tnum_unknown; - const struct bpf_prog *prog = env->prog; - struct bpf_reg_state *reg; -- struct tnum range = tnum_range(0, 1); -+ struct tnum range = tnum_range(0, 1), const_0 = tnum_const(0); - enum bpf_prog_type prog_type = resolve_prog_type(env->prog); - int err; - struct bpf_func_state *frame = env->cur_state->frame[0]; -@@ -10826,8 +10826,8 @@ static int check_return_code(struct bpf_verifier_env *env) - return -EINVAL; - } - -- if (!tnum_in(tnum_const(0), reg->var_off)) { -- verbose_invalid_scalar(env, reg, &range, "async callback", "R0"); -+ if (!tnum_in(const_0, reg->var_off)) { -+ verbose_invalid_scalar(env, reg, &const_0, "async callback", "R0"); - return -EINVAL; - } - return 0; -diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c -index 5407241dbb45f..289cc873cb719 100644 ---- a/kernel/cgroup/cgroup-v1.c -+++ b/kernel/cgroup/cgroup-v1.c -@@ -360,10 +360,9 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type, - } - css_task_iter_end(&it); - length = n; -- /* now sort & (if procs) strip out duplicates */ -+ /* now sort & strip out duplicates (tgids or recycled thread PIDs) */ - sort(array, length, sizeof(pid_t), cmppid, NULL); -- if (type == CGROUP_FILE_PROCS) -- length = pidlist_uniq(array, length); -+ length = pidlist_uniq(array, length); - - l = cgroup_pidlist_find_create(cgrp, type); - if (!l) { -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index 1e1557e42d2cc..bc1a97ee40b21 100644 ---- a/kernel/workqueue.c -+++ b/kernel/workqueue.c -@@ -5355,9 +5355,13 @@ static int workqueue_apply_unbound_cpumask(const cpumask_var_t unbound_cpumask) - list_for_each_entry(wq, &workqueues, list) { - if (!(wq->flags & WQ_UNBOUND)) - continue; -+ - /* creating multiple pwqs breaks ordering guarantee */ -- if (wq->flags & __WQ_ORDERED) -- continue; -+ if (!list_empty(&wq->pwqs)) { -+ if (wq->flags & __WQ_ORDERED_EXPLICIT) -+ continue; -+ wq->flags &= ~__WQ_ORDERED; -+ } - - ctx = apply_wqattrs_prepare(wq, wq->unbound_attrs, unbound_cpumask); - if (!ctx) { -diff --git a/net/can/isotp.c b/net/can/isotp.c -index 8c97f4061ffd7..545889935d39c 100644 ---- a/net/can/isotp.c -+++ b/net/can/isotp.c -@@ -925,21 +925,18 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) - if (!so->bound || so->tx.state == ISOTP_SHUTDOWN) - return -EADDRNOTAVAIL; - --wait_free_buffer: -- /* we do not support multiple buffers - for now */ -- if (wq_has_sleeper(&so->wait) && (msg->msg_flags & MSG_DONTWAIT)) -- return -EAGAIN; -+ while (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) { -+ /* we do not support multiple buffers - for now */ -+ if (msg->msg_flags & MSG_DONTWAIT) -+ return -EAGAIN; - -- /* wait for complete transmission of current pdu */ -- err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); -- if (err) -- goto err_event_drop; -- -- if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) { - if (so->tx.state == ISOTP_SHUTDOWN) - return -EADDRNOTAVAIL; - -- goto wait_free_buffer; -+ /* wait for complete transmission of current pdu */ -+ err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE); -+ if (err) -+ goto err_event_drop; - } - - if (!size || size > MAX_MSG_LENGTH) { -diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c -index 09feb3f1fcaa3..b9b64a2427caf 100644 ---- a/net/ceph/messenger.c -+++ b/net/ceph/messenger.c -@@ -454,8 +454,8 @@ int ceph_tcp_connect(struct ceph_connection *con) - set_sock_callbacks(sock, con); - - con_sock_state_connecting(con); -- ret = sock->ops->connect(sock, (struct sockaddr *)&ss, sizeof(ss), -- O_NONBLOCK); -+ ret = kernel_connect(sock, (struct sockaddr *)&ss, sizeof(ss), -+ O_NONBLOCK); - if (ret == -EINPROGRESS) { - dout("connect %s EINPROGRESS sk_state = %u\n", - ceph_pr_addr(&con->peer_addr), -diff --git a/net/core/dev.c b/net/core/dev.c -index a2e3c6470ab3f..5374761f5af2c 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -3274,15 +3274,19 @@ int skb_checksum_help(struct sk_buff *skb) - - offset = skb_checksum_start_offset(skb); - ret = -EINVAL; -- if (WARN_ON_ONCE(offset >= skb_headlen(skb))) { -+ if (unlikely(offset >= skb_headlen(skb))) { - DO_ONCE_LITE(skb_dump, KERN_ERR, skb, false); -+ WARN_ONCE(true, "offset (%d) >= skb_headlen() (%u)\n", -+ offset, skb_headlen(skb)); - goto out; - } - csum = skb_checksum(skb, offset, skb->len - offset, 0); - - offset += skb->csum_offset; -- if (WARN_ON_ONCE(offset + sizeof(__sum16) > skb_headlen(skb))) { -+ if (unlikely(offset + sizeof(__sum16) > skb_headlen(skb))) { - DO_ONCE_LITE(skb_dump, KERN_ERR, skb, false); -+ WARN_ONCE(true, "offset+2 (%zu) > skb_headlen() (%u)\n", -+ offset + sizeof(__sum16), skb_headlen(skb)); - goto out; - } - ret = skb_ensure_writable(skb, offset + sizeof(__sum16)); -diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c -index f68762ce4d8a3..73e5821584c18 100644 ---- a/net/ipv4/sysctl_net_ipv4.c -+++ b/net/ipv4/sysctl_net_ipv4.c -@@ -1387,6 +1387,15 @@ static struct ctl_table ipv4_net_table[] = { - .extra1 = SYSCTL_ZERO, - .extra2 = SYSCTL_TWO, - }, -+ { -+ .procname = "tcp_shrink_window", -+ .data = &init_net.ipv4.sysctl_tcp_shrink_window, -+ .maxlen = sizeof(u8), -+ .mode = 0644, -+ .proc_handler = proc_dou8vec_minmax, -+ .extra1 = SYSCTL_ZERO, -+ .extra2 = SYSCTL_ONE, -+ }, - { } - }; - -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index f9b8a4a1d2edc..5df19f93f86ab 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -3221,6 +3221,8 @@ static int __net_init tcp_sk_init(struct net *net) - else - net->ipv4.tcp_congestion_control = &tcp_reno; - -+ net->ipv4.sysctl_tcp_shrink_window = 0; -+ - return 0; - } - -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index 5921b0f6f9f41..443b1cab25299 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -259,8 +259,8 @@ static u16 tcp_select_window(struct sock *sk) - u32 old_win = tp->rcv_wnd; - u32 cur_win = tcp_receive_window(tp); - u32 new_win = __tcp_select_window(sk); -+ struct net *net = sock_net(sk); - -- /* Never shrink the offered window */ - if (new_win < cur_win) { - /* Danger Will Robinson! - * Don't update rcv_wup/rcv_wnd here or else -@@ -269,11 +269,14 @@ static u16 tcp_select_window(struct sock *sk) - * - * Relax Will Robinson. - */ -- if (new_win == 0) -- NET_INC_STATS(sock_net(sk), -- LINUX_MIB_TCPWANTZEROWINDOWADV); -- new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); -+ if (!READ_ONCE(net->ipv4.sysctl_tcp_shrink_window) || !tp->rx_opt.rcv_wscale) { -+ /* Never shrink the offered window */ -+ if (new_win == 0) -+ NET_INC_STATS(net, LINUX_MIB_TCPWANTZEROWINDOWADV); -+ new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); -+ } - } -+ - tp->rcv_wnd = new_win; - tp->rcv_wup = tp->rcv_nxt; - -@@ -281,7 +284,7 @@ static u16 tcp_select_window(struct sock *sk) - * scaled window. - */ - if (!tp->rx_opt.rcv_wscale && -- READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_workaround_signed_windows)) -+ READ_ONCE(net->ipv4.sysctl_tcp_workaround_signed_windows)) - new_win = min(new_win, MAX_TCP_WINDOW); - else - new_win = min(new_win, (65535U << tp->rx_opt.rcv_wscale)); -@@ -293,10 +296,9 @@ static u16 tcp_select_window(struct sock *sk) - if (new_win == 0) { - tp->pred_flags = 0; - if (old_win) -- NET_INC_STATS(sock_net(sk), -- LINUX_MIB_TCPTOZEROWINDOWADV); -+ NET_INC_STATS(net, LINUX_MIB_TCPTOZEROWINDOWADV); - } else if (old_win == 0) { -- NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFROMZEROWINDOWADV); -+ NET_INC_STATS(net, LINUX_MIB_TCPFROMZEROWINDOWADV); - } - - return new_win; -@@ -2949,6 +2951,7 @@ u32 __tcp_select_window(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -+ struct net *net = sock_net(sk); - /* MSS for the peer's data. Previous versions used mss_clamp - * here. I don't know if the value based on our guesses - * of peer's MSS is better for the performance. It's more correct -@@ -2970,6 +2973,15 @@ u32 __tcp_select_window(struct sock *sk) - if (mss <= 0) - return 0; - } -+ -+ /* Only allow window shrink if the sysctl is enabled and we have -+ * a non-zero scaling factor in effect. -+ */ -+ if (READ_ONCE(net->ipv4.sysctl_tcp_shrink_window) && tp->rx_opt.rcv_wscale) -+ goto shrink_window_allowed; -+ -+ /* do not allow window to shrink */ -+ - if (free_space < (full_space >> 1)) { - icsk->icsk_ack.quick = 0; - -@@ -3024,6 +3036,36 @@ u32 __tcp_select_window(struct sock *sk) - } - - return window; -+ -+shrink_window_allowed: -+ /* new window should always be an exact multiple of scaling factor */ -+ free_space = round_down(free_space, 1 << tp->rx_opt.rcv_wscale); -+ -+ if (free_space < (full_space >> 1)) { -+ icsk->icsk_ack.quick = 0; -+ -+ if (tcp_under_memory_pressure(sk)) -+ tcp_adjust_rcv_ssthresh(sk); -+ -+ /* if free space is too low, return a zero window */ -+ if (free_space < (allowed_space >> 4) || free_space < mss || -+ free_space < (1 << tp->rx_opt.rcv_wscale)) -+ return 0; -+ } -+ -+ if (free_space > tp->rcv_ssthresh) { -+ free_space = tp->rcv_ssthresh; -+ /* new window should always be an exact multiple of scaling factor -+ * -+ * For this case, we ALIGN "up" (increase free_space) because -+ * we know free_space is not zero here, it has been reduced from -+ * the memory-based limit, and rcv_ssthresh is not a hard limit -+ * (unlike sk_rcvbuf). -+ */ -+ free_space = ALIGN(free_space, (1 << tp->rx_opt.rcv_wscale)); -+ } -+ -+ return free_space; - } - - void tcp_skb_collapse_tstamp(struct sk_buff *skb, -diff --git a/net/mctp/route.c b/net/mctp/route.c -index f51a05ec71624..68be8f2b622dd 100644 ---- a/net/mctp/route.c -+++ b/net/mctp/route.c -@@ -737,6 +737,8 @@ struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet, - { - struct mctp_route *tmp, *rt = NULL; - -+ rcu_read_lock(); -+ - list_for_each_entry_rcu(tmp, &net->mctp.routes, list) { - /* TODO: add metrics */ - if (mctp_rt_match_eid(tmp, dnet, daddr)) { -@@ -747,21 +749,29 @@ struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet, - } - } - -+ rcu_read_unlock(); -+ - return rt; - } - - static struct mctp_route *mctp_route_lookup_null(struct net *net, - struct net_device *dev) - { -- struct mctp_route *rt; -+ struct mctp_route *tmp, *rt = NULL; - -- list_for_each_entry_rcu(rt, &net->mctp.routes, list) { -- if (rt->dev->dev == dev && rt->type == RTN_LOCAL && -- refcount_inc_not_zero(&rt->refs)) -- return rt; -+ rcu_read_lock(); -+ -+ list_for_each_entry_rcu(tmp, &net->mctp.routes, list) { -+ if (tmp->dev->dev == dev && tmp->type == RTN_LOCAL && -+ refcount_inc_not_zero(&tmp->refs)) { -+ rt = tmp; -+ break; -+ } - } - -- return NULL; -+ rcu_read_unlock(); -+ -+ return rt; - } - - static int mctp_do_fragment_route(struct mctp_route *rt, struct sk_buff *skb, -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index b6e0579e72644..881e05193ac97 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -3456,24 +3456,21 @@ static void schedule_3rdack_retransmission(struct sock *ssk) - sk_reset_timer(ssk, &icsk->icsk_delack_timer, timeout); - } - --void mptcp_subflow_process_delegated(struct sock *ssk) -+void mptcp_subflow_process_delegated(struct sock *ssk, long status) - { - struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); - struct sock *sk = subflow->conn; - -- if (test_bit(MPTCP_DELEGATE_SEND, &subflow->delegated_status)) { -+ if (status & BIT(MPTCP_DELEGATE_SEND)) { - mptcp_data_lock(sk); - if (!sock_owned_by_user(sk)) - __mptcp_subflow_push_pending(sk, ssk); - else - __set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->cb_flags); - mptcp_data_unlock(sk); -- mptcp_subflow_delegated_done(subflow, MPTCP_DELEGATE_SEND); - } -- if (test_bit(MPTCP_DELEGATE_ACK, &subflow->delegated_status)) { -+ if (status & BIT(MPTCP_DELEGATE_ACK)) - schedule_3rdack_retransmission(ssk); -- mptcp_subflow_delegated_done(subflow, MPTCP_DELEGATE_ACK); -- } - } - - static int mptcp_hash(struct sock *sk) -@@ -3981,14 +3978,17 @@ static int mptcp_napi_poll(struct napi_struct *napi, int budget) - struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - - bh_lock_sock_nested(ssk); -- if (!sock_owned_by_user(ssk) && -- mptcp_subflow_has_delegated_action(subflow)) -- mptcp_subflow_process_delegated(ssk); -- /* ... elsewhere tcp_release_cb_override already processed -- * the action or will do at next release_sock(). -- * In both case must dequeue the subflow here - on the same -- * CPU that scheduled it. -- */ -+ if (!sock_owned_by_user(ssk)) { -+ mptcp_subflow_process_delegated(ssk, xchg(&subflow->delegated_status, 0)); -+ } else { -+ /* tcp_release_cb_override already processed -+ * the action or will do at next release_sock(). -+ * In both case must dequeue the subflow here - on the same -+ * CPU that scheduled it. -+ */ -+ smp_wmb(); -+ clear_bit(MPTCP_DELEGATE_SCHEDULED, &subflow->delegated_status); -+ } - bh_unlock_sock(ssk); - sock_put(ssk); - -diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h -index 91d89a0aeb586..4ec8e0a81b5a4 100644 ---- a/net/mptcp/protocol.h -+++ b/net/mptcp/protocol.h -@@ -430,9 +430,11 @@ struct mptcp_delegated_action { - - DECLARE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions); - --#define MPTCP_DELEGATE_SEND 0 --#define MPTCP_DELEGATE_ACK 1 -+#define MPTCP_DELEGATE_SCHEDULED 0 -+#define MPTCP_DELEGATE_SEND 1 -+#define MPTCP_DELEGATE_ACK 2 - -+#define MPTCP_DELEGATE_ACTIONS_MASK (~BIT(MPTCP_DELEGATE_SCHEDULED)) - /* MPTCP subflow context */ - struct mptcp_subflow_context { - struct list_head node;/* conn_list of subflows */ -@@ -543,23 +545,24 @@ mptcp_subflow_get_mapped_dsn(const struct mptcp_subflow_context *subflow) - return subflow->map_seq + mptcp_subflow_get_map_offset(subflow); - } - --void mptcp_subflow_process_delegated(struct sock *ssk); -+void mptcp_subflow_process_delegated(struct sock *ssk, long actions); - - static inline void mptcp_subflow_delegate(struct mptcp_subflow_context *subflow, int action) - { -+ long old, set_bits = BIT(MPTCP_DELEGATE_SCHEDULED) | BIT(action); - struct mptcp_delegated_action *delegated; - bool schedule; - - /* the caller held the subflow bh socket lock */ - lockdep_assert_in_softirq(); - -- /* The implied barrier pairs with mptcp_subflow_delegated_done(), and -- * ensures the below list check sees list updates done prior to status -- * bit changes -+ /* The implied barrier pairs with tcp_release_cb_override() -+ * mptcp_napi_poll(), and ensures the below list check sees list -+ * updates done prior to delegated status bits changes - */ -- if (!test_and_set_bit(action, &subflow->delegated_status)) { -- /* still on delegated list from previous scheduling */ -- if (!list_empty(&subflow->delegated_node)) -+ old = set_mask_bits(&subflow->delegated_status, 0, set_bits); -+ if (!(old & BIT(MPTCP_DELEGATE_SCHEDULED))) { -+ if (WARN_ON_ONCE(!list_empty(&subflow->delegated_node))) - return; - - delegated = this_cpu_ptr(&mptcp_delegated_actions); -@@ -584,20 +587,6 @@ mptcp_subflow_delegated_next(struct mptcp_delegated_action *delegated) - return ret; - } - --static inline bool mptcp_subflow_has_delegated_action(const struct mptcp_subflow_context *subflow) --{ -- return !!READ_ONCE(subflow->delegated_status); --} -- --static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *subflow, int action) --{ -- /* pairs with mptcp_subflow_delegate, ensures delegate_node is updated before -- * touching the status bit -- */ -- smp_wmb(); -- clear_bit(action, &subflow->delegated_status); --} -- - int mptcp_is_enabled(const struct net *net); - unsigned int mptcp_get_add_addr_timeout(const struct net *net); - int mptcp_is_checksum_enabled(const struct net *net); -diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c -index b93b08a75017b..d611783c2601f 100644 ---- a/net/mptcp/subflow.c -+++ b/net/mptcp/subflow.c -@@ -1886,9 +1886,15 @@ static void subflow_ulp_clone(const struct request_sock *req, - static void tcp_release_cb_override(struct sock *ssk) - { - struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); -+ long status; - -- if (mptcp_subflow_has_delegated_action(subflow)) -- mptcp_subflow_process_delegated(ssk); -+ /* process and clear all the pending actions, but leave the subflow into -+ * the napi queue. To respect locking, only the same CPU that originated -+ * the action can touch the list. mptcp_napi_poll will take care of it. -+ */ -+ status = set_mask_bits(&subflow->delegated_status, MPTCP_DELEGATE_ACTIONS_MASK, 0); -+ if (status) -+ mptcp_subflow_process_delegated(ssk, status); - - tcp_release_cb(ssk); - } -diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c -index 6574f4e651b1a..e1dea9a820505 100644 ---- a/net/netfilter/ipvs/ip_vs_sync.c -+++ b/net/netfilter/ipvs/ip_vs_sync.c -@@ -1441,7 +1441,7 @@ static int bind_mcastif_addr(struct socket *sock, struct net_device *dev) - sin.sin_addr.s_addr = addr; - sin.sin_port = 0; - -- return sock->ops->bind(sock, (struct sockaddr*)&sin, sizeof(sin)); -+ return kernel_bind(sock, (struct sockaddr *)&sin, sizeof(sin)); - } - - static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen, -@@ -1548,7 +1548,7 @@ static int make_receive_sock(struct netns_ipvs *ipvs, int id, - - get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id); - sock->sk->sk_bound_dev_if = dev->ifindex; -- result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen); -+ result = kernel_bind(sock, (struct sockaddr *)&mcast_addr, salen); - if (result < 0) { - pr_err("Error binding to the multicast addr\n"); - goto error; -diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c -index 6705bb895e239..1dac28136e6a3 100644 ---- a/net/nfc/llcp_core.c -+++ b/net/nfc/llcp_core.c -@@ -203,17 +203,13 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, - - if (tmp_sock->ssap == ssap && tmp_sock->dsap == dsap) { - llcp_sock = tmp_sock; -+ sock_hold(&llcp_sock->sk); - break; - } - } - - read_unlock(&local->sockets.lock); - -- if (llcp_sock == NULL) -- return NULL; -- -- sock_hold(&llcp_sock->sk); -- - return llcp_sock; - } - -@@ -346,7 +342,8 @@ static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len) - - static - struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local, -- const u8 *sn, size_t sn_len) -+ const u8 *sn, size_t sn_len, -+ bool needref) - { - struct sock *sk; - struct nfc_llcp_sock *llcp_sock, *tmp_sock; -@@ -382,6 +379,8 @@ struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local, - - if (memcmp(sn, tmp_sock->service_name, sn_len) == 0) { - llcp_sock = tmp_sock; -+ if (needref) -+ sock_hold(&llcp_sock->sk); - break; - } - } -@@ -423,7 +422,8 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, - * to this service name. - */ - if (nfc_llcp_sock_from_sn(local, sock->service_name, -- sock->service_name_len) != NULL) { -+ sock->service_name_len, -+ false) != NULL) { - mutex_unlock(&local->sdp_lock); - - return LLCP_SAP_MAX; -@@ -824,16 +824,7 @@ out: - static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local, - const u8 *sn, size_t sn_len) - { -- struct nfc_llcp_sock *llcp_sock; -- -- llcp_sock = nfc_llcp_sock_from_sn(local, sn, sn_len); -- -- if (llcp_sock == NULL) -- return NULL; -- -- sock_hold(&llcp_sock->sk); -- -- return llcp_sock; -+ return nfc_llcp_sock_from_sn(local, sn, sn_len, true); - } - - static const u8 *nfc_llcp_connect_sn(const struct sk_buff *skb, size_t *sn_len) -@@ -1298,7 +1289,8 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local, - } - - llcp_sock = nfc_llcp_sock_from_sn(local, service_name, -- service_name_len); -+ service_name_len, -+ true); - if (!llcp_sock) { - sap = 0; - goto add_snl; -@@ -1318,6 +1310,7 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local, - - if (sap == LLCP_SAP_MAX) { - sap = 0; -+ nfc_llcp_sock_put(llcp_sock); - goto add_snl; - } - -@@ -1335,6 +1328,7 @@ static void nfc_llcp_recv_snl(struct nfc_llcp_local *local, - - pr_debug("%p %d\n", llcp_sock, sap); - -+ nfc_llcp_sock_put(llcp_sock); - add_snl: - sdp = nfc_llcp_build_sdres_tlv(tid, sap); - if (sdp == NULL) -diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c -index 4ffdf2f45c444..7535afd1537e9 100644 ---- a/net/nfc/nci/core.c -+++ b/net/nfc/nci/core.c -@@ -908,6 +908,11 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, - return -EINVAL; - } - -+ if (protocol >= NFC_PROTO_MAX) { -+ pr_err("the requested nfc protocol is invalid\n"); -+ return -EINVAL; -+ } -+ - if (!(nci_target->supported_protocols & (1 << protocol))) { - pr_err("target does not support the requested protocol 0x%x\n", - protocol); -diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c -index d788c6d28986f..a0046e99d6df7 100644 ---- a/net/rds/tcp_connect.c -+++ b/net/rds/tcp_connect.c -@@ -145,7 +145,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp) - addrlen = sizeof(sin); - } - -- ret = sock->ops->bind(sock, addr, addrlen); -+ ret = kernel_bind(sock, addr, addrlen); - if (ret) { - rdsdebug("bind failed with %d at address %pI6c\n", - ret, &conn->c_laddr); -diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c -index 7edf2e69d3fed..b576bd252fecb 100644 ---- a/net/rds/tcp_listen.c -+++ b/net/rds/tcp_listen.c -@@ -304,7 +304,7 @@ struct socket *rds_tcp_listen_init(struct net *net, bool isv6) - addr_len = sizeof(*sin); - } - -- ret = sock->ops->bind(sock, (struct sockaddr *)&ss, addr_len); -+ ret = kernel_bind(sock, (struct sockaddr *)&ss, addr_len); - if (ret < 0) { - rdsdebug("could not bind %s listener socket: %d\n", - isv6 ? "IPv6" : "IPv4", ret); -diff --git a/net/smc/smc_stats.h b/net/smc/smc_stats.h -index 4dbc237b7c19e..ee22d6f9a86aa 100644 ---- a/net/smc/smc_stats.h -+++ b/net/smc/smc_stats.h -@@ -93,13 +93,14 @@ do { \ - typeof(_smc_stats) stats = (_smc_stats); \ - typeof(_tech) t = (_tech); \ - typeof(_len) l = (_len); \ -- int _pos = fls64((l) >> 13); \ -+ int _pos; \ - typeof(_rc) r = (_rc); \ - int m = SMC_BUF_MAX - 1; \ - this_cpu_inc((*stats).smc[t].key ## _cnt); \ -- if (r <= 0) \ -+ if (r <= 0 || l <= 0) \ - break; \ -- _pos = (_pos < m) ? ((l == 1 << (_pos + 12)) ? _pos - 1 : _pos) : m; \ -+ _pos = fls64((l - 1) >> 13); \ -+ _pos = (_pos <= m) ? _pos : m; \ - this_cpu_inc((*stats).smc[t].key ## _pd.buf[_pos]); \ - this_cpu_add((*stats).smc[t].key ## _bytes, r); \ - } \ -@@ -139,9 +140,12 @@ while (0) - do { \ - typeof(_len) _l = (_len); \ - typeof(_tech) t = (_tech); \ -- int _pos = fls((_l) >> 13); \ -+ int _pos; \ - int m = SMC_BUF_MAX - 1; \ -- _pos = (_pos < m) ? ((_l == 1 << (_pos + 12)) ? _pos - 1 : _pos) : m; \ -+ if (_l <= 0) \ -+ break; \ -+ _pos = fls((_l - 1) >> 13); \ -+ _pos = (_pos <= m) ? _pos : m; \ - this_cpu_inc((*(_smc_stats)).smc[t].k ## _rmbsize.buf[_pos]); \ - } \ - while (0) -diff --git a/net/socket.c b/net/socket.c -index b0169168e3f4e..04cba91c7cbe5 100644 ---- a/net/socket.c -+++ b/net/socket.c -@@ -3454,7 +3454,11 @@ static long compat_sock_ioctl(struct file *file, unsigned int cmd, - - int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen) - { -- return sock->ops->bind(sock, addr, addrlen); -+ struct sockaddr_storage address; -+ -+ memcpy(&address, addr, addrlen); -+ -+ return sock->ops->bind(sock, (struct sockaddr *)&address, addrlen); - } - EXPORT_SYMBOL(kernel_bind); - -diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c -index c6fc50d67214c..85fb5c22529a7 100644 ---- a/security/keys/trusted-keys/trusted_core.c -+++ b/security/keys/trusted-keys/trusted_core.c -@@ -44,13 +44,12 @@ static const struct trusted_key_source trusted_key_sources[] = { - #endif - }; - --DEFINE_STATIC_CALL_NULL(trusted_key_init, *trusted_key_sources[0].ops->init); - DEFINE_STATIC_CALL_NULL(trusted_key_seal, *trusted_key_sources[0].ops->seal); - DEFINE_STATIC_CALL_NULL(trusted_key_unseal, - *trusted_key_sources[0].ops->unseal); - DEFINE_STATIC_CALL_NULL(trusted_key_get_random, - *trusted_key_sources[0].ops->get_random); --DEFINE_STATIC_CALL_NULL(trusted_key_exit, *trusted_key_sources[0].ops->exit); -+static void (*trusted_key_exit)(void); - static unsigned char migratable; - - enum { -@@ -359,19 +358,16 @@ static int __init init_trusted(void) - if (!get_random) - get_random = kernel_get_random; - -- static_call_update(trusted_key_init, -- trusted_key_sources[i].ops->init); - static_call_update(trusted_key_seal, - trusted_key_sources[i].ops->seal); - static_call_update(trusted_key_unseal, - trusted_key_sources[i].ops->unseal); - static_call_update(trusted_key_get_random, - get_random); -- static_call_update(trusted_key_exit, -- trusted_key_sources[i].ops->exit); -+ trusted_key_exit = trusted_key_sources[i].ops->exit; - migratable = trusted_key_sources[i].ops->migratable; - -- ret = static_call(trusted_key_init)(); -+ ret = trusted_key_sources[i].ops->init(); - if (!ret) - break; - } -@@ -388,7 +384,8 @@ static int __init init_trusted(void) - - static void __exit cleanup_trusted(void) - { -- static_call_cond(trusted_key_exit)(); -+ if (trusted_key_exit) -+ (*trusted_key_exit)(); - } - - late_initcall(init_trusted); -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 57e07aa4e136c..14e70e2f9c881 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -4639,6 +4639,22 @@ static void alc236_fixup_hp_mute_led_coefbit2(struct hda_codec *codec, - } - } - -+static void alc245_fixup_hp_mute_led_coefbit(struct hda_codec *codec, -+ const struct hda_fixup *fix, -+ int action) -+{ -+ struct alc_spec *spec = codec->spec; -+ -+ if (action == HDA_FIXUP_ACT_PRE_PROBE) { -+ spec->mute_led_polarity = 0; -+ spec->mute_led_coef.idx = 0x0b; -+ spec->mute_led_coef.mask = 3 << 2; -+ spec->mute_led_coef.on = 2 << 2; -+ spec->mute_led_coef.off = 1 << 2; -+ snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set); -+ } -+} -+ - /* turn on/off mic-mute LED per capture hook by coef bit */ - static int coef_micmute_led_set(struct led_classdev *led_cdev, - enum led_brightness brightness) -@@ -6969,6 +6985,29 @@ static void alc295_fixup_dell_inspiron_top_speakers(struct hda_codec *codec, - } - } - -+/* Forcibly assign NID 0x03 to HP while NID 0x02 to SPK */ -+static void alc287_fixup_bind_dacs(struct hda_codec *codec, -+ const struct hda_fixup *fix, int action) -+{ -+ struct alc_spec *spec = codec->spec; -+ static const hda_nid_t conn[] = { 0x02, 0x03 }; /* exclude 0x06 */ -+ static const hda_nid_t preferred_pairs[] = { -+ 0x17, 0x02, 0x21, 0x03, 0 -+ }; -+ -+ if (action != HDA_FIXUP_ACT_PRE_PROBE) -+ return; -+ -+ snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn); -+ spec->gen.preferred_dacs = preferred_pairs; -+ spec->gen.auto_mute_via_amp = 1; -+ if (spec->gen.autocfg.speaker_pins[0] != 0x14) { -+ snd_hda_codec_write_cache(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -+ 0x0); /* Make sure 0x14 was disable */ -+ } -+} -+ -+ - enum { - ALC269_FIXUP_GPIO2, - ALC269_FIXUP_SONY_VAIO, -@@ -7227,6 +7266,10 @@ enum { - ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS, - ALC236_FIXUP_DELL_DUAL_CODECS, - ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI, -+ ALC245_FIXUP_HP_MUTE_LED_COEFBIT, -+ ALC245_FIXUP_HP_X360_MUTE_LEDS, -+ ALC287_FIXUP_THINKPAD_I2S_SPK, -+ ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD, - }; - - /* A special fixup for Lenovo C940 and Yoga Duet 7; -@@ -9296,6 +9339,26 @@ static const struct hda_fixup alc269_fixups[] = { - .chained = true, - .chain_id = ALC269_FIXUP_THINKPAD_ACPI, - }, -+ [ALC245_FIXUP_HP_MUTE_LED_COEFBIT] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc245_fixup_hp_mute_led_coefbit, -+ }, -+ [ALC245_FIXUP_HP_X360_MUTE_LEDS] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc245_fixup_hp_mute_led_coefbit, -+ .chained = true, -+ .chain_id = ALC245_FIXUP_HP_GPIO_LED -+ }, -+ [ALC287_FIXUP_THINKPAD_I2S_SPK] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc287_fixup_bind_dacs, -+ }, -+ [ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc287_fixup_bind_dacs, -+ .chained = true, -+ .chain_id = ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI, -+ }, - }; - - static const struct snd_pci_quirk alc269_fixup_tbl[] = { -@@ -9531,6 +9594,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), - SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), - SND_PCI_QUIRK(0x103c, 0x887a, "HP Laptop 15s-eq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), -+ SND_PCI_QUIRK(0x103c, 0x888a, "HP ENVY x360 Convertible 15-eu0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), - SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8895, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED), - SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), -@@ -9562,6 +9626,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), -+ SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), - SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED), -@@ -9697,7 +9762,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x10ec, 0x124c, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), - SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), - SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), -- SND_PCI_QUIRK(0x10ec, 0x12cc, "Intel Reference board", ALC225_FIXUP_HEADSET_JACK), -+ SND_PCI_QUIRK(0x10ec, 0x12cc, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), - SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE), - SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), - SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_AMP), -@@ -9831,14 +9896,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), - SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), - SND_PCI_QUIRK(0x17aa, 0x22c2, "Thinkpad X1 Extreme Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), -- SND_PCI_QUIRK(0x17aa, 0x22f1, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI), -- SND_PCI_QUIRK(0x17aa, 0x22f2, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI), -- SND_PCI_QUIRK(0x17aa, 0x22f3, "Thinkpad", ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI), -- SND_PCI_QUIRK(0x17aa, 0x2316, "Thinkpad P1 Gen 6", ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI), -- SND_PCI_QUIRK(0x17aa, 0x2317, "Thinkpad P1 Gen 6", ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI), -- SND_PCI_QUIRK(0x17aa, 0x2318, "Thinkpad Z13 Gen2", ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI), -- SND_PCI_QUIRK(0x17aa, 0x2319, "Thinkpad Z16 Gen2", ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI), -- SND_PCI_QUIRK(0x17aa, 0x231a, "Thinkpad Z16 Gen2", ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI), -+ SND_PCI_QUIRK(0x17aa, 0x22f1, "Thinkpad", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), -+ SND_PCI_QUIRK(0x17aa, 0x22f2, "Thinkpad", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), -+ SND_PCI_QUIRK(0x17aa, 0x22f3, "Thinkpad", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), -+ SND_PCI_QUIRK(0x17aa, 0x2316, "Thinkpad P1 Gen 6", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), -+ SND_PCI_QUIRK(0x17aa, 0x2317, "Thinkpad P1 Gen 6", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), -+ SND_PCI_QUIRK(0x17aa, 0x2318, "Thinkpad Z13 Gen2", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), -+ SND_PCI_QUIRK(0x17aa, 0x2319, "Thinkpad Z16 Gen2", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), -+ SND_PCI_QUIRK(0x17aa, 0x231a, "Thinkpad Z16 Gen2", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), - SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), - SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), - SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), -@@ -9920,7 +9985,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), - SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), - SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), -- SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC225_FIXUP_HEADSET_JACK), -+ 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), - - #if 0 -@@ -10402,6 +10467,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { - {0x17, 0x90170111}, - {0x19, 0x03a11030}, - {0x21, 0x03211020}), -+ SND_HDA_PIN_QUIRK(0x10ec0287, 0x17aa, "Lenovo", ALC287_FIXUP_THINKPAD_I2S_SPK, -+ {0x17, 0x90170110}, -+ {0x19, 0x03a11030}, -+ {0x21, 0x03211020}), - SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE, - {0x12, 0x90a60130}, - {0x17, 0x90170110}, -diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c -index 533250efcbd83..c494de5f5c066 100644 ---- a/sound/soc/amd/yc/acp6x-mach.c -+++ b/sound/soc/amd/yc/acp6x-mach.c -@@ -234,6 +234,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "82V2"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82YM"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c -index 8c86b578eba83..29af9595dac19 100644 ---- a/sound/soc/codecs/sta32x.c -+++ b/sound/soc/codecs/sta32x.c -@@ -1054,35 +1054,32 @@ static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x) - of_property_read_u8(np, "st,ch3-output-mapping", - &pdata->ch3_output_mapping); - -- if (of_get_property(np, "st,fault-detect-recovery", NULL)) -- pdata->fault_detect_recovery = 1; -- if (of_get_property(np, "st,thermal-warning-recovery", NULL)) -- pdata->thermal_warning_recovery = 1; -- if (of_get_property(np, "st,thermal-warning-adjustment", NULL)) -- pdata->thermal_warning_adjustment = 1; -- if (of_get_property(np, "st,needs_esd_watchdog", NULL)) -- pdata->needs_esd_watchdog = 1; -+ pdata->fault_detect_recovery = -+ of_property_read_bool(np, "st,fault-detect-recovery"); -+ pdata->thermal_warning_recovery = -+ of_property_read_bool(np, "st,thermal-warning-recovery"); -+ pdata->thermal_warning_adjustment = -+ of_property_read_bool(np, "st,thermal-warning-adjustment"); -+ pdata->needs_esd_watchdog = -+ of_property_read_bool(np, "st,needs_esd_watchdog"); - - tmp = 140; - of_property_read_u16(np, "st,drop-compensation-ns", &tmp); - pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20; - - /* CONFE */ -- if (of_get_property(np, "st,max-power-use-mpcc", NULL)) -- pdata->max_power_use_mpcc = 1; -- -- if (of_get_property(np, "st,max-power-correction", NULL)) -- pdata->max_power_correction = 1; -- -- if (of_get_property(np, "st,am-reduction-mode", NULL)) -- pdata->am_reduction_mode = 1; -- -- if (of_get_property(np, "st,odd-pwm-speed-mode", NULL)) -- pdata->odd_pwm_speed_mode = 1; -+ pdata->max_power_use_mpcc = -+ of_property_read_bool(np, "st,max-power-use-mpcc"); -+ pdata->max_power_correction = -+ of_property_read_bool(np, "st,max-power-correction"); -+ pdata->am_reduction_mode = -+ of_property_read_bool(np, "st,am-reduction-mode"); -+ pdata->odd_pwm_speed_mode = -+ of_property_read_bool(np, "st,odd-pwm-speed-mode"); - - /* CONFF */ -- if (of_get_property(np, "st,invalid-input-detect-mute", NULL)) -- pdata->invalid_input_detect_mute = 1; -+ pdata->invalid_input_detect_mute = -+ of_property_read_bool(np, "st,invalid-input-detect-mute"); - - sta32x->pdata = pdata; - -diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c -index 9ed13aeb3cbdc..b033a5fcd6c04 100644 ---- a/sound/soc/codecs/sta350.c -+++ b/sound/soc/codecs/sta350.c -@@ -1106,12 +1106,12 @@ static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350) - of_property_read_u8(np, "st,ch3-output-mapping", - &pdata->ch3_output_mapping); - -- if (of_get_property(np, "st,thermal-warning-recovery", NULL)) -- pdata->thermal_warning_recovery = 1; -- if (of_get_property(np, "st,thermal-warning-adjustment", NULL)) -- pdata->thermal_warning_adjustment = 1; -- if (of_get_property(np, "st,fault-detect-recovery", NULL)) -- pdata->fault_detect_recovery = 1; -+ pdata->thermal_warning_recovery = -+ of_property_read_bool(np, "st,thermal-warning-recovery"); -+ pdata->thermal_warning_adjustment = -+ of_property_read_bool(np, "st,thermal-warning-adjustment"); -+ pdata->fault_detect_recovery = -+ of_property_read_bool(np, "st,fault-detect-recovery"); - - pdata->ffx_power_output_mode = STA350_FFX_PM_VARIABLE_DROP_COMP; - if (!of_property_read_string(np, "st,ffx-power-output-mode", -@@ -1133,41 +1133,34 @@ static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350) - of_property_read_u16(np, "st,drop-compensation-ns", &tmp); - pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20; - -- if (of_get_property(np, "st,overcurrent-warning-adjustment", NULL)) -- pdata->oc_warning_adjustment = 1; -+ pdata->oc_warning_adjustment = -+ of_property_read_bool(np, "st,overcurrent-warning-adjustment"); - - /* CONFE */ -- if (of_get_property(np, "st,max-power-use-mpcc", NULL)) -- pdata->max_power_use_mpcc = 1; -- -- if (of_get_property(np, "st,max-power-correction", NULL)) -- pdata->max_power_correction = 1; -- -- if (of_get_property(np, "st,am-reduction-mode", NULL)) -- pdata->am_reduction_mode = 1; -- -- if (of_get_property(np, "st,odd-pwm-speed-mode", NULL)) -- pdata->odd_pwm_speed_mode = 1; -- -- if (of_get_property(np, "st,distortion-compensation", NULL)) -- pdata->distortion_compensation = 1; -+ pdata->max_power_use_mpcc = -+ of_property_read_bool(np, "st,max-power-use-mpcc"); -+ pdata->max_power_correction = -+ of_property_read_bool(np, "st,max-power-correction"); -+ pdata->am_reduction_mode = -+ of_property_read_bool(np, "st,am-reduction-mode"); -+ pdata->odd_pwm_speed_mode = -+ of_property_read_bool(np, "st,odd-pwm-speed-mode"); -+ pdata->distortion_compensation = -+ of_property_read_bool(np, "st,distortion-compensation"); - - /* CONFF */ -- if (of_get_property(np, "st,invalid-input-detect-mute", NULL)) -- pdata->invalid_input_detect_mute = 1; -+ pdata->invalid_input_detect_mute = -+ of_property_read_bool(np, "st,invalid-input-detect-mute"); - - /* MISC */ -- if (of_get_property(np, "st,activate-mute-output", NULL)) -- pdata->activate_mute_output = 1; -- -- if (of_get_property(np, "st,bridge-immediate-off", NULL)) -- pdata->bridge_immediate_off = 1; -- -- if (of_get_property(np, "st,noise-shape-dc-cut", NULL)) -- pdata->noise_shape_dc_cut = 1; -- -- if (of_get_property(np, "st,powerdown-master-volume", NULL)) -- pdata->powerdown_master_vol = 1; -+ pdata->activate_mute_output = -+ of_property_read_bool(np, "st,activate-mute-output"); -+ pdata->bridge_immediate_off = -+ of_property_read_bool(np, "st,bridge-immediate-off"); -+ pdata->noise_shape_dc_cut = -+ of_property_read_bool(np, "st,noise-shape-dc-cut"); -+ pdata->powerdown_master_vol = -+ of_property_read_bool(np, "st,powerdown-master-volume"); - - if (!of_property_read_u8(np, "st,powerdown-delay-divider", &tmp8)) { - if (is_power_of_2(tmp8) && tmp8 >= 1 && tmp8 <= 128) -diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c -index 22143cc5afa70..f9e7122894bd2 100644 ---- a/sound/soc/codecs/tas5086.c -+++ b/sound/soc/codecs/tas5086.c -@@ -840,7 +840,7 @@ static int tas5086_probe(struct snd_soc_component *component) - snprintf(name, sizeof(name), - "ti,mid-z-channel-%d", i + 1); - -- if (of_get_property(of_node, name, NULL) != NULL) -+ if (of_property_read_bool(of_node, name)) - priv->pwm_start_mid_z |= 1 << i; - } - } -diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c -index b7552b0df7c3c..96fd9095e544b 100644 ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -710,10 +710,15 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, int dir) - { - unsigned int ofs = sai->soc_data->reg_offset; - bool tx = dir == TX; -- u32 xcsr, count = 100; -+ u32 xcsr, count = 100, mask; -+ -+ if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output) -+ mask = FSL_SAI_CSR_TERE; -+ else -+ mask = FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE; - - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), -- FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE, 0); -+ mask, 0); - - /* TERE will remain set till the end of current frame */ - do { -@@ -1381,18 +1386,18 @@ static int fsl_sai_probe(struct platform_device *pdev) - sai->cpu_dai_drv.symmetric_channels = 1; - sai->cpu_dai_drv.symmetric_sample_bits = 1; - -- if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && -- of_find_property(np, "fsl,sai-asynchronous", NULL)) { -+ if (of_property_read_bool(np, "fsl,sai-synchronous-rx") && -+ of_property_read_bool(np, "fsl,sai-asynchronous")) { - /* error out if both synchronous and asynchronous are present */ - dev_err(dev, "invalid binding for synchronous mode\n"); - return -EINVAL; - } - -- if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) { -+ if (of_property_read_bool(np, "fsl,sai-synchronous-rx")) { - /* Sync Rx with Tx */ - sai->synchronous[RX] = false; - sai->synchronous[TX] = true; -- } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) { -+ } else if (of_property_read_bool(np, "fsl,sai-asynchronous")) { - /* Discard all settings for asynchronous mode */ - sai->synchronous[RX] = false; - sai->synchronous[TX] = false; -@@ -1401,7 +1406,9 @@ static int fsl_sai_probe(struct platform_device *pdev) - sai->cpu_dai_drv.symmetric_sample_bits = 0; - } - -- if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && -+ sai->mclk_direction_output = of_property_read_bool(np, "fsl,sai-mclk-direction-output"); -+ -+ if (sai->mclk_direction_output && - of_device_is_compatible(np, "fsl,imx6ul-sai")) { - gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); - if (IS_ERR(gpr)) { -@@ -1442,7 +1449,7 @@ static int fsl_sai_probe(struct platform_device *pdev) - dev_warn(dev, "Error reading SAI version: %d\n", ret); - - /* Select MCLK direction */ -- if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && -+ if (sai->mclk_direction_output && - sai->soc_data->max_register >= FSL_SAI_MCTL) { - regmap_update_bits(sai->regmap, FSL_SAI_MCTL, - FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); -@@ -1560,6 +1567,17 @@ static const struct fsl_sai_soc_data fsl_sai_imx8mm_data = { - .max_register = FSL_SAI_MCTL, - }; - -+static const struct fsl_sai_soc_data fsl_sai_imx8mn_data = { -+ .use_imx_pcm = true, -+ .use_edma = false, -+ .fifo_depth = 128, -+ .reg_offset = 8, -+ .mclk0_is_mclk1 = false, -+ .pins = 8, -+ .flags = 0, -+ .max_register = FSL_SAI_MDIV, -+}; -+ - static const struct fsl_sai_soc_data fsl_sai_imx8mp_data = { - .use_imx_pcm = true, - .use_edma = false, -@@ -1569,6 +1587,7 @@ static const struct fsl_sai_soc_data fsl_sai_imx8mp_data = { - .pins = 8, - .flags = 0, - .max_register = FSL_SAI_MDIV, -+ .mclk_with_tere = true, - }; - - static const struct fsl_sai_soc_data fsl_sai_imx8ulp_data = { -@@ -1592,7 +1611,7 @@ static const struct of_device_id fsl_sai_ids[] = { - { .compatible = "fsl,imx8mm-sai", .data = &fsl_sai_imx8mm_data }, - { .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp_data }, - { .compatible = "fsl,imx8ulp-sai", .data = &fsl_sai_imx8ulp_data }, -- { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mp_data }, -+ { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mn_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, fsl_sai_ids); -@@ -1656,6 +1675,10 @@ static int fsl_sai_runtime_resume(struct device *dev) - if (ret) - goto disable_rx_clk; - -+ if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output) -+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs), -+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); -+ - return 0; - - disable_rx_clk: -diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h -index caad5b0ac4ff4..b4d616a44023c 100644 ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -232,6 +232,7 @@ struct fsl_sai_soc_data { - bool use_imx_pcm; - bool use_edma; - bool mclk0_is_mclk1; -+ bool mclk_with_tere; - unsigned int fifo_depth; - unsigned int pins; - unsigned int reg_offset; -@@ -288,6 +289,7 @@ struct fsl_sai { - bool synchronous[2]; - struct fsl_sai_dl_cfg *dl_cfg; - unsigned int dl_cfg_cnt; -+ bool mclk_direction_output; - - unsigned int mclk_id[2]; - unsigned int mclk_streams; -diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c -index 46a53551b955c..6af00b62a60fa 100644 ---- a/sound/soc/fsl/fsl_ssi.c -+++ b/sound/soc/fsl/fsl_ssi.c -@@ -1447,7 +1447,7 @@ static int fsl_ssi_probe_from_dt(struct fsl_ssi *ssi) - return -EINVAL; - } - strcpy(ssi->card_name, "ac97-codec"); -- } else if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) { -+ } else if (!of_property_read_bool(np, "fsl,ssi-asynchronous")) { - /* - * In synchronous mode, STCK and STFS ports are used by RX - * as well. So the software should limit the sample rates, -diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c -index 3f128ced41809..64a4d7e9db603 100644 ---- a/sound/soc/fsl/imx-card.c -+++ b/sound/soc/fsl/imx-card.c -@@ -563,7 +563,7 @@ static int imx_card_parse_of(struct imx_card_data *data) - link_data->cpu_sysclk_id = FSL_SAI_CLK_MAST1; - - /* sai may support mclk/bclk = 1 */ -- if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) { -+ if (of_property_read_bool(np, "fsl,mclk-equal-bclk")) { - link_data->one2one_ratio = true; - } else { - int i; -diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c -index 8811321717fbb..c719354635a3a 100644 ---- a/sound/soc/generic/simple-card-utils.c -+++ b/sound/soc/generic/simple-card-utils.c -@@ -331,7 +331,8 @@ int asoc_simple_startup(struct snd_pcm_substream *substream) - if (fixed_sysclk % props->mclk_fs) { - dev_err(rtd->dev, "fixed sysclk %u not divisible by mclk_fs %u\n", - fixed_sysclk, props->mclk_fs); -- return -EINVAL; -+ ret = -EINVAL; -+ goto codec_err; - } - ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, - fixed_rate, fixed_rate); -diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c -index 894b6610b9e27..e22d767b6e97a 100644 ---- a/sound/soc/intel/boards/sof_es8336.c -+++ b/sound/soc/intel/boards/sof_es8336.c -@@ -807,6 +807,16 @@ static const struct platform_device_id board_ids[] = { - SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK | - SOF_ES8336_JD_INVERTED), - }, -+ { -+ .name = "mtl_es83x6_c1_h02", -+ .driver_data = (kernel_ulong_t)(SOF_ES8336_SSP_CODEC(1) | -+ SOF_NO_OF_HDMI_CAPTURE_SSP(2) | -+ SOF_HDMI_CAPTURE_1_SSP(0) | -+ SOF_HDMI_CAPTURE_2_SSP(2) | -+ SOF_SSP_HDMI_CAPTURE_PRESENT | -+ SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK | -+ SOF_ES8336_JD_INVERTED), -+ }, - { } - }; - MODULE_DEVICE_TABLE(platform, board_ids); -diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c -index 414ac90273810..985012f2003e2 100644 ---- a/sound/soc/intel/boards/sof_sdw.c -+++ b/sound/soc/intel/boards/sof_sdw.c -@@ -347,6 +347,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { - /* No Jack */ - .driver_data = (void *)SOF_SDW_TGL_HDMI, - }, -+ { -+ .callback = sof_sdw_quirk_cb, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B14"), -+ }, -+ /* No Jack */ -+ .driver_data = (void *)SOF_SDW_TGL_HDMI, -+ }, -+ - { - .callback = sof_sdw_quirk_cb, - .matches = { -diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c -index 36c361fb28a4d..d3b4689460ecf 100644 ---- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c -+++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c -@@ -20,6 +20,16 @@ static const struct snd_soc_acpi_codecs mtl_rt5682_rt5682s_hp = { - .codecs = {"10EC5682", "RTL5682"}, - }; - -+static const struct snd_soc_acpi_codecs mtl_lt6911_hdmi = { -+ .num_codecs = 1, -+ .codecs = {"INTC10B0"} -+}; -+ -+static const struct snd_soc_acpi_codecs mtl_essx_83x6 = { -+ .num_codecs = 3, -+ .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, -+}; -+ - struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = { - { - .comp_ids = &mtl_rt5682_rt5682s_hp, -@@ -28,6 +38,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = { - .quirk_data = &mtl_max98357a_amp, - .sof_tplg_filename = "sof-mtl-max98357a-rt5682.tplg", - }, -+ { -+ .comp_ids = &mtl_essx_83x6, -+ .drv_name = "sof-essx8336", -+ .sof_tplg_filename = "sof-mtl-es8336", /* the tplg suffix is added at run time */ -+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER | -+ SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | -+ SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, -+ }, - {}, - }; - EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines); -@@ -66,6 +84,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { - .drv_name = "sof_sdw", - .sof_tplg_filename = "sof-mtl-rt711-rt1308-rt715.tplg", - }, -+ { -+ .comp_ids = &mtl_essx_83x6, -+ .drv_name = "mtl_es83x6_c1_h02", -+ .machine_quirk = snd_soc_acpi_codec_list, -+ .quirk_data = &mtl_lt6911_hdmi, -+ .sof_tplg_filename = "sof-mtl-es83x6-ssp1-hdmi-ssp02.tplg", -+ }, - { - .link_mask = BIT(0) | BIT(1) | BIT(3), - .links = sdw_mockup_headset_1amp_mic, -diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c -index 7ade6c5ed96ff..cb7fff48959a2 100644 ---- a/sound/soc/sh/rcar/ssi.c -+++ b/sound/soc/sh/rcar/ssi.c -@@ -1208,10 +1208,10 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) - goto rsnd_ssi_probe_done; - } - -- if (of_get_property(np, "shared-pin", NULL)) -+ if (of_property_read_bool(np, "shared-pin")) - rsnd_flags_set(ssi, RSND_SSI_CLK_PIN_SHARE); - -- if (of_get_property(np, "no-busif", NULL)) -+ if (of_property_read_bool(np, "no-busif")) - rsnd_flags_set(ssi, RSND_SSI_NO_BUSIF); - - ssi->irq = irq_of_parse_and_map(np, 0); -diff --git a/sound/soc/sof/amd/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c -index 5698d910b26f3..6fa060cab657e 100644 ---- a/sound/soc/sof/amd/pci-rmb.c -+++ b/sound/soc/sof/amd/pci-rmb.c -@@ -54,7 +54,6 @@ static const struct sof_amd_acp_desc rembrandt_chip_info = { - .sram_pte_offset = ACP6X_SRAM_PTE_OFFSET, - .i2s_pin_config_offset = ACP6X_I2S_PIN_CONFIG, - .hw_semaphore_offset = ACP6X_AXI2DAGB_SEM_0, -- .acp_clkmux_sel = ACP6X_CLKMUX_SEL, - .fusion_dsp_offset = ACP6X_DSP_FUSION_RUNSTALL, - }; - -diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c -index 9105ec623120a..783a2493707ea 100644 ---- a/sound/usb/mixer.c -+++ b/sound/usb/mixer.c -@@ -1204,6 +1204,13 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, - cval->res = 16; - } - break; -+ case USB_ID(0x1bcf, 0x2283): /* NexiGo N930AF FHD Webcam */ -+ if (!strcmp(kctl->id.name, "Mic Capture Volume")) { -+ usb_audio_info(chip, -+ "set resolution quirk: cval->res = 16\n"); -+ cval->res = 16; -+ } -+ break; - } - } - -diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c -index 4667d543f7481..6129a62316422 100644 ---- a/sound/usb/quirks.c -+++ b/sound/usb/quirks.c -@@ -1992,7 +1992,11 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip, - /* mic works only when ep packet size is set to wMaxPacketSize */ - fp->attributes |= UAC_EP_CS_ATTR_FILL_MAX; - break; -- -+ case USB_ID(0x3511, 0x2b1e): /* Opencomm2 UC USB Bluetooth dongle */ -+ /* mic works only when ep pitch control is not set */ -+ if (stream == SNDRV_PCM_STREAM_CAPTURE) -+ fp->attributes &= ~UAC_EP_CS_ATTR_PITCH_CONTROL; -+ break; - } - } - -@@ -2171,6 +2175,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_FIXED_RATE), - DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */ - QUIRK_FLAG_FIXED_RATE), -+ DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */ -+ QUIRK_FLAG_GET_SAMPLE_RATE), - - /* Vendor matches */ - VENDOR_FLG(0x045e, /* MS Lifecam */ diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.59-60.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.59-60.patch deleted file mode 100644 index 512a62e4a154..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.59-60.patch +++ /dev/null @@ -1,7686 +0,0 @@ -diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml -index a96f143479c79..eb0e9cca70570 100644 ---- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml -+++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml -@@ -59,7 +59,7 @@ properties: - maxItems: 4 - - clocks: -- minItems: 3 -+ minItems: 2 - items: - - description: Main peripheral bus clock, PCLK/HCLK - AHB Bus clock - - description: SDC MMC clock, MCLK -diff --git a/Makefile b/Makefile -index 4ad29c852e5f8..d47edcd8888e8 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 59 -+SUBLEVEL = 60 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi -index d69f0f4b4990d..d2d516d113baa 100644 ---- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi -+++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi -@@ -640,6 +640,7 @@ - &uart3 { - interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH - &omap4_pmx_core 0x17c>; -+ overrun-throttle-ms = <500>; - }; - - &uart4 { -diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c -index 227cf0a62800b..486aa03abbe17 100644 ---- a/arch/s390/pci/pci_dma.c -+++ b/arch/s390/pci/pci_dma.c -@@ -544,6 +544,17 @@ static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg, - s->dma_length = 0; - } - } -+ -+static unsigned long *bitmap_vzalloc(size_t bits, gfp_t flags) -+{ -+ size_t n = BITS_TO_LONGS(bits); -+ size_t bytes; -+ -+ if (unlikely(check_mul_overflow(n, sizeof(unsigned long), &bytes))) -+ return NULL; -+ -+ return vzalloc(bytes); -+} - - int zpci_dma_init_device(struct zpci_dev *zdev) - { -@@ -584,13 +595,13 @@ int zpci_dma_init_device(struct zpci_dev *zdev) - zdev->end_dma - zdev->start_dma + 1); - zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1; - zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; -- zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); -+ zdev->iommu_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL); - if (!zdev->iommu_bitmap) { - rc = -ENOMEM; - goto free_dma_table; - } - if (!s390_iommu_strict) { -- zdev->lazy_bitmap = vzalloc(zdev->iommu_pages / 8); -+ zdev->lazy_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL); - if (!zdev->lazy_bitmap) { - rc = -ENOMEM; - goto free_bitmap; -diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c -index e65f0968e0d9d..9c91cc40f4565 100644 ---- a/arch/x86/boot/compressed/sev.c -+++ b/arch/x86/boot/compressed/sev.c -@@ -103,6 +103,16 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, - return ES_OK; - } - -+static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size) -+{ -+ return ES_OK; -+} -+ -+static bool fault_in_kernel_space(unsigned long address) -+{ -+ return false; -+} -+ - #undef __init - #undef __pa - #define __init -diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h -index b475d9a582b88..e829fa4c6788e 100644 ---- a/arch/x86/include/asm/fpu/api.h -+++ b/arch/x86/include/asm/fpu/api.h -@@ -148,7 +148,8 @@ static inline void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd) { - static inline void fpu_sync_guest_vmexit_xfd_state(void) { } - #endif - --extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, unsigned int size, u32 pkru); -+extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, -+ unsigned int size, u64 xfeatures, u32 pkru); - extern int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf, u64 xcr0, u32 *vpkru); - - static inline void fpstate_set_confidential(struct fpu_guest *gfpu) -diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index 08a84f801bfea..c1dcaa3d2d6eb 100644 ---- a/arch/x86/include/asm/kvm_host.h -+++ b/arch/x86/include/asm/kvm_host.h -@@ -1324,7 +1324,6 @@ struct kvm_arch { - * the thread holds the MMU lock in write mode. - */ - spinlock_t tdp_mmu_pages_lock; -- struct workqueue_struct *tdp_mmu_zap_wq; - #endif /* CONFIG_X86_64 */ - - /* -@@ -1727,7 +1726,7 @@ void kvm_mmu_vendor_module_exit(void); - - void kvm_mmu_destroy(struct kvm_vcpu *vcpu); - int kvm_mmu_create(struct kvm_vcpu *vcpu); --int kvm_mmu_init_vm(struct kvm *kvm); -+void kvm_mmu_init_vm(struct kvm *kvm); - void kvm_mmu_uninit_vm(struct kvm *kvm); - - void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu); -diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h -index 02aac78cb21d4..184fd776cd39f 100644 ---- a/arch/x86/include/asm/svm.h -+++ b/arch/x86/include/asm/svm.h -@@ -259,6 +259,7 @@ enum avic_ipi_failure_cause { - AVIC_IPI_FAILURE_TARGET_NOT_RUNNING, - AVIC_IPI_FAILURE_INVALID_TARGET, - AVIC_IPI_FAILURE_INVALID_BACKING_PAGE, -+ AVIC_IPI_FAILURE_INVALID_IPI_VECTOR, - }; - - #define AVIC_PHYSICAL_MAX_INDEX_MASK GENMASK_ULL(8, 0) -diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c -index a083f9ac9e4f6..1d190761d00fd 100644 ---- a/arch/x86/kernel/fpu/core.c -+++ b/arch/x86/kernel/fpu/core.c -@@ -369,14 +369,15 @@ int fpu_swap_kvm_fpstate(struct fpu_guest *guest_fpu, bool enter_guest) - EXPORT_SYMBOL_GPL(fpu_swap_kvm_fpstate); - - void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, -- unsigned int size, u32 pkru) -+ unsigned int size, u64 xfeatures, u32 pkru) - { - struct fpstate *kstate = gfpu->fpstate; - union fpregs_state *ustate = buf; - struct membuf mb = { .p = buf, .left = size }; - - if (cpu_feature_enabled(X86_FEATURE_XSAVE)) { -- __copy_xstate_to_uabi_buf(mb, kstate, pkru, XSTATE_COPY_XSAVE); -+ __copy_xstate_to_uabi_buf(mb, kstate, xfeatures, pkru, -+ XSTATE_COPY_XSAVE); - } else { - memcpy(&ustate->fxsave, &kstate->regs.fxsave, - sizeof(ustate->fxsave)); -diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c -index 1afbc4866b100..ebe698f8af73b 100644 ---- a/arch/x86/kernel/fpu/xstate.c -+++ b/arch/x86/kernel/fpu/xstate.c -@@ -1053,6 +1053,7 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, - * __copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer - * @to: membuf descriptor - * @fpstate: The fpstate buffer from which to copy -+ * @xfeatures: The mask of xfeatures to save (XSAVE mode only) - * @pkru_val: The PKRU value to store in the PKRU component - * @copy_mode: The requested copy mode - * -@@ -1063,7 +1064,8 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, - * It supports partial copy but @to.pos always starts from zero. - */ - void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, -- u32 pkru_val, enum xstate_copy_mode copy_mode) -+ u64 xfeatures, u32 pkru_val, -+ enum xstate_copy_mode copy_mode) - { - const unsigned int off_mxcsr = offsetof(struct fxregs_state, mxcsr); - struct xregs_state *xinit = &init_fpstate.regs.xsave; -@@ -1087,7 +1089,7 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, - break; - - case XSTATE_COPY_XSAVE: -- header.xfeatures &= fpstate->user_xfeatures; -+ header.xfeatures &= fpstate->user_xfeatures & xfeatures; - break; - } - -@@ -1189,6 +1191,7 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, - enum xstate_copy_mode copy_mode) - { - __copy_xstate_to_uabi_buf(to, tsk->thread.fpu.fpstate, -+ tsk->thread.fpu.fpstate->user_xfeatures, - tsk->thread.pkru, copy_mode); - } - -@@ -1540,10 +1543,7 @@ static int fpstate_realloc(u64 xfeatures, unsigned int ksize, - fpregs_restore_userregs(); - - newfps->xfeatures = curfps->xfeatures | xfeatures; -- -- if (!guest_fpu) -- newfps->user_xfeatures = curfps->user_xfeatures | xfeatures; -- -+ newfps->user_xfeatures = curfps->user_xfeatures | xfeatures; - newfps->xfd = curfps->xfd & ~xfeatures; - - /* Do the final updates within the locked region */ -diff --git a/arch/x86/kernel/fpu/xstate.h b/arch/x86/kernel/fpu/xstate.h -index a4ecb04d8d646..3518fb26d06b0 100644 ---- a/arch/x86/kernel/fpu/xstate.h -+++ b/arch/x86/kernel/fpu/xstate.h -@@ -43,7 +43,8 @@ enum xstate_copy_mode { - - struct membuf; - extern void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, -- u32 pkru_val, enum xstate_copy_mode copy_mode); -+ u64 xfeatures, u32 pkru_val, -+ enum xstate_copy_mode copy_mode); - extern void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, - enum xstate_copy_mode mode); - extern int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf, u32 *pkru); -diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c -index 7dce812ce2538..71d8698702ce3 100644 ---- a/arch/x86/kernel/sev-shared.c -+++ b/arch/x86/kernel/sev-shared.c -@@ -629,6 +629,23 @@ fail: - sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); - } - -+static enum es_result vc_insn_string_check(struct es_em_ctxt *ctxt, -+ unsigned long address, -+ bool write) -+{ -+ if (user_mode(ctxt->regs) && fault_in_kernel_space(address)) { -+ ctxt->fi.vector = X86_TRAP_PF; -+ ctxt->fi.error_code = X86_PF_USER; -+ ctxt->fi.cr2 = address; -+ if (write) -+ ctxt->fi.error_code |= X86_PF_WRITE; -+ -+ return ES_EXCEPTION; -+ } -+ -+ return ES_OK; -+} -+ - static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, - void *src, char *buf, - unsigned int data_size, -@@ -636,7 +653,12 @@ static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, - bool backwards) - { - int i, b = backwards ? -1 : 1; -- enum es_result ret = ES_OK; -+ unsigned long address = (unsigned long)src; -+ enum es_result ret; -+ -+ ret = vc_insn_string_check(ctxt, address, false); -+ if (ret != ES_OK) -+ return ret; - - for (i = 0; i < count; i++) { - void *s = src + (i * data_size * b); -@@ -657,7 +679,12 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt, - bool backwards) - { - int i, s = backwards ? -1 : 1; -- enum es_result ret = ES_OK; -+ unsigned long address = (unsigned long)dst; -+ enum es_result ret; -+ -+ ret = vc_insn_string_check(ctxt, address, true); -+ if (ret != ES_OK) -+ return ret; - - for (i = 0; i < count; i++) { - void *d = dst + (i * data_size * s); -@@ -693,6 +720,9 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt, - static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) - { - struct insn *insn = &ctxt->insn; -+ size_t size; -+ u64 port; -+ - *exitinfo = 0; - - switch (insn->opcode.bytes[0]) { -@@ -701,7 +731,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) - case 0x6d: - *exitinfo |= IOIO_TYPE_INS; - *exitinfo |= IOIO_SEG_ES; -- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; -+ port = ctxt->regs->dx & 0xffff; - break; - - /* OUTS opcodes */ -@@ -709,41 +739,43 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) - case 0x6f: - *exitinfo |= IOIO_TYPE_OUTS; - *exitinfo |= IOIO_SEG_DS; -- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; -+ port = ctxt->regs->dx & 0xffff; - break; - - /* IN immediate opcodes */ - case 0xe4: - case 0xe5: - *exitinfo |= IOIO_TYPE_IN; -- *exitinfo |= (u8)insn->immediate.value << 16; -+ port = (u8)insn->immediate.value & 0xffff; - break; - - /* OUT immediate opcodes */ - case 0xe6: - case 0xe7: - *exitinfo |= IOIO_TYPE_OUT; -- *exitinfo |= (u8)insn->immediate.value << 16; -+ port = (u8)insn->immediate.value & 0xffff; - break; - - /* IN register opcodes */ - case 0xec: - case 0xed: - *exitinfo |= IOIO_TYPE_IN; -- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; -+ port = ctxt->regs->dx & 0xffff; - break; - - /* OUT register opcodes */ - case 0xee: - case 0xef: - *exitinfo |= IOIO_TYPE_OUT; -- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; -+ port = ctxt->regs->dx & 0xffff; - break; - - default: - return ES_DECODE_FAILED; - } - -+ *exitinfo |= port << 16; -+ - switch (insn->opcode.bytes[0]) { - case 0x6c: - case 0x6e: -@@ -753,12 +785,15 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) - case 0xee: - /* Single byte opcodes */ - *exitinfo |= IOIO_DATA_8; -+ size = 1; - break; - default: - /* Length determined by instruction parsing */ - *exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16 - : IOIO_DATA_32; -+ size = (insn->opnd_bytes == 2) ? 2 : 4; - } -+ - switch (insn->addr_bytes) { - case 2: - *exitinfo |= IOIO_ADDR_16; -@@ -774,7 +809,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) - if (insn_has_rep_prefix(insn)) - *exitinfo |= IOIO_REP; - -- return ES_OK; -+ return vc_ioio_check(ctxt, (u16)port, size); - } - - static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) -diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c -index afda719dd7253..e7968c41ecf57 100644 ---- a/arch/x86/kernel/sev.c -+++ b/arch/x86/kernel/sev.c -@@ -512,6 +512,33 @@ static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt - return ES_OK; - } - -+static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size) -+{ -+ BUG_ON(size > 4); -+ -+ if (user_mode(ctxt->regs)) { -+ struct thread_struct *t = ¤t->thread; -+ struct io_bitmap *iobm = t->io_bitmap; -+ size_t idx; -+ -+ if (!iobm) -+ goto fault; -+ -+ for (idx = port; idx < port + size; ++idx) { -+ if (test_bit(idx, iobm->bitmap)) -+ goto fault; -+ } -+ } -+ -+ return ES_OK; -+ -+fault: -+ ctxt->fi.vector = X86_TRAP_GP; -+ ctxt->fi.error_code = 0; -+ -+ return ES_EXCEPTION; -+} -+ - /* Include code shared with pre-decompression boot stage */ - #include "sev-shared.c" - -@@ -1552,6 +1579,9 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) - return ES_DECODE_FAILED; - } - -+ if (user_mode(ctxt->regs)) -+ return ES_UNSUPPORTED; -+ - switch (mmio) { - case MMIO_WRITE: - memcpy(ghcb->shared_buffer, reg_data, bytes); -diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c -index 7b4224f5ee2de..c3ef1fc602bf9 100644 ---- a/arch/x86/kvm/cpuid.c -+++ b/arch/x86/kvm/cpuid.c -@@ -338,14 +338,6 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) - vcpu->arch.guest_supported_xcr0 = - cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent); - -- /* -- * FP+SSE can always be saved/restored via KVM_{G,S}ET_XSAVE, even if -- * XSAVE/XCRO are not exposed to the guest, and even if XSAVE isn't -- * supported by the host. -- */ -- vcpu->arch.guest_fpu.fpstate->user_xfeatures = vcpu->arch.guest_supported_xcr0 | -- XFEATURE_MASK_FPSSE; -- - kvm_update_pv_runtime(vcpu); - - vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); -diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c -index 68eba393842f5..7e8dbd54869a6 100644 ---- a/arch/x86/kvm/lapic.c -+++ b/arch/x86/kvm/lapic.c -@@ -2535,13 +2535,17 @@ int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type) - { - u32 reg = kvm_lapic_get_reg(apic, lvt_type); - int vector, mode, trig_mode; -+ int r; - - if (kvm_apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) { - vector = reg & APIC_VECTOR_MASK; - mode = reg & APIC_MODE_MASK; - trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; -- return __apic_accept_irq(apic, mode, vector, 1, trig_mode, -- NULL); -+ -+ r = __apic_accept_irq(apic, mode, vector, 1, trig_mode, NULL); -+ if (r && lvt_type == APIC_LVTPC) -+ kvm_lapic_set_reg(apic, APIC_LVTPC, reg | APIC_LVT_MASKED); -+ return r; - } - return 0; - } -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 2a6fec4e2d196..d30325e297a03 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -5994,19 +5994,16 @@ static void kvm_mmu_invalidate_zap_pages_in_memslot(struct kvm *kvm, - kvm_mmu_zap_all_fast(kvm); - } - --int kvm_mmu_init_vm(struct kvm *kvm) -+void kvm_mmu_init_vm(struct kvm *kvm) - { - struct kvm_page_track_notifier_node *node = &kvm->arch.mmu_sp_tracker; -- int r; - - INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); - INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); - INIT_LIST_HEAD(&kvm->arch.lpage_disallowed_mmu_pages); - spin_lock_init(&kvm->arch.mmu_unsync_pages_lock); - -- r = kvm_mmu_init_tdp_mmu(kvm); -- if (r < 0) -- return r; -+ kvm_mmu_init_tdp_mmu(kvm); - - node->track_write = kvm_mmu_pte_write; - node->track_flush_slot = kvm_mmu_invalidate_zap_pages_in_memslot; -@@ -6019,8 +6016,6 @@ int kvm_mmu_init_vm(struct kvm *kvm) - - kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache; - kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO; -- -- return 0; - } - - static void mmu_free_vm_memory_caches(struct kvm *kvm) -diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h -index 582def531d4d9..0a9d5f2925c33 100644 ---- a/arch/x86/kvm/mmu/mmu_internal.h -+++ b/arch/x86/kvm/mmu/mmu_internal.h -@@ -56,7 +56,12 @@ struct kvm_mmu_page { - - bool tdp_mmu_page; - bool unsync; -- u8 mmu_valid_gen; -+ union { -+ u8 mmu_valid_gen; -+ -+ /* Only accessed under slots_lock. */ -+ bool tdp_mmu_scheduled_root_to_zap; -+ }; - bool lpage_disallowed; /* Can't be replaced by an equiv large page */ - - /* -@@ -92,13 +97,7 @@ struct kvm_mmu_page { - struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */ - tdp_ptep_t ptep; - }; -- union { -- DECLARE_BITMAP(unsync_child_bitmap, 512); -- struct { -- struct work_struct tdp_mmu_async_work; -- void *tdp_mmu_async_data; -- }; -- }; -+ DECLARE_BITMAP(unsync_child_bitmap, 512); - - struct list_head lpage_disallowed_link; - #ifdef CONFIG_X86_32 -diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c -index 9b9fc4e834d09..c3b0f973375b4 100644 ---- a/arch/x86/kvm/mmu/tdp_mmu.c -+++ b/arch/x86/kvm/mmu/tdp_mmu.c -@@ -14,24 +14,16 @@ static bool __read_mostly tdp_mmu_enabled = true; - module_param_named(tdp_mmu, tdp_mmu_enabled, bool, 0644); - - /* Initializes the TDP MMU for the VM, if enabled. */ --int kvm_mmu_init_tdp_mmu(struct kvm *kvm) -+void kvm_mmu_init_tdp_mmu(struct kvm *kvm) - { -- struct workqueue_struct *wq; -- - if (!tdp_enabled || !READ_ONCE(tdp_mmu_enabled)) -- return 0; -- -- wq = alloc_workqueue("kvm", WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_CPU_INTENSIVE, 0); -- if (!wq) -- return -ENOMEM; -+ return; - - /* This should not be changed for the lifetime of the VM. */ - kvm->arch.tdp_mmu_enabled = true; - INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots); - spin_lock_init(&kvm->arch.tdp_mmu_pages_lock); - INIT_LIST_HEAD(&kvm->arch.tdp_mmu_pages); -- kvm->arch.tdp_mmu_zap_wq = wq; -- return 1; - } - - /* Arbitrarily returns true so that this may be used in if statements. */ -@@ -57,20 +49,15 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) - * ultimately frees all roots. - */ - kvm_tdp_mmu_invalidate_all_roots(kvm); -- -- /* -- * Destroying a workqueue also first flushes the workqueue, i.e. no -- * need to invoke kvm_tdp_mmu_zap_invalidated_roots(). -- */ -- destroy_workqueue(kvm->arch.tdp_mmu_zap_wq); -+ kvm_tdp_mmu_zap_invalidated_roots(kvm); - - WARN_ON(!list_empty(&kvm->arch.tdp_mmu_pages)); - WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); - - /* - * Ensure that all the outstanding RCU callbacks to free shadow pages -- * can run before the VM is torn down. Work items on tdp_mmu_zap_wq -- * can call kvm_tdp_mmu_put_root and create new callbacks. -+ * can run before the VM is torn down. Putting the last reference to -+ * zapped roots will create new callbacks. - */ - rcu_barrier(); - } -@@ -97,46 +84,6 @@ static void tdp_mmu_free_sp_rcu_callback(struct rcu_head *head) - tdp_mmu_free_sp(sp); - } - --static void tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root, -- bool shared); -- --static void tdp_mmu_zap_root_work(struct work_struct *work) --{ -- struct kvm_mmu_page *root = container_of(work, struct kvm_mmu_page, -- tdp_mmu_async_work); -- struct kvm *kvm = root->tdp_mmu_async_data; -- -- read_lock(&kvm->mmu_lock); -- -- /* -- * A TLB flush is not necessary as KVM performs a local TLB flush when -- * allocating a new root (see kvm_mmu_load()), and when migrating vCPU -- * to a different pCPU. Note, the local TLB flush on reuse also -- * invalidates any paging-structure-cache entries, i.e. TLB entries for -- * intermediate paging structures, that may be zapped, as such entries -- * are associated with the ASID on both VMX and SVM. -- */ -- tdp_mmu_zap_root(kvm, root, true); -- -- /* -- * Drop the refcount using kvm_tdp_mmu_put_root() to test its logic for -- * avoiding an infinite loop. By design, the root is reachable while -- * it's being asynchronously zapped, thus a different task can put its -- * last reference, i.e. flowing through kvm_tdp_mmu_put_root() for an -- * asynchronously zapped root is unavoidable. -- */ -- kvm_tdp_mmu_put_root(kvm, root, true); -- -- read_unlock(&kvm->mmu_lock); --} -- --static void tdp_mmu_schedule_zap_root(struct kvm *kvm, struct kvm_mmu_page *root) --{ -- root->tdp_mmu_async_data = kvm; -- INIT_WORK(&root->tdp_mmu_async_work, tdp_mmu_zap_root_work); -- queue_work(kvm->arch.tdp_mmu_zap_wq, &root->tdp_mmu_async_work); --} -- - void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, - bool shared) - { -@@ -222,11 +169,11 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, - #define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \ - __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true) - --#define for_each_tdp_mmu_root_yield_safe(_kvm, _root) \ -- for (_root = tdp_mmu_next_root(_kvm, NULL, false, false); \ -+#define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _shared) \ -+ for (_root = tdp_mmu_next_root(_kvm, NULL, _shared, false); \ - _root; \ -- _root = tdp_mmu_next_root(_kvm, _root, false, false)) \ -- if (!kvm_lockdep_assert_mmu_lock_held(_kvm, false)) { \ -+ _root = tdp_mmu_next_root(_kvm, _root, _shared, false)) \ -+ if (!kvm_lockdep_assert_mmu_lock_held(_kvm, _shared)) { \ - } else - - /* -@@ -305,7 +252,7 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu) - * by a memslot update or by the destruction of the VM. Initialize the - * refcount to two; one reference for the vCPU, and one reference for - * the TDP MMU itself, which is held until the root is invalidated and -- * is ultimately put by tdp_mmu_zap_root_work(). -+ * is ultimately put by kvm_tdp_mmu_zap_invalidated_roots(). - */ - refcount_set(&root->tdp_mmu_root_count, 2); - -@@ -963,7 +910,7 @@ bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush) - { - struct kvm_mmu_page *root; - -- for_each_tdp_mmu_root_yield_safe(kvm, root) -+ for_each_tdp_mmu_root_yield_safe(kvm, root, false) - flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush); - - return flush; -@@ -985,7 +932,7 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) - * is being destroyed or the userspace VMM has exited. In both cases, - * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request. - */ -- for_each_tdp_mmu_root_yield_safe(kvm, root) -+ for_each_tdp_mmu_root_yield_safe(kvm, root, false) - tdp_mmu_zap_root(kvm, root, false); - } - -@@ -995,18 +942,47 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) - */ - void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm) - { -- flush_workqueue(kvm->arch.tdp_mmu_zap_wq); -+ struct kvm_mmu_page *root; -+ -+ read_lock(&kvm->mmu_lock); -+ -+ for_each_tdp_mmu_root_yield_safe(kvm, root, true) { -+ if (!root->tdp_mmu_scheduled_root_to_zap) -+ continue; -+ -+ root->tdp_mmu_scheduled_root_to_zap = false; -+ KVM_BUG_ON(!root->role.invalid, kvm); -+ -+ /* -+ * A TLB flush is not necessary as KVM performs a local TLB -+ * flush when allocating a new root (see kvm_mmu_load()), and -+ * when migrating a vCPU to a different pCPU. Note, the local -+ * TLB flush on reuse also invalidates paging-structure-cache -+ * entries, i.e. TLB entries for intermediate paging structures, -+ * that may be zapped, as such entries are associated with the -+ * ASID on both VMX and SVM. -+ */ -+ tdp_mmu_zap_root(kvm, root, true); -+ -+ /* -+ * The referenced needs to be put *after* zapping the root, as -+ * the root must be reachable by mmu_notifiers while it's being -+ * zapped -+ */ -+ kvm_tdp_mmu_put_root(kvm, root, true); -+ } -+ -+ read_unlock(&kvm->mmu_lock); - } - - /* - * Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that - * is about to be zapped, e.g. in response to a memslots update. The actual -- * zapping is performed asynchronously. Using a separate workqueue makes it -- * easy to ensure that the destruction is performed before the "fast zap" -- * completes, without keeping a separate list of invalidated roots; the list is -- * effectively the list of work items in the workqueue. -+ * zapping is done separately so that it happens with mmu_lock with read, -+ * whereas invalidating roots must be done with mmu_lock held for write (unless -+ * the VM is being destroyed). - * -- * Note, the asynchronous worker is gifted the TDP MMU's reference. -+ * Note, kvm_tdp_mmu_zap_invalidated_roots() is gifted the TDP MMU's reference. - * See kvm_tdp_mmu_get_vcpu_root_hpa(). - */ - void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) -@@ -1031,19 +1007,20 @@ void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) - /* - * As above, mmu_lock isn't held when destroying the VM! There can't - * be other references to @kvm, i.e. nothing else can invalidate roots -- * or be consuming roots, but walking the list of roots does need to be -- * guarded against roots being deleted by the asynchronous zap worker. -+ * or get/put references to roots. - */ -- rcu_read_lock(); -- -- list_for_each_entry_rcu(root, &kvm->arch.tdp_mmu_roots, link) { -+ list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) { -+ /* -+ * Note, invalid roots can outlive a memslot update! Invalid -+ * roots must be *zapped* before the memslot update completes, -+ * but a different task can acquire a reference and keep the -+ * root alive after its been zapped. -+ */ - if (!root->role.invalid) { -+ root->tdp_mmu_scheduled_root_to_zap = true; - root->role.invalid = true; -- tdp_mmu_schedule_zap_root(kvm, root); - } - } -- -- rcu_read_unlock(); - } - - /* -diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h -index d0a9fe0770fdd..c82a8bb321bb9 100644 ---- a/arch/x86/kvm/mmu/tdp_mmu.h -+++ b/arch/x86/kvm/mmu/tdp_mmu.h -@@ -65,7 +65,7 @@ u64 *kvm_tdp_mmu_fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, u64 addr, - u64 *spte); - - #ifdef CONFIG_X86_64 --int kvm_mmu_init_tdp_mmu(struct kvm *kvm); -+void kvm_mmu_init_tdp_mmu(struct kvm *kvm); - void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm); - static inline bool is_tdp_mmu_page(struct kvm_mmu_page *sp) { return sp->tdp_mmu_page; } - -@@ -86,7 +86,7 @@ static inline bool is_tdp_mmu(struct kvm_mmu *mmu) - return sp && is_tdp_mmu_page(sp) && sp->root_count; - } - #else --static inline int kvm_mmu_init_tdp_mmu(struct kvm *kvm) { return 0; } -+static inline void kvm_mmu_init_tdp_mmu(struct kvm *kvm) {} - static inline void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) {} - static inline bool is_tdp_mmu_page(struct kvm_mmu_page *sp) { return false; } - static inline bool is_tdp_mmu(struct kvm_mmu *mmu) { return false; } -diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c -index d3e66740c7c68..fb125b54ee680 100644 ---- a/arch/x86/kvm/svm/avic.c -+++ b/arch/x86/kvm/svm/avic.c -@@ -542,8 +542,11 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu) - case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE: - WARN_ONCE(1, "Invalid backing page\n"); - break; -+ case AVIC_IPI_FAILURE_INVALID_IPI_VECTOR: -+ /* Invalid IPI with vector < 16 */ -+ break; - default: -- pr_err("Unknown IPI interception\n"); -+ vcpu_unimpl(vcpu, "Unknown avic incomplete IPI interception\n"); - } - - return 1; -diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c -index 8053974af326c..bc288e6bde642 100644 ---- a/arch/x86/kvm/svm/nested.c -+++ b/arch/x86/kvm/svm/nested.c -@@ -1164,6 +1164,9 @@ void svm_leave_nested(struct kvm_vcpu *vcpu) - - nested_svm_uninit_mmu_context(vcpu); - vmcb_mark_all_dirty(svm->vmcb); -+ -+ if (kvm_apicv_activated(vcpu->kvm)) -+ kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu); - } - - kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 1931d3fcbbe09..4d6baae1ae748 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -5301,26 +5301,37 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, - return 0; - } - --static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, -- struct kvm_xsave *guest_xsave) --{ -- if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) -- return; -- -- fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, -- guest_xsave->region, -- sizeof(guest_xsave->region), -- vcpu->arch.pkru); --} - - static void kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu, - u8 *state, unsigned int size) - { -+ /* -+ * Only copy state for features that are enabled for the guest. The -+ * state itself isn't problematic, but setting bits in the header for -+ * features that are supported in *this* host but not exposed to the -+ * guest can result in KVM_SET_XSAVE failing when live migrating to a -+ * compatible host without the features that are NOT exposed to the -+ * guest. -+ * -+ * FP+SSE can always be saved/restored via KVM_{G,S}ET_XSAVE, even if -+ * XSAVE/XCRO are not exposed to the guest, and even if XSAVE isn't -+ * supported by the host. -+ */ -+ u64 supported_xcr0 = vcpu->arch.guest_supported_xcr0 | -+ XFEATURE_MASK_FPSSE; -+ - if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) - return; - -- fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, -- state, size, vcpu->arch.pkru); -+ fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, state, size, -+ supported_xcr0, vcpu->arch.pkru); -+} -+ -+static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, -+ struct kvm_xsave *guest_xsave) -+{ -+ return kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region, -+ sizeof(guest_xsave->region)); - } - - static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, -@@ -12442,9 +12453,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) - if (ret) - goto out; - -- ret = kvm_mmu_init_vm(kvm); -- if (ret) -- goto out_page_track; -+ kvm_mmu_init_vm(kvm); - - ret = static_call(kvm_x86_vm_init)(kvm); - if (ret) -@@ -12489,7 +12498,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) - - out_uninit_mmu: - kvm_mmu_uninit_vm(kvm); --out_page_track: - kvm_page_track_cleanup(kvm); - out: - return ret; -diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c -index c2c786eb95abc..1687483ff319e 100644 ---- a/drivers/acpi/irq.c -+++ b/drivers/acpi/irq.c -@@ -57,6 +57,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, - int polarity) - { - struct irq_fwspec fwspec; -+ unsigned int irq; - - fwspec.fwnode = acpi_get_gsi_domain_id(gsi); - if (WARN_ON(!fwspec.fwnode)) { -@@ -68,7 +69,11 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, - fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); - fwspec.param_count = 2; - -- return irq_create_fwspec_mapping(&fwspec); -+ irq = irq_create_fwspec_mapping(&fwspec); -+ if (!irq) -+ return -EINVAL; -+ -+ return irq; - } - EXPORT_SYMBOL_GPL(acpi_register_gsi); - -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index fbc231a3f7951..fa2fc1953fc26 100644 ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -2456,7 +2456,7 @@ static int ata_dev_config_lba(struct ata_device *dev) - { - const u16 *id = dev->id; - const char *lba_desc; -- char ncq_desc[24]; -+ char ncq_desc[32]; - int ret; - - dev->flags |= ATA_DFLAG_LBA; -diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c -index 2a04dd36a4948..1eaaf01418ea7 100644 ---- a/drivers/ata/libata-eh.c -+++ b/drivers/ata/libata-eh.c -@@ -2247,7 +2247,7 @@ static void ata_eh_link_report(struct ata_link *link) - struct ata_eh_context *ehc = &link->eh_context; - struct ata_queued_cmd *qc; - const char *frozen, *desc; -- char tries_buf[6] = ""; -+ char tries_buf[16] = ""; - int tag, nr_failed = 0; - - if (ehc->i.flags & ATA_EHI_QUIET) -diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c -index 7de1f27d0323d..df1f78abdf266 100644 ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -1572,7 +1572,7 @@ static int dev_get_regmap_match(struct device *dev, void *res, void *data) - - /* If the user didn't specify a name match any */ - if (data) -- return !strcmp((*r)->name, data); -+ return (*r)->name && !strcmp((*r)->name, data); - else - return 1; - } -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index f2062c2a28da8..96d4f48e36011 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -3984,6 +3984,7 @@ static int btusb_probe(struct usb_interface *intf, - - if (id->driver_info & BTUSB_QCA_ROME) { - data->setup_on_usb = btusb_setup_qca; -+ hdev->shutdown = btusb_shutdown_qca; - hdev->set_bdaddr = btusb_set_bdaddr_ath3012; - hdev->cmd_timeout = btusb_qca_cmd_timeout; - set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); -diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c -index c443c3b0a4da5..4415d850d698b 100644 ---- a/drivers/bluetooth/hci_vhci.c -+++ b/drivers/bluetooth/hci_vhci.c -@@ -74,7 +74,10 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) - struct vhci_data *data = hci_get_drvdata(hdev); - - memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); -+ -+ mutex_lock(&data->open_mutex); - skb_queue_tail(&data->readq, skb); -+ mutex_unlock(&data->open_mutex); - - wake_up_interruptible(&data->read_wait); - return 0; -diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c -index de14949a3fe5a..92c1f2baa4bff 100644 ---- a/drivers/gpio/gpio-timberdale.c -+++ b/drivers/gpio/gpio-timberdale.c -@@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, - unsigned offset, bool enabled) - { - struct timbgpio *tgpio = gpiochip_get_data(gpio); -+ unsigned long flags; - u32 reg; - -- spin_lock(&tgpio->lock); -+ spin_lock_irqsave(&tgpio->lock, flags); - reg = ioread32(tgpio->membase + offset); - - if (enabled) -@@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, - reg &= ~(1 << index); - - iowrite32(reg, tgpio->membase + offset); -- spin_unlock(&tgpio->lock); -+ spin_unlock_irqrestore(&tgpio->lock, flags); - - return 0; - } -diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c -index a429176673e7a..314dfaa633857 100644 ---- a/drivers/gpio/gpio-vf610.c -+++ b/drivers/gpio/gpio-vf610.c -@@ -30,7 +30,6 @@ struct fsl_gpio_soc_data { - - struct vf610_gpio_port { - struct gpio_chip gc; -- struct irq_chip ic; - void __iomem *base; - void __iomem *gpio_base; - const struct fsl_gpio_soc_data *sdata; -@@ -128,14 +127,14 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, - unsigned long mask = BIT(gpio); - u32 val; - -+ vf610_gpio_set(chip, gpio, value); -+ - if (port->sdata && port->sdata->have_paddr) { - val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR); - val |= mask; - vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR); - } - -- vf610_gpio_set(chip, gpio, value); -- - return pinctrl_gpio_direction_output(chip->base + gpio); - } - -@@ -207,20 +206,24 @@ static int vf610_gpio_irq_set_type(struct irq_data *d, u32 type) - - static void vf610_gpio_irq_mask(struct irq_data *d) - { -- struct vf610_gpio_port *port = -- gpiochip_get_data(irq_data_get_irq_chip_data(d)); -- void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq); -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -+ struct vf610_gpio_port *port = gpiochip_get_data(gc); -+ irq_hw_number_t gpio_num = irqd_to_hwirq(d); -+ void __iomem *pcr_base = port->base + PORT_PCR(gpio_num); - - vf610_gpio_writel(0, pcr_base); -+ gpiochip_disable_irq(gc, gpio_num); - } - - static void vf610_gpio_irq_unmask(struct irq_data *d) - { -- struct vf610_gpio_port *port = -- gpiochip_get_data(irq_data_get_irq_chip_data(d)); -- void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq); -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -+ struct vf610_gpio_port *port = gpiochip_get_data(gc); -+ irq_hw_number_t gpio_num = irqd_to_hwirq(d); -+ void __iomem *pcr_base = port->base + PORT_PCR(gpio_num); - -- vf610_gpio_writel(port->irqc[d->hwirq] << PORT_PCR_IRQC_OFFSET, -+ gpiochip_enable_irq(gc, gpio_num); -+ vf610_gpio_writel(port->irqc[gpio_num] << PORT_PCR_IRQC_OFFSET, - pcr_base); - } - -@@ -237,6 +240,18 @@ static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable) - return 0; - } - -+static const struct irq_chip vf610_irqchip = { -+ .name = "gpio-vf610", -+ .irq_ack = vf610_gpio_irq_ack, -+ .irq_mask = vf610_gpio_irq_mask, -+ .irq_unmask = vf610_gpio_irq_unmask, -+ .irq_set_type = vf610_gpio_irq_set_type, -+ .irq_set_wake = vf610_gpio_irq_set_wake, -+ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND -+ | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND, -+ GPIOCHIP_IRQ_RESOURCE_HELPERS, -+}; -+ - static void vf610_gpio_disable_clk(void *data) - { - clk_disable_unprepare(data); -@@ -249,7 +264,6 @@ static int vf610_gpio_probe(struct platform_device *pdev) - struct vf610_gpio_port *port; - struct gpio_chip *gc; - struct gpio_irq_chip *girq; -- struct irq_chip *ic; - int i; - int ret; - -@@ -315,14 +329,6 @@ static int vf610_gpio_probe(struct platform_device *pdev) - gc->direction_output = vf610_gpio_direction_output; - gc->set = vf610_gpio_set; - -- ic = &port->ic; -- ic->name = "gpio-vf610"; -- ic->irq_ack = vf610_gpio_irq_ack; -- ic->irq_mask = vf610_gpio_irq_mask; -- ic->irq_unmask = vf610_gpio_irq_unmask; -- ic->irq_set_type = vf610_gpio_irq_set_type; -- ic->irq_set_wake = vf610_gpio_irq_set_wake; -- - /* Mask all GPIO interrupts */ - for (i = 0; i < gc->ngpio; i++) - vf610_gpio_writel(0, port->base + PORT_PCR(i)); -@@ -331,7 +337,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) - vf610_gpio_writel(~0, port->base + PORT_ISFR); - - girq = &gc->irq; -- girq->chip = ic; -+ gpio_irq_chip_set_chip(girq, &vf610_irqchip); - girq->parent_handler = vf610_gpio_irq_handler; - girq->num_parents = 1; - girq->parents = devm_kcalloc(&pdev->dev, 1, -diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c -index 8472013ff38a2..0e78437c8389d 100644 ---- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c -+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c -@@ -1991,6 +1991,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 1): - case IP_VERSION(11, 0, 2): -+ case IP_VERSION(11, 0, 3): - *states = ATTR_STATE_SUPPORTED; - break; - default: -diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -index b89f7f7ca1885..1b5c27ed27370 100644 ---- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c -+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -@@ -673,7 +673,7 @@ static struct ti_sn65dsi86 *bridge_to_ti_sn65dsi86(struct drm_bridge *bridge) - return container_of(bridge, struct ti_sn65dsi86, bridge); - } - --static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) -+static int ti_sn_attach_host(struct auxiliary_device *adev, struct ti_sn65dsi86 *pdata) - { - int val; - struct mipi_dsi_host *host; -@@ -688,7 +688,7 @@ static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) - if (!host) - return -EPROBE_DEFER; - -- dsi = devm_mipi_dsi_device_register_full(dev, host, &info); -+ dsi = devm_mipi_dsi_device_register_full(&adev->dev, host, &info); - if (IS_ERR(dsi)) - return PTR_ERR(dsi); - -@@ -706,7 +706,7 @@ static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) - - pdata->dsi = dsi; - -- return devm_mipi_dsi_attach(dev, dsi); -+ return devm_mipi_dsi_attach(&adev->dev, dsi); - } - - static int ti_sn_bridge_attach(struct drm_bridge *bridge, -@@ -1279,9 +1279,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, - struct device_node *np = pdata->dev->of_node; - int ret; - -- pdata->next_bridge = devm_drm_of_get_bridge(pdata->dev, np, 1, 0); -+ pdata->next_bridge = devm_drm_of_get_bridge(&adev->dev, np, 1, 0); - if (IS_ERR(pdata->next_bridge)) -- return dev_err_probe(pdata->dev, PTR_ERR(pdata->next_bridge), -+ return dev_err_probe(&adev->dev, PTR_ERR(pdata->next_bridge), - "failed to create panel bridge\n"); - - ti_sn_bridge_parse_lanes(pdata, np); -@@ -1300,9 +1300,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, - - drm_bridge_add(&pdata->bridge); - -- ret = ti_sn_attach_host(pdata); -+ ret = ti_sn_attach_host(adev, pdata); - if (ret) { -- dev_err_probe(pdata->dev, ret, "failed to attach dsi host\n"); -+ dev_err_probe(&adev->dev, ret, "failed to attach dsi host\n"); - goto err_remove_bridge; - } - -diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c -index 0cb646cb04ee1..d5c15292ae937 100644 ---- a/drivers/gpu/drm/drm_panel_orientation_quirks.c -+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c -@@ -38,6 +38,14 @@ static const struct drm_dmi_panel_orientation_data gpd_micropc = { - .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, - }; - -+static const struct drm_dmi_panel_orientation_data gpd_onemix2s = { -+ .width = 1200, -+ .height = 1920, -+ .bios_dates = (const char * const []){ "05/21/2018", "10/26/2018", -+ "03/04/2019", NULL }, -+ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -+}; -+ - static const struct drm_dmi_panel_orientation_data gpd_pocket = { - .width = 1200, - .height = 1920, -@@ -401,6 +409,14 @@ static const struct dmi_system_id orientation_data[] = { - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), - }, - .driver_data = (void *)&lcd800x1280_rightside_up, -+ }, { /* One Mix 2S (generic strings, also match on bios date) */ -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), -+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), -+ }, -+ .driver_data = (void *)&gpd_onemix2s, - }, - {} - }; -diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c -index d445e2d63c9c8..d7e30d889a5ca 100644 ---- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c -+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c -@@ -235,6 +235,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err) - case 0: - case -EAGAIN: - case -ENOSPC: /* transient failure to evict? */ -+ case -ENOBUFS: /* temporarily out of fences? */ - case -ERESTARTSYS: - case -EINTR: - case -EBUSY: -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c -index 1d0374a577a5e..fb4f0e336b60e 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c -@@ -234,6 +234,7 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) - npages = obj->size >> PAGE_SHIFT; - mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL); - if (!mtk_gem->pages) { -+ sg_free_table(sgt); - kfree(sgt); - return -ENOMEM; - } -@@ -243,12 +244,15 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) - mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, - pgprot_writecombine(PAGE_KERNEL)); - if (!mtk_gem->kvaddr) { -+ sg_free_table(sgt); - kfree(sgt); - kfree(mtk_gem->pages); - return -ENOMEM; - } --out: -+ sg_free_table(sgt); - kfree(sgt); -+ -+out: - iosys_map_set_vaddr(map, mtk_gem->kvaddr); - - return 0; -diff --git a/drivers/hid/.kunitconfig b/drivers/hid/.kunitconfig -index 04daeff5c970e..675a8209c7aeb 100644 ---- a/drivers/hid/.kunitconfig -+++ b/drivers/hid/.kunitconfig -@@ -1,5 +1,6 @@ - CONFIG_KUNIT=y - CONFIG_USB=y - CONFIG_USB_HID=y -+CONFIG_HID_BATTERY_STRENGTH=y - CONFIG_HID_UCLOGIC=y - CONFIG_HID_KUNIT_TEST=y -diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig -index c1873ccc7248d..9ad5e43d9961b 100644 ---- a/drivers/hid/Kconfig -+++ b/drivers/hid/Kconfig -@@ -1263,6 +1263,7 @@ config HID_MCP2221 - config HID_KUNIT_TEST - tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS - depends on KUNIT -+ depends on HID_BATTERY_STRENGTH - depends on HID_UCLOGIC - default KUNIT_ALL_TESTS - help -diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c -index 403506b9697e7..b346d68a06f5a 100644 ---- a/drivers/hid/hid-holtek-kbd.c -+++ b/drivers/hid/hid-holtek-kbd.c -@@ -130,6 +130,10 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type, - return -ENODEV; - - boot_hid = usb_get_intfdata(boot_interface); -+ if (list_empty(&boot_hid->inputs)) { -+ hid_err(hid, "no inputs found\n"); -+ return -ENODEV; -+ } - boot_hid_input = list_first_entry(&boot_hid->inputs, - struct hid_input, list); - -diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c -new file mode 100644 -index 0000000000000..77c2d45ac62a7 ---- /dev/null -+++ b/drivers/hid/hid-input-test.c -@@ -0,0 +1,80 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * HID to Linux Input mapping -+ * -+ * Copyright (c) 2022 José Expósito -+ */ -+ -+#include -+ -+static void hid_test_input_set_battery_charge_status(struct kunit *test) -+{ -+ struct hid_device *dev; -+ bool handled; -+ -+ dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); -+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); -+ -+ handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0); -+ KUNIT_EXPECT_FALSE(test, handled); -+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN); -+ -+ handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0); -+ KUNIT_EXPECT_TRUE(test, handled); -+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING); -+ -+ handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1); -+ KUNIT_EXPECT_TRUE(test, handled); -+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING); -+} -+ -+static void hid_test_input_get_battery_property(struct kunit *test) -+{ -+ struct power_supply *psy; -+ struct hid_device *dev; -+ union power_supply_propval val; -+ int ret; -+ -+ dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); -+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); -+ dev->battery_avoid_query = true; -+ -+ psy = kunit_kzalloc(test, sizeof(*psy), GFP_KERNEL); -+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, psy); -+ psy->drv_data = dev; -+ -+ dev->battery_status = HID_BATTERY_UNKNOWN; -+ dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; -+ ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); -+ KUNIT_EXPECT_EQ(test, ret, 0); -+ KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_UNKNOWN); -+ -+ dev->battery_status = HID_BATTERY_REPORTED; -+ dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; -+ ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); -+ KUNIT_EXPECT_EQ(test, ret, 0); -+ KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_CHARGING); -+ -+ dev->battery_status = HID_BATTERY_REPORTED; -+ dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; -+ ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); -+ KUNIT_EXPECT_EQ(test, ret, 0); -+ KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_DISCHARGING); -+} -+ -+static struct kunit_case hid_input_tests[] = { -+ KUNIT_CASE(hid_test_input_set_battery_charge_status), -+ KUNIT_CASE(hid_test_input_get_battery_property), -+ { } -+}; -+ -+static struct kunit_suite hid_input_test_suite = { -+ .name = "hid_input", -+ .test_cases = hid_input_tests, -+}; -+ -+kunit_test_suite(hid_input_test_suite); -+ -+MODULE_DESCRIPTION("HID input KUnit tests"); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("José Expósito "); -diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c -index 77ee5e01e6111..4ba5df3c1e039 100644 ---- a/drivers/hid/hid-input.c -+++ b/drivers/hid/hid-input.c -@@ -492,7 +492,7 @@ static int hidinput_get_battery_property(struct power_supply *psy, - if (dev->battery_status == HID_BATTERY_UNKNOWN) - val->intval = POWER_SUPPLY_STATUS_UNKNOWN; - else -- val->intval = POWER_SUPPLY_STATUS_DISCHARGING; -+ val->intval = dev->battery_charge_status; - break; - - case POWER_SUPPLY_PROP_SCOPE: -@@ -560,6 +560,7 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, - dev->battery_max = max; - dev->battery_report_type = report_type; - dev->battery_report_id = field->report->id; -+ dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; - - /* - * Stylus is normally not connected to the device and thus we -@@ -626,6 +627,20 @@ static void hidinput_update_battery(struct hid_device *dev, int value) - power_supply_changed(dev->battery); - } - } -+ -+static bool hidinput_set_battery_charge_status(struct hid_device *dev, -+ unsigned int usage, int value) -+{ -+ switch (usage) { -+ case HID_BAT_CHARGING: -+ dev->battery_charge_status = value ? -+ POWER_SUPPLY_STATUS_CHARGING : -+ POWER_SUPPLY_STATUS_DISCHARGING; -+ return true; -+ } -+ -+ return false; -+} - #else /* !CONFIG_HID_BATTERY_STRENGTH */ - static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, - struct hid_field *field, bool is_percentage) -@@ -640,6 +655,12 @@ static void hidinput_cleanup_battery(struct hid_device *dev) - static void hidinput_update_battery(struct hid_device *dev, int value) - { - } -+ -+static bool hidinput_set_battery_charge_status(struct hid_device *dev, -+ unsigned int usage, int value) -+{ -+ return false; -+} - #endif /* CONFIG_HID_BATTERY_STRENGTH */ - - static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field, -@@ -1239,6 +1260,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - hidinput_setup_battery(device, HID_INPUT_REPORT, field, true); - usage->type = EV_PWR; - return; -+ case HID_BAT_CHARGING: -+ usage->type = EV_PWR; -+ return; - } - goto unknown; - -@@ -1481,7 +1505,11 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct - return; - - if (usage->type == EV_PWR) { -- hidinput_update_battery(hid, value); -+ bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value); -+ -+ if (!handled) -+ hidinput_update_battery(hid, value); -+ - return; - } - -@@ -2346,3 +2374,7 @@ void hidinput_disconnect(struct hid_device *hid) - cancel_work_sync(&hid->led_work); - } - EXPORT_SYMBOL_GPL(hidinput_disconnect); -+ -+#ifdef CONFIG_HID_KUNIT_TEST -+#include "hid-input-test.c" -+#endif -diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c -index fb427391c3b86..8d0dad12b2d37 100644 ---- a/drivers/hid/hid-logitech-hidpp.c -+++ b/drivers/hid/hid-logitech-hidpp.c -@@ -4427,6 +4427,8 @@ static const struct hid_device_id hidpp_devices[] = { - HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb008) }, - { /* MX Master mouse over Bluetooth */ - HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012) }, -+ { /* M720 Triathlon mouse over Bluetooth */ -+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb015) }, - { /* MX Ergo trackball over Bluetooth */ - HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01d) }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e) }, -diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c -index 521b2ffb42449..8db4ae05febc8 100644 ---- a/drivers/hid/hid-multitouch.c -+++ b/drivers/hid/hid-multitouch.c -@@ -2144,6 +2144,10 @@ static const struct hid_device_id mt_devices[] = { - USB_DEVICE_ID_MTP_STM)}, - - /* Synaptics devices */ -+ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, -+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, -+ USB_VENDOR_ID_SYNAPTICS, 0xcd7e) }, -+ - { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_SYNAPTICS, 0xce08) }, -diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c -index 5bfc0c4504608..8a8a3dd8af0c1 100644 ---- a/drivers/hid/hid-nintendo.c -+++ b/drivers/hid/hid-nintendo.c -@@ -2011,7 +2011,9 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) - struct joycon_input_report *report; - - req.subcmd_id = JC_SUBCMD_REQ_DEV_INFO; -+ mutex_lock(&ctlr->output_mutex); - ret = joycon_send_subcmd(ctlr, &req, 0, HZ); -+ mutex_unlock(&ctlr->output_mutex); - if (ret) { - hid_err(ctlr->hdev, "Failed to get joycon info; ret=%d\n", ret); - return ret; -@@ -2040,6 +2042,85 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) - return 0; - } - -+static int joycon_init(struct hid_device *hdev) -+{ -+ struct joycon_ctlr *ctlr = hid_get_drvdata(hdev); -+ int ret = 0; -+ -+ mutex_lock(&ctlr->output_mutex); -+ /* if handshake command fails, assume ble pro controller */ -+ if ((jc_type_is_procon(ctlr) || jc_type_is_chrggrip(ctlr)) && -+ !joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ)) { -+ hid_dbg(hdev, "detected USB controller\n"); -+ /* set baudrate for improved latency */ -+ ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M, HZ); -+ if (ret) { -+ hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret); -+ goto out_unlock; -+ } -+ /* handshake */ -+ ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ); -+ if (ret) { -+ hid_err(hdev, "Failed handshake; ret=%d\n", ret); -+ goto out_unlock; -+ } -+ /* -+ * Set no timeout (to keep controller in USB mode). -+ * This doesn't send a response, so ignore the timeout. -+ */ -+ joycon_send_usb(ctlr, JC_USB_CMD_NO_TIMEOUT, HZ/10); -+ } else if (jc_type_is_chrggrip(ctlr)) { -+ hid_err(hdev, "Failed charging grip handshake\n"); -+ ret = -ETIMEDOUT; -+ goto out_unlock; -+ } -+ -+ /* get controller calibration data, and parse it */ -+ ret = joycon_request_calibration(ctlr); -+ if (ret) { -+ /* -+ * We can function with default calibration, but it may be -+ * inaccurate. Provide a warning, and continue on. -+ */ -+ hid_warn(hdev, "Analog stick positions may be inaccurate\n"); -+ } -+ -+ /* get IMU calibration data, and parse it */ -+ ret = joycon_request_imu_calibration(ctlr); -+ if (ret) { -+ /* -+ * We can function with default calibration, but it may be -+ * inaccurate. Provide a warning, and continue on. -+ */ -+ hid_warn(hdev, "Unable to read IMU calibration data\n"); -+ } -+ -+ /* Set the reporting mode to 0x30, which is the full report mode */ -+ ret = joycon_set_report_mode(ctlr); -+ if (ret) { -+ hid_err(hdev, "Failed to set report mode; ret=%d\n", ret); -+ goto out_unlock; -+ } -+ -+ /* Enable rumble */ -+ ret = joycon_enable_rumble(ctlr); -+ if (ret) { -+ hid_err(hdev, "Failed to enable rumble; ret=%d\n", ret); -+ goto out_unlock; -+ } -+ -+ /* Enable the IMU */ -+ ret = joycon_enable_imu(ctlr); -+ if (ret) { -+ hid_err(hdev, "Failed to enable the IMU; ret=%d\n", ret); -+ goto out_unlock; -+ } -+ -+out_unlock: -+ mutex_unlock(&ctlr->output_mutex); -+ return ret; -+} -+ - /* Common handler for parsing inputs */ - static int joycon_ctlr_read_handler(struct joycon_ctlr *ctlr, u8 *data, - int size) -@@ -2171,85 +2252,19 @@ static int nintendo_hid_probe(struct hid_device *hdev, - - hid_device_io_start(hdev); - -- /* Initialize the controller */ -- mutex_lock(&ctlr->output_mutex); -- /* if handshake command fails, assume ble pro controller */ -- if ((jc_type_is_procon(ctlr) || jc_type_is_chrggrip(ctlr)) && -- !joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ)) { -- hid_dbg(hdev, "detected USB controller\n"); -- /* set baudrate for improved latency */ -- ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M, HZ); -- if (ret) { -- hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret); -- goto err_mutex; -- } -- /* handshake */ -- ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ); -- if (ret) { -- hid_err(hdev, "Failed handshake; ret=%d\n", ret); -- goto err_mutex; -- } -- /* -- * Set no timeout (to keep controller in USB mode). -- * This doesn't send a response, so ignore the timeout. -- */ -- joycon_send_usb(ctlr, JC_USB_CMD_NO_TIMEOUT, HZ/10); -- } else if (jc_type_is_chrggrip(ctlr)) { -- hid_err(hdev, "Failed charging grip handshake\n"); -- ret = -ETIMEDOUT; -- goto err_mutex; -- } -- -- /* get controller calibration data, and parse it */ -- ret = joycon_request_calibration(ctlr); -+ ret = joycon_init(hdev); - if (ret) { -- /* -- * We can function with default calibration, but it may be -- * inaccurate. Provide a warning, and continue on. -- */ -- hid_warn(hdev, "Analog stick positions may be inaccurate\n"); -- } -- -- /* get IMU calibration data, and parse it */ -- ret = joycon_request_imu_calibration(ctlr); -- if (ret) { -- /* -- * We can function with default calibration, but it may be -- * inaccurate. Provide a warning, and continue on. -- */ -- hid_warn(hdev, "Unable to read IMU calibration data\n"); -- } -- -- /* Set the reporting mode to 0x30, which is the full report mode */ -- ret = joycon_set_report_mode(ctlr); -- if (ret) { -- hid_err(hdev, "Failed to set report mode; ret=%d\n", ret); -- goto err_mutex; -- } -- -- /* Enable rumble */ -- ret = joycon_enable_rumble(ctlr); -- if (ret) { -- hid_err(hdev, "Failed to enable rumble; ret=%d\n", ret); -- goto err_mutex; -- } -- -- /* Enable the IMU */ -- ret = joycon_enable_imu(ctlr); -- if (ret) { -- hid_err(hdev, "Failed to enable the IMU; ret=%d\n", ret); -- goto err_mutex; -+ hid_err(hdev, "Failed to initialize controller; ret=%d\n", ret); -+ goto err_close; - } - - ret = joycon_read_info(ctlr); - if (ret) { - hid_err(hdev, "Failed to retrieve controller info; ret=%d\n", - ret); -- goto err_mutex; -+ goto err_close; - } - -- mutex_unlock(&ctlr->output_mutex); -- - /* Initialize the leds */ - ret = joycon_leds_create(ctlr); - if (ret) { -@@ -2275,8 +2290,6 @@ static int nintendo_hid_probe(struct hid_device *hdev, - hid_dbg(hdev, "probe - success\n"); - return 0; - --err_mutex: -- mutex_unlock(&ctlr->output_mutex); - err_close: - hid_hw_close(hdev); - err_stop: -@@ -2306,6 +2319,20 @@ static void nintendo_hid_remove(struct hid_device *hdev) - hid_hw_stop(hdev); - } - -+#ifdef CONFIG_PM -+ -+static int nintendo_hid_resume(struct hid_device *hdev) -+{ -+ int ret = joycon_init(hdev); -+ -+ if (ret) -+ hid_err(hdev, "Failed to restore controller after resume"); -+ -+ return ret; -+} -+ -+#endif -+ - static const struct hid_device_id nintendo_hid_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, - USB_DEVICE_ID_NINTENDO_PROCON) }, -@@ -2327,6 +2354,10 @@ static struct hid_driver nintendo_hid_driver = { - .probe = nintendo_hid_probe, - .remove = nintendo_hid_remove, - .raw_event = nintendo_hid_event, -+ -+#ifdef CONFIG_PM -+ .resume = nintendo_hid_resume, -+#endif - }; - module_hid_driver(nintendo_hid_driver); - -diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c -index 313904be5f3bd..57ff09f18c371 100644 ---- a/drivers/i2c/i2c-mux.c -+++ b/drivers/i2c/i2c-mux.c -@@ -341,7 +341,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, - priv->adap.lock_ops = &i2c_parent_lock_ops; - - /* Sanity check on class */ -- if (i2c_mux_parent_classes(parent) & class) -+ if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED) - dev_err(&parent->dev, - "Segment %d behind mux can't share classes with ancestors\n", - chan_id); -diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c -index 80eff7090f14a..faf680140c178 100644 ---- a/drivers/iio/adc/ad7192.c -+++ b/drivers/iio/adc/ad7192.c -@@ -177,7 +177,7 @@ struct ad7192_chip_info { - struct ad7192_state { - const struct ad7192_chip_info *chip_info; - struct regulator *avdd; -- struct regulator *dvdd; -+ struct regulator *vref; - struct clk *mclk; - u16 int_vref_mv; - u32 fclk; -@@ -1011,24 +1011,34 @@ static int ad7192_probe(struct spi_device *spi) - if (ret) - return ret; - -- st->dvdd = devm_regulator_get(&spi->dev, "dvdd"); -- if (IS_ERR(st->dvdd)) -- return PTR_ERR(st->dvdd); -+ ret = devm_regulator_get_enable(&spi->dev, "dvdd"); -+ if (ret) -+ return dev_err_probe(&spi->dev, ret, "Failed to enable specified DVdd supply\n"); - -- ret = regulator_enable(st->dvdd); -- if (ret) { -- dev_err(&spi->dev, "Failed to enable specified DVdd supply\n"); -- return ret; -- } -+ st->vref = devm_regulator_get_optional(&spi->dev, "vref"); -+ if (IS_ERR(st->vref)) { -+ if (PTR_ERR(st->vref) != -ENODEV) -+ return PTR_ERR(st->vref); - -- ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->dvdd); -- if (ret) -- return ret; -+ ret = regulator_get_voltage(st->avdd); -+ if (ret < 0) -+ return dev_err_probe(&spi->dev, ret, -+ "Device tree error, AVdd voltage undefined\n"); -+ } else { -+ ret = regulator_enable(st->vref); -+ if (ret) { -+ dev_err(&spi->dev, "Failed to enable specified Vref supply\n"); -+ return ret; -+ } - -- ret = regulator_get_voltage(st->avdd); -- if (ret < 0) { -- dev_err(&spi->dev, "Device tree error, reference voltage undefined\n"); -- return ret; -+ ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->vref); -+ if (ret) -+ return ret; -+ -+ ret = regulator_get_voltage(st->vref); -+ if (ret < 0) -+ return dev_err_probe(&spi->dev, ret, -+ "Device tree error, Vref voltage undefined\n"); - } - st->int_vref_mv = ret / 1000; - -diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c -index d98f7e4d202c1..1ddce991fb3f4 100644 ---- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c -+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c -@@ -190,8 +190,11 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev, - /* - * Ignore samples if the buffer is not set: it is needed if the ODR is - * set but the buffer is not enabled yet. -+ * -+ * Note: iio_device_claim_buffer_mode() returns -EBUSY if the buffer -+ * is not enabled. - */ -- if (!iio_buffer_enabled(indio_dev)) -+ if (iio_device_claim_buffer_mode(indio_dev) < 0) - return 0; - - out = (s16 *)st->samples; -@@ -210,6 +213,7 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev, - iio_push_to_buffers_with_timestamp(indio_dev, st->samples, - timestamp + delta); - -+ iio_device_release_buffer_mode(indio_dev); - return 0; - } - EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data); -diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c -index f3f8392623a46..c9614982cb671 100644 ---- a/drivers/iio/industrialio-core.c -+++ b/drivers/iio/industrialio-core.c -@@ -2084,6 +2084,44 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev) - } - EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); - -+/** -+ * iio_device_claim_buffer_mode - Keep device in buffer mode -+ * @indio_dev: the iio_dev associated with the device -+ * -+ * If the device is in buffer mode it is guaranteed to stay -+ * that way until iio_device_release_buffer_mode() is called. -+ * -+ * Use with iio_device_release_buffer_mode(). -+ * -+ * Returns: 0 on success, -EBUSY on failure. -+ */ -+int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) -+{ -+ mutex_lock(&indio_dev->mlock); -+ -+ if (iio_buffer_enabled(indio_dev)) -+ return 0; -+ -+ mutex_unlock(&indio_dev->mlock); -+ return -EBUSY; -+} -+EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); -+ -+/** -+ * iio_device_release_buffer_mode - releases claim on buffer mode -+ * @indio_dev: the iio_dev associated with the device -+ * -+ * Release the claim. Device is no longer guaranteed to stay -+ * in buffer mode. -+ * -+ * Use with iio_device_claim_buffer_mode(). -+ */ -+void iio_device_release_buffer_mode(struct iio_dev *indio_dev) -+{ -+ mutex_unlock(&indio_dev->mlock); -+} -+EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); -+ - /** - * iio_device_get_current_mode() - helper function providing read-only access to - * the opaque @currentmode variable -diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -index 89cd48fcec79f..4a4bab9aa7263 100644 ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -104,7 +104,7 @@ static int mmc_decode_cid(struct mmc_card *card) - case 3: /* MMC v3.1 - v3.3 */ - case 4: /* MMC v4 */ - card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); -- card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); -+ card->cid.oemid = UNSTUFF_BITS(resp, 104, 8); - card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); - card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); - card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); -diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c -index f64b9ac76a5cd..5914516df2f7f 100644 ---- a/drivers/mmc/core/sdio.c -+++ b/drivers/mmc/core/sdio.c -@@ -1089,8 +1089,14 @@ static int mmc_sdio_resume(struct mmc_host *host) - } - err = mmc_sdio_reinit_card(host); - } else if (mmc_card_wake_sdio_irq(host)) { -- /* We may have switched to 1-bit mode during suspend */ -+ /* -+ * We may have switched to 1-bit mode during suspend, -+ * need to hold retuning, because tuning only supprt -+ * 4-bit mode or 8 bit mode. -+ */ -+ mmc_retune_hold_now(host); - err = sdio_enable_4bit_bus(host->card); -+ mmc_retune_release(host); - } - - if (err) -diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c -index 1a0d4dc24717c..70e414027155d 100644 ---- a/drivers/mmc/host/mtk-sd.c -+++ b/drivers/mmc/host/mtk-sd.c -@@ -655,11 +655,11 @@ static void msdc_reset_hw(struct msdc_host *host) - u32 val; - - sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); -- readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0); -+ readl_poll_timeout_atomic(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0); - - sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); -- readl_poll_timeout(host->base + MSDC_FIFOCS, val, -- !(val & MSDC_FIFOCS_CLR), 0, 0); -+ readl_poll_timeout_atomic(host->base + MSDC_FIFOCS, val, -+ !(val & MSDC_FIFOCS_CLR), 0, 0); - - val = readl(host->base + MSDC_INT); - writel(val, host->base + MSDC_INT); -diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c -index 4d509f6561887..c580ba089a261 100644 ---- a/drivers/mmc/host/sdhci-pci-gli.c -+++ b/drivers/mmc/host/sdhci-pci-gli.c -@@ -756,42 +756,6 @@ static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg) - return value; - } - --#ifdef CONFIG_PM_SLEEP --static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip) --{ -- struct sdhci_pci_slot *slot = chip->slots[0]; -- -- pci_free_irq_vectors(slot->chip->pdev); -- gli_pcie_enable_msi(slot); -- -- return sdhci_pci_resume_host(chip); --} -- --static int sdhci_cqhci_gli_resume(struct sdhci_pci_chip *chip) --{ -- struct sdhci_pci_slot *slot = chip->slots[0]; -- int ret; -- -- ret = sdhci_pci_gli_resume(chip); -- if (ret) -- return ret; -- -- return cqhci_resume(slot->host->mmc); --} -- --static int sdhci_cqhci_gli_suspend(struct sdhci_pci_chip *chip) --{ -- struct sdhci_pci_slot *slot = chip->slots[0]; -- int ret; -- -- ret = cqhci_suspend(slot->host->mmc); -- if (ret) -- return ret; -- -- return sdhci_suspend_host(slot->host); --} --#endif -- - static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc, - struct mmc_ios *ios) - { -@@ -1040,6 +1004,70 @@ static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip) - } - #endif - -+#ifdef CONFIG_PM_SLEEP -+static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip) -+{ -+ struct sdhci_pci_slot *slot = chip->slots[0]; -+ -+ pci_free_irq_vectors(slot->chip->pdev); -+ gli_pcie_enable_msi(slot); -+ -+ return sdhci_pci_resume_host(chip); -+} -+ -+static int gl9763e_resume(struct sdhci_pci_chip *chip) -+{ -+ struct sdhci_pci_slot *slot = chip->slots[0]; -+ int ret; -+ -+ ret = sdhci_pci_gli_resume(chip); -+ if (ret) -+ return ret; -+ -+ ret = cqhci_resume(slot->host->mmc); -+ if (ret) -+ return ret; -+ -+ /* -+ * Disable LPM negotiation to bring device back in sync -+ * with its runtime_pm state. -+ */ -+ gl9763e_set_low_power_negotiation(slot, false); -+ -+ return 0; -+} -+ -+static int gl9763e_suspend(struct sdhci_pci_chip *chip) -+{ -+ struct sdhci_pci_slot *slot = chip->slots[0]; -+ int ret; -+ -+ /* -+ * Certain SoCs can suspend only with the bus in low- -+ * power state, notably x86 SoCs when using S0ix. -+ * Re-enable LPM negotiation to allow entering L1 state -+ * and entering system suspend. -+ */ -+ gl9763e_set_low_power_negotiation(slot, true); -+ -+ ret = cqhci_suspend(slot->host->mmc); -+ if (ret) -+ goto err_suspend; -+ -+ ret = sdhci_suspend_host(slot->host); -+ if (ret) -+ goto err_suspend_host; -+ -+ return 0; -+ -+err_suspend_host: -+ cqhci_resume(slot->host->mmc); -+err_suspend: -+ gl9763e_set_low_power_negotiation(slot, false); -+ return ret; -+} -+#endif -+ - static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot) - { - struct pci_dev *pdev = slot->chip->pdev; -@@ -1147,8 +1175,8 @@ const struct sdhci_pci_fixes sdhci_gl9763e = { - .probe_slot = gli_probe_slot_gl9763e, - .ops = &sdhci_gl9763e_ops, - #ifdef CONFIG_PM_SLEEP -- .resume = sdhci_cqhci_gli_resume, -- .suspend = sdhci_cqhci_gli_suspend, -+ .resume = gl9763e_resume, -+ .suspend = gl9763e_suspend, - #endif - #ifdef CONFIG_PM - .runtime_suspend = gl9763e_runtime_suspend, -diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-core.c -index c73854da51363..19dad5a23f944 100644 ---- a/drivers/mtd/maps/physmap-core.c -+++ b/drivers/mtd/maps/physmap-core.c -@@ -552,6 +552,17 @@ static int physmap_flash_probe(struct platform_device *dev) - if (info->probe_type) { - info->mtds[i] = do_map_probe(info->probe_type, - &info->maps[i]); -+ -+ /* Fall back to mapping region as ROM */ -+ if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) && -+ strcmp(info->probe_type, "map_rom")) { -+ dev_warn(&dev->dev, -+ "map_probe() failed for type %s\n", -+ info->probe_type); -+ -+ info->mtds[i] = do_map_probe("map_rom", -+ &info->maps[i]); -+ } - } else { - int j; - -diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c -index ec7e6eeac55f9..e6ffe87a599eb 100644 ---- a/drivers/mtd/nand/raw/arasan-nand-controller.c -+++ b/drivers/mtd/nand/raw/arasan-nand-controller.c -@@ -515,6 +515,7 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, - struct mtd_info *mtd = nand_to_mtd(chip); - unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0); - dma_addr_t dma_addr; -+ u8 status; - int ret; - struct anfc_op nfc_op = { - .pkt_reg = -@@ -561,10 +562,21 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, - } - - /* Spare data is not protected */ -- if (oob_required) -+ if (oob_required) { - ret = nand_write_oob_std(chip, page); -+ if (ret) -+ return ret; -+ } - -- return ret; -+ /* Check write status on the chip side */ -+ ret = nand_status_op(chip, &status); -+ if (ret) -+ return ret; -+ -+ if (status & NAND_STATUS_FAIL) -+ return -EIO; -+ -+ return 0; - } - - static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, -diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c -index a57a1501449aa..d527c03630bce 100644 ---- a/drivers/mtd/nand/raw/marvell_nand.c -+++ b/drivers/mtd/nand/raw/marvell_nand.c -@@ -1154,6 +1154,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, - .ndcb[2] = NDCB2_ADDR5_PAGE(page), - }; - unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0); -+ u8 status; - int ret; - - /* NFCv2 needs more information about the operation being executed */ -@@ -1187,7 +1188,18 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, - - ret = marvell_nfc_wait_op(chip, - PSEC_TO_MSEC(sdr->tPROG_max)); -- return ret; -+ if (ret) -+ return ret; -+ -+ /* Check write status on the chip side */ -+ ret = nand_status_op(chip, &status); -+ if (ret) -+ return ret; -+ -+ if (status & NAND_STATUS_FAIL) -+ return -EIO; -+ -+ return 0; - } - - static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip, -@@ -1616,6 +1628,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip, - int data_len = lt->data_bytes; - int spare_len = lt->spare_bytes; - int chunk, ret; -+ u8 status; - - marvell_nfc_select_target(chip, chip->cur_cs); - -@@ -1652,6 +1665,14 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip, - if (ret) - return ret; - -+ /* Check write status on the chip side */ -+ ret = nand_status_op(chip, &status); -+ if (ret) -+ return ret; -+ -+ if (status & NAND_STATUS_FAIL) -+ return -EIO; -+ - return 0; - } - -diff --git a/drivers/mtd/nand/raw/pl35x-nand-controller.c b/drivers/mtd/nand/raw/pl35x-nand-controller.c -index 3c6f6aff649f8..7bcece135715d 100644 ---- a/drivers/mtd/nand/raw/pl35x-nand-controller.c -+++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c -@@ -513,6 +513,7 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip, - u32 addr1 = 0, addr2 = 0, row; - u32 cmd_addr; - int i, ret; -+ u8 status; - - ret = pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_APB); - if (ret) -@@ -565,6 +566,14 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip, - if (ret) - goto disable_ecc_engine; - -+ /* Check write status on the chip side */ -+ ret = nand_status_op(chip, &status); -+ if (ret) -+ goto disable_ecc_engine; -+ -+ if (status & NAND_STATUS_FAIL) -+ ret = -EIO; -+ - disable_ecc_engine: - pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS); - -diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c -index 198a44794d2dc..fbf36cbcbb18d 100644 ---- a/drivers/mtd/nand/raw/qcom_nandc.c -+++ b/drivers/mtd/nand/raw/qcom_nandc.c -@@ -3310,7 +3310,7 @@ err_nandc_alloc: - err_aon_clk: - clk_disable_unprepare(nandc->core_clk); - err_core_clk: -- dma_unmap_resource(dev, res->start, resource_size(res), -+ dma_unmap_resource(dev, nandc->base_dma, resource_size(res), - DMA_BIDIRECTIONAL, 0); - return ret; - } -diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c -index 50b7295bc9222..12601bc4227a7 100644 ---- a/drivers/mtd/nand/spi/micron.c -+++ b/drivers/mtd/nand/spi/micron.c -@@ -12,7 +12,7 @@ - - #define SPINAND_MFR_MICRON 0x2c - --#define MICRON_STATUS_ECC_MASK GENMASK(7, 4) -+#define MICRON_STATUS_ECC_MASK GENMASK(6, 4) - #define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4) - #define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4) - #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4) -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index 7a3c7a74af04a..b170a3d8d007e 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -3990,7 +3990,7 @@ static inline const void *bond_pull_data(struct sk_buff *skb, - if (likely(n <= hlen)) - return data; - else if (skb && likely(pskb_may_pull(skb, n))) -- return skb->head; -+ return skb->data; - - return NULL; - } -diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c -index 72374b066f64a..cd1f240c90f39 100644 ---- a/drivers/net/dsa/bcm_sf2.c -+++ b/drivers/net/dsa/bcm_sf2.c -@@ -617,17 +617,16 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) - dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio"); - priv->master_mii_bus = of_mdio_find_bus(dn); - if (!priv->master_mii_bus) { -- of_node_put(dn); -- return -EPROBE_DEFER; -+ err = -EPROBE_DEFER; -+ goto err_of_node_put; - } - -- get_device(&priv->master_mii_bus->dev); - priv->master_mii_dn = dn; - - priv->slave_mii_bus = mdiobus_alloc(); - if (!priv->slave_mii_bus) { -- of_node_put(dn); -- return -ENOMEM; -+ err = -ENOMEM; -+ goto err_put_master_mii_bus_dev; - } - - priv->slave_mii_bus->priv = priv; -@@ -684,11 +683,17 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) - } - - err = mdiobus_register(priv->slave_mii_bus); -- if (err && dn) { -- mdiobus_free(priv->slave_mii_bus); -- of_node_put(dn); -- } -+ if (err && dn) -+ goto err_free_slave_mii_bus; - -+ return 0; -+ -+err_free_slave_mii_bus: -+ mdiobus_free(priv->slave_mii_bus); -+err_put_master_mii_bus_dev: -+ put_device(&priv->master_mii_bus->dev); -+err_of_node_put: -+ of_node_put(dn); - return err; - } - -@@ -696,6 +701,7 @@ static void bcm_sf2_mdio_unregister(struct bcm_sf2_priv *priv) - { - mdiobus_unregister(priv->slave_mii_bus); - mdiobus_free(priv->slave_mii_bus); -+ put_device(&priv->master_mii_bus->dev); - of_node_put(priv->master_mii_dn); - } - -diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c -index a4256087ac828..5e45bef4fd34f 100644 ---- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c -+++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c -@@ -911,7 +911,7 @@ static int csk_wait_memory(struct chtls_dev *cdev, - struct sock *sk, long *timeo_p) - { - DEFINE_WAIT_FUNC(wait, woken_wake_function); -- int err = 0; -+ int ret, err = 0; - long current_timeo; - long vm_wait = 0; - bool noblock; -@@ -942,10 +942,13 @@ static int csk_wait_memory(struct chtls_dev *cdev, - - set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); - sk->sk_write_pending++; -- sk_wait_event(sk, ¤t_timeo, sk->sk_err || -- (sk->sk_shutdown & SEND_SHUTDOWN) || -- (csk_mem_free(cdev, sk) && !vm_wait), &wait); -+ ret = sk_wait_event(sk, ¤t_timeo, sk->sk_err || -+ (sk->sk_shutdown & SEND_SHUTDOWN) || -+ (csk_mem_free(cdev, sk) && !vm_wait), -+ &wait); - sk->sk_write_pending--; -+ if (ret < 0) -+ goto do_error; - - if (vm_wait) { - vm_wait -= current_timeo; -@@ -1438,6 +1441,7 @@ static int chtls_pt_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, - int copied = 0; - int target; - long timeo; -+ int ret; - - buffers_freed = 0; - -@@ -1513,7 +1517,11 @@ static int chtls_pt_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, - if (copied >= target) - break; - chtls_cleanup_rbuf(sk, copied); -- sk_wait_data(sk, &timeo, NULL); -+ ret = sk_wait_data(sk, &timeo, NULL); -+ if (ret < 0) { -+ copied = copied ? : ret; -+ goto unlock; -+ } - continue; - found_ok_skb: - if (!skb->len) { -@@ -1608,6 +1616,8 @@ skip_copy: - - if (buffers_freed) - chtls_cleanup_rbuf(sk, copied); -+ -+unlock: - release_sock(sk); - return copied; - } -@@ -1624,6 +1634,7 @@ static int peekmsg(struct sock *sk, struct msghdr *msg, - int copied = 0; - size_t avail; /* amount of available data in current skb */ - long timeo; -+ int ret; - - lock_sock(sk); - timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); -@@ -1675,7 +1686,12 @@ static int peekmsg(struct sock *sk, struct msghdr *msg, - release_sock(sk); - lock_sock(sk); - } else { -- sk_wait_data(sk, &timeo, NULL); -+ ret = sk_wait_data(sk, &timeo, NULL); -+ if (ret < 0) { -+ /* here 'copied' is 0 due to previous checks */ -+ copied = ret; -+ break; -+ } - } - - if (unlikely(peek_seq != tp->copied_seq)) { -@@ -1746,6 +1762,7 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, - int copied = 0; - long timeo; - int target; /* Read at least this many bytes */ -+ int ret; - - buffers_freed = 0; - -@@ -1837,7 +1854,11 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, - if (copied >= target) - break; - chtls_cleanup_rbuf(sk, copied); -- sk_wait_data(sk, &timeo, NULL); -+ ret = sk_wait_data(sk, &timeo, NULL); -+ if (ret < 0) { -+ copied = copied ? : ret; -+ goto unlock; -+ } - continue; - - found_ok_skb: -@@ -1906,6 +1927,7 @@ skip_copy: - if (buffers_freed) - chtls_cleanup_rbuf(sk, copied); - -+unlock: - release_sock(sk); - return copied; - } -diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c -index 82e06272158df..6266756b47b9d 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_common.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c -@@ -1082,7 +1082,7 @@ void i40e_clear_hw(struct i40e_hw *hw) - I40E_PFLAN_QALLOC_FIRSTQ_SHIFT; - j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >> - I40E_PFLAN_QALLOC_LASTQ_SHIFT; -- if (val & I40E_PFLAN_QALLOC_VALID_MASK) -+ if (val & I40E_PFLAN_QALLOC_VALID_MASK && j >= base_queue) - num_queues = (j - base_queue) + 1; - else - num_queues = 0; -@@ -1092,7 +1092,7 @@ void i40e_clear_hw(struct i40e_hw *hw) - I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT; - j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >> - I40E_PF_VT_PFALLOC_LASTVF_SHIFT; -- if (val & I40E_PF_VT_PFALLOC_VALID_MASK) -+ if (val & I40E_PF_VT_PFALLOC_VALID_MASK && j >= i) - num_vfs = (j - i) + 1; - else - num_vfs = 0; -diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c -index 7276badfa19ea..c051503c3a892 100644 ---- a/drivers/net/ethernet/intel/ice/ice_lib.c -+++ b/drivers/net/ethernet/intel/ice/ice_lib.c -@@ -1100,8 +1100,7 @@ static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) - - ctxt->info.q_opt_rss = ((lut_type << ICE_AQ_VSI_Q_OPT_RSS_LUT_S) & - ICE_AQ_VSI_Q_OPT_RSS_LUT_M) | -- ((hash_type << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) & -- ICE_AQ_VSI_Q_OPT_RSS_HASH_M); -+ (hash_type & ICE_AQ_VSI_Q_OPT_RSS_HASH_M); - } - - static void -diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c -index 3f98781e74b28..f0f39364819ac 100644 ---- a/drivers/net/ethernet/intel/ice/ice_main.c -+++ b/drivers/net/ethernet/intel/ice/ice_main.c -@@ -6,6 +6,7 @@ - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - - #include -+#include - #include "ice.h" - #include "ice_base.h" - #include "ice_lib.h" -@@ -4681,6 +4682,20 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) - return -EINVAL; - } - -+ /* when under a kdump kernel initiate a reset before enabling the -+ * device in order to clear out any pending DMA transactions. These -+ * transactions can cause some systems to machine check when doing -+ * the pcim_enable_device() below. -+ */ -+ if (is_kdump_kernel()) { -+ pci_save_state(pdev); -+ pci_clear_master(pdev); -+ err = pcie_flr(pdev); -+ if (err) -+ return err; -+ pci_restore_state(pdev); -+ } -+ - /* this driver uses devres, see - * Documentation/driver-api/driver-model/devres.rst - */ -@@ -4708,7 +4723,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) - return err; - } - -- pci_enable_pcie_error_reporting(pdev); - pci_set_master(pdev); - - pf->pdev = pdev; -@@ -5001,7 +5015,6 @@ err_init_pf_unroll: - ice_devlink_destroy_regions(pf); - ice_deinit_hw(hw); - err_exit_unroll: -- pci_disable_pcie_error_reporting(pdev); - pci_disable_device(pdev); - return err; - } -@@ -5127,7 +5140,6 @@ static void ice_remove(struct pci_dev *pdev) - ice_reset(&pf->hw, ICE_RESET_PFR); - pci_wait_for_pending_transaction(pdev); - ice_clear_interrupt_scheme(pf); -- pci_disable_pcie_error_reporting(pdev); - pci_disable_device(pdev); - } - -diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h -index d3b17aa1d1a83..43c05b41627f7 100644 ---- a/drivers/net/ethernet/intel/igc/igc.h -+++ b/drivers/net/ethernet/intel/igc/igc.h -@@ -183,9 +183,11 @@ struct igc_adapter { - u32 max_frame_size; - u32 min_frame_size; - -+ int tc_setup_type; - ktime_t base_time; - ktime_t cycle_time; - bool qbv_enable; -+ u32 qbv_config_change_errors; - - /* OS defined structs */ - struct pci_dev *pdev; -@@ -228,6 +230,10 @@ struct igc_adapter { - struct ptp_clock *ptp_clock; - struct ptp_clock_info ptp_caps; - struct work_struct ptp_tx_work; -+ /* Access to ptp_tx_skb and ptp_tx_start are protected by the -+ * ptp_tx_lock. -+ */ -+ spinlock_t ptp_tx_lock; - struct sk_buff *ptp_tx_skb; - struct hwtstamp_config tstamp_config; - unsigned long ptp_tx_start; -@@ -429,7 +435,6 @@ enum igc_state_t { - __IGC_TESTING, - __IGC_RESETTING, - __IGC_DOWN, -- __IGC_PTP_TX_IN_PROGRESS, - }; - - enum igc_tx_flags { -diff --git a/drivers/net/ethernet/intel/igc/igc_base.c b/drivers/net/ethernet/intel/igc/igc_base.c -index a15927e772720..a1d815af507d9 100644 ---- a/drivers/net/ethernet/intel/igc/igc_base.c -+++ b/drivers/net/ethernet/intel/igc/igc_base.c -@@ -396,6 +396,35 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw) - rd32(IGC_MPC); - } - -+bool igc_is_device_id_i225(struct igc_hw *hw) -+{ -+ switch (hw->device_id) { -+ case IGC_DEV_ID_I225_LM: -+ case IGC_DEV_ID_I225_V: -+ case IGC_DEV_ID_I225_I: -+ case IGC_DEV_ID_I225_K: -+ case IGC_DEV_ID_I225_K2: -+ case IGC_DEV_ID_I225_LMVP: -+ case IGC_DEV_ID_I225_IT: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+bool igc_is_device_id_i226(struct igc_hw *hw) -+{ -+ switch (hw->device_id) { -+ case IGC_DEV_ID_I226_LM: -+ case IGC_DEV_ID_I226_V: -+ case IGC_DEV_ID_I226_K: -+ case IGC_DEV_ID_I226_IT: -+ return true; -+ default: -+ return false; -+ } -+} -+ - static struct igc_mac_operations igc_mac_ops_base = { - .init_hw = igc_init_hw_base, - .check_for_link = igc_check_for_copper_link, -diff --git a/drivers/net/ethernet/intel/igc/igc_base.h b/drivers/net/ethernet/intel/igc/igc_base.h -index 52849f5e8048d..9f3827eda157c 100644 ---- a/drivers/net/ethernet/intel/igc/igc_base.h -+++ b/drivers/net/ethernet/intel/igc/igc_base.h -@@ -7,6 +7,8 @@ - /* forward declaration */ - void igc_rx_fifo_flush_base(struct igc_hw *hw); - void igc_power_down_phy_copper_base(struct igc_hw *hw); -+bool igc_is_device_id_i225(struct igc_hw *hw); -+bool igc_is_device_id_i226(struct igc_hw *hw); - - /* Transmit Descriptor - Advanced */ - union igc_adv_tx_desc { -diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h -index 90ca01889cd82..efdabcbd66ddd 100644 ---- a/drivers/net/ethernet/intel/igc/igc_defines.h -+++ b/drivers/net/ethernet/intel/igc/igc_defines.h -@@ -515,6 +515,7 @@ - /* Transmit Scheduling */ - #define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001 - #define IGC_TQAVCTRL_ENHANCED_QAV 0x00000008 -+#define IGC_TQAVCTRL_FUTSCDDIS 0x00000080 - - #define IGC_TXQCTL_QUEUE_MODE_LAUNCHT 0x00000001 - #define IGC_TXQCTL_STRICT_CYCLE 0x00000002 -diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c -index 9166fde40c772..e23b95edb05ef 100644 ---- a/drivers/net/ethernet/intel/igc/igc_ethtool.c -+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c -@@ -67,6 +67,7 @@ static const struct igc_stats igc_gstrings_stats[] = { - IGC_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), - IGC_STAT("tx_lpi_counter", stats.tlpic), - IGC_STAT("rx_lpi_counter", stats.rlpic), -+ IGC_STAT("qbv_config_change_errors", qbv_config_change_errors), - }; - - #define IGC_NETDEV_STAT(_net_stat) { \ -diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c -index 1ac836a55cd31..4b6f882b380dc 100644 ---- a/drivers/net/ethernet/intel/igc/igc_main.c -+++ b/drivers/net/ethernet/intel/igc/igc_main.c -@@ -1606,9 +1606,10 @@ done: - * the other timer registers before skipping the - * timestamping request. - */ -- if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && -- !test_and_set_bit_lock(__IGC_PTP_TX_IN_PROGRESS, -- &adapter->state)) { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&adapter->ptp_tx_lock, flags); -+ if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && !adapter->ptp_tx_skb) { - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; - tx_flags |= IGC_TX_FLAGS_TSTAMP; - -@@ -1617,6 +1618,8 @@ done: - } else { - adapter->tx_hwtstamp_skipped++; - } -+ -+ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); - } - - if (skb_vlan_tag_present(skb)) { -@@ -6035,6 +6038,7 @@ static bool validate_schedule(struct igc_adapter *adapter, - const struct tc_taprio_qopt_offload *qopt) - { - int queue_uses[IGC_MAX_TX_QUEUES] = { }; -+ struct igc_hw *hw = &adapter->hw; - struct timespec64 now; - size_t n; - -@@ -6047,8 +6051,10 @@ static bool validate_schedule(struct igc_adapter *adapter, - * in the future, it will hold all the packets until that - * time, causing a lot of TX Hangs, so to avoid that, we - * reject schedules that would start in the future. -+ * Note: Limitation above is no longer in i226. - */ -- if (!is_base_time_past(qopt->base_time, &now)) -+ if (!is_base_time_past(qopt->base_time, &now) && -+ igc_is_device_id_i225(hw)) - return false; - - for (n = 0; n < qopt->num_entries; n++) { -@@ -6103,6 +6109,7 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter) - - adapter->base_time = 0; - adapter->cycle_time = NSEC_PER_SEC; -+ adapter->qbv_config_change_errors = 0; - - for (i = 0; i < adapter->num_tx_queues; i++) { - struct igc_ring *ring = adapter->tx_ring[i]; -@@ -6118,6 +6125,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, - struct tc_taprio_qopt_offload *qopt) - { - bool queue_configured[IGC_MAX_TX_QUEUES] = { }; -+ struct igc_hw *hw = &adapter->hw; - u32 start_time = 0, end_time = 0; - size_t n; - int i; -@@ -6130,7 +6138,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, - if (qopt->base_time < 0) - return -ERANGE; - -- if (adapter->base_time) -+ if (igc_is_device_id_i225(hw) && adapter->base_time) - return -EALREADY; - - if (!validate_schedule(adapter, qopt)) -@@ -6283,6 +6291,8 @@ static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type, - { - struct igc_adapter *adapter = netdev_priv(dev); - -+ adapter->tc_setup_type = type; -+ - switch (type) { - case TC_SETUP_QDISC_TAPRIO: - return igc_tsn_enable_qbv_scheduling(adapter, type_data); -diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c -index d96cdccdc1e1e..14cd7f995280d 100644 ---- a/drivers/net/ethernet/intel/igc/igc_ptp.c -+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c -@@ -622,6 +622,7 @@ static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter, - return 0; - } - -+/* Requires adapter->ptp_tx_lock held by caller. */ - static void igc_ptp_tx_timeout(struct igc_adapter *adapter) - { - struct igc_hw *hw = &adapter->hw; -@@ -629,7 +630,6 @@ static void igc_ptp_tx_timeout(struct igc_adapter *adapter) - dev_kfree_skb_any(adapter->ptp_tx_skb); - adapter->ptp_tx_skb = NULL; - adapter->tx_hwtstamp_timeouts++; -- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state); - /* Clear the tx valid bit in TSYNCTXCTL register to enable interrupt. */ - rd32(IGC_TXSTMPH); - netdev_warn(adapter->netdev, "Tx timestamp timeout\n"); -@@ -637,20 +637,20 @@ static void igc_ptp_tx_timeout(struct igc_adapter *adapter) - - void igc_ptp_tx_hang(struct igc_adapter *adapter) - { -- bool timeout = time_is_before_jiffies(adapter->ptp_tx_start + -- IGC_PTP_TX_TIMEOUT); -+ unsigned long flags; - -- if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state)) -- return; -+ spin_lock_irqsave(&adapter->ptp_tx_lock, flags); - -- /* If we haven't received a timestamp within the timeout, it is -- * reasonable to assume that it will never occur, so we can unlock the -- * timestamp bit when this occurs. -- */ -- if (timeout) { -- cancel_work_sync(&adapter->ptp_tx_work); -- igc_ptp_tx_timeout(adapter); -- } -+ if (!adapter->ptp_tx_skb) -+ goto unlock; -+ -+ if (time_is_after_jiffies(adapter->ptp_tx_start + IGC_PTP_TX_TIMEOUT)) -+ goto unlock; -+ -+ igc_ptp_tx_timeout(adapter); -+ -+unlock: -+ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); - } - - /** -@@ -660,6 +660,8 @@ void igc_ptp_tx_hang(struct igc_adapter *adapter) - * If we were asked to do hardware stamping and such a time stamp is - * available, then it must have been for this skb here because we only - * allow only one such packet into the queue. -+ * -+ * Context: Expects adapter->ptp_tx_lock to be held by caller. - */ - static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) - { -@@ -695,13 +697,7 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) - shhwtstamps.hwtstamp = - ktime_add_ns(shhwtstamps.hwtstamp, adjust); - -- /* Clear the lock early before calling skb_tstamp_tx so that -- * applications are not woken up before the lock bit is clear. We use -- * a copy of the skb pointer to ensure other threads can't change it -- * while we're notifying the stack. -- */ - adapter->ptp_tx_skb = NULL; -- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state); - - /* Notify the stack and free the skb after we've unlocked */ - skb_tstamp_tx(skb, &shhwtstamps); -@@ -712,24 +708,33 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) - * igc_ptp_tx_work - * @work: pointer to work struct - * -- * This work function polls the TSYNCTXCTL valid bit to determine when a -- * timestamp has been taken for the current stored skb. -+ * This work function checks the TSYNCTXCTL valid bit to determine when -+ * a timestamp has been taken for the current stored skb. - */ - static void igc_ptp_tx_work(struct work_struct *work) - { - struct igc_adapter *adapter = container_of(work, struct igc_adapter, - ptp_tx_work); - struct igc_hw *hw = &adapter->hw; -+ unsigned long flags; - u32 tsynctxctl; - -- if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state)) -- return; -+ spin_lock_irqsave(&adapter->ptp_tx_lock, flags); -+ -+ if (!adapter->ptp_tx_skb) -+ goto unlock; - - tsynctxctl = rd32(IGC_TSYNCTXCTL); -- if (WARN_ON_ONCE(!(tsynctxctl & IGC_TSYNCTXCTL_TXTT_0))) -- return; -+ tsynctxctl &= IGC_TSYNCTXCTL_TXTT_0; -+ if (!tsynctxctl) { -+ WARN_ONCE(1, "Received a TSTAMP interrupt but no TSTAMP is ready.\n"); -+ goto unlock; -+ } - - igc_ptp_tx_hwtstamp(adapter); -+ -+unlock: -+ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); - } - - /** -@@ -978,6 +983,7 @@ void igc_ptp_init(struct igc_adapter *adapter) - return; - } - -+ spin_lock_init(&adapter->ptp_tx_lock); - spin_lock_init(&adapter->tmreg_lock); - INIT_WORK(&adapter->ptp_tx_work, igc_ptp_tx_work); - -@@ -1042,7 +1048,6 @@ void igc_ptp_suspend(struct igc_adapter *adapter) - cancel_work_sync(&adapter->ptp_tx_work); - dev_kfree_skb_any(adapter->ptp_tx_skb); - adapter->ptp_tx_skb = NULL; -- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state); - - if (pci_device_is_present(adapter->pdev)) { - igc_ptp_time_save(adapter); -diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c -index 356c7455c5cee..725db36e399d2 100644 ---- a/drivers/net/ethernet/intel/igc/igc_tsn.c -+++ b/drivers/net/ethernet/intel/igc/igc_tsn.c -@@ -2,6 +2,7 @@ - /* Copyright (c) 2019 Intel Corporation */ - - #include "igc.h" -+#include "igc_hw.h" - #include "igc_tsn.h" - - static bool is_any_launchtime(struct igc_adapter *adapter) -@@ -62,7 +63,8 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter) - - tqavctrl = rd32(IGC_TQAVCTRL); - tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN | -- IGC_TQAVCTRL_ENHANCED_QAV); -+ IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS); -+ - wr32(IGC_TQAVCTRL, tqavctrl); - - for (i = 0; i < adapter->num_tx_queues; i++) { -@@ -82,25 +84,16 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter) - static int igc_tsn_enable_offload(struct igc_adapter *adapter) - { - struct igc_hw *hw = &adapter->hw; -+ bool tsn_mode_reconfig = false; - u32 tqavctrl, baset_l, baset_h; - u32 sec, nsec, cycle; - ktime_t base_time, systim; - int i; - -- cycle = adapter->cycle_time; -- base_time = adapter->base_time; -- - wr32(IGC_TSAUXC, 0); - wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN); - wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN); - -- tqavctrl = rd32(IGC_TQAVCTRL); -- tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV; -- wr32(IGC_TQAVCTRL, tqavctrl); -- -- wr32(IGC_QBVCYCLET_S, cycle); -- wr32(IGC_QBVCYCLET, cycle); -- - for (i = 0; i < adapter->num_tx_queues; i++) { - struct igc_ring *ring = adapter->tx_ring[i]; - u32 txqctl = 0; -@@ -203,21 +196,58 @@ skip_cbs: - wr32(IGC_TXQCTL(i), txqctl); - } - -+ tqavctrl = rd32(IGC_TQAVCTRL) & ~IGC_TQAVCTRL_FUTSCDDIS; -+ -+ if (tqavctrl & IGC_TQAVCTRL_TRANSMIT_MODE_TSN) -+ tsn_mode_reconfig = true; -+ -+ tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV; -+ -+ cycle = adapter->cycle_time; -+ base_time = adapter->base_time; -+ - nsec = rd32(IGC_SYSTIML); - sec = rd32(IGC_SYSTIMH); - - systim = ktime_set(sec, nsec); -- - if (ktime_compare(systim, base_time) > 0) { -- s64 n; -+ s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle); - -- n = div64_s64(ktime_sub_ns(systim, base_time), cycle); - base_time = ktime_add_ns(base_time, (n + 1) * cycle); -+ -+ /* Increase the counter if scheduling into the past while -+ * Gate Control List (GCL) is running. -+ */ -+ if ((rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) && -+ (adapter->tc_setup_type == TC_SETUP_QDISC_TAPRIO) && -+ tsn_mode_reconfig) -+ adapter->qbv_config_change_errors++; -+ } else { -+ /* According to datasheet section 7.5.2.9.3.3, FutScdDis bit -+ * has to be configured before the cycle time and base time. -+ * Tx won't hang if there is a GCL is already running, -+ * so in this case we don't need to set FutScdDis. -+ */ -+ if (igc_is_device_id_i226(hw) && -+ !(rd32(IGC_BASET_H) || rd32(IGC_BASET_L))) -+ tqavctrl |= IGC_TQAVCTRL_FUTSCDDIS; - } - -- baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l); -+ wr32(IGC_TQAVCTRL, tqavctrl); - -+ wr32(IGC_QBVCYCLET_S, cycle); -+ wr32(IGC_QBVCYCLET, cycle); -+ -+ baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l); - wr32(IGC_BASET_H, baset_h); -+ -+ /* In i226, Future base time is only supported when FutScdDis bit -+ * is enabled and only active for re-configuration. -+ * In this case, initialize the base time with zero to create -+ * "re-configuration" scenario then only set the desired base time. -+ */ -+ if (tqavctrl & IGC_TQAVCTRL_FUTSCDDIS) -+ wr32(IGC_BASET_L, 0); - wr32(IGC_BASET_L, baset_l); - - return 0; -@@ -244,17 +274,14 @@ int igc_tsn_reset(struct igc_adapter *adapter) - - int igc_tsn_offload_apply(struct igc_adapter *adapter) - { -- int err; -+ struct igc_hw *hw = &adapter->hw; - -- if (netif_running(adapter->netdev)) { -+ if (netif_running(adapter->netdev) && igc_is_device_id_i225(hw)) { - schedule_work(&adapter->reset_task); - return 0; - } - -- err = igc_tsn_enable_offload(adapter); -- if (err < 0) -- return err; -+ igc_tsn_reset(adapter); - -- adapter->flags = igc_tsn_new_flags(adapter); - return 0; - } -diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -index 61354f7985035..e171097c13654 100644 ---- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c -@@ -707,20 +707,19 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb, - hw_desc->dptr = tx_buffer->sglist_dma; - } - -- /* Flush the hw descriptor before writing to doorbell */ -- wmb(); -- -- /* Ring Doorbell to notify the NIC there is a new packet */ -- writel(1, iq->doorbell_reg); -+ netdev_tx_sent_queue(iq->netdev_q, skb->len); -+ skb_tx_timestamp(skb); - atomic_inc(&iq->instr_pending); - wi++; - if (wi == iq->max_count) - wi = 0; - iq->host_write_index = wi; -+ /* Flush the hw descriptor before writing to doorbell */ -+ wmb(); - -- netdev_tx_sent_queue(iq->netdev_q, skb->len); -+ /* Ring Doorbell to notify the NIC there is a new packet */ -+ writel(1, iq->doorbell_reg); - iq->stats.instr_posted++; -- skb_tx_timestamp(skb); - return NETDEV_TX_OK; - - dma_map_sg_err: -diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h -index ddec1627f1a7b..8d0bacf4e49cc 100644 ---- a/drivers/net/ethernet/marvell/sky2.h -+++ b/drivers/net/ethernet/marvell/sky2.h -@@ -2195,7 +2195,7 @@ struct rx_ring_info { - struct sk_buff *skb; - dma_addr_t data_addr; - DEFINE_DMA_UNMAP_LEN(data_size); -- dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; -+ dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT ?: 1]; - }; - - enum flow_control { -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c -index c4e40834e3ff9..374c0011a127b 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c -@@ -821,7 +821,7 @@ static void mlx5_fw_tracer_ownership_change(struct work_struct *work) - - mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner); - if (tracer->owner) { -- tracer->owner = false; -+ mlx5_fw_tracer_ownership_acquire(tracer); - return; - } - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c -index cd15d36b1507e..907ad6ffe7275 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c -@@ -23,7 +23,8 @@ static int mlx5e_set_int_port_tunnel(struct mlx5e_priv *priv, - - route_dev = dev_get_by_index(dev_net(e->out_dev), e->route_dev_ifindex); - -- if (!route_dev || !netif_is_ovs_master(route_dev)) -+ if (!route_dev || !netif_is_ovs_master(route_dev) || -+ attr->parse_attr->filter_dev == e->out_dev) - goto out; - - err = mlx5e_set_fwd_to_int_port_actions(priv, attr, e->route_dev_ifindex, -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c -index 4b9d567c8f473..48939c72b5925 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c -@@ -969,11 +969,8 @@ const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) - return ERR_PTR(err); - } - --static void mlx5_eswitch_event_handlers_register(struct mlx5_eswitch *esw) -+static void mlx5_eswitch_event_handler_register(struct mlx5_eswitch *esw) - { -- MLX5_NB_INIT(&esw->nb, eswitch_vport_event, NIC_VPORT_CHANGE); -- mlx5_eq_notifier_register(esw->dev, &esw->nb); -- - if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) { - MLX5_NB_INIT(&esw->esw_funcs.nb, mlx5_esw_funcs_changed_handler, - ESW_FUNCTIONS_CHANGED); -@@ -981,13 +978,11 @@ static void mlx5_eswitch_event_handlers_register(struct mlx5_eswitch *esw) - } - } - --static void mlx5_eswitch_event_handlers_unregister(struct mlx5_eswitch *esw) -+static void mlx5_eswitch_event_handler_unregister(struct mlx5_eswitch *esw) - { - if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) - mlx5_eq_notifier_unregister(esw->dev, &esw->esw_funcs.nb); - -- mlx5_eq_notifier_unregister(esw->dev, &esw->nb); -- - flush_workqueue(esw->work_queue); - } - -@@ -1273,6 +1268,9 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) - - mlx5_eswitch_update_num_of_vfs(esw, num_vfs); - -+ MLX5_NB_INIT(&esw->nb, eswitch_vport_event, NIC_VPORT_CHANGE); -+ mlx5_eq_notifier_register(esw->dev, &esw->nb); -+ - if (esw->mode == MLX5_ESWITCH_LEGACY) { - err = esw_legacy_enable(esw); - } else { -@@ -1285,7 +1283,7 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) - - esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED; - -- mlx5_eswitch_event_handlers_register(esw); -+ mlx5_eswitch_event_handler_register(esw); - - esw_info(esw->dev, "Enable: mode(%s), nvfs(%d), active vports(%d)\n", - esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", -@@ -1394,7 +1392,8 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw) - */ - mlx5_esw_mode_change_notify(esw, MLX5_ESWITCH_LEGACY); - -- mlx5_eswitch_event_handlers_unregister(esw); -+ mlx5_eq_notifier_unregister(esw->dev, &esw->nb); -+ mlx5_eswitch_event_handler_unregister(esw); - - esw_info(esw->dev, "Disable: mode(%s), nvfs(%d), active vports(%d)\n", - esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", -diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c -index ed274f033626d..810df65cdf085 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c -+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c -@@ -113,7 +113,10 @@ static void qed_ll2b_complete_tx_packet(void *cxt, - static int qed_ll2_alloc_buffer(struct qed_dev *cdev, - u8 **data, dma_addr_t *phys_addr) - { -- *data = kmalloc(cdev->ll2->rx_size, GFP_ATOMIC); -+ size_t size = cdev->ll2->rx_size + NET_SKB_PAD + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ -+ *data = kmalloc(size, GFP_ATOMIC); - if (!(*data)) { - DP_INFO(cdev, "Failed to allocate LL2 buffer data\n"); - return -ENOMEM; -@@ -2590,7 +2593,7 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params) - INIT_LIST_HEAD(&cdev->ll2->list); - spin_lock_init(&cdev->ll2->lock); - -- cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN + -+ cdev->ll2->rx_size = PRM_DMA_PAD_BYTES_NUM + ETH_HLEN + - L1_CACHE_BYTES + params->mtu; - - /* Allocate memory for LL2. -diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c -index 6cebf3aaa621f..dc5b27cb48fb0 100644 ---- a/drivers/net/phy/bcm7xxx.c -+++ b/drivers/net/phy/bcm7xxx.c -@@ -907,6 +907,9 @@ static void bcm7xxx_28nm_remove(struct phy_device *phydev) - .name = _name, \ - /* PHY_BASIC_FEATURES */ \ - .flags = PHY_IS_INTERNAL, \ -+ .get_sset_count = bcm_phy_get_sset_count, \ -+ .get_strings = bcm_phy_get_strings, \ -+ .get_stats = bcm7xxx_28nm_get_phy_stats, \ - .probe = bcm7xxx_28nm_probe, \ - .remove = bcm7xxx_28nm_remove, \ - .config_init = bcm7xxx_16nm_ephy_config_init, \ -diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index 7544df1ff50ec..d373953ddc300 100644 ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -3056,10 +3056,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, - struct net *net = sock_net(&tfile->sk); - struct tun_struct *tun; - void __user* argp = (void __user*)arg; -- unsigned int ifindex, carrier; -+ unsigned int carrier; - struct ifreq ifr; - kuid_t owner; - kgid_t group; -+ int ifindex; - int sndbuf; - int vnet_hdr_sz; - int le; -@@ -3115,7 +3116,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, - ret = -EFAULT; - if (copy_from_user(&ifindex, argp, sizeof(ifindex))) - goto unlock; -- -+ ret = -EINVAL; -+ if (ifindex < 0) -+ goto unlock; - ret = 0; - tfile->ifindex = ifindex; - goto unlock; -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 563ecd27b93ea..17da42fe605c3 100644 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -897,7 +897,7 @@ static int smsc95xx_reset(struct usbnet *dev) - - if (timeout >= 100) { - netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n"); -- return ret; -+ return -ETIMEDOUT; - } - - ret = smsc95xx_set_mac_address(dev); -diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -index 542cfcad6e0e6..2d01f6226b7c6 100644 ---- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -@@ -1585,6 +1585,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, - iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); - - memset(&info->status, 0, sizeof(info->status)); -+ info->flags &= ~(IEEE80211_TX_STAT_ACK | IEEE80211_TX_STAT_TX_FILTERED); - - /* inform mac80211 about what happened with the frame */ - switch (status & TX_STATUS_MSK) { -@@ -1936,6 +1937,8 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, - */ - if (!is_flush) - info->flags |= IEEE80211_TX_STAT_ACK; -+ else -+ info->flags &= ~IEEE80211_TX_STAT_ACK; - } - - /* -diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -index 7351acac6932d..54ab8b54369ba 100644 ---- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -@@ -921,6 +921,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, - while (tlv_buf_left >= sizeof(*tlv_rxba)) { - tlv_type = le16_to_cpu(tlv_rxba->header.type); - tlv_len = le16_to_cpu(tlv_rxba->header.len); -+ if (size_add(sizeof(tlv_rxba->header), tlv_len) > tlv_buf_left) { -+ mwifiex_dbg(priv->adapter, WARN, -+ "TLV size (%zu) overflows event_buf buf_left=%d\n", -+ size_add(sizeof(tlv_rxba->header), tlv_len), -+ tlv_buf_left); -+ return; -+ } -+ - if (tlv_type != TLV_TYPE_RXBA_SYNC) { - mwifiex_dbg(priv->adapter, ERROR, - "Wrong TLV id=0x%x\n", tlv_type); -@@ -929,6 +937,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, - - tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num); - tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len); -+ if (size_add(sizeof(*tlv_rxba), tlv_bitmap_len) > tlv_buf_left) { -+ mwifiex_dbg(priv->adapter, WARN, -+ "TLV size (%zu) overflows event_buf buf_left=%d\n", -+ size_add(sizeof(*tlv_rxba), tlv_bitmap_len), -+ tlv_buf_left); -+ return; -+ } -+ - mwifiex_dbg(priv->adapter, INFO, - "%pM tid=%d seq_num=%d bitmap_len=%d\n", - tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num, -diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c -index 8224675f8de25..b33004a4bcb5a 100644 ---- a/drivers/nvme/host/ioctl.c -+++ b/drivers/nvme/host/ioctl.c -@@ -32,9 +32,13 @@ static void *nvme_add_user_metadata(struct request *req, void __user *ubuf, - if (!buf) - goto out; - -- ret = -EFAULT; -- if ((req_op(req) == REQ_OP_DRV_OUT) && copy_from_user(buf, ubuf, len)) -- goto out_free_meta; -+ if (req_op(req) == REQ_OP_DRV_OUT) { -+ ret = -EFAULT; -+ if (copy_from_user(buf, ubuf, len)) -+ goto out_free_meta; -+ } else { -+ memset(buf, 0, len); -+ } - - bip = bio_integrity_alloc(bio, GFP_KERNEL, 1); - if (IS_ERR(bip)) { -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index 64990a2cfd0a7..886c3fc9578e4 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -3439,7 +3439,8 @@ static const struct pci_device_id nvme_id_table[] = { - { PCI_VDEVICE(INTEL, 0x0a54), /* Intel P4500/P4600 */ - .driver_data = NVME_QUIRK_STRIPE_SIZE | - NVME_QUIRK_DEALLOCATE_ZEROES | -- NVME_QUIRK_IGNORE_DEV_SUBNQN, }, -+ NVME_QUIRK_IGNORE_DEV_SUBNQN | -+ NVME_QUIRK_BOGUS_NID, }, - { PCI_VDEVICE(INTEL, 0x0a55), /* Dell Express Flash P4600 */ - .driver_data = NVME_QUIRK_STRIPE_SIZE | - NVME_QUIRK_DEALLOCATE_ZEROES, }, -diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c -index c478480f54aa2..aa1734e2fd44e 100644 ---- a/drivers/nvme/host/rdma.c -+++ b/drivers/nvme/host/rdma.c -@@ -643,6 +643,9 @@ static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) - - static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) - { -+ if (!test_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags)) -+ return; -+ - mutex_lock(&queue->queue_lock); - if (test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) - __nvme_rdma_stop_queue(queue); -diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c -index 7970a7640e585..fbae76cdc2546 100644 ---- a/drivers/nvme/target/fabrics-cmd-auth.c -+++ b/drivers/nvme/target/fabrics-cmd-auth.c -@@ -337,19 +337,21 @@ done: - __func__, ctrl->cntlid, req->sq->qid, - status, req->error_loc); - req->cqe->result.u64 = 0; -- nvmet_req_complete(req, status); - if (req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2 && - req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) { - unsigned long auth_expire_secs = ctrl->kato ? ctrl->kato : 120; - - mod_delayed_work(system_wq, &req->sq->auth_expired_work, - auth_expire_secs * HZ); -- return; -+ goto complete; - } - /* Final states, clear up variables */ - nvmet_auth_sq_free(req->sq); - if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) - nvmet_ctrl_fatal_error(ctrl); -+ -+complete: -+ nvmet_req_complete(req, status); - } - - static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al) -@@ -527,11 +529,12 @@ void nvmet_execute_auth_receive(struct nvmet_req *req) - kfree(d); - done: - req->cqe->result.u64 = 0; -- nvmet_req_complete(req, status); -+ - if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2) - nvmet_auth_sq_free(req->sq); - else if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE1) { - nvmet_auth_sq_free(req->sq); - nvmet_ctrl_fatal_error(ctrl); - } -+ nvmet_req_complete(req, status); - } -diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c -index 5e29da94f72d6..355d80323b836 100644 ---- a/drivers/nvme/target/tcp.c -+++ b/drivers/nvme/target/tcp.c -@@ -345,6 +345,7 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue) - - static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status) - { -+ queue->rcv_state = NVMET_TCP_RECV_ERR; - if (status == -EPIPE || status == -ECONNRESET) - kernel_sock_shutdown(queue->sock, SHUT_RDWR); - else -@@ -871,15 +872,11 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) - iov.iov_len = sizeof(*icresp); - ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len); - if (ret < 0) -- goto free_crypto; -+ return ret; /* queue removal will cleanup */ - - queue->state = NVMET_TCP_Q_LIVE; - nvmet_prepare_receive_pdu(queue); - return 0; --free_crypto: -- if (queue->hdr_digest || queue->data_digest) -- nvmet_tcp_free_crypto(queue); -- return ret; - } - - static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue, -diff --git a/drivers/phy/motorola/phy-mapphone-mdm6600.c b/drivers/phy/motorola/phy-mapphone-mdm6600.c -index 3cd4d51c247c3..67802f9e40ba0 100644 ---- a/drivers/phy/motorola/phy-mapphone-mdm6600.c -+++ b/drivers/phy/motorola/phy-mapphone-mdm6600.c -@@ -122,16 +122,10 @@ static int phy_mdm6600_power_on(struct phy *x) - { - struct phy_mdm6600 *ddata = phy_get_drvdata(x); - struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE]; -- int error; - - if (!ddata->enabled) - return -ENODEV; - -- error = pinctrl_pm_select_default_state(ddata->dev); -- if (error) -- dev_warn(ddata->dev, "%s: error with default_state: %i\n", -- __func__, error); -- - gpiod_set_value_cansleep(enable_gpio, 1); - - /* Allow aggressive PM for USB, it's only needed for n_gsm port */ -@@ -160,11 +154,6 @@ static int phy_mdm6600_power_off(struct phy *x) - - gpiod_set_value_cansleep(enable_gpio, 0); - -- error = pinctrl_pm_select_sleep_state(ddata->dev); -- if (error) -- dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", -- __func__, error); -- - return 0; - } - -@@ -456,6 +445,7 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata) - { - struct gpio_desc *reset_gpio = - ddata->ctrl_gpios[PHY_MDM6600_RESET]; -+ int error; - - ddata->enabled = false; - phy_mdm6600_cmd(ddata, PHY_MDM6600_CMD_BP_SHUTDOWN_REQ); -@@ -471,6 +461,17 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata) - } else { - dev_err(ddata->dev, "Timed out powering down\n"); - } -+ -+ /* -+ * Keep reset gpio high with padconf internal pull-up resistor to -+ * prevent modem from waking up during deeper SoC idle states. The -+ * gpio bank lines can have glitches if not in the always-on wkup -+ * domain. -+ */ -+ error = pinctrl_pm_select_sleep_state(ddata->dev); -+ if (error) -+ dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", -+ __func__, error); - } - - static void phy_mdm6600_deferred_power_on(struct work_struct *work) -@@ -571,12 +572,6 @@ static int phy_mdm6600_probe(struct platform_device *pdev) - ddata->dev = &pdev->dev; - platform_set_drvdata(pdev, ddata); - -- /* Active state selected in phy_mdm6600_power_on() */ -- error = pinctrl_pm_select_sleep_state(ddata->dev); -- if (error) -- dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", -- __func__, error); -- - error = phy_mdm6600_init_lines(ddata); - if (error) - return error; -@@ -627,10 +622,12 @@ idle: - pm_runtime_put_autosuspend(ddata->dev); - - cleanup: -- if (error < 0) -+ if (error < 0) { - phy_mdm6600_device_power_off(ddata); -- pm_runtime_disable(ddata->dev); -- pm_runtime_dont_use_autosuspend(ddata->dev); -+ pm_runtime_disable(ddata->dev); -+ pm_runtime_dont_use_autosuspend(ddata->dev); -+ } -+ - return error; - } - -@@ -639,6 +636,7 @@ static int phy_mdm6600_remove(struct platform_device *pdev) - struct phy_mdm6600 *ddata = platform_get_drvdata(pdev); - struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET]; - -+ pm_runtime_get_noresume(ddata->dev); - pm_runtime_dont_use_autosuspend(ddata->dev); - pm_runtime_put_sync(ddata->dev); - pm_runtime_disable(ddata->dev); -diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c -index 27e41873c04ff..9e57f4c62e609 100644 ---- a/drivers/pinctrl/core.c -+++ b/drivers/pinctrl/core.c -@@ -1007,20 +1007,17 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev, - - static struct pinctrl *find_pinctrl(struct device *dev) - { -- struct pinctrl *entry, *p = NULL; -+ struct pinctrl *p; - - mutex_lock(&pinctrl_list_mutex); -- -- list_for_each_entry(entry, &pinctrl_list, node) { -- if (entry->dev == dev) { -- p = entry; -- kref_get(&p->users); -- break; -+ list_for_each_entry(p, &pinctrl_list, node) -+ if (p->dev == dev) { -+ mutex_unlock(&pinctrl_list_mutex); -+ return p; - } -- } - - mutex_unlock(&pinctrl_list_mutex); -- return p; -+ return NULL; - } - - static void pinctrl_free(struct pinctrl *p, bool inlist); -@@ -1129,6 +1126,7 @@ struct pinctrl *pinctrl_get(struct device *dev) - p = find_pinctrl(dev); - if (p) { - dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n"); -+ kref_get(&p->users); - return p; - } - -diff --git a/drivers/platform/surface/surface_platform_profile.c b/drivers/platform/surface/surface_platform_profile.c -index fbf2e11fd6ce7..37c761f577149 100644 ---- a/drivers/platform/surface/surface_platform_profile.c -+++ b/drivers/platform/surface/surface_platform_profile.c -@@ -159,8 +159,7 @@ static int surface_platform_profile_probe(struct ssam_device *sdev) - set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, tpd->handler.choices); - set_bit(PLATFORM_PROFILE_PERFORMANCE, tpd->handler.choices); - -- platform_profile_register(&tpd->handler); -- return 0; -+ return platform_profile_register(&tpd->handler); - } - - static void surface_platform_profile_remove(struct ssam_device *sdev) -diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c -index d85d895fee894..df1db54d4e183 100644 ---- a/drivers/platform/x86/asus-nb-wmi.c -+++ b/drivers/platform/x86/asus-nb-wmi.c -@@ -531,6 +531,9 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) - static const struct key_entry asus_nb_wmi_keymap[] = { - { KE_KEY, ASUS_WMI_BRN_DOWN, { KEY_BRIGHTNESSDOWN } }, - { KE_KEY, ASUS_WMI_BRN_UP, { KEY_BRIGHTNESSUP } }, -+ { KE_KEY, 0x2a, { KEY_SELECTIVE_SCREENSHOT } }, -+ { KE_IGNORE, 0x2b, }, /* PrintScreen (also send via PS/2) on newer models */ -+ { KE_IGNORE, 0x2c, }, /* CapsLock (also send via PS/2) on newer models */ - { KE_KEY, 0x30, { KEY_VOLUMEUP } }, - { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, - { KE_KEY, 0x32, { KEY_MUTE } }, -diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 36effe04c6f33..49dd55b8e8faf 100644 ---- a/drivers/platform/x86/asus-wmi.c -+++ b/drivers/platform/x86/asus-wmi.c -@@ -3268,7 +3268,6 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) - { - unsigned int key_value = 1; - bool autorelease = 1; -- int orig_code = code; - - if (asus->driver->key_filter) { - asus->driver->key_filter(asus->driver, &code, &key_value, -@@ -3277,16 +3276,10 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) - return; - } - -- if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) -- code = ASUS_WMI_BRN_UP; -- else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX) -- code = ASUS_WMI_BRN_DOWN; -- -- if (code == ASUS_WMI_BRN_DOWN || code == ASUS_WMI_BRN_UP) { -- if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { -- asus_wmi_backlight_notify(asus, orig_code); -- return; -- } -+ if (acpi_video_get_backlight_type() == acpi_backlight_vendor && -+ code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNDOWN_MAX) { -+ asus_wmi_backlight_notify(asus, code); -+ return; - } - - if (code == NOTIFY_KBD_BRTUP) { -diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h -index a478ebfd34dfa..fc41d1b1bb7f8 100644 ---- a/drivers/platform/x86/asus-wmi.h -+++ b/drivers/platform/x86/asus-wmi.h -@@ -18,7 +18,7 @@ - #include - - #define ASUS_WMI_KEY_IGNORE (-1) --#define ASUS_WMI_BRN_DOWN 0x20 -+#define ASUS_WMI_BRN_DOWN 0x2e - #define ASUS_WMI_BRN_UP 0x2f - - struct module; -diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c -index fa8f14c925ec3..9b12fe8e95c91 100644 ---- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c -+++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c -@@ -153,7 +153,7 @@ show_uncore_data(initial_max_freq_khz); - - static int create_attr_group(struct uncore_data *data, char *name) - { -- int ret, index = 0; -+ int ret, freq, index = 0; - - init_attribute_rw(max_freq_khz); - init_attribute_rw(min_freq_khz); -@@ -165,7 +165,11 @@ static int create_attr_group(struct uncore_data *data, char *name) - data->uncore_attrs[index++] = &data->min_freq_khz_dev_attr.attr; - data->uncore_attrs[index++] = &data->initial_min_freq_khz_dev_attr.attr; - data->uncore_attrs[index++] = &data->initial_max_freq_khz_dev_attr.attr; -- data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr; -+ -+ ret = uncore_read_freq(data, &freq); -+ if (!ret) -+ data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr; -+ - data->uncore_attrs[index] = NULL; - - data->uncore_attr_group.name = name; -diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c -index 68e66b60445c3..9a92d515abb9b 100644 ---- a/drivers/platform/x86/touchscreen_dmi.c -+++ b/drivers/platform/x86/touchscreen_dmi.c -@@ -740,6 +740,21 @@ static const struct ts_dmi_data pipo_w11_data = { - .properties = pipo_w11_props, - }; - -+static const struct property_entry positivo_c4128b_props[] = { -+ PROPERTY_ENTRY_U32("touchscreen-min-x", 4), -+ PROPERTY_ENTRY_U32("touchscreen-min-y", 13), -+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1915), -+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1269), -+ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-positivo-c4128b.fw"), -+ PROPERTY_ENTRY_U32("silead,max-fingers", 10), -+ { } -+}; -+ -+static const struct ts_dmi_data positivo_c4128b_data = { -+ .acpi_name = "MSSL1680:00", -+ .properties = positivo_c4128b_props, -+}; -+ - static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = { - PROPERTY_ENTRY_U32("touchscreen-min-x", 32), - PROPERTY_ENTRY_U32("touchscreen-min-y", 16), -@@ -1457,6 +1472,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { - DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"), - }, - }, -+ { -+ /* Positivo C4128B */ -+ .driver_data = (void *)&positivo_c4128b_data, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "C4128B-1"), -+ }, -+ }, - { - /* Point of View mobii wintab p800w (v2.0) */ - .driver_data = (void *)&pov_mobii_wintab_p800w_v20_data, -diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig -index a8c46ba5878fe..54201f0374104 100644 ---- a/drivers/power/reset/Kconfig -+++ b/drivers/power/reset/Kconfig -@@ -299,7 +299,7 @@ config NVMEM_REBOOT_MODE - - config POWER_MLXBF - tristate "Mellanox BlueField power handling driver" -- depends on (GPIO_MLXBF2 && ACPI) -+ depends on (GPIO_MLXBF2 || GPIO_MLXBF3) && ACPI - help - This driver supports reset or low power mode handling for Mellanox BlueField. - -diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c -index f6a95f72af18d..34d3d82819064 100644 ---- a/drivers/regulator/core.c -+++ b/drivers/regulator/core.c -@@ -5725,15 +5725,11 @@ wash: - mutex_lock(®ulator_list_mutex); - regulator_ena_gpio_free(rdev); - mutex_unlock(®ulator_list_mutex); -- put_device(&rdev->dev); -- rdev = NULL; - clean: - if (dangling_of_gpiod) - gpiod_put(config->ena_gpiod); -- if (rdev && rdev->dev.of_node) -- of_node_put(rdev->dev.of_node); -- kfree(rdev); - kfree(config); -+ put_device(&rdev->dev); - rinse: - if (dangling_cfg_gpiod) - gpiod_put(cfg->ena_gpiod); -diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c -index c7db953985002..98a14c1f3d672 100644 ---- a/drivers/s390/cio/css.c -+++ b/drivers/s390/cio/css.c -@@ -233,17 +233,19 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid, - */ - ret = dma_set_coherent_mask(&sch->dev, DMA_BIT_MASK(31)); - if (ret) -- goto err; -+ goto err_lock; - /* - * But we don't have such restrictions imposed on the stuff that - * is handled by the streaming API. - */ - ret = dma_set_mask(&sch->dev, DMA_BIT_MASK(64)); - if (ret) -- goto err; -+ goto err_lock; - - return sch; - -+err_lock: -+ kfree(sch->lock); - err: - kfree(sch); - return ERR_PTR(ret); -diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c -index adc85e250822c..2e21f74a24705 100644 ---- a/drivers/tty/serial/8250/8250_omap.c -+++ b/drivers/tty/serial/8250/8250_omap.c -@@ -32,6 +32,7 @@ - #include "8250.h" - - #define DEFAULT_CLK_SPEED 48000000 -+#define OMAP_UART_REGSHIFT 2 - - #define UART_ERRATA_i202_MDR1_ACCESS (1 << 0) - #define OMAP_UART_WER_HAS_TX_WAKEUP (1 << 1) -@@ -109,6 +110,7 @@ - #define UART_OMAP_RX_LVL 0x19 - - struct omap8250_priv { -+ void __iomem *membase; - int line; - u8 habit; - u8 mdr1; -@@ -152,9 +154,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p); - static inline void omap_8250_rx_dma_flush(struct uart_8250_port *p) { } - #endif - --static u32 uart_read(struct uart_8250_port *up, u32 reg) -+static u32 uart_read(struct omap8250_priv *priv, u32 reg) - { -- return readl(up->port.membase + (reg << up->port.regshift)); -+ return readl(priv->membase + (reg << OMAP_UART_REGSHIFT)); - } - - /* -@@ -538,7 +540,7 @@ static void omap_serial_fill_features_erratas(struct uart_8250_port *up, - u32 mvr, scheme; - u16 revision, major, minor; - -- mvr = uart_read(up, UART_OMAP_MVER); -+ mvr = uart_read(priv, UART_OMAP_MVER); - - /* Check revision register scheme */ - scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT; -@@ -1319,7 +1321,7 @@ static int omap8250_probe(struct platform_device *pdev) - UPF_HARD_FLOW; - up.port.private_data = priv; - -- up.port.regshift = 2; -+ up.port.regshift = OMAP_UART_REGSHIFT; - up.port.fifosize = 64; - up.tx_loadsz = 64; - up.capabilities = UART_CAP_FIFO; -@@ -1381,6 +1383,8 @@ static int omap8250_probe(struct platform_device *pdev) - DEFAULT_CLK_SPEED); - } - -+ priv->membase = membase; -+ priv->line = -ENODEV; - priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; - priv->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; - cpu_latency_qos_add_request(&priv->pm_qos_request, priv->latency); -@@ -1388,6 +1392,8 @@ static int omap8250_probe(struct platform_device *pdev) - - spin_lock_init(&priv->rx_dma_lock); - -+ platform_set_drvdata(pdev, priv); -+ - device_init_wakeup(&pdev->dev, true); - pm_runtime_enable(&pdev->dev); - pm_runtime_use_autosuspend(&pdev->dev); -@@ -1449,7 +1455,6 @@ static int omap8250_probe(struct platform_device *pdev) - goto err; - } - priv->line = ret; -- platform_set_drvdata(pdev, priv); - pm_runtime_mark_last_busy(&pdev->dev); - pm_runtime_put_autosuspend(&pdev->dev); - return 0; -@@ -1471,17 +1476,17 @@ static int omap8250_remove(struct platform_device *pdev) - if (err) - return err; - -+ serial8250_unregister_port(priv->line); -+ priv->line = -ENODEV; - pm_runtime_dont_use_autosuspend(&pdev->dev); - pm_runtime_put_sync(&pdev->dev); - flush_work(&priv->qos_work); - pm_runtime_disable(&pdev->dev); -- serial8250_unregister_port(priv->line); - cpu_latency_qos_remove_request(&priv->pm_qos_request); - device_init_wakeup(&pdev->dev, false); - return 0; - } - --#ifdef CONFIG_PM_SLEEP - static int omap8250_prepare(struct device *dev) - { - struct omap8250_priv *priv = dev_get_drvdata(dev); -@@ -1505,7 +1510,7 @@ static int omap8250_suspend(struct device *dev) - { - struct omap8250_priv *priv = dev_get_drvdata(dev); - struct uart_8250_port *up = serial8250_get_port(priv->line); -- int err; -+ int err = 0; - - serial8250_suspend_port(priv->line); - -@@ -1515,7 +1520,8 @@ static int omap8250_suspend(struct device *dev) - if (!device_may_wakeup(dev)) - priv->wer = 0; - serial_out(up, UART_OMAP_WER, priv->wer); -- err = pm_runtime_force_suspend(dev); -+ if (uart_console(&up->port) && console_suspend_enabled) -+ err = pm_runtime_force_suspend(dev); - flush_work(&priv->qos_work); - - return err; -@@ -1524,11 +1530,15 @@ static int omap8250_suspend(struct device *dev) - static int omap8250_resume(struct device *dev) - { - struct omap8250_priv *priv = dev_get_drvdata(dev); -+ struct uart_8250_port *up = serial8250_get_port(priv->line); - int err; - -- err = pm_runtime_force_resume(dev); -- if (err) -- return err; -+ if (uart_console(&up->port) && console_suspend_enabled) { -+ err = pm_runtime_force_resume(dev); -+ if (err) -+ return err; -+ } -+ - serial8250_resume_port(priv->line); - /* Paired with pm_runtime_resume_and_get() in omap8250_suspend() */ - pm_runtime_mark_last_busy(dev); -@@ -1536,12 +1546,7 @@ static int omap8250_resume(struct device *dev) - - return 0; - } --#else --#define omap8250_prepare NULL --#define omap8250_complete NULL --#endif - --#ifdef CONFIG_PM - static int omap8250_lost_context(struct uart_8250_port *up) - { - u32 val; -@@ -1557,11 +1562,15 @@ static int omap8250_lost_context(struct uart_8250_port *up) - return 0; - } - -+static void uart_write(struct omap8250_priv *priv, u32 reg, u32 val) -+{ -+ writel(val, priv->membase + (reg << OMAP_UART_REGSHIFT)); -+} -+ - /* TODO: in future, this should happen via API in drivers/reset/ */ - static int omap8250_soft_reset(struct device *dev) - { - struct omap8250_priv *priv = dev_get_drvdata(dev); -- struct uart_8250_port *up = serial8250_get_port(priv->line); - int timeout = 100; - int sysc; - int syss; -@@ -1575,20 +1584,20 @@ static int omap8250_soft_reset(struct device *dev) - * needing omap8250_soft_reset() quirk. Do it in two writes as - * recommended in the comment for omap8250_update_scr(). - */ -- serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1); -- serial_out(up, UART_OMAP_SCR, -+ uart_write(priv, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1); -+ uart_write(priv, UART_OMAP_SCR, - OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL); - -- sysc = serial_in(up, UART_OMAP_SYSC); -+ sysc = uart_read(priv, UART_OMAP_SYSC); - - /* softreset the UART */ - sysc |= OMAP_UART_SYSC_SOFTRESET; -- serial_out(up, UART_OMAP_SYSC, sysc); -+ uart_write(priv, UART_OMAP_SYSC, sysc); - - /* By experiments, 1us enough for reset complete on AM335x */ - do { - udelay(1); -- syss = serial_in(up, UART_OMAP_SYSS); -+ syss = uart_read(priv, UART_OMAP_SYSS); - } while (--timeout && !(syss & OMAP_UART_SYSS_RESETDONE)); - - if (!timeout) { -@@ -1602,23 +1611,10 @@ static int omap8250_soft_reset(struct device *dev) - static int omap8250_runtime_suspend(struct device *dev) - { - struct omap8250_priv *priv = dev_get_drvdata(dev); -- struct uart_8250_port *up; -+ struct uart_8250_port *up = NULL; - -- /* In case runtime-pm tries this before we are setup */ -- if (!priv) -- return 0; -- -- up = serial8250_get_port(priv->line); -- /* -- * When using 'no_console_suspend', the console UART must not be -- * suspended. Since driver suspend is managed by runtime suspend, -- * preventing runtime suspend (by returning error) will keep device -- * active during suspend. -- */ -- if (priv->is_suspending && !console_suspend_enabled) { -- if (uart_console(&up->port)) -- return -EBUSY; -- } -+ if (priv->line >= 0) -+ up = serial8250_get_port(priv->line); - - if (priv->habit & UART_ERRATA_CLOCK_DISABLE) { - int ret; -@@ -1627,13 +1623,15 @@ static int omap8250_runtime_suspend(struct device *dev) - if (ret) - return ret; - -- /* Restore to UART mode after reset (for wakeup) */ -- omap8250_update_mdr1(up, priv); -- /* Restore wakeup enable register */ -- serial_out(up, UART_OMAP_WER, priv->wer); -+ if (up) { -+ /* Restore to UART mode after reset (for wakeup) */ -+ omap8250_update_mdr1(up, priv); -+ /* Restore wakeup enable register */ -+ serial_out(up, UART_OMAP_WER, priv->wer); -+ } - } - -- if (up->dma && up->dma->rxchan) -+ if (up && up->dma && up->dma->rxchan) - omap_8250_rx_dma_flush(up); - - priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; -@@ -1645,25 +1643,21 @@ static int omap8250_runtime_suspend(struct device *dev) - static int omap8250_runtime_resume(struct device *dev) - { - struct omap8250_priv *priv = dev_get_drvdata(dev); -- struct uart_8250_port *up; -+ struct uart_8250_port *up = NULL; - -- /* In case runtime-pm tries this before we are setup */ -- if (!priv) -- return 0; -- -- up = serial8250_get_port(priv->line); -+ if (priv->line >= 0) -+ up = serial8250_get_port(priv->line); - -- if (omap8250_lost_context(up)) -+ if (up && omap8250_lost_context(up)) - omap8250_restore_regs(up); - -- if (up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) -+ if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) - omap_8250_rx_dma(up); - - priv->latency = priv->calc_latency; - schedule_work(&priv->qos_work); - return 0; - } --#endif - - #ifdef CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP - static int __init omap8250_console_fixup(void) -@@ -1706,17 +1700,17 @@ console_initcall(omap8250_console_fixup); - #endif - - static const struct dev_pm_ops omap8250_dev_pm_ops = { -- SET_SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume) -- SET_RUNTIME_PM_OPS(omap8250_runtime_suspend, -+ SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume) -+ RUNTIME_PM_OPS(omap8250_runtime_suspend, - omap8250_runtime_resume, NULL) -- .prepare = omap8250_prepare, -- .complete = omap8250_complete, -+ .prepare = pm_sleep_ptr(omap8250_prepare), -+ .complete = pm_sleep_ptr(omap8250_complete), - }; - - static struct platform_driver omap8250_platform_driver = { - .driver = { - .name = "omap8250", -- .pm = &omap8250_dev_pm_ops, -+ .pm = pm_ptr(&omap8250_dev_pm_ops), - .of_match_table = omap8250_dt_ids, - }, - .probe = omap8250_probe, -diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c -index 2cc5c68c8689f..d4e57f9017db9 100644 ---- a/drivers/tty/serial/serial_core.c -+++ b/drivers/tty/serial/serial_core.c -@@ -48,8 +48,6 @@ static struct lock_class_key port_lock_key; - */ - #define RS485_MAX_RTS_DELAY 100 /* msecs */ - --static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, -- const struct ktermios *old_termios); - static void uart_wait_until_sent(struct tty_struct *tty, int timeout); - static void uart_change_pm(struct uart_state *state, - enum uart_pm_state pm_state); -@@ -177,6 +175,52 @@ static void uart_port_dtr_rts(struct uart_port *uport, int raise) - uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); - } - -+/* Caller holds port mutex */ -+static void uart_change_line_settings(struct tty_struct *tty, struct uart_state *state, -+ const struct ktermios *old_termios) -+{ -+ struct uart_port *uport = uart_port_check(state); -+ struct ktermios *termios; -+ int hw_stopped; -+ -+ /* -+ * If we have no tty, termios, or the port does not exist, -+ * then we can't set the parameters for this port. -+ */ -+ if (!tty || uport->type == PORT_UNKNOWN) -+ return; -+ -+ termios = &tty->termios; -+ uport->ops->set_termios(uport, termios, old_termios); -+ -+ /* -+ * Set modem status enables based on termios cflag -+ */ -+ spin_lock_irq(&uport->lock); -+ if (termios->c_cflag & CRTSCTS) -+ uport->status |= UPSTAT_CTS_ENABLE; -+ else -+ uport->status &= ~UPSTAT_CTS_ENABLE; -+ -+ if (termios->c_cflag & CLOCAL) -+ uport->status &= ~UPSTAT_DCD_ENABLE; -+ else -+ uport->status |= UPSTAT_DCD_ENABLE; -+ -+ /* reset sw-assisted CTS flow control based on (possibly) new mode */ -+ hw_stopped = uport->hw_stopped; -+ uport->hw_stopped = uart_softcts_mode(uport) && -+ !(uport->ops->get_mctrl(uport) & TIOCM_CTS); -+ if (uport->hw_stopped) { -+ if (!hw_stopped) -+ uport->ops->stop_tx(uport); -+ } else { -+ if (hw_stopped) -+ __uart_start(tty); -+ } -+ spin_unlock_irq(&uport->lock); -+} -+ - /* - * Startup the port. This will be called once per open. All calls - * will be serialised by the per-port mutex. -@@ -232,7 +276,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, - /* - * Initialise the hardware port settings. - */ -- uart_change_speed(tty, state, NULL); -+ uart_change_line_settings(tty, state, NULL); - - /* - * Setup the RTS and DTR signals once the -@@ -485,52 +529,6 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) - } - EXPORT_SYMBOL(uart_get_divisor); - --/* Caller holds port mutex */ --static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, -- const struct ktermios *old_termios) --{ -- struct uart_port *uport = uart_port_check(state); -- struct ktermios *termios; -- int hw_stopped; -- -- /* -- * If we have no tty, termios, or the port does not exist, -- * then we can't set the parameters for this port. -- */ -- if (!tty || uport->type == PORT_UNKNOWN) -- return; -- -- termios = &tty->termios; -- uport->ops->set_termios(uport, termios, old_termios); -- -- /* -- * Set modem status enables based on termios cflag -- */ -- spin_lock_irq(&uport->lock); -- if (termios->c_cflag & CRTSCTS) -- uport->status |= UPSTAT_CTS_ENABLE; -- else -- uport->status &= ~UPSTAT_CTS_ENABLE; -- -- if (termios->c_cflag & CLOCAL) -- uport->status &= ~UPSTAT_DCD_ENABLE; -- else -- uport->status |= UPSTAT_DCD_ENABLE; -- -- /* reset sw-assisted CTS flow control based on (possibly) new mode */ -- hw_stopped = uport->hw_stopped; -- uport->hw_stopped = uart_softcts_mode(uport) && -- !(uport->ops->get_mctrl(uport) & TIOCM_CTS); -- if (uport->hw_stopped) { -- if (!hw_stopped) -- uport->ops->stop_tx(uport); -- } else { -- if (hw_stopped) -- __uart_start(tty); -- } -- spin_unlock_irq(&uport->lock); --} -- - static int uart_put_char(struct tty_struct *tty, unsigned char c) - { - struct uart_state *state = tty->driver_data; -@@ -994,7 +992,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, - current->comm, - tty_name(port->tty)); - } -- uart_change_speed(tty, state, NULL); -+ uart_change_line_settings(tty, state, NULL); - } - } else { - retval = uart_startup(tty, state, 1); -@@ -1389,12 +1387,18 @@ static void uart_set_rs485_termination(struct uart_port *port, - static int uart_rs485_config(struct uart_port *port) - { - struct serial_rs485 *rs485 = &port->rs485; -+ unsigned long flags; - int ret; - -+ if (!(rs485->flags & SER_RS485_ENABLED)) -+ return 0; -+ - uart_sanitize_serial_rs485(port, rs485); - uart_set_rs485_termination(port, rs485); - -+ spin_lock_irqsave(&port->lock, flags); - ret = port->rs485_config(port, NULL, rs485); -+ spin_unlock_irqrestore(&port->lock, flags); - if (ret) - memset(rs485, 0, sizeof(*rs485)); - -@@ -1656,7 +1660,7 @@ static void uart_set_termios(struct tty_struct *tty, - goto out; - } - -- uart_change_speed(tty, state, old_termios); -+ uart_change_line_settings(tty, state, old_termios); - /* reload cflag from termios; port driver may have overridden flags */ - cflag = tty->termios.c_cflag; - -@@ -2456,12 +2460,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) - ret = ops->startup(uport); - if (ret == 0) { - if (tty) -- uart_change_speed(tty, state, NULL); -+ uart_change_line_settings(tty, state, NULL); -+ uart_rs485_config(uport); - spin_lock_irq(&uport->lock); - if (!(uport->rs485.flags & SER_RS485_ENABLED)) - ops->set_mctrl(uport, uport->mctrl); -- else -- uart_rs485_config(uport); - ops->start_tx(uport); - spin_unlock_irq(&uport->lock); - tty_port_set_initialized(port, 1); -@@ -2570,10 +2573,10 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, - port->mctrl &= TIOCM_DTR; - if (!(port->rs485.flags & SER_RS485_ENABLED)) - port->ops->set_mctrl(port, port->mctrl); -- else -- uart_rs485_config(port); - spin_unlock_irqrestore(&port->lock, flags); - -+ uart_rs485_config(port); -+ - /* - * If this driver supports console, and it hasn't been - * successfully registered yet, try to re-register it. -diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c -index 832d3ba9368ff..8edd0375e0a8a 100644 ---- a/drivers/usb/misc/onboard_usb_hub.c -+++ b/drivers/usb/misc/onboard_usb_hub.c -@@ -329,6 +329,7 @@ static struct platform_driver onboard_hub_driver = { - - /************************** USB driver **************************/ - -+#define VENDOR_ID_GENESYS 0x05e3 - #define VENDOR_ID_MICROCHIP 0x0424 - #define VENDOR_ID_REALTEK 0x0bda - #define VENDOR_ID_TI 0x0451 -@@ -405,6 +406,10 @@ static void onboard_hub_usbdev_disconnect(struct usb_device *udev) - } - - static const struct usb_device_id onboard_hub_id_table[] = { -+ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 */ -+ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 */ -+ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0620) }, /* Genesys Logic GL3523 USB 3.1 */ -+ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2412) }, /* USB2412 USB 2.0 */ - { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 */ - { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 */ - { USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 */ -diff --git a/drivers/usb/misc/onboard_usb_hub.h b/drivers/usb/misc/onboard_usb_hub.h -index 2cde54b69eede..d023fb90b4118 100644 ---- a/drivers/usb/misc/onboard_usb_hub.h -+++ b/drivers/usb/misc/onboard_usb_hub.h -@@ -22,11 +22,23 @@ static const struct onboard_hub_pdata ti_tusb8041_data = { - .reset_us = 3000, - }; - -+static const struct onboard_hub_pdata genesys_gl850g_data = { -+ .reset_us = 3, -+}; -+ -+static const struct onboard_hub_pdata genesys_gl852g_data = { -+ .reset_us = 50, -+}; -+ - static const struct of_device_id onboard_hub_match[] = { -+ { .compatible = "usb424,2412", .data = µchip_usb424_data, }, - { .compatible = "usb424,2514", .data = µchip_usb424_data, }, - { .compatible = "usb424,2517", .data = µchip_usb424_data, }, - { .compatible = "usb451,8140", .data = &ti_tusb8041_data, }, - { .compatible = "usb451,8142", .data = &ti_tusb8041_data, }, -+ { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, }, -+ { .compatible = "usb5e3,610", .data = &genesys_gl852g_data, }, -+ { .compatible = "usb5e3,620", .data = &genesys_gl852g_data, }, - { .compatible = "usbbda,411", .data = &realtek_rts5411_data, }, - { .compatible = "usbbda,5411", .data = &realtek_rts5411_data, }, - { .compatible = "usbbda,414", .data = &realtek_rts5411_data, }, -diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c -index f13930b4534c1..b9dd714a3ae69 100644 ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -203,6 +203,9 @@ static void option_instat_callback(struct urb *urb); - #define DELL_PRODUCT_5829E_ESIM 0x81e4 - #define DELL_PRODUCT_5829E 0x81e6 - -+#define DELL_PRODUCT_FM101R 0x8213 -+#define DELL_PRODUCT_FM101R_ESIM 0x8215 -+ - #define KYOCERA_VENDOR_ID 0x0c88 - #define KYOCERA_PRODUCT_KPC650 0x17da - #define KYOCERA_PRODUCT_KPC680 0x180a -@@ -1108,6 +1111,8 @@ static const struct usb_device_id option_ids[] = { - .driver_info = RSVD(0) | RSVD(6) }, - { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM), - .driver_info = RSVD(0) | RSVD(6) }, -+ { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R, 0xff) }, -+ { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R_ESIM, 0xff) }, - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, -@@ -1290,6 +1295,7 @@ static const struct usb_device_id option_ids[] = { - .driver_info = NCTRL(0) | RSVD(3) }, - { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */ - .driver_info = NCTRL(0) }, -+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1035, 0xff) }, /* Telit LE910C4-WWX (ECM) */ - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), - .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, - { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1), -@@ -2262,6 +2268,7 @@ static const struct usb_device_id option_ids[] = { - { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ - { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, - { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) }, - { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, - { } /* Terminating entry */ -diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c -index 1a327eb3580b4..e08688844f1e1 100644 ---- a/fs/btrfs/ctree.c -+++ b/fs/btrfs/ctree.c -@@ -563,18 +563,30 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, - u64 search_start; - int ret; - -- if (test_bit(BTRFS_ROOT_DELETING, &root->state)) -- btrfs_err(fs_info, -- "COW'ing blocks on a fs root that's being dropped"); -- -- if (trans->transaction != fs_info->running_transaction) -- WARN(1, KERN_CRIT "trans %llu running %llu\n", -- trans->transid, -- fs_info->running_transaction->transid); -+ if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) { -+ btrfs_abort_transaction(trans, -EUCLEAN); -+ btrfs_crit(fs_info, -+ "attempt to COW block %llu on root %llu that is being deleted", -+ buf->start, btrfs_root_id(root)); -+ return -EUCLEAN; -+ } - -- if (trans->transid != fs_info->generation) -- WARN(1, KERN_CRIT "trans %llu running %llu\n", -- trans->transid, fs_info->generation); -+ /* -+ * COWing must happen through a running transaction, which always -+ * matches the current fs generation (it's a transaction with a state -+ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs -+ * into error state to prevent the commit of any transaction. -+ */ -+ if (unlikely(trans->transaction != fs_info->running_transaction || -+ trans->transid != fs_info->generation)) { -+ btrfs_abort_transaction(trans, -EUCLEAN); -+ btrfs_crit(fs_info, -+"unexpected transaction when attempting to COW block %llu on root %llu, transaction %llu running transaction %llu fs generation %llu", -+ buf->start, btrfs_root_id(root), trans->transid, -+ fs_info->running_transaction->transid, -+ fs_info->generation); -+ return -EUCLEAN; -+ } - - if (!should_cow_block(trans, root, buf)) { - *cow_ret = buf; -@@ -686,8 +698,22 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, - int progress_passed = 0; - struct btrfs_disk_key disk_key; - -- WARN_ON(trans->transaction != fs_info->running_transaction); -- WARN_ON(trans->transid != fs_info->generation); -+ /* -+ * COWing must happen through a running transaction, which always -+ * matches the current fs generation (it's a transaction with a state -+ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs -+ * into error state to prevent the commit of any transaction. -+ */ -+ if (unlikely(trans->transaction != fs_info->running_transaction || -+ trans->transid != fs_info->generation)) { -+ btrfs_abort_transaction(trans, -EUCLEAN); -+ btrfs_crit(fs_info, -+"unexpected transaction when attempting to reallocate parent %llu for root %llu, transaction %llu running transaction %llu fs generation %llu", -+ parent->start, btrfs_root_id(root), trans->transid, -+ fs_info->running_transaction->transid, -+ fs_info->generation); -+ return -EUCLEAN; -+ } - - parent_nritems = btrfs_header_nritems(parent); - blocksize = fs_info->nodesize; -diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c -index 36a3debe94930..e08e3852c4788 100644 ---- a/fs/btrfs/delayed-ref.c -+++ b/fs/btrfs/delayed-ref.c -@@ -141,24 +141,17 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans) - * Transfer bytes to our delayed refs rsv - * - * @fs_info: the filesystem -- * @src: source block rsv to transfer from - * @num_bytes: number of bytes to transfer - * -- * This transfers up to the num_bytes amount from the src rsv to the -+ * This transfers up to the num_bytes amount, previously reserved, to the - * delayed_refs_rsv. Any extra bytes are returned to the space info. - */ - void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, -- struct btrfs_block_rsv *src, - u64 num_bytes) - { - struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv; - u64 to_free = 0; - -- spin_lock(&src->lock); -- src->reserved -= num_bytes; -- src->size -= num_bytes; -- spin_unlock(&src->lock); -- - spin_lock(&delayed_refs_rsv->lock); - if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) { - u64 delta = delayed_refs_rsv->size - -diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h -index d6304b690ec4a..712a6315e956b 100644 ---- a/fs/btrfs/delayed-ref.h -+++ b/fs/btrfs/delayed-ref.h -@@ -383,7 +383,6 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans); - int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, - enum btrfs_reserve_flush_enum flush); - void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, -- struct btrfs_block_rsv *src, - u64 num_bytes); - int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans); - bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); -diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c -index 08ff10a81cb90..2a7c9088fe1f8 100644 ---- a/fs/btrfs/extent-tree.c -+++ b/fs/btrfs/extent-tree.c -@@ -1663,12 +1663,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, - parent = ref->parent; - ref_root = ref->root; - -- if (node->ref_mod != 1) { -+ if (unlikely(node->ref_mod != 1)) { - btrfs_err(trans->fs_info, -- "btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu", -+ "btree block %llu has %d references rather than 1: action %d ref_root %llu parent %llu", - node->bytenr, node->ref_mod, node->action, ref_root, - parent); -- return -EIO; -+ return -EUCLEAN; - } - if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { - BUG_ON(!extent_op || !extent_op->update_flags); -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index 9e323420c96d3..9474265ee7ea3 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -3869,7 +3869,7 @@ static void get_block_group_info(struct list_head *groups_list, - static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info, - void __user *arg) - { -- struct btrfs_ioctl_space_args space_args; -+ struct btrfs_ioctl_space_args space_args = { 0 }; - struct btrfs_ioctl_space_info space; - struct btrfs_ioctl_space_info *dest; - struct btrfs_ioctl_space_info *dest_orig; -@@ -5223,7 +5223,7 @@ static int _btrfs_ioctl_send(struct inode *inode, void __user *argp, bool compat - - if (compat) { - #if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT) -- struct btrfs_ioctl_send_args_32 args32; -+ struct btrfs_ioctl_send_args_32 args32 = { 0 }; - - ret = copy_from_user(&args32, argp, sizeof(args32)); - if (ret) -diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c -index 1193214ba8c10..60db4c3b82fa1 100644 ---- a/fs/btrfs/transaction.c -+++ b/fs/btrfs/transaction.c -@@ -614,14 +614,14 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, - reloc_reserved = true; - } - -- ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes, flush); -+ ret = btrfs_reserve_metadata_bytes(fs_info, rsv, num_bytes, flush); - if (ret) - goto reserve_fail; - if (delayed_refs_bytes) { -- btrfs_migrate_to_delayed_refs_rsv(fs_info, rsv, -- delayed_refs_bytes); -+ btrfs_migrate_to_delayed_refs_rsv(fs_info, delayed_refs_bytes); - num_bytes -= delayed_refs_bytes; - } -+ btrfs_block_rsv_add_bytes(rsv, num_bytes, true); - - if (rsv->space_info->force_alloc) - do_chunk_alloc = true; -diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c -index c03ff6a5a7f6b..7c33b28c02aeb 100644 ---- a/fs/btrfs/tree-log.c -+++ b/fs/btrfs/tree-log.c -@@ -4767,7 +4767,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, - struct extent_buffer *leaf; - int slot; - int ins_nr = 0; -- int start_slot; -+ int start_slot = 0; - int ret; - - if (!(inode->flags & BTRFS_INODE_PREALLOC)) -diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c -index a40ebd2321d01..e62b4c139a72d 100644 ---- a/fs/btrfs/volumes.c -+++ b/fs/btrfs/volumes.c -@@ -5139,7 +5139,7 @@ static void init_alloc_chunk_ctl_policy_regular( - ASSERT(space_info); - - ctl->max_chunk_size = READ_ONCE(space_info->chunk_size); -- ctl->max_stripe_size = ctl->max_chunk_size; -+ ctl->max_stripe_size = min_t(u64, ctl->max_chunk_size, SZ_1G); - - if (ctl->type & BTRFS_BLOCK_GROUP_SYSTEM) - ctl->devs_max = min_t(int, ctl->devs_max, BTRFS_MAX_DEVS_SYS_CHUNK); -diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c -index d387708977a50..a5c31a479aacc 100644 ---- a/fs/fs-writeback.c -+++ b/fs/fs-writeback.c -@@ -1522,10 +1522,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb, - - if (wbc->pages_skipped) { - /* -- * writeback is not making progress due to locked -- * buffers. Skip this inode for now. -+ * Writeback is not making progress due to locked buffers. -+ * Skip this inode for now. Although having skipped pages -+ * is odd for clean inodes, it can happen for some -+ * filesystems so handle that gracefully. - */ -- redirty_tail_locked(inode, wb); -+ if (inode->i_state & I_DIRTY_ALL) -+ redirty_tail_locked(inode, wb); -+ else -+ inode_cgwb_move_to_attached(inode, wb); - return; - } - -diff --git a/fs/namei.c b/fs/namei.c -index 4248647f1ab24..5e1c2ab2ae709 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -187,7 +187,7 @@ getname_flags(const char __user *filename, int flags, int *empty) - } - } - -- result->refcnt = 1; -+ atomic_set(&result->refcnt, 1); - /* The empty path is special. */ - if (unlikely(!len)) { - if (empty) -@@ -248,7 +248,7 @@ getname_kernel(const char * filename) - memcpy((char *)result->name, filename, len); - result->uptr = NULL; - result->aname = NULL; -- result->refcnt = 1; -+ atomic_set(&result->refcnt, 1); - audit_getname(result); - - return result; -@@ -259,9 +259,10 @@ void putname(struct filename *name) - if (IS_ERR(name)) - return; - -- BUG_ON(name->refcnt <= 0); -+ if (WARN_ON_ONCE(!atomic_read(&name->refcnt))) -+ return; - -- if (--name->refcnt > 0) -+ if (!atomic_dec_and_test(&name->refcnt)) - return; - - if (name->name != name->iname) { -diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c -index 5c69a6e9ab3e1..81bbafab18a99 100644 ---- a/fs/nfs/flexfilelayout/flexfilelayout.c -+++ b/fs/nfs/flexfilelayout/flexfilelayout.c -@@ -2520,9 +2520,9 @@ ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo, - return i; - } - --static int --ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) -+static int ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) - { -+ struct pnfs_layout_hdr *lo; - struct nfs4_flexfile_layout *ff_layout; - const int dev_count = PNFS_LAYOUTSTATS_MAXDEV; - -@@ -2533,11 +2533,14 @@ ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) - return -ENOMEM; - - spin_lock(&args->inode->i_lock); -- ff_layout = FF_LAYOUT_FROM_HDR(NFS_I(args->inode)->layout); -- args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr, -- &args->devinfo[0], -- dev_count, -- NFS4_FF_OP_LAYOUTSTATS); -+ lo = NFS_I(args->inode)->layout; -+ if (lo && pnfs_layout_is_valid(lo)) { -+ ff_layout = FF_LAYOUT_FROM_HDR(lo); -+ args->num_dev = ff_layout_mirror_prepare_stats( -+ &ff_layout->generic_hdr, &args->devinfo[0], dev_count, -+ NFS4_FF_OP_LAYOUTSTATS); -+ } else -+ args->num_dev = 0; - spin_unlock(&args->inode->i_lock); - if (!args->num_dev) { - kfree(args->devinfo); -diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c -index d903ea10410c2..5a8fe0e57a3d3 100644 ---- a/fs/nfs/nfs42proc.c -+++ b/fs/nfs/nfs42proc.c -@@ -81,7 +81,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, - if (status == 0) { - if (nfs_should_remove_suid(inode)) { - spin_lock(&inode->i_lock); -- nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE); -+ nfs_set_cache_invalid(inode, -+ NFS_INO_REVAL_FORCED | NFS_INO_INVALID_MODE); - spin_unlock(&inode->i_lock); - } - status = nfs_post_op_update_inode_force_wcc(inode, -diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index e1297c6bcfbe2..5cf53def987e5 100644 ---- a/fs/nfs/nfs4proc.c -+++ b/fs/nfs/nfs4proc.c -@@ -8875,8 +8875,6 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre - /* Save the EXCHANGE_ID verifier session trunk tests */ - memcpy(clp->cl_confirm.data, argp->verifier.data, - sizeof(clp->cl_confirm.data)); -- if (resp->flags & EXCHGID4_FLAG_USE_PNFS_DS) -- set_bit(NFS_CS_DS, &clp->cl_flags); - out: - trace_nfs4_exchange_id(clp, status); - rpc_put_task(task); -diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c -index a5db5158c6345..1ffb1068216b6 100644 ---- a/fs/nfs/pnfs.c -+++ b/fs/nfs/pnfs.c -@@ -2634,31 +2634,44 @@ pnfs_should_return_unused_layout(struct pnfs_layout_hdr *lo, - return mode == 0; - } - --static int --pnfs_layout_return_unused_byserver(struct nfs_server *server, void *data) -+static int pnfs_layout_return_unused_byserver(struct nfs_server *server, -+ void *data) - { - const struct pnfs_layout_range *range = data; -+ const struct cred *cred; - struct pnfs_layout_hdr *lo; - struct inode *inode; -+ nfs4_stateid stateid; -+ enum pnfs_iomode iomode; -+ - restart: - rcu_read_lock(); - list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) { -- if (!pnfs_layout_can_be_returned(lo) || -+ inode = lo->plh_inode; -+ if (!inode || !pnfs_layout_can_be_returned(lo) || - test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) - continue; -- inode = lo->plh_inode; - spin_lock(&inode->i_lock); -- if (!pnfs_should_return_unused_layout(lo, range)) { -+ if (!lo->plh_inode || -+ !pnfs_should_return_unused_layout(lo, range)) { - spin_unlock(&inode->i_lock); - continue; - } -+ pnfs_get_layout_hdr(lo); -+ pnfs_set_plh_return_info(lo, range->iomode, 0); -+ if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, -+ range, 0) != 0 || -+ !pnfs_prepare_layoutreturn(lo, &stateid, &cred, &iomode)) { -+ spin_unlock(&inode->i_lock); -+ rcu_read_unlock(); -+ pnfs_put_layout_hdr(lo); -+ cond_resched(); -+ goto restart; -+ } - spin_unlock(&inode->i_lock); -- inode = pnfs_grab_inode_layout_hdr(lo); -- if (!inode) -- continue; - rcu_read_unlock(); -- pnfs_mark_layout_for_return(inode, range); -- iput(inode); -+ pnfs_send_layoutreturn(lo, &stateid, &cred, iomode, false); -+ pnfs_put_layout_hdr(lo); - cond_resched(); - goto restart; - } -diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c -index 829b62d3bb889..9c0fc3a29d0c9 100644 ---- a/fs/ntfs3/fsntfs.c -+++ b/fs/ntfs3/fsntfs.c -@@ -2428,10 +2428,12 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim) - { - CLST end, i, zone_len, zlen; - struct wnd_bitmap *wnd = &sbi->used.bitmap; -+ bool dirty = false; - - down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS); - if (!wnd_is_used(wnd, lcn, len)) { -- ntfs_set_state(sbi, NTFS_DIRTY_ERROR); -+ /* mark volume as dirty out of wnd->rw_lock */ -+ dirty = true; - - end = lcn + len; - len = 0; -@@ -2485,6 +2487,8 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim) - - out: - up_write(&wnd->rw_lock); -+ if (dirty) -+ ntfs_set_state(sbi, NTFS_DIRTY_ERROR); - } - - /* -diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c -index 495cfb37962fa..b89a33f5761ef 100644 ---- a/fs/ntfs3/index.c -+++ b/fs/ntfs3/index.c -@@ -729,6 +729,9 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx, - u32 total = le32_to_cpu(hdr->total); - u16 offs[128]; - -+ if (unlikely(!cmp)) -+ return NULL; -+ - fill_table: - if (end > total) - return NULL; -diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c -index f5d3092f478c5..df15e00c2a3a0 100644 ---- a/fs/ntfs3/xattr.c -+++ b/fs/ntfs3/xattr.c -@@ -209,7 +209,8 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, - size = le32_to_cpu(info->size); - - /* Enumerate all xattrs. */ -- for (ret = 0, off = 0; off < size; off += ea_size) { -+ ret = 0; -+ for (off = 0; off + sizeof(struct EA_FULL) < size; off += ea_size) { - ea = Add2Ptr(ea_all, off); - ea_size = unpacked_ea_size(ea); - -@@ -217,6 +218,10 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, - break; - - if (buffer) { -+ /* Check if we can use field ea->name */ -+ if (off + ea_size > size) -+ break; -+ - if (ret + ea->name_len + 1 > bytes_per_buffer) { - err = -ERANGE; - goto out; -diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c -index e6d711f42607b..86d4b6975dbcb 100644 ---- a/fs/overlayfs/copy_up.c -+++ b/fs/overlayfs/copy_up.c -@@ -300,7 +300,7 @@ static int ovl_set_timestamps(struct ovl_fs *ofs, struct dentry *upperdentry, - { - struct iattr attr = { - .ia_valid = -- ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, -+ ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_CTIME, - .ia_atime = stat->atime, - .ia_mtime = stat->mtime, - }; -diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h -index 1c2bde0ead736..678f741a7b330 100644 ---- a/include/linux/fprobe.h -+++ b/include/linux/fprobe.h -@@ -13,6 +13,8 @@ - * @nmissed: The counter for missing events. - * @flags: The status flag. - * @rethook: The rethook data structure. (internal data) -+ * @entry_data_size: The private data storage size. -+ * @nr_maxactive: The max number of active functions. - * @entry_handler: The callback function for function entry. - * @exit_handler: The callback function for function exit. - */ -@@ -29,9 +31,13 @@ struct fprobe { - unsigned long nmissed; - unsigned int flags; - struct rethook *rethook; -+ size_t entry_data_size; -+ int nr_maxactive; - -- void (*entry_handler)(struct fprobe *fp, unsigned long entry_ip, struct pt_regs *regs); -- void (*exit_handler)(struct fprobe *fp, unsigned long entry_ip, struct pt_regs *regs); -+ void (*entry_handler)(struct fprobe *fp, unsigned long entry_ip, -+ struct pt_regs *regs, void *entry_data); -+ void (*exit_handler)(struct fprobe *fp, unsigned long entry_ip, -+ struct pt_regs *regs, void *entry_data); - }; - - /* This fprobe is soft-disabled. */ -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 26ea1a0a59a10..dc745317e1bdb 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -2735,7 +2735,7 @@ struct audit_names; - struct filename { - const char *name; /* pointer to actual string */ - const __user char *uptr; /* original userland pointer */ -- int refcnt; -+ atomic_t refcnt; - struct audit_names *aname; - const char iname[]; - }; -diff --git a/include/linux/hid.h b/include/linux/hid.h -index 784dd6b6046eb..58f5ab29c11a7 100644 ---- a/include/linux/hid.h -+++ b/include/linux/hid.h -@@ -312,6 +312,7 @@ struct hid_item { - #define HID_DG_LATENCYMODE 0x000d0060 - - #define HID_BAT_ABSOLUTESTATEOFCHARGE 0x00850065 -+#define HID_BAT_CHARGING 0x00850044 - - #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076 - -@@ -612,6 +613,7 @@ struct hid_device { /* device report descriptor */ - __s32 battery_max; - __s32 battery_report_type; - __s32 battery_report_id; -+ __s32 battery_charge_status; - enum hid_battery_status battery_status; - bool battery_avoid_query; - ktime_t battery_ratelimit_time; -diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h -index f0ec8a5e5a7a9..9d3bd6379eb87 100644 ---- a/include/linux/iio/iio.h -+++ b/include/linux/iio/iio.h -@@ -629,6 +629,8 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev, - int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); - int iio_device_claim_direct_mode(struct iio_dev *indio_dev); - void iio_device_release_direct_mode(struct iio_dev *indio_dev); -+int iio_device_claim_buffer_mode(struct iio_dev *indio_dev); -+void iio_device_release_buffer_mode(struct iio_dev *indio_dev); - - extern struct bus_type iio_bus_type; - -diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h -index 649faac31ddb1..0cd33be7142ad 100644 ---- a/include/linux/kallsyms.h -+++ b/include/linux/kallsyms.h -@@ -69,6 +69,8 @@ static inline void *dereference_symbol_descriptor(void *ptr) - int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, - unsigned long), - void *data); -+int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long), -+ const char *name, void *data); - - /* Lookup the address for a symbol. Returns 0 if not found. */ - unsigned long kallsyms_lookup_name(const char *name); -@@ -168,6 +170,12 @@ static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct - { - return -EOPNOTSUPP; - } -+ -+static inline int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long), -+ const char *name, void *data) -+{ -+ return -EOPNOTSUPP; -+} - #endif /*CONFIG_KALLSYMS*/ - - static inline void print_ip_sym(const char *loglvl, unsigned long ip) -diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h -index 63fae3c7ae430..1578a4de1f3cb 100644 ---- a/include/linux/perf_event.h -+++ b/include/linux/perf_event.h -@@ -694,6 +694,7 @@ struct perf_event { - /* The cumulative AND of all event_caps for events in this group. */ - int group_caps; - -+ unsigned int group_generation; - struct perf_event *group_leader; - struct pmu *pmu; - void *pmu_private; -diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h -index ddbcbf9ccb2ce..583aebd8c1e01 100644 ---- a/include/net/bluetooth/hci_core.h -+++ b/include/net/bluetooth/hci_core.h -@@ -348,7 +348,7 @@ struct hci_dev { - struct list_head list; - struct mutex lock; - -- char name[8]; -+ const char *name; - unsigned long flags; - __u16 id; - __u8 bus; -diff --git a/include/net/bluetooth/hci_mon.h b/include/net/bluetooth/hci_mon.h -index 2d5fcda1bcd05..082f89531b889 100644 ---- a/include/net/bluetooth/hci_mon.h -+++ b/include/net/bluetooth/hci_mon.h -@@ -56,7 +56,7 @@ struct hci_mon_new_index { - __u8 type; - __u8 bus; - bdaddr_t bdaddr; -- char name[8]; -+ char name[8] __nonstring; - } __packed; - #define HCI_MON_NEW_INDEX_SIZE 16 - -diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h -index f0c13864180e2..15de07d365405 100644 ---- a/include/net/ip_fib.h -+++ b/include/net/ip_fib.h -@@ -154,6 +154,7 @@ struct fib_info { - int fib_nhs; - bool fib_nh_is_v6; - bool nh_updated; -+ bool pfsrc_removed; - struct nexthop *nh; - struct rcu_head rcu; - struct fib_nh fib_nh[]; -diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h -index bd7c3be4af5d7..423b52eca908d 100644 ---- a/include/net/netns/xfrm.h -+++ b/include/net/netns/xfrm.h -@@ -50,6 +50,7 @@ struct netns_xfrm { - struct list_head policy_all; - struct hlist_head *policy_byidx; - unsigned int policy_idx_hmask; -+ unsigned int idx_generator; - struct hlist_head policy_inexact[XFRM_POLICY_MAX]; - struct xfrm_policy_hash policy_bydst[XFRM_POLICY_MAX]; - unsigned int policy_count[XFRM_POLICY_MAX * 2]; -diff --git a/include/net/sock.h b/include/net/sock.h -index fe695e8bfe289..a1fcbb2a8a2ce 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -333,7 +333,7 @@ struct sk_filter; - * @sk_cgrp_data: cgroup data for this cgroup - * @sk_memcg: this socket's memory cgroup association - * @sk_write_pending: a write to stream socket waits to start -- * @sk_wait_pending: number of threads blocked on this socket -+ * @sk_disconnects: number of disconnect operations performed on this sock - * @sk_state_change: callback to indicate change in the state of the sock - * @sk_data_ready: callback to indicate there is data to be processed - * @sk_write_space: callback to indicate there is bf sending space available -@@ -426,7 +426,7 @@ struct sock { - unsigned int sk_napi_id; - #endif - int sk_rcvbuf; -- int sk_wait_pending; -+ int sk_disconnects; - - struct sk_filter __rcu *sk_filter; - union { -@@ -1185,8 +1185,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) - } - - #define sk_wait_event(__sk, __timeo, __condition, __wait) \ -- ({ int __rc; \ -- __sk->sk_wait_pending++; \ -+ ({ int __rc, __dis = __sk->sk_disconnects; \ - release_sock(__sk); \ - __rc = __condition; \ - if (!__rc) { \ -@@ -1196,8 +1195,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) - } \ - sched_annotate_sleep(); \ - lock_sock(__sk); \ -- __sk->sk_wait_pending--; \ -- __rc = __condition; \ -+ __rc = __dis == __sk->sk_disconnects ? __condition : -EPIPE; \ - __rc; \ - }) - -diff --git a/include/net/tcp.h b/include/net/tcp.h -index 9ebb54122bb71..548c75c8a34c7 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -141,6 +141,9 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); - #define TCP_RTO_MAX ((unsigned)(120*HZ)) - #define TCP_RTO_MIN ((unsigned)(HZ/5)) - #define TCP_TIMEOUT_MIN (2U) /* Min timeout for TCP timers in jiffies */ -+ -+#define TCP_TIMEOUT_MIN_US (2*USEC_PER_MSEC) /* Min TCP timeout in microsecs */ -+ - #define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC6298 2.1 initial RTO value */ - #define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value, now - * used as a fallback RTO for the -diff --git a/include/trace/events/neigh.h b/include/trace/events/neigh.h -index 5eaa1fa991715..833143d0992e0 100644 ---- a/include/trace/events/neigh.h -+++ b/include/trace/events/neigh.h -@@ -39,7 +39,6 @@ TRACE_EVENT(neigh_create, - ), - - TP_fast_assign( -- struct in6_addr *pin6; - __be32 *p32; - - __entry->family = tbl->family; -@@ -47,7 +46,6 @@ TRACE_EVENT(neigh_create, - __entry->entries = atomic_read(&tbl->gc_entries); - __entry->created = n != NULL; - __entry->gc_exempt = exempt_from_gc; -- pin6 = (struct in6_addr *)__entry->primary_key6; - p32 = (__be32 *)__entry->primary_key4; - - if (tbl->family == AF_INET) -@@ -57,6 +55,8 @@ TRACE_EVENT(neigh_create, - - #if IS_ENABLED(CONFIG_IPV6) - if (tbl->family == AF_INET6) { -+ struct in6_addr *pin6; -+ - pin6 = (struct in6_addr *)__entry->primary_key6; - *pin6 = *(struct in6_addr *)pkey; - } -diff --git a/kernel/auditsc.c b/kernel/auditsc.c -index a2240f54fc224..c5f41fc75d543 100644 ---- a/kernel/auditsc.c -+++ b/kernel/auditsc.c -@@ -2208,7 +2208,7 @@ __audit_reusename(const __user char *uptr) - if (!n->name) - continue; - if (n->name->uptr == uptr) { -- n->name->refcnt++; -+ atomic_inc(&n->name->refcnt); - return n->name; - } - } -@@ -2237,7 +2237,7 @@ void __audit_getname(struct filename *name) - n->name = name; - n->name_len = AUDIT_NAME_FULL; - name->aname = n; -- name->refcnt++; -+ atomic_inc(&name->refcnt); - } - - static inline int audit_copy_fcaps(struct audit_names *name, -@@ -2369,7 +2369,7 @@ out_alloc: - return; - if (name) { - n->name = name; -- name->refcnt++; -+ atomic_inc(&name->refcnt); - } - - out: -@@ -2496,7 +2496,7 @@ void __audit_inode_child(struct inode *parent, - if (found_parent) { - found_child->name = found_parent->name; - found_child->name_len = AUDIT_NAME_FULL; -- found_child->name->refcnt++; -+ atomic_inc(&found_child->name->refcnt); - } - } - -diff --git a/kernel/events/core.c b/kernel/events/core.c -index db1065daabb62..2b8315a948a2c 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -1962,6 +1962,7 @@ static void perf_group_attach(struct perf_event *event) - - list_add_tail(&event->sibling_list, &group_leader->sibling_list); - group_leader->nr_siblings++; -+ group_leader->group_generation++; - - perf_event__header_size(group_leader); - -@@ -2156,6 +2157,7 @@ static void perf_group_detach(struct perf_event *event) - if (leader != event) { - list_del_init(&event->sibling_list); - event->group_leader->nr_siblings--; -+ event->group_leader->group_generation++; - goto out; - } - -@@ -5279,7 +5281,7 @@ static int __perf_read_group_add(struct perf_event *leader, - u64 read_format, u64 *values) - { - struct perf_event_context *ctx = leader->ctx; -- struct perf_event *sub; -+ struct perf_event *sub, *parent; - unsigned long flags; - int n = 1; /* skip @nr */ - int ret; -@@ -5289,6 +5291,33 @@ static int __perf_read_group_add(struct perf_event *leader, - return ret; - - raw_spin_lock_irqsave(&ctx->lock, flags); -+ /* -+ * Verify the grouping between the parent and child (inherited) -+ * events is still in tact. -+ * -+ * Specifically: -+ * - leader->ctx->lock pins leader->sibling_list -+ * - parent->child_mutex pins parent->child_list -+ * - parent->ctx->mutex pins parent->sibling_list -+ * -+ * Because parent->ctx != leader->ctx (and child_list nests inside -+ * ctx->mutex), group destruction is not atomic between children, also -+ * see perf_event_release_kernel(). Additionally, parent can grow the -+ * group. -+ * -+ * Therefore it is possible to have parent and child groups in a -+ * different configuration and summing over such a beast makes no sense -+ * what so ever. -+ * -+ * Reject this. -+ */ -+ parent = leader->parent; -+ if (parent && -+ (parent->group_generation != leader->group_generation || -+ parent->nr_siblings != leader->nr_siblings)) { -+ ret = -ECHILD; -+ goto unlock; -+ } - - /* - * Since we co-schedule groups, {enabled,running} times of siblings -@@ -5322,8 +5351,9 @@ static int __perf_read_group_add(struct perf_event *leader, - values[n++] = atomic64_read(&sub->lost_samples); - } - -+unlock: - raw_spin_unlock_irqrestore(&ctx->lock, flags); -- return 0; -+ return ret; - } - - static int perf_read_group(struct perf_event *event, -@@ -5342,10 +5372,6 @@ static int perf_read_group(struct perf_event *event, - - values[0] = 1 + leader->nr_siblings; - -- /* -- * By locking the child_mutex of the leader we effectively -- * lock the child list of all siblings.. XXX explain how. -- */ - mutex_lock(&leader->child_mutex); - - ret = __perf_read_group_add(leader, read_format, values); -@@ -13267,6 +13293,7 @@ static int inherit_group(struct perf_event *parent_event, - !perf_get_aux_event(child_ctr, leader)) - return -EINVAL; - } -+ leader->group_generation = parent_event->group_generation; - return 0; - } - -diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c -index ad3cccb0970f8..824bcc7b5dbc3 100644 ---- a/kernel/kallsyms.c -+++ b/kernel/kallsyms.c -@@ -197,6 +197,16 @@ static int compare_symbol_name(const char *name, char *namebuf) - return strcmp(name, namebuf); - } - -+static unsigned int get_symbol_seq(int index) -+{ -+ unsigned int i, seq = 0; -+ -+ for (i = 0; i < 3; i++) -+ seq = (seq << 8) | kallsyms_seqs_of_names[3 * index + i]; -+ -+ return seq; -+} -+ - static int kallsyms_lookup_names(const char *name, - unsigned int *start, - unsigned int *end) -@@ -211,7 +221,7 @@ static int kallsyms_lookup_names(const char *name, - - while (low <= high) { - mid = low + (high - low) / 2; -- seq = kallsyms_seqs_of_names[mid]; -+ seq = get_symbol_seq(mid); - off = get_symbol_offset(seq); - kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); - ret = compare_symbol_name(name, namebuf); -@@ -228,7 +238,7 @@ static int kallsyms_lookup_names(const char *name, - - low = mid; - while (low) { -- seq = kallsyms_seqs_of_names[low - 1]; -+ seq = get_symbol_seq(low - 1); - off = get_symbol_offset(seq); - kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); - if (compare_symbol_name(name, namebuf)) -@@ -240,7 +250,7 @@ static int kallsyms_lookup_names(const char *name, - if (end) { - high = mid; - while (high < kallsyms_num_syms - 1) { -- seq = kallsyms_seqs_of_names[high + 1]; -+ seq = get_symbol_seq(high + 1); - off = get_symbol_offset(seq); - kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); - if (compare_symbol_name(name, namebuf)) -@@ -265,7 +275,7 @@ unsigned long kallsyms_lookup_name(const char *name) - - ret = kallsyms_lookup_names(name, &i, NULL); - if (!ret) -- return kallsyms_sym_address(kallsyms_seqs_of_names[i]); -+ return kallsyms_sym_address(get_symbol_seq(i)); - - return module_kallsyms_lookup_name(name); - } -@@ -293,6 +303,24 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, - return 0; - } - -+int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long), -+ const char *name, void *data) -+{ -+ int ret; -+ unsigned int i, start, end; -+ -+ ret = kallsyms_lookup_names(name, &start, &end); -+ if (ret) -+ return 0; -+ -+ for (i = start; !ret && i <= end; i++) { -+ ret = fn(data, kallsyms_sym_address(get_symbol_seq(i))); -+ cond_resched(); -+ } -+ -+ return ret; -+} -+ - static unsigned long get_symbol_pos(unsigned long addr, - unsigned long *symbolsize, - unsigned long *offset) -diff --git a/kernel/kallsyms_internal.h b/kernel/kallsyms_internal.h -index a04b7a5cb1e3e..27fabdcc40f57 100644 ---- a/kernel/kallsyms_internal.h -+++ b/kernel/kallsyms_internal.h -@@ -26,6 +26,6 @@ extern const char kallsyms_token_table[] __weak; - extern const u16 kallsyms_token_index[] __weak; - - extern const unsigned int kallsyms_markers[] __weak; --extern const unsigned int kallsyms_seqs_of_names[] __weak; -+extern const u8 kallsyms_seqs_of_names[] __weak; - - #endif // LINUX_KALLSYMS_INTERNAL_H_ -diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c -index 1207c78f85c11..853a07618a3cf 100644 ---- a/kernel/sched/cpufreq_schedutil.c -+++ b/kernel/sched/cpufreq_schedutil.c -@@ -345,7 +345,8 @@ static void sugov_update_single_freq(struct update_util_data *hook, u64 time, - * Except when the rq is capped by uclamp_max. - */ - if (!uclamp_rq_is_capped(cpu_rq(sg_cpu->cpu)) && -- sugov_cpu_is_busy(sg_cpu) && next_f < sg_policy->next_freq) { -+ sugov_cpu_is_busy(sg_cpu) && next_f < sg_policy->next_freq && -+ !sg_policy->need_freq_update) { - next_f = sg_policy->next_freq; - - /* Restore cached freq as next_freq has changed */ -diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c -index 8c77c54e6348b..f4a494a457c52 100644 ---- a/kernel/trace/bpf_trace.c -+++ b/kernel/trace/bpf_trace.c -@@ -2646,7 +2646,7 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link, - - static void - kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip, -- struct pt_regs *regs) -+ struct pt_regs *regs, void *data) - { - struct bpf_kprobe_multi_link *link; - -diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c -index 1322247ce6488..f386d6bd8e0e3 100644 ---- a/kernel/trace/fprobe.c -+++ b/kernel/trace/fprobe.c -@@ -17,14 +17,16 @@ - struct fprobe_rethook_node { - struct rethook_node node; - unsigned long entry_ip; -+ char data[]; - }; - - static void fprobe_handler(unsigned long ip, unsigned long parent_ip, - struct ftrace_ops *ops, struct ftrace_regs *fregs) - { - struct fprobe_rethook_node *fpr; -- struct rethook_node *rh; -+ struct rethook_node *rh = NULL; - struct fprobe *fp; -+ void *entry_data = NULL; - int bit; - - fp = container_of(ops, struct fprobe, ops); -@@ -37,9 +39,6 @@ static void fprobe_handler(unsigned long ip, unsigned long parent_ip, - return; - } - -- if (fp->entry_handler) -- fp->entry_handler(fp, ip, ftrace_get_regs(fregs)); -- - if (fp->exit_handler) { - rh = rethook_try_get(fp->rethook); - if (!rh) { -@@ -48,9 +47,16 @@ static void fprobe_handler(unsigned long ip, unsigned long parent_ip, - } - fpr = container_of(rh, struct fprobe_rethook_node, node); - fpr->entry_ip = ip; -- rethook_hook(rh, ftrace_get_regs(fregs), true); -+ if (fp->entry_data_size) -+ entry_data = fpr->data; - } - -+ if (fp->entry_handler) -+ fp->entry_handler(fp, ip, ftrace_get_regs(fregs), entry_data); -+ -+ if (rh) -+ rethook_hook(rh, ftrace_get_regs(fregs), true); -+ - out: - ftrace_test_recursion_unlock(bit); - } -@@ -81,7 +87,8 @@ static void fprobe_exit_handler(struct rethook_node *rh, void *data, - - fpr = container_of(rh, struct fprobe_rethook_node, node); - -- fp->exit_handler(fp, fpr->entry_ip, regs); -+ fp->exit_handler(fp, fpr->entry_ip, regs, -+ fp->entry_data_size ? (void *)fpr->data : NULL); - } - NOKPROBE_SYMBOL(fprobe_exit_handler); - -@@ -127,7 +134,7 @@ static int fprobe_init_rethook(struct fprobe *fp, int num) - { - int i, size; - -- if (num < 0) -+ if (num <= 0) - return -EINVAL; - - if (!fp->exit_handler) { -@@ -136,9 +143,12 @@ static int fprobe_init_rethook(struct fprobe *fp, int num) - } - - /* Initialize rethook if needed */ -- size = num * num_possible_cpus() * 2; -- if (size < 0) -- return -E2BIG; -+ if (fp->nr_maxactive) -+ size = fp->nr_maxactive; -+ else -+ size = num * num_possible_cpus() * 2; -+ if (size <= 0) -+ return -EINVAL; - - fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler); - if (!fp->rethook) -@@ -146,7 +156,7 @@ static int fprobe_init_rethook(struct fprobe *fp, int num) - for (i = 0; i < size; i++) { - struct fprobe_rethook_node *node; - -- node = kzalloc(sizeof(*node), GFP_KERNEL); -+ node = kzalloc(sizeof(*node) + fp->entry_data_size, GFP_KERNEL); - if (!node) { - rethook_free(fp->rethook); - fp->rethook = NULL; -diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c -index 9da418442a063..2e3dce5e2575e 100644 ---- a/kernel/trace/trace_events.c -+++ b/kernel/trace/trace_events.c -@@ -2777,6 +2777,7 @@ void trace_event_eval_update(struct trace_eval_map **map, int len) - update_event_fields(call, map[i]); - } - } -+ cond_resched(); - } - up_write(&trace_event_sem); - } -diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c -index 5a75b039e5860..22852029c6924 100644 ---- a/kernel/trace/trace_kprobe.c -+++ b/kernel/trace/trace_kprobe.c -@@ -705,6 +705,25 @@ static struct notifier_block trace_kprobe_module_nb = { - .priority = 1 /* Invoked after kprobe module callback */ - }; - -+static int count_symbols(void *data, unsigned long unused) -+{ -+ unsigned int *count = data; -+ -+ (*count)++; -+ -+ return 0; -+} -+ -+static unsigned int number_of_same_symbols(char *func_name) -+{ -+ unsigned int count; -+ -+ count = 0; -+ kallsyms_on_each_match_symbol(count_symbols, func_name, &count); -+ -+ return count; -+} -+ - static int __trace_kprobe_create(int argc, const char *argv[]) - { - /* -@@ -834,6 +853,31 @@ static int __trace_kprobe_create(int argc, const char *argv[]) - } - } - -+ if (symbol && !strchr(symbol, ':')) { -+ unsigned int count; -+ -+ count = number_of_same_symbols(symbol); -+ if (count > 1) { -+ /* -+ * Users should use ADDR to remove the ambiguity of -+ * using KSYM only. -+ */ -+ trace_probe_log_err(0, NON_UNIQ_SYMBOL); -+ ret = -EADDRNOTAVAIL; -+ -+ goto error; -+ } else if (count == 0) { -+ /* -+ * We can return ENOENT earlier than when register the -+ * kprobe. -+ */ -+ trace_probe_log_err(0, BAD_PROBE_ADDR); -+ ret = -ENOENT; -+ -+ goto error; -+ } -+ } -+ - trace_probe_log_set_index(0); - if (event) { - ret = traceprobe_parse_event_name(&event, &group, gbuf, -@@ -1744,6 +1788,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk) - } - - #ifdef CONFIG_PERF_EVENTS -+ - /* create a trace_kprobe, but don't add it to global lists */ - struct trace_event_call * - create_local_trace_kprobe(char *func, void *addr, unsigned long offs, -@@ -1754,6 +1799,24 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs, - int ret; - char *event; - -+ if (func) { -+ unsigned int count; -+ -+ count = number_of_same_symbols(func); -+ if (count > 1) -+ /* -+ * Users should use addr to remove the ambiguity of -+ * using func only. -+ */ -+ return ERR_PTR(-EADDRNOTAVAIL); -+ else if (count == 0) -+ /* -+ * We can return ENOENT earlier than when register the -+ * kprobe. -+ */ -+ return ERR_PTR(-ENOENT); -+ } -+ - /* - * local trace_kprobes are not added to dyn_event, so they are never - * searched in find_trace_kprobe(). Therefore, there is no concern of -diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h -index f41c330bd60f1..f48b3ed20b095 100644 ---- a/kernel/trace/trace_probe.h -+++ b/kernel/trace/trace_probe.h -@@ -404,6 +404,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, - C(BAD_MAXACT, "Invalid maxactive number"), \ - C(MAXACT_TOO_BIG, "Maxactive is too big"), \ - C(BAD_PROBE_ADDR, "Invalid probed address or symbol"), \ -+ C(NON_UNIQ_SYMBOL, "The symbol is not unique"), \ - C(BAD_RETPROBE, "Retprobe address must be an function entry"), \ - C(BAD_ADDR_SUFFIX, "Invalid probed address suffix"), \ - C(NO_GROUP_NAME, "Group name is not specified"), \ -diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug -index 12dfe6691dd52..4db0199651f56 100644 ---- a/lib/Kconfig.debug -+++ b/lib/Kconfig.debug -@@ -1219,13 +1219,16 @@ config DEBUG_TIMEKEEPING - config DEBUG_PREEMPT - bool "Debug preemptible kernel" - depends on DEBUG_KERNEL && PREEMPTION && TRACE_IRQFLAGS_SUPPORT -- default y - help - If you say Y here then the kernel will use a debug variant of the - commonly used smp_processor_id() function and will print warnings - if kernel code uses it in a preemption-unsafe way. Also, the kernel - will detect preemption count underflows. - -+ This option has potential to introduce high runtime overhead, -+ depending on workload as it triggers debugging routines for each -+ this_cpu operation. It should only be used for debugging purposes. -+ - menu "Lock Debugging (spinlocks, mutexes, etc...)" - - config LOCK_DEBUGGING_SUPPORT -diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c -index e0381b3ec410c..34fa5a5bbda1f 100644 ---- a/lib/test_fprobe.c -+++ b/lib/test_fprobe.c -@@ -30,7 +30,8 @@ static noinline u32 fprobe_selftest_target2(u32 value) - return (value / div_factor) + 1; - } - --static notrace void fp_entry_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs) -+static notrace void fp_entry_handler(struct fprobe *fp, unsigned long ip, -+ struct pt_regs *regs, void *data) - { - KUNIT_EXPECT_FALSE(current_test, preemptible()); - /* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */ -@@ -39,7 +40,8 @@ static notrace void fp_entry_handler(struct fprobe *fp, unsigned long ip, struct - entry_val = (rand1 / div_factor); - } - --static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs) -+static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip, -+ struct pt_regs *regs, void *data) - { - unsigned long ret = regs_return_value(regs); - -diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c -index 61059571c8779..728be9307f526 100644 ---- a/net/bluetooth/hci_conn.c -+++ b/net/bluetooth/hci_conn.c -@@ -1583,6 +1583,15 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, - return ERR_PTR(-EOPNOTSUPP); - } - -+ /* Reject outgoing connection to device with same BD ADDR against -+ * CVE-2020-26555 -+ */ -+ if (!bacmp(&hdev->bdaddr, dst)) { -+ bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n", -+ dst); -+ return ERR_PTR(-ECONNREFUSED); -+ } -+ - acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); - if (!acl) { - acl = hci_conn_add(hdev, ACL_LINK, dst, HCI_ROLE_MASTER); -@@ -2355,34 +2364,41 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, - if (!test_bit(HCI_CONN_AUTH, &conn->flags)) - goto auth; - -- /* An authenticated FIPS approved combination key has sufficient -- * security for security level 4. */ -- if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256 && -- sec_level == BT_SECURITY_FIPS) -- goto encrypt; -- -- /* An authenticated combination key has sufficient security for -- security level 3. */ -- if ((conn->key_type == HCI_LK_AUTH_COMBINATION_P192 || -- conn->key_type == HCI_LK_AUTH_COMBINATION_P256) && -- sec_level == BT_SECURITY_HIGH) -- goto encrypt; -- -- /* An unauthenticated combination key has sufficient security for -- security level 1 and 2. */ -- if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 || -- conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) && -- (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) -- goto encrypt; -- -- /* A combination key has always sufficient security for the security -- levels 1 or 2. High security level requires the combination key -- is generated using maximum PIN code length (16). -- For pre 2.1 units. */ -- if (conn->key_type == HCI_LK_COMBINATION && -- (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW || -- conn->pin_length == 16)) -- goto encrypt; -+ switch (conn->key_type) { -+ case HCI_LK_AUTH_COMBINATION_P256: -+ /* An authenticated FIPS approved combination key has -+ * sufficient security for security level 4 or lower. -+ */ -+ if (sec_level <= BT_SECURITY_FIPS) -+ goto encrypt; -+ break; -+ case HCI_LK_AUTH_COMBINATION_P192: -+ /* An authenticated combination key has sufficient security for -+ * security level 3 or lower. -+ */ -+ if (sec_level <= BT_SECURITY_HIGH) -+ goto encrypt; -+ break; -+ case HCI_LK_UNAUTH_COMBINATION_P192: -+ case HCI_LK_UNAUTH_COMBINATION_P256: -+ /* An unauthenticated combination key has sufficient security -+ * for security level 2 or lower. -+ */ -+ if (sec_level <= BT_SECURITY_MEDIUM) -+ goto encrypt; -+ break; -+ case HCI_LK_COMBINATION: -+ /* A combination key has always sufficient security for the -+ * security levels 2 or lower. High security level requires the -+ * combination key is generated using maximum PIN code length -+ * (16). For pre 2.1 units. -+ */ -+ if (sec_level <= BT_SECURITY_MEDIUM || conn->pin_length == 16) -+ goto encrypt; -+ break; -+ default: -+ break; -+ } - - auth: - if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) -diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c -index d13b498f148cc..6a1db678d032f 100644 ---- a/net/bluetooth/hci_core.c -+++ b/net/bluetooth/hci_core.c -@@ -2616,7 +2616,11 @@ int hci_register_dev(struct hci_dev *hdev) - if (id < 0) - return id; - -- snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); -+ error = dev_set_name(&hdev->dev, "hci%u", id); -+ if (error) -+ return error; -+ -+ hdev->name = dev_name(&hdev->dev); - hdev->id = id; - - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); -@@ -2638,8 +2642,6 @@ int hci_register_dev(struct hci_dev *hdev) - if (!IS_ERR_OR_NULL(bt_debugfs)) - hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); - -- dev_set_name(&hdev->dev, "%s", hdev->name); -- - error = device_add(&hdev->dev); - if (error < 0) - goto err_wqueue; -diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c -index e4d8857716eb7..c86a45344fe28 100644 ---- a/net/bluetooth/hci_event.c -+++ b/net/bluetooth/hci_event.c -@@ -25,6 +25,8 @@ - /* Bluetooth HCI event handling. */ - - #include -+#include -+#include - - #include - #include -@@ -3277,6 +3279,16 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, - - bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type); - -+ /* Reject incoming connection from device with same BD ADDR against -+ * CVE-2020-26555 -+ */ -+ if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) { -+ bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n", -+ &ev->bdaddr); -+ hci_reject_conn(hdev, &ev->bdaddr); -+ return; -+ } -+ - mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, - &flags); - -@@ -4686,6 +4698,15 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data, - if (!conn) - goto unlock; - -+ /* Ignore NULL link key against CVE-2020-26555 */ -+ if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) { -+ bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR", -+ &ev->bdaddr); -+ hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); -+ hci_conn_drop(conn); -+ goto unlock; -+ } -+ - hci_conn_hold(conn); - conn->disc_timeout = HCI_DISCONN_TIMEOUT; - hci_conn_drop(conn); -@@ -5221,8 +5242,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) - * available, then do not declare that OOB data is - * present. - */ -- if (!memcmp(data->rand256, ZERO_KEY, 16) || -- !memcmp(data->hash256, ZERO_KEY, 16)) -+ if (!crypto_memneq(data->rand256, ZERO_KEY, 16) || -+ !crypto_memneq(data->hash256, ZERO_KEY, 16)) - return 0x00; - - return 0x02; -@@ -5232,8 +5253,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) - * not supported by the hardware, then check that if - * P-192 data values are present. - */ -- if (!memcmp(data->rand192, ZERO_KEY, 16) || -- !memcmp(data->hash192, ZERO_KEY, 16)) -+ if (!crypto_memneq(data->rand192, ZERO_KEY, 16) || -+ !crypto_memneq(data->hash192, ZERO_KEY, 16)) - return 0x00; - - return 0x01; -@@ -5250,7 +5271,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data, - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); -- if (!conn) -+ if (!conn || !hci_conn_ssp_enabled(conn)) - goto unlock; - - hci_conn_hold(conn); -@@ -5497,7 +5518,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data, - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); -- if (!conn) -+ if (!conn || !hci_conn_ssp_enabled(conn)) - goto unlock; - - /* Reset the authentication requirement to unknown */ -diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c -index 1d249d839819d..484fc2a8e4baa 100644 ---- a/net/bluetooth/hci_sock.c -+++ b/net/bluetooth/hci_sock.c -@@ -439,7 +439,8 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) - ni->type = hdev->dev_type; - ni->bus = hdev->bus; - bacpy(&ni->bdaddr, &hdev->bdaddr); -- memcpy(ni->name, hdev->name, 8); -+ memcpy_and_pad(ni->name, sizeof(ni->name), hdev->name, -+ strnlen(hdev->name, sizeof(ni->name)), '\0'); - - opcode = cpu_to_le16(HCI_MON_NEW_INDEX); - break; -diff --git a/net/core/dev.c b/net/core/dev.c -index 5374761f5af2c..0d5aa820fd830 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -345,7 +345,6 @@ int netdev_name_node_alt_create(struct net_device *dev, const char *name) - static void __netdev_name_node_alt_destroy(struct netdev_name_node *name_node) - { - list_del(&name_node->list); -- netdev_name_node_del(name_node); - kfree(name_node->name); - netdev_name_node_free(name_node); - } -@@ -364,6 +363,8 @@ int netdev_name_node_alt_destroy(struct net_device *dev, const char *name) - if (name_node == dev->name_node || name_node->dev != dev) - return -EINVAL; - -+ netdev_name_node_del(name_node); -+ synchronize_rcu(); - __netdev_name_node_alt_destroy(name_node); - - return 0; -@@ -380,6 +381,7 @@ static void netdev_name_node_alt_flush(struct net_device *dev) - /* Device list insertion */ - static void list_netdevice(struct net_device *dev) - { -+ struct netdev_name_node *name_node; - struct net *net = dev_net(dev); - - ASSERT_RTNL(); -@@ -391,6 +393,9 @@ static void list_netdevice(struct net_device *dev) - dev_index_hash(net, dev->ifindex)); - write_unlock(&dev_base_lock); - -+ netdev_for_each_altname(dev, name_node) -+ netdev_name_node_add(net, name_node); -+ - dev_base_seq_inc(net); - } - -@@ -399,8 +404,13 @@ static void list_netdevice(struct net_device *dev) - */ - static void unlist_netdevice(struct net_device *dev, bool lock) - { -+ struct netdev_name_node *name_node; -+ - ASSERT_RTNL(); - -+ netdev_for_each_altname(dev, name_node) -+ netdev_name_node_del(name_node); -+ - /* Unlink dev from the device chain */ - if (lock) - write_lock(&dev_base_lock); -@@ -1053,7 +1063,8 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) - - for_each_netdev(net, d) { - struct netdev_name_node *name_node; -- list_for_each_entry(name_node, &d->name_node->list, list) { -+ -+ netdev_for_each_altname(d, name_node) { - if (!sscanf(name_node->name, name, &i)) - continue; - if (i < 0 || i >= max_netdevices) -@@ -1090,6 +1101,26 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) - return -ENFILE; - } - -+static int dev_prep_valid_name(struct net *net, struct net_device *dev, -+ const char *want_name, char *out_name) -+{ -+ int ret; -+ -+ if (!dev_valid_name(want_name)) -+ return -EINVAL; -+ -+ if (strchr(want_name, '%')) { -+ ret = __dev_alloc_name(net, want_name, out_name); -+ return ret < 0 ? ret : 0; -+ } else if (netdev_name_in_use(net, want_name)) { -+ return -EEXIST; -+ } else if (out_name != want_name) { -+ strscpy(out_name, want_name, IFNAMSIZ); -+ } -+ -+ return 0; -+} -+ - static int dev_alloc_name_ns(struct net *net, - struct net_device *dev, - const char *name) -@@ -1127,19 +1158,13 @@ EXPORT_SYMBOL(dev_alloc_name); - static int dev_get_valid_name(struct net *net, struct net_device *dev, - const char *name) - { -- BUG_ON(!net); -- -- if (!dev_valid_name(name)) -- return -EINVAL; -- -- if (strchr(name, '%')) -- return dev_alloc_name_ns(net, dev, name); -- else if (netdev_name_in_use(net, name)) -- return -EEXIST; -- else if (dev->name != name) -- strscpy(dev->name, name, IFNAMSIZ); -+ char buf[IFNAMSIZ]; -+ int ret; - -- return 0; -+ ret = dev_prep_valid_name(net, dev, name, buf); -+ if (ret >= 0) -+ strscpy(dev->name, buf, IFNAMSIZ); -+ return ret; - } - - /** -@@ -10930,7 +10955,9 @@ EXPORT_SYMBOL(unregister_netdev); - int __dev_change_net_namespace(struct net_device *dev, struct net *net, - const char *pat, int new_ifindex) - { -+ struct netdev_name_node *name_node; - struct net *net_old = dev_net(dev); -+ char new_name[IFNAMSIZ] = {}; - int err, new_nsid; - - ASSERT_RTNL(); -@@ -10957,10 +10984,15 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, - /* We get here if we can't use the current device name */ - if (!pat) - goto out; -- err = dev_get_valid_name(net, dev, pat); -+ err = dev_prep_valid_name(net, dev, pat, new_name); - if (err < 0) - goto out; - } -+ /* Check that none of the altnames conflicts. */ -+ err = -EEXIST; -+ netdev_for_each_altname(dev, name_node) -+ if (netdev_name_in_use(net, name_node->name)) -+ goto out; - - /* Check that new_ifindex isn't used yet. */ - err = -EBUSY; -@@ -11025,6 +11057,9 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, - kobject_uevent(&dev->dev.kobj, KOBJ_ADD); - netdev_adjacent_add_links(dev); - -+ if (new_name[0]) /* Rename the netdev to prepared name */ -+ strscpy(dev->name, new_name, IFNAMSIZ); -+ - /* Fixup kobjects */ - err = device_rename(&dev->dev, dev->name); - WARN_ON(err); -diff --git a/net/core/dev.h b/net/core/dev.h -index cbb8a925175a2..9ca91457c197e 100644 ---- a/net/core/dev.h -+++ b/net/core/dev.h -@@ -61,6 +61,9 @@ struct netdev_name_node { - int netdev_get_name(struct net *net, char *name, int ifindex); - int dev_change_name(struct net_device *dev, const char *newname); - -+#define netdev_for_each_altname(dev, namenode) \ -+ list_for_each_entry((namenode), &(dev)->name_node->list, list) -+ - int netdev_name_node_alt_create(struct net_device *dev, const char *name); - int netdev_name_node_alt_destroy(struct net_device *dev, const char *name); - -diff --git a/net/core/pktgen.c b/net/core/pktgen.c -index c3763056c554a..471d4effa8b49 100644 ---- a/net/core/pktgen.c -+++ b/net/core/pktgen.c -@@ -669,19 +669,19 @@ static int pktgen_if_show(struct seq_file *seq, void *v) - seq_puts(seq, " Flags: "); - - for (i = 0; i < NR_PKT_FLAGS; i++) { -- if (i == F_FLOW_SEQ) -+ if (i == FLOW_SEQ_SHIFT) - if (!pkt_dev->cflows) - continue; - -- if (pkt_dev->flags & (1 << i)) -+ if (pkt_dev->flags & (1 << i)) { - seq_printf(seq, "%s ", pkt_flag_names[i]); -- else if (i == F_FLOW_SEQ) -- seq_puts(seq, "FLOW_RND "); -- - #ifdef CONFIG_XFRM -- if (i == F_IPSEC && pkt_dev->spi) -- seq_printf(seq, "spi:%u", pkt_dev->spi); -+ if (i == IPSEC_SHIFT && pkt_dev->spi) -+ seq_printf(seq, "spi:%u ", pkt_dev->spi); - #endif -+ } else if (i == FLOW_SEQ_SHIFT) { -+ seq_puts(seq, "FLOW_RND "); -+ } - } - - seq_puts(seq, "\n"); -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 9d4507aa736b7..854b3fd66b1be 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -5394,13 +5394,11 @@ static unsigned int - rtnl_offload_xstats_get_size_hw_s_info_one(const struct net_device *dev, - enum netdev_offload_xstats_type type) - { -- bool enabled = netdev_offload_xstats_enabled(dev, type); -- - return nla_total_size(0) + - /* IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST */ - nla_total_size(sizeof(u8)) + - /* IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED */ -- (enabled ? nla_total_size(sizeof(u8)) : 0) + -+ nla_total_size(sizeof(u8)) + - 0; - } - -diff --git a/net/core/stream.c b/net/core/stream.c -index 5b05b889d31af..051aa71a8ad0f 100644 ---- a/net/core/stream.c -+++ b/net/core/stream.c -@@ -117,7 +117,7 @@ EXPORT_SYMBOL(sk_stream_wait_close); - */ - int sk_stream_wait_memory(struct sock *sk, long *timeo_p) - { -- int err = 0; -+ int ret, err = 0; - long vm_wait = 0; - long current_timeo = *timeo_p; - DEFINE_WAIT_FUNC(wait, woken_wake_function); -@@ -142,11 +142,13 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) - - set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); - sk->sk_write_pending++; -- sk_wait_event(sk, ¤t_timeo, READ_ONCE(sk->sk_err) || -- (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) || -- (sk_stream_memory_free(sk) && -- !vm_wait), &wait); -+ ret = sk_wait_event(sk, ¤t_timeo, READ_ONCE(sk->sk_err) || -+ (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) || -+ (sk_stream_memory_free(sk) && !vm_wait), -+ &wait); - sk->sk_write_pending--; -+ if (ret < 0) -+ goto do_error; - - if (vm_wait) { - vm_wait -= current_timeo; -diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index 04853c83c85c4..5d379df90c826 100644 ---- a/net/ipv4/af_inet.c -+++ b/net/ipv4/af_inet.c -@@ -589,7 +589,6 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) - - add_wait_queue(sk_sleep(sk), &wait); - sk->sk_write_pending += writebias; -- sk->sk_wait_pending++; - - /* Basic assumption: if someone sets sk->sk_err, he _must_ - * change state of the socket from TCP_SYN_*. -@@ -605,7 +604,6 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) - } - remove_wait_queue(sk_sleep(sk), &wait); - sk->sk_write_pending -= writebias; -- sk->sk_wait_pending--; - return timeo; - } - -@@ -634,6 +632,7 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, - return -EINVAL; - - if (uaddr->sa_family == AF_UNSPEC) { -+ sk->sk_disconnects++; - err = sk->sk_prot->disconnect(sk, flags); - sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED; - goto out; -@@ -688,6 +687,7 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, - int writebias = (sk->sk_protocol == IPPROTO_TCP) && - tcp_sk(sk)->fastopen_req && - tcp_sk(sk)->fastopen_req->data ? 1 : 0; -+ int dis = sk->sk_disconnects; - - /* Error code is set above */ - if (!timeo || !inet_wait_for_connect(sk, timeo, writebias)) -@@ -696,6 +696,11 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, - err = sock_intr_errno(timeo); - if (signal_pending(current)) - goto out; -+ -+ if (dis != sk->sk_disconnects) { -+ err = -EPIPE; -+ goto out; -+ } - } - - /* Connection was closed by RST, timeout, ICMP error -@@ -717,6 +722,7 @@ out: - sock_error: - err = sock_error(sk) ? : -ECONNABORTED; - sock->state = SS_UNCONNECTED; -+ sk->sk_disconnects++; - if (sk->sk_prot->disconnect(sk, flags)) - sock->state = SS_DISCONNECTING; - goto out; -diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c -index 2d094d417ecae..e2546961add3e 100644 ---- a/net/ipv4/esp4.c -+++ b/net/ipv4/esp4.c -@@ -732,7 +732,9 @@ static inline int esp_remove_trailer(struct sk_buff *skb) - skb->csum = csum_block_sub(skb->csum, csumdiff, - skb->len - trimlen); - } -- pskb_trim(skb, skb->len - trimlen); -+ ret = pskb_trim(skb, skb->len - trimlen); -+ if (unlikely(ret)) -+ return ret; - - ret = nexthdr[1]; - -diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c -index eafa4a0335157..5eb1b8d302bbd 100644 ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -1325,15 +1325,18 @@ __be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc, - unsigned char scope) - { - struct fib_nh *nh; -+ __be32 saddr; - - if (nhc->nhc_family != AF_INET) - return inet_select_addr(nhc->nhc_dev, 0, scope); - - nh = container_of(nhc, struct fib_nh, nh_common); -- nh->nh_saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope); -- nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid); -+ saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope); - -- return nh->nh_saddr; -+ WRITE_ONCE(nh->nh_saddr, saddr); -+ WRITE_ONCE(nh->nh_saddr_genid, atomic_read(&net->ipv4.dev_addr_genid)); -+ -+ return saddr; - } - - __be32 fib_result_prefsrc(struct net *net, struct fib_result *res) -@@ -1347,8 +1350,9 @@ __be32 fib_result_prefsrc(struct net *net, struct fib_result *res) - struct fib_nh *nh; - - nh = container_of(nhc, struct fib_nh, nh_common); -- if (nh->nh_saddr_genid == atomic_read(&net->ipv4.dev_addr_genid)) -- return nh->nh_saddr; -+ if (READ_ONCE(nh->nh_saddr_genid) == -+ atomic_read(&net->ipv4.dev_addr_genid)) -+ return READ_ONCE(nh->nh_saddr); - } - - return fib_info_update_nhc_saddr(net, nhc, res->fi->fib_scope); -@@ -1887,6 +1891,7 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local) - continue; - if (fi->fib_prefsrc == local) { - fi->fib_flags |= RTNH_F_DEAD; -+ fi->pfsrc_removed = true; - ret++; - } - } -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index d13fb9e76b971..9bdfdab906fe0 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -2027,6 +2027,7 @@ void fib_table_flush_external(struct fib_table *tb) - int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) - { - struct trie *t = (struct trie *)tb->tb_data; -+ struct nl_info info = { .nl_net = net }; - struct key_vector *pn = t->kv; - unsigned long cindex = 1; - struct hlist_node *tmp; -@@ -2089,6 +2090,9 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) - - fib_notify_alias_delete(net, n->key, &n->leaf, fa, - NULL); -+ if (fi->pfsrc_removed) -+ rtmsg_fib(RTM_DELROUTE, htonl(n->key), fa, -+ KEYLENGTH - fa->fa_slen, tb->tb_id, &info, 0); - hlist_del_rcu(&fa->fa_list); - fib_release_info(fa->fa_info); - alias_free_mem_rcu(fa); -diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c -index 62a3b103f258a..80ce0112e24b4 100644 ---- a/net/ipv4/inet_connection_sock.c -+++ b/net/ipv4/inet_connection_sock.c -@@ -1143,7 +1143,6 @@ struct sock *inet_csk_clone_lock(const struct sock *sk, - if (newsk) { - struct inet_connection_sock *newicsk = inet_csk(newsk); - -- newsk->sk_wait_pending = 0; - inet_sk_set_state(newsk, TCP_SYN_RECV); - newicsk->icsk_bind_hash = NULL; - newicsk->icsk_bind2_hash = NULL; -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index d79de4b95186b..62d9472ac8bca 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -148,8 +148,14 @@ static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2, - const struct sock *sk) - { - #if IS_ENABLED(CONFIG_IPV6) -- if (sk->sk_family != tb2->family) -- return false; -+ if (sk->sk_family != tb2->family) { -+ if (sk->sk_family == AF_INET) -+ return ipv6_addr_v4mapped(&tb2->v6_rcv_saddr) && -+ tb2->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; -+ -+ return ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr) && -+ sk->sk_v6_rcv_saddr.s6_addr32[3] == tb2->rcv_saddr; -+ } - - if (sk->sk_family == AF_INET6) - return ipv6_addr_equal(&tb2->v6_rcv_saddr, -@@ -799,19 +805,7 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb, - tb->l3mdev != l3mdev) - return false; - --#if IS_ENABLED(CONFIG_IPV6) -- if (sk->sk_family != tb->family) { -- if (sk->sk_family == AF_INET) -- return ipv6_addr_v4mapped(&tb->v6_rcv_saddr) && -- tb->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; -- -- return false; -- } -- -- if (sk->sk_family == AF_INET6) -- return ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); --#endif -- return tb->rcv_saddr == sk->sk_rcv_saddr; -+ return inet_bind2_bucket_addr_match(tb, sk); - } - - bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const struct net *net, -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 96fdde6e42b1b..288678f17ccaf 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -827,7 +827,9 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, - */ - if (!skb_queue_empty(&sk->sk_receive_queue)) - break; -- sk_wait_data(sk, &timeo, NULL); -+ ret = sk_wait_data(sk, &timeo, NULL); -+ if (ret < 0) -+ break; - if (signal_pending(current)) { - ret = sock_intr_errno(timeo); - break; -@@ -2549,7 +2551,11 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len, - __sk_flush_backlog(sk); - } else { - tcp_cleanup_rbuf(sk, copied); -- sk_wait_data(sk, &timeo, last); -+ err = sk_wait_data(sk, &timeo, last); -+ if (err < 0) { -+ err = copied ? : err; -+ goto out; -+ } - } - - if ((flags & MSG_PEEK) && -@@ -3073,12 +3079,6 @@ int tcp_disconnect(struct sock *sk, int flags) - int old_state = sk->sk_state; - u32 seq; - -- /* Deny disconnect if other threads are blocked in sk_wait_event() -- * or inet_wait_for_connect(). -- */ -- if (sk->sk_wait_pending) -- return -EBUSY; -- - if (old_state != TCP_CLOSE) - tcp_set_state(sk, TCP_CLOSE); - -diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c -index f53380fd89bcf..f8037d142bb75 100644 ---- a/net/ipv4/tcp_bpf.c -+++ b/net/ipv4/tcp_bpf.c -@@ -302,6 +302,10 @@ msg_bytes_ready: - } - - data = tcp_msg_wait_data(sk, psock, timeo); -+ if (data < 0) { -+ copied = data; -+ goto unlock; -+ } - if (data && !sk_psock_queue_empty(psock)) - goto msg_bytes_ready; - copied = -EAGAIN; -@@ -312,6 +316,8 @@ out: - tcp_rcv_space_adjust(sk); - if (copied > 0) - __tcp_cleanup_rbuf(sk, copied); -+ -+unlock: - release_sock(sk); - sk_psock_put(sk, psock); - return copied; -@@ -346,6 +352,10 @@ msg_bytes_ready: - - timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); - data = tcp_msg_wait_data(sk, psock, timeo); -+ if (data < 0) { -+ ret = data; -+ goto unlock; -+ } - if (data) { - if (!sk_psock_queue_empty(psock)) - goto msg_bytes_ready; -@@ -356,6 +366,8 @@ msg_bytes_ready: - copied = -EAGAIN; - } - ret = copied; -+ -+unlock: - release_sock(sk); - sk_psock_put(sk, psock); - return ret; -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index 5df19f93f86ab..7ebbbe561e402 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -1818,6 +1818,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb, - #ifdef CONFIG_TLS_DEVICE - tail->decrypted != skb->decrypted || - #endif -+ !mptcp_skb_can_collapse(tail, skb) || - thtail->doff != th->doff || - memcmp(thtail + 1, th + 1, hdrlen - sizeof(*th))) - goto no_coalesce; -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index 443b1cab25299..cc7ed86fb0a57 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -2489,6 +2489,18 @@ static bool tcp_pacing_check(struct sock *sk) - return true; - } - -+static bool tcp_rtx_queue_empty_or_single_skb(const struct sock *sk) -+{ -+ const struct rb_node *node = sk->tcp_rtx_queue.rb_node; -+ -+ /* No skb in the rtx queue. */ -+ if (!node) -+ return true; -+ -+ /* Only one skb in rtx queue. */ -+ return !node->rb_left && !node->rb_right; -+} -+ - /* TCP Small Queues : - * Control number of packets in qdisc/devices to two packets / or ~1 ms. - * (These limits are doubled for retransmits) -@@ -2526,12 +2538,12 @@ static bool tcp_small_queue_check(struct sock *sk, const struct sk_buff *skb, - limit += extra_bytes; - } - if (refcount_read(&sk->sk_wmem_alloc) > limit) { -- /* Always send skb if rtx queue is empty. -+ /* Always send skb if rtx queue is empty or has one skb. - * No need to wait for TX completion to call us back, - * after softirq/tasklet schedule. - * This helps when TX completions are delayed too much. - */ -- if (tcp_rtx_queue_empty(sk)) -+ if (tcp_rtx_queue_empty_or_single_skb(sk)) - return false; - - set_bit(TSQ_THROTTLED, &sk->sk_tsq_flags); -@@ -2735,7 +2747,7 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -- u32 timeout, rto_delta_us; -+ u32 timeout, timeout_us, rto_delta_us; - int early_retrans; - - /* Don't do any loss probe on a Fast Open connection before 3WHS -@@ -2759,11 +2771,12 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto) - * sample is available then probe after TCP_TIMEOUT_INIT. - */ - if (tp->srtt_us) { -- timeout = usecs_to_jiffies(tp->srtt_us >> 2); -+ timeout_us = tp->srtt_us >> 2; - if (tp->packets_out == 1) -- timeout += TCP_RTO_MIN; -+ timeout_us += tcp_rto_min_us(sk); - else -- timeout += TCP_TIMEOUT_MIN; -+ timeout_us += TCP_TIMEOUT_MIN_US; -+ timeout = usecs_to_jiffies(timeout_us); - } else { - timeout = TCP_TIMEOUT_INIT; - } -diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c -index 50abaa941387d..c085793691102 100644 ---- a/net/ipv4/tcp_recovery.c -+++ b/net/ipv4/tcp_recovery.c -@@ -104,7 +104,7 @@ bool tcp_rack_mark_lost(struct sock *sk) - tp->rack.advanced = 0; - tcp_rack_detect_loss(sk, &timeout); - if (timeout) { -- timeout = usecs_to_jiffies(timeout) + TCP_TIMEOUT_MIN; -+ timeout = usecs_to_jiffies(timeout + TCP_TIMEOUT_MIN_US); - inet_csk_reset_xmit_timer(sk, ICSK_TIME_REO_TIMEOUT, - timeout, inet_csk(sk)->icsk_rto); - } -diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c -index 14ed868680c6a..c2dcb5c613b6b 100644 ---- a/net/ipv6/esp6.c -+++ b/net/ipv6/esp6.c -@@ -770,7 +770,9 @@ static inline int esp_remove_trailer(struct sk_buff *skb) - skb->csum = csum_block_sub(skb->csum, csumdiff, - skb->len - trimlen); - } -- pskb_trim(skb, skb->len - trimlen); -+ ret = pskb_trim(skb, skb->len - trimlen); -+ if (unlikely(ret)) -+ return ret; - - ret = nexthdr[1]; - -diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c -index ea435eba30534..f0053087d2e47 100644 ---- a/net/ipv6/xfrm6_policy.c -+++ b/net/ipv6/xfrm6_policy.c -@@ -118,11 +118,11 @@ static void xfrm6_dst_destroy(struct dst_entry *dst) - { - struct xfrm_dst *xdst = (struct xfrm_dst *)dst; - -- if (likely(xdst->u.rt6.rt6i_idev)) -- in6_dev_put(xdst->u.rt6.rt6i_idev); - dst_destroy_metrics_generic(dst); - if (xdst->u.rt6.rt6i_uncached_list) - rt6_uncached_list_del(&xdst->u.rt6); -+ if (likely(xdst->u.rt6.rt6i_idev)) -+ in6_dev_put(xdst->u.rt6.rt6i_idev); - xfrm_dst_destroy(xdst); - } - -diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c -index 0167413d56972..ee9f455bb2d18 100644 ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1748,7 +1748,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, - /* VHT can override some HT caps such as the A-MSDU max length */ - if (params->vht_capa) - ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, -- params->vht_capa, link_sta); -+ params->vht_capa, NULL, -+ link_sta); - - if (params->he_capa) - ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, -diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c -index 9dffc30795887..79d2c55052897 100644 ---- a/net/mac80211/ibss.c -+++ b/net/mac80211/ibss.c -@@ -1068,7 +1068,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, - &chandef); - memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie)); - ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, -- &cap_ie, -+ &cap_ie, NULL, - &sta->deflink); - if (memcmp(&cap, &sta->sta.deflink.vht_cap, sizeof(cap))) - rates_updated |= true; -diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h -index 27479bbb093ac..99a976ea17498 100644 ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -2062,6 +2062,7 @@ void - ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, - struct ieee80211_supported_band *sband, - const struct ieee80211_vht_cap *vht_cap_ie, -+ const struct ieee80211_vht_cap *vht_cap_ie2, - struct link_sta_info *link_sta); - enum ieee80211_sta_rx_bandwidth - ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta); -diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c -index ddfe5102b9a43..bd0b7c189adfa 100644 ---- a/net/mac80211/mesh_plink.c -+++ b/net/mac80211/mesh_plink.c -@@ -443,7 +443,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, - changed |= IEEE80211_RC_BW_CHANGED; - - ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, -- elems->vht_cap_elem, -+ elems->vht_cap_elem, NULL, - &sta->deflink); - - ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap, -diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c -index dc9e7eb7dd857..c07645c999f9a 100644 ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -4083,10 +4083,33 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, - elems->ht_cap_elem, - link_sta); - -- if (elems->vht_cap_elem && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) -+ if (elems->vht_cap_elem && -+ !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) { -+ const struct ieee80211_vht_cap *bss_vht_cap = NULL; -+ const struct cfg80211_bss_ies *ies; -+ -+ /* -+ * Cisco AP module 9115 with FW 17.3 has a bug and sends a -+ * too large maximum MPDU length in the association response -+ * (indicating 12k) that it cannot actually process ... -+ * Work around that. -+ */ -+ rcu_read_lock(); -+ ies = rcu_dereference(cbss->ies); -+ if (ies) { -+ const struct element *elem; -+ -+ elem = cfg80211_find_elem(WLAN_EID_VHT_CAPABILITY, -+ ies->data, ies->len); -+ if (elem && elem->datalen >= sizeof(*bss_vht_cap)) -+ bss_vht_cap = (const void *)elem->data; -+ } -+ - ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, - elems->vht_cap_elem, -- link_sta); -+ bss_vht_cap, link_sta); -+ rcu_read_unlock(); -+ } - - if (elems->he_operation && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) && - elems->he_cap) { -diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c -index 2f9e1abdf375d..2db103a56a28f 100644 ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -680,7 +680,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) - } - - if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED && -- !ieee80211_is_deauth(hdr->frame_control))) -+ !ieee80211_is_deauth(hdr->frame_control)) && -+ tx->skb->protocol != tx->sdata->control_port_protocol) - return TX_DROP; - - if (!skip_hw && tx->key && -diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c -index 803de58814852..f7526be8a1c7e 100644 ---- a/net/mac80211/vht.c -+++ b/net/mac80211/vht.c -@@ -4,7 +4,7 @@ - * - * Portions of this file - * Copyright(c) 2015 - 2016 Intel Deutschland GmbH -- * Copyright (C) 2018 - 2022 Intel Corporation -+ * Copyright (C) 2018 - 2023 Intel Corporation - */ - - #include -@@ -116,12 +116,14 @@ void - ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, - struct ieee80211_supported_band *sband, - const struct ieee80211_vht_cap *vht_cap_ie, -+ const struct ieee80211_vht_cap *vht_cap_ie2, - struct link_sta_info *link_sta) - { - struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap; - struct ieee80211_sta_vht_cap own_cap; - u32 cap_info, i; - bool have_80mhz; -+ u32 mpdu_len; - - memset(vht_cap, 0, sizeof(*vht_cap)); - -@@ -317,11 +319,21 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, - - link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta); - -+ /* -+ * Work around the Cisco 9115 FW 17.3 bug by taking the min of -+ * both reported MPDU lengths. -+ */ -+ mpdu_len = vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK; -+ if (vht_cap_ie2) -+ mpdu_len = min_t(u32, mpdu_len, -+ le32_get_bits(vht_cap_ie2->vht_cap_info, -+ IEEE80211_VHT_CAP_MAX_MPDU_MASK)); -+ - /* - * FIXME - should the amsdu len be per link? store per link - * and maintain a minimum? - */ -- switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) { -+ switch (mpdu_len) { - case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: - link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454; - break; -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index 881e05193ac97..0eb20274459c8 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -1342,7 +1342,7 @@ alloc_skb: - if (copy == 0) { - u64 snd_una = READ_ONCE(msk->snd_una); - -- if (snd_una != msk->snd_nxt) { -+ if (snd_una != msk->snd_nxt || tcp_write_queue_tail(ssk)) { - tcp_remove_empty_skb(ssk); - return 0; - } -@@ -1350,11 +1350,6 @@ alloc_skb: - zero_window_probe = true; - data_seq = snd_una - 1; - copy = 1; -- -- /* all mptcp-level data is acked, no skbs should be present into the -- * ssk write queue -- */ -- WARN_ON_ONCE(reuse_skb); - } - - copy = min_t(size_t, copy, info->limit - info->sent); -@@ -1383,7 +1378,6 @@ alloc_skb: - if (reuse_skb) { - TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; - mpext->data_len += copy; -- WARN_ON_ONCE(zero_window_probe); - goto out; - } - -@@ -2374,6 +2368,26 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) - #define MPTCP_CF_PUSH BIT(1) - #define MPTCP_CF_FASTCLOSE BIT(2) - -+/* be sure to send a reset only if the caller asked for it, also -+ * clean completely the subflow status when the subflow reaches -+ * TCP_CLOSE state -+ */ -+static void __mptcp_subflow_disconnect(struct sock *ssk, -+ struct mptcp_subflow_context *subflow, -+ unsigned int flags) -+{ -+ if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || -+ (flags & MPTCP_CF_FASTCLOSE)) { -+ /* The MPTCP code never wait on the subflow sockets, TCP-level -+ * disconnect should never fail -+ */ -+ WARN_ON_ONCE(tcp_disconnect(ssk, 0)); -+ mptcp_subflow_ctx_reset(subflow); -+ } else { -+ tcp_shutdown(ssk, SEND_SHUTDOWN); -+ } -+} -+ - /* subflow sockets can be either outgoing (connect) or incoming - * (accept). - * -@@ -2411,7 +2425,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); - - if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) { -- /* be sure to force the tcp_disconnect() path, -+ /* be sure to force the tcp_close path - * to generate the egress reset - */ - ssk->sk_lingertime = 0; -@@ -2421,12 +2435,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - - need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); - if (!dispose_it) { -- /* The MPTCP code never wait on the subflow sockets, TCP-level -- * disconnect should never fail -- */ -- WARN_ON_ONCE(tcp_disconnect(ssk, 0)); -+ __mptcp_subflow_disconnect(ssk, subflow, flags); - msk->subflow->state = SS_UNCONNECTED; -- mptcp_subflow_ctx_reset(subflow); - release_sock(ssk); - - goto out; -@@ -3107,12 +3117,6 @@ static int mptcp_disconnect(struct sock *sk, int flags) - { - struct mptcp_sock *msk = mptcp_sk(sk); - -- /* Deny disconnect if other threads are blocked in sk_wait_event() -- * or inet_wait_for_connect(). -- */ -- if (sk->sk_wait_pending) -- return -EBUSY; -- - /* We are on the fastopen error path. We can't call straight into the - * subflows cleanup code due to lock nesting (we are already under - * msk->firstsocket lock). -@@ -3180,7 +3184,6 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk, - inet_sk(nsk)->pinet6 = mptcp_inet6_sk(nsk); - #endif - -- nsk->sk_wait_pending = 0; - __mptcp_init_sock(nsk); - - msk = mptcp_sk(nsk); -diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c -index d7de2ecb287eb..f44f2eaf32172 100644 ---- a/net/netfilter/nft_payload.c -+++ b/net/netfilter/nft_payload.c -@@ -132,7 +132,7 @@ void nft_payload_eval(const struct nft_expr *expr, - - switch (priv->base) { - case NFT_PAYLOAD_LL_HEADER: -- if (!skb_mac_header_was_set(skb)) -+ if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) == 0) - goto err; - - if (skb_vlan_tag_present(skb)) { -diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c -index 2660ceab3759d..e34662f4a71e0 100644 ---- a/net/netfilter/nft_set_rbtree.c -+++ b/net/netfilter/nft_set_rbtree.c -@@ -568,6 +568,8 @@ static void *nft_rbtree_deactivate(const struct net *net, - nft_rbtree_interval_end(this)) { - parent = parent->rb_right; - continue; -+ } else if (nft_set_elem_expired(&rbe->ext)) { -+ break; - } else if (!nft_set_elem_active(&rbe->ext, genmask)) { - parent = parent->rb_left; - continue; -diff --git a/net/nfc/nci/spi.c b/net/nfc/nci/spi.c -index 0935527d1d12b..b68150c971d0b 100644 ---- a/net/nfc/nci/spi.c -+++ b/net/nfc/nci/spi.c -@@ -151,6 +151,8 @@ static int send_acknowledge(struct nci_spi *nspi, u8 acknowledge) - int ret; - - skb = nci_skb_alloc(nspi->ndev, 0, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; - - /* add the NCI SPI header to the start of the buffer */ - hdr = skb_push(skb, NCI_SPI_HDR_LEN); -diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c -index f5afc9bcdee65..2cc95c8dc4c7b 100644 ---- a/net/rfkill/rfkill-gpio.c -+++ b/net/rfkill/rfkill-gpio.c -@@ -98,13 +98,13 @@ static int rfkill_gpio_probe(struct platform_device *pdev) - - rfkill->clk = devm_clk_get(&pdev->dev, NULL); - -- gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW); -+ gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_ASIS); - if (IS_ERR(gpio)) - return PTR_ERR(gpio); - - rfkill->reset_gpio = gpio; - -- gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_OUT_LOW); -+ gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_ASIS); - if (IS_ERR(gpio)) - return PTR_ERR(gpio); - -diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c -index 61d52594ff6d8..54dddc2ff5025 100644 ---- a/net/sched/sch_hfsc.c -+++ b/net/sched/sch_hfsc.c -@@ -903,6 +903,14 @@ hfsc_change_usc(struct hfsc_class *cl, struct tc_service_curve *usc, - cl->cl_flags |= HFSC_USC; - } - -+static void -+hfsc_upgrade_rt(struct hfsc_class *cl) -+{ -+ cl->cl_fsc = cl->cl_rsc; -+ rtsc_init(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vt, cl->cl_total); -+ cl->cl_flags |= HFSC_FSC; -+} -+ - static const struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = { - [TCA_HFSC_RSC] = { .len = sizeof(struct tc_service_curve) }, - [TCA_HFSC_FSC] = { .len = sizeof(struct tc_service_curve) }, -@@ -1012,10 +1020,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, - if (parent == NULL) - return -ENOENT; - } -- if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) { -- NL_SET_ERR_MSG(extack, "Invalid parent - parent class must have FSC"); -- return -EINVAL; -- } - - if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0) - return -EINVAL; -@@ -1066,6 +1070,12 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, - cl->cf_tree = RB_ROOT; - - sch_tree_lock(sch); -+ /* Check if the inner class is a misconfigured 'rt' */ -+ if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) { -+ NL_SET_ERR_MSG(extack, -+ "Forced curve change on parent 'rt' to 'sc'"); -+ hfsc_upgrade_rt(parent); -+ } - qdisc_class_hash_insert(&q->clhash, &cl->cl_common); - list_add_tail(&cl->siblings, &parent->children); - if (parent->level == 0) -diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c -index f774d840759d6..4ea41d6e36969 100644 ---- a/net/smc/af_smc.c -+++ b/net/smc/af_smc.c -@@ -1187,6 +1187,7 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc, - struct smc_clc_first_contact_ext *fce = - (struct smc_clc_first_contact_ext *) - (((u8 *)clc_v2) + sizeof(*clc_v2)); -+ struct net *net = sock_net(&smc->sk); - - if (!ini->first_contact_peer || aclc->hdr.version == SMC_V1) - return 0; -@@ -1195,7 +1196,7 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc, - memcpy(ini->smcrv2.nexthop_mac, &aclc->r0.lcl.mac, ETH_ALEN); - ini->smcrv2.uses_gateway = false; - } else { -- if (smc_ib_find_route(smc->clcsock->sk->sk_rcv_saddr, -+ if (smc_ib_find_route(net, smc->clcsock->sk->sk_rcv_saddr, - smc_ib_gid_to_ipv4(aclc->r0.lcl.gid), - ini->smcrv2.nexthop_mac, - &ini->smcrv2.uses_gateway)) -@@ -2322,7 +2323,7 @@ static int smc_listen_find_device(struct smc_sock *new_smc, - smc_find_ism_store_rc(rc, ini); - return (!rc) ? 0 : ini->rc; - } -- return SMC_CLC_DECL_NOSMCDEV; -+ return prfx_rc; - } - - /* listen worker: finish RDMA setup */ -diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c -index 854772dd52fd1..ace8611735321 100644 ---- a/net/smc/smc_ib.c -+++ b/net/smc/smc_ib.c -@@ -193,7 +193,7 @@ bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport) - return smcibdev->pattr[ibport - 1].state == IB_PORT_ACTIVE; - } - --int smc_ib_find_route(__be32 saddr, __be32 daddr, -+int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr, - u8 nexthop_mac[], u8 *uses_gateway) - { - struct neighbour *neigh = NULL; -@@ -205,7 +205,7 @@ int smc_ib_find_route(__be32 saddr, __be32 daddr, - - if (daddr == cpu_to_be32(INADDR_NONE)) - goto out; -- rt = ip_route_output_flow(&init_net, &fl4, NULL); -+ rt = ip_route_output_flow(net, &fl4, NULL); - if (IS_ERR(rt)) - goto out; - if (rt->rt_uses_gateway && rt->rt_gw_family != AF_INET) -@@ -235,6 +235,7 @@ static int smc_ib_determine_gid_rcu(const struct net_device *ndev, - if (smcrv2 && attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP && - smc_ib_gid_to_ipv4((u8 *)&attr->gid) != cpu_to_be32(INADDR_NONE)) { - struct in_device *in_dev = __in_dev_get_rcu(ndev); -+ struct net *net = dev_net(ndev); - const struct in_ifaddr *ifa; - bool subnet_match = false; - -@@ -248,7 +249,7 @@ static int smc_ib_determine_gid_rcu(const struct net_device *ndev, - } - if (!subnet_match) - goto out; -- if (smcrv2->daddr && smc_ib_find_route(smcrv2->saddr, -+ if (smcrv2->daddr && smc_ib_find_route(net, smcrv2->saddr, - smcrv2->daddr, - smcrv2->nexthop_mac, - &smcrv2->uses_gateway)) -diff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h -index 034295676e881..ebcb05ede7f55 100644 ---- a/net/smc/smc_ib.h -+++ b/net/smc/smc_ib.h -@@ -113,7 +113,7 @@ void smc_ib_sync_sg_for_device(struct smc_link *lnk, - int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport, - unsigned short vlan_id, u8 gid[], u8 *sgid_index, - struct smc_init_info_smcrv2 *smcrv2); --int smc_ib_find_route(__be32 saddr, __be32 daddr, -+int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr, - u8 nexthop_mac[], u8 *uses_gateway); - bool smc_ib_is_valid_local_systemid(void); - int smcr_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb); -diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c -index f2e7302a4d96b..338a443fa47b2 100644 ---- a/net/tls/tls_main.c -+++ b/net/tls/tls_main.c -@@ -96,8 +96,8 @@ void update_sk_prot(struct sock *sk, struct tls_context *ctx) - - int wait_on_pending_writer(struct sock *sk, long *timeo) - { -- int rc = 0; - DEFINE_WAIT_FUNC(wait, woken_wake_function); -+ int ret, rc = 0; - - add_wait_queue(sk_sleep(sk), &wait); - while (1) { -@@ -111,9 +111,13 @@ int wait_on_pending_writer(struct sock *sk, long *timeo) - break; - } - -- if (sk_wait_event(sk, timeo, -- !READ_ONCE(sk->sk_write_pending), &wait)) -+ ret = sk_wait_event(sk, timeo, -+ !READ_ONCE(sk->sk_write_pending), &wait); -+ if (ret) { -+ if (ret < 0) -+ rc = ret; - break; -+ } - } - remove_wait_queue(sk_sleep(sk), &wait); - return rc; -diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c -index 9be00ebbb2341..2af72d349192e 100644 ---- a/net/tls/tls_sw.c -+++ b/net/tls/tls_sw.c -@@ -1296,6 +1296,7 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, - struct tls_context *tls_ctx = tls_get_ctx(sk); - struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); - DEFINE_WAIT_FUNC(wait, woken_wake_function); -+ int ret = 0; - long timeo; - - timeo = sock_rcvtimeo(sk, nonblock); -@@ -1307,6 +1308,9 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, - if (sk->sk_err) - return sock_error(sk); - -+ if (ret < 0) -+ return ret; -+ - if (!skb_queue_empty(&sk->sk_receive_queue)) { - tls_strp_check_rcv(&ctx->strp); - if (tls_strp_msg_ready(ctx)) -@@ -1325,10 +1329,10 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, - released = true; - add_wait_queue(sk_sleep(sk), &wait); - sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); -- sk_wait_event(sk, &timeo, -- tls_strp_msg_ready(ctx) || -- !sk_psock_queue_empty(psock), -- &wait); -+ ret = sk_wait_event(sk, &timeo, -+ tls_strp_msg_ready(ctx) || -+ !sk_psock_queue_empty(psock), -+ &wait); - sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); - remove_wait_queue(sk_sleep(sk), &wait); - -@@ -1851,13 +1855,11 @@ tls_read_flush_backlog(struct sock *sk, struct tls_prot_info *prot, - return sk_flush_backlog(sk); - } - --static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, -- bool nonblock) -+static int tls_rx_reader_acquire(struct sock *sk, struct tls_sw_context_rx *ctx, -+ bool nonblock) - { - long timeo; -- int err; -- -- lock_sock(sk); -+ int ret; - - timeo = sock_rcvtimeo(sk, nonblock); - -@@ -1867,30 +1869,36 @@ static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, - ctx->reader_contended = 1; - - add_wait_queue(&ctx->wq, &wait); -- sk_wait_event(sk, &timeo, -- !READ_ONCE(ctx->reader_present), &wait); -+ ret = sk_wait_event(sk, &timeo, -+ !READ_ONCE(ctx->reader_present), &wait); - remove_wait_queue(&ctx->wq, &wait); - -- if (timeo <= 0) { -- err = -EAGAIN; -- goto err_unlock; -- } -- if (signal_pending(current)) { -- err = sock_intr_errno(timeo); -- goto err_unlock; -- } -+ if (timeo <= 0) -+ return -EAGAIN; -+ if (signal_pending(current)) -+ return sock_intr_errno(timeo); -+ if (ret < 0) -+ return ret; - } - - WRITE_ONCE(ctx->reader_present, 1); - - return 0; -+} - --err_unlock: -- release_sock(sk); -+static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, -+ bool nonblock) -+{ -+ int err; -+ -+ lock_sock(sk); -+ err = tls_rx_reader_acquire(sk, ctx, nonblock); -+ if (err) -+ release_sock(sk); - return err; - } - --static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) -+static void tls_rx_reader_release(struct sock *sk, struct tls_sw_context_rx *ctx) - { - if (unlikely(ctx->reader_contended)) { - if (wq_has_sleeper(&ctx->wq)) -@@ -1902,6 +1910,11 @@ static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) - } - - WRITE_ONCE(ctx->reader_present, 0); -+} -+ -+static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) -+{ -+ tls_rx_reader_release(sk, ctx); - release_sock(sk); - } - -diff --git a/net/wireless/core.c b/net/wireless/core.c -index 2c79604672062..bf2f1f583fb12 100644 ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -1618,7 +1618,7 @@ void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work) - list_add_tail(&work->entry, &rdev->wiphy_work_list); - spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); - -- schedule_work(&rdev->wiphy_work); -+ queue_work(system_unbound_wq, &rdev->wiphy_work); - } - EXPORT_SYMBOL_GPL(wiphy_work_queue); - -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index 1d993a490ac4b..b19b5acfaf3a9 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -8289,7 +8289,7 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - struct wireless_dev *wdev = dev->ieee80211_ptr; -- struct mesh_config cfg; -+ struct mesh_config cfg = {}; - u32 mask; - int err; - -diff --git a/net/wireless/scan.c b/net/wireless/scan.c -index e5c1510c098fd..b7e1631b3d80d 100644 ---- a/net/wireless/scan.c -+++ b/net/wireless/scan.c -@@ -876,6 +876,10 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev) - !cfg80211_find_ssid_match(ap, request)) - continue; - -+ if (!is_broadcast_ether_addr(request->bssid) && -+ !ether_addr_equal(request->bssid, ap->bssid)) -+ continue; -+ - if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid) - continue; - -diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c -index d71dbe822096a..85501b77f4e37 100644 ---- a/net/xfrm/xfrm_interface_core.c -+++ b/net/xfrm/xfrm_interface_core.c -@@ -379,8 +379,8 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err) - skb->dev = dev; - - if (err) { -- dev->stats.rx_errors++; -- dev->stats.rx_dropped++; -+ DEV_STATS_INC(dev, rx_errors); -+ DEV_STATS_INC(dev, rx_dropped); - - return 0; - } -@@ -425,7 +425,6 @@ static int - xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) - { - struct xfrm_if *xi = netdev_priv(dev); -- struct net_device_stats *stats = &xi->dev->stats; - struct dst_entry *dst = skb_dst(skb); - unsigned int length = skb->len; - struct net_device *tdev; -@@ -464,7 +463,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) - tdev = dst->dev; - - if (tdev == dev) { -- stats->collisions++; -+ DEV_STATS_INC(dev, collisions); - net_warn_ratelimited("%s: Local routing loop detected!\n", - dev->name); - goto tx_err_dst_release; -@@ -503,13 +502,13 @@ xmit: - if (net_xmit_eval(err) == 0) { - dev_sw_netstats_tx_add(dev, 1, length); - } else { -- stats->tx_errors++; -- stats->tx_aborted_errors++; -+ DEV_STATS_INC(dev, tx_errors); -+ DEV_STATS_INC(dev, tx_aborted_errors); - } - - return 0; - tx_err_link_failure: -- stats->tx_carrier_errors++; -+ DEV_STATS_INC(dev, tx_carrier_errors); - dst_link_failure(skb); - tx_err_dst_release: - dst_release(dst); -@@ -519,7 +518,6 @@ tx_err_dst_release: - static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct xfrm_if *xi = netdev_priv(dev); -- struct net_device_stats *stats = &xi->dev->stats; - struct dst_entry *dst = skb_dst(skb); - struct flowi fl; - int ret; -@@ -536,7 +534,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) - dst = ip6_route_output(dev_net(dev), NULL, &fl.u.ip6); - if (dst->error) { - dst_release(dst); -- stats->tx_carrier_errors++; -+ DEV_STATS_INC(dev, tx_carrier_errors); - goto tx_err; - } - skb_dst_set(skb, dst); -@@ -552,7 +550,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) - fl.u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; - rt = __ip_route_output_key(dev_net(dev), &fl.u.ip4); - if (IS_ERR(rt)) { -- stats->tx_carrier_errors++; -+ DEV_STATS_INC(dev, tx_carrier_errors); - goto tx_err; - } - skb_dst_set(skb, &rt->dst); -@@ -571,8 +569,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) - return NETDEV_TX_OK; - - tx_err: -- stats->tx_errors++; -- stats->tx_dropped++; -+ DEV_STATS_INC(dev, tx_errors); -+ DEV_STATS_INC(dev, tx_dropped); - kfree_skb(skb); - return NETDEV_TX_OK; - } -diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c -index e65de78cb61bf..e47c670c7e2cd 100644 ---- a/net/xfrm/xfrm_policy.c -+++ b/net/xfrm/xfrm_policy.c -@@ -850,7 +850,7 @@ static void xfrm_policy_inexact_list_reinsert(struct net *net, - struct hlist_node *newpos = NULL; - bool matches_s, matches_d; - -- if (!policy->bydst_reinsert) -+ if (policy->walk.dead || !policy->bydst_reinsert) - continue; - - WARN_ON_ONCE(policy->family != family); -@@ -1255,8 +1255,11 @@ static void xfrm_hash_rebuild(struct work_struct *work) - struct xfrm_pol_inexact_bin *bin; - u8 dbits, sbits; - -+ if (policy->walk.dead) -+ continue; -+ - dir = xfrm_policy_id2dir(policy->index); -- if (policy->walk.dead || dir >= XFRM_POLICY_MAX) -+ if (dir >= XFRM_POLICY_MAX) - continue; - - if ((dir & XFRM_POLICY_MASK) == XFRM_POLICY_OUT) { -@@ -1371,8 +1374,6 @@ EXPORT_SYMBOL(xfrm_policy_hash_rebuild); - * of an absolute inpredictability of ordering of rules. This will not pass. */ - static u32 xfrm_gen_index(struct net *net, int dir, u32 index) - { -- static u32 idx_generator; -- - for (;;) { - struct hlist_head *list; - struct xfrm_policy *p; -@@ -1380,8 +1381,8 @@ static u32 xfrm_gen_index(struct net *net, int dir, u32 index) - int found; - - if (!index) { -- idx = (idx_generator | dir); -- idx_generator += 8; -+ idx = (net->xfrm.idx_generator | dir); -+ net->xfrm.idx_generator += 8; - } else { - idx = index; - index = 0; -@@ -1790,9 +1791,11 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid) - - again: - list_for_each_entry(pol, &net->xfrm.policy_all, walk.all) { -+ if (pol->walk.dead) -+ continue; -+ - dir = xfrm_policy_id2dir(pol->index); -- if (pol->walk.dead || -- dir >= XFRM_POLICY_MAX || -+ if (dir >= XFRM_POLICY_MAX || - pol->type != type) - continue; - -@@ -3138,7 +3141,7 @@ no_transform: - } - - for (i = 0; i < num_pols; i++) -- pols[i]->curlft.use_time = ktime_get_real_seconds(); -+ WRITE_ONCE(pols[i]->curlft.use_time, ktime_get_real_seconds()); - - if (num_xfrms < 0) { - /* Prohibit the flow */ -diff --git a/samples/fprobe/fprobe_example.c b/samples/fprobe/fprobe_example.c -index e22da8573116e..dd794990ad7ec 100644 ---- a/samples/fprobe/fprobe_example.c -+++ b/samples/fprobe/fprobe_example.c -@@ -48,7 +48,8 @@ static void show_backtrace(void) - stack_trace_print(stacks, len, 24); - } - --static void sample_entry_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs) -+static void sample_entry_handler(struct fprobe *fp, unsigned long ip, -+ struct pt_regs *regs, void *data) - { - if (use_trace) - /* -@@ -63,7 +64,8 @@ static void sample_entry_handler(struct fprobe *fp, unsigned long ip, struct pt_ - show_backtrace(); - } - --static void sample_exit_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs) -+static void sample_exit_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs, -+ void *data) - { - unsigned long rip = instruction_pointer(regs); - -diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c -index 80aab2aa72246..ff8cce1757849 100644 ---- a/scripts/kallsyms.c -+++ b/scripts/kallsyms.c -@@ -602,7 +602,10 @@ static void write_src(void) - sort_symbols_by_name(); - output_label("kallsyms_seqs_of_names"); - for (i = 0; i < table_cnt; i++) -- printf("\t.long\t%u\n", table[i]->seq); -+ printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n", -+ (unsigned char)(table[i]->seq >> 16), -+ (unsigned char)(table[i]->seq >> 8), -+ (unsigned char)(table[i]->seq >> 0)); - printf("\n"); - - output_label("kallsyms_token_table"); -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 14e70e2f9c881..0163d4c7fdda8 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -7006,6 +7006,24 @@ static void alc287_fixup_bind_dacs(struct hda_codec *codec, - 0x0); /* Make sure 0x14 was disable */ - } - } -+/* Fix none verb table of Headset Mic pin */ -+static void alc_fixup_headset_mic(struct hda_codec *codec, -+ const struct hda_fixup *fix, int action) -+{ -+ struct alc_spec *spec = codec->spec; -+ static const struct hda_pintbl pincfgs[] = { -+ { 0x19, 0x03a1103c }, -+ { } -+ }; -+ -+ switch (action) { -+ case HDA_FIXUP_ACT_PRE_PROBE: -+ snd_hda_apply_pincfgs(codec, pincfgs); -+ alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12); -+ spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; -+ break; -+ } -+} - - - enum { -@@ -7270,6 +7288,7 @@ enum { - ALC245_FIXUP_HP_X360_MUTE_LEDS, - ALC287_FIXUP_THINKPAD_I2S_SPK, - ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD, -+ ALC2XX_FIXUP_HEADSET_MIC, - }; - - /* A special fixup for Lenovo C940 and Yoga Duet 7; -@@ -9359,6 +9378,10 @@ static const struct hda_fixup alc269_fixups[] = { - .chained = true, - .chain_id = ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI, - }, -+ [ALC2XX_FIXUP_HEADSET_MIC] = { -+ .type = HDA_FIXUP_FUNC, -+ .v.func = alc_fixup_headset_mic, -+ }, - }; - - static const struct snd_pci_quirk alc269_fixup_tbl[] = { -@@ -9626,6 +9649,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), -+ SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), - SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), - SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED), -@@ -9694,6 +9718,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), - SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301V", ALC285_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), -+ SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), - SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), -@@ -10633,6 +10658,8 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = { - SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, - {0x19, 0x40000000}, - {0x1a, 0x40000000}), -+ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC2XX_FIXUP_HEADSET_MIC, -+ {0x19, 0x40000000}), - {} - }; - -diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c -index 9c10200ff34b2..5b5b7c267a616 100644 ---- a/sound/soc/codecs/wcd938x-sdw.c -+++ b/sound/soc/codecs/wcd938x-sdw.c -@@ -1278,7 +1278,31 @@ static int wcd9380_probe(struct sdw_slave *pdev, - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - -- return component_add(dev, &wcd938x_sdw_component_ops); -+ ret = component_add(dev, &wcd938x_sdw_component_ops); -+ if (ret) -+ goto err_disable_rpm; -+ -+ return 0; -+ -+err_disable_rpm: -+ pm_runtime_disable(dev); -+ pm_runtime_set_suspended(dev); -+ pm_runtime_dont_use_autosuspend(dev); -+ -+ return ret; -+} -+ -+static int wcd9380_remove(struct sdw_slave *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ -+ component_del(dev, &wcd938x_sdw_component_ops); -+ -+ pm_runtime_disable(dev); -+ pm_runtime_set_suspended(dev); -+ pm_runtime_dont_use_autosuspend(dev); -+ -+ return 0; - } - - static const struct sdw_device_id wcd9380_slave_id[] = { -@@ -1320,6 +1344,7 @@ static const struct dev_pm_ops wcd938x_sdw_pm_ops = { - - static struct sdw_driver wcd9380_codec_driver = { - .probe = wcd9380_probe, -+ .remove = wcd9380_remove, - .ops = &wcd9380_slave_ops, - .id_table = wcd9380_slave_id, - .driver = { -diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c -index 2316481c2541b..c3964aa00b288 100644 ---- a/sound/soc/codecs/wcd938x.c -+++ b/sound/soc/codecs/wcd938x.c -@@ -3441,7 +3441,8 @@ static int wcd938x_bind(struct device *dev) - wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode); - if (!wcd938x->rxdev) { - dev_err(dev, "could not find slave with matching of node\n"); -- return -EINVAL; -+ ret = -EINVAL; -+ goto err_unbind; - } - wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev); - wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x; -@@ -3449,46 +3450,47 @@ static int wcd938x_bind(struct device *dev) - wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode); - if (!wcd938x->txdev) { - dev_err(dev, "could not find txslave with matching of node\n"); -- return -EINVAL; -+ ret = -EINVAL; -+ goto err_put_rxdev; - } - wcd938x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd938x->txdev); - wcd938x->sdw_priv[AIF1_CAP]->wcd938x = wcd938x; - wcd938x->tx_sdw_dev = dev_to_sdw_dev(wcd938x->txdev); -- if (!wcd938x->tx_sdw_dev) { -- dev_err(dev, "could not get txslave with matching of dev\n"); -- return -EINVAL; -- } - - /* As TX is main CSR reg interface, which should not be suspended first. - * expicilty add the dependency link */ - if (!device_link_add(wcd938x->rxdev, wcd938x->txdev, DL_FLAG_STATELESS | - DL_FLAG_PM_RUNTIME)) { - dev_err(dev, "could not devlink tx and rx\n"); -- return -EINVAL; -+ ret = -EINVAL; -+ goto err_put_txdev; - } - - if (!device_link_add(dev, wcd938x->txdev, DL_FLAG_STATELESS | - DL_FLAG_PM_RUNTIME)) { - dev_err(dev, "could not devlink wcd and tx\n"); -- return -EINVAL; -+ ret = -EINVAL; -+ goto err_remove_rxtx_link; - } - - if (!device_link_add(dev, wcd938x->rxdev, DL_FLAG_STATELESS | - DL_FLAG_PM_RUNTIME)) { - dev_err(dev, "could not devlink wcd and rx\n"); -- return -EINVAL; -+ ret = -EINVAL; -+ goto err_remove_tx_link; - } - - wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL); - if (!wcd938x->regmap) { - dev_err(dev, "could not get TX device regmap\n"); -- return -EINVAL; -+ ret = -EINVAL; -+ goto err_remove_rx_link; - } - - ret = wcd938x_irq_init(wcd938x, dev); - if (ret) { - dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret); -- return ret; -+ goto err_remove_rx_link; - } - - wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq; -@@ -3497,27 +3499,45 @@ static int wcd938x_bind(struct device *dev) - ret = wcd938x_set_micbias_data(wcd938x); - if (ret < 0) { - dev_err(dev, "%s: bad micbias pdata\n", __func__); -- return ret; -+ goto err_remove_rx_link; - } - - ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x, - wcd938x_dais, ARRAY_SIZE(wcd938x_dais)); -- if (ret) -+ if (ret) { - dev_err(dev, "%s: Codec registration failed\n", - __func__); -+ goto err_remove_rx_link; -+ } - -- return ret; -+ return 0; -+ -+err_remove_rx_link: -+ device_link_remove(dev, wcd938x->rxdev); -+err_remove_tx_link: -+ device_link_remove(dev, wcd938x->txdev); -+err_remove_rxtx_link: -+ device_link_remove(wcd938x->rxdev, wcd938x->txdev); -+err_put_txdev: -+ put_device(wcd938x->txdev); -+err_put_rxdev: -+ put_device(wcd938x->rxdev); -+err_unbind: -+ component_unbind_all(dev, wcd938x); - -+ return ret; - } - - static void wcd938x_unbind(struct device *dev) - { - struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); - -+ snd_soc_unregister_component(dev); - device_link_remove(dev, wcd938x->txdev); - device_link_remove(dev, wcd938x->rxdev); - device_link_remove(wcd938x->rxdev, wcd938x->txdev); -- snd_soc_unregister_component(dev); -+ put_device(wcd938x->txdev); -+ put_device(wcd938x->rxdev); - component_unbind_all(dev, wcd938x); - } - -diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c -index 430dd446321e5..452f0caf415b9 100644 ---- a/sound/soc/pxa/pxa-ssp.c -+++ b/sound/soc/pxa/pxa-ssp.c -@@ -779,7 +779,7 @@ static int pxa_ssp_probe(struct snd_soc_dai *dai) - if (IS_ERR(priv->extclk)) { - ret = PTR_ERR(priv->extclk); - if (ret == -EPROBE_DEFER) -- return ret; -+ goto err_priv; - - priv->extclk = NULL; - } -diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc -new file mode 100644 -index 0000000000000..bc9514428dbaf ---- /dev/null -+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc -@@ -0,0 +1,13 @@ -+#!/bin/sh -+# SPDX-License-Identifier: GPL-2.0 -+# description: Test failure of registering kprobe on non unique symbol -+# requires: kprobe_events -+ -+SYMBOL='name_show' -+ -+# We skip this test on kernel where SYMBOL is unique or does not exist. -+if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}" /proc/kallsyms)" -le '1' ]; then -+ exit_unsupported -+fi -+ -+! echo "p:test_non_unique ${SYMBOL}" > kprobe_events -diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh -index 7b20878a1af59..ea6fc59e9f62f 100755 ---- a/tools/testing/selftests/net/mptcp/mptcp_join.sh -+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh -@@ -1413,7 +1413,9 @@ chk_rst_nr() - count=$(get_counter ${ns_tx} "MPTcpExtMPRstTx") - if [ -z "$count" ]; then - echo -n "[skip]" -- elif [ $count -lt $rst_tx ]; then -+ # accept more rst than expected except if we don't expect any -+ elif { [ $rst_tx -ne 0 ] && [ $count -lt $rst_tx ]; } || -+ { [ $rst_tx -eq 0 ] && [ $count -ne 0 ]; }; then - echo "[fail] got $count MP_RST[s] TX expected $rst_tx" - fail_test - dump_stats=1 -@@ -1425,7 +1427,9 @@ chk_rst_nr() - count=$(get_counter ${ns_rx} "MPTcpExtMPRstRx") - if [ -z "$count" ]; then - echo -n "[skip]" -- elif [ "$count" -lt "$rst_rx" ]; then -+ # accept more rst than expected except if we don't expect any -+ elif { [ $rst_rx -ne 0 ] && [ $count -lt $rst_rx ]; } || -+ { [ $rst_rx -eq 0 ] && [ $count -ne 0 ]; }; then - echo "[fail] got $count MP_RST[s] RX expected $rst_rx" - fail_test - dump_stats=1 -@@ -2259,6 +2263,7 @@ remove_tests() - run_tests $ns1 $ns2 10.0.1.1 0 0 -1 slow - chk_join_nr 1 1 1 - chk_rm_nr 1 1 -+ chk_rst_nr 0 0 - fi - - # multiple subflows, remove -@@ -2270,6 +2275,7 @@ remove_tests() - run_tests $ns1 $ns2 10.0.1.1 0 0 -2 slow - chk_join_nr 2 2 2 - chk_rm_nr 2 2 -+ chk_rst_nr 0 0 - fi - - # single address, remove -@@ -2281,6 +2287,7 @@ remove_tests() - chk_join_nr 1 1 1 - chk_add_nr 1 1 - chk_rm_nr 1 1 invert -+ chk_rst_nr 0 0 - fi - - # subflow and signal, remove -@@ -2293,6 +2300,7 @@ remove_tests() - chk_join_nr 2 2 2 - chk_add_nr 1 1 - chk_rm_nr 1 1 -+ chk_rst_nr 0 0 - fi - - # subflows and signal, remove -@@ -2306,6 +2314,7 @@ remove_tests() - chk_join_nr 3 3 3 - chk_add_nr 1 1 - chk_rm_nr 2 2 -+ chk_rst_nr 0 0 - fi - - # addresses remove -@@ -2319,6 +2328,7 @@ remove_tests() - chk_join_nr 3 3 3 - chk_add_nr 3 3 - chk_rm_nr 3 3 invert -+ chk_rst_nr 0 0 - fi - - # invalid addresses remove -@@ -2332,6 +2342,7 @@ remove_tests() - chk_join_nr 1 1 1 - chk_add_nr 3 3 - chk_rm_nr 3 1 invert -+ chk_rst_nr 0 0 - fi - - # subflows and signal, flush -@@ -2345,6 +2356,7 @@ remove_tests() - chk_join_nr 3 3 3 - chk_add_nr 1 1 - chk_rm_nr 1 3 invert simult -+ chk_rst_nr 0 0 - fi - - # subflows flush -@@ -2362,6 +2374,7 @@ remove_tests() - else - chk_rm_nr 3 3 - fi -+ chk_rst_nr 0 0 - fi - - # addresses flush -@@ -2375,6 +2388,7 @@ remove_tests() - chk_join_nr 3 3 3 - chk_add_nr 3 3 - chk_rm_nr 3 3 invert simult -+ chk_rst_nr 0 0 - fi - - # invalid addresses flush -@@ -2388,6 +2402,7 @@ remove_tests() - chk_join_nr 1 1 1 - chk_add_nr 3 3 - chk_rm_nr 3 1 invert -+ chk_rst_nr 0 0 - fi - - # remove id 0 subflow -@@ -2398,6 +2413,7 @@ remove_tests() - run_tests $ns1 $ns2 10.0.1.1 0 0 -9 slow - chk_join_nr 1 1 1 - chk_rm_nr 1 1 -+ chk_rst_nr 0 0 - fi - - # remove id 0 address -@@ -2409,6 +2425,7 @@ remove_tests() - chk_join_nr 1 1 1 - chk_add_nr 1 1 - chk_rm_nr 1 1 invert -+ chk_rst_nr 0 0 invert - fi - } - -diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh -index 7ce46700a3ae3..52054a09d575c 100755 ---- a/tools/testing/selftests/net/openvswitch/openvswitch.sh -+++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh -@@ -3,6 +3,8 @@ - # - # OVS kernel module self tests - -+trap ovs_exit_sig EXIT TERM INT ERR -+ - # Kselftest framework requirement - SKIP code is 4. - ksft_skip=4 - -@@ -115,7 +117,7 @@ run_test() { - fi - - if python3 ovs-dpctl.py -h 2>&1 | \ -- grep "Need to install the python" >/dev/null 2>&1; then -+ grep -E "Need to (install|upgrade) the python" >/dev/null 2>&1; then - stdbuf -o0 printf "TEST: %-60s [PYLIB]\n" "${tdesc}" - return $ksft_skip - fi -diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py -index 5d467d1993cb1..e787a1f967b0d 100644 ---- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py -+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py -@@ -17,8 +17,10 @@ try: - from pyroute2.netlink import nla - from pyroute2.netlink.exceptions import NetlinkError - from pyroute2.netlink.generic import GenericNetlinkSocket -+ import pyroute2 -+ - except ModuleNotFoundError: -- print("Need to install the python pyroute2 package.") -+ print("Need to install the python pyroute2 package >= 0.6.") - sys.exit(0) - - -@@ -280,6 +282,12 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB()): - - - def main(argv): -+ # version check for pyroute2 -+ prverscheck = pyroute2.__version__.split(".") -+ if int(prverscheck[0]) == 0 and int(prverscheck[1]) < 6: -+ print("Need to upgrade the python pyroute2 package to >= 0.6.") -+ sys.exit(0) -+ - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", -diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh -index bb34329e02a7f..5267c88496d51 100755 ---- a/tools/testing/selftests/netfilter/nft_audit.sh -+++ b/tools/testing/selftests/netfilter/nft_audit.sh -@@ -11,6 +11,12 @@ nft --version >/dev/null 2>&1 || { - exit $SKIP_RC - } - -+# Run everything in a separate network namespace -+[ "${1}" != "run" ] && { unshare -n "${0}" run; exit $?; } -+ -+# give other scripts a chance to finish - audit_logread sees all activity -+sleep 1 -+ - logfile=$(mktemp) - rulefile=$(mktemp) - echo "logging into $logfile" -diff --git a/tools/testing/selftests/vm/charge_reserved_hugetlb.sh b/tools/testing/selftests/vm/charge_reserved_hugetlb.sh -index a5cb4b09a46c4..0899019a7fcb4 100644 ---- a/tools/testing/selftests/vm/charge_reserved_hugetlb.sh -+++ b/tools/testing/selftests/vm/charge_reserved_hugetlb.sh -@@ -25,7 +25,7 @@ if [[ "$1" == "-cgroup-v2" ]]; then - fi - - if [[ $cgroup2 ]]; then -- cgroup_path=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') -+ cgroup_path=$(mount -t cgroup2 | head -1 | awk '{print $3}') - if [[ -z "$cgroup_path" ]]; then - cgroup_path=/dev/cgroup/memory - mount -t cgroup2 none $cgroup_path -@@ -33,7 +33,7 @@ if [[ $cgroup2 ]]; then - fi - echo "+hugetlb" >$cgroup_path/cgroup.subtree_control - else -- cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk -e '{print $3}') -+ cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') - if [[ -z "$cgroup_path" ]]; then - cgroup_path=/dev/cgroup/memory - mount -t cgroup memory,hugetlb $cgroup_path -diff --git a/tools/testing/selftests/vm/hugetlb_reparenting_test.sh b/tools/testing/selftests/vm/hugetlb_reparenting_test.sh -index bf2d2a684edfd..14d26075c8635 100644 ---- a/tools/testing/selftests/vm/hugetlb_reparenting_test.sh -+++ b/tools/testing/selftests/vm/hugetlb_reparenting_test.sh -@@ -20,7 +20,7 @@ fi - - - if [[ $cgroup2 ]]; then -- CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') -+ CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk '{print $3}') - if [[ -z "$CGROUP_ROOT" ]]; then - CGROUP_ROOT=/dev/cgroup/memory - mount -t cgroup2 none $CGROUP_ROOT -@@ -28,7 +28,7 @@ if [[ $cgroup2 ]]; then - fi - echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control - else -- CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk -e '{print $3}') -+ CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') - if [[ -z "$CGROUP_ROOT" ]]; then - CGROUP_ROOT=/dev/cgroup/memory - mount -t cgroup memory,hugetlb $CGROUP_ROOT diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.60-61.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.60-61.patch deleted file mode 100644 index a25aac456f99..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.60-61.patch +++ /dev/null @@ -1,2922 +0,0 @@ -diff --git a/Makefile b/Makefile -index d47edcd8888e8..635474f38aaa9 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 60 -+SUBLEVEL = 61 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/omap4-l4-abe.dtsi b/arch/arm/boot/dts/omap4-l4-abe.dtsi -index 7ae8b620515c5..59f546a278f87 100644 ---- a/arch/arm/boot/dts/omap4-l4-abe.dtsi -+++ b/arch/arm/boot/dts/omap4-l4-abe.dtsi -@@ -109,6 +109,8 @@ - reg = <0x0 0xff>, /* MPU private access */ - <0x49022000 0xff>; /* L3 Interconnect */ - reg-names = "mpu", "dma"; -+ clocks = <&abe_clkctrl OMAP4_MCBSP1_CLKCTRL 24>; -+ clock-names = "fck"; - interrupts = ; - interrupt-names = "common"; - ti,buffer-size = <128>; -@@ -142,6 +144,8 @@ - reg = <0x0 0xff>, /* MPU private access */ - <0x49024000 0xff>; /* L3 Interconnect */ - reg-names = "mpu", "dma"; -+ clocks = <&abe_clkctrl OMAP4_MCBSP2_CLKCTRL 24>; -+ clock-names = "fck"; - interrupts = ; - interrupt-names = "common"; - ti,buffer-size = <128>; -@@ -175,6 +179,8 @@ - reg = <0x0 0xff>, /* MPU private access */ - <0x49026000 0xff>; /* L3 Interconnect */ - reg-names = "mpu", "dma"; -+ clocks = <&abe_clkctrl OMAP4_MCBSP3_CLKCTRL 24>; -+ clock-names = "fck"; - interrupts = ; - interrupt-names = "common"; - ti,buffer-size = <128>; -diff --git a/arch/arm/boot/dts/omap4-l4.dtsi b/arch/arm/boot/dts/omap4-l4.dtsi -index 46b8f9efd4131..3fcef3080eaec 100644 ---- a/arch/arm/boot/dts/omap4-l4.dtsi -+++ b/arch/arm/boot/dts/omap4-l4.dtsi -@@ -2043,6 +2043,8 @@ - compatible = "ti,omap4-mcbsp"; - reg = <0x0 0xff>; /* L4 Interconnect */ - reg-names = "mpu"; -+ clocks = <&l4_per_clkctrl OMAP4_MCBSP4_CLKCTRL 24>; -+ clock-names = "fck"; - interrupts = ; - interrupt-names = "common"; - ti,buffer-size = <128>; -diff --git a/arch/arm/boot/dts/omap5-l4-abe.dtsi b/arch/arm/boot/dts/omap5-l4-abe.dtsi -index a03bca5a35844..97b0c3b5f573f 100644 ---- a/arch/arm/boot/dts/omap5-l4-abe.dtsi -+++ b/arch/arm/boot/dts/omap5-l4-abe.dtsi -@@ -109,6 +109,8 @@ - reg = <0x0 0xff>, /* MPU private access */ - <0x49022000 0xff>; /* L3 Interconnect */ - reg-names = "mpu", "dma"; -+ clocks = <&abe_clkctrl OMAP5_MCBSP1_CLKCTRL 24>; -+ clock-names = "fck"; - interrupts = ; - interrupt-names = "common"; - ti,buffer-size = <128>; -@@ -142,6 +144,8 @@ - reg = <0x0 0xff>, /* MPU private access */ - <0x49024000 0xff>; /* L3 Interconnect */ - reg-names = "mpu", "dma"; -+ clocks = <&abe_clkctrl OMAP5_MCBSP2_CLKCTRL 24>; -+ clock-names = "fck"; - interrupts = ; - interrupt-names = "common"; - ti,buffer-size = <128>; -@@ -175,6 +179,8 @@ - reg = <0x0 0xff>, /* MPU private access */ - <0x49026000 0xff>; /* L3 Interconnect */ - reg-names = "mpu", "dma"; -+ clocks = <&abe_clkctrl OMAP5_MCBSP3_CLKCTRL 24>; -+ clock-names = "fck"; - interrupts = ; - interrupt-names = "common"; - ti,buffer-size = <128>; -diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c -index 410d17d1d4431..f618a6df29382 100644 ---- a/arch/arm/mach-omap1/timer32k.c -+++ b/arch/arm/mach-omap1/timer32k.c -@@ -176,17 +176,18 @@ static u64 notrace omap_32k_read_sched_clock(void) - return sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0; - } - -+static struct timespec64 persistent_ts; -+static cycles_t cycles; -+static unsigned int persistent_mult, persistent_shift; -+ - /** - * omap_read_persistent_clock64 - Return time from a persistent clock. -+ * @ts: &struct timespec64 for the returned time - * - * Reads the time from a source which isn't disabled during PM, the - * 32k sync timer. Convert the cycles elapsed since last read into - * nsecs and adds to a monotonically increasing timespec64. - */ --static struct timespec64 persistent_ts; --static cycles_t cycles; --static unsigned int persistent_mult, persistent_shift; -- - static void omap_read_persistent_clock64(struct timespec64 *ts) - { - unsigned long long nsecs; -@@ -206,10 +207,9 @@ static void omap_read_persistent_clock64(struct timespec64 *ts) - /** - * omap_init_clocksource_32k - setup and register counter 32k as a - * kernel clocksource -- * @pbase: base addr of counter_32k module -- * @size: size of counter_32k to map -+ * @vbase: base addr of counter_32k module - * -- * Returns 0 upon success or negative error code upon failure. -+ * Returns: %0 upon success or negative error code upon failure. - * - */ - static int __init omap_init_clocksource_32k(void __iomem *vbase) -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -index 9bdc0b93001f4..b2b3c72a0f87d 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi -@@ -493,6 +493,7 @@ - - &i2s0 { - pinctrl-0 = <&i2s0_2ch_bus>; -+ pinctrl-1 = <&i2s0_2ch_bus_bclk_off>; - rockchip,capture-channels = <2>; - rockchip,playback-channels = <2>; - status = "okay"; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -index 59858f2dc8b9f..5f3caf01badeb 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -@@ -2396,6 +2396,16 @@ - <4 RK_PA0 1 &pcfg_pull_none>; - }; - -+ i2s0_2ch_bus_bclk_off: i2s0-2ch-bus-bclk-off { -+ rockchip,pins = -+ <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>, -+ <3 RK_PD1 1 &pcfg_pull_none>, -+ <3 RK_PD2 1 &pcfg_pull_none>, -+ <3 RK_PD3 1 &pcfg_pull_none>, -+ <3 RK_PD7 1 &pcfg_pull_none>, -+ <4 RK_PA0 1 &pcfg_pull_none>; -+ }; -+ - i2s0_8ch_bus: i2s0-8ch-bus { - rockchip,pins = - <3 RK_PD0 1 &pcfg_pull_none>, -diff --git a/arch/sparc/lib/checksum_32.S b/arch/sparc/lib/checksum_32.S -index 781e39b3c009f..481e94e1f6857 100644 ---- a/arch/sparc/lib/checksum_32.S -+++ b/arch/sparc/lib/checksum_32.S -@@ -453,5 +453,5 @@ ccslow: cmp %g1, 0 - * we only bother with faults on loads... */ - - cc_fault: -- ret -+ retl - clr %o0 -diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h -index 637fa1df35124..c715097e92fd2 100644 ---- a/arch/x86/include/asm/i8259.h -+++ b/arch/x86/include/asm/i8259.h -@@ -69,6 +69,8 @@ struct legacy_pic { - void (*make_irq)(unsigned int irq); - }; - -+void legacy_pic_pcat_compat(void); -+ - extern struct legacy_pic *legacy_pic; - extern struct legacy_pic null_legacy_pic; - -diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h -index b3af2d45bbbb5..5190cc3db771e 100644 ---- a/arch/x86/include/asm/intel-family.h -+++ b/arch/x86/include/asm/intel-family.h -@@ -27,6 +27,7 @@ - * _X - regular server parts - * _D - micro server parts - * _N,_P - other mobile parts -+ * _H - premium mobile parts - * _S - other client parts - * - * Historical OPTDIFFs: -@@ -125,6 +126,7 @@ - - #define INTEL_FAM6_LUNARLAKE_M 0xBD - -+#define INTEL_FAM6_ARROWLAKE_H 0xC5 - #define INTEL_FAM6_ARROWLAKE 0xC6 - - /* "Small Core" Processors (Atom/E-Core) */ -diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c -index 0f762070a5e10..2252340b2133e 100644 ---- a/arch/x86/kernel/acpi/boot.c -+++ b/arch/x86/kernel/acpi/boot.c -@@ -147,6 +147,9 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) - pr_debug("Local APIC address 0x%08x\n", madt->address); - } - -+ if (madt->flags & ACPI_MADT_PCAT_COMPAT) -+ legacy_pic_pcat_compat(); -+ - /* ACPI 6.3 and newer support the online capable bit. */ - if (acpi_gbl_FADT.header.revision > 6 || - (acpi_gbl_FADT.header.revision == 6 && -diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c -index f91e5e31aa4f0..2ac5f488300cf 100644 ---- a/arch/x86/kernel/i8259.c -+++ b/arch/x86/kernel/i8259.c -@@ -32,6 +32,7 @@ - */ - static void init_8259A(int auto_eoi); - -+static bool pcat_compat __ro_after_init; - static int i8259A_auto_eoi; - DEFINE_RAW_SPINLOCK(i8259A_lock); - -@@ -301,15 +302,32 @@ static void unmask_8259A(void) - - static int probe_8259A(void) - { -+ unsigned char new_val, probe_val = ~(1 << PIC_CASCADE_IR); - unsigned long flags; -- unsigned char probe_val = ~(1 << PIC_CASCADE_IR); -- unsigned char new_val; -+ -+ /* -+ * If MADT has the PCAT_COMPAT flag set, then do not bother probing -+ * for the PIC. Some BIOSes leave the PIC uninitialized and probing -+ * fails. -+ * -+ * Right now this causes problems as quite some code depends on -+ * nr_legacy_irqs() > 0 or has_legacy_pic() == true. This is silly -+ * when the system has an IO/APIC because then PIC is not required -+ * at all, except for really old machines where the timer interrupt -+ * must be routed through the PIC. So just pretend that the PIC is -+ * there and let legacy_pic->init() initialize it for nothing. -+ * -+ * Alternatively this could just try to initialize the PIC and -+ * repeat the probe, but for cases where there is no PIC that's -+ * just pointless. -+ */ -+ if (pcat_compat) -+ return nr_legacy_irqs(); -+ - /* -- * Check to see if we have a PIC. -- * Mask all except the cascade and read -- * back the value we just wrote. If we don't -- * have a PIC, we will read 0xff as opposed to the -- * value we wrote. -+ * Check to see if we have a PIC. Mask all except the cascade and -+ * read back the value we just wrote. If we don't have a PIC, we -+ * will read 0xff as opposed to the value we wrote. - */ - raw_spin_lock_irqsave(&i8259A_lock, flags); - -@@ -431,5 +449,9 @@ static int __init i8259A_init_ops(void) - - return 0; - } -- - device_initcall(i8259A_init_ops); -+ -+void __init legacy_pic_pcat_compat(void) -+{ -+ pcat_compat = true; -+} -diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h -index c976490b75568..3666578b88a00 100644 ---- a/arch/x86/kvm/pmu.h -+++ b/arch/x86/kvm/pmu.h -@@ -63,6 +63,12 @@ static inline u64 pmc_read_counter(struct kvm_pmc *pmc) - return counter & pmc_bitmask(pmc); - } - -+static inline void pmc_write_counter(struct kvm_pmc *pmc, u64 val) -+{ -+ pmc->counter += val - pmc_read_counter(pmc); -+ pmc->counter &= pmc_bitmask(pmc); -+} -+ - static inline void pmc_release_perf_event(struct kvm_pmc *pmc) - { - if (pmc->perf_event) { -diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c -index 9d65cd095691b..1cb2bf9808f57 100644 ---- a/arch/x86/kvm/svm/pmu.c -+++ b/arch/x86/kvm/svm/pmu.c -@@ -149,7 +149,7 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) - /* MSR_PERFCTRn */ - pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER); - if (pmc) { -- pmc->counter += data - pmc_read_counter(pmc); -+ pmc_write_counter(pmc, data); - pmc_update_sample_period(pmc); - return 0; - } -diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c -index 9fabfe71fd879..9a75a0d5deae1 100644 ---- a/arch/x86/kvm/vmx/pmu_intel.c -+++ b/arch/x86/kvm/vmx/pmu_intel.c -@@ -461,11 +461,11 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) - if (!msr_info->host_initiated && - !(msr & MSR_PMC_FULL_WIDTH_BIT)) - data = (s64)(s32)data; -- pmc->counter += data - pmc_read_counter(pmc); -+ pmc_write_counter(pmc, data); - pmc_update_sample_period(pmc); - return 0; - } else if ((pmc = get_fixed_pmc(pmu, msr))) { -- pmc->counter += data - pmc_read_counter(pmc); -+ pmc_write_counter(pmc, data); - pmc_update_sample_period(pmc); - return 0; - } else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) { -diff --git a/block/blk-throttle.c b/block/blk-throttle.c -index 1007f80278579..009b0d76bf036 100644 ---- a/block/blk-throttle.c -+++ b/block/blk-throttle.c -@@ -723,6 +723,12 @@ static unsigned int calculate_io_allowed(u32 iops_limit, - - static u64 calculate_bytes_allowed(u64 bps_limit, unsigned long jiffy_elapsed) - { -+ /* -+ * Can result be wider than 64 bits? -+ * We check against 62, not 64, due to ilog2 truncation. -+ */ -+ if (ilog2(bps_limit) + ilog2(jiffy_elapsed) - ilog2(HZ) > 62) -+ return U64_MAX; - return mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed, (u64)HZ); - } - -diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c -index 2b9676416b8e8..e614eb3355d39 100644 ---- a/drivers/ata/libata-scsi.c -+++ b/drivers/ata/libata-scsi.c -@@ -1084,10 +1084,11 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) - - /* - * Ask the sd driver to issue START STOP UNIT on runtime suspend -- * and resume only. For system level suspend/resume, devices -- * power state is handled directly by libata EH. -+ * and resume and shutdown only. For system level suspend/resume, -+ * devices power state is handled directly by libata EH. - */ - sdev->manage_runtime_start_stop = true; -+ sdev->manage_shutdown = true; - } - - /* -diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c -index e0de6565800d2..33fedbd096f33 100644 ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -3340,6 +3340,7 @@ static void possible_parent_show(struct seq_file *s, struct clk_core *core, - unsigned int i, char terminator) - { - struct clk_core *parent; -+ const char *name = NULL; - - /* - * Go through the following options to fetch a parent's name. -@@ -3354,18 +3355,20 @@ static void possible_parent_show(struct seq_file *s, struct clk_core *core, - * registered (yet). - */ - parent = clk_core_get_parent_by_index(core, i); -- if (parent) -+ if (parent) { - seq_puts(s, parent->name); -- else if (core->parents[i].name) -+ } else if (core->parents[i].name) { - seq_puts(s, core->parents[i].name); -- else if (core->parents[i].fw_name) -+ } else if (core->parents[i].fw_name) { - seq_printf(s, "<%s>(fw)", core->parents[i].fw_name); -- else if (core->parents[i].index >= 0) -- seq_puts(s, -- of_clk_get_parent_name(core->of_node, -- core->parents[i].index)); -- else -- seq_puts(s, "(missing)"); -+ } else { -+ if (core->parents[i].index >= 0) -+ name = of_clk_get_parent_name(core->of_node, core->parents[i].index); -+ if (!name) -+ name = "(missing)"; -+ -+ seq_puts(s, name); -+ } - - seq_putc(s, terminator); - } -diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c -index 868bc7af21b0b..9b2824ed785b9 100644 ---- a/drivers/clk/ti/clk-44xx.c -+++ b/drivers/clk/ti/clk-44xx.c -@@ -749,9 +749,14 @@ static struct ti_dt_clk omap44xx_clks[] = { - DT_CLK(NULL, "mcbsp1_sync_mux_ck", "abe-clkctrl:0028:26"), - DT_CLK(NULL, "mcbsp2_sync_mux_ck", "abe-clkctrl:0030:26"), - DT_CLK(NULL, "mcbsp3_sync_mux_ck", "abe-clkctrl:0038:26"), -+ DT_CLK("40122000.mcbsp", "prcm_fck", "abe-clkctrl:0028:26"), -+ DT_CLK("40124000.mcbsp", "prcm_fck", "abe-clkctrl:0030:26"), -+ DT_CLK("40126000.mcbsp", "prcm_fck", "abe-clkctrl:0038:26"), - DT_CLK(NULL, "mcbsp4_sync_mux_ck", "l4-per-clkctrl:00c0:26"), -+ DT_CLK("48096000.mcbsp", "prcm_fck", "l4-per-clkctrl:00c0:26"), - DT_CLK(NULL, "ocp2scp_usb_phy_phy_48m", "l3-init-clkctrl:00c0:8"), - DT_CLK(NULL, "otg_60m_gfclk", "l3-init-clkctrl:0040:24"), -+ DT_CLK(NULL, "pad_fck", "pad_clks_ck"), - DT_CLK(NULL, "per_mcbsp4_gfclk", "l4-per-clkctrl:00c0:24"), - DT_CLK(NULL, "pmd_stm_clock_mux_ck", "emu-sys-clkctrl:0000:20"), - DT_CLK(NULL, "pmd_trace_clk_mux_ck", "emu-sys-clkctrl:0000:22"), -diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c -index b4aff76eb3735..74dfd5823f835 100644 ---- a/drivers/clk/ti/clk-54xx.c -+++ b/drivers/clk/ti/clk-54xx.c -@@ -565,15 +565,19 @@ static struct ti_dt_clk omap54xx_clks[] = { - DT_CLK(NULL, "gpio8_dbclk", "l4per-clkctrl:00f8:8"), - DT_CLK(NULL, "mcbsp1_gfclk", "abe-clkctrl:0028:24"), - DT_CLK(NULL, "mcbsp1_sync_mux_ck", "abe-clkctrl:0028:26"), -+ DT_CLK("40122000.mcbsp", "prcm_fck", "abe-clkctrl:0028:26"), - DT_CLK(NULL, "mcbsp2_gfclk", "abe-clkctrl:0030:24"), - DT_CLK(NULL, "mcbsp2_sync_mux_ck", "abe-clkctrl:0030:26"), -+ DT_CLK("40124000.mcbsp", "prcm_fck", "abe-clkctrl:0030:26"), - DT_CLK(NULL, "mcbsp3_gfclk", "abe-clkctrl:0038:24"), - DT_CLK(NULL, "mcbsp3_sync_mux_ck", "abe-clkctrl:0038:26"), -+ DT_CLK("40126000.mcbsp", "prcm_fck", "abe-clkctrl:0038:26"), - DT_CLK(NULL, "mmc1_32khz_clk", "l3init-clkctrl:0008:8"), - DT_CLK(NULL, "mmc1_fclk", "l3init-clkctrl:0008:25"), - DT_CLK(NULL, "mmc1_fclk_mux", "l3init-clkctrl:0008:24"), - DT_CLK(NULL, "mmc2_fclk", "l3init-clkctrl:0010:25"), - DT_CLK(NULL, "mmc2_fclk_mux", "l3init-clkctrl:0010:24"), -+ DT_CLK(NULL, "pad_fck", "pad_clks_ck"), - DT_CLK(NULL, "sata_ref_clk", "l3init-clkctrl:0068:8"), - DT_CLK(NULL, "timer10_gfclk_mux", "l4per-clkctrl:0008:24"), - DT_CLK(NULL, "timer11_gfclk_mux", "l4per-clkctrl:0010:24"), -diff --git a/drivers/crypto/virtio/virtio_crypto_common.h b/drivers/crypto/virtio/virtio_crypto_common.h -index 59a4c02594563..154590e1f7643 100644 ---- a/drivers/crypto/virtio/virtio_crypto_common.h -+++ b/drivers/crypto/virtio/virtio_crypto_common.h -@@ -35,6 +35,9 @@ struct virtio_crypto { - struct virtqueue *ctrl_vq; - struct data_queue *data_vq; - -+ /* Work struct for config space updates */ -+ struct work_struct config_work; -+ - /* To protect the vq operations for the controlq */ - spinlock_t ctrl_lock; - -diff --git a/drivers/crypto/virtio/virtio_crypto_core.c b/drivers/crypto/virtio/virtio_crypto_core.c -index 1198bd3063655..3842915ea7437 100644 ---- a/drivers/crypto/virtio/virtio_crypto_core.c -+++ b/drivers/crypto/virtio/virtio_crypto_core.c -@@ -335,6 +335,14 @@ static void virtcrypto_del_vqs(struct virtio_crypto *vcrypto) - virtcrypto_free_queues(vcrypto); - } - -+static void vcrypto_config_changed_work(struct work_struct *work) -+{ -+ struct virtio_crypto *vcrypto = -+ container_of(work, struct virtio_crypto, config_work); -+ -+ virtcrypto_update_status(vcrypto); -+} -+ - static int virtcrypto_probe(struct virtio_device *vdev) - { - int err = -EFAULT; -@@ -454,6 +462,8 @@ static int virtcrypto_probe(struct virtio_device *vdev) - if (err) - goto free_engines; - -+ INIT_WORK(&vcrypto->config_work, vcrypto_config_changed_work); -+ - return 0; - - free_engines: -@@ -489,6 +499,7 @@ static void virtcrypto_remove(struct virtio_device *vdev) - - dev_info(&vdev->dev, "Start virtcrypto_remove.\n"); - -+ flush_work(&vcrypto->config_work); - if (virtcrypto_dev_started(vcrypto)) - virtcrypto_dev_stop(vcrypto); - virtio_reset_device(vdev); -@@ -503,7 +514,7 @@ static void virtcrypto_config_changed(struct virtio_device *vdev) - { - struct virtio_crypto *vcrypto = vdev->priv; - -- virtcrypto_update_status(vcrypto); -+ schedule_work(&vcrypto->config_work); - } - - #ifdef CONFIG_PM_SLEEP -@@ -511,6 +522,7 @@ static int virtcrypto_freeze(struct virtio_device *vdev) - { - struct virtio_crypto *vcrypto = vdev->priv; - -+ flush_work(&vcrypto->config_work); - virtio_reset_device(vdev); - virtcrypto_free_unused_reqs(vcrypto); - if (virtcrypto_dev_started(vcrypto)) -diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c -index e322a326546b5..7ad2e03afd4e5 100644 ---- a/drivers/firewire/sbp2.c -+++ b/drivers/firewire/sbp2.c -@@ -1521,6 +1521,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) - if (sbp2_param_exclusive_login) { - sdev->manage_system_start_stop = true; - sdev->manage_runtime_start_stop = true; -+ sdev->manage_shutdown = true; - } - - if (sdev->type == TYPE_ROM) -diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c -index 1f410809d3ee4..0f656e4191d5c 100644 ---- a/drivers/firmware/imx/imx-dsp.c -+++ b/drivers/firmware/imx/imx-dsp.c -@@ -115,11 +115,11 @@ static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) - dsp_chan->idx = i % 2; - dsp_chan->ch = mbox_request_channel_byname(cl, chan_name); - if (IS_ERR(dsp_chan->ch)) { -- kfree(dsp_chan->name); - ret = PTR_ERR(dsp_chan->ch); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to request mbox chan %s ret %d\n", - chan_name, ret); -+ kfree(dsp_chan->name); - goto out; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c -index 53a3bb7fc9c47..1bfd7b49fe9c3 100644 ---- a/drivers/gpu/drm/amd/amdgpu/vi.c -+++ b/drivers/gpu/drm/amd/amdgpu/vi.c -@@ -1147,7 +1147,7 @@ static void vi_program_aspm(struct amdgpu_device *adev) - bool bL1SS = false; - bool bClkReqSupport = true; - -- if (!amdgpu_device_should_use_aspm(adev) || !amdgpu_device_aspm_support_quirk()) -+ if (!amdgpu_device_should_use_aspm(adev) || !amdgpu_device_pcie_dynamic_switching_supported()) - return; - - if (adev->flags & AMD_IS_APU || -diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c -index f854cb5eafbe7..72b2b171e533e 100644 ---- a/drivers/gpu/drm/display/drm_dp_mst_topology.c -+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c -@@ -2574,14 +2574,14 @@ static struct drm_dp_mst_branch *get_mst_branch_device_by_guid_helper( - struct drm_dp_mst_branch *found_mstb; - struct drm_dp_mst_port *port; - -+ if (!mstb) -+ return NULL; -+ - if (memcmp(mstb->guid, guid, 16) == 0) - return mstb; - - - list_for_each_entry(port, &mstb->ports, next) { -- if (!port->mstb) -- continue; -- - found_mstb = get_mst_branch_device_by_guid_helper(port->mstb, guid); - - if (found_mstb) -diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c -index 958b37123bf12..89eec585880f0 100644 ---- a/drivers/gpu/drm/i915/i915_pmu.c -+++ b/drivers/gpu/drm/i915/i915_pmu.c -@@ -760,9 +760,18 @@ static void i915_pmu_event_start(struct perf_event *event, int flags) - - static void i915_pmu_event_stop(struct perf_event *event, int flags) - { -+ struct drm_i915_private *i915 = -+ container_of(event->pmu, typeof(*i915), pmu.base); -+ struct i915_pmu *pmu = &i915->pmu; -+ -+ if (pmu->closed) -+ goto out; -+ - if (flags & PERF_EF_UPDATE) - i915_pmu_event_read(event); - i915_pmu_disable(event); -+ -+out: - event->hw.state = PERF_HES_STOPPED; - } - -diff --git a/drivers/gpu/drm/logicvc/Kconfig b/drivers/gpu/drm/logicvc/Kconfig -index fa7a883688094..1df22a852a23e 100644 ---- a/drivers/gpu/drm/logicvc/Kconfig -+++ b/drivers/gpu/drm/logicvc/Kconfig -@@ -5,5 +5,7 @@ config DRM_LOGICVC - select DRM_KMS_HELPER - select DRM_KMS_DMA_HELPER - select DRM_GEM_DMA_HELPER -+ select REGMAP -+ select REGMAP_MMIO - help - DRM display driver for the logiCVC programmable logic block from Xylon -diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index 866c52afb8b0a..6adf3b141316b 100644 ---- a/drivers/i2c/busses/i2c-aspeed.c -+++ b/drivers/i2c/busses/i2c-aspeed.c -@@ -749,6 +749,8 @@ static void __aspeed_i2c_reg_slave(struct aspeed_i2c_bus *bus, u16 slave_addr) - func_ctrl_reg_val = readl(bus->base + ASPEED_I2C_FUN_CTRL_REG); - func_ctrl_reg_val |= ASPEED_I2CD_SLAVE_EN; - writel(func_ctrl_reg_val, bus->base + ASPEED_I2C_FUN_CTRL_REG); -+ -+ bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; - } - - static int aspeed_i2c_reg_slave(struct i2c_client *client) -@@ -765,7 +767,6 @@ static int aspeed_i2c_reg_slave(struct i2c_client *client) - __aspeed_i2c_reg_slave(bus, client->addr); - - bus->slave = client; -- bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; - spin_unlock_irqrestore(&bus->lock, flags); - - return 0; -diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c -index d1c59d83a65b9..cb995449ebf3d 100644 ---- a/drivers/i2c/busses/i2c-stm32f7.c -+++ b/drivers/i2c/busses/i2c-stm32f7.c -@@ -1059,9 +1059,10 @@ static int stm32f7_i2c_smbus_xfer_msg(struct stm32f7_i2c_dev *i2c_dev, - /* Configure PEC */ - if ((flags & I2C_CLIENT_PEC) && f7_msg->size != I2C_SMBUS_QUICK) { - cr1 |= STM32F7_I2C_CR1_PECEN; -- cr2 |= STM32F7_I2C_CR2_PECBYTE; -- if (!f7_msg->read_write) -+ if (!f7_msg->read_write) { -+ cr2 |= STM32F7_I2C_CR2_PECBYTE; - f7_msg->count++; -+ } - } else { - cr1 &= ~STM32F7_I2C_CR1_PECEN; - cr2 &= ~STM32F7_I2C_CR2_PECBYTE; -@@ -1149,8 +1150,10 @@ static void stm32f7_i2c_smbus_rep_start(struct stm32f7_i2c_dev *i2c_dev) - f7_msg->stop = true; - - /* Add one byte for PEC if needed */ -- if (cr1 & STM32F7_I2C_CR1_PECEN) -+ if (cr1 & STM32F7_I2C_CR1_PECEN) { -+ cr2 |= STM32F7_I2C_CR2_PECBYTE; - f7_msg->count++; -+ } - - /* Set number of bytes to be transferred */ - cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK); -diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c -index 8e8688e8de0fb..45a3f7e7b3f68 100644 ---- a/drivers/i2c/muxes/i2c-demux-pinctrl.c -+++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c -@@ -61,7 +61,7 @@ static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 ne - if (ret) - goto err; - -- adap = of_find_i2c_adapter_by_node(priv->chan[new_chan].parent_np); -+ adap = of_get_i2c_adapter_by_node(priv->chan[new_chan].parent_np); - if (!adap) { - ret = -ENODEV; - goto err_with_revert; -diff --git a/drivers/i2c/muxes/i2c-mux-gpmux.c b/drivers/i2c/muxes/i2c-mux-gpmux.c -index 33024acaac02b..0ebc12575081c 100644 ---- a/drivers/i2c/muxes/i2c-mux-gpmux.c -+++ b/drivers/i2c/muxes/i2c-mux-gpmux.c -@@ -52,7 +52,7 @@ static struct i2c_adapter *mux_parent_adapter(struct device *dev) - dev_err(dev, "Cannot parse i2c-parent\n"); - return ERR_PTR(-ENODEV); - } -- parent = of_find_i2c_adapter_by_node(parent_np); -+ parent = of_get_i2c_adapter_by_node(parent_np); - of_node_put(parent_np); - if (!parent) - return ERR_PTR(-EPROBE_DEFER); -diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c -index d5ad904756fdf..f0bc4f3994817 100644 ---- a/drivers/i2c/muxes/i2c-mux-pinctrl.c -+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c -@@ -62,7 +62,7 @@ static struct i2c_adapter *i2c_mux_pinctrl_parent_adapter(struct device *dev) - dev_err(dev, "Cannot parse i2c-parent\n"); - return ERR_PTR(-ENODEV); - } -- parent = of_find_i2c_adapter_by_node(parent_np); -+ parent = of_get_i2c_adapter_by_node(parent_np); - of_node_put(parent_np); - if (!parent) - return ERR_PTR(-EPROBE_DEFER); -diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c -index cff1ba57fb16a..43c8af41b4a9d 100644 ---- a/drivers/iio/adc/exynos_adc.c -+++ b/drivers/iio/adc/exynos_adc.c -@@ -826,16 +826,26 @@ static int exynos_adc_probe(struct platform_device *pdev) - } - } - -+ /* leave out any TS related code if unreachable */ -+ if (IS_REACHABLE(CONFIG_INPUT)) { -+ has_ts = of_property_read_bool(pdev->dev.of_node, -+ "has-touchscreen") || pdata; -+ } -+ - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - info->irq = irq; - -- irq = platform_get_irq(pdev, 1); -- if (irq == -EPROBE_DEFER) -- return irq; -+ if (has_ts) { -+ irq = platform_get_irq(pdev, 1); -+ if (irq == -EPROBE_DEFER) -+ return irq; - -- info->tsirq = irq; -+ info->tsirq = irq; -+ } else { -+ info->tsirq = -1; -+ } - - info->dev = &pdev->dev; - -@@ -900,12 +910,6 @@ static int exynos_adc_probe(struct platform_device *pdev) - if (info->data->init_hw) - info->data->init_hw(info); - -- /* leave out any TS related code if unreachable */ -- if (IS_REACHABLE(CONFIG_INPUT)) { -- has_ts = of_property_read_bool(pdev->dev.of_node, -- "has-touchscreen") || pdata; -- } -- - if (pdata) - info->delay = pdata->delay; - else -diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c -index 292f2892d223a..abb8891b9e82d 100644 ---- a/drivers/iio/adc/xilinx-xadc-core.c -+++ b/drivers/iio/adc/xilinx-xadc-core.c -@@ -456,6 +456,9 @@ static const struct xadc_ops xadc_zynq_ops = { - .interrupt_handler = xadc_zynq_interrupt_handler, - .update_alarm = xadc_zynq_update_alarm, - .type = XADC_TYPE_S7, -+ /* Temp in C = (val * 503.975) / 2**bits - 273.15 */ -+ .temp_scale = 503975, -+ .temp_offset = 273150, - }; - - static const unsigned int xadc_axi_reg_offsets[] = { -@@ -566,6 +569,9 @@ static const struct xadc_ops xadc_7s_axi_ops = { - .interrupt_handler = xadc_axi_interrupt_handler, - .flags = XADC_FLAGS_BUFFERED | XADC_FLAGS_IRQ_OPTIONAL, - .type = XADC_TYPE_S7, -+ /* Temp in C = (val * 503.975) / 2**bits - 273.15 */ -+ .temp_scale = 503975, -+ .temp_offset = 273150, - }; - - static const struct xadc_ops xadc_us_axi_ops = { -@@ -577,6 +583,12 @@ static const struct xadc_ops xadc_us_axi_ops = { - .interrupt_handler = xadc_axi_interrupt_handler, - .flags = XADC_FLAGS_BUFFERED | XADC_FLAGS_IRQ_OPTIONAL, - .type = XADC_TYPE_US, -+ /** -+ * Values below are for UltraScale+ (SYSMONE4) using internal reference. -+ * See https://docs.xilinx.com/v/u/en-US/ug580-ultrascale-sysmon -+ */ -+ .temp_scale = 509314, -+ .temp_offset = 280231, - }; - - static int _xadc_update_adc_reg(struct xadc *xadc, unsigned int reg, -@@ -948,8 +960,7 @@ static int xadc_read_raw(struct iio_dev *indio_dev, - *val2 = bits; - return IIO_VAL_FRACTIONAL_LOG2; - case IIO_TEMP: -- /* Temp in C = (val * 503.975) / 2**bits - 273.15 */ -- *val = 503975; -+ *val = xadc->ops->temp_scale; - *val2 = bits; - return IIO_VAL_FRACTIONAL_LOG2; - default: -@@ -957,7 +968,7 @@ static int xadc_read_raw(struct iio_dev *indio_dev, - } - case IIO_CHAN_INFO_OFFSET: - /* Only the temperature channel has an offset */ -- *val = -((273150 << bits) / 503975); -+ *val = -((xadc->ops->temp_offset << bits) / xadc->ops->temp_scale); - return IIO_VAL_INT; - case IIO_CHAN_INFO_SAMP_FREQ: - ret = xadc_read_samplerate(xadc); -@@ -1426,28 +1437,6 @@ static int xadc_probe(struct platform_device *pdev) - if (ret) - return ret; - -- /* Disable all alarms */ -- ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_ALARM_MASK, -- XADC_CONF1_ALARM_MASK); -- if (ret) -- return ret; -- -- /* Set thresholds to min/max */ -- for (i = 0; i < 16; i++) { -- /* -- * Set max voltage threshold and both temperature thresholds to -- * 0xffff, min voltage threshold to 0. -- */ -- if (i % 8 < 4 || i == 7) -- xadc->threshold[i] = 0xffff; -- else -- xadc->threshold[i] = 0; -- ret = xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i), -- xadc->threshold[i]); -- if (ret) -- return ret; -- } -- - /* Go to non-buffered mode */ - xadc_postdisable(indio_dev); - -diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h -index 7d78ce6989671..3036f4d613ff5 100644 ---- a/drivers/iio/adc/xilinx-xadc.h -+++ b/drivers/iio/adc/xilinx-xadc.h -@@ -85,6 +85,8 @@ struct xadc_ops { - - unsigned int flags; - enum xadc_type type; -+ int temp_scale; -+ int temp_offset; - }; - - static inline int _xadc_read_adc_reg(struct xadc *xadc, unsigned int reg, -diff --git a/drivers/iio/afe/iio-rescale.c b/drivers/iio/afe/iio-rescale.c -index 1f280c360701b..56e5913ab82d1 100644 ---- a/drivers/iio/afe/iio-rescale.c -+++ b/drivers/iio/afe/iio-rescale.c -@@ -214,8 +214,18 @@ static int rescale_read_raw(struct iio_dev *indio_dev, - return ret < 0 ? ret : -EOPNOTSUPP; - } - -- ret = iio_read_channel_scale(rescale->source, &scale, &scale2); -- return rescale_process_offset(rescale, ret, scale, scale2, -+ if (iio_channel_has_info(rescale->source->channel, -+ IIO_CHAN_INFO_SCALE)) { -+ ret = iio_read_channel_scale(rescale->source, &scale, &scale2); -+ return rescale_process_offset(rescale, ret, scale, scale2, -+ schan_off, val, val2); -+ } -+ -+ /* -+ * If we get here we have no scale so scale 1:1 but apply -+ * rescaler and offset, if any. -+ */ -+ return rescale_process_offset(rescale, IIO_VAL_FRACTIONAL, 1, 1, - schan_off, val, val2); - default: - return -EINVAL; -@@ -280,8 +290,9 @@ static int rescale_configure_channel(struct device *dev, - chan->type = rescale->cfg->type; - - if (iio_channel_has_info(schan, IIO_CHAN_INFO_RAW) && -- iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE)) { -- dev_info(dev, "using raw+scale source channel\n"); -+ (iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE) || -+ iio_channel_has_info(schan, IIO_CHAN_INFO_OFFSET))) { -+ dev_info(dev, "using raw+scale/offset source channel\n"); - } else if (iio_channel_has_info(schan, IIO_CHAN_INFO_PROCESSED)) { - dev_info(dev, "using processed channel\n"); - rescale->chan_processed = true; -diff --git a/drivers/mcb/mcb-lpc.c b/drivers/mcb/mcb-lpc.c -index 53decd89876ee..a851e02364642 100644 ---- a/drivers/mcb/mcb-lpc.c -+++ b/drivers/mcb/mcb-lpc.c -@@ -23,7 +23,7 @@ static int mcb_lpc_probe(struct platform_device *pdev) - { - struct resource *res; - struct priv *priv; -- int ret = 0; -+ int ret = 0, table_size; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -58,16 +58,43 @@ static int mcb_lpc_probe(struct platform_device *pdev) - - ret = chameleon_parse_cells(priv->bus, priv->mem->start, priv->base); - if (ret < 0) { -- mcb_release_bus(priv->bus); -- return ret; -+ goto out_mcb_bus; - } - -- dev_dbg(&pdev->dev, "Found %d cells\n", ret); -+ table_size = ret; -+ -+ if (table_size < CHAM_HEADER_SIZE) { -+ /* Release the previous resources */ -+ devm_iounmap(&pdev->dev, priv->base); -+ devm_release_mem_region(&pdev->dev, priv->mem->start, resource_size(priv->mem)); -+ -+ /* Then, allocate it again with the actual chameleon table size */ -+ res = devm_request_mem_region(&pdev->dev, priv->mem->start, -+ table_size, -+ KBUILD_MODNAME); -+ if (!res) { -+ dev_err(&pdev->dev, "Failed to request PCI memory\n"); -+ ret = -EBUSY; -+ goto out_mcb_bus; -+ } -+ -+ priv->base = devm_ioremap(&pdev->dev, priv->mem->start, table_size); -+ if (!priv->base) { -+ dev_err(&pdev->dev, "Cannot ioremap\n"); -+ ret = -ENOMEM; -+ goto out_mcb_bus; -+ } -+ -+ platform_set_drvdata(pdev, priv); -+ } - - mcb_bus_add_devices(priv->bus); - - return 0; - -+out_mcb_bus: -+ mcb_release_bus(priv->bus); -+ return ret; - } - - static int mcb_lpc_remove(struct platform_device *pdev) -diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c -index c41cbacc75a2c..656b6b71c7682 100644 ---- a/drivers/mcb/mcb-parse.c -+++ b/drivers/mcb/mcb-parse.c -@@ -128,7 +128,7 @@ static void chameleon_parse_bar(void __iomem *base, - } - } - --static int chameleon_get_bar(char __iomem **base, phys_addr_t mapbase, -+static int chameleon_get_bar(void __iomem **base, phys_addr_t mapbase, - struct chameleon_bar **cb) - { - struct chameleon_bar *c; -@@ -177,12 +177,13 @@ int chameleon_parse_cells(struct mcb_bus *bus, phys_addr_t mapbase, - { - struct chameleon_fpga_header *header; - struct chameleon_bar *cb; -- char __iomem *p = base; -+ void __iomem *p = base; - int num_cells = 0; - uint32_t dtype; - int bar_count; - int ret; - u32 hsize; -+ u32 table_size; - - hsize = sizeof(struct chameleon_fpga_header); - -@@ -237,12 +238,16 @@ int chameleon_parse_cells(struct mcb_bus *bus, phys_addr_t mapbase, - num_cells++; - } - -- if (num_cells == 0) -- num_cells = -EINVAL; -+ if (num_cells == 0) { -+ ret = -EINVAL; -+ goto free_bar; -+ } - -+ table_size = p - base; -+ pr_debug("%d cell(s) found. Chameleon table size: 0x%04x bytes\n", num_cells, table_size); - kfree(cb); - kfree(header); -- return num_cells; -+ return table_size; - - free_bar: - kfree(cb); -diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c -index 4c51d216f3d43..cc57cc8204328 100644 ---- a/drivers/misc/fastrpc.c -+++ b/drivers/misc/fastrpc.c -@@ -903,6 +903,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) - if (err) - return err; - -+ memset(ctx->buf->virt, 0, pkt_size); - rpra = ctx->buf->virt; - list = fastrpc_invoke_buf_start(rpra, ctx->nscalars); - pages = fastrpc_phy_page_start(list, ctx->nscalars); -@@ -1035,6 +1036,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, - } - } - -+ /* Clean up fdlist which is updated by DSP */ - for (i = 0; i < FASTRPC_MAX_FDLIST; i++) { - if (!fdlist[i]) - break; -@@ -1099,11 +1101,9 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, - if (IS_ERR(ctx)) - return PTR_ERR(ctx); - -- if (ctx->nscalars) { -- err = fastrpc_get_args(kernel, ctx); -- if (err) -- goto bail; -- } -+ err = fastrpc_get_args(kernel, ctx); -+ if (err) -+ goto bail; - - /* make sure that all CPU memory writes are seen by DSP */ - dma_wmb(); -@@ -1119,6 +1119,13 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, - err = wait_for_completion_interruptible(&ctx->work); - } - -+ if (err) -+ goto bail; -+ -+ /* make sure that all memory writes by DSP are seen by CPU */ -+ dma_rmb(); -+ /* populate all the output buffers with results */ -+ err = fastrpc_put_args(ctx, kernel); - if (err) - goto bail; - -@@ -1127,15 +1134,6 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, - if (err) - goto bail; - -- if (ctx->nscalars) { -- /* make sure that all memory writes by DSP are seen by CPU */ -- dma_rmb(); -- /* populate all the output buffers with results */ -- err = fastrpc_put_args(ctx, kernel); -- if (err) -- goto bail; -- } -- - bail: - if (err != -ERESTARTSYS && err != -ETIMEDOUT) { - /* We are done with this compute context */ -@@ -1785,11 +1783,13 @@ static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_me - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0); - err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, - &args[0]); -- fastrpc_map_put(map); -- if (err) -+ if (err) { - dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n", map->fd, map->raddr); -+ return err; -+ } -+ fastrpc_map_put(map); - -- return err; -+ return 0; - } - - static int fastrpc_req_mem_unmap(struct fastrpc_user *fl, char __user *argp) -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index cdd7f126d4aea..1fc6767f18782 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -180,6 +180,8 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, - int recovery_mode, - struct mmc_queue *mq); - static void mmc_blk_hsq_req_done(struct mmc_request *mrq); -+static int mmc_spi_err_check(struct mmc_card *card); -+static int mmc_blk_busy_cb(void *cb_data, bool *busy); - - static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) - { -@@ -471,6 +473,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - struct mmc_data data = {}; - struct mmc_request mrq = {}; - struct scatterlist sg; -+ bool r1b_resp; -+ unsigned int busy_timeout_ms; - int err; - unsigned int target_part; - -@@ -559,6 +563,12 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - (cmd.opcode == MMC_SWITCH)) - return mmc_sanitize(card, idata->ic.cmd_timeout_ms); - -+ /* If it's an R1B response we need some more preparations. */ -+ busy_timeout_ms = idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS; -+ r1b_resp = (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B; -+ if (r1b_resp) -+ mmc_prepare_busy_cmd(card->host, &cmd, busy_timeout_ms); -+ - mmc_wait_for_req(card->host, &mrq); - memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp)); - -@@ -610,13 +620,27 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - if (idata->ic.postsleep_min_us) - usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); - -- if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { -- /* -- * Ensure RPMB/R1B command has completed by polling CMD13 "Send Status". Here we -- * allow to override the default timeout value if a custom timeout is specified. -- */ -- err = mmc_poll_for_busy(card, idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS, -- false, MMC_BUSY_IO); -+ if (mmc_host_is_spi(card->host)) { -+ if (idata->ic.write_flag || r1b_resp || cmd.flags & MMC_RSP_SPI_BUSY) -+ return mmc_spi_err_check(card); -+ return err; -+ } -+ -+ /* -+ * Ensure RPMB, writes and R1B responses are completed by polling with -+ * CMD13. Note that, usually we don't need to poll when using HW busy -+ * detection, but here it's needed since some commands may indicate the -+ * error through the R1 status bits. -+ */ -+ if (idata->rpmb || idata->ic.write_flag || r1b_resp) { -+ struct mmc_blk_busy_data cb_data = { -+ .card = card, -+ }; -+ -+ err = __mmc_poll_for_busy(card->host, 0, busy_timeout_ms, -+ &mmc_blk_busy_cb, &cb_data); -+ -+ idata->ic.response[0] = cb_data.status; - } - - return err; -diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c -index 81c55bfd6e0c2..3b3adbddf6641 100644 ---- a/drivers/mmc/core/mmc_ops.c -+++ b/drivers/mmc/core/mmc_ops.c -@@ -575,6 +575,7 @@ bool mmc_prepare_busy_cmd(struct mmc_host *host, struct mmc_command *cmd, - cmd->busy_timeout = timeout_ms; - return true; - } -+EXPORT_SYMBOL_GPL(mmc_prepare_busy_cmd); - - /** - * __mmc_switch - modify EXT_CSD register -diff --git a/drivers/net/ethernet/adi/adin1110.c b/drivers/net/ethernet/adi/adin1110.c -index ed2863ed6a5bb..7474afc0e8e73 100644 ---- a/drivers/net/ethernet/adi/adin1110.c -+++ b/drivers/net/ethernet/adi/adin1110.c -@@ -294,7 +294,7 @@ static int adin1110_read_fifo(struct adin1110_port_priv *port_priv) - { - struct adin1110_priv *priv = port_priv->priv; - u32 header_len = ADIN1110_RD_HEADER_LEN; -- struct spi_transfer t; -+ struct spi_transfer t = {0}; - u32 frame_size_no_fcs; - struct sk_buff *rxb; - u32 frame_size; -diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h -index a81f918091ccf..7d4cc4eafd59e 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e.h -+++ b/drivers/net/ethernet/intel/i40e/i40e.h -@@ -580,7 +580,6 @@ struct i40e_pf { - #define I40E_FLAG_DISABLE_FW_LLDP BIT(24) - #define I40E_FLAG_RS_FEC BIT(25) - #define I40E_FLAG_BASE_R_FEC BIT(26) --#define I40E_FLAG_VF_VLAN_PRUNING BIT(27) - /* TOTAL_PORT_SHUTDOWN - * Allows to physically disable the link on the NIC's port. - * If enabled, (after link down request from the OS) -@@ -603,6 +602,7 @@ struct i40e_pf { - * in abilities field of i40e_aq_set_phy_config structure - */ - #define I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED BIT(27) -+#define I40E_FLAG_VF_VLAN_PRUNING BIT(28) - - struct i40e_client_instance *cinst; - bool stat_offsets_loaded; -diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c -index 494775d65bf28..6d26ee8eefae9 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c -@@ -2770,7 +2770,7 @@ tx_only: - return budget; - } - -- if (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR) -+ if (q_vector->tx.ring[0].flags & I40E_TXR_FLAGS_WB_ON_ITR) - q_vector->arm_wb_state = false; - - /* Exit the polling mode, but don't re-enable interrupts if stack might -diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c -index a39f7f0d6ab0b..326bb5fdf5f90 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_main.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c -@@ -1449,9 +1449,9 @@ void iavf_down(struct iavf_adapter *adapter) - adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER; - if (!list_empty(&adapter->adv_rss_list_head)) - adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG; -- adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES; - } - -+ adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES; - mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); - } - -@@ -5020,8 +5020,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - INIT_WORK(&adapter->finish_config, iavf_finish_config); - INIT_DELAYED_WORK(&adapter->watchdog_task, iavf_watchdog_task); - INIT_DELAYED_WORK(&adapter->client_task, iavf_client_task); -- queue_delayed_work(adapter->wq, &adapter->watchdog_task, -- msecs_to_jiffies(5 * (pdev->devfn & 0x07))); - - /* Setup the wait queue for indicating transition to down status */ - init_waitqueue_head(&adapter->down_waitqueue); -@@ -5032,6 +5030,9 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - /* Setup the wait queue for indicating virtchannel events */ - init_waitqueue_head(&adapter->vc_waitqueue); - -+ queue_delayed_work(adapter->wq, &adapter->watchdog_task, -+ msecs_to_jiffies(5 * (pdev->devfn & 0x07))); -+ /* Initialization goes on in the work. Do not add more of it below. */ - return 0; - - err_ioremap: -diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c -index 96fa1c420f910..ceff537d9d22d 100644 ---- a/drivers/net/ethernet/intel/igb/igb_ethtool.c -+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c -@@ -2978,11 +2978,15 @@ static int igb_add_ethtool_nfc_entry(struct igb_adapter *adapter, - if (err) - goto err_out_w_lock; - -- igb_update_ethtool_nfc_entry(adapter, input, input->sw_idx); -+ err = igb_update_ethtool_nfc_entry(adapter, input, input->sw_idx); -+ if (err) -+ goto err_out_input_filter; - - spin_unlock(&adapter->nfc_lock); - return 0; - -+err_out_input_filter: -+ igb_erase_filter(adapter, input); - err_out_w_lock: - spin_unlock(&adapter->nfc_lock); - err_out: -diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c -index e23b95edb05ef..81897f7a90a91 100644 ---- a/drivers/net/ethernet/intel/igc/igc_ethtool.c -+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c -@@ -1817,7 +1817,7 @@ igc_ethtool_set_link_ksettings(struct net_device *netdev, - struct igc_adapter *adapter = netdev_priv(netdev); - struct net_device *dev = adapter->netdev; - struct igc_hw *hw = &adapter->hw; -- u32 advertising; -+ u16 advertised = 0; - - /* When adapter in resetting mode, autoneg/speed/duplex - * cannot be changed -@@ -1842,18 +1842,33 @@ igc_ethtool_set_link_ksettings(struct net_device *netdev, - while (test_and_set_bit(__IGC_RESETTING, &adapter->state)) - usleep_range(1000, 2000); - -- ethtool_convert_link_mode_to_legacy_u32(&advertising, -- cmd->link_modes.advertising); -- /* Converting to legacy u32 drops ETHTOOL_LINK_MODE_2500baseT_Full_BIT. -- * We have to check this and convert it to ADVERTISE_2500_FULL -- * (aka ETHTOOL_LINK_MODE_2500baseX_Full_BIT) explicitly. -- */ -- if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 2500baseT_Full)) -- advertising |= ADVERTISE_2500_FULL; -+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising, -+ 2500baseT_Full)) -+ advertised |= ADVERTISE_2500_FULL; -+ -+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising, -+ 1000baseT_Full)) -+ advertised |= ADVERTISE_1000_FULL; -+ -+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising, -+ 100baseT_Full)) -+ advertised |= ADVERTISE_100_FULL; -+ -+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising, -+ 100baseT_Half)) -+ advertised |= ADVERTISE_100_HALF; -+ -+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising, -+ 10baseT_Full)) -+ advertised |= ADVERTISE_10_FULL; -+ -+ if (ethtool_link_ksettings_test_link_mode(cmd, advertising, -+ 10baseT_Half)) -+ advertised |= ADVERTISE_10_HALF; - - if (cmd->base.autoneg == AUTONEG_ENABLE) { - hw->mac.autoneg = 1; -- hw->phy.autoneg_advertised = advertising; -+ hw->phy.autoneg_advertised = advertised; - if (adapter->fc_autoneg) - hw->fc.requested_mode = igc_fc_default; - } else { -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index a9a0dca0c0305..80b6079b8a8e3 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -4343,7 +4343,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, - unsigned int entry = dirty_tx % NUM_TX_DESC; - u32 status; - -- status = le32_to_cpu(tp->TxDescArray[entry].opts1); -+ status = le32_to_cpu(READ_ONCE(tp->TxDescArray[entry].opts1)); - if (status & DescOwn) - break; - -@@ -4380,7 +4380,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, - * If skb is NULL then we come here again once a tx irq is - * triggered after the last fragment is marked transmitted. - */ -- if (tp->cur_tx != dirty_tx && skb) -+ if (READ_ONCE(tp->cur_tx) != dirty_tx && skb) - rtl8169_doorbell(tp); - } - } -@@ -4413,7 +4413,7 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, int budget - dma_addr_t addr; - u32 status; - -- status = le32_to_cpu(desc->opts1); -+ status = le32_to_cpu(READ_ONCE(desc->opts1)); - if (status & DescOwn) - break; - -diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c -index dc14a66583ff3..44488c153ea25 100644 ---- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c -+++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c -@@ -1217,7 +1217,7 @@ static int gelic_wl_set_encodeext(struct net_device *netdev, - key_index = wl->current_key; - - if (!enc->length && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) { -- /* reques to change default key index */ -+ /* request to change default key index */ - pr_debug("%s: request to change default key to %d\n", - __func__, key_index); - wl->current_key = key_index; -diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c -index acb20ad4e37eb..477b4d4f860bd 100644 ---- a/drivers/net/gtp.c -+++ b/drivers/net/gtp.c -@@ -871,8 +871,9 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev, - - skb_dst_update_pmtu_no_confirm(skb, mtu); - -- if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) && -- mtu < ntohs(iph->tot_len)) { -+ if (iph->frag_off & htons(IP_DF) && -+ ((!skb_is_gso(skb) && skb->len > mtu) || -+ (skb_is_gso(skb) && !skb_gso_validate_network_len(skb, mtu)))) { - netdev_dbg(dev, "packet too big, fragmentation needed\n"); - icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(mtu)); -diff --git a/drivers/net/ieee802154/adf7242.c b/drivers/net/ieee802154/adf7242.c -index 5cf218c674a5a..32d92bdabd234 100644 ---- a/drivers/net/ieee802154/adf7242.c -+++ b/drivers/net/ieee802154/adf7242.c -@@ -1162,9 +1162,10 @@ static int adf7242_stats_show(struct seq_file *file, void *offset) - - static void adf7242_debugfs_init(struct adf7242_local *lp) - { -- char debugfs_dir_name[DNAME_INLINE_LEN + 1] = "adf7242-"; -+ char debugfs_dir_name[DNAME_INLINE_LEN + 1]; - -- strncat(debugfs_dir_name, dev_name(&lp->spi->dev), DNAME_INLINE_LEN); -+ snprintf(debugfs_dir_name, sizeof(debugfs_dir_name), -+ "adf7242-%s", dev_name(&lp->spi->dev)); - - lp->debugfs_root = debugfs_create_dir(debugfs_dir_name, NULL); - -diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c -index fc1458f96e170..c34974f7dfd26 100644 ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -1211,7 +1211,7 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) - - ret = usb_control_msg(tp->udev, tp->pipe_ctrl_in, - RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -- value, index, tmp, size, 500); -+ value, index, tmp, size, USB_CTRL_GET_TIMEOUT); - if (ret < 0) - memset(data, 0xff, size); - else -@@ -1234,7 +1234,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) - - ret = usb_control_msg(tp->udev, tp->pipe_ctrl_out, - RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, -- value, index, tmp, size, 500); -+ value, index, tmp, size, USB_CTRL_SET_TIMEOUT); - - kfree(tmp); - -@@ -9549,7 +9549,8 @@ u8 rtl8152_get_version(struct usb_interface *intf) - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -- PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); -+ PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), -+ USB_CTRL_GET_TIMEOUT); - if (ret > 0) - ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; - -@@ -9825,6 +9826,10 @@ static int rtl8152_probe(struct usb_interface *intf, - - out1: - tasklet_kill(&tp->tx_tl); -+ cancel_delayed_work_sync(&tp->hw_phy_work); -+ if (tp->rtl_ops.unload) -+ tp->rtl_ops.unload(tp); -+ rtl8152_release_firmware(tp); - usb_set_intfdata(intf, NULL); - out: - free_netdev(netdev); -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 17da42fe605c3..a530f20ee2575 100644 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -95,7 +95,9 @@ static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index, - ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN - | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, &buf, 4); -- if (ret < 0) { -+ if (ret < 4) { -+ ret = ret < 0 ? ret : -ENODATA; -+ - if (ret != -ENODEV) - netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", - index, ret); -diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c -index 14284e866f26e..9590a864efd56 100644 ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -506,7 +506,7 @@ static const struct ocotp_params imx6sl_params = { - }; - - static const struct ocotp_params imx6sll_params = { -- .nregs = 128, -+ .nregs = 80, - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -@@ -520,14 +520,14 @@ static const struct ocotp_params imx6sx_params = { - }; - - static const struct ocotp_params imx6ul_params = { -- .nregs = 128, -+ .nregs = 144, - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, - }; - - static const struct ocotp_params imx6ull_params = { -- .nregs = 64, -+ .nregs = 80, - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c -index a55998ae29fa4..bfcc5c45b8fa5 100644 ---- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c -+++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c -@@ -24,7 +24,8 @@ struct lpi_pinctrl { - char __iomem *tlmm_base; - char __iomem *slew_base; - struct clk_bulk_data clks[MAX_LPI_NUM_CLKS]; -- struct mutex slew_access_lock; -+ /* Protects from concurrent register updates */ -+ struct mutex lock; - const struct lpi_pinctrl_variant_data *data; - }; - -@@ -94,9 +95,11 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function, - if (WARN_ON(i == g->nfuncs)) - return -EINVAL; - -+ mutex_lock(&pctrl->lock); - val = lpi_gpio_read(pctrl, pin, LPI_GPIO_CFG_REG); - u32p_replace_bits(&val, i, LPI_GPIO_FUNCTION_MASK); - lpi_gpio_write(pctrl, pin, LPI_GPIO_CFG_REG, val); -+ mutex_unlock(&pctrl->lock); - - return 0; - } -@@ -202,14 +205,14 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group, - if (slew_offset == LPI_NO_SLEW) - break; - -- mutex_lock(&pctrl->slew_access_lock); -+ mutex_lock(&pctrl->lock); - - sval = ioread32(pctrl->slew_base + LPI_SLEW_RATE_CTL_REG); - sval &= ~(LPI_SLEW_RATE_MASK << slew_offset); - sval |= arg << slew_offset; - iowrite32(sval, pctrl->slew_base + LPI_SLEW_RATE_CTL_REG); - -- mutex_unlock(&pctrl->slew_access_lock); -+ mutex_unlock(&pctrl->lock); - break; - default: - return -EINVAL; -@@ -225,6 +228,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group, - lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG, val); - } - -+ mutex_lock(&pctrl->lock); - val = lpi_gpio_read(pctrl, group, LPI_GPIO_CFG_REG); - - u32p_replace_bits(&val, pullup, LPI_GPIO_PULL_MASK); -@@ -233,6 +237,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group, - u32p_replace_bits(&val, output_enabled, LPI_GPIO_OE_MASK); - - lpi_gpio_write(pctrl, group, LPI_GPIO_CFG_REG, val); -+ mutex_unlock(&pctrl->lock); - - return 0; - } -@@ -432,7 +437,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev) - pctrl->chip.of_gpio_n_cells = 2; - pctrl->chip.can_sleep = false; - -- mutex_init(&pctrl->slew_access_lock); -+ mutex_init(&pctrl->lock); - - pctrl->ctrl = devm_pinctrl_register(dev, &pctrl->desc, pctrl); - if (IS_ERR(pctrl->ctrl)) { -@@ -454,7 +459,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev) - return 0; - - err_pinctrl: -- mutex_destroy(&pctrl->slew_access_lock); -+ mutex_destroy(&pctrl->lock); - clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks); - - return ret; -@@ -466,7 +471,7 @@ int lpi_pinctrl_remove(struct platform_device *pdev) - struct lpi_pinctrl *pctrl = platform_get_drvdata(pdev); - int i; - -- mutex_destroy(&pctrl->slew_access_lock); -+ mutex_destroy(&pctrl->lock); - clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks); - - for (i = 0; i < pctrl->data->npins; i++) -diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c -index e7ece2738de94..3bb60687f2e42 100644 ---- a/drivers/platform/x86/thinkpad_acpi.c -+++ b/drivers/platform/x86/thinkpad_acpi.c -@@ -4513,6 +4513,79 @@ static const struct dmi_system_id fwbug_list[] __initconst = { - DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), - } - }, -+ /* https://bugzilla.kernel.org/show_bug.cgi?id=218024 */ -+ { -+ .ident = "V14 G4 AMN", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82YT"), -+ } -+ }, -+ { -+ .ident = "V14 G4 AMN", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "83GE"), -+ } -+ }, -+ { -+ .ident = "V15 G4 AMN", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82YU"), -+ } -+ }, -+ { -+ .ident = "V15 G4 AMN", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "83CQ"), -+ } -+ }, -+ { -+ .ident = "IdeaPad 1 14AMN7", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82VF"), -+ } -+ }, -+ { -+ .ident = "IdeaPad 1 15AMN7", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82VG"), -+ } -+ }, -+ { -+ .ident = "IdeaPad 1 15AMN7", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82X5"), -+ } -+ }, -+ { -+ .ident = "IdeaPad Slim 3 14AMN8", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82XN"), -+ } -+ }, -+ { -+ .ident = "IdeaPad Slim 3 15AMN8", -+ .driver_data = &quirk_s2idle_bug, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "82XQ"), -+ } -+ }, - {} - }; - -diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index 30184f7b762c1..deed8c909a786 100644 ---- a/drivers/scsi/sd.c -+++ b/drivers/scsi/sd.c -@@ -221,7 +221,8 @@ manage_start_stop_show(struct device *dev, - - return sysfs_emit(buf, "%u\n", - sdp->manage_system_start_stop && -- sdp->manage_runtime_start_stop); -+ sdp->manage_runtime_start_stop && -+ sdp->manage_shutdown); - } - static DEVICE_ATTR_RO(manage_start_stop); - -@@ -287,6 +288,35 @@ manage_runtime_start_stop_store(struct device *dev, - } - static DEVICE_ATTR_RW(manage_runtime_start_stop); - -+static ssize_t manage_shutdown_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct scsi_disk *sdkp = to_scsi_disk(dev); -+ struct scsi_device *sdp = sdkp->device; -+ -+ return sysfs_emit(buf, "%u\n", sdp->manage_shutdown); -+} -+ -+static ssize_t manage_shutdown_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct scsi_disk *sdkp = to_scsi_disk(dev); -+ struct scsi_device *sdp = sdkp->device; -+ bool v; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ if (kstrtobool(buf, &v)) -+ return -EINVAL; -+ -+ sdp->manage_shutdown = v; -+ -+ return count; -+} -+static DEVICE_ATTR_RW(manage_shutdown); -+ - static ssize_t - allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) - { -@@ -619,6 +649,7 @@ static struct attribute *sd_disk_attrs[] = { - &dev_attr_manage_start_stop.attr, - &dev_attr_manage_system_start_stop.attr, - &dev_attr_manage_runtime_start_stop.attr, -+ &dev_attr_manage_shutdown.attr, - &dev_attr_protection_type.attr, - &dev_attr_protection_mode.attr, - &dev_attr_app_tag_own.attr, -@@ -3700,8 +3731,10 @@ static void sd_shutdown(struct device *dev) - sd_sync_cache(sdkp, NULL); - } - -- if (system_state != SYSTEM_RESTART && -- sdkp->device->manage_system_start_stop) { -+ if ((system_state != SYSTEM_RESTART && -+ sdkp->device->manage_system_start_stop) || -+ (system_state == SYSTEM_POWER_OFF && -+ sdkp->device->manage_shutdown)) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - sd_start_stop_device(sdkp, 0); - } -diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c -index 1a059b028c501..2eea080298812 100644 ---- a/drivers/vhost/vhost.c -+++ b/drivers/vhost/vhost.c -@@ -1176,9 +1176,7 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev, - goto done; - } - -- if ((msg.type == VHOST_IOTLB_UPDATE || -- msg.type == VHOST_IOTLB_INVALIDATE) && -- msg.size == 0) { -+ if (msg.type == VHOST_IOTLB_UPDATE && msg.size == 0) { - ret = -EINVAL; - goto done; - } -diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c -index 3f78a3a1eb753..aa90bd0199d7e 100644 ---- a/drivers/virtio/virtio_balloon.c -+++ b/drivers/virtio/virtio_balloon.c -@@ -395,7 +395,11 @@ static inline s64 towards_target(struct virtio_balloon *vb) - virtio_cread_le(vb->vdev, struct virtio_balloon_config, num_pages, - &num_pages); - -- target = num_pages; -+ /* -+ * Aligned up to guest page size to avoid inflating and deflating -+ * balloon endlessly. -+ */ -+ target = ALIGN(num_pages, VIRTIO_BALLOON_PAGES_PER_PAGE); - return target - vb->num_pages; - } - -diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c -index dec3cba884586..de1a081089417 100644 ---- a/drivers/virtio/virtio_mmio.c -+++ b/drivers/virtio/virtio_mmio.c -@@ -614,14 +614,17 @@ static int virtio_mmio_probe(struct platform_device *pdev) - spin_lock_init(&vm_dev->lock); - - vm_dev->base = devm_platform_ioremap_resource(pdev, 0); -- if (IS_ERR(vm_dev->base)) -- return PTR_ERR(vm_dev->base); -+ if (IS_ERR(vm_dev->base)) { -+ rc = PTR_ERR(vm_dev->base); -+ goto free_vm_dev; -+ } - - /* Check magic value */ - magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); - if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) { - dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); -- return -ENODEV; -+ rc = -ENODEV; -+ goto free_vm_dev; - } - - /* Check device version */ -@@ -629,7 +632,8 @@ static int virtio_mmio_probe(struct platform_device *pdev) - if (vm_dev->version < 1 || vm_dev->version > 2) { - dev_err(&pdev->dev, "Version %ld not supported!\n", - vm_dev->version); -- return -ENXIO; -+ rc = -ENXIO; -+ goto free_vm_dev; - } - - vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); -@@ -638,7 +642,8 @@ static int virtio_mmio_probe(struct platform_device *pdev) - * virtio-mmio device with an ID 0 is a (dummy) placeholder - * with no function. End probing now with no error reported. - */ -- return -ENODEV; -+ rc = -ENODEV; -+ goto free_vm_dev; - } - vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); - -@@ -668,6 +673,10 @@ static int virtio_mmio_probe(struct platform_device *pdev) - put_device(&vm_dev->vdev.dev); - - return rc; -+ -+free_vm_dev: -+ kfree(vm_dev); -+ return rc; - } - - static int virtio_mmio_remove(struct platform_device *pdev) -diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c -index 869cb46bef960..ccdd41935ed71 100644 ---- a/drivers/virtio/virtio_pci_modern_dev.c -+++ b/drivers/virtio/virtio_pci_modern_dev.c -@@ -282,7 +282,7 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev) - err = -EINVAL; - mdev->common = vp_modern_map_capability(mdev, common, - sizeof(struct virtio_pci_common_cfg), 4, -- 0, sizeof(struct virtio_pci_common_cfg), -+ 0, sizeof(struct virtio_pci_modern_common_cfg), - NULL, NULL); - if (!mdev->common) - goto err_map_common; -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 3c8300e08f412..6ea6b7105fe35 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -4022,8 +4022,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, - struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); - struct ext4_super_block *es = sbi->s_es; - int bsbits, max; -- ext4_lblk_t end; -- loff_t size, start_off; -+ loff_t size, start_off, end; - loff_t orig_size __maybe_unused; - ext4_lblk_t start; - struct ext4_inode_info *ei = EXT4_I(ac->ac_inode); -@@ -4052,7 +4051,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, - - /* first, let's learn actual file size - * given current request is allocated */ -- size = ac->ac_o_ex.fe_logical + EXT4_C2B(sbi, ac->ac_o_ex.fe_len); -+ size = extent_logical_end(sbi, &ac->ac_o_ex); - size = size << bsbits; - if (size < i_size_read(ac->ac_inode)) - size = i_size_read(ac->ac_inode); -@@ -4131,7 +4130,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, - /* check we don't cross already preallocated blocks */ - rcu_read_lock(); - list_for_each_entry_rcu(pa, &ei->i_prealloc_list, pa_inode_list) { -- ext4_lblk_t pa_end; -+ loff_t pa_end; - - if (pa->pa_deleted) - continue; -@@ -4141,8 +4140,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, - continue; - } - -- pa_end = pa->pa_lstart + EXT4_C2B(EXT4_SB(ac->ac_sb), -- pa->pa_len); -+ pa_end = pa_logical_end(EXT4_SB(ac->ac_sb), pa); - - /* PA must not overlap original request */ - BUG_ON(!(ac->ac_o_ex.fe_logical >= pa_end || -@@ -4171,12 +4169,11 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, - /* XXX: extra loop to check we really don't overlap preallocations */ - rcu_read_lock(); - list_for_each_entry_rcu(pa, &ei->i_prealloc_list, pa_inode_list) { -- ext4_lblk_t pa_end; -+ loff_t pa_end; - - spin_lock(&pa->pa_lock); - if (pa->pa_deleted == 0) { -- pa_end = pa->pa_lstart + EXT4_C2B(EXT4_SB(ac->ac_sb), -- pa->pa_len); -+ pa_end = pa_logical_end(EXT4_SB(ac->ac_sb), pa); - BUG_ON(!(start >= pa_end || end <= pa->pa_lstart)); - } - spin_unlock(&pa->pa_lock); -@@ -4407,8 +4404,7 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac) - /* all fields in this condition don't change, - * so we can skip locking for them */ - if (ac->ac_o_ex.fe_logical < pa->pa_lstart || -- ac->ac_o_ex.fe_logical >= (pa->pa_lstart + -- EXT4_C2B(sbi, pa->pa_len))) -+ ac->ac_o_ex.fe_logical >= pa_logical_end(sbi, pa)) - continue; - - /* non-extent files can't have physical blocks past 2^32 */ -@@ -4653,8 +4649,11 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) - pa = ac->ac_pa; - - if (ac->ac_b_ex.fe_len < ac->ac_g_ex.fe_len) { -- int new_bex_start; -- int new_bex_end; -+ struct ext4_free_extent ex = { -+ .fe_logical = ac->ac_g_ex.fe_logical, -+ .fe_len = ac->ac_g_ex.fe_len, -+ }; -+ loff_t orig_goal_end = extent_logical_end(sbi, &ex); - - /* we can't allocate as much as normalizer wants. - * so, found space must get proper lstart -@@ -4673,29 +4672,23 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) - * still cover original start - * 3. Else, keep the best ex at start of original request. - */ -- new_bex_end = ac->ac_g_ex.fe_logical + -- EXT4_C2B(sbi, ac->ac_g_ex.fe_len); -- new_bex_start = new_bex_end - EXT4_C2B(sbi, ac->ac_b_ex.fe_len); -- if (ac->ac_o_ex.fe_logical >= new_bex_start) -- goto adjust_bex; -+ ex.fe_len = ac->ac_b_ex.fe_len; - -- new_bex_start = ac->ac_g_ex.fe_logical; -- new_bex_end = -- new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len); -- if (ac->ac_o_ex.fe_logical < new_bex_end) -+ ex.fe_logical = orig_goal_end - EXT4_C2B(sbi, ex.fe_len); -+ if (ac->ac_o_ex.fe_logical >= ex.fe_logical) - goto adjust_bex; - -- new_bex_start = ac->ac_o_ex.fe_logical; -- new_bex_end = -- new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len); -+ ex.fe_logical = ac->ac_g_ex.fe_logical; -+ if (ac->ac_o_ex.fe_logical < extent_logical_end(sbi, &ex)) -+ goto adjust_bex; - -+ ex.fe_logical = ac->ac_o_ex.fe_logical; - adjust_bex: -- ac->ac_b_ex.fe_logical = new_bex_start; -+ ac->ac_b_ex.fe_logical = ex.fe_logical; - - BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical); - BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len); -- BUG_ON(new_bex_end > (ac->ac_g_ex.fe_logical + -- EXT4_C2B(sbi, ac->ac_g_ex.fe_len))); -+ BUG_ON(extent_logical_end(sbi, &ex) > orig_goal_end); - } - - /* preallocation can change ac_b_ex, thus we store actually -@@ -5229,7 +5222,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) - - group_pa_eligible = sbi->s_mb_group_prealloc > 0; - inode_pa_eligible = true; -- size = ac->ac_o_ex.fe_logical + EXT4_C2B(sbi, ac->ac_o_ex.fe_len); -+ size = extent_logical_end(sbi, &ac->ac_o_ex); - isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1) - >> bsbits; - -diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h -index dcda2a943cee0..00b3898df4a76 100644 ---- a/fs/ext4/mballoc.h -+++ b/fs/ext4/mballoc.h -@@ -218,6 +218,20 @@ static inline ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, - (fex->fe_start << EXT4_SB(sb)->s_cluster_bits); - } - -+static inline loff_t extent_logical_end(struct ext4_sb_info *sbi, -+ struct ext4_free_extent *fex) -+{ -+ /* Use loff_t to avoid end exceeding ext4_lblk_t max. */ -+ return (loff_t)fex->fe_logical + EXT4_C2B(sbi, fex->fe_len); -+} -+ -+static inline loff_t pa_logical_end(struct ext4_sb_info *sbi, -+ struct ext4_prealloc_space *pa) -+{ -+ /* Use loff_t to avoid end exceeding ext4_lblk_t max. */ -+ return (loff_t)pa->pa_lstart + EXT4_C2B(sbi, pa->pa_len); -+} -+ - typedef int (*ext4_mballoc_query_range_fn)( - struct super_block *sb, - ext4_group_t agno, -diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c -index 4c11046800ab4..eccc6ce55a63a 100644 ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1659,6 +1659,12 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, - if (!flen || isdotent(fname, flen) || !tlen || isdotent(tname, tlen)) - goto out; - -+ err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; -+ if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) -+ goto out; -+ if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry) -+ goto out; -+ - retry: - host_err = fh_want_write(ffhp); - if (host_err) { -@@ -1690,12 +1696,6 @@ retry: - if (ndentry == trap) - goto out_dput_new; - -- host_err = -EXDEV; -- if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) -- goto out_dput_new; -- if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry) -- goto out_dput_new; -- - if ((ndentry->d_sb->s_export_op->flags & EXPORT_OP_CLOSE_BEFORE_UNLINK) && - nfsd_has_cached_files(ndentry)) { - close_cached = true; -diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h -index 58b53d08f2c8e..e46f6b49eb389 100644 ---- a/include/linux/hugetlb.h -+++ b/include/linux/hugetlb.h -@@ -70,6 +70,7 @@ struct resv_map { - long adds_in_progress; - struct list_head region_cache; - long region_cache_count; -+ struct rw_semaphore rw_sema; - #ifdef CONFIG_CGROUP_HUGETLB - /* - * On private mappings, the counter to uncharge reservations is stored -@@ -879,6 +880,11 @@ static inline bool hugepage_migration_supported(struct hstate *h) - return arch_hugetlb_migration_supported(h); - } - -+static inline bool __vma_private_lock(struct vm_area_struct *vma) -+{ -+ return (!(vma->vm_flags & VM_MAYSHARE)) && vma->vm_private_data; -+} -+ - /* - * Movability check is different as compared to migration check. - * It determines whether or not a huge page should be placed on -diff --git a/include/linux/kasan.h b/include/linux/kasan.h -index d811b3d7d2a15..6e6f0238d63cc 100644 ---- a/include/linux/kasan.h -+++ b/include/linux/kasan.h -@@ -471,10 +471,10 @@ static inline void kasan_free_module_shadow(const struct vm_struct *vm) {} - - #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ - --#ifdef CONFIG_KASAN_INLINE -+#ifdef CONFIG_KASAN - void kasan_non_canonical_hook(unsigned long addr); --#else /* CONFIG_KASAN_INLINE */ -+#else /* CONFIG_KASAN */ - static inline void kasan_non_canonical_hook(unsigned long addr) { } --#endif /* CONFIG_KASAN_INLINE */ -+#endif /* CONFIG_KASAN */ - - #endif /* LINUX_KASAN_H */ -diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h -index dc2cff18b68bd..5aabc36fb249b 100644 ---- a/include/scsi/scsi_device.h -+++ b/include/scsi/scsi_device.h -@@ -162,8 +162,24 @@ struct scsi_device { - * core. */ - unsigned int eh_timeout; /* Error handling timeout */ - -- bool manage_system_start_stop; /* Let HLD (sd) manage system start/stop */ -- bool manage_runtime_start_stop; /* Let HLD (sd) manage runtime start/stop */ -+ /* -+ * If true, let the high-level device driver (sd) manage the device -+ * power state for system suspend/resume (suspend to RAM and -+ * hibernation) operations. -+ */ -+ bool manage_system_start_stop; -+ -+ /* -+ * If true, let the high-level device driver (sd) manage the device -+ * power state for runtime device suspand and resume operations. -+ */ -+ bool manage_runtime_start_stop; -+ -+ /* -+ * If true, let the high-level device driver (sd) manage the device -+ * power state for system shutdown (power off) operations. -+ */ -+ bool manage_shutdown; - - unsigned removable:1; - unsigned changed:1; /* Data invalid due to media change */ -diff --git a/include/uapi/linux/gtp.h b/include/uapi/linux/gtp.h -index 2f61298a7b779..3dcdb9e33cba2 100644 ---- a/include/uapi/linux/gtp.h -+++ b/include/uapi/linux/gtp.h -@@ -33,6 +33,6 @@ enum gtp_attrs { - GTPA_PAD, - __GTPA_MAX, - }; --#define GTPA_MAX (__GTPA_MAX + 1) -+#define GTPA_MAX (__GTPA_MAX - 1) - - #endif /* _UAPI_LINUX_GTP_H_ */ -diff --git a/io_uring/fdinfo.c b/io_uring/fdinfo.c -index 882bd56b01ed0..ea2c2ded4e412 100644 ---- a/io_uring/fdinfo.c -+++ b/io_uring/fdinfo.c -@@ -51,7 +51,6 @@ static __cold int io_uring_show_cred(struct seq_file *m, unsigned int id, - static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, - struct seq_file *m) - { -- struct io_sq_data *sq = NULL; - struct io_overflow_cqe *ocqe; - struct io_rings *r = ctx->rings; - unsigned int sq_mask = ctx->sq_entries - 1, cq_mask = ctx->cq_entries - 1; -@@ -62,6 +61,7 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, - unsigned int cq_shift = 0; - unsigned int sq_shift = 0; - unsigned int sq_entries, cq_entries; -+ int sq_pid = -1, sq_cpu = -1; - bool has_lock; - unsigned int i; - -@@ -139,13 +139,19 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, - has_lock = mutex_trylock(&ctx->uring_lock); - - if (has_lock && (ctx->flags & IORING_SETUP_SQPOLL)) { -- sq = ctx->sq_data; -- if (!sq->thread) -- sq = NULL; -+ struct io_sq_data *sq = ctx->sq_data; -+ -+ if (mutex_trylock(&sq->lock)) { -+ if (sq->thread) { -+ sq_pid = task_pid_nr(sq->thread); -+ sq_cpu = task_cpu(sq->thread); -+ } -+ mutex_unlock(&sq->lock); -+ } - } - -- seq_printf(m, "SqThread:\t%d\n", sq ? task_pid_nr(sq->thread) : -1); -- seq_printf(m, "SqThreadCpu:\t%d\n", sq ? task_cpu(sq->thread) : -1); -+ seq_printf(m, "SqThread:\t%d\n", sq_pid); -+ seq_printf(m, "SqThreadCpu:\t%d\n", sq_cpu); - seq_printf(m, "UserFiles:\t%u\n", ctx->nr_user_files); - for (i = 0; has_lock && i < ctx->nr_user_files; i++) { - struct file *f = io_file_from_index(&ctx->file_table, i); -diff --git a/kernel/events/core.c b/kernel/events/core.c -index 2b8315a948a2c..8f2b9d8b9150e 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -13293,7 +13293,8 @@ static int inherit_group(struct perf_event *parent_event, - !perf_get_aux_event(child_ctr, leader)) - return -EINVAL; - } -- leader->group_generation = parent_event->group_generation; -+ if (leader) -+ leader->group_generation = parent_event->group_generation; - return 0; - } - -diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c -index 22852029c6924..56675294d7a3b 100644 ---- a/kernel/trace/trace_kprobe.c -+++ b/kernel/trace/trace_kprobe.c -@@ -989,7 +989,7 @@ EXPORT_SYMBOL_GPL(kprobe_event_cmd_init); - * @name: The name of the kprobe event - * @loc: The location of the kprobe event - * @kretprobe: Is this a return probe? -- * @args: Variable number of arg (pairs), one pair for each field -+ * @...: Variable number of arg (pairs), one pair for each field - * - * NOTE: Users normally won't want to call this function directly, but - * rather use the kprobe_event_gen_cmd_start() wrapper, which automatically -@@ -1062,7 +1062,7 @@ EXPORT_SYMBOL_GPL(__kprobe_event_gen_cmd_start); - /** - * __kprobe_event_add_fields - Add probe fields to a kprobe command from arg list - * @cmd: A pointer to the dynevent_cmd struct representing the new event -- * @args: Variable number of arg (pairs), one pair for each field -+ * @...: Variable number of arg (pairs), one pair for each field - * - * NOTE: Users normally won't want to call this function directly, but - * rather use the kprobe_event_add_fields() wrapper, which -diff --git a/lib/maple_tree.c b/lib/maple_tree.c -index 250b4c67fac8f..4976522e3e481 100644 ---- a/lib/maple_tree.c -+++ b/lib/maple_tree.c -@@ -5913,7 +5913,7 @@ int mas_expected_entries(struct ma_state *mas, unsigned long nr_entries) - /* Internal nodes */ - nr_nodes += DIV_ROUND_UP(nr_nodes, nonleaf_cap); - /* Add working room for split (2 nodes) + new parents */ -- mas_node_count(mas, nr_nodes + 3); -+ mas_node_count_gfp(mas, nr_nodes + 3, GFP_KERNEL); - - /* Detect if allocations run out */ - mas->mas_flags |= MA_STATE_PREALLOC; -diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c -index fad668042f3e7..ab9d4461abc9d 100644 ---- a/lib/test_maple_tree.c -+++ b/lib/test_maple_tree.c -@@ -9,6 +9,7 @@ - - #include - #include -+#include - - #define MTREE_ALLOC_MAX 0x2000000000000Ul - #ifndef CONFIG_DEBUG_MAPLE_TREE -@@ -1678,17 +1679,21 @@ static noinline void __init check_forking(struct maple_tree *mt) - void *val; - MA_STATE(mas, mt, 0, 0); - MA_STATE(newmas, mt, 0, 0); -+ struct rw_semaphore newmt_lock; -+ -+ init_rwsem(&newmt_lock); - - for (i = 0; i <= nr_entries; i++) - mtree_store_range(mt, i*10, i*10 + 5, - xa_mk_value(i), GFP_KERNEL); - - mt_set_non_kernel(99999); -- mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE); -+ mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN); -+ mt_set_external_lock(&newmt, &newmt_lock); - newmas.tree = &newmt; - mas_reset(&newmas); - mas_reset(&mas); -- mas_lock(&newmas); -+ down_write(&newmt_lock); - mas.index = 0; - mas.last = 0; - if (mas_expected_entries(&newmas, nr_entries)) { -@@ -1703,10 +1708,10 @@ static noinline void __init check_forking(struct maple_tree *mt) - } - rcu_read_unlock(); - mas_destroy(&newmas); -- mas_unlock(&newmas); - mt_validate(&newmt); - mt_set_non_kernel(0); -- mtree_destroy(&newmt); -+ __mt_destroy(&newmt); -+ up_write(&newmt_lock); - } - - static noinline void __init check_iteration(struct maple_tree *mt) -@@ -1818,6 +1823,10 @@ static noinline void __init bench_forking(struct maple_tree *mt) - void *val; - MA_STATE(mas, mt, 0, 0); - MA_STATE(newmas, mt, 0, 0); -+ struct rw_semaphore newmt_lock; -+ -+ init_rwsem(&newmt_lock); -+ mt_set_external_lock(&newmt, &newmt_lock); - - for (i = 0; i <= nr_entries; i++) - mtree_store_range(mt, i*10, i*10 + 5, -@@ -1832,7 +1841,7 @@ static noinline void __init bench_forking(struct maple_tree *mt) - mas.index = 0; - mas.last = 0; - rcu_read_lock(); -- mas_lock(&newmas); -+ down_write(&newmt_lock); - if (mas_expected_entries(&newmas, nr_entries)) { - printk("OOM!"); - BUG_ON(1); -@@ -1843,11 +1852,11 @@ static noinline void __init bench_forking(struct maple_tree *mt) - mas_store(&newmas, val); - } - mas_destroy(&newmas); -- mas_unlock(&newmas); - rcu_read_unlock(); - mt_validate(&newmt); - mt_set_non_kernel(0); -- mtree_destroy(&newmt); -+ __mt_destroy(&newmt); -+ up_write(&newmt_lock); - } - } - #endif -@@ -2453,6 +2462,10 @@ static noinline void __init check_dup_gaps(struct maple_tree *mt, - void *tmp; - MA_STATE(mas, mt, 0, 0); - MA_STATE(newmas, &newmt, 0, 0); -+ struct rw_semaphore newmt_lock; -+ -+ init_rwsem(&newmt_lock); -+ mt_set_external_lock(&newmt, &newmt_lock); - - if (!zero_start) - i = 1; -@@ -2462,9 +2475,9 @@ static noinline void __init check_dup_gaps(struct maple_tree *mt, - mtree_store_range(mt, i*10, (i+1)*10 - gap, - xa_mk_value(i), GFP_KERNEL); - -- mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE); -+ mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN); - mt_set_non_kernel(99999); -- mas_lock(&newmas); -+ down_write(&newmt_lock); - ret = mas_expected_entries(&newmas, nr_entries); - mt_set_non_kernel(0); - MT_BUG_ON(mt, ret != 0); -@@ -2477,9 +2490,9 @@ static noinline void __init check_dup_gaps(struct maple_tree *mt, - } - rcu_read_unlock(); - mas_destroy(&newmas); -- mas_unlock(&newmas); - -- mtree_destroy(&newmt); -+ __mt_destroy(&newmt); -+ up_write(&newmt_lock); - } - - /* Duplicate many sizes of trees. Mainly to test expected entry values */ -diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index c38ec6efec0f7..aa4a68dfb3b92 100644 ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -96,6 +96,7 @@ static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma); - static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma); - static void hugetlb_unshare_pmds(struct vm_area_struct *vma, - unsigned long start, unsigned long end); -+static struct resv_map *vma_resv_map(struct vm_area_struct *vma); - - static inline bool subpool_is_free(struct hugepage_subpool *spool) - { -@@ -272,6 +273,10 @@ void hugetlb_vma_lock_read(struct vm_area_struct *vma) - struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; - - down_read(&vma_lock->rw_sema); -+ } else if (__vma_private_lock(vma)) { -+ struct resv_map *resv_map = vma_resv_map(vma); -+ -+ down_read(&resv_map->rw_sema); - } - } - -@@ -281,6 +286,10 @@ void hugetlb_vma_unlock_read(struct vm_area_struct *vma) - struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; - - up_read(&vma_lock->rw_sema); -+ } else if (__vma_private_lock(vma)) { -+ struct resv_map *resv_map = vma_resv_map(vma); -+ -+ up_read(&resv_map->rw_sema); - } - } - -@@ -290,6 +299,10 @@ void hugetlb_vma_lock_write(struct vm_area_struct *vma) - struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; - - down_write(&vma_lock->rw_sema); -+ } else if (__vma_private_lock(vma)) { -+ struct resv_map *resv_map = vma_resv_map(vma); -+ -+ down_write(&resv_map->rw_sema); - } - } - -@@ -299,17 +312,27 @@ void hugetlb_vma_unlock_write(struct vm_area_struct *vma) - struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; - - up_write(&vma_lock->rw_sema); -+ } else if (__vma_private_lock(vma)) { -+ struct resv_map *resv_map = vma_resv_map(vma); -+ -+ up_write(&resv_map->rw_sema); - } - } - - int hugetlb_vma_trylock_write(struct vm_area_struct *vma) - { -- struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; - -- if (!__vma_shareable_lock(vma)) -- return 1; -+ if (__vma_shareable_lock(vma)) { -+ struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; - -- return down_write_trylock(&vma_lock->rw_sema); -+ return down_write_trylock(&vma_lock->rw_sema); -+ } else if (__vma_private_lock(vma)) { -+ struct resv_map *resv_map = vma_resv_map(vma); -+ -+ return down_write_trylock(&resv_map->rw_sema); -+ } -+ -+ return 1; - } - - void hugetlb_vma_assert_locked(struct vm_area_struct *vma) -@@ -318,6 +341,10 @@ void hugetlb_vma_assert_locked(struct vm_area_struct *vma) - struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; - - lockdep_assert_held(&vma_lock->rw_sema); -+ } else if (__vma_private_lock(vma)) { -+ struct resv_map *resv_map = vma_resv_map(vma); -+ -+ lockdep_assert_held(&resv_map->rw_sema); - } - } - -@@ -350,6 +377,11 @@ static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma) - struct hugetlb_vma_lock *vma_lock = vma->vm_private_data; - - __hugetlb_vma_unlock_write_put(vma_lock); -+ } else if (__vma_private_lock(vma)) { -+ struct resv_map *resv_map = vma_resv_map(vma); -+ -+ /* no free for anon vmas, but still need to unlock */ -+ up_write(&resv_map->rw_sema); - } - } - -@@ -1068,6 +1100,7 @@ struct resv_map *resv_map_alloc(void) - kref_init(&resv_map->refs); - spin_lock_init(&resv_map->lock); - INIT_LIST_HEAD(&resv_map->regions); -+ init_rwsem(&resv_map->rw_sema); - - resv_map->adds_in_progress = 0; - /* -@@ -1138,8 +1171,7 @@ static void set_vma_resv_map(struct vm_area_struct *vma, struct resv_map *map) - VM_BUG_ON_VMA(!is_vm_hugetlb_page(vma), vma); - VM_BUG_ON_VMA(vma->vm_flags & VM_MAYSHARE, vma); - -- set_vma_private_data(vma, (get_vma_private_data(vma) & -- HPAGE_RESV_MASK) | (unsigned long)map); -+ set_vma_private_data(vma, (unsigned long)map); - } - - static void set_vma_resv_flags(struct vm_area_struct *vma, unsigned long flags) -@@ -6898,8 +6930,10 @@ out_err: - */ - if (chg >= 0 && add < 0) - region_abort(resv_map, from, to, regions_needed); -- if (vma && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) -+ if (vma && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) { - kref_put(&resv_map->refs, resv_map_release); -+ set_vma_resv_map(vma, NULL); -+ } - return false; - } - -diff --git a/mm/kasan/report.c b/mm/kasan/report.c -index cc98dfdd3ed2f..66a37f177d231 100644 ---- a/mm/kasan/report.c -+++ b/mm/kasan/report.c -@@ -523,9 +523,8 @@ void kasan_report_async(void) - } - #endif /* CONFIG_KASAN_HW_TAGS */ - --#ifdef CONFIG_KASAN_INLINE - /* -- * With CONFIG_KASAN_INLINE, accesses to bogus pointers (outside the high -+ * With CONFIG_KASAN, accesses to bogus pointers (outside the high - * canonical half of the address space) cause out-of-bounds shadow memory reads - * before the actual access. For addresses in the low canonical half of the - * address space, as well as most non-canonical addresses, that out-of-bounds -@@ -561,4 +560,3 @@ void kasan_non_canonical_hook(unsigned long addr) - pr_alert("KASAN: %s in range [0x%016lx-0x%016lx]\n", bug_type, - orig_addr, orig_addr + KASAN_GRANULE_SIZE - 1); - } --#endif -diff --git a/mm/migrate.c b/mm/migrate.c -index 8d5c0dc618a57..9372a826e6d08 100644 ---- a/mm/migrate.c -+++ b/mm/migrate.c -@@ -1787,6 +1787,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, - const int __user *nodes, - int __user *status, int flags) - { -+ compat_uptr_t __user *compat_pages = (void __user *)pages; - int current_node = NUMA_NO_NODE; - LIST_HEAD(pagelist); - int start, i; -@@ -1800,8 +1801,17 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, - int node; - - err = -EFAULT; -- if (get_user(p, pages + i)) -- goto out_flush; -+ if (in_compat_syscall()) { -+ compat_uptr_t cp; -+ -+ if (get_user(cp, compat_pages + i)) -+ goto out_flush; -+ -+ p = compat_ptr(cp); -+ } else { -+ if (get_user(p, pages + i)) -+ goto out_flush; -+ } - if (get_user(node, nodes + i)) - goto out_flush; - addr = (unsigned long)untagged_addr(p); -diff --git a/mm/mmap.c b/mm/mmap.c -index 41a240bd81df8..8ffe3f87f7ba9 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -3147,13 +3147,13 @@ int vm_brk_flags(unsigned long addr, unsigned long request, unsigned long flags) - if (!len) - return 0; - -- if (mmap_write_lock_killable(mm)) -- return -EINTR; -- - /* Until we need other flags, refuse anything except VM_EXEC. */ - if ((flags & (~VM_EXEC)) != 0) - return -EINVAL; - -+ if (mmap_write_lock_killable(mm)) -+ return -EINTR; -+ - ret = check_brk_limits(addr, len); - if (ret) - goto limits_failed; -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index ca017c6008b7c..4583f8a42d914 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -9638,6 +9638,7 @@ static void break_down_buddy_pages(struct zone *zone, struct page *page, - next_page = page; - current_buddy = page + size; - } -+ page = next_page; - - if (set_page_guard(zone, current_buddy, high, migratetype)) - continue; -@@ -9645,7 +9646,6 @@ static void break_down_buddy_pages(struct zone *zone, struct page *page, - if (current_buddy != target) { - add_to_free_list(current_buddy, zone, high, migratetype); - set_buddy_order(current_buddy, high); -- page = next_page; - } - } - } -diff --git a/net/core/neighbour.c b/net/core/neighbour.c -index b20c9768d9f3f..41daa47d03934 100644 ---- a/net/core/neighbour.c -+++ b/net/core/neighbour.c -@@ -251,7 +251,8 @@ bool neigh_remove_one(struct neighbour *ndel, struct neigh_table *tbl) - - static int neigh_forced_gc(struct neigh_table *tbl) - { -- int max_clean = atomic_read(&tbl->gc_entries) - tbl->gc_thresh2; -+ int max_clean = atomic_read(&tbl->gc_entries) - -+ READ_ONCE(tbl->gc_thresh2); - unsigned long tref = jiffies - 5 * HZ; - struct neighbour *n, *tmp; - int shrunk = 0; -@@ -280,7 +281,7 @@ static int neigh_forced_gc(struct neigh_table *tbl) - } - } - -- tbl->last_flush = jiffies; -+ WRITE_ONCE(tbl->last_flush, jiffies); - - write_unlock_bh(&tbl->lock); - -@@ -464,17 +465,17 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl, - { - struct neighbour *n = NULL; - unsigned long now = jiffies; -- int entries; -+ int entries, gc_thresh3; - - if (exempt_from_gc) - goto do_alloc; - - entries = atomic_inc_return(&tbl->gc_entries) - 1; -- if (entries >= tbl->gc_thresh3 || -- (entries >= tbl->gc_thresh2 && -- time_after(now, tbl->last_flush + 5 * HZ))) { -- if (!neigh_forced_gc(tbl) && -- entries >= tbl->gc_thresh3) { -+ gc_thresh3 = READ_ONCE(tbl->gc_thresh3); -+ if (entries >= gc_thresh3 || -+ (entries >= READ_ONCE(tbl->gc_thresh2) && -+ time_after(now, READ_ONCE(tbl->last_flush) + 5 * HZ))) { -+ if (!neigh_forced_gc(tbl) && entries >= gc_thresh3) { - net_info_ratelimited("%s: neighbor table overflow!\n", - tbl->id); - NEIGH_CACHE_STAT_INC(tbl, table_fulls); -@@ -955,13 +956,14 @@ static void neigh_periodic_work(struct work_struct *work) - - if (time_after(jiffies, tbl->last_rand + 300 * HZ)) { - struct neigh_parms *p; -- tbl->last_rand = jiffies; -+ -+ WRITE_ONCE(tbl->last_rand, jiffies); - list_for_each_entry(p, &tbl->parms_list, list) - p->reachable_time = - neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME)); - } - -- if (atomic_read(&tbl->entries) < tbl->gc_thresh1) -+ if (atomic_read(&tbl->entries) < READ_ONCE(tbl->gc_thresh1)) - goto out; - - for (i = 0 ; i < (1 << nht->hash_shift); i++) { -@@ -2157,15 +2159,16 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, - ndtmsg->ndtm_pad2 = 0; - - if (nla_put_string(skb, NDTA_NAME, tbl->id) || -- nla_put_msecs(skb, NDTA_GC_INTERVAL, tbl->gc_interval, NDTA_PAD) || -- nla_put_u32(skb, NDTA_THRESH1, tbl->gc_thresh1) || -- nla_put_u32(skb, NDTA_THRESH2, tbl->gc_thresh2) || -- nla_put_u32(skb, NDTA_THRESH3, tbl->gc_thresh3)) -+ nla_put_msecs(skb, NDTA_GC_INTERVAL, READ_ONCE(tbl->gc_interval), -+ NDTA_PAD) || -+ nla_put_u32(skb, NDTA_THRESH1, READ_ONCE(tbl->gc_thresh1)) || -+ nla_put_u32(skb, NDTA_THRESH2, READ_ONCE(tbl->gc_thresh2)) || -+ nla_put_u32(skb, NDTA_THRESH3, READ_ONCE(tbl->gc_thresh3))) - goto nla_put_failure; - { - unsigned long now = jiffies; -- long flush_delta = now - tbl->last_flush; -- long rand_delta = now - tbl->last_rand; -+ long flush_delta = now - READ_ONCE(tbl->last_flush); -+ long rand_delta = now - READ_ONCE(tbl->last_rand); - struct neigh_hash_table *nht; - struct ndt_config ndc = { - .ndtc_key_len = tbl->key_len, -@@ -2173,7 +2176,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, - .ndtc_entries = atomic_read(&tbl->entries), - .ndtc_last_flush = jiffies_to_msecs(flush_delta), - .ndtc_last_rand = jiffies_to_msecs(rand_delta), -- .ndtc_proxy_qlen = tbl->proxy_queue.qlen, -+ .ndtc_proxy_qlen = READ_ONCE(tbl->proxy_queue.qlen), - }; - - rcu_read_lock(); -@@ -2196,17 +2199,17 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, - struct neigh_statistics *st; - - st = per_cpu_ptr(tbl->stats, cpu); -- ndst.ndts_allocs += st->allocs; -- ndst.ndts_destroys += st->destroys; -- ndst.ndts_hash_grows += st->hash_grows; -- ndst.ndts_res_failed += st->res_failed; -- ndst.ndts_lookups += st->lookups; -- ndst.ndts_hits += st->hits; -- ndst.ndts_rcv_probes_mcast += st->rcv_probes_mcast; -- ndst.ndts_rcv_probes_ucast += st->rcv_probes_ucast; -- ndst.ndts_periodic_gc_runs += st->periodic_gc_runs; -- ndst.ndts_forced_gc_runs += st->forced_gc_runs; -- ndst.ndts_table_fulls += st->table_fulls; -+ ndst.ndts_allocs += READ_ONCE(st->allocs); -+ ndst.ndts_destroys += READ_ONCE(st->destroys); -+ ndst.ndts_hash_grows += READ_ONCE(st->hash_grows); -+ ndst.ndts_res_failed += READ_ONCE(st->res_failed); -+ ndst.ndts_lookups += READ_ONCE(st->lookups); -+ ndst.ndts_hits += READ_ONCE(st->hits); -+ ndst.ndts_rcv_probes_mcast += READ_ONCE(st->rcv_probes_mcast); -+ ndst.ndts_rcv_probes_ucast += READ_ONCE(st->rcv_probes_ucast); -+ ndst.ndts_periodic_gc_runs += READ_ONCE(st->periodic_gc_runs); -+ ndst.ndts_forced_gc_runs += READ_ONCE(st->forced_gc_runs); -+ ndst.ndts_table_fulls += READ_ONCE(st->table_fulls); - } - - if (nla_put_64bit(skb, NDTA_STATS, sizeof(ndst), &ndst, -@@ -2435,16 +2438,16 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, - goto errout_tbl_lock; - - if (tb[NDTA_THRESH1]) -- tbl->gc_thresh1 = nla_get_u32(tb[NDTA_THRESH1]); -+ WRITE_ONCE(tbl->gc_thresh1, nla_get_u32(tb[NDTA_THRESH1])); - - if (tb[NDTA_THRESH2]) -- tbl->gc_thresh2 = nla_get_u32(tb[NDTA_THRESH2]); -+ WRITE_ONCE(tbl->gc_thresh2, nla_get_u32(tb[NDTA_THRESH2])); - - if (tb[NDTA_THRESH3]) -- tbl->gc_thresh3 = nla_get_u32(tb[NDTA_THRESH3]); -+ WRITE_ONCE(tbl->gc_thresh3, nla_get_u32(tb[NDTA_THRESH3])); - - if (tb[NDTA_GC_INTERVAL]) -- tbl->gc_interval = nla_get_msecs(tb[NDTA_GC_INTERVAL]); -+ WRITE_ONCE(tbl->gc_interval, nla_get_msecs(tb[NDTA_GC_INTERVAL])); - - err = 0; - -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index 068221e742425..d63942202493d 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -2202,16 +2202,17 @@ void tcp_enter_loss(struct sock *sk) - * restore sanity to the SACK scoreboard. If the apparent reneging - * persists until this RTO then we'll clear the SACK scoreboard. - */ --static bool tcp_check_sack_reneging(struct sock *sk, int flag) -+static bool tcp_check_sack_reneging(struct sock *sk, int *ack_flag) - { -- if (flag & FLAG_SACK_RENEGING && -- flag & FLAG_SND_UNA_ADVANCED) { -+ if (*ack_flag & FLAG_SACK_RENEGING && -+ *ack_flag & FLAG_SND_UNA_ADVANCED) { - struct tcp_sock *tp = tcp_sk(sk); - unsigned long delay = max(usecs_to_jiffies(tp->srtt_us >> 4), - msecs_to_jiffies(10)); - - inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, - delay, TCP_RTO_MAX); -+ *ack_flag &= ~FLAG_SET_XMIT_TIMER; - return true; - } - return false; -@@ -2981,7 +2982,7 @@ static void tcp_fastretrans_alert(struct sock *sk, const u32 prior_snd_una, - tp->prior_ssthresh = 0; - - /* B. In all the states check for reneging SACKs. */ -- if (tcp_check_sack_reneging(sk, flag)) -+ if (tcp_check_sack_reneging(sk, ack_flag)) - return; - - /* C. Check consistency of the current state. */ -diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c -index ad64f403536a9..460e7fbb42da3 100644 ---- a/net/vmw_vsock/virtio_transport.c -+++ b/net/vmw_vsock/virtio_transport.c -@@ -590,6 +590,11 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) - - virtio_device_ready(vdev); - -+ return 0; -+} -+ -+static void virtio_vsock_vqs_start(struct virtio_vsock *vsock) -+{ - mutex_lock(&vsock->tx_lock); - vsock->tx_run = true; - mutex_unlock(&vsock->tx_lock); -@@ -604,7 +609,16 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) - vsock->event_run = true; - mutex_unlock(&vsock->event_lock); - -- return 0; -+ /* virtio_transport_send_pkt() can queue packets once -+ * the_virtio_vsock is set, but they won't be processed until -+ * vsock->tx_run is set to true. We queue vsock->send_pkt_work -+ * when initialization finishes to send those packets queued -+ * earlier. -+ * We don't need to queue the other workers (rx, event) because -+ * as long as we don't fill the queues with empty buffers, the -+ * host can't send us any notification. -+ */ -+ queue_work(virtio_vsock_workqueue, &vsock->send_pkt_work); - } - - static void virtio_vsock_vqs_del(struct virtio_vsock *vsock) -@@ -707,6 +721,7 @@ static int virtio_vsock_probe(struct virtio_device *vdev) - goto out; - - rcu_assign_pointer(the_virtio_vsock, vsock); -+ virtio_vsock_vqs_start(vsock); - - mutex_unlock(&the_virtio_vsock_mutex); - -@@ -779,6 +794,7 @@ static int virtio_vsock_restore(struct virtio_device *vdev) - goto out; - - rcu_assign_pointer(the_virtio_vsock, vsock); -+ virtio_vsock_vqs_start(vsock); - - out: - mutex_unlock(&the_virtio_vsock_mutex); -diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c -index c3964aa00b288..a2abd1a111612 100644 ---- a/sound/soc/codecs/wcd938x.c -+++ b/sound/soc/codecs/wcd938x.c -@@ -3302,18 +3302,15 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device - int ret; - - wcd938x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0); -- if (wcd938x->reset_gpio < 0) { -- dev_err(dev, "Failed to get reset gpio: err = %d\n", -- wcd938x->reset_gpio); -- return wcd938x->reset_gpio; -- } -+ if (wcd938x->reset_gpio < 0) -+ return dev_err_probe(dev, wcd938x->reset_gpio, -+ "Failed to get reset gpio\n"); - - wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", - GPIOD_OUT_LOW); -- if (IS_ERR(wcd938x->us_euro_gpio)) { -- dev_err(dev, "us-euro swap Control GPIO not found\n"); -- return PTR_ERR(wcd938x->us_euro_gpio); -- } -+ if (IS_ERR(wcd938x->us_euro_gpio)) -+ return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio), -+ "us-euro swap Control GPIO not found\n"); - - cfg->swap_gnd_mic = wcd938x_swap_gnd_mic; - -@@ -3323,15 +3320,13 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device - wcd938x->supplies[3].supply = "vdd-mic-bias"; - - ret = regulator_bulk_get(dev, WCD938X_MAX_SUPPLY, wcd938x->supplies); -- if (ret) { -- dev_err(dev, "Failed to get supplies: err = %d\n", ret); -- return ret; -- } -+ if (ret) -+ return dev_err_probe(dev, ret, "Failed to get supplies\n"); - - ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies); - if (ret) { -- dev_err(dev, "Failed to enable supplies: err = %d\n", ret); -- return ret; -+ regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); -+ return dev_err_probe(dev, ret, "Failed to enable supplies\n"); - } - - wcd938x_dt_parse_micbias_info(dev, wcd938x); -@@ -3598,13 +3593,13 @@ static int wcd938x_probe(struct platform_device *pdev) - - ret = wcd938x_add_slave_components(wcd938x, dev, &match); - if (ret) -- return ret; -+ goto err_disable_regulators; - - wcd938x_reset(wcd938x); - - ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match); - if (ret) -- return ret; -+ goto err_disable_regulators; - - pm_runtime_set_autosuspend_delay(dev, 1000); - pm_runtime_use_autosuspend(dev); -@@ -3614,13 +3609,27 @@ static int wcd938x_probe(struct platform_device *pdev) - pm_runtime_idle(dev); - - return 0; -+ -+err_disable_regulators: -+ regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); -+ regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); -+ -+ return ret; - } - --static int wcd938x_remove(struct platform_device *pdev) -+static void wcd938x_remove(struct platform_device *pdev) - { -- component_master_del(&pdev->dev, &wcd938x_comp_ops); -+ struct device *dev = &pdev->dev; -+ struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); - -- return 0; -+ component_master_del(dev, &wcd938x_comp_ops); -+ -+ pm_runtime_disable(dev); -+ pm_runtime_set_suspended(dev); -+ pm_runtime_dont_use_autosuspend(dev); -+ -+ regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); -+ regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); - } - - #if defined(CONFIG_OF) -@@ -3634,7 +3643,7 @@ MODULE_DEVICE_TABLE(of, wcd938x_dt_match); - - static struct platform_driver wcd938x_codec_driver = { - .probe = wcd938x_probe, -- .remove = wcd938x_remove, -+ .remove_new = wcd938x_remove, - .driver = { - .name = "wcd938x_codec", - .of_match_table = of_match_ptr(wcd938x_dt_match), -diff --git a/tools/include/linux/rwsem.h b/tools/include/linux/rwsem.h -new file mode 100644 -index 0000000000000..83971b3cbfced ---- /dev/null -+++ b/tools/include/linux/rwsem.h -@@ -0,0 +1,40 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ -+#ifndef _TOOLS__RWSEM_H -+#define _TOOLS__RWSEM_H -+ -+#include -+ -+struct rw_semaphore { -+ pthread_rwlock_t lock; -+}; -+ -+static inline int init_rwsem(struct rw_semaphore *sem) -+{ -+ return pthread_rwlock_init(&sem->lock, NULL); -+} -+ -+static inline int exit_rwsem(struct rw_semaphore *sem) -+{ -+ return pthread_rwlock_destroy(&sem->lock); -+} -+ -+static inline int down_read(struct rw_semaphore *sem) -+{ -+ return pthread_rwlock_rdlock(&sem->lock); -+} -+ -+static inline int up_read(struct rw_semaphore *sem) -+{ -+ return pthread_rwlock_unlock(&sem->lock); -+} -+ -+static inline int down_write(struct rw_semaphore *sem) -+{ -+ return pthread_rwlock_wrlock(&sem->lock); -+} -+ -+static inline int up_write(struct rw_semaphore *sem) -+{ -+ return pthread_rwlock_unlock(&sem->lock); -+} -+#endif /* _TOOLS_RWSEM_H */ -diff --git a/tools/objtool/check.c b/tools/objtool/check.c -index f8008ab31eef0..cb363b507a329 100644 ---- a/tools/objtool/check.c -+++ b/tools/objtool/check.c -@@ -2478,7 +2478,7 @@ static bool is_special_call(struct instruction *insn) - if (!dest) - return false; - -- if (dest->fentry) -+ if (dest->fentry || dest->embedded_insn) - return true; - } - diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.61-62.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.61-62.patch deleted file mode 100644 index 9c94ec4694a3..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.61-62.patch +++ /dev/null @@ -1,1798 +0,0 @@ -diff --git a/Makefile b/Makefile -index 635474f38aaa9..2e7bc3cc1c177 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 61 -+SUBLEVEL = 62 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c -index c7e9c96719fa3..f42a3be5f28d7 100644 ---- a/arch/loongarch/mm/init.c -+++ b/arch/loongarch/mm/init.c -@@ -68,11 +68,11 @@ void copy_user_highpage(struct page *to, struct page *from, - { - void *vfrom, *vto; - -- vto = kmap_atomic(to); -- vfrom = kmap_atomic(from); -+ vfrom = kmap_local_page(from); -+ vto = kmap_local_page(to); - copy_page(vto, vfrom); -- kunmap_atomic(vfrom); -- kunmap_atomic(vto); -+ kunmap_local(vfrom); -+ kunmap_local(vto); - /* Make sure this page is cleared on other CPU's too before using it */ - smp_wmb(); - } -@@ -228,6 +228,7 @@ pgd_t swapper_pg_dir[_PTRS_PER_PGD] __section(".bss..swapper_pg_dir"); - pgd_t invalid_pg_dir[_PTRS_PER_PGD] __page_aligned_bss; - #ifndef __PAGETABLE_PUD_FOLDED - pud_t invalid_pud_table[PTRS_PER_PUD] __page_aligned_bss; -+EXPORT_SYMBOL(invalid_pud_table); - #endif - #ifndef __PAGETABLE_PMD_FOLDED - pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned_bss; -diff --git a/arch/powerpc/kernel/head_85xx.S b/arch/powerpc/kernel/head_85xx.S -index 52c0ab416326a..0e16aea7853b8 100644 ---- a/arch/powerpc/kernel/head_85xx.S -+++ b/arch/powerpc/kernel/head_85xx.S -@@ -394,7 +394,7 @@ interrupt_base: - #ifdef CONFIG_PPC_FPU - FP_UNAVAILABLE_EXCEPTION - #else -- EXCEPTION(0x0800, FP_UNAVAIL, FloatingPointUnavailable, unknown_exception) -+ EXCEPTION(0x0800, FP_UNAVAIL, FloatingPointUnavailable, emulation_assist_interrupt) - #endif - - /* System Call Interrupt */ -diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c -index efb301a4987ca..59b4ac57bfaf7 100644 ---- a/arch/powerpc/kernel/setup-common.c -+++ b/arch/powerpc/kernel/setup-common.c -@@ -946,6 +946,8 @@ void __init setup_arch(char **cmdline_p) - - /* Parse memory topology */ - mem_topology_setup(); -+ /* Set max_mapnr before paging_init() */ -+ set_max_mapnr(max_pfn); - - /* - * Release secondary cpus out of their spinloops at 0x60 now that -diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c -index 84d171953ba44..c7599b1737099 100644 ---- a/arch/powerpc/mm/mem.c -+++ b/arch/powerpc/mm/mem.c -@@ -288,7 +288,6 @@ void __init mem_init(void) - #endif - - high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); -- set_max_mapnr(max_pfn); - - kasan_late_init(); - -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index c871a6d6364ca..4194aa4c5f0e0 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -822,8 +822,7 @@ void svm_set_x2apic_msr_interception(struct vcpu_svm *svm, bool intercept) - if (intercept == svm->x2avic_msrs_intercepted) - return; - -- if (avic_mode != AVIC_MODE_X2 || -- !apic_x2apic_mode(svm->vcpu.arch.apic)) -+ if (avic_mode != AVIC_MODE_X2) - return; - - for (i = 0; i < MAX_DIRECT_ACCESS_MSRS; i++) { -diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c -index 3b09fdc507e04..594b016e76efc 100644 ---- a/drivers/dma/ste_dma40.c -+++ b/drivers/dma/ste_dma40.c -@@ -3697,6 +3697,7 @@ static int __init d40_probe(struct platform_device *pdev) - regulator_disable(base->lcpa_regulator); - regulator_put(base->lcpa_regulator); - } -+ pm_runtime_disable(base->dev); - - kfree(base->lcla_pool.alloc_map); - kfree(base->lookup_log_chans); -diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index b43e5e6ddaf6e..b7c0e8cc0764f 100644 ---- a/drivers/firmware/efi/efi.c -+++ b/drivers/firmware/efi/efi.c -@@ -245,9 +245,13 @@ static __init int efivar_ssdt_load(void) - if (status == EFI_NOT_FOUND) { - break; - } else if (status == EFI_BUFFER_TOO_SMALL) { -- name = krealloc(name, name_size, GFP_KERNEL); -- if (!name) -+ efi_char16_t *name_tmp = -+ krealloc(name, name_size, GFP_KERNEL); -+ if (!name_tmp) { -+ kfree(name); - return -ENOMEM; -+ } -+ name = name_tmp; - continue; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c -index d2139ac121595..1ed2142a6e7bf 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c -@@ -47,7 +47,6 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = { - bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio) - { - switch (ctx_prio) { -- case AMDGPU_CTX_PRIORITY_UNSET: - case AMDGPU_CTX_PRIORITY_VERY_LOW: - case AMDGPU_CTX_PRIORITY_LOW: - case AMDGPU_CTX_PRIORITY_NORMAL: -@@ -55,6 +54,7 @@ bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio) - case AMDGPU_CTX_PRIORITY_VERY_HIGH: - return true; - default: -+ case AMDGPU_CTX_PRIORITY_UNSET: - return false; - } - } -@@ -64,7 +64,8 @@ amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio) - { - switch (ctx_prio) { - case AMDGPU_CTX_PRIORITY_UNSET: -- return DRM_SCHED_PRIORITY_UNSET; -+ pr_warn_once("AMD-->DRM context priority value UNSET-->NORMAL"); -+ return DRM_SCHED_PRIORITY_NORMAL; - - case AMDGPU_CTX_PRIORITY_VERY_LOW: - return DRM_SCHED_PRIORITY_MIN; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -index 7bd8e33b14be5..e8b3e9520cf6e 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c -@@ -400,7 +400,10 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach) - continue; - } - -- r = amdgpu_vm_clear_freed(adev, vm, NULL); -+ /* Reserve fences for two SDMA page table updates */ -+ r = dma_resv_reserve_fences(resv, 2); -+ if (!r) -+ r = amdgpu_vm_clear_freed(adev, vm, NULL); - if (!r) - r = amdgpu_vm_handle_moved(adev, vm); - -diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c -index b84f74807ca13..ec9ddaad56a05 100644 ---- a/drivers/gpu/drm/ttm/ttm_device.c -+++ b/drivers/gpu/drm/ttm/ttm_device.c -@@ -239,10 +239,6 @@ void ttm_device_fini(struct ttm_device *bdev) - struct ttm_resource_manager *man; - unsigned i; - -- man = ttm_manager_type(bdev, TTM_PL_SYSTEM); -- ttm_resource_manager_set_used(man, false); -- ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL); -- - mutex_lock(&ttm_global_mutex); - list_del(&bdev->device_list); - mutex_unlock(&ttm_global_mutex); -@@ -252,6 +248,10 @@ void ttm_device_fini(struct ttm_device *bdev) - if (ttm_bo_delayed_delete(bdev, true)) - pr_debug("Delayed destroy list was clean\n"); - -+ man = ttm_manager_type(bdev, TTM_PL_SYSTEM); -+ ttm_resource_manager_set_used(man, false); -+ ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL); -+ - spin_lock(&bdev->lru_lock); - for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) - if (list_empty(&man->lru[0])) -diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c -index 1be0e5e0e80b2..c88a6afb29512 100644 ---- a/drivers/hwtracing/coresight/coresight-tmc-etr.c -+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c -@@ -610,7 +610,8 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, - - flat_buf->vaddr = dma_alloc_noncoherent(real_dev, etr_buf->size, - &flat_buf->daddr, -- DMA_FROM_DEVICE, GFP_KERNEL); -+ DMA_FROM_DEVICE, -+ GFP_KERNEL | __GFP_NOWARN); - if (!flat_buf->vaddr) { - kfree(flat_buf); - return -ENOMEM; -diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c -index d2c9f4cbd00c6..e43e93ac2798a 100644 ---- a/drivers/input/mouse/synaptics.c -+++ b/drivers/input/mouse/synaptics.c -@@ -1753,6 +1753,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse, - psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) && - !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10); - const struct rmi_device_platform_data pdata = { -+ .reset_delay_ms = 30, - .sensor_pdata = { - .sensor_type = rmi_sensor_touchpad, - .axis_align.flip_y = true, -diff --git a/drivers/input/rmi4/rmi_smbus.c b/drivers/input/rmi4/rmi_smbus.c -index c130468541b7d..7080c2ddbaf2b 100644 ---- a/drivers/input/rmi4/rmi_smbus.c -+++ b/drivers/input/rmi4/rmi_smbus.c -@@ -235,12 +235,29 @@ static void rmi_smb_clear_state(struct rmi_smb_xport *rmi_smb) - - static int rmi_smb_enable_smbus_mode(struct rmi_smb_xport *rmi_smb) - { -- int retval; -+ struct i2c_client *client = rmi_smb->client; -+ int smbus_version; -+ -+ /* -+ * psmouse driver resets the controller, we only need to wait -+ * to give the firmware chance to fully reinitialize. -+ */ -+ if (rmi_smb->xport.pdata.reset_delay_ms) -+ msleep(rmi_smb->xport.pdata.reset_delay_ms); - - /* we need to get the smbus version to activate the touchpad */ -- retval = rmi_smb_get_version(rmi_smb); -- if (retval < 0) -- return retval; -+ smbus_version = rmi_smb_get_version(rmi_smb); -+ if (smbus_version < 0) -+ return smbus_version; -+ -+ rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d", -+ smbus_version); -+ -+ if (smbus_version != 2 && smbus_version != 3) { -+ dev_err(&client->dev, "Unrecognized SMB version %d\n", -+ smbus_version); -+ return -ENODEV; -+ } - - return 0; - } -@@ -253,11 +270,10 @@ static int rmi_smb_reset(struct rmi_transport_dev *xport, u16 reset_addr) - rmi_smb_clear_state(rmi_smb); - - /* -- * we do not call the actual reset command, it has to be handled in -- * PS/2 or there will be races between PS/2 and SMBus. -- * PS/2 should ensure that a psmouse_reset is called before -- * intializing the device and after it has been removed to be in a known -- * state. -+ * We do not call the actual reset command, it has to be handled in -+ * PS/2 or there will be races between PS/2 and SMBus. PS/2 should -+ * ensure that a psmouse_reset is called before initializing the -+ * device and after it has been removed to be in a known state. - */ - return rmi_smb_enable_smbus_mode(rmi_smb); - } -@@ -273,7 +289,6 @@ static int rmi_smb_probe(struct i2c_client *client, - { - struct rmi_device_platform_data *pdata = dev_get_platdata(&client->dev); - struct rmi_smb_xport *rmi_smb; -- int smbus_version; - int error; - - if (!pdata) { -@@ -312,18 +327,9 @@ static int rmi_smb_probe(struct i2c_client *client, - rmi_smb->xport.proto_name = "smb"; - rmi_smb->xport.ops = &rmi_smb_ops; - -- smbus_version = rmi_smb_get_version(rmi_smb); -- if (smbus_version < 0) -- return smbus_version; -- -- rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d", -- smbus_version); -- -- if (smbus_version != 2 && smbus_version != 3) { -- dev_err(&client->dev, "Unrecognized SMB version %d\n", -- smbus_version); -- return -ENODEV; -- } -+ error = rmi_smb_enable_smbus_mode(rmi_smb); -+ if (error) -+ return error; - - i2c_set_clientdata(client, rmi_smb); - -diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c -index 499e5f81b3fe3..4b66850978e6e 100644 ---- a/drivers/irqchip/irq-riscv-intc.c -+++ b/drivers/irqchip/irq-riscv-intc.c -@@ -110,8 +110,16 @@ static int __init riscv_intc_init(struct device_node *node, - * for each INTC DT node. We only need to do INTC initialization - * for the INTC DT node belonging to boot CPU (or boot HART). - */ -- if (riscv_hartid_to_cpuid(hartid) != smp_processor_id()) -+ if (riscv_hartid_to_cpuid(hartid) != smp_processor_id()) { -+ /* -+ * The INTC nodes of each CPU are suppliers for downstream -+ * interrupt controllers (such as PLIC, IMSIC and APLIC -+ * direct-mode) so we should mark an INTC node as initialized -+ * if we are not creating IRQ domain for it. -+ */ -+ fwnode_dev_initialized(of_fwnode_handle(node), true); - return 0; -+ } - - intc_domain = irq_domain_add_linear(node, BITS_PER_LONG, - &riscv_intc_domain_ops, NULL); -diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c -index 8bbb2b114636c..dc6f67decb022 100644 ---- a/drivers/irqchip/irq-stm32-exti.c -+++ b/drivers/irqchip/irq-stm32-exti.c -@@ -458,6 +458,7 @@ static const struct irq_domain_ops irq_exti_domain_ops = { - .map = irq_map_generic_chip, - .alloc = stm32_exti_alloc, - .free = stm32_exti_free, -+ .xlate = irq_domain_xlate_twocell, - }; - - static void stm32_irq_ack(struct irq_data *d) -diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c -index d1e2f22537dbe..55dc16d8f6adb 100644 ---- a/drivers/misc/pci_endpoint_test.c -+++ b/drivers/misc/pci_endpoint_test.c -@@ -71,6 +71,7 @@ - #define PCI_DEVICE_ID_TI_AM654 0xb00c - #define PCI_DEVICE_ID_TI_J7200 0xb00f - #define PCI_DEVICE_ID_TI_AM64 0xb010 -+#define PCI_DEVICE_ID_TI_J721S2 0xb013 - #define PCI_DEVICE_ID_LS1088A 0x80c0 - - #define is_am654_pci_dev(pdev) \ -@@ -1004,6 +1005,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM64), - .driver_data = (kernel_ulong_t)&j721e_data, - }, -+ { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721S2), -+ .driver_data = (kernel_ulong_t)&j721e_data, -+ }, - { } - }; - MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl); -diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c -index 8d719f82854a9..76de55306c4d0 100644 ---- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c -+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c -@@ -3816,6 +3816,8 @@ int t4_load_phy_fw(struct adapter *adap, int win, - FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_DOWNLOAD)); - ret = t4_set_params_timeout(adap, adap->mbox, adap->pf, 0, 1, - ¶m, &val, 30000); -+ if (ret) -+ return ret; - - /* If we have version number support, then check to see that the new - * firmware got loaded properly. -diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c -index c34974f7dfd26..345e341d22338 100644 ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -3655,6 +3655,8 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) - int i; - - for (i = 0; i < 500; i++) { -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) - break; -@@ -3695,6 +3697,8 @@ static void r8153c_ups_en(struct r8152 *tp, bool enable) - int i; - - for (i = 0; i < 500; i++) { -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) - break; -@@ -4058,6 +4062,9 @@ static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait) - for (i = 0; wait && i < 5000; i++) { - u32 ocp_data; - -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ break; -+ - usleep_range(1000, 2000); - ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT); - if ((ocp_data & PATCH_READY) ^ check) -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index 472fa2c8ebcec..30e7c627f21a7 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -595,7 +595,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_ - /* - * In the AMD NL platform, this device ([1022:7912]) has a class code of - * PCI_CLASS_SERIAL_USB_XHCI (0x0c0330), which means the xhci driver will -- * claim it. -+ * claim it. The same applies on the VanGogh platform device ([1022:163a]). - * - * But the dwc3 driver is a more specific driver for this device, and we'd - * prefer to use it instead of xhci. To prevent xhci from claiming the -@@ -603,7 +603,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_ - * defines as "USB device (not host controller)". The dwc3 driver can then - * claim it based on its Vendor and Device ID. - */ --static void quirk_amd_nl_class(struct pci_dev *pdev) -+static void quirk_amd_dwc_class(struct pci_dev *pdev) - { - u32 class = pdev->class; - -@@ -613,7 +613,9 @@ static void quirk_amd_nl_class(struct pci_dev *pdev) - class, pdev->class); - } - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB, -- quirk_amd_nl_class); -+ quirk_amd_dwc_class); -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VANGOGH_USB, -+ quirk_amd_dwc_class); - - /* - * Synopsys USB 3.x host HAPS platform has a class code of -diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c -index a04ff89a7ec44..9925a6d94affc 100644 ---- a/drivers/platform/mellanox/mlxbf-tmfifo.c -+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c -@@ -588,24 +588,25 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring, - - if (vring->cur_len + sizeof(u64) <= len) { - /* The whole word. */ -- if (!IS_VRING_DROP(vring)) { -- if (is_rx) -+ if (is_rx) { -+ if (!IS_VRING_DROP(vring)) - memcpy(addr + vring->cur_len, &data, - sizeof(u64)); -- else -- memcpy(&data, addr + vring->cur_len, -- sizeof(u64)); -+ } else { -+ memcpy(&data, addr + vring->cur_len, -+ sizeof(u64)); - } - vring->cur_len += sizeof(u64); - } else { - /* Leftover bytes. */ -- if (!IS_VRING_DROP(vring)) { -- if (is_rx) -+ if (is_rx) { -+ if (!IS_VRING_DROP(vring)) - memcpy(addr + vring->cur_len, &data, - len - vring->cur_len); -- else -- memcpy(&data, addr + vring->cur_len, -- len - vring->cur_len); -+ } else { -+ data = 0; -+ memcpy(&data, addr + vring->cur_len, -+ len - vring->cur_len); - } - vring->cur_len = len; - } -diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c -index 7871ab5e979c0..ac88c9636b663 100644 ---- a/drivers/power/supply/power_supply_core.c -+++ b/drivers/power/supply/power_supply_core.c -@@ -29,7 +29,7 @@ - struct class *power_supply_class; - EXPORT_SYMBOL_GPL(power_supply_class); - --ATOMIC_NOTIFIER_HEAD(power_supply_notifier); -+BLOCKING_NOTIFIER_HEAD(power_supply_notifier); - EXPORT_SYMBOL_GPL(power_supply_notifier); - - static struct device_type power_supply_dev_type; -@@ -97,7 +97,7 @@ static void power_supply_changed_work(struct work_struct *work) - class_for_each_device(power_supply_class, NULL, psy, - __power_supply_changed_work); - power_supply_update_leds(psy); -- atomic_notifier_call_chain(&power_supply_notifier, -+ blocking_notifier_call_chain(&power_supply_notifier, - PSY_EVENT_PROP_CHANGED, psy); - kobject_uevent(&psy->dev.kobj, KOBJ_CHANGE); - spin_lock_irqsave(&psy->changed_lock, flags); -@@ -1112,13 +1112,13 @@ static void power_supply_dev_release(struct device *dev) - - int power_supply_reg_notifier(struct notifier_block *nb) - { -- return atomic_notifier_chain_register(&power_supply_notifier, nb); -+ return blocking_notifier_chain_register(&power_supply_notifier, nb); - } - EXPORT_SYMBOL_GPL(power_supply_reg_notifier); - - void power_supply_unreg_notifier(struct notifier_block *nb) - { -- atomic_notifier_chain_unregister(&power_supply_notifier, nb); -+ blocking_notifier_chain_unregister(&power_supply_notifier, nb); - } - EXPORT_SYMBOL_GPL(power_supply_unreg_notifier); - -diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c -index 8e24ebcebfe52..2ea3bdc638177 100644 ---- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c -+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c -@@ -12914,8 +12914,10 @@ _mpt3sas_init(void) - mpt3sas_ctl_init(hbas_to_enumerate); - - error = pci_register_driver(&mpt3sas_driver); -- if (error) -+ if (error) { -+ mpt3sas_ctl_exit(hbas_to_enumerate); - scsih_exit(); -+ } - - return error; - } -diff --git a/drivers/spi/spi-npcm-fiu.c b/drivers/spi/spi-npcm-fiu.c -index 49f6424e35af0..0624f52880705 100644 ---- a/drivers/spi/spi-npcm-fiu.c -+++ b/drivers/spi/spi-npcm-fiu.c -@@ -353,8 +353,9 @@ static int npcm_fiu_uma_read(struct spi_mem *mem, - uma_cfg |= ilog2(op->cmd.buswidth); - uma_cfg |= ilog2(op->addr.buswidth) - << NPCM_FIU_UMA_CFG_ADBPCK_SHIFT; -- uma_cfg |= ilog2(op->dummy.buswidth) -- << NPCM_FIU_UMA_CFG_DBPCK_SHIFT; -+ if (op->dummy.nbytes) -+ uma_cfg |= ilog2(op->dummy.buswidth) -+ << NPCM_FIU_UMA_CFG_DBPCK_SHIFT; - uma_cfg |= ilog2(op->data.buswidth) - << NPCM_FIU_UMA_CFG_RDBPCK_SHIFT; - uma_cfg |= op->dummy.nbytes << NPCM_FIU_UMA_CFG_DBSIZ_SHIFT; -diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c -index 4b43589304704..6b6abce6b69f4 100644 ---- a/drivers/tty/n_gsm.c -+++ b/drivers/tty/n_gsm.c -@@ -3404,6 +3404,8 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk) - - static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk) - { -+ if (dlci->gsm->dead) -+ return -EL2HLT; - if (dlci->adaption == 2) { - /* Send convergence layer type 2 empty data frame. */ - gsm_modem_upd_via_data(dlci, brk); -diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c -index 0ea89df6702f6..38fb7126ab0ef 100644 ---- a/drivers/tty/serial/8250/8250_pci.c -+++ b/drivers/tty/serial/8250/8250_pci.c -@@ -2447,6 +2447,153 @@ static struct pci_serial_quirk pci_serial_quirks[] = { - .init = pci_oxsemi_tornado_init, - .setup = pci_oxsemi_tornado_setup, - }, -+ /* -+ * Brainboxes devices - all Oxsemi based -+ */ -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4027, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4028, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4029, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4019, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4016, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4015, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x400A, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x400E, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x400C, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x400B, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x400F, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4010, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4011, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x401D, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x401E, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4013, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4017, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, -+ { -+ .vendor = PCI_VENDOR_ID_INTASHIELD, -+ .device = 0x4018, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .init = pci_oxsemi_tornado_init, -+ .setup = pci_oxsemi_tornado_setup, -+ }, - { - .vendor = PCI_VENDOR_ID_INTEL, - .device = 0x8811, -@@ -4931,6 +5078,12 @@ static const struct pci_device_id serial_pci_tbl[] = { - 0, 0, - pbn_b1_bt_1_115200 }, - -+ /* -+ * IntaShield IS-100 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0D60, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, -+ pbn_b2_1_115200 }, - /* - * IntaShield IS-200 - */ -@@ -4943,6 +5096,27 @@ static const struct pci_device_id serial_pci_tbl[] = { - { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ - pbn_b2_4_115200 }, -+ /* -+ * IntaShield IX-100 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x4027, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_oxsemi_1_15625000 }, -+ /* -+ * IntaShield IX-200 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x4028, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_oxsemi_2_15625000 }, -+ /* -+ * IntaShield IX-400 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x4029, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_oxsemi_4_15625000 }, - /* Brainboxes Devices */ - /* - * Brainboxes UC-101 -@@ -4958,10 +5132,14 @@ static const struct pci_device_id serial_pci_tbl[] = { - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, - pbn_b2_1_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0AA2, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_1_115200 }, - /* -- * Brainboxes UC-257 -+ * Brainboxes UC-253/UC-734 - */ -- { PCI_VENDOR_ID_INTASHIELD, 0x0861, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0CA1, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, - pbn_b2_2_115200 }, -@@ -4997,6 +5175,14 @@ static const struct pci_device_id serial_pci_tbl[] = { - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, - pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x08E2, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x08E3, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, - /* - * Brainboxes UC-310 - */ -@@ -5007,6 +5193,14 @@ static const struct pci_device_id serial_pci_tbl[] = { - /* - * Brainboxes UC-313 - */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x08A1, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x08A2, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, - { PCI_VENDOR_ID_INTASHIELD, 0x08A3, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, -@@ -5021,6 +5215,10 @@ static const struct pci_device_id serial_pci_tbl[] = { - /* - * Brainboxes UC-346 - */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0B01, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_4_115200 }, - { PCI_VENDOR_ID_INTASHIELD, 0x0B02, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, -@@ -5032,6 +5230,10 @@ static const struct pci_device_id serial_pci_tbl[] = { - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, - pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0A82, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, - { PCI_VENDOR_ID_INTASHIELD, 0x0A83, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, -@@ -5044,12 +5246,94 @@ static const struct pci_device_id serial_pci_tbl[] = { - 0, 0, - pbn_b2_4_115200 }, - /* -- * Brainboxes UC-420/431 -+ * Brainboxes UC-420 - */ - { PCI_VENDOR_ID_INTASHIELD, 0x0921, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, - pbn_b2_4_115200 }, -+ /* -+ * Brainboxes UC-607 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x09A1, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x09A2, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x09A3, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ /* -+ * Brainboxes UC-836 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0D41, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_4_115200 }, -+ /* -+ * Brainboxes UP-189 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0AC1, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0AC2, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0AC3, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ /* -+ * Brainboxes UP-200 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0B21, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0B22, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0B23, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ /* -+ * Brainboxes UP-869 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0C01, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0C02, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0C03, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ /* -+ * Brainboxes UP-880 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0C21, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0C22, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0C23, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_2_115200 }, - /* - * Brainboxes PX-101 - */ -@@ -5082,7 +5366,7 @@ static const struct pci_device_id serial_pci_tbl[] = { - { PCI_VENDOR_ID_INTASHIELD, 0x4015, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, -- pbn_oxsemi_4_15625000 }, -+ pbn_oxsemi_2_15625000 }, - /* - * Brainboxes PX-260/PX-701 - */ -@@ -5090,6 +5374,13 @@ static const struct pci_device_id serial_pci_tbl[] = { - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, - pbn_oxsemi_4_15625000 }, -+ /* -+ * Brainboxes PX-275/279 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0E41, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b2_8_115200 }, - /* - * Brainboxes PX-310 - */ -@@ -5137,16 +5428,38 @@ static const struct pci_device_id serial_pci_tbl[] = { - 0, 0, - pbn_oxsemi_4_15625000 }, - /* -- * Brainboxes PX-803 -+ * Brainboxes PX-475 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x401D, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_oxsemi_1_15625000 }, -+ /* -+ * Brainboxes PX-803/PX-857 - */ - { PCI_VENDOR_ID_INTASHIELD, 0x4009, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, -- pbn_b0_1_115200 }, -+ pbn_b0_2_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x4018, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_oxsemi_2_15625000 }, - { PCI_VENDOR_ID_INTASHIELD, 0x401E, - PCI_ANY_ID, PCI_ANY_ID, - 0, 0, -- pbn_oxsemi_1_15625000 }, -+ pbn_oxsemi_2_15625000 }, -+ /* -+ * Brainboxes PX-820 -+ */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x4002, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_b0_4_115200 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x4013, -+ PCI_ANY_ID, PCI_ANY_ID, -+ 0, 0, -+ pbn_oxsemi_4_15625000 }, - /* - * Brainboxes PX-846 - */ -diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c -index e549022642e56..ea106ad665a1f 100644 ---- a/drivers/usb/gadget/legacy/raw_gadget.c -+++ b/drivers/usb/gadget/legacy/raw_gadget.c -@@ -663,12 +663,12 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, - if (WARN_ON(in && dev->ep0_out_pending)) { - ret = -ENODEV; - dev->state = STATE_DEV_FAILED; -- goto out_done; -+ goto out_unlock; - } - if (WARN_ON(!in && dev->ep0_in_pending)) { - ret = -ENODEV; - dev->state = STATE_DEV_FAILED; -- goto out_done; -+ goto out_unlock; - } - - dev->req->buf = data; -@@ -683,7 +683,7 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, - "fail, usb_ep_queue returned %d\n", ret); - spin_lock_irqsave(&dev->lock, flags); - dev->state = STATE_DEV_FAILED; -- goto out_done; -+ goto out_queue_failed; - } - - ret = wait_for_completion_interruptible(&dev->ep0_done); -@@ -692,13 +692,16 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct usb_raw_ep_io *io, - usb_ep_dequeue(dev->gadget->ep0, dev->req); - wait_for_completion(&dev->ep0_done); - spin_lock_irqsave(&dev->lock, flags); -- goto out_done; -+ if (dev->ep0_status == -ECONNRESET) -+ dev->ep0_status = -EINTR; -+ goto out_interrupted; - } - - spin_lock_irqsave(&dev->lock, flags); -- ret = dev->ep0_status; - --out_done: -+out_interrupted: -+ ret = dev->ep0_status; -+out_queue_failed: - dev->ep0_urb_queued = false; - out_unlock: - spin_unlock_irqrestore(&dev->lock, flags); -@@ -1067,7 +1070,7 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, - "fail, usb_ep_queue returned %d\n", ret); - spin_lock_irqsave(&dev->lock, flags); - dev->state = STATE_DEV_FAILED; -- goto out_done; -+ goto out_queue_failed; - } - - ret = wait_for_completion_interruptible(&done); -@@ -1076,13 +1079,16 @@ static int raw_process_ep_io(struct raw_dev *dev, struct usb_raw_ep_io *io, - usb_ep_dequeue(ep->ep, ep->req); - wait_for_completion(&done); - spin_lock_irqsave(&dev->lock, flags); -- goto out_done; -+ if (ep->status == -ECONNRESET) -+ ep->status = -EINTR; -+ goto out_interrupted; - } - - spin_lock_irqsave(&dev->lock, flags); -- ret = ep->status; - --out_done: -+out_interrupted: -+ ret = ep->status; -+out_queue_failed: - ep->urb_queued = false; - out_unlock: - spin_unlock_irqrestore(&dev->lock, flags); -diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h -index 0547daf116a26..5df40759d77ad 100644 ---- a/drivers/usb/storage/unusual_cypress.h -+++ b/drivers/usb/storage/unusual_cypress.h -@@ -19,7 +19,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, - "Cypress ISD-300LP", - USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), - --UNUSUAL_DEV( 0x14cd, 0x6116, 0x0160, 0x0160, -+UNUSUAL_DEV( 0x14cd, 0x6116, 0x0150, 0x0160, - "Super Top", - "USB 2.0 SATA BRIDGE", - USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), -diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c -index ad4d0314d27fa..5e9d0c695fdb7 100644 ---- a/drivers/usb/typec/tcpm/tcpm.c -+++ b/drivers/usb/typec/tcpm/tcpm.c -@@ -1616,6 +1616,9 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev, - if (PD_VDO_VID(p[0]) != USB_SID_PD) - break; - -+ if (IS_ERR_OR_NULL(port->partner)) -+ break; -+ - if (PD_VDO_SVDM_VER(p[0]) < svdm_version) { - typec_partner_set_svdm_version(port->partner, - PD_VDO_SVDM_VER(p[0])); -diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c -index b3463d1371520..faaa64fa5dfe9 100644 ---- a/drivers/video/fbdev/aty/atyfb_base.c -+++ b/drivers/video/fbdev/aty/atyfb_base.c -@@ -3447,11 +3447,15 @@ static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, - } - - info->fix.mmio_start = raddr; -+#if defined(__i386__) || defined(__ia64__) - /* - * By using strong UC we force the MTRR to never have an - * effect on the MMIO region on both non-PAT and PAT systems. - */ - par->ati_regbase = ioremap_uc(info->fix.mmio_start, 0x1000); -+#else -+ par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000); -+#endif - if (par->ati_regbase == NULL) - return -ENOMEM; - -diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c -index 17cda57656838..5ea7c52baa5a8 100644 ---- a/drivers/video/fbdev/omap/omapfb_main.c -+++ b/drivers/video/fbdev/omap/omapfb_main.c -@@ -1643,13 +1643,13 @@ static int omapfb_do_probe(struct platform_device *pdev, - } - fbdev->int_irq = platform_get_irq(pdev, 0); - if (fbdev->int_irq < 0) { -- r = ENXIO; -+ r = -ENXIO; - goto cleanup; - } - - fbdev->ext_irq = platform_get_irq(pdev, 1); - if (fbdev->ext_irq < 0) { -- r = ENXIO; -+ r = -ENXIO; - goto cleanup; - } - -diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c -index 0e3cabbec4b40..a85463db9f986 100644 ---- a/drivers/video/fbdev/uvesafb.c -+++ b/drivers/video/fbdev/uvesafb.c -@@ -1935,10 +1935,10 @@ static void uvesafb_exit(void) - } - } - -- cn_del_callback(&uvesafb_cn_id); - driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d); - platform_device_unregister(uvesafb_device); - platform_driver_unregister(&uvesafb_driver); -+ cn_del_callback(&uvesafb_cn_id); - } - - module_exit(uvesafb_exit); -diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c -index f6a7fd47efd7a..82874be945248 100644 ---- a/fs/ceph/mds_client.c -+++ b/fs/ceph/mds_client.c -@@ -709,8 +709,8 @@ int ceph_wait_on_conflict_unlink(struct dentry *dentry) - if (!d_same_name(udentry, pdentry, &dname)) - goto next; - -+ found = dget_dlock(udentry); - spin_unlock(&udentry->d_lock); -- found = dget(udentry); - break; - next: - spin_unlock(&udentry->d_lock); -diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c -index 63169529b52c4..2215179c925b3 100644 ---- a/fs/ntfs3/attrib.c -+++ b/fs/ntfs3/attrib.c -@@ -1658,10 +1658,8 @@ repack: - le_b = NULL; - attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, - 0, NULL, &mi_b); -- if (!attr_b) { -- err = -ENOENT; -- goto out; -- } -+ if (!attr_b) -+ return -ENOENT; - - attr = attr_b; - le = le_b; -diff --git a/fs/ntfs3/attrlist.c b/fs/ntfs3/attrlist.c -index 81c22df27c725..0c6a68e71e7d4 100644 ---- a/fs/ntfs3/attrlist.c -+++ b/fs/ntfs3/attrlist.c -@@ -52,7 +52,8 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr) - - if (!attr->non_res) { - lsize = le32_to_cpu(attr->res.data_size); -- le = kmalloc(al_aligned(lsize), GFP_NOFS | __GFP_NOWARN); -+ /* attr is resident: lsize < record_size (1K or 4K) */ -+ le = kvmalloc(al_aligned(lsize), GFP_KERNEL); - if (!le) { - err = -ENOMEM; - goto out; -@@ -80,7 +81,17 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr) - if (err < 0) - goto out; - -- le = kmalloc(al_aligned(lsize), GFP_NOFS | __GFP_NOWARN); -+ /* attr is nonresident. -+ * The worst case: -+ * 1T (2^40) extremely fragmented file. -+ * cluster = 4K (2^12) => 2^28 fragments -+ * 2^9 fragments per one record => 2^19 records -+ * 2^5 bytes of ATTR_LIST_ENTRY per one record => 2^24 bytes. -+ * -+ * the result is 16M bytes per attribute list. -+ * Use kvmalloc to allocate in range [several Kbytes - dozen Mbytes] -+ */ -+ le = kvmalloc(al_aligned(lsize), GFP_KERNEL); - if (!le) { - err = -ENOMEM; - goto out; -diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c -index e0cdc91d88a85..c055bbdfe0f7c 100644 ---- a/fs/ntfs3/bitmap.c -+++ b/fs/ntfs3/bitmap.c -@@ -662,7 +662,8 @@ int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits) - wnd->bits_last = wbits; - - wnd->free_bits = -- kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS | __GFP_NOWARN); -+ kvmalloc_array(wnd->nwnd, sizeof(u16), GFP_KERNEL | __GFP_ZERO); -+ - if (!wnd->free_bits) - return -ENOMEM; - -diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c -index fb438d6040409..d4d9f4ffb6d9a 100644 ---- a/fs/ntfs3/dir.c -+++ b/fs/ntfs3/dir.c -@@ -309,7 +309,11 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, - return 0; - } - -- dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG; -+ /* NTFS: symlinks are "dir + reparse" or "file + reparse" */ -+ if (fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT) -+ dt_type = DT_LNK; -+ else -+ dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG; - - return !dir_emit(ctx, (s8 *)name, name_len, ino, dt_type); - } -diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c -index dda13e1f1b330..bb7e33c240737 100644 ---- a/fs/ntfs3/frecord.c -+++ b/fs/ntfs3/frecord.c -@@ -2149,7 +2149,7 @@ out1: - - for (i = 0; i < pages_per_frame; i++) { - pg = pages[i]; -- if (i == idx) -+ if (i == idx || !pg) - continue; - unlock_page(pg); - put_page(pg); -@@ -3198,6 +3198,12 @@ static bool ni_update_parent(struct ntfs_inode *ni, struct NTFS_DUP_INFO *dup, - if (!fname || !memcmp(&fname->dup, dup, sizeof(fname->dup))) - continue; - -+ /* Check simple case when parent inode equals current inode. */ -+ if (ino_get(&fname->home) == ni->vfs_inode.i_ino) { -+ ntfs_set_state(sbi, NTFS_DIRTY_ERROR); -+ continue; -+ } -+ - /* ntfs_iget5 may sleep. */ - dir = ntfs_iget5(sb, &fname->home, NULL); - if (IS_ERR(dir)) { -diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c -index 00faf41d8f97d..710cb5aa5a65b 100644 ---- a/fs/ntfs3/fslog.c -+++ b/fs/ntfs3/fslog.c -@@ -2169,8 +2169,10 @@ file_is_valid: - - if (!page) { - page = kmalloc(log->page_size, GFP_NOFS); -- if (!page) -- return -ENOMEM; -+ if (!page) { -+ err = -ENOMEM; -+ goto out; -+ } - } - - /* -diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c -index 9c0fc3a29d0c9..873b1434a9989 100644 ---- a/fs/ntfs3/fsntfs.c -+++ b/fs/ntfs3/fsntfs.c -@@ -953,18 +953,11 @@ out: - if (err) - return err; - -- mark_inode_dirty(&ni->vfs_inode); -+ mark_inode_dirty_sync(&ni->vfs_inode); - /* verify(!ntfs_update_mftmirr()); */ - -- /* -- * If we used wait=1, sync_inode_metadata waits for the io for the -- * inode to finish. It hangs when media is removed. -- * So wait=0 is sent down to sync_inode_metadata -- * and filemap_fdatawrite is used for the data blocks. -- */ -- err = sync_inode_metadata(&ni->vfs_inode, 0); -- if (!err) -- err = filemap_fdatawrite(ni->vfs_inode.i_mapping); -+ /* write mft record on disk. */ -+ err = _ni_write_inode(&ni->vfs_inode, 1); - - return err; - } -diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c -index 8e2fe0f69203b..6066eea3f61cb 100644 ---- a/fs/ntfs3/super.c -+++ b/fs/ntfs3/super.c -@@ -1141,7 +1141,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc) - goto put_inode_out; - } - bytes = inode->i_size; -- sbi->def_table = t = kmalloc(bytes, GFP_NOFS | __GFP_NOWARN); -+ sbi->def_table = t = kvmalloc(bytes, GFP_KERNEL); - if (!t) { - err = -ENOMEM; - goto put_inode_out; -diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h -index 2ae4fd62e01c4..17e7e3145a058 100644 ---- a/include/drm/gpu_scheduler.h -+++ b/include/drm/gpu_scheduler.h -@@ -55,8 +55,7 @@ enum drm_sched_priority { - DRM_SCHED_PRIORITY_HIGH, - DRM_SCHED_PRIORITY_KERNEL, - -- DRM_SCHED_PRIORITY_COUNT, -- DRM_SCHED_PRIORITY_UNSET = -2 -+ DRM_SCHED_PRIORITY_COUNT - }; - - /** -diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h -index 95f33dadb2be2..b76ff08506181 100644 ---- a/include/linux/pci_ids.h -+++ b/include/linux/pci_ids.h -@@ -568,6 +568,7 @@ - #define PCI_DEVICE_ID_AMD_19H_M60H_DF_F3 0x14e3 - #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F3 0x14f3 - #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F3 0x12fb -+#define PCI_DEVICE_ID_AMD_VANGOGH_USB 0x163a - #define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703 - #define PCI_DEVICE_ID_AMD_LANCE 0x2000 - #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 -diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h -index aa2c4a7c4826d..a10428884e6a5 100644 ---- a/include/linux/power_supply.h -+++ b/include/linux/power_supply.h -@@ -766,7 +766,7 @@ struct power_supply_battery_info { - int bti_resistance_tolerance; - }; - --extern struct atomic_notifier_head power_supply_notifier; -+extern struct blocking_notifier_head power_supply_notifier; - extern int power_supply_reg_notifier(struct notifier_block *nb); - extern void power_supply_unreg_notifier(struct notifier_block *nb); - #if IS_ENABLED(CONFIG_POWER_SUPPLY) -diff --git a/io_uring/rw.c b/io_uring/rw.c -index 0218fae12eddc..0133db648d8e9 100644 ---- a/io_uring/rw.c -+++ b/io_uring/rw.c -@@ -326,7 +326,7 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret, - struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); - unsigned final_ret = io_fixup_rw_res(req, ret); - -- if (req->flags & REQ_F_CUR_POS) -+ if (ret >= 0 && req->flags & REQ_F_CUR_POS) - req->file->f_pos = rw->kiocb.ki_pos; - if (ret >= 0 && (rw->kiocb.ki_complete == io_complete_rw)) { - if (!__io_complete_rw_common(req, ret)) { -diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index bfe2d1d50fbee..84e11c2caae42 100644 ---- a/mm/mempolicy.c -+++ b/mm/mempolicy.c -@@ -1525,8 +1525,10 @@ SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, le - /* - * Only update home node if there is an existing vma policy - */ -- if (!new) -+ if (!new) { -+ prev = vma; - continue; -+ } - - /* - * If any vma in the range got policy other than MPOL_BIND -diff --git a/mm/mmap.c b/mm/mmap.c -index 8ffe3f87f7ba9..c0f9575493deb 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -519,6 +519,7 @@ inline int vma_expand(struct ma_state *mas, struct vm_area_struct *vma, - struct anon_vma *anon_vma = vma->anon_vma; - struct file *file = vma->vm_file; - bool remove_next = false; -+ struct vm_area_struct *anon_dup = NULL; - - if (next && (vma != next) && (end == next->vm_end)) { - remove_next = true; -@@ -530,6 +531,8 @@ inline int vma_expand(struct ma_state *mas, struct vm_area_struct *vma, - error = anon_vma_clone(vma, next); - if (error) - return error; -+ -+ anon_dup = vma; - } - } - -@@ -602,6 +605,9 @@ inline int vma_expand(struct ma_state *mas, struct vm_area_struct *vma, - return 0; - - nomem: -+ if (anon_dup) -+ unlink_anon_vmas(anon_dup); -+ - return -ENOMEM; - } - -@@ -629,6 +635,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - int remove_next = 0; - MA_STATE(mas, &mm->mm_mt, 0, 0); - struct vm_area_struct *exporter = NULL, *importer = NULL; -+ struct vm_area_struct *anon_dup = NULL; - - if (next && !insert) { - if (end >= next->vm_end) { -@@ -709,11 +716,17 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - error = anon_vma_clone(importer, exporter); - if (error) - return error; -+ -+ anon_dup = importer; - } - } - -- if (mas_preallocate(&mas, vma, GFP_KERNEL)) -+ if (mas_preallocate(&mas, vma, GFP_KERNEL)) { -+ if (anon_dup) -+ unlink_anon_vmas(anon_dup); -+ - return -ENOMEM; -+ } - - vma_adjust_trans_huge(orig_vma, start, end, adjust_next); - if (file) { -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 5e3dbe2652dbd..5c783199b4999 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -7324,6 +7324,16 @@ nla_put_failure: - return -1; - } - -+static void audit_log_obj_reset(const struct nft_table *table, -+ unsigned int base_seq, unsigned int nentries) -+{ -+ char *buf = kasprintf(GFP_ATOMIC, "%s:%u", table->name, base_seq); -+ -+ audit_log_nfcfg(buf, table->family, nentries, -+ AUDIT_NFT_OP_OBJ_RESET, GFP_ATOMIC); -+ kfree(buf); -+} -+ - struct nft_obj_filter { - char *table; - u32 type; -@@ -7338,8 +7348,10 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) - struct net *net = sock_net(skb->sk); - int family = nfmsg->nfgen_family; - struct nftables_pernet *nft_net; -+ unsigned int entries = 0; - struct nft_object *obj; - bool reset = false; -+ int rc = 0; - - if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET) - reset = true; -@@ -7352,6 +7364,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) - if (family != NFPROTO_UNSPEC && family != table->family) - continue; - -+ entries = 0; - list_for_each_entry_rcu(obj, &table->objects, list) { - if (!nft_is_active(net, obj)) - goto cont; -@@ -7367,34 +7380,27 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) - filter->type != NFT_OBJECT_UNSPEC && - obj->ops->type->type != filter->type) - goto cont; -- if (reset) { -- char *buf = kasprintf(GFP_ATOMIC, -- "%s:%u", -- table->name, -- nft_net->base_seq); -- -- audit_log_nfcfg(buf, -- family, -- obj->handle, -- AUDIT_NFT_OP_OBJ_RESET, -- GFP_ATOMIC); -- kfree(buf); -- } - -- if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid, -- cb->nlh->nlmsg_seq, -- NFT_MSG_NEWOBJ, -- NLM_F_MULTI | NLM_F_APPEND, -- table->family, table, -- obj, reset) < 0) -- goto done; -+ rc = nf_tables_fill_obj_info(skb, net, -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NFT_MSG_NEWOBJ, -+ NLM_F_MULTI | NLM_F_APPEND, -+ table->family, table, -+ obj, reset); -+ if (rc < 0) -+ break; - -+ entries++; - nl_dump_check_consistent(cb, nlmsg_hdr(skb)); - cont: - idx++; - } -+ if (reset && entries) -+ audit_log_obj_reset(table, nft_net->base_seq, entries); -+ if (rc < 0) -+ break; - } --done: - rcu_read_unlock(); - - cb->args[0] = idx; -@@ -7499,7 +7505,7 @@ static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info, - - audit_log_nfcfg(buf, - family, -- obj->handle, -+ 1, - AUDIT_NFT_OP_OBJ_RESET, - GFP_ATOMIC); - kfree(buf); -diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c -index d97eb280cb2e8..c5ff699e30469 100644 ---- a/net/netfilter/nfnetlink_log.c -+++ b/net/netfilter/nfnetlink_log.c -@@ -690,8 +690,8 @@ nfulnl_log_packet(struct net *net, - unsigned int plen = 0; - struct nfnl_log_net *log = nfnl_log_pernet(net); - const struct nfnl_ct_hook *nfnl_ct = NULL; -+ enum ip_conntrack_info ctinfo = 0; - struct nf_conn *ct = NULL; -- enum ip_conntrack_info ctinfo; - - if (li_user && li_user->type == NF_LOG_TYPE_ULOG) - li = li_user; -diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c -index ba93e2a6bdbb4..04448bfb4d3db 100644 ---- a/net/sched/cls_u32.c -+++ b/net/sched/cls_u32.c -@@ -364,7 +364,7 @@ static int u32_init(struct tcf_proto *tp) - idr_init(&root_ht->handle_idr); - - if (tp_c == NULL) { -- tp_c = kzalloc(struct_size(tp_c, hlist->ht, 1), GFP_KERNEL); -+ tp_c = kzalloc(sizeof(*tp_c), GFP_KERNEL); - if (tp_c == NULL) { - kfree(root_ht); - return -ENOBUFS; -diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c -index 2873420c9aca8..bc03b5692983c 100644 ---- a/sound/hda/intel-dsp-config.c -+++ b/sound/hda/intel-dsp-config.c -@@ -343,6 +343,12 @@ static const struct config_entry config_table[] = { - DMI_MATCH(DMI_SYS_VENDOR, "Google"), - } - }, -+ { -+ .ident = "Google firmware", -+ .matches = { -+ DMI_MATCH(DMI_BIOS_VERSION, "Google"), -+ } -+ }, - {} - } - }, -diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c -index 620ecbfa4a7a8..f86fc7cd104d4 100644 ---- a/sound/soc/codecs/rt5645.c -+++ b/sound/soc/codecs/rt5645.c -@@ -3251,6 +3251,8 @@ int rt5645_set_jack_detect(struct snd_soc_component *component, - RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ); - regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL1, - RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL); -+ regmap_update_bits(rt5645->regmap, RT5645_DEPOP_M1, -+ RT5645_HP_CB_MASK, RT5645_HP_CB_PU); - } - rt5645_irq(0, rt5645); - -diff --git a/sound/soc/codecs/tas2780.c b/sound/soc/codecs/tas2780.c -index afdf0c863aa10..a2d27410bbefa 100644 ---- a/sound/soc/codecs/tas2780.c -+++ b/sound/soc/codecs/tas2780.c -@@ -39,7 +39,7 @@ static void tas2780_reset(struct tas2780_priv *tas2780) - usleep_range(2000, 2050); - } - -- snd_soc_component_write(tas2780->component, TAS2780_SW_RST, -+ ret = snd_soc_component_write(tas2780->component, TAS2780_SW_RST, - TAS2780_RST); - if (ret) - dev_err(tas2780->dev, "%s:errCode:0x%x Reset error!\n", -diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c -index 52bb557247244..6bd6da01aafac 100644 ---- a/sound/soc/codecs/tlv320adc3xxx.c -+++ b/sound/soc/codecs/tlv320adc3xxx.c -@@ -293,7 +293,7 @@ - #define ADC3XXX_BYPASS_RPGA 0x80 - - /* MICBIAS control bits */ --#define ADC3XXX_MICBIAS_MASK 0x2 -+#define ADC3XXX_MICBIAS_MASK 0x3 - #define ADC3XXX_MICBIAS1_SHIFT 5 - #define ADC3XXX_MICBIAS2_SHIFT 3 - -@@ -1099,7 +1099,7 @@ static int adc3xxx_parse_dt_micbias(struct adc3xxx *adc3xxx, - unsigned int val; - - if (!of_property_read_u32(np, propname, &val)) { -- if (val >= ADC3XXX_MICBIAS_AVDD) { -+ if (val > ADC3XXX_MICBIAS_AVDD) { - dev_err(dev, "Invalid property value for '%s'\n", propname); - return -EINVAL; - } -diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c -index fbb682747f598..a8bc4e45816df 100644 ---- a/sound/soc/generic/simple-card.c -+++ b/sound/soc/generic/simple-card.c -@@ -678,10 +678,12 @@ static int asoc_simple_probe(struct platform_device *pdev) - struct snd_soc_dai_link *dai_link = priv->dai_link; - struct simple_dai_props *dai_props = priv->dai_props; - -+ ret = -EINVAL; -+ - cinfo = dev->platform_data; - if (!cinfo) { - dev_err(dev, "no info for asoc-simple-card\n"); -- return -EINVAL; -+ goto err; - } - - if (!cinfo->name || -@@ -690,7 +692,7 @@ static int asoc_simple_probe(struct platform_device *pdev) - !cinfo->platform || - !cinfo->cpu_dai.name) { - dev_err(dev, "insufficient asoc_simple_card_info settings\n"); -- return -EINVAL; -+ goto err; - } - - cpus = dai_link->cpus; -diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c -index 643fd1036d60b..05fb4e20e8a40 100644 ---- a/sound/soc/sof/sof-pci-dev.c -+++ b/sound/soc/sof/sof-pci-dev.c -@@ -141,6 +141,13 @@ static const struct dmi_system_id community_key_platforms[] = { - DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"), - } - }, -+ { -+ .ident = "Google firmware", -+ .callback = chromebook_use_community_key, -+ .matches = { -+ DMI_MATCH(DMI_BIOS_VERSION, "Google"), -+ } -+ }, - {}, - }; - -diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c -index 6129a62316422..f458328f9ec42 100644 ---- a/sound/usb/quirks.c -+++ b/sound/usb/quirks.c -@@ -2218,6 +2218,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { - QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x2ab6, /* T+A devices */ - QUIRK_FLAG_DSD_RAW), -+ VENDOR_FLG(0x2afd, /* McIntosh Laboratory, Inc. */ -+ QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x2d87, /* Cayin device */ - QUIRK_FLAG_DSD_RAW), - VENDOR_FLG(0x3336, /* HEM devices */ -diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c -index 6612b00949e70..ca08e6dc8b232 100644 ---- a/tools/perf/util/evlist.c -+++ b/tools/perf/util/evlist.c -@@ -252,6 +252,9 @@ static struct evsel *evlist__dummy_event(struct evlist *evlist) - .type = PERF_TYPE_SOFTWARE, - .config = PERF_COUNT_SW_DUMMY, - .size = sizeof(attr), /* to capture ABI version */ -+ /* Avoid frequency mode for dummy events to avoid associated timers. */ -+ .freq = 0, -+ .sample_period = 1, - }; - - return evsel__new_idx(&attr, evlist->core.nr_entries); -@@ -278,8 +281,6 @@ struct evsel *evlist__add_aux_dummy(struct evlist *evlist, bool system_wide) - evsel->core.attr.exclude_kernel = 1; - evsel->core.attr.exclude_guest = 1; - evsel->core.attr.exclude_hv = 1; -- evsel->core.attr.freq = 0; -- evsel->core.attr.sample_period = 1; - evsel->core.system_wide = system_wide; - evsel->no_aux_samples = true; - evsel->name = strdup("dummy:u"); -diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh -index 5267c88496d51..99ed5bd6e8402 100755 ---- a/tools/testing/selftests/netfilter/nft_audit.sh -+++ b/tools/testing/selftests/netfilter/nft_audit.sh -@@ -99,6 +99,12 @@ do_test 'nft add counter t1 c1' \ - do_test 'nft add counter t2 c1; add counter t2 c2' \ - 'table=t2 family=2 entries=2 op=nft_register_obj' - -+for ((i = 3; i <= 500; i++)); do -+ echo "add counter t2 c$i" -+done >$rulefile -+do_test "nft -f $rulefile" \ -+'table=t2 family=2 entries=498 op=nft_register_obj' -+ - # adding/updating quotas - - do_test 'nft add quota t1 q1 { 10 bytes }' \ -@@ -107,6 +113,12 @@ do_test 'nft add quota t1 q1 { 10 bytes }' \ - do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \ - 'table=t2 family=2 entries=2 op=nft_register_obj' - -+for ((i = 3; i <= 500; i++)); do -+ echo "add quota t2 q$i { 10 bytes }" -+done >$rulefile -+do_test "nft -f $rulefile" \ -+'table=t2 family=2 entries=498 op=nft_register_obj' -+ - # changing the quota value triggers obj update path - do_test 'nft add quota t1 q1 { 20 bytes }' \ - 'table=t1 family=2 entries=1 op=nft_register_obj' -@@ -156,6 +168,40 @@ done - do_test 'nft reset set t1 s' \ - 'table=t1 family=2 entries=3 op=nft_reset_setelem' - -+# resetting counters -+ -+do_test 'nft reset counter t1 c1' \ -+'table=t1 family=2 entries=1 op=nft_reset_obj' -+ -+do_test 'nft reset counters t1' \ -+'table=t1 family=2 entries=1 op=nft_reset_obj' -+ -+do_test 'nft reset counters t2' \ -+'table=t2 family=2 entries=342 op=nft_reset_obj -+table=t2 family=2 entries=158 op=nft_reset_obj' -+ -+do_test 'nft reset counters' \ -+'table=t1 family=2 entries=1 op=nft_reset_obj -+table=t2 family=2 entries=341 op=nft_reset_obj -+table=t2 family=2 entries=159 op=nft_reset_obj' -+ -+# resetting quotas -+ -+do_test 'nft reset quota t1 q1' \ -+'table=t1 family=2 entries=1 op=nft_reset_obj' -+ -+do_test 'nft reset quotas t1' \ -+'table=t1 family=2 entries=1 op=nft_reset_obj' -+ -+do_test 'nft reset quotas t2' \ -+'table=t2 family=2 entries=315 op=nft_reset_obj -+table=t2 family=2 entries=185 op=nft_reset_obj' -+ -+do_test 'nft reset quotas' \ -+'table=t1 family=2 entries=1 op=nft_reset_obj -+table=t2 family=2 entries=314 op=nft_reset_obj -+table=t2 family=2 entries=186 op=nft_reset_obj' -+ - # deleting rules - - readarray -t handles < <(nft -a list chain t1 c1 | \ diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.62-63.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.62-63.patch deleted file mode 100644 index 00337f2fea0d..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.62-63.patch +++ /dev/null @@ -1,22957 +0,0 @@ -diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt -index 0088442efca1a..8f9784af92d6e 100644 ---- a/Documentation/devicetree/bindings/mfd/mt6397.txt -+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt -@@ -21,8 +21,10 @@ Required properties: - compatible: - "mediatek,mt6323" for PMIC MT6323 - "mediatek,mt6331" for PMIC MT6331 and MT6332 -- "mediatek,mt6358" for PMIC MT6358 and MT6366 -+ "mediatek,mt6357" for PMIC MT6357 -+ "mediatek,mt6358" for PMIC MT6358 - "mediatek,mt6359" for PMIC MT6359 -+ "mediatek,mt6366", "mediatek,mt6358" for PMIC MT6366 - "mediatek,mt6397" for PMIC MT6397 - - Optional subnodes: -@@ -39,6 +41,7 @@ Optional subnodes: - - compatible: "mediatek,mt6323-regulator" - see ../regulator/mt6323-regulator.txt - - compatible: "mediatek,mt6358-regulator" -+ - compatible: "mediatek,mt6366-regulator", "mediatek-mt6358-regulator" - see ../regulator/mt6358-regulator.txt - - compatible: "mediatek,mt6397-regulator" - see ../regulator/mt6397-regulator.txt -diff --git a/Documentation/virt/coco/sev-guest.rst b/Documentation/virt/coco/sev-guest.rst -index bf593e88cfd9d..68b0d2363af82 100644 ---- a/Documentation/virt/coco/sev-guest.rst -+++ b/Documentation/virt/coco/sev-guest.rst -@@ -37,11 +37,11 @@ along with a description: - the return value. General error numbers (-ENOMEM, -EINVAL) - are not detailed, but errors with specific meanings are. - --The guest ioctl should be issued on a file descriptor of the /dev/sev-guest device. --The ioctl accepts struct snp_user_guest_request. The input and output structure is --specified through the req_data and resp_data field respectively. If the ioctl fails --to execute due to a firmware error, then fw_err code will be set otherwise the --fw_err will be set to 0x00000000000000ff. -+The guest ioctl should be issued on a file descriptor of the /dev/sev-guest -+device. The ioctl accepts struct snp_user_guest_request. The input and -+output structure is specified through the req_data and resp_data field -+respectively. If the ioctl fails to execute due to a firmware error, then -+the fw_error code will be set, otherwise fw_error will be set to -1. - - The firmware checks that the message sequence counter is one greater than - the guests message sequence counter. If guest driver fails to increment message -@@ -57,8 +57,14 @@ counter (e.g. counter overflow), then -EIO will be returned. - __u64 req_data; - __u64 resp_data; - -- /* firmware error code on failure (see psp-sev.h) */ -- __u64 fw_err; -+ /* bits[63:32]: VMM error code, bits[31:0] firmware error code (see psp-sev.h) */ -+ union { -+ __u64 exitinfo2; -+ struct { -+ __u32 fw_error; -+ __u32 vmm_error; -+ }; -+ }; - }; - - 2.1 SNP_GET_REPORT -diff --git a/Makefile b/Makefile -index 2e7bc3cc1c177..7c69293b7e059 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 62 -+SUBLEVEL = 63 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/am3517-evm.dts b/arch/arm/boot/dts/am3517-evm.dts -index 7bab0a9dadb30..95508b7fa3bf6 100644 ---- a/arch/arm/boot/dts/am3517-evm.dts -+++ b/arch/arm/boot/dts/am3517-evm.dts -@@ -271,13 +271,6 @@ - >; - }; - -- leds_pins: pinmux_leds_pins { -- pinctrl-single,pins = < -- OMAP3_WKUP_IOPAD(0x2a24, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu0.gpio_11 */ -- OMAP3_WKUP_IOPAD(0x2a26, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu1.gpio_31 */ -- >; -- }; -- - mmc1_pins: pinmux_mmc1_pins { - pinctrl-single,pins = < - OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ -@@ -355,3 +348,12 @@ - >; - }; - }; -+ -+&omap3_pmx_wkup { -+ leds_pins: pinmux_leds_pins { -+ pinctrl-single,pins = < -+ OMAP3_WKUP_IOPAD(0x2a24, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu0.gpio_11 */ -+ OMAP3_WKUP_IOPAD(0x2a26, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu1.gpio_31 */ -+ >; -+ }; -+}; -diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi -index b47c86412de2c..17a1a06dfb3f1 100644 ---- a/arch/arm/boot/dts/qcom-mdm9615.dtsi -+++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi -@@ -82,14 +82,12 @@ - }; - }; - -- regulators { -- vsdcc_fixed: vsdcc-regulator { -- compatible = "regulator-fixed"; -- regulator-name = "SDCC Power"; -- regulator-min-microvolt = <2700000>; -- regulator-max-microvolt = <2700000>; -- regulator-always-on; -- }; -+ vsdcc_fixed: vsdcc-regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "SDCC Power"; -+ regulator-min-microvolt = <2700000>; -+ regulator-max-microvolt = <2700000>; -+ regulator-always-on; - }; - - soc: soc { -diff --git a/arch/arm/boot/dts/r8a7792-blanche.dts b/arch/arm/boot/dts/r8a7792-blanche.dts -index c66de9dd12dfc..6a83923aa4612 100644 ---- a/arch/arm/boot/dts/r8a7792-blanche.dts -+++ b/arch/arm/boot/dts/r8a7792-blanche.dts -@@ -239,7 +239,7 @@ - }; - - keyboard_pins: keyboard { -- pins = "GP_3_10", "GP_3_11", "GP_3_12", "GP_3_15", "GP_11_02"; -+ pins = "GP_3_10", "GP_3_11", "GP_3_12", "GP_3_15", "GP_11_2"; - bias-pull-up; - }; - -diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S -index d71ab61430b26..de75ae4d5ab41 100644 ---- a/arch/arm/lib/memset.S -+++ b/arch/arm/lib/memset.S -@@ -17,6 +17,7 @@ ENTRY(__memset) - ENTRY(mmioset) - WEAK(memset) - UNWIND( .fnstart ) -+ and r1, r1, #255 @ cast to unsigned char - ands r3, r0, #3 @ 1 unaligned? - mov ip, r0 @ preserve r0 as return value - bne 6f @ 1 -diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c -index 93c8ccbf29828..b647306eb1608 100644 ---- a/arch/arm/xen/enlighten.c -+++ b/arch/arm/xen/enlighten.c -@@ -164,9 +164,6 @@ static int xen_starting_cpu(unsigned int cpu) - BUG_ON(err); - per_cpu(xen_vcpu, cpu) = vcpup; - -- if (!xen_kernel_unmapped_at_usr()) -- xen_setup_runstate_info(cpu); -- - after_register_vcpu_info: - enable_percpu_irq(xen_events_irq, 0); - return 0; -@@ -523,9 +520,6 @@ static int __init xen_guest_init(void) - return -EINVAL; - } - -- if (!xen_kernel_unmapped_at_usr()) -- xen_time_setup_guest(); -- - if (xen_initial_domain()) - pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier); - -@@ -535,7 +529,13 @@ static int __init xen_guest_init(void) - } - early_initcall(xen_guest_init); - --static int __init xen_pm_init(void) -+static int xen_starting_runstate_cpu(unsigned int cpu) -+{ -+ xen_setup_runstate_info(cpu); -+ return 0; -+} -+ -+static int __init xen_late_init(void) - { - if (!xen_domain()) - return -ENODEV; -@@ -548,9 +548,16 @@ static int __init xen_pm_init(void) - do_settimeofday64(&ts); - } - -- return 0; -+ if (xen_kernel_unmapped_at_usr()) -+ return 0; -+ -+ xen_time_setup_guest(); -+ -+ return cpuhp_setup_state(CPUHP_AP_ARM_XEN_RUNSTATE_STARTING, -+ "arm/xen_runstate:starting", -+ xen_starting_runstate_cpu, NULL); - } --late_initcall(xen_pm_init); -+late_initcall(xen_late_init); - - - /* empty stubs */ -diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi -index 12c82bb1bb7aa..d583db18f74cc 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi -@@ -398,6 +398,7 @@ - "pll8k", "pll11k", "clkext3"; - dmas = <&sdma2 24 25 0x80000000>; - dma-names = "rx"; -+ #sound-dai-cells = <0>; - status = "disabled"; - }; - -diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi -index 37246ca9d9075..66fadbf19f0a3 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi -@@ -370,6 +370,7 @@ - "pll8k", "pll11k", "clkext3"; - dmas = <&sdma2 24 25 0x80000000>; - dma-names = "rx"; -+ #sound-dai-cells = <0>; - status = "disabled"; - }; - -diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi -index 7764b4146e0ab..2bbdacb1313f9 100644 ---- a/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi -@@ -8,5 +8,5 @@ - }; - - &jpegenc { -- compatible = "nxp,imx8qm-jpgdec", "nxp,imx8qxp-jpgenc"; -+ compatible = "nxp,imx8qm-jpgenc", "nxp,imx8qxp-jpgenc"; - }; -diff --git a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi -index 8e4ec243fb8fc..e5fc6cca50e74 100644 ---- a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi -+++ b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi -@@ -120,7 +120,7 @@ - "mpp59", "mpp60", "mpp61"; - marvell,function = "sdio"; - }; -- cp0_spi0_pins: cp0-spi-pins-0 { -+ cp0_spi1_pins: cp0-spi-pins-1 { - marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16"; - marvell,function = "spi1"; - }; -@@ -170,7 +170,7 @@ - - &cp0_spi1 { - pinctrl-names = "default"; -- pinctrl-0 = <&cp0_spi0_pins>; -+ pinctrl-0 = <&cp0_spi1_pins>; - reg = <0x700680 0x50>, /* control */ - <0x2000000 0x1000000>; /* CS0 */ - status = "okay"; -diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi -index c7de1ea0d470a..6eb6a175de38d 100644 ---- a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi -+++ b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi -@@ -307,7 +307,7 @@ - &cp0_spi1 { - status = "disabled"; - pinctrl-names = "default"; -- pinctrl-0 = <&cp0_spi0_pins>; -+ pinctrl-0 = <&cp0_spi1_pins>; - reg = <0x700680 0x50>; - - flash@0 { -@@ -371,7 +371,7 @@ - "mpp59", "mpp60", "mpp61"; - marvell,function = "sdio"; - }; -- cp0_spi0_pins: cp0-spi-pins-0 { -+ cp0_spi1_pins: cp0-spi-pins-1 { - marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16"; - marvell,function = "spi1"; - }; -diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi -index dfe2cf2f4b218..6598e9ac52b81 100644 ---- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi -+++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi -@@ -532,12 +532,12 @@ - , - , - , -- , -- , -- , -- , -- , -- ; -+ , -+ , -+ , -+ , -+ , -+ ; - status = "okay"; - }; - -diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -index 9650ae70c8723..9d116e1fbe10c 100644 ---- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts -@@ -200,6 +200,9 @@ - pd-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>; - - avdd-supply = <&pm8916_l6>; -+ a2vdd-supply = <&pm8916_l6>; -+ dvdd-supply = <&pm8916_l6>; -+ pvdd-supply = <&pm8916_l6>; - v1p2-supply = <&pm8916_l6>; - v3p3-supply = <&pm8916_l17>; - -diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi -index f84b3c1a03c53..bafac2cf7e3d6 100644 ---- a/arch/arm64/boot/dts/qcom/msm8916.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi -@@ -1257,7 +1257,7 @@ - #size-cells = <1>; - #iommu-cells = <1>; - compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; -- ranges = <0 0x01e20000 0x40000>; -+ ranges = <0 0x01e20000 0x20000>; - reg = <0x01ef0000 0x3000>; - clocks = <&gcc GCC_SMMU_CFG_CLK>, - <&gcc GCC_APSS_TCU_CLK>; -diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts -index 3ab0ad14e8704..95eab1f379229 100644 ---- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts -+++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts -@@ -109,11 +109,6 @@ - qcom,client-id = <1>; - }; - -- audio_mem: audio@cb400000 { -- reg = <0 0xcb000000 0 0x400000>; -- no-mem; -- }; -- - qseecom_mem: qseecom@cb400000 { - reg = <0 0xcb400000 0 0x1c00000>; - no-mem; -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index 0cdc579f26de7..aea356c63b9a3 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -820,7 +820,8 @@ - clocks = <&rpmhcc RPMH_CXO_CLK>, - <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, - <0>, <&pcie1_lane>, -- <0>, <0>, <0>, <0>; -+ <0>, <0>, <0>, -+ <&usb_1_ssphy>; - clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", - "pcie_0_pipe_clk", "pcie_1_pipe_clk", - "ufs_phy_rx_symbol_0_clk", "ufs_phy_rx_symbol_1_clk", -@@ -5337,6 +5338,14 @@ - reg = <0 0x18591000 0 0x1000>, - <0 0x18592000 0 0x1000>, - <0 0x18593000 0 0x1000>; -+ -+ interrupts = , -+ , -+ ; -+ interrupt-names = "dcvsh-irq-0", -+ "dcvsh-irq-1", -+ "dcvsh-irq-2"; -+ - clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; - clock-names = "xo", "alternate"; - #freq-domain-cells = <1>; -diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi -index b5f11fbcc3004..a5c0c788969fb 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi -@@ -145,6 +145,10 @@ - }; - }; - -+&cpufreq_hw { -+ /delete-property/ interrupts-extended; /* reference to lmh_cluster[01] */ -+}; -+ - &psci { - /delete-node/ cpu0; - /delete-node/ cpu1; -@@ -277,6 +281,14 @@ - &CLUSTER_SLEEP_0>; - }; - -+&lmh_cluster0 { -+ status = "disabled"; -+}; -+ -+&lmh_cluster1 { -+ status = "disabled"; -+}; -+ - /* - * Reserved memory changes - * -diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts -index de2d10e0315af..64958dee17d8b 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts -@@ -714,6 +714,8 @@ - vdd-1.8-xo-supply = <&vreg_l7a_1p8>; - vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; - vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; -+ -+ qcom,snoc-host-cap-8bit-quirk; - }; - - /* PINCTRL - additions to nodes defined in sdm845.dtsi */ -diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi -index de794a5078dfc..c586378fc6bc7 100644 ---- a/arch/arm64/boot/dts/qcom/sm8150.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi -@@ -1839,8 +1839,12 @@ - ranges; - clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, - <&gcc GCC_PCIE_0_CFG_AHB_CLK>, -+ <&gcc GCC_PCIE_0_CLKREF_CLK>, - <&gcc GCC_PCIE0_PHY_REFGEN_CLK>; -- clock-names = "aux", "cfg_ahb", "refgen"; -+ clock-names = "aux", -+ "cfg_ahb", -+ "ref", -+ "refgen"; - - resets = <&gcc GCC_PCIE_0_PHY_BCR>; - reset-names = "phy"; -@@ -1938,8 +1942,12 @@ - ranges; - clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, - <&gcc GCC_PCIE_1_CFG_AHB_CLK>, -+ <&gcc GCC_PCIE_1_CLKREF_CLK>, - <&gcc GCC_PCIE1_PHY_REFGEN_CLK>; -- clock-names = "aux", "cfg_ahb", "refgen"; -+ clock-names = "aux", -+ "cfg_ahb", -+ "ref", -+ "refgen"; - - resets = <&gcc GCC_PCIE_1_PHY_BCR>; - reset-names = "phy"; -diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi -index b3245b13b2611..793768a2c9e1e 100644 ---- a/arch/arm64/boot/dts/qcom/sm8350.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi -@@ -1778,7 +1778,7 @@ - }; - - qup_uart18_default: qup-uart18-default-state { -- pins = "gpio58", "gpio59"; -+ pins = "gpio68", "gpio69"; - function = "qup18"; - drive-strength = <2>; - bias-disable; -diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts -index b08a083d722d4..7f265c671654d 100644 ---- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts -+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts -@@ -172,7 +172,7 @@ - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&main_i2c1_pins_default>; -- clock-frequency = <400000>; -+ clock-frequency = <100000>; - - exp1: gpio@22 { - compatible = "ti,tca6424"; -diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h -index 357932938b5ab..7dce9c0aa7836 100644 ---- a/arch/arm64/include/asm/cputype.h -+++ b/arch/arm64/include/asm/cputype.h -@@ -85,7 +85,8 @@ - #define ARM_CPU_PART_NEOVERSE_N2 0xD49 - #define ARM_CPU_PART_CORTEX_A78C 0xD4B - --#define APM_CPU_PART_POTENZA 0x000 -+#define APM_CPU_PART_XGENE 0x000 -+#define APM_CPU_VAR_POTENZA 0x00 - - #define CAVIUM_CPU_PART_THUNDERX 0x0A1 - #define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2 -diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c -index dd20b8688d230..f44ae09a51956 100644 ---- a/arch/arm64/kvm/guest.c -+++ b/arch/arm64/kvm/guest.c -@@ -863,7 +863,7 @@ u32 __attribute_const__ kvm_target_cpu(void) - break; - case ARM_CPU_IMP_APM: - switch (part_number) { -- case APM_CPU_PART_POTENZA: -+ case APM_CPU_PART_XGENE: - return KVM_ARM_TARGET_XGENE_POTENZA; - } - break; -diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h b/arch/powerpc/include/asm/nohash/32/pte-40x.h -index 2d3153cfc0d79..acf61242e85bf 100644 ---- a/arch/powerpc/include/asm/nohash/32/pte-40x.h -+++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h -@@ -69,9 +69,6 @@ - - #define _PTE_NONE_MASK 0 - --/* Until my rework is finished, 40x still needs atomic PTE updates */ --#define PTE_ATOMIC_UPDATES 1 -- - #define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED) - #define _PAGE_BASE (_PAGE_BASE_NC) - -diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c -index 9bdd79aa51cfc..3956f32682c62 100644 ---- a/arch/powerpc/kernel/traps.c -+++ b/arch/powerpc/kernel/traps.c -@@ -1164,6 +1164,7 @@ static void emulate_single_step(struct pt_regs *regs) - __single_step_exception(regs); - } - -+#ifdef CONFIG_PPC_FPU_REGS - static inline int __parse_fpscr(unsigned long fpscr) - { - int ret = FPE_FLTUNK; -@@ -1190,6 +1191,7 @@ static inline int __parse_fpscr(unsigned long fpscr) - - return ret; - } -+#endif - - static void parse_fpe(struct pt_regs *regs) - { -diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c -index 9d229ef7f86ef..ada817c49b722 100644 ---- a/arch/powerpc/perf/imc-pmu.c -+++ b/arch/powerpc/perf/imc-pmu.c -@@ -51,7 +51,7 @@ static int trace_imc_mem_size; - * core and trace-imc - */ - static struct imc_pmu_ref imc_global_refc = { -- .lock = __SPIN_LOCK_INITIALIZER(imc_global_refc.lock), -+ .lock = __SPIN_LOCK_UNLOCKED(imc_global_refc.lock), - .id = 0, - .refc = 0, - }; -diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c -index 40f5ae5e1238d..92e60cb3163fa 100644 ---- a/arch/powerpc/platforms/book3s/vas-api.c -+++ b/arch/powerpc/platforms/book3s/vas-api.c -@@ -4,6 +4,8 @@ - * Copyright (C) 2019 Haren Myneni, IBM Corp - */ - -+#define pr_fmt(fmt) "vas-api: " fmt -+ - #include - #include - #include -@@ -78,7 +80,7 @@ int get_vas_user_win_ref(struct vas_user_win_ref *task_ref) - task_ref->mm = get_task_mm(current); - if (!task_ref->mm) { - put_pid(task_ref->pid); -- pr_err("VAS: pid(%d): mm_struct is not found\n", -+ pr_err("pid(%d): mm_struct is not found\n", - current->pid); - return -EPERM; - } -@@ -235,8 +237,7 @@ void vas_update_csb(struct coprocessor_request_block *crb, - rc = kill_pid_info(SIGSEGV, &info, pid); - rcu_read_unlock(); - -- pr_devel("%s(): pid %d kill_proc_info() rc %d\n", __func__, -- pid_vnr(pid), rc); -+ pr_devel("pid %d kill_proc_info() rc %d\n", pid_vnr(pid), rc); - } - - void vas_dump_crb(struct coprocessor_request_block *crb) -@@ -294,7 +295,7 @@ static int coproc_ioc_tx_win_open(struct file *fp, unsigned long arg) - - rc = copy_from_user(&uattr, uptr, sizeof(uattr)); - if (rc) { -- pr_err("%s(): copy_from_user() returns %d\n", __func__, rc); -+ pr_err("copy_from_user() returns %d\n", rc); - return -EFAULT; - } - -@@ -311,7 +312,7 @@ static int coproc_ioc_tx_win_open(struct file *fp, unsigned long arg) - txwin = cp_inst->coproc->vops->open_win(uattr.vas_id, uattr.flags, - cp_inst->coproc->cop_type); - if (IS_ERR(txwin)) { -- pr_err("%s() VAS window open failed, %ld\n", __func__, -+ pr_err_ratelimited("VAS window open failed rc=%ld\n", - PTR_ERR(txwin)); - return PTR_ERR(txwin); - } -@@ -405,8 +406,7 @@ static vm_fault_t vas_mmap_fault(struct vm_fault *vmf) - * window is not opened. Shouldn't expect this error. - */ - if (!cp_inst || !cp_inst->txwin) { -- pr_err("%s(): Unexpected fault on paste address with TX window closed\n", -- __func__); -+ pr_err("Unexpected fault on paste address with TX window closed\n"); - return VM_FAULT_SIGBUS; - } - -@@ -421,8 +421,7 @@ static vm_fault_t vas_mmap_fault(struct vm_fault *vmf) - * issue NX request. - */ - if (txwin->task_ref.vma != vmf->vma) { -- pr_err("%s(): No previous mapping with paste address\n", -- __func__); -+ pr_err("No previous mapping with paste address\n"); - return VM_FAULT_SIGBUS; - } - -@@ -481,19 +480,19 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) - txwin = cp_inst->txwin; - - if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) { -- pr_debug("%s(): size 0x%zx, PAGE_SIZE 0x%zx\n", __func__, -+ pr_debug("size 0x%zx, PAGE_SIZE 0x%zx\n", - (vma->vm_end - vma->vm_start), PAGE_SIZE); - return -EINVAL; - } - - /* Ensure instance has an open send window */ - if (!txwin) { -- pr_err("%s(): No send window open?\n", __func__); -+ pr_err("No send window open?\n"); - return -EINVAL; - } - - if (!cp_inst->coproc->vops || !cp_inst->coproc->vops->paste_addr) { -- pr_err("%s(): VAS API is not registered\n", __func__); -+ pr_err("VAS API is not registered\n"); - return -EACCES; - } - -@@ -510,14 +509,14 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) - */ - mutex_lock(&txwin->task_ref.mmap_mutex); - if (txwin->status != VAS_WIN_ACTIVE) { -- pr_err("%s(): Window is not active\n", __func__); -+ pr_err("Window is not active\n"); - rc = -EACCES; - goto out; - } - - paste_addr = cp_inst->coproc->vops->paste_addr(txwin); - if (!paste_addr) { -- pr_err("%s(): Window paste address failed\n", __func__); -+ pr_err("Window paste address failed\n"); - rc = -EINVAL; - goto out; - } -@@ -533,8 +532,8 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma) - rc = remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, - vma->vm_end - vma->vm_start, prot); - -- pr_devel("%s(): paste addr %llx at %lx, rc %d\n", __func__, -- paste_addr, vma->vm_start, rc); -+ pr_devel("paste addr %llx at %lx, rc %d\n", paste_addr, -+ vma->vm_start, rc); - - txwin->task_ref.vma = vma; - vma->vm_ops = &vas_vm_ops; -@@ -609,8 +608,7 @@ int vas_register_coproc_api(struct module *mod, enum vas_cop_type cop_type, - goto err; - } - -- pr_devel("%s: Added dev [%d,%d]\n", __func__, MAJOR(devno), -- MINOR(devno)); -+ pr_devel("Added dev [%d,%d]\n", MAJOR(devno), MINOR(devno)); - - return 0; - -diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c -index 2c2812a87d470..541199c6a587d 100644 ---- a/arch/powerpc/platforms/pseries/lpar.c -+++ b/arch/powerpc/platforms/pseries/lpar.c -@@ -524,8 +524,10 @@ static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p, - - if (cmd) { - rc = init_cpu_associativity(); -- if (rc) -+ if (rc) { -+ destroy_cpu_associativity(); - goto out; -+ } - - for_each_possible_cpu(cpu) { - disp = per_cpu_ptr(&vcpu_disp_data, cpu); -diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c -index 041a25c08066b..5db8060776b0c 100644 ---- a/arch/powerpc/platforms/pseries/vas.c -+++ b/arch/powerpc/platforms/pseries/vas.c -@@ -340,7 +340,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, - - if (atomic_inc_return(&cop_feat_caps->nr_used_credits) > - atomic_read(&cop_feat_caps->nr_total_credits)) { -- pr_err("Credits are not available to allocate window\n"); -+ pr_err_ratelimited("Credits are not available to allocate window\n"); - rc = -EINVAL; - goto out; - } -@@ -423,7 +423,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, - - put_vas_user_win_ref(&txwin->vas_win.task_ref); - rc = -EBUSY; -- pr_err("No credit is available to allocate window\n"); -+ pr_err_ratelimited("No credit is available to allocate window\n"); - - out_free: - /* -diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c -index 3925825954bcc..e5baa91ddd07b 100644 ---- a/arch/powerpc/sysdev/xive/native.c -+++ b/arch/powerpc/sysdev/xive/native.c -@@ -804,7 +804,7 @@ int xive_native_get_queue_info(u32 vp_id, u32 prio, - if (out_qpage) - *out_qpage = be64_to_cpu(qpage); - if (out_qsize) -- *out_qsize = be32_to_cpu(qsize); -+ *out_qsize = be64_to_cpu(qsize); - if (out_qeoi_page) - *out_qeoi_page = be64_to_cpu(qeoi_page); - if (out_escalate_irq) -diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c -index 852ecccd8920f..0f76181dc634d 100644 ---- a/arch/riscv/kernel/cpu.c -+++ b/arch/riscv/kernel/cpu.c -@@ -57,13 +57,14 @@ int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart) - */ - int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid) - { -- int rc; -- - for (; node; node = node->parent) { - if (of_device_is_compatible(node, "riscv")) { -- rc = riscv_of_processor_hartid(node, hartid); -- if (!rc) -- return 0; -+ *hartid = (unsigned long)of_get_cpu_hwid(node, 0); -+ if (*hartid == ~0UL) { -+ pr_warn("Found CPU without hart ID\n"); -+ return -ENODEV; -+ } -+ return 0; - } - } - -diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug -index c449e7c1b20ff..8bcd6c1431a95 100644 ---- a/arch/sh/Kconfig.debug -+++ b/arch/sh/Kconfig.debug -@@ -22,6 +22,17 @@ config STACK_DEBUG - every function call and will therefore incur a major - performance hit. Most users should say N. - -+config EARLY_PRINTK -+ bool "Early printk" -+ depends on SH_STANDARD_BIOS -+ help -+ Say Y here to redirect kernel printk messages to the serial port -+ used by the SH-IPL bootloader, starting very early in the boot -+ process and ending when the kernel's serial console is initialised. -+ This option is only useful while porting the kernel to a new machine, -+ when the kernel may crash or hang before the serial console is -+ initialised. If unsure, say N. -+ - config 4KSTACKS - bool "Use 4Kb for kernel stacks instead of 8Kb" - depends on DEBUG_KERNEL && (MMU || BROKEN) && !PAGE_SIZE_64KB -diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h -index b63be696b776a..0759af9b1acfc 100644 ---- a/arch/x86/include/asm/sev-common.h -+++ b/arch/x86/include/asm/sev-common.h -@@ -128,10 +128,6 @@ struct snp_psc_desc { - struct psc_entry entries[VMGEXIT_PSC_MAX_ENTRY]; - } __packed; - --/* Guest message request error codes */ --#define SNP_GUEST_REQ_INVALID_LEN BIT_ULL(32) --#define SNP_GUEST_REQ_ERR_BUSY BIT_ULL(33) -- - #define GHCB_MSR_TERM_REQ 0x100 - #define GHCB_MSR_TERM_REASON_SET_POS 12 - #define GHCB_MSR_TERM_REASON_SET_MASK 0xf -diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h -index a0a58c4122ec3..7ca5c9ec8b52e 100644 ---- a/arch/x86/include/asm/sev.h -+++ b/arch/x86/include/asm/sev.h -@@ -9,6 +9,8 @@ - #define __ASM_ENCRYPTED_STATE_H - - #include -+#include -+ - #include - #include - #include -@@ -185,6 +187,9 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate) - - return rc; - } -+ -+struct snp_guest_request_ioctl; -+ - void setup_ghcb(void); - void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, - unsigned long npages); -@@ -196,7 +201,7 @@ void snp_set_memory_private(unsigned long vaddr, unsigned long npages); - void snp_set_wakeup_secondary_cpu(void); - bool snp_init(struct boot_params *bp); - void __init __noreturn snp_abort(void); --int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err); -+int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio); - #else - static inline void sev_es_ist_enter(struct pt_regs *regs) { } - static inline void sev_es_ist_exit(void) { } -@@ -216,8 +221,7 @@ static inline void snp_set_memory_private(unsigned long vaddr, unsigned long npa - static inline void snp_set_wakeup_secondary_cpu(void) { } - static inline bool snp_init(struct boot_params *bp) { return false; } - static inline void snp_abort(void) { } --static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, -- unsigned long *fw_err) -+static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio) - { - return -ENOTTY; - } -diff --git a/arch/x86/include/asm/sparsemem.h b/arch/x86/include/asm/sparsemem.h -index 64df897c0ee30..1be13b2dfe8bf 100644 ---- a/arch/x86/include/asm/sparsemem.h -+++ b/arch/x86/include/asm/sparsemem.h -@@ -37,6 +37,8 @@ extern int phys_to_target_node(phys_addr_t start); - #define phys_to_target_node phys_to_target_node - extern int memory_add_physaddr_to_nid(u64 start); - #define memory_add_physaddr_to_nid memory_add_physaddr_to_nid -+extern int numa_fill_memblks(u64 start, u64 end); -+#define numa_fill_memblks numa_fill_memblks - #endif - #endif /* __ASSEMBLY__ */ - -diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h -index 1cc756eafa447..6ca0c661cb637 100644 ---- a/arch/x86/include/asm/uaccess.h -+++ b/arch/x86/include/asm/uaccess.h -@@ -518,7 +518,7 @@ copy_mc_to_kernel(void *to, const void *from, unsigned len); - #define copy_mc_to_kernel copy_mc_to_kernel - - unsigned long __must_check --copy_mc_to_user(void *to, const void *from, unsigned len); -+copy_mc_to_user(void __user *to, const void *from, unsigned len); - #endif - - /* -diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c -index 7e331e8f36929..8ea24df3c5ff1 100644 ---- a/arch/x86/kernel/amd_nb.c -+++ b/arch/x86/kernel/amd_nb.c -@@ -100,6 +100,9 @@ static const struct pci_device_id amd_nb_link_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F4) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F4) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F4) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F4) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F4) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, - {} - }; -diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c -index 263df737d5cd5..13dffc43ded02 100644 ---- a/arch/x86/kernel/cpu/bugs.c -+++ b/arch/x86/kernel/cpu/bugs.c -@@ -2477,7 +2477,7 @@ static void __init srso_select_mitigation(void) - pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode")); - - pred_cmd: -- if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) && -+ if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) && - boot_cpu_has(X86_FEATURE_SBPB)) - x86_pred_cmd = PRED_CMD_SBPB; - } -diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c -index 6a3cfaf6b72ad..84adf12a76d3c 100644 ---- a/arch/x86/kernel/head64.c -+++ b/arch/x86/kernel/head64.c -@@ -80,7 +80,7 @@ static struct desc_struct startup_gdt[GDT_ENTRIES] = { - * while the kernel still uses a direct mapping. - */ - static struct desc_ptr startup_gdt_descr = { -- .size = sizeof(startup_gdt), -+ .size = sizeof(startup_gdt)-1, - .address = 0, - }; - -diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c -index e7968c41ecf57..68b2a9d3dbc6b 100644 ---- a/arch/x86/kernel/sev.c -+++ b/arch/x86/kernel/sev.c -@@ -22,6 +22,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -2205,7 +2207,7 @@ static int __init init_sev_config(char *str) - } - __setup("sev=", init_sev_config); - --int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned long *fw_err) -+int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio) - { - struct ghcb_state state; - struct es_em_ctxt ctxt; -@@ -2213,8 +2215,7 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned - struct ghcb *ghcb; - int ret; - -- if (!fw_err) -- return -EINVAL; -+ rio->exitinfo2 = SEV_RET_NO_FW_CALL; - - /* - * __sev_get_ghcb() needs to run with IRQs disabled because it is using -@@ -2239,16 +2240,16 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned - if (ret) - goto e_put; - -- *fw_err = ghcb->save.sw_exit_info_2; -- switch (*fw_err) { -+ rio->exitinfo2 = ghcb->save.sw_exit_info_2; -+ switch (rio->exitinfo2) { - case 0: - break; - -- case SNP_GUEST_REQ_ERR_BUSY: -+ case SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_BUSY): - ret = -EAGAIN; - break; - -- case SNP_GUEST_REQ_INVALID_LEN: -+ case SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN): - /* Number of expected pages are returned in RBX */ - if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST) { - input->data_npages = ghcb_get_rbx(ghcb); -diff --git a/arch/x86/lib/copy_mc.c b/arch/x86/lib/copy_mc.c -index 80efd45a77617..6e8b7e600def5 100644 ---- a/arch/x86/lib/copy_mc.c -+++ b/arch/x86/lib/copy_mc.c -@@ -70,23 +70,23 @@ unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigne - } - EXPORT_SYMBOL_GPL(copy_mc_to_kernel); - --unsigned long __must_check copy_mc_to_user(void *dst, const void *src, unsigned len) -+unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, unsigned len) - { - unsigned long ret; - - if (copy_mc_fragile_enabled) { - __uaccess_begin(); -- ret = copy_mc_fragile(dst, src, len); -+ ret = copy_mc_fragile((__force void *)dst, src, len); - __uaccess_end(); - return ret; - } - - if (static_cpu_has(X86_FEATURE_ERMS)) { - __uaccess_begin(); -- ret = copy_mc_enhanced_fast_string(dst, src, len); -+ ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len); - __uaccess_end(); - return ret; - } - -- return copy_user_generic(dst, src, len); -+ return copy_user_generic((__force void *)dst, src, len); - } -diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c -index 5a53c2cc169cc..6993f026adec9 100644 ---- a/arch/x86/mm/maccess.c -+++ b/arch/x86/mm/maccess.c -@@ -9,12 +9,21 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) - unsigned long vaddr = (unsigned long)unsafe_src; - - /* -- * Range covering the highest possible canonical userspace address -- * as well as non-canonical address range. For the canonical range -- * we also need to include the userspace guard page. -+ * Do not allow userspace addresses. This disallows -+ * normal userspace and the userspace guard page: - */ -- return vaddr >= TASK_SIZE_MAX + PAGE_SIZE && -- __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits); -+ if (vaddr < TASK_SIZE_MAX + PAGE_SIZE) -+ return false; -+ -+ /* -+ * Allow everything during early boot before 'x86_virt_bits' -+ * is initialized. Needed for instruction decoding in early -+ * exception handlers. -+ */ -+ if (!boot_cpu_data.x86_virt_bits) -+ return true; -+ -+ return __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits); - } - #else - bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) -diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c -index 2aadb2019b4f2..c01c5506fd4ae 100644 ---- a/arch/x86/mm/numa.c -+++ b/arch/x86/mm/numa.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -961,4 +962,83 @@ int memory_add_physaddr_to_nid(u64 start) - return nid; - } - EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); -+ -+static int __init cmp_memblk(const void *a, const void *b) -+{ -+ const struct numa_memblk *ma = *(const struct numa_memblk **)a; -+ const struct numa_memblk *mb = *(const struct numa_memblk **)b; -+ -+ return ma->start - mb->start; -+} -+ -+static struct numa_memblk *numa_memblk_list[NR_NODE_MEMBLKS] __initdata; -+ -+/** -+ * numa_fill_memblks - Fill gaps in numa_meminfo memblks -+ * @start: address to begin fill -+ * @end: address to end fill -+ * -+ * Find and extend numa_meminfo memblks to cover the @start-@end -+ * physical address range, such that the first memblk includes -+ * @start, the last memblk includes @end, and any gaps in between -+ * are filled. -+ * -+ * RETURNS: -+ * 0 : Success -+ * NUMA_NO_MEMBLK : No memblk exists in @start-@end range -+ */ -+ -+int __init numa_fill_memblks(u64 start, u64 end) -+{ -+ struct numa_memblk **blk = &numa_memblk_list[0]; -+ struct numa_meminfo *mi = &numa_meminfo; -+ int count = 0; -+ u64 prev_end; -+ -+ /* -+ * Create a list of pointers to numa_meminfo memblks that -+ * overlap start, end. Exclude (start == bi->end) since -+ * end addresses in both a CFMWS range and a memblk range -+ * are exclusive. -+ * -+ * This list of pointers is used to make in-place changes -+ * that fill out the numa_meminfo memblks. -+ */ -+ for (int i = 0; i < mi->nr_blks; i++) { -+ struct numa_memblk *bi = &mi->blk[i]; -+ -+ if (start < bi->end && end >= bi->start) { -+ blk[count] = &mi->blk[i]; -+ count++; -+ } -+ } -+ if (!count) -+ return NUMA_NO_MEMBLK; -+ -+ /* Sort the list of pointers in memblk->start order */ -+ sort(&blk[0], count, sizeof(blk[0]), cmp_memblk, NULL); -+ -+ /* Make sure the first/last memblks include start/end */ -+ blk[0]->start = min(blk[0]->start, start); -+ blk[count - 1]->end = max(blk[count - 1]->end, end); -+ -+ /* -+ * Fill any gaps by tracking the previous memblks -+ * end address and backfilling to it if needed. -+ */ -+ prev_end = blk[0]->end; -+ for (int i = 1; i < count; i++) { -+ struct numa_memblk *curr = blk[i]; -+ -+ if (prev_end >= curr->start) { -+ if (prev_end < curr->end) -+ prev_end = curr->end; -+ } else { -+ curr->start = prev_end; -+ prev_end = curr->end; -+ } -+ } -+ return 0; -+} -+ - #endif -diff --git a/block/blk-core.c b/block/blk-core.c -index ebb7a1689b261..6eaf2b0ad7cca 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -490,8 +490,8 @@ static inline void bio_check_ro(struct bio *bio) - if (op_is_write(bio_op(bio)) && bdev_read_only(bio->bi_bdev)) { - if (op_is_flush(bio->bi_opf) && !bio_sectors(bio)) - return; -- pr_warn("Trying to write to read-only block-device %pg\n", -- bio->bi_bdev); -+ pr_warn_ratelimited("Trying to write to read-only block-device %pg\n", -+ bio->bi_bdev); - /* Older lvm-tools actually trigger this */ - } - } -diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c -index 120873dad2cc5..c727fb320eeea 100644 ---- a/drivers/acpi/device_sysfs.c -+++ b/drivers/acpi/device_sysfs.c -@@ -158,8 +158,8 @@ static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias, - return 0; - - len = snprintf(modalias, size, "acpi:"); -- if (len <= 0) -- return len; -+ if (len >= size) -+ return -ENOMEM; - - size -= len; - -@@ -212,8 +212,10 @@ static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias, - len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); - ACPI_FREE(buf.pointer); - -- if (len <= 0) -- return len; -+ if (len >= size) -+ return -ENOMEM; -+ -+ size -= len; - - of_compatible = acpi_dev->data.of_compatible; - if (of_compatible->type == ACPI_TYPE_PACKAGE) { -diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c -index 1f4fc5f8a819d..12f330b0eac01 100644 ---- a/drivers/acpi/numa/srat.c -+++ b/drivers/acpi/numa/srat.c -@@ -310,11 +310,16 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, - start = cfmws->base_hpa; - end = cfmws->base_hpa + cfmws->window_size; - -- /* Skip if the SRAT already described the NUMA details for this HPA */ -- node = phys_to_target_node(start); -- if (node != NUMA_NO_NODE) -+ /* -+ * The SRAT may have already described NUMA details for all, -+ * or a portion of, this CFMWS HPA range. Extend the memblks -+ * found for any portion of the window to cover the entire -+ * window. -+ */ -+ if (!numa_fill_memblks(start, end)) - return 0; - -+ /* No SRAT description. Create a new node. */ - node = acpi_map_pxm_to_node(*fake_pxm); - - if (node == NUMA_NO_NODE) { -diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c -index b8d9eb9a433ed..0565c18c2ee31 100644 ---- a/drivers/acpi/property.c -+++ b/drivers/acpi/property.c -@@ -1114,25 +1114,26 @@ static int acpi_data_prop_read(const struct acpi_device_data *data, - switch (proptype) { - case DEV_PROP_STRING: - break; -- case DEV_PROP_U8 ... DEV_PROP_U64: -+ default: - if (obj->type == ACPI_TYPE_BUFFER) { - if (nval > obj->buffer.length) - return -EOVERFLOW; -- break; -+ } else { -+ if (nval > obj->package.count) -+ return -EOVERFLOW; - } -- fallthrough; -- default: -- if (nval > obj->package.count) -- return -EOVERFLOW; - break; - } - if (nval == 0) - return -EINVAL; - -- if (obj->type != ACPI_TYPE_BUFFER) -- items = obj->package.elements; -- else -+ if (obj->type == ACPI_TYPE_BUFFER) { -+ if (proptype != DEV_PROP_U8) -+ return -EPROTO; - items = obj; -+ } else { -+ items = obj->package.elements; -+ } - - switch (proptype) { - case DEV_PROP_U8: -diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c -index 073d26ddb6c21..60b0128a10e86 100644 ---- a/drivers/acpi/video_detect.c -+++ b/drivers/acpi/video_detect.c -@@ -130,6 +130,16 @@ static int video_detect_force_native(const struct dmi_system_id *d) - return 0; - } - -+static int video_detect_portege_r100(const struct dmi_system_id *d) -+{ -+ struct pci_dev *dev; -+ /* Search for Trident CyberBlade XP4m32 to confirm Portégé R100 */ -+ dev = pci_get_device(PCI_VENDOR_ID_TRIDENT, 0x2100, NULL); -+ if (dev) -+ acpi_backlight_dmi = acpi_backlight_vendor; -+ return 0; -+} -+ - static const struct dmi_system_id video_detect_dmi_table[] = { - /* - * Models which should use the vendor backlight interface, -@@ -268,6 +278,22 @@ static const struct dmi_system_id video_detect_dmi_table[] = { - }, - }, - -+ /* -+ * Toshiba Portégé R100 has working both acpi_video and toshiba_acpi -+ * vendor driver. But none of them gets activated as it has a VGA with -+ * no kernel driver (Trident CyberBlade XP4m32). -+ * The DMI strings are generic so check for the VGA chip in callback. -+ */ -+ { -+ .callback = video_detect_portege_r100, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"), -+ DMI_MATCH(DMI_BOARD_NAME, "Portable PC") -+ }, -+ }, -+ - /* - * Models which need acpi_video backlight control where the GPU drivers - * do not call acpi_video_register_backlight() because no internal panel -diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c -index 817eda2075aa5..1e3d205ce15a0 100644 ---- a/drivers/base/regmap/regmap-debugfs.c -+++ b/drivers/base/regmap/regmap-debugfs.c -@@ -48,7 +48,7 @@ static ssize_t regmap_name_read_file(struct file *file, - name = map->dev->driver->name; - - ret = snprintf(buf, PAGE_SIZE, "%s\n", name); -- if (ret < 0) { -+ if (ret >= PAGE_SIZE) { - kfree(buf); - return ret; - } -diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c -index df1f78abdf266..140af27f591ae 100644 ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -1702,17 +1702,19 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, - } - - if (!map->cache_bypass && map->format.parse_val) { -- unsigned int ival; -+ unsigned int ival, offset; - int val_bytes = map->format.val_bytes; -- for (i = 0; i < val_len / val_bytes; i++) { -- ival = map->format.parse_val(val + (i * val_bytes)); -- ret = regcache_write(map, -- reg + regmap_get_offset(map, i), -- ival); -+ -+ /* Cache the last written value for noinc writes */ -+ i = noinc ? val_len - val_bytes : 0; -+ for (; i < val_len; i += val_bytes) { -+ ival = map->format.parse_val(val + i); -+ offset = noinc ? 0 : regmap_get_offset(map, i / val_bytes); -+ ret = regcache_write(map, reg + offset, ival); - if (ret) { - dev_err(map->dev, - "Error in caching of register: %x ret: %d\n", -- reg + regmap_get_offset(map, i), ret); -+ reg + offset, ret); - return ret; - } - } -diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c -index 7718c81e1dba8..e94d2ff6b1223 100644 ---- a/drivers/block/nbd.c -+++ b/drivers/block/nbd.c -@@ -250,7 +250,6 @@ static void nbd_dev_remove(struct nbd_device *nbd) - struct gendisk *disk = nbd->disk; - - del_gendisk(disk); -- put_disk(disk); - blk_mq_free_tag_set(&nbd->tag_set); - - /* -@@ -261,7 +260,7 @@ static void nbd_dev_remove(struct nbd_device *nbd) - idr_remove(&nbd_index_idr, nbd->index); - mutex_unlock(&nbd_index_mutex); - destroy_workqueue(nbd->recv_workq); -- kfree(nbd); -+ put_disk(disk); - } - - static void nbd_dev_remove_work(struct work_struct *work) -@@ -1608,6 +1607,13 @@ static void nbd_release(struct gendisk *disk, fmode_t mode) - nbd_put(nbd); - } - -+static void nbd_free_disk(struct gendisk *disk) -+{ -+ struct nbd_device *nbd = disk->private_data; -+ -+ kfree(nbd); -+} -+ - static const struct block_device_operations nbd_fops = - { - .owner = THIS_MODULE, -@@ -1615,6 +1621,7 @@ static const struct block_device_operations nbd_fops = - .release = nbd_release, - .ioctl = nbd_ioctl, - .compat_ioctl = nbd_ioctl, -+ .free_disk = nbd_free_disk, - }; - - #if IS_ENABLED(CONFIG_DEBUG_FS) -diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c -index e98fcac578d66..634eab4776f32 100644 ---- a/drivers/char/hw_random/bcm2835-rng.c -+++ b/drivers/char/hw_random/bcm2835-rng.c -@@ -71,7 +71,7 @@ static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max, - while ((rng_readl(priv, RNG_STATUS) >> 24) == 0) { - if (!wait) - return 0; -- hwrng_msleep(rng, 1000); -+ hwrng_yield(rng); - } - - num_words = rng_readl(priv, RNG_STATUS) >> 24; -diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c -index cc002b0c2f0c3..8f31f9d810305 100644 ---- a/drivers/char/hw_random/core.c -+++ b/drivers/char/hw_random/core.c -@@ -680,6 +680,12 @@ long hwrng_msleep(struct hwrng *rng, unsigned int msecs) - } - EXPORT_SYMBOL_GPL(hwrng_msleep); - -+long hwrng_yield(struct hwrng *rng) -+{ -+ return wait_for_completion_interruptible_timeout(&rng->dying, 1); -+} -+EXPORT_SYMBOL_GPL(hwrng_yield); -+ - static int __init hwrng_modinit(void) - { - int ret; -diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c -index 12fbe80918319..159baf00a8675 100644 ---- a/drivers/char/hw_random/geode-rng.c -+++ b/drivers/char/hw_random/geode-rng.c -@@ -58,7 +58,8 @@ struct amd_geode_priv { - - static int geode_rng_data_read(struct hwrng *rng, u32 *data) - { -- void __iomem *mem = (void __iomem *)rng->priv; -+ struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv; -+ void __iomem *mem = priv->membase; - - *data = readl(mem + GEODE_RNG_DATA_REG); - -@@ -67,7 +68,8 @@ static int geode_rng_data_read(struct hwrng *rng, u32 *data) - - static int geode_rng_data_present(struct hwrng *rng, int wait) - { -- void __iomem *mem = (void __iomem *)rng->priv; -+ struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv; -+ void __iomem *mem = priv->membase; - int data, i; - - for (i = 0; i < 20; i++) { -diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c -index e319cfa51a8a3..030186def9c69 100644 ---- a/drivers/clk/clk-npcm7xx.c -+++ b/drivers/clk/clk-npcm7xx.c -@@ -510,7 +510,7 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np) - return; - - npcm7xx_init_fail: -- kfree(npcm7xx_clk_data->hws); -+ kfree(npcm7xx_clk_data); - npcm7xx_init_np_err: - iounmap(clk_base); - npcm7xx_init_error: -diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c -index 2c7a830ce3080..fdec715c9ba9b 100644 ---- a/drivers/clk/clk-scmi.c -+++ b/drivers/clk/clk-scmi.c -@@ -213,6 +213,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev) - sclk->info = scmi_proto_clk_ops->info_get(ph, idx); - if (!sclk->info) { - dev_dbg(dev, "invalid clock info for idx %d\n", idx); -+ devm_kfree(dev, sclk); - continue; - } - -diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig -index 25785ec9c2762..f219004b8a337 100644 ---- a/drivers/clk/imx/Kconfig -+++ b/drivers/clk/imx/Kconfig -@@ -96,6 +96,7 @@ config CLK_IMX8QXP - depends on (ARCH_MXC && ARM64) || COMPILE_TEST - depends on IMX_SCU && HAVE_ARM_SMCCC - select MXC_CLK_SCU -+ select MXC_CLK - help - Build the driver for IMX8QXP SCU based clocks. - -diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c -index 882dcad4817d7..0a75814b3bc77 100644 ---- a/drivers/clk/imx/clk-imx8mq.c -+++ b/drivers/clk/imx/clk-imx8mq.c -@@ -288,8 +288,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) - void __iomem *base; - int err; - -- clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, -- IMX8MQ_CLK_END), GFP_KERNEL); -+ clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MQ_CLK_END), GFP_KERNEL); - if (WARN_ON(!clk_hw_data)) - return -ENOMEM; - -@@ -306,10 +305,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) - hws[IMX8MQ_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4"); - - np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop"); -- base = of_iomap(np, 0); -+ base = devm_of_iomap(dev, np, 0, NULL); - of_node_put(np); -- if (WARN_ON(!base)) -- return -ENOMEM; -+ if (WARN_ON(IS_ERR(base))) { -+ err = PTR_ERR(base); -+ goto unregister_hws; -+ } - - hws[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - hws[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -@@ -395,8 +396,10 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) - - np = dev->of_node; - base = devm_platform_ioremap_resource(pdev, 0); -- if (WARN_ON(IS_ERR(base))) -- return PTR_ERR(base); -+ if (WARN_ON(IS_ERR(base))) { -+ err = PTR_ERR(base); -+ goto unregister_hws; -+ } - - /* CORE */ - hws[IMX8MQ_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mq_a53_sels, base + 0x8000); -diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c -index 546a3703bfeb2..273de1f293076 100644 ---- a/drivers/clk/imx/clk-imx8qxp.c -+++ b/drivers/clk/imx/clk-imx8qxp.c -@@ -148,10 +148,10 @@ static int imx8qxp_clk_probe(struct platform_device *pdev) - imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER); - imx_clk_scu("adc1_clk", IMX_SC_R_ADC_1, IMX_SC_PM_CLK_PER); - imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER); -+ imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL); - imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER); - imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0); - imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS); -- imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL); - - /* Audio SS */ - imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL); -diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c -index ee5c72369334f..6bbdd4705d71f 100644 ---- a/drivers/clk/keystone/pll.c -+++ b/drivers/clk/keystone/pll.c -@@ -281,12 +281,13 @@ static void __init of_pll_div_clk_init(struct device_node *node) - - clk = clk_register_divider(NULL, clk_name, parent_name, 0, reg, shift, - mask, 0, NULL); -- if (clk) { -- of_clk_add_provider(node, of_clk_src_simple_get, clk); -- } else { -+ if (IS_ERR(clk)) { - pr_err("%s: error registering divider %s\n", __func__, clk_name); - iounmap(reg); -+ return; - } -+ -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); - } - CLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init); - -@@ -328,10 +329,12 @@ static void __init of_pll_mux_clk_init(struct device_node *node) - clk = clk_register_mux(NULL, clk_name, (const char **)&parents, - ARRAY_SIZE(parents) , 0, reg, shift, mask, - 0, NULL); -- if (clk) -- of_clk_add_provider(node, of_clk_src_simple_get, clk); -- else -+ if (IS_ERR(clk)) { - pr_err("%s: error registering mux %s\n", __func__, clk_name); -+ return; -+ } -+ -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); - } - CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init); - -diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c -index 1c3a93143dc5e..00d2e81bdd43e 100644 ---- a/drivers/clk/mediatek/clk-mt2701.c -+++ b/drivers/clk/mediatek/clk-mt2701.c -@@ -670,6 +670,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) - return PTR_ERR(base); - - clk_data = mtk_alloc_clk_data(CLK_TOP_NR); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), - clk_data); -@@ -749,6 +751,8 @@ static void __init mtk_infrasys_init_early(struct device_node *node) - - if (!infra_clk_data) { - infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); -+ if (!infra_clk_data) -+ return; - - for (i = 0; i < CLK_INFRA_NR; i++) - infra_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER); -@@ -776,6 +780,8 @@ static int mtk_infrasys_init(struct platform_device *pdev) - - if (!infra_clk_data) { - infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); -+ if (!infra_clk_data) -+ return -ENOMEM; - } else { - for (i = 0; i < CLK_INFRA_NR; i++) { - if (infra_clk_data->hws[i] == ERR_PTR(-EPROBE_DEFER)) -@@ -893,6 +899,8 @@ static int mtk_pericfg_init(struct platform_device *pdev) - return PTR_ERR(base); - - clk_data = mtk_alloc_clk_data(CLK_PERI_NR); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), - clk_data); -diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c -index 665981fc411f5..2c6a52ff5564e 100644 ---- a/drivers/clk/mediatek/clk-mt6765.c -+++ b/drivers/clk/mediatek/clk-mt6765.c -@@ -738,6 +738,8 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev) - } - - clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); - -@@ -773,6 +775,8 @@ static int clk_mt6765_top_probe(struct platform_device *pdev) - } - - clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), - clk_data); -@@ -813,6 +817,8 @@ static int clk_mt6765_ifr_probe(struct platform_device *pdev) - } - - clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_gates(node, ifr_clks, ARRAY_SIZE(ifr_clks), - clk_data); -diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c -index 0d0a90ee5eb2c..39dadc9547088 100644 ---- a/drivers/clk/mediatek/clk-mt6779.c -+++ b/drivers/clk/mediatek/clk-mt6779.c -@@ -1218,6 +1218,8 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev) - struct device_node *node = pdev->dev.of_node; - - clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); - -@@ -1238,6 +1240,8 @@ static int clk_mt6779_top_probe(struct platform_device *pdev) - return PTR_ERR(base); - - clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), - clk_data); -diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c -index 78339cb35beb0..b362e99c8f53c 100644 ---- a/drivers/clk/mediatek/clk-mt6797.c -+++ b/drivers/clk/mediatek/clk-mt6797.c -@@ -392,6 +392,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) - return PTR_ERR(base); - - clk_data = mtk_alloc_clk_data(CLK_TOP_NR); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs), - clk_data); -@@ -546,6 +548,8 @@ static void mtk_infrasys_init_early(struct device_node *node) - - if (!infra_clk_data) { - infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); -+ if (!infra_clk_data) -+ return; - - for (i = 0; i < CLK_INFRA_NR; i++) - infra_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER); -@@ -571,6 +575,8 @@ static int mtk_infrasys_init(struct platform_device *pdev) - - if (!infra_clk_data) { - infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); -+ if (!infra_clk_data) -+ return -ENOMEM; - } else { - for (i = 0; i < CLK_INFRA_NR; i++) { - if (infra_clk_data->hws[i] == ERR_PTR(-EPROBE_DEFER)) -diff --git a/drivers/clk/mediatek/clk-mt7629-eth.c b/drivers/clk/mediatek/clk-mt7629-eth.c -index b0c8fa3b8bbec..e1d2635c72c10 100644 ---- a/drivers/clk/mediatek/clk-mt7629-eth.c -+++ b/drivers/clk/mediatek/clk-mt7629-eth.c -@@ -79,6 +79,8 @@ static int clk_mt7629_ethsys_init(struct platform_device *pdev) - int r; - - clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_gates(node, eth_clks, CLK_ETH_NR_CLK, clk_data); - -@@ -101,6 +103,8 @@ static int clk_mt7629_sgmiisys_init(struct platform_device *pdev) - int r; - - clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_gates(node, sgmii_clks[id++], CLK_SGMII_NR_CLK, - clk_data); -diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c -index 0bc88b7d171b5..01ee45fcd7e34 100644 ---- a/drivers/clk/mediatek/clk-mt7629.c -+++ b/drivers/clk/mediatek/clk-mt7629.c -@@ -557,6 +557,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) - return PTR_ERR(base); - - clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), - clk_data); -@@ -580,6 +582,8 @@ static int mtk_infrasys_init(struct platform_device *pdev) - struct clk_hw_onecell_data *clk_data; - - clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), - clk_data); -@@ -603,6 +607,8 @@ static int mtk_pericfg_init(struct platform_device *pdev) - return PTR_ERR(base); - - clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); -+ if (!clk_data) -+ return -ENOMEM; - - mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), - clk_data); -diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig -index 76e6dee450d59..cbf55949c6493 100644 ---- a/drivers/clk/qcom/Kconfig -+++ b/drivers/clk/qcom/Kconfig -@@ -127,6 +127,7 @@ config IPQ_APSS_6018 - tristate "IPQ APSS Clock Controller" - select IPQ_APSS_PLL - depends on QCOM_APCS_IPC || COMPILE_TEST -+ depends on QCOM_SMEM - help - Support for APSS clock controller on IPQ platforms. The - APSS clock controller manages the Mux and enable block that feeds the -diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c -index 76551534f10df..dc797bd137caf 100644 ---- a/drivers/clk/qcom/clk-rcg2.c -+++ b/drivers/clk/qcom/clk-rcg2.c -@@ -158,17 +158,11 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index) - static unsigned long - calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div) - { -- if (hid_div) { -- rate *= 2; -- rate /= hid_div + 1; -- } -+ if (hid_div) -+ rate = mult_frac(rate, 2, hid_div + 1); - -- if (mode) { -- u64 tmp = rate; -- tmp *= m; -- do_div(tmp, n); -- rate = tmp; -- } -+ if (mode) -+ rate = mult_frac(rate, m, n); - - return rate; - } -diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c -index e161637067351..ff5a16700ef71 100644 ---- a/drivers/clk/qcom/gcc-msm8996.c -+++ b/drivers/clk/qcom/gcc-msm8996.c -@@ -245,71 +245,6 @@ static const struct clk_parent_data gcc_xo_gpll0_gpll4_gpll0_early_div[] = { - { .hw = &gpll0_early_div.hw } - }; - --static const struct freq_tbl ftbl_system_noc_clk_src[] = { -- F(19200000, P_XO, 1, 0, 0), -- F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0), -- F(100000000, P_GPLL0, 6, 0, 0), -- F(150000000, P_GPLL0, 4, 0, 0), -- F(200000000, P_GPLL0, 3, 0, 0), -- F(240000000, P_GPLL0, 2.5, 0, 0), -- { } --}; -- --static struct clk_rcg2 system_noc_clk_src = { -- .cmd_rcgr = 0x0401c, -- .hid_width = 5, -- .parent_map = gcc_xo_gpll0_gpll0_early_div_map, -- .freq_tbl = ftbl_system_noc_clk_src, -- .clkr.hw.init = &(struct clk_init_data){ -- .name = "system_noc_clk_src", -- .parent_data = gcc_xo_gpll0_gpll0_early_div, -- .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div), -- .ops = &clk_rcg2_ops, -- }, --}; -- --static const struct freq_tbl ftbl_config_noc_clk_src[] = { -- F(19200000, P_XO, 1, 0, 0), -- F(37500000, P_GPLL0, 16, 0, 0), -- F(75000000, P_GPLL0, 8, 0, 0), -- { } --}; -- --static struct clk_rcg2 config_noc_clk_src = { -- .cmd_rcgr = 0x0500c, -- .hid_width = 5, -- .parent_map = gcc_xo_gpll0_map, -- .freq_tbl = ftbl_config_noc_clk_src, -- .clkr.hw.init = &(struct clk_init_data){ -- .name = "config_noc_clk_src", -- .parent_data = gcc_xo_gpll0, -- .num_parents = ARRAY_SIZE(gcc_xo_gpll0), -- .ops = &clk_rcg2_ops, -- }, --}; -- --static const struct freq_tbl ftbl_periph_noc_clk_src[] = { -- F(19200000, P_XO, 1, 0, 0), -- F(37500000, P_GPLL0, 16, 0, 0), -- F(50000000, P_GPLL0, 12, 0, 0), -- F(75000000, P_GPLL0, 8, 0, 0), -- F(100000000, P_GPLL0, 6, 0, 0), -- { } --}; -- --static struct clk_rcg2 periph_noc_clk_src = { -- .cmd_rcgr = 0x06014, -- .hid_width = 5, -- .parent_map = gcc_xo_gpll0_map, -- .freq_tbl = ftbl_periph_noc_clk_src, -- .clkr.hw.init = &(struct clk_init_data){ -- .name = "periph_noc_clk_src", -- .parent_data = gcc_xo_gpll0, -- .num_parents = ARRAY_SIZE(gcc_xo_gpll0), -- .ops = &clk_rcg2_ops, -- }, --}; -- - static const struct freq_tbl ftbl_usb30_master_clk_src[] = { - F(19200000, P_XO, 1, 0, 0), - F(120000000, P_GPLL0, 5, 0, 0), -@@ -1298,11 +1233,7 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_mmss_noc_cfg_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, -+ .flags = CLK_IGNORE_UNUSED, - .ops = &clk_branch2_ops, - }, - }, -@@ -1465,11 +1396,6 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_usb_phy_cfg_ahb2phy_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -1499,11 +1425,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_sdcc1_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -1550,11 +1471,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_sdcc2_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -1584,11 +1500,6 @@ static struct clk_branch gcc_sdcc3_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_sdcc3_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -1618,11 +1529,6 @@ static struct clk_branch gcc_sdcc4_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_sdcc4_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -1636,11 +1542,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = { - .enable_mask = BIT(17), - .hw.init = &(struct clk_init_data){ - .name = "gcc_blsp1_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -1978,11 +1879,6 @@ static struct clk_branch gcc_blsp2_ahb_clk = { - .enable_mask = BIT(15), - .hw.init = &(struct clk_init_data){ - .name = "gcc_blsp2_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2319,11 +2215,6 @@ static struct clk_branch gcc_pdm_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pdm_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2354,11 +2245,6 @@ static struct clk_branch gcc_prng_ahb_clk = { - .enable_mask = BIT(13), - .hw.init = &(struct clk_init_data){ - .name = "gcc_prng_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2371,11 +2257,6 @@ static struct clk_branch gcc_tsif_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_tsif_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2423,11 +2304,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { - .enable_mask = BIT(10), - .hw.init = &(struct clk_init_data){ - .name = "gcc_boot_rom_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2521,11 +2397,6 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_0_slv_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2538,11 +2409,6 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_0_mstr_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2555,11 +2421,6 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_0_cfg_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2607,11 +2468,6 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_1_slv_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2624,11 +2480,6 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_1_mstr_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2641,11 +2492,6 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_1_cfg_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2693,11 +2539,6 @@ static struct clk_branch gcc_pcie_2_slv_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_2_slv_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2710,11 +2551,6 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_2_mstr_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2727,11 +2563,6 @@ static struct clk_branch gcc_pcie_2_cfg_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_2_cfg_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2779,11 +2610,6 @@ static struct clk_branch gcc_pcie_phy_cfg_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_pcie_phy_cfg_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -2830,11 +2656,6 @@ static struct clk_branch gcc_ufs_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_ufs_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -3061,11 +2882,7 @@ static struct clk_branch gcc_aggre0_snoc_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_aggre0_snoc_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, -+ .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -@@ -3078,11 +2895,7 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_aggre0_cnoc_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, -+ .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -@@ -3095,11 +2908,7 @@ static struct clk_branch gcc_smmu_aggre0_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_smmu_aggre0_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, -+ .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -@@ -3112,11 +2921,7 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_smmu_aggre0_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, -+ .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -@@ -3163,10 +2968,6 @@ static struct clk_branch gcc_dcc_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_dcc_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -@@ -3179,10 +2980,6 @@ static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_aggre0_noc_mpu_cfg_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -@@ -3195,11 +2992,6 @@ static struct clk_branch gcc_qspi_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_qspi_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &periph_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, -- .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -@@ -3348,10 +3140,6 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_mss_cfg_ahb_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &config_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -@@ -3364,10 +3152,6 @@ static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_mss_mnoc_bimc_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -@@ -3380,10 +3164,6 @@ static struct clk_branch gcc_mss_snoc_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_mss_snoc_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -@@ -3396,10 +3176,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = { - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_mss_q6_bimc_axi_clk", -- .parent_hws = (const struct clk_hw*[]){ -- &system_noc_clk_src.clkr.hw, -- }, -- .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -@@ -3495,9 +3271,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { - [GPLL0] = &gpll0.clkr, - [GPLL4_EARLY] = &gpll4_early.clkr, - [GPLL4] = &gpll4.clkr, -- [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr, -- [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr, -- [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr, - [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, - [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, - [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, -diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c -index 09cf827addabe..4501c15c4a417 100644 ---- a/drivers/clk/qcom/gcc-sm8150.c -+++ b/drivers/clk/qcom/gcc-sm8150.c -@@ -792,7 +792,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { - .name = "gcc_sdcc2_apps_clk_src", - .parent_data = gcc_parents_6, - .num_parents = ARRAY_SIZE(gcc_parents_6), -- .flags = CLK_SET_RATE_PARENT, -+ .flags = CLK_OPS_PARENT_ENABLE, - .ops = &clk_rcg2_floor_ops, - }, - }; -diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c -index c421b12916516..e5a72c2f080f8 100644 ---- a/drivers/clk/qcom/mmcc-msm8998.c -+++ b/drivers/clk/qcom/mmcc-msm8998.c -@@ -2478,6 +2478,7 @@ static struct clk_branch fd_ahb_clk = { - - static struct clk_branch mnoc_ahb_clk = { - .halt_reg = 0x5024, -+ .halt_check = BRANCH_HALT_SKIP, - .clkr = { - .enable_reg = 0x5024, - .enable_mask = BIT(0), -@@ -2493,6 +2494,7 @@ static struct clk_branch mnoc_ahb_clk = { - - static struct clk_branch bimc_smmu_ahb_clk = { - .halt_reg = 0xe004, -+ .halt_check = BRANCH_HALT_SKIP, - .hwcg_reg = 0xe004, - .hwcg_bit = 1, - .clkr = { -@@ -2510,6 +2512,7 @@ static struct clk_branch bimc_smmu_ahb_clk = { - - static struct clk_branch bimc_smmu_axi_clk = { - .halt_reg = 0xe008, -+ .halt_check = BRANCH_HALT_SKIP, - .hwcg_reg = 0xe008, - .hwcg_bit = 1, - .clkr = { -@@ -2650,11 +2653,13 @@ static struct gdsc camss_cpp_gdsc = { - static struct gdsc bimc_smmu_gdsc = { - .gdscr = 0xe020, - .gds_hw_ctrl = 0xe024, -+ .cxcs = (unsigned int []){ 0xe008 }, -+ .cxc_count = 1, - .pd = { - .name = "bimc_smmu", - }, - .pwrsts = PWRSTS_OFF_ON, -- .flags = HW_CTRL | ALWAYS_ON, -+ .flags = VOTABLE, - }; - - static struct clk_regmap *mmcc_msm8998_clocks[] = { -diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c -index e2e0447de1901..5a15f8788b922 100644 ---- a/drivers/clk/renesas/rcar-cpg-lib.c -+++ b/drivers/clk/renesas/rcar-cpg-lib.c -@@ -70,8 +70,21 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, - #define STPnHCK BIT(9 - SDnSRCFC_SHIFT) - - static const struct clk_div_table cpg_sdh_div_table[] = { -+ /* -+ * These values are recommended by the datasheet. Because they come -+ * first, Linux will only use these. -+ */ - { 0, 1 }, { 1, 2 }, { STPnHCK | 2, 4 }, { STPnHCK | 3, 8 }, -- { STPnHCK | 4, 16 }, { 0, 0 }, -+ { STPnHCK | 4, 16 }, -+ /* -+ * These values are not recommended because STPnHCK is wrong. But they -+ * have been seen because of broken firmware. So, we support reading -+ * them but Linux will sanitize them when initializing through -+ * recalc_rate. -+ */ -+ { STPnHCK | 0, 1 }, { STPnHCK | 1, 2 }, { 2, 4 }, { 3, 8 }, { 4, 16 }, -+ /* Sentinel */ -+ { 0, 0 } - }; - - struct clk * __init cpg_sdh_clk_register(const char *name, -diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c -index 2c877576c5729..84767cfc1e739 100644 ---- a/drivers/clk/renesas/rzg2l-cpg.c -+++ b/drivers/clk/renesas/rzg2l-cpg.c -@@ -11,6 +11,7 @@ - * Copyright (C) 2015 Renesas Electronics Corp. - */ - -+#include - #include - #include - #include -@@ -39,14 +40,13 @@ - #define WARN_DEBUG(x) do { } while (0) - #endif - --#define DIV_RSMASK(v, s, m) ((v >> s) & m) - #define GET_SHIFT(val) ((val >> 12) & 0xff) - #define GET_WIDTH(val) ((val >> 8) & 0xf) - --#define KDIV(val) DIV_RSMASK(val, 16, 0xffff) --#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff) --#define PDIV(val) DIV_RSMASK(val, 0, 0x3f) --#define SDIV(val) DIV_RSMASK(val, 0, 0x7) -+#define KDIV(val) ((s16)FIELD_GET(GENMASK(31, 16), val)) -+#define MDIV(val) FIELD_GET(GENMASK(15, 6), val) -+#define PDIV(val) FIELD_GET(GENMASK(5, 0), val) -+#define SDIV(val) FIELD_GET(GENMASK(2, 0), val) - - #define CLK_ON_R(reg) (reg) - #define CLK_MON_R(reg) (0x180 + (reg)) -@@ -192,7 +192,9 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) - u32 off = GET_REG_OFFSET(hwdata->conf); - u32 shift = GET_SHIFT(hwdata->conf); - const u32 clk_src_266 = 2; -- u32 bitmask; -+ u32 msk, val, bitmask; -+ unsigned long flags; -+ int ret; - - /* - * As per the HW manual, we should not directly switch from 533 MHz to -@@ -206,26 +208,30 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) - * the index to value mapping is done by adding 1 to the index. - */ - bitmask = (GENMASK(GET_WIDTH(hwdata->conf) - 1, 0) << shift) << 16; -+ msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS; -+ spin_lock_irqsave(&priv->rmw_lock, flags); - if (index != clk_src_266) { -- u32 msk, val; -- int ret; -- - writel(bitmask | ((clk_src_266 + 1) << shift), priv->base + off); - -- msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS; -- -- ret = readl_poll_timeout(priv->base + CPG_CLKSTATUS, val, -- !(val & msk), 100, -- CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); -- if (ret) { -- dev_err(priv->dev, "failed to switch clk source\n"); -- return ret; -- } -+ ret = readl_poll_timeout_atomic(priv->base + CPG_CLKSTATUS, val, -+ !(val & msk), 10, -+ CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); -+ if (ret) -+ goto unlock; - } - - writel(bitmask | ((index + 1) << shift), priv->base + off); - -- return 0; -+ ret = readl_poll_timeout_atomic(priv->base + CPG_CLKSTATUS, val, -+ !(val & msk), 10, -+ CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); -+unlock: -+ spin_unlock_irqrestore(&priv->rmw_lock, flags); -+ -+ if (ret) -+ dev_err(priv->dev, "failed to switch clk source\n"); -+ -+ return ret; - } - - static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw) -@@ -236,14 +242,8 @@ static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw) - - val >>= GET_SHIFT(hwdata->conf); - val &= GENMASK(GET_WIDTH(hwdata->conf) - 1, 0); -- if (val) { -- val--; -- } else { -- /* Prohibited clk source, change it to 533 MHz(reset value) */ -- rzg2l_cpg_sd_clk_mux_set_parent(hw, 0); -- } - -- return val; -+ return val ? val - 1 : 0; - } - - static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = { -@@ -699,18 +699,18 @@ static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw, - struct pll_clk *pll_clk = to_pll(hw); - struct rzg2l_cpg_priv *priv = pll_clk->priv; - unsigned int val1, val2; -- unsigned int mult = 1; -- unsigned int div = 1; -+ u64 rate; - - if (pll_clk->type != CLK_TYPE_SAM_PLL) - return parent_rate; - - val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); - val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); -- mult = MDIV(val1) + KDIV(val1) / 65536; -- div = PDIV(val1) << SDIV(val2); - -- return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div); -+ rate = mul_u64_u32_shr(parent_rate, (MDIV(val1) << 16) + KDIV(val1), -+ 16 + SDIV(val2)); -+ -+ return DIV_ROUND_CLOSEST_ULL(rate, PDIV(val1)); - } - - static const struct clk_ops rzg2l_cpg_pll_ops = { -diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h -index b33a3e79161b6..aefa53a900597 100644 ---- a/drivers/clk/renesas/rzg2l-cpg.h -+++ b/drivers/clk/renesas/rzg2l-cpg.h -@@ -43,7 +43,7 @@ - #define CPG_CLKSTATUS_SELSDHI0_STS BIT(28) - #define CPG_CLKSTATUS_SELSDHI1_STS BIT(29) - --#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 20000 -+#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 200 - - /* n = 0/1/2 for PLL1/4/6 */ - #define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) -diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c -index dd0709c9c2498..93183287c58db 100644 ---- a/drivers/clk/ti/apll.c -+++ b/drivers/clk/ti/apll.c -@@ -160,7 +160,7 @@ static void __init omap_clk_register_apll(void *user, - ad->clk_bypass = __clk_get_hw(clk); - - name = ti_dt_clk_name(node); -- clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name); -+ clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name); - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - kfree(init->parent_names); -@@ -400,7 +400,7 @@ static void __init of_omap2_apll_setup(struct device_node *node) - goto cleanup; - - name = ti_dt_clk_name(node); -- clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name); -+ clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name); - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - kfree(init); -diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c -index ff4d6a9516813..1c576599f6dbd 100644 ---- a/drivers/clk/ti/clk-dra7-atl.c -+++ b/drivers/clk/ti/clk-dra7-atl.c -@@ -197,7 +197,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node) - - init.parent_names = parent_names; - -- clk = ti_clk_register(NULL, &clk_hw->hw, name); -+ clk = of_ti_clk_register(node, &clk_hw->hw, name); - - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); -diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c -index 1dc2f15fb75b2..269355010cdce 100644 ---- a/drivers/clk/ti/clk.c -+++ b/drivers/clk/ti/clk.c -@@ -475,7 +475,7 @@ void __init ti_clk_add_aliases(void) - clkspec.np = np; - clk = of_clk_get_from_provider(&clkspec); - -- ti_clk_add_alias(NULL, clk, ti_dt_clk_name(np)); -+ ti_clk_add_alias(clk, ti_dt_clk_name(np)); - } - } - -@@ -528,7 +528,6 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks) - - /** - * ti_clk_add_alias - add a clock alias for a TI clock -- * @dev: device alias for this clock - * @clk: clock handle to create alias for - * @con: connection ID for this clock - * -@@ -536,7 +535,7 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks) - * and assigns the data to it. Returns 0 if successful, negative error - * value otherwise. - */ --int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con) -+int ti_clk_add_alias(struct clk *clk, const char *con) - { - struct clk_lookup *cl; - -@@ -550,8 +549,6 @@ int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con) - if (!cl) - return -ENOMEM; - -- if (dev) -- cl->dev_id = dev_name(dev); - cl->con_id = con; - cl->clk = clk; - -@@ -561,8 +558,8 @@ int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con) - } - - /** -- * ti_clk_register - register a TI clock to the common clock framework -- * @dev: device for this clock -+ * of_ti_clk_register - register a TI clock to the common clock framework -+ * @node: device node for this clock - * @hw: hardware clock handle - * @con: connection ID for this clock - * -@@ -570,17 +567,18 @@ int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con) - * alias for it. Returns a handle to the registered clock if successful, - * ERR_PTR value in failure. - */ --struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw, -- const char *con) -+struct clk *of_ti_clk_register(struct device_node *node, struct clk_hw *hw, -+ const char *con) - { - struct clk *clk; - int ret; - -- clk = clk_register(dev, hw); -- if (IS_ERR(clk)) -- return clk; -+ ret = of_clk_hw_register(node, hw); -+ if (ret) -+ return ERR_PTR(ret); - -- ret = ti_clk_add_alias(dev, clk, con); -+ clk = hw->clk; -+ ret = ti_clk_add_alias(clk, con); - if (ret) { - clk_unregister(clk); - return ERR_PTR(ret); -@@ -590,8 +588,8 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw, - } - - /** -- * ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework -- * @dev: device for this clock -+ * of_ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework -+ * @node: device node for this clock - * @hw: hardware clock handle - * @con: connection ID for this clock - * -@@ -600,13 +598,13 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw, - * Returns a handle to the registered clock if successful, ERR_PTR value - * in failure. - */ --struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw, -- const char *con) -+struct clk *of_ti_clk_register_omap_hw(struct device_node *node, -+ struct clk_hw *hw, const char *con) - { - struct clk *clk; - struct clk_hw_omap *oclk; - -- clk = ti_clk_register(dev, hw, con); -+ clk = of_ti_clk_register(node, hw, con); - if (IS_ERR(clk)) - return clk; - -diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c -index 57611bfb299c1..87e5624789ef6 100644 ---- a/drivers/clk/ti/clkctrl.c -+++ b/drivers/clk/ti/clkctrl.c -@@ -308,7 +308,7 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider, - init.ops = ops; - init.flags = 0; - -- clk = ti_clk_register(NULL, clk_hw, init.name); -+ clk = of_ti_clk_register(node, clk_hw, init.name); - if (IS_ERR_OR_NULL(clk)) { - ret = -EINVAL; - goto cleanup; -@@ -689,7 +689,7 @@ clkdm_found: - init.ops = &omap4_clkctrl_clk_ops; - hw->hw.init = &init; - -- clk = ti_clk_register_omap_hw(NULL, &hw->hw, init.name); -+ clk = of_ti_clk_register_omap_hw(node, &hw->hw, init.name); - if (IS_ERR_OR_NULL(clk)) - goto cleanup; - -diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h -index 37ab53339a9be..16a9f7c2280a5 100644 ---- a/drivers/clk/ti/clock.h -+++ b/drivers/clk/ti/clock.h -@@ -199,12 +199,12 @@ extern const struct omap_clkctrl_data dm816_clkctrl_data[]; - - typedef void (*ti_of_clk_init_cb_t)(void *, struct device_node *); - --struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw, -- const char *con); --struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw, -- const char *con); -+struct clk *of_ti_clk_register(struct device_node *node, struct clk_hw *hw, -+ const char *con); -+struct clk *of_ti_clk_register_omap_hw(struct device_node *node, -+ struct clk_hw *hw, const char *con); - const char *ti_dt_clk_name(struct device_node *np); --int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con); -+int ti_clk_add_alias(struct clk *clk, const char *con); - void ti_clk_add_aliases(void); - - void ti_clk_latch(struct clk_omap_reg *reg, s8 shift); -diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c -index 77b771dd050a9..b85382c370f7e 100644 ---- a/drivers/clk/ti/composite.c -+++ b/drivers/clk/ti/composite.c -@@ -176,7 +176,7 @@ static void __init _register_composite(void *user, - &ti_composite_gate_ops, 0); - - if (!IS_ERR(clk)) { -- ret = ti_clk_add_alias(NULL, clk, name); -+ ret = ti_clk_add_alias(clk, name); - if (ret) { - clk_unregister(clk); - goto cleanup; -diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c -index 488d3da60c317..5d5bb123ba949 100644 ---- a/drivers/clk/ti/divider.c -+++ b/drivers/clk/ti/divider.c -@@ -309,7 +309,6 @@ static struct clk *_register_divider(struct device_node *node, - u32 flags, - struct clk_omap_divider *div) - { -- struct clk *clk; - struct clk_init_data init; - const char *parent_name; - const char *name; -@@ -326,12 +325,7 @@ static struct clk *_register_divider(struct device_node *node, - div->hw.init = &init; - - /* register the clock */ -- clk = ti_clk_register(NULL, &div->hw, name); -- -- if (IS_ERR(clk)) -- kfree(div); -- -- return clk; -+ return of_ti_clk_register(node, &div->hw, name); - } - - int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, -diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c -index 8ed43bc6b7cc8..403ec81f561b6 100644 ---- a/drivers/clk/ti/dpll.c -+++ b/drivers/clk/ti/dpll.c -@@ -187,7 +187,7 @@ static void __init _register_dpll(void *user, - - /* register the clock */ - name = ti_dt_clk_name(node); -- clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name); -+ clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name); - - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); -@@ -259,7 +259,7 @@ static void _register_dpll_x2(struct device_node *node, - #endif - - /* register the clock */ -- clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name); -+ clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name); - - if (IS_ERR(clk)) - kfree(clk_hw); -diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c -index c80cee0f5d3d7..c102c53201686 100644 ---- a/drivers/clk/ti/fixed-factor.c -+++ b/drivers/clk/ti/fixed-factor.c -@@ -54,7 +54,7 @@ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node) - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - of_ti_clk_autoidle_setup(node); -- ti_clk_add_alias(NULL, clk, clk_name); -+ ti_clk_add_alias(clk, clk_name); - } - } - CLK_OF_DECLARE(ti_fixed_factor_clk, "ti,fixed-factor-clock", -diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c -index 307702921431d..8e477d50d0fdb 100644 ---- a/drivers/clk/ti/gate.c -+++ b/drivers/clk/ti/gate.c -@@ -85,7 +85,7 @@ static int omap36xx_gate_clk_enable_with_hsdiv_restore(struct clk_hw *hw) - return ret; - } - --static struct clk *_register_gate(struct device *dev, const char *name, -+static struct clk *_register_gate(struct device_node *node, const char *name, - const char *parent_name, unsigned long flags, - struct clk_omap_reg *reg, u8 bit_idx, - u8 clk_gate_flags, const struct clk_ops *ops, -@@ -115,7 +115,7 @@ static struct clk *_register_gate(struct device *dev, const char *name, - - init.flags = flags; - -- clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name); -+ clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name); - - if (IS_ERR(clk)) - kfree(clk_hw); -@@ -158,7 +158,7 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node, - clk_gate_flags |= INVERT_ENABLE; - - name = ti_dt_clk_name(node); -- clk = _register_gate(NULL, name, parent_name, flags, ®, -+ clk = _register_gate(node, name, parent_name, flags, ®, - enable_bit, clk_gate_flags, ops, hw_ops); - - if (!IS_ERR(clk)) -diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c -index f47beeea211e8..172301c646f85 100644 ---- a/drivers/clk/ti/interface.c -+++ b/drivers/clk/ti/interface.c -@@ -24,7 +24,8 @@ static const struct clk_ops ti_interface_clk_ops = { - .is_enabled = &omap2_dflt_clk_is_enabled, - }; - --static struct clk *_register_interface(struct device *dev, const char *name, -+static struct clk *_register_interface(struct device_node *node, -+ const char *name, - const char *parent_name, - struct clk_omap_reg *reg, u8 bit_idx, - const struct clk_hw_omap_ops *ops) -@@ -49,7 +50,7 @@ static struct clk *_register_interface(struct device *dev, const char *name, - init.num_parents = 1; - init.parent_names = &parent_name; - -- clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name); -+ clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name); - - if (IS_ERR(clk)) - kfree(clk_hw); -@@ -80,7 +81,7 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node, - } - - name = ti_dt_clk_name(node); -- clk = _register_interface(NULL, name, parent_name, ®, -+ clk = _register_interface(node, name, parent_name, ®, - enable_bit, ops); - - if (!IS_ERR(clk)) -diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c -index 46b45b3e8319a..1ebafa386be61 100644 ---- a/drivers/clk/ti/mux.c -+++ b/drivers/clk/ti/mux.c -@@ -118,7 +118,7 @@ const struct clk_ops ti_clk_mux_ops = { - .restore_context = clk_mux_restore_context, - }; - --static struct clk *_register_mux(struct device *dev, const char *name, -+static struct clk *_register_mux(struct device_node *node, const char *name, - const char * const *parent_names, - u8 num_parents, unsigned long flags, - struct clk_omap_reg *reg, u8 shift, u32 mask, -@@ -148,7 +148,7 @@ static struct clk *_register_mux(struct device *dev, const char *name, - mux->table = table; - mux->hw.init = &init; - -- clk = ti_clk_register(dev, &mux->hw, name); -+ clk = of_ti_clk_register(node, &mux->hw, name); - - if (IS_ERR(clk)) - kfree(mux); -@@ -207,7 +207,7 @@ static void of_mux_clk_setup(struct device_node *node) - mask = (1 << fls(mask)) - 1; - - name = ti_dt_clk_name(node); -- clk = _register_mux(NULL, name, parent_names, num_parents, -+ clk = _register_mux(node, name, parent_names, num_parents, - flags, ®, shift, mask, latch, clk_mux_flags, - NULL); - -diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c -index 239c70ac120e8..fee1c4bf10214 100644 ---- a/drivers/clocksource/arm_arch_timer.c -+++ b/drivers/clocksource/arm_arch_timer.c -@@ -817,8 +817,9 @@ static u64 __arch_timer_check_delta(void) - * Note that TVAL is signed, thus has only 31 of its - * 32 bits to express magnitude. - */ -- MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, -- APM_CPU_PART_POTENZA)), -+ MIDR_REV_RANGE(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, -+ APM_CPU_PART_XGENE), -+ APM_CPU_VAR_POTENZA, 0x0, 0xf), - {}, - }; - -diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c -index 00af1a8e34fbd..ec86aecb748f1 100644 ---- a/drivers/clocksource/timer-ti-dm.c -+++ b/drivers/clocksource/timer-ti-dm.c -@@ -141,6 +141,8 @@ struct dmtimer { - struct platform_device *pdev; - struct list_head node; - struct notifier_block nb; -+ struct notifier_block fclk_nb; -+ unsigned long fclk_rate; - }; - - static u32 omap_reserved_systimers; -@@ -254,8 +256,7 @@ static inline void __omap_dm_timer_enable_posted(struct dmtimer *timer) - timer->posted = OMAP_TIMER_POSTED; - } - --static inline void __omap_dm_timer_stop(struct dmtimer *timer, -- unsigned long rate) -+static inline void __omap_dm_timer_stop(struct dmtimer *timer) - { - u32 l; - -@@ -270,7 +271,7 @@ static inline void __omap_dm_timer_stop(struct dmtimer *timer, - * Wait for functional clock period x 3.5 to make sure that - * timer is stopped - */ -- udelay(3500000 / rate + 1); -+ udelay(3500000 / timer->fclk_rate + 1); - #endif - } - -@@ -349,6 +350,21 @@ static int omap_timer_context_notifier(struct notifier_block *nb, - return NOTIFY_OK; - } - -+static int omap_timer_fclk_notifier(struct notifier_block *nb, -+ unsigned long event, void *data) -+{ -+ struct clk_notifier_data *clk_data = data; -+ struct dmtimer *timer = container_of(nb, struct dmtimer, fclk_nb); -+ -+ switch (event) { -+ case POST_RATE_CHANGE: -+ timer->fclk_rate = clk_data->new_rate; -+ return NOTIFY_OK; -+ default: -+ return NOTIFY_DONE; -+ } -+} -+ - static int omap_dm_timer_reset(struct dmtimer *timer) - { - u32 l, timeout = 100000; -@@ -742,7 +758,6 @@ static int omap_dm_timer_stop(struct omap_dm_timer *cookie) - { - struct dmtimer *timer; - struct device *dev; -- unsigned long rate = 0; - - timer = to_dmtimer(cookie); - if (unlikely(!timer)) -@@ -750,10 +765,7 @@ static int omap_dm_timer_stop(struct omap_dm_timer *cookie) - - dev = &timer->pdev->dev; - -- if (!timer->omap1) -- rate = clk_get_rate(timer->fclk); -- -- __omap_dm_timer_stop(timer, rate); -+ __omap_dm_timer_stop(timer); - - pm_runtime_put_sync(dev); - -@@ -1112,6 +1124,14 @@ static int omap_dm_timer_probe(struct platform_device *pdev) - timer->fclk = devm_clk_get(dev, "fck"); - if (IS_ERR(timer->fclk)) - return PTR_ERR(timer->fclk); -+ -+ timer->fclk_nb.notifier_call = omap_timer_fclk_notifier; -+ ret = devm_clk_notifier_register(dev, timer->fclk, -+ &timer->fclk_nb); -+ if (ret) -+ return ret; -+ -+ timer->fclk_rate = clk_get_rate(timer->fclk); - } else { - timer->fclk = ERR_PTR(-ENODEV); - } -diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c -index d3d8bb0a69900..e156238b4da90 100644 ---- a/drivers/crypto/caam/caamalg.c -+++ b/drivers/crypto/caam/caamalg.c -@@ -566,7 +566,8 @@ static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, - if (keylen != CHACHA_KEY_SIZE + saltlen) - return -EINVAL; - -- ctx->cdata.key_virt = key; -+ memcpy(ctx->key, key, keylen); -+ ctx->cdata.key_virt = ctx->key; - ctx->cdata.keylen = keylen - saltlen; - - return chachapoly_set_sh_desc(aead); -diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c -index 4482cb145d051..56058d4992cc4 100644 ---- a/drivers/crypto/caam/caamalg_qi2.c -+++ b/drivers/crypto/caam/caamalg_qi2.c -@@ -639,7 +639,8 @@ static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, - if (keylen != CHACHA_KEY_SIZE + saltlen) - return -EINVAL; - -- ctx->cdata.key_virt = key; -+ memcpy(ctx->key, key, keylen); -+ ctx->cdata.key_virt = ctx->key; - ctx->cdata.keylen = keylen - saltlen; - - return chachapoly_set_sh_desc(aead); -diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c -index 3e583f0324874..b8e02c3a19610 100644 ---- a/drivers/crypto/ccp/sev-dev.c -+++ b/drivers/crypto/ccp/sev-dev.c -@@ -443,10 +443,10 @@ static int __sev_init_ex_locked(int *error) - - static int __sev_platform_init_locked(int *error) - { -+ int rc = 0, psp_ret = SEV_RET_NO_FW_CALL; - struct psp_device *psp = psp_master; -- struct sev_device *sev; -- int rc = 0, psp_ret = -1; - int (*init_function)(int *error); -+ struct sev_device *sev; - - if (!psp || !psp->sev_data) - return -ENODEV; -@@ -474,9 +474,11 @@ static int __sev_platform_init_locked(int *error) - * initialization function should succeed by replacing the state - * with a reset state. - */ -- dev_err(sev->dev, "SEV: retrying INIT command because of SECURE_DATA_INVALID error. Retrying once to reset PSP SEV state."); -+ dev_err(sev->dev, -+"SEV: retrying INIT command because of SECURE_DATA_INVALID error. Retrying once to reset PSP SEV state."); - rc = init_function(&psp_ret); - } -+ - if (error) - *error = psp_ret; - -diff --git a/drivers/crypto/hisilicon/Makefile b/drivers/crypto/hisilicon/Makefile -index 1e89269a2e4b0..8595a5a5d2288 100644 ---- a/drivers/crypto/hisilicon/Makefile -+++ b/drivers/crypto/hisilicon/Makefile -@@ -3,6 +3,6 @@ obj-$(CONFIG_CRYPTO_DEV_HISI_HPRE) += hpre/ - obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += sec/ - obj-$(CONFIG_CRYPTO_DEV_HISI_SEC2) += sec2/ - obj-$(CONFIG_CRYPTO_DEV_HISI_QM) += hisi_qm.o --hisi_qm-objs = qm.o sgl.o -+hisi_qm-objs = qm.o sgl.o debugfs.o - obj-$(CONFIG_CRYPTO_DEV_HISI_ZIP) += zip/ - obj-$(CONFIG_CRYPTO_DEV_HISI_TRNG) += trng/ -diff --git a/drivers/crypto/hisilicon/debugfs.c b/drivers/crypto/hisilicon/debugfs.c -new file mode 100644 -index 0000000000000..13bec8b2d7237 ---- /dev/null -+++ b/drivers/crypto/hisilicon/debugfs.c -@@ -0,0 +1,1097 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Copyright (c) 2022 HiSilicon Limited. */ -+#include -+#include "qm_common.h" -+ -+#define QM_DFX_BASE 0x0100000 -+#define QM_DFX_STATE1 0x0104000 -+#define QM_DFX_STATE2 0x01040C8 -+#define QM_DFX_COMMON 0x0000 -+#define QM_DFX_BASE_LEN 0x5A -+#define QM_DFX_STATE1_LEN 0x2E -+#define QM_DFX_STATE2_LEN 0x11 -+#define QM_DFX_COMMON_LEN 0xC3 -+#define QM_DFX_REGS_LEN 4UL -+#define QM_DBG_TMP_BUF_LEN 22 -+#define CURRENT_FUN_MASK GENMASK(5, 0) -+#define CURRENT_Q_MASK GENMASK(31, 16) -+#define QM_SQE_ADDR_MASK GENMASK(7, 0) -+ -+#define QM_DFX_MB_CNT_VF 0x104010 -+#define QM_DFX_DB_CNT_VF 0x104020 -+#define QM_DFX_SQE_CNT_VF_SQN 0x104030 -+#define QM_DFX_CQE_CNT_VF_CQN 0x104040 -+#define QM_DFX_QN_SHIFT 16 -+#define QM_DFX_CNT_CLR_CE 0x100118 -+#define QM_DBG_WRITE_LEN 1024 -+ -+static const char * const qm_debug_file_name[] = { -+ [CURRENT_QM] = "current_qm", -+ [CURRENT_Q] = "current_q", -+ [CLEAR_ENABLE] = "clear_enable", -+}; -+ -+struct qm_dfx_item { -+ const char *name; -+ u32 offset; -+}; -+ -+static struct qm_dfx_item qm_dfx_files[] = { -+ {"err_irq", offsetof(struct qm_dfx, err_irq_cnt)}, -+ {"aeq_irq", offsetof(struct qm_dfx, aeq_irq_cnt)}, -+ {"abnormal_irq", offsetof(struct qm_dfx, abnormal_irq_cnt)}, -+ {"create_qp_err", offsetof(struct qm_dfx, create_qp_err_cnt)}, -+ {"mb_err", offsetof(struct qm_dfx, mb_err_cnt)}, -+}; -+ -+#define CNT_CYC_REGS_NUM 10 -+static const struct debugfs_reg32 qm_dfx_regs[] = { -+ /* XXX_CNT are reading clear register */ -+ {"QM_ECC_1BIT_CNT ", 0x104000ull}, -+ {"QM_ECC_MBIT_CNT ", 0x104008ull}, -+ {"QM_DFX_MB_CNT ", 0x104018ull}, -+ {"QM_DFX_DB_CNT ", 0x104028ull}, -+ {"QM_DFX_SQE_CNT ", 0x104038ull}, -+ {"QM_DFX_CQE_CNT ", 0x104048ull}, -+ {"QM_DFX_SEND_SQE_TO_ACC_CNT ", 0x104050ull}, -+ {"QM_DFX_WB_SQE_FROM_ACC_CNT ", 0x104058ull}, -+ {"QM_DFX_ACC_FINISH_CNT ", 0x104060ull}, -+ {"QM_DFX_CQE_ERR_CNT ", 0x1040b4ull}, -+ {"QM_DFX_FUNS_ACTIVE_ST ", 0x200ull}, -+ {"QM_ECC_1BIT_INF ", 0x104004ull}, -+ {"QM_ECC_MBIT_INF ", 0x10400cull}, -+ {"QM_DFX_ACC_RDY_VLD0 ", 0x1040a0ull}, -+ {"QM_DFX_ACC_RDY_VLD1 ", 0x1040a4ull}, -+ {"QM_DFX_AXI_RDY_VLD ", 0x1040a8ull}, -+ {"QM_DFX_FF_ST0 ", 0x1040c8ull}, -+ {"QM_DFX_FF_ST1 ", 0x1040ccull}, -+ {"QM_DFX_FF_ST2 ", 0x1040d0ull}, -+ {"QM_DFX_FF_ST3 ", 0x1040d4ull}, -+ {"QM_DFX_FF_ST4 ", 0x1040d8ull}, -+ {"QM_DFX_FF_ST5 ", 0x1040dcull}, -+ {"QM_DFX_FF_ST6 ", 0x1040e0ull}, -+ {"QM_IN_IDLE_ST ", 0x1040e4ull}, -+}; -+ -+static const struct debugfs_reg32 qm_vf_dfx_regs[] = { -+ {"QM_DFX_FUNS_ACTIVE_ST ", 0x200ull}, -+}; -+ -+/* define the QM's dfx regs region and region length */ -+static struct dfx_diff_registers qm_diff_regs[] = { -+ { -+ .reg_offset = QM_DFX_BASE, -+ .reg_len = QM_DFX_BASE_LEN, -+ }, { -+ .reg_offset = QM_DFX_STATE1, -+ .reg_len = QM_DFX_STATE1_LEN, -+ }, { -+ .reg_offset = QM_DFX_STATE2, -+ .reg_len = QM_DFX_STATE2_LEN, -+ }, { -+ .reg_offset = QM_DFX_COMMON, -+ .reg_len = QM_DFX_COMMON_LEN, -+ }, -+}; -+ -+static struct hisi_qm *file_to_qm(struct debugfs_file *file) -+{ -+ struct qm_debug *debug = file->debug; -+ -+ return container_of(debug, struct hisi_qm, debug); -+} -+ -+static ssize_t qm_cmd_read(struct file *filp, char __user *buffer, -+ size_t count, loff_t *pos) -+{ -+ char buf[QM_DBG_READ_LEN]; -+ int len; -+ -+ len = scnprintf(buf, QM_DBG_READ_LEN, "%s\n", -+ "Please echo help to cmd to get help information"); -+ -+ return simple_read_from_buffer(buffer, count, pos, buf, len); -+} -+ -+static void dump_show(struct hisi_qm *qm, void *info, -+ unsigned int info_size, char *info_name) -+{ -+ struct device *dev = &qm->pdev->dev; -+ u8 *info_curr = info; -+ u32 i; -+#define BYTE_PER_DW 4 -+ -+ dev_info(dev, "%s DUMP\n", info_name); -+ for (i = 0; i < info_size; i += BYTE_PER_DW, info_curr += BYTE_PER_DW) { -+ pr_info("DW%u: %02X%02X %02X%02X\n", i / BYTE_PER_DW, -+ *(info_curr + 3), *(info_curr + 2), *(info_curr + 1), *(info_curr)); -+ } -+} -+ -+static int qm_sqc_dump(struct hisi_qm *qm, const char *s) -+{ -+ struct device *dev = &qm->pdev->dev; -+ struct qm_sqc *sqc, *sqc_curr; -+ dma_addr_t sqc_dma; -+ u32 qp_id; -+ int ret; -+ -+ if (!s) -+ return -EINVAL; -+ -+ ret = kstrtou32(s, 0, &qp_id); -+ if (ret || qp_id >= qm->qp_num) { -+ dev_err(dev, "Please input qp num (0-%u)", qm->qp_num - 1); -+ return -EINVAL; -+ } -+ -+ sqc = hisi_qm_ctx_alloc(qm, sizeof(*sqc), &sqc_dma); -+ if (IS_ERR(sqc)) -+ return PTR_ERR(sqc); -+ -+ ret = hisi_qm_mb(qm, QM_MB_CMD_SQC, sqc_dma, qp_id, 1); -+ if (ret) { -+ down_read(&qm->qps_lock); -+ if (qm->sqc) { -+ sqc_curr = qm->sqc + qp_id; -+ -+ dump_show(qm, sqc_curr, sizeof(*sqc), "SOFT SQC"); -+ } -+ up_read(&qm->qps_lock); -+ -+ goto free_ctx; -+ } -+ -+ dump_show(qm, sqc, sizeof(*sqc), "SQC"); -+ -+free_ctx: -+ hisi_qm_ctx_free(qm, sizeof(*sqc), sqc, &sqc_dma); -+ return 0; -+} -+ -+static int qm_cqc_dump(struct hisi_qm *qm, const char *s) -+{ -+ struct device *dev = &qm->pdev->dev; -+ struct qm_cqc *cqc, *cqc_curr; -+ dma_addr_t cqc_dma; -+ u32 qp_id; -+ int ret; -+ -+ if (!s) -+ return -EINVAL; -+ -+ ret = kstrtou32(s, 0, &qp_id); -+ if (ret || qp_id >= qm->qp_num) { -+ dev_err(dev, "Please input qp num (0-%u)", qm->qp_num - 1); -+ return -EINVAL; -+ } -+ -+ cqc = hisi_qm_ctx_alloc(qm, sizeof(*cqc), &cqc_dma); -+ if (IS_ERR(cqc)) -+ return PTR_ERR(cqc); -+ -+ ret = hisi_qm_mb(qm, QM_MB_CMD_CQC, cqc_dma, qp_id, 1); -+ if (ret) { -+ down_read(&qm->qps_lock); -+ if (qm->cqc) { -+ cqc_curr = qm->cqc + qp_id; -+ -+ dump_show(qm, cqc_curr, sizeof(*cqc), "SOFT CQC"); -+ } -+ up_read(&qm->qps_lock); -+ -+ goto free_ctx; -+ } -+ -+ dump_show(qm, cqc, sizeof(*cqc), "CQC"); -+ -+free_ctx: -+ hisi_qm_ctx_free(qm, sizeof(*cqc), cqc, &cqc_dma); -+ return 0; -+} -+ -+static int qm_eqc_aeqc_dump(struct hisi_qm *qm, char *s, size_t size, -+ int cmd, char *name) -+{ -+ struct device *dev = &qm->pdev->dev; -+ dma_addr_t xeqc_dma; -+ void *xeqc; -+ int ret; -+ -+ if (strsep(&s, " ")) { -+ dev_err(dev, "Please do not input extra characters!\n"); -+ return -EINVAL; -+ } -+ -+ xeqc = hisi_qm_ctx_alloc(qm, size, &xeqc_dma); -+ if (IS_ERR(xeqc)) -+ return PTR_ERR(xeqc); -+ -+ ret = hisi_qm_mb(qm, cmd, xeqc_dma, 0, 1); -+ if (ret) -+ goto err_free_ctx; -+ -+ dump_show(qm, xeqc, size, name); -+ -+err_free_ctx: -+ hisi_qm_ctx_free(qm, size, xeqc, &xeqc_dma); -+ return ret; -+} -+ -+static int q_dump_param_parse(struct hisi_qm *qm, char *s, -+ u32 *e_id, u32 *q_id, u16 q_depth) -+{ -+ struct device *dev = &qm->pdev->dev; -+ unsigned int qp_num = qm->qp_num; -+ char *presult; -+ int ret; -+ -+ presult = strsep(&s, " "); -+ if (!presult) { -+ dev_err(dev, "Please input qp number!\n"); -+ return -EINVAL; -+ } -+ -+ ret = kstrtou32(presult, 0, q_id); -+ if (ret || *q_id >= qp_num) { -+ dev_err(dev, "Please input qp num (0-%u)", qp_num - 1); -+ return -EINVAL; -+ } -+ -+ presult = strsep(&s, " "); -+ if (!presult) { -+ dev_err(dev, "Please input sqe number!\n"); -+ return -EINVAL; -+ } -+ -+ ret = kstrtou32(presult, 0, e_id); -+ if (ret || *e_id >= q_depth) { -+ dev_err(dev, "Please input sqe num (0-%u)", q_depth - 1); -+ return -EINVAL; -+ } -+ -+ if (strsep(&s, " ")) { -+ dev_err(dev, "Please do not input extra characters!\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int qm_sq_dump(struct hisi_qm *qm, char *s) -+{ -+ u16 sq_depth = qm->qp_array->cq_depth; -+ void *sqe, *sqe_curr; -+ struct hisi_qp *qp; -+ u32 qp_id, sqe_id; -+ int ret; -+ -+ ret = q_dump_param_parse(qm, s, &sqe_id, &qp_id, sq_depth); -+ if (ret) -+ return ret; -+ -+ sqe = kzalloc(qm->sqe_size * sq_depth, GFP_KERNEL); -+ if (!sqe) -+ return -ENOMEM; -+ -+ qp = &qm->qp_array[qp_id]; -+ memcpy(sqe, qp->sqe, qm->sqe_size * sq_depth); -+ sqe_curr = sqe + (u32)(sqe_id * qm->sqe_size); -+ memset(sqe_curr + qm->debug.sqe_mask_offset, QM_SQE_ADDR_MASK, -+ qm->debug.sqe_mask_len); -+ -+ dump_show(qm, sqe_curr, qm->sqe_size, "SQE"); -+ -+ kfree(sqe); -+ -+ return 0; -+} -+ -+static int qm_cq_dump(struct hisi_qm *qm, char *s) -+{ -+ struct qm_cqe *cqe_curr; -+ struct hisi_qp *qp; -+ u32 qp_id, cqe_id; -+ int ret; -+ -+ ret = q_dump_param_parse(qm, s, &cqe_id, &qp_id, qm->qp_array->cq_depth); -+ if (ret) -+ return ret; -+ -+ qp = &qm->qp_array[qp_id]; -+ cqe_curr = qp->cqe + cqe_id; -+ dump_show(qm, cqe_curr, sizeof(struct qm_cqe), "CQE"); -+ -+ return 0; -+} -+ -+static int qm_eq_aeq_dump(struct hisi_qm *qm, const char *s, -+ size_t size, char *name) -+{ -+ struct device *dev = &qm->pdev->dev; -+ void *xeqe; -+ u32 xeqe_id; -+ int ret; -+ -+ if (!s) -+ return -EINVAL; -+ -+ ret = kstrtou32(s, 0, &xeqe_id); -+ if (ret) -+ return -EINVAL; -+ -+ if (!strcmp(name, "EQE") && xeqe_id >= qm->eq_depth) { -+ dev_err(dev, "Please input eqe num (0-%u)", qm->eq_depth - 1); -+ return -EINVAL; -+ } else if (!strcmp(name, "AEQE") && xeqe_id >= qm->aeq_depth) { -+ dev_err(dev, "Please input aeqe num (0-%u)", qm->eq_depth - 1); -+ return -EINVAL; -+ } -+ -+ down_read(&qm->qps_lock); -+ -+ if (qm->eqe && !strcmp(name, "EQE")) { -+ xeqe = qm->eqe + xeqe_id; -+ } else if (qm->aeqe && !strcmp(name, "AEQE")) { -+ xeqe = qm->aeqe + xeqe_id; -+ } else { -+ ret = -EINVAL; -+ goto err_unlock; -+ } -+ -+ dump_show(qm, xeqe, size, name); -+ -+err_unlock: -+ up_read(&qm->qps_lock); -+ return ret; -+} -+ -+static int qm_dbg_help(struct hisi_qm *qm, char *s) -+{ -+ struct device *dev = &qm->pdev->dev; -+ -+ if (strsep(&s, " ")) { -+ dev_err(dev, "Please do not input extra characters!\n"); -+ return -EINVAL; -+ } -+ -+ dev_info(dev, "available commands:\n"); -+ dev_info(dev, "sqc \n"); -+ dev_info(dev, "cqc \n"); -+ dev_info(dev, "eqc\n"); -+ dev_info(dev, "aeqc\n"); -+ dev_info(dev, "sq \n"); -+ dev_info(dev, "cq \n"); -+ dev_info(dev, "eq \n"); -+ dev_info(dev, "aeq \n"); -+ -+ return 0; -+} -+ -+static int qm_cmd_write_dump(struct hisi_qm *qm, const char *cmd_buf) -+{ -+ struct device *dev = &qm->pdev->dev; -+ char *presult, *s, *s_tmp; -+ int ret; -+ -+ s = kstrdup(cmd_buf, GFP_KERNEL); -+ if (!s) -+ return -ENOMEM; -+ -+ s_tmp = s; -+ presult = strsep(&s, " "); -+ if (!presult) { -+ ret = -EINVAL; -+ goto err_buffer_free; -+ } -+ -+ if (!strcmp(presult, "sqc")) -+ ret = qm_sqc_dump(qm, s); -+ else if (!strcmp(presult, "cqc")) -+ ret = qm_cqc_dump(qm, s); -+ else if (!strcmp(presult, "eqc")) -+ ret = qm_eqc_aeqc_dump(qm, s, sizeof(struct qm_eqc), -+ QM_MB_CMD_EQC, "EQC"); -+ else if (!strcmp(presult, "aeqc")) -+ ret = qm_eqc_aeqc_dump(qm, s, sizeof(struct qm_aeqc), -+ QM_MB_CMD_AEQC, "AEQC"); -+ else if (!strcmp(presult, "sq")) -+ ret = qm_sq_dump(qm, s); -+ else if (!strcmp(presult, "cq")) -+ ret = qm_cq_dump(qm, s); -+ else if (!strcmp(presult, "eq")) -+ ret = qm_eq_aeq_dump(qm, s, sizeof(struct qm_eqe), "EQE"); -+ else if (!strcmp(presult, "aeq")) -+ ret = qm_eq_aeq_dump(qm, s, sizeof(struct qm_aeqe), "AEQE"); -+ else if (!strcmp(presult, "help")) -+ ret = qm_dbg_help(qm, s); -+ else -+ ret = -EINVAL; -+ -+ if (ret) -+ dev_info(dev, "Please echo help\n"); -+ -+err_buffer_free: -+ kfree(s_tmp); -+ -+ return ret; -+} -+ -+static ssize_t qm_cmd_write(struct file *filp, const char __user *buffer, -+ size_t count, loff_t *pos) -+{ -+ struct hisi_qm *qm = filp->private_data; -+ char *cmd_buf, *cmd_buf_tmp; -+ int ret; -+ -+ if (*pos) -+ return 0; -+ -+ ret = hisi_qm_get_dfx_access(qm); -+ if (ret) -+ return ret; -+ -+ /* Judge if the instance is being reset. */ -+ if (unlikely(atomic_read(&qm->status.flags) == QM_STOP)) { -+ ret = 0; -+ goto put_dfx_access; -+ } -+ -+ if (count > QM_DBG_WRITE_LEN) { -+ ret = -ENOSPC; -+ goto put_dfx_access; -+ } -+ -+ cmd_buf = memdup_user_nul(buffer, count); -+ if (IS_ERR(cmd_buf)) { -+ ret = PTR_ERR(cmd_buf); -+ goto put_dfx_access; -+ } -+ -+ cmd_buf_tmp = strchr(cmd_buf, '\n'); -+ if (cmd_buf_tmp) { -+ *cmd_buf_tmp = '\0'; -+ count = cmd_buf_tmp - cmd_buf + 1; -+ } -+ -+ ret = qm_cmd_write_dump(qm, cmd_buf); -+ if (ret) { -+ kfree(cmd_buf); -+ goto put_dfx_access; -+ } -+ -+ kfree(cmd_buf); -+ -+ ret = count; -+ -+put_dfx_access: -+ hisi_qm_put_dfx_access(qm); -+ return ret; -+} -+ -+static const struct file_operations qm_cmd_fops = { -+ .owner = THIS_MODULE, -+ .open = simple_open, -+ .read = qm_cmd_read, -+ .write = qm_cmd_write, -+}; -+ -+/** -+ * hisi_qm_regs_dump() - Dump registers's value. -+ * @s: debugfs file handle. -+ * @regset: accelerator registers information. -+ * -+ * Dump accelerator registers. -+ */ -+void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset) -+{ -+ struct pci_dev *pdev = to_pci_dev(regset->dev); -+ struct hisi_qm *qm = pci_get_drvdata(pdev); -+ const struct debugfs_reg32 *regs = regset->regs; -+ int regs_len = regset->nregs; -+ int i, ret; -+ u32 val; -+ -+ ret = hisi_qm_get_dfx_access(qm); -+ if (ret) -+ return; -+ -+ for (i = 0; i < regs_len; i++) { -+ val = readl(regset->base + regs[i].offset); -+ seq_printf(s, "%s= 0x%08x\n", regs[i].name, val); -+ } -+ -+ hisi_qm_put_dfx_access(qm); -+} -+EXPORT_SYMBOL_GPL(hisi_qm_regs_dump); -+ -+static int qm_regs_show(struct seq_file *s, void *unused) -+{ -+ struct hisi_qm *qm = s->private; -+ struct debugfs_regset32 regset; -+ -+ if (qm->fun_type == QM_HW_PF) { -+ regset.regs = qm_dfx_regs; -+ regset.nregs = ARRAY_SIZE(qm_dfx_regs); -+ } else { -+ regset.regs = qm_vf_dfx_regs; -+ regset.nregs = ARRAY_SIZE(qm_vf_dfx_regs); -+ } -+ -+ regset.base = qm->io_base; -+ regset.dev = &qm->pdev->dev; -+ -+ hisi_qm_regs_dump(s, ®set); -+ -+ return 0; -+} -+ -+DEFINE_SHOW_ATTRIBUTE(qm_regs); -+ -+static u32 current_q_read(struct hisi_qm *qm) -+{ -+ return readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) >> QM_DFX_QN_SHIFT; -+} -+ -+static int current_q_write(struct hisi_qm *qm, u32 val) -+{ -+ u32 tmp; -+ -+ if (val >= qm->debug.curr_qm_qp_num) -+ return -EINVAL; -+ -+ tmp = val << QM_DFX_QN_SHIFT | -+ (readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) & CURRENT_FUN_MASK); -+ writel(tmp, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); -+ -+ tmp = val << QM_DFX_QN_SHIFT | -+ (readl(qm->io_base + QM_DFX_CQE_CNT_VF_CQN) & CURRENT_FUN_MASK); -+ writel(tmp, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); -+ -+ return 0; -+} -+ -+static u32 clear_enable_read(struct hisi_qm *qm) -+{ -+ return readl(qm->io_base + QM_DFX_CNT_CLR_CE); -+} -+ -+/* rd_clr_ctrl 1 enable read clear, otherwise 0 disable it */ -+static int clear_enable_write(struct hisi_qm *qm, u32 rd_clr_ctrl) -+{ -+ if (rd_clr_ctrl > 1) -+ return -EINVAL; -+ -+ writel(rd_clr_ctrl, qm->io_base + QM_DFX_CNT_CLR_CE); -+ -+ return 0; -+} -+ -+static u32 current_qm_read(struct hisi_qm *qm) -+{ -+ return readl(qm->io_base + QM_DFX_MB_CNT_VF); -+} -+ -+static int qm_get_vf_qp_num(struct hisi_qm *qm, u32 fun_num) -+{ -+ u32 remain_q_num, vfq_num; -+ u32 num_vfs = qm->vfs_num; -+ -+ vfq_num = (qm->ctrl_qp_num - qm->qp_num) / num_vfs; -+ if (vfq_num >= qm->max_qp_num) -+ return qm->max_qp_num; -+ -+ remain_q_num = (qm->ctrl_qp_num - qm->qp_num) % num_vfs; -+ if (vfq_num + remain_q_num <= qm->max_qp_num) -+ return fun_num == num_vfs ? vfq_num + remain_q_num : vfq_num; -+ -+ /* -+ * if vfq_num + remain_q_num > max_qp_num, the last VFs, -+ * each with one more queue. -+ */ -+ return fun_num + remain_q_num > num_vfs ? vfq_num + 1 : vfq_num; -+} -+ -+static int current_qm_write(struct hisi_qm *qm, u32 val) -+{ -+ u32 tmp; -+ -+ if (val > qm->vfs_num) -+ return -EINVAL; -+ -+ /* According PF or VF Dev ID to calculation curr_qm_qp_num and store */ -+ if (!val) -+ qm->debug.curr_qm_qp_num = qm->qp_num; -+ else -+ qm->debug.curr_qm_qp_num = qm_get_vf_qp_num(qm, val); -+ -+ writel(val, qm->io_base + QM_DFX_MB_CNT_VF); -+ writel(val, qm->io_base + QM_DFX_DB_CNT_VF); -+ -+ tmp = val | -+ (readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) & CURRENT_Q_MASK); -+ writel(tmp, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); -+ -+ tmp = val | -+ (readl(qm->io_base + QM_DFX_CQE_CNT_VF_CQN) & CURRENT_Q_MASK); -+ writel(tmp, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); -+ -+ return 0; -+} -+ -+static ssize_t qm_debug_read(struct file *filp, char __user *buf, -+ size_t count, loff_t *pos) -+{ -+ struct debugfs_file *file = filp->private_data; -+ enum qm_debug_file index = file->index; -+ struct hisi_qm *qm = file_to_qm(file); -+ char tbuf[QM_DBG_TMP_BUF_LEN]; -+ u32 val; -+ int ret; -+ -+ ret = hisi_qm_get_dfx_access(qm); -+ if (ret) -+ return ret; -+ -+ mutex_lock(&file->lock); -+ switch (index) { -+ case CURRENT_QM: -+ val = current_qm_read(qm); -+ break; -+ case CURRENT_Q: -+ val = current_q_read(qm); -+ break; -+ case CLEAR_ENABLE: -+ val = clear_enable_read(qm); -+ break; -+ default: -+ goto err_input; -+ } -+ mutex_unlock(&file->lock); -+ -+ hisi_qm_put_dfx_access(qm); -+ ret = scnprintf(tbuf, QM_DBG_TMP_BUF_LEN, "%u\n", val); -+ return simple_read_from_buffer(buf, count, pos, tbuf, ret); -+ -+err_input: -+ mutex_unlock(&file->lock); -+ hisi_qm_put_dfx_access(qm); -+ return -EINVAL; -+} -+ -+static ssize_t qm_debug_write(struct file *filp, const char __user *buf, -+ size_t count, loff_t *pos) -+{ -+ struct debugfs_file *file = filp->private_data; -+ enum qm_debug_file index = file->index; -+ struct hisi_qm *qm = file_to_qm(file); -+ unsigned long val; -+ char tbuf[QM_DBG_TMP_BUF_LEN]; -+ int len, ret; -+ -+ if (*pos != 0) -+ return 0; -+ -+ if (count >= QM_DBG_TMP_BUF_LEN) -+ return -ENOSPC; -+ -+ len = simple_write_to_buffer(tbuf, QM_DBG_TMP_BUF_LEN - 1, pos, buf, -+ count); -+ if (len < 0) -+ return len; -+ -+ tbuf[len] = '\0'; -+ if (kstrtoul(tbuf, 0, &val)) -+ return -EFAULT; -+ -+ ret = hisi_qm_get_dfx_access(qm); -+ if (ret) -+ return ret; -+ -+ mutex_lock(&file->lock); -+ switch (index) { -+ case CURRENT_QM: -+ ret = current_qm_write(qm, val); -+ break; -+ case CURRENT_Q: -+ ret = current_q_write(qm, val); -+ break; -+ case CLEAR_ENABLE: -+ ret = clear_enable_write(qm, val); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ mutex_unlock(&file->lock); -+ -+ hisi_qm_put_dfx_access(qm); -+ -+ if (ret) -+ return ret; -+ -+ return count; -+} -+ -+static const struct file_operations qm_debug_fops = { -+ .owner = THIS_MODULE, -+ .open = simple_open, -+ .read = qm_debug_read, -+ .write = qm_debug_write, -+}; -+ -+static void dfx_regs_uninit(struct hisi_qm *qm, -+ struct dfx_diff_registers *dregs, int reg_len) -+{ -+ int i; -+ -+ /* Setting the pointer is NULL to prevent double free */ -+ for (i = 0; i < reg_len; i++) { -+ kfree(dregs[i].regs); -+ dregs[i].regs = NULL; -+ } -+ kfree(dregs); -+} -+ -+static struct dfx_diff_registers *dfx_regs_init(struct hisi_qm *qm, -+ const struct dfx_diff_registers *cregs, u32 reg_len) -+{ -+ struct dfx_diff_registers *diff_regs; -+ u32 j, base_offset; -+ int i; -+ -+ diff_regs = kcalloc(reg_len, sizeof(*diff_regs), GFP_KERNEL); -+ if (!diff_regs) -+ return ERR_PTR(-ENOMEM); -+ -+ for (i = 0; i < reg_len; i++) { -+ if (!cregs[i].reg_len) -+ continue; -+ -+ diff_regs[i].reg_offset = cregs[i].reg_offset; -+ diff_regs[i].reg_len = cregs[i].reg_len; -+ diff_regs[i].regs = kcalloc(QM_DFX_REGS_LEN, cregs[i].reg_len, -+ GFP_KERNEL); -+ if (!diff_regs[i].regs) -+ goto alloc_error; -+ -+ for (j = 0; j < diff_regs[i].reg_len; j++) { -+ base_offset = diff_regs[i].reg_offset + -+ j * QM_DFX_REGS_LEN; -+ diff_regs[i].regs[j] = readl(qm->io_base + base_offset); -+ } -+ } -+ -+ return diff_regs; -+ -+alloc_error: -+ while (i > 0) { -+ i--; -+ kfree(diff_regs[i].regs); -+ } -+ kfree(diff_regs); -+ return ERR_PTR(-ENOMEM); -+} -+ -+static int qm_diff_regs_init(struct hisi_qm *qm, -+ struct dfx_diff_registers *dregs, u32 reg_len) -+{ -+ qm->debug.qm_diff_regs = dfx_regs_init(qm, qm_diff_regs, ARRAY_SIZE(qm_diff_regs)); -+ if (IS_ERR(qm->debug.qm_diff_regs)) -+ return PTR_ERR(qm->debug.qm_diff_regs); -+ -+ qm->debug.acc_diff_regs = dfx_regs_init(qm, dregs, reg_len); -+ if (IS_ERR(qm->debug.acc_diff_regs)) { -+ dfx_regs_uninit(qm, qm->debug.qm_diff_regs, ARRAY_SIZE(qm_diff_regs)); -+ return PTR_ERR(qm->debug.acc_diff_regs); -+ } -+ -+ return 0; -+} -+ -+static void qm_last_regs_uninit(struct hisi_qm *qm) -+{ -+ struct qm_debug *debug = &qm->debug; -+ -+ if (qm->fun_type == QM_HW_VF || !debug->qm_last_words) -+ return; -+ -+ kfree(debug->qm_last_words); -+ debug->qm_last_words = NULL; -+} -+ -+static int qm_last_regs_init(struct hisi_qm *qm) -+{ -+ int dfx_regs_num = ARRAY_SIZE(qm_dfx_regs); -+ struct qm_debug *debug = &qm->debug; -+ int i; -+ -+ if (qm->fun_type == QM_HW_VF) -+ return 0; -+ -+ debug->qm_last_words = kcalloc(dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); -+ if (!debug->qm_last_words) -+ return -ENOMEM; -+ -+ for (i = 0; i < dfx_regs_num; i++) { -+ debug->qm_last_words[i] = readl_relaxed(qm->io_base + -+ qm_dfx_regs[i].offset); -+ } -+ -+ return 0; -+} -+ -+static void qm_diff_regs_uninit(struct hisi_qm *qm, u32 reg_len) -+{ -+ dfx_regs_uninit(qm, qm->debug.acc_diff_regs, reg_len); -+ dfx_regs_uninit(qm, qm->debug.qm_diff_regs, ARRAY_SIZE(qm_diff_regs)); -+} -+ -+/** -+ * hisi_qm_regs_debugfs_init() - Allocate memory for registers. -+ * @qm: device qm handle. -+ * @dregs: diff registers handle. -+ * @reg_len: diff registers region length. -+ */ -+int hisi_qm_regs_debugfs_init(struct hisi_qm *qm, -+ struct dfx_diff_registers *dregs, u32 reg_len) -+{ -+ int ret; -+ -+ if (!qm || !dregs) -+ return -EINVAL; -+ -+ if (qm->fun_type != QM_HW_PF) -+ return 0; -+ -+ ret = qm_last_regs_init(qm); -+ if (ret) { -+ dev_info(&qm->pdev->dev, "failed to init qm words memory!\n"); -+ return ret; -+ } -+ -+ ret = qm_diff_regs_init(qm, dregs, reg_len); -+ if (ret) { -+ qm_last_regs_uninit(qm); -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(hisi_qm_regs_debugfs_init); -+ -+/** -+ * hisi_qm_regs_debugfs_uninit() - Free memory for registers. -+ * @qm: device qm handle. -+ * @reg_len: diff registers region length. -+ */ -+void hisi_qm_regs_debugfs_uninit(struct hisi_qm *qm, u32 reg_len) -+{ -+ if (!qm || qm->fun_type != QM_HW_PF) -+ return; -+ -+ qm_diff_regs_uninit(qm, reg_len); -+ qm_last_regs_uninit(qm); -+} -+EXPORT_SYMBOL_GPL(hisi_qm_regs_debugfs_uninit); -+ -+/** -+ * hisi_qm_acc_diff_regs_dump() - Dump registers's value. -+ * @qm: device qm handle. -+ * @s: Debugfs file handle. -+ * @dregs: diff registers handle. -+ * @regs_len: diff registers region length. -+ */ -+void hisi_qm_acc_diff_regs_dump(struct hisi_qm *qm, struct seq_file *s, -+ struct dfx_diff_registers *dregs, u32 regs_len) -+{ -+ u32 j, val, base_offset; -+ int i, ret; -+ -+ if (!qm || !s || !dregs) -+ return; -+ -+ ret = hisi_qm_get_dfx_access(qm); -+ if (ret) -+ return; -+ -+ down_read(&qm->qps_lock); -+ for (i = 0; i < regs_len; i++) { -+ if (!dregs[i].reg_len) -+ continue; -+ -+ for (j = 0; j < dregs[i].reg_len; j++) { -+ base_offset = dregs[i].reg_offset + j * QM_DFX_REGS_LEN; -+ val = readl(qm->io_base + base_offset); -+ if (val != dregs[i].regs[j]) -+ seq_printf(s, "0x%08x = 0x%08x ---> 0x%08x\n", -+ base_offset, dregs[i].regs[j], val); -+ } -+ } -+ up_read(&qm->qps_lock); -+ -+ hisi_qm_put_dfx_access(qm); -+} -+EXPORT_SYMBOL_GPL(hisi_qm_acc_diff_regs_dump); -+ -+void hisi_qm_show_last_dfx_regs(struct hisi_qm *qm) -+{ -+ struct qm_debug *debug = &qm->debug; -+ struct pci_dev *pdev = qm->pdev; -+ u32 val; -+ int i; -+ -+ if (qm->fun_type == QM_HW_VF || !debug->qm_last_words) -+ return; -+ -+ for (i = 0; i < ARRAY_SIZE(qm_dfx_regs); i++) { -+ val = readl_relaxed(qm->io_base + qm_dfx_regs[i].offset); -+ if (debug->qm_last_words[i] != val) -+ pci_info(pdev, "%s \t= 0x%08x => 0x%08x\n", -+ qm_dfx_regs[i].name, debug->qm_last_words[i], val); -+ } -+} -+ -+static int qm_diff_regs_show(struct seq_file *s, void *unused) -+{ -+ struct hisi_qm *qm = s->private; -+ -+ hisi_qm_acc_diff_regs_dump(qm, s, qm->debug.qm_diff_regs, -+ ARRAY_SIZE(qm_diff_regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(qm_diff_regs); -+ -+static ssize_t qm_status_read(struct file *filp, char __user *buffer, -+ size_t count, loff_t *pos) -+{ -+ struct hisi_qm *qm = filp->private_data; -+ char buf[QM_DBG_READ_LEN]; -+ int val, len; -+ -+ val = atomic_read(&qm->status.flags); -+ len = scnprintf(buf, QM_DBG_READ_LEN, "%s\n", qm_s[val]); -+ -+ return simple_read_from_buffer(buffer, count, pos, buf, len); -+} -+ -+static const struct file_operations qm_status_fops = { -+ .owner = THIS_MODULE, -+ .open = simple_open, -+ .read = qm_status_read, -+}; -+ -+static void qm_create_debugfs_file(struct hisi_qm *qm, struct dentry *dir, -+ enum qm_debug_file index) -+{ -+ struct debugfs_file *file = qm->debug.files + index; -+ -+ debugfs_create_file(qm_debug_file_name[index], 0600, dir, file, -+ &qm_debug_fops); -+ -+ file->index = index; -+ mutex_init(&file->lock); -+ file->debug = &qm->debug; -+} -+ -+static int qm_debugfs_atomic64_set(void *data, u64 val) -+{ -+ if (val) -+ return -EINVAL; -+ -+ atomic64_set((atomic64_t *)data, 0); -+ -+ return 0; -+} -+ -+static int qm_debugfs_atomic64_get(void *data, u64 *val) -+{ -+ *val = atomic64_read((atomic64_t *)data); -+ -+ return 0; -+} -+ -+DEFINE_DEBUGFS_ATTRIBUTE(qm_atomic64_ops, qm_debugfs_atomic64_get, -+ qm_debugfs_atomic64_set, "%llu\n"); -+ -+/** -+ * hisi_qm_debug_init() - Initialize qm related debugfs files. -+ * @qm: The qm for which we want to add debugfs files. -+ * -+ * Create qm related debugfs files. -+ */ -+void hisi_qm_debug_init(struct hisi_qm *qm) -+{ -+ struct dfx_diff_registers *qm_regs = qm->debug.qm_diff_regs; -+ struct qm_dfx *dfx = &qm->debug.dfx; -+ struct dentry *qm_d; -+ void *data; -+ int i; -+ -+ qm_d = debugfs_create_dir("qm", qm->debug.debug_root); -+ qm->debug.qm_d = qm_d; -+ -+ /* only show this in PF */ -+ if (qm->fun_type == QM_HW_PF) { -+ qm_create_debugfs_file(qm, qm->debug.debug_root, CURRENT_QM); -+ for (i = CURRENT_Q; i < DEBUG_FILE_NUM; i++) -+ qm_create_debugfs_file(qm, qm->debug.qm_d, i); -+ } -+ -+ if (qm_regs) -+ debugfs_create_file("diff_regs", 0444, qm->debug.qm_d, -+ qm, &qm_diff_regs_fops); -+ -+ debugfs_create_file("regs", 0444, qm->debug.qm_d, qm, &qm_regs_fops); -+ -+ debugfs_create_file("cmd", 0600, qm->debug.qm_d, qm, &qm_cmd_fops); -+ -+ debugfs_create_file("status", 0444, qm->debug.qm_d, qm, -+ &qm_status_fops); -+ for (i = 0; i < ARRAY_SIZE(qm_dfx_files); i++) { -+ data = (atomic64_t *)((uintptr_t)dfx + qm_dfx_files[i].offset); -+ debugfs_create_file(qm_dfx_files[i].name, -+ 0644, -+ qm_d, -+ data, -+ &qm_atomic64_ops); -+ } -+ -+ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) -+ hisi_qm_set_algqos_init(qm); -+} -+EXPORT_SYMBOL_GPL(hisi_qm_debug_init); -+ -+/** -+ * hisi_qm_debug_regs_clear() - clear qm debug related registers. -+ * @qm: The qm for which we want to clear its debug registers. -+ */ -+void hisi_qm_debug_regs_clear(struct hisi_qm *qm) -+{ -+ const struct debugfs_reg32 *regs; -+ int i; -+ -+ /* clear current_qm */ -+ writel(0x0, qm->io_base + QM_DFX_MB_CNT_VF); -+ writel(0x0, qm->io_base + QM_DFX_DB_CNT_VF); -+ -+ /* clear current_q */ -+ writel(0x0, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); -+ writel(0x0, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); -+ -+ /* -+ * these registers are reading and clearing, so clear them after -+ * reading them. -+ */ -+ writel(0x1, qm->io_base + QM_DFX_CNT_CLR_CE); -+ -+ regs = qm_dfx_regs; -+ for (i = 0; i < CNT_CYC_REGS_NUM; i++) { -+ readl(qm->io_base + regs->offset); -+ regs++; -+ } -+ -+ /* clear clear_enable */ -+ writel(0x0, qm->io_base + QM_DFX_CNT_CLR_CE); -+} -+EXPORT_SYMBOL_GPL(hisi_qm_debug_regs_clear); -diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c -index baf1faec7046f..ff8a5f20a5df0 100644 ---- a/drivers/crypto/hisilicon/hpre/hpre_main.c -+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c -@@ -431,8 +431,11 @@ static u32 uacce_mode = UACCE_MODE_NOUACCE; - module_param_cb(uacce_mode, &hpre_uacce_mode_ops, &uacce_mode, 0444); - MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC); - -+static bool pf_q_num_flag; - static int pf_q_num_set(const char *val, const struct kernel_param *kp) - { -+ pf_q_num_flag = true; -+ - return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_HPRE_PF); - } - -@@ -1031,7 +1034,7 @@ static int hpre_cluster_debugfs_init(struct hisi_qm *qm) - - for (i = 0; i < clusters_num; i++) { - ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); -- if (ret < 0) -+ if (ret >= HPRE_DBGFS_VAL_MAX_LEN) - return -EINVAL; - tmp_d = debugfs_create_dir(buf, qm->debug.debug_root); - -@@ -1101,8 +1104,7 @@ static int hpre_debugfs_init(struct hisi_qm *qm) - - qm->debug.sqe_mask_offset = HPRE_SQE_MASK_OFFSET; - qm->debug.sqe_mask_len = HPRE_SQE_MASK_LEN; -- ret = hisi_qm_diff_regs_init(qm, hpre_diff_regs, -- ARRAY_SIZE(hpre_diff_regs)); -+ ret = hisi_qm_regs_debugfs_init(qm, hpre_diff_regs, ARRAY_SIZE(hpre_diff_regs)); - if (ret) { - dev_warn(dev, "Failed to init HPRE diff regs!\n"); - goto debugfs_remove; -@@ -1121,7 +1123,7 @@ static int hpre_debugfs_init(struct hisi_qm *qm) - return 0; - - failed_to_create: -- hisi_qm_diff_regs_uninit(qm, ARRAY_SIZE(hpre_diff_regs)); -+ hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(hpre_diff_regs)); - debugfs_remove: - debugfs_remove_recursive(qm->debug.debug_root); - return ret; -@@ -1129,7 +1131,7 @@ debugfs_remove: - - static void hpre_debugfs_exit(struct hisi_qm *qm) - { -- hisi_qm_diff_regs_uninit(qm, ARRAY_SIZE(hpre_diff_regs)); -+ hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(hpre_diff_regs)); - - debugfs_remove_recursive(qm->debug.debug_root); - } -@@ -1156,6 +1158,8 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - qm->qp_num = pf_q_num; - qm->debug.curr_qm_qp_num = pf_q_num; - qm->qm_list = &hpre_devices; -+ if (pf_q_num_flag) -+ set_bit(QM_MODULE_PARAM, &qm->misc_ctl); - } - - ret = hisi_qm_init(qm); -diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c -index 07e1e39a5e378..a4a3895c74181 100644 ---- a/drivers/crypto/hisilicon/qm.c -+++ b/drivers/crypto/hisilicon/qm.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include "qm_common.h" - - /* eq/aeq irq enable */ - #define QM_VF_AEQ_INT_SOURCE 0x0 -@@ -119,8 +120,6 @@ - #define QM_SQC_VFT_NUM_SHIFT_V2 45 - #define QM_SQC_VFT_NUM_MASK_v2 GENMASK(9, 0) - --#define QM_DFX_CNT_CLR_CE 0x100118 -- - #define QM_ABNORMAL_INT_SOURCE 0x100000 - #define QM_ABNORMAL_INT_MASK 0x100004 - #define QM_ABNORMAL_INT_MASK_VALUE 0x7fff -@@ -187,14 +186,6 @@ - #define QM_VF_RESET_WAIT_TIMEOUT_US \ - (QM_VF_RESET_WAIT_US * QM_VF_RESET_WAIT_CNT) - --#define QM_DFX_MB_CNT_VF 0x104010 --#define QM_DFX_DB_CNT_VF 0x104020 --#define QM_DFX_SQE_CNT_VF_SQN 0x104030 --#define QM_DFX_CQE_CNT_VF_CQN 0x104040 --#define QM_DFX_QN_SHIFT 16 --#define CURRENT_FUN_MASK GENMASK(5, 0) --#define CURRENT_Q_MASK GENMASK(31, 16) -- - #define POLL_PERIOD 10 - #define POLL_TIMEOUT 1000 - #define WAIT_PERIOD_US_MAX 200 -@@ -211,19 +202,13 @@ - #define QMC_ALIGN(sz) ALIGN(sz, 32) - - #define QM_DBG_READ_LEN 256 --#define QM_DBG_WRITE_LEN 1024 --#define QM_DBG_TMP_BUF_LEN 22 - #define QM_PCI_COMMAND_INVALID ~0 - #define QM_RESET_STOP_TX_OFFSET 1 - #define QM_RESET_STOP_RX_OFFSET 2 - - #define WAIT_PERIOD 20 - #define REMOVE_WAIT_DELAY 10 --#define QM_SQE_ADDR_MASK GENMASK(7, 0) - --#define QM_DRIVER_REMOVING 0 --#define QM_RST_SCHED 1 --#define QM_RESETTING 2 - #define QM_QOS_PARAM_NUM 2 - #define QM_QOS_VAL_NUM 1 - #define QM_QOS_BDF_PARAM_NUM 4 -@@ -250,15 +235,6 @@ - #define QM_QOS_MIN_CIR_B 100 - #define QM_QOS_MAX_CIR_U 6 - #define QM_QOS_MAX_CIR_S 11 --#define QM_DFX_BASE 0x0100000 --#define QM_DFX_STATE1 0x0104000 --#define QM_DFX_STATE2 0x01040C8 --#define QM_DFX_COMMON 0x0000 --#define QM_DFX_BASE_LEN 0x5A --#define QM_DFX_STATE1_LEN 0x2E --#define QM_DFX_STATE2_LEN 0x11 --#define QM_DFX_COMMON_LEN 0xC3 --#define QM_DFX_REGS_LEN 4UL - #define QM_AUTOSUSPEND_DELAY 3000 - - #define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \ -@@ -368,73 +344,6 @@ static const struct hisi_qm_cap_info qm_basic_info[] = { - {QM_VF_IRQ_NUM_CAP, 0x311c, 0, GENMASK(15, 0), 0x1, 0x2, 0x3}, - }; - --struct qm_cqe { -- __le32 rsvd0; -- __le16 cmd_id; -- __le16 rsvd1; -- __le16 sq_head; -- __le16 sq_num; -- __le16 rsvd2; -- __le16 w7; --}; -- --struct qm_eqe { -- __le32 dw0; --}; -- --struct qm_aeqe { -- __le32 dw0; --}; -- --struct qm_sqc { -- __le16 head; -- __le16 tail; -- __le32 base_l; -- __le32 base_h; -- __le32 dw3; -- __le16 w8; -- __le16 rsvd0; -- __le16 pasid; -- __le16 w11; -- __le16 cq_num; -- __le16 w13; -- __le32 rsvd1; --}; -- --struct qm_cqc { -- __le16 head; -- __le16 tail; -- __le32 base_l; -- __le32 base_h; -- __le32 dw3; -- __le16 w8; -- __le16 rsvd0; -- __le16 pasid; -- __le16 w11; -- __le32 dw6; -- __le32 rsvd1; --}; -- --struct qm_eqc { -- __le16 head; -- __le16 tail; -- __le32 base_l; -- __le32 base_h; -- __le32 dw3; -- __le32 rsvd[2]; -- __le32 dw6; --}; -- --struct qm_aeqc { -- __le16 head; -- __le16 tail; -- __le32 base_l; -- __le32 base_h; -- __le32 dw3; -- __le32 rsvd[2]; -- __le32 dw6; --}; -- - struct qm_mailbox { - __le16 w0; - __le16 queue_num; -@@ -467,25 +376,6 @@ struct hisi_qm_hw_ops { - int (*set_msi)(struct hisi_qm *qm, bool set); - }; - --struct qm_dfx_item { -- const char *name; -- u32 offset; --}; -- --static struct qm_dfx_item qm_dfx_files[] = { -- {"err_irq", offsetof(struct qm_dfx, err_irq_cnt)}, -- {"aeq_irq", offsetof(struct qm_dfx, aeq_irq_cnt)}, -- {"abnormal_irq", offsetof(struct qm_dfx, abnormal_irq_cnt)}, -- {"create_qp_err", offsetof(struct qm_dfx, create_qp_err_cnt)}, -- {"mb_err", offsetof(struct qm_dfx, mb_err_cnt)}, --}; -- --static const char * const qm_debug_file_name[] = { -- [CURRENT_QM] = "current_qm", -- [CURRENT_Q] = "current_q", -- [CLEAR_ENABLE] = "clear_enable", --}; -- - struct hisi_qm_hw_error { - u32 int_msk; - const char *msg; -@@ -510,23 +400,6 @@ static const struct hisi_qm_hw_error qm_hw_error[] = { - { /* sentinel */ } - }; - --/* define the QM's dfx regs region and region length */ --static struct dfx_diff_registers qm_diff_regs[] = { -- { -- .reg_offset = QM_DFX_BASE, -- .reg_len = QM_DFX_BASE_LEN, -- }, { -- .reg_offset = QM_DFX_STATE1, -- .reg_len = QM_DFX_STATE1_LEN, -- }, { -- .reg_offset = QM_DFX_STATE2, -- .reg_len = QM_DFX_STATE2_LEN, -- }, { -- .reg_offset = QM_DFX_COMMON, -- .reg_len = QM_DFX_COMMON_LEN, -- }, --}; -- - static const char * const qm_db_timeout[] = { - "sq", "cq", "eq", "aeq", - }; -@@ -535,10 +408,6 @@ static const char * const qm_fifo_overflow[] = { - "cq", "eq", "aeq", - }; - --static const char * const qm_s[] = { -- "init", "start", "close", "stop", --}; -- - static const char * const qp_s[] = { - "none", "init", "start", "stop", "close", - }; -@@ -1324,999 +1193,158 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base, - tmp = QM_CQC_VFT_VALID; - } - break; -- case SHAPER_VFT: -- if (factor) { -- tmp = factor->cir_b | -- (factor->cir_u << QM_SHAPER_FACTOR_CIR_U_SHIFT) | -- (factor->cir_s << QM_SHAPER_FACTOR_CIR_S_SHIFT) | -- (QM_SHAPER_CBS_B << QM_SHAPER_FACTOR_CBS_B_SHIFT) | -- (factor->cbs_s << QM_SHAPER_FACTOR_CBS_S_SHIFT); -- } -- break; -- } -- } -- -- writel(lower_32_bits(tmp), qm->io_base + QM_VFT_CFG_DATA_L); -- writel(upper_32_bits(tmp), qm->io_base + QM_VFT_CFG_DATA_H); --} -- --static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type, -- u32 fun_num, u32 base, u32 number) --{ -- struct qm_shaper_factor *factor = NULL; -- unsigned int val; -- int ret; -- -- if (type == SHAPER_VFT && test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) -- factor = &qm->factor[fun_num]; -- -- ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val, -- val & BIT(0), POLL_PERIOD, -- POLL_TIMEOUT); -- if (ret) -- return ret; -- -- writel(0x0, qm->io_base + QM_VFT_CFG_OP_WR); -- writel(type, qm->io_base + QM_VFT_CFG_TYPE); -- if (type == SHAPER_VFT) -- fun_num |= base << QM_SHAPER_VFT_OFFSET; -- -- writel(fun_num, qm->io_base + QM_VFT_CFG); -- -- qm_vft_data_cfg(qm, type, base, number, factor); -- -- writel(0x0, qm->io_base + QM_VFT_CFG_RDY); -- writel(0x1, qm->io_base + QM_VFT_CFG_OP_ENABLE); -- -- return readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val, -- val & BIT(0), POLL_PERIOD, -- POLL_TIMEOUT); --} -- --static int qm_shaper_init_vft(struct hisi_qm *qm, u32 fun_num) --{ -- u32 qos = qm->factor[fun_num].func_qos; -- int ret, i; -- -- ret = qm_get_shaper_para(qos * QM_QOS_RATE, &qm->factor[fun_num]); -- if (ret) { -- dev_err(&qm->pdev->dev, "failed to calculate shaper parameter!\n"); -- return ret; -- } -- writel(qm->type_rate, qm->io_base + QM_SHAPER_CFG); -- for (i = ALG_TYPE_0; i <= ALG_TYPE_1; i++) { -- /* The base number of queue reuse for different alg type */ -- ret = qm_set_vft_common(qm, SHAPER_VFT, fun_num, i, 1); -- if (ret) -- return ret; -- } -- -- return 0; --} -- --/* The config should be conducted after qm_dev_mem_reset() */ --static int qm_set_sqc_cqc_vft(struct hisi_qm *qm, u32 fun_num, u32 base, -- u32 number) --{ -- int ret, i; -- -- for (i = SQC_VFT; i <= CQC_VFT; i++) { -- ret = qm_set_vft_common(qm, i, fun_num, base, number); -- if (ret) -- return ret; -- } -- -- /* init default shaper qos val */ -- if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) { -- ret = qm_shaper_init_vft(qm, fun_num); -- if (ret) -- goto back_sqc_cqc; -- } -- -- return 0; --back_sqc_cqc: -- for (i = SQC_VFT; i <= CQC_VFT; i++) -- qm_set_vft_common(qm, i, fun_num, 0, 0); -- -- return ret; --} -- --static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number) --{ -- u64 sqc_vft; -- int ret; -- -- ret = hisi_qm_mb(qm, QM_MB_CMD_SQC_VFT_V2, 0, 0, 1); -- if (ret) -- return ret; -- -- sqc_vft = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) | -- ((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32); -- *base = QM_SQC_VFT_BASE_MASK_V2 & (sqc_vft >> QM_SQC_VFT_BASE_SHIFT_V2); -- *number = (QM_SQC_VFT_NUM_MASK_v2 & -- (sqc_vft >> QM_SQC_VFT_NUM_SHIFT_V2)) + 1; -- -- return 0; --} -- --static int qm_get_vf_qp_num(struct hisi_qm *qm, u32 fun_num) --{ -- u32 remain_q_num, vfq_num; -- u32 num_vfs = qm->vfs_num; -- -- vfq_num = (qm->ctrl_qp_num - qm->qp_num) / num_vfs; -- if (vfq_num >= qm->max_qp_num) -- return qm->max_qp_num; -- -- remain_q_num = (qm->ctrl_qp_num - qm->qp_num) % num_vfs; -- if (vfq_num + remain_q_num <= qm->max_qp_num) -- return fun_num == num_vfs ? vfq_num + remain_q_num : vfq_num; -- -- /* -- * if vfq_num + remain_q_num > max_qp_num, the last VFs, -- * each with one more queue. -- */ -- return fun_num + remain_q_num > num_vfs ? vfq_num + 1 : vfq_num; --} -- --static struct hisi_qm *file_to_qm(struct debugfs_file *file) --{ -- struct qm_debug *debug = file->debug; -- -- return container_of(debug, struct hisi_qm, debug); --} -- --static u32 current_q_read(struct hisi_qm *qm) --{ -- return readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) >> QM_DFX_QN_SHIFT; --} -- --static int current_q_write(struct hisi_qm *qm, u32 val) --{ -- u32 tmp; -- -- if (val >= qm->debug.curr_qm_qp_num) -- return -EINVAL; -- -- tmp = val << QM_DFX_QN_SHIFT | -- (readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) & CURRENT_FUN_MASK); -- writel(tmp, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); -- -- tmp = val << QM_DFX_QN_SHIFT | -- (readl(qm->io_base + QM_DFX_CQE_CNT_VF_CQN) & CURRENT_FUN_MASK); -- writel(tmp, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); -- -- return 0; --} -- --static u32 clear_enable_read(struct hisi_qm *qm) --{ -- return readl(qm->io_base + QM_DFX_CNT_CLR_CE); --} -- --/* rd_clr_ctrl 1 enable read clear, otherwise 0 disable it */ --static int clear_enable_write(struct hisi_qm *qm, u32 rd_clr_ctrl) --{ -- if (rd_clr_ctrl > 1) -- return -EINVAL; -- -- writel(rd_clr_ctrl, qm->io_base + QM_DFX_CNT_CLR_CE); -- -- return 0; --} -- --static u32 current_qm_read(struct hisi_qm *qm) --{ -- return readl(qm->io_base + QM_DFX_MB_CNT_VF); --} -- --static int current_qm_write(struct hisi_qm *qm, u32 val) --{ -- u32 tmp; -- -- if (val > qm->vfs_num) -- return -EINVAL; -- -- /* According PF or VF Dev ID to calculation curr_qm_qp_num and store */ -- if (!val) -- qm->debug.curr_qm_qp_num = qm->qp_num; -- else -- qm->debug.curr_qm_qp_num = qm_get_vf_qp_num(qm, val); -- -- writel(val, qm->io_base + QM_DFX_MB_CNT_VF); -- writel(val, qm->io_base + QM_DFX_DB_CNT_VF); -- -- tmp = val | -- (readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) & CURRENT_Q_MASK); -- writel(tmp, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); -- -- tmp = val | -- (readl(qm->io_base + QM_DFX_CQE_CNT_VF_CQN) & CURRENT_Q_MASK); -- writel(tmp, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); -- -- return 0; --} -- --static ssize_t qm_debug_read(struct file *filp, char __user *buf, -- size_t count, loff_t *pos) --{ -- struct debugfs_file *file = filp->private_data; -- enum qm_debug_file index = file->index; -- struct hisi_qm *qm = file_to_qm(file); -- char tbuf[QM_DBG_TMP_BUF_LEN]; -- u32 val; -- int ret; -- -- ret = hisi_qm_get_dfx_access(qm); -- if (ret) -- return ret; -- -- mutex_lock(&file->lock); -- switch (index) { -- case CURRENT_QM: -- val = current_qm_read(qm); -- break; -- case CURRENT_Q: -- val = current_q_read(qm); -- break; -- case CLEAR_ENABLE: -- val = clear_enable_read(qm); -- break; -- default: -- goto err_input; -- } -- mutex_unlock(&file->lock); -- -- hisi_qm_put_dfx_access(qm); -- ret = scnprintf(tbuf, QM_DBG_TMP_BUF_LEN, "%u\n", val); -- return simple_read_from_buffer(buf, count, pos, tbuf, ret); -- --err_input: -- mutex_unlock(&file->lock); -- hisi_qm_put_dfx_access(qm); -- return -EINVAL; --} -- --static ssize_t qm_debug_write(struct file *filp, const char __user *buf, -- size_t count, loff_t *pos) --{ -- struct debugfs_file *file = filp->private_data; -- enum qm_debug_file index = file->index; -- struct hisi_qm *qm = file_to_qm(file); -- unsigned long val; -- char tbuf[QM_DBG_TMP_BUF_LEN]; -- int len, ret; -- -- if (*pos != 0) -- return 0; -- -- if (count >= QM_DBG_TMP_BUF_LEN) -- return -ENOSPC; -- -- len = simple_write_to_buffer(tbuf, QM_DBG_TMP_BUF_LEN - 1, pos, buf, -- count); -- if (len < 0) -- return len; -- -- tbuf[len] = '\0'; -- if (kstrtoul(tbuf, 0, &val)) -- return -EFAULT; -- -- ret = hisi_qm_get_dfx_access(qm); -- if (ret) -- return ret; -- -- mutex_lock(&file->lock); -- switch (index) { -- case CURRENT_QM: -- ret = current_qm_write(qm, val); -- break; -- case CURRENT_Q: -- ret = current_q_write(qm, val); -- break; -- case CLEAR_ENABLE: -- ret = clear_enable_write(qm, val); -- break; -- default: -- ret = -EINVAL; -- } -- mutex_unlock(&file->lock); -- -- hisi_qm_put_dfx_access(qm); -- -- if (ret) -- return ret; -- -- return count; --} -- --static const struct file_operations qm_debug_fops = { -- .owner = THIS_MODULE, -- .open = simple_open, -- .read = qm_debug_read, -- .write = qm_debug_write, --}; -- --#define CNT_CYC_REGS_NUM 10 --static const struct debugfs_reg32 qm_dfx_regs[] = { -- /* XXX_CNT are reading clear register */ -- {"QM_ECC_1BIT_CNT ", 0x104000ull}, -- {"QM_ECC_MBIT_CNT ", 0x104008ull}, -- {"QM_DFX_MB_CNT ", 0x104018ull}, -- {"QM_DFX_DB_CNT ", 0x104028ull}, -- {"QM_DFX_SQE_CNT ", 0x104038ull}, -- {"QM_DFX_CQE_CNT ", 0x104048ull}, -- {"QM_DFX_SEND_SQE_TO_ACC_CNT ", 0x104050ull}, -- {"QM_DFX_WB_SQE_FROM_ACC_CNT ", 0x104058ull}, -- {"QM_DFX_ACC_FINISH_CNT ", 0x104060ull}, -- {"QM_DFX_CQE_ERR_CNT ", 0x1040b4ull}, -- {"QM_DFX_FUNS_ACTIVE_ST ", 0x200ull}, -- {"QM_ECC_1BIT_INF ", 0x104004ull}, -- {"QM_ECC_MBIT_INF ", 0x10400cull}, -- {"QM_DFX_ACC_RDY_VLD0 ", 0x1040a0ull}, -- {"QM_DFX_ACC_RDY_VLD1 ", 0x1040a4ull}, -- {"QM_DFX_AXI_RDY_VLD ", 0x1040a8ull}, -- {"QM_DFX_FF_ST0 ", 0x1040c8ull}, -- {"QM_DFX_FF_ST1 ", 0x1040ccull}, -- {"QM_DFX_FF_ST2 ", 0x1040d0ull}, -- {"QM_DFX_FF_ST3 ", 0x1040d4ull}, -- {"QM_DFX_FF_ST4 ", 0x1040d8ull}, -- {"QM_DFX_FF_ST5 ", 0x1040dcull}, -- {"QM_DFX_FF_ST6 ", 0x1040e0ull}, -- {"QM_IN_IDLE_ST ", 0x1040e4ull}, --}; -- --static const struct debugfs_reg32 qm_vf_dfx_regs[] = { -- {"QM_DFX_FUNS_ACTIVE_ST ", 0x200ull}, --}; -- --/** -- * hisi_qm_regs_dump() - Dump registers's value. -- * @s: debugfs file handle. -- * @regset: accelerator registers information. -- * -- * Dump accelerator registers. -- */ --void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset) --{ -- struct pci_dev *pdev = to_pci_dev(regset->dev); -- struct hisi_qm *qm = pci_get_drvdata(pdev); -- const struct debugfs_reg32 *regs = regset->regs; -- int regs_len = regset->nregs; -- int i, ret; -- u32 val; -- -- ret = hisi_qm_get_dfx_access(qm); -- if (ret) -- return; -- -- for (i = 0; i < regs_len; i++) { -- val = readl(regset->base + regs[i].offset); -- seq_printf(s, "%s= 0x%08x\n", regs[i].name, val); -- } -- -- hisi_qm_put_dfx_access(qm); --} --EXPORT_SYMBOL_GPL(hisi_qm_regs_dump); -- --static int qm_regs_show(struct seq_file *s, void *unused) --{ -- struct hisi_qm *qm = s->private; -- struct debugfs_regset32 regset; -- -- if (qm->fun_type == QM_HW_PF) { -- regset.regs = qm_dfx_regs; -- regset.nregs = ARRAY_SIZE(qm_dfx_regs); -- } else { -- regset.regs = qm_vf_dfx_regs; -- regset.nregs = ARRAY_SIZE(qm_vf_dfx_regs); -- } -- -- regset.base = qm->io_base; -- regset.dev = &qm->pdev->dev; -- -- hisi_qm_regs_dump(s, ®set); -- -- return 0; --} -- --DEFINE_SHOW_ATTRIBUTE(qm_regs); -- --static struct dfx_diff_registers *dfx_regs_init(struct hisi_qm *qm, -- const struct dfx_diff_registers *cregs, int reg_len) --{ -- struct dfx_diff_registers *diff_regs; -- u32 j, base_offset; -- int i; -- -- diff_regs = kcalloc(reg_len, sizeof(*diff_regs), GFP_KERNEL); -- if (!diff_regs) -- return ERR_PTR(-ENOMEM); -- -- for (i = 0; i < reg_len; i++) { -- if (!cregs[i].reg_len) -- continue; -- -- diff_regs[i].reg_offset = cregs[i].reg_offset; -- diff_regs[i].reg_len = cregs[i].reg_len; -- diff_regs[i].regs = kcalloc(QM_DFX_REGS_LEN, cregs[i].reg_len, -- GFP_KERNEL); -- if (!diff_regs[i].regs) -- goto alloc_error; -- -- for (j = 0; j < diff_regs[i].reg_len; j++) { -- base_offset = diff_regs[i].reg_offset + -- j * QM_DFX_REGS_LEN; -- diff_regs[i].regs[j] = readl(qm->io_base + base_offset); -- } -- } -- -- return diff_regs; -- --alloc_error: -- while (i > 0) { -- i--; -- kfree(diff_regs[i].regs); -- } -- kfree(diff_regs); -- return ERR_PTR(-ENOMEM); --} -- --static void dfx_regs_uninit(struct hisi_qm *qm, -- struct dfx_diff_registers *dregs, int reg_len) --{ -- int i; -- -- /* Setting the pointer is NULL to prevent double free */ -- for (i = 0; i < reg_len; i++) { -- kfree(dregs[i].regs); -- dregs[i].regs = NULL; -- } -- kfree(dregs); -- dregs = NULL; --} -- --/** -- * hisi_qm_diff_regs_init() - Allocate memory for registers. -- * @qm: device qm handle. -- * @dregs: diff registers handle. -- * @reg_len: diff registers region length. -- */ --int hisi_qm_diff_regs_init(struct hisi_qm *qm, -- struct dfx_diff_registers *dregs, int reg_len) --{ -- if (!qm || !dregs || reg_len <= 0) -- return -EINVAL; -- -- if (qm->fun_type != QM_HW_PF) -- return 0; -- -- qm->debug.qm_diff_regs = dfx_regs_init(qm, qm_diff_regs, -- ARRAY_SIZE(qm_diff_regs)); -- if (IS_ERR(qm->debug.qm_diff_regs)) -- return PTR_ERR(qm->debug.qm_diff_regs); -- -- qm->debug.acc_diff_regs = dfx_regs_init(qm, dregs, reg_len); -- if (IS_ERR(qm->debug.acc_diff_regs)) { -- dfx_regs_uninit(qm, qm->debug.qm_diff_regs, -- ARRAY_SIZE(qm_diff_regs)); -- return PTR_ERR(qm->debug.acc_diff_regs); -- } -- -- return 0; --} --EXPORT_SYMBOL_GPL(hisi_qm_diff_regs_init); -- --/** -- * hisi_qm_diff_regs_uninit() - Free memory for registers. -- * @qm: device qm handle. -- * @reg_len: diff registers region length. -- */ --void hisi_qm_diff_regs_uninit(struct hisi_qm *qm, int reg_len) --{ -- if (!qm || reg_len <= 0 || qm->fun_type != QM_HW_PF) -- return; -- -- dfx_regs_uninit(qm, qm->debug.acc_diff_regs, reg_len); -- dfx_regs_uninit(qm, qm->debug.qm_diff_regs, ARRAY_SIZE(qm_diff_regs)); --} --EXPORT_SYMBOL_GPL(hisi_qm_diff_regs_uninit); -- --/** -- * hisi_qm_acc_diff_regs_dump() - Dump registers's value. -- * @qm: device qm handle. -- * @s: Debugfs file handle. -- * @dregs: diff registers handle. -- * @regs_len: diff registers region length. -- */ --void hisi_qm_acc_diff_regs_dump(struct hisi_qm *qm, struct seq_file *s, -- struct dfx_diff_registers *dregs, int regs_len) --{ -- u32 j, val, base_offset; -- int i, ret; -- -- if (!qm || !s || !dregs || regs_len <= 0) -- return; -- -- ret = hisi_qm_get_dfx_access(qm); -- if (ret) -- return; -- -- down_read(&qm->qps_lock); -- for (i = 0; i < regs_len; i++) { -- if (!dregs[i].reg_len) -- continue; -- -- for (j = 0; j < dregs[i].reg_len; j++) { -- base_offset = dregs[i].reg_offset + j * QM_DFX_REGS_LEN; -- val = readl(qm->io_base + base_offset); -- if (val != dregs[i].regs[j]) -- seq_printf(s, "0x%08x = 0x%08x ---> 0x%08x\n", -- base_offset, dregs[i].regs[j], val); -- } -- } -- up_read(&qm->qps_lock); -- -- hisi_qm_put_dfx_access(qm); --} --EXPORT_SYMBOL_GPL(hisi_qm_acc_diff_regs_dump); -- --static int qm_diff_regs_show(struct seq_file *s, void *unused) --{ -- struct hisi_qm *qm = s->private; -- -- hisi_qm_acc_diff_regs_dump(qm, s, qm->debug.qm_diff_regs, -- ARRAY_SIZE(qm_diff_regs)); -- -- return 0; --} --DEFINE_SHOW_ATTRIBUTE(qm_diff_regs); -- --static ssize_t qm_cmd_read(struct file *filp, char __user *buffer, -- size_t count, loff_t *pos) --{ -- char buf[QM_DBG_READ_LEN]; -- int len; -- -- len = scnprintf(buf, QM_DBG_READ_LEN, "%s\n", -- "Please echo help to cmd to get help information"); -- -- return simple_read_from_buffer(buffer, count, pos, buf, len); --} -- --static void *qm_ctx_alloc(struct hisi_qm *qm, size_t ctx_size, -- dma_addr_t *dma_addr) --{ -- struct device *dev = &qm->pdev->dev; -- void *ctx_addr; -- -- ctx_addr = kzalloc(ctx_size, GFP_KERNEL); -- if (!ctx_addr) -- return ERR_PTR(-ENOMEM); -- -- *dma_addr = dma_map_single(dev, ctx_addr, ctx_size, DMA_FROM_DEVICE); -- if (dma_mapping_error(dev, *dma_addr)) { -- dev_err(dev, "DMA mapping error!\n"); -- kfree(ctx_addr); -- return ERR_PTR(-ENOMEM); -- } -- -- return ctx_addr; --} -- --static void qm_ctx_free(struct hisi_qm *qm, size_t ctx_size, -- const void *ctx_addr, dma_addr_t *dma_addr) --{ -- struct device *dev = &qm->pdev->dev; -- -- dma_unmap_single(dev, *dma_addr, ctx_size, DMA_FROM_DEVICE); -- kfree(ctx_addr); --} -- --static void dump_show(struct hisi_qm *qm, void *info, -- unsigned int info_size, char *info_name) --{ -- struct device *dev = &qm->pdev->dev; -- u8 *info_curr = info; -- u32 i; --#define BYTE_PER_DW 4 -- -- dev_info(dev, "%s DUMP\n", info_name); -- for (i = 0; i < info_size; i += BYTE_PER_DW, info_curr += BYTE_PER_DW) { -- pr_info("DW%u: %02X%02X %02X%02X\n", i / BYTE_PER_DW, -- *(info_curr + 3), *(info_curr + 2), *(info_curr + 1), *(info_curr)); -- } --} -- --static int qm_dump_sqc_raw(struct hisi_qm *qm, dma_addr_t dma_addr, u16 qp_id) --{ -- return hisi_qm_mb(qm, QM_MB_CMD_SQC, dma_addr, qp_id, 1); --} -- --static int qm_dump_cqc_raw(struct hisi_qm *qm, dma_addr_t dma_addr, u16 qp_id) --{ -- return hisi_qm_mb(qm, QM_MB_CMD_CQC, dma_addr, qp_id, 1); --} -- --static int qm_sqc_dump(struct hisi_qm *qm, const char *s) --{ -- struct device *dev = &qm->pdev->dev; -- struct qm_sqc *sqc, *sqc_curr; -- dma_addr_t sqc_dma; -- u32 qp_id; -- int ret; -- -- if (!s) -- return -EINVAL; -- -- ret = kstrtou32(s, 0, &qp_id); -- if (ret || qp_id >= qm->qp_num) { -- dev_err(dev, "Please input qp num (0-%u)", qm->qp_num - 1); -- return -EINVAL; -- } -- -- sqc = qm_ctx_alloc(qm, sizeof(*sqc), &sqc_dma); -- if (IS_ERR(sqc)) -- return PTR_ERR(sqc); -- -- ret = qm_dump_sqc_raw(qm, sqc_dma, qp_id); -- if (ret) { -- down_read(&qm->qps_lock); -- if (qm->sqc) { -- sqc_curr = qm->sqc + qp_id; -- -- dump_show(qm, sqc_curr, sizeof(*sqc), "SOFT SQC"); -- } -- up_read(&qm->qps_lock); -- -- goto free_ctx; -- } -- -- dump_show(qm, sqc, sizeof(*sqc), "SQC"); -- --free_ctx: -- qm_ctx_free(qm, sizeof(*sqc), sqc, &sqc_dma); -- return 0; --} -- --static int qm_cqc_dump(struct hisi_qm *qm, const char *s) --{ -- struct device *dev = &qm->pdev->dev; -- struct qm_cqc *cqc, *cqc_curr; -- dma_addr_t cqc_dma; -- u32 qp_id; -- int ret; -- -- if (!s) -- return -EINVAL; -- -- ret = kstrtou32(s, 0, &qp_id); -- if (ret || qp_id >= qm->qp_num) { -- dev_err(dev, "Please input qp num (0-%u)", qm->qp_num - 1); -- return -EINVAL; -- } -- -- cqc = qm_ctx_alloc(qm, sizeof(*cqc), &cqc_dma); -- if (IS_ERR(cqc)) -- return PTR_ERR(cqc); -- -- ret = qm_dump_cqc_raw(qm, cqc_dma, qp_id); -- if (ret) { -- down_read(&qm->qps_lock); -- if (qm->cqc) { -- cqc_curr = qm->cqc + qp_id; -- -- dump_show(qm, cqc_curr, sizeof(*cqc), "SOFT CQC"); -- } -- up_read(&qm->qps_lock); -- -- goto free_ctx; -- } -- -- dump_show(qm, cqc, sizeof(*cqc), "CQC"); -- --free_ctx: -- qm_ctx_free(qm, sizeof(*cqc), cqc, &cqc_dma); -- return 0; --} -- --static int qm_eqc_aeqc_dump(struct hisi_qm *qm, char *s, size_t size, -- int cmd, char *name) --{ -- struct device *dev = &qm->pdev->dev; -- dma_addr_t xeqc_dma; -- void *xeqc; -- int ret; -- -- if (strsep(&s, " ")) { -- dev_err(dev, "Please do not input extra characters!\n"); -- return -EINVAL; -- } -- -- xeqc = qm_ctx_alloc(qm, size, &xeqc_dma); -- if (IS_ERR(xeqc)) -- return PTR_ERR(xeqc); -- -- ret = hisi_qm_mb(qm, cmd, xeqc_dma, 0, 1); -- if (ret) -- goto err_free_ctx; -- -- dump_show(qm, xeqc, size, name); -- --err_free_ctx: -- qm_ctx_free(qm, size, xeqc, &xeqc_dma); -- return ret; --} -- --static int q_dump_param_parse(struct hisi_qm *qm, char *s, -- u32 *e_id, u32 *q_id, u16 q_depth) --{ -- struct device *dev = &qm->pdev->dev; -- unsigned int qp_num = qm->qp_num; -- char *presult; -- int ret; -- -- presult = strsep(&s, " "); -- if (!presult) { -- dev_err(dev, "Please input qp number!\n"); -- return -EINVAL; -- } -- -- ret = kstrtou32(presult, 0, q_id); -- if (ret || *q_id >= qp_num) { -- dev_err(dev, "Please input qp num (0-%u)", qp_num - 1); -- return -EINVAL; -- } -- -- presult = strsep(&s, " "); -- if (!presult) { -- dev_err(dev, "Please input sqe number!\n"); -- return -EINVAL; -- } -- -- ret = kstrtou32(presult, 0, e_id); -- if (ret || *e_id >= q_depth) { -- dev_err(dev, "Please input sqe num (0-%u)", q_depth - 1); -- return -EINVAL; -- } -- -- if (strsep(&s, " ")) { -- dev_err(dev, "Please do not input extra characters!\n"); -- return -EINVAL; -+ case SHAPER_VFT: -+ if (factor) { -+ tmp = factor->cir_b | -+ (factor->cir_u << QM_SHAPER_FACTOR_CIR_U_SHIFT) | -+ (factor->cir_s << QM_SHAPER_FACTOR_CIR_S_SHIFT) | -+ (QM_SHAPER_CBS_B << QM_SHAPER_FACTOR_CBS_B_SHIFT) | -+ (factor->cbs_s << QM_SHAPER_FACTOR_CBS_S_SHIFT); -+ } -+ break; -+ } - } - -- return 0; -+ writel(lower_32_bits(tmp), qm->io_base + QM_VFT_CFG_DATA_L); -+ writel(upper_32_bits(tmp), qm->io_base + QM_VFT_CFG_DATA_H); - } - --static int qm_sq_dump(struct hisi_qm *qm, char *s) -+static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type, -+ u32 fun_num, u32 base, u32 number) - { -- u16 sq_depth = qm->qp_array->cq_depth; -- void *sqe, *sqe_curr; -- struct hisi_qp *qp; -- u32 qp_id, sqe_id; -+ struct qm_shaper_factor *factor = NULL; -+ unsigned int val; - int ret; - -- ret = q_dump_param_parse(qm, s, &sqe_id, &qp_id, sq_depth); -+ if (type == SHAPER_VFT && test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) -+ factor = &qm->factor[fun_num]; -+ -+ ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val, -+ val & BIT(0), POLL_PERIOD, -+ POLL_TIMEOUT); - if (ret) - return ret; - -- sqe = kzalloc(qm->sqe_size * sq_depth, GFP_KERNEL); -- if (!sqe) -- return -ENOMEM; -+ writel(0x0, qm->io_base + QM_VFT_CFG_OP_WR); -+ writel(type, qm->io_base + QM_VFT_CFG_TYPE); -+ if (type == SHAPER_VFT) -+ fun_num |= base << QM_SHAPER_VFT_OFFSET; - -- qp = &qm->qp_array[qp_id]; -- memcpy(sqe, qp->sqe, qm->sqe_size * sq_depth); -- sqe_curr = sqe + (u32)(sqe_id * qm->sqe_size); -- memset(sqe_curr + qm->debug.sqe_mask_offset, QM_SQE_ADDR_MASK, -- qm->debug.sqe_mask_len); -+ writel(fun_num, qm->io_base + QM_VFT_CFG); - -- dump_show(qm, sqe_curr, qm->sqe_size, "SQE"); -+ qm_vft_data_cfg(qm, type, base, number, factor); - -- kfree(sqe); -+ writel(0x0, qm->io_base + QM_VFT_CFG_RDY); -+ writel(0x1, qm->io_base + QM_VFT_CFG_OP_ENABLE); - -- return 0; -+ return readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val, -+ val & BIT(0), POLL_PERIOD, -+ POLL_TIMEOUT); - } - --static int qm_cq_dump(struct hisi_qm *qm, char *s) -+static int qm_shaper_init_vft(struct hisi_qm *qm, u32 fun_num) - { -- struct qm_cqe *cqe_curr; -- struct hisi_qp *qp; -- u32 qp_id, cqe_id; -- int ret; -+ u32 qos = qm->factor[fun_num].func_qos; -+ int ret, i; - -- ret = q_dump_param_parse(qm, s, &cqe_id, &qp_id, qm->qp_array->cq_depth); -- if (ret) -+ ret = qm_get_shaper_para(qos * QM_QOS_RATE, &qm->factor[fun_num]); -+ if (ret) { -+ dev_err(&qm->pdev->dev, "failed to calculate shaper parameter!\n"); - return ret; -- -- qp = &qm->qp_array[qp_id]; -- cqe_curr = qp->cqe + cqe_id; -- dump_show(qm, cqe_curr, sizeof(struct qm_cqe), "CQE"); -+ } -+ writel(qm->type_rate, qm->io_base + QM_SHAPER_CFG); -+ for (i = ALG_TYPE_0; i <= ALG_TYPE_1; i++) { -+ /* The base number of queue reuse for different alg type */ -+ ret = qm_set_vft_common(qm, SHAPER_VFT, fun_num, i, 1); -+ if (ret) -+ return ret; -+ } - - return 0; - } - --static int qm_eq_aeq_dump(struct hisi_qm *qm, const char *s, -- size_t size, char *name) -+/* The config should be conducted after qm_dev_mem_reset() */ -+static int qm_set_sqc_cqc_vft(struct hisi_qm *qm, u32 fun_num, u32 base, -+ u32 number) - { -- struct device *dev = &qm->pdev->dev; -- void *xeqe; -- u32 xeqe_id; -- int ret; -- -- if (!s) -- return -EINVAL; -- -- ret = kstrtou32(s, 0, &xeqe_id); -- if (ret) -- return -EINVAL; -+ int ret, i; - -- if (!strcmp(name, "EQE") && xeqe_id >= qm->eq_depth) { -- dev_err(dev, "Please input eqe num (0-%u)", qm->eq_depth - 1); -- return -EINVAL; -- } else if (!strcmp(name, "AEQE") && xeqe_id >= qm->aeq_depth) { -- dev_err(dev, "Please input aeqe num (0-%u)", qm->eq_depth - 1); -- return -EINVAL; -+ for (i = SQC_VFT; i <= CQC_VFT; i++) { -+ ret = qm_set_vft_common(qm, i, fun_num, base, number); -+ if (ret) -+ return ret; - } - -- down_read(&qm->qps_lock); -- -- if (qm->eqe && !strcmp(name, "EQE")) { -- xeqe = qm->eqe + xeqe_id; -- } else if (qm->aeqe && !strcmp(name, "AEQE")) { -- xeqe = qm->aeqe + xeqe_id; -- } else { -- ret = -EINVAL; -- goto err_unlock; -+ /* init default shaper qos val */ -+ if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) { -+ ret = qm_shaper_init_vft(qm, fun_num); -+ if (ret) -+ goto back_sqc_cqc; - } - -- dump_show(qm, xeqe, size, name); -+ return 0; -+back_sqc_cqc: -+ for (i = SQC_VFT; i <= CQC_VFT; i++) -+ qm_set_vft_common(qm, i, fun_num, 0, 0); - --err_unlock: -- up_read(&qm->qps_lock); - return ret; - } - --static int qm_dbg_help(struct hisi_qm *qm, char *s) -+static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number) - { -- struct device *dev = &qm->pdev->dev; -+ u64 sqc_vft; -+ int ret; - -- if (strsep(&s, " ")) { -- dev_err(dev, "Please do not input extra characters!\n"); -- return -EINVAL; -- } -+ ret = hisi_qm_mb(qm, QM_MB_CMD_SQC_VFT_V2, 0, 0, 1); -+ if (ret) -+ return ret; - -- dev_info(dev, "available commands:\n"); -- dev_info(dev, "sqc \n"); -- dev_info(dev, "cqc \n"); -- dev_info(dev, "eqc\n"); -- dev_info(dev, "aeqc\n"); -- dev_info(dev, "sq \n"); -- dev_info(dev, "cq \n"); -- dev_info(dev, "eq \n"); -- dev_info(dev, "aeq \n"); -+ sqc_vft = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) | -+ ((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32); -+ *base = QM_SQC_VFT_BASE_MASK_V2 & (sqc_vft >> QM_SQC_VFT_BASE_SHIFT_V2); -+ *number = (QM_SQC_VFT_NUM_MASK_v2 & -+ (sqc_vft >> QM_SQC_VFT_NUM_SHIFT_V2)) + 1; - - return 0; - } - --static int qm_cmd_write_dump(struct hisi_qm *qm, const char *cmd_buf) -+void *hisi_qm_ctx_alloc(struct hisi_qm *qm, size_t ctx_size, -+ dma_addr_t *dma_addr) - { - struct device *dev = &qm->pdev->dev; -- char *presult, *s, *s_tmp; -- int ret; -- -- s = kstrdup(cmd_buf, GFP_KERNEL); -- if (!s) -- return -ENOMEM; -- -- s_tmp = s; -- presult = strsep(&s, " "); -- if (!presult) { -- ret = -EINVAL; -- goto err_buffer_free; -- } -- -- if (!strcmp(presult, "sqc")) -- ret = qm_sqc_dump(qm, s); -- else if (!strcmp(presult, "cqc")) -- ret = qm_cqc_dump(qm, s); -- else if (!strcmp(presult, "eqc")) -- ret = qm_eqc_aeqc_dump(qm, s, sizeof(struct qm_eqc), -- QM_MB_CMD_EQC, "EQC"); -- else if (!strcmp(presult, "aeqc")) -- ret = qm_eqc_aeqc_dump(qm, s, sizeof(struct qm_aeqc), -- QM_MB_CMD_AEQC, "AEQC"); -- else if (!strcmp(presult, "sq")) -- ret = qm_sq_dump(qm, s); -- else if (!strcmp(presult, "cq")) -- ret = qm_cq_dump(qm, s); -- else if (!strcmp(presult, "eq")) -- ret = qm_eq_aeq_dump(qm, s, sizeof(struct qm_eqe), "EQE"); -- else if (!strcmp(presult, "aeq")) -- ret = qm_eq_aeq_dump(qm, s, sizeof(struct qm_aeqe), "AEQE"); -- else if (!strcmp(presult, "help")) -- ret = qm_dbg_help(qm, s); -- else -- ret = -EINVAL; -+ void *ctx_addr; - -- if (ret) -- dev_info(dev, "Please echo help\n"); -+ ctx_addr = kzalloc(ctx_size, GFP_KERNEL); -+ if (!ctx_addr) -+ return ERR_PTR(-ENOMEM); - --err_buffer_free: -- kfree(s_tmp); -+ *dma_addr = dma_map_single(dev, ctx_addr, ctx_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(dev, *dma_addr)) { -+ dev_err(dev, "DMA mapping error!\n"); -+ kfree(ctx_addr); -+ return ERR_PTR(-ENOMEM); -+ } - -- return ret; -+ return ctx_addr; - } - --static ssize_t qm_cmd_write(struct file *filp, const char __user *buffer, -- size_t count, loff_t *pos) -+void hisi_qm_ctx_free(struct hisi_qm *qm, size_t ctx_size, -+ const void *ctx_addr, dma_addr_t *dma_addr) - { -- struct hisi_qm *qm = filp->private_data; -- char *cmd_buf, *cmd_buf_tmp; -- int ret; -- -- if (*pos) -- return 0; -- -- ret = hisi_qm_get_dfx_access(qm); -- if (ret) -- return ret; -- -- /* Judge if the instance is being reset. */ -- if (unlikely(atomic_read(&qm->status.flags) == QM_STOP)) { -- ret = 0; -- goto put_dfx_access; -- } -- -- if (count > QM_DBG_WRITE_LEN) { -- ret = -ENOSPC; -- goto put_dfx_access; -- } -- -- cmd_buf = memdup_user_nul(buffer, count); -- if (IS_ERR(cmd_buf)) { -- ret = PTR_ERR(cmd_buf); -- goto put_dfx_access; -- } -- -- cmd_buf_tmp = strchr(cmd_buf, '\n'); -- if (cmd_buf_tmp) { -- *cmd_buf_tmp = '\0'; -- count = cmd_buf_tmp - cmd_buf + 1; -- } -- -- ret = qm_cmd_write_dump(qm, cmd_buf); -- if (ret) { -- kfree(cmd_buf); -- goto put_dfx_access; -- } -- -- kfree(cmd_buf); -- -- ret = count; -+ struct device *dev = &qm->pdev->dev; - --put_dfx_access: -- hisi_qm_put_dfx_access(qm); -- return ret; -+ dma_unmap_single(dev, *dma_addr, ctx_size, DMA_FROM_DEVICE); -+ kfree(ctx_addr); - } - --static const struct file_operations qm_cmd_fops = { -- .owner = THIS_MODULE, -- .open = simple_open, -- .read = qm_cmd_read, -- .write = qm_cmd_write, --}; -- --static void qm_create_debugfs_file(struct hisi_qm *qm, struct dentry *dir, -- enum qm_debug_file index) -+static int qm_dump_sqc_raw(struct hisi_qm *qm, dma_addr_t dma_addr, u16 qp_id) - { -- struct debugfs_file *file = qm->debug.files + index; -- -- debugfs_create_file(qm_debug_file_name[index], 0600, dir, file, -- &qm_debug_fops); -+ return hisi_qm_mb(qm, QM_MB_CMD_SQC, dma_addr, qp_id, 1); -+} - -- file->index = index; -- mutex_init(&file->lock); -- file->debug = &qm->debug; -+static int qm_dump_cqc_raw(struct hisi_qm *qm, dma_addr_t dma_addr, u16 qp_id) -+{ -+ return hisi_qm_mb(qm, QM_MB_CMD_CQC, dma_addr, qp_id, 1); - } - - static void qm_hw_error_init_v1(struct hisi_qm *qm) -@@ -3100,7 +2128,7 @@ static int qm_drain_qp(struct hisi_qp *qp) - return ret; - } - -- addr = qm_ctx_alloc(qm, size, &dma_addr); -+ addr = hisi_qm_ctx_alloc(qm, size, &dma_addr); - if (IS_ERR(addr)) { - dev_err(dev, "Failed to alloc ctx for sqc and cqc!\n"); - return -ENOMEM; -@@ -3135,7 +2163,7 @@ static int qm_drain_qp(struct hisi_qp *qp) - usleep_range(WAIT_PERIOD_US_MIN, WAIT_PERIOD_US_MAX); - } - -- qm_ctx_free(qm, size, addr, &dma_addr); -+ hisi_qm_ctx_free(qm, size, addr, &dma_addr); - - return ret; - } -@@ -3659,7 +2687,6 @@ static void hisi_qm_pre_init(struct hisi_qm *qm) - mutex_init(&qm->mailbox_lock); - init_rwsem(&qm->qps_lock); - qm->qp_in_used = 0; -- qm->misc_ctl = false; - if (test_bit(QM_SUPPORT_RPM, &qm->caps)) { - if (!acpi_device_power_manageable(ACPI_COMPANION(&pdev->dev))) - dev_info(&pdev->dev, "_PS0 and _PR0 are not defined"); -@@ -3720,17 +2747,6 @@ static void hisi_qm_set_state(struct hisi_qm *qm, u8 state) - writel(state, qm->io_base + QM_VF_STATE); - } - --static void qm_last_regs_uninit(struct hisi_qm *qm) --{ -- struct qm_debug *debug = &qm->debug; -- -- if (qm->fun_type == QM_HW_VF || !debug->qm_last_words) -- return; -- -- kfree(debug->qm_last_words); -- debug->qm_last_words = NULL; --} -- - static void hisi_qm_unint_work(struct hisi_qm *qm) - { - destroy_workqueue(qm->wq); -@@ -3761,8 +2777,6 @@ static void hisi_qm_memory_uninit(struct hisi_qm *qm) - */ - void hisi_qm_uninit(struct hisi_qm *qm) - { -- qm_last_regs_uninit(qm); -- - qm_cmd_uninit(qm); - hisi_qm_unint_work(qm); - down_write(&qm->qps_lock); -@@ -4131,45 +3145,6 @@ err_unlock: - } - EXPORT_SYMBOL_GPL(hisi_qm_stop); - --static ssize_t qm_status_read(struct file *filp, char __user *buffer, -- size_t count, loff_t *pos) --{ -- struct hisi_qm *qm = filp->private_data; -- char buf[QM_DBG_READ_LEN]; -- int val, len; -- -- val = atomic_read(&qm->status.flags); -- len = scnprintf(buf, QM_DBG_READ_LEN, "%s\n", qm_s[val]); -- -- return simple_read_from_buffer(buffer, count, pos, buf, len); --} -- --static const struct file_operations qm_status_fops = { -- .owner = THIS_MODULE, -- .open = simple_open, -- .read = qm_status_read, --}; -- --static int qm_debugfs_atomic64_set(void *data, u64 val) --{ -- if (val) -- return -EINVAL; -- -- atomic64_set((atomic64_t *)data, 0); -- -- return 0; --} -- --static int qm_debugfs_atomic64_get(void *data, u64 *val) --{ -- *val = atomic64_read((atomic64_t *)data); -- -- return 0; --} -- --DEFINE_DEBUGFS_ATTRIBUTE(qm_atomic64_ops, qm_debugfs_atomic64_get, -- qm_debugfs_atomic64_set, "%llu\n"); -- - static void qm_hw_error_init(struct hisi_qm *qm) - { - if (!qm->ops->hw_error_init) { -@@ -4708,7 +3683,7 @@ static const struct file_operations qm_algqos_fops = { - * - * Create function qos debugfs files, VF ping PF to get function qos. - */ --static void hisi_qm_set_algqos_init(struct hisi_qm *qm) -+void hisi_qm_set_algqos_init(struct hisi_qm *qm) - { - if (qm->fun_type == QM_HW_PF) - debugfs_create_file("alg_qos", 0644, qm->debug.debug_root, -@@ -4718,88 +3693,6 @@ static void hisi_qm_set_algqos_init(struct hisi_qm *qm) - qm, &qm_algqos_fops); - } - --/** -- * hisi_qm_debug_init() - Initialize qm related debugfs files. -- * @qm: The qm for which we want to add debugfs files. -- * -- * Create qm related debugfs files. -- */ --void hisi_qm_debug_init(struct hisi_qm *qm) --{ -- struct dfx_diff_registers *qm_regs = qm->debug.qm_diff_regs; -- struct qm_dfx *dfx = &qm->debug.dfx; -- struct dentry *qm_d; -- void *data; -- int i; -- -- qm_d = debugfs_create_dir("qm", qm->debug.debug_root); -- qm->debug.qm_d = qm_d; -- -- /* only show this in PF */ -- if (qm->fun_type == QM_HW_PF) { -- qm_create_debugfs_file(qm, qm->debug.debug_root, CURRENT_QM); -- for (i = CURRENT_Q; i < DEBUG_FILE_NUM; i++) -- qm_create_debugfs_file(qm, qm->debug.qm_d, i); -- } -- -- if (qm_regs) -- debugfs_create_file("diff_regs", 0444, qm->debug.qm_d, -- qm, &qm_diff_regs_fops); -- -- debugfs_create_file("regs", 0444, qm->debug.qm_d, qm, &qm_regs_fops); -- -- debugfs_create_file("cmd", 0600, qm->debug.qm_d, qm, &qm_cmd_fops); -- -- debugfs_create_file("status", 0444, qm->debug.qm_d, qm, -- &qm_status_fops); -- for (i = 0; i < ARRAY_SIZE(qm_dfx_files); i++) { -- data = (atomic64_t *)((uintptr_t)dfx + qm_dfx_files[i].offset); -- debugfs_create_file(qm_dfx_files[i].name, -- 0644, -- qm_d, -- data, -- &qm_atomic64_ops); -- } -- -- if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) -- hisi_qm_set_algqos_init(qm); --} --EXPORT_SYMBOL_GPL(hisi_qm_debug_init); -- --/** -- * hisi_qm_debug_regs_clear() - clear qm debug related registers. -- * @qm: The qm for which we want to clear its debug registers. -- */ --void hisi_qm_debug_regs_clear(struct hisi_qm *qm) --{ -- const struct debugfs_reg32 *regs; -- int i; -- -- /* clear current_qm */ -- writel(0x0, qm->io_base + QM_DFX_MB_CNT_VF); -- writel(0x0, qm->io_base + QM_DFX_DB_CNT_VF); -- -- /* clear current_q */ -- writel(0x0, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); -- writel(0x0, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); -- -- /* -- * these registers are reading and clearing, so clear them after -- * reading them. -- */ -- writel(0x1, qm->io_base + QM_DFX_CNT_CLR_CE); -- -- regs = qm_dfx_regs; -- for (i = 0; i < CNT_CYC_REGS_NUM; i++) { -- readl(qm->io_base + regs->offset); -- regs++; -- } -- -- /* clear clear_enable */ -- writel(0x0, qm->io_base + QM_DFX_CNT_CLR_CE); --} --EXPORT_SYMBOL_GPL(hisi_qm_debug_regs_clear); -- - static void hisi_qm_init_vf_qos(struct hisi_qm *qm, int total_func) - { - int i; -@@ -5438,24 +4331,6 @@ static int qm_controller_reset_done(struct hisi_qm *qm) - return 0; - } - --static void qm_show_last_dfx_regs(struct hisi_qm *qm) --{ -- struct qm_debug *debug = &qm->debug; -- struct pci_dev *pdev = qm->pdev; -- u32 val; -- int i; -- -- if (qm->fun_type == QM_HW_VF || !debug->qm_last_words) -- return; -- -- for (i = 0; i < ARRAY_SIZE(qm_dfx_regs); i++) { -- val = readl_relaxed(qm->io_base + qm_dfx_regs[i].offset); -- if (debug->qm_last_words[i] != val) -- pci_info(pdev, "%s \t= 0x%08x => 0x%08x\n", -- qm_dfx_regs[i].name, debug->qm_last_words[i], val); -- } --} -- - static int qm_controller_reset(struct hisi_qm *qm) - { - struct pci_dev *pdev = qm->pdev; -@@ -5471,7 +4346,7 @@ static int qm_controller_reset(struct hisi_qm *qm) - return ret; - } - -- qm_show_last_dfx_regs(qm); -+ hisi_qm_show_last_dfx_regs(qm); - if (qm->err_ini->show_last_dfx_regs) - qm->err_ini->show_last_dfx_regs(qm); - -@@ -6091,6 +4966,7 @@ free_eq_irq: - - static int qm_get_qp_num(struct hisi_qm *qm) - { -+ struct device *dev = &qm->pdev->dev; - bool is_db_isolation; - - /* VF's qp_num assigned by PF in v2, and VF can get qp_num by vft. */ -@@ -6107,13 +4983,21 @@ static int qm_get_qp_num(struct hisi_qm *qm) - qm->max_qp_num = hisi_qm_get_hw_info(qm, qm_basic_info, - QM_FUNC_MAX_QP_CAP, is_db_isolation); - -- /* check if qp number is valid */ -- if (qm->qp_num > qm->max_qp_num) { -- dev_err(&qm->pdev->dev, "qp num(%u) is more than max qp num(%u)!\n", -+ if (qm->qp_num <= qm->max_qp_num) -+ return 0; -+ -+ if (test_bit(QM_MODULE_PARAM, &qm->misc_ctl)) { -+ /* Check whether the set qp number is valid */ -+ dev_err(dev, "qp num(%u) is more than max qp num(%u)!\n", - qm->qp_num, qm->max_qp_num); - return -EINVAL; - } - -+ dev_info(dev, "Default qp num(%u) is too big, reset it to Function's max qp num(%u)!\n", -+ qm->qp_num, qm->max_qp_num); -+ qm->qp_num = qm->max_qp_num; -+ qm->debug.curr_qm_qp_num = qm->qp_num; -+ - return 0; - } - -@@ -6358,26 +5242,6 @@ err_destroy_idr: - return ret; - } - --static void qm_last_regs_init(struct hisi_qm *qm) --{ -- int dfx_regs_num = ARRAY_SIZE(qm_dfx_regs); -- struct qm_debug *debug = &qm->debug; -- int i; -- -- if (qm->fun_type == QM_HW_VF) -- return; -- -- debug->qm_last_words = kcalloc(dfx_regs_num, sizeof(unsigned int), -- GFP_KERNEL); -- if (!debug->qm_last_words) -- return; -- -- for (i = 0; i < dfx_regs_num; i++) { -- debug->qm_last_words[i] = readl_relaxed(qm->io_base + -- qm_dfx_regs[i].offset); -- } --} -- - /** - * hisi_qm_init() - Initialize configures about qm. - * @qm: The qm needing init. -@@ -6426,8 +5290,6 @@ int hisi_qm_init(struct hisi_qm *qm) - qm_cmd_init(qm); - atomic_set(&qm->status.flags, QM_INIT); - -- qm_last_regs_init(qm); -- - return 0; - - err_free_qm_memory: -diff --git a/drivers/crypto/hisilicon/qm_common.h b/drivers/crypto/hisilicon/qm_common.h -new file mode 100644 -index 0000000000000..8e36aa9c681be ---- /dev/null -+++ b/drivers/crypto/hisilicon/qm_common.h -@@ -0,0 +1,86 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Copyright (c) 2022 HiSilicon Limited. */ -+#ifndef QM_COMMON_H -+#define QM_COMMON_H -+ -+#define QM_DBG_READ_LEN 256 -+ -+struct qm_cqe { -+ __le32 rsvd0; -+ __le16 cmd_id; -+ __le16 rsvd1; -+ __le16 sq_head; -+ __le16 sq_num; -+ __le16 rsvd2; -+ __le16 w7; -+}; -+ -+struct qm_eqe { -+ __le32 dw0; -+}; -+ -+struct qm_aeqe { -+ __le32 dw0; -+}; -+ -+struct qm_sqc { -+ __le16 head; -+ __le16 tail; -+ __le32 base_l; -+ __le32 base_h; -+ __le32 dw3; -+ __le16 w8; -+ __le16 rsvd0; -+ __le16 pasid; -+ __le16 w11; -+ __le16 cq_num; -+ __le16 w13; -+ __le32 rsvd1; -+}; -+ -+struct qm_cqc { -+ __le16 head; -+ __le16 tail; -+ __le32 base_l; -+ __le32 base_h; -+ __le32 dw3; -+ __le16 w8; -+ __le16 rsvd0; -+ __le16 pasid; -+ __le16 w11; -+ __le32 dw6; -+ __le32 rsvd1; -+}; -+ -+struct qm_eqc { -+ __le16 head; -+ __le16 tail; -+ __le32 base_l; -+ __le32 base_h; -+ __le32 dw3; -+ __le32 rsvd[2]; -+ __le32 dw6; -+}; -+ -+struct qm_aeqc { -+ __le16 head; -+ __le16 tail; -+ __le32 base_l; -+ __le32 base_h; -+ __le32 dw3; -+ __le32 rsvd[2]; -+ __le32 dw6; -+}; -+ -+static const char * const qm_s[] = { -+ "init", "start", "close", "stop", -+}; -+ -+void *hisi_qm_ctx_alloc(struct hisi_qm *qm, size_t ctx_size, -+ dma_addr_t *dma_addr); -+void hisi_qm_ctx_free(struct hisi_qm *qm, size_t ctx_size, -+ const void *ctx_addr, dma_addr_t *dma_addr); -+void hisi_qm_show_last_dfx_regs(struct hisi_qm *qm); -+void hisi_qm_set_algqos_init(struct hisi_qm *qm); -+ -+#endif -diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c -index 3705412bac5f1..e384988bda917 100644 ---- a/drivers/crypto/hisilicon/sec2/sec_main.c -+++ b/drivers/crypto/hisilicon/sec2/sec_main.c -@@ -312,8 +312,11 @@ static int sec_diff_regs_show(struct seq_file *s, void *unused) - } - DEFINE_SHOW_ATTRIBUTE(sec_diff_regs); - -+static bool pf_q_num_flag; - static int sec_pf_q_num_set(const char *val, const struct kernel_param *kp) - { -+ pf_q_num_flag = true; -+ - return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_SEC_PF); - } - -@@ -899,8 +902,7 @@ static int sec_debugfs_init(struct hisi_qm *qm) - qm->debug.sqe_mask_offset = SEC_SQE_MASK_OFFSET; - qm->debug.sqe_mask_len = SEC_SQE_MASK_LEN; - -- ret = hisi_qm_diff_regs_init(qm, sec_diff_regs, -- ARRAY_SIZE(sec_diff_regs)); -+ ret = hisi_qm_regs_debugfs_init(qm, sec_diff_regs, ARRAY_SIZE(sec_diff_regs)); - if (ret) { - dev_warn(dev, "Failed to init SEC diff regs!\n"); - goto debugfs_remove; -@@ -915,7 +917,7 @@ static int sec_debugfs_init(struct hisi_qm *qm) - return 0; - - failed_to_create: -- hisi_qm_diff_regs_uninit(qm, ARRAY_SIZE(sec_diff_regs)); -+ hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(sec_diff_regs)); - debugfs_remove: - debugfs_remove_recursive(sec_debugfs_root); - return ret; -@@ -923,7 +925,7 @@ debugfs_remove: - - static void sec_debugfs_exit(struct hisi_qm *qm) - { -- hisi_qm_diff_regs_uninit(qm, ARRAY_SIZE(sec_diff_regs)); -+ hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(sec_diff_regs)); - - debugfs_remove_recursive(qm->debug.debug_root); - } -@@ -1123,6 +1125,8 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - qm->qp_num = pf_q_num; - qm->debug.curr_qm_qp_num = pf_q_num; - qm->qm_list = &sec_devices; -+ if (pf_q_num_flag) -+ set_bit(QM_MODULE_PARAM, &qm->misc_ctl); - } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) { - /* - * have no way to get qm configure in VM in v1 hardware, -diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c -index c863435e8c75a..190b4fecfc747 100644 ---- a/drivers/crypto/hisilicon/zip/zip_main.c -+++ b/drivers/crypto/hisilicon/zip/zip_main.c -@@ -365,8 +365,11 @@ static u32 uacce_mode = UACCE_MODE_NOUACCE; - module_param_cb(uacce_mode, &zip_uacce_mode_ops, &uacce_mode, 0444); - MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC); - -+static bool pf_q_num_flag; - static int pf_q_num_set(const char *val, const struct kernel_param *kp) - { -+ pf_q_num_flag = true; -+ - return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_ZIP_PF); - } - -@@ -849,8 +852,7 @@ static int hisi_zip_debugfs_init(struct hisi_qm *qm) - qm->debug.sqe_mask_offset = HZIP_SQE_MASK_OFFSET; - qm->debug.sqe_mask_len = HZIP_SQE_MASK_LEN; - qm->debug.debug_root = dev_d; -- ret = hisi_qm_diff_regs_init(qm, hzip_diff_regs, -- ARRAY_SIZE(hzip_diff_regs)); -+ ret = hisi_qm_regs_debugfs_init(qm, hzip_diff_regs, ARRAY_SIZE(hzip_diff_regs)); - if (ret) { - dev_warn(dev, "Failed to init ZIP diff regs!\n"); - goto debugfs_remove; -@@ -869,7 +871,7 @@ static int hisi_zip_debugfs_init(struct hisi_qm *qm) - return 0; - - failed_to_create: -- hisi_qm_diff_regs_uninit(qm, ARRAY_SIZE(hzip_diff_regs)); -+ hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(hzip_diff_regs)); - debugfs_remove: - debugfs_remove_recursive(hzip_debugfs_root); - return ret; -@@ -895,7 +897,7 @@ static void hisi_zip_debug_regs_clear(struct hisi_qm *qm) - - static void hisi_zip_debugfs_exit(struct hisi_qm *qm) - { -- hisi_qm_diff_regs_uninit(qm, ARRAY_SIZE(hzip_diff_regs)); -+ hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(hzip_diff_regs)); - - debugfs_remove_recursive(qm->debug.debug_root); - -@@ -1141,6 +1143,8 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - qm->qp_num = pf_q_num; - qm->debug.curr_qm_qp_num = pf_q_num; - qm->qm_list = &zip_devices; -+ if (pf_q_num_flag) -+ set_bit(QM_MODULE_PARAM, &qm->misc_ctl); - } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) { - /* - * have no way to get qm configure in VM in v1 hardware, -diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile -index 80919cfcc29da..b0587d03eac29 100644 ---- a/drivers/crypto/qat/qat_common/Makefile -+++ b/drivers/crypto/qat/qat_common/Makefile -@@ -19,7 +19,8 @@ intel_qat-objs := adf_cfg.o \ - qat_asym_algs.o \ - qat_algs_send.o \ - qat_uclo.o \ -- qat_hal.o -+ qat_hal.o \ -+ qat_bl.o - - intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o - intel_qat-$(CONFIG_PCI_IOV) += adf_sriov.o adf_vf_isr.o adf_pfvf_utils.o \ -diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h -index 20f50d0e65f89..ad01d99e6e2ba 100644 ---- a/drivers/crypto/qat/qat_common/adf_accel_devices.h -+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h -@@ -27,7 +27,7 @@ - #define ADF_PCI_MAX_BARS 3 - #define ADF_DEVICE_NAME_LENGTH 32 - #define ADF_ETR_MAX_RINGS_PER_BANK 16 --#define ADF_MAX_MSIX_VECTOR_NAME 16 -+#define ADF_MAX_MSIX_VECTOR_NAME 48 - #define ADF_DEVICE_NAME_PREFIX "qat_" - - enum adf_accel_capabilities { -diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h -index bff613eec5c4b..d2bc2361cd069 100644 ---- a/drivers/crypto/qat/qat_common/adf_common_drv.h -+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h -@@ -25,6 +25,7 @@ - #define ADF_STATUS_AE_STARTED 6 - #define ADF_STATUS_PF_RUNNING 7 - #define ADF_STATUS_IRQ_ALLOCATED 8 -+#define ADF_STATUS_CRYPTO_ALGS_REGISTERED 9 - - enum adf_dev_reset_mode { - ADF_DEV_RESET_ASYNC = 0, -diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c -index d6f3314246179..2e3481270c4ba 100644 ---- a/drivers/crypto/qat/qat_common/adf_init.c -+++ b/drivers/crypto/qat/qat_common/adf_init.c -@@ -209,6 +209,8 @@ int adf_dev_start(struct adf_accel_dev *accel_dev) - clear_bit(ADF_STATUS_STARTED, &accel_dev->status); - return -EFAULT; - } -+ set_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status); -+ - return 0; - } - EXPORT_SYMBOL_GPL(adf_dev_start); -@@ -237,10 +239,12 @@ void adf_dev_stop(struct adf_accel_dev *accel_dev) - clear_bit(ADF_STATUS_STARTING, &accel_dev->status); - clear_bit(ADF_STATUS_STARTED, &accel_dev->status); - -- if (!list_empty(&accel_dev->crypto_list)) { -+ if (!list_empty(&accel_dev->crypto_list) && -+ test_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status)) { - qat_algs_unregister(); - qat_asym_algs_unregister(); - } -+ clear_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status); - - list_for_each(list_itr, &service_table) { - service = list_entry(list_itr, struct service_hndl, list); -diff --git a/drivers/crypto/qat/qat_common/adf_sysfs.c b/drivers/crypto/qat/qat_common/adf_sysfs.c -index 3eb6611ab1b11..81b2ecfcc8060 100644 ---- a/drivers/crypto/qat/qat_common/adf_sysfs.c -+++ b/drivers/crypto/qat/qat_common/adf_sysfs.c -@@ -61,7 +61,9 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, - dev_info(dev, "Starting device qat_dev%d\n", accel_id); - - ret = adf_dev_up(accel_dev, true); -- if (ret < 0) { -+ if (ret == -EALREADY) { -+ break; -+ } else if (ret) { - dev_err(dev, "Failed to start device qat_dev%d\n", - accel_id); - adf_dev_down(accel_dev, true); -diff --git a/drivers/crypto/qat/qat_common/adf_transport_debug.c b/drivers/crypto/qat/qat_common/adf_transport_debug.c -index 08bca1c506c0e..e2dd568b87b51 100644 ---- a/drivers/crypto/qat/qat_common/adf_transport_debug.c -+++ b/drivers/crypto/qat/qat_common/adf_transport_debug.c -@@ -90,7 +90,7 @@ DEFINE_SEQ_ATTRIBUTE(adf_ring_debug); - int adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name) - { - struct adf_etr_ring_debug_entry *ring_debug; -- char entry_name[8]; -+ char entry_name[16]; - - ring_debug = kzalloc(sizeof(*ring_debug), GFP_KERNEL); - if (!ring_debug) -@@ -192,7 +192,7 @@ int adf_bank_debugfs_add(struct adf_etr_bank_data *bank) - { - struct adf_accel_dev *accel_dev = bank->accel_dev; - struct dentry *parent = accel_dev->transport->debug; -- char name[8]; -+ char name[16]; - - snprintf(name, sizeof(name), "bank_%02d", bank->bank_number); - bank->bank_debug_dir = debugfs_create_dir(name, parent); -diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c -index f56ee4cc5ae8b..b61ada5591586 100644 ---- a/drivers/crypto/qat/qat_common/qat_algs.c -+++ b/drivers/crypto/qat/qat_common/qat_algs.c -@@ -23,6 +23,7 @@ - #include "icp_qat_hw.h" - #include "icp_qat_fw.h" - #include "icp_qat_fw_la.h" -+#include "qat_bl.h" - - #define QAT_AES_HW_CONFIG_ENC(alg, mode) \ - ICP_QAT_HW_CIPHER_CONFIG_BUILD(mode, alg, \ -@@ -663,189 +664,6 @@ static int qat_alg_aead_setkey(struct crypto_aead *tfm, const u8 *key, - return qat_alg_aead_newkey(tfm, key, keylen); - } - --static void qat_alg_free_bufl(struct qat_crypto_instance *inst, -- struct qat_crypto_request *qat_req) --{ -- struct device *dev = &GET_DEV(inst->accel_dev); -- struct qat_alg_buf_list *bl = qat_req->buf.bl; -- struct qat_alg_buf_list *blout = qat_req->buf.blout; -- dma_addr_t blp = qat_req->buf.blp; -- dma_addr_t blpout = qat_req->buf.bloutp; -- size_t sz = qat_req->buf.sz; -- size_t sz_out = qat_req->buf.sz_out; -- int bl_dma_dir; -- int i; -- -- bl_dma_dir = blp != blpout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL; -- -- for (i = 0; i < bl->num_bufs; i++) -- dma_unmap_single(dev, bl->bufers[i].addr, -- bl->bufers[i].len, bl_dma_dir); -- -- dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE); -- -- if (!qat_req->buf.sgl_src_valid) -- kfree(bl); -- -- if (blp != blpout) { -- /* If out of place operation dma unmap only data */ -- int bufless = blout->num_bufs - blout->num_mapped_bufs; -- -- for (i = bufless; i < blout->num_bufs; i++) { -- dma_unmap_single(dev, blout->bufers[i].addr, -- blout->bufers[i].len, -- DMA_FROM_DEVICE); -- } -- dma_unmap_single(dev, blpout, sz_out, DMA_TO_DEVICE); -- -- if (!qat_req->buf.sgl_dst_valid) -- kfree(blout); -- } --} -- --static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, -- struct scatterlist *sgl, -- struct scatterlist *sglout, -- struct qat_crypto_request *qat_req, -- gfp_t flags) --{ -- struct device *dev = &GET_DEV(inst->accel_dev); -- int i, sg_nctr = 0; -- int n = sg_nents(sgl); -- struct qat_alg_buf_list *bufl; -- struct qat_alg_buf_list *buflout = NULL; -- dma_addr_t blp = DMA_MAPPING_ERROR; -- dma_addr_t bloutp = DMA_MAPPING_ERROR; -- struct scatterlist *sg; -- size_t sz_out, sz = struct_size(bufl, bufers, n); -- int node = dev_to_node(&GET_DEV(inst->accel_dev)); -- int bufl_dma_dir; -- -- if (unlikely(!n)) -- return -EINVAL; -- -- qat_req->buf.sgl_src_valid = false; -- qat_req->buf.sgl_dst_valid = false; -- -- if (n > QAT_MAX_BUFF_DESC) { -- bufl = kzalloc_node(sz, flags, node); -- if (unlikely(!bufl)) -- return -ENOMEM; -- } else { -- bufl = &qat_req->buf.sgl_src.sgl_hdr; -- memset(bufl, 0, sizeof(struct qat_alg_buf_list)); -- qat_req->buf.sgl_src_valid = true; -- } -- -- bufl_dma_dir = sgl != sglout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL; -- -- for_each_sg(sgl, sg, n, i) -- bufl->bufers[i].addr = DMA_MAPPING_ERROR; -- -- for_each_sg(sgl, sg, n, i) { -- int y = sg_nctr; -- -- if (!sg->length) -- continue; -- -- bufl->bufers[y].addr = dma_map_single(dev, sg_virt(sg), -- sg->length, -- bufl_dma_dir); -- bufl->bufers[y].len = sg->length; -- if (unlikely(dma_mapping_error(dev, bufl->bufers[y].addr))) -- goto err_in; -- sg_nctr++; -- } -- bufl->num_bufs = sg_nctr; -- blp = dma_map_single(dev, bufl, sz, DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(dev, blp))) -- goto err_in; -- qat_req->buf.bl = bufl; -- qat_req->buf.blp = blp; -- qat_req->buf.sz = sz; -- /* Handle out of place operation */ -- if (sgl != sglout) { -- struct qat_alg_buf *bufers; -- -- n = sg_nents(sglout); -- sz_out = struct_size(buflout, bufers, n); -- sg_nctr = 0; -- -- if (n > QAT_MAX_BUFF_DESC) { -- buflout = kzalloc_node(sz_out, flags, node); -- if (unlikely(!buflout)) -- goto err_in; -- } else { -- buflout = &qat_req->buf.sgl_dst.sgl_hdr; -- memset(buflout, 0, sizeof(struct qat_alg_buf_list)); -- qat_req->buf.sgl_dst_valid = true; -- } -- -- bufers = buflout->bufers; -- for_each_sg(sglout, sg, n, i) -- bufers[i].addr = DMA_MAPPING_ERROR; -- -- for_each_sg(sglout, sg, n, i) { -- int y = sg_nctr; -- -- if (!sg->length) -- continue; -- -- bufers[y].addr = dma_map_single(dev, sg_virt(sg), -- sg->length, -- DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(dev, bufers[y].addr))) -- goto err_out; -- bufers[y].len = sg->length; -- sg_nctr++; -- } -- buflout->num_bufs = sg_nctr; -- buflout->num_mapped_bufs = sg_nctr; -- bloutp = dma_map_single(dev, buflout, sz_out, DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(dev, bloutp))) -- goto err_out; -- qat_req->buf.blout = buflout; -- qat_req->buf.bloutp = bloutp; -- qat_req->buf.sz_out = sz_out; -- } else { -- /* Otherwise set the src and dst to the same address */ -- qat_req->buf.bloutp = qat_req->buf.blp; -- qat_req->buf.sz_out = 0; -- } -- return 0; -- --err_out: -- if (!dma_mapping_error(dev, bloutp)) -- dma_unmap_single(dev, bloutp, sz_out, DMA_TO_DEVICE); -- -- n = sg_nents(sglout); -- for (i = 0; i < n; i++) -- if (!dma_mapping_error(dev, buflout->bufers[i].addr)) -- dma_unmap_single(dev, buflout->bufers[i].addr, -- buflout->bufers[i].len, -- DMA_FROM_DEVICE); -- -- if (!qat_req->buf.sgl_dst_valid) -- kfree(buflout); -- --err_in: -- if (!dma_mapping_error(dev, blp)) -- dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE); -- -- n = sg_nents(sgl); -- for (i = 0; i < n; i++) -- if (!dma_mapping_error(dev, bufl->bufers[i].addr)) -- dma_unmap_single(dev, bufl->bufers[i].addr, -- bufl->bufers[i].len, -- bufl_dma_dir); -- -- if (!qat_req->buf.sgl_src_valid) -- kfree(bufl); -- -- dev_err(dev, "Failed to map buf for dma\n"); -- return -ENOMEM; --} -- - static void qat_aead_alg_callback(struct icp_qat_fw_la_resp *qat_resp, - struct qat_crypto_request *qat_req) - { -@@ -855,7 +673,7 @@ static void qat_aead_alg_callback(struct icp_qat_fw_la_resp *qat_resp, - u8 stat_filed = qat_resp->comn_resp.comn_status; - int res = 0, qat_res = ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(stat_filed); - -- qat_alg_free_bufl(inst, qat_req); -+ qat_bl_free_bufl(inst->accel_dev, &qat_req->buf); - if (unlikely(qat_res != ICP_QAT_FW_COMN_STATUS_FLAG_OK)) - res = -EBADMSG; - areq->base.complete(&areq->base, res); -@@ -925,7 +743,7 @@ static void qat_skcipher_alg_callback(struct icp_qat_fw_la_resp *qat_resp, - u8 stat_filed = qat_resp->comn_resp.comn_status; - int res = 0, qat_res = ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(stat_filed); - -- qat_alg_free_bufl(inst, qat_req); -+ qat_bl_free_bufl(inst->accel_dev, &qat_req->buf); - if (unlikely(qat_res != ICP_QAT_FW_COMN_STATUS_FLAG_OK)) - res = -EINVAL; - -@@ -981,7 +799,8 @@ static int qat_alg_aead_dec(struct aead_request *areq) - if (cipher_len % AES_BLOCK_SIZE != 0) - return -EINVAL; - -- ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req, f); -+ ret = qat_bl_sgl_to_bufl(ctx->inst->accel_dev, areq->src, areq->dst, -+ &qat_req->buf, NULL, f); - if (unlikely(ret)) - return ret; - -@@ -1003,7 +822,7 @@ static int qat_alg_aead_dec(struct aead_request *areq) - - ret = qat_alg_send_sym_message(qat_req, ctx->inst, &areq->base); - if (ret == -ENOSPC) -- qat_alg_free_bufl(ctx->inst, qat_req); -+ qat_bl_free_bufl(ctx->inst->accel_dev, &qat_req->buf); - - return ret; - } -@@ -1024,7 +843,8 @@ static int qat_alg_aead_enc(struct aead_request *areq) - if (areq->cryptlen % AES_BLOCK_SIZE != 0) - return -EINVAL; - -- ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req, f); -+ ret = qat_bl_sgl_to_bufl(ctx->inst->accel_dev, areq->src, areq->dst, -+ &qat_req->buf, NULL, f); - if (unlikely(ret)) - return ret; - -@@ -1048,7 +868,7 @@ static int qat_alg_aead_enc(struct aead_request *areq) - - ret = qat_alg_send_sym_message(qat_req, ctx->inst, &areq->base); - if (ret == -ENOSPC) -- qat_alg_free_bufl(ctx->inst, qat_req); -+ qat_bl_free_bufl(ctx->inst->accel_dev, &qat_req->buf); - - return ret; - } -@@ -1209,7 +1029,8 @@ static int qat_alg_skcipher_encrypt(struct skcipher_request *req) - if (req->cryptlen == 0) - return 0; - -- ret = qat_alg_sgl_to_bufl(ctx->inst, req->src, req->dst, qat_req, f); -+ ret = qat_bl_sgl_to_bufl(ctx->inst->accel_dev, req->src, req->dst, -+ &qat_req->buf, NULL, f); - if (unlikely(ret)) - return ret; - -@@ -1230,7 +1051,7 @@ static int qat_alg_skcipher_encrypt(struct skcipher_request *req) - - ret = qat_alg_send_sym_message(qat_req, ctx->inst, &req->base); - if (ret == -ENOSPC) -- qat_alg_free_bufl(ctx->inst, qat_req); -+ qat_bl_free_bufl(ctx->inst->accel_dev, &qat_req->buf); - - return ret; - } -@@ -1275,7 +1096,8 @@ static int qat_alg_skcipher_decrypt(struct skcipher_request *req) - if (req->cryptlen == 0) - return 0; - -- ret = qat_alg_sgl_to_bufl(ctx->inst, req->src, req->dst, qat_req, f); -+ ret = qat_bl_sgl_to_bufl(ctx->inst->accel_dev, req->src, req->dst, -+ &qat_req->buf, NULL, f); - if (unlikely(ret)) - return ret; - -@@ -1297,7 +1119,7 @@ static int qat_alg_skcipher_decrypt(struct skcipher_request *req) - - ret = qat_alg_send_sym_message(qat_req, ctx->inst, &req->base); - if (ret == -ENOSPC) -- qat_alg_free_bufl(ctx->inst, qat_req); -+ qat_bl_free_bufl(ctx->inst->accel_dev, &qat_req->buf); - - return ret; - } -diff --git a/drivers/crypto/qat/qat_common/qat_algs_send.c b/drivers/crypto/qat/qat_common/qat_algs_send.c -index ff5b4347f7831..607ed88f4b197 100644 ---- a/drivers/crypto/qat/qat_common/qat_algs_send.c -+++ b/drivers/crypto/qat/qat_common/qat_algs_send.c -@@ -39,40 +39,44 @@ void qat_alg_send_backlog(struct qat_instance_backlog *backlog) - spin_unlock_bh(&backlog->lock); - } - --static void qat_alg_backlog_req(struct qat_alg_req *req, -- struct qat_instance_backlog *backlog) --{ -- INIT_LIST_HEAD(&req->list); -- -- spin_lock_bh(&backlog->lock); -- list_add_tail(&req->list, &backlog->list); -- spin_unlock_bh(&backlog->lock); --} -- --static int qat_alg_send_message_maybacklog(struct qat_alg_req *req) -+static bool qat_alg_try_enqueue(struct qat_alg_req *req) - { - struct qat_instance_backlog *backlog = req->backlog; - struct adf_etr_ring_data *tx_ring = req->tx_ring; - u32 *fw_req = req->fw_req; - -- /* If any request is already backlogged, then add to backlog list */ -+ /* Check if any request is already backlogged */ - if (!list_empty(&backlog->list)) -- goto enqueue; -+ return false; - -- /* If ring is nearly full, then add to backlog list */ -+ /* Check if ring is nearly full */ - if (adf_ring_nearly_full(tx_ring)) -- goto enqueue; -+ return false; - -- /* If adding request to HW ring fails, then add to backlog list */ -+ /* Try to enqueue to HW ring */ - if (adf_send_message(tx_ring, fw_req)) -- goto enqueue; -+ return false; - -- return -EINPROGRESS; -+ return true; -+} - --enqueue: -- qat_alg_backlog_req(req, backlog); - -- return -EBUSY; -+static int qat_alg_send_message_maybacklog(struct qat_alg_req *req) -+{ -+ struct qat_instance_backlog *backlog = req->backlog; -+ int ret = -EINPROGRESS; -+ -+ if (qat_alg_try_enqueue(req)) -+ return ret; -+ -+ spin_lock_bh(&backlog->lock); -+ if (!qat_alg_try_enqueue(req)) { -+ list_add_tail(&req->list, &backlog->list); -+ ret = -EBUSY; -+ } -+ spin_unlock_bh(&backlog->lock); -+ -+ return ret; - } - - int qat_alg_send_message(struct qat_alg_req *req) -diff --git a/drivers/crypto/qat/qat_common/qat_bl.c b/drivers/crypto/qat/qat_common/qat_bl.c -new file mode 100644 -index 0000000000000..221a4eb610a38 ---- /dev/null -+++ b/drivers/crypto/qat/qat_common/qat_bl.c -@@ -0,0 +1,224 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright(c) 2014 - 2022 Intel Corporation */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "adf_accel_devices.h" -+#include "qat_bl.h" -+#include "qat_crypto.h" -+ -+void qat_bl_free_bufl(struct adf_accel_dev *accel_dev, -+ struct qat_request_buffs *buf) -+{ -+ struct device *dev = &GET_DEV(accel_dev); -+ struct qat_alg_buf_list *bl = buf->bl; -+ struct qat_alg_buf_list *blout = buf->blout; -+ dma_addr_t blp = buf->blp; -+ dma_addr_t blpout = buf->bloutp; -+ size_t sz = buf->sz; -+ size_t sz_out = buf->sz_out; -+ int bl_dma_dir; -+ int i; -+ -+ bl_dma_dir = blp != blpout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL; -+ -+ for (i = 0; i < bl->num_bufs; i++) -+ dma_unmap_single(dev, bl->bufers[i].addr, -+ bl->bufers[i].len, bl_dma_dir); -+ -+ dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE); -+ -+ if (!buf->sgl_src_valid) -+ kfree(bl); -+ -+ if (blp != blpout) { -+ for (i = 0; i < blout->num_mapped_bufs; i++) { -+ dma_unmap_single(dev, blout->bufers[i].addr, -+ blout->bufers[i].len, -+ DMA_FROM_DEVICE); -+ } -+ dma_unmap_single(dev, blpout, sz_out, DMA_TO_DEVICE); -+ -+ if (!buf->sgl_dst_valid) -+ kfree(blout); -+ } -+} -+ -+static int __qat_bl_sgl_to_bufl(struct adf_accel_dev *accel_dev, -+ struct scatterlist *sgl, -+ struct scatterlist *sglout, -+ struct qat_request_buffs *buf, -+ dma_addr_t extra_dst_buff, -+ size_t sz_extra_dst_buff, -+ gfp_t flags) -+{ -+ struct device *dev = &GET_DEV(accel_dev); -+ int i, sg_nctr = 0; -+ int n = sg_nents(sgl); -+ struct qat_alg_buf_list *bufl; -+ struct qat_alg_buf_list *buflout = NULL; -+ dma_addr_t blp = DMA_MAPPING_ERROR; -+ dma_addr_t bloutp = DMA_MAPPING_ERROR; -+ struct scatterlist *sg; -+ size_t sz_out, sz = struct_size(bufl, bufers, n); -+ int node = dev_to_node(&GET_DEV(accel_dev)); -+ int bufl_dma_dir; -+ -+ if (unlikely(!n)) -+ return -EINVAL; -+ -+ buf->sgl_src_valid = false; -+ buf->sgl_dst_valid = false; -+ -+ if (n > QAT_MAX_BUFF_DESC) { -+ bufl = kzalloc_node(sz, flags, node); -+ if (unlikely(!bufl)) -+ return -ENOMEM; -+ } else { -+ bufl = &buf->sgl_src.sgl_hdr; -+ memset(bufl, 0, sizeof(struct qat_alg_buf_list)); -+ buf->sgl_src_valid = true; -+ } -+ -+ bufl_dma_dir = sgl != sglout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL; -+ -+ for (i = 0; i < n; i++) -+ bufl->bufers[i].addr = DMA_MAPPING_ERROR; -+ -+ for_each_sg(sgl, sg, n, i) { -+ int y = sg_nctr; -+ -+ if (!sg->length) -+ continue; -+ -+ bufl->bufers[y].addr = dma_map_single(dev, sg_virt(sg), -+ sg->length, -+ bufl_dma_dir); -+ bufl->bufers[y].len = sg->length; -+ if (unlikely(dma_mapping_error(dev, bufl->bufers[y].addr))) -+ goto err_in; -+ sg_nctr++; -+ } -+ bufl->num_bufs = sg_nctr; -+ blp = dma_map_single(dev, bufl, sz, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(dev, blp))) -+ goto err_in; -+ buf->bl = bufl; -+ buf->blp = blp; -+ buf->sz = sz; -+ /* Handle out of place operation */ -+ if (sgl != sglout) { -+ struct qat_alg_buf *bufers; -+ int extra_buff = extra_dst_buff ? 1 : 0; -+ int n_sglout = sg_nents(sglout); -+ -+ n = n_sglout + extra_buff; -+ sz_out = struct_size(buflout, bufers, n); -+ sg_nctr = 0; -+ -+ if (n > QAT_MAX_BUFF_DESC) { -+ buflout = kzalloc_node(sz_out, flags, node); -+ if (unlikely(!buflout)) -+ goto err_in; -+ } else { -+ buflout = &buf->sgl_dst.sgl_hdr; -+ memset(buflout, 0, sizeof(struct qat_alg_buf_list)); -+ buf->sgl_dst_valid = true; -+ } -+ -+ bufers = buflout->bufers; -+ for (i = 0; i < n; i++) -+ bufers[i].addr = DMA_MAPPING_ERROR; -+ -+ for_each_sg(sglout, sg, n_sglout, i) { -+ int y = sg_nctr; -+ -+ if (!sg->length) -+ continue; -+ -+ bufers[y].addr = dma_map_single(dev, sg_virt(sg), -+ sg->length, -+ DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(dev, bufers[y].addr))) -+ goto err_out; -+ bufers[y].len = sg->length; -+ sg_nctr++; -+ } -+ if (extra_buff) { -+ bufers[sg_nctr].addr = extra_dst_buff; -+ bufers[sg_nctr].len = sz_extra_dst_buff; -+ } -+ -+ buflout->num_bufs = sg_nctr; -+ buflout->num_bufs += extra_buff; -+ buflout->num_mapped_bufs = sg_nctr; -+ bloutp = dma_map_single(dev, buflout, sz_out, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(dev, bloutp))) -+ goto err_out; -+ buf->blout = buflout; -+ buf->bloutp = bloutp; -+ buf->sz_out = sz_out; -+ } else { -+ /* Otherwise set the src and dst to the same address */ -+ buf->bloutp = buf->blp; -+ buf->sz_out = 0; -+ } -+ return 0; -+ -+err_out: -+ if (!dma_mapping_error(dev, bloutp)) -+ dma_unmap_single(dev, bloutp, sz_out, DMA_TO_DEVICE); -+ -+ n = sg_nents(sglout); -+ for (i = 0; i < n; i++) { -+ if (buflout->bufers[i].addr == extra_dst_buff) -+ break; -+ if (!dma_mapping_error(dev, buflout->bufers[i].addr)) -+ dma_unmap_single(dev, buflout->bufers[i].addr, -+ buflout->bufers[i].len, -+ DMA_FROM_DEVICE); -+ } -+ -+ if (!buf->sgl_dst_valid) -+ kfree(buflout); -+ -+err_in: -+ if (!dma_mapping_error(dev, blp)) -+ dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE); -+ -+ n = sg_nents(sgl); -+ for (i = 0; i < n; i++) -+ if (!dma_mapping_error(dev, bufl->bufers[i].addr)) -+ dma_unmap_single(dev, bufl->bufers[i].addr, -+ bufl->bufers[i].len, -+ bufl_dma_dir); -+ -+ if (!buf->sgl_src_valid) -+ kfree(bufl); -+ -+ dev_err(dev, "Failed to map buf for dma\n"); -+ return -ENOMEM; -+} -+ -+int qat_bl_sgl_to_bufl(struct adf_accel_dev *accel_dev, -+ struct scatterlist *sgl, -+ struct scatterlist *sglout, -+ struct qat_request_buffs *buf, -+ struct qat_sgl_to_bufl_params *params, -+ gfp_t flags) -+{ -+ dma_addr_t extra_dst_buff = 0; -+ size_t sz_extra_dst_buff = 0; -+ -+ if (params) { -+ extra_dst_buff = params->extra_dst_buff; -+ sz_extra_dst_buff = params->sz_extra_dst_buff; -+ } -+ -+ return __qat_bl_sgl_to_bufl(accel_dev, sgl, sglout, buf, -+ extra_dst_buff, sz_extra_dst_buff, -+ flags); -+} -diff --git a/drivers/crypto/qat/qat_common/qat_bl.h b/drivers/crypto/qat/qat_common/qat_bl.h -new file mode 100644 -index 0000000000000..0c174fee9e645 ---- /dev/null -+++ b/drivers/crypto/qat/qat_common/qat_bl.h -@@ -0,0 +1,55 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* Copyright(c) 2014 - 2022 Intel Corporation */ -+#ifndef QAT_BL_H -+#define QAT_BL_H -+#include -+#include -+ -+#define QAT_MAX_BUFF_DESC 4 -+ -+struct qat_alg_buf { -+ u32 len; -+ u32 resrvd; -+ u64 addr; -+} __packed; -+ -+struct qat_alg_buf_list { -+ u64 resrvd; -+ u32 num_bufs; -+ u32 num_mapped_bufs; -+ struct qat_alg_buf bufers[]; -+} __packed; -+ -+struct qat_alg_fixed_buf_list { -+ struct qat_alg_buf_list sgl_hdr; -+ struct qat_alg_buf descriptors[QAT_MAX_BUFF_DESC]; -+} __packed __aligned(64); -+ -+struct qat_request_buffs { -+ struct qat_alg_buf_list *bl; -+ dma_addr_t blp; -+ struct qat_alg_buf_list *blout; -+ dma_addr_t bloutp; -+ size_t sz; -+ size_t sz_out; -+ bool sgl_src_valid; -+ bool sgl_dst_valid; -+ struct qat_alg_fixed_buf_list sgl_src; -+ struct qat_alg_fixed_buf_list sgl_dst; -+}; -+ -+struct qat_sgl_to_bufl_params { -+ dma_addr_t extra_dst_buff; -+ size_t sz_extra_dst_buff; -+}; -+ -+void qat_bl_free_bufl(struct adf_accel_dev *accel_dev, -+ struct qat_request_buffs *buf); -+int qat_bl_sgl_to_bufl(struct adf_accel_dev *accel_dev, -+ struct scatterlist *sgl, -+ struct scatterlist *sglout, -+ struct qat_request_buffs *buf, -+ struct qat_sgl_to_bufl_params *params, -+ gfp_t flags); -+ -+#endif -diff --git a/drivers/crypto/qat/qat_common/qat_crypto.h b/drivers/crypto/qat/qat_common/qat_crypto.h -index df3c738ce323a..bb116357a5684 100644 ---- a/drivers/crypto/qat/qat_common/qat_crypto.h -+++ b/drivers/crypto/qat/qat_common/qat_crypto.h -@@ -8,6 +8,7 @@ - #include - #include "adf_accel_devices.h" - #include "icp_qat_fw_la.h" -+#include "qat_bl.h" - - struct qat_instance_backlog { - struct list_head list; -@@ -35,39 +36,6 @@ struct qat_crypto_instance { - struct qat_instance_backlog backlog; - }; - --#define QAT_MAX_BUFF_DESC 4 -- --struct qat_alg_buf { -- u32 len; -- u32 resrvd; -- u64 addr; --} __packed; -- --struct qat_alg_buf_list { -- u64 resrvd; -- u32 num_bufs; -- u32 num_mapped_bufs; -- struct qat_alg_buf bufers[]; --} __packed; -- --struct qat_alg_fixed_buf_list { -- struct qat_alg_buf_list sgl_hdr; -- struct qat_alg_buf descriptors[QAT_MAX_BUFF_DESC]; --} __packed __aligned(64); -- --struct qat_crypto_request_buffs { -- struct qat_alg_buf_list *bl; -- dma_addr_t blp; -- struct qat_alg_buf_list *blout; -- dma_addr_t bloutp; -- size_t sz; -- size_t sz_out; -- bool sgl_src_valid; -- bool sgl_dst_valid; -- struct qat_alg_fixed_buf_list sgl_src; -- struct qat_alg_fixed_buf_list sgl_dst; --}; -- - struct qat_crypto_request; - - struct qat_crypto_request { -@@ -80,7 +48,7 @@ struct qat_crypto_request { - struct aead_request *aead_req; - struct skcipher_request *skcipher_req; - }; -- struct qat_crypto_request_buffs buf; -+ struct qat_request_buffs buf; - void (*cb)(struct icp_qat_fw_la_resp *resp, - struct qat_crypto_request *req); - union { -diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c -index 20ce488a77540..03cf99cce7047 100644 ---- a/drivers/cxl/core/memdev.c -+++ b/drivers/cxl/core/memdev.c -@@ -214,8 +214,8 @@ static void cxl_memdev_unregister(void *_cxlmd) - struct cxl_memdev *cxlmd = _cxlmd; - struct device *dev = &cxlmd->dev; - -- cxl_memdev_shutdown(dev); - cdev_device_del(&cxlmd->cdev, dev); -+ cxl_memdev_shutdown(dev); - put_device(dev); - } - -diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c -index 39ac069cabc75..74893c06aa087 100644 ---- a/drivers/devfreq/event/rockchip-dfi.c -+++ b/drivers/devfreq/event/rockchip-dfi.c -@@ -193,14 +193,15 @@ static int rockchip_dfi_probe(struct platform_device *pdev) - return dev_err_probe(dev, PTR_ERR(data->clk), - "Cannot get the clk pclk_ddr_mon\n"); - -- /* try to find the optional reference to the pmu syscon */ - node = of_parse_phandle(np, "rockchip,pmu", 0); -- if (node) { -- data->regmap_pmu = syscon_node_to_regmap(node); -- of_node_put(node); -- if (IS_ERR(data->regmap_pmu)) -- return PTR_ERR(data->regmap_pmu); -- } -+ if (!node) -+ return dev_err_probe(&pdev->dev, -ENODEV, "Can't find pmu_grf registers\n"); -+ -+ data->regmap_pmu = syscon_node_to_regmap(node); -+ of_node_put(node); -+ if (IS_ERR(data->regmap_pmu)) -+ return PTR_ERR(data->regmap_pmu); -+ - data->dev = dev; - - desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); -diff --git a/drivers/dma/idxd/Makefile b/drivers/dma/idxd/Makefile -index a1e9f2b3a37cc..817ffa95a9b11 100644 ---- a/drivers/dma/idxd/Makefile -+++ b/drivers/dma/idxd/Makefile -@@ -1,12 +1,12 @@ - ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=IDXD - -+obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o -+idxd_bus-y := bus.o -+ - obj-$(CONFIG_INTEL_IDXD) += idxd.o - idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o - - idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o - --obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o --idxd_bus-y := bus.o -- - obj-$(CONFIG_INTEL_IDXD_COMPAT) += idxd_compat.o - idxd_compat-y := compat.o -diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c -index 22a392fe6d32b..04c1f2ee874a5 100644 ---- a/drivers/dma/pxa_dma.c -+++ b/drivers/dma/pxa_dma.c -@@ -722,7 +722,6 @@ static void pxad_free_desc(struct virt_dma_desc *vd) - dma_addr_t dma; - struct pxad_desc_sw *sw_desc = to_pxad_sw_desc(vd); - -- BUG_ON(sw_desc->nb_desc == 0); - for (i = sw_desc->nb_desc - 1; i >= 0; i--) { - if (i > 0) - dma = sw_desc->hw_desc[i - 1]->ddadr; -diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c -index fa06d7e6d8e38..7ec6e5d728b03 100644 ---- a/drivers/dma/ti/edma.c -+++ b/drivers/dma/ti/edma.c -@@ -2410,7 +2410,7 @@ static int edma_probe(struct platform_device *pdev) - if (irq < 0 && node) - irq = irq_of_parse_and_map(node, 0); - -- if (irq >= 0) { -+ if (irq > 0) { - irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint", - dev_name(dev)); - ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name, -@@ -2426,7 +2426,7 @@ static int edma_probe(struct platform_device *pdev) - if (irq < 0 && node) - irq = irq_of_parse_and_map(node, 2); - -- if (irq >= 0) { -+ if (irq > 0) { - irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint", - dev_name(dev)); - ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name, -diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c -index b9ce784f087df..248594b59c64d 100644 ---- a/drivers/firmware/arm_ffa/bus.c -+++ b/drivers/firmware/arm_ffa/bus.c -@@ -193,6 +193,7 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, - dev->release = ffa_release_device; - dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id); - -+ ffa_dev->id = id; - ffa_dev->vm_id = vm_id; - ffa_dev->ops = ops; - uuid_copy(&ffa_dev->uuid, uuid); -diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c -index 21481fc05800f..e9f86b7573012 100644 ---- a/drivers/firmware/arm_ffa/driver.c -+++ b/drivers/firmware/arm_ffa/driver.c -@@ -668,17 +668,9 @@ static int ffa_partition_info_get(const char *uuid_str, - return 0; - } - --static void _ffa_mode_32bit_set(struct ffa_device *dev) --{ -- dev->mode_32bit = true; --} -- - static void ffa_mode_32bit_set(struct ffa_device *dev) - { -- if (drv_info->version > FFA_VERSION_1_0) -- return; -- -- _ffa_mode_32bit_set(dev); -+ dev->mode_32bit = true; - } - - static int ffa_sync_send_receive(struct ffa_device *dev, -@@ -787,7 +779,7 @@ static void ffa_setup_partitions(void) - - if (drv_info->version > FFA_VERSION_1_0 && - !(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC)) -- _ffa_mode_32bit_set(ffa_dev); -+ ffa_mode_32bit_set(ffa_dev); - } - kfree(pbuf); - } -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 4c550cfbc086c..597d1a367d96d 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -190,19 +190,6 @@ static int ti_sci_debugfs_create(struct platform_device *pdev, - return 0; - } - --/** -- * ti_sci_debugfs_destroy() - clean up log debug file -- * @pdev: platform device pointer -- * @info: Pointer to SCI entity information -- */ --static void ti_sci_debugfs_destroy(struct platform_device *pdev, -- struct ti_sci_info *info) --{ -- if (IS_ERR(info->debug_region)) -- return; -- -- debugfs_remove(info->d); --} - #else /* CONFIG_DEBUG_FS */ - static inline int ti_sci_debugfs_create(struct platform_device *dev, - struct ti_sci_info *info) -@@ -3451,43 +3438,12 @@ out: - return ret; - } - --static int ti_sci_remove(struct platform_device *pdev) --{ -- struct ti_sci_info *info; -- struct device *dev = &pdev->dev; -- int ret = 0; -- -- of_platform_depopulate(dev); -- -- info = platform_get_drvdata(pdev); -- -- if (info->nb.notifier_call) -- unregister_restart_handler(&info->nb); -- -- mutex_lock(&ti_sci_list_mutex); -- if (info->users) -- ret = -EBUSY; -- else -- list_del(&info->node); -- mutex_unlock(&ti_sci_list_mutex); -- -- if (!ret) { -- ti_sci_debugfs_destroy(pdev, info); -- -- /* Safe to free channels since no more users */ -- mbox_free_channel(info->chan_tx); -- mbox_free_channel(info->chan_rx); -- } -- -- return ret; --} -- - static struct platform_driver ti_sci_driver = { - .probe = ti_sci_probe, -- .remove = ti_sci_remove, - .driver = { - .name = "ti-sci", - .of_match_table = of_match_ptr(ti_sci_of_match), -+ .suppress_bind_attrs = true, - }, - }; - module_platform_driver(ti_sci_driver); -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -index 63feea08904cb..d7e758c86a0b8 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -@@ -487,11 +487,11 @@ svm_range_validate_svm_bo(struct amdgpu_device *adev, struct svm_range *prange) - - /* We need a new svm_bo. Spin-loop to wait for concurrent - * svm_range_bo_release to finish removing this range from -- * its range list. After this, it is safe to reuse the -- * svm_bo pointer and svm_bo_list head. -+ * its range list and set prange->svm_bo to null. After this, -+ * it is safe to reuse the svm_bo pointer and svm_bo_list head. - */ -- while (!list_empty_careful(&prange->svm_bo_list)) -- ; -+ while (!list_empty_careful(&prange->svm_bo_list) || prange->svm_bo) -+ cond_resched(); - - return false; - } -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 339f1f5a08339..42e266e074d1d 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -9626,16 +9626,27 @@ static void dm_get_oriented_plane_size(struct drm_plane_state *plane_state, - } - } - -+static void -+dm_get_plane_scale(struct drm_plane_state *plane_state, -+ int *out_plane_scale_w, int *out_plane_scale_h) -+{ -+ int plane_src_w, plane_src_h; -+ -+ dm_get_oriented_plane_size(plane_state, &plane_src_w, &plane_src_h); -+ *out_plane_scale_w = plane_state->crtc_w * 1000 / plane_src_w; -+ *out_plane_scale_h = plane_state->crtc_h * 1000 / plane_src_h; -+} -+ - static int dm_check_crtc_cursor(struct drm_atomic_state *state, - struct drm_crtc *crtc, - struct drm_crtc_state *new_crtc_state) - { -- struct drm_plane *cursor = crtc->cursor, *underlying; -+ struct drm_plane *cursor = crtc->cursor, *plane, *underlying; -+ struct drm_plane_state *old_plane_state, *new_plane_state; - struct drm_plane_state *new_cursor_state, *new_underlying_state; - int i; - int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h; -- int cursor_src_w, cursor_src_h; -- int underlying_src_w, underlying_src_h; -+ bool any_relevant_change = false; - - /* On DCE and DCN there is no dedicated hardware cursor plane. We get a - * cursor per pipe but it's going to inherit the scaling and -@@ -9643,13 +9654,50 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, - * blending properties match the underlying planes'. - */ - -- new_cursor_state = drm_atomic_get_new_plane_state(state, cursor); -- if (!new_cursor_state || !new_cursor_state->fb) -+ /* If no plane was enabled or changed scaling, no need to check again */ -+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { -+ int new_scale_w, new_scale_h, old_scale_w, old_scale_h; -+ -+ if (!new_plane_state || !new_plane_state->fb || new_plane_state->crtc != crtc) -+ continue; -+ -+ if (!old_plane_state || !old_plane_state->fb || old_plane_state->crtc != crtc) { -+ any_relevant_change = true; -+ break; -+ } -+ -+ if (new_plane_state->fb == old_plane_state->fb && -+ new_plane_state->crtc_w == old_plane_state->crtc_w && -+ new_plane_state->crtc_h == old_plane_state->crtc_h) -+ continue; -+ -+ dm_get_plane_scale(new_plane_state, &new_scale_w, &new_scale_h); -+ dm_get_plane_scale(old_plane_state, &old_scale_w, &old_scale_h); -+ -+ if (new_scale_w != old_scale_w || new_scale_h != old_scale_h) { -+ any_relevant_change = true; -+ break; -+ } -+ } -+ -+ if (!any_relevant_change) -+ return 0; -+ -+ new_cursor_state = drm_atomic_get_plane_state(state, cursor); -+ if (IS_ERR(new_cursor_state)) -+ return PTR_ERR(new_cursor_state); -+ -+ if (!new_cursor_state->fb) - return 0; - -- dm_get_oriented_plane_size(new_cursor_state, &cursor_src_w, &cursor_src_h); -- cursor_scale_w = new_cursor_state->crtc_w * 1000 / cursor_src_w; -- cursor_scale_h = new_cursor_state->crtc_h * 1000 / cursor_src_h; -+ dm_get_plane_scale(new_cursor_state, &cursor_scale_w, &cursor_scale_h); -+ -+ /* Need to check all enabled planes, even if this commit doesn't change -+ * their state -+ */ -+ i = drm_atomic_add_affected_planes(state, crtc); -+ if (i) -+ return i; - - for_each_new_plane_in_state_reverse(state, underlying, new_underlying_state, i) { - /* Narrow down to non-cursor planes on the same CRTC as the cursor */ -@@ -9660,10 +9708,8 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state, - if (!new_underlying_state->fb) - continue; - -- dm_get_oriented_plane_size(new_underlying_state, -- &underlying_src_w, &underlying_src_h); -- underlying_scale_w = new_underlying_state->crtc_w * 1000 / underlying_src_w; -- underlying_scale_h = new_underlying_state->crtc_h * 1000 / underlying_src_h; -+ dm_get_plane_scale(new_underlying_state, -+ &underlying_scale_w, &underlying_scale_h); - - if (cursor_scale_w != underlying_scale_w || - cursor_scale_h != underlying_scale_h) { -diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c -index 4f6f1deba28c6..9d7f3c99748b4 100644 ---- a/drivers/gpu/drm/bridge/ite-it66121.c -+++ b/drivers/gpu/drm/bridge/ite-it66121.c -@@ -1464,10 +1464,14 @@ static int it66121_audio_get_eld(struct device *dev, void *data, - struct it66121_ctx *ctx = dev_get_drvdata(dev); - - mutex_lock(&ctx->lock); -- -- memcpy(buf, ctx->connector->eld, -- min(sizeof(ctx->connector->eld), len)); -- -+ if (!ctx->connector) { -+ /* Pass en empty ELD if connector not available */ -+ dev_dbg(dev, "No connector present, passing empty EDID data"); -+ memset(buf, 0, len); -+ } else { -+ memcpy(buf, ctx->connector->eld, -+ min(sizeof(ctx->connector->eld), len)); -+ } - mutex_unlock(&ctx->lock); - - return 0; -diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c -index 5e419934d2a39..ac76c23635892 100644 ---- a/drivers/gpu/drm/bridge/lontium-lt8912b.c -+++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c -@@ -45,7 +45,6 @@ struct lt8912 { - - u8 data_lanes; - bool is_power_on; -- bool is_attached; - }; - - static int lt8912_write_init_config(struct lt8912 *lt) -@@ -516,14 +515,27 @@ static int lt8912_attach_dsi(struct lt8912 *lt) - return 0; - } - -+static void lt8912_bridge_hpd_cb(void *data, enum drm_connector_status status) -+{ -+ struct lt8912 *lt = data; -+ -+ if (lt->bridge.dev) -+ drm_helper_hpd_irq_event(lt->bridge.dev); -+} -+ - static int lt8912_bridge_connector_init(struct drm_bridge *bridge) - { - int ret; - struct lt8912 *lt = bridge_to_lt8912(bridge); - struct drm_connector *connector = <->connector; - -- connector->polled = DRM_CONNECTOR_POLL_CONNECT | -- DRM_CONNECTOR_POLL_DISCONNECT; -+ if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) { -+ drm_bridge_hpd_enable(lt->hdmi_port, lt8912_bridge_hpd_cb, lt); -+ connector->polled = DRM_CONNECTOR_POLL_HPD; -+ } else { -+ connector->polled = DRM_CONNECTOR_POLL_CONNECT | -+ DRM_CONNECTOR_POLL_DISCONNECT; -+ } - - ret = drm_connector_init(bridge->dev, connector, - <8912_connector_funcs, -@@ -546,6 +558,13 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge, - struct lt8912 *lt = bridge_to_lt8912(bridge); - int ret; - -+ ret = drm_bridge_attach(bridge->encoder, lt->hdmi_port, bridge, -+ DRM_BRIDGE_ATTACH_NO_CONNECTOR); -+ if (ret < 0) { -+ dev_err(lt->dev, "Failed to attach next bridge (%d)\n", ret); -+ return ret; -+ } -+ - if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { - ret = lt8912_bridge_connector_init(bridge); - if (ret) { -@@ -562,8 +581,6 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge, - if (ret) - goto error; - -- lt->is_attached = true; -- - return 0; - - error: -@@ -575,11 +592,10 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge) - { - struct lt8912 *lt = bridge_to_lt8912(bridge); - -- if (lt->is_attached) { -- lt8912_hard_power_off(lt); -- drm_connector_unregister(<->connector); -- drm_connector_cleanup(<->connector); -- } -+ lt8912_hard_power_off(lt); -+ -+ if (lt->connector.dev && lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) -+ drm_bridge_hpd_disable(lt->hdmi_port); - } - - static enum drm_connector_status -@@ -734,7 +750,6 @@ static void lt8912_remove(struct i2c_client *client) - { - struct lt8912 *lt = i2c_get_clientdata(client); - -- lt8912_bridge_detach(<->bridge); - drm_bridge_remove(<->bridge); - lt8912_free_i2c(lt); - lt8912_put_dt(lt); -diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c -index fa1ee6264d921..818848b2c04dd 100644 ---- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c -+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c -@@ -928,9 +928,9 @@ retry: - init_waitqueue_head(<9611uxc->wq); - INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work); - -- ret = devm_request_threaded_irq(dev, client->irq, NULL, -- lt9611uxc_irq_thread_handler, -- IRQF_ONESHOT, "lt9611uxc", lt9611uxc); -+ ret = request_threaded_irq(client->irq, NULL, -+ lt9611uxc_irq_thread_handler, -+ IRQF_ONESHOT, "lt9611uxc", lt9611uxc); - if (ret) { - dev_err(dev, "failed to request irq\n"); - goto err_disable_regulators; -@@ -966,6 +966,8 @@ retry: - return lt9611uxc_audio_init(dev, lt9611uxc); - - err_remove_bridge: -+ free_irq(client->irq, lt9611uxc); -+ cancel_work_sync(<9611uxc->work); - drm_bridge_remove(<9611uxc->bridge); - - err_disable_regulators: -@@ -982,7 +984,7 @@ static void lt9611uxc_remove(struct i2c_client *client) - { - struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client); - -- disable_irq(client->irq); -+ free_irq(client->irq, lt9611uxc); - cancel_work_sync(<9611uxc->work); - lt9611uxc_audio_exit(lt9611uxc); - drm_bridge_remove(<9611uxc->bridge); -diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c -index 2d0ac9987b58e..8429b6518b502 100644 ---- a/drivers/gpu/drm/bridge/tc358768.c -+++ b/drivers/gpu/drm/bridge/tc358768.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -217,6 +218,10 @@ static void tc358768_update_bits(struct tc358768_priv *priv, u32 reg, u32 mask, - u32 tmp, orig; - - tc358768_read(priv, reg, &orig); -+ -+ if (priv->error) -+ return; -+ - tmp = orig & ~mask; - tmp |= val & mask; - if (tmp != orig) -@@ -601,7 +606,7 @@ static int tc358768_setup_pll(struct tc358768_priv *priv, - - dev_dbg(priv->dev, "PLL: refclk %lu, fbd %u, prd %u, frs %u\n", - clk_get_rate(priv->refclk), fbd, prd, frs); -- dev_dbg(priv->dev, "PLL: pll_clk: %u, DSIClk %u, DSIByteClk %u\n", -+ dev_dbg(priv->dev, "PLL: pll_clk: %u, DSIClk %u, HSByteClk %u\n", - priv->dsiclk * 2, priv->dsiclk, priv->dsiclk / 4); - dev_dbg(priv->dev, "PLL: pclk %u (panel: %u)\n", - tc358768_pll_to_pclk(priv, priv->dsiclk * 2), -@@ -624,15 +629,14 @@ static int tc358768_setup_pll(struct tc358768_priv *priv, - return tc358768_clear_error(priv); - } - --#define TC358768_PRECISION 1000 --static u32 tc358768_ns_to_cnt(u32 ns, u32 period_nsk) -+static u32 tc358768_ns_to_cnt(u32 ns, u32 period_ps) - { -- return (ns * TC358768_PRECISION + period_nsk) / period_nsk; -+ return DIV_ROUND_UP(ns * 1000, period_ps); - } - --static u32 tc358768_to_ns(u32 nsk) -+static u32 tc358768_ps_to_ns(u32 ps) - { -- return (nsk / TC358768_PRECISION); -+ return ps / 1000; - } - - static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) -@@ -643,13 +647,15 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) - u32 val, val2, lptxcnt, hact, data_type; - s32 raw_val; - const struct drm_display_mode *mode; -- u32 dsibclk_nsk, dsiclk_nsk, ui_nsk, phy_delay_nsk; -- u32 dsiclk, dsibclk, video_start; -+ u32 hsbyteclk_ps, dsiclk_ps, ui_ps; -+ u32 dsiclk, hsbyteclk, video_start; - const u32 internal_delay = 40; - int ret, i; -+ struct videomode vm; -+ struct device *dev = priv->dev; - - if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) { -- dev_warn_once(priv->dev, "Non-continuous mode unimplemented, falling back to continuous\n"); -+ dev_warn_once(dev, "Non-continuous mode unimplemented, falling back to continuous\n"); - mode_flags &= ~MIPI_DSI_CLOCK_NON_CONTINUOUS; - } - -@@ -657,7 +663,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) - - ret = tc358768_sw_reset(priv); - if (ret) { -- dev_err(priv->dev, "Software reset failed: %d\n", ret); -+ dev_err(dev, "Software reset failed: %d\n", ret); - tc358768_hw_disable(priv); - return; - } -@@ -665,45 +671,47 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) - mode = &bridge->encoder->crtc->state->adjusted_mode; - ret = tc358768_setup_pll(priv, mode); - if (ret) { -- dev_err(priv->dev, "PLL setup failed: %d\n", ret); -+ dev_err(dev, "PLL setup failed: %d\n", ret); - tc358768_hw_disable(priv); - return; - } - -+ drm_display_mode_to_videomode(mode, &vm); -+ - dsiclk = priv->dsiclk; -- dsibclk = dsiclk / 4; -+ hsbyteclk = dsiclk / 4; - - /* Data Format Control Register */ - val = BIT(2) | BIT(1) | BIT(0); /* rdswap_en | dsitx_en | txdt_en */ - switch (dsi_dev->format) { - case MIPI_DSI_FMT_RGB888: - val |= (0x3 << 4); -- hact = mode->hdisplay * 3; -- video_start = (mode->htotal - mode->hsync_start) * 3; -+ hact = vm.hactive * 3; -+ video_start = (vm.hsync_len + vm.hback_porch) * 3; - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; - break; - case MIPI_DSI_FMT_RGB666: - val |= (0x4 << 4); -- hact = mode->hdisplay * 3; -- video_start = (mode->htotal - mode->hsync_start) * 3; -+ hact = vm.hactive * 3; -+ video_start = (vm.hsync_len + vm.hback_porch) * 3; - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18; - break; - - case MIPI_DSI_FMT_RGB666_PACKED: - val |= (0x4 << 4) | BIT(3); -- hact = mode->hdisplay * 18 / 8; -- video_start = (mode->htotal - mode->hsync_start) * 18 / 8; -+ hact = vm.hactive * 18 / 8; -+ video_start = (vm.hsync_len + vm.hback_porch) * 18 / 8; - data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18; - break; - - case MIPI_DSI_FMT_RGB565: - val |= (0x5 << 4); -- hact = mode->hdisplay * 2; -- video_start = (mode->htotal - mode->hsync_start) * 2; -+ hact = vm.hactive * 2; -+ video_start = (vm.hsync_len + vm.hback_porch) * 2; - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16; - break; - default: -- dev_err(priv->dev, "Invalid data format (%u)\n", -+ dev_err(dev, "Invalid data format (%u)\n", - dsi_dev->format); - tc358768_hw_disable(priv); - return; -@@ -723,69 +731,67 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) - tc358768_write(priv, TC358768_D0W_CNTRL + i * 4, 0x0000); - - /* DSI Timings */ -- dsibclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, -- dsibclk); -- dsiclk_nsk = (u32)div_u64((u64)1000000000 * TC358768_PRECISION, dsiclk); -- ui_nsk = dsiclk_nsk / 2; -- phy_delay_nsk = dsibclk_nsk + 2 * dsiclk_nsk; -- dev_dbg(priv->dev, "dsiclk_nsk: %u\n", dsiclk_nsk); -- dev_dbg(priv->dev, "ui_nsk: %u\n", ui_nsk); -- dev_dbg(priv->dev, "dsibclk_nsk: %u\n", dsibclk_nsk); -- dev_dbg(priv->dev, "phy_delay_nsk: %u\n", phy_delay_nsk); -+ hsbyteclk_ps = (u32)div_u64(PICO, hsbyteclk); -+ dsiclk_ps = (u32)div_u64(PICO, dsiclk); -+ ui_ps = dsiclk_ps / 2; -+ dev_dbg(dev, "dsiclk: %u ps, ui %u ps, hsbyteclk %u ps\n", dsiclk_ps, -+ ui_ps, hsbyteclk_ps); - - /* LP11 > 100us for D-PHY Rx Init */ -- val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1; -- dev_dbg(priv->dev, "LINEINITCNT: 0x%x\n", val); -+ val = tc358768_ns_to_cnt(100 * 1000, hsbyteclk_ps) - 1; -+ dev_dbg(dev, "LINEINITCNT: %u\n", val); - tc358768_write(priv, TC358768_LINEINITCNT, val); - - /* LPTimeCnt > 50ns */ -- val = tc358768_ns_to_cnt(50, dsibclk_nsk) - 1; -+ val = tc358768_ns_to_cnt(50, hsbyteclk_ps) - 1; - lptxcnt = val; -- dev_dbg(priv->dev, "LPTXTIMECNT: 0x%x\n", val); -+ dev_dbg(dev, "LPTXTIMECNT: %u\n", val); - tc358768_write(priv, TC358768_LPTXTIMECNT, val); - - /* 38ns < TCLK_PREPARE < 95ns */ -- val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1; -+ val = tc358768_ns_to_cnt(65, hsbyteclk_ps) - 1; -+ dev_dbg(dev, "TCLK_PREPARECNT %u\n", val); - /* TCLK_PREPARE + TCLK_ZERO > 300ns */ -- val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk), -- dsibclk_nsk) - 2; -+ val2 = tc358768_ns_to_cnt(300 - tc358768_ps_to_ns(2 * ui_ps), -+ hsbyteclk_ps) - 2; -+ dev_dbg(dev, "TCLK_ZEROCNT %u\n", val2); - val |= val2 << 8; -- dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val); - tc358768_write(priv, TC358768_TCLK_HEADERCNT, val); - - /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ -- raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5; -+ raw_val = tc358768_ns_to_cnt(60 + tc358768_ps_to_ns(2 * ui_ps), hsbyteclk_ps) - 5; - val = clamp(raw_val, 0, 127); -- dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val); -+ dev_dbg(dev, "TCLK_TRAILCNT: %u\n", val); - tc358768_write(priv, TC358768_TCLK_TRAILCNT, val); - - /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ -- val = 50 + tc358768_to_ns(4 * ui_nsk); -- val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1; -+ val = 50 + tc358768_ps_to_ns(4 * ui_ps); -+ val = tc358768_ns_to_cnt(val, hsbyteclk_ps) - 1; -+ dev_dbg(dev, "THS_PREPARECNT %u\n", val); - /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ -- raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10; -+ raw_val = tc358768_ns_to_cnt(145 - tc358768_ps_to_ns(3 * ui_ps), hsbyteclk_ps) - 10; - val2 = clamp(raw_val, 0, 127); -+ dev_dbg(dev, "THS_ZEROCNT %u\n", val2); - val |= val2 << 8; -- dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val); - tc358768_write(priv, TC358768_THS_HEADERCNT, val); - - /* TWAKEUP > 1ms in lptxcnt steps */ -- val = tc358768_ns_to_cnt(1020000, dsibclk_nsk); -+ val = tc358768_ns_to_cnt(1020000, hsbyteclk_ps); - val = val / (lptxcnt + 1) - 1; -- dev_dbg(priv->dev, "TWAKEUP: 0x%x\n", val); -+ dev_dbg(dev, "TWAKEUP: %u\n", val); - tc358768_write(priv, TC358768_TWAKEUP, val); - - /* TCLK_POSTCNT > 60ns + 52*UI */ -- val = tc358768_ns_to_cnt(60 + tc358768_to_ns(52 * ui_nsk), -- dsibclk_nsk) - 3; -- dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val); -+ val = tc358768_ns_to_cnt(60 + tc358768_ps_to_ns(52 * ui_ps), -+ hsbyteclk_ps) - 3; -+ dev_dbg(dev, "TCLK_POSTCNT: %u\n", val); - tc358768_write(priv, TC358768_TCLK_POSTCNT, val); - - /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ -- raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk), -- dsibclk_nsk) - 4; -+ raw_val = tc358768_ns_to_cnt(60 + tc358768_ps_to_ns(18 * ui_ps), -+ hsbyteclk_ps) - 4; - val = clamp(raw_val, 0, 15); -- dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val); -+ dev_dbg(dev, "THS_TRAILCNT: %u\n", val); - tc358768_write(priv, TC358768_THS_TRAILCNT, val); - - val = BIT(0); -@@ -793,16 +799,17 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) - val |= BIT(i + 1); - tc358768_write(priv, TC358768_HSTXVREGEN, val); - -- if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) -- tc358768_write(priv, TC358768_TXOPTIONCNTRL, 0x1); -+ tc358768_write(priv, TC358768_TXOPTIONCNTRL, -+ (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : BIT(0)); - - /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ -- val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4); -- val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1; -- val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk), -- dsibclk_nsk) - 2; -+ val = tc358768_ps_to_ns((lptxcnt + 1) * hsbyteclk_ps * 4); -+ val = tc358768_ns_to_cnt(val, hsbyteclk_ps) / 4 - 1; -+ dev_dbg(dev, "TXTAGOCNT: %u\n", val); -+ val2 = tc358768_ns_to_cnt(tc358768_ps_to_ns((lptxcnt + 1) * hsbyteclk_ps), -+ hsbyteclk_ps) - 2; -+ dev_dbg(dev, "RXTASURECNT: %u\n", val2); - val = val << 16 | val2; -- dev_dbg(priv->dev, "BTACNTRL1: 0x%x\n", val); - tc358768_write(priv, TC358768_BTACNTRL1, val); - - /* START[0] */ -@@ -813,43 +820,43 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) - tc358768_write(priv, TC358768_DSI_EVENT, 0); - - /* vact */ -- tc358768_write(priv, TC358768_DSI_VACT, mode->vdisplay); -+ tc358768_write(priv, TC358768_DSI_VACT, vm.vactive); - - /* vsw */ -- tc358768_write(priv, TC358768_DSI_VSW, -- mode->vsync_end - mode->vsync_start); -+ tc358768_write(priv, TC358768_DSI_VSW, vm.vsync_len); -+ - /* vbp */ -- tc358768_write(priv, TC358768_DSI_VBPR, -- mode->vtotal - mode->vsync_end); -+ tc358768_write(priv, TC358768_DSI_VBPR, vm.vback_porch); - - /* hsw * byteclk * ndl / pclk */ -- val = (u32)div_u64((mode->hsync_end - mode->hsync_start) * -- ((u64)priv->dsiclk / 4) * priv->dsi_lanes, -- mode->clock * 1000); -+ val = (u32)div_u64(vm.hsync_len * -+ (u64)hsbyteclk * priv->dsi_lanes, -+ vm.pixelclock); - tc358768_write(priv, TC358768_DSI_HSW, val); - - /* hbp * byteclk * ndl / pclk */ -- val = (u32)div_u64((mode->htotal - mode->hsync_end) * -- ((u64)priv->dsiclk / 4) * priv->dsi_lanes, -- mode->clock * 1000); -+ val = (u32)div_u64(vm.hback_porch * -+ (u64)hsbyteclk * priv->dsi_lanes, -+ vm.pixelclock); - tc358768_write(priv, TC358768_DSI_HBPR, val); - } else { - /* Set event mode */ - tc358768_write(priv, TC358768_DSI_EVENT, 1); - - /* vact */ -- tc358768_write(priv, TC358768_DSI_VACT, mode->vdisplay); -+ tc358768_write(priv, TC358768_DSI_VACT, vm.vactive); - - /* vsw (+ vbp) */ - tc358768_write(priv, TC358768_DSI_VSW, -- mode->vtotal - mode->vsync_start); -+ vm.vsync_len + vm.vback_porch); -+ - /* vbp (not used in event mode) */ - tc358768_write(priv, TC358768_DSI_VBPR, 0); - - /* (hsw + hbp) * byteclk * ndl / pclk */ -- val = (u32)div_u64((mode->htotal - mode->hsync_start) * -- ((u64)priv->dsiclk / 4) * priv->dsi_lanes, -- mode->clock * 1000); -+ val = (u32)div_u64((vm.hsync_len + vm.hback_porch) * -+ (u64)hsbyteclk * priv->dsi_lanes, -+ vm.pixelclock); - tc358768_write(priv, TC358768_DSI_HSW, val); - - /* hbp (not used in event mode) */ -@@ -860,11 +867,12 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) - tc358768_write(priv, TC358768_DSI_HACT, hact); - - /* VSYNC polarity */ -- if (!(mode->flags & DRM_MODE_FLAG_NVSYNC)) -- tc358768_update_bits(priv, TC358768_CONFCTL, BIT(5), BIT(5)); -+ tc358768_update_bits(priv, TC358768_CONFCTL, BIT(5), -+ (mode->flags & DRM_MODE_FLAG_PVSYNC) ? BIT(5) : 0); -+ - /* HSYNC polarity */ -- if (mode->flags & DRM_MODE_FLAG_PHSYNC) -- tc358768_update_bits(priv, TC358768_PP_MISC, BIT(0), BIT(0)); -+ tc358768_update_bits(priv, TC358768_PP_MISC, BIT(0), -+ (mode->flags & DRM_MODE_FLAG_PHSYNC) ? BIT(0) : 0); - - /* Start DSI Tx */ - tc358768_write(priv, TC358768_DSI_START, 0x1); -@@ -894,7 +902,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) - - ret = tc358768_clear_error(priv); - if (ret) { -- dev_err(priv->dev, "Bridge pre_enable failed: %d\n", ret); -+ dev_err(dev, "Bridge pre_enable failed: %d\n", ret); - tc358768_bridge_disable(bridge); - tc358768_bridge_post_disable(bridge); - } -diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c -index e592c5da70cee..da0145bc104a8 100644 ---- a/drivers/gpu/drm/drm_syncobj.c -+++ b/drivers/gpu/drm/drm_syncobj.c -@@ -1015,7 +1015,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, - fence = drm_syncobj_fence_get(syncobjs[i]); - if (!fence || dma_fence_chain_find_seqno(&fence, points[i])) { - dma_fence_put(fence); -- if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { -+ if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | -+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) { - continue; - } else { - timeout = -EINVAL; -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -index 14ddfe3a6be77..7fb52a573436e 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -@@ -402,6 +402,9 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) - unsigned int local_layer; - - plane_state = to_mtk_plane_state(plane->state); -+ -+ /* should not enable layer before crtc enabled */ -+ plane_state->pending.enable = false; - comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer); - if (comp) - mtk_ddp_comp_layer_config(comp, local_layer, -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c -index 2f5e007dd3800..c4a0203d17e38 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c -@@ -157,9 +157,9 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane, - plane->state->src_y = new_state->src_y; - plane->state->src_h = new_state->src_h; - plane->state->src_w = new_state->src_w; -- swap(plane->state->fb, new_state->fb); - - mtk_plane_update_new_state(new_state, new_plane_state); -+ swap(plane->state->fb, new_state->fb); - wmb(); /* Make sure the above parameters are set before update */ - new_plane_state->pending.async_dirty = true; - mtk_drm_crtc_async_update(new_state->crtc, plane, state); -diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c -index 9e1363c9fcdb4..3e74c7c1b89fa 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dsi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c -@@ -406,7 +406,7 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi) - if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) - tmp_reg |= HSTX_CKLP_EN; - -- if (!(dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)) -+ if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET) - tmp_reg |= DIS_EOT; - - writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL); -@@ -483,7 +483,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi) - timing->da_hs_zero + timing->da_hs_exit + 3; - - delta = dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST ? 18 : 12; -- delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 2 : 0; -+ delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 0 : 2; - - horizontal_frontporch_byte = vm->hfront_porch * dsi_tmp_buf_bpp; - horizontal_front_back_byte = horizontal_frontporch_byte + horizontal_backporch_byte; -diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c -index 8a95c744972a1..e9036e4036bc6 100644 ---- a/drivers/gpu/drm/msm/dsi/dsi.c -+++ b/drivers/gpu/drm/msm/dsi/dsi.c -@@ -127,6 +127,7 @@ static void dsi_unbind(struct device *dev, struct device *master, - struct msm_drm_private *priv = dev_get_drvdata(master); - struct msm_dsi *msm_dsi = dev_get_drvdata(dev); - -+ msm_dsi_tx_buf_free(msm_dsi->host); - priv->dsi[msm_dsi->id] = NULL; - } - -diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h -index 2a96b4fe7839f..6b239f77fca94 100644 ---- a/drivers/gpu/drm/msm/dsi/dsi.h -+++ b/drivers/gpu/drm/msm/dsi/dsi.h -@@ -123,6 +123,7 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size); - void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host); - void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host); - void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host); -+void msm_dsi_tx_buf_free(struct mipi_dsi_host *mipi_host); - int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova); - int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova); - int dsi_clk_init_v2(struct msm_dsi_host *msm_host); -diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c -index e20cd3dd2c6cc..a7c6e8a1754de 100644 ---- a/drivers/gpu/drm/msm/dsi/dsi_host.c -+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c -@@ -149,6 +149,7 @@ struct msm_dsi_host { - - /* DSI 6G TX buffer*/ - struct drm_gem_object *tx_gem_obj; -+ struct msm_gem_address_space *aspace; - - /* DSI v2 TX buffer */ - void *tx_buf; -@@ -1127,8 +1128,10 @@ int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size) - uint64_t iova; - u8 *data; - -+ msm_host->aspace = msm_gem_address_space_get(priv->kms->aspace); -+ - data = msm_gem_kernel_new(dev, size, MSM_BO_WC, -- priv->kms->aspace, -+ msm_host->aspace, - &msm_host->tx_gem_obj, &iova); - - if (IS_ERR(data)) { -@@ -1157,10 +1160,10 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size) - return 0; - } - --static void dsi_tx_buf_free(struct msm_dsi_host *msm_host) -+void msm_dsi_tx_buf_free(struct mipi_dsi_host *host) - { -+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host); - struct drm_device *dev = msm_host->dev; -- struct msm_drm_private *priv; - - /* - * This is possible if we're tearing down before we've had a chance to -@@ -1171,11 +1174,11 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host) - if (!dev) - return; - -- priv = dev->dev_private; - if (msm_host->tx_gem_obj) { -- msm_gem_unpin_iova(msm_host->tx_gem_obj, priv->kms->aspace); -- drm_gem_object_put(msm_host->tx_gem_obj); -+ msm_gem_kernel_put(msm_host->tx_gem_obj, msm_host->aspace); -+ msm_gem_address_space_put(msm_host->aspace); - msm_host->tx_gem_obj = NULL; -+ msm_host->aspace = NULL; - } - - if (msm_host->tx_buf) -@@ -2014,7 +2017,6 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host) - struct msm_dsi_host *msm_host = to_msm_dsi_host(host); - - DBG(""); -- dsi_tx_buf_free(msm_host); - if (msm_host->workqueue) { - destroy_workqueue(msm_host->workqueue); - msm_host->workqueue = NULL; -diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c -index 4f06356d9ce2e..f0ae087be914e 100644 ---- a/drivers/gpu/drm/radeon/evergreen.c -+++ b/drivers/gpu/drm/radeon/evergreen.c -@@ -4821,14 +4821,15 @@ restart_ih: - break; - case 44: /* hdmi */ - afmt_idx = src_data; -- if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG)) -- DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); -- - if (afmt_idx > 5) { - DRM_ERROR("Unhandled interrupt: %d %d\n", - src_id, src_data); - break; - } -+ -+ if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG)) -+ DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); -+ - afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1); -diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c -index 8526dda919317..0b33c3a1e6e3b 100644 ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.c -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c -@@ -1178,6 +1178,7 @@ static int cdn_dp_probe(struct platform_device *pdev) - struct cdn_dp_device *dp; - struct extcon_dev *extcon; - struct phy *phy; -+ int ret; - int i; - - dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); -@@ -1218,9 +1219,19 @@ static int cdn_dp_probe(struct platform_device *pdev) - mutex_init(&dp->lock); - dev_set_drvdata(dev, dp); - -- cdn_dp_audio_codec_init(dp, dev); -+ ret = cdn_dp_audio_codec_init(dp, dev); -+ if (ret) -+ return ret; -+ -+ ret = component_add(dev, &cdn_dp_component_ops); -+ if (ret) -+ goto err_audio_deinit; - -- return component_add(dev, &cdn_dp_component_ops); -+ return 0; -+ -+err_audio_deinit: -+ platform_device_unregister(dp->audio_pdev); -+ return ret; - } - - static int cdn_dp_remove(struct platform_device *pdev) -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -index 9426f7976d22e..10a4970ad2d8a 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c -@@ -39,7 +39,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) - - ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt, - prot); -- if (ret < rk_obj->base.size) { -+ if (ret < (ssize_t)rk_obj->base.size) { - DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n", - ret, rk_obj->base.size); - ret = -ENOMEM; -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index 2e2e08f4359a8..ae8c532f7fc84 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -@@ -1606,7 +1606,8 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc) - if (WARN_ON(!crtc->state)) - return NULL; - -- rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL); -+ rockchip_state = kmemdup(to_rockchip_crtc_state(crtc->state), -+ sizeof(*rockchip_state), GFP_KERNEL); - if (!rockchip_state) - return NULL; - -@@ -1631,7 +1632,10 @@ static void vop_crtc_reset(struct drm_crtc *crtc) - if (crtc->state) - vop_crtc_destroy_state(crtc, crtc->state); - -- __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); -+ if (crtc_state) -+ __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); -+ else -+ __drm_atomic_helper_crtc_reset(crtc, NULL); - } - - #ifdef CONFIG_DRM_ANALOGIX_DP -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -index 3c05ce01f73b8..b233f52675dc4 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c -@@ -2075,30 +2075,15 @@ static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = { - .atomic_disable = vop2_crtc_atomic_disable, - }; - --static void vop2_crtc_reset(struct drm_crtc *crtc) --{ -- struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); -- -- if (crtc->state) { -- __drm_atomic_helper_crtc_destroy_state(crtc->state); -- kfree(vcstate); -- } -- -- vcstate = kzalloc(sizeof(*vcstate), GFP_KERNEL); -- if (!vcstate) -- return; -- -- crtc->state = &vcstate->base; -- crtc->state->crtc = crtc; --} -- - static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc) - { -- struct rockchip_crtc_state *vcstate, *old_vcstate; -+ struct rockchip_crtc_state *vcstate; - -- old_vcstate = to_rockchip_crtc_state(crtc->state); -+ if (WARN_ON(!crtc->state)) -+ return NULL; - -- vcstate = kmemdup(old_vcstate, sizeof(*old_vcstate), GFP_KERNEL); -+ vcstate = kmemdup(to_rockchip_crtc_state(crtc->state), -+ sizeof(*vcstate), GFP_KERNEL); - if (!vcstate) - return NULL; - -@@ -2116,6 +2101,20 @@ static void vop2_crtc_destroy_state(struct drm_crtc *crtc, - kfree(vcstate); - } - -+static void vop2_crtc_reset(struct drm_crtc *crtc) -+{ -+ struct rockchip_crtc_state *vcstate = -+ kzalloc(sizeof(*vcstate), GFP_KERNEL); -+ -+ if (crtc->state) -+ vop2_crtc_destroy_state(crtc, crtc->state); -+ -+ if (vcstate) -+ __drm_atomic_helper_crtc_reset(crtc, &vcstate->base); -+ else -+ __drm_atomic_helper_crtc_reset(crtc, NULL); -+} -+ - static const struct drm_crtc_funcs vop2_crtc_funcs = { - .set_config = drm_atomic_helper_set_config, - .page_flip = drm_atomic_helper_page_flip, -diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c -index 047696432eb21..93c0c532fe5af 100644 ---- a/drivers/gpu/host1x/context.c -+++ b/drivers/gpu/host1x/context.c -@@ -34,10 +34,10 @@ int host1x_memory_context_list_init(struct host1x *host1x) - if (err < 0) - return 0; - -- cdl->devs = kcalloc(err, sizeof(*cdl->devs), GFP_KERNEL); -+ cdl->len = err / 4; -+ cdl->devs = kcalloc(cdl->len, sizeof(*cdl->devs), GFP_KERNEL); - if (!cdl->devs) - return -ENOMEM; -- cdl->len = err / 4; - - for (i = 0; i < cdl->len; i++) { - struct iommu_fwspec *fwspec; -diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c -index 27cadadda7c9d..2770d964133d5 100644 ---- a/drivers/hid/hid-cp2112.c -+++ b/drivers/hid/hid-cp2112.c -@@ -163,7 +163,6 @@ struct cp2112_device { - atomic_t read_avail; - atomic_t xfer_avail; - struct gpio_chip gc; -- struct irq_chip irq; - u8 *in_out_buffer; - struct mutex lock; - -@@ -1080,16 +1079,20 @@ static void cp2112_gpio_irq_mask(struct irq_data *d) - { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct cp2112_device *dev = gpiochip_get_data(gc); -+ irq_hw_number_t hwirq = irqd_to_hwirq(d); - -- __clear_bit(d->hwirq, &dev->irq_mask); -+ __clear_bit(hwirq, &dev->irq_mask); -+ gpiochip_disable_irq(gc, hwirq); - } - - static void cp2112_gpio_irq_unmask(struct irq_data *d) - { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct cp2112_device *dev = gpiochip_get_data(gc); -+ irq_hw_number_t hwirq = irqd_to_hwirq(d); - -- __set_bit(d->hwirq, &dev->irq_mask); -+ gpiochip_enable_irq(gc, hwirq); -+ __set_bit(hwirq, &dev->irq_mask); - } - - static void cp2112_gpio_poll_callback(struct work_struct *work) -@@ -1159,8 +1162,6 @@ static unsigned int cp2112_gpio_irq_startup(struct irq_data *d) - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct cp2112_device *dev = gpiochip_get_data(gc); - -- INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); -- - if (!dev->gpio_poll) { - dev->gpio_poll = true; - schedule_delayed_work(&dev->gpio_poll_worker, 0); -@@ -1175,7 +1176,12 @@ static void cp2112_gpio_irq_shutdown(struct irq_data *d) - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct cp2112_device *dev = gpiochip_get_data(gc); - -- cancel_delayed_work_sync(&dev->gpio_poll_worker); -+ cp2112_gpio_irq_mask(d); -+ -+ if (!dev->irq_mask) { -+ dev->gpio_poll = false; -+ cancel_delayed_work_sync(&dev->gpio_poll_worker); -+ } - } - - static int cp2112_gpio_irq_type(struct irq_data *d, unsigned int type) -@@ -1228,6 +1234,18 @@ err_desc: - return ret; - } - -+static const struct irq_chip cp2112_gpio_irqchip = { -+ .name = "cp2112-gpio", -+ .irq_startup = cp2112_gpio_irq_startup, -+ .irq_shutdown = cp2112_gpio_irq_shutdown, -+ .irq_ack = cp2112_gpio_irq_ack, -+ .irq_mask = cp2112_gpio_irq_mask, -+ .irq_unmask = cp2112_gpio_irq_unmask, -+ .irq_set_type = cp2112_gpio_irq_type, -+ .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE, -+ GPIOCHIP_IRQ_RESOURCE_HELPERS, -+}; -+ - static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) - { - struct cp2112_device *dev; -@@ -1337,17 +1355,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) - dev->gc.can_sleep = 1; - dev->gc.parent = &hdev->dev; - -- dev->irq.name = "cp2112-gpio"; -- dev->irq.irq_startup = cp2112_gpio_irq_startup; -- dev->irq.irq_shutdown = cp2112_gpio_irq_shutdown; -- dev->irq.irq_ack = cp2112_gpio_irq_ack; -- dev->irq.irq_mask = cp2112_gpio_irq_mask; -- dev->irq.irq_unmask = cp2112_gpio_irq_unmask; -- dev->irq.irq_set_type = cp2112_gpio_irq_type; -- dev->irq.flags = IRQCHIP_MASK_ON_SUSPEND; -- - girq = &dev->gc.irq; -- girq->chip = &dev->irq; -+ gpio_irq_chip_set_chip(girq, &cp2112_gpio_irqchip); - /* The event comes from the outside so no parent handler */ - girq->parent_handler = NULL; - girq->num_parents = 0; -@@ -1356,6 +1365,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) - girq->handler = handle_simple_irq; - girq->threaded = true; - -+ INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); -+ - ret = gpiochip_add_data(&dev->gc, dev); - if (ret < 0) { - hid_err(hdev, "error registering gpio chip\n"); -diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c -index 8d0dad12b2d37..fa1c7e07e220b 100644 ---- a/drivers/hid/hid-logitech-hidpp.c -+++ b/drivers/hid/hid-logitech-hidpp.c -@@ -31,11 +31,6 @@ MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Benjamin Tissoires "); - MODULE_AUTHOR("Nestor Lopez Casado "); - --static bool disable_raw_mode; --module_param(disable_raw_mode, bool, 0644); --MODULE_PARM_DESC(disable_raw_mode, -- "Disable Raw mode reporting for touchpads and keep firmware gestures."); -- - static bool disable_tap_to_click; - module_param(disable_tap_to_click, bool, 0644); - MODULE_PARM_DESC(disable_tap_to_click, -@@ -71,7 +66,7 @@ MODULE_PARM_DESC(disable_tap_to_click, - /* bits 2..20 are reserved for classes */ - /* #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) disabled */ - #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) --#define HIDPP_QUIRK_NO_HIDINPUT BIT(23) -+#define HIDPP_QUIRK_DELAYED_INIT BIT(23) - #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) - #define HIDPP_QUIRK_UNIFYING BIT(25) - #define HIDPP_QUIRK_HIDPP_WHEELS BIT(26) -@@ -88,8 +83,6 @@ MODULE_PARM_DESC(disable_tap_to_click, - HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL | \ - HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL) - --#define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT -- - #define HIDPP_CAPABILITY_HIDPP10_BATTERY BIT(0) - #define HIDPP_CAPABILITY_HIDPP20_BATTERY BIT(1) - #define HIDPP_CAPABILITY_BATTERY_MILEAGE BIT(2) -@@ -1764,15 +1757,14 @@ static int hidpp_battery_get_property(struct power_supply *psy, - /* -------------------------------------------------------------------------- */ - #define HIDPP_PAGE_WIRELESS_DEVICE_STATUS 0x1d4b - --static int hidpp_set_wireless_feature_index(struct hidpp_device *hidpp) -+static int hidpp_get_wireless_feature_index(struct hidpp_device *hidpp, u8 *feature_index) - { - u8 feature_type; - int ret; - - ret = hidpp_root_get_feature(hidpp, - HIDPP_PAGE_WIRELESS_DEVICE_STATUS, -- &hidpp->wireless_feature_index, -- &feature_type); -+ feature_index, &feature_type); - - return ret; - } -@@ -4006,6 +3998,13 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) - } - } - -+ if (hidpp->protocol_major >= 2) { -+ u8 feature_index; -+ -+ if (!hidpp_get_wireless_feature_index(hidpp, &feature_index)) -+ hidpp->wireless_feature_index = feature_index; -+ } -+ - if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) { - name = hidpp_get_device_name(hidpp); - if (name) { -@@ -4044,7 +4043,7 @@ static void hidpp_connect_event(struct hidpp_device *hidpp) - if (hidpp->capabilities & HIDPP_CAPABILITY_HI_RES_SCROLL) - hi_res_scroll_enable(hidpp); - -- if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input) -+ if (!(hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) || hidpp->delayed_input) - /* if the input nodes are already created, we can stop now */ - return; - -@@ -4149,7 +4148,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) - bool connected; - unsigned int connect_mask = HID_CONNECT_DEFAULT; - struct hidpp_ff_private_data data; -- bool will_restart = false; - - /* report_fixup needs drvdata to be set before we call hid_parse */ - hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); -@@ -4190,11 +4188,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) - hidpp_application_equals(hdev, HID_GD_KEYBOARD)) - hidpp->quirks |= HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS; - -- if (disable_raw_mode) { -- hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP; -- hidpp->quirks &= ~HIDPP_QUIRK_NO_HIDINPUT; -- } -- - if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { - ret = wtp_allocate(hdev, id); - if (ret) -@@ -4205,10 +4198,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) - return ret; - } - -- if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT || -- hidpp->quirks & HIDPP_QUIRK_UNIFYING) -- will_restart = true; -- - INIT_WORK(&hidpp->work, delayed_work_cb); - mutex_init(&hidpp->send_mutex); - init_waitqueue_head(&hidpp->wait); -@@ -4220,10 +4209,12 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) - hdev->name); - - /* -- * Plain USB connections need to actually call start and open -- * on the transport driver to allow incoming data. -+ * First call hid_hw_start(hdev, 0) to allow IO without connecting any -+ * hid subdrivers (hid-input, hidraw). This allows retrieving the dev's -+ * name and serial number and store these in hdev->name and hdev->uniq, -+ * before the hid-input and hidraw drivers expose these to userspace. - */ -- ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask); -+ ret = hid_hw_start(hdev, 0); - if (ret) { - hid_err(hdev, "hw start failed\n"); - goto hid_hw_start_fail; -@@ -4256,15 +4247,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) - hidpp_overwrite_name(hdev); - } - -- if (connected && hidpp->protocol_major >= 2) { -- ret = hidpp_set_wireless_feature_index(hidpp); -- if (ret == -ENOENT) -- hidpp->wireless_feature_index = 0; -- else if (ret) -- goto hid_hw_init_fail; -- ret = 0; -- } -- - if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { - ret = wtp_get_config(hidpp); - if (ret) -@@ -4278,21 +4260,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) - schedule_work(&hidpp->work); - flush_work(&hidpp->work); - -- if (will_restart) { -- /* Reset the HID node state */ -- hid_device_io_stop(hdev); -- hid_hw_close(hdev); -- hid_hw_stop(hdev); -+ if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) -+ connect_mask &= ~HID_CONNECT_HIDINPUT; - -- if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) -- connect_mask &= ~HID_CONNECT_HIDINPUT; -- -- /* Now export the actual inputs and hidraw nodes to the world */ -- ret = hid_hw_start(hdev, connect_mask); -- if (ret) { -- hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); -- goto hid_hw_start_fail; -- } -+ /* Now export the actual inputs and hidraw nodes to the world */ -+ ret = hid_connect(hdev, connect_mask); -+ if (ret) { -+ hid_err(hdev, "%s:hid_connect returned error %d\n", __func__, ret); -+ goto hid_hw_init_fail; - } - - if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { -@@ -4303,6 +4278,11 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) - ret); - } - -+ /* -+ * This relies on logi_dj_ll_close() being a no-op so that DJ connection -+ * events will still be received. -+ */ -+ hid_hw_close(hdev); - return ret; - - hid_hw_init_fail: -diff --git a/drivers/hte/hte-tegra194-test.c b/drivers/hte/hte-tegra194-test.c -index ce8c44e792213..60f0ef2cb324f 100644 ---- a/drivers/hte/hte-tegra194-test.c -+++ b/drivers/hte/hte-tegra194-test.c -@@ -154,8 +154,10 @@ static int tegra_hte_test_probe(struct platform_device *pdev) - } - - cnt = of_hte_req_count(hte.pdev); -- if (cnt < 0) -+ if (cnt < 0) { -+ ret = cnt; - goto free_irq; -+ } - - dev_info(&pdev->dev, "Total requested lines:%d\n", cnt); - -diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c -index 6724e0dd30880..25abf28084c96 100644 ---- a/drivers/hwmon/axi-fan-control.c -+++ b/drivers/hwmon/axi-fan-control.c -@@ -496,6 +496,21 @@ static int axi_fan_control_probe(struct platform_device *pdev) - return -ENODEV; - } - -+ ret = axi_fan_control_init(ctl, pdev->dev.of_node); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to initialize device\n"); -+ return ret; -+ } -+ -+ ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, -+ name, -+ ctl, -+ &axi_chip_info, -+ axi_fan_control_groups); -+ -+ if (IS_ERR(ctl->hdev)) -+ return PTR_ERR(ctl->hdev); -+ - ctl->irq = platform_get_irq(pdev, 0); - if (ctl->irq < 0) - return ctl->irq; -@@ -509,19 +524,7 @@ static int axi_fan_control_probe(struct platform_device *pdev) - return ret; - } - -- ret = axi_fan_control_init(ctl, pdev->dev.of_node); -- if (ret) { -- dev_err(&pdev->dev, "Failed to initialize device\n"); -- return ret; -- } -- -- ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, -- name, -- ctl, -- &axi_chip_info, -- axi_fan_control_groups); -- -- return PTR_ERR_OR_ZERO(ctl->hdev); -+ return 0; - } - - static struct platform_driver axi_fan_control_driver = { -diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c -index baaf8af4cb443..09aab5859fa75 100644 ---- a/drivers/hwmon/coretemp.c -+++ b/drivers/hwmon/coretemp.c -@@ -41,7 +41,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); - #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ - #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ - #define NUM_REAL_CORES 128 /* Number of Real cores per cpu */ --#define CORETEMP_NAME_LENGTH 19 /* String Length of attrs */ -+#define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */ - #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ - #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) - #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) -diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c -index c54233f0369b2..80310845fb993 100644 ---- a/drivers/hwmon/nct6775-core.c -+++ b/drivers/hwmon/nct6775-core.c -@@ -1528,17 +1528,21 @@ struct nct6775_data *nct6775_update_device(struct device *dev) - data->fan_div[i]); - - if (data->has_fan_min & BIT(i)) { -- err = nct6775_read_value(data, data->REG_FAN_MIN[i], ®); -+ u16 tmp; -+ -+ err = nct6775_read_value(data, data->REG_FAN_MIN[i], &tmp); - if (err) - goto out; -- data->fan_min[i] = reg; -+ data->fan_min[i] = tmp; - } - - if (data->REG_FAN_PULSES[i]) { -- err = nct6775_read_value(data, data->REG_FAN_PULSES[i], ®); -+ u16 tmp; -+ -+ err = nct6775_read_value(data, data->REG_FAN_PULSES[i], &tmp); - if (err) - goto out; -- data->fan_pulses[i] = (reg >> data->FAN_PULSE_SHIFT[i]) & 0x03; -+ data->fan_pulses[i] = (tmp >> data->FAN_PULSE_SHIFT[i]) & 0x03; - } - - err = nct6775_select_fan_div(dev, data, i, reg); -diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c -index 25fbbd4c9a2b3..886386272b9f4 100644 ---- a/drivers/hwmon/sch5627.c -+++ b/drivers/hwmon/sch5627.c -@@ -6,6 +6,7 @@ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -+#include - #include - #include - #include -@@ -32,6 +33,10 @@ - #define SCH5627_REG_PRIMARY_ID 0x3f - #define SCH5627_REG_CTRL 0x40 - -+#define SCH5627_CTRL_START BIT(0) -+#define SCH5627_CTRL_LOCK BIT(1) -+#define SCH5627_CTRL_VBAT BIT(4) -+ - #define SCH5627_NO_TEMPS 8 - #define SCH5627_NO_FANS 4 - #define SCH5627_NO_IN 5 -@@ -147,7 +152,8 @@ static int sch5627_update_in(struct sch5627_data *data) - - /* Trigger a Vbat voltage measurement every 5 minutes */ - if (time_after(jiffies, data->last_battery + 300 * HZ)) { -- sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | 0x10); -+ sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, -+ data->control | SCH5627_CTRL_VBAT); - data->last_battery = jiffies; - } - -@@ -226,6 +232,14 @@ static int reg_to_rpm(u16 reg) - static umode_t sch5627_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr, - int channel) - { -+ const struct sch5627_data *data = drvdata; -+ -+ /* Once the lock bit is set, the virtual registers become read-only -+ * until the next power cycle. -+ */ -+ if (data->control & SCH5627_CTRL_LOCK) -+ return 0444; -+ - if (type == hwmon_pwm && attr == hwmon_pwm_auto_channels_temp) - return 0644; - -@@ -483,14 +497,13 @@ static int sch5627_probe(struct platform_device *pdev) - return val; - - data->control = val; -- if (!(data->control & 0x01)) { -+ if (!(data->control & SCH5627_CTRL_START)) { - pr_err("hardware monitoring not enabled\n"); - return -ENODEV; - } - /* Trigger a Vbat voltage measurement, so that we get a valid reading - the first time we read Vbat */ -- sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, -- data->control | 0x10); -+ sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | SCH5627_CTRL_VBAT); - data->last_battery = jiffies; - - /* -diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c -index de3a0886c2f72..ac1f725807155 100644 ---- a/drivers/hwmon/sch56xx-common.c -+++ b/drivers/hwmon/sch56xx-common.c -@@ -7,10 +7,8 @@ - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - - #include --#include - #include - #include --#include - #include - #include - #include -@@ -21,10 +19,7 @@ - #include - #include "sch56xx-common.h" - --static bool ignore_dmi; --module_param(ignore_dmi, bool, 0); --MODULE_PARM_DESC(ignore_dmi, "Omit DMI check for supported devices (default=0)"); -- -+/* Insmod parameters */ - static bool nowayout = WATCHDOG_NOWAYOUT; - module_param(nowayout, bool, 0); - MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" -@@ -523,66 +518,11 @@ static int __init sch56xx_device_add(int address, const char *name) - return PTR_ERR_OR_ZERO(sch56xx_pdev); - } - --static const struct dmi_system_id sch56xx_dmi_override_table[] __initconst = { -- { -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), -- DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS W380"), -- }, -- }, -- { -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), -- DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO P710"), -- }, -- }, -- { -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), -- DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO E9900"), -- }, -- }, -- { } --}; -- --/* For autoloading only */ --static const struct dmi_system_id sch56xx_dmi_table[] __initconst = { -- { -- .matches = { -- DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), -- }, -- }, -- { } --}; --MODULE_DEVICE_TABLE(dmi, sch56xx_dmi_table); -- - static int __init sch56xx_init(void) - { -- const char *name = NULL; - int address; -+ const char *name = NULL; - -- if (!ignore_dmi) { -- if (!dmi_check_system(sch56xx_dmi_table)) -- return -ENODEV; -- -- if (!dmi_check_system(sch56xx_dmi_override_table)) { -- /* -- * Some machines like the Esprimo P720 and Esprimo C700 have -- * onboard devices named " Antiope"/" Theseus" instead of -- * "Antiope"/"Theseus", so we need to check for both. -- */ -- if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) && -- !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) && -- !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) && -- !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL)) -- return -ENODEV; -- } -- } -- -- /* -- * Some devices like the Esprimo C700 have both onboard devices, -- * so we still have to check manually -- */ - address = sch56xx_find(0x4e, &name); - if (address < 0) - address = sch56xx_find(0x2e, &name); -diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c -index 30a2a3200bed9..86a080f24d8a2 100644 ---- a/drivers/i2c/busses/i2c-bcm-iproc.c -+++ b/drivers/i2c/busses/i2c-bcm-iproc.c -@@ -316,26 +316,44 @@ static void bcm_iproc_i2c_slave_init( - iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); - } - --static void bcm_iproc_i2c_check_slave_status( -- struct bcm_iproc_i2c_dev *iproc_i2c) -+static bool bcm_iproc_i2c_check_slave_status -+ (struct bcm_iproc_i2c_dev *iproc_i2c, u32 status) - { - u32 val; -+ bool recover = false; - -- val = iproc_i2c_rd_reg(iproc_i2c, S_CMD_OFFSET); -- /* status is valid only when START_BUSY is cleared after it was set */ -- if (val & BIT(S_CMD_START_BUSY_SHIFT)) -- return; -+ /* check slave transmit status only if slave is transmitting */ -+ if (!iproc_i2c->slave_rx_only) { -+ val = iproc_i2c_rd_reg(iproc_i2c, S_CMD_OFFSET); -+ /* status is valid only when START_BUSY is cleared */ -+ if (!(val & BIT(S_CMD_START_BUSY_SHIFT))) { -+ val = (val >> S_CMD_STATUS_SHIFT) & S_CMD_STATUS_MASK; -+ if (val == S_CMD_STATUS_TIMEOUT || -+ val == S_CMD_STATUS_MASTER_ABORT) { -+ dev_warn(iproc_i2c->device, -+ (val == S_CMD_STATUS_TIMEOUT) ? -+ "slave random stretch time timeout\n" : -+ "Master aborted read transaction\n"); -+ recover = true; -+ } -+ } -+ } -+ -+ /* RX_EVENT is not valid when START_BUSY is set */ -+ if ((status & BIT(IS_S_RX_EVENT_SHIFT)) && -+ (status & BIT(IS_S_START_BUSY_SHIFT))) { -+ dev_warn(iproc_i2c->device, "Slave aborted read transaction\n"); -+ recover = true; -+ } - -- val = (val >> S_CMD_STATUS_SHIFT) & S_CMD_STATUS_MASK; -- if (val == S_CMD_STATUS_TIMEOUT || val == S_CMD_STATUS_MASTER_ABORT) { -- dev_err(iproc_i2c->device, (val == S_CMD_STATUS_TIMEOUT) ? -- "slave random stretch time timeout\n" : -- "Master aborted read transaction\n"); -+ if (recover) { - /* re-initialize i2c for recovery */ - bcm_iproc_i2c_enable_disable(iproc_i2c, false); - bcm_iproc_i2c_slave_init(iproc_i2c, true); - bcm_iproc_i2c_enable_disable(iproc_i2c, true); - } -+ -+ return recover; - } - - static void bcm_iproc_i2c_slave_read(struct bcm_iproc_i2c_dev *iproc_i2c) -@@ -420,48 +438,6 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, - u32 val; - u8 value; - -- /* -- * Slave events in case of master-write, master-write-read and, -- * master-read -- * -- * Master-write : only IS_S_RX_EVENT_SHIFT event -- * Master-write-read: both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT -- * events -- * Master-read : both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT -- * events or only IS_S_RD_EVENT_SHIFT -- * -- * iproc has a slave rx fifo size of 64 bytes. Rx fifo full interrupt -- * (IS_S_RX_FIFO_FULL_SHIFT) will be generated when RX fifo becomes -- * full. This can happen if Master issues write requests of more than -- * 64 bytes. -- */ -- if (status & BIT(IS_S_RX_EVENT_SHIFT) || -- status & BIT(IS_S_RD_EVENT_SHIFT) || -- status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) { -- /* disable slave interrupts */ -- val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); -- val &= ~iproc_i2c->slave_int_mask; -- iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); -- -- if (status & BIT(IS_S_RD_EVENT_SHIFT)) -- /* Master-write-read request */ -- iproc_i2c->slave_rx_only = false; -- else -- /* Master-write request only */ -- iproc_i2c->slave_rx_only = true; -- -- /* schedule tasklet to read data later */ -- tasklet_schedule(&iproc_i2c->slave_rx_tasklet); -- -- /* -- * clear only IS_S_RX_EVENT_SHIFT and -- * IS_S_RX_FIFO_FULL_SHIFT interrupt. -- */ -- val = BIT(IS_S_RX_EVENT_SHIFT); -- if (status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) -- val |= BIT(IS_S_RX_FIFO_FULL_SHIFT); -- iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, val); -- } - - if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) { - iproc_i2c->tx_underrun++; -@@ -493,8 +469,9 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, - * less than PKT_LENGTH bytes were output on the SMBUS - */ - iproc_i2c->slave_int_mask &= ~BIT(IE_S_TX_UNDERRUN_SHIFT); -- iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, -- iproc_i2c->slave_int_mask); -+ val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); -+ val &= ~BIT(IE_S_TX_UNDERRUN_SHIFT); -+ iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); - - /* End of SMBUS for Master Read */ - val = BIT(S_TX_WR_STATUS_SHIFT); -@@ -515,9 +492,49 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, - BIT(IS_S_START_BUSY_SHIFT)); - } - -- /* check slave transmit status only if slave is transmitting */ -- if (!iproc_i2c->slave_rx_only) -- bcm_iproc_i2c_check_slave_status(iproc_i2c); -+ /* if the controller has been reset, immediately return from the ISR */ -+ if (bcm_iproc_i2c_check_slave_status(iproc_i2c, status)) -+ return true; -+ -+ /* -+ * Slave events in case of master-write, master-write-read and, -+ * master-read -+ * -+ * Master-write : only IS_S_RX_EVENT_SHIFT event -+ * Master-write-read: both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT -+ * events -+ * Master-read : both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT -+ * events or only IS_S_RD_EVENT_SHIFT -+ * -+ * iproc has a slave rx fifo size of 64 bytes. Rx fifo full interrupt -+ * (IS_S_RX_FIFO_FULL_SHIFT) will be generated when RX fifo becomes -+ * full. This can happen if Master issues write requests of more than -+ * 64 bytes. -+ */ -+ if (status & BIT(IS_S_RX_EVENT_SHIFT) || -+ status & BIT(IS_S_RD_EVENT_SHIFT) || -+ status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) { -+ /* disable slave interrupts */ -+ val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); -+ val &= ~iproc_i2c->slave_int_mask; -+ iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); -+ -+ if (status & BIT(IS_S_RD_EVENT_SHIFT)) -+ /* Master-write-read request */ -+ iproc_i2c->slave_rx_only = false; -+ else -+ /* Master-write request only */ -+ iproc_i2c->slave_rx_only = true; -+ -+ /* schedule tasklet to read data later */ -+ tasklet_schedule(&iproc_i2c->slave_rx_tasklet); -+ -+ /* clear IS_S_RX_FIFO_FULL_SHIFT interrupt */ -+ if (status & BIT(IS_S_RX_FIFO_FULL_SHIFT)) { -+ val = BIT(IS_S_RX_FIFO_FULL_SHIFT); -+ iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, val); -+ } -+ } - - return true; - } -diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c -index 351c81a929a6c..ab0b5691b03e0 100644 ---- a/drivers/i3c/master.c -+++ b/drivers/i3c/master.c -@@ -1508,9 +1508,11 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master) - desc->dev->dev.of_node = desc->boardinfo->of_node; - - ret = device_register(&desc->dev->dev); -- if (ret) -+ if (ret) { - dev_err(&master->dev, - "Failed to add I3C device (err = %d)\n", ret); -+ put_device(&desc->dev->dev); -+ } - } - } - -diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c -index 85e289700c3c5..4abf80f75ef5d 100644 ---- a/drivers/iio/frequency/adf4350.c -+++ b/drivers/iio/frequency/adf4350.c -@@ -33,7 +33,6 @@ enum { - - struct adf4350_state { - struct spi_device *spi; -- struct regulator *reg; - struct gpio_desc *lock_detect_gpiod; - struct adf4350_platform_data *pdata; - struct clk *clk; -@@ -469,6 +468,15 @@ static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev) - return pdata; - } - -+static void adf4350_power_down(void *data) -+{ -+ struct iio_dev *indio_dev = data; -+ struct adf4350_state *st = iio_priv(indio_dev); -+ -+ st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN; -+ adf4350_sync_config(st); -+} -+ - static int adf4350_probe(struct spi_device *spi) - { - struct adf4350_platform_data *pdata; -@@ -491,31 +499,21 @@ static int adf4350_probe(struct spi_device *spi) - } - - if (!pdata->clkin) { -- clk = devm_clk_get(&spi->dev, "clkin"); -+ clk = devm_clk_get_enabled(&spi->dev, "clkin"); - if (IS_ERR(clk)) -- return -EPROBE_DEFER; -- -- ret = clk_prepare_enable(clk); -- if (ret < 0) -- return ret; -+ return PTR_ERR(clk); - } - - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); -- if (indio_dev == NULL) { -- ret = -ENOMEM; -- goto error_disable_clk; -- } -+ if (indio_dev == NULL) -+ return -ENOMEM; - - st = iio_priv(indio_dev); - -- st->reg = devm_regulator_get(&spi->dev, "vcc"); -- if (!IS_ERR(st->reg)) { -- ret = regulator_enable(st->reg); -- if (ret) -- goto error_disable_clk; -- } -+ ret = devm_regulator_get_enable(&spi->dev, "vcc"); -+ if (ret) -+ return ret; - -- spi_set_drvdata(spi, indio_dev); - st->spi = spi; - st->pdata = pdata; - -@@ -544,47 +542,21 @@ static int adf4350_probe(struct spi_device *spi) - - st->lock_detect_gpiod = devm_gpiod_get_optional(&spi->dev, NULL, - GPIOD_IN); -- if (IS_ERR(st->lock_detect_gpiod)) { -- ret = PTR_ERR(st->lock_detect_gpiod); -- goto error_disable_reg; -- } -+ if (IS_ERR(st->lock_detect_gpiod)) -+ return PTR_ERR(st->lock_detect_gpiod); - - if (pdata->power_up_frequency) { - ret = adf4350_set_freq(st, pdata->power_up_frequency); - if (ret) -- goto error_disable_reg; -+ return ret; - } - -- ret = iio_device_register(indio_dev); -+ ret = devm_add_action_or_reset(&spi->dev, adf4350_power_down, indio_dev); - if (ret) -- goto error_disable_reg; -- -- return 0; -- --error_disable_reg: -- if (!IS_ERR(st->reg)) -- regulator_disable(st->reg); --error_disable_clk: -- clk_disable_unprepare(clk); -- -- return ret; --} -- --static void adf4350_remove(struct spi_device *spi) --{ -- struct iio_dev *indio_dev = spi_get_drvdata(spi); -- struct adf4350_state *st = iio_priv(indio_dev); -- struct regulator *reg = st->reg; -- -- st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN; -- adf4350_sync_config(st); -- -- iio_device_unregister(indio_dev); -- -- clk_disable_unprepare(st->clk); -+ return dev_err_probe(&spi->dev, ret, -+ "Failed to add action to managed power down\n"); - -- if (!IS_ERR(reg)) -- regulator_disable(reg); -+ return devm_iio_device_register(&spi->dev, indio_dev); - } - - static const struct of_device_id adf4350_of_match[] = { -@@ -607,7 +579,6 @@ static struct spi_driver adf4350_driver = { - .of_match_table = adf4350_of_match, - }, - .probe = adf4350_probe, -- .remove = adf4350_remove, - .id_table = adf4350_id, - }; - module_spi_driver(adf4350_driver); -diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c -index 3c422698a51c1..3a9b9a28d858f 100644 ---- a/drivers/infiniband/core/device.c -+++ b/drivers/infiniband/core/device.c -@@ -804,7 +804,7 @@ static int alloc_port_data(struct ib_device *device) - * empty slots at the beginning. - */ - pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata, -- rdma_end_port(device) + 1), -+ size_add(rdma_end_port(device), 1)), - GFP_KERNEL); - if (!pdata_rcu) - return -ENOMEM; -diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c -index 0de83d9a4985d..8c69bdb5bb754 100644 ---- a/drivers/infiniband/core/sa_query.c -+++ b/drivers/infiniband/core/sa_query.c -@@ -2220,7 +2220,9 @@ static int ib_sa_add_one(struct ib_device *device) - s = rdma_start_port(device); - e = rdma_end_port(device); - -- sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL); -+ sa_dev = kzalloc(struct_size(sa_dev, port, -+ size_add(size_sub(e, s), 1)), -+ GFP_KERNEL); - if (!sa_dev) - return -ENOMEM; - -diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c -index ee59d73915689..ec5efdc166601 100644 ---- a/drivers/infiniband/core/sysfs.c -+++ b/drivers/infiniband/core/sysfs.c -@@ -903,7 +903,7 @@ alloc_hw_stats_device(struct ib_device *ibdev) - * Two extra attribue elements here, one for the lifespan entry and - * one to NULL terminate the list for the sysfs core code - */ -- data = kzalloc(struct_size(data, attrs, stats->num_counters + 1), -+ data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)), - GFP_KERNEL); - if (!data) - goto err_free_stats; -@@ -1009,7 +1009,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group) - * Two extra attribue elements here, one for the lifespan entry and - * one to NULL terminate the list for the sysfs core code - */ -- data = kzalloc(struct_size(data, attrs, stats->num_counters + 1), -+ data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)), - GFP_KERNEL); - if (!data) - goto err_free_stats; -@@ -1140,7 +1140,7 @@ static int setup_gid_attrs(struct ib_port *port, - int ret; - - gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list, -- attr->gid_tbl_len * 2), -+ size_mul(attr->gid_tbl_len, 2)), - GFP_KERNEL); - if (!gid_attr_group) - return -ENOMEM; -@@ -1205,8 +1205,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, - int ret; - - p = kvzalloc(struct_size(p, attrs_list, -- attr->gid_tbl_len + attr->pkey_tbl_len), -- GFP_KERNEL); -+ size_add(attr->gid_tbl_len, attr->pkey_tbl_len)), -+ GFP_KERNEL); - if (!p) - return ERR_PTR(-ENOMEM); - p->ibdev = device; -diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c -index 98cb594cd9a69..d96c78e436f98 100644 ---- a/drivers/infiniband/core/user_mad.c -+++ b/drivers/infiniband/core/user_mad.c -@@ -1373,7 +1373,9 @@ static int ib_umad_add_one(struct ib_device *device) - s = rdma_start_port(device); - e = rdma_end_port(device); - -- umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL); -+ umad_dev = kzalloc(struct_size(umad_dev, ports, -+ size_add(size_sub(e, s), 1)), -+ GFP_KERNEL); - if (!umad_dev) - return -ENOMEM; - -diff --git a/drivers/infiniband/hw/hfi1/efivar.c b/drivers/infiniband/hw/hfi1/efivar.c -index 7741a1d69097c..2b5d264f41e51 100644 ---- a/drivers/infiniband/hw/hfi1/efivar.c -+++ b/drivers/infiniband/hw/hfi1/efivar.c -@@ -112,7 +112,7 @@ int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind, - unsigned long *size, void **return_data) - { - char prefix_name[64]; -- char name[64]; -+ char name[128]; - int result; - - /* create a common prefix */ -diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c -index 480c062dd04f1..103a7787b3712 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_ah.c -+++ b/drivers/infiniband/hw/hns/hns_roce_ah.c -@@ -33,7 +33,9 @@ - #include - #include - #include -+#include "hnae3.h" - #include "hns_roce_device.h" -+#include "hns_roce_hw_v2.h" - - static inline u16 get_ah_udp_sport(const struct rdma_ah_attr *ah_attr) - { -@@ -58,6 +60,7 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, - struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device); - struct hns_roce_ah *ah = to_hr_ah(ibah); - int ret = 0; -+ u32 max_sl; - - if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata) - return -EOPNOTSUPP; -@@ -71,9 +74,17 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, - ah->av.hop_limit = grh->hop_limit; - ah->av.flowlabel = grh->flow_label; - ah->av.udp_sport = get_ah_udp_sport(ah_attr); -- ah->av.sl = rdma_ah_get_sl(ah_attr); - ah->av.tclass = get_tclass(grh); - -+ ah->av.sl = rdma_ah_get_sl(ah_attr); -+ max_sl = min_t(u32, MAX_SERVICE_LEVEL, hr_dev->caps.sl_num - 1); -+ if (unlikely(ah->av.sl > max_sl)) { -+ ibdev_err_ratelimited(&hr_dev->ib_dev, -+ "failed to set sl, sl (%u) shouldn't be larger than %u.\n", -+ ah->av.sl, max_sl); -+ return -EINVAL; -+ } -+ - memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE); - memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN); - -diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -index 33980485ef5ba..8a9d28f81149a 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -@@ -270,7 +270,7 @@ static bool check_inl_data_len(struct hns_roce_qp *qp, unsigned int len) - struct hns_roce_dev *hr_dev = to_hr_dev(qp->ibqp.device); - int mtu = ib_mtu_enum_to_int(qp->path_mtu); - -- if (len > qp->max_inline_data || len > mtu) { -+ if (mtu < 0 || len > qp->max_inline_data || len > mtu) { - ibdev_err(&hr_dev->ib_dev, - "invalid length of data, data len = %u, max inline len = %u, path mtu = %d.\n", - len, qp->max_inline_data, mtu); -@@ -4883,6 +4883,9 @@ static int check_cong_type(struct ib_qp *ibqp, - { - struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); - -+ if (ibqp->qp_type == IB_QPT_UD) -+ hr_dev->caps.cong_type = CONG_TYPE_DCQCN; -+ - /* different congestion types match different configurations */ - switch (hr_dev->caps.cong_type) { - case CONG_TYPE_DCQCN: -@@ -4979,22 +4982,32 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp, - struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); - struct ib_device *ibdev = &hr_dev->ib_dev; - const struct ib_gid_attr *gid_attr = NULL; -+ u8 sl = rdma_ah_get_sl(&attr->ah_attr); - int is_roce_protocol; - u16 vlan_id = 0xffff; - bool is_udp = false; -+ u32 max_sl; - u8 ib_port; - u8 hr_port; - int ret; - -+ max_sl = min_t(u32, MAX_SERVICE_LEVEL, hr_dev->caps.sl_num - 1); -+ if (unlikely(sl > max_sl)) { -+ ibdev_err_ratelimited(ibdev, -+ "failed to fill QPC, sl (%u) shouldn't be larger than %u.\n", -+ sl, max_sl); -+ return -EINVAL; -+ } -+ - /* - * If free_mr_en of qp is set, it means that this qp comes from - * free mr. This qp will perform the loopback operation. - * In the loopback scenario, only sl needs to be set. - */ - if (hr_qp->free_mr_en) { -- hr_reg_write(context, QPC_SL, rdma_ah_get_sl(&attr->ah_attr)); -+ hr_reg_write(context, QPC_SL, sl); - hr_reg_clear(qpc_mask, QPC_SL); -- hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr); -+ hr_qp->sl = sl; - return 0; - } - -@@ -5061,14 +5074,7 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp, - memcpy(context->dgid, grh->dgid.raw, sizeof(grh->dgid.raw)); - memset(qpc_mask->dgid, 0, sizeof(grh->dgid.raw)); - -- hr_qp->sl = rdma_ah_get_sl(&attr->ah_attr); -- if (unlikely(hr_qp->sl > MAX_SERVICE_LEVEL)) { -- ibdev_err(ibdev, -- "failed to fill QPC, sl (%u) shouldn't be larger than %d.\n", -- hr_qp->sl, MAX_SERVICE_LEVEL); -- return -EINVAL; -- } -- -+ hr_qp->sl = sl; - hr_reg_write(context, QPC_SL, hr_qp->sl); - hr_reg_clear(qpc_mask, QPC_SL); - -@@ -5961,7 +5967,7 @@ static void hns_roce_irq_work_handle(struct work_struct *work) - case HNS_ROCE_EVENT_TYPE_COMM_EST: - break; - case HNS_ROCE_EVENT_TYPE_SQ_DRAINED: -- ibdev_warn(ibdev, "send queue drained.\n"); -+ ibdev_dbg(ibdev, "send queue drained.\n"); - break; - case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR: - ibdev_err(ibdev, "local work queue 0x%x catast error, sub_event type is: %d\n", -@@ -5976,10 +5982,10 @@ static void hns_roce_irq_work_handle(struct work_struct *work) - irq_work->queue_num, irq_work->sub_type); - break; - case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH: -- ibdev_warn(ibdev, "SRQ limit reach.\n"); -+ ibdev_dbg(ibdev, "SRQ limit reach.\n"); - break; - case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH: -- ibdev_warn(ibdev, "SRQ last wqe reach.\n"); -+ ibdev_dbg(ibdev, "SRQ last wqe reach.\n"); - break; - case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR: - ibdev_err(ibdev, "SRQ catas error.\n"); -diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c -index 7a95f8677a02c..7b79e6b3f3baa 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_qp.c -+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c -@@ -1128,7 +1128,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, - { - struct hns_roce_ib_create_qp_resp resp = {}; - struct ib_device *ibdev = &hr_dev->ib_dev; -- struct hns_roce_ib_create_qp ucmd; -+ struct hns_roce_ib_create_qp ucmd = {}; - int ret; - - mutex_init(&hr_qp->mutex); -diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c -index 0baf3b5518b46..bce31e28eb303 100644 ---- a/drivers/infiniband/hw/mlx5/main.c -+++ b/drivers/infiniband/hw/mlx5/main.c -@@ -4027,10 +4027,8 @@ static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev) - return ret; - - ret = mlx5_mkey_cache_init(dev); -- if (ret) { -+ if (ret) - mlx5_ib_warn(dev, "mr cache init failed %d\n", ret); -- mlx5r_umr_resource_cleanup(dev); -- } - return ret; - } - -diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c -index ac53ed79ca64c..e0df3017e241a 100644 ---- a/drivers/infiniband/hw/mlx5/qp.c -+++ b/drivers/infiniband/hw/mlx5/qp.c -@@ -3960,6 +3960,30 @@ static unsigned int get_tx_affinity(struct ib_qp *qp, - return tx_affinity; - } - -+static int __mlx5_ib_qp_set_raw_qp_counter(struct mlx5_ib_qp *qp, u32 set_id, -+ struct mlx5_core_dev *mdev) -+{ -+ struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp; -+ struct mlx5_ib_rq *rq = &raw_packet_qp->rq; -+ u32 in[MLX5_ST_SZ_DW(modify_rq_in)] = {}; -+ void *rqc; -+ -+ if (!qp->rq.wqe_cnt) -+ return 0; -+ -+ MLX5_SET(modify_rq_in, in, rq_state, rq->state); -+ MLX5_SET(modify_rq_in, in, uid, to_mpd(qp->ibqp.pd)->uid); -+ -+ rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); -+ MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY); -+ -+ MLX5_SET64(modify_rq_in, in, modify_bitmask, -+ MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID); -+ MLX5_SET(rqc, rqc, counter_set_id, set_id); -+ -+ return mlx5_core_modify_rq(mdev, rq->base.mqp.qpn, in); -+} -+ - static int __mlx5_ib_qp_set_counter(struct ib_qp *qp, - struct rdma_counter *counter) - { -@@ -3975,6 +3999,9 @@ static int __mlx5_ib_qp_set_counter(struct ib_qp *qp, - else - set_id = mlx5_ib_get_counters_id(dev, mqp->port - 1); - -+ if (mqp->type == IB_QPT_RAW_PACKET) -+ return __mlx5_ib_qp_set_raw_qp_counter(mqp, set_id, dev->mdev); -+ - base = &mqp->trans_qp.base; - MLX5_SET(rts2rts_qp_in, in, opcode, MLX5_CMD_OP_RTS2RTS_QP); - MLX5_SET(rts2rts_qp_in, in, qpn, base->mqp.qpn); -diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c -index 50a0134b6901b..e6557d5f50ce5 100644 ---- a/drivers/input/rmi4/rmi_bus.c -+++ b/drivers/input/rmi4/rmi_bus.c -@@ -277,11 +277,11 @@ void rmi_unregister_function(struct rmi_function *fn) - - device_del(&fn->dev); - of_node_put(fn->dev.of_node); -- put_device(&fn->dev); - - for (i = 0; i < fn->num_of_irqs; i++) - irq_dispose_mapping(fn->irq[i]); - -+ put_device(&fn->dev); - } - - /** -diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c -index e4b2d9ef61b4d..0c6fc954e7296 100644 ---- a/drivers/interconnect/core.c -+++ b/drivers/interconnect/core.c -@@ -1100,15 +1100,17 @@ void icc_provider_del(struct icc_provider *provider) - } - EXPORT_SYMBOL_GPL(icc_provider_del); - -+static const struct of_device_id __maybe_unused ignore_list[] = { -+ { .compatible = "qcom,sc7180-ipa-virt" }, -+ { .compatible = "qcom,sdx55-ipa-virt" }, -+ { .compatible = "qcom,sm8150-ipa-virt" }, -+ {} -+}; -+ - static int of_count_icc_providers(struct device_node *np) - { - struct device_node *child; - int count = 0; -- const struct of_device_id __maybe_unused ignore_list[] = { -- { .compatible = "qcom,sc7180-ipa-virt" }, -- { .compatible = "qcom,sdx55-ipa-virt" }, -- {} -- }; - - for_each_available_child_of_node(np, child) { - if (of_property_read_bool(child, "#interconnect-cells") && -diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c -index 82d5e8a8c19ea..6d0450351a5a7 100644 ---- a/drivers/interconnect/qcom/sc7180.c -+++ b/drivers/interconnect/qcom/sc7180.c -@@ -153,30 +153,238 @@ DEFINE_QNODE(srvc_snoc, SC7180_SLAVE_SERVICE_SNOC, 1, 4); - DEFINE_QNODE(xs_qdss_stm, SC7180_SLAVE_QDSS_STM, 1, 4); - DEFINE_QNODE(xs_sys_tcu_cfg, SC7180_SLAVE_TCU, 1, 8); - --DEFINE_QBCM(bcm_acv, "ACV", false, &ebi); --DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); --DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); --DEFINE_QBCM(bcm_mm0, "MM0", false, &qns_mem_noc_hf); --DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); --DEFINE_QBCM(bcm_cn0, "CN0", true, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_ahb2phy0, &qhs_aop, &qhs_aoss, &qhs_boot_rom, &qhs_camera_cfg, &qhs_camera_nrt_throttle_cfg, &qhs_camera_rt_throttle_cfg, &qhs_clk_ctl, &qhs_cpr_cx, &qhs_cpr_mx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_display_rt_throttle_cfg, &qhs_display_throttle_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_mss_cfg, &qhs_npu_cfg, &qhs_npu_dma_throttle_cfg, &qhs_npu_dsp_throttle_cfg, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qm_cfg, &qhs_qm_mpu_cfg, &qhs_qup0, &qhs_qup1, &qhs_security, &qhs_snoc_cfg, &qhs_tcsr, &qhs_tlmm_1, &qhs_tlmm_2, &qhs_tlmm_3, &qhs_ufs_mem_cfg, &qhs_usb3, &qhs_venus_cfg, &qhs_venus_throttle_cfg, &qhs_vsense_ctrl_cfg, &srvc_cnoc); --DEFINE_QBCM(bcm_mm1, "MM1", false, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qhm_mnoc_cfg, &qxm_mdp0, &qxm_rot, &qxm_venus0, &qxm_venus_arm9); --DEFINE_QBCM(bcm_sh2, "SH2", false, &acm_sys_tcu); --DEFINE_QBCM(bcm_mm2, "MM2", false, &qns_mem_noc_sf); --DEFINE_QBCM(bcm_qup0, "QUP0", false, &qup_core_master_1, &qup_core_master_2); --DEFINE_QBCM(bcm_sh3, "SH3", false, &qnm_cmpnoc); --DEFINE_QBCM(bcm_sh4, "SH4", false, &acm_apps0); --DEFINE_QBCM(bcm_sn0, "SN0", true, &qns_gemnoc_sf); --DEFINE_QBCM(bcm_co0, "CO0", false, &qns_cdsp_gemnoc); --DEFINE_QBCM(bcm_sn1, "SN1", false, &qxs_imem); --DEFINE_QBCM(bcm_cn1, "CN1", false, &qhm_qspi, &xm_sdc2, &xm_emmc, &qhs_ahb2phy2, &qhs_emmc_cfg, &qhs_pdm, &qhs_qspi, &qhs_sdc2); --DEFINE_QBCM(bcm_sn2, "SN2", false, &qxm_pimem, &qns_gemnoc_gc); --DEFINE_QBCM(bcm_co2, "CO2", false, &qnm_npu); --DEFINE_QBCM(bcm_sn3, "SN3", false, &qxs_pimem); --DEFINE_QBCM(bcm_co3, "CO3", false, &qxm_npu_dsp); --DEFINE_QBCM(bcm_sn4, "SN4", false, &xs_qdss_stm); --DEFINE_QBCM(bcm_sn7, "SN7", false, &qnm_aggre1_noc); --DEFINE_QBCM(bcm_sn9, "SN9", false, &qnm_aggre2_noc); --DEFINE_QBCM(bcm_sn12, "SN12", false, &qnm_gemnoc); -+static struct qcom_icc_bcm bcm_acv = { -+ .name = "ACV", -+ .enable_mask = BIT(3), -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_mc0 = { -+ .name = "MC0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh0 = { -+ .name = "SH0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_llcc }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm0 = { -+ .name = "MM0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_hf }, -+}; -+ -+static struct qcom_icc_bcm bcm_ce0 = { -+ .name = "CE0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_crypto }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn0 = { -+ .name = "CN0", -+ .keepalive = true, -+ .num_nodes = 48, -+ .nodes = { &qnm_snoc, -+ &xm_qdss_dap, -+ &qhs_a1_noc_cfg, -+ &qhs_a2_noc_cfg, -+ &qhs_ahb2phy0, -+ &qhs_aop, -+ &qhs_aoss, -+ &qhs_boot_rom, -+ &qhs_camera_cfg, -+ &qhs_camera_nrt_throttle_cfg, -+ &qhs_camera_rt_throttle_cfg, -+ &qhs_clk_ctl, -+ &qhs_cpr_cx, -+ &qhs_cpr_mx, -+ &qhs_crypto0_cfg, -+ &qhs_dcc_cfg, -+ &qhs_ddrss_cfg, -+ &qhs_display_cfg, -+ &qhs_display_rt_throttle_cfg, -+ &qhs_display_throttle_cfg, -+ &qhs_glm, -+ &qhs_gpuss_cfg, -+ &qhs_imem_cfg, -+ &qhs_ipa, -+ &qhs_mnoc_cfg, -+ &qhs_mss_cfg, -+ &qhs_npu_cfg, -+ &qhs_npu_dma_throttle_cfg, -+ &qhs_npu_dsp_throttle_cfg, -+ &qhs_pimem_cfg, -+ &qhs_prng, -+ &qhs_qdss_cfg, -+ &qhs_qm_cfg, -+ &qhs_qm_mpu_cfg, -+ &qhs_qup0, -+ &qhs_qup1, -+ &qhs_security, -+ &qhs_snoc_cfg, -+ &qhs_tcsr, -+ &qhs_tlmm_1, -+ &qhs_tlmm_2, -+ &qhs_tlmm_3, -+ &qhs_ufs_mem_cfg, -+ &qhs_usb3, -+ &qhs_venus_cfg, -+ &qhs_venus_throttle_cfg, -+ &qhs_vsense_ctrl_cfg, -+ &srvc_cnoc -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm1 = { -+ .name = "MM1", -+ .keepalive = false, -+ .num_nodes = 8, -+ .nodes = { &qxm_camnoc_hf0_uncomp, -+ &qxm_camnoc_hf1_uncomp, -+ &qxm_camnoc_sf_uncomp, -+ &qhm_mnoc_cfg, -+ &qxm_mdp0, -+ &qxm_rot, -+ &qxm_venus0, -+ &qxm_venus_arm9 -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh2 = { -+ .name = "SH2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &acm_sys_tcu }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm2 = { -+ .name = "MM2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_qup0 = { -+ .name = "QUP0", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &qup_core_master_1, &qup_core_master_2 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh3 = { -+ .name = "SH3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_cmpnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh4 = { -+ .name = "SH4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &acm_apps0 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn0 = { -+ .name = "SN0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_gemnoc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_co0 = { -+ .name = "CO0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_cdsp_gemnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn1 = { -+ .name = "SN1", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_imem }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn1 = { -+ .name = "CN1", -+ .keepalive = false, -+ .num_nodes = 8, -+ .nodes = { &qhm_qspi, -+ &xm_sdc2, -+ &xm_emmc, -+ &qhs_ahb2phy2, -+ &qhs_emmc_cfg, -+ &qhs_pdm, -+ &qhs_qspi, -+ &qhs_sdc2 -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn2 = { -+ .name = "SN2", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &qxm_pimem, &qns_gemnoc_gc }, -+}; -+ -+static struct qcom_icc_bcm bcm_co2 = { -+ .name = "CO2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_npu }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn3 = { -+ .name = "SN3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_pimem }, -+}; -+ -+static struct qcom_icc_bcm bcm_co3 = { -+ .name = "CO3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_npu_dsp }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn4 = { -+ .name = "SN4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &xs_qdss_stm }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn7 = { -+ .name = "SN7", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_aggre1_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn9 = { -+ .name = "SN9", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_aggre2_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn12 = { -+ .name = "SN12", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_gemnoc }, -+}; - - static struct qcom_icc_bcm * const aggre1_noc_bcms[] = { - &bcm_cn1, -diff --git a/drivers/interconnect/qcom/sc7280.c b/drivers/interconnect/qcom/sc7280.c -index 971f538bc98ad..3c39edd21b6ca 100644 ---- a/drivers/interconnect/qcom/sc7280.c -+++ b/drivers/interconnect/qcom/sc7280.c -@@ -1284,6 +1284,7 @@ static struct qcom_icc_node srvc_snoc = { - - static struct qcom_icc_bcm bcm_acv = { - .name = "ACV", -+ .enable_mask = BIT(3), - .num_nodes = 1, - .nodes = { &ebi }, - }; -diff --git a/drivers/interconnect/qcom/sc8180x.c b/drivers/interconnect/qcom/sc8180x.c -index 8e32ca958824c..83461e31774ec 100644 ---- a/drivers/interconnect/qcom/sc8180x.c -+++ b/drivers/interconnect/qcom/sc8180x.c -@@ -1360,6 +1360,7 @@ static struct qcom_icc_node slv_qup_core_2 = { - - static struct qcom_icc_bcm bcm_acv = { - .name = "ACV", -+ .enable_mask = BIT(3), - .num_nodes = 1, - .nodes = { &slv_ebi } - }; -diff --git a/drivers/interconnect/qcom/sc8280xp.c b/drivers/interconnect/qcom/sc8280xp.c -index 507fe5f89791a..489f259a02e5b 100644 ---- a/drivers/interconnect/qcom/sc8280xp.c -+++ b/drivers/interconnect/qcom/sc8280xp.c -@@ -1727,6 +1727,7 @@ static struct qcom_icc_node srvc_snoc = { - - static struct qcom_icc_bcm bcm_acv = { - .name = "ACV", -+ .enable_mask = BIT(3), - .num_nodes = 1, - .nodes = { &ebi }, - }; -diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c -index 954e7bd13fc41..02cf890684441 100644 ---- a/drivers/interconnect/qcom/sdm845.c -+++ b/drivers/interconnect/qcom/sdm845.c -@@ -146,34 +146,256 @@ DEFINE_QNODE(srvc_snoc, SDM845_SLAVE_SERVICE_SNOC, 1, 4); - DEFINE_QNODE(xs_qdss_stm, SDM845_SLAVE_QDSS_STM, 1, 4); - DEFINE_QNODE(xs_sys_tcu_cfg, SDM845_SLAVE_TCU, 1, 8); - --DEFINE_QBCM(bcm_acv, "ACV", false, &ebi); --DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); --DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); --DEFINE_QBCM(bcm_mm0, "MM0", false, &qns_mem_noc_hf); --DEFINE_QBCM(bcm_sh1, "SH1", false, &qns_apps_io); --DEFINE_QBCM(bcm_mm1, "MM1", true, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf0, &qxm_camnoc_hf1, &qxm_mdp0, &qxm_mdp1); --DEFINE_QBCM(bcm_sh2, "SH2", false, &qns_memnoc_snoc); --DEFINE_QBCM(bcm_mm2, "MM2", false, &qns2_mem_noc); --DEFINE_QBCM(bcm_sh3, "SH3", false, &acm_tcu); --DEFINE_QBCM(bcm_mm3, "MM3", false, &qxm_camnoc_sf, &qxm_rot, &qxm_venus0, &qxm_venus1, &qxm_venus_arm9); --DEFINE_QBCM(bcm_sh5, "SH5", false, &qnm_apps); --DEFINE_QBCM(bcm_sn0, "SN0", true, &qns_memnoc_sf); --DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); --DEFINE_QBCM(bcm_cn0, "CN0", false, &qhm_spdm, &qhm_tic, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_aop, &qhs_aoss, &qhs_camera_cfg, &qhs_clk_ctl, &qhs_compute_dsp_cfg, &qhs_cpr_cx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_pcie0_cfg, &qhs_pcie_gen3_cfg, &qhs_pdm, &qhs_phy_refgen_south, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qupv3_north, &qhs_qupv3_south, &qhs_sdc2, &qhs_sdc4, &qhs_snoc_cfg, &qhs_spdm, &qhs_spss_cfg, &qhs_tcsr, &qhs_tlmm_north, &qhs_tlmm_south, &qhs_tsif, &qhs_ufs_card_cfg, &qhs_ufs_mem_cfg, &qhs_usb3_0, &qhs_usb3_1, &qhs_venus_cfg, &qhs_vsense_ctrl_cfg, &qns_cnoc_a2noc, &srvc_cnoc); --DEFINE_QBCM(bcm_qup0, "QUP0", false, &qhm_qup1, &qhm_qup2); --DEFINE_QBCM(bcm_sn1, "SN1", false, &qxs_imem); --DEFINE_QBCM(bcm_sn2, "SN2", false, &qns_memnoc_gc); --DEFINE_QBCM(bcm_sn3, "SN3", false, &qns_cnoc); --DEFINE_QBCM(bcm_sn4, "SN4", false, &qxm_pimem); --DEFINE_QBCM(bcm_sn5, "SN5", false, &xs_qdss_stm); --DEFINE_QBCM(bcm_sn6, "SN6", false, &qhs_apss, &srvc_snoc, &xs_sys_tcu_cfg); --DEFINE_QBCM(bcm_sn7, "SN7", false, &qxs_pcie); --DEFINE_QBCM(bcm_sn8, "SN8", false, &qxs_pcie_gen3); --DEFINE_QBCM(bcm_sn9, "SN9", false, &srvc_aggre1_noc, &qnm_aggre1_noc); --DEFINE_QBCM(bcm_sn11, "SN11", false, &srvc_aggre2_noc, &qnm_aggre2_noc); --DEFINE_QBCM(bcm_sn12, "SN12", false, &qnm_gladiator_sodv, &xm_gic); --DEFINE_QBCM(bcm_sn14, "SN14", false, &qnm_pcie_anoc); --DEFINE_QBCM(bcm_sn15, "SN15", false, &qnm_memnoc); -+static struct qcom_icc_bcm bcm_acv = { -+ .name = "ACV", -+ .enable_mask = BIT(3), -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_mc0 = { -+ .name = "MC0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh0 = { -+ .name = "SH0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_llcc }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm0 = { -+ .name = "MM0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_hf }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh1 = { -+ .name = "SH1", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_apps_io }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm1 = { -+ .name = "MM1", -+ .keepalive = true, -+ .num_nodes = 7, -+ .nodes = { &qxm_camnoc_hf0_uncomp, -+ &qxm_camnoc_hf1_uncomp, -+ &qxm_camnoc_sf_uncomp, -+ &qxm_camnoc_hf0, -+ &qxm_camnoc_hf1, -+ &qxm_mdp0, -+ &qxm_mdp1 -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh2 = { -+ .name = "SH2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_memnoc_snoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm2 = { -+ .name = "MM2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns2_mem_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh3 = { -+ .name = "SH3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &acm_tcu }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm3 = { -+ .name = "MM3", -+ .keepalive = false, -+ .num_nodes = 5, -+ .nodes = { &qxm_camnoc_sf, &qxm_rot, &qxm_venus0, &qxm_venus1, &qxm_venus_arm9 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh5 = { -+ .name = "SH5", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_apps }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn0 = { -+ .name = "SN0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_memnoc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_ce0 = { -+ .name = "CE0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_crypto }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn0 = { -+ .name = "CN0", -+ .keepalive = false, -+ .num_nodes = 47, -+ .nodes = { &qhm_spdm, -+ &qhm_tic, -+ &qnm_snoc, -+ &xm_qdss_dap, -+ &qhs_a1_noc_cfg, -+ &qhs_a2_noc_cfg, -+ &qhs_aop, -+ &qhs_aoss, -+ &qhs_camera_cfg, -+ &qhs_clk_ctl, -+ &qhs_compute_dsp_cfg, -+ &qhs_cpr_cx, -+ &qhs_crypto0_cfg, -+ &qhs_dcc_cfg, -+ &qhs_ddrss_cfg, -+ &qhs_display_cfg, -+ &qhs_glm, -+ &qhs_gpuss_cfg, -+ &qhs_imem_cfg, -+ &qhs_ipa, -+ &qhs_mnoc_cfg, -+ &qhs_pcie0_cfg, -+ &qhs_pcie_gen3_cfg, -+ &qhs_pdm, -+ &qhs_phy_refgen_south, -+ &qhs_pimem_cfg, -+ &qhs_prng, -+ &qhs_qdss_cfg, -+ &qhs_qupv3_north, -+ &qhs_qupv3_south, -+ &qhs_sdc2, -+ &qhs_sdc4, -+ &qhs_snoc_cfg, -+ &qhs_spdm, -+ &qhs_spss_cfg, -+ &qhs_tcsr, -+ &qhs_tlmm_north, -+ &qhs_tlmm_south, -+ &qhs_tsif, -+ &qhs_ufs_card_cfg, -+ &qhs_ufs_mem_cfg, -+ &qhs_usb3_0, -+ &qhs_usb3_1, -+ &qhs_venus_cfg, -+ &qhs_vsense_ctrl_cfg, -+ &qns_cnoc_a2noc, -+ &srvc_cnoc -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_qup0 = { -+ .name = "QUP0", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &qhm_qup1, &qhm_qup2 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn1 = { -+ .name = "SN1", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_imem }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn2 = { -+ .name = "SN2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_memnoc_gc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn3 = { -+ .name = "SN3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_cnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn4 = { -+ .name = "SN4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_pimem }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn5 = { -+ .name = "SN5", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &xs_qdss_stm }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn6 = { -+ .name = "SN6", -+ .keepalive = false, -+ .num_nodes = 3, -+ .nodes = { &qhs_apss, &srvc_snoc, &xs_sys_tcu_cfg }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn7 = { -+ .name = "SN7", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_pcie }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn8 = { -+ .name = "SN8", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_pcie_gen3 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn9 = { -+ .name = "SN9", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &srvc_aggre1_noc, &qnm_aggre1_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn11 = { -+ .name = "SN11", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &srvc_aggre2_noc, &qnm_aggre2_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn12 = { -+ .name = "SN12", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &qnm_gladiator_sodv, &xm_gic }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn14 = { -+ .name = "SN14", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_pcie_anoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn15 = { -+ .name = "SN15", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_memnoc }, -+}; - - static struct qcom_icc_bcm * const aggre1_noc_bcms[] = { - &bcm_sn9, -diff --git a/drivers/interconnect/qcom/sm6350.c b/drivers/interconnect/qcom/sm6350.c -index a3d46e59444e0..aae4b43b730c0 100644 ---- a/drivers/interconnect/qcom/sm6350.c -+++ b/drivers/interconnect/qcom/sm6350.c -@@ -142,31 +142,233 @@ DEFINE_QNODE(srvc_snoc, SM6350_SLAVE_SERVICE_SNOC, 1, 4); - DEFINE_QNODE(xs_qdss_stm, SM6350_SLAVE_QDSS_STM, 1, 4); - DEFINE_QNODE(xs_sys_tcu_cfg, SM6350_SLAVE_TCU, 1, 8); - --DEFINE_QBCM(bcm_acv, "ACV", false, &ebi); --DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); --DEFINE_QBCM(bcm_cn0, "CN0", true, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_ahb2phy0, &qhs_aoss, &qhs_boot_rom, &qhs_camera_cfg, &qhs_camera_nrt_thrott_cfg, &qhs_camera_rt_throttle_cfg, &qhs_clk_ctl, &qhs_cpr_cx, &qhs_cpr_mx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_display_throttle_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_mss_cfg, &qhs_npu_cfg, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qm_cfg, &qhs_qm_mpu_cfg, &qhs_qup0, &qhs_qup1, &qhs_security, &qhs_snoc_cfg, &qhs_tcsr, &qhs_ufs_mem_cfg, &qhs_usb3_0, &qhs_venus_cfg, &qhs_venus_throttle_cfg, &qhs_vsense_ctrl_cfg, &srvc_cnoc); --DEFINE_QBCM(bcm_cn1, "CN1", false, &xm_emmc, &xm_sdc2, &qhs_ahb2phy2, &qhs_emmc_cfg, &qhs_pdm, &qhs_sdc2); --DEFINE_QBCM(bcm_co0, "CO0", false, &qns_cdsp_gemnoc); --DEFINE_QBCM(bcm_co2, "CO2", false, &qnm_npu); --DEFINE_QBCM(bcm_co3, "CO3", false, &qxm_npu_dsp); --DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); --DEFINE_QBCM(bcm_mm0, "MM0", true, &qns_mem_noc_hf); --DEFINE_QBCM(bcm_mm1, "MM1", true, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_icp_uncomp, &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf, &qxm_mdp0); --DEFINE_QBCM(bcm_mm2, "MM2", false, &qns_mem_noc_sf); --DEFINE_QBCM(bcm_mm3, "MM3", false, &qhm_mnoc_cfg, &qnm_video0, &qnm_video_cvp, &qxm_camnoc_sf); --DEFINE_QBCM(bcm_qup0, "QUP0", false, &qup0_core_master, &qup1_core_master, &qup0_core_slave, &qup1_core_slave); --DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); --DEFINE_QBCM(bcm_sh2, "SH2", false, &acm_sys_tcu); --DEFINE_QBCM(bcm_sh3, "SH3", false, &qnm_cmpnoc); --DEFINE_QBCM(bcm_sh4, "SH4", false, &acm_apps); --DEFINE_QBCM(bcm_sn0, "SN0", true, &qns_gemnoc_sf); --DEFINE_QBCM(bcm_sn1, "SN1", false, &qxs_imem); --DEFINE_QBCM(bcm_sn2, "SN2", false, &qns_gemnoc_gc); --DEFINE_QBCM(bcm_sn3, "SN3", false, &qxs_pimem); --DEFINE_QBCM(bcm_sn4, "SN4", false, &xs_qdss_stm); --DEFINE_QBCM(bcm_sn5, "SN5", false, &qnm_aggre1_noc); --DEFINE_QBCM(bcm_sn6, "SN6", false, &qnm_aggre2_noc); --DEFINE_QBCM(bcm_sn10, "SN10", false, &qnm_gemnoc); -+static struct qcom_icc_bcm bcm_acv = { -+ .name = "ACV", -+ .enable_mask = BIT(3), -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_ce0 = { -+ .name = "CE0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_crypto }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn0 = { -+ .name = "CN0", -+ .keepalive = true, -+ .num_nodes = 41, -+ .nodes = { &qnm_snoc, -+ &xm_qdss_dap, -+ &qhs_a1_noc_cfg, -+ &qhs_a2_noc_cfg, -+ &qhs_ahb2phy0, -+ &qhs_aoss, -+ &qhs_boot_rom, -+ &qhs_camera_cfg, -+ &qhs_camera_nrt_thrott_cfg, -+ &qhs_camera_rt_throttle_cfg, -+ &qhs_clk_ctl, -+ &qhs_cpr_cx, -+ &qhs_cpr_mx, -+ &qhs_crypto0_cfg, -+ &qhs_dcc_cfg, -+ &qhs_ddrss_cfg, -+ &qhs_display_cfg, -+ &qhs_display_throttle_cfg, -+ &qhs_glm, -+ &qhs_gpuss_cfg, -+ &qhs_imem_cfg, -+ &qhs_ipa, -+ &qhs_mnoc_cfg, -+ &qhs_mss_cfg, -+ &qhs_npu_cfg, -+ &qhs_pimem_cfg, -+ &qhs_prng, -+ &qhs_qdss_cfg, -+ &qhs_qm_cfg, -+ &qhs_qm_mpu_cfg, -+ &qhs_qup0, -+ &qhs_qup1, -+ &qhs_security, -+ &qhs_snoc_cfg, -+ &qhs_tcsr, -+ &qhs_ufs_mem_cfg, -+ &qhs_usb3_0, -+ &qhs_venus_cfg, -+ &qhs_venus_throttle_cfg, -+ &qhs_vsense_ctrl_cfg, -+ &srvc_cnoc -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn1 = { -+ .name = "CN1", -+ .keepalive = false, -+ .num_nodes = 6, -+ .nodes = { &xm_emmc, -+ &xm_sdc2, -+ &qhs_ahb2phy2, -+ &qhs_emmc_cfg, -+ &qhs_pdm, -+ &qhs_sdc2 -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_co0 = { -+ .name = "CO0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_cdsp_gemnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_co2 = { -+ .name = "CO2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_npu }, -+}; -+ -+static struct qcom_icc_bcm bcm_co3 = { -+ .name = "CO3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_npu_dsp }, -+}; -+ -+static struct qcom_icc_bcm bcm_mc0 = { -+ .name = "MC0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm0 = { -+ .name = "MM0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_hf }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm1 = { -+ .name = "MM1", -+ .keepalive = true, -+ .num_nodes = 5, -+ .nodes = { &qxm_camnoc_hf0_uncomp, -+ &qxm_camnoc_icp_uncomp, -+ &qxm_camnoc_sf_uncomp, -+ &qxm_camnoc_hf, -+ &qxm_mdp0 -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm2 = { -+ .name = "MM2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm3 = { -+ .name = "MM3", -+ .keepalive = false, -+ .num_nodes = 4, -+ .nodes = { &qhm_mnoc_cfg, &qnm_video0, &qnm_video_cvp, &qxm_camnoc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_qup0 = { -+ .name = "QUP0", -+ .keepalive = false, -+ .num_nodes = 4, -+ .nodes = { &qup0_core_master, &qup1_core_master, &qup0_core_slave, &qup1_core_slave }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh0 = { -+ .name = "SH0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_llcc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh2 = { -+ .name = "SH2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &acm_sys_tcu }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh3 = { -+ .name = "SH3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_cmpnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh4 = { -+ .name = "SH4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &acm_apps }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn0 = { -+ .name = "SN0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_gemnoc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn1 = { -+ .name = "SN1", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_imem }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn2 = { -+ .name = "SN2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_gemnoc_gc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn3 = { -+ .name = "SN3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_pimem }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn4 = { -+ .name = "SN4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &xs_qdss_stm }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn5 = { -+ .name = "SN5", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_aggre1_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn6 = { -+ .name = "SN6", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_aggre2_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn10 = { -+ .name = "SN10", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_gemnoc }, -+}; - - static struct qcom_icc_bcm * const aggre1_noc_bcms[] = { - &bcm_cn1, -diff --git a/drivers/interconnect/qcom/sm8150.c b/drivers/interconnect/qcom/sm8150.c -index 1d04a4bfea800..685f35bbf5a7c 100644 ---- a/drivers/interconnect/qcom/sm8150.c -+++ b/drivers/interconnect/qcom/sm8150.c -@@ -56,7 +56,6 @@ DEFINE_QNODE(qnm_pcie, SM8150_MASTER_GEM_NOC_PCIE_SNOC, 1, 16, SM8150_SLAVE_LLCC - DEFINE_QNODE(qnm_snoc_gc, SM8150_MASTER_SNOC_GC_MEM_NOC, 1, 8, SM8150_SLAVE_LLCC); - DEFINE_QNODE(qnm_snoc_sf, SM8150_MASTER_SNOC_SF_MEM_NOC, 1, 16, SM8150_SLAVE_LLCC); - DEFINE_QNODE(qxm_ecc, SM8150_MASTER_ECC, 2, 32, SM8150_SLAVE_LLCC); --DEFINE_QNODE(ipa_core_master, SM8150_MASTER_IPA_CORE, 1, 8, SM8150_SLAVE_IPA_CORE); - DEFINE_QNODE(llcc_mc, SM8150_MASTER_LLCC, 4, 4, SM8150_SLAVE_EBI_CH0); - DEFINE_QNODE(qhm_mnoc_cfg, SM8150_MASTER_CNOC_MNOC_CFG, 1, 4, SM8150_SLAVE_SERVICE_MNOC); - DEFINE_QNODE(qxm_camnoc_hf0, SM8150_MASTER_CAMNOC_HF0, 1, 32, SM8150_SLAVE_MNOC_HF_MEM_NOC); -@@ -139,7 +138,6 @@ DEFINE_QNODE(qns_ecc, SM8150_SLAVE_ECC, 1, 32); - DEFINE_QNODE(qns_gem_noc_snoc, SM8150_SLAVE_GEM_NOC_SNOC, 1, 8, SM8150_MASTER_GEM_NOC_SNOC); - DEFINE_QNODE(qns_llcc, SM8150_SLAVE_LLCC, 4, 16, SM8150_MASTER_LLCC); - DEFINE_QNODE(srvc_gemnoc, SM8150_SLAVE_SERVICE_GEM_NOC, 1, 4); --DEFINE_QNODE(ipa_core_slave, SM8150_SLAVE_IPA_CORE, 1, 8); - DEFINE_QNODE(ebi, SM8150_SLAVE_EBI_CH0, 4, 4); - DEFINE_QNODE(qns2_mem_noc, SM8150_SLAVE_MNOC_SF_MEM_NOC, 1, 32, SM8150_MASTER_MNOC_SF_MEM_NOC); - DEFINE_QNODE(qns_mem_noc_hf, SM8150_SLAVE_MNOC_HF_MEM_NOC, 2, 32, SM8150_MASTER_MNOC_HF_MEM_NOC); -@@ -156,35 +154,262 @@ DEFINE_QNODE(xs_pcie_1, SM8150_SLAVE_PCIE_1, 1, 8); - DEFINE_QNODE(xs_qdss_stm, SM8150_SLAVE_QDSS_STM, 1, 4); - DEFINE_QNODE(xs_sys_tcu_cfg, SM8150_SLAVE_TCU, 1, 8); - --DEFINE_QBCM(bcm_acv, "ACV", false, &ebi); --DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); --DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); --DEFINE_QBCM(bcm_mm0, "MM0", true, &qns_mem_noc_hf); --DEFINE_QBCM(bcm_mm1, "MM1", false, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf0, &qxm_camnoc_hf1, &qxm_mdp0, &qxm_mdp1); --DEFINE_QBCM(bcm_sh2, "SH2", false, &qns_gem_noc_snoc); --DEFINE_QBCM(bcm_mm2, "MM2", false, &qxm_camnoc_sf, &qns2_mem_noc); --DEFINE_QBCM(bcm_sh3, "SH3", false, &acm_gpu_tcu, &acm_sys_tcu); --DEFINE_QBCM(bcm_mm3, "MM3", false, &qxm_rot, &qxm_venus0, &qxm_venus1, &qxm_venus_arm9); --DEFINE_QBCM(bcm_sh4, "SH4", false, &qnm_cmpnoc); --DEFINE_QBCM(bcm_sh5, "SH5", false, &acm_apps); --DEFINE_QBCM(bcm_sn0, "SN0", true, &qns_gemnoc_sf); --DEFINE_QBCM(bcm_co0, "CO0", false, &qns_cdsp_mem_noc); --DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); --DEFINE_QBCM(bcm_sn1, "SN1", false, &qxs_imem); --DEFINE_QBCM(bcm_co1, "CO1", false, &qnm_npu); --DEFINE_QBCM(bcm_ip0, "IP0", false, &ipa_core_slave); --DEFINE_QBCM(bcm_cn0, "CN0", true, &qhm_spdm, &qnm_snoc, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_ahb2phy_south, &qhs_aop, &qhs_aoss, &qhs_camera_cfg, &qhs_clk_ctl, &qhs_compute_dsp, &qhs_cpr_cx, &qhs_cpr_mmcx, &qhs_cpr_mx, &qhs_crypto0_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_emac_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_npu_cfg, &qhs_pcie0_cfg, &qhs_pcie1_cfg, &qhs_phy_refgen_north, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qspi, &qhs_qupv3_east, &qhs_qupv3_north, &qhs_qupv3_south, &qhs_sdc2, &qhs_sdc4, &qhs_snoc_cfg, &qhs_spdm, &qhs_spss_cfg, &qhs_ssc_cfg, &qhs_tcsr, &qhs_tlmm_east, &qhs_tlmm_north, &qhs_tlmm_south, &qhs_tlmm_west, &qhs_tsif, &qhs_ufs_card_cfg, &qhs_ufs_mem_cfg, &qhs_usb3_0, &qhs_usb3_1, &qhs_venus_cfg, &qhs_vsense_ctrl_cfg, &qns_cnoc_a2noc, &srvc_cnoc); --DEFINE_QBCM(bcm_qup0, "QUP0", false, &qhm_qup0, &qhm_qup1, &qhm_qup2); --DEFINE_QBCM(bcm_sn2, "SN2", false, &qns_gemnoc_gc); --DEFINE_QBCM(bcm_sn3, "SN3", false, &srvc_aggre1_noc, &srvc_aggre2_noc, &qns_cnoc); --DEFINE_QBCM(bcm_sn4, "SN4", false, &qxs_pimem); --DEFINE_QBCM(bcm_sn5, "SN5", false, &xs_qdss_stm); --DEFINE_QBCM(bcm_sn8, "SN8", false, &xs_pcie_0, &xs_pcie_1); --DEFINE_QBCM(bcm_sn9, "SN9", false, &qnm_aggre1_noc); --DEFINE_QBCM(bcm_sn11, "SN11", false, &qnm_aggre2_noc); --DEFINE_QBCM(bcm_sn12, "SN12", false, &qxm_pimem, &xm_gic); --DEFINE_QBCM(bcm_sn14, "SN14", false, &qns_pcie_mem_noc); --DEFINE_QBCM(bcm_sn15, "SN15", false, &qnm_gemnoc); -+static struct qcom_icc_bcm bcm_acv = { -+ .name = "ACV", -+ .enable_mask = BIT(3), -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_mc0 = { -+ .name = "MC0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh0 = { -+ .name = "SH0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_llcc }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm0 = { -+ .name = "MM0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_hf }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm1 = { -+ .name = "MM1", -+ .keepalive = false, -+ .num_nodes = 7, -+ .nodes = { &qxm_camnoc_hf0_uncomp, -+ &qxm_camnoc_hf1_uncomp, -+ &qxm_camnoc_sf_uncomp, -+ &qxm_camnoc_hf0, -+ &qxm_camnoc_hf1, -+ &qxm_mdp0, -+ &qxm_mdp1 -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh2 = { -+ .name = "SH2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_gem_noc_snoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm2 = { -+ .name = "MM2", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &qxm_camnoc_sf, &qns2_mem_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh3 = { -+ .name = "SH3", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &acm_gpu_tcu, &acm_sys_tcu }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm3 = { -+ .name = "MM3", -+ .keepalive = false, -+ .num_nodes = 4, -+ .nodes = { &qxm_rot, &qxm_venus0, &qxm_venus1, &qxm_venus_arm9 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh4 = { -+ .name = "SH4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_cmpnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh5 = { -+ .name = "SH5", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &acm_apps }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn0 = { -+ .name = "SN0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_gemnoc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_co0 = { -+ .name = "CO0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_cdsp_mem_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_ce0 = { -+ .name = "CE0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_crypto }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn1 = { -+ .name = "SN1", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_imem }, -+}; -+ -+static struct qcom_icc_bcm bcm_co1 = { -+ .name = "CO1", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_npu }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn0 = { -+ .name = "CN0", -+ .keepalive = true, -+ .num_nodes = 53, -+ .nodes = { &qhm_spdm, -+ &qnm_snoc, -+ &qhs_a1_noc_cfg, -+ &qhs_a2_noc_cfg, -+ &qhs_ahb2phy_south, -+ &qhs_aop, -+ &qhs_aoss, -+ &qhs_camera_cfg, -+ &qhs_clk_ctl, -+ &qhs_compute_dsp, -+ &qhs_cpr_cx, -+ &qhs_cpr_mmcx, -+ &qhs_cpr_mx, -+ &qhs_crypto0_cfg, -+ &qhs_ddrss_cfg, -+ &qhs_display_cfg, -+ &qhs_emac_cfg, -+ &qhs_glm, -+ &qhs_gpuss_cfg, -+ &qhs_imem_cfg, -+ &qhs_ipa, -+ &qhs_mnoc_cfg, -+ &qhs_npu_cfg, -+ &qhs_pcie0_cfg, -+ &qhs_pcie1_cfg, -+ &qhs_phy_refgen_north, -+ &qhs_pimem_cfg, -+ &qhs_prng, -+ &qhs_qdss_cfg, -+ &qhs_qspi, -+ &qhs_qupv3_east, -+ &qhs_qupv3_north, -+ &qhs_qupv3_south, -+ &qhs_sdc2, -+ &qhs_sdc4, -+ &qhs_snoc_cfg, -+ &qhs_spdm, -+ &qhs_spss_cfg, -+ &qhs_ssc_cfg, -+ &qhs_tcsr, -+ &qhs_tlmm_east, -+ &qhs_tlmm_north, -+ &qhs_tlmm_south, -+ &qhs_tlmm_west, -+ &qhs_tsif, -+ &qhs_ufs_card_cfg, -+ &qhs_ufs_mem_cfg, -+ &qhs_usb3_0, -+ &qhs_usb3_1, -+ &qhs_venus_cfg, -+ &qhs_vsense_ctrl_cfg, -+ &qns_cnoc_a2noc, -+ &srvc_cnoc -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_qup0 = { -+ .name = "QUP0", -+ .keepalive = false, -+ .num_nodes = 3, -+ .nodes = { &qhm_qup0, &qhm_qup1, &qhm_qup2 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn2 = { -+ .name = "SN2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_gemnoc_gc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn3 = { -+ .name = "SN3", -+ .keepalive = false, -+ .num_nodes = 3, -+ .nodes = { &srvc_aggre1_noc, &srvc_aggre2_noc, &qns_cnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn4 = { -+ .name = "SN4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_pimem }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn5 = { -+ .name = "SN5", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &xs_qdss_stm }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn8 = { -+ .name = "SN8", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &xs_pcie_0, &xs_pcie_1 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn9 = { -+ .name = "SN9", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_aggre1_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn11 = { -+ .name = "SN11", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_aggre2_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn12 = { -+ .name = "SN12", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &qxm_pimem, &xm_gic }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn14 = { -+ .name = "SN14", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_pcie_mem_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn15 = { -+ .name = "SN15", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_gemnoc }, -+}; - - static struct qcom_icc_bcm * const aggre1_noc_bcms[] = { - &bcm_qup0, -@@ -398,22 +623,6 @@ static const struct qcom_icc_desc sm8150_gem_noc = { - .num_bcms = ARRAY_SIZE(gem_noc_bcms), - }; - --static struct qcom_icc_bcm * const ipa_virt_bcms[] = { -- &bcm_ip0, --}; -- --static struct qcom_icc_node * const ipa_virt_nodes[] = { -- [MASTER_IPA_CORE] = &ipa_core_master, -- [SLAVE_IPA_CORE] = &ipa_core_slave, --}; -- --static const struct qcom_icc_desc sm8150_ipa_virt = { -- .nodes = ipa_virt_nodes, -- .num_nodes = ARRAY_SIZE(ipa_virt_nodes), -- .bcms = ipa_virt_bcms, -- .num_bcms = ARRAY_SIZE(ipa_virt_bcms), --}; -- - static struct qcom_icc_bcm * const mc_virt_bcms[] = { - &bcm_acv, - &bcm_mc0, -@@ -517,8 +726,6 @@ static const struct of_device_id qnoc_of_match[] = { - .data = &sm8150_dc_noc}, - { .compatible = "qcom,sm8150-gem-noc", - .data = &sm8150_gem_noc}, -- { .compatible = "qcom,sm8150-ipa-virt", -- .data = &sm8150_ipa_virt}, - { .compatible = "qcom,sm8150-mc-virt", - .data = &sm8150_mc_virt}, - { .compatible = "qcom,sm8150-mmss-noc", -diff --git a/drivers/interconnect/qcom/sm8150.h b/drivers/interconnect/qcom/sm8150.h -index 97996f64d799c..023161681fb87 100644 ---- a/drivers/interconnect/qcom/sm8150.h -+++ b/drivers/interconnect/qcom/sm8150.h -@@ -35,7 +35,7 @@ - #define SM8150_MASTER_GPU_TCU 24 - #define SM8150_MASTER_GRAPHICS_3D 25 - #define SM8150_MASTER_IPA 26 --#define SM8150_MASTER_IPA_CORE 27 -+/* 27 was used by SLAVE_IPA_CORE, now represented as RPMh clock */ - #define SM8150_MASTER_LLCC 28 - #define SM8150_MASTER_MDP_PORT0 29 - #define SM8150_MASTER_MDP_PORT1 30 -@@ -94,7 +94,7 @@ - #define SM8150_SLAVE_GRAPHICS_3D_CFG 83 - #define SM8150_SLAVE_IMEM_CFG 84 - #define SM8150_SLAVE_IPA_CFG 85 --#define SM8150_SLAVE_IPA_CORE 86 -+/* 86 was used by SLAVE_IPA_CORE, now represented as RPMh clock */ - #define SM8150_SLAVE_LLCC 87 - #define SM8150_SLAVE_LLCC_CFG 88 - #define SM8150_SLAVE_MNOC_HF_MEM_NOC 89 -diff --git a/drivers/interconnect/qcom/sm8350.c b/drivers/interconnect/qcom/sm8350.c -index 5398e7c8d826b..e6e2dcf4574d8 100644 ---- a/drivers/interconnect/qcom/sm8350.c -+++ b/drivers/interconnect/qcom/sm8350.c -@@ -165,38 +165,283 @@ DEFINE_QNODE(ebi_disp, SM8350_SLAVE_EBI1_DISP, 4, 4); - DEFINE_QNODE(qns_mem_noc_hf_disp, SM8350_SLAVE_MNOC_HF_MEM_NOC_DISP, 2, 32, SM8350_MASTER_MNOC_HF_MEM_NOC_DISP); - DEFINE_QNODE(qns_mem_noc_sf_disp, SM8350_SLAVE_MNOC_SF_MEM_NOC_DISP, 2, 32, SM8350_MASTER_MNOC_SF_MEM_NOC_DISP); - --DEFINE_QBCM(bcm_acv, "ACV", false, &ebi); --DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); --DEFINE_QBCM(bcm_cn0, "CN0", true, &qnm_gemnoc_cnoc, &qnm_gemnoc_pcie); --DEFINE_QBCM(bcm_cn1, "CN1", false, &xm_qdss_dap, &qhs_ahb2phy0, &qhs_ahb2phy1, &qhs_aoss, &qhs_apss, &qhs_camera_cfg, &qhs_clk_ctl, &qhs_compute_cfg, &qhs_cpr_cx, &qhs_cpr_mmcx, &qhs_cpr_mx, &qhs_crypto0_cfg, &qhs_cx_rdpm, &qhs_dcc_cfg, &qhs_display_cfg, &qhs_gpuss_cfg, &qhs_hwkm, &qhs_imem_cfg, &qhs_ipa, &qhs_ipc_router, &qhs_mss_cfg, &qhs_mx_rdpm, &qhs_pcie0_cfg, &qhs_pcie1_cfg, &qhs_pimem_cfg, &qhs_pka_wrapper_cfg, &qhs_pmu_wrapper_cfg, &qhs_qdss_cfg, &qhs_qup0, &qhs_qup1, &qhs_qup2, &qhs_security, &qhs_spss_cfg, &qhs_tcsr, &qhs_tlmm, &qhs_ufs_card_cfg, &qhs_ufs_mem_cfg, &qhs_usb3_0, &qhs_usb3_1, &qhs_venus_cfg, &qhs_vsense_ctrl_cfg, &qns_a1_noc_cfg, &qns_a2_noc_cfg, &qns_ddrss_cfg, &qns_mnoc_cfg, &qns_snoc_cfg, &srvc_cnoc); --DEFINE_QBCM(bcm_cn2, "CN2", false, &qhs_lpass_cfg, &qhs_pdm, &qhs_qspi, &qhs_sdc2, &qhs_sdc4); --DEFINE_QBCM(bcm_co0, "CO0", false, &qns_nsp_gemnoc); --DEFINE_QBCM(bcm_co3, "CO3", false, &qxm_nsp); --DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); --DEFINE_QBCM(bcm_mm0, "MM0", true, &qns_mem_noc_hf); --DEFINE_QBCM(bcm_mm1, "MM1", false, &qnm_camnoc_hf, &qxm_mdp0, &qxm_mdp1); --DEFINE_QBCM(bcm_mm4, "MM4", false, &qns_mem_noc_sf); --DEFINE_QBCM(bcm_mm5, "MM5", false, &qnm_camnoc_icp, &qnm_camnoc_sf, &qnm_video0, &qnm_video1, &qnm_video_cvp, &qxm_rot); --DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); --DEFINE_QBCM(bcm_sh2, "SH2", false, &alm_gpu_tcu, &alm_sys_tcu); --DEFINE_QBCM(bcm_sh3, "SH3", false, &qnm_cmpnoc); --DEFINE_QBCM(bcm_sh4, "SH4", false, &chm_apps); --DEFINE_QBCM(bcm_sn0, "SN0", true, &qns_gemnoc_sf); --DEFINE_QBCM(bcm_sn2, "SN2", false, &qns_gemnoc_gc); --DEFINE_QBCM(bcm_sn3, "SN3", false, &qxs_pimem); --DEFINE_QBCM(bcm_sn4, "SN4", false, &xs_qdss_stm); --DEFINE_QBCM(bcm_sn5, "SN5", false, &xm_pcie3_0); --DEFINE_QBCM(bcm_sn6, "SN6", false, &xm_pcie3_1); --DEFINE_QBCM(bcm_sn7, "SN7", false, &qnm_aggre1_noc); --DEFINE_QBCM(bcm_sn8, "SN8", false, &qnm_aggre2_noc); --DEFINE_QBCM(bcm_sn14, "SN14", false, &qns_pcie_mem_noc); --DEFINE_QBCM(bcm_acv_disp, "ACV", false, &ebi_disp); --DEFINE_QBCM(bcm_mc0_disp, "MC0", false, &ebi_disp); --DEFINE_QBCM(bcm_mm0_disp, "MM0", false, &qns_mem_noc_hf_disp); --DEFINE_QBCM(bcm_mm1_disp, "MM1", false, &qxm_mdp0_disp, &qxm_mdp1_disp); --DEFINE_QBCM(bcm_mm4_disp, "MM4", false, &qns_mem_noc_sf_disp); --DEFINE_QBCM(bcm_mm5_disp, "MM5", false, &qxm_rot_disp); --DEFINE_QBCM(bcm_sh0_disp, "SH0", false, &qns_llcc_disp); -+static struct qcom_icc_bcm bcm_acv = { -+ .name = "ACV", -+ .enable_mask = BIT(3), -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_ce0 = { -+ .name = "CE0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_crypto }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn0 = { -+ .name = "CN0", -+ .keepalive = true, -+ .num_nodes = 2, -+ .nodes = { &qnm_gemnoc_cnoc, &qnm_gemnoc_pcie }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn1 = { -+ .name = "CN1", -+ .keepalive = false, -+ .num_nodes = 47, -+ .nodes = { &xm_qdss_dap, -+ &qhs_ahb2phy0, -+ &qhs_ahb2phy1, -+ &qhs_aoss, -+ &qhs_apss, -+ &qhs_camera_cfg, -+ &qhs_clk_ctl, -+ &qhs_compute_cfg, -+ &qhs_cpr_cx, -+ &qhs_cpr_mmcx, -+ &qhs_cpr_mx, -+ &qhs_crypto0_cfg, -+ &qhs_cx_rdpm, -+ &qhs_dcc_cfg, -+ &qhs_display_cfg, -+ &qhs_gpuss_cfg, -+ &qhs_hwkm, -+ &qhs_imem_cfg, -+ &qhs_ipa, -+ &qhs_ipc_router, -+ &qhs_mss_cfg, -+ &qhs_mx_rdpm, -+ &qhs_pcie0_cfg, -+ &qhs_pcie1_cfg, -+ &qhs_pimem_cfg, -+ &qhs_pka_wrapper_cfg, -+ &qhs_pmu_wrapper_cfg, -+ &qhs_qdss_cfg, -+ &qhs_qup0, -+ &qhs_qup1, -+ &qhs_qup2, -+ &qhs_security, -+ &qhs_spss_cfg, -+ &qhs_tcsr, -+ &qhs_tlmm, -+ &qhs_ufs_card_cfg, -+ &qhs_ufs_mem_cfg, -+ &qhs_usb3_0, -+ &qhs_usb3_1, -+ &qhs_venus_cfg, -+ &qhs_vsense_ctrl_cfg, -+ &qns_a1_noc_cfg, -+ &qns_a2_noc_cfg, -+ &qns_ddrss_cfg, -+ &qns_mnoc_cfg, -+ &qns_snoc_cfg, -+ &srvc_cnoc -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_cn2 = { -+ .name = "CN2", -+ .keepalive = false, -+ .num_nodes = 5, -+ .nodes = { &qhs_lpass_cfg, &qhs_pdm, &qhs_qspi, &qhs_sdc2, &qhs_sdc4 }, -+}; -+ -+static struct qcom_icc_bcm bcm_co0 = { -+ .name = "CO0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_nsp_gemnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_co3 = { -+ .name = "CO3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_nsp }, -+}; -+ -+static struct qcom_icc_bcm bcm_mc0 = { -+ .name = "MC0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &ebi }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm0 = { -+ .name = "MM0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_hf }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm1 = { -+ .name = "MM1", -+ .keepalive = false, -+ .num_nodes = 3, -+ .nodes = { &qnm_camnoc_hf, &qxm_mdp0, &qxm_mdp1 }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm4 = { -+ .name = "MM4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm5 = { -+ .name = "MM5", -+ .keepalive = false, -+ .num_nodes = 6, -+ .nodes = { &qnm_camnoc_icp, -+ &qnm_camnoc_sf, -+ &qnm_video0, -+ &qnm_video1, -+ &qnm_video_cvp, -+ &qxm_rot -+ }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh0 = { -+ .name = "SH0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_llcc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh2 = { -+ .name = "SH2", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &alm_gpu_tcu, &alm_sys_tcu }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh3 = { -+ .name = "SH3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_cmpnoc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh4 = { -+ .name = "SH4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &chm_apps }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn0 = { -+ .name = "SN0", -+ .keepalive = true, -+ .num_nodes = 1, -+ .nodes = { &qns_gemnoc_sf }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn2 = { -+ .name = "SN2", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_gemnoc_gc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn3 = { -+ .name = "SN3", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxs_pimem }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn4 = { -+ .name = "SN4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &xs_qdss_stm }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn5 = { -+ .name = "SN5", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &xm_pcie3_0 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn6 = { -+ .name = "SN6", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &xm_pcie3_1 }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn7 = { -+ .name = "SN7", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_aggre1_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn8 = { -+ .name = "SN8", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qnm_aggre2_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_sn14 = { -+ .name = "SN14", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_pcie_mem_noc }, -+}; -+ -+static struct qcom_icc_bcm bcm_acv_disp = { -+ .name = "ACV", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &ebi_disp }, -+}; -+ -+static struct qcom_icc_bcm bcm_mc0_disp = { -+ .name = "MC0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &ebi_disp }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm0_disp = { -+ .name = "MM0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_hf_disp }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm1_disp = { -+ .name = "MM1", -+ .keepalive = false, -+ .num_nodes = 2, -+ .nodes = { &qxm_mdp0_disp, &qxm_mdp1_disp }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm4_disp = { -+ .name = "MM4", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_mem_noc_sf_disp }, -+}; -+ -+static struct qcom_icc_bcm bcm_mm5_disp = { -+ .name = "MM5", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qxm_rot_disp }, -+}; -+ -+static struct qcom_icc_bcm bcm_sh0_disp = { -+ .name = "SH0", -+ .keepalive = false, -+ .num_nodes = 1, -+ .nodes = { &qns_llcc_disp }, -+}; - - static struct qcom_icc_bcm * const aggre1_noc_bcms[] = { - }; -diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c -index cc892ecd52408..6d3e33e8b5f91 100644 ---- a/drivers/leds/leds-pwm.c -+++ b/drivers/leds/leds-pwm.c -@@ -53,7 +53,7 @@ static int led_pwm_set(struct led_classdev *led_cdev, - duty = led_dat->pwmstate.period - duty; - - led_dat->pwmstate.duty_cycle = duty; -- led_dat->pwmstate.enabled = duty > 0; -+ led_dat->pwmstate.enabled = true; - return pwm_apply_state(led_dat->pwm, &led_dat->pwmstate); - } - -diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c -index c7c9851c894a9..179eb243da2f6 100644 ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -2,7 +2,7 @@ - /* - * CZ.NIC's Turris Omnia LEDs driver - * -- * 2020 by Marek Behún -+ * 2020, 2023 by Marek Behún - */ - - #include -@@ -41,6 +41,37 @@ struct omnia_leds { - struct omnia_led leds[]; - }; - -+static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val) -+{ -+ u8 buf[2] = { cmd, val }; -+ -+ return i2c_master_send(client, buf, sizeof(buf)); -+} -+ -+static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd) -+{ -+ struct i2c_msg msgs[2]; -+ u8 reply; -+ int ret; -+ -+ msgs[0].addr = client->addr; -+ msgs[0].flags = 0; -+ msgs[0].len = 1; -+ msgs[0].buf = &cmd; -+ msgs[1].addr = client->addr; -+ msgs[1].flags = I2C_M_RD; -+ msgs[1].len = 1; -+ msgs[1].buf = &reply; -+ -+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); -+ if (likely(ret == ARRAY_SIZE(msgs))) -+ return reply; -+ else if (ret < 0) -+ return ret; -+ else -+ return -EIO; -+} -+ - static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, - enum led_brightness brightness) - { -@@ -64,7 +95,7 @@ static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, - if (buf[2] || buf[3] || buf[4]) - state |= CMD_LED_STATE_ON; - -- ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_STATE, state); -+ ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state); - if (ret >= 0 && (state & CMD_LED_STATE_ON)) - ret = i2c_master_send(leds->client, buf, 5); - -@@ -114,9 +145,9 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, - cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; - - /* put the LED into software mode */ -- ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE, -- CMD_LED_MODE_LED(led->reg) | -- CMD_LED_MODE_USER); -+ ret = omnia_cmd_write_u8(client, CMD_LED_MODE, -+ CMD_LED_MODE_LED(led->reg) | -+ CMD_LED_MODE_USER); - if (ret < 0) { - dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np, - ret); -@@ -124,8 +155,8 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, - } - - /* disable the LED */ -- ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE, -- CMD_LED_STATE_LED(led->reg)); -+ ret = omnia_cmd_write_u8(client, CMD_LED_STATE, -+ CMD_LED_STATE_LED(led->reg)); - if (ret < 0) { - dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret); - return ret; -@@ -156,12 +187,9 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *a, - char *buf) - { - struct i2c_client *client = to_i2c_client(dev); -- struct omnia_leds *leds = i2c_get_clientdata(client); - int ret; - -- mutex_lock(&leds->lock); -- ret = i2c_smbus_read_byte_data(client, CMD_LED_GET_BRIGHTNESS); -- mutex_unlock(&leds->lock); -+ ret = omnia_cmd_read_u8(client, CMD_LED_GET_BRIGHTNESS); - - if (ret < 0) - return ret; -@@ -173,7 +201,6 @@ static ssize_t brightness_store(struct device *dev, struct device_attribute *a, - const char *buf, size_t count) - { - struct i2c_client *client = to_i2c_client(dev); -- struct omnia_leds *leds = i2c_get_clientdata(client); - unsigned long brightness; - int ret; - -@@ -183,15 +210,9 @@ static ssize_t brightness_store(struct device *dev, struct device_attribute *a, - if (brightness > 100) - return -EINVAL; - -- mutex_lock(&leds->lock); -- ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS, -- (u8)brightness); -- mutex_unlock(&leds->lock); -- -- if (ret < 0) -- return ret; -+ ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness); - -- return count; -+ return ret < 0 ? ret : count; - } - static DEVICE_ATTR_RW(brightness); - -@@ -247,8 +268,8 @@ static void omnia_leds_remove(struct i2c_client *client) - u8 buf[5]; - - /* put all LEDs into default (HW triggered) mode */ -- i2c_smbus_write_byte_data(client, CMD_LED_MODE, -- CMD_LED_MODE_LED(OMNIA_BOARD_LEDS)); -+ omnia_cmd_write_u8(client, CMD_LED_MODE, -+ CMD_LED_MODE_LED(OMNIA_BOARD_LEDS)); - - /* set all LEDs color to [255, 255, 255] */ - buf[0] = CMD_LED_COLOR; -diff --git a/drivers/leds/trigger/ledtrig-cpu.c b/drivers/leds/trigger/ledtrig-cpu.c -index 8af4f9bb9cde8..05848a2fecff6 100644 ---- a/drivers/leds/trigger/ledtrig-cpu.c -+++ b/drivers/leds/trigger/ledtrig-cpu.c -@@ -130,7 +130,7 @@ static int ledtrig_prepare_down_cpu(unsigned int cpu) - - static int __init ledtrig_cpu_init(void) - { -- int cpu; -+ unsigned int cpu; - int ret; - - /* Supports up to 9999 cpu cores */ -@@ -152,7 +152,7 @@ static int __init ledtrig_cpu_init(void) - if (cpu >= 8) - continue; - -- snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); -+ snprintf(trig->name, MAX_NAME_LEN, "cpu%u", cpu); - - led_trigger_register_simple(trig->name, &trig->_trig); - } -diff --git a/drivers/media/cec/platform/Makefile b/drivers/media/cec/platform/Makefile -index 26d2bc7783944..a51e98ab4958d 100644 ---- a/drivers/media/cec/platform/Makefile -+++ b/drivers/media/cec/platform/Makefile -@@ -6,7 +6,7 @@ - # Please keep it in alphabetic order - obj-$(CONFIG_CEC_CROS_EC) += cros-ec/ - obj-$(CONFIG_CEC_GPIO) += cec-gpio/ --obj-$(CONFIG_CEC_MESON_AO) += meson/ -+obj-y += meson/ - obj-$(CONFIG_CEC_SAMSUNG_S5P) += s5p/ - obj-$(CONFIG_CEC_SECO) += seco/ - obj-$(CONFIG_CEC_STI) += sti/ -diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c -index 892cd97b7cab7..e8c28902d97e9 100644 ---- a/drivers/media/i2c/max9286.c -+++ b/drivers/media/i2c/max9286.c -@@ -1234,7 +1234,6 @@ static int max9286_parse_dt(struct max9286_priv *priv) - - i2c_mux_mask |= BIT(id); - } -- of_node_put(node); - of_node_put(i2c_mux); - - /* Parse the endpoints */ -@@ -1298,7 +1297,6 @@ static int max9286_parse_dt(struct max9286_priv *priv) - priv->source_mask |= BIT(ep.port); - priv->nsources++; - } -- of_node_put(node); - - /* - * Parse the initial value of the reverse channel amplitude from -diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c -index 2ee832426736d..e0019668a8f86 100644 ---- a/drivers/media/i2c/ov5640.c -+++ b/drivers/media/i2c/ov5640.c -@@ -2840,12 +2840,22 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd, - return 0; - } - -+static void __v4l2_ctrl_vblank_update(struct ov5640_dev *sensor, u32 vblank) -+{ -+ const struct ov5640_mode_info *mode = sensor->current_mode; -+ -+ __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV5640_MIN_VBLANK, -+ OV5640_MAX_VTS - mode->height, 1, vblank); -+ -+ __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, vblank); -+} -+ - static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) - { - const struct ov5640_mode_info *mode = sensor->current_mode; - enum ov5640_pixel_rate_id pixel_rate_id = mode->pixel_rate; - struct v4l2_mbus_framefmt *fmt = &sensor->fmt; -- const struct ov5640_timings *timings; -+ const struct ov5640_timings *timings = ov5640_timings(sensor, mode); - s32 exposure_val, exposure_max; - unsigned int hblank; - unsigned int i = 0; -@@ -2864,6 +2874,8 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) - __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, - ov5640_calc_pixel_rate(sensor)); - -+ __v4l2_ctrl_vblank_update(sensor, timings->vblank_def); -+ - return 0; - } - -@@ -2906,28 +2918,12 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) - __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, pixel_rate); - __v4l2_ctrl_s_ctrl(sensor->ctrls.link_freq, i); - -- timings = ov5640_timings(sensor, mode); - hblank = timings->htot - mode->width; - __v4l2_ctrl_modify_range(sensor->ctrls.hblank, - hblank, hblank, 1, hblank); - - vblank = timings->vblank_def; -- -- if (sensor->current_fr != mode->def_fps) { -- /* -- * Compute the vertical blanking according to the framerate -- * configured with s_frame_interval. -- */ -- int fie_num = sensor->frame_interval.numerator; -- int fie_denom = sensor->frame_interval.denominator; -- -- vblank = ((fie_num * pixel_rate / fie_denom) / timings->htot) - -- mode->height; -- } -- -- __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV5640_MIN_VBLANK, -- OV5640_MAX_VTS - mode->height, 1, vblank); -- __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, vblank); -+ __v4l2_ctrl_vblank_update(sensor, vblank); - - exposure_max = timings->crop.height + vblank - 4; - exposure_val = clamp_t(s32, sensor->ctrls.exposure->val, -@@ -3913,7 +3909,7 @@ static int ov5640_probe(struct i2c_client *client) - ret = ov5640_sensor_resume(dev); - if (ret) { - dev_err(dev, "failed to power on\n"); -- goto entity_cleanup; -+ goto free_ctrls; - } - - pm_runtime_set_active(dev); -@@ -3937,8 +3933,9 @@ static int ov5640_probe(struct i2c_client *client) - err_pm_runtime: - pm_runtime_put_noidle(dev); - pm_runtime_disable(dev); -- v4l2_ctrl_handler_free(&sensor->ctrls.handler); - ov5640_sensor_suspend(dev); -+free_ctrls: -+ v4l2_ctrl_handler_free(&sensor->ctrls.handler); - entity_cleanup: - media_entity_cleanup(&sensor->sd.entity); - mutex_destroy(&sensor->lock); -diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c -index d40b537f4e98b..24ba5729969dc 100644 ---- a/drivers/media/pci/bt8xx/bttv-driver.c -+++ b/drivers/media/pci/bt8xx/bttv-driver.c -@@ -4248,6 +4248,7 @@ static void bttv_remove(struct pci_dev *pci_dev) - - /* free resources */ - free_irq(btv->c.pci->irq,btv); -+ del_timer_sync(&btv->timeout); - iounmap(btv->bt848_mmio); - release_mem_region(pci_resource_start(btv->c.pci,0), - pci_resource_len(btv->c.pci,0)); -diff --git a/drivers/media/platform/amphion/vpu_defs.h b/drivers/media/platform/amphion/vpu_defs.h -index 667637eedb5d4..7320852668d64 100644 ---- a/drivers/media/platform/amphion/vpu_defs.h -+++ b/drivers/media/platform/amphion/vpu_defs.h -@@ -71,6 +71,7 @@ enum { - VPU_MSG_ID_TIMESTAMP_INFO, - VPU_MSG_ID_FIRMWARE_XCPT, - VPU_MSG_ID_PIC_SKIPPED, -+ VPU_MSG_ID_DBG_MSG, - }; - - enum VPU_ENC_MEMORY_RESOURSE { -diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c -index 2e78666322f02..66fdb0baea746 100644 ---- a/drivers/media/platform/amphion/vpu_helpers.c -+++ b/drivers/media/platform/amphion/vpu_helpers.c -@@ -454,6 +454,7 @@ const char *vpu_id_name(u32 id) - case VPU_MSG_ID_UNSUPPORTED: return "unsupported"; - case VPU_MSG_ID_FIRMWARE_XCPT: return "exception"; - case VPU_MSG_ID_PIC_SKIPPED: return "skipped"; -+ case VPU_MSG_ID_DBG_MSG: return "debug msg"; - } - return ""; - } -diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c -index c2f4fb12c3b64..6b37453eef76c 100644 ---- a/drivers/media/platform/amphion/vpu_malone.c -+++ b/drivers/media/platform/amphion/vpu_malone.c -@@ -726,6 +726,7 @@ static struct vpu_pair malone_msgs[] = { - {VPU_MSG_ID_UNSUPPORTED, VID_API_EVENT_UNSUPPORTED_STREAM}, - {VPU_MSG_ID_FIRMWARE_XCPT, VID_API_EVENT_FIRMWARE_XCPT}, - {VPU_MSG_ID_PIC_SKIPPED, VID_API_EVENT_PIC_SKIPPED}, -+ {VPU_MSG_ID_DBG_MSG, VID_API_EVENT_DBG_MSG_DEC}, - }; - - static void vpu_malone_pack_fs_alloc(struct vpu_rpc_event *pkt, -diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c -index d0ead051f7d18..b74a407a19f22 100644 ---- a/drivers/media/platform/amphion/vpu_msgs.c -+++ b/drivers/media/platform/amphion/vpu_msgs.c -@@ -23,6 +23,7 @@ - struct vpu_msg_handler { - u32 id; - void (*done)(struct vpu_inst *inst, struct vpu_rpc_event *pkt); -+ u32 is_str; - }; - - static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) -@@ -154,7 +155,7 @@ static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event - { - char *str = (char *)pkt->data; - -- if (strlen(str)) -+ if (*str) - dev_err(inst->dev, "instance %d firmware error : %s\n", inst->id, str); - else - dev_err(inst->dev, "instance %d is unsupported stream\n", inst->id); -@@ -180,6 +181,21 @@ static void vpu_session_handle_pic_skipped(struct vpu_inst *inst, struct vpu_rpc - vpu_inst_unlock(inst); - } - -+static void vpu_session_handle_dbg_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt) -+{ -+ char *str = (char *)pkt->data; -+ -+ if (*str) -+ dev_info(inst->dev, "instance %d firmware dbg msg : %s\n", inst->id, str); -+} -+ -+static void vpu_terminate_string_msg(struct vpu_rpc_event *pkt) -+{ -+ if (pkt->hdr.num == ARRAY_SIZE(pkt->data)) -+ pkt->hdr.num--; -+ pkt->data[pkt->hdr.num] = 0; -+} -+ - static struct vpu_msg_handler handlers[] = { - {VPU_MSG_ID_START_DONE, vpu_session_handle_start_done}, - {VPU_MSG_ID_STOP_DONE, vpu_session_handle_stop_done}, -@@ -193,9 +209,10 @@ static struct vpu_msg_handler handlers[] = { - {VPU_MSG_ID_PIC_DECODED, vpu_session_handle_pic_decoded}, - {VPU_MSG_ID_DEC_DONE, vpu_session_handle_pic_done}, - {VPU_MSG_ID_PIC_EOS, vpu_session_handle_eos}, -- {VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error}, -- {VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt}, -+ {VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error, true}, -+ {VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt, true}, - {VPU_MSG_ID_PIC_SKIPPED, vpu_session_handle_pic_skipped}, -+ {VPU_MSG_ID_DBG_MSG, vpu_session_handle_dbg_msg, true}, - }; - - static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *msg) -@@ -219,8 +236,12 @@ static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *m - } - } - -- if (handler && handler->done) -- handler->done(inst, msg); -+ if (handler) { -+ if (handler->is_str) -+ vpu_terminate_string_msg(msg); -+ if (handler->done) -+ handler->done(inst, msg); -+ } - - vpu_response_cmd(inst, msg_id, 1); - -diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c -index cc3ebb0d96f66..2a23da6a0b8ee 100644 ---- a/drivers/media/platform/cadence/cdns-csi2rx.c -+++ b/drivers/media/platform/cadence/cdns-csi2rx.c -@@ -404,8 +404,10 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) - asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh, - struct v4l2_async_subdev); - of_node_put(ep); -- if (IS_ERR(asd)) -+ if (IS_ERR(asd)) { -+ v4l2_async_nf_cleanup(&csi2rx->notifier); - return PTR_ERR(asd); -+ } - - csi2rx->notifier.ops = &csi2rx_notifier_ops; - -@@ -467,6 +469,7 @@ static int csi2rx_probe(struct platform_device *pdev) - return 0; - - err_cleanup: -+ v4l2_async_nf_unregister(&csi2rx->notifier); - v4l2_async_nf_cleanup(&csi2rx->notifier); - err_free_priv: - kfree(csi2rx); -@@ -477,6 +480,8 @@ static int csi2rx_remove(struct platform_device *pdev) - { - struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev); - -+ v4l2_async_nf_unregister(&csi2rx->notifier); -+ v4l2_async_nf_cleanup(&csi2rx->notifier); - v4l2_async_unregister_subdev(&csi2rx->subdev); - kfree(csi2rx); - -diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c -index 1cf037bf72dda..8c271c38caf73 100644 ---- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c -+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c -@@ -98,6 +98,7 @@ void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base) - u32 img_stride; - u32 mem_stride; - u32 i, enc_quality; -+ u32 nr_enc_quality = ARRAY_SIZE(mtk_jpeg_enc_quality); - - value = width << 16 | height; - writel(value, base + JPEG_ENC_IMG_SIZE); -@@ -128,8 +129,8 @@ void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx, void __iomem *base) - writel(img_stride, base + JPEG_ENC_IMG_STRIDE); - writel(mem_stride, base + JPEG_ENC_STRIDE); - -- enc_quality = mtk_jpeg_enc_quality[0].hardware_value; -- for (i = 0; i < ARRAY_SIZE(mtk_jpeg_enc_quality); i++) { -+ enc_quality = mtk_jpeg_enc_quality[nr_enc_quality - 1].hardware_value; -+ for (i = 0; i < nr_enc_quality; i++) { - if (ctx->enc_quality <= mtk_jpeg_enc_quality[i].quality_param) { - enc_quality = mtk_jpeg_enc_quality[i].hardware_value; - break; -diff --git a/drivers/media/platform/samsung/s3c-camif/camif-capture.c b/drivers/media/platform/samsung/s3c-camif/camif-capture.c -index db106ebdf870a..bca3cae4dd8bb 100644 ---- a/drivers/media/platform/samsung/s3c-camif/camif-capture.c -+++ b/drivers/media/platform/samsung/s3c-camif/camif-capture.c -@@ -1132,12 +1132,12 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx) - - ret = vb2_queue_init(q); - if (ret) -- goto err_vd_rel; -+ return ret; - - vp->pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_pads_init(&vfd->entity, 1, &vp->pad); - if (ret) -- goto err_vd_rel; -+ return ret; - - video_set_drvdata(vfd, vp); - -@@ -1170,8 +1170,6 @@ err_ctrlh_free: - v4l2_ctrl_handler_free(&vp->ctrl_handler); - err_me_cleanup: - media_entity_cleanup(&vfd->entity); --err_vd_rel: -- video_device_release(vfd); - return ret; - } - -diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c -index 8cb4a68c9119e..08840ba313e7a 100644 ---- a/drivers/media/platform/verisilicon/hantro_drv.c -+++ b/drivers/media/platform/verisilicon/hantro_drv.c -@@ -125,7 +125,8 @@ void hantro_watchdog(struct work_struct *work) - ctx = v4l2_m2m_get_curr_priv(vpu->m2m_dev); - if (ctx) { - vpu_err("frame processing timed out!\n"); -- ctx->codec_ops->reset(ctx); -+ if (ctx->codec_ops->reset) -+ ctx->codec_ops->reset(ctx); - hantro_job_finish(vpu, ctx, VB2_BUF_STATE_ERROR); - } - } -diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c -index 09d8cf9426895..708095cf09fe2 100644 ---- a/drivers/media/platform/verisilicon/hantro_postproc.c -+++ b/drivers/media/platform/verisilicon/hantro_postproc.c -@@ -103,7 +103,7 @@ static void hantro_postproc_g1_enable(struct hantro_ctx *ctx) - - static int down_scale_factor(struct hantro_ctx *ctx) - { -- if (ctx->src_fmt.width == ctx->dst_fmt.width) -+ if (ctx->src_fmt.width <= ctx->dst_fmt.width) - return 0; - - return DIV_ROUND_CLOSEST(ctx->src_fmt.width, ctx->dst_fmt.width); -diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c -index b51e6a3b8cbeb..f99878eff7ace 100644 ---- a/drivers/media/test-drivers/vidtv/vidtv_mux.c -+++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c -@@ -504,13 +504,16 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, - m->priv = args->priv; - m->network_id = args->network_id; - m->network_name = kstrdup(args->network_name, GFP_KERNEL); -+ if (!m->network_name) -+ goto free_mux_buf; -+ - m->timing.current_jiffies = get_jiffies_64(); - - if (args->channels) - m->channels = args->channels; - else - if (vidtv_channels_init(m) < 0) -- goto free_mux_buf; -+ goto free_mux_network_name; - - /* will alloc data for pmt_sections after initializing pat */ - if (vidtv_channel_si_init(m) < 0) -@@ -527,6 +530,8 @@ free_channel_si: - vidtv_channel_si_destroy(m); - free_channels: - vidtv_channels_destroy(m); -+free_mux_network_name: -+ kfree(m->network_name); - free_mux_buf: - vfree(m->mux_buf); - free_mux: -diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c -index a5875380ef407..c45828bc5b278 100644 ---- a/drivers/media/test-drivers/vidtv/vidtv_psi.c -+++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c -@@ -301,16 +301,29 @@ struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc - - desc->service_name_len = service_name_len; - -- if (service_name && service_name_len) -+ if (service_name && service_name_len) { - desc->service_name = kstrdup(service_name, GFP_KERNEL); -+ if (!desc->service_name) -+ goto free_desc; -+ } - - desc->provider_name_len = provider_name_len; - -- if (provider_name && provider_name_len) -+ if (provider_name && provider_name_len) { - desc->provider_name = kstrdup(provider_name, GFP_KERNEL); -+ if (!desc->provider_name) -+ goto free_desc_service_name; -+ } - - vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); - return desc; -+ -+free_desc_service_name: -+ if (service_name && service_name_len) -+ kfree(desc->service_name); -+free_desc: -+ kfree(desc); -+ return NULL; - } - - struct vidtv_psi_desc_registration -@@ -355,8 +368,13 @@ struct vidtv_psi_desc_network_name - - desc->length = network_name_len; - -- if (network_name && network_name_len) -+ if (network_name && network_name_len) { - desc->network_name = kstrdup(network_name, GFP_KERNEL); -+ if (!desc->network_name) { -+ kfree(desc); -+ return NULL; -+ } -+ } - - vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); - return desc; -@@ -442,15 +460,32 @@ struct vidtv_psi_desc_short_event - iso_language_code = "eng"; - - desc->iso_language_code = kstrdup(iso_language_code, GFP_KERNEL); -+ if (!desc->iso_language_code) -+ goto free_desc; - -- if (event_name && event_name_len) -+ if (event_name && event_name_len) { - desc->event_name = kstrdup(event_name, GFP_KERNEL); -+ if (!desc->event_name) -+ goto free_desc_language_code; -+ } - -- if (text && text_len) -+ if (text && text_len) { - desc->text = kstrdup(text, GFP_KERNEL); -+ if (!desc->text) -+ goto free_desc_event_name; -+ } - - vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc); - return desc; -+ -+free_desc_event_name: -+ if (event_name && event_name_len) -+ kfree(desc->event_name); -+free_desc_language_code: -+ kfree(desc->iso_language_code); -+free_desc: -+ kfree(desc); -+ return NULL; - } - - struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc) -diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c -index cd6f5374414d4..5f9dec71ff6e0 100644 ---- a/drivers/media/usb/dvb-usb-v2/af9035.c -+++ b/drivers/media/usb/dvb-usb-v2/af9035.c -@@ -323,8 +323,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, - ret = -EOPNOTSUPP; - } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || - (msg[0].addr == state->af9033_i2c_addr[1])) { -- if (msg[0].len < 3 || msg[1].len < 1) -- return -EOPNOTSUPP; -+ if (msg[0].len < 3 || msg[1].len < 1) { -+ ret = -EOPNOTSUPP; -+ goto unlock; -+ } - /* demod access via firmware interface */ - reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | - msg[0].buf[2]; -@@ -384,8 +386,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, - ret = -EOPNOTSUPP; - } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || - (msg[0].addr == state->af9033_i2c_addr[1])) { -- if (msg[0].len < 3) -- return -EOPNOTSUPP; -+ if (msg[0].len < 3) { -+ ret = -EOPNOTSUPP; -+ goto unlock; -+ } - /* demod access via firmware interface */ - reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | - msg[0].buf[2]; -@@ -460,6 +464,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap, - ret = -EOPNOTSUPP; - } - -+unlock: - mutex_unlock(&d->i2c_mutex); - - if (ret < 0) -diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c -index 5c4af05ed0440..3f83a77ce69e7 100644 ---- a/drivers/mfd/arizona-spi.c -+++ b/drivers/mfd/arizona-spi.c -@@ -159,6 +159,9 @@ static int arizona_spi_acpi_probe(struct arizona *arizona) - arizona->pdata.micd_ranges = arizona_micd_aosp_ranges; - arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges); - -+ /* Use left headphone speaker for HP vs line-out detection */ -+ arizona->pdata.hpdet_channel = ARIZONA_ACCDET_MODE_HPL; -+ - return 0; - } - -diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c -index c3149729cec2e..6cd0b0c752d6e 100644 ---- a/drivers/mfd/dln2.c -+++ b/drivers/mfd/dln2.c -@@ -827,7 +827,6 @@ out_stop_rx: - dln2_stop_rx_urbs(dln2); - - out_free: -- usb_put_dev(dln2->usb_dev); - dln2_free(dln2); - - return ret; -diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c -index 16d1861e96823..97909e3e2c303 100644 ---- a/drivers/mfd/mfd-core.c -+++ b/drivers/mfd/mfd-core.c -@@ -176,6 +176,7 @@ static int mfd_add_device(struct device *parent, int id, - struct platform_device *pdev; - struct device_node *np = NULL; - struct mfd_of_node_entry *of_entry, *tmp; -+ bool disabled = false; - int ret = -ENOMEM; - int platform_id; - int r; -@@ -213,11 +214,10 @@ static int mfd_add_device(struct device *parent, int id, - if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) { - for_each_child_of_node(parent->of_node, np) { - if (of_device_is_compatible(np, cell->of_compatible)) { -- /* Ignore 'disabled' devices error free */ -+ /* Skip 'disabled' devices */ - if (!of_device_is_available(np)) { -- of_node_put(np); -- ret = 0; -- goto fail_alias; -+ disabled = true; -+ continue; - } - - ret = mfd_match_of_node_to_dev(pdev, np, cell); -@@ -227,10 +227,17 @@ static int mfd_add_device(struct device *parent, int id, - if (ret) - goto fail_alias; - -- break; -+ goto match; - } - } - -+ if (disabled) { -+ /* Ignore 'disabled' devices error free */ -+ ret = 0; -+ goto fail_alias; -+ } -+ -+match: - if (!pdev->dev.of_node) - pr_warn("%s: Failed to locate of_node [id: %d]\n", - cell->name, platform_id); -diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c -index 7f6976a9f508b..48e0f8377e659 100644 ---- a/drivers/misc/ti-st/st_core.c -+++ b/drivers/misc/ti-st/st_core.c -@@ -15,6 +15,7 @@ - #include - - #include -+#include - - extern void st_kim_recv(void *, const unsigned char *, long); - void st_int_recv(void *, const unsigned char *, long); -@@ -435,7 +436,7 @@ static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) - case ST_LL_AWAKE_TO_ASLEEP: - pr_err("ST LL is illegal state(%ld)," - "purging received skb.", st_ll_getstate(st_gdata)); -- kfree_skb(skb); -+ dev_kfree_skb_irq(skb); - break; - case ST_LL_ASLEEP: - skb_queue_tail(&st_gdata->tx_waitq, skb); -@@ -444,7 +445,7 @@ static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) - default: - pr_err("ST LL is illegal state(%ld)," - "purging received skb.", st_ll_getstate(st_gdata)); -- kfree_skb(skb); -+ dev_kfree_skb_irq(skb); - break; - } - -@@ -498,7 +499,7 @@ void st_tx_wakeup(struct st_data_s *st_data) - spin_unlock_irqrestore(&st_data->lock, flags); - break; - } -- kfree_skb(skb); -+ dev_kfree_skb_irq(skb); - spin_unlock_irqrestore(&st_data->lock, flags); - } - /* if wake-up is set in another context- restart sending */ -diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -index 4a4bab9aa7263..89cd48fcec79f 100644 ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -104,7 +104,7 @@ static int mmc_decode_cid(struct mmc_card *card) - case 3: /* MMC v3.1 - v3.3 */ - case 4: /* MMC v4 */ - card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); -- card->cid.oemid = UNSTUFF_BITS(resp, 104, 8); -+ card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); - card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); - card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); - card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); -diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c -index c1956b1e9faf7..f685479eda1be 100644 ---- a/drivers/net/can/dev/dev.c -+++ b/drivers/net/can/dev/dev.c -@@ -132,7 +132,8 @@ static void can_restart(struct net_device *dev) - struct can_frame *cf; - int err; - -- BUG_ON(netif_carrier_ok(dev)); -+ if (netif_carrier_ok(dev)) -+ netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n"); - - /* No synchronization needed because the device is bus-off and - * no messages can come in or go out. -@@ -153,11 +154,12 @@ restart: - priv->can_stats.restarts++; - - /* Now restart the device */ -- err = priv->do_set_mode(dev, CAN_MODE_START); -- - netif_carrier_on(dev); -- if (err) -+ err = priv->do_set_mode(dev, CAN_MODE_START); -+ if (err) { - netdev_err(dev, "Error %d during restart", err); -+ netif_carrier_off(dev); -+ } - } - - static void can_restart_work(struct work_struct *work) -diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c -index f6d05b3ef59ab..3ebd4f779b9bd 100644 ---- a/drivers/net/can/dev/skb.c -+++ b/drivers/net/can/dev/skb.c -@@ -49,7 +49,11 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, - { - struct can_priv *priv = netdev_priv(dev); - -- BUG_ON(idx >= priv->echo_skb_max); -+ if (idx >= priv->echo_skb_max) { -+ netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n", -+ __func__, idx, priv->echo_skb_max); -+ return -EINVAL; -+ } - - /* check flag whether this packet has to be looped back */ - if (!(dev->flags & IFF_ECHO) || -diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c -index 9609041016776..85570e40c8e9b 100644 ---- a/drivers/net/ethernet/broadcom/tg3.c -+++ b/drivers/net/ethernet/broadcom/tg3.c -@@ -18086,7 +18086,8 @@ static void tg3_shutdown(struct pci_dev *pdev) - if (netif_running(dev)) - dev_close(dev); - -- tg3_power_down(tp); -+ if (system_state == SYSTEM_POWER_OFF) -+ tg3_power_down(tp); - - rtnl_unlock(); - -diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c -index 7750702900fa6..6f6525983130e 100644 ---- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c -+++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c -@@ -2259,7 +2259,7 @@ static void chtls_rx_ack(struct sock *sk, struct sk_buff *skb) - - if (tp->snd_una != snd_una) { - tp->snd_una = snd_una; -- tp->rcv_tstamp = tcp_time_stamp(tp); -+ tp->rcv_tstamp = tcp_jiffies32; - if (tp->snd_una == tp->snd_nxt && - !csk_flag_nochk(csk, CSK_TX_FAILOVER)) - csk_reset_flag(csk, CSK_TX_WAIT_IDLE); -diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c -index 2e5e0a8872704..d3f6ad586ba1b 100644 ---- a/drivers/net/ethernet/google/gve/gve_main.c -+++ b/drivers/net/ethernet/google/gve/gve_main.c -@@ -139,7 +139,7 @@ static int gve_alloc_stats_report(struct gve_priv *priv) - rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) * - priv->rx_cfg.num_queues; - priv->stats_report_len = struct_size(priv->stats_report, stats, -- tx_stats_num + rx_stats_num); -+ size_add(tx_stats_num, rx_stats_num)); - priv->stats_report = - dma_alloc_coherent(&priv->pdev->dev, priv->stats_report_len, - &priv->stats_report_bus, GFP_KERNEL); -diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c -index 08ccf0024ce1a..68ee2c59692d1 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -16283,11 +16283,15 @@ static void i40e_remove(struct pci_dev *pdev) - i40e_switch_branch_release(pf->veb[i]); - } - -- /* Now we can shutdown the PF's VSI, just before we kill -+ /* Now we can shutdown the PF's VSIs, just before we kill - * adminq and hmc. - */ -- if (pf->vsi[pf->lan_vsi]) -- i40e_vsi_release(pf->vsi[pf->lan_vsi]); -+ for (i = pf->num_alloc_vsi; i--;) -+ if (pf->vsi[i]) { -+ i40e_vsi_close(pf->vsi[i]); -+ i40e_vsi_release(pf->vsi[i]); -+ pf->vsi[i] = NULL; -+ } - - i40e_cloud_filter_exit(pf); - -diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h -index 06cfd567866c2..7389855fa307a 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf.h -+++ b/drivers/net/ethernet/intel/iavf/iavf.h -@@ -298,8 +298,6 @@ struct iavf_adapter { - #define IAVF_FLAG_CLIENT_NEEDS_OPEN BIT(10) - #define IAVF_FLAG_CLIENT_NEEDS_CLOSE BIT(11) - #define IAVF_FLAG_CLIENT_NEEDS_L2_PARAMS BIT(12) --#define IAVF_FLAG_PROMISC_ON BIT(13) --#define IAVF_FLAG_ALLMULTI_ON BIT(14) - #define IAVF_FLAG_LEGACY_RX BIT(15) - #define IAVF_FLAG_REINIT_ITR_NEEDED BIT(16) - #define IAVF_FLAG_QUEUES_DISABLED BIT(17) -@@ -325,10 +323,7 @@ struct iavf_adapter { - #define IAVF_FLAG_AQ_SET_HENA BIT_ULL(12) - #define IAVF_FLAG_AQ_SET_RSS_KEY BIT_ULL(13) - #define IAVF_FLAG_AQ_SET_RSS_LUT BIT_ULL(14) --#define IAVF_FLAG_AQ_REQUEST_PROMISC BIT_ULL(15) --#define IAVF_FLAG_AQ_RELEASE_PROMISC BIT_ULL(16) --#define IAVF_FLAG_AQ_REQUEST_ALLMULTI BIT_ULL(17) --#define IAVF_FLAG_AQ_RELEASE_ALLMULTI BIT_ULL(18) -+#define IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE BIT_ULL(15) - #define IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING BIT_ULL(19) - #define IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING BIT_ULL(20) - #define IAVF_FLAG_AQ_ENABLE_CHANNELS BIT_ULL(21) -@@ -365,6 +360,12 @@ struct iavf_adapter { - (IAVF_EXTENDED_CAP_SEND_VLAN_V2 | \ - IAVF_EXTENDED_CAP_RECV_VLAN_V2) - -+ /* Lock to prevent possible clobbering of -+ * current_netdev_promisc_flags -+ */ -+ spinlock_t current_netdev_promisc_flags_lock; -+ netdev_features_t current_netdev_promisc_flags; -+ - /* OS defined structs */ - struct net_device *netdev; - struct pci_dev *pdev; -@@ -551,7 +552,8 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter); - void iavf_del_ether_addrs(struct iavf_adapter *adapter); - void iavf_add_vlans(struct iavf_adapter *adapter); - void iavf_del_vlans(struct iavf_adapter *adapter); --void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags); -+void iavf_set_promiscuous(struct iavf_adapter *adapter); -+bool iavf_promiscuous_mode_changed(struct iavf_adapter *adapter); - void iavf_request_stats(struct iavf_adapter *adapter); - int iavf_request_reset(struct iavf_adapter *adapter); - void iavf_get_hena(struct iavf_adapter *adapter); -diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c -index 326bb5fdf5f90..4836bac2bd09d 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_main.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c -@@ -1198,6 +1198,16 @@ static int iavf_addr_unsync(struct net_device *netdev, const u8 *addr) - return 0; - } - -+/** -+ * iavf_promiscuous_mode_changed - check if promiscuous mode bits changed -+ * @adapter: device specific adapter -+ */ -+bool iavf_promiscuous_mode_changed(struct iavf_adapter *adapter) -+{ -+ return (adapter->current_netdev_promisc_flags ^ adapter->netdev->flags) & -+ (IFF_PROMISC | IFF_ALLMULTI); -+} -+ - /** - * iavf_set_rx_mode - NDO callback to set the netdev filters - * @netdev: network interface device structure -@@ -1211,19 +1221,10 @@ static void iavf_set_rx_mode(struct net_device *netdev) - __dev_mc_sync(netdev, iavf_addr_sync, iavf_addr_unsync); - spin_unlock_bh(&adapter->mac_vlan_list_lock); - -- if (netdev->flags & IFF_PROMISC && -- !(adapter->flags & IAVF_FLAG_PROMISC_ON)) -- adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_PROMISC; -- else if (!(netdev->flags & IFF_PROMISC) && -- adapter->flags & IAVF_FLAG_PROMISC_ON) -- adapter->aq_required |= IAVF_FLAG_AQ_RELEASE_PROMISC; -- -- if (netdev->flags & IFF_ALLMULTI && -- !(adapter->flags & IAVF_FLAG_ALLMULTI_ON)) -- adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_ALLMULTI; -- else if (!(netdev->flags & IFF_ALLMULTI) && -- adapter->flags & IAVF_FLAG_ALLMULTI_ON) -- adapter->aq_required |= IAVF_FLAG_AQ_RELEASE_ALLMULTI; -+ spin_lock_bh(&adapter->current_netdev_promisc_flags_lock); -+ if (iavf_promiscuous_mode_changed(adapter)) -+ adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE; -+ spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock); - } - - /** -@@ -2174,19 +2175,8 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter) - return 0; - } - -- if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_PROMISC) { -- iavf_set_promiscuous(adapter, FLAG_VF_UNICAST_PROMISC | -- FLAG_VF_MULTICAST_PROMISC); -- return 0; -- } -- -- if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_ALLMULTI) { -- iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC); -- return 0; -- } -- if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) || -- (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) { -- iavf_set_promiscuous(adapter, 0); -+ if (adapter->aq_required & IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE) { -+ iavf_set_promiscuous(adapter); - return 0; - } - -@@ -5008,6 +4998,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - spin_lock_init(&adapter->cloud_filter_list_lock); - spin_lock_init(&adapter->fdir_fltr_lock); - spin_lock_init(&adapter->adv_rss_lock); -+ spin_lock_init(&adapter->current_netdev_promisc_flags_lock); - - INIT_LIST_HEAD(&adapter->mac_filter_list); - INIT_LIST_HEAD(&adapter->vlan_filter_list); -diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c -index 2fc8e60ef6afb..5a66b05c03222 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c -@@ -948,14 +948,14 @@ void iavf_del_vlans(struct iavf_adapter *adapter) - /** - * iavf_set_promiscuous - * @adapter: adapter structure -- * @flags: bitmask to control unicast/multicast promiscuous. - * - * Request that the PF enable promiscuous mode for our VSI. - **/ --void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags) -+void iavf_set_promiscuous(struct iavf_adapter *adapter) - { -+ struct net_device *netdev = adapter->netdev; - struct virtchnl_promisc_info vpi; -- int promisc_all; -+ unsigned int flags; - - if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) { - /* bail because we already have a command pending */ -@@ -964,36 +964,57 @@ void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags) - return; - } - -- promisc_all = FLAG_VF_UNICAST_PROMISC | -- FLAG_VF_MULTICAST_PROMISC; -- if ((flags & promisc_all) == promisc_all) { -- adapter->flags |= IAVF_FLAG_PROMISC_ON; -- adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_PROMISC; -- dev_info(&adapter->pdev->dev, "Entering promiscuous mode\n"); -- } -+ /* prevent changes to promiscuous flags */ -+ spin_lock_bh(&adapter->current_netdev_promisc_flags_lock); - -- if (flags & FLAG_VF_MULTICAST_PROMISC) { -- adapter->flags |= IAVF_FLAG_ALLMULTI_ON; -- adapter->aq_required &= ~IAVF_FLAG_AQ_REQUEST_ALLMULTI; -- dev_info(&adapter->pdev->dev, "%s is entering multicast promiscuous mode\n", -- adapter->netdev->name); -+ /* sanity check to prevent duplicate AQ calls */ -+ if (!iavf_promiscuous_mode_changed(adapter)) { -+ adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE; -+ dev_dbg(&adapter->pdev->dev, "No change in promiscuous mode\n"); -+ /* allow changes to promiscuous flags */ -+ spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock); -+ return; - } - -- if (!flags) { -- if (adapter->flags & IAVF_FLAG_PROMISC_ON) { -- adapter->flags &= ~IAVF_FLAG_PROMISC_ON; -- adapter->aq_required &= ~IAVF_FLAG_AQ_RELEASE_PROMISC; -- dev_info(&adapter->pdev->dev, "Leaving promiscuous mode\n"); -- } -+ /* there are 2 bits, but only 3 states */ -+ if (!(netdev->flags & IFF_PROMISC) && -+ netdev->flags & IFF_ALLMULTI) { -+ /* State 1 - only multicast promiscuous mode enabled -+ * - !IFF_PROMISC && IFF_ALLMULTI -+ */ -+ flags = FLAG_VF_MULTICAST_PROMISC; -+ adapter->current_netdev_promisc_flags |= IFF_ALLMULTI; -+ adapter->current_netdev_promisc_flags &= ~IFF_PROMISC; -+ dev_info(&adapter->pdev->dev, "Entering multicast promiscuous mode\n"); -+ } else if (!(netdev->flags & IFF_PROMISC) && -+ !(netdev->flags & IFF_ALLMULTI)) { -+ /* State 2 - unicast/multicast promiscuous mode disabled -+ * - !IFF_PROMISC && !IFF_ALLMULTI -+ */ -+ flags = 0; -+ adapter->current_netdev_promisc_flags &= -+ ~(IFF_PROMISC | IFF_ALLMULTI); -+ dev_info(&adapter->pdev->dev, "Leaving promiscuous mode\n"); -+ } else { -+ /* State 3 - unicast/multicast promiscuous mode enabled -+ * - IFF_PROMISC && IFF_ALLMULTI -+ * - IFF_PROMISC && !IFF_ALLMULTI -+ */ -+ flags = FLAG_VF_UNICAST_PROMISC | FLAG_VF_MULTICAST_PROMISC; -+ adapter->current_netdev_promisc_flags |= IFF_PROMISC; -+ if (netdev->flags & IFF_ALLMULTI) -+ adapter->current_netdev_promisc_flags |= IFF_ALLMULTI; -+ else -+ adapter->current_netdev_promisc_flags &= ~IFF_ALLMULTI; - -- if (adapter->flags & IAVF_FLAG_ALLMULTI_ON) { -- adapter->flags &= ~IAVF_FLAG_ALLMULTI_ON; -- adapter->aq_required &= ~IAVF_FLAG_AQ_RELEASE_ALLMULTI; -- dev_info(&adapter->pdev->dev, "%s is leaving multicast promiscuous mode\n", -- adapter->netdev->name); -- } -+ dev_info(&adapter->pdev->dev, "Entering promiscuous mode\n"); - } - -+ adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_PROMISC_MODE; -+ -+ /* allow changes to promiscuous flags */ -+ spin_unlock_bh(&adapter->current_netdev_promisc_flags_lock); -+ - adapter->current_op = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE; - vpi.vsi_id = adapter->vsi_res->vsi_id; - vpi.flags = flags; -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c -index aadc352c2ffbd..5c9dc3f9262f5 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c -@@ -1222,6 +1222,11 @@ static int rvu_dbg_npa_ctx_display(struct seq_file *m, void *unused, int ctype) - - for (aura = id; aura < max_id; aura++) { - aq_req.aura_id = aura; -+ -+ /* Skip if queue is uninitialized */ -+ if (ctype == NPA_AQ_CTYPE_POOL && !test_bit(aura, pfvf->pool_bmap)) -+ continue; -+ - seq_printf(m, "======%s : %d=======\n", - (ctype == NPA_AQ_CTYPE_AURA) ? "AURA" : "POOL", - aq_req.aura_id); -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile b/drivers/net/ethernet/marvell/octeontx2/nic/Makefile -index 73fdb87986148..3d31ddf7c652e 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/Makefile -@@ -8,7 +8,7 @@ obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o otx2_ptp.o - - rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \ - otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \ -- otx2_devlink.o -+ otx2_devlink.o qos_sq.o - rvu_nicvf-y := otx2_vf.o otx2_devlink.o - - rvu_nicpf-$(CONFIG_DCB) += otx2_dcbnl.o -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -index 011355e73696e..0f896f606c3e6 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c -@@ -513,8 +513,8 @@ void otx2_config_irq_coalescing(struct otx2_nic *pfvf, int qidx) - (pfvf->hw.cq_ecount_wait - 1)); - } - --int __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, -- dma_addr_t *dma) -+static int __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, -+ dma_addr_t *dma) - { - u8 *buf; - -@@ -532,8 +532,8 @@ int __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, - return 0; - } - --static int otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, -- dma_addr_t *dma) -+int otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, -+ dma_addr_t *dma) - { - int ret; - -@@ -795,21 +795,21 @@ void otx2_txschq_stop(struct otx2_nic *pfvf) - void otx2_sqb_flush(struct otx2_nic *pfvf) - { - int qidx, sqe_tail, sqe_head; -+ struct otx2_snd_queue *sq; - u64 incr, *ptr, val; -- int timeout = 1000; - - ptr = (u64 *)otx2_get_regaddr(pfvf, NIX_LF_SQ_OP_STATUS); -- for (qidx = 0; qidx < pfvf->hw.tot_tx_queues; qidx++) { -+ for (qidx = 0; qidx < otx2_get_total_tx_queues(pfvf); qidx++) { -+ sq = &pfvf->qset.sq[qidx]; -+ if (!sq->sqb_ptrs) -+ continue; -+ - incr = (u64)qidx << 32; -- while (timeout) { -- val = otx2_atomic64_add(incr, ptr); -- sqe_head = (val >> 20) & 0x3F; -- sqe_tail = (val >> 28) & 0x3F; -- if (sqe_head == sqe_tail) -- break; -- usleep_range(1, 3); -- timeout--; -- } -+ val = otx2_atomic64_add(incr, ptr); -+ sqe_head = (val >> 20) & 0x3F; -+ sqe_tail = (val >> 28) & 0x3F; -+ if (sqe_head != sqe_tail) -+ usleep_range(50, 60); - } - } - -@@ -899,7 +899,7 @@ int otx2_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura) - return otx2_sync_mbox_msg(&pfvf->mbox); - } - --static int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura) -+int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura) - { - struct otx2_qset *qset = &pfvf->qset; - struct otx2_snd_queue *sq; -@@ -972,9 +972,17 @@ static int otx2_cq_init(struct otx2_nic *pfvf, u16 qidx) - cq->cint_idx = qidx - pfvf->hw.rx_queues; - cq->cqe_cnt = qset->sqe_cnt; - } else { -- cq->cq_type = CQ_XDP; -- cq->cint_idx = qidx - non_xdp_queues; -- cq->cqe_cnt = qset->sqe_cnt; -+ if (pfvf->hw.xdp_queues && -+ qidx < non_xdp_queues + pfvf->hw.xdp_queues) { -+ cq->cq_type = CQ_XDP; -+ cq->cint_idx = qidx - non_xdp_queues; -+ cq->cqe_cnt = qset->sqe_cnt; -+ } else { -+ cq->cq_type = CQ_QOS; -+ cq->cint_idx = qidx - non_xdp_queues - -+ pfvf->hw.xdp_queues; -+ cq->cqe_cnt = qset->sqe_cnt; -+ } - } - cq->cqe_size = pfvf->qset.xqe_size; - -@@ -1085,7 +1093,7 @@ int otx2_config_nix_queues(struct otx2_nic *pfvf) - } - - /* Initialize TX queues */ -- for (qidx = 0; qidx < pfvf->hw.tot_tx_queues; qidx++) { -+ for (qidx = 0; qidx < pfvf->hw.non_qos_queues; qidx++) { - u16 sqb_aura = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx); - - err = otx2_sq_init(pfvf, qidx, sqb_aura); -@@ -1132,7 +1140,7 @@ int otx2_config_nix(struct otx2_nic *pfvf) - - /* Set RQ/SQ/CQ counts */ - nixlf->rq_cnt = pfvf->hw.rx_queues; -- nixlf->sq_cnt = pfvf->hw.tot_tx_queues; -+ nixlf->sq_cnt = otx2_get_total_tx_queues(pfvf); - nixlf->cq_cnt = pfvf->qset.cq_cnt; - nixlf->rss_sz = MAX_RSS_INDIR_TBL_SIZE; - nixlf->rss_grps = MAX_RSS_GROUPS; -@@ -1170,7 +1178,7 @@ void otx2_sq_free_sqbs(struct otx2_nic *pfvf) - int sqb, qidx; - u64 iova, pa; - -- for (qidx = 0; qidx < hw->tot_tx_queues; qidx++) { -+ for (qidx = 0; qidx < otx2_get_total_tx_queues(pfvf); qidx++) { - sq = &qset->sq[qidx]; - if (!sq->sqb_ptrs) - continue; -@@ -1238,8 +1246,8 @@ void otx2_aura_pool_free(struct otx2_nic *pfvf) - pfvf->qset.pool = NULL; - } - --static int otx2_aura_init(struct otx2_nic *pfvf, int aura_id, -- int pool_id, int numptrs) -+int otx2_aura_init(struct otx2_nic *pfvf, int aura_id, -+ int pool_id, int numptrs) - { - struct npa_aq_enq_req *aq; - struct otx2_pool *pool; -@@ -1315,8 +1323,8 @@ static int otx2_aura_init(struct otx2_nic *pfvf, int aura_id, - return 0; - } - --static int otx2_pool_init(struct otx2_nic *pfvf, u16 pool_id, -- int stack_pages, int numptrs, int buf_size) -+int otx2_pool_init(struct otx2_nic *pfvf, u16 pool_id, -+ int stack_pages, int numptrs, int buf_size) - { - struct npa_aq_enq_req *aq; - struct otx2_pool *pool; -@@ -1386,7 +1394,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf) - stack_pages = - (num_sqbs + hw->stack_pg_ptrs - 1) / hw->stack_pg_ptrs; - -- for (qidx = 0; qidx < hw->tot_tx_queues; qidx++) { -+ for (qidx = 0; qidx < hw->non_qos_queues; qidx++) { - pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx); - /* Initialize aura context */ - err = otx2_aura_init(pfvf, pool_id, pool_id, num_sqbs); -@@ -1406,7 +1414,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf) - goto fail; - - /* Allocate pointers and free them to aura/pool */ -- for (qidx = 0; qidx < hw->tot_tx_queues; qidx++) { -+ for (qidx = 0; qidx < hw->non_qos_queues; qidx++) { - pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx); - pool = &pfvf->qset.pool[pool_id]; - -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -index 8a9793b06769f..efd66224b3dbf 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -@@ -27,6 +27,7 @@ - #include "otx2_txrx.h" - #include "otx2_devlink.h" - #include -+#include "qos.h" - - /* PCI device IDs */ - #define PCI_DEVID_OCTEONTX2_RVU_PF 0xA063 -@@ -186,7 +187,8 @@ struct otx2_hw { - u16 rx_queues; - u16 tx_queues; - u16 xdp_queues; -- u16 tot_tx_queues; -+ u16 tc_tx_queues; -+ u16 non_qos_queues; /* tx queues plus xdp queues */ - u16 max_queues; - u16 pool_cnt; - u16 rqpool_cnt; -@@ -498,6 +500,8 @@ struct otx2_nic { - u16 pfc_schq_list[NIX_TXSCH_LVL_CNT][MAX_TXSCHQ_PER_FUNC]; - bool pfc_alloc_status[NIX_PF_PFC_PRIO_MAX]; - #endif -+ /* qos */ -+ struct otx2_qos qos; - - /* napi event count. It is needed for adaptive irq coalescing. */ - u32 napi_events; -@@ -742,8 +746,7 @@ static inline void cn10k_aura_freeptr(void *dev, int aura, u64 buf) - /* Alloc pointer from pool/aura */ - static inline u64 otx2_aura_allocptr(struct otx2_nic *pfvf, int aura) - { -- u64 *ptr = (u64 *)otx2_get_regaddr(pfvf, -- NPA_LF_AURA_OP_ALLOCX(0)); -+ u64 *ptr = (__force u64 *)otx2_get_regaddr(pfvf, NPA_LF_AURA_OP_ALLOCX(0)); - u64 incr = (u64)aura | BIT_ULL(63); - - return otx2_atomic64_add(incr, ptr); -@@ -885,12 +888,23 @@ static inline void otx2_dma_unmap_page(struct otx2_nic *pfvf, - - static inline u16 otx2_get_smq_idx(struct otx2_nic *pfvf, u16 qidx) - { -+ u16 smq; - #ifdef CONFIG_DCB - if (qidx < NIX_PF_PFC_PRIO_MAX && pfvf->pfc_alloc_status[qidx]) - return pfvf->pfc_schq_list[NIX_TXSCH_LVL_SMQ][qidx]; - #endif -+ /* check if qidx falls under QOS queues */ -+ if (qidx >= pfvf->hw.non_qos_queues) -+ smq = pfvf->qos.qid_to_sqmap[qidx - pfvf->hw.non_qos_queues]; -+ else -+ smq = pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][0]; - -- return pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][0]; -+ return smq; -+} -+ -+static inline u16 otx2_get_total_tx_queues(struct otx2_nic *pfvf) -+{ -+ return pfvf->hw.non_qos_queues + pfvf->hw.tc_tx_queues; - } - - /* MSI-X APIs */ -@@ -919,18 +933,24 @@ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl, int prio, bool pfc_en); - int otx2_txsch_alloc(struct otx2_nic *pfvf); - void otx2_txschq_stop(struct otx2_nic *pfvf); - void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq); -+void otx2_free_pending_sqe(struct otx2_nic *pfvf); - void otx2_sqb_flush(struct otx2_nic *pfvf); --int __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, -- dma_addr_t *dma); -+int otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, -+ dma_addr_t *dma); - int otx2_rxtx_enable(struct otx2_nic *pfvf, bool enable); - void otx2_ctx_disable(struct mbox *mbox, int type, bool npa); - int otx2_nix_config_bp(struct otx2_nic *pfvf, bool enable); - void otx2_cleanup_rx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq); - void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq); -+int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura); - int otx2_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura); - int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura); - int otx2_alloc_buffer(struct otx2_nic *pfvf, struct otx2_cq_queue *cq, - dma_addr_t *dma); -+int otx2_pool_init(struct otx2_nic *pfvf, u16 pool_id, -+ int stack_pages, int numptrs, int buf_size); -+int otx2_aura_init(struct otx2_nic *pfvf, int aura_id, -+ int pool_id, int numptrs); - - /* RSS configuration APIs*/ - int otx2_rss_init(struct otx2_nic *pfvf); -@@ -1038,4 +1058,14 @@ static inline void cn10k_handle_mcs_event(struct otx2_nic *pfvf, - {} - #endif /* CONFIG_MACSEC */ - -+/* qos support */ -+static inline void otx2_qos_init(struct otx2_nic *pfvf, int qos_txqs) -+{ -+ struct otx2_hw *hw = &pfvf->hw; -+ -+ hw->tc_tx_queues = qos_txqs; -+} -+ -+u16 otx2_select_queue(struct net_device *netdev, struct sk_buff *skb, -+ struct net_device *sb_dev); - #endif /* OTX2_COMMON_H */ -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -index 17e546d0d7e55..c724131172f3f 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -@@ -23,6 +23,7 @@ - #include "otx2_struct.h" - #include "otx2_ptp.h" - #include "cn10k.h" -+#include "qos.h" - #include - - #define DRV_NAME "rvu_nicpf" -@@ -1194,36 +1195,38 @@ static char *nix_mnqerr_e_str[NIX_MNQERR_MAX] = { - }; - - static char *nix_snd_status_e_str[NIX_SND_STATUS_MAX] = { -- "NIX_SND_STATUS_GOOD", -- "NIX_SND_STATUS_SQ_CTX_FAULT", -- "NIX_SND_STATUS_SQ_CTX_POISON", -- "NIX_SND_STATUS_SQB_FAULT", -- "NIX_SND_STATUS_SQB_POISON", -- "NIX_SND_STATUS_HDR_ERR", -- "NIX_SND_STATUS_EXT_ERR", -- "NIX_SND_STATUS_JUMP_FAULT", -- "NIX_SND_STATUS_JUMP_POISON", -- "NIX_SND_STATUS_CRC_ERR", -- "NIX_SND_STATUS_IMM_ERR", -- "NIX_SND_STATUS_SG_ERR", -- "NIX_SND_STATUS_MEM_ERR", -- "NIX_SND_STATUS_INVALID_SUBDC", -- "NIX_SND_STATUS_SUBDC_ORDER_ERR", -- "NIX_SND_STATUS_DATA_FAULT", -- "NIX_SND_STATUS_DATA_POISON", -- "NIX_SND_STATUS_NPC_DROP_ACTION", -- "NIX_SND_STATUS_LOCK_VIOL", -- "NIX_SND_STATUS_NPC_UCAST_CHAN_ERR", -- "NIX_SND_STATUS_NPC_MCAST_CHAN_ERR", -- "NIX_SND_STATUS_NPC_MCAST_ABORT", -- "NIX_SND_STATUS_NPC_VTAG_PTR_ERR", -- "NIX_SND_STATUS_NPC_VTAG_SIZE_ERR", -- "NIX_SND_STATUS_SEND_STATS_ERR", -+ [NIX_SND_STATUS_GOOD] = "NIX_SND_STATUS_GOOD", -+ [NIX_SND_STATUS_SQ_CTX_FAULT] = "NIX_SND_STATUS_SQ_CTX_FAULT", -+ [NIX_SND_STATUS_SQ_CTX_POISON] = "NIX_SND_STATUS_SQ_CTX_POISON", -+ [NIX_SND_STATUS_SQB_FAULT] = "NIX_SND_STATUS_SQB_FAULT", -+ [NIX_SND_STATUS_SQB_POISON] = "NIX_SND_STATUS_SQB_POISON", -+ [NIX_SND_STATUS_HDR_ERR] = "NIX_SND_STATUS_HDR_ERR", -+ [NIX_SND_STATUS_EXT_ERR] = "NIX_SND_STATUS_EXT_ERR", -+ [NIX_SND_STATUS_JUMP_FAULT] = "NIX_SND_STATUS_JUMP_FAULT", -+ [NIX_SND_STATUS_JUMP_POISON] = "NIX_SND_STATUS_JUMP_POISON", -+ [NIX_SND_STATUS_CRC_ERR] = "NIX_SND_STATUS_CRC_ERR", -+ [NIX_SND_STATUS_IMM_ERR] = "NIX_SND_STATUS_IMM_ERR", -+ [NIX_SND_STATUS_SG_ERR] = "NIX_SND_STATUS_SG_ERR", -+ [NIX_SND_STATUS_MEM_ERR] = "NIX_SND_STATUS_MEM_ERR", -+ [NIX_SND_STATUS_INVALID_SUBDC] = "NIX_SND_STATUS_INVALID_SUBDC", -+ [NIX_SND_STATUS_SUBDC_ORDER_ERR] = "NIX_SND_STATUS_SUBDC_ORDER_ERR", -+ [NIX_SND_STATUS_DATA_FAULT] = "NIX_SND_STATUS_DATA_FAULT", -+ [NIX_SND_STATUS_DATA_POISON] = "NIX_SND_STATUS_DATA_POISON", -+ [NIX_SND_STATUS_NPC_DROP_ACTION] = "NIX_SND_STATUS_NPC_DROP_ACTION", -+ [NIX_SND_STATUS_LOCK_VIOL] = "NIX_SND_STATUS_LOCK_VIOL", -+ [NIX_SND_STATUS_NPC_UCAST_CHAN_ERR] = "NIX_SND_STAT_NPC_UCAST_CHAN_ERR", -+ [NIX_SND_STATUS_NPC_MCAST_CHAN_ERR] = "NIX_SND_STAT_NPC_MCAST_CHAN_ERR", -+ [NIX_SND_STATUS_NPC_MCAST_ABORT] = "NIX_SND_STATUS_NPC_MCAST_ABORT", -+ [NIX_SND_STATUS_NPC_VTAG_PTR_ERR] = "NIX_SND_STATUS_NPC_VTAG_PTR_ERR", -+ [NIX_SND_STATUS_NPC_VTAG_SIZE_ERR] = "NIX_SND_STATUS_NPC_VTAG_SIZE_ERR", -+ [NIX_SND_STATUS_SEND_MEM_FAULT] = "NIX_SND_STATUS_SEND_MEM_FAULT", -+ [NIX_SND_STATUS_SEND_STATS_ERR] = "NIX_SND_STATUS_SEND_STATS_ERR", - }; - - static irqreturn_t otx2_q_intr_handler(int irq, void *data) - { - struct otx2_nic *pf = data; -+ struct otx2_snd_queue *sq; - u64 val, *ptr; - u64 qidx = 0; - -@@ -1238,14 +1241,16 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data) - continue; - - if (val & BIT_ULL(42)) { -- netdev_err(pf->netdev, "CQ%lld: error reading NIX_LF_CQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", -+ netdev_err(pf->netdev, -+ "CQ%lld: error reading NIX_LF_CQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", - qidx, otx2_read64(pf, NIX_LF_ERR_INT)); - } else { - if (val & BIT_ULL(NIX_CQERRINT_DOOR_ERR)) - netdev_err(pf->netdev, "CQ%lld: Doorbell error", - qidx); - if (val & BIT_ULL(NIX_CQERRINT_CQE_FAULT)) -- netdev_err(pf->netdev, "CQ%lld: Memory fault on CQE write to LLC/DRAM", -+ netdev_err(pf->netdev, -+ "CQ%lld: Memory fault on CQE write to LLC/DRAM", - qidx); - } - -@@ -1253,10 +1258,14 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data) - } - - /* SQ */ -- for (qidx = 0; qidx < pf->hw.tot_tx_queues; qidx++) { -+ for (qidx = 0; qidx < otx2_get_total_tx_queues(pf); qidx++) { - u64 sq_op_err_dbg, mnq_err_dbg, snd_err_dbg; - u8 sq_op_err_code, mnq_err_code, snd_err_code; - -+ sq = &pf->qset.sq[qidx]; -+ if (!sq->sqb_ptrs) -+ continue; -+ - /* Below debug registers captures first errors corresponding to - * those registers. We don't have to check against SQ qid as - * these are fatal errors. -@@ -1268,7 +1277,8 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data) - (val & NIX_SQINT_BITS)); - - if (val & BIT_ULL(42)) { -- netdev_err(pf->netdev, "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", -+ netdev_err(pf->netdev, -+ "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n", - qidx, otx2_read64(pf, NIX_LF_ERR_INT)); - goto done; - } -@@ -1278,8 +1288,11 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data) - goto chk_mnq_err_dbg; - - sq_op_err_code = FIELD_GET(GENMASK(7, 0), sq_op_err_dbg); -- netdev_err(pf->netdev, "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(%llx) err=%s\n", -- qidx, sq_op_err_dbg, nix_sqoperr_e_str[sq_op_err_code]); -+ netdev_err(pf->netdev, -+ "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(0x%llx) err=%s(%#x)\n", -+ qidx, sq_op_err_dbg, -+ nix_sqoperr_e_str[sq_op_err_code], -+ sq_op_err_code); - - otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG, BIT_ULL(44)); - -@@ -1296,16 +1309,21 @@ chk_mnq_err_dbg: - goto chk_snd_err_dbg; - - mnq_err_code = FIELD_GET(GENMASK(7, 0), mnq_err_dbg); -- netdev_err(pf->netdev, "SQ%lld: NIX_LF_MNQ_ERR_DBG(%llx) err=%s\n", -- qidx, mnq_err_dbg, nix_mnqerr_e_str[mnq_err_code]); -+ netdev_err(pf->netdev, -+ "SQ%lld: NIX_LF_MNQ_ERR_DBG(0x%llx) err=%s(%#x)\n", -+ qidx, mnq_err_dbg, nix_mnqerr_e_str[mnq_err_code], -+ mnq_err_code); - otx2_write64(pf, NIX_LF_MNQ_ERR_DBG, BIT_ULL(44)); - - chk_snd_err_dbg: - snd_err_dbg = otx2_read64(pf, NIX_LF_SEND_ERR_DBG); - if (snd_err_dbg & BIT(44)) { - snd_err_code = FIELD_GET(GENMASK(7, 0), snd_err_dbg); -- netdev_err(pf->netdev, "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s\n", -- qidx, snd_err_dbg, nix_snd_status_e_str[snd_err_code]); -+ netdev_err(pf->netdev, -+ "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s(%#x)\n", -+ qidx, snd_err_dbg, -+ nix_snd_status_e_str[snd_err_code], -+ snd_err_code); - otx2_write64(pf, NIX_LF_SEND_ERR_DBG, BIT_ULL(44)); - } - -@@ -1379,7 +1397,7 @@ static void otx2_free_sq_res(struct otx2_nic *pf) - otx2_ctx_disable(&pf->mbox, NIX_AQ_CTYPE_SQ, false); - /* Free SQB pointers */ - otx2_sq_free_sqbs(pf); -- for (qidx = 0; qidx < pf->hw.tot_tx_queues; qidx++) { -+ for (qidx = 0; qidx < otx2_get_total_tx_queues(pf); qidx++) { - sq = &qset->sq[qidx]; - qmem_free(pf->dev, sq->sqe); - qmem_free(pf->dev, sq->tso_hdrs); -@@ -1429,7 +1447,7 @@ static int otx2_init_hw_resources(struct otx2_nic *pf) - * so, aura count = pool count. - */ - hw->rqpool_cnt = hw->rx_queues; -- hw->sqpool_cnt = hw->tot_tx_queues; -+ hw->sqpool_cnt = otx2_get_total_tx_queues(pf); - hw->pool_cnt = hw->rqpool_cnt + hw->sqpool_cnt; - - /* Maximum hardware supported transmit length */ -@@ -1578,6 +1596,7 @@ static void otx2_free_hw_resources(struct otx2_nic *pf) - else - otx2_cleanup_tx_cqes(pf, cq); - } -+ otx2_free_pending_sqe(pf); - - otx2_free_sq_res(pf); - -@@ -1682,11 +1701,14 @@ int otx2_open(struct net_device *netdev) - - netif_carrier_off(netdev); - -- pf->qset.cq_cnt = pf->hw.rx_queues + pf->hw.tot_tx_queues; - /* RQ and SQs are mapped to different CQs, - * so find out max CQ IRQs (i.e CINTs) needed. - */ -- pf->hw.cint_cnt = max(pf->hw.rx_queues, pf->hw.tx_queues); -+ pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues, -+ pf->hw.tc_tx_queues); -+ -+ pf->qset.cq_cnt = pf->hw.rx_queues + otx2_get_total_tx_queues(pf); -+ - qset->napi = kcalloc(pf->hw.cint_cnt, sizeof(*cq_poll), GFP_KERNEL); - if (!qset->napi) - return -ENOMEM; -@@ -1702,7 +1724,7 @@ int otx2_open(struct net_device *netdev) - if (!qset->cq) - goto err_free_mem; - -- qset->sq = kcalloc(pf->hw.tot_tx_queues, -+ qset->sq = kcalloc(pf->hw.non_qos_queues, - sizeof(struct otx2_snd_queue), GFP_KERNEL); - if (!qset->sq) - goto err_free_mem; -@@ -1737,6 +1759,11 @@ int otx2_open(struct net_device *netdev) - else - cq_poll->cq_ids[CQ_XDP] = CINT_INVALID_CQ; - -+ cq_poll->cq_ids[CQ_QOS] = (qidx < pf->hw.tc_tx_queues) ? -+ (qidx + pf->hw.rx_queues + -+ pf->hw.non_qos_queues) : -+ CINT_INVALID_CQ; -+ - cq_poll->dev = (void *)pf; - cq_poll->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_CQE; - INIT_WORK(&cq_poll->dim.work, otx2_dim_work); -@@ -1941,6 +1968,12 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev) - int qidx = skb_get_queue_mapping(skb); - struct otx2_snd_queue *sq; - struct netdev_queue *txq; -+ int sq_idx; -+ -+ /* XDP SQs are not mapped with TXQs -+ * advance qid to derive correct sq mapped with QOS -+ */ -+ sq_idx = (qidx >= pf->hw.tx_queues) ? (qidx + pf->hw.xdp_queues) : qidx; - - /* Check for minimum and maximum packet length */ - if (skb->len <= ETH_HLEN || -@@ -1949,7 +1982,7 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev) - return NETDEV_TX_OK; - } - -- sq = &pf->qset.sq[qidx]; -+ sq = &pf->qset.sq[sq_idx]; - txq = netdev_get_tx_queue(netdev, qidx); - - if (!otx2_sq_append_skb(netdev, sq, skb, qidx)) { -@@ -1967,8 +2000,8 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev) - return NETDEV_TX_OK; - } - --static u16 otx2_select_queue(struct net_device *netdev, struct sk_buff *skb, -- struct net_device *sb_dev) -+u16 otx2_select_queue(struct net_device *netdev, struct sk_buff *skb, -+ struct net_device *sb_dev) - { - #ifdef CONFIG_DCB - struct otx2_nic *pf = netdev_priv(netdev); -@@ -1990,6 +2023,7 @@ pick_tx: - #endif - return netdev_pick_tx(netdev, skb, NULL); - } -+EXPORT_SYMBOL(otx2_select_queue); - - static netdev_features_t otx2_fix_features(struct net_device *dev, - netdev_features_t features) -@@ -2520,7 +2554,7 @@ static int otx2_xdp_setup(struct otx2_nic *pf, struct bpf_prog *prog) - else - pf->hw.xdp_queues = 0; - -- pf->hw.tot_tx_queues += pf->hw.xdp_queues; -+ pf->hw.non_qos_queues += pf->hw.xdp_queues; - - if (if_up) - otx2_open(pf->netdev); -@@ -2703,10 +2737,10 @@ static void otx2_sriov_vfcfg_cleanup(struct otx2_nic *pf) - static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) - { - struct device *dev = &pdev->dev; -+ int err, qcount, qos_txqs; - struct net_device *netdev; - struct otx2_nic *pf; - struct otx2_hw *hw; -- int err, qcount; - int num_vec; - - err = pcim_enable_device(pdev); -@@ -2731,8 +2765,9 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) - - /* Set number of queues */ - qcount = min_t(int, num_online_cpus(), OTX2_MAX_CQ_CNT); -+ qos_txqs = min_t(int, qcount, OTX2_QOS_MAX_LEAF_NODES); - -- netdev = alloc_etherdev_mqs(sizeof(*pf), qcount, qcount); -+ netdev = alloc_etherdev_mqs(sizeof(*pf), qcount + qos_txqs, qcount); - if (!netdev) { - err = -ENOMEM; - goto err_release_regions; -@@ -2751,7 +2786,7 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) - hw->pdev = pdev; - hw->rx_queues = qcount; - hw->tx_queues = qcount; -- hw->tot_tx_queues = qcount; -+ hw->non_qos_queues = qcount; - hw->max_queues = qcount; - hw->rbuf_len = OTX2_DEFAULT_RBUF_LEN; - /* Use CQE of 128 byte descriptor size by default */ -@@ -2919,6 +2954,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) - goto err_pf_sriov_init; - #endif - -+ otx2_qos_init(pf, qos_txqs); -+ - return 0; - - err_pf_sriov_init: -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h -index fa37b9f312cae..4e5899d8fa2e6 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h -@@ -318,23 +318,23 @@ enum nix_snd_status_e { - NIX_SND_STATUS_EXT_ERR = 0x6, - NIX_SND_STATUS_JUMP_FAULT = 0x7, - NIX_SND_STATUS_JUMP_POISON = 0x8, -- NIX_SND_STATUS_CRC_ERR = 0x9, -- NIX_SND_STATUS_IMM_ERR = 0x10, -- NIX_SND_STATUS_SG_ERR = 0x11, -- NIX_SND_STATUS_MEM_ERR = 0x12, -- NIX_SND_STATUS_INVALID_SUBDC = 0x13, -- NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x14, -- NIX_SND_STATUS_DATA_FAULT = 0x15, -- NIX_SND_STATUS_DATA_POISON = 0x16, -- NIX_SND_STATUS_NPC_DROP_ACTION = 0x17, -- NIX_SND_STATUS_LOCK_VIOL = 0x18, -- NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x19, -- NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x20, -- NIX_SND_STATUS_NPC_MCAST_ABORT = 0x21, -- NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x22, -- NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x23, -- NIX_SND_STATUS_SEND_MEM_FAULT = 0x24, -- NIX_SND_STATUS_SEND_STATS_ERR = 0x25, -+ NIX_SND_STATUS_CRC_ERR = 0x10, -+ NIX_SND_STATUS_IMM_ERR = 0x11, -+ NIX_SND_STATUS_SG_ERR = 0x12, -+ NIX_SND_STATUS_MEM_ERR = 0x13, -+ NIX_SND_STATUS_INVALID_SUBDC = 0x14, -+ NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x15, -+ NIX_SND_STATUS_DATA_FAULT = 0x16, -+ NIX_SND_STATUS_DATA_POISON = 0x17, -+ NIX_SND_STATUS_NPC_DROP_ACTION = 0x20, -+ NIX_SND_STATUS_LOCK_VIOL = 0x21, -+ NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x22, -+ NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x23, -+ NIX_SND_STATUS_NPC_MCAST_ABORT = 0x24, -+ NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x25, -+ NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x26, -+ NIX_SND_STATUS_SEND_MEM_FAULT = 0x27, -+ NIX_SND_STATUS_SEND_STATS_ERR = 0x28, - NIX_SND_STATUS_MAX, - }; - -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -index 5704fb75fa477..20d801d30c732 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -@@ -468,12 +468,13 @@ process_cqe: - break; - } - -- if (cq->cq_type == CQ_XDP) { -+ qidx = cq->cq_idx - pfvf->hw.rx_queues; -+ -+ if (cq->cq_type == CQ_XDP) - otx2_xdp_snd_pkt_handler(pfvf, sq, cqe); -- } else { -- otx2_snd_pkt_handler(pfvf, cq, sq, cqe, budget, -- &tx_pkts, &tx_bytes); -- } -+ else -+ otx2_snd_pkt_handler(pfvf, cq, &pfvf->qset.sq[qidx], -+ cqe, budget, &tx_pkts, &tx_bytes); - - cqe->hdr.cqe_type = NIX_XQE_TYPE_INVALID; - processed_cqe++; -@@ -490,7 +491,11 @@ process_cqe: - if (likely(tx_pkts)) { - struct netdev_queue *txq; - -- txq = netdev_get_tx_queue(pfvf->netdev, cq->cint_idx); -+ qidx = cq->cq_idx - pfvf->hw.rx_queues; -+ -+ if (qidx >= pfvf->hw.tx_queues) -+ qidx -= pfvf->hw.xdp_queues; -+ txq = netdev_get_tx_queue(pfvf->netdev, qidx); - netdev_tx_completed_queue(txq, tx_pkts, tx_bytes); - /* Check if queue was stopped earlier due to ring full */ - smp_mb(); -@@ -738,7 +743,8 @@ static void otx2_sqe_add_hdr(struct otx2_nic *pfvf, struct otx2_snd_queue *sq, - sqe_hdr->aura = sq->aura_id; - /* Post a CQE Tx after pkt transmission */ - sqe_hdr->pnc = 1; -- sqe_hdr->sq = qidx; -+ sqe_hdr->sq = (qidx >= pfvf->hw.tx_queues) ? -+ qidx + pfvf->hw.xdp_queues : qidx; - } - sqe_hdr->total = skb->len; - /* Set SQE identifier which will be used later for freeing SKB */ -@@ -1218,13 +1224,17 @@ void otx2_cleanup_rx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq) - - void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq) - { -+ int tx_pkts = 0, tx_bytes = 0; - struct sk_buff *skb = NULL; - struct otx2_snd_queue *sq; - struct nix_cqe_tx_s *cqe; -+ struct netdev_queue *txq; - int processed_cqe = 0; - struct sg_list *sg; -+ int qidx; - -- sq = &pfvf->qset.sq[cq->cint_idx]; -+ qidx = cq->cq_idx - pfvf->hw.rx_queues; -+ sq = &pfvf->qset.sq[qidx]; - - if (otx2_nix_cq_op_status(pfvf, cq) || !cq->pend_cqe) - return; -@@ -1239,12 +1249,20 @@ void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq) - sg = &sq->sg[cqe->comp.sqe_id]; - skb = (struct sk_buff *)sg->skb; - if (skb) { -+ tx_bytes += skb->len; -+ tx_pkts++; - otx2_dma_unmap_skb_frags(pfvf, sg); - dev_kfree_skb_any(skb); - sg->skb = (u64)NULL; - } - } - -+ if (likely(tx_pkts)) { -+ if (qidx >= pfvf->hw.tx_queues) -+ qidx -= pfvf->hw.xdp_queues; -+ txq = netdev_get_tx_queue(pfvf->netdev, qidx); -+ netdev_tx_completed_queue(txq, tx_pkts, tx_bytes); -+ } - /* Free CQEs to HW */ - otx2_write64(pfvf, NIX_LF_CQ_OP_DOOR, - ((u64)cq->cq_idx << 32) | processed_cqe); -@@ -1271,6 +1289,38 @@ int otx2_rxtx_enable(struct otx2_nic *pfvf, bool enable) - return err; - } - -+void otx2_free_pending_sqe(struct otx2_nic *pfvf) -+{ -+ int tx_pkts = 0, tx_bytes = 0; -+ struct sk_buff *skb = NULL; -+ struct otx2_snd_queue *sq; -+ struct netdev_queue *txq; -+ struct sg_list *sg; -+ int sq_idx, sqe; -+ -+ for (sq_idx = 0; sq_idx < pfvf->hw.tx_queues; sq_idx++) { -+ sq = &pfvf->qset.sq[sq_idx]; -+ for (sqe = 0; sqe < sq->sqe_cnt; sqe++) { -+ sg = &sq->sg[sqe]; -+ skb = (struct sk_buff *)sg->skb; -+ if (skb) { -+ tx_bytes += skb->len; -+ tx_pkts++; -+ otx2_dma_unmap_skb_frags(pfvf, sg); -+ dev_kfree_skb_any(skb); -+ sg->skb = (u64)NULL; -+ } -+ } -+ -+ if (!tx_pkts) -+ continue; -+ txq = netdev_get_tx_queue(pfvf->netdev, sq_idx); -+ netdev_tx_completed_queue(txq, tx_pkts, tx_bytes); -+ tx_pkts = 0; -+ tx_bytes = 0; -+ } -+} -+ - static void otx2_xdp_sqe_add_sg(struct otx2_snd_queue *sq, u64 dma_addr, - int len, int *offset) - { -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h -index 93cac2c2664c2..7ab6db9a986fa 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h -@@ -102,7 +102,8 @@ enum cq_type { - CQ_RX, - CQ_TX, - CQ_XDP, -- CQS_PER_CINT = 3, /* RQ + SQ + XDP */ -+ CQ_QOS, -+ CQS_PER_CINT = 4, /* RQ + SQ + XDP + QOS_SQ */ - }; - - struct otx2_cq_poll { -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -index f8f0c01f62a14..404855bccb4b6 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c -@@ -475,6 +475,7 @@ static const struct net_device_ops otx2vf_netdev_ops = { - .ndo_open = otx2vf_open, - .ndo_stop = otx2vf_stop, - .ndo_start_xmit = otx2vf_xmit, -+ .ndo_select_queue = otx2_select_queue, - .ndo_set_rx_mode = otx2vf_set_rx_mode, - .ndo_set_mac_address = otx2_set_mac_address, - .ndo_change_mtu = otx2vf_change_mtu, -@@ -520,10 +521,10 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) - { - int num_vec = pci_msix_vec_count(pdev); - struct device *dev = &pdev->dev; -+ int err, qcount, qos_txqs; - struct net_device *netdev; - struct otx2_nic *vf; - struct otx2_hw *hw; -- int err, qcount; - - err = pcim_enable_device(pdev); - if (err) { -@@ -546,7 +547,8 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) - pci_set_master(pdev); - - qcount = num_online_cpus(); -- netdev = alloc_etherdev_mqs(sizeof(*vf), qcount, qcount); -+ qos_txqs = min_t(int, qcount, OTX2_QOS_MAX_LEAF_NODES); -+ netdev = alloc_etherdev_mqs(sizeof(*vf), qcount + qos_txqs, qcount); - if (!netdev) { - err = -ENOMEM; - goto err_release_regions; -@@ -566,7 +568,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) - hw->rx_queues = qcount; - hw->tx_queues = qcount; - hw->max_queues = qcount; -- hw->tot_tx_queues = qcount; -+ hw->non_qos_queues = qcount; - hw->rbuf_len = OTX2_DEFAULT_RBUF_LEN; - /* Use CQE of 128 byte descriptor size by default */ - hw->xqe_size = 128; -@@ -695,6 +697,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) - if (err) - goto err_shutdown_tc; - #endif -+ otx2_qos_init(vf, qos_txqs); - - return 0; - -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos.h b/drivers/net/ethernet/marvell/octeontx2/nic/qos.h -new file mode 100644 -index 0000000000000..73a62d092e99a ---- /dev/null -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos.h -@@ -0,0 +1,19 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Marvell RVU Ethernet driver -+ * -+ * Copyright (C) 2023 Marvell. -+ * -+ */ -+#ifndef OTX2_QOS_H -+#define OTX2_QOS_H -+ -+#define OTX2_QOS_MAX_LEAF_NODES 16 -+ -+int otx2_qos_enable_sq(struct otx2_nic *pfvf, int qidx, u16 smq); -+void otx2_qos_disable_sq(struct otx2_nic *pfvf, int qidx, u16 mdq); -+ -+struct otx2_qos { -+ u16 qid_to_sqmap[OTX2_QOS_MAX_LEAF_NODES]; -+ }; -+ -+#endif -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c -new file mode 100644 -index 0000000000000..e142d43f5a62c ---- /dev/null -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c -@@ -0,0 +1,282 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Marvell RVU Physical Function ethernet driver -+ * -+ * Copyright (C) 2023 Marvell. -+ * -+ */ -+ -+#include -+#include -+ -+#include "cn10k.h" -+#include "otx2_reg.h" -+#include "otx2_common.h" -+#include "otx2_txrx.h" -+#include "otx2_struct.h" -+ -+#define OTX2_QOS_MAX_LEAF_NODES 16 -+ -+static void otx2_qos_aura_pool_free(struct otx2_nic *pfvf, int pool_id) -+{ -+ struct otx2_pool *pool; -+ -+ if (!pfvf->qset.pool) -+ return; -+ -+ pool = &pfvf->qset.pool[pool_id]; -+ qmem_free(pfvf->dev, pool->stack); -+ qmem_free(pfvf->dev, pool->fc_addr); -+ pool->stack = NULL; -+ pool->fc_addr = NULL; -+} -+ -+static int otx2_qos_sq_aura_pool_init(struct otx2_nic *pfvf, int qidx) -+{ -+ struct otx2_qset *qset = &pfvf->qset; -+ int pool_id, stack_pages, num_sqbs; -+ struct otx2_hw *hw = &pfvf->hw; -+ struct otx2_snd_queue *sq; -+ struct otx2_pool *pool; -+ dma_addr_t bufptr; -+ int err, ptr; -+ u64 iova, pa; -+ -+ /* Calculate number of SQBs needed. -+ * -+ * For a 128byte SQE, and 4K size SQB, 31 SQEs will fit in one SQB. -+ * Last SQE is used for pointing to next SQB. -+ */ -+ num_sqbs = (hw->sqb_size / 128) - 1; -+ num_sqbs = (qset->sqe_cnt + num_sqbs) / num_sqbs; -+ -+ /* Get no of stack pages needed */ -+ stack_pages = -+ (num_sqbs + hw->stack_pg_ptrs - 1) / hw->stack_pg_ptrs; -+ -+ pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx); -+ pool = &pfvf->qset.pool[pool_id]; -+ -+ /* Initialize aura context */ -+ err = otx2_aura_init(pfvf, pool_id, pool_id, num_sqbs); -+ if (err) -+ return err; -+ -+ /* Initialize pool context */ -+ err = otx2_pool_init(pfvf, pool_id, stack_pages, -+ num_sqbs, hw->sqb_size); -+ if (err) -+ goto aura_free; -+ -+ /* Flush accumulated messages */ -+ err = otx2_sync_mbox_msg(&pfvf->mbox); -+ if (err) -+ goto pool_free; -+ -+ /* Allocate pointers and free them to aura/pool */ -+ sq = &qset->sq[qidx]; -+ sq->sqb_count = 0; -+ sq->sqb_ptrs = kcalloc(num_sqbs, sizeof(*sq->sqb_ptrs), GFP_KERNEL); -+ if (!sq->sqb_ptrs) { -+ err = -ENOMEM; -+ goto pool_free; -+ } -+ -+ for (ptr = 0; ptr < num_sqbs; ptr++) { -+ err = otx2_alloc_rbuf(pfvf, pool, &bufptr); -+ if (err) -+ goto sqb_free; -+ pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr); -+ sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr; -+ } -+ -+ return 0; -+ -+sqb_free: -+ while (ptr--) { -+ if (!sq->sqb_ptrs[ptr]) -+ continue; -+ iova = sq->sqb_ptrs[ptr]; -+ pa = otx2_iova_to_phys(pfvf->iommu_domain, iova); -+ dma_unmap_page_attrs(pfvf->dev, iova, hw->sqb_size, -+ DMA_FROM_DEVICE, -+ DMA_ATTR_SKIP_CPU_SYNC); -+ put_page(virt_to_page(phys_to_virt(pa))); -+ otx2_aura_allocptr(pfvf, pool_id); -+ } -+ sq->sqb_count = 0; -+ kfree(sq->sqb_ptrs); -+pool_free: -+ qmem_free(pfvf->dev, pool->stack); -+aura_free: -+ qmem_free(pfvf->dev, pool->fc_addr); -+ otx2_mbox_reset(&pfvf->mbox.mbox, 0); -+ return err; -+} -+ -+static void otx2_qos_sq_free_sqbs(struct otx2_nic *pfvf, int qidx) -+{ -+ struct otx2_qset *qset = &pfvf->qset; -+ struct otx2_hw *hw = &pfvf->hw; -+ struct otx2_snd_queue *sq; -+ u64 iova, pa; -+ int sqb; -+ -+ sq = &qset->sq[qidx]; -+ if (!sq->sqb_ptrs) -+ return; -+ for (sqb = 0; sqb < sq->sqb_count; sqb++) { -+ if (!sq->sqb_ptrs[sqb]) -+ continue; -+ iova = sq->sqb_ptrs[sqb]; -+ pa = otx2_iova_to_phys(pfvf->iommu_domain, iova); -+ dma_unmap_page_attrs(pfvf->dev, iova, hw->sqb_size, -+ DMA_FROM_DEVICE, -+ DMA_ATTR_SKIP_CPU_SYNC); -+ put_page(virt_to_page(phys_to_virt(pa))); -+ } -+ -+ sq->sqb_count = 0; -+ -+ sq = &qset->sq[qidx]; -+ qmem_free(pfvf->dev, sq->sqe); -+ qmem_free(pfvf->dev, sq->tso_hdrs); -+ kfree(sq->sg); -+ kfree(sq->sqb_ptrs); -+ qmem_free(pfvf->dev, sq->timestamps); -+ -+ memset((void *)sq, 0, sizeof(*sq)); -+} -+ -+/* send queue id */ -+static void otx2_qos_sqb_flush(struct otx2_nic *pfvf, int qidx) -+{ -+ int sqe_tail, sqe_head; -+ u64 incr, *ptr, val; -+ -+ ptr = (__force u64 *)otx2_get_regaddr(pfvf, NIX_LF_SQ_OP_STATUS); -+ incr = (u64)qidx << 32; -+ val = otx2_atomic64_add(incr, ptr); -+ sqe_head = (val >> 20) & 0x3F; -+ sqe_tail = (val >> 28) & 0x3F; -+ if (sqe_head != sqe_tail) -+ usleep_range(50, 60); -+} -+ -+static int otx2_qos_ctx_disable(struct otx2_nic *pfvf, u16 qidx, int aura_id) -+{ -+ struct nix_cn10k_aq_enq_req *cn10k_sq_aq; -+ struct npa_aq_enq_req *aura_aq; -+ struct npa_aq_enq_req *pool_aq; -+ struct nix_aq_enq_req *sq_aq; -+ -+ if (test_bit(CN10K_LMTST, &pfvf->hw.cap_flag)) { -+ cn10k_sq_aq = otx2_mbox_alloc_msg_nix_cn10k_aq_enq(&pfvf->mbox); -+ if (!cn10k_sq_aq) -+ return -ENOMEM; -+ cn10k_sq_aq->qidx = qidx; -+ cn10k_sq_aq->sq.ena = 0; -+ cn10k_sq_aq->sq_mask.ena = 1; -+ cn10k_sq_aq->ctype = NIX_AQ_CTYPE_SQ; -+ cn10k_sq_aq->op = NIX_AQ_INSTOP_WRITE; -+ } else { -+ sq_aq = otx2_mbox_alloc_msg_nix_aq_enq(&pfvf->mbox); -+ if (!sq_aq) -+ return -ENOMEM; -+ sq_aq->qidx = qidx; -+ sq_aq->sq.ena = 0; -+ sq_aq->sq_mask.ena = 1; -+ sq_aq->ctype = NIX_AQ_CTYPE_SQ; -+ sq_aq->op = NIX_AQ_INSTOP_WRITE; -+ } -+ -+ aura_aq = otx2_mbox_alloc_msg_npa_aq_enq(&pfvf->mbox); -+ if (!aura_aq) { -+ otx2_mbox_reset(&pfvf->mbox.mbox, 0); -+ return -ENOMEM; -+ } -+ -+ aura_aq->aura_id = aura_id; -+ aura_aq->aura.ena = 0; -+ aura_aq->aura_mask.ena = 1; -+ aura_aq->ctype = NPA_AQ_CTYPE_AURA; -+ aura_aq->op = NPA_AQ_INSTOP_WRITE; -+ -+ pool_aq = otx2_mbox_alloc_msg_npa_aq_enq(&pfvf->mbox); -+ if (!pool_aq) { -+ otx2_mbox_reset(&pfvf->mbox.mbox, 0); -+ return -ENOMEM; -+ } -+ -+ pool_aq->aura_id = aura_id; -+ pool_aq->pool.ena = 0; -+ pool_aq->pool_mask.ena = 1; -+ -+ pool_aq->ctype = NPA_AQ_CTYPE_POOL; -+ pool_aq->op = NPA_AQ_INSTOP_WRITE; -+ -+ return otx2_sync_mbox_msg(&pfvf->mbox); -+} -+ -+int otx2_qos_enable_sq(struct otx2_nic *pfvf, int qidx, u16 smq) -+{ -+ struct otx2_hw *hw = &pfvf->hw; -+ int pool_id, sq_idx, err; -+ -+ if (pfvf->flags & OTX2_FLAG_INTF_DOWN) -+ return -EPERM; -+ -+ sq_idx = hw->non_qos_queues + qidx; -+ -+ mutex_lock(&pfvf->mbox.lock); -+ err = otx2_qos_sq_aura_pool_init(pfvf, sq_idx); -+ if (err) -+ goto out; -+ -+ pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, sq_idx); -+ pfvf->qos.qid_to_sqmap[qidx] = smq; -+ err = otx2_sq_init(pfvf, sq_idx, pool_id); -+ if (err) -+ goto out; -+out: -+ mutex_unlock(&pfvf->mbox.lock); -+ return err; -+} -+ -+void otx2_qos_disable_sq(struct otx2_nic *pfvf, int qidx, u16 mdq) -+{ -+ struct otx2_qset *qset = &pfvf->qset; -+ struct otx2_hw *hw = &pfvf->hw; -+ struct otx2_snd_queue *sq; -+ struct otx2_cq_queue *cq; -+ int pool_id, sq_idx; -+ -+ sq_idx = hw->non_qos_queues + qidx; -+ -+ /* If the DOWN flag is set SQs are already freed */ -+ if (pfvf->flags & OTX2_FLAG_INTF_DOWN) -+ return; -+ -+ sq = &pfvf->qset.sq[sq_idx]; -+ if (!sq->sqb_ptrs) -+ return; -+ -+ if (sq_idx < hw->non_qos_queues || -+ sq_idx >= otx2_get_total_tx_queues(pfvf)) { -+ netdev_err(pfvf->netdev, "Send Queue is not a QoS queue\n"); -+ return; -+ } -+ -+ cq = &qset->cq[pfvf->hw.rx_queues + sq_idx]; -+ pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, sq_idx); -+ -+ otx2_qos_sqb_flush(pfvf, sq_idx); -+ otx2_smq_flush(pfvf, otx2_get_smq_idx(pfvf, sq_idx)); -+ otx2_cleanup_tx_cqes(pfvf, cq); -+ -+ mutex_lock(&pfvf->mbox.lock); -+ otx2_qos_ctx_disable(pfvf, sq_idx, pool_id); -+ mutex_unlock(&pfvf->mbox.lock); -+ -+ otx2_qos_sq_free_sqbs(pfvf, sq_idx); -+ otx2_qos_aura_pool_free(pfvf, pool_id); -+} -diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -index e270fb3361432..14cd44f8191ba 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -51,8 +51,8 @@ struct mtk_wdma_desc { - #define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4) - #define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8) - #define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9) --#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12) --#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13) -+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(10) /* wed v2 */ -+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(11) /* wed v2 */ - #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18) -diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c -index e2aced7ab4547..95f63fcf4ba1f 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c -@@ -496,7 +496,7 @@ mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks) - * is 2^ACL_MAX_BF_LOG - */ - bf_bank_size = 1 << MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_BF_LOG); -- bf = kzalloc(struct_size(bf, refcnt, bf_bank_size * num_erp_banks), -+ bf = kzalloc(struct_size(bf, refcnt, size_mul(bf_bank_size, num_erp_banks)), - GFP_KERNEL); - if (!bf) - return ERR_PTR(-ENOMEM); -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 80b6079b8a8e3..d14706265d9cb 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -2512,9 +2512,13 @@ static void rtl_set_rx_mode(struct net_device *dev) - - if (dev->flags & IFF_PROMISC) { - rx_mode |= AcceptAllPhys; -+ } else if (!(dev->flags & IFF_MULTICAST)) { -+ rx_mode &= ~AcceptMulticast; - } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || - dev->flags & IFF_ALLMULTI || -- tp->mac_version == RTL_GIGA_MAC_VER_35) { -+ tp->mac_version == RTL_GIGA_MAC_VER_35 || -+ tp->mac_version == RTL_GIGA_MAC_VER_46 || -+ tp->mac_version == RTL_GIGA_MAC_VER_48) { - /* accept all multicasts */ - } else if (netdev_mc_empty(dev)) { - rx_mode &= ~AcceptMulticast; -@@ -4556,12 +4560,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) - static void r8169_phylink_handler(struct net_device *ndev) - { - struct rtl8169_private *tp = netdev_priv(ndev); -+ struct device *d = tp_to_dev(tp); - - if (netif_carrier_ok(ndev)) { - rtl_link_chg_patch(tp); -- pm_request_resume(&tp->pci_dev->dev); -+ pm_request_resume(d); -+ netif_wake_queue(tp->dev); - } else { -- pm_runtime_idle(&tp->pci_dev->dev); -+ /* In few cases rx is broken after link-down otherwise */ -+ if (rtl_is_8125(tp)) -+ rtl_reset_work(tp); -+ pm_runtime_idle(d); - } - - phy_print_status(tp->phydev); -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h -index 1913385df6856..880a75bf2eb1f 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h -+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h -@@ -222,7 +222,7 @@ - ((val) << XGMAC_PPS_MINIDX(x)) - #define XGMAC_PPSCMD_START 0x2 - #define XGMAC_PPSCMD_STOP 0x5 --#define XGMAC_PPSEN0 BIT(4) -+#define XGMAC_PPSENx(x) BIT(4 + (x) * 8) - #define XGMAC_PPSx_TARGET_TIME_SEC(x) (0x00000d80 + (x) * 0x10) - #define XGMAC_PPSx_TARGET_TIME_NSEC(x) (0x00000d84 + (x) * 0x10) - #define XGMAC_TRGTBUSY0 BIT(31) -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -index c6c4d7948fe5f..f30e08a106cbe 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -@@ -1135,7 +1135,19 @@ static int dwxgmac2_flex_pps_config(void __iomem *ioaddr, int index, - - val |= XGMAC_PPSCMDx(index, XGMAC_PPSCMD_START); - val |= XGMAC_TRGTMODSELx(index, XGMAC_PPSCMD_START); -- val |= XGMAC_PPSEN0; -+ -+ /* XGMAC Core has 4 PPS outputs at most. -+ * -+ * Prior XGMAC Core 3.20, Fixed mode or Flexible mode are selectable for -+ * PPS0 only via PPSEN0. PPS{1,2,3} are in Flexible mode by default, -+ * and can not be switched to Fixed mode, since PPSEN{1,2,3} are -+ * read-only reserved to 0. -+ * But we always set PPSEN{1,2,3} do not make things worse ;-) -+ * -+ * From XGMAC Core 3.20 and later, PPSEN{0,1,2,3} are writable and must -+ * be set, or the PPS outputs stay in Fixed PPS mode by default. -+ */ -+ val |= XGMAC_PPSENx(index); - - writel(cfg->start.tv_sec, ioaddr + XGMAC_PPSx_TARGET_TIME_SEC(index)); - -diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c -index 50d7eacfec582..87e67121477cb 100644 ---- a/drivers/net/ethernet/toshiba/spider_net.c -+++ b/drivers/net/ethernet/toshiba/spider_net.c -@@ -2332,7 +2332,7 @@ spider_net_alloc_card(void) - struct spider_net_card *card; - - netdev = alloc_etherdev(struct_size(card, darray, -- tx_descriptors + rx_descriptors)); -+ size_add(tx_descriptors, rx_descriptors))); - if (!netdev) - return NULL; - -diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c -index 59e29e08398a0..b29b7d97b7739 100644 ---- a/drivers/net/ipvlan/ipvlan_core.c -+++ b/drivers/net/ipvlan/ipvlan_core.c -@@ -441,12 +441,12 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) - - err = ip_local_out(net, skb->sk, skb); - if (unlikely(net_xmit_eval(err))) -- dev->stats.tx_errors++; -+ DEV_STATS_INC(dev, tx_errors); - else - ret = NET_XMIT_SUCCESS; - goto out; - err: -- dev->stats.tx_errors++; -+ DEV_STATS_INC(dev, tx_errors); - kfree_skb(skb); - out: - return ret; -@@ -482,12 +482,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) - - err = ip6_local_out(net, skb->sk, skb); - if (unlikely(net_xmit_eval(err))) -- dev->stats.tx_errors++; -+ DEV_STATS_INC(dev, tx_errors); - else - ret = NET_XMIT_SUCCESS; - goto out; - err: -- dev->stats.tx_errors++; -+ DEV_STATS_INC(dev, tx_errors); - kfree_skb(skb); - out: - return ret; -diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c -index cd16bc8bf154c..fbf2d5b67aafa 100644 ---- a/drivers/net/ipvlan/ipvlan_main.c -+++ b/drivers/net/ipvlan/ipvlan_main.c -@@ -324,6 +324,7 @@ static void ipvlan_get_stats64(struct net_device *dev, - s->rx_dropped = rx_errs; - s->tx_dropped = tx_drps; - } -+ s->tx_errors = DEV_STATS_READ(dev, tx_errors); - } - - static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) -diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c -index 81453e84b6413..209ee9f352754 100644 ---- a/drivers/net/macsec.c -+++ b/drivers/net/macsec.c -@@ -3664,9 +3664,9 @@ static void macsec_get_stats64(struct net_device *dev, - - dev_fetch_sw_netstats(s, dev->tstats); - -- s->rx_dropped = atomic_long_read(&dev->stats.__rx_dropped); -- s->tx_dropped = atomic_long_read(&dev->stats.__tx_dropped); -- s->rx_errors = atomic_long_read(&dev->stats.__rx_errors); -+ s->rx_dropped = DEV_STATS_READ(dev, rx_dropped); -+ s->tx_dropped = DEV_STATS_READ(dev, tx_dropped); -+ s->rx_errors = DEV_STATS_READ(dev, rx_errors); - } - - static int macsec_get_iflink(const struct net_device *dev) -diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index cb77dd6ce9665..21c6b36dc6ebb 100644 ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8549,6 +8549,14 @@ static int ath11k_mac_op_get_txpower(struct ieee80211_hw *hw, - if (ar->state != ATH11K_STATE_ON) - goto err_fallback; - -+ /* Firmware doesn't provide Tx power during CAC hence no need to fetch -+ * the stats. -+ */ -+ if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) { -+ mutex_unlock(&ar->conf_mutex); -+ return -EAGAIN; -+ } -+ - req_param.pdev_id = ar->pdev->pdev_id; - req_param.stats_id = WMI_REQUEST_PDEV_STAT; - -diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c -index 3953ebd551bf8..79d2876a46b53 100644 ---- a/drivers/net/wireless/ath/ath11k/pci.c -+++ b/drivers/net/wireless/ath/ath11k/pci.c -@@ -853,10 +853,16 @@ unsupported_wcn6855_soc: - if (ret) - goto err_pci_disable_msi; - -+ ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); -+ if (ret) { -+ ath11k_err(ab, "failed to set irq affinity %d\n", ret); -+ goto err_pci_disable_msi; -+ } -+ - ret = ath11k_mhi_register(ab_pci); - if (ret) { - ath11k_err(ab, "failed to register mhi: %d\n", ret); -- goto err_pci_disable_msi; -+ goto err_irq_affinity_cleanup; - } - - ret = ath11k_hal_srng_init(ab); -@@ -877,12 +883,6 @@ unsupported_wcn6855_soc: - goto err_ce_free; - } - -- ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); -- if (ret) { -- ath11k_err(ab, "failed to set irq affinity %d\n", ret); -- goto err_free_irq; -- } -- - /* kernel may allocate a dummy vector before request_irq and - * then allocate a real vector when request_irq is called. - * So get msi_data here again to avoid spurious interrupt -@@ -891,19 +891,16 @@ unsupported_wcn6855_soc: - ret = ath11k_pci_config_msi_data(ab_pci); - if (ret) { - ath11k_err(ab, "failed to config msi_data: %d\n", ret); -- goto err_irq_affinity_cleanup; -+ goto err_free_irq; - } - - ret = ath11k_core_init(ab); - if (ret) { - ath11k_err(ab, "failed to init core: %d\n", ret); -- goto err_irq_affinity_cleanup; -+ goto err_free_irq; - } - return 0; - --err_irq_affinity_cleanup: -- ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); -- - err_free_irq: - ath11k_pcic_free_irq(ab); - -@@ -916,6 +913,9 @@ err_hal_srng_deinit: - err_mhi_unregister: - ath11k_mhi_unregister(ab_pci); - -+err_irq_affinity_cleanup: -+ ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); -+ - err_pci_disable_msi: - ath11k_pci_free_msi(ab_pci); - -diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c -index 27f4d74a41c80..2788a1b06c17c 100644 ---- a/drivers/net/wireless/ath/dfs_pattern_detector.c -+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c -@@ -206,7 +206,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) - - INIT_LIST_HEAD(&cd->head); - cd->freq = freq; -- cd->detectors = kmalloc_array(dpd->num_radar_types, -+ cd->detectors = kcalloc(dpd->num_radar_types, - sizeof(*cd->detectors), GFP_ATOMIC); - if (cd->detectors == NULL) - goto fail; -diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c -index 60a7b61d59aa3..ca1daec641c4f 100644 ---- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c -+++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c -@@ -3,6 +3,7 @@ - * - * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright (C) 2019 Intel Corporation -+ * Copyright (C) 2023 Intel Corporation - *****************************************************************************/ - - #include -@@ -1169,7 +1170,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb) - iwlagn_check_ratid_empty(priv, sta_id, tid); - } - -- iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs); -+ iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs, false); - - freed = 0; - -@@ -1315,7 +1316,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, - * block-ack window (we assume that they've been successfully - * transmitted ... if not, it's too late anyway). */ - iwl_trans_reclaim(priv->trans, scd_flow, ba_resp_scd_ssn, -- &reclaimed_skbs); -+ &reclaimed_skbs, false); - - IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " - "sta_id = %d\n", -diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h -index ba538d70985f4..39bee9c00e071 100644 ---- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h -+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h -@@ -13,6 +13,7 @@ - #define IWL_FW_INI_DOMAIN_ALWAYS_ON 0 - #define IWL_FW_INI_REGION_ID_MASK GENMASK(15, 0) - #define IWL_FW_INI_REGION_DUMP_POLICY_MASK GENMASK(31, 16) -+#define IWL_FW_INI_PRESET_DISABLE 0xff - - /** - * struct iwl_fw_ini_hcmd -diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h -index 128059ca77e60..06fb7d6653905 100644 ---- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h -+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h -@@ -1,6 +1,6 @@ - /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ - /* -- * Copyright (C) 2018-2022 Intel Corporation -+ * Copyright (C) 2018-2023 Intel Corporation - */ - #ifndef __iwl_dbg_tlv_h__ - #define __iwl_dbg_tlv_h__ -@@ -10,7 +10,8 @@ - #include - #include - --#define IWL_DBG_TLV_MAX_PRESET 15 -+#define IWL_DBG_TLV_MAX_PRESET 15 -+#define ENABLE_INI (IWL_DBG_TLV_MAX_PRESET + 1) - - /** - * struct iwl_dbg_tlv_node - debug TLV node -diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c -index a2203f661321c..5eba1a355f043 100644 ---- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c -+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c -@@ -1722,6 +1722,22 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) - #endif - - drv->trans->dbg.domains_bitmap = IWL_TRANS_FW_DBG_DOMAIN(drv->trans); -+ if (iwlwifi_mod_params.enable_ini != ENABLE_INI) { -+ /* We have a non-default value in the module parameter, -+ * take its value -+ */ -+ drv->trans->dbg.domains_bitmap &= 0xffff; -+ if (iwlwifi_mod_params.enable_ini != IWL_FW_INI_PRESET_DISABLE) { -+ if (iwlwifi_mod_params.enable_ini > ENABLE_INI) { -+ IWL_ERR(trans, -+ "invalid enable_ini module parameter value: max = %d, using 0 instead\n", -+ ENABLE_INI); -+ iwlwifi_mod_params.enable_ini = 0; -+ } -+ drv->trans->dbg.domains_bitmap = -+ BIT(IWL_FW_DBG_DOMAIN_POS + iwlwifi_mod_params.enable_ini); -+ } -+ } - - ret = iwl_request_firmware(drv, true); - if (ret) { -@@ -1770,8 +1786,6 @@ void iwl_drv_stop(struct iwl_drv *drv) - kfree(drv); - } - --#define ENABLE_INI (IWL_DBG_TLV_MAX_PRESET + 1) -- - /* shared module parameters */ - struct iwl_mod_params iwlwifi_mod_params = { - .fw_restart = true, -@@ -1891,38 +1905,7 @@ module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, uint, 0644); - MODULE_PARM_DESC(uapsd_disable, - "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)"); - --static int enable_ini_set(const char *arg, const struct kernel_param *kp) --{ -- int ret = 0; -- bool res; -- __u32 new_enable_ini; -- -- /* in case the argument type is a number */ -- ret = kstrtou32(arg, 0, &new_enable_ini); -- if (!ret) { -- if (new_enable_ini > ENABLE_INI) { -- pr_err("enable_ini cannot be %d, in range 0-16\n", new_enable_ini); -- return -EINVAL; -- } -- goto out; -- } -- -- /* in case the argument type is boolean */ -- ret = kstrtobool(arg, &res); -- if (ret) -- return ret; -- new_enable_ini = (res ? ENABLE_INI : 0); -- --out: -- iwlwifi_mod_params.enable_ini = new_enable_ini; -- return 0; --} -- --static const struct kernel_param_ops enable_ini_ops = { -- .set = enable_ini_set --}; -- --module_param_cb(enable_ini, &enable_ini_ops, &iwlwifi_mod_params.enable_ini, 0644); -+module_param_named(enable_ini, iwlwifi_mod_params.enable_ini, uint, 0444); - MODULE_PARM_DESC(enable_ini, - "0:disable, 1-15:FW_DBG_PRESET Values, 16:enabled without preset value defined," - "Debug INI TLV FW debug infrastructure (default: 16)"); -diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h -index d659ccd065f78..70022cadee35b 100644 ---- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h -+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h -@@ -56,6 +56,10 @@ - * 6) Eventually, the free function will be called. - */ - -+/* default preset 0 (start from bit 16)*/ -+#define IWL_FW_DBG_DOMAIN_POS 16 -+#define IWL_FW_DBG_DOMAIN BIT(IWL_FW_DBG_DOMAIN_POS) -+ - #define IWL_TRANS_FW_DBG_DOMAIN(trans) IWL_FW_INI_DOMAIN_ALWAYS_ON - - #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ -@@ -563,7 +567,7 @@ struct iwl_trans_ops { - int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_tx_cmd *dev_cmd, int queue); - void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, -- struct sk_buff_head *skbs); -+ struct sk_buff_head *skbs, bool is_flush); - - void (*set_q_ptrs)(struct iwl_trans *trans, int queue, int ptr); - -@@ -1187,14 +1191,15 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, - } - - static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, -- int ssn, struct sk_buff_head *skbs) -+ int ssn, struct sk_buff_head *skbs, -+ bool is_flush) - { - if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) { - IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); - return; - } - -- trans->ops->reclaim(trans, queue, ssn, skbs); -+ trans->ops->reclaim(trans, queue, ssn, skbs, is_flush); - } - - static inline void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue, -diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -index 2d01f6226b7c6..618355ecd9d7b 100644 ---- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -@@ -1572,7 +1572,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, - seq_ctl = le16_to_cpu(tx_resp->seq_ctl); - - /* we can free until ssn % q.n_bd not inclusive */ -- iwl_trans_reclaim(mvm->trans, txq_id, ssn, &skbs); -+ iwl_trans_reclaim(mvm->trans, txq_id, ssn, &skbs, false); - - while (!skb_queue_empty(&skbs)) { - struct sk_buff *skb = __skb_dequeue(&skbs); -@@ -1923,7 +1923,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, - * block-ack window (we assume that they've been successfully - * transmitted ... if not, it's too late anyway). - */ -- iwl_trans_reclaim(mvm->trans, txq, index, &reclaimed_skbs); -+ iwl_trans_reclaim(mvm->trans, txq, index, &reclaimed_skbs, is_flush); - - skb_queue_walk(&reclaimed_skbs, skb) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h -index f7e4f868363df..69b95ad5993b0 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h -@@ -497,6 +497,7 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans); - void iwl_pcie_rx_free(struct iwl_trans *trans); - void iwl_pcie_free_rbs_pool(struct iwl_trans *trans); - void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq); -+void iwl_pcie_rx_napi_sync(struct iwl_trans *trans); - void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority, - struct iwl_rxq *rxq); - -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -index b455e981faa1f..90a46faaaffdf 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause - /* -- * Copyright (C) 2003-2014, 2018-2022 Intel Corporation -+ * Copyright (C) 2003-2014, 2018-2023 Intel Corporation - * Copyright (C) 2013-2015 Intel Mobile Communications GmbH - * Copyright (C) 2016-2017 Intel Deutschland GmbH - */ -@@ -1053,6 +1053,22 @@ static int iwl_pcie_napi_poll_msix(struct napi_struct *napi, int budget) - return ret; - } - -+void iwl_pcie_rx_napi_sync(struct iwl_trans *trans) -+{ -+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); -+ int i; -+ -+ if (unlikely(!trans_pcie->rxq)) -+ return; -+ -+ for (i = 0; i < trans->num_rx_queues; i++) { -+ struct iwl_rxq *rxq = &trans_pcie->rxq[i]; -+ -+ if (rxq && rxq->napi.poll) -+ napi_synchronize(&rxq->napi); -+ } -+} -+ - static int _iwl_pcie_rx_init(struct iwl_trans *trans) - { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c -index 94f40c4d24217..8b9e4b9c5a2e9 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c -@@ -156,6 +156,8 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) - if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { - IWL_DEBUG_INFO(trans, - "DEVICE_ENABLED bit was set and is now cleared\n"); -+ iwl_pcie_synchronize_irqs(trans); -+ iwl_pcie_rx_napi_sync(trans); - iwl_txq_gen2_tx_free(trans); - iwl_pcie_rx_stop(trans); - } -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -index 8e95225cdd605..39ab6526e6b85 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -@@ -1261,6 +1261,8 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) - if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { - IWL_DEBUG_INFO(trans, - "DEVICE_ENABLED bit was set and is now cleared\n"); -+ iwl_pcie_synchronize_irqs(trans); -+ iwl_pcie_rx_napi_sync(trans); - iwl_pcie_tx_stop(trans); - iwl_pcie_rx_stop(trans); - -diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c -index 726185d6fab8b..8cf206837eeea 100644 ---- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c -+++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c -@@ -1551,7 +1551,7 @@ void iwl_txq_progress(struct iwl_txq *txq) - - /* Frees buffers until index _not_ inclusive */ - void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn, -- struct sk_buff_head *skbs) -+ struct sk_buff_head *skbs, bool is_flush) - { - struct iwl_txq *txq = trans->txqs.txq[txq_id]; - int tfd_num = iwl_txq_get_cmd_index(txq, ssn); -@@ -1622,9 +1622,11 @@ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn, - if (iwl_txq_space(trans, txq) > txq->low_mark && - test_bit(txq_id, trans->txqs.queue_stopped)) { - struct sk_buff_head overflow_skbs; -+ struct sk_buff *skb; - - __skb_queue_head_init(&overflow_skbs); -- skb_queue_splice_init(&txq->overflow_q, &overflow_skbs); -+ skb_queue_splice_init(&txq->overflow_q, -+ is_flush ? skbs : &overflow_skbs); - - /* - * We are going to transmit from the overflow queue. -@@ -1644,8 +1646,7 @@ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn, - */ - spin_unlock_bh(&txq->lock); - -- while (!skb_queue_empty(&overflow_skbs)) { -- struct sk_buff *skb = __skb_dequeue(&overflow_skbs); -+ while ((skb = __skb_dequeue(&overflow_skbs))) { - struct iwl_device_tx_cmd *dev_cmd_ptr; - - dev_cmd_ptr = *(void **)((u8 *)skb->cb + -diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.h b/drivers/net/wireless/intel/iwlwifi/queue/tx.h -index eca53bfd326d1..ceb6812fe20b2 100644 ---- a/drivers/net/wireless/intel/iwlwifi/queue/tx.h -+++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.h -@@ -173,7 +173,7 @@ void iwl_txq_gen1_update_byte_cnt_tbl(struct iwl_trans *trans, - struct iwl_txq *txq, u16 byte_cnt, - int num_tbs); - void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn, -- struct sk_buff_head *skbs); -+ struct sk_buff_head *skbs, bool is_flush); - void iwl_txq_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr); - void iwl_trans_txq_freeze_timer(struct iwl_trans *trans, unsigned long txqs, - bool freeze); -diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c -index b65b0a88c1ded..808466b7de472 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c -@@ -9,6 +9,23 @@ struct beacon_bc_data { - int count[MT7603_MAX_INTERFACES]; - }; - -+static void -+mt7603_mac_stuck_beacon_recovery(struct mt7603_dev *dev) -+{ -+ if (dev->beacon_check % 5 != 4) -+ return; -+ -+ mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN); -+ mt76_set(dev, MT_SCH_4, MT_SCH_4_RESET); -+ mt76_clear(dev, MT_SCH_4, MT_SCH_4_RESET); -+ mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN); -+ -+ mt76_set(dev, MT_WF_CFG_OFF_WOCCR, MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS); -+ mt76_set(dev, MT_ARB_SCR, MT_ARB_SCR_TX_DISABLE); -+ mt76_clear(dev, MT_ARB_SCR, MT_ARB_SCR_TX_DISABLE); -+ mt76_clear(dev, MT_WF_CFG_OFF_WOCCR, MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS); -+} -+ - static void - mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) - { -@@ -16,6 +33,8 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) - struct mt76_dev *mdev = &dev->mt76; - struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv; - struct sk_buff *skb = NULL; -+ u32 om_idx = mvif->idx; -+ u32 val; - - if (!(mdev->beacon_mask & BIT(mvif->idx))) - return; -@@ -24,20 +43,33 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) - if (!skb) - return; - -- mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON], -- MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL); -+ if (om_idx) -+ om_idx |= 0x10; -+ val = MT_DMA_FQCR0_BUSY | MT_DMA_FQCR0_MODE | -+ FIELD_PREP(MT_DMA_FQCR0_TARGET_BSS, om_idx) | -+ FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) | -+ FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8); - - spin_lock_bh(&dev->ps_lock); -- mt76_wr(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY | -- FIELD_PREP(MT_DMA_FQCR0_TARGET_WCID, mvif->sta.wcid.idx) | -- FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, -- dev->mphy.q_tx[MT_TXQ_CAB]->hw_idx) | -- FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) | -- FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8)); - -- if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) -+ mt76_wr(dev, MT_DMA_FQCR0, val | -+ FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BCN)); -+ if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) { - dev->beacon_check = MT7603_WATCHDOG_TIMEOUT; -+ goto out; -+ } -+ -+ mt76_wr(dev, MT_DMA_FQCR0, val | -+ FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BMC)); -+ if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) { -+ dev->beacon_check = MT7603_WATCHDOG_TIMEOUT; -+ goto out; -+ } - -+ mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON], -+ MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL); -+ -+out: - spin_unlock_bh(&dev->ps_lock); - } - -@@ -81,6 +113,18 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t) - data.dev = dev; - __skb_queue_head_init(&data.q); - -+ /* Flush all previous CAB queue packets and beacons */ -+ mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0)); -+ -+ mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_CAB], false); -+ mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BEACON], false); -+ -+ if (dev->mphy.q_tx[MT_TXQ_BEACON]->queued > 0) -+ dev->beacon_check++; -+ else -+ dev->beacon_check = 0; -+ mt7603_mac_stuck_beacon_recovery(dev); -+ - q = dev->mphy.q_tx[MT_TXQ_BEACON]; - spin_lock(&q->lock); - ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev), -@@ -89,14 +133,9 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t) - mt76_queue_kick(dev, q); - spin_unlock(&q->lock); - -- /* Flush all previous CAB queue packets */ -- mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0)); -- -- mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_CAB], false); -- - mt76_csa_check(mdev); - if (mdev->csa_complete) -- goto out; -+ return; - - q = dev->mphy.q_tx[MT_TXQ_CAB]; - do { -@@ -108,7 +147,7 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t) - skb_queue_len(&data.q) < 8); - - if (skb_queue_empty(&data.q)) -- goto out; -+ return; - - for (i = 0; i < ARRAY_SIZE(data.tail); i++) { - if (!data.tail[i]) -@@ -136,11 +175,6 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t) - MT_WF_ARB_CAB_START_BSSn(0) | - (MT_WF_ARB_CAB_START_BSS0n(1) * - ((1 << (MT7603_MAX_INTERFACES - 1)) - 1))); -- --out: -- mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BEACON], false); -- if (dev->mphy.q_tx[MT_TXQ_BEACON]->queued > hweight8(mdev->beacon_mask)) -- dev->beacon_check++; - } - - void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval) -diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/core.c b/drivers/net/wireless/mediatek/mt76/mt7603/core.c -index 60a996b63c0c0..915b8349146af 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7603/core.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7603/core.c -@@ -42,11 +42,13 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance) - } - - if (intr & MT_INT_RX_DONE(0)) { -+ dev->rx_pse_check = 0; - mt7603_irq_disable(dev, MT_INT_RX_DONE(0)); - napi_schedule(&dev->mt76.napi[0]); - } - - if (intr & MT_INT_RX_DONE(1)) { -+ dev->rx_pse_check = 0; - mt7603_irq_disable(dev, MT_INT_RX_DONE(1)); - napi_schedule(&dev->mt76.napi[1]); - } -diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c -index 6cff346d57a78..2980e1234d13f 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c -@@ -1430,15 +1430,6 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev) - - mt7603_beacon_set_timer(dev, -1, 0); - -- if (dev->reset_cause[RESET_CAUSE_RESET_FAILED] || -- dev->cur_reset_cause == RESET_CAUSE_RX_PSE_BUSY || -- dev->cur_reset_cause == RESET_CAUSE_BEACON_STUCK || -- dev->cur_reset_cause == RESET_CAUSE_TX_HANG) -- mt7603_pse_reset(dev); -- -- if (dev->reset_cause[RESET_CAUSE_RESET_FAILED]) -- goto skip_dma_reset; -- - mt7603_mac_stop(dev); - - mt76_clear(dev, MT_WPDMA_GLO_CFG, -@@ -1448,28 +1439,32 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev) - - mt7603_irq_disable(dev, mask); - -- mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_FORCE_TX_EOF); -- - mt7603_pse_client_reset(dev); - - mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], true); - for (i = 0; i < __MT_TXQ_MAX; i++) - mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true); - -+ mt7603_dma_sched_reset(dev); -+ -+ mt76_tx_status_check(&dev->mt76, true); -+ - mt76_for_each_q_rx(&dev->mt76, i) { - mt76_queue_rx_reset(dev, i); - } - -- mt76_tx_status_check(&dev->mt76, true); -+ if (dev->reset_cause[RESET_CAUSE_RESET_FAILED] || -+ dev->cur_reset_cause == RESET_CAUSE_RX_PSE_BUSY) -+ mt7603_pse_reset(dev); - -- mt7603_dma_sched_reset(dev); -+ if (!dev->reset_cause[RESET_CAUSE_RESET_FAILED]) { -+ mt7603_mac_dma_start(dev); - -- mt7603_mac_dma_start(dev); -+ mt7603_irq_enable(dev, mask); - -- mt7603_irq_enable(dev, mask); -+ clear_bit(MT76_RESET, &dev->mphy.state); -+ } - --skip_dma_reset: -- clear_bit(MT76_RESET, &dev->mphy.state); - mutex_unlock(&dev->mt76.mutex); - - mt76_worker_enable(&dev->mt76.tx_worker); -@@ -1559,20 +1554,29 @@ static bool mt7603_rx_pse_busy(struct mt7603_dev *dev) - { - u32 addr, val; - -- if (mt76_rr(dev, MT_MCU_DEBUG_RESET) & MT_MCU_DEBUG_RESET_QUEUES) -- return true; -- - if (mt7603_rx_fifo_busy(dev)) -- return false; -+ goto out; - - addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR + MT_CLIENT_STATUS); - mt76_wr(dev, addr, 3); - val = mt76_rr(dev, addr) >> 16; - -- if (is_mt7628(dev) && (val & 0x4001) == 0x4001) -- return true; -+ if (!(val & BIT(0))) -+ return false; - -- return (val & 0x8001) == 0x8001 || (val & 0xe001) == 0xe001; -+ if (is_mt7628(dev)) -+ val &= 0xa000; -+ else -+ val &= 0x8000; -+ if (!val) -+ return false; -+ -+out: -+ if (mt76_rr(dev, MT_INT_SOURCE_CSR) & -+ (MT_INT_RX_DONE(0) | MT_INT_RX_DONE(1))) -+ return false; -+ -+ return true; - } - - static bool -diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h -index 3b901090b29c6..9b84db233aceb 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h -+++ b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h -@@ -462,6 +462,11 @@ enum { - #define MT_WF_SEC_BASE 0x21a00 - #define MT_WF_SEC(ofs) (MT_WF_SEC_BASE + (ofs)) - -+#define MT_WF_CFG_OFF_BASE 0x21e00 -+#define MT_WF_CFG_OFF(ofs) (MT_WF_CFG_OFF_BASE + (ofs)) -+#define MT_WF_CFG_OFF_WOCCR MT_WF_CFG_OFF(0x004) -+#define MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS BIT(4) -+ - #define MT_SEC_SCR MT_WF_SEC(0x004) - #define MT_SEC_SCR_MASK_ORDER GENMASK(1, 0) - -diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c -index bcfc30d669c20..b2ea539f697f7 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c -@@ -988,13 +988,13 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, bool bfee) - { - struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; -- int tx_ant = hweight8(phy->mt76->chainmask) - 1; -+ int sts = hweight16(phy->mt76->chainmask); - - if (vif->type != NL80211_IFTYPE_STATION && - vif->type != NL80211_IFTYPE_AP) - return false; - -- if (!bfee && tx_ant < 2) -+ if (!bfee && sts < 2) - return false; - - if (sta->deflink.he_cap.has_he) { -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c -index 6f61d6a106272..5a34894a533be 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c -@@ -799,7 +799,7 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw) - } - - if (rtlpriv->btcoexist.bt_edca_dl != 0) { -- edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; -+ edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; - bt_change_edca = true; - } - -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c -index 0b6a15c2e5ccd..d92aad60edfe9 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c -@@ -640,7 +640,7 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) - } - - if (rtlpriv->btcoexist.bt_edca_dl != 0) { -- edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; -+ edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; - bt_change_edca = true; - } - -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c -index 8ada31380efa4..0ff8e355c23a4 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c -@@ -466,7 +466,7 @@ static void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw) - } - - if (rtlpriv->btcoexist.bt_edca_dl != 0) { -- edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; -+ edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; - bt_change_edca = true; - } - -diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c -index 9ebe544e51d0d..abd750c3c28e5 100644 ---- a/drivers/net/wireless/realtek/rtw88/debug.c -+++ b/drivers/net/wireless/realtek/rtw88/debug.c -@@ -1191,9 +1191,9 @@ static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { - #define rtw_debugfs_add_core(name, mode, fopname, parent) \ - do { \ - rtw_debug_priv_ ##name.rtwdev = rtwdev; \ -- if (!debugfs_create_file(#name, mode, \ -+ if (IS_ERR(debugfs_create_file(#name, mode, \ - parent, &rtw_debug_priv_ ##name,\ -- &file_ops_ ##fopname)) \ -+ &file_ops_ ##fopname))) \ - pr_debug("Unable to initialize debugfs:%s\n", \ - #name); \ - } while (0) -diff --git a/drivers/net/wireless/silabs/wfx/data_tx.c b/drivers/net/wireless/silabs/wfx/data_tx.c -index 6a5e52a96d183..caa22226b01bc 100644 ---- a/drivers/net/wireless/silabs/wfx/data_tx.c -+++ b/drivers/net/wireless/silabs/wfx/data_tx.c -@@ -226,53 +226,40 @@ static u8 wfx_tx_get_link_id(struct wfx_vif *wvif, struct ieee80211_sta *sta, - - static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates) - { -- int i; -- bool finished; -+ bool has_rate0 = false; -+ int i, j; - -- /* Firmware is not able to mix rates with different flags */ -- for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { -- if (rates[0].flags & IEEE80211_TX_RC_SHORT_GI) -- rates[i].flags |= IEEE80211_TX_RC_SHORT_GI; -- if (!(rates[0].flags & IEEE80211_TX_RC_SHORT_GI)) -+ for (i = 1, j = 1; j < IEEE80211_TX_MAX_RATES; j++) { -+ if (rates[j].idx == -1) -+ break; -+ /* The device use the rates in descending order, whatever the request from minstrel. -+ * We have to trade off here. Most important is to respect the primary rate -+ * requested by minstrel. So, we drops the entries with rate higher than the -+ * previous. -+ */ -+ if (rates[j].idx >= rates[i - 1].idx) { -+ rates[i - 1].count += rates[j].count; -+ rates[i - 1].count = min_t(u16, 15, rates[i - 1].count); -+ } else { -+ memcpy(rates + i, rates + j, sizeof(rates[i])); -+ if (rates[i].idx == 0) -+ has_rate0 = true; -+ /* The device apply Short GI only on the first rate */ - rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI; -- if (!(rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)) -- rates[i].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS; -- } -- -- /* Sort rates and remove duplicates */ -- do { -- finished = true; -- for (i = 0; i < IEEE80211_TX_MAX_RATES - 1; i++) { -- if (rates[i + 1].idx == rates[i].idx && -- rates[i].idx != -1) { -- rates[i].count += rates[i + 1].count; -- if (rates[i].count > 15) -- rates[i].count = 15; -- rates[i + 1].idx = -1; -- rates[i + 1].count = 0; -- -- finished = false; -- } -- if (rates[i + 1].idx > rates[i].idx) { -- swap(rates[i + 1], rates[i]); -- finished = false; -- } -+ i++; - } -- } while (!finished); -+ } - /* Ensure that MCS0 or 1Mbps is present at the end of the retry list */ -- for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { -- if (rates[i].idx == 0) -- break; -- if (rates[i].idx == -1) { -- rates[i].idx = 0; -- rates[i].count = 8; /* == hw->max_rate_tries */ -- rates[i].flags = rates[i - 1].flags & IEEE80211_TX_RC_MCS; -- break; -- } -+ if (!has_rate0 && i < IEEE80211_TX_MAX_RATES) { -+ rates[i].idx = 0; -+ rates[i].count = 8; /* == hw->max_rate_tries */ -+ rates[i].flags = rates[0].flags & IEEE80211_TX_RC_MCS; -+ i++; -+ } -+ for (; i < IEEE80211_TX_MAX_RATES; i++) { -+ memset(rates + i, 0, sizeof(rates[i])); -+ rates[i].idx = -1; - } -- /* All retries use long GI */ -- for (i = 1; i < IEEE80211_TX_MAX_RATES; i++) -- rates[i].flags &= ~IEEE80211_TX_RC_SHORT_GI; - } - - static u8 wfx_tx_get_retry_policy_id(struct wfx_vif *wvif, struct ieee80211_tx_info *tx_info) -diff --git a/drivers/nvdimm/of_pmem.c b/drivers/nvdimm/of_pmem.c -index 10dbdcdfb9ce9..0243789ba914b 100644 ---- a/drivers/nvdimm/of_pmem.c -+++ b/drivers/nvdimm/of_pmem.c -@@ -30,7 +30,13 @@ static int of_pmem_region_probe(struct platform_device *pdev) - if (!priv) - return -ENOMEM; - -- priv->bus_desc.provider_name = kstrdup(pdev->name, GFP_KERNEL); -+ priv->bus_desc.provider_name = devm_kstrdup(&pdev->dev, pdev->name, -+ GFP_KERNEL); -+ if (!priv->bus_desc.provider_name) { -+ kfree(priv); -+ return -ENOMEM; -+ } -+ - priv->bus_desc.module = THIS_MODULE; - priv->bus_desc.of_node = np; - -diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c -index e0875d3697624..7995f93db2a82 100644 ---- a/drivers/nvdimm/region_devs.c -+++ b/drivers/nvdimm/region_devs.c -@@ -892,7 +892,8 @@ unsigned int nd_region_acquire_lane(struct nd_region *nd_region) - { - unsigned int cpu, lane; - -- cpu = get_cpu(); -+ migrate_disable(); -+ cpu = smp_processor_id(); - if (nd_region->num_lanes < nr_cpu_ids) { - struct nd_percpu_lane *ndl_lock, *ndl_count; - -@@ -911,16 +912,15 @@ EXPORT_SYMBOL(nd_region_acquire_lane); - void nd_region_release_lane(struct nd_region *nd_region, unsigned int lane) - { - if (nd_region->num_lanes < nr_cpu_ids) { -- unsigned int cpu = get_cpu(); -+ unsigned int cpu = smp_processor_id(); - struct nd_percpu_lane *ndl_lock, *ndl_count; - - ndl_count = per_cpu_ptr(nd_region->lane, cpu); - ndl_lock = per_cpu_ptr(nd_region->lane, lane); - if (--ndl_count->count == 0) - spin_unlock(&ndl_lock->lock); -- put_cpu(); - } -- put_cpu(); -+ migrate_enable(); - } - EXPORT_SYMBOL(nd_region_release_lane); - -diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c -index b33004a4bcb5a..91e6d03475798 100644 ---- a/drivers/nvme/host/ioctl.c -+++ b/drivers/nvme/host/ioctl.c -@@ -435,10 +435,13 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req, - void *cookie = READ_ONCE(ioucmd->cookie); - - req->bio = pdu->bio; -- if (nvme_req(req)->flags & NVME_REQ_CANCELLED) -+ if (nvme_req(req)->flags & NVME_REQ_CANCELLED) { - pdu->nvme_status = -EINTR; -- else -+ } else { - pdu->nvme_status = nvme_req(req)->status; -+ if (!pdu->nvme_status) -+ pdu->nvme_status = blk_status_to_errno(err); -+ } - pdu->u.result = le64_to_cpu(nvme_req(req)->result.u64); - - /* -diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c -index d4c9b888a79d7..5c35884c226e6 100644 ---- a/drivers/pci/controller/vmd.c -+++ b/drivers/pci/controller/vmd.c -@@ -510,8 +510,7 @@ static void vmd_domain_reset(struct vmd_dev *vmd) - base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus, - PCI_DEVFN(dev, 0), 0); - -- hdr_type = readb(base + PCI_HEADER_TYPE) & -- PCI_HEADER_TYPE_MASK; -+ hdr_type = readb(base + PCI_HEADER_TYPE); - - functions = (hdr_type & 0x80) ? 8 : 1; - for (fn = 0; fn < functions; fn++) { -diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c -index f70197154a362..820cce7c8b400 100644 ---- a/drivers/pcmcia/cs.c -+++ b/drivers/pcmcia/cs.c -@@ -605,6 +605,7 @@ static int pccardd(void *__skt) - dev_warn(&skt->dev, "PCMCIA: unable to register socket\n"); - skt->thread = NULL; - complete(&skt->thread_done); -+ put_device(&skt->dev); - return 0; - } - ret = pccard_sysfs_add_socket(&skt->dev); -diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c -index ace133b9f7d45..2eb81d9484d27 100644 ---- a/drivers/pcmcia/ds.c -+++ b/drivers/pcmcia/ds.c -@@ -513,9 +513,6 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, - /* by default don't allow DMA */ - p_dev->dma_mask = 0; - p_dev->dev.dma_mask = &p_dev->dma_mask; -- dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no); -- if (!dev_name(&p_dev->dev)) -- goto err_free; - p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev)); - if (!p_dev->devname) - goto err_free; -@@ -573,8 +570,15 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, - - pcmcia_device_query(p_dev); - -- if (device_register(&p_dev->dev)) -- goto err_unreg; -+ dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no); -+ if (device_register(&p_dev->dev)) { -+ mutex_lock(&s->ops_mutex); -+ list_del(&p_dev->socket_device_list); -+ s->device_count--; -+ mutex_unlock(&s->ops_mutex); -+ put_device(&p_dev->dev); -+ return NULL; -+ } - - return p_dev; - -diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c -index cfb36adf4eb80..47e7c3206939f 100644 ---- a/drivers/perf/arm-cmn.c -+++ b/drivers/perf/arm-cmn.c -@@ -44,8 +44,11 @@ - #define CMN_MAX_DTMS (CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) * 4) - - /* The CFG node has various info besides the discovery tree */ --#define CMN_CFGM_PERIPH_ID_2 0x0010 --#define CMN_CFGM_PID2_REVISION GENMASK(7, 4) -+#define CMN_CFGM_PERIPH_ID_01 0x0008 -+#define CMN_CFGM_PID0_PART_0 GENMASK_ULL(7, 0) -+#define CMN_CFGM_PID1_PART_1 GENMASK_ULL(35, 32) -+#define CMN_CFGM_PERIPH_ID_23 0x0010 -+#define CMN_CFGM_PID2_REVISION GENMASK_ULL(7, 4) - - #define CMN_CFGM_INFO_GLOBAL 0x900 - #define CMN_INFO_MULTIPLE_DTM_EN BIT_ULL(63) -@@ -107,7 +110,9 @@ - - #define CMN_DTM_PMEVCNTSR 0x240 - --#define CMN_DTM_UNIT_INFO 0x0910 -+#define CMN650_DTM_UNIT_INFO 0x0910 -+#define CMN_DTM_UNIT_INFO 0x0960 -+#define CMN_DTM_UNIT_INFO_DTC_DOMAIN GENMASK_ULL(1, 0) - - #define CMN_DTM_NUM_COUNTERS 4 - /* Want more local counters? Why not replicate the whole DTM! Ugh... */ -@@ -186,6 +191,7 @@ - #define CMN_WP_DOWN 2 - - -+/* Internal values for encoding event support */ - enum cmn_model { - CMN600 = 1, - CMN650 = 2, -@@ -197,26 +203,34 @@ enum cmn_model { - CMN_650ON = CMN650 | CMN700, - }; - -+/* Actual part numbers and revision IDs defined by the hardware */ -+enum cmn_part { -+ PART_CMN600 = 0x434, -+ PART_CMN650 = 0x436, -+ PART_CMN700 = 0x43c, -+ PART_CI700 = 0x43a, -+}; -+ - /* CMN-600 r0px shouldn't exist in silicon, thankfully */ - enum cmn_revision { -- CMN600_R1P0, -- CMN600_R1P1, -- CMN600_R1P2, -- CMN600_R1P3, -- CMN600_R2P0, -- CMN600_R3P0, -- CMN600_R3P1, -- CMN650_R0P0 = 0, -- CMN650_R1P0, -- CMN650_R1P1, -- CMN650_R2P0, -- CMN650_R1P2, -- CMN700_R0P0 = 0, -- CMN700_R1P0, -- CMN700_R2P0, -- CI700_R0P0 = 0, -- CI700_R1P0, -- CI700_R2P0, -+ REV_CMN600_R1P0, -+ REV_CMN600_R1P1, -+ REV_CMN600_R1P2, -+ REV_CMN600_R1P3, -+ REV_CMN600_R2P0, -+ REV_CMN600_R3P0, -+ REV_CMN600_R3P1, -+ REV_CMN650_R0P0 = 0, -+ REV_CMN650_R1P0, -+ REV_CMN650_R1P1, -+ REV_CMN650_R2P0, -+ REV_CMN650_R1P2, -+ REV_CMN700_R0P0 = 0, -+ REV_CMN700_R1P0, -+ REV_CMN700_R2P0, -+ REV_CI700_R0P0 = 0, -+ REV_CI700_R1P0, -+ REV_CI700_R2P0, - }; - - enum cmn_node_type { -@@ -306,7 +320,7 @@ struct arm_cmn { - unsigned int state; - - enum cmn_revision rev; -- enum cmn_model model; -+ enum cmn_part part; - u8 mesh_x; - u8 mesh_y; - u16 num_xps; -@@ -394,19 +408,35 @@ static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn, - return NULL; - } - -+static enum cmn_model arm_cmn_model(const struct arm_cmn *cmn) -+{ -+ switch (cmn->part) { -+ case PART_CMN600: -+ return CMN600; -+ case PART_CMN650: -+ return CMN650; -+ case PART_CMN700: -+ return CMN700; -+ case PART_CI700: -+ return CI700; -+ default: -+ return 0; -+ }; -+} -+ - static u32 arm_cmn_device_connect_info(const struct arm_cmn *cmn, - const struct arm_cmn_node *xp, int port) - { - int offset = CMN_MXP__CONNECT_INFO(port); - - if (port >= 2) { -- if (cmn->model & (CMN600 | CMN650)) -+ if (cmn->part == PART_CMN600 || cmn->part == PART_CMN650) - return 0; - /* - * CI-700 may have extra ports, but still has the - * mesh_port_connect_info registers in the way. - */ -- if (cmn->model == CI700) -+ if (cmn->part == PART_CI700) - offset += CI700_CONNECT_INFO_P2_5_OFFSET; - } - -@@ -640,7 +670,7 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, - - eattr = container_of(attr, typeof(*eattr), attr.attr); - -- if (!(eattr->model & cmn->model)) -+ if (!(eattr->model & arm_cmn_model(cmn))) - return 0; - - type = eattr->type; -@@ -658,7 +688,7 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, - if ((intf & 4) && !(cmn->ports_used & BIT(intf & 3))) - return 0; - -- if (chan == 4 && cmn->model == CMN600) -+ if (chan == 4 && cmn->part == PART_CMN600) - return 0; - - if ((chan == 5 && cmn->rsp_vc_num < 2) || -@@ -669,19 +699,19 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, - } - - /* Revision-specific differences */ -- if (cmn->model == CMN600) { -- if (cmn->rev < CMN600_R1P3) { -+ if (cmn->part == PART_CMN600) { -+ if (cmn->rev < REV_CMN600_R1P3) { - if (type == CMN_TYPE_CXRA && eventid > 0x10) - return 0; - } -- if (cmn->rev < CMN600_R1P2) { -+ if (cmn->rev < REV_CMN600_R1P2) { - if (type == CMN_TYPE_HNF && eventid == 0x1b) - return 0; - if (type == CMN_TYPE_CXRA || type == CMN_TYPE_CXHA) - return 0; - } -- } else if (cmn->model == CMN650) { -- if (cmn->rev < CMN650_R2P0 || cmn->rev == CMN650_R1P2) { -+ } else if (cmn->part == PART_CMN650) { -+ if (cmn->rev < REV_CMN650_R2P0 || cmn->rev == REV_CMN650_R1P2) { - if (type == CMN_TYPE_HNF && eventid > 0x22) - return 0; - if (type == CMN_TYPE_SBSX && eventid == 0x17) -@@ -689,8 +719,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, - if (type == CMN_TYPE_RNI && eventid > 0x10) - return 0; - } -- } else if (cmn->model == CMN700) { -- if (cmn->rev < CMN700_R2P0) { -+ } else if (cmn->part == PART_CMN700) { -+ if (cmn->rev < REV_CMN700_R2P0) { - if (type == CMN_TYPE_HNF && eventid > 0x2c) - return 0; - if (type == CMN_TYPE_CCHA && eventid > 0x74) -@@ -698,7 +728,7 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, - if (type == CMN_TYPE_CCLA && eventid > 0x27) - return 0; - } -- if (cmn->rev < CMN700_R1P0) { -+ if (cmn->rev < REV_CMN700_R1P0) { - if (type == CMN_TYPE_HNF && eventid > 0x2b) - return 0; - } -@@ -1200,7 +1230,7 @@ static u32 arm_cmn_wp_config(struct perf_event *event) - u32 grp = CMN_EVENT_WP_GRP(event); - u32 exc = CMN_EVENT_WP_EXCLUSIVE(event); - u32 combine = CMN_EVENT_WP_COMBINE(event); -- bool is_cmn600 = to_cmn(event->pmu)->model == CMN600; -+ bool is_cmn600 = to_cmn(event->pmu)->part == PART_CMN600; - - config = FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL, dev) | - FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_CHN_SEL, chn) | -@@ -1520,14 +1550,14 @@ done: - return ret; - } - --static enum cmn_filter_select arm_cmn_filter_sel(enum cmn_model model, -+static enum cmn_filter_select arm_cmn_filter_sel(const struct arm_cmn *cmn, - enum cmn_node_type type, - unsigned int eventid) - { - struct arm_cmn_event_attr *e; -- int i; -+ enum cmn_model model = arm_cmn_model(cmn); - -- for (i = 0; i < ARRAY_SIZE(arm_cmn_event_attrs) - 1; i++) { -+ for (int i = 0; i < ARRAY_SIZE(arm_cmn_event_attrs) - 1; i++) { - e = container_of(arm_cmn_event_attrs[i], typeof(*e), attr.attr); - if (e->model & model && e->type == type && e->eventid == eventid) - return e->fsel; -@@ -1570,12 +1600,12 @@ static int arm_cmn_event_init(struct perf_event *event) - /* ...but the DTM may depend on which port we're watching */ - if (cmn->multi_dtm) - hw->dtm_offset = CMN_EVENT_WP_DEV_SEL(event) / 2; -- } else if (type == CMN_TYPE_XP && cmn->model == CMN700) { -+ } else if (type == CMN_TYPE_XP && cmn->part == PART_CMN700) { - hw->wide_sel = true; - } - - /* This is sufficiently annoying to recalculate, so cache it */ -- hw->filter_sel = arm_cmn_filter_sel(cmn->model, type, eventid); -+ hw->filter_sel = arm_cmn_filter_sel(cmn, type, eventid); - - bynodeid = CMN_EVENT_BYNODEID(event); - nodeid = CMN_EVENT_NODEID(event); -@@ -1966,6 +1996,16 @@ static int arm_cmn_init_dtcs(struct arm_cmn *cmn) - return 0; - } - -+static unsigned int arm_cmn_dtc_domain(struct arm_cmn *cmn, void __iomem *xp_region) -+{ -+ int offset = CMN_DTM_UNIT_INFO; -+ -+ if (cmn->part == PART_CMN650 || cmn->part == PART_CI700) -+ offset = CMN650_DTM_UNIT_INFO; -+ -+ return FIELD_GET(CMN_DTM_UNIT_INFO_DTC_DOMAIN, readl_relaxed(xp_region + offset)); -+} -+ - static void arm_cmn_init_node_info(struct arm_cmn *cmn, u32 offset, struct arm_cmn_node *node) - { - int level; -@@ -2006,6 +2046,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) - void __iomem *cfg_region; - struct arm_cmn_node cfg, *dn; - struct arm_cmn_dtm *dtm; -+ enum cmn_part part; - u16 child_count, child_poff; - u32 xp_offset[CMN_MAX_XPS]; - u64 reg; -@@ -2017,7 +2058,19 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) - return -ENODEV; - - cfg_region = cmn->base + rgn_offset; -- reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_2); -+ -+ reg = readq_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_01); -+ part = FIELD_GET(CMN_CFGM_PID0_PART_0, reg); -+ part |= FIELD_GET(CMN_CFGM_PID1_PART_1, reg) << 8; -+ if (cmn->part && cmn->part != part) -+ dev_warn(cmn->dev, -+ "Firmware binding mismatch: expected part number 0x%x, found 0x%x\n", -+ cmn->part, part); -+ cmn->part = part; -+ if (!arm_cmn_model(cmn)) -+ dev_warn(cmn->dev, "Unknown part number: 0x%x\n", part); -+ -+ reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_23); - cmn->rev = FIELD_GET(CMN_CFGM_PID2_REVISION, reg); - - reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL); -@@ -2081,10 +2134,10 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) - if (xp->id == (1 << 3)) - cmn->mesh_x = xp->logid; - -- if (cmn->model == CMN600) -+ if (cmn->part == PART_CMN600) - xp->dtc = 0xf; - else -- xp->dtc = 1 << readl_relaxed(xp_region + CMN_DTM_UNIT_INFO); -+ xp->dtc = 1 << arm_cmn_dtc_domain(cmn, xp_region); - - xp->dtm = dtm - cmn->dtms; - arm_cmn_init_dtm(dtm++, xp, 0); -@@ -2201,7 +2254,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) - if (cmn->num_xps == 1) - dev_warn(cmn->dev, "1x1 config not fully supported, translate XP events manually\n"); - -- dev_dbg(cmn->dev, "model %d, periph_id_2 revision %d\n", cmn->model, cmn->rev); -+ dev_dbg(cmn->dev, "periph_id part 0x%03x revision %d\n", cmn->part, cmn->rev); - reg = cmn->ports_used; - dev_dbg(cmn->dev, "mesh %dx%d, ID width %d, ports %6pbl%s\n", - cmn->mesh_x, cmn->mesh_y, arm_cmn_xyidbits(cmn), ®, -@@ -2256,17 +2309,17 @@ static int arm_cmn_probe(struct platform_device *pdev) - return -ENOMEM; - - cmn->dev = &pdev->dev; -- cmn->model = (unsigned long)device_get_match_data(cmn->dev); -+ cmn->part = (unsigned long)device_get_match_data(cmn->dev); - platform_set_drvdata(pdev, cmn); - -- if (cmn->model == CMN600 && has_acpi_companion(cmn->dev)) { -+ if (cmn->part == PART_CMN600 && has_acpi_companion(cmn->dev)) { - rootnode = arm_cmn600_acpi_probe(pdev, cmn); - } else { - rootnode = 0; - cmn->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(cmn->base)) - return PTR_ERR(cmn->base); -- if (cmn->model == CMN600) -+ if (cmn->part == PART_CMN600) - rootnode = arm_cmn600_of_probe(pdev->dev.of_node); - } - if (rootnode < 0) -@@ -2335,10 +2388,10 @@ static int arm_cmn_remove(struct platform_device *pdev) - - #ifdef CONFIG_OF - static const struct of_device_id arm_cmn_of_match[] = { -- { .compatible = "arm,cmn-600", .data = (void *)CMN600 }, -- { .compatible = "arm,cmn-650", .data = (void *)CMN650 }, -- { .compatible = "arm,cmn-700", .data = (void *)CMN700 }, -- { .compatible = "arm,ci-700", .data = (void *)CI700 }, -+ { .compatible = "arm,cmn-600", .data = (void *)PART_CMN600 }, -+ { .compatible = "arm,cmn-650" }, -+ { .compatible = "arm,cmn-700" }, -+ { .compatible = "arm,ci-700" }, - {} - }; - MODULE_DEVICE_TABLE(of, arm_cmn_of_match); -@@ -2346,9 +2399,9 @@ MODULE_DEVICE_TABLE(of, arm_cmn_of_match); - - #ifdef CONFIG_ACPI - static const struct acpi_device_id arm_cmn_acpi_match[] = { -- { "ARMHC600", CMN600 }, -- { "ARMHC650", CMN650 }, -- { "ARMHC700", CMN700 }, -+ { "ARMHC600", PART_CMN600 }, -+ { "ARMHC650" }, -+ { "ARMHC700" }, - {} - }; - MODULE_DEVICE_TABLE(acpi, arm_cmn_acpi_match); -diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c -index b61f1f9aba214..c4c1cd269c577 100644 ---- a/drivers/perf/hisilicon/hisi_pcie_pmu.c -+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c -@@ -342,6 +342,10 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event) - struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu); - struct hw_perf_event *hwc = &event->hw; - -+ /* Check the type first before going on, otherwise it's not our event */ -+ if (event->attr.type != event->pmu->type) -+ return -ENOENT; -+ - event->cpu = pcie_pmu->on_cpu; - - if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event))) -@@ -349,9 +353,6 @@ static int hisi_pcie_pmu_event_init(struct perf_event *event) - else - hwc->event_base = HISI_PCIE_CNT; - -- if (event->attr.type != event->pmu->type) -- return -ENOENT; -- - /* Sampling is not supported. */ - if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) - return -EOPNOTSUPP; -diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c -index 47d3cc9b6eecd..d385234fa28df 100644 ---- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c -+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c -@@ -416,8 +416,8 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev) - ret = perf_pmu_register(&pa_pmu->pmu, name, -1); - if (ret) { - dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret); -- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, -- &pa_pmu->node); -+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE, -+ &pa_pmu->node); - return ret; - } - -diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c -index b9c79f17230c2..7d363d475deb2 100644 ---- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c -+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c -@@ -450,8 +450,8 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev) - ret = perf_pmu_register(&sllc_pmu->pmu, name, -1); - if (ret) { - dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret); -- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, -- &sllc_pmu->node); -+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE, -+ &sllc_pmu->node); - return ret; - } - -diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c -index e0457d84af6b3..16869bf5bf4cc 100644 ---- a/drivers/perf/hisilicon/hns3_pmu.c -+++ b/drivers/perf/hisilicon/hns3_pmu.c -@@ -1556,8 +1556,8 @@ static int hns3_pmu_init_pmu(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu) - ret = perf_pmu_register(&hns3_pmu->pmu, hns3_pmu->pmu.name, -1); - if (ret) { - pci_err(pdev, "failed to register perf PMU, ret = %d.\n", ret); -- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, -- &hns3_pmu->node); -+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, -+ &hns3_pmu->node); - } - - return ret; -@@ -1568,8 +1568,8 @@ static void hns3_pmu_uninit_pmu(struct pci_dev *pdev) - struct hns3_pmu *hns3_pmu = pci_get_drvdata(pdev); - - perf_pmu_unregister(&hns3_pmu->pmu); -- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, -- &hns3_pmu->node); -+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE, -+ &hns3_pmu->node); - } - - static int hns3_pmu_init_dev(struct pci_dev *pdev) -diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c -index 2a617832a7e60..159812fe1c97c 100644 ---- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c -+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c -@@ -1173,6 +1173,8 @@ static void rzg2l_gpio_irq_disable(struct irq_data *d) - u32 port; - u8 bit; - -+ irq_chip_disable_parent(d); -+ - port = RZG2L_PIN_ID_TO_PORT(hwirq); - bit = RZG2L_PIN_ID_TO_PIN(hwirq); - -@@ -1187,7 +1189,6 @@ static void rzg2l_gpio_irq_disable(struct irq_data *d) - spin_unlock_irqrestore(&pctrl->lock, flags); - - gpiochip_disable_irq(gc, hwirq); -- irq_chip_disable_parent(d); - } - - static void rzg2l_gpio_irq_enable(struct irq_data *d) -diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c -index 2fe6e147785e4..2b79377cc21e2 100644 ---- a/drivers/platform/x86/wmi.c -+++ b/drivers/platform/x86/wmi.c -@@ -849,21 +849,13 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) - } - static int wmi_char_open(struct inode *inode, struct file *filp) - { -- const char *driver_name = filp->f_path.dentry->d_iname; -- struct wmi_block *wblock; -- struct wmi_block *next; -- -- list_for_each_entry_safe(wblock, next, &wmi_block_list, list) { -- if (!wblock->dev.dev.driver) -- continue; -- if (strcmp(driver_name, wblock->dev.dev.driver->name) == 0) { -- filp->private_data = wblock; -- break; -- } -- } -+ /* -+ * The miscdevice already stores a pointer to itself -+ * inside filp->private_data -+ */ -+ struct wmi_block *wblock = container_of(filp->private_data, struct wmi_block, char_dev); - -- if (!filp->private_data) -- return -ENODEV; -+ filp->private_data = wblock; - - return nonseekable_open(inode, filp); - } -@@ -1212,8 +1204,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) - struct wmi_block *wblock, *next; - union acpi_object *obj; - acpi_status status; -- int retval = 0; - u32 i, total; -+ int retval; - - status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out); - if (ACPI_FAILURE(status)) -@@ -1224,8 +1216,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) - return -ENXIO; - - if (obj->type != ACPI_TYPE_BUFFER) { -- retval = -ENXIO; -- goto out_free_pointer; -+ kfree(obj); -+ return -ENXIO; - } - - gblock = (const struct guid_block *)obj->buffer.pointer; -@@ -1240,8 +1232,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) - - wblock = kzalloc(sizeof(*wblock), GFP_KERNEL); - if (!wblock) { -- retval = -ENOMEM; -- break; -+ dev_err(wmi_bus_dev, "Failed to allocate %pUL\n", &gblock[i].guid); -+ continue; - } - - wblock->acpi_device = device; -@@ -1280,9 +1272,9 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) - } - } - --out_free_pointer: -- kfree(out.pointer); -- return retval; -+ kfree(obj); -+ -+ return 0; - } - - /* -diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c -index 3db3f96edf78d..6afd34d651c77 100644 ---- a/drivers/pwm/pwm-brcmstb.c -+++ b/drivers/pwm/pwm-brcmstb.c -@@ -290,7 +290,7 @@ static int brcmstb_pwm_suspend(struct device *dev) - { - struct brcmstb_pwm *p = dev_get_drvdata(dev); - -- clk_disable(p->clk); -+ clk_disable_unprepare(p->clk); - - return 0; - } -@@ -299,7 +299,7 @@ static int brcmstb_pwm_resume(struct device *dev) - { - struct brcmstb_pwm *p = dev_get_drvdata(dev); - -- clk_enable(p->clk); -+ clk_prepare_enable(p->clk); - - return 0; - } -diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c -index 44b1f93256b36..652fdb8dc7bfa 100644 ---- a/drivers/pwm/pwm-sti.c -+++ b/drivers/pwm/pwm-sti.c -@@ -79,6 +79,7 @@ struct sti_pwm_compat_data { - unsigned int cpt_num_devs; - unsigned int max_pwm_cnt; - unsigned int max_prescale; -+ struct sti_cpt_ddata *ddata; - }; - - struct sti_pwm_chip { -@@ -314,7 +315,7 @@ static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, - { - struct sti_pwm_chip *pc = to_sti_pwmchip(chip); - struct sti_pwm_compat_data *cdata = pc->cdata; -- struct sti_cpt_ddata *ddata = pwm_get_chip_data(pwm); -+ struct sti_cpt_ddata *ddata = &cdata->ddata[pwm->hwpwm]; - struct device *dev = pc->dev; - unsigned int effective_ticks; - unsigned long long high, low; -@@ -440,7 +441,7 @@ static irqreturn_t sti_pwm_interrupt(int irq, void *data) - while (cpt_int_stat) { - devicenum = ffs(cpt_int_stat) - 1; - -- ddata = pwm_get_chip_data(&pc->chip.pwms[devicenum]); -+ ddata = &pc->cdata->ddata[devicenum]; - - /* - * Capture input: -@@ -638,30 +639,28 @@ static int sti_pwm_probe(struct platform_device *pdev) - dev_err(dev, "failed to prepare clock\n"); - return ret; - } -+ -+ cdata->ddata = devm_kzalloc(dev, cdata->cpt_num_devs * sizeof(*cdata->ddata), GFP_KERNEL); -+ if (!cdata->ddata) -+ return -ENOMEM; - } - - pc->chip.dev = dev; - pc->chip.ops = &sti_pwm_ops; - pc->chip.npwm = pc->cdata->pwm_num_devs; - -- ret = pwmchip_add(&pc->chip); -- if (ret < 0) { -- clk_unprepare(pc->pwm_clk); -- clk_unprepare(pc->cpt_clk); -- return ret; -- } -- - for (i = 0; i < cdata->cpt_num_devs; i++) { -- struct sti_cpt_ddata *ddata; -- -- ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); -- if (!ddata) -- return -ENOMEM; -+ struct sti_cpt_ddata *ddata = &cdata->ddata[i]; - - init_waitqueue_head(&ddata->wait); - mutex_init(&ddata->lock); -+ } - -- pwm_set_chip_data(&pc->chip.pwms[i], ddata); -+ ret = pwmchip_add(&pc->chip); -+ if (ret < 0) { -+ clk_unprepare(pc->pwm_clk); -+ clk_unprepare(pc->cpt_clk); -+ return ret; - } - - platform_set_drvdata(pdev, pc); -diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c -index a0441b8086712..de7b5db8f7f2d 100644 ---- a/drivers/regulator/mt6358-regulator.c -+++ b/drivers/regulator/mt6358-regulator.c -@@ -655,12 +655,18 @@ static int mt6358_regulator_probe(struct platform_device *pdev) - struct mt6358_regulator_info *mt6358_info; - int i, max_regulator; - -- if (mt6397->chip_id == MT6366_CHIP_ID) { -- max_regulator = MT6366_MAX_REGULATOR; -- mt6358_info = mt6366_regulators; -- } else { -+ switch (mt6397->chip_id) { -+ case MT6358_CHIP_ID: - max_regulator = MT6358_MAX_REGULATOR; - mt6358_info = mt6358_regulators; -+ break; -+ case MT6366_CHIP_ID: -+ max_regulator = MT6366_MAX_REGULATOR; -+ mt6358_info = mt6366_regulators; -+ break; -+ default: -+ dev_err(&pdev->dev, "unsupported chip ID: %d\n", mt6397->chip_id); -+ return -EINVAL; - } - - for (i = 0; i < max_regulator; i++) { -diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c -index c05b722f00605..0d1517cb3c62d 100644 ---- a/drivers/rtc/rtc-pcf85363.c -+++ b/drivers/rtc/rtc-pcf85363.c -@@ -402,7 +402,7 @@ static int pcf85363_probe(struct i2c_client *client) - if (client->irq > 0) { - regmap_write(pcf85363->regmap, CTRL_FLAGS, 0); - regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO, -- PIN_IO_INTA_OUT, PIN_IO_INTAPM); -+ PIN_IO_INTAPM, PIN_IO_INTA_OUT); - ret = devm_request_threaded_irq(&client->dev, client->irq, - NULL, pcf85363_rtc_handle_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, -diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c -index 1a0c0b7289d26..41148b0430df9 100644 ---- a/drivers/scsi/ibmvscsi/ibmvfc.c -+++ b/drivers/scsi/ibmvscsi/ibmvfc.c -@@ -22,7 +22,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -5804,7 +5803,7 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost, - irq_failed: - do { - rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie); -- } while (rtas_busy_delay(rc)); -+ } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); - reg_failed: - LEAVE; - return rc; -diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c -index 85219b5e1f416..bc400669ee022 100644 ---- a/drivers/soc/qcom/llcc-qcom.c -+++ b/drivers/soc/qcom/llcc-qcom.c -@@ -778,6 +778,9 @@ static int qcom_llcc_probe(struct platform_device *pdev) - u32 version; - struct regmap *regmap; - -+ if (!IS_ERR(drv_data)) -+ return -EBUSY; -+ - drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); - if (!drv_data) { - ret = -ENOMEM; -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index d4b969e68c314..946e2186d2448 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -1093,6 +1093,7 @@ config SPI_XTENSA_XTFPGA - config SPI_ZYNQ_QSPI - tristate "Xilinx Zynq QSPI controller" - depends on ARCH_ZYNQ || COMPILE_TEST -+ depends on SPI_MEM - help - This enables support for the Zynq Quad SPI controller - in master mode. -diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c -index c7a4a3606547e..afecf69d3ceba 100644 ---- a/drivers/spi/spi-nxp-fspi.c -+++ b/drivers/spi/spi-nxp-fspi.c -@@ -708,7 +708,7 @@ static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op) - f->memmap_len = len > NXP_FSPI_MIN_IOMAP ? - len : NXP_FSPI_MIN_IOMAP; - -- f->ahb_addr = ioremap_wc(f->memmap_phy + f->memmap_start, -+ f->ahb_addr = ioremap(f->memmap_phy + f->memmap_start, - f->memmap_len); - - if (!f->ahb_addr) { -diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c -index 148043d0c2b84..24cab56ecb7fd 100644 ---- a/drivers/spi/spi-tegra20-slink.c -+++ b/drivers/spi/spi-tegra20-slink.c -@@ -1093,6 +1093,8 @@ static int tegra_slink_probe(struct platform_device *pdev) - reset_control_deassert(tspi->rst); - - spi_irq = platform_get_irq(pdev, 0); -+ if (spi_irq < 0) -+ return spi_irq; - tspi->irq = spi_irq; - ret = request_threaded_irq(tspi->irq, tegra_slink_isr, - tegra_slink_isr_thread, IRQF_ONESHOT, -diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c -index a6470a89851e3..fe5fbf6cf6314 100644 ---- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c -+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c -@@ -172,12 +172,12 @@ int cedrus_hw_suspend(struct device *device) - { - struct cedrus_dev *dev = dev_get_drvdata(device); - -- reset_control_assert(dev->rstc); -- - clk_disable_unprepare(dev->ram_clk); - clk_disable_unprepare(dev->mod_clk); - clk_disable_unprepare(dev->ahb_clk); - -+ reset_control_assert(dev->rstc); -+ - return 0; - } - -@@ -186,11 +186,18 @@ int cedrus_hw_resume(struct device *device) - struct cedrus_dev *dev = dev_get_drvdata(device); - int ret; - -+ ret = reset_control_reset(dev->rstc); -+ if (ret) { -+ dev_err(dev->dev, "Failed to apply reset\n"); -+ -+ return ret; -+ } -+ - ret = clk_prepare_enable(dev->ahb_clk); - if (ret) { - dev_err(dev->dev, "Failed to enable AHB clock\n"); - -- return ret; -+ goto err_rst; - } - - ret = clk_prepare_enable(dev->mod_clk); -@@ -207,21 +214,14 @@ int cedrus_hw_resume(struct device *device) - goto err_mod_clk; - } - -- ret = reset_control_reset(dev->rstc); -- if (ret) { -- dev_err(dev->dev, "Failed to apply reset\n"); -- -- goto err_ram_clk; -- } -- - return 0; - --err_ram_clk: -- clk_disable_unprepare(dev->ram_clk); - err_mod_clk: - clk_disable_unprepare(dev->mod_clk); - err_ahb_clk: - clk_disable_unprepare(dev->ahb_clk); -+err_rst: -+ reset_control_assert(dev->rstc); - - return ret; - } -diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c -index 1eae4ec719a8f..ebb36b2c72d5d 100644 ---- a/drivers/thermal/thermal_core.c -+++ b/drivers/thermal/thermal_core.c -@@ -649,7 +649,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, - if (result) - goto release_ida; - -- sprintf(dev->attr_name, "cdev%d_trip_point", dev->id); -+ snprintf(dev->attr_name, sizeof(dev->attr_name), "cdev%d_trip_point", -+ dev->id); - sysfs_attr_init(&dev->attr.attr); - dev->attr.attr.name = dev->attr_name; - dev->attr.attr.mode = 0444; -@@ -658,7 +659,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, - if (result) - goto remove_symbol_link; - -- sprintf(dev->weight_attr_name, "cdev%d_weight", dev->id); -+ snprintf(dev->weight_attr_name, sizeof(dev->weight_attr_name), -+ "cdev%d_weight", dev->id); - sysfs_attr_init(&dev->weight_attr.attr); - dev->weight_attr.attr.name = dev->weight_attr_name; - dev->weight_attr.attr.mode = S_IWUSR | S_IRUGO; -diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c -index 0d04287da0984..ef8741c3e6629 100644 ---- a/drivers/tty/tty_jobctrl.c -+++ b/drivers/tty/tty_jobctrl.c -@@ -300,12 +300,7 @@ void disassociate_ctty(int on_exit) - return; - } - -- spin_lock_irq(¤t->sighand->siglock); -- put_pid(current->signal->tty_old_pgrp); -- current->signal->tty_old_pgrp = NULL; -- tty = tty_kref_get(current->signal->tty); -- spin_unlock_irq(¤t->sighand->siglock); -- -+ tty = get_current_tty(); - if (tty) { - unsigned long flags; - -@@ -320,6 +315,16 @@ void disassociate_ctty(int on_exit) - tty_kref_put(tty); - } - -+ /* If tty->ctrl.pgrp is not NULL, it may be assigned to -+ * current->signal->tty_old_pgrp in a race condition, and -+ * cause pid memleak. Release current->signal->tty_old_pgrp -+ * after tty->ctrl.pgrp set to NULL. -+ */ -+ spin_lock_irq(¤t->sighand->siglock); -+ put_pid(current->signal->tty_old_pgrp); -+ current->signal->tty_old_pgrp = NULL; -+ spin_unlock_irq(¤t->sighand->siglock); -+ - /* Now clear signal->tty under the lock */ - read_lock(&tasklist_lock); - session_clear_tty(task_session(current)); -diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c -index 6ba4ef2c3949e..dc38d1fa77874 100644 ---- a/drivers/ufs/core/ufshcd.c -+++ b/drivers/ufs/core/ufshcd.c -@@ -3579,7 +3579,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, - */ - ret = utf16s_to_utf8s(uc_str->uc, - uc_str->len - QUERY_DESC_HDR_SIZE, -- UTF16_BIG_ENDIAN, str, ascii_len); -+ UTF16_BIG_ENDIAN, str, ascii_len - 1); - - /* replace non-printable or non-ASCII characters with spaces */ - for (i = 0; i < ret; i++) -diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c -index 3b08c5e811707..34bbdfadd66f3 100644 ---- a/drivers/usb/chipidea/host.c -+++ b/drivers/usb/chipidea/host.c -@@ -30,8 +30,7 @@ struct ehci_ci_priv { - }; - - struct ci_hdrc_dma_aligned_buffer { -- void *kmalloc_ptr; -- void *old_xfer_buffer; -+ void *original_buffer; - u8 data[]; - }; - -@@ -380,59 +379,52 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd) - return 0; - } - --static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb) -+static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb, bool copy_back) - { - struct ci_hdrc_dma_aligned_buffer *temp; -- size_t length; - - if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) - return; -+ urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; - - temp = container_of(urb->transfer_buffer, - struct ci_hdrc_dma_aligned_buffer, data); -+ urb->transfer_buffer = temp->original_buffer; -+ -+ if (copy_back && usb_urb_dir_in(urb)) { -+ size_t length; - -- if (usb_urb_dir_in(urb)) { - if (usb_pipeisoc(urb->pipe)) - length = urb->transfer_buffer_length; - else - length = urb->actual_length; - -- memcpy(temp->old_xfer_buffer, temp->data, length); -+ memcpy(temp->original_buffer, temp->data, length); - } -- urb->transfer_buffer = temp->old_xfer_buffer; -- kfree(temp->kmalloc_ptr); - -- urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; -+ kfree(temp); - } - - static int ci_hdrc_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) - { -- struct ci_hdrc_dma_aligned_buffer *temp, *kmalloc_ptr; -- const unsigned int ci_hdrc_usb_dma_align = 32; -- size_t kmalloc_size; -+ struct ci_hdrc_dma_aligned_buffer *temp; - -- if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0 || -- !((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1))) -+ if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0) -+ return 0; -+ if (IS_ALIGNED((uintptr_t)urb->transfer_buffer, 4) -+ && IS_ALIGNED(urb->transfer_buffer_length, 4)) - return 0; - -- /* Allocate a buffer with enough padding for alignment */ -- kmalloc_size = urb->transfer_buffer_length + -- sizeof(struct ci_hdrc_dma_aligned_buffer) + -- ci_hdrc_usb_dma_align - 1; -- -- kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); -- if (!kmalloc_ptr) -+ temp = kmalloc(sizeof(*temp) + ALIGN(urb->transfer_buffer_length, 4), mem_flags); -+ if (!temp) - return -ENOMEM; - -- /* Position our struct dma_aligned_buffer such that data is aligned */ -- temp = PTR_ALIGN(kmalloc_ptr + 1, ci_hdrc_usb_dma_align) - 1; -- temp->kmalloc_ptr = kmalloc_ptr; -- temp->old_xfer_buffer = urb->transfer_buffer; - if (usb_urb_dir_out(urb)) - memcpy(temp->data, urb->transfer_buffer, - urb->transfer_buffer_length); -- urb->transfer_buffer = temp->data; - -+ temp->original_buffer = urb->transfer_buffer; -+ urb->transfer_buffer = temp->data; - urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER; - - return 0; -@@ -449,7 +441,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, - - ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); - if (ret) -- ci_hdrc_free_dma_aligned_buffer(urb); -+ ci_hdrc_free_dma_aligned_buffer(urb, false); - - return ret; - } -@@ -457,7 +449,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, - static void ci_hdrc_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) - { - usb_hcd_unmap_urb_for_dma(hcd, urb); -- ci_hdrc_free_dma_aligned_buffer(urb); -+ ci_hdrc_free_dma_aligned_buffer(urb, true); - } - - int ci_hdrc_host_init(struct ci_hdrc *ci) -diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c -index 657f1f659ffaf..35c7a4df8e717 100644 ---- a/drivers/usb/dwc2/hcd.c -+++ b/drivers/usb/dwc2/hcd.c -@@ -4769,8 +4769,8 @@ fail3: - if (qh_allocated && qh->channel && qh->channel->qh == qh) - qh->channel->qh = NULL; - fail2: -- spin_unlock_irqrestore(&hsotg->lock, flags); - urb->hcpriv = NULL; -+ spin_unlock_irqrestore(&hsotg->lock, flags); - kfree(qtd); - fail1: - if (qh_allocated) { -diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c -index 2aed88c28ef69..c4dd648710ae0 100644 ---- a/drivers/usb/host/xhci-pci.c -+++ b/drivers/usb/host/xhci-pci.c -@@ -348,6 +348,8 @@ 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/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c -index 5fb55bf194931..c9a101f0e8d01 100644 ---- a/drivers/usb/host/xhci-plat.c -+++ b/drivers/usb/host/xhci-plat.c -@@ -456,23 +456,38 @@ static int __maybe_unused xhci_plat_resume(struct device *dev) - int ret; - - if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { -- clk_prepare_enable(xhci->clk); -- clk_prepare_enable(xhci->reg_clk); -+ ret = clk_prepare_enable(xhci->clk); -+ if (ret) -+ return ret; -+ -+ ret = clk_prepare_enable(xhci->reg_clk); -+ if (ret) { -+ clk_disable_unprepare(xhci->clk); -+ return ret; -+ } - } - - ret = xhci_priv_resume_quirk(hcd); - if (ret) -- return ret; -+ goto disable_clks; - - ret = xhci_resume(xhci, 0); - if (ret) -- return ret; -+ goto disable_clks; - - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - return 0; -+ -+disable_clks: -+ if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { -+ clk_disable_unprepare(xhci->clk); -+ clk_disable_unprepare(xhci->reg_clk); -+ } -+ -+ return ret; - } - - static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev) -diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c -index 3c6d452e3bf40..4104eea03e806 100644 ---- a/drivers/usb/usbip/stub_dev.c -+++ b/drivers/usb/usbip/stub_dev.c -@@ -462,8 +462,13 @@ static void stub_disconnect(struct usb_device *udev) - /* release port */ - rc = usb_hub_release_port(udev->parent, udev->portnum, - (struct usb_dev_state *) udev); -- if (rc) { -- dev_dbg(&udev->dev, "unable to release port\n"); -+ /* -+ * NOTE: If a HUB disconnect triggered disconnect of the down stream -+ * device usb_hub_release_port will return -ENODEV so we can safely ignore -+ * that error here. -+ */ -+ if (rc && (rc != -ENODEV)) { -+ dev_dbg(&udev->dev, "unable to release port (%i)\n", rc); - return; - } - -diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c -index a2b3743723639..1f3b89c885cca 100644 ---- a/drivers/vhost/vsock.c -+++ b/drivers/vhost/vsock.c -@@ -51,8 +51,7 @@ struct vhost_vsock { - struct hlist_node hash; - - struct vhost_work send_pkt_work; -- spinlock_t send_pkt_list_lock; -- struct list_head send_pkt_list; /* host->guest pending packets */ -+ struct sk_buff_head send_pkt_queue; /* host->guest pending packets */ - - atomic_t queued_replies; - -@@ -108,40 +107,31 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock, - vhost_disable_notify(&vsock->dev, vq); - - do { -- struct virtio_vsock_pkt *pkt; -+ struct virtio_vsock_hdr *hdr; -+ size_t iov_len, payload_len; - struct iov_iter iov_iter; -+ u32 flags_to_restore = 0; -+ struct sk_buff *skb; - unsigned out, in; - size_t nbytes; -- size_t iov_len, payload_len; - int head; -- u32 flags_to_restore = 0; - -- spin_lock_bh(&vsock->send_pkt_list_lock); -- if (list_empty(&vsock->send_pkt_list)) { -- spin_unlock_bh(&vsock->send_pkt_list_lock); -+ skb = virtio_vsock_skb_dequeue(&vsock->send_pkt_queue); -+ -+ if (!skb) { - vhost_enable_notify(&vsock->dev, vq); - break; - } - -- pkt = list_first_entry(&vsock->send_pkt_list, -- struct virtio_vsock_pkt, list); -- list_del_init(&pkt->list); -- spin_unlock_bh(&vsock->send_pkt_list_lock); -- - head = vhost_get_vq_desc(vq, vq->iov, ARRAY_SIZE(vq->iov), - &out, &in, NULL, NULL); - if (head < 0) { -- spin_lock_bh(&vsock->send_pkt_list_lock); -- list_add(&pkt->list, &vsock->send_pkt_list); -- spin_unlock_bh(&vsock->send_pkt_list_lock); -+ virtio_vsock_skb_queue_head(&vsock->send_pkt_queue, skb); - break; - } - - if (head == vq->num) { -- spin_lock_bh(&vsock->send_pkt_list_lock); -- list_add(&pkt->list, &vsock->send_pkt_list); -- spin_unlock_bh(&vsock->send_pkt_list_lock); -- -+ virtio_vsock_skb_queue_head(&vsock->send_pkt_queue, skb); - /* We cannot finish yet if more buffers snuck in while - * re-enabling notify. - */ -@@ -153,26 +143,27 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock, - } - - if (out) { -- virtio_transport_free_pkt(pkt); -+ kfree_skb(skb); - vq_err(vq, "Expected 0 output buffers, got %u\n", out); - break; - } - - iov_len = iov_length(&vq->iov[out], in); -- if (iov_len < sizeof(pkt->hdr)) { -- virtio_transport_free_pkt(pkt); -+ if (iov_len < sizeof(*hdr)) { -+ kfree_skb(skb); - vq_err(vq, "Buffer len [%zu] too small\n", iov_len); - break; - } - - iov_iter_init(&iov_iter, ITER_DEST, &vq->iov[out], in, iov_len); -- payload_len = pkt->len - pkt->off; -+ payload_len = skb->len; -+ hdr = virtio_vsock_hdr(skb); - - /* If the packet is greater than the space available in the - * buffer, we split it using multiple buffers. - */ -- if (payload_len > iov_len - sizeof(pkt->hdr)) { -- payload_len = iov_len - sizeof(pkt->hdr); -+ if (payload_len > iov_len - sizeof(*hdr)) { -+ payload_len = iov_len - sizeof(*hdr); - - /* As we are copying pieces of large packet's buffer to - * small rx buffers, headers of packets in rx queue are -@@ -185,31 +176,30 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock, - * bits set. After initialized header will be copied to - * rx buffer, these required bits will be restored. - */ -- if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SEQ_EOM) { -- pkt->hdr.flags &= ~cpu_to_le32(VIRTIO_VSOCK_SEQ_EOM); -+ if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM) { -+ hdr->flags &= ~cpu_to_le32(VIRTIO_VSOCK_SEQ_EOM); - flags_to_restore |= VIRTIO_VSOCK_SEQ_EOM; - -- if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SEQ_EOR) { -- pkt->hdr.flags &= ~cpu_to_le32(VIRTIO_VSOCK_SEQ_EOR); -+ if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOR) { -+ hdr->flags &= ~cpu_to_le32(VIRTIO_VSOCK_SEQ_EOR); - flags_to_restore |= VIRTIO_VSOCK_SEQ_EOR; - } - } - } - - /* Set the correct length in the header */ -- pkt->hdr.len = cpu_to_le32(payload_len); -+ hdr->len = cpu_to_le32(payload_len); - -- nbytes = copy_to_iter(&pkt->hdr, sizeof(pkt->hdr), &iov_iter); -- if (nbytes != sizeof(pkt->hdr)) { -- virtio_transport_free_pkt(pkt); -+ nbytes = copy_to_iter(hdr, sizeof(*hdr), &iov_iter); -+ if (nbytes != sizeof(*hdr)) { -+ kfree_skb(skb); - vq_err(vq, "Faulted on copying pkt hdr\n"); - break; - } - -- nbytes = copy_to_iter(pkt->buf + pkt->off, payload_len, -- &iov_iter); -+ nbytes = copy_to_iter(skb->data, payload_len, &iov_iter); - if (nbytes != payload_len) { -- virtio_transport_free_pkt(pkt); -+ kfree_skb(skb); - vq_err(vq, "Faulted on copying pkt buf\n"); - break; - } -@@ -217,31 +207,28 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock, - /* Deliver to monitoring devices all packets that we - * will transmit. - */ -- virtio_transport_deliver_tap_pkt(pkt); -+ virtio_transport_deliver_tap_pkt(skb); - -- vhost_add_used(vq, head, sizeof(pkt->hdr) + payload_len); -+ vhost_add_used(vq, head, sizeof(*hdr) + payload_len); - added = true; - -- pkt->off += payload_len; -+ skb_pull(skb, payload_len); - total_len += payload_len; - - /* If we didn't send all the payload we can requeue the packet - * to send it with the next available buffer. - */ -- if (pkt->off < pkt->len) { -- pkt->hdr.flags |= cpu_to_le32(flags_to_restore); -+ if (skb->len > 0) { -+ hdr->flags |= cpu_to_le32(flags_to_restore); - -- /* We are queueing the same virtio_vsock_pkt to handle -+ /* We are queueing the same skb to handle - * the remaining bytes, and we want to deliver it - * to monitoring devices in the next iteration. - */ -- pkt->tap_delivered = false; -- -- spin_lock_bh(&vsock->send_pkt_list_lock); -- list_add(&pkt->list, &vsock->send_pkt_list); -- spin_unlock_bh(&vsock->send_pkt_list_lock); -+ virtio_vsock_skb_clear_tap_delivered(skb); -+ virtio_vsock_skb_queue_head(&vsock->send_pkt_queue, skb); - } else { -- if (pkt->reply) { -+ if (virtio_vsock_skb_reply(skb)) { - int val; - - val = atomic_dec_return(&vsock->queued_replies); -@@ -253,7 +240,7 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock, - restart_tx = true; - } - -- virtio_transport_free_pkt(pkt); -+ consume_skb(skb); - } - } while(likely(!vhost_exceeds_weight(vq, ++pkts, total_len))); - if (added) -@@ -278,28 +265,26 @@ static void vhost_transport_send_pkt_work(struct vhost_work *work) - } - - static int --vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt) -+vhost_transport_send_pkt(struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct vhost_vsock *vsock; -- int len = pkt->len; -+ int len = skb->len; - - rcu_read_lock(); - - /* Find the vhost_vsock according to guest context id */ -- vsock = vhost_vsock_get(le64_to_cpu(pkt->hdr.dst_cid)); -+ vsock = vhost_vsock_get(le64_to_cpu(hdr->dst_cid)); - if (!vsock) { - rcu_read_unlock(); -- virtio_transport_free_pkt(pkt); -+ kfree_skb(skb); - return -ENODEV; - } - -- if (pkt->reply) -+ if (virtio_vsock_skb_reply(skb)) - atomic_inc(&vsock->queued_replies); - -- spin_lock_bh(&vsock->send_pkt_list_lock); -- list_add_tail(&pkt->list, &vsock->send_pkt_list); -- spin_unlock_bh(&vsock->send_pkt_list_lock); -- -+ virtio_vsock_skb_queue_tail(&vsock->send_pkt_queue, skb); - vhost_work_queue(&vsock->dev, &vsock->send_pkt_work); - - rcu_read_unlock(); -@@ -310,10 +295,8 @@ static int - vhost_transport_cancel_pkt(struct vsock_sock *vsk) - { - struct vhost_vsock *vsock; -- struct virtio_vsock_pkt *pkt, *n; - int cnt = 0; - int ret = -ENODEV; -- LIST_HEAD(freeme); - - rcu_read_lock(); - -@@ -322,20 +305,7 @@ vhost_transport_cancel_pkt(struct vsock_sock *vsk) - if (!vsock) - goto out; - -- spin_lock_bh(&vsock->send_pkt_list_lock); -- list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) { -- if (pkt->vsk != vsk) -- continue; -- list_move(&pkt->list, &freeme); -- } -- spin_unlock_bh(&vsock->send_pkt_list_lock); -- -- list_for_each_entry_safe(pkt, n, &freeme, list) { -- if (pkt->reply) -- cnt++; -- list_del(&pkt->list); -- virtio_transport_free_pkt(pkt); -- } -+ cnt = virtio_transport_purge_skbs(vsk, &vsock->send_pkt_queue); - - if (cnt) { - struct vhost_virtqueue *tx_vq = &vsock->vqs[VSOCK_VQ_TX]; -@@ -352,12 +322,14 @@ out: - return ret; - } - --static struct virtio_vsock_pkt * --vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq, -+static struct sk_buff * -+vhost_vsock_alloc_skb(struct vhost_virtqueue *vq, - unsigned int out, unsigned int in) - { -- struct virtio_vsock_pkt *pkt; -+ struct virtio_vsock_hdr *hdr; - struct iov_iter iov_iter; -+ struct sk_buff *skb; -+ size_t payload_len; - size_t nbytes; - size_t len; - -@@ -366,50 +338,48 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq, - return NULL; - } - -- pkt = kzalloc(sizeof(*pkt), GFP_KERNEL); -- if (!pkt) -+ len = iov_length(vq->iov, out); -+ -+ /* len contains both payload and hdr */ -+ skb = virtio_vsock_alloc_skb(len, GFP_KERNEL); -+ if (!skb) - return NULL; - -- len = iov_length(vq->iov, out); - iov_iter_init(&iov_iter, ITER_SOURCE, vq->iov, out, len); - -- nbytes = copy_from_iter(&pkt->hdr, sizeof(pkt->hdr), &iov_iter); -- if (nbytes != sizeof(pkt->hdr)) { -+ hdr = virtio_vsock_hdr(skb); -+ nbytes = copy_from_iter(hdr, sizeof(*hdr), &iov_iter); -+ if (nbytes != sizeof(*hdr)) { - vq_err(vq, "Expected %zu bytes for pkt->hdr, got %zu bytes\n", -- sizeof(pkt->hdr), nbytes); -- kfree(pkt); -+ sizeof(*hdr), nbytes); -+ kfree_skb(skb); - return NULL; - } - -- pkt->len = le32_to_cpu(pkt->hdr.len); -+ payload_len = le32_to_cpu(hdr->len); - - /* No payload */ -- if (!pkt->len) -- return pkt; -+ if (!payload_len) -+ return skb; - -- /* The pkt is too big */ -- if (pkt->len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE) { -- kfree(pkt); -+ /* The pkt is too big or the length in the header is invalid */ -+ if (payload_len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE || -+ payload_len + sizeof(*hdr) > len) { -+ kfree_skb(skb); - return NULL; - } - -- pkt->buf = kvmalloc(pkt->len, GFP_KERNEL); -- if (!pkt->buf) { -- kfree(pkt); -- return NULL; -- } -+ virtio_vsock_skb_rx_put(skb); - -- pkt->buf_len = pkt->len; -- -- nbytes = copy_from_iter(pkt->buf, pkt->len, &iov_iter); -- if (nbytes != pkt->len) { -- vq_err(vq, "Expected %u byte payload, got %zu bytes\n", -- pkt->len, nbytes); -- virtio_transport_free_pkt(pkt); -+ nbytes = copy_from_iter(skb->data, payload_len, &iov_iter); -+ if (nbytes != payload_len) { -+ vq_err(vq, "Expected %zu byte payload, got %zu bytes\n", -+ payload_len, nbytes); -+ kfree_skb(skb); - return NULL; - } - -- return pkt; -+ return skb; - } - - /* Is there space left for replies to rx packets? */ -@@ -496,9 +466,9 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) - poll.work); - struct vhost_vsock *vsock = container_of(vq->dev, struct vhost_vsock, - dev); -- struct virtio_vsock_pkt *pkt; - int head, pkts = 0, total_len = 0; - unsigned int out, in; -+ struct sk_buff *skb; - bool added = false; - - mutex_lock(&vq->mutex); -@@ -511,6 +481,8 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) - - vhost_disable_notify(&vsock->dev, vq); - do { -+ struct virtio_vsock_hdr *hdr; -+ - if (!vhost_vsock_more_replies(vsock)) { - /* Stop tx until the device processes already - * pending replies. Leave tx virtqueue -@@ -532,24 +504,26 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) - break; - } - -- pkt = vhost_vsock_alloc_pkt(vq, out, in); -- if (!pkt) { -+ skb = vhost_vsock_alloc_skb(vq, out, in); -+ if (!skb) { - vq_err(vq, "Faulted on pkt\n"); - continue; - } - -- total_len += sizeof(pkt->hdr) + pkt->len; -+ total_len += sizeof(*hdr) + skb->len; - - /* Deliver to monitoring devices all received packets */ -- virtio_transport_deliver_tap_pkt(pkt); -+ virtio_transport_deliver_tap_pkt(skb); -+ -+ hdr = virtio_vsock_hdr(skb); - - /* Only accept correctly addressed packets */ -- if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid && -- le64_to_cpu(pkt->hdr.dst_cid) == -+ if (le64_to_cpu(hdr->src_cid) == vsock->guest_cid && -+ le64_to_cpu(hdr->dst_cid) == - vhost_transport_get_local_cid()) -- virtio_transport_recv_pkt(&vhost_transport, pkt); -+ virtio_transport_recv_pkt(&vhost_transport, skb); - else -- virtio_transport_free_pkt(pkt); -+ kfree_skb(skb); - - vhost_add_used(vq, head, 0); - added = true; -@@ -693,8 +667,7 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) - VHOST_VSOCK_WEIGHT, true, NULL); - - file->private_data = vsock; -- spin_lock_init(&vsock->send_pkt_list_lock); -- INIT_LIST_HEAD(&vsock->send_pkt_list); -+ skb_queue_head_init(&vsock->send_pkt_queue); - vhost_work_init(&vsock->send_pkt_work, vhost_transport_send_pkt_work); - return 0; - -@@ -760,16 +733,7 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) - vhost_vsock_flush(vsock); - vhost_dev_stop(&vsock->dev); - -- spin_lock_bh(&vsock->send_pkt_list_lock); -- while (!list_empty(&vsock->send_pkt_list)) { -- struct virtio_vsock_pkt *pkt; -- -- pkt = list_first_entry(&vsock->send_pkt_list, -- struct virtio_vsock_pkt, list); -- list_del_init(&pkt->list); -- virtio_transport_free_pkt(pkt); -- } -- spin_unlock_bh(&vsock->send_pkt_list_lock); -+ virtio_vsock_skb_queue_purge(&vsock->send_pkt_queue); - - vhost_dev_cleanup(&vsock->dev); - kfree(vsock->dev.vqs); -diff --git a/drivers/video/fbdev/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c -index e332017c6af62..ce3c5b0b8f4ef 100644 ---- a/drivers/video/fbdev/fsl-diu-fb.c -+++ b/drivers/video/fbdev/fsl-diu-fb.c -@@ -490,7 +490,7 @@ static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s) - * Workaround for failed writing desc register of planes. - * Needed with MPC5121 DIU rev 2.0 silicon. - */ --void wr_reg_wa(u32 *reg, u32 val) -+static void wr_reg_wa(u32 *reg, u32 val) - { - do { - out_be32(reg, val); -diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c -index e6adb2890ecfe..b194e71f07bfc 100644 ---- a/drivers/video/fbdev/imsttfb.c -+++ b/drivers/video/fbdev/imsttfb.c -@@ -1495,8 +1495,8 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - - if (!request_mem_region(addr, size, "imsttfb")) { - printk(KERN_ERR "imsttfb: Can't reserve memory region\n"); -- framebuffer_release(info); -- return -ENODEV; -+ ret = -ENODEV; -+ goto release_info; - } - - switch (pdev->device) { -@@ -1513,34 +1513,39 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - printk(KERN_INFO "imsttfb: Device 0x%x unknown, " - "contact maintainer.\n", pdev->device); - ret = -ENODEV; -- goto error; -+ goto release_mem_region; - } - - info->fix.smem_start = addr; - info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? - 0x400000 : 0x800000); - if (!info->screen_base) -- goto error; -+ goto release_mem_region; - info->fix.mmio_start = addr + 0x800000; - par->dc_regs = ioremap(addr + 0x800000, 0x1000); - if (!par->dc_regs) -- goto error; -+ goto unmap_screen_base; - par->cmap_regs_phys = addr + 0x840000; - par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000); - if (!par->cmap_regs) -- goto error; -+ goto unmap_dc_regs; - info->pseudo_palette = par->palette; - ret = init_imstt(info); -- if (!ret) -- pci_set_drvdata(pdev, info); -- return ret; -+ if (ret) -+ goto unmap_cmap_regs; - --error: -- if (par->dc_regs) -- iounmap(par->dc_regs); -- if (info->screen_base) -- iounmap(info->screen_base); -+ pci_set_drvdata(pdev, info); -+ return 0; -+ -+unmap_cmap_regs: -+ iounmap(par->cmap_regs); -+unmap_dc_regs: -+ iounmap(par->dc_regs); -+unmap_screen_base: -+ iounmap(info->screen_base); -+release_mem_region: - release_mem_region(addr, size); -+release_info: - framebuffer_release(info); - return ret; - } -diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c -index 9e172f66a8edb..c47e54b2a865e 100644 ---- a/drivers/virt/coco/sev-guest/sev-guest.c -+++ b/drivers/virt/coco/sev-guest/sev-guest.c -@@ -57,6 +57,11 @@ struct snp_guest_dev { - - struct snp_secrets_page_layout *layout; - struct snp_req_data input; -+ union { -+ struct snp_report_req report; -+ struct snp_derived_key_req derived_key; -+ struct snp_ext_report_req ext_report; -+ } req; - u32 *os_area_msg_seqno; - u8 *vmpck; - }; -@@ -334,11 +339,12 @@ static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 - return __enc_payload(snp_dev, req, payload, sz); - } - --static int __handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, __u64 *fw_err) -+static int __handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, -+ struct snp_guest_request_ioctl *rio) - { -- unsigned long err = 0xff, override_err = 0; - unsigned long req_start = jiffies; - unsigned int override_npages = 0; -+ u64 override_err = 0; - int rc; - - retry_request: -@@ -348,7 +354,7 @@ retry_request: - * sequence number must be incremented or the VMPCK must be deleted to - * prevent reuse of the IV. - */ -- rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err); -+ rc = snp_issue_guest_request(exit_code, &snp_dev->input, rio); - switch (rc) { - case -ENOSPC: - /* -@@ -366,7 +372,7 @@ retry_request: - * request buffer size was too small and give the caller the - * required buffer size. - */ -- override_err = SNP_GUEST_REQ_INVALID_LEN; -+ override_err = SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN); - - /* - * If this call to the firmware succeeds, the sequence number can -@@ -379,7 +385,7 @@ retry_request: - goto retry_request; - - /* -- * The host may return SNP_GUEST_REQ_ERR_EBUSY if the request has been -+ * The host may return SNP_GUEST_VMM_ERR_BUSY if the request has been - * throttled. Retry in the driver to avoid returning and reusing the - * message sequence number on a different message. - */ -@@ -400,27 +406,29 @@ retry_request: - */ - snp_inc_msg_seqno(snp_dev); - -- if (fw_err) -- *fw_err = override_err ?: err; -+ if (override_err) { -+ rio->exitinfo2 = override_err; -+ -+ /* -+ * If an extended guest request was issued and the supplied certificate -+ * buffer was not large enough, a standard guest request was issued to -+ * prevent IV reuse. If the standard request was successful, return -EIO -+ * back to the caller as would have originally been returned. -+ */ -+ if (!rc && override_err == SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN)) -+ rc = -EIO; -+ } - - if (override_npages) - snp_dev->input.data_npages = override_npages; - -- /* -- * If an extended guest request was issued and the supplied certificate -- * buffer was not large enough, a standard guest request was issued to -- * prevent IV reuse. If the standard request was successful, return -EIO -- * back to the caller as would have originally been returned. -- */ -- if (!rc && override_err == SNP_GUEST_REQ_INVALID_LEN) -- return -EIO; -- - return rc; - } - --static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, int msg_ver, -- u8 type, void *req_buf, size_t req_sz, void *resp_buf, -- u32 resp_sz, __u64 *fw_err) -+static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, -+ struct snp_guest_request_ioctl *rio, u8 type, -+ void *req_buf, size_t req_sz, void *resp_buf, -+ u32 resp_sz) - { - u64 seqno; - int rc; -@@ -434,7 +442,7 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in - memset(snp_dev->response, 0, sizeof(struct snp_guest_msg)); - - /* Encrypt the userspace provided payload in snp_dev->secret_request. */ -- rc = enc_payload(snp_dev, seqno, msg_ver, type, req_buf, req_sz); -+ rc = enc_payload(snp_dev, seqno, rio->msg_version, type, req_buf, req_sz); - if (rc) - return rc; - -@@ -445,12 +453,16 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in - memcpy(snp_dev->request, &snp_dev->secret_request, - sizeof(snp_dev->secret_request)); - -- rc = __handle_guest_request(snp_dev, exit_code, fw_err); -+ rc = __handle_guest_request(snp_dev, exit_code, rio); - if (rc) { -- if (rc == -EIO && *fw_err == SNP_GUEST_REQ_INVALID_LEN) -+ if (rc == -EIO && -+ rio->exitinfo2 == SNP_GUEST_VMM_ERR(SNP_GUEST_VMM_ERR_INVALID_LEN)) - return rc; - -- dev_alert(snp_dev->dev, "Detected error from ASP request. rc: %d, fw_err: %llu\n", rc, *fw_err); -+ dev_alert(snp_dev->dev, -+ "Detected error from ASP request. rc: %d, exitinfo2: 0x%llx\n", -+ rc, rio->exitinfo2); -+ - snp_disable_vmpck(snp_dev); - return rc; - } -@@ -468,8 +480,8 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in - static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) - { - struct snp_guest_crypto *crypto = snp_dev->crypto; -+ struct snp_report_req *req = &snp_dev->req.report; - struct snp_report_resp *resp; -- struct snp_report_req req; - int rc, resp_len; - - lockdep_assert_held(&snp_cmd_mutex); -@@ -477,7 +489,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io - if (!arg->req_data || !arg->resp_data) - return -EINVAL; - -- if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) -+ if (copy_from_user(req, (void __user *)arg->req_data, sizeof(*req))) - return -EFAULT; - - /* -@@ -490,9 +502,9 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io - if (!resp) - return -ENOMEM; - -- rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg->msg_version, -- SNP_MSG_REPORT_REQ, &req, sizeof(req), resp->data, -- resp_len, &arg->fw_err); -+ rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg, -+ SNP_MSG_REPORT_REQ, req, sizeof(*req), resp->data, -+ resp_len); - if (rc) - goto e_free; - -@@ -506,9 +518,9 @@ e_free: - - static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) - { -+ struct snp_derived_key_req *req = &snp_dev->req.derived_key; - struct snp_guest_crypto *crypto = snp_dev->crypto; - struct snp_derived_key_resp resp = {0}; -- struct snp_derived_key_req req; - int rc, resp_len; - /* Response data is 64 bytes and max authsize for GCM is 16 bytes. */ - u8 buf[64 + 16]; -@@ -527,12 +539,11 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque - if (sizeof(buf) < resp_len) - return -ENOMEM; - -- if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) -+ if (copy_from_user(req, (void __user *)arg->req_data, sizeof(*req))) - return -EFAULT; - -- rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg->msg_version, -- SNP_MSG_KEY_REQ, &req, sizeof(req), buf, resp_len, -- &arg->fw_err); -+ rc = handle_guest_request(snp_dev, SVM_VMGEXIT_GUEST_REQUEST, arg, -+ SNP_MSG_KEY_REQ, req, sizeof(*req), buf, resp_len); - if (rc) - return rc; - -@@ -548,8 +559,8 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque - - static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) - { -+ struct snp_ext_report_req *req = &snp_dev->req.ext_report; - struct snp_guest_crypto *crypto = snp_dev->crypto; -- struct snp_ext_report_req req; - struct snp_report_resp *resp; - int ret, npages = 0, resp_len; - -@@ -558,18 +569,18 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques - if (!arg->req_data || !arg->resp_data) - return -EINVAL; - -- if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) -+ if (copy_from_user(req, (void __user *)arg->req_data, sizeof(*req))) - return -EFAULT; - - /* userspace does not want certificate data */ -- if (!req.certs_len || !req.certs_address) -+ if (!req->certs_len || !req->certs_address) - goto cmd; - -- if (req.certs_len > SEV_FW_BLOB_MAX_SIZE || -- !IS_ALIGNED(req.certs_len, PAGE_SIZE)) -+ if (req->certs_len > SEV_FW_BLOB_MAX_SIZE || -+ !IS_ALIGNED(req->certs_len, PAGE_SIZE)) - return -EINVAL; - -- if (!access_ok((const void __user *)req.certs_address, req.certs_len)) -+ if (!access_ok((const void __user *)req->certs_address, req->certs_len)) - return -EFAULT; - - /* -@@ -578,8 +589,8 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques - * the host. If host does not supply any certs in it, then copy - * zeros to indicate that certificate data was not provided. - */ -- memset(snp_dev->certs_data, 0, req.certs_len); -- npages = req.certs_len >> PAGE_SHIFT; -+ memset(snp_dev->certs_data, 0, req->certs_len); -+ npages = req->certs_len >> PAGE_SHIFT; - cmd: - /* - * The intermediate response buffer is used while decrypting the -@@ -592,15 +603,15 @@ cmd: - return -ENOMEM; - - snp_dev->input.data_npages = npages; -- ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg->msg_version, -- SNP_MSG_REPORT_REQ, &req.data, -- sizeof(req.data), resp->data, resp_len, &arg->fw_err); -+ ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg, -+ SNP_MSG_REPORT_REQ, &req->data, -+ sizeof(req->data), resp->data, resp_len); - - /* If certs length is invalid then copy the returned length */ -- if (arg->fw_err == SNP_GUEST_REQ_INVALID_LEN) { -- req.certs_len = snp_dev->input.data_npages << PAGE_SHIFT; -+ if (arg->vmm_error == SNP_GUEST_VMM_ERR_INVALID_LEN) { -+ req->certs_len = snp_dev->input.data_npages << PAGE_SHIFT; - -- if (copy_to_user((void __user *)arg->req_data, &req, sizeof(req))) -+ if (copy_to_user((void __user *)arg->req_data, req, sizeof(*req))) - ret = -EFAULT; - } - -@@ -608,8 +619,8 @@ cmd: - goto e_free; - - if (npages && -- copy_to_user((void __user *)req.certs_address, snp_dev->certs_data, -- req.certs_len)) { -+ copy_to_user((void __user *)req->certs_address, snp_dev->certs_data, -+ req->certs_len)) { - ret = -EFAULT; - goto e_free; - } -@@ -632,7 +643,7 @@ static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long - if (copy_from_user(&input, argp, sizeof(input))) - return -EFAULT; - -- input.fw_err = 0xff; -+ input.exitinfo2 = 0xff; - - /* Message version must be non-zero */ - if (!input.msg_version) -@@ -663,7 +674,7 @@ static long snp_guest_ioctl(struct file *file, unsigned int ioctl, unsigned long - - mutex_unlock(&snp_cmd_mutex); - -- if (input.fw_err && copy_to_user(argp, &input, sizeof(input))) -+ if (input.exitinfo2 && copy_to_user(argp, &input, sizeof(input))) - return -EFAULT; - - return ret; -diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c -index 281a48d9889fc..0fc91e9c4a773 100644 ---- a/drivers/watchdog/ixp4xx_wdt.c -+++ b/drivers/watchdog/ixp4xx_wdt.c -@@ -105,6 +105,25 @@ static const struct watchdog_ops ixp4xx_wdt_ops = { - .owner = THIS_MODULE, - }; - -+/* -+ * The A0 version of the IXP422 had a bug in the watchdog making -+ * is useless, but we still need to use it to restart the system -+ * as it is the only way, so in this special case we register a -+ * "dummy" watchdog that doesn't really work, but will support -+ * the restart operation. -+ */ -+static int ixp4xx_wdt_dummy(struct watchdog_device *wdd) -+{ -+ return 0; -+} -+ -+static const struct watchdog_ops ixp4xx_wdt_restart_only_ops = { -+ .start = ixp4xx_wdt_dummy, -+ .stop = ixp4xx_wdt_dummy, -+ .restart = ixp4xx_wdt_restart, -+ .owner = THIS_MODULE, -+}; -+ - static const struct watchdog_info ixp4xx_wdt_info = { - .options = WDIOF_KEEPALIVEPING - | WDIOF_MAGICCLOSE -@@ -120,14 +139,17 @@ static void ixp4xx_clock_action(void *d) - - static int ixp4xx_wdt_probe(struct platform_device *pdev) - { -+ static const struct watchdog_ops *iwdt_ops; - struct device *dev = &pdev->dev; - struct ixp4xx_wdt *iwdt; - struct clk *clk; - int ret; - - if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) { -- dev_err(dev, "Rev. A0 IXP42x CPU detected - watchdog disabled\n"); -- return -ENODEV; -+ dev_info(dev, "Rev. A0 IXP42x CPU detected - only restart supported\n"); -+ iwdt_ops = &ixp4xx_wdt_restart_only_ops; -+ } else { -+ iwdt_ops = &ixp4xx_wdt_ops; - } - - iwdt = devm_kzalloc(dev, sizeof(*iwdt), GFP_KERNEL); -@@ -153,7 +175,7 @@ static int ixp4xx_wdt_probe(struct platform_device *pdev) - iwdt->rate = IXP4XX_TIMER_FREQ; - - iwdt->wdd.info = &ixp4xx_wdt_info; -- iwdt->wdd.ops = &ixp4xx_wdt_ops; -+ iwdt->wdd.ops = iwdt_ops; - iwdt->wdd.min_timeout = 1; - iwdt->wdd.max_timeout = U32_MAX / iwdt->rate; - iwdt->wdd.parent = dev; -diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c -index 059de92aea7d0..d47eee6c51435 100644 ---- a/drivers/xen/xen-pciback/conf_space.c -+++ b/drivers/xen/xen-pciback/conf_space.c -@@ -288,12 +288,6 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev) - u16 val; - int ret = 0; - -- err = pci_read_config_word(dev, PCI_COMMAND, &val); -- if (err) -- return err; -- if (!(val & PCI_COMMAND_INTX_DISABLE)) -- ret |= INTERRUPT_TYPE_INTX; -- - /* - * Do not trust dev->msi(x)_enabled here, as enabling could be done - * bypassing the pci_*msi* functions, by the qemu. -@@ -316,6 +310,19 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev) - if (val & PCI_MSIX_FLAGS_ENABLE) - ret |= INTERRUPT_TYPE_MSIX; - } -+ -+ /* -+ * PCIe spec says device cannot use INTx if MSI/MSI-X is enabled, -+ * so check for INTx only when both are disabled. -+ */ -+ if (!ret) { -+ err = pci_read_config_word(dev, PCI_COMMAND, &val); -+ if (err) -+ return err; -+ if (!(val & PCI_COMMAND_INTX_DISABLE)) -+ ret |= INTERRUPT_TYPE_INTX; -+ } -+ - return ret ?: INTERRUPT_TYPE_NONE; - } - -diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c -index 097316a741268..1948a9700c8fa 100644 ---- a/drivers/xen/xen-pciback/conf_space_capability.c -+++ b/drivers/xen/xen-pciback/conf_space_capability.c -@@ -236,10 +236,16 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value, - return PCIBIOS_SET_FAILED; - - if (new_value & field_config->enable_bit) { -- /* don't allow enabling together with other interrupt types */ -+ /* -+ * Don't allow enabling together with other interrupt type, but do -+ * allow enabling MSI(-X) while INTx is still active to please Linuxes -+ * MSI(-X) startup sequence. It is safe to do, as according to PCI -+ * spec, device with enabled MSI(-X) shouldn't use INTx. -+ */ - int int_type = xen_pcibk_get_interrupt_type(dev); - - if (int_type == INTERRUPT_TYPE_NONE || -+ int_type == INTERRUPT_TYPE_INTX || - int_type == field_config->int_type) - goto write; - return PCIBIOS_SET_FAILED; -diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c -index 981435103af1a..fc03326459664 100644 ---- a/drivers/xen/xen-pciback/conf_space_header.c -+++ b/drivers/xen/xen-pciback/conf_space_header.c -@@ -104,24 +104,9 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) - pci_clear_mwi(dev); - } - -- if (dev_data && dev_data->allow_interrupt_control) { -- if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) { -- if (value & PCI_COMMAND_INTX_DISABLE) { -- pci_intx(dev, 0); -- } else { -- /* Do not allow enabling INTx together with MSI or MSI-X. */ -- switch (xen_pcibk_get_interrupt_type(dev)) { -- case INTERRUPT_TYPE_NONE: -- pci_intx(dev, 1); -- break; -- case INTERRUPT_TYPE_INTX: -- break; -- default: -- return PCIBIOS_SET_FAILED; -- } -- } -- } -- } -+ if (dev_data && dev_data->allow_interrupt_control && -+ ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE)) -+ pci_intx(dev, !(value & PCI_COMMAND_INTX_DISABLE)); - - cmd->val = value; - -diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c -index 639bf628389ba..3205e5d724c8c 100644 ---- a/drivers/xen/xenbus/xenbus_probe.c -+++ b/drivers/xen/xenbus/xenbus_probe.c -@@ -1025,7 +1025,7 @@ static int __init xenbus_init(void) - if (err < 0) { - pr_err("xenstore_late_init couldn't bind irq err=%d\n", - err); -- return err; -+ goto out_error; - } - - xs_init_irq = err; -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index 9474265ee7ea3..e015e1e025b6e 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -2420,7 +2420,7 @@ static noinline int key_in_sk(struct btrfs_key *key, - static noinline int copy_to_sk(struct btrfs_path *path, - struct btrfs_key *key, - struct btrfs_ioctl_search_key *sk, -- size_t *buf_size, -+ u64 *buf_size, - char __user *ubuf, - unsigned long *sk_offset, - int *num_found) -@@ -2552,7 +2552,7 @@ out: - - static noinline int search_ioctl(struct inode *inode, - struct btrfs_ioctl_search_key *sk, -- size_t *buf_size, -+ u64 *buf_size, - char __user *ubuf) - { - struct btrfs_fs_info *info = btrfs_sb(inode->i_sb); -@@ -2625,7 +2625,7 @@ static noinline int btrfs_ioctl_tree_search(struct inode *inode, - struct btrfs_ioctl_search_args __user *uargs = argp; - struct btrfs_ioctl_search_key sk; - int ret; -- size_t buf_size; -+ u64 buf_size; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; -@@ -2655,8 +2655,8 @@ static noinline int btrfs_ioctl_tree_search_v2(struct inode *inode, - struct btrfs_ioctl_search_args_v2 __user *uarg = argp; - struct btrfs_ioctl_search_args_v2 args; - int ret; -- size_t buf_size; -- const size_t buf_limit = SZ_16M; -+ u64 buf_size; -+ const u64 buf_limit = SZ_16M; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index 1bb55a6d79c23..aa5aadd70bbc2 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -1010,6 +1010,11 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, - ix = curp->p_idx; - } - -+ if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) { -+ EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!"); -+ return -EFSCORRUPTED; -+ } -+ - len = EXT_LAST_INDEX(curp->p_hdr) - ix + 1; - BUG_ON(len < 0); - if (len > 0) { -@@ -1019,11 +1024,6 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, - memmove(ix + 1, ix, len * sizeof(struct ext4_extent_idx)); - } - -- if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) { -- EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!"); -- return -EFSCORRUPTED; -- } -- - ix->ei_block = cpu_to_le32(logical); - ext4_idx_store_pblock(ix, ptr); - le16_add_cpu(&curp->p_hdr->eh_entries, 1); -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index a982f91b71eb2..ea05710ca9bdf 100644 ---- a/fs/f2fs/data.c -+++ b/fs/f2fs/data.c -@@ -2263,8 +2263,10 @@ skip_reading_dnode: - f2fs_wait_on_block_writeback(inode, blkaddr); - - if (f2fs_load_compressed_page(sbi, page, blkaddr)) { -- if (atomic_dec_and_test(&dic->remaining_pages)) -+ if (atomic_dec_and_test(&dic->remaining_pages)) { - f2fs_decompress_cluster(dic, true); -+ break; -+ } - continue; - } - -@@ -2950,7 +2952,9 @@ static int f2fs_write_cache_pages(struct address_space *mapping, - { - int ret = 0; - int done = 0, retry = 0; -- struct page *pages[F2FS_ONSTACK_PAGES]; -+ struct page *pages_local[F2FS_ONSTACK_PAGES]; -+ struct page **pages = pages_local; -+ struct folio_batch fbatch; - struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); - struct bio *bio = NULL; - sector_t last_block; -@@ -2971,7 +2975,9 @@ static int f2fs_write_cache_pages(struct address_space *mapping, - .private = NULL, - }; - #endif -+ int nr_folios, p, idx; - int nr_pages; -+ unsigned int max_pages = F2FS_ONSTACK_PAGES; - pgoff_t index; - pgoff_t end; /* Inclusive */ - pgoff_t done_index; -@@ -2981,6 +2987,17 @@ static int f2fs_write_cache_pages(struct address_space *mapping, - int submitted = 0; - int i; - -+#ifdef CONFIG_F2FS_FS_COMPRESSION -+ if (f2fs_compressed_file(inode) && -+ 1 << cc.log_cluster_size > F2FS_ONSTACK_PAGES) { -+ pages = f2fs_kzalloc(sbi, sizeof(struct page *) << -+ cc.log_cluster_size, GFP_NOFS | __GFP_NOFAIL); -+ max_pages = 1 << cc.log_cluster_size; -+ } -+#endif -+ -+ folio_batch_init(&fbatch); -+ - if (get_dirty_pages(mapping->host) <= - SM_I(F2FS_M_SB(mapping))->min_hot_blocks) - set_inode_flag(mapping->host, FI_HOT_DATA); -@@ -3006,13 +3023,38 @@ retry: - tag_pages_for_writeback(mapping, index, end); - done_index = index; - while (!done && !retry && (index <= end)) { -- nr_pages = find_get_pages_range_tag(mapping, &index, end, -- tag, F2FS_ONSTACK_PAGES, pages); -- if (nr_pages == 0) -+ nr_pages = 0; -+again: -+ nr_folios = filemap_get_folios_tag(mapping, &index, end, -+ tag, &fbatch); -+ if (nr_folios == 0) { -+ if (nr_pages) -+ goto write; - break; -+ } - -+ for (i = 0; i < nr_folios; i++) { -+ struct folio *folio = fbatch.folios[i]; -+ -+ idx = 0; -+ p = folio_nr_pages(folio); -+add_more: -+ pages[nr_pages] = folio_page(folio, idx); -+ folio_get(folio); -+ if (++nr_pages == max_pages) { -+ index = folio->index + idx + 1; -+ folio_batch_release(&fbatch); -+ goto write; -+ } -+ if (++idx < p) -+ goto add_more; -+ } -+ folio_batch_release(&fbatch); -+ goto again; -+write: - for (i = 0; i < nr_pages; i++) { - struct page *page = pages[i]; -+ struct folio *folio = page_folio(page); - bool need_readd; - readd: - need_readd = false; -@@ -3029,7 +3071,7 @@ readd: - } - - if (!f2fs_cluster_can_merge_page(&cc, -- page->index)) { -+ folio->index)) { - ret = f2fs_write_multi_pages(&cc, - &submitted, wbc, io_type); - if (!ret) -@@ -3038,27 +3080,28 @@ readd: - } - - if (unlikely(f2fs_cp_error(sbi))) -- goto lock_page; -+ goto lock_folio; - - if (!f2fs_cluster_is_empty(&cc)) -- goto lock_page; -+ goto lock_folio; - - if (f2fs_all_cluster_page_ready(&cc, - pages, i, nr_pages, true)) -- goto lock_page; -+ goto lock_folio; - - ret2 = f2fs_prepare_compress_overwrite( - inode, &pagep, -- page->index, &fsdata); -+ folio->index, &fsdata); - if (ret2 < 0) { - ret = ret2; - done = 1; - break; - } else if (ret2 && - (!f2fs_compress_write_end(inode, -- fsdata, page->index, 1) || -+ fsdata, folio->index, 1) || - !f2fs_all_cluster_page_ready(&cc, -- pages, i, nr_pages, false))) { -+ pages, i, nr_pages, -+ false))) { - retry = 1; - break; - } -@@ -3071,46 +3114,47 @@ readd: - break; - } - #ifdef CONFIG_F2FS_FS_COMPRESSION --lock_page: -+lock_folio: - #endif -- done_index = page->index; -+ done_index = folio->index; - retry_write: -- lock_page(page); -+ folio_lock(folio); - -- if (unlikely(page->mapping != mapping)) { -+ if (unlikely(folio->mapping != mapping)) { - continue_unlock: -- unlock_page(page); -+ folio_unlock(folio); - continue; - } - -- if (!PageDirty(page)) { -+ if (!folio_test_dirty(folio)) { - /* someone wrote it for us */ - goto continue_unlock; - } - -- if (PageWriteback(page)) { -+ if (folio_test_writeback(folio)) { - if (wbc->sync_mode != WB_SYNC_NONE) -- f2fs_wait_on_page_writeback(page, -+ f2fs_wait_on_page_writeback( -+ &folio->page, - DATA, true, true); - else - goto continue_unlock; - } - -- if (!clear_page_dirty_for_io(page)) -+ if (!folio_clear_dirty_for_io(folio)) - goto continue_unlock; - - #ifdef CONFIG_F2FS_FS_COMPRESSION - if (f2fs_compressed_file(inode)) { -- get_page(page); -- f2fs_compress_ctx_add_page(&cc, page); -+ folio_get(folio); -+ f2fs_compress_ctx_add_page(&cc, &folio->page); - continue; - } - #endif -- ret = f2fs_write_single_data_page(page, &submitted, -- &bio, &last_block, wbc, io_type, -- 0, true); -+ ret = f2fs_write_single_data_page(&folio->page, -+ &submitted, &bio, &last_block, -+ wbc, io_type, 0, true); - if (ret == AOP_WRITEPAGE_ACTIVATE) -- unlock_page(page); -+ folio_unlock(folio); - #ifdef CONFIG_F2FS_FS_COMPRESSION - result: - #endif -@@ -3134,7 +3178,8 @@ result: - } - goto next; - } -- done_index = page->index + 1; -+ done_index = folio->index + -+ folio_nr_pages(folio); - done = 1; - break; - } -@@ -3182,6 +3227,11 @@ next: - if (bio) - f2fs_submit_merged_ipu_write(sbi, &bio, NULL); - -+#ifdef CONFIG_F2FS_FS_COMPRESSION -+ if (pages != pages_local) -+ kfree(pages); -+#endif -+ - return ret; - } - -diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c -index 746c71716bead..d0c17366ebf48 100644 ---- a/fs/f2fs/file.c -+++ b/fs/f2fs/file.c -@@ -3249,6 +3249,7 @@ int f2fs_precache_extents(struct inode *inode) - return -EOPNOTSUPP; - - map.m_lblk = 0; -+ map.m_pblk = 0; - map.m_next_pgofs = NULL; - map.m_next_extent = &m_next_extent; - map.m_seg_type = NO_CHECK_TYPE; -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 2046f633fe57a..1ba85ef97cbd3 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -548,6 +548,29 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb, - } - - #ifdef CONFIG_F2FS_FS_COMPRESSION -+static bool is_compress_extension_exist(struct f2fs_sb_info *sbi, -+ const char *new_ext, bool is_ext) -+{ -+ unsigned char (*ext)[F2FS_EXTENSION_LEN]; -+ int ext_cnt; -+ int i; -+ -+ if (is_ext) { -+ ext = F2FS_OPTION(sbi).extensions; -+ ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; -+ } else { -+ ext = F2FS_OPTION(sbi).noextensions; -+ ext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; -+ } -+ -+ for (i = 0; i < ext_cnt; i++) { -+ if (!strcasecmp(new_ext, ext[i])) -+ return true; -+ } -+ -+ return false; -+} -+ - /* - * 1. The same extension name cannot not appear in both compress and non-compress extension - * at the same time. -@@ -1145,6 +1168,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) - return -EINVAL; - } - -+ if (is_compress_extension_exist(sbi, name, true)) { -+ kfree(name); -+ break; -+ } -+ - strcpy(ext[ext_cnt], name); - F2FS_OPTION(sbi).compress_ext_cnt++; - kfree(name); -@@ -1169,6 +1197,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) - return -EINVAL; - } - -+ if (is_compress_extension_exist(sbi, name, false)) { -+ kfree(name); -+ break; -+ } -+ - strcpy(noext[noext_cnt], name); - F2FS_OPTION(sbi).nocompress_ext_cnt++; - kfree(name); -diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c -index a5c31a479aacc..be2d329843d44 100644 ---- a/fs/fs-writeback.c -+++ b/fs/fs-writeback.c -@@ -611,6 +611,24 @@ out_free: - kfree(isw); - } - -+static bool isw_prepare_wbs_switch(struct inode_switch_wbs_context *isw, -+ struct list_head *list, int *nr) -+{ -+ struct inode *inode; -+ -+ list_for_each_entry(inode, list, i_io_list) { -+ if (!inode_prepare_wbs_switch(inode, isw->new_wb)) -+ continue; -+ -+ isw->inodes[*nr] = inode; -+ (*nr)++; -+ -+ if (*nr >= WB_MAX_INODES_PER_ISW - 1) -+ return true; -+ } -+ return false; -+} -+ - /** - * cleanup_offline_cgwb - detach associated inodes - * @wb: target wb -@@ -623,7 +641,6 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb) - { - struct cgroup_subsys_state *memcg_css; - struct inode_switch_wbs_context *isw; -- struct inode *inode; - int nr; - bool restart = false; - -@@ -645,17 +662,17 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb) - - nr = 0; - spin_lock(&wb->list_lock); -- list_for_each_entry(inode, &wb->b_attached, i_io_list) { -- if (!inode_prepare_wbs_switch(inode, isw->new_wb)) -- continue; -- -- isw->inodes[nr++] = inode; -- -- if (nr >= WB_MAX_INODES_PER_ISW - 1) { -- restart = true; -- break; -- } -- } -+ /* -+ * In addition to the inodes that have completed writeback, also switch -+ * cgwbs for those inodes only with dirty timestamps. Otherwise, those -+ * inodes won't be written back for a long time when lazytime is -+ * enabled, and thus pinning the dying cgwbs. It won't break the -+ * bandwidth restrictions, as writeback of inode metadata is not -+ * accounted for. -+ */ -+ restart = isw_prepare_wbs_switch(isw, &wb->b_attached, &nr); -+ if (!restart) -+ restart = isw_prepare_wbs_switch(isw, &wb->b_dirty_time, &nr); - spin_unlock(&wb->list_lock); - - /* no attached inodes? bail out */ -diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c -index 0c034ea399547..7787fb544621c 100644 ---- a/fs/pstore/platform.c -+++ b/fs/pstore/platform.c -@@ -561,6 +561,8 @@ out: - */ - int pstore_register(struct pstore_info *psi) - { -+ char *new_backend; -+ - if (backend && strcmp(backend, psi->name)) { - pr_warn("ignoring unexpected backend '%s'\n", psi->name); - return -EPERM; -@@ -580,11 +582,16 @@ int pstore_register(struct pstore_info *psi) - return -EINVAL; - } - -+ new_backend = kstrdup(psi->name, GFP_KERNEL); -+ if (!new_backend) -+ return -ENOMEM; -+ - mutex_lock(&psinfo_lock); - if (psinfo) { - pr_warn("backend '%s' already loaded: ignoring '%s'\n", - psinfo->name, psi->name); - mutex_unlock(&psinfo_lock); -+ kfree(new_backend); - return -EBUSY; - } - -@@ -617,7 +624,7 @@ int pstore_register(struct pstore_info *psi) - * Update the module parameter backend, so it is visible - * through /sys/module/pstore/parameters/backend - */ -- backend = kstrdup(psi->name, GFP_KERNEL); -+ backend = new_backend; - - pr_info("Registered %s as persistent store backend\n", psi->name); - -diff --git a/include/kunit/visibility.h b/include/kunit/visibility.h -new file mode 100644 -index 0000000000000..0dfe35feeec60 ---- /dev/null -+++ b/include/kunit/visibility.h -@@ -0,0 +1,33 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * KUnit API to allow symbols to be conditionally visible during KUnit -+ * testing -+ * -+ * Copyright (C) 2022, Google LLC. -+ * Author: Rae Moar -+ */ -+ -+#ifndef _KUNIT_VISIBILITY_H -+#define _KUNIT_VISIBILITY_H -+ -+#if IS_ENABLED(CONFIG_KUNIT) -+ /** -+ * VISIBLE_IF_KUNIT - A macro that sets symbols to be static if -+ * CONFIG_KUNIT is not enabled. Otherwise if CONFIG_KUNIT is enabled -+ * there is no change to the symbol definition. -+ */ -+ #define VISIBLE_IF_KUNIT -+ /** -+ * EXPORT_SYMBOL_IF_KUNIT(symbol) - Exports symbol into -+ * EXPORTED_FOR_KUNIT_TESTING namespace only if CONFIG_KUNIT is -+ * enabled. Must use MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING) -+ * in test file in order to use symbols. -+ */ -+ #define EXPORT_SYMBOL_IF_KUNIT(symbol) EXPORT_SYMBOL_NS(symbol, \ -+ EXPORTED_FOR_KUNIT_TESTING) -+#else -+ #define VISIBLE_IF_KUNIT static -+ #define EXPORT_SYMBOL_IF_KUNIT(symbol) -+#endif -+ -+#endif /* _KUNIT_VISIBILITY_H */ -diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h -index aefb06373720f..15e336281d1f4 100644 ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -72,7 +72,7 @@ void clk_hw_forward_rate_request(const struct clk_hw *core, - unsigned long parent_rate); - - /** -- * struct clk_duty - Struture encoding the duty cycle ratio of a clock -+ * struct clk_duty - Structure encoding the duty cycle ratio of a clock - * - * @num: Numerator of the duty cycle ratio - * @den: Denominator of the duty cycle ratio -@@ -127,7 +127,7 @@ struct clk_duty { - * @restore_context: Restore the context of the clock after a restoration - * of power. - * -- * @recalc_rate Recalculate the rate of this clock, by querying hardware. The -+ * @recalc_rate: Recalculate the rate of this clock, by querying hardware. The - * parent rate is an input parameter. It is up to the caller to - * ensure that the prepare_mutex is held across this call. If the - * driver cannot figure out a rate for this clock, it must return -@@ -454,7 +454,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, - * clock with the clock framework - * @dev: device that is registering this clock - * @name: name of this clock -- * @parent_name: name of clock's parent -+ * @parent_data: name of clock's parent - * @flags: framework-specific flags - * @fixed_rate: non-adjustable clock rate - * @fixed_accuracy: non-adjustable clock accuracy -@@ -469,7 +469,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, - * the clock framework - * @dev: device that is registering this clock - * @name: name of this clock -- * @parent_name: name of clock's parent -+ * @parent_data: name of clock's parent - * @flags: framework-specific flags - * @fixed_rate: non-adjustable clock rate - */ -@@ -628,7 +628,7 @@ struct clk_div_table { - * Clock with an adjustable divider affecting its output frequency. Implements - * .recalc_rate, .set_rate and .round_rate - * -- * Flags: -+ * @flags: - * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the - * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is - * the raw value read from the register, with the value of zero considered -@@ -1109,11 +1109,12 @@ struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev, - * @mwidth: width of the numerator bit field - * @nshift: shift to the denominator bit field - * @nwidth: width of the denominator bit field -+ * @approximation: clk driver's callback for calculating the divider clock - * @lock: register lock - * - * Clock with adjustable fractional divider affecting its output frequency. - * -- * Flags: -+ * @flags: - * CLK_FRAC_DIVIDER_ZERO_BASED - by default the numerator and denominator - * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED - * is set then the numerator and denominator are both the value read -@@ -1172,7 +1173,7 @@ void clk_hw_unregister_fractional_divider(struct clk_hw *hw); - * Clock with an adjustable multiplier affecting its output frequency. - * Implements .recalc_rate, .set_rate and .round_rate - * -- * Flags: -+ * @flags: - * CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read - * from the register, with 0 being a valid value effectively - * zeroing the output clock rate. If CLK_MULTIPLIER_ZERO_BYPASS is -diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h -index 2be2091c2b447..c7e0d80dbf6a5 100644 ---- a/include/linux/cpuhotplug.h -+++ b/include/linux/cpuhotplug.h -@@ -191,6 +191,7 @@ enum cpuhp_state { - /* Must be the last timer callback */ - CPUHP_AP_DUMMY_TIMER_STARTING, - CPUHP_AP_ARM_XEN_STARTING, -+ CPUHP_AP_ARM_XEN_RUNSTATE_STARTING, - CPUHP_AP_ARM_CORESIGHT_STARTING, - CPUHP_AP_ARM_CORESIGHT_CTI_STARTING, - CPUHP_AP_ARM64_ISNDEP_STARTING, -diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h -index c3618255b1504..41203ce27d64c 100644 ---- a/include/linux/hisi_acc_qm.h -+++ b/include/linux/hisi_acc_qm.h -@@ -145,6 +145,13 @@ enum qm_vf_state { - QM_NOT_READY, - }; - -+enum qm_misc_ctl_bits { -+ QM_DRIVER_REMOVING = 0x0, -+ QM_RST_SCHED, -+ QM_RESETTING, -+ QM_MODULE_PARAM, -+}; -+ - enum qm_cap_bits { - QM_SUPPORT_DB_ISOLATION = 0x0, - QM_SUPPORT_FUNC_QOS, -@@ -471,11 +478,11 @@ int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen); - int hisi_qm_sriov_configure(struct pci_dev *pdev, int num_vfs); - void hisi_qm_dev_err_init(struct hisi_qm *qm); - void hisi_qm_dev_err_uninit(struct hisi_qm *qm); --int hisi_qm_diff_regs_init(struct hisi_qm *qm, -- struct dfx_diff_registers *dregs, int reg_len); --void hisi_qm_diff_regs_uninit(struct hisi_qm *qm, int reg_len); -+int hisi_qm_regs_debugfs_init(struct hisi_qm *qm, -+ struct dfx_diff_registers *dregs, u32 reg_len); -+void hisi_qm_regs_debugfs_uninit(struct hisi_qm *qm, u32 reg_len); - void hisi_qm_acc_diff_regs_dump(struct hisi_qm *qm, struct seq_file *s, -- struct dfx_diff_registers *dregs, int regs_len); -+ struct dfx_diff_registers *dregs, u32 regs_len); - - pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev, - pci_channel_state_t state); -diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h -index 77c2885c4c130..2505d58bd5829 100644 ---- a/include/linux/hw_random.h -+++ b/include/linux/hw_random.h -@@ -63,5 +63,6 @@ extern void hwrng_unregister(struct hwrng *rng); - extern void devm_hwrng_unregister(struct device *dve, struct hwrng *rng); - - extern long hwrng_msleep(struct hwrng *rng, unsigned int msecs); -+extern long hwrng_yield(struct hwrng *rng); - - #endif /* LINUX_HWRANDOM_H_ */ -diff --git a/include/linux/idr.h b/include/linux/idr.h -index a0dce14090a9e..da5f5fa4a3a6a 100644 ---- a/include/linux/idr.h -+++ b/include/linux/idr.h -@@ -200,7 +200,7 @@ static inline void idr_preload_end(void) - */ - #define idr_for_each_entry_ul(idr, entry, tmp, id) \ - for (tmp = 0, id = 0; \ -- tmp <= id && ((entry) = idr_get_next_ul(idr, &(id))) != NULL; \ -+ ((entry) = tmp <= id ? idr_get_next_ul(idr, &(id)) : NULL) != NULL; \ - tmp = id, ++id) - - /** -@@ -224,10 +224,12 @@ static inline void idr_preload_end(void) - * @id: Entry ID. - * - * Continue to iterate over entries, continuing after the current position. -+ * After normal termination @entry is left with the value NULL. This -+ * is convenient for a "not found" value. - */ - #define idr_for_each_entry_continue_ul(idr, entry, tmp, id) \ - for (tmp = id; \ -- tmp <= id && ((entry) = idr_get_next_ul(idr, &(id))) != NULL; \ -+ ((entry) = tmp <= id ? idr_get_next_ul(idr, &(id)) : NULL) != NULL; \ - tmp = id, ++id) - - /* -diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h -index 0bc7cba798a34..b449765b5cac1 100644 ---- a/include/linux/mfd/core.h -+++ b/include/linux/mfd/core.h -@@ -92,7 +92,7 @@ struct mfd_cell { - * (above) when matching OF nodes with devices that have identical - * compatible strings - */ -- const u64 of_reg; -+ u64 of_reg; - - /* Set to 'true' to use 'of_reg' (above) - allows for of_reg=0 */ - bool use_of_reg; -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 5a04fbf724768..0373e09359905 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -5190,5 +5190,6 @@ extern struct net_device *blackhole_netdev; - #define DEV_STATS_INC(DEV, FIELD) atomic_long_inc(&(DEV)->stats.__##FIELD) - #define DEV_STATS_ADD(DEV, FIELD, VAL) \ - atomic_long_add((VAL), &(DEV)->stats.__##FIELD) -+#define DEV_STATS_READ(DEV, FIELD) atomic_long_read(&(DEV)->stats.__##FIELD) - - #endif /* _LINUX_NETDEVICE_H */ -diff --git a/include/linux/numa.h b/include/linux/numa.h -index 59df211d051fa..0f512c0aba54b 100644 ---- a/include/linux/numa.h -+++ b/include/linux/numa.h -@@ -12,6 +12,7 @@ - #define MAX_NUMNODES (1 << NODES_SHIFT) - - #define NUMA_NO_NODE (-1) -+#define NUMA_NO_MEMBLK (-1) - - /* optionally keep NUMA memory info available post init */ - #ifdef CONFIG_NUMA_KEEP_MEMINFO -@@ -43,6 +44,12 @@ static inline int phys_to_target_node(u64 start) - return 0; - } - #endif -+#ifndef numa_fill_memblks -+static inline int __init numa_fill_memblks(u64 start, u64 end) -+{ -+ return NUMA_NO_MEMBLK; -+} -+#endif - #else /* !CONFIG_NUMA */ - static inline int numa_map_to_online_node(int node) - { -diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h -index bbccb40442224..03307b72de6c6 100644 ---- a/include/linux/pagemap.h -+++ b/include/linux/pagemap.h -@@ -720,6 +720,8 @@ unsigned filemap_get_folios(struct address_space *mapping, pgoff_t *start, - pgoff_t end, struct folio_batch *fbatch); - unsigned filemap_get_folios_contig(struct address_space *mapping, - pgoff_t *start, pgoff_t end, struct folio_batch *fbatch); -+unsigned filemap_get_folios_tag(struct address_space *mapping, pgoff_t *start, -+ pgoff_t end, xa_mark_t tag, struct folio_batch *fbatch); - unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index, - pgoff_t end, xa_mark_t tag, unsigned int nr_pages, - struct page **pages); -diff --git a/include/linux/string.h b/include/linux/string.h -index cf7607b321027..26ab8928d8661 100644 ---- a/include/linux/string.h -+++ b/include/linux/string.h -@@ -276,10 +276,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, - */ - #define strtomem_pad(dest, src, pad) do { \ - const size_t _dest_len = __builtin_object_size(dest, 1); \ -+ const size_t _src_len = __builtin_object_size(src, 1); \ - \ - BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ - _dest_len == (size_t)-1); \ -- memcpy_and_pad(dest, _dest_len, src, strnlen(src, _dest_len), pad); \ -+ memcpy_and_pad(dest, _dest_len, src, \ -+ strnlen(src, min(_src_len, _dest_len)), pad); \ - } while (0) - - /** -@@ -297,10 +299,11 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, - */ - #define strtomem(dest, src) do { \ - const size_t _dest_len = __builtin_object_size(dest, 1); \ -+ const size_t _src_len = __builtin_object_size(src, 1); \ - \ - BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ - _dest_len == (size_t)-1); \ -- memcpy(dest, src, min(_dest_len, strnlen(src, _dest_len))); \ -+ memcpy(dest, src, strnlen(src, min(_src_len, _dest_len))); \ - } while (0) - - /** -diff --git a/include/linux/verification.h b/include/linux/verification.h -index f34e50ebcf60a..cb2d47f280910 100644 ---- a/include/linux/verification.h -+++ b/include/linux/verification.h -@@ -8,6 +8,7 @@ - #ifndef _LINUX_VERIFICATION_H - #define _LINUX_VERIFICATION_H - -+#include - #include - - /* -diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h -index 35d7eedb5e8e4..3f9c166113063 100644 ---- a/include/linux/virtio_vsock.h -+++ b/include/linux/virtio_vsock.h -@@ -7,6 +7,109 @@ - #include - #include - -+#define VIRTIO_VSOCK_SKB_HEADROOM (sizeof(struct virtio_vsock_hdr)) -+ -+struct virtio_vsock_skb_cb { -+ bool reply; -+ bool tap_delivered; -+}; -+ -+#define VIRTIO_VSOCK_SKB_CB(skb) ((struct virtio_vsock_skb_cb *)((skb)->cb)) -+ -+static inline struct virtio_vsock_hdr *virtio_vsock_hdr(struct sk_buff *skb) -+{ -+ return (struct virtio_vsock_hdr *)skb->head; -+} -+ -+static inline bool virtio_vsock_skb_reply(struct sk_buff *skb) -+{ -+ return VIRTIO_VSOCK_SKB_CB(skb)->reply; -+} -+ -+static inline void virtio_vsock_skb_set_reply(struct sk_buff *skb) -+{ -+ VIRTIO_VSOCK_SKB_CB(skb)->reply = true; -+} -+ -+static inline bool virtio_vsock_skb_tap_delivered(struct sk_buff *skb) -+{ -+ return VIRTIO_VSOCK_SKB_CB(skb)->tap_delivered; -+} -+ -+static inline void virtio_vsock_skb_set_tap_delivered(struct sk_buff *skb) -+{ -+ VIRTIO_VSOCK_SKB_CB(skb)->tap_delivered = true; -+} -+ -+static inline void virtio_vsock_skb_clear_tap_delivered(struct sk_buff *skb) -+{ -+ VIRTIO_VSOCK_SKB_CB(skb)->tap_delivered = false; -+} -+ -+static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb) -+{ -+ u32 len; -+ -+ len = le32_to_cpu(virtio_vsock_hdr(skb)->len); -+ -+ if (len > 0) -+ skb_put(skb, len); -+} -+ -+static inline struct sk_buff *virtio_vsock_alloc_skb(unsigned int size, gfp_t mask) -+{ -+ struct sk_buff *skb; -+ -+ if (size < VIRTIO_VSOCK_SKB_HEADROOM) -+ return NULL; -+ -+ skb = alloc_skb(size, mask); -+ if (!skb) -+ return NULL; -+ -+ skb_reserve(skb, VIRTIO_VSOCK_SKB_HEADROOM); -+ return skb; -+} -+ -+static inline void -+virtio_vsock_skb_queue_head(struct sk_buff_head *list, struct sk_buff *skb) -+{ -+ spin_lock_bh(&list->lock); -+ __skb_queue_head(list, skb); -+ spin_unlock_bh(&list->lock); -+} -+ -+static inline void -+virtio_vsock_skb_queue_tail(struct sk_buff_head *list, struct sk_buff *skb) -+{ -+ spin_lock_bh(&list->lock); -+ __skb_queue_tail(list, skb); -+ spin_unlock_bh(&list->lock); -+} -+ -+static inline struct sk_buff *virtio_vsock_skb_dequeue(struct sk_buff_head *list) -+{ -+ struct sk_buff *skb; -+ -+ spin_lock_bh(&list->lock); -+ skb = __skb_dequeue(list); -+ spin_unlock_bh(&list->lock); -+ -+ return skb; -+} -+ -+static inline void virtio_vsock_skb_queue_purge(struct sk_buff_head *list) -+{ -+ spin_lock_bh(&list->lock); -+ __skb_queue_purge(list); -+ spin_unlock_bh(&list->lock); -+} -+ -+static inline size_t virtio_vsock_skb_len(struct sk_buff *skb) -+{ -+ return (size_t)(skb_end_pointer(skb) - skb->head); -+} -+ - #define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE (1024 * 4) - #define VIRTIO_VSOCK_MAX_BUF_SIZE 0xFFFFFFFFUL - #define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64) -@@ -35,23 +138,10 @@ struct virtio_vsock_sock { - u32 last_fwd_cnt; - u32 rx_bytes; - u32 buf_alloc; -- struct list_head rx_queue; -+ struct sk_buff_head rx_queue; - u32 msg_count; - }; - --struct virtio_vsock_pkt { -- struct virtio_vsock_hdr hdr; -- struct list_head list; -- /* socket refcnt not held, only use for cancellation */ -- struct vsock_sock *vsk; -- void *buf; -- u32 buf_len; -- u32 len; -- u32 off; -- bool reply; -- bool tap_delivered; --}; -- - struct virtio_vsock_pkt_info { - u32 remote_cid, remote_port; - struct vsock_sock *vsk; -@@ -68,7 +158,7 @@ struct virtio_transport { - struct vsock_transport transport; - - /* Takes ownership of the packet */ -- int (*send_pkt)(struct virtio_vsock_pkt *pkt); -+ int (*send_pkt)(struct sk_buff *skb); - }; - - ssize_t -@@ -149,11 +239,10 @@ virtio_transport_dgram_enqueue(struct vsock_sock *vsk, - void virtio_transport_destruct(struct vsock_sock *vsk); - - void virtio_transport_recv_pkt(struct virtio_transport *t, -- struct virtio_vsock_pkt *pkt); --void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt); --void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt); -+ struct sk_buff *skb); -+void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct sk_buff *skb); - u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted); - void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit); --void virtio_transport_deliver_tap_pkt(struct virtio_vsock_pkt *pkt); -- -+void virtio_transport_deliver_tap_pkt(struct sk_buff *skb); -+int virtio_transport_purge_skbs(void *vsk, struct sk_buff_head *list); - #endif /* _LINUX_VIRTIO_VSOCK_H */ -diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h -index 7a6c3059d50b5..5bf5c1ab542ce 100644 ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -5690,6 +5690,16 @@ void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work); - */ - void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work); - -+/** -+ * wiphy_work_flush - flush previously queued work -+ * @wiphy: the wiphy, for debug purposes -+ * @work: the work to flush, this can be %NULL to flush all work -+ * -+ * Flush the work (i.e. run it if pending). This must be called -+ * under the wiphy mutex acquired by wiphy_lock(). -+ */ -+void wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *work); -+ - struct wiphy_delayed_work { - struct wiphy_work work; - struct wiphy *wiphy; -@@ -5733,6 +5743,17 @@ void wiphy_delayed_work_queue(struct wiphy *wiphy, - void wiphy_delayed_work_cancel(struct wiphy *wiphy, - struct wiphy_delayed_work *dwork); - -+/** -+ * wiphy_delayed_work_flush - flush previously queued delayed work -+ * @wiphy: the wiphy, for debug purposes -+ * @work: the work to flush -+ * -+ * Flush the work (i.e. run it if pending). This must be called -+ * under the wiphy mutex acquired by wiphy_lock(). -+ */ -+void wiphy_delayed_work_flush(struct wiphy *wiphy, -+ struct wiphy_delayed_work *dwork); -+ - /** - * struct wireless_dev - wireless device state - * -diff --git a/include/net/flow.h b/include/net/flow.h -index 2f0da4f0318b5..079cc493fe67d 100644 ---- a/include/net/flow.h -+++ b/include/net/flow.h -@@ -39,8 +39,8 @@ struct flowi_common { - #define FLOWI_FLAG_KNOWN_NH 0x02 - __u32 flowic_secid; - kuid_t flowic_uid; -- struct flowi_tunnel flowic_tun_key; - __u32 flowic_multipath_hash; -+ struct flowi_tunnel flowic_tun_key; - }; - - union flowi_uli { -diff --git a/include/net/netfilter/nf_nat_redirect.h b/include/net/netfilter/nf_nat_redirect.h -index 2418653a66db1..279380de904c8 100644 ---- a/include/net/netfilter/nf_nat_redirect.h -+++ b/include/net/netfilter/nf_nat_redirect.h -@@ -6,8 +6,7 @@ - #include - - unsigned int --nf_nat_redirect_ipv4(struct sk_buff *skb, -- const struct nf_nat_ipv4_multi_range_compat *mr, -+nf_nat_redirect_ipv4(struct sk_buff *skb, const struct nf_nat_range2 *range, - unsigned int hooknum); - unsigned int - nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, -diff --git a/include/net/tcp.h b/include/net/tcp.h -index 548c75c8a34c7..19646fdec23dc 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -810,7 +810,7 @@ static inline u32 tcp_time_stamp(const struct tcp_sock *tp) - } - - /* Convert a nsec timestamp into TCP TSval timestamp (ms based currently) */ --static inline u32 tcp_ns_to_ts(u64 ns) -+static inline u64 tcp_ns_to_ts(u64 ns) - { - return div_u64(ns, NSEC_PER_SEC / TCP_TS_HZ); - } -diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h -index 91b4c63d5cbf4..1c9da485318f9 100644 ---- a/include/uapi/linux/psp-sev.h -+++ b/include/uapi/linux/psp-sev.h -@@ -36,6 +36,13 @@ enum { - * SEV Firmware status code - */ - typedef enum { -+ /* -+ * This error code is not in the SEV spec. Its purpose is to convey that -+ * there was an error that prevented the SEV firmware from being called. -+ * The SEV API error codes are 16 bits, so the -1 value will not overlap -+ * with possible values from the specification. -+ */ -+ SEV_RET_NO_FW_CALL = -1, - SEV_RET_SUCCESS = 0, - SEV_RET_INVALID_PLATFORM_STATE, - SEV_RET_INVALID_GUEST_STATE, -diff --git a/include/uapi/linux/sev-guest.h b/include/uapi/linux/sev-guest.h -index 256aaeff7e654..2aa39112cf8dd 100644 ---- a/include/uapi/linux/sev-guest.h -+++ b/include/uapi/linux/sev-guest.h -@@ -52,8 +52,14 @@ struct snp_guest_request_ioctl { - __u64 req_data; - __u64 resp_data; - -- /* firmware error code on failure (see psp-sev.h) */ -- __u64 fw_err; -+ /* bits[63:32]: VMM error code, bits[31:0] firmware error code (see psp-sev.h) */ -+ union { -+ __u64 exitinfo2; -+ struct { -+ __u32 fw_error; -+ __u32 vmm_error; -+ }; -+ }; - }; - - struct snp_ext_report_req { -@@ -77,4 +83,12 @@ struct snp_ext_report_req { - /* Get SNP extended report as defined in the GHCB specification version 2. */ - #define SNP_GET_EXT_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x2, struct snp_guest_request_ioctl) - -+/* Guest message request EXIT_INFO_2 constants */ -+#define SNP_GUEST_FW_ERR_MASK GENMASK_ULL(31, 0) -+#define SNP_GUEST_VMM_ERR_SHIFT 32 -+#define SNP_GUEST_VMM_ERR(x) (((u64)x) << SNP_GUEST_VMM_ERR_SHIFT) -+ -+#define SNP_GUEST_VMM_ERR_INVALID_LEN 1 -+#define SNP_GUEST_VMM_ERR_BUSY 2 -+ - #endif /* __UAPI_LINUX_SEV_GUEST_H_ */ -diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c -index acc37e5a6d4e1..57ef6850c6a87 100644 ---- a/io_uring/kbuf.c -+++ b/io_uring/kbuf.c -@@ -19,12 +19,15 @@ - - #define BGID_ARRAY 64 - -+/* BIDs are addressed by a 16-bit field in a CQE */ -+#define MAX_BIDS_PER_BGID (1 << 16) -+ - struct io_provide_buf { - struct file *file; - __u64 addr; - __u32 len; - __u32 bgid; -- __u16 nbufs; -+ __u32 nbufs; - __u16 bid; - }; - -@@ -281,7 +284,7 @@ int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) - return -EINVAL; - - tmp = READ_ONCE(sqe->fd); -- if (!tmp || tmp > USHRT_MAX) -+ if (!tmp || tmp > MAX_BIDS_PER_BGID) - return -EINVAL; - - memset(p, 0, sizeof(*p)); -@@ -327,7 +330,7 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe - return -EINVAL; - - tmp = READ_ONCE(sqe->fd); -- if (!tmp || tmp > USHRT_MAX) -+ if (!tmp || tmp > MAX_BIDS_PER_BGID) - return -E2BIG; - p->nbufs = tmp; - p->addr = READ_ONCE(sqe->addr); -@@ -347,7 +350,7 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe - tmp = READ_ONCE(sqe->off); - if (tmp > USHRT_MAX) - return -E2BIG; -- if (tmp + p->nbufs >= USHRT_MAX) -+ if (tmp + p->nbufs > MAX_BIDS_PER_BGID) - return -EINVAL; - p->bid = tmp; - return 0; -diff --git a/io_uring/net.c b/io_uring/net.c -index 9fe1aada3ad00..57c626cb4d1a5 100644 ---- a/io_uring/net.c -+++ b/io_uring/net.c -@@ -1433,16 +1433,6 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags) - int ret; - bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; - -- if (connect->in_progress) { -- struct socket *socket; -- -- ret = -ENOTSOCK; -- socket = sock_from_file(req->file); -- if (socket) -- ret = sock_error(socket->sk); -- goto out; -- } -- - if (req_has_async_data(req)) { - io = req->async_data; - } else { -@@ -1462,9 +1452,7 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags) - && force_nonblock) { - if (ret == -EINPROGRESS) { - connect->in_progress = true; -- return -EAGAIN; -- } -- if (ret == -ECONNABORTED) { -+ } else if (ret == -ECONNABORTED) { - if (connect->seen_econnaborted) - goto out; - connect->seen_econnaborted = true; -@@ -1478,6 +1466,16 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags) - memcpy(req->async_data, &__io, sizeof(__io)); - return -EAGAIN; - } -+ if (connect->in_progress) { -+ /* -+ * At least bluetooth will return -EBADFD on a re-connect -+ * attempt, and it's (supposedly) also valid to get -EISCONN -+ * which means the previous result is good. For both of these, -+ * grab the sock_error() and use that for the completion. -+ */ -+ if (ret == -EBADFD || ret == -EISCONN) -+ ret = sock_error(sock_from_file(req->file)->sk); -+ } - if (ret == -ERESTARTSYS) - ret = -EINTR; - out: -diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c -index e4e7f343346f9..ce0051eee746e 100644 ---- a/kernel/bpf/hashtab.c -+++ b/kernel/bpf/hashtab.c -@@ -155,13 +155,15 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab, - hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1); - - preempt_disable(); -+ local_irq_save(flags); - if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) { - __this_cpu_dec(*(htab->map_locked[hash])); -+ local_irq_restore(flags); - preempt_enable(); - return -EBUSY; - } - -- raw_spin_lock_irqsave(&b->raw_lock, flags); -+ raw_spin_lock(&b->raw_lock); - *pflags = flags; - - return 0; -@@ -172,8 +174,9 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab, - unsigned long flags) - { - hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1); -- raw_spin_unlock_irqrestore(&b->raw_lock, flags); -+ raw_spin_unlock(&b->raw_lock); - __this_cpu_dec(*(htab->map_locked[hash])); -+ local_irq_restore(flags); - preempt_enable(); - } - -diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c -index a6b04faed282b..6212e4ae084bb 100644 ---- a/kernel/bpf/helpers.c -+++ b/kernel/bpf/helpers.c -@@ -1156,13 +1156,6 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map - ret = -EBUSY; - goto out; - } -- if (!atomic64_read(&map->usercnt)) { -- /* maps with timers must be either held by user space -- * or pinned in bpffs. -- */ -- ret = -EPERM; -- goto out; -- } - /* allocate hrtimer via map_kmalloc to use memcg accounting */ - t = bpf_map_kmalloc_node(map, sizeof(*t), GFP_ATOMIC, map->numa_node); - if (!t) { -@@ -1175,7 +1168,21 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map - rcu_assign_pointer(t->callback_fn, NULL); - hrtimer_init(&t->timer, clockid, HRTIMER_MODE_REL_SOFT); - t->timer.function = bpf_timer_cb; -- timer->timer = t; -+ WRITE_ONCE(timer->timer, t); -+ /* Guarantee the order between timer->timer and map->usercnt. So -+ * when there are concurrent uref release and bpf timer init, either -+ * bpf_timer_cancel_and_free() called by uref release reads a no-NULL -+ * timer or atomic64_read() below returns a zero usercnt. -+ */ -+ smp_mb(); -+ if (!atomic64_read(&map->usercnt)) { -+ /* maps with timers must be either held by user space -+ * or pinned in bpffs. -+ */ -+ WRITE_ONCE(timer->timer, NULL); -+ kfree(t); -+ ret = -EPERM; -+ } - out: - __bpf_spin_unlock_irqrestore(&timer->lock); - return ret; -@@ -1343,7 +1350,7 @@ void bpf_timer_cancel_and_free(void *val) - /* The subsequent bpf_timer_start/cancel() helpers won't be able to use - * this timer, since it won't be initialized. - */ -- timer->timer = NULL; -+ WRITE_ONCE(timer->timer, NULL); - out: - __bpf_spin_unlock_irqrestore(&timer->lock); - if (!t) -diff --git a/kernel/futex/core.c b/kernel/futex/core.c -index 514e4582b8634..d4141b0547187 100644 ---- a/kernel/futex/core.c -+++ b/kernel/futex/core.c -@@ -248,7 +248,17 @@ int get_futex_key(u32 __user *uaddr, bool fshared, union futex_key *key, - * but access_ok() should be faster than find_vma() - */ - if (!fshared) { -- key->private.mm = mm; -+ /* -+ * On no-MMU, shared futexes are treated as private, therefore -+ * we must not include the current process in the key. Since -+ * there is only one address space, the address is a unique key -+ * on its own. -+ */ -+ if (IS_ENABLED(CONFIG_MMU)) -+ key->private.mm = mm; -+ else -+ key->private.mm = NULL; -+ - key->private.address = address; - return 0; - } -diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c -index 1698e77645acf..75d0ae490e29c 100644 ---- a/kernel/irq/matrix.c -+++ b/kernel/irq/matrix.c -@@ -466,16 +466,16 @@ unsigned int irq_matrix_reserved(struct irq_matrix *m) - } - - /** -- * irq_matrix_allocated - Get the number of allocated irqs on the local cpu -+ * irq_matrix_allocated - Get the number of allocated non-managed irqs on the local CPU - * @m: Pointer to the matrix to search - * -- * This returns number of allocated irqs -+ * This returns number of allocated non-managed interrupts. - */ - unsigned int irq_matrix_allocated(struct irq_matrix *m) - { - struct cpumap *cm = this_cpu_ptr(m->maps); - -- return cm->allocated; -+ return cm->allocated - cm->managed_allocated; - } - - #ifdef CONFIG_GENERIC_IRQ_DEBUGFS -diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c -index 9ada0bc5247be..0e651fd4cc9fc 100644 ---- a/kernel/livepatch/core.c -+++ b/kernel/livepatch/core.c -@@ -244,7 +244,7 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab, - * symbols are exported and normal relas can be used instead. - */ - if (!sec_vmlinux && sym_vmlinux) { -- pr_err("invalid access to vmlinux symbol '%s' from module-specific livepatch relocation section", -+ pr_err("invalid access to vmlinux symbol '%s' from module-specific livepatch relocation section\n", - sym_name); - return -EINVAL; - } -diff --git a/kernel/module/decompress.c b/kernel/module/decompress.c -index 720e719253cd1..e1e9f69c5dd16 100644 ---- a/kernel/module/decompress.c -+++ b/kernel/module/decompress.c -@@ -100,7 +100,7 @@ static ssize_t module_gzip_decompress(struct load_info *info, - s.next_in = buf + gzip_hdr_len; - s.avail_in = size - gzip_hdr_len; - -- s.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); -+ s.workspace = vmalloc(zlib_inflate_workspacesize()); - if (!s.workspace) - return -ENOMEM; - -@@ -138,7 +138,7 @@ static ssize_t module_gzip_decompress(struct load_info *info, - out_inflate_end: - zlib_inflateEnd(&s); - out: -- kfree(s.workspace); -+ vfree(s.workspace); - return retval; - } - #elif CONFIG_MODULE_COMPRESS_XZ -diff --git a/kernel/padata.c b/kernel/padata.c -index de90af5fcbe6b..791d9cb07a501 100644 ---- a/kernel/padata.c -+++ b/kernel/padata.c -@@ -1094,12 +1094,16 @@ EXPORT_SYMBOL(padata_alloc_shell); - */ - void padata_free_shell(struct padata_shell *ps) - { -+ struct parallel_data *pd; -+ - if (!ps) - return; - - mutex_lock(&ps->pinst->lock); - list_del(&ps->list); -- padata_free_pd(rcu_dereference_protected(ps->pd, 1)); -+ pd = rcu_dereference_protected(ps->pd, 1); -+ if (refcount_dec_and_test(&pd->refcnt)) -+ padata_free_pd(pd); - mutex_unlock(&ps->pinst->lock); - - kfree(ps); -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 55d13980e29fd..18a4f8f28a25f 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -2463,9 +2463,11 @@ static int migration_cpu_stop(void *data) - * it. - */ - WARN_ON_ONCE(!pending->stop_pending); -+ preempt_disable(); - task_rq_unlock(rq, p, &rf); - stop_one_cpu_nowait(task_cpu(p), migration_cpu_stop, - &pending->arg, &pending->stop_work); -+ preempt_enable(); - return 0; - } - out: -@@ -2746,12 +2748,13 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag - complete = true; - } - -+ preempt_disable(); - task_rq_unlock(rq, p, rf); -- - if (push_task) { - stop_one_cpu_nowait(rq->cpu, push_cpu_stop, - p, &rq->push_work); - } -+ preempt_enable(); - - if (complete) - complete_all(&pending->done); -@@ -2817,12 +2820,13 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag - if (flags & SCA_MIGRATE_ENABLE) - p->migration_flags &= ~MDF_PUSH; - -+ preempt_disable(); - task_rq_unlock(rq, p, rf); -- - if (!stop_pending) { - stop_one_cpu_nowait(cpu_of(rq), migration_cpu_stop, - &pending->arg, &pending->stop_work); - } -+ preempt_enable(); - - if (flags & SCA_MIGRATE_ENABLE) - return 0; -@@ -9255,9 +9259,11 @@ static void balance_push(struct rq *rq) - * Temporarily drop rq->lock such that we can wake-up the stop task. - * Both preemption and IRQs are still disabled. - */ -+ preempt_disable(); - raw_spin_rq_unlock(rq); - stop_one_cpu_nowait(rq->cpu, __balance_push_cpu_stop, push_task, - this_cpu_ptr(&push_work)); -+ preempt_enable(); - /* - * At this point need_resched() is true and we'll take the loop in - * schedule(). The next pick is obviously going to be the stop task -diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c -index 9ce9810861ba5..389290e950bea 100644 ---- a/kernel/sched/deadline.c -+++ b/kernel/sched/deadline.c -@@ -2460,9 +2460,11 @@ skip: - double_unlock_balance(this_rq, src_rq); - - if (push_task) { -+ preempt_disable(); - raw_spin_rq_unlock(this_rq); - stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop, - push_task, &src_rq->push_work); -+ preempt_enable(); - raw_spin_rq_lock(this_rq); - } - } -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 612873ec2197f..2558ab9033bee 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -4279,22 +4279,6 @@ static inline unsigned long task_util_est(struct task_struct *p) - return max(task_util(p), _task_util_est(p)); - } - --#ifdef CONFIG_UCLAMP_TASK --static inline unsigned long uclamp_task_util(struct task_struct *p, -- unsigned long uclamp_min, -- unsigned long uclamp_max) --{ -- return clamp(task_util_est(p), uclamp_min, uclamp_max); --} --#else --static inline unsigned long uclamp_task_util(struct task_struct *p, -- unsigned long uclamp_min, -- unsigned long uclamp_max) --{ -- return task_util_est(p); --} --#endif -- - static inline void util_est_enqueue(struct cfs_rq *cfs_rq, - struct task_struct *p) - { -@@ -4585,7 +4569,7 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq) - - static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) - { -- return true; -+ return !cfs_rq->nr_running; - } - - #define UPDATE_TG 0x0 -@@ -7279,7 +7263,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - target = prev_cpu; - - sync_entity_load_avg(&p->se); -- if (!uclamp_task_util(p, p_util_min, p_util_max)) -+ if (!task_util_est(p) && p_util_min == 0) - goto unlock; - - eenv_task_busy_time(&eenv, p, prev_cpu); -@@ -7287,11 +7271,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - for (; pd; pd = pd->next) { - unsigned long util_min = p_util_min, util_max = p_util_max; - unsigned long cpu_cap, cpu_thermal_cap, util; -- unsigned long cur_delta, max_spare_cap = 0; -+ long prev_spare_cap = -1, max_spare_cap = -1; - unsigned long rq_util_min, rq_util_max; -- unsigned long prev_spare_cap = 0; -+ unsigned long cur_delta, base_energy; - int max_spare_cap_cpu = -1; -- unsigned long base_energy; - int fits, max_fits = -1; - - cpumask_and(cpus, perf_domain_span(pd), cpu_online_mask); -@@ -7354,7 +7337,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - prev_spare_cap = cpu_cap; - prev_fits = fits; - } else if ((fits > max_fits) || -- ((fits == max_fits) && (cpu_cap > max_spare_cap))) { -+ ((fits == max_fits) && ((long)cpu_cap > max_spare_cap))) { - /* - * Find the CPU with the maximum spare capacity - * among the remaining CPUs in the performance -@@ -7366,7 +7349,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - } - } - -- if (max_spare_cap_cpu < 0 && prev_spare_cap == 0) -+ if (max_spare_cap_cpu < 0 && prev_spare_cap < 0) - continue; - - eenv_pd_busy_time(&eenv, cpus, p); -@@ -7374,7 +7357,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - base_energy = compute_energy(&eenv, pd, cpus, p, -1); - - /* Evaluate the energy impact of using prev_cpu. */ -- if (prev_spare_cap > 0) { -+ if (prev_spare_cap > -1) { - prev_delta = compute_energy(&eenv, pd, cpus, p, - prev_cpu); - /* CPU utilization has changed */ -@@ -10730,13 +10713,15 @@ more_balance: - busiest->push_cpu = this_cpu; - active_balance = 1; - } -- raw_spin_rq_unlock_irqrestore(busiest, flags); - -+ preempt_disable(); -+ raw_spin_rq_unlock_irqrestore(busiest, flags); - if (active_balance) { - stop_one_cpu_nowait(cpu_of(busiest), - active_load_balance_cpu_stop, busiest, - &busiest->active_balance_work); - } -+ preempt_enable(); - } - } else { - sd->nr_balance_failed = 0; -diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c -index 576eb2f51f043..76bafa8d331a7 100644 ---- a/kernel/sched/rt.c -+++ b/kernel/sched/rt.c -@@ -2109,9 +2109,11 @@ retry: - */ - push_task = get_push_task(rq); - if (push_task) { -+ preempt_disable(); - raw_spin_rq_unlock(rq); - stop_one_cpu_nowait(rq->cpu, push_cpu_stop, - push_task, &rq->push_work); -+ preempt_enable(); - raw_spin_rq_lock(rq); - } - -@@ -2448,9 +2450,11 @@ skip: - double_unlock_balance(this_rq, src_rq); - - if (push_task) { -+ preempt_disable(); - raw_spin_rq_unlock(this_rq); - stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop, - push_task, &src_rq->push_work); -+ preempt_enable(); - raw_spin_rq_lock(this_rq); - } - } -diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c -index 56675294d7a3b..a34a4fcdab7b1 100644 ---- a/kernel/trace/trace_kprobe.c -+++ b/kernel/trace/trace_kprobe.c -@@ -986,9 +986,9 @@ EXPORT_SYMBOL_GPL(kprobe_event_cmd_init); - /** - * __kprobe_event_gen_cmd_start - Generate a kprobe event command from arg list - * @cmd: A pointer to the dynevent_cmd struct representing the new event -+ * @kretprobe: Is this a return probe? - * @name: The name of the kprobe event - * @loc: The location of the kprobe event -- * @kretprobe: Is this a return probe? - * @...: Variable number of arg (pairs), one pair for each field - * - * NOTE: Users normally won't want to call this function directly, but -diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c -index 74982b83707ca..05ac4cdb6806a 100644 ---- a/lib/kunit/executor.c -+++ b/lib/kunit/executor.c -@@ -102,8 +102,10 @@ static void kunit_free_suite_set(struct suite_set suite_set) - { - struct kunit_suite * const *suites; - -- for (suites = suite_set.start; suites < suite_set.end; suites++) -+ for (suites = suite_set.start; suites < suite_set.end; suites++) { -+ kfree((*suites)->test_cases); - kfree(*suites); -+ } - kfree(suite_set.start); - } - -diff --git a/mm/filemap.c b/mm/filemap.c -index 322aea78058a0..2d930470aacaa 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -2262,6 +2262,60 @@ out: - } - EXPORT_SYMBOL(filemap_get_folios_contig); - -+/** -+ * filemap_get_folios_tag - Get a batch of folios matching @tag -+ * @mapping: The address_space to search -+ * @start: The starting page index -+ * @end: The final page index (inclusive) -+ * @tag: The tag index -+ * @fbatch: The batch to fill -+ * -+ * Same as filemap_get_folios(), but only returning folios tagged with @tag. -+ * -+ * Return: The number of folios found. -+ * Also update @start to index the next folio for traversal. -+ */ -+unsigned filemap_get_folios_tag(struct address_space *mapping, pgoff_t *start, -+ pgoff_t end, xa_mark_t tag, struct folio_batch *fbatch) -+{ -+ XA_STATE(xas, &mapping->i_pages, *start); -+ struct folio *folio; -+ -+ rcu_read_lock(); -+ while ((folio = find_get_entry(&xas, end, tag)) != NULL) { -+ /* -+ * Shadow entries should never be tagged, but this iteration -+ * is lockless so there is a window for page reclaim to evict -+ * a page we saw tagged. Skip over it. -+ */ -+ if (xa_is_value(folio)) -+ continue; -+ if (!folio_batch_add(fbatch, folio)) { -+ unsigned long nr = folio_nr_pages(folio); -+ -+ if (folio_test_hugetlb(folio)) -+ nr = 1; -+ *start = folio->index + nr; -+ goto out; -+ } -+ } -+ /* -+ * We come here when there is no page beyond @end. We take care to not -+ * overflow the index @start as it confuses some of the callers. This -+ * breaks the iteration when there is a page at index -1 but that is -+ * already broke anyway. -+ */ -+ if (end == (pgoff_t)-1) -+ *start = (pgoff_t)-1; -+ else -+ *start = end + 1; -+out: -+ rcu_read_unlock(); -+ -+ return folio_batch_count(fbatch); -+} -+EXPORT_SYMBOL(filemap_get_folios_tag); -+ - /** - * find_get_pages_range_tag - Find and return head pages matching @tag. - * @mapping: the address_space to search -diff --git a/mm/readahead.c b/mm/readahead.c -index b10f0cf81d804..ba43428043a35 100644 ---- a/mm/readahead.c -+++ b/mm/readahead.c -@@ -749,7 +749,8 @@ ssize_t ksys_readahead(int fd, loff_t offset, size_t count) - */ - ret = -EINVAL; - if (!f.file->f_mapping || !f.file->f_mapping->a_ops || -- !S_ISREG(file_inode(f.file)->i_mode)) -+ (!S_ISREG(file_inode(f.file)->i_mode) && -+ !S_ISBLK(file_inode(f.file)->i_mode))) - goto out; - - ret = vfs_fadvise(f.file, offset, count, POSIX_FADV_WILLNEED); -diff --git a/net/9p/client.c b/net/9p/client.c -index af59c3f2ec2e7..a96e127ca4883 100644 ---- a/net/9p/client.c -+++ b/net/9p/client.c -@@ -537,12 +537,14 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) - return 0; - - if (!p9_is_proto_dotl(c)) { -- char *ename; -+ char *ename = NULL; - - err = p9pdu_readf(&req->rc, c->proto_version, "s?d", - &ename, &ecode); -- if (err) -+ if (err) { -+ kfree(ename); - goto out_err; -+ } - - if (p9_is_proto_dotu(c) && ecode < 512) - err = -ecode; -diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c -index 5218c4dfe0a89..d74fe13f3dceb 100644 ---- a/net/bluetooth/hci_sync.c -+++ b/net/bluetooth/hci_sync.c -@@ -151,7 +151,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen, - struct sk_buff *skb; - int err = 0; - -- bt_dev_dbg(hdev, "Opcode 0x%4x", opcode); -+ bt_dev_dbg(hdev, "Opcode 0x%4.4x", opcode); - - hci_req_init(&req, hdev); - -@@ -247,7 +247,7 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen, - skb = __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout, sk); - if (IS_ERR(skb)) { - if (!event) -- bt_dev_err(hdev, "Opcode 0x%4x failed: %ld", opcode, -+ bt_dev_err(hdev, "Opcode 0x%4.4x failed: %ld", opcode, - PTR_ERR(skb)); - return PTR_ERR(skb); - } -diff --git a/net/core/page_pool.c b/net/core/page_pool.c -index 2396c99bedeaa..caf6d950d54ad 100644 ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -209,8 +209,12 @@ static int page_pool_init(struct page_pool *pool, - return -ENOMEM; - #endif - -- if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0) -+ if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0) { -+#ifdef CONFIG_PAGE_POOL_STATS -+ free_percpu(pool->recycle_stats); -+#endif - return -ENOMEM; -+ } - - atomic_set(&pool->pages_state_release_cnt, 0); - -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 8dca4a7ca4a1f..73b1e0e53534e 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -3958,6 +3958,7 @@ static void skb_ts_finish(struct ts_config *conf, struct ts_state *state) - unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, - unsigned int to, struct ts_config *config) - { -+ unsigned int patlen = config->ops->get_pattern_len(config); - struct ts_state state; - unsigned int ret; - -@@ -3969,7 +3970,7 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, - skb_prepare_seq_read(skb, from, to, TS_SKB_CB(&state)); - - ret = textsearch_find(config, &state); -- return (ret <= to - from ? ret : UINT_MAX); -+ return (ret + patlen <= to - from ? ret : UINT_MAX); - } - EXPORT_SYMBOL(skb_find_text); - -diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c -index 247179d4c8865..9fe6d96797169 100644 ---- a/net/dccp/ipv4.c -+++ b/net/dccp/ipv4.c -@@ -628,9 +628,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) - if (dccp_parse_options(sk, dreq, skb)) - goto drop_and_free; - -- if (security_inet_conn_request(sk, skb, req)) -- goto drop_and_free; -- - ireq = inet_rsk(req); - sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); - sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); -@@ -638,6 +635,9 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) - ireq->ireq_family = AF_INET; - ireq->ir_iif = READ_ONCE(sk->sk_bound_dev_if); - -+ if (security_inet_conn_request(sk, skb, req)) -+ goto drop_and_free; -+ - /* - * Step 3: Process LISTEN state - * -diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c -index 6fb34eaf1237a..e0b0bf75a46c2 100644 ---- a/net/dccp/ipv6.c -+++ b/net/dccp/ipv6.c -@@ -359,15 +359,15 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) - if (dccp_parse_options(sk, dreq, skb)) - goto drop_and_free; - -- if (security_inet_conn_request(sk, skb, req)) -- goto drop_and_free; -- - ireq = inet_rsk(req); - ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; - ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; - ireq->ireq_family = AF_INET6; - ireq->ir_mark = inet_request_mark(sk, skb); - -+ if (security_inet_conn_request(sk, skb, req)) -+ goto drop_and_free; -+ - if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) || - np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || - np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { -diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c -index b71dab630a873..80cdc6f6b34c9 100644 ---- a/net/hsr/hsr_forward.c -+++ b/net/hsr/hsr_forward.c -@@ -342,9 +342,7 @@ struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame, - skb = skb_copy_expand(frame->skb_std, 0, - skb_tailroom(frame->skb_std) + HSR_HLEN, - GFP_ATOMIC); -- prp_fill_rct(skb, frame, port); -- -- return skb; -+ return prp_fill_rct(skb, frame, port); - } - - static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev, -diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c -index 26fb97d1d4d9a..f9514cf87649e 100644 ---- a/net/ipv4/syncookies.c -+++ b/net/ipv4/syncookies.c -@@ -41,7 +41,6 @@ static siphash_aligned_key_t syncookie_secret[2]; - * requested/supported by the syn/synack exchange. - */ - #define TSBITS 6 --#define TSMASK (((__u32)1 << TSBITS) - 1) - - static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, - u32 count, int c) -@@ -62,27 +61,22 @@ static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, - */ - u64 cookie_init_timestamp(struct request_sock *req, u64 now) - { -- struct inet_request_sock *ireq; -- u32 ts, ts_now = tcp_ns_to_ts(now); -+ const struct inet_request_sock *ireq = inet_rsk(req); -+ u64 ts, ts_now = tcp_ns_to_ts(now); - u32 options = 0; - -- ireq = inet_rsk(req); -- - options = ireq->wscale_ok ? ireq->snd_wscale : TS_OPT_WSCALE_MASK; - if (ireq->sack_ok) - options |= TS_OPT_SACK; - if (ireq->ecn_ok) - options |= TS_OPT_ECN; - -- ts = ts_now & ~TSMASK; -+ ts = (ts_now >> TSBITS) << TSBITS; - ts |= options; -- if (ts > ts_now) { -- ts >>= TSBITS; -- ts--; -- ts <<= TSBITS; -- ts |= options; -- } -- return (u64)ts * (NSEC_PER_SEC / TCP_TS_HZ); -+ if (ts > ts_now) -+ ts -= (1UL << TSBITS); -+ -+ return ts * (NSEC_PER_SEC / TCP_TS_HZ); - } - - -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index d63942202493d..65dae3d43684f 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -6420,22 +6420,23 @@ reset_and_undo: - - static void tcp_rcv_synrecv_state_fastopen(struct sock *sk) - { -+ struct tcp_sock *tp = tcp_sk(sk); - struct request_sock *req; - - /* If we are still handling the SYNACK RTO, see if timestamp ECR allows - * undo. If peer SACKs triggered fast recovery, we can't undo here. - */ -- if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) -- tcp_try_undo_loss(sk, false); -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss && !tp->packets_out) -+ tcp_try_undo_recovery(sk); - - /* Reset rtx states to prevent spurious retransmits_timed_out() */ -- tcp_sk(sk)->retrans_stamp = 0; -+ tp->retrans_stamp = 0; - inet_csk(sk)->icsk_retransmits = 0; - - /* Once we leave TCP_SYN_RECV or TCP_FIN_WAIT_1, - * we no longer need req so release it. - */ -- req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, -+ req = rcu_dereference_protected(tp->fastopen_rsk, - lockdep_sock_is_held(sk)); - reqsk_fastopen_remove(sk, req, false); - -diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c -index 99ac5efe244d3..a7364ff8b558d 100644 ---- a/net/ipv4/tcp_metrics.c -+++ b/net/ipv4/tcp_metrics.c -@@ -470,11 +470,15 @@ void tcp_init_metrics(struct sock *sk) - u32 val, crtt = 0; /* cached RTT scaled by 8 */ - - sk_dst_confirm(sk); -+ /* ssthresh may have been reduced unnecessarily during. -+ * 3WHS. Restore it back to its initial default. -+ */ -+ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; - if (!dst) - goto reset; - - rcu_read_lock(); -- tm = tcp_get_metrics(sk, dst, true); -+ tm = tcp_get_metrics(sk, dst, false); - if (!tm) { - rcu_read_unlock(); - goto reset; -@@ -489,11 +493,6 @@ void tcp_init_metrics(struct sock *sk) - tp->snd_ssthresh = val; - if (tp->snd_ssthresh > tp->snd_cwnd_clamp) - tp->snd_ssthresh = tp->snd_cwnd_clamp; -- } else { -- /* ssthresh may have been reduced unnecessarily during. -- * 3WHS. Restore it back to its initial default. -- */ -- tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; - } - val = tcp_metric_get(tm, TCP_METRIC_REORDERING); - if (val && tp->reordering != val) -@@ -908,7 +907,7 @@ static void tcp_metrics_flush_all(struct net *net) - match = net ? net_eq(tm_net(tm), net) : - !refcount_read(&tm_net(tm)->ns.count); - if (match) { -- *pp = tm->tcpm_next; -+ rcu_assign_pointer(*pp, tm->tcpm_next); - kfree_rcu(tm, rcu_head); - } else { - pp = &tm->tcpm_next; -@@ -949,7 +948,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info) - if (addr_same(&tm->tcpm_daddr, &daddr) && - (!src || addr_same(&tm->tcpm_saddr, &saddr)) && - net_eq(tm_net(tm), net)) { -- *pp = tm->tcpm_next; -+ rcu_assign_pointer(*pp, tm->tcpm_next); - kfree_rcu(tm, rcu_head); - found = true; - } else { -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index b2aa7777521f6..65abc92a81bd0 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -2714,10 +2714,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, - case UDP_ENCAP_ESPINUDP_NON_IKE: - #if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family == AF_INET6) -- up->encap_rcv = ipv6_stub->xfrm6_udp_encap_rcv; -+ WRITE_ONCE(up->encap_rcv, -+ ipv6_stub->xfrm6_udp_encap_rcv); - else - #endif -- up->encap_rcv = xfrm4_udp_encap_rcv; -+ WRITE_ONCE(up->encap_rcv, -+ xfrm4_udp_encap_rcv); - #endif - fallthrough; - case UDP_ENCAP_L2TPINUDP: -diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c -index ce2c5e728745f..3c2b2a85de367 100644 ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -161,7 +161,13 @@ ip6_finish_output_gso_slowpath_drop(struct net *net, struct sock *sk, - int err; - - skb_mark_not_on_list(segs); -- err = ip6_fragment(net, sk, segs, ip6_finish_output2); -+ /* Last GSO segment can be smaller than gso_size (and MTU). -+ * Adding a fragment header would produce an "atomic fragment", -+ * which is considered harmful (RFC-8021). Avoid that. -+ */ -+ err = segs->len > mtu ? -+ ip6_fragment(net, sk, segs, ip6_finish_output2) : -+ ip6_finish_output2(net, sk, segs); - if (err && ret == 0) - ret = err; - } -diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c -index 5014aa6634527..8698b49dfc8de 100644 ---- a/net/ipv6/syncookies.c -+++ b/net/ipv6/syncookies.c -@@ -180,14 +180,15 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) - treq = tcp_rsk(req); - treq->tfo_listener = false; - -- if (security_inet_conn_request(sk, skb, req)) -- goto out_free; -- - req->mss = mss; - ireq->ir_rmt_port = th->source; - ireq->ir_num = ntohs(th->dest); - ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; - ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; -+ -+ if (security_inet_conn_request(sk, skb, req)) -+ goto out_free; -+ - if (ipv6_opt_accepted(sk, skb, &TCP_SKB_CB(skb)->header.h6) || - np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || - np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { -diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c -index 7cac441862e21..51bccfb00a9cd 100644 ---- a/net/llc/llc_input.c -+++ b/net/llc/llc_input.c -@@ -127,8 +127,14 @@ static inline int llc_fixup_skb(struct sk_buff *skb) - skb->transport_header += llc_len; - skb_pull(skb, llc_len); - if (skb->protocol == htons(ETH_P_802_2)) { -- __be16 pdulen = eth_hdr(skb)->h_proto; -- s32 data_size = ntohs(pdulen) - llc_len; -+ __be16 pdulen; -+ s32 data_size; -+ -+ if (skb->mac_len < ETH_HLEN) -+ return 0; -+ -+ pdulen = eth_hdr(skb)->h_proto; -+ data_size = ntohs(pdulen) - llc_len; - - if (data_size < 0 || - !pskb_may_pull(skb, data_size)) -diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c -index 79d1cef8f15a9..06fb8e6944b06 100644 ---- a/net/llc/llc_s_ac.c -+++ b/net/llc/llc_s_ac.c -@@ -153,6 +153,9 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb) - int rc = 1; - u32 data_size; - -+ if (skb->mac_len < ETH_HLEN) -+ return 1; -+ - llc_pdu_decode_sa(skb, mac_da); - llc_pdu_decode_da(skb, mac_sa); - llc_pdu_decode_ssap(skb, &dsap); -diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c -index 05c6ae0920534..f506542925109 100644 ---- a/net/llc/llc_station.c -+++ b/net/llc/llc_station.c -@@ -76,6 +76,9 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) - u32 data_size; - struct sk_buff *nskb; - -+ if (skb->mac_len < ETH_HLEN) -+ goto out; -+ - /* The test request command is type U (llc_len = 3) */ - data_size = ntohs(eth_hdr(skb)->h_proto) - 3; - nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size); -diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h -index 99a976ea17498..d5dd2d9e89b48 100644 ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1361,7 +1361,7 @@ struct ieee80211_local { - /* wowlan is enabled -- don't reconfig on resume */ - bool wowlan; - -- struct work_struct radar_detected_work; -+ struct wiphy_work radar_detected_work; - - /* number of RX chains the hardware has */ - u8 rx_chains; -@@ -1438,14 +1438,14 @@ struct ieee80211_local { - int hw_scan_ies_bufsize; - struct cfg80211_scan_info scan_info; - -- struct work_struct sched_scan_stopped_work; -+ struct wiphy_work sched_scan_stopped_work; - struct ieee80211_sub_if_data __rcu *sched_scan_sdata; - struct cfg80211_sched_scan_request __rcu *sched_scan_req; - u8 scan_addr[ETH_ALEN]; - - unsigned long leave_oper_channel_time; - enum mac80211_scan_state next_scan_state; -- struct delayed_work scan_work; -+ struct wiphy_delayed_work scan_work; - struct ieee80211_sub_if_data __rcu *scan_sdata; - /* For backward compatibility only -- do not use */ - struct cfg80211_chan_def _oper_chandef; -@@ -1538,9 +1538,9 @@ struct ieee80211_local { - /* - * Remain-on-channel support - */ -- struct delayed_work roc_work; -+ struct wiphy_delayed_work roc_work; - struct list_head roc_list; -- struct work_struct hw_roc_start, hw_roc_done; -+ struct wiphy_work hw_roc_start, hw_roc_done; - unsigned long hw_roc_start_time; - u64 roc_cookie_counter; - -@@ -1862,7 +1862,7 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, - int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata); - - /* scan/BSS handling */ --void ieee80211_scan_work(struct work_struct *work); -+void ieee80211_scan_work(struct wiphy *wiphy, struct wiphy_work *work); - int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, - const u8 *ssid, u8 ssid_len, - struct ieee80211_channel **channels, -@@ -1892,7 +1892,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, - struct cfg80211_sched_scan_request *req); - int ieee80211_request_sched_scan_stop(struct ieee80211_local *local); - void ieee80211_sched_scan_end(struct ieee80211_local *local); --void ieee80211_sched_scan_stopped_work(struct work_struct *work); -+void ieee80211_sched_scan_stopped_work(struct wiphy *wiphy, -+ struct wiphy_work *work); - - /* off-channel/mgmt-tx */ - void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local); -@@ -2483,7 +2484,8 @@ bool ieee80211_is_radar_required(struct ieee80211_local *local); - void ieee80211_dfs_cac_timer(unsigned long data); - void ieee80211_dfs_cac_timer_work(struct work_struct *work); - void ieee80211_dfs_cac_cancel(struct ieee80211_local *local); --void ieee80211_dfs_radar_detected_work(struct work_struct *work); -+void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy, -+ struct wiphy_work *work); - int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, - struct cfg80211_csa_settings *csa_settings); - -diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c -index 8dd3c10a99e0b..e00e1bf0f754a 100644 ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -697,7 +697,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do - ieee80211_recalc_ps(local); - - if (cancel_scan) -- flush_delayed_work(&local->scan_work); -+ wiphy_delayed_work_flush(local->hw.wiphy, &local->scan_work); - - if (local->open_count == 0) { - ieee80211_stop_device(local); -diff --git a/net/mac80211/main.c b/net/mac80211/main.c -index 02b5abc7326bc..6faba47b7b0ea 100644 ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -334,10 +334,7 @@ static void ieee80211_restart_work(struct work_struct *work) - struct ieee80211_sub_if_data *sdata; - int ret; - -- /* wait for scan work complete */ - flush_workqueue(local->workqueue); -- flush_work(&local->sched_scan_stopped_work); -- flush_work(&local->radar_detected_work); - - rtnl_lock(); - /* we might do interface manipulations, so need both */ -@@ -377,8 +374,8 @@ static void ieee80211_restart_work(struct work_struct *work) - ieee80211_scan_cancel(local); - - /* make sure any new ROC will consider local->in_reconfig */ -- flush_delayed_work(&local->roc_work); -- flush_work(&local->hw_roc_done); -+ wiphy_delayed_work_flush(local->hw.wiphy, &local->roc_work); -+ wiphy_work_flush(local->hw.wiphy, &local->hw_roc_done); - - /* wait for all packet processing to be done */ - synchronize_net(); -@@ -807,12 +804,12 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, - INIT_LIST_HEAD(&local->chanctx_list); - mutex_init(&local->chanctx_mtx); - -- INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); -+ wiphy_delayed_work_init(&local->scan_work, ieee80211_scan_work); - - INIT_WORK(&local->restart_work, ieee80211_restart_work); - -- INIT_WORK(&local->radar_detected_work, -- ieee80211_dfs_radar_detected_work); -+ wiphy_work_init(&local->radar_detected_work, -+ ieee80211_dfs_radar_detected_work); - - INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); - local->smps_mode = IEEE80211_SMPS_OFF; -@@ -823,8 +820,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, - ieee80211_dynamic_ps_disable_work); - timer_setup(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, 0); - -- INIT_WORK(&local->sched_scan_stopped_work, -- ieee80211_sched_scan_stopped_work); -+ wiphy_work_init(&local->sched_scan_stopped_work, -+ ieee80211_sched_scan_stopped_work); - - spin_lock_init(&local->ack_status_lock); - idr_init(&local->ack_status_frames); -@@ -1471,13 +1468,15 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) - */ - ieee80211_remove_interfaces(local); - -+ wiphy_lock(local->hw.wiphy); -+ wiphy_delayed_work_cancel(local->hw.wiphy, &local->roc_work); -+ wiphy_work_cancel(local->hw.wiphy, &local->sched_scan_stopped_work); -+ wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work); -+ wiphy_unlock(local->hw.wiphy); - rtnl_unlock(); - -- cancel_delayed_work_sync(&local->roc_work); - cancel_work_sync(&local->restart_work); - cancel_work_sync(&local->reconfig_filter); -- flush_work(&local->sched_scan_stopped_work); -- flush_work(&local->radar_detected_work); - - ieee80211_clear_tx_pending(local); - rate_control_deinitialize(local); -diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c -index d78c82d6b6966..50dc379ca097e 100644 ---- a/net/mac80211/offchannel.c -+++ b/net/mac80211/offchannel.c -@@ -230,7 +230,7 @@ static bool ieee80211_recalc_sw_work(struct ieee80211_local *local, - if (dur == LONG_MAX) - return false; - -- mod_delayed_work(local->workqueue, &local->roc_work, dur); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, dur); - return true; - } - -@@ -258,7 +258,7 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc, - roc->notified = true; - } - --static void ieee80211_hw_roc_start(struct work_struct *work) -+static void ieee80211_hw_roc_start(struct wiphy *wiphy, struct wiphy_work *work) - { - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, hw_roc_start); -@@ -285,7 +285,7 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw) - - trace_api_ready_on_channel(local); - -- ieee80211_queue_work(hw, &local->hw_roc_start); -+ wiphy_work_queue(hw->wiphy, &local->hw_roc_start); - } - EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel); - -@@ -338,7 +338,7 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) - tmp->started = true; - tmp->abort = true; - } -- ieee80211_queue_work(&local->hw, &local->hw_roc_done); -+ wiphy_work_queue(local->hw.wiphy, &local->hw_roc_done); - return; - } - -@@ -368,8 +368,8 @@ static void _ieee80211_start_next_roc(struct ieee80211_local *local) - ieee80211_hw_config(local, 0); - } - -- ieee80211_queue_delayed_work(&local->hw, &local->roc_work, -- msecs_to_jiffies(min_dur)); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, -+ msecs_to_jiffies(min_dur)); - - /* tell userspace or send frame(s) */ - list_for_each_entry(tmp, &local->roc_list, list) { -@@ -407,8 +407,8 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) - _ieee80211_start_next_roc(local); - } else { - /* delay it a bit */ -- ieee80211_queue_delayed_work(&local->hw, &local->roc_work, -- round_jiffies_relative(HZ/2)); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, -+ round_jiffies_relative(HZ / 2)); - } - } - -@@ -451,7 +451,7 @@ static void __ieee80211_roc_work(struct ieee80211_local *local) - } - } - --static void ieee80211_roc_work(struct work_struct *work) -+static void ieee80211_roc_work(struct wiphy *wiphy, struct wiphy_work *work) - { - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, roc_work.work); -@@ -461,7 +461,7 @@ static void ieee80211_roc_work(struct work_struct *work) - mutex_unlock(&local->mtx); - } - --static void ieee80211_hw_roc_done(struct work_struct *work) -+static void ieee80211_hw_roc_done(struct wiphy *wiphy, struct wiphy_work *work) - { - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, hw_roc_done); -@@ -482,7 +482,7 @@ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw) - - trace_api_remain_on_channel_expired(local); - -- ieee80211_queue_work(hw, &local->hw_roc_done); -+ wiphy_work_queue(hw->wiphy, &local->hw_roc_done); - } - EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired); - -@@ -586,8 +586,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, - /* if not HW assist, just queue & schedule work */ - if (!local->ops->remain_on_channel) { - list_add_tail(&roc->list, &local->roc_list); -- ieee80211_queue_delayed_work(&local->hw, -- &local->roc_work, 0); -+ wiphy_delayed_work_queue(local->hw.wiphy, -+ &local->roc_work, 0); - } else { - /* otherwise actually kick it off here - * (for error handling) -@@ -695,7 +695,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, - if (!cookie) - return -ENOENT; - -- flush_work(&local->hw_roc_start); -+ wiphy_work_flush(local->hw.wiphy, &local->hw_roc_start); - - mutex_lock(&local->mtx); - list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { -@@ -745,7 +745,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, - } else { - /* go through work struct to return to the operating channel */ - found->abort = true; -- mod_delayed_work(local->workqueue, &local->roc_work, 0); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, 0); - } - - out_unlock: -@@ -994,9 +994,9 @@ int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, - - void ieee80211_roc_setup(struct ieee80211_local *local) - { -- INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start); -- INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done); -- INIT_DELAYED_WORK(&local->roc_work, ieee80211_roc_work); -+ wiphy_work_init(&local->hw_roc_start, ieee80211_hw_roc_start); -+ wiphy_work_init(&local->hw_roc_done, ieee80211_hw_roc_done); -+ wiphy_delayed_work_init(&local->roc_work, ieee80211_roc_work); - INIT_LIST_HEAD(&local->roc_list); - } - -diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c -index dc3cdee51e660..c37e2576f1c13 100644 ---- a/net/mac80211/scan.c -+++ b/net/mac80211/scan.c -@@ -291,8 +291,8 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) - * the beacon/proberesp rx gives us an opportunity to upgrade - * to active scan - */ -- set_bit(SCAN_BEACON_DONE, &local->scanning); -- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); -+ set_bit(SCAN_BEACON_DONE, &local->scanning); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0); - } - - if (ieee80211_is_probe_resp(mgmt->frame_control)) { -@@ -522,7 +522,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, - - memcpy(&local->scan_info, info, sizeof(*info)); - -- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0); - } - EXPORT_SYMBOL(ieee80211_scan_completed); - -@@ -562,8 +562,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local, - /* We need to set power level at maximum rate for scanning. */ - ieee80211_hw_config(local, 0); - -- ieee80211_queue_delayed_work(&local->hw, -- &local->scan_work, 0); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0); - - return 0; - } -@@ -620,8 +619,8 @@ void ieee80211_run_deferred_scan(struct ieee80211_local *local) - lockdep_is_held(&local->mtx)))) - return; - -- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, -- round_jiffies_relative(0)); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, -+ round_jiffies_relative(0)); - } - - static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata, -@@ -812,8 +811,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, - } - - /* Now, just wait a bit and we are all done! */ -- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, -- next_delay); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, -+ next_delay); - return 0; - } else { - /* Do normal software scan */ -@@ -1060,7 +1059,7 @@ static void ieee80211_scan_state_resume(struct ieee80211_local *local, - local->next_scan_state = SCAN_SET_CHANNEL; - } - --void ieee80211_scan_work(struct work_struct *work) -+void ieee80211_scan_work(struct wiphy *wiphy, struct wiphy_work *work) - { - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, scan_work.work); -@@ -1154,7 +1153,8 @@ void ieee80211_scan_work(struct work_struct *work) - } - } while (next_delay == 0); - -- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, -+ next_delay); - goto out; - - out_complete: -@@ -1297,12 +1297,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) - goto out; - } - -- /* -- * If the work is currently running, it must be blocked on -- * the mutex, but we'll set scan_sdata = NULL and it'll -- * simply exit once it acquires the mutex. -- */ -- cancel_delayed_work(&local->scan_work); -+ wiphy_delayed_work_cancel(local->hw.wiphy, &local->scan_work); - /* and clean up */ - memset(&local->scan_info, 0, sizeof(local->scan_info)); - __ieee80211_scan_completed(&local->hw, true); -@@ -1444,10 +1439,11 @@ void ieee80211_sched_scan_end(struct ieee80211_local *local) - - mutex_unlock(&local->mtx); - -- cfg80211_sched_scan_stopped(local->hw.wiphy, 0); -+ cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0); - } - --void ieee80211_sched_scan_stopped_work(struct work_struct *work) -+void ieee80211_sched_scan_stopped_work(struct wiphy *wiphy, -+ struct wiphy_work *work) - { - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, -@@ -1470,6 +1466,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) - if (local->in_reconfig) - return; - -- schedule_work(&local->sched_scan_stopped_work); -+ wiphy_work_queue(hw->wiphy, &local->sched_scan_stopped_work); - } - EXPORT_SYMBOL(ieee80211_sched_scan_stopped); -diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c -index b8c6f6a668fc9..49b71453dec37 100644 ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -2918,7 +2918,7 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta, - WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB) << 1; - - if (val) -- sta->sta.max_amsdu_subframes = 4 << val; -+ sta->sta.max_amsdu_subframes = 4 << (4 - val); - } - - #ifdef CONFIG_LOCKDEP -diff --git a/net/mac80211/util.c b/net/mac80211/util.c -index 98806c359b173..1088d90e355ba 100644 ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -2234,8 +2234,8 @@ static void ieee80211_flush_completed_scan(struct ieee80211_local *local, - */ - if (aborted) - set_bit(SCAN_ABORTED, &local->scanning); -- ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); -- flush_delayed_work(&local->scan_work); -+ wiphy_delayed_work_queue(local->hw.wiphy, &local->scan_work, 0); -+ wiphy_delayed_work_flush(local->hw.wiphy, &local->scan_work); - } - } - -@@ -4069,7 +4069,8 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) - mutex_unlock(&local->mtx); - } - --void ieee80211_dfs_radar_detected_work(struct work_struct *work) -+void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy, -+ struct wiphy_work *work) - { - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, radar_detected_work); -@@ -4087,9 +4088,7 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work) - } - mutex_unlock(&local->chanctx_mtx); - -- wiphy_lock(local->hw.wiphy); - ieee80211_dfs_cac_cancel(local); -- wiphy_unlock(local->hw.wiphy); - - if (num_chanctx > 1) - /* XXX: multi-channel is not supported yet */ -@@ -4104,7 +4103,7 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw) - - trace_api_radar_detected(local); - -- schedule_work(&local->radar_detected_work); -+ wiphy_work_queue(hw->wiphy, &local->radar_detected_work); - } - EXPORT_SYMBOL(ieee80211_radar_detected); - -diff --git a/net/netfilter/nf_nat_redirect.c b/net/netfilter/nf_nat_redirect.c -index f91579c821e9a..5b37487d9d11f 100644 ---- a/net/netfilter/nf_nat_redirect.c -+++ b/net/netfilter/nf_nat_redirect.c -@@ -10,6 +10,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -24,81 +25,104 @@ - #include - #include - -+static unsigned int -+nf_nat_redirect(struct sk_buff *skb, const struct nf_nat_range2 *range, -+ const union nf_inet_addr *newdst) -+{ -+ struct nf_nat_range2 newrange; -+ enum ip_conntrack_info ctinfo; -+ struct nf_conn *ct; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ -+ memset(&newrange, 0, sizeof(newrange)); -+ -+ newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS; -+ newrange.min_addr = *newdst; -+ newrange.max_addr = *newdst; -+ newrange.min_proto = range->min_proto; -+ newrange.max_proto = range->max_proto; -+ -+ return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); -+} -+ - unsigned int --nf_nat_redirect_ipv4(struct sk_buff *skb, -- const struct nf_nat_ipv4_multi_range_compat *mr, -+nf_nat_redirect_ipv4(struct sk_buff *skb, const struct nf_nat_range2 *range, - unsigned int hooknum) - { -- struct nf_conn *ct; -- enum ip_conntrack_info ctinfo; -- __be32 newdst; -- struct nf_nat_range2 newrange; -+ union nf_inet_addr newdst = {}; - - WARN_ON(hooknum != NF_INET_PRE_ROUTING && - hooknum != NF_INET_LOCAL_OUT); - -- ct = nf_ct_get(skb, &ctinfo); -- WARN_ON(!(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED))); -- - /* Local packets: make them go to loopback */ - if (hooknum == NF_INET_LOCAL_OUT) { -- newdst = htonl(0x7F000001); -+ newdst.ip = htonl(INADDR_LOOPBACK); - } else { - const struct in_device *indev; - -- newdst = 0; -- - indev = __in_dev_get_rcu(skb->dev); - if (indev) { - const struct in_ifaddr *ifa; - - ifa = rcu_dereference(indev->ifa_list); - if (ifa) -- newdst = ifa->ifa_local; -+ newdst.ip = ifa->ifa_local; - } - -- if (!newdst) -+ if (!newdst.ip) - return NF_DROP; - } - -- /* Transfer from original range. */ -- memset(&newrange.min_addr, 0, sizeof(newrange.min_addr)); -- memset(&newrange.max_addr, 0, sizeof(newrange.max_addr)); -- newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS; -- newrange.min_addr.ip = newdst; -- newrange.max_addr.ip = newdst; -- newrange.min_proto = mr->range[0].min; -- newrange.max_proto = mr->range[0].max; -- -- /* Hand modified range to generic setup. */ -- return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); -+ return nf_nat_redirect(skb, range, &newdst); - } - EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4); - - static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; - -+static bool nf_nat_redirect_ipv6_usable(const struct inet6_ifaddr *ifa, unsigned int scope) -+{ -+ unsigned int ifa_addr_type = ipv6_addr_type(&ifa->addr); -+ -+ if (ifa_addr_type & IPV6_ADDR_MAPPED) -+ return false; -+ -+ if ((ifa->flags & IFA_F_TENTATIVE) && (!(ifa->flags & IFA_F_OPTIMISTIC))) -+ return false; -+ -+ if (scope) { -+ unsigned int ifa_scope = ifa_addr_type & IPV6_ADDR_SCOPE_MASK; -+ -+ if (!(scope & ifa_scope)) -+ return false; -+ } -+ -+ return true; -+} -+ - unsigned int - nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, - unsigned int hooknum) - { -- struct nf_nat_range2 newrange; -- struct in6_addr newdst; -- enum ip_conntrack_info ctinfo; -- struct nf_conn *ct; -+ union nf_inet_addr newdst = {}; - -- ct = nf_ct_get(skb, &ctinfo); - if (hooknum == NF_INET_LOCAL_OUT) { -- newdst = loopback_addr; -+ newdst.in6 = loopback_addr; - } else { -+ unsigned int scope = ipv6_addr_scope(&ipv6_hdr(skb)->daddr); - struct inet6_dev *idev; -- struct inet6_ifaddr *ifa; - bool addr = false; - - idev = __in6_dev_get(skb->dev); - if (idev != NULL) { -+ const struct inet6_ifaddr *ifa; -+ - read_lock_bh(&idev->lock); - list_for_each_entry(ifa, &idev->addr_list, if_list) { -- newdst = ifa->addr; -+ if (!nf_nat_redirect_ipv6_usable(ifa, scope)) -+ continue; -+ -+ newdst.in6 = ifa->addr; - addr = true; - break; - } -@@ -109,12 +133,6 @@ nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range, - return NF_DROP; - } - -- newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS; -- newrange.min_addr.in6 = newdst; -- newrange.max_addr.in6 = newdst; -- newrange.min_proto = range->min_proto; -- newrange.max_proto = range->max_proto; -- -- return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); -+ return nf_nat_redirect(skb, range, &newdst); - } - EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv6); -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 5c783199b4999..d6d59e36d17a7 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -3279,10 +3279,6 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, - goto cont_skip; - if (*idx < s_idx) - goto cont; -- if (*idx > s_idx) { -- memset(&cb->args[1], 0, -- sizeof(cb->args) - sizeof(cb->args[0])); -- } - if (prule) - handle = prule->handle; - else -diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c -index 5ed64b2bd15e8..08b408d3e113d 100644 ---- a/net/netfilter/nft_redir.c -+++ b/net/netfilter/nft_redir.c -@@ -64,6 +64,8 @@ static int nft_redir_init(const struct nft_ctx *ctx, - } else { - priv->sreg_proto_max = priv->sreg_proto_min; - } -+ -+ priv->flags |= NF_NAT_RANGE_PROTO_SPECIFIED; - } - - if (tb[NFTA_REDIR_FLAGS]) { -@@ -98,25 +100,37 @@ nla_put_failure: - return -1; - } - --static void nft_redir_ipv4_eval(const struct nft_expr *expr, -- struct nft_regs *regs, -- const struct nft_pktinfo *pkt) -+static void nft_redir_eval(const struct nft_expr *expr, -+ struct nft_regs *regs, -+ const struct nft_pktinfo *pkt) - { -- struct nft_redir *priv = nft_expr_priv(expr); -- struct nf_nat_ipv4_multi_range_compat mr; -+ const struct nft_redir *priv = nft_expr_priv(expr); -+ struct nf_nat_range2 range; - -- memset(&mr, 0, sizeof(mr)); -+ memset(&range, 0, sizeof(range)); -+ range.flags = priv->flags; - if (priv->sreg_proto_min) { -- mr.range[0].min.all = (__force __be16)nft_reg_load16( -- ®s->data[priv->sreg_proto_min]); -- mr.range[0].max.all = (__force __be16)nft_reg_load16( -- ®s->data[priv->sreg_proto_max]); -- mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; -+ range.min_proto.all = (__force __be16) -+ nft_reg_load16(®s->data[priv->sreg_proto_min]); -+ range.max_proto.all = (__force __be16) -+ nft_reg_load16(®s->data[priv->sreg_proto_max]); - } - -- mr.range[0].flags |= priv->flags; -- -- regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr, nft_hook(pkt)); -+ switch (nft_pf(pkt)) { -+ case NFPROTO_IPV4: -+ regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &range, -+ nft_hook(pkt)); -+ break; -+#ifdef CONFIG_NF_TABLES_IPV6 -+ case NFPROTO_IPV6: -+ regs->verdict.code = nf_nat_redirect_ipv6(pkt->skb, &range, -+ nft_hook(pkt)); -+ break; -+#endif -+ default: -+ WARN_ON_ONCE(1); -+ break; -+ } - } - - static void -@@ -129,7 +143,7 @@ static struct nft_expr_type nft_redir_ipv4_type; - static const struct nft_expr_ops nft_redir_ipv4_ops = { - .type = &nft_redir_ipv4_type, - .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), -- .eval = nft_redir_ipv4_eval, -+ .eval = nft_redir_eval, - .init = nft_redir_init, - .destroy = nft_redir_ipv4_destroy, - .dump = nft_redir_dump, -@@ -147,28 +161,6 @@ static struct nft_expr_type nft_redir_ipv4_type __read_mostly = { - }; - - #ifdef CONFIG_NF_TABLES_IPV6 --static void nft_redir_ipv6_eval(const struct nft_expr *expr, -- struct nft_regs *regs, -- const struct nft_pktinfo *pkt) --{ -- struct nft_redir *priv = nft_expr_priv(expr); -- struct nf_nat_range2 range; -- -- memset(&range, 0, sizeof(range)); -- if (priv->sreg_proto_min) { -- range.min_proto.all = (__force __be16)nft_reg_load16( -- ®s->data[priv->sreg_proto_min]); -- range.max_proto.all = (__force __be16)nft_reg_load16( -- ®s->data[priv->sreg_proto_max]); -- range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; -- } -- -- range.flags |= priv->flags; -- -- regs->verdict.code = -- nf_nat_redirect_ipv6(pkt->skb, &range, nft_hook(pkt)); --} -- - static void - nft_redir_ipv6_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) - { -@@ -179,7 +171,7 @@ static struct nft_expr_type nft_redir_ipv6_type; - static const struct nft_expr_ops nft_redir_ipv6_ops = { - .type = &nft_redir_ipv6_type, - .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), -- .eval = nft_redir_ipv6_eval, -+ .eval = nft_redir_eval, - .init = nft_redir_init, - .destroy = nft_redir_ipv6_destroy, - .dump = nft_redir_dump, -@@ -198,20 +190,6 @@ static struct nft_expr_type nft_redir_ipv6_type __read_mostly = { - #endif - - #ifdef CONFIG_NF_TABLES_INET --static void nft_redir_inet_eval(const struct nft_expr *expr, -- struct nft_regs *regs, -- const struct nft_pktinfo *pkt) --{ -- switch (nft_pf(pkt)) { -- case NFPROTO_IPV4: -- return nft_redir_ipv4_eval(expr, regs, pkt); -- case NFPROTO_IPV6: -- return nft_redir_ipv6_eval(expr, regs, pkt); -- } -- -- WARN_ON_ONCE(1); --} -- - static void - nft_redir_inet_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) - { -@@ -222,7 +200,7 @@ static struct nft_expr_type nft_redir_inet_type; - static const struct nft_expr_ops nft_redir_inet_ops = { - .type = &nft_redir_inet_type, - .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), -- .eval = nft_redir_inet_eval, -+ .eval = nft_redir_eval, - .init = nft_redir_init, - .destroy = nft_redir_inet_destroy, - .dump = nft_redir_dump, -diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c -index 353ca7801251a..ff66b56a3f97d 100644 ---- a/net/netfilter/xt_REDIRECT.c -+++ b/net/netfilter/xt_REDIRECT.c -@@ -46,7 +46,6 @@ static void redirect_tg_destroy(const struct xt_tgdtor_param *par) - nf_ct_netns_put(par->net, par->family); - } - --/* FIXME: Take multiple ranges --RR */ - static int redirect_tg4_check(const struct xt_tgchk_param *par) - { - const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; -@@ -65,7 +64,14 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par) - static unsigned int - redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par) - { -- return nf_nat_redirect_ipv4(skb, par->targinfo, xt_hooknum(par)); -+ const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; -+ struct nf_nat_range2 range = { -+ .flags = mr->range[0].flags, -+ .min_proto = mr->range[0].min, -+ .max_proto = mr->range[0].max, -+ }; -+ -+ return nf_nat_redirect_ipv4(skb, &range, xt_hooknum(par)); - } - - static struct xt_target redirect_tg_reg[] __read_mostly = { -diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c -index 7ddb9a78e3fc8..ef93e0d3bee04 100644 ---- a/net/netfilter/xt_recent.c -+++ b/net/netfilter/xt_recent.c -@@ -561,7 +561,7 @@ recent_mt_proc_write(struct file *file, const char __user *input, - { - struct recent_table *t = pde_data(file_inode(file)); - struct recent_entry *e; -- char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")]; -+ char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:255.255.255.255")]; - const char *c = buf; - union nf_inet_addr addr = {}; - u_int16_t family; -diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c -index 4ea41d6e36969..d676119984c09 100644 ---- a/net/smc/af_smc.c -+++ b/net/smc/af_smc.c -@@ -274,7 +274,7 @@ static int __smc_release(struct smc_sock *smc) - - if (!smc->use_fallback) { - rc = smc_close_active(smc); -- sock_set_flag(sk, SOCK_DEAD); -+ smc_sock_set_flag(sk, SOCK_DEAD); - sk->sk_shutdown |= SHUTDOWN_MASK; - } else { - if (sk->sk_state != SMC_CLOSED) { -@@ -1710,7 +1710,7 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc) - if (new_clcsock) - sock_release(new_clcsock); - new_sk->sk_state = SMC_CLOSED; -- sock_set_flag(new_sk, SOCK_DEAD); -+ smc_sock_set_flag(new_sk, SOCK_DEAD); - sock_put(new_sk); /* final */ - *new_smc = NULL; - goto out; -diff --git a/net/smc/smc.h b/net/smc/smc.h -index 1d36720fc019c..bcb57e60b2155 100644 ---- a/net/smc/smc.h -+++ b/net/smc/smc.h -@@ -377,4 +377,9 @@ int smc_nl_dump_hs_limitation(struct sk_buff *skb, struct netlink_callback *cb); - int smc_nl_enable_hs_limitation(struct sk_buff *skb, struct genl_info *info); - int smc_nl_disable_hs_limitation(struct sk_buff *skb, struct genl_info *info); - -+static inline void smc_sock_set_flag(struct sock *sk, enum sock_flags flag) -+{ -+ set_bit(flag, &sk->sk_flags); -+} -+ - #endif /* __SMC_H */ -diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c -index 89105e95b4523..3c06625ceb200 100644 ---- a/net/smc/smc_cdc.c -+++ b/net/smc/smc_cdc.c -@@ -28,13 +28,15 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd, - { - struct smc_cdc_tx_pend *cdcpend = (struct smc_cdc_tx_pend *)pnd_snd; - struct smc_connection *conn = cdcpend->conn; -+ struct smc_buf_desc *sndbuf_desc; - struct smc_sock *smc; - int diff; - -+ sndbuf_desc = conn->sndbuf_desc; - smc = container_of(conn, struct smc_sock, conn); - bh_lock_sock(&smc->sk); -- if (!wc_status) { -- diff = smc_curs_diff(cdcpend->conn->sndbuf_desc->len, -+ if (!wc_status && sndbuf_desc) { -+ diff = smc_curs_diff(sndbuf_desc->len, - &cdcpend->conn->tx_curs_fin, - &cdcpend->cursor); - /* sndbuf_space is decreased in smc_sendmsg */ -@@ -114,9 +116,6 @@ int smc_cdc_msg_send(struct smc_connection *conn, - union smc_host_cursor cfed; - int rc; - -- if (unlikely(!READ_ONCE(conn->sndbuf_desc))) -- return -ENOBUFS; -- - smc_cdc_add_pending_send(conn, pend); - - conn->tx_cdc_seq++; -@@ -385,7 +384,7 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc, - smc->sk.sk_shutdown |= RCV_SHUTDOWN; - if (smc->clcsock && smc->clcsock->sk) - smc->clcsock->sk->sk_shutdown |= RCV_SHUTDOWN; -- sock_set_flag(&smc->sk, SOCK_DONE); -+ smc_sock_set_flag(&smc->sk, SOCK_DONE); - sock_hold(&smc->sk); /* sock_put in close_work */ - if (!queue_work(smc_close_wq, &conn->close_work)) - sock_put(&smc->sk); -diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c -index dbdf03e8aa5b5..10219f55aad14 100644 ---- a/net/smc/smc_close.c -+++ b/net/smc/smc_close.c -@@ -116,7 +116,8 @@ static void smc_close_cancel_work(struct smc_sock *smc) - struct sock *sk = &smc->sk; - - release_sock(sk); -- cancel_work_sync(&smc->conn.close_work); -+ if (cancel_work_sync(&smc->conn.close_work)) -+ sock_put(sk); - cancel_delayed_work_sync(&smc->conn.tx_work); - lock_sock(sk); - } -@@ -173,7 +174,7 @@ void smc_close_active_abort(struct smc_sock *smc) - break; - } - -- sock_set_flag(sk, SOCK_DEAD); -+ smc_sock_set_flag(sk, SOCK_DEAD); - sk->sk_state_change(sk); - - if (release_clcsock) { -diff --git a/net/tipc/link.c b/net/tipc/link.c -index 2eff1c7949cbc..8715c9b05f90d 100644 ---- a/net/tipc/link.c -+++ b/net/tipc/link.c -@@ -1446,7 +1446,7 @@ u16 tipc_get_gap_ack_blks(struct tipc_gap_ack_blks **ga, struct tipc_link *l, - p = (struct tipc_gap_ack_blks *)msg_data(hdr); - sz = ntohs(p->len); - /* Sanity check */ -- if (sz == struct_size(p, gacks, p->ugack_cnt + p->bgack_cnt)) { -+ if (sz == struct_size(p, gacks, size_add(p->ugack_cnt, p->bgack_cnt))) { - /* Good, check if the desired type exists */ - if ((uc && p->ugack_cnt) || (!uc && p->bgack_cnt)) - goto ok; -@@ -1533,7 +1533,7 @@ static u16 tipc_build_gap_ack_blks(struct tipc_link *l, struct tipc_msg *hdr) - __tipc_build_gap_ack_blks(ga, l, ga->bgack_cnt) : 0; - - /* Total len */ -- len = struct_size(ga, gacks, ga->bgack_cnt + ga->ugack_cnt); -+ len = struct_size(ga, gacks, size_add(ga->bgack_cnt, ga->ugack_cnt)); - ga->len = htons(len); - return len; - } -diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c -index e8fd257c0e688..1a9a5bdaccf4f 100644 ---- a/net/tipc/netlink.c -+++ b/net/tipc/netlink.c -@@ -88,7 +88,7 @@ const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { - - const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { - [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC }, -- [TIPC_NLA_LINK_NAME] = { .type = NLA_STRING, -+ [TIPC_NLA_LINK_NAME] = { .type = NLA_NUL_STRING, - .len = TIPC_MAX_LINK_NAME }, - [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 }, - [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG }, -@@ -125,7 +125,7 @@ const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { - - const struct nla_policy tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = { - [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC }, -- [TIPC_NLA_BEARER_NAME] = { .type = NLA_STRING, -+ [TIPC_NLA_BEARER_NAME] = { .type = NLA_NUL_STRING, - .len = TIPC_MAX_BEARER_NAME }, - [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED }, - [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 } -diff --git a/net/tls/tls.h b/net/tls/tls.h -index 17737a65c643a..0672acab27731 100644 ---- a/net/tls/tls.h -+++ b/net/tls/tls.h -@@ -70,6 +70,8 @@ struct tls_rec { - char content_type; - struct scatterlist sg_content_type; - -+ struct sock *sk; -+ - char aad_space[TLS_AAD_SPACE_SIZE]; - u8 iv_data[MAX_IV_SIZE]; - struct aead_request aead_req; -diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c -index 2af72d349192e..2e60bf06adff0 100644 ---- a/net/tls/tls_sw.c -+++ b/net/tls/tls_sw.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -57,6 +58,7 @@ struct tls_decrypt_arg { - }; - - struct tls_decrypt_ctx { -+ struct sock *sk; - u8 iv[MAX_IV_SIZE]; - u8 aad[TLS_MAX_AAD_SIZE]; - u8 tail; -@@ -179,18 +181,25 @@ static int tls_padding_length(struct tls_prot_info *prot, struct sk_buff *skb, - return sub; - } - --static void tls_decrypt_done(struct crypto_async_request *req, int err) -+static void tls_decrypt_done(crypto_completion_data_t *data, int err) - { -- struct aead_request *aead_req = (struct aead_request *)req; -+ struct aead_request *aead_req = crypto_get_completion_data(data); -+ struct crypto_aead *aead = crypto_aead_reqtfm(aead_req); - struct scatterlist *sgout = aead_req->dst; - struct scatterlist *sgin = aead_req->src; - struct tls_sw_context_rx *ctx; -+ struct tls_decrypt_ctx *dctx; - struct tls_context *tls_ctx; - struct scatterlist *sg; - unsigned int pages; - struct sock *sk; -+ int aead_size; - -- sk = (struct sock *)req->data; -+ aead_size = sizeof(*aead_req) + crypto_aead_reqsize(aead); -+ aead_size = ALIGN(aead_size, __alignof__(*dctx)); -+ dctx = (void *)((u8 *)aead_req + aead_size); -+ -+ sk = dctx->sk; - tls_ctx = tls_get_ctx(sk); - ctx = tls_sw_ctx_rx(tls_ctx); - -@@ -242,7 +251,7 @@ static int tls_do_decryption(struct sock *sk, - if (darg->async) { - aead_request_set_callback(aead_req, - CRYPTO_TFM_REQ_MAY_BACKLOG, -- tls_decrypt_done, sk); -+ tls_decrypt_done, aead_req); - atomic_inc(&ctx->decrypt_pending); - } else { - aead_request_set_callback(aead_req, -@@ -338,6 +347,8 @@ static struct tls_rec *tls_get_rec(struct sock *sk) - sg_set_buf(&rec->sg_aead_out[0], rec->aad_space, prot->aad_size); - sg_unmark_end(&rec->sg_aead_out[1]); - -+ rec->sk = sk; -+ - return rec; - } - -@@ -419,22 +430,27 @@ tx_err: - return rc; - } - --static void tls_encrypt_done(struct crypto_async_request *req, int err) -+static void tls_encrypt_done(crypto_completion_data_t *data, int err) - { -- struct aead_request *aead_req = (struct aead_request *)req; -- struct sock *sk = req->data; -- struct tls_context *tls_ctx = tls_get_ctx(sk); -- struct tls_prot_info *prot = &tls_ctx->prot_info; -- struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); -+ struct aead_request *aead_req = crypto_get_completion_data(data); -+ struct tls_sw_context_tx *ctx; -+ struct tls_context *tls_ctx; -+ struct tls_prot_info *prot; - struct scatterlist *sge; - struct sk_msg *msg_en; - struct tls_rec *rec; - bool ready = false; -+ struct sock *sk; - int pending; - - rec = container_of(aead_req, struct tls_rec, aead_req); - msg_en = &rec->msg_encrypted; - -+ sk = rec->sk; -+ tls_ctx = tls_get_ctx(sk); -+ prot = &tls_ctx->prot_info; -+ ctx = tls_sw_ctx_tx(tls_ctx); -+ - sge = sk_msg_elem(msg_en, msg_en->sg.curr); - sge->offset -= prot->prepend_size; - sge->length += prot->prepend_size; -@@ -522,7 +538,7 @@ static int tls_do_encryption(struct sock *sk, - data_len, rec->iv_data); - - aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG, -- tls_encrypt_done, sk); -+ tls_encrypt_done, aead_req); - - /* Add the record in tx_list */ - list_add_tail((struct list_head *)&rec->list, &ctx->tx_list); -@@ -1495,7 +1511,8 @@ static int tls_decrypt_sg(struct sock *sk, struct iov_iter *out_iov, - * Both structs are variable length. - */ - aead_size = sizeof(*aead_req) + crypto_aead_reqsize(ctx->aead_recv); -- mem = kmalloc(aead_size + struct_size(dctx, sg, n_sgin + n_sgout), -+ aead_size = ALIGN(aead_size, __alignof__(*dctx)); -+ mem = kmalloc(aead_size + struct_size(dctx, sg, size_add(n_sgin, n_sgout)), - sk->sk_allocation); - if (!mem) { - err = -ENOMEM; -@@ -1505,6 +1522,7 @@ static int tls_decrypt_sg(struct sock *sk, struct iov_iter *out_iov, - /* Segment the allocated memory */ - aead_req = (struct aead_request *)mem; - dctx = (struct tls_decrypt_ctx *)(mem + aead_size); -+ dctx->sk = sk; - sgin = &dctx->sg[0]; - sgout = &dctx->sg[n_sgin]; - -diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c -index 460e7fbb42da3..16575ea836590 100644 ---- a/net/vmw_vsock/virtio_transport.c -+++ b/net/vmw_vsock/virtio_transport.c -@@ -42,8 +42,7 @@ struct virtio_vsock { - bool tx_run; - - struct work_struct send_pkt_work; -- spinlock_t send_pkt_list_lock; -- struct list_head send_pkt_list; -+ struct sk_buff_head send_pkt_queue; - - atomic_t queued_replies; - -@@ -101,41 +100,31 @@ virtio_transport_send_pkt_work(struct work_struct *work) - vq = vsock->vqs[VSOCK_VQ_TX]; - - for (;;) { -- struct virtio_vsock_pkt *pkt; - struct scatterlist hdr, buf, *sgs[2]; - int ret, in_sg = 0, out_sg = 0; -+ struct sk_buff *skb; - bool reply; - -- spin_lock_bh(&vsock->send_pkt_list_lock); -- if (list_empty(&vsock->send_pkt_list)) { -- spin_unlock_bh(&vsock->send_pkt_list_lock); -+ skb = virtio_vsock_skb_dequeue(&vsock->send_pkt_queue); -+ if (!skb) - break; -- } -- -- pkt = list_first_entry(&vsock->send_pkt_list, -- struct virtio_vsock_pkt, list); -- list_del_init(&pkt->list); -- spin_unlock_bh(&vsock->send_pkt_list_lock); - -- virtio_transport_deliver_tap_pkt(pkt); -+ virtio_transport_deliver_tap_pkt(skb); -+ reply = virtio_vsock_skb_reply(skb); - -- reply = pkt->reply; -- -- sg_init_one(&hdr, &pkt->hdr, sizeof(pkt->hdr)); -+ sg_init_one(&hdr, virtio_vsock_hdr(skb), sizeof(*virtio_vsock_hdr(skb))); - sgs[out_sg++] = &hdr; -- if (pkt->buf) { -- sg_init_one(&buf, pkt->buf, pkt->len); -+ if (skb->len > 0) { -+ sg_init_one(&buf, skb->data, skb->len); - sgs[out_sg++] = &buf; - } - -- ret = virtqueue_add_sgs(vq, sgs, out_sg, in_sg, pkt, GFP_KERNEL); -+ ret = virtqueue_add_sgs(vq, sgs, out_sg, in_sg, skb, GFP_KERNEL); - /* Usually this means that there is no more space available in - * the vq - */ - if (ret < 0) { -- spin_lock_bh(&vsock->send_pkt_list_lock); -- list_add(&pkt->list, &vsock->send_pkt_list); -- spin_unlock_bh(&vsock->send_pkt_list_lock); -+ virtio_vsock_skb_queue_head(&vsock->send_pkt_queue, skb); - break; - } - -@@ -164,32 +153,32 @@ out: - } - - static int --virtio_transport_send_pkt(struct virtio_vsock_pkt *pkt) -+virtio_transport_send_pkt(struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr; - struct virtio_vsock *vsock; -- int len = pkt->len; -+ int len = skb->len; -+ -+ hdr = virtio_vsock_hdr(skb); - - rcu_read_lock(); - vsock = rcu_dereference(the_virtio_vsock); - if (!vsock) { -- virtio_transport_free_pkt(pkt); -+ kfree_skb(skb); - len = -ENODEV; - goto out_rcu; - } - -- if (le64_to_cpu(pkt->hdr.dst_cid) == vsock->guest_cid) { -- virtio_transport_free_pkt(pkt); -+ if (le64_to_cpu(hdr->dst_cid) == vsock->guest_cid) { -+ kfree_skb(skb); - len = -ENODEV; - goto out_rcu; - } - -- if (pkt->reply) -+ if (virtio_vsock_skb_reply(skb)) - atomic_inc(&vsock->queued_replies); - -- spin_lock_bh(&vsock->send_pkt_list_lock); -- list_add_tail(&pkt->list, &vsock->send_pkt_list); -- spin_unlock_bh(&vsock->send_pkt_list_lock); -- -+ virtio_vsock_skb_queue_tail(&vsock->send_pkt_queue, skb); - queue_work(virtio_vsock_workqueue, &vsock->send_pkt_work); - - out_rcu: -@@ -201,9 +190,7 @@ static int - virtio_transport_cancel_pkt(struct vsock_sock *vsk) - { - struct virtio_vsock *vsock; -- struct virtio_vsock_pkt *pkt, *n; - int cnt = 0, ret; -- LIST_HEAD(freeme); - - rcu_read_lock(); - vsock = rcu_dereference(the_virtio_vsock); -@@ -212,20 +199,7 @@ virtio_transport_cancel_pkt(struct vsock_sock *vsk) - goto out_rcu; - } - -- spin_lock_bh(&vsock->send_pkt_list_lock); -- list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) { -- if (pkt->vsk != vsk) -- continue; -- list_move(&pkt->list, &freeme); -- } -- spin_unlock_bh(&vsock->send_pkt_list_lock); -- -- list_for_each_entry_safe(pkt, n, &freeme, list) { -- if (pkt->reply) -- cnt++; -- list_del(&pkt->list); -- virtio_transport_free_pkt(pkt); -- } -+ cnt = virtio_transport_purge_skbs(vsk, &vsock->send_pkt_queue); - - if (cnt) { - struct virtqueue *rx_vq = vsock->vqs[VSOCK_VQ_RX]; -@@ -246,38 +220,28 @@ out_rcu: - - static void virtio_vsock_rx_fill(struct virtio_vsock *vsock) - { -- int buf_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE; -- struct virtio_vsock_pkt *pkt; -- struct scatterlist hdr, buf, *sgs[2]; -+ int total_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM; -+ struct scatterlist pkt, *p; - struct virtqueue *vq; -+ struct sk_buff *skb; - int ret; - - vq = vsock->vqs[VSOCK_VQ_RX]; - - do { -- pkt = kzalloc(sizeof(*pkt), GFP_KERNEL); -- if (!pkt) -+ skb = virtio_vsock_alloc_skb(total_len, GFP_KERNEL); -+ if (!skb) - break; - -- pkt->buf = kmalloc(buf_len, GFP_KERNEL); -- if (!pkt->buf) { -- virtio_transport_free_pkt(pkt); -+ memset(skb->head, 0, VIRTIO_VSOCK_SKB_HEADROOM); -+ sg_init_one(&pkt, virtio_vsock_hdr(skb), total_len); -+ p = &pkt; -+ ret = virtqueue_add_sgs(vq, &p, 0, 1, skb, GFP_KERNEL); -+ if (ret < 0) { -+ kfree_skb(skb); - break; - } - -- pkt->buf_len = buf_len; -- pkt->len = buf_len; -- -- sg_init_one(&hdr, &pkt->hdr, sizeof(pkt->hdr)); -- sgs[0] = &hdr; -- -- sg_init_one(&buf, pkt->buf, buf_len); -- sgs[1] = &buf; -- ret = virtqueue_add_sgs(vq, sgs, 0, 2, pkt, GFP_KERNEL); -- if (ret) { -- virtio_transport_free_pkt(pkt); -- break; -- } - vsock->rx_buf_nr++; - } while (vq->num_free); - if (vsock->rx_buf_nr > vsock->rx_buf_max_nr) -@@ -299,12 +263,12 @@ static void virtio_transport_tx_work(struct work_struct *work) - goto out; - - do { -- struct virtio_vsock_pkt *pkt; -+ struct sk_buff *skb; - unsigned int len; - - virtqueue_disable_cb(vq); -- while ((pkt = virtqueue_get_buf(vq, &len)) != NULL) { -- virtio_transport_free_pkt(pkt); -+ while ((skb = virtqueue_get_buf(vq, &len)) != NULL) { -+ consume_skb(skb); - added = true; - } - } while (!virtqueue_enable_cb(vq)); -@@ -529,7 +493,7 @@ static void virtio_transport_rx_work(struct work_struct *work) - do { - virtqueue_disable_cb(vq); - for (;;) { -- struct virtio_vsock_pkt *pkt; -+ struct sk_buff *skb; - unsigned int len; - - if (!virtio_transport_more_replies(vsock)) { -@@ -540,23 +504,22 @@ static void virtio_transport_rx_work(struct work_struct *work) - goto out; - } - -- pkt = virtqueue_get_buf(vq, &len); -- if (!pkt) { -+ skb = virtqueue_get_buf(vq, &len); -+ if (!skb) - break; -- } - - vsock->rx_buf_nr--; - - /* Drop short/long packets */ -- if (unlikely(len < sizeof(pkt->hdr) || -- len > sizeof(pkt->hdr) + pkt->len)) { -- virtio_transport_free_pkt(pkt); -+ if (unlikely(len < sizeof(struct virtio_vsock_hdr) || -+ len > virtio_vsock_skb_len(skb))) { -+ kfree_skb(skb); - continue; - } - -- pkt->len = len - sizeof(pkt->hdr); -- virtio_transport_deliver_tap_pkt(pkt); -- virtio_transport_recv_pkt(&virtio_transport, pkt); -+ virtio_vsock_skb_rx_put(skb); -+ virtio_transport_deliver_tap_pkt(skb); -+ virtio_transport_recv_pkt(&virtio_transport, skb); - } - } while (!virtqueue_enable_cb(vq)); - -@@ -624,7 +587,7 @@ static void virtio_vsock_vqs_start(struct virtio_vsock *vsock) - static void virtio_vsock_vqs_del(struct virtio_vsock *vsock) - { - struct virtio_device *vdev = vsock->vdev; -- struct virtio_vsock_pkt *pkt; -+ struct sk_buff *skb; - - /* Reset all connected sockets when the VQs disappear */ - vsock_for_each_connected_socket(&virtio_transport.transport, -@@ -651,23 +614,16 @@ static void virtio_vsock_vqs_del(struct virtio_vsock *vsock) - virtio_reset_device(vdev); - - mutex_lock(&vsock->rx_lock); -- while ((pkt = virtqueue_detach_unused_buf(vsock->vqs[VSOCK_VQ_RX]))) -- virtio_transport_free_pkt(pkt); -+ while ((skb = virtqueue_detach_unused_buf(vsock->vqs[VSOCK_VQ_RX]))) -+ kfree_skb(skb); - mutex_unlock(&vsock->rx_lock); - - mutex_lock(&vsock->tx_lock); -- while ((pkt = virtqueue_detach_unused_buf(vsock->vqs[VSOCK_VQ_TX]))) -- virtio_transport_free_pkt(pkt); -+ while ((skb = virtqueue_detach_unused_buf(vsock->vqs[VSOCK_VQ_TX]))) -+ kfree_skb(skb); - mutex_unlock(&vsock->tx_lock); - -- spin_lock_bh(&vsock->send_pkt_list_lock); -- while (!list_empty(&vsock->send_pkt_list)) { -- pkt = list_first_entry(&vsock->send_pkt_list, -- struct virtio_vsock_pkt, list); -- list_del(&pkt->list); -- virtio_transport_free_pkt(pkt); -- } -- spin_unlock_bh(&vsock->send_pkt_list_lock); -+ virtio_vsock_skb_queue_purge(&vsock->send_pkt_queue); - - /* Delete virtqueues and flush outstanding callbacks if any */ - vdev->config->del_vqs(vdev); -@@ -704,8 +660,7 @@ static int virtio_vsock_probe(struct virtio_device *vdev) - mutex_init(&vsock->tx_lock); - mutex_init(&vsock->rx_lock); - mutex_init(&vsock->event_lock); -- spin_lock_init(&vsock->send_pkt_list_lock); -- INIT_LIST_HEAD(&vsock->send_pkt_list); -+ skb_queue_head_init(&vsock->send_pkt_queue); - INIT_WORK(&vsock->rx_work, virtio_transport_rx_work); - INIT_WORK(&vsock->tx_work, virtio_transport_tx_work); - INIT_WORK(&vsock->event_work, virtio_transport_event_work); -diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c -index a9980e9b93040..79e79fd6efd19 100644 ---- a/net/vmw_vsock/virtio_transport_common.c -+++ b/net/vmw_vsock/virtio_transport_common.c -@@ -37,53 +37,58 @@ virtio_transport_get_ops(struct vsock_sock *vsk) - return container_of(t, struct virtio_transport, transport); - } - --static struct virtio_vsock_pkt * --virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info, -+/* Returns a new packet on success, otherwise returns NULL. -+ * -+ * If NULL is returned, errp is set to a negative errno. -+ */ -+static struct sk_buff * -+virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *info, - size_t len, - u32 src_cid, - u32 src_port, - u32 dst_cid, - u32 dst_port) - { -- struct virtio_vsock_pkt *pkt; -+ const size_t skb_len = VIRTIO_VSOCK_SKB_HEADROOM + len; -+ struct virtio_vsock_hdr *hdr; -+ struct sk_buff *skb; -+ void *payload; - int err; - -- pkt = kzalloc(sizeof(*pkt), GFP_KERNEL); -- if (!pkt) -+ skb = virtio_vsock_alloc_skb(skb_len, GFP_KERNEL); -+ if (!skb) - return NULL; - -- pkt->hdr.type = cpu_to_le16(info->type); -- pkt->hdr.op = cpu_to_le16(info->op); -- pkt->hdr.src_cid = cpu_to_le64(src_cid); -- pkt->hdr.dst_cid = cpu_to_le64(dst_cid); -- pkt->hdr.src_port = cpu_to_le32(src_port); -- pkt->hdr.dst_port = cpu_to_le32(dst_port); -- pkt->hdr.flags = cpu_to_le32(info->flags); -- pkt->len = len; -- pkt->hdr.len = cpu_to_le32(len); -- pkt->reply = info->reply; -- pkt->vsk = info->vsk; -+ hdr = virtio_vsock_hdr(skb); -+ hdr->type = cpu_to_le16(info->type); -+ hdr->op = cpu_to_le16(info->op); -+ hdr->src_cid = cpu_to_le64(src_cid); -+ hdr->dst_cid = cpu_to_le64(dst_cid); -+ hdr->src_port = cpu_to_le32(src_port); -+ hdr->dst_port = cpu_to_le32(dst_port); -+ hdr->flags = cpu_to_le32(info->flags); -+ hdr->len = cpu_to_le32(len); -+ hdr->buf_alloc = cpu_to_le32(0); -+ hdr->fwd_cnt = cpu_to_le32(0); - - if (info->msg && len > 0) { -- pkt->buf = kmalloc(len, GFP_KERNEL); -- if (!pkt->buf) -- goto out_pkt; -- -- pkt->buf_len = len; -- -- err = memcpy_from_msg(pkt->buf, info->msg, len); -+ payload = skb_put(skb, len); -+ err = memcpy_from_msg(payload, info->msg, len); - if (err) - goto out; - - if (msg_data_left(info->msg) == 0 && - info->type == VIRTIO_VSOCK_TYPE_SEQPACKET) { -- pkt->hdr.flags |= cpu_to_le32(VIRTIO_VSOCK_SEQ_EOM); -+ hdr->flags |= cpu_to_le32(VIRTIO_VSOCK_SEQ_EOM); - - if (info->msg->msg_flags & MSG_EOR) -- pkt->hdr.flags |= cpu_to_le32(VIRTIO_VSOCK_SEQ_EOR); -+ hdr->flags |= cpu_to_le32(VIRTIO_VSOCK_SEQ_EOR); - } - } - -+ if (info->reply) -+ virtio_vsock_skb_set_reply(skb); -+ - trace_virtio_transport_alloc_pkt(src_cid, src_port, - dst_cid, dst_port, - len, -@@ -91,19 +96,23 @@ virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info, - info->op, - info->flags); - -- return pkt; -+ if (info->vsk && !skb_set_owner_sk_safe(skb, sk_vsock(info->vsk))) { -+ WARN_ONCE(1, "failed to allocate skb on vsock socket with sk_refcnt == 0\n"); -+ goto out; -+ } -+ -+ return skb; - - out: -- kfree(pkt->buf); --out_pkt: -- kfree(pkt); -+ kfree_skb(skb); - return NULL; - } - - /* Packet capture */ - static struct sk_buff *virtio_transport_build_skb(void *opaque) - { -- struct virtio_vsock_pkt *pkt = opaque; -+ struct virtio_vsock_hdr *pkt_hdr; -+ struct sk_buff *pkt = opaque; - struct af_vsockmon_hdr *hdr; - struct sk_buff *skb; - size_t payload_len; -@@ -113,10 +122,11 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque) - * the payload length from the header and the buffer pointer taking - * care of the offset in the original packet. - */ -- payload_len = le32_to_cpu(pkt->hdr.len); -- payload_buf = pkt->buf + pkt->off; -+ pkt_hdr = virtio_vsock_hdr(pkt); -+ payload_len = pkt->len; -+ payload_buf = pkt->data; - -- skb = alloc_skb(sizeof(*hdr) + sizeof(pkt->hdr) + payload_len, -+ skb = alloc_skb(sizeof(*hdr) + sizeof(*pkt_hdr) + payload_len, - GFP_ATOMIC); - if (!skb) - return NULL; -@@ -124,16 +134,16 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque) - hdr = skb_put(skb, sizeof(*hdr)); - - /* pkt->hdr is little-endian so no need to byteswap here */ -- hdr->src_cid = pkt->hdr.src_cid; -- hdr->src_port = pkt->hdr.src_port; -- hdr->dst_cid = pkt->hdr.dst_cid; -- hdr->dst_port = pkt->hdr.dst_port; -+ hdr->src_cid = pkt_hdr->src_cid; -+ hdr->src_port = pkt_hdr->src_port; -+ hdr->dst_cid = pkt_hdr->dst_cid; -+ hdr->dst_port = pkt_hdr->dst_port; - - hdr->transport = cpu_to_le16(AF_VSOCK_TRANSPORT_VIRTIO); -- hdr->len = cpu_to_le16(sizeof(pkt->hdr)); -+ hdr->len = cpu_to_le16(sizeof(*pkt_hdr)); - memset(hdr->reserved, 0, sizeof(hdr->reserved)); - -- switch (le16_to_cpu(pkt->hdr.op)) { -+ switch (le16_to_cpu(pkt_hdr->op)) { - case VIRTIO_VSOCK_OP_REQUEST: - case VIRTIO_VSOCK_OP_RESPONSE: - hdr->op = cpu_to_le16(AF_VSOCK_OP_CONNECT); -@@ -154,7 +164,7 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque) - break; - } - -- skb_put_data(skb, &pkt->hdr, sizeof(pkt->hdr)); -+ skb_put_data(skb, pkt_hdr, sizeof(*pkt_hdr)); - - if (payload_len) { - skb_put_data(skb, payload_buf, payload_len); -@@ -163,13 +173,13 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque) - return skb; - } - --void virtio_transport_deliver_tap_pkt(struct virtio_vsock_pkt *pkt) -+void virtio_transport_deliver_tap_pkt(struct sk_buff *skb) - { -- if (pkt->tap_delivered) -+ if (virtio_vsock_skb_tap_delivered(skb)) - return; - -- vsock_deliver_tap(virtio_transport_build_skb, pkt); -- pkt->tap_delivered = true; -+ vsock_deliver_tap(virtio_transport_build_skb, skb); -+ virtio_vsock_skb_set_tap_delivered(skb); - } - EXPORT_SYMBOL_GPL(virtio_transport_deliver_tap_pkt); - -@@ -192,8 +202,8 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, - u32 src_cid, src_port, dst_cid, dst_port; - const struct virtio_transport *t_ops; - struct virtio_vsock_sock *vvs; -- struct virtio_vsock_pkt *pkt; - u32 pkt_len = info->pkt_len; -+ struct sk_buff *skb; - - info->type = virtio_transport_get_type(sk_vsock(vsk)); - -@@ -224,42 +234,44 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, - if (pkt_len == 0 && info->op == VIRTIO_VSOCK_OP_RW) - return pkt_len; - -- pkt = virtio_transport_alloc_pkt(info, pkt_len, -+ skb = virtio_transport_alloc_skb(info, pkt_len, - src_cid, src_port, - dst_cid, dst_port); -- if (!pkt) { -+ if (!skb) { - virtio_transport_put_credit(vvs, pkt_len); - return -ENOMEM; - } - -- virtio_transport_inc_tx_pkt(vvs, pkt); -+ virtio_transport_inc_tx_pkt(vvs, skb); - -- return t_ops->send_pkt(pkt); -+ return t_ops->send_pkt(skb); - } - - static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs, -- struct virtio_vsock_pkt *pkt) -+ u32 len) - { -- if (vvs->rx_bytes + pkt->len > vvs->buf_alloc) -+ if (vvs->rx_bytes + len > vvs->buf_alloc) - return false; - -- vvs->rx_bytes += pkt->len; -+ vvs->rx_bytes += len; - return true; - } - - static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs, -- struct virtio_vsock_pkt *pkt) -+ u32 len) - { -- vvs->rx_bytes -= pkt->len; -- vvs->fwd_cnt += pkt->len; -+ vvs->rx_bytes -= len; -+ vvs->fwd_cnt += len; - } - --void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt) -+void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); -+ - spin_lock_bh(&vvs->rx_lock); - vvs->last_fwd_cnt = vvs->fwd_cnt; -- pkt->hdr.fwd_cnt = cpu_to_le32(vvs->fwd_cnt); -- pkt->hdr.buf_alloc = cpu_to_le32(vvs->buf_alloc); -+ hdr->fwd_cnt = cpu_to_le32(vvs->fwd_cnt); -+ hdr->buf_alloc = cpu_to_le32(vvs->buf_alloc); - spin_unlock_bh(&vvs->rx_lock); - } - EXPORT_SYMBOL_GPL(virtio_transport_inc_tx_pkt); -@@ -303,29 +315,29 @@ virtio_transport_stream_do_peek(struct vsock_sock *vsk, - size_t len) - { - struct virtio_vsock_sock *vvs = vsk->trans; -- struct virtio_vsock_pkt *pkt; - size_t bytes, total = 0, off; -+ struct sk_buff *skb, *tmp; - int err = -EFAULT; - - spin_lock_bh(&vvs->rx_lock); - -- list_for_each_entry(pkt, &vvs->rx_queue, list) { -- off = pkt->off; -+ skb_queue_walk_safe(&vvs->rx_queue, skb, tmp) { -+ off = 0; - - if (total == len) - break; - -- while (total < len && off < pkt->len) { -+ while (total < len && off < skb->len) { - bytes = len - total; -- if (bytes > pkt->len - off) -- bytes = pkt->len - off; -+ if (bytes > skb->len - off) -+ bytes = skb->len - off; - - /* sk_lock is held by caller so no one else can dequeue. - * Unlock rx_lock since memcpy_to_msg() may sleep. - */ - spin_unlock_bh(&vvs->rx_lock); - -- err = memcpy_to_msg(msg, pkt->buf + off, bytes); -+ err = memcpy_to_msg(msg, skb->data + off, bytes); - if (err) - goto out; - -@@ -352,37 +364,39 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk, - size_t len) - { - struct virtio_vsock_sock *vvs = vsk->trans; -- struct virtio_vsock_pkt *pkt; - size_t bytes, total = 0; -- u32 free_space; -+ struct sk_buff *skb; - int err = -EFAULT; -+ u32 free_space; - - spin_lock_bh(&vvs->rx_lock); -- while (total < len && !list_empty(&vvs->rx_queue)) { -- pkt = list_first_entry(&vvs->rx_queue, -- struct virtio_vsock_pkt, list); -+ while (total < len && !skb_queue_empty(&vvs->rx_queue)) { -+ skb = skb_peek(&vvs->rx_queue); - - bytes = len - total; -- if (bytes > pkt->len - pkt->off) -- bytes = pkt->len - pkt->off; -+ if (bytes > skb->len) -+ bytes = skb->len; - - /* sk_lock is held by caller so no one else can dequeue. - * Unlock rx_lock since memcpy_to_msg() may sleep. - */ - spin_unlock_bh(&vvs->rx_lock); - -- err = memcpy_to_msg(msg, pkt->buf + pkt->off, bytes); -+ err = memcpy_to_msg(msg, skb->data, bytes); - if (err) - goto out; - - spin_lock_bh(&vvs->rx_lock); - - total += bytes; -- pkt->off += bytes; -- if (pkt->off == pkt->len) { -- virtio_transport_dec_rx_pkt(vvs, pkt); -- list_del(&pkt->list); -- virtio_transport_free_pkt(pkt); -+ skb_pull(skb, bytes); -+ -+ if (skb->len == 0) { -+ u32 pkt_len = le32_to_cpu(virtio_vsock_hdr(skb)->len); -+ -+ virtio_transport_dec_rx_pkt(vvs, pkt_len); -+ __skb_unlink(skb, &vvs->rx_queue); -+ consume_skb(skb); - } - } - -@@ -414,10 +428,10 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk, - int flags) - { - struct virtio_vsock_sock *vvs = vsk->trans; -- struct virtio_vsock_pkt *pkt; - int dequeued_len = 0; - size_t user_buf_len = msg_data_left(msg); - bool msg_ready = false; -+ struct sk_buff *skb; - - spin_lock_bh(&vvs->rx_lock); - -@@ -427,13 +441,18 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk, - } - - while (!msg_ready) { -- pkt = list_first_entry(&vvs->rx_queue, struct virtio_vsock_pkt, list); -+ struct virtio_vsock_hdr *hdr; -+ size_t pkt_len; -+ -+ skb = __skb_dequeue(&vvs->rx_queue); -+ if (!skb) -+ break; -+ hdr = virtio_vsock_hdr(skb); -+ pkt_len = (size_t)le32_to_cpu(hdr->len); - - if (dequeued_len >= 0) { -- size_t pkt_len; - size_t bytes_to_copy; - -- pkt_len = (size_t)le32_to_cpu(pkt->hdr.len); - bytes_to_copy = min(user_buf_len, pkt_len); - - if (bytes_to_copy) { -@@ -444,7 +463,7 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk, - */ - spin_unlock_bh(&vvs->rx_lock); - -- err = memcpy_to_msg(msg, pkt->buf, bytes_to_copy); -+ err = memcpy_to_msg(msg, skb->data, bytes_to_copy); - if (err) { - /* Copy of message failed. Rest of - * fragments will be freed without copy. -@@ -461,17 +480,16 @@ static int virtio_transport_seqpacket_do_dequeue(struct vsock_sock *vsk, - dequeued_len += pkt_len; - } - -- if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SEQ_EOM) { -+ if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM) { - msg_ready = true; - vvs->msg_count--; - -- if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SEQ_EOR) -+ if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOR) - msg->msg_flags |= MSG_EOR; - } - -- virtio_transport_dec_rx_pkt(vvs, pkt); -- list_del(&pkt->list); -- virtio_transport_free_pkt(pkt); -+ virtio_transport_dec_rx_pkt(vvs, pkt_len); -+ kfree_skb(skb); - } - - spin_unlock_bh(&vvs->rx_lock); -@@ -609,7 +627,7 @@ int virtio_transport_do_socket_init(struct vsock_sock *vsk, - - spin_lock_init(&vvs->rx_lock); - spin_lock_init(&vvs->tx_lock); -- INIT_LIST_HEAD(&vvs->rx_queue); -+ skb_queue_head_init(&vvs->rx_queue); - - return 0; - } -@@ -806,16 +824,16 @@ void virtio_transport_destruct(struct vsock_sock *vsk) - EXPORT_SYMBOL_GPL(virtio_transport_destruct); - - static int virtio_transport_reset(struct vsock_sock *vsk, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { - struct virtio_vsock_pkt_info info = { - .op = VIRTIO_VSOCK_OP_RST, -- .reply = !!pkt, -+ .reply = !!skb, - .vsk = vsk, - }; - - /* Send RST only if the original pkt is not a RST pkt */ -- if (pkt && le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) -+ if (skb && le16_to_cpu(virtio_vsock_hdr(skb)->op) == VIRTIO_VSOCK_OP_RST) - return 0; - - return virtio_transport_send_pkt_info(vsk, &info); -@@ -825,29 +843,30 @@ static int virtio_transport_reset(struct vsock_sock *vsk, - * attempt was made to connect to a socket that does not exist. - */ - static int virtio_transport_reset_no_sock(const struct virtio_transport *t, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { -- struct virtio_vsock_pkt *reply; -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct virtio_vsock_pkt_info info = { - .op = VIRTIO_VSOCK_OP_RST, -- .type = le16_to_cpu(pkt->hdr.type), -+ .type = le16_to_cpu(hdr->type), - .reply = true, - }; -+ struct sk_buff *reply; - - /* Send RST only if the original pkt is not a RST pkt */ -- if (le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) -+ if (le16_to_cpu(hdr->op) == VIRTIO_VSOCK_OP_RST) - return 0; - -- reply = virtio_transport_alloc_pkt(&info, 0, -- le64_to_cpu(pkt->hdr.dst_cid), -- le32_to_cpu(pkt->hdr.dst_port), -- le64_to_cpu(pkt->hdr.src_cid), -- le32_to_cpu(pkt->hdr.src_port)); -+ reply = virtio_transport_alloc_skb(&info, 0, -+ le64_to_cpu(hdr->dst_cid), -+ le32_to_cpu(hdr->dst_port), -+ le64_to_cpu(hdr->src_cid), -+ le32_to_cpu(hdr->src_port)); - if (!reply) - return -ENOMEM; - - if (!t) { -- virtio_transport_free_pkt(reply); -+ kfree_skb(reply); - return -ENOTCONN; - } - -@@ -858,16 +877,11 @@ static int virtio_transport_reset_no_sock(const struct virtio_transport *t, - static void virtio_transport_remove_sock(struct vsock_sock *vsk) - { - struct virtio_vsock_sock *vvs = vsk->trans; -- struct virtio_vsock_pkt *pkt, *tmp; - - /* We don't need to take rx_lock, as the socket is closing and we are - * removing it. - */ -- list_for_each_entry_safe(pkt, tmp, &vvs->rx_queue, list) { -- list_del(&pkt->list); -- virtio_transport_free_pkt(pkt); -- } -- -+ __skb_queue_purge(&vvs->rx_queue); - vsock_remove_sock(vsk); - } - -@@ -981,13 +995,14 @@ EXPORT_SYMBOL_GPL(virtio_transport_release); - - static int - virtio_transport_recv_connecting(struct sock *sk, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct vsock_sock *vsk = vsock_sk(sk); -- int err; - int skerr; -+ int err; - -- switch (le16_to_cpu(pkt->hdr.op)) { -+ switch (le16_to_cpu(hdr->op)) { - case VIRTIO_VSOCK_OP_RESPONSE: - sk->sk_state = TCP_ESTABLISHED; - sk->sk_socket->state = SS_CONNECTED; -@@ -1008,7 +1023,7 @@ virtio_transport_recv_connecting(struct sock *sk, - return 0; - - destroy: -- virtio_transport_reset(vsk, pkt); -+ virtio_transport_reset(vsk, skb); - sk->sk_state = TCP_CLOSE; - sk->sk_err = skerr; - sk_error_report(sk); -@@ -1017,34 +1032,37 @@ destroy: - - static void - virtio_transport_recv_enqueue(struct vsock_sock *vsk, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { - struct virtio_vsock_sock *vvs = vsk->trans; - bool can_enqueue, free_pkt = false; -+ struct virtio_vsock_hdr *hdr; -+ u32 len; - -- pkt->len = le32_to_cpu(pkt->hdr.len); -- pkt->off = 0; -+ hdr = virtio_vsock_hdr(skb); -+ len = le32_to_cpu(hdr->len); - - spin_lock_bh(&vvs->rx_lock); - -- can_enqueue = virtio_transport_inc_rx_pkt(vvs, pkt); -+ can_enqueue = virtio_transport_inc_rx_pkt(vvs, len); - if (!can_enqueue) { - free_pkt = true; - goto out; - } - -- if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SEQ_EOM) -+ if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM) - vvs->msg_count++; - - /* Try to copy small packets into the buffer of last packet queued, - * to avoid wasting memory queueing the entire buffer with a small - * payload. - */ -- if (pkt->len <= GOOD_COPY_LEN && !list_empty(&vvs->rx_queue)) { -- struct virtio_vsock_pkt *last_pkt; -+ if (len <= GOOD_COPY_LEN && !skb_queue_empty(&vvs->rx_queue)) { -+ struct virtio_vsock_hdr *last_hdr; -+ struct sk_buff *last_skb; - -- last_pkt = list_last_entry(&vvs->rx_queue, -- struct virtio_vsock_pkt, list); -+ last_skb = skb_peek_tail(&vvs->rx_queue); -+ last_hdr = virtio_vsock_hdr(last_skb); - - /* If there is space in the last packet queued, we copy the - * new packet in its buffer. We avoid this if the last packet -@@ -1052,35 +1070,35 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk, - * delimiter of SEQPACKET message, so 'pkt' is the first packet - * of a new message. - */ -- if ((pkt->len <= last_pkt->buf_len - last_pkt->len) && -- !(le32_to_cpu(last_pkt->hdr.flags) & VIRTIO_VSOCK_SEQ_EOM)) { -- memcpy(last_pkt->buf + last_pkt->len, pkt->buf, -- pkt->len); -- last_pkt->len += pkt->len; -+ if (skb->len < skb_tailroom(last_skb) && -+ !(le32_to_cpu(last_hdr->flags) & VIRTIO_VSOCK_SEQ_EOM)) { -+ memcpy(skb_put(last_skb, skb->len), skb->data, skb->len); - free_pkt = true; -- last_pkt->hdr.flags |= pkt->hdr.flags; -+ last_hdr->flags |= hdr->flags; -+ le32_add_cpu(&last_hdr->len, len); - goto out; - } - } - -- list_add_tail(&pkt->list, &vvs->rx_queue); -+ __skb_queue_tail(&vvs->rx_queue, skb); - - out: - spin_unlock_bh(&vvs->rx_lock); - if (free_pkt) -- virtio_transport_free_pkt(pkt); -+ kfree_skb(skb); - } - - static int - virtio_transport_recv_connected(struct sock *sk, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct vsock_sock *vsk = vsock_sk(sk); - int err = 0; - -- switch (le16_to_cpu(pkt->hdr.op)) { -+ switch (le16_to_cpu(hdr->op)) { - case VIRTIO_VSOCK_OP_RW: -- virtio_transport_recv_enqueue(vsk, pkt); -+ virtio_transport_recv_enqueue(vsk, skb); - vsock_data_ready(sk); - return err; - case VIRTIO_VSOCK_OP_CREDIT_REQUEST: -@@ -1090,18 +1108,23 @@ virtio_transport_recv_connected(struct sock *sk, - sk->sk_write_space(sk); - break; - case VIRTIO_VSOCK_OP_SHUTDOWN: -- if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SHUTDOWN_RCV) -+ if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_RCV) - vsk->peer_shutdown |= RCV_SHUTDOWN; -- if (le32_to_cpu(pkt->hdr.flags) & VIRTIO_VSOCK_SHUTDOWN_SEND) -+ if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_SEND) - vsk->peer_shutdown |= SEND_SHUTDOWN; -- if (vsk->peer_shutdown == SHUTDOWN_MASK && -- vsock_stream_has_data(vsk) <= 0 && -- !sock_flag(sk, SOCK_DONE)) { -- (void)virtio_transport_reset(vsk, NULL); -- -- virtio_transport_do_close(vsk, true); -+ if (vsk->peer_shutdown == SHUTDOWN_MASK) { -+ if (vsock_stream_has_data(vsk) <= 0 && !sock_flag(sk, SOCK_DONE)) { -+ (void)virtio_transport_reset(vsk, NULL); -+ virtio_transport_do_close(vsk, true); -+ } -+ /* Remove this socket anyway because the remote peer sent -+ * the shutdown. This way a new connection will succeed -+ * if the remote peer uses the same source port, -+ * even if the old socket is still unreleased, but now disconnected. -+ */ -+ vsock_remove_sock(vsk); - } -- if (le32_to_cpu(pkt->hdr.flags)) -+ if (le32_to_cpu(virtio_vsock_hdr(skb)->flags)) - sk->sk_state_change(sk); - break; - case VIRTIO_VSOCK_OP_RST: -@@ -1112,28 +1135,30 @@ virtio_transport_recv_connected(struct sock *sk, - break; - } - -- virtio_transport_free_pkt(pkt); -+ kfree_skb(skb); - return err; - } - - static void - virtio_transport_recv_disconnecting(struct sock *sk, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct vsock_sock *vsk = vsock_sk(sk); - -- if (le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) -+ if (le16_to_cpu(hdr->op) == VIRTIO_VSOCK_OP_RST) - virtio_transport_do_close(vsk, true); - } - - static int - virtio_transport_send_response(struct vsock_sock *vsk, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct virtio_vsock_pkt_info info = { - .op = VIRTIO_VSOCK_OP_RESPONSE, -- .remote_cid = le64_to_cpu(pkt->hdr.src_cid), -- .remote_port = le32_to_cpu(pkt->hdr.src_port), -+ .remote_cid = le64_to_cpu(hdr->src_cid), -+ .remote_port = le32_to_cpu(hdr->src_port), - .reply = true, - .vsk = vsk, - }; -@@ -1142,8 +1167,9 @@ virtio_transport_send_response(struct vsock_sock *vsk, - } - - static bool virtio_transport_space_update(struct sock *sk, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct vsock_sock *vsk = vsock_sk(sk); - struct virtio_vsock_sock *vvs = vsk->trans; - bool space_available; -@@ -1158,8 +1184,8 @@ static bool virtio_transport_space_update(struct sock *sk, - - /* buf_alloc and fwd_cnt is always included in the hdr */ - spin_lock_bh(&vvs->tx_lock); -- vvs->peer_buf_alloc = le32_to_cpu(pkt->hdr.buf_alloc); -- vvs->peer_fwd_cnt = le32_to_cpu(pkt->hdr.fwd_cnt); -+ vvs->peer_buf_alloc = le32_to_cpu(hdr->buf_alloc); -+ vvs->peer_fwd_cnt = le32_to_cpu(hdr->fwd_cnt); - space_available = virtio_transport_has_space(vsk); - spin_unlock_bh(&vvs->tx_lock); - return space_available; -@@ -1167,27 +1193,28 @@ static bool virtio_transport_space_update(struct sock *sk, - - /* Handle server socket */ - static int --virtio_transport_recv_listen(struct sock *sk, struct virtio_vsock_pkt *pkt, -+virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb, - struct virtio_transport *t) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct vsock_sock *vsk = vsock_sk(sk); - struct vsock_sock *vchild; - struct sock *child; - int ret; - -- if (le16_to_cpu(pkt->hdr.op) != VIRTIO_VSOCK_OP_REQUEST) { -- virtio_transport_reset_no_sock(t, pkt); -+ if (le16_to_cpu(hdr->op) != VIRTIO_VSOCK_OP_REQUEST) { -+ virtio_transport_reset_no_sock(t, skb); - return -EINVAL; - } - - if (sk_acceptq_is_full(sk)) { -- virtio_transport_reset_no_sock(t, pkt); -+ virtio_transport_reset_no_sock(t, skb); - return -ENOMEM; - } - - child = vsock_create_connected(sk); - if (!child) { -- virtio_transport_reset_no_sock(t, pkt); -+ virtio_transport_reset_no_sock(t, skb); - return -ENOMEM; - } - -@@ -1198,10 +1225,10 @@ virtio_transport_recv_listen(struct sock *sk, struct virtio_vsock_pkt *pkt, - child->sk_state = TCP_ESTABLISHED; - - vchild = vsock_sk(child); -- vsock_addr_init(&vchild->local_addr, le64_to_cpu(pkt->hdr.dst_cid), -- le32_to_cpu(pkt->hdr.dst_port)); -- vsock_addr_init(&vchild->remote_addr, le64_to_cpu(pkt->hdr.src_cid), -- le32_to_cpu(pkt->hdr.src_port)); -+ vsock_addr_init(&vchild->local_addr, le64_to_cpu(hdr->dst_cid), -+ le32_to_cpu(hdr->dst_port)); -+ vsock_addr_init(&vchild->remote_addr, le64_to_cpu(hdr->src_cid), -+ le32_to_cpu(hdr->src_port)); - - ret = vsock_assign_transport(vchild, vsk); - /* Transport assigned (looking at remote_addr) must be the same -@@ -1209,17 +1236,17 @@ virtio_transport_recv_listen(struct sock *sk, struct virtio_vsock_pkt *pkt, - */ - if (ret || vchild->transport != &t->transport) { - release_sock(child); -- virtio_transport_reset_no_sock(t, pkt); -+ virtio_transport_reset_no_sock(t, skb); - sock_put(child); - return ret; - } - -- if (virtio_transport_space_update(child, pkt)) -+ if (virtio_transport_space_update(child, skb)) - child->sk_write_space(child); - - vsock_insert_connected(vchild); - vsock_enqueue_accept(sk, child); -- virtio_transport_send_response(vchild, pkt); -+ virtio_transport_send_response(vchild, skb); - - release_sock(child); - -@@ -1237,29 +1264,30 @@ static bool virtio_transport_valid_type(u16 type) - * lock. - */ - void virtio_transport_recv_pkt(struct virtio_transport *t, -- struct virtio_vsock_pkt *pkt) -+ struct sk_buff *skb) - { -+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); - struct sockaddr_vm src, dst; - struct vsock_sock *vsk; - struct sock *sk; - bool space_available; - -- vsock_addr_init(&src, le64_to_cpu(pkt->hdr.src_cid), -- le32_to_cpu(pkt->hdr.src_port)); -- vsock_addr_init(&dst, le64_to_cpu(pkt->hdr.dst_cid), -- le32_to_cpu(pkt->hdr.dst_port)); -+ vsock_addr_init(&src, le64_to_cpu(hdr->src_cid), -+ le32_to_cpu(hdr->src_port)); -+ vsock_addr_init(&dst, le64_to_cpu(hdr->dst_cid), -+ le32_to_cpu(hdr->dst_port)); - - trace_virtio_transport_recv_pkt(src.svm_cid, src.svm_port, - dst.svm_cid, dst.svm_port, -- le32_to_cpu(pkt->hdr.len), -- le16_to_cpu(pkt->hdr.type), -- le16_to_cpu(pkt->hdr.op), -- le32_to_cpu(pkt->hdr.flags), -- le32_to_cpu(pkt->hdr.buf_alloc), -- le32_to_cpu(pkt->hdr.fwd_cnt)); -- -- if (!virtio_transport_valid_type(le16_to_cpu(pkt->hdr.type))) { -- (void)virtio_transport_reset_no_sock(t, pkt); -+ le32_to_cpu(hdr->len), -+ le16_to_cpu(hdr->type), -+ le16_to_cpu(hdr->op), -+ le32_to_cpu(hdr->flags), -+ le32_to_cpu(hdr->buf_alloc), -+ le32_to_cpu(hdr->fwd_cnt)); -+ -+ if (!virtio_transport_valid_type(le16_to_cpu(hdr->type))) { -+ (void)virtio_transport_reset_no_sock(t, skb); - goto free_pkt; - } - -@@ -1270,30 +1298,35 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, - if (!sk) { - sk = vsock_find_bound_socket(&dst); - if (!sk) { -- (void)virtio_transport_reset_no_sock(t, pkt); -+ (void)virtio_transport_reset_no_sock(t, skb); - goto free_pkt; - } - } - -- if (virtio_transport_get_type(sk) != le16_to_cpu(pkt->hdr.type)) { -- (void)virtio_transport_reset_no_sock(t, pkt); -+ if (virtio_transport_get_type(sk) != le16_to_cpu(hdr->type)) { -+ (void)virtio_transport_reset_no_sock(t, skb); - sock_put(sk); - goto free_pkt; - } - -+ if (!skb_set_owner_sk_safe(skb, sk)) { -+ WARN_ONCE(1, "receiving vsock socket has sk_refcnt == 0\n"); -+ goto free_pkt; -+ } -+ - vsk = vsock_sk(sk); - - lock_sock(sk); - - /* Check if sk has been closed before lock_sock */ - if (sock_flag(sk, SOCK_DONE)) { -- (void)virtio_transport_reset_no_sock(t, pkt); -+ (void)virtio_transport_reset_no_sock(t, skb); - release_sock(sk); - sock_put(sk); - goto free_pkt; - } - -- space_available = virtio_transport_space_update(sk, pkt); -+ space_available = virtio_transport_space_update(sk, skb); - - /* Update CID in case it has changed after a transport reset event */ - if (vsk->local_addr.svm_cid != VMADDR_CID_ANY) -@@ -1304,23 +1337,23 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, - - switch (sk->sk_state) { - case TCP_LISTEN: -- virtio_transport_recv_listen(sk, pkt, t); -- virtio_transport_free_pkt(pkt); -+ virtio_transport_recv_listen(sk, skb, t); -+ kfree_skb(skb); - break; - case TCP_SYN_SENT: -- virtio_transport_recv_connecting(sk, pkt); -- virtio_transport_free_pkt(pkt); -+ virtio_transport_recv_connecting(sk, skb); -+ kfree_skb(skb); - break; - case TCP_ESTABLISHED: -- virtio_transport_recv_connected(sk, pkt); -+ virtio_transport_recv_connected(sk, skb); - break; - case TCP_CLOSING: -- virtio_transport_recv_disconnecting(sk, pkt); -- virtio_transport_free_pkt(pkt); -+ virtio_transport_recv_disconnecting(sk, skb); -+ kfree_skb(skb); - break; - default: -- (void)virtio_transport_reset_no_sock(t, pkt); -- virtio_transport_free_pkt(pkt); -+ (void)virtio_transport_reset_no_sock(t, skb); -+ kfree_skb(skb); - break; - } - -@@ -1333,16 +1366,42 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, - return; - - free_pkt: -- virtio_transport_free_pkt(pkt); -+ kfree_skb(skb); - } - EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt); - --void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt) -+/* Remove skbs found in a queue that have a vsk that matches. -+ * -+ * Each skb is freed. -+ * -+ * Returns the count of skbs that were reply packets. -+ */ -+int virtio_transport_purge_skbs(void *vsk, struct sk_buff_head *queue) - { -- kvfree(pkt->buf); -- kfree(pkt); -+ struct sk_buff_head freeme; -+ struct sk_buff *skb, *tmp; -+ int cnt = 0; -+ -+ skb_queue_head_init(&freeme); -+ -+ spin_lock_bh(&queue->lock); -+ skb_queue_walk_safe(queue, skb, tmp) { -+ if (vsock_sk(skb->sk) != vsk) -+ continue; -+ -+ __skb_unlink(skb, queue); -+ __skb_queue_tail(&freeme, skb); -+ -+ if (virtio_vsock_skb_reply(skb)) -+ cnt++; -+ } -+ spin_unlock_bh(&queue->lock); -+ -+ __skb_queue_purge(&freeme); -+ -+ return cnt; - } --EXPORT_SYMBOL_GPL(virtio_transport_free_pkt); -+EXPORT_SYMBOL_GPL(virtio_transport_purge_skbs); - - MODULE_LICENSE("GPL v2"); - MODULE_AUTHOR("Asias He"); -diff --git a/net/vmw_vsock/vsock_loopback.c b/net/vmw_vsock/vsock_loopback.c -index 169a8cf65b390..89905c092645a 100644 ---- a/net/vmw_vsock/vsock_loopback.c -+++ b/net/vmw_vsock/vsock_loopback.c -@@ -15,8 +15,7 @@ - struct vsock_loopback { - struct workqueue_struct *workqueue; - -- spinlock_t pkt_list_lock; /* protects pkt_list */ -- struct list_head pkt_list; -+ struct sk_buff_head pkt_queue; - struct work_struct pkt_work; - }; - -@@ -27,14 +26,12 @@ static u32 vsock_loopback_get_local_cid(void) - return VMADDR_CID_LOCAL; - } - --static int vsock_loopback_send_pkt(struct virtio_vsock_pkt *pkt) -+static int vsock_loopback_send_pkt(struct sk_buff *skb) - { - struct vsock_loopback *vsock = &the_vsock_loopback; -- int len = pkt->len; -+ int len = skb->len; - -- spin_lock_bh(&vsock->pkt_list_lock); -- list_add_tail(&pkt->list, &vsock->pkt_list); -- spin_unlock_bh(&vsock->pkt_list_lock); -+ skb_queue_tail(&vsock->pkt_queue, skb); - - queue_work(vsock->workqueue, &vsock->pkt_work); - -@@ -44,21 +41,8 @@ static int vsock_loopback_send_pkt(struct virtio_vsock_pkt *pkt) - static int vsock_loopback_cancel_pkt(struct vsock_sock *vsk) - { - struct vsock_loopback *vsock = &the_vsock_loopback; -- struct virtio_vsock_pkt *pkt, *n; -- LIST_HEAD(freeme); -- -- spin_lock_bh(&vsock->pkt_list_lock); -- list_for_each_entry_safe(pkt, n, &vsock->pkt_list, list) { -- if (pkt->vsk != vsk) -- continue; -- list_move(&pkt->list, &freeme); -- } -- spin_unlock_bh(&vsock->pkt_list_lock); - -- list_for_each_entry_safe(pkt, n, &freeme, list) { -- list_del(&pkt->list); -- virtio_transport_free_pkt(pkt); -- } -+ virtio_transport_purge_skbs(vsk, &vsock->pkt_queue); - - return 0; - } -@@ -121,20 +105,18 @@ static void vsock_loopback_work(struct work_struct *work) - { - struct vsock_loopback *vsock = - container_of(work, struct vsock_loopback, pkt_work); -- LIST_HEAD(pkts); -+ struct sk_buff_head pkts; -+ struct sk_buff *skb; - -- spin_lock_bh(&vsock->pkt_list_lock); -- list_splice_init(&vsock->pkt_list, &pkts); -- spin_unlock_bh(&vsock->pkt_list_lock); -+ skb_queue_head_init(&pkts); - -- while (!list_empty(&pkts)) { -- struct virtio_vsock_pkt *pkt; -+ spin_lock_bh(&vsock->pkt_queue.lock); -+ skb_queue_splice_init(&vsock->pkt_queue, &pkts); -+ spin_unlock_bh(&vsock->pkt_queue.lock); - -- pkt = list_first_entry(&pkts, struct virtio_vsock_pkt, list); -- list_del_init(&pkt->list); -- -- virtio_transport_deliver_tap_pkt(pkt); -- virtio_transport_recv_pkt(&loopback_transport, pkt); -+ while ((skb = __skb_dequeue(&pkts))) { -+ virtio_transport_deliver_tap_pkt(skb); -+ virtio_transport_recv_pkt(&loopback_transport, skb); - } - } - -@@ -147,8 +129,7 @@ static int __init vsock_loopback_init(void) - if (!vsock->workqueue) - return -ENOMEM; - -- spin_lock_init(&vsock->pkt_list_lock); -- INIT_LIST_HEAD(&vsock->pkt_list); -+ skb_queue_head_init(&vsock->pkt_queue); - INIT_WORK(&vsock->pkt_work, vsock_loopback_work); - - ret = vsock_core_register(&loopback_transport.transport, -@@ -166,20 +147,12 @@ out_wq: - static void __exit vsock_loopback_exit(void) - { - struct vsock_loopback *vsock = &the_vsock_loopback; -- struct virtio_vsock_pkt *pkt; - - vsock_core_unregister(&loopback_transport.transport); - - flush_work(&vsock->pkt_work); - -- spin_lock_bh(&vsock->pkt_list_lock); -- while (!list_empty(&vsock->pkt_list)) { -- pkt = list_first_entry(&vsock->pkt_list, -- struct virtio_vsock_pkt, list); -- list_del(&pkt->list); -- virtio_transport_free_pkt(pkt); -- } -- spin_unlock_bh(&vsock->pkt_list_lock); -+ virtio_vsock_skb_queue_purge(&vsock->pkt_queue); - - destroy_workqueue(vsock->workqueue); - } -diff --git a/net/wireless/core.c b/net/wireless/core.c -index bf2f1f583fb12..63d75fecc2c53 100644 ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -1042,7 +1042,8 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy) - } - EXPORT_SYMBOL(wiphy_rfkill_start_polling); - --void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev) -+void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev, -+ struct wiphy_work *end) - { - unsigned int runaway_limit = 100; - unsigned long flags; -@@ -1061,6 +1062,10 @@ void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev) - wk->func(&rdev->wiphy, wk); - - spin_lock_irqsave(&rdev->wiphy_work_lock, flags); -+ -+ if (wk == end) -+ break; -+ - if (WARN_ON(--runaway_limit == 0)) - INIT_LIST_HEAD(&rdev->wiphy_work_list); - } -@@ -1111,7 +1116,7 @@ void wiphy_unregister(struct wiphy *wiphy) - #endif - - /* surely nothing is reachable now, clean up work */ -- cfg80211_process_wiphy_works(rdev); -+ cfg80211_process_wiphy_works(rdev, NULL); - wiphy_unlock(&rdev->wiphy); - rtnl_unlock(); - -@@ -1636,6 +1641,21 @@ void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work) - } - EXPORT_SYMBOL_GPL(wiphy_work_cancel); - -+void wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *work) -+{ -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ unsigned long flags; -+ bool run; -+ -+ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); -+ run = !work || !list_empty(&work->entry); -+ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); -+ -+ if (run) -+ cfg80211_process_wiphy_works(rdev, work); -+} -+EXPORT_SYMBOL_GPL(wiphy_work_flush); -+ - void wiphy_delayed_work_timer(struct timer_list *t) - { - struct wiphy_delayed_work *dwork = from_timer(dwork, t, timer); -@@ -1668,6 +1688,16 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy, - } - EXPORT_SYMBOL_GPL(wiphy_delayed_work_cancel); - -+void wiphy_delayed_work_flush(struct wiphy *wiphy, -+ struct wiphy_delayed_work *dwork) -+{ -+ lockdep_assert_held(&wiphy->mtx); -+ -+ del_timer_sync(&dwork->timer); -+ wiphy_work_flush(wiphy, &dwork->work); -+} -+EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush); -+ - static int __init cfg80211_init(void) - { - int err; -diff --git a/net/wireless/core.h b/net/wireless/core.h -index 86fd79912254d..e1accacc6f233 100644 ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -461,7 +461,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, - struct net_device *dev, enum nl80211_iftype ntype, - struct vif_params *params); - void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); --void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev); -+void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev, -+ struct wiphy_work *end); - void cfg80211_process_wdev_events(struct wireless_dev *wdev); - - bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, -diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c -index 4d3b658030105..a88f338c61d31 100644 ---- a/net/wireless/sysfs.c -+++ b/net/wireless/sysfs.c -@@ -105,14 +105,14 @@ static int wiphy_suspend(struct device *dev) - cfg80211_leave_all(rdev); - cfg80211_process_rdev_events(rdev); - } -- cfg80211_process_wiphy_works(rdev); -+ cfg80211_process_wiphy_works(rdev, NULL); - if (rdev->ops->suspend) - ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); - if (ret == 1) { - /* Driver refuse to configure wowlan */ - cfg80211_leave_all(rdev); - cfg80211_process_rdev_events(rdev); -- cfg80211_process_wiphy_works(rdev); -+ cfg80211_process_wiphy_works(rdev, NULL); - ret = rdev_suspend(rdev, NULL); - } - if (ret == 0) -diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c -index 111d5464c12df..39e2c8883ddd4 100644 ---- a/scripts/mod/file2alias.c -+++ b/scripts/mod/file2alias.c -@@ -1348,13 +1348,13 @@ static int do_typec_entry(const char *filename, void *symval, char *alias) - /* Looks like: tee:uuid */ - static int do_tee_entry(const char *filename, void *symval, char *alias) - { -- DEF_FIELD(symval, tee_client_device_id, uuid); -+ DEF_FIELD_ADDR(symval, tee_client_device_id, uuid); - - sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", -- uuid.b[0], uuid.b[1], uuid.b[2], uuid.b[3], uuid.b[4], -- uuid.b[5], uuid.b[6], uuid.b[7], uuid.b[8], uuid.b[9], -- uuid.b[10], uuid.b[11], uuid.b[12], uuid.b[13], uuid.b[14], -- uuid.b[15]); -+ uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], -+ uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], -+ uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], -+ uuid->b[15]); - - add_wildcard(alias); - return 1; -@@ -1401,10 +1401,10 @@ static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) - /* Looks like: ishtp:{guid} */ - static int do_ishtp_entry(const char *filename, void *symval, char *alias) - { -- DEF_FIELD(symval, ishtp_device_id, guid); -+ DEF_FIELD_ADDR(symval, ishtp_device_id, guid); - - strcpy(alias, ISHTP_MODULE_PREFIX "{"); -- add_guid(alias, guid); -+ add_guid(alias, *guid); - strcat(alias, "}"); - - return 1; -diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig -index cb3496e00d8a6..f334e7cccf2da 100644 ---- a/security/apparmor/Kconfig -+++ b/security/apparmor/Kconfig -@@ -106,8 +106,8 @@ config SECURITY_APPARMOR_PARANOID_LOAD - Disabling the check will speed up policy loads. - - config SECURITY_APPARMOR_KUNIT_TEST -- bool "Build KUnit tests for policy_unpack.c" if !KUNIT_ALL_TESTS -- depends on KUNIT=y && SECURITY_APPARMOR -+ tristate "Build KUnit tests for policy_unpack.c" if !KUNIT_ALL_TESTS -+ depends on KUNIT && SECURITY_APPARMOR - default KUNIT_ALL_TESTS - help - This builds the AppArmor KUnit tests. -diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile -index ff23fcfefe196..065f4e346553d 100644 ---- a/security/apparmor/Makefile -+++ b/security/apparmor/Makefile -@@ -8,6 +8,9 @@ apparmor-y := apparmorfs.o audit.o capability.o task.o ipc.o lib.o match.o \ - resource.o secid.o file.o policy_ns.o label.o mount.o net.o - apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o - -+obj-$(CONFIG_SECURITY_APPARMOR_KUNIT_TEST) += apparmor_policy_unpack_test.o -+apparmor_policy_unpack_test-objs += policy_unpack_test.o -+ - clean-files := capability_names.h rlim_names.h net_names.h - - # Build a lower case string table of address family names -diff --git a/security/apparmor/include/policy_unpack.h b/security/apparmor/include/policy_unpack.h -index eb5f7d7f132bb..e89b701447bcb 100644 ---- a/security/apparmor/include/policy_unpack.h -+++ b/security/apparmor/include/policy_unpack.h -@@ -48,6 +48,43 @@ enum { - AAFS_LOADDATA_NDENTS /* count of entries */ - }; - -+/* -+ * The AppArmor interface treats data as a type byte followed by the -+ * actual data. The interface has the notion of a named entry -+ * which has a name (AA_NAME typecode followed by name string) followed by -+ * the entries typecode and data. Named types allow for optional -+ * elements and extensions to be added and tested for without breaking -+ * backwards compatibility. -+ */ -+ -+enum aa_code { -+ AA_U8, -+ AA_U16, -+ AA_U32, -+ AA_U64, -+ AA_NAME, /* same as string except it is items name */ -+ AA_STRING, -+ AA_BLOB, -+ AA_STRUCT, -+ AA_STRUCTEND, -+ AA_LIST, -+ AA_LISTEND, -+ AA_ARRAY, -+ AA_ARRAYEND, -+}; -+ -+/* -+ * aa_ext is the read of the buffer containing the serialized profile. The -+ * data is copied into a kernel buffer in apparmorfs and then handed off to -+ * the unpack routines. -+ */ -+struct aa_ext { -+ void *start; -+ void *end; -+ void *pos; /* pointer to current position in the buffer */ -+ u32 version; -+}; -+ - /* - * struct aa_loaddata - buffer of policy raw_data set - * -@@ -126,4 +163,17 @@ static inline void aa_put_loaddata(struct aa_loaddata *data) - kref_put(&data->count, aa_loaddata_kref); - } - -+#if IS_ENABLED(CONFIG_KUNIT) -+bool aa_inbounds(struct aa_ext *e, size_t size); -+size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk); -+bool aa_unpack_X(struct aa_ext *e, enum aa_code code); -+bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name); -+bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name); -+bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name); -+size_t aa_unpack_array(struct aa_ext *e, const char *name); -+size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name); -+int aa_unpack_str(struct aa_ext *e, const char **string, const char *name); -+int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name); -+#endif -+ - #endif /* __POLICY_INTERFACE_H */ -diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c -index fbdfcef91c616..c7b84fb568414 100644 ---- a/security/apparmor/policy.c -+++ b/security/apparmor/policy.c -@@ -218,6 +218,7 @@ void aa_free_profile(struct aa_profile *profile) - - aa_put_ns(profile->ns); - kfree_sensitive(profile->rename); -+ kfree_sensitive(profile->disconnected); - - aa_free_file_rules(&profile->file); - aa_free_cap_rules(&profile->caps); -diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c -index 9c3fec2c7cf6b..7012fd82f1bb1 100644 ---- a/security/apparmor/policy_unpack.c -+++ b/security/apparmor/policy_unpack.c -@@ -14,6 +14,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -37,43 +38,6 @@ - #define v7 7 - #define v8 8 /* full network masking */ - --/* -- * The AppArmor interface treats data as a type byte followed by the -- * actual data. The interface has the notion of a named entry -- * which has a name (AA_NAME typecode followed by name string) followed by -- * the entries typecode and data. Named types allow for optional -- * elements and extensions to be added and tested for without breaking -- * backwards compatibility. -- */ -- --enum aa_code { -- AA_U8, -- AA_U16, -- AA_U32, -- AA_U64, -- AA_NAME, /* same as string except it is items name */ -- AA_STRING, -- AA_BLOB, -- AA_STRUCT, -- AA_STRUCTEND, -- AA_LIST, -- AA_LISTEND, -- AA_ARRAY, -- AA_ARRAYEND, --}; -- --/* -- * aa_ext is the read of the buffer containing the serialized profile. The -- * data is copied into a kernel buffer in apparmorfs and then handed off to -- * the unpack routines. -- */ --struct aa_ext { -- void *start; -- void *end; -- void *pos; /* pointer to current position in the buffer */ -- u32 version; --}; -- - /* audit callback for unpack fields */ - static void audit_cb(struct audit_buffer *ab, void *va) - { -@@ -199,10 +163,11 @@ struct aa_loaddata *aa_loaddata_alloc(size_t size) - } - - /* test if read will be in packed data bounds */ --static bool inbounds(struct aa_ext *e, size_t size) -+VISIBLE_IF_KUNIT bool aa_inbounds(struct aa_ext *e, size_t size) - { - return (size <= e->end - e->pos); - } -+EXPORT_SYMBOL_IF_KUNIT(aa_inbounds); - - static void *kvmemdup(const void *src, size_t len) - { -@@ -214,22 +179,22 @@ static void *kvmemdup(const void *src, size_t len) - } - - /** -- * unpack_u16_chunk - test and do bounds checking for a u16 size based chunk -+ * aa_unpack_u16_chunk - test and do bounds checking for a u16 size based chunk - * @e: serialized data read head (NOT NULL) - * @chunk: start address for chunk of data (NOT NULL) - * - * Returns: the size of chunk found with the read head at the end of the chunk. - */ --static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk) -+VISIBLE_IF_KUNIT size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk) - { - size_t size = 0; - void *pos = e->pos; - -- if (!inbounds(e, sizeof(u16))) -+ if (!aa_inbounds(e, sizeof(u16))) - goto fail; - size = le16_to_cpu(get_unaligned((__le16 *) e->pos)); - e->pos += sizeof(__le16); -- if (!inbounds(e, size)) -+ if (!aa_inbounds(e, size)) - goto fail; - *chunk = e->pos; - e->pos += size; -@@ -239,20 +204,22 @@ fail: - e->pos = pos; - return 0; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u16_chunk); - - /* unpack control byte */ --static bool unpack_X(struct aa_ext *e, enum aa_code code) -+VISIBLE_IF_KUNIT bool aa_unpack_X(struct aa_ext *e, enum aa_code code) - { -- if (!inbounds(e, 1)) -+ if (!aa_inbounds(e, 1)) - return false; - if (*(u8 *) e->pos != code) - return false; - e->pos++; - return true; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_X); - - /** -- * unpack_nameX - check is the next element is of type X with a name of @name -+ * aa_unpack_nameX - check is the next element is of type X with a name of @name - * @e: serialized data extent information (NOT NULL) - * @code: type code - * @name: name to match to the serialized element. (MAYBE NULL) -@@ -267,7 +234,7 @@ static bool unpack_X(struct aa_ext *e, enum aa_code code) - * - * Returns: false if either match fails, the read head does not move - */ --static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) -+VISIBLE_IF_KUNIT bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) - { - /* - * May need to reset pos if name or type doesn't match -@@ -277,9 +244,9 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) - * Check for presence of a tagname, and if present name size - * AA_NAME tag value is a u16. - */ -- if (unpack_X(e, AA_NAME)) { -+ if (aa_unpack_X(e, AA_NAME)) { - char *tag = NULL; -- size_t size = unpack_u16_chunk(e, &tag); -+ size_t size = aa_unpack_u16_chunk(e, &tag); - /* if a name is specified it must match. otherwise skip tag */ - if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag))) - goto fail; -@@ -289,20 +256,21 @@ static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name) - } - - /* now check if type code matches */ -- if (unpack_X(e, code)) -+ if (aa_unpack_X(e, code)) - return true; - - fail: - e->pos = pos; - return false; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_nameX); - - static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name) - { - void *pos = e->pos; - -- if (unpack_nameX(e, AA_U8, name)) { -- if (!inbounds(e, sizeof(u8))) -+ if (aa_unpack_nameX(e, AA_U8, name)) { -+ if (!aa_inbounds(e, sizeof(u8))) - goto fail; - if (data) - *data = *((u8 *)e->pos); -@@ -315,12 +283,12 @@ fail: - return false; - } - --static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) -+VISIBLE_IF_KUNIT bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name) - { - void *pos = e->pos; - -- if (unpack_nameX(e, AA_U32, name)) { -- if (!inbounds(e, sizeof(u32))) -+ if (aa_unpack_nameX(e, AA_U32, name)) { -+ if (!aa_inbounds(e, sizeof(u32))) - goto fail; - if (data) - *data = le32_to_cpu(get_unaligned((__le32 *) e->pos)); -@@ -332,13 +300,14 @@ fail: - e->pos = pos; - return false; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u32); - --static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name) -+VISIBLE_IF_KUNIT bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name) - { - void *pos = e->pos; - -- if (unpack_nameX(e, AA_U64, name)) { -- if (!inbounds(e, sizeof(u64))) -+ if (aa_unpack_nameX(e, AA_U64, name)) { -+ if (!aa_inbounds(e, sizeof(u64))) - goto fail; - if (data) - *data = le64_to_cpu(get_unaligned((__le64 *) e->pos)); -@@ -350,14 +319,15 @@ fail: - e->pos = pos; - return false; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u64); - --static size_t unpack_array(struct aa_ext *e, const char *name) -+VISIBLE_IF_KUNIT size_t aa_unpack_array(struct aa_ext *e, const char *name) - { - void *pos = e->pos; - -- if (unpack_nameX(e, AA_ARRAY, name)) { -+ if (aa_unpack_nameX(e, AA_ARRAY, name)) { - int size; -- if (!inbounds(e, sizeof(u16))) -+ if (!aa_inbounds(e, sizeof(u16))) - goto fail; - size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos)); - e->pos += sizeof(u16); -@@ -368,18 +338,19 @@ fail: - e->pos = pos; - return 0; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_array); - --static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name) -+VISIBLE_IF_KUNIT size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name) - { - void *pos = e->pos; - -- if (unpack_nameX(e, AA_BLOB, name)) { -+ if (aa_unpack_nameX(e, AA_BLOB, name)) { - u32 size; -- if (!inbounds(e, sizeof(u32))) -+ if (!aa_inbounds(e, sizeof(u32))) - goto fail; - size = le32_to_cpu(get_unaligned((__le32 *) e->pos)); - e->pos += sizeof(u32); -- if (inbounds(e, (size_t) size)) { -+ if (aa_inbounds(e, (size_t) size)) { - *blob = e->pos; - e->pos += size; - return size; -@@ -390,15 +361,16 @@ fail: - e->pos = pos; - return 0; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_blob); - --static int unpack_str(struct aa_ext *e, const char **string, const char *name) -+VISIBLE_IF_KUNIT int aa_unpack_str(struct aa_ext *e, const char **string, const char *name) - { - char *src_str; - size_t size = 0; - void *pos = e->pos; - *string = NULL; -- if (unpack_nameX(e, AA_STRING, name)) { -- size = unpack_u16_chunk(e, &src_str); -+ if (aa_unpack_nameX(e, AA_STRING, name)) { -+ size = aa_unpack_u16_chunk(e, &src_str); - if (size) { - /* strings are null terminated, length is size - 1 */ - if (src_str[size - 1] != 0) -@@ -413,12 +385,13 @@ fail: - e->pos = pos; - return 0; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_str); - --static int unpack_strdup(struct aa_ext *e, char **string, const char *name) -+VISIBLE_IF_KUNIT int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name) - { - const char *tmp; - void *pos = e->pos; -- int res = unpack_str(e, &tmp, name); -+ int res = aa_unpack_str(e, &tmp, name); - *string = NULL; - - if (!res) -@@ -432,6 +405,7 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name) - - return res; - } -+EXPORT_SYMBOL_IF_KUNIT(aa_unpack_strdup); - - - /** -@@ -446,7 +420,7 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e) - size_t size; - struct aa_dfa *dfa = NULL; - -- size = unpack_blob(e, &blob, "aadfa"); -+ size = aa_unpack_blob(e, &blob, "aadfa"); - if (size) { - /* - * The dfa is aligned with in the blob to 8 bytes -@@ -482,10 +456,10 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) - void *saved_pos = e->pos; - - /* exec table is optional */ -- if (unpack_nameX(e, AA_STRUCT, "xtable")) { -+ if (aa_unpack_nameX(e, AA_STRUCT, "xtable")) { - int i, size; - -- size = unpack_array(e, NULL); -+ size = aa_unpack_array(e, NULL); - /* currently 4 exec bits and entries 0-3 are reserved iupcx */ - if (size > 16 - 4) - goto fail; -@@ -497,8 +471,8 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) - profile->file.trans.size = size; - for (i = 0; i < size; i++) { - char *str; -- int c, j, pos, size2 = unpack_strdup(e, &str, NULL); -- /* unpack_strdup verifies that the last character is -+ int c, j, pos, size2 = aa_unpack_strdup(e, &str, NULL); -+ /* aa_unpack_strdup verifies that the last character is - * null termination byte. - */ - if (!size2) -@@ -521,7 +495,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) - goto fail; - /* beginning with : requires an embedded \0, - * verify that exactly 1 internal \0 exists -- * trailing \0 already verified by unpack_strdup -+ * trailing \0 already verified by aa_unpack_strdup - * - * convert \0 back to : for label_parse - */ -@@ -533,9 +507,9 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) - /* fail - all other cases with embedded \0 */ - goto fail; - } -- if (!unpack_nameX(e, AA_ARRAYEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) - goto fail; -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) - goto fail; - } - return true; -@@ -550,21 +524,21 @@ static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile) - { - void *pos = e->pos; - -- if (unpack_nameX(e, AA_STRUCT, "xattrs")) { -+ if (aa_unpack_nameX(e, AA_STRUCT, "xattrs")) { - int i, size; - -- size = unpack_array(e, NULL); -+ size = aa_unpack_array(e, NULL); - profile->xattr_count = size; - profile->xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL); - if (!profile->xattrs) - goto fail; - for (i = 0; i < size; i++) { -- if (!unpack_strdup(e, &profile->xattrs[i], NULL)) -+ if (!aa_unpack_strdup(e, &profile->xattrs[i], NULL)) - goto fail; - } -- if (!unpack_nameX(e, AA_ARRAYEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) - goto fail; -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) - goto fail; - } - -@@ -580,8 +554,8 @@ static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile) - void *pos = e->pos; - int i, size; - -- if (unpack_nameX(e, AA_STRUCT, "secmark")) { -- size = unpack_array(e, NULL); -+ if (aa_unpack_nameX(e, AA_STRUCT, "secmark")) { -+ size = aa_unpack_array(e, NULL); - - profile->secmark = kcalloc(size, sizeof(struct aa_secmark), - GFP_KERNEL); -@@ -595,12 +569,12 @@ static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile) - goto fail; - if (!unpack_u8(e, &profile->secmark[i].deny, NULL)) - goto fail; -- if (!unpack_strdup(e, &profile->secmark[i].label, NULL)) -+ if (!aa_unpack_strdup(e, &profile->secmark[i].label, NULL)) - goto fail; - } -- if (!unpack_nameX(e, AA_ARRAYEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) - goto fail; -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) - goto fail; - } - -@@ -624,26 +598,26 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile) - void *pos = e->pos; - - /* rlimits are optional */ -- if (unpack_nameX(e, AA_STRUCT, "rlimits")) { -+ if (aa_unpack_nameX(e, AA_STRUCT, "rlimits")) { - int i, size; - u32 tmp = 0; -- if (!unpack_u32(e, &tmp, NULL)) -+ if (!aa_unpack_u32(e, &tmp, NULL)) - goto fail; - profile->rlimits.mask = tmp; - -- size = unpack_array(e, NULL); -+ size = aa_unpack_array(e, NULL); - if (size > RLIM_NLIMITS) - goto fail; - for (i = 0; i < size; i++) { - u64 tmp2 = 0; - int a = aa_map_resource(i); -- if (!unpack_u64(e, &tmp2, NULL)) -+ if (!aa_unpack_u64(e, &tmp2, NULL)) - goto fail; - profile->rlimits.limits[a].rlim_max = tmp2; - } -- if (!unpack_nameX(e, AA_ARRAYEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) - goto fail; -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) - goto fail; - } - return true; -@@ -682,7 +656,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - const char *info = "failed to unpack profile"; - size_t ns_len; - struct rhashtable_params params = { 0 }; -- char *key = NULL; -+ char *key = NULL, *disconnected = NULL; - struct aa_data *data; - int i, error = -EPROTO; - kernel_cap_t tmpcap; -@@ -691,9 +665,9 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - *ns_name = NULL; - - /* check that we have the right struct being passed */ -- if (!unpack_nameX(e, AA_STRUCT, "profile")) -+ if (!aa_unpack_nameX(e, AA_STRUCT, "profile")) - goto fail; -- if (!unpack_str(e, &name, NULL)) -+ if (!aa_unpack_str(e, &name, NULL)) - goto fail; - if (*name == '\0') - goto fail; -@@ -713,10 +687,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - return ERR_PTR(-ENOMEM); - - /* profile renaming is optional */ -- (void) unpack_str(e, &profile->rename, "rename"); -+ (void) aa_unpack_str(e, &profile->rename, "rename"); - - /* attachment string is optional */ -- (void) unpack_str(e, &profile->attach, "attach"); -+ (void) aa_unpack_str(e, &profile->attach, "attach"); - - /* xmatch is optional and may be NULL */ - profile->xmatch = unpack_dfa(e); -@@ -728,7 +702,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - } - /* xmatch_len is not optional if xmatch is set */ - if (profile->xmatch) { -- if (!unpack_u32(e, &tmp, NULL)) { -+ if (!aa_unpack_u32(e, &tmp, NULL)) { - info = "missing xmatch len"; - goto fail; - } -@@ -736,15 +710,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - } - - /* disconnected attachment string is optional */ -- (void) unpack_str(e, &profile->disconnected, "disconnected"); -+ (void) aa_unpack_strdup(e, &disconnected, "disconnected"); -+ profile->disconnected = disconnected; - - /* per profile debug flags (complain, audit) */ -- if (!unpack_nameX(e, AA_STRUCT, "flags")) { -+ if (!aa_unpack_nameX(e, AA_STRUCT, "flags")) { - info = "profile missing flags"; - goto fail; - } - info = "failed to unpack profile flags"; -- if (!unpack_u32(e, &tmp, NULL)) -+ if (!aa_unpack_u32(e, &tmp, NULL)) - goto fail; - if (tmp & PACKED_FLAG_HAT) - profile->label.flags |= FLAG_HAT; -@@ -752,7 +727,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - profile->label.flags |= FLAG_DEBUG1; - if (tmp & PACKED_FLAG_DEBUG2) - profile->label.flags |= FLAG_DEBUG2; -- if (!unpack_u32(e, &tmp, NULL)) -+ if (!aa_unpack_u32(e, &tmp, NULL)) - goto fail; - if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) { - profile->mode = APPARMOR_COMPLAIN; -@@ -766,16 +741,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - } else { - goto fail; - } -- if (!unpack_u32(e, &tmp, NULL)) -+ if (!aa_unpack_u32(e, &tmp, NULL)) - goto fail; - if (tmp) - profile->audit = AUDIT_ALL; - -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) - goto fail; - - /* path_flags is optional */ -- if (unpack_u32(e, &profile->path_flags, "path_flags")) -+ if (aa_unpack_u32(e, &profile->path_flags, "path_flags")) - profile->path_flags |= profile->label.flags & - PATH_MEDIATE_DELETED; - else -@@ -783,38 +758,38 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - profile->path_flags = PATH_MEDIATE_DELETED; - - info = "failed to unpack profile capabilities"; -- if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) -+ if (!aa_unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) - goto fail; -- if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) -+ if (!aa_unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) - goto fail; -- if (!unpack_u32(e, &(profile->caps.quiet.cap[0]), NULL)) -+ if (!aa_unpack_u32(e, &(profile->caps.quiet.cap[0]), NULL)) - goto fail; -- if (!unpack_u32(e, &tmpcap.cap[0], NULL)) -+ if (!aa_unpack_u32(e, &tmpcap.cap[0], NULL)) - goto fail; - - info = "failed to unpack upper profile capabilities"; -- if (unpack_nameX(e, AA_STRUCT, "caps64")) { -+ if (aa_unpack_nameX(e, AA_STRUCT, "caps64")) { - /* optional upper half of 64 bit caps */ -- if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) -+ if (!aa_unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) - goto fail; -- if (!unpack_u32(e, &(profile->caps.audit.cap[1]), NULL)) -+ if (!aa_unpack_u32(e, &(profile->caps.audit.cap[1]), NULL)) - goto fail; -- if (!unpack_u32(e, &(profile->caps.quiet.cap[1]), NULL)) -+ if (!aa_unpack_u32(e, &(profile->caps.quiet.cap[1]), NULL)) - goto fail; -- if (!unpack_u32(e, &(tmpcap.cap[1]), NULL)) -+ if (!aa_unpack_u32(e, &(tmpcap.cap[1]), NULL)) - goto fail; -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) - goto fail; - } - - info = "failed to unpack extended profile capabilities"; -- if (unpack_nameX(e, AA_STRUCT, "capsx")) { -+ if (aa_unpack_nameX(e, AA_STRUCT, "capsx")) { - /* optional extended caps mediation mask */ -- if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) -+ if (!aa_unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) - goto fail; -- if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL)) -+ if (!aa_unpack_u32(e, &(profile->caps.extended.cap[1]), NULL)) - goto fail; -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) - goto fail; - } - -@@ -833,7 +808,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - goto fail; - } - -- if (unpack_nameX(e, AA_STRUCT, "policydb")) { -+ if (aa_unpack_nameX(e, AA_STRUCT, "policydb")) { - /* generic policy dfa - optional and may be NULL */ - info = "failed to unpack policydb"; - profile->policy.dfa = unpack_dfa(e); -@@ -845,7 +820,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - error = -EPROTO; - goto fail; - } -- if (!unpack_u32(e, &profile->policy.start[0], "start")) -+ if (!aa_unpack_u32(e, &profile->policy.start[0], "start")) - /* default start state */ - profile->policy.start[0] = DFA_START; - /* setup class index */ -@@ -855,7 +830,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - profile->policy.start[0], - i); - } -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) - goto fail; - } else - profile->policy.dfa = aa_get_dfa(nulldfa); -@@ -868,7 +843,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - info = "failed to unpack profile file rules"; - goto fail; - } else if (profile->file.dfa) { -- if (!unpack_u32(e, &profile->file.start, "dfa_start")) -+ if (!aa_unpack_u32(e, &profile->file.start, "dfa_start")) - /* default start state */ - profile->file.start = DFA_START; - } else if (profile->policy.dfa && -@@ -883,7 +858,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - goto fail; - } - -- if (unpack_nameX(e, AA_STRUCT, "data")) { -+ if (aa_unpack_nameX(e, AA_STRUCT, "data")) { - info = "out of memory"; - profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); - if (!profile->data) -@@ -901,7 +876,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - goto fail; - } - -- while (unpack_strdup(e, &key, NULL)) { -+ while (aa_unpack_strdup(e, &key, NULL)) { - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - kfree_sensitive(key); -@@ -909,7 +884,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - } - - data->key = key; -- data->size = unpack_blob(e, &data->data, NULL); -+ data->size = aa_unpack_blob(e, &data->data, NULL); - data->data = kvmemdup(data->data, data->size); - if (data->size && !data->data) { - kfree_sensitive(data->key); -@@ -926,13 +901,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) - } - } - -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) { -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) { - info = "failed to unpack end of key, value data table"; - goto fail; - } - } - -- if (!unpack_nameX(e, AA_STRUCTEND, NULL)) { -+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) { - info = "failed to unpack end of profile"; - goto fail; - } -@@ -965,7 +940,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns) - *ns = NULL; - - /* get the interface version */ -- if (!unpack_u32(e, &e->version, "version")) { -+ if (!aa_unpack_u32(e, &e->version, "version")) { - if (required) { - audit_iface(NULL, NULL, NULL, "invalid profile format", - e, error); -@@ -984,7 +959,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns) - } - - /* read the namespace if present */ -- if (unpack_str(e, &name, "namespace")) { -+ if (aa_unpack_str(e, &name, "namespace")) { - if (*name == '\0') { - audit_iface(NULL, NULL, NULL, "invalid namespace name", - e, error); -@@ -1256,7 +1231,3 @@ fail: - - return error; - } -- --#ifdef CONFIG_SECURITY_APPARMOR_KUNIT_TEST --#include "policy_unpack_test.c" --#endif /* CONFIG_SECURITY_APPARMOR_KUNIT_TEST */ -diff --git a/security/apparmor/policy_unpack_test.c b/security/apparmor/policy_unpack_test.c -index 0a969b2e03dba..f25cf2a023d57 100644 ---- a/security/apparmor/policy_unpack_test.c -+++ b/security/apparmor/policy_unpack_test.c -@@ -4,6 +4,7 @@ - */ - - #include -+#include - - #include "include/policy.h" - #include "include/policy_unpack.h" -@@ -43,6 +44,8 @@ - #define TEST_ARRAY_BUF_OFFSET \ - (TEST_NAMED_ARRAY_BUF_OFFSET + 3 + strlen(TEST_ARRAY_NAME) + 1) - -+MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); -+ - struct policy_unpack_fixture { - struct aa_ext *e; - size_t e_size; -@@ -125,16 +128,16 @@ static void policy_unpack_test_inbounds_when_inbounds(struct kunit *test) - { - struct policy_unpack_fixture *puf = test->priv; - -- KUNIT_EXPECT_TRUE(test, inbounds(puf->e, 0)); -- KUNIT_EXPECT_TRUE(test, inbounds(puf->e, puf->e_size / 2)); -- KUNIT_EXPECT_TRUE(test, inbounds(puf->e, puf->e_size)); -+ KUNIT_EXPECT_TRUE(test, aa_inbounds(puf->e, 0)); -+ KUNIT_EXPECT_TRUE(test, aa_inbounds(puf->e, puf->e_size / 2)); -+ KUNIT_EXPECT_TRUE(test, aa_inbounds(puf->e, puf->e_size)); - } - - static void policy_unpack_test_inbounds_when_out_of_bounds(struct kunit *test) - { - struct policy_unpack_fixture *puf = test->priv; - -- KUNIT_EXPECT_FALSE(test, inbounds(puf->e, puf->e_size + 1)); -+ KUNIT_EXPECT_FALSE(test, aa_inbounds(puf->e, puf->e_size + 1)); - } - - static void policy_unpack_test_unpack_array_with_null_name(struct kunit *test) -@@ -144,7 +147,7 @@ static void policy_unpack_test_unpack_array_with_null_name(struct kunit *test) - - puf->e->pos += TEST_ARRAY_BUF_OFFSET; - -- array_size = unpack_array(puf->e, NULL); -+ array_size = aa_unpack_array(puf->e, NULL); - - KUNIT_EXPECT_EQ(test, array_size, (u16)TEST_ARRAY_SIZE); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -159,7 +162,7 @@ static void policy_unpack_test_unpack_array_with_name(struct kunit *test) - - puf->e->pos += TEST_NAMED_ARRAY_BUF_OFFSET; - -- array_size = unpack_array(puf->e, name); -+ array_size = aa_unpack_array(puf->e, name); - - KUNIT_EXPECT_EQ(test, array_size, (u16)TEST_ARRAY_SIZE); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -175,7 +178,7 @@ static void policy_unpack_test_unpack_array_out_of_bounds(struct kunit *test) - puf->e->pos += TEST_NAMED_ARRAY_BUF_OFFSET; - puf->e->end = puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16); - -- array_size = unpack_array(puf->e, name); -+ array_size = aa_unpack_array(puf->e, name); - - KUNIT_EXPECT_EQ(test, array_size, 0); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -189,7 +192,7 @@ static void policy_unpack_test_unpack_blob_with_null_name(struct kunit *test) - size_t size; - - puf->e->pos += TEST_BLOB_BUF_OFFSET; -- size = unpack_blob(puf->e, &blob, NULL); -+ size = aa_unpack_blob(puf->e, &blob, NULL); - - KUNIT_ASSERT_EQ(test, size, TEST_BLOB_DATA_SIZE); - KUNIT_EXPECT_TRUE(test, -@@ -203,7 +206,7 @@ static void policy_unpack_test_unpack_blob_with_name(struct kunit *test) - size_t size; - - puf->e->pos += TEST_NAMED_BLOB_BUF_OFFSET; -- size = unpack_blob(puf->e, &blob, TEST_BLOB_NAME); -+ size = aa_unpack_blob(puf->e, &blob, TEST_BLOB_NAME); - - KUNIT_ASSERT_EQ(test, size, TEST_BLOB_DATA_SIZE); - KUNIT_EXPECT_TRUE(test, -@@ -222,7 +225,7 @@ static void policy_unpack_test_unpack_blob_out_of_bounds(struct kunit *test) - puf->e->end = puf->e->start + TEST_BLOB_BUF_OFFSET - + TEST_BLOB_DATA_SIZE - 1; - -- size = unpack_blob(puf->e, &blob, TEST_BLOB_NAME); -+ size = aa_unpack_blob(puf->e, &blob, TEST_BLOB_NAME); - - KUNIT_EXPECT_EQ(test, size, 0); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start); -@@ -235,7 +238,7 @@ static void policy_unpack_test_unpack_str_with_null_name(struct kunit *test) - size_t size; - - puf->e->pos += TEST_STRING_BUF_OFFSET; -- size = unpack_str(puf->e, &string, NULL); -+ size = aa_unpack_str(puf->e, &string, NULL); - - KUNIT_EXPECT_EQ(test, size, strlen(TEST_STRING_DATA) + 1); - KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA); -@@ -247,7 +250,7 @@ static void policy_unpack_test_unpack_str_with_name(struct kunit *test) - const char *string = NULL; - size_t size; - -- size = unpack_str(puf->e, &string, TEST_STRING_NAME); -+ size = aa_unpack_str(puf->e, &string, TEST_STRING_NAME); - - KUNIT_EXPECT_EQ(test, size, strlen(TEST_STRING_DATA) + 1); - KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA); -@@ -263,7 +266,7 @@ static void policy_unpack_test_unpack_str_out_of_bounds(struct kunit *test) - puf->e->end = puf->e->pos + TEST_STRING_BUF_OFFSET - + strlen(TEST_STRING_DATA) - 1; - -- size = unpack_str(puf->e, &string, TEST_STRING_NAME); -+ size = aa_unpack_str(puf->e, &string, TEST_STRING_NAME); - - KUNIT_EXPECT_EQ(test, size, 0); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start); -@@ -276,7 +279,7 @@ static void policy_unpack_test_unpack_strdup_with_null_name(struct kunit *test) - size_t size; - - puf->e->pos += TEST_STRING_BUF_OFFSET; -- size = unpack_strdup(puf->e, &string, NULL); -+ size = aa_unpack_strdup(puf->e, &string, NULL); - - KUNIT_EXPECT_EQ(test, size, strlen(TEST_STRING_DATA) + 1); - KUNIT_EXPECT_FALSE(test, -@@ -291,7 +294,7 @@ static void policy_unpack_test_unpack_strdup_with_name(struct kunit *test) - char *string = NULL; - size_t size; - -- size = unpack_strdup(puf->e, &string, TEST_STRING_NAME); -+ size = aa_unpack_strdup(puf->e, &string, TEST_STRING_NAME); - - KUNIT_EXPECT_EQ(test, size, strlen(TEST_STRING_DATA) + 1); - KUNIT_EXPECT_FALSE(test, -@@ -310,7 +313,7 @@ static void policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit *test) - puf->e->end = puf->e->pos + TEST_STRING_BUF_OFFSET - + strlen(TEST_STRING_DATA) - 1; - -- size = unpack_strdup(puf->e, &string, TEST_STRING_NAME); -+ size = aa_unpack_strdup(puf->e, &string, TEST_STRING_NAME); - - KUNIT_EXPECT_EQ(test, size, 0); - KUNIT_EXPECT_NULL(test, string); -@@ -324,7 +327,7 @@ static void policy_unpack_test_unpack_nameX_with_null_name(struct kunit *test) - - puf->e->pos += TEST_U32_BUF_OFFSET; - -- success = unpack_nameX(puf->e, AA_U32, NULL); -+ success = aa_unpack_nameX(puf->e, AA_U32, NULL); - - KUNIT_EXPECT_TRUE(test, success); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -338,7 +341,7 @@ static void policy_unpack_test_unpack_nameX_with_wrong_code(struct kunit *test) - - puf->e->pos += TEST_U32_BUF_OFFSET; - -- success = unpack_nameX(puf->e, AA_BLOB, NULL); -+ success = aa_unpack_nameX(puf->e, AA_BLOB, NULL); - - KUNIT_EXPECT_FALSE(test, success); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -353,7 +356,7 @@ static void policy_unpack_test_unpack_nameX_with_name(struct kunit *test) - - puf->e->pos += TEST_NAMED_U32_BUF_OFFSET; - -- success = unpack_nameX(puf->e, AA_U32, name); -+ success = aa_unpack_nameX(puf->e, AA_U32, name); - - KUNIT_EXPECT_TRUE(test, success); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -368,7 +371,7 @@ static void policy_unpack_test_unpack_nameX_with_wrong_name(struct kunit *test) - - puf->e->pos += TEST_NAMED_U32_BUF_OFFSET; - -- success = unpack_nameX(puf->e, AA_U32, name); -+ success = aa_unpack_nameX(puf->e, AA_U32, name); - - KUNIT_EXPECT_FALSE(test, success); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -389,7 +392,7 @@ static void policy_unpack_test_unpack_u16_chunk_basic(struct kunit *test) - */ - puf->e->end += TEST_U16_DATA; - -- size = unpack_u16_chunk(puf->e, &chunk); -+ size = aa_unpack_u16_chunk(puf->e, &chunk); - - KUNIT_EXPECT_PTR_EQ(test, chunk, - puf->e->start + TEST_U16_OFFSET + 2); -@@ -406,7 +409,7 @@ static void policy_unpack_test_unpack_u16_chunk_out_of_bounds_1( - - puf->e->pos = puf->e->end - 1; - -- size = unpack_u16_chunk(puf->e, &chunk); -+ size = aa_unpack_u16_chunk(puf->e, &chunk); - - KUNIT_EXPECT_EQ(test, size, 0); - KUNIT_EXPECT_NULL(test, chunk); -@@ -428,7 +431,7 @@ static void policy_unpack_test_unpack_u16_chunk_out_of_bounds_2( - */ - puf->e->end = puf->e->pos + TEST_U16_DATA - 1; - -- size = unpack_u16_chunk(puf->e, &chunk); -+ size = aa_unpack_u16_chunk(puf->e, &chunk); - - KUNIT_EXPECT_EQ(test, size, 0); - KUNIT_EXPECT_NULL(test, chunk); -@@ -443,7 +446,7 @@ static void policy_unpack_test_unpack_u32_with_null_name(struct kunit *test) - - puf->e->pos += TEST_U32_BUF_OFFSET; - -- success = unpack_u32(puf->e, &data, NULL); -+ success = aa_unpack_u32(puf->e, &data, NULL); - - KUNIT_EXPECT_TRUE(test, success); - KUNIT_EXPECT_EQ(test, data, TEST_U32_DATA); -@@ -460,7 +463,7 @@ static void policy_unpack_test_unpack_u32_with_name(struct kunit *test) - - puf->e->pos += TEST_NAMED_U32_BUF_OFFSET; - -- success = unpack_u32(puf->e, &data, name); -+ success = aa_unpack_u32(puf->e, &data, name); - - KUNIT_EXPECT_TRUE(test, success); - KUNIT_EXPECT_EQ(test, data, TEST_U32_DATA); -@@ -478,7 +481,7 @@ static void policy_unpack_test_unpack_u32_out_of_bounds(struct kunit *test) - puf->e->pos += TEST_NAMED_U32_BUF_OFFSET; - puf->e->end = puf->e->start + TEST_U32_BUF_OFFSET + sizeof(u32); - -- success = unpack_u32(puf->e, &data, name); -+ success = aa_unpack_u32(puf->e, &data, name); - - KUNIT_EXPECT_FALSE(test, success); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -493,7 +496,7 @@ static void policy_unpack_test_unpack_u64_with_null_name(struct kunit *test) - - puf->e->pos += TEST_U64_BUF_OFFSET; - -- success = unpack_u64(puf->e, &data, NULL); -+ success = aa_unpack_u64(puf->e, &data, NULL); - - KUNIT_EXPECT_TRUE(test, success); - KUNIT_EXPECT_EQ(test, data, TEST_U64_DATA); -@@ -510,7 +513,7 @@ static void policy_unpack_test_unpack_u64_with_name(struct kunit *test) - - puf->e->pos += TEST_NAMED_U64_BUF_OFFSET; - -- success = unpack_u64(puf->e, &data, name); -+ success = aa_unpack_u64(puf->e, &data, name); - - KUNIT_EXPECT_TRUE(test, success); - KUNIT_EXPECT_EQ(test, data, TEST_U64_DATA); -@@ -528,7 +531,7 @@ static void policy_unpack_test_unpack_u64_out_of_bounds(struct kunit *test) - puf->e->pos += TEST_NAMED_U64_BUF_OFFSET; - puf->e->end = puf->e->start + TEST_U64_BUF_OFFSET + sizeof(u64); - -- success = unpack_u64(puf->e, &data, name); -+ success = aa_unpack_u64(puf->e, &data, name); - - KUNIT_EXPECT_FALSE(test, success); - KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, -@@ -538,7 +541,7 @@ static void policy_unpack_test_unpack_u64_out_of_bounds(struct kunit *test) - static void policy_unpack_test_unpack_X_code_match(struct kunit *test) - { - struct policy_unpack_fixture *puf = test->priv; -- bool success = unpack_X(puf->e, AA_NAME); -+ bool success = aa_unpack_X(puf->e, AA_NAME); - - KUNIT_EXPECT_TRUE(test, success); - KUNIT_EXPECT_TRUE(test, puf->e->pos == puf->e->start + 1); -@@ -547,7 +550,7 @@ static void policy_unpack_test_unpack_X_code_match(struct kunit *test) - static void policy_unpack_test_unpack_X_code_mismatch(struct kunit *test) - { - struct policy_unpack_fixture *puf = test->priv; -- bool success = unpack_X(puf->e, AA_STRING); -+ bool success = aa_unpack_X(puf->e, AA_STRING); - - KUNIT_EXPECT_FALSE(test, success); - KUNIT_EXPECT_TRUE(test, puf->e->pos == puf->e->start); -@@ -559,7 +562,7 @@ static void policy_unpack_test_unpack_X_out_of_bounds(struct kunit *test) - bool success; - - puf->e->pos = puf->e->end; -- success = unpack_X(puf->e, AA_NAME); -+ success = aa_unpack_X(puf->e, AA_NAME); - - KUNIT_EXPECT_FALSE(test, success); - } -@@ -605,3 +608,5 @@ static struct kunit_suite apparmor_policy_unpack_test_module = { - }; - - kunit_test_suite(apparmor_policy_unpack_test_module); -+ -+MODULE_LICENSE("GPL"); -diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c -index a5b10a6a33a5e..c79a12e5c9ad2 100644 ---- a/sound/pci/hda/cs35l41_hda.c -+++ b/sound/pci/hda/cs35l41_hda.c -@@ -1501,8 +1501,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i - ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); - if (ret) { - dev_err(cs35l41->dev, "Register component failed: %d\n", ret); -- pm_runtime_disable(cs35l41->dev); -- goto err; -+ goto err_pm; - } - - dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", regid, reg_revid); -@@ -1510,6 +1509,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i - return 0; - - err_pm: -+ pm_runtime_dont_use_autosuspend(cs35l41->dev); - pm_runtime_disable(cs35l41->dev); - pm_runtime_put_noidle(cs35l41->dev); - -@@ -1528,6 +1528,7 @@ void cs35l41_hda_remove(struct device *dev) - struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); - - pm_runtime_get_sync(cs35l41->dev); -+ pm_runtime_dont_use_autosuspend(cs35l41->dev); - pm_runtime_disable(cs35l41->dev); - - if (cs35l41->halo_initialized) -diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c -index 2f4b0ee93aced..e91c1a4640e46 100644 ---- a/sound/soc/codecs/cs35l41.c -+++ b/sound/soc/codecs/cs35l41.c -@@ -374,10 +374,18 @@ static irqreturn_t cs35l41_irq(int irq, void *data) - struct cs35l41_private *cs35l41 = data; - unsigned int status[4] = { 0, 0, 0, 0 }; - unsigned int masks[4] = { 0, 0, 0, 0 }; -- int ret = IRQ_NONE; - unsigned int i; -+ int ret; - -- pm_runtime_get_sync(cs35l41->dev); -+ ret = pm_runtime_resume_and_get(cs35l41->dev); -+ if (ret < 0) { -+ dev_err(cs35l41->dev, -+ "pm_runtime_resume_and_get failed in %s: %d\n", -+ __func__, ret); -+ return IRQ_NONE; -+ } -+ -+ ret = IRQ_NONE; - - for (i = 0; i < ARRAY_SIZE(status); i++) { - regmap_read(cs35l41->regmap, -@@ -1330,6 +1338,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * - return 0; - - err_pm: -+ pm_runtime_dont_use_autosuspend(cs35l41->dev); - pm_runtime_disable(cs35l41->dev); - pm_runtime_put_noidle(cs35l41->dev); - -@@ -1346,6 +1355,7 @@ EXPORT_SYMBOL_GPL(cs35l41_probe); - void cs35l41_remove(struct cs35l41_private *cs35l41) - { - pm_runtime_get_sync(cs35l41->dev); -+ pm_runtime_dont_use_autosuspend(cs35l41->dev); - pm_runtime_disable(cs35l41->dev); - - regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); -diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c -index 0b1cdb2d60498..4d3c3365488a2 100644 ---- a/sound/soc/codecs/hdmi-codec.c -+++ b/sound/soc/codecs/hdmi-codec.c -@@ -861,18 +861,13 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component, - void *data) - { - struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); -- int ret = -ENOTSUPP; - - if (hcp->hcd.ops->hook_plugged_cb) { - hcp->jack = jack; -- ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent, -- hcp->hcd.data, -- plugged_cb, -- component->dev); -- if (ret) -- hcp->jack = NULL; -+ return 0; - } -- return ret; -+ -+ return -ENOTSUPP; - } - - static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) -@@ -948,6 +943,21 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component, - return ret; - } - -+static int hdmi_probe(struct snd_soc_component *component) -+{ -+ struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); -+ int ret = 0; -+ -+ if (hcp->hcd.ops->hook_plugged_cb) { -+ ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent, -+ hcp->hcd.data, -+ plugged_cb, -+ component->dev); -+ } -+ -+ return ret; -+} -+ - static void hdmi_remove(struct snd_soc_component *component) - { - struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); -@@ -958,6 +968,7 @@ static void hdmi_remove(struct snd_soc_component *component) - } - - static const struct snd_soc_component_driver hdmi_driver = { -+ .probe = hdmi_probe, - .remove = hdmi_remove, - .dapm_widgets = hdmi_widgets, - .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), -diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c -index 3153d19136b29..84e6f9eb784dc 100644 ---- a/sound/soc/fsl/fsl_easrc.c -+++ b/sound/soc/fsl/fsl_easrc.c -@@ -1966,17 +1966,21 @@ static int fsl_easrc_probe(struct platform_device *pdev) - &fsl_easrc_dai, 1); - if (ret) { - dev_err(dev, "failed to register ASoC DAI\n"); -- return ret; -+ goto err_pm_disable; - } - - ret = devm_snd_soc_register_component(dev, &fsl_asrc_component, - NULL, 0); - if (ret) { - dev_err(&pdev->dev, "failed to register ASoC platform\n"); -- return ret; -+ goto err_pm_disable; - } - - return 0; -+ -+err_pm_disable: -+ pm_runtime_disable(&pdev->dev); -+ return ret; - } - - static int fsl_easrc_remove(struct platform_device *pdev) -diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c -index 9014978100207..3f7ccae3f6b1a 100644 ---- a/sound/soc/fsl/mpc5200_dma.c -+++ b/sound/soc/fsl/mpc5200_dma.c -@@ -100,6 +100,9 @@ static irqreturn_t psc_dma_bcom_irq(int irq, void *_psc_dma_stream) - - /** - * psc_dma_trigger: start and stop the DMA transfer. -+ * @component: triggered component -+ * @substream: triggered substream -+ * @cmd: triggered command - * - * This function is called by ALSA to start, stop, pause, and resume the DMA - * transfer of data. -diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c -index 57ea815d3f041..b776c58dcf47a 100644 ---- a/sound/soc/intel/skylake/skl-sst-utils.c -+++ b/sound/soc/intel/skylake/skl-sst-utils.c -@@ -299,6 +299,7 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, - module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL); - if (!module->instance_id) { - ret = -ENOMEM; -+ kfree(module); - goto free_uuid_list; - } - -diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c b/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c -index 6babadb2e6fe2..f76bae1d81a09 100644 ---- a/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c -+++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c -@@ -1080,7 +1080,7 @@ static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev) - playback_codec = of_get_child_by_name(pdev->dev.of_node, "playback-codecs"); - if (!playback_codec) { - ret = -EINVAL; -- dev_err_probe(&pdev->dev, ret, "Property 'speaker-codecs' missing or invalid\n"); -+ dev_err_probe(&pdev->dev, ret, "Property 'playback-codecs' missing or invalid\n"); - goto err_playback_codec; - } - -@@ -1094,7 +1094,7 @@ static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev) - for_each_card_prelinks(card, i, dai_link) { - ret = mt8186_mt6366_card_set_be_link(card, dai_link, playback_codec, "I2S3"); - if (ret) { -- dev_err_probe(&pdev->dev, ret, "%s set speaker_codec fail\n", -+ dev_err_probe(&pdev->dev, ret, "%s set playback_codec fail\n", - dai_link->name); - goto err_probe; - } -diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c -index 879cf1be67a9f..6eb8c6cb5e673 100644 ---- a/sound/soc/soc-dapm.c -+++ b/sound/soc/soc-dapm.c -@@ -3670,7 +3670,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, - dapm_pinctrl_event(w, NULL, SND_SOC_DAPM_POST_PMD); - break; - case snd_soc_dapm_clock_supply: -- w->clk = devm_clk_get(dapm->dev, w->name); -+ w->clk = devm_clk_get(dapm->dev, widget->name); - if (IS_ERR(w->clk)) { - ret = PTR_ERR(w->clk); - goto request_failed; -diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c -index eaa16755a2704..93e1c38392a32 100644 ---- a/sound/soc/sof/core.c -+++ b/sound/soc/sof/core.c -@@ -434,9 +434,10 @@ int snd_sof_device_remove(struct device *dev) - struct snd_sof_dev *sdev = dev_get_drvdata(dev); - struct snd_sof_pdata *pdata = sdev->pdata; - int ret; -+ bool aborted = false; - - if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) -- cancel_work_sync(&sdev->probe_work); -+ aborted = cancel_work_sync(&sdev->probe_work); - - /* - * Unregister any registered client device first before IPC and debugfs -@@ -462,6 +463,9 @@ int snd_sof_device_remove(struct device *dev) - snd_sof_free_debug(sdev); - snd_sof_remove(sdev); - sof_ops_free(sdev); -+ } else if (aborted) { -+ /* probe_work never ran */ -+ sof_ops_free(sdev); - } - - /* release firmware */ -diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c -index 438e2fa843a03..1acc4505aa9a9 100644 ---- a/sound/soc/ti/ams-delta.c -+++ b/sound/soc/ti/ams-delta.c -@@ -303,7 +303,7 @@ static int cx81801_open(struct tty_struct *tty) - static void cx81801_close(struct tty_struct *tty) - { - struct snd_soc_component *component = tty->disc_data; -- struct snd_soc_dapm_context *dapm = &component->card->dapm; -+ struct snd_soc_dapm_context *dapm; - - del_timer_sync(&cx81801_timer); - -@@ -315,6 +315,8 @@ static void cx81801_close(struct tty_struct *tty) - - v253_ops.close(tty); - -+ dapm = &component->card->dapm; -+ - /* Revert back to default audio input/output constellation */ - snd_soc_dapm_mutex_lock(dapm); - -diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c -index 44bbf80f0cfdd..0d0a7a19d6f95 100644 ---- a/tools/iio/iio_generic_buffer.c -+++ b/tools/iio/iio_generic_buffer.c -@@ -54,9 +54,12 @@ enum autochan { - static unsigned int size_from_channelarray(struct iio_channel_info *channels, int num_channels) - { - unsigned int bytes = 0; -- int i = 0; -+ int i = 0, max = 0; -+ unsigned int misalignment; - - while (i < num_channels) { -+ if (channels[i].bytes > max) -+ max = channels[i].bytes; - if (bytes % channels[i].bytes == 0) - channels[i].location = bytes; - else -@@ -66,6 +69,14 @@ static unsigned int size_from_channelarray(struct iio_channel_info *channels, in - bytes = channels[i].location + channels[i].bytes; - i++; - } -+ /* -+ * We want the data in next sample to also be properly aligned so -+ * we'll add padding at the end if needed. Adding padding only -+ * works for channel data which size is 2^n bytes. -+ */ -+ misalignment = bytes % max; -+ if (misalignment) -+ bytes += max - misalignment; - - return bytes; - } -diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c -index a7ecc32e35125..cda649644e32d 100644 ---- a/tools/objtool/objtool.c -+++ b/tools/objtool/objtool.c -@@ -146,7 +146,5 @@ int main(int argc, const char **argv) - exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED); - pager_init(UNUSED); - -- objtool_run(argc, argv); -- -- return 0; -+ return objtool_run(argc, argv); - } -diff --git a/tools/perf/Documentation/perf-kwork.txt b/tools/perf/Documentation/perf-kwork.txt -index 3c36324712b6e..482d6c52e2edf 100644 ---- a/tools/perf/Documentation/perf-kwork.txt -+++ b/tools/perf/Documentation/perf-kwork.txt -@@ -8,7 +8,7 @@ perf-kwork - Tool to trace/measure kernel work properties (latencies) - SYNOPSIS - -------- - [verse] --'perf kwork' {record} -+'perf kwork' {record|report|latency|timehist} - - DESCRIPTION - ----------- -diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c -index fb8c63656ad89..25cba0d61736c 100644 ---- a/tools/perf/builtin-kwork.c -+++ b/tools/perf/builtin-kwork.c -@@ -399,12 +399,14 @@ static int work_push_atom(struct perf_kwork *kwork, - - work = work_findnew(&class->work_root, &key, &kwork->cmp_id); - if (work == NULL) { -- free(atom); -+ atom_free(atom); - return -1; - } - -- if (!profile_event_match(kwork, work, sample)) -+ if (!profile_event_match(kwork, work, sample)) { -+ atom_free(atom); - return 0; -+ } - - if (dst_type < KWORK_TRACE_MAX) { - dst_atom = list_last_entry_or_null(&work->atom_list[dst_type], -@@ -1670,9 +1672,10 @@ int cmd_kwork(int argc, const char **argv) - static struct perf_kwork kwork = { - .class_list = LIST_HEAD_INIT(kwork.class_list), - .tool = { -- .mmap = perf_event__process_mmap, -- .mmap2 = perf_event__process_mmap2, -- .sample = perf_kwork__process_tracepoint_sample, -+ .mmap = perf_event__process_mmap, -+ .mmap2 = perf_event__process_mmap2, -+ .sample = perf_kwork__process_tracepoint_sample, -+ .ordered_events = true, - }, - .atom_page_list = LIST_HEAD_INIT(kwork.atom_page_list), - .sort_list = LIST_HEAD_INIT(kwork.sort_list), -diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c -index a2c74a34e4a44..bdd8dd54fdb63 100644 ---- a/tools/perf/builtin-stat.c -+++ b/tools/perf/builtin-stat.c -@@ -1444,7 +1444,7 @@ static int perf_stat_init_aggr_mode(void) - * taking the highest cpu number to be the size of - * the aggregation translate cpumap. - */ -- if (evsel_list->core.user_requested_cpus) -+ if (!perf_cpu_map__empty(evsel_list->core.user_requested_cpus)) - nr = perf_cpu_map__max(evsel_list->core.user_requested_cpus).cpu; - else - nr = 0; -diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c -index 01f70b8e705a8..21f4d9ba023d9 100644 ---- a/tools/perf/util/bpf_off_cpu.c -+++ b/tools/perf/util/bpf_off_cpu.c -@@ -98,7 +98,7 @@ static void off_cpu_finish(void *arg __maybe_unused) - /* v5.18 kernel added prev_state arg, so it needs to check the signature */ - static void check_sched_switch_args(void) - { -- const struct btf *btf = bpf_object__btf(skel->obj); -+ const struct btf *btf = btf__load_vmlinux_btf(); - const struct btf_type *t1, *t2, *t3; - u32 type_id; - -@@ -116,7 +116,8 @@ static void check_sched_switch_args(void) - return; - - t3 = btf__type_by_id(btf, t2->type); -- if (t3 && btf_is_func_proto(t3) && btf_vlen(t3) == 4) { -+ /* btf_trace func proto has one more argument for the context */ -+ if (t3 && btf_is_func_proto(t3) && btf_vlen(t3) == 5) { - /* new format: pass prev_state as 4th arg */ - skel->rodata->has_prev_state = true; - } -diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c -index 17a05e943b44b..bffd058cbecee 100644 ---- a/tools/perf/util/hist.c -+++ b/tools/perf/util/hist.c -@@ -2645,8 +2645,6 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, - - /* If we have branch cycles always annotate them. */ - if (bs && bs->nr && entries[0].flags.cycles) { -- int i; -- - bi = sample__resolve_bstack(sample, al); - if (bi) { - struct addr_map_symbol *prev = NULL; -@@ -2661,7 +2659,7 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, - * Note that perf stores branches reversed from - * program order! - */ -- for (i = bs->nr - 1; i >= 0; i--) { -+ for (int i = bs->nr - 1; i >= 0; i--) { - addr_map_symbol__account_cycles(&bi[i].from, - nonany_branch_mode ? NULL : prev, - bi[i].flags.cycles); -@@ -2670,6 +2668,12 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, - if (total_cycles) - *total_cycles += bi[i].flags.cycles; - } -+ for (unsigned int i = 0; i < bs->nr; i++) { -+ map__put(bi[i].to.ms.map); -+ maps__put(bi[i].to.ms.maps); -+ map__put(bi[i].from.ms.map); -+ maps__put(bi[i].from.ms.maps); -+ } - free(bi); - } - } -diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c -index 76316e459c3de..9cd52f50ea7ac 100644 ---- a/tools/perf/util/machine.c -+++ b/tools/perf/util/machine.c -@@ -2555,16 +2555,18 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread, - save_lbr_cursor_node(thread, cursor, i); - } - -- /* Add LBR ip from first entries.to */ -- ip = entries[0].to; -- flags = &entries[0].flags; -- *branch_from = entries[0].from; -- err = add_callchain_ip(thread, cursor, parent, -- root_al, &cpumode, ip, -- true, flags, NULL, -- *branch_from); -- if (err) -- return err; -+ if (lbr_nr > 0) { -+ /* Add LBR ip from first entries.to */ -+ ip = entries[0].to; -+ flags = &entries[0].flags; -+ *branch_from = entries[0].from; -+ err = add_callchain_ip(thread, cursor, parent, -+ root_al, &cpumode, ip, -+ true, flags, NULL, -+ *branch_from); -+ if (err) -+ return err; -+ } - - return 0; - } -diff --git a/tools/testing/selftests/bpf/prog_tests/tailcalls.c b/tools/testing/selftests/bpf/prog_tests/tailcalls.c -index 58fe2c586ed76..09c189761926c 100644 ---- a/tools/testing/selftests/bpf/prog_tests/tailcalls.c -+++ b/tools/testing/selftests/bpf/prog_tests/tailcalls.c -@@ -271,11 +271,11 @@ static void test_tailcall_count(const char *which) - - data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); - if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) -- return; -+ goto out; - - data_fd = bpf_map__fd(data_map); -- if (CHECK_FAIL(map_fd < 0)) -- return; -+ if (CHECK_FAIL(data_fd < 0)) -+ goto out; - - i = 0; - err = bpf_map_lookup_elem(data_fd, &i, &val); -@@ -352,11 +352,11 @@ static void test_tailcall_4(void) - - data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); - if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) -- return; -+ goto out; - - data_fd = bpf_map__fd(data_map); -- if (CHECK_FAIL(map_fd < 0)) -- return; -+ if (CHECK_FAIL(data_fd < 0)) -+ goto out; - - for (i = 0; i < bpf_map__max_entries(prog_array); i++) { - snprintf(prog_name, sizeof(prog_name), "classifier_%d", i); -@@ -442,11 +442,11 @@ static void test_tailcall_5(void) - - data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); - if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) -- return; -+ goto out; - - data_fd = bpf_map__fd(data_map); -- if (CHECK_FAIL(map_fd < 0)) -- return; -+ if (CHECK_FAIL(data_fd < 0)) -+ goto out; - - for (i = 0; i < bpf_map__max_entries(prog_array); i++) { - snprintf(prog_name, sizeof(prog_name), "classifier_%d", i); -@@ -631,11 +631,11 @@ static void test_tailcall_bpf2bpf_2(void) - - data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); - if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) -- return; -+ goto out; - - data_fd = bpf_map__fd(data_map); -- if (CHECK_FAIL(map_fd < 0)) -- return; -+ if (CHECK_FAIL(data_fd < 0)) -+ goto out; - - i = 0; - err = bpf_map_lookup_elem(data_fd, &i, &val); -@@ -805,11 +805,11 @@ static void test_tailcall_bpf2bpf_4(bool noise) - - data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); - if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) -- return; -+ goto out; - - data_fd = bpf_map__fd(data_map); -- if (CHECK_FAIL(map_fd < 0)) -- return; -+ if (CHECK_FAIL(data_fd < 0)) -+ goto out; - - i = 0; - val.noise = noise; -@@ -872,7 +872,7 @@ static void test_tailcall_bpf2bpf_6(void) - ASSERT_EQ(topts.retval, 0, "tailcall retval"); - - data_fd = bpf_map__fd(obj->maps.bss); -- if (!ASSERT_GE(map_fd, 0, "bss map fd")) -+ if (!ASSERT_GE(data_fd, 0, "bss map fd")) - goto out; - - i = 0; -diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh -index dfe3d287f01d2..0d705fdcf3b76 100755 ---- a/tools/testing/selftests/net/pmtu.sh -+++ b/tools/testing/selftests/net/pmtu.sh -@@ -2013,7 +2013,7 @@ run_test() { - case $ret in - 0) - all_skipped=false -- [ $exitcode=$ksft_skip ] && exitcode=0 -+ [ $exitcode -eq $ksft_skip ] && exitcode=0 - ;; - $ksft_skip) - [ $all_skipped = true ] && exitcode=$ksft_skip -diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile -index 321db8850da00..bced422b78f72 100644 ---- a/tools/testing/selftests/netfilter/Makefile -+++ b/tools/testing/selftests/netfilter/Makefile -@@ -6,13 +6,14 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \ - nft_concat_range.sh nft_conntrack_helper.sh \ - nft_queue.sh nft_meta.sh nf_nat_edemux.sh \ - ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ -- conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh -+ conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh \ -+ conntrack_sctp_collision.sh xt_string.sh - - HOSTPKG_CONFIG := pkg-config - - CFLAGS += $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null) - LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) - --TEST_GEN_FILES = nf-queue connect_close audit_logread -+TEST_GEN_FILES = nf-queue connect_close audit_logread sctp_collision - - include ../lib.mk -diff --git a/tools/testing/selftests/netfilter/conntrack_sctp_collision.sh b/tools/testing/selftests/netfilter/conntrack_sctp_collision.sh -new file mode 100755 -index 0000000000000..a924e595cfd8b ---- /dev/null -+++ b/tools/testing/selftests/netfilter/conntrack_sctp_collision.sh -@@ -0,0 +1,89 @@ -+#!/bin/bash -+# SPDX-License-Identifier: GPL-2.0 -+# -+# Testing For SCTP COLLISION SCENARIO as Below: -+# -+# 14:35:47.655279 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT] [init tag: 2017837359] -+# 14:35:48.353250 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT] [init tag: 1187206187] -+# 14:35:48.353275 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT ACK] [init tag: 2017837359] -+# 14:35:48.353283 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [COOKIE ECHO] -+# 14:35:48.353977 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [COOKIE ACK] -+# 14:35:48.855335 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT ACK] [init tag: 164579970] -+# -+# TOPO: SERVER_NS (link0)<--->(link1) ROUTER_NS (link2)<--->(link3) CLIENT_NS -+ -+CLIENT_NS=$(mktemp -u client-XXXXXXXX) -+CLIENT_IP="198.51.200.1" -+CLIENT_PORT=1234 -+ -+SERVER_NS=$(mktemp -u server-XXXXXXXX) -+SERVER_IP="198.51.100.1" -+SERVER_PORT=1234 -+ -+ROUTER_NS=$(mktemp -u router-XXXXXXXX) -+CLIENT_GW="198.51.200.2" -+SERVER_GW="198.51.100.2" -+ -+# setup the topo -+setup() { -+ ip net add $CLIENT_NS -+ ip net add $SERVER_NS -+ ip net add $ROUTER_NS -+ ip -n $SERVER_NS link add link0 type veth peer name link1 netns $ROUTER_NS -+ ip -n $CLIENT_NS link add link3 type veth peer name link2 netns $ROUTER_NS -+ -+ ip -n $SERVER_NS link set link0 up -+ ip -n $SERVER_NS addr add $SERVER_IP/24 dev link0 -+ ip -n $SERVER_NS route add $CLIENT_IP dev link0 via $SERVER_GW -+ -+ ip -n $ROUTER_NS link set link1 up -+ ip -n $ROUTER_NS link set link2 up -+ ip -n $ROUTER_NS addr add $SERVER_GW/24 dev link1 -+ ip -n $ROUTER_NS addr add $CLIENT_GW/24 dev link2 -+ ip net exec $ROUTER_NS sysctl -wq net.ipv4.ip_forward=1 -+ -+ ip -n $CLIENT_NS link set link3 up -+ ip -n $CLIENT_NS addr add $CLIENT_IP/24 dev link3 -+ ip -n $CLIENT_NS route add $SERVER_IP dev link3 via $CLIENT_GW -+ -+ # simulate the delay on OVS upcall by setting up a delay for INIT_ACK with -+ # tc on $SERVER_NS side -+ tc -n $SERVER_NS qdisc add dev link0 root handle 1: htb -+ tc -n $SERVER_NS class add dev link0 parent 1: classid 1:1 htb rate 100mbit -+ tc -n $SERVER_NS filter add dev link0 parent 1: protocol ip u32 match ip protocol 132 \ -+ 0xff match u8 2 0xff at 32 flowid 1:1 -+ tc -n $SERVER_NS qdisc add dev link0 parent 1:1 handle 10: netem delay 1200ms -+ -+ # simulate the ctstate check on OVS nf_conntrack -+ ip net exec $ROUTER_NS iptables -A FORWARD -m state --state INVALID,UNTRACKED -j DROP -+ ip net exec $ROUTER_NS iptables -A INPUT -p sctp -j DROP -+ -+ # use a smaller number for assoc's max_retrans to reproduce the issue -+ modprobe sctp -+ ip net exec $CLIENT_NS sysctl -wq net.sctp.association_max_retrans=3 -+} -+ -+cleanup() { -+ ip net exec $CLIENT_NS pkill sctp_collision 2>&1 >/dev/null -+ ip net exec $SERVER_NS pkill sctp_collision 2>&1 >/dev/null -+ ip net del "$CLIENT_NS" -+ ip net del "$SERVER_NS" -+ ip net del "$ROUTER_NS" -+} -+ -+do_test() { -+ ip net exec $SERVER_NS ./sctp_collision server \ -+ $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT & -+ ip net exec $CLIENT_NS ./sctp_collision client \ -+ $CLIENT_IP $CLIENT_PORT $SERVER_IP $SERVER_PORT -+} -+ -+# NOTE: one way to work around the issue is set a smaller hb_interval -+# ip net exec $CLIENT_NS sysctl -wq net.sctp.hb_interval=3500 -+ -+# run the test case -+trap cleanup EXIT -+setup && \ -+echo "Test for SCTP Collision in nf_conntrack:" && \ -+do_test && echo "PASS!" -+exit $? -diff --git a/tools/testing/selftests/netfilter/sctp_collision.c b/tools/testing/selftests/netfilter/sctp_collision.c -new file mode 100644 -index 0000000000000..21bb1cfd8a856 ---- /dev/null -+++ b/tools/testing/selftests/netfilter/sctp_collision.c -@@ -0,0 +1,99 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+ -+int main(int argc, char *argv[]) -+{ -+ struct sockaddr_in saddr = {}, daddr = {}; -+ int sd, ret, len = sizeof(daddr); -+ struct timeval tv = {25, 0}; -+ char buf[] = "hello"; -+ -+ if (argc != 6 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) { -+ printf("%s \n", -+ argv[0]); -+ return -1; -+ } -+ -+ sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); -+ if (sd < 0) { -+ printf("Failed to create sd\n"); -+ return -1; -+ } -+ -+ saddr.sin_family = AF_INET; -+ saddr.sin_addr.s_addr = inet_addr(argv[2]); -+ saddr.sin_port = htons(atoi(argv[3])); -+ -+ ret = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr)); -+ if (ret < 0) { -+ printf("Failed to bind to address\n"); -+ goto out; -+ } -+ -+ ret = listen(sd, 5); -+ if (ret < 0) { -+ printf("Failed to listen on port\n"); -+ goto out; -+ } -+ -+ daddr.sin_family = AF_INET; -+ daddr.sin_addr.s_addr = inet_addr(argv[4]); -+ daddr.sin_port = htons(atoi(argv[5])); -+ -+ /* make test shorter than 25s */ -+ ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); -+ if (ret < 0) { -+ printf("Failed to setsockopt SO_RCVTIMEO\n"); -+ goto out; -+ } -+ -+ if (!strcmp(argv[1], "server")) { -+ sleep(1); /* wait a bit for client's INIT */ -+ ret = connect(sd, (struct sockaddr *)&daddr, len); -+ if (ret < 0) { -+ printf("Failed to connect to peer\n"); -+ goto out; -+ } -+ ret = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&daddr, &len); -+ if (ret < 0) { -+ printf("Failed to recv msg %d\n", ret); -+ goto out; -+ } -+ ret = sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&daddr, len); -+ if (ret < 0) { -+ printf("Failed to send msg %d\n", ret); -+ goto out; -+ } -+ printf("Server: sent! %d\n", ret); -+ } -+ -+ if (!strcmp(argv[1], "client")) { -+ usleep(300000); /* wait a bit for server's listening */ -+ ret = connect(sd, (struct sockaddr *)&daddr, len); -+ if (ret < 0) { -+ printf("Failed to connect to peer\n"); -+ goto out; -+ } -+ sleep(1); /* wait a bit for server's delayed INIT_ACK to reproduce the issue */ -+ ret = sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&daddr, len); -+ if (ret < 0) { -+ printf("Failed to send msg %d\n", ret); -+ goto out; -+ } -+ ret = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&daddr, &len); -+ if (ret < 0) { -+ printf("Failed to recv msg %d\n", ret); -+ goto out; -+ } -+ printf("Client: rcvd! %d\n", ret); -+ } -+ ret = 0; -+out: -+ close(sd); -+ return ret; -+} -diff --git a/tools/testing/selftests/netfilter/xt_string.sh b/tools/testing/selftests/netfilter/xt_string.sh -new file mode 100755 -index 0000000000000..1802653a47287 ---- /dev/null -+++ b/tools/testing/selftests/netfilter/xt_string.sh -@@ -0,0 +1,128 @@ -+#!/bin/bash -+# SPDX-License-Identifier: GPL-2.0 -+ -+# return code to signal skipped test -+ksft_skip=4 -+rc=0 -+ -+if ! iptables --version >/dev/null 2>&1; then -+ echo "SKIP: Test needs iptables" -+ exit $ksft_skip -+fi -+if ! ip -V >/dev/null 2>&1; then -+ echo "SKIP: Test needs iproute2" -+ exit $ksft_skip -+fi -+if ! nc -h >/dev/null 2>&1; then -+ echo "SKIP: Test needs netcat" -+ exit $ksft_skip -+fi -+ -+pattern="foo bar baz" -+patlen=11 -+hdrlen=$((20 + 8)) # IPv4 + UDP -+ns="ns-$(mktemp -u XXXXXXXX)" -+trap 'ip netns del $ns' EXIT -+ip netns add "$ns" -+ip -net "$ns" link add d0 type dummy -+ip -net "$ns" link set d0 up -+ip -net "$ns" addr add 10.1.2.1/24 dev d0 -+ -+#ip netns exec "$ns" tcpdump -npXi d0 & -+#tcpdump_pid=$! -+#trap 'kill $tcpdump_pid; ip netns del $ns' EXIT -+ -+add_rule() { # (alg, from, to) -+ ip netns exec "$ns" \ -+ iptables -A OUTPUT -o d0 -m string \ -+ --string "$pattern" --algo $1 --from $2 --to $3 -+} -+showrules() { # () -+ ip netns exec "$ns" iptables -v -S OUTPUT | grep '^-A' -+} -+zerorules() { -+ ip netns exec "$ns" iptables -Z OUTPUT -+} -+countrule() { # (pattern) -+ showrules | grep -c -- "$*" -+} -+send() { # (offset) -+ ( for ((i = 0; i < $1 - $hdrlen; i++)); do -+ printf " " -+ done -+ printf "$pattern" -+ ) | ip netns exec "$ns" nc -w 1 -u 10.1.2.2 27374 -+} -+ -+add_rule bm 1000 1500 -+add_rule bm 1400 1600 -+add_rule kmp 1000 1500 -+add_rule kmp 1400 1600 -+ -+zerorules -+send 0 -+send $((1000 - $patlen)) -+if [ $(countrule -c 0 0) -ne 4 ]; then -+ echo "FAIL: rules match data before --from" -+ showrules -+ ((rc--)) -+fi -+ -+zerorules -+send 1000 -+send $((1400 - $patlen)) -+if [ $(countrule -c 2) -ne 2 ]; then -+ echo "FAIL: only two rules should match at low offset" -+ showrules -+ ((rc--)) -+fi -+ -+zerorules -+send $((1500 - $patlen)) -+if [ $(countrule -c 1) -ne 4 ]; then -+ echo "FAIL: all rules should match at end of packet" -+ showrules -+ ((rc--)) -+fi -+ -+zerorules -+send 1495 -+if [ $(countrule -c 1) -ne 1 ]; then -+ echo "FAIL: only kmp with proper --to should match pattern spanning fragments" -+ showrules -+ ((rc--)) -+fi -+ -+zerorules -+send 1500 -+if [ $(countrule -c 1) -ne 2 ]; then -+ echo "FAIL: two rules should match pattern at start of second fragment" -+ showrules -+ ((rc--)) -+fi -+ -+zerorules -+send $((1600 - $patlen)) -+if [ $(countrule -c 1) -ne 2 ]; then -+ echo "FAIL: two rules should match pattern at end of largest --to" -+ showrules -+ ((rc--)) -+fi -+ -+zerorules -+send $((1600 - $patlen + 1)) -+if [ $(countrule -c 1) -ne 0 ]; then -+ echo "FAIL: no rules should match pattern extending largest --to" -+ showrules -+ ((rc--)) -+fi -+ -+zerorules -+send 1600 -+if [ $(countrule -c 1) -ne 0 ]; then -+ echo "FAIL: no rule should match pattern past largest --to" -+ showrules -+ ((rc--)) -+fi -+ -+exit $rc -diff --git a/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c b/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c -index 3fd8e903118f5..3bc46d6151f44 100644 ---- a/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c -+++ b/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c -@@ -62,7 +62,7 @@ static void error_report(struct error *err, const char *test_name) - break; - - case PIDFD_PASS: -- ksft_test_result_pass("%s test: Passed\n"); -+ ksft_test_result_pass("%s test: Passed\n", test_name); - break; - - default: -diff --git a/tools/testing/selftests/pidfd/pidfd_test.c b/tools/testing/selftests/pidfd/pidfd_test.c -index e2dd4ed849846..cf4f3174c83e0 100644 ---- a/tools/testing/selftests/pidfd/pidfd_test.c -+++ b/tools/testing/selftests/pidfd/pidfd_test.c -@@ -380,13 +380,13 @@ static int test_pidfd_send_signal_syscall_support(void) - - static void *test_pidfd_poll_exec_thread(void *priv) - { -- ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n", -+ ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n", - getpid(), syscall(SYS_gettid)); - ksft_print_msg("Child Thread: doing exec of sleep\n"); - - execl("/bin/sleep", "sleep", str(CHILD_THREAD_MIN_WAIT), (char *)NULL); - -- ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", -+ ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n", - getpid(), syscall(SYS_gettid)); - return NULL; - } -@@ -426,7 +426,7 @@ static int child_poll_exec_test(void *args) - { - pthread_t t1; - -- ksft_print_msg("Child (pidfd): starting. pid %d tid %d\n", getpid(), -+ ksft_print_msg("Child (pidfd): starting. pid %d tid %ld\n", getpid(), - syscall(SYS_gettid)); - pthread_create(&t1, NULL, test_pidfd_poll_exec_thread, NULL); - /* -@@ -479,10 +479,10 @@ static void test_pidfd_poll_exec(int use_waitpid) - - static void *test_pidfd_poll_leader_exit_thread(void *priv) - { -- ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n", -+ ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n", - getpid(), syscall(SYS_gettid)); - sleep(CHILD_THREAD_MIN_WAIT); -- ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", getpid(), syscall(SYS_gettid)); -+ ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n", getpid(), syscall(SYS_gettid)); - return NULL; - } - -@@ -491,7 +491,7 @@ static int child_poll_leader_exit_test(void *args) - { - pthread_t t1, t2; - -- ksft_print_msg("Child: starting. pid %d tid %d\n", getpid(), syscall(SYS_gettid)); -+ ksft_print_msg("Child: starting. pid %d tid %ld\n", getpid(), syscall(SYS_gettid)); - pthread_create(&t1, NULL, test_pidfd_poll_leader_exit_thread, NULL); - pthread_create(&t2, NULL, test_pidfd_poll_leader_exit_thread, NULL); - -diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c -index df0d8d8526fc6..4418155a879b9 100644 ---- a/tools/testing/selftests/resctrl/resctrl_tests.c -+++ b/tools/testing/selftests/resctrl/resctrl_tests.c -@@ -228,9 +228,14 @@ int main(int argc, char **argv) - return ksft_exit_skip("Not running as root. Skipping...\n"); - - if (has_ben) { -+ if (argc - ben_ind >= BENCHMARK_ARGS) -+ ksft_exit_fail_msg("Too long benchmark command.\n"); -+ - /* Extract benchmark command from command line. */ - for (i = ben_ind; i < argc; i++) { - benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i]; -+ if (strlen(argv[i]) >= BENCHMARK_ARG_SIZE) -+ ksft_exit_fail_msg("Too long benchmark command argument.\n"); - sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]); - } - benchmark_cmd[ben_count] = NULL; diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.63-64.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.63-64.patch deleted file mode 100644 index d0dc09a80a77..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.63-64.patch +++ /dev/null @@ -1,12540 +0,0 @@ -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 31af352b4762d..4ad60e127e048 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -5671,6 +5671,13 @@ - This feature may be more efficiently disabled - using the csdlock_debug- kernel parameter. - -+ smp.panic_on_ipistall= [KNL] -+ If a csd_lock_timeout extends for more than -+ the specified number of milliseconds, panic the -+ system. By default, let CSD-lock acquisition -+ take as long as they take. Specifying 300,000 -+ for this value provides a 5-minute timeout. -+ - smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices - smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port - smsc-ircc2.ircc_sir= [HW] SIR base I/O port -diff --git a/Makefile b/Makefile -index 7c69293b7e059..97c75ae364cdf 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 63 -+SUBLEVEL = 64 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h -index 58e039a851af0..3c82975d46db3 100644 ---- a/arch/arm/include/asm/exception.h -+++ b/arch/arm/include/asm/exception.h -@@ -10,10 +10,6 @@ - - #include - --#ifdef CONFIG_FUNCTION_GRAPH_TRACER - #define __exception_irq_entry __irq_entry --#else --#define __exception_irq_entry --#endif - - #endif /* __ASM_ARM_EXCEPTION_H */ -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 9ee9e17eb2ca0..ea70eb960565e 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -1304,6 +1304,8 @@ choice - config CPU_BIG_ENDIAN - bool "Build big-endian kernel" - depends on !LD_IS_LLD || LLD_VERSION >= 130000 -+ # https://github.com/llvm/llvm-project/commit/1379b150991f70a5782e9a143c2ba5308da1161c -+ depends on AS_IS_GNU || AS_VERSION >= 150000 - help - Say Y if you plan on running a kernel with a big-endian userspace. - -diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -index 348d9e3a91252..b53d74aee12ad 100644 ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -1186,26 +1186,34 @@ - dma-coherent; - }; - -- usb0: usb@3100000 { -- status = "disabled"; -- compatible = "snps,dwc3"; -- reg = <0x0 0x3100000 0x0 0x10000>; -- interrupts = <0 80 0x4>; /* Level high type */ -- dr_mode = "host"; -- snps,quirk-frame-length-adjustment = <0x20>; -- snps,dis_rxdet_inp3_quirk; -- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -- }; -+ bus: bus { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ compatible = "simple-bus"; -+ ranges; -+ dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; -+ -+ usb0: usb@3100000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x3100000 0x0 0x10000>; -+ interrupts = <0 80 0x4>; /* Level high type */ -+ dr_mode = "host"; -+ snps,quirk-frame-length-adjustment = <0x20>; -+ snps,dis_rxdet_inp3_quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ status = "disabled"; -+ }; - -- usb1: usb@3110000 { -- status = "disabled"; -- compatible = "snps,dwc3"; -- reg = <0x0 0x3110000 0x0 0x10000>; -- interrupts = <0 81 0x4>; /* Level high type */ -- dr_mode = "host"; -- snps,quirk-frame-length-adjustment = <0x20>; -- snps,dis_rxdet_inp3_quirk; -- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ usb1: usb@3110000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x3110000 0x0 0x10000>; -+ interrupts = <0 81 0x4>; /* Level high type */ -+ dr_mode = "host"; -+ snps,quirk-frame-length-adjustment = <0x20>; -+ snps,dis_rxdet_inp3_quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ status = "disabled"; -+ }; - }; - - ccn@4000000 { -diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -index c3492a3831558..43ff8f1f1475c 100644 ---- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -169,7 +169,7 @@ - smem { - compatible = "qcom,smem"; - memory-region = <&smem_region>; -- hwlocks = <&tcsr_mutex 0>; -+ hwlocks = <&tcsr_mutex 3>; - }; - - soc: soc { -@@ -248,7 +248,7 @@ - - tcsr_mutex: hwlock@1905000 { - compatible = "qcom,ipq6018-tcsr-mutex", "qcom,tcsr-mutex"; -- reg = <0x0 0x01905000 0x0 0x1000>; -+ reg = <0x0 0x01905000 0x0 0x20000>; - #hwlock-cells = <1>; - }; - -diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi -index 3f7cf3fdd319f..3d8e5ba51ce0d 100644 ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi -@@ -90,7 +90,7 @@ - reg = <0x0 0x4ab00000 0x0 0x00100000>; - no-map; - -- hwlocks = <&tcsr_mutex 0>; -+ hwlocks = <&tcsr_mutex 3>; - }; - - memory@4ac00000 { -diff --git a/arch/loongarch/include/asm/percpu.h b/arch/loongarch/include/asm/percpu.h -index ad8d88494554a..302f0e33975a2 100644 ---- a/arch/loongarch/include/asm/percpu.h -+++ b/arch/loongarch/include/asm/percpu.h -@@ -28,7 +28,7 @@ static inline void set_my_cpu_offset(unsigned long off) - #define __my_cpu_offset __my_cpu_offset - - #define PERCPU_OP(op, asm_op, c_op) \ --static inline unsigned long __percpu_##op(void *ptr, \ -+static __always_inline unsigned long __percpu_##op(void *ptr, \ - unsigned long val, int size) \ - { \ - unsigned long ret; \ -@@ -59,7 +59,7 @@ PERCPU_OP(and, and, &) - PERCPU_OP(or, or, |) - #undef PERCPU_OP - --static inline unsigned long __percpu_read(void *ptr, int size) -+static __always_inline unsigned long __percpu_read(void *ptr, int size) - { - unsigned long ret; - -@@ -96,7 +96,7 @@ static inline unsigned long __percpu_read(void *ptr, int size) - return ret; - } - --static inline void __percpu_write(void *ptr, unsigned long val, int size) -+static __always_inline void __percpu_write(void *ptr, unsigned long val, int size) - { - switch (size) { - case 1: -@@ -128,8 +128,8 @@ static inline void __percpu_write(void *ptr, unsigned long val, int size) - } - } - --static inline unsigned long __percpu_xchg(void *ptr, unsigned long val, -- int size) -+static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val, -+ int size) - { - switch (size) { - case 1: -diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h -index 7a90070136e82..8e38a86996fc6 100644 ---- a/arch/parisc/include/uapi/asm/pdc.h -+++ b/arch/parisc/include/uapi/asm/pdc.h -@@ -472,6 +472,7 @@ struct pdc_model { /* for PDC_MODEL */ - unsigned long arch_rev; - unsigned long pot_key; - unsigned long curr_key; -+ unsigned long width; /* default of PSW_W bit (1=enabled) */ - }; - - struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */ -diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S -index 0e5ebfe8d9d29..335887673c656 100644 ---- a/arch/parisc/kernel/entry.S -+++ b/arch/parisc/kernel/entry.S -@@ -462,13 +462,13 @@ - * to a CPU TLB 4k PFN (4k => 12 bits to shift) */ - #define PAGE_ADD_SHIFT (PAGE_SHIFT-12) - #define PAGE_ADD_HUGE_SHIFT (REAL_HPAGE_SHIFT-12) -+ #define PFN_START_BIT (63-ASM_PFN_PTE_SHIFT+(63-58)-PAGE_ADD_SHIFT) - - /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ - .macro convert_for_tlb_insert20 pte,tmp - #ifdef CONFIG_HUGETLB_PAGE - copy \pte,\tmp -- extrd,u \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ -- 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte -+ extrd,u \tmp,PFN_START_BIT,PFN_START_BIT+1,\pte - - depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ - (63-58)+PAGE_ADD_SHIFT,\pte -@@ -476,8 +476,7 @@ - depdi _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\ - (63-58)+PAGE_ADD_HUGE_SHIFT,\pte - #else /* Huge pages disabled */ -- extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ -- 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte -+ extrd,u \pte,PFN_START_BIT,PFN_START_BIT+1,\pte - depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ - (63-58)+PAGE_ADD_SHIFT,\pte - #endif -diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S -index fd15fd4bbb61b..5a7d43c0f469c 100644 ---- a/arch/parisc/kernel/head.S -+++ b/arch/parisc/kernel/head.S -@@ -70,9 +70,8 @@ $bss_loop: - stw,ma %arg2,4(%r1) - stw,ma %arg3,4(%r1) - --#if !defined(CONFIG_64BIT) && defined(CONFIG_PA20) -- /* This 32-bit kernel was compiled for PA2.0 CPUs. Check current CPU -- * and halt kernel if we detect a PA1.x CPU. */ -+#if defined(CONFIG_PA20) -+ /* check for 64-bit capable CPU as required by current kernel */ - ldi 32,%r10 - mtctl %r10,%cr11 - .level 2.0 -diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c -index 942aa830e110e..e3c31c771ce91 100644 ---- a/arch/powerpc/perf/core-book3s.c -+++ b/arch/powerpc/perf/core-book3s.c -@@ -1371,8 +1371,7 @@ static void power_pmu_disable(struct pmu *pmu) - /* - * Disable instruction sampling if it was enabled - */ -- if (cpuhw->mmcr.mmcra & MMCRA_SAMPLE_ENABLE) -- val &= ~MMCRA_SAMPLE_ENABLE; -+ val &= ~MMCRA_SAMPLE_ENABLE; - - /* Disable BHRB via mmcra (BHRBRD) for p10 */ - if (ppmu->flags & PPMU_ARCH_31) -@@ -1383,7 +1382,7 @@ static void power_pmu_disable(struct pmu *pmu) - * instruction sampling or BHRB. - */ - if (val != mmcra) { -- mtspr(SPRN_MMCRA, mmcra); -+ mtspr(SPRN_MMCRA, val); - mb(); - isync(); - } -diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c -index 113bdb151f687..40e26e9f318fd 100644 ---- a/arch/powerpc/platforms/powernv/opal-prd.c -+++ b/arch/powerpc/platforms/powernv/opal-prd.c -@@ -24,13 +24,20 @@ - #include - - -+struct opal_prd_msg { -+ union { -+ struct opal_prd_msg_header header; -+ DECLARE_FLEX_ARRAY(u8, data); -+ }; -+}; -+ - /* - * The msg member must be at the end of the struct, as it's followed by the - * message data. - */ - struct opal_prd_msg_queue_item { -- struct list_head list; -- struct opal_prd_msg_header msg; -+ struct list_head list; -+ struct opal_prd_msg msg; - }; - - static struct device_node *prd_node; -@@ -156,7 +163,7 @@ static ssize_t opal_prd_read(struct file *file, char __user *buf, - int rc; - - /* we need at least a header's worth of data */ -- if (count < sizeof(item->msg)) -+ if (count < sizeof(item->msg.header)) - return -EINVAL; - - if (*ppos) -@@ -186,7 +193,7 @@ static ssize_t opal_prd_read(struct file *file, char __user *buf, - return -EINTR; - } - -- size = be16_to_cpu(item->msg.size); -+ size = be16_to_cpu(item->msg.header.size); - if (size > count) { - err = -EINVAL; - goto err_requeue; -@@ -352,7 +359,7 @@ static int opal_prd_msg_notifier(struct notifier_block *nb, - if (!item) - return -ENOMEM; - -- memcpy(&item->msg, msg->params, msg_size); -+ memcpy(&item->msg.data, msg->params, msg_size); - - spin_lock_irqsave(&opal_prd_msg_queue_lock, flags); - list_add_tail(&item->list, &opal_prd_msg_queue); -diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h -index ac70b0fd9a9a3..86048c60f7002 100644 ---- a/arch/riscv/include/asm/page.h -+++ b/arch/riscv/include/asm/page.h -@@ -38,8 +38,8 @@ - #define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) - #endif - /* -- * By default, CONFIG_PAGE_OFFSET value corresponds to SV48 address space so -- * define the PAGE_OFFSET value for SV39. -+ * By default, CONFIG_PAGE_OFFSET value corresponds to SV57 address space so -+ * define the PAGE_OFFSET value for SV48 and SV39. - */ - #define PAGE_OFFSET_L4 _AC(0xffffaf8000000000, UL) - #define PAGE_OFFSET_L3 _AC(0xffffffd800000000, UL) -diff --git a/arch/riscv/kernel/probes/simulate-insn.c b/arch/riscv/kernel/probes/simulate-insn.c -index a20568bd1f1a8..41bf1eb0110dd 100644 ---- a/arch/riscv/kernel/probes/simulate-insn.c -+++ b/arch/riscv/kernel/probes/simulate-insn.c -@@ -24,7 +24,7 @@ static inline bool rv_insn_reg_set_val(struct pt_regs *regs, u32 index, - unsigned long val) - { - if (index == 0) -- return false; -+ return true; - else if (index <= 31) - *((unsigned long *)regs + index) = val; - else -diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c -index 8c3b59f1f9b80..7f534023f4ffe 100644 ---- a/arch/riscv/kernel/smp.c -+++ b/arch/riscv/kernel/smp.c -@@ -58,7 +58,6 @@ int riscv_hartid_to_cpuid(unsigned long hartid) - if (cpuid_to_hartid_map(i) == hartid) - return i; - -- pr_err("Couldn't find cpu id for hartid [%lu]\n", hartid); - return -ENOENT; - } - -diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c -index 20a9f991a6d74..e9090b38f8117 100644 ---- a/arch/riscv/mm/ptdump.c -+++ b/arch/riscv/mm/ptdump.c -@@ -384,6 +384,9 @@ static int __init ptdump_init(void) - - kernel_ptd_info.base_addr = KERN_VIRT_START; - -+ pg_level[1].name = pgtable_l5_enabled ? "P4D" : "PGD"; -+ pg_level[2].name = pgtable_l4_enabled ? "PUD" : "PGD"; -+ - for (i = 0; i < ARRAY_SIZE(pg_level); i++) - for (j = 0; j < ARRAY_SIZE(pte_bits); j++) - pg_level[i].mask |= pte_bits[j].mask; -diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c -index d5ea09d78938b..7bea3be8b8280 100644 ---- a/arch/s390/mm/page-states.c -+++ b/arch/s390/mm/page-states.c -@@ -132,7 +132,7 @@ static void mark_kernel_pud(p4d_t *p4d, unsigned long addr, unsigned long end) - continue; - if (!pud_folded(*pud)) { - page = phys_to_page(pud_val(*pud)); -- for (i = 0; i < 3; i++) -+ for (i = 0; i < 4; i++) - set_bit(PG_arch_1, &page[i].flags); - } - mark_kernel_pmd(pud, addr, next); -@@ -153,7 +153,7 @@ static void mark_kernel_p4d(pgd_t *pgd, unsigned long addr, unsigned long end) - continue; - if (!p4d_folded(*p4d)) { - page = phys_to_page(p4d_val(*p4d)); -- for (i = 0; i < 3; i++) -+ for (i = 0; i < 4; i++) - set_bit(PG_arch_1, &page[i].flags); - } - mark_kernel_pud(p4d, addr, next); -@@ -175,7 +175,7 @@ static void mark_kernel_pgd(void) - continue; - if (!pgd_folded(*pgd)) { - page = phys_to_page(pgd_val(*pgd)); -- for (i = 0; i < 3; i++) -+ for (i = 0; i < 4; i++) - set_bit(PG_arch_1, &page[i].flags); - } - mark_kernel_p4d(pgd, addr, next); -diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c -index 44340a1139e0b..959afa705e95c 100644 ---- a/arch/x86/crypto/sha1_ssse3_glue.c -+++ b/arch/x86/crypto/sha1_ssse3_glue.c -@@ -24,8 +24,17 @@ - #include - #include - #include -+#include - #include - -+static const struct x86_cpu_id module_cpu_ids[] = { -+ X86_MATCH_FEATURE(X86_FEATURE_AVX2, NULL), -+ X86_MATCH_FEATURE(X86_FEATURE_AVX, NULL), -+ X86_MATCH_FEATURE(X86_FEATURE_SSSE3, NULL), -+ {} -+}; -+MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids); -+ - static int sha1_update(struct shash_desc *desc, const u8 *data, - unsigned int len, sha1_block_fn *sha1_xform) - { -@@ -301,6 +310,9 @@ static inline void unregister_sha1_ni(void) { } - - static int __init sha1_ssse3_mod_init(void) - { -+ if (!x86_match_cpu(module_cpu_ids)) -+ return -ENODEV; -+ - if (register_sha1_ssse3()) - goto fail; - -diff --git a/arch/x86/crypto/sha256_ssse3_glue.c b/arch/x86/crypto/sha256_ssse3_glue.c -index 3a5f6be7dbba4..d25235f0ccafc 100644 ---- a/arch/x86/crypto/sha256_ssse3_glue.c -+++ b/arch/x86/crypto/sha256_ssse3_glue.c -@@ -38,11 +38,20 @@ - #include - #include - #include -+#include - #include - - asmlinkage void sha256_transform_ssse3(struct sha256_state *state, - const u8 *data, int blocks); - -+static const struct x86_cpu_id module_cpu_ids[] = { -+ X86_MATCH_FEATURE(X86_FEATURE_AVX2, NULL), -+ X86_MATCH_FEATURE(X86_FEATURE_AVX, NULL), -+ X86_MATCH_FEATURE(X86_FEATURE_SSSE3, NULL), -+ {} -+}; -+MODULE_DEVICE_TABLE(x86cpu, module_cpu_ids); -+ - static int _sha256_update(struct shash_desc *desc, const u8 *data, - unsigned int len, sha256_block_fn *sha256_xform) - { -@@ -366,6 +375,9 @@ static inline void unregister_sha256_ni(void) { } - - static int __init sha256_ssse3_mod_init(void) - { -+ if (!x86_match_cpu(module_cpu_ids)) -+ return -ENODEV; -+ - if (register_sha256_ssse3()) - goto fail; - -diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h -index 016fb500b3a6f..ec955ab2ff034 100644 ---- a/arch/x86/include/asm/msr-index.h -+++ b/arch/x86/include/asm/msr-index.h -@@ -551,6 +551,7 @@ - #define MSR_AMD64_CPUID_FN_1 0xc0011004 - #define MSR_AMD64_LS_CFG 0xc0011020 - #define MSR_AMD64_DC_CFG 0xc0011022 -+#define MSR_AMD64_TW_CFG 0xc0011023 - - #define MSR_AMD64_DE_CFG 0xc0011029 - #define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1 -diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h -index e3bae2b60a0db..ef2844d691735 100644 ---- a/arch/x86/include/asm/numa.h -+++ b/arch/x86/include/asm/numa.h -@@ -12,13 +12,6 @@ - - #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) - --/* -- * Too small node sizes may confuse the VM badly. Usually they -- * result from BIOS bugs. So dont recognize nodes as standalone -- * NUMA entities that have less than this amount of RAM listed: -- */ --#define NODE_MIN_SIZE (4*1024*1024) -- - extern int numa_off; - - /* -diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c -index c393b8773ace6..9e8380bd4fb9f 100644 ---- a/arch/x86/kernel/cpu/hygon.c -+++ b/arch/x86/kernel/cpu/hygon.c -@@ -86,8 +86,12 @@ static void hygon_get_topology(struct cpuinfo_x86 *c) - if (!err) - c->x86_coreid_bits = get_count_order(c->x86_max_cores); - -- /* Socket ID is ApicId[6] for these processors. */ -- c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT; -+ /* -+ * Socket ID is ApicId[6] for the processors with model <= 0x3 -+ * when running on host. -+ */ -+ if (!boot_cpu_has(X86_FEATURE_HYPERVISOR) && c->x86_model <= 0x3) -+ c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT; - - cacheinfo_hygon_init_llc_id(c, cpu); - } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) { -diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c -index 0adf4a437e85f..04cca46fed1e8 100644 ---- a/arch/x86/kvm/hyperv.c -+++ b/arch/x86/kvm/hyperv.c -@@ -705,10 +705,12 @@ static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count, - - stimer_cleanup(stimer); - stimer->count = count; -- if (stimer->count == 0) -- stimer->config.enable = 0; -- else if (stimer->config.auto_enable) -- stimer->config.enable = 1; -+ if (!host) { -+ if (stimer->count == 0) -+ stimer->config.enable = 0; -+ else if (stimer->config.auto_enable) -+ stimer->config.enable = 1; -+ } - - if (stimer->config.enable) - stimer_mark_pending(stimer, false); -diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c -index 7e8dbd54869a6..4dba0a84ba2f3 100644 ---- a/arch/x86/kvm/lapic.c -+++ b/arch/x86/kvm/lapic.c -@@ -2294,22 +2294,22 @@ EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); - void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset) - { - struct kvm_lapic *apic = vcpu->arch.apic; -- u64 val; - - /* -- * ICR is a single 64-bit register when x2APIC is enabled. For legacy -- * xAPIC, ICR writes need to go down the common (slightly slower) path -- * to get the upper half from ICR2. -+ * ICR is a single 64-bit register when x2APIC is enabled, all others -+ * registers hold 32-bit values. For legacy xAPIC, ICR writes need to -+ * go down the common path to get the upper half from ICR2. -+ * -+ * Note, using the write helpers may incur an unnecessary write to the -+ * virtual APIC state, but KVM needs to conditionally modify the value -+ * in certain cases, e.g. to clear the ICR busy bit. The cost of extra -+ * conditional branches is likely a wash relative to the cost of the -+ * maybe-unecessary write, and both are in the noise anyways. - */ -- if (apic_x2apic_mode(apic) && offset == APIC_ICR) { -- val = kvm_lapic_get_reg64(apic, APIC_ICR); -- kvm_apic_send_ipi(apic, (u32)val, (u32)(val >> 32)); -- trace_kvm_apic_write(APIC_ICR, val); -- } else { -- /* TODO: optimize to just emulate side effect w/o one more write */ -- val = kvm_lapic_get_reg(apic, offset); -- kvm_lapic_reg_write(apic, offset, (u32)val); -- } -+ if (apic_x2apic_mode(apic) && offset == APIC_ICR) -+ kvm_x2apic_icr_write(apic, kvm_lapic_get_reg64(apic, APIC_ICR)); -+ else -+ kvm_lapic_reg_write(apic, offset, kvm_lapic_get_reg(apic, offset)); - } - EXPORT_SYMBOL_GPL(kvm_apic_write_nodecode); - -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 4d6baae1ae748..7144e51668136 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -3582,6 +3582,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) - case MSR_AMD64_PATCH_LOADER: - case MSR_AMD64_BU_CFG2: - case MSR_AMD64_DC_CFG: -+ case MSR_AMD64_TW_CFG: - case MSR_F15H_EX_CFG: - break; - -@@ -3982,6 +3983,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) - case MSR_AMD64_BU_CFG2: - case MSR_IA32_PERF_CTL: - case MSR_AMD64_DC_CFG: -+ case MSR_AMD64_TW_CFG: - case MSR_F15H_EX_CFG: - /* - * Intel Sandy Bridge CPUs must support the RAPL (running average power -diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c -index c01c5506fd4ae..aa39d678fe81d 100644 ---- a/arch/x86/mm/numa.c -+++ b/arch/x86/mm/numa.c -@@ -602,13 +602,6 @@ static int __init numa_register_memblks(struct numa_meminfo *mi) - if (start >= end) - continue; - -- /* -- * Don't confuse VM with a node that doesn't have the -- * minimum amount of memory: -- */ -- if (end && (end - start) < NODE_MIN_SIZE) -- continue; -- - alloc_node_data(nid); - } - -diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c -index 9d10b846ccf73..005a36cb21bc4 100644 ---- a/crypto/pcrypt.c -+++ b/crypto/pcrypt.c -@@ -117,6 +117,8 @@ static int pcrypt_aead_encrypt(struct aead_request *req) - err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu); - if (!err) - return -EINPROGRESS; -+ if (err == -EBUSY) -+ return -EAGAIN; - - return err; - } -@@ -164,6 +166,8 @@ static int pcrypt_aead_decrypt(struct aead_request *req) - err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu); - if (!err) - return -EINPROGRESS; -+ if (err == -EBUSY) -+ return -EAGAIN; - - return err; - } -diff --git a/drivers/acpi/acpi_fpdt.c b/drivers/acpi/acpi_fpdt.c -index a2056c4c8cb70..271092f2700a1 100644 ---- a/drivers/acpi/acpi_fpdt.c -+++ b/drivers/acpi/acpi_fpdt.c -@@ -194,12 +194,19 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) - record_header = (void *)subtable_header + offset; - offset += record_header->length; - -+ if (!record_header->length) { -+ pr_err(FW_BUG "Zero-length record found in FPTD.\n"); -+ result = -EINVAL; -+ goto err; -+ } -+ - switch (record_header->type) { - case RECORD_S3_RESUME: - if (subtable_type != SUBTABLE_S3PT) { - pr_err(FW_BUG "Invalid record %d for subtable %s\n", - record_header->type, signature); -- return -EINVAL; -+ result = -EINVAL; -+ goto err; - } - if (record_resume) { - pr_err("Duplicate resume performance record found.\n"); -@@ -208,7 +215,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) - record_resume = (struct resume_performance_record *)record_header; - result = sysfs_create_group(fpdt_kobj, &resume_attr_group); - if (result) -- return result; -+ goto err; - break; - case RECORD_S3_SUSPEND: - if (subtable_type != SUBTABLE_S3PT) { -@@ -223,13 +230,14 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) - record_suspend = (struct suspend_performance_record *)record_header; - result = sysfs_create_group(fpdt_kobj, &suspend_attr_group); - if (result) -- return result; -+ goto err; - break; - case RECORD_BOOT: - if (subtable_type != SUBTABLE_FBPT) { - pr_err(FW_BUG "Invalid %d for subtable %s\n", - record_header->type, signature); -- return -EINVAL; -+ result = -EINVAL; -+ goto err; - } - if (record_boot) { - pr_err("Duplicate boot performance record found.\n"); -@@ -238,7 +246,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) - record_boot = (struct boot_performance_record *)record_header; - result = sysfs_create_group(fpdt_kobj, &boot_attr_group); - if (result) -- return result; -+ goto err; - break; - - default: -@@ -247,6 +255,18 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) - } - } - return 0; -+ -+err: -+ if (record_boot) -+ sysfs_remove_group(fpdt_kobj, &boot_attr_group); -+ -+ if (record_suspend) -+ sysfs_remove_group(fpdt_kobj, &suspend_attr_group); -+ -+ if (record_resume) -+ sysfs_remove_group(fpdt_kobj, &resume_attr_group); -+ -+ return result; - } - - static int __init acpi_init_fpdt(void) -@@ -255,6 +275,7 @@ static int __init acpi_init_fpdt(void) - struct acpi_table_header *header; - struct fpdt_subtable_entry *subtable; - u32 offset = sizeof(*header); -+ int result; - - status = acpi_get_table(ACPI_SIG_FPDT, 0, &header); - -@@ -263,8 +284,8 @@ static int __init acpi_init_fpdt(void) - - fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj); - if (!fpdt_kobj) { -- acpi_put_table(header); -- return -ENOMEM; -+ result = -ENOMEM; -+ goto err_nomem; - } - - while (offset < header->length) { -@@ -272,8 +293,10 @@ static int __init acpi_init_fpdt(void) - switch (subtable->type) { - case SUBTABLE_FBPT: - case SUBTABLE_S3PT: -- fpdt_process_subtable(subtable->address, -+ result = fpdt_process_subtable(subtable->address, - subtable->type); -+ if (result) -+ goto err_subtable; - break; - default: - /* Other types are reserved in ACPI 6.4 spec. */ -@@ -282,6 +305,12 @@ static int __init acpi_init_fpdt(void) - offset += sizeof(*subtable); - } - return 0; -+err_subtable: -+ kobject_put(fpdt_kobj); -+ -+err_nomem: -+ acpi_put_table(header); -+ return result; - } - - fs_initcall(acpi_init_fpdt); -diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c -index 8bb233d2d1e48..77d1f2cb89ef3 100644 ---- a/drivers/acpi/ec.c -+++ b/drivers/acpi/ec.c -@@ -1897,6 +1897,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-dk1xxx"), - }, - }, -+ { -+ /* -+ * HP 250 G7 Notebook PC -+ */ -+ .callback = ec_honor_dsdt_gpe, -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "HP"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "HP 250 G7 Notebook PC"), -+ }, -+ }, - { - /* - * Samsung hardware -diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c -index af6fa801d1ed8..99bab31919e4c 100644 ---- a/drivers/acpi/resource.c -+++ b/drivers/acpi/resource.c -@@ -499,6 +499,18 @@ static const struct dmi_system_id maingear_laptop[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "MG-VCP2-15A3070T"), - } - }, -+ { -+ /* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */ -+ .matches = { -+ DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"), -+ }, -+ }, -+ { -+ /* TongFang GM6XGxX/TUXEDO Stellaris 16 Gen5 AMD */ -+ .matches = { -+ DMI_MATCH(DMI_BOARD_NAME, "GM6XGxX"), -+ }, -+ }, - { - .ident = "MAINGEAR Vector Pro 2 17", - .matches = { -diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c -index 3241486869530..9bba8f280a4d4 100644 ---- a/drivers/atm/iphase.c -+++ b/drivers/atm/iphase.c -@@ -2291,19 +2291,21 @@ static int get_esi(struct atm_dev *dev) - static int reset_sar(struct atm_dev *dev) - { - IADEV *iadev; -- int i, error = 1; -+ int i, error; - unsigned int pci[64]; - - iadev = INPH_IA_DEV(dev); -- for(i=0; i<64; i++) -- if ((error = pci_read_config_dword(iadev->pci, -- i*4, &pci[i])) != PCIBIOS_SUCCESSFUL) -- return error; -+ for (i = 0; i < 64; i++) { -+ error = pci_read_config_dword(iadev->pci, i * 4, &pci[i]); -+ if (error != PCIBIOS_SUCCESSFUL) -+ return error; -+ } - writel(0, iadev->reg+IPHASE5575_EXT_RESET); -- for(i=0; i<64; i++) -- if ((error = pci_write_config_dword(iadev->pci, -- i*4, pci[i])) != PCIBIOS_SUCCESSFUL) -- return error; -+ for (i = 0; i < 64; i++) { -+ error = pci_write_config_dword(iadev->pci, i * 4, pci[i]); -+ if (error != PCIBIOS_SUCCESSFUL) -+ return error; -+ } - udelay(5); - return 0; - } -diff --git a/drivers/base/dd.c b/drivers/base/dd.c -index 380a53b6aee81..dbbe2cebb8917 100644 ---- a/drivers/base/dd.c -+++ b/drivers/base/dd.c -@@ -1262,8 +1262,8 @@ static void __device_release_driver(struct device *dev, struct device *parent) - if (dev->bus && dev->bus->dma_cleanup) - dev->bus->dma_cleanup(dev); - -- device_links_driver_cleanup(dev); - device_unbind_cleanup(dev); -+ device_links_driver_cleanup(dev); - - klist_remove(&dev->p->knode_driver); - device_pm_check_callbacks(dev); -diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c -index 8031007b4887d..cf3fa998093de 100644 ---- a/drivers/base/regmap/regcache.c -+++ b/drivers/base/regmap/regcache.c -@@ -331,6 +331,11 @@ static int regcache_default_sync(struct regmap *map, unsigned int min, - return 0; - } - -+static int rbtree_all(const void *key, const struct rb_node *node) -+{ -+ return 0; -+} -+ - /** - * regcache_sync - Sync the register cache with the hardware. - * -@@ -348,6 +353,7 @@ int regcache_sync(struct regmap *map) - unsigned int i; - const char *name; - bool bypass; -+ struct rb_node *node; - - if (WARN_ON(map->cache_type == REGCACHE_NONE)) - return -EINVAL; -@@ -392,6 +398,30 @@ out: - map->async = false; - map->cache_bypass = bypass; - map->no_sync_defaults = false; -+ -+ /* -+ * If we did any paging with cache bypassed and a cached -+ * paging register then the register and cache state might -+ * have gone out of sync, force writes of all the paging -+ * registers. -+ */ -+ rb_for_each(node, 0, &map->range_tree, rbtree_all) { -+ struct regmap_range_node *this = -+ 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) -+ continue; -+ -+ ret = _regmap_write(map, this->selector_reg, i); -+ if (ret != 0) { -+ dev_err(map->dev, "Failed to write %x = %x: %d\n", -+ this->selector_reg, i, ret); -+ break; -+ } -+ } -+ - map->unlock(map->lock_arg); - - regmap_async_complete(map); -diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c -index a7697027ce43b..efa5535a8e1d8 100644 ---- a/drivers/block/virtio_blk.c -+++ b/drivers/block/virtio_blk.c -@@ -900,6 +900,7 @@ static int virtblk_probe(struct virtio_device *vdev) - u16 min_io_size; - u8 physical_block_exp, alignment_offset; - unsigned int queue_depth; -+ size_t max_dma_size; - - if (!vdev->config->get) { - dev_err(&vdev->dev, "%s failure: config access disabled\n", -@@ -998,7 +999,8 @@ static int virtblk_probe(struct virtio_device *vdev) - /* No real sector limit. */ - blk_queue_max_hw_sectors(q, -1U); - -- max_size = virtio_max_dma_size(vdev); -+ max_dma_size = virtio_max_dma_size(vdev); -+ max_size = max_dma_size > U32_MAX ? U32_MAX : max_dma_size; - - /* Host can optionally specify maximum segment size and number of - * segments. */ -diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index 96d4f48e36011..954f7f3b5cc30 100644 ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -532,6 +532,18 @@ static const struct usb_device_id blacklist_table[] = { - { USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK | - BTUSB_WIDEBAND_SPEECH }, - -+ /* Realtek 8852BE Bluetooth devices */ -+ { USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ { USB_DEVICE(0x0bda, 0xb85b), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK | -+ BTUSB_WIDEBAND_SPEECH }, -+ - /* Realtek Bluetooth devices */ - { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), - .driver_info = BTUSB_REALTEK }, -@@ -2638,6 +2650,9 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, - goto err_free_wc; - } - -+ if (data->evt_skb == NULL) -+ goto err_free_wc; -+ - /* Parse and handle the return WMT event */ - wmt_evt = (struct btmtk_hci_wmt_evt *)data->evt_skb->data; - if (wmt_evt->whdr.op != hdr->op) { -diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c -index cde62a11f5736..4c5c7a8f41d08 100644 ---- a/drivers/clk/qcom/gcc-ipq6018.c -+++ b/drivers/clk/qcom/gcc-ipq6018.c -@@ -75,7 +75,6 @@ static struct clk_fixed_factor gpll0_out_main_div2 = { - &gpll0_main.clkr.hw }, - .num_parents = 1, - .ops = &clk_fixed_factor_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -89,7 +88,6 @@ static struct clk_alpha_pll_postdiv gpll0 = { - &gpll0_main.clkr.hw }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -164,7 +162,6 @@ static struct clk_alpha_pll_postdiv gpll6 = { - &gpll6_main.clkr.hw }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -195,7 +192,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { - &gpll4_main.clkr.hw }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -246,7 +242,6 @@ static struct clk_alpha_pll_postdiv gpll2 = { - &gpll2_main.clkr.hw }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -277,7 +272,6 @@ static struct clk_alpha_pll_postdiv nss_crypto_pll = { - &nss_crypto_pll_main.clkr.hw }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c -index 42d185fe19c8c..b2e83b38976e5 100644 ---- a/drivers/clk/qcom/gcc-ipq8074.c -+++ b/drivers/clk/qcom/gcc-ipq8074.c -@@ -419,7 +419,6 @@ static struct clk_fixed_factor gpll0_out_main_div2 = { - }, - .num_parents = 1, - .ops = &clk_fixed_factor_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -466,7 +465,6 @@ static struct clk_alpha_pll_postdiv gpll2 = { - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -499,7 +497,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -533,7 +530,6 @@ static struct clk_alpha_pll_postdiv gpll6 = { - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -547,7 +543,6 @@ static struct clk_fixed_factor gpll6_out_main_div2 = { - }, - .num_parents = 1, - .ops = &clk_fixed_factor_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -@@ -612,7 +607,6 @@ static struct clk_alpha_pll_postdiv nss_crypto_pll = { - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ro_ops, -- .flags = CLK_SET_RATE_PARENT, - }, - }; - -diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h -index 75234e0783e1c..83fe4eb3133cb 100644 ---- a/drivers/clk/socfpga/stratix10-clk.h -+++ b/drivers/clk/socfpga/stratix10-clk.h -@@ -7,8 +7,10 @@ - #define __STRATIX10_CLK_H - - struct stratix10_clock_data { -- struct clk_hw_onecell_data clk_data; - void __iomem *base; -+ -+ /* Must be last */ -+ struct clk_hw_onecell_data clk_data; - }; - - struct stratix10_pll_clock { -diff --git a/drivers/clk/visconti/pll.h b/drivers/clk/visconti/pll.h -index 16dae35ab3701..c4bd40676da4b 100644 ---- a/drivers/clk/visconti/pll.h -+++ b/drivers/clk/visconti/pll.h -@@ -15,9 +15,10 @@ - - struct visconti_pll_provider { - void __iomem *reg_base; -- struct regmap *regmap; -- struct clk_hw_onecell_data clk_data; - struct device_node *node; -+ -+ /* Must be last */ -+ struct clk_hw_onecell_data clk_data; - }; - - #define VISCONTI_PLL_RATE(_rate, _dacen, _dsmen, \ -diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c -index 27af17c995900..2a90c92a9182a 100644 ---- a/drivers/clocksource/timer-atmel-tcb.c -+++ b/drivers/clocksource/timer-atmel-tcb.c -@@ -315,6 +315,7 @@ static void __init tcb_setup_dual_chan(struct atmel_tc *tc, int mck_divisor_idx) - writel(mck_divisor_idx /* likely divide-by-8 */ - | ATMEL_TC_WAVE - | ATMEL_TC_WAVESEL_UP /* free-run */ -+ | ATMEL_TC_ASWTRG_SET /* TIOA0 rises at software trigger */ - | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ - | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ - tcaddr + ATMEL_TC_REG(0, CMR)); -diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c -index 7b2c70f2f353b..fabff69e52e58 100644 ---- a/drivers/clocksource/timer-imx-gpt.c -+++ b/drivers/clocksource/timer-imx-gpt.c -@@ -454,12 +454,16 @@ static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type t - return -ENOMEM; - - imxtm->base = of_iomap(np, 0); -- if (!imxtm->base) -- return -ENXIO; -+ if (!imxtm->base) { -+ ret = -ENXIO; -+ goto err_kfree; -+ } - - imxtm->irq = irq_of_parse_and_map(np, 0); -- if (imxtm->irq <= 0) -- return -EINVAL; -+ if (imxtm->irq <= 0) { -+ ret = -EINVAL; -+ goto err_kfree; -+ } - - imxtm->clk_ipg = of_clk_get_by_name(np, "ipg"); - -@@ -472,11 +476,15 @@ static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type t - - ret = _mxc_timer_init(imxtm); - if (ret) -- return ret; -+ goto err_kfree; - - initialized = 1; - - return 0; -+ -+err_kfree: -+ kfree(imxtm); -+ return ret; - } - - static int __init imx1_timer_init_dt(struct device_node *np) -diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c -index 1570d6f3e75d3..6e57df7a2249f 100644 ---- a/drivers/cpufreq/cpufreq_stats.c -+++ b/drivers/cpufreq/cpufreq_stats.c -@@ -131,25 +131,25 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) - len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n"); - len += scnprintf(buf + len, PAGE_SIZE - len, " : "); - for (i = 0; i < stats->state_num; i++) { -- if (len >= PAGE_SIZE) -+ if (len >= PAGE_SIZE - 1) - break; - len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ", - stats->freq_table[i]); - } -- if (len >= PAGE_SIZE) -- return PAGE_SIZE; -+ if (len >= PAGE_SIZE - 1) -+ return PAGE_SIZE - 1; - - len += scnprintf(buf + len, PAGE_SIZE - len, "\n"); - - for (i = 0; i < stats->state_num; i++) { -- if (len >= PAGE_SIZE) -+ if (len >= PAGE_SIZE - 1) - break; - - len += scnprintf(buf + len, PAGE_SIZE - len, "%9u: ", - stats->freq_table[i]); - - for (j = 0; j < stats->state_num; j++) { -- if (len >= PAGE_SIZE) -+ if (len >= PAGE_SIZE - 1) - break; - - if (pending) -@@ -159,12 +159,12 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) - - len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ", count); - } -- if (len >= PAGE_SIZE) -+ if (len >= PAGE_SIZE - 1) - break; - len += scnprintf(buf + len, PAGE_SIZE - len, "\n"); - } - -- if (len >= PAGE_SIZE) { -+ if (len >= PAGE_SIZE - 1) { - pr_warn_once("cpufreq transition table exceeds PAGE_SIZE. Disabling\n"); - return -EFBIG; - } -diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c -index a4a3895c74181..f9acf7ecc41be 100644 ---- a/drivers/crypto/hisilicon/qm.c -+++ b/drivers/crypto/hisilicon/qm.c -@@ -841,6 +841,8 @@ static void qm_poll_req_cb(struct hisi_qp *qp) - qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, - qp->qp_status.cq_head, 0); - atomic_dec(&qp->qp_status.used); -+ -+ cond_resched(); - } - - /* set c_flag */ -diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c -index 07b184382707e..dd610556a3afa 100644 ---- a/drivers/cxl/acpi.c -+++ b/drivers/cxl/acpi.c -@@ -219,7 +219,6 @@ static int add_host_bridge_uport(struct device *match, void *arg) - port = devm_cxl_add_port(host, match, dport->component_reg_phys, dport); - if (IS_ERR(port)) - return PTR_ERR(port); -- dev_dbg(host, "%s: add: %s\n", dev_name(match), dev_name(&port->dev)); - - return 0; - } -@@ -465,7 +464,6 @@ static int cxl_acpi_probe(struct platform_device *pdev) - root_port = devm_cxl_add_port(host, host, CXL_RESOURCE_NONE, NULL); - if (IS_ERR(root_port)) - return PTR_ERR(root_port); -- dev_dbg(host, "add: %s\n", dev_name(&root_port->dev)); - - rc = bus_for_each_dev(adev->dev.bus, NULL, root_port, - add_host_bridge_dport); -diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h -index 1d8f87be283fb..cbee2340f1bce 100644 ---- a/drivers/cxl/core/core.h -+++ b/drivers/cxl/core/core.h -@@ -56,17 +56,6 @@ resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled); - resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled); - extern struct rw_semaphore cxl_dpa_rwsem; - --bool is_switch_decoder(struct device *dev); --struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev); --static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port, -- struct cxl_memdev *cxlmd) --{ -- if (!port) -- return NULL; -- -- return xa_load(&port->endpoints, (unsigned long)&cxlmd->dev); --} -- - int cxl_memdev_init(void); - void cxl_memdev_exit(void); - void cxl_mbox_init(void); -diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c -index 5aa0726aafe6f..8c1db4e1b816d 100644 ---- a/drivers/cxl/core/hdm.c -+++ b/drivers/cxl/core/hdm.c -@@ -276,7 +276,7 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, - return 0; - } - --static int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, -+int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, - resource_size_t base, resource_size_t len, - resource_size_t skipped) - { -@@ -292,6 +292,7 @@ static int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, - - return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled); - } -+EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, CXL); - - resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled) - { -diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c -index e7556864ea808..bd41424319807 100644 ---- a/drivers/cxl/core/port.c -+++ b/drivers/cxl/core/port.c -@@ -455,6 +455,7 @@ bool is_switch_decoder(struct device *dev) - { - return is_root_decoder(dev) || dev->type == &cxl_decoder_switch_type; - } -+EXPORT_SYMBOL_NS_GPL(is_switch_decoder, CXL); - - struct cxl_decoder *to_cxl_decoder(struct device *dev) - { -@@ -482,6 +483,7 @@ struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev) - return NULL; - return container_of(dev, struct cxl_switch_decoder, cxld.dev); - } -+EXPORT_SYMBOL_NS_GPL(to_cxl_switch_decoder, CXL); - - static void cxl_ep_release(struct cxl_ep *ep) - { -@@ -655,16 +657,10 @@ err: - return ERR_PTR(rc); - } - --/** -- * devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy -- * @host: host device for devm operations -- * @uport: "physical" device implementing this upstream port -- * @component_reg_phys: (optional) for configurable cxl_port instances -- * @parent_dport: next hop up in the CXL memory decode hierarchy -- */ --struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport, -- resource_size_t component_reg_phys, -- struct cxl_dport *parent_dport) -+static struct cxl_port *__devm_cxl_add_port(struct device *host, -+ struct device *uport, -+ resource_size_t component_reg_phys, -+ struct cxl_dport *parent_dport) - { - struct cxl_port *port; - struct device *dev; -@@ -702,6 +698,40 @@ err: - put_device(dev); - return ERR_PTR(rc); - } -+ -+/** -+ * devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy -+ * @host: host device for devm operations -+ * @uport: "physical" device implementing this upstream port -+ * @component_reg_phys: (optional) for configurable cxl_port instances -+ * @parent_dport: next hop up in the CXL memory decode hierarchy -+ */ -+struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport, -+ resource_size_t component_reg_phys, -+ struct cxl_dport *parent_dport) -+{ -+ struct cxl_port *port, *parent_port; -+ -+ port = __devm_cxl_add_port(host, uport, component_reg_phys, -+ parent_dport); -+ -+ parent_port = parent_dport ? parent_dport->port : NULL; -+ if (IS_ERR(port)) { -+ dev_dbg(uport, "Failed to add%s%s%s: %ld\n", -+ parent_port ? " port to " : "", -+ parent_port ? dev_name(&parent_port->dev) : "", -+ parent_port ? "" : " root port", -+ PTR_ERR(port)); -+ } else { -+ dev_dbg(uport, "%s added%s%s%s\n", -+ dev_name(&port->dev), -+ parent_port ? " to " : "", -+ parent_port ? dev_name(&parent_port->dev) : "", -+ parent_port ? "" : " (root port)"); -+ } -+ -+ return port; -+} - EXPORT_SYMBOL_NS_GPL(devm_cxl_add_port, CXL); - - struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port) -@@ -1122,47 +1152,6 @@ static void reap_dports(struct cxl_port *port) - } - } - --int devm_cxl_add_endpoint(struct cxl_memdev *cxlmd, -- struct cxl_dport *parent_dport) --{ -- struct cxl_port *parent_port = parent_dport->port; -- struct cxl_dev_state *cxlds = cxlmd->cxlds; -- struct cxl_port *endpoint, *iter, *down; -- int rc; -- -- /* -- * Now that the path to the root is established record all the -- * intervening ports in the chain. -- */ -- for (iter = parent_port, down = NULL; !is_cxl_root(iter); -- down = iter, iter = to_cxl_port(iter->dev.parent)) { -- struct cxl_ep *ep; -- -- ep = cxl_ep_load(iter, cxlmd); -- ep->next = down; -- } -- -- endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev, -- cxlds->component_reg_phys, parent_dport); -- if (IS_ERR(endpoint)) -- return PTR_ERR(endpoint); -- -- dev_dbg(&cxlmd->dev, "add: %s\n", dev_name(&endpoint->dev)); -- -- rc = cxl_endpoint_autoremove(cxlmd, endpoint); -- if (rc) -- return rc; -- -- if (!endpoint->dev.driver) { -- dev_err(&cxlmd->dev, "%s failed probe\n", -- dev_name(&endpoint->dev)); -- return -ENXIO; -- } -- -- return 0; --} --EXPORT_SYMBOL_NS_GPL(devm_cxl_add_endpoint, CXL); -- - static void cxl_detach_ep(void *data) - { - struct cxl_memdev *cxlmd = data; -diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c -index 9709bbf773b72..ebc1b028555ca 100644 ---- a/drivers/cxl/core/region.c -+++ b/drivers/cxl/core/region.c -@@ -1012,7 +1012,14 @@ static int cxl_port_setup_targets(struct cxl_port *port, - } - - if (is_cxl_root(parent_port)) { -- parent_ig = cxlrd->cxlsd.cxld.interleave_granularity; -+ /* -+ * Root decoder IG is always set to value in CFMWS which -+ * may be different than this region's IG. We can use the -+ * region's IG here since interleave_granularity_store() -+ * does not allow interleaved host-bridges with -+ * root IG != region IG. -+ */ -+ parent_ig = p->interleave_granularity; - parent_iw = cxlrd->cxlsd.cxld.interleave_ways; - /* - * For purposes of address bit routing, use power-of-2 math for -@@ -1181,29 +1188,13 @@ static int cxl_region_setup_targets(struct cxl_region *cxlr) - return 0; - } - --static int cxl_region_attach(struct cxl_region *cxlr, -- struct cxl_endpoint_decoder *cxled, int pos) -+static int cxl_region_validate_position(struct cxl_region *cxlr, -+ struct cxl_endpoint_decoder *cxled, -+ int pos) - { -- struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); - struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); -- struct cxl_port *ep_port, *root_port, *iter; - struct cxl_region_params *p = &cxlr->params; -- struct cxl_dport *dport; -- int i, rc = -ENXIO; -- -- if (cxled->mode == CXL_DECODER_DEAD) { -- dev_dbg(&cxlr->dev, "%s dead\n", dev_name(&cxled->cxld.dev)); -- return -ENODEV; -- } -- -- /* all full of members, or interleave config not established? */ -- if (p->state > CXL_CONFIG_INTERLEAVE_ACTIVE) { -- dev_dbg(&cxlr->dev, "region already active\n"); -- return -EBUSY; -- } else if (p->state < CXL_CONFIG_INTERLEAVE_ACTIVE) { -- dev_dbg(&cxlr->dev, "interleave config missing\n"); -- return -ENXIO; -- } -+ int i; - - if (pos < 0 || pos >= p->interleave_ways) { - dev_dbg(&cxlr->dev, "position %d out of range %d\n", pos, -@@ -1242,6 +1233,77 @@ static int cxl_region_attach(struct cxl_region *cxlr, - } - } - -+ return 0; -+} -+ -+static int cxl_region_attach_position(struct cxl_region *cxlr, -+ struct cxl_root_decoder *cxlrd, -+ struct cxl_endpoint_decoder *cxled, -+ const struct cxl_dport *dport, int pos) -+{ -+ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); -+ struct cxl_port *iter; -+ int rc; -+ -+ if (cxlrd->calc_hb(cxlrd, pos) != dport) { -+ dev_dbg(&cxlr->dev, "%s:%s invalid target position for %s\n", -+ dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), -+ dev_name(&cxlrd->cxlsd.cxld.dev)); -+ return -ENXIO; -+ } -+ -+ for (iter = cxled_to_port(cxled); !is_cxl_root(iter); -+ iter = to_cxl_port(iter->dev.parent)) { -+ rc = cxl_port_attach_region(iter, cxlr, cxled, pos); -+ if (rc) -+ goto err; -+ } -+ -+ return 0; -+ -+err: -+ for (iter = cxled_to_port(cxled); !is_cxl_root(iter); -+ iter = to_cxl_port(iter->dev.parent)) -+ cxl_port_detach_region(iter, cxlr, cxled); -+ return rc; -+} -+ -+static int cxl_region_attach(struct cxl_region *cxlr, -+ struct cxl_endpoint_decoder *cxled, int pos) -+{ -+ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); -+ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); -+ struct cxl_region_params *p = &cxlr->params; -+ struct cxl_port *ep_port, *root_port; -+ struct cxl_dport *dport; -+ int rc = -ENXIO; -+ -+ if (cxled->mode != cxlr->mode) { -+ dev_dbg(&cxlr->dev, "%s region mode: %d mismatch: %d\n", -+ dev_name(&cxled->cxld.dev), cxlr->mode, cxled->mode); -+ return -EINVAL; -+ } -+ -+ if (cxled->mode == CXL_DECODER_DEAD) { -+ dev_dbg(&cxlr->dev, "%s dead\n", dev_name(&cxled->cxld.dev)); -+ return -ENODEV; -+ } -+ -+ /* all full of members, or interleave config not established? */ -+ if (p->state > CXL_CONFIG_INTERLEAVE_ACTIVE) { -+ dev_dbg(&cxlr->dev, "region already active\n"); -+ return -EBUSY; -+ } else if (p->state < CXL_CONFIG_INTERLEAVE_ACTIVE) { -+ dev_dbg(&cxlr->dev, "interleave config missing\n"); -+ return -ENXIO; -+ } -+ -+ if (p->nr_targets >= p->interleave_ways) { -+ dev_dbg(&cxlr->dev, "region already has %d endpoints\n", -+ p->nr_targets); -+ return -EINVAL; -+ } -+ - ep_port = cxled_to_port(cxled); - root_port = cxlrd_to_port(cxlrd); - dport = cxl_find_dport_by_dev(root_port, ep_port->host_bridge); -@@ -1252,13 +1314,6 @@ static int cxl_region_attach(struct cxl_region *cxlr, - return -ENXIO; - } - -- if (cxlrd->calc_hb(cxlrd, pos) != dport) { -- dev_dbg(&cxlr->dev, "%s:%s invalid target position for %s\n", -- dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), -- dev_name(&cxlrd->cxlsd.cxld.dev)); -- return -ENXIO; -- } -- - if (cxled->cxld.target_type != cxlr->type) { - dev_dbg(&cxlr->dev, "%s:%s type mismatch: %d vs %d\n", - dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), -@@ -1282,12 +1337,13 @@ static int cxl_region_attach(struct cxl_region *cxlr, - return -EINVAL; - } - -- for (iter = ep_port; !is_cxl_root(iter); -- iter = to_cxl_port(iter->dev.parent)) { -- rc = cxl_port_attach_region(iter, cxlr, cxled, pos); -- if (rc) -- goto err; -- } -+ rc = cxl_region_validate_position(cxlr, cxled, pos); -+ if (rc) -+ return rc; -+ -+ rc = cxl_region_attach_position(cxlr, cxlrd, cxled, dport, pos); -+ if (rc) -+ return rc; - - p->targets[pos] = cxled; - cxled->pos = pos; -@@ -1296,7 +1352,7 @@ static int cxl_region_attach(struct cxl_region *cxlr, - if (p->nr_targets == p->interleave_ways) { - rc = cxl_region_setup_targets(cxlr); - if (rc) -- goto err_decrement; -+ return rc; - p->state = CXL_CONFIG_ACTIVE; - } - -@@ -1308,14 +1364,6 @@ static int cxl_region_attach(struct cxl_region *cxlr, - }; - - return 0; -- --err_decrement: -- p->nr_targets--; --err: -- for (iter = ep_port; !is_cxl_root(iter); -- iter = to_cxl_port(iter->dev.parent)) -- cxl_port_detach_region(iter, cxlr, cxled); -- return rc; - } - - static int cxl_region_detach(struct cxl_endpoint_decoder *cxled) -diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h -index ac75554b5d763..7750ccb7652db 100644 ---- a/drivers/cxl/cxl.h -+++ b/drivers/cxl/cxl.h -@@ -562,8 +562,6 @@ struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port); - struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport, - resource_size_t component_reg_phys, - struct cxl_dport *parent_dport); --int devm_cxl_add_endpoint(struct cxl_memdev *cxlmd, -- struct cxl_dport *parent_dport); - struct cxl_port *find_cxl_root(struct device *dev); - int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd); - int cxl_bus_rescan(void); -@@ -577,8 +575,10 @@ struct cxl_dport *devm_cxl_add_dport(struct cxl_port *port, - - struct cxl_decoder *to_cxl_decoder(struct device *dev); - struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev); -+struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev); - struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev); - bool is_root_decoder(struct device *dev); -+bool is_switch_decoder(struct device *dev); - bool is_endpoint_decoder(struct device *dev); - struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port, - unsigned int nr_targets); -diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h -index 88e3a8e54b6a4..b58a5b782e5dc 100644 ---- a/drivers/cxl/cxlmem.h -+++ b/drivers/cxl/cxlmem.h -@@ -75,6 +75,18 @@ static inline bool is_cxl_endpoint(struct cxl_port *port) - } - - struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds); -+int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, -+ resource_size_t base, resource_size_t len, -+ resource_size_t skipped); -+ -+static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port, -+ struct cxl_memdev *cxlmd) -+{ -+ if (!port) -+ return NULL; -+ -+ return xa_load(&port->endpoints, (unsigned long)&cxlmd->dev); -+} - - /** - * struct cxl_mbox_cmd - A command to be submitted to hardware. -diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c -index 64ccf053d32c3..80263d12a8541 100644 ---- a/drivers/cxl/mem.c -+++ b/drivers/cxl/mem.c -@@ -45,6 +45,44 @@ static int cxl_mem_dpa_show(struct seq_file *file, void *data) - return 0; - } - -+static int devm_cxl_add_endpoint(struct cxl_memdev *cxlmd, -+ struct cxl_dport *parent_dport) -+{ -+ struct cxl_port *parent_port = parent_dport->port; -+ struct cxl_dev_state *cxlds = cxlmd->cxlds; -+ struct cxl_port *endpoint, *iter, *down; -+ int rc; -+ -+ /* -+ * Now that the path to the root is established record all the -+ * intervening ports in the chain. -+ */ -+ for (iter = parent_port, down = NULL; !is_cxl_root(iter); -+ down = iter, iter = to_cxl_port(iter->dev.parent)) { -+ struct cxl_ep *ep; -+ -+ ep = cxl_ep_load(iter, cxlmd); -+ ep->next = down; -+ } -+ -+ endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev, -+ cxlds->component_reg_phys, parent_dport); -+ if (IS_ERR(endpoint)) -+ return PTR_ERR(endpoint); -+ -+ rc = cxl_endpoint_autoremove(cxlmd, endpoint); -+ if (rc) -+ return rc; -+ -+ if (!endpoint->dev.driver) { -+ dev_err(&cxlmd->dev, "%s failed probe\n", -+ dev_name(&endpoint->dev)); -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+ - static int cxl_mem_probe(struct device *dev) - { - struct cxl_memdev *cxlmd = to_cxl_memdev(dev); -diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c -index 4e9bab61f4663..65ef1f5ca6b89 100644 ---- a/drivers/dma/stm32-mdma.c -+++ b/drivers/dma/stm32-mdma.c -@@ -490,7 +490,7 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, - src_maxburst = chan->dma_config.src_maxburst; - dst_maxburst = chan->dma_config.dst_maxburst; - -- ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)); -+ ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; - ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); - ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); - -@@ -966,7 +966,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, dma_addr_t src, - if (!desc) - return NULL; - -- ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)); -+ ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; - ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); - ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); - cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); -diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c -index 51eb85354c058..58f1a86065dc9 100644 ---- a/drivers/firmware/qcom_scm.c -+++ b/drivers/firmware/qcom_scm.c -@@ -164,6 +164,12 @@ static enum qcom_scm_convention __get_convention(void) - if (likely(qcom_scm_convention != SMC_CONVENTION_UNKNOWN)) - return qcom_scm_convention; - -+ /* -+ * Per the "SMC calling convention specification", the 64-bit calling -+ * convention can only be used when the client is 64-bit, otherwise -+ * system will encounter the undefined behaviour. -+ */ -+#if IS_ENABLED(CONFIG_ARM64) - /* - * Device isn't required as there is only one argument - no device - * needed to dma_map_single to secure world -@@ -184,6 +190,7 @@ static enum qcom_scm_convention __get_convention(void) - forced = true; - goto found; - } -+#endif - - probed_convention = SMC_CONVENTION_ARM_32; - ret = __scm_smc_call(NULL, &desc, probed_convention, &res, true); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c -index 30c28a69e847d..e4ad2bd8d8110 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c -@@ -29,6 +29,7 @@ - #include "amdgpu.h" - #include "atom.h" - -+#include - #include - #include - #include -@@ -289,6 +290,10 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) - if (adev->flags & AMD_IS_APU) - return false; - -+ /* ATRM is for on-platform devices only */ -+ if (dev_is_removable(&adev->pdev->dev)) -+ return false; -+ - while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { - dhandle = ACPI_HANDLE(&pdev->dev); - if (!dhandle) -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c -index 252a876b07258..fdc302aa59e7b 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c -@@ -179,6 +179,7 @@ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id, - } - - rcu_read_unlock(); -+ *result = NULL; - return -ENOENT; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -index 4624160315648..ced4e7e8f98b5 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -@@ -1391,7 +1391,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) - if (r == -ENOMEM) - DRM_ERROR("Not enough memory for command submission!\n"); - else if (r != -ERESTARTSYS && r != -EAGAIN) -- DRM_ERROR("Failed to process the buffer list %d!\n", r); -+ DRM_DEBUG("Failed to process the buffer list %d!\n", r); - goto error_fini; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -index de61a85c4b022..fd796574f87a5 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -@@ -589,6 +589,9 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, - ssize_t result = 0; - int r; - -+ if (!adev->smc_rreg) -+ return -EPERM; -+ - if (size & 0x3 || *pos & 0x3) - return -EINVAL; - -@@ -645,6 +648,9 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * - ssize_t result = 0; - int r; - -+ if (!adev->smc_wreg) -+ return -EPERM; -+ - if (size & 0x3 || *pos & 0x3) - return -EINVAL; - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index 92fa2faf63e41..8a1b84aaaf717 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2105,7 +2106,6 @@ out: - */ - static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) - { -- struct drm_device *dev = adev_to_drm(adev); - struct pci_dev *parent; - int i, r; - -@@ -2175,7 +2175,7 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) - (amdgpu_is_atpx_hybrid() || - amdgpu_has_atpx_dgpu_power_cntl()) && - ((adev->flags & AMD_IS_APU) == 0) && -- !pci_is_thunderbolt_attached(to_pci_dev(dev->dev))) -+ !dev_is_removable(&adev->pdev->dev)) - adev->flags |= AMD_IS_PX; - - if (!(adev->flags & AMD_IS_APU)) { -@@ -3968,7 +3968,7 @@ fence_driver_init: - - px = amdgpu_device_supports_px(ddev); - -- if (px || (!pci_is_thunderbolt_attached(adev->pdev) && -+ if (px || (!dev_is_removable(&adev->pdev->dev) && - apple_gmux_detect(NULL, NULL))) - vga_switcheroo_register_client(adev->pdev, - &amdgpu_switcheroo_ops, px); -@@ -4117,7 +4117,7 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev) - - px = amdgpu_device_supports_px(adev_to_drm(adev)); - -- if (px || (!pci_is_thunderbolt_attached(adev->pdev) && -+ if (px || (!dev_is_removable(&adev->pdev->dev) && - apple_gmux_detect(NULL, NULL))) - vga_switcheroo_unregister_client(adev->pdev); - -@@ -5330,7 +5330,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, - * Flush RAM to disk so that after reboot - * the user can read log and see why the system rebooted. - */ -- if (need_emergency_restart && amdgpu_ras_get_context(adev)->reboot) { -+ if (need_emergency_restart && amdgpu_ras_get_context(adev) && -+ amdgpu_ras_get_context(adev)->reboot) { - DRM_WARN("Emergency reboot."); - - ksys_sync_helper(); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c -index 09fc464f5f128..9fe2eae88ec17 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c -@@ -1273,7 +1273,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) - { - struct amdgpu_ras *con = amdgpu_ras_get_context(adev); - -- sysfs_remove_file_from_group(&adev->dev->kobj, -+ if (adev->dev->kobj.sd) -+ sysfs_remove_file_from_group(&adev->dev->kobj, - &con->badpages_attr.attr, - RAS_FS_NAME); - } -@@ -1290,7 +1291,8 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct amdgpu_device *adev) - .attrs = attrs, - }; - -- sysfs_remove_group(&adev->dev->kobj, &group); -+ if (adev->dev->kobj.sd) -+ sysfs_remove_group(&adev->dev->kobj, &group); - - return 0; - } -@@ -1337,7 +1339,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev, - if (!obj || !obj->attr_inuse) - return -EINVAL; - -- sysfs_remove_file_from_group(&adev->dev->kobj, -+ if (adev->dev->kobj.sd) -+ sysfs_remove_file_from_group(&adev->dev->kobj, - &obj->sysfs_attr.attr, - RAS_FS_NAME); - obj->attr_inuse = 0; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c -index 5c1193dd7d88c..48e612023d0c7 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c -@@ -391,8 +391,15 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev) - void *ptr; - int i, idx; - -+ bool in_ras_intr = amdgpu_ras_intr_triggered(); -+ - cancel_delayed_work_sync(&adev->vcn.idle_work); - -+ /* err_event_athub will corrupt VCPU buffer, so we need to -+ * restore fw data and clear buffer in amdgpu_vcn_resume() */ -+ if (in_ras_intr) -+ return 0; -+ - for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { - if (adev->vcn.harvest_config & (1 << i)) - continue; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c -index d60c4a2eeb0c5..06980b8527ff8 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c -@@ -239,6 +239,8 @@ static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector) - - for (i = 0; i < ARRAY_SIZE(common_modes); i++) { - mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false); -+ if (!mode) -+ continue; - drm_mode_probed_add(connector, mode); - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c -index 7ba47fc1917b2..73937ce8829cc 100644 ---- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c -+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c -@@ -28,6 +28,7 @@ - #include "nbio/nbio_2_3_offset.h" - #include "nbio/nbio_2_3_sh_mask.h" - #include -+#include - #include - - #define smnPCIE_CONFIG_CNTL 0x11180044 -@@ -361,7 +362,7 @@ static void nbio_v2_3_enable_aspm(struct amdgpu_device *adev, - - data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT; - -- if (pci_is_thunderbolt_attached(adev->pdev)) -+ if (dev_is_removable(&adev->pdev->dev)) - data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; - else - data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; -@@ -480,7 +481,7 @@ static void nbio_v2_3_program_aspm(struct amdgpu_device *adev) - - def = data = RREG32_PCIE(smnPCIE_LC_CNTL); - data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT; -- if (pci_is_thunderbolt_attached(adev->pdev)) -+ if (dev_is_removable(&adev->pdev->dev)) - data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; - else - data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT; -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -index d7e758c86a0b8..208812512d8a8 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c -@@ -612,8 +612,15 @@ create_bo_failed: - - void svm_range_vram_node_free(struct svm_range *prange) - { -- svm_range_bo_unref(prange->svm_bo); -- prange->ttm_res = NULL; -+ /* serialize prange->svm_bo unref */ -+ mutex_lock(&prange->lock); -+ /* prange->svm_bo has not been unref */ -+ if (prange->ttm_res) { -+ prange->ttm_res = NULL; -+ mutex_unlock(&prange->lock); -+ svm_range_bo_unref(prange->svm_bo); -+ } else -+ mutex_unlock(&prange->lock); - } - - struct amdgpu_device * -@@ -757,7 +764,7 @@ svm_range_apply_attrs(struct kfd_process *p, struct svm_range *prange, - prange->flags &= ~attrs[i].value; - break; - case KFD_IOCTL_SVM_ATTR_GRANULARITY: -- prange->granularity = attrs[i].value; -+ prange->granularity = min_t(uint32_t, attrs[i].value, 0x3F); - break; - default: - WARN_ONCE(1, "svm_range_check_attrs wasn't called?"); -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 42e266e074d1d..001932cb813dc 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -2057,7 +2057,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) - struct dmub_srv_create_params create_params; - struct dmub_srv_region_params region_params; - struct dmub_srv_region_info region_info; -- struct dmub_srv_fb_params fb_params; -+ struct dmub_srv_memory_params memory_params; - struct dmub_srv_fb_info *fb_info; - struct dmub_srv *dmub_srv; - const struct dmcub_firmware_header_v1_0 *hdr; -@@ -2188,6 +2188,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) - adev->dm.dmub_fw->data + - le32_to_cpu(hdr->header.ucode_array_offset_bytes) + - PSP_HEADER_BYTES; -+ region_params.is_mailbox_in_inbox = false; - - status = dmub_srv_calc_region_info(dmub_srv, ®ion_params, - ®ion_info); -@@ -2209,10 +2210,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) - return r; - - /* Rebase the regions on the framebuffer address. */ -- memset(&fb_params, 0, sizeof(fb_params)); -- fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr; -- fb_params.gpu_addr = adev->dm.dmub_bo_gpu_addr; -- fb_params.region_info = ®ion_info; -+ memset(&memory_params, 0, sizeof(memory_params)); -+ memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr; -+ memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr; -+ memory_params.region_info = ®ion_info; - - adev->dm.dmub_fb_info = - kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL); -@@ -2224,7 +2225,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) - return -ENOMEM; - } - -- status = dmub_srv_calc_fb_info(dmub_srv, &fb_params, fb_info); -+ status = dmub_srv_calc_mem_info(dmub_srv, &memory_params, fb_info); - if (status != DMUB_STATUS_OK) { - DRM_ERROR("Error calculating DMUB FB info: %d\n", status); - return -EINVAL; -@@ -7219,6 +7220,9 @@ static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap, - int i; - int result = -EIO; - -+ if (!ddc_service->ddc_pin || !ddc_service->ddc_pin->hw_info.hw_supported) -+ return result; -+ - cmd.payloads = kcalloc(num, sizeof(struct i2c_payload), GFP_KERNEL); - - if (!cmd.payloads) -@@ -9282,14 +9286,14 @@ static bool should_reset_plane(struct drm_atomic_state *state, - struct drm_plane *other; - struct drm_plane_state *old_other_state, *new_other_state; - struct drm_crtc_state *new_crtc_state; -+ struct amdgpu_device *adev = drm_to_adev(plane->dev); - int i; - - /* -- * TODO: Remove this hack once the checks below are sufficient -- * enough to determine when we need to reset all the planes on -- * the stream. -+ * TODO: Remove this hack for all asics once it proves that the -+ * fast updates works fine on DCN3.2+. - */ -- if (state->allow_modeset) -+ if (adev->ip_versions[DCE_HWIP][0] < IP_VERSION(3, 2, 0) && state->allow_modeset) - return true; - - /* Exit early if we know that we're adding or removing the plane. */ -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c -index 15d3caf3d6d72..7a309547c2b3f 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c -@@ -996,7 +996,8 @@ static bool dc_construct(struct dc *dc, - /* set i2c speed if not done by the respective dcnxxx__resource.c */ - if (dc->caps.i2c_speed_in_khz_hdcp == 0) - dc->caps.i2c_speed_in_khz_hdcp = dc->caps.i2c_speed_in_khz; -- -+ if (dc->caps.max_optimizable_video_width == 0) -+ dc->caps.max_optimizable_video_width = 5120; - dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); - if (!dc->clk_mgr) - goto fail; -@@ -1805,7 +1806,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c - if (dc->hwss.subvp_pipe_control_lock) - dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use); - -- if (dc->debug.enable_double_buffered_dsc_pg_support) -+ if (dc->hwss.update_dsc_pg) - dc->hwss.update_dsc_pg(dc, context, false); - - disable_dangling_plane(dc, context); -@@ -1904,7 +1905,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c - dc->hwss.optimize_bandwidth(dc, context); - } - -- if (dc->debug.enable_double_buffered_dsc_pg_support) -+ if (dc->hwss.update_dsc_pg) - dc->hwss.update_dsc_pg(dc, context, true); - - if (dc->ctx->dce_version >= DCE_VERSION_MAX) -@@ -2192,7 +2193,7 @@ void dc_post_update_surfaces_to_stream(struct dc *dc) - - dc->hwss.optimize_bandwidth(dc, context); - -- if (dc->debug.enable_double_buffered_dsc_pg_support) -+ if (dc->hwss.update_dsc_pg) - dc->hwss.update_dsc_pg(dc, context, true); - } - -@@ -2438,6 +2439,7 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa - } - - static enum surface_update_type get_scaling_info_update_type( -+ const struct dc *dc, - const struct dc_surface_update *u) - { - union surface_update_flags *update_flags = &u->surface->update_flags; -@@ -2472,6 +2474,12 @@ static enum surface_update_type get_scaling_info_update_type( - update_flags->bits.clock_change = 1; - } - -+ if (u->scaling_info->src_rect.width > dc->caps.max_optimizable_video_width && -+ (u->scaling_info->clip_rect.width > u->surface->clip_rect.width || -+ u->scaling_info->clip_rect.height > u->surface->clip_rect.height)) -+ /* Changing clip size of a large surface may result in MPC slice count change */ -+ update_flags->bits.bandwidth_change = 1; -+ - if (u->scaling_info->src_rect.x != u->surface->src_rect.x - || u->scaling_info->src_rect.y != u->surface->src_rect.y - || u->scaling_info->clip_rect.x != u->surface->clip_rect.x -@@ -2509,7 +2517,7 @@ static enum surface_update_type det_surface_update(const struct dc *dc, - type = get_plane_info_update_type(u); - elevate_update_type(&overall_type, type); - -- type = get_scaling_info_update_type(u); -+ type = get_scaling_info_update_type(dc, u); - elevate_update_type(&overall_type, type); - - if (u->flip_addr) { -@@ -3445,7 +3453,7 @@ static void commit_planes_for_stream(struct dc *dc, - if (get_seamless_boot_stream_count(context) == 0) - dc->hwss.prepare_bandwidth(dc, context); - -- if (dc->debug.enable_double_buffered_dsc_pg_support) -+ if (dc->hwss.update_dsc_pg) - dc->hwss.update_dsc_pg(dc, context, false); - - context_clock_trace(dc, context); -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c -index 38d71b5c1f2d5..556c57c390ffd 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c -@@ -567,7 +567,7 @@ uint32_t dc_stream_get_vblank_counter(const struct dc_stream_state *stream) - for (i = 0; i < MAX_PIPES; i++) { - struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; - -- if (res_ctx->pipe_ctx[i].stream != stream) -+ if (res_ctx->pipe_ctx[i].stream != stream || !tg) - continue; - - return tg->funcs->get_frame_count(tg); -@@ -626,7 +626,7 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream, - for (i = 0; i < MAX_PIPES; i++) { - struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; - -- if (res_ctx->pipe_ctx[i].stream != stream) -+ if (res_ctx->pipe_ctx[i].stream != stream || !tg) - continue; - - tg->funcs->get_scanoutpos(tg, -diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h -index a4540f83aae59..f773a467fef54 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc.h -+++ b/drivers/gpu/drm/amd/display/dc/dc.h -@@ -230,6 +230,11 @@ struct dc_caps { - uint32_t dmdata_alloc_size; - unsigned int max_cursor_size; - unsigned int max_video_width; -+ /* -+ * max video plane width that can be safely assumed to be always -+ * supported by single DPP pipe. -+ */ -+ unsigned int max_optimizable_video_width; - unsigned int min_horizontal_blanking_period; - int linear_pitch_alignment; - bool dcc_const_color; -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -index d477dcc9149fa..50b3547977281 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -@@ -79,6 +79,9 @@ void dcn32_dsc_pg_control( - if (hws->ctx->dc->debug.disable_dsc_power_gate) - return; - -+ if (!hws->ctx->dc->debug.enable_double_buffered_dsc_pg_support) -+ return; -+ - REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); - if (org_ip_request_cntl == 0) - REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); -diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h -index 5f17b252e9be4..a21fe7b037d1f 100644 ---- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h -+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h -@@ -174,6 +174,7 @@ struct dmub_srv_region_params { - uint32_t vbios_size; - const uint8_t *fw_inst_const; - const uint8_t *fw_bss_data; -+ bool is_mailbox_in_inbox; - }; - - /** -@@ -193,20 +194,25 @@ struct dmub_srv_region_params { - */ - struct dmub_srv_region_info { - uint32_t fb_size; -+ uint32_t inbox_size; - uint8_t num_regions; - struct dmub_region regions[DMUB_WINDOW_TOTAL]; - }; - - /** -- * struct dmub_srv_fb_params - parameters used for driver fb setup -+ * struct dmub_srv_memory_params - parameters used for driver fb setup - * @region_info: region info calculated by dmub service -- * @cpu_addr: base cpu address for the framebuffer -- * @gpu_addr: base gpu virtual address for the framebuffer -+ * @cpu_fb_addr: base cpu address for the framebuffer -+ * @cpu_inbox_addr: base cpu address for the gart -+ * @gpu_fb_addr: base gpu virtual address for the framebuffer -+ * @gpu_inbox_addr: base gpu virtual address for the gart - */ --struct dmub_srv_fb_params { -+struct dmub_srv_memory_params { - const struct dmub_srv_region_info *region_info; -- void *cpu_addr; -- uint64_t gpu_addr; -+ void *cpu_fb_addr; -+ void *cpu_inbox_addr; -+ uint64_t gpu_fb_addr; -+ uint64_t gpu_inbox_addr; - }; - - /** -@@ -524,8 +530,8 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, - * DMUB_STATUS_OK - success - * DMUB_STATUS_INVALID - unspecified error - */ --enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, -- const struct dmub_srv_fb_params *params, -+enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, -+ const struct dmub_srv_memory_params *params, - struct dmub_srv_fb_info *out); - - /** -diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c -index 0dab22d794808..c3327875933e9 100644 ---- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c -+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c -@@ -384,7 +384,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, - uint32_t fw_state_size = DMUB_FW_STATE_SIZE; - uint32_t trace_buffer_size = DMUB_TRACE_BUFFER_SIZE; - uint32_t scratch_mem_size = DMUB_SCRATCH_MEM_SIZE; -- -+ uint32_t previous_top = 0; - if (!dmub->sw_init) - return DMUB_STATUS_INVALID; - -@@ -409,8 +409,15 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, - bios->base = dmub_align(stack->top, 256); - bios->top = bios->base + params->vbios_size; - -- mail->base = dmub_align(bios->top, 256); -- mail->top = mail->base + DMUB_MAILBOX_SIZE; -+ if (params->is_mailbox_in_inbox) { -+ mail->base = 0; -+ mail->top = mail->base + DMUB_MAILBOX_SIZE; -+ previous_top = bios->top; -+ } else { -+ mail->base = dmub_align(bios->top, 256); -+ mail->top = mail->base + DMUB_MAILBOX_SIZE; -+ previous_top = mail->top; -+ } - - fw_info = dmub_get_fw_meta_info(params); - -@@ -429,7 +436,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, - dmub->fw_version = fw_info->fw_version; - } - -- trace_buff->base = dmub_align(mail->top, 256); -+ trace_buff->base = dmub_align(previous_top, 256); - trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64); - - fw_state->base = dmub_align(trace_buff->top, 256); -@@ -440,11 +447,14 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, - - out->fb_size = dmub_align(scratch_mem->top, 4096); - -+ if (params->is_mailbox_in_inbox) -+ out->inbox_size = dmub_align(mail->top, 4096); -+ - return DMUB_STATUS_OK; - } - --enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, -- const struct dmub_srv_fb_params *params, -+enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, -+ const struct dmub_srv_memory_params *params, - struct dmub_srv_fb_info *out) - { - uint8_t *cpu_base; -@@ -459,8 +469,8 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, - if (params->region_info->num_regions != DMUB_NUM_WINDOWS) - return DMUB_STATUS_INVALID; - -- cpu_base = (uint8_t *)params->cpu_addr; -- gpu_base = params->gpu_addr; -+ cpu_base = (uint8_t *)params->cpu_fb_addr; -+ gpu_base = params->gpu_fb_addr; - - for (i = 0; i < DMUB_NUM_WINDOWS; ++i) { - const struct dmub_region *reg = -@@ -468,6 +478,12 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, - - out->fb[i].cpu_addr = cpu_base + reg->base; - out->fb[i].gpu_addr = gpu_base + reg->base; -+ -+ if (i == DMUB_WINDOW_4_MAILBOX && params->cpu_inbox_addr != 0) { -+ out->fb[i].cpu_addr = (uint8_t *)params->cpu_inbox_addr + reg->base; -+ out->fb[i].gpu_addr = params->gpu_inbox_addr + reg->base; -+ } -+ - out->fb[i].size = reg->top - reg->base; - } - -diff --git a/drivers/gpu/drm/amd/include/pptable.h b/drivers/gpu/drm/amd/include/pptable.h -index 0b6a057e0a4c4..5aac8d545bdc6 100644 ---- a/drivers/gpu/drm/amd/include/pptable.h -+++ b/drivers/gpu/drm/amd/include/pptable.h -@@ -78,7 +78,7 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER - typedef struct _ATOM_PPLIB_STATE - { - UCHAR ucNonClockStateIndex; -- UCHAR ucClockStateIndices[1]; // variable-sized -+ UCHAR ucClockStateIndices[]; // variable-sized - } ATOM_PPLIB_STATE; - - -@@ -473,7 +473,7 @@ typedef struct _ATOM_PPLIB_STATE_V2 - /** - * Driver will read the first ucNumDPMLevels in this array - */ -- UCHAR clockInfoIndex[1]; -+ UCHAR clockInfoIndex[]; - } ATOM_PPLIB_STATE_V2; - - typedef struct _StateArray{ -diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c -index 0e78437c8389d..29f3d8431089e 100644 ---- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c -+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c -@@ -758,7 +758,7 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - -- if (count > 127) -+ if (count > 127 || count == 0) - return -EINVAL; - - if (*buf == 's') -@@ -778,7 +778,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, - else - return -EINVAL; - -- memcpy(buf_cpy, buf, count+1); -+ memcpy(buf_cpy, buf, count); -+ buf_cpy[count] = 0; - - tmp_str = buf_cpy; - -@@ -795,6 +796,9 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, - return -EINVAL; - parameter_size++; - -+ if (!tmp_str) -+ break; -+ - while (isspace(*tmp_str)) - tmp_str++; - } -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h -index b0ac4d121adca..e0e40b054c08b 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h -@@ -164,7 +164,7 @@ typedef struct _ATOM_Tonga_State { - typedef struct _ATOM_Tonga_State_Array { - UCHAR ucRevId; - UCHAR ucNumEntries; /* Number of entries. */ -- ATOM_Tonga_State entries[1]; /* Dynamically allocate entries. */ -+ ATOM_Tonga_State entries[]; /* Dynamically allocate entries. */ - } ATOM_Tonga_State_Array; - - typedef struct _ATOM_Tonga_MCLK_Dependency_Record { -@@ -179,7 +179,7 @@ typedef struct _ATOM_Tonga_MCLK_Dependency_Record { - typedef struct _ATOM_Tonga_MCLK_Dependency_Table { - UCHAR ucRevId; - UCHAR ucNumEntries; /* Number of entries. */ -- ATOM_Tonga_MCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ -+ ATOM_Tonga_MCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ - } ATOM_Tonga_MCLK_Dependency_Table; - - typedef struct _ATOM_Tonga_SCLK_Dependency_Record { -@@ -194,7 +194,7 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Record { - typedef struct _ATOM_Tonga_SCLK_Dependency_Table { - UCHAR ucRevId; - UCHAR ucNumEntries; /* Number of entries. */ -- ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ -+ ATOM_Tonga_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ - } ATOM_Tonga_SCLK_Dependency_Table; - - typedef struct _ATOM_Polaris_SCLK_Dependency_Record { -@@ -210,7 +210,7 @@ typedef struct _ATOM_Polaris_SCLK_Dependency_Record { - typedef struct _ATOM_Polaris_SCLK_Dependency_Table { - UCHAR ucRevId; - UCHAR ucNumEntries; /* Number of entries. */ -- ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ -+ ATOM_Polaris_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ - } ATOM_Polaris_SCLK_Dependency_Table; - - typedef struct _ATOM_Tonga_PCIE_Record { -@@ -222,7 +222,7 @@ typedef struct _ATOM_Tonga_PCIE_Record { - typedef struct _ATOM_Tonga_PCIE_Table { - UCHAR ucRevId; - UCHAR ucNumEntries; /* Number of entries. */ -- ATOM_Tonga_PCIE_Record entries[1]; /* Dynamically allocate entries. */ -+ ATOM_Tonga_PCIE_Record entries[]; /* Dynamically allocate entries. */ - } ATOM_Tonga_PCIE_Table; - - typedef struct _ATOM_Polaris10_PCIE_Record { -@@ -235,7 +235,7 @@ typedef struct _ATOM_Polaris10_PCIE_Record { - typedef struct _ATOM_Polaris10_PCIE_Table { - UCHAR ucRevId; - UCHAR ucNumEntries; /* Number of entries. */ -- ATOM_Polaris10_PCIE_Record entries[1]; /* Dynamically allocate entries. */ -+ ATOM_Polaris10_PCIE_Record entries[]; /* Dynamically allocate entries. */ - } ATOM_Polaris10_PCIE_Table; - - -@@ -252,7 +252,7 @@ typedef struct _ATOM_Tonga_MM_Dependency_Record { - typedef struct _ATOM_Tonga_MM_Dependency_Table { - UCHAR ucRevId; - UCHAR ucNumEntries; /* Number of entries. */ -- ATOM_Tonga_MM_Dependency_Record entries[1]; /* Dynamically allocate entries. */ -+ ATOM_Tonga_MM_Dependency_Record entries[]; /* Dynamically allocate entries. */ - } ATOM_Tonga_MM_Dependency_Table; - - typedef struct _ATOM_Tonga_Voltage_Lookup_Record { -@@ -265,7 +265,7 @@ typedef struct _ATOM_Tonga_Voltage_Lookup_Record { - typedef struct _ATOM_Tonga_Voltage_Lookup_Table { - UCHAR ucRevId; - UCHAR ucNumEntries; /* Number of entries. */ -- ATOM_Tonga_Voltage_Lookup_Record entries[1]; /* Dynamically allocate entries. */ -+ ATOM_Tonga_Voltage_Lookup_Record entries[]; /* Dynamically allocate entries. */ - } ATOM_Tonga_Voltage_Lookup_Table; - - typedef struct _ATOM_Tonga_Fan_Table { -diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -index a664a0a284784..47ff3694ffa57 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -@@ -1221,7 +1221,7 @@ static int smu_smc_hw_setup(struct smu_context *smu) - { - struct smu_feature *feature = &smu->smu_feature; - struct amdgpu_device *adev = smu->adev; -- uint32_t pcie_gen = 0, pcie_width = 0; -+ uint8_t pcie_gen = 0, pcie_width = 0; - uint64_t features_supported; - int ret = 0; - -diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h -index 1ab77a6cdb653..4174cb295dd0b 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h -+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h -@@ -844,7 +844,7 @@ struct pptable_funcs { - * &pcie_gen_cap: Maximum allowed PCIe generation. - * &pcie_width_cap: Maximum allowed PCIe width. - */ -- int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap); -+ int (*update_pcie_parameters)(struct smu_context *smu, uint8_t pcie_gen_cap, uint8_t pcie_width_cap); - - /** - * @i2c_init: Initialize i2c. -diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h -index d6479a8088554..636b9579b96b0 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h -+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h -@@ -298,8 +298,8 @@ int smu_v13_0_get_pptable_from_firmware(struct smu_context *smu, - uint32_t pptable_id); - - int smu_v13_0_update_pcie_parameters(struct smu_context *smu, -- uint32_t pcie_gen_cap, -- uint32_t pcie_width_cap); -+ uint8_t pcie_gen_cap, -+ uint8_t pcie_width_cap); - - #endif - #endif -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c -index ca278280865fa..ed2112efc6c68 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c -@@ -2368,8 +2368,8 @@ static int navi10_get_power_limit(struct smu_context *smu, - } - - static int navi10_update_pcie_parameters(struct smu_context *smu, -- uint32_t pcie_gen_cap, -- uint32_t pcie_width_cap) -+ uint8_t pcie_gen_cap, -+ uint8_t pcie_width_cap) - { - struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; - PPTable_t *pptable = smu->smu_table.driver_pptable; -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -index fbc4d706748b7..cfd41d56e9701 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c -@@ -2084,14 +2084,14 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context - #define MAX(a, b) ((a) > (b) ? (a) : (b)) - - static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu, -- uint32_t pcie_gen_cap, -- uint32_t pcie_width_cap) -+ uint8_t pcie_gen_cap, -+ uint8_t pcie_width_cap) - { - struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; - struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table; - uint8_t *table_member1, *table_member2; -- uint32_t min_gen_speed, max_gen_speed; -- uint32_t min_lane_width, max_lane_width; -+ uint8_t min_gen_speed, max_gen_speed; -+ uint8_t min_lane_width, max_lane_width; - uint32_t smu_pcie_arg; - int ret, i; - -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -index 3104d49379090..1b0fb93539ec4 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c -@@ -2486,8 +2486,8 @@ int smu_v13_0_mode1_reset(struct smu_context *smu) - } - - int smu_v13_0_update_pcie_parameters(struct smu_context *smu, -- uint32_t pcie_gen_cap, -- uint32_t pcie_width_cap) -+ uint8_t pcie_gen_cap, -+ uint8_t pcie_width_cap) - { - struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; - struct smu_13_0_pcie_table *pcie_table = -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c -index 503e844baede2..af244def4801b 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c -@@ -324,12 +324,12 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu) - if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC) - smu->dc_controlled_by_gpio = true; - -- if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_BACO || -- powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO) -+ if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_BACO) { - smu_baco->platform_support = true; - -- if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO) -- smu_baco->maco_support = true; -+ if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO) -+ smu_baco->maco_support = true; -+ } - - table_context->thermal_controller_type = - powerplay_table->thermal_controller_type; -@@ -1645,38 +1645,10 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, - } - } - -- if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE && -- (((smu->adev->pdev->device == 0x744C) && (smu->adev->pdev->revision == 0xC8)) || -- ((smu->adev->pdev->device == 0x744C) && (smu->adev->pdev->revision == 0xCC)))) { -- ret = smu_cmn_update_table(smu, -- SMU_TABLE_ACTIVITY_MONITOR_COEFF, -- WORKLOAD_PPLIB_COMPUTE_BIT, -- (void *)(&activity_monitor_external), -- false); -- if (ret) { -- dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); -- return ret; -- } -- -- ret = smu_cmn_update_table(smu, -- SMU_TABLE_ACTIVITY_MONITOR_COEFF, -- WORKLOAD_PPLIB_CUSTOM_BIT, -- (void *)(&activity_monitor_external), -- true); -- if (ret) { -- dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); -- return ret; -- } -- -- workload_type = smu_cmn_to_asic_specific_index(smu, -- CMN2ASIC_MAPPING_WORKLOAD, -- PP_SMC_POWER_PROFILE_CUSTOM); -- } else { -- /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ -- workload_type = smu_cmn_to_asic_specific_index(smu, -+ /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ -+ workload_type = smu_cmn_to_asic_specific_index(smu, - CMN2ASIC_MAPPING_WORKLOAD, - smu->power_profile_mode); -- } - - if (workload_type < 0) - return -EINVAL; -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c -index bf24850027dab..bd065f1c699f5 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c -@@ -326,12 +326,13 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu) - if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_HARDWAREDC) - smu->dc_controlled_by_gpio = true; - -- if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_BACO || -- powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_MACO) -+ if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_BACO) { - smu_baco->platform_support = true; - -- if (smu_baco->platform_support && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled)) -- smu_baco->maco_support = true; -+ if ((powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_MACO) -+ && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled)) -+ smu_baco->maco_support = true; -+ } - - table_context->thermal_controller_type = - powerplay_table->thermal_controller_type; -diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c -index 3276a3e82c628..916f2c36bf2f7 100644 ---- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c -+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c -@@ -1223,7 +1223,7 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, - return 0; - } - --static void -+static int - komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, - struct komeda_pipeline_state *new) - { -@@ -1243,8 +1243,12 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, - c = komeda_pipeline_get_component(pipe, id); - c_st = komeda_component_get_state_and_set_user(c, - drm_st, NULL, new->crtc); -+ if (PTR_ERR(c_st) == -EDEADLK) -+ return -EDEADLK; - WARN_ON(IS_ERR(c_st)); - } -+ -+ return 0; - } - - /* release unclaimed pipeline resource */ -@@ -1266,9 +1270,8 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, - if (WARN_ON(IS_ERR_OR_NULL(st))) - return -EINVAL; - -- komeda_pipeline_unbound_components(pipe, st); -+ return komeda_pipeline_unbound_components(pipe, st); - -- return 0; - } - - /* Since standalone disabled components must be disabled separately and in the -diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c -index d72c2fac0ff1a..b7362356e5448 100644 ---- a/drivers/gpu/drm/drm_lease.c -+++ b/drivers/gpu/drm/drm_lease.c -@@ -507,8 +507,8 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, - /* Handle leased objects, if any */ - idr_init(&leases); - if (object_count != 0) { -- object_ids = memdup_user(u64_to_user_ptr(cl->object_ids), -- array_size(object_count, sizeof(__u32))); -+ object_ids = memdup_array_user(u64_to_user_ptr(cl->object_ids), -+ object_count, sizeof(__u32)); - if (IS_ERR(object_ids)) { - ret = PTR_ERR(object_ids); - idr_destroy(&leases); -diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h -index ae544b69fc475..52f9ed3c24b8e 100644 ---- a/drivers/gpu/drm/gma500/psb_drv.h -+++ b/drivers/gpu/drm/gma500/psb_drv.h -@@ -426,6 +426,7 @@ struct drm_psb_private { - uint32_t pipestat[PSB_NUM_PIPE]; - - spinlock_t irqmask_lock; -+ bool irq_enabled; - - /* Power */ - bool pm_initialized; -diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c -index d421031462df6..ab2d49dab35a0 100644 ---- a/drivers/gpu/drm/gma500/psb_irq.c -+++ b/drivers/gpu/drm/gma500/psb_irq.c -@@ -338,6 +338,8 @@ int gma_irq_install(struct drm_device *dev) - - gma_irq_postinstall(dev); - -+ dev_priv->irq_enabled = true; -+ - return 0; - } - -@@ -348,6 +350,9 @@ void gma_irq_uninstall(struct drm_device *dev) - unsigned long irqflags; - unsigned int i; - -+ if (!dev_priv->irq_enabled) -+ return; -+ - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - if (dev_priv->ops->hotplug_enable) -diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c -index 92925f0f72396..25dcdde5feb69 100644 ---- a/drivers/gpu/drm/i915/display/intel_cdclk.c -+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c -@@ -2368,6 +2368,18 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state) - for_each_pipe(dev_priv, pipe) - min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk); - -+ /* -+ * Avoid glk_force_audio_cdclk() causing excessive screen -+ * blinking when multiple pipes are active by making sure -+ * CDCLK frequency is always high enough for audio. With a -+ * single active pipe we can always change CDCLK frequency -+ * by changing the cd2x divider (see glk_cdclk_table[]) and -+ * thus a full modeset won't be needed then. -+ */ -+ if (IS_GEMINILAKE(dev_priv) && cdclk_state->active_pipes && -+ !is_power_of_2(cdclk_state->active_pipes)) -+ min_cdclk = max(2 * 96000, min_cdclk); -+ - if (min_cdclk > dev_priv->display.cdclk.max_cdclk_freq) { - drm_dbg_kms(&dev_priv->drm, - "required cdclk (%d kHz) exceeds max (%d kHz)\n", -diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c -index 598028870124d..5e1b11db74816 100644 ---- a/drivers/gpu/drm/i915/gem/i915_gem_context.c -+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c -@@ -844,6 +844,7 @@ static int set_proto_ctx_sseu(struct drm_i915_file_private *fpriv, - if (idx >= pc->num_user_engines) - return -EINVAL; - -+ idx = array_index_nospec(idx, pc->num_user_engines); - pe = &pc->user_engines[idx]; - - /* Only render engine supports RPCS configuration. */ -diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c -index 3ce49c118b83f..2d4f09813a15b 100644 ---- a/drivers/gpu/drm/i915/i915_perf.c -+++ b/drivers/gpu/drm/i915/i915_perf.c -@@ -3809,11 +3809,8 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data, - u32 known_open_flags; - int ret; - -- if (!perf->i915) { -- drm_dbg(&perf->i915->drm, -- "i915 perf interface not available for this system\n"); -+ if (!perf->i915) - return -ENOTSUPP; -- } - - known_open_flags = I915_PERF_FLAG_FD_CLOEXEC | - I915_PERF_FLAG_FD_NONBLOCK | -@@ -4140,11 +4137,8 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data, - struct i915_oa_reg *regs; - int err, id; - -- if (!perf->i915) { -- drm_dbg(&perf->i915->drm, -- "i915 perf interface not available for this system\n"); -+ if (!perf->i915) - return -ENOTSUPP; -- } - - if (!perf->metrics_kobj) { - drm_dbg(&perf->i915->drm, -@@ -4306,11 +4300,8 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data, - struct i915_oa_config *oa_config; - int ret; - -- if (!perf->i915) { -- drm_dbg(&perf->i915->drm, -- "i915 perf interface not available for this system\n"); -+ if (!perf->i915) - return -ENOTSUPP; -- } - - if (i915_perf_stream_paranoid && !perfmon_capable()) { - drm_dbg(&perf->i915->drm, -diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c -index 395a190274cfb..2c850b6d945bc 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dp.c -+++ b/drivers/gpu/drm/mediatek/mtk_dp.c -@@ -1983,7 +1983,6 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, - bool enabled = mtk_dp->enabled; - struct edid *new_edid = NULL; - struct mtk_dp_audio_cfg *audio_caps = &mtk_dp->info.audio_cur_cfg; -- struct cea_sad *sads; - - if (!enabled) { - drm_bridge_chain_pre_enable(bridge); -@@ -2006,11 +2005,16 @@ static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge, - */ - if (mtk_dp_parse_capabilities(mtk_dp)) { - drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n"); -+ kfree(new_edid); - new_edid = NULL; - } - - if (new_edid) { -+ struct cea_sad *sads; -+ - audio_caps->sad_count = drm_edid_to_sad(new_edid, &sads); -+ kfree(sads); -+ - audio_caps->detect_monitor = drm_detect_monitor_audio(new_edid); - } - -diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c -index 5149cebc93f61..d38086650fcf7 100644 ---- a/drivers/gpu/drm/msm/dp/dp_panel.c -+++ b/drivers/gpu/drm/msm/dp/dp_panel.c -@@ -266,26 +266,9 @@ int dp_panel_get_modes(struct dp_panel *dp_panel, - - static u8 dp_panel_get_edid_checksum(struct edid *edid) - { -- struct edid *last_block; -- u8 *raw_edid; -- bool is_edid_corrupt = false; -+ edid += edid->extensions; - -- if (!edid) { -- DRM_ERROR("invalid edid input\n"); -- return 0; -- } -- -- raw_edid = (u8 *)edid; -- raw_edid += (edid->extensions * EDID_LENGTH); -- last_block = (struct edid *)raw_edid; -- -- /* block type extension */ -- drm_edid_block_valid(raw_edid, 1, false, &is_edid_corrupt); -- if (!is_edid_corrupt) -- return last_block->checksum; -- -- DRM_ERROR("Invalid block, no checksum\n"); -- return 0; -+ return edid->checksum; - } - - void dp_panel_handle_sink_request(struct dp_panel *dp_panel) -diff --git a/drivers/gpu/drm/panel/panel-arm-versatile.c b/drivers/gpu/drm/panel/panel-arm-versatile.c -index abb0788843c60..503ecea72c5ea 100644 ---- a/drivers/gpu/drm/panel/panel-arm-versatile.c -+++ b/drivers/gpu/drm/panel/panel-arm-versatile.c -@@ -267,6 +267,8 @@ static int versatile_panel_get_modes(struct drm_panel *panel, - connector->display_info.bus_flags = vpanel->panel_type->bus_flags; - - mode = drm_mode_duplicate(connector->dev, &vpanel->panel_type->mode); -+ if (!mode) -+ return -ENOMEM; - drm_mode_set_name(mode); - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - -diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c -index 86a472b01360b..b6e514aabe1d3 100644 ---- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c -+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c -@@ -428,29 +428,30 @@ static int st7703_prepare(struct drm_panel *panel) - return 0; - - dev_dbg(ctx->dev, "Resetting the panel\n"); -- ret = regulator_enable(ctx->vcc); -+ gpiod_set_value_cansleep(ctx->reset_gpio, 1); -+ -+ ret = regulator_enable(ctx->iovcc); - if (ret < 0) { -- dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); -+ dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); - return ret; - } -- ret = regulator_enable(ctx->iovcc); -+ -+ ret = regulator_enable(ctx->vcc); - if (ret < 0) { -- dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); -- goto disable_vcc; -+ dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); -+ regulator_disable(ctx->iovcc); -+ return ret; - } - -- gpiod_set_value_cansleep(ctx->reset_gpio, 1); -- usleep_range(20, 40); -+ /* Give power supplies time to stabilize before deasserting reset. */ -+ usleep_range(10000, 20000); -+ - gpiod_set_value_cansleep(ctx->reset_gpio, 0); -- msleep(20); -+ usleep_range(15000, 20000); - - ctx->prepared = true; - - return 0; -- --disable_vcc: -- regulator_disable(ctx->vcc); -- return ret; - } - - static const u32 mantix_bus_formats[] = { -diff --git a/drivers/gpu/drm/panel/panel-tpo-tpg110.c b/drivers/gpu/drm/panel/panel-tpo-tpg110.c -index 0b1f5a11a0554..735f1ea25c121 100644 ---- a/drivers/gpu/drm/panel/panel-tpo-tpg110.c -+++ b/drivers/gpu/drm/panel/panel-tpo-tpg110.c -@@ -379,6 +379,8 @@ static int tpg110_get_modes(struct drm_panel *panel, - connector->display_info.bus_flags = tpg->panel_mode->bus_flags; - - mode = drm_mode_duplicate(connector->dev, &tpg->panel_mode->mode); -+ if (!mode) -+ return -ENOMEM; - drm_mode_set_name(mode); - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - -diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c -index a152a7c6db215..f91a86225d5e7 100644 ---- a/drivers/gpu/drm/qxl/qxl_display.c -+++ b/drivers/gpu/drm/qxl/qxl_display.c -@@ -1229,6 +1229,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev) - if (!qdev->monitors_config_bo) - return 0; - -+ kfree(qdev->dumb_heads); -+ qdev->dumb_heads = NULL; -+ - qdev->monitors_config = NULL; - qdev->ram_header->monitors_config = 0; - -diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c -index f7431d2246044..5837af5123a9f 100644 ---- a/drivers/gpu/drm/radeon/radeon_connectors.c -+++ b/drivers/gpu/drm/radeon/radeon_connectors.c -@@ -1122,6 +1122,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector) - else { - /* only 800x600 is supported right now on pre-avivo chips */ - tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false); -+ if (!tv_mode) -+ return 0; - tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, tv_mode); - } -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -index 591c301e6cf21..1a1a286bc749f 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -@@ -774,9 +774,9 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, - sizeof(metadata->mip_levels)); - metadata->num_sizes = num_sizes; - metadata->sizes = -- memdup_user((struct drm_vmw_size __user *)(unsigned long) -+ memdup_array_user((struct drm_vmw_size __user *)(unsigned long) - req->size_addr, -- sizeof(*metadata->sizes) * metadata->num_sizes); -+ metadata->num_sizes, sizeof(*metadata->sizes)); - if (IS_ERR(metadata->sizes)) { - ret = PTR_ERR(metadata->sizes); - goto out_no_sizes; -diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h -index 9a17e5cc3539b..130fc5f341422 100644 ---- a/drivers/hid/hid-ids.h -+++ b/drivers/hid/hid-ids.h -@@ -365,6 +365,7 @@ - - #define USB_VENDOR_ID_DELL 0x413c - #define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE 0x301a -+#define USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W 0x4503 - - #define USB_VENDOR_ID_DELORME 0x1163 - #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 -diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c -index 44763c0da4441..7c1b33be9d134 100644 ---- a/drivers/hid/hid-lenovo.c -+++ b/drivers/hid/hid-lenovo.c -@@ -51,7 +51,12 @@ struct lenovo_drvdata { - int select_right; - int sensitivity; - int press_speed; -- u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ -+ /* 0: Up -+ * 1: Down (undecided) -+ * 2: Scrolling -+ * 3: Patched firmware, disable workaround -+ */ -+ u8 middlebutton_state; - bool fn_lock; - }; - -@@ -521,6 +526,19 @@ static void lenovo_features_set_cptkbd(struct hid_device *hdev) - int ret; - struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); - -+ /* -+ * Tell the keyboard a driver understands it, and turn F7, F9, F11 into -+ * regular keys -+ */ -+ ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); -+ if (ret) -+ hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); -+ -+ /* Switch middle button to native mode */ -+ ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); -+ if (ret) -+ hid_warn(hdev, "Failed to switch middle button: %d\n", ret); -+ - ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); - if (ret) - hid_err(hdev, "Fn-lock setting failed: %d\n", ret); -@@ -668,31 +686,48 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, - { - struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); - -- /* "wheel" scroll events */ -- if (usage->type == EV_REL && (usage->code == REL_WHEEL || -- usage->code == REL_HWHEEL)) { -- /* Scroll events disable middle-click event */ -- cptkbd_data->middlebutton_state = 2; -- return 0; -- } -+ if (cptkbd_data->middlebutton_state != 3) { -+ /* REL_X and REL_Y events during middle button pressed -+ * are only possible on patched, bug-free firmware -+ * so set middlebutton_state to 3 -+ * to never apply workaround anymore -+ */ -+ if (cptkbd_data->middlebutton_state == 1 && -+ usage->type == EV_REL && -+ (usage->code == REL_X || usage->code == REL_Y)) { -+ cptkbd_data->middlebutton_state = 3; -+ /* send middle button press which was hold before */ -+ input_event(field->hidinput->input, -+ EV_KEY, BTN_MIDDLE, 1); -+ input_sync(field->hidinput->input); -+ } -+ -+ /* "wheel" scroll events */ -+ if (usage->type == EV_REL && (usage->code == REL_WHEEL || -+ usage->code == REL_HWHEEL)) { -+ /* Scroll events disable middle-click event */ -+ cptkbd_data->middlebutton_state = 2; -+ return 0; -+ } - -- /* Middle click events */ -- if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { -- if (value == 1) { -- cptkbd_data->middlebutton_state = 1; -- } else if (value == 0) { -- if (cptkbd_data->middlebutton_state == 1) { -- /* No scrolling inbetween, send middle-click */ -- input_event(field->hidinput->input, -- EV_KEY, BTN_MIDDLE, 1); -- input_sync(field->hidinput->input); -- input_event(field->hidinput->input, -- EV_KEY, BTN_MIDDLE, 0); -- input_sync(field->hidinput->input); -+ /* Middle click events */ -+ if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { -+ if (value == 1) { -+ cptkbd_data->middlebutton_state = 1; -+ } else if (value == 0) { -+ if (cptkbd_data->middlebutton_state == 1) { -+ /* No scrolling inbetween, send middle-click */ -+ input_event(field->hidinput->input, -+ EV_KEY, BTN_MIDDLE, 1); -+ input_sync(field->hidinput->input); -+ input_event(field->hidinput->input, -+ EV_KEY, BTN_MIDDLE, 0); -+ input_sync(field->hidinput->input); -+ } -+ cptkbd_data->middlebutton_state = 0; - } -- cptkbd_data->middlebutton_state = 0; -+ return 1; - } -- return 1; - } - - if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { -@@ -1126,22 +1161,6 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev) - } - hid_set_drvdata(hdev, cptkbd_data); - -- /* -- * Tell the keyboard a driver understands it, and turn F7, F9, F11 into -- * regular keys (Compact only) -- */ -- if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD || -- hdev->product == USB_DEVICE_ID_LENOVO_CBTKBD) { -- ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); -- if (ret) -- hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); -- } -- -- /* Switch middle button to native mode */ -- ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); -- if (ret) -- hid_warn(hdev, "Failed to switch middle button: %d\n", ret); -- - /* Set keyboard settings to known state */ - cptkbd_data->middlebutton_state = 0; - cptkbd_data->fn_lock = true; -@@ -1264,6 +1283,24 @@ err: - return ret; - } - -+#ifdef CONFIG_PM -+static int lenovo_reset_resume(struct hid_device *hdev) -+{ -+ switch (hdev->product) { -+ case USB_DEVICE_ID_LENOVO_CUSBKBD: -+ case USB_DEVICE_ID_LENOVO_TPIIUSBKBD: -+ if (hdev->type == HID_TYPE_USBMOUSE) -+ lenovo_features_set_cptkbd(hdev); -+ -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+#endif -+ - static void lenovo_remove_tpkbd(struct hid_device *hdev) - { - struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); -@@ -1380,6 +1417,9 @@ static struct hid_driver lenovo_driver = { - .raw_event = lenovo_raw_event, - .event = lenovo_event, - .report_fixup = lenovo_report_fixup, -+#ifdef CONFIG_PM -+ .reset_resume = lenovo_reset_resume, -+#endif - }; - module_hid_driver(lenovo_driver); - -diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c -index f8f20a7c24b17..056bb32091285 100644 ---- a/drivers/hid/hid-quirks.c -+++ b/drivers/hid/hid-quirks.c -@@ -66,6 +66,7 @@ static const struct hid_device_id hid_quirks[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, - { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, -+ { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W), HID_QUIRK_ALWAYS_POLL }, - { HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET }, - { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT }, - { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT }, -diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c -index 004ccb2d9f369..948d547690c64 100644 ---- a/drivers/i2c/busses/i2c-designware-master.c -+++ b/drivers/i2c/busses/i2c-designware-master.c -@@ -456,10 +456,16 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) - - /* - * Because we don't know the buffer length in the -- * I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop -- * the transaction here. -+ * I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop the -+ * transaction here. Also disable the TX_EMPTY IRQ -+ * while waiting for the data length byte to avoid the -+ * bogus interrupts flood. - */ -- if (buf_len > 0 || flags & I2C_M_RECV_LEN) { -+ if (flags & I2C_M_RECV_LEN) { -+ dev->status |= STATUS_WRITE_IN_PROGRESS; -+ intr_mask &= ~DW_IC_INTR_TX_EMPTY; -+ break; -+ } else if (buf_len > 0) { - /* more bytes to be written */ - dev->status |= STATUS_WRITE_IN_PROGRESS; - break; -@@ -495,6 +501,13 @@ i2c_dw_recv_len(struct dw_i2c_dev *dev, u8 len) - msgs[dev->msg_read_idx].len = len; - msgs[dev->msg_read_idx].flags &= ~I2C_M_RECV_LEN; - -+ /* -+ * Received buffer length, re-enable TX_EMPTY interrupt -+ * to resume the SMBUS transaction. -+ */ -+ regmap_update_bits(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_TX_EMPTY, -+ DW_IC_INTR_TX_EMPTY); -+ - return len; - } - -diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c -index da1f6b60f9c9a..3159ffbb77a20 100644 ---- a/drivers/i2c/busses/i2c-i801.c -+++ b/drivers/i2c/busses/i2c-i801.c -@@ -690,15 +690,11 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, - return i801_check_post(priv, result ? priv->status : -ETIMEDOUT); - } - -- for (i = 1; i <= len; i++) { -- if (i == len && read_write == I2C_SMBUS_READ) -- smbcmd |= SMBHSTCNT_LAST_BYTE; -- outb_p(smbcmd, SMBHSTCNT(priv)); -- -- if (i == 1) -- outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START, -- SMBHSTCNT(priv)); -+ if (len == 1 && read_write == I2C_SMBUS_READ) -+ smbcmd |= SMBHSTCNT_LAST_BYTE; -+ outb_p(smbcmd | SMBHSTCNT_START, SMBHSTCNT(priv)); - -+ for (i = 1; i <= len; i++) { - status = i801_wait_byte_done(priv); - if (status) - goto exit; -@@ -721,9 +717,12 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, - data->block[0] = len; - } - -- /* Retrieve/store value in SMBBLKDAT */ -- if (read_write == I2C_SMBUS_READ) -+ if (read_write == I2C_SMBUS_READ) { - data->block[i] = inb_p(SMBBLKDAT(priv)); -+ if (i == len - 1) -+ outb_p(smbcmd | SMBHSTCNT_LAST_BYTE, SMBHSTCNT(priv)); -+ } -+ - if (read_write == I2C_SMBUS_WRITE && i+1 <= len) - outb_p(data->block[i+1], SMBBLKDAT(priv)); - -diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c -index b605b6e43cb90..ade3f0ea59551 100644 ---- a/drivers/i2c/busses/i2c-pxa.c -+++ b/drivers/i2c/busses/i2c-pxa.c -@@ -264,6 +264,9 @@ struct pxa_i2c { - u32 hs_mask; - - struct i2c_bus_recovery_info recovery; -+ struct pinctrl *pinctrl; -+ struct pinctrl_state *pinctrl_default; -+ struct pinctrl_state *pinctrl_recovery; - }; - - #define _IBMR(i2c) ((i2c)->reg_ibmr) -@@ -1302,12 +1305,13 @@ static void i2c_pxa_prepare_recovery(struct i2c_adapter *adap) - */ - gpiod_set_value(i2c->recovery.scl_gpiod, ibmr & IBMR_SCLS); - gpiod_set_value(i2c->recovery.sda_gpiod, ibmr & IBMR_SDAS); -+ -+ WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery)); - } - - static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap) - { - struct pxa_i2c *i2c = adap->algo_data; -- struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; - u32 isr; - - /* -@@ -1321,7 +1325,7 @@ static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap) - i2c_pxa_do_reset(i2c); - } - -- WARN_ON(pinctrl_select_state(bri->pinctrl, bri->pins_default)); -+ WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default)); - - dev_dbg(&i2c->adap.dev, "recovery: IBMR 0x%08x ISR 0x%08x\n", - readl(_IBMR(i2c)), readl(_ISR(i2c))); -@@ -1343,20 +1347,76 @@ static int i2c_pxa_init_recovery(struct pxa_i2c *i2c) - if (IS_ENABLED(CONFIG_I2C_PXA_SLAVE)) - return 0; - -- bri->pinctrl = devm_pinctrl_get(dev); -- if (PTR_ERR(bri->pinctrl) == -ENODEV) { -- bri->pinctrl = NULL; -+ i2c->pinctrl = devm_pinctrl_get(dev); -+ if (PTR_ERR(i2c->pinctrl) == -ENODEV) -+ i2c->pinctrl = NULL; -+ if (IS_ERR(i2c->pinctrl)) -+ return PTR_ERR(i2c->pinctrl); -+ -+ if (!i2c->pinctrl) -+ return 0; -+ -+ i2c->pinctrl_default = pinctrl_lookup_state(i2c->pinctrl, -+ PINCTRL_STATE_DEFAULT); -+ i2c->pinctrl_recovery = pinctrl_lookup_state(i2c->pinctrl, "recovery"); -+ -+ if (IS_ERR(i2c->pinctrl_default) || IS_ERR(i2c->pinctrl_recovery)) { -+ dev_info(dev, "missing pinmux recovery information: %ld %ld\n", -+ PTR_ERR(i2c->pinctrl_default), -+ PTR_ERR(i2c->pinctrl_recovery)); -+ return 0; -+ } -+ -+ /* -+ * Claiming GPIOs can influence the pinmux state, and may glitch the -+ * I2C bus. Do this carefully. -+ */ -+ bri->scl_gpiod = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN); -+ if (bri->scl_gpiod == ERR_PTR(-EPROBE_DEFER)) -+ return -EPROBE_DEFER; -+ if (IS_ERR(bri->scl_gpiod)) { -+ dev_info(dev, "missing scl gpio recovery information: %pe\n", -+ bri->scl_gpiod); -+ return 0; -+ } -+ -+ /* -+ * We have SCL. Pull SCL low and wait a bit so that SDA glitches -+ * have no effect. -+ */ -+ gpiod_direction_output(bri->scl_gpiod, 0); -+ udelay(10); -+ bri->sda_gpiod = devm_gpiod_get(dev, "sda", GPIOD_OUT_HIGH_OPEN_DRAIN); -+ -+ /* Wait a bit in case of a SDA glitch, and then release SCL. */ -+ udelay(10); -+ gpiod_direction_output(bri->scl_gpiod, 1); -+ -+ if (bri->sda_gpiod == ERR_PTR(-EPROBE_DEFER)) -+ return -EPROBE_DEFER; -+ -+ if (IS_ERR(bri->sda_gpiod)) { -+ dev_info(dev, "missing sda gpio recovery information: %pe\n", -+ bri->sda_gpiod); - return 0; - } -- if (IS_ERR(bri->pinctrl)) -- return PTR_ERR(bri->pinctrl); - - bri->prepare_recovery = i2c_pxa_prepare_recovery; - bri->unprepare_recovery = i2c_pxa_unprepare_recovery; -+ bri->recover_bus = i2c_generic_scl_recovery; - - i2c->adap.bus_recovery_info = bri; - -- return 0; -+ /* -+ * Claiming GPIOs can change the pinmux state, which confuses the -+ * pinctrl since pinctrl's idea of the current setting is unaffected -+ * by the pinmux change caused by claiming the GPIO. Work around that -+ * by switching pinctrl to the GPIO state here. We do it this way to -+ * avoid glitching the I2C bus. -+ */ -+ pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery); -+ -+ return pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default); - } - - static int i2c_pxa_probe(struct platform_device *dev) -diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c -index 9e3483f507ff5..f2ed13b551088 100644 ---- a/drivers/i2c/busses/i2c-sun6i-p2wi.c -+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c -@@ -201,6 +201,11 @@ static int p2wi_probe(struct platform_device *pdev) - return -EINVAL; - } - -+ if (clk_freq == 0) { -+ dev_err(dev, "clock-frequency is set to 0 in DT\n"); -+ return -EINVAL; -+ } -+ - if (of_get_child_count(np) > 1) { - dev_err(dev, "P2WI only supports one slave device\n"); - return -EINVAL; -diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c -index 7539b0740351d..5e3976ba52650 100644 ---- a/drivers/i2c/i2c-core-base.c -+++ b/drivers/i2c/i2c-core-base.c -@@ -916,8 +916,9 @@ int i2c_dev_irq_from_resources(const struct resource *resources, - struct i2c_client * - i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info) - { -- struct i2c_client *client; -- int status; -+ struct i2c_client *client; -+ bool need_put = false; -+ int status; - - client = kzalloc(sizeof *client, GFP_KERNEL); - if (!client) -@@ -955,7 +956,6 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf - client->dev.fwnode = info->fwnode; - - device_enable_async_suspend(&client->dev); -- i2c_dev_set_name(adap, client, info); - - if (info->swnode) { - status = device_add_software_node(&client->dev, info->swnode); -@@ -967,6 +967,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf - } - } - -+ i2c_dev_set_name(adap, client, info); - status = device_register(&client->dev); - if (status) - goto out_remove_swnode; -@@ -978,6 +979,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf - - out_remove_swnode: - device_remove_software_node(&client->dev); -+ need_put = true; - out_err_put_of_node: - of_node_put(info->of_node); - out_err: -@@ -985,7 +987,10 @@ out_err: - "Failed to register i2c client %s at 0x%02x (%d)\n", - client->name, client->addr, status); - out_err_silent: -- kfree(client); -+ if (need_put) -+ put_device(&client->dev); -+ else -+ kfree(client); - return ERR_PTR(status); - } - EXPORT_SYMBOL_GPL(i2c_new_client_device); -diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h -index 1247e6e6e9751..05b8b8dfa9bdd 100644 ---- a/drivers/i2c/i2c-core.h -+++ b/drivers/i2c/i2c-core.h -@@ -29,7 +29,7 @@ int i2c_dev_irq_from_resources(const struct resource *resources, - */ - static inline bool i2c_in_atomic_xfer_mode(void) - { -- return system_state > SYSTEM_RUNNING && irqs_disabled(); -+ return system_state > SYSTEM_RUNNING && !preemptible(); - } - - static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap) -diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c -index ab0adaa130dae..dd35f341b16fd 100644 ---- a/drivers/i2c/i2c-dev.c -+++ b/drivers/i2c/i2c-dev.c -@@ -450,8 +450,8 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) - return -EINVAL; - -- rdwr_pa = memdup_user(rdwr_arg.msgs, -- rdwr_arg.nmsgs * sizeof(struct i2c_msg)); -+ rdwr_pa = memdup_array_user(rdwr_arg.msgs, -+ rdwr_arg.nmsgs, sizeof(struct i2c_msg)); - if (IS_ERR(rdwr_pa)) - return PTR_ERR(rdwr_pa); - -diff --git a/drivers/i3c/master/i3c-master-cdns.c b/drivers/i3c/master/i3c-master-cdns.c -index 5b37ffe5ad5be..4a49c75a9408c 100644 ---- a/drivers/i3c/master/i3c-master-cdns.c -+++ b/drivers/i3c/master/i3c-master-cdns.c -@@ -192,7 +192,7 @@ - #define SLV_STATUS1_HJ_DIS BIT(18) - #define SLV_STATUS1_MR_DIS BIT(17) - #define SLV_STATUS1_PROT_ERR BIT(16) --#define SLV_STATUS1_DA(x) (((s) & GENMASK(15, 9)) >> 9) -+#define SLV_STATUS1_DA(s) (((s) & GENMASK(15, 9)) >> 9) - #define SLV_STATUS1_HAS_DA BIT(8) - #define SLV_STATUS1_DDR_RX_FULL BIT(7) - #define SLV_STATUS1_DDR_TX_FULL BIT(6) -@@ -1624,13 +1624,13 @@ static int cdns_i3c_master_probe(struct platform_device *pdev) - /* Device ID0 is reserved to describe this master. */ - master->maxdevs = CONF_STATUS0_DEVS_NUM(val); - master->free_rr_slots = GENMASK(master->maxdevs, 1); -+ master->caps.ibirfifodepth = CONF_STATUS0_IBIR_DEPTH(val); -+ master->caps.cmdrfifodepth = CONF_STATUS0_CMDR_DEPTH(val); - - val = readl(master->regs + CONF_STATUS1); - master->caps.cmdfifodepth = CONF_STATUS1_CMD_DEPTH(val); - master->caps.rxfifodepth = CONF_STATUS1_RX_DEPTH(val); - master->caps.txfifodepth = CONF_STATUS1_TX_DEPTH(val); -- master->caps.ibirfifodepth = CONF_STATUS0_IBIR_DEPTH(val); -- master->caps.cmdrfifodepth = CONF_STATUS0_CMDR_DEPTH(val); - - spin_lock_init(&master->ibi.lock); - master->ibi.num_slots = CONF_STATUS1_IBI_HW_RES(val); -diff --git a/drivers/i3c/master/mipi-i3c-hci/dat_v1.c b/drivers/i3c/master/mipi-i3c-hci/dat_v1.c -index 97bb49ff5b53b..47b9b4d4ed3fc 100644 ---- a/drivers/i3c/master/mipi-i3c-hci/dat_v1.c -+++ b/drivers/i3c/master/mipi-i3c-hci/dat_v1.c -@@ -64,15 +64,17 @@ static int hci_dat_v1_init(struct i3c_hci *hci) - return -EOPNOTSUPP; - } - -- /* use a bitmap for faster free slot search */ -- hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL); -- if (!hci->DAT_data) -- return -ENOMEM; -- -- /* clear them */ -- for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) { -- dat_w0_write(dat_idx, 0); -- dat_w1_write(dat_idx, 0); -+ if (!hci->DAT_data) { -+ /* use a bitmap for faster free slot search */ -+ hci->DAT_data = bitmap_zalloc(hci->DAT_entries, GFP_KERNEL); -+ if (!hci->DAT_data) -+ return -ENOMEM; -+ -+ /* clear them */ -+ for (dat_idx = 0; dat_idx < hci->DAT_entries; dat_idx++) { -+ dat_w0_write(dat_idx, 0); -+ dat_w1_write(dat_idx, 0); -+ } - } - - return 0; -@@ -87,7 +89,13 @@ static void hci_dat_v1_cleanup(struct i3c_hci *hci) - static int hci_dat_v1_alloc_entry(struct i3c_hci *hci) - { - unsigned int dat_idx; -+ int ret; - -+ if (!hci->DAT_data) { -+ ret = hci_dat_v1_init(hci); -+ if (ret) -+ return ret; -+ } - dat_idx = find_first_zero_bit(hci->DAT_data, hci->DAT_entries); - if (dat_idx >= hci->DAT_entries) - return -ENOENT; -@@ -103,7 +111,8 @@ static void hci_dat_v1_free_entry(struct i3c_hci *hci, unsigned int dat_idx) - { - dat_w0_write(dat_idx, 0); - dat_w1_write(dat_idx, 0); -- __clear_bit(dat_idx, hci->DAT_data); -+ if (hci->DAT_data) -+ __clear_bit(dat_idx, hci->DAT_data); - } - - static void hci_dat_v1_set_dynamic_addr(struct i3c_hci *hci, -diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c -index 2990ac9eaade7..71b5dbe45c45c 100644 ---- a/drivers/i3c/master/mipi-i3c-hci/dma.c -+++ b/drivers/i3c/master/mipi-i3c-hci/dma.c -@@ -734,7 +734,7 @@ static bool hci_dma_irq_handler(struct i3c_hci *hci, unsigned int mask) - unsigned int i; - bool handled = false; - -- for (i = 0; mask && i < 8; i++) { -+ for (i = 0; mask && i < rings->total; i++) { - struct hci_rh_data *rh; - u32 status; - -diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c -index 4eebf15f685a3..f30d457e91196 100644 ---- a/drivers/i3c/master/svc-i3c-master.c -+++ b/drivers/i3c/master/svc-i3c-master.c -@@ -92,6 +92,8 @@ - #define SVC_I3C_MINTCLR 0x094 - #define SVC_I3C_MINTMASKED 0x098 - #define SVC_I3C_MERRWARN 0x09C -+#define SVC_I3C_MERRWARN_NACK BIT(2) -+#define SVC_I3C_MERRWARN_TIMEOUT BIT(20) - #define SVC_I3C_MDMACTRL 0x0A0 - #define SVC_I3C_MDATACTRL 0x0AC - #define SVC_I3C_MDATACTRL_FLUSHTB BIT(0) -@@ -168,6 +170,7 @@ struct svc_i3c_xfer { - * @ibi.slots: Available IBI slots - * @ibi.tbq_slot: To be queued IBI slot - * @ibi.lock: IBI lock -+ * @lock: Transfer lock, protect between IBI work thread and callbacks from master - */ - struct svc_i3c_master { - struct i3c_master_controller base; -@@ -195,6 +198,7 @@ struct svc_i3c_master { - /* Prevent races within IBI handlers */ - spinlock_t lock; - } ibi; -+ struct mutex lock; - }; - - /** -@@ -217,6 +221,14 @@ static bool svc_i3c_master_error(struct svc_i3c_master *master) - if (SVC_I3C_MSTATUS_ERRWARN(mstatus)) { - merrwarn = readl(master->regs + SVC_I3C_MERRWARN); - writel(merrwarn, master->regs + SVC_I3C_MERRWARN); -+ -+ /* Ignore timeout error */ -+ if (merrwarn & SVC_I3C_MERRWARN_TIMEOUT) { -+ dev_dbg(master->dev, "Warning condition: MSTATUS 0x%08x, MERRWARN 0x%08x\n", -+ mstatus, merrwarn); -+ return false; -+ } -+ - dev_err(master->dev, - "Error condition: MSTATUS 0x%08x, MERRWARN 0x%08x\n", - mstatus, merrwarn); -@@ -323,6 +335,7 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, - struct i3c_ibi_slot *slot; - unsigned int count; - u32 mdatactrl; -+ int ret, val; - u8 *buf; - - slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); -@@ -332,6 +345,13 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, - slot->len = 0; - buf = slot->data; - -+ ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val, -+ SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); -+ if (ret) { -+ dev_err(master->dev, "Timeout when polling for COMPLETE\n"); -+ return ret; -+ } -+ - while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) && - slot->len < SVC_I3C_FIFO_SIZE) { - mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL); -@@ -376,6 +396,7 @@ static void svc_i3c_master_ibi_work(struct work_struct *work) - u32 status, val; - int ret; - -+ mutex_lock(&master->lock); - /* Acknowledge the incoming interrupt with the AUTOIBI mechanism */ - writel(SVC_I3C_MCTRL_REQUEST_AUTO_IBI | - SVC_I3C_MCTRL_IBIRESP_AUTO, -@@ -386,6 +407,7 @@ static void svc_i3c_master_ibi_work(struct work_struct *work) - SVC_I3C_MSTATUS_IBIWON(val), 0, 1000); - if (ret) { - dev_err(master->dev, "Timeout when polling for IBIWON\n"); -+ svc_i3c_master_emit_stop(master); - goto reenable_ibis; - } - -@@ -452,12 +474,13 @@ static void svc_i3c_master_ibi_work(struct work_struct *work) - - reenable_ibis: - svc_i3c_master_enable_interrupts(master, SVC_I3C_MINT_SLVSTART); -+ mutex_unlock(&master->lock); - } - - static irqreturn_t svc_i3c_master_irq_handler(int irq, void *dev_id) - { - struct svc_i3c_master *master = (struct svc_i3c_master *)dev_id; -- u32 active = readl(master->regs + SVC_I3C_MINTMASKED); -+ u32 active = readl(master->regs + SVC_I3C_MSTATUS); - - if (!SVC_I3C_MSTATUS_SLVSTART(active)) - return IRQ_NONE; -@@ -999,6 +1022,9 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, - u32 reg; - int ret; - -+ /* clean SVC_I3C_MINT_IBIWON w1c bits */ -+ writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS); -+ - writel(SVC_I3C_MCTRL_REQUEST_START_ADDR | - xfer_type | - SVC_I3C_MCTRL_IBIRESP_NACK | -@@ -1012,6 +1038,11 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, - if (ret) - goto emit_stop; - -+ if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) { -+ ret = -ENXIO; -+ goto emit_stop; -+ } -+ - if (rnw) - ret = svc_i3c_master_read(master, in, xfer_len); - else -@@ -1019,6 +1050,23 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, - if (ret < 0) - goto emit_stop; - -+ /* -+ * According to I3C spec ver 1.1.1, 5.1.2.2.3 Consequence of Controller Starting a Frame -+ * with I3C Target Address. -+ * -+ * The I3C Controller normally should start a Frame, the Address may be arbitrated, and so -+ * the Controller shall monitor to see whether an In-Band Interrupt request, a Controller -+ * Role Request (i.e., Secondary Controller requests to become the Active Controller), or -+ * a Hot-Join Request has been made. -+ * -+ * If missed IBIWON check, the wrong data will be return. When IBIWON happen, return failure -+ * and yield the above events handler. -+ */ -+ if (SVC_I3C_MSTATUS_IBIWON(reg)) { -+ ret = -ENXIO; -+ goto emit_stop; -+ } -+ - if (rnw) - *read_len = ret; - -@@ -1191,9 +1239,11 @@ static int svc_i3c_master_send_bdcast_ccc_cmd(struct svc_i3c_master *master, - cmd->read_len = 0; - cmd->continued = false; - -+ mutex_lock(&master->lock); - svc_i3c_master_enqueue_xfer(master, xfer); - if (!wait_for_completion_timeout(&xfer->comp, msecs_to_jiffies(1000))) - svc_i3c_master_dequeue_xfer(master, xfer); -+ mutex_unlock(&master->lock); - - ret = xfer->ret; - kfree(buf); -@@ -1237,9 +1287,11 @@ static int svc_i3c_master_send_direct_ccc_cmd(struct svc_i3c_master *master, - cmd->read_len = read_len; - cmd->continued = false; - -+ mutex_lock(&master->lock); - svc_i3c_master_enqueue_xfer(master, xfer); - if (!wait_for_completion_timeout(&xfer->comp, msecs_to_jiffies(1000))) - svc_i3c_master_dequeue_xfer(master, xfer); -+ mutex_unlock(&master->lock); - - if (cmd->read_len != xfer_len) - ccc->dests[0].payload.len = cmd->read_len; -@@ -1296,9 +1348,11 @@ static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev, - cmd->continued = (i + 1) < nxfers; - } - -+ mutex_lock(&master->lock); - svc_i3c_master_enqueue_xfer(master, xfer); - if (!wait_for_completion_timeout(&xfer->comp, msecs_to_jiffies(1000))) - svc_i3c_master_dequeue_xfer(master, xfer); -+ mutex_unlock(&master->lock); - - ret = xfer->ret; - svc_i3c_master_free_xfer(xfer); -@@ -1334,9 +1388,11 @@ static int svc_i3c_master_i2c_xfers(struct i2c_dev_desc *dev, - cmd->continued = (i + 1 < nxfers); - } - -+ mutex_lock(&master->lock); - svc_i3c_master_enqueue_xfer(master, xfer); - if (!wait_for_completion_timeout(&xfer->comp, msecs_to_jiffies(1000))) - svc_i3c_master_dequeue_xfer(master, xfer); -+ mutex_unlock(&master->lock); - - ret = xfer->ret; - svc_i3c_master_free_xfer(xfer); -@@ -1527,6 +1583,8 @@ static int svc_i3c_master_probe(struct platform_device *pdev) - - INIT_WORK(&master->hj_work, svc_i3c_master_hj_work); - INIT_WORK(&master->ibi_work, svc_i3c_master_ibi_work); -+ mutex_init(&master->lock); -+ - ret = devm_request_irq(dev, master->irq, svc_i3c_master_irq_handler, - IRQF_NO_SUSPEND, "svc-i3c-irq", master); - if (ret) -diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c -index 81d5db91c67bf..dee47b899e5df 100644 ---- a/drivers/iio/adc/stm32-adc-core.c -+++ b/drivers/iio/adc/stm32-adc-core.c -@@ -695,6 +695,8 @@ static int stm32_adc_probe(struct platform_device *pdev) - struct stm32_adc_priv *priv; - struct device *dev = &pdev->dev; - struct device_node *np = pdev->dev.of_node; -+ const struct of_device_id *of_id; -+ - struct resource *res; - u32 max_rate; - int ret; -@@ -707,8 +709,11 @@ static int stm32_adc_probe(struct platform_device *pdev) - return -ENOMEM; - platform_set_drvdata(pdev, &priv->common); - -- priv->cfg = (const struct stm32_adc_priv_cfg *) -- of_match_device(dev->driver->of_match_table, dev)->data; -+ of_id = of_match_device(dev->driver->of_match_table, dev); -+ if (!of_id) -+ return -ENODEV; -+ -+ priv->cfg = (const struct stm32_adc_priv_cfg *)of_id->data; - priv->nb_adc_max = priv->cfg->num_adcs; - spin_lock_init(&priv->common.lock); - -diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c -index a0802332c8cb3..5395cf56fbd90 100644 ---- a/drivers/infiniband/hw/hfi1/pcie.c -+++ b/drivers/infiniband/hw/hfi1/pcie.c -@@ -3,6 +3,7 @@ - * Copyright(c) 2015 - 2019 Intel Corporation. - */ - -+#include - #include - #include - #include -@@ -212,12 +213,6 @@ static u32 extract_speed(u16 linkstat) - return speed; - } - --/* return the PCIe link speed from the given link status */ --static u32 extract_width(u16 linkstat) --{ -- return (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; --} -- - /* read the link status and set dd->{lbus_width,lbus_speed,lbus_info} */ - static void update_lbus_info(struct hfi1_devdata *dd) - { -@@ -230,7 +225,7 @@ static void update_lbus_info(struct hfi1_devdata *dd) - return; - } - -- dd->lbus_width = extract_width(linkstat); -+ dd->lbus_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat); - dd->lbus_speed = extract_speed(linkstat); - snprintf(dd->lbus_info, sizeof(dd->lbus_info), - "PCIe,%uMHz,x%u", dd->lbus_speed, dd->lbus_width); -diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c -index c19a4d2023805..fc6957fddce8e 100644 ---- a/drivers/input/joystick/xpad.c -+++ b/drivers/input/joystick/xpad.c -@@ -474,6 +474,7 @@ static const struct usb_device_id xpad_table[] = { - XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ - XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */ - XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries Controllers */ -+ XPAD_XBOXONE_VENDOR(0x10f5), /* Turtle Beach Controllers */ - XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */ - XPAD_XBOX360_VENDOR(0x11ff), /* PXN V900 */ - XPAD_XBOX360_VENDOR(0x1209), /* Ardwiino Controllers */ -diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c -index e7b6989d8b4a8..a6b4ccc314cac 100644 ---- a/drivers/mcb/mcb-core.c -+++ b/drivers/mcb/mcb-core.c -@@ -246,6 +246,7 @@ int mcb_device_register(struct mcb_bus *bus, struct mcb_device *dev) - return 0; - - out: -+ put_device(&dev->dev); - - return ret; - } -diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c -index 656b6b71c7682..1ae37e693de04 100644 ---- a/drivers/mcb/mcb-parse.c -+++ b/drivers/mcb/mcb-parse.c -@@ -106,7 +106,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus, - return 0; - - err: -- put_device(&mdev->dev); -+ mcb_free_dev(mdev); - - return ret; - } -diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c -index 962fc32c947c5..9eb03bb224698 100644 ---- a/drivers/md/dm-verity-fec.c -+++ b/drivers/md/dm-verity-fec.c -@@ -185,7 +185,7 @@ static int fec_is_erasure(struct dm_verity *v, struct dm_verity_io *io, - { - if (unlikely(verity_hash(v, verity_io_hash_req(v, io), - data, 1 << v->data_dev_block_bits, -- verity_io_real_digest(v, io)))) -+ verity_io_real_digest(v, io), true))) - return 0; - - return memcmp(verity_io_real_digest(v, io), want_digest, -@@ -386,7 +386,7 @@ static int fec_decode_rsb(struct dm_verity *v, struct dm_verity_io *io, - /* Always re-validate the corrected block against the expected hash */ - r = verity_hash(v, verity_io_hash_req(v, io), fio->output, - 1 << v->data_dev_block_bits, -- verity_io_real_digest(v, io)); -+ verity_io_real_digest(v, io), true); - if (unlikely(r < 0)) - return r; - -diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c -index 14a9988ec30ba..b86d41219ba9c 100644 ---- a/drivers/md/dm-verity-target.c -+++ b/drivers/md/dm-verity-target.c -@@ -132,20 +132,21 @@ static int verity_hash_update(struct dm_verity *v, struct ahash_request *req, - * Wrapper for crypto_ahash_init, which handles verity salting. - */ - static int verity_hash_init(struct dm_verity *v, struct ahash_request *req, -- struct crypto_wait *wait) -+ struct crypto_wait *wait, bool may_sleep) - { - int r; - - ahash_request_set_tfm(req, v->tfm); -- ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP | -- CRYPTO_TFM_REQ_MAY_BACKLOG, -- crypto_req_done, (void *)wait); -+ ahash_request_set_callback(req, -+ may_sleep ? CRYPTO_TFM_REQ_MAY_SLEEP | CRYPTO_TFM_REQ_MAY_BACKLOG : 0, -+ crypto_req_done, (void *)wait); - crypto_init_wait(wait); - - r = crypto_wait_req(crypto_ahash_init(req), wait); - - if (unlikely(r < 0)) { -- DMERR("crypto_ahash_init failed: %d", r); -+ if (r != -ENOMEM) -+ DMERR("crypto_ahash_init failed: %d", r); - return r; - } - -@@ -176,12 +177,12 @@ out: - } - - int verity_hash(struct dm_verity *v, struct ahash_request *req, -- const u8 *data, size_t len, u8 *digest) -+ const u8 *data, size_t len, u8 *digest, bool may_sleep) - { - int r; - struct crypto_wait wait; - -- r = verity_hash_init(v, req, &wait); -+ r = verity_hash_init(v, req, &wait, may_sleep); - if (unlikely(r < 0)) - goto out; - -@@ -317,7 +318,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io, - - r = verity_hash(v, verity_io_hash_req(v, io), - data, 1 << v->hash_dev_block_bits, -- verity_io_real_digest(v, io)); -+ verity_io_real_digest(v, io), !io->in_tasklet); - if (unlikely(r < 0)) - goto release_ret_r; - -@@ -548,7 +549,7 @@ static int verity_verify_io(struct dm_verity_io *io) - continue; - } - -- r = verity_hash_init(v, req, &wait); -+ r = verity_hash_init(v, req, &wait, !io->in_tasklet); - if (unlikely(r < 0)) - return r; - -@@ -641,7 +642,7 @@ static void verity_tasklet(unsigned long data) - - io->in_tasklet = true; - err = verity_verify_io(io); -- if (err == -EAGAIN) { -+ if (err == -EAGAIN || err == -ENOMEM) { - /* fallback to retrying with work-queue */ - INIT_WORK(&io->work, verity_work); - queue_work(io->v->verify_wq, &io->work); -@@ -1018,7 +1019,7 @@ static int verity_alloc_zero_digest(struct dm_verity *v) - goto out; - - r = verity_hash(v, req, zero_data, 1 << v->data_dev_block_bits, -- v->zero_digest); -+ v->zero_digest, true); - - out: - kfree(req); -diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h -index 2f555b4203679..f96f4e281ee4a 100644 ---- a/drivers/md/dm-verity.h -+++ b/drivers/md/dm-verity.h -@@ -128,7 +128,7 @@ extern int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io, - u8 *data, size_t len)); - - extern int verity_hash(struct dm_verity *v, struct ahash_request *req, -- const u8 *data, size_t len, u8 *digest); -+ const u8 *data, size_t len, u8 *digest, bool may_sleep); - - extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io, - sector_t block, u8 *digest, bool *is_zero); -diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c -index 4a14d7e5d9f25..5fdb922d24e05 100644 ---- a/drivers/media/i2c/ccs/ccs-core.c -+++ b/drivers/media/i2c/ccs/ccs-core.c -@@ -3088,7 +3088,7 @@ static int ccs_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) - try_fmt->code = sensor->internal_csi_format->code; - try_fmt->field = V4L2_FIELD_NONE; - -- if (ssd != sensor->pixel_array) -+ if (ssd == sensor->pixel_array) - continue; - - try_comp = v4l2_subdev_get_try_compose(sd, fh->state, i); -diff --git a/drivers/media/i2c/ccs/ccs-quirk.h b/drivers/media/i2c/ccs/ccs-quirk.h -index 5838fcda92fd4..0b1a64958d714 100644 ---- a/drivers/media/i2c/ccs/ccs-quirk.h -+++ b/drivers/media/i2c/ccs/ccs-quirk.h -@@ -32,12 +32,10 @@ struct ccs_sensor; - * @reg: Pointer to the register to access - * @value: Register value, set by the caller on write, or - * by the quirk on read -- * -- * @flags: Quirk flags -- * - * @return: 0 on success, -ENOIOCTLCMD if no register - * access may be done by the caller (default read - * value is zero), else negative error code on error -+ * @flags: Quirk flags - */ - struct ccs_quirk { - int (*limits)(struct ccs_sensor *sensor); -diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c -index 74edcc76d12f4..6e1a0614e6d06 100644 ---- a/drivers/media/pci/cobalt/cobalt-driver.c -+++ b/drivers/media/pci/cobalt/cobalt-driver.c -@@ -8,6 +8,7 @@ - * All rights reserved. - */ - -+#include - #include - #include - #include -@@ -210,17 +211,17 @@ void cobalt_pcie_status_show(struct cobalt *cobalt) - pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &stat); - cobalt_info("PCIe link capability 0x%08x: %s per lane and %u lanes\n", - capa, get_link_speed(capa), -- (capa & PCI_EXP_LNKCAP_MLW) >> 4); -+ FIELD_GET(PCI_EXP_LNKCAP_MLW, capa)); - cobalt_info("PCIe link control 0x%04x\n", ctrl); - cobalt_info("PCIe link status 0x%04x: %s per lane and %u lanes\n", - stat, get_link_speed(stat), -- (stat & PCI_EXP_LNKSTA_NLW) >> 4); -+ FIELD_GET(PCI_EXP_LNKSTA_NLW, stat)); - - /* Bus */ - pcie_capability_read_dword(pci_bus_dev, PCI_EXP_LNKCAP, &capa); - cobalt_info("PCIe bus link capability 0x%08x: %s per lane and %u lanes\n", - capa, get_link_speed(capa), -- (capa & PCI_EXP_LNKCAP_MLW) >> 4); -+ FIELD_GET(PCI_EXP_LNKCAP_MLW, capa)); - - /* Slot */ - pcie_capability_read_dword(pci_dev, PCI_EXP_SLTCAP, &capa); -@@ -239,7 +240,7 @@ static unsigned pcie_link_get_lanes(struct cobalt *cobalt) - if (!pci_is_pcie(pci_dev)) - return 0; - pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &link); -- return (link & PCI_EXP_LNKSTA_NLW) >> 4; -+ return FIELD_GET(PCI_EXP_LNKSTA_NLW, link); - } - - static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt) -@@ -250,7 +251,7 @@ static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt) - if (!pci_is_pcie(pci_dev)) - return 0; - pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &link); -- return (link & PCI_EXP_LNKCAP_MLW) >> 4; -+ return FIELD_GET(PCI_EXP_LNKCAP_MLW, link); - } - - static void msi_config_show(struct cobalt *cobalt, struct pci_dev *pci_dev) -diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c -index 2031bde13a939..904208f6f9546 100644 ---- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c -+++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c -@@ -355,9 +355,6 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable) - u8 dt_id = vc * 4; - - if (tg->enabled) { -- /* Config Test Generator */ -- vc = 0xa; -- - /* configure one DT, infinite frames */ - val = vc << TPG_VC_CFG0_VC_NUM; - val |= INTELEAVING_MODE_ONE_SHOT << TPG_VC_CFG0_LINE_INTERLEAVING_MODE; -@@ -370,14 +367,14 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable) - - writel_relaxed(0x12345678, csid->base + CSID_TPG_LFSR_SEED); - -- val = input_format->height & 0x1fff << TPG_DT_n_CFG_0_FRAME_HEIGHT; -- val |= input_format->width & 0x1fff << TPG_DT_n_CFG_0_FRAME_WIDTH; -+ val = (input_format->height & 0x1fff) << TPG_DT_n_CFG_0_FRAME_HEIGHT; -+ val |= (input_format->width & 0x1fff) << TPG_DT_n_CFG_0_FRAME_WIDTH; - writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_0(0)); - - val = format->data_type << TPG_DT_n_CFG_1_DATA_TYPE; - writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_1(0)); - -- val = tg->mode << TPG_DT_n_CFG_2_PAYLOAD_MODE; -+ val = (tg->mode - 1) << TPG_DT_n_CFG_2_PAYLOAD_MODE; - val |= 0xBE << TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD; - val |= format->decode_format << TPG_DT_n_CFG_2_ENCODE_FORMAT; - writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_2(0)); -diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c -index 04baa80494c66..4dba61b8d3f2a 100644 ---- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c -+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c -@@ -476,7 +476,7 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, - - settle_cnt = csiphy_settle_cnt_calc(link_freq, csiphy->timer_clk_rate); - -- val = is_gen2 ? BIT(7) : CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE; -+ val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE; - for (i = 0; i < c->num_data; i++) - val |= BIT(c->data[i].pos * 2); - -diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c -index 600150cfc4f70..07b64d257512c 100644 ---- a/drivers/media/platform/qcom/camss/camss-vfe-170.c -+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c -@@ -7,7 +7,6 @@ - * Copyright (C) 2020-2021 Linaro Ltd. - */ - --#include - #include - #include - #include -@@ -494,35 +493,20 @@ static int vfe_enable_output(struct vfe_line *line) - return 0; - } - --static int vfe_disable_output(struct vfe_line *line) -+static void vfe_disable_output(struct vfe_line *line) - { - struct vfe_device *vfe = to_vfe(line); - struct vfe_output *output = &line->output; - unsigned long flags; - unsigned int i; -- bool done; -- int timeout = 0; -- -- do { -- spin_lock_irqsave(&vfe->output_lock, flags); -- done = !output->gen2.active_num; -- spin_unlock_irqrestore(&vfe->output_lock, flags); -- usleep_range(10000, 20000); -- -- if (timeout++ == 100) { -- dev_err(vfe->camss->dev, "VFE idle timeout - resetting\n"); -- vfe_reset(vfe); -- output->gen2.active_num = 0; -- return 0; -- } -- } while (!done); - - spin_lock_irqsave(&vfe->output_lock, flags); - for (i = 0; i < output->wm_num; i++) - vfe_wm_stop(vfe, output->wm_idx[i]); -+ output->gen2.active_num = 0; - spin_unlock_irqrestore(&vfe->output_lock, flags); - -- return 0; -+ vfe_reset(vfe); - } - - /* -diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c -index 1295851103931..ab42600f7a745 100644 ---- a/drivers/media/platform/qcom/camss/camss-vfe-480.c -+++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c -@@ -8,7 +8,6 @@ - * Copyright (C) 2021 Jonathan Marek - */ - --#include - #include - #include - #include -@@ -311,35 +310,20 @@ static int vfe_enable_output(struct vfe_line *line) - return 0; - } - --static int vfe_disable_output(struct vfe_line *line) -+static void vfe_disable_output(struct vfe_line *line) - { - struct vfe_device *vfe = to_vfe(line); - struct vfe_output *output = &line->output; - unsigned long flags; - unsigned int i; -- bool done; -- int timeout = 0; -- -- do { -- spin_lock_irqsave(&vfe->output_lock, flags); -- done = !output->gen2.active_num; -- spin_unlock_irqrestore(&vfe->output_lock, flags); -- usleep_range(10000, 20000); -- -- if (timeout++ == 100) { -- dev_err(vfe->camss->dev, "VFE idle timeout - resetting\n"); -- vfe_reset(vfe); -- output->gen2.active_num = 0; -- return 0; -- } -- } while (!done); - - spin_lock_irqsave(&vfe->output_lock, flags); - for (i = 0; i < output->wm_num; i++) - vfe_wm_stop(vfe, output->wm_idx[i]); -+ output->gen2.active_num = 0; - spin_unlock_irqrestore(&vfe->output_lock, flags); - -- return 0; -+ vfe_reset(vfe); - } - - /* -diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c -index d8cd9b09c20de..ee4d7dccefe16 100644 ---- a/drivers/media/platform/qcom/camss/camss-vfe.c -+++ b/drivers/media/platform/qcom/camss/camss-vfe.c -@@ -535,7 +535,8 @@ static int vfe_check_clock_rates(struct vfe_device *vfe) - struct camss_clock *clock = &vfe->clock[i]; - - if (!strcmp(clock->name, "vfe0") || -- !strcmp(clock->name, "vfe1")) { -+ !strcmp(clock->name, "vfe1") || -+ !strcmp(clock->name, "vfe_lite")) { - u64 min_rate = 0; - unsigned long rate; - -@@ -611,7 +612,7 @@ int vfe_get(struct vfe_device *vfe) - } else { - ret = vfe_check_clock_rates(vfe); - if (ret < 0) -- goto error_pm_runtime_get; -+ goto error_pm_domain; - } - vfe->power_count++; - -diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c -index a157cac72e0ab..5057b2c4cf6c4 100644 ---- a/drivers/media/platform/qcom/camss/camss.c -+++ b/drivers/media/platform/qcom/camss/camss.c -@@ -1624,6 +1624,12 @@ static int camss_probe(struct platform_device *pdev) - if (ret < 0) - goto err_cleanup; - -+ ret = camss_configure_pd(camss); -+ if (ret < 0) { -+ dev_err(dev, "Failed to configure power domains: %d\n", ret); -+ goto err_cleanup; -+ } -+ - ret = camss_init_subdevices(camss); - if (ret < 0) - goto err_cleanup; -@@ -1676,12 +1682,6 @@ static int camss_probe(struct platform_device *pdev) - } - } - -- ret = camss_configure_pd(camss); -- if (ret < 0) { -- dev_err(dev, "Failed to configure power domains: %d\n", ret); -- return ret; -- } -- - pm_runtime_enable(dev); - - return 0; -diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c -index df96db3761a72..1c5cc5a5f89a6 100644 ---- a/drivers/media/platform/qcom/venus/hfi_msgs.c -+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c -@@ -374,7 +374,7 @@ session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt *pkt, - memcpy(&bufreq[idx], buf_req, sizeof(*bufreq)); - idx++; - -- if (idx > HFI_BUFFER_TYPE_MAX) -+ if (idx >= HFI_BUFFER_TYPE_MAX) - return HFI_ERR_SESSION_INVALID_PARAMETER; - - req_bytes -= sizeof(struct hfi_buffer_requirements); -diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c -index 6cf74b2bc5ae3..c43839539d4dd 100644 ---- a/drivers/media/platform/qcom/venus/hfi_parser.c -+++ b/drivers/media/platform/qcom/venus/hfi_parser.c -@@ -19,6 +19,9 @@ static void init_codecs(struct venus_core *core) - struct hfi_plat_caps *caps = core->caps, *cap; - unsigned long bit; - -+ if (hweight_long(core->dec_codecs) + hweight_long(core->enc_codecs) > MAX_CODEC_NUM) -+ return; -+ - for_each_set_bit(bit, &core->dec_codecs, MAX_CODEC_NUM) { - cap = &caps[core->codecs_count++]; - cap->codec = BIT(bit); -@@ -86,6 +89,9 @@ static void fill_profile_level(struct hfi_plat_caps *cap, const void *data, - { - const struct hfi_profile_level *pl = data; - -+ if (cap->num_pl + num >= HFI_MAX_PROFILE_COUNT) -+ return; -+ - memcpy(&cap->pl[cap->num_pl], pl, num * sizeof(*pl)); - cap->num_pl += num; - } -@@ -111,6 +117,9 @@ fill_caps(struct hfi_plat_caps *cap, const void *data, unsigned int num) - { - const struct hfi_capability *caps = data; - -+ if (cap->num_caps + num >= MAX_CAP_ENTRIES) -+ return; -+ - memcpy(&cap->caps[cap->num_caps], caps, num * sizeof(*caps)); - cap->num_caps += num; - } -@@ -137,6 +146,9 @@ static void fill_raw_fmts(struct hfi_plat_caps *cap, const void *fmts, - { - const struct raw_formats *formats = fmts; - -+ if (cap->num_fmts + num_fmts >= MAX_FMT_ENTRIES) -+ return; -+ - memcpy(&cap->fmts[cap->num_fmts], formats, num_fmts * sizeof(*formats)); - cap->num_fmts += num_fmts; - } -@@ -159,6 +171,9 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data) - rawfmts[i].buftype = fmt->buffer_type; - i++; - -+ if (i >= MAX_FMT_ENTRIES) -+ return; -+ - if (pinfo->num_planes > MAX_PLANES) - break; - -diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c -index 8fc8f46dc3908..d46938aab26b7 100644 ---- a/drivers/media/platform/qcom/venus/hfi_venus.c -+++ b/drivers/media/platform/qcom/venus/hfi_venus.c -@@ -205,6 +205,11 @@ static int venus_write_queue(struct venus_hfi_device *hdev, - - new_wr_idx = wr_idx + dwords; - wr_ptr = (u32 *)(queue->qmem.kva + (wr_idx << 2)); -+ -+ if (wr_ptr < (u32 *)queue->qmem.kva || -+ wr_ptr > (u32 *)(queue->qmem.kva + queue->qmem.size - sizeof(*wr_ptr))) -+ return -EINVAL; -+ - if (new_wr_idx < qsize) { - memcpy(wr_ptr, packet, dwords << 2); - } else { -@@ -272,6 +277,11 @@ static int venus_read_queue(struct venus_hfi_device *hdev, - } - - rd_ptr = (u32 *)(queue->qmem.kva + (rd_idx << 2)); -+ -+ if (rd_ptr < (u32 *)queue->qmem.kva || -+ rd_ptr > (u32 *)(queue->qmem.kva + queue->qmem.size - sizeof(*rd_ptr))) -+ return -EINVAL; -+ - dwords = *rd_ptr >> 2; - if (!dwords) - return -EINVAL; -diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c -index 74546f7e34691..5719dda6e0f0e 100644 ---- a/drivers/media/rc/imon.c -+++ b/drivers/media/rc/imon.c -@@ -2427,6 +2427,12 @@ static int imon_probe(struct usb_interface *interface, - goto fail; - } - -+ if (first_if->dev.driver != interface->dev.driver) { -+ dev_err(&interface->dev, "inconsistent driver matching\n"); -+ ret = -EINVAL; -+ goto fail; -+ } -+ - if (ifnum == 0) { - ictx = imon_init_intf0(interface, id); - if (!ictx) { -diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c -index 3d8488c39c561..3311099cbd573 100644 ---- a/drivers/media/rc/ir-sharp-decoder.c -+++ b/drivers/media/rc/ir-sharp-decoder.c -@@ -15,7 +15,9 @@ - #define SHARP_UNIT 40 /* us */ - #define SHARP_BIT_PULSE (8 * SHARP_UNIT) /* 320us */ - #define SHARP_BIT_0_PERIOD (25 * SHARP_UNIT) /* 1ms (680us space) */ --#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680ms space) */ -+#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680us space) */ -+#define SHARP_BIT_0_SPACE (17 * SHARP_UNIT) /* 680us space */ -+#define SHARP_BIT_1_SPACE (42 * SHARP_UNIT) /* 1680us space */ - #define SHARP_ECHO_SPACE (1000 * SHARP_UNIT) /* 40 ms */ - #define SHARP_TRAILER_SPACE (125 * SHARP_UNIT) /* 5 ms (even longer) */ - -@@ -168,8 +170,8 @@ static const struct ir_raw_timings_pd ir_sharp_timings = { - .header_pulse = 0, - .header_space = 0, - .bit_pulse = SHARP_BIT_PULSE, -- .bit_space[0] = SHARP_BIT_0_PERIOD, -- .bit_space[1] = SHARP_BIT_1_PERIOD, -+ .bit_space[0] = SHARP_BIT_0_SPACE, -+ .bit_space[1] = SHARP_BIT_1_SPACE, - .trailer_pulse = SHARP_BIT_PULSE, - .trailer_space = SHARP_ECHO_SPACE, - .msb_first = 1, -diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c -index 25ab61dae126d..184e0b35744f3 100644 ---- a/drivers/media/rc/lirc_dev.c -+++ b/drivers/media/rc/lirc_dev.c -@@ -276,7 +276,11 @@ static ssize_t lirc_transmit(struct file *file, const char __user *buf, - if (ret < 0) - goto out_kfree_raw; - -- count = ret; -+ /* drop trailing space */ -+ if (!(ret % 2)) -+ count = ret - 1; -+ else -+ count = ret; - - txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL); - if (!txbuf) { -diff --git a/drivers/media/test-drivers/vivid/vivid-rds-gen.c b/drivers/media/test-drivers/vivid/vivid-rds-gen.c -index b5b104ee64c99..c57771119a34b 100644 ---- a/drivers/media/test-drivers/vivid/vivid-rds-gen.c -+++ b/drivers/media/test-drivers/vivid/vivid-rds-gen.c -@@ -145,7 +145,7 @@ void vivid_rds_gen_fill(struct vivid_rds_gen *rds, unsigned freq, - rds->ta = alt; - rds->ms = true; - snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", -- freq / 16, ((freq & 0xf) * 10) / 16); -+ (freq / 16) % 1000000, (((freq & 0xf) * 10) / 16) % 10); - if (alt) - strscpy(rds->radiotext, - " The Radio Data System can switch between different Radio Texts ", -diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c -index 46ed95483e222..5f5fa851ca640 100644 ---- a/drivers/media/usb/gspca/cpia1.c -+++ b/drivers/media/usb/gspca/cpia1.c -@@ -18,6 +18,7 @@ - - #include - #include -+#include - - #include "gspca.h" - -@@ -1028,6 +1029,8 @@ static int set_flicker(struct gspca_dev *gspca_dev, int on, int apply) - sd->params.exposure.expMode = 2; - sd->exposure_status = EXPOSURE_NORMAL; - } -+ if (sd->params.exposure.gain >= BITS_PER_TYPE(currentexp)) -+ return -EINVAL; - currentexp = currentexp << sd->params.exposure.gain; - sd->params.exposure.gain = 0; - /* round down current exposure to nearest value */ -diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c -index 699f44ffff0e4..ae5759200622c 100644 ---- a/drivers/mfd/intel-lpss-pci.c -+++ b/drivers/mfd/intel-lpss-pci.c -@@ -561,6 +561,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { - { PCI_VDEVICE(INTEL, 0xa3e2), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0xa3e3), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0xa3e6), (kernel_ulong_t)&spt_uart_info }, -+ /* LNL-M */ -+ { PCI_VDEVICE(INTEL, 0xa825), (kernel_ulong_t)&bxt_uart_info }, -+ { PCI_VDEVICE(INTEL, 0xa826), (kernel_ulong_t)&bxt_uart_info }, -+ { PCI_VDEVICE(INTEL, 0xa827), (kernel_ulong_t)&tgl_info }, -+ { PCI_VDEVICE(INTEL, 0xa830), (kernel_ulong_t)&tgl_info }, -+ { PCI_VDEVICE(INTEL, 0xa846), (kernel_ulong_t)&tgl_info }, -+ { PCI_VDEVICE(INTEL, 0xa850), (kernel_ulong_t)&ehl_i2c_info }, -+ { PCI_VDEVICE(INTEL, 0xa851), (kernel_ulong_t)&ehl_i2c_info }, -+ { PCI_VDEVICE(INTEL, 0xa852), (kernel_ulong_t)&bxt_uart_info }, -+ { PCI_VDEVICE(INTEL, 0xa878), (kernel_ulong_t)&ehl_i2c_info }, -+ { PCI_VDEVICE(INTEL, 0xa879), (kernel_ulong_t)&ehl_i2c_info }, -+ { PCI_VDEVICE(INTEL, 0xa87a), (kernel_ulong_t)&ehl_i2c_info }, -+ { PCI_VDEVICE(INTEL, 0xa87b), (kernel_ulong_t)&ehl_i2c_info }, - { } - }; - MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids); -diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c -index 7e2cd79d17ebf..8e449cff5cec4 100644 ---- a/drivers/mfd/qcom-spmi-pmic.c -+++ b/drivers/mfd/qcom-spmi-pmic.c -@@ -30,6 +30,8 @@ struct qcom_spmi_dev { - struct qcom_spmi_pmic pmic; - }; - -+static DEFINE_MUTEX(pmic_spmi_revid_lock); -+ - #define N_USIDS(n) ((void *)n) - - static const struct of_device_id pmic_spmi_id_table[] = { -@@ -76,24 +78,21 @@ static const struct of_device_id pmic_spmi_id_table[] = { - * - * This only supports PMICs with 1 or 2 USIDs. - */ --static struct spmi_device *qcom_pmic_get_base_usid(struct device *dev) -+static struct spmi_device *qcom_pmic_get_base_usid(struct spmi_device *sdev, struct qcom_spmi_dev *ctx) - { -- struct spmi_device *sdev; -- struct qcom_spmi_dev *ctx; - struct device_node *spmi_bus; -- struct device_node *other_usid = NULL; -+ struct device_node *child; - int function_parent_usid, ret; - u32 pmic_addr; - -- sdev = to_spmi_device(dev); -- ctx = dev_get_drvdata(&sdev->dev); -- - /* - * Quick return if the function device is already in the base - * USID. This will always be hit for PMICs with only 1 USID. - */ -- if (sdev->usid % ctx->num_usids == 0) -+ if (sdev->usid % ctx->num_usids == 0) { -+ get_device(&sdev->dev); - return sdev; -+ } - - function_parent_usid = sdev->usid; - -@@ -105,28 +104,61 @@ static struct spmi_device *qcom_pmic_get_base_usid(struct device *dev) - * device for USID 2. - */ - spmi_bus = of_get_parent(sdev->dev.of_node); -- do { -- other_usid = of_get_next_child(spmi_bus, other_usid); -- -- ret = of_property_read_u32_index(other_usid, "reg", 0, &pmic_addr); -- if (ret) -- return ERR_PTR(ret); -+ sdev = ERR_PTR(-ENODATA); -+ for_each_child_of_node(spmi_bus, child) { -+ ret = of_property_read_u32_index(child, "reg", 0, &pmic_addr); -+ if (ret) { -+ of_node_put(child); -+ sdev = ERR_PTR(ret); -+ break; -+ } - -- sdev = spmi_device_from_of(other_usid); - if (pmic_addr == function_parent_usid - (ctx->num_usids - 1)) { -- if (!sdev) -+ sdev = spmi_device_from_of(child); -+ if (!sdev) { - /* -- * If the base USID for this PMIC hasn't probed yet -- * but the secondary USID has, then we need to defer -- * the function driver so that it will attempt to -- * probe again when the base USID is ready. -+ * If the base USID for this PMIC hasn't been -+ * registered yet then we need to defer. - */ -- return ERR_PTR(-EPROBE_DEFER); -- return sdev; -+ sdev = ERR_PTR(-EPROBE_DEFER); -+ } -+ of_node_put(child); -+ break; - } -- } while (other_usid->sibling); -+ } - -- return ERR_PTR(-ENODATA); -+ of_node_put(spmi_bus); -+ -+ return sdev; -+} -+ -+static int pmic_spmi_get_base_revid(struct spmi_device *sdev, struct qcom_spmi_dev *ctx) -+{ -+ struct qcom_spmi_dev *base_ctx; -+ struct spmi_device *base; -+ int ret = 0; -+ -+ base = qcom_pmic_get_base_usid(sdev, ctx); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ /* -+ * Copy revid info from base device if it has probed and is still -+ * bound to its driver. -+ */ -+ mutex_lock(&pmic_spmi_revid_lock); -+ base_ctx = spmi_device_get_drvdata(base); -+ if (!base_ctx) { -+ ret = -EPROBE_DEFER; -+ goto out_unlock; -+ } -+ memcpy(&ctx->pmic, &base_ctx->pmic, sizeof(ctx->pmic)); -+out_unlock: -+ mutex_unlock(&pmic_spmi_revid_lock); -+ -+ put_device(&base->dev); -+ -+ return ret; - } - - static int pmic_spmi_load_revid(struct regmap *map, struct device *dev, -@@ -204,11 +236,7 @@ const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev) - if (!of_match_device(pmic_spmi_id_table, dev->parent)) - return ERR_PTR(-EINVAL); - -- sdev = qcom_pmic_get_base_usid(dev->parent); -- -- if (IS_ERR(sdev)) -- return ERR_CAST(sdev); -- -+ sdev = to_spmi_device(dev->parent); - spmi = dev_get_drvdata(&sdev->dev); - - return &spmi->pmic; -@@ -243,16 +271,31 @@ static int pmic_spmi_probe(struct spmi_device *sdev) - ret = pmic_spmi_load_revid(regmap, &sdev->dev, &ctx->pmic); - if (ret < 0) - return ret; -+ } else { -+ ret = pmic_spmi_get_base_revid(sdev, ctx); -+ if (ret) -+ return ret; - } -+ -+ mutex_lock(&pmic_spmi_revid_lock); - spmi_device_set_drvdata(sdev, ctx); -+ mutex_unlock(&pmic_spmi_revid_lock); - - return devm_of_platform_populate(&sdev->dev); - } - -+static void pmic_spmi_remove(struct spmi_device *sdev) -+{ -+ mutex_lock(&pmic_spmi_revid_lock); -+ spmi_device_set_drvdata(sdev, NULL); -+ mutex_unlock(&pmic_spmi_revid_lock); -+} -+ - MODULE_DEVICE_TABLE(of, pmic_spmi_id_table); - - static struct spmi_driver pmic_spmi_driver = { - .probe = pmic_spmi_probe, -+ .remove = pmic_spmi_remove, - .driver = { - .name = "pmic-spmi", - .of_match_table = pmic_spmi_id_table, -diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c -index 55dc16d8f6adb..18059a12d4e18 100644 ---- a/drivers/misc/pci_endpoint_test.c -+++ b/drivers/misc/pci_endpoint_test.c -@@ -81,6 +81,7 @@ - #define PCI_DEVICE_ID_RENESAS_R8A774B1 0x002b - #define PCI_DEVICE_ID_RENESAS_R8A774C0 0x002d - #define PCI_DEVICE_ID_RENESAS_R8A774E1 0x0025 -+#define PCI_DEVICE_ID_RENESAS_R8A779F0 0x0031 - - static DEFINE_IDA(pci_endpoint_test_ida); - -@@ -996,6 +997,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774B1),}, - { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774C0),}, - { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774E1),}, -+ { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A779F0), -+ .driver_data = (kernel_ulong_t)&default_data, -+ }, - { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E), - .driver_data = (kernel_ulong_t)&j721e_data, - }, -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index 1fc6767f18782..67a7ae9b997aa 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -2404,8 +2404,10 @@ enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req) - } - ret = mmc_blk_cqe_issue_flush(mq, req); - break; -- case REQ_OP_READ: - case REQ_OP_WRITE: -+ card->written_flag = true; -+ fallthrough; -+ case REQ_OP_READ: - if (host->cqe_enabled) - ret = mmc_blk_cqe_issue_rw_rq(mq, req); - else -diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h -index 4edf9057fa79d..b7754a1b8d978 100644 ---- a/drivers/mmc/core/card.h -+++ b/drivers/mmc/core/card.h -@@ -280,4 +280,8 @@ static inline int mmc_card_broken_sd_cache(const struct mmc_card *c) - return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE; - } - -+static inline int mmc_card_broken_cache_flush(const struct mmc_card *c) -+{ -+ return c->quirks & MMC_QUIRK_BROKEN_CACHE_FLUSH; -+} - #endif -diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -index 89cd48fcec79f..a46ce0868fe1f 100644 ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -2081,13 +2081,17 @@ static int _mmc_flush_cache(struct mmc_host *host) - { - int err = 0; - -+ if (mmc_card_broken_cache_flush(host->card) && !host->card->written_flag) -+ return 0; -+ - if (_mmc_cache_enabled(host)) { - err = mmc_switch(host->card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_FLUSH_CACHE, 1, - CACHE_FLUSH_TIMEOUT_MS); - if (err) -- pr_err("%s: cache flush error %d\n", -- mmc_hostname(host), err); -+ pr_err("%s: cache flush error %d\n", mmc_hostname(host), err); -+ else -+ host->card->written_flag = false; - } - - return err; -diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h -index 857315f185fcf..ec760ac0b3977 100644 ---- a/drivers/mmc/core/quirks.h -+++ b/drivers/mmc/core/quirks.h -@@ -117,11 +117,12 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = { - MMC_QUIRK_TRIM_BROKEN), - - /* -- * Micron MTFC4GACAJCN-1M advertises TRIM but it does not seems to -- * support being used to offload WRITE_ZEROES. -+ * Micron MTFC4GACAJCN-1M supports TRIM but does not appear to support -+ * WRITE_ZEROES offloading. It also supports caching, but the cache can -+ * only be flushed after a write has occurred. - */ - MMC_FIXUP("Q2J54A", CID_MANFID_MICRON, 0x014e, add_quirk_mmc, -- MMC_QUIRK_TRIM_BROKEN), -+ MMC_QUIRK_TRIM_BROKEN | MMC_QUIRK_BROKEN_CACHE_FLUSH), - - /* - * Some SD cards reports discard support while they don't -diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c -index 0f39f86bd0c26..7e571cc719605 100644 ---- a/drivers/mmc/host/meson-gx-mmc.c -+++ b/drivers/mmc/host/meson-gx-mmc.c -@@ -817,7 +817,6 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) - - cmd_cfg |= FIELD_PREP(CMD_CFG_CMD_INDEX_MASK, cmd->opcode); - cmd_cfg |= CMD_CFG_OWNER; /* owned by CPU */ -- cmd_cfg |= CMD_CFG_ERROR; /* stop in case of error */ - - meson_mmc_set_response_bits(cmd, &cmd_cfg); - -diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c -index c580ba089a261..33d7039c19169 100644 ---- a/drivers/mmc/host/sdhci-pci-gli.c -+++ b/drivers/mmc/host/sdhci-pci-gli.c -@@ -24,6 +24,12 @@ - #define GLI_9750_WT_EN_ON 0x1 - #define GLI_9750_WT_EN_OFF 0x0 - -+#define PCI_GLI_9750_PM_CTRL 0xFC -+#define PCI_GLI_9750_PM_STATE GENMASK(1, 0) -+ -+#define PCI_GLI_9750_CORRERR_MASK 0x214 -+#define PCI_GLI_9750_CORRERR_MASK_REPLAY_TIMER_TIMEOUT BIT(12) -+ - #define SDHCI_GLI_9750_CFG2 0x848 - #define SDHCI_GLI_9750_CFG2_L1DLY GENMASK(28, 24) - #define GLI_9750_CFG2_L1DLY_VALUE 0x1F -@@ -148,6 +154,9 @@ - #define PCI_GLI_9755_PM_CTRL 0xFC - #define PCI_GLI_9755_PM_STATE GENMASK(1, 0) - -+#define PCI_GLI_9755_CORRERR_MASK 0x214 -+#define PCI_GLI_9755_CORRERR_MASK_REPLAY_TIMER_TIMEOUT BIT(12) -+ - #define GLI_MAX_TUNING_LOOP 40 - - /* Genesys Logic chipset */ -@@ -469,8 +478,12 @@ static void sdhci_gl9750_set_clock(struct sdhci_host *host, unsigned int clock) - - static void gl9750_hw_setting(struct sdhci_host *host) - { -+ struct sdhci_pci_slot *slot = sdhci_priv(host); -+ struct pci_dev *pdev; - u32 value; - -+ pdev = slot->chip->pdev; -+ - gl9750_wt_on(host); - - value = sdhci_readl(host, SDHCI_GLI_9750_CFG2); -@@ -480,6 +493,18 @@ static void gl9750_hw_setting(struct sdhci_host *host) - GLI_9750_CFG2_L1DLY_VALUE); - sdhci_writel(host, value, SDHCI_GLI_9750_CFG2); - -+ /* toggle PM state to allow GL9750 to enter ASPM L1.2 */ -+ pci_read_config_dword(pdev, PCI_GLI_9750_PM_CTRL, &value); -+ value |= PCI_GLI_9750_PM_STATE; -+ pci_write_config_dword(pdev, PCI_GLI_9750_PM_CTRL, value); -+ value &= ~PCI_GLI_9750_PM_STATE; -+ pci_write_config_dword(pdev, PCI_GLI_9750_PM_CTRL, value); -+ -+ /* mask the replay timer timeout of AER */ -+ pci_read_config_dword(pdev, PCI_GLI_9750_CORRERR_MASK, &value); -+ value |= PCI_GLI_9750_CORRERR_MASK_REPLAY_TIMER_TIMEOUT; -+ pci_write_config_dword(pdev, PCI_GLI_9750_CORRERR_MASK, value); -+ - gl9750_wt_off(host); - } - -@@ -689,6 +714,11 @@ static void gl9755_hw_setting(struct sdhci_pci_slot *slot) - value &= ~PCI_GLI_9755_PM_STATE; - pci_write_config_dword(pdev, PCI_GLI_9755_PM_CTRL, value); - -+ /* mask the replay timer timeout of AER */ -+ pci_read_config_dword(pdev, PCI_GLI_9755_CORRERR_MASK, &value); -+ value |= PCI_GLI_9755_CORRERR_MASK_REPLAY_TIMER_TIMEOUT; -+ pci_write_config_dword(pdev, PCI_GLI_9755_CORRERR_MASK, value); -+ - gl9755_wt_off(pdev); - } - -diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c -index 8e22b375247ef..c16dbe64859e6 100644 ---- a/drivers/mmc/host/sdhci_am654.c -+++ b/drivers/mmc/host/sdhci_am654.c -@@ -597,7 +597,7 @@ static int sdhci_am654_get_otap_delay(struct sdhci_host *host, - return 0; - } - -- for (i = MMC_TIMING_MMC_HS; i <= MMC_TIMING_MMC_HS400; i++) { -+ for (i = MMC_TIMING_LEGACY; i <= MMC_TIMING_MMC_HS400; i++) { - - ret = device_property_read_u32(dev, td[i].otap_binding, - &sdhci_am654->otap_del_sel[i]); -diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c -index 7dc0e91dabfc7..05ffd5bf5a6f0 100644 ---- a/drivers/mmc/host/vub300.c -+++ b/drivers/mmc/host/vub300.c -@@ -2311,6 +2311,7 @@ static int vub300_probe(struct usb_interface *interface, - vub300->read_only = - (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0; - } else { -+ retval = -EINVAL; - goto error5; - } - usb_set_intfdata(interface, vub300); -diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c -index 54f92d09d9cf4..02aaf09d6f5cd 100644 ---- a/drivers/mtd/chips/cfi_cmdset_0001.c -+++ b/drivers/mtd/chips/cfi_cmdset_0001.c -@@ -421,9 +421,25 @@ read_pri_intelext(struct map_info *map, __u16 adr) - extra_size = 0; - - /* Protection Register info */ -- if (extp->NumProtectionFields) -+ if (extp->NumProtectionFields) { -+ struct cfi_intelext_otpinfo *otp = -+ (struct cfi_intelext_otpinfo *)&extp->extra[0]; -+ - extra_size += (extp->NumProtectionFields - 1) * -- sizeof(struct cfi_intelext_otpinfo); -+ sizeof(struct cfi_intelext_otpinfo); -+ -+ if (extp_size >= sizeof(*extp) + extra_size) { -+ int i; -+ -+ /* Do some byteswapping if necessary */ -+ for (i = 0; i < extp->NumProtectionFields - 1; i++) { -+ otp->ProtRegAddr = le32_to_cpu(otp->ProtRegAddr); -+ otp->FactGroups = le16_to_cpu(otp->FactGroups); -+ otp->UserGroups = le16_to_cpu(otp->UserGroups); -+ otp++; -+ } -+ } -+ } - } - - if (extp->MinorVersion >= '1') { -diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c -index 6f4cea81f97c0..1f8a33fb84607 100644 ---- a/drivers/mtd/nand/raw/intel-nand-controller.c -+++ b/drivers/mtd/nand/raw/intel-nand-controller.c -@@ -619,6 +619,11 @@ static int ebu_nand_probe(struct platform_device *pdev) - ebu_host->cs_num = cs; - - resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs); -+ if (!resname) { -+ ret = -ENOMEM; -+ goto err_of_node_put; -+ } -+ - ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev, - resname); - if (IS_ERR(ebu_host->cs[cs].chipaddr)) { -@@ -655,6 +660,11 @@ static int ebu_nand_probe(struct platform_device *pdev) - } - - resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", cs); -+ if (!resname) { -+ ret = -ENOMEM; -+ goto err_cleanup_dma; -+ } -+ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname); - if (!res) { - ret = -EINVAL; -diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c -index ac4947f720478..0aeac8ccbd0ee 100644 ---- a/drivers/mtd/nand/raw/meson_nand.c -+++ b/drivers/mtd/nand/raw/meson_nand.c -@@ -1021,6 +1021,9 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc) - init.name = devm_kasprintf(nfc->dev, - GFP_KERNEL, "%s#div", - dev_name(nfc->dev)); -+ if (!init.name) -+ return -ENOMEM; -+ - init.ops = &clk_divider_ops; - nfc_divider_parent_data[0].fw_name = "device"; - init.parent_data = nfc_divider_parent_data; -diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c -index a9b9031ce6167..d33030b68ac44 100644 ---- a/drivers/mtd/nand/raw/tegra_nand.c -+++ b/drivers/mtd/nand/raw/tegra_nand.c -@@ -1197,6 +1197,10 @@ static int tegra_nand_probe(struct platform_device *pdev) - init_completion(&ctrl->dma_complete); - - ctrl->irq = platform_get_irq(pdev, 0); -+ if (ctrl->irq < 0) { -+ err = ctrl->irq; -+ goto err_put_pm; -+ } - err = devm_request_irq(&pdev->dev, ctrl->irq, tegra_nand_irq, 0, - dev_name(&pdev->dev), ctrl); - if (err) { -diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c -index b170a3d8d007e..710734a5af9bf 100644 ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -1503,6 +1503,10 @@ done: - static void bond_setup_by_slave(struct net_device *bond_dev, - struct net_device *slave_dev) - { -+ bool was_up = !!(bond_dev->flags & IFF_UP); -+ -+ dev_close(bond_dev); -+ - bond_dev->header_ops = slave_dev->header_ops; - - bond_dev->type = slave_dev->type; -@@ -1517,6 +1521,8 @@ static void bond_setup_by_slave(struct net_device *bond_dev, - bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); - bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); - } -+ if (was_up) -+ dev_open(bond_dev, NULL); - } - - /* On bonding slaves other than the currently active slave, suppress -diff --git a/drivers/net/dsa/lan9303_mdio.c b/drivers/net/dsa/lan9303_mdio.c -index 4f33369a2de52..47484f55e2aba 100644 ---- a/drivers/net/dsa/lan9303_mdio.c -+++ b/drivers/net/dsa/lan9303_mdio.c -@@ -32,7 +32,7 @@ static int lan9303_mdio_write(void *ctx, uint32_t reg, uint32_t val) - struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx; - - reg <<= 2; /* reg num to offset */ -- mutex_lock(&sw_dev->device->bus->mdio_lock); -+ mutex_lock_nested(&sw_dev->device->bus->mdio_lock, MDIO_MUTEX_NESTED); - lan9303_mdio_real_write(sw_dev->device, reg, val & 0xffff); - lan9303_mdio_real_write(sw_dev->device, reg + 2, (val >> 16) & 0xffff); - mutex_unlock(&sw_dev->device->bus->mdio_lock); -@@ -50,7 +50,7 @@ static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val) - struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx; - - reg <<= 2; /* reg num to offset */ -- mutex_lock(&sw_dev->device->bus->mdio_lock); -+ mutex_lock_nested(&sw_dev->device->bus->mdio_lock, MDIO_MUTEX_NESTED); - *val = lan9303_mdio_real_read(sw_dev->device, reg); - *val |= (lan9303_mdio_real_read(sw_dev->device, reg + 2) << 16); - mutex_unlock(&sw_dev->device->bus->mdio_lock); -diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h -index 43d821fe7a542..63ba64dbb7310 100644 ---- a/drivers/net/ethernet/atheros/atl1c/atl1c.h -+++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h -@@ -504,15 +504,12 @@ struct atl1c_rrd_ring { - u16 next_to_use; - u16 next_to_clean; - struct napi_struct napi; -- struct page *rx_page; -- unsigned int rx_page_offset; - }; - - /* board specific private data structure */ - struct atl1c_adapter { - struct net_device *netdev; - struct pci_dev *pdev; -- unsigned int rx_frag_size; - struct atl1c_hw hw; - struct atl1c_hw_stats hw_stats; - struct mii_if_info mii; /* MII interface info */ -diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -index 7762e532c6a4f..6eb86d75955fe 100644 ---- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -@@ -493,15 +493,10 @@ static int atl1c_set_mac_addr(struct net_device *netdev, void *p) - static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, - struct net_device *dev) - { -- unsigned int head_size; - int mtu = dev->mtu; - - adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ? - roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; -- -- head_size = SKB_DATA_ALIGN(adapter->rx_buffer_len + NET_SKB_PAD + NET_IP_ALIGN) + -- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -- adapter->rx_frag_size = roundup_pow_of_two(head_size); - } - - static netdev_features_t atl1c_fix_features(struct net_device *netdev, -@@ -974,7 +969,6 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter) - static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) - { - struct pci_dev *pdev = adapter->pdev; -- int i; - - dma_free_coherent(&pdev->dev, adapter->ring_header.size, - adapter->ring_header.desc, adapter->ring_header.dma); -@@ -987,12 +981,6 @@ static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) - kfree(adapter->tpd_ring[0].buffer_info); - adapter->tpd_ring[0].buffer_info = NULL; - } -- for (i = 0; i < adapter->rx_queue_count; ++i) { -- if (adapter->rrd_ring[i].rx_page) { -- put_page(adapter->rrd_ring[i].rx_page); -- adapter->rrd_ring[i].rx_page = NULL; -- } -- } - } - - /** -@@ -1764,48 +1752,11 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter, - skb_checksum_none_assert(skb); - } - --static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter, -- u32 queue, bool napi_mode) --{ -- struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[queue]; -- struct sk_buff *skb; -- struct page *page; -- -- if (adapter->rx_frag_size > PAGE_SIZE) { -- if (likely(napi_mode)) -- return napi_alloc_skb(&rrd_ring->napi, -- adapter->rx_buffer_len); -- else -- return netdev_alloc_skb_ip_align(adapter->netdev, -- adapter->rx_buffer_len); -- } -- -- page = rrd_ring->rx_page; -- if (!page) { -- page = alloc_page(GFP_ATOMIC); -- if (unlikely(!page)) -- return NULL; -- rrd_ring->rx_page = page; -- rrd_ring->rx_page_offset = 0; -- } -- -- skb = build_skb(page_address(page) + rrd_ring->rx_page_offset, -- adapter->rx_frag_size); -- if (likely(skb)) { -- skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); -- rrd_ring->rx_page_offset += adapter->rx_frag_size; -- if (rrd_ring->rx_page_offset >= PAGE_SIZE) -- rrd_ring->rx_page = NULL; -- else -- get_page(page); -- } -- return skb; --} -- - static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, u32 queue, - bool napi_mode) - { - struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[queue]; -+ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[queue]; - struct pci_dev *pdev = adapter->pdev; - struct atl1c_buffer *buffer_info, *next_info; - struct sk_buff *skb; -@@ -1824,13 +1775,27 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, u32 queue, - while (next_info->flags & ATL1C_BUFFER_FREE) { - rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); - -- skb = atl1c_alloc_skb(adapter, queue, napi_mode); -+ /* When DMA RX address is set to something like -+ * 0x....fc0, it will be very likely to cause DMA -+ * RFD overflow issue. -+ * -+ * To work around it, we apply rx skb with 64 bytes -+ * longer space, and offset the address whenever -+ * 0x....fc0 is detected. -+ */ -+ if (likely(napi_mode)) -+ skb = napi_alloc_skb(&rrd_ring->napi, adapter->rx_buffer_len + 64); -+ else -+ skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len + 64); - if (unlikely(!skb)) { - if (netif_msg_rx_err(adapter)) - dev_warn(&pdev->dev, "alloc rx buffer failed\n"); - break; - } - -+ if (((unsigned long)skb->data & 0xfff) == 0xfc0) -+ skb_reserve(skb, 64); -+ - /* - * Make buffer alignment 2 beyond a 16 byte boundary - * this will result in a 16 byte aligned IP header after -diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c -index fdf10318758b4..7c0b0bc033c9c 100644 ---- a/drivers/net/ethernet/cortina/gemini.c -+++ b/drivers/net/ethernet/cortina/gemini.c -@@ -432,8 +432,8 @@ static const struct gmac_max_framelen gmac_maxlens[] = { - .val = CONFIG0_MAXLEN_1536, - }, - { -- .max_l3_len = 1542, -- .val = CONFIG0_MAXLEN_1542, -+ .max_l3_len = 1548, -+ .val = CONFIG0_MAXLEN_1548, - }, - { - .max_l3_len = 9212, -@@ -1145,6 +1145,7 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, - dma_addr_t mapping; - unsigned short mtu; - void *buffer; -+ int ret; - - mtu = ETH_HLEN; - mtu += netdev->mtu; -@@ -1159,9 +1160,30 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, - word3 |= mtu; - } - -- if (skb->ip_summed != CHECKSUM_NONE) { -+ if (skb->len >= ETH_FRAME_LEN) { -+ /* Hardware offloaded checksumming isn't working on frames -+ * bigger than 1514 bytes. A hypothesis about this is that the -+ * checksum buffer is only 1518 bytes, so when the frames get -+ * bigger they get truncated, or the last few bytes get -+ * overwritten by the FCS. -+ * -+ * Just use software checksumming and bypass on bigger frames. -+ */ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) { -+ ret = skb_checksum_help(skb); -+ if (ret) -+ return ret; -+ } -+ word1 |= TSS_BYPASS_BIT; -+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { - int tcp = 0; - -+ /* We do not switch off the checksumming on non TCP/UDP -+ * frames: as is shown from tests, the checksumming engine -+ * is smart enough to see that a frame is not actually TCP -+ * or UDP and then just pass it through without any changes -+ * to the frame. -+ */ - if (skb->protocol == htons(ETH_P_IP)) { - word1 |= TSS_IP_CHKSUM_BIT; - tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; -@@ -1978,15 +2000,6 @@ static int gmac_change_mtu(struct net_device *netdev, int new_mtu) - return 0; - } - --static netdev_features_t gmac_fix_features(struct net_device *netdev, -- netdev_features_t features) --{ -- if (netdev->mtu + ETH_HLEN + VLAN_HLEN > MTU_SIZE_BIT_MASK) -- features &= ~GMAC_OFFLOAD_FEATURES; -- -- return features; --} -- - static int gmac_set_features(struct net_device *netdev, - netdev_features_t features) - { -@@ -2212,7 +2225,6 @@ static const struct net_device_ops gmac_351x_ops = { - .ndo_set_mac_address = gmac_set_mac_address, - .ndo_get_stats64 = gmac_get_stats64, - .ndo_change_mtu = gmac_change_mtu, -- .ndo_fix_features = gmac_fix_features, - .ndo_set_features = gmac_set_features, - }; - -@@ -2464,11 +2476,12 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev) - - netdev->hw_features = GMAC_OFFLOAD_FEATURES; - netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; -- /* We can handle jumbo frames up to 10236 bytes so, let's accept -- * payloads of 10236 bytes minus VLAN and ethernet header -+ /* We can receive jumbo frames up to 10236 bytes but only -+ * transmit 2047 bytes so, let's accept payloads of 2047 -+ * bytes minus VLAN and ethernet header - */ - netdev->min_mtu = ETH_MIN_MTU; -- netdev->max_mtu = 10236 - VLAN_ETH_HLEN; -+ netdev->max_mtu = MTU_SIZE_BIT_MASK - VLAN_ETH_HLEN; - - port->freeq_refill = 0; - netif_napi_add(netdev, &port->napi, gmac_napi_poll); -diff --git a/drivers/net/ethernet/cortina/gemini.h b/drivers/net/ethernet/cortina/gemini.h -index 9fdf77d5eb374..24bb989981f23 100644 ---- a/drivers/net/ethernet/cortina/gemini.h -+++ b/drivers/net/ethernet/cortina/gemini.h -@@ -502,7 +502,7 @@ union gmac_txdesc_3 { - #define SOF_BIT 0x80000000 - #define EOF_BIT 0x40000000 - #define EOFIE_BIT BIT(29) --#define MTU_SIZE_BIT_MASK 0x1fff -+#define MTU_SIZE_BIT_MASK 0x7ff /* Max MTU 2047 bytes */ - - /* GMAC Tx Descriptor */ - struct gmac_txdesc { -@@ -787,7 +787,7 @@ union gmac_config0 { - #define CONFIG0_MAXLEN_1536 0 - #define CONFIG0_MAXLEN_1518 1 - #define CONFIG0_MAXLEN_1522 2 --#define CONFIG0_MAXLEN_1542 3 -+#define CONFIG0_MAXLEN_1548 3 - #define CONFIG0_MAXLEN_9k 4 /* 9212 */ - #define CONFIG0_MAXLEN_10k 5 /* 10236 */ - #define CONFIG0_MAXLEN_1518__6 6 -diff --git a/drivers/net/ethernet/engleder/tsnep.h b/drivers/net/ethernet/engleder/tsnep.h -index 09a723b827c77..0a0d3d7ba63b3 100644 ---- a/drivers/net/ethernet/engleder/tsnep.h -+++ b/drivers/net/ethernet/engleder/tsnep.h -@@ -123,7 +123,7 @@ struct tsnep_rx { - - struct tsnep_queue { - struct tsnep_adapter *adapter; -- char name[IFNAMSIZ + 9]; -+ char name[IFNAMSIZ + 16]; - - struct tsnep_tx *tx; - struct tsnep_rx *rx; -diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c -index 2be518db04270..c86dfbce787f1 100644 ---- a/drivers/net/ethernet/engleder/tsnep_main.c -+++ b/drivers/net/ethernet/engleder/tsnep_main.c -@@ -973,14 +973,14 @@ static int tsnep_request_irq(struct tsnep_queue *queue, bool first) - dev = queue->adapter; - } else { - if (queue->tx && queue->rx) -- sprintf(queue->name, "%s-txrx-%d", name, -- queue->rx->queue_index); -+ snprintf(queue->name, sizeof(queue->name), "%s-txrx-%d", -+ name, queue->rx->queue_index); - else if (queue->tx) -- sprintf(queue->name, "%s-tx-%d", name, -- queue->tx->queue_index); -+ snprintf(queue->name, sizeof(queue->name), "%s-tx-%d", -+ name, queue->tx->queue_index); - else -- sprintf(queue->name, "%s-rx-%d", name, -- queue->rx->queue_index); -+ snprintf(queue->name, sizeof(queue->name), "%s-rx-%d", -+ name, queue->rx->queue_index); - handler = tsnep_irq_txrx; - dev = queue; - } -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -index 00eed9835cb55..d2603cfc122c8 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c -@@ -494,11 +494,14 @@ static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector, - } - - sprintf(result[j++], "%d", i); -- sprintf(result[j++], "%s", dim_state_str[dim->state]); -+ sprintf(result[j++], "%s", dim->state < ARRAY_SIZE(dim_state_str) ? -+ dim_state_str[dim->state] : "unknown"); - sprintf(result[j++], "%u", dim->profile_ix); -- sprintf(result[j++], "%s", dim_cqe_mode_str[dim->mode]); -+ sprintf(result[j++], "%s", dim->mode < ARRAY_SIZE(dim_cqe_mode_str) ? -+ dim_cqe_mode_str[dim->mode] : "unknown"); - sprintf(result[j++], "%s", -- dim_tune_stat_str[dim->tune_state]); -+ dim->tune_state < ARRAY_SIZE(dim_tune_stat_str) ? -+ dim_tune_stat_str[dim->tune_state] : "unknown"); - sprintf(result[j++], "%u", dim->steps_left); - sprintf(result[j++], "%u", dim->steps_right); - sprintf(result[j++], "%u", dim->tired); -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -index 04c9baca1b0f8..5ad22b815b2f0 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -@@ -5139,7 +5139,7 @@ static int hns3_init_mac_addr(struct net_device *netdev) - struct hns3_nic_priv *priv = netdev_priv(netdev); - char format_mac_addr[HNAE3_FORMAT_MAC_ADDR_LEN]; - struct hnae3_handle *h = priv->ae_handle; -- u8 mac_addr_temp[ETH_ALEN]; -+ u8 mac_addr_temp[ETH_ALEN] = {0}; - int ret = 0; - - if (h->ae_algo->ops->get_mac_addr) -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -index 3e1d202d60ce1..48b0cb5ec5d29 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c -@@ -74,6 +74,7 @@ static void hclge_sync_fd_table(struct hclge_dev *hdev); - static void hclge_update_fec_stats(struct hclge_dev *hdev); - static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, - int wait_cnt); -+static int hclge_update_port_info(struct hclge_dev *hdev); - - static struct hnae3_ae_algo ae_algo; - -@@ -3141,6 +3142,9 @@ static void hclge_update_link_status(struct hclge_dev *hdev) - - if (state != hdev->hw.mac.link) { - hdev->hw.mac.link = state; -+ if (state == HCLGE_LINK_STATUS_UP) -+ hclge_update_port_info(hdev); -+ - client->ops->link_status_change(handle, state); - hclge_config_mac_tnl_int(hdev, state); - if (rclient && rclient->ops->link_status_change) -@@ -10132,8 +10136,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, - struct hclge_vport_vlan_cfg *vlan, *tmp; - struct hclge_dev *hdev = vport->back; - -- mutex_lock(&hdev->vport_lock); -- - list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) { - if (vlan->vlan_id == vlan_id) { - if (is_write_tbl && vlan->hd_tbl_status) -@@ -10148,8 +10150,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, - break; - } - } -- -- mutex_unlock(&hdev->vport_lock); - } - - void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list) -@@ -10558,11 +10558,16 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, - * handle mailbox. Just record the vlan id, and remove it after - * reset finished. - */ -+ mutex_lock(&hdev->vport_lock); - if ((test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || - test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) && is_kill) { - set_bit(vlan_id, vport->vlan_del_fail_bmap); -+ mutex_unlock(&hdev->vport_lock); - return -EBUSY; -+ } else if (!is_kill && test_bit(vlan_id, vport->vlan_del_fail_bmap)) { -+ clear_bit(vlan_id, vport->vlan_del_fail_bmap); - } -+ mutex_unlock(&hdev->vport_lock); - - /* when port base vlan enabled, we use port base vlan as the vlan - * filter entry. In this case, we don't update vlan filter table -@@ -10577,17 +10582,22 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, - } - - if (!ret) { -- if (!is_kill) -+ if (!is_kill) { - hclge_add_vport_vlan_table(vport, vlan_id, - writen_to_tbl); -- else if (is_kill && vlan_id != 0) -+ } else if (is_kill && vlan_id != 0) { -+ mutex_lock(&hdev->vport_lock); - hclge_rm_vport_vlan_table(vport, vlan_id, false); -+ mutex_unlock(&hdev->vport_lock); -+ } - } else if (is_kill) { - /* when remove hw vlan filter failed, record the vlan id, - * and try to remove it from hw later, to be consistence - * with stack - */ -+ mutex_lock(&hdev->vport_lock); - set_bit(vlan_id, vport->vlan_del_fail_bmap); -+ mutex_unlock(&hdev->vport_lock); - } - - hclge_set_vport_vlan_fltr_change(vport); -@@ -10627,6 +10637,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) - int i, ret, sync_cnt = 0; - u16 vlan_id; - -+ mutex_lock(&hdev->vport_lock); - /* start from vport 1 for PF is always alive */ - for (i = 0; i < hdev->num_alloc_vport; i++) { - struct hclge_vport *vport = &hdev->vport[i]; -@@ -10637,21 +10648,26 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) - ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), - vport->vport_id, vlan_id, - true); -- if (ret && ret != -EINVAL) -+ if (ret && ret != -EINVAL) { -+ mutex_unlock(&hdev->vport_lock); - return; -+ } - - clear_bit(vlan_id, vport->vlan_del_fail_bmap); - hclge_rm_vport_vlan_table(vport, vlan_id, false); - hclge_set_vport_vlan_fltr_change(vport); - - sync_cnt++; -- if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) -+ if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) { -+ mutex_unlock(&hdev->vport_lock); - return; -+ } - - vlan_id = find_first_bit(vport->vlan_del_fail_bmap, - VLAN_N_VID); - } - } -+ mutex_unlock(&hdev->vport_lock); - - hclge_sync_vlan_fltr_state(hdev); - } -@@ -11642,6 +11658,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) - goto err_msi_irq_uninit; - - if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) { -+ clear_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps); - if (hnae3_dev_phy_imp_supported(hdev)) - ret = hclge_update_tp_port_info(hdev); - else -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c -index 72cf5145e15a2..5a978ea101a90 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c -@@ -1258,6 +1258,8 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, - test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) && is_kill) { - set_bit(vlan_id, hdev->vlan_del_fail_bmap); - return -EBUSY; -+ } else if (!is_kill && test_bit(vlan_id, hdev->vlan_del_fail_bmap)) { -+ clear_bit(vlan_id, hdev->vlan_del_fail_bmap); - } - - hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, -@@ -1285,20 +1287,25 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) - int ret, sync_cnt = 0; - u16 vlan_id; - -+ if (bitmap_empty(hdev->vlan_del_fail_bmap, VLAN_N_VID)) -+ return; -+ -+ rtnl_lock(); - vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); - while (vlan_id != VLAN_N_VID) { - ret = hclgevf_set_vlan_filter(handle, htons(ETH_P_8021Q), - vlan_id, true); - if (ret) -- return; -+ break; - - clear_bit(vlan_id, hdev->vlan_del_fail_bmap); - sync_cnt++; - if (sync_cnt >= HCLGEVF_MAX_SYNC_COUNT) -- return; -+ break; - - vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); - } -+ rtnl_unlock(); - } - - static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) -@@ -2028,8 +2035,18 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, - return HCLGEVF_VECTOR0_EVENT_OTHER; - } - -+static void hclgevf_reset_timer(struct timer_list *t) -+{ -+ struct hclgevf_dev *hdev = from_timer(hdev, t, reset_timer); -+ -+ hclgevf_clear_event_cause(hdev, HCLGEVF_VECTOR0_EVENT_RST); -+ hclgevf_reset_task_schedule(hdev); -+} -+ - static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) - { -+#define HCLGEVF_RESET_DELAY 5 -+ - enum hclgevf_evt_cause event_cause; - struct hclgevf_dev *hdev = data; - u32 clearval; -@@ -2041,7 +2058,8 @@ static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) - - switch (event_cause) { - case HCLGEVF_VECTOR0_EVENT_RST: -- hclgevf_reset_task_schedule(hdev); -+ mod_timer(&hdev->reset_timer, -+ jiffies + msecs_to_jiffies(HCLGEVF_RESET_DELAY)); - break; - case HCLGEVF_VECTOR0_EVENT_MBX: - hclgevf_mbx_handler(hdev); -@@ -2987,6 +3005,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) - HCLGEVF_DRIVER_NAME); - - hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); -+ timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); - - return 0; - -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h -index 59ca6c794d6db..d65ace07b4569 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h -@@ -219,6 +219,7 @@ struct hclgevf_dev { - enum hnae3_reset_type reset_level; - unsigned long reset_pending; - enum hnae3_reset_type reset_type; -+ struct timer_list reset_timer; - - #define HCLGEVF_RESET_REQUESTED 0 - #define HCLGEVF_RESET_PENDING 1 -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c -index bbf7b14079de3..85c2a634c8f96 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c -@@ -63,6 +63,9 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1, - i++; - } - -+ /* ensure additional_info will be seen after received_resp */ -+ smp_rmb(); -+ - if (i >= HCLGEVF_MAX_TRY_TIMES) { - dev_err(&hdev->pdev->dev, - "VF could not get mbx(%u,%u) resp(=%d) from PF in %d tries\n", -@@ -178,6 +181,10 @@ static void hclgevf_handle_mbx_response(struct hclgevf_dev *hdev, - resp->resp_status = hclgevf_resp_to_errno(resp_status); - memcpy(resp->additional_info, req->msg.resp_data, - HCLGE_MBX_MAX_RESP_DATA_SIZE * sizeof(u8)); -+ -+ /* ensure additional_info will be seen before setting received_resp */ -+ smp_wmb(); -+ - if (match_id) { - /* If match_id is not zero, it means PF support match_id. - * if the match_id is right, VF get the right response, or -diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c -index aca5b72cfeec6..eb4ebaa1c92ff 100644 ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -4730,14 +4730,17 @@ static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset, - u8 *data) - { - if (sset == ETH_SS_STATS) { -+ struct mvneta_port *pp = netdev_priv(netdev); - int i; - - for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++) - memcpy(data + i * ETH_GSTRING_LEN, - mvneta_statistics[i].name, ETH_GSTRING_LEN); - -- data += ETH_GSTRING_LEN * ARRAY_SIZE(mvneta_statistics); -- page_pool_ethtool_stats_get_strings(data); -+ if (!pp->bm_priv) { -+ data += ETH_GSTRING_LEN * ARRAY_SIZE(mvneta_statistics); -+ page_pool_ethtool_stats_get_strings(data); -+ } - } - } - -@@ -4855,8 +4858,10 @@ static void mvneta_ethtool_pp_stats(struct mvneta_port *pp, u64 *data) - struct page_pool_stats stats = {}; - int i; - -- for (i = 0; i < rxq_number; i++) -- page_pool_get_stats(pp->rxqs[i].page_pool, &stats); -+ for (i = 0; i < rxq_number; i++) { -+ if (pp->rxqs[i].page_pool) -+ page_pool_get_stats(pp->rxqs[i].page_pool, &stats); -+ } - - page_pool_ethtool_stats_get(data, &stats); - } -@@ -4872,14 +4877,21 @@ static void mvneta_ethtool_get_stats(struct net_device *dev, - for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++) - *data++ = pp->ethtool_stats[i]; - -- mvneta_ethtool_pp_stats(pp, data); -+ if (!pp->bm_priv) -+ mvneta_ethtool_pp_stats(pp, data); - } - - static int mvneta_ethtool_get_sset_count(struct net_device *dev, int sset) - { -- if (sset == ETH_SS_STATS) -- return ARRAY_SIZE(mvneta_statistics) + -- page_pool_ethtool_stats_get_count(); -+ if (sset == ETH_SS_STATS) { -+ int count = ARRAY_SIZE(mvneta_statistics); -+ struct mvneta_port *pp = netdev_priv(dev); -+ -+ if (!pp->bm_priv) -+ count += page_pool_ethtool_stats_get_count(); -+ -+ return count; -+ } - - return -EOPNOTSUPP; - } -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c -index 1ae15b8536a85..9b1f1369ac4d8 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c -@@ -668,11 +668,11 @@ static int mlx5e_rx_reporter_dump(struct devlink_health_reporter *reporter, - - void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq) - { -- char icosq_str[MLX5E_REPORTER_PER_Q_MAX_LEN] = {}; - char err_str[MLX5E_REPORTER_PER_Q_MAX_LEN]; - struct mlx5e_icosq *icosq = rq->icosq; - struct mlx5e_priv *priv = rq->priv; - struct mlx5e_err_ctx err_ctx = {}; -+ char icosq_str[32] = {}; - - err_ctx.ctx = rq; - err_ctx.recover = mlx5e_rx_reporter_timeout_recover; -@@ -681,7 +681,7 @@ void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq) - if (icosq) - snprintf(icosq_str, sizeof(icosq_str), "ICOSQ: 0x%x, ", icosq->sqn); - snprintf(err_str, sizeof(err_str), -- "RX timeout on channel: %d, %sRQ: 0x%x, CQ: 0x%x", -+ "RX timeout on channel: %d, %s RQ: 0x%x, CQ: 0x%x", - rq->ix, icosq_str, rq->rqn, rq->cq.mcq.cqn); - - mlx5e_health_report(priv, priv->rx_reporter, err_str, &err_ctx); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c -index 83bb0811e7741..4db0483c066a8 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c -@@ -300,9 +300,6 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, - if (err) - goto destroy_neigh_entry; - -- e->encap_size = ipv4_encap_size; -- e->encap_header = encap_header; -- - if (!(nud_state & NUD_VALID)) { - neigh_event_send(attr.n, NULL); - /* the encap entry will be made valid on neigh update event -@@ -322,6 +319,8 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, - goto destroy_neigh_entry; - } - -+ e->encap_size = ipv4_encap_size; -+ e->encap_header = encap_header; - e->flags |= MLX5_ENCAP_ENTRY_VALID; - mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); - mlx5e_route_lookup_ipv4_put(&attr); -@@ -404,16 +403,12 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, - if (err) - goto free_encap; - -- e->encap_size = ipv4_encap_size; -- kfree(e->encap_header); -- e->encap_header = encap_header; -- - if (!(nud_state & NUD_VALID)) { - neigh_event_send(attr.n, NULL); - /* the encap entry will be made valid on neigh update event - * and not used before that. - */ -- goto release_neigh; -+ goto free_encap; - } - - memset(&reformat_params, 0, sizeof(reformat_params)); -@@ -427,6 +422,10 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, - goto free_encap; - } - -+ e->encap_size = ipv4_encap_size; -+ kfree(e->encap_header); -+ e->encap_header = encap_header; -+ - e->flags |= MLX5_ENCAP_ENTRY_VALID; - mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); - mlx5e_route_lookup_ipv4_put(&attr); -@@ -568,9 +567,6 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, - if (err) - goto destroy_neigh_entry; - -- e->encap_size = ipv6_encap_size; -- e->encap_header = encap_header; -- - if (!(nud_state & NUD_VALID)) { - neigh_event_send(attr.n, NULL); - /* the encap entry will be made valid on neigh update event -@@ -590,6 +586,8 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, - goto destroy_neigh_entry; - } - -+ e->encap_size = ipv6_encap_size; -+ e->encap_header = encap_header; - e->flags |= MLX5_ENCAP_ENTRY_VALID; - mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); - mlx5e_route_lookup_ipv6_put(&attr); -@@ -671,16 +669,12 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, - if (err) - goto free_encap; - -- e->encap_size = ipv6_encap_size; -- kfree(e->encap_header); -- e->encap_header = encap_header; -- - if (!(nud_state & NUD_VALID)) { - neigh_event_send(attr.n, NULL); - /* the encap entry will be made valid on neigh update event - * and not used before that. - */ -- goto release_neigh; -+ goto free_encap; - } - - memset(&reformat_params, 0, sizeof(reformat_params)); -@@ -694,6 +688,10 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, - goto free_encap; - } - -+ e->encap_size = ipv6_encap_size; -+ kfree(e->encap_header); -+ e->encap_header = encap_header; -+ - e->flags |= MLX5_ENCAP_ENTRY_VALID; - mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); - mlx5e_route_lookup_ipv6_put(&attr); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -index 1728e197558d0..eeba91d9c5211 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -@@ -43,12 +43,17 @@ void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv, - struct ethtool_drvinfo *drvinfo) - { - struct mlx5_core_dev *mdev = priv->mdev; -+ int count; - - strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); -- snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -- "%d.%d.%04d (%.16s)", -- fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev), -- mdev->board_id); -+ count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -+ "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), -+ fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); -+ if (count == sizeof(drvinfo->fw_version)) -+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -+ "%d.%d.%04d", fw_rev_maj(mdev), -+ fw_rev_min(mdev), fw_rev_sub(mdev)); -+ - strscpy(drvinfo->bus_info, dev_name(mdev->device), - sizeof(drvinfo->bus_info)); - } -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -index bd895ef341a0b..2653cb96c3105 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -@@ -69,13 +69,17 @@ static void mlx5e_rep_get_drvinfo(struct net_device *dev, - { - struct mlx5e_priv *priv = netdev_priv(dev); - struct mlx5_core_dev *mdev = priv->mdev; -+ int count; - - strscpy(drvinfo->driver, mlx5e_rep_driver_name, - sizeof(drvinfo->driver)); -- snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -- "%d.%d.%04d (%.16s)", -- fw_rev_maj(mdev), fw_rev_min(mdev), -- fw_rev_sub(mdev), mdev->board_id); -+ count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -+ "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), -+ fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); -+ if (count == sizeof(drvinfo->fw_version)) -+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -+ "%d.%d.%04d", fw_rev_maj(mdev), -+ fw_rev_min(mdev), fw_rev_sub(mdev)); - } - - static const struct counter_desc sw_rep_stats_desc[] = { -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c -index 7ab489520a873..43239555f7850 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c -@@ -3102,7 +3102,7 @@ static struct mlx5_fields fields[] = { - OFFLOAD(DIPV6_31_0, 32, U32_MAX, ip6.daddr.s6_addr32[3], 0, - dst_ipv4_dst_ipv6.ipv6_layout.ipv6[12]), - OFFLOAD(IPV6_HOPLIMIT, 8, U8_MAX, ip6.hop_limit, 0, ttl_hoplimit), -- OFFLOAD(IP_DSCP, 16, 0xc00f, ip6, 0, ip_dscp), -+ OFFLOAD(IP_DSCP, 16, 0x0fc0, ip6, 0, ip_dscp), - - OFFLOAD(TCP_SPORT, 16, U16_MAX, tcp.source, 0, tcp_sport), - OFFLOAD(TCP_DPORT, 16, U16_MAX, tcp.dest, 0, tcp_dport), -@@ -3113,21 +3113,31 @@ static struct mlx5_fields fields[] = { - OFFLOAD(UDP_DPORT, 16, U16_MAX, udp.dest, 0, udp_dport), - }; - --static unsigned long mask_to_le(unsigned long mask, int size) -+static u32 mask_field_get(void *mask, struct mlx5_fields *f) - { -- __be32 mask_be32; -- __be16 mask_be16; -- -- if (size == 32) { -- mask_be32 = (__force __be32)(mask); -- mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); -- } else if (size == 16) { -- mask_be32 = (__force __be32)(mask); -- mask_be16 = *(__be16 *)&mask_be32; -- mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16)); -+ switch (f->field_bsize) { -+ case 32: -+ return be32_to_cpu(*(__be32 *)mask) & f->field_mask; -+ case 16: -+ return be16_to_cpu(*(__be16 *)mask) & (u16)f->field_mask; -+ default: -+ return *(u8 *)mask & (u8)f->field_mask; - } -+} - -- return mask; -+static void mask_field_clear(void *mask, struct mlx5_fields *f) -+{ -+ switch (f->field_bsize) { -+ case 32: -+ *(__be32 *)mask &= ~cpu_to_be32(f->field_mask); -+ break; -+ case 16: -+ *(__be16 *)mask &= ~cpu_to_be16((u16)f->field_mask); -+ break; -+ default: -+ *(u8 *)mask &= ~(u8)f->field_mask; -+ break; -+ } - } - - static int offload_pedit_fields(struct mlx5e_priv *priv, -@@ -3139,11 +3149,12 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, - struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals; - struct pedit_headers_action *hdrs = parse_attr->hdrs; - void *headers_c, *headers_v, *action, *vals_p; -- u32 *s_masks_p, *a_masks_p, s_mask, a_mask; - struct mlx5e_tc_mod_hdr_acts *mod_acts; -- unsigned long mask, field_mask; -+ void *s_masks_p, *a_masks_p; - int i, first, last, next_z; - struct mlx5_fields *f; -+ unsigned long mask; -+ u32 s_mask, a_mask; - u8 cmd; - - mod_acts = &parse_attr->mod_hdr_acts; -@@ -3159,15 +3170,11 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, - bool skip; - - f = &fields[i]; -- /* avoid seeing bits set from previous iterations */ -- s_mask = 0; -- a_mask = 0; -- - s_masks_p = (void *)set_masks + f->offset; - a_masks_p = (void *)add_masks + f->offset; - -- s_mask = *s_masks_p & f->field_mask; -- a_mask = *a_masks_p & f->field_mask; -+ s_mask = mask_field_get(s_masks_p, f); -+ a_mask = mask_field_get(a_masks_p, f); - - if (!s_mask && !a_mask) /* nothing to offload here */ - continue; -@@ -3194,22 +3201,20 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, - match_mask, f->field_bsize)) - skip = true; - /* clear to denote we consumed this field */ -- *s_masks_p &= ~f->field_mask; -+ mask_field_clear(s_masks_p, f); - } else { - cmd = MLX5_ACTION_TYPE_ADD; - mask = a_mask; - vals_p = (void *)add_vals + f->offset; - /* add 0 is no change */ -- if ((*(u32 *)vals_p & f->field_mask) == 0) -+ if (!mask_field_get(vals_p, f)) - skip = true; - /* clear to denote we consumed this field */ -- *a_masks_p &= ~f->field_mask; -+ mask_field_clear(a_masks_p, f); - } - if (skip) - continue; - -- mask = mask_to_le(mask, f->field_bsize); -- - first = find_first_bit(&mask, f->field_bsize); - next_z = find_next_zero_bit(&mask, f->field_bsize, first); - last = find_last_bit(&mask, f->field_bsize); -@@ -3236,10 +3241,9 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, - MLX5_SET(set_action_in, action, field, f->field); - - if (cmd == MLX5_ACTION_TYPE_SET) { -+ unsigned long field_mask = f->field_mask; - int start; - -- field_mask = mask_to_le(f->field_mask, f->field_bsize); -- - /* if field is bit sized it can start not from first bit */ - start = find_first_bit(&field_mask, f->field_bsize); - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index d14706265d9cb..770391cefb4e4 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -614,6 +614,7 @@ struct rtl8169_private { - - unsigned supports_gmii:1; - unsigned aspm_manageable:1; -+ unsigned dash_enabled:1; - dma_addr_t counters_phys_addr; - struct rtl8169_counters *counters; - struct rtl8169_tc_offsets tc_offset; -@@ -1186,14 +1187,26 @@ static bool r8168ep_check_dash(struct rtl8169_private *tp) - return r8168ep_ocp_read(tp, 0x128) & BIT(0); - } - --static enum rtl_dash_type rtl_check_dash(struct rtl8169_private *tp) -+static bool rtl_dash_is_enabled(struct rtl8169_private *tp) -+{ -+ switch (tp->dash_type) { -+ case RTL_DASH_DP: -+ return r8168dp_check_dash(tp); -+ case RTL_DASH_EP: -+ return r8168ep_check_dash(tp); -+ default: -+ return false; -+ } -+} -+ -+static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp) - { - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_28: - case RTL_GIGA_MAC_VER_31: -- return r8168dp_check_dash(tp) ? RTL_DASH_DP : RTL_DASH_NONE; -+ return RTL_DASH_DP; - case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53: -- return r8168ep_check_dash(tp) ? RTL_DASH_EP : RTL_DASH_NONE; -+ return RTL_DASH_EP; - default: - return RTL_DASH_NONE; - } -@@ -1383,7 +1396,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) - - device_set_wakeup_enable(tp_to_dev(tp), wolopts); - -- if (tp->dash_type == RTL_DASH_NONE) { -+ if (!tp->dash_enabled) { - rtl_set_d3_pll_down(tp, !wolopts); - tp->dev->wol_enabled = wolopts ? 1 : 0; - } -@@ -2442,7 +2455,7 @@ static void rtl_wol_enable_rx(struct rtl8169_private *tp) - - static void rtl_prepare_power_down(struct rtl8169_private *tp) - { -- if (tp->dash_type != RTL_DASH_NONE) -+ if (tp->dash_enabled) - return; - - if (tp->mac_version == RTL_GIGA_MAC_VER_32 || -@@ -2516,9 +2529,7 @@ static void rtl_set_rx_mode(struct net_device *dev) - rx_mode &= ~AcceptMulticast; - } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || - dev->flags & IFF_ALLMULTI || -- tp->mac_version == RTL_GIGA_MAC_VER_35 || -- tp->mac_version == RTL_GIGA_MAC_VER_46 || -- tp->mac_version == RTL_GIGA_MAC_VER_48) { -+ tp->mac_version == RTL_GIGA_MAC_VER_35) { - /* accept all multicasts */ - } else if (netdev_mc_empty(dev)) { - rx_mode &= ~AcceptMulticast; -@@ -4613,10 +4624,16 @@ static void rtl8169_down(struct rtl8169_private *tp) - rtl8169_cleanup(tp); - rtl_disable_exit_l1(tp); - rtl_prepare_power_down(tp); -+ -+ if (tp->dash_type != RTL_DASH_NONE) -+ rtl8168_driver_stop(tp); - } - - static void rtl8169_up(struct rtl8169_private *tp) - { -+ if (tp->dash_type != RTL_DASH_NONE) -+ rtl8168_driver_start(tp); -+ - pci_set_master(tp->pci_dev); - phy_init_hw(tp->phydev); - phy_resume(tp->phydev); -@@ -4834,7 +4851,7 @@ static int rtl8169_runtime_idle(struct device *device) - { - struct rtl8169_private *tp = dev_get_drvdata(device); - -- if (tp->dash_type != RTL_DASH_NONE) -+ if (tp->dash_enabled) - return -EBUSY; - - if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev)) -@@ -4860,8 +4877,7 @@ static void rtl_shutdown(struct pci_dev *pdev) - /* Restore original MAC address */ - rtl_rar_set(tp, tp->dev->perm_addr); - -- if (system_state == SYSTEM_POWER_OFF && -- tp->dash_type == RTL_DASH_NONE) { -+ if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) { - pci_wake_from_d3(pdev, tp->saved_wolopts); - pci_set_power_state(pdev, PCI_D3hot); - } -@@ -5217,7 +5233,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1); - tp->aspm_manageable = !rc; - -- tp->dash_type = rtl_check_dash(tp); -+ tp->dash_type = rtl_get_dash_type(tp); -+ tp->dash_enabled = rtl_dash_is_enabled(tp); - - tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; - -@@ -5287,7 +5304,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - /* configure chip for default features */ - rtl8169_set_features(dev, dev->features); - -- if (tp->dash_type == RTL_DASH_NONE) { -+ if (!tp->dash_enabled) { - rtl_set_d3_pll_down(tp, true); - } else { - rtl_set_d3_pll_down(tp, false); -@@ -5327,7 +5344,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - "ok" : "ko"); - - if (tp->dash_type != RTL_DASH_NONE) { -- netdev_info(dev, "DASH enabled\n"); -+ netdev_info(dev, "DASH %s\n", -+ tp->dash_enabled ? "enabled" : "disabled"); - rtl8168_driver_start(tp); - } - -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index 1559a4dafd413..9f76c2f7d513b 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -5198,6 +5198,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - - dma_dir = page_pool_get_dma_dir(rx_q->page_pool); - buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; -+ limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit); - - if (netif_msg_rx_status(priv)) { - void *rx_head; -@@ -5233,10 +5234,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - len = 0; - } - -+read_again: - if (count >= limit) - break; - --read_again: - buf1_len = 0; - buf2_len = 0; - entry = next_entry; -diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c -index b29b7d97b7739..d447f3076e24a 100644 ---- a/drivers/net/ipvlan/ipvlan_core.c -+++ b/drivers/net/ipvlan/ipvlan_core.c -@@ -411,7 +411,7 @@ struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h, - return addr; - } - --static int ipvlan_process_v4_outbound(struct sk_buff *skb) -+static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb) - { - const struct iphdr *ip4h = ip_hdr(skb); - struct net_device *dev = skb->dev; -@@ -453,13 +453,11 @@ out: - } - - #if IS_ENABLED(CONFIG_IPV6) --static int ipvlan_process_v6_outbound(struct sk_buff *skb) -+ -+static noinline_for_stack int -+ipvlan_route_v6_outbound(struct net_device *dev, struct sk_buff *skb) - { - const struct ipv6hdr *ip6h = ipv6_hdr(skb); -- struct net_device *dev = skb->dev; -- struct net *net = dev_net(dev); -- struct dst_entry *dst; -- int err, ret = NET_XMIT_DROP; - struct flowi6 fl6 = { - .flowi6_oif = dev->ifindex, - .daddr = ip6h->daddr, -@@ -469,27 +467,38 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) - .flowi6_mark = skb->mark, - .flowi6_proto = ip6h->nexthdr, - }; -+ struct dst_entry *dst; -+ int err; - -- dst = ip6_route_output(net, NULL, &fl6); -- if (dst->error) { -- ret = dst->error; -+ dst = ip6_route_output(dev_net(dev), NULL, &fl6); -+ err = dst->error; -+ if (err) { - dst_release(dst); -- goto err; -+ return err; - } - skb_dst_set(skb, dst); -+ return 0; -+} -+ -+static int ipvlan_process_v6_outbound(struct sk_buff *skb) -+{ -+ struct net_device *dev = skb->dev; -+ int err, ret = NET_XMIT_DROP; -+ -+ err = ipvlan_route_v6_outbound(dev, skb); -+ if (unlikely(err)) { -+ DEV_STATS_INC(dev, tx_errors); -+ kfree_skb(skb); -+ return err; -+ } - - memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); - -- err = ip6_local_out(net, skb->sk, skb); -+ err = ip6_local_out(dev_net(dev), skb->sk, skb); - if (unlikely(net_xmit_eval(err))) - DEV_STATS_INC(dev, tx_errors); - else - ret = NET_XMIT_SUCCESS; -- goto out; --err: -- DEV_STATS_INC(dev, tx_errors); -- kfree_skb(skb); --out: - return ret; - } - #else -diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c -index b8cc55b2d721c..012830d12fde6 100644 ---- a/drivers/net/macvlan.c -+++ b/drivers/net/macvlan.c -@@ -771,7 +771,7 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change) - if (dev->flags & IFF_UP) { - if (change & IFF_ALLMULTI) - dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1); -- if (change & IFF_PROMISC) -+ if (!macvlan_passthru(vlan->port) && change & IFF_PROMISC) - dev_set_promiscuity(lowerdev, - dev->flags & IFF_PROMISC ? 1 : -1); - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index 5b064a1de92f0..fc58e4afb38dd 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1479,6 +1479,7 @@ struct phylink *phylink_create(struct phylink_config *config, - pl->config = config; - if (config->type == PHYLINK_NETDEV) { - pl->netdev = to_net_dev(config->dev); -+ netif_carrier_off(pl->netdev); - } else if (config->type == PHYLINK_DEV) { - pl->dev = config->dev; - } else { -diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c -index 18283b7b94bcd..94ef6f9ca5103 100644 ---- a/drivers/net/ppp/ppp_synctty.c -+++ b/drivers/net/ppp/ppp_synctty.c -@@ -462,6 +462,10 @@ ppp_sync_ioctl(struct ppp_channel *chan, unsigned int cmd, unsigned long arg) - case PPPIOCSMRU: - if (get_user(val, (int __user *) argp)) - break; -+ if (val > U16_MAX) { -+ err = -EINVAL; -+ break; -+ } - if (val < PPP_MRU) - val = PPP_MRU; - ap->mru = val; -@@ -697,7 +701,7 @@ ppp_sync_input(struct syncppp *ap, const unsigned char *buf, - - /* strip address/control field if present */ - p = skb->data; -- if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { -+ if (skb->len >= 2 && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { - /* chop off address/control */ - if (skb->len < 3) - goto err; -diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c -index c861e66ef6bc5..41f387e15dcd0 100644 ---- a/drivers/net/wireless/ath/ath10k/debug.c -+++ b/drivers/net/wireless/ath/ath10k/debug.c -@@ -1139,7 +1139,7 @@ void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, - u32 sset, u8 *data) - { - if (sset == ETH_SS_STATS) -- memcpy(data, *ath10k_gstrings_stats, -+ memcpy(data, ath10k_gstrings_stats, - sizeof(ath10k_gstrings_stats)); - } - -diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c -index cfcb759a87dea..4b7266d928470 100644 ---- a/drivers/net/wireless/ath/ath10k/snoc.c -+++ b/drivers/net/wireless/ath/ath10k/snoc.c -@@ -828,12 +828,20 @@ static void ath10k_snoc_hif_get_default_pipe(struct ath10k *ar, - - static inline void ath10k_snoc_irq_disable(struct ath10k *ar) - { -- ath10k_ce_disable_interrupts(ar); -+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); -+ int id; -+ -+ for (id = 0; id < CE_COUNT_MAX; id++) -+ disable_irq(ar_snoc->ce_irqs[id].irq_line); - } - - static inline void ath10k_snoc_irq_enable(struct ath10k *ar) - { -- ath10k_ce_enable_interrupts(ar); -+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); -+ int id; -+ -+ for (id = 0; id < CE_COUNT_MAX; id++) -+ enable_irq(ar_snoc->ce_irqs[id].irq_line); - } - - static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe) -@@ -1089,6 +1097,8 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar, - goto err_free_rri; - } - -+ ath10k_ce_enable_interrupts(ar); -+ - return 0; - - err_free_rri: -@@ -1252,8 +1262,8 @@ static int ath10k_snoc_request_irq(struct ath10k *ar) - - for (id = 0; id < CE_COUNT_MAX; id++) { - ret = request_irq(ar_snoc->ce_irqs[id].irq_line, -- ath10k_snoc_per_engine_handler, 0, -- ce_name[id], ar); -+ ath10k_snoc_per_engine_handler, -+ IRQF_NO_AUTOEN, ce_name[id], ar); - if (ret) { - ath10k_err(ar, - "failed to register IRQ handler for CE %d: %d\n", -diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c -index 38be646bc0214..b1067bcdf88a5 100644 ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1621,14 +1621,20 @@ static void ath11k_htt_pktlog(struct ath11k_base *ab, struct sk_buff *skb) - u8 pdev_id; - - pdev_id = FIELD_GET(HTT_T2H_PPDU_STATS_INFO_PDEV_ID, data->hdr); -+ -+ rcu_read_lock(); -+ - ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id); - if (!ar) { - ath11k_warn(ab, "invalid pdev id %d on htt pktlog\n", pdev_id); -- return; -+ goto out; - } - - trace_ath11k_htt_pktlog(ar, data->payload, hdr->size, - ar->ab->pktlog_defs_checksum); -+ -+out: -+ rcu_read_unlock(); - } - - static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab, -diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c -index 3e0a47f4a3ebd..142b201052660 100644 ---- a/drivers/net/wireless/ath/ath11k/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -7729,6 +7729,8 @@ ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base *ab, struct sk_buff - ev->detector_id, ev->segment_id, ev->timestamp, ev->is_chirp, - ev->freq_offset, ev->sidx); - -+ rcu_read_lock(); -+ - ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id); - - if (!ar) { -@@ -7746,6 +7748,8 @@ ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base *ab, struct sk_buff - ieee80211_radar_detected(ar->hw); - - exit: -+ rcu_read_unlock(); -+ - kfree(tb); - } - -@@ -7775,15 +7779,19 @@ ath11k_wmi_pdev_temperature_event(struct ath11k_base *ab, - ath11k_dbg(ab, ATH11K_DBG_WMI, - "pdev temperature ev temp %d pdev_id %d\n", ev->temp, ev->pdev_id); - -+ rcu_read_lock(); -+ - ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id); - if (!ar) { - ath11k_warn(ab, "invalid pdev id in pdev temperature ev %d", ev->pdev_id); -- kfree(tb); -- return; -+ goto exit; - } - - ath11k_thermal_event_temperature(ar, ev->temp); - -+exit: -+ rcu_read_unlock(); -+ - kfree(tb); - } - -@@ -7993,12 +8001,13 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab, - return; - } - -+ rcu_read_lock(); -+ - arvif = ath11k_mac_get_arvif_by_vdev_id(ab, ev->vdev_id); - if (!arvif) { - ath11k_warn(ab, "failed to get arvif for vdev_id:%d\n", - ev->vdev_id); -- kfree(tb); -- return; -+ goto exit; - } - - ath11k_dbg(ab, ATH11K_DBG_WMI, "wmi gtk offload event refresh_cnt %d\n", -@@ -8015,6 +8024,8 @@ static void ath11k_wmi_gtk_offload_status_event(struct ath11k_base *ab, - - ieee80211_gtk_rekey_notify(arvif->vif, arvif->bssid, - (void *)&replay_ctr_be, GFP_ATOMIC); -+exit: -+ rcu_read_unlock(); - - kfree(tb); - } -diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c -index fb7a2952d0ce8..d9bac1c343490 100644 ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1333,7 +1333,7 @@ void ath9k_get_et_strings(struct ieee80211_hw *hw, - u32 sset, u8 *data) - { - if (sset == ETH_SS_STATS) -- memcpy(data, *ath9k_gstrings_stats, -+ memcpy(data, ath9k_gstrings_stats, - sizeof(ath9k_gstrings_stats)); - } - -diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c -index c55aab01fff5d..e79bbcd3279af 100644 ---- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c -@@ -428,7 +428,7 @@ void ath9k_htc_get_et_strings(struct ieee80211_hw *hw, - u32 sset, u8 *data) - { - if (sset == ETH_SS_STATS) -- memcpy(data, *ath9k_htc_gstrings_stats, -+ memcpy(data, ath9k_htc_gstrings_stats, - sizeof(ath9k_htc_gstrings_stats)); - } - -diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -index 618355ecd9d7b..caaf4d52e2c64 100644 ---- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -@@ -524,16 +524,20 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, - flags |= IWL_TX_FLAGS_ENCRYPT_DIS; - - /* -- * For data packets rate info comes from the fw. Only -- * set rate/antenna during connection establishment or in case -- * no station is given. -+ * For data and mgmt packets rate info comes from the fw. Only -+ * set rate/antenna for injected frames with fixed rate, or -+ * when no sta is given. - */ -- if (!sta || !ieee80211_is_data(hdr->frame_control) || -- mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { -+ if (unlikely(!sta || -+ info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) { - flags |= IWL_TX_FLAGS_CMD_RATE; - rate_n_flags = - iwl_mvm_get_tx_rate_n_flags(mvm, info, sta, - hdr->frame_control); -+ } else if (!ieee80211_is_data(hdr->frame_control) || -+ mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { -+ /* These are important frames */ -+ flags |= IWL_TX_FLAGS_HIGH_PRI; - } - - if (mvm->trans->trans_cfg->device_family >= -diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c -index db70cef854bc4..abcd165a62cfe 100644 ---- a/drivers/net/wireless/mac80211_hwsim.c -+++ b/drivers/net/wireless/mac80211_hwsim.c -@@ -3021,7 +3021,7 @@ static void mac80211_hwsim_get_et_strings(struct ieee80211_hw *hw, - u32 sset, u8 *data) - { - if (sset == ETH_SS_STATS) -- memcpy(data, *mac80211_hwsim_gstrings_stats, -+ memcpy(data, mac80211_hwsim_gstrings_stats, - sizeof(mac80211_hwsim_gstrings_stats)); - } - -diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c -index 58bbf50081e47..9eb115c79c90a 100644 ---- a/drivers/net/wireless/microchip/wilc1000/wlan.c -+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c -@@ -1492,7 +1492,7 @@ int wilc_wlan_init(struct net_device *dev) - } - - if (!wilc->vmm_table) -- wilc->vmm_table = kzalloc(WILC_VMM_TBL_SIZE, GFP_KERNEL); -+ wilc->vmm_table = kcalloc(WILC_VMM_TBL_SIZE, sizeof(u32), GFP_KERNEL); - - if (!wilc->vmm_table) { - ret = -ENOBUFS; -diff --git a/drivers/net/wireless/purelifi/plfxlc/mac.c b/drivers/net/wireless/purelifi/plfxlc/mac.c -index d3cdffbded693..87a4ff888ddd4 100644 ---- a/drivers/net/wireless/purelifi/plfxlc/mac.c -+++ b/drivers/net/wireless/purelifi/plfxlc/mac.c -@@ -666,7 +666,7 @@ static void plfxlc_get_et_strings(struct ieee80211_hw *hw, - u32 sset, u8 *data) - { - if (sset == ETH_SS_STATS) -- memcpy(data, *et_strings, sizeof(et_strings)); -+ memcpy(data, et_strings, sizeof(et_strings)); - } - - static void plfxlc_get_et_stats(struct ieee80211_hw *hw, -diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c -index 6f5e5f0230d39..332bcc0053a5e 100644 ---- a/drivers/parisc/power.c -+++ b/drivers/parisc/power.c -@@ -197,6 +197,14 @@ static struct notifier_block parisc_panic_block = { - .priority = INT_MAX, - }; - -+/* qemu soft power-off function */ -+static int qemu_power_off(struct sys_off_data *data) -+{ -+ /* this turns the system off via SeaBIOS */ -+ gsc_writel(0, (unsigned long) data->cb_data); -+ pdc_soft_power_button(1); -+ return NOTIFY_DONE; -+} - - static int __init power_init(void) - { -@@ -226,7 +234,13 @@ static int __init power_init(void) - soft_power_reg); - } - -- power_task = kthread_run(kpowerswd, (void*)soft_power_reg, KTHREAD_NAME); -+ power_task = NULL; -+ if (running_on_qemu && soft_power_reg) -+ register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT, -+ qemu_power_off, (void *)soft_power_reg); -+ else -+ power_task = kthread_run(kpowerswd, (void*)soft_power_reg, -+ KTHREAD_NAME); - if (IS_ERR(power_task)) { - printk(KERN_ERR DRIVER_NAME ": thread creation failed. Driver not loaded.\n"); - pdc_soft_power_button(0); -diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c -index ec56110055665..e5519978ba475 100644 ---- a/drivers/pci/controller/dwc/pci-exynos.c -+++ b/drivers/pci/controller/dwc/pci-exynos.c -@@ -375,7 +375,7 @@ fail_probe: - return ret; - } - --static int __exit exynos_pcie_remove(struct platform_device *pdev) -+static int exynos_pcie_remove(struct platform_device *pdev) - { - struct exynos_pcie *ep = platform_get_drvdata(pdev); - -@@ -431,7 +431,7 @@ static const struct of_device_id exynos_pcie_of_match[] = { - - static struct platform_driver exynos_pcie_driver = { - .probe = exynos_pcie_probe, -- .remove = __exit_p(exynos_pcie_remove), -+ .remove = exynos_pcie_remove, - .driver = { - .name = "exynos-pcie", - .of_match_table = exynos_pcie_of_match, -diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c -index 78818853af9e4..d2634dafb68e5 100644 ---- a/drivers/pci/controller/dwc/pci-keystone.c -+++ b/drivers/pci/controller/dwc/pci-keystone.c -@@ -1101,7 +1101,7 @@ static const struct of_device_id ks_pcie_of_match[] = { - { }, - }; - --static int __init ks_pcie_probe(struct platform_device *pdev) -+static int ks_pcie_probe(struct platform_device *pdev) - { - const struct dw_pcie_host_ops *host_ops; - const struct dw_pcie_ep_ops *ep_ops; -@@ -1303,7 +1303,7 @@ err_link: - return ret; - } - --static int __exit ks_pcie_remove(struct platform_device *pdev) -+static int ks_pcie_remove(struct platform_device *pdev) - { - struct keystone_pcie *ks_pcie = platform_get_drvdata(pdev); - struct device_link **link = ks_pcie->link; -@@ -1319,9 +1319,9 @@ static int __exit ks_pcie_remove(struct platform_device *pdev) - return 0; - } - --static struct platform_driver ks_pcie_driver __refdata = { -+static struct platform_driver ks_pcie_driver = { - .probe = ks_pcie_probe, -- .remove = __exit_p(ks_pcie_remove), -+ .remove = ks_pcie_remove, - .driver = { - .name = "keystone-pcie", - .of_match_table = ks_pcie_of_match, -diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c -index d09507f822a7d..a824d8e8edb9d 100644 ---- a/drivers/pci/controller/dwc/pcie-kirin.c -+++ b/drivers/pci/controller/dwc/pcie-kirin.c -@@ -742,7 +742,7 @@ err: - return ret; - } - --static int __exit kirin_pcie_remove(struct platform_device *pdev) -+static int kirin_pcie_remove(struct platform_device *pdev) - { - struct kirin_pcie *kirin_pcie = platform_get_drvdata(pdev); - -@@ -819,7 +819,7 @@ static int kirin_pcie_probe(struct platform_device *pdev) - - static struct platform_driver kirin_pcie_driver = { - .probe = kirin_pcie_probe, -- .remove = __exit_p(kirin_pcie_remove), -+ .remove = kirin_pcie_remove, - .driver = { - .name = "kirin-pcie", - .of_match_table = kirin_pcie_match, -diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c -index 2241029537a03..5d1ae2706f6ea 100644 ---- a/drivers/pci/controller/dwc/pcie-tegra194.c -+++ b/drivers/pci/controller/dwc/pcie-tegra194.c -@@ -9,6 +9,7 @@ - * Author: Vidya Sagar - */ - -+#include - #include - #include - #include -@@ -324,8 +325,7 @@ static void apply_bad_link_workaround(struct dw_pcie_rp *pp) - */ - val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA); - if (val & PCI_EXP_LNKSTA_LBMS) { -- current_link_width = (val & PCI_EXP_LNKSTA_NLW) >> -- PCI_EXP_LNKSTA_NLW_SHIFT; -+ current_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val); - if (pcie->init_link_width > current_link_width) { - dev_warn(pci->dev, "PCIe link is bad, width reduced\n"); - val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + -@@ -740,8 +740,7 @@ static void tegra_pcie_enable_system_interrupts(struct dw_pcie_rp *pp) - - val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base + - PCI_EXP_LNKSTA); -- pcie->init_link_width = (val_w & PCI_EXP_LNKSTA_NLW) >> -- PCI_EXP_LNKSTA_NLW_SHIFT; -+ pcie->init_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val_w); - - val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base + - PCI_EXP_LNKCTL); -@@ -900,7 +899,7 @@ static int tegra_pcie_dw_host_init(struct dw_pcie_rp *pp) - /* Configure Max lane width from DT */ - val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP); - val &= ~PCI_EXP_LNKCAP_MLW; -- val |= (pcie->num_lanes << PCI_EXP_LNKSTA_NLW_SHIFT); -+ val |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, pcie->num_lanes); - dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, val); - - /* Clear Slot Clock Configuration bit if SRNS configuration */ -diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c -index 1ced73726a267..668601fd0b296 100644 ---- a/drivers/pci/controller/pci-mvebu.c -+++ b/drivers/pci/controller/pci-mvebu.c -@@ -264,7 +264,7 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) - */ - lnkcap = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP); - lnkcap &= ~PCI_EXP_LNKCAP_MLW; -- lnkcap |= (port->is_x4 ? 4 : 1) << 4; -+ lnkcap |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, port->is_x4 ? 4 : 1); - mvebu_writel(port, lnkcap, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP); - - /* Disable Root Bridge I/O space, memory space and bus mastering. */ -diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c -index 7aa1c20582ab8..2f5eddf03ac6a 100644 ---- a/drivers/pci/pci-acpi.c -+++ b/drivers/pci/pci-acpi.c -@@ -911,7 +911,7 @@ pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) - { - int acpi_state, d_max; - -- if (pdev->no_d3cold) -+ if (pdev->no_d3cold || !pdev->d3cold_allowed) - d_max = ACPI_STATE_D3_HOT; - else - d_max = ACPI_STATE_D3_COLD; -diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c -index dd0d9d9bc5097..df1c44a5c886c 100644 ---- a/drivers/pci/pci-sysfs.c -+++ b/drivers/pci/pci-sysfs.c -@@ -12,7 +12,7 @@ - * Modeled after usb's driverfs.c - */ - -- -+#include - #include - #include - #include -@@ -230,8 +230,7 @@ static ssize_t current_link_width_show(struct device *dev, - if (err) - return -EINVAL; - -- return sysfs_emit(buf, "%u\n", -- (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT); -+ return sysfs_emit(buf, "%u\n", FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat)); - } - static DEVICE_ATTR_RO(current_link_width); - -@@ -530,10 +529,7 @@ static ssize_t d3cold_allowed_store(struct device *dev, - return -EINVAL; - - pdev->d3cold_allowed = !!val; -- if (pdev->d3cold_allowed) -- pci_d3cold_enable(pdev); -- else -- pci_d3cold_disable(pdev); -+ pci_bridge_d3_update(pdev); - - pm_runtime_resume(dev); - -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index 835e9ea14b3a1..8df156c28aade 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -717,15 +717,18 @@ u16 pci_find_vsec_capability(struct pci_dev *dev, u16 vendor, int cap) - { - u16 vsec = 0; - u32 header; -+ int ret; - - if (vendor != dev->vendor) - return 0; - - while ((vsec = pci_find_next_ext_capability(dev, vsec, - PCI_EXT_CAP_ID_VNDR))) { -- if (pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, -- &header) == PCIBIOS_SUCCESSFUL && -- PCI_VNDR_HEADER_ID(header) == cap) -+ ret = pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, &header); -+ if (ret != PCIBIOS_SUCCESSFUL) -+ continue; -+ -+ if (PCI_VNDR_HEADER_ID(header) == cap) - return vsec; - } - -@@ -3710,14 +3713,14 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) - return 0; - - pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap); -- cap &= PCI_REBAR_CAP_SIZES; -+ cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap); - - /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ - if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f && -- bar == 0 && cap == 0x7000) -- cap = 0x3f000; -+ bar == 0 && cap == 0x700) -+ return 0x3f00; - -- return cap >> 4; -+ return cap; - } - EXPORT_SYMBOL(pci_rebar_get_possible_sizes); - -@@ -6135,8 +6138,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev, - pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta); - - next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS]; -- next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >> -- PCI_EXP_LNKSTA_NLW_SHIFT; -+ next_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta); - - next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed); - -@@ -6208,7 +6210,7 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev) - - pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); - if (lnkcap) -- return (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4; -+ return FIELD_GET(PCI_EXP_LNKCAP_MLW, lnkcap); - - return PCIE_LNK_WIDTH_UNKNOWN; - } -diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c -index 7e89cdbd446fc..5d1756f53ba84 100644 ---- a/drivers/pci/pcie/aspm.c -+++ b/drivers/pci/pcie/aspm.c -@@ -1248,6 +1248,8 @@ static ssize_t aspm_attr_store_common(struct device *dev, - link->aspm_disable &= ~ASPM_STATE_L1; - } else { - link->aspm_disable |= state; -+ if (state & ASPM_STATE_L1) -+ link->aspm_disable |= ASPM_STATE_L1SS; - } - - pcie_config_aspm_link(link, policy_to_aspm_state(link)); -diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c -index 0945f50fe94ff..e19b79821dd6d 100644 ---- a/drivers/pci/probe.c -+++ b/drivers/pci/probe.c -@@ -1643,15 +1643,15 @@ static void pci_set_removable(struct pci_dev *dev) - static bool pci_ext_cfg_is_aliased(struct pci_dev *dev) - { - #ifdef CONFIG_PCI_QUIRKS -- int pos; -+ int pos, ret; - u32 header, tmp; - - pci_read_config_dword(dev, PCI_VENDOR_ID, &header); - - for (pos = PCI_CFG_SPACE_SIZE; - pos < PCI_CFG_SPACE_EXP_SIZE; pos += PCI_CFG_SPACE_SIZE) { -- if (pci_read_config_dword(dev, pos, &tmp) != PCIBIOS_SUCCESSFUL -- || header != tmp) -+ ret = pci_read_config_dword(dev, pos, &tmp); -+ if ((ret != PCIBIOS_SUCCESSFUL) || (header != tmp)) - return false; - } - -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index 30e7c627f21a7..48389785d9247 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -5288,7 +5288,7 @@ int pci_dev_specific_disable_acs_redir(struct pci_dev *dev) - */ - static void quirk_intel_qat_vf_cap(struct pci_dev *pdev) - { -- int pos, i = 0; -+ int pos, i = 0, ret; - u8 next_cap; - u16 reg16, *cap; - struct pci_cap_saved_state *state; -@@ -5334,8 +5334,8 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev) - pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; - - pdev->cfg_size = PCI_CFG_SPACE_EXP_SIZE; -- if (pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status) != -- PCIBIOS_SUCCESSFUL || (status == 0xffffffff)) -+ ret = pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status); -+ if ((ret != PCIBIOS_SUCCESSFUL) || (PCI_POSSIBLE_ERROR(status))) - pdev->cfg_size = PCI_CFG_SPACE_SIZE; - - if (pci_find_saved_cap(pdev, PCI_CAP_ID_EXP)) -@@ -5404,6 +5404,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0420, quirk_no_ext_tags); - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags); - - #ifdef CONFIG_PCI_ATS -+static void quirk_no_ats(struct pci_dev *pdev) -+{ -+ pci_info(pdev, "disabling ATS\n"); -+ pdev->ats_cap = 0; -+} -+ - /* - * Some devices require additional driver setup to enable ATS. Don't use - * ATS for those devices as ATS will be enabled before the driver has had a -@@ -5417,14 +5423,10 @@ static void quirk_amd_harvest_no_ats(struct pci_dev *pdev) - (pdev->subsystem_device == 0xce19 || - pdev->subsystem_device == 0xcc10 || - pdev->subsystem_device == 0xcc08)) -- goto no_ats; -- else -- return; -+ quirk_no_ats(pdev); -+ } else { -+ quirk_no_ats(pdev); - } -- --no_ats: -- pci_info(pdev, "disabling ATS\n"); -- pdev->ats_cap = 0; - } - - /* AMD Stoney platform GPU */ -@@ -5447,6 +5449,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats); - /* AMD Raven platform iGPU */ - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats); -+ -+/* -+ * Intel IPU E2000 revisions before C0 implement incorrect endianness -+ * in ATS Invalidate Request message body. Disable ATS for those devices. -+ */ -+static void quirk_intel_e2000_no_ats(struct pci_dev *pdev) -+{ -+ if (pdev->revision < 0x20) -+ quirk_no_ats(pdev); -+} -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_ats); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_ats); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_ats); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_ats); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_ats); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats); - #endif /* CONFIG_PCI_ATS */ - - /* Freescale PCIe doesn't support MSI in RC mode */ -diff --git a/drivers/platform/chrome/cros_ec_proto_test.c b/drivers/platform/chrome/cros_ec_proto_test.c -index c6a83df91ae1e..b46a8bc2196fe 100644 ---- a/drivers/platform/chrome/cros_ec_proto_test.c -+++ b/drivers/platform/chrome/cros_ec_proto_test.c -@@ -2667,6 +2667,7 @@ static int cros_ec_proto_test_init(struct kunit *test) - ec_dev->dev->release = cros_ec_proto_test_release; - ec_dev->cmd_xfer = cros_kunit_ec_xfer_mock; - ec_dev->pkt_xfer = cros_kunit_ec_xfer_mock; -+ mutex_init(&ec_dev->lock); - - priv->msg = (struct cros_ec_command *)priv->_msg; - -diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c -index 3bb60687f2e42..05a55bc31c796 100644 ---- a/drivers/platform/x86/thinkpad_acpi.c -+++ b/drivers/platform/x86/thinkpad_acpi.c -@@ -10019,6 +10019,7 @@ static const struct tpacpi_quirk battery_quirk_table[] __initconst = { - * Individual addressing is broken on models that expose the - * primary battery as BAT1. - */ -+ TPACPI_Q_LNV('8', 'F', true), /* Thinkpad X120e */ - TPACPI_Q_LNV('J', '7', true), /* B5400 */ - TPACPI_Q_LNV('J', 'I', true), /* Thinkpad 11e */ - TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */ -diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c -index af3bc65c4595d..9311f3d09c8fc 100644 ---- a/drivers/ptp/ptp_chardev.c -+++ b/drivers/ptp/ptp_chardev.c -@@ -487,7 +487,8 @@ ssize_t ptp_read(struct posix_clock *pc, - - for (i = 0; i < cnt; i++) { - event[i] = queue->buf[queue->head]; -- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; -+ /* Paired with READ_ONCE() in queue_cnt() */ -+ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); - } - - spin_unlock_irqrestore(&queue->lock, flags); -diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c -index 51cae72bb6db2..3c3e4fbefebaf 100644 ---- a/drivers/ptp/ptp_clock.c -+++ b/drivers/ptp/ptp_clock.c -@@ -56,10 +56,11 @@ static void enqueue_external_timestamp(struct timestamp_event_queue *queue, - dst->t.sec = seconds; - dst->t.nsec = remainder; - -+ /* Both WRITE_ONCE() are paired with READ_ONCE() in queue_cnt() */ - if (!queue_free(queue)) -- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; -+ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); - -- queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS; -+ WRITE_ONCE(queue->tail, (queue->tail + 1) % PTP_MAX_TIMESTAMPS); - - spin_unlock_irqrestore(&queue->lock, flags); - } -diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h -index 75f58fc468a71..b8d4f61f14be4 100644 ---- a/drivers/ptp/ptp_private.h -+++ b/drivers/ptp/ptp_private.h -@@ -76,9 +76,13 @@ struct ptp_vclock { - * that a writer might concurrently increment the tail does not - * matter, since the queue remains nonempty nonetheless. - */ --static inline int queue_cnt(struct timestamp_event_queue *q) -+static inline int queue_cnt(const struct timestamp_event_queue *q) - { -- int cnt = q->tail - q->head; -+ /* -+ * Paired with WRITE_ONCE() in enqueue_external_timestamp(), -+ * ptp_read(), extts_fifo_show(). -+ */ -+ int cnt = READ_ONCE(q->tail) - READ_ONCE(q->head); - return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt; - } - -diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c -index f30b0a4394705..74b9c794d6363 100644 ---- a/drivers/ptp/ptp_sysfs.c -+++ b/drivers/ptp/ptp_sysfs.c -@@ -79,7 +79,8 @@ static ssize_t extts_fifo_show(struct device *dev, - qcnt = queue_cnt(queue); - if (qcnt) { - event = queue->buf[queue->head]; -- queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; -+ /* Paired with READ_ONCE() in queue_cnt() */ -+ WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); - } - spin_unlock_irqrestore(&queue->lock, flags); - -diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c -index b02c631f3b71a..4c0f9fe1ba779 100644 ---- a/drivers/s390/crypto/ap_bus.c -+++ b/drivers/s390/crypto/ap_bus.c -@@ -1012,6 +1012,10 @@ EXPORT_SYMBOL(ap_driver_unregister); - - void ap_bus_force_rescan(void) - { -+ /* Only trigger AP bus scans after the initial scan is done */ -+ if (atomic64_read(&ap_scan_bus_count) <= 0) -+ return; -+ - /* processing a asynchronous bus rescan */ - del_timer(&ap_config_timer); - queue_work(system_long_wq, &ap_scan_work); -diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -index c0e74d768716d..c4305ec38ebf3 100644 ---- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -@@ -4717,6 +4717,12 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba) - hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS; - } - -+static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) -+{ -+ debugfs_remove_recursive(hisi_hba->debugfs_dir); -+ hisi_hba->debugfs_dir = NULL; -+} -+ - static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) - { - struct device *dev = hisi_hba->dev; -@@ -4740,18 +4746,13 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) - - for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { - if (debugfs_alloc_v3_hw(hisi_hba, i)) { -- debugfs_remove_recursive(hisi_hba->debugfs_dir); -+ debugfs_exit_v3_hw(hisi_hba); - dev_dbg(dev, "failed to init debugfs!\n"); - break; - } - } - } - --static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) --{ -- debugfs_remove_recursive(hisi_hba->debugfs_dir); --} -- - static int - hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) - { -diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c -index 41148b0430df9..013f5c05e9f39 100644 ---- a/drivers/scsi/ibmvscsi/ibmvfc.c -+++ b/drivers/scsi/ibmvscsi/ibmvfc.c -@@ -1518,7 +1518,11 @@ static struct ibmvfc_event *ibmvfc_get_event(struct ibmvfc_queue *queue) - unsigned long flags; - - spin_lock_irqsave(&queue->l_lock, flags); -- BUG_ON(list_empty(&queue->free)); -+ if (list_empty(&queue->free)) { -+ ibmvfc_log(queue->vhost, 4, "empty event pool on queue:%ld\n", queue->hwq_id); -+ spin_unlock_irqrestore(&queue->l_lock, flags); -+ return NULL; -+ } - evt = list_entry(queue->free.next, struct ibmvfc_event, queue_list); - atomic_set(&evt->free, 0); - list_del(&evt->queue_list); -@@ -1947,9 +1951,15 @@ static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) - if (vhost->using_channels) { - scsi_channel = hwq % vhost->scsi_scrqs.active_queues; - evt = ibmvfc_get_event(&vhost->scsi_scrqs.scrqs[scsi_channel]); -+ if (!evt) -+ return SCSI_MLQUEUE_HOST_BUSY; -+ - evt->hwq = hwq % vhost->scsi_scrqs.active_queues; -- } else -+ } else { - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) -+ return SCSI_MLQUEUE_HOST_BUSY; -+ } - - ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT); - evt->cmnd = cmnd; -@@ -2037,6 +2047,11 @@ static int ibmvfc_bsg_timeout(struct bsg_job *job) - - vhost->aborting_passthru = 1; - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ spin_unlock_irqrestore(vhost->host->host_lock, flags); -+ return -ENOMEM; -+ } -+ - ibmvfc_init_event(evt, ibmvfc_bsg_timeout_done, IBMVFC_MAD_FORMAT); - - tmf = &evt->iu.tmf; -@@ -2095,6 +2110,10 @@ static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id) - goto unlock_out; - - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ rc = -ENOMEM; -+ goto unlock_out; -+ } - ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); - plogi = &evt->iu.plogi; - memset(plogi, 0, sizeof(*plogi)); -@@ -2213,6 +2232,11 @@ static int ibmvfc_bsg_request(struct bsg_job *job) - } - - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ spin_unlock_irqrestore(vhost->host->host_lock, flags); -+ rc = -ENOMEM; -+ goto out; -+ } - ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); - mad = &evt->iu.passthru; - -@@ -2301,6 +2325,11 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) - else - evt = ibmvfc_get_event(&vhost->crq); - -+ if (!evt) { -+ spin_unlock_irqrestore(vhost->host->host_lock, flags); -+ return -ENOMEM; -+ } -+ - ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); - tmf = ibmvfc_init_vfc_cmd(evt, sdev); - iu = ibmvfc_get_fcp_iu(vhost, tmf); -@@ -2504,6 +2533,8 @@ static struct ibmvfc_event *ibmvfc_init_tmf(struct ibmvfc_queue *queue, - struct ibmvfc_tmf *tmf; - - evt = ibmvfc_get_event(queue); -+ if (!evt) -+ return NULL; - ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); - - tmf = &evt->iu.tmf; -@@ -2560,6 +2591,11 @@ static int ibmvfc_cancel_all_mq(struct scsi_device *sdev, int type) - - if (found_evt && vhost->logged_in) { - evt = ibmvfc_init_tmf(&queues[i], sdev, type); -+ if (!evt) { -+ spin_unlock(queues[i].q_lock); -+ spin_unlock_irqrestore(vhost->host->host_lock, flags); -+ return -ENOMEM; -+ } - evt->sync_iu = &queues[i].cancel_rsp; - ibmvfc_send_event(evt, vhost, default_timeout); - list_add_tail(&evt->cancel, &cancelq); -@@ -2773,6 +2809,10 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) - - if (vhost->state == IBMVFC_ACTIVE) { - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ spin_unlock_irqrestore(vhost->host->host_lock, flags); -+ return -ENOMEM; -+ } - ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); - tmf = ibmvfc_init_vfc_cmd(evt, sdev); - iu = ibmvfc_get_fcp_iu(vhost, tmf); -@@ -4031,6 +4071,12 @@ static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt) - - kref_get(&tgt->kref); - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); -+ kref_put(&tgt->kref, ibmvfc_release_tgt); -+ __ibmvfc_reset_host(vhost); -+ return; -+ } - vhost->discovery_threads++; - ibmvfc_init_event(evt, ibmvfc_tgt_prli_done, IBMVFC_MAD_FORMAT); - evt->tgt = tgt; -@@ -4138,6 +4184,12 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt) - kref_get(&tgt->kref); - tgt->logo_rcvd = 0; - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); -+ kref_put(&tgt->kref, ibmvfc_release_tgt); -+ __ibmvfc_reset_host(vhost); -+ return; -+ } - vhost->discovery_threads++; - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); - ibmvfc_init_event(evt, ibmvfc_tgt_plogi_done, IBMVFC_MAD_FORMAT); -@@ -4214,6 +4266,8 @@ static struct ibmvfc_event *__ibmvfc_tgt_get_implicit_logout_evt(struct ibmvfc_t - - kref_get(&tgt->kref); - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) -+ return NULL; - ibmvfc_init_event(evt, done, IBMVFC_MAD_FORMAT); - evt->tgt = tgt; - mad = &evt->iu.implicit_logout; -@@ -4241,6 +4295,13 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) - vhost->discovery_threads++; - evt = __ibmvfc_tgt_get_implicit_logout_evt(tgt, - ibmvfc_tgt_implicit_logout_done); -+ if (!evt) { -+ vhost->discovery_threads--; -+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); -+ kref_put(&tgt->kref, ibmvfc_release_tgt); -+ __ibmvfc_reset_host(vhost); -+ return; -+ } - - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); - if (ibmvfc_send_event(evt, vhost, default_timeout)) { -@@ -4380,6 +4441,12 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target *tgt) - - kref_get(&tgt->kref); - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); -+ kref_put(&tgt->kref, ibmvfc_release_tgt); -+ __ibmvfc_reset_host(vhost); -+ return; -+ } - vhost->discovery_threads++; - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); - ibmvfc_init_event(evt, ibmvfc_tgt_move_login_done, IBMVFC_MAD_FORMAT); -@@ -4546,6 +4613,14 @@ static void ibmvfc_adisc_timeout(struct timer_list *t) - vhost->abort_threads++; - kref_get(&tgt->kref); - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ tgt_err(tgt, "Failed to get cancel event for ADISC.\n"); -+ vhost->abort_threads--; -+ kref_put(&tgt->kref, ibmvfc_release_tgt); -+ __ibmvfc_reset_host(vhost); -+ spin_unlock_irqrestore(vhost->host->host_lock, flags); -+ return; -+ } - ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT); - - evt->tgt = tgt; -@@ -4596,6 +4671,12 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt) - - kref_get(&tgt->kref); - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); -+ kref_put(&tgt->kref, ibmvfc_release_tgt); -+ __ibmvfc_reset_host(vhost); -+ return; -+ } - vhost->discovery_threads++; - ibmvfc_init_event(evt, ibmvfc_tgt_adisc_done, IBMVFC_MAD_FORMAT); - evt->tgt = tgt; -@@ -4699,6 +4780,12 @@ static void ibmvfc_tgt_query_target(struct ibmvfc_target *tgt) - - kref_get(&tgt->kref); - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); -+ kref_put(&tgt->kref, ibmvfc_release_tgt); -+ __ibmvfc_reset_host(vhost); -+ return; -+ } - vhost->discovery_threads++; - evt->tgt = tgt; - ibmvfc_init_event(evt, ibmvfc_tgt_query_target_done, IBMVFC_MAD_FORMAT); -@@ -4871,6 +4958,13 @@ static void ibmvfc_discover_targets(struct ibmvfc_host *vhost) - { - struct ibmvfc_discover_targets *mad; - struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); -+ int level = IBMVFC_DEFAULT_LOG_LEVEL; -+ -+ if (!evt) { -+ ibmvfc_log(vhost, level, "Discover Targets failed: no available events\n"); -+ ibmvfc_hard_reset_host(vhost); -+ return; -+ } - - ibmvfc_init_event(evt, ibmvfc_discover_targets_done, IBMVFC_MAD_FORMAT); - mad = &evt->iu.discover_targets; -@@ -4948,8 +5042,15 @@ static void ibmvfc_channel_setup(struct ibmvfc_host *vhost) - struct ibmvfc_scsi_channels *scrqs = &vhost->scsi_scrqs; - unsigned int num_channels = - min(vhost->client_scsi_channels, vhost->max_vios_scsi_channels); -+ int level = IBMVFC_DEFAULT_LOG_LEVEL; - int i; - -+ if (!evt) { -+ ibmvfc_log(vhost, level, "Channel Setup failed: no available events\n"); -+ ibmvfc_hard_reset_host(vhost); -+ return; -+ } -+ - memset(setup_buf, 0, sizeof(*setup_buf)); - if (num_channels == 0) - setup_buf->flags = cpu_to_be32(IBMVFC_CANCEL_CHANNELS); -@@ -5011,6 +5112,13 @@ static void ibmvfc_channel_enquiry(struct ibmvfc_host *vhost) - { - struct ibmvfc_channel_enquiry *mad; - struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); -+ int level = IBMVFC_DEFAULT_LOG_LEVEL; -+ -+ if (!evt) { -+ ibmvfc_log(vhost, level, "Channel Enquiry failed: no available events\n"); -+ ibmvfc_hard_reset_host(vhost); -+ return; -+ } - - ibmvfc_init_event(evt, ibmvfc_channel_enquiry_done, IBMVFC_MAD_FORMAT); - mad = &evt->iu.channel_enquiry; -@@ -5133,6 +5241,12 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost) - struct ibmvfc_npiv_login_mad *mad; - struct ibmvfc_event *evt = ibmvfc_get_event(&vhost->crq); - -+ if (!evt) { -+ ibmvfc_dbg(vhost, "NPIV Login failed: no available events\n"); -+ ibmvfc_hard_reset_host(vhost); -+ return; -+ } -+ - ibmvfc_gather_partition_info(vhost); - ibmvfc_set_login_info(vhost); - ibmvfc_init_event(evt, ibmvfc_npiv_login_done, IBMVFC_MAD_FORMAT); -@@ -5197,6 +5311,12 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *vhost) - struct ibmvfc_event *evt; - - evt = ibmvfc_get_event(&vhost->crq); -+ if (!evt) { -+ ibmvfc_dbg(vhost, "NPIV Logout failed: no available events\n"); -+ ibmvfc_hard_reset_host(vhost); -+ return; -+ } -+ - ibmvfc_init_event(evt, ibmvfc_npiv_logout_done, IBMVFC_MAD_FORMAT); - - mad = &evt->iu.npiv_logout; -diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c -index 9c02c9523c4d4..ab06e9aeb613e 100644 ---- a/drivers/scsi/libfc/fc_lport.c -+++ b/drivers/scsi/libfc/fc_lport.c -@@ -241,6 +241,12 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, - } - mutex_lock(&lport->disc.disc_mutex); - lport->ptp_rdata = fc_rport_create(lport, remote_fid); -+ if (!lport->ptp_rdata) { -+ printk(KERN_WARNING "libfc: Failed to setup lport 0x%x\n", -+ lport->port_id); -+ mutex_unlock(&lport->disc.disc_mutex); -+ return; -+ } - kref_get(&lport->ptp_rdata->kref); - lport->ptp_rdata->ids.port_name = remote_wwpn; - lport->ptp_rdata->ids.node_name = remote_wwnn; -diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c -index e392a984c7b87..37208bc08c667 100644 ---- a/drivers/scsi/megaraid/megaraid_sas_base.c -+++ b/drivers/scsi/megaraid/megaraid_sas_base.c -@@ -263,13 +263,13 @@ u32 megasas_readl(struct megasas_instance *instance, - * Fusion registers could intermittently return all zeroes. - * This behavior is transient in nature and subsequent reads will - * return valid value. As a workaround in driver, retry readl for -- * upto three times until a non-zero value is read. -+ * up to thirty times until a non-zero value is read. - */ - if (instance->adapter_type == AERO_SERIES) { - do { - ret_val = readl(addr); - i++; -- } while (ret_val == 0 && i < 3); -+ } while (ret_val == 0 && i < 30); - return ret_val; - } else { - return readl(addr); -diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c -index 2093888f154e0..809be43f440dc 100644 ---- a/drivers/scsi/mpt3sas/mpt3sas_base.c -+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c -@@ -224,8 +224,8 @@ _base_readl_ext_retry(const volatile void __iomem *addr) - - for (i = 0 ; i < 30 ; i++) { - ret_val = readl(addr); -- if (ret_val == 0) -- continue; -+ if (ret_val != 0) -+ break; - } - - return ret_val; -diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c -index b33ffec1cb75e..25ca0544b9639 100644 ---- a/drivers/scsi/qla2xxx/qla_os.c -+++ b/drivers/scsi/qla2xxx/qla_os.c -@@ -1831,8 +1831,16 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, - } - - spin_lock_irqsave(qp->qp_lock_ptr, *flags); -- if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd))) -- sp->done(sp, res); -+ switch (sp->type) { -+ case SRB_SCSI_CMD: -+ if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd))) -+ sp->done(sp, res); -+ break; -+ default: -+ if (ret_cmd) -+ sp->done(sp, res); -+ break; -+ } - } else { - sp->done(sp, res); - } -diff --git a/drivers/soc/bcm/bcm2835-power.c b/drivers/soc/bcm/bcm2835-power.c -index 5bcd047768b60..cbcd1298ef5bd 100644 ---- a/drivers/soc/bcm/bcm2835-power.c -+++ b/drivers/soc/bcm/bcm2835-power.c -@@ -175,7 +175,7 @@ static int bcm2835_asb_control(struct bcm2835_power *power, u32 reg, bool enable - } - writel(PM_PASSWORD | val, base + reg); - -- while (readl(base + reg) & ASB_ACK) { -+ while (!!(readl(base + reg) & ASB_ACK) == enable) { - cpu_relax(); - if (ktime_get_ns() - start >= 1000) - return -ETIMEDOUT; -diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c -index 90a8b2c0676ff..419ed15cc10c4 100644 ---- a/drivers/soc/imx/gpc.c -+++ b/drivers/soc/imx/gpc.c -@@ -498,6 +498,7 @@ static int imx_gpc_probe(struct platform_device *pdev) - - pd_pdev->dev.parent = &pdev->dev; - pd_pdev->dev.of_node = np; -+ pd_pdev->dev.fwnode = of_fwnode_handle(np); - - ret = platform_device_add(pd_pdev); - if (ret) { -diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c -index 2a1096dab63d3..9ebdd0cd0b1cf 100644 ---- a/drivers/soundwire/dmi-quirks.c -+++ b/drivers/soundwire/dmi-quirks.c -@@ -141,7 +141,7 @@ static const struct dmi_system_id adr_remap_quirk_table[] = { - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), -- DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16"), - }, - .driver_data = (void *)hp_omen_16, - }, -diff --git a/drivers/thunderbolt/quirks.c b/drivers/thunderbolt/quirks.c -index 8c2ee431fcde8..4ab3803e10c83 100644 ---- a/drivers/thunderbolt/quirks.c -+++ b/drivers/thunderbolt/quirks.c -@@ -30,6 +30,9 @@ static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw) - { - struct tb_port *port; - -+ if (tb_switch_is_icm(sw)) -+ return; -+ - tb_switch_for_each_port(sw, port) { - if (!tb_port_is_usb3_down(port)) - continue; -diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c -index d9d0232753286..281bc83acfadd 100644 ---- a/drivers/tty/hvc/hvc_xen.c -+++ b/drivers/tty/hvc/hvc_xen.c -@@ -377,18 +377,21 @@ void xen_console_resume(void) - #ifdef CONFIG_HVC_XEN_FRONTEND - static void xencons_disconnect_backend(struct xencons_info *info) - { -- if (info->irq > 0) -- unbind_from_irqhandler(info->irq, NULL); -- info->irq = 0; -+ if (info->hvc != NULL) -+ hvc_remove(info->hvc); -+ info->hvc = NULL; -+ if (info->irq > 0) { -+ evtchn_put(info->evtchn); -+ info->irq = 0; -+ info->evtchn = 0; -+ } -+ /* evtchn_put() will also close it so this is only an error path */ - if (info->evtchn > 0) - xenbus_free_evtchn(info->xbdev, info->evtchn); - info->evtchn = 0; - if (info->gntref > 0) - gnttab_free_grant_references(info->gntref); - info->gntref = 0; -- if (info->hvc != NULL) -- hvc_remove(info->hvc); -- info->hvc = NULL; - } - - static void xencons_free(struct xencons_info *info) -@@ -433,7 +436,7 @@ static int xencons_connect_backend(struct xenbus_device *dev, - if (ret) - return ret; - info->evtchn = evtchn; -- irq = bind_interdomain_evtchn_to_irq_lateeoi(dev, evtchn); -+ irq = bind_evtchn_to_irq_lateeoi(evtchn); - if (irq < 0) - return irq; - info->irq = irq; -@@ -553,10 +556,23 @@ static void xencons_backend_changed(struct xenbus_device *dev, - if (dev->state == XenbusStateClosed) - break; - fallthrough; /* Missed the backend's CLOSING state */ -- case XenbusStateClosing: -+ case XenbusStateClosing: { -+ struct xencons_info *info = dev_get_drvdata(&dev->dev);; -+ -+ /* -+ * Don't tear down the evtchn and grant ref before the other -+ * end has disconnected, but do stop userspace from trying -+ * to use the device before we allow the backend to close. -+ */ -+ if (info->hvc) { -+ hvc_remove(info->hvc); -+ info->hvc = NULL; -+ } -+ - xenbus_frontend_closed(dev); - break; - } -+ } - } - - static const struct xenbus_device_id xencons_ids[] = { -@@ -588,7 +604,7 @@ static int __init xen_hvc_init(void) - ops = &dom0_hvc_ops; - r = xen_initial_domain_console_init(); - if (r < 0) -- return r; -+ goto register_fe; - info = vtermno_to_xencons(HVC_COOKIE); - } else { - ops = &domU_hvc_ops; -@@ -597,7 +613,7 @@ static int __init xen_hvc_init(void) - else - r = xen_pv_console_init(); - if (r < 0) -- return r; -+ goto register_fe; - - info = vtermno_to_xencons(HVC_COOKIE); - info->irq = bind_evtchn_to_irq_lateeoi(info->evtchn); -@@ -616,12 +632,13 @@ static int __init xen_hvc_init(void) - list_del(&info->list); - spin_unlock_irqrestore(&xencons_lock, flags); - if (info->irq) -- unbind_from_irqhandler(info->irq, NULL); -+ evtchn_put(info->evtchn); - kfree(info); - return r; - } - - r = 0; -+ register_fe: - #ifdef CONFIG_HVC_XEN_FRONTEND - r = xenbus_register_frontend(&xencons_driver); - #endif -diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c -index 056243c12836c..8f6d54c04b9ba 100644 ---- a/drivers/tty/serial/meson_uart.c -+++ b/drivers/tty/serial/meson_uart.c -@@ -380,10 +380,14 @@ static void meson_uart_set_termios(struct uart_port *port, - else - val |= AML_UART_STOP_BIT_1SB; - -- if (cflags & CRTSCTS) -- val &= ~AML_UART_TWO_WIRE_EN; -- else -+ if (cflags & CRTSCTS) { -+ if (port->flags & UPF_HARD_FLOW) -+ val &= ~AML_UART_TWO_WIRE_EN; -+ else -+ termios->c_cflag &= ~CRTSCTS; -+ } else { - val |= AML_UART_TWO_WIRE_EN; -+ } - - writel(val, port->membase + AML_UART_CONTROL); - -@@ -698,6 +702,7 @@ static int meson_uart_probe(struct platform_device *pdev) - u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */ - int ret = 0; - int irq; -+ bool has_rtscts; - - if (pdev->dev.of_node) - pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); -@@ -725,6 +730,7 @@ static int meson_uart_probe(struct platform_device *pdev) - return irq; - - of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize); -+ has_rtscts = of_property_read_bool(pdev->dev.of_node, "uart-has-rtscts"); - - if (meson_ports[pdev->id]) { - dev_err(&pdev->dev, "port %d already allocated\n", pdev->id); -@@ -744,6 +750,8 @@ static int meson_uart_probe(struct platform_device *pdev) - port->mapsize = resource_size(res_mem); - port->irq = irq; - port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY; -+ if (has_rtscts) -+ port->flags |= UPF_HARD_FLOW; - port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE); - port->dev = &pdev->dev; - port->line = pdev->id; -diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c -index d2b2720db6ca7..248067197287a 100644 ---- a/drivers/tty/sysrq.c -+++ b/drivers/tty/sysrq.c -@@ -263,13 +263,14 @@ static void sysrq_handle_showallcpus(int key) - if (in_hardirq()) - regs = get_irq_regs(); - -- pr_info("CPU%d:\n", smp_processor_id()); -+ pr_info("CPU%d:\n", get_cpu()); - if (regs) - show_regs(regs); - else - show_stack(NULL, NULL, KERN_INFO); - - schedule_work(&sysrq_showallcpus); -+ put_cpu(); - } - } - -diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c -index 34ba6e54789a7..b8b832c75b856 100644 ---- a/drivers/tty/vcc.c -+++ b/drivers/tty/vcc.c -@@ -579,18 +579,22 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) - return -ENOMEM; - - name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL); -+ if (!name) { -+ rv = -ENOMEM; -+ goto free_port; -+ } - - rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions, - ARRAY_SIZE(vcc_versions), NULL, name); - if (rv) -- goto free_port; -+ goto free_name; - - port->vio.debug = vcc_dbg_vio; - vcc_ldc_cfg.debug = vcc_dbg_ldc; - - rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port); - if (rv) -- goto free_port; -+ goto free_name; - - spin_lock_init(&port->lock); - -@@ -624,6 +628,11 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) - goto unreg_tty; - } - port->domain = kstrdup(domain, GFP_KERNEL); -+ if (!port->domain) { -+ rv = -ENOMEM; -+ goto unreg_tty; -+ } -+ - - mdesc_release(hp); - -@@ -653,8 +662,9 @@ free_table: - vcc_table_remove(port->index); - free_ldc: - vio_ldc_free(&port->vio); --free_port: -+free_name: - kfree(name); -+free_port: - kfree(port); - - return rv; -diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c -index 57e2f4cc744f7..a811db88eedae 100644 ---- a/drivers/usb/dwc3/core.c -+++ b/drivers/usb/dwc3/core.c -@@ -1111,6 +1111,111 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc) - } - } - -+static void dwc3_config_threshold(struct dwc3 *dwc) -+{ -+ u32 reg; -+ u8 rx_thr_num; -+ u8 rx_maxburst; -+ u8 tx_thr_num; -+ u8 tx_maxburst; -+ -+ /* -+ * Must config both number of packets and max burst settings to enable -+ * RX and/or TX threshold. -+ */ -+ if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { -+ rx_thr_num = dwc->rx_thr_num_pkt_prd; -+ rx_maxburst = dwc->rx_max_burst_prd; -+ tx_thr_num = dwc->tx_thr_num_pkt_prd; -+ tx_maxburst = dwc->tx_max_burst_prd; -+ -+ if (rx_thr_num && rx_maxburst) { -+ reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); -+ reg |= DWC31_RXTHRNUMPKTSEL_PRD; -+ -+ reg &= ~DWC31_RXTHRNUMPKT_PRD(~0); -+ reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num); -+ -+ reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0); -+ reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst); -+ -+ dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); -+ } -+ -+ if (tx_thr_num && tx_maxburst) { -+ reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); -+ reg |= DWC31_TXTHRNUMPKTSEL_PRD; -+ -+ reg &= ~DWC31_TXTHRNUMPKT_PRD(~0); -+ reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num); -+ -+ reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0); -+ reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst); -+ -+ dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); -+ } -+ } -+ -+ rx_thr_num = dwc->rx_thr_num_pkt; -+ rx_maxburst = dwc->rx_max_burst; -+ tx_thr_num = dwc->tx_thr_num_pkt; -+ tx_maxburst = dwc->tx_max_burst; -+ -+ if (DWC3_IP_IS(DWC3)) { -+ if (rx_thr_num && rx_maxburst) { -+ reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); -+ reg |= DWC3_GRXTHRCFG_PKTCNTSEL; -+ -+ reg &= ~DWC3_GRXTHRCFG_RXPKTCNT(~0); -+ reg |= DWC3_GRXTHRCFG_RXPKTCNT(rx_thr_num); -+ -+ reg &= ~DWC3_GRXTHRCFG_MAXRXBURSTSIZE(~0); -+ reg |= DWC3_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst); -+ -+ dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); -+ } -+ -+ if (tx_thr_num && tx_maxburst) { -+ reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); -+ reg |= DWC3_GTXTHRCFG_PKTCNTSEL; -+ -+ reg &= ~DWC3_GTXTHRCFG_TXPKTCNT(~0); -+ reg |= DWC3_GTXTHRCFG_TXPKTCNT(tx_thr_num); -+ -+ reg &= ~DWC3_GTXTHRCFG_MAXTXBURSTSIZE(~0); -+ reg |= DWC3_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst); -+ -+ dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); -+ } -+ } else { -+ if (rx_thr_num && rx_maxburst) { -+ reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); -+ reg |= DWC31_GRXTHRCFG_PKTCNTSEL; -+ -+ reg &= ~DWC31_GRXTHRCFG_RXPKTCNT(~0); -+ reg |= DWC31_GRXTHRCFG_RXPKTCNT(rx_thr_num); -+ -+ reg &= ~DWC31_GRXTHRCFG_MAXRXBURSTSIZE(~0); -+ reg |= DWC31_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst); -+ -+ dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); -+ } -+ -+ if (tx_thr_num && tx_maxburst) { -+ reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); -+ reg |= DWC31_GTXTHRCFG_PKTCNTSEL; -+ -+ reg &= ~DWC31_GTXTHRCFG_TXPKTCNT(~0); -+ reg |= DWC31_GTXTHRCFG_TXPKTCNT(tx_thr_num); -+ -+ reg &= ~DWC31_GTXTHRCFG_MAXTXBURSTSIZE(~0); -+ reg |= DWC31_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst); -+ -+ dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); -+ } -+ } -+} -+ - /** - * dwc3_core_init - Low-level initialization of DWC3 Core - * @dwc: Pointer to our controller context structure -@@ -1278,42 +1383,7 @@ static int dwc3_core_init(struct dwc3 *dwc) - dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); - } - -- /* -- * Must config both number of packets and max burst settings to enable -- * RX and/or TX threshold. -- */ -- if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { -- u8 rx_thr_num = dwc->rx_thr_num_pkt_prd; -- u8 rx_maxburst = dwc->rx_max_burst_prd; -- u8 tx_thr_num = dwc->tx_thr_num_pkt_prd; -- u8 tx_maxburst = dwc->tx_max_burst_prd; -- -- if (rx_thr_num && rx_maxburst) { -- reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); -- reg |= DWC31_RXTHRNUMPKTSEL_PRD; -- -- reg &= ~DWC31_RXTHRNUMPKT_PRD(~0); -- reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num); -- -- reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0); -- reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst); -- -- dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); -- } -- -- if (tx_thr_num && tx_maxburst) { -- reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); -- reg |= DWC31_TXTHRNUMPKTSEL_PRD; -- -- reg &= ~DWC31_TXTHRNUMPKT_PRD(~0); -- reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num); -- -- reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0); -- reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst); -- -- dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); -- } -- } -+ dwc3_config_threshold(dwc); - - return 0; - -@@ -1462,6 +1532,10 @@ static void dwc3_get_properties(struct dwc3 *dwc) - u8 lpm_nyet_threshold; - u8 tx_de_emphasis; - u8 hird_threshold; -+ u8 rx_thr_num_pkt = 0; -+ u8 rx_max_burst = 0; -+ u8 tx_thr_num_pkt = 0; -+ u8 tx_max_burst = 0; - u8 rx_thr_num_pkt_prd = 0; - u8 rx_max_burst_prd = 0; - u8 tx_thr_num_pkt_prd = 0; -@@ -1524,6 +1598,14 @@ static void dwc3_get_properties(struct dwc3 *dwc) - "snps,usb2-lpm-disable"); - dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev, - "snps,usb2-gadget-lpm-disable"); -+ device_property_read_u8(dev, "snps,rx-thr-num-pkt", -+ &rx_thr_num_pkt); -+ device_property_read_u8(dev, "snps,rx-max-burst", -+ &rx_max_burst); -+ device_property_read_u8(dev, "snps,tx-thr-num-pkt", -+ &tx_thr_num_pkt); -+ device_property_read_u8(dev, "snps,tx-max-burst", -+ &tx_max_burst); - device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd", - &rx_thr_num_pkt_prd); - device_property_read_u8(dev, "snps,rx-max-burst-prd", -@@ -1601,6 +1683,12 @@ static void dwc3_get_properties(struct dwc3 *dwc) - - dwc->hird_threshold = hird_threshold; - -+ dwc->rx_thr_num_pkt = rx_thr_num_pkt; -+ dwc->rx_max_burst = rx_max_burst; -+ -+ dwc->tx_thr_num_pkt = tx_thr_num_pkt; -+ dwc->tx_max_burst = tx_max_burst; -+ - dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd; - dwc->rx_max_burst_prd = rx_max_burst_prd; - -diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h -index 80cc532ba9d55..889c122dad457 100644 ---- a/drivers/usb/dwc3/core.h -+++ b/drivers/usb/dwc3/core.h -@@ -209,6 +209,11 @@ - #define DWC3_GRXTHRCFG_RXPKTCNT(n) (((n) & 0xf) << 24) - #define DWC3_GRXTHRCFG_PKTCNTSEL BIT(29) - -+/* Global TX Threshold Configuration Register */ -+#define DWC3_GTXTHRCFG_MAXTXBURSTSIZE(n) (((n) & 0xff) << 16) -+#define DWC3_GTXTHRCFG_TXPKTCNT(n) (((n) & 0xf) << 24) -+#define DWC3_GTXTHRCFG_PKTCNTSEL BIT(29) -+ - /* Global RX Threshold Configuration Register for DWC_usb31 only */ - #define DWC31_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 16) - #define DWC31_GRXTHRCFG_RXPKTCNT(n) (((n) & 0x1f) << 21) -@@ -1041,6 +1046,10 @@ struct dwc3_scratchpad_array { - * @test_mode_nr: test feature selector - * @lpm_nyet_threshold: LPM NYET response threshold - * @hird_threshold: HIRD threshold -+ * @rx_thr_num_pkt: USB receive packet count -+ * @rx_max_burst: max USB receive burst size -+ * @tx_thr_num_pkt: USB transmit packet count -+ * @tx_max_burst: max USB transmit burst size - * @rx_thr_num_pkt_prd: periodic ESS receive packet count - * @rx_max_burst_prd: max periodic ESS receive burst size - * @tx_thr_num_pkt_prd: periodic ESS transmit packet count -@@ -1268,6 +1277,10 @@ struct dwc3 { - u8 test_mode_nr; - u8 lpm_nyet_threshold; - u8 hird_threshold; -+ u8 rx_thr_num_pkt; -+ u8 rx_max_burst; -+ u8 tx_thr_num_pkt; -+ u8 tx_max_burst; - u8 rx_thr_num_pkt_prd; - u8 rx_max_burst_prd; - u8 tx_thr_num_pkt_prd; -diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c -index faf90a2174194..bbb6ff6b11aa1 100644 ---- a/drivers/usb/gadget/function/f_ncm.c -+++ b/drivers/usb/gadget/function/f_ncm.c -@@ -1425,7 +1425,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) - struct usb_composite_dev *cdev = c->cdev; - struct f_ncm *ncm = func_to_ncm(f); - struct usb_string *us; -- int status; -+ int status = 0; - struct usb_ep *ep; - struct f_ncm_opts *ncm_opts; - -@@ -1443,22 +1443,17 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) - f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; - } - -- /* -- * in drivers/usb/gadget/configfs.c:configfs_composite_bind() -- * configurations are bound in sequence with list_for_each_entry, -- * in each configuration its functions are bound in sequence -- * with list_for_each_entry, so we assume no race condition -- * with regard to ncm_opts->bound access -- */ -- if (!ncm_opts->bound) { -- mutex_lock(&ncm_opts->lock); -- gether_set_gadget(ncm_opts->net, cdev->gadget); -+ mutex_lock(&ncm_opts->lock); -+ gether_set_gadget(ncm_opts->net, cdev->gadget); -+ if (!ncm_opts->bound) - status = gether_register_netdev(ncm_opts->net); -- mutex_unlock(&ncm_opts->lock); -- if (status) -- goto fail; -- ncm_opts->bound = true; -- } -+ mutex_unlock(&ncm_opts->lock); -+ -+ if (status) -+ goto fail; -+ -+ ncm_opts->bound = true; -+ - us = usb_gstrings_attach(cdev, ncm_strings, - ARRAY_SIZE(ncm_string_defs)); - if (IS_ERR(us)) { -diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c -index c4dd648710ae0..24bcf6ab12d8a 100644 ---- a/drivers/usb/host/xhci-pci.c -+++ b/drivers/usb/host/xhci-pci.c -@@ -508,7 +508,9 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) - /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ - pm_runtime_put_noidle(&dev->dev); - -- if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) -+ if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0) -+ pm_runtime_forbid(&dev->dev); -+ else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) - pm_runtime_allow(&dev->dev); - - dma_set_max_seg_size(&dev->dev, UINT_MAX); -diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c -index 31a156669a531..c8374527a27d9 100644 ---- a/drivers/vhost/vdpa.c -+++ b/drivers/vhost/vdpa.c -@@ -1427,7 +1427,6 @@ static int vhost_vdpa_probe(struct vdpa_device *vdpa) - - err: - put_device(&v->dev); -- ida_simple_remove(&vhost_vdpa_ida, v->minor); - return r; - } - -diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c -index 63862803421f1..7bf28545b47a0 100644 ---- a/drivers/watchdog/sbsa_gwdt.c -+++ b/drivers/watchdog/sbsa_gwdt.c -@@ -153,14 +153,14 @@ static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd, - timeout = clamp_t(unsigned int, timeout, 1, wdd->max_hw_heartbeat_ms / 1000); - - if (action) -- sbsa_gwdt_reg_write(gwdt->clk * timeout, gwdt); -+ sbsa_gwdt_reg_write((u64)gwdt->clk * timeout, gwdt); - else - /* - * In the single stage mode, The first signal (WS0) is ignored, - * the timeout is (WOR * 2), so the WOR should be configured - * to half value of timeout. - */ -- sbsa_gwdt_reg_write(gwdt->clk / 2 * timeout, gwdt); -+ sbsa_gwdt_reg_write(((u64)gwdt->clk / 2) * timeout, gwdt); - - return 0; - } -diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c -index 80b46de14f413..af9115d648092 100644 ---- a/drivers/xen/events/events_base.c -+++ b/drivers/xen/events/events_base.c -@@ -600,7 +600,9 @@ static void lateeoi_list_add(struct irq_info *info) - - spin_lock_irqsave(&eoi->eoi_list_lock, flags); - -- if (list_empty(&eoi->eoi_list)) { -+ elem = list_first_entry_or_null(&eoi->eoi_list, struct irq_info, -+ eoi_list); -+ if (!elem || info->eoi_time < elem->eoi_time) { - list_add(&info->eoi_list, &eoi->eoi_list); - mod_delayed_work_on(info->eoi_cpu, system_wq, - &eoi->delayed, delay); -diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c -index 2807bb63f7802..3b9aa61de8c2d 100644 ---- a/fs/9p/xattr.c -+++ b/fs/9p/xattr.c -@@ -65,7 +65,7 @@ ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name, - struct p9_fid *fid; - int ret; - -- p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n", -+ p9_debug(P9_DEBUG_VFS, "name = '%s' value_len = %zu\n", - name, buffer_size); - fid = v9fs_fid_lookup(dentry); - if (IS_ERR(fid)) -@@ -136,7 +136,8 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name, - - ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) - { -- return v9fs_xattr_get(dentry, NULL, buffer, buffer_size); -+ /* Txattrwalk with an empty string lists xattrs instead */ -+ return v9fs_xattr_get(dentry, "", buffer, buffer_size); - } - - static int v9fs_xattr_handler_get(const struct xattr_handler *handler, -diff --git a/fs/btrfs/delalloc-space.c b/fs/btrfs/delalloc-space.c -index 118b2e20b2e19..0b62ce77053f5 100644 ---- a/fs/btrfs/delalloc-space.c -+++ b/fs/btrfs/delalloc-space.c -@@ -320,9 +320,6 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, - } else { - if (current->journal_info) - flush = BTRFS_RESERVE_FLUSH_LIMIT; -- -- if (btrfs_transaction_in_commit(fs_info)) -- schedule_timeout(1); - } - - num_bytes = ALIGN(num_bytes, fs_info->sectorsize); -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 4063447217f92..81eac121c6b23 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -7166,8 +7166,15 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode, - int ret; - - alloc_hint = get_extent_allocation_hint(inode, start, len); -+again: - ret = btrfs_reserve_extent(root, len, len, fs_info->sectorsize, - 0, alloc_hint, &ins, 1, 1); -+ if (ret == -EAGAIN) { -+ ASSERT(btrfs_is_zoned(fs_info)); -+ wait_on_bit_io(&inode->root->fs_info->flags, BTRFS_FS_NEED_ZONE_FINISH, -+ TASK_UNINTERRUPTIBLE); -+ goto again; -+ } - if (ret) - return ERR_PTR(ret); - -diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c -index 90b0477911449..30e97c51f0e14 100644 ---- a/fs/exfat/namei.c -+++ b/fs/exfat/namei.c -@@ -338,14 +338,20 @@ static int exfat_find_empty_entry(struct inode *inode, - if (exfat_check_max_dentries(inode)) - return -ENOSPC; - -- /* we trust p_dir->size regardless of FAT type */ -- if (exfat_find_last_cluster(sb, p_dir, &last_clu)) -- return -EIO; -- - /* - * Allocate new cluster to this directory - */ -- exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags); -+ if (ei->start_clu != EXFAT_EOF_CLUSTER) { -+ /* we trust p_dir->size regardless of FAT type */ -+ if (exfat_find_last_cluster(sb, p_dir, &last_clu)) -+ return -EIO; -+ -+ exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags); -+ } else { -+ /* This directory is empty */ -+ exfat_chain_set(&clu, EXFAT_EOF_CLUSTER, 0, -+ ALLOC_NO_FAT_CHAIN); -+ } - - /* allocate a cluster */ - ret = exfat_alloc_cluster(inode, 1, &clu, IS_DIRSYNC(inode)); -@@ -355,6 +361,11 @@ static int exfat_find_empty_entry(struct inode *inode, - if (exfat_zeroed_cluster(inode, clu.dir)) - return -EIO; - -+ if (ei->start_clu == EXFAT_EOF_CLUSTER) { -+ ei->start_clu = clu.dir; -+ p_dir->dir = clu.dir; -+ } -+ - /* append to the FAT chain */ - if (clu.flags != p_dir->flags) { - /* no-fat-chain bit is disabled, -@@ -644,7 +655,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, - info->type = exfat_get_entry_type(ep); - info->attr = le16_to_cpu(ep->dentry.file.attr); - info->size = le64_to_cpu(ep2->dentry.stream.valid_size); -- if ((info->type == TYPE_FILE) && (info->size == 0)) { -+ if (info->size == 0) { - info->flags = ALLOC_NO_FAT_CHAIN; - info->start_clu = EXFAT_EOF_CLUSTER; - } else { -@@ -888,6 +899,9 @@ static int exfat_check_dir_empty(struct super_block *sb, - - dentries_per_clu = sbi->dentries_per_clu; - -+ if (p_dir->dir == EXFAT_EOF_CLUSTER) -+ return 0; -+ - exfat_chain_dup(&clu, p_dir); - - while (clu.dir != EXFAT_EOF_CLUSTER) { -@@ -1262,7 +1276,8 @@ static int __exfat_rename(struct inode *old_parent_inode, - } - - /* Free the clusters if new_inode is a dir(as if exfat_rmdir) */ -- if (new_entry_type == TYPE_DIR) { -+ if (new_entry_type == TYPE_DIR && -+ new_ei->start_clu != EXFAT_EOF_CLUSTER) { - /* new_ei, new_clu_to_free */ - struct exfat_chain new_clu_to_free; - -diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h -index 3219669732bf4..0db6ae0ca9369 100644 ---- a/fs/ext4/acl.h -+++ b/fs/ext4/acl.h -@@ -68,6 +68,11 @@ extern int ext4_init_acl(handle_t *, struct inode *, struct inode *); - static inline int - ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) - { -+ /* usually, the umask is applied by posix_acl_create(), but if -+ ext4 ACL support is disabled at compile time, we need to do -+ it here, because posix_acl_create() will never be called */ -+ inode->i_mode &= ~current_umask(); -+ - return 0; - } - #endif /* CONFIG_EXT4_FS_POSIX_ACL */ -diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c -index 44e83521bfded..b57e497679ef9 100644 ---- a/fs/ext4/extents_status.c -+++ b/fs/ext4/extents_status.c -@@ -1365,8 +1365,8 @@ retry: - } - } - if (count_reserved) -- count_rsvd(inode, lblk, orig_es.es_len - len1 - len2, -- &orig_es, &rc); -+ count_rsvd(inode, orig_es.es_lblk + len1, -+ orig_es.es_len - len1 - len2, &orig_es, &rc); - goto out_get_reserved; - } - -diff --git a/fs/ext4/file.c b/fs/ext4/file.c -index a7a597c727e63..8ebe4dc7b0170 100644 ---- a/fs/ext4/file.c -+++ b/fs/ext4/file.c -@@ -296,80 +296,38 @@ out: - } - - static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset, -- ssize_t written, size_t count) -+ ssize_t count) - { - handle_t *handle; -- bool truncate = false; -- u8 blkbits = inode->i_blkbits; -- ext4_lblk_t written_blk, end_blk; -- int ret; -- -- /* -- * Note that EXT4_I(inode)->i_disksize can get extended up to -- * inode->i_size while the I/O was running due to writeback of delalloc -- * blocks. But, the code in ext4_iomap_alloc() is careful to use -- * zeroed/unwritten extents if this is possible; thus we won't leave -- * uninitialized blocks in a file even if we didn't succeed in writing -- * as much as we intended. -- */ -- WARN_ON_ONCE(i_size_read(inode) < EXT4_I(inode)->i_disksize); -- if (offset + count <= EXT4_I(inode)->i_disksize) { -- /* -- * We need to ensure that the inode is removed from the orphan -- * list if it has been added prematurely, due to writeback of -- * delalloc blocks. -- */ -- if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) { -- handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); -- -- if (IS_ERR(handle)) { -- ext4_orphan_del(NULL, inode); -- return PTR_ERR(handle); -- } -- -- ext4_orphan_del(handle, inode); -- ext4_journal_stop(handle); -- } -- -- return written; -- } -- -- if (written < 0) -- goto truncate; - -+ lockdep_assert_held_write(&inode->i_rwsem); - handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); -- if (IS_ERR(handle)) { -- written = PTR_ERR(handle); -- goto truncate; -- } -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); - -- if (ext4_update_inode_size(inode, offset + written)) { -- ret = ext4_mark_inode_dirty(handle, inode); -+ if (ext4_update_inode_size(inode, offset + count)) { -+ int ret = ext4_mark_inode_dirty(handle, inode); - if (unlikely(ret)) { -- written = ret; - ext4_journal_stop(handle); -- goto truncate; -+ return ret; - } - } - -- /* -- * We may need to truncate allocated but not written blocks beyond EOF. -- */ -- written_blk = ALIGN(offset + written, 1 << blkbits); -- end_blk = ALIGN(offset + count, 1 << blkbits); -- if (written_blk < end_blk && ext4_can_truncate(inode)) -- truncate = true; -- -- /* -- * Remove the inode from the orphan list if it has been extended and -- * everything went OK. -- */ -- if (!truncate && inode->i_nlink) -+ if (inode->i_nlink) - ext4_orphan_del(handle, inode); - ext4_journal_stop(handle); - -- if (truncate) { --truncate: -+ return count; -+} -+ -+/* -+ * Clean up the inode after DIO or DAX extending write has completed and the -+ * inode size has been updated using ext4_handle_inode_extension(). -+ */ -+static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count) -+{ -+ lockdep_assert_held_write(&inode->i_rwsem); -+ if (count < 0) { - ext4_truncate_failed_write(inode); - /* - * If the truncate operation failed early, then the inode may -@@ -378,9 +336,28 @@ truncate: - */ - if (inode->i_nlink) - ext4_orphan_del(NULL, inode); -+ return; - } -+ /* -+ * If i_disksize got extended due to writeback of delalloc blocks while -+ * the DIO was running we could fail to cleanup the orphan list in -+ * ext4_handle_inode_extension(). Do it now. -+ */ -+ if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) { -+ handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); - -- return written; -+ if (IS_ERR(handle)) { -+ /* -+ * The write has successfully completed. Not much to -+ * do with the error here so just cleanup the orphan -+ * list and hope for the best. -+ */ -+ ext4_orphan_del(NULL, inode); -+ return; -+ } -+ ext4_orphan_del(handle, inode); -+ ext4_journal_stop(handle); -+ } - } - - static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size, -@@ -389,31 +366,22 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size, - loff_t pos = iocb->ki_pos; - struct inode *inode = file_inode(iocb->ki_filp); - -+ if (!error && size && flags & IOMAP_DIO_UNWRITTEN) -+ error = ext4_convert_unwritten_extents(NULL, inode, pos, size); - if (error) - return error; -- -- if (size && flags & IOMAP_DIO_UNWRITTEN) { -- error = ext4_convert_unwritten_extents(NULL, inode, pos, size); -- if (error < 0) -- return error; -- } - /* -- * If we are extending the file, we have to update i_size here before -- * page cache gets invalidated in iomap_dio_rw(). Otherwise racing -- * buffered reads could zero out too much from page cache pages. Update -- * of on-disk size will happen later in ext4_dio_write_iter() where -- * we have enough information to also perform orphan list handling etc. -- * Note that we perform all extending writes synchronously under -- * i_rwsem held exclusively so i_size update is safe here in that case. -- * If the write was not extending, we cannot see pos > i_size here -- * because operations reducing i_size like truncate wait for all -- * outstanding DIO before updating i_size. -+ * Note that EXT4_I(inode)->i_disksize can get extended up to -+ * inode->i_size while the I/O was running due to writeback of delalloc -+ * blocks. But the code in ext4_iomap_alloc() is careful to use -+ * zeroed/unwritten extents if this is possible; thus we won't leave -+ * uninitialized blocks in a file even if we didn't succeed in writing -+ * as much as we intended. - */ -- pos += size; -- if (pos > i_size_read(inode)) -- i_size_write(inode, pos); -- -- return 0; -+ WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize)); -+ if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize)) -+ return size; -+ return ext4_handle_inode_extension(inode, pos, size); - } - - static const struct iomap_dio_ops ext4_dio_write_ops = { -@@ -589,9 +557,16 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from) - NULL, 0); - if (ret == -ENOTBLK) - ret = 0; -- -- if (extend) -- ret = ext4_handle_inode_extension(inode, offset, ret, count); -+ if (extend) { -+ /* -+ * We always perform extending DIO write synchronously so by -+ * now the IO is completed and ext4_handle_inode_extension() -+ * was called. Cleanup the inode in case of error or race with -+ * writeback of delalloc blocks. -+ */ -+ WARN_ON_ONCE(ret == -EIOCBQUEUED); -+ ext4_inode_extension_cleanup(inode, ret); -+ } - - out: - if (ilock_shared) -@@ -672,8 +647,10 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from) - - ret = dax_iomap_rw(iocb, from, &ext4_iomap_ops); - -- if (extend) -- ret = ext4_handle_inode_extension(inode, offset, ret, count); -+ if (extend) { -+ ret = ext4_handle_inode_extension(inode, offset, ret); -+ ext4_inode_extension_cleanup(inode, ret); -+ } - out: - inode_unlock(inode); - if (ret > 0) -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 5aa3003cfc688..2479508deab3b 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -824,10 +824,22 @@ int ext4_get_block(struct inode *inode, sector_t iblock, - int ext4_get_block_unwritten(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create) - { -+ int ret = 0; -+ - ext4_debug("ext4_get_block_unwritten: inode %lu, create flag %d\n", - inode->i_ino, create); -- return _ext4_get_block(inode, iblock, bh_result, -+ ret = _ext4_get_block(inode, iblock, bh_result, - EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT); -+ -+ /* -+ * If the buffer is marked unwritten, mark it as new to make sure it is -+ * zeroed out correctly in case of partial writes. Otherwise, there is -+ * a chance of stale data getting exposed. -+ */ -+ if (ret == 0 && buffer_unwritten(bh_result)) -+ set_buffer_new(bh_result); -+ -+ return ret; - } - - /* Maximum number of blocks we map for direct IO at once. */ -diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c -index b493233750ab2..9833ab6db117c 100644 ---- a/fs/ext4/resize.c -+++ b/fs/ext4/resize.c -@@ -560,13 +560,8 @@ static int setup_new_flex_group_blocks(struct super_block *sb, - if (meta_bg == 0 && !ext4_bg_has_super(sb, group)) - goto handle_itb; - -- if (meta_bg == 1) { -- ext4_group_t first_group; -- first_group = ext4_meta_bg_first_group(sb, group); -- if (first_group != group + 1 && -- first_group != group + EXT4_DESC_PER_BLOCK(sb) - 1) -- goto handle_itb; -- } -+ if (meta_bg == 1) -+ goto handle_itb; - - block = start + ext4_bg_has_super(sb, group); - /* Copy all of the GDT blocks into the backup in this group */ -@@ -1191,8 +1186,10 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data, - ext4_group_first_block_no(sb, group)); - BUFFER_TRACE(bh, "get_write_access"); - if ((err = ext4_journal_get_write_access(handle, sb, bh, -- EXT4_JTR_NONE))) -+ EXT4_JTR_NONE))) { -+ brelse(bh); - break; -+ } - lock_buffer(bh); - memcpy(bh->b_data, data, size); - if (rest) -@@ -1602,6 +1599,8 @@ exit_journal: - int gdb_num_end = ((group + flex_gd->count - 1) / - EXT4_DESC_PER_BLOCK(sb)); - int meta_bg = ext4_has_feature_meta_bg(sb); -+ sector_t padding_blocks = meta_bg ? 0 : sbi->s_sbh->b_blocknr - -+ ext4_group_first_block_no(sb, 0); - sector_t old_gdb = 0; - - update_backups(sb, ext4_group_first_block_no(sb, 0), -@@ -1613,8 +1612,8 @@ exit_journal: - gdb_num); - if (old_gdb == gdb_bh->b_blocknr) - continue; -- update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data, -- gdb_bh->b_size, meta_bg); -+ update_backups(sb, gdb_bh->b_blocknr - padding_blocks, -+ gdb_bh->b_data, gdb_bh->b_size, meta_bg); - old_gdb = gdb_bh->b_blocknr; - } - } -@@ -1983,9 +1982,7 @@ static int ext4_convert_meta_bg(struct super_block *sb, struct inode *inode) - - errout: - ret = ext4_journal_stop(handle); -- if (!err) -- err = ret; -- return ret; -+ return err ? err : ret; - - invalid_resize_inode: - ext4_error(sb, "corrupted/inconsistent resize inode"); -diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c -index fb75ff7b3448d..11d9dce994dbe 100644 ---- a/fs/f2fs/compress.c -+++ b/fs/f2fs/compress.c -@@ -1983,7 +1983,7 @@ void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) - int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) - { - dev_t dev = sbi->sb->s_bdev->bd_dev; -- char slab_name[32]; -+ char slab_name[35]; - - if (!f2fs_sb_has_compression(sbi)) - return 0; -diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c -index a010b4bc36d2c..6efccd7ccfe1b 100644 ---- a/fs/f2fs/node.c -+++ b/fs/f2fs/node.c -@@ -1455,7 +1455,8 @@ page_hit: - ofs_of_node(page), cpver_of_node(page), - next_blkaddr_of_node(page)); - set_sbi_flag(sbi, SBI_NEED_FSCK); -- err = -EINVAL; -+ f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER); -+ err = -EFSCORRUPTED; - out_err: - ClearPageUptodate(page); - out_put_err: -@@ -2737,7 +2738,9 @@ recover_xnid: - f2fs_update_inode_page(inode); - - /* 3: update and set xattr node page dirty */ -- memcpy(F2FS_NODE(xpage), F2FS_NODE(page), VALID_XATTR_BLOCK_SIZE); -+ if (page) -+ memcpy(F2FS_NODE(xpage), F2FS_NODE(page), -+ VALID_XATTR_BLOCK_SIZE); - - set_page_dirty(xpage); - f2fs_put_page(xpage, 1); -diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c -index db3b641f2158c..adaad16468d8a 100644 ---- a/fs/f2fs/xattr.c -+++ b/fs/f2fs/xattr.c -@@ -363,10 +363,10 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage, - - *xe = __find_xattr(cur_addr, last_txattr_addr, NULL, index, len, name); - if (!*xe) { -- f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr", -+ f2fs_err(F2FS_I_SB(inode), "lookup inode (%lu) has corrupted xattr", - inode->i_ino); - set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); -- err = -EFSCORRUPTED; -+ err = -ENODATA; - f2fs_handle_error(F2FS_I_SB(inode), - ERROR_CORRUPTED_XATTR); - goto out; -@@ -583,13 +583,12 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) - - if ((void *)(entry) + sizeof(__u32) > last_base_addr || - (void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) { -- f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr", -+ f2fs_err(F2FS_I_SB(inode), "list inode (%lu) has corrupted xattr", - inode->i_ino); - set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); -- error = -EFSCORRUPTED; - f2fs_handle_error(F2FS_I_SB(inode), - ERROR_CORRUPTED_XATTR); -- goto cleanup; -+ break; - } - - if (!handler || (handler->list && !handler->list(dentry))) -@@ -650,7 +649,7 @@ static int __f2fs_setxattr(struct inode *inode, int index, - - if (size > MAX_VALUE_LEN(inode)) - return -E2BIG; -- -+retry: - error = read_all_xattrs(inode, ipage, &base_addr); - if (error) - return error; -@@ -660,7 +659,14 @@ static int __f2fs_setxattr(struct inode *inode, int index, - /* find entry with wanted name. */ - here = __find_xattr(base_addr, last_base_addr, NULL, index, len, name); - if (!here) { -- f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr", -+ if (!F2FS_I(inode)->i_xattr_nid) { -+ f2fs_notice(F2FS_I_SB(inode), -+ "recover xattr in inode (%lu)", inode->i_ino); -+ f2fs_recover_xattr_data(inode, NULL); -+ kfree(base_addr); -+ goto retry; -+ } -+ f2fs_err(F2FS_I_SB(inode), "set inode (%lu) has corrupted xattr", - inode->i_ino); - set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK); - error = -EFSCORRUPTED; -diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c -index 04a201584fa7c..23e6962cdd6e3 100644 ---- a/fs/gfs2/inode.c -+++ b/fs/gfs2/inode.c -@@ -1845,16 +1845,24 @@ out: - int gfs2_permission(struct user_namespace *mnt_userns, struct inode *inode, - int mask) - { -+ int may_not_block = mask & MAY_NOT_BLOCK; - struct gfs2_inode *ip; - struct gfs2_holder i_gh; -+ struct gfs2_glock *gl; - int error; - - gfs2_holder_mark_uninitialized(&i_gh); - ip = GFS2_I(inode); -- if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { -- if (mask & MAY_NOT_BLOCK) -+ gl = rcu_dereference_check(ip->i_gl, !may_not_block); -+ if (unlikely(!gl)) { -+ /* inode is getting torn down, must be RCU mode */ -+ WARN_ON_ONCE(!may_not_block); -+ return -ECHILD; -+ } -+ if (gfs2_glock_is_locked_by_me(gl) == NULL) { -+ if (may_not_block) - return -ECHILD; -- error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); -+ error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); - if (error) - return error; - } -diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c -index 1ed17226d9ede..86bc73bd770b4 100644 ---- a/fs/gfs2/quota.c -+++ b/fs/gfs2/quota.c -@@ -438,6 +438,17 @@ static int qd_check_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd, - (sync_gen && (qd->qd_sync_gen >= *sync_gen))) - return 0; - -+ /* -+ * If qd_change is 0 it means a pending quota change was negated. -+ * We should not sync it, but we still have a qd reference and slot -+ * reference taken by gfs2_quota_change -> do_qc that need to be put. -+ */ -+ if (!qd->qd_change && test_and_clear_bit(QDF_CHANGE, &qd->qd_flags)) { -+ slot_put(qd); -+ qd_put(qd); -+ return 0; -+ } -+ - if (!lockref_get_not_dead(&qd->qd_lockref)) - return 0; - -diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c -index 44c564f0bc622..302d1e43d7012 100644 ---- a/fs/gfs2/super.c -+++ b/fs/gfs2/super.c -@@ -1435,7 +1435,7 @@ out: - wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE); - gfs2_glock_add_to_lru(ip->i_gl); - gfs2_glock_put_eventually(ip->i_gl); -- ip->i_gl = NULL; -+ rcu_assign_pointer(ip->i_gl, NULL); - } - } - -diff --git a/fs/inode.c b/fs/inode.c -index 6ae760db13116..73ad1b0d47758 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -2501,6 +2501,22 @@ struct timespec64 current_time(struct inode *inode) - } - EXPORT_SYMBOL(current_time); - -+/** -+ * inode_set_ctime_current - set the ctime to current_time -+ * @inode: inode -+ * -+ * Set the inode->i_ctime to the current value for the inode. Returns -+ * the current value that was assigned to i_ctime. -+ */ -+struct timespec64 inode_set_ctime_current(struct inode *inode) -+{ -+ struct timespec64 now = current_time(inode); -+ -+ inode_set_ctime(inode, now.tv_sec, now.tv_nsec); -+ return now; -+} -+EXPORT_SYMBOL(inode_set_ctime_current); -+ - /** - * in_group_or_capable - check whether caller is CAP_FSETID privileged - * @mnt_userns: user namespace of the mount @inode was found from -diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c -index 357a3f7632e39..2426b89f1576f 100644 ---- a/fs/jbd2/recovery.c -+++ b/fs/jbd2/recovery.c -@@ -288,6 +288,8 @@ int jbd2_journal_recover(journal_t *journal) - journal_superblock_t * sb; - - struct recovery_info info; -+ errseq_t wb_err; -+ struct address_space *mapping; - - memset(&info, 0, sizeof(info)); - sb = journal->j_superblock; -@@ -305,6 +307,9 @@ int jbd2_journal_recover(journal_t *journal) - return 0; - } - -+ wb_err = 0; -+ mapping = journal->j_fs_dev->bd_inode->i_mapping; -+ errseq_check_and_advance(&mapping->wb_err, &wb_err); - err = do_one_pass(journal, &info, PASS_SCAN); - if (!err) - err = do_one_pass(journal, &info, PASS_REVOKE); -@@ -323,6 +328,9 @@ int jbd2_journal_recover(journal_t *journal) - - jbd2_journal_clear_revoke(journal); - err2 = sync_blockdev(journal->j_fs_dev); -+ if (!err) -+ err = err2; -+ err2 = errseq_check_and_advance(&mapping->wb_err, &wb_err); - if (!err) - err = err2; - /* Make sure all replayed data is on permanent storage */ -diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c -index e9d075cbd71ad..4d56f6081a5d2 100644 ---- a/fs/jfs/jfs_dmap.c -+++ b/fs/jfs/jfs_dmap.c -@@ -87,7 +87,7 @@ static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, - static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); - static int dbFindBits(u32 word, int l2nb); - static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); --static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); -+static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl); - static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, - int nblocks); - static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, -@@ -180,7 +180,8 @@ int dbMount(struct inode *ipbmap) - bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); - - bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); -- if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) { -+ if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE || -+ bmp->db_l2nbperpage < 0) { - err = -EINVAL; - goto err_release_metapage; - } -@@ -194,6 +195,12 @@ int dbMount(struct inode *ipbmap) - bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel); - bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); - bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); -+ if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 || -+ bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) { -+ err = -EINVAL; -+ goto err_release_metapage; -+ } -+ - bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); - bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight); - bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); -@@ -1710,7 +1717,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) - * dbFindLeaf() returns the index of the leaf at which - * free space was found. - */ -- rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx); -+ rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true); - - /* release the buffer. - */ -@@ -1957,7 +1964,7 @@ dbAllocDmapLev(struct bmap * bmp, - * free space. if sufficient free space is found, dbFindLeaf() - * returns the index of the leaf at which free space was found. - */ -- if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx)) -+ if (dbFindLeaf((dmtree_t *) &dp->tree, l2nb, &leafidx, false)) - return -ENOSPC; - - if (leafidx < 0) -@@ -2921,14 +2928,18 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval) - * leafidx - return pointer to be set to the index of the leaf - * describing at least l2nb free blocks if sufficient - * free blocks are found. -+ * is_ctl - determines if the tree is of type ctl - * - * RETURN VALUES: - * 0 - success - * -ENOSPC - insufficient free blocks. - */ --static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) -+static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl) - { - int ti, n = 0, k, x = 0; -+ int max_size; -+ -+ max_size = is_ctl ? CTLTREESIZE : TREESIZE; - - /* first check the root of the tree to see if there is - * sufficient free space. -@@ -2949,6 +2960,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) - /* sufficient free space found. move to the next - * level (or quit if this is the last level). - */ -+ if (x + n > max_size) -+ return -ENOSPC; - if (l2nb <= tp->dmt_stree[x + n]) - break; - } -diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c -index 4899663996d81..6ed2e1d4c894f 100644 ---- a/fs/jfs/jfs_imap.c -+++ b/fs/jfs/jfs_imap.c -@@ -1320,7 +1320,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) - int diAlloc(struct inode *pip, bool dir, struct inode *ip) - { - int rc, ino, iagno, addext, extno, bitno, sword; -- int nwords, rem, i, agno; -+ int nwords, rem, i, agno, dn_numag; - u32 mask, inosmap, extsmap; - struct inode *ipimap; - struct metapage *mp; -@@ -1356,6 +1356,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) - - /* get the ag number of this iag */ - agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb)); -+ dn_numag = JFS_SBI(pip->i_sb)->bmap->db_numag; -+ if (agno < 0 || agno > dn_numag) -+ return -EIO; - - if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) { - /* -diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index 5cf53def987e5..85a952143e9fb 100644 ---- a/fs/nfs/nfs4proc.c -+++ b/fs/nfs/nfs4proc.c -@@ -5628,7 +5628,7 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr, - - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE]; - nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0); -- nfs4_state_protect_write(server->nfs_client, clnt, msg, hdr); -+ nfs4_state_protect_write(hdr->ds_clp ? hdr->ds_clp : server->nfs_client, clnt, msg, hdr); - } - - static void nfs4_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data) -@@ -5669,7 +5669,8 @@ static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_mess - data->res.server = server; - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT]; - nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, 0); -- nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_COMMIT, clnt, msg); -+ nfs4_state_protect(data->ds_clp ? data->ds_clp : server->nfs_client, -+ NFS_SP4_MACH_CRED_COMMIT, clnt, msg); - } - - static int _nfs4_proc_commit(struct file *dst, struct nfs_commitargs *args, -@@ -8939,6 +8940,7 @@ void nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt, - - sp4_how = (adata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED); - -+try_again: - /* Test connection for session trunking. Async exchange_id call */ - task = nfs4_run_exchange_id(adata->clp, adata->cred, sp4_how, xprt); - if (IS_ERR(task)) -@@ -8951,11 +8953,15 @@ void nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt, - - if (status == 0) - rpc_clnt_xprt_switch_add_xprt(clnt, xprt); -- else if (rpc_clnt_xprt_switch_has_addr(clnt, -+ else if (status != -NFS4ERR_DELAY && rpc_clnt_xprt_switch_has_addr(clnt, - (struct sockaddr *)&xprt->addr)) - rpc_clnt_xprt_switch_remove_xprt(clnt, xprt); - - rpc_put_task(task); -+ if (status == -NFS4ERR_DELAY) { -+ ssleep(1); -+ goto try_again; -+ } - } - EXPORT_SYMBOL_GPL(nfs4_test_session_trunk); - -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index 96714e105d7bf..faecdbfa01a29 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -2799,7 +2799,7 @@ static int client_opens_release(struct inode *inode, struct file *file) - - /* XXX: alternatively, we could get/drop in seq start/stop */ - drop_client(clp); -- return 0; -+ return seq_release(inode, file); - } - - static const struct file_operations client_states_fops = { -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index 08d3a1f34ac6c..51eec4a8e82b2 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -2155,7 +2155,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) - ovl_trusted_xattr_handlers; - sb->s_fs_info = ofs; - sb->s_flags |= SB_POSIXACL; -- sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE; -+ sb->s_iflags |= SB_I_SKIP_SYNC; - - err = -ENOMEM; - root_dentry = ovl_get_root(sb, upperpath.dentry, oe); -diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c -index 72f2b373221ed..4a4c04a3b1a0a 100644 ---- a/fs/proc/proc_sysctl.c -+++ b/fs/proc/proc_sysctl.c -@@ -1814,7 +1814,6 @@ static const struct sysctl_alias sysctl_aliases[] = { - {"hung_task_panic", "kernel.hung_task_panic" }, - {"numa_zonelist_order", "vm.numa_zonelist_order" }, - {"softlockup_all_cpu_backtrace", "kernel.softlockup_all_cpu_backtrace" }, -- {"softlockup_panic", "kernel.softlockup_panic" }, - { } - }; - -@@ -1830,6 +1829,13 @@ static const char *sysctl_find_alias(char *param) - return NULL; - } - -+bool sysctl_is_alias(char *param) -+{ -+ const char *alias = sysctl_find_alias(param); -+ -+ return alias != NULL; -+} -+ - /* Set sysctl value passed on kernel command line. */ - static int process_sysctl_arg(char *param, char *val, - const char *unused, void *arg) -diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c -index f26ddfcaa5e61..b0cf3869d3bf5 100644 ---- a/fs/quota/dquot.c -+++ b/fs/quota/dquot.c -@@ -2403,6 +2403,20 @@ static int vfs_setup_quota_inode(struct inode *inode, int type) - if (sb_has_quota_loaded(sb, type)) - return -EBUSY; - -+ /* -+ * Quota files should never be encrypted. They should be thought of as -+ * filesystem metadata, not user data. New-style internal quota files -+ * cannot be encrypted by users anyway, but old-style external quota -+ * files could potentially be incorrectly created in an encrypted -+ * directory, hence this explicit check. Some reasons why encrypted -+ * quota files don't work include: (1) some filesystems that support -+ * encryption don't handle it in their quota_read and quota_write, and -+ * (2) cleaning up encrypted quota files at unmount would need special -+ * consideration, as quota files are cleaned up later than user files. -+ */ -+ if (IS_ENCRYPTED(inode)) -+ return -EINVAL; -+ - dqopt->files[type] = igrab(inode); - if (!dqopt->files[type]) - return -EIO; -diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c -index e41154ad96afc..ed396b186c5a4 100644 ---- a/fs/smb/client/cifs_debug.c -+++ b/fs/smb/client/cifs_debug.c -@@ -380,6 +380,11 @@ skip_rdma: - seq_printf(m, "\n\n\tSessions: "); - i = 0; - list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { -+ spin_lock(&ses->ses_lock); -+ if (ses->ses_status == SES_EXITING) { -+ spin_unlock(&ses->ses_lock); -+ continue; -+ } - i++; - if ((ses->serverDomain == NULL) || - (ses->serverOS == NULL) || -@@ -400,6 +405,7 @@ skip_rdma: - ses->ses_count, ses->serverOS, ses->serverNOS, - ses->capabilities, ses->ses_status); - } -+ spin_unlock(&ses->ses_lock); - - seq_printf(m, "\n\tSecurity type: %s ", - get_security_type_str(server->ops->select_sectype(server, ses->sectype))); -diff --git a/fs/smb/client/cifs_spnego.c b/fs/smb/client/cifs_spnego.c -index 342717bf1dc28..1e6819daaaa7e 100644 ---- a/fs/smb/client/cifs_spnego.c -+++ b/fs/smb/client/cifs_spnego.c -@@ -64,8 +64,8 @@ struct key_type cifs_spnego_key_type = { - * strlen(";sec=ntlmsspi") */ - #define MAX_MECH_STR_LEN 13 - --/* strlen of "host=" */ --#define HOST_KEY_LEN 5 -+/* strlen of ";host=" */ -+#define HOST_KEY_LEN 6 - - /* strlen of ";ip4=" or ";ip6=" */ - #define IP_KEY_LEN 5 -diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c -index 18d66497c42d1..33ea1440f4b06 100644 ---- a/fs/smb/client/cifsfs.c -+++ b/fs/smb/client/cifsfs.c -@@ -1186,6 +1186,7 @@ const char *cifs_get_link(struct dentry *dentry, struct inode *inode, - - const struct inode_operations cifs_symlink_inode_ops = { - .get_link = cifs_get_link, -+ .setattr = cifs_setattr, - .permission = cifs_permission, - .listxattr = cifs_listxattr, - }; -diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h -index cc458b98441c7..c403816d0b6c1 100644 ---- a/fs/smb/client/cifspdu.h -+++ b/fs/smb/client/cifspdu.h -@@ -2570,7 +2570,7 @@ typedef struct { - - - struct win_dev { -- unsigned char type[8]; /* IntxCHR or IntxBLK */ -+ unsigned char type[8]; /* IntxCHR or IntxBLK or LnxFIFO*/ - __le64 major; - __le64 minor; - } __attribute__((packed)); -diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h -index a914b88ca51a1..f37e4da0fe405 100644 ---- a/fs/smb/client/cifsproto.h -+++ b/fs/smb/client/cifsproto.h -@@ -79,7 +79,7 @@ extern char *cifs_compose_mount_options(const char *sb_mountdata, - const char *fullpath, const struct dfs_info3_param *ref, - char **devname); - extern void delete_mid(struct mid_q_entry *mid); --extern void release_mid(struct mid_q_entry *mid); -+void __release_mid(struct kref *refcount); - extern void cifs_wake_up_task(struct mid_q_entry *mid); - extern int cifs_handle_standard(struct TCP_Server_Info *server, - struct mid_q_entry *mid); -@@ -694,4 +694,9 @@ struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon); - void cifs_put_tcon_super(struct super_block *sb); - int cifs_wait_for_server_reconnect(struct TCP_Server_Info *server, bool retry); - -+static inline void release_mid(struct mid_q_entry *mid) -+{ -+ kref_put(&mid->refcount, __release_mid); -+} -+ - #endif /* _CIFSPROTO_H */ -diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c -index acb8951eb7576..6ca1e00b3f76a 100644 ---- a/fs/smb/client/connect.c -+++ b/fs/smb/client/connect.c -@@ -205,13 +205,14 @@ cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server, - /* If server is a channel, select the primary channel */ - pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; - -- spin_lock(&pserver->srv_lock); -+ /* if we need to signal just this channel */ - if (!all_channels) { -- pserver->tcpStatus = CifsNeedReconnect; -- spin_unlock(&pserver->srv_lock); -+ spin_lock(&server->srv_lock); -+ if (server->tcpStatus != CifsExiting) -+ server->tcpStatus = CifsNeedReconnect; -+ spin_unlock(&server->srv_lock); - return; - } -- spin_unlock(&pserver->srv_lock); - - spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { -@@ -4204,8 +4205,12 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, - is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses); - spin_unlock(&ses->chan_lock); - -- if (!is_binding) -+ if (!is_binding) { - ses->ses_status = SES_IN_SETUP; -+ -+ /* force iface_list refresh */ -+ ses->iface_last_update = 0; -+ } - spin_unlock(&ses->ses_lock); - - /* update ses ip_addr only for primary chan */ -diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c -index 9531ea2430899..05516309ec3ab 100644 ---- a/fs/smb/client/inode.c -+++ b/fs/smb/client/inode.c -@@ -567,6 +567,10 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path, - cifs_dbg(FYI, "Symlink\n"); - fattr->cf_mode |= S_IFLNK; - fattr->cf_dtype = DT_LNK; -+ } else if (memcmp("LnxFIFO", pbuf, 8) == 0) { -+ cifs_dbg(FYI, "FIFO\n"); -+ fattr->cf_mode |= S_IFIFO; -+ fattr->cf_dtype = DT_FIFO; - } else { - fattr->cf_mode |= S_IFREG; /* file? */ - fattr->cf_dtype = DT_REG; -diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c -index 1e3e22979604f..f0d164873500b 100644 ---- a/fs/smb/client/sess.c -+++ b/fs/smb/client/sess.c -@@ -186,7 +186,6 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) - } - - if (!(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) { -- ses->chan_max = 1; - spin_unlock(&ses->chan_lock); - cifs_server_dbg(VFS, "no multichannel support\n"); - return 0; -diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c -index 572293c18e16f..eaa5bd148810a 100644 ---- a/fs/smb/client/smb2misc.c -+++ b/fs/smb/client/smb2misc.c -@@ -787,7 +787,7 @@ __smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid, - { - struct close_cancelled_open *cancelled; - -- cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC); -+ cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); - if (!cancelled) - return -ENOMEM; - -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index efff7137412b4..2c1898803279a 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -5215,7 +5215,7 @@ smb2_make_node(unsigned int xid, struct inode *inode, - * over SMB2/SMB3 and Samba will do this with SMB3.1.1 POSIX Extensions - */ - -- if (!S_ISCHR(mode) && !S_ISBLK(mode)) -+ if (!S_ISCHR(mode) && !S_ISBLK(mode) && !S_ISFIFO(mode)) - return rc; - - cifs_dbg(FYI, "sfu compat create special file\n"); -@@ -5263,6 +5263,12 @@ smb2_make_node(unsigned int xid, struct inode *inode, - pdev->minor = cpu_to_le64(MINOR(dev)); - rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms, - &bytes_written, iov, 1); -+ } else if (S_ISFIFO(mode)) { -+ memcpy(pdev->type, "LnxFIFO", 8); -+ pdev->major = 0; -+ pdev->minor = 0; -+ rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms, -+ &bytes_written, iov, 1); - } - tcon->ses->server->ops->close(xid, tcon, &fid); - d_drop(dentry); -diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c -index 22954a9c7a6c7..69dbd08fd4419 100644 ---- a/fs/smb/client/smb2transport.c -+++ b/fs/smb/client/smb2transport.c -@@ -451,6 +451,8 @@ generate_smb3signingkey(struct cifs_ses *ses, - ptriplet->encryption.context, - ses->smb3encryptionkey, - SMB3_ENC_DEC_KEY_SIZE); -+ if (rc) -+ return rc; - rc = generate_key(ses, ptriplet->decryption.label, - ptriplet->decryption.context, - ses->smb3decryptionkey, -@@ -459,9 +461,6 @@ generate_smb3signingkey(struct cifs_ses *ses, - return rc; - } - -- if (rc) -- return rc; -- - #ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS - cifs_dbg(VFS, "%s: dumping generated AES session keys\n", __func__); - /* -diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c -index 87aea456ee903..8a1dd8407a3a7 100644 ---- a/fs/smb/client/transport.c -+++ b/fs/smb/client/transport.c -@@ -76,7 +76,7 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) - return temp; - } - --static void __release_mid(struct kref *refcount) -+void __release_mid(struct kref *refcount) - { - struct mid_q_entry *midEntry = - container_of(refcount, struct mid_q_entry, refcount); -@@ -156,15 +156,6 @@ static void __release_mid(struct kref *refcount) - mempool_free(midEntry, cifs_mid_poolp); - } - --void release_mid(struct mid_q_entry *mid) --{ -- struct TCP_Server_Info *server = mid->server; -- -- spin_lock(&server->mid_lock); -- kref_put(&mid->refcount, __release_mid); -- spin_unlock(&server->mid_lock); --} -- - void - delete_mid(struct mid_q_entry *mid) - { -diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c -index 998fa51f9b684..786b4f6e1263a 100644 ---- a/fs/smb/client/xattr.c -+++ b/fs/smb/client/xattr.c -@@ -150,10 +150,13 @@ static int cifs_xattr_set(const struct xattr_handler *handler, - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) - goto out; - -- if (pTcon->ses->server->ops->set_EA) -+ if (pTcon->ses->server->ops->set_EA) { - rc = pTcon->ses->server->ops->set_EA(xid, pTcon, - full_path, name, value, (__u16)size, - cifs_sb->local_nls, cifs_sb); -+ if (rc == 0) -+ inode_set_ctime_current(inode); -+ } - break; - - case XATTR_CIFS_ACL: -diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c -index a4421d9458d90..adc41b57b84c6 100644 ---- a/fs/smb/server/smb_common.c -+++ b/fs/smb/server/smb_common.c -@@ -372,11 +372,22 @@ static int smb1_allocate_rsp_buf(struct ksmbd_work *work) - return 0; - } - -+/** -+ * set_smb1_rsp_status() - set error type in smb response header -+ * @work: smb work containing smb response header -+ * @err: error code to set in response -+ */ -+static void set_smb1_rsp_status(struct ksmbd_work *work, __le32 err) -+{ -+ work->send_no_response = 1; -+} -+ - static struct smb_version_ops smb1_server_ops = { - .get_cmd_val = get_smb1_cmd_val, - .init_rsp_hdr = init_smb1_rsp_hdr, - .allocate_rsp_buf = smb1_allocate_rsp_buf, - .check_user_session = smb1_check_user_session, -+ .set_rsp_status = set_smb1_rsp_status, - }; - - static int smb1_negotiate(struct ksmbd_work *work) -diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c -index b05ff9b146b55..c24df86eb112b 100644 ---- a/fs/smb/server/smbacl.c -+++ b/fs/smb/server/smbacl.c -@@ -1107,6 +1107,7 @@ pass: - struct smb_acl *pdacl; - struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL; - int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size; -+ int pntsd_alloc_size; - - if (parent_pntsd->osidoffset) { - powner_sid = (struct smb_sid *)((char *)parent_pntsd + -@@ -1119,9 +1120,10 @@ pass: - pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4); - } - -- pntsd = kzalloc(sizeof(struct smb_ntsd) + powner_sid_size + -- pgroup_sid_size + sizeof(struct smb_acl) + -- nt_size, GFP_KERNEL); -+ pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size + -+ pgroup_sid_size + sizeof(struct smb_acl) + nt_size; -+ -+ pntsd = kzalloc(pntsd_alloc_size, GFP_KERNEL); - if (!pntsd) { - rc = -ENOMEM; - goto free_aces_base; -@@ -1136,6 +1138,27 @@ pass: - pntsd->gsidoffset = parent_pntsd->gsidoffset; - pntsd->dacloffset = parent_pntsd->dacloffset; - -+ if ((u64)le32_to_cpu(pntsd->osidoffset) + powner_sid_size > -+ pntsd_alloc_size) { -+ rc = -EINVAL; -+ kfree(pntsd); -+ goto free_aces_base; -+ } -+ -+ if ((u64)le32_to_cpu(pntsd->gsidoffset) + pgroup_sid_size > -+ pntsd_alloc_size) { -+ rc = -EINVAL; -+ kfree(pntsd); -+ goto free_aces_base; -+ } -+ -+ if ((u64)le32_to_cpu(pntsd->dacloffset) + sizeof(struct smb_acl) + nt_size > -+ pntsd_alloc_size) { -+ rc = -EINVAL; -+ kfree(pntsd); -+ goto free_aces_base; -+ } -+ - if (pntsd->osidoffset) { - struct smb_sid *owner_sid = (struct smb_sid *)((char *)pntsd + - le32_to_cpu(pntsd->osidoffset)); -diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c -index 0e5dba2343ea1..e6609067ef261 100644 ---- a/fs/xfs/xfs_inode_item_recover.c -+++ b/fs/xfs/xfs_inode_item_recover.c -@@ -369,24 +369,26 @@ xlog_recover_inode_commit_pass2( - * superblock flag to determine whether we need to look at di_flushiter - * to skip replay when the on disk inode is newer than the log one - */ -- if (!xfs_has_v3inodes(mp) && -- ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) { -- /* -- * Deal with the wrap case, DI_MAX_FLUSH is less -- * than smaller numbers -- */ -- if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH && -- ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) { -- /* do nothing */ -- } else { -- trace_xfs_log_recover_inode_skip(log, in_f); -- error = 0; -- goto out_release; -+ if (!xfs_has_v3inodes(mp)) { -+ if (ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) { -+ /* -+ * Deal with the wrap case, DI_MAX_FLUSH is less -+ * than smaller numbers -+ */ -+ if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH && -+ ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) { -+ /* do nothing */ -+ } else { -+ trace_xfs_log_recover_inode_skip(log, in_f); -+ error = 0; -+ goto out_release; -+ } - } -+ -+ /* Take the opportunity to reset the flush iteration count */ -+ ldip->di_flushiter = 0; - } - -- /* Take the opportunity to reset the flush iteration count */ -- ldip->di_flushiter = 0; - - if (unlikely(S_ISREG(ldip->di_mode))) { - if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) && -diff --git a/include/linux/damon.h b/include/linux/damon.h -index 620ada094c3b2..b13be7ae2275e 100644 ---- a/include/linux/damon.h -+++ b/include/linux/damon.h -@@ -559,6 +559,13 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx) - return ctx->ops.id == DAMON_OPS_VADDR || ctx->ops.id == DAMON_OPS_FVADDR; - } - -+static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs) -+{ -+ /* {aggr,sample}_interval are unsigned long, hence could overflow */ -+ return min(attrs->aggr_interval / attrs->sample_interval, -+ (unsigned long)UINT_MAX); -+} -+ - - int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive); - int damon_stop(struct damon_ctx **ctxs, int nr_ctxs); -diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h -index 99dc7bfbcd3c3..7dacc109eb251 100644 ---- a/include/linux/ethtool.h -+++ b/include/linux/ethtool.h -@@ -836,10 +836,10 @@ int ethtool_get_phc_vclocks(struct net_device *dev, int **vclock_index); - - /** - * ethtool_sprintf - Write formatted string to ethtool string data -- * @data: Pointer to start of string to update -+ * @data: Pointer to a pointer to the start of string to update - * @fmt: Format of string to write - * -- * Write formatted string to data. Update data to point at start of -+ * Write formatted string to *data. Update *data to point at start of - * next string. - */ - extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...); -diff --git a/include/linux/fs.h b/include/linux/fs.h -index dc745317e1bdb..b6af6abc7a77f 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1812,7 +1812,50 @@ static inline bool fsuidgid_has_mapping(struct super_block *sb, - kgid_has_mapping(fs_userns, kgid); - } - --extern struct timespec64 current_time(struct inode *inode); -+struct timespec64 current_time(struct inode *inode); -+struct timespec64 inode_set_ctime_current(struct inode *inode); -+ -+/** -+ * inode_get_ctime - fetch the current ctime from the inode -+ * @inode: inode from which to fetch ctime -+ * -+ * Grab the current ctime from the inode and return it. -+ */ -+static inline struct timespec64 inode_get_ctime(const struct inode *inode) -+{ -+ return inode->i_ctime; -+} -+ -+/** -+ * inode_set_ctime_to_ts - set the ctime in the inode -+ * @inode: inode in which to set the ctime -+ * @ts: value to set in the ctime field -+ * -+ * Set the ctime in @inode to @ts -+ */ -+static inline struct timespec64 inode_set_ctime_to_ts(struct inode *inode, -+ struct timespec64 ts) -+{ -+ inode->i_ctime = ts; -+ return ts; -+} -+ -+/** -+ * inode_set_ctime - set the ctime in the inode -+ * @inode: inode in which to set the ctime -+ * @sec: tv_sec value to set -+ * @nsec: tv_nsec value to set -+ * -+ * Set the ctime in @inode to { @sec, @nsec } -+ */ -+static inline struct timespec64 inode_set_ctime(struct inode *inode, -+ time64_t sec, long nsec) -+{ -+ struct timespec64 ts = { .tv_sec = sec, -+ .tv_nsec = nsec }; -+ -+ return inode_set_ctime_to_ts(inode, ts); -+} - - /* - * Snapshotting support. -diff --git a/include/linux/generic-radix-tree.h b/include/linux/generic-radix-tree.h -index 107613f7d7920..f6cd0f909d9fb 100644 ---- a/include/linux/generic-radix-tree.h -+++ b/include/linux/generic-radix-tree.h -@@ -38,6 +38,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -184,6 +185,12 @@ void *__genradix_iter_peek(struct genradix_iter *, struct __genradix *, size_t); - static inline void __genradix_iter_advance(struct genradix_iter *iter, - size_t obj_size) - { -+ if (iter->offset + obj_size < iter->offset) { -+ iter->offset = SIZE_MAX; -+ iter->pos = SIZE_MAX; -+ return; -+ } -+ - iter->offset += obj_size; - - if (!is_power_of_2(obj_size) && -diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h -index 4a97a6db9bcec..02b19c508b78f 100644 ---- a/include/linux/lsm_hook_defs.h -+++ b/include/linux/lsm_hook_defs.h -@@ -48,7 +48,7 @@ LSM_HOOK(int, 0, quota_on, struct dentry *dentry) - LSM_HOOK(int, 0, syslog, int type) - LSM_HOOK(int, 0, settime, const struct timespec64 *ts, - const struct timezone *tz) --LSM_HOOK(int, 0, vm_enough_memory, struct mm_struct *mm, long pages) -+LSM_HOOK(int, 1, vm_enough_memory, struct mm_struct *mm, long pages) - LSM_HOOK(int, 0, bprm_creds_for_exec, struct linux_binprm *bprm) - LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, struct file *file) - LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm) -@@ -266,7 +266,7 @@ LSM_HOOK(void, LSM_RET_VOID, release_secctx, char *secdata, u32 seclen) - LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode) - LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen) - LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen) --LSM_HOOK(int, 0, inode_getsecctx, struct inode *inode, void **ctx, -+LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode, void **ctx, - u32 *ctxlen) - - #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE) -diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h -index daa2f40d9ce65..7b12eebc5586d 100644 ---- a/include/linux/mmc/card.h -+++ b/include/linux/mmc/card.h -@@ -295,7 +295,9 @@ struct mmc_card { - #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ - #define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14) /* Disable broken SD discard support */ - #define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */ -+#define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16) /* Don't flush cache until the write has occurred */ - -+ bool written_flag; /* Indicates eMMC has been written since power on */ - bool reenable_cmdq; /* Re-enable Command Queue */ - - unsigned int erase_size; /* erase size in sectors */ -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 0df425bf9bd75..8cfcc5d454512 100644 ---- a/include/linux/preempt.h -+++ b/include/linux/preempt.h -@@ -98,14 +98,21 @@ static __always_inline unsigned char interrupt_context_level(void) - return level; - } - -+/* -+ * These macro definitions avoid redundant invocations of preempt_count() -+ * because such invocations would result in redundant loads given that -+ * preempt_count() is commonly implemented with READ_ONCE(). -+ */ -+ - #define nmi_count() (preempt_count() & NMI_MASK) - #define hardirq_count() (preempt_count() & HARDIRQ_MASK) - #ifdef CONFIG_PREEMPT_RT - # define softirq_count() (current->softirq_disable_cnt & SOFTIRQ_MASK) -+# define irq_count() ((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) | softirq_count()) - #else - # define softirq_count() (preempt_count() & SOFTIRQ_MASK) -+# define irq_count() (preempt_count() & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK)) - #endif --#define irq_count() (nmi_count() | hardirq_count() | softirq_count()) - - /* - * Macros to retrieve the current execution context: -@@ -118,7 +125,11 @@ static __always_inline unsigned char interrupt_context_level(void) - #define in_nmi() (nmi_count()) - #define in_hardirq() (hardirq_count()) - #define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) --#define in_task() (!(in_nmi() | in_hardirq() | in_serving_softirq())) -+#ifdef CONFIG_PREEMPT_RT -+# define in_task() (!((preempt_count() & (NMI_MASK | HARDIRQ_MASK)) | in_serving_softirq())) -+#else -+# define in_task() (!(preempt_count() & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) -+#endif - - /* - * The following macros are deprecated and should not be used in new code: -diff --git a/include/linux/pwm.h b/include/linux/pwm.h -index 161e91167b9c0..5e88f1b591832 100644 ---- a/include/linux/pwm.h -+++ b/include/linux/pwm.h -@@ -41,8 +41,8 @@ struct pwm_args { - }; - - enum { -- PWMF_REQUESTED = 1 << 0, -- PWMF_EXPORTED = 1 << 1, -+ PWMF_REQUESTED = 0, -+ PWMF_EXPORTED = 1, - }; - - /* -diff --git a/include/linux/socket.h b/include/linux/socket.h -index de3701a2a2129..1db29aab8f9c3 100644 ---- a/include/linux/socket.h -+++ b/include/linux/socket.h -@@ -376,6 +376,7 @@ struct ucred { - #define SOL_MPTCP 284 - #define SOL_MCTP 285 - #define SOL_SMC 286 -+#define SOL_VSOCK 287 - - /* IPX options */ - #define IPX_TYPE 1 -diff --git a/include/linux/string.h b/include/linux/string.h -index 26ab8928d8661..422606e98cc42 100644 ---- a/include/linux/string.h -+++ b/include/linux/string.h -@@ -5,7 +5,9 @@ - #include /* for inline */ - #include /* for size_t */ - #include /* for NULL */ -+#include /* for ERR_PTR() */ - #include /* for E2BIG */ -+#include /* for check_mul_overflow() */ - #include - #include - -@@ -14,6 +16,44 @@ extern void *memdup_user(const void __user *, size_t); - extern void *vmemdup_user(const void __user *, size_t); - extern void *memdup_user_nul(const void __user *, size_t); - -+/** -+ * memdup_array_user - duplicate array from user space -+ * @src: source address in user space -+ * @n: number of array members to copy -+ * @size: size of one array member -+ * -+ * Return: an ERR_PTR() on failure. Result is physically -+ * contiguous, to be freed by kfree(). -+ */ -+static inline void *memdup_array_user(const void __user *src, size_t n, size_t size) -+{ -+ size_t nbytes; -+ -+ if (check_mul_overflow(n, size, &nbytes)) -+ return ERR_PTR(-EOVERFLOW); -+ -+ return memdup_user(src, nbytes); -+} -+ -+/** -+ * vmemdup_array_user - duplicate array from user space -+ * @src: source address in user space -+ * @n: number of array members to copy -+ * @size: size of one array member -+ * -+ * Return: an ERR_PTR() on failure. Result may be not -+ * physically contiguous. Use kvfree() to free. -+ */ -+static inline void *vmemdup_array_user(const void __user *src, size_t n, size_t size) -+{ -+ size_t nbytes; -+ -+ if (check_mul_overflow(n, size, &nbytes)) -+ return ERR_PTR(-EOVERFLOW); -+ -+ return vmemdup_user(src, nbytes); -+} -+ - /* - * Include machine specific inline routines - */ -diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h -index 770ef2cb57752..c794b0ce4e782 100644 ---- a/include/linux/sunrpc/clnt.h -+++ b/include/linux/sunrpc/clnt.h -@@ -84,6 +84,7 @@ struct rpc_clnt { - }; - const struct cred *cl_cred; - unsigned int cl_max_connect; /* max number of transports not to the same IP */ -+ struct super_block *pipefs_sb; - }; - - /* -diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h -index 780690dc08cda..a207c7ed41bd2 100644 ---- a/include/linux/sysctl.h -+++ b/include/linux/sysctl.h -@@ -238,6 +238,7 @@ extern void __register_sysctl_init(const char *path, struct ctl_table *table, - extern struct ctl_table_header *register_sysctl_mount_point(const char *path); - - void do_sysctl_args(void); -+bool sysctl_is_alias(char *param); - int do_proc_douintvec(struct ctl_table *table, int write, - void *buffer, size_t *lenp, loff_t *ppos, - int (*conv)(unsigned long *lvalp, -@@ -301,6 +302,11 @@ static inline void setup_sysctl_set(struct ctl_table_set *p, - static inline void do_sysctl_args(void) - { - } -+ -+static inline bool sysctl_is_alias(char *param) -+{ -+ return false; -+} - #endif /* CONFIG_SYSCTL */ - - int sysctl_max_threads(struct ctl_table *table, int write, void *buffer, -diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h -index 422f4ca656cf9..c8b5e9781d01a 100644 ---- a/include/linux/trace_events.h -+++ b/include/linux/trace_events.h -@@ -478,6 +478,7 @@ enum { - EVENT_FILE_FL_TRIGGER_COND_BIT, - EVENT_FILE_FL_PID_FILTER_BIT, - EVENT_FILE_FL_WAS_ENABLED_BIT, -+ EVENT_FILE_FL_FREED_BIT, - }; - - extern struct trace_event_file *trace_get_event_file(const char *instance, -@@ -616,6 +617,7 @@ extern int __kprobe_event_add_fields(struct dynevent_cmd *cmd, ...); - * TRIGGER_COND - When set, one or more triggers has an associated filter - * PID_FILTER - When set, the event is filtered based on pid - * WAS_ENABLED - Set when enabled to know to clear trace on module removal -+ * FREED - File descriptor is freed, all fields should be considered invalid - */ - enum { - EVENT_FILE_FL_ENABLED = (1 << EVENT_FILE_FL_ENABLED_BIT), -@@ -629,6 +631,7 @@ enum { - EVENT_FILE_FL_TRIGGER_COND = (1 << EVENT_FILE_FL_TRIGGER_COND_BIT), - EVENT_FILE_FL_PID_FILTER = (1 << EVENT_FILE_FL_PID_FILTER_BIT), - EVENT_FILE_FL_WAS_ENABLED = (1 << EVENT_FILE_FL_WAS_ENABLED_BIT), -+ EVENT_FILE_FL_FREED = (1 << EVENT_FILE_FL_FREED_BIT), - }; - - struct trace_event_file { -@@ -657,6 +660,7 @@ struct trace_event_file { - * caching and such. Which is mostly OK ;-) - */ - unsigned long flags; -+ atomic_t ref; /* ref count for opened files */ - atomic_t sm_ref; /* soft-mode reference counter */ - atomic_t tm_ref; /* trigger-mode reference counter */ - }; -diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h -index 3ca41b9da6473..5d052e193a85c 100644 ---- a/include/linux/workqueue.h -+++ b/include/linux/workqueue.h -@@ -222,18 +222,16 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } - * to generate better code. - */ - #ifdef CONFIG_LOCKDEP --#define __INIT_WORK(_work, _func, _onstack) \ -+#define __INIT_WORK_KEY(_work, _func, _onstack, _key) \ - do { \ -- static struct lock_class_key __key; \ -- \ - __init_work((_work), _onstack); \ - (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ -- lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, &__key, 0); \ -+ lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, (_key), 0); \ - INIT_LIST_HEAD(&(_work)->entry); \ - (_work)->func = (_func); \ - } while (0) - #else --#define __INIT_WORK(_work, _func, _onstack) \ -+#define __INIT_WORK_KEY(_work, _func, _onstack, _key) \ - do { \ - __init_work((_work), _onstack); \ - (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ -@@ -242,12 +240,22 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } - } while (0) - #endif - -+#define __INIT_WORK(_work, _func, _onstack) \ -+ do { \ -+ static __maybe_unused struct lock_class_key __key; \ -+ \ -+ __INIT_WORK_KEY(_work, _func, _onstack, &__key); \ -+ } while (0) -+ - #define INIT_WORK(_work, _func) \ - __INIT_WORK((_work), (_func), 0) - - #define INIT_WORK_ONSTACK(_work, _func) \ - __INIT_WORK((_work), (_func), 1) - -+#define INIT_WORK_ONSTACK_KEY(_work, _func, _key) \ -+ __INIT_WORK_KEY((_work), (_func), 1, _key) -+ - #define __INIT_DELAYED_WORK(_work, _func, _tflags) \ - do { \ - INIT_WORK(&(_work)->work, (_func)); \ -@@ -681,8 +689,32 @@ static inline long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) - return fn(arg); - } - #else --long work_on_cpu(int cpu, long (*fn)(void *), void *arg); --long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg); -+long work_on_cpu_key(int cpu, long (*fn)(void *), -+ void *arg, struct lock_class_key *key); -+/* -+ * A new key is defined for each caller to make sure the work -+ * associated with the function doesn't share its locking class. -+ */ -+#define work_on_cpu(_cpu, _fn, _arg) \ -+({ \ -+ static struct lock_class_key __key; \ -+ \ -+ work_on_cpu_key(_cpu, _fn, _arg, &__key); \ -+}) -+ -+long work_on_cpu_safe_key(int cpu, long (*fn)(void *), -+ void *arg, struct lock_class_key *key); -+ -+/* -+ * A new key is defined for each caller to make sure the work -+ * associated with the function doesn't share its locking class. -+ */ -+#define work_on_cpu_safe(_cpu, _fn, _arg) \ -+({ \ -+ static struct lock_class_key __key; \ -+ \ -+ work_on_cpu_safe_key(_cpu, _fn, _arg, &__key); \ -+}) - #endif /* CONFIG_SMP */ - - #ifdef CONFIG_FREEZER -diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h -index d1f81a6d7773b..c726da3b7d68a 100644 ---- a/include/net/netfilter/nf_tables.h -+++ b/include/net/netfilter/nf_tables.h -@@ -177,9 +177,9 @@ static inline __be32 nft_reg_load_be32(const u32 *sreg) - return *(__force __be32 *)sreg; - } - --static inline void nft_reg_store64(u32 *dreg, u64 val) -+static inline void nft_reg_store64(u64 *dreg, u64 val) - { -- put_unaligned(val, (u64 *)dreg); -+ put_unaligned(val, dreg); - } - - static inline u64 nft_reg_load64(const u32 *sreg) -diff --git a/include/net/sock.h b/include/net/sock.h -index a1fcbb2a8a2ce..b6027b01c2455 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -2032,21 +2032,33 @@ static inline void sk_tx_queue_set(struct sock *sk, int tx_queue) - /* sk_tx_queue_mapping accept only upto a 16-bit value */ - if (WARN_ON_ONCE((unsigned short)tx_queue >= USHRT_MAX)) - return; -- sk->sk_tx_queue_mapping = tx_queue; -+ /* Paired with READ_ONCE() in sk_tx_queue_get() and -+ * other WRITE_ONCE() because socket lock might be not held. -+ */ -+ WRITE_ONCE(sk->sk_tx_queue_mapping, tx_queue); - } - - #define NO_QUEUE_MAPPING USHRT_MAX - - static inline void sk_tx_queue_clear(struct sock *sk) - { -- sk->sk_tx_queue_mapping = NO_QUEUE_MAPPING; -+ /* Paired with READ_ONCE() in sk_tx_queue_get() and -+ * other WRITE_ONCE() because socket lock might be not held. -+ */ -+ WRITE_ONCE(sk->sk_tx_queue_mapping, NO_QUEUE_MAPPING); - } - - static inline int sk_tx_queue_get(const struct sock *sk) - { -- if (sk && sk->sk_tx_queue_mapping != NO_QUEUE_MAPPING) -- return sk->sk_tx_queue_mapping; -+ if (sk) { -+ /* Paired with WRITE_ONCE() in sk_tx_queue_clear() -+ * and sk_tx_queue_set(). -+ */ -+ int val = READ_ONCE(sk->sk_tx_queue_mapping); - -+ if (val != NO_QUEUE_MAPPING) -+ return val; -+ } - return -1; - } - -@@ -2195,7 +2207,7 @@ static inline void __dst_negative_advice(struct sock *sk) - if (ndst != dst) { - rcu_assign_pointer(sk->sk_dst_cache, ndst); - sk_tx_queue_clear(sk); -- sk->sk_dst_pending_confirm = 0; -+ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); - } - } - } -@@ -2212,7 +2224,7 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst) - struct dst_entry *old_dst; - - sk_tx_queue_clear(sk); -- sk->sk_dst_pending_confirm = 0; -+ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); - old_dst = rcu_dereference_protected(sk->sk_dst_cache, - lockdep_sock_is_held(sk)); - rcu_assign_pointer(sk->sk_dst_cache, dst); -@@ -2225,7 +2237,7 @@ sk_dst_set(struct sock *sk, struct dst_entry *dst) - struct dst_entry *old_dst; - - sk_tx_queue_clear(sk); -- sk->sk_dst_pending_confirm = 0; -+ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); - old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst); - dst_release(old_dst); - } -diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h -index 528279056b3ab..1a5f90b0a5463 100644 ---- a/include/sound/soc-acpi.h -+++ b/include/sound/soc-acpi.h -@@ -67,6 +67,10 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg) - * @i2s_link_mask: I2S/TDM links enabled on the board - * @num_dai_drivers: number of elements in @dai_drivers - * @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode -+ * @subsystem_vendor: optional PCI SSID vendor value -+ * @subsystem_device: optional PCI SSID device value -+ * @subsystem_id_set: true if a value has been written to -+ * subsystem_vendor and subsystem_device. - */ - struct snd_soc_acpi_mach_params { - u32 acpi_ipc_irq_index; -@@ -79,6 +83,9 @@ struct snd_soc_acpi_mach_params { - u32 i2s_link_mask; - u32 num_dai_drivers; - struct snd_soc_dai_driver *dai_drivers; -+ unsigned short subsystem_vendor; -+ unsigned short subsystem_device; -+ bool subsystem_id_set; - }; - - /** -diff --git a/include/sound/soc-card.h b/include/sound/soc-card.h -index 9d31a5c0db33c..40d3023cf0d16 100644 ---- a/include/sound/soc-card.h -+++ b/include/sound/soc-card.h -@@ -44,6 +44,43 @@ int snd_soc_card_add_dai_link(struct snd_soc_card *card, - void snd_soc_card_remove_dai_link(struct snd_soc_card *card, - struct snd_soc_dai_link *dai_link); - -+#ifdef CONFIG_PCI -+static inline void snd_soc_card_set_pci_ssid(struct snd_soc_card *card, -+ unsigned short vendor, -+ unsigned short device) -+{ -+ card->pci_subsystem_vendor = vendor; -+ card->pci_subsystem_device = device; -+ card->pci_subsystem_set = true; -+} -+ -+static inline int snd_soc_card_get_pci_ssid(struct snd_soc_card *card, -+ unsigned short *vendor, -+ unsigned short *device) -+{ -+ if (!card->pci_subsystem_set) -+ return -ENOENT; -+ -+ *vendor = card->pci_subsystem_vendor; -+ *device = card->pci_subsystem_device; -+ -+ return 0; -+} -+#else /* !CONFIG_PCI */ -+static inline void snd_soc_card_set_pci_ssid(struct snd_soc_card *card, -+ unsigned short vendor, -+ unsigned short device) -+{ -+} -+ -+static inline int snd_soc_card_get_pci_ssid(struct snd_soc_card *card, -+ unsigned short *vendor, -+ unsigned short *device) -+{ -+ return -ENOENT; -+} -+#endif /* CONFIG_PCI */ -+ - /* device driver data */ - static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, - void *data) -diff --git a/include/sound/soc.h b/include/sound/soc.h -index 37bbfc8b45cb2..108617cea9c67 100644 ---- a/include/sound/soc.h -+++ b/include/sound/soc.h -@@ -911,6 +911,17 @@ struct snd_soc_card { - #ifdef CONFIG_DMI - char dmi_longname[80]; - #endif /* CONFIG_DMI */ -+ -+#ifdef CONFIG_PCI -+ /* -+ * PCI does not define 0 as invalid, so pci_subsystem_set indicates -+ * whether a value has been written to these fields. -+ */ -+ unsigned short pci_subsystem_vendor; -+ unsigned short pci_subsystem_device; -+ bool pci_subsystem_set; -+#endif /* CONFIG_PCI */ -+ - char topology_shortname[32]; - - struct device *dev; -diff --git a/include/sound/sof.h b/include/sound/sof.h -index 341fef19e6124..1caeb7bf109b4 100644 ---- a/include/sound/sof.h -+++ b/include/sound/sof.h -@@ -63,6 +63,14 @@ struct snd_sof_pdata { - const char *name; - const char *platform; - -+ /* -+ * PCI SSID. As PCI does not define 0 as invalid, the subsystem_id_set -+ * flag indicates that a value has been written to these members. -+ */ -+ unsigned short subsystem_vendor; -+ unsigned short subsystem_device; -+ bool subsystem_id_set; -+ - struct device *dev; - - /* indicate how many first bytes shouldn't be loaded into DSP memory. */ -diff --git a/include/uapi/linux/vm_sockets.h b/include/uapi/linux/vm_sockets.h -index c60ca33eac594..ed07181d4eff9 100644 ---- a/include/uapi/linux/vm_sockets.h -+++ b/include/uapi/linux/vm_sockets.h -@@ -191,4 +191,21 @@ struct sockaddr_vm { - - #define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9) - -+/* MSG_ZEROCOPY notifications are encoded in the standard error format, -+ * sock_extended_err. See Documentation/networking/msg_zerocopy.rst in -+ * kernel source tree for more details. -+ */ -+ -+/* 'cmsg_level' field value of 'struct cmsghdr' for notification parsing -+ * when MSG_ZEROCOPY flag is used on transmissions. -+ */ -+ -+#define SOL_VSOCK 287 -+ -+/* 'cmsg_type' field value of 'struct cmsghdr' for notification parsing -+ * when MSG_ZEROCOPY flag is used on transmissions. -+ */ -+ -+#define VSOCK_RECVERR 1 -+ - #endif /* _UAPI_VM_SOCKETS_H */ -diff --git a/init/main.c b/init/main.c -index fe378351e8a95..87a52bdb41d67 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -533,6 +533,10 @@ static int __init unknown_bootoption(char *param, char *val, - { - size_t len = strlen(param); - -+ /* Handle params aliased to sysctls */ -+ if (sysctl_is_alias(param)) -+ return 0; -+ - repair_env_string(param, val); - - /* Handle obsolete-style parameters */ -diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c -index 65075f1e4ac8c..7a98cd176a127 100644 ---- a/kernel/audit_watch.c -+++ b/kernel/audit_watch.c -@@ -527,11 +527,18 @@ int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark) - unsigned long ino; - dev_t dev; - -- exe_file = get_task_exe_file(tsk); -+ /* only do exe filtering if we are recording @current events/records */ -+ if (tsk != current) -+ return 0; -+ -+ if (!current->mm) -+ return 0; -+ exe_file = get_mm_exe_file(current->mm); - if (!exe_file) - return 0; - ino = file_inode(exe_file)->i_ino; - dev = file_inode(exe_file)->i_sb->s_dev; - fput(exe_file); -+ - return audit_mark_compare(mark, ino, dev); - } -diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c -index 64706723624b9..7225cb67c0d3a 100644 ---- a/kernel/bpf/core.c -+++ b/kernel/bpf/core.c -@@ -608,7 +608,11 @@ static __always_inline int bpf_tree_comp(void *key, struct latch_tree_node *n) - - if (val < ksym->start) - return -1; -- if (val >= ksym->end) -+ /* Ensure that we detect return addresses as part of the program, when -+ * the final instruction is a call for a program part of the stack -+ * trace. Therefore, do val > ksym->end instead of val >= ksym->end. -+ */ -+ if (val > ksym->end) - return 1; - - return 0; -diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c -index eb3f52be115d6..12d360d80c149 100644 ---- a/kernel/bpf/verifier.c -+++ b/kernel/bpf/verifier.c -@@ -978,7 +978,8 @@ static void print_verifier_state(struct bpf_verifier_env *env, - if (state->in_async_callback_fn) - verbose(env, " async_cb"); - verbose(env, "\n"); -- mark_verifier_state_clean(env); -+ if (!print_all) -+ mark_verifier_state_clean(env); - } - - static inline u32 vlog_alignment(u32 pos) -@@ -2595,7 +2596,12 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, - if (class == BPF_ALU || class == BPF_ALU64) { - if (!(*reg_mask & dreg)) - return 0; -- if (opcode == BPF_MOV) { -+ if (opcode == BPF_END || opcode == BPF_NEG) { -+ /* sreg is reserved and unused -+ * dreg still need precision before this insn -+ */ -+ return 0; -+ } else if (opcode == BPF_MOV) { - if (BPF_SRC(insn->code) == BPF_X) { - /* dreg = sreg - * dreg needs precision after this insn -@@ -3291,7 +3297,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, - insn->imm != 0 && env->bpf_capable) { - struct bpf_reg_state fake_reg = {}; - -- __mark_reg_known(&fake_reg, (u32)insn->imm); -+ __mark_reg_known(&fake_reg, insn->imm); - fake_reg.type = SCALAR_VALUE; - save_register_state(state, spi, &fake_reg, size); - } else if (reg && is_spillable_regtype(reg->type)) { -@@ -10476,6 +10482,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, - !sanitize_speculative_path(env, insn, *insn_idx + 1, - *insn_idx)) - return -EFAULT; -+ if (env->log.level & BPF_LOG_LEVEL) -+ print_insn_state(env, this_branch->frame[this_branch->curframe]); - *insn_idx += insn->off; - return 0; - } else if (pred == 0) { -@@ -10488,6 +10496,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, - *insn_idx + insn->off + 1, - *insn_idx)) - return -EFAULT; -+ if (env->log.level & BPF_LOG_LEVEL) -+ print_insn_state(env, this_branch->frame[this_branch->curframe]); - return 0; - } - -diff --git a/kernel/cpu.c b/kernel/cpu.c -index f8eb1825f704f..0e4d362e90825 100644 ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -1243,11 +1243,14 @@ static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target) - /* - * Ensure that the control task does not run on the to be offlined - * CPU to prevent a deadlock against cfs_b->period_timer. -+ * Also keep at least one housekeeping cpu onlined to avoid generating -+ * an empty sched_domain span. - */ -- cpu = cpumask_any_but(cpu_online_mask, cpu); -- if (cpu >= nr_cpu_ids) -- return -EBUSY; -- return work_on_cpu(cpu, __cpu_down_maps_locked, &work); -+ for_each_cpu_and(cpu, cpu_online_mask, housekeeping_cpumask(HK_TYPE_DOMAIN)) { -+ if (cpu != work.cpu) -+ return work_on_cpu(cpu, __cpu_down_maps_locked, &work); -+ } -+ return -EBUSY; - } - - static int cpu_down(unsigned int cpu, enum cpuhp_state target) -diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c -index d5e9ccde3ab8e..3a904d8697c8f 100644 ---- a/kernel/debug/debug_core.c -+++ b/kernel/debug/debug_core.c -@@ -1006,6 +1006,9 @@ void kgdb_panic(const char *msg) - if (panic_timeout) - return; - -+ debug_locks_off(); -+ console_flush_on_panic(CONSOLE_FLUSH_PENDING); -+ - if (dbg_kdb_mode) - kdb_printf("PANIC: %s\n", msg); - -diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c -index 273a0fe7910a5..45965f13757e4 100644 ---- a/kernel/events/ring_buffer.c -+++ b/kernel/events/ring_buffer.c -@@ -699,6 +699,12 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event, - watermark = 0; - } - -+ /* -+ * kcalloc_node() is unable to allocate buffer if the size is larger -+ * than: PAGE_SIZE << MAX_ORDER; directly bail out in this case. -+ */ -+ if (get_order((unsigned long)nr_pages * sizeof(void *)) > MAX_ORDER) -+ return -ENOMEM; - rb->aux_pages = kcalloc_node(nr_pages, sizeof(void *), GFP_KERNEL, - node); - if (!rb->aux_pages) -diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c -index c653cd31548d0..5a452b94b6434 100644 ---- a/kernel/irq/generic-chip.c -+++ b/kernel/irq/generic-chip.c -@@ -544,21 +544,34 @@ EXPORT_SYMBOL_GPL(irq_setup_alt_chip); - void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, - unsigned int clr, unsigned int set) - { -- unsigned int i = gc->irq_base; -+ unsigned int i, virq; - - raw_spin_lock(&gc_lock); - list_del(&gc->list); - raw_spin_unlock(&gc_lock); - -- for (; msk; msk >>= 1, i++) { -+ for (i = 0; msk; msk >>= 1, i++) { - if (!(msk & 0x01)) - continue; - -+ /* -+ * Interrupt domain based chips store the base hardware -+ * interrupt number in gc::irq_base. Otherwise gc::irq_base -+ * contains the base Linux interrupt number. -+ */ -+ if (gc->domain) { -+ virq = irq_find_mapping(gc->domain, gc->irq_base + i); -+ if (!virq) -+ continue; -+ } else { -+ virq = gc->irq_base + i; -+ } -+ - /* Remove handler first. That will mask the irq line */ -- irq_set_handler(i, NULL); -- irq_set_chip(i, &no_irq_chip); -- irq_set_chip_data(i, NULL); -- irq_modify_status(i, clr, set); -+ irq_set_handler(virq, NULL); -+ irq_set_chip(virq, &no_irq_chip); -+ irq_set_chip_data(virq, NULL); -+ irq_modify_status(virq, clr, set); - } - } - EXPORT_SYMBOL_GPL(irq_remove_generic_chip); -diff --git a/kernel/kexec.c b/kernel/kexec.c -index cb8e6e6f983c7..5ff1dcc4acb78 100644 ---- a/kernel/kexec.c -+++ b/kernel/kexec.c -@@ -240,7 +240,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, - ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT)) - return -EINVAL; - -- ksegments = memdup_user(segments, nr_segments * sizeof(ksegments[0])); -+ ksegments = memdup_array_user(segments, nr_segments, sizeof(ksegments[0])); - if (IS_ERR(ksegments)) - return PTR_ERR(ksegments); - -diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c -index 43efb2a041602..b1e25695185a4 100644 ---- a/kernel/locking/test-ww_mutex.c -+++ b/kernel/locking/test-ww_mutex.c -@@ -466,7 +466,6 @@ retry: - } while (!time_after(jiffies, stress->timeout)); - - kfree(order); -- kfree(stress); - } - - struct reorder_lock { -@@ -531,7 +530,6 @@ out: - list_for_each_entry_safe(ll, ln, &locks, link) - kfree(ll); - kfree(order); -- kfree(stress); - } - - static void stress_one_work(struct work_struct *work) -@@ -552,8 +550,6 @@ static void stress_one_work(struct work_struct *work) - break; - } - } while (!time_after(jiffies, stress->timeout)); -- -- kfree(stress); - } - - #define STRESS_INORDER BIT(0) -@@ -564,15 +560,24 @@ static void stress_one_work(struct work_struct *work) - static int stress(int nlocks, int nthreads, unsigned int flags) - { - struct ww_mutex *locks; -- int n; -+ struct stress *stress_array; -+ int n, count; - - locks = kmalloc_array(nlocks, sizeof(*locks), GFP_KERNEL); - if (!locks) - return -ENOMEM; - -+ stress_array = kmalloc_array(nthreads, sizeof(*stress_array), -+ GFP_KERNEL); -+ if (!stress_array) { -+ kfree(locks); -+ return -ENOMEM; -+ } -+ - for (n = 0; n < nlocks; n++) - ww_mutex_init(&locks[n], &ww_class); - -+ count = 0; - for (n = 0; nthreads; n++) { - struct stress *stress; - void (*fn)(struct work_struct *work); -@@ -596,9 +601,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags) - if (!fn) - continue; - -- stress = kmalloc(sizeof(*stress), GFP_KERNEL); -- if (!stress) -- break; -+ stress = &stress_array[count++]; - - INIT_WORK(&stress->work, fn); - stress->locks = locks; -@@ -613,6 +616,7 @@ static int stress(int nlocks, int nthreads, unsigned int flags) - - for (n = 0; n < nlocks; n++) - ww_mutex_destroy(&locks[n]); -+ kfree(stress_array); - kfree(locks); - - return 0; -diff --git a/kernel/padata.c b/kernel/padata.c -index 791d9cb07a501..7bef7dae3db54 100644 ---- a/kernel/padata.c -+++ b/kernel/padata.c -@@ -194,7 +194,7 @@ int padata_do_parallel(struct padata_shell *ps, - *cb_cpu = cpu; - } - -- err = -EBUSY; -+ err = -EBUSY; - if ((pinst->flags & PADATA_RESET)) - goto out; - -diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c -index c20ca5fb9adc8..03c4ca4048e3e 100644 ---- a/kernel/power/snapshot.c -+++ b/kernel/power/snapshot.c -@@ -2418,8 +2418,9 @@ static void *get_highmem_page_buffer(struct page *page, - pbe->copy_page = tmp; - } else { - /* Copy of the page will be stored in normal memory */ -- kaddr = safe_pages_list; -- safe_pages_list = safe_pages_list->next; -+ kaddr = __get_safe_page(ca->gfp_mask); -+ if (!kaddr) -+ return ERR_PTR(-ENOMEM); - pbe->copy_page = virt_to_page(kaddr); - } - pbe->next = highmem_pblist; -@@ -2599,8 +2600,9 @@ static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca) - return ERR_PTR(-ENOMEM); - } - pbe->orig_address = page_address(page); -- pbe->address = safe_pages_list; -- safe_pages_list = safe_pages_list->next; -+ pbe->address = __get_safe_page(ca->gfp_mask); -+ if (!pbe->address) -+ return ERR_PTR(-ENOMEM); - pbe->next = restore_pblist; - restore_pblist = pbe; - return pbe->address; -@@ -2631,8 +2633,6 @@ int snapshot_write_next(struct snapshot_handle *handle) - if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages) - return 0; - -- handle->sync_read = 1; -- - if (!handle->cur) { - if (!buffer) - /* This makes the buffer be freed by swsusp_free() */ -@@ -2668,7 +2668,6 @@ int snapshot_write_next(struct snapshot_handle *handle) - memory_bm_position_reset(&orig_bm); - restore_pblist = NULL; - handle->buffer = get_buffer(&orig_bm, &ca); -- handle->sync_read = 0; - if (IS_ERR(handle->buffer)) - return PTR_ERR(handle->buffer); - } -@@ -2678,9 +2677,8 @@ int snapshot_write_next(struct snapshot_handle *handle) - handle->buffer = get_buffer(&orig_bm, &ca); - if (IS_ERR(handle->buffer)) - return PTR_ERR(handle->buffer); -- if (handle->buffer != buffer) -- handle->sync_read = 0; - } -+ handle->sync_read = (handle->buffer == buffer); - handle->cur++; - return PAGE_SIZE; - } -diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c -index 4db36d543be37..8fdf076720384 100644 ---- a/kernel/rcu/srcutree.c -+++ b/kernel/rcu/srcutree.c -@@ -223,7 +223,7 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags) - snp->grplo = cpu; - snp->grphi = cpu; - } -- sdp->grpmask = 1 << (cpu - sdp->mynode->grplo); -+ sdp->grpmask = 1UL << (cpu - sdp->mynode->grplo); - } - smp_store_release(&ssp->srcu_size_state, SRCU_SIZE_WAIT_BARRIER); - return true; -@@ -722,7 +722,7 @@ static void srcu_schedule_cbs_snp(struct srcu_struct *ssp, struct srcu_node *snp - int cpu; - - for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) { -- if (!(mask & (1 << (cpu - snp->grplo)))) -+ if (!(mask & (1UL << (cpu - snp->grplo)))) - continue; - srcu_schedule_cbs_sdp(per_cpu_ptr(ssp->sda, cpu), delay); - } -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index 917a1e43f7839..15df37bc052a9 100644 ---- a/kernel/rcu/tree.c -+++ b/kernel/rcu/tree.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1604,10 +1605,22 @@ static bool rcu_gp_fqs_check_wake(int *gfp) - */ - static void rcu_gp_fqs(bool first_time) - { -+ int nr_fqs = READ_ONCE(rcu_state.nr_fqs_jiffies_stall); - struct rcu_node *rnp = rcu_get_root(); - - WRITE_ONCE(rcu_state.gp_activity, jiffies); - WRITE_ONCE(rcu_state.n_force_qs, rcu_state.n_force_qs + 1); -+ -+ WARN_ON_ONCE(nr_fqs > 3); -+ /* Only countdown nr_fqs for stall purposes if jiffies moves. */ -+ if (nr_fqs) { -+ if (nr_fqs == 1) { -+ WRITE_ONCE(rcu_state.jiffies_stall, -+ jiffies + rcu_jiffies_till_stall_check()); -+ } -+ WRITE_ONCE(rcu_state.nr_fqs_jiffies_stall, --nr_fqs); -+ } -+ - if (first_time) { - /* Collect dyntick-idle snapshots. */ - force_qs_rnp(dyntick_save_progress_counter); -@@ -3369,6 +3382,14 @@ void kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func) - - WRITE_ONCE(krcp->count, krcp->count + 1); - -+ /* -+ * The kvfree_rcu() caller considers the pointer freed at this point -+ * and likely removes any references to it. Since the actual slab -+ * freeing (and kmemleak_free()) is deferred, tell kmemleak to ignore -+ * this object (no scanning or false positives reporting). -+ */ -+ kmemleak_ignore(ptr); -+ - // Set timer to drain after KFREE_DRAIN_JIFFIES. - if (rcu_scheduler_active == RCU_SCHEDULER_RUNNING) - schedule_delayed_monitor_work(krcp); -diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h -index d4a97e40ea9c3..7b702220d81cb 100644 ---- a/kernel/rcu/tree.h -+++ b/kernel/rcu/tree.h -@@ -365,6 +365,10 @@ struct rcu_state { - /* in jiffies. */ - unsigned long jiffies_stall; /* Time at which to check */ - /* for CPU stalls. */ -+ int nr_fqs_jiffies_stall; /* Number of fqs loops after -+ * which read jiffies and set -+ * jiffies_stall. Stall -+ * warnings disabled if !0. */ - unsigned long jiffies_resched; /* Time at which to resched */ - /* a reluctant CPU. */ - unsigned long n_force_qs_gpstart; /* Snapshot of n_force_qs at */ -diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h -index 5653560573e22..7d15b5b5a235a 100644 ---- a/kernel/rcu/tree_stall.h -+++ b/kernel/rcu/tree_stall.h -@@ -149,12 +149,17 @@ static void panic_on_rcu_stall(void) - /** - * rcu_cpu_stall_reset - restart stall-warning timeout for current grace period - * -+ * To perform the reset request from the caller, disable stall detection until -+ * 3 fqs loops have passed. This is required to ensure a fresh jiffies is -+ * loaded. It should be safe to do from the fqs loop as enough timer -+ * interrupts and context switches should have passed. -+ * - * The caller must disable hard irqs. - */ - void rcu_cpu_stall_reset(void) - { -- WRITE_ONCE(rcu_state.jiffies_stall, -- jiffies + rcu_jiffies_till_stall_check()); -+ WRITE_ONCE(rcu_state.nr_fqs_jiffies_stall, 3); -+ WRITE_ONCE(rcu_state.jiffies_stall, ULONG_MAX); - } - - ////////////////////////////////////////////////////////////////////////////// -@@ -170,6 +175,7 @@ static void record_gp_stall_check_time(void) - WRITE_ONCE(rcu_state.gp_start, j); - j1 = rcu_jiffies_till_stall_check(); - smp_mb(); // ->gp_start before ->jiffies_stall and caller's ->gp_seq. -+ WRITE_ONCE(rcu_state.nr_fqs_jiffies_stall, 0); - WRITE_ONCE(rcu_state.jiffies_stall, j + j1); - rcu_state.jiffies_resched = j + j1 / 2; - rcu_state.n_force_qs_gpstart = READ_ONCE(rcu_state.n_force_qs); -@@ -694,6 +700,16 @@ static void check_cpu_stall(struct rcu_data *rdp) - !rcu_gp_in_progress()) - return; - rcu_stall_kick_kthreads(); -+ -+ /* -+ * Check if it was requested (via rcu_cpu_stall_reset()) that the FQS -+ * loop has to set jiffies to ensure a non-stale jiffies value. This -+ * is required to have good jiffies value after coming out of long -+ * breaks of jiffies updates. Not doing so can cause false positives. -+ */ -+ if (READ_ONCE(rcu_state.nr_fqs_jiffies_stall) > 0) -+ return; -+ - j = jiffies; - - /* -diff --git a/kernel/reboot.c b/kernel/reboot.c -index 3bba88c7ffc6b..6ebef11c88760 100644 ---- a/kernel/reboot.c -+++ b/kernel/reboot.c -@@ -74,6 +74,7 @@ void __weak (*pm_power_off)(void); - void emergency_restart(void) - { - kmsg_dump(KMSG_DUMP_EMERG); -+ system_state = SYSTEM_RESTART; - machine_emergency_restart(); - } - EXPORT_SYMBOL_GPL(emergency_restart); -diff --git a/kernel/smp.c b/kernel/smp.c -index 06a413987a14a..63e466bb6b03a 100644 ---- a/kernel/smp.c -+++ b/kernel/smp.c -@@ -185,6 +185,8 @@ static DEFINE_PER_CPU(struct cfd_seq_local, cfd_seq_local); - - static ulong csd_lock_timeout = 5000; /* CSD lock timeout in milliseconds. */ - module_param(csd_lock_timeout, ulong, 0444); -+static int panic_on_ipistall; /* CSD panic timeout in milliseconds, 300000 for five minutes. */ -+module_param(panic_on_ipistall, int, 0444); - - static atomic_t csd_bug_count = ATOMIC_INIT(0); - static u64 cfd_seq; -@@ -343,6 +345,7 @@ static bool csd_lock_wait_toolong(struct __call_single_data *csd, u64 ts0, u64 * - } - - ts2 = sched_clock(); -+ /* How long since we last checked for a stuck CSD lock.*/ - ts_delta = ts2 - *ts1; - if (likely(ts_delta <= csd_lock_timeout_ns || csd_lock_timeout_ns == 0)) - return false; -@@ -356,9 +359,17 @@ static bool csd_lock_wait_toolong(struct __call_single_data *csd, u64 ts0, u64 * - else - cpux = cpu; - cpu_cur_csd = smp_load_acquire(&per_cpu(cur_csd, cpux)); /* Before func and info. */ -+ /* How long since this CSD lock was stuck. */ -+ ts_delta = ts2 - ts0; - pr_alert("csd: %s non-responsive CSD lock (#%d) on CPU#%d, waiting %llu ns for CPU#%02d %pS(%ps).\n", -- firsttime ? "Detected" : "Continued", *bug_id, raw_smp_processor_id(), ts2 - ts0, -+ firsttime ? "Detected" : "Continued", *bug_id, raw_smp_processor_id(), ts_delta, - cpu, csd->func, csd->info); -+ /* -+ * If the CSD lock is still stuck after 5 minutes, it is unlikely -+ * to become unstuck. Use a signed comparison to avoid triggering -+ * on underflows when the TSC is out of sync between sockets. -+ */ -+ BUG_ON(panic_on_ipistall > 0 && (s64)ts_delta > ((s64)panic_on_ipistall * NSEC_PER_MSEC)); - if (cpu_cur_csd && csd != cpu_cur_csd) { - pr_alert("\tcsd: CSD lock (#%d) handling prior %pS(%ps) request.\n", - *bug_id, READ_ONCE(per_cpu(cur_csd_func, cpux)), -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 9db92a6e14636..ddcfc78e93e00 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -4912,6 +4912,20 @@ int tracing_open_file_tr(struct inode *inode, struct file *filp) - if (ret) - return ret; - -+ mutex_lock(&event_mutex); -+ -+ /* Fail if the file is marked for removal */ -+ if (file->flags & EVENT_FILE_FL_FREED) { -+ trace_array_put(file->tr); -+ ret = -ENODEV; -+ } else { -+ event_file_get(file); -+ } -+ -+ mutex_unlock(&event_mutex); -+ if (ret) -+ return ret; -+ - filp->private_data = inode->i_private; - - return 0; -@@ -4922,6 +4936,7 @@ int tracing_release_file_tr(struct inode *inode, struct file *filp) - struct trace_event_file *file = inode->i_private; - - trace_array_put(file->tr); -+ event_file_put(file); - - return 0; - } -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 7e6d5101bdb05..10aaafa2936dc 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -1631,6 +1631,9 @@ extern void event_trigger_unregister(struct event_command *cmd_ops, - char *glob, - struct event_trigger_data *trigger_data); - -+extern void event_file_get(struct trace_event_file *file); -+extern void event_file_put(struct trace_event_file *file); -+ - /** - * struct event_trigger_ops - callbacks for trace event triggers - * -diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c -index 2e3dce5e2575e..a6d2f99f847d3 100644 ---- a/kernel/trace/trace_events.c -+++ b/kernel/trace/trace_events.c -@@ -988,26 +988,38 @@ static void remove_subsystem(struct trace_subsystem_dir *dir) - } - } - --static void remove_event_file_dir(struct trace_event_file *file) -+void event_file_get(struct trace_event_file *file) - { -- struct dentry *dir = file->dir; -- struct dentry *child; -+ atomic_inc(&file->ref); -+} - -- if (dir) { -- spin_lock(&dir->d_lock); /* probably unneeded */ -- list_for_each_entry(child, &dir->d_subdirs, d_child) { -- if (d_really_is_positive(child)) /* probably unneeded */ -- d_inode(child)->i_private = NULL; -- } -- spin_unlock(&dir->d_lock); -+void event_file_put(struct trace_event_file *file) -+{ -+ if (WARN_ON_ONCE(!atomic_read(&file->ref))) { -+ if (file->flags & EVENT_FILE_FL_FREED) -+ kmem_cache_free(file_cachep, file); -+ return; -+ } - -- tracefs_remove(dir); -+ if (atomic_dec_and_test(&file->ref)) { -+ /* Count should only go to zero when it is freed */ -+ if (WARN_ON_ONCE(!(file->flags & EVENT_FILE_FL_FREED))) -+ return; -+ kmem_cache_free(file_cachep, file); - } -+} -+ -+static void remove_event_file_dir(struct trace_event_file *file) -+{ -+ struct dentry *dir = file->dir; -+ -+ tracefs_remove(dir); - - list_del(&file->list); - remove_subsystem(file->system); - free_event_filter(file->filter); -- kmem_cache_free(file_cachep, file); -+ file->flags |= EVENT_FILE_FL_FREED; -+ event_file_put(file); - } - - /* -@@ -1380,7 +1392,7 @@ event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, - flags = file->flags; - mutex_unlock(&event_mutex); - -- if (!file) -+ if (!file || flags & EVENT_FILE_FL_FREED) - return -ENODEV; - - if (flags & EVENT_FILE_FL_ENABLED && -@@ -1418,7 +1430,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, - ret = -ENODEV; - mutex_lock(&event_mutex); - file = event_file_data(filp); -- if (likely(file)) -+ if (likely(file && !(file->flags & EVENT_FILE_FL_FREED))) - ret = ftrace_event_enable_disable(file, val); - mutex_unlock(&event_mutex); - break; -@@ -1692,7 +1704,7 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, - - mutex_lock(&event_mutex); - file = event_file_data(filp); -- if (file) -+ if (file && !(file->flags & EVENT_FILE_FL_FREED)) - print_event_filter(file, s); - mutex_unlock(&event_mutex); - -@@ -2810,6 +2822,7 @@ trace_create_new_event(struct trace_event_call *call, - atomic_set(&file->tm_ref, 0); - INIT_LIST_HEAD(&file->triggers); - list_add(&file->list, &tr->events); -+ event_file_get(file); - - return file; - } -diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c -index 96acc2b71ac74..86a0531efd43d 100644 ---- a/kernel/trace/trace_events_filter.c -+++ b/kernel/trace/trace_events_filter.c -@@ -1997,6 +1997,9 @@ int apply_event_filter(struct trace_event_file *file, char *filter_string) - struct event_filter *filter = NULL; - int err; - -+ if (file->flags & EVENT_FILE_FL_FREED) -+ return -ENODEV; -+ - if (!strcmp(strstrip(filter_string), "0")) { - filter_disable(file); - filter = event_filter(file); -diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c -index b0d3876c96ab2..94a2e9d21f582 100644 ---- a/kernel/trace/trace_events_synth.c -+++ b/kernel/trace/trace_events_synth.c -@@ -473,7 +473,7 @@ static unsigned int trace_string(struct synth_trace_event *entry, - - #ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if ((unsigned long)str_val < TASK_SIZE) -- ret = strncpy_from_user_nofault(str_field, str_val, STR_VAR_LEN_MAX); -+ ret = strncpy_from_user_nofault(str_field, (const void __user *)str_val, STR_VAR_LEN_MAX); - else - #endif - ret = strncpy_from_kernel_nofault(str_field, str_val, STR_VAR_LEN_MAX); -diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c -index 28ed71d277bd7..442bb92212f2a 100644 ---- a/kernel/watch_queue.c -+++ b/kernel/watch_queue.c -@@ -332,7 +332,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe, - filter.__reserved != 0) - return -EINVAL; - -- tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf)); -+ tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf)); - if (IS_ERR(tf)) - return PTR_ERR(tf); - -diff --git a/kernel/watchdog.c b/kernel/watchdog.c -index 8e61f21e7e33e..45693fb3e08de 100644 ---- a/kernel/watchdog.c -+++ b/kernel/watchdog.c -@@ -183,6 +183,13 @@ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts); - static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); - static unsigned long soft_lockup_nmi_warn; - -+static int __init softlockup_panic_setup(char *str) -+{ -+ softlockup_panic = simple_strtoul(str, NULL, 0); -+ return 1; -+} -+__setup("softlockup_panic=", softlockup_panic_setup); -+ - static int __init nowatchdog_setup(char *str) - { - watchdog_user_enabled = 0; -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index bc1a97ee40b21..f3b6ac232e219 100644 ---- a/kernel/workqueue.c -+++ b/kernel/workqueue.c -@@ -5185,50 +5185,54 @@ static void work_for_cpu_fn(struct work_struct *work) - } - - /** -- * work_on_cpu - run a function in thread context on a particular cpu -+ * work_on_cpu_key - run a function in thread context on a particular cpu - * @cpu: the cpu to run on - * @fn: the function to run - * @arg: the function arg -+ * @key: The lock class key for lock debugging purposes - * - * It is up to the caller to ensure that the cpu doesn't go offline. - * The caller must not hold any locks which would prevent @fn from completing. - * - * Return: The value @fn returns. - */ --long work_on_cpu(int cpu, long (*fn)(void *), void *arg) -+long work_on_cpu_key(int cpu, long (*fn)(void *), -+ void *arg, struct lock_class_key *key) - { - struct work_for_cpu wfc = { .fn = fn, .arg = arg }; - -- INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); -+ INIT_WORK_ONSTACK_KEY(&wfc.work, work_for_cpu_fn, key); - schedule_work_on(cpu, &wfc.work); - flush_work(&wfc.work); - destroy_work_on_stack(&wfc.work); - return wfc.ret; - } --EXPORT_SYMBOL_GPL(work_on_cpu); -+EXPORT_SYMBOL_GPL(work_on_cpu_key); - - /** -- * work_on_cpu_safe - run a function in thread context on a particular cpu -+ * work_on_cpu_safe_key - run a function in thread context on a particular cpu - * @cpu: the cpu to run on - * @fn: the function to run - * @arg: the function argument -+ * @key: The lock class key for lock debugging purposes - * - * Disables CPU hotplug and calls work_on_cpu(). The caller must not hold - * any locks which would prevent @fn from completing. - * - * Return: The value @fn returns. - */ --long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) -+long work_on_cpu_safe_key(int cpu, long (*fn)(void *), -+ void *arg, struct lock_class_key *key) - { - long ret = -ENODEV; - - cpus_read_lock(); - if (cpu_online(cpu)) -- ret = work_on_cpu(cpu, fn, arg); -+ ret = work_on_cpu_key(cpu, fn, arg, key); - cpus_read_unlock(); - return ret; - } --EXPORT_SYMBOL_GPL(work_on_cpu_safe); -+EXPORT_SYMBOL_GPL(work_on_cpu_safe_key); - #endif /* CONFIG_SMP */ - - #ifdef CONFIG_FREEZER -diff --git a/lib/generic-radix-tree.c b/lib/generic-radix-tree.c -index f25eb111c0516..7dfa88282b006 100644 ---- a/lib/generic-radix-tree.c -+++ b/lib/generic-radix-tree.c -@@ -166,6 +166,10 @@ void *__genradix_iter_peek(struct genradix_iter *iter, - struct genradix_root *r; - struct genradix_node *n; - unsigned level, i; -+ -+ if (iter->offset == SIZE_MAX) -+ return NULL; -+ - restart: - r = READ_ONCE(radix->root); - if (!r) -@@ -184,10 +188,17 @@ restart: - (GENRADIX_ARY - 1); - - while (!n->children[i]) { -+ size_t objs_per_ptr = genradix_depth_size(level); -+ -+ if (iter->offset + objs_per_ptr < iter->offset) { -+ iter->offset = SIZE_MAX; -+ iter->pos = SIZE_MAX; -+ return NULL; -+ } -+ - i++; -- iter->offset = round_down(iter->offset + -- genradix_depth_size(level), -- genradix_depth_size(level)); -+ iter->offset = round_down(iter->offset + objs_per_ptr, -+ objs_per_ptr); - iter->pos = (iter->offset >> PAGE_SHIFT) * - objs_per_page; - if (i == GENRADIX_ARY) -diff --git a/mm/cma.c b/mm/cma.c -index 4a978e09547a8..30b6ca30009bb 100644 ---- a/mm/cma.c -+++ b/mm/cma.c -@@ -500,7 +500,7 @@ struct page *cma_alloc(struct cma *cma, unsigned long count, - */ - if (page) { - for (i = 0; i < count; i++) -- page_kasan_tag_reset(page + i); -+ page_kasan_tag_reset(nth_page(page, i)); - } - - if (ret && !no_warn) { -diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c -index efbc2bda8b9cd..63bdad20dbaf8 100644 ---- a/mm/damon/lru_sort.c -+++ b/mm/damon/lru_sort.c -@@ -195,9 +195,7 @@ static int damon_lru_sort_apply_parameters(void) - if (err) - return err; - -- /* aggr_interval / sample_interval is the maximum nr_accesses */ -- hot_thres = damon_lru_sort_mon_attrs.aggr_interval / -- damon_lru_sort_mon_attrs.sample_interval * -+ hot_thres = damon_max_nr_accesses(&damon_lru_sort_mon_attrs) * - hot_thres_access_freq / 1000; - scheme = damon_lru_sort_new_hot_scheme(hot_thres); - if (!scheme) -diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c -index 13b99975cbc2c..0b75a8d5c7068 100644 ---- a/mm/damon/ops-common.c -+++ b/mm/damon/ops-common.c -@@ -87,7 +87,6 @@ void damon_pmdp_mkold(pmd_t *pmd, struct vm_area_struct *vma, unsigned long addr - int damon_hot_score(struct damon_ctx *c, struct damon_region *r, - struct damos *s) - { -- unsigned int max_nr_accesses; - int freq_subscore; - unsigned int age_in_sec; - int age_in_log, age_subscore; -@@ -95,8 +94,8 @@ int damon_hot_score(struct damon_ctx *c, struct damon_region *r, - unsigned int age_weight = s->quota.weight_age; - int hotness; - -- max_nr_accesses = c->attrs.aggr_interval / c->attrs.sample_interval; -- freq_subscore = r->nr_accesses * DAMON_MAX_SUBSCORE / max_nr_accesses; -+ freq_subscore = r->nr_accesses * DAMON_MAX_SUBSCORE / -+ damon_max_nr_accesses(&c->attrs); - - age_in_sec = (unsigned long)r->age * c->attrs.aggr_interval / 1000000; - for (age_in_log = 0; age_in_log < DAMON_MAX_AGE_IN_LOG && age_in_sec; -diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c -index 07e5f1bdf025f..dbf5e4de97a0f 100644 ---- a/mm/damon/sysfs.c -+++ b/mm/damon/sysfs.c -@@ -2188,58 +2188,75 @@ destroy_targets_out: - return err; - } - --/* -- * Search a target in a context that corresponds to the sysfs target input. -- * -- * Return: pointer to the target if found, NULL if not found, or negative -- * error code if the search failed. -- */ --static struct damon_target *damon_sysfs_existing_target( -- struct damon_sysfs_target *sys_target, struct damon_ctx *ctx) -+static int damon_sysfs_update_target_pid(struct damon_target *target, int pid) - { -- struct pid *pid; -- struct damon_target *t; -+ struct pid *pid_new; - -- if (!damon_target_has_pid(ctx)) { -- /* Up to only one target for paddr could exist */ -- damon_for_each_target(t, ctx) -- return t; -- return NULL; -+ pid_new = find_get_pid(pid); -+ if (!pid_new) -+ return -EINVAL; -+ -+ if (pid_new == target->pid) { -+ put_pid(pid_new); -+ return 0; - } - -- /* ops.id should be DAMON_OPS_VADDR or DAMON_OPS_FVADDR */ -- pid = find_get_pid(sys_target->pid); -- if (!pid) -- return ERR_PTR(-EINVAL); -- damon_for_each_target(t, ctx) { -- if (t->pid == pid) { -- put_pid(pid); -- return t; -- } -+ put_pid(target->pid); -+ target->pid = pid_new; -+ return 0; -+} -+ -+static int damon_sysfs_update_target(struct damon_target *target, -+ struct damon_ctx *ctx, -+ struct damon_sysfs_target *sys_target) -+{ -+ int err; -+ -+ if (damon_target_has_pid(ctx)) { -+ err = damon_sysfs_update_target_pid(target, sys_target->pid); -+ if (err) -+ return err; - } -- put_pid(pid); -- return NULL; -+ -+ /* -+ * Do monitoring target region boundary update only if one or more -+ * regions are set by the user. This is for keeping current monitoring -+ * target results and range easier, especially for dynamic monitoring -+ * target regions update ops like 'vaddr'. -+ */ -+ if (sys_target->regions->nr) -+ err = damon_sysfs_set_regions(target, sys_target->regions); -+ return err; - } - - static int damon_sysfs_set_targets(struct damon_ctx *ctx, - struct damon_sysfs_targets *sysfs_targets) - { -- int i, err; -+ struct damon_target *t, *next; -+ int i = 0, err; - - /* Multiple physical address space monitoring targets makes no sense */ - if (ctx->ops.id == DAMON_OPS_PADDR && sysfs_targets->nr > 1) - return -EINVAL; - -- for (i = 0; i < sysfs_targets->nr; i++) { -+ damon_for_each_target_safe(t, next, ctx) { -+ if (i < sysfs_targets->nr) { -+ err = damon_sysfs_update_target(t, ctx, -+ sysfs_targets->targets_arr[i]); -+ if (err) -+ return err; -+ } else { -+ if (damon_target_has_pid(ctx)) -+ put_pid(t->pid); -+ damon_destroy_target(t); -+ } -+ i++; -+ } -+ -+ for (; i < sysfs_targets->nr; i++) { - struct damon_sysfs_target *st = sysfs_targets->targets_arr[i]; -- struct damon_target *t = damon_sysfs_existing_target(st, ctx); - -- if (IS_ERR(t)) -- return PTR_ERR(t); -- if (!t) -- err = damon_sysfs_add_target(st, ctx); -- else -- err = damon_sysfs_set_regions(t, st->regions); -+ err = damon_sysfs_add_target(st, ctx); - if (err) - return err; - } -diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index b20fef29e5bb5..2753fb54cdf38 100644 ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -2757,13 +2757,15 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) - int nr = folio_nr_pages(folio); - - xas_split(&xas, folio, folio_order(folio)); -- if (folio_test_swapbacked(folio)) { -- __lruvec_stat_mod_folio(folio, NR_SHMEM_THPS, -- -nr); -- } else { -- __lruvec_stat_mod_folio(folio, NR_FILE_THPS, -- -nr); -- filemap_nr_thps_dec(mapping); -+ if (folio_test_pmd_mappable(folio)) { -+ if (folio_test_swapbacked(folio)) { -+ __lruvec_stat_mod_folio(folio, -+ NR_SHMEM_THPS, -nr); -+ } else { -+ __lruvec_stat_mod_folio(folio, -+ NR_FILE_THPS, -nr); -+ filemap_nr_thps_dec(mapping); -+ } - } - } - -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index dacbaf4f7b2c4..9da98e3e71cfe 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -2854,7 +2854,8 @@ static void commit_charge(struct folio *folio, struct mem_cgroup *memcg) - * Moreover, it should not come from DMA buffer and is not readily - * reclaimable. So those GFP bits should be masked off. - */ --#define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT) -+#define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | \ -+ __GFP_ACCOUNT | __GFP_NOFAIL) - - /* - * mod_objcg_mlstate() may be called with irq enabled, so -diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c -index fd40f7e9f1763..bd2570b4f9b7b 100644 ---- a/mm/memory_hotplug.c -+++ b/mm/memory_hotplug.c -@@ -1611,7 +1611,7 @@ static int scan_movable_pages(unsigned long start, unsigned long end, - */ - if (HPageMigratable(head)) - goto found; -- skip = compound_nr(head) - (page - head); -+ skip = compound_nr(head) - (pfn - page_to_pfn(head)); - pfn += skip - 1; - } - return -ENOENT; -diff --git a/net/9p/client.c b/net/9p/client.c -index a96e127ca4883..84b93b04d0f06 100644 ---- a/net/9p/client.c -+++ b/net/9p/client.c -@@ -1987,7 +1987,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid, - goto error; - } - p9_debug(P9_DEBUG_9P, -- ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n", -+ ">>> TXATTRWALK file_fid %d, attr_fid %d name '%s'\n", - file_fid->fid, attr_fid->fid, attr_name); - - req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds", -diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c -index 5a1aecf7fe487..a69422366a235 100644 ---- a/net/9p/trans_fd.c -+++ b/net/9p/trans_fd.c -@@ -833,14 +833,21 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd) - goto out_free_ts; - if (!(ts->rd->f_mode & FMODE_READ)) - goto out_put_rd; -- /* prevent workers from hanging on IO when fd is a pipe */ -- ts->rd->f_flags |= O_NONBLOCK; -+ /* Prevent workers from hanging on IO when fd is a pipe. -+ * It's technically possible for userspace or concurrent mounts to -+ * modify this flag concurrently, which will likely result in a -+ * broken filesystem. However, just having bad flags here should -+ * not crash the kernel or cause any other sort of bug, so mark this -+ * particular data race as intentional so that tooling (like KCSAN) -+ * can allow it and detect further problems. -+ */ -+ data_race(ts->rd->f_flags |= O_NONBLOCK); - ts->wr = fget(wfd); - if (!ts->wr) - goto out_put_rd; - if (!(ts->wr->f_mode & FMODE_WRITE)) - goto out_put_wr; -- ts->wr->f_flags |= O_NONBLOCK; -+ data_race(ts->wr->f_flags |= O_NONBLOCK); - - client->trans = ts; - client->status = Connected; -diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c -index 728be9307f526..55e0ecd88543e 100644 ---- a/net/bluetooth/hci_conn.c -+++ b/net/bluetooth/hci_conn.c -@@ -168,13 +168,11 @@ static void hci_conn_cleanup(struct hci_conn *conn) - hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); - } - -- hci_conn_del_sysfs(conn); -- - debugfs_remove_recursive(conn->debugfs); - -- hci_dev_put(hdev); -+ hci_conn_del_sysfs(conn); - -- hci_conn_put(conn); -+ hci_dev_put(hdev); - } - - static void le_scan_cleanup(struct work_struct *work) -diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c -index 08542dfc2dc53..633b82d542728 100644 ---- a/net/bluetooth/hci_sysfs.c -+++ b/net/bluetooth/hci_sysfs.c -@@ -33,7 +33,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn) - { - struct hci_dev *hdev = conn->hdev; - -- BT_DBG("conn %p", conn); -+ bt_dev_dbg(hdev, "conn %p", conn); - - conn->dev.type = &bt_link; - conn->dev.class = bt_class; -@@ -46,27 +46,30 @@ void hci_conn_add_sysfs(struct hci_conn *conn) - { - struct hci_dev *hdev = conn->hdev; - -- BT_DBG("conn %p", conn); -+ bt_dev_dbg(hdev, "conn %p", conn); - - if (device_is_registered(&conn->dev)) - return; - - dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); - -- if (device_add(&conn->dev) < 0) { -+ if (device_add(&conn->dev) < 0) - bt_dev_err(hdev, "failed to register connection device"); -- return; -- } -- -- hci_dev_hold(hdev); - } - - void hci_conn_del_sysfs(struct hci_conn *conn) - { - struct hci_dev *hdev = conn->hdev; - -- if (!device_is_registered(&conn->dev)) -+ bt_dev_dbg(hdev, "conn %p", conn); -+ -+ if (!device_is_registered(&conn->dev)) { -+ /* If device_add() has *not* succeeded, use *only* put_device() -+ * to drop the reference count. -+ */ -+ put_device(&conn->dev); - return; -+ } - - while (1) { - struct device *dev; -@@ -78,9 +81,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn) - put_device(dev); - } - -- device_del(&conn->dev); -- -- hci_dev_put(hdev); -+ device_unregister(&conn->dev); - } - - static void bt_host_release(struct device *dev) -diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c -index 73242962be5d7..06d94b2c6b5de 100644 ---- a/net/bridge/netfilter/nf_conntrack_bridge.c -+++ b/net/bridge/netfilter/nf_conntrack_bridge.c -@@ -37,7 +37,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk, - ktime_t tstamp = skb->tstamp; - struct ip_frag_state state; - struct iphdr *iph; -- int err; -+ int err = 0; - - /* for offloaded checksums cleanup checksum before fragmentation */ - if (skb->ip_summed == CHECKSUM_PARTIAL && -diff --git a/net/core/sock.c b/net/core/sock.c -index 0ee2e33bbe5f8..4305e55dbfba4 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -596,7 +596,7 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) - INDIRECT_CALL_INET(dst->ops->check, ip6_dst_check, ipv4_dst_check, - dst, cookie) == NULL) { - sk_tx_queue_clear(sk); -- sk->sk_dst_pending_confirm = 0; -+ WRITE_ONCE(sk->sk_dst_pending_confirm, 0); - RCU_INIT_POINTER(sk->sk_dst_cache, NULL); - dst_release(dst); - return NULL; -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index 62d9472ac8bca..f2ed2aed08ab3 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -731,12 +731,12 @@ int __inet_hash(struct sock *sk, struct sock *osk) - if (err) - goto unlock; - } -+ sock_set_flag(sk, SOCK_RCU_FREE); - if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && - sk->sk_family == AF_INET6) - __sk_nulls_add_node_tail_rcu(sk, &ilb2->nulls_head); - else - __sk_nulls_add_node_rcu(sk, &ilb2->nulls_head); -- sock_set_flag(sk, SOCK_RCU_FREE); - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); - unlock: - spin_unlock(&ilb2->lock); -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index cc7ed86fb0a57..5b93d1ed1ed19 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -1319,7 +1319,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, - skb->destructor = skb_is_tcp_pure_ack(skb) ? __sock_wfree : tcp_wfree; - refcount_add(skb->truesize, &sk->sk_wmem_alloc); - -- skb_set_dst_pending_confirm(skb, sk->sk_dst_pending_confirm); -+ skb_set_dst_pending_confirm(skb, READ_ONCE(sk->sk_dst_pending_confirm)); - - /* Build TCP header and checksum it. */ - th = (struct tcphdr *)skb->data; -diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c -index ee9f455bb2d18..2ca442f485132 100644 ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -3006,6 +3006,10 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, - else - *dbm = sdata->vif.bss_conf.txpower; - -+ /* INT_MIN indicates no power level was set yet */ -+ if (*dbm == INT_MIN) -+ return -EINVAL; -+ - return 0; - } - -diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c -index 5d845fcf3d09e..980050f6b456f 100644 ---- a/net/mptcp/pm_netlink.c -+++ b/net/mptcp/pm_netlink.c -@@ -1557,8 +1557,9 @@ void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list) - struct mptcp_pm_addr_entry *entry; - - list_for_each_entry(entry, rm_list, list) { -- remove_anno_list_by_saddr(msk, &entry->addr); -- if (alist.nr < MPTCP_RM_IDS_MAX) -+ if ((remove_anno_list_by_saddr(msk, &entry->addr) || -+ lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) && -+ alist.nr < MPTCP_RM_IDS_MAX) - alist.ids[alist.nr++] = entry->addr.id; - } - -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index 0eb20274459c8..76539d1004ebb 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -1275,6 +1275,8 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk, - mptcp_do_fallback(ssk); - } - -+#define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1)) -+ - static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, - struct mptcp_data_frag *dfrag, - struct mptcp_sendmsg_info *info) -@@ -1301,6 +1303,8 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, - return -EAGAIN; - - /* compute send limit */ -+ if (unlikely(ssk->sk_gso_max_size > MPTCP_MAX_GSO_SIZE)) -+ ssk->sk_gso_max_size = MPTCP_MAX_GSO_SIZE; - info->mss_now = tcp_send_mss(ssk, &info->size_goal, info->flags); - copy = info->size_goal; - -diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c -index 937bd4c556151..30374fd44228f 100644 ---- a/net/mptcp/sockopt.c -+++ b/net/mptcp/sockopt.c -@@ -735,8 +735,11 @@ static int mptcp_setsockopt_v4_set_tos(struct mptcp_sock *msk, int optname, - val = inet_sk(sk)->tos; - mptcp_for_each_subflow(msk, subflow) { - struct sock *ssk = mptcp_subflow_tcp_sock(subflow); -+ bool slow; - -+ slow = lock_sock_fast(ssk); - __ip_sock_set_tos(ssk, val); -+ unlock_sock_fast(ssk, slow); - } - release_sock(sk); - -diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c -index f8854bff286cb..62fb1031763d1 100644 ---- a/net/ncsi/ncsi-aen.c -+++ b/net/ncsi/ncsi-aen.c -@@ -89,11 +89,6 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp, - if ((had_link == has_link) || chained) - return 0; - -- if (had_link) -- netif_carrier_off(ndp->ndev.dev); -- else -- netif_carrier_on(ndp->ndev.dev); -- - if (!ndp->multi_package && !nc->package->multi_channel) { - if (had_link) { - ndp->flags |= NCSI_DEV_RESHUFFLE; -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index d6d59e36d17a7..421211eba838b 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -6194,6 +6194,12 @@ static int nft_setelem_deactivate(const struct net *net, - return ret; - } - -+static void nft_setelem_catchall_destroy(struct nft_set_elem_catchall *catchall) -+{ -+ list_del_rcu(&catchall->list); -+ kfree_rcu(catchall, rcu); -+} -+ - static void nft_setelem_catchall_remove(const struct net *net, - const struct nft_set *set, - const struct nft_set_elem *elem) -@@ -6202,8 +6208,7 @@ static void nft_setelem_catchall_remove(const struct net *net, - - list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { - if (catchall->elem == elem->priv) { -- list_del_rcu(&catchall->list); -- kfree_rcu(catchall, rcu); -+ nft_setelem_catchall_destroy(catchall); - break; - } - } -@@ -9266,9 +9271,8 @@ void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans) - call_rcu(&trans->rcu, nft_trans_gc_trans_free); - } - --static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, -- unsigned int gc_seq, -- bool sync) -+struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc, -+ unsigned int gc_seq) - { - struct nft_set_elem_catchall *catchall; - const struct nft_set *set = gc->set; -@@ -9284,11 +9288,7 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, - - nft_set_elem_dead(ext); - dead_elem: -- if (sync) -- gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); -- else -- gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); -- -+ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); - if (!gc) - return NULL; - -@@ -9298,15 +9298,34 @@ dead_elem: - return gc; - } - --struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc, -- unsigned int gc_seq) --{ -- return nft_trans_gc_catchall(gc, gc_seq, false); --} -- - struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc) - { -- return nft_trans_gc_catchall(gc, 0, true); -+ struct nft_set_elem_catchall *catchall, *next; -+ const struct nft_set *set = gc->set; -+ struct nft_set_elem elem; -+ struct nft_set_ext *ext; -+ -+ WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net)); -+ -+ list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { -+ ext = nft_set_elem_ext(set, catchall->elem); -+ -+ if (!nft_set_elem_expired(ext)) -+ continue; -+ -+ gc = nft_trans_gc_queue_sync(gc, GFP_KERNEL); -+ if (!gc) -+ return NULL; -+ -+ memset(&elem, 0, sizeof(elem)); -+ elem.priv = catchall->elem; -+ -+ nft_setelem_data_deactivate(gc->net, gc->set, &elem); -+ nft_setelem_catchall_destroy(catchall); -+ nft_trans_gc_elem_add(gc, elem.priv); -+ } -+ -+ return gc; - } - - static void nf_tables_module_autoload_cleanup(struct net *net) -diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c -index 2e2eb2cb17bc7..605178133d9eb 100644 ---- a/net/netfilter/nft_byteorder.c -+++ b/net/netfilter/nft_byteorder.c -@@ -38,13 +38,14 @@ void nft_byteorder_eval(const struct nft_expr *expr, - - switch (priv->size) { - case 8: { -+ u64 *dst64 = (void *)dst; - u64 src64; - - switch (priv->op) { - case NFT_BYTEORDER_NTOH: - for (i = 0; i < priv->len / 8; i++) { - src64 = nft_reg_load64(&src[i]); -- nft_reg_store64(&dst[i], -+ nft_reg_store64(&dst64[i], - be64_to_cpu((__force __be64)src64)); - } - break; -@@ -52,7 +53,7 @@ void nft_byteorder_eval(const struct nft_expr *expr, - for (i = 0; i < priv->len / 8; i++) { - src64 = (__force __u64) - cpu_to_be64(nft_reg_load64(&src[i])); -- nft_reg_store64(&dst[i], src64); -+ nft_reg_store64(&dst64[i], src64); - } - break; - } -diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c -index 55d2d49c34259..6e83321926229 100644 ---- a/net/netfilter/nft_meta.c -+++ b/net/netfilter/nft_meta.c -@@ -63,7 +63,7 @@ nft_meta_get_eval_time(enum nft_meta_keys key, - { - switch (key) { - case NFT_META_TIME_NS: -- nft_reg_store64(dest, ktime_get_real_ns()); -+ nft_reg_store64((u64 *)dest, ktime_get_real_ns()); - break; - case NFT_META_TIME_DAY: - nft_reg_store8(dest, nft_meta_weekday()); -diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c -index 2b803383c7b31..61e5c77462e94 100644 ---- a/net/sunrpc/clnt.c -+++ b/net/sunrpc/clnt.c -@@ -111,7 +111,8 @@ static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) - - pipefs_sb = rpc_get_sb_net(net); - if (pipefs_sb) { -- __rpc_clnt_remove_pipedir(clnt); -+ if (pipefs_sb == clnt->pipefs_sb) -+ __rpc_clnt_remove_pipedir(clnt); - rpc_put_sb_net(net); - } - } -@@ -151,6 +152,8 @@ rpc_setup_pipedir(struct super_block *pipefs_sb, struct rpc_clnt *clnt) - { - struct dentry *dentry; - -+ clnt->pipefs_sb = pipefs_sb; -+ - if (clnt->cl_program->pipe_dir_name != NULL) { - dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt); - if (IS_ERR(dentry)) -@@ -2157,6 +2160,7 @@ call_connect_status(struct rpc_task *task) - task->tk_status = 0; - switch (status) { - case -ECONNREFUSED: -+ case -ECONNRESET: - /* A positive refusal suggests a rebind is needed. */ - if (RPC_IS_SOFTCONN(task)) - break; -@@ -2165,7 +2169,6 @@ call_connect_status(struct rpc_task *task) - goto out_retry; - } - fallthrough; -- case -ECONNRESET: - case -ECONNABORTED: - case -ENETDOWN: - case -ENETUNREACH: -diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c -index 5a8e6d46809ae..82afb56695f8d 100644 ---- a/net/sunrpc/rpcb_clnt.c -+++ b/net/sunrpc/rpcb_clnt.c -@@ -746,6 +746,10 @@ void rpcb_getport_async(struct rpc_task *task) - - child = rpcb_call_async(rpcb_clnt, map, proc); - rpc_release_client(rpcb_clnt); -+ if (IS_ERR(child)) { -+ /* rpcb_map_release() has freed the arguments */ -+ return; -+ } - - xprt->stat.bind_count++; - rpc_put_task(child); -diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c -index 6da6608985ce9..b2dd01e5274e9 100644 ---- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c -+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c -@@ -857,7 +857,8 @@ out_readfail: - if (ret == -EINVAL) - svc_rdma_send_error(rdma_xprt, ctxt, ret); - svc_rdma_recv_ctxt_put(rdma_xprt, ctxt); -- return ret; -+ svc_xprt_deferred_close(xprt); -+ return -ENOTCONN; - - out_backchannel: - svc_rdma_handle_bc_reply(rqstp, ctxt); -diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c -index dfea27a906f2f..9eb7cab6b2f60 100644 ---- a/net/tipc/netlink_compat.c -+++ b/net/tipc/netlink_compat.c -@@ -101,6 +101,7 @@ static int tipc_add_tlv(struct sk_buff *skb, u16 type, void *data, u16 len) - return -EMSGSIZE; - - skb_put(skb, TLV_SPACE(len)); -+ memset(tlv, 0, TLV_SPACE(len)); - tlv->tlv_type = htons(type); - tlv->tlv_len = htons(TLV_LENGTH(len)); - if (len && data) -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index 310952f4c68f7..6dbeb80073338 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -2641,15 +2641,16 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state) - - if (!(state->flags & MSG_PEEK)) - WRITE_ONCE(u->oob_skb, NULL); -- -+ else -+ skb_get(oob_skb); - unix_state_unlock(sk); - - chunk = state->recv_actor(oob_skb, 0, chunk, state); - -- if (!(state->flags & MSG_PEEK)) { -+ if (!(state->flags & MSG_PEEK)) - UNIXCB(oob_skb).consumed += 1; -- kfree_skb(oob_skb); -- } -+ -+ consume_skb(oob_skb); - - mutex_unlock(&u->iolock); - -diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c -index 8360c790a8a01..84471745c0829 100644 ---- a/net/vmw_vsock/af_vsock.c -+++ b/net/vmw_vsock/af_vsock.c -@@ -89,6 +89,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -110,6 +111,7 @@ - #include - #include - #include -+#include - - static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr); - static void vsock_sk_destruct(struct sock *sk); -@@ -2096,6 +2098,10 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, - int err; - - sk = sock->sk; -+ -+ if (unlikely(flags & MSG_ERRQUEUE)) -+ return sock_recv_errqueue(sk, msg, len, SOL_VSOCK, VSOCK_RECVERR); -+ - vsk = vsock_sk(sk); - err = 0; - -diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c -index 951b74ba1b242..366395cab490d 100644 ---- a/scripts/gcc-plugins/randomize_layout_plugin.c -+++ b/scripts/gcc-plugins/randomize_layout_plugin.c -@@ -191,12 +191,14 @@ static void partition_struct(tree *fields, unsigned long length, struct partitio - - static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state) - { -- unsigned long i, x; -+ unsigned long i, x, index; - struct partition_group size_group[length]; - unsigned long num_groups = 0; - unsigned long randnum; - - partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups); -+ -+ /* FIXME: this group shuffle is currently a no-op. */ - for (i = num_groups - 1; i > 0; i--) { - struct partition_group tmp; - randnum = ranval(prng_state) % (i + 1); -@@ -206,11 +208,14 @@ static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prn - } - - for (x = 0; x < num_groups; x++) { -- for (i = size_group[x].start + size_group[x].length - 1; i > size_group[x].start; i--) { -+ for (index = size_group[x].length - 1; index > 0; index--) { - tree tmp; -+ -+ i = size_group[x].start + index; - if (DECL_BIT_FIELD_TYPE(newtree[i])) - continue; -- randnum = ranval(prng_state) % (i + 1); -+ randnum = ranval(prng_state) % (index + 1); -+ randnum += size_group[x].start; - // we could handle this case differently if desired - if (DECL_BIT_FIELD_TYPE(newtree[randnum])) - continue; -diff --git a/security/integrity/iint.c b/security/integrity/iint.c -index 65418e0906c13..cb251ab0e7076 100644 ---- a/security/integrity/iint.c -+++ b/security/integrity/iint.c -@@ -66,9 +66,32 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode) - return iint; - } - --static void iint_free(struct integrity_iint_cache *iint) -+#define IMA_MAX_NESTING (FILESYSTEM_MAX_STACK_DEPTH+1) -+ -+/* -+ * It is not clear that IMA should be nested at all, but as long is it measures -+ * files both on overlayfs and on underlying fs, we need to annotate the iint -+ * mutex to avoid lockdep false positives related to IMA + overlayfs. -+ * See ovl_lockdep_annotate_inode_mutex_key() for more details. -+ */ -+static inline void iint_lockdep_annotate(struct integrity_iint_cache *iint, -+ struct inode *inode) -+{ -+#ifdef CONFIG_LOCKDEP -+ static struct lock_class_key iint_mutex_key[IMA_MAX_NESTING]; -+ -+ int depth = inode->i_sb->s_stack_depth; -+ -+ if (WARN_ON_ONCE(depth < 0 || depth >= IMA_MAX_NESTING)) -+ depth = 0; -+ -+ lockdep_set_class(&iint->mutex, &iint_mutex_key[depth]); -+#endif -+} -+ -+static void iint_init_always(struct integrity_iint_cache *iint, -+ struct inode *inode) - { -- kfree(iint->ima_hash); - iint->ima_hash = NULL; - iint->version = 0; - iint->flags = 0UL; -@@ -80,6 +103,14 @@ static void iint_free(struct integrity_iint_cache *iint) - iint->ima_creds_status = INTEGRITY_UNKNOWN; - iint->evm_status = INTEGRITY_UNKNOWN; - iint->measured_pcrs = 0; -+ mutex_init(&iint->mutex); -+ iint_lockdep_annotate(iint, inode); -+} -+ -+static void iint_free(struct integrity_iint_cache *iint) -+{ -+ kfree(iint->ima_hash); -+ mutex_destroy(&iint->mutex); - kmem_cache_free(iint_cache, iint); - } - -@@ -112,6 +143,8 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode) - if (!iint) - return NULL; - -+ iint_init_always(iint, inode); -+ - write_lock(&integrity_iint_lock); - - p = &integrity_iint_tree.rb_node; -@@ -161,25 +194,18 @@ void integrity_inode_free(struct inode *inode) - iint_free(iint); - } - --static void init_once(void *foo) -+static void iint_init_once(void *foo) - { - struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo; - - memset(iint, 0, sizeof(*iint)); -- iint->ima_file_status = INTEGRITY_UNKNOWN; -- iint->ima_mmap_status = INTEGRITY_UNKNOWN; -- iint->ima_bprm_status = INTEGRITY_UNKNOWN; -- iint->ima_read_status = INTEGRITY_UNKNOWN; -- iint->ima_creds_status = INTEGRITY_UNKNOWN; -- iint->evm_status = INTEGRITY_UNKNOWN; -- mutex_init(&iint->mutex); - } - - static int __init integrity_iintcache_init(void) - { - iint_cache = - kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache), -- 0, SLAB_PANIC, init_once); -+ 0, SLAB_PANIC, iint_init_once); - return 0; - } - DEFINE_LSM(integrity) = { -diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c -index 1e3a7a4f8833f..026c8c9db9920 100644 ---- a/security/integrity/ima/ima_api.c -+++ b/security/integrity/ima/ima_api.c -@@ -243,6 +243,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, - { - const char *audit_cause = "failed"; - struct inode *inode = file_inode(file); -+ struct inode *real_inode = d_real_inode(file_dentry(file)); - const char *filename = file->f_path.dentry->d_name.name; - struct ima_max_digest_data hash; - int result = 0; -@@ -305,6 +306,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, - iint->ima_hash = tmpbuf; - memcpy(iint->ima_hash, &hash, length); - iint->version = i_version; -+ if (real_inode != inode) { -+ iint->real_ino = real_inode->i_ino; -+ iint->real_dev = real_inode->i_sb->s_dev; -+ } - - /* Possibly temporary failure due to type of read (eg. O_DIRECT) */ - if (!result) -diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c -index bc84a0ac25aaa..185666d90eebc 100644 ---- a/security/integrity/ima/ima_main.c -+++ b/security/integrity/ima/ima_main.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #include "ima.h" - -@@ -202,7 +203,7 @@ static int process_measurement(struct file *file, const struct cred *cred, - u32 secid, char *buf, loff_t size, int mask, - enum ima_hooks func) - { -- struct inode *inode = file_inode(file); -+ struct inode *backing_inode, *inode = file_inode(file); - struct integrity_iint_cache *iint = NULL; - struct ima_template_desc *template_desc = NULL; - char *pathbuf = NULL; -@@ -278,6 +279,19 @@ static int process_measurement(struct file *file, const struct cred *cred, - iint->measured_pcrs = 0; - } - -+ /* Detect and re-evaluate changes made to the backing file. */ -+ backing_inode = d_real_inode(file_dentry(file)); -+ if (backing_inode != inode && -+ (action & IMA_DO_MASK) && (iint->flags & IMA_DONE_MASK)) { -+ if (!IS_I_VERSION(backing_inode) || -+ backing_inode->i_sb->s_dev != iint->real_dev || -+ backing_inode->i_ino != iint->real_ino || -+ !inode_eq_iversion(backing_inode, iint->version)) { -+ iint->flags &= ~IMA_DONE_MASK; -+ iint->measured_pcrs = 0; -+ } -+ } -+ - /* Determine if already appraised/measured based on bitmask - * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED, - * IMA_AUDIT, IMA_AUDITED) -diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h -index 7167a6e99bdc0..52c3c806bf69f 100644 ---- a/security/integrity/integrity.h -+++ b/security/integrity/integrity.h -@@ -164,6 +164,8 @@ struct integrity_iint_cache { - unsigned long flags; - unsigned long measured_pcrs; - unsigned long atomic_flags; -+ unsigned long real_ino; -+ dev_t real_dev; - enum integrity_status ima_file_status:4; - enum integrity_status ima_mmap_status:4; - enum integrity_status ima_bprm_status:4; -diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c -index 85fb5c22529a7..fee1ab2c734d3 100644 ---- a/security/keys/trusted-keys/trusted_core.c -+++ b/security/keys/trusted-keys/trusted_core.c -@@ -358,17 +358,17 @@ static int __init init_trusted(void) - if (!get_random) - get_random = kernel_get_random; - -- static_call_update(trusted_key_seal, -- trusted_key_sources[i].ops->seal); -- static_call_update(trusted_key_unseal, -- trusted_key_sources[i].ops->unseal); -- static_call_update(trusted_key_get_random, -- get_random); -- trusted_key_exit = trusted_key_sources[i].ops->exit; -- migratable = trusted_key_sources[i].ops->migratable; -- - ret = trusted_key_sources[i].ops->init(); -- if (!ret) -+ if (!ret) { -+ static_call_update(trusted_key_seal, trusted_key_sources[i].ops->seal); -+ static_call_update(trusted_key_unseal, trusted_key_sources[i].ops->unseal); -+ static_call_update(trusted_key_get_random, get_random); -+ -+ trusted_key_exit = trusted_key_sources[i].ops->exit; -+ migratable = trusted_key_sources[i].ops->migratable; -+ } -+ -+ if (!ret || ret != -ENODEV) - break; - } - -diff --git a/security/keys/trusted-keys/trusted_tee.c b/security/keys/trusted-keys/trusted_tee.c -index c8626686ee1b7..24f67ca8d7131 100644 ---- a/security/keys/trusted-keys/trusted_tee.c -+++ b/security/keys/trusted-keys/trusted_tee.c -@@ -65,24 +65,16 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob) - int ret; - struct tee_ioctl_invoke_arg inv_arg; - struct tee_param param[4]; -- struct tee_shm *reg_shm_in = NULL, *reg_shm_out = NULL; -+ struct tee_shm *reg_shm = NULL; - - memset(&inv_arg, 0, sizeof(inv_arg)); - memset(¶m, 0, sizeof(param)); - -- reg_shm_in = tee_shm_register_kernel_buf(pvt_data.ctx, p->key, -- p->key_len); -- if (IS_ERR(reg_shm_in)) { -- dev_err(pvt_data.dev, "key shm register failed\n"); -- return PTR_ERR(reg_shm_in); -- } -- -- reg_shm_out = tee_shm_register_kernel_buf(pvt_data.ctx, p->blob, -- sizeof(p->blob)); -- if (IS_ERR(reg_shm_out)) { -- dev_err(pvt_data.dev, "blob shm register failed\n"); -- ret = PTR_ERR(reg_shm_out); -- goto out; -+ reg_shm = tee_shm_register_kernel_buf(pvt_data.ctx, p->key, -+ sizeof(p->key) + sizeof(p->blob)); -+ if (IS_ERR(reg_shm)) { -+ dev_err(pvt_data.dev, "shm register failed\n"); -+ return PTR_ERR(reg_shm); - } - - inv_arg.func = TA_CMD_SEAL; -@@ -90,13 +82,13 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob) - inv_arg.num_params = 4; - - param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; -- param[0].u.memref.shm = reg_shm_in; -+ param[0].u.memref.shm = reg_shm; - param[0].u.memref.size = p->key_len; - param[0].u.memref.shm_offs = 0; - param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; -- param[1].u.memref.shm = reg_shm_out; -+ param[1].u.memref.shm = reg_shm; - param[1].u.memref.size = sizeof(p->blob); -- param[1].u.memref.shm_offs = 0; -+ param[1].u.memref.shm_offs = sizeof(p->key); - - ret = tee_client_invoke_func(pvt_data.ctx, &inv_arg, param); - if ((ret < 0) || (inv_arg.ret != 0)) { -@@ -107,11 +99,7 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob) - p->blob_len = param[1].u.memref.size; - } - --out: -- if (reg_shm_out) -- tee_shm_free(reg_shm_out); -- if (reg_shm_in) -- tee_shm_free(reg_shm_in); -+ tee_shm_free(reg_shm); - - return ret; - } -@@ -124,24 +112,16 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob) - int ret; - struct tee_ioctl_invoke_arg inv_arg; - struct tee_param param[4]; -- struct tee_shm *reg_shm_in = NULL, *reg_shm_out = NULL; -+ struct tee_shm *reg_shm = NULL; - - memset(&inv_arg, 0, sizeof(inv_arg)); - memset(¶m, 0, sizeof(param)); - -- reg_shm_in = tee_shm_register_kernel_buf(pvt_data.ctx, p->blob, -- p->blob_len); -- if (IS_ERR(reg_shm_in)) { -- dev_err(pvt_data.dev, "blob shm register failed\n"); -- return PTR_ERR(reg_shm_in); -- } -- -- reg_shm_out = tee_shm_register_kernel_buf(pvt_data.ctx, p->key, -- sizeof(p->key)); -- if (IS_ERR(reg_shm_out)) { -- dev_err(pvt_data.dev, "key shm register failed\n"); -- ret = PTR_ERR(reg_shm_out); -- goto out; -+ reg_shm = tee_shm_register_kernel_buf(pvt_data.ctx, p->key, -+ sizeof(p->key) + sizeof(p->blob)); -+ if (IS_ERR(reg_shm)) { -+ dev_err(pvt_data.dev, "shm register failed\n"); -+ return PTR_ERR(reg_shm); - } - - inv_arg.func = TA_CMD_UNSEAL; -@@ -149,11 +129,11 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob) - inv_arg.num_params = 4; - - param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; -- param[0].u.memref.shm = reg_shm_in; -+ param[0].u.memref.shm = reg_shm; - param[0].u.memref.size = p->blob_len; -- param[0].u.memref.shm_offs = 0; -+ param[0].u.memref.shm_offs = sizeof(p->key); - param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; -- param[1].u.memref.shm = reg_shm_out; -+ param[1].u.memref.shm = reg_shm; - param[1].u.memref.size = sizeof(p->key); - param[1].u.memref.shm_offs = 0; - -@@ -166,11 +146,7 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob) - p->key_len = param[1].u.memref.size; - } - --out: -- if (reg_shm_out) -- tee_shm_free(reg_shm_out); -- if (reg_shm_in) -- tee_shm_free(reg_shm_in); -+ tee_shm_free(reg_shm); - - return ret; - } -diff --git a/sound/core/info.c b/sound/core/info.c -index 0b2f04dcb5897..e2f302e55bbb2 100644 ---- a/sound/core/info.c -+++ b/sound/core/info.c -@@ -56,7 +56,7 @@ struct snd_info_private_data { - }; - - static int snd_info_version_init(void); --static void snd_info_disconnect(struct snd_info_entry *entry); -+static void snd_info_clear_entries(struct snd_info_entry *entry); - - /* - -@@ -569,11 +569,16 @@ void snd_info_card_disconnect(struct snd_card *card) - { - if (!card) - return; -- mutex_lock(&info_mutex); -+ - proc_remove(card->proc_root_link); -- card->proc_root_link = NULL; - if (card->proc_root) -- snd_info_disconnect(card->proc_root); -+ proc_remove(card->proc_root->p); -+ -+ mutex_lock(&info_mutex); -+ if (card->proc_root) -+ snd_info_clear_entries(card->proc_root); -+ card->proc_root_link = NULL; -+ card->proc_root = NULL; - mutex_unlock(&info_mutex); - } - -@@ -745,15 +750,14 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, - } - EXPORT_SYMBOL(snd_info_create_card_entry); - --static void snd_info_disconnect(struct snd_info_entry *entry) -+static void snd_info_clear_entries(struct snd_info_entry *entry) - { - struct snd_info_entry *p; - - if (!entry->p) - return; - list_for_each_entry(p, &entry->children, list) -- snd_info_disconnect(p); -- proc_remove(entry->p); -+ snd_info_clear_entries(p); - entry->p = NULL; - } - -@@ -770,8 +774,9 @@ void snd_info_free_entry(struct snd_info_entry * entry) - if (!entry) - return; - if (entry->p) { -+ proc_remove(entry->p); - mutex_lock(&info_mutex); -- snd_info_disconnect(entry); -+ snd_info_clear_entries(entry); - mutex_unlock(&info_mutex); - } - -diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c -index 1b8be39c38a96..741a5d17ae4cb 100644 ---- a/sound/hda/hdac_stream.c -+++ b/sound/hda/hdac_stream.c -@@ -338,8 +338,10 @@ struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus, - struct hdac_stream *res = NULL; - - /* make a non-zero unique key for the substream */ -- int key = (substream->pcm->device << 16) | (substream->number << 2) | -- (substream->stream + 1); -+ int key = (substream->number << 2) | (substream->stream + 1); -+ -+ if (substream->pcm) -+ key |= (substream->pcm->device << 16); - - spin_lock_irq(&bus->reg_lock); - list_for_each_entry(azx_dev, &bus->stream_list, list) { -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 0163d4c7fdda8..b63e12b661996 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9624,6 +9624,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED), -+ SND_PCI_QUIRK(0x103c, 0x890e, "HP 255 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), - SND_PCI_QUIRK(0x103c, 0x8919, "HP Pavilion Aero Laptop 13-be0xxx", ALC287_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x896d, "HP ZBook Firefly 16 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -@@ -9659,6 +9660,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8b2f, "HP 255 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), - SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b43, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8b44, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -@@ -9692,12 +9694,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8c70, "HP EliteBook 835 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), - SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), - SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), - SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK), - SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), - SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), -+ SND_PCI_QUIRK(0x1043, 0x10d3, "ASUS K6500ZC", ALC294_FIXUP_ASUS_SPK), - SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), -@@ -9749,6 +9755,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), - SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), - SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2), -+ SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2), - SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), - SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), -@@ -10590,22 +10597,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { - {0x12, 0x90a60130}, - {0x17, 0x90170110}, - {0x21, 0x03211020}), -- SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, -- {0x14, 0x90170110}, -- {0x21, 0x04211020}), -- SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, -- {0x14, 0x90170110}, -- {0x21, 0x04211030}), -- SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, -- ALC295_STANDARD_PINS, -- {0x17, 0x21014020}, -- {0x18, 0x21a19030}), -- SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, -- ALC295_STANDARD_PINS, -- {0x17, 0x21014040}, -- {0x18, 0x21a19050}), -- SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, -- ALC295_STANDARD_PINS), - SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, - ALC298_STANDARD_PINS, - {0x17, 0x90170110}), -@@ -10649,6 +10640,9 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = { - SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, - {0x19, 0x40000000}, - {0x1b, 0x40000000}), -+ SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, -+ {0x19, 0x40000000}, -+ {0x1b, 0x40000000}), - SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, - {0x19, 0x40000000}, - {0x1a, 0x40000000}), -diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c -index 8ed48c86ccb33..2ccc68513f7c1 100644 ---- a/sound/soc/codecs/lpass-wsa-macro.c -+++ b/sound/soc/codecs/lpass-wsa-macro.c -@@ -1682,6 +1682,9 @@ static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w, - boost_path_cfg1 = CDC_WSA_RX1_RX_PATH_CFG1; - reg = CDC_WSA_RX1_RX_PATH_CTL; - reg_mix = CDC_WSA_RX1_RX_PATH_MIX_CTL; -+ } else { -+ dev_warn(component->dev, "Incorrect widget name in the driver\n"); -+ return -EINVAL; - } - - switch (event) { -diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c -index cdcbf04b8832f..5e2ec60e2954b 100644 ---- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c -+++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c -@@ -75,6 +75,39 @@ static struct snd_soc_acpi_mach *cht_ess8316_quirk(void *arg) - return arg; - } - -+/* -+ * The Lenovo Yoga Tab 3 Pro YT3-X90, with Android factory OS has a buggy DSDT -+ * with the coded not being listed at all. -+ */ -+static const struct dmi_system_id lenovo_yoga_tab3_x90[] = { -+ { -+ /* Lenovo Yoga Tab 3 Pro YT3-X90, codec missing from DSDT */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), -+ }, -+ }, -+ { } -+}; -+ -+static struct snd_soc_acpi_mach cht_lenovo_yoga_tab3_x90_mach = { -+ .id = "10WM5102", -+ .drv_name = "bytcr_wm5102", -+ .fw_filename = "intel/fw_sst_22a8.bin", -+ .board = "bytcr_wm5102", -+ .sof_tplg_filename = "sof-cht-wm5102.tplg", -+}; -+ -+static struct snd_soc_acpi_mach *lenovo_yt3_x90_quirk(void *arg) -+{ -+ if (dmi_check_system(lenovo_yoga_tab3_x90)) -+ return &cht_lenovo_yoga_tab3_x90_mach; -+ -+ /* Skip wildcard match snd_soc_acpi_intel_cherrytrail_machines[] entry */ -+ return NULL; -+} -+ - static const struct snd_soc_acpi_codecs rt5640_comp_ids = { - .num_codecs = 2, - .codecs = { "10EC5640", "10EC3276" }, -@@ -175,6 +208,16 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = { - .drv_name = "sof_pcm512x", - .sof_tplg_filename = "sof-cht-src-50khz-pcm512x.tplg", - }, -+ /* -+ * Special case for the Lenovo Yoga Tab 3 Pro YT3-X90 where the DSDT -+ * misses the codec. Match on the SST id instead, lenovo_yt3_x90_quirk() -+ * will return a YT3 specific mach or NULL when called on other hw, -+ * skipping this entry. -+ */ -+ { -+ .id = "808622A8", -+ .machine_quirk = lenovo_yt3_x90_quirk, -+ }, - - #if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) - /* -diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c -index c08f3960ddd96..06e1872abfee7 100644 ---- a/sound/soc/sof/ipc4.c -+++ b/sound/soc/sof/ipc4.c -@@ -601,6 +601,9 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev) - case SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS: - sof_ipc4_mtrace_update_pos(sdev, SOF_IPC4_LOG_CORE_GET(ipc4_msg->primary)); - break; -+ case SOF_IPC4_NOTIFY_EXCEPTION_CAUGHT: -+ snd_sof_dsp_panic(sdev, 0, true); -+ break; - default: - dev_dbg(sdev->dev, "Unhandled DSP message: %#x|%#x\n", - ipc4_msg->primary, ipc4_msg->extension); -diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c -index cf2c0db57d899..061ab7289a6c3 100644 ---- a/sound/soc/sof/sof-audio.c -+++ b/sound/soc/sof/sof-audio.c -@@ -832,6 +832,13 @@ int sof_machine_check(struct snd_sof_dev *sdev) - mach = snd_sof_machine_select(sdev); - if (mach) { - sof_pdata->machine = mach; -+ -+ if (sof_pdata->subsystem_id_set) { -+ mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor; -+ mach->mach_params.subsystem_device = sof_pdata->subsystem_device; -+ mach->mach_params.subsystem_id_set = true; -+ } -+ - snd_sof_set_mach_params(mach, sdev); - return 0; - } -diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c -index 05fb4e20e8a40..99cc272e321d0 100644 ---- a/sound/soc/sof/sof-pci-dev.c -+++ b/sound/soc/sof/sof-pci-dev.c -@@ -217,6 +217,14 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) - return ret; - - sof_pdata->name = pci_name(pci); -+ -+ /* PCI defines a vendor ID of 0xFFFF as invalid. */ -+ if (pci->subsystem_vendor != 0xFFFF) { -+ sof_pdata->subsystem_vendor = pci->subsystem_vendor; -+ sof_pdata->subsystem_device = pci->subsystem_device; -+ sof_pdata->subsystem_id_set = true; -+ } -+ - sof_pdata->desc = desc; - sof_pdata->dev = dev; - -diff --git a/sound/soc/ti/omap-mcbsp.c b/sound/soc/ti/omap-mcbsp.c -index 7c539a41a6a34..4b8aac1a36fa2 100644 ---- a/sound/soc/ti/omap-mcbsp.c -+++ b/sound/soc/ti/omap-mcbsp.c -@@ -74,14 +74,16 @@ static int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) - return -EINVAL; - } - -- pm_runtime_put_sync(mcbsp->dev); -+ if (mcbsp->active) -+ pm_runtime_put_sync(mcbsp->dev); - - r = clk_set_parent(mcbsp->fclk, fck_src); - if (r) - dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n", - src); - -- pm_runtime_get_sync(mcbsp->dev); -+ if (mcbsp->active) -+ pm_runtime_get_sync(mcbsp->dev); - - clk_put(fck_src); - -diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c -index d1338a4071268..6fb64c58b408b 100644 ---- a/tools/perf/util/intel-pt.c -+++ b/tools/perf/util/intel-pt.c -@@ -1483,9 +1483,11 @@ static void intel_pt_sample_flags(struct intel_pt_queue *ptq) - } else if (ptq->state->flags & INTEL_PT_ASYNC) { - if (!ptq->state->to_ip) - ptq->flags = PERF_IP_FLAG_BRANCH | -+ PERF_IP_FLAG_ASYNC | - PERF_IP_FLAG_TRACE_END; - else if (ptq->state->from_nr && !ptq->state->to_nr) - ptq->flags = PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | -+ PERF_IP_FLAG_ASYNC | - PERF_IP_FLAG_VMEXIT; - else - ptq->flags = PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | -diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c -index c61c6c704fbe6..b113900d94879 100644 ---- a/tools/power/x86/turbostat/turbostat.c -+++ b/tools/power/x86/turbostat/turbostat.c -@@ -2180,7 +2180,7 @@ retry: - if ((DO_BIC(BIC_CPU_c6) || soft_c1_residency_display(BIC_CPU_c6)) && !do_knl_cstates) { - if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) - return -7; -- } else if (do_knl_cstates || soft_c1_residency_display(BIC_CPU_c6)) { -+ } else if (do_knl_cstates && soft_c1_residency_display(BIC_CPU_c6)) { - if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6)) - return -7; - } -@@ -5790,6 +5790,7 @@ void process_cpuid() - rapl_probe(family, model); - perf_limit_reasons_probe(family, model); - automatic_cstate_conversion_probe(family, model); -+ prewake_cstate_probe(family, model); - - check_tcc_offset(model_orig); - -diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c -index 7edce12fd2ce5..339b31a3319bf 100644 ---- a/tools/testing/cxl/test/cxl.c -+++ b/tools/testing/cxl/test/cxl.c -@@ -551,6 +551,142 @@ static int mock_decoder_reset(struct cxl_decoder *cxld) - return 0; - } - -+static void default_mock_decoder(struct cxl_decoder *cxld) -+{ -+ cxld->hpa_range = (struct range){ -+ .start = 0, -+ .end = -1, -+ }; -+ -+ cxld->interleave_ways = 1; -+ cxld->interleave_granularity = 256; -+ cxld->target_type = CXL_DECODER_EXPANDER; -+ cxld->commit = mock_decoder_commit; -+ cxld->reset = mock_decoder_reset; -+} -+ -+static int first_decoder(struct device *dev, void *data) -+{ -+ struct cxl_decoder *cxld; -+ -+ if (!is_switch_decoder(dev)) -+ return 0; -+ cxld = to_cxl_decoder(dev); -+ if (cxld->id == 0) -+ return 1; -+ return 0; -+} -+ -+static void mock_init_hdm_decoder(struct cxl_decoder *cxld) -+{ -+ struct acpi_cedt_cfmws *window = mock_cfmws[0]; -+ struct platform_device *pdev = NULL; -+ struct cxl_endpoint_decoder *cxled; -+ struct cxl_switch_decoder *cxlsd; -+ struct cxl_port *port, *iter; -+ const int size = SZ_512M; -+ struct cxl_memdev *cxlmd; -+ struct cxl_dport *dport; -+ struct device *dev; -+ bool hb0 = false; -+ u64 base; -+ int i; -+ -+ if (is_endpoint_decoder(&cxld->dev)) { -+ cxled = to_cxl_endpoint_decoder(&cxld->dev); -+ cxlmd = cxled_to_memdev(cxled); -+ WARN_ON(!dev_is_platform(cxlmd->dev.parent)); -+ pdev = to_platform_device(cxlmd->dev.parent); -+ -+ /* check is endpoint is attach to host-bridge0 */ -+ port = cxled_to_port(cxled); -+ do { -+ if (port->uport == &cxl_host_bridge[0]->dev) { -+ hb0 = true; -+ break; -+ } -+ if (is_cxl_port(port->dev.parent)) -+ port = to_cxl_port(port->dev.parent); -+ else -+ port = NULL; -+ } while (port); -+ port = cxled_to_port(cxled); -+ } -+ -+ /* -+ * The first decoder on the first 2 devices on the first switch -+ * attached to host-bridge0 mock a fake / static RAM region. All -+ * other decoders are default disabled. Given the round robin -+ * assignment those devices are named cxl_mem.0, and cxl_mem.4. -+ * -+ * See 'cxl list -BMPu -m cxl_mem.0,cxl_mem.4' -+ */ -+ if (!hb0 || pdev->id % 4 || pdev->id > 4 || cxld->id > 0) { -+ default_mock_decoder(cxld); -+ return; -+ } -+ -+ base = window->base_hpa; -+ cxld->hpa_range = (struct range) { -+ .start = base, -+ .end = base + size - 1, -+ }; -+ -+ cxld->interleave_ways = 2; -+ eig_to_granularity(window->granularity, &cxld->interleave_granularity); -+ cxld->target_type = CXL_DECODER_EXPANDER; -+ cxld->flags = CXL_DECODER_F_ENABLE; -+ cxled->state = CXL_DECODER_STATE_AUTO; -+ port->commit_end = cxld->id; -+ devm_cxl_dpa_reserve(cxled, 0, size / cxld->interleave_ways, 0); -+ cxld->commit = mock_decoder_commit; -+ cxld->reset = mock_decoder_reset; -+ -+ /* -+ * Now that endpoint decoder is set up, walk up the hierarchy -+ * and setup the switch and root port decoders targeting @cxlmd. -+ */ -+ iter = port; -+ for (i = 0; i < 2; i++) { -+ dport = iter->parent_dport; -+ iter = dport->port; -+ dev = device_find_child(&iter->dev, NULL, first_decoder); -+ /* -+ * Ancestor ports are guaranteed to be enumerated before -+ * @port, and all ports have at least one decoder. -+ */ -+ if (WARN_ON(!dev)) -+ continue; -+ cxlsd = to_cxl_switch_decoder(dev); -+ if (i == 0) { -+ /* put cxl_mem.4 second in the decode order */ -+ if (pdev->id == 4) -+ cxlsd->target[1] = dport; -+ else -+ cxlsd->target[0] = dport; -+ } else -+ cxlsd->target[0] = dport; -+ cxld = &cxlsd->cxld; -+ cxld->target_type = CXL_DECODER_EXPANDER; -+ cxld->flags = CXL_DECODER_F_ENABLE; -+ iter->commit_end = 0; -+ /* -+ * Switch targets 2 endpoints, while host bridge targets -+ * one root port -+ */ -+ if (i == 0) -+ cxld->interleave_ways = 2; -+ else -+ cxld->interleave_ways = 1; -+ cxld->interleave_granularity = 4096; -+ cxld->hpa_range = (struct range) { -+ .start = base, -+ .end = base + size - 1, -+ }; -+ put_device(dev); -+ } -+} -+ - static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm) - { - struct cxl_port *port = cxlhdm->port; -@@ -596,16 +732,7 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm) - cxld = &cxled->cxld; - } - -- cxld->hpa_range = (struct range) { -- .start = 0, -- .end = -1, -- }; -- -- cxld->interleave_ways = min_not_zero(target_count, 1); -- cxld->interleave_granularity = SZ_4K; -- cxld->target_type = CXL_DECODER_EXPANDER; -- cxld->commit = mock_decoder_commit; -- cxld->reset = mock_decoder_reset; -+ mock_init_hdm_decoder(cxld); - - if (target_count) { - rc = device_for_each_child(port->uport, &ctx, -diff --git a/tools/testing/selftests/efivarfs/create-read.c b/tools/testing/selftests/efivarfs/create-read.c -index 9674a19396a32..7bc7af4eb2c17 100644 ---- a/tools/testing/selftests/efivarfs/create-read.c -+++ b/tools/testing/selftests/efivarfs/create-read.c -@@ -32,8 +32,10 @@ int main(int argc, char **argv) - rc = read(fd, buf, sizeof(buf)); - if (rc != 0) { - fprintf(stderr, "Reading a new var should return EOF\n"); -+ close(fd); - return EXIT_FAILURE; - } - -+ close(fd); - return EXIT_SUCCESS; - } -diff --git a/tools/testing/selftests/lkdtm/config b/tools/testing/selftests/lkdtm/config -index 5d52f64dfb430..7afe05e8c4d79 100644 ---- a/tools/testing/selftests/lkdtm/config -+++ b/tools/testing/selftests/lkdtm/config -@@ -9,7 +9,6 @@ CONFIG_INIT_ON_FREE_DEFAULT_ON=y - CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y - CONFIG_UBSAN=y - CONFIG_UBSAN_BOUNDS=y --CONFIG_UBSAN_TRAP=y - CONFIG_STACKPROTECTOR_STRONG=y - CONFIG_SLUB_DEBUG=y - CONFIG_SLUB_DEBUG_ON=y -diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt -index 607b8d7e3ea34..2f3a1b96da6e3 100644 ---- a/tools/testing/selftests/lkdtm/tests.txt -+++ b/tools/testing/selftests/lkdtm/tests.txt -@@ -7,7 +7,7 @@ EXCEPTION - #EXHAUST_STACK Corrupts memory on failure - #CORRUPT_STACK Crashes entire system on success - #CORRUPT_STACK_STRONG Crashes entire system on success --ARRAY_BOUNDS -+ARRAY_BOUNDS call trace:|UBSAN: array-index-out-of-bounds - CORRUPT_LIST_ADD list_add corruption - CORRUPT_LIST_DEL list_del corruption - STACK_GUARD_PAGE_LEADING -diff --git a/tools/testing/selftests/resctrl/Makefile b/tools/testing/selftests/resctrl/Makefile -index 5073dbc961258..2deac2031de9e 100644 ---- a/tools/testing/selftests/resctrl/Makefile -+++ b/tools/testing/selftests/resctrl/Makefile -@@ -1,6 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0 - --CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2 -+CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE - CFLAGS += $(KHDR_INCLUDES) - - TEST_GEN_PROGS := resctrl_tests -diff --git a/tools/testing/selftests/resctrl/cmt_test.c b/tools/testing/selftests/resctrl/cmt_test.c -index 3b0454e7fc826..dd9f9db70af46 100644 ---- a/tools/testing/selftests/resctrl/cmt_test.c -+++ b/tools/testing/selftests/resctrl/cmt_test.c -@@ -91,9 +91,6 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) - if (ret) - return ret; - -- if (!validate_resctrl_feature_request(CMT_STR)) -- return -1; -- - ret = get_cbm_mask("L3", cbm_mask); - if (ret) - return ret; -diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c -index 97dc98c0c9497..ff8b588b63ed7 100644 ---- a/tools/testing/selftests/resctrl/mba_test.c -+++ b/tools/testing/selftests/resctrl/mba_test.c -@@ -12,7 +12,7 @@ - - #define RESULT_FILE_NAME "result_mba" - #define NUM_OF_RUNS 5 --#define MAX_DIFF_PERCENT 5 -+#define MAX_DIFF_PERCENT 8 - #define ALLOCATION_MAX 100 - #define ALLOCATION_MIN 10 - #define ALLOCATION_STEP 10 -diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c -index 280187628054d..5dc1dce89733a 100644 ---- a/tools/testing/selftests/resctrl/mbm_test.c -+++ b/tools/testing/selftests/resctrl/mbm_test.c -@@ -11,7 +11,7 @@ - #include "resctrl.h" - - #define RESULT_FILE_NAME "result_mbm" --#define MAX_DIFF_PERCENT 5 -+#define MAX_DIFF_PERCENT 8 - #define NUM_OF_RUNS 5 - - static int -diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h -index dbe5cfb545585..4597bba66ad45 100644 ---- a/tools/testing/selftests/resctrl/resctrl.h -+++ b/tools/testing/selftests/resctrl/resctrl.h -@@ -1,5 +1,4 @@ - /* SPDX-License-Identifier: GPL-2.0 */ --#define _GNU_SOURCE - #ifndef RESCTRL_H - #define RESCTRL_H - #include diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.64-65.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.64-65.patch deleted file mode 100644 index 70227a3a3caf..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.64-65.patch +++ /dev/null @@ -1,4244 +0,0 @@ -diff --git a/Makefile b/Makefile -index 97c75ae364cdf..1646e334a647f 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 64 -+SUBLEVEL = 65 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c -index b647306eb1608..d12fdb9c05a89 100644 ---- a/arch/arm/xen/enlighten.c -+++ b/arch/arm/xen/enlighten.c -@@ -484,7 +484,8 @@ static int __init xen_guest_init(void) - * for secondary CPUs as they are brought up. - * For uniformity we use VCPUOP_register_vcpu_info even on cpu0. - */ -- xen_vcpu_info = alloc_percpu(struct vcpu_info); -+ xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info), -+ 1 << fls(sizeof(struct vcpu_info) - 1)); - if (xen_vcpu_info == NULL) - return -ENOMEM; - -diff --git a/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi -index faafefe562e4b..d74c126d5ee07 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi -@@ -27,6 +27,7 @@ - regulator-name = "eth_phy_pwr"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; -+ regulator-enable-ramp-delay = <20000>; - gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; -diff --git a/arch/arm64/include/asm/kfence.h b/arch/arm64/include/asm/kfence.h -index aa855c6a0ae6f..a81937fae9f6d 100644 ---- a/arch/arm64/include/asm/kfence.h -+++ b/arch/arm64/include/asm/kfence.h -@@ -19,4 +19,14 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) - return true; - } - -+#ifdef CONFIG_KFENCE -+extern bool kfence_early_init; -+static inline bool arm64_kfence_can_set_direct_map(void) -+{ -+ return !kfence_early_init; -+} -+#else /* CONFIG_KFENCE */ -+static inline bool arm64_kfence_can_set_direct_map(void) { return false; } -+#endif /* CONFIG_KFENCE */ -+ - #endif /* __ASM_KFENCE_H */ -diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h -index f4af547ef54ca..2e4d7da74fb87 100644 ---- a/arch/arm64/include/asm/setup.h -+++ b/arch/arm64/include/asm/setup.h -@@ -21,9 +21,22 @@ static inline bool arch_parse_debug_rodata(char *arg) - extern bool rodata_enabled; - extern bool rodata_full; - -- if (arg && !strcmp(arg, "full")) { -+ if (!arg) -+ return false; -+ -+ if (!strcmp(arg, "full")) { -+ rodata_enabled = rodata_full = true; -+ return true; -+ } -+ -+ if (!strcmp(arg, "off")) { -+ rodata_enabled = rodata_full = false; -+ return true; -+ } -+ -+ if (!strcmp(arg, "on")) { - rodata_enabled = true; -- rodata_full = true; -+ rodata_full = false; - return true; - } - -diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c -index 9a7c389651540..4b302dbf78e96 100644 ---- a/arch/arm64/mm/mmu.c -+++ b/arch/arm64/mm/mmu.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -38,6 +39,7 @@ - #include - #include - #include -+#include - - #define NO_BLOCK_MAPPINGS BIT(0) - #define NO_CONT_MAPPINGS BIT(1) -@@ -521,12 +523,67 @@ static int __init enable_crash_mem_map(char *arg) - } - early_param("crashkernel", enable_crash_mem_map); - -+#ifdef CONFIG_KFENCE -+ -+bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL; -+ -+/* early_param() will be parsed before map_mem() below. */ -+static int __init parse_kfence_early_init(char *arg) -+{ -+ int val; -+ -+ if (get_option(&arg, &val)) -+ kfence_early_init = !!val; -+ return 0; -+} -+early_param("kfence.sample_interval", parse_kfence_early_init); -+ -+static phys_addr_t __init arm64_kfence_alloc_pool(void) -+{ -+ phys_addr_t kfence_pool; -+ -+ if (!kfence_early_init) -+ return 0; -+ -+ kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); -+ if (!kfence_pool) { -+ pr_err("failed to allocate kfence pool\n"); -+ kfence_early_init = false; -+ return 0; -+ } -+ -+ /* Temporarily mark as NOMAP. */ -+ memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE); -+ -+ return kfence_pool; -+} -+ -+static void __init arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) -+{ -+ if (!kfence_pool) -+ return; -+ -+ /* KFENCE pool needs page-level mapping. */ -+ __map_memblock(pgdp, kfence_pool, kfence_pool + KFENCE_POOL_SIZE, -+ pgprot_tagged(PAGE_KERNEL), -+ NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); -+ memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE); -+ __kfence_pool = phys_to_virt(kfence_pool); -+} -+#else /* CONFIG_KFENCE */ -+ -+static inline phys_addr_t arm64_kfence_alloc_pool(void) { return 0; } -+static inline void arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) { } -+ -+#endif /* CONFIG_KFENCE */ -+ - static void __init map_mem(pgd_t *pgdp) - { - static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN); - phys_addr_t kernel_start = __pa_symbol(_stext); - phys_addr_t kernel_end = __pa_symbol(__init_begin); - phys_addr_t start, end; -+ phys_addr_t early_kfence_pool; - int flags = NO_EXEC_MAPPINGS; - u64 i; - -@@ -539,6 +596,8 @@ static void __init map_mem(pgd_t *pgdp) - */ - BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end)); - -+ early_kfence_pool = arm64_kfence_alloc_pool(); -+ - if (can_set_direct_map()) - flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; - -@@ -604,6 +663,8 @@ static void __init map_mem(pgd_t *pgdp) - } - } - #endif -+ -+ arm64_kfence_map_pool(early_kfence_pool, pgdp); - } - - void mark_rodata_ro(void) -diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c -index 5922178d7a064..826cb200b204f 100644 ---- a/arch/arm64/mm/pageattr.c -+++ b/arch/arm64/mm/pageattr.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - - struct page_change_data { - pgprot_t set_mask; -@@ -22,12 +23,14 @@ bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED - bool can_set_direct_map(void) - { - /* -- * rodata_full, DEBUG_PAGEALLOC and KFENCE require linear map to be -+ * rodata_full and DEBUG_PAGEALLOC require linear map to be - * mapped at page granularity, so that it is possible to - * protect/unprotect single pages. -+ * -+ * KFENCE pool requires page-granular mapping if initialized late. - */ -- return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() || -- IS_ENABLED(CONFIG_KFENCE); -+ return rodata_full || debug_pagealloc_enabled() || -+ arm64_kfence_can_set_direct_map(); - } - - static int change_page_range(pte_t *ptep, unsigned long addr, void *data) -@@ -102,8 +105,7 @@ static int change_memory_common(unsigned long addr, int numpages, - * If we are manipulating read-only permissions, apply the same - * change to the linear mapping of the pages that back this VM area. - */ -- if (rodata_enabled && -- rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || -+ if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || - pgprot_val(clear_mask) == PTE_RDONLY)) { - for (i = 0; i < area->nr_pages; i++) { - __change_memory_common((u64)page_address(area->pages[i]), -diff --git a/arch/mips/kvm/mmu.c b/arch/mips/kvm/mmu.c -index 74cd64a24d059..19ec27be20f06 100644 ---- a/arch/mips/kvm/mmu.c -+++ b/arch/mips/kvm/mmu.c -@@ -593,7 +593,7 @@ static int kvm_mips_map_page(struct kvm_vcpu *vcpu, unsigned long gpa, - gfn_t gfn = gpa >> PAGE_SHIFT; - int srcu_idx, err; - kvm_pfn_t pfn; -- pte_t *ptep, entry, old_pte; -+ pte_t *ptep, entry; - bool writeable; - unsigned long prot_bits; - unsigned long mmu_seq; -@@ -665,7 +665,6 @@ retry: - entry = pfn_pte(pfn, __pgprot(prot_bits)); - - /* Write the PTE */ -- old_pte = *ptep; - set_pte(ptep, entry); - - err = 0; -diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c -index 99bab31919e4c..c297e40c5bdc0 100644 ---- a/drivers/acpi/resource.c -+++ b/drivers/acpi/resource.c -@@ -446,6 +446,13 @@ static const struct dmi_system_id asus_laptop[] = { - DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"), - }, - }, -+ { -+ /* Asus ExpertBook B1402CVA */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"), -+ }, -+ }, - { - .ident = "Asus ExpertBook B2402CBA", - .matches = { -diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c -index 43bb224430d3c..8892931ea8676 100644 ---- a/drivers/ata/pata_isapnp.c -+++ b/drivers/ata/pata_isapnp.c -@@ -82,6 +82,9 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev - if (pnp_port_valid(idev, 1)) { - ctl_addr = devm_ioport_map(&idev->dev, - pnp_port_start(idev, 1), 1); -+ if (!ctl_addr) -+ return -ENOMEM; -+ - ap->ioaddr.altstatus_addr = ctl_addr; - ap->ioaddr.ctl_addr = ctl_addr; - ap->ops = &isapnp_port_ops; -diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c -index d12ec092e62df..91a005c46b107 100644 ---- a/drivers/gpu/drm/i915/gt/intel_gt.c -+++ b/drivers/gpu/drm/i915/gt/intel_gt.c -@@ -903,8 +903,6 @@ int intel_gt_probe_all(struct drm_i915_private *i915) - - err: - i915_probe_error(i915, "Failed to initialize %s! (%d)\n", gtdef->name, ret); -- intel_gt_release_all(i915); -- - return ret; - } - -@@ -923,15 +921,6 @@ int intel_gt_tiles_init(struct drm_i915_private *i915) - return 0; - } - --void intel_gt_release_all(struct drm_i915_private *i915) --{ -- struct intel_gt *gt; -- unsigned int id; -- -- for_each_gt(gt, i915, id) -- i915->gt[id] = NULL; --} -- - void intel_gt_info_print(const struct intel_gt_info *info, - struct drm_printer *p) - { -diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c -index 75a93951fe429..be0ebed2a360f 100644 ---- a/drivers/gpu/drm/i915/i915_driver.c -+++ b/drivers/gpu/drm/i915/i915_driver.c -@@ -901,7 +901,7 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - - ret = i915_driver_mmio_probe(i915); - if (ret < 0) -- goto out_tiles_cleanup; -+ goto out_runtime_pm_put; - - ret = i915_driver_hw_probe(i915); - if (ret < 0) -@@ -959,8 +959,6 @@ out_cleanup_hw: - i915_ggtt_driver_late_release(i915); - out_cleanup_mmio: - i915_driver_mmio_release(i915); --out_tiles_cleanup: -- intel_gt_release_all(i915); - out_runtime_pm_put: - enable_rpm_wakeref_asserts(&i915->runtime_pm); - i915_driver_late_release(i915); -diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c -index c924f1124ebca..1c008bd9102ff 100644 ---- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c -+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c -@@ -36,6 +36,7 @@ struct panel_desc { - const struct panel_init_cmd *init_cmds; - unsigned int lanes; - bool discharge_on_disable; -+ bool lp11_before_reset; - }; - - struct boe_panel { -@@ -1269,6 +1270,10 @@ static int boe_panel_prepare(struct drm_panel *panel) - - usleep_range(10000, 11000); - -+ if (boe->desc->lp11_before_reset) { -+ mipi_dsi_dcs_nop(boe->dsi); -+ usleep_range(1000, 2000); -+ } - gpiod_set_value(boe->enable_gpio, 1); - usleep_range(1000, 2000); - gpiod_set_value(boe->enable_gpio, 0); -@@ -1468,6 +1473,7 @@ static const struct panel_desc auo_b101uan08_3_desc = { - .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_LPM, - .init_cmds = auo_b101uan08_3_init_cmd, -+ .lp11_before_reset = true, - }; - - static const struct drm_display_mode boe_tv105wum_nw0_default_mode = { -@@ -1495,6 +1501,7 @@ static const struct panel_desc boe_tv105wum_nw0_desc = { - .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_LPM, - .init_cmds = boe_init_cmd, -+ .lp11_before_reset = true, - }; - - static int boe_panel_get_modes(struct drm_panel *panel, -diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c -index 0e8622ccd3a0f..005377f58eb4a 100644 ---- a/drivers/gpu/drm/panel/panel-simple.c -+++ b/drivers/gpu/drm/panel/panel-simple.c -@@ -2205,13 +2205,13 @@ static const struct panel_desc innolux_g070y2_t02 = { - static const struct display_timing innolux_g101ice_l01_timing = { - .pixelclock = { 60400000, 71100000, 74700000 }, - .hactive = { 1280, 1280, 1280 }, -- .hfront_porch = { 41, 80, 100 }, -- .hback_porch = { 40, 79, 99 }, -- .hsync_len = { 1, 1, 1 }, -+ .hfront_porch = { 30, 60, 70 }, -+ .hback_porch = { 30, 60, 70 }, -+ .hsync_len = { 22, 40, 60 }, - .vactive = { 800, 800, 800 }, -- .vfront_porch = { 5, 11, 14 }, -- .vback_porch = { 4, 11, 14 }, -- .vsync_len = { 1, 1, 1 }, -+ .vfront_porch = { 3, 8, 14 }, -+ .vback_porch = { 3, 8, 14 }, -+ .vsync_len = { 4, 7, 12 }, - .flags = DISPLAY_FLAGS_DE_HIGH, - }; - -@@ -2228,6 +2228,7 @@ static const struct panel_desc innolux_g101ice_l01 = { - .disable = 200, - }, - .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, -+ .bus_flags = DRM_BUS_FLAG_DE_HIGH, - .connector_type = DRM_MODE_CONNECTOR_LVDS, - }; - -diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -index ae8c532f7fc84..632ab8941eb44 100644 ---- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c -@@ -248,14 +248,22 @@ static inline void vop_cfg_done(struct vop *vop) - VOP_REG_SET(vop, common, cfg_done, 1); - } - --static bool has_rb_swapped(uint32_t format) -+static bool has_rb_swapped(uint32_t version, uint32_t format) - { - switch (format) { - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_ABGR8888: -- case DRM_FORMAT_BGR888: - case DRM_FORMAT_BGR565: - return true; -+ /* -+ * full framework (IP version 3.x) only need rb swapped for RGB888 and -+ * little framework (IP version 2.x) only need rb swapped for BGR888, -+ * check for 3.x to also only rb swap BGR888 for unknown vop version -+ */ -+ case DRM_FORMAT_RGB888: -+ return VOP_MAJOR(version) == 3; -+ case DRM_FORMAT_BGR888: -+ return VOP_MAJOR(version) != 3; - default: - return false; - } -@@ -1017,7 +1025,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, - VOP_WIN_SET(vop, win, dsp_info, dsp_info); - VOP_WIN_SET(vop, win, dsp_st, dsp_st); - -- rb_swap = has_rb_swapped(fb->format->format); -+ rb_swap = has_rb_swapped(vop->data->version, fb->format->format); - VOP_WIN_SET(vop, win, rb_swap, rb_swap); - - /* -diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index 799a3086dbb06..cdad3a0662876 100644 ---- a/drivers/hid/hid-core.c -+++ b/drivers/hid/hid-core.c -@@ -707,15 +707,22 @@ static void hid_close_report(struct hid_device *device) - * Free a device structure, all reports, and all fields. - */ - --static void hid_device_release(struct device *dev) -+void hiddev_free(struct kref *ref) - { -- struct hid_device *hid = to_hid_device(dev); -+ struct hid_device *hid = container_of(ref, struct hid_device, ref); - - hid_close_report(hid); - kfree(hid->dev_rdesc); - kfree(hid); - } - -+static void hid_device_release(struct device *dev) -+{ -+ struct hid_device *hid = to_hid_device(dev); -+ -+ kref_put(&hid->ref, hiddev_free); -+} -+ - /* - * Fetch a report description item from the data stream. We support long - * items, though they are not used yet. -@@ -2813,6 +2820,7 @@ struct hid_device *hid_allocate_device(void) - spin_lock_init(&hdev->debug_list_lock); - sema_init(&hdev->driver_input_lock, 1); - mutex_init(&hdev->ll_open_lock); -+ kref_init(&hdev->ref); - - return hdev; - } -diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c -index 15e35702773cd..7f78622b1b0b3 100644 ---- a/drivers/hid/hid-debug.c -+++ b/drivers/hid/hid-debug.c -@@ -1132,6 +1132,7 @@ static int hid_debug_events_open(struct inode *inode, struct file *file) - goto out; - } - list->hdev = (struct hid_device *) inode->i_private; -+ kref_get(&list->hdev->ref); - file->private_data = list; - mutex_init(&list->read_mutex); - -@@ -1224,6 +1225,8 @@ static int hid_debug_events_release(struct inode *inode, struct file *file) - list_del(&list->node); - spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags); - kfifo_free(&list->hid_debug_fifo); -+ -+ kref_put(&list->hdev->ref, hiddev_free); - kfree(list); - - return 0; -diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c -index 68b9d7ca864e2..4d3595d6d1c40 100644 ---- a/drivers/md/bcache/btree.c -+++ b/drivers/md/bcache/btree.c -@@ -1342,7 +1342,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, - memset(new_nodes, 0, sizeof(new_nodes)); - closure_init_stack(&cl); - -- while (nodes < GC_MERGE_NODES && !IS_ERR(r[nodes].b)) -+ while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b)) - keys += r[nodes++].keys; - - blocks = btree_default_blocks(b->c) * 2 / 3; -@@ -1506,6 +1506,8 @@ static int btree_gc_rewrite_node(struct btree *b, struct btree_op *op, - return 0; - - n = btree_node_alloc_replacement(replace, NULL); -+ if (IS_ERR(n)) -+ return 0; - - /* recheck reserve after allocating replacement node */ - if (btree_check_reserve(b, NULL)) { -diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c -index c6f677059214d..025fe6479bb68 100644 ---- a/drivers/md/bcache/sysfs.c -+++ b/drivers/md/bcache/sysfs.c -@@ -1103,7 +1103,7 @@ SHOW(__bch_cache) - sum += INITIAL_PRIO - cached[i]; - - if (n) -- do_div(sum, n); -+ sum = div64_u64(sum, n); - - for (i = 0; i < ARRAY_SIZE(q); i++) - q[i] = INITIAL_PRIO - cached[n * (i + 1) / -diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c -index 7bac2a88b794a..01c7c6ca4789f 100644 ---- a/drivers/md/bcache/writeback.c -+++ b/drivers/md/bcache/writeback.c -@@ -977,24 +977,35 @@ static int bch_btre_dirty_init_thread_nr(void) - void bch_sectors_dirty_init(struct bcache_device *d) - { - int i; -+ struct btree *b = NULL; - struct bkey *k = NULL; - struct btree_iter iter; - struct sectors_dirty_init op; - struct cache_set *c = d->c; - struct bch_dirty_init_state state; - -+retry_lock: -+ b = c->root; -+ rw_lock(0, b, b->level); -+ if (b != c->root) { -+ rw_unlock(0, b); -+ goto retry_lock; -+ } -+ - /* Just count root keys if no leaf node */ -- rw_lock(0, c->root, c->root->level); - if (c->root->level == 0) { - bch_btree_op_init(&op.op, -1); - op.inode = d->id; - op.count = 0; - - for_each_key_filter(&c->root->keys, -- k, &iter, bch_ptr_invalid) -+ k, &iter, bch_ptr_invalid) { -+ if (KEY_INODE(k) != op.inode) -+ continue; - sectors_dirty_init_fn(&op.op, c->root, k); -+ } - -- rw_unlock(0, c->root); -+ rw_unlock(0, b); - return; - } - -@@ -1014,23 +1025,24 @@ void bch_sectors_dirty_init(struct bcache_device *d) - if (atomic_read(&state.enough)) - break; - -+ atomic_inc(&state.started); - state.infos[i].state = &state; - state.infos[i].thread = - kthread_run(bch_dirty_init_thread, &state.infos[i], - "bch_dirtcnt[%d]", i); - if (IS_ERR(state.infos[i].thread)) { - pr_err("fails to run thread bch_dirty_init[%d]\n", i); -+ atomic_dec(&state.started); - for (--i; i >= 0; i--) - kthread_stop(state.infos[i].thread); - goto out; - } -- atomic_inc(&state.started); - } - - out: - /* Must wait for all threads to stop. */ - wait_event(state.wait, atomic_read(&state.started) == 0); -- rw_unlock(0, c->root); -+ rw_unlock(0, b); - } - - void bch_cached_dev_writeback_init(struct cached_dev *dc) -diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c -index 02b8f4e818276..43541c8e2b43d 100644 ---- a/drivers/md/dm-delay.c -+++ b/drivers/md/dm-delay.c -@@ -30,7 +30,7 @@ struct delay_c { - struct workqueue_struct *kdelayd_wq; - struct work_struct flush_expired_bios; - struct list_head delayed_bios; -- atomic_t may_delay; -+ bool may_delay; - - struct delay_class read; - struct delay_class write; -@@ -191,7 +191,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) - INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); - INIT_LIST_HEAD(&dc->delayed_bios); - mutex_init(&dc->timer_lock); -- atomic_set(&dc->may_delay, 1); -+ dc->may_delay = true; - dc->argc = argc; - - ret = delay_class_ctr(ti, &dc->read, argv); -@@ -246,7 +246,7 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio) - struct dm_delay_info *delayed; - unsigned long expires = 0; - -- if (!c->delay || !atomic_read(&dc->may_delay)) -+ if (!c->delay) - return DM_MAPIO_REMAPPED; - - delayed = dm_per_bio_data(bio, sizeof(struct dm_delay_info)); -@@ -255,6 +255,10 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio) - delayed->expires = expires = jiffies + msecs_to_jiffies(c->delay); - - mutex_lock(&delayed_bios_lock); -+ if (unlikely(!dc->may_delay)) { -+ mutex_unlock(&delayed_bios_lock); -+ return DM_MAPIO_REMAPPED; -+ } - c->ops++; - list_add_tail(&delayed->list, &dc->delayed_bios); - mutex_unlock(&delayed_bios_lock); -@@ -268,7 +272,10 @@ static void delay_presuspend(struct dm_target *ti) - { - struct delay_c *dc = ti->private; - -- atomic_set(&dc->may_delay, 0); -+ mutex_lock(&delayed_bios_lock); -+ dc->may_delay = false; -+ mutex_unlock(&delayed_bios_lock); -+ - del_timer_sync(&dc->delay_timer); - flush_bios(flush_delayed_bios(dc, 1)); - } -@@ -277,7 +284,7 @@ static void delay_resume(struct dm_target *ti) - { - struct delay_c *dc = ti->private; - -- atomic_set(&dc->may_delay, 1); -+ dc->may_delay = true; - } - - static int delay_map(struct dm_target *ti, struct bio *bio) -diff --git a/drivers/md/md.c b/drivers/md/md.c -index e87507d29895e..20f67edae95d0 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -8648,7 +8648,8 @@ static void md_end_io_acct(struct bio *bio) - struct md_io_acct *md_io_acct = bio->bi_private; - struct bio *orig_bio = md_io_acct->orig_bio; - -- orig_bio->bi_status = bio->bi_status; -+ if (bio->bi_status && !orig_bio->bi_status) -+ orig_bio->bi_status = bio->bi_status; - - bio_end_io_acct(orig_bio, md_io_acct->start_time); - bio_put(bio); -diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c -index 07b64d257512c..f9492b1d16e3e 100644 ---- a/drivers/media/platform/qcom/camss/camss-vfe-170.c -+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c -@@ -671,7 +671,12 @@ out_unlock: - */ - static void vfe_pm_domain_off(struct vfe_device *vfe) - { -- /* nop */ -+ struct camss *camss = vfe->camss; -+ -+ if (vfe->id >= camss->vfe_num) -+ return; -+ -+ device_link_del(camss->genpd_link[vfe->id]); - } - - /* -@@ -680,6 +685,19 @@ static void vfe_pm_domain_off(struct vfe_device *vfe) - */ - static int vfe_pm_domain_on(struct vfe_device *vfe) - { -+ struct camss *camss = vfe->camss; -+ enum vfe_line_id id = vfe->id; -+ -+ if (id >= camss->vfe_num) -+ return 0; -+ -+ camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], -+ DL_FLAG_STATELESS | -+ DL_FLAG_PM_RUNTIME | -+ DL_FLAG_RPM_ACTIVE); -+ if (!camss->genpd_link[id]) -+ return -EINVAL; -+ - return 0; - } - -diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c -index ab42600f7a745..72f5cfeeb49bf 100644 ---- a/drivers/media/platform/qcom/camss/camss-vfe-480.c -+++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c -@@ -478,7 +478,12 @@ out_unlock: - */ - static void vfe_pm_domain_off(struct vfe_device *vfe) - { -- /* nop */ -+ struct camss *camss = vfe->camss; -+ -+ if (vfe->id >= camss->vfe_num) -+ return; -+ -+ device_link_del(camss->genpd_link[vfe->id]); - } - - /* -@@ -487,6 +492,19 @@ static void vfe_pm_domain_off(struct vfe_device *vfe) - */ - static int vfe_pm_domain_on(struct vfe_device *vfe) - { -+ struct camss *camss = vfe->camss; -+ enum vfe_line_id id = vfe->id; -+ -+ if (id >= camss->vfe_num) -+ return 0; -+ -+ camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], -+ DL_FLAG_STATELESS | -+ DL_FLAG_PM_RUNTIME | -+ DL_FLAG_RPM_ACTIVE); -+ if (!camss->genpd_link[id]) -+ return -EINVAL; -+ - return 0; - } - -diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c -index 5057b2c4cf6c4..a30461de3e844 100644 ---- a/drivers/media/platform/qcom/camss/camss.c -+++ b/drivers/media/platform/qcom/camss/camss.c -@@ -1453,7 +1453,6 @@ static const struct media_device_ops camss_media_ops = { - static int camss_configure_pd(struct camss *camss) - { - struct device *dev = camss->dev; -- int last_pm_domain = 0; - int i; - int ret; - -@@ -1484,32 +1483,34 @@ static int camss_configure_pd(struct camss *camss) - if (!camss->genpd_link) - return -ENOMEM; - -+ /* -+ * VFE power domains are in the beginning of the list, and while all -+ * power domains should be attached, only if TITAN_TOP power domain is -+ * found in the list, it should be linked over here. -+ */ - for (i = 0; i < camss->genpd_num; i++) { - camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i); - if (IS_ERR(camss->genpd[i])) { - ret = PTR_ERR(camss->genpd[i]); - goto fail_pm; - } -+ } - -- camss->genpd_link[i] = device_link_add(camss->dev, camss->genpd[i], -- DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | -- DL_FLAG_RPM_ACTIVE); -- if (!camss->genpd_link[i]) { -- dev_pm_domain_detach(camss->genpd[i], true); -+ if (i > camss->vfe_num) { -+ camss->genpd_link[i - 1] = device_link_add(camss->dev, camss->genpd[i - 1], -+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | -+ DL_FLAG_RPM_ACTIVE); -+ if (!camss->genpd_link[i - 1]) { - ret = -EINVAL; - goto fail_pm; - } -- -- last_pm_domain = i; - } - - return 0; - - fail_pm: -- for (i = 0; i < last_pm_domain; i++) { -- device_link_del(camss->genpd_link[i]); -+ for (--i ; i >= 0; i--) - dev_pm_domain_detach(camss->genpd[i], true); -- } - - return ret; - } -@@ -1537,6 +1538,20 @@ static int camss_icc_get(struct camss *camss) - return 0; - } - -+static void camss_genpd_cleanup(struct camss *camss) -+{ -+ int i; -+ -+ if (camss->genpd_num == 1) -+ return; -+ -+ if (camss->genpd_num > camss->vfe_num) -+ device_link_del(camss->genpd_link[camss->genpd_num - 1]); -+ -+ for (i = 0; i < camss->genpd_num; i++) -+ dev_pm_domain_detach(camss->genpd[i], true); -+} -+ - /* - * camss_probe - Probe CAMSS platform device - * @pdev: Pointer to CAMSS platform device -@@ -1612,31 +1627,23 @@ static int camss_probe(struct platform_device *pdev) - if (!camss->vfe) - return -ENOMEM; - -- v4l2_async_nf_init(&camss->notifier); -- -- num_subdevs = camss_of_parse_ports(camss); -- if (num_subdevs < 0) { -- ret = num_subdevs; -- goto err_cleanup; -- } -- - ret = camss_icc_get(camss); - if (ret < 0) -- goto err_cleanup; -+ return ret; - - ret = camss_configure_pd(camss); - if (ret < 0) { - dev_err(dev, "Failed to configure power domains: %d\n", ret); -- goto err_cleanup; -+ return ret; - } - - ret = camss_init_subdevices(camss); - if (ret < 0) -- goto err_cleanup; -+ goto err_genpd_cleanup; - - ret = dma_set_mask_and_coherent(dev, 0xffffffff); - if (ret) -- goto err_cleanup; -+ goto err_genpd_cleanup; - - camss->media_dev.dev = camss->dev; - strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", -@@ -1648,12 +1655,20 @@ static int camss_probe(struct platform_device *pdev) - ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); - if (ret < 0) { - dev_err(dev, "Failed to register V4L2 device: %d\n", ret); -- goto err_cleanup; -+ goto err_genpd_cleanup; -+ } -+ -+ v4l2_async_nf_init(&camss->notifier); -+ -+ num_subdevs = camss_of_parse_ports(camss); -+ if (num_subdevs < 0) { -+ ret = num_subdevs; -+ goto err_v4l2_device_unregister; - } - - ret = camss_register_entities(camss); - if (ret < 0) -- goto err_register_entities; -+ goto err_v4l2_device_unregister; - - if (num_subdevs) { - camss->notifier.ops = &camss_subdev_notifier_ops; -@@ -1688,31 +1703,22 @@ static int camss_probe(struct platform_device *pdev) - - err_register_subdevs: - camss_unregister_entities(camss); --err_register_entities: -+err_v4l2_device_unregister: - v4l2_device_unregister(&camss->v4l2_dev); --err_cleanup: - v4l2_async_nf_cleanup(&camss->notifier); -+err_genpd_cleanup: -+ camss_genpd_cleanup(camss); - - return ret; - } - - void camss_delete(struct camss *camss) - { -- int i; -- - v4l2_device_unregister(&camss->v4l2_dev); - media_device_unregister(&camss->media_dev); - media_device_cleanup(&camss->media_dev); - - pm_runtime_disable(camss->dev); -- -- if (camss->genpd_num == 1) -- return; -- -- for (i = 0; i < camss->genpd_num; i++) { -- device_link_del(camss->genpd_link[i]); -- dev_pm_domain_detach(camss->genpd[i], true); -- } - } - - /* -@@ -1721,7 +1727,7 @@ void camss_delete(struct camss *camss) - * - * Always returns 0. - */ --static int camss_remove(struct platform_device *pdev) -+static void camss_remove(struct platform_device *pdev) - { - struct camss *camss = platform_get_drvdata(pdev); - -@@ -1732,7 +1738,7 @@ static int camss_remove(struct platform_device *pdev) - if (atomic_read(&camss->ref_count) == 0) - camss_delete(camss); - -- return 0; -+ camss_genpd_cleanup(camss); - } - - static const struct of_device_id camss_dt_match[] = { -@@ -1794,7 +1800,7 @@ static const struct dev_pm_ops camss_pm_ops = { - - static struct platform_driver qcom_camss_driver = { - .probe = camss_probe, -- .remove = camss_remove, -+ .remove_new = camss_remove, - .driver = { - .name = "qcom-camss", - .of_match_table = camss_dt_match, -diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c -index 614c0278419bc..6b73648b37793 100644 ---- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c -+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c -@@ -682,10 +682,24 @@ static void xgbe_service(struct work_struct *work) - static void xgbe_service_timer(struct timer_list *t) - { - struct xgbe_prv_data *pdata = from_timer(pdata, t, service_timer); -+ struct xgbe_channel *channel; -+ unsigned int i; - - queue_work(pdata->dev_workqueue, &pdata->service_work); - - mod_timer(&pdata->service_timer, jiffies + HZ); -+ -+ if (!pdata->tx_usecs) -+ return; -+ -+ for (i = 0; i < pdata->channel_count; i++) { -+ channel = pdata->channel[i]; -+ if (!channel->tx_ring || channel->tx_timer_active) -+ break; -+ channel->tx_timer_active = 1; -+ mod_timer(&channel->tx_timer, -+ jiffies + usecs_to_jiffies(pdata->tx_usecs)); -+ } - } - - static void xgbe_init_timers(struct xgbe_prv_data *pdata) -diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c -index 6e83ff59172a3..32fab5e772462 100644 ---- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c -+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c -@@ -314,10 +314,15 @@ static int xgbe_get_link_ksettings(struct net_device *netdev, - - cmd->base.phy_address = pdata->phy.address; - -- cmd->base.autoneg = pdata->phy.autoneg; -- cmd->base.speed = pdata->phy.speed; -- cmd->base.duplex = pdata->phy.duplex; -+ if (netif_carrier_ok(netdev)) { -+ cmd->base.speed = pdata->phy.speed; -+ cmd->base.duplex = pdata->phy.duplex; -+ } else { -+ cmd->base.speed = SPEED_UNKNOWN; -+ cmd->base.duplex = DUPLEX_UNKNOWN; -+ } - -+ cmd->base.autoneg = pdata->phy.autoneg; - cmd->base.port = PORT_NONE; - - XGBE_LM_COPY(cmd, supported, lks, supported); -diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c -index ca7372369b3e6..60be836b294bb 100644 ---- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c -+++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c -@@ -1178,7 +1178,19 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) - if (pdata->phy.duplex != DUPLEX_FULL) - return -EINVAL; - -- xgbe_set_mode(pdata, mode); -+ /* Force the mode change for SFI in Fixed PHY config. -+ * Fixed PHY configs needs PLL to be enabled while doing mode set. -+ * When the SFP module isn't connected during boot, driver assumes -+ * AN is ON and attempts autonegotiation. However, if the connected -+ * SFP comes up in Fixed PHY config, the link will not come up as -+ * PLL isn't enabled while the initial mode set command is issued. -+ * So, force the mode change for SFI in Fixed PHY configuration to -+ * fix link issues. -+ */ -+ if (mode == XGBE_MODE_SFI) -+ xgbe_change_mode(pdata, mode); -+ else -+ xgbe_set_mode(pdata, mode); - - return 0; - } -diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c -index 8bcb98b85e3d9..a289f1bb3dbfc 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_client.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_client.c -@@ -686,8 +686,8 @@ static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, - ctxt.flags = I40E_AQ_VSI_TYPE_PF; - if (err) { - dev_info(&pf->pdev->dev, -- "couldn't get PF vsi config, err %d aq_err %s\n", -- err, -+ "couldn't get PF vsi config, err %pe aq_err %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - return -ENOENT; -@@ -714,8 +714,8 @@ static int i40e_client_update_vsi_ctxt(struct i40e_info *ldev, - err = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (err) { - dev_info(&pf->pdev->dev, -- "update VSI ctxt for PE failed, err %d aq_err %s\n", -- err, -+ "update VSI ctxt for PE failed, err %pe aq_err %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - } -diff --git a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c -index bba70bd5703bf..195421d863ab1 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c -@@ -135,8 +135,8 @@ static int i40e_dcbnl_ieee_setets(struct net_device *netdev, - ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg); - if (ret) { - dev_info(&pf->pdev->dev, -- "Failed setting DCB ETS configuration err %d aq_err %s\n", -- ret, -+ "Failed setting DCB ETS configuration err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return -EINVAL; - } -@@ -174,8 +174,8 @@ static int i40e_dcbnl_ieee_setpfc(struct net_device *netdev, - ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg); - if (ret) { - dev_info(&pf->pdev->dev, -- "Failed setting DCB PFC configuration err %d aq_err %s\n", -- ret, -+ "Failed setting DCB PFC configuration err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return -EINVAL; - } -@@ -225,8 +225,8 @@ static int i40e_dcbnl_ieee_setapp(struct net_device *netdev, - ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg); - if (ret) { - dev_info(&pf->pdev->dev, -- "Failed setting DCB configuration err %d aq_err %s\n", -- ret, -+ "Failed setting DCB configuration err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return -EINVAL; - } -@@ -290,8 +290,8 @@ static int i40e_dcbnl_ieee_delapp(struct net_device *netdev, - ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg); - if (ret) { - dev_info(&pf->pdev->dev, -- "Failed setting DCB configuration err %d aq_err %s\n", -- ret, -+ "Failed setting DCB configuration err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return -EINVAL; - } -diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c -index e632041aed5f8..107bcca7db8c9 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c -@@ -1453,8 +1453,8 @@ static int i40e_set_link_ksettings(struct net_device *netdev, - status = i40e_aq_set_phy_config(hw, &config, NULL); - if (status) { - netdev_info(netdev, -- "Set phy config failed, err %d aq_err %s\n", -- status, -+ "Set phy config failed, err %pe aq_err %s\n", -+ ERR_PTR(status), - i40e_aq_str(hw, hw->aq.asq_last_status)); - err = -EAGAIN; - goto done; -@@ -1463,8 +1463,8 @@ static int i40e_set_link_ksettings(struct net_device *netdev, - status = i40e_update_link_info(hw); - if (status) - netdev_dbg(netdev, -- "Updating link info failed with err %d aq_err %s\n", -- status, -+ "Updating link info failed with err %pe aq_err %s\n", -+ ERR_PTR(status), - i40e_aq_str(hw, hw->aq.asq_last_status)); - - } else { -@@ -1515,8 +1515,8 @@ static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg) - status = i40e_aq_set_phy_config(hw, &config, NULL); - if (status) { - netdev_info(netdev, -- "Set phy config failed, err %d aq_err %s\n", -- status, -+ "Set phy config failed, err %pe aq_err %s\n", -+ ERR_PTR(status), - i40e_aq_str(hw, hw->aq.asq_last_status)); - err = -EAGAIN; - goto done; -@@ -1529,8 +1529,8 @@ static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg) - * (e.g. no physical connection etc.) - */ - netdev_dbg(netdev, -- "Updating link info failed with err %d aq_err %s\n", -- status, -+ "Updating link info failed with err %pe aq_err %s\n", -+ ERR_PTR(status), - i40e_aq_str(hw, hw->aq.asq_last_status)); - } - -@@ -1636,8 +1636,8 @@ static int i40e_nway_reset(struct net_device *netdev) - - ret = i40e_aq_set_link_restart_an(hw, link_up, NULL); - if (ret) { -- netdev_info(netdev, "link restart failed, err %d aq_err %s\n", -- ret, -+ netdev_info(netdev, "link restart failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return -EIO; - } -@@ -1753,20 +1753,20 @@ static int i40e_set_pauseparam(struct net_device *netdev, - status = i40e_set_fc(hw, &aq_failures, link_up); - - if (aq_failures & I40E_SET_FC_AQ_FAIL_GET) { -- netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with err %d aq_err %s\n", -- status, -+ netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with err %pe aq_err %s\n", -+ ERR_PTR(status), - i40e_aq_str(hw, hw->aq.asq_last_status)); - err = -EAGAIN; - } - if (aq_failures & I40E_SET_FC_AQ_FAIL_SET) { -- netdev_info(netdev, "Set fc failed on the set_phy_config call with err %d aq_err %s\n", -- status, -+ netdev_info(netdev, "Set fc failed on the set_phy_config call with err %pe aq_err %s\n", -+ ERR_PTR(status), - i40e_aq_str(hw, hw->aq.asq_last_status)); - err = -EAGAIN; - } - if (aq_failures & I40E_SET_FC_AQ_FAIL_UPDATE) { -- netdev_info(netdev, "Set fc failed on the get_link_info call with err %d aq_err %s\n", -- status, -+ netdev_info(netdev, "Set fc failed on the get_link_info call with err %pe aq_err %s\n", -+ ERR_PTR(status), - i40e_aq_str(hw, hw->aq.asq_last_status)); - err = -EAGAIN; - } -@@ -5360,8 +5360,8 @@ flags_complete: - 0, NULL); - if (ret && pf->hw.aq.asq_last_status != I40E_AQ_RC_ESRCH) { - dev_info(&pf->pdev->dev, -- "couldn't set switch config bits, err %d aq_err %s\n", -- ret, -+ "couldn't set switch config bits, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - /* not a fatal problem, just keep going */ -@@ -5433,8 +5433,8 @@ flags_complete: - return -EBUSY; - default: - dev_warn(&pf->pdev->dev, -- "Starting FW LLDP agent failed: error: %d, %s\n", -- status, -+ "Starting FW LLDP agent failed: error: %pe, %s\n", -+ ERR_PTR(status), - i40e_aq_str(&pf->hw, - adq_err)); - return -EINVAL; -diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c -index 68ee2c59692d1..9f5824eb8808a 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -1822,8 +1822,8 @@ static int i40e_set_mac(struct net_device *netdev, void *p) - ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL, - addr->sa_data, NULL); - if (ret) -- netdev_info(netdev, "Ignoring error from firmware on LAA update, status %d, AQ ret %s\n", -- ret, -+ netdev_info(netdev, "Ignoring error from firmware on LAA update, status %pe, AQ ret %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - } - -@@ -1854,8 +1854,8 @@ static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed, - ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw); - if (ret) { - dev_info(&pf->pdev->dev, -- "Cannot set RSS key, err %d aq_err %s\n", -- ret, -+ "Cannot set RSS key, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return ret; - } -@@ -1866,8 +1866,8 @@ static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed, - ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size); - if (ret) { - dev_info(&pf->pdev->dev, -- "Cannot set RSS lut, err %d aq_err %s\n", -- ret, -+ "Cannot set RSS lut, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return ret; - } -@@ -2358,8 +2358,8 @@ void i40e_aqc_del_filters(struct i40e_vsi *vsi, const char *vsi_name, - if (aq_ret && !(aq_status == I40E_AQ_RC_ENOENT)) { - *retval = -EIO; - dev_info(&vsi->back->pdev->dev, -- "ignoring delete macvlan error on %s, err %d, aq_err %s\n", -- vsi_name, aq_ret, -+ "ignoring delete macvlan error on %s, err %pe, aq_err %s\n", -+ vsi_name, ERR_PTR(aq_ret), - i40e_aq_str(hw, aq_status)); - } - } -@@ -2488,8 +2488,8 @@ static int i40e_set_promiscuous(struct i40e_pf *pf, bool promisc) - NULL); - if (aq_ret) { - dev_info(&pf->pdev->dev, -- "Set default VSI failed, err %d, aq_err %s\n", -- aq_ret, -+ "Set default VSI failed, err %pe, aq_err %s\n", -+ ERR_PTR(aq_ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - } - } else { -@@ -2500,8 +2500,8 @@ static int i40e_set_promiscuous(struct i40e_pf *pf, bool promisc) - true); - if (aq_ret) { - dev_info(&pf->pdev->dev, -- "set unicast promisc failed, err %d, aq_err %s\n", -- aq_ret, -+ "set unicast promisc failed, err %pe, aq_err %s\n", -+ ERR_PTR(aq_ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - } - aq_ret = i40e_aq_set_vsi_multicast_promiscuous( -@@ -2510,8 +2510,8 @@ static int i40e_set_promiscuous(struct i40e_pf *pf, bool promisc) - promisc, NULL); - if (aq_ret) { - dev_info(&pf->pdev->dev, -- "set multicast promisc failed, err %d, aq_err %s\n", -- aq_ret, -+ "set multicast promisc failed, err %pe, aq_err %s\n", -+ ERR_PTR(aq_ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - } - } -@@ -2815,9 +2815,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) - retval = i40e_aq_rc_to_posix(aq_ret, - hw->aq.asq_last_status); - dev_info(&pf->pdev->dev, -- "set multi promisc failed on %s, err %d aq_err %s\n", -+ "set multi promisc failed on %s, err %pe aq_err %s\n", - vsi_name, -- aq_ret, -+ ERR_PTR(aq_ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - } else { - dev_info(&pf->pdev->dev, "%s allmulti mode.\n", -@@ -2835,10 +2835,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) - retval = i40e_aq_rc_to_posix(aq_ret, - hw->aq.asq_last_status); - dev_info(&pf->pdev->dev, -- "Setting promiscuous %s failed on %s, err %d aq_err %s\n", -+ "Setting promiscuous %s failed on %s, err %pe aq_err %s\n", - cur_promisc ? "on" : "off", - vsi_name, -- aq_ret, -+ ERR_PTR(aq_ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - } - } -@@ -2986,8 +2986,8 @@ void i40e_vlan_stripping_enable(struct i40e_vsi *vsi) - ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (ret) { - dev_info(&vsi->back->pdev->dev, -- "update vlan stripping failed, err %d aq_err %s\n", -- ret, -+ "update vlan stripping failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&vsi->back->hw, - vsi->back->hw.aq.asq_last_status)); - } -@@ -3021,8 +3021,8 @@ void i40e_vlan_stripping_disable(struct i40e_vsi *vsi) - ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (ret) { - dev_info(&vsi->back->pdev->dev, -- "update vlan stripping failed, err %d aq_err %s\n", -- ret, -+ "update vlan stripping failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&vsi->back->hw, - vsi->back->hw.aq.asq_last_status)); - } -@@ -3266,8 +3266,8 @@ int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid) - ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (ret) { - dev_info(&vsi->back->pdev->dev, -- "add pvid failed, err %d aq_err %s\n", -- ret, -+ "add pvid failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&vsi->back->hw, - vsi->back->hw.aq.asq_last_status)); - return -ENOENT; -@@ -5533,8 +5533,8 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi) - ret = i40e_aq_query_vsi_bw_config(hw, vsi->seid, &bw_config, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't get PF vsi bw config, err %d aq_err %s\n", -- ret, -+ "couldn't get PF vsi bw config, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return -EINVAL; - } -@@ -5544,8 +5544,8 @@ static int i40e_vsi_get_bw_info(struct i40e_vsi *vsi) - NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't get PF vsi ets bw config, err %d aq_err %s\n", -- ret, -+ "couldn't get PF vsi ets bw config, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return -EINVAL; - } -@@ -5734,8 +5734,8 @@ int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset) - - ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); - if (ret) { -- dev_info(&pf->pdev->dev, "Update vsi config failed, err %d aq_err %s\n", -- ret, -+ dev_info(&pf->pdev->dev, "Update vsi config failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return ret; - } -@@ -5790,8 +5790,8 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc) - &bw_config, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "Failed querying vsi bw info, err %d aq_err %s\n", -- ret, -+ "Failed querying vsi bw info, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - goto out; - } -@@ -5857,8 +5857,8 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc) - ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "Update vsi tc config failed, err %d aq_err %s\n", -- ret, -+ "Update vsi tc config failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - goto out; - } -@@ -5870,8 +5870,8 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc) - ret = i40e_vsi_get_bw_info(vsi); - if (ret) { - dev_info(&pf->pdev->dev, -- "Failed updating vsi bw info, err %d aq_err %s\n", -- ret, -+ "Failed updating vsi bw info, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - goto out; - } -@@ -5962,8 +5962,8 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate) - I40E_MAX_BW_INACTIVE_ACCUM, NULL); - if (ret) - dev_err(&pf->pdev->dev, -- "Failed set tx rate (%llu Mbps) for vsi->seid %u, err %d aq_err %s\n", -- max_tx_rate, seid, ret, -+ "Failed set tx rate (%llu Mbps) for vsi->seid %u, err %pe aq_err %s\n", -+ max_tx_rate, seid, ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return ret; - } -@@ -6038,8 +6038,8 @@ static void i40e_remove_queue_channels(struct i40e_vsi *vsi) - last_aq_status = pf->hw.aq.asq_last_status; - if (ret) - dev_info(&pf->pdev->dev, -- "Failed to delete cloud filter, err %d aq_err %s\n", -- ret, -+ "Failed to delete cloud filter, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, last_aq_status)); - kfree(cfilter); - } -@@ -6173,8 +6173,8 @@ static int i40e_vsi_reconfig_rss(struct i40e_vsi *vsi, u16 rss_size) - ret = i40e_config_rss(vsi, seed, lut, vsi->rss_table_size); - if (ret) { - dev_info(&pf->pdev->dev, -- "Cannot set RSS lut, err %d aq_err %s\n", -- ret, -+ "Cannot set RSS lut, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - kfree(lut); - return ret; -@@ -6272,8 +6272,8 @@ static int i40e_add_channel(struct i40e_pf *pf, u16 uplink_seid, - ret = i40e_aq_add_vsi(hw, &ctxt, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "add new vsi failed, err %d aq_err %s\n", -- ret, -+ "add new vsi failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - return -ENOENT; -@@ -6518,8 +6518,8 @@ static int i40e_validate_and_set_switch_mode(struct i40e_vsi *vsi) - mode, NULL); - if (ret && hw->aq.asq_last_status != I40E_AQ_RC_ESRCH) - dev_err(&pf->pdev->dev, -- "couldn't set switch config bits, err %d aq_err %s\n", -- ret, -+ "couldn't set switch config bits, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, - hw->aq.asq_last_status)); - -@@ -6719,8 +6719,8 @@ int i40e_veb_config_tc(struct i40e_veb *veb, u8 enabled_tc) - &bw_data, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "VEB bw config failed, err %d aq_err %s\n", -- ret, -+ "VEB bw config failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - goto out; - } -@@ -6729,8 +6729,8 @@ int i40e_veb_config_tc(struct i40e_veb *veb, u8 enabled_tc) - ret = i40e_veb_get_bw_info(veb); - if (ret) { - dev_info(&pf->pdev->dev, -- "Failed getting veb bw config, err %d aq_err %s\n", -- ret, -+ "Failed getting veb bw config, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - } - -@@ -6813,8 +6813,8 @@ static int i40e_resume_port_tx(struct i40e_pf *pf) - ret = i40e_aq_resume_port_tx(hw, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "Resume Port Tx failed, err %d aq_err %s\n", -- ret, -+ "Resume Port Tx failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - /* Schedule PF reset to recover */ - set_bit(__I40E_PF_RESET_REQUESTED, pf->state); -@@ -6838,8 +6838,8 @@ static int i40e_suspend_port_tx(struct i40e_pf *pf) - ret = i40e_aq_suspend_port_tx(hw, pf->mac_seid, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "Suspend Port Tx failed, err %d aq_err %s\n", -- ret, -+ "Suspend Port Tx failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - /* Schedule PF reset to recover */ - set_bit(__I40E_PF_RESET_REQUESTED, pf->state); -@@ -6878,8 +6878,8 @@ static int i40e_hw_set_dcb_config(struct i40e_pf *pf, - ret = i40e_set_dcb_config(&pf->hw); - if (ret) { - dev_info(&pf->pdev->dev, -- "Set DCB Config failed, err %d aq_err %s\n", -- ret, -+ "Set DCB Config failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - goto out; - } -@@ -6995,8 +6995,8 @@ int i40e_hw_dcb_config(struct i40e_pf *pf, struct i40e_dcbx_config *new_cfg) - i40e_aqc_opc_modify_switching_comp_ets, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "Modify Port ETS failed, err %d aq_err %s\n", -- ret, -+ "Modify Port ETS failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - goto out; - } -@@ -7033,8 +7033,8 @@ int i40e_hw_dcb_config(struct i40e_pf *pf, struct i40e_dcbx_config *new_cfg) - ret = i40e_aq_dcb_updated(&pf->hw, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "DCB Updated failed, err %d aq_err %s\n", -- ret, -+ "DCB Updated failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - goto out; - } -@@ -7117,8 +7117,8 @@ int i40e_dcb_sw_default_config(struct i40e_pf *pf) - i40e_aqc_opc_enable_switching_comp_ets, NULL); - if (err) { - dev_info(&pf->pdev->dev, -- "Enable Port ETS failed, err %d aq_err %s\n", -- err, -+ "Enable Port ETS failed, err %pe aq_err %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - err = -ENOENT; - goto out; -@@ -7197,8 +7197,8 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf) - pf->flags |= I40E_FLAG_DISABLE_FW_LLDP; - } else { - dev_info(&pf->pdev->dev, -- "Query for DCB configuration failed, err %d aq_err %s\n", -- err, -+ "Query for DCB configuration failed, err %pe aq_err %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - } - -@@ -7436,8 +7436,8 @@ static int i40e_force_link_state(struct i40e_pf *pf, bool is_up) - NULL); - if (err) { - dev_err(&pf->pdev->dev, -- "failed to get phy cap., ret = %d last_status = %s\n", -- err, -+ "failed to get phy cap., ret = %pe last_status = %s\n", -+ ERR_PTR(err), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return err; - } -@@ -7448,8 +7448,8 @@ static int i40e_force_link_state(struct i40e_pf *pf, bool is_up) - NULL); - if (err) { - dev_err(&pf->pdev->dev, -- "failed to get phy cap., ret = %d last_status = %s\n", -- err, -+ "failed to get phy cap., ret = %pe last_status = %s\n", -+ ERR_PTR(err), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return err; - } -@@ -7493,8 +7493,8 @@ static int i40e_force_link_state(struct i40e_pf *pf, bool is_up) - - if (err) { - dev_err(&pf->pdev->dev, -- "set phy config ret = %d last_status = %s\n", -- err, -+ "set phy config ret = %pe last_status = %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return err; - } -@@ -7834,8 +7834,8 @@ static int i40e_fwd_ring_up(struct i40e_vsi *vsi, struct net_device *vdev, - rx_ring->netdev = NULL; - } - dev_info(&pf->pdev->dev, -- "Error adding mac filter on macvlan err %d, aq_err %s\n", -- ret, -+ "Error adding mac filter on macvlan err %pe, aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, aq_err)); - netdev_err(vdev, "L2fwd offload disabled to L2 filter error\n"); - } -@@ -7907,8 +7907,8 @@ static int i40e_setup_macvlans(struct i40e_vsi *vsi, u16 macvlan_cnt, u16 qcnt, - ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "Update vsi tc config failed, err %d aq_err %s\n", -- ret, -+ "Update vsi tc config failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return ret; - } -@@ -8123,8 +8123,8 @@ static void i40e_fwd_del(struct net_device *netdev, void *vdev) - ch->fwd = NULL; - } else { - dev_info(&pf->pdev->dev, -- "Error deleting mac filter on macvlan err %d, aq_err %s\n", -- ret, -+ "Error deleting mac filter on macvlan err %pe, aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, aq_err)); - } - break; -@@ -8875,7 +8875,8 @@ static int i40e_delete_clsflower(struct i40e_vsi *vsi, - kfree(filter); - if (err) { - dev_err(&pf->pdev->dev, -- "Failed to delete cloud filter, err %d\n", err); -+ "Failed to delete cloud filter, err %pe\n", -+ ERR_PTR(err)); - return i40e_aq_rc_to_posix(err, pf->hw.aq.asq_last_status); - } - -@@ -9437,8 +9438,8 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf, - pf->flags &= ~I40E_FLAG_DCB_CAPABLE; - } else { - dev_info(&pf->pdev->dev, -- "Failed querying DCB configuration data from firmware, err %d aq_err %s\n", -- ret, -+ "Failed querying DCB configuration data from firmware, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - } -@@ -10264,8 +10265,8 @@ static void i40e_enable_pf_switch_lb(struct i40e_pf *pf) - ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't get PF vsi config, err %d aq_err %s\n", -- ret, -+ "couldn't get PF vsi config, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return; - } -@@ -10276,8 +10277,8 @@ static void i40e_enable_pf_switch_lb(struct i40e_pf *pf) - ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "update vsi switch failed, err %d aq_err %s\n", -- ret, -+ "update vsi switch failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - } - } -@@ -10300,8 +10301,8 @@ static void i40e_disable_pf_switch_lb(struct i40e_pf *pf) - ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't get PF vsi config, err %d aq_err %s\n", -- ret, -+ "couldn't get PF vsi config, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return; - } -@@ -10312,8 +10313,8 @@ static void i40e_disable_pf_switch_lb(struct i40e_pf *pf) - ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "update vsi switch failed, err %d aq_err %s\n", -- ret, -+ "update vsi switch failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - } - } -@@ -10457,8 +10458,8 @@ static int i40e_get_capabilities(struct i40e_pf *pf, - buf_len = data_size; - } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) { - dev_info(&pf->pdev->dev, -- "capability discovery failed, err %d aq_err %s\n", -- err, -+ "capability discovery failed, err %pe aq_err %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - return -ENODEV; -@@ -10595,8 +10596,8 @@ static int i40e_rebuild_cloud_filters(struct i40e_vsi *vsi, u16 seid) - - if (ret) { - dev_dbg(&pf->pdev->dev, -- "Failed to rebuild cloud filter, err %d aq_err %s\n", -- ret, -+ "Failed to rebuild cloud filter, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - return ret; -@@ -10836,8 +10837,8 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) - /* rebuild the basics for the AdminQ, HMC, and initial HW switch */ - ret = i40e_init_adminq(&pf->hw); - if (ret) { -- dev_info(&pf->pdev->dev, "Rebuild AdminQ failed, err %d aq_err %s\n", -- ret, -+ dev_info(&pf->pdev->dev, "Rebuild AdminQ failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - goto clear_recovery; - } -@@ -10948,8 +10949,8 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) - I40E_AQ_EVENT_MEDIA_NA | - I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL); - if (ret) -- dev_info(&pf->pdev->dev, "set phy mask fail, err %d aq_err %s\n", -- ret, -+ dev_info(&pf->pdev->dev, "set phy mask fail, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - - /* Rebuild the VSIs and VEBs that existed before reset. -@@ -11052,8 +11053,8 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) - msleep(75); - ret = i40e_aq_set_link_restart_an(&pf->hw, true, NULL); - if (ret) -- dev_info(&pf->pdev->dev, "link restart failed, err %d aq_err %s\n", -- ret, -+ dev_info(&pf->pdev->dev, "link restart failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - } -@@ -11084,9 +11085,9 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) - ret = i40e_set_promiscuous(pf, pf->cur_promisc); - if (ret) - dev_warn(&pf->pdev->dev, -- "Failed to restore promiscuous setting: %s, err %d aq_err %s\n", -+ "Failed to restore promiscuous setting: %s, err %pe aq_err %s\n", - pf->cur_promisc ? "on" : "off", -- ret, -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - - i40e_reset_all_vfs(pf, true); -@@ -12220,8 +12221,8 @@ static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed, - (struct i40e_aqc_get_set_rss_key_data *)seed); - if (ret) { - dev_info(&pf->pdev->dev, -- "Cannot get RSS key, err %d aq_err %s\n", -- ret, -+ "Cannot get RSS key, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - return ret; -@@ -12234,8 +12235,8 @@ static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed, - ret = i40e_aq_get_rss_lut(hw, vsi->id, pf_lut, lut, lut_size); - if (ret) { - dev_info(&pf->pdev->dev, -- "Cannot get RSS lut, err %d aq_err %s\n", -- ret, -+ "Cannot get RSS lut, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - return ret; -@@ -12575,8 +12576,8 @@ int i40e_commit_partition_bw_setting(struct i40e_pf *pf) - last_aq_status = pf->hw.aq.asq_last_status; - if (ret) { - dev_info(&pf->pdev->dev, -- "Cannot acquire NVM for read access, err %d aq_err %s\n", -- ret, -+ "Cannot acquire NVM for read access, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, last_aq_status)); - goto bw_commit_out; - } -@@ -12592,8 +12593,8 @@ int i40e_commit_partition_bw_setting(struct i40e_pf *pf) - last_aq_status = pf->hw.aq.asq_last_status; - i40e_release_nvm(&pf->hw); - if (ret) { -- dev_info(&pf->pdev->dev, "NVM read error, err %d aq_err %s\n", -- ret, -+ dev_info(&pf->pdev->dev, "NVM read error, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, last_aq_status)); - goto bw_commit_out; - } -@@ -12606,8 +12607,8 @@ int i40e_commit_partition_bw_setting(struct i40e_pf *pf) - last_aq_status = pf->hw.aq.asq_last_status; - if (ret) { - dev_info(&pf->pdev->dev, -- "Cannot acquire NVM for write access, err %d aq_err %s\n", -- ret, -+ "Cannot acquire NVM for write access, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, last_aq_status)); - goto bw_commit_out; - } -@@ -12626,8 +12627,8 @@ int i40e_commit_partition_bw_setting(struct i40e_pf *pf) - i40e_release_nvm(&pf->hw); - if (ret) - dev_info(&pf->pdev->dev, -- "BW settings NOT SAVED, err %d aq_err %s\n", -- ret, -+ "BW settings NOT SAVED, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, last_aq_status)); - bw_commit_out: - -@@ -12681,8 +12682,8 @@ static bool i40e_is_total_port_shutdown_enabled(struct i40e_pf *pf) - - err_nvm: - dev_warn(&pf->pdev->dev, -- "total-port-shutdown feature is off due to read nvm error: %d\n", -- read_status); -+ "total-port-shutdown feature is off due to read nvm error: %pe\n", -+ ERR_PTR(read_status)); - return ret; - } - -@@ -13009,8 +13010,8 @@ static int i40e_udp_tunnel_set_port(struct net_device *netdev, - ret = i40e_aq_add_udp_tunnel(hw, ntohs(ti->port), type, &filter_index, - NULL); - if (ret) { -- netdev_info(netdev, "add UDP port failed, err %d aq_err %s\n", -- ret, -+ netdev_info(netdev, "add UDP port failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return -EIO; - } -@@ -13029,8 +13030,8 @@ static int i40e_udp_tunnel_unset_port(struct net_device *netdev, - - ret = i40e_aq_del_udp_tunnel(hw, ti->hw_priv, NULL); - if (ret) { -- netdev_info(netdev, "delete UDP port failed, err %d aq_err %s\n", -- ret, -+ netdev_info(netdev, "delete UDP port failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(hw, hw->aq.asq_last_status)); - return -EIO; - } -@@ -13919,8 +13920,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi) - ctxt.flags = I40E_AQ_VSI_TYPE_PF; - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't get PF vsi config, err %d aq_err %s\n", -- ret, -+ "couldn't get PF vsi config, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - return -ENOENT; -@@ -13969,8 +13970,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi) - ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "update vsi failed, err %d aq_err %s\n", -- ret, -+ "update vsi failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - ret = -ENOENT; -@@ -13992,9 +13993,9 @@ static int i40e_add_vsi(struct i40e_vsi *vsi) - * message and continue - */ - dev_info(&pf->pdev->dev, -- "failed to configure TCs for main VSI tc_map 0x%08x, err %d aq_err %s\n", -+ "failed to configure TCs for main VSI tc_map 0x%08x, err %pe aq_err %s\n", - enabled_tc, -- ret, -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - } -@@ -14088,8 +14089,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi) - ret = i40e_aq_add_vsi(hw, &ctxt, NULL); - if (ret) { - dev_info(&vsi->back->pdev->dev, -- "add vsi failed, err %d aq_err %s\n", -- ret, -+ "add vsi failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - ret = -ENOENT; -@@ -14120,8 +14121,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi) - ret = i40e_vsi_get_bw_info(vsi); - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't get vsi bw info, err %d aq_err %s\n", -- ret, -+ "couldn't get vsi bw info, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - /* VSI is already added so not tearing that up */ - ret = 0; -@@ -14567,8 +14568,8 @@ static int i40e_veb_get_bw_info(struct i40e_veb *veb) - &bw_data, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "query veb bw config failed, err %d aq_err %s\n", -- ret, -+ "query veb bw config failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, hw->aq.asq_last_status)); - goto out; - } -@@ -14577,8 +14578,8 @@ static int i40e_veb_get_bw_info(struct i40e_veb *veb) - &ets_data, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "query veb bw ets config failed, err %d aq_err %s\n", -- ret, -+ "query veb bw ets config failed, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, hw->aq.asq_last_status)); - goto out; - } -@@ -14774,8 +14775,8 @@ static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi) - /* get a VEB from the hardware */ - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't add VEB, err %d aq_err %s\n", -- ret, -+ "couldn't add VEB, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return -EPERM; - } -@@ -14785,16 +14786,16 @@ static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi) - &veb->stats_idx, NULL, NULL, NULL); - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't get VEB statistics idx, err %d aq_err %s\n", -- ret, -+ "couldn't get VEB statistics idx, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return -EPERM; - } - ret = i40e_veb_get_bw_info(veb); - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't get VEB bw info, err %d aq_err %s\n", -- ret, -+ "couldn't get VEB bw info, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - i40e_aq_delete_element(&pf->hw, veb->seid, NULL); - return -ENOENT; -@@ -15050,8 +15051,8 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acqui - ret = i40e_fetch_switch_configuration(pf, false); - if (ret) { - dev_info(&pf->pdev->dev, -- "couldn't fetch switch config, err %d aq_err %s\n", -- ret, -+ "couldn't fetch switch config, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - return ret; - } -@@ -15077,8 +15078,8 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acqui - NULL); - if (ret && pf->hw.aq.asq_last_status != I40E_AQ_RC_ESRCH) { - dev_info(&pf->pdev->dev, -- "couldn't set switch config bits, err %d aq_err %s\n", -- ret, -+ "couldn't set switch config bits, err %pe aq_err %s\n", -+ ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - /* not a fatal problem, just keep going */ -@@ -15984,8 +15985,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - I40E_AQ_EVENT_MEDIA_NA | - I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL); - if (err) -- dev_info(&pf->pdev->dev, "set phy mask fail, err %d aq_err %s\n", -- err, -+ dev_info(&pf->pdev->dev, "set phy mask fail, err %pe aq_err %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - - /* Reconfigure hardware for allowing smaller MSS in the case -@@ -16003,8 +16004,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - msleep(75); - err = i40e_aq_set_link_restart_an(&pf->hw, true, NULL); - if (err) -- dev_info(&pf->pdev->dev, "link restart failed, err %d aq_err %s\n", -- err, -+ dev_info(&pf->pdev->dev, "link restart failed, err %pe aq_err %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - } -@@ -16136,8 +16137,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - /* get the requested speeds from the fw */ - err = i40e_aq_get_phy_capabilities(hw, false, false, &abilities, NULL); - if (err) -- dev_dbg(&pf->pdev->dev, "get requested speeds ret = %d last_status = %s\n", -- err, -+ dev_dbg(&pf->pdev->dev, "get requested speeds ret = %pe last_status = %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - pf->hw.phy.link_info.requested_speeds = abilities.link_speed; - -@@ -16147,8 +16148,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - /* get the supported phy types from the fw */ - err = i40e_aq_get_phy_capabilities(hw, false, true, &abilities, NULL); - if (err) -- dev_dbg(&pf->pdev->dev, "get supported phy types ret = %d last_status = %s\n", -- err, -+ dev_dbg(&pf->pdev->dev, "get supported phy types ret = %pe last_status = %s\n", -+ ERR_PTR(err), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - - /* make sure the MFS hasn't been set lower than the default */ -diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c -index 779ba907009a5..f99c1f7fec406 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c -@@ -1429,8 +1429,8 @@ static int i40e_nvmupd_exec_aq(struct i40e_hw *hw, - buff_size, &cmd_details); - if (status) { - i40e_debug(hw, I40E_DEBUG_NVM, -- "%s err %d aq_err %s\n", -- __func__, status, -+ "%s err %pe aq_err %s\n", -+ __func__, ERR_PTR(status), - i40e_aq_str(hw, hw->aq.asq_last_status)); - *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status); - return status; -diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -index 547e67d9470b7..cb925baf72ce0 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -@@ -1264,9 +1264,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable, - int aq_err = pf->hw.aq.asq_last_status; - - dev_err(&pf->pdev->dev, -- "VF %d failed to set multicast promiscuous mode err %d aq_err %s\n", -+ "VF %d failed to set multicast promiscuous mode err %pe aq_err %s\n", - vf->vf_id, -- aq_ret, -+ ERR_PTR(aq_ret), - i40e_aq_str(&pf->hw, aq_err)); - - return aq_ret; -@@ -1280,9 +1280,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable, - int aq_err = pf->hw.aq.asq_last_status; - - dev_err(&pf->pdev->dev, -- "VF %d failed to set unicast promiscuous mode err %d aq_err %s\n", -+ "VF %d failed to set unicast promiscuous mode err %pe aq_err %s\n", - vf->vf_id, -- aq_ret, -+ ERR_PTR(aq_ret), - i40e_aq_str(&pf->hw, aq_err)); - } - -@@ -1297,9 +1297,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable, - int aq_err = pf->hw.aq.asq_last_status; - - dev_err(&pf->pdev->dev, -- "VF %d failed to set multicast promiscuous mode err %d aq_err %s\n", -+ "VF %d failed to set multicast promiscuous mode err %pe aq_err %s\n", - vf->vf_id, -- aq_ret, -+ ERR_PTR(aq_ret), - i40e_aq_str(&pf->hw, aq_err)); - - if (!aq_tmp) -@@ -1313,9 +1313,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable, - int aq_err = pf->hw.aq.asq_last_status; - - dev_err(&pf->pdev->dev, -- "VF %d failed to set unicast promiscuous mode err %d aq_err %s\n", -+ "VF %d failed to set unicast promiscuous mode err %pe aq_err %s\n", - vf->vf_id, -- aq_ret, -+ ERR_PTR(aq_ret), - i40e_aq_str(&pf->hw, aq_err)); - - if (!aq_tmp) -@@ -3615,8 +3615,8 @@ static void i40e_del_all_cloud_filters(struct i40e_vf *vf) - ret = i40e_add_del_cloud_filter(vsi, cfilter, false); - if (ret) - dev_err(&pf->pdev->dev, -- "VF %d: Failed to delete cloud filter, err %d aq_err %s\n", -- vf->vf_id, ret, -+ "VF %d: Failed to delete cloud filter, err %pe aq_err %s\n", -+ vf->vf_id, ERR_PTR(ret), - i40e_aq_str(&pf->hw, - pf->hw.aq.asq_last_status)); - -@@ -3718,8 +3718,8 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg) - ret = i40e_add_del_cloud_filter(vsi, &cfilter, false); - if (ret) { - dev_err(&pf->pdev->dev, -- "VF %d: Failed to delete cloud filter, err %d aq_err %s\n", -- vf->vf_id, ret, -+ "VF %d: Failed to delete cloud filter, err %pe aq_err %s\n", -+ vf->vf_id, ERR_PTR(ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - goto err; - } -@@ -3774,7 +3774,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) - struct i40e_pf *pf = vf->pf; - struct i40e_vsi *vsi = NULL; - int aq_ret = 0; -- int i, ret; -+ int i; - - if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { - aq_ret = I40E_ERR_PARAM; -@@ -3798,8 +3798,10 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) - } - - cfilter = kzalloc(sizeof(*cfilter), GFP_KERNEL); -- if (!cfilter) -- return -ENOMEM; -+ if (!cfilter) { -+ aq_ret = -ENOMEM; -+ goto err_out; -+ } - - /* parse destination mac address */ - for (i = 0; i < ETH_ALEN; i++) -@@ -3847,13 +3849,13 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) - - /* Adding cloud filter programmed as TC filter */ - if (tcf.dst_port) -- ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter, true); -+ aq_ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter, true); - else -- ret = i40e_add_del_cloud_filter(vsi, cfilter, true); -- if (ret) { -+ aq_ret = i40e_add_del_cloud_filter(vsi, cfilter, true); -+ if (aq_ret) { - dev_err(&pf->pdev->dev, -- "VF %d: Failed to add cloud filter, err %d aq_err %s\n", -- vf->vf_id, ret, -+ "VF %d: Failed to add cloud filter, err %pe aq_err %s\n", -+ vf->vf_id, ERR_PTR(aq_ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - goto err_free; - } -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c -index 934c199667b59..5c4a4d3557702 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c -@@ -1069,6 +1069,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) - struct ethhdr *eth_hdr; - bool new = false; - int err = 0; -+ u64 vf_num; - u32 ring; - - if (!flow_cfg->max_flows) { -@@ -1081,7 +1082,21 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) - if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT)) - return -ENOMEM; - -- if (ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC) -+ /* Number of queues on a VF can be greater or less than -+ * the PF's queue. Hence no need to check for the -+ * queue count. Hence no need to check queue count if PF -+ * is installing for its VF. Below is the expected vf_num value -+ * based on the ethtool commands. -+ * -+ * e.g. -+ * 1. ethtool -U ... action -1 ==> vf_num:255 -+ * 2. ethtool -U ... action ==> vf_num:0 -+ * 3. ethtool -U ... vf queue ==> -+ * vf_num:vf_idx+1 -+ */ -+ vf_num = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie); -+ if (!is_otx2_vf(pfvf->pcifunc) && !vf_num && -+ ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC) - return -EINVAL; - - if (fsp->location >= otx2_get_maxflows(flow_cfg)) -@@ -1163,6 +1178,9 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) - flow_cfg->nr_flows++; - } - -+ if (flow->is_vf) -+ netdev_info(pfvf->netdev, -+ "Make sure that VF's queue number is within its queue limit\n"); - return 0; - } - -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -index c724131172f3f..1d2d72c60a12c 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -@@ -1919,6 +1919,8 @@ int otx2_stop(struct net_device *netdev) - /* Clear RSS enable flag */ - rss = &pf->hw.rss_info; - rss->enable = false; -+ if (!netif_is_rxfh_configured(netdev)) -+ kfree(rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]); - - /* Cleanup Queue IRQ */ - vec = pci_irq_vector(pf->pdev, -diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -index d14648558338b..5ea9dc251dd9a 100644 ---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -@@ -821,7 +821,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) - if (lp->features & XAE_FEATURE_FULL_TX_CSUM) { - /* Tx Full Checksum Offload Enabled */ - cur_p->app0 |= 2; -- } else if (lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) { -+ } else if (lp->features & XAE_FEATURE_PARTIAL_TX_CSUM) { - csum_start_off = skb_transport_offset(skb); - csum_index_off = csum_start_off + skb->csum_offset; - /* Tx Partial Checksum Offload Enabled */ -diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c -index 89eb4f179a3ce..0285894c892ab 100644 ---- a/drivers/net/hyperv/netvsc_drv.c -+++ b/drivers/net/hyperv/netvsc_drv.c -@@ -2204,9 +2204,6 @@ static int netvsc_vf_join(struct net_device *vf_netdev, - goto upper_link_failed; - } - -- /* set slave flag before open to prevent IPv6 addrconf */ -- vf_netdev->flags |= IFF_SLAVE; -- - schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); - - call_netdevice_notifiers(NETDEV_JOIN, vf_netdev); -@@ -2313,16 +2310,18 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev) - - } - -- /* Fallback path to check synthetic vf with -- * help of mac addr -+ /* Fallback path to check synthetic vf with help of mac addr. -+ * Because this function can be called before vf_netdev is -+ * initialized (NETDEV_POST_INIT) when its perm_addr has not been copied -+ * from dev_addr, also try to match to its dev_addr. -+ * Note: On Hyper-V and Azure, it's not possible to set a MAC address -+ * on a VF that matches to the MAC of a unrelated NETVSC device. - */ - list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) { - ndev = hv_get_drvdata(ndev_ctx->device_ctx); -- if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr)) { -- netdev_notice(vf_netdev, -- "falling back to mac addr based matching\n"); -+ if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr) || -+ ether_addr_equal(vf_netdev->dev_addr, ndev->perm_addr)) - return ndev; -- } - } - - netdev_notice(vf_netdev, -@@ -2330,6 +2329,19 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev) - return NULL; - } - -+static int netvsc_prepare_bonding(struct net_device *vf_netdev) -+{ -+ struct net_device *ndev; -+ -+ ndev = get_netvsc_byslot(vf_netdev); -+ if (!ndev) -+ return NOTIFY_DONE; -+ -+ /* set slave flag before open to prevent IPv6 addrconf */ -+ vf_netdev->flags |= IFF_SLAVE; -+ return NOTIFY_DONE; -+} -+ - static int netvsc_register_vf(struct net_device *vf_netdev) - { - struct net_device_context *net_device_ctx; -@@ -2529,15 +2541,6 @@ static int netvsc_probe(struct hv_device *dev, - goto devinfo_failed; - } - -- nvdev = rndis_filter_device_add(dev, device_info); -- if (IS_ERR(nvdev)) { -- ret = PTR_ERR(nvdev); -- netdev_err(net, "unable to add netvsc device (ret %d)\n", ret); -- goto rndis_failed; -- } -- -- eth_hw_addr_set(net, device_info->mac_adr); -- - /* We must get rtnl lock before scheduling nvdev->subchan_work, - * otherwise netvsc_subchan_work() can get rtnl lock first and wait - * all subchannels to show up, but that may not happen because -@@ -2545,9 +2548,23 @@ static int netvsc_probe(struct hv_device *dev, - * -> ... -> device_add() -> ... -> __device_attach() can't get - * the device lock, so all the subchannels can't be processed -- - * finally netvsc_subchan_work() hangs forever. -+ * -+ * The rtnl lock also needs to be held before rndis_filter_device_add() -+ * which advertises nvsp_2_vsc_capability / sriov bit, and triggers -+ * VF NIC offering and registering. If VF NIC finished register_netdev() -+ * earlier it may cause name based config failure. - */ - rtnl_lock(); - -+ nvdev = rndis_filter_device_add(dev, device_info); -+ if (IS_ERR(nvdev)) { -+ ret = PTR_ERR(nvdev); -+ netdev_err(net, "unable to add netvsc device (ret %d)\n", ret); -+ goto rndis_failed; -+ } -+ -+ eth_hw_addr_set(net, device_info->mac_adr); -+ - if (nvdev->num_chn > 1) - schedule_work(&nvdev->subchan_work); - -@@ -2581,9 +2598,9 @@ static int netvsc_probe(struct hv_device *dev, - return 0; - - register_failed: -- rtnl_unlock(); - rndis_filter_device_remove(dev, nvdev); - rndis_failed: -+ rtnl_unlock(); - netvsc_devinfo_put(device_info); - devinfo_failed: - free_percpu(net_device_ctx->vf_stats); -@@ -2749,6 +2766,8 @@ static int netvsc_netdev_event(struct notifier_block *this, - return NOTIFY_DONE; - - switch (event) { -+ case NETDEV_POST_INIT: -+ return netvsc_prepare_bonding(event_dev); - case NETDEV_REGISTER: - return netvsc_register_vf(event_dev); - case NETDEV_UNREGISTER: -@@ -2784,12 +2803,17 @@ static int __init netvsc_drv_init(void) - } - netvsc_ring_bytes = ring_size * PAGE_SIZE; - -+ register_netdevice_notifier(&netvsc_netdev_notifier); -+ - ret = vmbus_driver_register(&netvsc_drv); - if (ret) -- return ret; -+ goto err_vmbus_reg; - -- register_netdevice_notifier(&netvsc_netdev_notifier); - return 0; -+ -+err_vmbus_reg: -+ unregister_netdevice_notifier(&netvsc_netdev_notifier); -+ return ret; - } - - MODULE_LICENSE("GPL"); -diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c -index aff39bf3161de..4ea0e155bb0d5 100644 ---- a/drivers/net/usb/ax88179_178a.c -+++ b/drivers/net/usb/ax88179_178a.c -@@ -1583,11 +1583,11 @@ static int ax88179_reset(struct usbnet *dev) - - *tmp16 = AX_PHYPWR_RSTCTL_IPRL; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); -- msleep(200); -+ msleep(500); - - *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); -- msleep(100); -+ msleep(200); - - /* Ethernet PHY Auto Detach*/ - ax88179_auto_detach(dev); -diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c -index d58e9f818d3b7..895a621c9e267 100644 ---- a/drivers/net/wireguard/device.c -+++ b/drivers/net/wireguard/device.c -@@ -209,7 +209,7 @@ static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev) - */ - while (skb_queue_len(&peer->staged_packet_queue) > MAX_STAGED_PACKETS) { - dev_kfree_skb(__skb_dequeue(&peer->staged_packet_queue)); -- ++dev->stats.tx_dropped; -+ DEV_STATS_INC(dev, tx_dropped); - } - skb_queue_splice_tail(&packets, &peer->staged_packet_queue); - spin_unlock_bh(&peer->staged_packet_queue.lock); -@@ -227,7 +227,7 @@ err_icmp: - else if (skb->protocol == htons(ETH_P_IPV6)) - icmpv6_ndo_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); - err: -- ++dev->stats.tx_errors; -+ DEV_STATS_INC(dev, tx_errors); - kfree_skb(skb); - return ret; - } -diff --git a/drivers/net/wireguard/receive.c b/drivers/net/wireguard/receive.c -index 0b3f0c8435509..a176653c88616 100644 ---- a/drivers/net/wireguard/receive.c -+++ b/drivers/net/wireguard/receive.c -@@ -416,20 +416,20 @@ dishonest_packet_peer: - net_dbg_skb_ratelimited("%s: Packet has unallowed src IP (%pISc) from peer %llu (%pISpfsc)\n", - dev->name, skb, peer->internal_id, - &peer->endpoint.addr); -- ++dev->stats.rx_errors; -- ++dev->stats.rx_frame_errors; -+ DEV_STATS_INC(dev, rx_errors); -+ DEV_STATS_INC(dev, rx_frame_errors); - goto packet_processed; - dishonest_packet_type: - net_dbg_ratelimited("%s: Packet is neither ipv4 nor ipv6 from peer %llu (%pISpfsc)\n", - dev->name, peer->internal_id, &peer->endpoint.addr); -- ++dev->stats.rx_errors; -- ++dev->stats.rx_frame_errors; -+ DEV_STATS_INC(dev, rx_errors); -+ DEV_STATS_INC(dev, rx_frame_errors); - goto packet_processed; - dishonest_packet_size: - net_dbg_ratelimited("%s: Packet has incorrect size from peer %llu (%pISpfsc)\n", - dev->name, peer->internal_id, &peer->endpoint.addr); -- ++dev->stats.rx_errors; -- ++dev->stats.rx_length_errors; -+ DEV_STATS_INC(dev, rx_errors); -+ DEV_STATS_INC(dev, rx_length_errors); - goto packet_processed; - packet_processed: - dev_kfree_skb(skb); -diff --git a/drivers/net/wireguard/send.c b/drivers/net/wireguard/send.c -index 95c853b59e1da..0d48e0f4a1ba3 100644 ---- a/drivers/net/wireguard/send.c -+++ b/drivers/net/wireguard/send.c -@@ -333,7 +333,8 @@ err: - void wg_packet_purge_staged_packets(struct wg_peer *peer) - { - spin_lock_bh(&peer->staged_packet_queue.lock); -- peer->device->dev->stats.tx_dropped += peer->staged_packet_queue.qlen; -+ DEV_STATS_ADD(peer->device->dev, tx_dropped, -+ peer->staged_packet_queue.qlen); - __skb_queue_purge(&peer->staged_packet_queue); - spin_unlock_bh(&peer->staged_packet_queue.lock); - } -diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c -index 43b5bd8bb6a52..d8da840a1c0ed 100644 ---- a/drivers/nvme/target/fabrics-cmd.c -+++ b/drivers/nvme/target/fabrics-cmd.c -@@ -244,6 +244,8 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req) - goto out; - } - -+ d->subsysnqn[NVMF_NQN_FIELD_LEN - 1] = '\0'; -+ d->hostnqn[NVMF_NQN_FIELD_LEN - 1] = '\0'; - status = nvmet_alloc_ctrl(d->subsysnqn, d->hostnqn, req, - le32_to_cpu(c->kato), &ctrl); - if (status) -@@ -313,6 +315,8 @@ static void nvmet_execute_io_connect(struct nvmet_req *req) - goto out; - } - -+ d->subsysnqn[NVMF_NQN_FIELD_LEN - 1] = '\0'; -+ d->hostnqn[NVMF_NQN_FIELD_LEN - 1] = '\0'; - ctrl = nvmet_ctrl_find_get(d->subsysnqn, d->hostnqn, - le16_to_cpu(d->cntlid), req); - if (!ctrl) { -diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c -index 04d9b1d4b1ba9..f207de4a87a0f 100644 ---- a/drivers/s390/block/dasd.c -+++ b/drivers/s390/block/dasd.c -@@ -673,18 +673,20 @@ static void dasd_profile_start(struct dasd_block *block, - * we count each request only once. - */ - device = cqr->startdev; -- if (device->profile.data) { -- counter = 1; /* request is not yet queued on the start device */ -- list_for_each(l, &device->ccw_queue) -- if (++counter >= 31) -- break; -- } -+ if (!device->profile.data) -+ return; -+ -+ spin_lock(get_ccwdev_lock(device->cdev)); -+ counter = 1; /* request is not yet queued on the start device */ -+ list_for_each(l, &device->ccw_queue) -+ if (++counter >= 31) -+ break; -+ spin_unlock(get_ccwdev_lock(device->cdev)); -+ - spin_lock(&device->profile.lock); -- if (device->profile.data) { -- device->profile.data->dasd_io_nr_req[counter]++; -- if (rq_data_dir(req) == READ) -- device->profile.data->dasd_read_nr_req[counter]++; -- } -+ device->profile.data->dasd_io_nr_req[counter]++; -+ if (rq_data_dir(req) == READ) -+ device->profile.data->dasd_read_nr_req[counter]++; - spin_unlock(&device->profile.lock); - } - -diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c -index b23e543b3a3d5..8a2cc0405a4ad 100644 ---- a/drivers/usb/cdns3/cdnsp-ring.c -+++ b/drivers/usb/cdns3/cdnsp-ring.c -@@ -1522,6 +1522,7 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data) - unsigned long flags; - int counter = 0; - -+ local_bh_disable(); - spin_lock_irqsave(&pdev->lock, flags); - - if (pdev->cdnsp_state & (CDNSP_STATE_HALTED | CDNSP_STATE_DYING)) { -@@ -1534,6 +1535,7 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data) - cdnsp_died(pdev); - - spin_unlock_irqrestore(&pdev->lock, flags); -+ local_bh_enable(); - return IRQ_HANDLED; - } - -@@ -1550,6 +1552,7 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data) - cdnsp_update_erst_dequeue(pdev, event_ring_deq, 1); - - spin_unlock_irqrestore(&pdev->lock, flags); -+ local_bh_enable(); - - return IRQ_HANDLED; - } -diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c -index c9740caa5974b..9e85cbb0c4f15 100644 ---- a/drivers/usb/dwc2/hcd_intr.c -+++ b/drivers/usb/dwc2/hcd_intr.c -@@ -2015,15 +2015,17 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) - { - struct dwc2_qtd *qtd; - struct dwc2_host_chan *chan; -- u32 hcint, hcintmsk; -+ u32 hcint, hcintraw, hcintmsk; - - chan = hsotg->hc_ptr_array[chnum]; - -- hcint = dwc2_readl(hsotg, HCINT(chnum)); -+ hcintraw = dwc2_readl(hsotg, HCINT(chnum)); - hcintmsk = dwc2_readl(hsotg, HCINTMSK(chnum)); -+ hcint = hcintraw & hcintmsk; -+ dwc2_writel(hsotg, hcint, HCINT(chnum)); -+ - if (!chan) { - dev_err(hsotg->dev, "## hc_ptr_array for channel is NULL ##\n"); -- dwc2_writel(hsotg, hcint, HCINT(chnum)); - return; - } - -@@ -2032,11 +2034,9 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) - chnum); - dev_vdbg(hsotg->dev, - " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n", -- hcint, hcintmsk, hcint & hcintmsk); -+ hcintraw, hcintmsk, hcint); - } - -- dwc2_writel(hsotg, hcint, HCINT(chnum)); -- - /* - * If we got an interrupt after someone called - * dwc2_hcd_endpoint_disable() we don't want to crash below -@@ -2046,8 +2046,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) - return; - } - -- chan->hcint = hcint; -- hcint &= hcintmsk; -+ chan->hcint = hcintraw; - - /* - * If the channel was halted due to a dequeue, the qtd list might -diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c -index a811db88eedae..1f23c96fa94f8 100644 ---- a/drivers/usb/dwc3/core.c -+++ b/drivers/usb/dwc3/core.c -@@ -2036,6 +2036,8 @@ static int dwc3_probe(struct platform_device *pdev) - - pm_runtime_put(dev); - -+ dma_set_max_seg_size(dev, UINT_MAX); -+ - return 0; - - err5: -diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c -index 039bf241769af..57ddd2e43022e 100644 ---- a/drivers/usb/dwc3/drd.c -+++ b/drivers/usb/dwc3/drd.c -@@ -505,6 +505,7 @@ static int dwc3_setup_role_switch(struct dwc3 *dwc) - dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL; - mode = DWC3_GCTL_PRTCAP_DEVICE; - } -+ dwc3_set_mode(dwc, mode); - - dwc3_role_switch.fwnode = dev_fwnode(dwc->dev); - dwc3_role_switch.set = dwc3_usb_role_switch_set; -@@ -526,7 +527,6 @@ static int dwc3_setup_role_switch(struct dwc3 *dwc) - } - } - -- dwc3_set_mode(dwc, mode); - return 0; - } - #else -diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c -index 72c22851d7eef..93747ab2cf5b8 100644 ---- a/drivers/usb/dwc3/dwc3-qcom.c -+++ b/drivers/usb/dwc3/dwc3-qcom.c -@@ -550,7 +550,7 @@ static int dwc3_qcom_setup_irq(struct platform_device *pdev) - irq_set_status_flags(irq, IRQ_NOAUTOEN); - ret = devm_request_threaded_irq(qcom->dev, irq, NULL, - qcom_dwc3_resume_irq, -- IRQF_TRIGGER_HIGH | IRQF_ONESHOT, -+ IRQF_ONESHOT, - "qcom_dwc3 HS", qcom); - if (ret) { - dev_err(qcom->dev, "hs_phy_irq failed: %d\n", ret); -@@ -565,7 +565,7 @@ static int dwc3_qcom_setup_irq(struct platform_device *pdev) - irq_set_status_flags(irq, IRQ_NOAUTOEN); - ret = devm_request_threaded_irq(qcom->dev, irq, NULL, - qcom_dwc3_resume_irq, -- IRQF_TRIGGER_HIGH | IRQF_ONESHOT, -+ IRQF_ONESHOT, - "qcom_dwc3 DP_HS", qcom); - if (ret) { - dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret); -@@ -580,7 +580,7 @@ static int dwc3_qcom_setup_irq(struct platform_device *pdev) - irq_set_status_flags(irq, IRQ_NOAUTOEN); - ret = devm_request_threaded_irq(qcom->dev, irq, NULL, - qcom_dwc3_resume_irq, -- IRQF_TRIGGER_HIGH | IRQF_ONESHOT, -+ IRQF_ONESHOT, - "qcom_dwc3 DM_HS", qcom); - if (ret) { - dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret); -@@ -595,7 +595,7 @@ static int dwc3_qcom_setup_irq(struct platform_device *pdev) - irq_set_status_flags(irq, IRQ_NOAUTOEN); - ret = devm_request_threaded_irq(qcom->dev, irq, NULL, - qcom_dwc3_resume_irq, -- IRQF_TRIGGER_HIGH | IRQF_ONESHOT, -+ IRQF_ONESHOT, - "qcom_dwc3 SS", qcom); - if (ret) { - dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret); -@@ -759,6 +759,7 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev) - if (!qcom->dwc3) { - ret = -ENODEV; - dev_err(dev, "failed to get dwc3 platform device\n"); -+ of_platform_depopulate(dev); - } - - node_put: -@@ -767,9 +768,9 @@ node_put: - return ret; - } - --static struct platform_device * --dwc3_qcom_create_urs_usb_platdev(struct device *dev) -+static struct platform_device *dwc3_qcom_create_urs_usb_platdev(struct device *dev) - { -+ struct platform_device *urs_usb = NULL; - struct fwnode_handle *fwh; - struct acpi_device *adev; - char name[8]; -@@ -789,9 +790,26 @@ dwc3_qcom_create_urs_usb_platdev(struct device *dev) - - adev = to_acpi_device_node(fwh); - if (!adev) -- return NULL; -+ goto err_put_handle; -+ -+ urs_usb = acpi_create_platform_device(adev, NULL); -+ if (IS_ERR_OR_NULL(urs_usb)) -+ goto err_put_handle; -+ -+ return urs_usb; -+ -+err_put_handle: -+ fwnode_handle_put(fwh); -+ -+ return urs_usb; -+} - -- return acpi_create_platform_device(adev, NULL); -+static void dwc3_qcom_destroy_urs_usb_platdev(struct platform_device *urs_usb) -+{ -+ struct fwnode_handle *fwh = urs_usb->dev.fwnode; -+ -+ platform_device_unregister(urs_usb); -+ fwnode_handle_put(fwh); - } - - static int dwc3_qcom_probe(struct platform_device *pdev) -@@ -876,13 +894,13 @@ static int dwc3_qcom_probe(struct platform_device *pdev) - qcom->qscratch_base = devm_ioremap_resource(dev, parent_res); - if (IS_ERR(qcom->qscratch_base)) { - ret = PTR_ERR(qcom->qscratch_base); -- goto clk_disable; -+ goto free_urs; - } - - ret = dwc3_qcom_setup_irq(pdev); - if (ret) { - dev_err(dev, "failed to setup IRQs, err=%d\n", ret); -- goto clk_disable; -+ goto free_urs; - } - - /* -@@ -901,7 +919,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev) - - if (ret) { - dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret); -- goto depopulate; -+ goto free_urs; - } - - ret = dwc3_qcom_interconnect_init(qcom); -@@ -933,10 +951,16 @@ static int dwc3_qcom_probe(struct platform_device *pdev) - interconnect_exit: - dwc3_qcom_interconnect_exit(qcom); - depopulate: -- if (np) -+ if (np) { - of_platform_depopulate(&pdev->dev); -- else -- platform_device_put(pdev); -+ } else { -+ device_remove_software_node(&qcom->dwc3->dev); -+ platform_device_del(qcom->dwc3); -+ } -+ platform_device_put(qcom->dwc3); -+free_urs: -+ if (qcom->urs_usb) -+ dwc3_qcom_destroy_urs_usb_platdev(qcom->urs_usb); - clk_disable: - for (i = qcom->num_clocks - 1; i >= 0; i--) { - clk_disable_unprepare(qcom->clks[i]); -@@ -955,11 +979,16 @@ static int dwc3_qcom_remove(struct platform_device *pdev) - struct device *dev = &pdev->dev; - int i; - -- device_remove_software_node(&qcom->dwc3->dev); -- if (np) -+ if (np) { - of_platform_depopulate(&pdev->dev); -- else -- platform_device_put(pdev); -+ } else { -+ device_remove_software_node(&qcom->dwc3->dev); -+ platform_device_del(qcom->dwc3); -+ } -+ platform_device_put(qcom->dwc3); -+ -+ if (qcom->urs_usb) -+ dwc3_qcom_destroy_urs_usb_platdev(qcom->urs_usb); - - for (i = qcom->num_clocks - 1; i >= 0; i--) { - clk_disable_unprepare(qcom->clks[i]); -diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c -index b9dd714a3ae69..7f2aa72d52e65 100644 ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -203,8 +203,8 @@ static void option_instat_callback(struct urb *urb); - #define DELL_PRODUCT_5829E_ESIM 0x81e4 - #define DELL_PRODUCT_5829E 0x81e6 - --#define DELL_PRODUCT_FM101R 0x8213 --#define DELL_PRODUCT_FM101R_ESIM 0x8215 -+#define DELL_PRODUCT_FM101R_ESIM 0x8213 -+#define DELL_PRODUCT_FM101R 0x8215 - - #define KYOCERA_VENDOR_ID 0x0c88 - #define KYOCERA_PRODUCT_KPC650 0x17da -@@ -609,6 +609,8 @@ static void option_instat_callback(struct urb *urb); - #define UNISOC_VENDOR_ID 0x1782 - /* TOZED LT70-C based on UNISOC SL8563 uses UNISOC's vendor ID */ - #define TOZED_PRODUCT_LT70C 0x4055 -+/* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */ -+#define LUAT_PRODUCT_AIR720U 0x4e00 - - /* Device flags */ - -@@ -1546,7 +1548,8 @@ static const struct usb_device_id option_ids[] = { - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), - .driver_info = RSVD(4) }, -- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff), -+ .driver_info = RSVD(4) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ - .driver_info = RSVD(4) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) }, -@@ -2249,6 +2252,7 @@ static const struct usb_device_id option_ids[] = { - .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, - { USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */ - { USB_DEVICE_INTERFACE_CLASS(0x1782, 0x4d11, 0xff) }, /* Fibocom L610 (ECM/RNDIS mode) */ -+ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x0001, 0xff, 0xff, 0xff) }, /* Fibocom L716-EU (ECM/RNDIS mode) */ - { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ - .driver_info = RSVD(4) | RSVD(5) }, - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ -@@ -2271,6 +2275,7 @@ static const struct usb_device_id option_ids[] = { - { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) }, - { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, - { } /* Terminating entry */ - }; - MODULE_DEVICE_TABLE(usb, option_ids); -diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c -index 5e9d0c695fdb7..bf615dc8085e9 100644 ---- a/drivers/usb/typec/tcpm/tcpm.c -+++ b/drivers/usb/typec/tcpm/tcpm.c -@@ -5426,6 +5426,15 @@ static void _tcpm_pd_hard_reset(struct tcpm_port *port) - if (port->bist_request == BDO_MODE_TESTDATA && port->tcpc->set_bist_data) - port->tcpc->set_bist_data(port->tcpc, false); - -+ switch (port->state) { -+ case ERROR_RECOVERY: -+ case PORT_RESET: -+ case PORT_RESET_WAIT_OFF: -+ return; -+ default: -+ break; -+ } -+ - if (port->ams != NONE_AMS) - port->ams = NONE_AMS; - if (port->hard_reset_count < PD_N_HARD_RESET_COUNT) -diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c -index 67aa74d201627..7290f2b402e2a 100644 ---- a/drivers/xen/swiotlb-xen.c -+++ b/drivers/xen/swiotlb-xen.c -@@ -405,4 +405,5 @@ const struct dma_map_ops xen_swiotlb_dma_ops = { - .get_sgtable = dma_common_get_sgtable, - .alloc_pages = dma_common_alloc_pages, - .free_pages = dma_common_free_pages, -+ .max_mapping_size = swiotlb_max_mapping_size, - }; -diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c -index d7d9402ff7182..91e804c70dd0a 100644 ---- a/fs/afs/dynroot.c -+++ b/fs/afs/dynroot.c -@@ -132,8 +132,8 @@ static int afs_probe_cell_name(struct dentry *dentry) - - ret = dns_query(net->net, "afsdb", name, len, "srv=1", - NULL, NULL, false); -- if (ret == -ENODATA) -- ret = -EDESTADDRREQ; -+ if (ret == -ENODATA || ret == -ENOKEY) -+ ret = -ENOENT; - return ret; - } - -diff --git a/fs/afs/internal.h b/fs/afs/internal.h -index 9ba7b68375c9f..c2d70fc1698c0 100644 ---- a/fs/afs/internal.h -+++ b/fs/afs/internal.h -@@ -552,6 +552,7 @@ struct afs_server_entry { - }; - - struct afs_server_list { -+ struct rcu_head rcu; - afs_volid_t vids[AFS_MAXTYPES]; /* Volume IDs */ - refcount_t usage; - unsigned char nr_servers; -diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c -index ed9056703505f..b59896b1de0af 100644 ---- a/fs/afs/server_list.c -+++ b/fs/afs/server_list.c -@@ -17,7 +17,7 @@ void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist) - for (i = 0; i < slist->nr_servers; i++) - afs_unuse_server(net, slist->servers[i].server, - afs_server_trace_put_slist); -- kfree(slist); -+ kfree_rcu(slist, rcu); - } - } - -diff --git a/fs/afs/super.c b/fs/afs/super.c -index 95d713074dc81..e95fb4cb4fcd2 100644 ---- a/fs/afs/super.c -+++ b/fs/afs/super.c -@@ -407,6 +407,8 @@ static int afs_validate_fc(struct fs_context *fc) - return PTR_ERR(volume); - - ctx->volume = volume; -+ if (volume->type != AFSVL_RWVOL) -+ ctx->flock_mode = afs_flock_mode_local; - } - - return 0; -diff --git a/fs/afs/vl_rotate.c b/fs/afs/vl_rotate.c -index 488e58490b16e..eb415ce563600 100644 ---- a/fs/afs/vl_rotate.c -+++ b/fs/afs/vl_rotate.c -@@ -58,6 +58,12 @@ static bool afs_start_vl_iteration(struct afs_vl_cursor *vc) - } - - /* Status load is ordered after lookup counter load */ -+ if (cell->dns_status == DNS_LOOKUP_GOT_NOT_FOUND) { -+ pr_warn("No record of cell %s\n", cell->name); -+ vc->error = -ENOENT; -+ return false; -+ } -+ - if (cell->dns_source == DNS_RECORD_UNAVAILABLE) { - vc->error = -EDESTADDRREQ; - return false; -@@ -285,6 +291,7 @@ failed: - */ - static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc) - { -+ struct afs_cell *cell = vc->cell; - static int count; - int i; - -@@ -294,6 +301,9 @@ static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc) - - rcu_read_lock(); - pr_notice("EDESTADDR occurred\n"); -+ pr_notice("CELL: %s err=%d\n", cell->name, cell->error); -+ pr_notice("DNS: src=%u st=%u lc=%x\n", -+ cell->dns_source, cell->dns_status, cell->dns_lookup_count); - pr_notice("VC: ut=%lx ix=%u ni=%hu fl=%hx err=%hd\n", - vc->untried, vc->index, vc->nr_iterations, vc->flags, vc->error); - -diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c -index b57e497679ef9..470d29fb407a5 100644 ---- a/fs/ext4/extents_status.c -+++ b/fs/ext4/extents_status.c -@@ -144,14 +144,17 @@ - static struct kmem_cache *ext4_es_cachep; - static struct kmem_cache *ext4_pending_cachep; - --static int __es_insert_extent(struct inode *inode, struct extent_status *newes); -+static int __es_insert_extent(struct inode *inode, struct extent_status *newes, -+ struct extent_status *prealloc); - static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, -- ext4_lblk_t end, int *reserved); -+ ext4_lblk_t end, int *reserved, -+ struct extent_status *prealloc); - static int es_reclaim_extents(struct ext4_inode_info *ei, int *nr_to_scan); - static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, - struct ext4_inode_info *locked_ei); --static void __revise_pending(struct inode *inode, ext4_lblk_t lblk, -- ext4_lblk_t len); -+static int __revise_pending(struct inode *inode, ext4_lblk_t lblk, -+ ext4_lblk_t len, -+ struct pending_reservation **prealloc); - - int __init ext4_init_es(void) - { -@@ -448,22 +451,49 @@ static void ext4_es_list_del(struct inode *inode) - spin_unlock(&sbi->s_es_lock); - } - --static struct extent_status * --ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len, -- ext4_fsblk_t pblk) -+static inline struct pending_reservation *__alloc_pending(bool nofail) -+{ -+ if (!nofail) -+ return kmem_cache_alloc(ext4_pending_cachep, GFP_ATOMIC); -+ -+ return kmem_cache_zalloc(ext4_pending_cachep, GFP_KERNEL | __GFP_NOFAIL); -+} -+ -+static inline void __free_pending(struct pending_reservation *pr) -+{ -+ kmem_cache_free(ext4_pending_cachep, pr); -+} -+ -+/* -+ * Returns true if we cannot fail to allocate memory for this extent_status -+ * entry and cannot reclaim it until its status changes. -+ */ -+static inline bool ext4_es_must_keep(struct extent_status *es) -+{ -+ /* fiemap, bigalloc, and seek_data/hole need to use it. */ -+ if (ext4_es_is_delayed(es)) -+ return true; -+ -+ return false; -+} -+ -+static inline struct extent_status *__es_alloc_extent(bool nofail) -+{ -+ if (!nofail) -+ return kmem_cache_alloc(ext4_es_cachep, GFP_ATOMIC); -+ -+ return kmem_cache_zalloc(ext4_es_cachep, GFP_KERNEL | __GFP_NOFAIL); -+} -+ -+static void ext4_es_init_extent(struct inode *inode, struct extent_status *es, -+ ext4_lblk_t lblk, ext4_lblk_t len, ext4_fsblk_t pblk) - { -- struct extent_status *es; -- es = kmem_cache_alloc(ext4_es_cachep, GFP_ATOMIC); -- if (es == NULL) -- return NULL; - es->es_lblk = lblk; - es->es_len = len; - es->es_pblk = pblk; - -- /* -- * We don't count delayed extent because we never try to reclaim them -- */ -- if (!ext4_es_is_delayed(es)) { -+ /* We never try to reclaim a must kept extent, so we don't count it. */ -+ if (!ext4_es_must_keep(es)) { - if (!EXT4_I(inode)->i_es_shk_nr++) - ext4_es_list_add(inode); - percpu_counter_inc(&EXT4_SB(inode->i_sb)-> -@@ -472,8 +502,11 @@ ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len, - - EXT4_I(inode)->i_es_all_nr++; - percpu_counter_inc(&EXT4_SB(inode->i_sb)->s_es_stats.es_stats_all_cnt); -+} - -- return es; -+static inline void __es_free_extent(struct extent_status *es) -+{ -+ kmem_cache_free(ext4_es_cachep, es); - } - - static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) -@@ -481,8 +514,8 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) - EXT4_I(inode)->i_es_all_nr--; - percpu_counter_dec(&EXT4_SB(inode->i_sb)->s_es_stats.es_stats_all_cnt); - -- /* Decrease the shrink counter when this es is not delayed */ -- if (!ext4_es_is_delayed(es)) { -+ /* Decrease the shrink counter when we can reclaim the extent. */ -+ if (!ext4_es_must_keep(es)) { - BUG_ON(EXT4_I(inode)->i_es_shk_nr == 0); - if (!--EXT4_I(inode)->i_es_shk_nr) - ext4_es_list_del(inode); -@@ -490,7 +523,7 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) - s_es_stats.es_stats_shk_cnt); - } - -- kmem_cache_free(ext4_es_cachep, es); -+ __es_free_extent(es); - } - - /* -@@ -751,7 +784,8 @@ static inline void ext4_es_insert_extent_check(struct inode *inode, - } - #endif - --static int __es_insert_extent(struct inode *inode, struct extent_status *newes) -+static int __es_insert_extent(struct inode *inode, struct extent_status *newes, -+ struct extent_status *prealloc) - { - struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree; - struct rb_node **p = &tree->root.rb_node; -@@ -791,10 +825,15 @@ static int __es_insert_extent(struct inode *inode, struct extent_status *newes) - } - } - -- es = ext4_es_alloc_extent(inode, newes->es_lblk, newes->es_len, -- newes->es_pblk); -+ if (prealloc) -+ es = prealloc; -+ else -+ es = __es_alloc_extent(false); - if (!es) - return -ENOMEM; -+ ext4_es_init_extent(inode, es, newes->es_lblk, newes->es_len, -+ newes->es_pblk); -+ - rb_link_node(&es->rb_node, parent, p); - rb_insert_color(&es->rb_node, &tree->root); - -@@ -815,8 +854,12 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, - { - struct extent_status newes; - ext4_lblk_t end = lblk + len - 1; -- int err = 0; -+ int err1 = 0, err2 = 0, err3 = 0; - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); -+ struct extent_status *es1 = NULL; -+ struct extent_status *es2 = NULL; -+ struct pending_reservation *pr = NULL; -+ bool revise_pending = false; - - if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) - return 0; -@@ -844,29 +887,57 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, - - ext4_es_insert_extent_check(inode, &newes); - -+ revise_pending = sbi->s_cluster_ratio > 1 && -+ test_opt(inode->i_sb, DELALLOC) && -+ (status & (EXTENT_STATUS_WRITTEN | -+ EXTENT_STATUS_UNWRITTEN)); -+retry: -+ if (err1 && !es1) -+ es1 = __es_alloc_extent(true); -+ if ((err1 || err2) && !es2) -+ es2 = __es_alloc_extent(true); -+ if ((err1 || err2 || err3) && revise_pending && !pr) -+ pr = __alloc_pending(true); - write_lock(&EXT4_I(inode)->i_es_lock); -- err = __es_remove_extent(inode, lblk, end, NULL); -- if (err != 0) -+ -+ err1 = __es_remove_extent(inode, lblk, end, NULL, es1); -+ if (err1 != 0) - goto error; --retry: -- err = __es_insert_extent(inode, &newes); -- if (err == -ENOMEM && __es_shrink(EXT4_SB(inode->i_sb), -- 128, EXT4_I(inode))) -- goto retry; -- if (err == -ENOMEM && !ext4_es_is_delayed(&newes)) -- err = 0; -+ /* Free preallocated extent if it didn't get used. */ -+ if (es1) { -+ if (!es1->es_len) -+ __es_free_extent(es1); -+ es1 = NULL; -+ } - -- if (sbi->s_cluster_ratio > 1 && test_opt(inode->i_sb, DELALLOC) && -- (status & EXTENT_STATUS_WRITTEN || -- status & EXTENT_STATUS_UNWRITTEN)) -- __revise_pending(inode, lblk, len); -+ err2 = __es_insert_extent(inode, &newes, es2); -+ if (err2 == -ENOMEM && !ext4_es_must_keep(&newes)) -+ err2 = 0; -+ if (err2 != 0) -+ goto error; -+ /* Free preallocated extent if it didn't get used. */ -+ if (es2) { -+ if (!es2->es_len) -+ __es_free_extent(es2); -+ es2 = NULL; -+ } - -+ if (revise_pending) { -+ err3 = __revise_pending(inode, lblk, len, &pr); -+ if (err3 != 0) -+ goto error; -+ if (pr) { -+ __free_pending(pr); -+ pr = NULL; -+ } -+ } - error: - write_unlock(&EXT4_I(inode)->i_es_lock); -+ if (err1 || err2 || err3) -+ goto retry; - - ext4_es_print_tree(inode); -- -- return err; -+ return 0; - } - - /* -@@ -899,7 +970,7 @@ void ext4_es_cache_extent(struct inode *inode, ext4_lblk_t lblk, - - es = __es_tree_search(&EXT4_I(inode)->i_es_tree.root, lblk); - if (!es || es->es_lblk > end) -- __es_insert_extent(inode, &newes); -+ __es_insert_extent(inode, &newes, NULL); - write_unlock(&EXT4_I(inode)->i_es_lock); - } - -@@ -1270,7 +1341,7 @@ static unsigned int get_rsvd(struct inode *inode, ext4_lblk_t end, - rc->ndelonly--; - node = rb_next(&pr->rb_node); - rb_erase(&pr->rb_node, &tree->root); -- kmem_cache_free(ext4_pending_cachep, pr); -+ __free_pending(pr); - if (!node) - break; - pr = rb_entry(node, struct pending_reservation, -@@ -1289,6 +1360,7 @@ static unsigned int get_rsvd(struct inode *inode, ext4_lblk_t end, - * @lblk - first block in range - * @end - last block in range - * @reserved - number of cluster reservations released -+ * @prealloc - pre-allocated es to avoid memory allocation failures - * - * If @reserved is not NULL and delayed allocation is enabled, counts - * block/cluster reservations freed by removing range and if bigalloc -@@ -1296,7 +1368,8 @@ static unsigned int get_rsvd(struct inode *inode, ext4_lblk_t end, - * error code on failure. - */ - static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, -- ext4_lblk_t end, int *reserved) -+ ext4_lblk_t end, int *reserved, -+ struct extent_status *prealloc) - { - struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree; - struct rb_node *node; -@@ -1304,14 +1377,12 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, - struct extent_status orig_es; - ext4_lblk_t len1, len2; - ext4_fsblk_t block; -- int err; -+ int err = 0; - bool count_reserved = true; - struct rsvd_count rc; - - if (reserved == NULL || !test_opt(inode->i_sb, DELALLOC)) - count_reserved = false; --retry: -- err = 0; - - es = __es_tree_search(&tree->root, lblk); - if (!es) -@@ -1345,14 +1416,13 @@ retry: - orig_es.es_len - len2; - ext4_es_store_pblock_status(&newes, block, - ext4_es_status(&orig_es)); -- err = __es_insert_extent(inode, &newes); -+ err = __es_insert_extent(inode, &newes, prealloc); - if (err) { -+ if (!ext4_es_must_keep(&newes)) -+ return 0; -+ - es->es_lblk = orig_es.es_lblk; - es->es_len = orig_es.es_len; -- if ((err == -ENOMEM) && -- __es_shrink(EXT4_SB(inode->i_sb), -- 128, EXT4_I(inode))) -- goto retry; - goto out; - } - } else { -@@ -1432,6 +1502,7 @@ int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, - ext4_lblk_t end; - int err = 0; - int reserved = 0; -+ struct extent_status *es = NULL; - - if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) - return 0; -@@ -1446,17 +1517,29 @@ int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, - end = lblk + len - 1; - BUG_ON(end < lblk); - -+retry: -+ if (err && !es) -+ es = __es_alloc_extent(true); - /* - * ext4_clear_inode() depends on us taking i_es_lock unconditionally - * so that we are sure __es_shrink() is done with the inode before it - * is reclaimed. - */ - write_lock(&EXT4_I(inode)->i_es_lock); -- err = __es_remove_extent(inode, lblk, end, &reserved); -+ err = __es_remove_extent(inode, lblk, end, &reserved, es); -+ /* Free preallocated extent if it didn't get used. */ -+ if (es) { -+ if (!es->es_len) -+ __es_free_extent(es); -+ es = NULL; -+ } - write_unlock(&EXT4_I(inode)->i_es_lock); -+ if (err) -+ goto retry; -+ - ext4_es_print_tree(inode); - ext4_da_release_space(inode, reserved); -- return err; -+ return 0; - } - - static int __es_shrink(struct ext4_sb_info *sbi, int nr_to_scan, -@@ -1704,11 +1787,8 @@ static int es_do_reclaim_extents(struct ext4_inode_info *ei, ext4_lblk_t end, - - (*nr_to_scan)--; - node = rb_next(&es->rb_node); -- /* -- * We can't reclaim delayed extent from status tree because -- * fiemap, bigallic, and seek_data/hole need to use it. -- */ -- if (ext4_es_is_delayed(es)) -+ -+ if (ext4_es_must_keep(es)) - goto next; - if (ext4_es_is_referenced(es)) { - ext4_es_clear_referenced(es); -@@ -1772,7 +1852,7 @@ void ext4_clear_inode_es(struct inode *inode) - while (node) { - es = rb_entry(node, struct extent_status, rb_node); - node = rb_next(node); -- if (!ext4_es_is_delayed(es)) { -+ if (!ext4_es_must_keep(es)) { - rb_erase(&es->rb_node, &tree->root); - ext4_es_free_extent(inode, es); - } -@@ -1859,11 +1939,13 @@ static struct pending_reservation *__get_pending(struct inode *inode, - * - * @inode - file containing the cluster - * @lblk - logical block in the cluster to be added -+ * @prealloc - preallocated pending entry - * - * Returns 0 on successful insertion and -ENOMEM on failure. If the - * pending reservation is already in the set, returns successfully. - */ --static int __insert_pending(struct inode *inode, ext4_lblk_t lblk) -+static int __insert_pending(struct inode *inode, ext4_lblk_t lblk, -+ struct pending_reservation **prealloc) - { - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - struct ext4_pending_tree *tree = &EXT4_I(inode)->i_pending_tree; -@@ -1889,10 +1971,15 @@ static int __insert_pending(struct inode *inode, ext4_lblk_t lblk) - } - } - -- pr = kmem_cache_alloc(ext4_pending_cachep, GFP_ATOMIC); -- if (pr == NULL) { -- ret = -ENOMEM; -- goto out; -+ if (likely(*prealloc == NULL)) { -+ pr = __alloc_pending(false); -+ if (!pr) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } else { -+ pr = *prealloc; -+ *prealloc = NULL; - } - pr->lclu = lclu; - -@@ -1922,7 +2009,7 @@ static void __remove_pending(struct inode *inode, ext4_lblk_t lblk) - if (pr != NULL) { - tree = &EXT4_I(inode)->i_pending_tree; - rb_erase(&pr->rb_node, &tree->root); -- kmem_cache_free(ext4_pending_cachep, pr); -+ __free_pending(pr); - } - } - -@@ -1983,7 +2070,10 @@ int ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk, - bool allocated) - { - struct extent_status newes; -- int err = 0; -+ int err1 = 0, err2 = 0, err3 = 0; -+ struct extent_status *es1 = NULL; -+ struct extent_status *es2 = NULL; -+ struct pending_reservation *pr = NULL; - - if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY) - return 0; -@@ -1998,29 +2088,52 @@ int ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk, - - ext4_es_insert_extent_check(inode, &newes); - -+retry: -+ if (err1 && !es1) -+ es1 = __es_alloc_extent(true); -+ if ((err1 || err2) && !es2) -+ es2 = __es_alloc_extent(true); -+ if ((err1 || err2 || err3) && allocated && !pr) -+ pr = __alloc_pending(true); - write_lock(&EXT4_I(inode)->i_es_lock); - -- err = __es_remove_extent(inode, lblk, lblk, NULL); -- if (err != 0) -- goto error; --retry: -- err = __es_insert_extent(inode, &newes); -- if (err == -ENOMEM && __es_shrink(EXT4_SB(inode->i_sb), -- 128, EXT4_I(inode))) -- goto retry; -- if (err != 0) -+ err1 = __es_remove_extent(inode, lblk, lblk, NULL, es1); -+ if (err1 != 0) - goto error; -+ /* Free preallocated extent if it didn't get used. */ -+ if (es1) { -+ if (!es1->es_len) -+ __es_free_extent(es1); -+ es1 = NULL; -+ } - -- if (allocated) -- __insert_pending(inode, lblk); -+ err2 = __es_insert_extent(inode, &newes, es2); -+ if (err2 != 0) -+ goto error; -+ /* Free preallocated extent if it didn't get used. */ -+ if (es2) { -+ if (!es2->es_len) -+ __es_free_extent(es2); -+ es2 = NULL; -+ } - -+ if (allocated) { -+ err3 = __insert_pending(inode, lblk, &pr); -+ if (err3 != 0) -+ goto error; -+ if (pr) { -+ __free_pending(pr); -+ pr = NULL; -+ } -+ } - error: - write_unlock(&EXT4_I(inode)->i_es_lock); -+ if (err1 || err2 || err3) -+ goto retry; - - ext4_es_print_tree(inode); - ext4_print_pending_tree(inode); -- -- return err; -+ return 0; - } - - /* -@@ -2121,21 +2234,24 @@ unsigned int ext4_es_delayed_clu(struct inode *inode, ext4_lblk_t lblk, - * @inode - file containing the range - * @lblk - logical block defining the start of range - * @len - length of range in blocks -+ * @prealloc - preallocated pending entry - * - * Used after a newly allocated extent is added to the extents status tree. - * Requires that the extents in the range have either written or unwritten - * status. Must be called while holding i_es_lock. - */ --static void __revise_pending(struct inode *inode, ext4_lblk_t lblk, -- ext4_lblk_t len) -+static int __revise_pending(struct inode *inode, ext4_lblk_t lblk, -+ ext4_lblk_t len, -+ struct pending_reservation **prealloc) - { - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - ext4_lblk_t end = lblk + len - 1; - ext4_lblk_t first, last; - bool f_del = false, l_del = false; -+ int ret = 0; - - if (len == 0) -- return; -+ return 0; - - /* - * Two cases - block range within single cluster and block range -@@ -2156,7 +2272,9 @@ static void __revise_pending(struct inode *inode, ext4_lblk_t lblk, - f_del = __es_scan_range(inode, &ext4_es_is_delonly, - first, lblk - 1); - if (f_del) { -- __insert_pending(inode, first); -+ ret = __insert_pending(inode, first, prealloc); -+ if (ret < 0) -+ goto out; - } else { - last = EXT4_LBLK_CMASK(sbi, end) + - sbi->s_cluster_ratio - 1; -@@ -2164,9 +2282,11 @@ static void __revise_pending(struct inode *inode, ext4_lblk_t lblk, - l_del = __es_scan_range(inode, - &ext4_es_is_delonly, - end + 1, last); -- if (l_del) -- __insert_pending(inode, last); -- else -+ if (l_del) { -+ ret = __insert_pending(inode, last, prealloc); -+ if (ret < 0) -+ goto out; -+ } else - __remove_pending(inode, last); - } - } else { -@@ -2174,18 +2294,24 @@ static void __revise_pending(struct inode *inode, ext4_lblk_t lblk, - if (first != lblk) - f_del = __es_scan_range(inode, &ext4_es_is_delonly, - first, lblk - 1); -- if (f_del) -- __insert_pending(inode, first); -- else -+ if (f_del) { -+ ret = __insert_pending(inode, first, prealloc); -+ if (ret < 0) -+ goto out; -+ } else - __remove_pending(inode, first); - - last = EXT4_LBLK_CMASK(sbi, end) + sbi->s_cluster_ratio - 1; - if (last != end) - l_del = __es_scan_range(inode, &ext4_es_is_delonly, - end + 1, last); -- if (l_del) -- __insert_pending(inode, last); -- else -+ if (l_del) { -+ ret = __insert_pending(inode, last, prealloc); -+ if (ret < 0) -+ goto out; -+ } else - __remove_pending(inode, last); - } -+out: -+ return ret; - } -diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h -index f21259ead64bb..3c07d587ae9e9 100644 ---- a/fs/nfsd/cache.h -+++ b/fs/nfsd/cache.h -@@ -82,7 +82,8 @@ int nfsd_drc_slab_create(void); - void nfsd_drc_slab_free(void); - int nfsd_reply_cache_init(struct nfsd_net *); - void nfsd_reply_cache_shutdown(struct nfsd_net *); --int nfsd_cache_lookup(struct svc_rqst *); -+int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, -+ unsigned int len); - void nfsd_cache_update(struct svc_rqst *, int, __be32 *); - int nfsd_reply_cache_stats_show(struct seq_file *m, void *v); - -diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c -index 3e64a3d50a1c5..f53335ae0ab22 100644 ---- a/fs/nfsd/nfscache.c -+++ b/fs/nfsd/nfscache.c -@@ -311,33 +311,53 @@ nfsd_reply_cache_scan(struct shrinker *shrink, struct shrink_control *sc) - - return prune_cache_entries(nn); - } --/* -- * Walk an xdr_buf and get a CRC for at most the first RC_CSUMLEN bytes -+ -+/** -+ * nfsd_cache_csum - Checksum incoming NFS Call arguments -+ * @buf: buffer containing a whole RPC Call message -+ * @start: starting byte of the NFS Call header -+ * @remaining: size of the NFS Call header, in bytes -+ * -+ * Compute a weak checksum of the leading bytes of an NFS procedure -+ * call header to help verify that a retransmitted Call matches an -+ * entry in the duplicate reply cache. -+ * -+ * To avoid assumptions about how the RPC message is laid out in -+ * @buf and what else it might contain (eg, a GSS MIC suffix), the -+ * caller passes us the exact location and length of the NFS Call -+ * header. -+ * -+ * Returns a 32-bit checksum value, as defined in RFC 793. - */ --static __wsum --nfsd_cache_csum(struct svc_rqst *rqstp) -+static __wsum nfsd_cache_csum(struct xdr_buf *buf, unsigned int start, -+ unsigned int remaining) - { -+ unsigned int base, len; -+ struct xdr_buf subbuf; -+ __wsum csum = 0; -+ void *p; - int idx; -- unsigned int base; -- __wsum csum; -- struct xdr_buf *buf = &rqstp->rq_arg; -- const unsigned char *p = buf->head[0].iov_base; -- size_t csum_len = min_t(size_t, buf->head[0].iov_len + buf->page_len, -- RC_CSUMLEN); -- size_t len = min(buf->head[0].iov_len, csum_len); -+ -+ if (remaining > RC_CSUMLEN) -+ remaining = RC_CSUMLEN; -+ if (xdr_buf_subsegment(buf, &subbuf, start, remaining)) -+ return csum; - - /* rq_arg.head first */ -- csum = csum_partial(p, len, 0); -- csum_len -= len; -+ if (subbuf.head[0].iov_len) { -+ len = min_t(unsigned int, subbuf.head[0].iov_len, remaining); -+ csum = csum_partial(subbuf.head[0].iov_base, len, csum); -+ remaining -= len; -+ } - - /* Continue into page array */ -- idx = buf->page_base / PAGE_SIZE; -- base = buf->page_base & ~PAGE_MASK; -- while (csum_len) { -- p = page_address(buf->pages[idx]) + base; -- len = min_t(size_t, PAGE_SIZE - base, csum_len); -+ idx = subbuf.page_base / PAGE_SIZE; -+ base = subbuf.page_base & ~PAGE_MASK; -+ while (remaining) { -+ p = page_address(subbuf.pages[idx]) + base; -+ len = min_t(unsigned int, PAGE_SIZE - base, remaining); - csum = csum_partial(p, len, csum); -- csum_len -= len; -+ remaining -= len; - base = 0; - ++idx; - } -@@ -408,6 +428,8 @@ out: - /** - * nfsd_cache_lookup - Find an entry in the duplicate reply cache - * @rqstp: Incoming Call to find -+ * @start: starting byte in @rqstp->rq_arg of the NFS Call header -+ * @len: size of the NFS Call header, in bytes - * - * Try to find an entry matching the current call in the cache. When none - * is found, we try to grab the oldest expired entry off the LRU list. If -@@ -420,7 +442,8 @@ out: - * %RC_REPLY: Reply from cache - * %RC_DROPIT: Do not process the request further - */ --int nfsd_cache_lookup(struct svc_rqst *rqstp) -+int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, -+ unsigned int len) - { - struct nfsd_net *nn; - struct svc_cacherep *rp, *found; -@@ -435,7 +458,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp) - goto out; - } - -- csum = nfsd_cache_csum(rqstp); -+ csum = nfsd_cache_csum(&rqstp->rq_arg, start, len); - - /* - * Since the common case is a cache miss followed by an insert, -diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c -index 6b20f285f3ca6..f6cc99af81925 100644 ---- a/fs/nfsd/nfssvc.c -+++ b/fs/nfsd/nfssvc.c -@@ -1027,6 +1027,8 @@ out: - int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) - { - const struct svc_procedure *proc = rqstp->rq_procinfo; -+ unsigned int start, len; -+ __be32 *nfs_reply; - - /* - * Give the xdr decoder a chance to change this if it wants -@@ -1035,10 +1037,18 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) - rqstp->rq_cachetype = proc->pc_cachetype; - - svcxdr_init_decode(rqstp); -+ -+ /* -+ * ->pc_decode advances the argument stream past the NFS -+ * Call header, so grab the header's starting location and -+ * size now for the call to nfsd_cache_lookup(). -+ */ -+ start = xdr_stream_pos(&rqstp->rq_arg_stream); -+ len = xdr_stream_remaining(&rqstp->rq_arg_stream); - if (!proc->pc_decode(rqstp, &rqstp->rq_arg_stream)) - goto out_decode_err; - -- switch (nfsd_cache_lookup(rqstp)) { -+ switch (nfsd_cache_lookup(rqstp, start, len)) { - case RC_DOIT: - break; - case RC_REPLY: -@@ -1053,6 +1063,7 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) - */ - svcxdr_init_encode(rqstp); - -+ nfs_reply = xdr_inline_decode(&rqstp->rq_res_stream, 0); - *statp = proc->pc_func(rqstp); - if (*statp == rpc_drop_reply || test_bit(RQ_DROPME, &rqstp->rq_flags)) - goto out_update_drop; -@@ -1060,7 +1071,7 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) - if (!proc->pc_encode(rqstp, &rqstp->rq_res_stream)) - goto out_encode_err; - -- nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1); -+ nfsd_cache_update(rqstp, rqstp->rq_cachetype, nfs_reply); - out_cached_reply: - return 1; - -diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c -index ed396b186c5a4..0acb455368f23 100644 ---- a/fs/smb/client/cifs_debug.c -+++ b/fs/smb/client/cifs_debug.c -@@ -220,6 +220,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) - struct cifs_ses *ses; - struct cifs_tcon *tcon; - struct cifs_server_iface *iface; -+ size_t iface_weight = 0, iface_min_speed = 0; -+ struct cifs_server_iface *last_iface = NULL; - int c, i, j; - - seq_puts(m, -@@ -457,13 +459,29 @@ skip_rdma: - - spin_lock(&ses->iface_lock); - if (ses->iface_count) -- seq_printf(m, "\n\n\tServer interfaces: %zu", -- ses->iface_count); -+ seq_printf(m, "\n\n\tServer interfaces: %zu" -+ "\tLast updated: %lu seconds ago", -+ ses->iface_count, -+ (jiffies - ses->iface_last_update) / HZ); -+ -+ last_iface = list_last_entry(&ses->iface_list, -+ struct cifs_server_iface, -+ iface_head); -+ iface_min_speed = last_iface->speed; -+ - j = 0; - list_for_each_entry(iface, &ses->iface_list, - iface_head) { - seq_printf(m, "\n\t%d)", ++j); - cifs_dump_iface(m, iface); -+ -+ iface_weight = iface->speed / iface_min_speed; -+ seq_printf(m, "\t\tWeight (cur,total): (%zu,%zu)" -+ "\n\t\tAllocated channels: %u\n", -+ iface->weight_fulfilled, -+ iface_weight, -+ iface->num_channels); -+ - if (is_ses_using_iface(ses, iface)) - seq_puts(m, "\t\t[CONNECTED]\n"); - } -diff --git a/fs/smb/client/cifs_ioctl.h b/fs/smb/client/cifs_ioctl.h -index d86d78d5bfdc1..26327442e383b 100644 ---- a/fs/smb/client/cifs_ioctl.h -+++ b/fs/smb/client/cifs_ioctl.h -@@ -26,6 +26,11 @@ struct smb_mnt_fs_info { - __u64 cifs_posix_caps; - } __packed; - -+struct smb_mnt_tcon_info { -+ __u32 tid; -+ __u64 session_id; -+} __packed; -+ - struct smb_snapshot_array { - __u32 number_of_snapshots; - __u32 number_of_snapshots_returned; -@@ -108,7 +113,8 @@ struct smb3_notify_info { - #define CIFS_IOC_NOTIFY _IOW(CIFS_IOCTL_MAGIC, 9, struct smb3_notify) - #define CIFS_DUMP_FULL_KEY _IOWR(CIFS_IOCTL_MAGIC, 10, struct smb3_full_key_debug_info) - #define CIFS_IOC_NOTIFY_INFO _IOWR(CIFS_IOCTL_MAGIC, 11, struct smb3_notify_info) --#define CIFS_IOC_SHUTDOWN _IOR ('X', 125, __u32) -+#define CIFS_IOC_GET_TCON_INFO _IOR(CIFS_IOCTL_MAGIC, 12, struct smb_mnt_tcon_info) -+#define CIFS_IOC_SHUTDOWN _IOR('X', 125, __u32) - - /* - * Flags for going down operation -diff --git a/fs/smb/client/cifsfs.h b/fs/smb/client/cifsfs.h -index b6c38896fb2db..a1d8791c4fcd2 100644 ---- a/fs/smb/client/cifsfs.h -+++ b/fs/smb/client/cifsfs.h -@@ -105,8 +105,8 @@ extern int cifs_lock(struct file *, int, struct file_lock *); - extern int cifs_fsync(struct file *, loff_t, loff_t, int); - extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int); - extern int cifs_flush(struct file *, fl_owner_t id); --extern int cifs_file_mmap(struct file * , struct vm_area_struct *); --extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *); -+extern int cifs_file_mmap(struct file *file, struct vm_area_struct *vma); -+extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma); - extern const struct file_operations cifs_dir_ops; - extern int cifs_dir_open(struct inode *inode, struct file *file); - extern int cifs_readdir(struct file *file, struct dir_context *ctx); -diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h -index 39602f39aea8f..2e814eadd6aef 100644 ---- a/fs/smb/client/cifsglob.h -+++ b/fs/smb/client/cifsglob.h -@@ -788,6 +788,7 @@ static inline unsigned int - in_flight(struct TCP_Server_Info *server) - { - unsigned int num; -+ - spin_lock(&server->req_lock); - num = server->in_flight; - spin_unlock(&server->req_lock); -@@ -798,6 +799,7 @@ static inline bool - has_credits(struct TCP_Server_Info *server, int *credits, int num_credits) - { - int num; -+ - spin_lock(&server->req_lock); - num = *credits; - spin_unlock(&server->req_lock); -@@ -954,6 +956,8 @@ struct cifs_server_iface { - struct list_head iface_head; - struct kref refcount; - size_t speed; -+ size_t weight_fulfilled; -+ unsigned int num_channels; - unsigned int rdma_capable : 1; - unsigned int rss_capable : 1; - unsigned int is_active : 1; /* unset if non existent */ -@@ -991,7 +995,7 @@ struct cifs_ses { - struct TCP_Server_Info *server; /* pointer to server info */ - int ses_count; /* reference counter */ - enum ses_status_enum ses_status; /* updates protected by cifs_tcp_ses_lock */ -- unsigned overrideSecFlg; /* if non-zero override global sec flags */ -+ unsigned int overrideSecFlg; /* if non-zero override global sec flags */ - char *serverOS; /* name of operating system underlying server */ - char *serverNOS; /* name of network operating system of server */ - char *serverDomain; /* security realm of server */ -@@ -1347,7 +1351,7 @@ struct cifsFileInfo { - __u32 pid; /* process id who opened file */ - struct cifs_fid fid; /* file id from remote */ - struct list_head rlist; /* reconnect list */ -- /* BB add lock scope info here if needed */ ; -+ /* BB add lock scope info here if needed */ - /* lock scope id (0 if none) */ - struct dentry *dentry; - struct tcon_link *tlink; -@@ -1735,6 +1739,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, - int number_of_items) - { - int i; -+ - if ((number_of_items == 0) || (param == NULL)) - return; - for (i = 0; i < number_of_items; i++) { -diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c -index 6ca1e00b3f76a..5b19918938346 100644 ---- a/fs/smb/client/connect.c -+++ b/fs/smb/client/connect.c -@@ -2070,6 +2070,12 @@ void cifs_put_smb_ses(struct cifs_ses *ses) - } - } - -+ /* we now account for primary channel in iface->refcount */ -+ if (ses->chans[0].iface) { -+ kref_put(&ses->chans[0].iface->refcount, release_iface); -+ ses->chans[0].server = NULL; -+ } -+ - sesInfoFree(ses); - cifs_put_tcp_session(server, 0); - } -diff --git a/fs/smb/client/ioctl.c b/fs/smb/client/ioctl.c -index 6419ec47c2a85..ae9905e2b9d4a 100644 ---- a/fs/smb/client/ioctl.c -+++ b/fs/smb/client/ioctl.c -@@ -117,6 +117,20 @@ out_drop_write: - return rc; - } - -+static long smb_mnt_get_tcon_info(struct cifs_tcon *tcon, void __user *arg) -+{ -+ int rc = 0; -+ struct smb_mnt_tcon_info tcon_inf; -+ -+ tcon_inf.tid = tcon->tid; -+ tcon_inf.session_id = tcon->ses->Suid; -+ -+ if (copy_to_user(arg, &tcon_inf, sizeof(struct smb_mnt_tcon_info))) -+ rc = -EFAULT; -+ -+ return rc; -+} -+ - static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon, - void __user *arg) - { -@@ -410,6 +424,17 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) - tcon = tlink_tcon(pSMBFile->tlink); - rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg); - break; -+ case CIFS_IOC_GET_TCON_INFO: -+ cifs_sb = CIFS_SB(inode->i_sb); -+ tlink = cifs_sb_tlink(cifs_sb); -+ if (IS_ERR(tlink)) { -+ rc = PTR_ERR(tlink); -+ break; -+ } -+ tcon = tlink_tcon(tlink); -+ rc = smb_mnt_get_tcon_info(tcon, (void __user *)arg); -+ cifs_put_tlink(tlink); -+ break; - case CIFS_ENUMERATE_SNAPSHOTS: - if (pSMBFile == NULL) - break; -diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c -index f0d164873500b..634035bcb9347 100644 ---- a/fs/smb/client/sess.c -+++ b/fs/smb/client/sess.c -@@ -164,7 +164,9 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) - int left; - int rc = 0; - int tries = 0; -+ size_t iface_weight = 0, iface_min_speed = 0; - struct cifs_server_iface *iface = NULL, *niface = NULL; -+ struct cifs_server_iface *last_iface = NULL; - - spin_lock(&ses->chan_lock); - -@@ -192,21 +194,11 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) - } - spin_unlock(&ses->chan_lock); - -- /* -- * Keep connecting to same, fastest, iface for all channels as -- * long as its RSS. Try next fastest one if not RSS or channel -- * creation fails. -- */ -- spin_lock(&ses->iface_lock); -- iface = list_first_entry(&ses->iface_list, struct cifs_server_iface, -- iface_head); -- spin_unlock(&ses->iface_lock); -- - while (left > 0) { - - tries++; - if (tries > 3*ses->chan_max) { -- cifs_dbg(FYI, "too many channel open attempts (%d channels left to open)\n", -+ cifs_dbg(VFS, "too many channel open attempts (%d channels left to open)\n", - left); - break; - } -@@ -214,17 +206,35 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) - spin_lock(&ses->iface_lock); - if (!ses->iface_count) { - spin_unlock(&ses->iface_lock); -+ cifs_dbg(VFS, "server %s does not advertise interfaces\n", -+ ses->server->hostname); - break; - } - -+ if (!iface) -+ iface = list_first_entry(&ses->iface_list, struct cifs_server_iface, -+ iface_head); -+ last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface, -+ iface_head); -+ iface_min_speed = last_iface->speed; -+ - list_for_each_entry_safe_from(iface, niface, &ses->iface_list, - iface_head) { -+ /* do not mix rdma and non-rdma interfaces */ -+ if (iface->rdma_capable != ses->server->rdma) -+ continue; -+ - /* skip ifaces that are unusable */ - if (!iface->is_active || - (is_ses_using_iface(ses, iface) && -- !iface->rss_capable)) { -+ !iface->rss_capable)) -+ continue; -+ -+ /* check if we already allocated enough channels */ -+ iface_weight = iface->speed / iface_min_speed; -+ -+ if (iface->weight_fulfilled >= iface_weight) - continue; -- } - - /* take ref before unlock */ - kref_get(&iface->refcount); -@@ -241,10 +251,21 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) - continue; - } - -- cifs_dbg(FYI, "successfully opened new channel on iface:%pIS\n", -+ iface->num_channels++; -+ iface->weight_fulfilled++; -+ cifs_dbg(VFS, "successfully opened new channel on iface:%pIS\n", - &iface->sockaddr); - break; - } -+ -+ /* reached end of list. reset weight_fulfilled and start over */ -+ if (list_entry_is_head(iface, &ses->iface_list, iface_head)) { -+ list_for_each_entry(iface, &ses->iface_list, iface_head) -+ iface->weight_fulfilled = 0; -+ spin_unlock(&ses->iface_lock); -+ iface = NULL; -+ continue; -+ } - spin_unlock(&ses->iface_lock); - - left--; -@@ -263,8 +284,11 @@ int - cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server) - { - unsigned int chan_index; -+ size_t iface_weight = 0, iface_min_speed = 0; - struct cifs_server_iface *iface = NULL; - struct cifs_server_iface *old_iface = NULL; -+ struct cifs_server_iface *last_iface = NULL; -+ struct sockaddr_storage ss; - int rc = 0; - - spin_lock(&ses->chan_lock); -@@ -283,14 +307,49 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server) - } - spin_unlock(&ses->chan_lock); - -+ spin_lock(&server->srv_lock); -+ ss = server->dstaddr; -+ spin_unlock(&server->srv_lock); -+ - spin_lock(&ses->iface_lock); -+ if (!ses->iface_count) { -+ spin_unlock(&ses->iface_lock); -+ cifs_dbg(VFS, "server %s does not advertise interfaces\n", ses->server->hostname); -+ return 0; -+ } -+ -+ last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface, -+ iface_head); -+ iface_min_speed = last_iface->speed; -+ - /* then look for a new one */ - list_for_each_entry(iface, &ses->iface_list, iface_head) { -+ if (!chan_index) { -+ /* if we're trying to get the updated iface for primary channel */ -+ if (!cifs_match_ipaddr((struct sockaddr *) &ss, -+ (struct sockaddr *) &iface->sockaddr)) -+ continue; -+ -+ kref_get(&iface->refcount); -+ break; -+ } -+ -+ /* do not mix rdma and non-rdma interfaces */ -+ if (iface->rdma_capable != server->rdma) -+ continue; -+ - if (!iface->is_active || - (is_ses_using_iface(ses, iface) && - !iface->rss_capable)) { - continue; - } -+ -+ /* check if we already allocated enough channels */ -+ iface_weight = iface->speed / iface_min_speed; -+ -+ if (iface->weight_fulfilled >= iface_weight) -+ continue; -+ - kref_get(&iface->refcount); - break; - } -@@ -301,16 +360,41 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server) - cifs_dbg(FYI, "unable to find a suitable iface\n"); - } - -+ if (!chan_index && !iface) { -+ cifs_dbg(FYI, "unable to get the interface matching: %pIS\n", -+ &ss); -+ spin_unlock(&ses->iface_lock); -+ return 0; -+ } -+ - /* now drop the ref to the current iface */ - if (old_iface && iface) { - cifs_dbg(FYI, "replacing iface: %pIS with %pIS\n", - &old_iface->sockaddr, - &iface->sockaddr); -+ -+ old_iface->num_channels--; -+ if (old_iface->weight_fulfilled) -+ old_iface->weight_fulfilled--; -+ iface->num_channels++; -+ iface->weight_fulfilled++; -+ - kref_put(&old_iface->refcount, release_iface); - } else if (old_iface) { - cifs_dbg(FYI, "releasing ref to iface: %pIS\n", - &old_iface->sockaddr); -+ -+ old_iface->num_channels--; -+ if (old_iface->weight_fulfilled) -+ old_iface->weight_fulfilled--; -+ - kref_put(&old_iface->refcount, release_iface); -+ } else if (!chan_index) { -+ /* special case: update interface for primary channel */ -+ cifs_dbg(FYI, "referencing primary channel iface: %pIS\n", -+ &iface->sockaddr); -+ iface->num_channels++; -+ iface->weight_fulfilled++; - } else { - WARN_ON(!iface); - cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr); -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index 2c1898803279a..4cc56e4695fbc 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -752,6 +752,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_ - unsigned int ret_data_len = 0; - struct network_interface_info_ioctl_rsp *out_buf = NULL; - struct cifs_ses *ses = tcon->ses; -+ struct TCP_Server_Info *pserver; - - /* do not query too frequently */ - if (ses->iface_last_update && -@@ -776,6 +777,11 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_ - if (rc) - goto out; - -+ /* check if iface is still active */ -+ pserver = ses->chans[0].server; -+ if (pserver && !cifs_chan_is_iface_active(ses, pserver)) -+ cifs_chan_update_iface(ses, pserver); -+ - out: - kfree(out_buf); - return rc; -diff --git a/include/linux/hid.h b/include/linux/hid.h -index 58f5ab29c11a7..b688069b17944 100644 ---- a/include/linux/hid.h -+++ b/include/linux/hid.h -@@ -653,10 +653,13 @@ struct hid_device { /* device report descriptor */ - struct list_head debug_list; - spinlock_t debug_list_lock; - wait_queue_head_t debug_wait; -+ struct kref ref; - - unsigned int id; /* system unique id */ - }; - -+void hiddev_free(struct kref *ref); -+ - #define to_hid_device(pdev) \ - container_of(pdev, struct hid_device, dev) - -diff --git a/io_uring/fs.c b/io_uring/fs.c -index 27676e0150049..abf4295db0caf 100644 ---- a/io_uring/fs.c -+++ b/io_uring/fs.c -@@ -254,7 +254,7 @@ int io_linkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) - newf = u64_to_user_ptr(READ_ONCE(sqe->addr2)); - lnk->flags = READ_ONCE(sqe->hardlink_flags); - -- lnk->oldpath = getname(oldf); -+ lnk->oldpath = getname_uflags(oldf, lnk->flags); - if (IS_ERR(lnk->oldpath)) - return PTR_ERR(lnk->oldpath); - -diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c -index cce95164204f3..7ada0339b3870 100644 ---- a/io_uring/rsrc.c -+++ b/io_uring/rsrc.c -@@ -1351,7 +1351,7 @@ int io_import_fixed(int ddir, struct iov_iter *iter, - */ - const struct bio_vec *bvec = imu->bvec; - -- if (offset <= bvec->bv_len) { -+ if (offset < bvec->bv_len) { - iov_iter_advance(iter, offset); - } else { - unsigned long seg_skip; -diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index 0224b0329d011..3b38303ed27b3 100644 ---- a/kernel/locking/lockdep.c -+++ b/kernel/locking/lockdep.c -@@ -3453,7 +3453,8 @@ static int alloc_chain_hlocks(int req) - size = chain_block_size(curr); - if (likely(size >= req)) { - del_chain_block(0, size, chain_block_next(curr)); -- add_chain_block(curr + req, size - req); -+ if (size > req) -+ add_chain_block(curr + req, size - req); - return curr; - } - } -diff --git a/mm/kfence/core.c b/mm/kfence/core.c -index a477b7fb8aa33..c597cfebb0e86 100644 ---- a/mm/kfence/core.c -+++ b/mm/kfence/core.c -@@ -828,6 +828,10 @@ void __init kfence_alloc_pool(void) - if (!kfence_sample_interval) - return; - -+ /* if the pool has already been initialized by arch, skip the below. */ -+ if (__kfence_pool) -+ return; -+ - __kfence_pool = memblock_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); - - if (!__kfence_pool) -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 9cbaae4f5ee71..474f391fab35d 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -780,7 +780,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow - goto reject_redirect; - } - -- n = __ipv4_neigh_lookup(rt->dst.dev, new_gw); -+ n = __ipv4_neigh_lookup(rt->dst.dev, (__force u32)new_gw); - if (!n) - n = neigh_create(&arp_tbl, &new_gw, rt->dst.dev); - if (!IS_ERR(n)) { -diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c -index d676119984c09..b6609527dff62 100644 ---- a/net/smc/af_smc.c -+++ b/net/smc/af_smc.c -@@ -585,8 +585,12 @@ static int smcr_clnt_conf_first_link(struct smc_sock *smc) - struct smc_llc_qentry *qentry; - int rc; - -- /* receive CONFIRM LINK request from server over RoCE fabric */ -- qentry = smc_llc_wait(link->lgr, NULL, SMC_LLC_WAIT_TIME, -+ /* Receive CONFIRM LINK request from server over RoCE fabric. -+ * Increasing the client's timeout by twice as much as the server's -+ * timeout by default can temporarily avoid decline messages of -+ * both sides crossing or colliding -+ */ -+ qentry = smc_llc_wait(link->lgr, NULL, 2 * SMC_LLC_WAIT_TIME, - SMC_LLC_CONFIRM_LINK); - if (!qentry) { - struct smc_clc_msg_decline dclc; diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.65-66.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.65-66.patch deleted file mode 100644 index eae065518fe7..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.65-66.patch +++ /dev/null @@ -1,4837 +0,0 @@ -diff --git a/Makefile b/Makefile -index 1646e334a647f..5d7e995d686c8 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 65 -+SUBLEVEL = 66 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c -index d12fdb9c05a89..eace3607fef41 100644 ---- a/arch/arm/xen/enlighten.c -+++ b/arch/arm/xen/enlighten.c -@@ -204,7 +204,7 @@ static void xen_power_off(void) - - static irqreturn_t xen_arm_callback(int irq, void *arg) - { -- xen_hvm_evtchn_do_upcall(); -+ xen_evtchn_do_upcall(); - return IRQ_HANDLED; - } - -diff --git a/arch/parisc/include/asm/alternative.h b/arch/parisc/include/asm/alternative.h -index 1ed45fd085d3b..1eb488f25b838 100644 ---- a/arch/parisc/include/asm/alternative.h -+++ b/arch/parisc/include/asm/alternative.h -@@ -34,7 +34,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, - - /* Alternative SMP implementation. */ - #define ALTERNATIVE(cond, replacement) "!0:" \ -- ".section .altinstructions, \"aw\" !" \ -+ ".section .altinstructions, \"a\" !" \ -+ ".align 4 !" \ - ".word (0b-4-.) !" \ - ".hword 1, " __stringify(cond) " !" \ - ".word " __stringify(replacement) " !" \ -@@ -44,7 +45,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, - - /* to replace one single instructions by a new instruction */ - #define ALTERNATIVE(from, to, cond, replacement)\ -- .section .altinstructions, "aw" ! \ -+ .section .altinstructions, "a" ! \ -+ .align 4 ! \ - .word (from - .) ! \ - .hword (to - from)/4, cond ! \ - .word replacement ! \ -@@ -52,7 +54,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, - - /* to replace multiple instructions by new code */ - #define ALTERNATIVE_CODE(from, num_instructions, cond, new_instr_ptr)\ -- .section .altinstructions, "aw" ! \ -+ .section .altinstructions, "a" ! \ -+ .align 4 ! \ - .word (from - .) ! \ - .hword -num_instructions, cond ! \ - .word (new_instr_ptr - .) ! \ -diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h -index 75677b526b2bb..74d17d7e759da 100644 ---- a/arch/parisc/include/asm/assembly.h -+++ b/arch/parisc/include/asm/assembly.h -@@ -574,6 +574,7 @@ - */ - #define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \ - .section __ex_table,"aw" ! \ -+ .align 4 ! \ - .word (fault_addr - .), (except_addr - .) ! \ - .previous - -diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h -index 4b6d60b941247..b9cad0bb4461b 100644 ---- a/arch/parisc/include/asm/bug.h -+++ b/arch/parisc/include/asm/bug.h -@@ -28,13 +28,15 @@ - do { \ - asm volatile("\n" \ - "1:\t" PARISC_BUG_BREAK_ASM "\n" \ -- "\t.pushsection __bug_table,\"aw\"\n" \ -+ "\t.pushsection __bug_table,\"a\"\n" \ -+ "\t.align %4\n" \ - "2:\t" ASM_WORD_INSN "1b, %c0\n" \ -- "\t.short %c1, %c2\n" \ -- "\t.org 2b+%c3\n" \ -+ "\t.short %1, %2\n" \ -+ "\t.blockz %3-2*%4-2*2\n" \ - "\t.popsection" \ - : : "i" (__FILE__), "i" (__LINE__), \ -- "i" (0), "i" (sizeof(struct bug_entry)) ); \ -+ "i" (0), "i" (sizeof(struct bug_entry)), \ -+ "i" (sizeof(long)) ); \ - unreachable(); \ - } while(0) - -@@ -51,27 +53,31 @@ - do { \ - asm volatile("\n" \ - "1:\t" PARISC_BUG_BREAK_ASM "\n" \ -- "\t.pushsection __bug_table,\"aw\"\n" \ -+ "\t.pushsection __bug_table,\"a\"\n" \ -+ "\t.align %4\n" \ - "2:\t" ASM_WORD_INSN "1b, %c0\n" \ -- "\t.short %c1, %c2\n" \ -- "\t.org 2b+%c3\n" \ -+ "\t.short %1, %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(struct bug_entry)), \ -+ "i" (sizeof(long)) ); \ - } while(0) - #else - #define __WARN_FLAGS(flags) \ - do { \ - asm volatile("\n" \ - "1:\t" PARISC_BUG_BREAK_ASM "\n" \ -- "\t.pushsection __bug_table,\"aw\"\n" \ -+ "\t.pushsection __bug_table,\"a\"\n" \ -+ "\t.align %2\n" \ - "2:\t" ASM_WORD_INSN "1b\n" \ -- "\t.short %c0\n" \ -- "\t.org 2b+%c1\n" \ -+ "\t.short %0\n" \ -+ "\t.blockz %1-%2-2\n" \ - "\t.popsection" \ - : : "i" (BUGFLAG_WARNING|(flags)), \ -- "i" (sizeof(struct bug_entry)) ); \ -+ "i" (sizeof(struct bug_entry)), \ -+ "i" (sizeof(long)) ); \ - } while(0) - #endif - -diff --git a/arch/parisc/include/asm/jump_label.h b/arch/parisc/include/asm/jump_label.h -index af2a598bc0f81..94428798b6aa6 100644 ---- a/arch/parisc/include/asm/jump_label.h -+++ b/arch/parisc/include/asm/jump_label.h -@@ -15,10 +15,12 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran - asm_volatile_goto("1:\n\t" - "nop\n\t" - ".pushsection __jump_table, \"aw\"\n\t" -+ ".align %1\n\t" - ".word 1b - ., %l[l_yes] - .\n\t" - __stringify(ASM_ULONG_INSN) " %c0 - .\n\t" - ".popsection\n\t" -- : : "i" (&((char *)key)[branch]) : : l_yes); -+ : : "i" (&((char *)key)[branch]), "i" (sizeof(long)) -+ : : l_yes); - - return false; - l_yes: -@@ -30,10 +32,12 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool - asm_volatile_goto("1:\n\t" - "b,n %l[l_yes]\n\t" - ".pushsection __jump_table, \"aw\"\n\t" -+ ".align %1\n\t" - ".word 1b - ., %l[l_yes] - .\n\t" - __stringify(ASM_ULONG_INSN) " %c0 - .\n\t" - ".popsection\n\t" -- : : "i" (&((char *)key)[branch]) : : l_yes); -+ : : "i" (&((char *)key)[branch]), "i" (sizeof(long)) -+ : : l_yes); - - return false; - l_yes: -diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h -index 10a061d6899cd..883a9ddbb6770 100644 ---- a/arch/parisc/include/asm/ldcw.h -+++ b/arch/parisc/include/asm/ldcw.h -@@ -56,7 +56,7 @@ - }) - - #ifdef CONFIG_SMP --# define __lock_aligned __section(".data..lock_aligned") -+# define __lock_aligned __section(".data..lock_aligned") __aligned(16) - #endif - - #endif /* __PARISC_LDCW_H */ -diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h -index 2bf660eabe421..4165079898d9e 100644 ---- a/arch/parisc/include/asm/uaccess.h -+++ b/arch/parisc/include/asm/uaccess.h -@@ -41,6 +41,7 @@ struct exception_table_entry { - - #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ - ".section __ex_table,\"aw\"\n" \ -+ ".align 4\n" \ - ".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \ - ".previous\n" - -diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h -index 87245c584784e..8d94739d75c67 100644 ---- a/arch/parisc/include/uapi/asm/errno.h -+++ b/arch/parisc/include/uapi/asm/errno.h -@@ -75,7 +75,6 @@ - - /* We now return you to your regularly scheduled HPUX. */ - --#define ENOSYM 215 /* symbol does not exist in executable */ - #define ENOTSOCK 216 /* Socket operation on non-socket */ - #define EDESTADDRREQ 217 /* Destination address required */ - #define EMSGSIZE 218 /* Message too long */ -@@ -101,7 +100,6 @@ - #define ETIMEDOUT 238 /* Connection timed out */ - #define ECONNREFUSED 239 /* Connection refused */ - #define EREFUSED ECONNREFUSED /* for HP's NFS apparently */ --#define EREMOTERELEASE 240 /* Remote peer released connection */ - #define EHOSTDOWN 241 /* Host is down */ - #define EHOSTUNREACH 242 /* No route to host */ - -diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S -index 2769eb991f58d..ad3a3239ea74b 100644 ---- a/arch/parisc/kernel/vmlinux.lds.S -+++ b/arch/parisc/kernel/vmlinux.lds.S -@@ -131,6 +131,7 @@ SECTIONS - RO_DATA(8) - - /* unwind info */ -+ . = ALIGN(4); - .PARISC.unwind : { - __start___unwind = .; - *(.PARISC.unwind) -diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S -index f71f2bbd4de64..9854364e599c1 100644 ---- a/arch/powerpc/kernel/fpu.S -+++ b/arch/powerpc/kernel/fpu.S -@@ -23,6 +23,15 @@ - #include - - #ifdef CONFIG_VSX -+#define __REST_1FPVSR(n,c,base) \ -+BEGIN_FTR_SECTION \ -+ b 2f; \ -+END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ -+ REST_FPR(n,base); \ -+ b 3f; \ -+2: REST_VSR(n,c,base); \ -+3: -+ - #define __REST_32FPVSRS(n,c,base) \ - BEGIN_FTR_SECTION \ - b 2f; \ -@@ -41,9 +50,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ - 2: SAVE_32VSRS(n,c,base); \ - 3: - #else -+#define __REST_1FPVSR(n,b,base) REST_FPR(n, base) - #define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) - #define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) - #endif -+#define REST_1FPVSR(n,c,base) __REST_1FPVSR(n,__REG_##c,__REG_##base) - #define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) - #define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) - -@@ -67,6 +78,7 @@ _GLOBAL(store_fp_state) - SAVE_32FPVSRS(0, R4, R3) - mffs fr0 - stfd fr0,FPSTATE_FPSCR(r3) -+ REST_1FPVSR(0, R4, R3) - blr - EXPORT_SYMBOL(store_fp_state) - -@@ -138,4 +150,5 @@ _GLOBAL(save_fpu) - 2: SAVE_32FPVSRS(0, R4, R6) - mffs fr0 - stfd fr0,FPSTATE_FPSCR(r6) -+ REST_1FPVSR(0, R4, R6) - blr -diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c -index 67da147fe34dc..f2cbad5228811 100644 ---- a/arch/powerpc/kernel/process.c -+++ b/arch/powerpc/kernel/process.c -@@ -1163,11 +1163,11 @@ void kvmppc_save_user_regs(void) - - usermsr = current->thread.regs->msr; - -+ /* Caller has enabled FP/VEC/VSX/TM in MSR */ - if (usermsr & MSR_FP) -- save_fpu(current); -- -+ __giveup_fpu(current); - if (usermsr & MSR_VEC) -- save_altivec(current); -+ __giveup_altivec(current); - - #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - if (usermsr & MSR_TM) { -diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S -index 5cf64740edb82..99c1e70841ea2 100644 ---- a/arch/powerpc/kernel/vector.S -+++ b/arch/powerpc/kernel/vector.S -@@ -32,6 +32,7 @@ _GLOBAL(store_vr_state) - mfvscr v0 - li r4, VRSTATE_VSCR - stvx v0, r4, r3 -+ lvx v0, 0, r3 - blr - EXPORT_SYMBOL(store_vr_state) - -@@ -108,6 +109,7 @@ _GLOBAL(save_altivec) - mfvscr v0 - li r4,VRSTATE_VSCR - stvx v0,r4,r7 -+ lvx v0,0,r7 - blr - - #ifdef CONFIG_VSX -diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c -index 6c2826417b337..93c60c0c9d4a7 100644 ---- a/arch/x86/entry/common.c -+++ b/arch/x86/entry/common.c -@@ -294,7 +294,7 @@ static void __xen_pv_evtchn_do_upcall(struct pt_regs *regs) - - inc_irq_stat(irq_hv_callback_count); - -- xen_hvm_evtchn_do_upcall(); -+ xen_evtchn_do_upcall(); - - set_irq_regs(old_regs); - } -diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h -index 2c6698aa218b1..abc07d0045897 100644 ---- a/arch/x86/include/asm/kvm-x86-ops.h -+++ b/arch/x86/include/asm/kvm-x86-ops.h -@@ -106,6 +106,7 @@ KVM_X86_OP_OPTIONAL(vcpu_blocking) - KVM_X86_OP_OPTIONAL(vcpu_unblocking) - KVM_X86_OP_OPTIONAL(pi_update_irte) - KVM_X86_OP_OPTIONAL(pi_start_assignment) -+KVM_X86_OP_OPTIONAL(apicv_pre_state_restore) - KVM_X86_OP_OPTIONAL(apicv_post_state_restore) - KVM_X86_OP_OPTIONAL_RET0(dy_apicv_has_pending_interrupt) - KVM_X86_OP_OPTIONAL(set_hv_timer) -diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index c1dcaa3d2d6eb..dfcdcafe3a2cd 100644 ---- a/arch/x86/include/asm/kvm_host.h -+++ b/arch/x86/include/asm/kvm_host.h -@@ -1603,6 +1603,7 @@ struct kvm_x86_ops { - int (*pi_update_irte)(struct kvm *kvm, unsigned int host_irq, - uint32_t guest_irq, bool set); - void (*pi_start_assignment)(struct kvm *kvm); -+ void (*apicv_pre_state_restore)(struct kvm_vcpu *vcpu); - void (*apicv_post_state_restore)(struct kvm_vcpu *vcpu); - bool (*dy_apicv_has_pending_interrupt)(struct kvm_vcpu *vcpu); - -diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c -index 7517eb05bdc1a..ab348aec86632 100644 ---- a/arch/x86/kernel/apic/msi.c -+++ b/arch/x86/kernel/apic/msi.c -@@ -55,14 +55,14 @@ msi_set_affinity(struct irq_data *irqd, const struct cpumask *mask, bool force) - * caused by the non-atomic update of the address/data pair. - * - * Direct update is possible when: -- * - The MSI is maskable (remapped MSI does not use this code path)). -- * The quirk bit is not set in this case. -+ * - The MSI is maskable (remapped MSI does not use this code path). -+ * The reservation mode bit is set in this case. - * - The new vector is the same as the old vector - * - The old vector is MANAGED_IRQ_SHUTDOWN_VECTOR (interrupt starts up) - * - The interrupt is not yet started up - * - The new destination CPU is the same as the old destination CPU - */ -- if (!irqd_msi_nomask_quirk(irqd) || -+ if (!irqd_can_reserve(irqd) || - cfg->vector == old_cfg.vector || - old_cfg.vector == MANAGED_IRQ_SHUTDOWN_VECTOR || - !irqd_is_started(irqd) || -@@ -202,8 +202,6 @@ struct irq_domain * __init native_create_pci_msi_domain(void) - if (!d) { - irq_domain_free_fwnode(fn); - pr_warn("Failed to initialize PCI-MSI irqdomain.\n"); -- } else { -- d->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK; - } - return d; - } -diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c -index 4dba0a84ba2f3..edcf45e312b99 100644 ---- a/arch/x86/kvm/lapic.c -+++ b/arch/x86/kvm/lapic.c -@@ -2446,6 +2446,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) - u64 msr_val; - int i; - -+ static_call_cond(kvm_x86_apicv_pre_state_restore)(vcpu); -+ - if (!init_event) { - msr_val = APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE; - if (kvm_vcpu_is_reset_bsp(vcpu)) -@@ -2757,6 +2759,8 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s) - struct kvm_lapic *apic = vcpu->arch.apic; - int r; - -+ static_call_cond(kvm_x86_apicv_pre_state_restore)(vcpu); -+ - kvm_lapic_set_base(vcpu, vcpu->arch.apic_base); - /* set SPIV separately to get count of SW disabled APICs right */ - apic_set_spiv(apic, *((u32 *)(s->regs + APIC_SPIV))); -diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c -index 31a10d774df6d..98d732b9418f1 100644 ---- a/arch/x86/kvm/vmx/vmx.c -+++ b/arch/x86/kvm/vmx/vmx.c -@@ -6799,7 +6799,7 @@ static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) - vmcs_write64(EOI_EXIT_BITMAP3, eoi_exit_bitmap[3]); - } - --static void vmx_apicv_post_state_restore(struct kvm_vcpu *vcpu) -+static void vmx_apicv_pre_state_restore(struct kvm_vcpu *vcpu) - { - struct vcpu_vmx *vmx = to_vmx(vcpu); - -@@ -8172,7 +8172,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { - .set_apic_access_page_addr = vmx_set_apic_access_page_addr, - .refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl, - .load_eoi_exitmap = vmx_load_eoi_exitmap, -- .apicv_post_state_restore = vmx_apicv_post_state_restore, -+ .apicv_pre_state_restore = vmx_apicv_pre_state_restore, - .check_apicv_inhibit_reasons = vmx_check_apicv_inhibit_reasons, - .hwapic_irr_update = vmx_hwapic_irr_update, - .hwapic_isr_update = vmx_hwapic_isr_update, -diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c -index b8db2148c07d5..3c61bb98c10e2 100644 ---- a/arch/x86/xen/enlighten.c -+++ b/arch/x86/xen/enlighten.c -@@ -32,10 +32,13 @@ EXPORT_SYMBOL_GPL(hypercall_page); - * &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info - * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info - * but during boot it is switched to point to xen_vcpu_info. -- * The pointer is used in __xen_evtchn_do_upcall to acknowledge pending events. -+ * The pointer is used in xen_evtchn_do_upcall to acknowledge pending events. -+ * Make sure that xen_vcpu_info doesn't cross a page boundary by making it -+ * cache-line aligned (the struct is guaranteed to have a size of 64 bytes, -+ * which matches the cache line size of 64-bit x86 processors). - */ - DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); --DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); -+DEFINE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info); - - /* Linux <-> Xen vCPU id mapping */ - DEFINE_PER_CPU(uint32_t, xen_vcpu_id); -@@ -160,6 +163,7 @@ void xen_vcpu_setup(int cpu) - int err; - struct vcpu_info *vcpup; - -+ BUILD_BUG_ON(sizeof(*vcpup) > SMP_CACHE_BYTES); - BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); - - /* -diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c -index c1cd28e915a3a..c66807dd02703 100644 ---- a/arch/x86/xen/enlighten_hvm.c -+++ b/arch/x86/xen/enlighten_hvm.c -@@ -136,7 +136,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback) - - inc_irq_stat(irq_hv_callback_count); - -- xen_hvm_evtchn_do_upcall(); -+ xen_evtchn_do_upcall(); - - set_irq_regs(old_regs); - } -diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h -index a10903785a338..b2b2f4315b78d 100644 ---- a/arch/x86/xen/xen-ops.h -+++ b/arch/x86/xen/xen-ops.h -@@ -21,7 +21,7 @@ extern void *xen_initial_gdt; - struct trap_info; - void xen_copy_trap_info(struct trap_info *traps); - --DECLARE_PER_CPU(struct vcpu_info, xen_vcpu_info); -+DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info); - DECLARE_PER_CPU(unsigned long, xen_cr3); - DECLARE_PER_CPU(unsigned long, xen_current_cr3); - -diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c -index e614eb3355d39..a9da2f05e6297 100644 ---- a/drivers/ata/libata-scsi.c -+++ b/drivers/ata/libata-scsi.c -@@ -1086,9 +1086,14 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) - * Ask the sd driver to issue START STOP UNIT on runtime suspend - * and resume and shutdown only. For system level suspend/resume, - * devices power state is handled directly by libata EH. -+ * Given that disks are always spun up on system resume, also -+ * make sure that the sd driver forces runtime suspended disks -+ * to be resumed to correctly reflect the power state of the -+ * device. - */ -- sdev->manage_runtime_start_stop = true; -- sdev->manage_shutdown = true; -+ sdev->manage_runtime_start_stop = 1; -+ sdev->manage_shutdown = 1; -+ sdev->force_runtime_start_on_system_start = 1; - } - - /* -diff --git a/drivers/auxdisplay/hd44780_common.c b/drivers/auxdisplay/hd44780_common.c -index 3934c2eebf33d..7cbf375b0fa5e 100644 ---- a/drivers/auxdisplay/hd44780_common.c -+++ b/drivers/auxdisplay/hd44780_common.c -@@ -82,7 +82,15 @@ int hd44780_common_clear_display(struct charlcd *lcd) - hdc->write_cmd(hdc, LCD_CMD_DISPLAY_CLEAR); - /* datasheet says to wait 1,64 milliseconds */ - long_sleep(2); -- return 0; -+ -+ /* -+ * The Hitachi HD44780 controller (and compatible ones) reset the DDRAM -+ * address when executing the DISPLAY_CLEAR command, thus the -+ * following call is not required. However, other controllers do not -+ * (e.g. NewHaven NHD-0220DZW-AG5), thus move the cursor to home -+ * unconditionally to support both. -+ */ -+ return hd44780_common_home(lcd); - } - EXPORT_SYMBOL_GPL(hd44780_common_clear_display); - -diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c -index f8d2bba9173d8..edc294ee5a5bc 100644 ---- a/drivers/cpufreq/amd-pstate.c -+++ b/drivers/cpufreq/amd-pstate.c -@@ -296,7 +296,9 @@ static int amd_pstate_target(struct cpufreq_policy *policy, - static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy, - unsigned int target_freq) - { -- return amd_pstate_update_freq(policy, target_freq, true); -+ if (!amd_pstate_update_freq(policy, target_freq, true)) -+ return target_freq; -+ return policy->cur; - } - - static void amd_pstate_adjust_perf(unsigned int cpu, -diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c -index ad4ce84931446..925fc17eaacb2 100644 ---- a/drivers/cpufreq/imx6q-cpufreq.c -+++ b/drivers/cpufreq/imx6q-cpufreq.c -@@ -209,6 +209,14 @@ static struct cpufreq_driver imx6q_cpufreq_driver = { - .suspend = cpufreq_generic_suspend, - }; - -+static void imx6x_disable_freq_in_opp(struct device *dev, unsigned long freq) -+{ -+ int ret = dev_pm_opp_disable(dev, freq); -+ -+ if (ret < 0 && ret != -ENODEV) -+ dev_warn(dev, "failed to disable %ldMHz OPP\n", freq / 1000000); -+} -+ - #define OCOTP_CFG3 0x440 - #define OCOTP_CFG3_SPEED_SHIFT 16 - #define OCOTP_CFG3_SPEED_1P2GHZ 0x3 -@@ -254,17 +262,15 @@ static int imx6q_opp_check_speed_grading(struct device *dev) - val &= 0x3; - - if (val < OCOTP_CFG3_SPEED_996MHZ) -- if (dev_pm_opp_disable(dev, 996000000)) -- dev_warn(dev, "failed to disable 996MHz OPP\n"); -+ imx6x_disable_freq_in_opp(dev, 996000000); - - if (of_machine_is_compatible("fsl,imx6q") || - of_machine_is_compatible("fsl,imx6qp")) { - if (val != OCOTP_CFG3_SPEED_852MHZ) -- if (dev_pm_opp_disable(dev, 852000000)) -- dev_warn(dev, "failed to disable 852MHz OPP\n"); -+ imx6x_disable_freq_in_opp(dev, 852000000); -+ - if (val != OCOTP_CFG3_SPEED_1P2GHZ) -- if (dev_pm_opp_disable(dev, 1200000000)) -- dev_warn(dev, "failed to disable 1.2GHz OPP\n"); -+ imx6x_disable_freq_in_opp(dev, 1200000000); - } - - return 0; -@@ -316,20 +322,16 @@ static int imx6ul_opp_check_speed_grading(struct device *dev) - val >>= OCOTP_CFG3_SPEED_SHIFT; - val &= 0x3; - -- if (of_machine_is_compatible("fsl,imx6ul")) { -+ if (of_machine_is_compatible("fsl,imx6ul")) - if (val != OCOTP_CFG3_6UL_SPEED_696MHZ) -- if (dev_pm_opp_disable(dev, 696000000)) -- dev_warn(dev, "failed to disable 696MHz OPP\n"); -- } -+ imx6x_disable_freq_in_opp(dev, 696000000); - - if (of_machine_is_compatible("fsl,imx6ull")) { -- if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ) -- if (dev_pm_opp_disable(dev, 792000000)) -- dev_warn(dev, "failed to disable 792MHz OPP\n"); -+ if (val < OCOTP_CFG3_6ULL_SPEED_792MHZ) -+ imx6x_disable_freq_in_opp(dev, 792000000); - - if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ) -- if (dev_pm_opp_disable(dev, 900000000)) -- dev_warn(dev, "failed to disable 900MHz OPP\n"); -+ imx6x_disable_freq_in_opp(dev, 900000000); - } - - return ret; -diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c -index f1ba71aed33c3..e78ff9333c7a3 100644 ---- a/drivers/dma-buf/dma-resv.c -+++ b/drivers/dma-buf/dma-resv.c -@@ -296,7 +296,7 @@ void dma_resv_add_fence(struct dma_resv *obj, struct dma_fence *fence, - - dma_resv_list_entry(fobj, i, obj, &old, &old_usage); - if ((old->context == fence->context && old_usage >= usage && -- dma_fence_is_later(fence, old)) || -+ dma_fence_is_later_or_same(fence, old)) || - dma_fence_is_signaled(old)) { - dma_resv_list_set(fobj, i, fence, usage); - dma_fence_put(old); -diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c -index adddd8c45d0c1..74bab06283b71 100644 ---- a/drivers/firewire/core-device.c -+++ b/drivers/firewire/core-device.c -@@ -717,14 +717,11 @@ static void create_units(struct fw_device *device) - fw_unit_attributes, - &unit->attribute_group); - -- if (device_register(&unit->device) < 0) -- goto skip_unit; -- - fw_device_get(device); -- continue; -- -- skip_unit: -- kfree(unit); -+ if (device_register(&unit->device) < 0) { -+ put_device(&unit->device); -+ continue; -+ } - } - } - -diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c -index 7ad2e03afd4e5..234cd17fdee13 100644 ---- a/drivers/firewire/sbp2.c -+++ b/drivers/firewire/sbp2.c -@@ -1519,9 +1519,9 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) - sdev->use_10_for_rw = 1; - - if (sbp2_param_exclusive_login) { -- sdev->manage_system_start_stop = true; -- sdev->manage_runtime_start_stop = true; -- sdev->manage_shutdown = true; -+ sdev->manage_system_start_stop = 1; -+ sdev->manage_runtime_start_stop = 1; -+ sdev->manage_shutdown = 1; - } - - if (sdev->type == TYPE_ROM) -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -index 6e5bc74846952..b9983ca99eb7d 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -@@ -2200,6 +2200,8 @@ retry_init: - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); - -+ pci_wake_from_d3(pdev, TRUE); -+ - /* - * For runpm implemented via BACO, PMFW will handle the - * timing for BACO in and out: -diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c -index bc65fc1350f9a..23e7e5126eae6 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c -@@ -82,6 +82,10 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_4_me.bin"); - MODULE_FIRMWARE("amdgpu/gc_11_0_4_mec.bin"); - MODULE_FIRMWARE("amdgpu/gc_11_0_4_rlc.bin"); - -+static const struct soc15_reg_golden golden_settings_gc_11_0[] = { -+ SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL, 0x20000000, 0x20000000) -+}; -+ - static const struct soc15_reg_golden golden_settings_gc_11_0_1[] = - { - SOC15_REG_GOLDEN_VALUE(GC, 0, regCGTT_GS_NGG_CLK_CTRL, 0x9fff8fff, 0x00000010), -@@ -274,6 +278,10 @@ static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev) - default: - break; - } -+ soc15_program_register_sequence(adev, -+ golden_settings_gc_11_0, -+ (const u32)ARRAY_SIZE(golden_settings_gc_11_0)); -+ - } - - static void gfx_v11_0_write_data_to_reg(struct amdgpu_ring *ring, int eng_sel, -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 001932cb813dc..6d5f3c5fb4a62 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -6149,7 +6149,7 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector, - dm_new_state->underscan_enable = val; - ret = 0; - } else if (property == adev->mode_info.abm_level_property) { -- dm_new_state->abm_level = val; -+ dm_new_state->abm_level = val ?: ABM_LEVEL_IMMEDIATE_DISABLE; - ret = 0; - } - -@@ -6194,7 +6194,8 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector, - *val = dm_state->underscan_enable; - ret = 0; - } else if (property == adev->mode_info.abm_level_property) { -- *val = dm_state->abm_level; -+ *val = (dm_state->abm_level != ABM_LEVEL_IMMEDIATE_DISABLE) ? -+ dm_state->abm_level : 0; - ret = 0; - } - -@@ -6274,7 +6275,8 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector) - state->pbn = 0; - - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) -- state->abm_level = amdgpu_dm_abm_level; -+ state->abm_level = amdgpu_dm_abm_level ?: -+ ABM_LEVEL_IMMEDIATE_DISABLE; - - __drm_atomic_helper_connector_reset(connector, &state->base); - } -diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h -index f773a467fef54..7e775cec06927 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc.h -+++ b/drivers/gpu/drm/amd/display/dc/dc.h -@@ -499,9 +499,12 @@ enum dcn_zstate_support_state { - DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY, - DCN_ZSTATE_SUPPORT_DISALLOW, - }; --/* -- * For any clocks that may differ per pipe -- * only the max is stored in this structure -+ -+/** -+ * dc_clocks - DC pipe clocks -+ * -+ * For any clocks that may differ per pipe only the max is stored in this -+ * structure - */ - struct dc_clocks { - int dispclk_khz; -@@ -528,6 +531,16 @@ struct dc_clocks { - bool prev_p_state_change_support; - bool fclk_prev_p_state_change_support; - int num_ways; -+ -+ /** -+ * @fw_based_mclk_switching -+ * -+ * DC has a mechanism that leverage the variable refresh rate to switch -+ * memory clock in cases that we have a large latency to achieve the -+ * memory clock change and a short vblank window. DC has some -+ * requirements to enable this feature, and this field describes if the -+ * system support or not such a feature. -+ */ - bool fw_based_mclk_switching; - bool fw_based_mclk_switching_shut_down; - int prev_num_ways; -diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h -index 364ff913527d8..31c6a80c216ff 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc_stream.h -+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h -@@ -202,7 +202,18 @@ struct dc_stream_state { - bool use_vsc_sdp_for_colorimetry; - bool ignore_msa_timing_param; - -+ /** -+ * @allow_freesync: -+ * -+ * It say if Freesync is enabled or not. -+ */ - bool allow_freesync; -+ -+ /** -+ * @vrr_active_variable: -+ * -+ * It describes if VRR is in use. -+ */ - bool vrr_active_variable; - bool freesync_on_desktop; - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -index 7a00fe525dfba..3538973bd0c6c 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -@@ -308,7 +308,10 @@ bool cm_helper_convert_to_custom_float( - #define NUMBER_REGIONS 32 - #define NUMBER_SW_SEGMENTS 16 - --bool cm_helper_translate_curve_to_hw_format( -+#define DC_LOGGER \ -+ ctx->logger -+ -+bool cm_helper_translate_curve_to_hw_format(struct dc_context *ctx, - const struct dc_transfer_func *output_tf, - struct pwl_params *lut_params, bool fixpoint) - { -@@ -482,10 +485,18 @@ bool cm_helper_translate_curve_to_hw_format( - rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); - rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); - -+ - if (fixpoint == true) { -- rgb->delta_red_reg = dc_fixpt_clamp_u0d10(rgb->delta_red); -- rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green); -- rgb->delta_blue_reg = dc_fixpt_clamp_u0d10(rgb->delta_blue); -+ uint32_t red_clamp = dc_fixpt_clamp_u0d14(rgb->delta_red); -+ uint32_t green_clamp = dc_fixpt_clamp_u0d14(rgb->delta_green); -+ uint32_t blue_clamp = dc_fixpt_clamp_u0d14(rgb->delta_blue); -+ -+ if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp >> 10) -+ DC_LOG_WARNING("Losing delta precision while programming shaper LUT."); -+ -+ rgb->delta_red_reg = red_clamp & 0x3ff; -+ rgb->delta_green_reg = green_clamp & 0x3ff; -+ rgb->delta_blue_reg = blue_clamp & 0x3ff; - rgb->red_reg = dc_fixpt_clamp_u0d14(rgb->red); - rgb->green_reg = dc_fixpt_clamp_u0d14(rgb->green); - rgb->blue_reg = dc_fixpt_clamp_u0d14(rgb->blue); -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h -index 3b8cd7410498a..0a68b63d61260 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h -@@ -106,6 +106,7 @@ bool cm_helper_convert_to_custom_float( - bool fixpoint); - - bool cm_helper_translate_curve_to_hw_format( -+ struct dc_context *ctx, - const struct dc_transfer_func *output_tf, - struct pwl_params *lut_params, bool fixpoint); - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -index 3940271189632..d84579da64003 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -@@ -1867,7 +1867,7 @@ bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, - /* dcn10_translate_regamma_to_hw_format takes 750us, only do it when full - * update. - */ -- else if (cm_helper_translate_curve_to_hw_format( -+ else if (cm_helper_translate_curve_to_hw_format(dc->ctx, - stream->out_transfer_func, - &dpp->regamma_params, false)) { - dpp->funcs->dpp_program_regamma_pwl( -diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -index fbc188812ccc9..9bd6a5716cdc1 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -@@ -843,7 +843,7 @@ bool dcn20_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, - params = &stream->out_transfer_func->pwl; - else if (pipe_ctx->stream->out_transfer_func->type == - TF_TYPE_DISTRIBUTED_POINTS && -- cm_helper_translate_curve_to_hw_format( -+ cm_helper_translate_curve_to_hw_format(dc->ctx, - stream->out_transfer_func, - &mpc->blender_params, false)) - params = &mpc->blender_params; -@@ -872,7 +872,7 @@ bool dcn20_set_blend_lut( - if (plane_state->blend_tf->type == TF_TYPE_HWPWL) - blend_lut = &plane_state->blend_tf->pwl; - else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) { -- cm_helper_translate_curve_to_hw_format( -+ cm_helper_translate_curve_to_hw_format(plane_state->ctx, - plane_state->blend_tf, - &dpp_base->regamma_params, false); - blend_lut = &dpp_base->regamma_params; -@@ -894,7 +894,7 @@ bool dcn20_set_shaper_3dlut( - if (plane_state->in_shaper_func->type == TF_TYPE_HWPWL) - shaper_lut = &plane_state->in_shaper_func->pwl; - else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) { -- cm_helper_translate_curve_to_hw_format( -+ cm_helper_translate_curve_to_hw_format(plane_state->ctx, - plane_state->in_shaper_func, - &dpp_base->shaper_params, true); - shaper_lut = &dpp_base->shaper_params; -diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c -index 6a3d3a0ec0a36..701c7d8bc038a 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c -@@ -280,7 +280,7 @@ bool dwb3_ogam_set_input_transfer_func( - dwb_ogam_lut = kzalloc(sizeof(*dwb_ogam_lut), GFP_KERNEL); - - if (dwb_ogam_lut) { -- cm_helper_translate_curve_to_hw_format( -+ cm_helper_translate_curve_to_hw_format(dwbc->ctx, - in_transfer_func_dwb_ogam, - dwb_ogam_lut, false); - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -index a1b312483d7f1..53262f6bc40b0 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -@@ -91,8 +91,8 @@ bool dcn30_set_blend_lut( - return result; - } - --static bool dcn30_set_mpc_shaper_3dlut( -- struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream) -+static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx, -+ const struct dc_stream_state *stream) - { - struct dpp *dpp_base = pipe_ctx->plane_res.dpp; - int mpcc_id = pipe_ctx->plane_res.hubp->inst; -@@ -104,19 +104,18 @@ static bool dcn30_set_mpc_shaper_3dlut( - const struct pwl_params *shaper_lut = NULL; - //get the shaper lut params - if (stream->func_shaper) { -- if (stream->func_shaper->type == TF_TYPE_HWPWL) -+ if (stream->func_shaper->type == TF_TYPE_HWPWL) { - shaper_lut = &stream->func_shaper->pwl; -- else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) { -- cm_helper_translate_curve_to_hw_format( -- stream->func_shaper, -- &dpp_base->shaper_params, true); -+ } else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) { -+ cm_helper_translate_curve_to_hw_format(stream->ctx, stream->func_shaper, -+ &dpp_base->shaper_params, true); - shaper_lut = &dpp_base->shaper_params; - } - } - - if (stream->lut3d_func && -- stream->lut3d_func->state.bits.initialized == 1 && -- stream->lut3d_func->state.bits.rmu_idx_valid == 1) { -+ stream->lut3d_func->state.bits.initialized == 1 && -+ stream->lut3d_func->state.bits.rmu_idx_valid == 1) { - if (stream->lut3d_func->state.bits.rmu_mux_num == 0) - mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu0_mux; - else if (stream->lut3d_func->state.bits.rmu_mux_num == 1) -@@ -125,20 +124,22 @@ static bool dcn30_set_mpc_shaper_3dlut( - mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu2_mux; - if (mpcc_id_projected != mpcc_id) - BREAK_TO_DEBUGGER(); -- /*find the reason why logical layer assigned a differant mpcc_id into acquire_post_bldn_3dlut*/ -+ /* find the reason why logical layer assigned a different -+ * mpcc_id into acquire_post_bldn_3dlut -+ */ - acquired_rmu = mpc->funcs->acquire_rmu(mpc, mpcc_id, -- stream->lut3d_func->state.bits.rmu_mux_num); -+ stream->lut3d_func->state.bits.rmu_mux_num); - if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num) - BREAK_TO_DEBUGGER(); -- result = mpc->funcs->program_3dlut(mpc, -- &stream->lut3d_func->lut_3d, -- stream->lut3d_func->state.bits.rmu_mux_num); -+ -+ result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d, -+ stream->lut3d_func->state.bits.rmu_mux_num); - result = mpc->funcs->program_shaper(mpc, shaper_lut, -- stream->lut3d_func->state.bits.rmu_mux_num); -- } else -- /*loop through the available mux and release the requested mpcc_id*/ -+ stream->lut3d_func->state.bits.rmu_mux_num); -+ } else { -+ // loop through the available mux and release the requested mpcc_id - mpc->funcs->release_rmu(mpc, mpcc_id); -- -+ } - - return result; - } -diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c -index 503ab45b4ace3..6b8abdb5c7f89 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c -@@ -884,7 +884,7 @@ static const struct dc_plane_cap plane_cap = { - static const struct dc_debug_options debug_defaults_drv = { - .disable_z10 = false, - .enable_z9_disable_interface = true, -- .minimum_z8_residency_time = 2000, -+ .minimum_z8_residency_time = 2100, - .psr_skip_crtc_disable = true, - .disable_dmcu = true, - .force_abm_enable = false, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -index 50b3547977281..bd75d3cba0980 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c -@@ -530,7 +530,7 @@ static bool dcn32_set_mpc_shaper_3dlut( - if (stream->func_shaper->type == TF_TYPE_HWPWL) - shaper_lut = &stream->func_shaper->pwl; - else if (stream->func_shaper->type == TF_TYPE_DISTRIBUTED_POINTS) { -- cm_helper_translate_curve_to_hw_format( -+ cm_helper_translate_curve_to_hw_format(stream->ctx, - stream->func_shaper, - &dpp_base->shaper_params, true); - shaper_lut = &dpp_base->shaper_params; -@@ -566,8 +566,7 @@ bool dcn32_set_mcm_luts( - if (plane_state->blend_tf->type == TF_TYPE_HWPWL) - lut_params = &plane_state->blend_tf->pwl; - else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) { -- cm_helper_translate_curve_to_hw_format( -- plane_state->blend_tf, -+ cm3_helper_translate_curve_to_hw_format(plane_state->blend_tf, - &dpp_base->regamma_params, false); - lut_params = &dpp_base->regamma_params; - } -@@ -581,8 +580,7 @@ bool dcn32_set_mcm_luts( - else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) { - // TODO: dpp_base replace - ASSERT(false); -- cm_helper_translate_curve_to_hw_format( -- plane_state->in_shaper_func, -+ cm3_helper_translate_curve_to_hw_format(plane_state->in_shaper_func, - &dpp_base->shaper_params, true); - lut_params = &dpp_base->shaper_params; - } -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h -index 74e86732e3010..2cbdd75429ffd 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h -@@ -29,6 +29,13 @@ - #define DC__PRESENT 1 - #define DC__PRESENT__1 1 - #define DC__NUM_DPP 4 -+ -+/** -+ * @DC__VOLTAGE_STATES: -+ * -+ * Define the maximum amount of states supported by the ASIC. Every ASIC has a -+ * specific number of states; this macro defines the maximum number of states. -+ */ - #define DC__VOLTAGE_STATES 20 - #define DC__NUM_DPP__4 1 - #define DC__NUM_DPP__0_PRESENT 1 -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c -index dbe5d2efa4a30..9d224bb2b3df6 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c -@@ -948,10 +948,8 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc - { - int plane_count; - int i; -- unsigned int min_dst_y_next_start_us; - - plane_count = 0; -- min_dst_y_next_start_us = 0; - for (i = 0; i < dc->res_pool->pipe_count; i++) { - if (context->res_ctx.pipe_ctx[i].plane_state) - plane_count++; -@@ -973,26 +971,15 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc - else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { - struct dc_link *link = context->streams[0]->sink->link; - struct dc_stream_status *stream_status = &context->stream_status[0]; -- struct dc_stream_state *current_stream = context->streams[0]; - int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000; - bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency; - bool is_pwrseq0 = link->link_index == 0; -- bool isFreesyncVideo; -- -- isFreesyncVideo = current_stream->adjust.v_total_min == current_stream->adjust.v_total_max; -- isFreesyncVideo = isFreesyncVideo && current_stream->timing.v_total < current_stream->adjust.v_total_min; -- for (i = 0; i < dc->res_pool->pipe_count; i++) { -- if (context->res_ctx.pipe_ctx[i].stream == current_stream && isFreesyncVideo) { -- min_dst_y_next_start_us = context->res_ctx.pipe_ctx[i].dlg_regs.min_dst_y_next_start_us; -- break; -- } -- } - - /* Don't support multi-plane configurations */ - if (stream_status->plane_count > 1) - return DCN_ZSTATE_SUPPORT_DISALLOW; - -- if (is_pwrseq0 && (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || min_dst_y_next_start_us > 5000)) -+ if (is_pwrseq0 && context->bw_ctx.dml.vba.StutterPeriod > 5000.0) - return DCN_ZSTATE_SUPPORT_ALLOW; - else if (is_pwrseq0 && link->psr_settings.psr_version == DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr) - return allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY : DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY; -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c -index c89b761bcb926..85e0d1c2a9085 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c -@@ -1788,6 +1788,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, - int i, pipe_idx, vlevel_temp = 0; - double dcfclk = dcn3_2_soc.clock_limits[0].dcfclk_mhz; - double dcfclk_from_validation = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; -+ double dram_speed_from_validation = context->bw_ctx.dml.vba.DRAMSpeed; - double dcfclk_from_fw_based_mclk_switching = dcfclk_from_validation; - bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != - dm_dram_clock_change_unsupported; -@@ -1921,7 +1922,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, - } - - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) { -- min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed; -+ min_dram_speed_mts = dram_speed_from_validation; - min_dram_speed_mts_margin = 160; - - context->bw_ctx.dml.soc.dram_clock_change_latency_us = -diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h -index f394b3f3922a8..0bffae95f3a29 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h -@@ -105,14 +105,39 @@ enum source_macro_tile_size { - enum cursor_bpp { - dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2 - }; -+ -+/** -+ * @enum clock_change_support - It represents possible reasons to change the DRAM clock. -+ * -+ * DC may change the DRAM clock during its execution, and this enum tracks all -+ * the available methods. Note that every ASIC has their specific way to deal -+ * with these clock switch. -+ */ - enum clock_change_support { -+ /** -+ * @dm_dram_clock_change_uninitialized: If you see this, we might have -+ * a code initialization issue -+ */ - dm_dram_clock_change_uninitialized = 0, -+ -+ /** -+ * @dm_dram_clock_change_vactive: Support DRAM switch in VActive -+ */ - dm_dram_clock_change_vactive, -+ -+ /** -+ * @dm_dram_clock_change_vblank: Support DRAM switch in VBlank -+ */ - dm_dram_clock_change_vblank, -+ - dm_dram_clock_change_vactive_w_mall_full_frame, - dm_dram_clock_change_vactive_w_mall_sub_vp, - dm_dram_clock_change_vblank_w_mall_full_frame, - dm_dram_clock_change_vblank_w_mall_sub_vp, -+ -+ /** -+ * @dm_dram_clock_change_unsupported: Do not support DRAM switch -+ */ - dm_dram_clock_change_unsupported - }; - -diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h -index 2b34b02dbd459..81e53e67cd0b0 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h -+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h -@@ -419,6 +419,15 @@ struct vba_vars_st { - double MinPixelChunkSizeBytes; - unsigned int DCCMetaBufferSizeBytes; - // Pipe/Plane Parameters -+ -+ /** @VoltageLevel: -+ * Every ASIC has a fixed number of DPM states, and some devices might -+ * have some particular voltage configuration that does not map -+ * directly to the DPM states. This field tells how many states the -+ * target device supports; even though this field combines the DPM and -+ * special SOC voltages, it mostly matches the total number of DPM -+ * states. -+ */ - int VoltageLevel; - double FabricClock; - double DRAMSpeed; -diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h -index 5fa7c4772af4f..d2b9e3f83fc3b 100644 ---- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h -+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h -@@ -115,6 +115,13 @@ struct resource_funcs { - int vlevel); - void (*update_soc_for_wm_a)( - struct dc *dc, struct dc_state *context); -+ -+ /** -+ * @populate_dml_pipes - Populate pipe data struct -+ * -+ * Returns: -+ * Total of pipes available in the specific ASIC. -+ */ - int (*populate_dml_pipes)( - struct dc *dc, - struct dc_state *context, -diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h -index cd2be729846b4..a819f0f97c5f3 100644 ---- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h -+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h -@@ -35,6 +35,13 @@ - ******************************************************************************/ - - #define MAX_AUDIOS 7 -+ -+/** -+ * @MAX_PIPES: -+ * -+ * Every ASIC support a fixed number of pipes; MAX_PIPES defines a large number -+ * to be used inside loops and for determining array sizes. -+ */ - #define MAX_PIPES 6 - #define MAX_DIG_LINK_ENCODERS 7 - #define MAX_DWB_PIPES 1 -diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h -index a21fe7b037d1f..aaabaab49809d 100644 ---- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h -+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h -@@ -332,6 +332,8 @@ struct dmub_srv_hw_funcs { - void (*setup_mailbox)(struct dmub_srv *dmub, - const struct dmub_region *inbox1); - -+ uint32_t (*get_inbox1_wptr)(struct dmub_srv *dmub); -+ - uint32_t (*get_inbox1_rptr)(struct dmub_srv *dmub); - - void (*set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset); -@@ -590,6 +592,18 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, - */ - enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub); - -+/** -+ * dmub_srv_sync_inbox1() - sync sw state with hw state -+ * @dmub: the dmub service -+ * -+ * Sync sw state with hw state when resume from S0i3 -+ * -+ * Return: -+ * DMUB_STATUS_OK - success -+ * DMUB_STATUS_INVALID - unspecified error -+ */ -+enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub); -+ - /** - * dmub_srv_cmd_queue() - queues a command to the DMUB - * @dmub: the dmub service -diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c -index a6540e27044d2..98dad0d47e72c 100644 ---- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c -+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c -@@ -282,6 +282,11 @@ void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub, - REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base); - } - -+uint32_t dmub_dcn20_get_inbox1_wptr(struct dmub_srv *dmub) -+{ -+ return REG_READ(DMCUB_INBOX1_WPTR); -+} -+ - uint32_t dmub_dcn20_get_inbox1_rptr(struct dmub_srv *dmub) - { - return REG_READ(DMCUB_INBOX1_RPTR); -diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h -index c2e5831ac52cc..1df128e57ed3b 100644 ---- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h -+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h -@@ -202,6 +202,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub, - void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub, - const struct dmub_region *inbox1); - -+uint32_t dmub_dcn20_get_inbox1_wptr(struct dmub_srv *dmub); -+ - uint32_t dmub_dcn20_get_inbox1_rptr(struct dmub_srv *dmub); - - void dmub_dcn20_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset); -diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c -index 89d24fb7024e2..5e952541e72d5 100644 ---- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c -+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c -@@ -242,6 +242,11 @@ void dmub_dcn31_setup_mailbox(struct dmub_srv *dmub, - REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base); - } - -+uint32_t dmub_dcn31_get_inbox1_wptr(struct dmub_srv *dmub) -+{ -+ return REG_READ(DMCUB_INBOX1_WPTR); -+} -+ - uint32_t dmub_dcn31_get_inbox1_rptr(struct dmub_srv *dmub) - { - return REG_READ(DMCUB_INBOX1_RPTR); -diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h -index eb62410941473..89c5a948b67d5 100644 ---- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h -+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h -@@ -204,6 +204,8 @@ void dmub_dcn31_setup_windows(struct dmub_srv *dmub, - void dmub_dcn31_setup_mailbox(struct dmub_srv *dmub, - const struct dmub_region *inbox1); - -+uint32_t dmub_dcn31_get_inbox1_wptr(struct dmub_srv *dmub); -+ - uint32_t dmub_dcn31_get_inbox1_rptr(struct dmub_srv *dmub); - - void dmub_dcn31_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset); -diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c -index 9c20516be066c..d2f03f797279f 100644 ---- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c -+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c -@@ -266,6 +266,11 @@ void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub, - REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base); - } - -+uint32_t dmub_dcn32_get_inbox1_wptr(struct dmub_srv *dmub) -+{ -+ return REG_READ(DMCUB_INBOX1_WPTR); -+} -+ - uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub) - { - return REG_READ(DMCUB_INBOX1_RPTR); -diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h -index 7d1a6eb4d6657..f15336b6e22be 100644 ---- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h -+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h -@@ -206,6 +206,8 @@ void dmub_dcn32_setup_windows(struct dmub_srv *dmub, - void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub, - const struct dmub_region *inbox1); - -+uint32_t dmub_dcn32_get_inbox1_wptr(struct dmub_srv *dmub); -+ - uint32_t dmub_dcn32_get_inbox1_rptr(struct dmub_srv *dmub); - - void dmub_dcn32_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset); -diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c -index c3327875933e9..e951fd837aa27 100644 ---- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c -+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c -@@ -167,6 +167,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) - funcs->backdoor_load = dmub_dcn20_backdoor_load; - funcs->setup_windows = dmub_dcn20_setup_windows; - funcs->setup_mailbox = dmub_dcn20_setup_mailbox; -+ funcs->get_inbox1_wptr = dmub_dcn20_get_inbox1_wptr; - funcs->get_inbox1_rptr = dmub_dcn20_get_inbox1_rptr; - funcs->set_inbox1_wptr = dmub_dcn20_set_inbox1_wptr; - funcs->is_supported = dmub_dcn20_is_supported; -@@ -243,6 +244,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) - funcs->backdoor_load = dmub_dcn31_backdoor_load; - funcs->setup_windows = dmub_dcn31_setup_windows; - funcs->setup_mailbox = dmub_dcn31_setup_mailbox; -+ funcs->get_inbox1_wptr = dmub_dcn31_get_inbox1_wptr; - funcs->get_inbox1_rptr = dmub_dcn31_get_inbox1_rptr; - funcs->set_inbox1_wptr = dmub_dcn31_set_inbox1_wptr; - funcs->setup_out_mailbox = dmub_dcn31_setup_out_mailbox; -@@ -281,6 +283,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) - funcs->backdoor_load_zfb_mode = dmub_dcn32_backdoor_load_zfb_mode; - funcs->setup_windows = dmub_dcn32_setup_windows; - funcs->setup_mailbox = dmub_dcn32_setup_mailbox; -+ funcs->get_inbox1_wptr = dmub_dcn32_get_inbox1_wptr; - funcs->get_inbox1_rptr = dmub_dcn32_get_inbox1_rptr; - funcs->set_inbox1_wptr = dmub_dcn32_set_inbox1_wptr; - funcs->setup_out_mailbox = dmub_dcn32_setup_out_mailbox; -@@ -666,6 +669,27 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, - return DMUB_STATUS_OK; - } - -+enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub) -+{ -+ if (!dmub->sw_init) -+ return DMUB_STATUS_INVALID; -+ -+ if (dmub->hw_funcs.get_inbox1_rptr && dmub->hw_funcs.get_inbox1_wptr) { -+ uint32_t rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); -+ uint32_t wptr = dmub->hw_funcs.get_inbox1_wptr(dmub); -+ -+ if (rptr > dmub->inbox1_rb.capacity || wptr > dmub->inbox1_rb.capacity) { -+ return DMUB_STATUS_HW_FAILURE; -+ } else { -+ dmub->inbox1_rb.rptr = rptr; -+ dmub->inbox1_rb.wrpt = wptr; -+ dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt; -+ } -+ } -+ -+ return DMUB_STATUS_OK; -+} -+ - enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub) - { - if (!dmub->sw_init) -@@ -694,6 +718,11 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub, - if (!dmub->hw_init) - return DMUB_STATUS_INVALID; - -+ if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity || -+ dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) { -+ return DMUB_STATUS_HW_FAILURE; -+ } -+ - if (dmub_rb_push_front(&dmub->inbox1_rb, cmd)) - return DMUB_STATUS_OK; - -@@ -964,6 +993,7 @@ enum dmub_status dmub_srv_wait_for_inbox0_ack(struct dmub_srv *dmub, uint32_t ti - ack = dmub->hw_funcs.read_inbox0_ack_register(dmub); - if (ack) - return DMUB_STATUS_OK; -+ udelay(1); - } - return DMUB_STATUS_TIMEOUT; - } -diff --git a/drivers/gpu/drm/amd/include/asic_reg/gc/gc_11_0_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/gc/gc_11_0_0_offset.h -index c92c4b83253f8..4bff1ef8a9a64 100644 ---- a/drivers/gpu/drm/amd/include/asic_reg/gc/gc_11_0_0_offset.h -+++ b/drivers/gpu/drm/amd/include/asic_reg/gc/gc_11_0_0_offset.h -@@ -6369,6 +6369,8 @@ - #define regTCP_INVALIDATE_BASE_IDX 1 - #define regTCP_STATUS 0x19a1 - #define regTCP_STATUS_BASE_IDX 1 -+#define regTCP_CNTL 0x19a2 -+#define regTCP_CNTL_BASE_IDX 1 - #define regTCP_CNTL2 0x19a3 - #define regTCP_CNTL2_BASE_IDX 1 - #define regTCP_DEBUG_INDEX 0x19a5 -diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c -index d30ec3005ea19..cd8b0ab0112ae 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c -@@ -258,8 +258,11 @@ static int aldebaran_tables_init(struct smu_context *smu) - } - - smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL); -- if (!smu_table->ecc_table) -+ if (!smu_table->ecc_table) { -+ kfree(smu_table->metrics_table); -+ kfree(smu_table->gpu_metrics_table); - return -ENOMEM; -+ } - - return 0; - } -diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c -index fc6957fddce8e..8404286302b0c 100644 ---- a/drivers/input/joystick/xpad.c -+++ b/drivers/input/joystick/xpad.c -@@ -136,6 +136,7 @@ static const struct xpad_device { - { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, - { 0x044f, 0x0f10, "Thrustmaster Modena GT Wheel", 0, XTYPE_XBOX }, - { 0x044f, 0xb326, "Thrustmaster Gamepad GP XID", 0, XTYPE_XBOX360 }, -+ { 0x03f0, 0x0495, "HyperX Clutch Gladiate", 0, XTYPE_XBOXONE }, - { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX }, - { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX }, - { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, -@@ -459,6 +460,7 @@ static const struct usb_device_id xpad_table[] = { - XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 Controller */ - XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */ - XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */ -+ XPAD_XBOXONE_VENDOR(0x03f0), /* HP HyperX Xbox One Controllers */ - XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ - XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ - XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ -diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c -index f800989ea0462..418af1db0192d 100644 ---- a/drivers/iommu/intel/dmar.c -+++ b/drivers/iommu/intel/dmar.c -@@ -1495,6 +1495,15 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid, - { - struct qi_desc desc; - -+ /* -+ * VT-d spec, section 4.3: -+ * -+ * Software is recommended to not submit any Device-TLB invalidation -+ * requests while address remapping hardware is disabled. -+ */ -+ if (!(iommu->gcmd & DMA_GCMD_TE)) -+ return; -+ - if (mask) { - addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1; - desc.qw1 = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE; -@@ -1560,6 +1569,15 @@ void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid, - unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size_order - 1); - struct qi_desc desc = {.qw1 = 0, .qw2 = 0, .qw3 = 0}; - -+ /* -+ * VT-d spec, section 4.3: -+ * -+ * Software is recommended to not submit any Device-TLB invalidation -+ * requests while address remapping hardware is disabled. -+ */ -+ if (!(iommu->gcmd & DMA_GCMD_TE)) -+ return; -+ - desc.qw0 = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) | - QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE | - QI_DEV_IOTLB_PFSID(pfsid); -diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c -index 5c4f5aa8e87e4..e111b35a7aff2 100644 ---- a/drivers/iommu/intel/iommu.c -+++ b/drivers/iommu/intel/iommu.c -@@ -277,7 +277,7 @@ static LIST_HEAD(dmar_satc_units); - #define for_each_rmrr_units(rmrr) \ - list_for_each_entry(rmrr, &dmar_rmrr_units, list) - --static void dmar_remove_one_dev_info(struct device *dev); -+static void device_block_translation(struct device *dev); - - int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON); - int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON); -@@ -1418,7 +1418,7 @@ static void iommu_enable_pci_caps(struct device_domain_info *info) - { - struct pci_dev *pdev; - -- if (!info || !dev_is_pci(info->dev)) -+ if (!dev_is_pci(info->dev)) - return; - - pdev = to_pci_dev(info->dev); -@@ -2064,7 +2064,6 @@ static int domain_context_mapping_one(struct dmar_domain *domain, - } else { - iommu_flush_write_buffer(iommu); - } -- iommu_enable_pci_caps(info); - - ret = 0; - -@@ -2494,13 +2493,6 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) - - /* PASID table is mandatory for a PCI device in scalable mode. */ - if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { -- ret = intel_pasid_alloc_table(dev); -- if (ret) { -- dev_err(dev, "PASID table allocation failed\n"); -- dmar_remove_one_dev_info(dev); -- return ret; -- } -- - /* Setup the PASID entry for requests without PASID: */ - if (hw_pass_through && domain_type_is_si(domain)) - ret = intel_pasid_setup_pass_through(iommu, domain, -@@ -2513,7 +2505,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) - dev, PASID_RID2PASID); - if (ret) { - dev_err(dev, "Setup RID2PASID failed\n"); -- dmar_remove_one_dev_info(dev); -+ device_block_translation(dev); - return ret; - } - } -@@ -2521,10 +2513,13 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) - ret = domain_context_mapping(domain, dev); - if (ret) { - dev_err(dev, "Domain context map failed\n"); -- dmar_remove_one_dev_info(dev); -+ device_block_translation(dev); - return ret; - } - -+ if (sm_supported(info->iommu) || !domain_type_is_si(info->domain)) -+ iommu_enable_pci_caps(info); -+ - return 0; - } - -@@ -4091,8 +4086,8 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op - */ - static void domain_context_clear(struct device_domain_info *info) - { -- if (!info->iommu || !info->dev || !dev_is_pci(info->dev)) -- return; -+ if (!dev_is_pci(info->dev)) -+ domain_context_clear_one(info, info->bus, info->devfn); - - pci_for_each_dma_alias(to_pci_dev(info->dev), - &domain_context_clear_one_cb, info); -@@ -4112,7 +4107,6 @@ static void dmar_remove_one_dev_info(struct device *dev) - - iommu_disable_dev_iotlb(info); - domain_context_clear(info); -- intel_pasid_free_table(info->dev); - } - - spin_lock_irqsave(&domain->lock, flags); -@@ -4123,6 +4117,37 @@ static void dmar_remove_one_dev_info(struct device *dev) - info->domain = NULL; - } - -+/* -+ * Clear the page table pointer in context or pasid table entries so that -+ * all DMA requests without PASID from the device are blocked. If the page -+ * table has been set, clean up the data structures. -+ */ -+static void device_block_translation(struct device *dev) -+{ -+ struct device_domain_info *info = dev_iommu_priv_get(dev); -+ struct intel_iommu *iommu = info->iommu; -+ unsigned long flags; -+ -+ iommu_disable_dev_iotlb(info); -+ if (!dev_is_real_dma_subdevice(dev)) { -+ if (sm_supported(iommu)) -+ intel_pasid_tear_down_entry(iommu, dev, -+ PASID_RID2PASID, false); -+ else -+ domain_context_clear(info); -+ } -+ -+ if (!info->domain) -+ return; -+ -+ spin_lock_irqsave(&info->domain->lock, flags); -+ list_del(&info->link); -+ spin_unlock_irqrestore(&info->domain->lock, flags); -+ -+ domain_detach_iommu(info->domain, iommu); -+ info->domain = NULL; -+} -+ - static int md_domain_init(struct dmar_domain *domain, int guest_width) - { - int adjust_width; -@@ -4246,7 +4271,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, - struct device_domain_info *info = dev_iommu_priv_get(dev); - - if (info->domain) -- dmar_remove_one_dev_info(dev); -+ device_block_translation(dev); - } - - ret = prepare_domain_attach_device(domain, dev); -@@ -4477,6 +4502,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev) - struct device_domain_info *info; - struct intel_iommu *iommu; - u8 bus, devfn; -+ int ret; - - iommu = device_to_iommu(dev, &bus, &devfn); - if (!iommu || !iommu->iommu.ops) -@@ -4521,6 +4547,16 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev) - - dev_iommu_priv_set(dev, info); - -+ if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { -+ ret = intel_pasid_alloc_table(dev); -+ if (ret) { -+ dev_err(dev, "PASID table allocation failed\n"); -+ dev_iommu_priv_set(dev, NULL); -+ kfree(info); -+ return ERR_PTR(ret); -+ } -+ } -+ - return &iommu->iommu; - } - -@@ -4529,6 +4565,7 @@ static void intel_iommu_release_device(struct device *dev) - struct device_domain_info *info = dev_iommu_priv_get(dev); - - dmar_remove_one_dev_info(dev); -+ intel_pasid_free_table(dev); - dev_iommu_priv_set(dev, NULL); - kfree(info); - set_dma_ops(dev, NULL); -@@ -4872,7 +4909,7 @@ static void quirk_igfx_skip_te_disable(struct pci_dev *dev) - ver = (dev->device >> 8) & 0xff; - if (ver != 0x45 && ver != 0x46 && ver != 0x4c && - ver != 0x4e && ver != 0x8a && ver != 0x98 && -- ver != 0x9a && ver != 0xa7) -+ ver != 0x9a && ver != 0xa7 && ver != 0x7d) - return; - - if (risky_device(dev)) -diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c -index 4d3595d6d1c40..05e3157fc7b4e 100644 ---- a/drivers/md/bcache/btree.c -+++ b/drivers/md/bcache/btree.c -@@ -1489,7 +1489,7 @@ out_nocoalesce: - bch_keylist_free(&keylist); - - for (i = 0; i < nodes; i++) -- if (!IS_ERR(new_nodes[i])) { -+ if (!IS_ERR_OR_NULL(new_nodes[i])) { - btree_node_free(new_nodes[i]); - rw_unlock(true, new_nodes[i]); - } -diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c -index 9eb03bb224698..0304e36af329c 100644 ---- a/drivers/md/dm-verity-fec.c -+++ b/drivers/md/dm-verity-fec.c -@@ -24,7 +24,8 @@ bool verity_fec_is_enabled(struct dm_verity *v) - */ - static inline struct dm_verity_fec_io *fec_io(struct dm_verity_io *io) - { -- return (struct dm_verity_fec_io *) verity_io_digest_end(io->v, io); -+ return (struct dm_verity_fec_io *) -+ ((char *)io + io->v->ti->per_io_data_size - sizeof(struct dm_verity_fec_io)); - } - - /* -diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c -index b86d41219ba9c..24df610a2c438 100644 ---- a/drivers/md/dm-verity-target.c -+++ b/drivers/md/dm-verity-target.c -@@ -631,7 +631,6 @@ static void verity_work(struct work_struct *w) - - io->in_tasklet = false; - -- verity_fec_init_io(io); - verity_finish_io(io, errno_to_blk_status(verity_verify_io(io))); - } - -@@ -657,7 +656,9 @@ static void verity_end_io(struct bio *bio) - struct dm_verity_io *io = bio->bi_private; - - if (bio->bi_status && -- (!verity_fec_is_enabled(io->v) || verity_is_system_shutting_down())) { -+ (!verity_fec_is_enabled(io->v) || -+ verity_is_system_shutting_down() || -+ (bio->bi_opf & REQ_RAHEAD))) { - verity_finish_io(io, bio->bi_status); - return; - } -@@ -779,6 +780,8 @@ static int verity_map(struct dm_target *ti, struct bio *bio) - bio->bi_private = io; - io->iter = bio->bi_iter; - -+ verity_fec_init_io(io); -+ - verity_submit_prefetch(v, io); - - submit_bio_noacct(bio); -diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h -index f96f4e281ee4a..f9d522c870e61 100644 ---- a/drivers/md/dm-verity.h -+++ b/drivers/md/dm-verity.h -@@ -115,12 +115,6 @@ static inline u8 *verity_io_want_digest(struct dm_verity *v, - return (u8 *)(io + 1) + v->ahash_reqsize + v->digest_size; - } - --static inline u8 *verity_io_digest_end(struct dm_verity *v, -- struct dm_verity_io *io) --{ -- return verity_io_want_digest(v, io) + v->digest_size; --} -- - extern int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io, - struct bvec_iter *iter, - int (*process)(struct dm_verity *v, -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index 67a7ae9b997aa..770490234c872 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -1505,6 +1505,8 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req) - blk_mq_requeue_request(req, true); - else - __blk_mq_end_request(req, BLK_STS_OK); -+ } else if (mq->in_recovery) { -+ blk_mq_requeue_request(req, true); - } else { - blk_mq_end_request(req, BLK_STS_OK); - } -diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -index de1cc9e1ae576..df85c35a86a3b 100644 ---- a/drivers/mmc/core/core.c -+++ b/drivers/mmc/core/core.c -@@ -552,7 +552,9 @@ int mmc_cqe_recovery(struct mmc_host *host) - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; - cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ - cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT; -- mmc_wait_for_cmd(host, &cmd, 0); -+ mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); -+ -+ mmc_poll_for_busy(host->card, MMC_CQE_RECOVERY_TIMEOUT, true, MMC_BUSY_IO); - - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = MMC_CMDQ_TASK_MGMT; -@@ -560,10 +562,13 @@ int mmc_cqe_recovery(struct mmc_host *host) - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; - cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ - cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT; -- err = mmc_wait_for_cmd(host, &cmd, 0); -+ err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); - - host->cqe_ops->cqe_recovery_finish(host); - -+ if (err) -+ err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); -+ - mmc_retune_release(host); - - return err; -diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c -index 609201a467ef9..4dcbc2281d2b5 100644 ---- a/drivers/mmc/core/regulator.c -+++ b/drivers/mmc/core/regulator.c -@@ -271,3 +271,44 @@ int mmc_regulator_get_supply(struct mmc_host *mmc) - return 0; - } - EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); -+ -+/** -+ * mmc_regulator_enable_vqmmc - enable VQMMC regulator for a host -+ * @mmc: the host to regulate -+ * -+ * Returns 0 or errno. Enables the regulator for vqmmc. -+ * Keeps track of the enable status for ensuring that calls to -+ * regulator_enable/disable are balanced. -+ */ -+int mmc_regulator_enable_vqmmc(struct mmc_host *mmc) -+{ -+ int ret = 0; -+ -+ if (!IS_ERR(mmc->supply.vqmmc) && !mmc->vqmmc_enabled) { -+ ret = regulator_enable(mmc->supply.vqmmc); -+ if (ret < 0) -+ dev_err(mmc_dev(mmc), "enabling vqmmc regulator failed\n"); -+ else -+ mmc->vqmmc_enabled = true; -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mmc_regulator_enable_vqmmc); -+ -+/** -+ * mmc_regulator_disable_vqmmc - disable VQMMC regulator for a host -+ * @mmc: the host to regulate -+ * -+ * Returns 0 or errno. Disables the regulator for vqmmc. -+ * Keeps track of the enable status for ensuring that calls to -+ * regulator_enable/disable are balanced. -+ */ -+void mmc_regulator_disable_vqmmc(struct mmc_host *mmc) -+{ -+ if (!IS_ERR(mmc->supply.vqmmc) && mmc->vqmmc_enabled) { -+ regulator_disable(mmc->supply.vqmmc); -+ mmc->vqmmc_enabled = false; -+ } -+} -+EXPORT_SYMBOL_GPL(mmc_regulator_disable_vqmmc); -diff --git a/drivers/mmc/host/cqhci-core.c b/drivers/mmc/host/cqhci-core.c -index b3d7d6d8d6548..41e94cd141098 100644 ---- a/drivers/mmc/host/cqhci-core.c -+++ b/drivers/mmc/host/cqhci-core.c -@@ -942,8 +942,8 @@ static bool cqhci_clear_all_tasks(struct mmc_host *mmc, unsigned int timeout) - ret = cqhci_tasks_cleared(cq_host); - - if (!ret) -- pr_debug("%s: cqhci: Failed to clear tasks\n", -- mmc_hostname(mmc)); -+ pr_warn("%s: cqhci: Failed to clear tasks\n", -+ mmc_hostname(mmc)); - - return ret; - } -@@ -976,7 +976,7 @@ static bool cqhci_halt(struct mmc_host *mmc, unsigned int timeout) - ret = cqhci_halted(cq_host); - - if (!ret) -- pr_debug("%s: cqhci: Failed to halt\n", mmc_hostname(mmc)); -+ pr_warn("%s: cqhci: Failed to halt\n", mmc_hostname(mmc)); - - return ret; - } -@@ -984,10 +984,10 @@ static bool cqhci_halt(struct mmc_host *mmc, unsigned int timeout) - /* - * After halting we expect to be able to use the command line. We interpret the - * failure to halt to mean the data lines might still be in use (and the upper -- * layers will need to send a STOP command), so we set the timeout based on a -- * generous command timeout. -+ * layers will need to send a STOP command), however failing to halt complicates -+ * the recovery, so set a timeout that would reasonably allow I/O to complete. - */ --#define CQHCI_START_HALT_TIMEOUT 5 -+#define CQHCI_START_HALT_TIMEOUT 500 - - static void cqhci_recovery_start(struct mmc_host *mmc) - { -@@ -1075,28 +1075,28 @@ static void cqhci_recovery_finish(struct mmc_host *mmc) - - ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); - -- if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) -- ok = false; -- - /* - * The specification contradicts itself, by saying that tasks cannot be - * cleared if CQHCI does not halt, but if CQHCI does not halt, it should - * be disabled/re-enabled, but not to disable before clearing tasks. - * Have a go anyway. - */ -- if (!ok) { -- pr_debug("%s: cqhci: disable / re-enable\n", mmc_hostname(mmc)); -- cqcfg = cqhci_readl(cq_host, CQHCI_CFG); -- cqcfg &= ~CQHCI_ENABLE; -- cqhci_writel(cq_host, cqcfg, CQHCI_CFG); -- cqcfg |= CQHCI_ENABLE; -- cqhci_writel(cq_host, cqcfg, CQHCI_CFG); -- /* Be sure that there are no tasks */ -- ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); -- if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) -- ok = false; -- WARN_ON(!ok); -- } -+ if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) -+ ok = false; -+ -+ /* Disable to make sure tasks really are cleared */ -+ cqcfg = cqhci_readl(cq_host, CQHCI_CFG); -+ cqcfg &= ~CQHCI_ENABLE; -+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG); -+ -+ cqcfg = cqhci_readl(cq_host, CQHCI_CFG); -+ cqcfg |= CQHCI_ENABLE; -+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG); -+ -+ cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); -+ -+ if (!ok) -+ cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT); - - cqhci_recover_mrqs(cq_host); - -diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c -index 33d7039c19169..3b5b5c139206d 100644 ---- a/drivers/mmc/host/sdhci-pci-gli.c -+++ b/drivers/mmc/host/sdhci-pci-gli.c -@@ -801,6 +801,32 @@ static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc, - sdhci_writel(host, val, SDHCI_GLI_9763E_HS400_ES_REG); - } - -+static void gl9763e_set_low_power_negotiation(struct sdhci_pci_slot *slot, -+ bool enable) -+{ -+ struct pci_dev *pdev = slot->chip->pdev; -+ u32 value; -+ -+ pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); -+ value &= ~GLI_9763E_VHS_REV; -+ value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_W); -+ pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); -+ -+ pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG, &value); -+ -+ if (enable) -+ value &= ~GLI_9763E_CFG_LPSN_DIS; -+ else -+ value |= GLI_9763E_CFG_LPSN_DIS; -+ -+ pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG, value); -+ -+ pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); -+ value &= ~GLI_9763E_VHS_REV; -+ value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); -+ pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); -+} -+ - static void sdhci_set_gl9763e_signaling(struct sdhci_host *host, - unsigned int timing) - { -@@ -909,6 +935,9 @@ static int gl9763e_add_host(struct sdhci_pci_slot *slot) - if (ret) - goto cleanup; - -+ /* Disable LPM negotiation to avoid entering L1 state. */ -+ gl9763e_set_low_power_negotiation(slot, false); -+ - return 0; - - cleanup: -@@ -960,31 +989,6 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot) - } - - #ifdef CONFIG_PM --static void gl9763e_set_low_power_negotiation(struct sdhci_pci_slot *slot, bool enable) --{ -- struct pci_dev *pdev = slot->chip->pdev; -- u32 value; -- -- pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); -- value &= ~GLI_9763E_VHS_REV; -- value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_W); -- pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); -- -- pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG, &value); -- -- if (enable) -- value &= ~GLI_9763E_CFG_LPSN_DIS; -- else -- value |= GLI_9763E_CFG_LPSN_DIS; -- -- pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG, value); -- -- pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); -- value &= ~GLI_9763E_VHS_REV; -- value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); -- pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); --} -- - static int gl9763e_runtime_suspend(struct sdhci_pci_chip *chip) - { - struct sdhci_pci_slot *slot = chip->slots[0]; -diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c -index 525f979e2a974..2101b6e794c0e 100644 ---- a/drivers/mmc/host/sdhci-sprd.c -+++ b/drivers/mmc/host/sdhci-sprd.c -@@ -405,12 +405,33 @@ static void sdhci_sprd_request_done(struct sdhci_host *host, - mmc_request_done(host->mmc, mrq); - } - -+static void sdhci_sprd_set_power(struct sdhci_host *host, unsigned char mode, -+ unsigned short vdd) -+{ -+ struct mmc_host *mmc = host->mmc; -+ -+ switch (mode) { -+ case MMC_POWER_OFF: -+ mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, 0); -+ -+ mmc_regulator_disable_vqmmc(mmc); -+ break; -+ case MMC_POWER_ON: -+ mmc_regulator_enable_vqmmc(mmc); -+ break; -+ case MMC_POWER_UP: -+ mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, vdd); -+ break; -+ } -+} -+ - static struct sdhci_ops sdhci_sprd_ops = { - .read_l = sdhci_sprd_readl, - .write_l = sdhci_sprd_writel, - .write_w = sdhci_sprd_writew, - .write_b = sdhci_sprd_writeb, - .set_clock = sdhci_sprd_set_clock, -+ .set_power = sdhci_sprd_set_power, - .get_max_clock = sdhci_sprd_get_max_clock, - .get_min_clock = sdhci_sprd_get_min_clock, - .set_bus_width = sdhci_set_bus_width, -@@ -676,6 +697,10 @@ static int sdhci_sprd_probe(struct platform_device *pdev) - host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | - SDHCI_SUPPORT_DDR50); - -+ ret = mmc_regulator_get_supply(host->mmc); -+ if (ret) -+ goto pm_runtime_disable; -+ - ret = sdhci_setup_host(host); - if (ret) - goto pm_runtime_disable; -diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -index 6383d9805dac9..b58162ce81d87 100644 ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -1043,14 +1043,12 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv *priv, - dma_addr_t addr; - - buffer_start = skb->data - dpaa2_eth_needed_headroom(skb); -- -- /* If there's enough room to align the FD address, do it. -- * It will help hardware optimize accesses. -- */ - aligned_start = PTR_ALIGN(buffer_start - DPAA2_ETH_TX_BUF_ALIGN, - DPAA2_ETH_TX_BUF_ALIGN); - if (aligned_start >= skb->head) - buffer_start = aligned_start; -+ else -+ return -ENOMEM; - - /* Store a backpointer to the skb at the beginning of the buffer - * (in the private data area) such that we can release it -@@ -4738,6 +4736,8 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev) - if (err) - goto err_dl_port_add; - -+ net_dev->needed_headroom = DPAA2_ETH_SWA_SIZE + DPAA2_ETH_TX_BUF_ALIGN; -+ - err = register_netdev(net_dev); - if (err < 0) { - dev_err(dev, "register_netdev() failed\n"); -diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -index 447718483ef47..e703846adc9f0 100644 ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -702,7 +702,7 @@ static inline bool dpaa2_eth_rx_pause_enabled(u64 link_options) - - static inline unsigned int dpaa2_eth_needed_headroom(struct sk_buff *skb) - { -- unsigned int headroom = DPAA2_ETH_SWA_SIZE; -+ unsigned int headroom = DPAA2_ETH_SWA_SIZE + DPAA2_ETH_TX_BUF_ALIGN; - - /* If we don't have an skb (e.g. XDP buffer), we only need space for - * the software annotation area -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -index 11eeb36cf9a54..a0c31f5b2ce05 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -@@ -232,7 +232,7 @@ M(NPC_GET_KEX_CFG, 0x600c, npc_get_kex_cfg, \ - M(NPC_INSTALL_FLOW, 0x600d, npc_install_flow, \ - npc_install_flow_req, npc_install_flow_rsp) \ - M(NPC_DELETE_FLOW, 0x600e, npc_delete_flow, \ -- npc_delete_flow_req, msg_rsp) \ -+ npc_delete_flow_req, npc_delete_flow_rsp) \ - M(NPC_MCAM_READ_ENTRY, 0x600f, npc_mcam_read_entry, \ - npc_mcam_read_entry_req, \ - npc_mcam_read_entry_rsp) \ -@@ -1471,6 +1471,8 @@ struct npc_install_flow_req { - u8 vtag0_op; - u16 vtag1_def; - u8 vtag1_op; -+ /* old counter value */ -+ u16 cntr_val; - }; - - struct npc_install_flow_rsp { -@@ -1486,6 +1488,11 @@ struct npc_delete_flow_req { - u8 all; /* PF + VFs */ - }; - -+struct npc_delete_flow_rsp { -+ struct mbox_msghdr hdr; -+ u16 cntr_val; -+}; -+ - struct npc_mcam_read_entry_req { - struct mbox_msghdr hdr; - u16 entry; /* MCAM entry to read */ -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -index 1f3a8cf42765e..7310047136986 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -@@ -5236,6 +5236,8 @@ int rvu_mbox_handler_nix_bandprof_free(struct rvu *rvu, - - ipolicer = &nix_hw->ipolicer[layer]; - for (idx = 0; idx < req->prof_count[layer]; idx++) { -+ if (idx == MAX_BANDPROF_PER_PFFUNC) -+ break; - prof_idx = req->prof_idx[layer][idx]; - if (prof_idx >= ipolicer->band_prof.max || - ipolicer->pfvf_map[prof_idx] != pcifunc) -@@ -5249,8 +5251,6 @@ int rvu_mbox_handler_nix_bandprof_free(struct rvu *rvu, - ipolicer->pfvf_map[prof_idx] = 0x00; - ipolicer->match_id[prof_idx] = 0; - rvu_free_rsrc(&ipolicer->band_prof, prof_idx); -- if (idx == MAX_BANDPROF_PER_PFFUNC) -- break; - } - } - mutex_unlock(&rvu->rsrc_lock); -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c -index 1eb5eb29a2ba6..80d6aa3f14c11 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c -@@ -1184,7 +1184,7 @@ find_rule: - write_req.enable_entry = (u8)enable; - /* if counter is available then clear and use it */ - if (req->set_cntr && rule->has_cntr) { -- rvu_write64(rvu, blkaddr, NPC_AF_MATCH_STATX(rule->cntr), 0x00); -+ rvu_write64(rvu, blkaddr, NPC_AF_MATCH_STATX(rule->cntr), req->cntr_val); - write_req.set_cntr = 1; - write_req.cntr = rule->cntr; - } -@@ -1399,12 +1399,13 @@ static int npc_delete_flow(struct rvu *rvu, struct rvu_npc_mcam_rule *rule, - - int rvu_mbox_handler_npc_delete_flow(struct rvu *rvu, - struct npc_delete_flow_req *req, -- struct msg_rsp *rsp) -+ struct npc_delete_flow_rsp *rsp) - { - struct npc_mcam *mcam = &rvu->hw->mcam; - struct rvu_npc_mcam_rule *iter, *tmp; - u16 pcifunc = req->hdr.pcifunc; - struct list_head del_list; -+ int blkaddr; - - INIT_LIST_HEAD(&del_list); - -@@ -1420,6 +1421,10 @@ int rvu_mbox_handler_npc_delete_flow(struct rvu *rvu, - list_move_tail(&iter->list, &del_list); - /* single rule */ - } else if (req->entry == iter->entry) { -+ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); -+ if (blkaddr) -+ rsp->cntr_val = rvu_read64(rvu, blkaddr, -+ NPC_AF_MATCH_STATX(iter->cntr)); - list_move_tail(&iter->list, &del_list); - break; - } -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c -index 3392487f6b47b..329b5a02914d7 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c -@@ -145,6 +145,7 @@ void rvu_switch_enable(struct rvu *rvu) - struct npc_mcam_alloc_entry_req alloc_req = { 0 }; - struct npc_mcam_alloc_entry_rsp alloc_rsp = { 0 }; - struct npc_delete_flow_req uninstall_req = { 0 }; -+ struct npc_delete_flow_rsp uninstall_rsp = { 0 }; - struct npc_mcam_free_entry_req free_req = { 0 }; - struct rvu_switch *rswitch = &rvu->rswitch; - struct msg_rsp rsp; -@@ -184,7 +185,7 @@ void rvu_switch_enable(struct rvu *rvu) - uninstall_rules: - uninstall_req.start = rswitch->start_entry; - uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1; -- rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &rsp); -+ rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &uninstall_rsp); - kfree(rswitch->entry2pcifunc); - free_entries: - free_req.all = 1; -@@ -196,6 +197,7 @@ exit: - void rvu_switch_disable(struct rvu *rvu) - { - struct npc_delete_flow_req uninstall_req = { 0 }; -+ struct npc_delete_flow_rsp uninstall_rsp = { 0 }; - struct npc_mcam_free_entry_req free_req = { 0 }; - struct rvu_switch *rswitch = &rvu->rswitch; - struct rvu_hwinfo *hw = rvu->hw; -@@ -232,7 +234,7 @@ void rvu_switch_disable(struct rvu *rvu) - uninstall_req.start = rswitch->start_entry; - uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1; - free_req.all = 1; -- rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &rsp); -+ rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &uninstall_rsp); - rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp); - rswitch->used_entries = 0; - kfree(rswitch->entry2pcifunc); -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c -index 826f691de2595..59d8d1ba15c28 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c -@@ -448,6 +448,9 @@ int cn10k_set_ipolicer_rate(struct otx2_nic *pfvf, u16 profile, - aq->prof.pebs_mantissa = 0; - aq->prof_mask.pebs_mantissa = 0xFF; - -+ aq->prof.hl_en = 0; -+ aq->prof_mask.hl_en = 1; -+ - /* Fill AQ info */ - aq->qidx = profile; - aq->ctype = NIX_AQ_CTYPE_BANDPROF; -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -index efd66224b3dbf..44950c2542bb7 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h -@@ -339,13 +339,8 @@ struct otx2_flow_config { - struct list_head flow_list; - u32 dmacflt_max_flows; - u16 max_flows; --}; -- --struct otx2_tc_info { -- /* hash table to store TC offloaded flows */ -- struct rhashtable flow_table; -- struct rhashtable_params flow_ht_params; -- unsigned long *tc_entries_bitmap; -+ struct list_head flow_list_tc; -+ bool ntuple; - }; - - struct dev_hw_ops { -@@ -465,7 +460,6 @@ struct otx2_nic { - /* NPC MCAM */ - struct otx2_flow_config *flow_cfg; - struct otx2_mac_table *mac_table; -- struct otx2_tc_info tc_info; - - u64 reset_count; - struct work_struct reset_task; -@@ -1024,7 +1018,8 @@ int otx2_init_tc(struct otx2_nic *nic); - void otx2_shutdown_tc(struct otx2_nic *nic); - int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type, - void *type_data); --int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic); -+void otx2_tc_apply_ingress_police_rules(struct otx2_nic *nic); -+ - /* CGX/RPM DMAC filters support */ - int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf); - int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u32 bit_pos); -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c -index 777a27047c8e8..5f71a72f95e50 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c -@@ -41,7 +41,6 @@ static int otx2_dl_mcam_count_set(struct devlink *devlink, u32 id, - return 0; - - otx2_alloc_mcam_entries(pfvf, ctx->val.vu16); -- otx2_tc_alloc_ent_bitmap(pfvf); - - return 0; - } -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c -index 0eb74e8c553dd..aaf1af2a402ec 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c -@@ -753,6 +753,7 @@ static int otx2_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *nfc) - struct otx2_nic *pfvf = netdev_priv(dev); - int ret = -EOPNOTSUPP; - -+ pfvf->flow_cfg->ntuple = ntuple; - switch (nfc->cmd) { - case ETHTOOL_SRXFH: - ret = otx2_set_rss_hash_opts(pfvf, nfc); -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c -index 5c4a4d3557702..5c757508322b9 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c -@@ -276,6 +276,7 @@ int otx2vf_mcam_flow_init(struct otx2_nic *pfvf) - - flow_cfg = pfvf->flow_cfg; - INIT_LIST_HEAD(&flow_cfg->flow_list); -+ INIT_LIST_HEAD(&flow_cfg->flow_list_tc); - flow_cfg->max_flows = 0; - - return 0; -@@ -298,6 +299,7 @@ int otx2_mcam_flow_init(struct otx2_nic *pf) - return -ENOMEM; - - INIT_LIST_HEAD(&pf->flow_cfg->flow_list); -+ INIT_LIST_HEAD(&pf->flow_cfg->flow_list_tc); - - /* Allocate bare minimum number of MCAM entries needed for - * unicast and ntuple filters. -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -index 1d2d72c60a12c..18c5d2b3f7f95 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -@@ -566,7 +566,9 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) - otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(1), intr); - otx2_queue_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr, - TYPE_PFVF); -- vfs -= 64; -+ if (intr) -+ trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr); -+ vfs = 64; - } - - intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(0)); -@@ -574,7 +576,8 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) - - otx2_queue_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr, TYPE_PFVF); - -- trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr); -+ if (intr) -+ trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr); - - return IRQ_HANDLED; - } -@@ -1855,6 +1858,8 @@ int otx2_open(struct net_device *netdev) - if (pf->flags & OTX2_FLAG_DMACFLTR_SUPPORT) - otx2_dmacflt_reinstall_flows(pf); - -+ otx2_tc_apply_ingress_police_rules(pf); -+ - err = otx2_rxtx_enable(pf, true); - /* If a mbox communication error happens at this point then interface - * will end up in a state such that it is in down state but hardware -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c -index 1aeb18a901b13..bb77ab7ddfefd 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c -@@ -48,9 +48,8 @@ struct otx2_tc_flow_stats { - }; - - struct otx2_tc_flow { -- struct rhash_head node; -+ struct list_head list; - unsigned long cookie; -- unsigned int bitpos; - struct rcu_head rcu; - struct otx2_tc_flow_stats stats; - spinlock_t lock; /* lock for stats */ -@@ -58,31 +57,13 @@ struct otx2_tc_flow { - u16 entry; - u16 leaf_profile; - bool is_act_police; -+ u32 prio; -+ struct npc_install_flow_req req; -+ u64 rate; -+ u32 burst; -+ bool is_pps; - }; - --int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic) --{ -- struct otx2_tc_info *tc = &nic->tc_info; -- -- if (!nic->flow_cfg->max_flows) -- return 0; -- -- /* Max flows changed, free the existing bitmap */ -- kfree(tc->tc_entries_bitmap); -- -- tc->tc_entries_bitmap = -- kcalloc(BITS_TO_LONGS(nic->flow_cfg->max_flows), -- sizeof(long), GFP_KERNEL); -- if (!tc->tc_entries_bitmap) { -- netdev_err(nic->netdev, -- "Unable to alloc TC flow entries bitmap\n"); -- return -ENOMEM; -- } -- -- return 0; --} --EXPORT_SYMBOL(otx2_tc_alloc_ent_bitmap); -- - static void otx2_get_egress_burst_cfg(struct otx2_nic *nic, u32 burst, - u32 *burst_exp, u32 *burst_mantissa) - { -@@ -321,21 +302,10 @@ static int otx2_tc_egress_matchall_delete(struct otx2_nic *nic, - return err; - } - --static int otx2_tc_act_set_police(struct otx2_nic *nic, -- struct otx2_tc_flow *node, -- struct flow_cls_offload *f, -- u64 rate, u32 burst, u32 mark, -- struct npc_install_flow_req *req, bool pps) -+static int otx2_tc_act_set_hw_police(struct otx2_nic *nic, -+ struct otx2_tc_flow *node) - { -- struct netlink_ext_ack *extack = f->common.extack; -- struct otx2_hw *hw = &nic->hw; -- int rq_idx, rc; -- -- rq_idx = find_first_zero_bit(&nic->rq_bmap, hw->rx_queues); -- if (rq_idx >= hw->rx_queues) { -- NL_SET_ERR_MSG_MOD(extack, "Police action rules exceeded"); -- return -EINVAL; -- } -+ int rc; - - mutex_lock(&nic->mbox.lock); - -@@ -345,23 +315,17 @@ static int otx2_tc_act_set_police(struct otx2_nic *nic, - return rc; - } - -- rc = cn10k_set_ipolicer_rate(nic, node->leaf_profile, burst, rate, pps); -+ rc = cn10k_set_ipolicer_rate(nic, node->leaf_profile, -+ node->burst, node->rate, node->is_pps); - if (rc) - goto free_leaf; - -- rc = cn10k_map_unmap_rq_policer(nic, rq_idx, node->leaf_profile, true); -+ rc = cn10k_map_unmap_rq_policer(nic, node->rq, node->leaf_profile, true); - if (rc) - goto free_leaf; - - mutex_unlock(&nic->mbox.lock); - -- req->match_id = mark & 0xFFFFULL; -- req->index = rq_idx; -- req->op = NIX_RX_ACTIONOP_UCAST; -- set_bit(rq_idx, &nic->rq_bmap); -- node->is_act_police = true; -- node->rq = rq_idx; -- - return 0; - - free_leaf: -@@ -373,6 +337,39 @@ free_leaf: - return rc; - } - -+static int otx2_tc_act_set_police(struct otx2_nic *nic, -+ struct otx2_tc_flow *node, -+ struct flow_cls_offload *f, -+ u64 rate, u32 burst, u32 mark, -+ struct npc_install_flow_req *req, bool pps) -+{ -+ struct netlink_ext_ack *extack = f->common.extack; -+ struct otx2_hw *hw = &nic->hw; -+ int rq_idx, rc; -+ -+ rq_idx = find_first_zero_bit(&nic->rq_bmap, hw->rx_queues); -+ if (rq_idx >= hw->rx_queues) { -+ NL_SET_ERR_MSG_MOD(extack, "Police action rules exceeded"); -+ return -EINVAL; -+ } -+ -+ req->match_id = mark & 0xFFFFULL; -+ req->index = rq_idx; -+ req->op = NIX_RX_ACTIONOP_UCAST; -+ -+ node->is_act_police = true; -+ node->rq = rq_idx; -+ node->burst = burst; -+ node->rate = rate; -+ node->is_pps = pps; -+ -+ rc = otx2_tc_act_set_hw_police(nic, node); -+ if (!rc) -+ set_bit(rq_idx, &nic->rq_bmap); -+ -+ return rc; -+} -+ - static int otx2_tc_parse_actions(struct otx2_nic *nic, - struct flow_action *flow_action, - struct npc_install_flow_req *req, -@@ -689,8 +686,117 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node, - return otx2_tc_parse_actions(nic, &rule->action, req, f, node); - } - --static int otx2_del_mcam_flow_entry(struct otx2_nic *nic, u16 entry) -+static void otx2_destroy_tc_flow_list(struct otx2_nic *pfvf) -+{ -+ struct otx2_flow_config *flow_cfg = pfvf->flow_cfg; -+ struct otx2_tc_flow *iter, *tmp; -+ -+ if (!(pfvf->flags & OTX2_FLAG_MCAM_ENTRIES_ALLOC)) -+ return; -+ -+ list_for_each_entry_safe(iter, tmp, &flow_cfg->flow_list_tc, list) { -+ list_del(&iter->list); -+ kfree(iter); -+ flow_cfg->nr_flows--; -+ } -+} -+ -+static struct otx2_tc_flow *otx2_tc_get_entry_by_cookie(struct otx2_flow_config *flow_cfg, -+ unsigned long cookie) -+{ -+ struct otx2_tc_flow *tmp; -+ -+ list_for_each_entry(tmp, &flow_cfg->flow_list_tc, list) { -+ if (tmp->cookie == cookie) -+ return tmp; -+ } -+ -+ return NULL; -+} -+ -+static struct otx2_tc_flow *otx2_tc_get_entry_by_index(struct otx2_flow_config *flow_cfg, -+ int index) -+{ -+ struct otx2_tc_flow *tmp; -+ int i = 0; -+ -+ list_for_each_entry(tmp, &flow_cfg->flow_list_tc, list) { -+ if (i == index) -+ return tmp; -+ i++; -+ } -+ -+ return NULL; -+} -+ -+static void otx2_tc_del_from_flow_list(struct otx2_flow_config *flow_cfg, -+ struct otx2_tc_flow *node) -+{ -+ struct list_head *pos, *n; -+ struct otx2_tc_flow *tmp; -+ -+ list_for_each_safe(pos, n, &flow_cfg->flow_list_tc) { -+ tmp = list_entry(pos, struct otx2_tc_flow, list); -+ if (node == tmp) { -+ list_del(&node->list); -+ return; -+ } -+ } -+} -+ -+static int otx2_tc_add_to_flow_list(struct otx2_flow_config *flow_cfg, -+ struct otx2_tc_flow *node) -+{ -+ struct list_head *pos, *n; -+ struct otx2_tc_flow *tmp; -+ int index = 0; -+ -+ /* If the flow list is empty then add the new node */ -+ if (list_empty(&flow_cfg->flow_list_tc)) { -+ list_add(&node->list, &flow_cfg->flow_list_tc); -+ return index; -+ } -+ -+ list_for_each_safe(pos, n, &flow_cfg->flow_list_tc) { -+ tmp = list_entry(pos, struct otx2_tc_flow, list); -+ if (node->prio < tmp->prio) -+ break; -+ index++; -+ } -+ -+ list_add(&node->list, pos->prev); -+ return index; -+} -+ -+static int otx2_add_mcam_flow_entry(struct otx2_nic *nic, struct npc_install_flow_req *req) -+{ -+ struct npc_install_flow_req *tmp_req; -+ int err; -+ -+ mutex_lock(&nic->mbox.lock); -+ tmp_req = otx2_mbox_alloc_msg_npc_install_flow(&nic->mbox); -+ if (!tmp_req) { -+ mutex_unlock(&nic->mbox.lock); -+ return -ENOMEM; -+ } -+ -+ memcpy(tmp_req, req, sizeof(struct npc_install_flow_req)); -+ /* Send message to AF */ -+ err = otx2_sync_mbox_msg(&nic->mbox); -+ if (err) { -+ netdev_err(nic->netdev, "Failed to install MCAM flow entry %d\n", -+ req->entry); -+ mutex_unlock(&nic->mbox.lock); -+ return -EFAULT; -+ } -+ -+ mutex_unlock(&nic->mbox.lock); -+ return 0; -+} -+ -+static int otx2_del_mcam_flow_entry(struct otx2_nic *nic, u16 entry, u16 *cntr_val) - { -+ struct npc_delete_flow_rsp *rsp; - struct npc_delete_flow_req *req; - int err; - -@@ -711,22 +817,113 @@ static int otx2_del_mcam_flow_entry(struct otx2_nic *nic, u16 entry) - mutex_unlock(&nic->mbox.lock); - return -EFAULT; - } -+ -+ if (cntr_val) { -+ rsp = (struct npc_delete_flow_rsp *)otx2_mbox_get_rsp(&nic->mbox.mbox, -+ 0, &req->hdr); -+ if (IS_ERR(rsp)) { -+ netdev_err(nic->netdev, "Failed to get MCAM delete response for entry %d\n", -+ entry); -+ mutex_unlock(&nic->mbox.lock); -+ return -EFAULT; -+ } -+ -+ *cntr_val = rsp->cntr_val; -+ } -+ - mutex_unlock(&nic->mbox.lock); -+ return 0; -+} -+ -+static int otx2_tc_update_mcam_table_del_req(struct otx2_nic *nic, -+ struct otx2_flow_config *flow_cfg, -+ struct otx2_tc_flow *node) -+{ -+ struct list_head *pos, *n; -+ struct otx2_tc_flow *tmp; -+ int i = 0, index = 0; -+ u16 cntr_val = 0; -+ -+ /* Find and delete the entry from the list and re-install -+ * all the entries from beginning to the index of the -+ * deleted entry to higher mcam indexes. -+ */ -+ list_for_each_safe(pos, n, &flow_cfg->flow_list_tc) { -+ tmp = list_entry(pos, struct otx2_tc_flow, list); -+ if (node == tmp) { -+ list_del(&tmp->list); -+ break; -+ } -+ -+ otx2_del_mcam_flow_entry(nic, tmp->entry, &cntr_val); -+ tmp->entry++; -+ tmp->req.entry = tmp->entry; -+ tmp->req.cntr_val = cntr_val; -+ index++; -+ } -+ -+ list_for_each_safe(pos, n, &flow_cfg->flow_list_tc) { -+ if (i == index) -+ break; -+ -+ tmp = list_entry(pos, struct otx2_tc_flow, list); -+ otx2_add_mcam_flow_entry(nic, &tmp->req); -+ i++; -+ } - - return 0; - } - -+static int otx2_tc_update_mcam_table_add_req(struct otx2_nic *nic, -+ struct otx2_flow_config *flow_cfg, -+ struct otx2_tc_flow *node) -+{ -+ int mcam_idx = flow_cfg->max_flows - flow_cfg->nr_flows - 1; -+ struct otx2_tc_flow *tmp; -+ int list_idx, i; -+ u16 cntr_val = 0; -+ -+ /* Find the index of the entry(list_idx) whose priority -+ * is greater than the new entry and re-install all -+ * the entries from beginning to list_idx to higher -+ * mcam indexes. -+ */ -+ list_idx = otx2_tc_add_to_flow_list(flow_cfg, node); -+ for (i = 0; i < list_idx; i++) { -+ tmp = otx2_tc_get_entry_by_index(flow_cfg, i); -+ if (!tmp) -+ return -ENOMEM; -+ -+ otx2_del_mcam_flow_entry(nic, tmp->entry, &cntr_val); -+ tmp->entry = flow_cfg->flow_ent[mcam_idx]; -+ tmp->req.entry = tmp->entry; -+ tmp->req.cntr_val = cntr_val; -+ otx2_add_mcam_flow_entry(nic, &tmp->req); -+ mcam_idx++; -+ } -+ -+ return mcam_idx; -+} -+ -+static int otx2_tc_update_mcam_table(struct otx2_nic *nic, -+ struct otx2_flow_config *flow_cfg, -+ struct otx2_tc_flow *node, -+ bool add_req) -+{ -+ if (add_req) -+ return otx2_tc_update_mcam_table_add_req(nic, flow_cfg, node); -+ -+ return otx2_tc_update_mcam_table_del_req(nic, flow_cfg, node); -+} -+ - static int otx2_tc_del_flow(struct otx2_nic *nic, - struct flow_cls_offload *tc_flow_cmd) - { - struct otx2_flow_config *flow_cfg = nic->flow_cfg; -- struct otx2_tc_info *tc_info = &nic->tc_info; - struct otx2_tc_flow *flow_node; - int err; - -- flow_node = rhashtable_lookup_fast(&tc_info->flow_table, -- &tc_flow_cmd->cookie, -- tc_info->flow_ht_params); -+ flow_node = otx2_tc_get_entry_by_cookie(flow_cfg, tc_flow_cmd->cookie); - if (!flow_node) { - netdev_err(nic->netdev, "tc flow not found for cookie 0x%lx\n", - tc_flow_cmd->cookie); -@@ -734,6 +931,11 @@ static int otx2_tc_del_flow(struct otx2_nic *nic, - } - - if (flow_node->is_act_police) { -+ __clear_bit(flow_node->rq, &nic->rq_bmap); -+ -+ if (nic->flags & OTX2_FLAG_INTF_DOWN) -+ goto free_mcam_flow; -+ - mutex_lock(&nic->mbox.lock); - - err = cn10k_map_unmap_rq_policer(nic, flow_node->rq, -@@ -749,21 +951,14 @@ static int otx2_tc_del_flow(struct otx2_nic *nic, - "Unable to free leaf bandwidth profile(%d)\n", - flow_node->leaf_profile); - -- __clear_bit(flow_node->rq, &nic->rq_bmap); -- - mutex_unlock(&nic->mbox.lock); - } - -- otx2_del_mcam_flow_entry(nic, flow_node->entry); -- -- WARN_ON(rhashtable_remove_fast(&nic->tc_info.flow_table, -- &flow_node->node, -- nic->tc_info.flow_ht_params)); -+free_mcam_flow: -+ otx2_del_mcam_flow_entry(nic, flow_node->entry, NULL); -+ otx2_tc_update_mcam_table(nic, flow_cfg, flow_node, false); - kfree_rcu(flow_node, rcu); -- -- clear_bit(flow_node->bitpos, tc_info->tc_entries_bitmap); - flow_cfg->nr_flows--; -- - return 0; - } - -@@ -772,15 +967,19 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, - { - struct netlink_ext_ack *extack = tc_flow_cmd->common.extack; - struct otx2_flow_config *flow_cfg = nic->flow_cfg; -- struct otx2_tc_info *tc_info = &nic->tc_info; - struct otx2_tc_flow *new_node, *old_node; - struct npc_install_flow_req *req, dummy; -- int rc, err; -+ int rc, err, mcam_idx; - - if (!(nic->flags & OTX2_FLAG_TC_FLOWER_SUPPORT)) - return -ENOMEM; - -- if (bitmap_full(tc_info->tc_entries_bitmap, flow_cfg->max_flows)) { -+ if (nic->flags & OTX2_FLAG_INTF_DOWN) { -+ NL_SET_ERR_MSG_MOD(extack, "Interface not initialized"); -+ return -EINVAL; -+ } -+ -+ if (flow_cfg->nr_flows == flow_cfg->max_flows) { - NL_SET_ERR_MSG_MOD(extack, - "Free MCAM entry not available to add the flow"); - return -ENOMEM; -@@ -792,6 +991,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, - return -ENOMEM; - spin_lock_init(&new_node->lock); - new_node->cookie = tc_flow_cmd->cookie; -+ new_node->prio = tc_flow_cmd->common.prio; - - memset(&dummy, 0, sizeof(struct npc_install_flow_req)); - -@@ -802,12 +1002,11 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, - } - - /* If a flow exists with the same cookie, delete it */ -- old_node = rhashtable_lookup_fast(&tc_info->flow_table, -- &tc_flow_cmd->cookie, -- tc_info->flow_ht_params); -+ old_node = otx2_tc_get_entry_by_cookie(flow_cfg, tc_flow_cmd->cookie); - if (old_node) - otx2_tc_del_flow(nic, tc_flow_cmd); - -+ mcam_idx = otx2_tc_update_mcam_table(nic, flow_cfg, new_node, true); - mutex_lock(&nic->mbox.lock); - req = otx2_mbox_alloc_msg_npc_install_flow(&nic->mbox); - if (!req) { -@@ -818,11 +1017,8 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, - - memcpy(&dummy.hdr, &req->hdr, sizeof(struct mbox_msghdr)); - memcpy(req, &dummy, sizeof(struct npc_install_flow_req)); -- -- new_node->bitpos = find_first_zero_bit(tc_info->tc_entries_bitmap, -- flow_cfg->max_flows); - req->channel = nic->hw.rx_chan_base; -- req->entry = flow_cfg->flow_ent[flow_cfg->max_flows - new_node->bitpos - 1]; -+ req->entry = flow_cfg->flow_ent[mcam_idx]; - req->intf = NIX_INTF_RX; - req->set_cntr = 1; - new_node->entry = req->entry; -@@ -832,26 +1028,18 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, - if (rc) { - NL_SET_ERR_MSG_MOD(extack, "Failed to install MCAM flow entry"); - mutex_unlock(&nic->mbox.lock); -- kfree_rcu(new_node, rcu); - goto free_leaf; - } -- mutex_unlock(&nic->mbox.lock); - -- /* add new flow to flow-table */ -- rc = rhashtable_insert_fast(&nic->tc_info.flow_table, &new_node->node, -- nic->tc_info.flow_ht_params); -- if (rc) { -- otx2_del_mcam_flow_entry(nic, req->entry); -- kfree_rcu(new_node, rcu); -- goto free_leaf; -- } -+ mutex_unlock(&nic->mbox.lock); -+ memcpy(&new_node->req, req, sizeof(struct npc_install_flow_req)); - -- set_bit(new_node->bitpos, tc_info->tc_entries_bitmap); - flow_cfg->nr_flows++; -- - return 0; - - free_leaf: -+ otx2_tc_del_from_flow_list(flow_cfg, new_node); -+ kfree_rcu(new_node, rcu); - if (new_node->is_act_police) { - mutex_lock(&nic->mbox.lock); - -@@ -878,16 +1066,13 @@ free_leaf: - static int otx2_tc_get_flow_stats(struct otx2_nic *nic, - struct flow_cls_offload *tc_flow_cmd) - { -- struct otx2_tc_info *tc_info = &nic->tc_info; - struct npc_mcam_get_stats_req *req; - struct npc_mcam_get_stats_rsp *rsp; - struct otx2_tc_flow_stats *stats; - struct otx2_tc_flow *flow_node; - int err; - -- flow_node = rhashtable_lookup_fast(&tc_info->flow_table, -- &tc_flow_cmd->cookie, -- tc_info->flow_ht_params); -+ flow_node = otx2_tc_get_entry_by_cookie(nic->flow_cfg, tc_flow_cmd->cookie); - if (!flow_node) { - netdev_info(nic->netdev, "tc flow not found for cookie %lx", - tc_flow_cmd->cookie); -@@ -1035,12 +1220,20 @@ static int otx2_setup_tc_block_ingress_cb(enum tc_setup_type type, - void *type_data, void *cb_priv) - { - struct otx2_nic *nic = cb_priv; -+ bool ntuple; - - if (!tc_cls_can_offload_and_chain0(nic->netdev, type_data)) - return -EOPNOTSUPP; - -+ ntuple = nic->netdev->features & NETIF_F_NTUPLE; - switch (type) { - case TC_SETUP_CLSFLOWER: -+ if (ntuple) { -+ netdev_warn(nic->netdev, -+ "Can't install TC flower offload rule when NTUPLE is active"); -+ return -EOPNOTSUPP; -+ } -+ - return otx2_setup_tc_cls_flower(nic, type_data); - case TC_SETUP_CLSMATCHALL: - return otx2_setup_tc_ingress_matchall(nic, type_data); -@@ -1123,18 +1316,8 @@ int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type, - } - EXPORT_SYMBOL(otx2_setup_tc); - --static const struct rhashtable_params tc_flow_ht_params = { -- .head_offset = offsetof(struct otx2_tc_flow, node), -- .key_offset = offsetof(struct otx2_tc_flow, cookie), -- .key_len = sizeof(((struct otx2_tc_flow *)0)->cookie), -- .automatic_shrinking = true, --}; -- - int otx2_init_tc(struct otx2_nic *nic) - { -- struct otx2_tc_info *tc = &nic->tc_info; -- int err; -- - /* Exclude receive queue 0 being used for police action */ - set_bit(0, &nic->rq_bmap); - -@@ -1144,25 +1327,54 @@ int otx2_init_tc(struct otx2_nic *nic) - return -EINVAL; - } - -- err = otx2_tc_alloc_ent_bitmap(nic); -- if (err) -- return err; -- -- tc->flow_ht_params = tc_flow_ht_params; -- err = rhashtable_init(&tc->flow_table, &tc->flow_ht_params); -- if (err) { -- kfree(tc->tc_entries_bitmap); -- tc->tc_entries_bitmap = NULL; -- } -- return err; -+ return 0; - } - EXPORT_SYMBOL(otx2_init_tc); - - void otx2_shutdown_tc(struct otx2_nic *nic) - { -- struct otx2_tc_info *tc = &nic->tc_info; -- -- kfree(tc->tc_entries_bitmap); -- rhashtable_destroy(&tc->flow_table); -+ otx2_destroy_tc_flow_list(nic); - } - EXPORT_SYMBOL(otx2_shutdown_tc); -+ -+static void otx2_tc_config_ingress_rule(struct otx2_nic *nic, -+ struct otx2_tc_flow *node) -+{ -+ struct npc_install_flow_req *req; -+ -+ if (otx2_tc_act_set_hw_police(nic, node)) -+ return; -+ -+ mutex_lock(&nic->mbox.lock); -+ -+ req = otx2_mbox_alloc_msg_npc_install_flow(&nic->mbox); -+ if (!req) -+ goto err; -+ -+ memcpy(req, &node->req, sizeof(struct npc_install_flow_req)); -+ -+ if (otx2_sync_mbox_msg(&nic->mbox)) -+ netdev_err(nic->netdev, -+ "Failed to install MCAM flow entry for ingress rule"); -+err: -+ mutex_unlock(&nic->mbox.lock); -+} -+ -+void otx2_tc_apply_ingress_police_rules(struct otx2_nic *nic) -+{ -+ struct otx2_flow_config *flow_cfg = nic->flow_cfg; -+ struct otx2_tc_flow *node; -+ -+ /* If any ingress policer rules exist for the interface then -+ * apply those rules. Ingress policer rules depend on bandwidth -+ * profiles linked to the receive queues. Since no receive queues -+ * exist when interface is down, ingress policer rules are stored -+ * and configured in hardware after all receive queues are allocated -+ * in otx2_open. -+ */ -+ list_for_each_entry(node, &flow_cfg->flow_list_tc, list) { -+ if (node->is_act_police) -+ otx2_tc_config_ingress_rule(nic, node); -+ } -+} -+EXPORT_SYMBOL(otx2_tc_apply_ingress_police_rules); -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 770391cefb4e4..abfa375b08878 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -576,6 +576,8 @@ struct rtl8169_tc_offsets { - enum rtl_flag { - RTL_FLAG_TASK_ENABLED = 0, - RTL_FLAG_TASK_RESET_PENDING, -+ RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, -+ RTL_FLAG_TASK_TX_TIMEOUT, - RTL_FLAG_MAX - }; - -@@ -3943,7 +3945,7 @@ static void rtl8169_tx_timeout(struct net_device *dev, unsigned int txqueue) - { - struct rtl8169_private *tp = netdev_priv(dev); - -- rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); -+ rtl_schedule_task(tp, RTL_FLAG_TASK_TX_TIMEOUT); - } - - static int rtl8169_tx_map(struct rtl8169_private *tp, const u32 *opts, u32 len, -@@ -4537,6 +4539,7 @@ static void rtl_task(struct work_struct *work) - { - struct rtl8169_private *tp = - container_of(work, struct rtl8169_private, wk.work); -+ int ret; - - rtnl_lock(); - -@@ -4544,9 +4547,21 @@ static void rtl_task(struct work_struct *work) - !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) - goto out_unlock; - -+ if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) { -+ /* ASPM compatibility issues are a typical reason for tx timeouts */ -+ ret = pci_disable_link_state(tp->pci_dev, PCIE_LINK_STATE_L1 | -+ PCIE_LINK_STATE_L0S); -+ if (!ret) -+ netdev_warn_once(tp->dev, "ASPM disabled on Tx timeout\n"); -+ goto reset; -+ } -+ - if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) { -+reset: - rtl_reset_work(tp); - netif_wake_queue(tp->dev); -+ } else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) { -+ rtl_reset_work(tp); - } - out_unlock: - rtnl_unlock(); -@@ -4580,7 +4595,7 @@ static void r8169_phylink_handler(struct net_device *ndev) - } else { - /* In few cases rx is broken after link-down otherwise */ - if (rtl_is_8125(tp)) -- rtl_reset_work(tp); -+ rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE); - pm_runtime_idle(d); - } - -@@ -4656,7 +4671,7 @@ static int rtl8169_close(struct net_device *dev) - rtl8169_down(tp); - rtl8169_rx_clear(tp); - -- cancel_work_sync(&tp->wk.work); -+ cancel_work(&tp->wk.work); - - free_irq(tp->irq, tp); - -@@ -4890,6 +4905,8 @@ static void rtl_remove_one(struct pci_dev *pdev) - if (pci_dev_run_wake(pdev)) - pm_runtime_get_noresume(&pdev->dev); - -+ cancel_work_sync(&tp->wk.work); -+ - unregister_netdev(tp->dev); - - if (tp->dash_type != RTL_DASH_NONE) -diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c -index 9a52283d77544..68cb5616ef991 100644 ---- a/drivers/net/ethernet/renesas/ravb_main.c -+++ b/drivers/net/ethernet/renesas/ravb_main.c -@@ -517,6 +517,15 @@ static void ravb_emac_init_gbeth(struct net_device *ndev) - { - struct ravb_private *priv = netdev_priv(ndev); - -+ if (priv->phy_interface == PHY_INTERFACE_MODE_MII) { -+ ravb_write(ndev, (1000 << 16) | CXR35_SEL_XMII_MII, CXR35); -+ ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, 0); -+ } else { -+ ravb_write(ndev, (1000 << 16) | CXR35_SEL_XMII_RGMII, CXR35); -+ ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, -+ CXR31_SEL_LINK0); -+ } -+ - /* Receive frame limit set register */ - ravb_write(ndev, GBETH_RX_BUFF_MAX + ETH_FCS_LEN, RFLR); - -@@ -539,14 +548,6 @@ static void ravb_emac_init_gbeth(struct net_device *ndev) - - /* E-MAC interrupt enable register */ - ravb_write(ndev, ECSIPR_ICDIP, ECSIPR); -- -- if (priv->phy_interface == PHY_INTERFACE_MODE_MII) { -- ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, 0); -- ravb_write(ndev, (1000 << 16) | CXR35_SEL_XMII_MII, CXR35); -- } else { -- ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, -- CXR31_SEL_LINK0); -- } - } - - static void ravb_emac_init_rcar(struct net_device *ndev) -@@ -1827,19 +1828,20 @@ static int ravb_open(struct net_device *ndev) - if (info->gptp) - ravb_ptp_init(ndev, priv->pdev); - -- netif_tx_start_all_queues(ndev); -- - /* PHY control start */ - error = ravb_phy_start(ndev); - if (error) - goto out_ptp_stop; - -+ netif_tx_start_all_queues(ndev); -+ - return 0; - - out_ptp_stop: - /* Stop PTP Clock driver */ - if (info->gptp) - ravb_ptp_stop(ndev); -+ ravb_stop_dma(ndev); - out_free_irq_mgmta: - if (!info->multi_irqs) - goto out_free_irq; -@@ -1890,6 +1892,12 @@ static void ravb_tx_timeout_work(struct work_struct *work) - struct net_device *ndev = priv->ndev; - int error; - -+ if (!rtnl_trylock()) { -+ usleep_range(1000, 2000); -+ schedule_work(&priv->work); -+ return; -+ } -+ - netif_tx_stop_all_queues(ndev); - - /* Stop PTP Clock driver */ -@@ -1923,7 +1931,7 @@ static void ravb_tx_timeout_work(struct work_struct *work) - */ - netdev_err(ndev, "%s: ravb_dmac_init() failed, error %d\n", - __func__, error); -- return; -+ goto out_unlock; - } - ravb_emac_init(ndev); - -@@ -1933,6 +1941,9 @@ out: - ravb_ptp_init(ndev, priv->pdev); - - netif_tx_start_all_queues(ndev); -+ -+out_unlock: -+ rtnl_unlock(); - } - - /* Packet transmit function for Ethernet AVB */ -@@ -2661,9 +2672,14 @@ static int ravb_probe(struct platform_device *pdev) - ndev->features = info->net_features; - ndev->hw_features = info->net_hw_features; - -- reset_control_deassert(rstc); -+ error = reset_control_deassert(rstc); -+ if (error) -+ goto out_free_netdev; -+ - pm_runtime_enable(&pdev->dev); -- pm_runtime_get_sync(&pdev->dev); -+ error = pm_runtime_resume_and_get(&pdev->dev); -+ if (error < 0) -+ goto out_rpm_disable; - - if (info->multi_irqs) { - if (info->err_mgmt_irqs) -@@ -2888,11 +2904,12 @@ out_disable_gptp_clk: - out_disable_refclk: - clk_disable_unprepare(priv->refclk); - out_release: -- free_netdev(ndev); -- - pm_runtime_put(&pdev->dev); -+out_rpm_disable: - pm_runtime_disable(&pdev->dev); - reset_control_assert(rstc); -+out_free_netdev: -+ free_netdev(ndev); - return error; - } - -@@ -2902,22 +2919,26 @@ static int ravb_remove(struct platform_device *pdev) - struct ravb_private *priv = netdev_priv(ndev); - const struct ravb_hw_info *info = priv->info; - -- /* Stop PTP Clock driver */ -- if (info->ccc_gac) -- ravb_ptp_stop(ndev); -- -- clk_disable_unprepare(priv->gptp_clk); -- clk_disable_unprepare(priv->refclk); -- -- /* Set reset mode */ -- ravb_write(ndev, CCC_OPC_RESET, CCC); - unregister_netdev(ndev); - if (info->nc_queues) - netif_napi_del(&priv->napi[RAVB_NC]); - netif_napi_del(&priv->napi[RAVB_BE]); -+ - ravb_mdio_release(priv); -+ -+ /* Stop PTP Clock driver */ -+ if (info->ccc_gac) -+ ravb_ptp_stop(ndev); -+ - dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat, - priv->desc_bat_dma); -+ -+ /* Set reset mode */ -+ ravb_write(ndev, CCC_OPC_RESET, CCC); -+ -+ clk_disable_unprepare(priv->gptp_clk); -+ clk_disable_unprepare(priv->refclk); -+ - pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - reset_control_assert(priv->rstc); -diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c -index ea4910ae0921a..6a7c1d325c464 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c -+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c -@@ -177,8 +177,10 @@ - #define MMC_XGMAC_RX_DISCARD_OCT_GB 0x1b4 - #define MMC_XGMAC_RX_ALIGN_ERR_PKT 0x1bc - -+#define MMC_XGMAC_TX_FPE_INTR_MASK 0x204 - #define MMC_XGMAC_TX_FPE_FRAG 0x208 - #define MMC_XGMAC_TX_HOLD_REQ 0x20c -+#define MMC_XGMAC_RX_FPE_INTR_MASK 0x224 - #define MMC_XGMAC_RX_PKT_ASSEMBLY_ERR 0x228 - #define MMC_XGMAC_RX_PKT_SMD_ERR 0x22c - #define MMC_XGMAC_RX_PKT_ASSEMBLY_OK 0x230 -@@ -352,6 +354,8 @@ static void dwxgmac_mmc_intr_all_mask(void __iomem *mmcaddr) - { - writel(0x0, mmcaddr + MMC_RX_INTR_MASK); - writel(0x0, mmcaddr + MMC_TX_INTR_MASK); -+ writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_TX_FPE_INTR_MASK); -+ writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_RX_FPE_INTR_MASK); - writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_RX_IPC_INTR_MASK); - } - -diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c -index 25ddfabc58f73..5b156c5bc04a5 100644 ---- a/drivers/nvme/host/core.c -+++ b/drivers/nvme/host/core.c -@@ -2058,6 +2058,13 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns, - if (ret) - return ret; - -+ if (id->ncap == 0) { -+ /* namespace not allocated or attached */ -+ info->is_removed = true; -+ ret = -ENODEV; -+ goto error; -+ } -+ - blk_mq_freeze_queue(ns->disk->queue); - lbaf = nvme_lbaf_index(id->flbas); - ns->lba_shift = id->lbaf[lbaf].ds; -@@ -2107,6 +2114,8 @@ out: - set_bit(NVME_NS_READY, &ns->flags); - ret = 0; - } -+ -+error: - kfree(id); - return ret; - } -diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c -index d4c566c1c8725..1c7fd05ce0280 100644 ---- a/drivers/pci/controller/dwc/pcie-qcom-ep.c -+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c -@@ -120,6 +120,7 @@ - - /* ELBI registers */ - #define ELBI_SYS_STTS 0x08 -+#define ELBI_CS2_ENABLE 0xa4 - - /* DBI registers */ - #define DBI_CON_STATUS 0x44 -@@ -252,6 +253,21 @@ static void qcom_pcie_dw_stop_link(struct dw_pcie *pci) - disable_irq(pcie_ep->perst_irq); - } - -+static void qcom_pcie_dw_write_dbi2(struct dw_pcie *pci, void __iomem *base, -+ u32 reg, size_t size, u32 val) -+{ -+ struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci); -+ int ret; -+ -+ writel(1, pcie_ep->elbi + ELBI_CS2_ENABLE); -+ -+ ret = dw_pcie_write(pci->dbi_base2 + reg, size, val); -+ if (ret) -+ dev_err(pci->dev, "Failed to write DBI2 register (0x%x): %d\n", reg, ret); -+ -+ writel(0, pcie_ep->elbi + ELBI_CS2_ENABLE); -+} -+ - static int qcom_pcie_enable_resources(struct qcom_pcie_ep *pcie_ep) - { - int ret; -@@ -446,6 +462,7 @@ static const struct dw_pcie_ops pci_ops = { - .link_up = qcom_pcie_dw_link_up, - .start_link = qcom_pcie_dw_start_link, - .stop_link = qcom_pcie_dw_stop_link, -+ .write_dbi2 = qcom_pcie_dw_write_dbi2, - }; - - static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev, -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index 48389785d9247..c132839d99dc8 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -6058,3 +6058,15 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size); - #endif -+ -+/* -+ * Devices known to require a longer delay before first config space access -+ * after reset recovery or resume from D3cold: -+ * -+ * VideoPropulsion (aka Genroco) Torrent QN16e MPEG QAM Modulator -+ */ -+static void pci_fixup_d3cold_delay_1sec(struct pci_dev *pdev) -+{ -+ pdev->d3cold_delay = 1000; -+} -+DECLARE_PCI_FIXUP_FINAL(0x5555, 0x0004, pci_fixup_d3cold_delay_1sec); -diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c -index 9e57f4c62e609..f1962866bb814 100644 ---- a/drivers/pinctrl/core.c -+++ b/drivers/pinctrl/core.c -@@ -1239,17 +1239,17 @@ static void pinctrl_link_add(struct pinctrl_dev *pctldev, - static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) - { - struct pinctrl_setting *setting, *setting2; -- struct pinctrl_state *old_state = p->state; -+ struct pinctrl_state *old_state = READ_ONCE(p->state); - int ret; - -- if (p->state) { -+ if (old_state) { - /* - * For each pinmux setting in the old state, forget SW's record - * of mux owner for that pingroup. Any pingroups which are - * still owned by the new state will be re-acquired by the call - * to pinmux_enable_setting() in the loop below. - */ -- list_for_each_entry(setting, &p->state->settings, node) { -+ list_for_each_entry(setting, &old_state->settings, node) { - if (setting->type != PIN_MAP_TYPE_MUX_GROUP) - continue; - pinmux_disable_setting(setting); -diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c -index 2ff7717530bf8..8a2f18fa3faf5 100644 ---- a/drivers/powercap/dtpm_cpu.c -+++ b/drivers/powercap/dtpm_cpu.c -@@ -24,7 +24,6 @@ - #include - #include - #include --#include - - struct dtpm_cpu { - struct dtpm dtpm; -@@ -104,8 +103,7 @@ static u64 get_pd_power_uw(struct dtpm *dtpm) - if (pd->table[i].frequency < freq) - continue; - -- return scale_pd_power_uw(pd_mask, pd->table[i].power * -- MICROWATT_PER_MILLIWATT); -+ return scale_pd_power_uw(pd_mask, pd->table[i].power); - } - - return 0; -@@ -122,11 +120,9 @@ static int update_pd_power_uw(struct dtpm *dtpm) - nr_cpus = cpumask_weight(&cpus); - - dtpm->power_min = em->table[0].power; -- dtpm->power_min *= MICROWATT_PER_MILLIWATT; - dtpm->power_min *= nr_cpus; - - dtpm->power_max = em->table[em->nr_perf_states - 1].power; -- dtpm->power_max *= MICROWATT_PER_MILLIWATT; - dtpm->power_max *= nr_cpus; - - return 0; -diff --git a/drivers/powercap/dtpm_devfreq.c b/drivers/powercap/dtpm_devfreq.c -index 91276761a31d9..612c3b59dd5be 100644 ---- a/drivers/powercap/dtpm_devfreq.c -+++ b/drivers/powercap/dtpm_devfreq.c -@@ -39,10 +39,8 @@ static int update_pd_power_uw(struct dtpm *dtpm) - struct em_perf_domain *pd = em_pd_get(dev); - - dtpm->power_min = pd->table[0].power; -- dtpm->power_min *= MICROWATT_PER_MILLIWATT; - - dtpm->power_max = pd->table[pd->nr_perf_states - 1].power; -- dtpm->power_max *= MICROWATT_PER_MILLIWATT; - - return 0; - } -@@ -54,13 +52,10 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit) - struct device *dev = devfreq->dev.parent; - struct em_perf_domain *pd = em_pd_get(dev); - unsigned long freq; -- u64 power; - int i; - - for (i = 0; i < pd->nr_perf_states; i++) { -- -- power = pd->table[i].power * MICROWATT_PER_MILLIWATT; -- if (power > power_limit) -+ if (pd->table[i].power > power_limit) - break; - } - -@@ -68,7 +63,7 @@ static u64 set_pd_power_limit(struct dtpm *dtpm, u64 power_limit) - - dev_pm_qos_update_request(&dtpm_devfreq->qos_req, freq); - -- power_limit = pd->table[i - 1].power * MICROWATT_PER_MILLIWATT; -+ power_limit = pd->table[i - 1].power; - - return power_limit; - } -@@ -110,7 +105,7 @@ static u64 get_pd_power_uw(struct dtpm *dtpm) - if (pd->table[i].frequency < freq) - continue; - -- power = pd->table[i].power * MICROWATT_PER_MILLIWATT; -+ power = pd->table[i].power; - power *= status.busy_time; - power >>= 10; - -diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index deed8c909a786..31b5273f43a71 100644 ---- a/drivers/scsi/sd.c -+++ b/drivers/scsi/sd.c -@@ -3834,8 +3834,15 @@ static int sd_resume(struct device *dev, bool runtime) - - static int sd_resume_system(struct device *dev) - { -- if (pm_runtime_suspended(dev)) -+ if (pm_runtime_suspended(dev)) { -+ struct scsi_disk *sdkp = dev_get_drvdata(dev); -+ struct scsi_device *sdp = sdkp ? sdkp->device : NULL; -+ -+ if (sdp && sdp->force_runtime_start_on_system_start) -+ pm_request_resume(dev); -+ - return 0; -+ } - - return sd_resume(dev, false); - } -diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c -index 151fef199c380..5d046be8b2dd5 100644 ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -3299,33 +3299,52 @@ void spi_unregister_controller(struct spi_controller *ctlr) - } - EXPORT_SYMBOL_GPL(spi_unregister_controller); - -+static inline int __spi_check_suspended(const struct spi_controller *ctlr) -+{ -+ return ctlr->flags & SPI_CONTROLLER_SUSPENDED ? -ESHUTDOWN : 0; -+} -+ -+static inline void __spi_mark_suspended(struct spi_controller *ctlr) -+{ -+ mutex_lock(&ctlr->bus_lock_mutex); -+ ctlr->flags |= SPI_CONTROLLER_SUSPENDED; -+ mutex_unlock(&ctlr->bus_lock_mutex); -+} -+ -+static inline void __spi_mark_resumed(struct spi_controller *ctlr) -+{ -+ mutex_lock(&ctlr->bus_lock_mutex); -+ ctlr->flags &= ~SPI_CONTROLLER_SUSPENDED; -+ mutex_unlock(&ctlr->bus_lock_mutex); -+} -+ - int spi_controller_suspend(struct spi_controller *ctlr) - { -- int ret; -+ int ret = 0; - - /* Basically no-ops for non-queued controllers */ -- if (!ctlr->queued) -- return 0; -- -- ret = spi_stop_queue(ctlr); -- if (ret) -- dev_err(&ctlr->dev, "queue stop failed\n"); -+ if (ctlr->queued) { -+ ret = spi_stop_queue(ctlr); -+ if (ret) -+ dev_err(&ctlr->dev, "queue stop failed\n"); -+ } - -+ __spi_mark_suspended(ctlr); - return ret; - } - EXPORT_SYMBOL_GPL(spi_controller_suspend); - - int spi_controller_resume(struct spi_controller *ctlr) - { -- int ret; -- -- if (!ctlr->queued) -- return 0; -+ int ret = 0; - -- ret = spi_start_queue(ctlr); -- if (ret) -- dev_err(&ctlr->dev, "queue restart failed\n"); -+ __spi_mark_resumed(ctlr); - -+ if (ctlr->queued) { -+ ret = spi_start_queue(ctlr); -+ if (ret) -+ dev_err(&ctlr->dev, "queue restart failed\n"); -+ } - return ret; - } - EXPORT_SYMBOL_GPL(spi_controller_resume); -@@ -4050,8 +4069,7 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s - ctlr->cur_msg = msg; - ret = __spi_pump_transfer_message(ctlr, msg, was_busy); - if (ret) -- goto out; -- -+ dev_err(&ctlr->dev, "noqueue transfer failed\n"); - ctlr->cur_msg = NULL; - ctlr->fallback = false; - -@@ -4067,7 +4085,6 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s - spi_idle_runtime_pm(ctlr); - } - --out: - mutex_unlock(&ctlr->io_mutex); - } - -@@ -4090,6 +4107,11 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) - int status; - struct spi_controller *ctlr = spi->controller; - -+ if (__spi_check_suspended(ctlr)) { -+ dev_warn_once(&spi->dev, "Attempted to sync while suspend\n"); -+ return -ESHUTDOWN; -+ } -+ - status = __spi_validate(spi, message); - if (status != 0) - return status; -diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c -index 21145eb8f2a9c..b398fba942964 100644 ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -486,6 +486,7 @@ static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg) - case SC16IS7XX_TXLVL_REG: - case SC16IS7XX_RXLVL_REG: - case SC16IS7XX_IOSTATE_REG: -+ case SC16IS7XX_IOCONTROL_REG: - return true; - default: - break; -@@ -1555,6 +1556,10 @@ static int sc16is7xx_probe(struct device *dev, - goto out_ports; - } - -+ ret = uart_get_rs485_mode(&s->p[i].port); -+ if (ret) -+ goto out_ports; -+ - /* Disable all interrupts */ - sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_IER_REG, 0); - /* Disable TX/RX */ -diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c -index 48bc8a4814ac4..d396ac8b9cedd 100644 ---- a/drivers/usb/core/config.c -+++ b/drivers/usb/core/config.c -@@ -61,7 +61,7 @@ static void usb_parse_ssp_isoc_endpoint_companion(struct device *ddev, - desc = (struct usb_ssp_isoc_ep_comp_descriptor *) buffer; - if (desc->bDescriptorType != USB_DT_SSP_ISOC_ENDPOINT_COMP || - size < USB_DT_SSP_ISOC_EP_COMP_SIZE) { -- dev_warn(ddev, "Invalid SuperSpeedPlus isoc endpoint companion" -+ dev_notice(ddev, "Invalid SuperSpeedPlus isoc endpoint companion" - "for config %d interface %d altsetting %d ep %d.\n", - cfgno, inum, asnum, ep->desc.bEndpointAddress); - return; -@@ -83,7 +83,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, - - if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP || - size < USB_DT_SS_EP_COMP_SIZE) { -- dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " -+ dev_notice(ddev, "No SuperSpeed endpoint companion for config %d " - " interface %d altsetting %d ep %d: " - "using minimum values\n", - cfgno, inum, asnum, ep->desc.bEndpointAddress); -@@ -109,13 +109,13 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, - - /* Check the various values */ - if (usb_endpoint_xfer_control(&ep->desc) && desc->bMaxBurst != 0) { -- dev_warn(ddev, "Control endpoint with bMaxBurst = %d in " -+ dev_notice(ddev, "Control endpoint with bMaxBurst = %d in " - "config %d interface %d altsetting %d ep %d: " - "setting to zero\n", desc->bMaxBurst, - cfgno, inum, asnum, ep->desc.bEndpointAddress); - ep->ss_ep_comp.bMaxBurst = 0; - } else if (desc->bMaxBurst > 15) { -- dev_warn(ddev, "Endpoint with bMaxBurst = %d in " -+ dev_notice(ddev, "Endpoint with bMaxBurst = %d in " - "config %d interface %d altsetting %d ep %d: " - "setting to 15\n", desc->bMaxBurst, - cfgno, inum, asnum, ep->desc.bEndpointAddress); -@@ -125,7 +125,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, - if ((usb_endpoint_xfer_control(&ep->desc) || - usb_endpoint_xfer_int(&ep->desc)) && - desc->bmAttributes != 0) { -- dev_warn(ddev, "%s endpoint with bmAttributes = %d in " -+ dev_notice(ddev, "%s endpoint with bmAttributes = %d in " - "config %d interface %d altsetting %d ep %d: " - "setting to zero\n", - usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Bulk", -@@ -134,7 +134,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, - ep->ss_ep_comp.bmAttributes = 0; - } else if (usb_endpoint_xfer_bulk(&ep->desc) && - desc->bmAttributes > 16) { -- dev_warn(ddev, "Bulk endpoint with more than 65536 streams in " -+ dev_notice(ddev, "Bulk endpoint with more than 65536 streams in " - "config %d interface %d altsetting %d ep %d: " - "setting to max\n", - cfgno, inum, asnum, ep->desc.bEndpointAddress); -@@ -142,7 +142,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, - } else if (usb_endpoint_xfer_isoc(&ep->desc) && - !USB_SS_SSP_ISOC_COMP(desc->bmAttributes) && - USB_SS_MULT(desc->bmAttributes) > 3) { -- dev_warn(ddev, "Isoc endpoint has Mult of %d in " -+ dev_notice(ddev, "Isoc endpoint has Mult of %d in " - "config %d interface %d altsetting %d ep %d: " - "setting to 3\n", - USB_SS_MULT(desc->bmAttributes), -@@ -160,7 +160,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, - else - max_tx = 999999; - if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { -- dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " -+ dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in " - "config %d interface %d altsetting %d ep %d: " - "setting to %d\n", - usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", -@@ -273,7 +273,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - else if (d->bLength >= USB_DT_ENDPOINT_SIZE) - n = USB_DT_ENDPOINT_SIZE; - else { -- dev_warn(ddev, "config %d interface %d altsetting %d has an " -+ dev_notice(ddev, "config %d interface %d altsetting %d has an " - "invalid endpoint descriptor of length %d, skipping\n", - cfgno, inum, asnum, d->bLength); - goto skip_to_next_endpoint_or_interface_descriptor; -@@ -281,7 +281,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - - i = d->bEndpointAddress & ~USB_ENDPOINT_DIR_MASK; - if (i >= 16 || i == 0) { -- dev_warn(ddev, "config %d interface %d altsetting %d has an " -+ dev_notice(ddev, "config %d interface %d altsetting %d has an " - "invalid endpoint with address 0x%X, skipping\n", - cfgno, inum, asnum, d->bEndpointAddress); - goto skip_to_next_endpoint_or_interface_descriptor; -@@ -293,7 +293,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - - /* Check for duplicate endpoint addresses */ - if (config_endpoint_is_duplicate(config, inum, asnum, d)) { -- dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", -+ dev_notice(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n", - cfgno, inum, asnum, d->bEndpointAddress); - goto skip_to_next_endpoint_or_interface_descriptor; - } -@@ -301,7 +301,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - /* Ignore some endpoints */ - if (udev->quirks & USB_QUIRK_ENDPOINT_IGNORE) { - if (usb_endpoint_is_ignored(udev, ifp, d)) { -- dev_warn(ddev, "config %d interface %d altsetting %d has an ignored endpoint with address 0x%X, skipping\n", -+ dev_notice(ddev, "config %d interface %d altsetting %d has an ignored endpoint with address 0x%X, skipping\n", - cfgno, inum, asnum, - d->bEndpointAddress); - goto skip_to_next_endpoint_or_interface_descriptor; -@@ -378,7 +378,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - } - } - if (d->bInterval < i || d->bInterval > j) { -- dev_warn(ddev, "config %d interface %d altsetting %d " -+ dev_notice(ddev, "config %d interface %d altsetting %d " - "endpoint 0x%X has an invalid bInterval %d, " - "changing to %d\n", - cfgno, inum, asnum, -@@ -391,7 +391,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - * them usable, we will try treating them as Interrupt endpoints. - */ - if (udev->speed == USB_SPEED_LOW && usb_endpoint_xfer_bulk(d)) { -- dev_warn(ddev, "config %d interface %d altsetting %d " -+ dev_notice(ddev, "config %d interface %d altsetting %d " - "endpoint 0x%X is Bulk; changing to Interrupt\n", - cfgno, inum, asnum, d->bEndpointAddress); - endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT; -@@ -408,7 +408,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - */ - maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize); - if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) { -- dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n", -+ dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n", - cfgno, inum, asnum, d->bEndpointAddress); - } - -@@ -439,7 +439,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - j = maxpacket_maxes[usb_endpoint_type(&endpoint->desc)]; - - if (maxp > j) { -- dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n", -+ dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n", - cfgno, inum, asnum, d->bEndpointAddress, maxp, j); - maxp = j; - endpoint->desc.wMaxPacketSize = cpu_to_le16(i | maxp); -@@ -452,7 +452,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, - */ - if (udev->speed == USB_SPEED_HIGH && usb_endpoint_xfer_bulk(d)) { - if (maxp != 512) -- dev_warn(ddev, "config %d interface %d altsetting %d " -+ dev_notice(ddev, "config %d interface %d altsetting %d " - "bulk endpoint 0x%X has invalid maxpacket %d\n", - cfgno, inum, asnum, d->bEndpointAddress, - maxp); -@@ -533,7 +533,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno, - i < intfc->num_altsetting; - (++i, ++alt)) { - if (alt->desc.bAlternateSetting == asnum) { -- dev_warn(ddev, "Duplicate descriptor for config %d " -+ dev_notice(ddev, "Duplicate descriptor for config %d " - "interface %d altsetting %d, skipping\n", - cfgno, inum, asnum); - goto skip_to_next_interface_descriptor; -@@ -559,7 +559,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno, - num_ep = num_ep_orig = alt->desc.bNumEndpoints; - alt->desc.bNumEndpoints = 0; /* Use as a counter */ - if (num_ep > USB_MAXENDPOINTS) { -- dev_warn(ddev, "too many endpoints for config %d interface %d " -+ dev_notice(ddev, "too many endpoints for config %d interface %d " - "altsetting %d: %d, using maximum allowed: %d\n", - cfgno, inum, asnum, num_ep, USB_MAXENDPOINTS); - num_ep = USB_MAXENDPOINTS; -@@ -590,7 +590,7 @@ static int usb_parse_interface(struct device *ddev, int cfgno, - } - - if (n != num_ep_orig) -- dev_warn(ddev, "config %d interface %d altsetting %d has %d " -+ dev_notice(ddev, "config %d interface %d altsetting %d has %d " - "endpoint descriptor%s, different from the interface " - "descriptor's value: %d\n", - cfgno, inum, asnum, n, plural(n), num_ep_orig); -@@ -625,7 +625,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - if (config->desc.bDescriptorType != USB_DT_CONFIG || - config->desc.bLength < USB_DT_CONFIG_SIZE || - config->desc.bLength > size) { -- dev_err(ddev, "invalid descriptor for config index %d: " -+ dev_notice(ddev, "invalid descriptor for config index %d: " - "type = 0x%X, length = %d\n", cfgidx, - config->desc.bDescriptorType, config->desc.bLength); - return -EINVAL; -@@ -636,7 +636,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - size -= config->desc.bLength; - - if (nintf > USB_MAXINTERFACES) { -- dev_warn(ddev, "config %d has too many interfaces: %d, " -+ dev_notice(ddev, "config %d has too many interfaces: %d, " - "using maximum allowed: %d\n", - cfgno, nintf, USB_MAXINTERFACES); - nintf = USB_MAXINTERFACES; -@@ -650,7 +650,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - (buffer2 += header->bLength, size2 -= header->bLength)) { - - if (size2 < sizeof(struct usb_descriptor_header)) { -- dev_warn(ddev, "config %d descriptor has %d excess " -+ dev_notice(ddev, "config %d descriptor has %d excess " - "byte%s, ignoring\n", - cfgno, size2, plural(size2)); - break; -@@ -658,7 +658,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - - header = (struct usb_descriptor_header *) buffer2; - if ((header->bLength > size2) || (header->bLength < 2)) { -- dev_warn(ddev, "config %d has an invalid descriptor " -+ dev_notice(ddev, "config %d has an invalid descriptor " - "of length %d, skipping remainder of the config\n", - cfgno, header->bLength); - break; -@@ -670,7 +670,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - - d = (struct usb_interface_descriptor *) header; - if (d->bLength < USB_DT_INTERFACE_SIZE) { -- dev_warn(ddev, "config %d has an invalid " -+ dev_notice(ddev, "config %d has an invalid " - "interface descriptor of length %d, " - "skipping\n", cfgno, d->bLength); - continue; -@@ -680,7 +680,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - - if ((dev->quirks & USB_QUIRK_HONOR_BNUMINTERFACES) && - n >= nintf_orig) { -- dev_warn(ddev, "config %d has more interface " -+ dev_notice(ddev, "config %d has more interface " - "descriptors, than it declares in " - "bNumInterfaces, ignoring interface " - "number: %d\n", cfgno, inum); -@@ -688,7 +688,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - } - - if (inum >= nintf_orig) -- dev_warn(ddev, "config %d has an invalid " -+ dev_notice(ddev, "config %d has an invalid " - "interface number: %d but max is %d\n", - cfgno, inum, nintf_orig - 1); - -@@ -713,14 +713,14 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - - d = (struct usb_interface_assoc_descriptor *)header; - if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) { -- dev_warn(ddev, -+ dev_notice(ddev, - "config %d has an invalid interface association descriptor of length %d, skipping\n", - cfgno, d->bLength); - continue; - } - - if (iad_num == USB_MAXIADS) { -- dev_warn(ddev, "found more Interface " -+ dev_notice(ddev, "found more Interface " - "Association Descriptors " - "than allocated for in " - "configuration %d\n", cfgno); -@@ -731,7 +731,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - - } else if (header->bDescriptorType == USB_DT_DEVICE || - header->bDescriptorType == USB_DT_CONFIG) -- dev_warn(ddev, "config %d contains an unexpected " -+ dev_notice(ddev, "config %d contains an unexpected " - "descriptor of type 0x%X, skipping\n", - cfgno, header->bDescriptorType); - -@@ -740,11 +740,11 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - config->desc.wTotalLength = cpu_to_le16(buffer2 - buffer0); - - if (n != nintf) -- dev_warn(ddev, "config %d has %d interface%s, different from " -+ dev_notice(ddev, "config %d has %d interface%s, different from " - "the descriptor's value: %d\n", - cfgno, n, plural(n), nintf_orig); - else if (n == 0) -- dev_warn(ddev, "config %d has no interfaces?\n", cfgno); -+ dev_notice(ddev, "config %d has no interfaces?\n", cfgno); - config->desc.bNumInterfaces = nintf = n; - - /* Check for missing interface numbers */ -@@ -754,7 +754,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - break; - } - if (j >= nintf) -- dev_warn(ddev, "config %d has no interface number " -+ dev_notice(ddev, "config %d has no interface number " - "%d\n", cfgno, i); - } - -@@ -762,7 +762,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - for (i = 0; i < nintf; ++i) { - j = nalts[i]; - if (j > USB_MAXALTSETTING) { -- dev_warn(ddev, "too many alternate settings for " -+ dev_notice(ddev, "too many alternate settings for " - "config %d interface %d: %d, " - "using maximum allowed: %d\n", - cfgno, inums[i], j, USB_MAXALTSETTING); -@@ -811,7 +811,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, - break; - } - if (n >= intfc->num_altsetting) -- dev_warn(ddev, "config %d interface %d has no " -+ dev_notice(ddev, "config %d interface %d has no " - "altsetting %d\n", cfgno, inums[i], j); - } - } -@@ -868,7 +868,7 @@ int usb_get_configuration(struct usb_device *dev) - int result; - - if (ncfg > USB_MAXCONFIG) { -- dev_warn(ddev, "too many configurations: %d, " -+ dev_notice(ddev, "too many configurations: %d, " - "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); - dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; - } -@@ -902,7 +902,7 @@ int usb_get_configuration(struct usb_device *dev) - "descriptor/%s: %d\n", cfgno, "start", result); - if (result != -EPIPE) - goto err; -- dev_err(ddev, "chopping to %d config(s)\n", cfgno); -+ dev_notice(ddev, "chopping to %d config(s)\n", cfgno); - dev->descriptor.bNumConfigurations = cfgno; - break; - } else if (result < 4) { -@@ -934,7 +934,7 @@ int usb_get_configuration(struct usb_device *dev) - goto err; - } - if (result < length) { -- dev_warn(ddev, "config index %d descriptor too short " -+ dev_notice(ddev, "config index %d descriptor too short " - "(expected %i, got %i)\n", cfgno, length, result); - length = result; - } -@@ -993,7 +993,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) - /* Get BOS descriptor */ - ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE); - if (ret < USB_DT_BOS_SIZE || bos->bLength < USB_DT_BOS_SIZE) { -- dev_err(ddev, "unable to get BOS descriptor or descriptor too short\n"); -+ dev_notice(ddev, "unable to get BOS descriptor or descriptor too short\n"); - if (ret >= 0) - ret = -ENOMSG; - kfree(bos); -@@ -1021,7 +1021,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) - - ret = usb_get_descriptor(dev, USB_DT_BOS, 0, buffer, total_len); - if (ret < total_len) { -- dev_err(ddev, "unable to get BOS descriptor set\n"); -+ dev_notice(ddev, "unable to get BOS descriptor set\n"); - if (ret >= 0) - ret = -ENOMSG; - goto err; -@@ -1046,8 +1046,8 @@ int usb_get_bos_descriptor(struct usb_device *dev) - } - - if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { -- dev_warn(ddev, "descriptor type invalid, skip\n"); -- continue; -+ dev_notice(ddev, "descriptor type invalid, skip\n"); -+ goto skip_to_next_descriptor; - } - - switch (cap_type) { -@@ -1081,6 +1081,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) - break; - } - -+skip_to_next_descriptor: - total_len -= length; - buffer += length; - } -diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c -index c9a101f0e8d01..c9438dc56f5fc 100644 ---- a/drivers/usb/host/xhci-plat.c -+++ b/drivers/usb/host/xhci-plat.c -@@ -184,7 +184,7 @@ static int xhci_plat_probe(struct platform_device *pdev) - int ret; - int irq; - struct xhci_plat_priv *priv = NULL; -- -+ bool of_match; - - if (usb_disabled()) - return -ENODEV; -@@ -305,16 +305,23 @@ static int xhci_plat_probe(struct platform_device *pdev) - &xhci->imod_interval); - } - -- hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0); -- if (IS_ERR(hcd->usb_phy)) { -- ret = PTR_ERR(hcd->usb_phy); -- if (ret == -EPROBE_DEFER) -- goto disable_clk; -- hcd->usb_phy = NULL; -- } else { -- ret = usb_phy_init(hcd->usb_phy); -- if (ret) -- goto disable_clk; -+ /* -+ * Drivers such as dwc3 manages PHYs themself (and rely on driver name -+ * matching for the xhci platform device). -+ */ -+ of_match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); -+ if (of_match) { -+ hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0); -+ if (IS_ERR(hcd->usb_phy)) { -+ ret = PTR_ERR(hcd->usb_phy); -+ if (ret == -EPROBE_DEFER) -+ goto disable_clk; -+ hcd->usb_phy = NULL; -+ } else { -+ ret = usb_phy_init(hcd->usb_phy); -+ if (ret) -+ goto disable_clk; -+ } - } - - hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node); -diff --git a/drivers/video/fbdev/sticore.h b/drivers/video/fbdev/sticore.h -index 0ebdd28a0b813..d83ab3ded5f3d 100644 ---- a/drivers/video/fbdev/sticore.h -+++ b/drivers/video/fbdev/sticore.h -@@ -231,7 +231,7 @@ struct sti_rom_font { - u8 height; - u8 font_type; /* language type */ - u8 bytes_per_char; -- u32 next_font; -+ s32 next_font; /* note: signed int */ - u8 underline_height; - u8 underline_pos; - u8 res008[2]; -diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c -index af9115d648092..00f8e349921d4 100644 ---- a/drivers/xen/events/events_base.c -+++ b/drivers/xen/events/events_base.c -@@ -1710,9 +1710,10 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl) - generic_handle_irq(irq); - } - --static void __xen_evtchn_do_upcall(void) -+int xen_evtchn_do_upcall(void) - { - struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); -+ int ret = vcpu_info->evtchn_upcall_pending ? IRQ_HANDLED : IRQ_NONE; - int cpu = smp_processor_id(); - struct evtchn_loop_ctrl ctrl = { 0 }; - -@@ -1744,25 +1745,10 @@ static void __xen_evtchn_do_upcall(void) - * above. - */ - __this_cpu_inc(irq_epoch); --} -- --void xen_evtchn_do_upcall(struct pt_regs *regs) --{ -- struct pt_regs *old_regs = set_irq_regs(regs); -- -- irq_enter(); -- -- __xen_evtchn_do_upcall(); - -- irq_exit(); -- set_irq_regs(old_regs); --} -- --void xen_hvm_evtchn_do_upcall(void) --{ -- __xen_evtchn_do_upcall(); -+ return ret; - } --EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall); -+EXPORT_SYMBOL_GPL(xen_evtchn_do_upcall); - - /* Rebind a new event channel to an existing irq. */ - void rebind_evtchn_irq(evtchn_port_t evtchn, int irq) -diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c -index cd07e3fed0faf..544d3f9010b92 100644 ---- a/drivers/xen/platform-pci.c -+++ b/drivers/xen/platform-pci.c -@@ -64,14 +64,13 @@ static uint64_t get_callback_via(struct pci_dev *pdev) - - static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id) - { -- xen_hvm_evtchn_do_upcall(); -- return IRQ_HANDLED; -+ return xen_evtchn_do_upcall(); - } - - static int xen_allocate_irq(struct pci_dev *pdev) - { - return request_irq(pdev->irq, do_hvm_evtchn_intr, -- IRQF_NOBALANCING | IRQF_TRIGGER_RISING, -+ IRQF_NOBALANCING | IRQF_SHARED, - "xen-platform-pci", pdev); - } - -diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index d1dae29a3d012..40152458e7b74 100644 ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -3493,6 +3493,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device - goto fail_alloc; - } - -+ btrfs_info(fs_info, "first mount of filesystem %pU", disk_super->fsid); - /* - * Verify the type first, if that or the checksum value are - * corrupted, we'll find out -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index e015e1e025b6e..dc6e3cce747c1 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -5236,6 +5236,7 @@ static int _btrfs_ioctl_send(struct inode *inode, void __user *argp, bool compat - arg->clone_sources = compat_ptr(args32.clone_sources); - arg->parent_root = args32.parent_root; - arg->flags = args32.flags; -+ arg->version = args32.version; - memcpy(arg->reserved, args32.reserved, - sizeof(args32.reserved)); - #else -diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c -index a248f46cfe728..4b052d4009d31 100644 ---- a/fs/btrfs/ref-verify.c -+++ b/fs/btrfs/ref-verify.c -@@ -788,6 +788,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info, - dump_ref_action(fs_info, ra); - kfree(ref); - kfree(ra); -+ kfree(re); - goto out_unlock; - } else if (be->num_refs == 0) { - btrfs_err(fs_info, -@@ -797,6 +798,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info, - dump_ref_action(fs_info, ra); - kfree(ref); - kfree(ra); -+ kfree(re); - goto out_unlock; - } - -diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c -index 547b5c2292186..4a4d65b5e24f7 100644 ---- a/fs/btrfs/send.c -+++ b/fs/btrfs/send.c -@@ -7885,7 +7885,7 @@ long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg) - } - - sctx->send_filp = fget(arg->send_fd); -- if (!sctx->send_filp) { -+ if (!sctx->send_filp || !(sctx->send_filp->f_mode & FMODE_WRITE)) { - ret = -EBADF; - goto out; - } -diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c -index 2c562febd801e..6fc5fa18d1ee6 100644 ---- a/fs/btrfs/super.c -+++ b/fs/btrfs/super.c -@@ -391,7 +391,10 @@ void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, - - static void btrfs_put_super(struct super_block *sb) - { -- close_ctree(btrfs_sb(sb)); -+ struct btrfs_fs_info *fs_info = btrfs_sb(sb); -+ -+ btrfs_info(fs_info, "last unmount of filesystem %pU", fs_info->fs_devices->fsid); -+ close_ctree(fs_info); - } - - enum { -diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c -index e62b4c139a72d..6fc2d99270c18 100644 ---- a/fs/btrfs/volumes.c -+++ b/fs/btrfs/volumes.c -@@ -3074,15 +3074,16 @@ struct extent_map *btrfs_get_chunk_map(struct btrfs_fs_info *fs_info, - read_unlock(&em_tree->lock); - - if (!em) { -- btrfs_crit(fs_info, "unable to find logical %llu length %llu", -+ btrfs_crit(fs_info, -+ "unable to find chunk map for logical %llu length %llu", - logical, length); - return ERR_PTR(-EINVAL); - } - -- if (em->start > logical || em->start + em->len < logical) { -+ if (em->start > logical || em->start + em->len <= logical) { - btrfs_crit(fs_info, -- "found a bad mapping, wanted %llu-%llu, found %llu-%llu", -- logical, length, em->start, em->start + em->len); -+ "found a bad chunk map, wanted %llu-%llu, found %llu-%llu", -+ logical, logical + length, em->start, em->start + em->len); - free_extent_map(em); - return ERR_PTR(-EINVAL); - } -diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c -index 4eb559a16c9ed..105c4a1d20a20 100644 ---- a/fs/iomap/direct-io.c -+++ b/fs/iomap/direct-io.c -@@ -94,7 +94,6 @@ ssize_t iomap_dio_complete(struct iomap_dio *dio) - if (offset + ret > dio->i_size && - !(dio->flags & IOMAP_DIO_WRITE)) - ret = dio->i_size - offset; -- iocb->ki_pos += ret; - } - - /* -@@ -120,18 +119,19 @@ ssize_t iomap_dio_complete(struct iomap_dio *dio) - } - - inode_dio_end(file_inode(iocb->ki_filp)); -- /* -- * If this is a DSYNC write, make sure we push it to stable storage now -- * that we've written data. -- */ -- if (ret > 0 && (dio->flags & IOMAP_DIO_NEED_SYNC)) -- ret = generic_write_sync(iocb, ret); -- -- if (ret > 0) -- ret += dio->done_before; -+ if (ret > 0) { -+ iocb->ki_pos += ret; - -+ /* -+ * If this is a DSYNC write, make sure we push it to stable -+ * storage now that we've written data. -+ */ -+ if (dio->flags & IOMAP_DIO_NEED_SYNC) -+ ret = generic_write_sync(iocb, ret); -+ if (ret > 0) -+ ret += dio->done_before; -+ } - kfree(dio); -- - return ret; - } - EXPORT_SYMBOL_GPL(iomap_dio_complete); -diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c -index 05516309ec3ab..7be51f9d2fa18 100644 ---- a/fs/smb/client/inode.c -+++ b/fs/smb/client/inode.c -@@ -772,6 +772,8 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_i - } - - if (S_ISLNK(fattr->cf_mode)) { -+ if (likely(data->symlink_target)) -+ fattr->cf_eof = strnlen(data->symlink_target, PATH_MAX); - fattr->cf_symlink_target = data->symlink_target; - data->symlink_target = NULL; - } -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index 4cc56e4695fbc..e628848a1df93 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -3424,6 +3424,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, - struct inode *inode = file_inode(file); - struct cifsInodeInfo *cifsi = CIFS_I(inode); - struct cifsFileInfo *cfile = file->private_data; -+ unsigned long long new_size; - long rc; - unsigned int xid; - __le64 eof; -@@ -3454,10 +3455,15 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, - /* - * do we also need to change the size of the file? - */ -- if (keep_size == false && i_size_read(inode) < offset + len) { -- eof = cpu_to_le64(offset + len); -+ new_size = offset + len; -+ if (keep_size == false && (unsigned long long)i_size_read(inode) < new_size) { -+ eof = cpu_to_le64(new_size); - rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, - cfile->fid.volatile_fid, cfile->pid, &eof); -+ if (rc >= 0) { -+ truncate_setsize(inode, new_size); -+ fscache_resize_cookie(cifs_inode_cookie(inode), new_size); -+ } - } - - zero_range_exit: -@@ -3852,6 +3858,9 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon, - if (rc < 0) - goto out_2; - -+ truncate_setsize(inode, old_eof + len); -+ fscache_resize_cookie(cifs_inode_cookie(inode), i_size_read(inode)); -+ - rc = smb2_copychunk_range(xid, cfile, cfile, off, count, off + len); - if (rc < 0) - goto out_2; -diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h -index 3dfb994312b1f..b79097b9070b3 100644 ---- a/include/linux/dma-fence.h -+++ b/include/linux/dma-fence.h -@@ -478,6 +478,21 @@ static inline bool dma_fence_is_later(struct dma_fence *f1, - return __dma_fence_is_later(f1->seqno, f2->seqno, f1->ops); - } - -+/** -+ * dma_fence_is_later_or_same - return true if f1 is later or same as f2 -+ * @f1: the first fence from the same context -+ * @f2: the second fence from the same context -+ * -+ * Returns true if f1 is chronologically later than f2 or the same fence. Both -+ * fences must be from the same context, since a seqno is not re-used across -+ * contexts. -+ */ -+static inline bool dma_fence_is_later_or_same(struct dma_fence *f1, -+ struct dma_fence *f2) -+{ -+ return f1 == f2 || dma_fence_is_later(f1, f2); -+} -+ - /** - * dma_fence_later - return the chronologically later fence - * @f1: the first fence from the same context -diff --git a/include/linux/irq.h b/include/linux/irq.h -index c3eb89606c2b1..06c692cc0accb 100644 ---- a/include/linux/irq.h -+++ b/include/linux/irq.h -@@ -215,8 +215,6 @@ struct irq_data { - * IRQD_SINGLE_TARGET - IRQ allows only a single affinity target - * IRQD_DEFAULT_TRIGGER_SET - Expected trigger already been set - * IRQD_CAN_RESERVE - Can use reservation mode -- * IRQD_MSI_NOMASK_QUIRK - Non-maskable MSI quirk for affinity change -- * required - * IRQD_HANDLE_ENFORCE_IRQCTX - Enforce that handle_irq_*() is only invoked - * from actual interrupt context. - * IRQD_AFFINITY_ON_ACTIVATE - Affinity is set on activation. Don't call -@@ -245,10 +243,9 @@ enum { - IRQD_SINGLE_TARGET = (1 << 24), - IRQD_DEFAULT_TRIGGER_SET = (1 << 25), - IRQD_CAN_RESERVE = (1 << 26), -- IRQD_MSI_NOMASK_QUIRK = (1 << 27), -- IRQD_HANDLE_ENFORCE_IRQCTX = (1 << 28), -- IRQD_AFFINITY_ON_ACTIVATE = (1 << 29), -- IRQD_IRQ_ENABLED_ON_SUSPEND = (1 << 30), -+ IRQD_HANDLE_ENFORCE_IRQCTX = (1 << 27), -+ IRQD_AFFINITY_ON_ACTIVATE = (1 << 28), -+ IRQD_IRQ_ENABLED_ON_SUSPEND = (1 << 29), - }; - - #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors) -@@ -423,21 +420,6 @@ static inline bool irqd_can_reserve(struct irq_data *d) - return __irqd_to_state(d) & IRQD_CAN_RESERVE; - } - --static inline void irqd_set_msi_nomask_quirk(struct irq_data *d) --{ -- __irqd_to_state(d) |= IRQD_MSI_NOMASK_QUIRK; --} -- --static inline void irqd_clr_msi_nomask_quirk(struct irq_data *d) --{ -- __irqd_to_state(d) &= ~IRQD_MSI_NOMASK_QUIRK; --} -- --static inline bool irqd_msi_nomask_quirk(struct irq_data *d) --{ -- return __irqd_to_state(d) & IRQD_MSI_NOMASK_QUIRK; --} -- - static inline void irqd_set_affinity_on_activate(struct irq_data *d) - { - __irqd_to_state(d) |= IRQD_AFFINITY_ON_ACTIVATE; -diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index 8fdd3cf971a30..8f918f9a1228d 100644 ---- a/include/linux/mmc/host.h -+++ b/include/linux/mmc/host.h -@@ -450,6 +450,7 @@ struct mmc_host { - unsigned int retune_paused:1; /* re-tuning is temporarily disabled */ - unsigned int retune_crc_disable:1; /* don't trigger retune upon crc */ - unsigned int can_dma_map_merge:1; /* merging can be used */ -+ unsigned int vqmmc_enabled:1; /* vqmmc regulator is enabled */ - - int rescan_disable; /* disable card detection */ - int rescan_entered; /* used with nonremovable devices */ -@@ -597,6 +598,8 @@ static inline int mmc_regulator_set_vqmmc(struct mmc_host *mmc, - #endif - - int mmc_regulator_get_supply(struct mmc_host *mmc); -+int mmc_regulator_enable_vqmmc(struct mmc_host *mmc); -+void mmc_regulator_disable_vqmmc(struct mmc_host *mmc); - - static inline int mmc_card_is_removable(struct mmc_host *host) - { -diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h -index fbf8c0d95968e..877395e075afe 100644 ---- a/include/linux/spi/spi.h -+++ b/include/linux/spi/spi.h -@@ -531,6 +531,7 @@ struct spi_controller { - #define SPI_CONTROLLER_MUST_TX BIT(4) /* Requires tx */ - - #define SPI_MASTER_GPIO_SS BIT(5) /* GPIO CS must select slave */ -+#define SPI_CONTROLLER_SUSPENDED BIT(6) /* Currently suspended */ - - /* Flag indicating if the allocation of this struct is devres-managed */ - bool devm_allocated; -diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h -index 5aabc36fb249b..fdc31fdb612da 100644 ---- a/include/scsi/scsi_device.h -+++ b/include/scsi/scsi_device.h -@@ -167,19 +167,25 @@ struct scsi_device { - * power state for system suspend/resume (suspend to RAM and - * hibernation) operations. - */ -- bool manage_system_start_stop; -+ unsigned manage_system_start_stop:1; - - /* - * If true, let the high-level device driver (sd) manage the device - * power state for runtime device suspand and resume operations. - */ -- bool manage_runtime_start_stop; -+ unsigned manage_runtime_start_stop:1; - - /* - * If true, let the high-level device driver (sd) manage the device - * power state for system shutdown (power off) operations. - */ -- bool manage_shutdown; -+ unsigned manage_shutdown:1; -+ -+ /* -+ * If set and if the device is runtime suspended, ask the high-level -+ * device driver (sd) to force a runtime resume of the device. -+ */ -+ unsigned force_runtime_start_on_system_start:1; - - unsigned removable:1; - unsigned changed:1; /* Data invalid due to media change */ -diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h -index 7837ba4fe7289..dcd50fb2164a1 100644 ---- a/include/uapi/linux/stddef.h -+++ b/include/uapi/linux/stddef.h -@@ -27,7 +27,7 @@ - union { \ - struct { MEMBERS } ATTRS; \ - struct TAG { MEMBERS } ATTRS NAME; \ -- } -+ } ATTRS - - /** - * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union -diff --git a/include/xen/events.h b/include/xen/events.h -index 344081e71584b..b303bd24e2a6c 100644 ---- a/include/xen/events.h -+++ b/include/xen/events.h -@@ -106,8 +106,7 @@ int irq_from_virq(unsigned int cpu, unsigned int virq); - evtchn_port_t evtchn_from_irq(unsigned irq); - - int xen_set_callback_via(uint64_t via); --void xen_evtchn_do_upcall(struct pt_regs *regs); --void xen_hvm_evtchn_do_upcall(void); -+int xen_evtchn_do_upcall(void); - - /* Bind a pirq for a physical interrupt to an irq. */ - int xen_bind_pirq_gsi_to_irq(unsigned gsi, -diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c -index bbcaac64038ef..0b78fac882b2b 100644 ---- a/kernel/irq/debugfs.c -+++ b/kernel/irq/debugfs.c -@@ -121,7 +121,6 @@ static const struct irq_bit_descr irqdata_states[] = { - BIT_MASK_DESCR(IRQD_AFFINITY_ON_ACTIVATE), - BIT_MASK_DESCR(IRQD_MANAGED_SHUTDOWN), - BIT_MASK_DESCR(IRQD_CAN_RESERVE), -- BIT_MASK_DESCR(IRQD_MSI_NOMASK_QUIRK), - - BIT_MASK_DESCR(IRQD_FORWARDED_TO_VCPU), - -diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c -index 77e513e2e5da7..4e462b5f7bbe8 100644 ---- a/kernel/irq/msi.c -+++ b/kernel/irq/msi.c -@@ -807,7 +807,6 @@ static int msi_handle_pci_fail(struct irq_domain *domain, struct msi_desc *desc, - - #define VIRQ_CAN_RESERVE 0x01 - #define VIRQ_ACTIVATE 0x02 --#define VIRQ_NOMASK_QUIRK 0x04 - - static int msi_init_virq(struct irq_domain *domain, int virq, unsigned int vflags) - { -@@ -816,8 +815,6 @@ static int msi_init_virq(struct irq_domain *domain, int virq, unsigned int vflag - - if (!(vflags & VIRQ_CAN_RESERVE)) { - irqd_clr_can_reserve(irqd); -- if (vflags & VIRQ_NOMASK_QUIRK) -- irqd_set_msi_nomask_quirk(irqd); - - /* - * If the interrupt is managed but no CPU is available to -@@ -877,15 +874,8 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, - * Interrupt can use a reserved vector and will not occupy - * a real device vector until the interrupt is requested. - */ -- if (msi_check_reservation_mode(domain, info, dev)) { -+ if (msi_check_reservation_mode(domain, info, dev)) - vflags |= VIRQ_CAN_RESERVE; -- /* -- * MSI affinity setting requires a special quirk (X86) when -- * reservation mode is active. -- */ -- if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK) -- vflags |= VIRQ_NOMASK_QUIRK; -- } - - msi_for_each_desc(desc, dev, MSI_DESC_NOTASSOCIATED) { - ops->set_desc(&arg, desc); -diff --git a/lib/errname.c b/lib/errname.c -index 67739b174a8cc..0c336b0f12f60 100644 ---- a/lib/errname.c -+++ b/lib/errname.c -@@ -111,9 +111,6 @@ static const char *names_0[] = { - E(ENOSPC), - E(ENOSR), - E(ENOSTR), --#ifdef ENOSYM -- E(ENOSYM), --#endif - E(ENOSYS), - E(ENOTBLK), - E(ENOTCONN), -@@ -144,9 +141,6 @@ static const char *names_0[] = { - #endif - E(EREMOTE), - E(EREMOTEIO), --#ifdef EREMOTERELEASE -- E(EREMOTERELEASE), --#endif - E(ERESTART), - E(ERFKILL), - E(EROFS), -diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c -index cbc4816ed7d83..ac53ef7eec915 100644 ---- a/net/ipv4/igmp.c -+++ b/net/ipv4/igmp.c -@@ -216,8 +216,10 @@ static void igmp_start_timer(struct ip_mc_list *im, int max_delay) - int tv = prandom_u32_max(max_delay); - - im->tm_running = 1; -- if (!mod_timer(&im->timer, jiffies+tv+2)) -- refcount_inc(&im->refcnt); -+ if (refcount_inc_not_zero(&im->refcnt)) { -+ if (mod_timer(&im->timer, jiffies + tv + 2)) -+ ip_ma_put(im); -+ } - } - - static void igmp_gq_start_timer(struct in_device *in_dev) -diff --git a/net/wireless/core.h b/net/wireless/core.h -index e1accacc6f233..ee980965a7cfb 100644 ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -297,6 +297,7 @@ struct cfg80211_cqm_config { - u32 rssi_hyst; - s32 last_rssi_event_value; - enum nl80211_cqm_rssi_threshold_event last_rssi_event_type; -+ bool use_range_api; - int n_rssi_thresholds; - s32 rssi_thresholds[]; - }; -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index b19b5acfaf3a9..42c858219b341 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -12574,10 +12574,6 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, - int i, n, low_index; - int err; - -- /* RSSI reporting disabled? */ -- if (!cqm_config) -- return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); -- - /* - * Obtain current RSSI value if possible, if not and no RSSI threshold - * event has been received yet, we should receive an event after a -@@ -12652,18 +12648,6 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) - return -EOPNOTSUPP; - -- if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) { -- if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */ -- return rdev_set_cqm_rssi_config(rdev, dev, 0, 0); -- -- return rdev_set_cqm_rssi_config(rdev, dev, -- thresholds[0], hysteresis); -- } -- -- if (!wiphy_ext_feature_isset(&rdev->wiphy, -- NL80211_EXT_FEATURE_CQM_RSSI_LIST)) -- return -EOPNOTSUPP; -- - if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */ - n_thresholds = 0; - -@@ -12671,6 +12655,20 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - old = rcu_dereference_protected(wdev->cqm_config, - lockdep_is_held(&wdev->mtx)); - -+ /* if already disabled just succeed */ -+ if (!n_thresholds && !old) -+ return 0; -+ -+ if (n_thresholds > 1) { -+ if (!wiphy_ext_feature_isset(&rdev->wiphy, -+ NL80211_EXT_FEATURE_CQM_RSSI_LIST) || -+ !rdev->ops->set_cqm_rssi_range_config) -+ return -EOPNOTSUPP; -+ } else { -+ if (!rdev->ops->set_cqm_rssi_config) -+ return -EOPNOTSUPP; -+ } -+ - if (n_thresholds) { - cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, - n_thresholds), -@@ -12685,13 +12683,26 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - memcpy(cqm_config->rssi_thresholds, thresholds, - flex_array_size(cqm_config, rssi_thresholds, - n_thresholds)); -+ cqm_config->use_range_api = n_thresholds > 1 || -+ !rdev->ops->set_cqm_rssi_config; - - rcu_assign_pointer(wdev->cqm_config, cqm_config); -+ -+ if (cqm_config->use_range_api) -+ err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); -+ else -+ err = rdev_set_cqm_rssi_config(rdev, dev, -+ thresholds[0], -+ hysteresis); - } else { - RCU_INIT_POINTER(wdev->cqm_config, NULL); -+ /* if enabled as range also disable via range */ -+ if (old->use_range_api) -+ err = rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); -+ else -+ err = rdev_set_cqm_rssi_config(rdev, dev, 0, 0); - } - -- err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); - if (err) { - rcu_assign_pointer(wdev->cqm_config, old); - kfree_rcu(cqm_config, rcu_head); -@@ -18758,10 +18769,11 @@ void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work) - wdev_lock(wdev); - cqm_config = rcu_dereference_protected(wdev->cqm_config, - lockdep_is_held(&wdev->mtx)); -- if (!wdev->cqm_config) -+ if (!cqm_config) - goto unlock; - -- cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); -+ if (cqm_config->use_range_api) -+ cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); - - rssi_level = cqm_config->last_rssi_event_value; - rssi_event = cqm_config->last_rssi_event_type; -diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c -index 54f4b593a1158..5aaf3dcecf27e 100644 ---- a/sound/pci/hda/hda_intel.c -+++ b/sound/pci/hda/hda_intel.c -@@ -2215,6 +2215,8 @@ static const struct snd_pci_quirk power_save_denylist[] = { - SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0), - /* https://bugs.launchpad.net/bugs/1821663 */ - SND_PCI_QUIRK(0x1631, 0xe017, "Packard Bell NEC IMEDIA 5204", 0), -+ /* KONTRON SinglePC may cause a stall at runtime resume */ -+ SND_PCI_QUIRK(0x1734, 0x1232, "KONTRON SinglePC", 0), - {} - }; - #endif /* CONFIG_PM */ -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index b63e12b661996..d1944c83b03a2 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -1986,6 +1986,7 @@ enum { - ALC887_FIXUP_ASUS_AUDIO, - ALC887_FIXUP_ASUS_HMIC, - ALCS1200A_FIXUP_MIC_VREF, -+ ALC888VD_FIXUP_MIC_100VREF, - }; - - static void alc889_fixup_coef(struct hda_codec *codec, -@@ -2539,6 +2540,13 @@ static const struct hda_fixup alc882_fixups[] = { - {} - } - }, -+ [ALC888VD_FIXUP_MIC_100VREF] = { -+ .type = HDA_FIXUP_PINCTLS, -+ .v.pins = (const struct hda_pintbl[]) { -+ { 0x18, PIN_VREF100 }, /* headset mic */ -+ {} -+ } -+ }, - }; - - static const struct snd_pci_quirk alc882_fixup_tbl[] = { -@@ -2608,6 +2616,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { - SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF), - - SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), -+ SND_PCI_QUIRK(0x10ec, 0x12d8, "iBase Elo Touch", ALC888VD_FIXUP_MIC_100VREF), - SND_PCI_QUIRK(0x13fe, 0x1009, "Advantech MIT-W101", ALC886_FIXUP_EAPD), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), - SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), -@@ -3255,6 +3264,7 @@ static void alc_disable_headset_jack_key(struct hda_codec *codec) - case 0x10ec0230: - case 0x10ec0236: - case 0x10ec0256: -+ case 0x10ec0257: - case 0x19e58326: - alc_write_coef_idx(codec, 0x48, 0x0); - alc_update_coef_idx(codec, 0x49, 0x0045, 0x0); -@@ -3284,6 +3294,7 @@ static void alc_enable_headset_jack_key(struct hda_codec *codec) - case 0x10ec0230: - case 0x10ec0236: - case 0x10ec0256: -+ case 0x10ec0257: - case 0x19e58326: - alc_write_coef_idx(codec, 0x48, 0xd011); - alc_update_coef_idx(codec, 0x49, 0x007f, 0x0045); -@@ -6495,6 +6506,7 @@ static void alc_combo_jack_hp_jd_restart(struct hda_codec *codec) - case 0x10ec0236: - case 0x10ec0255: - case 0x10ec0256: -+ case 0x10ec0257: - case 0x19e58326: - alc_update_coef_idx(codec, 0x1b, 0x8000, 1 << 15); /* Reset HP JD */ - alc_update_coef_idx(codec, 0x1b, 0x8000, 0 << 15); -diff --git a/tools/arch/parisc/include/uapi/asm/errno.h b/tools/arch/parisc/include/uapi/asm/errno.h -index 87245c584784e..8d94739d75c67 100644 ---- a/tools/arch/parisc/include/uapi/asm/errno.h -+++ b/tools/arch/parisc/include/uapi/asm/errno.h -@@ -75,7 +75,6 @@ - - /* We now return you to your regularly scheduled HPUX. */ - --#define ENOSYM 215 /* symbol does not exist in executable */ - #define ENOTSOCK 216 /* Socket operation on non-socket */ - #define EDESTADDRREQ 217 /* Destination address required */ - #define EMSGSIZE 218 /* Message too long */ -@@ -101,7 +100,6 @@ - #define ETIMEDOUT 238 /* Connection timed out */ - #define ECONNREFUSED 239 /* Connection refused */ - #define EREFUSED ECONNREFUSED /* for HP's NFS apparently */ --#define EREMOTERELEASE 240 /* Remote peer released connection */ - #define EHOSTDOWN 241 /* Host is down */ - #define EHOSTUNREACH 242 /* No route to host */ - -diff --git a/tools/testing/selftests/net/af_unix/diag_uid.c b/tools/testing/selftests/net/af_unix/diag_uid.c -index 5b88f7129fea4..79a3dd75590e8 100644 ---- a/tools/testing/selftests/net/af_unix/diag_uid.c -+++ b/tools/testing/selftests/net/af_unix/diag_uid.c -@@ -148,7 +148,6 @@ void receive_response(struct __test_metadata *_metadata, - .msg_iov = &iov, - .msg_iovlen = 1 - }; -- struct unix_diag_req *udr; - struct nlmsghdr *nlh; - int ret; - -diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c -index 24b21b15ed3fb..6ff3e732f449f 100644 ---- a/tools/testing/selftests/net/cmsg_sender.c -+++ b/tools/testing/selftests/net/cmsg_sender.c -@@ -416,9 +416,9 @@ int main(int argc, char *argv[]) - { - struct addrinfo hints, *ai; - struct iovec iov[1]; -+ unsigned char *buf; - struct msghdr msg; - char cbuf[1024]; -- char *buf; - int err; - int fd; - -diff --git a/tools/testing/selftests/net/ipsec.c b/tools/testing/selftests/net/ipsec.c -index 9a8229abfa026..be4a30a0d02ae 100644 ---- a/tools/testing/selftests/net/ipsec.c -+++ b/tools/testing/selftests/net/ipsec.c -@@ -2263,7 +2263,7 @@ static int check_results(void) - - int main(int argc, char **argv) - { -- unsigned int nr_process = 1; -+ long nr_process = 1; - int route_sock = -1, ret = KSFT_SKIP; - int test_desc_fd[2]; - uint32_t route_seq; -@@ -2284,7 +2284,7 @@ int main(int argc, char **argv) - exit_usage(argv); - } - -- if (nr_process > MAX_PROCESSES || !nr_process) { -+ if (nr_process > MAX_PROCESSES || nr_process < 1) { - printk("nr_process should be between [1; %u]", - MAX_PROCESSES); - exit_usage(argv); -diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c -index 7df6b9b6f9a84..e6b514cb7bdda 100644 ---- a/tools/testing/selftests/net/mptcp/mptcp_connect.c -+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c -@@ -18,6 +18,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -1050,15 +1051,11 @@ again: - - static void init_rng(void) - { -- int fd = open("/dev/urandom", O_RDONLY); - unsigned int foo; - -- if (fd > 0) { -- int ret = read(fd, &foo, sizeof(foo)); -- -- if (ret < 0) -- srand(fd + foo); -- close(fd); -+ if (getrandom(&foo, sizeof(foo), 0) == -1) { -+ perror("getrandom"); -+ exit(1); - } - - srand(foo); -diff --git a/tools/testing/selftests/net/mptcp/mptcp_inq.c b/tools/testing/selftests/net/mptcp/mptcp_inq.c -index 8672d898f8cda..218aac4673212 100644 ---- a/tools/testing/selftests/net/mptcp/mptcp_inq.c -+++ b/tools/testing/selftests/net/mptcp/mptcp_inq.c -@@ -18,6 +18,7 @@ - #include - - #include -+#include - #include - #include - #include -@@ -519,15 +520,11 @@ static int client(int unixfd) - - static void init_rng(void) - { -- int fd = open("/dev/urandom", O_RDONLY); - unsigned int foo; - -- if (fd > 0) { -- int ret = read(fd, &foo, sizeof(foo)); -- -- if (ret < 0) -- srand(fd + foo); -- close(fd); -+ if (getrandom(&foo, sizeof(foo), 0) == -1) { -+ perror("getrandom"); -+ exit(1); - } - - srand(foo); diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.66-67.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.66-67.patch deleted file mode 100644 index 38a86e856415..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.66-67.patch +++ /dev/null @@ -1,122 +0,0 @@ -diff --git a/Makefile b/Makefile -index 5d7e995d686c8..c27600b90cad2 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 66 -+SUBLEVEL = 67 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/net/wireless/core.h b/net/wireless/core.h -index ee980965a7cfb..e1accacc6f233 100644 ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -297,7 +297,6 @@ struct cfg80211_cqm_config { - u32 rssi_hyst; - s32 last_rssi_event_value; - enum nl80211_cqm_rssi_threshold_event last_rssi_event_type; -- bool use_range_api; - int n_rssi_thresholds; - s32 rssi_thresholds[]; - }; -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index 42c858219b341..b19b5acfaf3a9 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -12574,6 +12574,10 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, - int i, n, low_index; - int err; - -+ /* RSSI reporting disabled? */ -+ if (!cqm_config) -+ return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); -+ - /* - * Obtain current RSSI value if possible, if not and no RSSI threshold - * event has been received yet, we should receive an event after a -@@ -12648,6 +12652,18 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) - return -EOPNOTSUPP; - -+ if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) { -+ if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */ -+ return rdev_set_cqm_rssi_config(rdev, dev, 0, 0); -+ -+ return rdev_set_cqm_rssi_config(rdev, dev, -+ thresholds[0], hysteresis); -+ } -+ -+ if (!wiphy_ext_feature_isset(&rdev->wiphy, -+ NL80211_EXT_FEATURE_CQM_RSSI_LIST)) -+ return -EOPNOTSUPP; -+ - if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */ - n_thresholds = 0; - -@@ -12655,20 +12671,6 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - old = rcu_dereference_protected(wdev->cqm_config, - lockdep_is_held(&wdev->mtx)); - -- /* if already disabled just succeed */ -- if (!n_thresholds && !old) -- return 0; -- -- if (n_thresholds > 1) { -- if (!wiphy_ext_feature_isset(&rdev->wiphy, -- NL80211_EXT_FEATURE_CQM_RSSI_LIST) || -- !rdev->ops->set_cqm_rssi_range_config) -- return -EOPNOTSUPP; -- } else { -- if (!rdev->ops->set_cqm_rssi_config) -- return -EOPNOTSUPP; -- } -- - if (n_thresholds) { - cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, - n_thresholds), -@@ -12683,26 +12685,13 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - memcpy(cqm_config->rssi_thresholds, thresholds, - flex_array_size(cqm_config, rssi_thresholds, - n_thresholds)); -- cqm_config->use_range_api = n_thresholds > 1 || -- !rdev->ops->set_cqm_rssi_config; - - rcu_assign_pointer(wdev->cqm_config, cqm_config); -- -- if (cqm_config->use_range_api) -- err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); -- else -- err = rdev_set_cqm_rssi_config(rdev, dev, -- thresholds[0], -- hysteresis); - } else { - RCU_INIT_POINTER(wdev->cqm_config, NULL); -- /* if enabled as range also disable via range */ -- if (old->use_range_api) -- err = rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); -- else -- err = rdev_set_cqm_rssi_config(rdev, dev, 0, 0); - } - -+ err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); - if (err) { - rcu_assign_pointer(wdev->cqm_config, old); - kfree_rcu(cqm_config, rcu_head); -@@ -18769,11 +18758,10 @@ void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work) - wdev_lock(wdev); - cqm_config = rcu_dereference_protected(wdev->cqm_config, - lockdep_is_held(&wdev->mtx)); -- if (!cqm_config) -+ if (!wdev->cqm_config) - goto unlock; - -- if (cqm_config->use_range_api) -- cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); -+ cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); - - rssi_level = cqm_config->last_rssi_event_value; - rssi_event = cqm_config->last_rssi_event_type; diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.67-68.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.67-68.patch deleted file mode 100644 index 78edec2836c3..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.67-68.patch +++ /dev/null @@ -1,9166 +0,0 @@ -diff --git a/Documentation/ABI/testing/sysfs-bus-optee-devices b/Documentation/ABI/testing/sysfs-bus-optee-devices -index 0f58701367b66..af31e5a22d89f 100644 ---- a/Documentation/ABI/testing/sysfs-bus-optee-devices -+++ b/Documentation/ABI/testing/sysfs-bus-optee-devices -@@ -6,3 +6,12 @@ Description: - OP-TEE bus provides reference to registered drivers under this directory. The - matches Trusted Application (TA) driver and corresponding TA in secure OS. Drivers - are free to create needed API under optee-ta- directory. -+ -+What: /sys/bus/tee/devices/optee-ta-/need_supplicant -+Date: November 2023 -+KernelVersion: 6.7 -+Contact: op-tee@lists.trustedfirmware.org -+Description: -+ Allows to distinguish whether an OP-TEE based TA/device requires user-space -+ tee-supplicant to function properly or not. This attribute will be present for -+ devices which depend on tee-supplicant to be running. -diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml -index 509d20c091af8..6a206111d4e0f 100644 ---- a/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml -+++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml -@@ -62,6 +62,9 @@ properties: - - description: MPM pin number - - description: GIC SPI number for the MPM pin - -+ '#power-domain-cells': -+ const: 0 -+ - required: - - compatible - - reg -@@ -93,4 +96,5 @@ examples: - <86 183>, - <90 260>, - <91 260>; -+ #power-domain-cells = <0>; - }; -diff --git a/Makefile b/Makefile -index c27600b90cad2..2a8ad0cec2f1c 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 67 -+SUBLEVEL = 68 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/imx28-xea.dts b/arch/arm/boot/dts/imx28-xea.dts -index a400c108f66a2..6c5e6856648af 100644 ---- a/arch/arm/boot/dts/imx28-xea.dts -+++ b/arch/arm/boot/dts/imx28-xea.dts -@@ -8,6 +8,7 @@ - #include "imx28-lwe.dtsi" - - / { -+ model = "Liebherr XEA board"; - compatible = "lwn,imx28-xea", "fsl,imx28"; - }; - -diff --git a/arch/arm/boot/dts/imx6ul-pico.dtsi b/arch/arm/boot/dts/imx6ul-pico.dtsi -index 357ffb2f5ad61..dd6790852b0d6 100644 ---- a/arch/arm/boot/dts/imx6ul-pico.dtsi -+++ b/arch/arm/boot/dts/imx6ul-pico.dtsi -@@ -121,6 +121,8 @@ - max-speed = <100>; - interrupt-parent = <&gpio5>; - interrupts = <6 IRQ_TYPE_LEVEL_LOW>; -+ clocks = <&clks IMX6UL_CLK_ENET_REF>; -+ clock-names = "rmii-ref"; - }; - }; - }; -diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi -index 667568aa4326a..45947707134b8 100644 ---- a/arch/arm/boot/dts/imx7s.dtsi -+++ b/arch/arm/boot/dts/imx7s.dtsi -@@ -454,7 +454,7 @@ - }; - - gpt1: timer@302d0000 { -- compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; -+ compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; - reg = <0x302d0000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_GPT1_ROOT_CLK>, -@@ -463,7 +463,7 @@ - }; - - gpt2: timer@302e0000 { -- compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; -+ compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; - reg = <0x302e0000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_GPT2_ROOT_CLK>, -@@ -473,7 +473,7 @@ - }; - - gpt3: timer@302f0000 { -- compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; -+ compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; - reg = <0x302f0000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_GPT3_ROOT_CLK>, -@@ -483,7 +483,7 @@ - }; - - gpt4: timer@30300000 { -- compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; -+ compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; - reg = <0x30300000 0x10000>; - interrupts = ; - clocks = <&clks IMX7D_GPT4_ROOT_CLK>, -diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c -index b9efe9da06e0b..3d76e8c28c51d 100644 ---- a/arch/arm/mach-imx/mmdc.c -+++ b/arch/arm/mach-imx/mmdc.c -@@ -502,6 +502,10 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b - - name = devm_kasprintf(&pdev->dev, - GFP_KERNEL, "mmdc%d", ret); -+ if (!name) { -+ ret = -ENOMEM; -+ goto pmu_release_id; -+ } - - pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; - pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data; -@@ -524,9 +528,10 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b - - pmu_register_err: - pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret); -- ida_simple_remove(&mmdc_ida, pmu_mmdc->id); - cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); - hrtimer_cancel(&pmu_mmdc->hrtimer); -+pmu_release_id: -+ ida_simple_remove(&mmdc_ida, pmu_mmdc->id); - pmu_free: - kfree(pmu_mmdc); - return ret; -diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi -index 25630a395db56..8c34b3e12a66a 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi -@@ -1301,6 +1301,7 @@ - phys = <&usb3_phy0>, <&usb3_phy0>; - phy-names = "usb2-phy", "usb3-phy"; - snps,gfladj-refclk-lpm-sel-quirk; -+ snps,parkmode-disable-ss-quirk; - }; - - }; -@@ -1343,6 +1344,7 @@ - phys = <&usb3_phy1>, <&usb3_phy1>; - phy-names = "usb2-phy", "usb3-phy"; - snps,gfladj-refclk-lpm-sel-quirk; -+ snps,parkmode-disable-ss-quirk; - }; - }; - -diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi -index bf8f02c1535c1..e642cb7d54d77 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi -@@ -1431,7 +1431,7 @@ - phys = <&usb3_phy0>, <&usb3_phy0>; - phy-names = "usb2-phy", "usb3-phy"; - power-domains = <&pgc_otg1>; -- usb3-resume-missing-cas; -+ snps,parkmode-disable-ss-quirk; - status = "disabled"; - }; - -@@ -1463,7 +1463,7 @@ - phys = <&usb3_phy1>, <&usb3_phy1>; - phy-names = "usb2-phy", "usb3-phy"; - power-domains = <&pgc_otg2>; -- usb3-resume-missing-cas; -+ snps,parkmode-disable-ss-quirk; - status = "disabled"; - }; - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index d3f9eab2b7844..2c35ed0734a47 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -72,7 +72,7 @@ - }; - }; - -- memory { -+ memory@40000000 { - reg = <0 0x40000000 0 0x40000000>; - }; - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -index 36722cabe626e..f9313b697ac12 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -@@ -54,7 +54,7 @@ - }; - }; - -- memory { -+ memory@40000000 { - reg = <0 0x40000000 0 0x20000000>; - }; - -diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts -index 0b5f154007be8..49c7185243cc1 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts -+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts -@@ -43,7 +43,7 @@ - id-gpio = <&pio 16 GPIO_ACTIVE_HIGH>; - }; - -- usb_p1_vbus: regulator@0 { -+ usb_p1_vbus: regulator-usb-p1 { - compatible = "regulator-fixed"; - regulator-name = "usb_vbus"; - regulator-min-microvolt = <5000000>; -@@ -52,7 +52,7 @@ - enable-active-high; - }; - -- usb_p0_vbus: regulator@1 { -+ usb_p0_vbus: regulator-usb-p0 { - compatible = "regulator-fixed"; - regulator-name = "vbus"; - regulator-min-microvolt = <5000000>; -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts -index 52dc4a50e34d3..2ca0da51efaa0 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts -+++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts -@@ -30,14 +30,14 @@ - #address-cells = <2>; - #size-cells = <2>; - ranges; -- scp_mem_reserved: scp_mem_region { -+ scp_mem_reserved: memory@50000000 { - compatible = "shared-dma-pool"; - reg = <0 0x50000000 0 0x2900000>; - no-map; - }; - }; - -- ntc@0 { -+ thermal-sensor { - compatible = "murata,ncp03wf104"; - pullup-uv = <1800000>; - pullup-ohm = <390000>; -@@ -139,8 +139,8 @@ - }; - - &pio { -- i2c_pins_0: i2c0{ -- pins_i2c{ -+ i2c_pins_0: i2c0 { -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -148,8 +148,8 @@ - }; - }; - -- i2c_pins_1: i2c1{ -- pins_i2c{ -+ i2c_pins_1: i2c1 { -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -157,8 +157,8 @@ - }; - }; - -- i2c_pins_2: i2c2{ -- pins_i2c{ -+ i2c_pins_2: i2c2 { -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -166,8 +166,8 @@ - }; - }; - -- i2c_pins_3: i2c3{ -- pins_i2c{ -+ i2c_pins_3: i2c3 { -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -175,8 +175,8 @@ - }; - }; - -- i2c_pins_4: i2c4{ -- pins_i2c{ -+ i2c_pins_4: i2c4 { -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -184,8 +184,8 @@ - }; - }; - -- i2c_pins_5: i2c5{ -- pins_i2c{ -+ i2c_pins_5: i2c5 { -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -193,8 +193,8 @@ - }; - }; - -- spi_pins_0: spi0{ -- pins_spi{ -+ spi_pins_0: spi0 { -+ pins_spi { - pinmux = , - , - , -@@ -308,8 +308,8 @@ - }; - }; - -- spi_pins_1: spi1{ -- pins_spi{ -+ spi_pins_1: spi1 { -+ pins_spi { - pinmux = , - , - , -@@ -318,8 +318,8 @@ - }; - }; - -- spi_pins_2: spi2{ -- pins_spi{ -+ spi_pins_2: spi2 { -+ pins_spi { - pinmux = , - , - , -@@ -328,8 +328,8 @@ - }; - }; - -- spi_pins_3: spi3{ -- pins_spi{ -+ spi_pins_3: spi3 { -+ pins_spi { - pinmux = , - , - , -@@ -338,8 +338,8 @@ - }; - }; - -- spi_pins_4: spi4{ -- pins_spi{ -+ spi_pins_4: spi4 { -+ pins_spi { - pinmux = , - , - , -@@ -348,8 +348,8 @@ - }; - }; - -- spi_pins_5: spi5{ -- pins_spi{ -+ spi_pins_5: spi5 { -+ pins_spi { - pinmux = , - , - , -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi -index 3ac83be536274..dccf367c7ec6c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi -@@ -101,6 +101,8 @@ - - &dsi0 { - status = "okay"; -+ /delete-property/#size-cells; -+ /delete-property/#address-cells; - /delete-node/panel@0; - ports { - port { -@@ -437,20 +439,20 @@ - }; - - touchscreen_pins: touchscreen-pins { -- touch_int_odl { -+ touch-int-odl { - pinmux = ; - input-enable; - bias-pull-up; - }; - -- touch_rst_l { -+ touch-rst-l { - pinmux = ; - output-high; - }; - }; - - trackpad_pins: trackpad-pins { -- trackpad_int { -+ trackpad-int { - pinmux = ; - input-enable; - bias-disable; /* pulled externally */ -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi -index 632fd89e75969..a428a581c93a8 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi -@@ -108,7 +108,7 @@ - #size-cells = <2>; - ranges; - -- scp_mem_reserved: scp_mem_region { -+ scp_mem_reserved: memory@50000000 { - compatible = "shared-dma-pool"; - reg = <0 0x50000000 0 0x2900000>; - no-map; -@@ -423,7 +423,7 @@ - - &pio { - aud_pins_default: audiopins { -- pins_bus { -+ pins-bus { - pinmux = , - , - , -@@ -445,7 +445,7 @@ - }; - - aud_pins_tdm_out_on: audiotdmouton { -- pins_bus { -+ pins-bus { - pinmux = , - , - , -@@ -457,7 +457,7 @@ - }; - - aud_pins_tdm_out_off: audiotdmoutoff { -- pins_bus { -+ pins-bus { - pinmux = , - , - , -@@ -471,13 +471,13 @@ - }; - - bt_pins: bt-pins { -- pins_bt_en { -+ pins-bt-en { - pinmux = ; - output-low; - }; - }; - -- ec_ap_int_odl: ec_ap_int_odl { -+ ec_ap_int_odl: ec-ap-int-odl { - pins1 { - pinmux = ; - input-enable; -@@ -485,7 +485,7 @@ - }; - }; - -- h1_int_od_l: h1_int_od_l { -+ h1_int_od_l: h1-int-od-l { - pins1 { - pinmux = ; - input-enable; -@@ -493,7 +493,7 @@ - }; - - i2c0_pins: i2c0 { -- pins_bus { -+ pins-bus { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -502,7 +502,7 @@ - }; - - i2c1_pins: i2c1 { -- pins_bus { -+ pins-bus { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -511,7 +511,7 @@ - }; - - i2c2_pins: i2c2 { -- pins_bus { -+ pins-bus { - pinmux = , - ; - bias-disable; -@@ -520,7 +520,7 @@ - }; - - i2c3_pins: i2c3 { -- pins_bus { -+ pins-bus { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -529,7 +529,7 @@ - }; - - i2c4_pins: i2c4 { -- pins_bus { -+ pins-bus { - pinmux = , - ; - bias-disable; -@@ -538,7 +538,7 @@ - }; - - i2c5_pins: i2c5 { -- pins_bus { -+ pins-bus { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -547,7 +547,7 @@ - }; - - i2c6_pins: i2c6 { -- pins_bus { -+ pins-bus { - pinmux = , - ; - bias-disable; -@@ -555,7 +555,7 @@ - }; - - mmc0_pins_default: mmc0-pins-default { -- pins_cmd_dat { -+ pins-cmd-dat { - pinmux = , - , - , -@@ -570,13 +570,13 @@ - mediatek,pull-up-adv = <01>; - }; - -- pins_clk { -+ pins-clk { - pinmux = ; - drive-strength = ; - mediatek,pull-down-adv = <10>; - }; - -- pins_rst { -+ pins-rst { - pinmux = ; - drive-strength = ; - mediatek,pull-down-adv = <01>; -@@ -584,7 +584,7 @@ - }; - - mmc0_pins_uhs: mmc0-pins-uhs { -- pins_cmd_dat { -+ pins-cmd-dat { - pinmux = , - , - , -@@ -599,19 +599,19 @@ - mediatek,pull-up-adv = <01>; - }; - -- pins_clk { -+ pins-clk { - pinmux = ; - drive-strength = ; - mediatek,pull-down-adv = <10>; - }; - -- pins_ds { -+ pins-ds { - pinmux = ; - drive-strength = ; - mediatek,pull-down-adv = <10>; - }; - -- pins_rst { -+ pins-rst { - pinmux = ; - drive-strength = ; - mediatek,pull-up-adv = <01>; -@@ -619,7 +619,7 @@ - }; - - mmc1_pins_default: mmc1-pins-default { -- pins_cmd_dat { -+ pins-cmd-dat { - pinmux = , - , - , -@@ -629,7 +629,7 @@ - mediatek,pull-up-adv = <10>; - }; - -- pins_clk { -+ pins-clk { - pinmux = ; - input-enable; - mediatek,pull-down-adv = <10>; -@@ -637,7 +637,7 @@ - }; - - mmc1_pins_uhs: mmc1-pins-uhs { -- pins_cmd_dat { -+ pins-cmd-dat { - pinmux = , - , - , -@@ -648,7 +648,7 @@ - mediatek,pull-up-adv = <10>; - }; - -- pins_clk { -+ pins-clk { - pinmux = ; - drive-strength = ; - mediatek,pull-down-adv = <10>; -@@ -656,15 +656,15 @@ - }; - }; - -- panel_pins_default: panel_pins_default { -- panel_reset { -+ panel_pins_default: panel-pins-default { -+ panel-reset { - pinmux = ; - output-low; - bias-pull-up; - }; - }; - -- pwm0_pin_default: pwm0_pin_default { -+ pwm0_pin_default: pwm0-pin-default { - pins1 { - pinmux = ; - output-high; -@@ -676,14 +676,14 @@ - }; - - scp_pins: scp { -- pins_scp_uart { -+ pins-scp-uart { - pinmux = , - ; - }; - }; - - spi0_pins: spi0 { -- pins_spi{ -+ pins-spi { - pinmux = , - , - , -@@ -693,7 +693,7 @@ - }; - - spi1_pins: spi1 { -- pins_spi{ -+ pins-spi { - pinmux = , - , - , -@@ -703,20 +703,20 @@ - }; - - spi2_pins: spi2 { -- pins_spi{ -+ pins-spi { - pinmux = , - , - ; - bias-disable; - }; -- pins_spi_mi { -+ pins-spi-mi { - pinmux = ; - mediatek,pull-down-adv = <00>; - }; - }; - - spi3_pins: spi3 { -- pins_spi{ -+ pins-spi { - pinmux = , - , - , -@@ -726,7 +726,7 @@ - }; - - spi4_pins: spi4 { -- pins_spi{ -+ pins-spi { - pinmux = , - , - , -@@ -736,7 +736,7 @@ - }; - - spi5_pins: spi5 { -- pins_spi{ -+ pins-spi { - pinmux = , - , - , -@@ -746,63 +746,63 @@ - }; - - uart0_pins_default: uart0-pins-default { -- pins_rx { -+ pins-rx { - pinmux = ; - input-enable; - bias-pull-up; - }; -- pins_tx { -+ pins-tx { - pinmux = ; - }; - }; - - uart1_pins_default: uart1-pins-default { -- pins_rx { -+ pins-rx { - pinmux = ; - input-enable; - bias-pull-up; - }; -- pins_tx { -+ pins-tx { - pinmux = ; - }; -- pins_rts { -+ pins-rts { - pinmux = ; - output-enable; - }; -- pins_cts { -+ pins-cts { - pinmux = ; - input-enable; - }; - }; - - uart1_pins_sleep: uart1-pins-sleep { -- pins_rx { -+ pins-rx { - pinmux = ; - input-enable; - bias-pull-up; - }; -- pins_tx { -+ pins-tx { - pinmux = ; - }; -- pins_rts { -+ pins-rts { - pinmux = ; - output-enable; - }; -- pins_cts { -+ pins-cts { - pinmux = ; - input-enable; - }; - }; - - wifi_pins_pwrseq: wifi-pins-pwrseq { -- pins_wifi_enable { -+ pins-wifi-enable { - pinmux = ; - output-low; - }; - }; - - wifi_pins_wakeup: wifi-pins-wakeup { -- pins_wifi_wakeup { -+ pins-wifi-wakeup { - pinmux = ; - input-enable; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts -index a1d01639df30a..dd8d39861d9ca 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts -+++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts -@@ -178,7 +178,7 @@ - - &pio { - i2c_pins_0: i2c0 { -- pins_i2c{ -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -187,7 +187,7 @@ - }; - - i2c_pins_1: i2c1 { -- pins_i2c{ -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -196,7 +196,7 @@ - }; - - i2c_pins_2: i2c2 { -- pins_i2c{ -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -205,7 +205,7 @@ - }; - - i2c_pins_3: i2c3 { -- pins_i2c{ -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -214,7 +214,7 @@ - }; - - i2c_pins_4: i2c4 { -- pins_i2c{ -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -@@ -223,7 +223,7 @@ - }; - - i2c_pins_5: i2c5 { -- pins_i2c{ -+ pins_i2c { - pinmux = , - ; - mediatek,pull-up-adv = <3>; -diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi -index 268a1f28af8ce..10779a9947fe2 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi -@@ -1136,127 +1136,6 @@ - nvmem-cell-names = "calibration-data"; - }; - -- thermal_zones: thermal-zones { -- cpu_thermal: cpu-thermal { -- polling-delay-passive = <100>; -- polling-delay = <500>; -- thermal-sensors = <&thermal 0>; -- sustainable-power = <5000>; -- -- trips { -- threshold: trip-point0 { -- temperature = <68000>; -- hysteresis = <2000>; -- type = "passive"; -- }; -- -- target: trip-point1 { -- temperature = <80000>; -- hysteresis = <2000>; -- type = "passive"; -- }; -- -- cpu_crit: cpu-crit { -- temperature = <115000>; -- hysteresis = <2000>; -- type = "critical"; -- }; -- }; -- -- cooling-maps { -- map0 { -- trip = <&target>; -- cooling-device = <&cpu0 -- THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>, -- <&cpu1 -- THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>, -- <&cpu2 -- THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>, -- <&cpu3 -- THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>; -- contribution = <3072>; -- }; -- map1 { -- trip = <&target>; -- cooling-device = <&cpu4 -- THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>, -- <&cpu5 -- THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>, -- <&cpu6 -- THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>, -- <&cpu7 -- THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>; -- contribution = <1024>; -- }; -- }; -- }; -- -- /* The tzts1 ~ tzts6 don't need to polling */ -- /* The tzts1 ~ tzts6 don't need to thermal throttle */ -- -- tzts1: tzts1 { -- polling-delay-passive = <0>; -- polling-delay = <0>; -- thermal-sensors = <&thermal 1>; -- sustainable-power = <5000>; -- trips {}; -- cooling-maps {}; -- }; -- -- tzts2: tzts2 { -- polling-delay-passive = <0>; -- polling-delay = <0>; -- thermal-sensors = <&thermal 2>; -- sustainable-power = <5000>; -- trips {}; -- cooling-maps {}; -- }; -- -- tzts3: tzts3 { -- polling-delay-passive = <0>; -- polling-delay = <0>; -- thermal-sensors = <&thermal 3>; -- sustainable-power = <5000>; -- trips {}; -- cooling-maps {}; -- }; -- -- tzts4: tzts4 { -- polling-delay-passive = <0>; -- polling-delay = <0>; -- thermal-sensors = <&thermal 4>; -- sustainable-power = <5000>; -- trips {}; -- cooling-maps {}; -- }; -- -- tzts5: tzts5 { -- polling-delay-passive = <0>; -- polling-delay = <0>; -- thermal-sensors = <&thermal 5>; -- sustainable-power = <5000>; -- trips {}; -- cooling-maps {}; -- }; -- -- tztsABB: tztsABB { -- polling-delay-passive = <0>; -- polling-delay = <0>; -- thermal-sensors = <&thermal 6>; -- sustainable-power = <5000>; -- trips {}; -- cooling-maps {}; -- }; -- }; -- - pwm0: pwm@1100e000 { - compatible = "mediatek,mt8183-disp-pwm"; - reg = <0 0x1100e000 0 0x1000>; -@@ -2031,4 +1910,125 @@ - power-domains = <&spm MT8183_POWER_DOMAIN_CAM>; - }; - }; -+ -+ thermal_zones: thermal-zones { -+ cpu_thermal: cpu-thermal { -+ polling-delay-passive = <100>; -+ polling-delay = <500>; -+ thermal-sensors = <&thermal 0>; -+ sustainable-power = <5000>; -+ -+ trips { -+ threshold: trip-point0 { -+ temperature = <68000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ target: trip-point1 { -+ temperature = <80000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ cpu_crit: cpu-crit { -+ temperature = <115000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&target>; -+ cooling-device = <&cpu0 -+ THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>, -+ <&cpu1 -+ THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>, -+ <&cpu2 -+ THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>, -+ <&cpu3 -+ THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ contribution = <3072>; -+ }; -+ map1 { -+ trip = <&target>; -+ cooling-device = <&cpu4 -+ THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>, -+ <&cpu5 -+ THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>, -+ <&cpu6 -+ THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>, -+ <&cpu7 -+ THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ contribution = <1024>; -+ }; -+ }; -+ }; -+ -+ /* The tzts1 ~ tzts6 don't need to polling */ -+ /* The tzts1 ~ tzts6 don't need to thermal throttle */ -+ -+ tzts1: tzts1 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&thermal 1>; -+ sustainable-power = <5000>; -+ trips {}; -+ cooling-maps {}; -+ }; -+ -+ tzts2: tzts2 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&thermal 2>; -+ sustainable-power = <5000>; -+ trips {}; -+ cooling-maps {}; -+ }; -+ -+ tzts3: tzts3 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&thermal 3>; -+ sustainable-power = <5000>; -+ trips {}; -+ cooling-maps {}; -+ }; -+ -+ tzts4: tzts4 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&thermal 4>; -+ sustainable-power = <5000>; -+ trips {}; -+ cooling-maps {}; -+ }; -+ -+ tzts5: tzts5 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&thermal 5>; -+ sustainable-power = <5000>; -+ trips {}; -+ cooling-maps {}; -+ }; -+ -+ tztsABB: tztsABB { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&thermal 6>; -+ sustainable-power = <5000>; -+ trips {}; -+ cooling-maps {}; -+ }; -+ }; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi -index 9b62e161db261..4b8a1c462906e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi -@@ -207,7 +207,7 @@ - pinctrl-0 = <&i2c7_pins>; - - pmic@34 { -- #interrupt-cells = <1>; -+ #interrupt-cells = <2>; - compatible = "mediatek,mt6360"; - reg = <0x34>; - interrupt-controller; -diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi -index ef2764a595eda..414cbe3451270 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi -@@ -471,6 +471,8 @@ - - power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 { - reg = ; -+ clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>; -+ clock-names = "venc1-larb"; - mediatek,infracfg = <&infracfg_ao>; - #power-domain-cells = <0>; - }; -@@ -533,6 +535,8 @@ - - power-domain@MT8195_POWER_DOMAIN_VENC { - reg = ; -+ clocks = <&vencsys CLK_VENC_LARB>; -+ clock-names = "venc0-larb"; - mediatek,infracfg = <&infracfg_ao>; - #power-domain-cells = <0>; - }; -@@ -1985,7 +1989,7 @@ - reg = <0 0x1b010000 0 0x1000>; - mediatek,larb-id = <20>; - mediatek,smi = <&smi_common_vpp>; -- clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>, -+ clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>, - <&vencsys_core1 CLK_VENC_CORE1_GALS>, - <&vppsys0 CLK_VPP0_GALS_VDO0_VDO1_VENCSYS_CORE1>; - clock-names = "apb", "smi", "gals"; -diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -index 49ae15708a0b6..905a50aa5dc38 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi -@@ -666,7 +666,7 @@ - - vdec: video-codec@ff360000 { - compatible = "rockchip,rk3328-vdec", "rockchip,rk3399-vdec"; -- reg = <0x0 0xff360000 0x0 0x400>; -+ reg = <0x0 0xff360000 0x0 0x480>; - interrupts = ; - clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>, - <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -index 5f3caf01badeb..a7e6eccb14cc6 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi -@@ -1062,7 +1062,9 @@ - power-domain@RK3399_PD_VDU { - reg = ; - clocks = <&cru ACLK_VDU>, -- <&cru HCLK_VDU>; -+ <&cru HCLK_VDU>, -+ <&cru SCLK_VDU_CA>, -+ <&cru SCLK_VDU_CORE>; - pm_qos = <&qos_video_m1_r>, - <&qos_video_m1_w>; - #power-domain-cells = <0>; -@@ -1338,7 +1340,7 @@ - - vdec: video-codec@ff660000 { - compatible = "rockchip,rk3399-vdec"; -- reg = <0x0 0xff660000 0x0 0x400>; -+ reg = <0x0 0xff660000 0x0 0x480>; - interrupts = ; - clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>, - <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>; -diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c -index 82b4402810da0..40ed49d9adff5 100644 ---- a/arch/loongarch/net/bpf_jit.c -+++ b/arch/loongarch/net/bpf_jit.c -@@ -796,8 +796,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext - - /* function return */ - case BPF_JMP | BPF_EXIT: -- emit_sext_32(ctx, regmap[BPF_REG_0], true); -- - if (i == ctx->prog->len - 1) - break; - -@@ -844,14 +842,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext - } - break; - case BPF_DW: -- if (is_signed_imm12(off)) { -- emit_insn(ctx, ldd, dst, src, off); -- } else if (is_signed_imm14(off)) { -- emit_insn(ctx, ldptrd, dst, src, off); -- } else { -- move_imm(ctx, t1, off, is32); -- emit_insn(ctx, ldxd, dst, src, t1); -- } -+ move_imm(ctx, t1, off, is32); -+ emit_insn(ctx, ldxd, dst, src, t1); - break; - } - break; -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 0e62f5edaee2e..585783c9907ef 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -483,6 +483,7 @@ config MACH_LOONGSON2EF - - config MACH_LOONGSON64 - bool "Loongson 64-bit family of machines" -+ select ARCH_DMA_DEFAULT_COHERENT - select ARCH_SPARSEMEM_ENABLE - select ARCH_MIGHT_HAVE_PC_PARPORT - select ARCH_MIGHT_HAVE_PC_SERIO -@@ -1304,6 +1305,7 @@ config CPU_LOONGSON64 - select CPU_SUPPORTS_MSA - select CPU_DIEI_BROKEN if !LOONGSON3_ENHANCEMENT - select CPU_MIPSR2_IRQ_VI -+ select DMA_NONCOHERENT - select WEAK_ORDERING - select WEAK_REORDERING_BEYOND_LLSC - select MIPS_ASID_BITS_VARIABLE -diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h -index 035b1a69e2d00..e007edd6b60a7 100644 ---- a/arch/mips/include/asm/mach-loongson64/boot_param.h -+++ b/arch/mips/include/asm/mach-loongson64/boot_param.h -@@ -14,7 +14,11 @@ - #define ADAPTER_ROM 8 - #define ACPI_TABLE 9 - #define SMBIOS_TABLE 10 --#define MAX_MEMORY_TYPE 11 -+#define UMA_VIDEO_RAM 11 -+#define VUMA_VIDEO_RAM 12 -+#define MAX_MEMORY_TYPE 13 -+ -+#define MEM_SIZE_IS_IN_BYTES (1 << 31) - - #define LOONGSON3_BOOT_MEM_MAP_MAX 128 - struct efi_memory_map_loongson { -@@ -117,7 +121,8 @@ struct irq_source_routing_table { - u64 pci_io_start_addr; - u64 pci_io_end_addr; - u64 pci_config_addr; -- u32 dma_mask_bits; -+ u16 dma_mask_bits; -+ u16 dma_noncoherent; - } __packed; - - struct interface_info { -diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c -index bbe9ce471791e..17d80e2f2e4cb 100644 ---- a/arch/mips/kernel/process.c -+++ b/arch/mips/kernel/process.c -@@ -121,6 +121,19 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) - /* Put the stack after the struct pt_regs. */ - childksp = (unsigned long) childregs; - p->thread.cp0_status = (read_c0_status() & ~(ST0_CU2|ST0_CU1)) | ST0_KERNEL_CUMASK; -+ -+ /* -+ * New tasks lose permission to use the fpu. This accelerates context -+ * switching for most programs since they don't use the fpu. -+ */ -+ clear_tsk_thread_flag(p, TIF_USEDFPU); -+ clear_tsk_thread_flag(p, TIF_USEDMSA); -+ clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE); -+ -+#ifdef CONFIG_MIPS_MT_FPAFF -+ clear_tsk_thread_flag(p, TIF_FPUBOUND); -+#endif /* CONFIG_MIPS_MT_FPAFF */ -+ - if (unlikely(args->fn)) { - /* kernel thread */ - unsigned long status = p->thread.cp0_status; -@@ -149,20 +162,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) - p->thread.reg29 = (unsigned long) childregs; - p->thread.reg31 = (unsigned long) ret_from_fork; - -- /* -- * New tasks lose permission to use the fpu. This accelerates context -- * switching for most programs since they don't use the fpu. -- */ - childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); - -- clear_tsk_thread_flag(p, TIF_USEDFPU); -- clear_tsk_thread_flag(p, TIF_USEDMSA); -- clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE); -- --#ifdef CONFIG_MIPS_MT_FPAFF -- clear_tsk_thread_flag(p, TIF_FPUBOUND); --#endif /* CONFIG_MIPS_MT_FPAFF */ -- - #ifdef CONFIG_MIPS_FP_SUPPORT - atomic_set(&p->thread.bd_emu_frame, BD_EMUFRAME_NONE); - #endif -diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c -index c961e2999f15a..ef3750a6ffacf 100644 ---- a/arch/mips/loongson64/env.c -+++ b/arch/mips/loongson64/env.c -@@ -13,6 +13,8 @@ - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - */ -+ -+#include - #include - #include - #include -@@ -147,8 +149,14 @@ void __init prom_lefi_init_env(void) - - loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits; - if (loongson_sysconf.dma_mask_bits < 32 || -- loongson_sysconf.dma_mask_bits > 64) -+ loongson_sysconf.dma_mask_bits > 64) { - loongson_sysconf.dma_mask_bits = 32; -+ dma_default_coherent = true; -+ } else { -+ dma_default_coherent = !eirq_source->dma_noncoherent; -+ } -+ -+ pr_info("Firmware: Coherent DMA: %s\n", dma_default_coherent ? "on" : "off"); - - loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm; - loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; -diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c -index ee8de1735b7c0..f25caa6aa9d30 100644 ---- a/arch/mips/loongson64/init.c -+++ b/arch/mips/loongson64/init.c -@@ -49,8 +49,7 @@ void virtual_early_config(void) - void __init szmem(unsigned int node) - { - u32 i, mem_type; -- static unsigned long num_physpages; -- u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; -+ phys_addr_t node_id, mem_start, mem_size; - - /* Otherwise come from DTB */ - if (loongson_sysconf.fw_interface != LOONGSON_LEFI) -@@ -64,30 +63,46 @@ void __init szmem(unsigned int node) - - mem_type = loongson_memmap->map[i].mem_type; - mem_size = loongson_memmap->map[i].mem_size; -- mem_start = loongson_memmap->map[i].mem_start; -+ -+ /* Memory size comes in MB if MEM_SIZE_IS_IN_BYTES not set */ -+ if (mem_size & MEM_SIZE_IS_IN_BYTES) -+ mem_size &= ~MEM_SIZE_IS_IN_BYTES; -+ else -+ mem_size = mem_size << 20; -+ -+ mem_start = (node_id << 44) | loongson_memmap->map[i].mem_start; - - switch (mem_type) { - case SYSTEM_RAM_LOW: - case SYSTEM_RAM_HIGH: -- start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; -- node_psize = (mem_size << 20) >> PAGE_SHIFT; -- end_pfn = start_pfn + node_psize; -- num_physpages += node_psize; -- pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", -- (u32)node_id, mem_type, mem_start, mem_size); -- pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", -- start_pfn, end_pfn, num_physpages); -- memblock_add_node(PFN_PHYS(start_pfn), -- PFN_PHYS(node_psize), node, -+ case UMA_VIDEO_RAM: -+ pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes usable\n", -+ (u32)node_id, mem_type, &mem_start, &mem_size); -+ memblock_add_node(mem_start, mem_size, node, - MEMBLOCK_NONE); - break; - case SYSTEM_RAM_RESERVED: -- pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", -- (u32)node_id, mem_type, mem_start, mem_size); -- memblock_reserve(((node_id << 44) + mem_start), mem_size << 20); -+ case VIDEO_ROM: -+ case ADAPTER_ROM: -+ case ACPI_TABLE: -+ case SMBIOS_TABLE: -+ pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes reserved\n", -+ (u32)node_id, mem_type, &mem_start, &mem_size); -+ memblock_reserve(mem_start, mem_size); -+ break; -+ /* We should not reserve VUMA_VIDEO_RAM as it overlaps with MMIO */ -+ case VUMA_VIDEO_RAM: -+ default: -+ pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes unhandled\n", -+ (u32)node_id, mem_type, &mem_start, &mem_size); - break; - } - } -+ -+ /* Reserve vgabios if it comes from firmware */ -+ if (loongson_sysconf.vgabios_addr) -+ memblock_reserve(virt_to_phys((void *)loongson_sysconf.vgabios_addr), -+ SZ_256K); - } - - #ifndef CONFIG_NUMA -diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig -index 67c26e81e2150..345d5e021484c 100644 ---- a/arch/parisc/Kconfig -+++ b/arch/parisc/Kconfig -@@ -105,9 +105,12 @@ config ARCH_HAS_ILOG2_U64 - default n - - config GENERIC_BUG -- bool -- default y -+ def_bool y - depends on BUG -+ select GENERIC_BUG_RELATIVE_POINTERS if 64BIT -+ -+config GENERIC_BUG_RELATIVE_POINTERS -+ bool - - config GENERIC_HWEIGHT - bool -diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h -index b9cad0bb4461b..833555f74ffa7 100644 ---- a/arch/parisc/include/asm/bug.h -+++ b/arch/parisc/include/asm/bug.h -@@ -17,26 +17,27 @@ - #define PARISC_BUG_BREAK_ASM "break 0x1f, 0x1fff" - #define PARISC_BUG_BREAK_INSN 0x03ffe01f /* PARISC_BUG_BREAK_ASM */ - --#if defined(CONFIG_64BIT) --#define ASM_WORD_INSN ".dword\t" -+#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS -+# define __BUG_REL(val) ".word " __stringify(val) " - ." - #else --#define ASM_WORD_INSN ".word\t" -+# define __BUG_REL(val) ".word " __stringify(val) - #endif - -+ - #ifdef CONFIG_DEBUG_BUGVERBOSE - #define BUG() \ - do { \ - asm volatile("\n" \ - "1:\t" PARISC_BUG_BREAK_ASM "\n" \ - "\t.pushsection __bug_table,\"a\"\n" \ -- "\t.align %4\n" \ -- "2:\t" ASM_WORD_INSN "1b, %c0\n" \ -+ "\t.align 4\n" \ -+ "2:\t" __BUG_REL(1b) "\n" \ -+ "\t" __BUG_REL(%c0) "\n" \ - "\t.short %1, %2\n" \ -- "\t.blockz %3-2*%4-2*2\n" \ -+ "\t.blockz %3-2*4-2*2\n" \ - "\t.popsection" \ - : : "i" (__FILE__), "i" (__LINE__), \ -- "i" (0), "i" (sizeof(struct bug_entry)), \ -- "i" (sizeof(long)) ); \ -+ "i" (0), "i" (sizeof(struct bug_entry)) ); \ - unreachable(); \ - } while(0) - -@@ -54,15 +55,15 @@ - asm volatile("\n" \ - "1:\t" PARISC_BUG_BREAK_ASM "\n" \ - "\t.pushsection __bug_table,\"a\"\n" \ -- "\t.align %4\n" \ -- "2:\t" ASM_WORD_INSN "1b, %c0\n" \ -+ "\t.align 4\n" \ -+ "2:\t" __BUG_REL(1b) "\n" \ -+ "\t" __BUG_REL(%c0) "\n" \ - "\t.short %1, %2\n" \ -- "\t.blockz %3-2*%4-2*2\n" \ -+ "\t.blockz %3-2*4-2*2\n" \ - "\t.popsection" \ - : : "i" (__FILE__), "i" (__LINE__), \ - "i" (BUGFLAG_WARNING|(flags)), \ -- "i" (sizeof(struct bug_entry)), \ -- "i" (sizeof(long)) ); \ -+ "i" (sizeof(struct bug_entry)) ); \ - } while(0) - #else - #define __WARN_FLAGS(flags) \ -@@ -70,14 +71,13 @@ - asm volatile("\n" \ - "1:\t" PARISC_BUG_BREAK_ASM "\n" \ - "\t.pushsection __bug_table,\"a\"\n" \ -- "\t.align %2\n" \ -- "2:\t" ASM_WORD_INSN "1b\n" \ -+ "\t.align 4\n" \ -+ "2:\t" __BUG_REL(1b) "\n" \ - "\t.short %0\n" \ -- "\t.blockz %1-%2-2\n" \ -+ "\t.blockz %1-4-2\n" \ - "\t.popsection" \ - : : "i" (BUGFLAG_WARNING|(flags)), \ -- "i" (sizeof(struct bug_entry)), \ -- "i" (sizeof(long)) ); \ -+ "i" (sizeof(struct bug_entry)) ); \ - } while(0) - #endif - -diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs -index 69774bb362d6a..29d78eefc8894 100644 ---- a/arch/riscv/Kconfig.socs -+++ b/arch/riscv/Kconfig.socs -@@ -23,6 +23,7 @@ config SOC_STARFIVE - select PINCTRL - select RESET_CONTROLLER - select SIFIVE_PLIC -+ select ARM_AMBA - help - This enables support for StarFive SoC platform hardware. - -diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c -index 378f5b1514435..5348d842c7453 100644 ---- a/arch/riscv/kernel/traps_misaligned.c -+++ b/arch/riscv/kernel/traps_misaligned.c -@@ -342,16 +342,14 @@ int handle_misaligned_store(struct pt_regs *regs) - } else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) { - len = 8; - val.data_ulong = GET_RS2S(insn, regs); -- } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP && -- ((insn >> SH_RD) & 0x1f)) { -+ } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP) { - len = 8; - val.data_ulong = GET_RS2C(insn, regs); - #endif - } else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) { - len = 4; - val.data_ulong = GET_RS2S(insn, regs); -- } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP && -- ((insn >> SH_RD) & 0x1f)) { -+ } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP) { - len = 4; - val.data_ulong = GET_RS2C(insn, regs); - } else { -diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c -index 4909dcd762e8c..9977d637f836d 100644 ---- a/arch/s390/mm/pgtable.c -+++ b/arch/s390/mm/pgtable.c -@@ -731,7 +731,7 @@ void ptep_zap_unused(struct mm_struct *mm, unsigned long addr, - pte_clear(mm, addr, ptep); - } - if (reset) -- pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK; -+ pgste_val(pgste) &= ~(_PGSTE_GPS_USAGE_MASK | _PGSTE_GPS_NODAT); - pgste_set_unlock(ptep, pgste); - preempt_enable(); - } -diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c -index 8a1d48b8c2a3e..d0565a9e7d8c9 100644 ---- a/arch/x86/coco/tdx/tdx.c -+++ b/arch/x86/coco/tdx/tdx.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c -index 93c60c0c9d4a7..9c0b26ae51069 100644 ---- a/arch/x86/entry/common.c -+++ b/arch/x86/entry/common.c -@@ -25,6 +25,7 @@ - #include - #endif - -+#include - #include - #include - #include -@@ -96,6 +97,10 @@ static __always_inline int syscall_32_enter(struct pt_regs *regs) - return (int)regs->orig_ax; - } - -+#ifdef CONFIG_IA32_EMULATION -+bool __ia32_enabled __ro_after_init = true; -+#endif -+ - /* - * Invoke a 32-bit syscall. Called with IRQs on in CONTEXT_KERNEL. - */ -@@ -115,7 +120,96 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr) - } - } - --/* Handles int $0x80 */ -+#ifdef CONFIG_IA32_EMULATION -+static __always_inline bool int80_is_external(void) -+{ -+ const unsigned int offs = (0x80 / 32) * 0x10; -+ const u32 bit = BIT(0x80 % 32); -+ -+ /* The local APIC on XENPV guests is fake */ -+ if (cpu_feature_enabled(X86_FEATURE_XENPV)) -+ return false; -+ -+ /* -+ * If vector 0x80 is set in the APIC ISR then this is an external -+ * interrupt. Either from broken hardware or injected by a VMM. -+ * -+ * Note: In guest mode this is only valid for secure guests where -+ * the secure module fully controls the vAPIC exposed to the guest. -+ */ -+ return apic_read(APIC_ISR + offs) & bit; -+} -+ -+/** -+ * int80_emulation - 32-bit legacy syscall entry -+ * -+ * This entry point can be used by 32-bit and 64-bit programs to perform -+ * 32-bit system calls. Instances of INT $0x80 can be found inline in -+ * various programs and libraries. It is also used by the vDSO's -+ * __kernel_vsyscall fallback for hardware that doesn't support a faster -+ * entry method. Restarted 32-bit system calls also fall back to INT -+ * $0x80 regardless of what instruction was originally used to do the -+ * system call. -+ * -+ * This is considered a slow path. It is not used by most libc -+ * implementations on modern hardware except during process startup. -+ * -+ * The arguments for the INT $0x80 based syscall are on stack in the -+ * pt_regs structure: -+ * eax: system call number -+ * ebx, ecx, edx, esi, edi, ebp: arg1 - arg 6 -+ */ -+DEFINE_IDTENTRY_RAW(int80_emulation) -+{ -+ int nr; -+ -+ /* Kernel does not use INT $0x80! */ -+ if (unlikely(!user_mode(regs))) { -+ irqentry_enter(regs); -+ instrumentation_begin(); -+ panic("Unexpected external interrupt 0x80\n"); -+ } -+ -+ /* -+ * Establish kernel context for instrumentation, including for -+ * int80_is_external() below which calls into the APIC driver. -+ * Identical for soft and external interrupts. -+ */ -+ enter_from_user_mode(regs); -+ -+ instrumentation_begin(); -+ add_random_kstack_offset(); -+ -+ /* Validate that this is a soft interrupt to the extent possible */ -+ if (unlikely(int80_is_external())) -+ panic("Unexpected external interrupt 0x80\n"); -+ -+ /* -+ * The low level idtentry code pushed -1 into regs::orig_ax -+ * and regs::ax contains the syscall number. -+ * -+ * User tracing code (ptrace or signal handlers) might assume -+ * that the regs::orig_ax contains a 32-bit number on invoking -+ * a 32-bit syscall. -+ * -+ * Establish the syscall convention by saving the 32bit truncated -+ * syscall number in regs::orig_ax and by invalidating regs::ax. -+ */ -+ regs->orig_ax = regs->ax & GENMASK(31, 0); -+ regs->ax = -ENOSYS; -+ -+ nr = syscall_32_enter(regs); -+ -+ local_irq_enable(); -+ nr = syscall_enter_from_user_mode_work(regs, nr); -+ do_syscall_32_irqs_on(regs, nr); -+ -+ instrumentation_end(); -+ syscall_exit_to_user_mode(regs); -+} -+#else /* CONFIG_IA32_EMULATION */ -+ -+/* Handles int $0x80 on a 32bit kernel */ - __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) - { - int nr = syscall_32_enter(regs); -@@ -134,6 +228,7 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) - instrumentation_end(); - syscall_exit_to_user_mode(regs); - } -+#endif /* !CONFIG_IA32_EMULATION */ - - static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) - { -diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S -index 4dd19819053a5..d6c08d8986b17 100644 ---- a/arch/x86/entry/entry_64_compat.S -+++ b/arch/x86/entry/entry_64_compat.S -@@ -277,80 +277,3 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL) - ANNOTATE_NOENDBR - int3 - SYM_CODE_END(entry_SYSCALL_compat) -- --/* -- * 32-bit legacy system call entry. -- * -- * 32-bit x86 Linux system calls traditionally used the INT $0x80 -- * instruction. INT $0x80 lands here. -- * -- * This entry point can be used by 32-bit and 64-bit programs to perform -- * 32-bit system calls. Instances of INT $0x80 can be found inline in -- * various programs and libraries. It is also used by the vDSO's -- * __kernel_vsyscall fallback for hardware that doesn't support a faster -- * entry method. Restarted 32-bit system calls also fall back to INT -- * $0x80 regardless of what instruction was originally used to do the -- * system call. -- * -- * This is considered a slow path. It is not used by most libc -- * implementations on modern hardware except during process startup. -- * -- * Arguments: -- * eax system call number -- * ebx arg1 -- * ecx arg2 -- * edx arg3 -- * esi arg4 -- * edi arg5 -- * ebp arg6 -- */ --SYM_CODE_START(entry_INT80_compat) -- UNWIND_HINT_ENTRY -- ENDBR -- /* -- * Interrupts are off on entry. -- */ -- ASM_CLAC /* Do this early to minimize exposure */ -- ALTERNATIVE "swapgs", "", X86_FEATURE_XENPV -- -- /* -- * User tracing code (ptrace or signal handlers) might assume that -- * the saved RAX contains a 32-bit number when we're invoking a 32-bit -- * syscall. Just in case the high bits are nonzero, zero-extend -- * the syscall number. (This could almost certainly be deleted -- * with no ill effects.) -- */ -- movl %eax, %eax -- -- /* switch to thread stack expects orig_ax and rdi to be pushed */ -- pushq %rax /* pt_regs->orig_ax */ -- -- /* Need to switch before accessing the thread stack. */ -- SWITCH_TO_KERNEL_CR3 scratch_reg=%rax -- -- /* In the Xen PV case we already run on the thread stack. */ -- ALTERNATIVE "", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV -- -- movq %rsp, %rax -- movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp -- -- pushq 5*8(%rax) /* regs->ss */ -- pushq 4*8(%rax) /* regs->rsp */ -- pushq 3*8(%rax) /* regs->eflags */ -- pushq 2*8(%rax) /* regs->cs */ -- pushq 1*8(%rax) /* regs->ip */ -- pushq 0*8(%rax) /* regs->orig_ax */ --.Lint80_keep_stack: -- -- PUSH_AND_CLEAR_REGS rax=$-ENOSYS -- UNWIND_HINT_REGS -- -- cld -- -- IBRS_ENTER -- UNTRAIN_RET -- -- movq %rsp, %rdi -- call do_int80_syscall_32 -- jmp swapgs_restore_regs_and_return_to_usermode --SYM_CODE_END(entry_INT80_compat) -diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h -index fada857f0a1ed..9805629479d96 100644 ---- a/arch/x86/include/asm/ia32.h -+++ b/arch/x86/include/asm/ia32.h -@@ -68,6 +68,27 @@ extern void ia32_pick_mmap_layout(struct mm_struct *mm); - - #endif - --#endif /* CONFIG_IA32_EMULATION */ -+extern bool __ia32_enabled; -+ -+static inline bool ia32_enabled(void) -+{ -+ return __ia32_enabled; -+} -+ -+static inline void ia32_disable(void) -+{ -+ __ia32_enabled = false; -+} -+ -+#else /* !CONFIG_IA32_EMULATION */ -+ -+static inline bool ia32_enabled(void) -+{ -+ return IS_ENABLED(CONFIG_X86_32); -+} -+ -+static inline void ia32_disable(void) {} -+ -+#endif - - #endif /* _ASM_X86_IA32_H */ -diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h -index 72184b0b2219e..fca710a93eb9c 100644 ---- a/arch/x86/include/asm/idtentry.h -+++ b/arch/x86/include/asm/idtentry.h -@@ -569,6 +569,10 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_UD, exc_invalid_op); - DECLARE_IDTENTRY_RAW(X86_TRAP_BP, exc_int3); - DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF, exc_page_fault); - -+#if defined(CONFIG_IA32_EMULATION) -+DECLARE_IDTENTRY_RAW(IA32_SYSCALL_VECTOR, int80_emulation); -+#endif -+ - #ifdef CONFIG_X86_MCE - #ifdef CONFIG_X86_64 - DECLARE_IDTENTRY_MCE(X86_TRAP_MC, exc_machine_check); -diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h -index 12ef86b19910d..84294b66b9162 100644 ---- a/arch/x86/include/asm/proto.h -+++ b/arch/x86/include/asm/proto.h -@@ -32,10 +32,6 @@ void entry_SYSCALL_compat(void); - void entry_SYSCALL_compat_safe_stack(void); - void entry_SYSRETL_compat_unsafe_stack(void); - void entry_SYSRETL_compat_end(void); --void entry_INT80_compat(void); --#ifdef CONFIG_XEN_PV --void xen_entry_INT80_compat(void); --#endif - #endif - - void x86_configure_nx(void); -diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c -index b66960358381b..c1d09c8844d67 100644 ---- a/arch/x86/kernel/cpu/amd.c -+++ b/arch/x86/kernel/cpu/amd.c -@@ -1291,6 +1291,9 @@ static void zenbleed_check_cpu(void *unused) - - void amd_check_microcode(void) - { -+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) -+ return; -+ - on_each_cpu(zenbleed_check_cpu, NULL, 1); - } - -diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c -index a58c6bc1cd68c..f5a3374e62cb1 100644 ---- a/arch/x86/kernel/idt.c -+++ b/arch/x86/kernel/idt.c -@@ -117,7 +117,7 @@ static const __initconst struct idt_data def_idts[] = { - - SYSG(X86_TRAP_OF, asm_exc_overflow), - #if defined(CONFIG_IA32_EMULATION) -- SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat), -+ SYSG(IA32_SYSCALL_VECTOR, asm_int80_emulation), - #elif defined(CONFIG_X86_32) - SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32), - #endif -diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c -index 68b2a9d3dbc6b..c8dfb0fdde7f9 100644 ---- a/arch/x86/kernel/sev.c -+++ b/arch/x86/kernel/sev.c -@@ -1279,10 +1279,6 @@ void setup_ghcb(void) - if (!cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) - return; - -- /* First make sure the hypervisor talks a supported protocol. */ -- if (!sev_es_negotiate_protocol()) -- sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); -- - /* - * Check whether the runtime #VC exception handler is active. It uses - * the per-CPU GHCB page which is set up by sev_es_init_vc_handling(). -@@ -1297,6 +1293,13 @@ void setup_ghcb(void) - return; - } - -+ /* -+ * Make sure the hypervisor talks a supported protocol. -+ * This gets called only in the BSP boot phase. -+ */ -+ if (!sev_es_negotiate_protocol()) -+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); -+ - /* - * Clear the boot_ghcb. The first exception comes in before the bss - * section is cleared. -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index 4194aa4c5f0e0..4a663812562db 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -1786,15 +1786,17 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) - bool old_paging = is_paging(vcpu); - - #ifdef CONFIG_X86_64 -- if (vcpu->arch.efer & EFER_LME && !vcpu->arch.guest_state_protected) { -+ if (vcpu->arch.efer & EFER_LME) { - if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { - vcpu->arch.efer |= EFER_LMA; -- svm->vmcb->save.efer |= EFER_LMA | EFER_LME; -+ if (!vcpu->arch.guest_state_protected) -+ svm->vmcb->save.efer |= EFER_LMA | EFER_LME; - } - - if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) { - vcpu->arch.efer &= ~EFER_LMA; -- svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); -+ if (!vcpu->arch.guest_state_protected) -+ svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); - } - } - #endif -diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c -index 3ea0f763540a4..3e93af083e037 100644 ---- a/arch/x86/mm/mem_encrypt_amd.c -+++ b/arch/x86/mm/mem_encrypt_amd.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - #include "mm_internal.h" - -@@ -502,6 +503,16 @@ void __init sme_early_init(void) - x86_platform.guest.enc_status_change_finish = amd_enc_status_change_finish; - x86_platform.guest.enc_tlb_flush_required = amd_enc_tlb_flush_required; - x86_platform.guest.enc_cache_flush_required = amd_enc_cache_flush_required; -+ -+ /* -+ * The VMM is capable of injecting interrupt 0x80 and triggering the -+ * compatibility syscall path. -+ * -+ * By default, the 32-bit emulation is disabled in order to ensure -+ * the safety of the VM. -+ */ -+ if (sev_status & MSR_AMD64_SEV_ENABLED) -+ ia32_disable(); - } - - void __init mem_encrypt_free_decrypted_mem(void) -diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c -index 333539bdbdaae..9280e15de3af5 100644 ---- a/arch/x86/xen/enlighten_pv.c -+++ b/arch/x86/xen/enlighten_pv.c -@@ -623,7 +623,7 @@ static struct trap_array_entry trap_array[] = { - TRAP_ENTRY(exc_int3, false ), - TRAP_ENTRY(exc_overflow, false ), - #ifdef CONFIG_IA32_EMULATION -- { entry_INT80_compat, xen_entry_INT80_compat, false }, -+ TRAP_ENTRY(int80_emulation, false ), - #endif - TRAP_ENTRY(exc_page_fault, false ), - TRAP_ENTRY(exc_divide_error, false ), -diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S -index 6b4fdf6b95422..dec5e03e7a2cf 100644 ---- a/arch/x86/xen/xen-asm.S -+++ b/arch/x86/xen/xen-asm.S -@@ -156,7 +156,7 @@ xen_pv_trap asm_xenpv_exc_machine_check - #endif /* CONFIG_X86_MCE */ - xen_pv_trap asm_exc_simd_coprocessor_error - #ifdef CONFIG_IA32_EMULATION --xen_pv_trap entry_INT80_compat -+xen_pv_trap asm_int80_emulation - #endif - xen_pv_trap asm_exc_xen_unknown_trap - xen_pv_trap asm_exc_xen_hypervisor_callback -diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index a0e347f6f97eb..94154a849a3ea 100644 ---- a/drivers/acpi/scan.c -+++ b/drivers/acpi/scan.c -@@ -1563,17 +1563,22 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev, - int err; - const struct iommu_ops *ops; - -+ /* Serialise to make dev->iommu stable under our potential fwspec */ -+ mutex_lock(&iommu_probe_device_lock); - /* - * If we already translated the fwspec there is nothing left to do, - * return the iommu_ops. - */ - ops = acpi_iommu_fwspec_ops(dev); -- if (ops) -+ if (ops) { -+ mutex_unlock(&iommu_probe_device_lock); - return ops; -+ } - - err = iort_iommu_configure_id(dev, id_in); - if (err && err != -EPROBE_DEFER) - err = viot_iommu_configure(dev); -+ mutex_unlock(&iommu_probe_device_lock); - - /* - * If we have reason to believe the IOMMU driver missed the initial -diff --git a/drivers/android/binder.c b/drivers/android/binder.c -index e4a6da81cd4b3..9cc3a2b1b4fc1 100644 ---- a/drivers/android/binder.c -+++ b/drivers/android/binder.c -@@ -4788,6 +4788,7 @@ static void binder_release_work(struct binder_proc *proc, - "undelivered TRANSACTION_ERROR: %u\n", - e->cmd); - } break; -+ case BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT: - case BINDER_WORK_TRANSACTION_COMPLETE: { - binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "undelivered TRANSACTION_COMPLETE\n"); -diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c -index 1c06781f71148..f3bd9f104bd12 100644 ---- a/drivers/base/devcoredump.c -+++ b/drivers/base/devcoredump.c -@@ -363,6 +363,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, - devcd->devcd_dev.class = &devcd_class; - - mutex_lock(&devcd->mutex); -+ dev_set_uevent_suppress(&devcd->devcd_dev, true); - if (device_add(&devcd->devcd_dev)) - goto put_device; - -@@ -377,6 +378,8 @@ void dev_coredumpm(struct device *dev, struct module *owner, - "devcoredump")) - dev_warn(dev, "devcoredump create_link failed\n"); - -+ dev_set_uevent_suppress(&devcd->devcd_dev, false); -+ kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); - INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); - schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT); - mutex_unlock(&devcd->mutex); -diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c -index cf3fa998093de..4f3dd9316fb2f 100644 ---- a/drivers/base/regmap/regcache.c -+++ b/drivers/base/regmap/regcache.c -@@ -410,8 +410,7 @@ out: - rb_entry(node, struct regmap_range_node, node); - - /* If there's nothing in the cache there's nothing to sync */ -- ret = regcache_read(map, this->selector_reg, &i); -- if (ret != 0) -+ if (regcache_read(map, this->selector_reg, &i) != 0) - continue; - - ret = _regmap_write(map, this->selector_reg, i); -diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c -index cd27bf173dec8..a64648682c72c 100644 ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -463,14 +463,17 @@ static ssize_t export_store(struct class *class, - goto done; - - status = gpiod_set_transitory(desc, false); -- if (!status) { -- status = gpiod_export(desc, true); -- if (status < 0) -- gpiod_free(desc); -- else -- set_bit(FLAG_SYSFS, &desc->flags); -+ if (status) { -+ gpiod_free(desc); -+ goto done; - } - -+ status = gpiod_export(desc, true); -+ if (status < 0) -+ gpiod_free(desc); -+ else -+ set_bit(FLAG_SYSFS, &desc->flags); -+ - done: - if (status) - pr_debug("%s: status %d\n", __func__, status); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -index ced4e7e8f98b5..133e4e03c143c 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c -@@ -201,7 +201,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, - } - - for (i = 0; i < p->nchunks; i++) { -- struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL; -+ struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL; - struct drm_amdgpu_cs_chunk user_chunk; - uint32_t __user *cdata; - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index 2fced451f0aea..aabde6ebb190e 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -90,7 +90,7 @@ static void amdgpu_display_flip_work_func(struct work_struct *__work) - - struct drm_crtc *crtc = &amdgpu_crtc->base; - unsigned long flags; -- unsigned i; -+ unsigned int i; - int vpos, hpos; - - for (i = 0; i < work->shared_count; ++i) -@@ -167,7 +167,7 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, - u64 tiling_flags; - int i, r; - -- work = kzalloc(sizeof *work, GFP_KERNEL); -+ work = kzalloc(sizeof(*work), GFP_KERNEL); - if (work == NULL) - return -ENOMEM; - -@@ -298,18 +298,17 @@ int amdgpu_display_crtc_set_config(struct drm_mode_set *set, - - adev = drm_to_adev(dev); - /* if we have active crtcs and we don't have a power ref, -- take the current one */ -+ * take the current one -+ */ - if (active && !adev->have_disp_power_ref) { - adev->have_disp_power_ref = true; - return ret; - } -- /* if we have no active crtcs, then drop the power ref -- we got before */ -- if (!active && adev->have_disp_power_ref) { -- pm_runtime_put_autosuspend(dev->dev); -+ /* if we have no active crtcs, then go to -+ * drop the power ref we got before -+ */ -+ if (!active && adev->have_disp_power_ref) - adev->have_disp_power_ref = false; -- } -- - out: - /* drop the power reference we got coming in here */ - pm_runtime_put_autosuspend(dev->dev); -@@ -473,11 +472,10 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, - if (amdgpu_connector->router.ddc_valid) - amdgpu_i2c_router_select_ddc_port(amdgpu_connector); - -- if (use_aux) { -+ if (use_aux) - ret = i2c_transfer(&amdgpu_connector->ddc_bus->aux.ddc, msgs, 2); -- } else { -+ else - ret = i2c_transfer(&amdgpu_connector->ddc_bus->adapter, msgs, 2); -- } - - if (ret != 2) - /* Couldn't find an accessible DDC on this connector */ -@@ -486,10 +484,12 @@ bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector, - * EDID header starts with: - * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. - * Only the first 6 bytes must be valid as -- * drm_edid_block_valid() can fix the last 2 bytes */ -+ * drm_edid_block_valid() can fix the last 2 bytes -+ */ - if (drm_edid_header_is_valid(buf) < 6) { - /* Couldn't find an accessible EDID on this -- * connector */ -+ * connector -+ */ - return false; - } - return true; -@@ -1204,8 +1204,10 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, - - obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); - if (obj == NULL) { -- drm_dbg_kms(dev, "No GEM object associated to handle 0x%08X, " -- "can't create framebuffer\n", mode_cmd->handles[0]); -+ drm_dbg_kms(dev, -+ "No GEM object associated to handle 0x%08X, can't create framebuffer\n", -+ mode_cmd->handles[0]); -+ - return ERR_PTR(-ENOENT); - } - -@@ -1398,6 +1400,7 @@ bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc, - } - if (amdgpu_crtc->rmx_type != RMX_OFF) { - fixed20_12 a, b; -+ - a.full = dfixed_const(src_v); - b.full = dfixed_const(dst_v); - amdgpu_crtc->vsc.full = dfixed_div(a, b); -@@ -1417,7 +1420,7 @@ bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc, - * - * \param dev Device to query. - * \param pipe Crtc to query. -- * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). -+ * \param flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). - * For driver internal use only also supports these flags: - * - * USE_REAL_VBLANKSTART to use the real start of vblank instead -@@ -1493,8 +1496,8 @@ int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev, - - /* Called from driver internal vblank counter query code? */ - if (flags & GET_DISTANCE_TO_VBLANKSTART) { -- /* Caller wants distance from real vbl_start in *hpos */ -- *hpos = *vpos - vbl_start; -+ /* Caller wants distance from real vbl_start in *hpos */ -+ *hpos = *vpos - vbl_start; - } - - /* Fudge vblank to start a few scanlines earlier to handle the -@@ -1516,7 +1519,7 @@ int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev, - - /* In vblank? */ - if (in_vbl) -- ret |= DRM_SCANOUTPOS_IN_VBLANK; -+ ret |= DRM_SCANOUTPOS_IN_VBLANK; - - /* Called from driver internal vblank counter query code? */ - if (flags & GET_DISTANCE_TO_VBLANKSTART) { -@@ -1622,6 +1625,7 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev) - - if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { - struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); -+ - r = amdgpu_bo_reserve(aobj, true); - if (r == 0) { - amdgpu_bo_unpin(aobj); -@@ -1629,9 +1633,9 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev) - } - } - -- if (fb == NULL || fb->obj[0] == NULL) { -+ if (!fb || !fb->obj[0]) - continue; -- } -+ - robj = gem_to_amdgpu_bo(fb->obj[0]); - if (!amdgpu_display_robj_is_fb(adev, robj)) { - r = amdgpu_bo_reserve(robj, true); -@@ -1658,6 +1662,7 @@ int amdgpu_display_resume_helper(struct amdgpu_device *adev) - - if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) { - struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo); -+ - r = amdgpu_bo_reserve(aobj, true); - if (r == 0) { - r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c -index 4d9eb0137f8c4..d6c4293829aab 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c -@@ -79,6 +79,8 @@ - * That is, for an I2C EEPROM driver everything is controlled by - * the "eeprom_addr". - * -+ * See also top of amdgpu_ras_eeprom.c. -+ * - * P.S. If you need to write, lock and read the Identification Page, - * (M24M02-DR device only, which we do not use), change the "7" to - * "0xF" in the macro below, and let the client set bit 20 to 1 in -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c -index 84c241b9a2a13..f5f747cfe90a1 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c -@@ -33,12 +33,29 @@ - - #include "amdgpu_reset.h" - --#define EEPROM_I2C_MADDR_VEGA20 0x0 --#define EEPROM_I2C_MADDR_ARCTURUS 0x40000 --#define EEPROM_I2C_MADDR_ARCTURUS_D342 0x0 --#define EEPROM_I2C_MADDR_SIENNA_CICHLID 0x0 --#define EEPROM_I2C_MADDR_ALDEBARAN 0x0 --#define EEPROM_I2C_MADDR_SMU_13_0_0 (0x54UL << 16) -+/* These are memory addresses as would be seen by one or more EEPROM -+ * chips strung on the I2C bus, usually by manipulating pins 1-3 of a -+ * set of EEPROM devices. They form a continuous memory space. -+ * -+ * The I2C device address includes the device type identifier, 1010b, -+ * which is a reserved value and indicates that this is an I2C EEPROM -+ * device. It also includes the top 3 bits of the 19 bit EEPROM memory -+ * address, namely bits 18, 17, and 16. This makes up the 7 bit -+ * address sent on the I2C bus with bit 0 being the direction bit, -+ * which is not represented here, and sent by the hardware directly. -+ * -+ * For instance, -+ * 50h = 1010000b => device type identifier 1010b, bits 18:16 = 000b, address 0. -+ * 54h = 1010100b => --"--, bits 18:16 = 100b, address 40000h. -+ * 56h = 1010110b => --"--, bits 18:16 = 110b, address 60000h. -+ * Depending on the size of the I2C EEPROM device(s), bits 18:16 may -+ * address memory in a device or a device on the I2C bus, depending on -+ * the status of pins 1-3. See top of amdgpu_eeprom.c. -+ * -+ * The RAS table lives either at address 0 or address 40000h of EEPROM. -+ */ -+#define EEPROM_I2C_MADDR_0 0x0 -+#define EEPROM_I2C_MADDR_4 0x40000 - - /* - * The 2 macros bellow represent the actual size in bytes that -@@ -90,33 +107,23 @@ - - static bool __is_ras_eeprom_supported(struct amdgpu_device *adev) - { -- return adev->asic_type == CHIP_VEGA20 || -- adev->asic_type == CHIP_ARCTURUS || -- adev->asic_type == CHIP_SIENNA_CICHLID || -- adev->asic_type == CHIP_ALDEBARAN; --} -- --static bool __get_eeprom_i2c_addr_arct(struct amdgpu_device *adev, -- struct amdgpu_ras_eeprom_control *control) --{ -- struct atom_context *atom_ctx = adev->mode_info.atom_context; -- -- if (!control || !atom_ctx) -+ switch (adev->ip_versions[MP1_HWIP][0]) { -+ case IP_VERSION(11, 0, 2): /* VEGA20 and ARCTURUS */ -+ case IP_VERSION(11, 0, 7): /* Sienna cichlid */ -+ case IP_VERSION(13, 0, 0): -+ case IP_VERSION(13, 0, 2): /* Aldebaran */ -+ case IP_VERSION(13, 0, 6): -+ case IP_VERSION(13, 0, 10): -+ return true; -+ default: - return false; -- -- if (strnstr(atom_ctx->vbios_version, -- "D342", -- sizeof(atom_ctx->vbios_version))) -- control->i2c_address = EEPROM_I2C_MADDR_ARCTURUS_D342; -- else -- control->i2c_address = EEPROM_I2C_MADDR_ARCTURUS; -- -- return true; -+ } - } - - static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, - struct amdgpu_ras_eeprom_control *control) - { -+ struct atom_context *atom_ctx = adev->mode_info.atom_context; - u8 i2c_addr; - - if (!control) -@@ -137,36 +144,42 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, - return true; - } - -- switch (adev->asic_type) { -- case CHIP_VEGA20: -- control->i2c_address = EEPROM_I2C_MADDR_VEGA20; -- break; -- -- case CHIP_ARCTURUS: -- return __get_eeprom_i2c_addr_arct(adev, control); -- -- case CHIP_SIENNA_CICHLID: -- control->i2c_address = EEPROM_I2C_MADDR_SIENNA_CICHLID; -- break; -- -- case CHIP_ALDEBARAN: -- control->i2c_address = EEPROM_I2C_MADDR_ALDEBARAN; -- break; -- -- default: -- return false; -- } -- - switch (adev->ip_versions[MP1_HWIP][0]) { -+ case IP_VERSION(11, 0, 2): -+ /* VEGA20 and ARCTURUS */ -+ if (adev->asic_type == CHIP_VEGA20) -+ control->i2c_address = EEPROM_I2C_MADDR_0; -+ else if (strnstr(atom_ctx->vbios_version, -+ "D342", -+ sizeof(atom_ctx->vbios_version))) -+ control->i2c_address = EEPROM_I2C_MADDR_0; -+ else -+ control->i2c_address = EEPROM_I2C_MADDR_4; -+ return true; -+ case IP_VERSION(11, 0, 7): -+ control->i2c_address = EEPROM_I2C_MADDR_0; -+ return true; -+ case IP_VERSION(13, 0, 2): -+ if (strnstr(atom_ctx->vbios_version, "D673", -+ sizeof(atom_ctx->vbios_version))) -+ control->i2c_address = EEPROM_I2C_MADDR_4; -+ else -+ control->i2c_address = EEPROM_I2C_MADDR_0; -+ return true; - case IP_VERSION(13, 0, 0): -- control->i2c_address = EEPROM_I2C_MADDR_SMU_13_0_0; -- break; -- -+ if (strnstr(atom_ctx->vbios_pn, "D707", -+ sizeof(atom_ctx->vbios_pn))) -+ control->i2c_address = EEPROM_I2C_MADDR_0; -+ else -+ control->i2c_address = EEPROM_I2C_MADDR_4; -+ return true; -+ case IP_VERSION(13, 0, 6): -+ case IP_VERSION(13, 0, 10): -+ control->i2c_address = EEPROM_I2C_MADDR_4; -+ return true; - default: -- break; -+ return false; - } -- -- return true; - } - - static void -diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c -index 23e7e5126eae6..66a6f7a37ebcf 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c -@@ -397,7 +397,7 @@ static int gfx_v11_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) - adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); - cpu_ptr = &adev->wb.wb[index]; - -- r = amdgpu_ib_get(adev, NULL, 16, AMDGPU_IB_POOL_DIRECT, &ib); -+ r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); - if (r) { - DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); - goto err1; -diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c -index 7f0b18b0d4c48..71ef25425c7f6 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c -@@ -883,8 +883,8 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) - gpu_addr = adev->wb.gpu_addr + (index * 4); - adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); - memset(&ib, 0, sizeof(ib)); -- r = amdgpu_ib_get(adev, NULL, 16, -- AMDGPU_IB_POOL_DIRECT, &ib); -+ -+ r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); - if (r) - goto err1; - -diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -index fe371022e5104..84ca601f7d5f3 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c -@@ -1034,8 +1034,8 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) - gpu_addr = adev->wb.gpu_addr + (index * 4); - adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); - memset(&ib, 0, sizeof(ib)); -- r = amdgpu_ib_get(adev, NULL, 16, -- AMDGPU_IB_POOL_DIRECT, &ib); -+ -+ r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); - if (r) - goto err1; - -diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig -index 57946d80b02db..12baf9ba03c96 100644 ---- a/drivers/gpu/drm/bridge/Kconfig -+++ b/drivers/gpu/drm/bridge/Kconfig -@@ -309,6 +309,7 @@ config DRM_TOSHIBA_TC358768 - select REGMAP_I2C - select DRM_PANEL - select DRM_MIPI_DSI -+ select VIDEOMODE_HELPERS - help - Toshiba TC358768AXBG/TC358778XBG DSI bridge chip driver. - -diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c -index 8219310025de5..f7422f0cf579d 100644 ---- a/drivers/gpu/drm/i915/display/icl_dsi.c -+++ b/drivers/gpu/drm/i915/display/icl_dsi.c -@@ -1500,6 +1500,13 @@ static void gen11_dsi_post_disable(struct intel_atomic_state *state, - static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) - { -+ struct drm_i915_private *i915 = to_i915(connector->dev); -+ enum drm_mode_status status; -+ -+ status = intel_cpu_transcoder_mode_valid(i915, mode); -+ if (status != MODE_OK) -+ return status; -+ - /* FIXME: DSC? */ - return intel_dsi_mode_valid(connector, mode); - } -diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c -index 4a8ff2f976085..e60b2cf84b851 100644 ---- a/drivers/gpu/drm/i915/display/intel_crt.c -+++ b/drivers/gpu/drm/i915/display/intel_crt.c -@@ -343,8 +343,13 @@ intel_crt_mode_valid(struct drm_connector *connector, - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); - int max_dotclk = dev_priv->max_dotclk_freq; -+ enum drm_mode_status status; - int max_clock; - -+ status = intel_cpu_transcoder_mode_valid(dev_priv, mode); -+ if (status != MODE_OK) -+ return status; -+ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - -diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c -index 96e679a176e94..1777a12f2f421 100644 ---- a/drivers/gpu/drm/i915/display/intel_display.c -+++ b/drivers/gpu/drm/i915/display/intel_display.c -@@ -8229,6 +8229,16 @@ intel_mode_valid(struct drm_device *dev, - mode->vtotal > vtotal_max) - return MODE_V_ILLEGAL; - -+ return MODE_OK; -+} -+ -+enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *dev_priv, -+ const struct drm_display_mode *mode) -+{ -+ /* -+ * Additional transcoder timing limits, -+ * excluding BXT/GLK DSI transcoders. -+ */ - if (DISPLAY_VER(dev_priv) >= 5) { - if (mode->hdisplay < 64 || - mode->htotal - mode->hdisplay < 32) -diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h -index 884e8e67b17c7..b4f941674357b 100644 ---- a/drivers/gpu/drm/i915/display/intel_display.h -+++ b/drivers/gpu/drm/i915/display/intel_display.h -@@ -554,6 +554,9 @@ enum drm_mode_status - intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, - const struct drm_display_mode *mode, - bool bigjoiner); -+enum drm_mode_status -+intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915, -+ const struct drm_display_mode *mode); - enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port); - bool is_trans_port_sync_mode(const struct intel_crtc_state *state); - bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state); -diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c -index 594ea037050a9..5970f4149090f 100644 ---- a/drivers/gpu/drm/i915/display/intel_dp.c -+++ b/drivers/gpu/drm/i915/display/intel_dp.c -@@ -973,8 +973,9 @@ intel_dp_mode_valid(struct drm_connector *_connector, - enum drm_mode_status status; - bool dsc = false, bigjoiner = false; - -- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) -- return MODE_NO_DBLESCAN; -+ status = intel_cpu_transcoder_mode_valid(dev_priv, mode); -+ if (status != MODE_OK) -+ return status; - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - return MODE_H_ILLEGAL; -diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c -index 9a6822256ddf6..eec32f682012c 100644 ---- a/drivers/gpu/drm/i915/display/intel_dp_mst.c -+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c -@@ -703,6 +703,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, - return 0; - } - -+ *status = intel_cpu_transcoder_mode_valid(dev_priv, mode); -+ if (*status != MODE_OK) -+ return 0; -+ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { - *status = MODE_NO_DBLESCAN; - return 0; -diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c -index 5572e43026e4d..511c589070087 100644 ---- a/drivers/gpu/drm/i915/display/intel_dvo.c -+++ b/drivers/gpu/drm/i915/display/intel_dvo.c -@@ -225,10 +225,16 @@ intel_dvo_mode_valid(struct drm_connector *connector, - { - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_dvo *intel_dvo = intel_attached_dvo(intel_connector); -+ struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); - const struct drm_display_mode *fixed_mode = - intel_panel_fixed_mode(intel_connector, mode); - int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; - int target_clock = mode->clock; -+ enum drm_mode_status status; -+ -+ status = intel_cpu_transcoder_mode_valid(i915, mode); -+ if (status != MODE_OK) -+ return status; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; -diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c -index 7816b2a33feeb..2600019fc8b96 100644 ---- a/drivers/gpu/drm/i915/display/intel_hdmi.c -+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c -@@ -1987,8 +1987,9 @@ intel_hdmi_mode_valid(struct drm_connector *connector, - bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state); - bool ycbcr_420_only; - -- if (mode->flags & DRM_MODE_FLAG_DBLSCAN) -- return MODE_NO_DBLESCAN; -+ status = intel_cpu_transcoder_mode_valid(dev_priv, mode); -+ if (status != MODE_OK) -+ return status; - - if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) - clock *= 2; -diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c -index a749a5a66d624..40b5d3d3c7e14 100644 ---- a/drivers/gpu/drm/i915/display/intel_lvds.c -+++ b/drivers/gpu/drm/i915/display/intel_lvds.c -@@ -92,9 +92,9 @@ bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv, - - /* asserts want to know the pipe even if the port is disabled */ - if (HAS_PCH_CPT(dev_priv)) -- *pipe = (val & LVDS_PIPE_SEL_MASK_CPT) >> LVDS_PIPE_SEL_SHIFT_CPT; -+ *pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK_CPT, val); - else -- *pipe = (val & LVDS_PIPE_SEL_MASK) >> LVDS_PIPE_SEL_SHIFT; -+ *pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK, val); - - return val & LVDS_PORT_EN; - } -@@ -389,11 +389,16 @@ intel_lvds_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) - { - struct intel_connector *intel_connector = to_intel_connector(connector); -+ struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); - const struct drm_display_mode *fixed_mode = - intel_panel_fixed_mode(intel_connector, mode); - int max_pixclk = to_i915(connector->dev)->max_dotclk_freq; - enum drm_mode_status status; - -+ status = intel_cpu_transcoder_mode_valid(i915, mode); -+ if (status != MODE_OK) -+ return status; -+ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - -diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c -index 2c2e0f041f869..8294dddfd9de8 100644 ---- a/drivers/gpu/drm/i915/display/intel_sdvo.c -+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c -@@ -115,7 +115,6 @@ struct intel_sdvo { - - enum port port; - -- bool has_hdmi_monitor; - bool has_hdmi_audio; - - /* DDC bus used by this SDVO encoder */ -@@ -1278,10 +1277,13 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config) - pipe_config->clock_set = true; - } - --static bool intel_has_hdmi_sink(struct intel_sdvo *sdvo, -+static bool intel_has_hdmi_sink(struct intel_sdvo_connector *intel_sdvo_connector, - const struct drm_connector_state *conn_state) - { -- return sdvo->has_hdmi_monitor && -+ struct drm_connector *connector = conn_state->connector; -+ -+ return intel_sdvo_connector->is_hdmi && -+ connector->display_info.is_hdmi && - READ_ONCE(to_intel_digital_connector_state(conn_state)->force_audio) != HDMI_AUDIO_OFF_DVI; - } - -@@ -1360,7 +1362,7 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, - pipe_config->pixel_multiplier = - intel_sdvo_get_pixel_multiplier(adjusted_mode); - -- pipe_config->has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo, conn_state); -+ pipe_config->has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, conn_state); - - if (pipe_config->has_hdmi_sink) { - if (intel_sdvo_state->base.force_audio == HDMI_AUDIO_AUTO) -@@ -1871,13 +1873,19 @@ static enum drm_mode_status - intel_sdvo_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) - { -+ struct drm_i915_private *i915 = to_i915(connector->dev); - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector)); - struct intel_sdvo_connector *intel_sdvo_connector = - to_intel_sdvo_connector(connector); -- int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; -- bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo, connector->state); -+ bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, connector->state); -+ int max_dotclk = i915->max_dotclk_freq; -+ enum drm_mode_status status; - int clock = mode->clock; - -+ status = intel_cpu_transcoder_mode_valid(i915, mode); -+ if (status != MODE_OK) -+ return status; -+ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - -@@ -2064,7 +2072,6 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector) - if (edid->input & DRM_EDID_INPUT_DIGITAL) { - status = connector_status_connected; - if (intel_sdvo_connector->is_hdmi) { -- intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); - intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); - } - } else -@@ -2116,7 +2123,6 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) - - intel_sdvo->attached_output = response; - -- intel_sdvo->has_hdmi_monitor = false; - intel_sdvo->has_hdmi_audio = false; - - if ((intel_sdvo_connector->output_flag & response) == 0) -diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c -index dcf89d701f0f6..fb25be800e753 100644 ---- a/drivers/gpu/drm/i915/display/intel_tv.c -+++ b/drivers/gpu/drm/i915/display/intel_tv.c -@@ -956,8 +956,14 @@ static enum drm_mode_status - intel_tv_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) - { -+ struct drm_i915_private *i915 = to_i915(connector->dev); - const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state); -- int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; -+ int max_dotclk = i915->max_dotclk_freq; -+ enum drm_mode_status status; -+ -+ status = intel_cpu_transcoder_mode_valid(i915, mode); -+ if (status != MODE_OK) -+ return status; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; -diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c -index 00c80f29ad999..114088ca59ed4 100644 ---- a/drivers/gpu/drm/i915/display/vlv_dsi.c -+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c -@@ -1627,9 +1627,25 @@ static const struct drm_encoder_funcs intel_dsi_funcs = { - .destroy = intel_dsi_encoder_destroy, - }; - -+static enum drm_mode_status vlv_dsi_mode_valid(struct drm_connector *connector, -+ struct drm_display_mode *mode) -+{ -+ struct drm_i915_private *i915 = to_i915(connector->dev); -+ -+ if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { -+ enum drm_mode_status status; -+ -+ status = intel_cpu_transcoder_mode_valid(i915, mode); -+ if (status != MODE_OK) -+ return status; -+ } -+ -+ return intel_dsi_mode_valid(connector, mode); -+} -+ - static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = { - .get_modes = intel_dsi_get_modes, -- .mode_valid = intel_dsi_mode_valid, -+ .mode_valid = vlv_dsi_mode_valid, - .atomic_check = intel_digital_connector_atomic_check, - }; - -diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h -index 25015996f627a..c6766704340eb 100644 ---- a/drivers/gpu/drm/i915/i915_reg.h -+++ b/drivers/gpu/drm/i915/i915_reg.h -@@ -2681,52 +2681,50 @@ - * Enables the LVDS port. This bit must be set before DPLLs are enabled, as - * the DPLL semantics change when the LVDS is assigned to that pipe. - */ --#define LVDS_PORT_EN (1 << 31) -+#define LVDS_PORT_EN REG_BIT(31) - /* Selects pipe B for LVDS data. Must be set on pre-965. */ --#define LVDS_PIPE_SEL_SHIFT 30 --#define LVDS_PIPE_SEL_MASK (1 << 30) --#define LVDS_PIPE_SEL(pipe) ((pipe) << 30) --#define LVDS_PIPE_SEL_SHIFT_CPT 29 --#define LVDS_PIPE_SEL_MASK_CPT (3 << 29) --#define LVDS_PIPE_SEL_CPT(pipe) ((pipe) << 29) -+#define LVDS_PIPE_SEL_MASK REG_BIT(30) -+#define LVDS_PIPE_SEL(pipe) REG_FIELD_PREP(LVDS_PIPE_SEL_MASK, (pipe)) -+#define LVDS_PIPE_SEL_MASK_CPT REG_GENMASK(30, 29) -+#define LVDS_PIPE_SEL_CPT(pipe) REG_FIELD_PREP(LVDS_PIPE_SEL_MASK_CPT, (pipe)) - /* LVDS dithering flag on 965/g4x platform */ --#define LVDS_ENABLE_DITHER (1 << 25) -+#define LVDS_ENABLE_DITHER REG_BIT(25) - /* LVDS sync polarity flags. Set to invert (i.e. negative) */ --#define LVDS_VSYNC_POLARITY (1 << 21) --#define LVDS_HSYNC_POLARITY (1 << 20) -+#define LVDS_VSYNC_POLARITY REG_BIT(21) -+#define LVDS_HSYNC_POLARITY REG_BIT(20) - - /* Enable border for unscaled (or aspect-scaled) display */ --#define LVDS_BORDER_ENABLE (1 << 15) -+#define LVDS_BORDER_ENABLE REG_BIT(15) - /* - * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per - * pixel. - */ --#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) --#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) --#define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -+#define LVDS_A0A2_CLKA_POWER_MASK REG_GENMASK(9, 8) -+#define LVDS_A0A2_CLKA_POWER_DOWN REG_FIELD_PREP(LVDS_A0A2_CLKA_POWER_MASK, 0) -+#define LVDS_A0A2_CLKA_POWER_UP REG_FIELD_PREP(LVDS_A0A2_CLKA_POWER_MASK, 3) - /* - * Controls the A3 data pair, which contains the additional LSBs for 24 bit - * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be - * on. - */ --#define LVDS_A3_POWER_MASK (3 << 6) --#define LVDS_A3_POWER_DOWN (0 << 6) --#define LVDS_A3_POWER_UP (3 << 6) -+#define LVDS_A3_POWER_MASK REG_GENMASK(7, 6) -+#define LVDS_A3_POWER_DOWN REG_FIELD_PREP(LVDS_A3_POWER_MASK, 0) -+#define LVDS_A3_POWER_UP REG_FIELD_PREP(LVDS_A3_POWER_MASK, 3) - /* - * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP - * is set. - */ --#define LVDS_CLKB_POWER_MASK (3 << 4) --#define LVDS_CLKB_POWER_DOWN (0 << 4) --#define LVDS_CLKB_POWER_UP (3 << 4) -+#define LVDS_CLKB_POWER_MASK REG_GENMASK(5, 4) -+#define LVDS_CLKB_POWER_DOWN REG_FIELD_PREP(LVDS_CLKB_POWER_MASK, 0) -+#define LVDS_CLKB_POWER_UP REG_FIELD_PREP(LVDS_CLKB_POWER_MASK, 3) - /* - * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 - * setting for whether we are in dual-channel mode. The B3 pair will - * additionally only be powered up when LVDS_A3_POWER_UP is set. - */ --#define LVDS_B0B3_POWER_MASK (3 << 2) --#define LVDS_B0B3_POWER_DOWN (0 << 2) --#define LVDS_B0B3_POWER_UP (3 << 2) -+#define LVDS_B0B3_POWER_MASK REG_GENMASK(3, 2) -+#define LVDS_B0B3_POWER_DOWN REG_FIELD_PREP(LVDS_B0B3_POWER_MASK, 0) -+#define LVDS_B0B3_POWER_UP REG_FIELD_PREP(LVDS_B0B3_POWER_MASK, 3) - - /* Video Data Island Packet control */ - #define VIDEO_DIP_DATA _MMIO(0x61178) -@@ -6461,7 +6459,7 @@ - #define FDI_PLL_CTL_2 _MMIO(0xfe004) - - #define PCH_LVDS _MMIO(0xe1180) --#define LVDS_DETECTED (1 << 1) -+#define LVDS_DETECTED REG_BIT(1) - - #define _PCH_DP_B 0xe4100 - #define PCH_DP_B _MMIO(_PCH_DP_B) -diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c -index 0962c12eba5a0..2147afb725581 100644 ---- a/drivers/hwmon/acpi_power_meter.c -+++ b/drivers/hwmon/acpi_power_meter.c -@@ -31,6 +31,7 @@ - #define POWER_METER_CAN_NOTIFY (1 << 3) - #define POWER_METER_IS_BATTERY (1 << 8) - #define UNKNOWN_HYSTERESIS 0xFFFFFFFF -+#define UNKNOWN_POWER 0xFFFFFFFF - - #define METER_NOTIFY_CONFIG 0x80 - #define METER_NOTIFY_TRIP 0x81 -@@ -348,6 +349,9 @@ static ssize_t show_power(struct device *dev, - update_meter(resource); - mutex_unlock(&resource->lock); - -+ if (resource->power == UNKNOWN_POWER) -+ return -ENODATA; -+ - return sprintf(buf, "%llu\n", resource->power * 1000); - } - -diff --git a/drivers/hwmon/nzxt-kraken2.c b/drivers/hwmon/nzxt-kraken2.c -index 89f7ea4f42d47..badbcaf01f90b 100644 ---- a/drivers/hwmon/nzxt-kraken2.c -+++ b/drivers/hwmon/nzxt-kraken2.c -@@ -161,13 +161,13 @@ static int kraken2_probe(struct hid_device *hdev, - ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); - if (ret) { - hid_err(hdev, "hid hw start failed with %d\n", ret); -- goto fail_and_stop; -+ return ret; - } - - ret = hid_hw_open(hdev); - if (ret) { - hid_err(hdev, "hid hw open failed with %d\n", ret); -- goto fail_and_close; -+ goto fail_and_stop; - } - - priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "kraken2", -diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c -index 1cf7478da6ee8..fda48a0afc1a5 100644 ---- a/drivers/hwtracing/coresight/coresight-etm4x-core.c -+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c -@@ -2072,7 +2072,7 @@ static void clear_etmdrvdata(void *info) - etmdrvdata[cpu] = NULL; - } - --static int __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) -+static void etm4_remove_dev(struct etmv4_drvdata *drvdata) - { - etm_perf_symlink(drvdata->csdev, false); - /* -@@ -2094,10 +2094,9 @@ static int __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) - cscfg_unregister_csdev(drvdata->csdev); - coresight_unregister(drvdata->csdev); - -- return 0; - } - --static void __exit etm4_remove_amba(struct amba_device *adev) -+static void etm4_remove_amba(struct amba_device *adev) - { - struct etmv4_drvdata *drvdata = dev_get_drvdata(&adev->dev); - -@@ -2105,15 +2104,14 @@ static void __exit etm4_remove_amba(struct amba_device *adev) - etm4_remove_dev(drvdata); - } - --static int __exit etm4_remove_platform_dev(struct platform_device *pdev) -+static int etm4_remove_platform_dev(struct platform_device *pdev) - { -- int ret = 0; - struct etmv4_drvdata *drvdata = dev_get_drvdata(&pdev->dev); - - if (drvdata) -- ret = etm4_remove_dev(drvdata); -+ etm4_remove_dev(drvdata); - pm_runtime_disable(&pdev->dev); -- return ret; -+ return 0; - } - - static const struct amba_id etm4_ids[] = { -diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c -index 4140efd664097..016220ba0addd 100644 ---- a/drivers/hwtracing/ptt/hisi_ptt.c -+++ b/drivers/hwtracing/ptt/hisi_ptt.c -@@ -837,6 +837,10 @@ static void hisi_ptt_pmu_del(struct perf_event *event, int flags) - hisi_ptt_pmu_stop(event, PERF_EF_UPDATE); - } - -+static void hisi_ptt_pmu_read(struct perf_event *event) -+{ -+} -+ - static void hisi_ptt_remove_cpuhp_instance(void *hotplug_node) - { - cpuhp_state_remove_instance_nocalls(hisi_ptt_pmu_online, hotplug_node); -@@ -880,6 +884,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt) - .stop = hisi_ptt_pmu_stop, - .add = hisi_ptt_pmu_add, - .del = hisi_ptt_pmu_del, -+ .read = hisi_ptt_pmu_read, - }; - - reg = readl(hisi_ptt->iobase + HISI_PTT_LOCATION); -diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c -index 6fdb25a5f8016..ad98c85ec2e7a 100644 ---- a/drivers/i2c/busses/i2c-designware-common.c -+++ b/drivers/i2c/busses/i2c-designware-common.c -@@ -63,7 +63,7 @@ static int dw_reg_read(void *context, unsigned int reg, unsigned int *val) - { - struct dw_i2c_dev *dev = context; - -- *val = readl_relaxed(dev->base + reg); -+ *val = readl(dev->base + reg); - - return 0; - } -@@ -72,7 +72,7 @@ static int dw_reg_write(void *context, unsigned int reg, unsigned int val) - { - struct dw_i2c_dev *dev = context; - -- writel_relaxed(val, dev->base + reg); -+ writel(val, dev->base + reg); - - return 0; - } -@@ -81,7 +81,7 @@ static int dw_reg_read_swab(void *context, unsigned int reg, unsigned int *val) - { - struct dw_i2c_dev *dev = context; - -- *val = swab32(readl_relaxed(dev->base + reg)); -+ *val = swab32(readl(dev->base + reg)); - - return 0; - } -@@ -90,7 +90,7 @@ static int dw_reg_write_swab(void *context, unsigned int reg, unsigned int val) - { - struct dw_i2c_dev *dev = context; - -- writel_relaxed(swab32(val), dev->base + reg); -+ writel(swab32(val), dev->base + reg); - - return 0; - } -@@ -99,8 +99,8 @@ static int dw_reg_read_word(void *context, unsigned int reg, unsigned int *val) - { - struct dw_i2c_dev *dev = context; - -- *val = readw_relaxed(dev->base + reg) | -- (readw_relaxed(dev->base + reg + 2) << 16); -+ *val = readw(dev->base + reg) | -+ (readw(dev->base + reg + 2) << 16); - - return 0; - } -@@ -109,8 +109,8 @@ static int dw_reg_write_word(void *context, unsigned int reg, unsigned int val) - { - struct dw_i2c_dev *dev = context; - -- writew_relaxed(val, dev->base + reg); -- writew_relaxed(val >> 16, dev->base + reg + 2); -+ writew(val, dev->base + reg); -+ writew(val >> 16, dev->base + reg + 2); - - return 0; - } -diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c -index 957634eceba8f..8ce569bf7525e 100644 ---- a/drivers/infiniband/core/umem.c -+++ b/drivers/infiniband/core/umem.c -@@ -96,12 +96,6 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, - return page_size; - } - -- /* rdma_for_each_block() has a bug if the page size is smaller than the -- * page size used to build the umem. For now prevent smaller page sizes -- * from being returned. -- */ -- pgsz_bitmap &= GENMASK(BITS_PER_LONG - 1, PAGE_SHIFT); -- - /* The best result is the smallest page size that results in the minimum - * number of required pages. Compute the largest page size that could - * work based on VA address bits that don't change. -diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c -index e58893387bb4d..43d396a7d8e16 100644 ---- a/drivers/infiniband/hw/bnxt_re/main.c -+++ b/drivers/infiniband/hw/bnxt_re/main.c -@@ -70,7 +70,7 @@ static char version[] = - BNXT_RE_DESC "\n"; - - MODULE_AUTHOR("Eddie Wai "); --MODULE_DESCRIPTION(BNXT_RE_DESC " Driver"); -+MODULE_DESCRIPTION(BNXT_RE_DESC); - MODULE_LICENSE("Dual BSD/GPL"); - - /* globals */ -diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -index 8a9d28f81149a..c2ee80546d120 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -@@ -4913,10 +4913,15 @@ static int check_cong_type(struct ib_qp *ibqp, - cong_alg->wnd_mode_sel = WND_LIMIT; - break; - default: -- ibdev_err(&hr_dev->ib_dev, -- "error type(%u) for congestion selection.\n", -- hr_dev->caps.cong_type); -- return -EINVAL; -+ ibdev_warn(&hr_dev->ib_dev, -+ "invalid type(%u) for congestion selection.\n", -+ hr_dev->caps.cong_type); -+ hr_dev->caps.cong_type = CONG_TYPE_DCQCN; -+ cong_alg->alg_sel = CONG_DCQCN; -+ cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; -+ cong_alg->dip_vld = DIP_INVALID; -+ cong_alg->wnd_mode_sel = WND_LIMIT; -+ break; - } - - return 0; -diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c -index c07ce85d243f1..311a1138e838d 100644 ---- a/drivers/infiniband/hw/irdma/hw.c -+++ b/drivers/infiniband/hw/irdma/hw.c -@@ -322,7 +322,11 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) - break; - case IRDMA_AE_QP_SUSPEND_COMPLETE: - if (iwqp->iwdev->vsi.tc_change_pending) { -- atomic_dec(&iwqp->sc_qp.vsi->qp_suspend_reqs); -+ if (!atomic_dec_return(&qp->vsi->qp_suspend_reqs)) -+ wake_up(&iwqp->iwdev->suspend_wq); -+ } -+ if (iwqp->suspend_pending) { -+ iwqp->suspend_pending = false; - wake_up(&iwqp->iwdev->suspend_wq); - } - break; -@@ -568,16 +572,13 @@ static void irdma_destroy_irq(struct irdma_pci_f *rf, - * Issue destroy cqp request and - * free the resources associated with the cqp - */ --static void irdma_destroy_cqp(struct irdma_pci_f *rf, bool free_hwcqp) -+static void irdma_destroy_cqp(struct irdma_pci_f *rf) - { - struct irdma_sc_dev *dev = &rf->sc_dev; - struct irdma_cqp *cqp = &rf->cqp; - int status = 0; - -- if (rf->cqp_cmpl_wq) -- destroy_workqueue(rf->cqp_cmpl_wq); -- if (free_hwcqp) -- status = irdma_sc_cqp_destroy(dev->cqp); -+ status = irdma_sc_cqp_destroy(dev->cqp); - if (status) - ibdev_dbg(to_ibdev(dev), "ERR: Destroy CQP failed %d\n", status); - -@@ -741,6 +742,9 @@ static void irdma_destroy_ccq(struct irdma_pci_f *rf) - struct irdma_ccq *ccq = &rf->ccq; - int status = 0; - -+ if (rf->cqp_cmpl_wq) -+ destroy_workqueue(rf->cqp_cmpl_wq); -+ - if (!rf->reset) - status = irdma_sc_ccq_destroy(dev->ccq, 0, true); - if (status) -@@ -921,8 +925,8 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) - - cqp->scratch_array = kcalloc(sqsize, sizeof(*cqp->scratch_array), GFP_KERNEL); - if (!cqp->scratch_array) { -- kfree(cqp->cqp_requests); -- return -ENOMEM; -+ status = -ENOMEM; -+ goto err_scratch; - } - - dev->cqp = &cqp->sc_cqp; -@@ -932,15 +936,14 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) - cqp->sq.va = dma_alloc_coherent(dev->hw->device, cqp->sq.size, - &cqp->sq.pa, GFP_KERNEL); - if (!cqp->sq.va) { -- kfree(cqp->scratch_array); -- kfree(cqp->cqp_requests); -- return -ENOMEM; -+ status = -ENOMEM; -+ goto err_sq; - } - - status = irdma_obj_aligned_mem(rf, &mem, sizeof(struct irdma_cqp_ctx), - IRDMA_HOST_CTX_ALIGNMENT_M); - if (status) -- goto exit; -+ goto err_ctx; - - dev->cqp->host_ctx_pa = mem.pa; - dev->cqp->host_ctx = mem.va; -@@ -966,7 +969,7 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) - status = irdma_sc_cqp_init(dev->cqp, &cqp_init_info); - if (status) { - ibdev_dbg(to_ibdev(dev), "ERR: cqp init status %d\n", status); -- goto exit; -+ goto err_ctx; - } - - spin_lock_init(&cqp->req_lock); -@@ -977,7 +980,7 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) - ibdev_dbg(to_ibdev(dev), - "ERR: cqp create failed - status %d maj_err %d min_err %d\n", - status, maj_err, min_err); -- goto exit; -+ goto err_ctx; - } - - INIT_LIST_HEAD(&cqp->cqp_avail_reqs); -@@ -991,8 +994,16 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) - init_waitqueue_head(&cqp->remove_wq); - return 0; - --exit: -- irdma_destroy_cqp(rf, false); -+err_ctx: -+ dma_free_coherent(dev->hw->device, cqp->sq.size, -+ cqp->sq.va, cqp->sq.pa); -+ cqp->sq.va = NULL; -+err_sq: -+ kfree(cqp->scratch_array); -+ cqp->scratch_array = NULL; -+err_scratch: -+ kfree(cqp->cqp_requests); -+ cqp->cqp_requests = NULL; - - return status; - } -@@ -1159,7 +1170,6 @@ static int irdma_create_ceq(struct irdma_pci_f *rf, struct irdma_ceq *iwceq, - int status; - struct irdma_ceq_init_info info = {}; - struct irdma_sc_dev *dev = &rf->sc_dev; -- u64 scratch; - u32 ceq_size; - - info.ceq_id = ceq_id; -@@ -1180,14 +1190,13 @@ static int irdma_create_ceq(struct irdma_pci_f *rf, struct irdma_ceq *iwceq, - iwceq->sc_ceq.ceq_id = ceq_id; - info.dev = dev; - info.vsi = vsi; -- scratch = (uintptr_t)&rf->cqp.sc_cqp; - status = irdma_sc_ceq_init(&iwceq->sc_ceq, &info); - if (!status) { - if (dev->ceq_valid) - status = irdma_cqp_ceq_cmd(&rf->sc_dev, &iwceq->sc_ceq, - IRDMA_OP_CEQ_CREATE); - else -- status = irdma_sc_cceq_create(&iwceq->sc_ceq, scratch); -+ status = irdma_sc_cceq_create(&iwceq->sc_ceq, 0); - } - - if (status) { -@@ -1740,7 +1749,7 @@ void irdma_ctrl_deinit_hw(struct irdma_pci_f *rf) - rf->reset, rf->rdma_ver); - fallthrough; - case CQP_CREATED: -- irdma_destroy_cqp(rf, true); -+ irdma_destroy_cqp(rf); - fallthrough; - case INITIAL_STATE: - irdma_del_init_mem(rf); -diff --git a/drivers/infiniband/hw/irdma/main.c b/drivers/infiniband/hw/irdma/main.c -index 514453777e07d..be1030d1adfaf 100644 ---- a/drivers/infiniband/hw/irdma/main.c -+++ b/drivers/infiniband/hw/irdma/main.c -@@ -48,7 +48,7 @@ static void irdma_prep_tc_change(struct irdma_device *iwdev) - /* Wait for all qp's to suspend */ - wait_event_timeout(iwdev->suspend_wq, - !atomic_read(&iwdev->vsi.qp_suspend_reqs), -- IRDMA_EVENT_TIMEOUT); -+ msecs_to_jiffies(IRDMA_EVENT_TIMEOUT_MS)); - irdma_ws_reset(&iwdev->vsi); - } - -diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h -index 9cbe64311f985..6a6b14d8fca45 100644 ---- a/drivers/infiniband/hw/irdma/main.h -+++ b/drivers/infiniband/hw/irdma/main.h -@@ -78,7 +78,7 @@ extern struct auxiliary_driver i40iw_auxiliary_drv; - - #define MAX_DPC_ITERATIONS 128 - --#define IRDMA_EVENT_TIMEOUT 50000 -+#define IRDMA_EVENT_TIMEOUT_MS 5000 - #define IRDMA_VCHNL_EVENT_TIMEOUT 100000 - #define IRDMA_RST_TIMEOUT_HZ 4 - -diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c -index 3b8b2341981ea..447e1bcc82a32 100644 ---- a/drivers/infiniband/hw/irdma/verbs.c -+++ b/drivers/infiniband/hw/irdma/verbs.c -@@ -1098,6 +1098,21 @@ static int irdma_query_pkey(struct ib_device *ibdev, u32 port, u16 index, - return 0; - } - -+static int irdma_wait_for_suspend(struct irdma_qp *iwqp) -+{ -+ if (!wait_event_timeout(iwqp->iwdev->suspend_wq, -+ !iwqp->suspend_pending, -+ msecs_to_jiffies(IRDMA_EVENT_TIMEOUT_MS))) { -+ iwqp->suspend_pending = false; -+ ibdev_warn(&iwqp->iwdev->ibdev, -+ "modify_qp timed out waiting for suspend. qp_id = %d, last_ae = 0x%x\n", -+ iwqp->ibqp.qp_num, iwqp->last_aeq); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ - /** - * irdma_modify_qp_roce - modify qp request - * @ibqp: qp's pointer for modify -@@ -1359,17 +1374,11 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr, - - info.next_iwarp_state = IRDMA_QP_STATE_SQD; - issue_modify_qp = 1; -+ iwqp->suspend_pending = true; - break; - case IB_QPS_SQE: - case IB_QPS_ERR: - case IB_QPS_RESET: -- if (iwqp->iwarp_state == IRDMA_QP_STATE_RTS) { -- spin_unlock_irqrestore(&iwqp->lock, flags); -- info.next_iwarp_state = IRDMA_QP_STATE_SQD; -- irdma_hw_modify_qp(iwdev, iwqp, &info, true); -- spin_lock_irqsave(&iwqp->lock, flags); -- } -- - if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) { - spin_unlock_irqrestore(&iwqp->lock, flags); - if (udata && udata->inlen) { -@@ -1406,6 +1415,11 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr, - ctx_info->rem_endpoint_idx = udp_info->arp_idx; - if (irdma_hw_modify_qp(iwdev, iwqp, &info, true)) - return -EINVAL; -+ if (info.next_iwarp_state == IRDMA_QP_STATE_SQD) { -+ ret = irdma_wait_for_suspend(iwqp); -+ if (ret) -+ return ret; -+ } - spin_lock_irqsave(&iwqp->lock, flags); - if (iwqp->iwarp_state == info.curr_iwarp_state) { - iwqp->iwarp_state = info.next_iwarp_state; -diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h -index a536e9fa85ebf..9f9e273bbff3e 100644 ---- a/drivers/infiniband/hw/irdma/verbs.h -+++ b/drivers/infiniband/hw/irdma/verbs.h -@@ -193,6 +193,7 @@ struct irdma_qp { - u8 flush_issued : 1; - u8 sig_all : 1; - u8 pau_mode : 1; -+ u8 suspend_pending : 1; - u8 rsvd : 1; - u8 iwarp_state; - u16 term_sq_flush_code; -diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c -index a67f58359de9e..cc07c91f9c549 100644 ---- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c -+++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c -@@ -382,7 +382,7 @@ static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno, - struct rtrs_clt_path *clt_path; - int err; - -- if (WARN_ON(!req->in_use)) -+ if (!req->in_use) - return; - if (WARN_ON(!req->con)) - return; -@@ -1694,7 +1694,7 @@ static int create_con_cq_qp(struct rtrs_clt_con *con) - clt_path->s.dev_ref++; - max_send_wr = min_t(int, wr_limit, - /* QD * (REQ + RSP + FR REGS or INVS) + drain */ -- clt_path->queue_depth * 3 + 1); -+ clt_path->queue_depth * 4 + 1); - max_recv_wr = min_t(int, wr_limit, - clt_path->queue_depth * 3 + 1); - max_send_sge = 2; -@@ -2346,8 +2346,6 @@ static int init_conns(struct rtrs_clt_path *clt_path) - if (err) - goto destroy; - -- rtrs_start_hb(&clt_path->s); -- - return 0; - - destroy: -@@ -2621,6 +2619,7 @@ static int init_path(struct rtrs_clt_path *clt_path) - goto out; - } - rtrs_clt_path_up(clt_path); -+ rtrs_start_hb(&clt_path->s); - out: - mutex_unlock(&clt_path->init_mutex); - -diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c -index 22d7ba05e9fe8..e978ee4bb73ae 100644 ---- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c -+++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c -@@ -63,8 +63,9 @@ static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path, - { - enum rtrs_srv_state old_state; - bool changed = false; -+ unsigned long flags; - -- spin_lock_irq(&srv_path->state_lock); -+ spin_lock_irqsave(&srv_path->state_lock, flags); - old_state = srv_path->state; - switch (new_state) { - case RTRS_SRV_CONNECTED: -@@ -85,7 +86,7 @@ static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path, - } - if (changed) - srv_path->state = new_state; -- spin_unlock_irq(&srv_path->state_lock); -+ spin_unlock_irqrestore(&srv_path->state_lock, flags); - - return changed; - } -@@ -548,7 +549,10 @@ static void unmap_cont_bufs(struct rtrs_srv_path *srv_path) - struct rtrs_srv_mr *srv_mr; - - srv_mr = &srv_path->mrs[i]; -- rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1); -+ -+ if (always_invalidate) -+ rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1); -+ - ib_dereg_mr(srv_mr->mr); - ib_dma_unmap_sg(srv_path->s.dev->ib_dev, srv_mr->sgt.sgl, - srv_mr->sgt.nents, DMA_BIDIRECTIONAL); -@@ -714,20 +718,23 @@ static void rtrs_srv_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc) - WARN_ON(wc->opcode != IB_WC_SEND); - } - --static void rtrs_srv_path_up(struct rtrs_srv_path *srv_path) -+static int rtrs_srv_path_up(struct rtrs_srv_path *srv_path) - { - struct rtrs_srv_sess *srv = srv_path->srv; - struct rtrs_srv_ctx *ctx = srv->ctx; -- int up; -+ int up, ret = 0; - - mutex_lock(&srv->paths_ev_mutex); - up = ++srv->paths_up; - if (up == 1) -- ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL); -+ ret = ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL); - mutex_unlock(&srv->paths_ev_mutex); - - /* Mark session as established */ -- srv_path->established = true; -+ if (!ret) -+ srv_path->established = true; -+ -+ return ret; - } - - static void rtrs_srv_path_down(struct rtrs_srv_path *srv_path) -@@ -856,7 +863,12 @@ static int process_info_req(struct rtrs_srv_con *con, - goto iu_free; - kobject_get(&srv_path->kobj); - get_device(&srv_path->srv->dev); -- rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED); -+ err = rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED); -+ if (!err) { -+ rtrs_err(s, "rtrs_srv_change_state(), err: %d\n", err); -+ goto iu_free; -+ } -+ - rtrs_srv_start_hb(srv_path); - - /* -@@ -865,7 +877,11 @@ static int process_info_req(struct rtrs_srv_con *con, - * all connections are successfully established. Thus, simply notify - * listener with a proper event if we are the first path. - */ -- rtrs_srv_path_up(srv_path); -+ err = rtrs_srv_path_up(srv_path); -+ if (err) { -+ rtrs_err(s, "rtrs_srv_path_up(), err: %d\n", err); -+ goto iu_free; -+ } - - ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev, - tx_iu->dma_addr, -@@ -1521,7 +1537,6 @@ static void rtrs_srv_close_work(struct work_struct *work) - - srv_path = container_of(work, typeof(*srv_path), close_work); - -- rtrs_srv_destroy_path_files(srv_path); - rtrs_srv_stop_hb(srv_path); - - for (i = 0; i < srv_path->s.con_num; i++) { -@@ -1541,6 +1556,8 @@ static void rtrs_srv_close_work(struct work_struct *work) - /* Wait for all completion */ - wait_for_completion(&srv_path->complete_done); - -+ rtrs_srv_destroy_path_files(srv_path); -+ - /* Notify upper layer if we are the last path */ - rtrs_srv_path_down(srv_path); - -diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c -index 2bcd1f23d07d2..8b38972394776 100644 ---- a/drivers/iommu/iommu.c -+++ b/drivers/iommu/iommu.c -@@ -278,12 +278,13 @@ static void dev_iommu_free(struct device *dev) - kfree(param); - } - -+DEFINE_MUTEX(iommu_probe_device_lock); -+ - static int __iommu_probe_device(struct device *dev, struct list_head *group_list) - { - const struct iommu_ops *ops = dev->bus->iommu_ops; - struct iommu_device *iommu_dev; - struct iommu_group *group; -- static DEFINE_MUTEX(iommu_probe_device_lock); - int ret; - - if (!ops) -@@ -295,11 +296,9 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list - * probably be able to use device_lock() here to minimise the scope, - * but for now enforcing a simple global ordering is fine. - */ -- mutex_lock(&iommu_probe_device_lock); -- if (!dev_iommu_get(dev)) { -- ret = -ENOMEM; -- goto err_unlock; -- } -+ lockdep_assert_held(&iommu_probe_device_lock); -+ if (!dev_iommu_get(dev)) -+ return -ENOMEM; - - if (!try_module_get(ops->owner)) { - ret = -EINVAL; -@@ -326,7 +325,6 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list - mutex_unlock(&group->mutex); - iommu_group_put(group); - -- mutex_unlock(&iommu_probe_device_lock); - iommu_device_link(iommu_dev, dev); - - return 0; -@@ -341,9 +339,6 @@ out_module_put: - err_free: - dev_iommu_free(dev); - --err_unlock: -- mutex_unlock(&iommu_probe_device_lock); -- - return ret; - } - -@@ -353,7 +348,9 @@ int iommu_probe_device(struct device *dev) - struct iommu_group *group; - int ret; - -+ mutex_lock(&iommu_probe_device_lock); - ret = __iommu_probe_device(dev, NULL); -+ mutex_unlock(&iommu_probe_device_lock); - if (ret) - goto err_out; - -@@ -1684,7 +1681,9 @@ static int probe_iommu_group(struct device *dev, void *data) - return 0; - } - -+ mutex_lock(&iommu_probe_device_lock); - ret = __iommu_probe_device(dev, group_list); -+ mutex_unlock(&iommu_probe_device_lock); - if (ret == -ENODEV) - ret = 0; - -diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c -index 5696314ae69e7..1fa1db3be8529 100644 ---- a/drivers/iommu/of_iommu.c -+++ b/drivers/iommu/of_iommu.c -@@ -112,16 +112,20 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, - const u32 *id) - { - const struct iommu_ops *ops = NULL; -- struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); -+ struct iommu_fwspec *fwspec; - int err = NO_IOMMU; - - if (!master_np) - return NULL; - -+ /* Serialise to make dev->iommu stable under our potential fwspec */ -+ mutex_lock(&iommu_probe_device_lock); -+ fwspec = dev_iommu_fwspec_get(dev); - if (fwspec) { -- if (fwspec->ops) -+ if (fwspec->ops) { -+ mutex_unlock(&iommu_probe_device_lock); - return fwspec->ops; -- -+ } - /* In the deferred case, start again from scratch */ - iommu_fwspec_free(dev); - } -@@ -155,6 +159,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, - fwspec = dev_iommu_fwspec_get(dev); - ops = fwspec->ops; - } -+ mutex_unlock(&iommu_probe_device_lock); -+ - /* - * If we have reason to believe the IOMMU driver missed the initial - * probe for dev, replay it to get things in order. -diff --git a/drivers/md/md.c b/drivers/md/md.c -index 20f67edae95d0..0c2801d770901 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -93,6 +93,18 @@ static int remove_and_add_spares(struct mddev *mddev, - struct md_rdev *this); - static void mddev_detach(struct mddev *mddev); - -+enum md_ro_state { -+ MD_RDWR, -+ MD_RDONLY, -+ MD_AUTO_READ, -+ MD_MAX_STATE -+}; -+ -+static bool md_is_rdwr(struct mddev *mddev) -+{ -+ return (mddev->ro == MD_RDWR); -+} -+ - /* - * Default number of read corrections we'll attempt on an rdev - * before ejecting it from the array. We divide the read error -@@ -444,7 +456,7 @@ static void md_submit_bio(struct bio *bio) - if (!bio) - return; - -- if (mddev->ro == 1 && unlikely(rw == WRITE)) { -+ if (mddev->ro == MD_RDONLY && unlikely(rw == WRITE)) { - if (bio_sectors(bio) != 0) - bio->bi_status = BLK_STS_IOERR; - bio_endio(bio); -@@ -2643,7 +2655,7 @@ void md_update_sb(struct mddev *mddev, int force_change) - int any_badblocks_changed = 0; - int ret = -1; - -- if (mddev->ro) { -+ if (!md_is_rdwr(mddev)) { - if (force_change) - set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags); - return; -@@ -3909,7 +3921,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len) - goto out_unlock; - } - rv = -EROFS; -- if (mddev->ro) -+ if (!md_is_rdwr(mddev)) - goto out_unlock; - - /* request to change the personality. Need to ensure: -@@ -4115,7 +4127,7 @@ layout_store(struct mddev *mddev, const char *buf, size_t len) - if (mddev->pers) { - if (mddev->pers->check_reshape == NULL) - err = -EBUSY; -- else if (mddev->ro) -+ else if (!md_is_rdwr(mddev)) - err = -EROFS; - else { - mddev->new_layout = n; -@@ -4224,7 +4236,7 @@ chunk_size_store(struct mddev *mddev, const char *buf, size_t len) - if (mddev->pers) { - if (mddev->pers->check_reshape == NULL) - err = -EBUSY; -- else if (mddev->ro) -+ else if (!md_is_rdwr(mddev)) - err = -EROFS; - else { - mddev->new_chunk_sectors = n >> 9; -@@ -4347,13 +4359,13 @@ array_state_show(struct mddev *mddev, char *page) - - if (mddev->pers && !test_bit(MD_NOT_READY, &mddev->flags)) { - switch(mddev->ro) { -- case 1: -+ case MD_RDONLY: - st = readonly; - break; -- case 2: -+ case MD_AUTO_READ: - st = read_auto; - break; -- case 0: -+ case MD_RDWR: - spin_lock(&mddev->lock); - if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) - st = write_pending; -@@ -4389,7 +4401,8 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) - int err = 0; - enum array_state st = match_word(buf, array_states); - -- if (mddev->pers && (st == active || st == clean) && mddev->ro != 1) { -+ if (mddev->pers && (st == active || st == clean) && -+ mddev->ro != MD_RDONLY) { - /* don't take reconfig_mutex when toggling between - * clean and active - */ -@@ -4433,23 +4446,23 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) - if (mddev->pers) - err = md_set_readonly(mddev, NULL); - else { -- mddev->ro = 1; -+ mddev->ro = MD_RDONLY; - set_disk_ro(mddev->gendisk, 1); - err = do_md_run(mddev); - } - break; - case read_auto: - if (mddev->pers) { -- if (mddev->ro == 0) -+ if (md_is_rdwr(mddev)) - err = md_set_readonly(mddev, NULL); -- else if (mddev->ro == 1) -+ else if (mddev->ro == MD_RDONLY) - err = restart_array(mddev); - if (err == 0) { -- mddev->ro = 2; -+ mddev->ro = MD_AUTO_READ; - set_disk_ro(mddev->gendisk, 0); - } - } else { -- mddev->ro = 2; -+ mddev->ro = MD_AUTO_READ; - err = do_md_run(mddev); - } - break; -@@ -4474,7 +4487,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) - wake_up(&mddev->sb_wait); - err = 0; - } else { -- mddev->ro = 0; -+ mddev->ro = MD_RDWR; - set_disk_ro(mddev->gendisk, 0); - err = do_md_run(mddev); - } -@@ -4775,7 +4788,7 @@ action_show(struct mddev *mddev, char *page) - if (test_bit(MD_RECOVERY_FROZEN, &recovery)) - type = "frozen"; - else if (test_bit(MD_RECOVERY_RUNNING, &recovery) || -- (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &recovery))) { -+ (md_is_rdwr(mddev) && test_bit(MD_RECOVERY_NEEDED, &recovery))) { - if (test_bit(MD_RECOVERY_RESHAPE, &recovery)) - type = "reshape"; - else if (test_bit(MD_RECOVERY_SYNC, &recovery)) { -@@ -4861,11 +4874,11 @@ action_store(struct mddev *mddev, const char *page, size_t len) - set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); - set_bit(MD_RECOVERY_SYNC, &mddev->recovery); - } -- if (mddev->ro == 2) { -+ if (mddev->ro == MD_AUTO_READ) { - /* A write to sync_action is enough to justify - * canceling read-auto mode - */ -- mddev->ro = 0; -+ mddev->ro = MD_RDWR; - md_wakeup_thread(mddev->sync_thread); - } - set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); -@@ -5093,8 +5106,7 @@ max_sync_store(struct mddev *mddev, const char *buf, size_t len) - goto out_unlock; - - err = -EBUSY; -- if (max < mddev->resync_max && -- mddev->ro == 0 && -+ if (max < mddev->resync_max && md_is_rdwr(mddev) && - test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) - goto out_unlock; - -@@ -5829,8 +5841,8 @@ int md_run(struct mddev *mddev) - continue; - sync_blockdev(rdev->bdev); - invalidate_bdev(rdev->bdev); -- if (mddev->ro != 1 && rdev_read_only(rdev)) { -- mddev->ro = 1; -+ if (mddev->ro != MD_RDONLY && rdev_read_only(rdev)) { -+ mddev->ro = MD_RDONLY; - if (mddev->gendisk) - set_disk_ro(mddev->gendisk, 1); - } -@@ -5938,8 +5950,8 @@ int md_run(struct mddev *mddev) - - mddev->ok_start_degraded = start_dirty_degraded; - -- if (start_readonly && mddev->ro == 0) -- mddev->ro = 2; /* read-only, but switch on first write */ -+ if (start_readonly && md_is_rdwr(mddev)) -+ mddev->ro = MD_AUTO_READ; /* read-only, but switch on first write */ - - err = pers->run(mddev); - if (err) -@@ -6017,8 +6029,8 @@ int md_run(struct mddev *mddev) - mddev->sysfs_action = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_action"); - mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed"); - mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded"); -- } else if (mddev->ro == 2) /* auto-readonly not meaningful */ -- mddev->ro = 0; -+ } else if (mddev->ro == MD_AUTO_READ) -+ mddev->ro = MD_RDWR; - - atomic_set(&mddev->max_corr_read_errors, - MD_DEFAULT_MAX_CORRECTED_READ_ERRORS); -@@ -6036,7 +6048,7 @@ int md_run(struct mddev *mddev) - if (rdev->raid_disk >= 0) - sysfs_link_rdev(mddev, rdev); /* failure here is OK */ - -- if (mddev->degraded && !mddev->ro) -+ if (mddev->degraded && md_is_rdwr(mddev)) - /* This ensures that recovering status is reported immediately - * via sysfs - until a lack of spares is confirmed. - */ -@@ -6128,7 +6140,7 @@ static int restart_array(struct mddev *mddev) - return -ENXIO; - if (!mddev->pers) - return -EINVAL; -- if (!mddev->ro) -+ if (md_is_rdwr(mddev)) - return -EBUSY; - - rcu_read_lock(); -@@ -6147,7 +6159,7 @@ static int restart_array(struct mddev *mddev) - return -EROFS; - - mddev->safemode = 0; -- mddev->ro = 0; -+ mddev->ro = MD_RDWR; - set_disk_ro(disk, 0); - pr_debug("md: %s switched to read-write mode.\n", mdname(mddev)); - /* Kick recovery or resync if necessary */ -@@ -6174,7 +6186,7 @@ static void md_clean(struct mddev *mddev) - mddev->clevel[0] = 0; - mddev->flags = 0; - mddev->sb_flags = 0; -- mddev->ro = 0; -+ mddev->ro = MD_RDWR; - mddev->metadata_type[0] = 0; - mddev->chunk_sectors = 0; - mddev->ctime = mddev->utime = 0; -@@ -6226,7 +6238,7 @@ static void __md_stop_writes(struct mddev *mddev) - } - md_bitmap_flush(mddev); - -- if (mddev->ro == 0 && -+ if (md_is_rdwr(mddev) && - ((!mddev->in_sync && !mddev_is_clustered(mddev)) || - mddev->sb_flags)) { - /* mark array as shutdown cleanly */ -@@ -6302,6 +6314,9 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) - int err = 0; - int did_freeze = 0; - -+ if (mddev->external && test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) -+ return -EBUSY; -+ - if (!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) { - did_freeze = 1; - set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); -@@ -6314,8 +6329,6 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) - * which will now never happen */ - wake_up_process(mddev->sync_thread->tsk); - -- if (mddev->external && test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) -- return -EBUSY; - mddev_unlock(mddev); - wait_event(resync_wait, !test_bit(MD_RECOVERY_RUNNING, - &mddev->recovery)); -@@ -6328,29 +6341,30 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) - mddev->sync_thread || - test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { - pr_warn("md: %s still in use.\n",mdname(mddev)); -- if (did_freeze) { -- clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); -- set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); -- md_wakeup_thread(mddev->thread); -- } - err = -EBUSY; - goto out; - } -+ - if (mddev->pers) { - __md_stop_writes(mddev); - -- err = -ENXIO; -- if (mddev->ro==1) -+ if (mddev->ro == MD_RDONLY) { -+ err = -ENXIO; - goto out; -- mddev->ro = 1; -+ } -+ -+ mddev->ro = MD_RDONLY; - set_disk_ro(mddev->gendisk, 1); -+ } -+ -+out: -+ if ((mddev->pers && !err) || did_freeze) { - clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); - set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); - md_wakeup_thread(mddev->thread); - sysfs_notify_dirent_safe(mddev->sysfs_state); -- err = 0; - } --out: -+ - mutex_unlock(&mddev->open_mutex); - return err; - } -@@ -6399,7 +6413,7 @@ static int do_md_stop(struct mddev *mddev, int mode, - return -EBUSY; - } - if (mddev->pers) { -- if (mddev->ro) -+ if (!md_is_rdwr(mddev)) - set_disk_ro(disk, 0); - - __md_stop_writes(mddev); -@@ -6416,8 +6430,8 @@ static int do_md_stop(struct mddev *mddev, int mode, - mutex_unlock(&mddev->open_mutex); - mddev->changed = 1; - -- if (mddev->ro) -- mddev->ro = 0; -+ if (!md_is_rdwr(mddev)) -+ mddev->ro = MD_RDWR; - } else - mutex_unlock(&mddev->open_mutex); - /* -@@ -7232,7 +7246,7 @@ static int update_size(struct mddev *mddev, sector_t num_sectors) - if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || - mddev->sync_thread) - return -EBUSY; -- if (mddev->ro) -+ if (!md_is_rdwr(mddev)) - return -EROFS; - - rdev_for_each(rdev, mddev) { -@@ -7262,7 +7276,7 @@ static int update_raid_disks(struct mddev *mddev, int raid_disks) - /* change the number of raid disks */ - if (mddev->pers->check_reshape == NULL) - return -EINVAL; -- if (mddev->ro) -+ if (!md_is_rdwr(mddev)) - return -EROFS; - if (raid_disks <= 0 || - (mddev->max_disks && raid_disks >= mddev->max_disks)) -@@ -7686,26 +7700,25 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, - * The remaining ioctls are changing the state of the - * superblock, so we do not allow them on read-only arrays. - */ -- if (mddev->ro && mddev->pers) { -- if (mddev->ro == 2) { -- mddev->ro = 0; -- sysfs_notify_dirent_safe(mddev->sysfs_state); -- set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); -- /* mddev_unlock will wake thread */ -- /* If a device failed while we were read-only, we -- * need to make sure the metadata is updated now. -- */ -- if (test_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags)) { -- mddev_unlock(mddev); -- wait_event(mddev->sb_wait, -- !test_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags) && -- !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)); -- mddev_lock_nointr(mddev); -- } -- } else { -+ if (!md_is_rdwr(mddev) && mddev->pers) { -+ if (mddev->ro != MD_AUTO_READ) { - err = -EROFS; - goto unlock; - } -+ mddev->ro = MD_RDWR; -+ sysfs_notify_dirent_safe(mddev->sysfs_state); -+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); -+ /* mddev_unlock will wake thread */ -+ /* If a device failed while we were read-only, we -+ * need to make sure the metadata is updated now. -+ */ -+ if (test_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags)) { -+ mddev_unlock(mddev); -+ wait_event(mddev->sb_wait, -+ !test_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags) && -+ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)); -+ mddev_lock_nointr(mddev); -+ } - } - - switch (cmd) { -@@ -7791,11 +7804,11 @@ static int md_set_read_only(struct block_device *bdev, bool ro) - * Transitioning to read-auto need only happen for arrays that call - * md_write_start and which are not ready for writes yet. - */ -- if (!ro && mddev->ro == 1 && mddev->pers) { -+ if (!ro && mddev->ro == MD_RDONLY && mddev->pers) { - err = restart_array(mddev); - if (err) - goto out_unlock; -- mddev->ro = 2; -+ mddev->ro = MD_AUTO_READ; - } - - out_unlock: -@@ -8269,9 +8282,9 @@ static int md_seq_show(struct seq_file *seq, void *v) - seq_printf(seq, "%s : %sactive", mdname(mddev), - mddev->pers ? "" : "in"); - if (mddev->pers) { -- if (mddev->ro==1) -+ if (mddev->ro == MD_RDONLY) - seq_printf(seq, " (read-only)"); -- if (mddev->ro==2) -+ if (mddev->ro == MD_AUTO_READ) - seq_printf(seq, " (auto-read-only)"); - seq_printf(seq, " %s", mddev->pers->name); - } -@@ -8530,10 +8543,10 @@ bool md_write_start(struct mddev *mddev, struct bio *bi) - if (bio_data_dir(bi) != WRITE) - return true; - -- BUG_ON(mddev->ro == 1); -- if (mddev->ro == 2) { -+ BUG_ON(mddev->ro == MD_RDONLY); -+ if (mddev->ro == MD_AUTO_READ) { - /* need to switch to read/write */ -- mddev->ro = 0; -+ mddev->ro = MD_RDWR; - set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); - md_wakeup_thread(mddev->thread); - md_wakeup_thread(mddev->sync_thread); -@@ -8584,7 +8597,7 @@ void md_write_inc(struct mddev *mddev, struct bio *bi) - { - if (bio_data_dir(bi) != WRITE) - return; -- WARN_ON_ONCE(mddev->in_sync || mddev->ro); -+ WARN_ON_ONCE(mddev->in_sync || !md_is_rdwr(mddev)); - percpu_ref_get(&mddev->writes_pending); - } - EXPORT_SYMBOL(md_write_inc); -@@ -8690,7 +8703,7 @@ void md_allow_write(struct mddev *mddev) - { - if (!mddev->pers) - return; -- if (mddev->ro) -+ if (!md_is_rdwr(mddev)) - return; - if (!mddev->pers->sync_request) - return; -@@ -8738,7 +8751,7 @@ void md_do_sync(struct md_thread *thread) - if (test_bit(MD_RECOVERY_DONE, &mddev->recovery) || - test_bit(MD_RECOVERY_WAIT, &mddev->recovery)) - return; -- if (mddev->ro) {/* never try to sync a read-only array */ -+ if (!md_is_rdwr(mddev)) {/* never try to sync a read-only array */ - set_bit(MD_RECOVERY_INTR, &mddev->recovery); - return; - } -@@ -9207,9 +9220,9 @@ static int remove_and_add_spares(struct mddev *mddev, - if (test_bit(Faulty, &rdev->flags)) - continue; - if (!test_bit(Journal, &rdev->flags)) { -- if (mddev->ro && -- ! (rdev->saved_raid_disk >= 0 && -- !test_bit(Bitmap_sync, &rdev->flags))) -+ if (!md_is_rdwr(mddev) && -+ !(rdev->saved_raid_disk >= 0 && -+ !test_bit(Bitmap_sync, &rdev->flags))) - continue; - - rdev->recovery_offset = 0; -@@ -9307,7 +9320,8 @@ void md_check_recovery(struct mddev *mddev) - flush_signals(current); - } - -- if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) -+ if (!md_is_rdwr(mddev) && -+ !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) - return; - if ( ! ( - (mddev->sb_flags & ~ (1<external && mddev->safemode == 1) - mddev->safemode = 0; - -- if (mddev->ro) { -+ if (!md_is_rdwr(mddev)) { - struct md_rdev *rdev; - if (!mddev->external && mddev->in_sync) - /* 'Blocked' flag not needed as failed devices -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index 98d4e93efa31c..e4564ca1f2434 100644 ---- a/drivers/md/raid5.c -+++ b/drivers/md/raid5.c -@@ -5905,11 +5905,11 @@ static bool stripe_ahead_of_reshape(struct mddev *mddev, struct r5conf *conf, - int dd_idx; - - for (dd_idx = 0; dd_idx < sh->disks; dd_idx++) { -- if (dd_idx == sh->pd_idx) -+ if (dd_idx == sh->pd_idx || dd_idx == sh->qd_idx) - continue; - - min_sector = min(min_sector, sh->dev[dd_idx].sector); -- max_sector = min(max_sector, sh->dev[dd_idx].sector); -+ max_sector = max(max_sector, sh->dev[dd_idx].sector); - } - - spin_lock_irq(&conf->device_lock); -diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c -index 0b2fbe1335a77..c70c89209fe55 100644 ---- a/drivers/misc/mei/client.c -+++ b/drivers/misc/mei/client.c -@@ -1978,7 +1978,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) - - mei_hdr = mei_msg_hdr_init(cb); - if (IS_ERR(mei_hdr)) { -- rets = -PTR_ERR(mei_hdr); -+ rets = PTR_ERR(mei_hdr); - mei_hdr = NULL; - goto err; - } -@@ -2002,7 +2002,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) - - hbuf_slots = mei_hbuf_empty_slots(dev); - if (hbuf_slots < 0) { -- rets = -EOVERFLOW; -+ buf_len = -EOVERFLOW; - goto out; - } - -diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h -index 19e996a829c9d..b54275389f8ac 100644 ---- a/drivers/net/arcnet/arcdevice.h -+++ b/drivers/net/arcnet/arcdevice.h -@@ -186,6 +186,8 @@ do { \ - #define ARC_IS_5MBIT 1 /* card default speed is 5MBit */ - #define ARC_CAN_10MBIT 2 /* card uses COM20022, supporting 10MBit, - but default is 2.5MBit. */ -+#define ARC_HAS_LED 4 /* card has software controlled LEDs */ -+#define ARC_HAS_ROTARY 8 /* card has rotary encoder */ - - /* information needed to define an encapsulation driver */ - struct ArcProto { -diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c -index c580acb8b1d34..7b5c8bb02f119 100644 ---- a/drivers/net/arcnet/com20020-pci.c -+++ b/drivers/net/arcnet/com20020-pci.c -@@ -213,12 +213,13 @@ static int com20020pci_probe(struct pci_dev *pdev, - if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15)) - lp->backplane = 1; - -- /* Get the dev_id from the PLX rotary coder */ -- if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) -- dev_id_mask = 0x3; -- dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; -- -- snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); -+ if (ci->flags & ARC_HAS_ROTARY) { -+ /* Get the dev_id from the PLX rotary coder */ -+ if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) -+ dev_id_mask = 0x3; -+ dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; -+ snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); -+ } - - if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { - pr_err("IO address %Xh is empty!\n", ioaddr); -@@ -230,6 +231,10 @@ static int com20020pci_probe(struct pci_dev *pdev, - goto err_free_arcdev; - } - -+ ret = com20020_found(dev, IRQF_SHARED); -+ if (ret) -+ goto err_free_arcdev; -+ - card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), - GFP_KERNEL); - if (!card) { -@@ -239,41 +244,39 @@ static int com20020pci_probe(struct pci_dev *pdev, - - card->index = i; - card->pci_priv = priv; -- card->tx_led.brightness_set = led_tx_set; -- card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, -- GFP_KERNEL, "arc%d-%d-tx", -- dev->dev_id, i); -- card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, -- "pci:green:tx:%d-%d", -- dev->dev_id, i); -- -- card->tx_led.dev = &dev->dev; -- card->recon_led.brightness_set = led_recon_set; -- card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, -- GFP_KERNEL, "arc%d-%d-recon", -- dev->dev_id, i); -- card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, -- "pci:red:recon:%d-%d", -- dev->dev_id, i); -- card->recon_led.dev = &dev->dev; -- card->dev = dev; -- -- ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); -- if (ret) -- goto err_free_arcdev; - -- ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); -- if (ret) -- goto err_free_arcdev; -- -- dev_set_drvdata(&dev->dev, card); -- -- ret = com20020_found(dev, IRQF_SHARED); -- if (ret) -- goto err_free_arcdev; -- -- devm_arcnet_led_init(dev, dev->dev_id, i); -+ if (ci->flags & ARC_HAS_LED) { -+ card->tx_led.brightness_set = led_tx_set; -+ card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, -+ GFP_KERNEL, "arc%d-%d-tx", -+ dev->dev_id, i); -+ card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, -+ "pci:green:tx:%d-%d", -+ dev->dev_id, i); -+ -+ card->tx_led.dev = &dev->dev; -+ card->recon_led.brightness_set = led_recon_set; -+ card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, -+ GFP_KERNEL, "arc%d-%d-recon", -+ dev->dev_id, i); -+ card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, -+ "pci:red:recon:%d-%d", -+ dev->dev_id, i); -+ card->recon_led.dev = &dev->dev; -+ -+ ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); -+ if (ret) -+ goto err_free_arcdev; -+ -+ ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); -+ if (ret) -+ goto err_free_arcdev; -+ -+ dev_set_drvdata(&dev->dev, card); -+ devm_arcnet_led_init(dev, dev->dev_id, i); -+ } - -+ card->dev = dev; - list_add(&card->list, &priv->list_dev); - continue; - -@@ -329,7 +332,7 @@ static struct com20020_pci_card_info card_info_5mbit = { - }; - - static struct com20020_pci_card_info card_info_sohard = { -- .name = "PLX-PCI", -+ .name = "SOHARD SH ARC-PCI", - .devcount = 1, - /* SOHARD needs PCI base addr 4 */ - .chan_map_tbl = { -@@ -364,7 +367,7 @@ static struct com20020_pci_card_info card_info_eae_arc1 = { - }, - }, - .rotary = 0x0, -- .flags = ARC_CAN_10MBIT, -+ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, - }; - - static struct com20020_pci_card_info card_info_eae_ma1 = { -@@ -396,7 +399,7 @@ static struct com20020_pci_card_info card_info_eae_ma1 = { - }, - }, - .rotary = 0x0, -- .flags = ARC_CAN_10MBIT, -+ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, - }; - - static struct com20020_pci_card_info card_info_eae_fb2 = { -@@ -421,7 +424,7 @@ static struct com20020_pci_card_info card_info_eae_fb2 = { - }, - }, - .rotary = 0x0, -- .flags = ARC_CAN_10MBIT, -+ .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, - }; - - static const struct pci_device_id com20020pci_id_table[] = { -diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c -index 80b44043e6c53..28c9b6f1a54f1 100644 ---- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c -+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c -@@ -553,17 +553,17 @@ void aq_ptp_tx_hwtstamp(struct aq_nic_s *aq_nic, u64 timestamp) - - /* aq_ptp_rx_hwtstamp - utility function which checks for RX time stamp - * @adapter: pointer to adapter struct -- * @skb: particular skb to send timestamp with -+ * @shhwtstamps: particular skb_shared_hwtstamps to save timestamp - * - * if the timestamp is valid, we convert it into the timecounter ns - * value, then store that result into the hwtstamps structure which - * is passed up the network stack - */ --static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct sk_buff *skb, -+static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct skb_shared_hwtstamps *shhwtstamps, - u64 timestamp) - { - timestamp -= atomic_read(&aq_ptp->offset_ingress); -- aq_ptp_convert_to_hwtstamp(aq_ptp, skb_hwtstamps(skb), timestamp); -+ aq_ptp_convert_to_hwtstamp(aq_ptp, shhwtstamps, timestamp); - } - - void aq_ptp_hwtstamp_config_get(struct aq_ptp_s *aq_ptp, -@@ -639,7 +639,7 @@ bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring) - &aq_ptp->ptp_rx == ring || &aq_ptp->hwts_rx == ring; - } - --u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, -+u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct skb_shared_hwtstamps *shhwtstamps, u8 *p, - unsigned int len) - { - struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp; -@@ -648,7 +648,7 @@ u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, - p, len, ×tamp); - - if (ret > 0) -- aq_ptp_rx_hwtstamp(aq_ptp, skb, timestamp); -+ aq_ptp_rx_hwtstamp(aq_ptp, shhwtstamps, timestamp); - - return ret; - } -diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h -index 28ccb7ca2df9e..210b723f22072 100644 ---- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h -+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.h -@@ -67,7 +67,7 @@ int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp, - /* Return either ring is belong to PTP or not*/ - bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring); - --u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, -+u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct skb_shared_hwtstamps *shhwtstamps, u8 *p, - unsigned int len); - - struct ptp_clock *aq_ptp_get_ptp_clock(struct aq_ptp_s *aq_ptp); -@@ -143,7 +143,7 @@ static inline bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring) - } - - static inline u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, -- struct sk_buff *skb, u8 *p, -+ struct skb_shared_hwtstamps *shhwtstamps, u8 *p, - unsigned int len) - { - return 0; -diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -index 2dc8d215a5918..b5a49166fa972 100644 ---- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -@@ -647,7 +647,7 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi, - } - if (is_ptp_ring) - buff->len -= -- aq_ptp_extract_ts(self->aq_nic, skb, -+ aq_ptp_extract_ts(self->aq_nic, skb_hwtstamps(skb), - aq_buf_vaddr(&buff->rxdata), - buff->len); - -@@ -742,6 +742,8 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, - struct aq_ring_buff_s *buff = &rx_ring->buff_ring[rx_ring->sw_head]; - bool is_ptp_ring = aq_ptp_ring(rx_ring->aq_nic, rx_ring); - struct aq_ring_buff_s *buff_ = NULL; -+ u16 ptp_hwtstamp_len = 0; -+ struct skb_shared_hwtstamps shhwtstamps; - struct sk_buff *skb = NULL; - unsigned int next_ = 0U; - struct xdp_buff xdp; -@@ -810,11 +812,12 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, - hard_start = page_address(buff->rxdata.page) + - buff->rxdata.pg_off - rx_ring->page_offset; - -- if (is_ptp_ring) -- buff->len -= -- aq_ptp_extract_ts(rx_ring->aq_nic, skb, -- aq_buf_vaddr(&buff->rxdata), -- buff->len); -+ if (is_ptp_ring) { -+ ptp_hwtstamp_len = aq_ptp_extract_ts(rx_ring->aq_nic, &shhwtstamps, -+ aq_buf_vaddr(&buff->rxdata), -+ buff->len); -+ buff->len -= ptp_hwtstamp_len; -+ } - - xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq); - xdp_prepare_buff(&xdp, hard_start, rx_ring->page_offset, -@@ -834,6 +837,9 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, - if (IS_ERR(skb) || !skb) - continue; - -+ if (ptp_hwtstamp_len > 0) -+ *skb_hwtstamps(skb) = shhwtstamps; -+ - if (buff->is_vlan) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), - buff->vlan_rx_tag); -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c -index d8afcf8d6b30e..4d6663ff84722 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c -@@ -2075,6 +2075,7 @@ destroy_flow_table: - rhashtable_destroy(&tc_info->flow_table); - free_tc_info: - kfree(tc_info); -+ bp->tc_info = NULL; - return rc; - } - -diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c -index 85570e40c8e9b..f60a16de565ed 100644 ---- a/drivers/net/ethernet/broadcom/tg3.c -+++ b/drivers/net/ethernet/broadcom/tg3.c -@@ -6853,7 +6853,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) - desc_idx, *post_ptr); - drop_it_no_recycle: - /* Other statistics kept track of by card. */ -- tp->rx_dropped++; -+ tnapi->rx_dropped++; - goto next_pkt; - } - -@@ -7879,8 +7879,10 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi, - - segs = skb_gso_segment(skb, tp->dev->features & - ~(NETIF_F_TSO | NETIF_F_TSO6)); -- if (IS_ERR(segs) || !segs) -+ if (IS_ERR(segs) || !segs) { -+ tnapi->tx_dropped++; - goto tg3_tso_bug_end; -+ } - - skb_list_walk_safe(segs, seg, next) { - skb_mark_not_on_list(seg); -@@ -8151,7 +8153,7 @@ dma_error: - drop: - dev_kfree_skb_any(skb); - drop_nofree: -- tp->tx_dropped++; -+ tnapi->tx_dropped++; - return NETDEV_TX_OK; - } - -@@ -9330,7 +9332,7 @@ static void __tg3_set_rx_mode(struct net_device *); - /* tp->lock is held. */ - static int tg3_halt(struct tg3 *tp, int kind, bool silent) - { -- int err; -+ int err, i; - - tg3_stop_fw(tp); - -@@ -9351,6 +9353,13 @@ static int tg3_halt(struct tg3 *tp, int kind, bool silent) - - /* And make sure the next sample is new data */ - memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); -+ -+ for (i = 0; i < TG3_IRQ_MAX_VECS; ++i) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ tnapi->rx_dropped = 0; -+ tnapi->tx_dropped = 0; -+ } - } - - return err; -@@ -11900,6 +11909,9 @@ static void tg3_get_nstats(struct tg3 *tp, struct rtnl_link_stats64 *stats) - { - struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev; - struct tg3_hw_stats *hw_stats = tp->hw_stats; -+ unsigned long rx_dropped; -+ unsigned long tx_dropped; -+ int i; - - stats->rx_packets = old_stats->rx_packets + - get_stat64(&hw_stats->rx_ucast_packets) + -@@ -11946,8 +11958,26 @@ static void tg3_get_nstats(struct tg3 *tp, struct rtnl_link_stats64 *stats) - stats->rx_missed_errors = old_stats->rx_missed_errors + - get_stat64(&hw_stats->rx_discards); - -- stats->rx_dropped = tp->rx_dropped; -- stats->tx_dropped = tp->tx_dropped; -+ /* Aggregate per-queue counters. The per-queue counters are updated -+ * by a single writer, race-free. The result computed by this loop -+ * might not be 100% accurate (counters can be updated in the middle of -+ * the loop) but the next tg3_get_nstats() will recompute the current -+ * value so it is acceptable. -+ * -+ * Note that these counters wrap around at 4G on 32bit machines. -+ */ -+ rx_dropped = (unsigned long)(old_stats->rx_dropped); -+ tx_dropped = (unsigned long)(old_stats->tx_dropped); -+ -+ for (i = 0; i < tp->irq_cnt; i++) { -+ struct tg3_napi *tnapi = &tp->napi[i]; -+ -+ rx_dropped += tnapi->rx_dropped; -+ tx_dropped += tnapi->tx_dropped; -+ } -+ -+ stats->rx_dropped = rx_dropped; -+ stats->tx_dropped = tx_dropped; - } - - static int tg3_get_regs_len(struct net_device *dev) -diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h -index 1000c894064f0..8d753f8c5b065 100644 ---- a/drivers/net/ethernet/broadcom/tg3.h -+++ b/drivers/net/ethernet/broadcom/tg3.h -@@ -3018,6 +3018,7 @@ struct tg3_napi { - u16 *rx_rcb_prod_idx; - struct tg3_rx_prodring_set prodring; - struct tg3_rx_buffer_desc *rx_rcb; -+ unsigned long rx_dropped; - - u32 tx_prod ____cacheline_aligned; - u32 tx_cons; -@@ -3026,6 +3027,7 @@ struct tg3_napi { - u32 prodmbox; - struct tg3_tx_buffer_desc *tx_ring; - struct tg3_tx_ring_info *tx_buffers; -+ unsigned long tx_dropped; - - dma_addr_t status_mapping; - dma_addr_t rx_rcb_mapping; -@@ -3219,8 +3221,6 @@ struct tg3 { - - - /* begin "everything else" cacheline(s) section */ -- unsigned long rx_dropped; -- unsigned long tx_dropped; - struct rtnl_link_stats64 net_stats_prev; - struct tg3_ethtool_stats estats_prev; - -diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c -index 928d934cb21a5..f75668c479351 100644 ---- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c -+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c -@@ -66,6 +66,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb) - } - } - -+static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv) -+{ -+#define HNS_MAC_LINK_WAIT_TIME 5 -+#define HNS_MAC_LINK_WAIT_CNT 40 -+ -+ u32 link_status = 0; -+ int i; -+ -+ if (!mac_ctrl_drv->get_link_status) -+ return link_status; -+ -+ for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) { -+ msleep(HNS_MAC_LINK_WAIT_TIME); -+ mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status); -+ if (!link_status) -+ break; -+ } -+ -+ return link_status; -+} -+ - void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) - { - struct mac_driver *mac_ctrl_drv; -@@ -83,6 +104,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) - &sfp_prsnt); - if (!ret) - *link_status = *link_status && sfp_prsnt; -+ -+ /* for FIBER port, it may have a fake link up. -+ * when the link status changes from down to up, we need to do -+ * anti-shake. the anti-shake time is base on tests. -+ * only FIBER port need to do this. -+ */ -+ if (*link_status && !mac_cb->link) -+ *link_status = hns_mac_link_anti_shake(mac_ctrl_drv); - } - - mac_cb->link = *link_status; -diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c -index 7cf10d1e2b311..85722afe21770 100644 ---- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c -+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c -@@ -142,7 +142,8 @@ MODULE_DEVICE_TABLE(acpi, hns_enet_acpi_match); - - static void fill_desc(struct hnae_ring *ring, void *priv, - int size, dma_addr_t dma, int frag_end, -- int buf_num, enum hns_desc_type type, int mtu) -+ int buf_num, enum hns_desc_type type, int mtu, -+ bool is_gso) - { - struct hnae_desc *desc = &ring->desc[ring->next_to_use]; - struct hnae_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; -@@ -275,6 +276,15 @@ static int hns_nic_maybe_stop_tso( - return 0; - } - -+static int hns_nic_maybe_stop_tx_v2(struct sk_buff **out_skb, int *bnum, -+ struct hnae_ring *ring) -+{ -+ if (skb_is_gso(*out_skb)) -+ return hns_nic_maybe_stop_tso(out_skb, bnum, ring); -+ else -+ return hns_nic_maybe_stop_tx(out_skb, bnum, ring); -+} -+ - static void fill_tso_desc(struct hnae_ring *ring, void *priv, - int size, dma_addr_t dma, int frag_end, - int buf_num, enum hns_desc_type type, int mtu) -@@ -300,6 +310,19 @@ static void fill_tso_desc(struct hnae_ring *ring, void *priv, - mtu); - } - -+static void fill_desc_v2(struct hnae_ring *ring, void *priv, -+ int size, dma_addr_t dma, int frag_end, -+ int buf_num, enum hns_desc_type type, int mtu, -+ bool is_gso) -+{ -+ if (is_gso) -+ fill_tso_desc(ring, priv, size, dma, frag_end, buf_num, type, -+ mtu); -+ else -+ fill_v2_desc(ring, priv, size, dma, frag_end, buf_num, type, -+ mtu); -+} -+ - netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, - struct sk_buff *skb, - struct hns_nic_ring_data *ring_data) -@@ -313,6 +336,7 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, - int seg_num; - dma_addr_t dma; - int size, next_to_use; -+ bool is_gso; - int i; - - switch (priv->ops.maybe_stop_tx(&skb, &buf_num, ring)) { -@@ -339,8 +363,9 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, - ring->stats.sw_err_cnt++; - goto out_err_tx_ok; - } -+ is_gso = skb_is_gso(skb); - priv->ops.fill_desc(ring, skb, size, dma, seg_num == 1 ? 1 : 0, -- buf_num, DESC_TYPE_SKB, ndev->mtu); -+ buf_num, DESC_TYPE_SKB, ndev->mtu, is_gso); - - /* fill the fragments */ - for (i = 1; i < seg_num; i++) { -@@ -354,7 +379,7 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, - } - priv->ops.fill_desc(ring, skb_frag_page(frag), size, dma, - seg_num - 1 == i ? 1 : 0, buf_num, -- DESC_TYPE_PAGE, ndev->mtu); -+ DESC_TYPE_PAGE, ndev->mtu, is_gso); - } - - /*complete translate all packets*/ -@@ -1776,15 +1801,6 @@ static int hns_nic_set_features(struct net_device *netdev, - netdev_info(netdev, "enet v1 do not support tso!\n"); - break; - default: -- if (features & (NETIF_F_TSO | NETIF_F_TSO6)) { -- priv->ops.fill_desc = fill_tso_desc; -- priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; -- /* The chip only support 7*4096 */ -- netif_set_tso_max_size(netdev, 7 * 4096); -- } else { -- priv->ops.fill_desc = fill_v2_desc; -- priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; -- } - break; - } - netdev->features = features; -@@ -2159,16 +2175,9 @@ static void hns_nic_set_priv_ops(struct net_device *netdev) - priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; - } else { - priv->ops.get_rxd_bnum = get_v2rx_desc_bnum; -- if ((netdev->features & NETIF_F_TSO) || -- (netdev->features & NETIF_F_TSO6)) { -- priv->ops.fill_desc = fill_tso_desc; -- priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; -- /* This chip only support 7*4096 */ -- netif_set_tso_max_size(netdev, 7 * 4096); -- } else { -- priv->ops.fill_desc = fill_v2_desc; -- priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; -- } -+ priv->ops.fill_desc = fill_desc_v2; -+ priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx_v2; -+ netif_set_tso_max_size(netdev, 7 * 4096); - /* enable tso when init - * control tso on/off through TSE bit in bd - */ -diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h -index ffa9d6573f54b..3f3ee032f631c 100644 ---- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h -+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h -@@ -44,7 +44,8 @@ struct hns_nic_ring_data { - struct hns_nic_ops { - void (*fill_desc)(struct hnae_ring *ring, void *priv, - int size, dma_addr_t dma, int frag_end, -- int buf_num, enum hns_desc_type type, int mtu); -+ int buf_num, enum hns_desc_type type, int mtu, -+ bool is_gso); - int (*maybe_stop_tx)(struct sk_buff **out_skb, - int *bnum, struct hnae_ring *ring); - void (*get_rxd_bnum)(u32 bnum_flag, int *out_bnum); -diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c -index 9f5824eb8808a..b4157ff370a31 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -16158,7 +16158,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - I40E_PRTGL_SAH_MFS_MASK) >> I40E_PRTGL_SAH_MFS_SHIFT; - if (val < MAX_FRAME_SIZE_DEFAULT) - dev_warn(&pdev->dev, "MFS for port %x has been set below the default: %x\n", -- i, val); -+ pf->hw.port, val); - - /* Add a filter to drop all Flow control frames from any VSI from being - * transmitted. By doing so we stop a malicious VF from sending out -diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -index c13b4fa659ee9..31e02624aca48 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -@@ -829,18 +829,10 @@ static int __iavf_set_coalesce(struct net_device *netdev, - struct iavf_adapter *adapter = netdev_priv(netdev); - int i; - -- if (ec->rx_coalesce_usecs == 0) { -- if (ec->use_adaptive_rx_coalesce) -- netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n"); -- } else if ((ec->rx_coalesce_usecs < IAVF_MIN_ITR) || -- (ec->rx_coalesce_usecs > IAVF_MAX_ITR)) { -+ if (ec->rx_coalesce_usecs > IAVF_MAX_ITR) { - netif_info(adapter, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n"); - return -EINVAL; -- } else if (ec->tx_coalesce_usecs == 0) { -- if (ec->use_adaptive_tx_coalesce) -- netif_info(adapter, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n"); -- } else if ((ec->tx_coalesce_usecs < IAVF_MIN_ITR) || -- (ec->tx_coalesce_usecs > IAVF_MAX_ITR)) { -+ } else if (ec->tx_coalesce_usecs > IAVF_MAX_ITR) { - netif_info(adapter, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n"); - return -EINVAL; - } -diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.h b/drivers/net/ethernet/intel/iavf/iavf_txrx.h -index 7e6ee32d19b69..10ba36602c0c1 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_txrx.h -+++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.h -@@ -15,7 +15,6 @@ - */ - #define IAVF_ITR_DYNAMIC 0x8000 /* use top bit as a flag */ - #define IAVF_ITR_MASK 0x1FFE /* mask for ITR register value */ --#define IAVF_MIN_ITR 2 /* reg uses 2 usec resolution */ - #define IAVF_ITR_100K 10 /* all values below must be even */ - #define IAVF_ITR_50K 20 - #define IAVF_ITR_20K 50 -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -index a0c31f5b2ce05..03ebabd616353 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h -@@ -1877,7 +1877,7 @@ struct mcs_hw_info { - u8 tcam_entries; /* RX/TX Tcam entries per mcs block */ - u8 secy_entries; /* RX/TX SECY entries per mcs block */ - u8 sc_entries; /* RX/TX SC CAM entries per mcs block */ -- u8 sa_entries; /* PN table entries = SA entries */ -+ u16 sa_entries; /* PN table entries = SA entries */ - u64 rsvd[16]; - }; - -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c -index c43f19dfbd744..c1775bd01c2b4 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c -@@ -117,7 +117,7 @@ void mcs_get_rx_secy_stats(struct mcs *mcs, struct mcs_secy_stats *stats, int id - reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYTAGGEDCTLX(id); - stats->pkt_tagged_ctl_cnt = mcs_reg_read(mcs, reg); - -- reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(id); -+ reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(id); - stats->pkt_untaged_cnt = mcs_reg_read(mcs, reg); - - reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(id); -@@ -215,7 +215,7 @@ void mcs_get_sc_stats(struct mcs *mcs, struct mcs_sc_stats *stats, - reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCNOTVALIDX(id); - stats->pkt_notvalid_cnt = mcs_reg_read(mcs, reg); - -- reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(id); -+ reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(id); - stats->pkt_unchecked_cnt = mcs_reg_read(mcs, reg); - - if (mcs->hw->mcs_blks > 1) { -@@ -1219,6 +1219,17 @@ struct mcs *mcs_get_pdata(int mcs_id) - return NULL; - } - -+bool is_mcs_bypass(int mcs_id) -+{ -+ struct mcs *mcs_dev; -+ -+ list_for_each_entry(mcs_dev, &mcs_list, mcs_list) { -+ if (mcs_dev->mcs_id == mcs_id) -+ return mcs_dev->bypass; -+ } -+ return true; -+} -+ - void mcs_set_port_cfg(struct mcs *mcs, struct mcs_port_cfg_set_req *req) - { - u64 val = 0; -@@ -1436,7 +1447,7 @@ static int mcs_x2p_calibration(struct mcs *mcs) - return err; - } - --static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass) -+static void mcs_set_external_bypass(struct mcs *mcs, bool bypass) - { - u64 val; - -@@ -1447,6 +1458,7 @@ static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass) - else - val &= ~BIT_ULL(6); - mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val); -+ mcs->bypass = bypass; - } - - static void mcs_global_cfg(struct mcs *mcs) -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs.h b/drivers/net/ethernet/marvell/octeontx2/af/mcs.h -index 0f89dcb764654..f927cc61dfd21 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/mcs.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs.h -@@ -149,6 +149,7 @@ struct mcs { - u16 num_vec; - void *rvu; - u16 *tx_sa_active; -+ bool bypass; - }; - - struct mcs_ops { -@@ -206,6 +207,7 @@ void mcs_get_custom_tag_cfg(struct mcs *mcs, struct mcs_custom_tag_cfg_get_req * - int mcs_alloc_ctrlpktrule(struct rsrc_bmap *rsrc, u16 *pf_map, u16 offset, u16 pcifunc); - int mcs_free_ctrlpktrule(struct mcs *mcs, struct mcs_free_ctrl_pkt_rule_req *req); - int mcs_ctrlpktrule_write(struct mcs *mcs, struct mcs_ctrl_pkt_rule_write_req *req); -+bool is_mcs_bypass(int mcs_id); - - /* CN10K-B APIs */ - void cn10kb_mcs_set_hw_capabilities(struct mcs *mcs); -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h b/drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h -index f3ab01fc363c8..f4c6de89002c1 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h -@@ -810,14 +810,37 @@ - offset = 0x9d8ull; \ - offset; }) - -+#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(a) ({ \ -+ u64 offset; \ -+ \ -+ offset = 0xee80ull; \ -+ if (mcs->hw->mcs_blks > 1) \ -+ offset = 0xe818ull; \ -+ offset += (a) * 0x8ull; \ -+ offset; }) -+ -+#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(a) ({ \ -+ u64 offset; \ -+ \ -+ offset = 0xa680ull; \ -+ if (mcs->hw->mcs_blks > 1) \ -+ offset = 0xd018ull; \ -+ offset += (a) * 0x8ull; \ -+ offset; }) -+ -+#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(a) ({ \ -+ u64 offset; \ -+ \ -+ offset = 0xf680ull; \ -+ if (mcs->hw->mcs_blks > 1) \ -+ offset = 0xe018ull; \ -+ offset += (a) * 0x8ull; \ -+ offset; }) -+ - #define MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCDECRYPTEDX(a) (0xe680ull + (a) * 0x8ull) - #define MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCVALIDATEX(a) (0xde80ull + (a) * 0x8ull) --#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(a) (0xa680ull + (a) * 0x8ull) - #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYNOTAGX(a) (0xd218 + (a) * 0x8ull) --#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(a) (0xd018ull + (a) * 0x8ull) --#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(a) (0xee80ull + (a) * 0x8ull) - #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(a) (0xb680ull + (a) * 0x8ull) --#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(a) (0xf680ull + (a) * 0x8ull) - #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSAINVALIDX(a) (0x12680ull + (a) * 0x8ull) - #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTUSINGSAERRORX(a) (0x15680ull + (a) * 0x8ull) - #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTVALIDX(a) (0x13680ull + (a) * 0x8ull) -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c -index 733add3a9dc6b..d88d86bf07b03 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c -@@ -2622,6 +2622,9 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc) - */ - rvu_npc_free_mcam_entries(rvu, pcifunc, -1); - -+ if (rvu->mcs_blk_cnt) -+ rvu_mcs_flr_handler(rvu, pcifunc); -+ - mutex_unlock(&rvu->flr_lock); - } - -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -index a3346ea7876c5..95a7bc396e8ea 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -@@ -325,6 +325,7 @@ struct nix_hw { - struct nix_txvlan txvlan; - struct nix_ipolicer *ipolicer; - u64 *tx_credits; -+ u8 cc_mcs_cnt; - }; - - /* RVU block's capabilities or functionality, -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c -index dc7bd2ce78f7d..d609512998992 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c -@@ -1285,7 +1285,7 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) - - rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq"); - if (!rvu_dl->devlink_wq) -- goto err; -+ return -ENOMEM; - - INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work); - INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work); -@@ -1293,9 +1293,6 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) - INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work); - - return 0; --err: -- rvu_npa_health_reporters_destroy(rvu_dl); -- return -ENOMEM; - } - - static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl) -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -index 7310047136986..959f36efdc4a6 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -@@ -12,6 +12,7 @@ - #include "rvu_reg.h" - #include "rvu.h" - #include "npc.h" -+#include "mcs.h" - #include "cgx.h" - #include "lmac_common.h" - #include "rvu_npc_hash.h" -@@ -4164,6 +4165,12 @@ static void nix_link_config(struct rvu *rvu, int blkaddr, - SDP_HW_MAX_FRS << 16 | NIC_HW_MIN_FRS); - } - -+ /* Get MCS external bypass status for CN10K-B */ -+ if (mcs_get_blkcnt() == 1) { -+ /* Adjust for 2 credits when external bypass is disabled */ -+ nix_hw->cc_mcs_cnt = is_mcs_bypass(0) ? 0 : 2; -+ } -+ - /* Set credits for Tx links assuming max packet length allowed. - * This will be reconfigured based on MTU set for PF/VF. - */ -@@ -4187,6 +4194,7 @@ static void nix_link_config(struct rvu *rvu, int blkaddr, - tx_credits = (lmac_fifo_len - lmac_max_frs) / 16; - /* Enable credits and set credit pkt count to max allowed */ - cfg = (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1); -+ cfg |= FIELD_PREP(NIX_AF_LINKX_MCS_CNT_MASK, nix_hw->cc_mcs_cnt); - - link = iter + slink; - nix_hw->tx_credits[link] = tx_credits; -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -index 16cfc802e348d..f65805860c8d4 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -@@ -389,7 +389,13 @@ static u64 npc_get_default_entry_action(struct rvu *rvu, struct npc_mcam *mcam, - int bank, nixlf, index; - - /* get ucast entry rule entry index */ -- nix_get_nixlf(rvu, pf_func, &nixlf, NULL); -+ if (nix_get_nixlf(rvu, pf_func, &nixlf, NULL)) { -+ dev_err(rvu->dev, "%s: nixlf not attached to pcifunc:0x%x\n", -+ __func__, pf_func); -+ /* Action 0 is drop */ -+ return 0; -+ } -+ - index = npc_get_nixlf_mcam_index(mcam, pf_func, nixlf, - NIXLF_UCAST_ENTRY); - bank = npc_get_bank(mcam, index); -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c -index b3150f0532919..d46ac29adb966 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c -@@ -31,8 +31,8 @@ static struct hw_reg_map txsch_reg_map[NIX_TXSCH_LVL_CNT] = { - {NIX_TXSCH_LVL_TL4, 3, 0xFFFF, {{0x0B00, 0x0B08}, {0x0B10, 0x0B18}, - {0x1200, 0x12E0} } }, - {NIX_TXSCH_LVL_TL3, 4, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608}, -- {0x1610, 0x1618}, {0x1700, 0x17B0} } }, -- {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17B0} } }, -+ {0x1610, 0x1618}, {0x1700, 0x17C8} } }, -+ {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17C8} } }, - {NIX_TXSCH_LVL_TL1, 1, 0xFFFF, {{0x0C00, 0x0D98} } }, - }; - -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h -index 39f7a7cb27558..b690e5566f12a 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h -@@ -434,6 +434,7 @@ - - #define NIX_AF_LINKX_BASE_MASK GENMASK_ULL(11, 0) - #define NIX_AF_LINKX_RANGE_MASK GENMASK_ULL(19, 16) -+#define NIX_AF_LINKX_MCS_CNT_MASK GENMASK_ULL(33, 32) - - /* SSO */ - #define SSO_AF_CONST (0x1000) -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c -index aaf1af2a402ec..af779ae40d3c2 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c -@@ -323,9 +323,12 @@ static void otx2_get_pauseparam(struct net_device *netdev, - if (is_otx2_lbkvf(pfvf->pdev)) - return; - -+ mutex_lock(&pfvf->mbox.lock); - req = otx2_mbox_alloc_msg_cgx_cfg_pause_frm(&pfvf->mbox); -- if (!req) -+ if (!req) { -+ mutex_unlock(&pfvf->mbox.lock); - return; -+ } - - if (!otx2_sync_mbox_msg(&pfvf->mbox)) { - rsp = (struct cgx_pause_frm_cfg *) -@@ -333,6 +336,7 @@ static void otx2_get_pauseparam(struct net_device *netdev, - pause->rx_pause = rsp->rx_pause; - pause->tx_pause = rsp->tx_pause; - } -+ mutex_unlock(&pfvf->mbox.lock); - } - - static int otx2_set_pauseparam(struct net_device *netdev, -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -index 18c5d2b3f7f95..55807e2043edf 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -@@ -1676,6 +1676,14 @@ static void otx2_do_set_rx_mode(struct otx2_nic *pf) - mutex_unlock(&pf->mbox.lock); - } - -+static void otx2_set_irq_coalesce(struct otx2_nic *pfvf) -+{ -+ int cint; -+ -+ for (cint = 0; cint < pfvf->hw.cint_cnt; cint++) -+ otx2_config_irq_coalescing(pfvf, cint); -+} -+ - static void otx2_dim_work(struct work_struct *w) - { - struct dim_cq_moder cur_moder; -@@ -1691,6 +1699,7 @@ static void otx2_dim_work(struct work_struct *w) - CQ_TIMER_THRESH_MAX : cur_moder.usec; - pfvf->hw.cq_ecount_wait = (cur_moder.pkts > NAPI_POLL_WEIGHT) ? - NAPI_POLL_WEIGHT : cur_moder.pkts; -+ otx2_set_irq_coalesce(pfvf); - dim->state = DIM_START_MEASURE; - } - -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -index 20d801d30c732..aee392a15b23c 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c -@@ -510,11 +510,18 @@ static void otx2_adjust_adaptive_coalese(struct otx2_nic *pfvf, struct otx2_cq_p - { - struct dim_sample dim_sample; - u64 rx_frames, rx_bytes; -+ u64 tx_frames, tx_bytes; - - rx_frames = OTX2_GET_RX_STATS(RX_BCAST) + OTX2_GET_RX_STATS(RX_MCAST) + - OTX2_GET_RX_STATS(RX_UCAST); - rx_bytes = OTX2_GET_RX_STATS(RX_OCTS); -- dim_update_sample(pfvf->napi_events, rx_frames, rx_bytes, &dim_sample); -+ tx_bytes = OTX2_GET_TX_STATS(TX_OCTS); -+ tx_frames = OTX2_GET_TX_STATS(TX_UCAST); -+ -+ dim_update_sample(pfvf->napi_events, -+ rx_frames + tx_frames, -+ rx_bytes + tx_bytes, -+ &dim_sample); - net_dim(&cq_poll->dim, dim_sample); - } - -@@ -555,16 +562,9 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) - if (pfvf->flags & OTX2_FLAG_INTF_DOWN) - return workdone; - -- /* Check for adaptive interrupt coalesce */ -- if (workdone != 0 && -- ((pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) == -- OTX2_FLAG_ADPTV_INT_COAL_ENABLED)) { -- /* Adjust irq coalese using net_dim */ -+ /* Adjust irq coalese using net_dim */ -+ if (pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) - otx2_adjust_adaptive_coalese(pfvf, cq_poll); -- /* Update irq coalescing */ -- for (i = 0; i < pfvf->hw.cint_cnt; i++) -- otx2_config_irq_coalescing(pfvf, i); -- } - - /* Re-enable interrupts */ - otx2_write64(pfvf, NIX_LF_CINTX_ENA_W1S(cq_poll->cint_idx), -diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h -index 93a4258421667..13dfcf9f75dad 100644 ---- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h -+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h -@@ -214,7 +214,7 @@ struct ionic_desc_info { - void *cb_arg; - }; - --#define IONIC_QUEUE_NAME_MAX_SZ 32 -+#define IONIC_QUEUE_NAME_MAX_SZ 16 - - struct ionic_queue { - struct device *dev; -diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c -index a89ab455af67d..f7634884c7508 100644 ---- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c -+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c -@@ -46,24 +46,24 @@ static void ionic_lif_queue_identify(struct ionic_lif *lif); - static void ionic_dim_work(struct work_struct *work) - { - struct dim *dim = container_of(work, struct dim, work); -+ struct ionic_intr_info *intr; - struct dim_cq_moder cur_moder; - struct ionic_qcq *qcq; -+ struct ionic_lif *lif; - u32 new_coal; - - cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); - qcq = container_of(dim, struct ionic_qcq, dim); -- new_coal = ionic_coal_usec_to_hw(qcq->q.lif->ionic, cur_moder.usec); -+ lif = qcq->q.lif; -+ new_coal = ionic_coal_usec_to_hw(lif->ionic, cur_moder.usec); - new_coal = new_coal ? new_coal : 1; - -- if (qcq->intr.dim_coal_hw != new_coal) { -- unsigned int qi = qcq->cq.bound_q->index; -- struct ionic_lif *lif = qcq->q.lif; -- -- qcq->intr.dim_coal_hw = new_coal; -+ intr = &qcq->intr; -+ if (intr->dim_coal_hw != new_coal) { -+ intr->dim_coal_hw = new_coal; - - ionic_intr_coal_init(lif->ionic->idev.intr_ctrl, -- lif->rxqcqs[qi]->intr.index, -- qcq->intr.dim_coal_hw); -+ intr->index, intr->dim_coal_hw); - } - - dim->state = DIM_START_MEASURE; -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index abfa375b08878..d22457f2cf9cf 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -193,6 +193,7 @@ enum rtl_registers { - /* No threshold before first PCI xfer */ - #define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) - #define RX_EARLY_OFF (1 << 11) -+#define RX_PAUSE_SLOT_ON (1 << 11) /* 8125b and later */ - #define RXCFG_DMA_SHIFT 8 - /* Unlimited maximum PCI burst. */ - #define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) -@@ -2237,9 +2238,13 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53: - RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); - break; -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63: -+ case RTL_GIGA_MAC_VER_61: - RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST); - break; -+ case RTL_GIGA_MAC_VER_63: -+ RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST | -+ RX_PAUSE_SLOT_ON); -+ break; - default: - RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST); - break; -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c -index e95d35f1e5a0c..8fd167501fa0e 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c -@@ -710,28 +710,22 @@ void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev, - } - } - --void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, -+void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, -+ u32 num_txq, u32 num_rxq, - bool enable) - { - u32 value; - -- if (!enable) { -- value = readl(ioaddr + MAC_FPE_CTRL_STS); -- -- value &= ~EFPE; -- -- writel(value, ioaddr + MAC_FPE_CTRL_STS); -- return; -+ if (enable) { -+ cfg->fpe_csr = EFPE; -+ value = readl(ioaddr + GMAC_RXQ_CTRL1); -+ value &= ~GMAC_RXQCTRL_FPRQ; -+ value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT; -+ writel(value, ioaddr + GMAC_RXQ_CTRL1); -+ } else { -+ cfg->fpe_csr = 0; - } -- -- value = readl(ioaddr + GMAC_RXQ_CTRL1); -- value &= ~GMAC_RXQCTRL_FPRQ; -- value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT; -- writel(value, ioaddr + GMAC_RXQ_CTRL1); -- -- value = readl(ioaddr + MAC_FPE_CTRL_STS); -- value |= EFPE; -- writel(value, ioaddr + MAC_FPE_CTRL_STS); -+ writel(cfg->fpe_csr, ioaddr + MAC_FPE_CTRL_STS); - } - - int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) -@@ -741,6 +735,9 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) - - status = FPE_EVENT_UNKNOWN; - -+ /* Reads from the MAC_FPE_CTRL_STS register should only be performed -+ * here, since the status flags of MAC_FPE_CTRL_STS are "clear on read" -+ */ - value = readl(ioaddr + MAC_FPE_CTRL_STS); - - if (value & TRSP) { -@@ -766,19 +763,15 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) - return status; - } - --void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, enum stmmac_mpacket_type type) -+void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, -+ enum stmmac_mpacket_type type) - { -- u32 value; -+ u32 value = cfg->fpe_csr; - -- value = readl(ioaddr + MAC_FPE_CTRL_STS); -- -- if (type == MPACKET_VERIFY) { -- value &= ~SRSP; -+ if (type == MPACKET_VERIFY) - value |= SVER; -- } else { -- value &= ~SVER; -+ else if (type == MPACKET_RESPONSE) - value |= SRSP; -- } - - writel(value, ioaddr + MAC_FPE_CTRL_STS); - } -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h -index 53c138d0ff480..34e620790eb37 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h -@@ -153,9 +153,11 @@ int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, - unsigned int ptp_rate); - void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev, - struct stmmac_extra_stats *x, u32 txqcnt); --void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, -+void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, -+ u32 num_txq, u32 num_rxq, - bool enable); - void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, -+ struct stmmac_fpe_cfg *cfg, - enum stmmac_mpacket_type type); - int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev); - -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -index f30e08a106cbe..c2181c277291b 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c -@@ -1441,7 +1441,8 @@ static int dwxgmac3_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, - return 0; - } - --static void dwxgmac3_fpe_configure(void __iomem *ioaddr, u32 num_txq, -+static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, -+ u32 num_txq, - u32 num_rxq, bool enable) - { - u32 value; -diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h -index 592b4067f9b8f..b2b9cf04bc726 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/hwif.h -+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h -@@ -392,9 +392,11 @@ struct stmmac_ops { - unsigned int ptp_rate); - void (*est_irq_status)(void __iomem *ioaddr, struct net_device *dev, - struct stmmac_extra_stats *x, u32 txqcnt); -- void (*fpe_configure)(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, -+ void (*fpe_configure)(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, -+ u32 num_txq, u32 num_rxq, - bool enable); - void (*fpe_send_mpacket)(void __iomem *ioaddr, -+ struct stmmac_fpe_cfg *cfg, - enum stmmac_mpacket_type type); - int (*fpe_irq_status)(void __iomem *ioaddr, struct net_device *dev); - }; -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index 9f76c2f7d513b..69aac8ed84f67 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -957,7 +957,8 @@ static void stmmac_fpe_link_state_handle(struct stmmac_priv *priv, bool is_up) - bool *hs_enable = &fpe_cfg->hs_enable; - - if (is_up && *hs_enable) { -- stmmac_fpe_send_mpacket(priv, priv->ioaddr, MPACKET_VERIFY); -+ stmmac_fpe_send_mpacket(priv, priv->ioaddr, fpe_cfg, -+ MPACKET_VERIFY); - } else { - *lo_state = FPE_STATE_OFF; - *lp_state = FPE_STATE_OFF; -@@ -5704,6 +5705,7 @@ static void stmmac_fpe_event_status(struct stmmac_priv *priv, int status) - /* If user has requested FPE enable, quickly response */ - if (*hs_enable) - stmmac_fpe_send_mpacket(priv, priv->ioaddr, -+ fpe_cfg, - MPACKET_RESPONSE); - } - -@@ -7028,6 +7030,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work) - if (*lo_state == FPE_STATE_ENTERING_ON && - *lp_state == FPE_STATE_ENTERING_ON) { - stmmac_fpe_configure(priv, priv->ioaddr, -+ fpe_cfg, - priv->plat->tx_queues_to_use, - priv->plat->rx_queues_to_use, - *enable); -@@ -7046,6 +7049,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work) - netdev_info(priv->dev, SEND_VERIFY_MPAKCET_FMT, - *lo_state, *lp_state); - stmmac_fpe_send_mpacket(priv, priv->ioaddr, -+ fpe_cfg, - MPACKET_VERIFY); - } - /* Sleep then retry */ -@@ -7060,6 +7064,7 @@ void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable) - if (priv->plat->fpe_cfg->hs_enable != enable) { - if (enable) { - stmmac_fpe_send_mpacket(priv, priv->ioaddr, -+ priv->plat->fpe_cfg, - MPACKET_VERIFY); - } else { - priv->plat->fpe_cfg->lo_fpe_state = FPE_STATE_OFF; -@@ -7472,6 +7477,7 @@ int stmmac_suspend(struct device *dev) - if (priv->dma_cap.fpesel) { - /* Disable FPE */ - stmmac_fpe_configure(priv, priv->ioaddr, -+ priv->plat->fpe_cfg, - priv->plat->tx_queues_to_use, - priv->plat->rx_queues_to_use, false); - -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c -index 773e415cc2de6..390c900832cd2 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c -@@ -1073,6 +1073,7 @@ disable: - - priv->plat->fpe_cfg->enable = false; - stmmac_fpe_configure(priv, priv->ioaddr, -+ priv->plat->fpe_cfg, - priv->plat->tx_queues_to_use, - priv->plat->rx_queues_to_use, - false); -diff --git a/drivers/net/hyperv/Kconfig b/drivers/net/hyperv/Kconfig -index ca7bf7f897d36..c8cbd85adcf99 100644 ---- a/drivers/net/hyperv/Kconfig -+++ b/drivers/net/hyperv/Kconfig -@@ -3,5 +3,6 @@ config HYPERV_NET - tristate "Microsoft Hyper-V virtual network driver" - depends on HYPERV - select UCS2_STRING -+ select NLS - help - Select this option to enable the Hyper-V virtual network driver. -diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c -index 345e341d22338..4d833781294a4 100644 ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -763,7 +763,7 @@ enum rtl_register_content { - - /* rtl8152 flags */ - enum rtl8152_flags { -- RTL8152_UNPLUG = 0, -+ RTL8152_INACCESSIBLE = 0, - RTL8152_SET_RX_MODE, - WORK_ENABLE, - RTL8152_LINK_CHG, -@@ -1244,7 +1244,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) - static void rtl_set_unplug(struct r8152 *tp) - { - if (tp->udev->state == USB_STATE_NOTATTACHED) { -- set_bit(RTL8152_UNPLUG, &tp->flags); -+ set_bit(RTL8152_INACCESSIBLE, &tp->flags); - smp_mb__after_atomic(); - } - } -@@ -1255,7 +1255,7 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, - u16 limit = 64; - int ret = 0; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return -ENODEV; - - /* both size and indix must be 4 bytes align */ -@@ -1299,7 +1299,7 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, - u16 byteen_start, byteen_end, byen; - u16 limit = 512; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return -ENODEV; - - /* both size and indix must be 4 bytes align */ -@@ -1529,7 +1529,7 @@ static int read_mii_word(struct net_device *netdev, int phy_id, int reg) - struct r8152 *tp = netdev_priv(netdev); - int ret; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return -ENODEV; - - if (phy_id != R8152_PHY_ID) -@@ -1545,7 +1545,7 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) - { - struct r8152 *tp = netdev_priv(netdev); - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - if (phy_id != R8152_PHY_ID) -@@ -1750,7 +1750,7 @@ static void read_bulk_callback(struct urb *urb) - if (!tp) - return; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - if (!test_bit(WORK_ENABLE, &tp->flags)) -@@ -1842,7 +1842,7 @@ static void write_bulk_callback(struct urb *urb) - if (!test_bit(WORK_ENABLE, &tp->flags)) - return; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - if (!skb_queue_empty(&tp->tx_queue)) -@@ -1863,7 +1863,7 @@ static void intr_callback(struct urb *urb) - if (!test_bit(WORK_ENABLE, &tp->flags)) - return; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - switch (status) { -@@ -2607,7 +2607,7 @@ static void bottom_half(struct tasklet_struct *t) - { - struct r8152 *tp = from_tasklet(tp, t, tx_tl); - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - if (!test_bit(WORK_ENABLE, &tp->flags)) -@@ -2650,7 +2650,7 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) - int ret; - - /* The rx would be stopped, so skip submitting */ -- if (test_bit(RTL8152_UNPLUG, &tp->flags) || -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags) || - !test_bit(WORK_ENABLE, &tp->flags) || !netif_carrier_ok(tp->netdev)) - return 0; - -@@ -2857,6 +2857,8 @@ static void rtl8152_nic_reset(struct r8152 *tp) - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); - - for (i = 0; i < 1000; i++) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ break; - if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) - break; - usleep_range(100, 400); -@@ -3050,7 +3052,7 @@ static int rtl_enable(struct r8152 *tp) - - static int rtl8152_enable(struct r8152 *tp) - { -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return -ENODEV; - - set_tx_qlen(tp); -@@ -3137,7 +3139,7 @@ static int rtl8153_enable(struct r8152 *tp) - { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return -ENODEV; - - set_tx_qlen(tp); -@@ -3169,7 +3171,7 @@ static void rtl_disable(struct r8152 *tp) - u32 ocp_data; - int i; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { - rtl_drop_queued_tx(tp); - return; - } -@@ -3186,6 +3188,8 @@ static void rtl_disable(struct r8152 *tp) - rxdy_gated_en(tp, true); - - for (i = 0; i < 1000; i++) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ break; - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY) - break; -@@ -3193,6 +3197,8 @@ static void rtl_disable(struct r8152 *tp) - } - - for (i = 0; i < 1000; i++) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ break; - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY) - break; - usleep_range(1000, 2000); -@@ -3623,7 +3629,7 @@ static u16 r8153_phy_status(struct r8152 *tp, u16 desired) - } - - msleep(20); -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - break; - } - -@@ -3655,7 +3661,7 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) - int i; - - for (i = 0; i < 500; i++) { -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) -@@ -3697,7 +3703,7 @@ static void r8153c_ups_en(struct r8152 *tp, bool enable) - int i; - - for (i = 0; i < 500; i++) { -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & - AUTOLOAD_DONE) -@@ -4062,8 +4068,8 @@ static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait) - for (i = 0; wait && i < 5000; i++) { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -- break; -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ return -ENODEV; - - usleep_range(1000, 2000); - ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT); -@@ -5381,6 +5387,8 @@ static void wait_oob_link_list_ready(struct r8152 *tp) - int i; - - for (i = 0; i < 1000; i++) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ break; - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; -@@ -5395,6 +5403,8 @@ static void r8156b_wait_loading_flash(struct r8152 *tp) - int i; - - for (i = 0; i < 100; i++) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ break; - if (ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & GPHY_PATCH_DONE) - break; - usleep_range(1000, 2000); -@@ -5517,6 +5527,8 @@ static int r8153_pre_firmware_1(struct r8152 *tp) - for (i = 0; i < 104; i++) { - u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_WDT1_CTRL); - -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ return -ENODEV; - if (!(ocp_data & WTD1_EN)) - break; - usleep_range(1000, 2000); -@@ -5673,6 +5685,8 @@ static void r8153_aldps_en(struct r8152 *tp, bool enable) - data &= ~EN_ALDPS; - ocp_reg_write(tp, OCP_POWER_CFG, data); - for (i = 0; i < 20; i++) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ return; - usleep_range(1000, 2000); - if (ocp_read_word(tp, MCU_TYPE_PLA, 0xe000) & 0x0100) - break; -@@ -6026,7 +6040,7 @@ static int rtl8156_enable(struct r8152 *tp) - u32 ocp_data; - u16 speed; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return -ENODEV; - - r8156_fc_parameter(tp); -@@ -6084,7 +6098,7 @@ static int rtl8156b_enable(struct r8152 *tp) - u32 ocp_data; - u16 speed; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return -ENODEV; - - set_tx_qlen(tp); -@@ -6270,7 +6284,7 @@ out: - - static void rtl8152_up(struct r8152 *tp) - { -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8152_aldps_en(tp, false); -@@ -6280,7 +6294,7 @@ static void rtl8152_up(struct r8152 *tp) - - static void rtl8152_down(struct r8152 *tp) - { -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { - rtl_drop_queued_tx(tp); - return; - } -@@ -6295,7 +6309,7 @@ static void rtl8153_up(struct r8152 *tp) - { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153_u1u2en(tp, false); -@@ -6335,7 +6349,7 @@ static void rtl8153_down(struct r8152 *tp) - { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { - rtl_drop_queued_tx(tp); - return; - } -@@ -6356,7 +6370,7 @@ static void rtl8153b_up(struct r8152 *tp) - { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153b_u1u2en(tp, false); -@@ -6380,7 +6394,7 @@ static void rtl8153b_down(struct r8152 *tp) - { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { - rtl_drop_queued_tx(tp); - return; - } -@@ -6417,7 +6431,7 @@ static void rtl8153c_up(struct r8152 *tp) - { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153b_u1u2en(tp, false); -@@ -6498,7 +6512,7 @@ static void rtl8156_up(struct r8152 *tp) - { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153b_u1u2en(tp, false); -@@ -6571,7 +6585,7 @@ static void rtl8156_down(struct r8152 *tp) - { - u32 ocp_data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { - rtl_drop_queued_tx(tp); - return; - } -@@ -6709,7 +6723,7 @@ static void rtl_work_func_t(struct work_struct *work) - /* If the device is unplugged or !netif_running(), the workqueue - * doesn't need to wake the device, and could return directly. - */ -- if (test_bit(RTL8152_UNPLUG, &tp->flags) || !netif_running(tp->netdev)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags) || !netif_running(tp->netdev)) - return; - - if (usb_autopm_get_interface(tp->intf) < 0) -@@ -6748,7 +6762,7 @@ static void rtl_hw_phy_work_func_t(struct work_struct *work) - { - struct r8152 *tp = container_of(work, struct r8152, hw_phy_work.work); - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - if (usb_autopm_get_interface(tp->intf) < 0) -@@ -6875,7 +6889,7 @@ static int rtl8152_close(struct net_device *netdev) - netif_stop_queue(netdev); - - res = usb_autopm_get_interface(tp->intf); -- if (res < 0 || test_bit(RTL8152_UNPLUG, &tp->flags)) { -+ if (res < 0 || test_bit(RTL8152_INACCESSIBLE, &tp->flags)) { - rtl_drop_queued_tx(tp); - rtl_stop_rx(tp); - } else { -@@ -6908,7 +6922,7 @@ static void r8152b_init(struct r8152 *tp) - u32 ocp_data; - u16 data; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - data = r8152_mdio_read(tp, MII_BMCR); -@@ -6952,7 +6966,7 @@ static void r8153_init(struct r8152 *tp) - u16 data; - int i; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153_u1u2en(tp, false); -@@ -6963,7 +6977,7 @@ static void r8153_init(struct r8152 *tp) - break; - - msleep(20); -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - break; - } - -@@ -7092,7 +7106,7 @@ static void r8153b_init(struct r8152 *tp) - u16 data; - int i; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153b_u1u2en(tp, false); -@@ -7103,7 +7117,7 @@ static void r8153b_init(struct r8152 *tp) - break; - - msleep(20); -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - break; - } - -@@ -7174,7 +7188,7 @@ static void r8153c_init(struct r8152 *tp) - u16 data; - int i; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153b_u1u2en(tp, false); -@@ -7194,7 +7208,7 @@ static void r8153c_init(struct r8152 *tp) - break; - - msleep(20); -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - } - -@@ -8023,7 +8037,7 @@ static void r8156_init(struct r8152 *tp) - u16 data; - int i; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); -@@ -8044,7 +8058,7 @@ static void r8156_init(struct r8152 *tp) - break; - - msleep(20); -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - } - -@@ -8119,7 +8133,7 @@ static void r8156b_init(struct r8152 *tp) - u16 data; - int i; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_ECM_OP); -@@ -8153,7 +8167,7 @@ static void r8156b_init(struct r8152 *tp) - break; - - msleep(20); -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - } - -@@ -9219,7 +9233,7 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) - struct mii_ioctl_data *data = if_mii(rq); - int res; - -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return -ENODEV; - - res = usb_autopm_get_interface(tp->intf); -@@ -9321,7 +9335,7 @@ static const struct net_device_ops rtl8152_netdev_ops = { - - static void rtl8152_unload(struct r8152 *tp) - { -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - if (tp->version != RTL_VER_01) -@@ -9330,7 +9344,7 @@ static void rtl8152_unload(struct r8152 *tp) - - static void rtl8153_unload(struct r8152 *tp) - { -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153_power_cut_en(tp, false); -@@ -9338,7 +9352,7 @@ static void rtl8153_unload(struct r8152 *tp) - - static void rtl8153b_unload(struct r8152 *tp) - { -- if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) - return; - - r8153b_power_cut_en(tp, false); -diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h -index 69f9e69208f68..118bf08a708b9 100644 ---- a/drivers/nvme/host/nvme.h -+++ b/drivers/nvme/host/nvme.h -@@ -154,6 +154,11 @@ enum nvme_quirks { - * No temperature thresholds for channels other than 0 (Composite). - */ - NVME_QUIRK_NO_SECONDARY_TEMP_THRESH = (1 << 19), -+ -+ /* -+ * Disables simple suspend/resume path. -+ */ -+ NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND = (1 << 20), - }; - - /* -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index 886c3fc9578e4..3d01290994d89 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -3093,6 +3093,18 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) - if ((dmi_match(DMI_BOARD_VENDOR, "LENOVO")) && - dmi_match(DMI_BOARD_NAME, "LNVNB161216")) - return NVME_QUIRK_SIMPLE_SUSPEND; -+ } else if (pdev->vendor == 0x2646 && (pdev->device == 0x2263 || -+ pdev->device == 0x500f)) { -+ /* -+ * Exclude some Kingston NV1 and A2000 devices from -+ * NVME_QUIRK_SIMPLE_SUSPEND. Do a full suspend to save a -+ * lot fo energy with s2idle sleep on some TUXEDO platforms. -+ */ -+ if (dmi_match(DMI_BOARD_NAME, "NS5X_NS7XAU") || -+ dmi_match(DMI_BOARD_NAME, "NS5x_7xAU") || -+ dmi_match(DMI_BOARD_NAME, "NS5x_7xPU") || -+ dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1")) -+ return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND; - } - - return 0; -@@ -3133,7 +3145,9 @@ static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, - dev->dev = get_device(&pdev->dev); - - quirks |= check_vendor_combination_bug(pdev); -- if (!noacpi && acpi_storage_d3(&pdev->dev)) { -+ if (!noacpi && -+ !(quirks & NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND) && -+ acpi_storage_d3(&pdev->dev)) { - /* - * Some systems use a bios work around to ask for D3 on - * platforms that support kernel managed suspend. -diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index 0fbf331a748fd..9bb9fe0fad07c 100644 ---- a/drivers/of/dynamic.c -+++ b/drivers/of/dynamic.c -@@ -104,8 +104,9 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) - * - * Returns the new state of a device based on the notifier used. - * -- * Return: 0 on device going from enabled to disabled, 1 on device -- * going from disabled to enabled and -1 on no change. -+ * Return: OF_RECONFIG_CHANGE_REMOVE on device going from enabled to -+ * disabled, OF_RECONFIG_CHANGE_ADD on device going from disabled to -+ * enabled and OF_RECONFIG_NO_CHANGE on no change. - */ - int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr) - { -diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c -index 5784dc20fb382..4605758d32146 100644 ---- a/drivers/parport/parport_pc.c -+++ b/drivers/parport/parport_pc.c -@@ -2614,6 +2614,8 @@ enum parport_pc_pci_cards { - netmos_9865, - quatech_sppxp100, - wch_ch382l, -+ brainboxes_uc146, -+ brainboxes_px203, - }; - - -@@ -2678,6 +2680,8 @@ static struct parport_pc_pci { - /* netmos_9865 */ { 1, { { 0, -1 }, } }, - /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, - /* wch_ch382l */ { 1, { { 2, -1 }, } }, -+ /* brainboxes_uc146 */ { 1, { { 3, -1 }, } }, -+ /* brainboxes_px203 */ { 1, { { 0, -1 }, } }, - }; - - static const struct pci_device_id parport_pc_pci_tbl[] = { -@@ -2771,6 +2775,23 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { - PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, - /* WCH CH382L PCI-E single parallel port card */ - { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l }, -+ /* Brainboxes IX-500/550 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x402a, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, -+ /* Brainboxes UC-146/UC-157 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0be1, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc146 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0be2, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc146 }, -+ /* Brainboxes PX-146/PX-257 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x401c, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, -+ /* Brainboxes PX-203 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x4007, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_px203 }, -+ /* Brainboxes PX-475 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x401f, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, - { 0, } /* terminate list */ - }; - MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl); -diff --git a/drivers/platform/mellanox/mlxbf-bootctl.c b/drivers/platform/mellanox/mlxbf-bootctl.c -index 1c7a288b59a5c..6a171a4f9dc68 100644 ---- a/drivers/platform/mellanox/mlxbf-bootctl.c -+++ b/drivers/platform/mellanox/mlxbf-bootctl.c -@@ -17,6 +17,7 @@ - - #define MLXBF_BOOTCTL_SB_SECURE_MASK 0x03 - #define MLXBF_BOOTCTL_SB_TEST_MASK 0x0c -+#define MLXBF_BOOTCTL_SB_DEV_MASK BIT(4) - - #define MLXBF_SB_KEY_NUM 4 - -@@ -37,11 +38,18 @@ static struct mlxbf_bootctl_name boot_names[] = { - { MLXBF_BOOTCTL_NONE, "none" }, - }; - -+enum { -+ MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION = 0, -+ MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE = 1, -+ MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE = 2, -+ MLXBF_BOOTCTL_SB_LIFECYCLE_RMA = 3 -+}; -+ - static const char * const mlxbf_bootctl_lifecycle_states[] = { -- [0] = "Production", -- [1] = "GA Secured", -- [2] = "GA Non-Secured", -- [3] = "RMA", -+ [MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION] = "Production", -+ [MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE] = "GA Secured", -+ [MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE] = "GA Non-Secured", -+ [MLXBF_BOOTCTL_SB_LIFECYCLE_RMA] = "RMA", - }; - - /* ARM SMC call which is atomic and no need for lock. */ -@@ -165,25 +173,30 @@ static ssize_t second_reset_action_store(struct device *dev, - static ssize_t lifecycle_state_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -+ int status_bits; -+ int use_dev_key; -+ int test_state; - int lc_state; - -- lc_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS, -- MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE); -- if (lc_state < 0) -- return lc_state; -+ status_bits = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS, -+ MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE); -+ if (status_bits < 0) -+ return status_bits; - -- lc_state &= -- MLXBF_BOOTCTL_SB_TEST_MASK | MLXBF_BOOTCTL_SB_SECURE_MASK; -+ use_dev_key = status_bits & MLXBF_BOOTCTL_SB_DEV_MASK; -+ test_state = status_bits & MLXBF_BOOTCTL_SB_TEST_MASK; -+ lc_state = status_bits & MLXBF_BOOTCTL_SB_SECURE_MASK; - - /* - * If the test bits are set, we specify that the current state may be - * due to using the test bits. - */ -- if (lc_state & MLXBF_BOOTCTL_SB_TEST_MASK) { -- lc_state &= MLXBF_BOOTCTL_SB_SECURE_MASK; -- -+ if (test_state) { - return sprintf(buf, "%s(test)\n", - mlxbf_bootctl_lifecycle_states[lc_state]); -+ } else if (use_dev_key && -+ (lc_state == MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE)) { -+ return sprintf(buf, "Secured (development)\n"); - } - - return sprintf(buf, "%s\n", mlxbf_bootctl_lifecycle_states[lc_state]); -diff --git a/drivers/platform/mellanox/mlxbf-pmc.c b/drivers/platform/mellanox/mlxbf-pmc.c -index 2d4bbe99959ef..db7a1d360cd2c 100644 ---- a/drivers/platform/mellanox/mlxbf-pmc.c -+++ b/drivers/platform/mellanox/mlxbf-pmc.c -@@ -1202,6 +1202,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num) - attr->dev_attr.show = mlxbf_pmc_event_list_show; - attr->nr = blk_num; - attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "event_list"); -+ if (!attr->dev_attr.attr.name) -+ return -ENOMEM; - pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr; - attr = NULL; - -@@ -1214,6 +1216,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num) - attr->nr = blk_num; - attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, - "enable"); -+ if (!attr->dev_attr.attr.name) -+ return -ENOMEM; - pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr; - attr = NULL; - } -@@ -1240,6 +1244,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num) - attr->nr = blk_num; - attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, - "counter%d", j); -+ if (!attr->dev_attr.attr.name) -+ return -ENOMEM; - pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr; - attr = NULL; - -@@ -1251,6 +1257,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num) - attr->nr = blk_num; - attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, - "event%d", j); -+ if (!attr->dev_attr.attr.name) -+ return -ENOMEM; - pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr; - attr = NULL; - } -@@ -1283,6 +1291,8 @@ static int mlxbf_pmc_init_perftype_reg(struct device *dev, int blk_num) - attr->nr = blk_num; - attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, - events[j].evt_name); -+ if (!attr->dev_attr.attr.name) -+ return -ENOMEM; - pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr; - attr = NULL; - i++; -@@ -1311,6 +1321,8 @@ static int mlxbf_pmc_create_groups(struct device *dev, int blk_num) - pmc->block[blk_num].block_attr_grp.attrs = pmc->block[blk_num].block_attr; - pmc->block[blk_num].block_attr_grp.name = devm_kasprintf( - dev, GFP_KERNEL, pmc->block_name[blk_num]); -+ if (!pmc->block[blk_num].block_attr_grp.name) -+ return -ENOMEM; - pmc->groups[blk_num] = &pmc->block[blk_num].block_attr_grp; - - return 0; -@@ -1442,6 +1454,8 @@ static int mlxbf_pmc_probe(struct platform_device *pdev) - - pmc->hwmon_dev = devm_hwmon_device_register_with_groups( - dev, "bfperf", pmc, pmc->groups); -+ if (IS_ERR(pmc->hwmon_dev)) -+ return PTR_ERR(pmc->hwmon_dev); - platform_set_drvdata(pdev, pmc); - - return 0; -diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c -index 1a6373dea109c..6152be38398c4 100644 ---- a/drivers/platform/surface/aggregator/core.c -+++ b/drivers/platform/surface/aggregator/core.c -@@ -231,9 +231,12 @@ static int ssam_receive_buf(struct serdev_device *dev, const unsigned char *buf, - size_t n) - { - struct ssam_controller *ctrl; -+ int ret; - - ctrl = serdev_device_get_drvdata(dev); -- return ssam_controller_receive_buf(ctrl, buf, n); -+ ret = ssam_controller_receive_buf(ctrl, buf, n); -+ -+ return ret < 0 ? 0 : ret; - } - - static void ssam_write_wakeup(struct serdev_device *dev) -diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig -index 1396a839dd8a4..d5acef3202dad 100644 ---- a/drivers/platform/x86/Kconfig -+++ b/drivers/platform/x86/Kconfig -@@ -271,6 +271,7 @@ config ASUS_WMI - depends on RFKILL || RFKILL = n - depends on HOTPLUG_PCI - depends on ACPI_VIDEO || ACPI_VIDEO = n -+ depends on SERIO_I8042 || SERIO_I8042 = n - select INPUT_SPARSEKMAP - select LEDS_CLASS - select NEW_LEDS -@@ -287,7 +288,6 @@ config ASUS_WMI - config ASUS_NB_WMI - tristate "Asus Notebook WMI Driver" - depends on ASUS_WMI -- depends on SERIO_I8042 || SERIO_I8042 = n - help - This is a driver for newer Asus notebooks. It adds extra features - like wireless radio and bluetooth control, leds, hotkeys, backlight... -diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c -index df1db54d4e183..af3da303e2b15 100644 ---- a/drivers/platform/x86/asus-nb-wmi.c -+++ b/drivers/platform/x86/asus-nb-wmi.c -@@ -501,8 +501,6 @@ static const struct dmi_system_id asus_quirks[] = { - - static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) - { -- int ret; -- - quirks = &quirk_asus_unknown; - dmi_check_system(asus_quirks); - -@@ -517,15 +515,6 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) - - if (tablet_mode_sw != -1) - quirks->tablet_switch_mode = tablet_mode_sw; -- -- if (quirks->i8042_filter) { -- ret = i8042_install_filter(quirks->i8042_filter); -- if (ret) { -- pr_warn("Unable to install key filter\n"); -- return; -- } -- pr_info("Using i8042 filter function for receiving events\n"); -- } - } - - static const struct key_entry asus_nb_wmi_keymap[] = { -diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 49dd55b8e8faf..296150eaef929 100644 ---- a/drivers/platform/x86/asus-wmi.c -+++ b/drivers/platform/x86/asus-wmi.c -@@ -3839,6 +3839,12 @@ static int asus_wmi_add(struct platform_device *pdev) - goto fail_wmi_handler; - } - -+ if (asus->driver->quirks->i8042_filter) { -+ err = i8042_install_filter(asus->driver->quirks->i8042_filter); -+ if (err) -+ pr_warn("Unable to install key filter - %d\n", err); -+ } -+ - asus_wmi_battery_init(asus); - - asus_wmi_debugfs_init(asus); -@@ -3873,6 +3879,8 @@ static int asus_wmi_remove(struct platform_device *device) - struct asus_wmi *asus; - - asus = platform_get_drvdata(device); -+ if (asus->driver->quirks->i8042_filter) -+ i8042_remove_filter(asus->driver->quirks->i8042_filter); - wmi_remove_notify_handler(asus->driver->event_guid); - asus_wmi_backlight_exit(asus); - asus_wmi_input_exit(asus); -diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c -index 2b79377cc21e2..b3f3e23a64eee 100644 ---- a/drivers/platform/x86/wmi.c -+++ b/drivers/platform/x86/wmi.c -@@ -1227,6 +1227,11 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) - if (debug_dump_wdg) - wmi_dump_wdg(&gblock[i]); - -+ if (!gblock[i].instance_count) { -+ dev_info(wmi_bus_dev, FW_INFO "%pUL has zero instances\n", &gblock[i].guid); -+ continue; -+ } -+ - if (guid_already_parsed_for_legacy(device, &gblock[i].guid)) - continue; - -diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c -index 8a2f18fa3faf5..9193c3b8edebe 100644 ---- a/drivers/powercap/dtpm_cpu.c -+++ b/drivers/powercap/dtpm_cpu.c -@@ -140,6 +140,8 @@ static void pd_release(struct dtpm *dtpm) - if (policy) { - for_each_cpu(dtpm_cpu->cpu, policy->related_cpus) - per_cpu(dtpm_per_cpu, dtpm_cpu->cpu) = NULL; -+ -+ cpufreq_cpu_put(policy); - } - - kfree(dtpm_cpu); -@@ -191,12 +193,16 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent) - return 0; - - pd = em_cpu_get(cpu); -- if (!pd || em_is_artificial(pd)) -- return -EINVAL; -+ if (!pd || em_is_artificial(pd)) { -+ ret = -EINVAL; -+ goto release_policy; -+ } - - dtpm_cpu = kzalloc(sizeof(*dtpm_cpu), GFP_KERNEL); -- if (!dtpm_cpu) -- return -ENOMEM; -+ if (!dtpm_cpu) { -+ ret = -ENOMEM; -+ goto release_policy; -+ } - - dtpm_init(&dtpm_cpu->dtpm, &dtpm_ops); - dtpm_cpu->cpu = cpu; -@@ -216,6 +222,7 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent) - if (ret) - goto out_dtpm_unregister; - -+ cpufreq_cpu_put(policy); - return 0; - - out_dtpm_unregister: -@@ -227,6 +234,8 @@ out_kfree_dtpm_cpu: - per_cpu(dtpm_per_cpu, cpu) = NULL; - kfree(dtpm_cpu); - -+release_policy: -+ cpufreq_cpu_put(policy); - return ret; - } - -diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c -index 50a577ac3bb42..b6df0d4319072 100644 ---- a/drivers/scsi/be2iscsi/be_main.c -+++ b/drivers/scsi/be2iscsi/be_main.c -@@ -2710,6 +2710,7 @@ init_wrb_hndl_failed: - kfree(pwrb_context->pwrb_handle_base); - kfree(pwrb_context->pwrb_handle_basestd); - } -+ kfree(phwi_ctxt->be_wrbq); - return -ENOMEM; - } - -diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c -index 64f0e047c23d2..4b10921276942 100644 ---- a/drivers/tee/optee/device.c -+++ b/drivers/tee/optee/device.c -@@ -60,7 +60,16 @@ static void optee_release_device(struct device *dev) - kfree(optee_device); - } - --static int optee_register_device(const uuid_t *device_uuid) -+static ssize_t need_supplicant_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return 0; -+} -+ -+static DEVICE_ATTR_RO(need_supplicant); -+ -+static int optee_register_device(const uuid_t *device_uuid, u32 func) - { - struct tee_client_device *optee_device = NULL; - int rc; -@@ -83,6 +92,10 @@ static int optee_register_device(const uuid_t *device_uuid) - put_device(&optee_device->dev); - } - -+ if (func == PTA_CMD_GET_DEVICES_SUPP) -+ device_create_file(&optee_device->dev, -+ &dev_attr_need_supplicant); -+ - return rc; - } - -@@ -142,7 +155,7 @@ static int __optee_enumerate_devices(u32 func) - num_devices = shm_size / sizeof(uuid_t); - - for (idx = 0; idx < num_devices; idx++) { -- rc = optee_register_device(&device_uuid[idx]); -+ rc = optee_register_device(&device_uuid[idx], func); - if (rc) - goto out_shm; - } -diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c -index 7db51781289ed..88035100b86c6 100644 ---- a/drivers/tty/serial/8250/8250_dw.c -+++ b/drivers/tty/serial/8250/8250_dw.c -@@ -795,6 +795,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = { - { "INT33C5", (kernel_ulong_t)&dw8250_dw_apb }, - { "INT3434", (kernel_ulong_t)&dw8250_dw_apb }, - { "INT3435", (kernel_ulong_t)&dw8250_dw_apb }, -+ { "INTC10EE", (kernel_ulong_t)&dw8250_dw_apb }, - { }, - }; - MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); -diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c -index f271becfc46c1..02c9b98a6bbf1 100644 ---- a/drivers/tty/serial/8250/8250_early.c -+++ b/drivers/tty/serial/8250/8250_early.c -@@ -197,6 +197,7 @@ static int __init early_omap8250_setup(struct earlycon_device *device, - OF_EARLYCON_DECLARE(omap8250, "ti,omap2-uart", early_omap8250_setup); - OF_EARLYCON_DECLARE(omap8250, "ti,omap3-uart", early_omap8250_setup); - OF_EARLYCON_DECLARE(omap8250, "ti,omap4-uart", early_omap8250_setup); -+OF_EARLYCON_DECLARE(omap8250, "ti,am654-uart", early_omap8250_setup); - - #endif - -diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c -index 2e21f74a24705..0b04d810b3e61 100644 ---- a/drivers/tty/serial/8250/8250_omap.c -+++ b/drivers/tty/serial/8250/8250_omap.c -@@ -825,7 +825,7 @@ static void __dma_rx_do_complete(struct uart_8250_port *p) - if (priv->habit & UART_HAS_RHR_IT_DIS) { - reg = serial_in(p, UART_OMAP_IER2); - reg &= ~UART_OMAP_IER2_RHR_IT_DIS; -- serial_out(p, UART_OMAP_IER2, UART_OMAP_IER2_RHR_IT_DIS); -+ serial_out(p, UART_OMAP_IER2, reg); - } - - dmaengine_tx_status(rxchan, cookie, &state); -@@ -967,7 +967,7 @@ static int omap_8250_rx_dma(struct uart_8250_port *p) - if (priv->habit & UART_HAS_RHR_IT_DIS) { - reg = serial_in(p, UART_OMAP_IER2); - reg |= UART_OMAP_IER2_RHR_IT_DIS; -- serial_out(p, UART_OMAP_IER2, UART_OMAP_IER2_RHR_IT_DIS); -+ serial_out(p, UART_OMAP_IER2, reg); - } - - dma_async_issue_pending(dma->rxchan); -@@ -1186,10 +1186,12 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) - - status = serial_port_in(port, UART_LSR); - -- if (priv->habit & UART_HAS_EFR2) -- am654_8250_handle_rx_dma(up, iir, status); -- else -- status = omap_8250_handle_rx_dma(up, iir, status); -+ if ((iir & 0x3f) != UART_IIR_THRI) { -+ if (priv->habit & UART_HAS_EFR2) -+ am654_8250_handle_rx_dma(up, iir, status); -+ else -+ status = omap_8250_handle_rx_dma(up, iir, status); -+ } - - serial8250_modem_status(up); - if (status & UART_LSR_THRE && up->dma->tx_err) { -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 0a1cc36f93aa7..c74eaf2552c32 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -218,17 +218,18 @@ static struct vendor_data vendor_st = { - - /* Deals with DMA transactions */ - --struct pl011_sgbuf { -- struct scatterlist sg; -- char *buf; -+struct pl011_dmabuf { -+ dma_addr_t dma; -+ size_t len; -+ char *buf; - }; - - struct pl011_dmarx_data { - struct dma_chan *chan; - struct completion complete; - bool use_buf_b; -- struct pl011_sgbuf sgbuf_a; -- struct pl011_sgbuf sgbuf_b; -+ struct pl011_dmabuf dbuf_a; -+ struct pl011_dmabuf dbuf_b; - dma_cookie_t cookie; - bool running; - struct timer_list timer; -@@ -241,7 +242,8 @@ struct pl011_dmarx_data { - - struct pl011_dmatx_data { - struct dma_chan *chan; -- struct scatterlist sg; -+ dma_addr_t dma; -+ size_t len; - char *buf; - bool queued; - }; -@@ -365,32 +367,24 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) - - #define PL011_DMA_BUFFER_SIZE PAGE_SIZE - --static int pl011_sgbuf_init(struct dma_chan *chan, struct pl011_sgbuf *sg, -+static int pl011_dmabuf_init(struct dma_chan *chan, struct pl011_dmabuf *db, - enum dma_data_direction dir) - { -- dma_addr_t dma_addr; -- -- sg->buf = dma_alloc_coherent(chan->device->dev, -- PL011_DMA_BUFFER_SIZE, &dma_addr, GFP_KERNEL); -- if (!sg->buf) -+ db->buf = dma_alloc_coherent(chan->device->dev, PL011_DMA_BUFFER_SIZE, -+ &db->dma, GFP_KERNEL); -+ if (!db->buf) - return -ENOMEM; -- -- sg_init_table(&sg->sg, 1); -- sg_set_page(&sg->sg, phys_to_page(dma_addr), -- PL011_DMA_BUFFER_SIZE, offset_in_page(dma_addr)); -- sg_dma_address(&sg->sg) = dma_addr; -- sg_dma_len(&sg->sg) = PL011_DMA_BUFFER_SIZE; -+ db->len = PL011_DMA_BUFFER_SIZE; - - return 0; - } - --static void pl011_sgbuf_free(struct dma_chan *chan, struct pl011_sgbuf *sg, -+static void pl011_dmabuf_free(struct dma_chan *chan, struct pl011_dmabuf *db, - enum dma_data_direction dir) - { -- if (sg->buf) { -+ if (db->buf) { - dma_free_coherent(chan->device->dev, -- PL011_DMA_BUFFER_SIZE, sg->buf, -- sg_dma_address(&sg->sg)); -+ PL011_DMA_BUFFER_SIZE, db->buf, db->dma); - } - } - -@@ -551,8 +545,8 @@ static void pl011_dma_tx_callback(void *data) - - spin_lock_irqsave(&uap->port.lock, flags); - if (uap->dmatx.queued) -- dma_unmap_sg(dmatx->chan->device->dev, &dmatx->sg, 1, -- DMA_TO_DEVICE); -+ dma_unmap_single(dmatx->chan->device->dev, dmatx->dma, -+ dmatx->len, DMA_TO_DEVICE); - - dmacr = uap->dmacr; - uap->dmacr = dmacr & ~UART011_TXDMAE; -@@ -638,18 +632,19 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) - memcpy(&dmatx->buf[first], &xmit->buf[0], second); - } - -- dmatx->sg.length = count; -- -- if (dma_map_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE) != 1) { -+ dmatx->len = count; -+ dmatx->dma = dma_map_single(dma_dev->dev, dmatx->buf, count, -+ DMA_TO_DEVICE); -+ if (dmatx->dma == DMA_MAPPING_ERROR) { - uap->dmatx.queued = false; - dev_dbg(uap->port.dev, "unable to map TX DMA\n"); - return -EBUSY; - } - -- desc = dmaengine_prep_slave_sg(chan, &dmatx->sg, 1, DMA_MEM_TO_DEV, -+ desc = dmaengine_prep_slave_single(chan, dmatx->dma, dmatx->len, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { -- dma_unmap_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE); -+ dma_unmap_single(dma_dev->dev, dmatx->dma, dmatx->len, DMA_TO_DEVICE); - uap->dmatx.queued = false; - /* - * If DMA cannot be used right now, we complete this -@@ -813,8 +808,8 @@ __acquires(&uap->port.lock) - dmaengine_terminate_async(uap->dmatx.chan); - - if (uap->dmatx.queued) { -- dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1, -- DMA_TO_DEVICE); -+ dma_unmap_single(uap->dmatx.chan->device->dev, uap->dmatx.dma, -+ uap->dmatx.len, DMA_TO_DEVICE); - uap->dmatx.queued = false; - uap->dmacr &= ~UART011_TXDMAE; - pl011_write(uap->dmacr, uap, REG_DMACR); -@@ -828,15 +823,15 @@ static int pl011_dma_rx_trigger_dma(struct uart_amba_port *uap) - struct dma_chan *rxchan = uap->dmarx.chan; - struct pl011_dmarx_data *dmarx = &uap->dmarx; - struct dma_async_tx_descriptor *desc; -- struct pl011_sgbuf *sgbuf; -+ struct pl011_dmabuf *dbuf; - - if (!rxchan) - return -EIO; - - /* Start the RX DMA job */ -- sgbuf = uap->dmarx.use_buf_b ? -- &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; -- desc = dmaengine_prep_slave_sg(rxchan, &sgbuf->sg, 1, -+ dbuf = uap->dmarx.use_buf_b ? -+ &uap->dmarx.dbuf_b : &uap->dmarx.dbuf_a; -+ desc = dmaengine_prep_slave_single(rxchan, dbuf->dma, dbuf->len, - DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - /* -@@ -876,8 +871,8 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, - bool readfifo) - { - struct tty_port *port = &uap->port.state->port; -- struct pl011_sgbuf *sgbuf = use_buf_b ? -- &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; -+ struct pl011_dmabuf *dbuf = use_buf_b ? -+ &uap->dmarx.dbuf_b : &uap->dmarx.dbuf_a; - int dma_count = 0; - u32 fifotaken = 0; /* only used for vdbg() */ - -@@ -886,7 +881,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, - - if (uap->dmarx.poll_rate) { - /* The data can be taken by polling */ -- dmataken = sgbuf->sg.length - dmarx->last_residue; -+ dmataken = dbuf->len - dmarx->last_residue; - /* Recalculate the pending size */ - if (pending >= dmataken) - pending -= dmataken; -@@ -900,7 +895,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, - * Note that tty_insert_flip_buf() tries to take as many chars - * as it can. - */ -- dma_count = tty_insert_flip_string(port, sgbuf->buf + dmataken, -+ dma_count = tty_insert_flip_string(port, dbuf->buf + dmataken, - pending); - - uap->port.icount.rx += dma_count; -@@ -911,7 +906,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, - - /* Reset the last_residue for Rx DMA poll */ - if (uap->dmarx.poll_rate) -- dmarx->last_residue = sgbuf->sg.length; -+ dmarx->last_residue = dbuf->len; - - /* - * Only continue with trying to read the FIFO if all DMA chars have -@@ -946,8 +941,8 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) - { - struct pl011_dmarx_data *dmarx = &uap->dmarx; - struct dma_chan *rxchan = dmarx->chan; -- struct pl011_sgbuf *sgbuf = dmarx->use_buf_b ? -- &dmarx->sgbuf_b : &dmarx->sgbuf_a; -+ struct pl011_dmabuf *dbuf = dmarx->use_buf_b ? -+ &dmarx->dbuf_b : &dmarx->dbuf_a; - size_t pending; - struct dma_tx_state state; - enum dma_status dmastat; -@@ -969,7 +964,7 @@ static void pl011_dma_rx_irq(struct uart_amba_port *uap) - pl011_write(uap->dmacr, uap, REG_DMACR); - uap->dmarx.running = false; - -- pending = sgbuf->sg.length - state.residue; -+ pending = dbuf->len - state.residue; - BUG_ON(pending > PL011_DMA_BUFFER_SIZE); - /* Then we terminate the transfer - we now know our residue */ - dmaengine_terminate_all(rxchan); -@@ -996,8 +991,8 @@ static void pl011_dma_rx_callback(void *data) - struct pl011_dmarx_data *dmarx = &uap->dmarx; - struct dma_chan *rxchan = dmarx->chan; - bool lastbuf = dmarx->use_buf_b; -- struct pl011_sgbuf *sgbuf = dmarx->use_buf_b ? -- &dmarx->sgbuf_b : &dmarx->sgbuf_a; -+ struct pl011_dmabuf *dbuf = dmarx->use_buf_b ? -+ &dmarx->dbuf_b : &dmarx->dbuf_a; - size_t pending; - struct dma_tx_state state; - int ret; -@@ -1015,7 +1010,7 @@ static void pl011_dma_rx_callback(void *data) - * the DMA irq handler. So we check the residue here. - */ - rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state); -- pending = sgbuf->sg.length - state.residue; -+ pending = dbuf->len - state.residue; - BUG_ON(pending > PL011_DMA_BUFFER_SIZE); - /* Then we terminate the transfer - we now know our residue */ - dmaengine_terminate_all(rxchan); -@@ -1067,16 +1062,16 @@ static void pl011_dma_rx_poll(struct timer_list *t) - unsigned long flags; - unsigned int dmataken = 0; - unsigned int size = 0; -- struct pl011_sgbuf *sgbuf; -+ struct pl011_dmabuf *dbuf; - int dma_count; - struct dma_tx_state state; - -- sgbuf = dmarx->use_buf_b ? &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; -+ dbuf = dmarx->use_buf_b ? &uap->dmarx.dbuf_b : &uap->dmarx.dbuf_a; - rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state); - if (likely(state.residue < dmarx->last_residue)) { -- dmataken = sgbuf->sg.length - dmarx->last_residue; -+ dmataken = dbuf->len - dmarx->last_residue; - size = dmarx->last_residue - state.residue; -- dma_count = tty_insert_flip_string(port, sgbuf->buf + dmataken, -+ dma_count = tty_insert_flip_string(port, dbuf->buf + dmataken, - size); - if (dma_count == size) - dmarx->last_residue = state.residue; -@@ -1123,7 +1118,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) - return; - } - -- sg_init_one(&uap->dmatx.sg, uap->dmatx.buf, PL011_DMA_BUFFER_SIZE); -+ uap->dmatx.len = PL011_DMA_BUFFER_SIZE; - - /* The DMA buffer is now the FIFO the TTY subsystem can use */ - uap->port.fifosize = PL011_DMA_BUFFER_SIZE; -@@ -1133,7 +1128,7 @@ static void pl011_dma_startup(struct uart_amba_port *uap) - goto skip_rx; - - /* Allocate and map DMA RX buffers */ -- ret = pl011_sgbuf_init(uap->dmarx.chan, &uap->dmarx.sgbuf_a, -+ ret = pl011_dmabuf_init(uap->dmarx.chan, &uap->dmarx.dbuf_a, - DMA_FROM_DEVICE); - if (ret) { - dev_err(uap->port.dev, "failed to init DMA %s: %d\n", -@@ -1141,12 +1136,12 @@ static void pl011_dma_startup(struct uart_amba_port *uap) - goto skip_rx; - } - -- ret = pl011_sgbuf_init(uap->dmarx.chan, &uap->dmarx.sgbuf_b, -+ ret = pl011_dmabuf_init(uap->dmarx.chan, &uap->dmarx.dbuf_b, - DMA_FROM_DEVICE); - if (ret) { - dev_err(uap->port.dev, "failed to init DMA %s: %d\n", - "RX buffer B", ret); -- pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_a, -+ pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_a, - DMA_FROM_DEVICE); - goto skip_rx; - } -@@ -1200,8 +1195,9 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) - /* In theory, this should already be done by pl011_dma_flush_buffer */ - dmaengine_terminate_all(uap->dmatx.chan); - if (uap->dmatx.queued) { -- dma_unmap_sg(uap->dmatx.chan->device->dev, &uap->dmatx.sg, 1, -- DMA_TO_DEVICE); -+ dma_unmap_single(uap->dmatx.chan->device->dev, -+ uap->dmatx.dma, uap->dmatx.len, -+ DMA_TO_DEVICE); - uap->dmatx.queued = false; - } - -@@ -1212,8 +1208,8 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap) - if (uap->using_rx_dma) { - dmaengine_terminate_all(uap->dmarx.chan); - /* Clean up the RX DMA */ -- pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_a, DMA_FROM_DEVICE); -- pl011_sgbuf_free(uap->dmarx.chan, &uap->dmarx.sgbuf_b, DMA_FROM_DEVICE); -+ pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_a, DMA_FROM_DEVICE); -+ pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_b, DMA_FROM_DEVICE); - if (uap->dmarx.poll_rate) - del_timer_sync(&uap->dmarx.timer); - uap->using_rx_dma = false; -diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c -index b398fba942964..b4b849415c503 100644 ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -769,6 +769,18 @@ static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) - case SC16IS7XX_IIR_RTOI_SRC: - case SC16IS7XX_IIR_XOFFI_SRC: - rxlen = sc16is7xx_port_read(port, SC16IS7XX_RXLVL_REG); -+ -+ /* -+ * There is a silicon bug that makes the chip report a -+ * time-out interrupt but no data in the FIFO. This is -+ * described in errata section 18.1.4. -+ * -+ * When this happens, read one byte from the FIFO to -+ * clear the interrupt. -+ */ -+ if (iir == SC16IS7XX_IIR_RTOI_SRC && !rxlen) -+ rxlen = 1; -+ - if (rxlen) - sc16is7xx_handle_rx(port, rxlen, iir); - break; -diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c -index 6be6009f911e1..f1ca9250cad96 100644 ---- a/drivers/usb/gadget/function/f_hid.c -+++ b/drivers/usb/gadget/function/f_hid.c -@@ -88,6 +88,7 @@ static void hidg_release(struct device *dev) - { - struct f_hidg *hidg = container_of(dev, struct f_hidg, dev); - -+ kfree(hidg->report_desc); - kfree(hidg->set_report_buf); - kfree(hidg); - } -@@ -1287,9 +1288,9 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) - hidg->report_length = opts->report_length; - hidg->report_desc_length = opts->report_desc_length; - if (opts->report_desc) { -- hidg->report_desc = devm_kmemdup(&hidg->dev, opts->report_desc, -- opts->report_desc_length, -- GFP_KERNEL); -+ hidg->report_desc = kmemdup(opts->report_desc, -+ opts->report_desc_length, -+ GFP_KERNEL); - if (!hidg->report_desc) { - put_device(&hidg->dev); - --opts->refcnt; -diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c -index 1c0c61e8ba696..c40f2ecbe1b8c 100644 ---- a/drivers/usb/gadget/udc/core.c -+++ b/drivers/usb/gadget/udc/core.c -@@ -1608,8 +1608,6 @@ static void gadget_unbind_driver(struct device *dev) - - dev_dbg(&udc->dev, "unbinding gadget driver [%s]\n", driver->function); - -- kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); -- - udc->allow_connect = false; - cancel_work_sync(&udc->vbus_work); - mutex_lock(&udc->connect_lock); -@@ -1629,6 +1627,8 @@ static void gadget_unbind_driver(struct device *dev) - driver->is_bound = false; - udc->driver = NULL; - mutex_unlock(&udc_lock); -+ -+ kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); - } - - /* ------------------------------------------------------------------------- */ -diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c -index 24bcf6ab12d8a..e02ef31da68e4 100644 ---- a/drivers/usb/host/xhci-pci.c -+++ b/drivers/usb/host/xhci-pci.c -@@ -348,8 +348,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) - /* xHC spec requires PCI devices to support D3hot and D3cold */ - if (xhci->hci_version >= 0x120) - xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; -- else if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version >= 0x110) -- xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; - - if (xhci->quirks & XHCI_RESET_ON_RESUME) - xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, -diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c -index 3c3bab33e03a5..49d6b2388b874 100644 ---- a/drivers/usb/typec/class.c -+++ b/drivers/usb/typec/class.c -@@ -267,7 +267,7 @@ static void typec_altmode_put_partner(struct altmode *altmode) - if (!partner) - return; - -- adev = &partner->adev; -+ adev = &altmode->adev; - - if (is_typec_plug(adev->dev.parent)) { - struct typec_plug *plug = to_typec_plug(adev->dev.parent); -@@ -497,7 +497,8 @@ static void typec_altmode_release(struct device *dev) - { - struct altmode *alt = to_altmode(to_typec_altmode(dev)); - -- typec_altmode_put_partner(alt); -+ if (!is_typec_port(dev->parent)) -+ typec_altmode_put_partner(alt); - - altmode_id_remove(alt->adev.dev.parent, alt->id); - kfree(alt); -diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c -index bf99654371b35..2b7e796c48897 100644 ---- a/drivers/vdpa/mlx5/net/mlx5_vnet.c -+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c -@@ -2508,13 +2508,18 @@ static int setup_cvq_vring(struct mlx5_vdpa_dev *mvdev) - struct mlx5_control_vq *cvq = &mvdev->cvq; - int err = 0; - -- if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) -+ if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) { -+ u16 idx = cvq->vring.last_avail_idx; -+ - err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features, - MLX5_CVQ_MAX_ENT, false, - (struct vring_desc *)(uintptr_t)cvq->desc_addr, - (struct vring_avail *)(uintptr_t)cvq->driver_addr, - (struct vring_used *)(uintptr_t)cvq->device_addr); - -+ if (!err) -+ cvq->vring.last_avail_idx = cvq->vring.last_used_idx = idx; -+ } - return err; - } - -diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c -index 2c6078a6b8ecb..58ca7c936393c 100644 ---- a/fs/nilfs2/sufile.c -+++ b/fs/nilfs2/sufile.c -@@ -501,15 +501,38 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum) - - down_write(&NILFS_MDT(sufile)->mi_sem); - ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh); -- if (!ret) { -- mark_buffer_dirty(bh); -- nilfs_mdt_mark_dirty(sufile); -- kaddr = kmap_atomic(bh->b_page); -- su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr); -+ if (ret) -+ goto out_sem; -+ -+ kaddr = kmap_atomic(bh->b_page); -+ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr); -+ if (unlikely(nilfs_segment_usage_error(su))) { -+ struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; -+ -+ kunmap_atomic(kaddr); -+ brelse(bh); -+ if (nilfs_segment_is_active(nilfs, segnum)) { -+ nilfs_error(sufile->i_sb, -+ "active segment %llu is erroneous", -+ (unsigned long long)segnum); -+ } else { -+ /* -+ * Segments marked erroneous are never allocated by -+ * nilfs_sufile_alloc(); only active segments, ie, -+ * the segments indexed by ns_segnum or ns_nextnum, -+ * can be erroneous here. -+ */ -+ WARN_ON_ONCE(1); -+ } -+ ret = -EIO; -+ } else { - nilfs_segment_usage_set_dirty(su); - kunmap_atomic(kaddr); -+ mark_buffer_dirty(bh); -+ nilfs_mdt_mark_dirty(sufile); - brelse(bh); - } -+out_sem: - up_write(&NILFS_MDT(sufile)->mi_sem); - return ret; - } -@@ -536,9 +559,14 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, - - kaddr = kmap_atomic(bh->b_page); - su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr); -- WARN_ON(nilfs_segment_usage_error(su)); -- if (modtime) -+ if (modtime) { -+ /* -+ * Check segusage error and set su_lastmod only when updating -+ * this entry with a valid timestamp, not for cancellation. -+ */ -+ WARN_ON_ONCE(nilfs_segment_usage_error(su)); - su->su_lastmod = cpu_to_le64(modtime); -+ } - su->su_nblocks = cpu_to_le32(nblocks); - kunmap_atomic(kaddr); - -diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c -index 0f0667957c810..71400496ed365 100644 ---- a/fs/nilfs2/the_nilfs.c -+++ b/fs/nilfs2/the_nilfs.c -@@ -716,7 +716,11 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data) - goto failed_sbh; - } - nilfs_release_super_block(nilfs); -- sb_set_blocksize(sb, blocksize); -+ if (!sb_set_blocksize(sb, blocksize)) { -+ nilfs_err(sb, "bad blocksize %d", blocksize); -+ err = -EINVAL; -+ goto out; -+ } - - err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp); - if (err) -diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c -index 33ea1440f4b06..2e15b182e59fc 100644 ---- a/fs/smb/client/cifsfs.c -+++ b/fs/smb/client/cifsfs.c -@@ -1191,32 +1191,103 @@ const struct inode_operations cifs_symlink_inode_ops = { - .listxattr = cifs_listxattr, - }; - -+/* -+ * Advance the EOF marker to after the source range. -+ */ -+static int cifs_precopy_set_eof(struct inode *src_inode, struct cifsInodeInfo *src_cifsi, -+ struct cifs_tcon *src_tcon, -+ unsigned int xid, loff_t src_end) -+{ -+ struct cifsFileInfo *writeable_srcfile; -+ int rc = -EINVAL; -+ -+ writeable_srcfile = find_writable_file(src_cifsi, FIND_WR_FSUID_ONLY); -+ if (writeable_srcfile) { -+ if (src_tcon->ses->server->ops->set_file_size) -+ rc = src_tcon->ses->server->ops->set_file_size( -+ xid, src_tcon, writeable_srcfile, -+ src_inode->i_size, true /* no need to set sparse */); -+ else -+ rc = -ENOSYS; -+ cifsFileInfo_put(writeable_srcfile); -+ cifs_dbg(FYI, "SetFSize for copychunk rc = %d\n", rc); -+ } -+ -+ if (rc < 0) -+ goto set_failed; -+ -+ netfs_resize_file(&src_cifsi->netfs, src_end); -+ fscache_resize_cookie(cifs_inode_cookie(src_inode), src_end); -+ return 0; -+ -+set_failed: -+ return filemap_write_and_wait(src_inode->i_mapping); -+} -+ -+/* -+ * Flush out either the folio that overlaps the beginning of a range in which -+ * pos resides or the folio that overlaps the end of a range unless that folio -+ * is entirely within the range we're going to invalidate. We extend the flush -+ * bounds to encompass the folio. -+ */ -+static int cifs_flush_folio(struct inode *inode, loff_t pos, loff_t *_fstart, loff_t *_fend, -+ bool first) -+{ -+ struct folio *folio; -+ unsigned long long fpos, fend; -+ pgoff_t index = pos / PAGE_SIZE; -+ size_t size; -+ int rc = 0; -+ -+ folio = filemap_get_folio(inode->i_mapping, index); -+ if (IS_ERR(folio)) -+ return 0; -+ -+ size = folio_size(folio); -+ fpos = folio_pos(folio); -+ fend = fpos + size - 1; -+ *_fstart = min_t(unsigned long long, *_fstart, fpos); -+ *_fend = max_t(unsigned long long, *_fend, fend); -+ if ((first && pos == fpos) || (!first && pos == fend)) -+ goto out; -+ -+ rc = filemap_write_and_wait_range(inode->i_mapping, fpos, fend); -+out: -+ folio_put(folio); -+ return rc; -+} -+ - static loff_t cifs_remap_file_range(struct file *src_file, loff_t off, - struct file *dst_file, loff_t destoff, loff_t len, - unsigned int remap_flags) - { - struct inode *src_inode = file_inode(src_file); - struct inode *target_inode = file_inode(dst_file); -+ struct cifsInodeInfo *src_cifsi = CIFS_I(src_inode); -+ struct cifsInodeInfo *target_cifsi = CIFS_I(target_inode); - struct cifsFileInfo *smb_file_src = src_file->private_data; -- struct cifsFileInfo *smb_file_target; -- struct cifs_tcon *target_tcon; -+ struct cifsFileInfo *smb_file_target = dst_file->private_data; -+ struct cifs_tcon *target_tcon, *src_tcon; -+ unsigned long long destend, fstart, fend, new_size; - unsigned int xid; - int rc; - -- if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY)) -+ if (remap_flags & REMAP_FILE_DEDUP) -+ return -EOPNOTSUPP; -+ if (remap_flags & ~REMAP_FILE_ADVISORY) - return -EINVAL; - - cifs_dbg(FYI, "clone range\n"); - - xid = get_xid(); - -- if (!src_file->private_data || !dst_file->private_data) { -+ if (!smb_file_src || !smb_file_target) { - rc = -EBADF; - cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n"); - goto out; - } - -- smb_file_target = dst_file->private_data; -+ src_tcon = tlink_tcon(smb_file_src->tlink); - target_tcon = tlink_tcon(smb_file_target->tlink); - - /* -@@ -1229,20 +1300,63 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off, - if (len == 0) - len = src_inode->i_size - off; - -- cifs_dbg(FYI, "about to flush pages\n"); -- /* should we flush first and last page first */ -- truncate_inode_pages_range(&target_inode->i_data, destoff, -- PAGE_ALIGN(destoff + len)-1); -+ cifs_dbg(FYI, "clone range\n"); - -- if (target_tcon->ses->server->ops->duplicate_extents) -+ /* Flush the source buffer */ -+ rc = filemap_write_and_wait_range(src_inode->i_mapping, off, -+ off + len - 1); -+ if (rc) -+ goto unlock; -+ -+ /* The server-side copy will fail if the source crosses the EOF marker. -+ * Advance the EOF marker after the flush above to the end of the range -+ * if it's short of that. -+ */ -+ if (src_cifsi->netfs.remote_i_size < off + len) { -+ rc = cifs_precopy_set_eof(src_inode, src_cifsi, src_tcon, xid, off + len); -+ if (rc < 0) -+ goto unlock; -+ } -+ -+ new_size = destoff + len; -+ destend = destoff + len - 1; -+ -+ /* Flush the folios at either end of the destination range to prevent -+ * accidental loss of dirty data outside of the range. -+ */ -+ fstart = destoff; -+ fend = destend; -+ -+ rc = cifs_flush_folio(target_inode, destoff, &fstart, &fend, true); -+ if (rc) -+ goto unlock; -+ rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false); -+ if (rc) -+ goto unlock; -+ -+ /* Discard all the folios that overlap the destination region. */ -+ cifs_dbg(FYI, "about to discard pages %llx-%llx\n", fstart, fend); -+ truncate_inode_pages_range(&target_inode->i_data, fstart, fend); -+ -+ fscache_invalidate(cifs_inode_cookie(target_inode), NULL, -+ i_size_read(target_inode), 0); -+ -+ rc = -EOPNOTSUPP; -+ if (target_tcon->ses->server->ops->duplicate_extents) { - rc = target_tcon->ses->server->ops->duplicate_extents(xid, - smb_file_src, smb_file_target, off, len, destoff); -- else -- rc = -EOPNOTSUPP; -+ if (rc == 0 && new_size > i_size_read(target_inode)) { -+ truncate_setsize(target_inode, new_size); -+ netfs_resize_file(&target_cifsi->netfs, new_size); -+ fscache_resize_cookie(cifs_inode_cookie(target_inode), -+ new_size); -+ } -+ } - - /* force revalidate of size and timestamps of target file now - that target is updated on the server */ - CIFS_I(target_inode)->time = 0; -+unlock: - /* although unlocking in the reverse order from locking is not - strictly necessary here it is a little cleaner to be consistent */ - unlock_two_nondirectories(src_inode, target_inode); -@@ -1258,10 +1372,12 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, - { - struct inode *src_inode = file_inode(src_file); - struct inode *target_inode = file_inode(dst_file); -+ struct cifsInodeInfo *src_cifsi = CIFS_I(src_inode); - struct cifsFileInfo *smb_file_src; - struct cifsFileInfo *smb_file_target; - struct cifs_tcon *src_tcon; - struct cifs_tcon *target_tcon; -+ unsigned long long destend, fstart, fend; - ssize_t rc; - - cifs_dbg(FYI, "copychunk range\n"); -@@ -1301,13 +1417,41 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, - if (rc) - goto unlock; - -- /* should we flush first and last page first */ -- truncate_inode_pages(&target_inode->i_data, 0); -+ /* The server-side copy will fail if the source crosses the EOF marker. -+ * Advance the EOF marker after the flush above to the end of the range -+ * if it's short of that. -+ */ -+ if (src_cifsi->server_eof < off + len) { -+ rc = cifs_precopy_set_eof(src_inode, src_cifsi, src_tcon, xid, off + len); -+ if (rc < 0) -+ goto unlock; -+ } -+ -+ destend = destoff + len - 1; -+ -+ /* Flush the folios at either end of the destination range to prevent -+ * accidental loss of dirty data outside of the range. -+ */ -+ fstart = destoff; -+ fend = destend; -+ -+ rc = cifs_flush_folio(target_inode, destoff, &fstart, &fend, true); -+ if (rc) -+ goto unlock; -+ rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false); -+ if (rc) -+ goto unlock; -+ -+ /* Discard all the folios that overlap the destination region. */ -+ truncate_inode_pages_range(&target_inode->i_data, fstart, fend); - - rc = file_modified(dst_file); -- if (!rc) -+ if (!rc) { - rc = target_tcon->ses->server->ops->copychunk_range(xid, - smb_file_src, smb_file_target, off, len, destoff); -+ if (rc > 0 && destoff + rc > i_size_read(target_inode)) -+ truncate_setsize(target_inode, destoff + rc); -+ } - - file_accessed(src_file); - -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index e628848a1df93..6ef3c00de5ca1 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -2834,6 +2834,8 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, - usleep_range(512, 2048); - } while (++retry_count < 5); - -+ if (!rc && !dfs_rsp) -+ rc = -EIO; - if (rc) { - if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP) - cifs_tcon_dbg(VFS, "%s: ioctl error: rc=%d\n", __func__, rc); -diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h -index c7e0d80dbf6a5..67575bc8a7e29 100644 ---- a/include/linux/cpuhotplug.h -+++ b/include/linux/cpuhotplug.h -@@ -196,6 +196,7 @@ enum cpuhp_state { - CPUHP_AP_ARM_CORESIGHT_CTI_STARTING, - CPUHP_AP_ARM64_ISNDEP_STARTING, - CPUHP_AP_SMPCFD_DYING, -+ CPUHP_AP_HRTIMERS_DYING, - CPUHP_AP_X86_TBOOT_DYING, - CPUHP_AP_ARM_CACHE_B15_RAC_DYING, - CPUHP_AP_ONLINE, -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index 0ee140176f102..f2044d5a652b5 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -531,9 +531,9 @@ extern void sysrq_timer_list_show(void); - - int hrtimers_prepare_cpu(unsigned int cpu); - #ifdef CONFIG_HOTPLUG_CPU --int hrtimers_dead_cpu(unsigned int cpu); -+int hrtimers_cpu_dying(unsigned int cpu); - #else --#define hrtimers_dead_cpu NULL -+#define hrtimers_cpu_dying NULL - #endif - - #endif -diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h -index e46f6b49eb389..1c6f35ba1604f 100644 ---- a/include/linux/hugetlb.h -+++ b/include/linux/hugetlb.h -@@ -880,10 +880,7 @@ static inline bool hugepage_migration_supported(struct hstate *h) - return arch_hugetlb_migration_supported(h); - } - --static inline bool __vma_private_lock(struct vm_area_struct *vma) --{ -- return (!(vma->vm_flags & VM_MAYSHARE)) && vma->vm_private_data; --} -+bool __vma_private_lock(struct vm_area_struct *vma); - - /* - * Movability check is different as compared to migration check. -diff --git a/include/linux/iommu.h b/include/linux/iommu.h -index 3c9da1f8979e3..9d87090953bcc 100644 ---- a/include/linux/iommu.h -+++ b/include/linux/iommu.h -@@ -657,6 +657,7 @@ static inline void dev_iommu_priv_set(struct device *dev, void *priv) - dev->iommu->priv = priv; - } - -+extern struct mutex iommu_probe_device_lock; - int iommu_probe_device(struct device *dev); - void iommu_release_device(struct device *dev); - -diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h -index 85a64cb95d755..8de5d51a0b5e7 100644 ---- a/include/linux/kprobes.h -+++ b/include/linux/kprobes.h -@@ -140,7 +140,7 @@ static inline bool kprobe_ftrace(struct kprobe *p) - * - */ - struct kretprobe_holder { -- struct kretprobe *rp; -+ struct kretprobe __rcu *rp; - refcount_t ref; - }; - -@@ -202,10 +202,8 @@ extern int arch_trampoline_kprobe(struct kprobe *p); - #ifdef CONFIG_KRETPROBE_ON_RETHOOK - static nokprobe_inline struct kretprobe *get_kretprobe(struct kretprobe_instance *ri) - { -- RCU_LOCKDEP_WARN(!rcu_read_lock_any_held(), -- "Kretprobe is accessed from instance under preemptive context"); -- -- return (struct kretprobe *)READ_ONCE(ri->node.rethook->data); -+ /* rethook::data is non-changed field, so that you can access it freely. */ -+ return (struct kretprobe *)ri->node.rethook->data; - } - static nokprobe_inline unsigned long get_kretprobe_retaddr(struct kretprobe_instance *ri) - { -@@ -250,10 +248,7 @@ unsigned long kretprobe_trampoline_handler(struct pt_regs *regs, - - static nokprobe_inline struct kretprobe *get_kretprobe(struct kretprobe_instance *ri) - { -- RCU_LOCKDEP_WARN(!rcu_read_lock_any_held(), -- "Kretprobe is accessed from instance under preemptive context"); -- -- return READ_ONCE(ri->rph->rp); -+ return rcu_dereference_check(ri->rph->rp, rcu_read_lock_any_held()); - } - - static nokprobe_inline unsigned long get_kretprobe_retaddr(struct kretprobe_instance *ri) -diff --git a/include/linux/rethook.h b/include/linux/rethook.h -index bdbe6717f45a2..a00963f33bc14 100644 ---- a/include/linux/rethook.h -+++ b/include/linux/rethook.h -@@ -29,7 +29,12 @@ typedef void (*rethook_handler_t) (struct rethook_node *, void *, struct pt_regs - */ - struct rethook { - void *data; -- rethook_handler_t handler; -+ /* -+ * To avoid sparse warnings, this uses a raw function pointer with -+ * __rcu, instead of rethook_handler_t. But this must be same as -+ * rethook_handler_t. -+ */ -+ void (__rcu *handler) (struct rethook_node *, void *, struct pt_regs *); - struct freelist_head pool; - refcount_t ref; - struct rcu_head rcu; -diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h -index d82ff9fa1a6e8..9f4a4f70270df 100644 ---- a/include/linux/stmmac.h -+++ b/include/linux/stmmac.h -@@ -172,6 +172,7 @@ struct stmmac_fpe_cfg { - bool hs_enable; /* FPE handshake enable */ - enum stmmac_fpe_state lp_fpe_state; /* Link Partner FPE state */ - enum stmmac_fpe_state lo_fpe_state; /* Local station FPE state */ -+ u32 fpe_csr; /* MAC_FPE_CTRL_STS reg cache */ - }; - - struct stmmac_safety_feature_cfg { -diff --git a/include/net/genetlink.h b/include/net/genetlink.h -index 9f97f73615b69..b9e5a22ae3ff9 100644 ---- a/include/net/genetlink.h -+++ b/include/net/genetlink.h -@@ -12,10 +12,12 @@ - * struct genl_multicast_group - generic netlink multicast group - * @name: name of the multicast group, names are per-family - * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM) -+ * @cap_sys_admin: whether %CAP_SYS_ADMIN is required for binding - */ - struct genl_multicast_group { - char name[GENL_NAMSIZ]; - u8 flags; -+ u8 cap_sys_admin:1; - }; - - struct genl_ops; -diff --git a/include/net/tcp.h b/include/net/tcp.h -index 19646fdec23dc..c3d56b337f358 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -1460,17 +1460,22 @@ static inline int tcp_full_space(const struct sock *sk) - return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf)); - } - --static inline void tcp_adjust_rcv_ssthresh(struct sock *sk) -+static inline void __tcp_adjust_rcv_ssthresh(struct sock *sk, u32 new_ssthresh) - { - int unused_mem = sk_unused_reserved_mem(sk); - struct tcp_sock *tp = tcp_sk(sk); - -- tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); -+ tp->rcv_ssthresh = min(tp->rcv_ssthresh, new_ssthresh); - if (unused_mem) - tp->rcv_ssthresh = max_t(u32, tp->rcv_ssthresh, - tcp_win_from_space(sk, unused_mem)); - } - -+static inline void tcp_adjust_rcv_ssthresh(struct sock *sk) -+{ -+ __tcp_adjust_rcv_ssthresh(sk, 4U * tcp_sk(sk)->advmss); -+} -+ - void tcp_cleanup_rbuf(struct sock *sk, int copied); - void __tcp_cleanup_rbuf(struct sock *sk, int copied); - -diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h -index 92a673cd9b4fd..77b83ea62dd69 100644 ---- a/include/rdma/ib_umem.h -+++ b/include/rdma/ib_umem.h -@@ -78,6 +78,13 @@ static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter, - { - __rdma_block_iter_start(biter, umem->sgt_append.sgt.sgl, - umem->sgt_append.sgt.nents, pgsz); -+ biter->__sg_advance = ib_umem_offset(umem) & ~(pgsz - 1); -+ biter->__sg_numblocks = ib_umem_num_dma_blocks(umem, pgsz); -+} -+ -+static inline bool __rdma_umem_block_iter_next(struct ib_block_iter *biter) -+{ -+ return __rdma_block_iter_next(biter) && biter->__sg_numblocks--; - } - - /** -@@ -93,7 +100,7 @@ static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter, - */ - #define rdma_umem_for_each_dma_block(umem, biter, pgsz) \ - for (__rdma_umem_block_iter_start(biter, umem, pgsz); \ -- __rdma_block_iter_next(biter);) -+ __rdma_umem_block_iter_next(biter);) - - #ifdef CONFIG_INFINIBAND_USER_MEM - -diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h -index 975d6e9efbcb4..5582509003264 100644 ---- a/include/rdma/ib_verbs.h -+++ b/include/rdma/ib_verbs.h -@@ -2835,6 +2835,7 @@ struct ib_block_iter { - /* internal states */ - struct scatterlist *__sg; /* sg holding the current aligned block */ - dma_addr_t __dma_addr; /* unaligned DMA address of this block */ -+ size_t __sg_numblocks; /* ib_umem_num_dma_blocks() */ - unsigned int __sg_nents; /* number of SG entries */ - unsigned int __sg_advance; /* number of bytes to advance in sg in next step */ - unsigned int __pg_bit; /* alignment of current block */ -diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h -index 466fd3f4447c2..af8f4c304d272 100644 ---- a/include/uapi/linux/netfilter/nf_tables.h -+++ b/include/uapi/linux/netfilter/nf_tables.h -@@ -816,12 +816,14 @@ enum nft_exthdr_flags { - * @NFT_EXTHDR_OP_TCP: match against tcp options - * @NFT_EXTHDR_OP_IPV4: match against ipv4 options - * @NFT_EXTHDR_OP_SCTP: match against sctp chunks -+ * @NFT_EXTHDR_OP_DCCP: match against dccp otions - */ - enum nft_exthdr_op { - NFT_EXTHDR_OP_IPV6, - NFT_EXTHDR_OP_TCPOPT, - NFT_EXTHDR_OP_IPV4, - NFT_EXTHDR_OP_SCTP, -+ NFT_EXTHDR_OP_DCCP, - __NFT_EXTHDR_OP_MAX - }; - #define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1) -diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c -index f413ebed81ab3..35894955b4549 100644 ---- a/io_uring/io_uring.c -+++ b/io_uring/io_uring.c -@@ -1377,6 +1377,7 @@ static __cold void io_iopoll_try_reap_events(struct io_ring_ctx *ctx) - if (!(ctx->flags & IORING_SETUP_IOPOLL)) - return; - -+ percpu_ref_get(&ctx->refs); - mutex_lock(&ctx->uring_lock); - while (!wq_list_empty(&ctx->iopoll_list)) { - /* let it sleep and repeat later if can't complete a request */ -@@ -1394,6 +1395,7 @@ static __cold void io_iopoll_try_reap_events(struct io_ring_ctx *ctx) - } - } - mutex_unlock(&ctx->uring_lock); -+ percpu_ref_put(&ctx->refs); - } - - static int io_iopoll_check(struct io_ring_ctx *ctx, long min) -@@ -2800,12 +2802,7 @@ static __cold void io_ring_exit_work(struct work_struct *work) - init_completion(&exit.completion); - init_task_work(&exit.task_work, io_tctx_exit_cb); - exit.ctx = ctx; -- /* -- * Some may use context even when all refs and requests have been put, -- * and they are free to do so while still holding uring_lock or -- * completion_lock, see io_req_task_submit(). Apart from other work, -- * this lock/unlock section also waits them to finish. -- */ -+ - mutex_lock(&ctx->uring_lock); - while (!list_empty(&ctx->tctx_list)) { - WARN_ON_ONCE(time_after(jiffies, timeout)); -diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h -index d60c758326b42..acaf8dad05401 100644 ---- a/io_uring/rsrc.h -+++ b/io_uring/rsrc.h -@@ -79,17 +79,10 @@ int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, - - int __io_scm_file_account(struct io_ring_ctx *ctx, struct file *file); - --#if defined(CONFIG_UNIX) --static inline bool io_file_need_scm(struct file *filp) --{ -- return !!unix_get_socket(filp); --} --#else - static inline bool io_file_need_scm(struct file *filp) - { - return false; - } --#endif - - static inline int io_scm_file_account(struct io_ring_ctx *ctx, - struct file *file) -diff --git a/kernel/cgroup/legacy_freezer.c b/kernel/cgroup/legacy_freezer.c -index 122dacb3a4439..66d1708042a72 100644 ---- a/kernel/cgroup/legacy_freezer.c -+++ b/kernel/cgroup/legacy_freezer.c -@@ -66,9 +66,15 @@ static struct freezer *parent_freezer(struct freezer *freezer) - bool cgroup_freezing(struct task_struct *task) - { - bool ret; -+ unsigned int state; - - rcu_read_lock(); -- ret = task_freezer(task)->state & CGROUP_FREEZING; -+ /* Check if the cgroup is still FREEZING, but not FROZEN. The extra -+ * !FROZEN check is required, because the FREEZING bit is not cleared -+ * when the state FROZEN is reached. -+ */ -+ state = task_freezer(task)->state; -+ ret = (state & CGROUP_FREEZING) && !(state & CGROUP_FROZEN); - rcu_read_unlock(); - - return ret; -diff --git a/kernel/cpu.c b/kernel/cpu.c -index 0e4d362e90825..551468d9c5a85 100644 ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -1733,7 +1733,7 @@ static struct cpuhp_step cpuhp_hp_states[] = { - [CPUHP_HRTIMERS_PREPARE] = { - .name = "hrtimers:prepare", - .startup.single = hrtimers_prepare_cpu, -- .teardown.single = hrtimers_dead_cpu, -+ .teardown.single = NULL, - }, - [CPUHP_SMPCFD_PREPARE] = { - .name = "smpcfd:prepare", -@@ -1800,6 +1800,12 @@ static struct cpuhp_step cpuhp_hp_states[] = { - .startup.single = NULL, - .teardown.single = smpcfd_dying_cpu, - }, -+ [CPUHP_AP_HRTIMERS_DYING] = { -+ .name = "hrtimers:dying", -+ .startup.single = NULL, -+ .teardown.single = hrtimers_cpu_dying, -+ }, -+ - /* Entry state on starting. Interrupts enabled from here on. Transient - * state for synchronsization */ - [CPUHP_AP_ONLINE] = { -diff --git a/kernel/events/core.c b/kernel/events/core.c -index 8f2b9d8b9150e..0193243f65e5c 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -1812,31 +1812,34 @@ static inline void perf_event__state_init(struct perf_event *event) - PERF_EVENT_STATE_INACTIVE; - } - --static void __perf_event_read_size(struct perf_event *event, int nr_siblings) -+static int __perf_event_read_size(u64 read_format, int nr_siblings) - { - int entry = sizeof(u64); /* value */ - int size = 0; - int nr = 1; - -- if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) -+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) - size += sizeof(u64); - -- if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) -+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) - size += sizeof(u64); - -- if (event->attr.read_format & PERF_FORMAT_ID) -+ if (read_format & PERF_FORMAT_ID) - entry += sizeof(u64); - -- if (event->attr.read_format & PERF_FORMAT_LOST) -+ if (read_format & PERF_FORMAT_LOST) - entry += sizeof(u64); - -- if (event->attr.read_format & PERF_FORMAT_GROUP) { -+ if (read_format & PERF_FORMAT_GROUP) { - nr += nr_siblings; - size += sizeof(u64); - } - -- size += entry * nr; -- event->read_size = size; -+ /* -+ * Since perf_event_validate_size() limits this to 16k and inhibits -+ * adding more siblings, this will never overflow. -+ */ -+ return size + nr * entry; - } - - static void __perf_event_header_size(struct perf_event *event, u64 sample_type) -@@ -1886,8 +1889,9 @@ static void __perf_event_header_size(struct perf_event *event, u64 sample_type) - */ - static void perf_event__header_size(struct perf_event *event) - { -- __perf_event_read_size(event, -- event->group_leader->nr_siblings); -+ event->read_size = -+ __perf_event_read_size(event->attr.read_format, -+ event->group_leader->nr_siblings); - __perf_event_header_size(event, event->attr.sample_type); - } - -@@ -1918,24 +1922,35 @@ static void perf_event__id_header_size(struct perf_event *event) - event->id_header_size = size; - } - -+/* -+ * Check that adding an event to the group does not result in anybody -+ * overflowing the 64k event limit imposed by the output buffer. -+ * -+ * Specifically, check that the read_size for the event does not exceed 16k, -+ * read_size being the one term that grows with groups size. Since read_size -+ * depends on per-event read_format, also (re)check the existing events. -+ * -+ * This leaves 48k for the constant size fields and things like callchains, -+ * branch stacks and register sets. -+ */ - static bool perf_event_validate_size(struct perf_event *event) - { -- /* -- * The values computed here will be over-written when we actually -- * attach the event. -- */ -- __perf_event_read_size(event, event->group_leader->nr_siblings + 1); -- __perf_event_header_size(event, event->attr.sample_type & ~PERF_SAMPLE_READ); -- perf_event__id_header_size(event); -+ struct perf_event *sibling, *group_leader = event->group_leader; - -- /* -- * Sum the lot; should not exceed the 64k limit we have on records. -- * Conservative limit to allow for callchains and other variable fields. -- */ -- if (event->read_size + event->header_size + -- event->id_header_size + sizeof(struct perf_event_header) >= 16*1024) -+ if (__perf_event_read_size(event->attr.read_format, -+ group_leader->nr_siblings + 1) > 16*1024) - return false; - -+ if (__perf_event_read_size(group_leader->attr.read_format, -+ group_leader->nr_siblings + 1) > 16*1024) -+ return false; -+ -+ for_each_sibling_event(sibling, group_leader) { -+ if (__perf_event_read_size(sibling->attr.read_format, -+ group_leader->nr_siblings + 1) > 16*1024) -+ return false; -+ } -+ - return true; - } - -diff --git a/kernel/kprobes.c b/kernel/kprobes.c -index 3da9726232ff9..dbfddfa86c14e 100644 ---- a/kernel/kprobes.c -+++ b/kernel/kprobes.c -@@ -2253,7 +2253,7 @@ int register_kretprobe(struct kretprobe *rp) - if (!rp->rph) - return -ENOMEM; - -- rp->rph->rp = rp; -+ rcu_assign_pointer(rp->rph->rp, rp); - for (i = 0; i < rp->maxactive; i++) { - inst = kzalloc(sizeof(struct kretprobe_instance) + - rp->data_size, GFP_KERNEL); -@@ -2314,7 +2314,7 @@ void unregister_kretprobes(struct kretprobe **rps, int num) - #ifdef CONFIG_KRETPROBE_ON_RETHOOK - rethook_free(rps[i]->rh); - #else -- rps[i]->rph->rp = NULL; -+ rcu_assign_pointer(rps[i]->rph->rp, NULL); - #endif - } - mutex_unlock(&kprobe_mutex); -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index e4f0e3b0c4f4f..5561dabc9b225 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -2216,29 +2216,22 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, - } - } - --int hrtimers_dead_cpu(unsigned int scpu) -+int hrtimers_cpu_dying(unsigned int dying_cpu) - { - struct hrtimer_cpu_base *old_base, *new_base; -- int i; -+ int i, ncpu = cpumask_first(cpu_active_mask); - -- BUG_ON(cpu_online(scpu)); -- tick_cancel_sched_timer(scpu); -+ tick_cancel_sched_timer(dying_cpu); -+ -+ old_base = this_cpu_ptr(&hrtimer_bases); -+ new_base = &per_cpu(hrtimer_bases, ncpu); - -- /* -- * this BH disable ensures that raise_softirq_irqoff() does -- * not wakeup ksoftirqd (and acquire the pi-lock) while -- * holding the cpu_base lock -- */ -- local_bh_disable(); -- local_irq_disable(); -- old_base = &per_cpu(hrtimer_bases, scpu); -- new_base = this_cpu_ptr(&hrtimer_bases); - /* - * The caller is globally serialized and nobody else - * takes two locks at once, deadlock is not possible. - */ -- raw_spin_lock(&new_base->lock); -- raw_spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); -+ raw_spin_lock(&old_base->lock); -+ raw_spin_lock_nested(&new_base->lock, SINGLE_DEPTH_NESTING); - - for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { - migrate_hrtimer_list(&old_base->clock_base[i], -@@ -2249,15 +2242,13 @@ int hrtimers_dead_cpu(unsigned int scpu) - * The migration might have changed the first expiring softirq - * timer on this CPU. Update it. - */ -- hrtimer_update_softirq_timer(new_base, false); -+ __hrtimer_get_next_event(new_base, HRTIMER_ACTIVE_SOFT); -+ /* Tell the other CPU to retrigger the next event */ -+ smp_call_function_single(ncpu, retrigger_next_event, NULL, 0); - -- raw_spin_unlock(&old_base->lock); - raw_spin_unlock(&new_base->lock); -+ raw_spin_unlock(&old_base->lock); - -- /* Check, if we got expired work to do */ -- __hrtimer_peek_ahead_timers(); -- local_irq_enable(); -- local_bh_enable(); - return 0; - } - -diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c -index 468006cce7cae..3686626b52c57 100644 ---- a/kernel/trace/rethook.c -+++ b/kernel/trace/rethook.c -@@ -63,7 +63,7 @@ static void rethook_free_rcu(struct rcu_head *head) - */ - void rethook_stop(struct rethook *rh) - { -- WRITE_ONCE(rh->handler, NULL); -+ rcu_assign_pointer(rh->handler, NULL); - } - - /** -@@ -78,11 +78,17 @@ void rethook_stop(struct rethook *rh) - */ - void rethook_free(struct rethook *rh) - { -- WRITE_ONCE(rh->handler, NULL); -+ rethook_stop(rh); - - call_rcu(&rh->rcu, rethook_free_rcu); - } - -+static inline rethook_handler_t rethook_get_handler(struct rethook *rh) -+{ -+ return (rethook_handler_t)rcu_dereference_check(rh->handler, -+ rcu_read_lock_any_held()); -+} -+ - /** - * rethook_alloc() - Allocate struct rethook. - * @data: a data to pass the @handler when hooking the return. -@@ -102,7 +108,7 @@ struct rethook *rethook_alloc(void *data, rethook_handler_t handler) - } - - rh->data = data; -- rh->handler = handler; -+ rcu_assign_pointer(rh->handler, handler); - rh->pool.head = NULL; - refcount_set(&rh->ref, 1); - -@@ -142,9 +148,10 @@ static void free_rethook_node_rcu(struct rcu_head *head) - */ - void rethook_recycle(struct rethook_node *node) - { -- lockdep_assert_preemption_disabled(); -+ rethook_handler_t handler; - -- if (likely(READ_ONCE(node->rethook->handler))) -+ handler = rethook_get_handler(node->rethook); -+ if (likely(handler)) - freelist_add(&node->freelist, &node->rethook->pool); - else - call_rcu(&node->rcu, free_rethook_node_rcu); -@@ -160,11 +167,9 @@ NOKPROBE_SYMBOL(rethook_recycle); - */ - struct rethook_node *rethook_try_get(struct rethook *rh) - { -- rethook_handler_t handler = READ_ONCE(rh->handler); -+ rethook_handler_t handler = rethook_get_handler(rh); - struct freelist_node *fn; - -- lockdep_assert_preemption_disabled(); -- - /* Check whether @rh is going to be freed. */ - if (unlikely(!handler)) - return NULL; -@@ -312,7 +317,7 @@ unsigned long rethook_trampoline_handler(struct pt_regs *regs, - rhn = container_of(first, struct rethook_node, llist); - if (WARN_ON_ONCE(rhn->frame != frame)) - break; -- handler = READ_ONCE(rhn->rethook->handler); -+ handler = rethook_get_handler(rhn->rethook); - if (handler) - handler(rhn, rhn->rethook->data, regs); - -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index b7383358c4ea1..c02a4cb879913 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -646,8 +646,8 @@ static inline bool __rb_time_read(rb_time_t *t, u64 *ret, unsigned long *cnt) - - *cnt = rb_time_cnt(top); - -- /* If top and bottom counts don't match, this interrupted a write */ -- if (*cnt != rb_time_cnt(bottom)) -+ /* If top and msb counts don't match, this interrupted a write */ -+ if (*cnt != rb_time_cnt(msb)) - return false; - - /* The shift to msb will lose its cnt bits */ -@@ -3025,22 +3025,19 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, - local_read(&bpage->write) & ~RB_WRITE_MASK; - unsigned long event_length = rb_event_length(event); - -+ /* -+ * For the before_stamp to be different than the write_stamp -+ * to make sure that the next event adds an absolute -+ * value and does not rely on the saved write stamp, which -+ * is now going to be bogus. -+ */ -+ rb_time_set(&cpu_buffer->before_stamp, 0); -+ - /* Something came in, can't discard */ - if (!rb_time_cmpxchg(&cpu_buffer->write_stamp, - write_stamp, write_stamp - delta)) - return 0; - -- /* -- * It's possible that the event time delta is zero -- * (has the same time stamp as the previous event) -- * in which case write_stamp and before_stamp could -- * be the same. In such a case, force before_stamp -- * to be different than write_stamp. It doesn't -- * matter what it is, as long as its different. -- */ -- if (!delta) -- rb_time_set(&cpu_buffer->before_stamp, 0); -- - /* - * If an event were to come in now, it would see that the - * write_stamp and the before_stamp are different, and assume -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index ddcfc78e93e00..d2db4d6f0f2fd 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -2297,13 +2297,7 @@ int is_tracing_stopped(void) - return global_trace.stop_count; - } - --/** -- * tracing_start - quick start of the tracer -- * -- * If tracing is enabled but was stopped by tracing_stop, -- * this will start the tracer back up. -- */ --void tracing_start(void) -+static void tracing_start_tr(struct trace_array *tr) - { - struct trace_buffer *buffer; - unsigned long flags; -@@ -2311,119 +2305,83 @@ void tracing_start(void) - if (tracing_disabled) - return; - -- raw_spin_lock_irqsave(&global_trace.start_lock, flags); -- if (--global_trace.stop_count) { -- if (global_trace.stop_count < 0) { -+ raw_spin_lock_irqsave(&tr->start_lock, flags); -+ if (--tr->stop_count) { -+ if (WARN_ON_ONCE(tr->stop_count < 0)) { - /* Someone screwed up their debugging */ -- WARN_ON_ONCE(1); -- global_trace.stop_count = 0; -+ tr->stop_count = 0; - } - goto out; - } - - /* Prevent the buffers from switching */ -- arch_spin_lock(&global_trace.max_lock); -+ arch_spin_lock(&tr->max_lock); - -- buffer = global_trace.array_buffer.buffer; -+ buffer = tr->array_buffer.buffer; - if (buffer) - ring_buffer_record_enable(buffer); - - #ifdef CONFIG_TRACER_MAX_TRACE -- buffer = global_trace.max_buffer.buffer; -+ buffer = tr->max_buffer.buffer; - if (buffer) - ring_buffer_record_enable(buffer); - #endif - -- arch_spin_unlock(&global_trace.max_lock); -- -- out: -- raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); --} -- --static void tracing_start_tr(struct trace_array *tr) --{ -- struct trace_buffer *buffer; -- unsigned long flags; -- -- if (tracing_disabled) -- return; -- -- /* If global, we need to also start the max tracer */ -- if (tr->flags & TRACE_ARRAY_FL_GLOBAL) -- return tracing_start(); -- -- raw_spin_lock_irqsave(&tr->start_lock, flags); -- -- if (--tr->stop_count) { -- if (tr->stop_count < 0) { -- /* Someone screwed up their debugging */ -- WARN_ON_ONCE(1); -- tr->stop_count = 0; -- } -- goto out; -- } -- -- buffer = tr->array_buffer.buffer; -- if (buffer) -- ring_buffer_record_enable(buffer); -+ arch_spin_unlock(&tr->max_lock); - - out: - raw_spin_unlock_irqrestore(&tr->start_lock, flags); - } - - /** -- * tracing_stop - quick stop of the tracer -+ * tracing_start - quick start of the tracer - * -- * Light weight way to stop tracing. Use in conjunction with -- * tracing_start. -+ * If tracing is enabled but was stopped by tracing_stop, -+ * this will start the tracer back up. - */ --void tracing_stop(void) -+void tracing_start(void) -+ -+{ -+ return tracing_start_tr(&global_trace); -+} -+ -+static void tracing_stop_tr(struct trace_array *tr) - { - struct trace_buffer *buffer; - unsigned long flags; - -- raw_spin_lock_irqsave(&global_trace.start_lock, flags); -- if (global_trace.stop_count++) -+ raw_spin_lock_irqsave(&tr->start_lock, flags); -+ if (tr->stop_count++) - goto out; - - /* Prevent the buffers from switching */ -- arch_spin_lock(&global_trace.max_lock); -+ arch_spin_lock(&tr->max_lock); - -- buffer = global_trace.array_buffer.buffer; -+ buffer = tr->array_buffer.buffer; - if (buffer) - ring_buffer_record_disable(buffer); - - #ifdef CONFIG_TRACER_MAX_TRACE -- buffer = global_trace.max_buffer.buffer; -+ buffer = tr->max_buffer.buffer; - if (buffer) - ring_buffer_record_disable(buffer); - #endif - -- arch_spin_unlock(&global_trace.max_lock); -+ arch_spin_unlock(&tr->max_lock); - - out: -- raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); -+ raw_spin_unlock_irqrestore(&tr->start_lock, flags); - } - --static void tracing_stop_tr(struct trace_array *tr) -+/** -+ * tracing_stop - quick stop of the tracer -+ * -+ * Light weight way to stop tracing. Use in conjunction with -+ * tracing_start. -+ */ -+void tracing_stop(void) - { -- struct trace_buffer *buffer; -- unsigned long flags; -- -- /* If global, we need to also stop the max tracer */ -- if (tr->flags & TRACE_ARRAY_FL_GLOBAL) -- return tracing_stop(); -- -- raw_spin_lock_irqsave(&tr->start_lock, flags); -- if (tr->stop_count++) -- goto out; -- -- buffer = tr->array_buffer.buffer; -- if (buffer) -- ring_buffer_record_disable(buffer); -- -- out: -- raw_spin_unlock_irqrestore(&tr->start_lock, flags); -+ return tracing_stop_tr(&global_trace); - } - - static int trace_save_cmdline(struct task_struct *tsk) -@@ -2707,8 +2665,11 @@ void trace_buffered_event_enable(void) - for_each_tracing_cpu(cpu) { - page = alloc_pages_node(cpu_to_node(cpu), - GFP_KERNEL | __GFP_NORETRY, 0); -- if (!page) -- goto failed; -+ /* This is just an optimization and can handle failures */ -+ if (!page) { -+ pr_err("Failed to allocate event buffer\n"); -+ break; -+ } - - event = page_address(page); - memset(event, 0, sizeof(*event)); -@@ -2722,10 +2683,6 @@ void trace_buffered_event_enable(void) - WARN_ON_ONCE(1); - preempt_enable(); - } -- -- return; -- failed: -- trace_buffered_event_disable(); - } - - static void enable_trace_buffered_event(void *data) -@@ -2760,11 +2717,9 @@ void trace_buffered_event_disable(void) - if (--trace_buffered_event_ref) - return; - -- preempt_disable(); - /* For each CPU, set the buffer as used. */ -- smp_call_function_many(tracing_buffer_mask, -- disable_trace_buffered_event, NULL, 1); -- preempt_enable(); -+ on_each_cpu_mask(tracing_buffer_mask, disable_trace_buffered_event, -+ NULL, true); - - /* Wait for all current users to finish */ - synchronize_rcu(); -@@ -2773,17 +2728,19 @@ void trace_buffered_event_disable(void) - free_page((unsigned long)per_cpu(trace_buffered_event, cpu)); - per_cpu(trace_buffered_event, cpu) = NULL; - } -+ - /* -- * Make sure trace_buffered_event is NULL before clearing -- * trace_buffered_event_cnt. -+ * Wait for all CPUs that potentially started checking if they can use -+ * their event buffer only after the previous synchronize_rcu() call and -+ * they still read a valid pointer from trace_buffered_event. It must be -+ * ensured they don't see cleared trace_buffered_event_cnt else they -+ * could wrongly decide to use the pointed-to buffer which is now freed. - */ -- smp_wmb(); -+ synchronize_rcu(); - -- preempt_disable(); -- /* Do the work on each cpu */ -- smp_call_function_many(tracing_buffer_mask, -- enable_trace_buffered_event, NULL, 1); -- preempt_enable(); -+ /* For each CPU, relinquish the buffer */ -+ on_each_cpu_mask(tracing_buffer_mask, enable_trace_buffered_event, NULL, -+ true); - } - - static struct trace_buffer *temp_buffer; -@@ -6258,6 +6215,15 @@ static void set_buffer_entries(struct array_buffer *buf, unsigned long val) - per_cpu_ptr(buf->data, cpu)->entries = val; - } - -+static void update_buffer_entries(struct array_buffer *buf, int cpu) -+{ -+ if (cpu == RING_BUFFER_ALL_CPUS) { -+ set_buffer_entries(buf, ring_buffer_size(buf->buffer, 0)); -+ } else { -+ per_cpu_ptr(buf->data, cpu)->entries = ring_buffer_size(buf->buffer, cpu); -+ } -+} -+ - #ifdef CONFIG_TRACER_MAX_TRACE - /* resize @tr's buffer to the size of @size_tr's entries */ - static int resize_buffer_duplicate_size(struct array_buffer *trace_buf, -@@ -6302,13 +6268,15 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, - if (!tr->array_buffer.buffer) - return 0; - -+ /* Do not allow tracing while resizng ring buffer */ -+ tracing_stop_tr(tr); -+ - ret = ring_buffer_resize(tr->array_buffer.buffer, size, cpu); - if (ret < 0) -- return ret; -+ goto out_start; - - #ifdef CONFIG_TRACER_MAX_TRACE -- if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL) || -- !tr->current_trace->use_max_tr) -+ if (!tr->current_trace->use_max_tr) - goto out; - - ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu); -@@ -6333,22 +6301,17 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, - WARN_ON(1); - tracing_disabled = 1; - } -- return ret; -+ goto out_start; - } - -- if (cpu == RING_BUFFER_ALL_CPUS) -- set_buffer_entries(&tr->max_buffer, size); -- else -- per_cpu_ptr(tr->max_buffer.data, cpu)->entries = size; -+ update_buffer_entries(&tr->max_buffer, cpu); - - out: - #endif /* CONFIG_TRACER_MAX_TRACE */ - -- if (cpu == RING_BUFFER_ALL_CPUS) -- set_buffer_entries(&tr->array_buffer, size); -- else -- per_cpu_ptr(tr->array_buffer.data, cpu)->entries = size; -- -+ update_buffer_entries(&tr->array_buffer, cpu); -+ out_start: -+ tracing_start_tr(tr); - return ret; - } - -diff --git a/lib/zstd/common/fse_decompress.c b/lib/zstd/common/fse_decompress.c -index 2c8bbe3e4c148..f37b7aec088ec 100644 ---- a/lib/zstd/common/fse_decompress.c -+++ b/lib/zstd/common/fse_decompress.c -@@ -312,7 +312,7 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size - - typedef struct { - short ncount[FSE_MAX_SYMBOL_VALUE + 1]; -- FSE_DTable dtable[1]; /* Dynamically sized */ -+ FSE_DTable dtable[]; /* Dynamically sized */ - } FSE_DecompressWksp; - - -diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c -index dbf5e4de97a0f..9ea21b6d266be 100644 ---- a/mm/damon/sysfs.c -+++ b/mm/damon/sysfs.c -@@ -2210,7 +2210,7 @@ static int damon_sysfs_update_target(struct damon_target *target, - struct damon_ctx *ctx, - struct damon_sysfs_target *sys_target) - { -- int err; -+ int err = 0; - - if (damon_target_has_pid(ctx)) { - err = damon_sysfs_update_target_pid(target, sys_target->pid); -diff --git a/mm/filemap.c b/mm/filemap.c -index 2d930470aacaa..d633ab8cd56f1 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -3319,7 +3319,7 @@ static bool filemap_map_pmd(struct vm_fault *vmf, struct page *page) - } - } - -- if (pmd_none(*vmf->pmd)) -+ if (pmd_none(*vmf->pmd) && vmf->prealloc_pte) - pmd_install(mm, vmf->pmd, &vmf->prealloc_pte); - - /* See comment in handle_pte_fault() */ -diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index aa4a68dfb3b92..37288a7f0fa65 100644 ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -1189,6 +1189,13 @@ static int is_vma_resv_set(struct vm_area_struct *vma, unsigned long flag) - return (get_vma_private_data(vma) & flag) != 0; - } - -+bool __vma_private_lock(struct vm_area_struct *vma) -+{ -+ return !(vma->vm_flags & VM_MAYSHARE) && -+ get_vma_private_data(vma) & ~HPAGE_RESV_MASK && -+ is_vma_resv_set(vma, HPAGE_RESV_OWNER); -+} -+ - void hugetlb_dup_vma_private(struct vm_area_struct *vma) - { - VM_BUG_ON_VMA(!is_vm_hugetlb_page(vma), vma); -diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c -index f084a4a6b7ab2..8e0a90b45df22 100644 ---- a/net/core/drop_monitor.c -+++ b/net/core/drop_monitor.c -@@ -181,7 +181,7 @@ out: - } - - static const struct genl_multicast_group dropmon_mcgrps[] = { -- { .name = "events", }, -+ { .name = "events", .cap_sys_admin = 1 }, - }; - - static void send_dm_alert(struct work_struct *work) -@@ -1604,11 +1604,13 @@ static const struct genl_small_ops dropmon_ops[] = { - .cmd = NET_DM_CMD_START, - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = net_dm_cmd_trace, -+ .flags = GENL_ADMIN_PERM, - }, - { - .cmd = NET_DM_CMD_STOP, - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = net_dm_cmd_trace, -+ .flags = GENL_ADMIN_PERM, - }, - { - .cmd = NET_DM_CMD_CONFIG_GET, -diff --git a/net/core/filter.c b/net/core/filter.c -index adc327f4af1e9..3a6110ea4009f 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -2582,6 +2582,22 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes) - return 0; - } - -+static void sk_msg_reset_curr(struct sk_msg *msg) -+{ -+ u32 i = msg->sg.start; -+ u32 len = 0; -+ -+ do { -+ len += sk_msg_elem(msg, i)->length; -+ sk_msg_iter_var_next(i); -+ if (len >= msg->sg.size) -+ break; -+ } while (i != msg->sg.end); -+ -+ msg->sg.curr = i; -+ msg->sg.copybreak = 0; -+} -+ - static const struct bpf_func_proto bpf_msg_cork_bytes_proto = { - .func = bpf_msg_cork_bytes, - .gpl_only = false, -@@ -2701,6 +2717,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start, - msg->sg.end - shift + NR_MSG_FRAG_IDS : - msg->sg.end - shift; - out: -+ sk_msg_reset_curr(msg); - msg->data = sg_virt(&msg->sg.data[first_sge]) + start - offset; - msg->data_end = msg->data + bytes; - return 0; -@@ -2837,6 +2854,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start, - msg->sg.data[new] = rsge; - } - -+ sk_msg_reset_curr(msg); - sk_msg_compute_data_pointers(msg); - return 0; - } -@@ -3005,6 +3023,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, - - sk_mem_uncharge(msg->sk, len - pop); - msg->sg.size -= (len - pop); -+ sk_msg_reset_curr(msg); - sk_msg_compute_data_pointers(msg); - return 0; - } -diff --git a/net/core/scm.c b/net/core/scm.c -index acb7d776fa6ec..e762a4b8a1d22 100644 ---- a/net/core/scm.c -+++ b/net/core/scm.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #include - -@@ -103,6 +104,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) - - if (fd < 0 || !(file = fget_raw(fd))) - return -EBADF; -+ /* don't allow io_uring files */ -+ if (io_uring_get_socket(file)) { -+ fput(file); -+ return -EINVAL; -+ } - *fpp++ = file; - fpl->count++; - } -diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c -index 5b8242265617d..d67d026d7f975 100644 ---- a/net/ipv4/ip_gre.c -+++ b/net/ipv4/ip_gre.c -@@ -634,15 +634,18 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, - } - - if (dev->header_ops) { -+ int pull_len = tunnel->hlen + sizeof(struct iphdr); -+ - if (skb_cow_head(skb, 0)) - goto free_skb; - - tnl_params = (const struct iphdr *)skb->data; - -- /* Pull skb since ip_tunnel_xmit() needs skb->data pointing -- * to gre header. -- */ -- skb_pull(skb, tunnel->hlen + sizeof(struct iphdr)); -+ if (!pskb_network_may_pull(skb, pull_len)) -+ goto free_skb; -+ -+ /* ip_tunnel_xmit() needs skb->data pointing to gre header. */ -+ skb_pull(skb, pull_len); - skb_reset_mac_header(skb); - - if (skb->ip_summed == CHECKSUM_PARTIAL && -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 288678f17ccaf..58409ea2da0af 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -3473,9 +3473,25 @@ int tcp_set_window_clamp(struct sock *sk, int val) - return -EINVAL; - tp->window_clamp = 0; - } else { -- tp->window_clamp = val < SOCK_MIN_RCVBUF / 2 ? -- SOCK_MIN_RCVBUF / 2 : val; -- tp->rcv_ssthresh = min(tp->rcv_wnd, tp->window_clamp); -+ u32 new_rcv_ssthresh, old_window_clamp = tp->window_clamp; -+ u32 new_window_clamp = val < SOCK_MIN_RCVBUF / 2 ? -+ SOCK_MIN_RCVBUF / 2 : val; -+ -+ if (new_window_clamp == old_window_clamp) -+ return 0; -+ -+ tp->window_clamp = new_window_clamp; -+ if (new_window_clamp < old_window_clamp) { -+ /* need to apply the reserved mem provisioning only -+ * when shrinking the window clamp -+ */ -+ __tcp_adjust_rcv_ssthresh(sk, tp->window_clamp); -+ -+ } else { -+ new_rcv_ssthresh = min(tp->rcv_wnd, tp->window_clamp); -+ tp->rcv_ssthresh = max(new_rcv_ssthresh, -+ tp->rcv_ssthresh); -+ } - } - return 0; - } -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index 65dae3d43684f..34460c9b37ae2 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -3803,8 +3803,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) - * then we can probably ignore it. - */ - if (before(ack, prior_snd_una)) { -+ u32 max_window; -+ -+ /* do not accept ACK for bytes we never sent. */ -+ max_window = min_t(u64, tp->max_window, tp->bytes_acked); - /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */ -- if (before(ack, prior_snd_una - tp->max_window)) { -+ if (before(ack, prior_snd_una - max_window)) { - if (!(flag & FLAG_NO_CHALLENGE_ACK)) - tcp_send_challenge_ack(sk); - return -SKB_DROP_REASON_TCP_TOO_OLD_ACK; -diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c -index eb6640f9a7921..1840735e9cb07 100644 ---- a/net/ipv6/ip6_fib.c -+++ b/net/ipv6/ip6_fib.c -@@ -1502,13 +1502,9 @@ out: - if (!pn_leaf && !(pn->fn_flags & RTN_RTINFO)) { - pn_leaf = fib6_find_prefix(info->nl_net, table, - pn); --#if RT6_DEBUG >= 2 -- if (!pn_leaf) { -- WARN_ON(!pn_leaf); -+ if (!pn_leaf) - pn_leaf = - info->nl_net->ipv6.fib6_null_entry; -- } --#endif - fib6_info_hold(pn_leaf); - rcu_assign_pointer(pn->leaf, pn_leaf); - } -diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c -index 20eede37d5228..d47dfdcb899b0 100644 ---- a/net/netfilter/ipset/ip_set_core.c -+++ b/net/netfilter/ipset/ip_set_core.c -@@ -61,6 +61,8 @@ MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); - ip_set_dereference((inst)->ip_set_list)[id] - #define ip_set_ref_netlink(inst,id) \ - rcu_dereference_raw((inst)->ip_set_list)[id] -+#define ip_set_dereference_nfnl(p) \ -+ rcu_dereference_check(p, lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET)) - - /* The set types are implemented in modules and registered set types - * can be found in ip_set_type_list. Adding/deleting types is -@@ -708,15 +710,10 @@ __ip_set_put_netlink(struct ip_set *set) - static struct ip_set * - ip_set_rcu_get(struct net *net, ip_set_id_t index) - { -- struct ip_set *set; - struct ip_set_net *inst = ip_set_pernet(net); - -- rcu_read_lock(); -- /* ip_set_list itself needs to be protected */ -- set = rcu_dereference(inst->ip_set_list)[index]; -- rcu_read_unlock(); -- -- return set; -+ /* ip_set_list and the set pointer need to be protected */ -+ return ip_set_dereference_nfnl(inst->ip_set_list)[index]; - } - - static inline void -@@ -1399,6 +1396,9 @@ static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info, - ip_set(inst, to_id) = from; - write_unlock_bh(&ip_set_ref_lock); - -+ /* Make sure all readers of the old set pointers are completed. */ -+ synchronize_rcu(); -+ - return 0; - } - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 421211eba838b..05fa5141af516 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -805,7 +805,7 @@ static struct nft_table *nft_table_lookup(const struct net *net, - - static struct nft_table *nft_table_lookup_byhandle(const struct net *net, - const struct nlattr *nla, -- u8 genmask, u32 nlpid) -+ int family, u8 genmask, u32 nlpid) - { - struct nftables_pernet *nft_net; - struct nft_table *table; -@@ -813,6 +813,7 @@ static struct nft_table *nft_table_lookup_byhandle(const struct net *net, - nft_net = nft_pernet(net); - list_for_each_entry(table, &nft_net->tables, list) { - if (be64_to_cpu(nla_get_be64(nla)) == table->handle && -+ table->family == family && - nft_active_genmask(table, genmask)) { - if (nft_table_has_owner(table) && - nlpid && table->nlpid != nlpid) -@@ -1537,7 +1538,7 @@ static int nf_tables_deltable(struct sk_buff *skb, const struct nfnl_info *info, - - if (nla[NFTA_TABLE_HANDLE]) { - attr = nla[NFTA_TABLE_HANDLE]; -- table = nft_table_lookup_byhandle(net, attr, genmask, -+ table = nft_table_lookup_byhandle(net, attr, family, genmask, - NETLINK_CB(skb).portid); - } else { - attr = nla[NFTA_TABLE_NAME]; -diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c -index cf9a1ae87d9b1..a470e5f612843 100644 ---- a/net/netfilter/nft_dynset.c -+++ b/net/netfilter/nft_dynset.c -@@ -279,10 +279,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx, - priv->expr_array[i] = dynset_expr; - priv->num_exprs++; - -- if (set->num_exprs && -- dynset_expr->ops != set->exprs[i]->ops) { -- err = -EOPNOTSUPP; -- goto err_expr_free; -+ if (set->num_exprs) { -+ if (i >= set->num_exprs) { -+ err = -EINVAL; -+ goto err_expr_free; -+ } -+ if (dynset_expr->ops != set->exprs[i]->ops) { -+ err = -EOPNOTSUPP; -+ goto err_expr_free; -+ } - } - i++; - } -diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c -index efb50c2b41f32..de588f7b69c45 100644 ---- a/net/netfilter/nft_exthdr.c -+++ b/net/netfilter/nft_exthdr.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -214,7 +215,7 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr, - - offset = i + priv->offset; - if (priv->flags & NFT_EXTHDR_F_PRESENT) { -- *dest = 1; -+ nft_reg_store8(dest, 1); - } else { - if (priv->len % NFT_REG32_SIZE) - dest[priv->len / NFT_REG32_SIZE] = 0; -@@ -409,6 +410,82 @@ err: - regs->verdict.code = NFT_BREAK; - } - -+static void nft_exthdr_dccp_eval(const struct nft_expr *expr, -+ struct nft_regs *regs, -+ const struct nft_pktinfo *pkt) -+{ -+ struct nft_exthdr *priv = nft_expr_priv(expr); -+ unsigned int thoff, dataoff, optoff, optlen, i; -+ u32 *dest = ®s->data[priv->dreg]; -+ const struct dccp_hdr *dh; -+ struct dccp_hdr _dh; -+ -+ if (pkt->tprot != IPPROTO_DCCP || pkt->fragoff) -+ goto err; -+ -+ thoff = nft_thoff(pkt); -+ -+ dh = skb_header_pointer(pkt->skb, thoff, sizeof(_dh), &_dh); -+ if (!dh) -+ goto err; -+ -+ dataoff = dh->dccph_doff * sizeof(u32); -+ optoff = __dccp_hdr_len(dh); -+ if (dataoff <= optoff) -+ goto err; -+ -+ optlen = dataoff - optoff; -+ -+ for (i = 0; i < optlen; ) { -+ /* Options 0 (DCCPO_PADDING) - 31 (DCCPO_MAX_RESERVED) are 1B in -+ * the length; the remaining options are at least 2B long. In -+ * all cases, the first byte contains the option type. In -+ * multi-byte options, the second byte contains the option -+ * length, which must be at least two: 1 for the type plus 1 for -+ * the length plus 0-253 for any following option data. We -+ * aren't interested in the option data, only the type and the -+ * length, so we don't need to read more than two bytes at a -+ * time. -+ */ -+ unsigned int buflen = optlen - i; -+ u8 buf[2], *bufp; -+ u8 type, len; -+ -+ if (buflen > sizeof(buf)) -+ buflen = sizeof(buf); -+ -+ bufp = skb_header_pointer(pkt->skb, thoff + optoff + i, buflen, -+ &buf); -+ if (!bufp) -+ goto err; -+ -+ type = bufp[0]; -+ -+ if (type == priv->type) { -+ nft_reg_store8(dest, 1); -+ return; -+ } -+ -+ if (type <= DCCPO_MAX_RESERVED) { -+ i++; -+ continue; -+ } -+ -+ if (buflen < 2) -+ goto err; -+ -+ len = bufp[1]; -+ -+ if (len < 2) -+ goto err; -+ -+ i += len; -+ } -+ -+err: -+ *dest = 0; -+} -+ - static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = { - [NFTA_EXTHDR_DREG] = { .type = NLA_U32 }, - [NFTA_EXTHDR_TYPE] = { .type = NLA_U8 }, -@@ -560,6 +637,22 @@ static int nft_exthdr_ipv4_init(const struct nft_ctx *ctx, - return 0; - } - -+static int nft_exthdr_dccp_init(const struct nft_ctx *ctx, -+ const struct nft_expr *expr, -+ const struct nlattr * const tb[]) -+{ -+ struct nft_exthdr *priv = nft_expr_priv(expr); -+ int err = nft_exthdr_init(ctx, expr, tb); -+ -+ if (err < 0) -+ return err; -+ -+ if (!(priv->flags & NFT_EXTHDR_F_PRESENT)) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} -+ - static int nft_exthdr_dump_common(struct sk_buff *skb, const struct nft_exthdr *priv) - { - if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type)) -@@ -686,6 +779,15 @@ static const struct nft_expr_ops nft_exthdr_sctp_ops = { - .reduce = nft_exthdr_reduce, - }; - -+static const struct nft_expr_ops nft_exthdr_dccp_ops = { -+ .type = &nft_exthdr_type, -+ .size = NFT_EXPR_SIZE(sizeof(struct nft_exthdr)), -+ .eval = nft_exthdr_dccp_eval, -+ .init = nft_exthdr_dccp_init, -+ .dump = nft_exthdr_dump, -+ .reduce = nft_exthdr_reduce, -+}; -+ - static const struct nft_expr_ops * - nft_exthdr_select_ops(const struct nft_ctx *ctx, - const struct nlattr * const tb[]) -@@ -720,6 +822,10 @@ nft_exthdr_select_ops(const struct nft_ctx *ctx, - if (tb[NFTA_EXTHDR_DREG]) - return &nft_exthdr_sctp_ops; - break; -+ case NFT_EXTHDR_OP_DCCP: -+ if (tb[NFTA_EXTHDR_DREG]) -+ return &nft_exthdr_dccp_ops; -+ break; - } - - return ERR_PTR(-EOPNOTSUPP); -diff --git a/net/netfilter/nft_fib.c b/net/netfilter/nft_fib.c -index 1f12d7ade606c..5748415f74d0b 100644 ---- a/net/netfilter/nft_fib.c -+++ b/net/netfilter/nft_fib.c -@@ -144,11 +144,15 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv, - switch (priv->result) { - case NFT_FIB_RESULT_OIF: - index = dev ? dev->ifindex : 0; -- *dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index; -+ if (priv->flags & NFTA_FIB_F_PRESENT) -+ nft_reg_store8(dreg, !!index); -+ else -+ *dreg = index; -+ - break; - case NFT_FIB_RESULT_OIFNAME: - if (priv->flags & NFTA_FIB_F_PRESENT) -- *dreg = !!dev; -+ nft_reg_store8(dreg, !!dev); - else - strncpy(reg, dev ? dev->name : "", IFNAMSIZ); - break; -diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c -index deea6196d9925..4e1cc31729b80 100644 ---- a/net/netfilter/nft_set_pipapo.c -+++ b/net/netfilter/nft_set_pipapo.c -@@ -2042,6 +2042,9 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set, - - e = f->mt[r].e; - -+ if (!nft_set_elem_active(&e->ext, iter->genmask)) -+ goto cont; -+ - elem.priv = e; - - iter->err = iter->fn(ctx, set, iter, &elem); -diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c -index e85ce69924aee..50332888c8d23 100644 ---- a/net/netfilter/xt_owner.c -+++ b/net/netfilter/xt_owner.c -@@ -76,18 +76,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) - */ - return false; - -- filp = sk->sk_socket->file; -- if (filp == NULL) -+ read_lock_bh(&sk->sk_callback_lock); -+ filp = sk->sk_socket ? sk->sk_socket->file : NULL; -+ if (filp == NULL) { -+ read_unlock_bh(&sk->sk_callback_lock); - return ((info->match ^ info->invert) & - (XT_OWNER_UID | XT_OWNER_GID)) == 0; -+ } - - if (info->match & XT_OWNER_UID) { - kuid_t uid_min = make_kuid(net->user_ns, info->uid_min); - kuid_t uid_max = make_kuid(net->user_ns, info->uid_max); - if ((uid_gte(filp->f_cred->fsuid, uid_min) && - uid_lte(filp->f_cred->fsuid, uid_max)) ^ -- !(info->invert & XT_OWNER_UID)) -+ !(info->invert & XT_OWNER_UID)) { -+ read_unlock_bh(&sk->sk_callback_lock); - return false; -+ } - } - - if (info->match & XT_OWNER_GID) { -@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) - } - } - -- if (match ^ !(info->invert & XT_OWNER_GID)) -+ if (match ^ !(info->invert & XT_OWNER_GID)) { -+ read_unlock_bh(&sk->sk_callback_lock); - return false; -+ } - } - -+ read_unlock_bh(&sk->sk_callback_lock); - return true; - } - -diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c -index 3e16527beb914..505d3b910cc29 100644 ---- a/net/netlink/genetlink.c -+++ b/net/netlink/genetlink.c -@@ -1438,6 +1438,9 @@ static int genl_bind(struct net *net, int group) - if ((grp->flags & GENL_UNS_ADMIN_PERM) && - !ns_capable(net->user_ns, CAP_NET_ADMIN)) - ret = -EPERM; -+ if (grp->cap_sys_admin && -+ !ns_capable(net->user_ns, CAP_SYS_ADMIN)) -+ ret = -EPERM; - - break; - } -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 451bd8bfafd23..51882f07ef70c 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -4275,7 +4275,7 @@ static void packet_mm_open(struct vm_area_struct *vma) - struct sock *sk = sock->sk; - - if (sk) -- atomic_inc(&pkt_sk(sk)->mapped); -+ atomic_long_inc(&pkt_sk(sk)->mapped); - } - - static void packet_mm_close(struct vm_area_struct *vma) -@@ -4285,7 +4285,7 @@ static void packet_mm_close(struct vm_area_struct *vma) - struct sock *sk = sock->sk; - - if (sk) -- atomic_dec(&pkt_sk(sk)->mapped); -+ atomic_long_dec(&pkt_sk(sk)->mapped); - } - - static const struct vm_operations_struct packet_mmap_ops = { -@@ -4380,7 +4380,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, - - err = -EBUSY; - if (!closing) { -- if (atomic_read(&po->mapped)) -+ if (atomic_long_read(&po->mapped)) - goto out; - if (packet_read_pending(rb)) - goto out; -@@ -4483,7 +4483,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, - - err = -EBUSY; - mutex_lock(&po->pg_vec_lock); -- if (closing || atomic_read(&po->mapped) == 0) { -+ if (closing || atomic_long_read(&po->mapped) == 0) { - err = 0; - spin_lock_bh(&rb_queue->lock); - swap(rb->pg_vec, pg_vec); -@@ -4501,9 +4501,9 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, - po->prot_hook.func = (po->rx_ring.pg_vec) ? - tpacket_rcv : packet_rcv; - skb_queue_purge(rb_queue); -- if (atomic_read(&po->mapped)) -- pr_err("packet_mmap: vma is busy: %d\n", -- atomic_read(&po->mapped)); -+ if (atomic_long_read(&po->mapped)) -+ pr_err("packet_mmap: vma is busy: %ld\n", -+ atomic_long_read(&po->mapped)); - } - mutex_unlock(&po->pg_vec_lock); - -@@ -4581,7 +4581,7 @@ static int packet_mmap(struct file *file, struct socket *sock, - } - } - -- atomic_inc(&po->mapped); -+ atomic_long_inc(&po->mapped); - vma->vm_ops = &packet_mmap_ops; - err = 0; - -diff --git a/net/packet/internal.h b/net/packet/internal.h -index 3bae8ea7a36f5..b2edfe6fc8e77 100644 ---- a/net/packet/internal.h -+++ b/net/packet/internal.h -@@ -126,7 +126,7 @@ struct packet_sock { - __be16 num; - struct packet_rollover *rollover; - struct packet_mclist *mclist; -- atomic_t mapped; -+ atomic_long_t mapped; - enum tpacket_versions tp_version; - unsigned int tp_hdrlen; - unsigned int tp_reserve; -diff --git a/net/psample/psample.c b/net/psample/psample.c -index 81a794e36f535..c34e902855dbe 100644 ---- a/net/psample/psample.c -+++ b/net/psample/psample.c -@@ -31,7 +31,8 @@ enum psample_nl_multicast_groups { - - static const struct genl_multicast_group psample_nl_mcgrps[] = { - [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, -- [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, -+ [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME, -+ .flags = GENL_UNS_ADMIN_PERM }, - }; - - static struct genl_family psample_nl_family __ro_after_init; -diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c -index f7592638e61d3..5c8e02d56fd43 100644 ---- a/net/xdp/xsk.c -+++ b/net/xdp/xsk.c -@@ -722,7 +722,7 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock, - - rcu_read_lock(); - if (xsk_check_common(xs)) -- goto skip_tx; -+ goto out; - - pool = xs->pool; - -@@ -734,12 +734,11 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock, - xsk_generic_xmit(sk); - } - --skip_tx: - if (xs->rx && !xskq_prod_is_empty(xs->rx)) - mask |= EPOLLIN | EPOLLRDNORM; - if (xs->tx && xsk_tx_writeable(xs)) - mask |= EPOLLOUT | EPOLLWRNORM; -- -+out: - rcu_read_unlock(); - return mask; - } -diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl -index d48dfed6d3dba..a0f9101d5fd44 100755 ---- a/scripts/checkstack.pl -+++ b/scripts/checkstack.pl -@@ -146,15 +146,11 @@ $total_size = 0; - while (my $line = ) { - if ($line =~ m/$funcre/) { - $func = $1; -- next if $line !~ m/^($xs*)/; -+ next if $line !~ m/^($x*)/; - if ($total_size > $min_stack) { - push @stack, "$intro$total_size\n"; - } -- -- $addr = $1; -- $addr =~ s/ /0/g; -- $addr = "0x$addr"; -- -+ $addr = "0x$1"; - $intro = "$addr $func [$file]:"; - my $padlen = 56 - length($intro); - while ($padlen > 0) { -diff --git a/scripts/dtc/dt-extract-compatibles b/scripts/dtc/dt-extract-compatibles -index a1119762ed086..9686a1cf85498 100755 ---- a/scripts/dtc/dt-extract-compatibles -+++ b/scripts/dtc/dt-extract-compatibles -@@ -1,8 +1,8 @@ - #!/usr/bin/env python3 - # SPDX-License-Identifier: GPL-2.0-only - -+import fnmatch - import os --import glob - import re - import argparse - -@@ -49,6 +49,24 @@ def print_compat(filename, compatibles): - else: - print(*compatibles, sep='\n') - -+def glob_without_symlinks(root, glob): -+ for path, dirs, files in os.walk(root): -+ # Ignore hidden directories -+ for d in dirs: -+ if fnmatch.fnmatch(d, ".*"): -+ dirs.remove(d) -+ for f in files: -+ if fnmatch.fnmatch(f, glob): -+ yield os.path.join(path, f) -+ -+def files_to_parse(path_args): -+ for f in path_args: -+ if os.path.isdir(f): -+ for filename in glob_without_symlinks(f, "*.c"): -+ yield filename -+ else: -+ yield f -+ - show_filename = False - - if __name__ == "__main__": -@@ -59,11 +77,6 @@ if __name__ == "__main__": - - show_filename = args.with_filename - -- for f in args.cfile: -- if os.path.isdir(f): -- for filename in glob.iglob(f + "/**/*.c", recursive=True): -- compat_list = parse_compatibles(filename) -- print_compat(filename, compat_list) -- else: -- compat_list = parse_compatibles(f) -- print_compat(f, compat_list) -+ for f in files_to_parse(args.cfile): -+ compat_list = parse_compatibles(f) -+ print_compat(f, compat_list) -diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c -index 0572330bf8a78..a76925b46ce63 100644 ---- a/scripts/kconfig/symbol.c -+++ b/scripts/kconfig/symbol.c -@@ -122,9 +122,9 @@ static long long sym_get_range_val(struct symbol *sym, int base) - static void sym_validate_range(struct symbol *sym) - { - struct property *prop; -+ struct symbol *range_sym; - int base; - long long val, val2; -- char str[64]; - - switch (sym->type) { - case S_INT: -@@ -140,17 +140,15 @@ static void sym_validate_range(struct symbol *sym) - if (!prop) - return; - val = strtoll(sym->curr.val, NULL, base); -- val2 = sym_get_range_val(prop->expr->left.sym, base); -+ range_sym = prop->expr->left.sym; -+ val2 = sym_get_range_val(range_sym, base); - if (val >= val2) { -- val2 = sym_get_range_val(prop->expr->right.sym, base); -+ range_sym = prop->expr->right.sym; -+ val2 = sym_get_range_val(range_sym, base); - if (val <= val2) - return; - } -- if (sym->type == S_INT) -- sprintf(str, "%lld", val2); -- else -- sprintf(str, "0x%llx", val2); -- sym->curr.val = xstrdup(str); -+ sym->curr.val = range_sym->curr.val; - } - - static void sym_set_changed(struct symbol *sym) -diff --git a/sound/core/pcm.c b/sound/core/pcm.c -index 9d95e37311230..2415a3c3ac6c9 100644 ---- a/sound/core/pcm.c -+++ b/sound/core/pcm.c -@@ -253,6 +253,7 @@ static const char * const snd_pcm_state_names[] = { - STATE(DRAINING), - STATE(PAUSED), - STATE(SUSPENDED), -+ STATE(DISCONNECTED), - }; - - static const char * const snd_pcm_access_names[] = { -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index d1944c83b03a2..c6cae3369a6a1 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -10031,6 +10031,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), - SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC295_FIXUP_CHROME_BOOK), - SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), -+ SND_PCI_QUIRK(0xf111, 0x0005, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), -+ SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), - - #if 0 - /* Below is a quirk table taken from the old code. -@@ -11952,6 +11954,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { - SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN), - SND_PCI_QUIRK(0x17aa, 0x3321, "Lenovo ThinkCentre M70 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN), - SND_PCI_QUIRK(0x17aa, 0x331b, "Lenovo ThinkCentre M90 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN), -+ SND_PCI_QUIRK(0x17aa, 0x3364, "Lenovo ThinkCentre M90 Gen5", ALC897_FIXUP_HEADSET_MIC_PIN), - SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2), - SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), - SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), -diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c -index c494de5f5c066..1dde1f3196acc 100644 ---- a/sound/soc/amd/yc/acp6x-mach.c -+++ b/sound/soc/amd/yc/acp6x-mach.c -@@ -283,6 +283,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c -index 9f59518005a5f..840bbe991cd3a 100644 ---- a/sound/soc/codecs/lpass-tx-macro.c -+++ b/sound/soc/codecs/lpass-tx-macro.c -@@ -1871,6 +1871,11 @@ static int tx_macro_probe(struct platform_device *pdev) - - tx->dev = dev; - -+ /* Set active_decimator default value */ -+ tx->active_decimator[TX_MACRO_AIF1_CAP] = -1; -+ tx->active_decimator[TX_MACRO_AIF2_CAP] = -1; -+ tx->active_decimator[TX_MACRO_AIF3_CAP] = -1; -+ - /* set MCLK and NPL rates */ - clk_set_rate(tx->mclk, MCLK_FREQ); - clk_set_rate(tx->npl, MCLK_FREQ); -diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c -index 8a2e9771bb50e..2cfca78f0401f 100644 ---- a/sound/soc/codecs/wm_adsp.c -+++ b/sound/soc/codecs/wm_adsp.c -@@ -1401,12 +1401,12 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) - ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, - ®ion->base_addr); - if (ret < 0) -- return ret; -+ goto err; - - ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, - &offset); - if (ret < 0) -- return ret; -+ goto err; - - region->cumulative_size = offset; - -@@ -1417,6 +1417,10 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) - } - - return 0; -+ -+err: -+ kfree(buf->regions); -+ return ret; - } - - static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf) -diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c -index 96fd9095e544b..6364d9be28fbb 100644 ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -674,6 +674,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, - FSL_SAI_CR3_TRCE_MASK, - FSL_SAI_CR3_TRCE((dl_cfg[dl_cfg_idx].mask[tx] & trce_mask))); - -+ /* -+ * When the TERE and FSD_MSTR enabled before configuring the word width -+ * There will be no frame sync clock issue, because word width impact -+ * the generation of frame sync clock. -+ * -+ * TERE enabled earlier only for i.MX8MP case for the hardware limitation, -+ * We need to disable FSD_MSTR before configuring word width, then enable -+ * FSD_MSTR bit for this specific case. -+ */ -+ if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output && -+ !sai->is_consumer_mode) -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), -+ FSL_SAI_CR4_FSD_MSTR, 0); -+ - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | - FSL_SAI_CR4_CHMOD_MASK, -@@ -681,6 +695,13 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, - regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); -+ -+ /* Enable FSD_MSTR after configuring word width */ -+ if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output && -+ !sai->is_consumer_mode) -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), -+ FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR); -+ - regmap_write(sai->regmap, FSL_SAI_xMR(tx), - ~0UL - ((1 << min(channels, slots)) - 1)); - -diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c -index ab0d459f42715..1f32e3ae3aa31 100644 ---- a/sound/usb/mixer_quirks.c -+++ b/sound/usb/mixer_quirks.c -@@ -2978,6 +2978,7 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer) - #define SND_DJM_850_IDX 0x2 - #define SND_DJM_900NXS2_IDX 0x3 - #define SND_DJM_750MK2_IDX 0x4 -+#define SND_DJM_450_IDX 0x5 - - - #define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \ -@@ -3108,6 +3109,31 @@ static const struct snd_djm_ctl snd_djm_ctls_250mk2[] = { - }; - - -+// DJM-450 -+static const u16 snd_djm_opts_450_cap1[] = { -+ 0x0103, 0x0100, 0x0106, 0x0107, 0x0108, 0x0109, 0x010d, 0x010a }; -+ -+static const u16 snd_djm_opts_450_cap2[] = { -+ 0x0203, 0x0200, 0x0206, 0x0207, 0x0208, 0x0209, 0x020d, 0x020a }; -+ -+static const u16 snd_djm_opts_450_cap3[] = { -+ 0x030a, 0x0311, 0x0312, 0x0307, 0x0308, 0x0309, 0x030d }; -+ -+static const u16 snd_djm_opts_450_pb1[] = { 0x0100, 0x0101, 0x0104 }; -+static const u16 snd_djm_opts_450_pb2[] = { 0x0200, 0x0201, 0x0204 }; -+static const u16 snd_djm_opts_450_pb3[] = { 0x0300, 0x0301, 0x0304 }; -+ -+static const struct snd_djm_ctl snd_djm_ctls_450[] = { -+ SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), -+ SND_DJM_CTL("Ch1 Input", 450_cap1, 2, SND_DJM_WINDEX_CAP), -+ SND_DJM_CTL("Ch2 Input", 450_cap2, 2, SND_DJM_WINDEX_CAP), -+ SND_DJM_CTL("Ch3 Input", 450_cap3, 0, SND_DJM_WINDEX_CAP), -+ SND_DJM_CTL("Ch1 Output", 450_pb1, 0, SND_DJM_WINDEX_PB), -+ SND_DJM_CTL("Ch2 Output", 450_pb2, 1, SND_DJM_WINDEX_PB), -+ SND_DJM_CTL("Ch3 Output", 450_pb3, 2, SND_DJM_WINDEX_PB) -+}; -+ -+ - // DJM-750 - static const u16 snd_djm_opts_750_cap1[] = { - 0x0101, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, 0x010f }; -@@ -3203,6 +3229,7 @@ static const struct snd_djm_device snd_djm_devices[] = { - [SND_DJM_850_IDX] = SND_DJM_DEVICE(850), - [SND_DJM_900NXS2_IDX] = SND_DJM_DEVICE(900nxs2), - [SND_DJM_750MK2_IDX] = SND_DJM_DEVICE(750mk2), -+ [SND_DJM_450_IDX] = SND_DJM_DEVICE(450), - }; - - -@@ -3449,6 +3476,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) - case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */ - err = snd_djm_controls_create(mixer, SND_DJM_250MK2_IDX); - break; -+ case USB_ID(0x2b73, 0x0013): /* Pioneer DJ DJM-450 */ -+ err = snd_djm_controls_create(mixer, SND_DJM_450_IDX); -+ break; - case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */ - err = snd_djm_controls_create(mixer, SND_DJM_750_IDX); - break; diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.68-69.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.68-69.patch deleted file mode 100644 index fd8d28e168ff..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.68-69.patch +++ /dev/null @@ -1,4110 +0,0 @@ -diff --git a/Makefile b/Makefile -index 2a8ad0cec2f1c..9a3b34d2387fa 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 68 -+SUBLEVEL = 69 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile -index 5e56d26a22398..c9496539c3351 100644 ---- a/arch/arm64/Makefile -+++ b/arch/arm64/Makefile -@@ -157,7 +157,7 @@ endif - - all: $(notdir $(KBUILD_IMAGE)) - -- -+vmlinuz.efi: Image - Image vmlinuz.efi: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ - -diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h -index 5d0f1f7b76004..56c7df4c65325 100644 ---- a/arch/arm64/include/asm/pgtable.h -+++ b/arch/arm64/include/asm/pgtable.h -@@ -822,6 +822,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) - if (pte_hw_dirty(pte)) - pte = pte_mkdirty(pte); - pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); -+ /* -+ * If we end up clearing hw dirtiness for a sw-dirty PTE, set hardware -+ * dirtiness again. -+ */ -+ if (pte_sw_dirty(pte)) -+ pte = pte_mkdirty(pte); - return pte; - } - -diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile -index 01b57b7263225..ed47a3a87768e 100644 ---- a/arch/loongarch/Makefile -+++ b/arch/loongarch/Makefile -@@ -116,6 +116,8 @@ vdso_install: - - all: $(notdir $(KBUILD_IMAGE)) - -+vmlinuz.efi: vmlinux.efi -+ - vmlinux.elf vmlinux.efi vmlinuz.efi: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@ - -diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c -index d2b7d5df132a9..150df6e17bb6a 100644 ---- a/arch/loongarch/kernel/time.c -+++ b/arch/loongarch/kernel/time.c -@@ -58,14 +58,16 @@ static int constant_set_state_oneshot(struct clock_event_device *evt) - return 0; - } - --static int constant_set_state_oneshot_stopped(struct clock_event_device *evt) -+static int constant_set_state_periodic(struct clock_event_device *evt) - { -+ unsigned long period; - unsigned long timer_config; - - raw_spin_lock(&state_lock); - -- timer_config = csr_read64(LOONGARCH_CSR_TCFG); -- timer_config &= ~CSR_TCFG_EN; -+ period = const_clock_freq / HZ; -+ timer_config = period & CSR_TCFG_VAL; -+ timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN); - csr_write64(timer_config, LOONGARCH_CSR_TCFG); - - raw_spin_unlock(&state_lock); -@@ -73,16 +75,14 @@ static int constant_set_state_oneshot_stopped(struct clock_event_device *evt) - return 0; - } - --static int constant_set_state_periodic(struct clock_event_device *evt) -+static int constant_set_state_shutdown(struct clock_event_device *evt) - { -- unsigned long period; - unsigned long timer_config; - - raw_spin_lock(&state_lock); - -- period = const_clock_freq / HZ; -- timer_config = period & CSR_TCFG_VAL; -- timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN); -+ timer_config = csr_read64(LOONGARCH_CSR_TCFG); -+ timer_config &= ~CSR_TCFG_EN; - csr_write64(timer_config, LOONGARCH_CSR_TCFG); - - raw_spin_unlock(&state_lock); -@@ -90,11 +90,6 @@ static int constant_set_state_periodic(struct clock_event_device *evt) - return 0; - } - --static int constant_set_state_shutdown(struct clock_event_device *evt) --{ -- return 0; --} -- - static int constant_timer_next_event(unsigned long delta, struct clock_event_device *evt) - { - unsigned long timer_config; -@@ -156,7 +151,7 @@ int constant_clockevent_init(void) - cd->rating = 320; - cd->cpumask = cpumask_of(cpu); - cd->set_state_oneshot = constant_set_state_oneshot; -- cd->set_state_oneshot_stopped = constant_set_state_oneshot_stopped; -+ cd->set_state_oneshot_stopped = constant_set_state_shutdown; - cd->set_state_periodic = constant_set_state_periodic; - cd->set_state_shutdown = constant_set_state_shutdown; - cd->set_next_event = constant_timer_next_event; -diff --git a/arch/powerpc/kernel/trace/ftrace_mprofile.S b/arch/powerpc/kernel/trace/ftrace_mprofile.S -index 6f9c2dea905b7..f4a72b38488f7 100644 ---- a/arch/powerpc/kernel/trace/ftrace_mprofile.S -+++ b/arch/powerpc/kernel/trace/ftrace_mprofile.S -@@ -62,7 +62,7 @@ - .endif - - /* Save previous stack pointer (r1) */ -- addi r8, r1, SWITCH_FRAME_SIZE -+ addi r8, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE - PPC_STL r8, GPR1(r1) - - .if \allregs == 1 -@@ -182,7 +182,7 @@ ftrace_no_trace: - mflr r3 - mtctr r3 - REST_GPR(3, r1) -- addi r1, r1, SWITCH_FRAME_SIZE -+ addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE - mtlr r0 - bctr - #endif -diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c -index 5fd72d4b8bbb0..7d454141433c8 100644 ---- a/arch/x86/events/intel/uncore_discovery.c -+++ b/arch/x86/events/intel/uncore_discovery.c -@@ -140,13 +140,21 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, - unsigned int *box_offset, *ids; - int i; - -- if (WARN_ON_ONCE(!unit->ctl || !unit->ctl_offset || !unit->ctr_offset)) -+ if (!unit->ctl || !unit->ctl_offset || !unit->ctr_offset) { -+ pr_info("Invalid address is detected for uncore type %d box %d, " -+ "Disable the uncore unit.\n", -+ unit->box_type, unit->box_id); - return; -+ } - - if (parsed) { - type = search_uncore_discovery_type(unit->box_type); -- if (WARN_ON_ONCE(!type)) -+ if (!type) { -+ pr_info("A spurious uncore type %d is detected, " -+ "Disable the uncore type.\n", -+ unit->box_type); - return; -+ } - /* Store the first box of each die */ - if (!type->box_ctrl_die[die]) - type->box_ctrl_die[die] = unit->ctl; -@@ -181,8 +189,12 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, - ids[i] = type->ids[i]; - box_offset[i] = type->box_offset[i]; - -- if (WARN_ON_ONCE(unit->box_id == ids[i])) -+ if (unit->box_id == ids[i]) { -+ pr_info("Duplicate uncore type %d box ID %d is detected, " -+ "Drop the duplicate uncore unit.\n", -+ unit->box_type, unit->box_id); - goto free_ids; -+ } - } - ids[i] = unit->box_id; - box_offset[i] = unit->ctl - type->box_ctrl; -diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c -index 189ae92de4d06..c18e5c764643b 100644 ---- a/arch/x86/hyperv/hv_init.c -+++ b/arch/x86/hyperv/hv_init.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -267,15 +268,31 @@ static int hv_cpu_die(unsigned int cpu) - - static int __init hv_pci_init(void) - { -- int gen2vm = efi_enabled(EFI_BOOT); -+ bool gen2vm = efi_enabled(EFI_BOOT); - - /* -- * For Generation-2 VM, we exit from pci_arch_init() by returning 0. -- * The purpose is to suppress the harmless warning: -+ * A Generation-2 VM doesn't support legacy PCI/PCIe, so both -+ * raw_pci_ops and raw_pci_ext_ops are NULL, and pci_subsys_init() -> -+ * pcibios_init() doesn't call pcibios_resource_survey() -> -+ * e820__reserve_resources_late(); as a result, any emulated persistent -+ * memory of E820_TYPE_PRAM (12) via the kernel parameter -+ * memmap=nn[KMG]!ss is not added into iomem_resource and hence can't be -+ * detected by register_e820_pmem(). Fix this by directly calling -+ * e820__reserve_resources_late() here: e820__reserve_resources_late() -+ * depends on e820__reserve_resources(), which has been called earlier -+ * from setup_arch(). Note: e820__reserve_resources_late() also adds -+ * any memory of E820_TYPE_PMEM (7) into iomem_resource, and -+ * acpi_nfit_register_region() -> acpi_nfit_insert_resource() -> -+ * region_intersects() returns REGION_INTERSECTS, so the memory of -+ * E820_TYPE_PMEM won't get added twice. -+ * -+ * We return 0 here so that pci_arch_init() won't print the warning: - * "PCI: Fatal: No config space access function found" - */ -- if (gen2vm) -+ if (gen2vm) { -+ e820__reserve_resources_late(); - return 0; -+ } - - /* For Generation-1 VM, we'll proceed in pci_arch_init(). */ - return 1; -diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c -index 60f366f98fa2b..1b7fd1fc2f337 100644 ---- a/block/blk-cgroup.c -+++ b/block/blk-cgroup.c -@@ -462,6 +462,7 @@ static void blkg_destroy_all(struct gendisk *disk) - struct request_queue *q = disk->queue; - struct blkcg_gq *blkg, *n; - int count = BLKG_DESTROY_BATCH_SIZE; -+ int i; - - restart: - spin_lock_irq(&q->queue_lock); -@@ -487,6 +488,18 @@ restart: - } - } - -+ /* -+ * Mark policy deactivated since policy offline has been done, and -+ * the free is scheduled, so future blkcg_deactivate_policy() can -+ * be bypassed -+ */ -+ for (i = 0; i < BLKCG_MAX_POLS; i++) { -+ struct blkcg_policy *pol = blkcg_policy[i]; -+ -+ if (pol) -+ __clear_bit(pol->plid, q->blkcg_pols); -+ } -+ - q->root_blkg = NULL; - spin_unlock_irq(&q->queue_lock); - } -diff --git a/block/blk-throttle.c b/block/blk-throttle.c -index 009b0d76bf036..62a3f62316df1 100644 ---- a/block/blk-throttle.c -+++ b/block/blk-throttle.c -@@ -1333,6 +1333,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) - tg_bps_limit(tg, READ), tg_bps_limit(tg, WRITE), - tg_iops_limit(tg, READ), tg_iops_limit(tg, WRITE)); - -+ rcu_read_lock(); - /* - * Update has_rules[] flags for the updated tg's subtree. A tg is - * considered to have rules if either the tg itself or any of its -@@ -1360,6 +1361,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) - this_tg->latency_target = max(this_tg->latency_target, - parent_tg->latency_target); - } -+ rcu_read_unlock(); - - /* - * We're already holding queue_lock and know @tg is valid. Let's -diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c -index 94fbc3abe60e6..d3c30a28c410e 100644 ---- a/drivers/atm/solos-pci.c -+++ b/drivers/atm/solos-pci.c -@@ -449,9 +449,9 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, - struct sk_buff *skb; - unsigned int len; - -- spin_lock(&card->cli_queue_lock); -+ spin_lock_bh(&card->cli_queue_lock); - skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]); -- spin_unlock(&card->cli_queue_lock); -+ spin_unlock_bh(&card->cli_queue_lock); - if(skb == NULL) - return sprintf(buf, "No data.\n"); - -@@ -956,14 +956,14 @@ static void pclose(struct atm_vcc *vcc) - struct pkt_hdr *header; - - /* Remove any yet-to-be-transmitted packets from the pending queue */ -- spin_lock(&card->tx_queue_lock); -+ spin_lock_bh(&card->tx_queue_lock); - skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) { - if (SKB_CB(skb)->vcc == vcc) { - skb_unlink(skb, &card->tx_queue[port]); - solos_pop(vcc, skb); - } - } -- spin_unlock(&card->tx_queue_lock); -+ spin_unlock_bh(&card->tx_queue_lock); - - skb = alloc_skb(sizeof(*header), GFP_KERNEL); - if (!skb) { -diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c -index e94d2ff6b1223..8037aaefeb2ed 100644 ---- a/drivers/block/nbd.c -+++ b/drivers/block/nbd.c -@@ -67,6 +67,7 @@ struct nbd_sock { - struct recv_thread_args { - struct work_struct work; - struct nbd_device *nbd; -+ struct nbd_sock *nsock; - int index; - }; - -@@ -489,15 +490,9 @@ done: - return BLK_EH_DONE; - } - --/* -- * Send or receive packet. Return a positive value on success and -- * negtive value on failue, and never return 0. -- */ --static int sock_xmit(struct nbd_device *nbd, int index, int send, -- struct iov_iter *iter, int msg_flags, int *sent) -+static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, -+ struct iov_iter *iter, int msg_flags, int *sent) - { -- struct nbd_config *config = nbd->config; -- struct socket *sock = config->socks[index]->sock; - int result; - struct msghdr msg; - unsigned int noreclaim_flag; -@@ -539,6 +534,19 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send, - return result; - } - -+/* -+ * Send or receive packet. Return a positive value on success and -+ * negtive value on failure, and never return 0. -+ */ -+static int sock_xmit(struct nbd_device *nbd, int index, int send, -+ struct iov_iter *iter, int msg_flags, int *sent) -+{ -+ struct nbd_config *config = nbd->config; -+ struct socket *sock = config->socks[index]->sock; -+ -+ return __sock_xmit(nbd, sock, send, iter, msg_flags, sent); -+} -+ - /* - * Different settings for sk->sk_sndtimeo can result in different return values - * if there is a signal pending when we enter sendmsg, because reasons? -@@ -695,7 +703,7 @@ out: - return 0; - } - --static int nbd_read_reply(struct nbd_device *nbd, int index, -+static int nbd_read_reply(struct nbd_device *nbd, struct socket *sock, - struct nbd_reply *reply) - { - struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)}; -@@ -704,7 +712,7 @@ static int nbd_read_reply(struct nbd_device *nbd, int index, - - reply->magic = 0; - iov_iter_kvec(&to, ITER_DEST, &iov, 1, sizeof(*reply)); -- result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); -+ result = __sock_xmit(nbd, sock, 0, &to, MSG_WAITALL, NULL); - if (result < 0) { - if (!nbd_disconnected(nbd->config)) - dev_err(disk_to_dev(nbd->disk), -@@ -828,14 +836,14 @@ static void recv_work(struct work_struct *work) - struct nbd_device *nbd = args->nbd; - struct nbd_config *config = nbd->config; - struct request_queue *q = nbd->disk->queue; -- struct nbd_sock *nsock; -+ struct nbd_sock *nsock = args->nsock; - struct nbd_cmd *cmd; - struct request *rq; - - while (1) { - struct nbd_reply reply; - -- if (nbd_read_reply(nbd, args->index, &reply)) -+ if (nbd_read_reply(nbd, nsock->sock, &reply)) - break; - - /* -@@ -870,7 +878,6 @@ static void recv_work(struct work_struct *work) - percpu_ref_put(&q->q_usage_counter); - } - -- nsock = config->socks[args->index]; - mutex_lock(&nsock->tx_lock); - nbd_mark_nsock_dead(nbd, nsock, 1); - mutex_unlock(&nsock->tx_lock); -@@ -1214,6 +1221,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) - INIT_WORK(&args->work, recv_work); - args->index = i; - args->nbd = nbd; -+ args->nsock = nsock; - nsock->cookie++; - mutex_unlock(&nsock->tx_lock); - sockfd_put(old); -@@ -1396,6 +1404,7 @@ static int nbd_start_device(struct nbd_device *nbd) - refcount_inc(&nbd->config_refs); - INIT_WORK(&args->work, recv_work); - args->nbd = nbd; -+ args->nsock = config->socks[i]; - args->index = i; - queue_work(nbd->recv_workq, &args->work); - } -@@ -1530,17 +1539,20 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, - return error; - } - --static struct nbd_config *nbd_alloc_config(void) -+static int nbd_alloc_and_init_config(struct nbd_device *nbd) - { - struct nbd_config *config; - -+ if (WARN_ON(nbd->config)) -+ return -EINVAL; -+ - if (!try_module_get(THIS_MODULE)) -- return ERR_PTR(-ENODEV); -+ return -ENODEV; - - config = kzalloc(sizeof(struct nbd_config), GFP_NOFS); - if (!config) { - module_put(THIS_MODULE); -- return ERR_PTR(-ENOMEM); -+ return -ENOMEM; - } - - atomic_set(&config->recv_threads, 0); -@@ -1548,7 +1560,10 @@ static struct nbd_config *nbd_alloc_config(void) - init_waitqueue_head(&config->conn_wait); - config->blksize_bits = NBD_DEF_BLKSIZE_BITS; - atomic_set(&config->live_connections, 0); -- return config; -+ nbd->config = config; -+ refcount_set(&nbd->config_refs, 1); -+ -+ return 0; - } - - static int nbd_open(struct block_device *bdev, fmode_t mode) -@@ -1567,21 +1582,17 @@ static int nbd_open(struct block_device *bdev, fmode_t mode) - goto out; - } - if (!refcount_inc_not_zero(&nbd->config_refs)) { -- struct nbd_config *config; -- - mutex_lock(&nbd->config_lock); - if (refcount_inc_not_zero(&nbd->config_refs)) { - mutex_unlock(&nbd->config_lock); - goto out; - } -- config = nbd_alloc_config(); -- if (IS_ERR(config)) { -- ret = PTR_ERR(config); -+ ret = nbd_alloc_and_init_config(nbd); -+ if (ret) { - mutex_unlock(&nbd->config_lock); - goto out; - } -- nbd->config = config; -- refcount_set(&nbd->config_refs, 1); -+ - refcount_inc(&nbd->refs); - mutex_unlock(&nbd->config_lock); - if (max_part) -@@ -1990,22 +2001,17 @@ again: - pr_err("nbd%d already in use\n", index); - return -EBUSY; - } -- if (WARN_ON(nbd->config)) { -- mutex_unlock(&nbd->config_lock); -- nbd_put(nbd); -- return -EINVAL; -- } -- config = nbd_alloc_config(); -- if (IS_ERR(config)) { -+ -+ ret = nbd_alloc_and_init_config(nbd); -+ if (ret) { - mutex_unlock(&nbd->config_lock); - nbd_put(nbd); - pr_err("couldn't allocate config\n"); -- return PTR_ERR(config); -+ return ret; - } -- nbd->config = config; -- refcount_set(&nbd->config_refs, 1); -- set_bit(NBD_RT_BOUND, &config->runtime_flags); - -+ config = nbd->config; -+ set_bit(NBD_RT_BOUND, &config->runtime_flags); - ret = nbd_genl_size_set(info, nbd); - if (ret) - goto out; -diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c -index 592d48ecf241f..7abcd7f2848ee 100644 ---- a/drivers/dma/stm32-dma.c -+++ b/drivers/dma/stm32-dma.c -@@ -1249,8 +1249,8 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( - enum dma_slave_buswidth max_width; - struct stm32_dma_desc *desc; - size_t xfer_count, offset; -- u32 num_sgs, best_burst, dma_burst, threshold; -- int i; -+ u32 num_sgs, best_burst, threshold; -+ int dma_burst, i; - - num_sgs = DIV_ROUND_UP(len, STM32_DMA_ALIGNED_MAX_DATA_ITEMS); - desc = kzalloc(struct_size(desc, sg_req, num_sgs), GFP_NOWAIT); -@@ -1268,6 +1268,10 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( - best_burst = stm32_dma_get_best_burst(len, STM32_DMA_MAX_BURST, - threshold, max_width); - dma_burst = stm32_dma_get_burst(chan, best_burst); -+ if (dma_burst < 0) { -+ kfree(desc); -+ return NULL; -+ } - - stm32_dma_clear_reg(&desc->sg_req[i].chan_reg); - desc->sg_req[i].chan_reg.dma_scr = -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c -index 4642cff0e1a4f..69b3829bbe53f 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c -@@ -631,13 +631,14 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry) - - if (!entry->bo) - return; -+ -+ entry->bo->vm_bo = NULL; - shadow = amdgpu_bo_shadowed(entry->bo); - if (shadow) { - ttm_bo_set_bulk_move(&shadow->tbo, NULL); - amdgpu_bo_unref(&shadow); - } - ttm_bo_set_bulk_move(&entry->bo->tbo, NULL); -- entry->bo->vm_bo = NULL; - - spin_lock(&entry->vm->status_lock); - list_del(&entry->vm_status); -diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c -index 809eca54fc617..856db876af141 100644 ---- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c -+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c -@@ -1690,6 +1690,32 @@ static void sdma_v5_2_get_clockgating_state(void *handle, u64 *flags) - *flags |= AMD_CG_SUPPORT_SDMA_LS; - } - -+static void sdma_v5_2_ring_begin_use(struct amdgpu_ring *ring) -+{ -+ struct amdgpu_device *adev = ring->adev; -+ -+ /* SDMA 5.2.3 (RMB) FW doesn't seem to properly -+ * disallow GFXOFF in some cases leading to -+ * hangs in SDMA. Disallow GFXOFF while SDMA is active. -+ * We can probably just limit this to 5.2.3, -+ * but it shouldn't hurt for other parts since -+ * this GFXOFF will be disallowed anyway when SDMA is -+ * active, this just makes it explicit. -+ */ -+ amdgpu_gfx_off_ctrl(adev, false); -+} -+ -+static void sdma_v5_2_ring_end_use(struct amdgpu_ring *ring) -+{ -+ struct amdgpu_device *adev = ring->adev; -+ -+ /* SDMA 5.2.3 (RMB) FW doesn't seem to properly -+ * disallow GFXOFF in some cases leading to -+ * hangs in SDMA. Allow GFXOFF when SDMA is complete. -+ */ -+ amdgpu_gfx_off_ctrl(adev, true); -+} -+ - const struct amd_ip_funcs sdma_v5_2_ip_funcs = { - .name = "sdma_v5_2", - .early_init = sdma_v5_2_early_init, -@@ -1738,6 +1764,8 @@ static const struct amdgpu_ring_funcs sdma_v5_2_ring_funcs = { - .test_ib = sdma_v5_2_ring_test_ib, - .insert_nop = sdma_v5_2_ring_insert_nop, - .pad_ib = sdma_v5_2_ring_pad_ib, -+ .begin_use = sdma_v5_2_ring_begin_use, -+ .end_use = sdma_v5_2_ring_end_use, - .emit_wreg = sdma_v5_2_ring_emit_wreg, - .emit_reg_wait = sdma_v5_2_ring_emit_reg_wait, - .emit_reg_write_reg_wait = sdma_v5_2_ring_emit_reg_write_reg_wait, -diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c -index 9edd39322c822..67287ad07226c 100644 ---- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c -+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c -@@ -816,6 +816,8 @@ bool is_psr_su_specific_panel(struct dc_link *link) - ((dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x08) || - (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x07))) - isPSRSUSupported = false; -+ else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03) -+ isPSRSUSupported = false; - else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1) - isPSRSUSupported = true; - } -diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c -index eefa33c555aca..23d854bd73b77 100644 ---- a/drivers/gpu/drm/i915/display/intel_fb.c -+++ b/drivers/gpu/drm/i915/display/intel_fb.c -@@ -1441,8 +1441,20 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p - - size += remap_info->size; - } else { -- unsigned int dst_stride = plane_view_dst_stride_tiles(fb, color_plane, -- remap_info->width); -+ unsigned int dst_stride; -+ -+ /* -+ * The hardware automagically calculates the CCS AUX surface -+ * stride from the main surface stride so can't really remap a -+ * smaller subset (unless we'd remap in whole AUX page units). -+ */ -+ if (intel_fb_needs_pot_stride_remap(fb) && -+ intel_fb_is_ccs_modifier(fb->base.modifier)) -+ dst_stride = remap_info->src_stride; -+ else -+ dst_stride = remap_info->width; -+ -+ dst_stride = plane_view_dst_stride_tiles(fb, color_plane, dst_stride); - - assign_chk_ovf(i915, remap_info->dst_stride, dst_stride); - color_plane_info->mapping_stride = dst_stride * -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -index 7fb52a573436e..558000db4a100 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c -@@ -736,6 +736,7 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc, - crtc); - struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state); - struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); -+ unsigned long flags; - - if (mtk_crtc->event && mtk_crtc_state->base.event) - DRM_ERROR("new event while there is still a pending event\n"); -@@ -743,7 +744,11 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc, - if (mtk_crtc_state->base.event) { - mtk_crtc_state->base.event->pipe = drm_crtc_index(crtc); - WARN_ON(drm_crtc_vblank_get(crtc) != 0); -+ -+ spin_lock_irqsave(&crtc->dev->event_lock, flags); - mtk_crtc->event = mtk_crtc_state->base.event; -+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags); -+ - mtk_crtc_state->base.event = NULL; - } - } -diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c -index d1094bb1aa429..220d6b2af4d3f 100644 ---- a/drivers/hid/hid-asus.c -+++ b/drivers/hid/hid-asus.c -@@ -380,7 +380,7 @@ static int asus_raw_event(struct hid_device *hdev, - return 0; - } - --static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size) -+static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size) - { - unsigned char *dmabuf; - int ret; -@@ -403,7 +403,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size - - static int asus_kbd_init(struct hid_device *hdev) - { -- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, -+ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, - 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; - int ret; - -@@ -417,7 +417,7 @@ static int asus_kbd_init(struct hid_device *hdev) - static int asus_kbd_get_functions(struct hid_device *hdev, - unsigned char *kbd_func) - { -- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; -+ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; - u8 *readbuf; - int ret; - -@@ -448,7 +448,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev, - - static int rog_nkey_led_init(struct hid_device *hdev) - { -- u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; -+ const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; - u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20, - 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; - u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1, -@@ -1012,6 +1012,24 @@ static int asus_start_multitouch(struct hid_device *hdev) - return 0; - } - -+static int __maybe_unused asus_resume(struct hid_device *hdev) { -+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev); -+ int ret = 0; -+ -+ if (drvdata->kbd_backlight) { -+ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, -+ drvdata->kbd_backlight->cdev.brightness }; -+ ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); -+ if (ret < 0) { -+ hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); -+ goto asus_resume_err; -+ } -+ } -+ -+asus_resume_err: -+ return ret; -+} -+ - static int __maybe_unused asus_reset_resume(struct hid_device *hdev) - { - struct asus_drvdata *drvdata = hid_get_drvdata(hdev); -@@ -1303,6 +1321,7 @@ static struct hid_driver asus_driver = { - .input_configured = asus_input_configured, - #ifdef CONFIG_PM - .reset_resume = asus_reset_resume, -+ .resume = asus_resume, - #endif - .event = asus_event, - .raw_event = asus_raw_event -diff --git a/drivers/hid/hid-glorious.c b/drivers/hid/hid-glorious.c -index 558eb08c19ef9..281b3a7187cec 100644 ---- a/drivers/hid/hid-glorious.c -+++ b/drivers/hid/hid-glorious.c -@@ -21,6 +21,10 @@ MODULE_DESCRIPTION("HID driver for Glorious PC Gaming Race mice"); - * Glorious Model O and O- specify the const flag in the consumer input - * report descriptor, which leads to inputs being ignored. Fix this - * by patching the descriptor. -+ * -+ * Glorious Model I incorrectly specifes the Usage Minimum for its -+ * keyboard HID report, causing keycodes to be misinterpreted. -+ * Fix this by setting Usage Minimum to 0 in that report. - */ - static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int *rsize) -@@ -32,6 +36,10 @@ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc, - rdesc[85] = rdesc[113] = rdesc[141] = \ - HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE; - } -+ if (*rsize == 156 && rdesc[41] == 1) { -+ hid_info(hdev, "patching Glorious Model I keyboard report descriptor\n"); -+ rdesc[41] = 0; -+ } - return rdesc; - } - -@@ -44,6 +52,8 @@ static void glorious_update_name(struct hid_device *hdev) - model = "Model O"; break; - case USB_DEVICE_ID_GLORIOUS_MODEL_D: - model = "Model D"; break; -+ case USB_DEVICE_ID_GLORIOUS_MODEL_I: -+ model = "Model I"; break; - } - - snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model); -@@ -66,10 +76,12 @@ static int glorious_probe(struct hid_device *hdev, - } - - static const struct hid_device_id glorious_devices[] = { -- { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, -+ { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH, - USB_DEVICE_ID_GLORIOUS_MODEL_O) }, -- { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, -+ { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH, - USB_DEVICE_ID_GLORIOUS_MODEL_D) }, -+ { HID_USB_DEVICE(USB_VENDOR_ID_LAVIEW, -+ USB_DEVICE_ID_GLORIOUS_MODEL_I) }, - { } - }; - MODULE_DEVICE_TABLE(hid, glorious_devices); -diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h -index 130fc5f341422..1be454bafcb91 100644 ---- a/drivers/hid/hid-ids.h -+++ b/drivers/hid/hid-ids.h -@@ -503,10 +503,6 @@ - #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a - #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100 - --#define USB_VENDOR_ID_GLORIOUS 0x258a --#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 --#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 -- - #define I2C_VENDOR_ID_GOODIX 0x27c6 - #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 - -@@ -729,6 +725,9 @@ - #define USB_VENDOR_ID_LABTEC 0x1020 - #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 - -+#define USB_VENDOR_ID_LAVIEW 0x22D4 -+#define USB_DEVICE_ID_GLORIOUS_MODEL_I 0x1503 -+ - #define USB_VENDOR_ID_LCPOWER 0x1241 - #define USB_DEVICE_ID_LCPOWER_LC1000 0xf767 - -@@ -1131,6 +1130,10 @@ - #define USB_VENDOR_ID_SIGMATEL 0x066F - #define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780 - -+#define USB_VENDOR_ID_SINOWEALTH 0x258a -+#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 -+#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 -+ - #define USB_VENDOR_ID_SIS_TOUCH 0x0457 - #define USB_DEVICE_ID_SIS9200_TOUCH 0x9200 - #define USB_DEVICE_ID_SIS817_TOUCH 0x0817 -diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c -index 7c1b33be9d134..149a3c74346b4 100644 ---- a/drivers/hid/hid-lenovo.c -+++ b/drivers/hid/hid-lenovo.c -@@ -692,7 +692,8 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, - * so set middlebutton_state to 3 - * to never apply workaround anymore - */ -- if (cptkbd_data->middlebutton_state == 1 && -+ if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD && -+ cptkbd_data->middlebutton_state == 1 && - usage->type == EV_REL && - (usage->code == REL_X || usage->code == REL_Y)) { - cptkbd_data->middlebutton_state = 3; -diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c -index 8db4ae05febc8..5ec1f174127a3 100644 ---- a/drivers/hid/hid-multitouch.c -+++ b/drivers/hid/hid-multitouch.c -@@ -2048,6 +2048,11 @@ static const struct hid_device_id mt_devices[] = { - MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, - USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, - -+ /* HONOR GLO-GXXX panel */ -+ { .driver_data = MT_CLS_VTL, -+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, -+ 0x347d, 0x7853) }, -+ - /* Ilitek dual touch panel */ - { .driver_data = MT_CLS_NSMU, - MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, -diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c -index 056bb32091285..60884066362a1 100644 ---- a/drivers/hid/hid-quirks.c -+++ b/drivers/hid/hid-quirks.c -@@ -33,6 +33,7 @@ static const struct hid_device_id hid_quirks[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS }, - { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD }, - { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL }, -+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL }, - { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET }, - { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET }, - { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET }, -diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h -index aebb7ef10e631..e86fa736dc4ee 100644 ---- a/drivers/md/bcache/bcache.h -+++ b/drivers/md/bcache/bcache.h -@@ -265,6 +265,7 @@ struct bcache_device { - #define BCACHE_DEV_WB_RUNNING 3 - #define BCACHE_DEV_RATE_DW_RUNNING 4 - int nr_stripes; -+#define BCH_MIN_STRIPE_SZ ((4 << 20) >> SECTOR_SHIFT) - unsigned int stripe_size; - atomic_t *stripe_sectors_dirty; - unsigned long *full_dirty_stripes; -diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c -index 05e3157fc7b4e..6a2f57ae0f3c2 100644 ---- a/drivers/md/bcache/btree.c -+++ b/drivers/md/bcache/btree.c -@@ -974,6 +974,9 @@ err: - * - * The btree node will have either a read or a write lock held, depending on - * level and op->lock. -+ * -+ * Note: Only error code or btree pointer will be returned, it is unncessary -+ * for callers to check NULL pointer. - */ - struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op, - struct bkey *k, int level, bool write, -@@ -1085,6 +1088,10 @@ retry: - mutex_unlock(&b->c->bucket_lock); - } - -+/* -+ * Only error code or btree pointer will be returned, it is unncessary for -+ * callers to check NULL pointer. -+ */ - struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, - int level, bool wait, - struct btree *parent) -diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c -index 7660962e7b8b4..70e5bd8961d2f 100644 ---- a/drivers/md/bcache/super.c -+++ b/drivers/md/bcache/super.c -@@ -905,6 +905,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, - - if (!d->stripe_size) - d->stripe_size = 1 << 31; -+ else if (d->stripe_size < BCH_MIN_STRIPE_SZ) -+ d->stripe_size = roundup(BCH_MIN_STRIPE_SZ, d->stripe_size); - - n = DIV_ROUND_UP_ULL(sectors, d->stripe_size); - if (!n || n > max_stripes) { -@@ -2017,7 +2019,7 @@ static int run_cache_set(struct cache_set *c) - c->root = bch_btree_node_get(c, NULL, k, - j->btree_level, - true, NULL); -- if (IS_ERR_OR_NULL(c->root)) -+ if (IS_ERR(c->root)) - goto err; - - list_del_init(&c->root->list); -diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c -index 01c7c6ca4789f..18c6e0d2877b5 100644 ---- a/drivers/md/bcache/writeback.c -+++ b/drivers/md/bcache/writeback.c -@@ -913,7 +913,7 @@ static int bch_dirty_init_thread(void *arg) - int cur_idx, prev_idx, skip_nr; - - k = p = NULL; -- cur_idx = prev_idx = 0; -+ prev_idx = 0; - - bch_btree_iter_init(&c->root->keys, &iter, NULL); - k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); -diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c b/drivers/net/ethernet/amazon/ena/ena_eth_com.c -index 3d6f0a466a9ed..f9f886289b970 100644 ---- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c -+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c -@@ -328,9 +328,6 @@ static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, - * compare it to the stored version, just create the meta - */ - if (io_sq->disable_meta_caching) { -- if (unlikely(!ena_tx_ctx->meta_valid)) -- return -EINVAL; -- - *have_meta = true; - return ena_com_create_meta(io_sq, ena_meta); - } -diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c -index 42a66b74c1e5b..044b8afde69a0 100644 ---- a/drivers/net/ethernet/amazon/ena/ena_netdev.c -+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c -@@ -74,6 +74,8 @@ static void ena_unmap_tx_buff(struct ena_ring *tx_ring, - struct ena_tx_buffer *tx_info); - static int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter, - int first_index, int count); -+static void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter, -+ int first_index, int count); - - /* Increase a stat by cnt while holding syncp seqlock on 32bit machines */ - static void ena_increase_stat(u64 *statp, u64 cnt, -@@ -457,23 +459,22 @@ static void ena_init_all_xdp_queues(struct ena_adapter *adapter) - - static int ena_setup_and_create_all_xdp_queues(struct ena_adapter *adapter) - { -+ u32 xdp_first_ring = adapter->xdp_first_ring; -+ u32 xdp_num_queues = adapter->xdp_num_queues; - int rc = 0; - -- rc = ena_setup_tx_resources_in_range(adapter, adapter->xdp_first_ring, -- adapter->xdp_num_queues); -+ rc = ena_setup_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues); - if (rc) - goto setup_err; - -- rc = ena_create_io_tx_queues_in_range(adapter, -- adapter->xdp_first_ring, -- adapter->xdp_num_queues); -+ rc = ena_create_io_tx_queues_in_range(adapter, xdp_first_ring, xdp_num_queues); - if (rc) - goto create_err; - - return 0; - - create_err: -- ena_free_all_io_tx_resources(adapter); -+ ena_free_all_io_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues); - setup_err: - return rc; - } -@@ -1617,20 +1618,23 @@ static void ena_set_rx_hash(struct ena_ring *rx_ring, - } - } - --static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp) -+static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp, u16 num_descs) - { - struct ena_rx_buffer *rx_info; - int ret; - -+ /* XDP multi-buffer packets not supported */ -+ if (unlikely(num_descs > 1)) { -+ netdev_err_once(rx_ring->adapter->netdev, -+ "xdp: dropped unsupported multi-buffer packets\n"); -+ ena_increase_stat(&rx_ring->rx_stats.xdp_drop, 1, &rx_ring->syncp); -+ return ENA_XDP_DROP; -+ } -+ - rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]; - xdp_prepare_buff(xdp, page_address(rx_info->page), - rx_info->page_offset, - rx_ring->ena_bufs[0].len, false); -- /* If for some reason we received a bigger packet than -- * we expect, then we simply drop it -- */ -- if (unlikely(rx_ring->ena_bufs[0].len > ENA_XDP_MAX_MTU)) -- return ENA_XDP_DROP; - - ret = ena_xdp_execute(rx_ring, xdp); - -@@ -1699,7 +1703,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, - ena_rx_ctx.l4_proto, ena_rx_ctx.hash); - - if (ena_xdp_present_ring(rx_ring)) -- xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp); -+ xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp, ena_rx_ctx.descs); - - /* allocate skb and fill it */ - if (xdp_verdict == ENA_XDP_PASS) -diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -index b5a49166fa972..4d9d7d1edb9b3 100644 ---- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c -@@ -938,11 +938,14 @@ void aq_ring_free(struct aq_ring_s *self) - return; - - kfree(self->buff_ring); -+ self->buff_ring = NULL; - -- if (self->dx_ring) -+ if (self->dx_ring) { - dma_free_coherent(aq_nic_get_dev(self->aq_nic), - self->size * self->dx_size, self->dx_ring, - self->dx_ring_pa); -+ self->dx_ring = NULL; -+ } - } - - unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data) -diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c -index 16c490692f422..4950fde82d175 100644 ---- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c -+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c -@@ -1923,8 +1923,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, - - /* Skip VLAN tag if present */ - if (ether_type == ETH_P_8021Q) { -- struct vlan_ethhdr *vhdr = -- (struct vlan_ethhdr *)skb->data; -+ struct vlan_ethhdr *vhdr = skb_vlan_eth_hdr(skb); - - ether_type = ntohs(vhdr->h_vlan_encapsulated_proto); - } -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -index e81cb825dff4c..623cdeb29ed90 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -@@ -1796,6 +1796,21 @@ static void bnxt_deliver_skb(struct bnxt *bp, struct bnxt_napi *bnapi, - napi_gro_receive(&bnapi->napi, skb); - } - -+static bool bnxt_rx_ts_valid(struct bnxt *bp, u32 flags, -+ struct rx_cmp_ext *rxcmp1, u32 *cmpl_ts) -+{ -+ u32 ts = le32_to_cpu(rxcmp1->rx_cmp_timestamp); -+ -+ if (BNXT_PTP_RX_TS_VALID(flags)) -+ goto ts_valid; -+ if (!bp->ptp_all_rx_tstamp || !ts || !BNXT_ALL_RX_TS_VALID(flags)) -+ return false; -+ -+ts_valid: -+ *cmpl_ts = ts; -+ return true; -+} -+ - /* returns the following: - * 1 - 1 packet successfully received - * 0 - successful TPA_START, packet not completed yet -@@ -1821,6 +1836,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, - struct sk_buff *skb; - struct xdp_buff xdp; - u32 flags, misc; -+ u32 cmpl_ts; - void *data; - int rc = 0; - -@@ -2043,10 +2059,8 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, - } - } - -- if (unlikely((flags & RX_CMP_FLAGS_ITYPES_MASK) == -- RX_CMP_FLAGS_ITYPE_PTP_W_TS) || bp->ptp_all_rx_tstamp) { -+ if (bnxt_rx_ts_valid(bp, flags, rxcmp1, &cmpl_ts)) { - if (bp->flags & BNXT_FLAG_CHIP_P5) { -- u32 cmpl_ts = le32_to_cpu(rxcmp1->rx_cmp_timestamp); - u64 ns, ts; - - if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { -@@ -10708,8 +10722,10 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init, - bnxt_free_skbs(bp); - - /* Save ring stats before shutdown */ -- if (bp->bnapi && irq_re_init) -+ if (bp->bnapi && irq_re_init) { - bnxt_get_ring_stats(bp, &bp->net_stats_prev); -+ bnxt_get_ring_err_stats(bp, &bp->ring_err_stats_prev); -+ } - if (irq_re_init) { - bnxt_free_irq(bp); - bnxt_del_napi(bp); -@@ -10717,10 +10733,8 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init, - bnxt_free_mem(bp, irq_re_init); - } - --int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) -+void bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) - { -- int rc = 0; -- - if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { - /* If we get here, it means firmware reset is in progress - * while we are trying to close. We can safely proceed with -@@ -10735,15 +10749,18 @@ int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) - - #ifdef CONFIG_BNXT_SRIOV - if (bp->sriov_cfg) { -+ int rc; -+ - rc = wait_event_interruptible_timeout(bp->sriov_cfg_wait, - !bp->sriov_cfg, - BNXT_SRIOV_CFG_WAIT_TMO); -- if (rc) -- netdev_warn(bp->dev, "timeout waiting for SRIOV config operation to complete!\n"); -+ if (!rc) -+ netdev_warn(bp->dev, "timeout waiting for SRIOV config operation to complete, proceeding to close!\n"); -+ else if (rc < 0) -+ netdev_warn(bp->dev, "SRIOV config operation interrupted, proceeding to close!\n"); - } - #endif - __bnxt_close_nic(bp, irq_re_init, link_re_init); -- return rc; - } - - static int bnxt_close(struct net_device *dev) -@@ -10958,6 +10975,34 @@ bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - clear_bit(BNXT_STATE_READ_STATS, &bp->state); - } - -+static void bnxt_get_one_ring_err_stats(struct bnxt *bp, -+ struct bnxt_total_ring_err_stats *stats, -+ struct bnxt_cp_ring_info *cpr) -+{ -+ struct bnxt_sw_stats *sw_stats = &cpr->sw_stats; -+ u64 *hw_stats = cpr->stats.sw_stats; -+ -+ stats->rx_total_l4_csum_errors += sw_stats->rx.rx_l4_csum_errors; -+ stats->rx_total_resets += sw_stats->rx.rx_resets; -+ stats->rx_total_buf_errors += sw_stats->rx.rx_buf_errors; -+ stats->rx_total_oom_discards += sw_stats->rx.rx_oom_discards; -+ stats->rx_total_netpoll_discards += sw_stats->rx.rx_netpoll_discards; -+ stats->rx_total_ring_discards += -+ BNXT_GET_RING_STATS64(hw_stats, rx_discard_pkts); -+ stats->tx_total_ring_discards += -+ BNXT_GET_RING_STATS64(hw_stats, tx_discard_pkts); -+ stats->total_missed_irqs += sw_stats->cmn.missed_irqs; -+} -+ -+void bnxt_get_ring_err_stats(struct bnxt *bp, -+ struct bnxt_total_ring_err_stats *stats) -+{ -+ int i; -+ -+ for (i = 0; i < bp->cp_nr_rings; i++) -+ bnxt_get_one_ring_err_stats(bp, stats, &bp->bnapi[i]->cp_ring); -+} -+ - static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask) - { - struct net_device *dev = bp->dev; -@@ -13882,6 +13927,8 @@ static int bnxt_resume(struct device *device) - if (rc) - goto resume_exit; - -+ bnxt_clear_reservations(bp, true); -+ - if (bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, false)) { - rc = -ENODEV; - goto resume_exit; -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h -index 1d2588c92977e..111098b4b6062 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h -@@ -160,7 +160,7 @@ struct rx_cmp { - #define RX_CMP_FLAGS_ERROR (1 << 6) - #define RX_CMP_FLAGS_PLACEMENT (7 << 7) - #define RX_CMP_FLAGS_RSS_VALID (1 << 10) -- #define RX_CMP_FLAGS_UNUSED (1 << 11) -+ #define RX_CMP_FLAGS_PKT_METADATA_PRESENT (1 << 11) - #define RX_CMP_FLAGS_ITYPES_SHIFT 12 - #define RX_CMP_FLAGS_ITYPES_MASK 0xf000 - #define RX_CMP_FLAGS_ITYPE_UNKNOWN (0 << 12) -@@ -187,6 +187,12 @@ struct rx_cmp { - __le32 rx_cmp_rss_hash; - }; - -+#define BNXT_PTP_RX_TS_VALID(flags) \ -+ (((flags) & RX_CMP_FLAGS_ITYPES_MASK) == RX_CMP_FLAGS_ITYPE_PTP_W_TS) -+ -+#define BNXT_ALL_RX_TS_VALID(flags) \ -+ !((flags) & RX_CMP_FLAGS_PKT_METADATA_PRESENT) -+ - #define RX_CMP_HASH_VALID(rxcmp) \ - ((rxcmp)->rx_cmp_len_flags_type & cpu_to_le32(RX_CMP_FLAGS_RSS_VALID)) - -@@ -950,6 +956,17 @@ struct bnxt_sw_stats { - struct bnxt_cmn_sw_stats cmn; - }; - -+struct bnxt_total_ring_err_stats { -+ u64 rx_total_l4_csum_errors; -+ u64 rx_total_resets; -+ u64 rx_total_buf_errors; -+ u64 rx_total_oom_discards; -+ u64 rx_total_netpoll_discards; -+ u64 rx_total_ring_discards; -+ u64 tx_total_ring_discards; -+ u64 total_missed_irqs; -+}; -+ - struct bnxt_stats_mem { - u64 *sw_stats; - u64 *hw_masks; -@@ -2007,6 +2024,8 @@ struct bnxt { - u8 pri2cos_idx[8]; - u8 pri2cos_valid; - -+ struct bnxt_total_ring_err_stats ring_err_stats_prev; -+ - u16 hwrm_max_req_len; - u16 hwrm_max_ext_req_len; - unsigned int hwrm_cmd_timeout; -@@ -2330,7 +2349,9 @@ int bnxt_open_nic(struct bnxt *, bool, bool); - int bnxt_half_open_nic(struct bnxt *bp); - void bnxt_half_close_nic(struct bnxt *bp); - void bnxt_reenable_sriov(struct bnxt *bp); --int bnxt_close_nic(struct bnxt *, bool, bool); -+void bnxt_close_nic(struct bnxt *, bool, bool); -+void bnxt_get_ring_err_stats(struct bnxt *bp, -+ struct bnxt_total_ring_err_stats *stats); - int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words, - u32 *reg_buf); - void bnxt_fw_exception(struct bnxt *bp); -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c -index 8a6f788f62944..2bdebd9c069d8 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c -@@ -478,15 +478,8 @@ static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change, - return -ENODEV; - } - bnxt_ulp_stop(bp); -- if (netif_running(bp->dev)) { -- rc = bnxt_close_nic(bp, true, true); -- if (rc) { -- NL_SET_ERR_MSG_MOD(extack, "Failed to close"); -- dev_close(bp->dev); -- rtnl_unlock(); -- break; -- } -- } -+ if (netif_running(bp->dev)) -+ bnxt_close_nic(bp, true, true); - bnxt_vf_reps_free(bp); - rc = bnxt_hwrm_func_drv_unrgtr(bp); - if (rc) { -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c -index 89f046ce1373c..7260b4671ecca 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c -@@ -164,9 +164,8 @@ static int bnxt_set_coalesce(struct net_device *dev, - reset_coalesce: - if (test_bit(BNXT_STATE_OPEN, &bp->state)) { - if (update_stats) { -- rc = bnxt_close_nic(bp, true, false); -- if (!rc) -- rc = bnxt_open_nic(bp, true, false); -+ bnxt_close_nic(bp, true, false); -+ rc = bnxt_open_nic(bp, true, false); - } else { - rc = bnxt_hwrm_set_coal(bp); - } -@@ -956,12 +955,7 @@ static int bnxt_set_channels(struct net_device *dev, - * before PF unload - */ - } -- rc = bnxt_close_nic(bp, true, false); -- if (rc) { -- netdev_err(bp->dev, "Set channel failure rc :%x\n", -- rc); -- return rc; -- } -+ bnxt_close_nic(bp, true, false); - } - - if (sh) { -@@ -3634,12 +3628,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest, - bnxt_run_fw_tests(bp, test_mask, &test_results); - } else { - bnxt_ulp_stop(bp); -- rc = bnxt_close_nic(bp, true, false); -- if (rc) { -- etest->flags |= ETH_TEST_FL_FAILED; -- bnxt_ulp_start(bp, rc); -- return; -- } -+ bnxt_close_nic(bp, true, false); - bnxt_run_fw_tests(bp, test_mask, &test_results); - - buf[BNXT_MACLPBK_TEST_IDX] = 1; -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c -index 4faaa9a50f4bc..ae734314f8de5 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c -@@ -506,9 +506,8 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp) - - if (netif_running(bp->dev)) { - if (ptp->rx_filter == HWTSTAMP_FILTER_ALL) { -- rc = bnxt_close_nic(bp, false, false); -- if (!rc) -- rc = bnxt_open_nic(bp, false, false); -+ bnxt_close_nic(bp, false, false); -+ rc = bnxt_open_nic(bp, false, false); - } else { - bnxt_ptp_cfg_tstamp_filters(bp); - } -diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c -index b12152e2fca0a..a9e4e6464a04c 100644 ---- a/drivers/net/ethernet/emulex/benet/be_main.c -+++ b/drivers/net/ethernet/emulex/benet/be_main.c -@@ -1125,7 +1125,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, - struct be_wrb_params - *wrb_params) - { -- struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; -+ struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb); - unsigned int eth_hdr_len; - struct iphdr *ip; - -diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c -index c39b866e2582d..16d3c3610720b 100644 ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c -@@ -139,7 +139,8 @@ int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block, - err = dpsw_acl_add_entry(ethsw->mc_io, 0, ethsw->dpsw_handle, - filter_block->acl_id, acl_entry_cfg); - -- dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff), -+ dma_unmap_single(dev, acl_entry_cfg->key_iova, -+ DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, - DMA_TO_DEVICE); - if (err) { - dev_err(dev, "dpsw_acl_add_entry() failed %d\n", err); -@@ -181,8 +182,8 @@ dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block, - err = dpsw_acl_remove_entry(ethsw->mc_io, 0, ethsw->dpsw_handle, - block->acl_id, acl_entry_cfg); - -- dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff), -- DMA_TO_DEVICE); -+ dma_unmap_single(dev, acl_entry_cfg->key_iova, -+ DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, DMA_TO_DEVICE); - if (err) { - dev_err(dev, "dpsw_acl_remove_entry() failed %d\n", err); - kfree(cmd_buff); -diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -index 2b5909fa93cfa..b98ef4ba172f6 100644 ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -@@ -1978,9 +1978,6 @@ static int dpaa2_switch_port_attr_set_event(struct net_device *netdev, - return notifier_from_errno(err); - } - --static struct notifier_block dpaa2_switch_port_switchdev_nb; --static struct notifier_block dpaa2_switch_port_switchdev_blocking_nb; -- - static int dpaa2_switch_port_bridge_join(struct net_device *netdev, - struct net_device *upper_dev, - struct netlink_ext_ack *extack) -@@ -2023,9 +2020,7 @@ static int dpaa2_switch_port_bridge_join(struct net_device *netdev, - goto err_egress_flood; - - err = switchdev_bridge_port_offload(netdev, netdev, NULL, -- &dpaa2_switch_port_switchdev_nb, -- &dpaa2_switch_port_switchdev_blocking_nb, -- false, extack); -+ NULL, NULL, false, extack); - if (err) - goto err_switchdev_offload; - -@@ -2059,9 +2054,7 @@ static int dpaa2_switch_port_restore_rxvlan(struct net_device *vdev, int vid, vo - - static void dpaa2_switch_port_pre_bridge_leave(struct net_device *netdev) - { -- switchdev_bridge_port_unoffload(netdev, NULL, -- &dpaa2_switch_port_switchdev_nb, -- &dpaa2_switch_port_switchdev_blocking_nb); -+ switchdev_bridge_port_unoffload(netdev, NULL, NULL, NULL); - } - - static int dpaa2_switch_port_bridge_leave(struct net_device *netdev) -diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c -index 33226a22d8a4a..6d1b760022821 100644 ---- a/drivers/net/ethernet/freescale/fec_main.c -+++ b/drivers/net/ethernet/freescale/fec_main.c -@@ -3541,31 +3541,26 @@ static int fec_set_features(struct net_device *netdev, - return 0; - } - --static u16 fec_enet_get_raw_vlan_tci(struct sk_buff *skb) --{ -- struct vlan_ethhdr *vhdr; -- unsigned short vlan_TCI = 0; -- -- if (skb->protocol == htons(ETH_P_ALL)) { -- vhdr = (struct vlan_ethhdr *)(skb->data); -- vlan_TCI = ntohs(vhdr->h_vlan_TCI); -- } -- -- return vlan_TCI; --} -- - static u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb, - struct net_device *sb_dev) - { - struct fec_enet_private *fep = netdev_priv(ndev); -- u16 vlan_tag; -+ u16 vlan_tag = 0; - - if (!(fep->quirks & FEC_QUIRK_HAS_AVB)) - return netdev_pick_tx(ndev, skb, NULL); - -- vlan_tag = fec_enet_get_raw_vlan_tci(skb); -- if (!vlan_tag) -+ /* VLAN is present in the payload.*/ -+ if (eth_type_vlan(skb->protocol)) { -+ struct vlan_ethhdr *vhdr = skb_vlan_eth_hdr(skb); -+ -+ vlan_tag = ntohs(vhdr->h_vlan_TCI); -+ /* VLAN is present in the skb but not yet pushed in the payload.*/ -+ } else if (skb_vlan_tag_present(skb)) { -+ vlan_tag = skb->vlan_tci; -+ } else { - return vlan_tag; -+ } - - return fec_enet_vlan_pri_to_queue[vlan_tag >> 13]; - } -diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -index 5ad22b815b2f0..78d6752fe0519 100644 ---- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c -@@ -1532,7 +1532,7 @@ static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring, - if (unlikely(rc < 0)) - return rc; - -- vhdr = (struct vlan_ethhdr *)skb->data; -+ vhdr = skb_vlan_eth_hdr(skb); - vhdr->h_vlan_TCI |= cpu_to_be16((skb->priority << VLAN_PRIO_SHIFT) - & VLAN_PRIO_MASK); - -diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c -index 6d26ee8eefae9..94cf82668efaa 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c -@@ -2986,7 +2986,7 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb, - rc = skb_cow_head(skb, 0); - if (rc < 0) - return rc; -- vhdr = (struct vlan_ethhdr *)skb->data; -+ vhdr = skb_vlan_eth_hdr(skb); - vhdr->h_vlan_TCI = htons(tx_flags >> - I40E_TX_FLAGS_VLAN_SHIFT); - } else { -diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h -index 7389855fa307a..ee0871d929302 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf.h -+++ b/drivers/net/ethernet/intel/iavf/iavf.h -@@ -303,6 +303,7 @@ struct iavf_adapter { - #define IAVF_FLAG_QUEUES_DISABLED BIT(17) - #define IAVF_FLAG_SETUP_NETDEV_FEATURES BIT(18) - #define IAVF_FLAG_REINIT_MSIX_NEEDED BIT(20) -+#define IAVF_FLAG_FDIR_ENABLED BIT(21) - /* duplicates for common code */ - #define IAVF_FLAG_DCB_ENABLED 0 - /* flags for admin queue service task */ -diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -index 31e02624aca48..f4ac2b164b3e9 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c -@@ -1063,7 +1063,7 @@ iavf_get_ethtool_fdir_entry(struct iavf_adapter *adapter, - struct iavf_fdir_fltr *rule = NULL; - int ret = 0; - -- if (!FDIR_FLTR_SUPPORT(adapter)) -+ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) - return -EOPNOTSUPP; - - spin_lock_bh(&adapter->fdir_fltr_lock); -@@ -1205,7 +1205,7 @@ iavf_get_fdir_fltr_ids(struct iavf_adapter *adapter, struct ethtool_rxnfc *cmd, - unsigned int cnt = 0; - int val = 0; - -- if (!FDIR_FLTR_SUPPORT(adapter)) -+ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) - return -EOPNOTSUPP; - - cmd->data = IAVF_MAX_FDIR_FILTERS; -@@ -1397,7 +1397,7 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx - int count = 50; - int err; - -- if (!FDIR_FLTR_SUPPORT(adapter)) -+ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) - return -EOPNOTSUPP; - - if (fsp->flow_type & FLOW_MAC_EXT) -@@ -1438,12 +1438,16 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx - spin_lock_bh(&adapter->fdir_fltr_lock); - iavf_fdir_list_add_fltr(adapter, fltr); - adapter->fdir_active_fltr++; -- fltr->state = IAVF_FDIR_FLTR_ADD_REQUEST; -- adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER; -+ if (adapter->link_up) { -+ fltr->state = IAVF_FDIR_FLTR_ADD_REQUEST; -+ adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER; -+ } else { -+ fltr->state = IAVF_FDIR_FLTR_INACTIVE; -+ } - spin_unlock_bh(&adapter->fdir_fltr_lock); - -- mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); -- -+ if (adapter->link_up) -+ mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); - ret: - if (err && fltr) - kfree(fltr); -@@ -1465,7 +1469,7 @@ static int iavf_del_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx - struct iavf_fdir_fltr *fltr = NULL; - int err = 0; - -- if (!FDIR_FLTR_SUPPORT(adapter)) -+ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) - return -EOPNOTSUPP; - - spin_lock_bh(&adapter->fdir_fltr_lock); -@@ -1474,6 +1478,11 @@ static int iavf_del_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx - if (fltr->state == IAVF_FDIR_FLTR_ACTIVE) { - fltr->state = IAVF_FDIR_FLTR_DEL_REQUEST; - adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER; -+ } else if (fltr->state == IAVF_FDIR_FLTR_INACTIVE) { -+ list_del(&fltr->list); -+ kfree(fltr); -+ adapter->fdir_active_fltr--; -+ fltr = NULL; - } else { - err = -EBUSY; - } -@@ -1782,7 +1791,7 @@ static int iavf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, - ret = 0; - break; - case ETHTOOL_GRXCLSRLCNT: -- if (!FDIR_FLTR_SUPPORT(adapter)) -+ if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED)) - break; - spin_lock_bh(&adapter->fdir_fltr_lock); - cmd->rule_cnt = adapter->fdir_active_fltr; -diff --git a/drivers/net/ethernet/intel/iavf/iavf_fdir.h b/drivers/net/ethernet/intel/iavf/iavf_fdir.h -index 9eb9f73f6adf3..d31bd923ba8cb 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_fdir.h -+++ b/drivers/net/ethernet/intel/iavf/iavf_fdir.h -@@ -6,12 +6,25 @@ - - struct iavf_adapter; - --/* State of Flow Director filter */ -+/* State of Flow Director filter -+ * -+ * *_REQUEST states are used to mark filter to be sent to PF driver to perform -+ * an action (either add or delete filter). *_PENDING states are an indication -+ * that request was sent to PF and the driver is waiting for response. -+ * -+ * Both DELETE and DISABLE states are being used to delete a filter in PF. -+ * The difference is that after a successful response filter in DEL_PENDING -+ * state is being deleted from VF driver as well and filter in DIS_PENDING state -+ * is being changed to INACTIVE state. -+ */ - enum iavf_fdir_fltr_state_t { - IAVF_FDIR_FLTR_ADD_REQUEST, /* User requests to add filter */ - IAVF_FDIR_FLTR_ADD_PENDING, /* Filter pending add by the PF */ - IAVF_FDIR_FLTR_DEL_REQUEST, /* User requests to delete filter */ - IAVF_FDIR_FLTR_DEL_PENDING, /* Filter pending delete by the PF */ -+ IAVF_FDIR_FLTR_DIS_REQUEST, /* Filter scheduled to be disabled */ -+ IAVF_FDIR_FLTR_DIS_PENDING, /* Filter pending disable by the PF */ -+ IAVF_FDIR_FLTR_INACTIVE, /* Filter inactive on link down */ - IAVF_FDIR_FLTR_ACTIVE, /* Filter is active */ - }; - -diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c -index 4836bac2bd09d..b9c4b311cd625 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_main.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c -@@ -1368,18 +1368,20 @@ static void iavf_clear_cloud_filters(struct iavf_adapter *adapter) - **/ - static void iavf_clear_fdir_filters(struct iavf_adapter *adapter) - { -- struct iavf_fdir_fltr *fdir, *fdirtmp; -+ struct iavf_fdir_fltr *fdir; - - /* remove all Flow Director filters */ - spin_lock_bh(&adapter->fdir_fltr_lock); -- list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head, -- list) { -+ list_for_each_entry(fdir, &adapter->fdir_list_head, list) { - if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) { -- list_del(&fdir->list); -- kfree(fdir); -- adapter->fdir_active_fltr--; -- } else { -- fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST; -+ /* Cancel a request, keep filter as inactive */ -+ fdir->state = IAVF_FDIR_FLTR_INACTIVE; -+ } else if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING || -+ fdir->state == IAVF_FDIR_FLTR_ACTIVE) { -+ /* Disable filters which are active or have a pending -+ * request to PF to be added -+ */ -+ fdir->state = IAVF_FDIR_FLTR_DIS_REQUEST; - } - } - spin_unlock_bh(&adapter->fdir_fltr_lock); -@@ -4210,6 +4212,33 @@ static int iavf_setup_tc(struct net_device *netdev, enum tc_setup_type type, - } - } - -+/** -+ * iavf_restore_fdir_filters -+ * @adapter: board private structure -+ * -+ * Restore existing FDIR filters when VF netdev comes back up. -+ **/ -+static void iavf_restore_fdir_filters(struct iavf_adapter *adapter) -+{ -+ struct iavf_fdir_fltr *f; -+ -+ spin_lock_bh(&adapter->fdir_fltr_lock); -+ list_for_each_entry(f, &adapter->fdir_list_head, list) { -+ if (f->state == IAVF_FDIR_FLTR_DIS_REQUEST) { -+ /* Cancel a request, keep filter as active */ -+ f->state = IAVF_FDIR_FLTR_ACTIVE; -+ } else if (f->state == IAVF_FDIR_FLTR_DIS_PENDING || -+ f->state == IAVF_FDIR_FLTR_INACTIVE) { -+ /* Add filters which are inactive or have a pending -+ * request to PF to be deleted -+ */ -+ f->state = IAVF_FDIR_FLTR_ADD_REQUEST; -+ adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER; -+ } -+ } -+ spin_unlock_bh(&adapter->fdir_fltr_lock); -+} -+ - /** - * iavf_open - Called when a network interface is made active - * @netdev: network interface device structure -@@ -4277,8 +4306,9 @@ static int iavf_open(struct net_device *netdev) - - spin_unlock_bh(&adapter->mac_vlan_list_lock); - -- /* Restore VLAN filters that were removed with IFF_DOWN */ -+ /* Restore filters that were removed with IFF_DOWN */ - iavf_restore_filters(adapter); -+ iavf_restore_fdir_filters(adapter); - - iavf_configure(adapter); - -@@ -4415,6 +4445,49 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu) - return ret; - } - -+/** -+ * iavf_disable_fdir - disable Flow Director and clear existing filters -+ * @adapter: board private structure -+ **/ -+static void iavf_disable_fdir(struct iavf_adapter *adapter) -+{ -+ struct iavf_fdir_fltr *fdir, *fdirtmp; -+ bool del_filters = false; -+ -+ adapter->flags &= ~IAVF_FLAG_FDIR_ENABLED; -+ -+ /* remove all Flow Director filters */ -+ spin_lock_bh(&adapter->fdir_fltr_lock); -+ list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head, -+ list) { -+ if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST || -+ fdir->state == IAVF_FDIR_FLTR_INACTIVE) { -+ /* Delete filters not registered in PF */ -+ list_del(&fdir->list); -+ kfree(fdir); -+ adapter->fdir_active_fltr--; -+ } else if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING || -+ fdir->state == IAVF_FDIR_FLTR_DIS_REQUEST || -+ fdir->state == IAVF_FDIR_FLTR_ACTIVE) { -+ /* Filters registered in PF, schedule their deletion */ -+ fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST; -+ del_filters = true; -+ } else if (fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) { -+ /* Request to delete filter already sent to PF, change -+ * state to DEL_PENDING to delete filter after PF's -+ * response, not set as INACTIVE -+ */ -+ fdir->state = IAVF_FDIR_FLTR_DEL_PENDING; -+ } -+ } -+ spin_unlock_bh(&adapter->fdir_fltr_lock); -+ -+ if (del_filters) { -+ adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER; -+ mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); -+ } -+} -+ - #define NETIF_VLAN_OFFLOAD_FEATURES (NETIF_F_HW_VLAN_CTAG_RX | \ - NETIF_F_HW_VLAN_CTAG_TX | \ - NETIF_F_HW_VLAN_STAG_RX | \ -@@ -4437,6 +4510,13 @@ static int iavf_set_features(struct net_device *netdev, - iavf_set_vlan_offload_features(adapter, netdev->features, - features); - -+ if ((netdev->features & NETIF_F_NTUPLE) ^ (features & NETIF_F_NTUPLE)) { -+ if (features & NETIF_F_NTUPLE) -+ adapter->flags |= IAVF_FLAG_FDIR_ENABLED; -+ else -+ iavf_disable_fdir(adapter); -+ } -+ - return 0; - } - -@@ -4732,6 +4812,9 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev, - { - struct iavf_adapter *adapter = netdev_priv(netdev); - -+ if (!FDIR_FLTR_SUPPORT(adapter)) -+ features &= ~NETIF_F_NTUPLE; -+ - return iavf_fix_netdev_vlan_features(adapter, features); - } - -@@ -4849,6 +4932,12 @@ int iavf_process_config(struct iavf_adapter *adapter) - if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) - netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; - -+ if (FDIR_FLTR_SUPPORT(adapter)) { -+ netdev->hw_features |= NETIF_F_NTUPLE; -+ netdev->features |= NETIF_F_NTUPLE; -+ adapter->flags |= IAVF_FLAG_FDIR_ENABLED; -+ } -+ - netdev->priv_flags |= IFF_UNICAST_FLT; - - /* Do not turn on offloads when they are requested to be turned off. -diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c -index 5a66b05c03222..951ef350323a2 100644 ---- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c -+++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c -@@ -1752,8 +1752,8 @@ void iavf_add_fdir_filter(struct iavf_adapter *adapter) - **/ - void iavf_del_fdir_filter(struct iavf_adapter *adapter) - { -+ struct virtchnl_fdir_del f = {}; - struct iavf_fdir_fltr *fdir; -- struct virtchnl_fdir_del f; - bool process_fltr = false; - int len; - -@@ -1770,11 +1770,16 @@ void iavf_del_fdir_filter(struct iavf_adapter *adapter) - list_for_each_entry(fdir, &adapter->fdir_list_head, list) { - if (fdir->state == IAVF_FDIR_FLTR_DEL_REQUEST) { - process_fltr = true; -- memset(&f, 0, len); - f.vsi_id = fdir->vc_add_msg.vsi_id; - f.flow_id = fdir->flow_id; - fdir->state = IAVF_FDIR_FLTR_DEL_PENDING; - break; -+ } else if (fdir->state == IAVF_FDIR_FLTR_DIS_REQUEST) { -+ process_fltr = true; -+ f.vsi_id = fdir->vc_add_msg.vsi_id; -+ f.flow_id = fdir->flow_id; -+ fdir->state = IAVF_FDIR_FLTR_DIS_PENDING; -+ break; - } - } - spin_unlock_bh(&adapter->fdir_fltr_lock); -@@ -1918,6 +1923,48 @@ static void iavf_netdev_features_vlan_strip_set(struct net_device *netdev, - netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX; - } - -+/** -+ * iavf_activate_fdir_filters - Reactivate all FDIR filters after a reset -+ * @adapter: private adapter structure -+ * -+ * Called after a reset to re-add all FDIR filters and delete some of them -+ * if they were pending to be deleted. -+ */ -+static void iavf_activate_fdir_filters(struct iavf_adapter *adapter) -+{ -+ struct iavf_fdir_fltr *f, *ftmp; -+ bool add_filters = false; -+ -+ spin_lock_bh(&adapter->fdir_fltr_lock); -+ list_for_each_entry_safe(f, ftmp, &adapter->fdir_list_head, list) { -+ if (f->state == IAVF_FDIR_FLTR_ADD_REQUEST || -+ f->state == IAVF_FDIR_FLTR_ADD_PENDING || -+ f->state == IAVF_FDIR_FLTR_ACTIVE) { -+ /* All filters and requests have been removed in PF, -+ * restore them -+ */ -+ f->state = IAVF_FDIR_FLTR_ADD_REQUEST; -+ add_filters = true; -+ } else if (f->state == IAVF_FDIR_FLTR_DIS_REQUEST || -+ f->state == IAVF_FDIR_FLTR_DIS_PENDING) { -+ /* Link down state, leave filters as inactive */ -+ f->state = IAVF_FDIR_FLTR_INACTIVE; -+ } else if (f->state == IAVF_FDIR_FLTR_DEL_REQUEST || -+ f->state == IAVF_FDIR_FLTR_DEL_PENDING) { -+ /* Delete filters that were pending to be deleted, the -+ * list on PF is already cleared after a reset -+ */ -+ list_del(&f->list); -+ kfree(f); -+ adapter->fdir_active_fltr--; -+ } -+ } -+ spin_unlock_bh(&adapter->fdir_fltr_lock); -+ -+ if (add_filters) -+ adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER; -+} -+ - /** - * iavf_virtchnl_completion - * @adapter: adapter structure -@@ -2095,7 +2142,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, - spin_lock_bh(&adapter->fdir_fltr_lock); - list_for_each_entry(fdir, &adapter->fdir_list_head, - list) { -- if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING) { -+ if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING || -+ fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) { - fdir->state = IAVF_FDIR_FLTR_ACTIVE; - dev_info(&adapter->pdev->dev, "Failed to del Flow Director filter, error %s\n", - iavf_stat_str(&adapter->hw, -@@ -2232,6 +2280,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, - - spin_unlock_bh(&adapter->mac_vlan_list_lock); - -+ iavf_activate_fdir_filters(adapter); -+ - iavf_parse_vf_resource_msg(adapter); - - /* negotiated VIRTCHNL_VF_OFFLOAD_VLAN_V2, so wait for the -@@ -2421,7 +2471,9 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, - list_for_each_entry_safe(fdir, fdir_tmp, &adapter->fdir_list_head, - list) { - if (fdir->state == IAVF_FDIR_FLTR_DEL_PENDING) { -- if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS) { -+ if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS || -+ del_fltr->status == -+ VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) { - dev_info(&adapter->pdev->dev, "Flow Director filter with location %u is deleted\n", - fdir->loc); - list_del(&fdir->list); -@@ -2433,6 +2485,17 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, - del_fltr->status); - iavf_print_fdir_fltr(adapter, fdir); - } -+ } else if (fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) { -+ if (del_fltr->status == VIRTCHNL_FDIR_SUCCESS || -+ del_fltr->status == -+ VIRTCHNL_FDIR_FAILURE_RULE_NONEXIST) { -+ fdir->state = IAVF_FDIR_FLTR_INACTIVE; -+ } else { -+ fdir->state = IAVF_FDIR_FLTR_ACTIVE; -+ dev_info(&adapter->pdev->dev, "Failed to disable Flow Director filter with status: %d\n", -+ del_fltr->status); -+ iavf_print_fdir_fltr(adapter, fdir); -+ } - } - } - spin_unlock_bh(&adapter->fdir_fltr_lock); -diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c -index 6105419ae2d5f..9e0e13638c463 100644 ---- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c -+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c -@@ -8822,7 +8822,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, - - if (skb_cow_head(skb, 0)) - goto out_drop; -- vhdr = (struct vlan_ethhdr *)skb->data; -+ vhdr = skb_vlan_eth_hdr(skb); - vhdr->h_vlan_TCI = htons(tx_flags >> - IXGBE_TX_FLAGS_VLAN_SHIFT); - } else { -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c -index d609512998992..b9a4efb955333 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c -@@ -642,7 +642,7 @@ static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl) - - rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq"); - if (!rvu_dl->devlink_wq) -- goto err; -+ return -ENOMEM; - - INIT_WORK(&rvu_reporters->intr_work, rvu_nix_intr_work); - INIT_WORK(&rvu_reporters->gen_work, rvu_nix_gen_work); -@@ -650,9 +650,6 @@ static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl) - INIT_WORK(&rvu_reporters->ras_work, rvu_nix_ras_work); - - return 0; --err: -- rvu_nix_health_reporters_destroy(rvu_dl); -- return -ENOMEM; - } - - static int rvu_nix_health_reporters_create(struct rvu_devlink *rvu_dl) -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -index f65805860c8d4..0bcf3e5592806 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c -@@ -671,6 +671,7 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, - int blkaddr, ucast_idx, index; - struct nix_rx_action action = { 0 }; - u64 relaxed_mask; -+ u8 flow_key_alg; - - if (!hw->cap.nix_rx_multicast && is_cgx_vf(rvu, pcifunc)) - return; -@@ -701,6 +702,8 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, - action.op = NIX_RX_ACTIONOP_UCAST; - } - -+ flow_key_alg = action.flow_key_alg; -+ - /* RX_ACTION set to MCAST for CGX PF's */ - if (hw->cap.nix_rx_multicast && pfvf->use_mce_list && - is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) { -@@ -740,7 +743,7 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, - req.vf = pcifunc; - req.index = action.index; - req.match_id = action.match_id; -- req.flow_key_alg = action.flow_key_alg; -+ req.flow_key_alg = flow_key_alg; - - rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); - } -@@ -854,6 +857,7 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, - u8 mac_addr[ETH_ALEN] = { 0 }; - struct nix_rx_action action = { 0 }; - struct rvu_pfvf *pfvf; -+ u8 flow_key_alg; - u16 vf_func; - - /* Only CGX PF/VF can add allmulticast entry */ -@@ -888,6 +892,7 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, - *(u64 *)&action = npc_get_mcam_action(rvu, mcam, - blkaddr, ucast_idx); - -+ flow_key_alg = action.flow_key_alg; - if (action.op != NIX_RX_ACTIONOP_RSS) { - *(u64 *)&action = 0; - action.op = NIX_RX_ACTIONOP_UCAST; -@@ -924,7 +929,7 @@ void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, - req.vf = pcifunc | vf_func; - req.index = action.index; - req.match_id = action.match_id; -- req.flow_key_alg = action.flow_key_alg; -+ req.flow_key_alg = flow_key_alg; - - rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); - } -@@ -990,11 +995,38 @@ static void npc_update_vf_flow_entry(struct rvu *rvu, struct npc_mcam *mcam, - mutex_unlock(&mcam->lock); - } - -+static void npc_update_rx_action_with_alg_idx(struct rvu *rvu, struct nix_rx_action action, -+ struct rvu_pfvf *pfvf, int mcam_index, int blkaddr, -+ int alg_idx) -+ -+{ -+ struct npc_mcam *mcam = &rvu->hw->mcam; -+ struct rvu_hwinfo *hw = rvu->hw; -+ int bank, op_rss; -+ -+ if (!is_mcam_entry_enabled(rvu, mcam, blkaddr, mcam_index)) -+ return; -+ -+ op_rss = (!hw->cap.nix_rx_multicast || !pfvf->use_mce_list); -+ -+ bank = npc_get_bank(mcam, mcam_index); -+ mcam_index &= (mcam->banksize - 1); -+ -+ /* If Rx action is MCAST update only RSS algorithm index */ -+ if (!op_rss) { -+ *(u64 *)&action = rvu_read64(rvu, blkaddr, -+ NPC_AF_MCAMEX_BANKX_ACTION(mcam_index, bank)); -+ -+ action.flow_key_alg = alg_idx; -+ } -+ rvu_write64(rvu, blkaddr, -+ NPC_AF_MCAMEX_BANKX_ACTION(mcam_index, bank), *(u64 *)&action); -+} -+ - void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, - int group, int alg_idx, int mcam_index) - { - struct npc_mcam *mcam = &rvu->hw->mcam; -- struct rvu_hwinfo *hw = rvu->hw; - struct nix_rx_action action; - int blkaddr, index, bank; - struct rvu_pfvf *pfvf; -@@ -1050,15 +1082,16 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, - /* If PF's promiscuous entry is enabled, - * Set RSS action for that entry as well - */ -- if ((!hw->cap.nix_rx_multicast || !pfvf->use_mce_list) && -- is_mcam_entry_enabled(rvu, mcam, blkaddr, index)) { -- bank = npc_get_bank(mcam, index); -- index &= (mcam->banksize - 1); -+ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, -+ alg_idx); - -- rvu_write64(rvu, blkaddr, -- NPC_AF_MCAMEX_BANKX_ACTION(index, bank), -- *(u64 *)&action); -- } -+ index = npc_get_nixlf_mcam_index(mcam, pcifunc, -+ nixlf, NIXLF_ALLMULTI_ENTRY); -+ /* If PF's allmulti entry is enabled, -+ * Set RSS action for that entry as well -+ */ -+ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, -+ alg_idx); - } - - void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -index 55807e2043edf..a2d8ac6204054 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c -@@ -1638,6 +1638,21 @@ static void otx2_free_hw_resources(struct otx2_nic *pf) - mutex_unlock(&mbox->lock); - } - -+static bool otx2_promisc_use_mce_list(struct otx2_nic *pfvf) -+{ -+ int vf; -+ -+ /* The AF driver will determine whether to allow the VF netdev or not */ -+ if (is_otx2_vf(pfvf->pcifunc)) -+ return true; -+ -+ /* check if there are any trusted VFs associated with the PF netdev */ -+ for (vf = 0; vf < pci_num_vf(pfvf->pdev); vf++) -+ if (pfvf->vf_configs[vf].trusted) -+ return true; -+ return false; -+} -+ - static void otx2_do_set_rx_mode(struct otx2_nic *pf) - { - struct net_device *netdev = pf->netdev; -@@ -1670,7 +1685,8 @@ static void otx2_do_set_rx_mode(struct otx2_nic *pf) - if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST)) - req->mode |= NIX_RX_MODE_ALLMULTI; - -- req->mode |= NIX_RX_MODE_USE_MCE; -+ if (otx2_promisc_use_mce_list(pf)) -+ req->mode |= NIX_RX_MODE_USE_MCE; - - otx2_sync_mbox_msg(&pf->mbox); - mutex_unlock(&pf->mbox.lock); -@@ -2634,11 +2650,14 @@ static int otx2_ndo_set_vf_trust(struct net_device *netdev, int vf, - pf->vf_configs[vf].trusted = enable; - rc = otx2_set_vf_permissions(pf, vf, OTX2_TRUSTED_VF); - -- if (rc) -+ if (rc) { - pf->vf_configs[vf].trusted = !enable; -- else -+ } else { - netdev_info(pf->netdev, "VF %d is %strusted\n", - vf, enable ? "" : "not "); -+ otx2_set_rx_mode(netdev); -+ } -+ - return rc; - } - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h -index bc76fe6b06230..0ee456480a488 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en.h -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h -@@ -847,6 +847,7 @@ enum { - MLX5E_STATE_DESTROYING, - MLX5E_STATE_XDP_TX_ENABLED, - MLX5E_STATE_XDP_ACTIVE, -+ MLX5E_STATE_CHANNELS_ACTIVE, - }; - - struct mlx5e_modify_sq_param { -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -index 42e6f2fcf5f59..9910a0480f589 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -@@ -2586,6 +2586,7 @@ void mlx5e_close_channels(struct mlx5e_channels *chs) - { - int i; - -+ ASSERT_RTNL(); - if (chs->ptp) { - mlx5e_ptp_close(chs->ptp); - chs->ptp = NULL; -@@ -2865,17 +2866,29 @@ void mlx5e_activate_priv_channels(struct mlx5e_priv *priv) - if (mlx5e_is_vport_rep(priv)) - mlx5e_rep_activate_channels(priv); - -+ set_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state); -+ - mlx5e_wait_channels_min_rx_wqes(&priv->channels); - - if (priv->rx_res) - mlx5e_rx_res_channels_activate(priv->rx_res, &priv->channels); - } - -+static void mlx5e_cancel_tx_timeout_work(struct mlx5e_priv *priv) -+{ -+ WARN_ON_ONCE(test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)); -+ if (current_work() != &priv->tx_timeout_work) -+ cancel_work_sync(&priv->tx_timeout_work); -+} -+ - void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv) - { - if (priv->rx_res) - mlx5e_rx_res_channels_deactivate(priv->rx_res); - -+ clear_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state); -+ mlx5e_cancel_tx_timeout_work(priv); -+ - if (mlx5e_is_vport_rep(priv)) - mlx5e_rep_deactivate_channels(priv); - -@@ -4617,8 +4630,17 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) - struct net_device *netdev = priv->netdev; - int i; - -- rtnl_lock(); -- mutex_lock(&priv->state_lock); -+ /* Take rtnl_lock to ensure no change in netdev->real_num_tx_queues -+ * through this flow. However, channel closing flows have to wait for -+ * this work to finish while holding rtnl lock too. So either get the -+ * lock or find that channels are being closed for other reason and -+ * this work is not relevant anymore. -+ */ -+ while (!rtnl_trylock()) { -+ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)) -+ return; -+ msleep(20); -+ } - - if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) - goto unlock; -@@ -4637,7 +4659,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) - } - - unlock: -- mutex_unlock(&priv->state_lock); - rtnl_unlock(); - } - -diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -index de8d54b23f738..c005a9df59d1c 100644 ---- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -@@ -1862,7 +1862,7 @@ netxen_tso_check(struct net_device *netdev, - - if (protocol == cpu_to_be16(ETH_P_8021Q)) { - -- vh = (struct vlan_ethhdr *)skb->data; -+ vh = skb_vlan_eth_hdr(skb); - protocol = vh->h_vlan_encapsulated_proto; - flags = FLAGS_VLAN_TAGGED; - -diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c -index 65e20693c549e..33f4f58ee51c6 100644 ---- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c -+++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c -@@ -933,6 +933,7 @@ static void qed_ilt_shadow_free(struct qed_hwfn *p_hwfn) - p_dma->virt_addr = NULL; - } - kfree(p_mngr->ilt_shadow); -+ p_mngr->ilt_shadow = NULL; - } - - static int qed_ilt_blk_alloc(struct qed_hwfn *p_hwfn, -diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c -index 92930a055cbcc..41894d154013b 100644 ---- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c -+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c -@@ -318,7 +318,7 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, - - if (adapter->flags & QLCNIC_VLAN_FILTERING) { - if (protocol == ETH_P_8021Q) { -- vh = (struct vlan_ethhdr *)skb->data; -+ vh = skb_vlan_eth_hdr(skb); - vlan_id = ntohs(vh->h_vlan_TCI); - } else if (skb_vlan_tag_present(skb)) { - vlan_id = skb_vlan_tag_get(skb); -@@ -468,7 +468,7 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter, - u32 producer = tx_ring->producer; - - if (protocol == ETH_P_8021Q) { -- vh = (struct vlan_ethhdr *)skb->data; -+ vh = skb_vlan_eth_hdr(skb); - flags = QLCNIC_FLAGS_VLAN_TAGGED; - vlan_tci = ntohs(vh->h_vlan_TCI); - protocol = ntohs(vh->h_vlan_encapsulated_proto); -diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c -index f62c39544e086..a739c06ede4e7 100644 ---- a/drivers/net/ethernet/qualcomm/qca_debug.c -+++ b/drivers/net/ethernet/qualcomm/qca_debug.c -@@ -30,6 +30,8 @@ - - #define QCASPI_MAX_REGS 0x20 - -+#define QCASPI_RX_MAX_FRAMES 4 -+ - static const u16 qcaspi_spi_regs[] = { - SPI_REG_BFR_SIZE, - SPI_REG_WRBUF_SPC_AVA, -@@ -252,9 +254,9 @@ qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, - { - struct qcaspi *qca = netdev_priv(dev); - -- ring->rx_max_pending = 4; -+ ring->rx_max_pending = QCASPI_RX_MAX_FRAMES; - ring->tx_max_pending = TX_RING_MAX_LEN; -- ring->rx_pending = 4; -+ ring->rx_pending = QCASPI_RX_MAX_FRAMES; - ring->tx_pending = qca->txr.count; - } - -@@ -263,22 +265,21 @@ qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, - struct kernel_ethtool_ringparam *kernel_ring, - struct netlink_ext_ack *extack) - { -- const struct net_device_ops *ops = dev->netdev_ops; - struct qcaspi *qca = netdev_priv(dev); - -- if ((ring->rx_pending) || -+ if (ring->rx_pending != QCASPI_RX_MAX_FRAMES || - (ring->rx_mini_pending) || - (ring->rx_jumbo_pending)) - return -EINVAL; - -- if (netif_running(dev)) -- ops->ndo_stop(dev); -+ if (qca->spi_thread) -+ kthread_park(qca->spi_thread); - - qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN); - qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN); - -- if (netif_running(dev)) -- ops->ndo_open(dev); -+ if (qca->spi_thread) -+ kthread_unpark(qca->spi_thread); - - return 0; - } -diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c -index 4a1b94e5a8ea9..82f5173a2cfd5 100644 ---- a/drivers/net/ethernet/qualcomm/qca_spi.c -+++ b/drivers/net/ethernet/qualcomm/qca_spi.c -@@ -581,6 +581,18 @@ qcaspi_spi_thread(void *data) - netdev_info(qca->net_dev, "SPI thread created\n"); - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); -+ if (kthread_should_park()) { -+ netif_tx_disable(qca->net_dev); -+ netif_carrier_off(qca->net_dev); -+ qcaspi_flush_tx_ring(qca); -+ kthread_parkme(); -+ if (qca->sync == QCASPI_SYNC_READY) { -+ netif_carrier_on(qca->net_dev); -+ netif_wake_queue(qca->net_dev); -+ } -+ continue; -+ } -+ - if ((qca->intr_req == qca->intr_svc) && - !qca->txr.skb[qca->txr.head]) - schedule(); -@@ -609,11 +621,17 @@ qcaspi_spi_thread(void *data) - if (intr_cause & SPI_INT_CPU_ON) { - qcaspi_qca7k_sync(qca, QCASPI_EVENT_CPUON); - -+ /* Frame decoding in progress */ -+ if (qca->frm_handle.state != qca->frm_handle.init) -+ qca->net_dev->stats.rx_dropped++; -+ -+ qcafrm_fsm_init_spi(&qca->frm_handle); -+ qca->stats.device_reset++; -+ - /* not synced. */ - if (qca->sync != QCASPI_SYNC_READY) - continue; - -- qca->stats.device_reset++; - netif_wake_queue(qca->net_dev); - netif_carrier_on(qca->net_dev); - } -diff --git a/drivers/net/ethernet/sfc/tx_tso.c b/drivers/net/ethernet/sfc/tx_tso.c -index 898e5c61d9086..d381d8164f07c 100644 ---- a/drivers/net/ethernet/sfc/tx_tso.c -+++ b/drivers/net/ethernet/sfc/tx_tso.c -@@ -147,7 +147,7 @@ static __be16 efx_tso_check_protocol(struct sk_buff *skb) - EFX_WARN_ON_ONCE_PARANOID(((struct ethhdr *)skb->data)->h_proto != - protocol); - if (protocol == htons(ETH_P_8021Q)) { -- struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; -+ struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb); - - protocol = veh->h_vlan_encapsulated_proto; - } -diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig -index 31ff351740342..58091ee2bfe60 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/Kconfig -+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig -@@ -256,7 +256,7 @@ config DWMAC_INTEL - config DWMAC_LOONGSON - tristate "Loongson PCI DWMAC support" - default MACH_LOONGSON64 -- depends on STMMAC_ETH && PCI -+ depends on (MACH_LOONGSON64 || COMPILE_TEST) && STMMAC_ETH && PCI - depends on COMMON_CLK - help - This selects the LOONGSON PCI bus support for the stmmac driver, -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c -index a25c187d31853..49c7aa86faaa8 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c -@@ -68,17 +68,15 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id - if (!plat) - return -ENOMEM; - -+ plat->mdio_bus_data = devm_kzalloc(&pdev->dev, -+ sizeof(*plat->mdio_bus_data), -+ GFP_KERNEL); -+ if (!plat->mdio_bus_data) -+ return -ENOMEM; -+ - plat->mdio_node = of_get_child_by_name(np, "mdio"); - if (plat->mdio_node) { - dev_info(&pdev->dev, "Found MDIO subnode\n"); -- -- plat->mdio_bus_data = devm_kzalloc(&pdev->dev, -- sizeof(*plat->mdio_bus_data), -- GFP_KERNEL); -- if (!plat->mdio_bus_data) { -- ret = -ENOMEM; -- goto err_put_node; -- } - plat->mdio_bus_data->needs_reset = true; - } - -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index 69aac8ed84f67..deb6e95a1bca6 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -4566,13 +4566,10 @@ dma_map_err: - - static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) - { -- struct vlan_ethhdr *veth; -- __be16 vlan_proto; -+ struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb); -+ __be16 vlan_proto = veth->h_vlan_proto; - u16 vlanid; - -- veth = (struct vlan_ethhdr *)skb->data; -- vlan_proto = veth->h_vlan_proto; -- - if ((vlan_proto == htons(ETH_P_8021Q) && - dev->features & NETIF_F_HW_VLAN_CTAG_RX) || - (vlan_proto == htons(ETH_P_8021AD) && -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c -index 5f177ea807258..379fc887ddf46 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c -@@ -483,7 +483,11 @@ int stmmac_mdio_register(struct net_device *ndev) - new_bus->parent = priv->device; - - err = of_mdiobus_register(new_bus, mdio_node); -- if (err != 0) { -+ if (err == -ENODEV) { -+ err = 0; -+ dev_info(dev, "MDIO bus is disabled\n"); -+ goto bus_register_fail; -+ } else if (err) { - dev_err_probe(dev, err, "Cannot register the MDIO bus\n"); - goto bus_register_fail; - } -diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c -index 556b2d1cd2aca..293eaf6b3ec9e 100644 ---- a/drivers/net/team/team.c -+++ b/drivers/net/team/team.c -@@ -285,8 +285,10 @@ static int __team_options_register(struct team *team, - return 0; - - inst_rollback: -- for (i--; i >= 0; i--) -+ for (i--; i >= 0; i--) { - __team_option_inst_del_option(team, dst_opts[i]); -+ list_del(&dst_opts[i]->list); -+ } - - i = option_count; - alloc_rollback: -diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c -index a017e9de2119d..7b8afa589a53c 100644 ---- a/drivers/net/usb/aqc111.c -+++ b/drivers/net/usb/aqc111.c -@@ -1079,17 +1079,17 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - u16 pkt_count = 0; - u64 desc_hdr = 0; - u16 vlan_tag = 0; -- u32 skb_len = 0; -+ u32 skb_len; - - if (!skb) - goto err; - -- if (skb->len == 0) -+ skb_len = skb->len; -+ if (skb_len < sizeof(desc_hdr)) - goto err; - -- skb_len = skb->len; - /* RX Descriptor Header */ -- skb_trim(skb, skb->len - sizeof(desc_hdr)); -+ skb_trim(skb, skb_len - sizeof(desc_hdr)); - desc_hdr = le64_to_cpup((u64 *)skb_tail_pointer(skb)); - - /* Check these packets */ -diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c -index 4fb981b8732ef..2d82481d34e6b 100644 ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -1288,6 +1288,7 @@ static const struct usb_device_id products[] = { - {QMI_FIXED_INTF(0x19d2, 0x0168, 4)}, - {QMI_FIXED_INTF(0x19d2, 0x0176, 3)}, - {QMI_FIXED_INTF(0x19d2, 0x0178, 3)}, -+ {QMI_FIXED_INTF(0x19d2, 0x0189, 4)}, /* ZTE MF290 */ - {QMI_FIXED_INTF(0x19d2, 0x0191, 4)}, /* ZTE EuFi890 */ - {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */ - {QMI_FIXED_INTF(0x19d2, 0x0200, 1)}, -diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c -index 4d833781294a4..958a02b19554d 100644 ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -8288,43 +8288,6 @@ static bool rtl_check_vendor_ok(struct usb_interface *intf) - return true; - } - --static bool rtl_vendor_mode(struct usb_interface *intf) --{ -- struct usb_host_interface *alt = intf->cur_altsetting; -- struct usb_device *udev; -- struct usb_host_config *c; -- int i, num_configs; -- -- if (alt->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) -- return rtl_check_vendor_ok(intf); -- -- /* The vendor mode is not always config #1, so to find it out. */ -- udev = interface_to_usbdev(intf); -- c = udev->config; -- num_configs = udev->descriptor.bNumConfigurations; -- if (num_configs < 2) -- return false; -- -- for (i = 0; i < num_configs; (i++, c++)) { -- struct usb_interface_descriptor *desc = NULL; -- -- if (c->desc.bNumInterfaces > 0) -- desc = &c->intf_cache[0]->altsetting->desc; -- else -- continue; -- -- if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) { -- usb_driver_set_configuration(udev, c->desc.bConfigurationValue); -- break; -- } -- } -- -- if (i == num_configs) -- dev_err(&intf->dev, "Unexpected Device\n"); -- -- return false; --} -- - static int rtl8152_pre_reset(struct usb_interface *intf) - { - struct r8152 *tp = usb_get_intfdata(intf); -@@ -9556,9 +9519,8 @@ static int rtl_fw_init(struct r8152 *tp) - return 0; - } - --u8 rtl8152_get_version(struct usb_interface *intf) -+static u8 __rtl_get_hw_ver(struct usb_device *udev) - { -- struct usb_device *udev = interface_to_usbdev(intf); - u32 ocp_data = 0; - __le32 *tmp; - u8 version; -@@ -9628,10 +9590,19 @@ u8 rtl8152_get_version(struct usb_interface *intf) - break; - default: - version = RTL_VER_UNKNOWN; -- dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); -+ dev_info(&udev->dev, "Unknown version 0x%04x\n", ocp_data); - break; - } - -+ return version; -+} -+ -+u8 rtl8152_get_version(struct usb_interface *intf) -+{ -+ u8 version; -+ -+ version = __rtl_get_hw_ver(interface_to_usbdev(intf)); -+ - dev_dbg(&intf->dev, "Detected version 0x%04x\n", version); - - return version; -@@ -9675,7 +9646,10 @@ static int rtl8152_probe(struct usb_interface *intf, - if (version == RTL_VER_UNKNOWN) - return -ENODEV; - -- if (!rtl_vendor_mode(intf)) -+ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) -+ return -ENODEV; -+ -+ if (!rtl_check_vendor_ok(intf)) - return -ENODEV; - - usb_reset_device(udev); -@@ -9875,43 +9849,37 @@ static void rtl8152_disconnect(struct usb_interface *intf) - } - } - --#define REALTEK_USB_DEVICE(vend, prod) { \ -- USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC), \ --}, \ --{ \ -- USB_DEVICE_AND_INTERFACE_INFO(vend, prod, USB_CLASS_COMM, \ -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), \ --} -- - /* table of devices that work with this driver */ - static const struct usb_device_id rtl8152_table[] = { - /* Realtek */ -- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8050), -- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8053), -- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8152), -- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153), -- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8155), -- REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8156), -+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8050) }, -+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8053) }, -+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8152) }, -+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8153) }, -+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8155) }, -+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x8156) }, - - /* Microsoft */ -- REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab), -- REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6), -- REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927), -- REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0c5e), -- REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3054), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3069), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3082), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x721e), -- REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387), -- REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041), -- REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff), -- REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601), -+ { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab) }, -+ { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6) }, -+ { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927) }, -+ { USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0c5e) }, -+ { USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x304f) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3054) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3062) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3069) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x3082) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x7205) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x720c) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x7214) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0x721e) }, -+ { USB_DEVICE(VENDOR_ID_LENOVO, 0xa387) }, -+ { USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041) }, -+ { USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff) }, -+ { USB_DEVICE(VENDOR_ID_TPLINK, 0x0601) }, -+ { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, -+ { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, - {} - }; - -@@ -9931,7 +9899,68 @@ static struct usb_driver rtl8152_driver = { - .disable_hub_initiated_lpm = 1, - }; - --module_usb_driver(rtl8152_driver); -+static int rtl8152_cfgselector_probe(struct usb_device *udev) -+{ -+ struct usb_host_config *c; -+ int i, num_configs; -+ -+ /* Switch the device to vendor mode, if and only if the vendor mode -+ * driver supports it. -+ */ -+ if (__rtl_get_hw_ver(udev) == RTL_VER_UNKNOWN) -+ return 0; -+ -+ /* The vendor mode is not always config #1, so to find it out. */ -+ c = udev->config; -+ num_configs = udev->descriptor.bNumConfigurations; -+ for (i = 0; i < num_configs; (i++, c++)) { -+ struct usb_interface_descriptor *desc = NULL; -+ -+ if (!c->desc.bNumInterfaces) -+ continue; -+ desc = &c->intf_cache[0]->altsetting->desc; -+ if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) -+ break; -+ } -+ -+ if (i == num_configs) -+ return -ENODEV; -+ -+ if (usb_set_configuration(udev, c->desc.bConfigurationValue)) { -+ dev_err(&udev->dev, "Failed to set configuration %d\n", -+ c->desc.bConfigurationValue); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_driver rtl8152_cfgselector_driver = { -+ .name = MODULENAME "-cfgselector", -+ .probe = rtl8152_cfgselector_probe, -+ .id_table = rtl8152_table, -+ .generic_subclass = 1, -+ .supports_autosuspend = 1, -+}; -+ -+static int __init rtl8152_driver_init(void) -+{ -+ int ret; -+ -+ ret = usb_register_device_driver(&rtl8152_cfgselector_driver, THIS_MODULE); -+ if (ret) -+ return ret; -+ return usb_register(&rtl8152_driver); -+} -+ -+static void __exit rtl8152_driver_exit(void) -+{ -+ usb_deregister(&rtl8152_driver); -+ usb_deregister_device_driver(&rtl8152_cfgselector_driver); -+} -+ -+module_init(rtl8152_driver_init); -+module_exit(rtl8152_driver_exit); - - MODULE_AUTHOR(DRIVER_AUTHOR); - MODULE_DESCRIPTION(DRIVER_DESC); -diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c -index 9dfd3d0293054..69aef668f1056 100644 ---- a/drivers/nvme/host/auth.c -+++ b/drivers/nvme/host/auth.c -@@ -834,6 +834,8 @@ static void nvme_queue_auth_work(struct work_struct *work) - } - - fail2: -+ if (chap->status == 0) -+ chap->status = NVME_AUTH_DHCHAP_FAILURE_FAILED; - dev_dbg(ctrl->device, "%s: qid %d send failure2, status %x\n", - __func__, chap->qid, chap->status); - tl = nvme_auth_set_dhchap_failure2_data(ctrl, chap); -diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c -index 5b156c5bc04a5..eb7c87b344b8f 100644 ---- a/drivers/nvme/host/core.c -+++ b/drivers/nvme/host/core.c -@@ -1845,16 +1845,18 @@ set_pi: - return ret; - } - --static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) -+static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) - { - struct nvme_ctrl *ctrl = ns->ctrl; -+ int ret; - -- if (nvme_init_ms(ns, id)) -- return; -+ ret = nvme_init_ms(ns, id); -+ if (ret) -+ return ret; - - ns->features &= ~(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS); - if (!ns->ms || !(ctrl->ops->flags & NVME_F_METADATA_SUPPORTED)) -- return; -+ return 0; - - if (ctrl->ops->flags & NVME_F_FABRICS) { - /* -@@ -1863,7 +1865,7 @@ static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) - * remap the separate metadata buffer from the block layer. - */ - if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT))) -- return; -+ return 0; - - ns->features |= NVME_NS_EXT_LBAS; - -@@ -1890,6 +1892,7 @@ static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id) - else - ns->features |= NVME_NS_METADATA_SUPPORTED; - } -+ return 0; - } - - static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, -@@ -2070,7 +2073,11 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns, - ns->lba_shift = id->lbaf[lbaf].ds; - nvme_set_queue_limits(ns->ctrl, ns->queue); - -- nvme_configure_metadata(ns, id); -+ ret = nvme_configure_metadata(ns, id); -+ if (ret < 0) { -+ blk_mq_unfreeze_queue(ns->disk->queue); -+ goto out; -+ } - nvme_set_chunk_sectors(ns, id); - nvme_update_disk_info(ns->disk, ns, id); - -diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c -index fe0f732f6e434..a860f25473df6 100644 ---- a/drivers/pci/controller/pci-loongson.c -+++ b/drivers/pci/controller/pci-loongson.c -@@ -80,13 +80,49 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_LPC, system_bus_quirk); - -+/* -+ * Some Loongson PCIe ports have hardware limitations on their Maximum Read -+ * Request Size. They can't handle anything larger than this. Sane -+ * firmware will set proper MRRS at boot, so we only need no_inc_mrrs for -+ * bridges. However, some MIPS Loongson firmware doesn't set MRRS properly, -+ * so we have to enforce maximum safe MRRS, which is 256 bytes. -+ */ -+#ifdef CONFIG_MIPS -+static void loongson_set_min_mrrs_quirk(struct pci_dev *pdev) -+{ -+ struct pci_bus *bus = pdev->bus; -+ struct pci_dev *bridge; -+ static const struct pci_device_id bridge_devids[] = { -+ { PCI_VDEVICE(LOONGSON, DEV_LS2K_PCIE_PORT0) }, -+ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT0) }, -+ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT1) }, -+ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT2) }, -+ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT3) }, -+ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT4) }, -+ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT5) }, -+ { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT6) }, -+ { 0, }, -+ }; -+ -+ /* look for the matching bridge */ -+ while (!pci_is_root_bus(bus)) { -+ bridge = bus->self; -+ bus = bus->parent; -+ -+ if (pci_match_id(bridge_devids, bridge)) { -+ if (pcie_get_readrq(pdev) > 256) { -+ pci_info(pdev, "limiting MRRS to 256\n"); -+ pcie_set_readrq(pdev, 256); -+ } -+ break; -+ } -+ } -+} -+DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_set_min_mrrs_quirk); -+#endif -+ - static void loongson_mrrs_quirk(struct pci_dev *pdev) - { -- /* -- * Some Loongson PCIe ports have h/w limitations of maximum read -- * request size. They can't handle anything larger than this. So -- * force this limit on any devices attached under these ports. -- */ - struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus); - - bridge->no_inc_mrrs = 1; -diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c -index ea0195337bab9..6efa3d8db9a56 100644 ---- a/drivers/pci/hotplug/acpiphp_glue.c -+++ b/drivers/pci/hotplug/acpiphp_glue.c -@@ -504,15 +504,12 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge) - if (pass && dev->subordinate) { - check_hotplug_bridge(slot, dev); - pcibios_resource_survey_bus(dev->subordinate); -- if (pci_is_root_bus(bus)) -- __pci_bus_size_bridges(dev->subordinate, &add_list); -+ __pci_bus_size_bridges(dev->subordinate, -+ &add_list); - } - } - } -- if (pci_is_root_bus(bus)) -- __pci_bus_assign_resources(bus, &add_list, NULL); -- else -- pci_assign_unassigned_bridge_resources(bus->self); -+ __pci_bus_assign_resources(bus, &add_list, NULL); - } - - acpiphp_sanitize_bus(bus); -diff --git a/drivers/platform/x86/intel/telemetry/core.c b/drivers/platform/x86/intel/telemetry/core.c -index fdf55b5d69480..e4be40f73eebf 100644 ---- a/drivers/platform/x86/intel/telemetry/core.c -+++ b/drivers/platform/x86/intel/telemetry/core.c -@@ -102,7 +102,7 @@ static const struct telemetry_core_ops telm_defpltops = { - /** - * telemetry_update_events() - Update telemetry Configuration - * @pss_evtconfig: PSS related config. No change if num_evts = 0. -- * @pss_evtconfig: IOSS related config. No change if num_evts = 0. -+ * @ioss_evtconfig: IOSS related config. No change if num_evts = 0. - * - * This API updates the IOSS & PSS Telemetry configuration. Old config - * is overwritten. Call telemetry_reset_events when logging is over -@@ -176,7 +176,7 @@ EXPORT_SYMBOL_GPL(telemetry_reset_events); - /** - * telemetry_get_eventconfig() - Returns the pss and ioss events enabled - * @pss_evtconfig: Pointer to PSS related configuration. -- * @pss_evtconfig: Pointer to IOSS related configuration. -+ * @ioss_evtconfig: Pointer to IOSS related configuration. - * @pss_len: Number of u32 elements allocated for pss_evtconfig array - * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array - * -diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c -index b10ea69a638e1..2624441d2fa92 100644 ---- a/drivers/soundwire/stream.c -+++ b/drivers/soundwire/stream.c -@@ -744,14 +744,15 @@ error_1: - * sdw_ml_sync_bank_switch: Multilink register bank switch - * - * @bus: SDW bus instance -+ * @multi_link: whether this is a multi-link stream with hardware-based sync - * - * Caller function should free the buffers on error - */ --static int sdw_ml_sync_bank_switch(struct sdw_bus *bus) -+static int sdw_ml_sync_bank_switch(struct sdw_bus *bus, bool multi_link) - { - unsigned long time_left; - -- if (!bus->multi_link) -+ if (!multi_link) - return 0; - - /* Wait for completion of transfer */ -@@ -848,7 +849,7 @@ static int do_bank_switch(struct sdw_stream_runtime *stream) - bus->bank_switch_timeout = DEFAULT_BANK_SWITCH_TIMEOUT; - - /* Check if bank switch was successful */ -- ret = sdw_ml_sync_bank_switch(bus); -+ ret = sdw_ml_sync_bank_switch(bus, multi_link); - if (ret < 0) { - dev_err(bus->dev, - "multi link bank switch failed: %d\n", ret); -diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c -index 671ee8843c889..5703a9ddb6d0d 100644 ---- a/drivers/staging/gdm724x/gdm_lte.c -+++ b/drivers/staging/gdm724x/gdm_lte.c -@@ -349,7 +349,7 @@ static s32 gdm_lte_tx_nic_type(struct net_device *dev, struct sk_buff *skb) - /* Get ethernet protocol */ - eth = (struct ethhdr *)skb->data; - if (ntohs(eth->h_proto) == ETH_P_8021Q) { -- vlan_eth = (struct vlan_ethhdr *)skb->data; -+ vlan_eth = skb_vlan_eth_hdr(skb); - mac_proto = ntohs(vlan_eth->h_vlan_encapsulated_proto); - network_data = skb->data + VLAN_ETH_HLEN; - nic_type |= NIC_TYPE_F_VLAN; -@@ -435,7 +435,7 @@ static netdev_tx_t gdm_lte_tx(struct sk_buff *skb, struct net_device *dev) - * driver based on the NIC mac - */ - if (nic_type & NIC_TYPE_F_VLAN) { -- struct vlan_ethhdr *vlan_eth = (struct vlan_ethhdr *)skb->data; -+ struct vlan_ethhdr *vlan_eth = skb_vlan_eth_hdr(skb); - - nic->vlan_id = ntohs(vlan_eth->h_vlan_TCI) & VLAN_VID_MASK; - data_buf = skb->data + (VLAN_ETH_HLEN - ETH_HLEN); -diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c -index c62939e5ea1f0..37036db63aff3 100644 ---- a/fs/afs/rxrpc.c -+++ b/fs/afs/rxrpc.c -@@ -424,7 +424,7 @@ error_kill_call: - if (call->async) { - if (cancel_work_sync(&call->async_work)) - afs_put_call(call); -- afs_put_call(call); -+ afs_set_call_complete(call, ret, 0); - } - - ac->error = ret; -diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c -index afcc96a1f4276..539bc9bdcb93f 100644 ---- a/fs/btrfs/extent_io.c -+++ b/fs/btrfs/extent_io.c -@@ -3390,7 +3390,8 @@ static int try_release_extent_state(struct extent_io_tree *tree, - ret = 0; - } else { - u32 clear_bits = ~(EXTENT_LOCKED | EXTENT_NODATASUM | -- EXTENT_DELALLOC_NEW | EXTENT_CTLBITS); -+ EXTENT_DELALLOC_NEW | EXTENT_CTLBITS | -+ EXTENT_QGROUP_RESERVED); - - /* - * At this point we can safely clear everything except the -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index dc6e3cce747c1..e8e4781c48a50 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -2182,6 +2182,15 @@ static noinline int __btrfs_ioctl_snap_create(struct file *file, - * are limited to own subvolumes only - */ - ret = -EPERM; -+ } else if (btrfs_ino(BTRFS_I(src_inode)) != BTRFS_FIRST_FREE_OBJECTID) { -+ /* -+ * Snapshots must be made with the src_inode referring -+ * to the subvolume inode, otherwise the permission -+ * checking above is useless because we may have -+ * permission on a lower directory but not the subvol -+ * itself. -+ */ -+ ret = -EINVAL; - } else { - ret = btrfs_mksnapshot(&file->f_path, mnt_userns, - name, namelen, -diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c -index bd0c7157e3878..0321753c16b9f 100644 ---- a/fs/btrfs/ordered-data.c -+++ b/fs/btrfs/ordered-data.c -@@ -544,7 +544,9 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode, - release = entry->disk_num_bytes; - else - release = entry->num_bytes; -- btrfs_delalloc_release_metadata(btrfs_inode, release, false); -+ btrfs_delalloc_release_metadata(btrfs_inode, release, -+ test_bit(BTRFS_ORDERED_IOERR, -+ &entry->flags)); - } - - percpu_counter_add_batch(&fs_info->ordered_bytes, -entry->num_bytes, -diff --git a/fs/ext4/file.c b/fs/ext4/file.c -index 8ebe4dc7b0170..18f5fd2a163b0 100644 ---- a/fs/ext4/file.c -+++ b/fs/ext4/file.c -@@ -339,9 +339,10 @@ static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count) - return; - } - /* -- * If i_disksize got extended due to writeback of delalloc blocks while -- * the DIO was running we could fail to cleanup the orphan list in -- * ext4_handle_inode_extension(). Do it now. -+ * If i_disksize got extended either due to writeback of delalloc -+ * blocks or extending truncate while the DIO was running we could fail -+ * to cleanup the orphan list in ext4_handle_inode_extension(). Do it -+ * now. - */ - if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) { - handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); -@@ -376,10 +377,11 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size, - * blocks. But the code in ext4_iomap_alloc() is careful to use - * zeroed/unwritten extents if this is possible; thus we won't leave - * uninitialized blocks in a file even if we didn't succeed in writing -- * as much as we intended. -+ * as much as we intended. Also we can race with truncate or write -+ * expanding the file so we have to be a bit careful here. - */ -- WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize)); -- if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize)) -+ if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize) && -+ pos + size <= i_size_read(inode)) - return size; - return ext4_handle_inode_extension(inode, pos, size); - } -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 6ea6b7105fe35..a6e41746890d4 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -4110,6 +4110,10 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, - start = max(start, rounddown(ac->ac_o_ex.fe_logical, - (ext4_lblk_t)EXT4_BLOCKS_PER_GROUP(ac->ac_sb))); - -+ /* avoid unnecessary preallocation that may trigger assertions */ -+ if (start + size > EXT_MAX_BLOCKS) -+ size = EXT_MAX_BLOCKS - start; -+ - /* don't cover already allocated blocks in selected range */ - if (ar->pleft && start <= ar->lleft) { - size -= ar->lleft + 1 - start; -diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c -index e23e802a80130..6e71904c396f1 100644 ---- a/fs/fuse/dax.c -+++ b/fs/fuse/dax.c -@@ -1224,6 +1224,7 @@ void fuse_dax_conn_free(struct fuse_conn *fc) - if (fc->dax) { - fuse_free_dax_mem_ranges(&fc->dax->free_ranges); - kfree(fc->dax); -+ fc->dax = NULL; - } - } - -diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c -index eaa5bd148810a..88942b1fb4318 100644 ---- a/fs/smb/client/smb2misc.c -+++ b/fs/smb/client/smb2misc.c -@@ -313,6 +313,9 @@ static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = { - char * - smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr) - { -+ const int max_off = 4096; -+ const int max_len = 128 * 1024; -+ - *off = 0; - *len = 0; - -@@ -384,29 +387,20 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr) - * Invalid length or offset probably means data area is invalid, but - * we have little choice but to ignore the data area in this case. - */ -- if (*off > 4096) { -- cifs_dbg(VFS, "offset %d too large, data area ignored\n", *off); -- *len = 0; -- *off = 0; -- } else if (*off < 0) { -- cifs_dbg(VFS, "negative offset %d to data invalid ignore data area\n", -- *off); -+ if (unlikely(*off < 0 || *off > max_off || -+ *len < 0 || *len > max_len)) { -+ cifs_dbg(VFS, "%s: invalid data area (off=%d len=%d)\n", -+ __func__, *off, *len); - *off = 0; - *len = 0; -- } else if (*len < 0) { -- cifs_dbg(VFS, "negative data length %d invalid, data area ignored\n", -- *len); -- *len = 0; -- } else if (*len > 128 * 1024) { -- cifs_dbg(VFS, "data area larger than 128K: %d\n", *len); -+ } else if (*off == 0) { - *len = 0; - } - - /* return pointer to beginning of data area, ie offset from SMB start */ -- if ((*off != 0) && (*len != 0)) -+ if (*off > 0 && *len > 0) - return (char *)shdr + *off; -- else -- return NULL; -+ return NULL; - } - - /* -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index 6ef3c00de5ca1..1b3489a2f0db7 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -3122,7 +3122,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, - struct kvec close_iov[1]; - struct smb2_ioctl_rsp *ioctl_rsp; - struct reparse_data_buffer *reparse_buf; -- u32 plen; -+ u32 off, count, len; - - cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); - -@@ -3202,16 +3202,22 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, - */ - if (rc == 0) { - /* See MS-FSCC 2.3.23 */ -+ off = le32_to_cpu(ioctl_rsp->OutputOffset); -+ count = le32_to_cpu(ioctl_rsp->OutputCount); -+ if (check_add_overflow(off, count, &len) || -+ len > rsp_iov[1].iov_len) { -+ cifs_tcon_dbg(VFS, "%s: invalid ioctl: off=%d count=%d\n", -+ __func__, off, count); -+ rc = -EIO; -+ goto query_rp_exit; -+ } - -- reparse_buf = (struct reparse_data_buffer *) -- ((char *)ioctl_rsp + -- le32_to_cpu(ioctl_rsp->OutputOffset)); -- plen = le32_to_cpu(ioctl_rsp->OutputCount); -- -- if (plen + le32_to_cpu(ioctl_rsp->OutputOffset) > -- rsp_iov[1].iov_len) { -- cifs_tcon_dbg(FYI, "srv returned invalid ioctl len: %d\n", -- plen); -+ reparse_buf = (void *)((u8 *)ioctl_rsp + off); -+ len = sizeof(*reparse_buf); -+ if (count < len || -+ count < le16_to_cpu(reparse_buf->ReparseDataLength) + len) { -+ cifs_tcon_dbg(VFS, "%s: invalid ioctl: off=%d count=%d\n", -+ __func__, off, count); - rc = -EIO; - goto query_rp_exit; - } -@@ -5065,6 +5071,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server, - struct smb2_hdr *shdr; - unsigned int pdu_length = server->pdu_size; - unsigned int buf_size; -+ unsigned int next_cmd; - struct mid_q_entry *mid_entry; - int next_is_large; - char *next_buffer = NULL; -@@ -5093,14 +5100,15 @@ receive_encrypted_standard(struct TCP_Server_Info *server, - next_is_large = server->large_buf; - one_more: - shdr = (struct smb2_hdr *)buf; -- if (shdr->NextCommand) { -+ next_cmd = le32_to_cpu(shdr->NextCommand); -+ if (next_cmd) { -+ if (WARN_ON_ONCE(next_cmd > pdu_length)) -+ return -1; - if (next_is_large) - next_buffer = (char *)cifs_buf_get(); - else - next_buffer = (char *)cifs_small_buf_get(); -- memcpy(next_buffer, -- buf + le32_to_cpu(shdr->NextCommand), -- pdu_length - le32_to_cpu(shdr->NextCommand)); -+ memcpy(next_buffer, buf + next_cmd, pdu_length - next_cmd); - } - - mid_entry = smb2_find_mid(server, buf); -@@ -5124,8 +5132,8 @@ one_more: - else - ret = cifs_handle_standard(server, mid_entry); - -- if (ret == 0 && shdr->NextCommand) { -- pdu_length -= le32_to_cpu(shdr->NextCommand); -+ if (ret == 0 && next_cmd) { -+ pdu_length -= next_cmd; - server->large_buf = next_is_large; - if (next_is_large) - server->bigbuf = buf = next_buffer; -diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h -index 9619015d78f29..c8a4014f9d395 100644 ---- a/fs/smb/common/smb2pdu.h -+++ b/fs/smb/common/smb2pdu.h -@@ -1116,7 +1116,7 @@ struct smb2_change_notify_rsp { - #define SMB2_CREATE_SD_BUFFER "SecD" /* security descriptor */ - #define SMB2_CREATE_DURABLE_HANDLE_REQUEST "DHnQ" - #define SMB2_CREATE_DURABLE_HANDLE_RECONNECT "DHnC" --#define SMB2_CREATE_ALLOCATION_SIZE "AISi" -+#define SMB2_CREATE_ALLOCATION_SIZE "AlSi" - #define SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST "MxAc" - #define SMB2_CREATE_TIMEWARP_REQUEST "TWrp" - #define SMB2_CREATE_QUERY_ON_DISK_ID "QFid" -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index 683152007566c..1598ad6155fef 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -7135,6 +7135,7 @@ skip: - smb2_remove_blocked_lock, - argv); - if (rc) { -+ kfree(argv); - err = -ENOMEM; - goto out; - } -diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h -index 995513fa26904..0655aa5b57b29 100644 ---- a/include/asm-generic/qspinlock.h -+++ b/include/asm-generic/qspinlock.h -@@ -70,7 +70,7 @@ static __always_inline int queued_spin_is_locked(struct qspinlock *lock) - */ - static __always_inline int queued_spin_value_unlocked(struct qspinlock lock) - { -- return !atomic_read(&lock.val); -+ return !lock.val.counter; - } - - /** -diff --git a/include/linux/cred.h b/include/linux/cred.h -index 9ed9232af9340..09c1ed9242b4a 100644 ---- a/include/linux/cred.h -+++ b/include/linux/cred.h -@@ -108,7 +108,7 @@ static inline int groups_search(const struct group_info *group_info, kgid_t grp) - * same context as task->real_cred. - */ - struct cred { -- atomic_t usage; -+ atomic_long_t usage; - #ifdef CONFIG_DEBUG_CREDENTIALS - atomic_t subscribers; /* number of processes subscribed */ - void *put_addr; -@@ -228,7 +228,7 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred) - */ - static inline struct cred *get_new_cred(struct cred *cred) - { -- atomic_inc(&cred->usage); -+ atomic_long_inc(&cred->usage); - return cred; - } - -@@ -260,7 +260,7 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred) - struct cred *nonconst_cred = (struct cred *) cred; - if (!cred) - return NULL; -- if (!atomic_inc_not_zero(&nonconst_cred->usage)) -+ if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) - return NULL; - validate_creds(cred); - nonconst_cred->non_rcu = 0; -@@ -284,7 +284,7 @@ static inline void put_cred(const struct cred *_cred) - - if (cred) { - validate_creds(cred); -- if (atomic_dec_and_test(&(cred)->usage)) -+ if (atomic_long_dec_and_test(&(cred)->usage)) - __put_cred(cred); - } - } -diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h -index 68b1c41332984..e0d0a645be7cf 100644 ---- a/include/linux/if_vlan.h -+++ b/include/linux/if_vlan.h -@@ -62,6 +62,14 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) - return (struct vlan_ethhdr *)skb_mac_header(skb); - } - -+/* Prefer this version in TX path, instead of -+ * skb_reset_mac_header() + vlan_eth_hdr() -+ */ -+static inline struct vlan_ethhdr *skb_vlan_eth_hdr(const struct sk_buff *skb) -+{ -+ return (struct vlan_ethhdr *)skb->data; -+} -+ - #define VLAN_PRIO_MASK 0xe000 /* Priority Code Point */ - #define VLAN_PRIO_SHIFT 13 - #define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator / Drop Eligible Indicator */ -@@ -531,7 +539,7 @@ static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, - */ - static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) - { -- struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data; -+ struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb); - - if (!eth_type_vlan(veth->h_vlan_proto)) - return -EINVAL; -@@ -732,7 +740,7 @@ static inline bool skb_vlan_tagged_multi(struct sk_buff *skb) - if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) - return false; - -- veh = (struct vlan_ethhdr *)skb->data; -+ veh = skb_vlan_eth_hdr(skb); - protocol = veh->h_vlan_encapsulated_proto; - } - -diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h -index 4ef6c09cc2eec..c21e19a1514d1 100644 ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -231,22 +231,27 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, - if (folio_test_unevictable(folio) || !lrugen->enabled) - return false; - /* -- * There are three common cases for this page: -- * 1. If it's hot, e.g., freshly faulted in or previously hot and -- * migrated, add it to the youngest generation. -- * 2. If it's cold but can't be evicted immediately, i.e., an anon page -- * not in swapcache or a dirty page pending writeback, add it to the -- * second oldest generation. -- * 3. Everything else (clean, cold) is added to the oldest generation. -+ * There are four common cases for this page: -+ * 1. If it's hot, i.e., freshly faulted in, add it to the youngest -+ * generation, and it's protected over the rest below. -+ * 2. If it can't be evicted immediately, i.e., a dirty page pending -+ * writeback, add it to the second youngest generation. -+ * 3. If it should be evicted first, e.g., cold and clean from -+ * folio_rotate_reclaimable(), add it to the oldest generation. -+ * 4. Everything else falls between 2 & 3 above and is added to the -+ * second oldest generation if it's considered inactive, or the -+ * oldest generation otherwise. See lru_gen_is_active(). - */ - if (folio_test_active(folio)) - seq = lrugen->max_seq; - else if ((type == LRU_GEN_ANON && !folio_test_swapcache(folio)) || - (folio_test_reclaim(folio) && - (folio_test_dirty(folio) || folio_test_writeback(folio)))) -- seq = lrugen->min_seq[type] + 1; -- else -+ seq = lrugen->max_seq - 1; -+ else if (reclaiming || lrugen->min_seq[type] + MIN_NR_GENS >= lrugen->max_seq) - seq = lrugen->min_seq[type]; -+ else -+ seq = lrugen->min_seq[type] + 1; - - gen = lru_gen_from_seq(seq); - flags = (gen + 1UL) << LRU_GEN_PGOFF; -diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h -index 20d88b1defc30..33a4c146dc19c 100644 ---- a/include/linux/usb/r8152.h -+++ b/include/linux/usb/r8152.h -@@ -29,6 +29,8 @@ - #define VENDOR_ID_LINKSYS 0x13b1 - #define VENDOR_ID_NVIDIA 0x0955 - #define VENDOR_ID_TPLINK 0x2357 -+#define VENDOR_ID_DLINK 0x2001 -+#define VENDOR_ID_ASUS 0x0b05 - - #if IS_REACHABLE(CONFIG_USB_RTL8152) - extern u8 rtl8152_get_version(struct usb_interface *intf); -diff --git a/include/net/addrconf.h b/include/net/addrconf.h -index c04f359655b86..86eb2aba1479c 100644 ---- a/include/net/addrconf.h -+++ b/include/net/addrconf.h -@@ -31,17 +31,22 @@ struct prefix_info { - __u8 length; - __u8 prefix_len; - -+ union __packed { -+ __u8 flags; -+ struct __packed { - #if defined(__BIG_ENDIAN_BITFIELD) -- __u8 onlink : 1, -+ __u8 onlink : 1, - autoconf : 1, - reserved : 6; - #elif defined(__LITTLE_ENDIAN_BITFIELD) -- __u8 reserved : 6, -+ __u8 reserved : 6, - autoconf : 1, - onlink : 1; - #else - #error "Please fix " - #endif -+ }; -+ }; - __be32 valid; - __be32 prefered; - __be32 reserved2; -@@ -49,6 +54,9 @@ struct prefix_info { - struct in6_addr prefix; - }; - -+/* rfc4861 4.6.2: IPv6 PIO is 32 bytes in size */ -+static_assert(sizeof(struct prefix_info) == 32); -+ - #include - #include - #include -diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h -index c8490729b4aea..31bf475eca762 100644 ---- a/include/net/if_inet6.h -+++ b/include/net/if_inet6.h -@@ -22,10 +22,6 @@ - #define IF_RS_SENT 0x10 - #define IF_READY 0x80000000 - --/* prefix flags */ --#define IF_PREFIX_ONLINK 0x01 --#define IF_PREFIX_AUTOCONF 0x02 -- - enum { - INET6_IFADDR_STATE_PREDAD, - INET6_IFADDR_STATE_DAD, -diff --git a/kernel/cred.c b/kernel/cred.c -index e10c15f51c1fe..d35bc0aa98cba 100644 ---- a/kernel/cred.c -+++ b/kernel/cred.c -@@ -99,17 +99,17 @@ static void put_cred_rcu(struct rcu_head *rcu) - - #ifdef CONFIG_DEBUG_CREDENTIALS - if (cred->magic != CRED_MAGIC_DEAD || -- atomic_read(&cred->usage) != 0 || -+ atomic_long_read(&cred->usage) != 0 || - read_cred_subscribers(cred) != 0) - panic("CRED: put_cred_rcu() sees %p with" -- " mag %x, put %p, usage %d, subscr %d\n", -+ " mag %x, put %p, usage %ld, subscr %d\n", - cred, cred->magic, cred->put_addr, -- atomic_read(&cred->usage), -+ atomic_long_read(&cred->usage), - read_cred_subscribers(cred)); - #else -- if (atomic_read(&cred->usage) != 0) -- panic("CRED: put_cred_rcu() sees %p with usage %d\n", -- cred, atomic_read(&cred->usage)); -+ if (atomic_long_read(&cred->usage) != 0) -+ panic("CRED: put_cred_rcu() sees %p with usage %ld\n", -+ cred, atomic_long_read(&cred->usage)); - #endif - - security_cred_free(cred); -@@ -134,11 +134,11 @@ static void put_cred_rcu(struct rcu_head *rcu) - */ - void __put_cred(struct cred *cred) - { -- kdebug("__put_cred(%p{%d,%d})", cred, -- atomic_read(&cred->usage), -+ kdebug("__put_cred(%p{%ld,%d})", cred, -+ atomic_long_read(&cred->usage), - read_cred_subscribers(cred)); - -- BUG_ON(atomic_read(&cred->usage) != 0); -+ BUG_ON(atomic_long_read(&cred->usage) != 0); - #ifdef CONFIG_DEBUG_CREDENTIALS - BUG_ON(read_cred_subscribers(cred) != 0); - cred->magic = CRED_MAGIC_DEAD; -@@ -161,8 +161,8 @@ void exit_creds(struct task_struct *tsk) - { - struct cred *cred; - -- kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred, -- atomic_read(&tsk->cred->usage), -+ kdebug("exit_creds(%u,%p,%p,{%ld,%d})", tsk->pid, tsk->real_cred, tsk->cred, -+ atomic_long_read(&tsk->cred->usage), - read_cred_subscribers(tsk->cred)); - - cred = (struct cred *) tsk->real_cred; -@@ -221,7 +221,7 @@ struct cred *cred_alloc_blank(void) - if (!new) - return NULL; - -- atomic_set(&new->usage, 1); -+ atomic_long_set(&new->usage, 1); - #ifdef CONFIG_DEBUG_CREDENTIALS - new->magic = CRED_MAGIC; - #endif -@@ -267,7 +267,7 @@ struct cred *prepare_creds(void) - memcpy(new, old, sizeof(struct cred)); - - new->non_rcu = 0; -- atomic_set(&new->usage, 1); -+ atomic_long_set(&new->usage, 1); - set_cred_subscribers(new, 0); - get_group_info(new->group_info); - get_uid(new->user); -@@ -355,8 +355,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) - p->real_cred = get_cred(p->cred); - get_cred(p->cred); - alter_cred_subscribers(p->cred, 2); -- kdebug("share_creds(%p{%d,%d})", -- p->cred, atomic_read(&p->cred->usage), -+ kdebug("share_creds(%p{%ld,%d})", -+ p->cred, atomic_long_read(&p->cred->usage), - read_cred_subscribers(p->cred)); - inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1); - return 0; -@@ -449,8 +449,8 @@ int commit_creds(struct cred *new) - struct task_struct *task = current; - const struct cred *old = task->real_cred; - -- kdebug("commit_creds(%p{%d,%d})", new, -- atomic_read(&new->usage), -+ kdebug("commit_creds(%p{%ld,%d})", new, -+ atomic_long_read(&new->usage), - read_cred_subscribers(new)); - - BUG_ON(task->cred != old); -@@ -459,7 +459,7 @@ int commit_creds(struct cred *new) - validate_creds(old); - validate_creds(new); - #endif -- BUG_ON(atomic_read(&new->usage) < 1); -+ BUG_ON(atomic_long_read(&new->usage) < 1); - - get_cred(new); /* we will require a ref for the subj creds too */ - -@@ -532,14 +532,14 @@ EXPORT_SYMBOL(commit_creds); - */ - void abort_creds(struct cred *new) - { -- kdebug("abort_creds(%p{%d,%d})", new, -- atomic_read(&new->usage), -+ kdebug("abort_creds(%p{%ld,%d})", new, -+ atomic_long_read(&new->usage), - read_cred_subscribers(new)); - - #ifdef CONFIG_DEBUG_CREDENTIALS - BUG_ON(read_cred_subscribers(new) != 0); - #endif -- BUG_ON(atomic_read(&new->usage) < 1); -+ BUG_ON(atomic_long_read(&new->usage) < 1); - put_cred(new); - } - EXPORT_SYMBOL(abort_creds); -@@ -555,8 +555,8 @@ const struct cred *override_creds(const struct cred *new) - { - const struct cred *old = current->cred; - -- kdebug("override_creds(%p{%d,%d})", new, -- atomic_read(&new->usage), -+ kdebug("override_creds(%p{%ld,%d})", new, -+ atomic_long_read(&new->usage), - read_cred_subscribers(new)); - - validate_creds(old); -@@ -578,8 +578,8 @@ const struct cred *override_creds(const struct cred *new) - rcu_assign_pointer(current->cred, new); - alter_cred_subscribers(old, -1); - -- kdebug("override_creds() = %p{%d,%d}", old, -- atomic_read(&old->usage), -+ kdebug("override_creds() = %p{%ld,%d}", old, -+ atomic_long_read(&old->usage), - read_cred_subscribers(old)); - return old; - } -@@ -596,8 +596,8 @@ void revert_creds(const struct cred *old) - { - const struct cred *override = current->cred; - -- kdebug("revert_creds(%p{%d,%d})", old, -- atomic_read(&old->usage), -+ kdebug("revert_creds(%p{%ld,%d})", old, -+ atomic_long_read(&old->usage), - read_cred_subscribers(old)); - - validate_creds(old); -@@ -729,7 +729,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) - - *new = *old; - new->non_rcu = 0; -- atomic_set(&new->usage, 1); -+ atomic_long_set(&new->usage, 1); - set_cred_subscribers(new, 0); - get_uid(new->user); - get_user_ns(new->user_ns); -@@ -843,8 +843,8 @@ static void dump_invalid_creds(const struct cred *cred, const char *label, - cred == tsk->cred ? "[eff]" : ""); - printk(KERN_ERR "CRED: ->magic=%x, put_addr=%p\n", - cred->magic, cred->put_addr); -- printk(KERN_ERR "CRED: ->usage=%d, subscr=%d\n", -- atomic_read(&cred->usage), -+ printk(KERN_ERR "CRED: ->usage=%ld, subscr=%d\n", -+ atomic_long_read(&cred->usage), - read_cred_subscribers(cred)); - printk(KERN_ERR "CRED: ->*uid = { %d,%d,%d,%d }\n", - from_kuid_munged(&init_user_ns, cred->uid), -@@ -916,9 +916,9 @@ EXPORT_SYMBOL(__validate_process_creds); - */ - void validate_creds_for_do_exit(struct task_struct *tsk) - { -- kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})", -+ kdebug("validate_creds_for_do_exit(%p,%p{%ld,%d})", - tsk->real_cred, tsk->cred, -- atomic_read(&tsk->cred->usage), -+ atomic_long_read(&tsk->cred->usage), - read_cred_subscribers(tsk->cred)); - - __validate_process_creds(tsk, __FILE__, __LINE__); -diff --git a/kernel/events/core.c b/kernel/events/core.c -index 0193243f65e5c..8c7d2f4f5fbab 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -1945,6 +1945,16 @@ static bool perf_event_validate_size(struct perf_event *event) - group_leader->nr_siblings + 1) > 16*1024) - return false; - -+ /* -+ * When creating a new group leader, group_leader->ctx is initialized -+ * after the size has been validated, but we cannot safely use -+ * for_each_sibling_event() until group_leader->ctx is set. A new group -+ * leader cannot have any siblings yet, so we can safely skip checking -+ * the non-existent siblings. -+ */ -+ if (event == group_leader) -+ return true; -+ - for_each_sibling_event(sibling, group_leader) { - if (__perf_event_read_size(sibling->attr.read_format, - group_leader->nr_siblings + 1) > 16*1024) -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index c02a4cb879913..61803208706a5 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -711,6 +711,9 @@ static int rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) - unsigned long cnt2, top2, bottom2, msb2; - u64 val; - -+ /* Any interruptions in this function should cause a failure */ -+ cnt = local_read(&t->cnt); -+ - /* The cmpxchg always fails if it interrupted an update */ - if (!__rb_time_read(t, &val, &cnt2)) - return false; -@@ -718,17 +721,18 @@ static int rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) - if (val != expect) - return false; - -- cnt = local_read(&t->cnt); - if ((cnt & 3) != cnt2) - return false; - - cnt2 = cnt + 1; - - rb_time_split(val, &top, &bottom, &msb); -+ msb = rb_time_val_cnt(msb, cnt); - top = rb_time_val_cnt(top, cnt); - bottom = rb_time_val_cnt(bottom, cnt); - - rb_time_split(set, &top2, &bottom2, &msb2); -+ msb2 = rb_time_val_cnt(msb2, cnt); - top2 = rb_time_val_cnt(top2, cnt2); - bottom2 = rb_time_val_cnt(bottom2, cnt2); - -@@ -1801,6 +1805,8 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer) - free_buffer_page(bpage); - } - -+ free_page((unsigned long)cpu_buffer->free_page); -+ - kfree(cpu_buffer); - } - -@@ -2401,7 +2407,7 @@ rb_iter_head_event(struct ring_buffer_iter *iter) - */ - barrier(); - -- if ((iter->head + length) > commit || length > BUF_MAX_DATA_SIZE) -+ if ((iter->head + length) > commit || length > BUF_PAGE_SIZE) - /* Writer corrupted the read? */ - goto reset; - -@@ -3576,7 +3582,10 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, - * absolute timestamp. - * Don't bother if this is the start of a new page (w == 0). - */ -- if (unlikely(!a_ok || !b_ok || (info->before != info->after && w))) { -+ if (!w) { -+ /* Use the sub-buffer timestamp */ -+ info->delta = 0; -+ } else if (unlikely(!a_ok || !b_ok || info->before != info->after)) { - info->add_timestamp |= RB_ADD_STAMP_FORCE | RB_ADD_STAMP_EXTEND; - info->length += RB_LEN_TIME_EXTEND; - } else { -@@ -3599,26 +3608,19 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, - - /* See if we shot pass the end of this buffer page */ - if (unlikely(write > BUF_PAGE_SIZE)) { -- /* before and after may now different, fix it up*/ -- b_ok = rb_time_read(&cpu_buffer->before_stamp, &info->before); -- a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after); -- if (a_ok && b_ok && info->before != info->after) -- (void)rb_time_cmpxchg(&cpu_buffer->before_stamp, -- info->before, info->after); -- if (a_ok && b_ok) -- check_buffer(cpu_buffer, info, CHECK_FULL_PAGE); -+ check_buffer(cpu_buffer, info, CHECK_FULL_PAGE); - return rb_move_tail(cpu_buffer, tail, info); - } - - if (likely(tail == w)) { -- u64 save_before; -- bool s_ok; -- - /* Nothing interrupted us between A and C */ - /*D*/ rb_time_set(&cpu_buffer->write_stamp, info->ts); -- barrier(); -- /*E*/ s_ok = rb_time_read(&cpu_buffer->before_stamp, &save_before); -- RB_WARN_ON(cpu_buffer, !s_ok); -+ /* -+ * If something came in between C and D, the write stamp -+ * may now not be in sync. But that's fine as the before_stamp -+ * will be different and then next event will just be forced -+ * to use an absolute timestamp. -+ */ - if (likely(!(info->add_timestamp & - (RB_ADD_STAMP_FORCE | RB_ADD_STAMP_ABSOLUTE)))) - /* This did not interrupt any time update */ -@@ -3626,24 +3628,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, - else - /* Just use full timestamp for interrupting event */ - info->delta = info->ts; -- barrier(); - check_buffer(cpu_buffer, info, tail); -- if (unlikely(info->ts != save_before)) { -- /* SLOW PATH - Interrupted between C and E */ -- -- a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after); -- RB_WARN_ON(cpu_buffer, !a_ok); -- -- /* Write stamp must only go forward */ -- if (save_before > info->after) { -- /* -- * We do not care about the result, only that -- * it gets updated atomically. -- */ -- (void)rb_time_cmpxchg(&cpu_buffer->write_stamp, -- info->after, save_before); -- } -- } - } else { - u64 ts; - /* SLOW PATH - Interrupted between A and C */ -@@ -3734,6 +3719,8 @@ rb_reserve_next_event(struct trace_buffer *buffer, - if (ring_buffer_time_stamp_abs(cpu_buffer->buffer)) { - add_ts_default = RB_ADD_STAMP_ABSOLUTE; - info.length += RB_LEN_TIME_EXTEND; -+ if (info.length > BUF_MAX_DATA_SIZE) -+ goto out_fail; - } else { - add_ts_default = RB_ADD_STAMP_NONE; - } -@@ -5118,7 +5105,8 @@ ring_buffer_read_prepare(struct trace_buffer *buffer, int cpu, gfp_t flags) - if (!iter) - return NULL; - -- iter->event = kmalloc(BUF_MAX_DATA_SIZE, flags); -+ /* Holds the entire event: data and meta data */ -+ iter->event = kmalloc(BUF_PAGE_SIZE, flags); - if (!iter->event) { - kfree(iter); - return NULL; -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index d2db4d6f0f2fd..87eca95b57fb3 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -6268,7 +6268,7 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, - if (!tr->array_buffer.buffer) - return 0; - -- /* Do not allow tracing while resizng ring buffer */ -+ /* Do not allow tracing while resizing ring buffer */ - tracing_stop_tr(tr); - - ret = ring_buffer_resize(tr->array_buffer.buffer, size, cpu); -@@ -6276,7 +6276,7 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, - goto out_start; - - #ifdef CONFIG_TRACER_MAX_TRACE -- if (!tr->current_trace->use_max_tr) -+ if (!tr->allocated_snapshot) - goto out; - - ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu); -diff --git a/mm/shmem.c b/mm/shmem.c -index 806741bbe4a68..f7c08e169e423 100644 ---- a/mm/shmem.c -+++ b/mm/shmem.c -@@ -1024,7 +1024,24 @@ whole_folios: - } - VM_BUG_ON_FOLIO(folio_test_writeback(folio), - folio); -- truncate_inode_folio(mapping, folio); -+ -+ if (!folio_test_large(folio)) { -+ truncate_inode_folio(mapping, folio); -+ } else if (truncate_inode_partial_folio(folio, lstart, lend)) { -+ /* -+ * If we split a page, reset the loop so -+ * that we pick up the new sub pages. -+ * Otherwise the THP was entirely -+ * dropped or the target range was -+ * zeroed, so just continue the loop as -+ * is. -+ */ -+ if (!folio_test_large(folio)) { -+ folio_unlock(folio); -+ index = start; -+ break; -+ } -+ } - } - index = folio->index + folio_nr_pages(folio) - 1; - folio_unlock(folio); -diff --git a/mm/vmscan.c b/mm/vmscan.c -index 93d6f27dd40b4..3f090faa6377f 100644 ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4770,7 +4770,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c - } - - /* protected */ -- if (tier > tier_idx) { -+ if (tier > tier_idx || refs == BIT(LRU_REFS_WIDTH)) { - int hist = lru_hist_from_seq(lrugen->min_seq[type]); - - gen = folio_inc_gen(lruvec, folio, false); -diff --git a/mm/workingset.c b/mm/workingset.c -index ae7e984b23c6b..6e4699055ed37 100644 ---- a/mm/workingset.c -+++ b/mm/workingset.c -@@ -289,10 +289,10 @@ static void lru_gen_refault(struct folio *folio, void *shadow) - * 1. For pages accessed through page tables, hotter pages pushed out - * hot pages which refaulted immediately. - * 2. For pages accessed multiple times through file descriptors, -- * numbers of accesses might have been out of the range. -+ * they would have been protected by sort_folio(). - */ -- if (lru_gen_in_fault() || refs == BIT(LRU_REFS_WIDTH)) { -- folio_set_workingset(folio); -+ if (lru_gen_in_fault() || refs >= BIT(LRU_REFS_WIDTH) - 1) { -+ set_mask_bits(&folio->flags, 0, LRU_REFS_MASK | BIT(PG_workingset)); - mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta); - } - unlock: -diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c -index a06f4d4a6f476..f67f14db16334 100644 ---- a/net/appletalk/ddp.c -+++ b/net/appletalk/ddp.c -@@ -1811,15 +1811,14 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) - break; - } - case TIOCINQ: { -- /* -- * These two are safe on a single CPU system as only -- * user tasks fiddle here -- */ -- struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); -+ struct sk_buff *skb; - long amount = 0; - -+ spin_lock_irq(&sk->sk_receive_queue.lock); -+ skb = skb_peek(&sk->sk_receive_queue); - if (skb) - amount = skb->len - sizeof(struct ddpehdr); -+ spin_unlock_irq(&sk->sk_receive_queue.lock); - rc = put_user(amount, (int __user *)argp); - break; - } -diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c -index 838ebf0cabbfb..f81f8d56f5c0c 100644 ---- a/net/atm/ioctl.c -+++ b/net/atm/ioctl.c -@@ -73,14 +73,17 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, - case SIOCINQ: - { - struct sk_buff *skb; -+ int amount; - - if (sock->state != SS_CONNECTED) { - error = -EINVAL; - goto done; - } -+ spin_lock_irq(&sk->sk_receive_queue.lock); - skb = skb_peek(&sk->sk_receive_queue); -- error = put_user(skb ? skb->len : 0, -- (int __user *)argp) ? -EFAULT : 0; -+ amount = skb ? skb->len : 0; -+ spin_unlock_irq(&sk->sk_receive_queue.lock); -+ error = put_user(amount, (int __user *)argp) ? -EFAULT : 0; - goto done; - } - case ATM_SETSC: -diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c -index 38d411a52f331..d7b525a495e45 100644 ---- a/net/batman-adv/soft-interface.c -+++ b/net/batman-adv/soft-interface.c -@@ -444,7 +444,7 @@ void batadv_interface_rx(struct net_device *soft_iface, - if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) - goto dropped; - -- vhdr = (struct vlan_ethhdr *)skb->data; -+ vhdr = skb_vlan_eth_hdr(skb); - - /* drop batman-in-batman packets to prevent loops */ - if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index 5b93d1ed1ed19..67087da45a1f7 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -3210,7 +3210,13 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) - if (skb_still_in_host_queue(sk, skb)) - return -EBUSY; - -+start: - if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) { -+ if (unlikely(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) { -+ TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN; -+ TCP_SKB_CB(skb)->seq++; -+ goto start; -+ } - if (unlikely(before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))) { - WARN_ON_ONCE(1); - return -EINVAL; -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index c63ccd39fc552..b8dc20fe7a4e2 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -6105,11 +6105,7 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, - pmsg->prefix_len = pinfo->prefix_len; - pmsg->prefix_type = pinfo->type; - pmsg->prefix_pad3 = 0; -- pmsg->prefix_flags = 0; -- if (pinfo->onlink) -- pmsg->prefix_flags |= IF_PREFIX_ONLINK; -- if (pinfo->autoconf) -- pmsg->prefix_flags |= IF_PREFIX_AUTOCONF; -+ pmsg->prefix_flags = pinfo->flags; - - if (nla_put(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix)) - goto nla_put_failure; -diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c -index ca2b17f32670d..674937284b8d2 100644 ---- a/net/rose/af_rose.c -+++ b/net/rose/af_rose.c -@@ -1315,9 +1315,11 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) - case TIOCINQ: { - struct sk_buff *skb; - long amount = 0L; -- /* These two are safe on a single CPU system as only user tasks fiddle here */ -+ -+ spin_lock_irq(&sk->sk_receive_queue.lock); - if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) - amount = skb->len; -+ spin_unlock_irq(&sk->sk_receive_queue.lock); - return put_user(amount, (unsigned int __user *) argp); - } - -diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c -index 2e60bf06adff0..0323040d34bc6 100644 ---- a/net/tls/tls_sw.c -+++ b/net/tls/tls_sw.c -@@ -1225,6 +1225,8 @@ alloc_payload: - } - - sk_msg_page_add(msg_pl, page, copy, offset); -+ msg_pl->sg.copybreak = 0; -+ msg_pl->sg.curr = msg_pl->sg.end; - sk_mem_charge(sk, copy); - - offset += copy; -diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c -index 79e79fd6efd19..2e25890ca52d1 100644 ---- a/net/vmw_vsock/virtio_transport_common.c -+++ b/net/vmw_vsock/virtio_transport_common.c -@@ -583,7 +583,7 @@ static s64 virtio_transport_has_space(struct vsock_sock *vsk) - struct virtio_vsock_sock *vvs = vsk->trans; - s64 bytes; - -- bytes = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); -+ bytes = (s64)vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); - if (bytes < 0) - bytes = 0; - -diff --git a/scripts/sign-file.c b/scripts/sign-file.c -index 598ef5465f825..3edb156ae52c3 100644 ---- a/scripts/sign-file.c -+++ b/scripts/sign-file.c -@@ -322,7 +322,7 @@ int main(int argc, char **argv) - CMS_NOSMIMECAP | use_keyid | - use_signed_attrs), - "CMS_add1_signer"); -- ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0, -+ ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) != 1, - "CMS_final"); - - #else -@@ -341,10 +341,10 @@ int main(int argc, char **argv) - b = BIO_new_file(sig_file_name, "wb"); - ERR(!b, "%s", sig_file_name); - #ifndef USE_PKCS7 -- ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) < 0, -+ ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) != 1, - "%s", sig_file_name); - #else -- ERR(i2d_PKCS7_bio(b, pkcs7) < 0, -+ ERR(i2d_PKCS7_bio(b, pkcs7) != 1, - "%s", sig_file_name); - #endif - BIO_free(b); -@@ -374,9 +374,9 @@ int main(int argc, char **argv) - - if (!raw_sig) { - #ifndef USE_PKCS7 -- ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name); -+ ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) != 1, "%s", dest_name); - #else -- ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name); -+ ERR(i2d_PKCS7_bio(bd, pkcs7) != 1, "%s", dest_name); - #endif - } else { - BIO *b; -@@ -396,7 +396,7 @@ int main(int argc, char **argv) - ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name); - ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name); - -- ERR(BIO_free(bd) < 0, "%s", dest_name); -+ ERR(BIO_free(bd) != 1, "%s", dest_name); - - /* Finally, if we're signing in place, replace the original. */ - if (replace_orig) -diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c -index 7b5e09070ab9b..f460ac80c8e49 100644 ---- a/sound/pci/hda/patch_hdmi.c -+++ b/sound/pci/hda/patch_hdmi.c -@@ -1993,7 +1993,10 @@ static const struct snd_pci_quirk force_connect_list[] = { - SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1), - SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1), - SND_PCI_QUIRK(0x103c, 0x8715, "HP", 1), -+ SND_PCI_QUIRK(0x1043, 0x86ae, "ASUS", 1), /* Z170 PRO */ -+ SND_PCI_QUIRK(0x1043, 0x86c7, "ASUS", 1), /* Z170M PLUS */ - SND_PCI_QUIRK(0x1462, 0xec94, "MS-7C94", 1), -+ SND_PCI_QUIRK(0x8086, 0x2060, "Intel NUC5CPYB", 1), - SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", 1), - {} - }; -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index c6cae3369a6a1..a7c361e0daebe 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9577,6 +9577,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), - SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3), - SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), -+ SND_PCI_QUIRK(0x103c, 0x84ae, "HP 15-db0403ng", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), - SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN), - SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), - SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), -diff --git a/tools/testing/selftests/bpf/progs/bpf_loop_bench.c b/tools/testing/selftests/bpf/progs/bpf_loop_bench.c -index 4ce76eb064c41..d461746fd3c1e 100644 ---- a/tools/testing/selftests/bpf/progs/bpf_loop_bench.c -+++ b/tools/testing/selftests/bpf/progs/bpf_loop_bench.c -@@ -15,13 +15,16 @@ static int empty_callback(__u32 index, void *data) - return 0; - } - -+static int outer_loop(__u32 index, void *data) -+{ -+ bpf_loop(nr_loops, empty_callback, NULL, 0); -+ __sync_add_and_fetch(&hits, nr_loops); -+ return 0; -+} -+ - SEC("fentry/" SYS_PREFIX "sys_getpgid") - int benchmark(void *ctx) - { -- for (int i = 0; i < 1000; i++) { -- bpf_loop(nr_loops, empty_callback, NULL, 0); -- -- __sync_add_and_fetch(&hits, nr_loops); -- } -+ bpf_loop(1000, outer_loop, NULL, 0); - return 0; - } diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.69-70.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.69-70.patch deleted file mode 100644 index f22e31fe78e2..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.69-70.patch +++ /dev/null @@ -1,5394 +0,0 @@ -diff --git a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.yaml -index ff317fd7c15bf..2e1fcff3c2801 100644 ---- a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.yaml -+++ b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.yaml -@@ -14,9 +14,11 @@ allOf: - - properties: - compatible: -- enum: -- - fsl,imx23-ocotp -- - fsl,imx28-ocotp -+ items: -+ - enum: -+ - fsl,imx23-ocotp -+ - fsl,imx28-ocotp -+ - const: fsl,ocotp - - "#address-cells": - const: 1 -@@ -40,7 +42,7 @@ additionalProperties: false - examples: - - | - ocotp: efuse@8002c000 { -- compatible = "fsl,imx28-ocotp"; -+ compatible = "fsl,imx28-ocotp", "fsl,ocotp"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x8002c000 0x2000>; -diff --git a/Makefile b/Makefile -index 9a3b34d2387fa..270593fcafdcd 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 69 -+SUBLEVEL = 70 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi -index 97ce0c4f1df7e..a79920ec461f0 100644 ---- a/arch/arm/boot/dts/dra7.dtsi -+++ b/arch/arm/boot/dts/dra7.dtsi -@@ -144,7 +144,7 @@ - - l3-noc@44000000 { - compatible = "ti,dra7-l3-noc"; -- reg = <0x44000000 0x1000>, -+ reg = <0x44000000 0x1000000>, - <0x45000000 0x1000>; - interrupts-extended = <&crossbar_mpu GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, - <&wakeupgen GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; -diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c -index 59755b5a1ad7a..75091aa7269ae 100644 ---- a/arch/arm/mach-omap2/id.c -+++ b/arch/arm/mach-omap2/id.c -@@ -793,11 +793,16 @@ void __init omap_soc_device_init(void) - - soc_dev_attr->machine = soc_name; - soc_dev_attr->family = omap_get_family(); -+ if (!soc_dev_attr->family) { -+ kfree(soc_dev_attr); -+ return; -+ } - soc_dev_attr->revision = soc_rev; - soc_dev_attr->custom_attr_group = omap_soc_groups[0]; - - soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { -+ kfree(soc_dev_attr->family); - kfree(soc_dev_attr); - return; - } -diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c -index 6cc380a15eb76..de94515fb17c6 100644 ---- a/arch/arm64/kvm/arm.c -+++ b/arch/arm64/kvm/arm.c -@@ -386,7 +386,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) - kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache); - kvm_timer_vcpu_terminate(vcpu); - kvm_pmu_vcpu_destroy(vcpu); -- -+ kvm_vgic_vcpu_destroy(vcpu); - kvm_arm_vcpu_destroy(vcpu); - } - -diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c -index f2f3bf4a04b0b..0919e3b8f46ec 100644 ---- a/arch/arm64/kvm/vgic/vgic-init.c -+++ b/arch/arm64/kvm/vgic/vgic-init.c -@@ -368,7 +368,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm) - vgic_v4_teardown(kvm); - } - --void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) -+static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) - { - struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - -@@ -379,29 +379,39 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) - vgic_flush_pending_lpis(vcpu); - - INIT_LIST_HEAD(&vgic_cpu->ap_list_head); -- vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; -+ if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { -+ vgic_unregister_redist_iodev(vcpu); -+ vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; -+ } - } - --static void __kvm_vgic_destroy(struct kvm *kvm) -+void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) -+{ -+ struct kvm *kvm = vcpu->kvm; -+ -+ mutex_lock(&kvm->slots_lock); -+ __kvm_vgic_vcpu_destroy(vcpu); -+ mutex_unlock(&kvm->slots_lock); -+} -+ -+void kvm_vgic_destroy(struct kvm *kvm) - { - struct kvm_vcpu *vcpu; - unsigned long i; - -- lockdep_assert_held(&kvm->arch.config_lock); -+ mutex_lock(&kvm->slots_lock); - - vgic_debug_destroy(kvm); - - kvm_for_each_vcpu(i, vcpu, kvm) -- kvm_vgic_vcpu_destroy(vcpu); -+ __kvm_vgic_vcpu_destroy(vcpu); -+ -+ mutex_lock(&kvm->arch.config_lock); - - kvm_vgic_dist_destroy(kvm); --} - --void kvm_vgic_destroy(struct kvm *kvm) --{ -- mutex_lock(&kvm->arch.config_lock); -- __kvm_vgic_destroy(kvm); - mutex_unlock(&kvm->arch.config_lock); -+ mutex_unlock(&kvm->slots_lock); - } - - /** -@@ -469,25 +479,26 @@ int kvm_vgic_map_resources(struct kvm *kvm) - type = VGIC_V3; - } - -- if (ret) { -- __kvm_vgic_destroy(kvm); -+ if (ret) - goto out; -- } -+ - dist->ready = true; - dist_base = dist->vgic_dist_base; - mutex_unlock(&kvm->arch.config_lock); - - ret = vgic_register_dist_iodev(kvm, dist_base, type); -- if (ret) { -+ if (ret) - kvm_err("Unable to register VGIC dist MMIO regions\n"); -- kvm_vgic_destroy(kvm); -- } -- mutex_unlock(&kvm->slots_lock); -- return ret; - -+ goto out_slots; - out: - mutex_unlock(&kvm->arch.config_lock); -+out_slots: - mutex_unlock(&kvm->slots_lock); -+ -+ if (ret) -+ kvm_vgic_destroy(kvm); -+ - return ret; - } - -diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c -index 188d2187eede9..871a45d4fc84c 100644 ---- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c -+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c -@@ -820,7 +820,7 @@ out_unlock: - return ret; - } - --static void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu) -+void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu) - { - struct vgic_io_device *rd_dev = &vcpu->arch.vgic_cpu.rd_iodev; - -diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h -index 23e280fa0a16f..9f80a580ca771 100644 ---- a/arch/arm64/kvm/vgic/vgic.h -+++ b/arch/arm64/kvm/vgic/vgic.h -@@ -229,6 +229,7 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq); - int vgic_v3_save_pending_tables(struct kvm *kvm); - int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count); - int vgic_register_redist_iodev(struct kvm_vcpu *vcpu); -+void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu); - bool vgic_v3_check_base(struct kvm *kvm); - - void vgic_v3_load(struct kvm_vcpu *vcpu); -diff --git a/arch/riscv/include/asm/signal.h b/arch/riscv/include/asm/signal.h -index 532c29ef03769..956ae0a01bad1 100644 ---- a/arch/riscv/include/asm/signal.h -+++ b/arch/riscv/include/asm/signal.h -@@ -7,6 +7,6 @@ - #include - - asmlinkage __visible --void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); -+void do_work_pending(struct pt_regs *regs, unsigned long thread_info_flags); - - #endif -diff --git a/arch/s390/include/asm/fpu/api.h b/arch/s390/include/asm/fpu/api.h -index b714ed0ef6885..9acf48e53a87f 100644 ---- a/arch/s390/include/asm/fpu/api.h -+++ b/arch/s390/include/asm/fpu/api.h -@@ -79,7 +79,7 @@ static inline int test_fp_ctl(u32 fpc) - #define KERNEL_VXR_HIGH (KERNEL_VXR_V16V23|KERNEL_VXR_V24V31) - - #define KERNEL_VXR (KERNEL_VXR_LOW|KERNEL_VXR_HIGH) --#define KERNEL_FPR (KERNEL_FPC|KERNEL_VXR_V0V7) -+#define KERNEL_FPR (KERNEL_FPC|KERNEL_VXR_LOW) - - struct kernel_fpu; - -diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c -index 46b7ee0ab01a4..6b8c93989aa31 100644 ---- a/arch/x86/kernel/alternative.c -+++ b/arch/x86/kernel/alternative.c -@@ -1015,8 +1015,8 @@ void __init_or_module text_poke_early(void *addr, const void *opcode, - } else { - local_irq_save(flags); - memcpy(addr, opcode, len); -- local_irq_restore(flags); - sync_core(); -+ local_irq_restore(flags); - - /* - * Could also do a CLFLUSH here to speed up CPU recovery; but -diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c -index 5e680e039d0e1..4686c1d9d0cfd 100644 ---- a/arch/x86/net/bpf_jit_comp.c -+++ b/arch/x86/net/bpf_jit_comp.c -@@ -2553,3 +2553,49 @@ void bpf_jit_free(struct bpf_prog *prog) - - bpf_prog_unlock_free(prog); - } -+ -+void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke, -+ struct bpf_prog *new, struct bpf_prog *old) -+{ -+ u8 *old_addr, *new_addr, *old_bypass_addr; -+ int ret; -+ -+ old_bypass_addr = old ? NULL : poke->bypass_addr; -+ old_addr = old ? (u8 *)old->bpf_func + poke->adj_off : NULL; -+ new_addr = new ? (u8 *)new->bpf_func + poke->adj_off : NULL; -+ -+ /* -+ * On program loading or teardown, the program's kallsym entry -+ * might not be in place, so we use __bpf_arch_text_poke to skip -+ * the kallsyms check. -+ */ -+ if (new) { -+ ret = __bpf_arch_text_poke(poke->tailcall_target, -+ BPF_MOD_JUMP, -+ old_addr, new_addr); -+ BUG_ON(ret < 0); -+ if (!old) { -+ ret = __bpf_arch_text_poke(poke->tailcall_bypass, -+ BPF_MOD_JUMP, -+ poke->bypass_addr, -+ NULL); -+ BUG_ON(ret < 0); -+ } -+ } else { -+ ret = __bpf_arch_text_poke(poke->tailcall_bypass, -+ BPF_MOD_JUMP, -+ old_bypass_addr, -+ poke->bypass_addr); -+ BUG_ON(ret < 0); -+ /* let other CPUs finish the execution of program -+ * so that it will not possible to expose them -+ * to invalid nop, stack unwind, nop state -+ */ -+ if (!ret) -+ synchronize_rcu(); -+ ret = __bpf_arch_text_poke(poke->tailcall_target, -+ BPF_MOD_JUMP, -+ old_addr, NULL); -+ BUG_ON(ret < 0); -+ } -+} -diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig -index 9b1ec5d8c99c8..a65fc2ae15b49 100644 ---- a/arch/x86/xen/Kconfig -+++ b/arch/x86/xen/Kconfig -@@ -9,6 +9,7 @@ config XEN - select PARAVIRT_CLOCK - select X86_HV_CALLBACK_VECTOR - depends on X86_64 || (X86_32 && X86_PAE) -+ depends on X86_64 || (X86_GENERIC || MPENTIUM4 || MCORE2 || MATOM || MK8) - depends on X86_LOCAL_APIC && X86_TSC - help - This is the Linux Xen port. Enabling this will allow the -diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 426d0b42685a0..127e3ceb59799 100644 ---- a/drivers/block/loop.c -+++ b/drivers/block/loop.c -@@ -1777,14 +1777,43 @@ static const struct block_device_operations lo_fops = { - /* - * If max_loop is specified, create that many devices upfront. - * This also becomes a hard limit. If max_loop is not specified, -+ * the default isn't a hard limit (as before commit 85c50197716c -+ * changed the default value from 0 for max_loop=0 reasons), just - * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module - * init time. Loop devices can be requested on-demand with the - * /dev/loop-control interface, or be instantiated by accessing - * a 'dead' device node. - */ - static int max_loop = CONFIG_BLK_DEV_LOOP_MIN_COUNT; --module_param(max_loop, int, 0444); -+ -+#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD -+static bool max_loop_specified; -+ -+static int max_loop_param_set_int(const char *val, -+ const struct kernel_param *kp) -+{ -+ int ret; -+ -+ ret = param_set_int(val, kp); -+ if (ret < 0) -+ return ret; -+ -+ max_loop_specified = true; -+ return 0; -+} -+ -+static const struct kernel_param_ops max_loop_param_ops = { -+ .set = max_loop_param_set_int, -+ .get = param_get_int, -+}; -+ -+module_param_cb(max_loop, &max_loop_param_ops, &max_loop, 0444); - MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); -+#else -+module_param(max_loop, int, 0444); -+MODULE_PARM_DESC(max_loop, "Initial number of loop devices"); -+#endif -+ - module_param(max_part, int, 0444); - MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device"); - -@@ -2089,14 +2118,18 @@ static void loop_remove(struct loop_device *lo) - put_disk(lo->lo_disk); - } - -+#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD - static void loop_probe(dev_t dev) - { - int idx = MINOR(dev) >> part_shift; - -- if (max_loop && idx >= max_loop) -+ if (max_loop_specified && max_loop && idx >= max_loop) - return; - loop_add(idx); - } -+#else -+#define loop_probe NULL -+#endif /* !CONFIG_BLOCK_LEGACY_AUTOLOAD */ - - static int loop_control_remove(int idx) - { -@@ -2277,6 +2310,9 @@ module_exit(loop_exit); - static int __init max_loop_setup(char *str) - { - max_loop = simple_strtol(str, NULL, 0); -+#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD -+ max_loop_specified = true; -+#endif - return 1; - } - -diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c -index c2f0f74193f0e..3fa74051f31b4 100644 ---- a/drivers/block/ublk_drv.c -+++ b/drivers/block/ublk_drv.c -@@ -103,6 +103,9 @@ struct ublk_uring_cmd_pdu { - */ - #define UBLK_IO_FLAG_NEED_GET_DATA 0x08 - -+/* atomic RW with ubq->cancel_lock */ -+#define UBLK_IO_FLAG_CANCELED 0x80000000 -+ - struct ublk_io { - /* userspace buffer address from io cmd */ - __u64 addr; -@@ -126,6 +129,7 @@ struct ublk_queue { - unsigned int max_io_sz; - bool force_abort; - unsigned short nr_io_ready; /* how many ios setup */ -+ spinlock_t cancel_lock; - struct ublk_device *dev; - struct ublk_io ios[]; - }; -@@ -1045,28 +1049,28 @@ static inline bool ublk_queue_ready(struct ublk_queue *ubq) - return ubq->nr_io_ready == ubq->q_depth; - } - --static void ublk_cmd_cancel_cb(struct io_uring_cmd *cmd, unsigned issue_flags) --{ -- io_uring_cmd_done(cmd, UBLK_IO_RES_ABORT, 0, issue_flags); --} -- - static void ublk_cancel_queue(struct ublk_queue *ubq) - { - int i; - -- if (!ublk_queue_ready(ubq)) -- return; -- - for (i = 0; i < ubq->q_depth; i++) { - struct ublk_io *io = &ubq->ios[i]; - -- if (io->flags & UBLK_IO_FLAG_ACTIVE) -- io_uring_cmd_complete_in_task(io->cmd, -- ublk_cmd_cancel_cb); -- } -+ if (io->flags & UBLK_IO_FLAG_ACTIVE) { -+ bool done; - -- /* all io commands are canceled */ -- ubq->nr_io_ready = 0; -+ spin_lock(&ubq->cancel_lock); -+ done = !!(io->flags & UBLK_IO_FLAG_CANCELED); -+ if (!done) -+ io->flags |= UBLK_IO_FLAG_CANCELED; -+ spin_unlock(&ubq->cancel_lock); -+ -+ if (!done) -+ io_uring_cmd_done(io->cmd, -+ UBLK_IO_RES_ABORT, 0, -+ IO_URING_F_UNLOCKED); -+ } -+ } - } - - /* Cancel all pending commands, must be called after del_gendisk() returns */ -@@ -1113,7 +1117,6 @@ static void __ublk_quiesce_dev(struct ublk_device *ub) - blk_mq_quiesce_queue(ub->ub_disk->queue); - ublk_wait_tagset_rqs_idle(ub); - ub->dev_info.state = UBLK_S_DEV_QUIESCED; -- ublk_cancel_dev(ub); - /* we are going to release task_struct of ubq_daemon and resets - * ->ubq_daemon to NULL. So in monitor_work, check on ubq_daemon causes UAF. - * Besides, monitor_work is not necessary in QUIESCED state since we have -@@ -1136,6 +1139,7 @@ static void ublk_quiesce_work_fn(struct work_struct *work) - __ublk_quiesce_dev(ub); - unlock: - mutex_unlock(&ub->mutex); -+ ublk_cancel_dev(ub); - } - - static void ublk_unquiesce_dev(struct ublk_device *ub) -@@ -1175,8 +1179,8 @@ static void ublk_stop_dev(struct ublk_device *ub) - put_disk(ub->ub_disk); - ub->ub_disk = NULL; - unlock: -- ublk_cancel_dev(ub); - mutex_unlock(&ub->mutex); -+ ublk_cancel_dev(ub); - cancel_delayed_work_sync(&ub->monitor_work); - } - -@@ -1353,6 +1357,7 @@ static int ublk_init_queue(struct ublk_device *ub, int q_id) - void *ptr; - int size; - -+ spin_lock_init(&ubq->cancel_lock); - ubq->flags = ub->dev_info.flags; - ubq->q_id = q_id; - ubq->q_depth = ub->dev_info.queue_depth; -@@ -1882,8 +1887,9 @@ static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq) - int i; - - WARN_ON_ONCE(!(ubq->ubq_daemon && ubq_daemon_is_dying(ubq))); -+ - /* All old ioucmds have to be completed */ -- WARN_ON_ONCE(ubq->nr_io_ready); -+ ubq->nr_io_ready = 0; - /* old daemon is PF_EXITING, put it now */ - put_task_struct(ubq->ubq_daemon); - /* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */ -diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c -index 4415d850d698b..44dc91555aa00 100644 ---- a/drivers/bluetooth/hci_vhci.c -+++ b/drivers/bluetooth/hci_vhci.c -@@ -11,6 +11,7 @@ - #include - #include - -+#include - #include - #include - #include -@@ -44,6 +45,7 @@ struct vhci_data { - bool wakeup; - __u16 msft_opcode; - bool aosp_capable; -+ atomic_t initialized; - }; - - static int vhci_open_dev(struct hci_dev *hdev) -@@ -75,11 +77,10 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) - - memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); - -- mutex_lock(&data->open_mutex); - skb_queue_tail(&data->readq, skb); -- mutex_unlock(&data->open_mutex); - -- wake_up_interruptible(&data->read_wait); -+ if (atomic_read(&data->initialized)) -+ wake_up_interruptible(&data->read_wait); - return 0; - } - -@@ -363,7 +364,8 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode) - skb_put_u8(skb, 0xff); - skb_put_u8(skb, opcode); - put_unaligned_le16(hdev->id, skb_put(skb, 2)); -- skb_queue_tail(&data->readq, skb); -+ skb_queue_head(&data->readq, skb); -+ atomic_inc(&data->initialized); - - wake_up_interruptible(&data->read_wait); - return 0; -diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c -index 59a2fe2448f17..15c6b85b125d4 100644 ---- a/drivers/bus/ti-sysc.c -+++ b/drivers/bus/ti-sysc.c -@@ -2174,13 +2174,23 @@ static int sysc_reset(struct sysc *ddata) - sysc_val = sysc_read_sysconfig(ddata); - sysc_val |= sysc_mask; - sysc_write(ddata, sysc_offset, sysc_val); -- /* Flush posted write */ -+ -+ /* -+ * Some devices need a delay before reading registers -+ * after reset. Presumably a srst_udelay is not needed -+ * for devices that use a rstctrl register reset. -+ */ -+ if (ddata->cfg.srst_udelay) -+ fsleep(ddata->cfg.srst_udelay); -+ -+ /* -+ * Flush posted write. For devices needing srst_udelay -+ * this should trigger an interconnect error if the -+ * srst_udelay value is needed but not configured. -+ */ - sysc_val = sysc_read_sysconfig(ddata); - } - -- if (ddata->cfg.srst_udelay) -- fsleep(ddata->cfg.srst_udelay); -- - if (ddata->post_reset_quirk) - ddata->post_reset_quirk(ddata); - -diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c -index c22fcaa44a614..6b7d47a52b10a 100644 ---- a/drivers/gpio/gpio-dwapb.c -+++ b/drivers/gpio/gpio-dwapb.c -@@ -283,13 +283,15 @@ static void dwapb_irq_enable(struct irq_data *d) - { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct dwapb_gpio *gpio = to_dwapb_gpio(gc); -+ irq_hw_number_t hwirq = irqd_to_hwirq(d); - unsigned long flags; - u32 val; - - raw_spin_lock_irqsave(&gc->bgpio_lock, flags); -- val = dwapb_read(gpio, GPIO_INTEN); -- val |= BIT(irqd_to_hwirq(d)); -+ val = dwapb_read(gpio, GPIO_INTEN) | BIT(hwirq); - dwapb_write(gpio, GPIO_INTEN, val); -+ val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(hwirq); -+ dwapb_write(gpio, GPIO_INTMASK, val); - raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); - } - -@@ -297,12 +299,14 @@ static void dwapb_irq_disable(struct irq_data *d) - { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct dwapb_gpio *gpio = to_dwapb_gpio(gc); -+ irq_hw_number_t hwirq = irqd_to_hwirq(d); - unsigned long flags; - u32 val; - - raw_spin_lock_irqsave(&gc->bgpio_lock, flags); -- val = dwapb_read(gpio, GPIO_INTEN); -- val &= ~BIT(irqd_to_hwirq(d)); -+ val = dwapb_read(gpio, GPIO_INTMASK) | BIT(hwirq); -+ dwapb_write(gpio, GPIO_INTMASK, val); -+ val = dwapb_read(gpio, GPIO_INTEN) & ~BIT(hwirq); - dwapb_write(gpio, GPIO_INTEN, val); - raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); - } -diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c -index 6ab1cf489d035..e40c93f0960b4 100644 ---- a/drivers/gpio/gpiolib-cdev.c -+++ b/drivers/gpio/gpiolib-cdev.c -@@ -2444,10 +2444,7 @@ static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip) - return 0; - } - --/* -- * gpio_ioctl() - ioctl handler for the GPIO chardev -- */ --static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+static long gpio_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg) - { - struct gpio_chardev_data *cdev = file->private_data; - struct gpio_device *gdev = cdev->gdev; -@@ -2484,6 +2481,17 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - } - } - -+/* -+ * gpio_ioctl() - ioctl handler for the GPIO chardev -+ */ -+static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ struct gpio_chardev_data *cdev = file->private_data; -+ -+ return call_ioctl_locked(file, cmd, arg, cdev->gdev, -+ gpio_ioctl_unlocked); -+} -+ - #ifdef CONFIG_COMPAT - static long gpio_ioctl_compat(struct file *file, unsigned int cmd, - unsigned long arg) -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 6d5f3c5fb4a62..13e0b521e3dba 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5104,6 +5104,9 @@ static void fill_dc_dirty_rects(struct drm_plane *plane, - if (plane->type == DRM_PLANE_TYPE_CURSOR) - return; - -+ if (new_plane_state->rotation != DRM_MODE_ROTATE_0) -+ goto ffu; -+ - num_clips = drm_plane_get_damage_clips_count(new_plane_state); - clips = drm_plane_get_damage_clips(new_plane_state); - -diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h -index 848db8676adfd..46c2b991aa108 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h -+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h -@@ -465,6 +465,7 @@ struct dc_cursor_mi_param { - struct fixed31_32 v_scale_ratio; - enum dc_rotation_angle rotation; - bool mirror; -+ struct dc_stream_state *stream; - }; - - /* IPP related types */ -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -index d84579da64003..009b5861a3fec 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c -@@ -3427,7 +3427,8 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) - .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, - .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, - .rotation = pipe_ctx->plane_state->rotation, -- .mirror = pipe_ctx->plane_state->horizontal_mirror -+ .mirror = pipe_ctx->plane_state->horizontal_mirror, -+ .stream = pipe_ctx->stream, - }; - bool pipe_split_on = false; - bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) || -diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c -index 4566bc7abf17e..aa252dc263267 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c -@@ -1075,8 +1075,16 @@ void hubp2_cursor_set_position( - if (src_y_offset < 0) - src_y_offset = 0; - /* Save necessary cursor info x, y position. w, h is saved in attribute func. */ -- hubp->cur_rect.x = src_x_offset + param->viewport.x; -- hubp->cur_rect.y = src_y_offset + param->viewport.y; -+ if (param->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 && -+ param->rotation != ROTATION_ANGLE_0) { -+ hubp->cur_rect.x = 0; -+ hubp->cur_rect.y = 0; -+ hubp->cur_rect.w = param->stream->timing.h_addressable; -+ hubp->cur_rect.h = param->stream->timing.v_addressable; -+ } else { -+ hubp->cur_rect.x = src_x_offset + param->viewport.x; -+ hubp->cur_rect.y = src_y_offset + param->viewport.y; -+ } - } - - void hubp2_clk_cntl(struct hubp *hubp, bool enable) -diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -index 53262f6bc40b0..72bec33e371f3 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -@@ -994,5 +994,8 @@ void dcn30_prepare_bandwidth(struct dc *dc, - dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); - - dcn20_prepare_bandwidth(dc, context); -+ -+ dc_dmub_srv_p_state_delegate(dc, -+ context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching, context); - } - -diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c -index 18f0a5ae3bacd..a502af0b6dd47 100644 ---- a/drivers/gpu/drm/i915/display/intel_atomic.c -+++ b/drivers/gpu/drm/i915/display/intel_atomic.c -@@ -41,6 +41,7 @@ - #include "intel_global_state.h" - #include "intel_hdcp.h" - #include "intel_psr.h" -+#include "intel_fb.h" - #include "skl_universal_plane.h" - - /** -@@ -302,198 +303,6 @@ intel_crtc_destroy_state(struct drm_crtc *crtc, - kfree(crtc_state); - } - --static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state, -- int num_scalers_need, struct intel_crtc *intel_crtc, -- const char *name, int idx, -- struct intel_plane_state *plane_state, -- int *scaler_id) --{ -- struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); -- int j; -- u32 mode; -- -- if (*scaler_id < 0) { -- /* find a free scaler */ -- for (j = 0; j < intel_crtc->num_scalers; j++) { -- if (scaler_state->scalers[j].in_use) -- continue; -- -- *scaler_id = j; -- scaler_state->scalers[*scaler_id].in_use = 1; -- break; -- } -- } -- -- if (drm_WARN(&dev_priv->drm, *scaler_id < 0, -- "Cannot find scaler for %s:%d\n", name, idx)) -- return; -- -- /* set scaler mode */ -- if (plane_state && plane_state->hw.fb && -- plane_state->hw.fb->format->is_yuv && -- plane_state->hw.fb->format->num_planes > 1) { -- struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); -- if (DISPLAY_VER(dev_priv) == 9) { -- mode = SKL_PS_SCALER_MODE_NV12; -- } else if (icl_is_hdr_plane(dev_priv, plane->id)) { -- /* -- * On gen11+'s HDR planes we only use the scaler for -- * scaling. They have a dedicated chroma upsampler, so -- * we don't need the scaler to upsample the UV plane. -- */ -- mode = PS_SCALER_MODE_NORMAL; -- } else { -- struct intel_plane *linked = -- plane_state->planar_linked_plane; -- -- mode = PS_SCALER_MODE_PLANAR; -- -- if (linked) -- mode |= PS_PLANE_Y_SEL(linked->id); -- } -- } else if (DISPLAY_VER(dev_priv) >= 10) { -- mode = PS_SCALER_MODE_NORMAL; -- } else if (num_scalers_need == 1 && intel_crtc->num_scalers > 1) { -- /* -- * when only 1 scaler is in use on a pipe with 2 scalers -- * scaler 0 operates in high quality (HQ) mode. -- * In this case use scaler 0 to take advantage of HQ mode -- */ -- scaler_state->scalers[*scaler_id].in_use = 0; -- *scaler_id = 0; -- scaler_state->scalers[0].in_use = 1; -- mode = SKL_PS_SCALER_MODE_HQ; -- } else { -- mode = SKL_PS_SCALER_MODE_DYN; -- } -- -- drm_dbg_kms(&dev_priv->drm, "Attached scaler id %u.%u to %s:%d\n", -- intel_crtc->pipe, *scaler_id, name, idx); -- scaler_state->scalers[*scaler_id].mode = mode; --} -- --/** -- * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests -- * @dev_priv: i915 device -- * @intel_crtc: intel crtc -- * @crtc_state: incoming crtc_state to validate and setup scalers -- * -- * This function sets up scalers based on staged scaling requests for -- * a @crtc and its planes. It is called from crtc level check path. If request -- * is a supportable request, it attaches scalers to requested planes and crtc. -- * -- * This function takes into account the current scaler(s) in use by any planes -- * not being part of this atomic state -- * -- * Returns: -- * 0 - scalers were setup succesfully -- * error code - otherwise -- */ --int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, -- struct intel_crtc *intel_crtc, -- struct intel_crtc_state *crtc_state) --{ -- struct drm_plane *plane = NULL; -- struct intel_plane *intel_plane; -- struct intel_plane_state *plane_state = NULL; -- struct intel_crtc_scaler_state *scaler_state = -- &crtc_state->scaler_state; -- struct drm_atomic_state *drm_state = crtc_state->uapi.state; -- struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state); -- int num_scalers_need; -- int i; -- -- num_scalers_need = hweight32(scaler_state->scaler_users); -- -- /* -- * High level flow: -- * - staged scaler requests are already in scaler_state->scaler_users -- * - check whether staged scaling requests can be supported -- * - add planes using scalers that aren't in current transaction -- * - assign scalers to requested users -- * - as part of plane commit, scalers will be committed -- * (i.e., either attached or detached) to respective planes in hw -- * - as part of crtc_commit, scaler will be either attached or detached -- * to crtc in hw -- */ -- -- /* fail if required scalers > available scalers */ -- if (num_scalers_need > intel_crtc->num_scalers){ -- drm_dbg_kms(&dev_priv->drm, -- "Too many scaling requests %d > %d\n", -- num_scalers_need, intel_crtc->num_scalers); -- return -EINVAL; -- } -- -- /* walkthrough scaler_users bits and start assigning scalers */ -- for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) { -- int *scaler_id; -- const char *name; -- int idx; -- -- /* skip if scaler not required */ -- if (!(scaler_state->scaler_users & (1 << i))) -- continue; -- -- if (i == SKL_CRTC_INDEX) { -- name = "CRTC"; -- idx = intel_crtc->base.base.id; -- -- /* panel fitter case: assign as a crtc scaler */ -- scaler_id = &scaler_state->scaler_id; -- } else { -- name = "PLANE"; -- -- /* plane scaler case: assign as a plane scaler */ -- /* find the plane that set the bit as scaler_user */ -- plane = drm_state->planes[i].ptr; -- -- /* -- * to enable/disable hq mode, add planes that are using scaler -- * into this transaction -- */ -- if (!plane) { -- struct drm_plane_state *state; -- -- /* -- * GLK+ scalers don't have a HQ mode so it -- * isn't necessary to change between HQ and dyn mode -- * on those platforms. -- */ -- if (DISPLAY_VER(dev_priv) >= 10) -- continue; -- -- plane = drm_plane_from_index(&dev_priv->drm, i); -- state = drm_atomic_get_plane_state(drm_state, plane); -- if (IS_ERR(state)) { -- drm_dbg_kms(&dev_priv->drm, -- "Failed to add [PLANE:%d] to drm_state\n", -- plane->base.id); -- return PTR_ERR(state); -- } -- } -- -- intel_plane = to_intel_plane(plane); -- idx = plane->base.id; -- -- /* plane on different crtc cannot be a scaler user of this crtc */ -- if (drm_WARN_ON(&dev_priv->drm, -- intel_plane->pipe != intel_crtc->pipe)) -- continue; -- -- plane_state = intel_atomic_get_new_plane_state(intel_state, -- intel_plane); -- scaler_id = &plane_state->scaler_id; -- } -- -- intel_atomic_setup_scaler(scaler_state, num_scalers_need, -- intel_crtc, name, idx, -- plane_state, scaler_id); -- } -- -- return 0; --} -- - struct drm_atomic_state * - intel_atomic_state_alloc(struct drm_device *dev) - { -diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h -index 1dc439983dd94..e506f6a873447 100644 ---- a/drivers/gpu/drm/i915/display/intel_atomic.h -+++ b/drivers/gpu/drm/i915/display/intel_atomic.h -@@ -52,8 +52,4 @@ struct intel_crtc_state * - intel_atomic_get_crtc_state(struct drm_atomic_state *state, - struct intel_crtc *crtc); - --int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, -- struct intel_crtc *intel_crtc, -- struct intel_crtc_state *crtc_state); -- - #endif /* __INTEL_ATOMIC_H__ */ -diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c -index 1777a12f2f421..fb8d1d63407a2 100644 ---- a/drivers/gpu/drm/i915/display/intel_display.c -+++ b/drivers/gpu/drm/i915/display/intel_display.c -@@ -6481,6 +6481,17 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state, - return -EINVAL; - } - -+ /* -+ * FIXME: Bigjoiner+async flip is busted currently. -+ * Remove this check once the issues are fixed. -+ */ -+ if (new_crtc_state->bigjoiner_pipes) { -+ drm_dbg_kms(&i915->drm, -+ "[CRTC:%d:%s] async flip disallowed with bigjoiner\n", -+ crtc->base.base.id, crtc->base.name); -+ return -EINVAL; -+ } -+ - for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, - new_plane_state, i) { - if (plane->pipe != crtc->pipe) -diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c -index 23d854bd73b77..c69a638796c62 100644 ---- a/drivers/gpu/drm/i915/display/intel_fb.c -+++ b/drivers/gpu/drm/i915/display/intel_fb.c -@@ -1176,7 +1176,8 @@ bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb) - { - struct drm_i915_private *i915 = to_i915(fb->base.dev); - -- return IS_ALDERLAKE_P(i915) && fb->base.modifier != DRM_FORMAT_MOD_LINEAR; -+ return (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) && -+ intel_fb_uses_dpt(&fb->base); - } - - static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation) -@@ -1312,9 +1313,11 @@ plane_view_scanout_stride(const struct intel_framebuffer *fb, int color_plane, - unsigned int tile_width, - unsigned int src_stride_tiles, unsigned int dst_stride_tiles) - { -+ struct drm_i915_private *i915 = to_i915(fb->base.dev); - unsigned int stride_tiles; - -- if (IS_ALDERLAKE_P(to_i915(fb->base.dev))) -+ if ((IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) && -+ src_stride_tiles < dst_stride_tiles) - stride_tiles = src_stride_tiles; - else - stride_tiles = dst_stride_tiles; -@@ -1520,7 +1523,8 @@ static void intel_fb_view_init(struct drm_i915_private *i915, struct intel_fb_vi - memset(view, 0, sizeof(*view)); - view->gtt.type = view_type; - -- if (view_type == I915_GTT_VIEW_REMAPPED && IS_ALDERLAKE_P(i915)) -+ if (view_type == I915_GTT_VIEW_REMAPPED && -+ (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)) - view->gtt.remapped.plane_alignment = SZ_2M / PAGE_SIZE; - } - -diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c -index 90f42f63128ec..0b74f91e865d0 100644 ---- a/drivers/gpu/drm/i915/display/skl_scaler.c -+++ b/drivers/gpu/drm/i915/display/skl_scaler.c -@@ -337,6 +337,263 @@ int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, - return 0; - } - -+static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state, -+ int num_scalers_need, struct intel_crtc *intel_crtc, -+ const char *name, int idx, -+ struct intel_plane_state *plane_state, -+ int *scaler_id) -+{ -+ struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); -+ int j; -+ u32 mode; -+ -+ if (*scaler_id < 0) { -+ /* find a free scaler */ -+ for (j = 0; j < intel_crtc->num_scalers; j++) { -+ if (scaler_state->scalers[j].in_use) -+ continue; -+ -+ *scaler_id = j; -+ scaler_state->scalers[*scaler_id].in_use = 1; -+ break; -+ } -+ } -+ -+ if (drm_WARN(&dev_priv->drm, *scaler_id < 0, -+ "Cannot find scaler for %s:%d\n", name, idx)) -+ return -EINVAL; -+ -+ /* set scaler mode */ -+ if (plane_state && plane_state->hw.fb && -+ plane_state->hw.fb->format->is_yuv && -+ plane_state->hw.fb->format->num_planes > 1) { -+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); -+ -+ if (DISPLAY_VER(dev_priv) == 9) { -+ mode = SKL_PS_SCALER_MODE_NV12; -+ } else if (icl_is_hdr_plane(dev_priv, plane->id)) { -+ /* -+ * On gen11+'s HDR planes we only use the scaler for -+ * scaling. They have a dedicated chroma upsampler, so -+ * we don't need the scaler to upsample the UV plane. -+ */ -+ mode = PS_SCALER_MODE_NORMAL; -+ } else { -+ struct intel_plane *linked = -+ plane_state->planar_linked_plane; -+ -+ mode = PS_SCALER_MODE_PLANAR; -+ -+ if (linked) -+ mode |= PS_PLANE_Y_SEL(linked->id); -+ } -+ } else if (DISPLAY_VER(dev_priv) >= 10) { -+ mode = PS_SCALER_MODE_NORMAL; -+ } else if (num_scalers_need == 1 && intel_crtc->num_scalers > 1) { -+ /* -+ * when only 1 scaler is in use on a pipe with 2 scalers -+ * scaler 0 operates in high quality (HQ) mode. -+ * In this case use scaler 0 to take advantage of HQ mode -+ */ -+ scaler_state->scalers[*scaler_id].in_use = 0; -+ *scaler_id = 0; -+ scaler_state->scalers[0].in_use = 1; -+ mode = SKL_PS_SCALER_MODE_HQ; -+ } else { -+ mode = SKL_PS_SCALER_MODE_DYN; -+ } -+ -+ /* -+ * FIXME: we should also check the scaler factors for pfit, so -+ * this shouldn't be tied directly to planes. -+ */ -+ if (plane_state && plane_state->hw.fb) { -+ const struct drm_framebuffer *fb = plane_state->hw.fb; -+ const struct drm_rect *src = &plane_state->uapi.src; -+ const struct drm_rect *dst = &plane_state->uapi.dst; -+ int hscale, vscale, max_vscale, max_hscale; -+ -+ /* -+ * FIXME: When two scalers are needed, but only one of -+ * them needs to downscale, we should make sure that -+ * the one that needs downscaling support is assigned -+ * as the first scaler, so we don't reject downscaling -+ * unnecessarily. -+ */ -+ -+ if (DISPLAY_VER(dev_priv) >= 14) { -+ /* -+ * On versions 14 and up, only the first -+ * scaler supports a vertical scaling factor -+ * of more than 1.0, while a horizontal -+ * scaling factor of 3.0 is supported. -+ */ -+ max_hscale = 0x30000 - 1; -+ if (*scaler_id == 0) -+ max_vscale = 0x30000 - 1; -+ else -+ max_vscale = 0x10000; -+ -+ } else if (DISPLAY_VER(dev_priv) >= 10 || -+ !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) { -+ max_hscale = 0x30000 - 1; -+ max_vscale = 0x30000 - 1; -+ } else { -+ max_hscale = 0x20000 - 1; -+ max_vscale = 0x20000 - 1; -+ } -+ -+ /* -+ * FIXME: We should change the if-else block above to -+ * support HQ vs dynamic scaler properly. -+ */ -+ -+ /* Check if required scaling is within limits */ -+ hscale = drm_rect_calc_hscale(src, dst, 1, max_hscale); -+ vscale = drm_rect_calc_vscale(src, dst, 1, max_vscale); -+ -+ if (hscale < 0 || vscale < 0) { -+ drm_dbg_kms(&dev_priv->drm, -+ "Scaler %d doesn't support required plane scaling\n", -+ *scaler_id); -+ drm_rect_debug_print("src: ", src, true); -+ drm_rect_debug_print("dst: ", dst, false); -+ -+ return -EINVAL; -+ } -+ } -+ -+ drm_dbg_kms(&dev_priv->drm, "Attached scaler id %u.%u to %s:%d\n", -+ intel_crtc->pipe, *scaler_id, name, idx); -+ scaler_state->scalers[*scaler_id].mode = mode; -+ -+ return 0; -+} -+ -+/** -+ * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests -+ * @dev_priv: i915 device -+ * @intel_crtc: intel crtc -+ * @crtc_state: incoming crtc_state to validate and setup scalers -+ * -+ * This function sets up scalers based on staged scaling requests for -+ * a @crtc and its planes. It is called from crtc level check path. If request -+ * is a supportable request, it attaches scalers to requested planes and crtc. -+ * -+ * This function takes into account the current scaler(s) in use by any planes -+ * not being part of this atomic state -+ * -+ * Returns: -+ * 0 - scalers were setup successfully -+ * error code - otherwise -+ */ -+int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, -+ struct intel_crtc *intel_crtc, -+ struct intel_crtc_state *crtc_state) -+{ -+ struct drm_plane *plane = NULL; -+ struct intel_plane *intel_plane; -+ struct intel_crtc_scaler_state *scaler_state = -+ &crtc_state->scaler_state; -+ struct drm_atomic_state *drm_state = crtc_state->uapi.state; -+ struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state); -+ int num_scalers_need; -+ int i; -+ -+ num_scalers_need = hweight32(scaler_state->scaler_users); -+ -+ /* -+ * High level flow: -+ * - staged scaler requests are already in scaler_state->scaler_users -+ * - check whether staged scaling requests can be supported -+ * - add planes using scalers that aren't in current transaction -+ * - assign scalers to requested users -+ * - as part of plane commit, scalers will be committed -+ * (i.e., either attached or detached) to respective planes in hw -+ * - as part of crtc_commit, scaler will be either attached or detached -+ * to crtc in hw -+ */ -+ -+ /* fail if required scalers > available scalers */ -+ if (num_scalers_need > intel_crtc->num_scalers) { -+ drm_dbg_kms(&dev_priv->drm, -+ "Too many scaling requests %d > %d\n", -+ num_scalers_need, intel_crtc->num_scalers); -+ return -EINVAL; -+ } -+ -+ /* walkthrough scaler_users bits and start assigning scalers */ -+ for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) { -+ struct intel_plane_state *plane_state = NULL; -+ int *scaler_id; -+ const char *name; -+ int idx, ret; -+ -+ /* skip if scaler not required */ -+ if (!(scaler_state->scaler_users & (1 << i))) -+ continue; -+ -+ if (i == SKL_CRTC_INDEX) { -+ name = "CRTC"; -+ idx = intel_crtc->base.base.id; -+ -+ /* panel fitter case: assign as a crtc scaler */ -+ scaler_id = &scaler_state->scaler_id; -+ } else { -+ name = "PLANE"; -+ -+ /* plane scaler case: assign as a plane scaler */ -+ /* find the plane that set the bit as scaler_user */ -+ plane = drm_state->planes[i].ptr; -+ -+ /* -+ * to enable/disable hq mode, add planes that are using scaler -+ * into this transaction -+ */ -+ if (!plane) { -+ struct drm_plane_state *state; -+ -+ /* -+ * GLK+ scalers don't have a HQ mode so it -+ * isn't necessary to change between HQ and dyn mode -+ * on those platforms. -+ */ -+ if (DISPLAY_VER(dev_priv) >= 10) -+ continue; -+ -+ plane = drm_plane_from_index(&dev_priv->drm, i); -+ state = drm_atomic_get_plane_state(drm_state, plane); -+ if (IS_ERR(state)) { -+ drm_dbg_kms(&dev_priv->drm, -+ "Failed to add [PLANE:%d] to drm_state\n", -+ plane->base.id); -+ return PTR_ERR(state); -+ } -+ } -+ -+ intel_plane = to_intel_plane(plane); -+ idx = plane->base.id; -+ -+ /* plane on different crtc cannot be a scaler user of this crtc */ -+ if (drm_WARN_ON(&dev_priv->drm, -+ intel_plane->pipe != intel_crtc->pipe)) -+ continue; -+ -+ plane_state = intel_atomic_get_new_plane_state(intel_state, -+ intel_plane); -+ scaler_id = &plane_state->scaler_id; -+ } -+ -+ ret = intel_atomic_setup_scaler(scaler_state, num_scalers_need, -+ intel_crtc, name, idx, -+ plane_state, scaler_id); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int glk_coef_tap(int i) - { - return i % 7; -diff --git a/drivers/gpu/drm/i915/display/skl_scaler.h b/drivers/gpu/drm/i915/display/skl_scaler.h -index 0097d5d08e102..f040f6ac061f2 100644 ---- a/drivers/gpu/drm/i915/display/skl_scaler.h -+++ b/drivers/gpu/drm/i915/display/skl_scaler.h -@@ -8,17 +8,22 @@ - #include - - enum drm_scaling_filter; -+enum pipe; - struct drm_i915_private; -+struct intel_crtc; - struct intel_crtc_state; --struct intel_plane_state; - struct intel_plane; --enum pipe; -+struct intel_plane_state; - - int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state); - - int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, - struct intel_plane_state *plane_state); - -+int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, -+ struct intel_crtc *intel_crtc, -+ struct intel_crtc_state *crtc_state); -+ - void skl_pfit_enable(const struct intel_crtc_state *crtc_state); - - void skl_program_plane_scaler(struct intel_plane *plane, -@@ -26,4 +31,5 @@ void skl_program_plane_scaler(struct intel_plane *plane, - const struct intel_plane_state *plane_state); - void skl_detach_scalers(const struct intel_crtc_state *crtc_state); - void skl_scaler_disable(const struct intel_crtc_state *old_crtc_state); -+ - #endif -diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c -index b96ae15e0ad91..6d35bb3974818 100644 ---- a/drivers/hid/i2c-hid/i2c-hid-acpi.c -+++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c -@@ -39,8 +39,13 @@ static const struct acpi_device_id i2c_hid_acpi_blacklist[] = { - * The CHPN0001 ACPI device, which is used to describe the Chipone - * ICN8505 controller, has a _CID of PNP0C50 but is not HID compatible. - */ -- {"CHPN0001", 0 }, -- { }, -+ { "CHPN0001" }, -+ /* -+ * The IDEA5002 ACPI device causes high interrupt usage and spurious -+ * wakeups from suspend. -+ */ -+ { "IDEA5002" }, -+ { } - }; - - /* HID I²C Device: 3cdff6f7-4267-4555-ad05-b30a3d8938de */ -@@ -115,9 +120,9 @@ static int i2c_hid_acpi_probe(struct i2c_client *client) - } - - static const struct acpi_device_id i2c_hid_acpi_match[] = { -- {"ACPI0C50", 0 }, -- {"PNP0C50", 0 }, -- { }, -+ { "ACPI0C50" }, -+ { "PNP0C50" }, -+ { } - }; - MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match); - -diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index 6adf3b141316b..86daf791aa27c 100644 ---- a/drivers/i2c/busses/i2c-aspeed.c -+++ b/drivers/i2c/busses/i2c-aspeed.c -@@ -249,18 +249,46 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - if (!slave) - return 0; - -- command = readl(bus->base + ASPEED_I2C_CMD_REG); -+ /* -+ * Handle stop conditions early, prior to SLAVE_MATCH. Some masters may drive -+ * transfers with low enough latency between the nak/stop phase of the current -+ * command and the start/address phase of the following command that the -+ * interrupts are coalesced by the time we process them. -+ */ -+ if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { -+ irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; -+ bus->slave_state = ASPEED_I2C_SLAVE_STOP; -+ } -+ -+ if (irq_status & ASPEED_I2CD_INTR_TX_NAK && -+ bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) { -+ irq_handled |= ASPEED_I2CD_INTR_TX_NAK; -+ bus->slave_state = ASPEED_I2C_SLAVE_STOP; -+ } -+ -+ /* Propagate any stop conditions to the slave implementation. */ -+ if (bus->slave_state == ASPEED_I2C_SLAVE_STOP) { -+ i2c_slave_event(slave, I2C_SLAVE_STOP, &value); -+ bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; -+ } - -- /* Slave was requested, restart state machine. */ -+ /* -+ * Now that we've dealt with any potentially coalesced stop conditions, -+ * address any start conditions. -+ */ - if (irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH) { - irq_handled |= ASPEED_I2CD_INTR_SLAVE_MATCH; - bus->slave_state = ASPEED_I2C_SLAVE_START; - } - -- /* Slave is not currently active, irq was for someone else. */ -+ /* -+ * If the slave has been stopped and not started then slave interrupt -+ * handling is complete. -+ */ - if (bus->slave_state == ASPEED_I2C_SLAVE_INACTIVE) - return irq_handled; - -+ command = readl(bus->base + ASPEED_I2C_CMD_REG); - dev_dbg(bus->dev, "slave irq status 0x%08x, cmd 0x%08x\n", - irq_status, command); - -@@ -279,17 +307,6 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - irq_handled |= ASPEED_I2CD_INTR_RX_DONE; - } - -- /* Slave was asked to stop. */ -- if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { -- irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; -- bus->slave_state = ASPEED_I2C_SLAVE_STOP; -- } -- if (irq_status & ASPEED_I2CD_INTR_TX_NAK && -- bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) { -- irq_handled |= ASPEED_I2CD_INTR_TX_NAK; -- bus->slave_state = ASPEED_I2C_SLAVE_STOP; -- } -- - switch (bus->slave_state) { - case ASPEED_I2C_SLAVE_READ_REQUESTED: - if (unlikely(irq_status & ASPEED_I2CD_INTR_TX_ACK)) -@@ -324,8 +341,7 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value); - break; - case ASPEED_I2C_SLAVE_STOP: -- i2c_slave_event(slave, I2C_SLAVE_STOP, &value); -- bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; -+ /* Stop event handling is done early. Unreachable. */ - break; - case ASPEED_I2C_SLAVE_START: - /* Slave was just started. Waiting for the next event. */; -diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c -index 642c5c4895e37..3ac253a27dd97 100644 ---- a/drivers/iio/adc/ti_am335x_adc.c -+++ b/drivers/iio/adc/ti_am335x_adc.c -@@ -671,8 +671,10 @@ static int tiadc_probe(struct platform_device *pdev) - platform_set_drvdata(pdev, indio_dev); - - err = tiadc_request_dma(pdev, adc_dev); -- if (err && err == -EPROBE_DEFER) -+ if (err && err != -ENODEV) { -+ dev_err_probe(&pdev->dev, err, "DMA request failed\n"); - goto err_dma; -+ } - - return 0; - -diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c b/drivers/iio/buffer/industrialio-triggered-buffer.c -index 8d4fc97d10059..2b7873e8a959b 100644 ---- a/drivers/iio/buffer/industrialio-triggered-buffer.c -+++ b/drivers/iio/buffer/industrialio-triggered-buffer.c -@@ -46,6 +46,16 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, - struct iio_buffer *buffer; - int ret; - -+ /* -+ * iio_triggered_buffer_cleanup() assumes that the buffer allocated here -+ * is assigned to indio_dev->buffer but this is only the case if this -+ * function is the first caller to iio_device_attach_buffer(). If -+ * indio_dev->buffer is already set then we can't proceed otherwise the -+ * cleanup function will try to free a buffer that was not allocated here. -+ */ -+ if (indio_dev->buffer) -+ return -EADDRINUSE; -+ - buffer = iio_kfifo_allocate(); - if (!buffer) { - ret = -ENOMEM; -diff --git a/drivers/iio/common/ms_sensors/ms_sensors_i2c.c b/drivers/iio/common/ms_sensors/ms_sensors_i2c.c -index 6633b35a94e69..9c9bc77003c7f 100644 ---- a/drivers/iio/common/ms_sensors/ms_sensors_i2c.c -+++ b/drivers/iio/common/ms_sensors/ms_sensors_i2c.c -@@ -15,8 +15,8 @@ - /* Conversion times in us */ - static const u16 ms_sensors_ht_t_conversion_time[] = { 50000, 25000, - 13000, 7000 }; --static const u16 ms_sensors_ht_h_conversion_time[] = { 16000, 3000, -- 5000, 8000 }; -+static const u16 ms_sensors_ht_h_conversion_time[] = { 16000, 5000, -+ 3000, 8000 }; - static const u16 ms_sensors_tp_conversion_time[] = { 500, 1100, 2100, - 4100, 8220, 16440 }; - -diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c -index 86fbbe9040503..19a1ef5351d24 100644 ---- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c -+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c -@@ -736,13 +736,13 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, - ret = inv_mpu6050_sensor_show(st, st->reg->gyro_offset, - chan->channel2, val); - mutex_unlock(&st->lock); -- return IIO_VAL_INT; -+ return ret; - case IIO_ACCEL: - mutex_lock(&st->lock); - ret = inv_mpu6050_sensor_show(st, st->reg->accl_offset, - chan->channel2, val); - mutex_unlock(&st->lock); -- return IIO_VAL_INT; -+ return ret; - - default: - return -EINVAL; -diff --git a/drivers/input/keyboard/ipaq-micro-keys.c b/drivers/input/keyboard/ipaq-micro-keys.c -index 13a66a8e3411f..e0c51189e329c 100644 ---- a/drivers/input/keyboard/ipaq-micro-keys.c -+++ b/drivers/input/keyboard/ipaq-micro-keys.c -@@ -105,6 +105,9 @@ static int micro_key_probe(struct platform_device *pdev) - keys->codes = devm_kmemdup(&pdev->dev, micro_keycodes, - keys->input->keycodesize * keys->input->keycodemax, - GFP_KERNEL); -+ if (!keys->codes) -+ return -ENOMEM; -+ - keys->input->keycode = keys->codes; - - __set_bit(EV_KEY, keys->input->evbit); -diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c -index e79f5497948b8..9116f4248fd09 100644 ---- a/drivers/input/misc/soc_button_array.c -+++ b/drivers/input/misc/soc_button_array.c -@@ -299,6 +299,11 @@ static int soc_button_parse_btn_desc(struct device *dev, - info->name = "power"; - info->event_code = KEY_POWER; - info->wakeup = true; -+ } else if (upage == 0x01 && usage == 0xc6) { -+ info->name = "airplane mode switch"; -+ info->event_type = EV_SW; -+ info->event_code = SW_RFKILL_ALL; -+ info->active_low = false; - } else if (upage == 0x01 && usage == 0xca) { - info->name = "rotation lock switch"; - info->event_type = EV_SW; -diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c -index 0c6fc954e7296..1d9494f64a215 100644 ---- a/drivers/interconnect/core.c -+++ b/drivers/interconnect/core.c -@@ -381,6 +381,9 @@ struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec) - } - mutex_unlock(&icc_lock); - -+ if (!node) -+ return ERR_PTR(-EINVAL); -+ - if (IS_ERR(node)) - return ERR_CAST(node); - -diff --git a/drivers/interconnect/qcom/sm8250.c b/drivers/interconnect/qcom/sm8250.c -index 5cdb058fa0959..9c2dd40d9a559 100644 ---- a/drivers/interconnect/qcom/sm8250.c -+++ b/drivers/interconnect/qcom/sm8250.c -@@ -551,6 +551,7 @@ static struct platform_driver qnoc_driver = { - .driver = { - .name = "qnoc-sm8250", - .of_match_table = qnoc_of_match, -+ .sync_state = icc_sync_state, - }, - }; - module_platform_driver(qnoc_driver); -diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c -index 382c5cc471952..100a6a236d92a 100644 ---- a/drivers/md/dm-bufio.c -+++ b/drivers/md/dm-bufio.c -@@ -1914,6 +1914,13 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c) - } - EXPORT_SYMBOL_GPL(dm_bufio_client_destroy); - -+void dm_bufio_client_reset(struct dm_bufio_client *c) -+{ -+ drop_buffers(c); -+ flush_work(&c->shrink_work); -+} -+EXPORT_SYMBOL_GPL(dm_bufio_client_reset); -+ - void dm_bufio_set_sector_offset(struct dm_bufio_client *c, sector_t start) - { - c->start = start; -diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c -index fe7dad3ffa75f..77fcff82c82ac 100644 ---- a/drivers/md/dm-integrity.c -+++ b/drivers/md/dm-integrity.c -@@ -1763,11 +1763,12 @@ static void integrity_metadata(struct work_struct *w) - sectors_to_process = dio->range.n_sectors; - - __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) { -+ struct bio_vec bv_copy = bv; - unsigned int pos; - char *mem, *checksums_ptr; - - again: -- mem = bvec_kmap_local(&bv); -+ mem = bvec_kmap_local(&bv_copy); - pos = 0; - checksums_ptr = checksums; - do { -@@ -1776,7 +1777,7 @@ again: - sectors_to_process -= ic->sectors_per_block; - pos += ic->sectors_per_block << SECTOR_SHIFT; - sector += ic->sectors_per_block; -- } while (pos < bv.bv_len && sectors_to_process && checksums != checksums_onstack); -+ } while (pos < bv_copy.bv_len && sectors_to_process && checksums != checksums_onstack); - kunmap_local(mem); - - r = dm_integrity_rw_tag(ic, checksums, &dio->metadata_block, &dio->metadata_offset, -@@ -1801,9 +1802,9 @@ again: - if (!sectors_to_process) - break; - -- if (unlikely(pos < bv.bv_len)) { -- bv.bv_offset += pos; -- bv.bv_len -= pos; -+ if (unlikely(pos < bv_copy.bv_len)) { -+ bv_copy.bv_offset += pos; -+ bv_copy.bv_len -= pos; - goto again; - } - } -diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c -index 4a0e15109997b..bb0e0a270f62a 100644 ---- a/drivers/md/dm-thin-metadata.c -+++ b/drivers/md/dm-thin-metadata.c -@@ -597,6 +597,8 @@ static int __format_metadata(struct dm_pool_metadata *pmd) - r = dm_tm_create_with_sm(pmd->bm, THIN_SUPERBLOCK_LOCATION, - &pmd->tm, &pmd->metadata_sm); - if (r < 0) { -+ pmd->tm = NULL; -+ pmd->metadata_sm = NULL; - DMERR("tm_create_with_sm failed"); - return r; - } -@@ -605,6 +607,7 @@ static int __format_metadata(struct dm_pool_metadata *pmd) - if (IS_ERR(pmd->data_sm)) { - DMERR("sm_disk_create failed"); - r = PTR_ERR(pmd->data_sm); -+ pmd->data_sm = NULL; - goto bad_cleanup_tm; - } - -@@ -635,11 +638,15 @@ static int __format_metadata(struct dm_pool_metadata *pmd) - - bad_cleanup_nb_tm: - dm_tm_destroy(pmd->nb_tm); -+ pmd->nb_tm = NULL; - bad_cleanup_data_sm: - dm_sm_destroy(pmd->data_sm); -+ pmd->data_sm = NULL; - bad_cleanup_tm: - dm_tm_destroy(pmd->tm); -+ pmd->tm = NULL; - dm_sm_destroy(pmd->metadata_sm); -+ pmd->metadata_sm = NULL; - - return r; - } -@@ -705,6 +712,8 @@ static int __open_metadata(struct dm_pool_metadata *pmd) - sizeof(disk_super->metadata_space_map_root), - &pmd->tm, &pmd->metadata_sm); - if (r < 0) { -+ pmd->tm = NULL; -+ pmd->metadata_sm = NULL; - DMERR("tm_open_with_sm failed"); - goto bad_unlock_sblock; - } -@@ -714,6 +723,7 @@ static int __open_metadata(struct dm_pool_metadata *pmd) - if (IS_ERR(pmd->data_sm)) { - DMERR("sm_disk_open failed"); - r = PTR_ERR(pmd->data_sm); -+ pmd->data_sm = NULL; - goto bad_cleanup_tm; - } - -@@ -740,9 +750,12 @@ static int __open_metadata(struct dm_pool_metadata *pmd) - - bad_cleanup_data_sm: - dm_sm_destroy(pmd->data_sm); -+ pmd->data_sm = NULL; - bad_cleanup_tm: - dm_tm_destroy(pmd->tm); -+ pmd->tm = NULL; - dm_sm_destroy(pmd->metadata_sm); -+ pmd->metadata_sm = NULL; - bad_unlock_sblock: - dm_bm_unlock(sblock); - -@@ -789,9 +802,13 @@ static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd, - bool destroy_bm) - { - dm_sm_destroy(pmd->data_sm); -+ pmd->data_sm = NULL; - dm_sm_destroy(pmd->metadata_sm); -+ pmd->metadata_sm = NULL; - dm_tm_destroy(pmd->nb_tm); -+ pmd->nb_tm = NULL; - dm_tm_destroy(pmd->tm); -+ pmd->tm = NULL; - if (destroy_bm) - dm_block_manager_destroy(pmd->bm); - } -@@ -999,8 +1016,7 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd) - __func__, r); - } - pmd_write_unlock(pmd); -- if (!pmd->fail_io) -- __destroy_persistent_data_objects(pmd, true); -+ __destroy_persistent_data_objects(pmd, true); - - kfree(pmd); - return 0; -@@ -1875,53 +1891,29 @@ static void __set_abort_with_changes_flags(struct dm_pool_metadata *pmd) - int dm_pool_abort_metadata(struct dm_pool_metadata *pmd) - { - int r = -EINVAL; -- struct dm_block_manager *old_bm = NULL, *new_bm = NULL; - - /* fail_io is double-checked with pmd->root_lock held below */ - if (unlikely(pmd->fail_io)) - return r; - -- /* -- * Replacement block manager (new_bm) is created and old_bm destroyed outside of -- * pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of -- * shrinker associated with the block manager's bufio client vs pmd root_lock). -- * - must take shrinker_rwsem without holding pmd->root_lock -- */ -- new_bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT, -- THIN_MAX_CONCURRENT_LOCKS); -- - pmd_write_lock(pmd); - if (pmd->fail_io) { - pmd_write_unlock(pmd); -- goto out; -+ return r; - } -- - __set_abort_with_changes_flags(pmd); -+ -+ /* destroy data_sm/metadata_sm/nb_tm/tm */ - __destroy_persistent_data_objects(pmd, false); -- old_bm = pmd->bm; -- if (IS_ERR(new_bm)) { -- DMERR("could not create block manager during abort"); -- pmd->bm = NULL; -- r = PTR_ERR(new_bm); -- goto out_unlock; -- } - -- pmd->bm = new_bm; -+ /* reset bm */ -+ dm_block_manager_reset(pmd->bm); -+ -+ /* rebuild data_sm/metadata_sm/nb_tm/tm */ - r = __open_or_format_metadata(pmd, false); -- if (r) { -- pmd->bm = NULL; -- goto out_unlock; -- } -- new_bm = NULL; --out_unlock: - if (r) - pmd->fail_io = true; - pmd_write_unlock(pmd); -- dm_block_manager_destroy(old_bm); --out: -- if (new_bm && !IS_ERR(new_bm)) -- dm_block_manager_destroy(new_bm); -- - return r; - } - -diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c -index 1f40100908d7c..2bbfbb704c751 100644 ---- a/drivers/md/persistent-data/dm-block-manager.c -+++ b/drivers/md/persistent-data/dm-block-manager.c -@@ -415,6 +415,12 @@ void dm_block_manager_destroy(struct dm_block_manager *bm) - } - EXPORT_SYMBOL_GPL(dm_block_manager_destroy); - -+void dm_block_manager_reset(struct dm_block_manager *bm) -+{ -+ dm_bufio_client_reset(bm->bufio); -+} -+EXPORT_SYMBOL_GPL(dm_block_manager_reset); -+ - unsigned int dm_bm_block_size(struct dm_block_manager *bm) - { - return dm_bufio_get_block_size(bm->bufio); -diff --git a/drivers/md/persistent-data/dm-block-manager.h b/drivers/md/persistent-data/dm-block-manager.h -index 58a23b8ec1902..4371d85d3c258 100644 ---- a/drivers/md/persistent-data/dm-block-manager.h -+++ b/drivers/md/persistent-data/dm-block-manager.h -@@ -35,6 +35,7 @@ struct dm_block_manager *dm_block_manager_create( - struct block_device *bdev, unsigned int block_size, - unsigned int max_held_per_thread); - void dm_block_manager_destroy(struct dm_block_manager *bm); -+void dm_block_manager_reset(struct dm_block_manager *bm); - - unsigned int dm_bm_block_size(struct dm_block_manager *bm); - dm_block_t dm_bm_nr_blocks(struct dm_block_manager *bm); -diff --git a/drivers/md/persistent-data/dm-space-map.h b/drivers/md/persistent-data/dm-space-map.h -index a015cd11f6e97..85aa0a3974fe0 100644 ---- a/drivers/md/persistent-data/dm-space-map.h -+++ b/drivers/md/persistent-data/dm-space-map.h -@@ -76,7 +76,8 @@ struct dm_space_map { - - static inline void dm_sm_destroy(struct dm_space_map *sm) - { -- sm->destroy(sm); -+ if (sm) -+ sm->destroy(sm); - } - - static inline int dm_sm_extend(struct dm_space_map *sm, dm_block_t extra_blocks) -diff --git a/drivers/md/persistent-data/dm-transaction-manager.c b/drivers/md/persistent-data/dm-transaction-manager.c -index 39885f8355847..557a3ecfe75a0 100644 ---- a/drivers/md/persistent-data/dm-transaction-manager.c -+++ b/drivers/md/persistent-data/dm-transaction-manager.c -@@ -197,6 +197,9 @@ EXPORT_SYMBOL_GPL(dm_tm_create_non_blocking_clone); - - void dm_tm_destroy(struct dm_transaction_manager *tm) - { -+ if (!tm) -+ return; -+ - if (!tm->is_clone) - wipe_shadow_table(tm); - -diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c -index 5935be190b9e2..5f2a6fcba9670 100644 ---- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c -+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c -@@ -866,10 +866,13 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter) - netdev_err(adapter->netdev, "offset(%d) > ring size(%d) !!\n", - offset, adapter->ring_size); - err = -1; -- goto failed; -+ goto free_buffer; - } - - return 0; -+free_buffer: -+ kfree(tx_ring->tx_buffer); -+ tx_ring->tx_buffer = NULL; - failed: - if (adapter->ring_vir_addr != NULL) { - dma_free_coherent(&pdev->dev, adapter->ring_size, -diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c -index bfddbff7bcdfb..28fb643d2917f 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c -@@ -399,9 +399,10 @@ static int otx2_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc) - static int otx2_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc) - { - struct otx2_nic *pfvf = netdev_priv(dev); -+ u8 old_pfc_en; - int err; - -- /* Save PFC configuration to interface */ -+ old_pfc_en = pfvf->pfc_en; - pfvf->pfc_en = pfc->pfc_en; - - if (pfvf->hw.tx_queues >= NIX_PF_PFC_PRIO_MAX) -@@ -411,13 +412,17 @@ static int otx2_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc) - * supported by the tx queue configuration - */ - err = otx2_check_pfc_config(pfvf); -- if (err) -+ if (err) { -+ pfvf->pfc_en = old_pfc_en; - return err; -+ } - - process_pfc: - err = otx2_config_priority_flow_ctrl(pfvf); -- if (err) -+ if (err) { -+ pfvf->pfc_en = old_pfc_en; - return err; -+ } - - /* Request Per channel Bpids */ - if (pfc->pfc_en) -@@ -425,6 +430,12 @@ process_pfc: - - err = otx2_pfc_txschq_update(pfvf); - if (err) { -+ if (pfc->pfc_en) -+ otx2_nix_config_bp(pfvf, false); -+ -+ otx2_pfc_txschq_stop(pfvf); -+ pfvf->pfc_en = old_pfc_en; -+ otx2_config_priority_flow_ctrl(pfvf); - dev_err(pfvf->dev, "%s failed to update TX schedulers\n", __func__); - return err; - } -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c -index b3253e263ebc8..ac6a0785b10d8 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c -@@ -48,6 +48,25 @@ - #define CREATE_TRACE_POINTS - #include "diag/cmd_tracepoint.h" - -+struct mlx5_ifc_mbox_out_bits { -+ u8 status[0x8]; -+ u8 reserved_at_8[0x18]; -+ -+ u8 syndrome[0x20]; -+ -+ u8 reserved_at_40[0x40]; -+}; -+ -+struct mlx5_ifc_mbox_in_bits { -+ u8 opcode[0x10]; -+ u8 uid[0x10]; -+ -+ u8 reserved_at_20[0x10]; -+ u8 op_mod[0x10]; -+ -+ u8 reserved_at_40[0x40]; -+}; -+ - enum { - CMD_IF_REV = 5, - }; -@@ -71,6 +90,26 @@ enum { - MLX5_CMD_DELIVERY_STAT_CMD_DESCR_ERR = 0x10, - }; - -+static u16 in_to_opcode(void *in) -+{ -+ return MLX5_GET(mbox_in, in, opcode); -+} -+ -+/* Returns true for opcodes that might be triggered very frequently and throttle -+ * the command interface. Limit their command slots usage. -+ */ -+static bool mlx5_cmd_is_throttle_opcode(u16 op) -+{ -+ switch (op) { -+ case MLX5_CMD_OP_CREATE_GENERAL_OBJECT: -+ case MLX5_CMD_OP_DESTROY_GENERAL_OBJECT: -+ case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: -+ case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: -+ return true; -+ } -+ return false; -+} -+ - static struct mlx5_cmd_work_ent * - cmd_alloc_ent(struct mlx5_cmd *cmd, struct mlx5_cmd_msg *in, - struct mlx5_cmd_msg *out, void *uout, int uout_size, -@@ -92,6 +131,7 @@ cmd_alloc_ent(struct mlx5_cmd *cmd, struct mlx5_cmd_msg *in, - ent->context = context; - ent->cmd = cmd; - ent->page_queue = page_queue; -+ ent->op = in_to_opcode(in->first.data); - refcount_set(&ent->refcnt, 1); - - return ent; -@@ -116,24 +156,27 @@ static u8 alloc_token(struct mlx5_cmd *cmd) - return token; - } - --static int cmd_alloc_index(struct mlx5_cmd *cmd) -+static int cmd_alloc_index(struct mlx5_cmd *cmd, struct mlx5_cmd_work_ent *ent) - { - unsigned long flags; - int ret; - - spin_lock_irqsave(&cmd->alloc_lock, flags); -- ret = find_first_bit(&cmd->bitmask, cmd->max_reg_cmds); -- if (ret < cmd->max_reg_cmds) -- clear_bit(ret, &cmd->bitmask); -+ ret = find_first_bit(&cmd->vars.bitmask, cmd->vars.max_reg_cmds); -+ if (ret < cmd->vars.max_reg_cmds) { -+ clear_bit(ret, &cmd->vars.bitmask); -+ ent->idx = ret; -+ cmd->ent_arr[ent->idx] = ent; -+ } - spin_unlock_irqrestore(&cmd->alloc_lock, flags); - -- return ret < cmd->max_reg_cmds ? ret : -ENOMEM; -+ return ret < cmd->vars.max_reg_cmds ? ret : -ENOMEM; - } - - static void cmd_free_index(struct mlx5_cmd *cmd, int idx) - { - lockdep_assert_held(&cmd->alloc_lock); -- set_bit(idx, &cmd->bitmask); -+ set_bit(idx, &cmd->vars.bitmask); - } - - static void cmd_ent_get(struct mlx5_cmd_work_ent *ent) -@@ -152,7 +195,7 @@ static void cmd_ent_put(struct mlx5_cmd_work_ent *ent) - - if (ent->idx >= 0) { - cmd_free_index(cmd, ent->idx); -- up(ent->page_queue ? &cmd->pages_sem : &cmd->sem); -+ up(ent->page_queue ? &cmd->vars.pages_sem : &cmd->vars.sem); - } - - cmd_free_ent(ent); -@@ -162,7 +205,7 @@ out: - - static struct mlx5_cmd_layout *get_inst(struct mlx5_cmd *cmd, int idx) - { -- return cmd->cmd_buf + (idx << cmd->log_stride); -+ return cmd->cmd_buf + (idx << cmd->vars.log_stride); - } - - static int mlx5_calc_cmd_blocks(struct mlx5_cmd_msg *msg) -@@ -753,25 +796,6 @@ static int cmd_status_to_err(u8 status) - } - } - --struct mlx5_ifc_mbox_out_bits { -- u8 status[0x8]; -- u8 reserved_at_8[0x18]; -- -- u8 syndrome[0x20]; -- -- u8 reserved_at_40[0x40]; --}; -- --struct mlx5_ifc_mbox_in_bits { -- u8 opcode[0x10]; -- u8 uid[0x10]; -- -- u8 reserved_at_20[0x10]; -- u8 op_mod[0x10]; -- -- u8 reserved_at_40[0x40]; --}; -- - void mlx5_cmd_out_err(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod, void *out) - { - u32 syndrome = MLX5_GET(mbox_out, out, syndrome); -@@ -789,7 +813,7 @@ static void cmd_status_print(struct mlx5_core_dev *dev, void *in, void *out) - u16 opcode, op_mod; - u16 uid; - -- opcode = MLX5_GET(mbox_in, in, opcode); -+ opcode = in_to_opcode(in); - op_mod = MLX5_GET(mbox_in, in, op_mod); - uid = MLX5_GET(mbox_in, in, uid); - -@@ -801,7 +825,7 @@ int mlx5_cmd_check(struct mlx5_core_dev *dev, int err, void *in, void *out) - { - /* aborted due to PCI error or via reset flow mlx5_cmd_trigger_completions() */ - if (err == -ENXIO) { -- u16 opcode = MLX5_GET(mbox_in, in, opcode); -+ u16 opcode = in_to_opcode(in); - u32 syndrome; - u8 status; - -@@ -830,9 +854,9 @@ static void dump_command(struct mlx5_core_dev *dev, - struct mlx5_cmd_work_ent *ent, int input) - { - struct mlx5_cmd_msg *msg = input ? ent->in : ent->out; -- u16 op = MLX5_GET(mbox_in, ent->lay->in, opcode); - struct mlx5_cmd_mailbox *next = msg->next; - int n = mlx5_calc_cmd_blocks(msg); -+ u16 op = ent->op; - int data_only; - u32 offset = 0; - int dump_len; -@@ -884,11 +908,6 @@ static void dump_command(struct mlx5_core_dev *dev, - mlx5_core_dbg(dev, "cmd[%d]: end dump\n", ent->idx); - } - --static u16 msg_to_opcode(struct mlx5_cmd_msg *in) --{ -- return MLX5_GET(mbox_in, in->first.data, opcode); --} -- - static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced); - - static void cb_timeout_handler(struct work_struct *work) -@@ -906,13 +925,13 @@ static void cb_timeout_handler(struct work_struct *work) - /* Maybe got handled by eq recover ? */ - if (!test_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state)) { - mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, recovered after timeout\n", ent->idx, -- mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); -+ mlx5_command_str(ent->op), ent->op); - goto out; /* phew, already handled */ - } - - ent->ret = -ETIMEDOUT; - mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, timeout. Will cause a leak of a command resource\n", -- ent->idx, mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); -+ ent->idx, mlx5_command_str(ent->op), ent->op); - mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true); - - out: -@@ -955,10 +974,10 @@ static void cmd_work_handler(struct work_struct *work) - cb_timeout = msecs_to_jiffies(mlx5_tout_ms(dev, CMD)); - - complete(&ent->handling); -- sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; -+ sem = ent->page_queue ? &cmd->vars.pages_sem : &cmd->vars.sem; - down(sem); - if (!ent->page_queue) { -- alloc_ret = cmd_alloc_index(cmd); -+ alloc_ret = cmd_alloc_index(cmd, ent); - if (alloc_ret < 0) { - mlx5_core_err_rl(dev, "failed to allocate command entry\n"); - if (ent->callback) { -@@ -973,20 +992,18 @@ static void cmd_work_handler(struct work_struct *work) - up(sem); - return; - } -- ent->idx = alloc_ret; - } else { -- ent->idx = cmd->max_reg_cmds; -+ ent->idx = cmd->vars.max_reg_cmds; - spin_lock_irqsave(&cmd->alloc_lock, flags); -- clear_bit(ent->idx, &cmd->bitmask); -+ clear_bit(ent->idx, &cmd->vars.bitmask); -+ cmd->ent_arr[ent->idx] = ent; - spin_unlock_irqrestore(&cmd->alloc_lock, flags); - } - -- cmd->ent_arr[ent->idx] = ent; - lay = get_inst(cmd, ent->idx); - ent->lay = lay; - memset(lay, 0, sizeof(*lay)); - memcpy(lay->in, ent->in->first.data, sizeof(lay->in)); -- ent->op = be32_to_cpu(lay->in[0]) >> 16; - if (ent->in->next) - lay->in_ptr = cpu_to_be64(ent->in->next->dma); - lay->inlen = cpu_to_be32(ent->in->len); -@@ -1099,12 +1116,12 @@ static void wait_func_handle_exec_timeout(struct mlx5_core_dev *dev, - */ - if (wait_for_completion_timeout(&ent->done, timeout)) { - mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) recovered after timeout\n", ent->idx, -- mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); -+ mlx5_command_str(ent->op), ent->op); - return; - } - - mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) No done completion\n", ent->idx, -- mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); -+ mlx5_command_str(ent->op), ent->op); - - ent->ret = -ETIMEDOUT; - mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true); -@@ -1131,12 +1148,10 @@ out_err: - - if (err == -ETIMEDOUT) { - mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n", -- mlx5_command_str(msg_to_opcode(ent->in)), -- msg_to_opcode(ent->in)); -+ mlx5_command_str(ent->op), ent->op); - } else if (err == -ECANCELED) { - mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n", -- mlx5_command_str(msg_to_opcode(ent->in)), -- msg_to_opcode(ent->in)); -+ mlx5_command_str(ent->op), ent->op); - } - mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n", - err, deliv_status_to_str(ent->status), ent->status); -@@ -1170,7 +1185,6 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, - u8 status = 0; - int err = 0; - s64 ds; -- u16 op; - - if (callback && page_queue) - return -EINVAL; -@@ -1210,9 +1224,8 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, - goto out_free; - - ds = ent->ts2 - ent->ts1; -- op = MLX5_GET(mbox_in, in->first.data, opcode); -- if (op < MLX5_CMD_OP_MAX) { -- stats = &cmd->stats[op]; -+ if (ent->op < MLX5_CMD_OP_MAX) { -+ stats = &cmd->stats[ent->op]; - spin_lock_irq(&stats->lock); - stats->sum += ds; - ++stats->n; -@@ -1220,7 +1233,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, - } - mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_TIME, - "fw exec time for %s is %lld nsec\n", -- mlx5_command_str(op), ds); -+ mlx5_command_str(ent->op), ds); - - out_free: - status = ent->status; -@@ -1558,15 +1571,15 @@ void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode) - struct mlx5_cmd *cmd = &dev->cmd; - int i; - -- for (i = 0; i < cmd->max_reg_cmds; i++) -- down(&cmd->sem); -- down(&cmd->pages_sem); -+ for (i = 0; i < cmd->vars.max_reg_cmds; i++) -+ down(&cmd->vars.sem); -+ down(&cmd->vars.pages_sem); - - cmd->allowed_opcode = opcode; - -- up(&cmd->pages_sem); -- for (i = 0; i < cmd->max_reg_cmds; i++) -- up(&cmd->sem); -+ up(&cmd->vars.pages_sem); -+ for (i = 0; i < cmd->vars.max_reg_cmds; i++) -+ up(&cmd->vars.sem); - } - - static void mlx5_cmd_change_mod(struct mlx5_core_dev *dev, int mode) -@@ -1574,15 +1587,15 @@ static void mlx5_cmd_change_mod(struct mlx5_core_dev *dev, int mode) - struct mlx5_cmd *cmd = &dev->cmd; - int i; - -- for (i = 0; i < cmd->max_reg_cmds; i++) -- down(&cmd->sem); -- down(&cmd->pages_sem); -+ for (i = 0; i < cmd->vars.max_reg_cmds; i++) -+ down(&cmd->vars.sem); -+ down(&cmd->vars.pages_sem); - - cmd->mode = mode; - -- up(&cmd->pages_sem); -- for (i = 0; i < cmd->max_reg_cmds; i++) -- up(&cmd->sem); -+ up(&cmd->vars.pages_sem); -+ for (i = 0; i < cmd->vars.max_reg_cmds; i++) -+ up(&cmd->vars.sem); - } - - static int cmd_comp_notifier(struct notifier_block *nb, -@@ -1641,7 +1654,7 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force - - /* there can be at most 32 command queues */ - vector = vec & 0xffffffff; -- for (i = 0; i < (1 << cmd->log_sz); i++) { -+ for (i = 0; i < (1 << cmd->vars.log_sz); i++) { - if (test_bit(i, &vector)) { - ent = cmd->ent_arr[i]; - -@@ -1730,7 +1743,7 @@ static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) - /* wait for pending handlers to complete */ - mlx5_eq_synchronize_cmd_irq(dev); - spin_lock_irqsave(&dev->cmd.alloc_lock, flags); -- vector = ~dev->cmd.bitmask & ((1ul << (1 << dev->cmd.log_sz)) - 1); -+ vector = ~dev->cmd.vars.bitmask & ((1ul << (1 << dev->cmd.vars.log_sz)) - 1); - if (!vector) - goto no_trig; - -@@ -1739,14 +1752,14 @@ static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) - * to guarantee pending commands will not get freed in the meanwhile. - * For that reason, it also has to be done inside the alloc_lock. - */ -- for_each_set_bit(i, &bitmask, (1 << cmd->log_sz)) -+ for_each_set_bit(i, &bitmask, (1 << cmd->vars.log_sz)) - cmd_ent_get(cmd->ent_arr[i]); - vector |= MLX5_TRIGGERED_CMD_COMP; - spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags); - - mlx5_core_dbg(dev, "vector 0x%llx\n", vector); - mlx5_cmd_comp_handler(dev, vector, true); -- for_each_set_bit(i, &bitmask, (1 << cmd->log_sz)) -+ for_each_set_bit(i, &bitmask, (1 << cmd->vars.log_sz)) - cmd_ent_put(cmd->ent_arr[i]); - return; - -@@ -1759,22 +1772,22 @@ void mlx5_cmd_flush(struct mlx5_core_dev *dev) - struct mlx5_cmd *cmd = &dev->cmd; - int i; - -- for (i = 0; i < cmd->max_reg_cmds; i++) { -- while (down_trylock(&cmd->sem)) { -+ for (i = 0; i < cmd->vars.max_reg_cmds; i++) { -+ while (down_trylock(&cmd->vars.sem)) { - mlx5_cmd_trigger_completions(dev); - cond_resched(); - } - } - -- while (down_trylock(&cmd->pages_sem)) { -+ while (down_trylock(&cmd->vars.pages_sem)) { - mlx5_cmd_trigger_completions(dev); - cond_resched(); - } - - /* Unlock cmdif */ -- up(&cmd->pages_sem); -- for (i = 0; i < cmd->max_reg_cmds; i++) -- up(&cmd->sem); -+ up(&cmd->vars.pages_sem); -+ for (i = 0; i < cmd->vars.max_reg_cmds; i++) -+ up(&cmd->vars.sem); - } - - static struct mlx5_cmd_msg *alloc_msg(struct mlx5_core_dev *dev, int in_size, -@@ -1817,7 +1830,7 @@ cache_miss: - - static int is_manage_pages(void *in) - { -- return MLX5_GET(mbox_in, in, opcode) == MLX5_CMD_OP_MANAGE_PAGES; -+ return in_to_opcode(in) == MLX5_CMD_OP_MANAGE_PAGES; - } - - /* Notes: -@@ -1828,8 +1841,9 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, - int out_size, mlx5_cmd_cbk_t callback, void *context, - bool force_polling) - { -- u16 opcode = MLX5_GET(mbox_in, in, opcode); - struct mlx5_cmd_msg *inb, *outb; -+ u16 opcode = in_to_opcode(in); -+ bool throttle_op; - int pages_queue; - gfp_t gfp; - u8 token; -@@ -1838,13 +1852,21 @@ static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, - if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, opcode)) - return -ENXIO; - -+ throttle_op = mlx5_cmd_is_throttle_opcode(opcode); -+ if (throttle_op) { -+ /* atomic context may not sleep */ -+ if (callback) -+ return -EINVAL; -+ down(&dev->cmd.vars.throttle_sem); -+ } -+ - pages_queue = is_manage_pages(in); - gfp = callback ? GFP_ATOMIC : GFP_KERNEL; - - inb = alloc_msg(dev, in_size, gfp); - if (IS_ERR(inb)) { - err = PTR_ERR(inb); -- return err; -+ goto out_up; - } - - token = alloc_token(&dev->cmd); -@@ -1878,6 +1900,9 @@ out_out: - mlx5_free_cmd_msg(dev, outb); - out_in: - free_msg(dev, inb); -+out_up: -+ if (throttle_op) -+ up(&dev->cmd.vars.throttle_sem); - return err; - } - -@@ -1952,8 +1977,8 @@ static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, u16 op - int mlx5_cmd_do(struct mlx5_core_dev *dev, void *in, int in_size, void *out, int out_size) - { - int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, false); -- u16 opcode = MLX5_GET(mbox_in, in, opcode); - u16 op_mod = MLX5_GET(mbox_in, in, op_mod); -+ u16 opcode = in_to_opcode(in); - - return cmd_status_err(dev, err, opcode, op_mod, out); - } -@@ -1998,8 +2023,8 @@ int mlx5_cmd_exec_polling(struct mlx5_core_dev *dev, void *in, int in_size, - void *out, int out_size) - { - int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, true); -- u16 opcode = MLX5_GET(mbox_in, in, opcode); - u16 op_mod = MLX5_GET(mbox_in, in, op_mod); -+ u16 opcode = in_to_opcode(in); - - err = cmd_status_err(dev, err, opcode, op_mod, out); - return mlx5_cmd_check(dev, err, in, out); -@@ -2051,7 +2076,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size, - - work->ctx = ctx; - work->user_callback = callback; -- work->opcode = MLX5_GET(mbox_in, in, opcode); -+ work->opcode = in_to_opcode(in); - work->op_mod = MLX5_GET(mbox_in, in, op_mod); - work->out = out; - if (WARN_ON(!atomic_inc_not_zero(&ctx->num_inflight))) -@@ -2187,16 +2212,16 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) - goto err_free_pool; - - cmd_l = ioread32be(&dev->iseg->cmdq_addr_l_sz) & 0xff; -- cmd->log_sz = cmd_l >> 4 & 0xf; -- cmd->log_stride = cmd_l & 0xf; -- if (1 << cmd->log_sz > MLX5_MAX_COMMANDS) { -+ cmd->vars.log_sz = cmd_l >> 4 & 0xf; -+ cmd->vars.log_stride = cmd_l & 0xf; -+ if (1 << cmd->vars.log_sz > MLX5_MAX_COMMANDS) { - mlx5_core_err(dev, "firmware reports too many outstanding commands %d\n", -- 1 << cmd->log_sz); -+ 1 << cmd->vars.log_sz); - err = -EINVAL; - goto err_free_page; - } - -- if (cmd->log_sz + cmd->log_stride > MLX5_ADAPTER_PAGE_SHIFT) { -+ if (cmd->vars.log_sz + cmd->vars.log_stride > MLX5_ADAPTER_PAGE_SHIFT) { - mlx5_core_err(dev, "command queue size overflow\n"); - err = -EINVAL; - goto err_free_page; -@@ -2204,13 +2229,13 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) - - cmd->state = MLX5_CMDIF_STATE_DOWN; - cmd->checksum_disabled = 1; -- cmd->max_reg_cmds = (1 << cmd->log_sz) - 1; -- cmd->bitmask = (1UL << cmd->max_reg_cmds) - 1; -+ cmd->vars.max_reg_cmds = (1 << cmd->vars.log_sz) - 1; -+ cmd->vars.bitmask = (1UL << cmd->vars.max_reg_cmds) - 1; - -- cmd->cmdif_rev = ioread32be(&dev->iseg->cmdif_rev_fw_sub) >> 16; -- if (cmd->cmdif_rev > CMD_IF_REV) { -+ cmd->vars.cmdif_rev = ioread32be(&dev->iseg->cmdif_rev_fw_sub) >> 16; -+ if (cmd->vars.cmdif_rev > CMD_IF_REV) { - mlx5_core_err(dev, "driver does not support command interface version. driver %d, firmware %d\n", -- CMD_IF_REV, cmd->cmdif_rev); -+ CMD_IF_REV, cmd->vars.cmdif_rev); - err = -EOPNOTSUPP; - goto err_free_page; - } -@@ -2220,8 +2245,9 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) - for (i = 0; i < MLX5_CMD_OP_MAX; i++) - spin_lock_init(&cmd->stats[i].lock); - -- sema_init(&cmd->sem, cmd->max_reg_cmds); -- sema_init(&cmd->pages_sem, 1); -+ sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds); -+ sema_init(&cmd->vars.pages_sem, 1); -+ sema_init(&cmd->vars.throttle_sem, DIV_ROUND_UP(cmd->vars.max_reg_cmds, 2)); - - cmd_h = (u32)((u64)(cmd->dma) >> 32); - cmd_l = (u32)(cmd->dma); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c -index bb95b40d25eb5..e0b0729e238c1 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c -@@ -176,8 +176,8 @@ static ssize_t slots_read(struct file *filp, char __user *buf, size_t count, - int ret; - - cmd = filp->private_data; -- weight = bitmap_weight(&cmd->bitmask, cmd->max_reg_cmds); -- field = cmd->max_reg_cmds - weight; -+ weight = bitmap_weight(&cmd->vars.bitmask, cmd->vars.max_reg_cmds); -+ field = cmd->vars.max_reg_cmds - weight; - ret = snprintf(tbuf, sizeof(tbuf), "%d\n", field); - return simple_read_from_buffer(buf, count, pos, tbuf, ret); - } -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c -index 374c0011a127b..3ba54ffa54bfe 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c -@@ -691,7 +691,7 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work) - - while (block_timestamp > tracer->last_timestamp) { - /* Check block override if it's not the first block */ -- if (!tracer->last_timestamp) { -+ if (tracer->last_timestamp) { - u64 *ts_event; - /* To avoid block override be the HW in case of buffer - * wraparound, the time stamp of the previous block -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c b/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c -index be83ad9db82a4..e1283531e0b81 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c -@@ -154,6 +154,7 @@ static int fs_udp_create_groups(struct mlx5e_flow_table *ft, enum fs_udp_type ty - in = kvzalloc(inlen, GFP_KERNEL); - if (!in || !ft->g) { - kfree(ft->g); -+ ft->g = NULL; - kvfree(in); - return -ENOMEM; - } -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c -index 4db0483c066a8..83bb0811e7741 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c -@@ -300,6 +300,9 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, - if (err) - goto destroy_neigh_entry; - -+ e->encap_size = ipv4_encap_size; -+ e->encap_header = encap_header; -+ - if (!(nud_state & NUD_VALID)) { - neigh_event_send(attr.n, NULL); - /* the encap entry will be made valid on neigh update event -@@ -319,8 +322,6 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, - goto destroy_neigh_entry; - } - -- e->encap_size = ipv4_encap_size; -- e->encap_header = encap_header; - e->flags |= MLX5_ENCAP_ENTRY_VALID; - mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); - mlx5e_route_lookup_ipv4_put(&attr); -@@ -403,12 +404,16 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, - if (err) - goto free_encap; - -+ e->encap_size = ipv4_encap_size; -+ kfree(e->encap_header); -+ e->encap_header = encap_header; -+ - if (!(nud_state & NUD_VALID)) { - neigh_event_send(attr.n, NULL); - /* the encap entry will be made valid on neigh update event - * and not used before that. - */ -- goto free_encap; -+ goto release_neigh; - } - - memset(&reformat_params, 0, sizeof(reformat_params)); -@@ -422,10 +427,6 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, - goto free_encap; - } - -- e->encap_size = ipv4_encap_size; -- kfree(e->encap_header); -- e->encap_header = encap_header; -- - e->flags |= MLX5_ENCAP_ENTRY_VALID; - mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); - mlx5e_route_lookup_ipv4_put(&attr); -@@ -567,6 +568,9 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, - if (err) - goto destroy_neigh_entry; - -+ e->encap_size = ipv6_encap_size; -+ e->encap_header = encap_header; -+ - if (!(nud_state & NUD_VALID)) { - neigh_event_send(attr.n, NULL); - /* the encap entry will be made valid on neigh update event -@@ -586,8 +590,6 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, - goto destroy_neigh_entry; - } - -- e->encap_size = ipv6_encap_size; -- e->encap_header = encap_header; - e->flags |= MLX5_ENCAP_ENTRY_VALID; - mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); - mlx5e_route_lookup_ipv6_put(&attr); -@@ -669,12 +671,16 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, - if (err) - goto free_encap; - -+ e->encap_size = ipv6_encap_size; -+ kfree(e->encap_header); -+ e->encap_header = encap_header; -+ - if (!(nud_state & NUD_VALID)) { - neigh_event_send(attr.n, NULL); - /* the encap entry will be made valid on neigh update event - * and not used before that. - */ -- goto free_encap; -+ goto release_neigh; - } - - memset(&reformat_params, 0, sizeof(reformat_params)); -@@ -688,10 +694,6 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, - goto free_encap; - } - -- e->encap_size = ipv6_encap_size; -- kfree(e->encap_header); -- e->encap_header = encap_header; -- - e->flags |= MLX5_ENCAP_ENTRY_VALID; - mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); - mlx5e_route_lookup_ipv6_put(&attr); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -index eeba91d9c5211..ceeb23f478e15 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -@@ -49,7 +49,7 @@ void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv, - count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), - fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); -- if (count == sizeof(drvinfo->fw_version)) -+ if (count >= sizeof(drvinfo->fw_version)) - snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "%d.%d.%04d", fw_rev_maj(mdev), - fw_rev_min(mdev), fw_rev_sub(mdev)); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -index 2653cb96c3105..5aeca9534f15a 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c -@@ -76,7 +76,7 @@ static void mlx5e_rep_get_drvinfo(struct net_device *dev, - count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), - fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); -- if (count == sizeof(drvinfo->fw_version)) -+ if (count >= sizeof(drvinfo->fw_version)) - snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "%d.%d.%04d", fw_rev_maj(mdev), - fw_rev_min(mdev), fw_rev_sub(mdev)); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c -index d5c3173250309..3f68e3198aa64 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c -@@ -277,7 +277,7 @@ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev, - req_list_size = max_list_size; - } - -- out_sz = MLX5_ST_SZ_BYTES(query_nic_vport_context_in) + -+ out_sz = MLX5_ST_SZ_BYTES(query_nic_vport_context_out) + - req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout); - - out = kvzalloc(out_sz, GFP_KERNEL); -diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h -index fecd43754cead..e5ec0a363aff8 100644 ---- a/drivers/net/ethernet/micrel/ks8851.h -+++ b/drivers/net/ethernet/micrel/ks8851.h -@@ -350,6 +350,8 @@ union ks8851_tx_hdr { - * @rxd: Space for receiving SPI data, in DMA-able space. - * @txd: Space for transmitting SPI data, in DMA-able space. - * @msg_enable: The message flags controlling driver output (see ethtool). -+ * @tx_space: Free space in the hardware TX buffer (cached copy of KS_TXMIR). -+ * @queued_len: Space required in hardware TX buffer for queued packets in txq. - * @fid: Incrementing frame id tag. - * @rc_ier: Cached copy of KS_IER. - * @rc_ccr: Cached copy of KS_CCR. -@@ -399,6 +401,7 @@ struct ks8851_net { - struct work_struct rxctrl_work; - - struct sk_buff_head txq; -+ unsigned int queued_len; - - struct eeprom_93cx6 eeprom; - struct regulator *vdd_reg; -diff --git a/drivers/net/ethernet/micrel/ks8851_common.c b/drivers/net/ethernet/micrel/ks8851_common.c -index cfbc900d4aeb9..0bf13b38b8f5b 100644 ---- a/drivers/net/ethernet/micrel/ks8851_common.c -+++ b/drivers/net/ethernet/micrel/ks8851_common.c -@@ -362,16 +362,18 @@ static irqreturn_t ks8851_irq(int irq, void *_ks) - handled |= IRQ_RXPSI; - - if (status & IRQ_TXI) { -- handled |= IRQ_TXI; -+ unsigned short tx_space = ks8851_rdreg16(ks, KS_TXMIR); - -- /* no lock here, tx queue should have been stopped */ -+ netif_dbg(ks, intr, ks->netdev, -+ "%s: txspace %d\n", __func__, tx_space); - -- /* update our idea of how much tx space is available to the -- * system */ -- ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR); -+ spin_lock(&ks->statelock); -+ ks->tx_space = tx_space; -+ if (netif_queue_stopped(ks->netdev)) -+ netif_wake_queue(ks->netdev); -+ spin_unlock(&ks->statelock); - -- netif_dbg(ks, intr, ks->netdev, -- "%s: txspace %d\n", __func__, ks->tx_space); -+ handled |= IRQ_TXI; - } - - if (status & IRQ_RXI) -@@ -414,9 +416,6 @@ static irqreturn_t ks8851_irq(int irq, void *_ks) - if (status & IRQ_LCI) - mii_check_link(&ks->mii); - -- if (status & IRQ_TXI) -- netif_wake_queue(ks->netdev); -- - return IRQ_HANDLED; - } - -@@ -500,6 +499,7 @@ static int ks8851_net_open(struct net_device *dev) - ks8851_wrreg16(ks, KS_ISR, ks->rc_ier); - ks8851_wrreg16(ks, KS_IER, ks->rc_ier); - -+ ks->queued_len = 0; - netif_start_queue(ks->netdev); - - netif_dbg(ks, ifup, ks->netdev, "network device up\n"); -diff --git a/drivers/net/ethernet/micrel/ks8851_spi.c b/drivers/net/ethernet/micrel/ks8851_spi.c -index 70bc7253454f6..88e26c120b483 100644 ---- a/drivers/net/ethernet/micrel/ks8851_spi.c -+++ b/drivers/net/ethernet/micrel/ks8851_spi.c -@@ -286,6 +286,18 @@ static void ks8851_wrfifo_spi(struct ks8851_net *ks, struct sk_buff *txp, - netdev_err(ks->netdev, "%s: spi_sync() failed\n", __func__); - } - -+/** -+ * calc_txlen - calculate size of message to send packet -+ * @len: Length of data -+ * -+ * Returns the size of the TXFIFO message needed to send -+ * this packet. -+ */ -+static unsigned int calc_txlen(unsigned int len) -+{ -+ return ALIGN(len + 4, 4); -+} -+ - /** - * ks8851_rx_skb_spi - receive skbuff - * @ks: The device state -@@ -305,7 +317,9 @@ static void ks8851_rx_skb_spi(struct ks8851_net *ks, struct sk_buff *skb) - */ - static void ks8851_tx_work(struct work_struct *work) - { -+ unsigned int dequeued_len = 0; - struct ks8851_net_spi *kss; -+ unsigned short tx_space; - struct ks8851_net *ks; - unsigned long flags; - struct sk_buff *txb; -@@ -322,6 +336,8 @@ static void ks8851_tx_work(struct work_struct *work) - last = skb_queue_empty(&ks->txq); - - if (txb) { -+ dequeued_len += calc_txlen(txb->len); -+ - ks8851_wrreg16_spi(ks, KS_RXQCR, - ks->rc_rxqcr | RXQCR_SDA); - ks8851_wrfifo_spi(ks, txb, last); -@@ -332,6 +348,13 @@ static void ks8851_tx_work(struct work_struct *work) - } - } - -+ tx_space = ks8851_rdreg16_spi(ks, KS_TXMIR); -+ -+ spin_lock(&ks->statelock); -+ ks->queued_len -= dequeued_len; -+ ks->tx_space = tx_space; -+ spin_unlock(&ks->statelock); -+ - ks8851_unlock_spi(ks, &flags); - } - -@@ -346,18 +369,6 @@ static void ks8851_flush_tx_work_spi(struct ks8851_net *ks) - flush_work(&kss->tx_work); - } - --/** -- * calc_txlen - calculate size of message to send packet -- * @len: Length of data -- * -- * Returns the size of the TXFIFO message needed to send -- * this packet. -- */ --static unsigned int calc_txlen(unsigned int len) --{ -- return ALIGN(len + 4, 4); --} -- - /** - * ks8851_start_xmit_spi - transmit packet using SPI - * @skb: The buffer to transmit -@@ -386,16 +397,17 @@ static netdev_tx_t ks8851_start_xmit_spi(struct sk_buff *skb, - - spin_lock(&ks->statelock); - -- if (needed > ks->tx_space) { -+ if (ks->queued_len + needed > ks->tx_space) { - netif_stop_queue(dev); - ret = NETDEV_TX_BUSY; - } else { -- ks->tx_space -= needed; -+ ks->queued_len += needed; - skb_queue_tail(&ks->txq, skb); - } - - spin_unlock(&ks->statelock); -- schedule_work(&kss->tx_work); -+ if (ret == NETDEV_TX_OK) -+ schedule_work(&kss->tx_work); - - return ret; - } -diff --git a/drivers/net/ethernet/microsoft/Kconfig b/drivers/net/ethernet/microsoft/Kconfig -index fe4e7a7d9c0b5..8b6c4cc37c53c 100644 ---- a/drivers/net/ethernet/microsoft/Kconfig -+++ b/drivers/net/ethernet/microsoft/Kconfig -@@ -19,6 +19,7 @@ config MICROSOFT_MANA - tristate "Microsoft Azure Network Adapter (MANA) support" - depends on PCI_MSI && X86_64 - depends on PCI_HYPERV -+ select PAGE_POOL - help - This driver supports Microsoft Azure Network Adapter (MANA). - So far, the driver is only supported on X86_64. -diff --git a/drivers/net/ethernet/mscc/ocelot_stats.c b/drivers/net/ethernet/mscc/ocelot_stats.c -index 0066219bb0e89..6b95262dad904 100644 ---- a/drivers/net/ethernet/mscc/ocelot_stats.c -+++ b/drivers/net/ethernet/mscc/ocelot_stats.c -@@ -216,10 +216,10 @@ static void ocelot_port_rmon_stats_cb(struct ocelot *ocelot, int port, void *pri - rmon_stats->hist_tx[0] = s[OCELOT_STAT_TX_64]; - rmon_stats->hist_tx[1] = s[OCELOT_STAT_TX_65_127]; - rmon_stats->hist_tx[2] = s[OCELOT_STAT_TX_128_255]; -- rmon_stats->hist_tx[3] = s[OCELOT_STAT_TX_128_255]; -- rmon_stats->hist_tx[4] = s[OCELOT_STAT_TX_256_511]; -- rmon_stats->hist_tx[5] = s[OCELOT_STAT_TX_512_1023]; -- rmon_stats->hist_tx[6] = s[OCELOT_STAT_TX_1024_1526]; -+ rmon_stats->hist_tx[3] = s[OCELOT_STAT_TX_256_511]; -+ rmon_stats->hist_tx[4] = s[OCELOT_STAT_TX_512_1023]; -+ rmon_stats->hist_tx[5] = s[OCELOT_STAT_TX_1024_1526]; -+ rmon_stats->hist_tx[6] = s[OCELOT_STAT_TX_1527_MAX]; - } - - void ocelot_port_get_rmon_stats(struct ocelot *ocelot, int port, -diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c -index 4ea0e155bb0d5..5a1bf42ce1566 100644 ---- a/drivers/net/usb/ax88179_178a.c -+++ b/drivers/net/usb/ax88179_178a.c -@@ -173,6 +173,7 @@ struct ax88179_data { - u8 in_pm; - u32 wol_supported; - u32 wolopts; -+ u8 disconnecting; - }; - - struct ax88179_int_data { -@@ -208,6 +209,7 @@ static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - { - int ret; - int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); -+ struct ax88179_data *ax179_data = dev->driver_priv; - - BUG_ON(!dev); - -@@ -219,7 +221,7 @@ static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, data, size); - -- if (unlikely(ret < 0)) -+ if (unlikely((ret < 0) && !(ret == -ENODEV && ax179_data->disconnecting))) - netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n", - index, ret); - -@@ -231,6 +233,7 @@ static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - { - int ret; - int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); -+ struct ax88179_data *ax179_data = dev->driver_priv; - - BUG_ON(!dev); - -@@ -242,7 +245,7 @@ static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, - ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, data, size); - -- if (unlikely(ret < 0)) -+ if (unlikely((ret < 0) && !(ret == -ENODEV && ax179_data->disconnecting))) - netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n", - index, ret); - -@@ -492,6 +495,20 @@ static int ax88179_resume(struct usb_interface *intf) - return usbnet_resume(intf); - } - -+static void ax88179_disconnect(struct usb_interface *intf) -+{ -+ struct usbnet *dev = usb_get_intfdata(intf); -+ struct ax88179_data *ax179_data; -+ -+ if (!dev) -+ return; -+ -+ ax179_data = dev->driver_priv; -+ ax179_data->disconnecting = 1; -+ -+ usbnet_disconnect(intf); -+} -+ - static void - ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) - { -@@ -1906,7 +1923,7 @@ static struct usb_driver ax88179_178a_driver = { - .suspend = ax88179_suspend, - .resume = ax88179_resume, - .reset_resume = ax88179_resume, -- .disconnect = usbnet_disconnect, -+ .disconnect = ax88179_disconnect, - .supports_autosuspend = 1, - .disable_hub_initiated_lpm = 1, - }; -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -index 39ab6526e6b85..796972f224326 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -@@ -3034,7 +3034,7 @@ static u32 iwl_trans_pcie_dump_rbs(struct iwl_trans *trans, - struct iwl_rxq *rxq = &trans_pcie->rxq[0]; - u32 i, r, j, rb_len = 0; - -- spin_lock(&rxq->lock); -+ spin_lock_bh(&rxq->lock); - - r = le16_to_cpu(iwl_get_closed_rb_stts(trans, rxq)) & 0x0FFF; - -@@ -3058,7 +3058,7 @@ static u32 iwl_trans_pcie_dump_rbs(struct iwl_trans *trans, - *data = iwl_fw_error_next_data(*data); - } - -- spin_unlock(&rxq->lock); -+ spin_unlock_bh(&rxq->lock); - - return rb_len; - } -diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c -index eb7c87b344b8f..5b906dbb1096c 100644 ---- a/drivers/nvme/host/core.c -+++ b/drivers/nvme/host/core.c -@@ -4835,6 +4835,8 @@ static void nvme_fw_act_work(struct work_struct *work) - struct nvme_ctrl, fw_act_work); - unsigned long fw_act_timeout; - -+ nvme_auth_stop(ctrl); -+ - if (ctrl->mtfa) - fw_act_timeout = jiffies + - msecs_to_jiffies(ctrl->mtfa * 100); -@@ -4890,7 +4892,6 @@ static bool nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) - * firmware activation. - */ - if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) { -- nvme_auth_stop(ctrl); - requeue = false; - queue_work(nvme_wq, &ctrl->fw_act_work); - } -diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c -index f71c6457e3509..2425d4813c3c5 100644 ---- a/drivers/pinctrl/pinctrl-at91-pio4.c -+++ b/drivers/pinctrl/pinctrl-at91-pio4.c -@@ -1033,6 +1033,13 @@ static const struct of_device_id atmel_pctrl_of_match[] = { - } - }; - -+/* -+ * This lock class allows to tell lockdep that parent IRQ and children IRQ do -+ * not share the same class so it does not raise false positive -+ */ -+static struct lock_class_key atmel_lock_key; -+static struct lock_class_key atmel_request_key; -+ - static int atmel_pinctrl_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -1185,6 +1192,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) - irq_set_chip_and_handler(irq, &atmel_gpio_irq_chip, - handle_simple_irq); - irq_set_chip_data(irq, atmel_pioctrl); -+ irq_set_lockdep_class(irq, &atmel_lock_key, &atmel_request_key); - dev_dbg(dev, - "atmel gpio irq domain: hwirq: %d, linux irq: %d\n", - i, irq); -diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c -index 5b544fb7f3d88..3b18a03075f46 100644 ---- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c -+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c -@@ -489,7 +489,7 @@ static int starfive_dt_node_to_map(struct pinctrl_dev *pctldev, - - nmaps = 0; - ngroups = 0; -- for_each_child_of_node(np, child) { -+ for_each_available_child_of_node(np, child) { - int npinmux = of_property_count_u32_elems(child, "pinmux"); - int npins = of_property_count_u32_elems(child, "pins"); - -@@ -524,7 +524,7 @@ static int starfive_dt_node_to_map(struct pinctrl_dev *pctldev, - nmaps = 0; - ngroups = 0; - mutex_lock(&sfp->mutex); -- for_each_child_of_node(np, child) { -+ for_each_available_child_of_node(np, child) { - int npins; - int i; - -diff --git a/drivers/reset/core.c b/drivers/reset/core.c -index f0a076e94118f..92cc13ef3e566 100644 ---- a/drivers/reset/core.c -+++ b/drivers/reset/core.c -@@ -807,6 +807,9 @@ static void __reset_control_put_internal(struct reset_control *rstc) - { - lockdep_assert_held(&reset_list_mutex); - -+ if (IS_ERR_OR_NULL(rstc)) -+ return; -+ - kref_put(&rstc->refcnt, __reset_control_release); - } - -@@ -1017,11 +1020,8 @@ EXPORT_SYMBOL_GPL(reset_control_put); - void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs) - { - mutex_lock(&reset_list_mutex); -- while (num_rstcs--) { -- if (IS_ERR_OR_NULL(rstcs[num_rstcs].rstc)) -- continue; -+ while (num_rstcs--) - __reset_control_put_internal(rstcs[num_rstcs].rstc); -- } - mutex_unlock(&reset_list_mutex); - } - EXPORT_SYMBOL_GPL(reset_control_bulk_put); -diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h -index 7c6efde75da66..5e115e8b2ba46 100644 ---- a/drivers/scsi/aacraid/aacraid.h -+++ b/drivers/scsi/aacraid/aacraid.h -@@ -1678,7 +1678,6 @@ struct aac_dev - u32 handle_pci_error; - bool init_reset; - u8 soft_reset_support; -- u8 use_map_queue; - }; - - #define aac_adapter_interrupt(dev) \ -diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c -index 013a9a334972e..25cee03d7f973 100644 ---- a/drivers/scsi/aacraid/commsup.c -+++ b/drivers/scsi/aacraid/commsup.c -@@ -223,12 +223,8 @@ int aac_fib_setup(struct aac_dev * dev) - struct fib *aac_fib_alloc_tag(struct aac_dev *dev, struct scsi_cmnd *scmd) - { - struct fib *fibptr; -- u32 blk_tag; -- int i; - -- blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); -- i = blk_mq_unique_tag_to_tag(blk_tag); -- fibptr = &dev->fibs[i]; -+ fibptr = &dev->fibs[scsi_cmd_to_rq(scmd)->tag]; - /* - * Null out fields that depend on being zero at the start of - * each I/O -diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c -index bff49b8ab057d..5ba5c18b77b46 100644 ---- a/drivers/scsi/aacraid/linit.c -+++ b/drivers/scsi/aacraid/linit.c -@@ -19,7 +19,6 @@ - - #include - #include --#include - #include - #include - #include -@@ -506,15 +505,6 @@ common_config: - return 0; - } - --static void aac_map_queues(struct Scsi_Host *shost) --{ -- struct aac_dev *aac = (struct aac_dev *)shost->hostdata; -- -- blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], -- aac->pdev, 0); -- aac->use_map_queue = true; --} -- - /** - * aac_change_queue_depth - alter queue depths - * @sdev: SCSI device we are considering -@@ -1499,7 +1489,6 @@ static struct scsi_host_template aac_driver_template = { - .bios_param = aac_biosparm, - .shost_groups = aac_host_groups, - .slave_configure = aac_slave_configure, -- .map_queues = aac_map_queues, - .change_queue_depth = aac_change_queue_depth, - .sdev_groups = aac_dev_groups, - .eh_abort_handler = aac_eh_abort, -@@ -1787,8 +1776,6 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) - shost->max_lun = AAC_MAX_LUN; - - pci_set_drvdata(pdev, shost); -- shost->nr_hw_queues = aac->max_msix; -- shost->host_tagset = 1; - - error = scsi_add_host(shost, &pdev->dev); - if (error) -@@ -1921,7 +1908,6 @@ static void aac_remove_one(struct pci_dev *pdev) - struct aac_dev *aac = (struct aac_dev *)shost->hostdata; - - aac_cancel_rescan_worker(aac); -- aac->use_map_queue = false; - scsi_remove_host(shost); - - __aac_shutdown(aac); -diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c -index 61949f3741886..11ef58204e96f 100644 ---- a/drivers/scsi/aacraid/src.c -+++ b/drivers/scsi/aacraid/src.c -@@ -493,10 +493,6 @@ static int aac_src_deliver_message(struct fib *fib) - #endif - - u16 vector_no; -- struct scsi_cmnd *scmd; -- u32 blk_tag; -- struct Scsi_Host *shost = dev->scsi_host_ptr; -- struct blk_mq_queue_map *qmap; - - atomic_inc(&q->numpending); - -@@ -509,25 +505,8 @@ static int aac_src_deliver_message(struct fib *fib) - if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) - && dev->sa_firmware) - vector_no = aac_get_vector(dev); -- else { -- if (!fib->vector_no || !fib->callback_data) { -- if (shost && dev->use_map_queue) { -- qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; -- vector_no = qmap->mq_map[raw_smp_processor_id()]; -- } -- /* -- * We hardcode the vector_no for -- * reserved commands as a valid shost is -- * absent during the init -- */ -- else -- vector_no = 0; -- } else { -- scmd = (struct scsi_cmnd *)fib->callback_data; -- blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); -- vector_no = blk_mq_unique_tag_to_hwq(blk_tag); -- } -- } -+ else -+ vector_no = fib->vector_no; - - if (native_hba) { - if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) { -diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c -index 05ddbb9bb7d8a..451a58e0fd969 100644 ---- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c -+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c -@@ -429,7 +429,6 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, - struct fcoe_ctlr *ctlr; - struct fcoe_rcv_info *fr; - struct fcoe_percpu_s *bg; -- struct sk_buff *tmp_skb; - - interface = container_of(ptype, struct bnx2fc_interface, - fcoe_packet_type); -@@ -441,11 +440,9 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, - goto err; - } - -- tmp_skb = skb_share_check(skb, GFP_ATOMIC); -- if (!tmp_skb) -- goto err; -- -- skb = tmp_skb; -+ skb = skb_share_check(skb, GFP_ATOMIC); -+ if (!skb) -+ return -1; - - if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { - printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n"); -diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c -index 02520f9123066..9a289d6f2e5ee 100644 ---- a/drivers/scsi/scsi_error.c -+++ b/drivers/scsi/scsi_error.c -@@ -1108,6 +1108,7 @@ retry: - - scsi_log_send(scmd); - scmd->submitter = SUBMITTED_BY_SCSI_ERROR_HANDLER; -+ scmd->flags |= SCMD_LAST; - - /* - * Lock sdev->state_mutex to avoid that scsi_device_quiesce() can -@@ -2402,6 +2403,7 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg) - scsi_init_command(dev, scmd); - - scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL; -+ scmd->flags |= SCMD_LAST; - memset(&scmd->sdb, 0, sizeof(scmd->sdb)); - - scmd->cmd_len = 0; -diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c -index d89f92032c1c2..f691bce5c1477 100644 ---- a/drivers/thunderbolt/debugfs.c -+++ b/drivers/thunderbolt/debugfs.c -@@ -943,7 +943,7 @@ static void margining_port_remove(struct tb_port *port) - snprintf(dir_name, sizeof(dir_name), "port%d", port->port); - parent = debugfs_lookup(dir_name, port->sw->debugfs_dir); - if (parent) -- debugfs_remove_recursive(debugfs_lookup("margining", parent)); -+ debugfs_lookup_and_remove("margining", parent); - - kfree(port->usb4->margining); - port->usb4->margining = NULL; -diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c -index 05e28a5ce42b1..fe2173e37b061 100644 ---- a/drivers/usb/serial/ftdi_sio.c -+++ b/drivers/usb/serial/ftdi_sio.c -@@ -1033,9 +1033,9 @@ static const struct usb_device_id id_table_combined[] = { - { USB_DEVICE(FTDI_VID, ACTISENSE_USG_PID) }, - { USB_DEVICE(FTDI_VID, ACTISENSE_NGT_PID) }, - { USB_DEVICE(FTDI_VID, ACTISENSE_NGW_PID) }, -- { USB_DEVICE(FTDI_VID, ACTISENSE_D9AC_PID) }, -- { USB_DEVICE(FTDI_VID, ACTISENSE_D9AD_PID) }, -- { USB_DEVICE(FTDI_VID, ACTISENSE_D9AE_PID) }, -+ { USB_DEVICE(FTDI_VID, ACTISENSE_UID_PID) }, -+ { USB_DEVICE(FTDI_VID, ACTISENSE_USA_PID) }, -+ { USB_DEVICE(FTDI_VID, ACTISENSE_NGX_PID) }, - { USB_DEVICE(FTDI_VID, ACTISENSE_D9AF_PID) }, - { USB_DEVICE(FTDI_VID, CHETCO_SEAGAUGE_PID) }, - { USB_DEVICE(FTDI_VID, CHETCO_SEASWITCH_PID) }, -diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h -index e2099445db708..21a2b5a25fc09 100644 ---- a/drivers/usb/serial/ftdi_sio_ids.h -+++ b/drivers/usb/serial/ftdi_sio_ids.h -@@ -1568,9 +1568,9 @@ - #define ACTISENSE_USG_PID 0xD9A9 /* USG USB Serial Adapter */ - #define ACTISENSE_NGT_PID 0xD9AA /* NGT NMEA2000 Interface */ - #define ACTISENSE_NGW_PID 0xD9AB /* NGW NMEA2000 Gateway */ --#define ACTISENSE_D9AC_PID 0xD9AC /* Actisense Reserved */ --#define ACTISENSE_D9AD_PID 0xD9AD /* Actisense Reserved */ --#define ACTISENSE_D9AE_PID 0xD9AE /* Actisense Reserved */ -+#define ACTISENSE_UID_PID 0xD9AC /* USB Isolating Device */ -+#define ACTISENSE_USA_PID 0xD9AD /* USB to Serial Adapter */ -+#define ACTISENSE_NGX_PID 0xD9AE /* NGX NMEA2000 Gateway */ - #define ACTISENSE_D9AF_PID 0xD9AF /* Actisense Reserved */ - #define CHETCO_SEAGAUGE_PID 0xA548 /* SeaGauge USB Adapter */ - #define CHETCO_SEASWITCH_PID 0xA549 /* SeaSwitch USB Adapter */ -diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c -index 7f2aa72d52e65..4adef92598709 100644 ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -272,6 +272,7 @@ static void option_instat_callback(struct urb *urb); - #define QUECTEL_PRODUCT_RM500Q 0x0800 - #define QUECTEL_PRODUCT_RM520N 0x0801 - #define QUECTEL_PRODUCT_EC200U 0x0901 -+#define QUECTEL_PRODUCT_EG912Y 0x6001 - #define QUECTEL_PRODUCT_EC200S_CN 0x6002 - #define QUECTEL_PRODUCT_EC200A 0x6005 - #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 -@@ -1232,6 +1233,7 @@ static const struct usb_device_id option_ids[] = { - { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0700, 0xff), /* BG95 */ - .driver_info = RSVD(3) | ZLP }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0x40) }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), - .driver_info = ZLP }, -@@ -1244,6 +1246,7 @@ static const struct usb_device_id option_ids[] = { - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG912Y, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, - - { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, -@@ -2242,6 +2245,8 @@ static const struct usb_device_id option_ids[] = { - .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, - { USB_DEVICE(0x0489, 0xe0b5), /* Foxconn T77W968 ESIM */ - .driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0da, 0xff), /* Foxconn T99W265 MBIM variant */ -+ .driver_info = RSVD(3) | RSVD(5) }, - { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0db, 0xff), /* Foxconn T99W265 MBIM */ - .driver_info = RSVD(3) }, - { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0ee, 0xff), /* Foxconn T99W368 MBIM */ -diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h -index 20dcbccb290b3..fd68204374f2c 100644 ---- a/drivers/usb/storage/unusual_devs.h -+++ b/drivers/usb/storage/unusual_devs.h -@@ -1305,6 +1305,17 @@ UNUSUAL_DEV( 0x090c, 0x6000, 0x0100, 0x0100, - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_INITIAL_READ10 ), - -+/* -+ * Patch by Tasos Sahanidis -+ * This flash drive always shows up with write protect enabled -+ * during the first mode sense. -+ */ -+UNUSUAL_DEV(0x0951, 0x1697, 0x0100, 0x0100, -+ "Kingston", -+ "DT Ultimate G3", -+ USB_SC_DEVICE, USB_PR_DEVICE, NULL, -+ US_FL_NO_WP_DETECT), -+ - /* - * This Pentax still camera is not conformant - * to the USB storage specification: - -diff --git a/fs/afs/cell.c b/fs/afs/cell.c -index 988c2ac7cecec..926cb1188eba6 100644 ---- a/fs/afs/cell.c -+++ b/fs/afs/cell.c -@@ -409,10 +409,12 @@ static int afs_update_cell(struct afs_cell *cell) - if (ret == -ENOMEM) - goto out_wake; - -- ret = -ENOMEM; - vllist = afs_alloc_vlserver_list(0); -- if (!vllist) -+ if (!vllist) { -+ if (ret >= 0) -+ ret = -ENOMEM; - goto out_wake; -+ } - - switch (ret) { - case -ENODATA: -diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c -index 91e804c70dd0a..9937993cf29dc 100644 ---- a/fs/afs/dynroot.c -+++ b/fs/afs/dynroot.c -@@ -114,6 +114,7 @@ static int afs_probe_cell_name(struct dentry *dentry) - struct afs_net *net = afs_d2net(dentry); - const char *name = dentry->d_name.name; - size_t len = dentry->d_name.len; -+ char *result = NULL; - int ret; - - /* Names prefixed with a dot are R/W mounts. */ -@@ -131,9 +132,22 @@ static int afs_probe_cell_name(struct dentry *dentry) - } - - ret = dns_query(net->net, "afsdb", name, len, "srv=1", -- NULL, NULL, false); -- if (ret == -ENODATA || ret == -ENOKEY) -+ &result, NULL, false); -+ if (ret == -ENODATA || ret == -ENOKEY || ret == 0) - ret = -ENOENT; -+ if (ret > 0 && ret >= sizeof(struct dns_server_list_v1_header)) { -+ struct dns_server_list_v1_header *v1 = (void *)result; -+ -+ if (v1->hdr.zero == 0 && -+ v1->hdr.content == DNS_PAYLOAD_IS_SERVER_LIST && -+ v1->hdr.version == 1 && -+ (v1->status != DNS_LOOKUP_GOOD && -+ v1->status != DNS_LOOKUP_GOOD_WITH_BAD)) -+ return -ENOENT; -+ -+ } -+ -+ kfree(result); - return ret; - } - -@@ -252,20 +266,9 @@ static int afs_dynroot_d_revalidate(struct dentry *dentry, unsigned int flags) - return 1; - } - --/* -- * Allow the VFS to enquire as to whether a dentry should be unhashed (mustn't -- * sleep) -- * - called from dput() when d_count is going to 0. -- * - return 1 to request dentry be unhashed, 0 otherwise -- */ --static int afs_dynroot_d_delete(const struct dentry *dentry) --{ -- return d_really_is_positive(dentry); --} -- - const struct dentry_operations afs_dynroot_dentry_operations = { - .d_revalidate = afs_dynroot_d_revalidate, -- .d_delete = afs_dynroot_d_delete, -+ .d_delete = always_delete_dentry, - .d_release = afs_d_release, - .d_automount = afs_d_automount, - }; -diff --git a/fs/afs/internal.h b/fs/afs/internal.h -index c2d70fc1698c0..fcbb598d8c85d 100644 ---- a/fs/afs/internal.h -+++ b/fs/afs/internal.h -@@ -585,6 +585,7 @@ struct afs_volume { - #define AFS_VOLUME_OFFLINE 4 /* - T if volume offline notice given */ - #define AFS_VOLUME_BUSY 5 /* - T if volume busy notice given */ - #define AFS_VOLUME_MAYBE_NO_IBULK 6 /* - T if some servers don't have InlineBulkStatus */ -+#define AFS_VOLUME_RM_TREE 7 /* - Set if volume removed from cell->volumes */ - #ifdef CONFIG_AFS_FSCACHE - struct fscache_volume *cache; /* Caching cookie */ - #endif -@@ -1517,6 +1518,7 @@ extern struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *, - extern struct afs_volume *afs_create_volume(struct afs_fs_context *); - extern int afs_activate_volume(struct afs_volume *); - extern void afs_deactivate_volume(struct afs_volume *); -+bool afs_try_get_volume(struct afs_volume *volume, enum afs_volume_trace reason); - extern struct afs_volume *afs_get_volume(struct afs_volume *, enum afs_volume_trace); - extern void afs_put_volume(struct afs_net *, struct afs_volume *, enum afs_volume_trace); - extern int afs_check_volume_status(struct afs_volume *, struct afs_operation *); -diff --git a/fs/afs/volume.c b/fs/afs/volume.c -index f4937029dcd72..1c9144e3e83ac 100644 ---- a/fs/afs/volume.c -+++ b/fs/afs/volume.c -@@ -32,8 +32,13 @@ static struct afs_volume *afs_insert_volume_into_cell(struct afs_cell *cell, - } else if (p->vid > volume->vid) { - pp = &(*pp)->rb_right; - } else { -- volume = afs_get_volume(p, afs_volume_trace_get_cell_insert); -- goto found; -+ if (afs_try_get_volume(p, afs_volume_trace_get_cell_insert)) { -+ volume = p; -+ goto found; -+ } -+ -+ set_bit(AFS_VOLUME_RM_TREE, &volume->flags); -+ rb_replace_node_rcu(&p->cell_node, &volume->cell_node, &cell->volumes); - } - } - -@@ -56,7 +61,8 @@ static void afs_remove_volume_from_cell(struct afs_volume *volume) - afs_volume_trace_remove); - write_seqlock(&cell->volume_lock); - hlist_del_rcu(&volume->proc_link); -- rb_erase(&volume->cell_node, &cell->volumes); -+ if (!test_and_set_bit(AFS_VOLUME_RM_TREE, &volume->flags)) -+ rb_erase(&volume->cell_node, &cell->volumes); - write_sequnlock(&cell->volume_lock); - } - } -@@ -235,6 +241,20 @@ static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume) - _leave(" [destroyed]"); - } - -+/* -+ * Try to get a reference on a volume record. -+ */ -+bool afs_try_get_volume(struct afs_volume *volume, enum afs_volume_trace reason) -+{ -+ int r; -+ -+ if (__refcount_inc_not_zero(&volume->ref, &r)) { -+ trace_afs_volume(volume->vid, r + 1, reason); -+ return true; -+ } -+ return false; -+} -+ - /* - * Get a reference on a volume record. - */ -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index 4cd8e44cba4c5..b27795e13ff31 100644 ---- a/fs/btrfs/free-space-cache.c -+++ b/fs/btrfs/free-space-cache.c -@@ -2685,13 +2685,8 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group, - bg_reclaim_threshold = READ_ONCE(sinfo->bg_reclaim_threshold); - - spin_lock(&ctl->tree_lock); -- /* Count initial region as zone_unusable until it gets activated. */ - if (!used) - to_free = size; -- else if (initial && -- test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &block_group->fs_info->flags) && -- (block_group->flags & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM))) -- to_free = 0; - else if (initial) - to_free = block_group->zone_capacity; - else if (offset >= block_group->alloc_offset) -@@ -2719,8 +2714,7 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group, - reclaimable_unusable = block_group->zone_unusable - - (block_group->length - block_group->zone_capacity); - /* All the region is now unusable. Mark it as unused and reclaim */ -- if (block_group->zone_unusable == block_group->length && -- block_group->alloc_offset) { -+ if (block_group->zone_unusable == block_group->length) { - btrfs_mark_bg_unused(block_group); - } else if (bg_reclaim_threshold && - reclaimable_unusable >= -diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c -index 675dbed075d8e..99cb690da9893 100644 ---- a/fs/btrfs/zoned.c -+++ b/fs/btrfs/zoned.c -@@ -1574,19 +1574,9 @@ void btrfs_calc_zone_unusable(struct btrfs_block_group *cache) - return; - - WARN_ON(cache->bytes_super != 0); -- -- /* Check for block groups never get activated */ -- if (test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &cache->fs_info->flags) && -- cache->flags & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM) && -- !test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &cache->runtime_flags) && -- cache->alloc_offset == 0) { -- unusable = cache->length; -- free = 0; -- } else { -- unusable = (cache->alloc_offset - cache->used) + -- (cache->length - cache->zone_capacity); -- free = cache->zone_capacity - cache->alloc_offset; -- } -+ unusable = (cache->alloc_offset - cache->used) + -+ (cache->length - cache->zone_capacity); -+ free = cache->zone_capacity - cache->alloc_offset; - - /* We only need ->free_space in ALLOC_SEQ block groups */ - cache->cached = BTRFS_CACHE_FINISHED; -@@ -1882,7 +1872,6 @@ struct btrfs_device *btrfs_zoned_get_device(struct btrfs_fs_info *fs_info, - bool btrfs_zone_activate(struct btrfs_block_group *block_group) - { - struct btrfs_fs_info *fs_info = block_group->fs_info; -- struct btrfs_space_info *space_info = block_group->space_info; - struct map_lookup *map; - struct btrfs_device *device; - u64 physical; -@@ -1894,7 +1883,6 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group) - - map = block_group->physical_map; - -- spin_lock(&space_info->lock); - spin_lock(&block_group->lock); - if (test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags)) { - ret = true; -@@ -1923,14 +1911,7 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group) - - /* Successfully activated all the zones */ - set_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags); -- WARN_ON(block_group->alloc_offset != 0); -- if (block_group->zone_unusable == block_group->length) { -- block_group->zone_unusable = block_group->length - block_group->zone_capacity; -- space_info->bytes_zone_unusable -= block_group->zone_capacity; -- } - spin_unlock(&block_group->lock); -- btrfs_try_granting_tickets(fs_info, space_info); -- spin_unlock(&space_info->lock); - - /* For the active block group list */ - btrfs_get_block_group(block_group); -@@ -1943,7 +1924,6 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group) - - out_unlock: - spin_unlock(&block_group->lock); -- spin_unlock(&space_info->lock); - return ret; - } - -diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h -index 98a9cf5318731..a9681fecbd91f 100644 ---- a/fs/fuse/fuse_i.h -+++ b/fs/fuse/fuse_i.h -@@ -63,6 +63,19 @@ struct fuse_forget_link { - struct fuse_forget_link *next; - }; - -+/* Submount lookup tracking */ -+struct fuse_submount_lookup { -+ /** Refcount */ -+ refcount_t count; -+ -+ /** Unique ID, which identifies the inode between userspace -+ * and kernel */ -+ u64 nodeid; -+ -+ /** The request used for sending the FORGET message */ -+ struct fuse_forget_link *forget; -+}; -+ - /** FUSE inode */ - struct fuse_inode { - /** Inode data */ -@@ -155,6 +168,8 @@ struct fuse_inode { - */ - struct fuse_inode_dax *dax; - #endif -+ /** Submount specific lookup tracking */ -+ struct fuse_submount_lookup *submount_lookup; - }; - - /** FUSE inode state bits */ -diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c -index bc3c3e76c646d..f81000d968875 100644 ---- a/fs/fuse/inode.c -+++ b/fs/fuse/inode.c -@@ -68,6 +68,24 @@ struct fuse_forget_link *fuse_alloc_forget(void) - return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL_ACCOUNT); - } - -+static struct fuse_submount_lookup *fuse_alloc_submount_lookup(void) -+{ -+ struct fuse_submount_lookup *sl; -+ -+ sl = kzalloc(sizeof(struct fuse_submount_lookup), GFP_KERNEL_ACCOUNT); -+ if (!sl) -+ return NULL; -+ sl->forget = fuse_alloc_forget(); -+ if (!sl->forget) -+ goto out_free; -+ -+ return sl; -+ -+out_free: -+ kfree(sl); -+ return NULL; -+} -+ - static struct inode *fuse_alloc_inode(struct super_block *sb) - { - struct fuse_inode *fi; -@@ -83,6 +101,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) - fi->attr_version = 0; - fi->orig_ino = 0; - fi->state = 0; -+ fi->submount_lookup = NULL; - mutex_init(&fi->mutex); - spin_lock_init(&fi->lock); - fi->forget = fuse_alloc_forget(); -@@ -113,6 +132,17 @@ static void fuse_free_inode(struct inode *inode) - kmem_cache_free(fuse_inode_cachep, fi); - } - -+static void fuse_cleanup_submount_lookup(struct fuse_conn *fc, -+ struct fuse_submount_lookup *sl) -+{ -+ if (!refcount_dec_and_test(&sl->count)) -+ return; -+ -+ fuse_queue_forget(fc, sl->forget, sl->nodeid, 1); -+ sl->forget = NULL; -+ kfree(sl); -+} -+ - static void fuse_evict_inode(struct inode *inode) - { - struct fuse_inode *fi = get_fuse_inode(inode); -@@ -132,6 +162,11 @@ static void fuse_evict_inode(struct inode *inode) - fi->nlookup); - fi->forget = NULL; - } -+ -+ if (fi->submount_lookup) { -+ fuse_cleanup_submount_lookup(fc, fi->submount_lookup); -+ fi->submount_lookup = NULL; -+ } - } - if (S_ISREG(inode->i_mode) && !fuse_is_bad(inode)) { - WARN_ON(!list_empty(&fi->write_files)); -@@ -311,6 +346,13 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, - fuse_dax_dontcache(inode, attr->flags); - } - -+static void fuse_init_submount_lookup(struct fuse_submount_lookup *sl, -+ u64 nodeid) -+{ -+ sl->nodeid = nodeid; -+ refcount_set(&sl->count, 1); -+} -+ - static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr) - { - inode->i_mode = attr->mode & S_IFMT; -@@ -368,12 +410,22 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, - */ - if (fc->auto_submounts && (attr->flags & FUSE_ATTR_SUBMOUNT) && - S_ISDIR(attr->mode)) { -+ struct fuse_inode *fi; -+ - inode = new_inode(sb); - if (!inode) - return NULL; - - fuse_init_inode(inode, attr); -- get_fuse_inode(inode)->nodeid = nodeid; -+ fi = get_fuse_inode(inode); -+ fi->nodeid = nodeid; -+ fi->submount_lookup = fuse_alloc_submount_lookup(); -+ if (!fi->submount_lookup) { -+ iput(inode); -+ return NULL; -+ } -+ /* Sets nlookup = 1 on fi->submount_lookup->nlookup */ -+ fuse_init_submount_lookup(fi->submount_lookup, nodeid); - inode->i_flags |= S_AUTOMOUNT; - goto done; - } -@@ -396,11 +448,11 @@ retry: - iput(inode); - goto retry; - } --done: - fi = get_fuse_inode(inode); - spin_lock(&fi->lock); - fi->nlookup++; - spin_unlock(&fi->lock); -+done: - fuse_change_attributes(inode, attr, attr_valid, attr_version); - - return inode; -@@ -1439,6 +1491,8 @@ static int fuse_fill_super_submount(struct super_block *sb, - struct super_block *parent_sb = parent_fi->inode.i_sb; - struct fuse_attr root_attr; - struct inode *root; -+ struct fuse_submount_lookup *sl; -+ struct fuse_inode *fi; - - fuse_sb_defaults(sb); - fm->sb = sb; -@@ -1461,12 +1515,27 @@ static int fuse_fill_super_submount(struct super_block *sb, - * its nlookup should not be incremented. fuse_iget() does - * that, though, so undo it here. - */ -- get_fuse_inode(root)->nlookup--; -+ fi = get_fuse_inode(root); -+ fi->nlookup--; -+ - sb->s_d_op = &fuse_dentry_operations; - sb->s_root = d_make_root(root); - if (!sb->s_root) - return -ENOMEM; - -+ /* -+ * Grab the parent's submount_lookup pointer and take a -+ * reference on the shared nlookup from the parent. This is to -+ * prevent the last forget for this nodeid from getting -+ * triggered until all users have finished with it. -+ */ -+ sl = parent_fi->submount_lookup; -+ WARN_ON(!sl); -+ if (sl) { -+ refcount_inc(&sl->count); -+ fi->submount_lookup = sl; -+ } -+ - return 0; - } - -diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c -index 0acb455368f23..5df8d93233376 100644 ---- a/fs/smb/client/cifs_debug.c -+++ b/fs/smb/client/cifs_debug.c -@@ -38,11 +38,13 @@ void cifs_dump_detail(void *buf, struct TCP_Server_Info *server) - #ifdef CONFIG_CIFS_DEBUG2 - struct smb_hdr *smb = buf; - -- cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n", -- smb->Command, smb->Status.CifsError, -- smb->Flags, smb->Flags2, smb->Mid, smb->Pid); -- cifs_dbg(VFS, "smb buf %p len %u\n", smb, -- server->ops->calc_smb_size(smb)); -+ cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d Wct: %d\n", -+ smb->Command, smb->Status.CifsError, smb->Flags, -+ smb->Flags2, smb->Mid, smb->Pid, smb->WordCount); -+ if (!server->ops->check_message(buf, server->total_read, server)) { -+ cifs_dbg(VFS, "smb buf %p len %u\n", smb, -+ server->ops->calc_smb_size(smb)); -+ } - #endif /* CONFIG_CIFS_DEBUG2 */ - } - -diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h -index 2e814eadd6aef..512ac9dea9787 100644 ---- a/fs/smb/client/cifsglob.h -+++ b/fs/smb/client/cifsglob.h -@@ -513,7 +513,8 @@ struct smb_version_operations { - struct mid_q_entry **, char **, int *); - enum securityEnum (*select_sectype)(struct TCP_Server_Info *, - enum securityEnum); -- int (*next_header)(char *); -+ int (*next_header)(struct TCP_Server_Info *server, char *buf, -+ unsigned int *noff); - /* ioctl passthrough for query_info */ - int (*ioctl_query_info)(const unsigned int xid, - struct cifs_tcon *tcon, -diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c -index 5b19918938346..f725a119ce312 100644 ---- a/fs/smb/client/connect.c -+++ b/fs/smb/client/connect.c -@@ -1225,7 +1225,12 @@ next_pdu: - server->total_read += length; - - if (server->ops->next_header) { -- next_offset = server->ops->next_header(buf); -+ if (server->ops->next_header(server, buf, &next_offset)) { -+ cifs_dbg(VFS, "%s: malformed response (next_offset=%u)\n", -+ __func__, next_offset); -+ cifs_reconnect(server, true); -+ continue; -+ } - if (next_offset) - server->pdu_size = next_offset; - } -diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c -index 31e06133acc3d..41290c12d0bcc 100644 ---- a/fs/smb/client/misc.c -+++ b/fs/smb/client/misc.c -@@ -350,6 +350,10 @@ checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server) - cifs_dbg(VFS, "Length less than smb header size\n"); - } - return -EIO; -+ } else if (total_read < sizeof(*smb) + 2 * smb->WordCount) { -+ cifs_dbg(VFS, "%s: can't read BCC due to invalid WordCount(%u)\n", -+ __func__, smb->WordCount); -+ return -EIO; - } - - /* otherwise, there is enough to get to the BCC */ -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index 1b3489a2f0db7..df03d80ab6d5f 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -5196,17 +5196,22 @@ smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid) - NULL, 0, 0, false); - } - --static int --smb2_next_header(char *buf) -+static int smb2_next_header(struct TCP_Server_Info *server, char *buf, -+ unsigned int *noff) - { - struct smb2_hdr *hdr = (struct smb2_hdr *)buf; - struct smb2_transform_hdr *t_hdr = (struct smb2_transform_hdr *)buf; - -- if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) -- return sizeof(struct smb2_transform_hdr) + -- le32_to_cpu(t_hdr->OriginalMessageSize); -- -- return le32_to_cpu(hdr->NextCommand); -+ if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) { -+ *noff = le32_to_cpu(t_hdr->OriginalMessageSize); -+ if (unlikely(check_add_overflow(*noff, sizeof(*t_hdr), noff))) -+ return -EINVAL; -+ } else { -+ *noff = le32_to_cpu(hdr->NextCommand); -+ } -+ if (unlikely(*noff && *noff < MID_HEADER_SIZE(server))) -+ return -EINVAL; -+ return 0; - } - - static int -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index 847d69d327c2a..05ff8a457a3d7 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -372,10 +372,15 @@ static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon, - void **request_buf, unsigned int *total_len) - { - /* BB eventually switch this to SMB2 specific small buf size */ -- if (smb2_command == SMB2_SET_INFO) -+ switch (smb2_command) { -+ case SMB2_SET_INFO: -+ case SMB2_QUERY_INFO: - *request_buf = cifs_buf_get(); -- else -+ break; -+ default: - *request_buf = cifs_small_buf_get(); -+ break; -+ } - if (*request_buf == NULL) { - /* BB should we add a retry in here if not a writepage? */ - return -ENOMEM; -@@ -3523,8 +3528,13 @@ SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, - struct smb2_query_info_req *req; - struct kvec *iov = rqst->rq_iov; - unsigned int total_len; -+ size_t len; - int rc; - -+ if (unlikely(check_add_overflow(input_len, sizeof(*req), &len) || -+ len > CIFSMaxBufSize)) -+ return -EINVAL; -+ - rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server, - (void **) &req, &total_len); - if (rc) -@@ -3546,7 +3556,7 @@ SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, - - iov[0].iov_base = (char *)req; - /* 1 for Buffer */ -- iov[0].iov_len = total_len - 1 + input_len; -+ iov[0].iov_len = len; - return 0; - } - -@@ -3554,7 +3564,7 @@ void - SMB2_query_info_free(struct smb_rqst *rqst) - { - if (rqst && rqst->rq_iov) -- cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ -+ cifs_buf_release(rqst->rq_iov[0].iov_base); /* request */ - } - - static int -@@ -5439,6 +5449,11 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, - return 0; - } - -+static inline void free_qfs_info_req(struct kvec *iov) -+{ -+ cifs_buf_release(iov->iov_base); -+} -+ - int - SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, - u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata) -@@ -5470,7 +5485,7 @@ SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, - - rc = cifs_send_recv(xid, ses, server, - &rqst, &resp_buftype, flags, &rsp_iov); -- cifs_small_buf_release(iov.iov_base); -+ free_qfs_info_req(&iov); - if (rc) { - cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); - goto posix_qfsinf_exit; -@@ -5521,7 +5536,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, - - rc = cifs_send_recv(xid, ses, server, - &rqst, &resp_buftype, flags, &rsp_iov); -- cifs_small_buf_release(iov.iov_base); -+ free_qfs_info_req(&iov); - if (rc) { - cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); - goto qfsinf_exit; -@@ -5588,7 +5603,7 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, - - rc = cifs_send_recv(xid, ses, server, - &rqst, &resp_buftype, flags, &rsp_iov); -- cifs_small_buf_release(iov.iov_base); -+ free_qfs_info_req(&iov); - if (rc) { - cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); - goto qfsattr_exit; -diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c -index 6b7d95b65f4b6..f4728e65d1bda 100644 ---- a/fs/ubifs/tnc.c -+++ b/fs/ubifs/tnc.c -@@ -65,6 +65,7 @@ static void do_insert_old_idx(struct ubifs_info *c, - else { - ubifs_err(c, "old idx added twice!"); - kfree(old_idx); -+ return; - } - } - rb_link_node(&old_idx->rb, parent, p); -diff --git a/include/linux/bpf.h b/include/linux/bpf.h -index 1fba826f0acef..3ce9e39ecdb85 100644 ---- a/include/linux/bpf.h -+++ b/include/linux/bpf.h -@@ -2681,6 +2681,9 @@ enum bpf_text_poke_type { - int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, - void *addr1, void *addr2); - -+void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke, -+ struct bpf_prog *new, struct bpf_prog *old); -+ - void *bpf_arch_text_copy(void *dst, void *src, size_t len); - int bpf_arch_text_invalidate(void *dst, size_t len); - -diff --git a/include/linux/damon.h b/include/linux/damon.h -index b13be7ae2275e..e6941b239f449 100644 ---- a/include/linux/damon.h -+++ b/include/linux/damon.h -@@ -8,6 +8,7 @@ - #ifndef _DAMON_H_ - #define _DAMON_H_ - -+#include - #include - #include - #include -@@ -452,6 +453,8 @@ struct damon_ctx { - /* private: internal use only */ - struct timespec64 last_aggregation; - struct timespec64 last_ops_update; -+ /* for waiting until the execution of the kdamond_fn is started */ -+ struct completion kdamond_started; - - /* public: */ - struct task_struct *kdamond; -diff --git a/include/linux/dm-bufio.h b/include/linux/dm-bufio.h -index 1262d92ab88fc..2e71ca35942e9 100644 ---- a/include/linux/dm-bufio.h -+++ b/include/linux/dm-bufio.h -@@ -37,6 +37,8 @@ dm_bufio_client_create(struct block_device *bdev, unsigned int block_size, - */ - void dm_bufio_client_destroy(struct dm_bufio_client *c); - -+void dm_bufio_client_reset(struct dm_bufio_client *c); -+ - /* - * Set the sector range. - * When this function is called, there must be no I/O in progress on the bufio -diff --git a/include/linux/kasan.h b/include/linux/kasan.h -index 6e6f0238d63cc..4603e6e30c0ea 100644 ---- a/include/linux/kasan.h -+++ b/include/linux/kasan.h -@@ -471,10 +471,10 @@ static inline void kasan_free_module_shadow(const struct vm_struct *vm) {} - - #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */ - --#ifdef CONFIG_KASAN -+#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) - void kasan_non_canonical_hook(unsigned long addr); --#else /* CONFIG_KASAN */ -+#else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ - static inline void kasan_non_canonical_hook(unsigned long addr) { } --#endif /* CONFIG_KASAN */ -+#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ - - #endif /* LINUX_KASAN_H */ -diff --git a/include/linux/key-type.h b/include/linux/key-type.h -index 7d985a1dfe4af..5caf3ce823733 100644 ---- a/include/linux/key-type.h -+++ b/include/linux/key-type.h -@@ -73,6 +73,7 @@ struct key_type { - - unsigned int flags; - #define KEY_TYPE_NET_DOMAIN 0x00000001 /* Keys of this type have a net namespace domain */ -+#define KEY_TYPE_INSTANT_REAP 0x00000002 /* Keys of this type don't have a delay after expiring */ - - /* vet a description */ - int (*vet_description)(const char *description); -diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h -index 3660ce6a93496..93ec34a94b724 100644 ---- a/include/linux/mlx5/driver.h -+++ b/include/linux/mlx5/driver.h -@@ -282,18 +282,23 @@ struct mlx5_cmd_stats { - struct mlx5_cmd { - struct mlx5_nb nb; - -+ /* members which needs to be queried or reinitialized each reload */ -+ struct { -+ u16 cmdif_rev; -+ u8 log_sz; -+ u8 log_stride; -+ int max_reg_cmds; -+ unsigned long bitmask; -+ struct semaphore sem; -+ struct semaphore pages_sem; -+ struct semaphore throttle_sem; -+ } vars; - enum mlx5_cmdif_state state; - void *cmd_alloc_buf; - dma_addr_t alloc_dma; - int alloc_size; - void *cmd_buf; - dma_addr_t dma; -- u16 cmdif_rev; -- u8 log_sz; -- u8 log_stride; -- int max_reg_cmds; -- int events; -- u32 __iomem *vector; - - /* protect command queue allocations - */ -@@ -303,11 +308,8 @@ struct mlx5_cmd { - */ - spinlock_t token_lock; - u8 token; -- unsigned long bitmask; - char wq_name[MLX5_CMD_WQ_MAX_NAME]; - struct workqueue_struct *wq; -- struct semaphore sem; -- struct semaphore pages_sem; - int mode; - u16 allowed_opcode; - struct mlx5_cmd_work_ent *ent_arr[MLX5_MAX_COMMANDS]; -diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h -index 583aebd8c1e01..5f8a534b65746 100644 ---- a/include/net/bluetooth/hci_core.h -+++ b/include/net/bluetooth/hci_core.h -@@ -187,6 +187,7 @@ struct blocked_key { - struct smp_csrk { - bdaddr_t bdaddr; - u8 bdaddr_type; -+ u8 link_type; - u8 type; - u8 val[16]; - }; -@@ -196,6 +197,7 @@ struct smp_ltk { - struct rcu_head rcu; - bdaddr_t bdaddr; - u8 bdaddr_type; -+ u8 link_type; - u8 authenticated; - u8 type; - u8 enc_size; -@@ -210,6 +212,7 @@ struct smp_irk { - bdaddr_t rpa; - bdaddr_t bdaddr; - u8 addr_type; -+ u8 link_type; - u8 val[16]; - }; - -@@ -217,6 +220,8 @@ struct link_key { - struct list_head list; - struct rcu_head rcu; - bdaddr_t bdaddr; -+ u8 bdaddr_type; -+ u8 link_type; - u8 type; - u8 val[HCI_LINK_KEY_SIZE]; - u8 pin_len; -diff --git a/include/trace/events/9p.h b/include/trace/events/9p.h -index 4dfa6d7f83baa..cd104a1343e2d 100644 ---- a/include/trace/events/9p.h -+++ b/include/trace/events/9p.h -@@ -178,18 +178,21 @@ TRACE_EVENT(9p_protocol_dump, - __field( void *, clnt ) - __field( __u8, type ) - __field( __u16, tag ) -- __array( unsigned char, line, P9_PROTO_DUMP_SZ ) -+ __dynamic_array(unsigned char, line, -+ min_t(size_t, pdu->capacity, P9_PROTO_DUMP_SZ)) - ), - - TP_fast_assign( - __entry->clnt = clnt; - __entry->type = pdu->id; - __entry->tag = pdu->tag; -- memcpy(__entry->line, pdu->sdata, P9_PROTO_DUMP_SZ); -+ memcpy(__get_dynamic_array(line), pdu->sdata, -+ __get_dynamic_array_len(line)); - ), -- TP_printk("clnt %lu %s(tag = %d)\n%.3x: %16ph\n%.3x: %16ph\n", -+ TP_printk("clnt %lu %s(tag = %d)\n%*ph\n", - (unsigned long)__entry->clnt, show_9p_op(__entry->type), -- __entry->tag, 0, __entry->line, 16, __entry->line + 16) -+ __entry->tag, __get_dynamic_array_len(line), -+ __get_dynamic_array(line)) - ); - - -diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c -index 832b2659e96e2..00f23febb9a7d 100644 ---- a/kernel/bpf/arraymap.c -+++ b/kernel/bpf/arraymap.c -@@ -997,11 +997,16 @@ static void prog_array_map_poke_untrack(struct bpf_map *map, - mutex_unlock(&aux->poke_mutex); - } - -+void __weak bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke, -+ struct bpf_prog *new, struct bpf_prog *old) -+{ -+ WARN_ON_ONCE(1); -+} -+ - static void prog_array_map_poke_run(struct bpf_map *map, u32 key, - struct bpf_prog *old, - struct bpf_prog *new) - { -- u8 *old_addr, *new_addr, *old_bypass_addr; - struct prog_poke_elem *elem; - struct bpf_array_aux *aux; - -@@ -1010,7 +1015,7 @@ static void prog_array_map_poke_run(struct bpf_map *map, u32 key, - - list_for_each_entry(elem, &aux->poke_progs, list) { - struct bpf_jit_poke_descriptor *poke; -- int i, ret; -+ int i; - - for (i = 0; i < elem->aux->size_poke_tab; i++) { - poke = &elem->aux->poke_tab[i]; -@@ -1029,21 +1034,10 @@ static void prog_array_map_poke_run(struct bpf_map *map, u32 key, - * activated, so tail call updates can arrive from here - * while JIT is still finishing its final fixup for - * non-activated poke entries. -- * 3) On program teardown, the program's kallsym entry gets -- * removed out of RCU callback, but we can only untrack -- * from sleepable context, therefore bpf_arch_text_poke() -- * might not see that this is in BPF text section and -- * bails out with -EINVAL. As these are unreachable since -- * RCU grace period already passed, we simply skip them. -- * 4) Also programs reaching refcount of zero while patching -+ * 3) Also programs reaching refcount of zero while patching - * is in progress is okay since we're protected under - * poke_mutex and untrack the programs before the JIT -- * buffer is freed. When we're still in the middle of -- * patching and suddenly kallsyms entry of the program -- * gets evicted, we just skip the rest which is fine due -- * to point 3). -- * 5) Any other error happening below from bpf_arch_text_poke() -- * is a unexpected bug. -+ * buffer is freed. - */ - if (!READ_ONCE(poke->tailcall_target_stable)) - continue; -@@ -1053,39 +1047,7 @@ static void prog_array_map_poke_run(struct bpf_map *map, u32 key, - poke->tail_call.key != key) - continue; - -- old_bypass_addr = old ? NULL : poke->bypass_addr; -- old_addr = old ? (u8 *)old->bpf_func + poke->adj_off : NULL; -- new_addr = new ? (u8 *)new->bpf_func + poke->adj_off : NULL; -- -- if (new) { -- ret = bpf_arch_text_poke(poke->tailcall_target, -- BPF_MOD_JUMP, -- old_addr, new_addr); -- BUG_ON(ret < 0 && ret != -EINVAL); -- if (!old) { -- ret = bpf_arch_text_poke(poke->tailcall_bypass, -- BPF_MOD_JUMP, -- poke->bypass_addr, -- NULL); -- BUG_ON(ret < 0 && ret != -EINVAL); -- } -- } else { -- ret = bpf_arch_text_poke(poke->tailcall_bypass, -- BPF_MOD_JUMP, -- old_bypass_addr, -- poke->bypass_addr); -- BUG_ON(ret < 0 && ret != -EINVAL); -- /* let other CPUs finish the execution of program -- * so that it will not possible to expose them -- * to invalid nop, stack unwind, nop state -- */ -- if (!ret) -- synchronize_rcu(); -- ret = bpf_arch_text_poke(poke->tailcall_target, -- BPF_MOD_JUMP, -- old_addr, NULL); -- BUG_ON(ret < 0 && ret != -EINVAL); -- } -+ bpf_arch_poke_desc_update(poke, new, old); - } - } - } -diff --git a/kernel/trace/synth_event_gen_test.c b/kernel/trace/synth_event_gen_test.c -index 8d77526892f45..d944924cd1e1c 100644 ---- a/kernel/trace/synth_event_gen_test.c -+++ b/kernel/trace/synth_event_gen_test.c -@@ -477,6 +477,17 @@ static int __init synth_event_gen_test_init(void) - - ret = test_trace_synth_event(); - WARN_ON(ret); -+ -+ /* Disable when done */ -+ trace_array_set_clr_event(gen_synth_test->tr, -+ "synthetic", -+ "gen_synth_test", false); -+ trace_array_set_clr_event(empty_synth_test->tr, -+ "synthetic", -+ "empty_synth_test", false); -+ trace_array_set_clr_event(create_synth_test->tr, -+ "synthetic", -+ "create_synth_test", false); - out: - return ret; - } -diff --git a/lib/vsprintf.c b/lib/vsprintf.c -index 24f37bab8bc1f..fa1c197018551 100644 ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -2092,15 +2092,20 @@ char *fwnode_full_name_string(struct fwnode_handle *fwnode, char *buf, - - /* Loop starting from the root node to the current node. */ - for (depth = fwnode_count_parents(fwnode); depth >= 0; depth--) { -- struct fwnode_handle *__fwnode = -- fwnode_get_nth_parent(fwnode, depth); -+ /* -+ * Only get a reference for other nodes (i.e. parent nodes). -+ * fwnode refcount may be 0 here. -+ */ -+ struct fwnode_handle *__fwnode = depth ? -+ fwnode_get_nth_parent(fwnode, depth) : fwnode; - - buf = string(buf, end, fwnode_get_name_prefix(__fwnode), - default_str_spec); - buf = string(buf, end, fwnode_get_name(__fwnode), - default_str_spec); - -- fwnode_handle_put(__fwnode); -+ if (depth) -+ fwnode_handle_put(__fwnode); - } - - return buf; -diff --git a/mm/damon/core.c b/mm/damon/core.c -index 36d098d06c558..5db9bec8ae67c 100644 ---- a/mm/damon/core.c -+++ b/mm/damon/core.c -@@ -383,6 +383,8 @@ struct damon_ctx *damon_new_ctx(void) - if (!ctx) - return NULL; - -+ init_completion(&ctx->kdamond_started); -+ - ctx->attrs.sample_interval = 5 * 1000; - ctx->attrs.aggr_interval = 100 * 1000; - ctx->attrs.ops_update_interval = 60 * 1000 * 1000; -@@ -519,11 +521,14 @@ static int __damon_start(struct damon_ctx *ctx) - mutex_lock(&ctx->kdamond_lock); - if (!ctx->kdamond) { - err = 0; -+ reinit_completion(&ctx->kdamond_started); - ctx->kdamond = kthread_run(kdamond_fn, ctx, "kdamond.%d", - nr_running_ctxs); - if (IS_ERR(ctx->kdamond)) { - err = PTR_ERR(ctx->kdamond); - ctx->kdamond = NULL; -+ } else { -+ wait_for_completion(&ctx->kdamond_started); - } - } - mutex_unlock(&ctx->kdamond_lock); -@@ -1147,6 +1152,8 @@ static int kdamond_fn(void *data) - - pr_debug("kdamond (%d) starts\n", current->pid); - -+ complete(&ctx->kdamond_started); -+ - if (ctx->ops.init) - ctx->ops.init(ctx); - if (ctx->callback.before_start && ctx->callback.before_start(ctx)) -diff --git a/mm/kasan/report.c b/mm/kasan/report.c -index 66a37f177d231..5d9ae80df4954 100644 ---- a/mm/kasan/report.c -+++ b/mm/kasan/report.c -@@ -523,8 +523,9 @@ void kasan_report_async(void) - } - #endif /* CONFIG_KASAN_HW_TAGS */ - -+#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) - /* -- * With CONFIG_KASAN, accesses to bogus pointers (outside the high -+ * With CONFIG_KASAN_INLINE, accesses to bogus pointers (outside the high - * canonical half of the address space) cause out-of-bounds shadow memory reads - * before the actual access. For addresses in the low canonical half of the - * address space, as well as most non-canonical addresses, that out-of-bounds -@@ -560,3 +561,4 @@ void kasan_non_canonical_hook(unsigned long addr) - pr_alert("KASAN: %s in range [0x%016lx-0x%016lx]\n", bug_type, - orig_addr, orig_addr + KASAN_GRANULE_SIZE - 1); - } -+#endif -diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c -index 0beb44f2fe1f0..f001582345052 100644 ---- a/net/8021q/vlan_core.c -+++ b/net/8021q/vlan_core.c -@@ -407,6 +407,8 @@ int vlan_vids_add_by_dev(struct net_device *dev, - return 0; - - list_for_each_entry(vid_info, &vlan_info->vid_list, list) { -+ if (!vlan_hw_filter_capable(by_dev, vid_info->proto)) -+ continue; - err = vlan_vid_add(dev, vid_info->proto, vid_info->vid); - if (err) - goto unwind; -@@ -417,6 +419,8 @@ unwind: - list_for_each_entry_continue_reverse(vid_info, - &vlan_info->vid_list, - list) { -+ if (!vlan_hw_filter_capable(by_dev, vid_info->proto)) -+ continue; - vlan_vid_del(dev, vid_info->proto, vid_info->vid); - } - -@@ -436,8 +440,11 @@ void vlan_vids_del_by_dev(struct net_device *dev, - if (!vlan_info) - return; - -- list_for_each_entry(vid_info, &vlan_info->vid_list, list) -+ list_for_each_entry(vid_info, &vlan_info->vid_list, list) { -+ if (!vlan_hw_filter_capable(by_dev, vid_info->proto)) -+ continue; - vlan_vid_del(dev, vid_info->proto, vid_info->vid); -+ } - } - EXPORT_SYMBOL(vlan_vids_del_by_dev); - -diff --git a/net/9p/protocol.c b/net/9p/protocol.c -index 4e3a2a1ffcb3f..0e6603b1ec906 100644 ---- a/net/9p/protocol.c -+++ b/net/9p/protocol.c -@@ -394,6 +394,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, - uint16_t *nwname = va_arg(ap, uint16_t *); - char ***wnames = va_arg(ap, char ***); - -+ *wnames = NULL; -+ - errcode = p9pdu_readf(pdu, proto_version, - "w", nwname); - if (!errcode) { -@@ -403,6 +405,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, - GFP_NOFS); - if (!*wnames) - errcode = -ENOMEM; -+ else -+ (*wnames)[0] = NULL; - } - - if (!errcode) { -@@ -414,8 +418,10 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, - proto_version, - "s", - &(*wnames)[i]); -- if (errcode) -+ if (errcode) { -+ (*wnames)[i] = NULL; - break; -+ } - } - } - -@@ -423,11 +429,14 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, - if (*wnames) { - int i; - -- for (i = 0; i < *nwname; i++) -+ for (i = 0; i < *nwname; i++) { -+ if (!(*wnames)[i]) -+ break; - kfree((*wnames)[i]); -+ } -+ kfree(*wnames); -+ *wnames = NULL; - } -- kfree(*wnames); -- *wnames = NULL; - } - } - break; -diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c -index 1c3c7ff5c3c66..f1b7510359e4b 100644 ---- a/net/bluetooth/af_bluetooth.c -+++ b/net/bluetooth/af_bluetooth.c -@@ -264,11 +264,14 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, - if (flags & MSG_OOB) - return -EOPNOTSUPP; - -+ lock_sock(sk); -+ - skb = skb_recv_datagram(sk, flags, &err); - if (!skb) { - if (sk->sk_shutdown & RCV_SHUTDOWN) -- return 0; -+ err = 0; - -+ release_sock(sk); - return err; - } - -@@ -294,6 +297,8 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, - - skb_free_datagram(sk, skb); - -+ release_sock(sk); -+ - if (flags & MSG_TRUNC) - copied = skblen; - -diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c -index c86a45344fe28..dcb13c64e8e7c 100644 ---- a/net/bluetooth/hci_event.c -+++ b/net/bluetooth/hci_event.c -@@ -515,6 +515,9 @@ static u8 hci_cc_read_class_of_dev(struct hci_dev *hdev, void *data, - { - struct hci_rp_read_class_of_dev *rp = data; - -+ if (WARN_ON(!hdev)) -+ return HCI_ERROR_UNSPECIFIED; -+ - bt_dev_dbg(hdev, "status 0x%2.2x", rp->status); - - if (rp->status) -@@ -746,9 +749,23 @@ static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data, - } else { - conn->enc_key_size = rp->key_size; - status = 0; -+ -+ if (conn->enc_key_size < hdev->min_enc_key_size) { -+ /* As slave role, the conn->state has been set to -+ * BT_CONNECTED and l2cap conn req might not be received -+ * yet, at this moment the l2cap layer almost does -+ * nothing with the non-zero status. -+ * So we also clear encrypt related bits, and then the -+ * handler of l2cap conn req will get the right secure -+ * state at a later time. -+ */ -+ status = HCI_ERROR_AUTH_FAILURE; -+ clear_bit(HCI_CONN_ENCRYPT, &conn->flags); -+ clear_bit(HCI_CONN_AES_CCM, &conn->flags); -+ } - } - -- hci_encrypt_cfm(conn, 0); -+ hci_encrypt_cfm(conn, status); - - done: - hci_dev_unlock(hdev); -@@ -2298,7 +2315,8 @@ static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) - return; - } - -- set_bit(HCI_INQUIRY, &hdev->flags); -+ if (hci_sent_cmd_data(hdev, HCI_OP_INQUIRY)) -+ set_bit(HCI_INQUIRY, &hdev->flags); - } - - static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) -diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c -index a7899857aee5d..4c5793053393f 100644 ---- a/net/bluetooth/l2cap_core.c -+++ b/net/bluetooth/l2cap_core.c -@@ -6493,6 +6493,14 @@ drop: - kfree_skb(skb); - } - -+static inline void l2cap_sig_send_rej(struct l2cap_conn *conn, u16 ident) -+{ -+ struct l2cap_cmd_rej_unk rej; -+ -+ rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); -+ l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); -+} -+ - static inline void l2cap_sig_channel(struct l2cap_conn *conn, - struct sk_buff *skb) - { -@@ -6518,23 +6526,24 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, - - if (len > skb->len || !cmd->ident) { - BT_DBG("corrupted command"); -+ l2cap_sig_send_rej(conn, cmd->ident); - break; - } - - err = l2cap_bredr_sig_cmd(conn, cmd, len, skb->data); - if (err) { -- struct l2cap_cmd_rej_unk rej; -- - BT_ERR("Wrong link type (%d)", err); -- -- rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); -- l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, -- sizeof(rej), &rej); -+ l2cap_sig_send_rej(conn, cmd->ident); - } - - skb_pull(skb, len); - } - -+ if (skb->len > 0) { -+ BT_DBG("corrupted command"); -+ l2cap_sig_send_rej(conn, 0); -+ } -+ - drop: - kfree_skb(skb); - } -diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c -index d2e8565d0b33f..6d631a2e60166 100644 ---- a/net/bluetooth/mgmt.c -+++ b/net/bluetooth/mgmt.c -@@ -2883,7 +2883,8 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, - for (i = 0; i < key_count; i++) { - struct mgmt_link_key_info *key = &cp->keys[i]; - -- if (key->addr.type != BDADDR_BREDR || key->type > 0x08) -+ /* Considering SMP over BREDR/LE, there is no need to check addr_type */ -+ if (key->type > 0x08) - return mgmt_cmd_status(sk, hdev->id, - MGMT_OP_LOAD_LINK_KEYS, - MGMT_STATUS_INVALID_PARAMS); -@@ -7129,6 +7130,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, - - for (i = 0; i < irk_count; i++) { - struct mgmt_irk_info *irk = &cp->irks[i]; -+ u8 addr_type = le_addr_type(irk->addr.type); - - if (hci_is_blocked_key(hdev, - HCI_BLOCKED_KEY_TYPE_IRK, -@@ -7138,8 +7140,12 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, - continue; - } - -+ /* When using SMP over BR/EDR, the addr type should be set to BREDR */ -+ if (irk->addr.type == BDADDR_BREDR) -+ addr_type = BDADDR_BREDR; -+ - hci_add_irk(hdev, &irk->addr.bdaddr, -- le_addr_type(irk->addr.type), irk->val, -+ addr_type, irk->val, - BDADDR_ANY); - } - -@@ -7220,6 +7226,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, - for (i = 0; i < key_count; i++) { - struct mgmt_ltk_info *key = &cp->keys[i]; - u8 type, authenticated; -+ u8 addr_type = le_addr_type(key->addr.type); - - if (hci_is_blocked_key(hdev, - HCI_BLOCKED_KEY_TYPE_LTK, -@@ -7254,8 +7261,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, - continue; - } - -+ /* When using SMP over BR/EDR, the addr type should be set to BREDR */ -+ if (key->addr.type == BDADDR_BREDR) -+ addr_type = BDADDR_BREDR; -+ - hci_add_ltk(hdev, &key->addr.bdaddr, -- le_addr_type(key->addr.type), type, authenticated, -+ addr_type, type, authenticated, - key->val, key->enc_size, key->ediv, key->rand); - } - -@@ -9523,7 +9534,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, - - ev.store_hint = persistent; - bacpy(&ev.key.addr.bdaddr, &key->bdaddr); -- ev.key.addr.type = BDADDR_BREDR; -+ ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type); - ev.key.type = key->type; - memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE); - ev.key.pin_len = key->pin_len; -@@ -9574,7 +9585,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) - ev.store_hint = persistent; - - bacpy(&ev.key.addr.bdaddr, &key->bdaddr); -- ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); -+ ev.key.addr.type = link_to_bdaddr(key->link_type, key->bdaddr_type); - ev.key.type = mgmt_ltk_type(key); - ev.key.enc_size = key->enc_size; - ev.key.ediv = key->ediv; -@@ -9603,7 +9614,7 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent) - - bacpy(&ev.rpa, &irk->rpa); - bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr); -- ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type); -+ ev.irk.addr.type = link_to_bdaddr(irk->link_type, irk->addr_type); - memcpy(ev.irk.val, irk->val, sizeof(irk->val)); - - mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL); -@@ -9632,7 +9643,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, - ev.store_hint = persistent; - - bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr); -- ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type); -+ ev.key.addr.type = link_to_bdaddr(csrk->link_type, csrk->bdaddr_type); - ev.key.type = csrk->type; - memcpy(ev.key.val, csrk->val, sizeof(csrk->val)); - -diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c -index 70663229b3cc9..ecb005bce65ac 100644 ---- a/net/bluetooth/smp.c -+++ b/net/bluetooth/smp.c -@@ -1058,6 +1058,7 @@ static void smp_notify_keys(struct l2cap_conn *conn) - } - - if (smp->remote_irk) { -+ smp->remote_irk->link_type = hcon->type; - mgmt_new_irk(hdev, smp->remote_irk, persistent); - - /* Now that user space can be considered to know the -@@ -1072,24 +1073,28 @@ static void smp_notify_keys(struct l2cap_conn *conn) - } - - if (smp->csrk) { -+ smp->csrk->link_type = hcon->type; - smp->csrk->bdaddr_type = hcon->dst_type; - bacpy(&smp->csrk->bdaddr, &hcon->dst); - mgmt_new_csrk(hdev, smp->csrk, persistent); - } - - if (smp->responder_csrk) { -+ smp->responder_csrk->link_type = hcon->type; - smp->responder_csrk->bdaddr_type = hcon->dst_type; - bacpy(&smp->responder_csrk->bdaddr, &hcon->dst); - mgmt_new_csrk(hdev, smp->responder_csrk, persistent); - } - - if (smp->ltk) { -+ smp->ltk->link_type = hcon->type; - smp->ltk->bdaddr_type = hcon->dst_type; - bacpy(&smp->ltk->bdaddr, &hcon->dst); - mgmt_new_ltk(hdev, smp->ltk, persistent); - } - - if (smp->responder_ltk) { -+ smp->responder_ltk->link_type = hcon->type; - smp->responder_ltk->bdaddr_type = hcon->dst_type; - bacpy(&smp->responder_ltk->bdaddr, &hcon->dst); - mgmt_new_ltk(hdev, smp->responder_ltk, persistent); -@@ -1109,6 +1114,8 @@ static void smp_notify_keys(struct l2cap_conn *conn) - key = hci_add_link_key(hdev, smp->conn->hcon, &hcon->dst, - smp->link_key, type, 0, &persistent); - if (key) { -+ key->link_type = hcon->type; -+ key->bdaddr_type = hcon->dst_type; - mgmt_new_link_key(hdev, key, persistent); - - /* Don't keep debug keys around if the relevant -diff --git a/net/core/dev.c b/net/core/dev.c -index 0d5aa820fd830..0a5566b6f8a25 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -3551,6 +3551,9 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb, - if (gso_segs > READ_ONCE(dev->gso_max_segs)) - return features & ~NETIF_F_GSO_MASK; - -+ if (unlikely(skb->len >= READ_ONCE(dev->gso_max_size))) -+ return features & ~NETIF_F_GSO_MASK; -+ - if (!skb_shinfo(skb)->gso_type) { - skb_warn_bad_offload(skb); - return features & ~NETIF_F_GSO_MASK; -diff --git a/net/core/stream.c b/net/core/stream.c -index 051aa71a8ad0f..30e7deff4c551 100644 ---- a/net/core/stream.c -+++ b/net/core/stream.c -@@ -79,7 +79,7 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p) - remove_wait_queue(sk_sleep(sk), &wait); - sk->sk_write_pending--; - } while (!done); -- return 0; -+ return done < 0 ? done : 0; - } - EXPORT_SYMBOL(sk_stream_wait_connect); - -diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c -index 3aced951d5ab8..03f8f33dc134c 100644 ---- a/net/dns_resolver/dns_key.c -+++ b/net/dns_resolver/dns_key.c -@@ -91,6 +91,7 @@ const struct cred *dns_resolver_cache; - static int - dns_resolver_preparse(struct key_preparsed_payload *prep) - { -+ const struct dns_server_list_v1_header *v1; - const struct dns_payload_header *bin; - struct user_key_payload *upayload; - unsigned long derrno; -@@ -122,6 +123,13 @@ dns_resolver_preparse(struct key_preparsed_payload *prep) - return -EINVAL; - } - -+ v1 = (const struct dns_server_list_v1_header *)bin; -+ if ((v1->status != DNS_LOOKUP_GOOD && -+ v1->status != DNS_LOOKUP_GOOD_WITH_BAD)) { -+ if (prep->expiry == TIME64_MAX) -+ prep->expiry = ktime_get_real_seconds() + 1; -+ } -+ - result_len = datalen; - goto store_result; - } -@@ -314,7 +322,7 @@ static long dns_resolver_read(const struct key *key, - - struct key_type key_type_dns_resolver = { - .name = "dns_resolver", -- .flags = KEY_TYPE_NET_DOMAIN, -+ .flags = KEY_TYPE_NET_DOMAIN | KEY_TYPE_INSTANT_REAP, - .preparse = dns_resolver_preparse, - .free_preparse = dns_resolver_free_preparse, - .instantiate = generic_key_instantiate, -diff --git a/net/ife/ife.c b/net/ife/ife.c -index 13bbf8cb6a396..be05b690b9ef2 100644 ---- a/net/ife/ife.c -+++ b/net/ife/ife.c -@@ -82,6 +82,7 @@ void *ife_decode(struct sk_buff *skb, u16 *metalen) - if (unlikely(!pskb_may_pull(skb, total_pull))) - return NULL; - -+ ifehdr = (struct ifeheadr *)(skb->data + skb->dev->hard_header_len); - skb_set_mac_header(skb, total_pull); - __skb_pull(skb, total_pull); - *metalen = ifehdrln - IFE_METAHDRLEN; -diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c -index 2ca442f485132..a2c4866080bd7 100644 ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1694,10 +1694,10 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, - lockdep_is_held(&local->sta_mtx)); - - /* -- * If there are no changes, then accept a link that doesn't exist, -+ * If there are no changes, then accept a link that exist, - * unless it's a new link. - */ -- if (params->link_id < 0 && !new_link && -+ if (params->link_id >= 0 && !new_link && - !params->link_mac && !params->txpwr_set && - !params->supported_rates_len && - !params->ht_capa && !params->vht_capa && -diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c -index bd0b7c189adfa..711c3377f428b 100644 ---- a/net/mac80211/mesh_plink.c -+++ b/net/mac80211/mesh_plink.c -@@ -1051,8 +1051,8 @@ mesh_plink_get_event(struct ieee80211_sub_if_data *sdata, - case WLAN_SP_MESH_PEERING_OPEN: - if (!matches_local) - event = OPN_RJCT; -- if (!mesh_plink_free_count(sdata) || -- (sta->mesh->plid && sta->mesh->plid != plid)) -+ else if (!mesh_plink_free_count(sdata) || -+ (sta->mesh->plid && sta->mesh->plid != plid)) - event = OPN_IGNR; - else - event = OPN_ACPT; -@@ -1060,9 +1060,9 @@ mesh_plink_get_event(struct ieee80211_sub_if_data *sdata, - case WLAN_SP_MESH_PEERING_CONFIRM: - if (!matches_local) - event = CNF_RJCT; -- if (!mesh_plink_free_count(sdata) || -- sta->mesh->llid != llid || -- (sta->mesh->plid && sta->mesh->plid != plid)) -+ else if (!mesh_plink_free_count(sdata) || -+ sta->mesh->llid != llid || -+ (sta->mesh->plid && sta->mesh->plid != plid)) - event = CNF_IGNR; - else - event = CNF_ACPT; -@@ -1230,6 +1230,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, - return; - } - elems = ieee802_11_parse_elems(baseaddr, len - baselen, true, NULL); -- mesh_process_plink_frame(sdata, mgmt, elems, rx_status); -- kfree(elems); -+ if (elems) { -+ mesh_process_plink_frame(sdata, mgmt, elems, rx_status); -+ kfree(elems); -+ } - } -diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c -index 2cc95c8dc4c7b..f74baefd855d3 100644 ---- a/net/rfkill/rfkill-gpio.c -+++ b/net/rfkill/rfkill-gpio.c -@@ -116,6 +116,14 @@ static int rfkill_gpio_probe(struct platform_device *pdev) - return -EINVAL; - } - -+ ret = gpiod_direction_output(rfkill->reset_gpio, true); -+ if (ret) -+ return ret; -+ -+ ret = gpiod_direction_output(rfkill->shutdown_gpio, true); -+ if (ret) -+ return ret; -+ - rfkill->rfkill_dev = rfkill_alloc(rfkill->name, &pdev->dev, - rfkill->type, &rfkill_gpio_ops, - rfkill); -diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c -index 674937284b8d2..29b74a569e0b0 100644 ---- a/net/rose/af_rose.c -+++ b/net/rose/af_rose.c -@@ -182,21 +182,47 @@ void rose_kill_by_neigh(struct rose_neigh *neigh) - */ - static void rose_kill_by_device(struct net_device *dev) - { -- struct sock *s; -+ struct sock *sk, *array[16]; -+ struct rose_sock *rose; -+ bool rescan; -+ int i, cnt; - -+start: -+ rescan = false; -+ cnt = 0; - spin_lock_bh(&rose_list_lock); -- sk_for_each(s, &rose_list) { -- struct rose_sock *rose = rose_sk(s); -+ sk_for_each(sk, &rose_list) { -+ rose = rose_sk(sk); -+ if (rose->device == dev) { -+ if (cnt == ARRAY_SIZE(array)) { -+ rescan = true; -+ break; -+ } -+ sock_hold(sk); -+ array[cnt++] = sk; -+ } -+ } -+ spin_unlock_bh(&rose_list_lock); - -+ for (i = 0; i < cnt; i++) { -+ sk = array[cnt]; -+ rose = rose_sk(sk); -+ lock_sock(sk); -+ spin_lock_bh(&rose_list_lock); - if (rose->device == dev) { -- rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0); -+ rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0); - if (rose->neighbour) - rose->neighbour->use--; - netdev_put(rose->device, &rose->dev_tracker); - rose->device = NULL; - } -+ spin_unlock_bh(&rose_list_lock); -+ release_sock(sk); -+ sock_put(sk); -+ cond_resched(); - } -- spin_unlock_bh(&rose_list_lock); -+ if (rescan) -+ goto start; - } - - /* -@@ -656,7 +682,10 @@ static int rose_release(struct socket *sock) - break; - } - -+ spin_lock_bh(&rose_list_lock); - netdev_put(rose->device, &rose->dev_tracker); -+ rose->device = NULL; -+ spin_unlock_bh(&rose_list_lock); - sock->sk = NULL; - release_sock(sk); - sock_put(sk); -diff --git a/net/wireless/certs/wens.hex b/net/wireless/certs/wens.hex -new file mode 100644 -index 0000000000000..0d50369bede98 ---- /dev/null -+++ b/net/wireless/certs/wens.hex -@@ -0,0 +1,87 @@ -+/* Chen-Yu Tsai's regdb certificate */ -+0x30, 0x82, 0x02, 0xa7, 0x30, 0x82, 0x01, 0x8f, -+0x02, 0x14, 0x61, 0xc0, 0x38, 0x65, 0x1a, 0xab, -+0xdc, 0xf9, 0x4b, 0xd0, 0xac, 0x7f, 0xf0, 0x6c, -+0x72, 0x48, 0xdb, 0x18, 0xc6, 0x00, 0x30, 0x0d, -+0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, -+0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x0f, 0x31, -+0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, -+0x0c, 0x04, 0x77, 0x65, 0x6e, 0x73, 0x30, 0x20, -+0x17, 0x0d, 0x32, 0x33, 0x31, 0x32, 0x30, 0x31, -+0x30, 0x37, 0x34, 0x31, 0x31, 0x34, 0x5a, 0x18, -+0x0f, 0x32, 0x31, 0x32, 0x33, 0x31, 0x31, 0x30, -+0x37, 0x30, 0x37, 0x34, 0x31, 0x31, 0x34, 0x5a, -+0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, -+0x55, 0x04, 0x03, 0x0c, 0x04, 0x77, 0x65, 0x6e, -+0x73, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, -+0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, -+0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, -+0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, -+0x01, 0x00, 0xa9, 0x7a, 0x2c, 0x78, 0x4d, 0xa7, -+0x19, 0x2d, 0x32, 0x52, 0xa0, 0x2e, 0x6c, 0xef, -+0x88, 0x7f, 0x15, 0xc5, 0xb6, 0x69, 0x54, 0x16, -+0x43, 0x14, 0x79, 0x53, 0xb7, 0xae, 0x88, 0xfe, -+0xc0, 0xb7, 0x5d, 0x47, 0x8e, 0x1a, 0xe1, 0xef, -+0xb3, 0x90, 0x86, 0xda, 0xd3, 0x64, 0x81, 0x1f, -+0xce, 0x5d, 0x9e, 0x4b, 0x6e, 0x58, 0x02, 0x3e, -+0xb2, 0x6f, 0x5e, 0x42, 0x47, 0x41, 0xf4, 0x2c, -+0xb8, 0xa8, 0xd4, 0xaa, 0xc0, 0x0e, 0xe6, 0x48, -+0xf0, 0xa8, 0xce, 0xcb, 0x08, 0xae, 0x37, 0xaf, -+0xf6, 0x40, 0x39, 0xcb, 0x55, 0x6f, 0x5b, 0x4f, -+0x85, 0x34, 0xe6, 0x69, 0x10, 0x50, 0x72, 0x5e, -+0x4e, 0x9d, 0x4c, 0xba, 0x38, 0x36, 0x0d, 0xce, -+0x73, 0x38, 0xd7, 0x27, 0x02, 0x2a, 0x79, 0x03, -+0xe1, 0xac, 0xcf, 0xb0, 0x27, 0x85, 0x86, 0x93, -+0x17, 0xab, 0xec, 0x42, 0x77, 0x37, 0x65, 0x8a, -+0x44, 0xcb, 0xd6, 0x42, 0x93, 0x92, 0x13, 0xe3, -+0x39, 0x45, 0xc5, 0x6e, 0x00, 0x4a, 0x7f, 0xcb, -+0x42, 0x17, 0x2b, 0x25, 0x8c, 0xb8, 0x17, 0x3b, -+0x15, 0x36, 0x59, 0xde, 0x42, 0xce, 0x21, 0xe6, -+0xb6, 0xc7, 0x6e, 0x5e, 0x26, 0x1f, 0xf7, 0x8a, -+0x57, 0x9e, 0xa5, 0x96, 0x72, 0xb7, 0x02, 0x32, -+0xeb, 0x07, 0x2b, 0x73, 0xe2, 0x4f, 0x66, 0x58, -+0x9a, 0xeb, 0x0f, 0x07, 0xb6, 0xab, 0x50, 0x8b, -+0xc3, 0x8f, 0x17, 0xfa, 0x0a, 0x99, 0xc2, 0x16, -+0x25, 0xbf, 0x2d, 0x6b, 0x1a, 0xaa, 0xe6, 0x3e, -+0x5f, 0xeb, 0x6d, 0x9b, 0x5d, 0x4d, 0x42, 0x83, -+0x2d, 0x39, 0xb8, 0xc9, 0xac, 0xdb, 0x3a, 0x91, -+0x50, 0xdf, 0xbb, 0xb1, 0x76, 0x6d, 0x15, 0x73, -+0xfd, 0xc6, 0xe6, 0x6b, 0x71, 0x9e, 0x67, 0x36, -+0x22, 0x83, 0x79, 0xb1, 0xd6, 0xb8, 0x84, 0x52, -+0xaf, 0x96, 0x5b, 0xc3, 0x63, 0x02, 0x4e, 0x78, -+0x70, 0x57, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, -+0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, -+0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, -+0x01, 0x01, 0x00, 0x24, 0x28, 0xee, 0x22, 0x74, -+0x7f, 0x7c, 0xfa, 0x6c, 0x1f, 0xb3, 0x18, 0xd1, -+0xc2, 0x3d, 0x7d, 0x29, 0x42, 0x88, 0xad, 0x82, -+0xa5, 0xb1, 0x8a, 0x05, 0xd0, 0xec, 0x5c, 0x91, -+0x20, 0xf6, 0x82, 0xfd, 0xd5, 0x67, 0x60, 0x5f, -+0x31, 0xf5, 0xbd, 0x88, 0x91, 0x70, 0xbd, 0xb8, -+0xb9, 0x8c, 0x88, 0xfe, 0x53, 0xc9, 0x54, 0x9b, -+0x43, 0xc4, 0x7a, 0x43, 0x74, 0x6b, 0xdd, 0xb0, -+0xb1, 0x3b, 0x33, 0x45, 0x46, 0x78, 0xa3, 0x1c, -+0xef, 0x54, 0x68, 0xf7, 0x85, 0x9c, 0xe4, 0x51, -+0x6f, 0x06, 0xaf, 0x81, 0xdb, 0x2a, 0x7b, 0x7b, -+0x6f, 0xa8, 0x9c, 0x67, 0xd8, 0xcb, 0xc9, 0x91, -+0x40, 0x00, 0xae, 0xd9, 0xa1, 0x9f, 0xdd, 0xa6, -+0x43, 0x0e, 0x28, 0x7b, 0xaa, 0x1b, 0xe9, 0x84, -+0xdb, 0x76, 0x64, 0x42, 0x70, 0xc9, 0xc0, 0xeb, -+0xae, 0x84, 0x11, 0x16, 0x68, 0x4e, 0x84, 0x9e, -+0x7e, 0x92, 0x36, 0xee, 0x1c, 0x3b, 0x08, 0x63, -+0xeb, 0x79, 0x84, 0x15, 0x08, 0x9d, 0xaf, 0xc8, -+0x9a, 0xc7, 0x34, 0xd3, 0x94, 0x4b, 0xd1, 0x28, -+0x97, 0xbe, 0xd1, 0x45, 0x75, 0xdc, 0x35, 0x62, -+0xac, 0x1d, 0x1f, 0xb7, 0xb7, 0x15, 0x87, 0xc8, -+0x98, 0xc0, 0x24, 0x31, 0x56, 0x8d, 0xed, 0xdb, -+0x06, 0xc6, 0x46, 0xbf, 0x4b, 0x6d, 0xa6, 0xd5, -+0xab, 0xcc, 0x60, 0xfc, 0xe5, 0x37, 0xb6, 0x53, -+0x7d, 0x58, 0x95, 0xa9, 0x56, 0xc7, 0xf7, 0xee, -+0xc3, 0xa0, 0x76, 0xf7, 0x65, 0x4d, 0x53, 0xfa, -+0xff, 0x5f, 0x76, 0x33, 0x5a, 0x08, 0xfa, 0x86, -+0x92, 0x5a, 0x13, 0xfa, 0x1a, 0xfc, 0xf2, 0x1b, -+0x8c, 0x7f, 0x42, 0x6d, 0xb7, 0x7e, 0xb7, 0xb4, -+0xf0, 0xc7, 0x83, 0xbb, 0xa2, 0x81, 0x03, 0x2d, -+0xd4, 0x2a, 0x63, 0x3f, 0xf7, 0x31, 0x2e, 0x40, -+0x33, 0x5c, 0x46, 0xbc, 0x9b, 0xc1, 0x05, 0xa5, -+0x45, 0x4e, 0xc3, -diff --git a/net/wireless/core.h b/net/wireless/core.h -index e1accacc6f233..ee980965a7cfb 100644 ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -297,6 +297,7 @@ struct cfg80211_cqm_config { - u32 rssi_hyst; - s32 last_rssi_event_value; - enum nl80211_cqm_rssi_threshold_event last_rssi_event_type; -+ bool use_range_api; - int n_rssi_thresholds; - s32 rssi_thresholds[]; - }; -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index b19b5acfaf3a9..70fb14b8bab07 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -12574,10 +12574,6 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, - int i, n, low_index; - int err; - -- /* RSSI reporting disabled? */ -- if (!cqm_config) -- return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); -- - /* - * Obtain current RSSI value if possible, if not and no RSSI threshold - * event has been received yet, we should receive an event after a -@@ -12652,18 +12648,6 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) - return -EOPNOTSUPP; - -- if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) { -- if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */ -- return rdev_set_cqm_rssi_config(rdev, dev, 0, 0); -- -- return rdev_set_cqm_rssi_config(rdev, dev, -- thresholds[0], hysteresis); -- } -- -- if (!wiphy_ext_feature_isset(&rdev->wiphy, -- NL80211_EXT_FEATURE_CQM_RSSI_LIST)) -- return -EOPNOTSUPP; -- - if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */ - n_thresholds = 0; - -@@ -12671,6 +12655,26 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - old = rcu_dereference_protected(wdev->cqm_config, - lockdep_is_held(&wdev->mtx)); - -+ /* if already disabled just succeed */ -+ if (!n_thresholds && !old) { -+ err = 0; -+ goto unlock; -+ } -+ -+ if (n_thresholds > 1) { -+ if (!wiphy_ext_feature_isset(&rdev->wiphy, -+ NL80211_EXT_FEATURE_CQM_RSSI_LIST) || -+ !rdev->ops->set_cqm_rssi_range_config) { -+ err = -EOPNOTSUPP; -+ goto unlock; -+ } -+ } else { -+ if (!rdev->ops->set_cqm_rssi_config) { -+ err = -EOPNOTSUPP; -+ goto unlock; -+ } -+ } -+ - if (n_thresholds) { - cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, - n_thresholds), -@@ -12685,13 +12689,26 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, - memcpy(cqm_config->rssi_thresholds, thresholds, - flex_array_size(cqm_config, rssi_thresholds, - n_thresholds)); -+ cqm_config->use_range_api = n_thresholds > 1 || -+ !rdev->ops->set_cqm_rssi_config; - - rcu_assign_pointer(wdev->cqm_config, cqm_config); -+ -+ if (cqm_config->use_range_api) -+ err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); -+ else -+ err = rdev_set_cqm_rssi_config(rdev, dev, -+ thresholds[0], -+ hysteresis); - } else { - RCU_INIT_POINTER(wdev->cqm_config, NULL); -+ /* if enabled as range also disable via range */ -+ if (old->use_range_api) -+ err = rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); -+ else -+ err = rdev_set_cqm_rssi_config(rdev, dev, 0, 0); - } - -- err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); - if (err) { - rcu_assign_pointer(wdev->cqm_config, old); - kfree_rcu(cqm_config, rcu_head); -@@ -18758,10 +18775,11 @@ void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work) - wdev_lock(wdev); - cqm_config = rcu_dereference_protected(wdev->cqm_config, - lockdep_is_held(&wdev->mtx)); -- if (!wdev->cqm_config) -+ if (!cqm_config) - goto unlock; - -- cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); -+ if (cqm_config->use_range_api) -+ cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); - - rssi_level = cqm_config->last_rssi_event_value; - rssi_event = cqm_config->last_rssi_event_type; -diff --git a/security/keys/gc.c b/security/keys/gc.c -index 3c90807476eb0..eaddaceda14ea 100644 ---- a/security/keys/gc.c -+++ b/security/keys/gc.c -@@ -66,6 +66,19 @@ void key_schedule_gc(time64_t gc_at) - } - } - -+/* -+ * Set the expiration time on a key. -+ */ -+void key_set_expiry(struct key *key, time64_t expiry) -+{ -+ key->expiry = expiry; -+ if (expiry != TIME64_MAX) { -+ if (!(key->type->flags & KEY_TYPE_INSTANT_REAP)) -+ expiry += key_gc_delay; -+ key_schedule_gc(expiry); -+ } -+} -+ - /* - * Schedule a dead links collection run. - */ -@@ -176,7 +189,6 @@ static void key_garbage_collector(struct work_struct *work) - static u8 gc_state; /* Internal persistent state */ - #define KEY_GC_REAP_AGAIN 0x01 /* - Need another cycle */ - #define KEY_GC_REAPING_LINKS 0x02 /* - We need to reap links */ --#define KEY_GC_SET_TIMER 0x04 /* - We need to restart the timer */ - #define KEY_GC_REAPING_DEAD_1 0x10 /* - We need to mark dead keys */ - #define KEY_GC_REAPING_DEAD_2 0x20 /* - We need to reap dead key links */ - #define KEY_GC_REAPING_DEAD_3 0x40 /* - We need to reap dead keys */ -@@ -184,21 +196,17 @@ static void key_garbage_collector(struct work_struct *work) - - struct rb_node *cursor; - struct key *key; -- time64_t new_timer, limit; -+ time64_t new_timer, limit, expiry; - - kenter("[%lx,%x]", key_gc_flags, gc_state); - - limit = ktime_get_real_seconds(); -- if (limit > key_gc_delay) -- limit -= key_gc_delay; -- else -- limit = key_gc_delay; - - /* Work out what we're going to be doing in this pass */ - gc_state &= KEY_GC_REAPING_DEAD_1 | KEY_GC_REAPING_DEAD_2; - gc_state <<= 1; - if (test_and_clear_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags)) -- gc_state |= KEY_GC_REAPING_LINKS | KEY_GC_SET_TIMER; -+ gc_state |= KEY_GC_REAPING_LINKS; - - if (test_and_clear_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags)) - gc_state |= KEY_GC_REAPING_DEAD_1; -@@ -233,8 +241,11 @@ continue_scanning: - } - } - -- if (gc_state & KEY_GC_SET_TIMER) { -- if (key->expiry > limit && key->expiry < new_timer) { -+ expiry = key->expiry; -+ if (expiry != TIME64_MAX) { -+ if (!(key->type->flags & KEY_TYPE_INSTANT_REAP)) -+ expiry += key_gc_delay; -+ if (expiry > limit && expiry < new_timer) { - kdebug("will expire %x in %lld", - key_serial(key), key->expiry - limit); - new_timer = key->expiry; -@@ -276,7 +287,7 @@ maybe_resched: - */ - kdebug("pass complete"); - -- if (gc_state & KEY_GC_SET_TIMER && new_timer != (time64_t)TIME64_MAX) { -+ if (new_timer != TIME64_MAX) { - new_timer += key_gc_delay; - key_schedule_gc(new_timer); - } -diff --git a/security/keys/internal.h b/security/keys/internal.h -index 3c1e7122076b9..ec2ec335b6133 100644 ---- a/security/keys/internal.h -+++ b/security/keys/internal.h -@@ -174,6 +174,7 @@ extern unsigned key_gc_delay; - extern void keyring_gc(struct key *keyring, time64_t limit); - extern void keyring_restriction_gc(struct key *keyring, - struct key_type *dead_type); -+void key_set_expiry(struct key *key, time64_t expiry); - extern void key_schedule_gc(time64_t gc_at); - extern void key_schedule_gc_links(void); - extern void key_gc_keytype(struct key_type *ktype); -@@ -222,10 +223,18 @@ extern struct key *key_get_instantiation_authkey(key_serial_t target_id); - */ - static inline bool key_is_dead(const struct key *key, time64_t limit) - { -+ time64_t expiry = key->expiry; -+ -+ if (expiry != TIME64_MAX) { -+ if (!(key->type->flags & KEY_TYPE_INSTANT_REAP)) -+ expiry += key_gc_delay; -+ if (expiry <= limit) -+ return true; -+ } -+ - return - key->flags & ((1 << KEY_FLAG_DEAD) | - (1 << KEY_FLAG_INVALIDATED)) || -- (key->expiry > 0 && key->expiry <= limit) || - key->domain_tag->removed; - } - -diff --git a/security/keys/key.c b/security/keys/key.c -index c45afdd1dfbb4..e65240641ca57 100644 ---- a/security/keys/key.c -+++ b/security/keys/key.c -@@ -294,6 +294,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, - key->uid = uid; - key->gid = gid; - key->perm = perm; -+ key->expiry = TIME64_MAX; - key->restrict_link = restrict_link; - key->last_used_at = ktime_get_real_seconds(); - -@@ -463,10 +464,7 @@ static int __key_instantiate_and_link(struct key *key, - if (authkey) - key_invalidate(authkey); - -- if (prep->expiry != TIME64_MAX) { -- key->expiry = prep->expiry; -- key_schedule_gc(prep->expiry + key_gc_delay); -- } -+ key_set_expiry(key, prep->expiry); - } - } - -@@ -606,8 +604,7 @@ int key_reject_and_link(struct key *key, - atomic_inc(&key->user->nikeys); - mark_key_instantiated(key, -error); - notify_key(key, NOTIFY_KEY_INSTANTIATED, -error); -- key->expiry = ktime_get_real_seconds() + timeout; -- key_schedule_gc(key->expiry + key_gc_delay); -+ key_set_expiry(key, ktime_get_real_seconds() + timeout); - - if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) - awaken = 1; -@@ -722,16 +719,14 @@ found_kernel_type: - - void key_set_timeout(struct key *key, unsigned timeout) - { -- time64_t expiry = 0; -+ time64_t expiry = TIME64_MAX; - - /* make the changes with the locks held to prevent races */ - down_write(&key->sem); - - if (timeout > 0) - expiry = ktime_get_real_seconds() + timeout; -- -- key->expiry = expiry; -- key_schedule_gc(key->expiry + key_gc_delay); -+ key_set_expiry(key, expiry); - - up_write(&key->sem); - } -diff --git a/security/keys/proc.c b/security/keys/proc.c -index d0cde6685627f..4f4e2c1824f18 100644 ---- a/security/keys/proc.c -+++ b/security/keys/proc.c -@@ -198,7 +198,7 @@ static int proc_keys_show(struct seq_file *m, void *v) - - /* come up with a suitable timeout value */ - expiry = READ_ONCE(key->expiry); -- if (expiry == 0) { -+ if (expiry == TIME64_MAX) { - memcpy(xbuf, "perm", 5); - } else if (now >= expiry) { - memcpy(xbuf, "expd", 5); -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index a7c361e0daebe..a88ed60dcd96a 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9735,6 +9735,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604V", ALC285_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603V", ALC285_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), -+ SND_PCI_QUIRK(0x1043, 0x1533, "ASUS GV302XA", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301V", ALC285_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), - SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), -diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c -index 4d3c3365488a2..d8259afc60b08 100644 ---- a/sound/soc/codecs/hdmi-codec.c -+++ b/sound/soc/codecs/hdmi-codec.c -@@ -834,8 +834,9 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai) - static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp, - unsigned int jack_status) - { -- if (hcp->jack && jack_status != hcp->jack_status) { -- snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT); -+ if (jack_status != hcp->jack_status) { -+ if (hcp->jack) -+ snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT); - hcp->jack_status = jack_status; - } - } -@@ -864,6 +865,13 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component, - - if (hcp->hcd.ops->hook_plugged_cb) { - hcp->jack = jack; -+ -+ /* -+ * Report the initial jack status which may have been provided -+ * by the parent hdmi driver while the hpd hook was registered. -+ */ -+ snd_soc_jack_report(jack, hcp->jack_status, SND_JACK_LINEOUT); -+ - return 0; - } - -diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c -index 6364d9be28fbb..cf1cd0460ad98 100644 ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -715,6 +715,9 @@ static int fsl_sai_hw_free(struct snd_pcm_substream *substream, - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - unsigned int ofs = sai->soc_data->reg_offset; - -+ /* Clear xMR to avoid channel swap with mclk_with_tere enabled case */ -+ regmap_write(sai->regmap, FSL_SAI_xMR(tx), 0); -+ - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), - FSL_SAI_CR3_TRCE_MASK, 0); - -diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c -index f458328f9ec42..33380cad3a735 100644 ---- a/sound/usb/quirks.c -+++ b/sound/usb/quirks.c -@@ -1385,7 +1385,7 @@ free_buf: - - static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev) - { -- msleep(2000); -+ msleep(4000); - - return 0; - } -@@ -1628,7 +1628,7 @@ int snd_usb_apply_boot_quirk_once(struct usb_device *dev, - unsigned int id) - { - switch (id) { -- case USB_ID(0x07fd, 0x0008): /* MOTU M Series */ -+ case USB_ID(0x07fd, 0x0008): /* MOTU M Series, 1st hardware version */ - return snd_usb_motu_m_series_boot_quirk(dev); - } - -diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh -index ea6fc59e9f62f..e52d513009fb0 100755 ---- a/tools/testing/selftests/net/mptcp/mptcp_join.sh -+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh -@@ -2652,7 +2652,7 @@ backup_tests() - fi - - if reset "mpc backup" && -- continue_if mptcp_lib_kallsyms_doesnt_have "mptcp_subflow_send_ack$"; then -+ continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then - pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup - run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow - chk_join_nr 0 0 0 -@@ -2660,7 +2660,7 @@ backup_tests() - fi - - if reset "mpc backup both sides" && -- continue_if mptcp_lib_kallsyms_doesnt_have "mptcp_subflow_send_ack$"; then -+ continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then - pm_nl_add_endpoint $ns1 10.0.1.1 flags subflow,backup - pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup - run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow -@@ -2669,7 +2669,7 @@ backup_tests() - fi - - if reset "mpc switch to backup" && -- continue_if mptcp_lib_kallsyms_doesnt_have "mptcp_subflow_send_ack$"; then -+ continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then - pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow - run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup - chk_join_nr 0 0 0 -@@ -2677,7 +2677,7 @@ backup_tests() - fi - - if reset "mpc switch to backup both sides" && -- continue_if mptcp_lib_kallsyms_doesnt_have "mptcp_subflow_send_ack$"; then -+ continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then - pm_nl_add_endpoint $ns1 10.0.1.1 flags subflow - pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow - run_tests $ns1 $ns2 10.0.1.1 0 0 0 slow backup diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.70-71.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.70-71.patch deleted file mode 100644 index b085fc4d77e7..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.70-71.patch +++ /dev/null @@ -1,7517 +0,0 @@ -diff --git a/Makefile b/Makefile -index 270593fcafdcd..2840e36fd5596 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 70 -+SUBLEVEL = 71 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi -index 32d397b3950b9..b2e7f6a710740 100644 ---- a/arch/arm/boot/dts/am33xx.dtsi -+++ b/arch/arm/boot/dts/am33xx.dtsi -@@ -349,6 +349,7 @@ - , - , - ; -+ ti,sysc-delay-us = <2>; - clocks = <&l3s_clkctrl AM3_L3S_USB_OTG_HS_CLKCTRL 0>; - clock-names = "fck"; - #address-cells = <1>; -diff --git a/drivers/base/property.c b/drivers/base/property.c -index b0c40d9734847..eb9b01c2ff1d9 100644 ---- a/drivers/base/property.c -+++ b/drivers/base/property.c -@@ -17,12 +17,19 @@ - #include - #include - --struct fwnode_handle *dev_fwnode(const struct device *dev) -+struct fwnode_handle *__dev_fwnode(struct device *dev) - { - return IS_ENABLED(CONFIG_OF) && dev->of_node ? - of_fwnode_handle(dev->of_node) : dev->fwnode; - } --EXPORT_SYMBOL_GPL(dev_fwnode); -+EXPORT_SYMBOL_GPL(__dev_fwnode); -+ -+const struct fwnode_handle *__dev_fwnode_const(const struct device *dev) -+{ -+ return IS_ENABLED(CONFIG_OF) && dev->of_node ? -+ of_fwnode_handle(dev->of_node) : dev->fwnode; -+} -+EXPORT_SYMBOL_GPL(__dev_fwnode_const); - - /** - * device_property_present - check if a property of a device is present -diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c -index aec55f7e1f260..2d939773445d7 100644 ---- a/drivers/iio/imu/adis16475.c -+++ b/drivers/iio/imu/adis16475.c -@@ -1243,50 +1243,6 @@ static int adis16475_config_irq_pin(struct adis16475 *st) - return 0; - } - --static const struct of_device_id adis16475_of_match[] = { -- { .compatible = "adi,adis16470", -- .data = &adis16475_chip_info[ADIS16470] }, -- { .compatible = "adi,adis16475-1", -- .data = &adis16475_chip_info[ADIS16475_1] }, -- { .compatible = "adi,adis16475-2", -- .data = &adis16475_chip_info[ADIS16475_2] }, -- { .compatible = "adi,adis16475-3", -- .data = &adis16475_chip_info[ADIS16475_3] }, -- { .compatible = "adi,adis16477-1", -- .data = &adis16475_chip_info[ADIS16477_1] }, -- { .compatible = "adi,adis16477-2", -- .data = &adis16475_chip_info[ADIS16477_2] }, -- { .compatible = "adi,adis16477-3", -- .data = &adis16475_chip_info[ADIS16477_3] }, -- { .compatible = "adi,adis16465-1", -- .data = &adis16475_chip_info[ADIS16465_1] }, -- { .compatible = "adi,adis16465-2", -- .data = &adis16475_chip_info[ADIS16465_2] }, -- { .compatible = "adi,adis16465-3", -- .data = &adis16475_chip_info[ADIS16465_3] }, -- { .compatible = "adi,adis16467-1", -- .data = &adis16475_chip_info[ADIS16467_1] }, -- { .compatible = "adi,adis16467-2", -- .data = &adis16475_chip_info[ADIS16467_2] }, -- { .compatible = "adi,adis16467-3", -- .data = &adis16475_chip_info[ADIS16467_3] }, -- { .compatible = "adi,adis16500", -- .data = &adis16475_chip_info[ADIS16500] }, -- { .compatible = "adi,adis16505-1", -- .data = &adis16475_chip_info[ADIS16505_1] }, -- { .compatible = "adi,adis16505-2", -- .data = &adis16475_chip_info[ADIS16505_2] }, -- { .compatible = "adi,adis16505-3", -- .data = &adis16475_chip_info[ADIS16505_3] }, -- { .compatible = "adi,adis16507-1", -- .data = &adis16475_chip_info[ADIS16507_1] }, -- { .compatible = "adi,adis16507-2", -- .data = &adis16475_chip_info[ADIS16507_2] }, -- { .compatible = "adi,adis16507-3", -- .data = &adis16475_chip_info[ADIS16507_3] }, -- { }, --}; --MODULE_DEVICE_TABLE(of, adis16475_of_match); - - static int adis16475_probe(struct spi_device *spi) - { -@@ -1300,7 +1256,7 @@ static int adis16475_probe(struct spi_device *spi) - - st = iio_priv(indio_dev); - -- st->info = device_get_match_data(&spi->dev); -+ st->info = spi_get_device_match_data(spi); - if (!st->info) - return -EINVAL; - -@@ -1340,12 +1296,83 @@ static int adis16475_probe(struct spi_device *spi) - return 0; - } - -+static const struct of_device_id adis16475_of_match[] = { -+ { .compatible = "adi,adis16470", -+ .data = &adis16475_chip_info[ADIS16470] }, -+ { .compatible = "adi,adis16475-1", -+ .data = &adis16475_chip_info[ADIS16475_1] }, -+ { .compatible = "adi,adis16475-2", -+ .data = &adis16475_chip_info[ADIS16475_2] }, -+ { .compatible = "adi,adis16475-3", -+ .data = &adis16475_chip_info[ADIS16475_3] }, -+ { .compatible = "adi,adis16477-1", -+ .data = &adis16475_chip_info[ADIS16477_1] }, -+ { .compatible = "adi,adis16477-2", -+ .data = &adis16475_chip_info[ADIS16477_2] }, -+ { .compatible = "adi,adis16477-3", -+ .data = &adis16475_chip_info[ADIS16477_3] }, -+ { .compatible = "adi,adis16465-1", -+ .data = &adis16475_chip_info[ADIS16465_1] }, -+ { .compatible = "adi,adis16465-2", -+ .data = &adis16475_chip_info[ADIS16465_2] }, -+ { .compatible = "adi,adis16465-3", -+ .data = &adis16475_chip_info[ADIS16465_3] }, -+ { .compatible = "adi,adis16467-1", -+ .data = &adis16475_chip_info[ADIS16467_1] }, -+ { .compatible = "adi,adis16467-2", -+ .data = &adis16475_chip_info[ADIS16467_2] }, -+ { .compatible = "adi,adis16467-3", -+ .data = &adis16475_chip_info[ADIS16467_3] }, -+ { .compatible = "adi,adis16500", -+ .data = &adis16475_chip_info[ADIS16500] }, -+ { .compatible = "adi,adis16505-1", -+ .data = &adis16475_chip_info[ADIS16505_1] }, -+ { .compatible = "adi,adis16505-2", -+ .data = &adis16475_chip_info[ADIS16505_2] }, -+ { .compatible = "adi,adis16505-3", -+ .data = &adis16475_chip_info[ADIS16505_3] }, -+ { .compatible = "adi,adis16507-1", -+ .data = &adis16475_chip_info[ADIS16507_1] }, -+ { .compatible = "adi,adis16507-2", -+ .data = &adis16475_chip_info[ADIS16507_2] }, -+ { .compatible = "adi,adis16507-3", -+ .data = &adis16475_chip_info[ADIS16507_3] }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, adis16475_of_match); -+ -+static const struct spi_device_id adis16475_ids[] = { -+ { "adis16470", (kernel_ulong_t)&adis16475_chip_info[ADIS16470] }, -+ { "adis16475-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_1] }, -+ { "adis16475-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_2] }, -+ { "adis16475-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16475_3] }, -+ { "adis16477-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_1] }, -+ { "adis16477-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_2] }, -+ { "adis16477-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16477_3] }, -+ { "adis16465-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_1] }, -+ { "adis16465-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_2] }, -+ { "adis16465-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16465_3] }, -+ { "adis16467-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_1] }, -+ { "adis16467-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_2] }, -+ { "adis16467-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16467_3] }, -+ { "adis16500", (kernel_ulong_t)&adis16475_chip_info[ADIS16500] }, -+ { "adis16505-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_1] }, -+ { "adis16505-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_2] }, -+ { "adis16505-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16505_3] }, -+ { "adis16507-1", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_1] }, -+ { "adis16507-2", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_2] }, -+ { "adis16507-3", (kernel_ulong_t)&adis16475_chip_info[ADIS16507_3] }, -+ { } -+}; -+MODULE_DEVICE_TABLE(spi, adis16475_ids); -+ - static struct spi_driver adis16475_driver = { - .driver = { - .name = "adis16475", - .of_match_table = adis16475_of_match, - }, - .probe = adis16475_probe, -+ .id_table = adis16475_ids, - }; - module_spi_driver(adis16475_driver); - -diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c -index c4f22d50dba58..78daf2b2143c5 100644 ---- a/drivers/spi/spi-atmel.c -+++ b/drivers/spi/spi-atmel.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - - /* SPI register offsets */ -@@ -278,6 +279,7 @@ struct atmel_spi { - bool keep_cs; - - u32 fifo_size; -+ bool last_polarity; - u8 native_cs_free; - u8 native_cs_for_gpio; - }; -@@ -290,6 +292,22 @@ struct atmel_spi_device { - #define SPI_MAX_DMA_XFER 65535 /* true for both PDC and DMA */ - #define INVALID_DMA_ADDRESS 0xffffffff - -+/* -+ * This frequency can be anything supported by the controller, but to avoid -+ * unnecessary delay, the highest possible frequency is chosen. -+ * -+ * This frequency is the highest possible which is not interfering with other -+ * chip select registers (see Note for Serial Clock Bit Rate configuration in -+ * Atmel-11121F-ATARM-SAMA5D3-Series-Datasheet_02-Feb-16, page 1283) -+ */ -+#define DUMMY_MSG_FREQUENCY 0x02 -+/* -+ * 8 bits is the minimum data the controller is capable of sending. -+ * -+ * This message can be anything as it should not be treated by any SPI device. -+ */ -+#define DUMMY_MSG 0xAA -+ - /* - * Version 2 of the SPI controller has - * - CR.LASTXFER -@@ -303,6 +321,43 @@ static bool atmel_spi_is_v2(struct atmel_spi *as) - return as->caps.is_spi2; - } - -+/* -+ * Send a dummy message. -+ * -+ * This is sometimes needed when using a CS GPIO to force clock transition when -+ * switching between devices with different polarities. -+ */ -+static void atmel_spi_send_dummy(struct atmel_spi *as, struct spi_device *spi, int chip_select) -+{ -+ u32 status; -+ u32 csr; -+ -+ /* -+ * Set a clock frequency to allow sending message on SPI bus. -+ * The frequency here can be anything, but is needed for -+ * the controller to send the data. -+ */ -+ csr = spi_readl(as, CSR0 + 4 * chip_select); -+ csr = SPI_BFINS(SCBR, DUMMY_MSG_FREQUENCY, csr); -+ spi_writel(as, CSR0 + 4 * chip_select, csr); -+ -+ /* -+ * Read all data coming from SPI bus, needed to be able to send -+ * the message. -+ */ -+ spi_readl(as, RDR); -+ while (spi_readl(as, SR) & SPI_BIT(RDRF)) { -+ spi_readl(as, RDR); -+ cpu_relax(); -+ } -+ -+ spi_writel(as, TDR, DUMMY_MSG); -+ -+ readl_poll_timeout_atomic(as->regs + SPI_SR, status, -+ (status & SPI_BIT(TXEMPTY)), 1, 1000); -+} -+ -+ - /* - * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby - * they assume that spi slave device state will not change on deselect, so -@@ -319,11 +374,17 @@ static bool atmel_spi_is_v2(struct atmel_spi *as) - * Master on Chip Select 0.") No workaround exists for that ... so for - * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH, - * and (c) will trigger that first erratum in some cases. -+ * -+ * When changing the clock polarity, the SPI controller waits for the next -+ * transmission to enforce the default clock state. This may be an issue when -+ * using a GPIO as Chip Select: the clock level is applied only when the first -+ * packet is sent, once the CS has already been asserted. The workaround is to -+ * avoid this by sending a first (dummy) message before toggling the CS state. - */ -- - static void cs_activate(struct atmel_spi *as, struct spi_device *spi) - { - struct atmel_spi_device *asd = spi->controller_state; -+ bool new_polarity; - int chip_select; - u32 mr; - -@@ -352,6 +413,25 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) - } - - mr = spi_readl(as, MR); -+ -+ /* -+ * Ensures the clock polarity is valid before we actually -+ * assert the CS to avoid spurious clock edges to be -+ * processed by the spi devices. -+ */ -+ if (spi_get_csgpiod(spi, 0)) { -+ new_polarity = (asd->csr & SPI_BIT(CPOL)) != 0; -+ if (new_polarity != as->last_polarity) { -+ /* -+ * Need to disable the GPIO before sending the dummy -+ * message because it is already set by the spi core. -+ */ -+ gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), 0); -+ atmel_spi_send_dummy(as, spi, chip_select); -+ as->last_polarity = new_polarity; -+ gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), 1); -+ } -+ } - } else { - u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; - int i; -diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c -index 5d046be8b2dd5..22d227878bc44 100644 ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -360,6 +360,18 @@ const struct spi_device_id *spi_get_device_id(const struct spi_device *sdev) - } - EXPORT_SYMBOL_GPL(spi_get_device_id); - -+const void *spi_get_device_match_data(const struct spi_device *sdev) -+{ -+ const void *match; -+ -+ match = device_get_match_data(&sdev->dev); -+ if (match) -+ return match; -+ -+ return (const void *)spi_get_device_id(sdev)->driver_data; -+} -+EXPORT_SYMBOL_GPL(spi_get_device_match_data); -+ - static int spi_match_device(struct device *dev, struct device_driver *drv) - { - const struct spi_device *spi = to_spi_device(dev); -@@ -592,7 +604,7 @@ static void spi_dev_set_name(struct spi_device *spi) - } - - dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->controller->dev), -- spi->chip_select); -+ spi_get_chipselect(spi, 0)); - } - - static int spi_dev_check(struct device *dev, void *data) -@@ -601,7 +613,7 @@ static int spi_dev_check(struct device *dev, void *data) - struct spi_device *new_spi = data; - - if (spi->controller == new_spi->controller && -- spi->chip_select == new_spi->chip_select) -+ spi_get_chipselect(spi, 0) == spi_get_chipselect(new_spi, 0)) - return -EBUSY; - return 0; - } -@@ -626,7 +638,7 @@ static int __spi_add_device(struct spi_device *spi) - status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check); - if (status) { - dev_err(dev, "chipselect %d already in use\n", -- spi->chip_select); -+ spi_get_chipselect(spi, 0)); - return status; - } - -@@ -637,7 +649,7 @@ static int __spi_add_device(struct spi_device *spi) - } - - if (ctlr->cs_gpiods) -- spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select]; -+ spi_set_csgpiod(spi, 0, ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]); - - /* - * Drivers may modify this initial i/o setup, but will -@@ -680,8 +692,8 @@ int spi_add_device(struct spi_device *spi) - int status; - - /* Chipselects are numbered 0..max; validate. */ -- if (spi->chip_select >= ctlr->num_chipselect) { -- dev_err(dev, "cs%d >= max %d\n", spi->chip_select, -+ if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) { -+ dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0), - ctlr->num_chipselect); - return -EINVAL; - } -@@ -702,8 +714,8 @@ static int spi_add_device_locked(struct spi_device *spi) - struct device *dev = ctlr->dev.parent; - - /* Chipselects are numbered 0..max; validate. */ -- if (spi->chip_select >= ctlr->num_chipselect) { -- dev_err(dev, "cs%d >= max %d\n", spi->chip_select, -+ if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) { -+ dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0), - ctlr->num_chipselect); - return -EINVAL; - } -@@ -749,7 +761,7 @@ struct spi_device *spi_new_device(struct spi_controller *ctlr, - - WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias)); - -- proxy->chip_select = chip->chip_select; -+ spi_set_chipselect(proxy, 0, chip->chip_select); - proxy->max_speed_hz = chip->max_speed_hz; - proxy->mode = chip->mode; - proxy->irq = chip->irq; -@@ -958,24 +970,23 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) - * Avoid calling into the driver (or doing delays) if the chip select - * isn't actually changing from the last time this was called. - */ -- if (!force && ((enable && spi->controller->last_cs == spi->chip_select) || -- (!enable && spi->controller->last_cs != spi->chip_select)) && -+ if (!force && ((enable && spi->controller->last_cs == spi_get_chipselect(spi, 0)) || -+ (!enable && spi->controller->last_cs != spi_get_chipselect(spi, 0))) && - (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH))) - return; - - trace_spi_set_cs(spi, activate); - -- spi->controller->last_cs = enable ? spi->chip_select : -1; -+ spi->controller->last_cs = enable ? spi_get_chipselect(spi, 0) : -1; - spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH; - -- if ((spi->cs_gpiod || !spi->controller->set_cs_timing) && !activate) { -+ if ((spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) && !activate) - spi_delay_exec(&spi->cs_hold, NULL); -- } - - if (spi->mode & SPI_CS_HIGH) - enable = !enable; - -- if (spi->cs_gpiod) { -+ if (spi_get_csgpiod(spi, 0)) { - if (!(spi->mode & SPI_NO_CS)) { - /* - * Historically ACPI has no means of the GPIO polarity and -@@ -988,10 +999,10 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) - * into account. - */ - if (has_acpi_companion(&spi->dev)) -- gpiod_set_value_cansleep(spi->cs_gpiod, !enable); -+ gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), !enable); - else - /* Polarity handled by GPIO library */ -- gpiod_set_value_cansleep(spi->cs_gpiod, activate); -+ gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), activate); - } - /* Some SPI masters need both GPIO CS & slave_select */ - if ((spi->controller->flags & SPI_MASTER_GPIO_SS) && -@@ -1001,7 +1012,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) - spi->controller->set_cs(spi, !enable); - } - -- if (spi->cs_gpiod || !spi->controller->set_cs_timing) { -+ if (spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) { - if (activate) - spi_delay_exec(&spi->cs_setup, NULL); - else -@@ -2291,7 +2302,7 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, - nc, rc); - return rc; - } -- spi->chip_select = value; -+ spi_set_chipselect(spi, 0, value); - - /* Device speed */ - if (!of_property_read_u32(nc, "spi-max-frequency", &value)) -@@ -2405,7 +2416,7 @@ struct spi_device *spi_new_ancillary_device(struct spi_device *spi, - strscpy(ancillary->modalias, "dummy", sizeof(ancillary->modalias)); - - /* Use provided chip-select for ancillary device */ -- ancillary->chip_select = chip_select; -+ spi_set_chipselect(ancillary, 0, chip_select); - - /* Take over SPI mode/speed from SPI main device */ - ancillary->max_speed_hz = spi->max_speed_hz; -@@ -2652,7 +2663,7 @@ struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, - spi->mode |= lookup.mode; - spi->irq = lookup.irq; - spi->bits_per_word = lookup.bits_per_word; -- spi->chip_select = lookup.chip_select; -+ spi_set_chipselect(spi, 0, lookup.chip_select); - - return spi; - } -@@ -3611,6 +3622,37 @@ static int __spi_validate_bits_per_word(struct spi_controller *ctlr, - return 0; - } - -+/** -+ * spi_set_cs_timing - configure CS setup, hold, and inactive delays -+ * @spi: the device that requires specific CS timing configuration -+ * -+ * Return: zero on success, else a negative error code. -+ */ -+static int spi_set_cs_timing(struct spi_device *spi) -+{ -+ struct device *parent = spi->controller->dev.parent; -+ int status = 0; -+ -+ if (spi->controller->set_cs_timing && !spi_get_csgpiod(spi, 0)) { -+ if (spi->controller->auto_runtime_pm) { -+ status = pm_runtime_get_sync(parent); -+ if (status < 0) { -+ pm_runtime_put_noidle(parent); -+ dev_err(&spi->controller->dev, "Failed to power device: %d\n", -+ status); -+ return status; -+ } -+ -+ status = spi->controller->set_cs_timing(spi); -+ pm_runtime_mark_last_busy(parent); -+ pm_runtime_put_autosuspend(parent); -+ } else { -+ status = spi->controller->set_cs_timing(spi); -+ } -+ } -+ return status; -+} -+ - /** - * spi_setup - setup SPI mode and clock rate - * @spi: the device whose settings are being modified -@@ -3707,6 +3749,12 @@ int spi_setup(struct spi_device *spi) - } - } - -+ status = spi_set_cs_timing(spi); -+ if (status) { -+ mutex_unlock(&spi->controller->io_mutex); -+ return status; -+ } -+ - if (spi->controller->auto_runtime_pm && spi->controller->set_cs) { - status = pm_runtime_resume_and_get(spi->controller->dev.parent); - if (status < 0) { -@@ -3790,7 +3838,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) - * cs_change is set for each transfer. - */ - if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) || -- spi->cs_gpiod)) { -+ spi_get_csgpiod(spi, 0))) { - size_t maxsize; - int ret; - -diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c -index c4c1fbc12b4cd..dc968960769e1 100644 ---- a/drivers/usb/host/fotg210-hcd.c -+++ b/drivers/usb/host/fotg210-hcd.c -@@ -429,8 +429,6 @@ static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh, - temp = size; - size -= temp; - next += temp; -- if (temp == size) -- goto done; - } - - temp = snprintf(next, size, "\n"); -@@ -440,7 +438,6 @@ static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh, - size -= temp; - next += temp; - --done: - *sizep = size; - *nextp = next; - } -diff --git a/fs/namei.c b/fs/namei.c -index 5e1c2ab2ae709..b5578f4ce5d6e 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -253,6 +253,7 @@ getname_kernel(const char * filename) - - return result; - } -+EXPORT_SYMBOL(getname_kernel); - - void putname(struct filename *name) - { -@@ -271,6 +272,7 @@ void putname(struct filename *name) - } else - __putname(name); - } -+EXPORT_SYMBOL(putname); - - /** - * check_acl - perform ACL permission checking -@@ -1581,8 +1583,9 @@ static struct dentry *lookup_dcache(const struct qstr *name, - * when directory is guaranteed to have no in-lookup children - * at all. - */ --static struct dentry *__lookup_hash(const struct qstr *name, -- struct dentry *base, unsigned int flags) -+struct dentry *lookup_one_qstr_excl(const struct qstr *name, -+ struct dentry *base, -+ unsigned int flags) - { - struct dentry *dentry = lookup_dcache(name, base, flags); - struct dentry *old; -@@ -1606,6 +1609,7 @@ static struct dentry *__lookup_hash(const struct qstr *name, - } - return dentry; - } -+EXPORT_SYMBOL(lookup_one_qstr_excl); - - static struct dentry *lookup_fast(struct nameidata *nd) - { -@@ -2532,16 +2536,17 @@ static int path_parentat(struct nameidata *nd, unsigned flags, - } - - /* Note: this does not consume "name" */ --static int filename_parentat(int dfd, struct filename *name, -- unsigned int flags, struct path *parent, -- struct qstr *last, int *type) -+static int __filename_parentat(int dfd, struct filename *name, -+ unsigned int flags, struct path *parent, -+ struct qstr *last, int *type, -+ const struct path *root) - { - int retval; - struct nameidata nd; - - if (IS_ERR(name)) - return PTR_ERR(name); -- set_nameidata(&nd, dfd, name, NULL); -+ set_nameidata(&nd, dfd, name, root); - retval = path_parentat(&nd, flags | LOOKUP_RCU, parent); - if (unlikely(retval == -ECHILD)) - retval = path_parentat(&nd, flags, parent); -@@ -2556,6 +2561,13 @@ static int filename_parentat(int dfd, struct filename *name, - return retval; - } - -+static int filename_parentat(int dfd, struct filename *name, -+ unsigned int flags, struct path *parent, -+ struct qstr *last, int *type) -+{ -+ return __filename_parentat(dfd, name, flags, parent, last, type, NULL); -+} -+ - /* does lookup, returns the object with parent locked */ - static struct dentry *__kern_path_locked(struct filename *name, struct path *path) - { -@@ -2571,7 +2583,7 @@ static struct dentry *__kern_path_locked(struct filename *name, struct path *pat - return ERR_PTR(-EINVAL); - } - inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT); -- d = __lookup_hash(&last, path->dentry, 0); -+ d = lookup_one_qstr_excl(&last, path->dentry, 0); - if (IS_ERR(d)) { - inode_unlock(path->dentry->d_inode); - path_put(path); -@@ -2599,6 +2611,24 @@ int kern_path(const char *name, unsigned int flags, struct path *path) - } - EXPORT_SYMBOL(kern_path); - -+/** -+ * vfs_path_parent_lookup - lookup a parent path relative to a dentry-vfsmount pair -+ * @filename: filename structure -+ * @flags: lookup flags -+ * @parent: pointer to struct path to fill -+ * @last: last component -+ * @type: type of the last component -+ * @root: pointer to struct path of the base directory -+ */ -+int vfs_path_parent_lookup(struct filename *filename, unsigned int flags, -+ struct path *parent, struct qstr *last, int *type, -+ const struct path *root) -+{ -+ return __filename_parentat(AT_FDCWD, filename, flags, parent, last, -+ type, root); -+} -+EXPORT_SYMBOL(vfs_path_parent_lookup); -+ - /** - * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair - * @dentry: pointer to dentry of the base directory -@@ -2980,20 +3010,10 @@ static inline int may_create(struct user_namespace *mnt_userns, - return inode_permission(mnt_userns, dir, MAY_WRITE | MAY_EXEC); - } - --/* -- * p1 and p2 should be directories on the same fs. -- */ --struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) -+static struct dentry *lock_two_directories(struct dentry *p1, struct dentry *p2) - { - struct dentry *p; - -- if (p1 == p2) { -- inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); -- return NULL; -- } -- -- mutex_lock(&p1->d_sb->s_vfs_rename_mutex); -- - p = d_ancestor(p2, p1); - if (p) { - inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); -@@ -3012,8 +3032,64 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) - I_MUTEX_PARENT, I_MUTEX_PARENT2); - return NULL; - } -+ -+/* -+ * p1 and p2 should be directories on the same fs. -+ */ -+struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) -+{ -+ if (p1 == p2) { -+ inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); -+ return NULL; -+ } -+ -+ mutex_lock(&p1->d_sb->s_vfs_rename_mutex); -+ return lock_two_directories(p1, p2); -+} - EXPORT_SYMBOL(lock_rename); - -+/* -+ * c1 and p2 should be on the same fs. -+ */ -+struct dentry *lock_rename_child(struct dentry *c1, struct dentry *p2) -+{ -+ if (READ_ONCE(c1->d_parent) == p2) { -+ /* -+ * hopefully won't need to touch ->s_vfs_rename_mutex at all. -+ */ -+ inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); -+ /* -+ * now that p2 is locked, nobody can move in or out of it, -+ * so the test below is safe. -+ */ -+ if (likely(c1->d_parent == p2)) -+ return NULL; -+ -+ /* -+ * c1 got moved out of p2 while we'd been taking locks; -+ * unlock and fall back to slow case. -+ */ -+ inode_unlock(p2->d_inode); -+ } -+ -+ mutex_lock(&c1->d_sb->s_vfs_rename_mutex); -+ /* -+ * nobody can move out of any directories on this fs. -+ */ -+ if (likely(c1->d_parent != p2)) -+ return lock_two_directories(c1->d_parent, p2); -+ -+ /* -+ * c1 got moved into p2 while we were taking locks; -+ * we need p2 locked and ->s_vfs_rename_mutex unlocked, -+ * for consistency with lock_rename(). -+ */ -+ inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); -+ mutex_unlock(&c1->d_sb->s_vfs_rename_mutex); -+ return NULL; -+} -+EXPORT_SYMBOL(lock_rename_child); -+ - void unlock_rename(struct dentry *p1, struct dentry *p2) - { - inode_unlock(p1->d_inode); -@@ -3806,7 +3882,8 @@ static struct dentry *filename_create(int dfd, struct filename *name, - if (last.name[last.len] && !want_dir) - create_flags = 0; - inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT); -- dentry = __lookup_hash(&last, path->dentry, reval_flag | create_flags); -+ dentry = lookup_one_qstr_excl(&last, path->dentry, -+ reval_flag | create_flags); - if (IS_ERR(dentry)) - goto unlock; - -@@ -4168,7 +4245,7 @@ retry: - goto exit2; - - inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT); -- dentry = __lookup_hash(&last, path.dentry, lookup_flags); -+ dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags); - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto exit3; -@@ -4302,7 +4379,7 @@ retry: - goto exit2; - retry_deleg: - inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT); -- dentry = __lookup_hash(&last, path.dentry, lookup_flags); -+ dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - struct user_namespace *mnt_userns; -@@ -4876,7 +4953,8 @@ retry: - retry_deleg: - trap = lock_rename(new_path.dentry, old_path.dentry); - -- old_dentry = __lookup_hash(&old_last, old_path.dentry, lookup_flags); -+ old_dentry = lookup_one_qstr_excl(&old_last, old_path.dentry, -+ lookup_flags); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -4884,7 +4962,8 @@ retry_deleg: - error = -ENOENT; - if (d_is_negative(old_dentry)) - goto exit4; -- new_dentry = __lookup_hash(&new_last, new_path.dentry, lookup_flags | target_flags); -+ new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry, -+ lookup_flags | target_flags); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; -diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c -index 573de0d49e172..b3b4542e31ed5 100644 ---- a/fs/nfsd/nfsctl.c -+++ b/fs/nfsd/nfsctl.c -@@ -716,8 +716,10 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred - - err = svc_addsock(nn->nfsd_serv, net, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred); - -- if (err >= 0 && -- !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) -+ if (err < 0 && !nn->nfsd_serv->sv_nrthreads && !nn->keep_active) -+ nfsd_last_thread(net); -+ else if (err >= 0 && -+ !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) - svc_get(nn->nfsd_serv); - - nfsd_put(net); -@@ -767,6 +769,9 @@ out_close: - svc_xprt_put(xprt); - } - out_err: -+ if (!nn->nfsd_serv->sv_nrthreads && !nn->keep_active) -+ nfsd_last_thread(net); -+ - nfsd_put(net); - return err; - } -diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h -index 09726c5b9a317..53166cce7062c 100644 ---- a/fs/nfsd/nfsd.h -+++ b/fs/nfsd/nfsd.h -@@ -97,7 +97,12 @@ int nfsd_pool_stats_open(struct inode *, struct file *); - int nfsd_pool_stats_release(struct inode *, struct file *); - void nfsd_shutdown_threads(struct net *net); - --void nfsd_put(struct net *net); -+static inline void nfsd_put(struct net *net) -+{ -+ struct nfsd_net *nn = net_generic(net, nfsd_net_id); -+ -+ svc_put(nn->nfsd_serv); -+} - - bool i_am_nfsd(void); - -@@ -134,6 +139,7 @@ int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change); - int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change); - void nfsd_reset_versions(struct nfsd_net *nn); - int nfsd_create_serv(struct net *net); -+void nfsd_last_thread(struct net *net); - - extern int nfsd_max_blksize; - -diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c -index f6cc99af81925..350c6c72f793f 100644 ---- a/fs/nfsd/nfssvc.c -+++ b/fs/nfsd/nfssvc.c -@@ -523,9 +523,14 @@ static struct notifier_block nfsd_inet6addr_notifier = { - /* Only used under nfsd_mutex, so this atomic may be overkill: */ - static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0); - --static void nfsd_last_thread(struct svc_serv *serv, struct net *net) -+void nfsd_last_thread(struct net *net) - { - struct nfsd_net *nn = net_generic(net, nfsd_net_id); -+ struct svc_serv *serv = nn->nfsd_serv; -+ -+ spin_lock(&nfsd_notifier_lock); -+ nn->nfsd_serv = NULL; -+ spin_unlock(&nfsd_notifier_lock); - - /* check if the notifier still has clients */ - if (atomic_dec_return(&nfsd_notifier_refcount) == 0) { -@@ -535,6 +540,8 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net) - #endif - } - -+ svc_xprt_destroy_all(serv, net); -+ - /* - * write_ports can create the server without actually starting - * any threads--if we get shut down before any threads are -@@ -625,7 +632,8 @@ void nfsd_shutdown_threads(struct net *net) - svc_get(serv); - /* Kill outstanding nfsd threads */ - svc_set_num_threads(serv, NULL, 0); -- nfsd_put(net); -+ nfsd_last_thread(net); -+ svc_put(serv); - mutex_unlock(&nfsd_mutex); - } - -@@ -655,9 +663,6 @@ int nfsd_create_serv(struct net *net) - serv->sv_maxconn = nn->max_connections; - error = svc_bind(serv, net); - if (error < 0) { -- /* NOT nfsd_put() as notifiers (see below) haven't -- * been set up yet. -- */ - svc_put(serv); - return error; - } -@@ -700,29 +705,6 @@ int nfsd_get_nrthreads(int n, int *nthreads, struct net *net) - return 0; - } - --/* This is the callback for kref_put() below. -- * There is no code here as the first thing to be done is -- * call svc_shutdown_net(), but we cannot get the 'net' from -- * the kref. So do all the work when kref_put returns true. -- */ --static void nfsd_noop(struct kref *ref) --{ --} -- --void nfsd_put(struct net *net) --{ -- struct nfsd_net *nn = net_generic(net, nfsd_net_id); -- -- if (kref_put(&nn->nfsd_serv->sv_refcnt, nfsd_noop)) { -- svc_xprt_destroy_all(nn->nfsd_serv, net); -- nfsd_last_thread(nn->nfsd_serv, net); -- svc_destroy(&nn->nfsd_serv->sv_refcnt); -- spin_lock(&nfsd_notifier_lock); -- nn->nfsd_serv = NULL; -- spin_unlock(&nfsd_notifier_lock); -- } --} -- - int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) - { - int i = 0; -@@ -773,7 +755,7 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) - if (err) - break; - } -- nfsd_put(net); -+ svc_put(nn->nfsd_serv); - return err; - } - -@@ -788,6 +770,7 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) - int error; - bool nfsd_up_before; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); -+ struct svc_serv *serv; - - mutex_lock(&nfsd_mutex); - dprintk("nfsd: creating service\n"); -@@ -807,22 +790,25 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) - goto out; - - nfsd_up_before = nn->nfsd_net_up; -+ serv = nn->nfsd_serv; - - error = nfsd_startup_net(net, cred); - if (error) - goto out_put; -- error = svc_set_num_threads(nn->nfsd_serv, NULL, nrservs); -+ error = svc_set_num_threads(serv, NULL, nrservs); - if (error) - goto out_shutdown; -- error = nn->nfsd_serv->sv_nrthreads; -+ error = serv->sv_nrthreads; -+ if (error == 0) -+ nfsd_last_thread(net); - out_shutdown: - if (error < 0 && !nfsd_up_before) - nfsd_shutdown_net(net); - out_put: - /* Threads now hold service active */ - if (xchg(&nn->keep_active, 0)) -- nfsd_put(net); -- nfsd_put(net); -+ svc_put(serv); -+ svc_put(serv); - out: - mutex_unlock(&nfsd_mutex); - return error; -@@ -1138,11 +1124,12 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file) - - int nfsd_pool_stats_release(struct inode *inode, struct file *file) - { -+ struct seq_file *seq = file->private_data; -+ struct svc_serv *serv = seq->private; - int ret = seq_release(inode, file); -- struct net *net = inode->i_sb->s_fs_info; - - mutex_lock(&nfsd_mutex); -- nfsd_put(net); -+ svc_put(serv); - mutex_unlock(&nfsd_mutex); - return ret; - } -diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h -index c8a4014f9d395..07549957b3099 100644 ---- a/fs/smb/common/smb2pdu.h -+++ b/fs/smb/common/smb2pdu.h -@@ -1196,6 +1196,7 @@ struct create_posix { - #define SMB2_LEASE_WRITE_CACHING_LE cpu_to_le32(0x04) - - #define SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE cpu_to_le32(0x02) -+#define SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE cpu_to_le32(0x04) - - #define SMB2_LEASE_KEY_SIZE 16 - -diff --git a/fs/smb/server/Kconfig b/fs/smb/server/Kconfig -index e1fe17747ed69..d036ab80fec35 100644 ---- a/fs/smb/server/Kconfig -+++ b/fs/smb/server/Kconfig -@@ -1,5 +1,5 @@ - config SMB_SERVER -- tristate "SMB3 server support (EXPERIMENTAL)" -+ tristate "SMB3 server support" - depends on INET - depends on MULTIUSER - depends on FILE_LOCKING -@@ -33,14 +33,16 @@ config SMB_SERVER - in ksmbd-tools, available from - https://github.com/cifsd-team/ksmbd-tools. - More detail about how to run the ksmbd kernel server is -- available via README file -+ available via the README file - (https://github.com/cifsd-team/ksmbd-tools/blob/master/README). - - ksmbd kernel server includes support for auto-negotiation, - Secure negotiate, Pre-authentication integrity, oplock/lease, - compound requests, multi-credit, packet signing, RDMA(smbdirect), - smb3 encryption, copy-offload, secure per-user session -- establishment via NTLM or NTLMv2. -+ establishment via Kerberos or NTLMv2. -+ -+if SMB_SERVER - - config SMB_SERVER_SMBDIRECT - bool "Support for SMB Direct protocol" -@@ -54,6 +56,8 @@ config SMB_SERVER_SMBDIRECT - SMB Direct allows transferring SMB packets over RDMA. If unsure, - say N. - -+endif -+ - config SMB_SERVER_CHECK_CAP_NET_ADMIN - bool "Enable check network administration capability" - depends on SMB_SERVER -diff --git a/fs/smb/server/asn1.c b/fs/smb/server/asn1.c -index c03eba0903682..4a4b2b03ff33d 100644 ---- a/fs/smb/server/asn1.c -+++ b/fs/smb/server/asn1.c -@@ -208,32 +208,29 @@ int ksmbd_neg_token_init_mech_type(void *context, size_t hdrlen, - return 0; - } - --int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen, -- unsigned char tag, const void *value, -- size_t vlen) -+static int ksmbd_neg_token_alloc(void *context, size_t hdrlen, -+ unsigned char tag, const void *value, -+ size_t vlen) - { - struct ksmbd_conn *conn = context; - -- conn->mechToken = kmalloc(vlen + 1, GFP_KERNEL); -+ conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL); - if (!conn->mechToken) - return -ENOMEM; - -- memcpy(conn->mechToken, value, vlen); -- conn->mechToken[vlen] = '\0'; - return 0; - } - --int ksmbd_neg_token_targ_resp_token(void *context, size_t hdrlen, -+int ksmbd_neg_token_init_mech_token(void *context, size_t hdrlen, - unsigned char tag, const void *value, - size_t vlen) - { -- struct ksmbd_conn *conn = context; -- -- conn->mechToken = kmalloc(vlen + 1, GFP_KERNEL); -- if (!conn->mechToken) -- return -ENOMEM; -+ return ksmbd_neg_token_alloc(context, hdrlen, tag, value, vlen); -+} - -- memcpy(conn->mechToken, value, vlen); -- conn->mechToken[vlen] = '\0'; -- return 0; -+int ksmbd_neg_token_targ_resp_token(void *context, size_t hdrlen, -+ unsigned char tag, const void *value, -+ size_t vlen) -+{ -+ return ksmbd_neg_token_alloc(context, hdrlen, tag, value, vlen); - } -diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c -index 15e5684e328c1..229a6527870d0 100644 ---- a/fs/smb/server/auth.c -+++ b/fs/smb/server/auth.c -@@ -1032,11 +1032,15 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, - { - struct scatterlist *sg; - unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20; -- int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0; -+ int i, *nr_entries, total_entries = 0, sg_idx = 0; - - if (!nvec) - return NULL; - -+ nr_entries = kcalloc(nvec, sizeof(int), GFP_KERNEL); -+ if (!nr_entries) -+ return NULL; -+ - for (i = 0; i < nvec - 1; i++) { - unsigned long kaddr = (unsigned long)iov[i + 1].iov_base; - -@@ -1054,8 +1058,10 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, - total_entries += 2; - - sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL); -- if (!sg) -+ if (!sg) { -+ kfree(nr_entries); - return NULL; -+ } - - sg_init_table(sg, total_entries); - smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len); -@@ -1089,6 +1095,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, - } - } - smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE); -+ kfree(nr_entries); - return sg; - } - -diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c -index ff97cad8d5b45..b6fa1e285c401 100644 ---- a/fs/smb/server/connection.c -+++ b/fs/smb/server/connection.c -@@ -114,10 +114,8 @@ void ksmbd_conn_enqueue_request(struct ksmbd_work *work) - struct ksmbd_conn *conn = work->conn; - struct list_head *requests_queue = NULL; - -- if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE) { -+ if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE) - requests_queue = &conn->requests; -- work->syncronous = true; -- } - - if (requests_queue) { - atomic_inc(&conn->req_running); -@@ -127,28 +125,22 @@ void ksmbd_conn_enqueue_request(struct ksmbd_work *work) - } - } - --int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work) -+void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work) - { - struct ksmbd_conn *conn = work->conn; -- int ret = 1; - - if (list_empty(&work->request_entry) && - list_empty(&work->async_request_entry)) -- return 0; -+ return; - -- if (!work->multiRsp) -- atomic_dec(&conn->req_running); -+ atomic_dec(&conn->req_running); - spin_lock(&conn->request_lock); -- if (!work->multiRsp) { -- list_del_init(&work->request_entry); -- if (work->syncronous == false) -- list_del_init(&work->async_request_entry); -- ret = 0; -- } -+ list_del_init(&work->request_entry); - spin_unlock(&conn->request_lock); -+ if (work->asynchronous) -+ release_async_work(work); - - wake_up_all(&conn->req_running_q); -- return ret; - } - - void ksmbd_conn_lock(struct ksmbd_conn *conn) -@@ -175,63 +167,31 @@ void ksmbd_all_conn_set_status(u64 sess_id, u32 status) - - void ksmbd_conn_wait_idle(struct ksmbd_conn *conn, u64 sess_id) - { -- struct ksmbd_conn *bind_conn; -- - wait_event(conn->req_running_q, atomic_read(&conn->req_running) < 2); -- -- down_read(&conn_list_lock); -- list_for_each_entry(bind_conn, &conn_list, conns_list) { -- if (bind_conn == conn) -- continue; -- -- if ((bind_conn->binding || xa_load(&bind_conn->sessions, sess_id)) && -- !ksmbd_conn_releasing(bind_conn) && -- atomic_read(&bind_conn->req_running)) { -- wait_event(bind_conn->req_running_q, -- atomic_read(&bind_conn->req_running) == 0); -- } -- } -- up_read(&conn_list_lock); - } - - int ksmbd_conn_write(struct ksmbd_work *work) - { - struct ksmbd_conn *conn = work->conn; -- size_t len = 0; - int sent; -- struct kvec iov[3]; -- int iov_idx = 0; - - if (!work->response_buf) { - pr_err("NULL response header\n"); - return -EINVAL; - } - -- if (work->tr_buf) { -- iov[iov_idx] = (struct kvec) { work->tr_buf, -- sizeof(struct smb2_transform_hdr) + 4 }; -- len += iov[iov_idx++].iov_len; -- } -+ if (work->send_no_response) -+ return 0; - -- if (work->aux_payload_sz) { -- iov[iov_idx] = (struct kvec) { work->response_buf, work->resp_hdr_sz }; -- len += iov[iov_idx++].iov_len; -- iov[iov_idx] = (struct kvec) { work->aux_payload_buf, work->aux_payload_sz }; -- len += iov[iov_idx++].iov_len; -- } else { -- if (work->tr_buf) -- iov[iov_idx].iov_len = work->resp_hdr_sz; -- else -- iov[iov_idx].iov_len = get_rfc1002_len(work->response_buf) + 4; -- iov[iov_idx].iov_base = work->response_buf; -- len += iov[iov_idx++].iov_len; -- } -+ if (!work->iov_idx) -+ return -EINVAL; - - ksmbd_conn_lock(conn); -- sent = conn->transport->ops->writev(conn->transport, &iov[0], -- iov_idx, len, -- work->need_invalidate_rkey, -- work->remote_key); -+ sent = conn->transport->ops->writev(conn->transport, work->iov, -+ work->iov_cnt, -+ get_rfc1002_len(work->iov[0].iov_base) + 4, -+ work->need_invalidate_rkey, -+ work->remote_key); - ksmbd_conn_unlock(conn); - - if (sent < 0) { -@@ -345,7 +305,7 @@ int ksmbd_conn_handler_loop(void *p) - max_allowed_pdu_size = SMB3_MAX_MSGSIZE; - - if (pdu_size > max_allowed_pdu_size) { -- pr_err_ratelimited("PDU length(%u) excceed maximum allowed pdu size(%u) on connection(%d)\n", -+ pr_err_ratelimited("PDU length(%u) exceeded maximum allowed pdu size(%u) on connection(%d)\n", - pdu_size, max_allowed_pdu_size, - READ_ONCE(conn->status)); - break; -diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h -index 335fdd714d595..3c005246a32e8 100644 ---- a/fs/smb/server/connection.h -+++ b/fs/smb/server/connection.h -@@ -159,7 +159,7 @@ int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, - struct smb2_buffer_desc_v1 *desc, - unsigned int desc_len); - void ksmbd_conn_enqueue_request(struct ksmbd_work *work); --int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work); -+void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work); - void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops); - int ksmbd_conn_handler_loop(void *p); - int ksmbd_conn_transport_init(void); -diff --git a/fs/smb/server/ksmbd_netlink.h b/fs/smb/server/ksmbd_netlink.h -index ce866ff159bfe..b7521e41402e0 100644 ---- a/fs/smb/server/ksmbd_netlink.h -+++ b/fs/smb/server/ksmbd_netlink.h -@@ -74,6 +74,7 @@ struct ksmbd_heartbeat { - #define KSMBD_GLOBAL_FLAG_SMB2_LEASES BIT(0) - #define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION BIT(1) - #define KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL BIT(2) -+#define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF BIT(3) - - /* - * IPC request for ksmbd server startup -@@ -351,7 +352,8 @@ enum KSMBD_TREE_CONN_STATUS { - #define KSMBD_SHARE_FLAG_STREAMS BIT(11) - #define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS BIT(12) - #define KSMBD_SHARE_FLAG_ACL_XATTR BIT(13) --#define KSMBD_SHARE_FLAG_UPDATE BIT(14) -+#define KSMBD_SHARE_FLAG_UPDATE BIT(14) -+#define KSMBD_SHARE_FLAG_CROSSMNT BIT(15) - - /* - * Tree connect request flags. -diff --git a/fs/smb/server/ksmbd_work.c b/fs/smb/server/ksmbd_work.c -index 14b9caebf7a4f..d7c676c151e20 100644 ---- a/fs/smb/server/ksmbd_work.c -+++ b/fs/smb/server/ksmbd_work.c -@@ -27,18 +27,38 @@ struct ksmbd_work *ksmbd_alloc_work_struct(void) - INIT_LIST_HEAD(&work->async_request_entry); - INIT_LIST_HEAD(&work->fp_entry); - INIT_LIST_HEAD(&work->interim_entry); -+ INIT_LIST_HEAD(&work->aux_read_list); -+ work->iov_alloc_cnt = 4; -+ work->iov = kcalloc(work->iov_alloc_cnt, sizeof(struct kvec), -+ GFP_KERNEL); -+ if (!work->iov) { -+ kmem_cache_free(work_cache, work); -+ work = NULL; -+ } - } - return work; - } - - void ksmbd_free_work_struct(struct ksmbd_work *work) - { -+ struct aux_read *ar, *tmp; -+ - WARN_ON(work->saved_cred != NULL); - - kvfree(work->response_buf); -- kvfree(work->aux_payload_buf); -+ -+ list_for_each_entry_safe(ar, tmp, &work->aux_read_list, entry) { -+ kvfree(ar->buf); -+ list_del(&ar->entry); -+ kfree(ar); -+ } -+ - kfree(work->tr_buf); - kvfree(work->request_buf); -+ kfree(work->iov); -+ if (!list_empty(&work->interim_entry)) -+ list_del(&work->interim_entry); -+ - if (work->async_id) - ksmbd_release_id(&work->conn->async_ida, work->async_id); - kmem_cache_free(work_cache, work); -@@ -77,3 +97,81 @@ bool ksmbd_queue_work(struct ksmbd_work *work) - { - return queue_work(ksmbd_wq, &work->work); - } -+ -+static inline void __ksmbd_iov_pin(struct ksmbd_work *work, void *ib, -+ unsigned int ib_len) -+{ -+ work->iov[++work->iov_idx].iov_base = ib; -+ work->iov[work->iov_idx].iov_len = ib_len; -+ work->iov_cnt++; -+} -+ -+static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, -+ void *aux_buf, unsigned int aux_size) -+{ -+ struct aux_read *ar = NULL; -+ int need_iov_cnt = 1; -+ -+ if (aux_size) { -+ need_iov_cnt++; -+ ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL); -+ if (!ar) -+ return -ENOMEM; -+ } -+ -+ if (work->iov_alloc_cnt < work->iov_cnt + need_iov_cnt) { -+ struct kvec *new; -+ -+ work->iov_alloc_cnt += 4; -+ new = krealloc(work->iov, -+ sizeof(struct kvec) * work->iov_alloc_cnt, -+ GFP_KERNEL | __GFP_ZERO); -+ if (!new) { -+ kfree(ar); -+ work->iov_alloc_cnt -= 4; -+ return -ENOMEM; -+ } -+ work->iov = new; -+ } -+ -+ /* Plus rfc_length size on first iov */ -+ if (!work->iov_idx) { -+ work->iov[work->iov_idx].iov_base = work->response_buf; -+ *(__be32 *)work->iov[0].iov_base = 0; -+ work->iov[work->iov_idx].iov_len = 4; -+ work->iov_cnt++; -+ } -+ -+ __ksmbd_iov_pin(work, ib, len); -+ inc_rfc1001_len(work->iov[0].iov_base, len); -+ -+ if (aux_size) { -+ __ksmbd_iov_pin(work, aux_buf, aux_size); -+ inc_rfc1001_len(work->iov[0].iov_base, aux_size); -+ -+ ar->buf = aux_buf; -+ list_add(&ar->entry, &work->aux_read_list); -+ } -+ -+ return 0; -+} -+ -+int ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len) -+{ -+ return __ksmbd_iov_pin_rsp(work, ib, len, NULL, 0); -+} -+ -+int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len, -+ void *aux_buf, unsigned int aux_size) -+{ -+ return __ksmbd_iov_pin_rsp(work, ib, len, aux_buf, aux_size); -+} -+ -+int allocate_interim_rsp_buf(struct ksmbd_work *work) -+{ -+ work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, GFP_KERNEL); -+ if (!work->response_buf) -+ return -ENOMEM; -+ work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; -+ return 0; -+} -diff --git a/fs/smb/server/ksmbd_work.h b/fs/smb/server/ksmbd_work.h -index 5ece58e40c979..8ca2c813246e6 100644 ---- a/fs/smb/server/ksmbd_work.h -+++ b/fs/smb/server/ksmbd_work.h -@@ -19,6 +19,11 @@ enum { - KSMBD_WORK_CLOSED, - }; - -+struct aux_read { -+ void *buf; -+ struct list_head entry; -+}; -+ - /* one of these for every pending CIFS request at the connection */ - struct ksmbd_work { - /* Server corresponding to this mid */ -@@ -31,13 +36,19 @@ struct ksmbd_work { - /* Response buffer */ - void *response_buf; - -- /* Read data buffer */ -- void *aux_payload_buf; -+ struct list_head aux_read_list; -+ -+ struct kvec *iov; -+ int iov_alloc_cnt; -+ int iov_cnt; -+ int iov_idx; - - /* Next cmd hdr in compound req buf*/ - int next_smb2_rcv_hdr_off; - /* Next cmd hdr in compound rsp buf*/ - int next_smb2_rsp_hdr_off; -+ /* Current cmd hdr in compound rsp buf*/ -+ int curr_smb2_rsp_hdr_off; - - /* - * Current Local FID assigned compound response if SMB2 CREATE -@@ -53,22 +64,17 @@ struct ksmbd_work { - unsigned int credits_granted; - - /* response smb header size */ -- unsigned int resp_hdr_sz; - unsigned int response_sz; -- /* Read data count */ -- unsigned int aux_payload_sz; - - void *tr_buf; - - unsigned char state; -- /* Multiple responses for one request e.g. SMB ECHO */ -- bool multiRsp:1; - /* No response for cancelled request */ - bool send_no_response:1; - /* Request is encrypted */ - bool encrypted:1; - /* Is this SYNC or ASYNC ksmbd_work */ -- bool syncronous:1; -+ bool asynchronous:1; - bool need_invalidate_rkey:1; - - unsigned int remote_key; -@@ -95,6 +101,15 @@ static inline void *ksmbd_resp_buf_next(struct ksmbd_work *work) - return work->response_buf + work->next_smb2_rsp_hdr_off + 4; - } - -+/** -+ * ksmbd_resp_buf_curr - Get current buffer on compound response. -+ * @work: smb work containing response buffer -+ */ -+static inline void *ksmbd_resp_buf_curr(struct ksmbd_work *work) -+{ -+ return work->response_buf + work->curr_smb2_rsp_hdr_off + 4; -+} -+ - /** - * ksmbd_req_buf_next - Get next buffer on compound request. - * @work: smb work containing response buffer -@@ -113,5 +128,8 @@ int ksmbd_work_pool_init(void); - int ksmbd_workqueue_init(void); - void ksmbd_workqueue_destroy(void); - bool ksmbd_queue_work(struct ksmbd_work *work); -- -+int ksmbd_iov_pin_rsp_read(struct ksmbd_work *work, void *ib, int len, -+ void *aux_buf, unsigned int aux_size); -+int ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len); -+int allocate_interim_rsp_buf(struct ksmbd_work *work); - #endif /* __KSMBD_WORK_H__ */ -diff --git a/fs/smb/server/mgmt/share_config.h b/fs/smb/server/mgmt/share_config.h -index 3fd3382939421..5f591751b9236 100644 ---- a/fs/smb/server/mgmt/share_config.h -+++ b/fs/smb/server/mgmt/share_config.h -@@ -34,29 +34,22 @@ struct ksmbd_share_config { - #define KSMBD_SHARE_INVALID_UID ((__u16)-1) - #define KSMBD_SHARE_INVALID_GID ((__u16)-1) - --static inline int share_config_create_mode(struct ksmbd_share_config *share, -- umode_t posix_mode) -+static inline umode_t -+share_config_create_mode(struct ksmbd_share_config *share, -+ umode_t posix_mode) - { -- if (!share->force_create_mode) { -- if (!posix_mode) -- return share->create_mask; -- else -- return posix_mode & share->create_mask; -- } -- return share->force_create_mode & share->create_mask; -+ umode_t mode = (posix_mode ?: (umode_t)-1) & share->create_mask; -+ -+ return mode | share->force_create_mode; - } - --static inline int share_config_directory_mode(struct ksmbd_share_config *share, -- umode_t posix_mode) -+static inline umode_t -+share_config_directory_mode(struct ksmbd_share_config *share, -+ umode_t posix_mode) - { -- if (!share->force_directory_mode) { -- if (!posix_mode) -- return share->directory_mask; -- else -- return posix_mode & share->directory_mask; -- } -+ umode_t mode = (posix_mode ?: (umode_t)-1) & share->directory_mask; - -- return share->force_directory_mode & share->directory_mask; -+ return mode | share->force_directory_mode; - } - - static inline int test_share_config_flag(struct ksmbd_share_config *share, -diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c -index f07a05f376513..d2c81a8a11dda 100644 ---- a/fs/smb/server/mgmt/tree_connect.c -+++ b/fs/smb/server/mgmt/tree_connect.c -@@ -73,7 +73,10 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, - - tree_conn->user = sess->user; - tree_conn->share_conf = sc; -+ tree_conn->t_state = TREE_NEW; - status.tree_conn = tree_conn; -+ atomic_set(&tree_conn->refcount, 1); -+ init_waitqueue_head(&tree_conn->refcount_q); - - ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, - GFP_KERNEL)); -@@ -93,14 +96,33 @@ out_error: - return status; - } - -+void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) -+{ -+ /* -+ * Checking waitqueue to releasing tree connect on -+ * tree disconnect. waitqueue_active is safe because it -+ * uses atomic operation for condition. -+ */ -+ if (!atomic_dec_return(&tcon->refcount) && -+ waitqueue_active(&tcon->refcount_q)) -+ wake_up(&tcon->refcount_q); -+} -+ - int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, - struct ksmbd_tree_connect *tree_conn) - { - int ret; - -+ write_lock(&sess->tree_conns_lock); -+ xa_erase(&sess->tree_conns, tree_conn->id); -+ write_unlock(&sess->tree_conns_lock); -+ -+ if (!atomic_dec_and_test(&tree_conn->refcount)) -+ wait_event(tree_conn->refcount_q, -+ atomic_read(&tree_conn->refcount) == 0); -+ - ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); - ksmbd_release_tree_conn_id(sess, tree_conn->id); -- xa_erase(&sess->tree_conns, tree_conn->id); - ksmbd_share_config_put(tree_conn->share_conf); - kfree(tree_conn); - return ret; -@@ -111,26 +133,19 @@ struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess, - { - struct ksmbd_tree_connect *tcon; - -+ read_lock(&sess->tree_conns_lock); - tcon = xa_load(&sess->tree_conns, id); - if (tcon) { -- if (test_bit(TREE_CONN_EXPIRE, &tcon->status)) -+ if (tcon->t_state != TREE_CONNECTED) -+ tcon = NULL; -+ else if (!atomic_inc_not_zero(&tcon->refcount)) - tcon = NULL; - } -+ read_unlock(&sess->tree_conns_lock); - - return tcon; - } - --struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess, -- unsigned int id) --{ -- struct ksmbd_tree_connect *tc; -- -- tc = ksmbd_tree_conn_lookup(sess, id); -- if (tc) -- return tc->share_conf; -- return NULL; --} -- - int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess) - { - int ret = 0; -@@ -140,8 +155,18 @@ int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess) - if (!sess) - return -EINVAL; - -- xa_for_each(&sess->tree_conns, id, tc) -+ xa_for_each(&sess->tree_conns, id, tc) { -+ write_lock(&sess->tree_conns_lock); -+ if (tc->t_state == TREE_DISCONNECTED) { -+ write_unlock(&sess->tree_conns_lock); -+ ret = -ENOENT; -+ continue; -+ } -+ tc->t_state = TREE_DISCONNECTED; -+ write_unlock(&sess->tree_conns_lock); -+ - ret |= ksmbd_tree_conn_disconnect(sess, tc); -+ } - xa_destroy(&sess->tree_conns); - return ret; - } -diff --git a/fs/smb/server/mgmt/tree_connect.h b/fs/smb/server/mgmt/tree_connect.h -index 700df36cf3e30..6377a70b811c8 100644 ---- a/fs/smb/server/mgmt/tree_connect.h -+++ b/fs/smb/server/mgmt/tree_connect.h -@@ -14,7 +14,11 @@ struct ksmbd_share_config; - struct ksmbd_user; - struct ksmbd_conn; - --#define TREE_CONN_EXPIRE 1 -+enum { -+ TREE_NEW = 0, -+ TREE_CONNECTED, -+ TREE_DISCONNECTED -+}; - - struct ksmbd_tree_connect { - int id; -@@ -27,7 +31,9 @@ struct ksmbd_tree_connect { - - int maximal_access; - bool posix_extensions; -- unsigned long status; -+ atomic_t refcount; -+ wait_queue_head_t refcount_q; -+ unsigned int t_state; - }; - - struct ksmbd_tree_conn_status { -@@ -46,6 +52,7 @@ struct ksmbd_session; - struct ksmbd_tree_conn_status - ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess, - const char *share_name); -+void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon); - - int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, - struct ksmbd_tree_connect *tree_conn); -@@ -53,9 +60,6 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, - struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess, - unsigned int id); - --struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess, -- unsigned int id); -- - int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess); - - #endif /* __TREE_CONNECT_MANAGEMENT_H__ */ -diff --git a/fs/smb/server/mgmt/user_config.h b/fs/smb/server/mgmt/user_config.h -index 6a44109617f14..e068a19fd9049 100644 ---- a/fs/smb/server/mgmt/user_config.h -+++ b/fs/smb/server/mgmt/user_config.h -@@ -18,7 +18,6 @@ struct ksmbd_user { - - size_t passkey_sz; - char *passkey; -- unsigned int failed_login_count; - }; - - static inline bool user_guest(struct ksmbd_user *user) -diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c -index cf6621e21ba36..15f68ee050894 100644 ---- a/fs/smb/server/mgmt/user_session.c -+++ b/fs/smb/server/mgmt/user_session.c -@@ -25,7 +25,6 @@ static DECLARE_RWSEM(sessions_table_lock); - struct ksmbd_session_rpc { - int id; - unsigned int method; -- struct list_head list; - }; - - static void free_channel_list(struct ksmbd_session *sess) -@@ -58,15 +57,14 @@ static void __session_rpc_close(struct ksmbd_session *sess, - static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess) - { - struct ksmbd_session_rpc *entry; -+ long index; - -- while (!list_empty(&sess->rpc_handle_list)) { -- entry = list_entry(sess->rpc_handle_list.next, -- struct ksmbd_session_rpc, -- list); -- -- list_del(&entry->list); -+ xa_for_each(&sess->rpc_handle_list, index, entry) { -+ xa_erase(&sess->rpc_handle_list, index); - __session_rpc_close(sess, entry); - } -+ -+ xa_destroy(&sess->rpc_handle_list); - } - - static int __rpc_method(char *rpc_name) -@@ -102,13 +100,13 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) - - entry = kzalloc(sizeof(struct ksmbd_session_rpc), GFP_KERNEL); - if (!entry) -- return -EINVAL; -+ return -ENOMEM; - -- list_add(&entry->list, &sess->rpc_handle_list); - entry->method = method; - entry->id = ksmbd_ipc_id_alloc(); - if (entry->id < 0) - goto free_entry; -+ xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL); - - resp = ksmbd_rpc_open(sess, entry->id); - if (!resp) -@@ -117,9 +115,9 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) - kvfree(resp); - return entry->id; - free_id: -+ xa_erase(&sess->rpc_handle_list, entry->id); - ksmbd_rpc_id_free(entry->id); - free_entry: -- list_del(&entry->list); - kfree(entry); - return -EINVAL; - } -@@ -128,24 +126,17 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id) - { - struct ksmbd_session_rpc *entry; - -- list_for_each_entry(entry, &sess->rpc_handle_list, list) { -- if (entry->id == id) { -- list_del(&entry->list); -- __session_rpc_close(sess, entry); -- break; -- } -- } -+ entry = xa_erase(&sess->rpc_handle_list, id); -+ if (entry) -+ __session_rpc_close(sess, entry); - } - - int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) - { - struct ksmbd_session_rpc *entry; - -- list_for_each_entry(entry, &sess->rpc_handle_list, list) { -- if (entry->id == id) -- return entry->method; -- } -- return 0; -+ entry = xa_load(&sess->rpc_handle_list, id); -+ return entry ? entry->method : 0; - } - - void ksmbd_session_destroy(struct ksmbd_session *sess) -@@ -362,8 +353,9 @@ static struct ksmbd_session *__session_create(int protocol) - set_session_flag(sess, protocol); - xa_init(&sess->tree_conns); - xa_init(&sess->ksmbd_chann_list); -- INIT_LIST_HEAD(&sess->rpc_handle_list); -+ xa_init(&sess->rpc_handle_list); - sess->sequence_number = 1; -+ rwlock_init(&sess->tree_conns_lock); - - ret = __init_smb2_session(sess); - if (ret) -diff --git a/fs/smb/server/mgmt/user_session.h b/fs/smb/server/mgmt/user_session.h -index 51f38e5b61abb..63cb08fffde84 100644 ---- a/fs/smb/server/mgmt/user_session.h -+++ b/fs/smb/server/mgmt/user_session.h -@@ -52,7 +52,7 @@ struct ksmbd_session { - struct xarray ksmbd_chann_list; - struct xarray tree_conns; - struct ida tree_conn_ida; -- struct list_head rpc_handle_list; -+ struct xarray rpc_handle_list; - - __u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE]; - __u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE]; -@@ -60,6 +60,7 @@ struct ksmbd_session { - - struct ksmbd_file_table file_table; - unsigned long last_active; -+ rwlock_t tree_conns_lock; - }; - - static inline int test_session_flag(struct ksmbd_session *sess, int bit) -diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c -index c81aee9ce7ec4..af0f6914eca45 100644 ---- a/fs/smb/server/oplock.c -+++ b/fs/smb/server/oplock.c -@@ -102,9 +102,10 @@ static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx) - lease->new_state = 0; - lease->flags = lctx->flags; - lease->duration = lctx->duration; -+ lease->is_dir = lctx->is_dir; - memcpy(lease->parent_lease_key, lctx->parent_lease_key, SMB2_LEASE_KEY_SIZE); - lease->version = lctx->version; -- lease->epoch = 0; -+ lease->epoch = le16_to_cpu(lctx->epoch); - INIT_LIST_HEAD(&opinfo->lease_entry); - opinfo->o_lease = lease; - -@@ -395,8 +396,8 @@ void close_id_del_oplock(struct ksmbd_file *fp) - { - struct oplock_info *opinfo; - -- if (S_ISDIR(file_inode(fp->filp)->i_mode)) -- return; -+ if (fp->reserve_lease_break) -+ smb_lazy_parent_lease_break_close(fp); - - opinfo = opinfo_get(fp); - if (!opinfo) -@@ -543,12 +544,13 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci, - /* upgrading lease */ - if ((atomic_read(&ci->op_count) + - atomic_read(&ci->sop_count)) == 1) { -- if (lease->state == -- (lctx->req_state & lease->state)) { -+ if (lease->state != SMB2_LEASE_NONE_LE && -+ lease->state == (lctx->req_state & lease->state)) { - lease->state |= lctx->req_state; - if (lctx->req_state & - SMB2_LEASE_WRITE_CACHING_LE) - lease_read_to_write(opinfo); -+ - } - } else if ((atomic_read(&ci->op_count) + - atomic_read(&ci->sop_count)) > 1) { -@@ -616,15 +618,6 @@ static int oplock_break_pending(struct oplock_info *opinfo, int req_op_level) - return 0; - } - --static inline int allocate_oplock_break_buf(struct ksmbd_work *work) --{ -- work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, GFP_KERNEL); -- if (!work->response_buf) -- return -ENOMEM; -- work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; -- return 0; --} -- - /** - * __smb2_oplock_break_noti() - send smb2 oplock break cmd from conn - * to client -@@ -639,7 +632,6 @@ static void __smb2_oplock_break_noti(struct work_struct *wk) - { - struct smb2_oplock_break *rsp = NULL; - struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work); -- struct ksmbd_conn *conn = work->conn; - struct oplock_break_info *br_info = work->request_buf; - struct smb2_hdr *rsp_hdr; - struct ksmbd_file *fp; -@@ -648,7 +640,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk) - if (!fp) - goto out; - -- if (allocate_oplock_break_buf(work)) { -+ if (allocate_interim_rsp_buf(work)) { - pr_err("smb2_allocate_rsp_buf failed! "); - ksmbd_fd_put(work, fp); - goto out; -@@ -656,8 +648,6 @@ static void __smb2_oplock_break_noti(struct work_struct *wk) - - rsp_hdr = smb2_get_msg(work->response_buf); - memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); -- *(__be32 *)work->response_buf = -- cpu_to_be32(conn->vals->header_size); - rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; - rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; - rsp_hdr->CreditRequest = cpu_to_le16(0); -@@ -684,13 +674,15 @@ static void __smb2_oplock_break_noti(struct work_struct *wk) - rsp->PersistentFid = fp->persistent_id; - rsp->VolatileFid = fp->volatile_id; - -- inc_rfc1001_len(work->response_buf, 24); -+ ksmbd_fd_put(work, fp); -+ if (ksmbd_iov_pin_rsp(work, (void *)rsp, -+ sizeof(struct smb2_oplock_break))) -+ goto out; - - ksmbd_debug(OPLOCK, - "sending oplock break v_id %llu p_id = %llu lock level = %d\n", - rsp->VolatileFid, rsp->PersistentFid, rsp->OplockLevel); - -- ksmbd_fd_put(work, fp); - ksmbd_conn_write(work); - - out: -@@ -751,18 +743,15 @@ static void __smb2_lease_break_noti(struct work_struct *wk) - struct smb2_lease_break *rsp = NULL; - struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work); - struct lease_break_info *br_info = work->request_buf; -- struct ksmbd_conn *conn = work->conn; - struct smb2_hdr *rsp_hdr; - -- if (allocate_oplock_break_buf(work)) { -+ if (allocate_interim_rsp_buf(work)) { - ksmbd_debug(OPLOCK, "smb2_allocate_rsp_buf failed! "); - goto out; - } - - rsp_hdr = smb2_get_msg(work->response_buf); - memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); -- *(__be32 *)work->response_buf = -- cpu_to_be32(conn->vals->header_size); - rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; - rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; - rsp_hdr->CreditRequest = cpu_to_le16(0); -@@ -791,7 +780,9 @@ static void __smb2_lease_break_noti(struct work_struct *wk) - rsp->AccessMaskHint = 0; - rsp->ShareMaskHint = 0; - -- inc_rfc1001_len(work->response_buf, 44); -+ if (ksmbd_iov_pin_rsp(work, (void *)rsp, -+ sizeof(struct smb2_lease_break))) -+ goto out; - - ksmbd_conn_write(work); - -@@ -844,7 +835,8 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo) - interim_entry); - setup_async_work(in_work, NULL, NULL); - smb2_send_interim_resp(in_work, STATUS_PENDING); -- list_del(&in_work->interim_entry); -+ list_del_init(&in_work->interim_entry); -+ release_async_work(in_work); - } - INIT_WORK(&work->work, __smb2_lease_break_noti); - ksmbd_queue_work(work); -@@ -910,7 +902,8 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level) - lease->new_state = - SMB2_LEASE_READ_CACHING_LE; - } else { -- if (lease->state & SMB2_LEASE_HANDLE_CACHING_LE) -+ if (lease->state & SMB2_LEASE_HANDLE_CACHING_LE && -+ !lease->is_dir) - lease->new_state = - SMB2_LEASE_READ_CACHING_LE; - else -@@ -1042,6 +1035,7 @@ static void copy_lease(struct oplock_info *op1, struct oplock_info *op2) - SMB2_LEASE_KEY_SIZE); - lease2->duration = lease1->duration; - lease2->flags = lease1->flags; -+ lease2->epoch = lease1->epoch++; - } - - static int add_lease_global_list(struct oplock_info *opinfo) -@@ -1091,6 +1085,89 @@ static void set_oplock_level(struct oplock_info *opinfo, int level, - } - } - -+void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, -+ struct lease_ctx_info *lctx) -+{ -+ struct oplock_info *opinfo; -+ struct ksmbd_inode *p_ci = NULL; -+ -+ if (lctx->version != 2) -+ return; -+ -+ p_ci = ksmbd_inode_lookup_lock(fp->filp->f_path.dentry->d_parent); -+ if (!p_ci) -+ return; -+ -+ read_lock(&p_ci->m_lock); -+ list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { -+ if (!opinfo->is_lease) -+ continue; -+ -+ if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE && -+ (!(lctx->flags & SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE) || -+ !compare_guid_key(opinfo, fp->conn->ClientGUID, -+ lctx->parent_lease_key))) { -+ if (!atomic_inc_not_zero(&opinfo->refcount)) -+ continue; -+ -+ atomic_inc(&opinfo->conn->r_count); -+ if (ksmbd_conn_releasing(opinfo->conn)) { -+ atomic_dec(&opinfo->conn->r_count); -+ continue; -+ } -+ -+ read_unlock(&p_ci->m_lock); -+ oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE); -+ opinfo_conn_put(opinfo); -+ read_lock(&p_ci->m_lock); -+ } -+ } -+ read_unlock(&p_ci->m_lock); -+ -+ ksmbd_inode_put(p_ci); -+} -+ -+void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp) -+{ -+ struct oplock_info *opinfo; -+ struct ksmbd_inode *p_ci = NULL; -+ -+ rcu_read_lock(); -+ opinfo = rcu_dereference(fp->f_opinfo); -+ rcu_read_unlock(); -+ -+ if (!opinfo->is_lease || opinfo->o_lease->version != 2) -+ return; -+ -+ p_ci = ksmbd_inode_lookup_lock(fp->filp->f_path.dentry->d_parent); -+ if (!p_ci) -+ return; -+ -+ read_lock(&p_ci->m_lock); -+ list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { -+ if (!opinfo->is_lease) -+ continue; -+ -+ if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE) { -+ if (!atomic_inc_not_zero(&opinfo->refcount)) -+ continue; -+ -+ atomic_inc(&opinfo->conn->r_count); -+ if (ksmbd_conn_releasing(opinfo->conn)) { -+ atomic_dec(&opinfo->conn->r_count); -+ continue; -+ } -+ read_unlock(&p_ci->m_lock); -+ oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE); -+ opinfo_conn_put(opinfo); -+ read_lock(&p_ci->m_lock); -+ } -+ } -+ read_unlock(&p_ci->m_lock); -+ -+ ksmbd_inode_put(p_ci); -+} -+ - /** - * smb_grant_oplock() - handle oplock/lease request on file open - * @work: smb work -@@ -1114,10 +1191,6 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, - bool prev_op_has_lease; - __le32 prev_op_state = 0; - -- /* not support directory lease */ -- if (S_ISDIR(file_inode(fp->filp)->i_mode)) -- return 0; -- - opinfo = alloc_opinfo(work, pid, tid); - if (!opinfo) - return -ENOMEM; -@@ -1374,6 +1447,7 @@ void create_lease_buf(u8 *rbuf, struct lease *lease) - memcpy(buf->lcontext.LeaseKey, lease->lease_key, - SMB2_LEASE_KEY_SIZE); - buf->lcontext.LeaseFlags = lease->flags; -+ buf->lcontext.Epoch = cpu_to_le16(++lease->epoch); - buf->lcontext.LeaseState = lease->state; - memcpy(buf->lcontext.ParentLeaseKey, lease->parent_lease_key, - SMB2_LEASE_KEY_SIZE); -@@ -1410,10 +1484,11 @@ void create_lease_buf(u8 *rbuf, struct lease *lease) - /** - * parse_lease_state() - parse lease context containted in file open request - * @open_req: buffer containing smb2 file open(create) request -+ * @is_dir: whether leasing file is directory - * - * Return: oplock state, -ENOENT if create lease context not found - */ --struct lease_ctx_info *parse_lease_state(void *open_req) -+struct lease_ctx_info *parse_lease_state(void *open_req, bool is_dir) - { - struct create_context *cc; - struct smb2_create_req *req = (struct smb2_create_req *)open_req; -@@ -1431,8 +1506,14 @@ struct lease_ctx_info *parse_lease_state(void *open_req) - struct create_lease_v2 *lc = (struct create_lease_v2 *)cc; - - memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); -- lreq->req_state = lc->lcontext.LeaseState; -+ if (is_dir) { -+ lreq->req_state = lc->lcontext.LeaseState & -+ ~SMB2_LEASE_WRITE_CACHING_LE; -+ lreq->is_dir = true; -+ } else -+ lreq->req_state = lc->lcontext.LeaseState; - lreq->flags = lc->lcontext.LeaseFlags; -+ lreq->epoch = lc->lcontext.Epoch; - lreq->duration = lc->lcontext.LeaseDuration; - memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey, - SMB2_LEASE_KEY_SIZE); -diff --git a/fs/smb/server/oplock.h b/fs/smb/server/oplock.h -index 4b0fe6da76940..5b93ea9196c01 100644 ---- a/fs/smb/server/oplock.h -+++ b/fs/smb/server/oplock.h -@@ -34,7 +34,9 @@ struct lease_ctx_info { - __le32 flags; - __le64 duration; - __u8 parent_lease_key[SMB2_LEASE_KEY_SIZE]; -+ __le16 epoch; - int version; -+ bool is_dir; - }; - - struct lease_table { -@@ -53,6 +55,7 @@ struct lease { - __u8 parent_lease_key[SMB2_LEASE_KEY_SIZE]; - int version; - unsigned short epoch; -+ bool is_dir; - struct lease_table *l_lb; - }; - -@@ -108,7 +111,7 @@ void opinfo_put(struct oplock_info *opinfo); - - /* Lease related functions */ - void create_lease_buf(u8 *rbuf, struct lease *lease); --struct lease_ctx_info *parse_lease_state(void *open_req); -+struct lease_ctx_info *parse_lease_state(void *open_req, bool is_dir); - __u8 smb2_map_lease_to_oplock(__le32 lease_state); - int lease_read_to_write(struct oplock_info *opinfo); - -@@ -124,4 +127,7 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn, - int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci, - struct lease_ctx_info *lctx); - void destroy_lease_table(struct ksmbd_conn *conn); -+void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, -+ struct lease_ctx_info *lctx); -+void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp); - #endif /* __KSMBD_OPLOCK_H */ -diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c -index 9804cabe72a84..11b201e6ee44b 100644 ---- a/fs/smb/server/server.c -+++ b/fs/smb/server/server.c -@@ -115,8 +115,10 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, - if (check_conn_state(work)) - return SERVER_HANDLER_CONTINUE; - -- if (ksmbd_verify_smb_message(work)) -+ if (ksmbd_verify_smb_message(work)) { -+ conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); - return SERVER_HANDLER_ABORT; -+ } - - command = conn->ops->get_cmd_val(work); - *cmd = command; -@@ -163,6 +165,7 @@ static void __handle_ksmbd_work(struct ksmbd_work *work, - { - u16 command = 0; - int rc; -+ bool is_chained = false; - - if (conn->ops->allocate_rsp_buf(work)) - return; -@@ -229,16 +232,17 @@ static void __handle_ksmbd_work(struct ksmbd_work *work, - } - } - -+ is_chained = is_chained_smb2_message(work); -+ - if (work->sess && - (work->sess->sign || smb3_11_final_sess_setup_resp(work) || - conn->ops->is_sign_req(work, command))) - conn->ops->set_sign_rsp(work); -- } while (is_chained_smb2_message(work)); -- -- if (work->send_no_response) -- return; -+ } while (is_chained == true); - - send: -+ if (work->tcon) -+ ksmbd_tree_connect_put(work->tcon); - smb3_preauth_hash_rsp(work); - if (work->sess && work->sess->enc && work->encrypted && - conn->ops->encrypt_resp) { -@@ -442,11 +446,9 @@ static ssize_t stats_show(struct class *class, struct class_attribute *attr, - "reset", - "shutdown" - }; -- -- ssize_t sz = scnprintf(buf, PAGE_SIZE, "%d %s %d %lu\n", stats_version, -- state[server_conf.state], server_conf.tcp_port, -- server_conf.ipc_last_active / HZ); -- return sz; -+ return sysfs_emit(buf, "%d %s %d %lu\n", stats_version, -+ state[server_conf.state], server_conf.tcp_port, -+ server_conf.ipc_last_active / HZ); - } - - static ssize_t kill_server_store(struct class *class, -@@ -478,19 +480,13 @@ static ssize_t debug_show(struct class *class, struct class_attribute *attr, - - for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) { - if ((ksmbd_debug_types >> i) & 1) { -- pos = scnprintf(buf + sz, -- PAGE_SIZE - sz, -- "[%s] ", -- debug_type_strings[i]); -+ pos = sysfs_emit_at(buf, sz, "[%s] ", debug_type_strings[i]); - } else { -- pos = scnprintf(buf + sz, -- PAGE_SIZE - sz, -- "%s ", -- debug_type_strings[i]); -+ pos = sysfs_emit_at(buf, sz, "%s ", debug_type_strings[i]); - } - sz += pos; - } -- sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n"); -+ sz += sysfs_emit_at(buf, sz, "\n"); - return sz; - } - -@@ -599,8 +595,6 @@ static int __init ksmbd_server_init(void) - if (ret) - goto err_crypto_destroy; - -- pr_warn_once("The ksmbd server is experimental\n"); -- - return 0; - - err_crypto_destroy: -diff --git a/fs/smb/server/smb2misc.c b/fs/smb/server/smb2misc.c -index e881df1d10cbd..03dded29a9804 100644 ---- a/fs/smb/server/smb2misc.c -+++ b/fs/smb/server/smb2misc.c -@@ -106,16 +106,25 @@ static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, - break; - case SMB2_CREATE: - { -+ unsigned short int name_off = -+ le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset); -+ unsigned short int name_len = -+ le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength); -+ - if (((struct smb2_create_req *)hdr)->CreateContextsLength) { - *off = le32_to_cpu(((struct smb2_create_req *) - hdr)->CreateContextsOffset); - *len = le32_to_cpu(((struct smb2_create_req *) - hdr)->CreateContextsLength); -- break; -+ if (!name_len) -+ break; -+ -+ if (name_off + name_len < (u64)*off + *len) -+ break; - } - -- *off = le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset); -- *len = le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength); -+ *off = name_off; -+ *len = name_len; - break; - } - case SMB2_QUERY_INFO: -@@ -440,10 +449,8 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) - - validate_credit: - if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) && -- smb2_validate_credit_charge(work->conn, hdr)) { -- work->conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); -+ smb2_validate_credit_charge(work->conn, hdr)) - return 1; -- } - - return 0; - } -diff --git a/fs/smb/server/smb2ops.c b/fs/smb/server/smb2ops.c -index ab23da2120b94..535402629655e 100644 ---- a/fs/smb/server/smb2ops.c -+++ b/fs/smb/server/smb2ops.c -@@ -221,7 +221,8 @@ void init_smb3_0_server(struct ksmbd_conn *conn) - conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE; - - if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) -- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; -+ conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING | -+ SMB2_GLOBAL_CAP_DIRECTORY_LEASING; - - if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION && - conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION) -@@ -245,10 +246,12 @@ void init_smb3_02_server(struct ksmbd_conn *conn) - conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE; - - if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) -- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; -+ conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING | -+ SMB2_GLOBAL_CAP_DIRECTORY_LEASING; - -- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION && -- conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION) -+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION || -+ (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) && -+ conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)) - conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION; - - if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) -@@ -269,7 +272,13 @@ int init_smb3_11_server(struct ksmbd_conn *conn) - conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE; - - if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) -- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; -+ conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING | -+ SMB2_GLOBAL_CAP_DIRECTORY_LEASING; -+ -+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION || -+ (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) && -+ conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)) -+ conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION; - - if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) - conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index 1598ad6155fef..ea48dd06d4da3 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -144,12 +144,18 @@ void smb2_set_err_rsp(struct ksmbd_work *work) - err_rsp = smb2_get_msg(work->response_buf); - - if (err_rsp->hdr.Status != STATUS_STOPPED_ON_SYMLINK) { -+ int err; -+ - err_rsp->StructureSize = SMB2_ERROR_STRUCTURE_SIZE2_LE; - err_rsp->ErrorContextCount = 0; - err_rsp->Reserved = 0; - err_rsp->ByteCount = 0; - err_rsp->ErrorData[0] = 0; -- inc_rfc1001_len(work->response_buf, SMB2_ERROR_STRUCTURE_SIZE2); -+ err = ksmbd_iov_pin_rsp(work, (void *)err_rsp, -+ __SMB2_HEADER_STRUCTURE_SIZE + -+ SMB2_ERROR_STRUCTURE_SIZE2); -+ if (err) -+ work->send_no_response = 1; - } - } - -@@ -224,11 +230,12 @@ void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err) - { - struct smb2_hdr *rsp_hdr; - -- if (work->next_smb2_rcv_hdr_off) -- rsp_hdr = ksmbd_resp_buf_next(work); -- else -- rsp_hdr = smb2_get_msg(work->response_buf); -+ rsp_hdr = smb2_get_msg(work->response_buf); - rsp_hdr->Status = err; -+ -+ work->iov_idx = 0; -+ work->iov_cnt = 0; -+ work->next_smb2_rcv_hdr_off = 0; - smb2_set_err_rsp(work); - } - -@@ -244,9 +251,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work) - struct smb2_hdr *rsp_hdr; - struct smb2_negotiate_rsp *rsp; - struct ksmbd_conn *conn = work->conn; -- -- *(__be32 *)work->response_buf = -- cpu_to_be32(conn->vals->header_size); -+ int err; - - rsp_hdr = smb2_get_msg(work->response_buf); - memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); -@@ -285,13 +290,14 @@ int init_smb2_neg_rsp(struct ksmbd_work *work) - rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH); - ksmbd_copy_gss_neg_header((char *)(&rsp->hdr) + - le16_to_cpu(rsp->SecurityBufferOffset)); -- inc_rfc1001_len(work->response_buf, -- sizeof(struct smb2_negotiate_rsp) - -- sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) + -- AUTH_GSS_LENGTH); - rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE; - if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY) - rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE; -+ err = ksmbd_iov_pin_rsp(work, rsp, -+ sizeof(struct smb2_negotiate_rsp) - -+ sizeof(rsp->Buffer) + AUTH_GSS_LENGTH); -+ if (err) -+ return err; - conn->use_spnego = true; - - ksmbd_conn_set_need_negotiate(conn); -@@ -390,11 +396,12 @@ static void init_chained_smb2_rsp(struct ksmbd_work *work) - next_hdr_offset = le32_to_cpu(req->NextCommand); - - new_len = ALIGN(len, 8); -- inc_rfc1001_len(work->response_buf, -- sizeof(struct smb2_hdr) + new_len - len); -+ work->iov[work->iov_idx].iov_len += (new_len - len); -+ inc_rfc1001_len(work->response_buf, new_len - len); - rsp->NextCommand = cpu_to_le32(new_len); - - work->next_smb2_rcv_hdr_off += next_hdr_offset; -+ work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off; - work->next_smb2_rsp_hdr_off += new_len; - ksmbd_debug(SMB, - "Compound req new_len = %d rcv off = %d rsp off = %d\n", -@@ -470,10 +477,10 @@ bool is_chained_smb2_message(struct ksmbd_work *work) - len = len - get_rfc1002_len(work->response_buf); - if (len) { - ksmbd_debug(SMB, "padding len %u\n", len); -+ work->iov[work->iov_idx].iov_len += len; - inc_rfc1001_len(work->response_buf, len); -- if (work->aux_payload_sz) -- work->aux_payload_sz += len; - } -+ work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off; - } - return false; - } -@@ -488,11 +495,8 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work) - { - struct smb2_hdr *rsp_hdr = smb2_get_msg(work->response_buf); - struct smb2_hdr *rcv_hdr = smb2_get_msg(work->request_buf); -- struct ksmbd_conn *conn = work->conn; - - memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); -- *(__be32 *)work->response_buf = -- cpu_to_be32(conn->vals->header_size); - rsp_hdr->ProtocolId = rcv_hdr->ProtocolId; - rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; - rsp_hdr->Command = rcv_hdr->Command; -@@ -508,12 +512,6 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work) - rsp_hdr->SessionId = rcv_hdr->SessionId; - memcpy(rsp_hdr->Signature, rcv_hdr->Signature, 16); - -- work->syncronous = true; -- if (work->async_id) { -- ksmbd_release_id(&conn->async_ida, work->async_id); -- work->async_id = 0; -- } -- - return 0; - } - -@@ -549,7 +547,7 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work) - if (le32_to_cpu(hdr->NextCommand) > 0) - sz = large_sz; - -- work->response_buf = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO); -+ work->response_buf = kvzalloc(sz, GFP_KERNEL); - if (!work->response_buf) - return -ENOMEM; - -@@ -659,21 +657,16 @@ smb2_get_name(const char *src, const int maxlen, struct nls_table *local_nls) - - int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg) - { -- struct smb2_hdr *rsp_hdr; - struct ksmbd_conn *conn = work->conn; - int id; - -- rsp_hdr = smb2_get_msg(work->response_buf); -- rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND; -- - id = ksmbd_acquire_async_msg_id(&conn->async_ida); - if (id < 0) { - pr_err("Failed to alloc async message id\n"); - return id; - } -- work->syncronous = false; -+ work->asynchronous = true; - work->async_id = id; -- rsp_hdr->Id.AsyncId = cpu_to_le64(id); - - ksmbd_debug(SMB, - "Send interim Response to inform async request id : %d\n", -@@ -691,18 +684,47 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg) - return 0; - } - -+void release_async_work(struct ksmbd_work *work) -+{ -+ struct ksmbd_conn *conn = work->conn; -+ -+ spin_lock(&conn->request_lock); -+ list_del_init(&work->async_request_entry); -+ spin_unlock(&conn->request_lock); -+ -+ work->asynchronous = 0; -+ work->cancel_fn = NULL; -+ kfree(work->cancel_argv); -+ work->cancel_argv = NULL; -+ if (work->async_id) { -+ ksmbd_release_id(&conn->async_ida, work->async_id); -+ work->async_id = 0; -+ } -+} -+ - void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status) - { - struct smb2_hdr *rsp_hdr; -+ struct ksmbd_work *in_work = ksmbd_alloc_work_struct(); - -- rsp_hdr = smb2_get_msg(work->response_buf); -- smb2_set_err_rsp(work); -+ if (allocate_interim_rsp_buf(in_work)) { -+ pr_err("smb_allocate_rsp_buf failed!\n"); -+ ksmbd_free_work_struct(in_work); -+ return; -+ } -+ -+ in_work->conn = work->conn; -+ memcpy(smb2_get_msg(in_work->response_buf), ksmbd_resp_buf_next(work), -+ __SMB2_HEADER_STRUCTURE_SIZE); -+ -+ rsp_hdr = smb2_get_msg(in_work->response_buf); -+ rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND; -+ rsp_hdr->Id.AsyncId = cpu_to_le64(work->async_id); -+ smb2_set_err_rsp(in_work); - rsp_hdr->Status = status; - -- work->multiRsp = 1; -- ksmbd_conn_write(work); -- rsp_hdr->Status = 0; -- work->multiRsp = 0; -+ ksmbd_conn_write(in_work); -+ ksmbd_free_work_struct(in_work); - } - - static __le32 smb2_get_reparse_tag_special_file(umode_t mode) -@@ -774,19 +796,6 @@ static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt, - pneg_ctxt->Ciphers[0] = cipher_type; - } - --static void build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt, -- __le16 comp_algo) --{ -- pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES; -- pneg_ctxt->DataLength = -- cpu_to_le16(sizeof(struct smb2_compression_capabilities_context) -- - sizeof(struct smb2_neg_context)); -- pneg_ctxt->Reserved = cpu_to_le32(0); -- pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(1); -- pneg_ctxt->Flags = cpu_to_le32(0); -- pneg_ctxt->CompressionAlgorithms[0] = comp_algo; --} -- - static void build_sign_cap_ctxt(struct smb2_signing_capabilities *pneg_ctxt, - __le16 sign_algo) - { -@@ -822,11 +831,10 @@ static void build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt) - pneg_ctxt->Name[15] = 0x7C; - } - --static void assemble_neg_contexts(struct ksmbd_conn *conn, -- struct smb2_negotiate_rsp *rsp, -- void *smb2_buf_len) -+static unsigned int assemble_neg_contexts(struct ksmbd_conn *conn, -+ struct smb2_negotiate_rsp *rsp) - { -- char *pneg_ctxt = (char *)rsp + -+ char * const pneg_ctxt = (char *)rsp + - le32_to_cpu(rsp->NegotiateContextOffset); - int neg_ctxt_cnt = 1; - int ctxt_size; -@@ -835,62 +843,46 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, - "assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n"); - build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt, - conn->preauth_info->Preauth_HashId); -- rsp->NegotiateContextCount = cpu_to_le16(neg_ctxt_cnt); -- inc_rfc1001_len(smb2_buf_len, AUTH_GSS_PADDING); - ctxt_size = sizeof(struct smb2_preauth_neg_context); -- /* Round to 8 byte boundary */ -- pneg_ctxt += round_up(sizeof(struct smb2_preauth_neg_context), 8); - - if (conn->cipher_type) { -+ /* Round to 8 byte boundary */ - ctxt_size = round_up(ctxt_size, 8); - ksmbd_debug(SMB, - "assemble SMB2_ENCRYPTION_CAPABILITIES context\n"); -- build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt, -+ build_encrypt_ctxt((struct smb2_encryption_neg_context *) -+ (pneg_ctxt + ctxt_size), - conn->cipher_type); -- rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); -+ neg_ctxt_cnt++; - ctxt_size += sizeof(struct smb2_encryption_neg_context) + 2; -- /* Round to 8 byte boundary */ -- pneg_ctxt += -- round_up(sizeof(struct smb2_encryption_neg_context) + 2, -- 8); - } - -- if (conn->compress_algorithm) { -- ctxt_size = round_up(ctxt_size, 8); -- ksmbd_debug(SMB, -- "assemble SMB2_COMPRESSION_CAPABILITIES context\n"); -- /* Temporarily set to SMB3_COMPRESS_NONE */ -- build_compression_ctxt((struct smb2_compression_capabilities_context *)pneg_ctxt, -- conn->compress_algorithm); -- rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); -- ctxt_size += sizeof(struct smb2_compression_capabilities_context) + 2; -- /* Round to 8 byte boundary */ -- pneg_ctxt += round_up(sizeof(struct smb2_compression_capabilities_context) + 2, -- 8); -- } -+ /* compression context not yet supported */ -+ WARN_ON(conn->compress_algorithm != SMB3_COMPRESS_NONE); - - if (conn->posix_ext_supported) { - ctxt_size = round_up(ctxt_size, 8); - ksmbd_debug(SMB, - "assemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n"); -- build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); -- rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); -+ build_posix_ctxt((struct smb2_posix_neg_context *) -+ (pneg_ctxt + ctxt_size)); -+ neg_ctxt_cnt++; - ctxt_size += sizeof(struct smb2_posix_neg_context); -- /* Round to 8 byte boundary */ -- pneg_ctxt += round_up(sizeof(struct smb2_posix_neg_context), 8); - } - - if (conn->signing_negotiated) { - ctxt_size = round_up(ctxt_size, 8); - ksmbd_debug(SMB, - "assemble SMB2_SIGNING_CAPABILITIES context\n"); -- build_sign_cap_ctxt((struct smb2_signing_capabilities *)pneg_ctxt, -+ build_sign_cap_ctxt((struct smb2_signing_capabilities *) -+ (pneg_ctxt + ctxt_size), - conn->signing_algorithm); -- rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); -+ neg_ctxt_cnt++; - ctxt_size += sizeof(struct smb2_signing_capabilities) + 2; - } - -- inc_rfc1001_len(smb2_buf_len, ctxt_size); -+ rsp->NegotiateContextCount = cpu_to_le16(neg_ctxt_cnt); -+ return ctxt_size + AUTH_GSS_PADDING; - } - - static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn, -@@ -935,7 +927,7 @@ static void decode_encrypt_ctxt(struct ksmbd_conn *conn, - return; - } - -- if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION)) -+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) - return; - - for (i = 0; i < cph_cnt; i++) { -@@ -1106,7 +1098,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work) - struct smb2_negotiate_req *req = smb2_get_msg(work->request_buf); - struct smb2_negotiate_rsp *rsp = smb2_get_msg(work->response_buf); - int rc = 0; -- unsigned int smb2_buf_len, smb2_neg_size; -+ unsigned int smb2_buf_len, smb2_neg_size, neg_ctxt_len = 0; - __le32 status; - - ksmbd_debug(SMB, "Received negotiate request\n"); -@@ -1199,7 +1191,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work) - conn->preauth_info->Preauth_HashValue); - rsp->NegotiateContextOffset = - cpu_to_le32(OFFSET_OF_NEG_CONTEXT); -- assemble_neg_contexts(conn, rsp, work->response_buf); -+ neg_ctxt_len = assemble_neg_contexts(conn, rsp); - break; - case SMB302_PROT_ID: - init_smb3_02_server(conn); -@@ -1249,9 +1241,6 @@ int smb2_handle_negotiate(struct ksmbd_work *work) - rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH); - ksmbd_copy_gss_neg_header((char *)(&rsp->hdr) + - le16_to_cpu(rsp->SecurityBufferOffset)); -- inc_rfc1001_len(work->response_buf, sizeof(struct smb2_negotiate_rsp) - -- sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) + -- AUTH_GSS_LENGTH); - rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE; - conn->use_spnego = true; - -@@ -1269,9 +1258,16 @@ int smb2_handle_negotiate(struct ksmbd_work *work) - ksmbd_conn_set_need_negotiate(conn); - - err_out: -+ if (rc) -+ rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; -+ -+ if (!rc) -+ rc = ksmbd_iov_pin_rsp(work, rsp, -+ sizeof(struct smb2_negotiate_rsp) - -+ sizeof(rsp->Buffer) + -+ AUTH_GSS_LENGTH + neg_ctxt_len); - if (rc < 0) - smb2_set_err_rsp(work); -- - return rc; - } - -@@ -1471,7 +1467,6 @@ static int ntlm_authenticate(struct ksmbd_work *work, - memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len); - rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len); - kfree(spnego_blob); -- inc_rfc1001_len(work->response_buf, spnego_blob_len - 1); - } - - user = session_user(conn, req); -@@ -1544,7 +1539,8 @@ static int ntlm_authenticate(struct ksmbd_work *work, - return -EINVAL; - } - sess->enc = true; -- rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; -+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION) -+ rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; - /* - * signing is disable if encryption is enable - * on this session -@@ -1616,7 +1612,6 @@ static int krb5_authenticate(struct ksmbd_work *work, - return -EINVAL; - } - rsp->SecurityBufferLength = cpu_to_le16(out_len); -- inc_rfc1001_len(work->response_buf, out_len - 1); - - if ((conn->sign || server_conf.enforced_signing) || - (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) -@@ -1630,7 +1625,8 @@ static int krb5_authenticate(struct ksmbd_work *work, - return -EINVAL; - } - sess->enc = true; -- rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; -+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION) -+ rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; - sess->sign = false; - } - -@@ -1687,7 +1683,6 @@ int smb2_sess_setup(struct ksmbd_work *work) - rsp->SessionFlags = 0; - rsp->SecurityBufferOffset = cpu_to_le16(72); - rsp->SecurityBufferLength = 0; -- inc_rfc1001_len(work->response_buf, 9); - - ksmbd_conn_lock(conn); - if (!req->hdr.SessionId) { -@@ -1823,13 +1818,6 @@ int smb2_sess_setup(struct ksmbd_work *work) - goto out_err; - rsp->hdr.Status = - STATUS_MORE_PROCESSING_REQUIRED; -- /* -- * Note: here total size -1 is done as an -- * adjustment for 0 size blob -- */ -- inc_rfc1001_len(work->response_buf, -- le16_to_cpu(rsp->SecurityBufferLength) - 1); -- - } else if (negblob->MessageType == NtLmAuthenticate) { - rc = ntlm_authenticate(work, req, rsp); - if (rc) -@@ -1914,6 +1902,18 @@ out_err: - ksmbd_conn_set_need_negotiate(conn); - } - } -+ smb2_set_err_rsp(work); -+ } else { -+ unsigned int iov_len; -+ -+ if (rsp->SecurityBufferLength) -+ iov_len = offsetof(struct smb2_sess_setup_rsp, Buffer) + -+ le16_to_cpu(rsp->SecurityBufferLength); -+ else -+ iov_len = sizeof(struct smb2_sess_setup_rsp); -+ rc = ksmbd_iov_pin_rsp(work, rsp, iov_len); -+ if (rc) -+ rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; - } - - ksmbd_conn_unlock(conn); -@@ -1991,14 +1991,20 @@ int smb2_tree_connect(struct ksmbd_work *work) - if (conn->posix_ext_supported) - status.tree_conn->posix_extensions = true; - -+ write_lock(&sess->tree_conns_lock); -+ status.tree_conn->t_state = TREE_CONNECTED; -+ write_unlock(&sess->tree_conns_lock); - rsp->StructureSize = cpu_to_le16(16); -- inc_rfc1001_len(work->response_buf, 16); - out_err1: - rsp->Capabilities = 0; - rsp->Reserved = 0; - /* default manual caching */ - rsp->ShareFlags = SMB2_SHAREFLAG_MANUAL_CACHING; - -+ rc = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_tree_connect_rsp)); -+ if (rc) -+ status.ret = KSMBD_TREE_CONN_STATUS_NOMEM; -+ - if (!IS_ERR(treename)) - kfree(treename); - if (!IS_ERR(name)) -@@ -2111,26 +2117,56 @@ int smb2_tree_disconnect(struct ksmbd_work *work) - struct smb2_tree_disconnect_req *req; - struct ksmbd_session *sess = work->sess; - struct ksmbd_tree_connect *tcon = work->tcon; -+ int err; - - WORK_BUFFERS(work, req, rsp); - -- rsp->StructureSize = cpu_to_le16(4); -- inc_rfc1001_len(work->response_buf, 4); -- - ksmbd_debug(SMB, "request\n"); - -- if (!tcon || test_and_set_bit(TREE_CONN_EXPIRE, &tcon->status)) { -+ if (!tcon) { - ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); - - rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; -- smb2_set_err_rsp(work); -- return 0; -+ err = -ENOENT; -+ goto err_out; - } - - ksmbd_close_tree_conn_fds(work); -- ksmbd_tree_conn_disconnect(sess, tcon); -+ -+ write_lock(&sess->tree_conns_lock); -+ if (tcon->t_state == TREE_DISCONNECTED) { -+ write_unlock(&sess->tree_conns_lock); -+ rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; -+ err = -ENOENT; -+ goto err_out; -+ } -+ -+ WARN_ON_ONCE(atomic_dec_and_test(&tcon->refcount)); -+ tcon->t_state = TREE_DISCONNECTED; -+ write_unlock(&sess->tree_conns_lock); -+ -+ err = ksmbd_tree_conn_disconnect(sess, tcon); -+ if (err) { -+ rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; -+ goto err_out; -+ } -+ - work->tcon = NULL; -+ -+ rsp->StructureSize = cpu_to_le16(4); -+ err = ksmbd_iov_pin_rsp(work, rsp, -+ sizeof(struct smb2_tree_disconnect_rsp)); -+ if (err) { -+ rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; -+ goto err_out; -+ } -+ - return 0; -+ -+err_out: -+ smb2_set_err_rsp(work); -+ return err; -+ - } - - /** -@@ -2146,17 +2182,23 @@ int smb2_session_logoff(struct ksmbd_work *work) - struct smb2_logoff_rsp *rsp; - struct ksmbd_session *sess; - u64 sess_id; -+ int err; - - WORK_BUFFERS(work, req, rsp); - -- sess_id = le64_to_cpu(req->hdr.SessionId); -- -- rsp->StructureSize = cpu_to_le16(4); -- inc_rfc1001_len(work->response_buf, 4); -- - ksmbd_debug(SMB, "request\n"); - -+ ksmbd_conn_lock(conn); -+ if (!ksmbd_conn_good(conn)) { -+ ksmbd_conn_unlock(conn); -+ rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; -+ smb2_set_err_rsp(work); -+ return -ENOENT; -+ } -+ sess_id = le64_to_cpu(req->hdr.SessionId); - ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_RECONNECT); -+ ksmbd_conn_unlock(conn); -+ - ksmbd_close_session_fds(work); - ksmbd_conn_wait_idle(conn, sess_id); - -@@ -2169,7 +2211,7 @@ int smb2_session_logoff(struct ksmbd_work *work) - ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId); - rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; - smb2_set_err_rsp(work); -- return 0; -+ return -ENOENT; - } - - ksmbd_destroy_file_table(&sess->file_table); -@@ -2178,6 +2220,14 @@ int smb2_session_logoff(struct ksmbd_work *work) - ksmbd_free_user(sess->user); - sess->user = NULL; - ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_NEGOTIATE); -+ -+ rsp->StructureSize = cpu_to_le16(4); -+ err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_logoff_rsp)); -+ if (err) { -+ rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; -+ smb2_set_err_rsp(work); -+ return err; -+ } - return 0; - } - -@@ -2230,7 +2280,10 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work) - rsp->CreateContextsOffset = 0; - rsp->CreateContextsLength = 0; - -- inc_rfc1001_len(work->response_buf, 88); /* StructureSize - 1*/ -+ err = ksmbd_iov_pin_rsp(work, rsp, offsetof(struct smb2_create_rsp, Buffer)); -+ if (err) -+ goto out; -+ - kfree(name); - return 0; - -@@ -2309,7 +2362,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, - /* delete the EA only when it exits */ - if (rc > 0) { - rc = ksmbd_vfs_remove_xattr(user_ns, -- path->dentry, -+ path, - attr_name); - - if (rc < 0) { -@@ -2323,9 +2376,9 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, - /* if the EA doesn't exist, just do nothing. */ - rc = 0; - } else { -- rc = ksmbd_vfs_setxattr(user_ns, -- path->dentry, attr_name, value, -- le16_to_cpu(eabuf->EaValueLength), 0); -+ rc = ksmbd_vfs_setxattr(user_ns, path, attr_name, value, -+ le16_to_cpu(eabuf->EaValueLength), -+ 0, true); - if (rc < 0) { - ksmbd_debug(SMB, - "ksmbd_vfs_setxattr is failed(%d)\n", -@@ -2388,8 +2441,7 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path, - return -EBADF; - } - -- rc = ksmbd_vfs_setxattr(user_ns, path->dentry, -- xattr_stream_name, NULL, 0, 0); -+ rc = ksmbd_vfs_setxattr(user_ns, path, xattr_stream_name, NULL, 0, 0, false); - if (rc < 0) - pr_err("Failed to store XATTR stream name :%d\n", rc); - return 0; -@@ -2417,7 +2469,7 @@ static int smb2_remove_smb_xattrs(const struct path *path) - if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && - !strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, - STREAM_PREFIX_LEN)) { -- err = ksmbd_vfs_remove_xattr(user_ns, path->dentry, -+ err = ksmbd_vfs_remove_xattr(user_ns, path, - name); - if (err) - ksmbd_debug(SMB, "remove xattr failed : %s\n", -@@ -2464,8 +2516,7 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, const struct path * - da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME | - XATTR_DOSINFO_ITIME; - -- rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_user_ns(path->mnt), -- path->dentry, &da); -+ rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_user_ns(path->mnt), path, &da, true); - if (rc) - ksmbd_debug(SMB, "failed to store file attribute into xattr\n"); - } -@@ -2492,8 +2543,9 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, - } - } - --static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name, -- int open_flags, umode_t posix_mode, bool is_dir) -+static int smb2_creat(struct ksmbd_work *work, struct path *parent_path, -+ struct path *path, char *name, int open_flags, -+ umode_t posix_mode, bool is_dir) - { - struct ksmbd_tree_connect *tcon = work->tcon; - struct ksmbd_share_config *share = tcon->share_conf; -@@ -2520,7 +2572,7 @@ static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name, - return rc; - } - -- rc = ksmbd_vfs_kern_path(work, name, 0, path, 0); -+ rc = ksmbd_vfs_kern_path_locked(work, name, 0, parent_path, path, 0); - if (rc) { - pr_err("cannot get linux path (%s), err = %d\n", - name, rc); -@@ -2554,7 +2606,7 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work, - sizeof(struct create_sd_buf_req)) - return -EINVAL; - return set_info_sec(work->conn, work->tcon, path, &sd_buf->ntsd, -- le32_to_cpu(sd_buf->ccontext.DataLength), true); -+ le32_to_cpu(sd_buf->ccontext.DataLength), true, false); - } - - static void ksmbd_acls_fattr(struct smb_fattr *fattr, -@@ -2590,7 +2642,7 @@ int smb2_open(struct ksmbd_work *work) - struct ksmbd_tree_connect *tcon = work->tcon; - struct smb2_create_req *req; - struct smb2_create_rsp *rsp; -- struct path path; -+ struct path path, parent_path; - struct ksmbd_share_config *share = tcon->share_conf; - struct ksmbd_file *fp = NULL; - struct file *filp = NULL; -@@ -2614,6 +2666,7 @@ int smb2_open(struct ksmbd_work *work) - u64 time; - umode_t posix_mode = 0; - __le32 daccess, maximal_access = 0; -+ int iov_len = 0; - - WORK_BUFFERS(work, req, rsp); - -@@ -2635,7 +2688,7 @@ int smb2_open(struct ksmbd_work *work) - *(char *)req->Buffer == '\\') { - pr_err("not allow directory name included leading slash\n"); - rc = -EINVAL; -- goto err_out1; -+ goto err_out2; - } - - name = smb2_get_name(req->Buffer, -@@ -2646,7 +2699,7 @@ int smb2_open(struct ksmbd_work *work) - if (rc != -ENOMEM) - rc = -ENOENT; - name = NULL; -- goto err_out1; -+ goto err_out2; - } - - ksmbd_debug(SMB, "converted name = %s\n", name); -@@ -2654,48 +2707,44 @@ int smb2_open(struct ksmbd_work *work) - if (!test_share_config_flag(work->tcon->share_conf, - KSMBD_SHARE_FLAG_STREAMS)) { - rc = -EBADF; -- goto err_out1; -+ goto err_out2; - } - rc = parse_stream_name(name, &stream_name, &s_type); - if (rc < 0) -- goto err_out1; -+ goto err_out2; - } - - rc = ksmbd_validate_filename(name); - if (rc < 0) -- goto err_out1; -+ goto err_out2; - - if (ksmbd_share_veto_filename(share, name)) { - rc = -ENOENT; - ksmbd_debug(SMB, "Reject open(), vetoed file: %s\n", - name); -- goto err_out1; -+ goto err_out2; - } - } else { - name = kstrdup("", GFP_KERNEL); - if (!name) { - rc = -ENOMEM; -- goto err_out1; -+ goto err_out2; - } - } - -- req_op_level = req->RequestedOplockLevel; -- if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) -- lc = parse_lease_state(req); -- - if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE)) { - pr_err("Invalid impersonationlevel : 0x%x\n", - le32_to_cpu(req->ImpersonationLevel)); - rc = -EIO; - rsp->hdr.Status = STATUS_BAD_IMPERSONATION_LEVEL; -- goto err_out1; -+ goto err_out2; - } - - if (req->CreateOptions && !(req->CreateOptions & CREATE_OPTIONS_MASK_LE)) { - pr_err("Invalid create options : 0x%x\n", - le32_to_cpu(req->CreateOptions)); - rc = -EINVAL; -- goto err_out1; -+ goto err_out2; - } else { - if (req->CreateOptions & FILE_SEQUENTIAL_ONLY_LE && - req->CreateOptions & FILE_RANDOM_ACCESS_LE) -@@ -2705,13 +2754,13 @@ int smb2_open(struct ksmbd_work *work) - (FILE_OPEN_BY_FILE_ID_LE | CREATE_TREE_CONNECTION | - FILE_RESERVE_OPFILTER_LE)) { - rc = -EOPNOTSUPP; -- goto err_out1; -+ goto err_out2; - } - - if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) { - if (req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE) { - rc = -EINVAL; -- goto err_out1; -+ goto err_out2; - } else if (req->CreateOptions & FILE_NO_COMPRESSION_LE) { - req->CreateOptions = ~(FILE_NO_COMPRESSION_LE); - } -@@ -2723,21 +2772,21 @@ int smb2_open(struct ksmbd_work *work) - pr_err("Invalid create disposition : 0x%x\n", - le32_to_cpu(req->CreateDisposition)); - rc = -EINVAL; -- goto err_out1; -+ goto err_out2; - } - - if (!(req->DesiredAccess & DESIRED_ACCESS_MASK)) { - pr_err("Invalid desired access : 0x%x\n", - le32_to_cpu(req->DesiredAccess)); - rc = -EACCES; -- goto err_out1; -+ goto err_out2; - } - - if (req->FileAttributes && !(req->FileAttributes & FILE_ATTRIBUTE_MASK_LE)) { - pr_err("Invalid file attribute : 0x%x\n", - le32_to_cpu(req->FileAttributes)); - rc = -EINVAL; -- goto err_out1; -+ goto err_out2; - } - - if (req->CreateContextsOffset) { -@@ -2745,19 +2794,19 @@ int smb2_open(struct ksmbd_work *work) - context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER, 4); - if (IS_ERR(context)) { - rc = PTR_ERR(context); -- goto err_out1; -+ goto err_out2; - } else if (context) { - ea_buf = (struct create_ea_buf_req *)context; - if (le16_to_cpu(context->DataOffset) + - le32_to_cpu(context->DataLength) < - sizeof(struct create_ea_buf_req)) { - rc = -EINVAL; -- goto err_out1; -+ goto err_out2; - } - if (req->CreateOptions & FILE_NO_EA_KNOWLEDGE_LE) { - rsp->hdr.Status = STATUS_ACCESS_DENIED; - rc = -EACCES; -- goto err_out1; -+ goto err_out2; - } - } - -@@ -2765,7 +2814,7 @@ int smb2_open(struct ksmbd_work *work) - SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, 4); - if (IS_ERR(context)) { - rc = PTR_ERR(context); -- goto err_out1; -+ goto err_out2; - } else if (context) { - ksmbd_debug(SMB, - "get query maximal access context\n"); -@@ -2776,11 +2825,11 @@ int smb2_open(struct ksmbd_work *work) - SMB2_CREATE_TIMEWARP_REQUEST, 4); - if (IS_ERR(context)) { - rc = PTR_ERR(context); -- goto err_out1; -+ goto err_out2; - } else if (context) { - ksmbd_debug(SMB, "get timewarp context\n"); - rc = -EBADF; -- goto err_out1; -+ goto err_out2; - } - - if (tcon->posix_extensions) { -@@ -2788,7 +2837,7 @@ int smb2_open(struct ksmbd_work *work) - SMB2_CREATE_TAG_POSIX, 16); - if (IS_ERR(context)) { - rc = PTR_ERR(context); -- goto err_out1; -+ goto err_out2; - } else if (context) { - struct create_posix *posix = - (struct create_posix *)context; -@@ -2796,7 +2845,7 @@ int smb2_open(struct ksmbd_work *work) - le32_to_cpu(context->DataLength) < - sizeof(struct create_posix) - 4) { - rc = -EINVAL; -- goto err_out1; -+ goto err_out2; - } - ksmbd_debug(SMB, "get posix context\n"); - -@@ -2808,11 +2857,14 @@ int smb2_open(struct ksmbd_work *work) - - if (ksmbd_override_fsids(work)) { - rc = -ENOMEM; -- goto err_out1; -+ goto err_out2; - } - -- rc = ksmbd_vfs_kern_path(work, name, LOOKUP_NO_SYMLINKS, &path, 1); -+ rc = ksmbd_vfs_kern_path_locked(work, name, LOOKUP_NO_SYMLINKS, -+ &parent_path, &path, 1); - if (!rc) { -+ file_present = true; -+ - if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) { - /* - * If file exists with under flags, return access -@@ -2821,7 +2873,6 @@ int smb2_open(struct ksmbd_work *work) - if (req->CreateDisposition == FILE_OVERWRITE_IF_LE || - req->CreateDisposition == FILE_OPEN_IF_LE) { - rc = -EACCES; -- path_put(&path); - goto err_out; - } - -@@ -2829,26 +2880,23 @@ int smb2_open(struct ksmbd_work *work) - ksmbd_debug(SMB, - "User does not have write permission\n"); - rc = -EACCES; -- path_put(&path); - goto err_out; - } - } else if (d_is_symlink(path.dentry)) { - rc = -EACCES; -- path_put(&path); - goto err_out; - } -- } - -- if (rc) { -+ file_present = true; -+ user_ns = mnt_user_ns(path.mnt); -+ } else { - if (rc != -ENOENT) - goto err_out; - ksmbd_debug(SMB, "can not get linux path for %s, rc = %d\n", - name, rc); - rc = 0; -- } else { -- file_present = true; -- user_ns = mnt_user_ns(path.mnt); - } -+ - if (stream_name) { - if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) { - if (s_type == DATA_STREAM) { -@@ -2910,11 +2958,9 @@ int smb2_open(struct ksmbd_work *work) - if (!file_present) { - daccess = cpu_to_le32(GENERIC_ALL_FLAGS); - } else { -- rc = ksmbd_vfs_query_maximal_access(user_ns, -+ ksmbd_vfs_query_maximal_access(user_ns, - path.dentry, - &daccess); -- if (rc) -- goto err_out; - already_permitted = true; - } - maximal_access = daccess; -@@ -2935,7 +2981,8 @@ int smb2_open(struct ksmbd_work *work) - - /*create file if not present */ - if (!file_present) { -- rc = smb2_creat(work, &path, name, open_flags, posix_mode, -+ rc = smb2_creat(work, &parent_path, &path, name, open_flags, -+ posix_mode, - req->CreateOptions & FILE_DIRECTORY_FILE_LE); - if (rc) { - if (rc == -ENOENT) { -@@ -2976,15 +3023,16 @@ int smb2_open(struct ksmbd_work *work) - - if ((daccess & FILE_DELETE_LE) || - (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { -- rc = ksmbd_vfs_may_delete(user_ns, -- path.dentry); -+ rc = inode_permission(user_ns, -+ d_inode(path.dentry->d_parent), -+ MAY_EXEC | MAY_WRITE); - if (rc) - goto err_out; - } - } - } - -- rc = ksmbd_query_inode_status(d_inode(path.dentry->d_parent)); -+ rc = ksmbd_query_inode_status(path.dentry->d_parent); - if (rc == KSMBD_INODE_STATUS_PENDING_DELETE) { - rc = -EBUSY; - goto err_out; -@@ -3040,7 +3088,7 @@ int smb2_open(struct ksmbd_work *work) - struct inode *inode = d_inode(path.dentry); - - posix_acl_rc = ksmbd_vfs_inherit_posix_acl(user_ns, -- inode, -+ &path, - d_inode(path.dentry->d_parent)); - if (posix_acl_rc) - ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc); -@@ -3056,7 +3104,7 @@ int smb2_open(struct ksmbd_work *work) - if (rc) { - if (posix_acl_rc) - ksmbd_vfs_set_init_posix_acl(user_ns, -- inode); -+ &path); - - if (test_share_config_flag(work->tcon->share_conf, - KSMBD_SHARE_FLAG_ACL_XATTR)) { -@@ -3096,9 +3144,10 @@ int smb2_open(struct ksmbd_work *work) - - rc = ksmbd_vfs_set_sd_xattr(conn, - user_ns, -- path.dentry, -+ &path, - pntsd, -- pntsd_size); -+ pntsd_size, -+ false); - kfree(pntsd); - if (rc) - pr_err("failed to store ntacl in xattr : %d\n", -@@ -3121,11 +3170,6 @@ int smb2_open(struct ksmbd_work *work) - - fp->attrib_only = !(req->DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE | - FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE)); -- if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC && -- !fp->attrib_only && !stream_name) { -- smb_break_all_oplock(work, fp); -- need_truncate = 1; -- } - - /* fp should be searchable through ksmbd_inode.m_fp_list - * after daccess, saccess, attrib_only, and stream are -@@ -3141,23 +3185,43 @@ int smb2_open(struct ksmbd_work *work) - goto err_out; - } - -+ if (file_present || created) -+ ksmbd_vfs_kern_path_unlock(&parent_path, &path); -+ -+ if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC && -+ !fp->attrib_only && !stream_name) { -+ smb_break_all_oplock(work, fp); -+ need_truncate = 1; -+ } -+ -+ req_op_level = req->RequestedOplockLevel; -+ if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) -+ lc = parse_lease_state(req, S_ISDIR(file_inode(filp)->i_mode)); -+ - share_ret = ksmbd_smb_check_shared_mode(fp->filp, fp); - if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) || - (req_op_level == SMB2_OPLOCK_LEVEL_LEASE && - !(conn->vals->capabilities & SMB2_GLOBAL_CAP_LEASING))) { - if (share_ret < 0 && !S_ISDIR(file_inode(fp->filp)->i_mode)) { - rc = share_ret; -- goto err_out; -+ goto err_out1; - } - } else { - if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) { -+ /* -+ * Compare parent lease using parent key. If there is no -+ * a lease that has same parent key, Send lease break -+ * notification. -+ */ -+ smb_send_parent_lease_break_noti(fp, lc); -+ - req_op_level = smb2_map_lease_to_oplock(lc->req_state); - ksmbd_debug(SMB, - "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n", - name, req_op_level, lc->req_state); - rc = find_same_lease_key(sess, fp->f_ci, lc); - if (rc) -- goto err_out; -+ goto err_out1; - } else if (open_flags == O_RDONLY && - (req_op_level == SMB2_OPLOCK_LEVEL_BATCH || - req_op_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) -@@ -3168,16 +3232,16 @@ int smb2_open(struct ksmbd_work *work) - le32_to_cpu(req->hdr.Id.SyncId.TreeId), - lc, share_ret); - if (rc < 0) -- goto err_out; -+ goto err_out1; - } - - if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) - ksmbd_fd_set_delete_on_close(fp, file_info); - - if (need_truncate) { -- rc = smb2_create_truncate(&path); -+ rc = smb2_create_truncate(&fp->filp->f_path); - if (rc) -- goto err_out; -+ goto err_out1; - } - - if (req->CreateContextsOffset) { -@@ -3187,7 +3251,7 @@ int smb2_open(struct ksmbd_work *work) - SMB2_CREATE_ALLOCATION_SIZE, 4); - if (IS_ERR(az_req)) { - rc = PTR_ERR(az_req); -- goto err_out; -+ goto err_out1; - } else if (az_req) { - loff_t alloc_size; - int err; -@@ -3196,7 +3260,7 @@ int smb2_open(struct ksmbd_work *work) - le32_to_cpu(az_req->ccontext.DataLength) < - sizeof(struct create_alloc_size_req)) { - rc = -EINVAL; -- goto err_out; -+ goto err_out1; - } - alloc_size = le64_to_cpu(az_req->AllocationSize); - ksmbd_debug(SMB, -@@ -3214,7 +3278,7 @@ int smb2_open(struct ksmbd_work *work) - context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID, 4); - if (IS_ERR(context)) { - rc = PTR_ERR(context); -- goto err_out; -+ goto err_out1; - } else if (context) { - ksmbd_debug(SMB, "get query on disk id context\n"); - query_disk_id = 1; -@@ -3223,7 +3287,7 @@ int smb2_open(struct ksmbd_work *work) - - rc = ksmbd_vfs_getattr(&path, &stat); - if (rc) -- goto err_out; -+ goto err_out1; - - if (stat.result_mask & STATX_BTIME) - fp->create_time = ksmbd_UnixTimeToNT(stat.btime); -@@ -3266,7 +3330,7 @@ int smb2_open(struct ksmbd_work *work) - - rsp->CreateContextsOffset = 0; - rsp->CreateContextsLength = 0; -- inc_rfc1001_len(work->response_buf, 88); /* StructureSize - 1*/ -+ iov_len = offsetof(struct smb2_create_rsp, Buffer); - - /* If lease is request send lease context response */ - if (opinfo && opinfo->is_lease) { -@@ -3281,8 +3345,7 @@ int smb2_open(struct ksmbd_work *work) - create_lease_buf(rsp->Buffer, opinfo->o_lease); - le32_add_cpu(&rsp->CreateContextsLength, - conn->vals->create_lease_size); -- inc_rfc1001_len(work->response_buf, -- conn->vals->create_lease_size); -+ iov_len += conn->vals->create_lease_size; - next_ptr = &lease_ccontext->Next; - next_off = conn->vals->create_lease_size; - } -@@ -3302,8 +3365,7 @@ int smb2_open(struct ksmbd_work *work) - le32_to_cpu(maximal_access)); - le32_add_cpu(&rsp->CreateContextsLength, - conn->vals->create_mxac_size); -- inc_rfc1001_len(work->response_buf, -- conn->vals->create_mxac_size); -+ iov_len += conn->vals->create_mxac_size; - if (next_ptr) - *next_ptr = cpu_to_le32(next_off); - next_ptr = &mxac_ccontext->Next; -@@ -3321,8 +3383,7 @@ int smb2_open(struct ksmbd_work *work) - stat.ino, tcon->id); - le32_add_cpu(&rsp->CreateContextsLength, - conn->vals->create_disk_id_size); -- inc_rfc1001_len(work->response_buf, -- conn->vals->create_disk_id_size); -+ iov_len += conn->vals->create_disk_id_size; - if (next_ptr) - *next_ptr = cpu_to_le32(next_off); - next_ptr = &disk_id_ccontext->Next; -@@ -3336,8 +3397,7 @@ int smb2_open(struct ksmbd_work *work) - fp); - le32_add_cpu(&rsp->CreateContextsLength, - conn->vals->create_posix_size); -- inc_rfc1001_len(work->response_buf, -- conn->vals->create_posix_size); -+ iov_len += conn->vals->create_posix_size; - if (next_ptr) - *next_ptr = cpu_to_le32(next_off); - } -@@ -3348,10 +3408,17 @@ int smb2_open(struct ksmbd_work *work) - } - - err_out: -- if (file_present || created) -- path_put(&path); -- ksmbd_revert_fsids(work); -+ if (rc && (file_present || created)) -+ ksmbd_vfs_kern_path_unlock(&parent_path, &path); -+ - err_out1: -+ ksmbd_revert_fsids(work); -+ -+err_out2: -+ if (!rc) { -+ ksmbd_update_fstate(&work->sess->file_table, fp, FP_INITED); -+ rc = ksmbd_iov_pin_rsp(work, (void *)rsp, iov_len); -+ } - if (rc) { - if (rc == -EINVAL) - rsp->hdr.Status = STATUS_INVALID_PARAMETER; -@@ -3525,7 +3592,7 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, - goto free_conv_name; - } - -- struct_sz = readdir_info_level_struct_sz(info_level) - 1 + conv_len; -+ struct_sz = readdir_info_level_struct_sz(info_level) + conv_len; - next_entry_offset = ALIGN(struct_sz, KSMBD_DIR_INFO_ALIGNMENT); - d_info->last_entry_off_align = next_entry_offset - struct_sz; - -@@ -3777,7 +3844,7 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info, - return -EOPNOTSUPP; - - conv_len = (d_info->name_len + 1) * 2; -- next_entry_offset = ALIGN(struct_sz - 1 + conv_len, -+ next_entry_offset = ALIGN(struct_sz + conv_len, - KSMBD_DIR_INFO_ALIGNMENT); - - if (next_entry_offset > d_info->out_buf_len) { -@@ -4077,7 +4144,10 @@ int smb2_query_dir(struct ksmbd_work *work) - rsp->OutputBufferOffset = cpu_to_le16(0); - rsp->OutputBufferLength = cpu_to_le32(0); - rsp->Buffer[0] = 0; -- inc_rfc1001_len(work->response_buf, 9); -+ rc = ksmbd_iov_pin_rsp(work, (void *)rsp, -+ sizeof(struct smb2_query_directory_rsp)); -+ if (rc) -+ goto err_out; - } else { - no_buf_len: - ((struct file_directory_info *) -@@ -4089,7 +4159,11 @@ no_buf_len: - rsp->StructureSize = cpu_to_le16(9); - rsp->OutputBufferOffset = cpu_to_le16(72); - rsp->OutputBufferLength = cpu_to_le32(d_info.data_count); -- inc_rfc1001_len(work->response_buf, 8 + d_info.data_count); -+ rc = ksmbd_iov_pin_rsp(work, (void *)rsp, -+ offsetof(struct smb2_query_directory_rsp, Buffer) + -+ d_info.data_count); -+ if (rc) -+ goto err_out; - } - - kfree(srch_ptr); -@@ -4130,27 +4204,18 @@ err_out2: - * @reqOutputBufferLength: max buffer length expected in command response - * @rsp: query info response buffer contains output buffer length - * @rsp_org: base response buffer pointer in case of chained response -- * @infoclass_size: query info class response buffer size - * - * Return: 0 on success, otherwise error - */ - static int buffer_check_err(int reqOutputBufferLength, - struct smb2_query_info_rsp *rsp, -- void *rsp_org, int infoclass_size) -+ void *rsp_org) - { - if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) { -- if (reqOutputBufferLength < infoclass_size) { -- pr_err("Invalid Buffer Size Requested\n"); -- rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH; -- *(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr)); -- return -EINVAL; -- } -- -- ksmbd_debug(SMB, "Buffer Overflow\n"); -- rsp->hdr.Status = STATUS_BUFFER_OVERFLOW; -- *(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr) + -- reqOutputBufferLength); -- rsp->OutputBufferLength = cpu_to_le32(reqOutputBufferLength); -+ pr_err("Invalid Buffer Size Requested\n"); -+ rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH; -+ *(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr)); -+ return -EINVAL; - } - return 0; - } -@@ -4169,7 +4234,6 @@ static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp, - sinfo->Directory = 0; - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_standard_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_standard_info)); - } - - static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num, -@@ -4183,7 +4247,6 @@ static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num, - file_info->IndexNumber = cpu_to_le64(num | (1ULL << 63)); - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_internal_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_internal_info)); - } - - static int smb2_get_info_file_pipe(struct ksmbd_session *sess, -@@ -4209,14 +4272,12 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess, - case FILE_STANDARD_INFORMATION: - get_standard_info_pipe(rsp, rsp_org); - rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), -- rsp, rsp_org, -- FILE_STANDARD_INFORMATION_SIZE); -+ rsp, rsp_org); - break; - case FILE_INTERNAL_INFORMATION: - get_internal_info_pipe(rsp, id, rsp_org); - rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), -- rsp, rsp_org, -- FILE_INTERNAL_INFORMATION_SIZE); -+ rsp, rsp_org); - break; - default: - ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n", -@@ -4384,7 +4445,6 @@ done: - if (rsp_data_cnt == 0) - rsp->hdr.Status = STATUS_NO_EAS_ON_FILE; - rsp->OutputBufferLength = cpu_to_le32(rsp_data_cnt); -- inc_rfc1001_len(rsp_org, rsp_data_cnt); - out: - kvfree(xattr_list); - return rc; -@@ -4399,7 +4459,6 @@ static void get_file_access_info(struct smb2_query_info_rsp *rsp, - file_info->AccessFlags = fp->daccess; - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_access_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_access_info)); - } - - static int get_file_basic_info(struct smb2_query_info_rsp *rsp, -@@ -4429,7 +4488,6 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp, - basic_info->Pad1 = 0; - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_basic_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_basic_info)); - return 0; - } - -@@ -4454,8 +4512,6 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp, - sinfo->Directory = S_ISDIR(stat.mode) ? 1 : 0; - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_standard_info)); -- inc_rfc1001_len(rsp_org, -- sizeof(struct smb2_file_standard_info)); - } - - static void get_file_alignment_info(struct smb2_query_info_rsp *rsp, -@@ -4467,8 +4523,6 @@ static void get_file_alignment_info(struct smb2_query_info_rsp *rsp, - file_info->AlignmentRequirement = 0; - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_alignment_info)); -- inc_rfc1001_len(rsp_org, -- sizeof(struct smb2_file_alignment_info)); - } - - static int get_file_all_info(struct ksmbd_work *work, -@@ -4532,7 +4586,6 @@ static int get_file_all_info(struct ksmbd_work *work, - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_all_info) + conv_len - 1); - kfree(filename); -- inc_rfc1001_len(rsp_org, le32_to_cpu(rsp->OutputBufferLength)); - return 0; - } - -@@ -4555,7 +4608,6 @@ static void get_file_alternate_info(struct ksmbd_work *work, - file_info->FileNameLength = cpu_to_le32(conv_len); - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_alt_name_info) + conv_len); -- inc_rfc1001_len(rsp_org, le32_to_cpu(rsp->OutputBufferLength)); - } - - static void get_file_stream_info(struct ksmbd_work *work, -@@ -4655,7 +4707,6 @@ out: - kvfree(xattr_list); - - rsp->OutputBufferLength = cpu_to_le32(nbytes); -- inc_rfc1001_len(rsp_org, nbytes); - } - - static void get_file_internal_info(struct smb2_query_info_rsp *rsp, -@@ -4670,7 +4721,6 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp, - file_info->IndexNumber = cpu_to_le64(stat.ino); - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_internal_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_internal_info)); - } - - static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, -@@ -4706,7 +4756,6 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, - file_info->Reserved = cpu_to_le32(0); - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_ntwrk_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_ntwrk_info)); - return 0; - } - -@@ -4718,7 +4767,6 @@ static void get_file_ea_info(struct smb2_query_info_rsp *rsp, void *rsp_org) - file_info->EASize = 0; - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_ea_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_ea_info)); - } - - static void get_file_position_info(struct smb2_query_info_rsp *rsp, -@@ -4730,7 +4778,6 @@ static void get_file_position_info(struct smb2_query_info_rsp *rsp, - file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos); - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_pos_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_pos_info)); - } - - static void get_file_mode_info(struct smb2_query_info_rsp *rsp, -@@ -4742,7 +4789,6 @@ static void get_file_mode_info(struct smb2_query_info_rsp *rsp, - file_info->Mode = fp->coption & FILE_MODE_INFO_MASK; - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_mode_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_mode_info)); - } - - static void get_file_compression_info(struct smb2_query_info_rsp *rsp, -@@ -4764,7 +4810,6 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp, - - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_comp_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_comp_info)); - } - - static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp, -@@ -4783,11 +4828,10 @@ static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp, - file_info->ReparseTag = 0; - rsp->OutputBufferLength = - cpu_to_le32(sizeof(struct smb2_file_attr_tag_info)); -- inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_attr_tag_info)); - return 0; - } - --static int find_file_posix_info(struct smb2_query_info_rsp *rsp, -+static void find_file_posix_info(struct smb2_query_info_rsp *rsp, - struct ksmbd_file *fp, void *rsp_org) - { - struct smb311_posix_qinfo *file_info; -@@ -4825,8 +4869,6 @@ static int find_file_posix_info(struct smb2_query_info_rsp *rsp, - SIDUNIX_GROUP, (struct smb_sid *)&file_info->Sids[16]); - - rsp->OutputBufferLength = cpu_to_le32(out_buf_len); -- inc_rfc1001_len(rsp_org, out_buf_len); -- return out_buf_len; - } - - static int smb2_get_info_file(struct ksmbd_work *work, -@@ -4836,7 +4878,6 @@ static int smb2_get_info_file(struct ksmbd_work *work, - struct ksmbd_file *fp; - int fileinfoclass = 0; - int rc = 0; -- int file_infoclass_size; - unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; - - if (test_share_config_flag(work->tcon->share_conf, -@@ -4869,85 +4910,69 @@ static int smb2_get_info_file(struct ksmbd_work *work, - switch (fileinfoclass) { - case FILE_ACCESS_INFORMATION: - get_file_access_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_ACCESS_INFORMATION_SIZE; - break; - - case FILE_BASIC_INFORMATION: - rc = get_file_basic_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_BASIC_INFORMATION_SIZE; - break; - - case FILE_STANDARD_INFORMATION: - get_file_standard_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_STANDARD_INFORMATION_SIZE; - break; - - case FILE_ALIGNMENT_INFORMATION: - get_file_alignment_info(rsp, work->response_buf); -- file_infoclass_size = FILE_ALIGNMENT_INFORMATION_SIZE; - break; - - case FILE_ALL_INFORMATION: - rc = get_file_all_info(work, rsp, fp, work->response_buf); -- file_infoclass_size = FILE_ALL_INFORMATION_SIZE; - break; - - case FILE_ALTERNATE_NAME_INFORMATION: - get_file_alternate_info(work, rsp, fp, work->response_buf); -- file_infoclass_size = FILE_ALTERNATE_NAME_INFORMATION_SIZE; - break; - - case FILE_STREAM_INFORMATION: - get_file_stream_info(work, rsp, fp, work->response_buf); -- file_infoclass_size = FILE_STREAM_INFORMATION_SIZE; - break; - - case FILE_INTERNAL_INFORMATION: - get_file_internal_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_INTERNAL_INFORMATION_SIZE; - break; - - case FILE_NETWORK_OPEN_INFORMATION: - rc = get_file_network_open_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_NETWORK_OPEN_INFORMATION_SIZE; - break; - - case FILE_EA_INFORMATION: - get_file_ea_info(rsp, work->response_buf); -- file_infoclass_size = FILE_EA_INFORMATION_SIZE; - break; - - case FILE_FULL_EA_INFORMATION: - rc = smb2_get_ea(work, fp, req, rsp, work->response_buf); -- file_infoclass_size = FILE_FULL_EA_INFORMATION_SIZE; - break; - - case FILE_POSITION_INFORMATION: - get_file_position_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_POSITION_INFORMATION_SIZE; - break; - - case FILE_MODE_INFORMATION: - get_file_mode_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_MODE_INFORMATION_SIZE; - break; - - case FILE_COMPRESSION_INFORMATION: - get_file_compression_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_COMPRESSION_INFORMATION_SIZE; - break; - - case FILE_ATTRIBUTE_TAG_INFORMATION: - rc = get_file_attribute_tag_info(rsp, fp, work->response_buf); -- file_infoclass_size = FILE_ATTRIBUTE_TAG_INFORMATION_SIZE; - break; - case SMB_FIND_FILE_POSIX_INFO: - if (!work->tcon->posix_extensions) { - pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); - rc = -EOPNOTSUPP; - } else { -- file_infoclass_size = find_file_posix_info(rsp, fp, -- work->response_buf); -+ find_file_posix_info(rsp, fp, work->response_buf); - } - break; - default: -@@ -4957,8 +4982,7 @@ static int smb2_get_info_file(struct ksmbd_work *work, - } - if (!rc) - rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), -- rsp, work->response_buf, -- file_infoclass_size); -+ rsp, work->response_buf); - ksmbd_fd_put(work, fp); - return rc; - } -@@ -4974,7 +4998,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - struct kstatfs stfs; - struct path path; - int rc = 0, len; -- int fs_infoclass_size = 0; - - if (!share->path) - return -EIO; -@@ -5004,8 +5027,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->DeviceType = cpu_to_le32(stfs.f_type); - info->DeviceCharacteristics = cpu_to_le32(0x00000020); - rsp->OutputBufferLength = cpu_to_le32(8); -- inc_rfc1001_len(work->response_buf, 8); -- fs_infoclass_size = FS_DEVICE_INFORMATION_SIZE; - break; - } - case FS_ATTRIBUTE_INFORMATION: -@@ -5034,8 +5055,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->FileSystemNameLen = cpu_to_le32(len); - sz = sizeof(struct filesystem_attribute_info) - 2 + len; - rsp->OutputBufferLength = cpu_to_le32(sz); -- inc_rfc1001_len(work->response_buf, sz); -- fs_infoclass_size = FS_ATTRIBUTE_INFORMATION_SIZE; - break; - } - case FS_VOLUME_INFORMATION: -@@ -5062,8 +5081,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->Reserved = 0; - sz = sizeof(struct filesystem_vol_info) - 2 + len; - rsp->OutputBufferLength = cpu_to_le32(sz); -- inc_rfc1001_len(work->response_buf, sz); -- fs_infoclass_size = FS_VOLUME_INFORMATION_SIZE; - break; - } - case FS_SIZE_INFORMATION: -@@ -5076,8 +5093,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->SectorsPerAllocationUnit = cpu_to_le32(1); - info->BytesPerSector = cpu_to_le32(stfs.f_bsize); - rsp->OutputBufferLength = cpu_to_le32(24); -- inc_rfc1001_len(work->response_buf, 24); -- fs_infoclass_size = FS_SIZE_INFORMATION_SIZE; - break; - } - case FS_FULL_SIZE_INFORMATION: -@@ -5093,8 +5108,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->SectorsPerAllocationUnit = cpu_to_le32(1); - info->BytesPerSector = cpu_to_le32(stfs.f_bsize); - rsp->OutputBufferLength = cpu_to_le32(32); -- inc_rfc1001_len(work->response_buf, 32); -- fs_infoclass_size = FS_FULL_SIZE_INFORMATION_SIZE; - break; - } - case FS_OBJECT_ID_INFORMATION: -@@ -5114,8 +5127,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->extended_info.rel_date = 0; - memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0")); - rsp->OutputBufferLength = cpu_to_le32(64); -- inc_rfc1001_len(work->response_buf, 64); -- fs_infoclass_size = FS_OBJECT_ID_INFORMATION_SIZE; - break; - } - case FS_SECTOR_SIZE_INFORMATION: -@@ -5137,8 +5148,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->ByteOffsetForSectorAlignment = 0; - info->ByteOffsetForPartitionAlignment = 0; - rsp->OutputBufferLength = cpu_to_le32(28); -- inc_rfc1001_len(work->response_buf, 28); -- fs_infoclass_size = FS_SECTOR_SIZE_INFORMATION_SIZE; - break; - } - case FS_CONTROL_INFORMATION: -@@ -5159,8 +5168,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->DefaultQuotaLimit = cpu_to_le64(SMB2_NO_FID); - info->Padding = 0; - rsp->OutputBufferLength = cpu_to_le32(48); -- inc_rfc1001_len(work->response_buf, 48); -- fs_infoclass_size = FS_CONTROL_INFORMATION_SIZE; - break; - } - case FS_POSIX_INFORMATION: -@@ -5180,8 +5187,6 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - info->TotalFileNodes = cpu_to_le64(stfs.f_files); - info->FreeFileNodes = cpu_to_le64(stfs.f_ffree); - rsp->OutputBufferLength = cpu_to_le32(56); -- inc_rfc1001_len(work->response_buf, 56); -- fs_infoclass_size = FS_POSIX_INFORMATION_SIZE; - } - break; - } -@@ -5190,8 +5195,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, - return -EOPNOTSUPP; - } - rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), -- rsp, work->response_buf, -- fs_infoclass_size); -+ rsp, work->response_buf); - path_put(&path); - return rc; - } -@@ -5225,7 +5229,6 @@ static int smb2_get_info_sec(struct ksmbd_work *work, - - secdesclen = sizeof(struct smb_ntsd); - rsp->OutputBufferLength = cpu_to_le32(secdesclen); -- inc_rfc1001_len(work->response_buf, secdesclen); - - return 0; - } -@@ -5270,7 +5273,6 @@ static int smb2_get_info_sec(struct ksmbd_work *work, - return rc; - - rsp->OutputBufferLength = cpu_to_le32(secdesclen); -- inc_rfc1001_len(work->response_buf, secdesclen); - return 0; - } - -@@ -5309,6 +5311,14 @@ int smb2_query_info(struct ksmbd_work *work) - rc = -EOPNOTSUPP; - } - -+ if (!rc) { -+ rsp->StructureSize = cpu_to_le16(9); -+ rsp->OutputBufferOffset = cpu_to_le16(72); -+ rc = ksmbd_iov_pin_rsp(work, (void *)rsp, -+ offsetof(struct smb2_query_info_rsp, Buffer) + -+ le32_to_cpu(rsp->OutputBufferLength)); -+ } -+ - if (rc < 0) { - if (rc == -EACCES) - rsp->hdr.Status = STATUS_ACCESS_DENIED; -@@ -5316,6 +5326,8 @@ int smb2_query_info(struct ksmbd_work *work) - rsp->hdr.Status = STATUS_FILE_CLOSED; - else if (rc == -EIO) - rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR; -+ else if (rc == -ENOMEM) -+ rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; - else if (rc == -EOPNOTSUPP || rsp->hdr.Status == 0) - rsp->hdr.Status = STATUS_INVALID_INFO_CLASS; - smb2_set_err_rsp(work); -@@ -5324,9 +5336,6 @@ int smb2_query_info(struct ksmbd_work *work) - rc); - return rc; - } -- rsp->StructureSize = cpu_to_le16(9); -- rsp->OutputBufferOffset = cpu_to_le16(72); -- inc_rfc1001_len(work->response_buf, 8); - return 0; - } - -@@ -5357,8 +5366,9 @@ static noinline int smb2_close_pipe(struct ksmbd_work *work) - rsp->AllocationSize = 0; - rsp->EndOfFile = 0; - rsp->Attributes = 0; -- inc_rfc1001_len(work->response_buf, 60); -- return 0; -+ -+ return ksmbd_iov_pin_rsp(work, (void *)rsp, -+ sizeof(struct smb2_close_rsp)); - } - - /** -@@ -5463,15 +5473,17 @@ int smb2_close(struct ksmbd_work *work) - - err = ksmbd_close_fd(work, volatile_id); - out: -+ if (!err) -+ err = ksmbd_iov_pin_rsp(work, (void *)rsp, -+ sizeof(struct smb2_close_rsp)); -+ - if (err) { - if (rsp->hdr.Status == 0) - rsp->hdr.Status = STATUS_FILE_CLOSED; - smb2_set_err_rsp(work); -- } else { -- inc_rfc1001_len(work->response_buf, 60); - } - -- return 0; -+ return err; - } - - /** -@@ -5489,50 +5501,24 @@ int smb2_echo(struct ksmbd_work *work) - - rsp->StructureSize = cpu_to_le16(4); - rsp->Reserved = 0; -- inc_rfc1001_len(work->response_buf, 4); -- return 0; -+ return ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_echo_rsp)); - } - - static int smb2_rename(struct ksmbd_work *work, - struct ksmbd_file *fp, -- struct user_namespace *user_ns, - struct smb2_file_rename_info *file_info, - struct nls_table *local_nls) - { - struct ksmbd_share_config *share = fp->tcon->share_conf; -- char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL; -- char *pathname = NULL; -- struct path path; -- bool file_present = true; -- int rc; -+ char *new_name = NULL; -+ int rc, flags = 0; - - ksmbd_debug(SMB, "setting FILE_RENAME_INFO\n"); -- pathname = kmalloc(PATH_MAX, GFP_KERNEL); -- if (!pathname) -- return -ENOMEM; -- -- abs_oldname = file_path(fp->filp, pathname, PATH_MAX); -- if (IS_ERR(abs_oldname)) { -- rc = -EINVAL; -- goto out; -- } -- old_name = strrchr(abs_oldname, '/'); -- if (old_name && old_name[1] != '\0') { -- old_name++; -- } else { -- ksmbd_debug(SMB, "can't get last component in path %s\n", -- abs_oldname); -- rc = -ENOENT; -- goto out; -- } -- - new_name = smb2_get_name(file_info->FileName, - le32_to_cpu(file_info->FileNameLength), - local_nls); -- if (IS_ERR(new_name)) { -- rc = PTR_ERR(new_name); -- goto out; -- } -+ if (IS_ERR(new_name)) -+ return PTR_ERR(new_name); - - if (strchr(new_name, ':')) { - int s_type; -@@ -5558,10 +5544,10 @@ static int smb2_rename(struct ksmbd_work *work, - if (rc) - goto out; - -- rc = ksmbd_vfs_setxattr(user_ns, -- fp->filp->f_path.dentry, -+ rc = ksmbd_vfs_setxattr(file_mnt_user_ns(fp->filp), -+ &fp->filp->f_path, - xattr_stream_name, -- NULL, 0, 0); -+ NULL, 0, 0, true); - if (rc < 0) { - pr_err("failed to store stream name in xattr: %d\n", - rc); -@@ -5573,47 +5559,18 @@ static int smb2_rename(struct ksmbd_work *work, - } - - ksmbd_debug(SMB, "new name %s\n", new_name); -- rc = ksmbd_vfs_kern_path(work, new_name, LOOKUP_NO_SYMLINKS, &path, 1); -- if (rc) { -- if (rc != -ENOENT) -- goto out; -- file_present = false; -- } else { -- path_put(&path); -- } -- - if (ksmbd_share_veto_filename(share, new_name)) { - rc = -ENOENT; - ksmbd_debug(SMB, "Can't rename vetoed file: %s\n", new_name); - goto out; - } - -- if (file_info->ReplaceIfExists) { -- if (file_present) { -- rc = ksmbd_vfs_remove_file(work, new_name); -- if (rc) { -- if (rc != -ENOTEMPTY) -- rc = -EINVAL; -- ksmbd_debug(SMB, "cannot delete %s, rc %d\n", -- new_name, rc); -- goto out; -- } -- } -- } else { -- if (file_present && -- strncmp(old_name, path.dentry->d_name.name, strlen(old_name))) { -- rc = -EEXIST; -- ksmbd_debug(SMB, -- "cannot rename already existing file\n"); -- goto out; -- } -- } -+ if (!file_info->ReplaceIfExists) -+ flags = RENAME_NOREPLACE; - -- rc = ksmbd_vfs_fp_rename(work, fp, new_name); -+ rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags); - out: -- kfree(pathname); -- if (!IS_ERR(new_name)) -- kfree(new_name); -+ kfree(new_name); - return rc; - } - -@@ -5624,8 +5581,8 @@ static int smb2_create_link(struct ksmbd_work *work, - struct nls_table *local_nls) - { - char *link_name = NULL, *target_name = NULL, *pathname = NULL; -- struct path path; -- bool file_present = true; -+ struct path path, parent_path; -+ bool file_present = false; - int rc; - - if (buf_len < (u64)sizeof(struct smb2_file_link_info) + -@@ -5653,18 +5610,17 @@ static int smb2_create_link(struct ksmbd_work *work, - } - - ksmbd_debug(SMB, "target name is %s\n", target_name); -- rc = ksmbd_vfs_kern_path(work, link_name, LOOKUP_NO_SYMLINKS, &path, 0); -+ rc = ksmbd_vfs_kern_path_locked(work, link_name, LOOKUP_NO_SYMLINKS, -+ &parent_path, &path, 0); - if (rc) { - if (rc != -ENOENT) - goto out; -- file_present = false; -- } else { -- path_put(&path); -- } -+ } else -+ file_present = true; - - if (file_info->ReplaceIfExists) { - if (file_present) { -- rc = ksmbd_vfs_remove_file(work, link_name); -+ rc = ksmbd_vfs_remove_file(work, &path); - if (rc) { - rc = -EINVAL; - ksmbd_debug(SMB, "cannot delete %s\n", -@@ -5684,6 +5640,9 @@ static int smb2_create_link(struct ksmbd_work *work, - if (rc) - rc = -EINVAL; - out: -+ if (file_present) -+ ksmbd_vfs_kern_path_unlock(&parent_path, &path); -+ - if (!IS_ERR(link_name)) - kfree(link_name); - kfree(pathname); -@@ -5750,8 +5709,8 @@ static int set_file_basic_info(struct ksmbd_file *fp, - da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME | - XATTR_DOSINFO_ITIME; - -- rc = ksmbd_vfs_set_dos_attrib_xattr(user_ns, -- filp->f_path.dentry, &da); -+ rc = ksmbd_vfs_set_dos_attrib_xattr(user_ns, &filp->f_path, &da, -+ true); - if (rc) - ksmbd_debug(SMB, - "failed to restore file attribute in EA\n"); -@@ -5861,12 +5820,6 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, - struct smb2_file_rename_info *rename_info, - unsigned int buf_len) - { -- struct user_namespace *user_ns; -- struct ksmbd_file *parent_fp; -- struct dentry *parent; -- struct dentry *dentry = fp->filp->f_path.dentry; -- int ret; -- - if (!(fp->daccess & FILE_DELETE_LE)) { - pr_err("no right to delete : 0x%x\n", fp->daccess); - return -EACCES; -@@ -5876,32 +5829,10 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, - le32_to_cpu(rename_info->FileNameLength)) - return -EINVAL; - -- user_ns = file_mnt_user_ns(fp->filp); -- if (ksmbd_stream_fd(fp)) -- goto next; -- -- parent = dget_parent(dentry); -- ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry); -- if (ret) { -- dput(parent); -- return ret; -- } -- -- parent_fp = ksmbd_lookup_fd_inode(d_inode(parent)); -- inode_unlock(d_inode(parent)); -- dput(parent); -+ if (!le32_to_cpu(rename_info->FileNameLength)) -+ return -EINVAL; - -- if (parent_fp) { -- if (parent_fp->daccess & FILE_DELETE_LE) { -- pr_err("parent dir is opened with delete access\n"); -- ksmbd_fd_put(work, parent_fp); -- return -ESHARE; -- } -- ksmbd_fd_put(work, parent_fp); -- } --next: -- return smb2_rename(work, fp, user_ns, rename_info, -- work->conn->local_nls); -+ return smb2_rename(work, fp, rename_info, work->conn->local_nls); - } - - static int set_file_disposition_info(struct ksmbd_file *fp, -@@ -6091,7 +6022,7 @@ static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info, - fp->saccess |= FILE_SHARE_DELETE_LE; - - return set_info_sec(fp->conn, fp->tcon, &fp->filp->f_path, pntsd, -- buf_len, false); -+ buf_len, false, true); - } - - /** -@@ -6161,7 +6092,10 @@ int smb2_set_info(struct ksmbd_work *work) - goto err_out; - - rsp->StructureSize = cpu_to_le16(2); -- inc_rfc1001_len(work->response_buf, 2); -+ rc = ksmbd_iov_pin_rsp(work, (void *)rsp, -+ sizeof(struct smb2_set_info_rsp)); -+ if (rc) -+ goto err_out; - ksmbd_fd_put(work, fp); - return 0; - -@@ -6208,28 +6142,36 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work) - - id = req->VolatileFileId; - -- inc_rfc1001_len(work->response_buf, 16); - rpc_resp = ksmbd_rpc_read(work->sess, id); - if (rpc_resp) { -+ void *aux_payload_buf; -+ - if (rpc_resp->flags != KSMBD_RPC_OK) { - err = -EINVAL; - goto out; - } - -- work->aux_payload_buf = -- kvmalloc(rpc_resp->payload_sz, GFP_KERNEL | __GFP_ZERO); -- if (!work->aux_payload_buf) { -+ aux_payload_buf = -+ kvmalloc(rpc_resp->payload_sz, GFP_KERNEL); -+ if (!aux_payload_buf) { - err = -ENOMEM; - goto out; - } - -- memcpy(work->aux_payload_buf, rpc_resp->payload, -- rpc_resp->payload_sz); -+ memcpy(aux_payload_buf, rpc_resp->payload, rpc_resp->payload_sz); - - nbytes = rpc_resp->payload_sz; -- work->resp_hdr_sz = get_rfc1002_len(work->response_buf) + 4; -- work->aux_payload_sz = nbytes; -+ err = ksmbd_iov_pin_rsp_read(work, (void *)rsp, -+ offsetof(struct smb2_read_rsp, Buffer), -+ aux_payload_buf, nbytes); -+ if (err) -+ goto out; - kvfree(rpc_resp); -+ } else { -+ err = ksmbd_iov_pin_rsp(work, (void *)rsp, -+ offsetof(struct smb2_read_rsp, Buffer)); -+ if (err) -+ goto out; - } - - rsp->StructureSize = cpu_to_le16(17); -@@ -6238,7 +6180,6 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work) - rsp->DataLength = cpu_to_le32(nbytes); - rsp->DataRemaining = 0; - rsp->Flags = 0; -- inc_rfc1001_len(work->response_buf, nbytes); - return 0; - - out: -@@ -6312,13 +6253,8 @@ int smb2_read(struct ksmbd_work *work) - int err = 0; - bool is_rdma_channel = false; - unsigned int max_read_size = conn->vals->max_read_size; -- -- WORK_BUFFERS(work, req, rsp); -- if (work->next_smb2_rcv_hdr_off) { -- work->send_no_response = 1; -- err = -EOPNOTSUPP; -- goto out; -- } -+ unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; -+ void *aux_payload_buf; - - if (test_share_config_flag(work->tcon->share_conf, - KSMBD_SHARE_FLAG_PIPE)) { -@@ -6326,6 +6262,25 @@ int smb2_read(struct ksmbd_work *work) - return smb2_read_pipe(work); - } - -+ if (work->next_smb2_rcv_hdr_off) { -+ req = ksmbd_req_buf_next(work); -+ rsp = ksmbd_resp_buf_next(work); -+ if (!has_file_id(req->VolatileFileId)) { -+ ksmbd_debug(SMB, "Compound request set FID = %llu\n", -+ work->compound_fid); -+ id = work->compound_fid; -+ pid = work->compound_pfid; -+ } -+ } else { -+ req = smb2_get_msg(work->request_buf); -+ rsp = smb2_get_msg(work->response_buf); -+ } -+ -+ if (!has_file_id(id)) { -+ id = req->VolatileFileId; -+ pid = req->PersistentFileId; -+ } -+ - if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE || - req->Channel == SMB2_CHANNEL_RDMA_V1) { - is_rdma_channel = true; -@@ -6348,7 +6303,7 @@ int smb2_read(struct ksmbd_work *work) - goto out; - } - -- fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId); -+ fp = ksmbd_lookup_fd_slow(work, id, pid); - if (!fp) { - err = -ENOENT; - goto out; -@@ -6374,21 +6329,20 @@ int smb2_read(struct ksmbd_work *work) - ksmbd_debug(SMB, "filename %pD, offset %lld, len %zu\n", - fp->filp, offset, length); - -- work->aux_payload_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO); -- if (!work->aux_payload_buf) { -+ aux_payload_buf = kvzalloc(length, GFP_KERNEL); -+ if (!aux_payload_buf) { - err = -ENOMEM; - goto out; - } - -- nbytes = ksmbd_vfs_read(work, fp, length, &offset); -+ nbytes = ksmbd_vfs_read(work, fp, length, &offset, aux_payload_buf); - if (nbytes < 0) { - err = nbytes; - goto out; - } - - if ((nbytes == 0 && length != 0) || nbytes < mincount) { -- kvfree(work->aux_payload_buf); -- work->aux_payload_buf = NULL; -+ kvfree(aux_payload_buf); - rsp->hdr.Status = STATUS_END_OF_FILE; - smb2_set_err_rsp(work); - ksmbd_fd_put(work, fp); -@@ -6401,11 +6355,10 @@ int smb2_read(struct ksmbd_work *work) - if (is_rdma_channel == true) { - /* write data to the client using rdma channel */ - remain_bytes = smb2_read_rdma_channel(work, req, -- work->aux_payload_buf, -+ aux_payload_buf, - nbytes); -- kvfree(work->aux_payload_buf); -- work->aux_payload_buf = NULL; -- -+ kvfree(aux_payload_buf); -+ aux_payload_buf = NULL; - nbytes = 0; - if (remain_bytes < 0) { - err = (int)remain_bytes; -@@ -6419,10 +6372,11 @@ int smb2_read(struct ksmbd_work *work) - rsp->DataLength = cpu_to_le32(nbytes); - rsp->DataRemaining = cpu_to_le32(remain_bytes); - rsp->Flags = 0; -- inc_rfc1001_len(work->response_buf, 16); -- work->resp_hdr_sz = get_rfc1002_len(work->response_buf) + 4; -- work->aux_payload_sz = nbytes; -- inc_rfc1001_len(work->response_buf, nbytes); -+ err = ksmbd_iov_pin_rsp_read(work, (void *)rsp, -+ offsetof(struct smb2_read_rsp, Buffer), -+ aux_payload_buf, nbytes); -+ if (err) -+ goto out; - ksmbd_fd_put(work, fp); - return 0; - -@@ -6505,8 +6459,8 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work) - rsp->DataLength = cpu_to_le32(length); - rsp->DataRemaining = 0; - rsp->Reserved2 = 0; -- inc_rfc1001_len(work->response_buf, 16); -- return 0; -+ err = ksmbd_iov_pin_rsp(work, (void *)rsp, -+ offsetof(struct smb2_write_rsp, Buffer)); - out: - if (err) { - rsp->hdr.Status = STATUS_INVALID_HANDLE; -@@ -6525,7 +6479,7 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work, - int ret; - ssize_t nbytes; - -- data_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO); -+ data_buf = kvzalloc(length, GFP_KERNEL); - if (!data_buf) - return -ENOMEM; - -@@ -6662,7 +6616,9 @@ int smb2_write(struct ksmbd_work *work) - rsp->DataLength = cpu_to_le32(nbytes); - rsp->DataRemaining = 0; - rsp->Reserved2 = 0; -- inc_rfc1001_len(work->response_buf, 16); -+ err = ksmbd_iov_pin_rsp(work, rsp, offsetof(struct smb2_write_rsp, Buffer)); -+ if (err) -+ goto out; - ksmbd_fd_put(work, fp); - return 0; - -@@ -6709,15 +6665,11 @@ int smb2_flush(struct ksmbd_work *work) - - rsp->StructureSize = cpu_to_le16(4); - rsp->Reserved = 0; -- inc_rfc1001_len(work->response_buf, 4); -- return 0; -+ return ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_flush_rsp)); - - out: -- if (err) { -- rsp->hdr.Status = STATUS_INVALID_HANDLE; -- smb2_set_err_rsp(work); -- } -- -+ rsp->hdr.Status = STATUS_INVALID_HANDLE; -+ smb2_set_err_rsp(work); - return err; - } - -@@ -6843,7 +6795,7 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags) - case SMB2_LOCKFLAG_UNLOCK: - ksmbd_debug(SMB, "received unlock request\n"); - flock->fl_type = F_UNLCK; -- cmd = 0; -+ cmd = F_SETLK; - break; - } - -@@ -6949,6 +6901,7 @@ int smb2_lock(struct ksmbd_work *work) - if (lock_start > U64_MAX - lock_length) { - pr_err("Invalid lock range requested\n"); - rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE; -+ locks_free_lock(flock); - goto out; - } - -@@ -6968,6 +6921,7 @@ int smb2_lock(struct ksmbd_work *work) - "the end offset(%llx) is smaller than the start offset(%llx)\n", - flock->fl_end, flock->fl_start); - rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE; -+ locks_free_lock(flock); - goto out; - } - -@@ -6979,6 +6933,7 @@ int smb2_lock(struct ksmbd_work *work) - flock->fl_type != F_UNLCK) { - pr_err("conflict two locks in one request\n"); - err = -EINVAL; -+ locks_free_lock(flock); - goto out; - } - } -@@ -6987,6 +6942,7 @@ int smb2_lock(struct ksmbd_work *work) - smb_lock = smb2_lock_init(flock, cmd, flags, &lock_list); - if (!smb_lock) { - err = -EINVAL; -+ locks_free_lock(flock); - goto out; - } - } -@@ -7118,10 +7074,6 @@ skip: - - ksmbd_debug(SMB, - "would have to wait for getting lock\n"); -- spin_lock(&work->conn->llist_lock); -- list_add_tail(&smb_lock->clist, -- &work->conn->lock_list); -- spin_unlock(&work->conn->llist_lock); - list_add(&smb_lock->llist, &rollback_list); - - argv = kmalloc(sizeof(void *), GFP_KERNEL); -@@ -7147,19 +7099,12 @@ skip: - - ksmbd_vfs_posix_lock_wait(flock); - -- spin_lock(&work->conn->request_lock); - spin_lock(&fp->f_lock); - list_del(&work->fp_entry); -- work->cancel_fn = NULL; -- kfree(argv); - spin_unlock(&fp->f_lock); -- spin_unlock(&work->conn->request_lock); - - if (work->state != KSMBD_WORK_ACTIVE) { - list_del(&smb_lock->llist); -- spin_lock(&work->conn->llist_lock); -- list_del(&smb_lock->clist); -- spin_unlock(&work->conn->llist_lock); - locks_free_lock(flock); - - if (work->state == KSMBD_WORK_CANCELLED) { -@@ -7171,8 +7116,7 @@ skip: - work->send_no_response = 1; - goto out; - } -- init_smb2_rsp_hdr(work); -- smb2_set_err_rsp(work); -+ - rsp->hdr.Status = - STATUS_RANGE_NOT_LOCKED; - kfree(smb_lock); -@@ -7180,19 +7124,16 @@ skip: - } - - list_del(&smb_lock->llist); -- spin_lock(&work->conn->llist_lock); -- list_del(&smb_lock->clist); -- spin_unlock(&work->conn->llist_lock); -- -+ release_async_work(work); - goto retry; - } else if (!rc) { -+ list_add(&smb_lock->llist, &rollback_list); - spin_lock(&work->conn->llist_lock); - list_add_tail(&smb_lock->clist, - &work->conn->lock_list); - list_add_tail(&smb_lock->flist, - &fp->lock_list); - spin_unlock(&work->conn->llist_lock); -- list_add(&smb_lock->llist, &rollback_list); - ksmbd_debug(SMB, "successful in taking lock\n"); - } else { - goto out; -@@ -7207,7 +7148,10 @@ skip: - ksmbd_debug(SMB, "successful in taking lock\n"); - rsp->hdr.Status = STATUS_SUCCESS; - rsp->Reserved = 0; -- inc_rfc1001_len(work->response_buf, 4); -+ err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lock_rsp)); -+ if (err) -+ goto out; -+ - ksmbd_fd_put(work, fp); - return 0; - -@@ -7226,7 +7170,7 @@ out: - rlock->fl_start = smb_lock->start; - rlock->fl_end = smb_lock->end; - -- rc = vfs_lock_file(filp, 0, rlock, NULL); -+ rc = vfs_lock_file(filp, F_SETLK, rlock, NULL); - if (rc) - pr_err("rollback unlock fail : %d\n", rc); - -@@ -7648,7 +7592,8 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id, - - da.attr = le32_to_cpu(fp->f_ci->m_fattr); - ret = ksmbd_vfs_set_dos_attrib_xattr(user_ns, -- fp->filp->f_path.dentry, &da); -+ &fp->filp->f_path, -+ &da, true); - if (ret) - fp->f_ci->m_fattr = old_fattr; - } -@@ -8003,9 +7948,9 @@ dup_ext_out: - rsp->Reserved = cpu_to_le16(0); - rsp->Flags = cpu_to_le32(0); - rsp->Reserved2 = cpu_to_le32(0); -- inc_rfc1001_len(work->response_buf, 48 + nbytes); -- -- return 0; -+ ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_ioctl_rsp) + nbytes); -+ if (!ret) -+ return ret; - - out: - if (ret == -EACCES) -@@ -8140,8 +8085,9 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) - rsp->Reserved2 = 0; - rsp->VolatileFid = volatile_id; - rsp->PersistentFid = persistent_id; -- inc_rfc1001_len(work->response_buf, 24); -- return; -+ ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break)); -+ if (!ret) -+ return; - - err_out: - opinfo->op_state = OPLOCK_STATE_NONE; -@@ -8273,6 +8219,11 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) - le32_to_cpu(req->LeaseState)); - } - -+ if (ret < 0) { -+ rsp->hdr.Status = err; -+ goto err_out; -+ } -+ - lease_state = lease->state; - opinfo->op_state = OPLOCK_STATE_NONE; - wake_up_interruptible_all(&opinfo->oplock_q); -@@ -8280,22 +8231,17 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) - wake_up_interruptible_all(&opinfo->oplock_brk); - opinfo_put(opinfo); - -- if (ret < 0) { -- rsp->hdr.Status = err; -- goto err_out; -- } -- - rsp->StructureSize = cpu_to_le16(36); - rsp->Reserved = 0; - rsp->Flags = 0; - memcpy(rsp->LeaseKey, req->LeaseKey, 16); - rsp->LeaseState = lease_state; - rsp->LeaseDuration = 0; -- inc_rfc1001_len(work->response_buf, 36); -- return; -+ ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack)); -+ if (!ret) -+ return; - - err_out: -- opinfo->op_state = OPLOCK_STATE_NONE; - wake_up_interruptible_all(&opinfo->oplock_q); - atomic_dec(&opinfo->breaking_cnt); - wake_up_interruptible_all(&opinfo->oplock_brk); -@@ -8430,43 +8376,19 @@ int smb2_check_sign_req(struct ksmbd_work *work) - void smb2_set_sign_rsp(struct ksmbd_work *work) - { - struct smb2_hdr *hdr; -- struct smb2_hdr *req_hdr; - char signature[SMB2_HMACSHA256_SIZE]; -- struct kvec iov[2]; -- size_t len; -+ struct kvec *iov; - int n_vec = 1; - -- hdr = smb2_get_msg(work->response_buf); -- if (work->next_smb2_rsp_hdr_off) -- hdr = ksmbd_resp_buf_next(work); -- -- req_hdr = ksmbd_req_buf_next(work); -- -- if (!work->next_smb2_rsp_hdr_off) { -- len = get_rfc1002_len(work->response_buf); -- if (req_hdr->NextCommand) -- len = ALIGN(len, 8); -- } else { -- len = get_rfc1002_len(work->response_buf) - -- work->next_smb2_rsp_hdr_off; -- len = ALIGN(len, 8); -- } -- -- if (req_hdr->NextCommand) -- hdr->NextCommand = cpu_to_le32(len); -- -+ hdr = ksmbd_resp_buf_curr(work); - hdr->Flags |= SMB2_FLAGS_SIGNED; - memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE); - -- iov[0].iov_base = (char *)&hdr->ProtocolId; -- iov[0].iov_len = len; -- -- if (work->aux_payload_sz) { -- iov[0].iov_len -= work->aux_payload_sz; -- -- iov[1].iov_base = work->aux_payload_buf; -- iov[1].iov_len = work->aux_payload_sz; -+ if (hdr->Command == SMB2_READ) { -+ iov = &work->iov[work->iov_idx - 1]; - n_vec++; -+ } else { -+ iov = &work->iov[work->iov_idx]; - } - - if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec, -@@ -8542,29 +8464,14 @@ int smb3_check_sign_req(struct ksmbd_work *work) - void smb3_set_sign_rsp(struct ksmbd_work *work) - { - struct ksmbd_conn *conn = work->conn; -- struct smb2_hdr *req_hdr, *hdr; -+ struct smb2_hdr *hdr; - struct channel *chann; - char signature[SMB2_CMACAES_SIZE]; -- struct kvec iov[2]; -+ struct kvec *iov; - int n_vec = 1; -- size_t len; - char *signing_key; - -- hdr = smb2_get_msg(work->response_buf); -- if (work->next_smb2_rsp_hdr_off) -- hdr = ksmbd_resp_buf_next(work); -- -- req_hdr = ksmbd_req_buf_next(work); -- -- if (!work->next_smb2_rsp_hdr_off) { -- len = get_rfc1002_len(work->response_buf); -- if (req_hdr->NextCommand) -- len = ALIGN(len, 8); -- } else { -- len = get_rfc1002_len(work->response_buf) - -- work->next_smb2_rsp_hdr_off; -- len = ALIGN(len, 8); -- } -+ hdr = ksmbd_resp_buf_curr(work); - - if (conn->binding == false && - le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { -@@ -8580,21 +8487,18 @@ void smb3_set_sign_rsp(struct ksmbd_work *work) - if (!signing_key) - return; - -- if (req_hdr->NextCommand) -- hdr->NextCommand = cpu_to_le32(len); -- - hdr->Flags |= SMB2_FLAGS_SIGNED; - memset(hdr->Signature, 0, SMB2_SIGNATURE_SIZE); -- iov[0].iov_base = (char *)&hdr->ProtocolId; -- iov[0].iov_len = len; -- if (work->aux_payload_sz) { -- iov[0].iov_len -= work->aux_payload_sz; -- iov[1].iov_base = work->aux_payload_buf; -- iov[1].iov_len = work->aux_payload_sz; -+ -+ if (hdr->Command == SMB2_READ) { -+ iov = &work->iov[work->iov_idx - 1]; - n_vec++; -+ } else { -+ iov = &work->iov[work->iov_idx]; - } - -- if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, signature)) -+ if (!ksmbd_sign_smb3_pdu(conn, signing_key, iov, n_vec, -+ signature)) - memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE); - } - -@@ -8661,45 +8565,22 @@ static void fill_transform_hdr(void *tr_buf, char *old_buf, __le16 cipher_type) - - int smb3_encrypt_resp(struct ksmbd_work *work) - { -- char *buf = work->response_buf; -- struct kvec iov[3]; -+ struct kvec *iov = work->iov; - int rc = -ENOMEM; -- int buf_size = 0, rq_nvec = 2 + (work->aux_payload_sz ? 1 : 0); -- -- if (ARRAY_SIZE(iov) < rq_nvec) -- return -ENOMEM; -+ void *tr_buf; - -- work->tr_buf = kzalloc(sizeof(struct smb2_transform_hdr) + 4, GFP_KERNEL); -- if (!work->tr_buf) -+ tr_buf = kzalloc(sizeof(struct smb2_transform_hdr) + 4, GFP_KERNEL); -+ if (!tr_buf) - return rc; - - /* fill transform header */ -- fill_transform_hdr(work->tr_buf, buf, work->conn->cipher_type); -+ fill_transform_hdr(tr_buf, work->response_buf, work->conn->cipher_type); - -- iov[0].iov_base = work->tr_buf; -+ iov[0].iov_base = tr_buf; - iov[0].iov_len = sizeof(struct smb2_transform_hdr) + 4; -- buf_size += iov[0].iov_len - 4; -- -- iov[1].iov_base = buf + 4; -- iov[1].iov_len = get_rfc1002_len(buf); -- if (work->aux_payload_sz) { -- iov[1].iov_len = work->resp_hdr_sz - 4; -- -- iov[2].iov_base = work->aux_payload_buf; -- iov[2].iov_len = work->aux_payload_sz; -- buf_size += iov[2].iov_len; -- } -- buf_size += iov[1].iov_len; -- work->resp_hdr_sz = iov[1].iov_len; -- -- rc = ksmbd_crypt_message(work, iov, rq_nvec, 1); -- if (rc) -- return rc; -- -- memmove(buf, iov[1].iov_base, iov[1].iov_len); -- *(__be32 *)work->tr_buf = cpu_to_be32(buf_size); -+ work->tr_buf = tr_buf; - -- return rc; -+ return ksmbd_crypt_message(work, iov, work->iov_idx + 1, 1); - } - - bool smb3_is_transform_hdr(void *buf) -diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h -index 665a837378540..59e3de95961c1 100644 ---- a/fs/smb/server/smb2pdu.h -+++ b/fs/smb/server/smb2pdu.h -@@ -446,7 +446,7 @@ struct smb2_posix_info { - /* SidBuffer contain two sids (UNIX user sid(16), UNIX group sid(16)) */ - u8 SidBuffer[32]; - __le32 name_len; -- u8 name[1]; -+ u8 name[]; - /* - * var sized owner SID - * var sized group SID -@@ -488,6 +488,7 @@ int find_matching_smb2_dialect(int start_index, __le16 *cli_dialects, - struct file_lock *smb_flock_init(struct file *f); - int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), - void **arg); -+void release_async_work(struct ksmbd_work *work); - void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status); - struct channel *lookup_chann_list(struct ksmbd_session *sess, - struct ksmbd_conn *conn); -diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c -index adc41b57b84c6..d160363c09ebc 100644 ---- a/fs/smb/server/smb_common.c -+++ b/fs/smb/server/smb_common.c -@@ -266,7 +266,7 @@ static int ksmbd_negotiate_smb_dialect(void *buf) - if (smb2_neg_size > smb_buf_length) - goto err_out; - -- if (smb2_neg_size + le16_to_cpu(req->DialectCount) * sizeof(__le16) > -+ if (struct_size(req, Dialects, le16_to_cpu(req->DialectCount)) > - smb_buf_length) - goto err_out; - -@@ -319,12 +319,6 @@ static int init_smb1_rsp_hdr(struct ksmbd_work *work) - struct smb_hdr *rsp_hdr = (struct smb_hdr *)work->response_buf; - struct smb_hdr *rcv_hdr = (struct smb_hdr *)work->request_buf; - -- /* -- * Remove 4 byte direct TCP header. -- */ -- *(__be32 *)work->response_buf = -- cpu_to_be32(sizeof(struct smb_hdr) - 4); -- - rsp_hdr->Command = SMB_COM_NEGOTIATE; - *(__le32 *)rsp_hdr->Protocol = SMB1_PROTO_NUMBER; - rsp_hdr->Flags = SMBFLG_RESPONSE; -@@ -359,8 +353,8 @@ static int smb1_check_user_session(struct ksmbd_work *work) - */ - static int smb1_allocate_rsp_buf(struct ksmbd_work *work) - { -- work->response_buf = kmalloc(MAX_CIFS_SMALL_BUFFER_SIZE, -- GFP_KERNEL | __GFP_ZERO); -+ work->response_buf = kzalloc(MAX_CIFS_SMALL_BUFFER_SIZE, -+ GFP_KERNEL); - work->response_sz = MAX_CIFS_SMALL_BUFFER_SIZE; - - if (!work->response_buf) { -@@ -571,10 +565,11 @@ static int smb_handle_negotiate(struct ksmbd_work *work) - - ksmbd_debug(SMB, "Unsupported SMB1 protocol\n"); - -- /* Add 2 byte bcc and 2 byte DialectIndex. */ -- inc_rfc1001_len(work->response_buf, 4); -- neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS; -+ if (ksmbd_iov_pin_rsp(work, (void *)neg_rsp, -+ sizeof(struct smb_negotiate_rsp) - 4)) -+ return -ENOMEM; - -+ neg_rsp->hdr.Status.CifsError = STATUS_SUCCESS; - neg_rsp->hdr.WordCount = 1; - neg_rsp->DialectIndex = cpu_to_le16(work->conn->dialect); - neg_rsp->ByteCount = 0; -diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h -index 1cbb492cdefec..f1092519c0c28 100644 ---- a/fs/smb/server/smb_common.h -+++ b/fs/smb/server/smb_common.h -@@ -200,7 +200,7 @@ struct smb_hdr { - struct smb_negotiate_req { - struct smb_hdr hdr; /* wct = 0 */ - __le16 ByteCount; -- unsigned char DialectsArray[1]; -+ unsigned char DialectsArray[]; - } __packed; - - struct smb_negotiate_rsp { -@@ -263,14 +263,14 @@ struct file_directory_info { - __le64 AllocationSize; - __le32 ExtFileAttributes; - __le32 FileNameLength; -- char FileName[1]; -+ char FileName[]; - } __packed; /* level 0x101 FF resp data */ - - struct file_names_info { - __le32 NextEntryOffset; - __u32 FileIndex; - __le32 FileNameLength; -- char FileName[1]; -+ char FileName[]; - } __packed; /* level 0xc FF resp data */ - - struct file_full_directory_info { -@@ -285,7 +285,7 @@ struct file_full_directory_info { - __le32 ExtFileAttributes; - __le32 FileNameLength; - __le32 EaSize; -- char FileName[1]; -+ char FileName[]; - } __packed; /* level 0x102 FF resp */ - - struct file_both_directory_info { -@@ -303,7 +303,7 @@ struct file_both_directory_info { - __u8 ShortNameLength; - __u8 Reserved; - __u8 ShortName[24]; -- char FileName[1]; -+ char FileName[]; - } __packed; /* level 0x104 FFrsp data */ - - struct file_id_both_directory_info { -@@ -323,7 +323,7 @@ struct file_id_both_directory_info { - __u8 ShortName[24]; - __le16 Reserved2; - __le64 UniqueId; -- char FileName[1]; -+ char FileName[]; - } __packed; - - struct file_id_full_dir_info { -@@ -340,7 +340,7 @@ struct file_id_full_dir_info { - __le32 EaSize; /* EA size */ - __le32 Reserved; - __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ -- char FileName[1]; -+ char FileName[]; - } __packed; /* level 0x105 FF rsp data */ - - struct smb_version_values { -diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c -index c24df86eb112b..d9bbd2eb89c35 100644 ---- a/fs/smb/server/smbacl.c -+++ b/fs/smb/server/smbacl.c -@@ -97,7 +97,7 @@ int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid) - /* compare all of the subauth values if any */ - num_sat = ctsid->num_subauth; - num_saw = cwsid->num_subauth; -- num_subauth = num_sat < num_saw ? num_sat : num_saw; -+ num_subauth = min(num_sat, num_saw); - if (num_subauth) { - for (i = 0; i < num_subauth; ++i) { - if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) { -@@ -1185,8 +1185,7 @@ pass: - pntsd_size += sizeof(struct smb_acl) + nt_size; - } - -- ksmbd_vfs_set_sd_xattr(conn, user_ns, -- path->dentry, pntsd, pntsd_size); -+ ksmbd_vfs_set_sd_xattr(conn, user_ns, path, pntsd, pntsd_size, false); - kfree(pntsd); - } - -@@ -1313,7 +1312,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, - - if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) { - posix_acls = get_acl(d_inode(path->dentry), ACL_TYPE_ACCESS); -- if (posix_acls && !found) { -+ if (!IS_ERR_OR_NULL(posix_acls) && !found) { - unsigned int id = -1; - - pa_entry = posix_acls->a_entries; -@@ -1337,7 +1336,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, - } - } - } -- if (posix_acls) -+ if (!IS_ERR_OR_NULL(posix_acls)) - posix_acl_release(posix_acls); - } - -@@ -1378,7 +1377,7 @@ err_out: - - int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, - const struct path *path, struct smb_ntsd *pntsd, int ntsd_len, -- bool type_check) -+ bool type_check, bool get_write) - { - int rc; - struct smb_fattr fattr = {{0}}; -@@ -1406,7 +1405,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, - newattrs.ia_valid |= ATTR_MODE; - newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777); - -- ksmbd_vfs_remove_acl_xattrs(user_ns, path->dentry); -+ ksmbd_vfs_remove_acl_xattrs(user_ns, path); - /* Update posix acls */ - if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) { - rc = set_posix_acl(user_ns, inode, -@@ -1437,15 +1436,14 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, - - if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) { - /* Update WinACL in xattr */ -- ksmbd_vfs_remove_sd_xattrs(user_ns, path->dentry); -- ksmbd_vfs_set_sd_xattr(conn, user_ns, -- path->dentry, pntsd, ntsd_len); -+ ksmbd_vfs_remove_sd_xattrs(user_ns, path); -+ ksmbd_vfs_set_sd_xattr(conn, user_ns, path, pntsd, ntsd_len, -+ get_write); - } - - out: - posix_acl_release(fattr.cf_acls); - posix_acl_release(fattr.cf_dacls); -- mark_inode_dirty(inode); - return rc; - } - -diff --git a/fs/smb/server/smbacl.h b/fs/smb/server/smbacl.h -index 618f2e0236b31..9651a25518881 100644 ---- a/fs/smb/server/smbacl.h -+++ b/fs/smb/server/smbacl.h -@@ -207,7 +207,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, - __le32 *pdaccess, int uid); - int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, - const struct path *path, struct smb_ntsd *pntsd, int ntsd_len, -- bool type_check); -+ bool type_check, bool get_write); - void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); - void ksmbd_init_domain(u32 *sub_auth); - -diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c -index 40c721f9227e4..b49d47bdafc94 100644 ---- a/fs/smb/server/transport_ipc.c -+++ b/fs/smb/server/transport_ipc.c -@@ -229,7 +229,7 @@ static struct ksmbd_ipc_msg *ipc_msg_alloc(size_t sz) - struct ksmbd_ipc_msg *msg; - size_t msg_sz = sz + sizeof(struct ksmbd_ipc_msg); - -- msg = kvmalloc(msg_sz, GFP_KERNEL | __GFP_ZERO); -+ msg = kvzalloc(msg_sz, GFP_KERNEL); - if (msg) - msg->sz = sz; - return msg; -@@ -268,7 +268,7 @@ static int handle_response(int type, void *payload, size_t sz) - entry->type + 1, type); - } - -- entry->response = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO); -+ entry->response = kvzalloc(sz, GFP_KERNEL); - if (!entry->response) { - ret = -ENOMEM; - break; -diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c -index 7578200f63b1d..c5629a68c8b73 100644 ---- a/fs/smb/server/transport_rdma.c -+++ b/fs/smb/server/transport_rdma.c -@@ -1241,14 +1241,12 @@ static int smb_direct_writev(struct ksmbd_transport *t, - - //FIXME: skip RFC1002 header.. - buflen -= 4; -- iov[0].iov_base += 4; -- iov[0].iov_len -= 4; - - remaining_data_length = buflen; - ksmbd_debug(RDMA, "Sending smb (RDMA): smb_len=%u\n", buflen); - - smb_direct_send_ctx_init(st, &send_ctx, need_invalidate, remote_key); -- start = i = 0; -+ start = i = 1; - buflen = 0; - while (true) { - buflen += iov[i].iov_len; -@@ -2142,8 +2140,7 @@ static int smb_direct_ib_client_add(struct ib_device *ib_dev) - if (ib_dev->node_type != RDMA_NODE_IB_CA) - smb_direct_port = SMB_DIRECT_PORT_IWARP; - -- if (!ib_dev->ops.get_netdev || -- !rdma_frwr_is_supported(&ib_dev->attrs)) -+ if (!rdma_frwr_is_supported(&ib_dev->attrs)) - return 0; - - smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL); -@@ -2243,17 +2240,38 @@ bool ksmbd_rdma_capable_netdev(struct net_device *netdev) - for (i = 0; i < smb_dev->ib_dev->phys_port_cnt; i++) { - struct net_device *ndev; - -- ndev = smb_dev->ib_dev->ops.get_netdev(smb_dev->ib_dev, -- i + 1); -- if (!ndev) -- continue; -+ if (smb_dev->ib_dev->ops.get_netdev) { -+ ndev = smb_dev->ib_dev->ops.get_netdev( -+ smb_dev->ib_dev, i + 1); -+ if (!ndev) -+ continue; - -- if (ndev == netdev) { -+ if (ndev == netdev) { -+ dev_put(ndev); -+ rdma_capable = true; -+ goto out; -+ } - dev_put(ndev); -- rdma_capable = true; -- goto out; -+ /* if ib_dev does not implement ops.get_netdev -+ * check for matching infiniband GUID in hw_addr -+ */ -+ } else if (netdev->type == ARPHRD_INFINIBAND) { -+ struct netdev_hw_addr *ha; -+ union ib_gid gid; -+ u32 port_num; -+ int ret; -+ -+ netdev_hw_addr_list_for_each( -+ ha, &netdev->dev_addrs) { -+ memcpy(&gid, ha->addr + 4, sizeof(gid)); -+ ret = ib_find_gid(smb_dev->ib_dev, &gid, -+ &port_num, NULL); -+ if (!ret) { -+ rdma_capable = true; -+ goto out; -+ } -+ } - } -- dev_put(ndev); - } - } - out: -diff --git a/fs/smb/server/unicode.c b/fs/smb/server/unicode.c -index a0db699ddafda..33fc6d45c0f38 100644 ---- a/fs/smb/server/unicode.c -+++ b/fs/smb/server/unicode.c -@@ -14,46 +14,10 @@ - #include "uniupr.h" - #include "smb_common.h" - --/* -- * smb_utf16_bytes() - how long will a string be after conversion? -- * @from: pointer to input string -- * @maxbytes: don't go past this many bytes of input string -- * @codepage: destination codepage -- * -- * Walk a utf16le string and return the number of bytes that the string will -- * be after being converted to the given charset, not including any null -- * termination required. Don't walk past maxbytes in the source buffer. -- * -- * Return: string length after conversion -- */ --static int smb_utf16_bytes(const __le16 *from, int maxbytes, -- const struct nls_table *codepage) --{ -- int i; -- int charlen, outlen = 0; -- int maxwords = maxbytes / 2; -- char tmp[NLS_MAX_CHARSET_SIZE]; -- __u16 ftmp; -- -- for (i = 0; i < maxwords; i++) { -- ftmp = get_unaligned_le16(&from[i]); -- if (ftmp == 0) -- break; -- -- charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE); -- if (charlen > 0) -- outlen += charlen; -- else -- outlen++; -- } -- -- return outlen; --} -- - /* - * cifs_mapchar() - convert a host-endian char to proper char in codepage - * @target: where converted character should be copied -- * @src_char: 2 byte host-endian source character -+ * @from: host-endian source string - * @cp: codepage to which character should be converted - * @mapchar: should character be mapped according to mapchars mount option? - * -@@ -64,10 +28,13 @@ static int smb_utf16_bytes(const __le16 *from, int maxbytes, - * Return: string length after conversion - */ - static int --cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, -+cifs_mapchar(char *target, const __u16 *from, const struct nls_table *cp, - bool mapchar) - { - int len = 1; -+ __u16 src_char; -+ -+ src_char = *from; - - if (!mapchar) - goto cp_convert; -@@ -105,30 +72,66 @@ out: - - cp_convert: - len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE); -- if (len <= 0) { -- *target = '?'; -- len = 1; -- } -+ if (len <= 0) -+ goto surrogate_pair; -+ -+ goto out; -+ -+surrogate_pair: -+ /* convert SURROGATE_PAIR and IVS */ -+ if (strcmp(cp->charset, "utf8")) -+ goto unknown; -+ len = utf16s_to_utf8s(from, 3, UTF16_LITTLE_ENDIAN, target, 6); -+ if (len <= 0) -+ goto unknown; -+ return len; - -+unknown: -+ *target = '?'; -+ len = 1; - goto out; - } - - /* -- * is_char_allowed() - check for valid character -- * @ch: input character to be checked -+ * smb_utf16_bytes() - compute converted string length -+ * @from: pointer to input string -+ * @maxbytes: input string length -+ * @codepage: destination codepage -+ * -+ * Walk a utf16le string and return the number of bytes that the string will -+ * be after being converted to the given charset, not including any null -+ * termination required. Don't walk past maxbytes in the source buffer. - * -- * Return: 1 if char is allowed, otherwise 0 -+ * Return: string length after conversion - */ --static inline int is_char_allowed(char *ch) -+static int smb_utf16_bytes(const __le16 *from, int maxbytes, -+ const struct nls_table *codepage) - { -- /* check for control chars, wildcards etc. */ -- if (!(*ch & 0x80) && -- (*ch <= 0x1f || -- *ch == '?' || *ch == '"' || *ch == '<' || -- *ch == '>' || *ch == '|')) -- return 0; -- -- return 1; -+ int i, j; -+ int charlen, outlen = 0; -+ int maxwords = maxbytes / 2; -+ char tmp[NLS_MAX_CHARSET_SIZE]; -+ __u16 ftmp[3]; -+ -+ for (i = 0; i < maxwords; i++) { -+ ftmp[0] = get_unaligned_le16(&from[i]); -+ if (ftmp[0] == 0) -+ break; -+ for (j = 1; j <= 2; j++) { -+ if (i + j < maxwords) -+ ftmp[j] = get_unaligned_le16(&from[i + j]); -+ else -+ ftmp[j] = 0; -+ } -+ -+ charlen = cifs_mapchar(tmp, ftmp, codepage, 0); -+ if (charlen > 0) -+ outlen += charlen; -+ else -+ outlen++; -+ } -+ -+ return outlen; - } - - /* -@@ -158,12 +161,12 @@ static inline int is_char_allowed(char *ch) - static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, - const struct nls_table *codepage, bool mapchar) - { -- int i, charlen, safelen; -+ int i, j, charlen, safelen; - int outlen = 0; - int nullsize = nls_nullsize(codepage); - int fromwords = fromlen / 2; - char tmp[NLS_MAX_CHARSET_SIZE]; -- __u16 ftmp; -+ __u16 ftmp[3]; /* ftmp[3] = 3array x 2bytes = 6bytes UTF-16 */ - - /* - * because the chars can be of varying widths, we need to take care -@@ -174,9 +177,15 @@ static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, - safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize); - - for (i = 0; i < fromwords; i++) { -- ftmp = get_unaligned_le16(&from[i]); -- if (ftmp == 0) -+ ftmp[0] = get_unaligned_le16(&from[i]); -+ if (ftmp[0] == 0) - break; -+ for (j = 1; j <= 2; j++) { -+ if (i + j < fromwords) -+ ftmp[j] = get_unaligned_le16(&from[i + j]); -+ else -+ ftmp[j] = 0; -+ } - - /* - * check to see if converting this character might make the -@@ -191,6 +200,19 @@ static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, - /* put converted char into 'to' buffer */ - charlen = cifs_mapchar(&to[outlen], ftmp, codepage, mapchar); - outlen += charlen; -+ -+ /* -+ * charlen (=bytes of UTF-8 for 1 character) -+ * 4bytes UTF-8(surrogate pair) is charlen=4 -+ * (4bytes UTF-16 code) -+ * 7-8bytes UTF-8(IVS) is charlen=3+4 or 4+4 -+ * (2 UTF-8 pairs divided to 2 UTF-16 pairs) -+ */ -+ if (charlen == 4) -+ i++; -+ else if (charlen >= 5) -+ /* 5-6bytes UTF-8 */ -+ i += 2; - } - - /* properly null-terminate string */ -@@ -325,6 +347,9 @@ int smbConvertToUTF16(__le16 *target, const char *source, int srclen, - char src_char; - __le16 dst_char; - wchar_t tmp; -+ wchar_t wchar_to[6]; /* UTF-16 */ -+ int ret; -+ unicode_t u; - - if (!mapchars) - return smb_strtoUTF16(target, source, srclen, cp); -@@ -367,11 +392,57 @@ int smbConvertToUTF16(__le16 *target, const char *source, int srclen, - * if no match, use question mark, which at least in - * some cases serves as wild card - */ -- if (charlen < 1) { -- dst_char = cpu_to_le16(0x003f); -- charlen = 1; -+ if (charlen > 0) -+ goto ctoUTF16; -+ -+ /* convert SURROGATE_PAIR */ -+ if (strcmp(cp->charset, "utf8")) -+ goto unknown; -+ if (*(source + i) & 0x80) { -+ charlen = utf8_to_utf32(source + i, 6, &u); -+ if (charlen < 0) -+ goto unknown; -+ } else -+ goto unknown; -+ ret = utf8s_to_utf16s(source + i, charlen, -+ UTF16_LITTLE_ENDIAN, -+ wchar_to, 6); -+ if (ret < 0) -+ goto unknown; -+ -+ i += charlen; -+ dst_char = cpu_to_le16(*wchar_to); -+ if (charlen <= 3) -+ /* 1-3bytes UTF-8 to 2bytes UTF-16 */ -+ put_unaligned(dst_char, &target[j]); -+ else if (charlen == 4) { -+ /* -+ * 4bytes UTF-8(surrogate pair) to 4bytes UTF-16 -+ * 7-8bytes UTF-8(IVS) divided to 2 UTF-16 -+ * (charlen=3+4 or 4+4) -+ */ -+ put_unaligned(dst_char, &target[j]); -+ dst_char = cpu_to_le16(*(wchar_to + 1)); -+ j++; -+ put_unaligned(dst_char, &target[j]); -+ } else if (charlen >= 5) { -+ /* 5-6bytes UTF-8 to 6bytes UTF-16 */ -+ put_unaligned(dst_char, &target[j]); -+ dst_char = cpu_to_le16(*(wchar_to + 1)); -+ j++; -+ put_unaligned(dst_char, &target[j]); -+ dst_char = cpu_to_le16(*(wchar_to + 2)); -+ j++; -+ put_unaligned(dst_char, &target[j]); - } -+ continue; -+ -+unknown: -+ dst_char = cpu_to_le16(0x003f); -+ charlen = 1; - } -+ -+ctoUTF16: - /* - * character may take more than one byte in the source string, - * but will take exactly two bytes in the target string -diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c -index 36914db8b6616..fe2c80ea2e47e 100644 ---- a/fs/smb/server/vfs.c -+++ b/fs/smb/server/vfs.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - #include "../../internal.h" /* for vfs_path_lookup */ - -@@ -36,19 +37,6 @@ - #include "mgmt/user_session.h" - #include "mgmt/user_config.h" - --static char *extract_last_component(char *path) --{ -- char *p = strrchr(path, '/'); -- -- if (p && p[1] != '\0') { -- *p = '\0'; -- p++; -- } else { -- p = NULL; -- } -- return p; --} -- - static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work, - struct inode *parent_inode, - struct inode *inode) -@@ -62,67 +50,96 @@ static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work, - - /** - * ksmbd_vfs_lock_parent() - lock parent dentry if it is stable -- * -- * the parent dentry got by dget_parent or @parent could be -- * unstable, we try to lock a parent inode and lookup the -- * child dentry again. -- * -- * the reference count of @parent isn't incremented. - */ --int ksmbd_vfs_lock_parent(struct user_namespace *user_ns, struct dentry *parent, -- struct dentry *child) -+int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child) - { -- struct dentry *dentry; -- int ret = 0; -- - inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); -- dentry = lookup_one(user_ns, child->d_name.name, parent, -- child->d_name.len); -- if (IS_ERR(dentry)) { -- ret = PTR_ERR(dentry); -- goto out_err; -- } -- -- if (dentry != child) { -- ret = -ESTALE; -- dput(dentry); -- goto out_err; -+ if (child->d_parent != parent) { -+ inode_unlock(d_inode(parent)); -+ return -ENOENT; - } - -- dput(dentry); - return 0; --out_err: -- inode_unlock(d_inode(parent)); -- return ret; - } - --int ksmbd_vfs_may_delete(struct user_namespace *user_ns, -- struct dentry *dentry) -+static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf, -+ char *pathname, unsigned int flags, -+ struct path *parent_path, -+ struct path *path) - { -- struct dentry *parent; -- int ret; -+ struct qstr last; -+ struct filename *filename; -+ struct path *root_share_path = &share_conf->vfs_path; -+ int err, type; -+ struct dentry *d; -+ -+ if (pathname[0] == '\0') { -+ pathname = share_conf->path; -+ root_share_path = NULL; -+ } else { -+ flags |= LOOKUP_BENEATH; -+ } -+ -+ filename = getname_kernel(pathname); -+ if (IS_ERR(filename)) -+ return PTR_ERR(filename); - -- parent = dget_parent(dentry); -- ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry); -- if (ret) { -- dput(parent); -- return ret; -+ err = vfs_path_parent_lookup(filename, flags, -+ parent_path, &last, &type, -+ root_share_path); -+ if (err) { -+ putname(filename); -+ return err; - } - -- ret = inode_permission(user_ns, d_inode(parent), -- MAY_EXEC | MAY_WRITE); -+ if (unlikely(type != LAST_NORM)) { -+ path_put(parent_path); -+ putname(filename); -+ return -ENOENT; -+ } - -- inode_unlock(d_inode(parent)); -- dput(parent); -- return ret; -+ err = mnt_want_write(parent_path->mnt); -+ if (err) { -+ path_put(parent_path); -+ putname(filename); -+ return -ENOENT; -+ } -+ -+ inode_lock_nested(parent_path->dentry->d_inode, I_MUTEX_PARENT); -+ d = lookup_one_qstr_excl(&last, parent_path->dentry, 0); -+ if (IS_ERR(d)) -+ goto err_out; -+ -+ if (d_is_negative(d)) { -+ dput(d); -+ goto err_out; -+ } -+ -+ path->dentry = d; -+ path->mnt = mntget(parent_path->mnt); -+ -+ if (test_share_config_flag(share_conf, KSMBD_SHARE_FLAG_CROSSMNT)) { -+ err = follow_down(path); -+ if (err < 0) { -+ path_put(path); -+ goto err_out; -+ } -+ } -+ -+ putname(filename); -+ return 0; -+ -+err_out: -+ inode_unlock(d_inode(parent_path->dentry)); -+ mnt_drop_write(parent_path->mnt); -+ path_put(parent_path); -+ putname(filename); -+ return -ENOENT; - } - --int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns, -+void ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns, - struct dentry *dentry, __le32 *daccess) - { -- struct dentry *parent; -- int ret = 0; -- - *daccess = cpu_to_le32(FILE_READ_ATTRIBUTES | READ_CONTROL); - - if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_WRITE)) -@@ -137,19 +154,8 @@ int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns, - if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_EXEC)) - *daccess |= FILE_EXECUTE_LE; - -- parent = dget_parent(dentry); -- ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry); -- if (ret) { -- dput(parent); -- return ret; -- } -- -- if (!inode_permission(user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE)) -+ if (!inode_permission(user_ns, d_inode(dentry->d_parent), MAY_EXEC | MAY_WRITE)) - *daccess |= FILE_DELETE_LE; -- -- inode_unlock(d_inode(parent)); -- dput(parent); -- return ret; - } - - /** -@@ -185,6 +191,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode) - } else { - pr_err("File(%s): creation failed (err:%d)\n", name, err); - } -+ - done_path_create(&path, dentry); - return err; - } -@@ -218,27 +225,26 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) - user_ns = mnt_user_ns(path.mnt); - mode |= S_IFDIR; - err = vfs_mkdir(user_ns, d_inode(path.dentry), dentry, mode); -- if (err) { -- goto out; -- } else if (d_unhashed(dentry)) { -+ if (!err && d_unhashed(dentry)) { - struct dentry *d; - - d = lookup_one(user_ns, dentry->d_name.name, dentry->d_parent, - dentry->d_name.len); - if (IS_ERR(d)) { - err = PTR_ERR(d); -- goto out; -+ goto out_err; - } - if (unlikely(d_is_negative(d))) { - dput(d); - err = -ENOENT; -- goto out; -+ goto out_err; - } - - ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(d)); - dput(d); - } --out: -+ -+out_err: - done_path_create(&path, dentry); - if (err) - pr_err("mkdir(%s): creation failed (err:%d)\n", name, err); -@@ -358,15 +364,15 @@ out: - * @fid: file id of open file - * @count: read byte count - * @pos: file pos -+ * @rbuf: read data buffer - * - * Return: number of read bytes on success, otherwise error - */ - int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, -- loff_t *pos) -+ loff_t *pos, char *rbuf) - { - struct file *filp = fp->filp; - ssize_t nbytes = 0; -- char *rbuf = work->aux_payload_buf; - struct inode *inode = file_inode(filp); - - if (S_ISDIR(inode->i_mode)) -@@ -410,7 +416,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, - { - char *stream_buf = NULL, *wbuf; - struct user_namespace *user_ns = file_mnt_user_ns(fp->filp); -- size_t size, v_len; -+ size_t size; -+ ssize_t v_len; - int err = 0; - - ksmbd_debug(VFS, "write stream data pos : %llu, count : %zd\n", -@@ -427,14 +434,14 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, - fp->stream.name, - fp->stream.size, - &stream_buf); -- if ((int)v_len < 0) { -+ if (v_len < 0) { - pr_err("not found stream in xattr : %zd\n", v_len); -- err = (int)v_len; -+ err = v_len; - goto out; - } - - if (v_len < size) { -- wbuf = kvmalloc(size, GFP_KERNEL | __GFP_ZERO); -+ wbuf = kvzalloc(size, GFP_KERNEL); - if (!wbuf) { - err = -ENOMEM; - goto out; -@@ -449,11 +456,12 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, - memcpy(&stream_buf[*pos], buf, count); - - err = ksmbd_vfs_setxattr(user_ns, -- fp->filp->f_path.dentry, -+ &fp->filp->f_path, - fp->stream.name, - (void *)stream_buf, - size, -- 0); -+ 0, -+ true); - if (err < 0) - goto out; - -@@ -510,6 +518,9 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, - } - } - -+ /* Reserve lease break for parent dir at closing time */ -+ fp->reserve_lease_break = true; -+ - /* Do we need to break any of a levelII oplock? */ - smb_break_all_levII_oplock(work, fp, 1); - -@@ -581,54 +592,32 @@ int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id) - * - * Return: 0 on success, otherwise error - */ --int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name) -+int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path) - { - struct user_namespace *user_ns; -- struct path path; -- struct dentry *parent; -+ struct dentry *parent = path->dentry->d_parent; - int err; - - if (ksmbd_override_fsids(work)) - return -ENOMEM; - -- err = ksmbd_vfs_kern_path(work, name, LOOKUP_NO_SYMLINKS, &path, false); -- if (err) { -- ksmbd_debug(VFS, "can't get %s, err %d\n", name, err); -- ksmbd_revert_fsids(work); -- return err; -- } -- -- user_ns = mnt_user_ns(path.mnt); -- parent = dget_parent(path.dentry); -- err = ksmbd_vfs_lock_parent(user_ns, parent, path.dentry); -- if (err) { -- dput(parent); -- path_put(&path); -- ksmbd_revert_fsids(work); -- return err; -- } -- -- if (!d_inode(path.dentry)->i_nlink) { -+ if (!d_inode(path->dentry)->i_nlink) { - err = -ENOENT; - goto out_err; - } - -- if (S_ISDIR(d_inode(path.dentry)->i_mode)) { -- err = vfs_rmdir(user_ns, d_inode(parent), path.dentry); -+ user_ns = mnt_user_ns(path->mnt); -+ if (S_ISDIR(d_inode(path->dentry)->i_mode)) { -+ err = vfs_rmdir(user_ns, d_inode(parent), path->dentry); - if (err && err != -ENOTEMPTY) -- ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name, -- err); -+ ksmbd_debug(VFS, "rmdir failed, err %d\n", err); - } else { -- err = vfs_unlink(user_ns, d_inode(parent), path.dentry, NULL); -+ err = vfs_unlink(user_ns, d_inode(parent), path->dentry, NULL); - if (err) -- ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name, -- err); -+ ksmbd_debug(VFS, "unlink failed, err %d\n", err); - } - - out_err: -- inode_unlock(d_inode(parent)); -- dput(parent); -- path_put(&path); - ksmbd_revert_fsids(work); - return err; - } -@@ -687,149 +676,120 @@ out1: - return err; - } - --static int ksmbd_validate_entry_in_use(struct dentry *src_dent) -+int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path, -+ char *newname, int flags) - { -- struct dentry *dst_dent; -+ struct dentry *old_parent, *new_dentry, *trap; -+ struct dentry *old_child = old_path->dentry; -+ struct path new_path; -+ struct qstr new_last; -+ struct renamedata rd; -+ struct filename *to; -+ struct ksmbd_share_config *share_conf = work->tcon->share_conf; -+ struct ksmbd_file *parent_fp; -+ int new_type; -+ int err, lookup_flags = LOOKUP_NO_SYMLINKS; -+ -+ if (ksmbd_override_fsids(work)) -+ return -ENOMEM; - -- spin_lock(&src_dent->d_lock); -- list_for_each_entry(dst_dent, &src_dent->d_subdirs, d_child) { -- struct ksmbd_file *child_fp; -+ to = getname_kernel(newname); -+ if (IS_ERR(to)) { -+ err = PTR_ERR(to); -+ goto revert_fsids; -+ } - -- if (d_really_is_negative(dst_dent)) -- continue; -+retry: -+ err = vfs_path_parent_lookup(to, lookup_flags | LOOKUP_BENEATH, -+ &new_path, &new_last, &new_type, -+ &share_conf->vfs_path); -+ if (err) -+ goto out1; - -- child_fp = ksmbd_lookup_fd_inode(d_inode(dst_dent)); -- if (child_fp) { -- spin_unlock(&src_dent->d_lock); -- ksmbd_debug(VFS, "Forbid rename, sub file/dir is in use\n"); -- return -EACCES; -- } -+ if (old_path->mnt != new_path.mnt) { -+ err = -EXDEV; -+ goto out2; - } -- spin_unlock(&src_dent->d_lock); - -- return 0; --} -+ err = mnt_want_write(old_path->mnt); -+ if (err) -+ goto out2; - --static int __ksmbd_vfs_rename(struct ksmbd_work *work, -- struct user_namespace *src_user_ns, -- struct dentry *src_dent_parent, -- struct dentry *src_dent, -- struct user_namespace *dst_user_ns, -- struct dentry *dst_dent_parent, -- struct dentry *trap_dent, -- char *dst_name) --{ -- struct dentry *dst_dent; -- int err; -+ trap = lock_rename_child(old_child, new_path.dentry); - -- if (!work->tcon->posix_extensions) { -- err = ksmbd_validate_entry_in_use(src_dent); -- if (err) -- return err; -+ old_parent = dget(old_child->d_parent); -+ if (d_unhashed(old_child)) { -+ err = -EINVAL; -+ goto out3; - } - -- if (d_really_is_negative(src_dent_parent)) -- return -ENOENT; -- if (d_really_is_negative(dst_dent_parent)) -- return -ENOENT; -- if (d_really_is_negative(src_dent)) -- return -ENOENT; -- if (src_dent == trap_dent) -- return -EINVAL; -- -- if (ksmbd_override_fsids(work)) -- return -ENOMEM; -+ parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent); -+ if (parent_fp) { -+ if (parent_fp->daccess & FILE_DELETE_LE) { -+ pr_err("parent dir is opened with delete access\n"); -+ err = -ESHARE; -+ ksmbd_fd_put(work, parent_fp); -+ goto out3; -+ } -+ ksmbd_fd_put(work, parent_fp); -+ } - -- dst_dent = lookup_one(dst_user_ns, dst_name, dst_dent_parent, -- strlen(dst_name)); -- err = PTR_ERR(dst_dent); -- if (IS_ERR(dst_dent)) { -- pr_err("lookup failed %s [%d]\n", dst_name, err); -- goto out; -+ new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry, -+ lookup_flags | LOOKUP_RENAME_TARGET); -+ if (IS_ERR(new_dentry)) { -+ err = PTR_ERR(new_dentry); -+ goto out3; - } - -- err = -ENOTEMPTY; -- if (dst_dent != trap_dent && !d_really_is_positive(dst_dent)) { -- struct renamedata rd = { -- .old_mnt_userns = src_user_ns, -- .old_dir = d_inode(src_dent_parent), -- .old_dentry = src_dent, -- .new_mnt_userns = dst_user_ns, -- .new_dir = d_inode(dst_dent_parent), -- .new_dentry = dst_dent, -- }; -- err = vfs_rename(&rd); -+ if (d_is_symlink(new_dentry)) { -+ err = -EACCES; -+ goto out4; - } -- if (err) -- pr_err("vfs_rename failed err %d\n", err); -- if (dst_dent) -- dput(dst_dent); --out: -- ksmbd_revert_fsids(work); -- return err; --} - --int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, -- char *newname) --{ -- struct user_namespace *user_ns; -- struct path dst_path; -- struct dentry *src_dent_parent, *dst_dent_parent; -- struct dentry *src_dent, *trap_dent, *src_child; -- char *dst_name; -- int err; -+ if ((flags & RENAME_NOREPLACE) && d_is_positive(new_dentry)) { -+ err = -EEXIST; -+ goto out4; -+ } - -- dst_name = extract_last_component(newname); -- if (!dst_name) { -- dst_name = newname; -- newname = ""; -+ if (old_child == trap) { -+ err = -EINVAL; -+ goto out4; - } - -- src_dent_parent = dget_parent(fp->filp->f_path.dentry); -- src_dent = fp->filp->f_path.dentry; -+ if (new_dentry == trap) { -+ err = -ENOTEMPTY; -+ goto out4; -+ } -+ -+ rd.old_mnt_userns = mnt_user_ns(old_path->mnt), -+ rd.old_dir = d_inode(old_parent), -+ rd.old_dentry = old_child, -+ rd.new_mnt_userns = mnt_user_ns(new_path.mnt), -+ rd.new_dir = new_path.dentry->d_inode, -+ rd.new_dentry = new_dentry, -+ rd.flags = flags, -+ rd.delegated_inode = NULL, -+ err = vfs_rename(&rd); -+ if (err) -+ ksmbd_debug(VFS, "vfs_rename failed err %d\n", err); - -- err = ksmbd_vfs_kern_path(work, newname, -- LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY, -- &dst_path, false); -- if (err) { -- ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err); -- goto out; -+out4: -+ dput(new_dentry); -+out3: -+ dput(old_parent); -+ unlock_rename(old_parent, new_path.dentry); -+ mnt_drop_write(old_path->mnt); -+out2: -+ path_put(&new_path); -+ -+ if (retry_estale(err, lookup_flags)) { -+ lookup_flags |= LOOKUP_REVAL; -+ goto retry; - } -- dst_dent_parent = dst_path.dentry; -- -- trap_dent = lock_rename(src_dent_parent, dst_dent_parent); -- dget(src_dent); -- dget(dst_dent_parent); -- user_ns = file_mnt_user_ns(fp->filp); -- src_child = lookup_one(user_ns, src_dent->d_name.name, src_dent_parent, -- src_dent->d_name.len); -- if (IS_ERR(src_child)) { -- err = PTR_ERR(src_child); -- goto out_lock; -- } -- -- if (src_child != src_dent) { -- err = -ESTALE; -- dput(src_child); -- goto out_lock; -- } -- dput(src_child); -- -- err = __ksmbd_vfs_rename(work, -- user_ns, -- src_dent_parent, -- src_dent, -- mnt_user_ns(dst_path.mnt), -- dst_dent_parent, -- trap_dent, -- dst_name); --out_lock: -- dput(src_dent); -- dput(dst_dent_parent); -- unlock_rename(src_dent_parent, dst_dent_parent); -- path_put(&dst_path); --out: -- dput(src_dent_parent); -+out1: -+ putname(to); -+revert_fsids: -+ ksmbd_revert_fsids(work); - return err; - } - -@@ -892,7 +852,7 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list) - if (size <= 0) - return size; - -- vlist = kvmalloc(size, GFP_KERNEL | __GFP_ZERO); -+ vlist = kvzalloc(size, GFP_KERNEL); - if (!vlist) - return -ENOMEM; - -@@ -950,28 +910,38 @@ ssize_t ksmbd_vfs_getxattr(struct user_namespace *user_ns, - /** - * ksmbd_vfs_setxattr() - vfs helper for smb set extended attributes value - * @user_ns: user namespace -- * @dentry: dentry to set XATTR at -- * @name: xattr name for setxattr -- * @value: xattr value to set -- * @size: size of xattr value -+ * @path: path of dentry to set XATTR at -+ * @attr_name: xattr name for setxattr -+ * @attr_value: xattr value to set -+ * @attr_size: size of xattr value - * @flags: destination buffer length -+ * @get_write: get write access to a mount - * - * Return: 0 on success, otherwise error - */ - int ksmbd_vfs_setxattr(struct user_namespace *user_ns, -- struct dentry *dentry, const char *attr_name, -- void *attr_value, size_t attr_size, int flags) -+ const struct path *path, const char *attr_name, -+ void *attr_value, size_t attr_size, int flags, -+ bool get_write) - { - int err; - -+ if (get_write == true) { -+ err = mnt_want_write(path->mnt); -+ if (err) -+ return err; -+ } -+ - err = vfs_setxattr(user_ns, -- dentry, -+ path->dentry, - attr_name, - attr_value, - attr_size, - flags); - if (err) - ksmbd_debug(VFS, "setxattr failed, err %d\n", err); -+ if (get_write == true) -+ mnt_drop_write(path->mnt); - return err; - } - -@@ -1075,19 +1045,34 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, - } - - int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns, -- struct dentry *dentry, char *attr_name) -+ const struct path *path, char *attr_name) - { -- return vfs_removexattr(user_ns, dentry, attr_name); -+ int err; -+ -+ err = mnt_want_write(path->mnt); -+ if (err) -+ return err; -+ -+ err = vfs_removexattr(user_ns, path->dentry, attr_name); -+ mnt_drop_write(path->mnt); -+ -+ return err; - } - --int ksmbd_vfs_unlink(struct user_namespace *user_ns, -- struct dentry *dir, struct dentry *dentry) -+int ksmbd_vfs_unlink(struct file *filp) - { - int err = 0; -+ struct dentry *dir, *dentry = filp->f_path.dentry; -+ struct user_namespace *user_ns = file_mnt_user_ns(filp); - -- err = ksmbd_vfs_lock_parent(user_ns, dir, dentry); -+ err = mnt_want_write(filp->f_path.mnt); - if (err) - return err; -+ -+ dir = dget_parent(dentry); -+ err = ksmbd_vfs_lock_parent(dir, dentry); -+ if (err) -+ goto out; - dget(dentry); - - if (S_ISDIR(d_inode(dentry)->i_mode)) -@@ -1099,6 +1084,9 @@ int ksmbd_vfs_unlink(struct user_namespace *user_ns, - inode_unlock(d_inode(dir)); - if (err) - ksmbd_debug(VFS, "failed to delete, err %d\n", err); -+out: -+ dput(dir); -+ mnt_drop_write(filp->f_path.mnt); - - return err; - } -@@ -1201,32 +1189,29 @@ static int ksmbd_vfs_lookup_in_dir(const struct path *dir, char *name, - } - - /** -- * ksmbd_vfs_kern_path() - lookup a file and get path info -- * @name: file path that is relative to share -- * @flags: lookup flags -- * @path: if lookup succeed, return path info -+ * ksmbd_vfs_kern_path_locked() - lookup a file and get path info -+ * @name: file path that is relative to share -+ * @flags: lookup flags -+ * @parent_path: if lookup succeed, return parent_path info -+ * @path: if lookup succeed, return path info - * @caseless: caseless filename lookup - * - * Return: 0 on success, otherwise error - */ --int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name, -- unsigned int flags, struct path *path, bool caseless) -+int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, -+ unsigned int flags, struct path *parent_path, -+ struct path *path, bool caseless) - { - struct ksmbd_share_config *share_conf = work->tcon->share_conf; - int err; - -- flags |= LOOKUP_BENEATH; -- err = vfs_path_lookup(share_conf->vfs_path.dentry, -- share_conf->vfs_path.mnt, -- name, -- flags, -- path); -+ err = ksmbd_vfs_path_lookup_locked(share_conf, name, flags, parent_path, -+ path); - if (!err) - return 0; - - if (caseless) { - char *filepath; -- struct path parent; - size_t path_len, remain_len; - - filepath = kstrdup(name, GFP_KERNEL); -@@ -1236,10 +1221,10 @@ int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name, - path_len = strlen(filepath); - remain_len = path_len; - -- parent = share_conf->vfs_path; -- path_get(&parent); -+ *parent_path = share_conf->vfs_path; -+ path_get(parent_path); - -- while (d_can_lookup(parent.dentry)) { -+ while (d_can_lookup(parent_path->dentry)) { - char *filename = filepath + path_len - remain_len; - char *next = strchrnul(filename, '/'); - size_t filename_len = next - filename; -@@ -1248,12 +1233,11 @@ int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name, - if (filename_len == 0) - break; - -- err = ksmbd_vfs_lookup_in_dir(&parent, filename, -+ err = ksmbd_vfs_lookup_in_dir(parent_path, filename, - filename_len, - work->conn->um); -- path_put(&parent); - if (err) -- goto out; -+ goto out2; - - next[0] = '\0'; - -@@ -1261,26 +1245,50 @@ int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name, - share_conf->vfs_path.mnt, - filepath, - flags, -- &parent); -+ path); - if (err) -- goto out; -- else if (is_last) { -- *path = parent; -- goto out; -- } -+ goto out2; -+ else if (is_last) -+ goto out1; -+ path_put(parent_path); -+ *parent_path = *path; - - next[0] = '/'; - remain_len -= filename_len + 1; - } - -- path_put(&parent); - err = -EINVAL; --out: -+out2: -+ path_put(parent_path); -+out1: - kfree(filepath); - } -+ -+ if (!err) { -+ err = mnt_want_write(parent_path->mnt); -+ if (err) { -+ path_put(path); -+ path_put(parent_path); -+ return err; -+ } -+ -+ err = ksmbd_vfs_lock_parent(parent_path->dentry, path->dentry); -+ if (err) { -+ path_put(path); -+ path_put(parent_path); -+ } -+ } - return err; - } - -+void ksmbd_vfs_kern_path_unlock(struct path *parent_path, struct path *path) -+{ -+ inode_unlock(d_inode(parent_path->dentry)); -+ mnt_drop_write(parent_path->mnt); -+ path_put(path); -+ path_put(parent_path); -+} -+ - struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work, - const char *name, - unsigned int flags, -@@ -1299,13 +1307,13 @@ struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work, - } - - int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns, -- struct dentry *dentry) -+ const struct path *path) - { - char *name, *xattr_list = NULL; - ssize_t xattr_list_len; - int err = 0; - -- xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list); -+ xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); - if (xattr_list_len < 0) { - goto out; - } else if (!xattr_list_len) { -@@ -1321,25 +1329,25 @@ int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns, - sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) || - !strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT, - sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) { -- err = ksmbd_vfs_remove_xattr(user_ns, dentry, name); -+ err = ksmbd_vfs_remove_xattr(user_ns, path, name); - if (err) - ksmbd_debug(SMB, - "remove acl xattr failed : %s\n", name); - } - } -+ - out: - kvfree(xattr_list); - return err; - } - --int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns, -- struct dentry *dentry) -+int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns, const struct path *path) - { - char *name, *xattr_list = NULL; - ssize_t xattr_list_len; - int err = 0; - -- xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list); -+ xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); - if (xattr_list_len < 0) { - goto out; - } else if (!xattr_list_len) { -@@ -1352,7 +1360,7 @@ int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns, - ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name)); - - if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) { -- err = ksmbd_vfs_remove_xattr(user_ns, dentry, name); -+ err = ksmbd_vfs_remove_xattr(user_ns, path, name); - if (err) - ksmbd_debug(SMB, "remove xattr failed : %s\n", name); - } -@@ -1376,7 +1384,7 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct user_namespac - return NULL; - - posix_acls = get_acl(inode, acl_type); -- if (!posix_acls) -+ if (IS_ERR_OR_NULL(posix_acls)) - return NULL; - - smb_acl = kzalloc(sizeof(struct xattr_smb_acl) + -@@ -1429,13 +1437,15 @@ out: - - int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, - struct user_namespace *user_ns, -- struct dentry *dentry, -- struct smb_ntsd *pntsd, int len) -+ const struct path *path, -+ struct smb_ntsd *pntsd, int len, -+ bool get_write) - { - int rc; - struct ndr sd_ndr = {0}, acl_ndr = {0}; - struct xattr_ntacl acl = {0}; - struct xattr_smb_acl *smb_acl, *def_smb_acl = NULL; -+ struct dentry *dentry = path->dentry; - struct inode *inode = d_inode(dentry); - - acl.version = 4; -@@ -1487,9 +1497,9 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, - goto out; - } - -- rc = ksmbd_vfs_setxattr(user_ns, dentry, -+ rc = ksmbd_vfs_setxattr(user_ns, path, - XATTR_NAME_SD, sd_ndr.data, -- sd_ndr.offset, 0); -+ sd_ndr.offset, 0, get_write); - if (rc < 0) - pr_err("Failed to store XATTR ntacl :%d\n", rc); - -@@ -1577,8 +1587,9 @@ free_n_data: - } - - int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns, -- struct dentry *dentry, -- struct xattr_dos_attrib *da) -+ const struct path *path, -+ struct xattr_dos_attrib *da, -+ bool get_write) - { - struct ndr n; - int err; -@@ -1587,8 +1598,8 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns, - if (err) - return err; - -- err = ksmbd_vfs_setxattr(user_ns, dentry, XATTR_NAME_DOS_ATTRIBUTE, -- (void *)n.data, n.offset, 0); -+ err = ksmbd_vfs_setxattr(user_ns, path, XATTR_NAME_DOS_ATTRIBUTE, -+ (void *)n.data, n.offset, 0, get_write); - if (err) - ksmbd_debug(SMB, "failed to store dos attribute in xattr\n"); - kfree(n.data); -@@ -1824,10 +1835,11 @@ void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock) - } - - int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns, -- struct inode *inode) -+ struct path *path) - { - struct posix_acl_state acl_state; - struct posix_acl *acls; -+ struct inode *inode = d_inode(path->dentry); - int rc; - - if (!IS_ENABLED(CONFIG_FS_POSIX_ACL)) -@@ -1856,6 +1868,7 @@ int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns, - return -ENOMEM; - } - posix_state_to_acl(&acl_state, acls->a_entries); -+ - rc = set_posix_acl(user_ns, inode, ACL_TYPE_ACCESS, acls); - if (rc < 0) - ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", -@@ -1868,23 +1881,25 @@ int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns, - ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", - rc); - } -+ - free_acl_state(&acl_state); - posix_acl_release(acls); - return rc; - } - - int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns, -- struct inode *inode, struct inode *parent_inode) -+ struct path *path, struct inode *parent_inode) - { - struct posix_acl *acls; - struct posix_acl_entry *pace; -+ struct inode *inode = d_inode(path->dentry); - int rc, i; - - if (!IS_ENABLED(CONFIG_FS_POSIX_ACL)) - return -EOPNOTSUPP; - - acls = get_acl(parent_inode, ACL_TYPE_DEFAULT); -- if (!acls) -+ if (IS_ERR_OR_NULL(acls)) - return -ENOENT; - pace = acls->a_entries; - -@@ -1906,6 +1921,7 @@ int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns, - ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", - rc); - } -+ - posix_acl_release(acls); - return rc; - } -diff --git a/fs/smb/server/vfs.h b/fs/smb/server/vfs.h -index 593059ca85112..e761dde2443e2 100644 ---- a/fs/smb/server/vfs.h -+++ b/fs/smb/server/vfs.h -@@ -71,25 +71,23 @@ struct ksmbd_kstat { - __le32 file_attributes; - }; - --int ksmbd_vfs_lock_parent(struct user_namespace *user_ns, struct dentry *parent, -- struct dentry *child); --int ksmbd_vfs_may_delete(struct user_namespace *user_ns, struct dentry *dentry); --int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns, -+int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child); -+void ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns, - struct dentry *dentry, __le32 *daccess); - int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode); - int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode); --int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, -- size_t count, loff_t *pos); -+int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, -+ loff_t *pos, char *rbuf); - int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, - char *buf, size_t count, loff_t *pos, bool sync, - ssize_t *written); - int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id); --int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name); -+int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path); - int ksmbd_vfs_link(struct ksmbd_work *work, - const char *oldname, const char *newname); - int ksmbd_vfs_getattr(const struct path *path, struct kstat *stat); --int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, -- char *newname); -+int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path, -+ char *newname, int flags); - int ksmbd_vfs_truncate(struct ksmbd_work *work, - struct ksmbd_file *fp, loff_t size); - struct srv_copychunk; -@@ -110,15 +108,17 @@ ssize_t ksmbd_vfs_casexattr_len(struct user_namespace *user_ns, - struct dentry *dentry, char *attr_name, - int attr_name_len); - int ksmbd_vfs_setxattr(struct user_namespace *user_ns, -- struct dentry *dentry, const char *attr_name, -- void *attr_value, size_t attr_size, int flags); -+ const struct path *path, const char *attr_name, -+ void *attr_value, size_t attr_size, int flags, -+ bool get_write); - int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, - size_t *xattr_stream_name_size, int s_type); - int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns, -- struct dentry *dentry, char *attr_name); --int ksmbd_vfs_kern_path(struct ksmbd_work *work, -- char *name, unsigned int flags, struct path *path, -- bool caseless); -+ const struct path *path, char *attr_name); -+int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, -+ unsigned int flags, struct path *parent_path, -+ struct path *path, bool caseless); -+void ksmbd_vfs_kern_path_unlock(struct path *parent_path, struct path *path); - struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work, - const char *name, - unsigned int flags, -@@ -131,8 +131,7 @@ struct file_allocated_range_buffer; - int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, - struct file_allocated_range_buffer *ranges, - unsigned int in_count, unsigned int *out_count); --int ksmbd_vfs_unlink(struct user_namespace *user_ns, -- struct dentry *dir, struct dentry *dentry); -+int ksmbd_vfs_unlink(struct file *filp); - void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat); - int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, - struct user_namespace *user_ns, -@@ -142,26 +141,27 @@ void ksmbd_vfs_posix_lock_wait(struct file_lock *flock); - int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout); - void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock); - int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns, -- struct dentry *dentry); --int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns, -- struct dentry *dentry); -+ const struct path *path); -+int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns, const struct path *path); - int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, - struct user_namespace *user_ns, -- struct dentry *dentry, -- struct smb_ntsd *pntsd, int len); -+ const struct path *path, -+ struct smb_ntsd *pntsd, int len, -+ bool get_write); - int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, - struct user_namespace *user_ns, - struct dentry *dentry, - struct smb_ntsd **pntsd); - int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns, -- struct dentry *dentry, -- struct xattr_dos_attrib *da); -+ const struct path *path, -+ struct xattr_dos_attrib *da, -+ bool get_write); - int ksmbd_vfs_get_dos_attrib_xattr(struct user_namespace *user_ns, - struct dentry *dentry, - struct xattr_dos_attrib *da); - int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns, -- struct inode *inode); -+ struct path *path); - int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns, -- struct inode *inode, -+ struct path *path, - struct inode *parent_inode); - #endif /* __KSMBD_VFS_H__ */ -diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c -index 6ec6c129465d3..2528ce8aeebbe 100644 ---- a/fs/smb/server/vfs_cache.c -+++ b/fs/smb/server/vfs_cache.c -@@ -65,14 +65,14 @@ static unsigned long inode_hash(struct super_block *sb, unsigned long hashval) - return tmp & inode_hash_mask; - } - --static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode) -+static struct ksmbd_inode *__ksmbd_inode_lookup(struct dentry *de) - { - struct hlist_head *head = inode_hashtable + -- inode_hash(inode->i_sb, inode->i_ino); -+ inode_hash(d_inode(de)->i_sb, (unsigned long)de); - struct ksmbd_inode *ci = NULL, *ret_ci = NULL; - - hlist_for_each_entry(ci, head, m_hash) { -- if (ci->m_inode == inode) { -+ if (ci->m_de == de) { - if (atomic_inc_not_zero(&ci->m_count)) - ret_ci = ci; - break; -@@ -83,26 +83,27 @@ static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode) - - static struct ksmbd_inode *ksmbd_inode_lookup(struct ksmbd_file *fp) - { -- return __ksmbd_inode_lookup(file_inode(fp->filp)); -+ return __ksmbd_inode_lookup(fp->filp->f_path.dentry); - } - --static struct ksmbd_inode *ksmbd_inode_lookup_by_vfsinode(struct inode *inode) -+struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d) - { - struct ksmbd_inode *ci; - - read_lock(&inode_hash_lock); -- ci = __ksmbd_inode_lookup(inode); -+ ci = __ksmbd_inode_lookup(d); - read_unlock(&inode_hash_lock); -+ - return ci; - } - --int ksmbd_query_inode_status(struct inode *inode) -+int ksmbd_query_inode_status(struct dentry *dentry) - { - struct ksmbd_inode *ci; - int ret = KSMBD_INODE_STATUS_UNKNOWN; - - read_lock(&inode_hash_lock); -- ci = __ksmbd_inode_lookup(inode); -+ ci = __ksmbd_inode_lookup(dentry); - if (ci) { - ret = KSMBD_INODE_STATUS_OK; - if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) -@@ -142,7 +143,7 @@ void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, - static void ksmbd_inode_hash(struct ksmbd_inode *ci) - { - struct hlist_head *b = inode_hashtable + -- inode_hash(ci->m_inode->i_sb, ci->m_inode->i_ino); -+ inode_hash(d_inode(ci->m_de)->i_sb, (unsigned long)ci->m_de); - - hlist_add_head(&ci->m_hash, b); - } -@@ -156,7 +157,6 @@ static void ksmbd_inode_unhash(struct ksmbd_inode *ci) - - static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp) - { -- ci->m_inode = file_inode(fp->filp); - atomic_set(&ci->m_count, 1); - atomic_set(&ci->op_count, 0); - atomic_set(&ci->sop_count, 0); -@@ -165,6 +165,7 @@ static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp) - INIT_LIST_HEAD(&ci->m_fp_list); - INIT_LIST_HEAD(&ci->m_op_list); - rwlock_init(&ci->m_lock); -+ ci->m_de = fp->filp->f_path.dentry; - return 0; - } - -@@ -208,7 +209,7 @@ static void ksmbd_inode_free(struct ksmbd_inode *ci) - kfree(ci); - } - --static void ksmbd_inode_put(struct ksmbd_inode *ci) -+void ksmbd_inode_put(struct ksmbd_inode *ci) - { - if (atomic_dec_and_test(&ci->m_count)) - ksmbd_inode_free(ci); -@@ -243,7 +244,6 @@ void ksmbd_release_inode_hash(void) - - static void __ksmbd_inode_close(struct ksmbd_file *fp) - { -- struct dentry *dir, *dentry; - struct ksmbd_inode *ci = fp->f_ci; - int err; - struct file *filp; -@@ -252,7 +252,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) - if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) { - ci->m_flags &= ~S_DEL_ON_CLS_STREAM; - err = ksmbd_vfs_remove_xattr(file_mnt_user_ns(filp), -- filp->f_path.dentry, -+ &filp->f_path, - fp->stream.name); - if (err) - pr_err("remove xattr failed : %s\n", -@@ -262,11 +262,9 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) - if (atomic_dec_and_test(&ci->m_count)) { - write_lock(&ci->m_lock); - if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) { -- dentry = filp->f_path.dentry; -- dir = dentry->d_parent; - ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); - write_unlock(&ci->m_lock); -- ksmbd_vfs_unlink(file_mnt_user_ns(filp), dir, dentry); -+ ksmbd_vfs_unlink(filp); - write_lock(&ci->m_lock); - } - write_unlock(&ci->m_lock); -@@ -335,6 +333,9 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp) - - static struct ksmbd_file *ksmbd_fp_get(struct ksmbd_file *fp) - { -+ if (fp->f_state != FP_INITED) -+ return NULL; -+ - if (!atomic_inc_not_zero(&fp->refcount)) - return NULL; - return fp; -@@ -384,15 +385,20 @@ int ksmbd_close_fd(struct ksmbd_work *work, u64 id) - return 0; - - ft = &work->sess->file_table; -- read_lock(&ft->lock); -+ write_lock(&ft->lock); - fp = idr_find(ft->idr, id); - if (fp) { - set_close_state_blocked_works(fp); - -- if (!atomic_dec_and_test(&fp->refcount)) -+ if (fp->f_state != FP_INITED) - fp = NULL; -+ else { -+ fp->f_state = FP_CLOSED; -+ if (!atomic_dec_and_test(&fp->refcount)) -+ fp = NULL; -+ } - } -- read_unlock(&ft->lock); -+ write_unlock(&ft->lock); - - if (!fp) - return -EINVAL; -@@ -482,12 +488,15 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid) - return fp; - } - --struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode) -+struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry) - { - struct ksmbd_file *lfp; - struct ksmbd_inode *ci; -+ struct inode *inode = d_inode(dentry); - -- ci = ksmbd_inode_lookup_by_vfsinode(inode); -+ read_lock(&inode_hash_lock); -+ ci = __ksmbd_inode_lookup(dentry); -+ read_unlock(&inode_hash_lock); - if (!ci) - return NULL; - -@@ -572,6 +581,7 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp) - fp->tcon = work->tcon; - fp->volatile_id = KSMBD_NO_FID; - fp->persistent_id = KSMBD_NO_FID; -+ fp->f_state = FP_NEW; - fp->f_ci = ksmbd_inode_get(fp); - - if (!fp->f_ci) { -@@ -593,6 +603,17 @@ err_out: - return ERR_PTR(ret); - } - -+void ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp, -+ unsigned int state) -+{ -+ if (!fp) -+ return; -+ -+ write_lock(&ft->lock); -+ fp->f_state = state; -+ write_unlock(&ft->lock); -+} -+ - static int - __close_file_table_ids(struct ksmbd_file_table *ft, - struct ksmbd_tree_connect *tcon, -diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h -index fcb13413fa8d9..a528f0cc775ae 100644 ---- a/fs/smb/server/vfs_cache.h -+++ b/fs/smb/server/vfs_cache.h -@@ -51,7 +51,7 @@ struct ksmbd_inode { - atomic_t op_count; - /* opinfo count for streams */ - atomic_t sop_count; -- struct inode *m_inode; -+ struct dentry *m_de; - unsigned int m_flags; - struct hlist_node m_hash; - struct list_head m_fp_list; -@@ -60,6 +60,12 @@ struct ksmbd_inode { - __le32 m_fattr; - }; - -+enum { -+ FP_NEW = 0, -+ FP_INITED, -+ FP_CLOSED -+}; -+ - struct ksmbd_file { - struct file *filp; - u64 persistent_id; -@@ -98,6 +104,8 @@ struct ksmbd_file { - /* if ls is happening on directory, below is valid*/ - struct ksmbd_readdir_data readdir_data; - int dot_dotdot[2]; -+ unsigned int f_state; -+ bool reserve_lease_break; - }; - - static inline void set_ctx_actor(struct dir_context *ctx, -@@ -131,9 +139,11 @@ struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id); - struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, - u64 pid); - void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); -+struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d); -+void ksmbd_inode_put(struct ksmbd_inode *ci); - struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); - struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); --struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode); -+struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry); - unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp); - struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp); - void ksmbd_close_tree_conn_fds(struct ksmbd_work *work); -@@ -142,6 +152,8 @@ int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode); - int ksmbd_init_global_file_table(void); - void ksmbd_free_global_file_table(void); - void ksmbd_set_fd_limit(unsigned long limit); -+void ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp, -+ unsigned int state); - - /* - * INODE hash -@@ -155,7 +167,7 @@ enum KSMBD_INODE_STATUS { - KSMBD_INODE_STATUS_PENDING_DELETE, - }; - --int ksmbd_query_inode_status(struct inode *inode); -+int ksmbd_query_inode_status(struct dentry *dentry); - bool ksmbd_inode_pending_delete(struct ksmbd_file *fp); - void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp); - void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp); -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index 57674b3c58774..07a7eeef47d39 100644 ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -565,7 +565,7 @@ struct request_queue { - #define QUEUE_FLAG_NOXMERGES 9 /* No extended merges */ - #define QUEUE_FLAG_ADD_RANDOM 10 /* Contributes to random pool */ - #define QUEUE_FLAG_SAME_FORCE 12 /* force complete on same CPU */ --#define QUEUE_FLAG_HW_WC 18 /* Write back caching supported */ -+#define QUEUE_FLAG_HW_WC 13 /* Write back caching supported */ - #define QUEUE_FLAG_INIT_DONE 14 /* queue is initialized */ - #define QUEUE_FLAG_STABLE_WRITES 15 /* don't modify blks until WB is done */ - #define QUEUE_FLAG_POLL 16 /* IO polling enabled if set */ -diff --git a/include/linux/export-internal.h b/include/linux/export-internal.h -index fe7e6ba918f10..29de29af9546c 100644 ---- a/include/linux/export-internal.h -+++ b/include/linux/export-internal.h -@@ -12,6 +12,7 @@ - - #define SYMBOL_CRC(sym, crc, sec) \ - asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \ -+ ".balign 4" "\n" \ - "__crc_" #sym ":" "\n" \ - ".long " #crc "\n" \ - ".previous" "\n") -diff --git a/include/linux/module.h b/include/linux/module.h -index ec61fb53979a9..35876e89eb93f 100644 ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -879,8 +879,17 @@ static inline bool module_sig_ok(struct module *module) - } - #endif /* CONFIG_MODULE_SIG */ - -+#if defined(CONFIG_MODULES) && defined(CONFIG_KALLSYMS) - int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, - struct module *, unsigned long), - void *data); -+#else -+static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, -+ struct module *, unsigned long), -+ void *data) -+{ -+ return -EOPNOTSUPP; -+} -+#endif /* CONFIG_MODULES && CONFIG_KALLSYMS */ - - #endif /* _LINUX_MODULE_H */ -diff --git a/include/linux/namei.h b/include/linux/namei.h -index 00fee52df8423..5c0149603dc3d 100644 ---- a/include/linux/namei.h -+++ b/include/linux/namei.h -@@ -57,12 +57,18 @@ static inline int user_path_at(int dfd, const char __user *name, unsigned flags, - return user_path_at_empty(dfd, name, flags, path, NULL); - } - -+struct dentry *lookup_one_qstr_excl(const struct qstr *name, -+ struct dentry *base, -+ unsigned int flags); - extern int kern_path(const char *, unsigned, struct path *); - - extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int); - extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int); - extern void done_path_create(struct path *, struct dentry *); - extern struct dentry *kern_path_locked(const char *, struct path *); -+int vfs_path_parent_lookup(struct filename *filename, unsigned int flags, -+ struct path *parent, struct qstr *last, int *type, -+ const struct path *root); - - extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int); - extern struct dentry *lookup_one_len(const char *, struct dentry *, int); -@@ -81,6 +87,7 @@ extern int follow_down(struct path *); - extern int follow_up(struct path *); - - extern struct dentry *lock_rename(struct dentry *, struct dentry *); -+extern struct dentry *lock_rename_child(struct dentry *, struct dentry *); - extern void unlock_rename(struct dentry *, struct dentry *); - - extern int __must_check nd_jump_link(const struct path *path); -diff --git a/include/linux/property.h b/include/linux/property.h -index 117cc200c656d..587b5b666b5bb 100644 ---- a/include/linux/property.h -+++ b/include/linux/property.h -@@ -32,7 +32,12 @@ enum dev_dma_attr { - DEV_DMA_COHERENT, - }; - --struct fwnode_handle *dev_fwnode(const struct device *dev); -+const struct fwnode_handle *__dev_fwnode_const(const struct device *dev); -+struct fwnode_handle *__dev_fwnode(struct device *dev); -+#define dev_fwnode(dev) \ -+ _Generic((dev), \ -+ const struct device *: __dev_fwnode_const, \ -+ struct device *: __dev_fwnode)(dev) - - bool device_property_present(struct device *dev, const char *propname); - int device_property_read_u8_array(struct device *dev, const char *propname, -diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h -index 877395e075afe..8e9054d9f6df0 100644 ---- a/include/linux/spi/spi.h -+++ b/include/linux/spi/spi.h -@@ -263,6 +263,26 @@ static inline void *spi_get_drvdata(struct spi_device *spi) - return dev_get_drvdata(&spi->dev); - } - -+static inline u8 spi_get_chipselect(const struct spi_device *spi, u8 idx) -+{ -+ return spi->chip_select; -+} -+ -+static inline void spi_set_chipselect(struct spi_device *spi, u8 idx, u8 chipselect) -+{ -+ spi->chip_select = chipselect; -+} -+ -+static inline struct gpio_desc *spi_get_csgpiod(const struct spi_device *spi, u8 idx) -+{ -+ return spi->cs_gpiod; -+} -+ -+static inline void spi_set_csgpiod(struct spi_device *spi, u8 idx, struct gpio_desc *csgpiod) -+{ -+ spi->cs_gpiod = csgpiod; -+} -+ - struct spi_message; - - /** -@@ -1515,6 +1535,9 @@ extern void spi_unregister_device(struct spi_device *spi); - extern const struct spi_device_id * - spi_get_device_id(const struct spi_device *sdev); - -+extern const void * -+spi_get_device_match_data(const struct spi_device *sdev); -+ - static inline bool - spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer) - { -diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c -index f5c5c9175333d..4523f99b03589 100644 ---- a/kernel/module/kallsyms.c -+++ b/kernel/module/kallsyms.c -@@ -494,7 +494,6 @@ unsigned long module_kallsyms_lookup_name(const char *name) - return ret; - } - --#ifdef CONFIG_LIVEPATCH - int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, - struct module *, unsigned long), - void *data) -@@ -531,4 +530,3 @@ out: - mutex_unlock(&module_mutex); - return ret; - } --#endif /* CONFIG_LIVEPATCH */ -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index 61803208706a5..06d52525407b8 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -705,48 +705,6 @@ rb_time_read_cmpxchg(local_t *l, unsigned long expect, unsigned long set) - return ret == expect; - } - --static int rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) --{ -- unsigned long cnt, top, bottom, msb; -- unsigned long cnt2, top2, bottom2, msb2; -- u64 val; -- -- /* Any interruptions in this function should cause a failure */ -- cnt = local_read(&t->cnt); -- -- /* The cmpxchg always fails if it interrupted an update */ -- if (!__rb_time_read(t, &val, &cnt2)) -- return false; -- -- if (val != expect) -- return false; -- -- if ((cnt & 3) != cnt2) -- return false; -- -- cnt2 = cnt + 1; -- -- rb_time_split(val, &top, &bottom, &msb); -- msb = rb_time_val_cnt(msb, cnt); -- top = rb_time_val_cnt(top, cnt); -- bottom = rb_time_val_cnt(bottom, cnt); -- -- rb_time_split(set, &top2, &bottom2, &msb2); -- msb2 = rb_time_val_cnt(msb2, cnt); -- top2 = rb_time_val_cnt(top2, cnt2); -- bottom2 = rb_time_val_cnt(bottom2, cnt2); -- -- if (!rb_time_read_cmpxchg(&t->cnt, cnt, cnt2)) -- return false; -- if (!rb_time_read_cmpxchg(&t->msb, msb, msb2)) -- return false; -- if (!rb_time_read_cmpxchg(&t->top, top, top2)) -- return false; -- if (!rb_time_read_cmpxchg(&t->bottom, bottom, bottom2)) -- return false; -- return true; --} -- - #else /* 64 bits */ - - /* local64_t always succeeds */ -@@ -760,13 +718,6 @@ static void rb_time_set(rb_time_t *t, u64 val) - { - local64_set(&t->time, val); - } -- --static bool rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) --{ -- u64 val; -- val = local64_cmpxchg(&t->time, expect, set); -- return val == expect; --} - #endif - - /* -@@ -935,9 +886,14 @@ static __always_inline bool full_hit(struct trace_buffer *buffer, int cpu, int f - if (!nr_pages || !full) - return true; - -- dirty = ring_buffer_nr_dirty_pages(buffer, cpu); -+ /* -+ * Add one as dirty will never equal nr_pages, as the sub-buffer -+ * that the writer is on is not counted as dirty. -+ * This is needed if "buffer_percent" is set to 100. -+ */ -+ dirty = ring_buffer_nr_dirty_pages(buffer, cpu) + 1; - -- return (dirty * 100) > (full * nr_pages); -+ return (dirty * 100) >= (full * nr_pages); - } - - /* -@@ -997,7 +953,8 @@ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu) - /* make sure the waiters see the new index */ - smp_wmb(); - -- rb_wake_up_waiters(&rbwork->work); -+ /* This can be called in any context */ -+ irq_work_queue(&rbwork->work); - } - - /** -@@ -2981,25 +2938,6 @@ static unsigned rb_calculate_event_length(unsigned length) - return length; - } - --static u64 rb_time_delta(struct ring_buffer_event *event) --{ -- switch (event->type_len) { -- case RINGBUF_TYPE_PADDING: -- return 0; -- -- case RINGBUF_TYPE_TIME_EXTEND: -- return rb_event_time_stamp(event); -- -- case RINGBUF_TYPE_TIME_STAMP: -- return 0; -- -- case RINGBUF_TYPE_DATA: -- return event->time_delta; -- default: -- return 0; -- } --} -- - static inline int - rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, - struct ring_buffer_event *event) -@@ -3008,8 +2946,6 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, - struct buffer_page *bpage; - unsigned long index; - unsigned long addr; -- u64 write_stamp; -- u64 delta; - - new_index = rb_event_index(event); - old_index = new_index + rb_event_ts_length(event); -@@ -3018,14 +2954,10 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, - - bpage = READ_ONCE(cpu_buffer->tail_page); - -- delta = rb_time_delta(event); -- -- if (!rb_time_read(&cpu_buffer->write_stamp, &write_stamp)) -- return 0; -- -- /* Make sure the write stamp is read before testing the location */ -- barrier(); -- -+ /* -+ * Make sure the tail_page is still the same and -+ * the next write location is the end of this event -+ */ - if (bpage->page == (void *)addr && rb_page_write(bpage) == old_index) { - unsigned long write_mask = - local_read(&bpage->write) & ~RB_WRITE_MASK; -@@ -3036,20 +2968,20 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, - * 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. -+ * -+ * By setting the before_stamp to zero, the next event -+ * is not going to use the write_stamp and will instead -+ * create an absolute timestamp. This means there's no -+ * reason to update the wirte_stamp! - */ - rb_time_set(&cpu_buffer->before_stamp, 0); - -- /* Something came in, can't discard */ -- if (!rb_time_cmpxchg(&cpu_buffer->write_stamp, -- write_stamp, write_stamp - delta)) -- return 0; -- - /* - * If an event were to come in now, it would see that the - * write_stamp and the before_stamp are different, and assume - * that this event just added itself before updating - * the write stamp. The interrupting event will fix the -- * write stamp for us, and use the before stamp as its delta. -+ * write stamp for us, and use an absolute timestamp. - */ - - /* -@@ -3488,7 +3420,7 @@ static void check_buffer(struct ring_buffer_per_cpu *cpu_buffer, - return; - - /* -- * If this interrupted another event, -+ * If this interrupted another event, - */ - if (atomic_inc_return(this_cpu_ptr(&checking)) != 1) - goto out; -@@ -3632,20 +3564,36 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, - } else { - u64 ts; - /* SLOW PATH - Interrupted between A and C */ -- a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after); -- /* Was interrupted before here, write_stamp must be valid */ -+ -+ /* Save the old before_stamp */ -+ a_ok = rb_time_read(&cpu_buffer->before_stamp, &info->before); - RB_WARN_ON(cpu_buffer, !a_ok); -+ -+ /* -+ * Read a new timestamp and update the before_stamp to make -+ * the next event after this one force using an absolute -+ * timestamp. This is in case an interrupt were to come in -+ * between E and F. -+ */ - ts = rb_time_stamp(cpu_buffer->buffer); -+ rb_time_set(&cpu_buffer->before_stamp, ts); -+ - barrier(); -- /*E*/ if (write == (local_read(&tail_page->write) & RB_WRITE_MASK) && -- info->after < ts && -- rb_time_cmpxchg(&cpu_buffer->write_stamp, -- info->after, ts)) { -- /* Nothing came after this event between C and E */ -+ /*E*/ a_ok = rb_time_read(&cpu_buffer->write_stamp, &info->after); -+ /* Was interrupted before here, write_stamp must be valid */ -+ RB_WARN_ON(cpu_buffer, !a_ok); -+ barrier(); -+ /*F*/ if (write == (local_read(&tail_page->write) & RB_WRITE_MASK) && -+ info->after == info->before && info->after < ts) { -+ /* -+ * Nothing came after this event between C and F, it is -+ * safe to use info->after for the delta as it -+ * matched info->before and is still valid. -+ */ - info->delta = ts - info->after; - } else { - /* -- * Interrupted between C and E: -+ * Interrupted between C and F: - * Lost the previous events time stamp. Just set the - * delta to zero, and this will be the same time as - * the event this event interrupted. And the events that -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 87eca95b57fb3..deae65af76ecf 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -1850,6 +1850,9 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu, - __update_max_tr(tr, tsk, cpu); - - arch_spin_unlock(&tr->max_lock); -+ -+ /* Any waiters on the old snapshot buffer need to wake up */ -+ ring_buffer_wake_waiters(tr->array_buffer.buffer, RING_BUFFER_ALL_CPUS); - } - - /** -@@ -1901,12 +1904,23 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) - - static int wait_on_pipe(struct trace_iterator *iter, int full) - { -+ int ret; -+ - /* Iterators are static, they should be filled or empty */ - if (trace_buffer_iter(iter, iter->cpu_file)) - return 0; - -- return ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file, -- full); -+ ret = ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file, full); -+ -+#ifdef CONFIG_TRACER_MAX_TRACE -+ /* -+ * Make sure this is still the snapshot buffer, as if a snapshot were -+ * to happen, this would now be the main buffer. -+ */ -+ if (iter->snapshot) -+ iter->array_buffer = &iter->tr->max_buffer; -+#endif -+ return ret; - } - - #ifdef CONFIG_FTRACE_STARTUP_TEST -@@ -8433,7 +8447,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, - - wait_index = READ_ONCE(iter->wait_index); - -- ret = wait_on_pipe(iter, iter->tr->buffer_percent); -+ ret = wait_on_pipe(iter, iter->snapshot ? 0 : iter->tr->buffer_percent); - if (ret) - goto out; - -diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c -index a34a4fcdab7b1..e3993d19687db 100644 ---- a/kernel/trace/trace_kprobe.c -+++ b/kernel/trace/trace_kprobe.c -@@ -714,14 +714,31 @@ static int count_symbols(void *data, unsigned long unused) - return 0; - } - -+struct sym_count_ctx { -+ unsigned int count; -+ const char *name; -+}; -+ -+static int count_mod_symbols(void *data, const char *name, -+ struct module *module, unsigned long unused) -+{ -+ struct sym_count_ctx *ctx = data; -+ -+ if (strcmp(name, ctx->name) == 0) -+ ctx->count++; -+ -+ return 0; -+} -+ - static unsigned int number_of_same_symbols(char *func_name) - { -- unsigned int count; -+ struct sym_count_ctx ctx = { .count = 0, .name = func_name }; -+ -+ kallsyms_on_each_match_symbol(count_symbols, func_name, &ctx.count); - -- count = 0; -- kallsyms_on_each_match_symbol(count_symbols, func_name, &count); -+ module_kallsyms_on_each_symbol(count_mod_symbols, &ctx); - -- return count; -+ return ctx.count; - } - - static int __trace_kprobe_create(int argc, const char *argv[]) -diff --git a/mm/filemap.c b/mm/filemap.c -index d633ab8cd56f1..10fe6430693bd 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -2744,6 +2744,15 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, - goto put_folios; - end_offset = min_t(loff_t, isize, iocb->ki_pos + iter->count); - -+ /* -+ * Pairs with a barrier in -+ * block_write_end()->mark_buffer_dirty() or other page -+ * dirtying routines like iomap_write_end() to ensure -+ * changes to page contents are visible before we see -+ * increased inode size. -+ */ -+ smp_rmb(); -+ - /* - * Once we start copying data, we don't want to be touching any - * cachelines that might be contended: -diff --git a/mm/memory-failure.c b/mm/memory-failure.c -index 99de0328d1bed..ebd717157c813 100644 ---- a/mm/memory-failure.c -+++ b/mm/memory-failure.c -@@ -1421,7 +1421,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, - * This check implies we don't kill processes if their pages - * are in the swap cache early. Those are always late kills. - */ -- if (!page_mapped(hpage)) -+ if (!page_mapped(p)) - return true; - - if (PageKsm(p)) { -@@ -1477,10 +1477,10 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, - try_to_unmap(folio, ttu); - } - -- unmap_success = !page_mapped(hpage); -+ unmap_success = !page_mapped(p); - if (!unmap_success) - pr_err("%#lx: failed to unmap page (mapcount=%d)\n", -- pfn, page_mapcount(hpage)); -+ pfn, page_mapcount(p)); - - /* - * try_to_unmap() might put mlocked page in lru cache, so call -@@ -1560,7 +1560,7 @@ static void unmap_and_kill(struct list_head *to_kill, unsigned long pfn, - * mapping being torn down is communicated in siginfo, see - * kill_proc() - */ -- loff_t start = (index << PAGE_SHIFT) & ~(size - 1); -+ loff_t start = ((loff_t)index << PAGE_SHIFT) & ~(size - 1); - - unmap_mapping_range(mapping, start, size, 0); - } -diff --git a/mm/migrate.c b/mm/migrate.c -index 9372a826e6d08..91bd69c61148e 100644 ---- a/mm/migrate.c -+++ b/mm/migrate.c -@@ -388,6 +388,7 @@ int folio_migrate_mapping(struct address_space *mapping, - int dirty; - int expected_count = folio_expected_refs(mapping, folio) + extra_count; - long nr = folio_nr_pages(folio); -+ long entries, i; - - if (!mapping) { - /* Anonymous page without mapping */ -@@ -425,8 +426,10 @@ int folio_migrate_mapping(struct address_space *mapping, - folio_set_swapcache(newfolio); - newfolio->private = folio_get_private(folio); - } -+ entries = nr; - } else { - VM_BUG_ON_FOLIO(folio_test_swapcache(folio), folio); -+ entries = 1; - } - - /* Move dirty while page refs frozen and newpage not yet exposed */ -@@ -436,7 +439,11 @@ int folio_migrate_mapping(struct address_space *mapping, - folio_set_dirty(newfolio); - } - -- xas_store(&xas, newfolio); -+ /* Swap cache still stores N entries instead of a high-order entry */ -+ for (i = 0; i < entries; i++) { -+ xas_store(&xas, newfolio); -+ xas_next(&xas); -+ } - - /* - * Drop cache reference from old page by unfreezing -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 05fa5141af516..3d6ebb9877a4e 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -9480,7 +9480,7 @@ static void nft_set_commit_update(struct list_head *set_update_list) - list_for_each_entry_safe(set, next, set_update_list, pending_update) { - list_del_init(&set->pending_update); - -- if (!set->ops->commit) -+ if (!set->ops->commit || set->dead) - continue; - - set->ops->commit(set); diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.71-72.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.71-72.patch deleted file mode 100644 index 2496793b28d5..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.71-72.patch +++ /dev/null @@ -1,9332 +0,0 @@ -diff --git a/MAINTAINERS b/MAINTAINERS -index 07a9c274c0e29..13d1078808bb5 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -10803,6 +10803,8 @@ L: linux-kernel@vger.kernel.org - S: Maintained - T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core - F: kernel/irq/ -+F: include/linux/group_cpus.h -+F: lib/group_cpus.c - - IRQCHIP DRIVERS - M: Thomas Gleixner -diff --git a/Makefile b/Makefile -index 2840e36fd5596..bad3387b3251c 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 71 -+SUBLEVEL = 72 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/Kconfig b/arch/Kconfig -index b60d271bf76a9..14273a6203dfc 100644 ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -34,6 +34,9 @@ config ARCH_HAS_SUBPAGE_FAULTS - config HOTPLUG_SMT - bool - -+config SMT_NUM_THREADS_DYNAMIC -+ bool -+ - config GENERIC_ENTRY - bool - -diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c -index 26cbce1353387..b2f5f4f28705f 100644 ---- a/arch/arm/mach-sunxi/mc_smp.c -+++ b/arch/arm/mach-sunxi/mc_smp.c -@@ -808,12 +808,12 @@ static int __init sunxi_mc_smp_init(void) - break; - } - -- is_a83t = sunxi_mc_smp_data[i].is_a83t; -- - of_node_put(node); - if (ret) - return -ENODEV; - -+ is_a83t = sunxi_mc_smp_data[i].is_a83t; -+ - if (!sunxi_mc_smp_cpu_table_init()) - return -EINVAL; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi -index a5c0c788969fb..43ee28db61aa8 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi -@@ -150,15 +150,15 @@ - }; - - &psci { -- /delete-node/ cpu0; -- /delete-node/ cpu1; -- /delete-node/ cpu2; -- /delete-node/ cpu3; -- /delete-node/ cpu4; -- /delete-node/ cpu5; -- /delete-node/ cpu6; -- /delete-node/ cpu7; -- /delete-node/ cpu-cluster0; -+ /delete-node/ power-domain-cpu0; -+ /delete-node/ power-domain-cpu1; -+ /delete-node/ power-domain-cpu2; -+ /delete-node/ power-domain-cpu3; -+ /delete-node/ power-domain-cpu4; -+ /delete-node/ power-domain-cpu5; -+ /delete-node/ power-domain-cpu6; -+ /delete-node/ power-domain-cpu7; -+ /delete-node/ power-domain-cluster; - }; - - &cpus { -@@ -351,7 +351,9 @@ - - - &apps_rsc { -- pm8998-rpmh-regulators { -+ /delete-property/ power-domains; -+ -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -@@ -633,7 +635,7 @@ - }; - }; - -- pm8005-rpmh-regulators { -+ regulators-1 { - compatible = "qcom,pm8005-rpmh-regulators"; - qcom,pmic-id = "c"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -index c9efcb894a52f..8c9ccf5b4ea41 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -@@ -271,7 +271,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - vdd-s1-supply = <&vph_pwr>; -@@ -396,7 +396,7 @@ - }; - }; - -- pmi8998-rpmh-regulators { -+ regulators-1 { - compatible = "qcom,pmi8998-rpmh-regulators"; - qcom,pmic-id = "b"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi -index 20f275f8694dc..e2921640880a1 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi -@@ -166,7 +166,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -@@ -419,7 +419,7 @@ - }; - }; - -- pmi8998-rpmh-regulators { -+ regulators-1 { - compatible = "qcom,pmi8998-rpmh-regulators"; - qcom,pmic-id = "b"; - -@@ -433,7 +433,7 @@ - }; - }; - -- pm8005-rpmh-regulators { -+ regulators-2 { - compatible = "qcom,pm8005-rpmh-regulators"; - qcom,pmic-id = "c"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts -index 64958dee17d8b..b47e333aa3510 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts -@@ -117,7 +117,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -@@ -382,7 +382,7 @@ - }; - }; - -- pmi8998-rpmh-regulators { -+ regulators-1 { - compatible = "qcom,pmi8998-rpmh-regulators"; - qcom,pmic-id = "b"; - -@@ -396,7 +396,7 @@ - }; - }; - -- pm8005-rpmh-regulators { -+ regulators-2 { - compatible = "qcom,pm8005-rpmh-regulators"; - qcom,pmic-id = "c"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi -index 392461c29e76e..0713b774a97be 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi -@@ -144,7 +144,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -@@ -280,7 +280,7 @@ - }; - }; - -- pmi8998-rpmh-regulators { -+ regulators-1 { - compatible = "qcom,pmi8998-rpmh-regulators"; - qcom,pmic-id = "b"; - -@@ -294,7 +294,7 @@ - }; - }; - -- pm8005-rpmh-regulators { -+ regulators-2 { - compatible = "qcom,pm8005-rpmh-regulators"; - qcom,pmic-id = "c"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts -index 83261c9bb4f23..b65c35865dab9 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts -@@ -110,7 +110,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -@@ -375,7 +375,7 @@ - }; - }; - -- pmi8998-rpmh-regulators { -+ regulators-1 { - compatible = "qcom,pmi8998-rpmh-regulators"; - qcom,pmic-id = "b"; - -@@ -389,7 +389,7 @@ - }; - }; - -- pm8005-rpmh-regulators { -+ regulators-2 { - compatible = "qcom,pm8005-rpmh-regulators"; - qcom,pmic-id = "c"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi -index d6918e6d19799..249a715d5aae1 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi -@@ -78,7 +78,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -@@ -308,7 +308,7 @@ - }; - }; - -- pmi8998-rpmh-regulators { -+ regulators-1 { - compatible = "qcom,pmi8998-rpmh-regulators"; - qcom,pmic-id = "b"; - -@@ -319,7 +319,7 @@ - }; - }; - -- pm8005-rpmh-regulators { -+ regulators-2 { - compatible = "qcom,pm8005-rpmh-regulators"; - qcom,pmic-id = "c"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts -index 0f470cf1ed1c1..6d6b3dd699475 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts -@@ -125,7 +125,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts -index 093b04359ec39..ffbe45a99b74a 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts -@@ -143,7 +143,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -@@ -343,7 +343,7 @@ - }; - }; - -- pmi8998-rpmh-regulators { -+ regulators-1 { - compatible = "qcom,pmi8998-rpmh-regulators"; - qcom,pmic-id = "b"; - -@@ -355,7 +355,7 @@ - }; - }; - -- pm8005-rpmh-regulators { -+ regulators-2 { - compatible = "qcom,pm8005-rpmh-regulators"; - qcom,pmic-id = "c"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts -index 74f43da51fa50..48a41ace8fc58 100644 ---- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts -+++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts -@@ -99,7 +99,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -diff --git a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts -index d028a7eb364a6..c169d2870bdf4 100644 ---- a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts -+++ b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts -@@ -129,7 +129,7 @@ - }; - - &apps_rsc { -- pm8998-rpmh-regulators { -+ regulators-0 { - compatible = "qcom,pm8998-rpmh-regulators"; - qcom,pmic-id = "a"; - -diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c -index f043a7ff220b7..28fa80fd69fa0 100644 ---- a/arch/s390/kernel/perf_cpum_cf.c -+++ b/arch/s390/kernel/perf_cpum_cf.c -@@ -2,7 +2,7 @@ - /* - * Performance event support for s390x - CPU-measurement Counter Facility - * -- * Copyright IBM Corp. 2012, 2021 -+ * Copyright IBM Corp. 2012, 2022 - * Author(s): Hendrik Brueckner - * Thomas Richter - */ -@@ -434,6 +434,12 @@ static void cpumf_hw_inuse(void) - mutex_unlock(&pmc_reserve_mutex); - } - -+static int is_userspace_event(u64 ev) -+{ -+ return cpumf_generic_events_user[PERF_COUNT_HW_CPU_CYCLES] == ev || -+ cpumf_generic_events_user[PERF_COUNT_HW_INSTRUCTIONS] == ev; -+} -+ - static int __hw_perf_event_init(struct perf_event *event, unsigned int type) - { - struct perf_event_attr *attr = &event->attr; -@@ -456,19 +462,26 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type) - if (is_sampling_event(event)) /* No sampling support */ - return -ENOENT; - ev = attr->config; -- /* Count user space (problem-state) only */ - if (!attr->exclude_user && attr->exclude_kernel) { -- if (ev >= ARRAY_SIZE(cpumf_generic_events_user)) -- return -EOPNOTSUPP; -- ev = cpumf_generic_events_user[ev]; -- -- /* No support for kernel space counters only */ -+ /* -+ * Count user space (problem-state) only -+ * Handle events 32 and 33 as 0:u and 1:u -+ */ -+ if (!is_userspace_event(ev)) { -+ if (ev >= ARRAY_SIZE(cpumf_generic_events_user)) -+ return -EOPNOTSUPP; -+ ev = cpumf_generic_events_user[ev]; -+ } - } else if (!attr->exclude_kernel && attr->exclude_user) { -+ /* No support for kernel space counters only */ - return -EOPNOTSUPP; -- } else { /* Count user and kernel space */ -- if (ev >= ARRAY_SIZE(cpumf_generic_events_basic)) -- return -EOPNOTSUPP; -- ev = cpumf_generic_events_basic[ev]; -+ } else { -+ /* Count user and kernel space, incl. events 32 + 33 */ -+ if (!is_userspace_event(ev)) { -+ if (ev >= ARRAY_SIZE(cpumf_generic_events_basic)) -+ return -EOPNOTSUPP; -+ ev = cpumf_generic_events_basic[ev]; -+ } - } - break; - -diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c -index 9a0ce5315f36d..3cbb461820666 100644 ---- a/arch/s390/mm/vmem.c -+++ b/arch/s390/mm/vmem.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -44,8 +45,11 @@ void *vmem_crst_alloc(unsigned long val) - unsigned long *table; - - table = vmem_alloc_pages(CRST_ALLOC_ORDER); -- if (table) -- crst_table_init(table, val); -+ if (!table) -+ return NULL; -+ crst_table_init(table, val); -+ if (slab_is_available()) -+ arch_set_page_dat(virt_to_page(table), CRST_ALLOC_ORDER); - return table; - } - -diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c -index 2fb5e1541efc1..949129443b1c0 100644 ---- a/arch/x86/events/intel/core.c -+++ b/arch/x86/events/intel/core.c -@@ -4033,12 +4033,17 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data) - u64 pebs_mask = cpuc->pebs_enabled & x86_pmu.pebs_capable; - int global_ctrl, pebs_enable; - -+ /* -+ * In addition to obeying exclude_guest/exclude_host, remove bits being -+ * used for PEBS when running a guest, because PEBS writes to virtual -+ * addresses (not physical addresses). -+ */ - *nr = 0; - global_ctrl = (*nr)++; - arr[global_ctrl] = (struct perf_guest_switch_msr){ - .msr = MSR_CORE_PERF_GLOBAL_CTRL, - .host = intel_ctrl & ~cpuc->intel_ctrl_guest_mask, -- .guest = intel_ctrl & (~cpuc->intel_ctrl_host_mask | ~pebs_mask), -+ .guest = intel_ctrl & ~cpuc->intel_ctrl_host_mask & ~pebs_mask, - }; - - if (!x86_pmu.pebs) -diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c -index ea155f0cf545c..6120f25b0d5cc 100644 ---- a/arch/x86/kernel/kprobes/core.c -+++ b/arch/x86/kernel/kprobes/core.c -@@ -549,7 +549,8 @@ static void kprobe_emulate_call_indirect(struct kprobe *p, struct pt_regs *regs) - { - unsigned long offs = addrmode_regoffs[p->ainsn.indirect.reg]; - -- int3_emulate_call(regs, regs_get_register(regs, offs)); -+ int3_emulate_push(regs, regs->ip - INT3_INSN_SIZE + p->ainsn.size); -+ int3_emulate_jmp(regs, regs_get_register(regs, offs)); - } - NOKPROBE_SYMBOL(kprobe_emulate_call_indirect); - -diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c -index 4686c1d9d0cfd..b69aee6245e4a 100644 ---- a/arch/x86/net/bpf_jit_comp.c -+++ b/arch/x86/net/bpf_jit_comp.c -@@ -893,6 +893,10 @@ static void emit_nops(u8 **pprog, int len) - - #define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp))) - -+/* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */ -+#define RESTORE_TAIL_CALL_CNT(stack) \ -+ EMIT3_off32(0x48, 0x8B, 0x85, -round_up(stack, 8) - 8) -+ - static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image, - int oldproglen, struct jit_context *ctx, bool jmp_padding) - { -@@ -1436,9 +1440,7 @@ st: if (is_imm8(insn->off)) - case BPF_JMP | BPF_CALL: - func = (u8 *) __bpf_call_base + imm32; - if (tail_call_reachable) { -- /* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */ -- EMIT3_off32(0x48, 0x8B, 0x85, -- -round_up(bpf_prog->aux->stack_depth, 8) - 8); -+ RESTORE_TAIL_CALL_CNT(bpf_prog->aux->stack_depth); - if (!imm32 || emit_call(&prog, func, image + addrs[i - 1] + 7)) - return -EINVAL; - } else { -@@ -1623,16 +1625,24 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */ - break; - - case BPF_JMP | BPF_JA: -- if (insn->off == -1) -- /* -1 jmp instructions will always jump -- * backwards two bytes. Explicitly handling -- * this case avoids wasting too many passes -- * when there are long sequences of replaced -- * dead code. -- */ -- jmp_offset = -2; -- else -- jmp_offset = addrs[i + insn->off] - addrs[i]; -+ case BPF_JMP32 | BPF_JA: -+ if (BPF_CLASS(insn->code) == BPF_JMP) { -+ if (insn->off == -1) -+ /* -1 jmp instructions will always jump -+ * backwards two bytes. Explicitly handling -+ * this case avoids wasting too many passes -+ * when there are long sequences of replaced -+ * dead code. -+ */ -+ jmp_offset = -2; -+ else -+ jmp_offset = addrs[i + insn->off] - addrs[i]; -+ } else { -+ if (insn->imm == -1) -+ jmp_offset = -2; -+ else -+ jmp_offset = addrs[i + insn->imm] - addrs[i]; -+ } - - if (!jmp_offset) { - /* -@@ -1750,63 +1760,37 @@ emit_jmp: - return proglen; - } - --static void save_regs(const struct btf_func_model *m, u8 **prog, int nr_args, -+static void save_regs(const struct btf_func_model *m, u8 **prog, int nr_regs, - int stack_size) - { -- int i, j, arg_size, nr_regs; -+ int i; -+ - /* Store function arguments to stack. - * For a function that accepts two pointers the sequence will be: - * mov QWORD PTR [rbp-0x10],rdi - * mov QWORD PTR [rbp-0x8],rsi - */ -- for (i = 0, j = 0; i < min(nr_args, 6); i++) { -- if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) { -- nr_regs = (m->arg_size[i] + 7) / 8; -- arg_size = 8; -- } else { -- nr_regs = 1; -- arg_size = m->arg_size[i]; -- } -- -- while (nr_regs) { -- emit_stx(prog, bytes_to_bpf_size(arg_size), -- BPF_REG_FP, -- j == 5 ? X86_REG_R9 : BPF_REG_1 + j, -- -(stack_size - j * 8)); -- nr_regs--; -- j++; -- } -- } -+ for (i = 0; i < min(nr_regs, 6); i++) -+ emit_stx(prog, BPF_DW, BPF_REG_FP, -+ i == 5 ? X86_REG_R9 : BPF_REG_1 + i, -+ -(stack_size - i * 8)); - } - --static void restore_regs(const struct btf_func_model *m, u8 **prog, int nr_args, -+static void restore_regs(const struct btf_func_model *m, u8 **prog, int nr_regs, - int stack_size) - { -- int i, j, arg_size, nr_regs; -+ int i; - - /* Restore function arguments from stack. - * For a function that accepts two pointers the sequence will be: - * EMIT4(0x48, 0x8B, 0x7D, 0xF0); mov rdi,QWORD PTR [rbp-0x10] - * EMIT4(0x48, 0x8B, 0x75, 0xF8); mov rsi,QWORD PTR [rbp-0x8] - */ -- for (i = 0, j = 0; i < min(nr_args, 6); i++) { -- if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) { -- nr_regs = (m->arg_size[i] + 7) / 8; -- arg_size = 8; -- } else { -- nr_regs = 1; -- arg_size = m->arg_size[i]; -- } -- -- while (nr_regs) { -- emit_ldx(prog, bytes_to_bpf_size(arg_size), -- j == 5 ? X86_REG_R9 : BPF_REG_1 + j, -- BPF_REG_FP, -- -(stack_size - j * 8)); -- nr_regs--; -- j++; -- } -- } -+ for (i = 0; i < min(nr_regs, 6); i++) -+ emit_ldx(prog, BPF_DW, -+ i == 5 ? X86_REG_R9 : BPF_REG_1 + i, -+ BPF_REG_FP, -+ -(stack_size - i * 8)); - } - - static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, -@@ -2031,8 +2015,8 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - struct bpf_tramp_links *tlinks, - void *func_addr) - { -- int ret, i, nr_args = m->nr_args, extra_nregs = 0; -- int regs_off, ip_off, args_off, stack_size = nr_args * 8, run_ctx_off; -+ int i, ret, nr_regs = m->nr_args, stack_size = 0; -+ int regs_off, nregs_off, ip_off, run_ctx_off; - struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY]; - struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT]; - struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN]; -@@ -2041,17 +2025,14 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - u8 *prog; - bool save_ret; - -- /* x86-64 supports up to 6 arguments. 7+ can be added in the future */ -- if (nr_args > 6) -- return -ENOTSUPP; -- -- for (i = 0; i < MAX_BPF_FUNC_ARGS; i++) { -+ /* extra registers for struct arguments */ -+ for (i = 0; i < m->nr_args; i++) - if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG) -- extra_nregs += (m->arg_size[i] + 7) / 8 - 1; -- } -- if (nr_args + extra_nregs > 6) -+ nr_regs += (m->arg_size[i] + 7) / 8 - 1; -+ -+ /* x86-64 supports up to 6 arguments. 7+ can be added in the future */ -+ if (nr_regs > 6) - return -ENOTSUPP; -- stack_size += extra_nregs * 8; - - /* Generated trampoline stack layout: - * -@@ -2065,11 +2046,12 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - * [ ... ] - * RBP - regs_off [ reg_arg1 ] program's ctx pointer - * -- * RBP - args_off [ arg regs count ] always -+ * RBP - nregs_off [ regs count ] always - * - * RBP - ip_off [ traced function ] BPF_TRAMP_F_IP_ARG flag - * - * RBP - run_ctx_off [ bpf_tramp_run_ctx ] -+ * RSP [ tail_call_cnt ] BPF_TRAMP_F_TAIL_CALL_CTX - */ - - /* room for return value of orig_call or fentry prog */ -@@ -2077,11 +2059,12 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - if (save_ret) - stack_size += 8; - -+ stack_size += nr_regs * 8; - regs_off = stack_size; - -- /* args count */ -+ /* regs count */ - stack_size += 8; -- args_off = stack_size; -+ nregs_off = stack_size; - - if (flags & BPF_TRAMP_F_IP_ARG) - stack_size += 8; /* room for IP address argument */ -@@ -2106,14 +2089,16 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - EMIT1(0x55); /* push rbp */ - EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */ - EMIT4(0x48, 0x83, 0xEC, stack_size); /* sub rsp, stack_size */ -+ if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) -+ EMIT1(0x50); /* push rax */ - EMIT1(0x53); /* push rbx */ - - /* Store number of argument registers of the traced function: -- * mov rax, nr_args + extra_nregs -- * mov QWORD PTR [rbp - args_off], rax -+ * mov rax, nr_regs -+ * mov QWORD PTR [rbp - nregs_off], rax - */ -- emit_mov_imm64(&prog, BPF_REG_0, 0, (u32) nr_args + extra_nregs); -- emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -args_off); -+ emit_mov_imm64(&prog, BPF_REG_0, 0, (u32) nr_regs); -+ emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -nregs_off); - - if (flags & BPF_TRAMP_F_IP_ARG) { - /* Store IP address of the traced function: -@@ -2124,7 +2109,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -ip_off); - } - -- save_regs(m, &prog, nr_args, regs_off); -+ save_regs(m, &prog, nr_regs, regs_off); - - if (flags & BPF_TRAMP_F_CALL_ORIG) { - /* arg1: mov rdi, im */ -@@ -2154,11 +2139,17 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - } - - if (flags & BPF_TRAMP_F_CALL_ORIG) { -- restore_regs(m, &prog, nr_args, regs_off); -+ restore_regs(m, &prog, nr_regs, regs_off); -+ -+ if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) -+ /* Before calling the original function, restore the -+ * tail_call_cnt from stack to rax. -+ */ -+ RESTORE_TAIL_CALL_CNT(stack_size); - - if (flags & BPF_TRAMP_F_ORIG_STACK) { -- emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, 8); -- EMIT2(0xff, 0xd0); /* call *rax */ -+ emit_ldx(&prog, BPF_DW, BPF_REG_6, BPF_REG_FP, 8); -+ EMIT2(0xff, 0xd3); /* call *rbx */ - } else { - /* call original function */ - if (emit_call(&prog, orig_call, prog)) { -@@ -2195,7 +2186,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - } - - if (flags & BPF_TRAMP_F_RESTORE_REGS) -- restore_regs(m, &prog, nr_args, regs_off); -+ restore_regs(m, &prog, nr_regs, regs_off); - - /* This needs to be done regardless. If there were fmod_ret programs, - * the return value is only updated on the stack and still needs to be -@@ -2209,7 +2200,12 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i - ret = -EINVAL; - goto cleanup; - } -- } -+ } else if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) -+ /* Before running the original function, restore the -+ * tail_call_cnt from stack to rax. -+ */ -+ RESTORE_TAIL_CALL_CNT(stack_size); -+ - /* restore return value of orig_call or fentry prog back into RAX */ - if (save_ret) - emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, -8); -diff --git a/block/bdev.c b/block/bdev.c -index d699ecdb32604..b61502ec8da06 100644 ---- a/block/bdev.c -+++ b/block/bdev.c -@@ -507,6 +507,8 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno) - - void bdev_add(struct block_device *bdev, dev_t dev) - { -+ if (bdev_stable_writes(bdev)) -+ mapping_set_stable_writes(bdev->bd_inode->i_mapping); - bdev->bd_dev = dev; - bdev->bd_inode->i_rdev = dev; - bdev->bd_inode->i_ino = dev; -diff --git a/block/blk-mq.c b/block/blk-mq.c -index 100fb0c3114f8..383d94615e502 100644 ---- a/block/blk-mq.c -+++ b/block/blk-mq.c -@@ -2855,11 +2855,8 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, - }; - struct request *rq; - -- if (unlikely(bio_queue_enter(bio))) -- return NULL; -- - if (blk_mq_attempt_bio_merge(q, bio, nsegs)) -- goto queue_exit; -+ return NULL; - - rq_qos_throttle(q, bio); - -@@ -2875,35 +2872,23 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, - rq_qos_cleanup(q, bio); - if (bio->bi_opf & REQ_NOWAIT) - bio_wouldblock_error(bio); --queue_exit: -- blk_queue_exit(q); - return NULL; - } - --static inline struct request *blk_mq_get_cached_request(struct request_queue *q, -- struct blk_plug *plug, struct bio **bio, unsigned int nsegs) -+/* return true if this @rq can be used for @bio */ -+static bool blk_mq_can_use_cached_rq(struct request *rq, struct blk_plug *plug, -+ struct bio *bio) - { -- struct request *rq; -- enum hctx_type type, hctx_type; -+ enum hctx_type type = blk_mq_get_hctx_type(bio->bi_opf); -+ enum hctx_type hctx_type = rq->mq_hctx->type; - -- if (!plug) -- return NULL; -- rq = rq_list_peek(&plug->cached_rq); -- if (!rq || rq->q != q) -- return NULL; -- -- if (blk_mq_attempt_bio_merge(q, *bio, nsegs)) { -- *bio = NULL; -- return NULL; -- } -+ WARN_ON_ONCE(rq_list_peek(&plug->cached_rq) != rq); - -- type = blk_mq_get_hctx_type((*bio)->bi_opf); -- hctx_type = rq->mq_hctx->type; - if (type != hctx_type && - !(type == HCTX_TYPE_READ && hctx_type == HCTX_TYPE_DEFAULT)) -- return NULL; -- if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf)) -- return NULL; -+ return false; -+ if (op_is_flush(rq->cmd_flags) != op_is_flush(bio->bi_opf)) -+ return false; - - /* - * If any qos ->throttle() end up blocking, we will have flushed the -@@ -2911,11 +2896,11 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q, - * before we throttle. - */ - plug->cached_rq = rq_list_next(rq); -- rq_qos_throttle(q, *bio); -+ rq_qos_throttle(rq->q, bio); - -- rq->cmd_flags = (*bio)->bi_opf; -+ rq->cmd_flags = bio->bi_opf; - INIT_LIST_HEAD(&rq->queuelist); -- return rq; -+ return true; - } - - static void bio_set_ioprio(struct bio *bio) -@@ -2944,7 +2929,7 @@ void blk_mq_submit_bio(struct bio *bio) - struct request_queue *q = bdev_get_queue(bio->bi_bdev); - struct blk_plug *plug = blk_mq_plug(bio); - const int is_sync = op_is_sync(bio->bi_opf); -- struct request *rq; -+ struct request *rq = NULL; - unsigned int nr_segs = 1; - blk_status_t ret; - -@@ -2955,20 +2940,36 @@ void blk_mq_submit_bio(struct bio *bio) - return; - } - -- if (!bio_integrity_prep(bio)) -- return; -- - bio_set_ioprio(bio); - -- rq = blk_mq_get_cached_request(q, plug, &bio, nr_segs); -- if (!rq) { -- if (!bio) -+ if (plug) { -+ rq = rq_list_peek(&plug->cached_rq); -+ if (rq && rq->q != q) -+ rq = NULL; -+ } -+ if (rq) { -+ if (!bio_integrity_prep(bio)) - return; -- rq = blk_mq_get_new_requests(q, plug, bio, nr_segs); -- if (unlikely(!rq)) -+ if (blk_mq_attempt_bio_merge(q, bio, nr_segs)) - return; -+ if (blk_mq_can_use_cached_rq(rq, plug, bio)) -+ goto done; -+ percpu_ref_get(&q->q_usage_counter); -+ } else { -+ if (unlikely(bio_queue_enter(bio))) -+ return; -+ if (!bio_integrity_prep(bio)) -+ goto fail; -+ } -+ -+ rq = blk_mq_get_new_requests(q, plug, bio, nr_segs); -+ if (unlikely(!rq)) { -+fail: -+ blk_queue_exit(q); -+ return; - } - -+done: - trace_block_getrq(bio); - - rq_qos_track(q, rq, bio); -diff --git a/block/fops.c b/block/fops.c -index 6197d1c41652d..01cb6260fa24d 100644 ---- a/block/fops.c -+++ b/block/fops.c -@@ -655,24 +655,35 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start, - - filemap_invalidate_lock(inode->i_mapping); - -- /* Invalidate the page cache, including dirty pages. */ -- error = truncate_bdev_range(bdev, file->f_mode, start, end); -- if (error) -- goto fail; -- -+ /* -+ * Invalidate the page cache, including dirty pages, for valid -+ * de-allocate mode calls to fallocate(). -+ */ - switch (mode) { - case FALLOC_FL_ZERO_RANGE: - case FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE: -+ error = truncate_bdev_range(bdev, file->f_mode, start, end); -+ if (error) -+ goto fail; -+ - error = blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT, - len >> SECTOR_SHIFT, GFP_KERNEL, - BLKDEV_ZERO_NOUNMAP); - break; - case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE: -+ error = truncate_bdev_range(bdev, file->f_mode, start, end); -+ if (error) -+ goto fail; -+ - error = blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT, - len >> SECTOR_SHIFT, GFP_KERNEL, - BLKDEV_ZERO_NOFALLBACK); - break; - case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE | FALLOC_FL_NO_HIDE_STALE: -+ error = truncate_bdev_range(bdev, file->f_mode, start, end); -+ if (error) -+ goto fail; -+ - error = blkdev_issue_discard(bdev, start >> SECTOR_SHIFT, - len >> SECTOR_SHIFT, GFP_KERNEL); - break; -diff --git a/drivers/base/memory.c b/drivers/base/memory.c -index 9aa0da991cfb9..5d39f3e374dae 100644 ---- a/drivers/base/memory.c -+++ b/drivers/base/memory.c -@@ -175,6 +175,9 @@ int memory_notify(unsigned long val, void *v) - return blocking_notifier_call_chain(&memory_chain, val, v); - } - -+/* -+ * 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); -@@ -193,10 +196,11 @@ static int memory_block_online(struct memory_block *mem) - * stage helps to keep accounting easier to follow - e.g vmemmaps - * belong to the same zone as the memory they backed. - */ -+ 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, -@@ -204,7 +208,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; - } - - /* -@@ -216,9 +220,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); -@@ -233,6 +242,7 @@ static int memory_block_offline(struct memory_block *mem) - * Unaccount before offlining, such that unpopulated zone and kthreads - * can properly be torn down in offline_pages(). - */ -+ mem_hotplug_begin(); - if (nr_vmemmap_pages) - adjust_present_page_count(pfn_to_page(start_pfn), mem->group, - -nr_vmemmap_pages); -@@ -244,13 +254,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/firewire/ohci.c b/drivers/firewire/ohci.c -index 17c9d825188bb..667ff40f39353 100644 ---- a/drivers/firewire/ohci.c -+++ b/drivers/firewire/ohci.c -@@ -279,6 +279,51 @@ static char ohci_driver_name[] = KBUILD_MODNAME; - #define QUIRK_TI_SLLZ059 0x20 - #define QUIRK_IR_WAKE 0x40 - -+// On PCI Express Root Complex in any type of AMD Ryzen machine, VIA VT6306/6307/6308 with Asmedia -+// ASM1083/1085 brings an inconvenience that the read accesses to 'Isochronous Cycle Timer' register -+// (at offset 0xf0 in PCI I/O space) often causes unexpected system reboot. The mechanism is not -+// clear, since the read access to the other registers is enough safe; e.g. 'Node ID' register, -+// while it is probable due to detection of any type of PCIe error. -+#define QUIRK_REBOOT_BY_CYCLE_TIMER_READ 0x80000000 -+ -+#if IS_ENABLED(CONFIG_X86) -+ -+static bool has_reboot_by_cycle_timer_read_quirk(const struct fw_ohci *ohci) -+{ -+ return !!(ohci->quirks & QUIRK_REBOOT_BY_CYCLE_TIMER_READ); -+} -+ -+#define PCI_DEVICE_ID_ASMEDIA_ASM108X 0x1080 -+ -+static bool detect_vt630x_with_asm1083_on_amd_ryzen_machine(const struct pci_dev *pdev) -+{ -+ const struct pci_dev *pcie_to_pci_bridge; -+ -+ // Detect any type of AMD Ryzen machine. -+ if (!static_cpu_has(X86_FEATURE_ZEN)) -+ return false; -+ -+ // Detect VIA VT6306/6307/6308. -+ if (pdev->vendor != PCI_VENDOR_ID_VIA) -+ return false; -+ if (pdev->device != PCI_DEVICE_ID_VIA_VT630X) -+ return false; -+ -+ // Detect Asmedia ASM1083/1085. -+ pcie_to_pci_bridge = pdev->bus->self; -+ if (pcie_to_pci_bridge->vendor != PCI_VENDOR_ID_ASMEDIA) -+ return false; -+ if (pcie_to_pci_bridge->device != PCI_DEVICE_ID_ASMEDIA_ASM108X) -+ return false; -+ -+ return true; -+} -+ -+#else -+#define has_reboot_by_cycle_timer_read_quirk(ohci) false -+#define detect_vt630x_with_asm1083_on_amd_ryzen_machine(pdev) false -+#endif -+ - /* In case of multiple matches in ohci_quirks[], only the first one is used. */ - static const struct { - unsigned short vendor, device, revision, flags; -@@ -1713,6 +1758,9 @@ static u32 get_cycle_time(struct fw_ohci *ohci) - s32 diff01, diff12; - int i; - -+ if (has_reboot_by_cycle_timer_read_quirk(ohci)) -+ return 0; -+ - c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); - - if (ohci->quirks & QUIRK_CYCLE_TIMER) { -@@ -3615,6 +3663,9 @@ static int pci_probe(struct pci_dev *dev, - if (param_quirks) - ohci->quirks = param_quirks; - -+ if (detect_vt630x_with_asm1083_on_amd_ryzen_machine(dev)) -+ ohci->quirks |= QUIRK_REBOOT_BY_CYCLE_TIMER_READ; -+ - /* - * Because dma_alloc_coherent() allocates at least one page, - * we save space by using a common buffer for the AR request/ -diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c -index 431bda9165c3d..2775bcafe40f6 100644 ---- a/drivers/firmware/arm_scmi/perf.c -+++ b/drivers/firmware/arm_scmi/perf.c -@@ -131,7 +131,7 @@ struct perf_dom_info { - u32 opp_count; - u32 sustained_freq_khz; - u32 sustained_perf_level; -- u32 mult_factor; -+ unsigned long mult_factor; - char name[SCMI_MAX_STR_SIZE]; - struct scmi_opp opp[MAX_OPPS]; - struct scmi_fc_info *fc_info; -@@ -223,8 +223,8 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph, - dom_info->mult_factor = 1000; - else - dom_info->mult_factor = -- (dom_info->sustained_freq_khz * 1000) / -- dom_info->sustained_perf_level; -+ (dom_info->sustained_freq_khz * 1000UL) -+ / dom_info->sustained_perf_level; - strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE); - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index 8a1b84aaaf717..a5352e5e2bd47 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -1976,15 +1976,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) - - adev->firmware.gpu_info_fw = NULL; - -- if (adev->mman.discovery_bin) { -- /* -- * FIXME: The bounding box is still needed by Navi12, so -- * temporarily read it from gpu_info firmware. Should be dropped -- * when DAL no longer needs it. -- */ -- if (adev->asic_type != CHIP_NAVI12) -- return 0; -- } -+ if (adev->mman.discovery_bin) -+ return 0; - - switch (adev->asic_type) { - default: -diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c -index 9d224bb2b3df6..ce893fe1c69f4 100644 ---- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c -+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c -@@ -438,7 +438,115 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = { - .use_urgent_burst_bw = 0 - }; - --struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 }; -+struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { -+ .clock_limits = { -+ { -+ .state = 0, -+ .dcfclk_mhz = 560.0, -+ .fabricclk_mhz = 560.0, -+ .dispclk_mhz = 513.0, -+ .dppclk_mhz = 513.0, -+ .phyclk_mhz = 540.0, -+ .socclk_mhz = 560.0, -+ .dscclk_mhz = 171.0, -+ .dram_speed_mts = 1069.0, -+ }, -+ { -+ .state = 1, -+ .dcfclk_mhz = 694.0, -+ .fabricclk_mhz = 694.0, -+ .dispclk_mhz = 642.0, -+ .dppclk_mhz = 642.0, -+ .phyclk_mhz = 600.0, -+ .socclk_mhz = 694.0, -+ .dscclk_mhz = 214.0, -+ .dram_speed_mts = 1324.0, -+ }, -+ { -+ .state = 2, -+ .dcfclk_mhz = 875.0, -+ .fabricclk_mhz = 875.0, -+ .dispclk_mhz = 734.0, -+ .dppclk_mhz = 734.0, -+ .phyclk_mhz = 810.0, -+ .socclk_mhz = 875.0, -+ .dscclk_mhz = 245.0, -+ .dram_speed_mts = 1670.0, -+ }, -+ { -+ .state = 3, -+ .dcfclk_mhz = 1000.0, -+ .fabricclk_mhz = 1000.0, -+ .dispclk_mhz = 1100.0, -+ .dppclk_mhz = 1100.0, -+ .phyclk_mhz = 810.0, -+ .socclk_mhz = 1000.0, -+ .dscclk_mhz = 367.0, -+ .dram_speed_mts = 2000.0, -+ }, -+ { -+ .state = 4, -+ .dcfclk_mhz = 1200.0, -+ .fabricclk_mhz = 1200.0, -+ .dispclk_mhz = 1284.0, -+ .dppclk_mhz = 1284.0, -+ .phyclk_mhz = 810.0, -+ .socclk_mhz = 1200.0, -+ .dscclk_mhz = 428.0, -+ .dram_speed_mts = 2000.0, -+ }, -+ { -+ .state = 5, -+ .dcfclk_mhz = 1200.0, -+ .fabricclk_mhz = 1200.0, -+ .dispclk_mhz = 1284.0, -+ .dppclk_mhz = 1284.0, -+ .phyclk_mhz = 810.0, -+ .socclk_mhz = 1200.0, -+ .dscclk_mhz = 428.0, -+ .dram_speed_mts = 2000.0, -+ }, -+ }, -+ -+ .num_states = 5, -+ .sr_exit_time_us = 1.9, -+ .sr_enter_plus_exit_time_us = 4.4, -+ .urgent_latency_us = 3.0, -+ .urgent_latency_pixel_data_only_us = 4.0, -+ .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, -+ .urgent_latency_vm_data_only_us = 4.0, -+ .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, -+ .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, -+ .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, -+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0, -+ .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0, -+ .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, -+ .max_avg_sdp_bw_use_normal_percent = 40.0, -+ .max_avg_dram_bw_use_normal_percent = 40.0, -+ .writeback_latency_us = 12.0, -+ .ideal_dram_bw_after_urgent_percent = 40.0, -+ .max_request_size_bytes = 256, -+ .dram_channel_width_bytes = 16, -+ .fabric_datapath_to_dcn_data_return_bytes = 64, -+ .dcn_downspread_percent = 0.5, -+ .downspread_percent = 0.5, -+ .dram_page_open_time_ns = 50.0, -+ .dram_rw_turnaround_time_ns = 17.5, -+ .dram_return_buffer_per_channel_bytes = 8192, -+ .round_trip_ping_latency_dcfclk_cycles = 131, -+ .urgent_out_of_order_return_per_channel_bytes = 4096, -+ .channel_interleave_bytes = 256, -+ .num_banks = 8, -+ .num_chans = 16, -+ .vmm_page_size_bytes = 4096, -+ .dram_clock_change_latency_us = 45.0, -+ .writeback_dram_clock_change_latency_us = 23.0, -+ .return_bus_width_bytes = 64, -+ .dispclk_dppclk_vco_speed_mhz = 3850, -+ .xfc_bus_transport_time_us = 20, -+ .xfc_xbuf_latency_tolerance_us = 50, -+ .use_urgent_burst_bw = 0, -+}; - - struct _vcs_dpi_ip_params_st dcn2_1_ip = { - .odm_capable = 1, -diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -index 1b5c27ed27370..ff4d0564122a3 100644 ---- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c -+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c -@@ -527,6 +527,7 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux, - u32 request_val = AUX_CMD_REQ(msg->request); - u8 *buf = msg->buffer; - unsigned int len = msg->size; -+ unsigned int short_len; - unsigned int val; - int ret; - u8 addr_len[SN_AUX_LENGTH_REG + 1 - SN_AUX_ADDR_19_16_REG]; -@@ -600,7 +601,8 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux, - } - - if (val & AUX_IRQ_STATUS_AUX_SHORT) { -- ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &len); -+ ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &short_len); -+ len = min(len, short_len); - if (ret) - goto exit; - } else if (val & AUX_IRQ_STATUS_NAT_I2C_FAIL) { -diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c -index 5970f4149090f..4699c21102261 100644 ---- a/drivers/gpu/drm/i915/display/intel_dp.c -+++ b/drivers/gpu/drm/i915/display/intel_dp.c -@@ -3707,7 +3707,7 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, - intel_dp->train_set, crtc_state->lane_count); - - drm_dp_set_phy_test_pattern(&intel_dp->aux, data, -- link_status[DP_DPCD_REV]); -+ intel_dp->dpcd[DP_DPCD_REV]); - } - - static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) -diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h -index f0c2349404b46..aebd09e2d4087 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_drv.h -+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h -@@ -390,6 +390,11 @@ void mgag200_primary_plane_helper_atomic_disable(struct drm_plane *plane, - .destroy = drm_plane_cleanup, \ - DRM_GEM_SHADOW_PLANE_FUNCS - -+void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, const struct drm_format_info *format); -+void mgag200_crtc_set_gamma(struct mga_device *mdev, -+ const struct drm_format_info *format, -+ struct drm_color_lut *lut); -+ - enum drm_mode_status mgag200_crtc_helper_mode_valid(struct drm_crtc *crtc, - const struct drm_display_mode *mode); - int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *new_state); -diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c -index bce267e0f7de3..8d4538b710477 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_g200er.c -+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c -@@ -202,6 +202,11 @@ static void mgag200_g200er_crtc_helper_atomic_enable(struct drm_crtc *crtc, - - mgag200_g200er_reset_tagfifo(mdev); - -+ if (crtc_state->gamma_lut) -+ mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data); -+ else -+ mgag200_crtc_set_gamma_linear(mdev, format); -+ - mgag200_enable_display(mdev); - - if (funcs->enable_vidrst) -diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c -index ac957f42abe18..56e6f986bff31 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c -+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c -@@ -203,6 +203,11 @@ static void mgag200_g200ev_crtc_helper_atomic_enable(struct drm_crtc *crtc, - - mgag200_g200ev_set_hiprilvl(mdev); - -+ if (crtc_state->gamma_lut) -+ mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data); -+ else -+ mgag200_crtc_set_gamma_linear(mdev, format); -+ - mgag200_enable_display(mdev); - - if (funcs->enable_vidrst) -diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c -index bd6e573c9a1a3..ff2b3c6622e7a 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_g200se.c -+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c -@@ -334,6 +334,11 @@ static void mgag200_g200se_crtc_helper_atomic_enable(struct drm_crtc *crtc, - - mgag200_g200se_set_hiprilvl(mdev, adjusted_mode, format); - -+ if (crtc_state->gamma_lut) -+ mgag200_crtc_set_gamma(mdev, format, crtc_state->gamma_lut->data); -+ else -+ mgag200_crtc_set_gamma_linear(mdev, format); -+ - mgag200_enable_display(mdev); - - if (funcs->enable_vidrst) -diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c -index ae90b260312a5..554adf05e0734 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_mode.c -+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c -@@ -28,8 +28,8 @@ - * This file contains setup code for the CRTC. - */ - --static void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, -- const struct drm_format_info *format) -+void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, -+ const struct drm_format_info *format) - { - int i; - -@@ -65,9 +65,9 @@ static void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, - } - } - --static void mgag200_crtc_set_gamma(struct mga_device *mdev, -- const struct drm_format_info *format, -- struct drm_color_lut *lut) -+void mgag200_crtc_set_gamma(struct mga_device *mdev, -+ const struct drm_format_info *format, -+ struct drm_color_lut *lut) - { - int i; - -diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h -index 05b8b8dfa9bdd..36587f38dff3d 100644 ---- a/drivers/i2c/i2c-core.h -+++ b/drivers/i2c/i2c-core.h -@@ -3,6 +3,7 @@ - * i2c-core.h - interfaces internal to the I2C framework - */ - -+#include - #include - - struct i2c_devinfo { -@@ -29,7 +30,8 @@ int i2c_dev_irq_from_resources(const struct resource *resources, - */ - static inline bool i2c_in_atomic_xfer_mode(void) - { -- return system_state > SYSTEM_RUNNING && !preemptible(); -+ return system_state > SYSTEM_RUNNING && -+ (IS_ENABLED(CONFIG_PREEMPT_COUNT) ? !preemptible() : irqs_disabled()); - } - - static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap) -diff --git a/drivers/interconnect/qcom/sm8250.c b/drivers/interconnect/qcom/sm8250.c -index 9c2dd40d9a559..5cdb058fa0959 100644 ---- a/drivers/interconnect/qcom/sm8250.c -+++ b/drivers/interconnect/qcom/sm8250.c -@@ -551,7 +551,6 @@ static struct platform_driver qnoc_driver = { - .driver = { - .name = "qnoc-sm8250", - .of_match_table = qnoc_of_match, -- .sync_state = icc_sync_state, - }, - }; - module_platform_driver(qnoc_driver); -diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c -index 904208f6f9546..0147cc062e1ae 100644 ---- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c -+++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c -@@ -334,13 +334,14 @@ static const struct csid_format csid_formats[] = { - }, - }; - --static void csid_configure_stream(struct csid_device *csid, u8 enable) -+static void __csid_configure_stream(struct csid_device *csid, u8 enable, u8 vc) - { - struct csid_testgen_config *tg = &csid->testgen; - u32 val; - u32 phy_sel = 0; - u8 lane_cnt = csid->phy.lane_cnt; -- struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_SRC]; -+ /* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */ -+ struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc]; - const struct csid_format *format = csid_get_fmt_entry(csid->formats, csid->nformats, - input_format->code); - -@@ -351,8 +352,19 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable) - phy_sel = csid->phy.csiphy_id; - - if (enable) { -- u8 vc = 0; /* Virtual Channel 0 */ -- u8 dt_id = vc * 4; -+ /* -+ * DT_ID is a two bit bitfield that is concatenated with -+ * the four least significant bits of the five bit VC -+ * bitfield to generate an internal CID value. -+ * -+ * CSID_RDI_CFG0(vc) -+ * DT_ID : 28:27 -+ * VC : 26:22 -+ * DT : 21:16 -+ * -+ * CID : VC 3:0 << 2 | DT_ID 1:0 -+ */ -+ u8 dt_id = vc & 0x03; - - if (tg->enabled) { - /* configure one DT, infinite frames */ -@@ -392,42 +404,42 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable) - val |= format->data_type << RDI_CFG0_DATA_TYPE; - val |= vc << RDI_CFG0_VIRTUAL_CHANNEL; - val |= dt_id << RDI_CFG0_DT_ID; -- writel_relaxed(val, csid->base + CSID_RDI_CFG0(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc)); - - /* CSID_TIMESTAMP_STB_POST_IRQ */ - val = 2 << RDI_CFG1_TIMESTAMP_STB_SEL; -- writel_relaxed(val, csid->base + CSID_RDI_CFG1(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_CFG1(vc)); - - val = 1; -- writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(vc)); - - val = 0; -- writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PATTERN(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PATTERN(vc)); - - val = 1; -- writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc)); - - val = 0; -- writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc)); - - val = 1; -- writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PERIOD(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PERIOD(vc)); - - val = 0; -- writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PATTERN(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PATTERN(vc)); - - val = 1; -- writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PERIOD(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PERIOD(vc)); - - val = 0; -- writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PATTERN(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PATTERN(vc)); - - val = 0; -- writel_relaxed(val, csid->base + CSID_RDI_CTRL(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc)); - -- val = readl_relaxed(csid->base + CSID_RDI_CFG0(0)); -+ val = readl_relaxed(csid->base + CSID_RDI_CFG0(vc)); - val |= 1 << RDI_CFG0_ENABLE; -- writel_relaxed(val, csid->base + CSID_RDI_CFG0(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc)); - } - - if (tg->enabled) { -@@ -446,6 +458,8 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable) - writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0); - - val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN; -+ if (vc > 3) -+ val |= 1 << CSI2_RX_CFG1_VC_MODE; - val |= 1 << CSI2_RX_CFG1_MISR_EN; - writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1); - -@@ -453,7 +467,16 @@ static void csid_configure_stream(struct csid_device *csid, u8 enable) - val = HALT_CMD_RESUME_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD; - else - val = HALT_CMD_HALT_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD; -- writel_relaxed(val, csid->base + CSID_RDI_CTRL(0)); -+ writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc)); -+} -+ -+static void csid_configure_stream(struct csid_device *csid, u8 enable) -+{ -+ u8 i; -+ /* Loop through all enabled VCs and configure stream for each */ -+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) -+ if (csid->phy.en_vc & BIT(i)) -+ __csid_configure_stream(csid, enable, i); - } - - static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val) -@@ -499,6 +522,7 @@ static irqreturn_t csid_isr(int irq, void *dev) - struct csid_device *csid = dev; - u32 val; - u8 reset_done; -+ int i; - - val = readl_relaxed(csid->base + CSID_TOP_IRQ_STATUS); - writel_relaxed(val, csid->base + CSID_TOP_IRQ_CLEAR); -@@ -507,8 +531,12 @@ static irqreturn_t csid_isr(int irq, void *dev) - val = readl_relaxed(csid->base + CSID_CSI2_RX_IRQ_STATUS); - writel_relaxed(val, csid->base + CSID_CSI2_RX_IRQ_CLEAR); - -- val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(0)); -- writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(0)); -+ /* Read and clear IRQ status for each enabled RDI channel */ -+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) -+ if (csid->phy.en_vc & BIT(i)) { -+ val = readl_relaxed(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i)); -+ writel_relaxed(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i)); -+ } - - val = 1 << IRQ_CMD_CLEAR; - writel_relaxed(val, csid->base + CSID_IRQ_CMD); -diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c -index 88f188e0f7501..6360314f04a63 100644 ---- a/drivers/media/platform/qcom/camss/camss-csid.c -+++ b/drivers/media/platform/qcom/camss/camss-csid.c -@@ -196,6 +196,8 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) - return ret; - } - -+ csid->phy.need_vc_update = true; -+ - enable_irq(csid->irq); - - ret = csid->ops->reset(csid); -@@ -249,7 +251,10 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) - return -ENOLINK; - } - -- csid->ops->configure_stream(csid, enable); -+ if (csid->phy.need_vc_update) { -+ csid->ops->configure_stream(csid, enable); -+ csid->phy.need_vc_update = false; -+ } - - return 0; - } -@@ -460,6 +465,7 @@ static int csid_set_format(struct v4l2_subdev *sd, - { - struct csid_device *csid = v4l2_get_subdevdata(sd); - struct v4l2_mbus_framefmt *format; -+ int i; - - format = __csid_get_format(csid, sd_state, fmt->pad, fmt->which); - if (format == NULL) -@@ -468,14 +474,14 @@ static int csid_set_format(struct v4l2_subdev *sd, - csid_try_format(csid, sd_state, fmt->pad, &fmt->format, fmt->which); - *format = fmt->format; - -- /* Propagate the format from sink to source */ -+ /* Propagate the format from sink to source pads */ - if (fmt->pad == MSM_CSID_PAD_SINK) { -- format = __csid_get_format(csid, sd_state, MSM_CSID_PAD_SRC, -- fmt->which); -+ for (i = MSM_CSID_PAD_FIRST_SRC; i < MSM_CSID_PADS_NUM; ++i) { -+ format = __csid_get_format(csid, sd_state, i, fmt->which); - -- *format = fmt->format; -- csid_try_format(csid, sd_state, MSM_CSID_PAD_SRC, format, -- fmt->which); -+ *format = fmt->format; -+ csid_try_format(csid, sd_state, i, format, fmt->which); -+ } - } - - return 0; -@@ -738,7 +744,6 @@ static int csid_link_setup(struct media_entity *entity, - struct csid_device *csid; - struct csiphy_device *csiphy; - struct csiphy_lanes_cfg *lane_cfg; -- struct v4l2_subdev_format format = { 0 }; - - sd = media_entity_to_v4l2_subdev(entity); - csid = v4l2_get_subdevdata(sd); -@@ -761,11 +766,22 @@ static int csid_link_setup(struct media_entity *entity, - lane_cfg = &csiphy->cfg.csi2->lane_cfg; - csid->phy.lane_cnt = lane_cfg->num_data; - csid->phy.lane_assign = csid_get_lane_assign(lane_cfg); -+ } -+ /* Decide which virtual channels to enable based on which source pads are enabled */ -+ if (local->flags & MEDIA_PAD_FL_SOURCE) { -+ struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); -+ struct csid_device *csid = v4l2_get_subdevdata(sd); -+ struct device *dev = csid->camss->dev; -+ -+ if (flags & MEDIA_LNK_FL_ENABLED) -+ csid->phy.en_vc |= BIT(local->index - 1); -+ else -+ csid->phy.en_vc &= ~BIT(local->index - 1); - -- /* Reset format on source pad to sink pad format */ -- format.pad = MSM_CSID_PAD_SRC; -- format.which = V4L2_SUBDEV_FORMAT_ACTIVE; -- csid_set_format(&csid->subdev, NULL, &format); -+ csid->phy.need_vc_update = true; -+ -+ dev_dbg(dev, "%s: Enabled CSID virtual channels mask 0x%x\n", -+ __func__, csid->phy.en_vc); - } - - return 0; -@@ -816,6 +832,7 @@ int msm_csid_register_entity(struct csid_device *csid, - struct v4l2_subdev *sd = &csid->subdev; - struct media_pad *pads = csid->pads; - struct device *dev = csid->camss->dev; -+ int i; - int ret; - - v4l2_subdev_init(sd, &csid_v4l2_ops); -@@ -852,7 +869,8 @@ int msm_csid_register_entity(struct csid_device *csid, - } - - pads[MSM_CSID_PAD_SINK].flags = MEDIA_PAD_FL_SINK; -- pads[MSM_CSID_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE; -+ for (i = MSM_CSID_PAD_FIRST_SRC; i < MSM_CSID_PADS_NUM; ++i) -+ pads[i].flags = MEDIA_PAD_FL_SOURCE; - - sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; - sd->entity.ops = &csid_media_ops; -diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h -index f06040e44c515..d4b48432a0973 100644 ---- a/drivers/media/platform/qcom/camss/camss-csid.h -+++ b/drivers/media/platform/qcom/camss/camss-csid.h -@@ -19,8 +19,13 @@ - #include - - #define MSM_CSID_PAD_SINK 0 --#define MSM_CSID_PAD_SRC 1 --#define MSM_CSID_PADS_NUM 2 -+#define MSM_CSID_PAD_FIRST_SRC 1 -+#define MSM_CSID_PADS_NUM 5 -+ -+#define MSM_CSID_PAD_SRC (MSM_CSID_PAD_FIRST_SRC) -+ -+/* CSID hardware can demultiplex up to 4 outputs */ -+#define MSM_CSID_MAX_SRC_STREAMS 4 - - #define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12 - #define DATA_TYPE_YUV420_8BIT 0x18 -@@ -81,6 +86,8 @@ struct csid_phy_config { - u8 csiphy_id; - u8 lane_cnt; - u32 lane_assign; -+ u32 en_vc; -+ u8 need_vc_update; - }; - - struct csid_device; -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index 770490234c872..e9ce53d200bc1 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -866,9 +866,10 @@ static const struct block_device_operations mmc_bdops = { - static int mmc_blk_part_switch_pre(struct mmc_card *card, - unsigned int part_type) - { -+ const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB; - int ret = 0; - -- if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) { -+ if ((part_type & mask) == mask) { - if (card->ext_csd.cmdq_en) { - ret = mmc_cmdq_disable(card); - if (ret) -@@ -883,9 +884,10 @@ static int mmc_blk_part_switch_pre(struct mmc_card *card, - static int mmc_blk_part_switch_post(struct mmc_card *card, - unsigned int part_type) - { -+ const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB; - int ret = 0; - -- if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) { -+ if ((part_type & mask) == mask) { - mmc_retune_unpause(card->host); - if (card->reenable_cmdq && !card->ext_csd.cmdq_en) - ret = mmc_cmdq_enable(card); -@@ -3180,4 +3182,3 @@ module_exit(mmc_blk_exit); - - MODULE_LICENSE("GPL"); - MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); -- -diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c -index b89dca1f15e9c..25c152ef5d60e 100644 ---- a/drivers/mmc/core/host.c -+++ b/drivers/mmc/core/host.c -@@ -670,6 +670,7 @@ EXPORT_SYMBOL(mmc_remove_host); - */ - void mmc_free_host(struct mmc_host *host) - { -+ cancel_delayed_work_sync(&host->detect); - mmc_pwrseq_free(host); - put_device(&host->class_dev); - } -diff --git a/drivers/mmc/host/meson-mx-sdhc-mmc.c b/drivers/mmc/host/meson-mx-sdhc-mmc.c -index da85c2f2acb83..c0e3b1634a88a 100644 ---- a/drivers/mmc/host/meson-mx-sdhc-mmc.c -+++ b/drivers/mmc/host/meson-mx-sdhc-mmc.c -@@ -269,7 +269,7 @@ static int meson_mx_sdhc_enable_clks(struct mmc_host *mmc) - static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios) - { - struct meson_mx_sdhc_host *host = mmc_priv(mmc); -- u32 rx_clk_phase; -+ u32 val, rx_clk_phase; - int ret; - - meson_mx_sdhc_disable_clks(mmc); -@@ -290,27 +290,11 @@ static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios) - mmc->actual_clock = clk_get_rate(host->sd_clk); - - /* -- * according to Amlogic the following latching points are -- * selected with empirical values, there is no (known) formula -- * to calculate these. -+ * Phase 90 should work in most cases. For data transmission, -+ * meson_mx_sdhc_execute_tuning() will find a accurate value - */ -- if (mmc->actual_clock > 100000000) { -- rx_clk_phase = 1; -- } else if (mmc->actual_clock > 45000000) { -- if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) -- rx_clk_phase = 15; -- else -- rx_clk_phase = 11; -- } else if (mmc->actual_clock >= 25000000) { -- rx_clk_phase = 15; -- } else if (mmc->actual_clock > 5000000) { -- rx_clk_phase = 23; -- } else if (mmc->actual_clock > 1000000) { -- rx_clk_phase = 55; -- } else { -- rx_clk_phase = 1061; -- } -- -+ regmap_read(host->regmap, MESON_SDHC_CLKC, &val); -+ rx_clk_phase = FIELD_GET(MESON_SDHC_CLKC_CLK_DIV, val) / 4; - regmap_update_bits(host->regmap, MESON_SDHC_CLK2, - MESON_SDHC_CLK2_RX_CLK_PHASE, - FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE, -diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c -index 2101b6e794c0e..66c1782823d89 100644 ---- a/drivers/mmc/host/sdhci-sprd.c -+++ b/drivers/mmc/host/sdhci-sprd.c -@@ -228,15 +228,19 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host, - div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8); - sdhci_enable_clk(host, div); - -+ val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); -+ mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN; - /* Enable CLK_AUTO when the clock is greater than 400K. */ - if (clk > 400000) { -- val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); -- mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | -- SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN; - if (mask != (val & mask)) { - val |= mask; - sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); - } -+ } else { -+ if (val & mask) { -+ val &= ~mask; -+ sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); -+ } - } - } - -diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -index 623cdeb29ed90..df4d88d35701b 100644 ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -@@ -12081,6 +12081,8 @@ static void bnxt_sp_task(struct work_struct *work) - bnxt_cfg_ntp_filters(bp); - if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) - bnxt_hwrm_exec_fwd_req(bp); -+ if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) -+ netdev_info(bp->dev, "Receive PF driver unload event!\n"); - if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) { - bnxt_hwrm_port_qstats(bp, 0); - bnxt_hwrm_port_qstats_ext(bp, 0); -@@ -13059,8 +13061,6 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp) - } - } - } -- if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) -- netdev_info(bp->dev, "Receive PF driver unload event!\n"); - } - - #else -diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c -index 1ae082eb9e905..c2a9913082153 100644 ---- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c -+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c -@@ -2131,8 +2131,10 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) - /* Note: if we ever change from DMA_TX_APPEND_CRC below we - * will need to restore software padding of "runt" packets - */ -+ len_stat |= DMA_TX_APPEND_CRC; -+ - if (!i) { -- len_stat |= DMA_TX_APPEND_CRC | DMA_SOP; -+ len_stat |= DMA_SOP; - if (skb->ip_summed == CHECKSUM_PARTIAL) - len_stat |= DMA_TX_DO_CSUM; - } -diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -index b58162ce81d87..de62eee58a00e 100644 ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -509,8 +509,6 @@ static struct sk_buff *dpaa2_eth_copybreak(struct dpaa2_eth_channel *ch, - - memcpy(skb->data, fd_vaddr + fd_offset, fd_length); - -- dpaa2_eth_recycle_buf(priv, ch, dpaa2_fd_get_addr(fd)); -- - return skb; - } - -@@ -528,6 +526,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, - struct dpaa2_eth_drv_stats *percpu_extras; - struct device *dev = priv->net_dev->dev.parent; - struct dpaa2_fas *fas; -+ bool recycle_rx_buf = false; - void *buf_data; - u32 status = 0; - u32 xdp_act; -@@ -560,6 +559,8 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, - dma_unmap_page(dev, addr, priv->rx_buf_size, - DMA_BIDIRECTIONAL); - skb = dpaa2_eth_build_linear_skb(ch, fd, vaddr); -+ } else { -+ recycle_rx_buf = true; - } - } else if (fd_format == dpaa2_fd_sg) { - WARN_ON(priv->xdp_prog); -@@ -607,6 +608,8 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, - - list_add_tail(&skb->list, ch->rx_list); - -+ if (recycle_rx_buf) -+ dpaa2_eth_recycle_buf(priv, ch, dpaa2_fd_get_addr(fd)); - return; - - err_build_skb: -diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -index eea7d7a07c007..59888826469b9 100644 ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -227,17 +227,8 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev, - struct ethtool_stats *stats, - u64 *data) - { -- int i = 0; -- int j, k, err; -- int num_cnt; -- union dpni_statistics dpni_stats; -- u32 fcnt, bcnt; -- u32 fcnt_rx_total = 0, fcnt_tx_total = 0; -- u32 bcnt_rx_total = 0, bcnt_tx_total = 0; -- u32 buf_cnt; - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -- struct dpaa2_eth_drv_stats *extras; -- struct dpaa2_eth_ch_stats *ch_stats; -+ union dpni_statistics dpni_stats; - int dpni_stats_page_size[DPNI_STATISTICS_CNT] = { - sizeof(dpni_stats.page_0), - sizeof(dpni_stats.page_1), -@@ -247,6 +238,13 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev, - sizeof(dpni_stats.page_5), - sizeof(dpni_stats.page_6), - }; -+ u32 fcnt_rx_total = 0, fcnt_tx_total = 0; -+ u32 bcnt_rx_total = 0, bcnt_tx_total = 0; -+ struct dpaa2_eth_ch_stats *ch_stats; -+ struct dpaa2_eth_drv_stats *extras; -+ int j, k, err, num_cnt, i = 0; -+ u32 fcnt, bcnt; -+ u32 buf_cnt; - - memset(data, 0, - sizeof(u64) * (DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS)); -diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c -index b4157ff370a31..63d43ef86f9b9 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -104,12 +104,18 @@ static struct workqueue_struct *i40e_wq; - static void netdev_hw_addr_refcnt(struct i40e_mac_filter *f, - struct net_device *netdev, int delta) - { -+ struct netdev_hw_addr_list *ha_list; - struct netdev_hw_addr *ha; - - if (!f || !netdev) - return; - -- netdev_for_each_mc_addr(ha, netdev) { -+ if (is_unicast_ether_addr(f->macaddr) || is_link_local_ether_addr(f->macaddr)) -+ ha_list = &netdev->uc; -+ else -+ ha_list = &netdev->mc; -+ -+ netdev_hw_addr_list_for_each(ha, ha_list) { - if (ether_addr_equal(ha->addr, f->macaddr)) { - ha->refcount += delta; - if (ha->refcount <= 0) -@@ -16444,6 +16450,9 @@ static void i40e_pci_error_reset_done(struct pci_dev *pdev) - return; - - i40e_reset_and_rebuild(pf, false, false); -+#ifdef CONFIG_PCI_IOV -+ i40e_restore_all_vfs_msi_state(pdev); -+#endif /* CONFIG_PCI_IOV */ - } - - /** -diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -index cb925baf72ce0..c7d761426d6ce 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c -@@ -152,6 +152,32 @@ void i40e_vc_notify_reset(struct i40e_pf *pf) - (u8 *)&pfe, sizeof(struct virtchnl_pf_event)); - } - -+#ifdef CONFIG_PCI_IOV -+void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev) -+{ -+ u16 vf_id; -+ u16 pos; -+ -+ /* Continue only if this is a PF */ -+ if (!pdev->is_physfn) -+ return; -+ -+ if (!pci_num_vf(pdev)) -+ return; -+ -+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); -+ if (pos) { -+ struct pci_dev *vf_dev = NULL; -+ -+ pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id); -+ while ((vf_dev = pci_get_device(pdev->vendor, vf_id, vf_dev))) { -+ if (vf_dev->is_virtfn && vf_dev->physfn == pdev) -+ pci_restore_msi_state(vf_dev); -+ } -+ } -+} -+#endif /* CONFIG_PCI_IOV */ -+ - /** - * i40e_vc_notify_vf_reset - * @vf: pointer to the VF structure -@@ -3451,16 +3477,16 @@ static int i40e_validate_cloud_filter(struct i40e_vf *vf, - bool found = false; - int bkt; - -- if (!tc_filter->action) { -+ if (tc_filter->action != VIRTCHNL_ACTION_TC_REDIRECT) { - dev_info(&pf->pdev->dev, -- "VF %d: Currently ADq doesn't support Drop Action\n", -- vf->vf_id); -+ "VF %d: ADQ doesn't support this action (%d)\n", -+ vf->vf_id, tc_filter->action); - goto err; - } - - /* action_meta is TC number here to which the filter is applied */ - if (!tc_filter->action_meta || -- tc_filter->action_meta > I40E_MAX_VF_VSI) { -+ tc_filter->action_meta > vf->num_tc) { - dev_info(&pf->pdev->dev, "VF %d: Invalid TC number %u\n", - vf->vf_id, tc_filter->action_meta); - goto err; -diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h -index 358bbdb587951..bd497cc5303a1 100644 ---- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h -+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h -@@ -135,6 +135,9 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable); - - void i40e_vc_notify_link_state(struct i40e_pf *pf); - void i40e_vc_notify_reset(struct i40e_pf *pf); -+#ifdef CONFIG_PCI_IOV -+void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev); -+#endif /* CONFIG_PCI_IOV */ - int i40e_get_vf_stats(struct net_device *netdev, int vf_id, - struct ifla_vf_stats *vf_stats); - -diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c -index f0f39364819ac..ab46cfca4028d 100644 ---- a/drivers/net/ethernet/intel/ice/ice_main.c -+++ b/drivers/net/ethernet/intel/ice/ice_main.c -@@ -2138,7 +2138,7 @@ static int ice_configure_phy(struct ice_vsi *vsi) - - /* Ensure we have media as we cannot configure a medialess port */ - if (!(phy->link_info.link_info & ICE_AQ_MEDIA_AVAILABLE)) -- return -EPERM; -+ return -ENOMEDIUM; - - ice_print_topo_conflict(vsi); - -@@ -9065,8 +9065,14 @@ int ice_stop(struct net_device *netdev) - int link_err = ice_force_phys_link_state(vsi, false); - - if (link_err) { -- netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n", -- vsi->vsi_num, link_err); -+ if (link_err == -ENOMEDIUM) -+ netdev_info(vsi->netdev, "Skipping link reconfig - no media attached, VSI %d\n", -+ vsi->vsi_num); -+ else -+ netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n", -+ vsi->vsi_num, link_err); -+ -+ ice_vsi_close(vsi); - return -EIO; - } - } -diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h -index 43c05b41627f7..2a894ca49d93b 100644 ---- a/drivers/net/ethernet/intel/igc/igc.h -+++ b/drivers/net/ethernet/intel/igc/igc.h -@@ -538,6 +538,7 @@ struct igc_nfc_filter { - u16 etype; - __be16 vlan_etype; - u16 vlan_tci; -+ u16 vlan_tci_mask; - u8 src_addr[ETH_ALEN]; - u8 dst_addr[ETH_ALEN]; - u8 user_data[8]; -diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c -index 81897f7a90a91..2bee9cace5983 100644 ---- a/drivers/net/ethernet/intel/igc/igc_ethtool.c -+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c -@@ -957,6 +957,7 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev, - } - - #define ETHER_TYPE_FULL_MASK ((__force __be16)~0) -+#define VLAN_TCI_FULL_MASK ((__force __be16)~0) - static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter, - struct ethtool_rxnfc *cmd) - { -@@ -979,10 +980,16 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter, - fsp->m_u.ether_spec.h_proto = ETHER_TYPE_FULL_MASK; - } - -+ if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) { -+ fsp->flow_type |= FLOW_EXT; -+ fsp->h_ext.vlan_etype = rule->filter.vlan_etype; -+ fsp->m_ext.vlan_etype = ETHER_TYPE_FULL_MASK; -+ } -+ - if (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) { - fsp->flow_type |= FLOW_EXT; - fsp->h_ext.vlan_tci = htons(rule->filter.vlan_tci); -- fsp->m_ext.vlan_tci = htons(VLAN_PRIO_MASK); -+ fsp->m_ext.vlan_tci = htons(rule->filter.vlan_tci_mask); - } - - if (rule->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) { -@@ -1217,6 +1224,7 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule, - - if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) { - rule->filter.vlan_tci = ntohs(fsp->h_ext.vlan_tci); -+ rule->filter.vlan_tci_mask = ntohs(fsp->m_ext.vlan_tci); - rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_TCI; - } - -@@ -1254,11 +1262,19 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule, - memcpy(rule->filter.user_mask, fsp->m_ext.data, sizeof(fsp->m_ext.data)); - } - -- /* When multiple filter options or user data or vlan etype is set, use a -- * flex filter. -+ /* The i225/i226 has various different filters. Flex filters provide a -+ * way to match up to the first 128 bytes of a packet. Use them for: -+ * a) For specific user data -+ * b) For VLAN EtherType -+ * c) For full TCI match -+ * d) Or in case multiple filter criteria are set -+ * -+ * Otherwise, use the simple MAC, VLAN PRIO or EtherType filters. - */ - if ((rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) || - (rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) || -+ ((rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_TCI) && -+ rule->filter.vlan_tci_mask == ntohs(VLAN_TCI_FULL_MASK)) || - (rule->filter.match_flags & (rule->filter.match_flags - 1))) - rule->flex = true; - else -@@ -1328,6 +1344,26 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter, - return -EINVAL; - } - -+ /* There are two ways to match the VLAN TCI: -+ * 1. Match on PCP field and use vlan prio filter for it -+ * 2. Match on complete TCI field and use flex filter for it -+ */ -+ if ((fsp->flow_type & FLOW_EXT) && -+ fsp->m_ext.vlan_tci && -+ fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK) && -+ fsp->m_ext.vlan_tci != VLAN_TCI_FULL_MASK) { -+ netdev_dbg(netdev, "VLAN mask not supported\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ /* VLAN EtherType can only be matched by full mask. */ -+ if ((fsp->flow_type & FLOW_EXT) && -+ fsp->m_ext.vlan_etype && -+ fsp->m_ext.vlan_etype != ETHER_TYPE_FULL_MASK) { -+ netdev_dbg(netdev, "VLAN EtherType mask not supported\n"); -+ return -EOPNOTSUPP; -+ } -+ - if (fsp->location >= IGC_MAX_RXNFC_RULES) { - netdev_dbg(netdev, "Invalid location\n"); - return -EINVAL; -diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c -index 725db36e399d2..31ea0781b65ec 100644 ---- a/drivers/net/ethernet/intel/igc/igc_tsn.c -+++ b/drivers/net/ethernet/intel/igc/igc_tsn.c -@@ -178,7 +178,7 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter) - wr32(IGC_TQAVCC(i), tqavcc); - - wr32(IGC_TQAVHC(i), -- 0x80000000 + ring->hicredit * 0x7735); -+ 0x80000000 + ring->hicredit * 0x7736); - } else { - /* Disable any CBS for the queue */ - txqctl &= ~(IGC_TXQCTL_QAV_SEL_MASK); -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c -index 65c0373d34d12..90be87dc105d3 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c -@@ -78,7 +78,7 @@ static bool is_dev_rpm(void *cgxd) - - bool is_lmac_valid(struct cgx *cgx, int lmac_id) - { -- if (!cgx || lmac_id < 0 || lmac_id >= MAX_LMAC_PER_CGX) -+ if (!cgx || lmac_id < 0 || lmac_id >= cgx->max_lmac_per_mac) - return false; - return test_bit(lmac_id, &cgx->lmac_bmap); - } -@@ -90,7 +90,7 @@ static int get_sequence_id_of_lmac(struct cgx *cgx, int lmac_id) - { - int tmp, id = 0; - -- for_each_set_bit(tmp, &cgx->lmac_bmap, MAX_LMAC_PER_CGX) { -+ for_each_set_bit(tmp, &cgx->lmac_bmap, cgx->max_lmac_per_mac) { - if (tmp == lmac_id) - break; - id++; -@@ -121,7 +121,7 @@ u64 cgx_read(struct cgx *cgx, u64 lmac, u64 offset) - - struct lmac *lmac_pdata(u8 lmac_id, struct cgx *cgx) - { -- if (!cgx || lmac_id >= MAX_LMAC_PER_CGX) -+ if (!cgx || lmac_id >= cgx->max_lmac_per_mac) - return NULL; - - return cgx->lmac_idmap[lmac_id]; -@@ -1410,7 +1410,7 @@ int cgx_get_fwdata_base(u64 *base) - if (!cgx) - return -ENXIO; - -- first_lmac = find_first_bit(&cgx->lmac_bmap, MAX_LMAC_PER_CGX); -+ first_lmac = find_first_bit(&cgx->lmac_bmap, cgx->max_lmac_per_mac); - req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_FWD_BASE, req); - err = cgx_fwi_cmd_generic(req, &resp, cgx, first_lmac); - if (!err) -@@ -1499,7 +1499,7 @@ static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable) - - static inline int cgx_fwi_read_version(u64 *resp, struct cgx *cgx) - { -- int first_lmac = find_first_bit(&cgx->lmac_bmap, MAX_LMAC_PER_CGX); -+ int first_lmac = find_first_bit(&cgx->lmac_bmap, cgx->max_lmac_per_mac); - u64 req = 0; - - req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_FW_VER, req); -@@ -1537,7 +1537,7 @@ static void cgx_lmac_linkup_work(struct work_struct *work) - int i, err; - - /* Do Link up for all the enabled lmacs */ -- for_each_set_bit(i, &cgx->lmac_bmap, MAX_LMAC_PER_CGX) { -+ for_each_set_bit(i, &cgx->lmac_bmap, cgx->max_lmac_per_mac) { - err = cgx_fwi_link_change(cgx, i, true); - if (err) - dev_info(dev, "cgx port %d:%d Link up command failed\n", -@@ -1557,14 +1557,6 @@ int cgx_lmac_linkup_start(void *cgxd) - return 0; - } - --static void cgx_lmac_get_fifolen(struct cgx *cgx) --{ -- u64 cfg; -- -- cfg = cgx_read(cgx, 0, CGX_CONST); -- cgx->mac_ops->fifo_len = FIELD_GET(CGX_CONST_RXFIFO_SIZE, cfg); --} -- - static int cgx_configure_interrupt(struct cgx *cgx, struct lmac *lmac, - int cnt, bool req_free) - { -@@ -1619,17 +1611,14 @@ static int cgx_lmac_init(struct cgx *cgx) - u64 lmac_list; - int i, err; - -- cgx_lmac_get_fifolen(cgx); -- -- cgx->lmac_count = cgx->mac_ops->get_nr_lmacs(cgx); - /* lmac_list specifies which lmacs are enabled - * when bit n is set to 1, LMAC[n] is enabled - */ - if (cgx->mac_ops->non_contiguous_serdes_lane) - lmac_list = cgx_read(cgx, 0, CGXX_CMRX_RX_LMACS) & 0xFULL; - -- if (cgx->lmac_count > MAX_LMAC_PER_CGX) -- cgx->lmac_count = MAX_LMAC_PER_CGX; -+ if (cgx->lmac_count > cgx->max_lmac_per_mac) -+ cgx->lmac_count = cgx->max_lmac_per_mac; - - for (i = 0; i < cgx->lmac_count; i++) { - lmac = kzalloc(sizeof(struct lmac), GFP_KERNEL); -@@ -1707,7 +1696,7 @@ static int cgx_lmac_exit(struct cgx *cgx) - } - - /* Free all lmac related resources */ -- for_each_set_bit(i, &cgx->lmac_bmap, MAX_LMAC_PER_CGX) { -+ for_each_set_bit(i, &cgx->lmac_bmap, cgx->max_lmac_per_mac) { - lmac = cgx->lmac_idmap[i]; - if (!lmac) - continue; -@@ -1723,6 +1712,12 @@ static int cgx_lmac_exit(struct cgx *cgx) - - static void cgx_populate_features(struct cgx *cgx) - { -+ u64 cfg; -+ -+ cfg = cgx_read(cgx, 0, CGX_CONST); -+ cgx->mac_ops->fifo_len = FIELD_GET(CGX_CONST_RXFIFO_SIZE, cfg); -+ cgx->max_lmac_per_mac = FIELD_GET(CGX_CONST_MAX_LMACS, cfg); -+ - if (is_dev_rpm(cgx)) - cgx->hw_features = (RVU_LMAC_FEAT_DMACF | RVU_MAC_RPM | - RVU_LMAC_FEAT_FC | RVU_LMAC_FEAT_PTP); -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h -index 04338db38671b..09ddb00f63cc7 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h -@@ -18,11 +18,8 @@ - /* PCI BAR nos */ - #define PCI_CFG_REG_BAR_NUM 0 - --#define CGX_ID_MASK 0x7 --#define MAX_LMAC_PER_CGX 4 -+#define CGX_ID_MASK 0xF - #define MAX_DMAC_ENTRIES_PER_CGX 32 --#define CGX_FIFO_LEN 65536 /* 64K for both Rx & Tx */ --#define CGX_OFFSET(x) ((x) * MAX_LMAC_PER_CGX) - - /* Registers */ - #define CGXX_CMRX_CFG 0x00 -@@ -56,6 +53,7 @@ - #define CGXX_SCRATCH1_REG 0x1058 - #define CGX_CONST 0x2000 - #define CGX_CONST_RXFIFO_SIZE GENMASK_ULL(23, 0) -+#define CGX_CONST_MAX_LMACS GENMASK_ULL(31, 24) - #define CGXX_SPUX_CONTROL1 0x10000 - #define CGXX_SPUX_LNX_FEC_CORR_BLOCKS 0x10700 - #define CGXX_SPUX_LNX_FEC_UNCORR_BLOCKS 0x10800 -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h b/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h -index 52b6016789fa4..697cfec74aa1e 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h -@@ -128,7 +128,10 @@ struct cgx { - struct pci_dev *pdev; - u8 cgx_id; - u8 lmac_count; -- struct lmac *lmac_idmap[MAX_LMAC_PER_CGX]; -+ /* number of LMACs per MAC could be 4 or 8 */ -+ u8 max_lmac_per_mac; -+#define MAX_LMAC_COUNT 8 -+ struct lmac *lmac_idmap[MAX_LMAC_COUNT]; - struct work_struct cgx_cmd_work; - struct workqueue_struct *cgx_cmd_workq; - struct list_head cgx_list; -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h -index d027c23b8ef8e..aaff91bc7415a 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h -@@ -514,7 +514,7 @@ struct npc_lt_def { - u8 ltype_mask; - u8 ltype_match; - u8 lid; --}; -+} __packed; - - struct npc_lt_def_ipsec { - u8 ltype_mask; -@@ -522,7 +522,7 @@ struct npc_lt_def_ipsec { - u8 lid; - u8 spi_offset; - u8 spi_nz; --}; -+} __packed; - - struct npc_lt_def_apad { - u8 ltype_mask; -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c -index a70e1153fa04b..6b4792a942d84 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c -@@ -283,6 +283,11 @@ void rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable) - cfg = FIELD_SET(RPM_PFC_CLASS_MASK, 0, cfg); - rpm_write(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL, cfg); - -+ /* Disable forward pause to driver */ -+ cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); -+ cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD; -+ rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); -+ - /* Enable channel mask for all LMACS */ - rpm_write(rpm, 0, RPMX_CMR_CHAN_MSK_OR, ~0ULL); - } -@@ -451,12 +456,10 @@ int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 p - - if (rx_pause) { - cfg &= ~(RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | -- RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE | -- RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD); -+ RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE); - } else { - cfg |= (RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | -- RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE | -- RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD); -+ RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE); - } - - if (tx_pause) { -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -index 95a7bc396e8ea..0b76dfa979d4e 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h -@@ -480,7 +480,7 @@ struct rvu { - u8 cgx_mapped_pfs; - u8 cgx_cnt_max; /* CGX port count max */ - u8 *pf2cgxlmac_map; /* pf to cgx_lmac map */ -- u16 *cgxlmac2pf_map; /* bitmap of mapped pfs for -+ u64 *cgxlmac2pf_map; /* bitmap of mapped pfs for - * every cgx lmac port - */ - unsigned long pf_notify_bmap; /* Flags for PF notification */ -@@ -850,6 +850,7 @@ u32 rvu_cgx_get_fifolen(struct rvu *rvu); - void *rvu_first_cgx_pdata(struct rvu *rvu); - int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id); - int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable); -+int rvu_cgx_tx_enable(struct rvu *rvu, u16 pcifunc, bool enable); - int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause, - u16 pfc_en); - int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause); -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c -index c60b9580ca969..bcb4385d0621c 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c -@@ -55,8 +55,9 @@ bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature) - return (cgx_features_get(cgxd) & feature); - } - -+#define CGX_OFFSET(x) ((x) * rvu->hw->lmac_per_cgx) - /* Returns bitmap of mapped PFs */ --static u16 cgxlmac_to_pfmap(struct rvu *rvu, u8 cgx_id, u8 lmac_id) -+static u64 cgxlmac_to_pfmap(struct rvu *rvu, u8 cgx_id, u8 lmac_id) - { - return rvu->cgxlmac2pf_map[CGX_OFFSET(cgx_id) + lmac_id]; - } -@@ -71,7 +72,8 @@ int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id) - if (!pfmap) - return -ENODEV; - else -- return find_first_bit(&pfmap, 16); -+ return find_first_bit(&pfmap, -+ rvu->cgx_cnt_max * rvu->hw->lmac_per_cgx); - } - - static u8 cgxlmac_id_to_bmap(u8 cgx_id, u8 lmac_id) -@@ -129,14 +131,14 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu) - if (!cgx_cnt_max) - return 0; - -- if (cgx_cnt_max > 0xF || MAX_LMAC_PER_CGX > 0xF) -+ if (cgx_cnt_max > 0xF || rvu->hw->lmac_per_cgx > 0xF) - return -EINVAL; - - /* Alloc map table - * An additional entry is required since PF id starts from 1 and - * hence entry at offset 0 is invalid. - */ -- size = (cgx_cnt_max * MAX_LMAC_PER_CGX + 1) * sizeof(u8); -+ size = (cgx_cnt_max * rvu->hw->lmac_per_cgx + 1) * sizeof(u8); - rvu->pf2cgxlmac_map = devm_kmalloc(rvu->dev, size, GFP_KERNEL); - if (!rvu->pf2cgxlmac_map) - return -ENOMEM; -@@ -145,9 +147,10 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu) - memset(rvu->pf2cgxlmac_map, 0xFF, size); - - /* Reverse map table */ -- rvu->cgxlmac2pf_map = devm_kzalloc(rvu->dev, -- cgx_cnt_max * MAX_LMAC_PER_CGX * sizeof(u16), -- GFP_KERNEL); -+ rvu->cgxlmac2pf_map = -+ devm_kzalloc(rvu->dev, -+ cgx_cnt_max * rvu->hw->lmac_per_cgx * sizeof(u64), -+ GFP_KERNEL); - if (!rvu->cgxlmac2pf_map) - return -ENOMEM; - -@@ -156,7 +159,7 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu) - if (!rvu_cgx_pdata(cgx, rvu)) - continue; - lmac_bmap = cgx_get_lmac_bmap(rvu_cgx_pdata(cgx, rvu)); -- for_each_set_bit(iter, &lmac_bmap, MAX_LMAC_PER_CGX) { -+ for_each_set_bit(iter, &lmac_bmap, rvu->hw->lmac_per_cgx) { - lmac = cgx_get_lmacid(rvu_cgx_pdata(cgx, rvu), - iter); - rvu->pf2cgxlmac_map[pf] = cgxlmac_id_to_bmap(cgx, lmac); -@@ -235,7 +238,8 @@ static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu) - pfmap = cgxlmac_to_pfmap(rvu, event->cgx_id, event->lmac_id); - - do { -- pfid = find_first_bit(&pfmap, 16); -+ pfid = find_first_bit(&pfmap, -+ rvu->cgx_cnt_max * rvu->hw->lmac_per_cgx); - clear_bit(pfid, &pfmap); - - /* check if notification is enabled */ -@@ -310,7 +314,7 @@ static int cgx_lmac_event_handler_init(struct rvu *rvu) - if (!cgxd) - continue; - lmac_bmap = cgx_get_lmac_bmap(cgxd); -- for_each_set_bit(lmac, &lmac_bmap, MAX_LMAC_PER_CGX) { -+ for_each_set_bit(lmac, &lmac_bmap, rvu->hw->lmac_per_cgx) { - err = cgx_lmac_evh_register(&cb, cgxd, lmac); - if (err) - dev_err(rvu->dev, -@@ -396,7 +400,7 @@ int rvu_cgx_exit(struct rvu *rvu) - if (!cgxd) - continue; - lmac_bmap = cgx_get_lmac_bmap(cgxd); -- for_each_set_bit(lmac, &lmac_bmap, MAX_LMAC_PER_CGX) -+ for_each_set_bit(lmac, &lmac_bmap, rvu->hw->lmac_per_cgx) - cgx_lmac_evh_unregister(cgxd, lmac); - } - -@@ -456,6 +460,23 @@ int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start) - return mac_ops->mac_rx_tx_enable(cgxd, lmac_id, start); - } - -+int rvu_cgx_tx_enable(struct rvu *rvu, u16 pcifunc, bool enable) -+{ -+ int pf = rvu_get_pf(pcifunc); -+ struct mac_ops *mac_ops; -+ u8 cgx_id, lmac_id; -+ void *cgxd; -+ -+ if (!is_cgx_config_permitted(rvu, pcifunc)) -+ return LMAC_AF_ERR_PERM_DENIED; -+ -+ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); -+ cgxd = rvu_cgx_pdata(cgx_id, rvu); -+ mac_ops = get_mac_ops(cgxd); -+ -+ return mac_ops->mac_tx_enable(cgxd, lmac_id, enable); -+} -+ - int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable) - { - struct mac_ops *mac_ops; -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c -index 5c9dc3f9262f5..cc5d342e026c7 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c -@@ -2618,7 +2618,7 @@ static void rvu_dbg_cgx_init(struct rvu *rvu) - rvu->rvu_dbg.cgx = debugfs_create_dir(dname, - rvu->rvu_dbg.cgx_root); - -- for_each_set_bit(lmac_id, &lmac_bmap, MAX_LMAC_PER_CGX) { -+ for_each_set_bit(lmac_id, &lmac_bmap, rvu->hw->lmac_per_cgx) { - /* lmac debugfs dir */ - sprintf(dname, "lmac%d", lmac_id); - rvu->rvu_dbg.lmac = -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -index 959f36efdc4a6..bb99302eab67a 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c -@@ -3923,90 +3923,18 @@ static void nix_find_link_frs(struct rvu *rvu, - req->minlen = minlen; - } - --static int --nix_config_link_credits(struct rvu *rvu, int blkaddr, int link, -- u16 pcifunc, u64 tx_credits) --{ -- struct rvu_hwinfo *hw = rvu->hw; -- int pf = rvu_get_pf(pcifunc); -- u8 cgx_id = 0, lmac_id = 0; -- unsigned long poll_tmo; -- bool restore_tx_en = 0; -- struct nix_hw *nix_hw; -- u64 cfg, sw_xoff = 0; -- u32 schq = 0; -- u32 credits; -- int rc; -- -- nix_hw = get_nix_hw(rvu->hw, blkaddr); -- if (!nix_hw) -- return NIX_AF_ERR_INVALID_NIXBLK; -- -- if (tx_credits == nix_hw->tx_credits[link]) -- return 0; -- -- /* Enable cgx tx if disabled for credits to be back */ -- if (is_pf_cgxmapped(rvu, pf)) { -- rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); -- restore_tx_en = !rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), -- lmac_id, true); -- } -- -- mutex_lock(&rvu->rsrc_lock); -- /* Disable new traffic to link */ -- if (hw->cap.nix_shaping) { -- schq = nix_get_tx_link(rvu, pcifunc); -- sw_xoff = rvu_read64(rvu, blkaddr, NIX_AF_TL1X_SW_XOFF(schq)); -- rvu_write64(rvu, blkaddr, -- NIX_AF_TL1X_SW_XOFF(schq), BIT_ULL(0)); -- } -- -- rc = NIX_AF_ERR_LINK_CREDITS; -- poll_tmo = jiffies + usecs_to_jiffies(200000); -- /* Wait for credits to return */ -- do { -- if (time_after(jiffies, poll_tmo)) -- goto exit; -- usleep_range(100, 200); -- -- cfg = rvu_read64(rvu, blkaddr, -- NIX_AF_TX_LINKX_NORM_CREDIT(link)); -- credits = (cfg >> 12) & 0xFFFFFULL; -- } while (credits != nix_hw->tx_credits[link]); -- -- cfg &= ~(0xFFFFFULL << 12); -- cfg |= (tx_credits << 12); -- rvu_write64(rvu, blkaddr, NIX_AF_TX_LINKX_NORM_CREDIT(link), cfg); -- rc = 0; -- -- nix_hw->tx_credits[link] = tx_credits; -- --exit: -- /* Enable traffic back */ -- if (hw->cap.nix_shaping && !sw_xoff) -- rvu_write64(rvu, blkaddr, NIX_AF_TL1X_SW_XOFF(schq), 0); -- -- /* Restore state of cgx tx */ -- if (restore_tx_en) -- rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), lmac_id, false); -- -- mutex_unlock(&rvu->rsrc_lock); -- return rc; --} -- - int rvu_mbox_handler_nix_set_hw_frs(struct rvu *rvu, struct nix_frs_cfg *req, - struct msg_rsp *rsp) - { - struct rvu_hwinfo *hw = rvu->hw; - u16 pcifunc = req->hdr.pcifunc; - int pf = rvu_get_pf(pcifunc); -- int blkaddr, schq, link = -1; -- struct nix_txsch *txsch; -- u64 cfg, lmac_fifo_len; -+ int blkaddr, link = -1; - struct nix_hw *nix_hw; - struct rvu_pfvf *pfvf; - u8 cgx = 0, lmac = 0; - u16 max_mtu; -+ u64 cfg; - - blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc); - if (blkaddr < 0) -@@ -4027,25 +3955,6 @@ int rvu_mbox_handler_nix_set_hw_frs(struct rvu *rvu, struct nix_frs_cfg *req, - if (req->update_minlen && req->minlen < NIC_HW_MIN_FRS) - return NIX_AF_ERR_FRS_INVALID; - -- /* Check if requester wants to update SMQ's */ -- if (!req->update_smq) -- goto rx_frscfg; -- -- /* Update min/maxlen in each of the SMQ attached to this PF/VF */ -- txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ]; -- mutex_lock(&rvu->rsrc_lock); -- for (schq = 0; schq < txsch->schq.max; schq++) { -- if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc) -- continue; -- cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(schq)); -- cfg = (cfg & ~(0xFFFFULL << 8)) | ((u64)req->maxlen << 8); -- if (req->update_minlen) -- cfg = (cfg & ~0x7FULL) | ((u64)req->minlen & 0x7F); -- rvu_write64(rvu, blkaddr, NIX_AF_SMQX_CFG(schq), cfg); -- } -- mutex_unlock(&rvu->rsrc_lock); -- --rx_frscfg: - /* Check if config is for SDP link */ - if (req->sdp_link) { - if (!hw->sdp_links) -@@ -4068,7 +3977,6 @@ rx_frscfg: - if (link < 0) - return NIX_AF_ERR_RX_LINK_INVALID; - -- - linkcfg: - nix_find_link_frs(rvu, req, pcifunc); - -@@ -4078,19 +3986,7 @@ linkcfg: - cfg = (cfg & ~0xFFFFULL) | req->minlen; - rvu_write64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link), cfg); - -- if (req->sdp_link || pf == 0) -- return 0; -- -- /* Update transmit credits for CGX links */ -- lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, lmac); -- if (!lmac_fifo_len) { -- dev_err(rvu->dev, -- "%s: Failed to get CGX/RPM%d:LMAC%d FIFO size\n", -- __func__, cgx, lmac); -- return 0; -- } -- return nix_config_link_credits(rvu, blkaddr, link, pcifunc, -- (lmac_fifo_len - req->maxlen) / 16); -+ return 0; - } - - int rvu_mbox_handler_nix_set_rx_cfg(struct rvu *rvu, struct nix_rx_cfg *req, -@@ -4183,7 +4079,7 @@ static void nix_link_config(struct rvu *rvu, int blkaddr, - - /* Get LMAC id's from bitmap */ - lmac_bmap = cgx_get_lmac_bmap(rvu_cgx_pdata(cgx, rvu)); -- for_each_set_bit(iter, &lmac_bmap, MAX_LMAC_PER_CGX) { -+ for_each_set_bit(iter, &lmac_bmap, rvu->hw->lmac_per_cgx) { - lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, iter); - if (!lmac_fifo_len) { - dev_err(rvu->dev, -@@ -4610,7 +4506,13 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req, - pfvf = rvu_get_pfvf(rvu, pcifunc); - clear_bit(NIXLF_INITIALIZED, &pfvf->flags); - -- return rvu_cgx_start_stop_io(rvu, pcifunc, false); -+ err = rvu_cgx_start_stop_io(rvu, pcifunc, false); -+ if (err) -+ return err; -+ -+ rvu_cgx_tx_enable(rvu, pcifunc, true); -+ -+ return 0; - } - - #define RX_SA_BASE GENMASK_ULL(52, 7) -diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c -index 34fa59575fa91..54e0dfdc9d984 100644 ---- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c -+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c -@@ -1999,7 +1999,9 @@ int rvu_npc_exact_init(struct rvu *rvu) - /* Install SDP drop rule */ - drop_mcam_idx = &table->num_drop_rules; - -- max_lmac_cnt = rvu->cgx_cnt_max * MAX_LMAC_PER_CGX + PF_CGXMAP_BASE; -+ max_lmac_cnt = rvu->cgx_cnt_max * rvu->hw->lmac_per_cgx + -+ PF_CGXMAP_BASE; -+ - for (i = PF_CGXMAP_BASE; i < max_lmac_cnt; i++) { - if (rvu->pf2cgxlmac_map[i] == 0xFF) - continue; -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -index d136360ac6a98..a6d3fc96e1685 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c -@@ -25,7 +25,7 @@ - struct mlx5_irq { - struct atomic_notifier_head nh; - cpumask_var_t mask; -- char name[MLX5_MAX_IRQ_NAME]; -+ char name[MLX5_MAX_IRQ_FORMATTED_NAME]; - struct mlx5_irq_pool *pool; - int refcount; - u32 index; -@@ -236,8 +236,8 @@ struct mlx5_irq *mlx5_irq_alloc(struct mlx5_irq_pool *pool, int i, - else - irq_sf_set_name(pool, name, i); - ATOMIC_INIT_NOTIFIER_HEAD(&irq->nh); -- snprintf(irq->name, MLX5_MAX_IRQ_NAME, -- "%s@pci:%s", name, pci_name(dev->pdev)); -+ snprintf(irq->name, MLX5_MAX_IRQ_FORMATTED_NAME, -+ MLX5_IRQ_NAME_FORMAT_STR, name, pci_name(dev->pdev)); - err = request_irq(irq->irqn, irq_int_handler, 0, irq->name, - &irq->nh); - if (err) { -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h -index 5c7e68bee43a0..4047179307c4a 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h -+++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.h -@@ -7,6 +7,9 @@ - #include - - #define MLX5_MAX_IRQ_NAME (32) -+#define MLX5_IRQ_NAME_FORMAT_STR ("%s@pci:%s") -+#define MLX5_MAX_IRQ_FORMATTED_NAME \ -+ (MLX5_MAX_IRQ_NAME + sizeof(MLX5_IRQ_NAME_FORMAT_STR)) - /* max irq_index is 2047, so four chars */ - #define MLX5_MAX_IRQ_IDX_CHARS (4) - #define MLX5_EQ_REFS_PER_IRQ (2) -diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c -index 0d5a41a2ae010..227d01cace3f0 100644 ---- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c -+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c -@@ -267,6 +267,13 @@ static bool mlxbf_gige_rx_packet(struct mlxbf_gige *priv, int *rx_pkts) - priv->stats.rx_truncate_errors++; - } - -+ /* Read receive consumer index before replenish so that this routine -+ * returns accurate return value even if packet is received into -+ * just-replenished buffer prior to exiting this routine. -+ */ -+ rx_ci = readq(priv->base + MLXBF_GIGE_RX_CQE_PACKET_CI); -+ rx_ci_rem = rx_ci % priv->rx_q_entries; -+ - /* Let hardware know we've replenished one buffer */ - rx_pi++; - -@@ -279,8 +286,6 @@ static bool mlxbf_gige_rx_packet(struct mlxbf_gige *priv, int *rx_pkts) - rx_pi_rem = rx_pi % priv->rx_q_entries; - if (rx_pi_rem == 0) - priv->valid_polarity ^= 1; -- rx_ci = readq(priv->base + MLXBF_GIGE_RX_CQE_PACKET_CI); -- rx_ci_rem = rx_ci % priv->rx_q_entries; - - if (skb) - netif_receive_skb(skb); -diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c -index 0d57ffcedf0c6..fc78bc959ded8 100644 ---- a/drivers/net/ethernet/qlogic/qla3xxx.c -+++ b/drivers/net/ethernet/qlogic/qla3xxx.c -@@ -2591,6 +2591,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) - - if (qdev->lrg_buf_q_alloc_virt_addr == NULL) { - netdev_err(qdev->ndev, "lBufQ failed\n"); -+ kfree(qdev->lrg_buf); - return -ENOMEM; - } - qdev->lrg_buf_q_virt_addr = qdev->lrg_buf_q_alloc_virt_addr; -@@ -2615,6 +2616,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) - qdev->lrg_buf_q_alloc_size, - qdev->lrg_buf_q_alloc_virt_addr, - qdev->lrg_buf_q_alloc_phy_addr); -+ kfree(qdev->lrg_buf); - return -ENOMEM; - } - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index d22457f2cf9cf..06663c11ca96d 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -1145,7 +1145,7 @@ static void rtl8168ep_driver_start(struct rtl8169_private *tp) - { - r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START); - r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01); -- rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 10); -+ rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30); - } - - static void rtl8168_driver_start(struct rtl8169_private *tp) -diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c -index 68cb5616ef991..c2c56a5289caf 100644 ---- a/drivers/net/ethernet/renesas/ravb_main.c -+++ b/drivers/net/ethernet/renesas/ravb_main.c -@@ -68,16 +68,27 @@ int ravb_wait(struct net_device *ndev, enum ravb_reg reg, u32 mask, u32 value) - return -ETIMEDOUT; - } - --static int ravb_config(struct net_device *ndev) -+static int ravb_set_opmode(struct net_device *ndev, u32 opmode) - { -+ u32 csr_ops = 1U << (opmode & CCC_OPC); -+ u32 ccc_mask = CCC_OPC; - int error; - -- /* Set config mode */ -- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG); -- /* Check if the operating mode is changed to the config mode */ -- error = ravb_wait(ndev, CSR, CSR_OPS, CSR_OPS_CONFIG); -- if (error) -- netdev_err(ndev, "failed to switch device to config mode\n"); -+ /* If gPTP active in config mode is supported it needs to be configured -+ * along with CSEL and operating mode in the same access. This is a -+ * hardware limitation. -+ */ -+ if (opmode & CCC_GAC) -+ ccc_mask |= CCC_GAC | CCC_CSEL; -+ -+ /* Set operating mode */ -+ ravb_modify(ndev, CCC, ccc_mask, opmode); -+ /* Check if the operating mode is changed to the requested one */ -+ error = ravb_wait(ndev, CSR, CSR_OPS, csr_ops); -+ if (error) { -+ netdev_err(ndev, "failed to switch device to requested mode (%u)\n", -+ opmode & CCC_OPC); -+ } - - return error; - } -@@ -675,7 +686,7 @@ static int ravb_dmac_init(struct net_device *ndev) - int error; - - /* Set CONFIG mode */ -- error = ravb_config(ndev); -+ error = ravb_set_opmode(ndev, CCC_OPC_CONFIG); - if (error) - return error; - -@@ -684,9 +695,7 @@ static int ravb_dmac_init(struct net_device *ndev) - return error; - - /* Setting the control will start the AVB-DMAC process. */ -- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_OPERATION); -- -- return 0; -+ return ravb_set_opmode(ndev, CCC_OPC_OPERATION); - } - - static void ravb_get_tx_tstamp(struct net_device *ndev) -@@ -1048,7 +1057,7 @@ static int ravb_stop_dma(struct net_device *ndev) - return error; - - /* Stop AVB-DMAC process */ -- return ravb_config(ndev); -+ return ravb_set_opmode(ndev, CCC_OPC_CONFIG); - } - - /* E-MAC interrupt handler */ -@@ -2576,21 +2585,25 @@ static int ravb_set_gti(struct net_device *ndev) - return 0; - } - --static void ravb_set_config_mode(struct net_device *ndev) -+static int ravb_set_config_mode(struct net_device *ndev) - { - struct ravb_private *priv = netdev_priv(ndev); - const struct ravb_hw_info *info = priv->info; -+ int error; - - if (info->gptp) { -- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG); -+ error = ravb_set_opmode(ndev, CCC_OPC_CONFIG); -+ if (error) -+ return error; - /* Set CSEL value */ - ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB); - } else if (info->ccc_gac) { -- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG | -- CCC_GAC | CCC_CSEL_HPB); -+ error = ravb_set_opmode(ndev, CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB); - } else { -- ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG); -+ error = ravb_set_opmode(ndev, CCC_OPC_CONFIG); - } -+ -+ return error; - } - - /* Set tx and rx clock internal delay modes */ -@@ -2810,7 +2823,9 @@ static int ravb_probe(struct platform_device *pdev) - ndev->ethtool_ops = &ravb_ethtool_ops; - - /* Set AVB config mode */ -- ravb_set_config_mode(ndev); -+ error = ravb_set_config_mode(ndev); -+ if (error) -+ goto out_disable_gptp_clk; - - if (info->gptp || info->ccc_gac) { - /* Set GTI value */ -@@ -2933,8 +2948,7 @@ static int ravb_remove(struct platform_device *pdev) - dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat, - priv->desc_bat_dma); - -- /* Set reset mode */ -- ravb_write(ndev, CCC_OPC_RESET, CCC); -+ ravb_set_opmode(ndev, CCC_OPC_RESET); - - clk_disable_unprepare(priv->gptp_clk); - clk_disable_unprepare(priv->refclk); -@@ -3018,8 +3032,11 @@ static int __maybe_unused ravb_resume(struct device *dev) - int ret = 0; - - /* If WoL is enabled set reset mode to rearm the WoL logic */ -- if (priv->wol_enabled) -- ravb_write(ndev, CCC_OPC_RESET, CCC); -+ if (priv->wol_enabled) { -+ ret = ravb_set_opmode(ndev, CCC_OPC_RESET); -+ if (ret) -+ return ret; -+ } - - /* All register have been reset to default values. - * Restore all registers which where setup at probe time and -@@ -3027,7 +3044,9 @@ static int __maybe_unused ravb_resume(struct device *dev) - */ - - /* Set AVB config mode */ -- ravb_set_config_mode(ndev); -+ ret = ravb_set_config_mode(ndev); -+ if (ret) -+ return ret; - - if (info->gptp || info->ccc_gac) { - /* Set GTI value */ -diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c -index 9220afeddee81..3f290791df1c4 100644 ---- a/drivers/net/ethernet/sfc/rx_common.c -+++ b/drivers/net/ethernet/sfc/rx_common.c -@@ -820,8 +820,10 @@ int efx_probe_filters(struct efx_nic *efx) - } - - if (!success) { -- efx_for_each_channel(channel, efx) -+ efx_for_each_channel(channel, efx) { - kfree(channel->rps_flow_id); -+ channel->rps_flow_id = NULL; -+ } - efx->type->filter_table_remove(efx); - rc = -ENOMEM; - goto out_unlock; -diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c -index 477b4d4f860bd..bace989591f75 100644 ---- a/drivers/net/gtp.c -+++ b/drivers/net/gtp.c -@@ -629,7 +629,7 @@ static void __gtp_encap_destroy(struct sock *sk) - gtp->sk0 = NULL; - else - gtp->sk1u = NULL; -- udp_sk(sk)->encap_type = 0; -+ WRITE_ONCE(udp_sk(sk)->encap_type, 0); - rcu_assign_sk_user_data(sk, NULL); - release_sock(sk); - sock_put(sk); -@@ -681,7 +681,7 @@ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb) - - netdev_dbg(gtp->dev, "encap_recv sk=%p\n", sk); - -- switch (udp_sk(sk)->encap_type) { -+ switch (READ_ONCE(udp_sk(sk)->encap_type)) { - case UDP_ENCAP_GTP0: - netdev_dbg(gtp->dev, "received GTP0 packet\n"); - ret = gtp0_udp_encap_recv(gtp, skb); -diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c -index 3777c7e2e6fc0..e47bb125048d4 100644 ---- a/drivers/net/usb/ax88172a.c -+++ b/drivers/net/usb/ax88172a.c -@@ -161,7 +161,9 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) - u8 buf[ETH_ALEN]; - struct ax88172a_private *priv; - -- usbnet_get_endpoints(dev, intf); -+ ret = usbnet_get_endpoints(dev, intf); -+ if (ret) -+ return ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) -diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h -index 157d1f31c4871..c5a306b01fe20 100644 ---- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h -+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h -@@ -348,8 +348,8 @@ - #define RFIC_REG_RD 0xAD0470 - #define WFPM_CTRL_REG 0xA03030 - #define WFPM_OTP_CFG1_ADDR 0x00a03098 --#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4) --#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5) -+#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(5) -+#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(4) - - #define WFPM_GP2 0xA030B4 - -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h -index 69b95ad5993b0..2ec4ee8ab317c 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h -@@ -745,7 +745,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) - } - } - --void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans); -+void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans, bool from_irq); - - static inline bool iwl_is_rfkill_set(struct iwl_trans *trans) - { -@@ -792,7 +792,7 @@ static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans) - return (trans->dbg.dest_tlv || iwl_trans_dbg_ini_valid(trans)); - } - --void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state); -+void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state, bool from_irq); - void iwl_trans_pcie_dump_regs(struct iwl_trans *trans); - - #ifdef CONFIG_IWLWIFI_DEBUGFS -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -index 90a46faaaffdf..57a11ee05bc36 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -@@ -1781,7 +1781,7 @@ static u32 iwl_pcie_int_cause_ict(struct iwl_trans *trans) - return inta; - } - --void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans) -+void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans, bool from_irq) - { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct isr_statistics *isr_stats = &trans_pcie->isr_stats; -@@ -1805,7 +1805,7 @@ void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans) - isr_stats->rfkill++; - - if (prev != report) -- iwl_trans_pcie_rf_kill(trans, report); -+ iwl_trans_pcie_rf_kill(trans, report, from_irq); - mutex_unlock(&trans_pcie->mutex); - - if (hw_rfkill) { -@@ -1945,7 +1945,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) - - /* HW RF KILL switch toggled */ - if (inta & CSR_INT_BIT_RF_KILL) { -- iwl_pcie_handle_rfkill_irq(trans); -+ iwl_pcie_handle_rfkill_irq(trans, true); - handled |= CSR_INT_BIT_RF_KILL; - } - -@@ -2362,7 +2362,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) - - /* HW RF KILL switch toggled */ - if (inta_hw & MSIX_HW_INT_CAUSES_REG_RF_KILL) -- iwl_pcie_handle_rfkill_irq(trans); -+ iwl_pcie_handle_rfkill_irq(trans, true); - - if (inta_hw & MSIX_HW_INT_CAUSES_REG_HW_ERR) { - IWL_ERR(trans, -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -index 796972f224326..c7ed35b3dd8d5 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c -@@ -1080,7 +1080,7 @@ bool iwl_pcie_check_hw_rf_kill(struct iwl_trans *trans) - report = test_bit(STATUS_RFKILL_OPMODE, &trans->status); - - if (prev != report) -- iwl_trans_pcie_rf_kill(trans, report); -+ iwl_trans_pcie_rf_kill(trans, report, false); - - return hw_rfkill; - } -@@ -1234,7 +1234,7 @@ static void iwl_pcie_init_msix(struct iwl_trans_pcie *trans_pcie) - trans_pcie->hw_mask = trans_pcie->hw_init_mask; - } - --static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) -+static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool from_irq) - { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - -@@ -1261,7 +1261,8 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) - if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) { - IWL_DEBUG_INFO(trans, - "DEVICE_ENABLED bit was set and is now cleared\n"); -- iwl_pcie_synchronize_irqs(trans); -+ if (!from_irq) -+ iwl_pcie_synchronize_irqs(trans); - iwl_pcie_rx_napi_sync(trans); - iwl_pcie_tx_stop(trans); - iwl_pcie_rx_stop(trans); -@@ -1451,7 +1452,7 @@ void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans *trans, - clear_bit(STATUS_RFKILL_OPMODE, &trans->status); - } - if (hw_rfkill != was_in_rfkill) -- iwl_trans_pcie_rf_kill(trans, hw_rfkill); -+ iwl_trans_pcie_rf_kill(trans, hw_rfkill, false); - } - - static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) -@@ -1466,12 +1467,12 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) - mutex_lock(&trans_pcie->mutex); - trans_pcie->opmode_down = true; - was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status); -- _iwl_trans_pcie_stop_device(trans); -+ _iwl_trans_pcie_stop_device(trans, false); - iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill); - mutex_unlock(&trans_pcie->mutex); - } - --void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) -+void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state, bool from_irq) - { - struct iwl_trans_pcie __maybe_unused *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); -@@ -1484,7 +1485,7 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) - if (trans->trans_cfg->gen2) - _iwl_trans_pcie_gen2_stop_device(trans); - else -- _iwl_trans_pcie_stop_device(trans); -+ _iwl_trans_pcie_stop_device(trans, from_irq); - } - } - -@@ -2815,7 +2816,7 @@ static ssize_t iwl_dbgfs_rfkill_write(struct file *file, - IWL_WARN(trans, "changing debug rfkill %d->%d\n", - trans_pcie->debug_rfkill, new_value); - trans_pcie->debug_rfkill = new_value; -- iwl_pcie_handle_rfkill_irq(trans); -+ iwl_pcie_handle_rfkill_irq(trans, false); - - return count; - } -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index 8df156c28aade..5368a37154cf9 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -1302,6 +1302,9 @@ static int pci_set_full_power_state(struct pci_dev *dev) - pci_restore_bars(dev); - } - -+ if (dev->bus->self) -+ pcie_aspm_pm_state_change(dev->bus->self); -+ - return 0; - } - -@@ -1396,6 +1399,9 @@ static int pci_set_low_power_state(struct pci_dev *dev, pci_power_t state) - pci_power_name(dev->current_state), - pci_power_name(state)); - -+ if (dev->bus->self) -+ pcie_aspm_pm_state_change(dev->bus->self); -+ - return 0; - } - -diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h -index ffccb03933e27..ed6d75d138c7a 100644 ---- a/drivers/pci/pci.h -+++ b/drivers/pci/pci.h -@@ -561,10 +561,12 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active); - #ifdef CONFIG_PCIEASPM - void pcie_aspm_init_link_state(struct pci_dev *pdev); - void pcie_aspm_exit_link_state(struct pci_dev *pdev); -+void pcie_aspm_pm_state_change(struct pci_dev *pdev); - void pcie_aspm_powersave_config_link(struct pci_dev *pdev); - #else - static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } - static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } -+static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { } - static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } - #endif - -diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c -index 5d1756f53ba84..25736d408e88e 100644 ---- a/drivers/pci/pcie/aspm.c -+++ b/drivers/pci/pcie/aspm.c -@@ -1055,6 +1055,25 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) - up_read(&pci_bus_sem); - } - -+/* @pdev: the root port or switch downstream port */ -+void pcie_aspm_pm_state_change(struct pci_dev *pdev) -+{ -+ struct pcie_link_state *link = pdev->link_state; -+ -+ if (aspm_disabled || !link) -+ return; -+ /* -+ * Devices changed PM state, we should recheck if latency -+ * meets all functions' requirement -+ */ -+ down_read(&pci_bus_sem); -+ mutex_lock(&aspm_lock); -+ pcie_update_aspm_capable(link->root); -+ pcie_config_aspm_path(link); -+ mutex_unlock(&aspm_lock); -+ up_read(&pci_bus_sem); -+} -+ - void pcie_aspm_powersave_config_link(struct pci_dev *pdev) - { - struct pcie_link_state *link = pdev->link_state; -diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c -index b194e71f07bfc..aa51cb72cbba5 100644 ---- a/drivers/video/fbdev/imsttfb.c -+++ b/drivers/video/fbdev/imsttfb.c -@@ -1419,7 +1419,6 @@ static int init_imstt(struct fb_info *info) - if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len - || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) { - printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); -- framebuffer_release(info); - return -ENODEV; - } - -@@ -1452,10 +1451,11 @@ static int init_imstt(struct fb_info *info) - FBINFO_HWACCEL_FILLRECT | - FBINFO_HWACCEL_YPAN; - -- fb_alloc_cmap(&info->cmap, 0, 0); -+ if (fb_alloc_cmap(&info->cmap, 0, 0)) -+ return -ENODEV; - - if (register_framebuffer(info) < 0) { -- framebuffer_release(info); -+ fb_dealloc_cmap(&info->cmap); - return -ENODEV; - } - -diff --git a/fs/9p/cache.c b/fs/9p/cache.c -index cebba4eaa0b57..12c0ae29f1857 100644 ---- a/fs/9p/cache.c -+++ b/fs/9p/cache.c -@@ -68,6 +68,8 @@ void v9fs_cache_inode_get_cookie(struct inode *inode) - &path, sizeof(path), - &version, sizeof(version), - i_size_read(&v9inode->netfs.inode)); -+ if (v9inode->netfs.cache) -+ mapping_set_release_always(inode->i_mapping); - - p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n", - inode, v9fs_inode_cookie(v9inode)); -diff --git a/fs/afs/internal.h b/fs/afs/internal.h -index fcbb598d8c85d..a25fdc3e52310 100644 ---- a/fs/afs/internal.h -+++ b/fs/afs/internal.h -@@ -682,6 +682,8 @@ static inline void afs_vnode_set_cache(struct afs_vnode *vnode, - { - #ifdef CONFIG_AFS_FSCACHE - vnode->netfs.cache = cookie; -+ if (cookie) -+ mapping_set_release_always(vnode->netfs.inode.i_mapping); - #endif - } - -diff --git a/fs/btrfs/delalloc-space.c b/fs/btrfs/delalloc-space.c -index 0b62ce77053f5..f2bc5563c0f92 100644 ---- a/fs/btrfs/delalloc-space.c -+++ b/fs/btrfs/delalloc-space.c -@@ -197,7 +197,7 @@ void btrfs_free_reserved_data_space(struct btrfs_inode *inode, - start = round_down(start, fs_info->sectorsize); - - btrfs_free_reserved_data_space_noquota(fs_info, len); -- btrfs_qgroup_free_data(inode, reserved, start, len); -+ btrfs_qgroup_free_data(inode, reserved, start, len, NULL); - } - - /** -diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c -index b14d2da9b26d3..14478da875313 100644 ---- a/fs/btrfs/file-item.c -+++ b/fs/btrfs/file-item.c -@@ -602,7 +602,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, - } - - sums->bytenr = start; -- sums->len = (int)size; -+ sums->len = size; - - offset = (start - key.offset) >> fs_info->sectorsize_bits; - offset *= csum_size; -diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c -index 0a46fff3dd067..1783a0fbf1665 100644 ---- a/fs/btrfs/file.c -+++ b/fs/btrfs/file.c -@@ -3191,7 +3191,7 @@ static long btrfs_fallocate(struct file *file, int mode, - qgroup_reserved -= range->len; - } else if (qgroup_reserved > 0) { - btrfs_qgroup_free_data(BTRFS_I(inode), data_reserved, -- range->start, range->len); -+ range->start, range->len, NULL); - qgroup_reserved -= range->len; - } - list_del(&range->list); -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 81eac121c6b23..9a7d77c410e22 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -466,7 +466,7 @@ out: - * And at reserve time, it's always aligned to page size, so - * just free one page here. - */ -- btrfs_qgroup_free_data(inode, NULL, 0, PAGE_SIZE); -+ btrfs_qgroup_free_data(inode, NULL, 0, PAGE_SIZE, NULL); - btrfs_free_path(path); - btrfs_end_transaction(trans); - return ret; -@@ -5372,7 +5372,7 @@ static void evict_inode_truncate_pages(struct inode *inode) - */ - if (state_flags & EXTENT_DELALLOC) - btrfs_qgroup_free_data(BTRFS_I(inode), NULL, start, -- end - start + 1); -+ end - start + 1, NULL); - - clear_extent_bit(io_tree, start, end, - EXTENT_CLEAR_ALL_BITS | EXTENT_DO_ACCOUNTING, -@@ -8440,7 +8440,7 @@ next: - * reserved data space. - * Since the IO will never happen for this page. - */ -- btrfs_qgroup_free_data(inode, NULL, cur, range_end + 1 - cur); -+ btrfs_qgroup_free_data(inode, NULL, cur, range_end + 1 - cur, NULL); - if (!inode_evicting) { - clear_extent_bit(tree, cur, range_end, EXTENT_LOCKED | - EXTENT_DELALLOC | EXTENT_UPTODATE | -@@ -9902,7 +9902,7 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( - struct btrfs_path *path; - u64 start = ins->objectid; - u64 len = ins->offset; -- int qgroup_released; -+ u64 qgroup_released = 0; - int ret; - - memset(&stack_fi, 0, sizeof(stack_fi)); -@@ -9915,9 +9915,9 @@ static struct btrfs_trans_handle *insert_prealloc_file_extent( - btrfs_set_stack_file_extent_compression(&stack_fi, BTRFS_COMPRESS_NONE); - /* Encryption and other encoding is reserved and all 0 */ - -- qgroup_released = btrfs_qgroup_release_data(inode, file_offset, len); -- if (qgroup_released < 0) -- return ERR_PTR(qgroup_released); -+ ret = btrfs_qgroup_release_data(inode, file_offset, len, &qgroup_released); -+ if (ret < 0) -+ return ERR_PTR(ret); - - if (trans) { - ret = insert_reserved_file_extent(trans, inode, -@@ -10903,7 +10903,7 @@ out_delalloc_release: - btrfs_delalloc_release_metadata(inode, disk_num_bytes, ret < 0); - out_qgroup_free_data: - if (ret < 0) -- btrfs_qgroup_free_data(inode, data_reserved, start, num_bytes); -+ btrfs_qgroup_free_data(inode, data_reserved, start, num_bytes, NULL); - out_free_data_space: - /* - * If btrfs_reserve_extent() succeeded, then we already decremented -diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c -index 0321753c16b9f..1b2af4785c0e2 100644 ---- a/fs/btrfs/ordered-data.c -+++ b/fs/btrfs/ordered-data.c -@@ -172,11 +172,12 @@ int btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset, - struct rb_node *node; - struct btrfs_ordered_extent *entry; - int ret; -+ u64 qgroup_rsv = 0; - - if (flags & - ((1 << BTRFS_ORDERED_NOCOW) | (1 << BTRFS_ORDERED_PREALLOC))) { - /* For nocow write, we can release the qgroup rsv right now */ -- ret = btrfs_qgroup_free_data(inode, NULL, file_offset, num_bytes); -+ ret = btrfs_qgroup_free_data(inode, NULL, file_offset, num_bytes, &qgroup_rsv); - if (ret < 0) - return ret; - ret = 0; -@@ -185,7 +186,7 @@ int btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset, - * The ordered extent has reserved qgroup space, release now - * and pass the reserved number for qgroup_record to free. - */ -- ret = btrfs_qgroup_release_data(inode, file_offset, num_bytes); -+ ret = btrfs_qgroup_release_data(inode, file_offset, num_bytes, &qgroup_rsv); - if (ret < 0) - return ret; - } -@@ -203,7 +204,7 @@ int btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset, - entry->inode = igrab(&inode->vfs_inode); - entry->compress_type = compress_type; - entry->truncated_len = (u64)-1; -- entry->qgroup_rsv = ret; -+ entry->qgroup_rsv = qgroup_rsv; - entry->physical = (u64)-1; - - ASSERT((flags & ~BTRFS_ORDERED_TYPE_FLAGS) == 0); -diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h -index f59f2dbdb25ed..cc3ca4bb9bd54 100644 ---- a/fs/btrfs/ordered-data.h -+++ b/fs/btrfs/ordered-data.h -@@ -20,7 +20,7 @@ struct btrfs_ordered_sum { - /* - * this is the length in bytes covered by the sums array below. - */ -- int len; -+ u32 len; - struct list_head list; - /* last field is a variable length array of csums */ - u8 sums[]; -diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c -index 26cabffd59710..96ec9ccc2ef61 100644 ---- a/fs/btrfs/qgroup.c -+++ b/fs/btrfs/qgroup.c -@@ -3833,13 +3833,14 @@ int btrfs_qgroup_reserve_data(struct btrfs_inode *inode, - - /* Free ranges specified by @reserved, normally in error path */ - static int qgroup_free_reserved_data(struct btrfs_inode *inode, -- struct extent_changeset *reserved, u64 start, u64 len) -+ struct extent_changeset *reserved, -+ u64 start, u64 len, u64 *freed_ret) - { - struct btrfs_root *root = inode->root; - struct ulist_node *unode; - struct ulist_iterator uiter; - struct extent_changeset changeset; -- int freed = 0; -+ u64 freed = 0; - int ret; - - extent_changeset_init(&changeset); -@@ -3880,7 +3881,9 @@ static int qgroup_free_reserved_data(struct btrfs_inode *inode, - } - btrfs_qgroup_free_refroot(root->fs_info, root->root_key.objectid, freed, - BTRFS_QGROUP_RSV_DATA); -- ret = freed; -+ if (freed_ret) -+ *freed_ret = freed; -+ ret = 0; - out: - extent_changeset_release(&changeset); - return ret; -@@ -3888,7 +3891,7 @@ out: - - static int __btrfs_qgroup_release_data(struct btrfs_inode *inode, - struct extent_changeset *reserved, u64 start, u64 len, -- int free) -+ u64 *released, int free) - { - struct extent_changeset changeset; - int trace_op = QGROUP_RELEASE; -@@ -3900,7 +3903,7 @@ static int __btrfs_qgroup_release_data(struct btrfs_inode *inode, - /* In release case, we shouldn't have @reserved */ - WARN_ON(!free && reserved); - if (free && reserved) -- return qgroup_free_reserved_data(inode, reserved, start, len); -+ return qgroup_free_reserved_data(inode, reserved, start, len, released); - extent_changeset_init(&changeset); - ret = clear_record_extent_bits(&inode->io_tree, start, start + len -1, - EXTENT_QGROUP_RESERVED, &changeset); -@@ -3915,7 +3918,8 @@ static int __btrfs_qgroup_release_data(struct btrfs_inode *inode, - btrfs_qgroup_free_refroot(inode->root->fs_info, - inode->root->root_key.objectid, - changeset.bytes_changed, BTRFS_QGROUP_RSV_DATA); -- ret = changeset.bytes_changed; -+ if (released) -+ *released = changeset.bytes_changed; - out: - extent_changeset_release(&changeset); - return ret; -@@ -3934,9 +3938,10 @@ out: - * NOTE: This function may sleep for memory allocation. - */ - int btrfs_qgroup_free_data(struct btrfs_inode *inode, -- struct extent_changeset *reserved, u64 start, u64 len) -+ struct extent_changeset *reserved, -+ u64 start, u64 len, u64 *freed) - { -- return __btrfs_qgroup_release_data(inode, reserved, start, len, 1); -+ return __btrfs_qgroup_release_data(inode, reserved, start, len, freed, 1); - } - - /* -@@ -3954,9 +3959,9 @@ int btrfs_qgroup_free_data(struct btrfs_inode *inode, - * - * NOTE: This function may sleep for memory allocation. - */ --int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len) -+int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len, u64 *released) - { -- return __btrfs_qgroup_release_data(inode, NULL, start, len, 0); -+ return __btrfs_qgroup_release_data(inode, NULL, start, len, released, 0); - } - - static void add_root_meta_rsv(struct btrfs_root *root, int num_bytes, -diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h -index 578c77e94200f..c382923f7628e 100644 ---- a/fs/btrfs/qgroup.h -+++ b/fs/btrfs/qgroup.h -@@ -360,10 +360,10 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid, - /* New io_tree based accurate qgroup reserve API */ - int btrfs_qgroup_reserve_data(struct btrfs_inode *inode, - struct extent_changeset **reserved, u64 start, u64 len); --int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len); -+int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len, u64 *released); - int btrfs_qgroup_free_data(struct btrfs_inode *inode, - struct extent_changeset *reserved, u64 start, -- u64 len); -+ u64 len, u64 *freed); - int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, - enum btrfs_qgroup_rsv_type type, bool enforce); - int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, -diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c -index 03ca8f2f657ab..50b2ee163af60 100644 ---- a/fs/cachefiles/namei.c -+++ b/fs/cachefiles/namei.c -@@ -584,6 +584,8 @@ static bool cachefiles_open_file(struct cachefiles_object *object, - if (ret < 0) - goto check_failed; - -+ clear_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &object->cookie->flags); -+ - object->file = file; - - /* Always update the atime on an object we've just looked up (this is -diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c -index 177d8e8d73fe4..de1dee46d3df7 100644 ---- a/fs/ceph/cache.c -+++ b/fs/ceph/cache.c -@@ -36,6 +36,8 @@ void ceph_fscache_register_inode_cookie(struct inode *inode) - &ci->i_vino, sizeof(ci->i_vino), - &ci->i_version, sizeof(ci->i_version), - i_size_read(inode)); -+ if (ci->netfs.cache) -+ mapping_set_release_always(inode->i_mapping); - } - - void ceph_fscache_unregister_inode_cookie(struct ceph_inode_info *ci) -diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c -index 044e34cd835c1..dedc9d445f243 100644 ---- a/fs/ext4/move_extent.c -+++ b/fs/ext4/move_extent.c -@@ -253,6 +253,7 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode, - { - struct inode *orig_inode = file_inode(o_filp); - struct page *pagep[2] = {NULL, NULL}; -+ struct folio *folio[2] = {NULL, NULL}; - handle_t *handle; - ext4_lblk_t orig_blk_offset, donor_blk_offset; - unsigned long blocksize = orig_inode->i_sb->s_blocksize; -@@ -313,6 +314,13 @@ again: - * hold page's lock, if it is still the case data copy is not - * necessary, just swap data blocks between orig and donor. - */ -+ folio[0] = page_folio(pagep[0]); -+ folio[1] = page_folio(pagep[1]); -+ -+ VM_BUG_ON_FOLIO(folio_test_large(folio[0]), folio[0]); -+ VM_BUG_ON_FOLIO(folio_test_large(folio[1]), folio[1]); -+ VM_BUG_ON_FOLIO(folio_nr_pages(folio[0]) != folio_nr_pages(folio[1]), folio[1]); -+ - if (unwritten) { - ext4_double_down_write_data_sem(orig_inode, donor_inode); - /* If any of extents in range became initialized we have to -@@ -331,10 +339,8 @@ again: - ext4_double_up_write_data_sem(orig_inode, donor_inode); - goto data_copy; - } -- if ((page_has_private(pagep[0]) && -- !try_to_release_page(pagep[0], 0)) || -- (page_has_private(pagep[1]) && -- !try_to_release_page(pagep[1], 0))) { -+ if (!filemap_release_folio(folio[0], 0) || -+ !filemap_release_folio(folio[1], 0)) { - *err = -EBUSY; - goto drop_data_sem; - } -@@ -344,19 +350,19 @@ again: - block_len_in_page, 1, err); - drop_data_sem: - ext4_double_up_write_data_sem(orig_inode, donor_inode); -- goto unlock_pages; -+ goto unlock_folios; - } - data_copy: -- *err = mext_page_mkuptodate(pagep[0], from, from + replaced_size); -+ *err = mext_page_mkuptodate(&folio[0]->page, from, from + replaced_size); - if (*err) -- goto unlock_pages; -+ goto unlock_folios; - - /* At this point all buffers in range are uptodate, old mapping layout - * is no longer required, try to drop it now. */ -- if ((page_has_private(pagep[0]) && !try_to_release_page(pagep[0], 0)) || -- (page_has_private(pagep[1]) && !try_to_release_page(pagep[1], 0))) { -+ if (!filemap_release_folio(folio[0], 0) || -+ !filemap_release_folio(folio[1], 0)) { - *err = -EBUSY; -- goto unlock_pages; -+ goto unlock_folios; - } - ext4_double_down_write_data_sem(orig_inode, donor_inode); - replaced_count = ext4_swap_extents(handle, orig_inode, donor_inode, -@@ -369,13 +375,13 @@ data_copy: - replaced_size = - block_len_in_page << orig_inode->i_blkbits; - } else -- goto unlock_pages; -+ goto unlock_folios; - } - /* Perform all necessary steps similar write_begin()/write_end() - * but keeping in mind that i_size will not change */ -- if (!page_has_buffers(pagep[0])) -- create_empty_buffers(pagep[0], 1 << orig_inode->i_blkbits, 0); -- bh = page_buffers(pagep[0]); -+ if (!folio_buffers(folio[0])) -+ create_empty_buffers(&folio[0]->page, 1 << orig_inode->i_blkbits, 0); -+ bh = folio_buffers(folio[0]); - for (i = 0; i < data_offset_in_page; i++) - bh = bh->b_this_page; - for (i = 0; i < block_len_in_page; i++) { -@@ -385,7 +391,7 @@ data_copy: - bh = bh->b_this_page; - } - if (!*err) -- *err = block_commit_write(pagep[0], from, from + replaced_size); -+ *err = block_commit_write(&folio[0]->page, from, from + replaced_size); - - if (unlikely(*err < 0)) - goto repair_branches; -@@ -395,11 +401,11 @@ data_copy: - *err = ext4_jbd2_inode_add_write(handle, orig_inode, - (loff_t)orig_page_offset << PAGE_SHIFT, replaced_size); - --unlock_pages: -- unlock_page(pagep[0]); -- put_page(pagep[0]); -- unlock_page(pagep[1]); -- put_page(pagep[1]); -+unlock_folios: -+ folio_unlock(folio[0]); -+ folio_put(folio[0]); -+ folio_unlock(folio[1]); -+ folio_put(folio[1]); - stop_journal: - ext4_journal_stop(handle); - if (*err == -ENOSPC && -@@ -430,7 +436,7 @@ repair_branches: - *err = -EIO; - } - replaced_count = 0; -- goto unlock_pages; -+ goto unlock_folios; - } - - /** -diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c -index 5df04ed010cae..eb4d69f53337f 100644 ---- a/fs/f2fs/checkpoint.c -+++ b/fs/f2fs/checkpoint.c -@@ -984,7 +984,7 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) - - cp_blk_no = le32_to_cpu(fsb->cp_blkaddr); - if (cur_page == cp2) -- cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg); -+ cp_blk_no += BIT(le32_to_cpu(fsb->log_blocks_per_seg)); - - for (i = 1; i < cp_blks; i++) { - void *sit_bitmap_ptr; -diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c -index 11d9dce994dbe..4cb58e8d699e2 100644 ---- a/fs/f2fs/compress.c -+++ b/fs/f2fs/compress.c -@@ -241,7 +241,7 @@ static int lz4_init_compress_ctx(struct compress_ctx *cc) - unsigned int size = LZ4_MEM_COMPRESS; - - #ifdef CONFIG_F2FS_FS_LZ4HC -- if (F2FS_I(cc->inode)->i_compress_flag >> COMPRESS_LEVEL_OFFSET) -+ if (F2FS_I(cc->inode)->i_compress_level) - size = LZ4HC_MEM_COMPRESS; - #endif - -@@ -267,8 +267,7 @@ static void lz4_destroy_compress_ctx(struct compress_ctx *cc) - #ifdef CONFIG_F2FS_FS_LZ4HC - static int lz4hc_compress_pages(struct compress_ctx *cc) - { -- unsigned char level = F2FS_I(cc->inode)->i_compress_flag >> -- COMPRESS_LEVEL_OFFSET; -+ unsigned char level = F2FS_I(cc->inode)->i_compress_level; - int len; - - if (level) -@@ -332,17 +331,15 @@ static const struct f2fs_compress_ops f2fs_lz4_ops = { - #endif - - #ifdef CONFIG_F2FS_FS_ZSTD --#define F2FS_ZSTD_DEFAULT_CLEVEL 1 -- - static int zstd_init_compress_ctx(struct compress_ctx *cc) - { - zstd_parameters params; - zstd_cstream *stream; - void *workspace; - unsigned int workspace_size; -- unsigned char level = F2FS_I(cc->inode)->i_compress_flag >> -- COMPRESS_LEVEL_OFFSET; -+ unsigned char level = F2FS_I(cc->inode)->i_compress_level; - -+ /* Need to remain this for backward compatibility */ - if (!level) - level = F2FS_ZSTD_DEFAULT_CLEVEL; - -@@ -675,7 +672,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc) - - cc->cbuf->clen = cpu_to_le32(cc->clen); - -- if (fi->i_compress_flag & 1 << COMPRESS_CHKSUM) -+ if (fi->i_compress_flag & BIT(COMPRESS_CHKSUM)) - chksum = f2fs_crc32(F2FS_I_SB(cc->inode), - cc->cbuf->cdata, cc->clen); - cc->cbuf->chksum = cpu_to_le32(chksum); -@@ -773,7 +770,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task) - - ret = cops->decompress_pages(dic); - -- if (!ret && (fi->i_compress_flag & 1 << COMPRESS_CHKSUM)) { -+ if (!ret && (fi->i_compress_flag & BIT(COMPRESS_CHKSUM))) { - u32 provided = le32_to_cpu(dic->cbuf->chksum); - u32 calculated = f2fs_crc32(sbi, dic->cbuf->cdata, dic->clen); - -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index ea05710ca9bdf..3666c1fd77a64 100644 ---- a/fs/f2fs/data.c -+++ b/fs/f2fs/data.c -@@ -95,17 +95,17 @@ static enum count_type __read_io_type(struct page *page) - /* postprocessing steps for read bios */ - enum bio_post_read_step { - #ifdef CONFIG_FS_ENCRYPTION -- STEP_DECRYPT = 1 << 0, -+ STEP_DECRYPT = BIT(0), - #else - STEP_DECRYPT = 0, /* compile out the decryption-related code */ - #endif - #ifdef CONFIG_F2FS_FS_COMPRESSION -- STEP_DECOMPRESS = 1 << 1, -+ STEP_DECOMPRESS = BIT(1), - #else - STEP_DECOMPRESS = 0, /* compile out the decompression-related code */ - #endif - #ifdef CONFIG_FS_VERITY -- STEP_VERITY = 1 << 2, -+ STEP_VERITY = BIT(2), - #else - STEP_VERITY = 0, /* compile out the verity-related code */ - #endif -@@ -409,7 +409,7 @@ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr) - - static blk_opf_t f2fs_io_flags(struct f2fs_io_info *fio) - { -- unsigned int temp_mask = (1 << NR_TEMP_TYPE) - 1; -+ unsigned int temp_mask = GENMASK(NR_TEMP_TYPE - 1, 0); - unsigned int fua_flag, meta_flag, io_flag; - blk_opf_t op_flags = 0; - -@@ -431,9 +431,9 @@ static blk_opf_t f2fs_io_flags(struct f2fs_io_info *fio) - * 5 | 4 | 3 | 2 | 1 | 0 | - * Cold | Warm | Hot | Cold | Warm | Hot | - */ -- if ((1 << fio->temp) & meta_flag) -+ if (BIT(fio->temp) & meta_flag) - op_flags |= REQ_META; -- if ((1 << fio->temp) & fua_flag) -+ if (BIT(fio->temp) & fua_flag) - op_flags |= REQ_FUA; - return op_flags; - } -diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c -index 8373eba3a1337..510736d2ae110 100644 ---- a/fs/f2fs/dir.c -+++ b/fs/f2fs/dir.c -@@ -29,7 +29,7 @@ static unsigned long dir_blocks(struct inode *inode) - static unsigned int dir_buckets(unsigned int level, int dir_level) - { - if (level + dir_level < MAX_DIR_HASH_DEPTH / 2) -- return 1 << (level + dir_level); -+ return BIT(level + dir_level); - else - return MAX_DIR_BUCKETS; - } -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index f56abb39601ac..5c76ba764b71f 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -64,7 +64,7 @@ enum { - }; - - #ifdef CONFIG_F2FS_FAULT_INJECTION --#define F2FS_ALL_FAULT_TYPE ((1 << FAULT_MAX) - 1) -+#define F2FS_ALL_FAULT_TYPE (GENMASK(FAULT_MAX - 1, 0)) - - struct f2fs_fault_info { - atomic_t inject_ops; -@@ -73,7 +73,7 @@ struct f2fs_fault_info { - }; - - extern const char *f2fs_fault_name[FAULT_MAX]; --#define IS_FAULT_SET(fi, type) ((fi)->inject_type & (1 << (type))) -+#define IS_FAULT_SET(fi, type) ((fi)->inject_type & BIT(type)) - #endif - - /* -@@ -840,7 +840,7 @@ struct f2fs_inode_info { - unsigned char i_compress_algorithm; /* algorithm type */ - unsigned char i_log_cluster_size; /* log of cluster size */ - unsigned char i_compress_level; /* compress level (lz4hc,zstd) */ -- unsigned short i_compress_flag; /* compress flag */ -+ unsigned char i_compress_flag; /* compress flag */ - unsigned int i_cluster_size; /* cluster size */ - - unsigned int atomic_write_cnt; -@@ -1412,7 +1412,7 @@ static inline void set_page_private_##name(struct page *page) \ - static inline void clear_page_private_##name(struct page *page) \ - { \ - clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \ -- if (page_private(page) == 1 << PAGE_PRIVATE_NOT_POINTER) { \ -+ if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) { \ - set_page_private(page, 0); \ - if (PagePrivate(page)) { \ - ClearPagePrivate(page); \ -@@ -1462,8 +1462,8 @@ static inline void set_page_private_data(struct page *page, unsigned long data) - - static inline void clear_page_private_data(struct page *page) - { -- page_private(page) &= (1 << PAGE_PRIVATE_MAX) - 1; -- if (page_private(page) == 1 << PAGE_PRIVATE_NOT_POINTER) { -+ page_private(page) &= GENMASK(PAGE_PRIVATE_MAX - 1, 0); -+ if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) { - set_page_private(page, 0); - if (PagePrivate(page)) { - ClearPagePrivate(page); -@@ -1501,6 +1501,8 @@ struct compress_data { - - #define F2FS_COMPRESSED_PAGE_MAGIC 0xF5F2C000 - -+#define F2FS_ZSTD_DEFAULT_CLEVEL 1 -+ - #define COMPRESS_LEVEL_OFFSET 8 - - /* compress context */ -@@ -2882,7 +2884,7 @@ static inline int f2fs_test_bit(unsigned int nr, char *addr) - int mask; - - addr += (nr >> 3); -- mask = 1 << (7 - (nr & 0x07)); -+ mask = BIT(7 - (nr & 0x07)); - return mask & *addr; - } - -@@ -2891,7 +2893,7 @@ static inline void f2fs_set_bit(unsigned int nr, char *addr) - int mask; - - addr += (nr >> 3); -- mask = 1 << (7 - (nr & 0x07)); -+ mask = BIT(7 - (nr & 0x07)); - *addr |= mask; - } - -@@ -2900,7 +2902,7 @@ static inline void f2fs_clear_bit(unsigned int nr, char *addr) - int mask; - - addr += (nr >> 3); -- mask = 1 << (7 - (nr & 0x07)); -+ mask = BIT(7 - (nr & 0x07)); - *addr &= ~mask; - } - -@@ -2910,7 +2912,7 @@ static inline int f2fs_test_and_set_bit(unsigned int nr, char *addr) - int ret; - - addr += (nr >> 3); -- mask = 1 << (7 - (nr & 0x07)); -+ mask = BIT(7 - (nr & 0x07)); - ret = mask & *addr; - *addr |= mask; - return ret; -@@ -2922,7 +2924,7 @@ static inline int f2fs_test_and_clear_bit(unsigned int nr, char *addr) - int ret; - - addr += (nr >> 3); -- mask = 1 << (7 - (nr & 0x07)); -+ mask = BIT(7 - (nr & 0x07)); - ret = mask & *addr; - *addr &= ~mask; - return ret; -@@ -2933,7 +2935,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) - int mask; - - addr += (nr >> 3); -- mask = 1 << (7 - (nr & 0x07)); -+ mask = BIT(7 - (nr & 0x07)); - *addr ^= mask; - } - -@@ -4333,15 +4335,14 @@ static inline int set_compress_context(struct inode *inode) - F2FS_OPTION(sbi).compress_log_size; - F2FS_I(inode)->i_compress_flag = - F2FS_OPTION(sbi).compress_chksum ? -- 1 << COMPRESS_CHKSUM : 0; -+ BIT(COMPRESS_CHKSUM) : 0; - F2FS_I(inode)->i_cluster_size = -- 1 << F2FS_I(inode)->i_log_cluster_size; -+ BIT(F2FS_I(inode)->i_log_cluster_size); - if ((F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 || - F2FS_I(inode)->i_compress_algorithm == COMPRESS_ZSTD) && - F2FS_OPTION(sbi).compress_level) -- F2FS_I(inode)->i_compress_flag |= -- F2FS_OPTION(sbi).compress_level << -- COMPRESS_LEVEL_OFFSET; -+ F2FS_I(inode)->i_compress_level = -+ F2FS_OPTION(sbi).compress_level; - F2FS_I(inode)->i_flags |= F2FS_COMPR_FL; - set_inode_flag(inode, FI_COMPRESSED_FILE); - stat_inc_compr_inode(inode); -diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c -index d0c17366ebf48..9b9fb3c57ec6c 100644 ---- a/fs/f2fs/file.c -+++ b/fs/f2fs/file.c -@@ -3983,7 +3983,16 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg) - - F2FS_I(inode)->i_compress_algorithm = option.algorithm; - F2FS_I(inode)->i_log_cluster_size = option.log_cluster_size; -- F2FS_I(inode)->i_cluster_size = 1 << option.log_cluster_size; -+ F2FS_I(inode)->i_cluster_size = BIT(option.log_cluster_size); -+ /* Set default level */ -+ if (F2FS_I(inode)->i_compress_algorithm == COMPRESS_ZSTD) -+ F2FS_I(inode)->i_compress_level = F2FS_ZSTD_DEFAULT_CLEVEL; -+ else -+ F2FS_I(inode)->i_compress_level = 0; -+ /* Adjust mount option level */ -+ if (option.algorithm == F2FS_OPTION(sbi).compress_algorithm && -+ F2FS_OPTION(sbi).compress_level) -+ F2FS_I(inode)->i_compress_level = F2FS_OPTION(sbi).compress_level; - f2fs_mark_inode_dirty_sync(inode, true); - - if (!f2fs_is_compress_backend_ready(inode)) -diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c -index 1fc7760499f10..0010579f17368 100644 ---- a/fs/f2fs/inode.c -+++ b/fs/f2fs/inode.c -@@ -450,12 +450,18 @@ static int do_read_inode(struct inode *inode) - (fi->i_flags & F2FS_COMPR_FL)) { - if (F2FS_FITS_IN_INODE(ri, fi->i_extra_isize, - i_log_cluster_size)) { -+ unsigned short compress_flag; -+ - atomic_set(&fi->i_compr_blocks, - le64_to_cpu(ri->i_compr_blocks)); - fi->i_compress_algorithm = ri->i_compress_algorithm; - fi->i_log_cluster_size = ri->i_log_cluster_size; -- fi->i_compress_flag = le16_to_cpu(ri->i_compress_flag); -- fi->i_cluster_size = 1 << fi->i_log_cluster_size; -+ compress_flag = le16_to_cpu(ri->i_compress_flag); -+ fi->i_compress_level = compress_flag >> -+ COMPRESS_LEVEL_OFFSET; -+ fi->i_compress_flag = compress_flag & -+ GENMASK(COMPRESS_LEVEL_OFFSET - 1, 0); -+ fi->i_cluster_size = BIT(fi->i_log_cluster_size); - set_inode_flag(inode, FI_COMPRESSED_FILE); - } - } -@@ -675,13 +681,17 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page) - if (f2fs_sb_has_compression(F2FS_I_SB(inode)) && - F2FS_FITS_IN_INODE(ri, F2FS_I(inode)->i_extra_isize, - i_log_cluster_size)) { -+ unsigned short compress_flag; -+ - ri->i_compr_blocks = - cpu_to_le64(atomic_read( - &F2FS_I(inode)->i_compr_blocks)); - ri->i_compress_algorithm = - F2FS_I(inode)->i_compress_algorithm; -- ri->i_compress_flag = -- cpu_to_le16(F2FS_I(inode)->i_compress_flag); -+ compress_flag = F2FS_I(inode)->i_compress_flag | -+ F2FS_I(inode)->i_compress_level << -+ COMPRESS_LEVEL_OFFSET; -+ ri->i_compress_flag = cpu_to_le16(compress_flag); - ri->i_log_cluster_size = - F2FS_I(inode)->i_log_cluster_size; - } -diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h -index 0aa48704c77a0..7068f3ac036a5 100644 ---- a/fs/f2fs/node.h -+++ b/fs/f2fs/node.h -@@ -93,17 +93,15 @@ static inline void copy_node_info(struct node_info *dst, - static inline void set_nat_flag(struct nat_entry *ne, - unsigned int type, bool set) - { -- unsigned char mask = 0x01 << type; - if (set) -- ne->ni.flag |= mask; -+ ne->ni.flag |= BIT(type); - else -- ne->ni.flag &= ~mask; -+ ne->ni.flag &= ~BIT(type); - } - - static inline bool get_nat_flag(struct nat_entry *ne, unsigned int type) - { -- unsigned char mask = 0x01 << type; -- return ne->ni.flag & mask; -+ return ne->ni.flag & BIT(type); - } - - static inline void nat_reset_flag(struct nat_entry *ne) -@@ -224,7 +222,7 @@ static inline pgoff_t next_nat_addr(struct f2fs_sb_info *sbi, - struct f2fs_nm_info *nm_i = NM_I(sbi); - - block_addr -= nm_i->nat_blkaddr; -- block_addr ^= 1 << sbi->log_blocks_per_seg; -+ block_addr ^= BIT(sbi->log_blocks_per_seg); - return block_addr + nm_i->nat_blkaddr; - } - -@@ -394,7 +392,7 @@ static inline nid_t get_nid(struct page *p, int off, bool i) - static inline int is_node(struct page *page, int type) - { - struct f2fs_node *rn = F2FS_NODE(page); -- return le32_to_cpu(rn->footer.flag) & (1 << type); -+ return le32_to_cpu(rn->footer.flag) & BIT(type); - } - - #define is_cold_node(page) is_node(page, COLD_BIT_SHIFT) -@@ -407,9 +405,9 @@ static inline void set_cold_node(struct page *page, bool is_dir) - unsigned int flag = le32_to_cpu(rn->footer.flag); - - if (is_dir) -- flag &= ~(0x1 << COLD_BIT_SHIFT); -+ flag &= ~BIT(COLD_BIT_SHIFT); - else -- flag |= (0x1 << COLD_BIT_SHIFT); -+ flag |= BIT(COLD_BIT_SHIFT); - rn->footer.flag = cpu_to_le32(flag); - } - -@@ -418,9 +416,9 @@ static inline void set_mark(struct page *page, int mark, int type) - struct f2fs_node *rn = F2FS_NODE(page); - unsigned int flag = le32_to_cpu(rn->footer.flag); - if (mark) -- flag |= (0x1 << type); -+ flag |= BIT(type); - else -- flag &= ~(0x1 << type); -+ flag &= ~BIT(type); - rn->footer.flag = cpu_to_le32(flag); - - #ifdef CONFIG_F2FS_CHECK_FS -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 1ba85ef97cbd3..3805162dcef2b 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -613,14 +613,12 @@ static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str) - { - #ifdef CONFIG_F2FS_FS_LZ4HC - unsigned int level; --#endif - - if (strlen(str) == 3) { - F2FS_OPTION(sbi).compress_level = 0; - return 0; - } - --#ifdef CONFIG_F2FS_FS_LZ4HC - str += 3; - - if (str[0] != ':') { -@@ -638,6 +636,10 @@ static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str) - F2FS_OPTION(sbi).compress_level = level; - return 0; - #else -+ if (strlen(str) == 3) { -+ F2FS_OPTION(sbi).compress_level = 0; -+ return 0; -+ } - f2fs_info(sbi, "kernel doesn't support lz4hc compression"); - return -EINVAL; - #endif -@@ -651,7 +653,7 @@ static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str) - int len = 4; - - if (strlen(str) == len) { -- F2FS_OPTION(sbi).compress_level = 0; -+ F2FS_OPTION(sbi).compress_level = F2FS_ZSTD_DEFAULT_CLEVEL; - return 0; - } - -@@ -664,7 +666,7 @@ static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str) - if (kstrtouint(str + 1, 10, &level)) - return -EINVAL; - -- if (!level || level > zstd_max_clevel()) { -+ if (level < zstd_min_clevel() || level > zstd_max_clevel()) { - f2fs_info(sbi, "invalid zstd compress level: %d", level); - return -EINVAL; - } -@@ -898,8 +900,8 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) - if (args->from && match_int(args, &arg)) - return -EINVAL; - if (arg <= 0 || arg > __ilog2_u32(BIO_MAX_VECS)) { -- f2fs_warn(sbi, "Not support %d, larger than %d", -- 1 << arg, BIO_MAX_VECS); -+ f2fs_warn(sbi, "Not support %ld, larger than %d", -+ BIT(arg), BIO_MAX_VECS); - return -EINVAL; - } - F2FS_OPTION(sbi).write_io_size_bits = arg; -@@ -1340,7 +1342,7 @@ default_check: - #endif - - if (F2FS_IO_SIZE_BITS(sbi) && !f2fs_lfs_mode(sbi)) { -- f2fs_err(sbi, "Should set mode=lfs with %uKB-sized IO", -+ f2fs_err(sbi, "Should set mode=lfs with %luKB-sized IO", - F2FS_IO_SIZE_KB(sbi)); - return -EINVAL; - } -@@ -3356,7 +3358,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, - total_sections = le32_to_cpu(raw_super->section_count); - - /* blocks_per_seg should be 512, given the above check */ -- blocks_per_seg = 1 << le32_to_cpu(raw_super->log_blocks_per_seg); -+ blocks_per_seg = BIT(le32_to_cpu(raw_super->log_blocks_per_seg)); - - if (segment_count > F2FS_MAX_SEGMENT || - segment_count < F2FS_MIN_SEGMENTS) { -@@ -3625,9 +3627,9 @@ static void init_sb_info(struct f2fs_sb_info *sbi) - sbi->log_sectors_per_block = - le32_to_cpu(raw_super->log_sectors_per_block); - sbi->log_blocksize = le32_to_cpu(raw_super->log_blocksize); -- sbi->blocksize = 1 << sbi->log_blocksize; -+ sbi->blocksize = BIT(sbi->log_blocksize); - sbi->log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); -- sbi->blocks_per_seg = 1 << sbi->log_blocks_per_seg; -+ sbi->blocks_per_seg = BIT(sbi->log_blocks_per_seg); - sbi->segs_per_sec = le32_to_cpu(raw_super->segs_per_sec); - sbi->secs_per_zone = le32_to_cpu(raw_super->secs_per_zone); - sbi->total_sections = le32_to_cpu(raw_super->section_count); -@@ -3883,7 +3885,7 @@ void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason) - - f2fs_down_write(&sbi->sb_lock); - -- if (raw_super->s_stop_reason[reason] < ((1 << BITS_PER_BYTE) - 1)) -+ if (raw_super->s_stop_reason[reason] < GENMASK(BITS_PER_BYTE - 1, 0)) - raw_super->s_stop_reason[reason]++; - - err = f2fs_commit_super(sbi, false); -@@ -4033,7 +4035,7 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi) - FDEV(i).start_blk, FDEV(i).end_blk); - } - f2fs_info(sbi, -- "IO Block Size: %8d KB", F2FS_IO_SIZE_KB(sbi)); -+ "IO Block Size: %8ld KB", F2FS_IO_SIZE_KB(sbi)); - return 0; - } - -diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c -index 3d68bfa75cf2a..751a108e612ff 100644 ---- a/fs/f2fs/sysfs.c -+++ b/fs/f2fs/sysfs.c -@@ -451,7 +451,7 @@ out: - if (ret < 0) - return ret; - #ifdef CONFIG_F2FS_FAULT_INJECTION -- if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX)) -+ if (a->struct_type == FAULT_INFO_TYPE && t >= BIT(FAULT_MAX)) - return -EINVAL; - if (a->struct_type == FAULT_INFO_RATE && t >= UINT_MAX) - return -EINVAL; -diff --git a/fs/inode.c b/fs/inode.c -index 73ad1b0d47758..8cfda7a6d5900 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -215,6 +215,8 @@ int inode_init_always(struct super_block *sb, struct inode *inode) - lockdep_set_class_and_name(&mapping->invalidate_lock, - &sb->s_type->invalidate_lock_key, - "mapping.invalidate_lock"); -+ if (sb->s_iflags & SB_I_STABLE_WRITES) -+ mapping_set_stable_writes(mapping); - inode->i_private = NULL; - inode->i_mapping = mapping; - INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ -diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c -index e731c00a9fcbc..d3c938dd2b12a 100644 ---- a/fs/nfs/fscache.c -+++ b/fs/nfs/fscache.c -@@ -176,6 +176,9 @@ void nfs_fscache_init_inode(struct inode *inode) - &auxdata, /* aux_data */ - sizeof(auxdata), - i_size_read(inode)); -+ -+ if (netfs_inode(inode)->cache) -+ mapping_set_release_always(inode->i_mapping); - } - - /* -diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h -index 512ac9dea9787..7f1aea4c11b9c 100644 ---- a/fs/smb/client/cifsglob.h -+++ b/fs/smb/client/cifsglob.h -@@ -972,7 +972,6 @@ release_iface(struct kref *ref) - struct cifs_server_iface *iface = container_of(ref, - struct cifs_server_iface, - refcount); -- list_del_init(&iface->iface_head); - kfree(iface); - } - -diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c -index f725a119ce312..49fdc6dfdcf8d 100644 ---- a/fs/smb/client/connect.c -+++ b/fs/smb/client/connect.c -@@ -258,10 +258,13 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server, - spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) { - /* check if iface is still active */ -- if (!cifs_chan_is_iface_active(ses, server)) -+ spin_lock(&ses->chan_lock); -+ if (!cifs_chan_is_iface_active(ses, server)) { -+ spin_unlock(&ses->chan_lock); - cifs_chan_update_iface(ses, server); -+ spin_lock(&ses->chan_lock); -+ } - -- spin_lock(&ses->chan_lock); - if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server)) { - spin_unlock(&ses->chan_lock); - continue; -diff --git a/fs/smb/client/fscache.c b/fs/smb/client/fscache.c -index e73625b5d0cc6..f64bad513ba6d 100644 ---- a/fs/smb/client/fscache.c -+++ b/fs/smb/client/fscache.c -@@ -108,6 +108,8 @@ void cifs_fscache_get_inode_cookie(struct inode *inode) - &cifsi->uniqueid, sizeof(cifsi->uniqueid), - &cd, sizeof(cd), - i_size_read(&cifsi->netfs.inode)); -+ if (cifsi->netfs.cache) -+ mapping_set_release_always(inode->i_mapping); - } - - void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) -diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c -index 7be51f9d2fa18..5343898bac8a6 100644 ---- a/fs/smb/client/inode.c -+++ b/fs/smb/client/inode.c -@@ -264,7 +264,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, - fattr->cf_dtype = DT_REG; - break; - case UNIX_SYMLINK: -- fattr->cf_mode |= S_IFLNK; -+ fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode; - fattr->cf_dtype = DT_LNK; - break; - case UNIX_DIR: -diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c -index ba6cc50af390f..a7475bc05cac0 100644 ---- a/fs/smb/client/smb2file.c -+++ b/fs/smb/client/smb2file.c -@@ -34,7 +34,7 @@ static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov) - len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp, - ErrorContextData) + - sizeof(struct smb2_symlink_err_rsp)); -- if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err)) -+ if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err) + 1) - return ERR_PTR(-EINVAL); - - p = (struct smb2_error_context_rsp *)err->ErrorData; -diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c -index 88942b1fb4318..fdf7a7f188c5f 100644 ---- a/fs/smb/client/smb2misc.c -+++ b/fs/smb/client/smb2misc.c -@@ -113,7 +113,7 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len, - } else if (nc_offset + 1 == non_ctxlen) { - cifs_dbg(FYI, "no SPNEGO security blob in negprot rsp\n"); - size_of_pad_before_neg_ctxts = 0; -- } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE) -+ } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE + 1) - /* has padding, but no SPNEGO blob */ - size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen + 1; - else -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index df03d80ab6d5f..4596d2dfdec3a 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -588,16 +588,12 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, - } - - /* -- * Go through iface_list and do kref_put to remove -- * any unused ifaces. ifaces in use will be removed -- * when the last user calls a kref_put on it -+ * Go through iface_list and mark them as inactive - */ - list_for_each_entry_safe(iface, niface, &ses->iface_list, -- iface_head) { -+ iface_head) - iface->is_active = 0; -- kref_put(&iface->refcount, release_iface); -- ses->iface_count--; -- } -+ - spin_unlock(&ses->iface_lock); - - /* -@@ -672,10 +668,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, - iface_head) { - ret = iface_cmp(iface, &tmp_iface); - if (!ret) { -- /* just get a ref so that it doesn't get picked/freed */ - iface->is_active = 1; -- kref_get(&iface->refcount); -- ses->iface_count++; - spin_unlock(&ses->iface_lock); - goto next_iface; - } else if (ret < 0) { -@@ -742,6 +735,20 @@ next_iface: - } - - out: -+ /* -+ * Go through the list again and put the inactive entries -+ */ -+ spin_lock(&ses->iface_lock); -+ list_for_each_entry_safe(iface, niface, &ses->iface_list, -+ iface_head) { -+ if (!iface->is_active) { -+ list_del(&iface->iface_head); -+ kref_put(&iface->refcount, release_iface); -+ ses->iface_count--; -+ } -+ } -+ spin_unlock(&ses->iface_lock); -+ - return rc; - } - -@@ -778,9 +785,14 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_ - goto out; - - /* check if iface is still active */ -+ spin_lock(&ses->chan_lock); - pserver = ses->chans[0].server; -- if (pserver && !cifs_chan_is_iface_active(ses, pserver)) -+ if (pserver && !cifs_chan_is_iface_active(ses, pserver)) { -+ spin_unlock(&ses->chan_lock); - cifs_chan_update_iface(ses, pserver); -+ spin_lock(&ses->chan_lock); -+ } -+ spin_unlock(&ses->chan_lock); - - out: - kfree(out_buf); -@@ -5752,7 +5764,7 @@ struct smb_version_values smb20_values = { - .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -5774,7 +5786,7 @@ struct smb_version_values smb21_values = { - .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -5795,7 +5807,7 @@ struct smb_version_values smb3any_values = { - .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -5816,7 +5828,7 @@ struct smb_version_values smbdefault_values = { - .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -5837,7 +5849,7 @@ struct smb_version_values smb30_values = { - .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -5858,7 +5870,7 @@ struct smb_version_values smb302_values = { - .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -5879,7 +5891,7 @@ struct smb_version_values smb311_values = { - .header_size = sizeof(struct smb2_hdr), - .header_preamble_size = 0, - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index 05ff8a457a3d7..2dfbf1b23cfa0 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -1386,7 +1386,7 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data) - - /* Testing shows that buffer offset must be at location of Buffer[0] */ - req->SecurityBufferOffset = -- cpu_to_le16(sizeof(struct smb2_sess_setup_req) - 1 /* pad */); -+ cpu_to_le16(sizeof(struct smb2_sess_setup_req)); - req->SecurityBufferLength = cpu_to_le16(sess_data->iov[1].iov_len); - - memset(&rqst, 0, sizeof(struct smb_rqst)); -@@ -1905,8 +1905,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, - iov[0].iov_len = total_len - 1; - - /* Testing shows that buffer offset must be at location of Buffer[0] */ -- req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req) -- - 1 /* pad */); -+ req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req)); - req->PathLength = cpu_to_le16(unc_path_len - 2); - iov[1].iov_base = unc_path; - iov[1].iov_len = unc_path_len; -@@ -3796,7 +3795,7 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, - ses->Suid, (u8)watch_tree, completion_filter); - /* validate that notify information is plausible */ - if ((rsp_iov.iov_base == NULL) || -- (rsp_iov.iov_len < sizeof(struct smb2_change_notify_rsp))) -+ (rsp_iov.iov_len < sizeof(struct smb2_change_notify_rsp) + 1)) - goto cnotify_exit; - - smb_rsp = (struct smb2_change_notify_rsp *)rsp_iov.iov_base; -@@ -5009,7 +5008,7 @@ int SMB2_query_directory_init(const unsigned int xid, - memcpy(bufptr, &asteriks, len); - - req->FileNameOffset = -- cpu_to_le16(sizeof(struct smb2_query_directory_req) - 1); -+ cpu_to_le16(sizeof(struct smb2_query_directory_req)); - req->FileNameLength = cpu_to_le16(len); - /* - * BB could be 30 bytes or so longer if we used SMB2 specific -@@ -5205,8 +5204,7 @@ SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, - req->VolatileFileId = volatile_fid; - req->AdditionalInformation = cpu_to_le32(additional_info); - -- req->BufferOffset = -- cpu_to_le16(sizeof(struct smb2_set_info_req) - 1); -+ req->BufferOffset = cpu_to_le16(sizeof(struct smb2_set_info_req)); - req->BufferLength = cpu_to_le32(*size); - - memcpy(req->Buffer, *data, *size); -@@ -5440,9 +5438,9 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, - req->VolatileFileId = volatile_fid; - /* 1 for pad */ - req->InputBufferOffset = -- cpu_to_le16(sizeof(struct smb2_query_info_req) - 1); -+ cpu_to_le16(sizeof(struct smb2_query_info_req)); - req->OutputBufferLength = cpu_to_le32( -- outbuf_len + sizeof(struct smb2_query_info_rsp) - 1); -+ outbuf_len + sizeof(struct smb2_query_info_rsp)); - - iov->iov_base = (char *)req; - iov->iov_len = total_len; -diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h -index 1237bb86e93a8..a5773a06aba8e 100644 ---- a/fs/smb/client/smb2pdu.h -+++ b/fs/smb/client/smb2pdu.h -@@ -57,7 +57,7 @@ struct smb2_rdma_crypto_transform { - #define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL - - #define SMB2_SYMLINK_STRUCT_SIZE \ -- (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) -+ (sizeof(struct smb2_err_rsp) + sizeof(struct smb2_symlink_err_rsp)) - - #define SYMLINK_ERROR_TAG 0x4c4d5953 - -diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h -index 07549957b3099..5593bb49954c6 100644 ---- a/fs/smb/common/smb2pdu.h -+++ b/fs/smb/common/smb2pdu.h -@@ -189,7 +189,7 @@ struct smb2_err_rsp { - __u8 ErrorContextCount; - __u8 Reserved; - __le32 ByteCount; /* even if zero, at least one byte follows */ -- __u8 ErrorData[1]; /* variable length */ -+ __u8 ErrorData[]; /* variable length */ - } __packed; - - #define SMB3_AES_CCM_NONCE 11 -@@ -330,7 +330,7 @@ struct smb2_tree_connect_req { - __le16 Flags; /* Flags in SMB3.1.1 */ - __le16 PathOffset; - __le16 PathLength; -- __u8 Buffer[1]; /* variable length */ -+ __u8 Buffer[]; /* variable length */ - } __packed; - - /* Possible ShareType values */ -@@ -617,7 +617,7 @@ struct smb2_negotiate_rsp { - __le16 SecurityBufferOffset; - __le16 SecurityBufferLength; - __le32 NegotiateContextOffset; /* Pre:SMB3.1.1 was reserved/ignored */ -- __u8 Buffer[1]; /* variable length GSS security buffer */ -+ __u8 Buffer[]; /* variable length GSS security buffer */ - } __packed; - - -@@ -638,7 +638,7 @@ struct smb2_sess_setup_req { - __le16 SecurityBufferOffset; - __le16 SecurityBufferLength; - __le64 PreviousSessionId; -- __u8 Buffer[1]; /* variable length GSS security buffer */ -+ __u8 Buffer[]; /* variable length GSS security buffer */ - } __packed; - - /* Currently defined SessionFlags */ -@@ -655,7 +655,7 @@ struct smb2_sess_setup_rsp { - __le16 SessionFlags; - __le16 SecurityBufferOffset; - __le16 SecurityBufferLength; -- __u8 Buffer[1]; /* variable length GSS security buffer */ -+ __u8 Buffer[]; /* variable length GSS security buffer */ - } __packed; - - -@@ -737,7 +737,7 @@ struct smb2_read_req { - __le32 RemainingBytes; - __le16 ReadChannelInfoOffset; - __le16 ReadChannelInfoLength; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - /* Read flags */ -@@ -752,7 +752,7 @@ struct smb2_read_rsp { - __le32 DataLength; - __le32 DataRemaining; - __le32 Flags; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - -@@ -776,7 +776,7 @@ struct smb2_write_req { - __le16 WriteChannelInfoOffset; - __le16 WriteChannelInfoLength; - __le32 Flags; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - struct smb2_write_rsp { -@@ -787,7 +787,7 @@ struct smb2_write_rsp { - __le32 DataLength; - __le32 DataRemaining; - __u32 Reserved2; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - -@@ -834,7 +834,10 @@ struct smb2_lock_req { - __u64 PersistentFileId; - __u64 VolatileFileId; - /* Followed by at least one */ -- struct smb2_lock_element locks[1]; -+ union { -+ struct smb2_lock_element lock; -+ DECLARE_FLEX_ARRAY(struct smb2_lock_element, locks); -+ }; - } __packed; - - struct smb2_lock_rsp { -@@ -888,7 +891,7 @@ struct smb2_query_directory_req { - __le16 FileNameOffset; - __le16 FileNameLength; - __le32 OutputBufferLength; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - struct smb2_query_directory_rsp { -@@ -896,7 +899,7 @@ struct smb2_query_directory_rsp { - __le16 StructureSize; /* Must be 9 */ - __le16 OutputBufferOffset; - __le32 OutputBufferLength; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - /* -@@ -919,7 +922,7 @@ struct smb2_set_info_req { - __le32 AdditionalInformation; - __u64 PersistentFileId; - __u64 VolatileFileId; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - struct smb2_set_info_rsp { -@@ -974,7 +977,7 @@ struct smb2_change_notify_rsp { - __le16 StructureSize; /* Must be 9 */ - __le16 OutputBufferOffset; - __le32 OutputBufferLength; -- __u8 Buffer[1]; /* array of file notify structs */ -+ __u8 Buffer[]; /* array of file notify structs */ - } __packed; - - -@@ -1180,7 +1183,7 @@ struct smb2_create_rsp { - __u64 VolatileFileId; - __le32 CreateContextsOffset; - __le32 CreateContextsLength; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - struct create_posix { -@@ -1524,7 +1527,7 @@ struct smb2_query_info_req { - __le32 Flags; - __u64 PersistentFileId; - __u64 VolatileFileId; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - struct smb2_query_info_rsp { -@@ -1532,7 +1535,7 @@ struct smb2_query_info_rsp { - __le16 StructureSize; /* Must be 9 */ - __le16 OutputBufferOffset; - __le32 OutputBufferLength; -- __u8 Buffer[1]; -+ __u8 Buffer[]; - } __packed; - - /* -@@ -1593,7 +1596,10 @@ struct smb2_file_all_info { /* data block encoding of response to level 18 */ - __le32 Mode; - __le32 AlignmentRequirement; - __le32 FileNameLength; -- char FileName[1]; -+ union { -+ char __pad; /* Legacy structure padding */ -+ DECLARE_FLEX_ARRAY(char, FileName); -+ }; - } __packed; /* level 18 Query */ - - struct smb2_file_eof_info { /* encoding of request for level 10 */ -diff --git a/fs/smb/server/smb2ops.c b/fs/smb/server/smb2ops.c -index 535402629655e..27a9dce3e03ab 100644 ---- a/fs/smb/server/smb2ops.c -+++ b/fs/smb/server/smb2ops.c -@@ -26,7 +26,7 @@ static struct smb_version_values smb21_server_values = { - .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, - .header_size = sizeof(struct smb2_hdr), - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -52,7 +52,7 @@ static struct smb_version_values smb30_server_values = { - .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, - .header_size = sizeof(struct smb2_hdr), - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -79,7 +79,7 @@ static struct smb_version_values smb302_server_values = { - .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, - .header_size = sizeof(struct smb2_hdr), - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -@@ -106,7 +106,7 @@ static struct smb_version_values smb311_server_values = { - .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, - .header_size = sizeof(struct smb2_hdr), - .max_header_size = MAX_SMB2_HDR_SIZE, -- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, -+ .read_rsp_size = sizeof(struct smb2_read_rsp), - .lock_cmd = SMB2_LOCK, - .cap_unix = 0, - .cap_nt_find = SMB2_NT_FIND, -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index ea48dd06d4da3..6e5ed0ac578a6 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -294,8 +294,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work) - if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY) - rsp->SecurityMode |= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE; - err = ksmbd_iov_pin_rsp(work, rsp, -- sizeof(struct smb2_negotiate_rsp) - -- sizeof(rsp->Buffer) + AUTH_GSS_LENGTH); -+ sizeof(struct smb2_negotiate_rsp) + AUTH_GSS_LENGTH); - if (err) - return err; - conn->use_spnego = true; -@@ -1263,9 +1262,8 @@ err_out: - - if (!rc) - rc = ksmbd_iov_pin_rsp(work, rsp, -- sizeof(struct smb2_negotiate_rsp) - -- sizeof(rsp->Buffer) + -- AUTH_GSS_LENGTH + neg_ctxt_len); -+ sizeof(struct smb2_negotiate_rsp) + -+ AUTH_GSS_LENGTH + neg_ctxt_len); - if (rc < 0) - smb2_set_err_rsp(work); - return rc; -diff --git a/fs/splice.c b/fs/splice.c -index 5969b7a1d353a..d0230cf8ec571 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -65,8 +65,7 @@ static bool page_cache_pipe_buf_try_steal(struct pipe_inode_info *pipe, - */ - folio_wait_writeback(folio); - -- if (folio_has_private(folio) && -- !filemap_release_folio(folio, GFP_KERNEL)) -+ if (!filemap_release_folio(folio, GFP_KERNEL)) - goto out_unlock; - - /* -@@ -764,6 +763,17 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, - return out->f_op->splice_write(pipe, out, ppos, len, flags); - } - -+/* -+ * Indicate to the caller that there was a premature EOF when reading from the -+ * source and the caller didn't indicate they would be sending more data after -+ * this. -+ */ -+static void do_splice_eof(struct splice_desc *sd) -+{ -+ if (sd->splice_eof) -+ sd->splice_eof(sd); -+} -+ - /* - * Attempt to initiate a splice from a file to a pipe. - */ -@@ -864,7 +874,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, - - ret = do_splice_to(in, &pos, pipe, len, flags); - if (unlikely(ret <= 0)) -- goto out_release; -+ goto read_failure; - - read_len = ret; - sd->total_len = read_len; -@@ -904,6 +914,15 @@ done: - file_accessed(in); - return bytes; - -+read_failure: -+ /* -+ * If the user did *not* set SPLICE_F_MORE *and* we didn't hit that -+ * "use all of len" case that cleared SPLICE_F_MORE, *and* we did a -+ * "->splice_in()" that returned EOF (ie zero) *and* we have sent at -+ * least 1 byte *then* we will also do the ->splice_eof() call. -+ */ -+ if (ret == 0 && !more && len > 0 && bytes) -+ do_splice_eof(sd); - out_release: - /* - * If we did an incomplete transfer we must release -@@ -932,6 +951,14 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, - sd->flags); - } - -+static void direct_file_splice_eof(struct splice_desc *sd) -+{ -+ struct file *file = sd->u.file; -+ -+ if (file->f_op->splice_eof) -+ file->f_op->splice_eof(file); -+} -+ - /** - * do_splice_direct - splices data directly between two files - * @in: file to splice from -@@ -957,6 +984,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, - .flags = flags, - .pos = *ppos, - .u.file = out, -+ .splice_eof = direct_file_splice_eof, - .opos = opos, - }; - long ret; -diff --git a/include/linux/bpf.h b/include/linux/bpf.h -index 3ce9e39ecdb85..ba22cf4f5fc0e 100644 ---- a/include/linux/bpf.h -+++ b/include/linux/bpf.h -@@ -702,10 +702,14 @@ bpf_ctx_record_field_size(struct bpf_insn_access_aux *aux, u32 size) - aux->ctx_field_size = size; - } - -+static bool bpf_is_ldimm64(const struct bpf_insn *insn) -+{ -+ return insn->code == (BPF_LD | BPF_IMM | BPF_DW); -+} -+ - static inline bool bpf_pseudo_func(const struct bpf_insn *insn) - { -- return insn->code == (BPF_LD | BPF_IMM | BPF_DW) && -- insn->src_reg == BPF_PSEUDO_FUNC; -+ return bpf_is_ldimm64(insn) && insn->src_reg == BPF_PSEUDO_FUNC; - } - - struct bpf_prog_ops { -@@ -825,6 +829,11 @@ struct btf_func_model { - */ - #define BPF_TRAMP_F_SHARE_IPMODIFY BIT(6) - -+/* Indicate that current trampoline is in a tail call context. Then, it has to -+ * cache and restore tail_call_cnt to avoid infinite tail call loop. -+ */ -+#define BPF_TRAMP_F_TAIL_CALL_CTX BIT(7) -+ - /* Each call __bpf_prog_enter + call bpf_func + call __bpf_prog_exit is ~50 - * bytes on x86. - */ -diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h -index 1a32baa78ce26..f080ccf27d256 100644 ---- a/include/linux/bpf_verifier.h -+++ b/include/linux/bpf_verifier.h -@@ -429,6 +429,7 @@ struct bpf_insn_aux_data { - /* below fields are initialized once */ - unsigned int orig_idx; /* original instruction index */ - bool prune_point; -+ bool jmp_point; - }; - - #define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */ -diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h -index ee0d75d9a302d..1e0df607e40c4 100644 ---- a/include/linux/f2fs_fs.h -+++ b/include/linux/f2fs_fs.h -@@ -40,9 +40,8 @@ - - #define F2FS_ENC_UTF8_12_1 1 - --#define F2FS_IO_SIZE(sbi) (1 << F2FS_OPTION(sbi).write_io_size_bits) /* Blocks */ --#define F2FS_IO_SIZE_KB(sbi) (1 << (F2FS_OPTION(sbi).write_io_size_bits + 2)) /* KB */ --#define F2FS_IO_SIZE_BYTES(sbi) (1 << (F2FS_OPTION(sbi).write_io_size_bits + 12)) /* B */ -+#define F2FS_IO_SIZE(sbi) BIT(F2FS_OPTION(sbi).write_io_size_bits) /* Blocks */ -+#define F2FS_IO_SIZE_KB(sbi) BIT(F2FS_OPTION(sbi).write_io_size_bits + 2) /* KB */ - #define F2FS_IO_SIZE_BITS(sbi) (F2FS_OPTION(sbi).write_io_size_bits) /* power of 2 */ - #define F2FS_IO_SIZE_MASK(sbi) (F2FS_IO_SIZE(sbi) - 1) - #define F2FS_IO_ALIGNED(sbi) (F2FS_IO_SIZE(sbi) > 1) -@@ -340,7 +339,7 @@ enum { - OFFSET_BIT_SHIFT - }; - --#define OFFSET_BIT_MASK (0x07) /* (0x01 << OFFSET_BIT_SHIFT) - 1 */ -+#define OFFSET_BIT_MASK GENMASK(OFFSET_BIT_SHIFT - 1, 0) - - struct node_footer { - __le32 nid; /* node id */ -@@ -545,7 +544,7 @@ typedef __le32 f2fs_hash_t; - #define MAX_DIR_HASH_DEPTH 63 - - /* MAX buckets in one level of dir */ --#define MAX_DIR_BUCKETS (1 << ((MAX_DIR_HASH_DEPTH / 2) - 1)) -+#define MAX_DIR_BUCKETS BIT((MAX_DIR_HASH_DEPTH / 2) - 1) - - /* - * space utilization of regular dentry and inline dentry (w/o extra reservation) -diff --git a/include/linux/fs.h b/include/linux/fs.h -index b6af6abc7a77f..4a1911dcf834b 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -2177,6 +2177,7 @@ struct file_operations { - int (*flock) (struct file *, int, struct file_lock *); - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); - ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); -+ void (*splice_eof)(struct file *file); - int (*setlease)(struct file *, long, struct file_lock **, void **); - long (*fallocate)(struct file *file, int mode, loff_t offset, - loff_t len); -diff --git a/include/linux/group_cpus.h b/include/linux/group_cpus.h -new file mode 100644 -index 0000000000000..e42807ec61f6e ---- /dev/null -+++ b/include/linux/group_cpus.h -@@ -0,0 +1,14 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (C) 2016 Thomas Gleixner. -+ * Copyright (C) 2016-2017 Christoph Hellwig. -+ */ -+ -+#ifndef __LINUX_GROUP_CPUS_H -+#define __LINUX_GROUP_CPUS_H -+#include -+#include -+ -+struct cpumask *group_cpus_evenly(unsigned int numgrps); -+ -+#endif -diff --git a/include/linux/net.h b/include/linux/net.h -index 18d942bbdf6e0..25baca60f6cba 100644 ---- a/include/linux/net.h -+++ b/include/linux/net.h -@@ -209,6 +209,7 @@ struct proto_ops { - int offset, size_t size, int flags); - ssize_t (*splice_read)(struct socket *sock, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, unsigned int flags); -+ void (*splice_eof)(struct socket *sock); - int (*set_peek_off)(struct sock *sk, int val); - int (*peek_len)(struct socket *sock); - -diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h -index 03307b72de6c6..1be5a1fa6a3a8 100644 ---- a/include/linux/pagemap.h -+++ b/include/linux/pagemap.h -@@ -199,6 +199,9 @@ enum mapping_flags { - /* writeback related tags are not used */ - AS_NO_WRITEBACK_TAGS = 5, - AS_LARGE_FOLIO_SUPPORT = 6, -+ AS_RELEASE_ALWAYS, /* Call ->release_folio(), even if no private data */ -+ AS_STABLE_WRITES, /* must wait for writeback before modifying -+ folio contents */ - }; - - /** -@@ -269,6 +272,36 @@ static inline int mapping_use_writeback_tags(struct address_space *mapping) - return !test_bit(AS_NO_WRITEBACK_TAGS, &mapping->flags); - } - -+static inline bool mapping_release_always(const struct address_space *mapping) -+{ -+ return test_bit(AS_RELEASE_ALWAYS, &mapping->flags); -+} -+ -+static inline void mapping_set_release_always(struct address_space *mapping) -+{ -+ set_bit(AS_RELEASE_ALWAYS, &mapping->flags); -+} -+ -+static inline void mapping_clear_release_always(struct address_space *mapping) -+{ -+ clear_bit(AS_RELEASE_ALWAYS, &mapping->flags); -+} -+ -+static inline bool mapping_stable_writes(const struct address_space *mapping) -+{ -+ return test_bit(AS_STABLE_WRITES, &mapping->flags); -+} -+ -+static inline void mapping_set_stable_writes(struct address_space *mapping) -+{ -+ set_bit(AS_STABLE_WRITES, &mapping->flags); -+} -+ -+static inline void mapping_clear_stable_writes(struct address_space *mapping) -+{ -+ clear_bit(AS_STABLE_WRITES, &mapping->flags); -+} -+ - static inline gfp_t mapping_gfp_mask(struct address_space * mapping) - { - return mapping->gfp_mask; -diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h -index c1637515a8a41..c953b8c0d2f43 100644 ---- a/include/linux/skmsg.h -+++ b/include/linux/skmsg.h -@@ -106,6 +106,7 @@ struct sk_psock { - struct mutex work_mutex; - struct sk_psock_work_state work_state; - struct delayed_work work; -+ struct sock *sk_pair; - struct rcu_work rwork; - }; - -diff --git a/include/linux/socket.h b/include/linux/socket.h -index 1db29aab8f9c3..b3c58042bd254 100644 ---- a/include/linux/socket.h -+++ b/include/linux/socket.h -@@ -324,6 +324,7 @@ struct ucred { - */ - - #define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */ -+#define MSG_SPLICE_PAGES 0x8000000 /* Splice the pages from the iterator in sendmsg() */ - #define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */ - #define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exec for file - descriptor received through -@@ -334,6 +335,8 @@ struct ucred { - #define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */ - #endif - -+/* Flags to be cleared on entry by sendmsg and sendmmsg syscalls */ -+#define MSG_INTERNAL_SENDMSG_FLAGS (MSG_SPLICE_PAGES) - - /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ - #define SOL_IP 0 -diff --git a/include/linux/splice.h b/include/linux/splice.h -index a55179fd60fc3..41a70687be853 100644 ---- a/include/linux/splice.h -+++ b/include/linux/splice.h -@@ -38,6 +38,7 @@ struct splice_desc { - struct file *file; /* file to read/write */ - void *data; /* cookie */ - } u; -+ void (*splice_eof)(struct splice_desc *sd); /* Unexpected EOF handler */ - loff_t pos; /* file position */ - loff_t *opos; /* sendfile: output position */ - size_t num_spliced; /* number of bytes already spliced */ -diff --git a/include/linux/udp.h b/include/linux/udp.h -index e96da4157d04d..efd9ab6df3797 100644 ---- a/include/linux/udp.h -+++ b/include/linux/udp.h -@@ -30,25 +30,33 @@ static inline u32 udp_hashfn(const struct net *net, u32 num, u32 mask) - return (num + net_hash_mix(net)) & mask; - } - -+enum { -+ UDP_FLAGS_CORK, /* Cork is required */ -+ UDP_FLAGS_NO_CHECK6_TX, /* Send zero UDP6 checksums on TX? */ -+ UDP_FLAGS_NO_CHECK6_RX, /* Allow zero UDP6 checksums on RX? */ -+ UDP_FLAGS_GRO_ENABLED, /* Request GRO aggregation */ -+ UDP_FLAGS_ACCEPT_FRAGLIST, -+ UDP_FLAGS_ACCEPT_L4, -+ UDP_FLAGS_ENCAP_ENABLED, /* This socket enabled encap */ -+}; -+ - struct udp_sock { - /* inet_sock has to be the first member */ - struct inet_sock inet; - #define udp_port_hash inet.sk.__sk_common.skc_u16hashes[0] - #define udp_portaddr_hash inet.sk.__sk_common.skc_u16hashes[1] - #define udp_portaddr_node inet.sk.__sk_common.skc_portaddr_node -+ -+ unsigned long udp_flags; -+ - int pending; /* Any pending frames ? */ -- unsigned int corkflag; /* Cork is required */ - __u8 encap_type; /* Is this an Encapsulation socket? */ -- unsigned char no_check6_tx:1,/* Send zero UDP6 checksums on TX? */ -- no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */ -- encap_enabled:1, /* This socket enabled encap -- * processing; UDP tunnels and -- * different encapsulation layer set -- * this -- */ -- gro_enabled:1, /* Request GRO aggregation */ -- accept_udp_l4:1, -- accept_udp_fraglist:1; -+ -+/* indicator bits used by pcflag: */ -+#define UDPLITE_BIT 0x1 /* set by udplite proto init function */ -+#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ -+#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */ -+ __u8 pcflag; /* marks socket as UDP-Lite if > 0 */ - /* - * Following member retains the information to create a UDP header - * when the socket is uncorked. -@@ -60,12 +68,6 @@ struct udp_sock { - */ - __u16 pcslen; - __u16 pcrlen; --/* indicator bits used by pcflag: */ --#define UDPLITE_BIT 0x1 /* set by udplite proto init function */ --#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ --#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */ -- __u8 pcflag; /* marks socket as UDP-Lite if > 0 */ -- __u8 unused[3]; - /* - * For encapsulation sockets. - */ -@@ -89,6 +91,17 @@ struct udp_sock { - int forward_deficit; - }; - -+#define udp_test_bit(nr, sk) \ -+ test_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) -+#define udp_set_bit(nr, sk) \ -+ set_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) -+#define udp_test_and_set_bit(nr, sk) \ -+ test_and_set_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) -+#define udp_clear_bit(nr, sk) \ -+ clear_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags) -+#define udp_assign_bit(nr, sk, val) \ -+ assign_bit(UDP_FLAGS_##nr, &udp_sk(sk)->udp_flags, val) -+ - #define UDP_MAX_SEGMENTS (1 << 6UL) - - static inline struct udp_sock *udp_sk(const struct sock *sk) -@@ -98,22 +111,22 @@ static inline struct udp_sock *udp_sk(const struct sock *sk) - - static inline void udp_set_no_check6_tx(struct sock *sk, bool val) - { -- udp_sk(sk)->no_check6_tx = val; -+ udp_assign_bit(NO_CHECK6_TX, sk, val); - } - - static inline void udp_set_no_check6_rx(struct sock *sk, bool val) - { -- udp_sk(sk)->no_check6_rx = val; -+ udp_assign_bit(NO_CHECK6_RX, sk, val); - } - --static inline bool udp_get_no_check6_tx(struct sock *sk) -+static inline bool udp_get_no_check6_tx(const struct sock *sk) - { -- return udp_sk(sk)->no_check6_tx; -+ return udp_test_bit(NO_CHECK6_TX, sk); - } - --static inline bool udp_get_no_check6_rx(struct sock *sk) -+static inline bool udp_get_no_check6_rx(const struct sock *sk) - { -- return udp_sk(sk)->no_check6_rx; -+ return udp_test_bit(NO_CHECK6_RX, sk); - } - - static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk, -@@ -132,10 +145,12 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) - if (!skb_is_gso(skb)) - return false; - -- if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && !udp_sk(sk)->accept_udp_l4) -+ if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && -+ !udp_test_bit(ACCEPT_L4, sk)) - return true; - -- if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && !udp_sk(sk)->accept_udp_fraglist) -+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST && -+ !udp_test_bit(ACCEPT_FRAGLIST, sk)) - return true; - - return false; -@@ -143,8 +158,8 @@ static inline bool udp_unexpected_gso(struct sock *sk, struct sk_buff *skb) - - static inline void udp_allow_gso(struct sock *sk) - { -- udp_sk(sk)->accept_udp_l4 = 1; -- udp_sk(sk)->accept_udp_fraglist = 1; -+ udp_set_bit(ACCEPT_L4, sk); -+ udp_set_bit(ACCEPT_FRAGLIST, sk); - } - - #define udp_portaddr_for_each_entry(__sk, list) \ -diff --git a/include/net/af_unix.h b/include/net/af_unix.h -index 480fa579787e5..55ca217c626b7 100644 ---- a/include/net/af_unix.h -+++ b/include/net/af_unix.h -@@ -77,6 +77,7 @@ static inline struct unix_sock *unix_sk(const struct sock *sk) - { - return (struct unix_sock *)sk; - } -+#define unix_peer(sk) (unix_sk(sk)->peer) - - #define peer_wait peer_wq.wait - -diff --git a/include/net/inet_common.h b/include/net/inet_common.h -index cec453c18f1d6..4673bbfd2811f 100644 ---- a/include/net/inet_common.h -+++ b/include/net/inet_common.h -@@ -33,6 +33,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags, - bool kern); - int inet_send_prepare(struct sock *sk); - int inet_sendmsg(struct socket *sock, struct msghdr *msg, size_t size); -+void inet_splice_eof(struct socket *sock); - ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, - size_t size, int flags); - int inet_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, -diff --git a/include/net/ip.h b/include/net/ip.h -index c286344628dba..c83c09c65623f 100644 ---- a/include/net/ip.h -+++ b/include/net/ip.h -@@ -95,7 +95,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm, - ipcm_init(ipcm); - - ipcm->sockc.mark = READ_ONCE(inet->sk.sk_mark); -- ipcm->sockc.tsflags = inet->sk.sk_tsflags; -+ ipcm->sockc.tsflags = READ_ONCE(inet->sk.sk_tsflags); - ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if); - ipcm->addr = inet->inet_saddr; - ipcm->protocol = inet->inet_num; -diff --git a/include/net/netfilter/nf_conntrack_act_ct.h b/include/net/netfilter/nf_conntrack_act_ct.h -index 078d3c52c03f9..e5f2f0b73a9a0 100644 ---- a/include/net/netfilter/nf_conntrack_act_ct.h -+++ b/include/net/netfilter/nf_conntrack_act_ct.h -@@ -20,7 +20,22 @@ static inline struct nf_conn_act_ct_ext *nf_conn_act_ct_ext_find(const struct nf - #endif - } - --static inline struct nf_conn_act_ct_ext *nf_conn_act_ct_ext_add(struct nf_conn *ct) -+static inline void nf_conn_act_ct_ext_fill(struct sk_buff *skb, struct nf_conn *ct, -+ enum ip_conntrack_info ctinfo) -+{ -+#if IS_ENABLED(CONFIG_NET_ACT_CT) -+ struct nf_conn_act_ct_ext *act_ct_ext; -+ -+ act_ct_ext = nf_conn_act_ct_ext_find(ct); -+ if (dev_net(skb->dev) == &init_net && act_ct_ext) -+ act_ct_ext->ifindex[CTINFO2DIR(ctinfo)] = skb->dev->ifindex; -+#endif -+} -+ -+static inline struct -+nf_conn_act_ct_ext *nf_conn_act_ct_ext_add(struct sk_buff *skb, -+ struct nf_conn *ct, -+ enum ip_conntrack_info ctinfo) - { - #if IS_ENABLED(CONFIG_NET_ACT_CT) - struct nf_conn_act_ct_ext *act_ct = nf_ct_ext_find(ct, NF_CT_EXT_ACT_CT); -@@ -29,22 +44,11 @@ static inline struct nf_conn_act_ct_ext *nf_conn_act_ct_ext_add(struct nf_conn * - return act_ct; - - act_ct = nf_ct_ext_add(ct, NF_CT_EXT_ACT_CT, GFP_ATOMIC); -+ nf_conn_act_ct_ext_fill(skb, ct, ctinfo); - return act_ct; - #else - return NULL; - #endif - } - --static inline void nf_conn_act_ct_ext_fill(struct sk_buff *skb, struct nf_conn *ct, -- enum ip_conntrack_info ctinfo) --{ --#if IS_ENABLED(CONFIG_NET_ACT_CT) -- struct nf_conn_act_ct_ext *act_ct_ext; -- -- act_ct_ext = nf_conn_act_ct_ext_find(ct); -- if (dev_net(skb->dev) == &init_net && act_ct_ext) -- act_ct_ext->ifindex[CTINFO2DIR(ctinfo)] = skb->dev->ifindex; --#endif --} -- - #endif /* _NF_CONNTRACK_ACT_CT_H */ -diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h -index cd982f4a0f50c..dde4dd9c4012c 100644 ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -53,14 +53,17 @@ struct nf_flowtable_type { - struct list_head list; - int family; - int (*init)(struct nf_flowtable *ft); -+ bool (*gc)(const struct flow_offload *flow); - int (*setup)(struct nf_flowtable *ft, - struct net_device *dev, - enum flow_block_command cmd); - int (*action)(struct net *net, -- const struct flow_offload *flow, -+ struct flow_offload *flow, - enum flow_offload_tuple_dir dir, - struct nf_flow_rule *flow_rule); - void (*free)(struct nf_flowtable *ft); -+ void (*get)(struct nf_flowtable *ft); -+ void (*put)(struct nf_flowtable *ft); - nf_hookfn *hook; - struct module *owner; - }; -@@ -164,6 +167,8 @@ enum nf_flow_flags { - NF_FLOW_HW_DYING, - NF_FLOW_HW_DEAD, - NF_FLOW_HW_PENDING, -+ NF_FLOW_HW_BIDIRECTIONAL, -+ NF_FLOW_HW_ESTABLISHED, - }; - - enum flow_offload_type { -@@ -237,6 +242,11 @@ nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table, - } - - list_add_tail(&block_cb->list, &block->cb_list); -+ up_write(&flow_table->flow_block_lock); -+ -+ if (flow_table->type->get) -+ flow_table->type->get(flow_table); -+ return 0; - - unlock: - up_write(&flow_table->flow_block_lock); -@@ -259,6 +269,9 @@ nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table, - WARN_ON(true); - } - up_write(&flow_table->flow_block_lock); -+ -+ if (flow_table->type->put) -+ flow_table->type->put(flow_table); - } - - int flow_offload_route_init(struct flow_offload *flow, -@@ -266,7 +279,7 @@ int flow_offload_route_init(struct flow_offload *flow, - - int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); - void flow_offload_refresh(struct nf_flowtable *flow_table, -- struct flow_offload *flow); -+ struct flow_offload *flow, bool force); - - struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, - struct flow_offload_tuple *tuple); -@@ -312,10 +325,10 @@ void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable); - int nf_flow_table_offload_setup(struct nf_flowtable *flowtable, - struct net_device *dev, - enum flow_block_command cmd); --int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow, -+int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow, - enum flow_offload_tuple_dir dir, - struct nf_flow_rule *flow_rule); --int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow, -+int nf_flow_rule_route_ipv6(struct net *net, struct flow_offload *flow, - enum flow_offload_tuple_dir dir, - struct nf_flow_rule *flow_rule); - -diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h -index c4a6147b0ef8c..5225d2bd1a6e9 100644 ---- a/include/net/netfilter/nf_tables_ipv4.h -+++ b/include/net/netfilter/nf_tables_ipv4.h -@@ -29,8 +29,8 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt) - if (iph->ihl < 5 || iph->version != 4) - return -1; - -- len = ntohs(iph->tot_len); -- thoff = iph->ihl * 4; -+ len = iph_totlen(pkt->skb, iph); -+ thoff = skb_network_offset(pkt->skb) + (iph->ihl * 4); - if (pkt->skb->len < len) - return -1; - else if (len < thoff) -@@ -62,7 +62,7 @@ static inline int nft_set_pktinfo_ipv4_ingress(struct nft_pktinfo *pkt) - if (iph->ihl < 5 || iph->version != 4) - goto inhdr_error; - -- len = ntohs(iph->tot_len); -+ len = iph_totlen(pkt->skb, iph); - thoff = iph->ihl * 4; - if (pkt->skb->len < len) { - __IP_INC_STATS(nft_net(pkt), IPSTATS_MIB_INTRUNCATEDPKTS); -diff --git a/include/net/sock.h b/include/net/sock.h -index b6027b01c2455..6b51e85ae69e3 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -1279,6 +1279,7 @@ struct proto { - size_t len, int flags, int *addr_len); - int (*sendpage)(struct sock *sk, struct page *page, - int offset, size_t size, int flags); -+ void (*splice_eof)(struct socket *sock); - int (*bind)(struct sock *sk, - struct sockaddr *addr, int addr_len); - int (*bind_add)(struct sock *sk, -@@ -1928,7 +1929,9 @@ struct sockcm_cookie { - static inline void sockcm_init(struct sockcm_cookie *sockc, - const struct sock *sk) - { -- *sockc = (struct sockcm_cookie) { .tsflags = sk->sk_tsflags }; -+ *sockc = (struct sockcm_cookie) { -+ .tsflags = READ_ONCE(sk->sk_tsflags) -+ }; - } - - int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg, -@@ -2741,9 +2744,9 @@ void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, - static inline void - sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) - { -- ktime_t kt = skb->tstamp; - struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); -- -+ u32 tsflags = READ_ONCE(sk->sk_tsflags); -+ ktime_t kt = skb->tstamp; - /* - * generate control messages if - * - receive time stamping in software requested -@@ -2751,10 +2754,10 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) - * - hardware time stamps available and wanted - */ - if (sock_flag(sk, SOCK_RCVTSTAMP) || -- (sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) || -- (kt && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) || -+ (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) || -+ (kt && tsflags & SOF_TIMESTAMPING_SOFTWARE) || - (hwtstamps->hwtstamp && -- (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE))) -+ (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE))) - __sock_recv_timestamp(msg, sk, skb); - else - sock_write_timestamp(sk, kt); -@@ -2776,7 +2779,8 @@ static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk, - #define TSFLAGS_ANY (SOF_TIMESTAMPING_SOFTWARE | \ - SOF_TIMESTAMPING_RAW_HARDWARE) - -- if (sk->sk_flags & FLAGS_RECV_CMSGS || sk->sk_tsflags & TSFLAGS_ANY) -+ if (sk->sk_flags & FLAGS_RECV_CMSGS || -+ READ_ONCE(sk->sk_tsflags) & TSFLAGS_ANY) - __sock_recv_cmsgs(msg, sk, skb); - else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP))) - sock_write_timestamp(sk, skb->tstamp); -@@ -2825,6 +2829,11 @@ static inline bool sk_is_tcp(const struct sock *sk) - return sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP; - } - -+static inline bool sk_is_stream_unix(const struct sock *sk) -+{ -+ return sk->sk_family == AF_UNIX && sk->sk_type == SOCK_STREAM; -+} -+ - /** - * sk_eat_skb - Release a skb if it is no longer needed - * @sk: socket to eat this skb from -diff --git a/include/net/tcp.h b/include/net/tcp.h -index c3d56b337f358..4c838f7290dd9 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -332,6 +332,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size); - int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size); - int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *copied, - size_t size, struct ubuf_info *uarg); -+void tcp_splice_eof(struct socket *sock); - int tcp_sendpage(struct sock *sk, struct page *page, int offset, size_t size, - int flags); - int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, -diff --git a/include/net/udp.h b/include/net/udp.h -index fee053bcd17c6..fa4cdbe55552c 100644 ---- a/include/net/udp.h -+++ b/include/net/udp.h -@@ -269,6 +269,7 @@ int udp_get_port(struct sock *sk, unsigned short snum, - int udp_err(struct sk_buff *, u32); - int udp_abort(struct sock *sk, int err); - int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); -+void udp_splice_eof(struct socket *sock); - int udp_push_pending_frames(struct sock *sk); - void udp_flush_pending_frames(struct sock *sk); - int udp_cmsg_send(struct sock *sk, struct msghdr *msg, u16 *gso_size); -diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h -index 72394f441dad8..e5f81710b18f4 100644 ---- a/include/net/udp_tunnel.h -+++ b/include/net/udp_tunnel.h -@@ -174,16 +174,13 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum) - } - #endif - --static inline void udp_tunnel_encap_enable(struct socket *sock) -+static inline void udp_tunnel_encap_enable(struct sock *sk) - { -- struct udp_sock *up = udp_sk(sock->sk); -- -- if (up->encap_enabled) -+ if (udp_test_and_set_bit(ENCAP_ENABLED, sk)) - return; - -- up->encap_enabled = 1; - #if IS_ENABLED(CONFIG_IPV6) -- if (sock->sk->sk_family == PF_INET6) -+ if (READ_ONCE(sk->sk_family) == PF_INET6) - ipv6_stub->udpv6_encap_enable(); - #endif - udp_encap_enable(); -diff --git a/io_uring/net.c b/io_uring/net.c -index 57c626cb4d1a5..67f09a40bcb21 100644 ---- a/io_uring/net.c -+++ b/io_uring/net.c -@@ -389,6 +389,7 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags) - if (flags & MSG_WAITALL) - min_ret = iov_iter_count(&msg.msg_iter); - -+ flags &= ~MSG_INTERNAL_SENDMSG_FLAGS; - msg.msg_flags = flags; - ret = sock_sendmsg(sock, &msg); - if (ret < min_ret) { -@@ -1137,6 +1138,7 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags) - msg_flags |= MSG_DONTWAIT; - if (msg_flags & MSG_WAITALL) - min_ret = iov_iter_count(&msg.msg_iter); -+ msg_flags &= ~MSG_INTERNAL_SENDMSG_FLAGS; - - msg.msg_flags = msg_flags; - msg.msg_ubuf = &io_notif_to_data(zc->notif)->uarg; -diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c -index 7225cb67c0d3a..76bf1de261152 100644 ---- a/kernel/bpf/core.c -+++ b/kernel/bpf/core.c -@@ -365,9 +365,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 = insn->off; -+ -+ if (insn->code == (BPF_JMP32 | BPF_JA)) { -+ off = insn->imm; -+ 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; -@@ -375,8 +384,12 @@ static int bpf_adj_delta_to_off(struct bpf_insn *insn, u32 pos, s32 end_old, - off -= delta; - if (off < off_min || off > off_max) - return -ERANGE; -- if (!probe_pass) -- insn->off = off; -+ if (!probe_pass) { -+ if (insn->code == (BPF_JMP32 | BPF_JA)) -+ insn->imm = off; -+ else -+ insn->off = off; -+ } - return 0; - } - -@@ -1586,6 +1599,7 @@ EXPORT_SYMBOL_GPL(__bpf_call_base); - INSN_3(JMP, JSLE, K), \ - INSN_3(JMP, JSET, K), \ - INSN_2(JMP, JA), \ -+ INSN_2(JMP32, JA), \ - /* Store instructions. */ \ - /* Register based. */ \ - INSN_3(STX, MEM, B), \ -@@ -1862,6 +1876,9 @@ out: - JMP_JA: - insn += insn->off; - CONT; -+ JMP32_JA: -+ insn += insn->imm; -+ CONT; - JMP_EXIT: - return BPF_R0; - /* JMP */ -diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c -index c4381dfcd6b09..748ac86169941 100644 ---- a/kernel/bpf/trampoline.c -+++ b/kernel/bpf/trampoline.c -@@ -443,8 +443,8 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut - goto out; - } - -- /* clear all bits except SHARE_IPMODIFY */ -- tr->flags &= BPF_TRAMP_F_SHARE_IPMODIFY; -+ /* clear all bits except SHARE_IPMODIFY and TAIL_CALL_CTX */ -+ tr->flags &= (BPF_TRAMP_F_SHARE_IPMODIFY | BPF_TRAMP_F_TAIL_CALL_CTX); - - if (tlinks[BPF_TRAMP_FEXIT].nr_links || - tlinks[BPF_TRAMP_MODIFY_RETURN].nr_links) { -diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c -index 12d360d80c149..142e10d49fd81 100644 ---- a/kernel/bpf/verifier.c -+++ b/kernel/bpf/verifier.c -@@ -2254,7 +2254,10 @@ static int check_subprogs(struct bpf_verifier_env *env) - goto next; - if (BPF_OP(code) == BPF_EXIT || BPF_OP(code) == BPF_CALL) - goto next; -- off = i + insn[i].off + 1; -+ if (code == (BPF_JMP32 | BPF_JA)) -+ off = i + insn[i].imm + 1; -+ else -+ off = i + insn[i].off + 1; - if (off < subprog_start || off >= subprog_end) { - verbose(env, "jump out of range from insn %d to %d\n", i, off); - return -EINVAL; -@@ -2266,6 +2269,7 @@ next: - * or unconditional jump back - */ - if (code != (BPF_JMP | BPF_EXIT) && -+ code != (BPF_JMP32 | BPF_JA) && - code != (BPF_JMP | BPF_JA)) { - verbose(env, "last insn is not an exit or jmp\n"); - return -EINVAL; -@@ -2512,6 +2516,16 @@ static int check_reg_arg(struct bpf_verifier_env *env, u32 regno, - return 0; - } - -+static void mark_jmp_point(struct bpf_verifier_env *env, int idx) -+{ -+ env->insn_aux_data[idx].jmp_point = true; -+} -+ -+static bool is_jmp_point(struct bpf_verifier_env *env, int insn_idx) -+{ -+ return env->insn_aux_data[insn_idx].jmp_point; -+} -+ - /* for any branch, call, exit record the history of jmps in the given state */ - static int push_jmp_history(struct bpf_verifier_env *env, - struct bpf_verifier_state *cur) -@@ -2520,6 +2534,9 @@ static int push_jmp_history(struct bpf_verifier_env *env, - struct bpf_idx_pair *p; - size_t alloc_size; - -+ if (!is_jmp_point(env, env->insn_idx)) -+ return 0; -+ - cnt++; - alloc_size = kmalloc_size_roundup(size_mul(cnt, sizeof(*p))); - p = krealloc(cur->jmp_history, alloc_size, GFP_USER); -@@ -2534,12 +2551,29 @@ static int push_jmp_history(struct bpf_verifier_env *env, - - /* Backtrack one insn at a time. If idx is not at the top of recorded - * history then previous instruction came from straight line execution. -+ * Return -ENOENT if we exhausted all instructions within given state. -+ * -+ * It's legal to have a bit of a looping with the same starting and ending -+ * insn index within the same state, e.g.: 3->4->5->3, so just because current -+ * instruction index is the same as state's first_idx doesn't mean we are -+ * done. If there is still some jump history left, we should keep going. We -+ * need to take into account that we might have a jump history between given -+ * state's parent and itself, due to checkpointing. In this case, we'll have -+ * history entry recording a jump from last instruction of parent state and -+ * first instruction of given state. - */ - static int get_prev_insn_idx(struct bpf_verifier_state *st, int i, - u32 *history) - { - u32 cnt = *history; - -+ if (i == st->first_insn_idx) { -+ if (cnt == 0) -+ return -ENOENT; -+ if (cnt == 1 && st->jmp_history[0].idx == i) -+ return -ENOENT; -+ } -+ - if (cnt && st->jmp_history[cnt - 1].idx == i) { - i = st->jmp_history[cnt - 1].prev_idx; - (*history)--; -@@ -3035,9 +3069,9 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int frame, int r - * Nothing to be tracked further in the parent state. - */ - return 0; -- if (i == first_idx) -- break; - i = get_prev_insn_idx(st, i, &history); -+ if (i == -ENOENT) -+ break; - if (i >= env->prog->len) { - /* This can happen if backtracking reached insn 0 - * and there are still reg_mask or stack_mask -@@ -11000,11 +11034,16 @@ static struct bpf_verifier_state_list **explored_state( - return &env->explored_states[(idx ^ state->callsite) % state_htab_size(env)]; - } - --static void init_explored_state(struct bpf_verifier_env *env, int idx) -+static void mark_prune_point(struct bpf_verifier_env *env, int idx) - { - env->insn_aux_data[idx].prune_point = true; - } - -+static bool is_prune_point(struct bpf_verifier_env *env, int insn_idx) -+{ -+ return env->insn_aux_data[insn_idx].prune_point; -+} -+ - enum { - DONE_EXPLORING = 0, - KEEP_EXPLORING = 1, -@@ -11033,9 +11072,11 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env, - return -EINVAL; - } - -- if (e == BRANCH) -+ if (e == BRANCH) { - /* mark branch target for state pruning */ -- init_explored_state(env, w); -+ mark_prune_point(env, w); -+ mark_jmp_point(env, w); -+ } - - if (insn_state[w] == 0) { - /* tree-edge */ -@@ -11062,21 +11103,23 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env, - return DONE_EXPLORING; - } - --static int visit_func_call_insn(int t, int insn_cnt, -- struct bpf_insn *insns, -+static int visit_func_call_insn(int t, struct bpf_insn *insns, - struct bpf_verifier_env *env, - bool visit_callee) - { -- int ret; -+ int ret, insn_sz; - -- ret = push_insn(t, t + 1, FALLTHROUGH, env, false); -+ insn_sz = bpf_is_ldimm64(&insns[t]) ? 2 : 1; -+ ret = push_insn(t, t + insn_sz, FALLTHROUGH, env, false); - if (ret) - return ret; - -- if (t + 1 < insn_cnt) -- init_explored_state(env, t + 1); -+ mark_prune_point(env, t + insn_sz); -+ /* when we exit from subprog, we need to record non-linear history */ -+ mark_jmp_point(env, t + insn_sz); -+ - if (visit_callee) { -- init_explored_state(env, t); -+ mark_prune_point(env, t); - ret = push_insn(t, t + insns[t].imm + 1, BRANCH, env, - /* It's ok to allow recursion from CFG point of - * view. __check_func_call() will do the actual -@@ -11092,65 +11135,64 @@ static int visit_func_call_insn(int t, int insn_cnt, - * DONE_EXPLORING - the instruction was fully explored - * KEEP_EXPLORING - there is still work to be done before it is fully explored - */ --static int visit_insn(int t, int insn_cnt, struct bpf_verifier_env *env) -+static int visit_insn(int t, struct bpf_verifier_env *env) - { -- struct bpf_insn *insns = env->prog->insnsi; -- int ret; -+ struct bpf_insn *insns = env->prog->insnsi, *insn = &insns[t]; -+ int ret, off, insn_sz; - -- if (bpf_pseudo_func(insns + t)) -- return visit_func_call_insn(t, insn_cnt, insns, env, true); -+ if (bpf_pseudo_func(insn)) -+ return visit_func_call_insn(t, insns, env, true); - - /* All non-branch instructions have a single fall-through edge. */ -- if (BPF_CLASS(insns[t].code) != BPF_JMP && -- BPF_CLASS(insns[t].code) != BPF_JMP32) -- return push_insn(t, t + 1, FALLTHROUGH, env, false); -+ if (BPF_CLASS(insn->code) != BPF_JMP && -+ BPF_CLASS(insn->code) != BPF_JMP32) { -+ insn_sz = bpf_is_ldimm64(insn) ? 2 : 1; -+ return push_insn(t, t + insn_sz, FALLTHROUGH, env, false); -+ } - -- switch (BPF_OP(insns[t].code)) { -+ switch (BPF_OP(insn->code)) { - case BPF_EXIT: - return DONE_EXPLORING; - - case BPF_CALL: -- if (insns[t].imm == BPF_FUNC_timer_set_callback) -- /* Mark this call insn to trigger is_state_visited() check -- * before call itself is processed by __check_func_call(). -- * Otherwise new async state will be pushed for further -- * exploration. -+ if (insn->imm == BPF_FUNC_timer_set_callback) -+ /* Mark this call insn as a prune point to trigger -+ * is_state_visited() check before call itself is -+ * processed by __check_func_call(). Otherwise new -+ * async state will be pushed for further exploration. - */ -- init_explored_state(env, t); -- return visit_func_call_insn(t, insn_cnt, insns, env, -- insns[t].src_reg == BPF_PSEUDO_CALL); -+ mark_prune_point(env, t); -+ return visit_func_call_insn(t, insns, env, insn->src_reg == BPF_PSEUDO_CALL); - - case BPF_JA: -- if (BPF_SRC(insns[t].code) != BPF_K) -+ if (BPF_SRC(insn->code) != BPF_K) - return -EINVAL; - -+ if (BPF_CLASS(insn->code) == BPF_JMP) -+ off = insn->off; -+ else -+ off = insn->imm; -+ - /* unconditional jump with single edge */ -- ret = push_insn(t, t + insns[t].off + 1, FALLTHROUGH, env, -+ ret = push_insn(t, t + off + 1, FALLTHROUGH, env, - true); - if (ret) - return ret; - -- /* unconditional jmp is not a good pruning point, -- * but it's marked, since backtracking needs -- * to record jmp history in is_state_visited(). -- */ -- init_explored_state(env, t + insns[t].off + 1); -- /* tell verifier to check for equivalent states -- * after every call and jump -- */ -- if (t + 1 < insn_cnt) -- init_explored_state(env, t + 1); -+ mark_prune_point(env, t + off + 1); -+ mark_jmp_point(env, t + off + 1); - - return ret; - - default: - /* conditional jump with two edges */ -- init_explored_state(env, t); -+ mark_prune_point(env, t); -+ - ret = push_insn(t, t + 1, FALLTHROUGH, env, true); - if (ret) - return ret; - -- return push_insn(t, t + insns[t].off + 1, BRANCH, env, true); -+ return push_insn(t, t + insn->off + 1, BRANCH, env, true); - } - } - -@@ -11181,7 +11223,7 @@ static int check_cfg(struct bpf_verifier_env *env) - while (env->cfg.cur_stack > 0) { - int t = insn_stack[env->cfg.cur_stack - 1]; - -- ret = visit_insn(t, insn_cnt, env); -+ ret = visit_insn(t, env); - switch (ret) { - case DONE_EXPLORING: - insn_state[t] = EXPLORED; -@@ -11205,11 +11247,21 @@ static int check_cfg(struct bpf_verifier_env *env) - } - - for (i = 0; i < insn_cnt; i++) { -+ struct bpf_insn *insn = &env->prog->insnsi[i]; -+ - if (insn_state[i] != EXPLORED) { - verbose(env, "unreachable insn %d\n", i); - ret = -EINVAL; - goto err_free; - } -+ if (bpf_is_ldimm64(insn)) { -+ if (insn_state[i + 1] != 0) { -+ verbose(env, "jump into the middle of ldimm64 insn %d\n", i); -+ ret = -EINVAL; -+ goto err_free; -+ } -+ i++; /* skip second half of ldimm64 */ -+ } - } - ret = 0; /* cfg looks good */ - -@@ -12178,11 +12230,11 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) - bool add_new_state = env->test_state_freq ? true : false; - - cur->last_insn_idx = env->prev_insn_idx; -- if (!env->insn_aux_data[insn_idx].prune_point) -+ if (!is_prune_point(env, insn_idx)) - /* this 'insn_idx' instruction wasn't marked, so we will not - * be doing state search here - */ -- return 0; -+ return push_jmp_history(env, cur); - - /* bpf progs typically have pruning point every 4 instructions - * http://vger.kernel.org/bpfconf2019.html#session-1 -@@ -12674,15 +12726,18 @@ static int do_check(struct bpf_verifier_env *env) - return err; - } else if (opcode == BPF_JA) { - if (BPF_SRC(insn->code) != BPF_K || -- insn->imm != 0 || - insn->src_reg != BPF_REG_0 || - insn->dst_reg != BPF_REG_0 || -- class == BPF_JMP32) { -+ (class == BPF_JMP && insn->imm != 0) || -+ (class == BPF_JMP32 && insn->off != 0)) { - verbose(env, "BPF_JA uses reserved fields\n"); - return -EINVAL; - } - -- env->insn_idx += insn->off + 1; -+ if (class == BPF_JMP) -+ env->insn_idx += insn->off + 1; -+ else -+ env->insn_idx += insn->imm + 1; - continue; - - } else if (opcode == BPF_EXIT) { -@@ -13508,13 +13563,13 @@ static bool insn_is_cond_jump(u8 code) - { - u8 op; - -+ op = BPF_OP(code); - if (BPF_CLASS(code) == BPF_JMP32) -- return true; -+ return op != BPF_JA; - - if (BPF_CLASS(code) != BPF_JMP) - return false; - -- op = BPF_OP(code); - return op != BPF_JA && op != BPF_EXIT && op != BPF_CALL; - } - -@@ -15442,6 +15497,9 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) - if (!tr) - return -ENOMEM; - -+ if (tgt_prog && tgt_prog->aux->tail_call_reachable) -+ tr->flags = BPF_TRAMP_F_TAIL_CALL_CTX; -+ - prog->aux->dst_trampoline = tr; - return 0; - } -diff --git a/kernel/cpu.c b/kernel/cpu.c -index 551468d9c5a85..e6f0101941ed8 100644 ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -446,9 +446,31 @@ static int __init smt_cmdline_disable(char *str) - } - early_param("nosmt", smt_cmdline_disable); - --static inline bool cpu_smt_allowed(unsigned int cpu) -+/* -+ * For Archicture supporting partial SMT states check if the thread is allowed. -+ * Otherwise this has already been checked through cpu_smt_max_threads when -+ * setting the SMT level. -+ */ -+static inline bool cpu_smt_thread_allowed(unsigned int cpu) - { -- if (cpu_smt_control == CPU_SMT_ENABLED) -+#ifdef CONFIG_SMT_NUM_THREADS_DYNAMIC -+ return topology_smt_thread_allowed(cpu); -+#else -+ return true; -+#endif -+} -+ -+static inline bool cpu_bootable(unsigned int cpu) -+{ -+ if (cpu_smt_control == CPU_SMT_ENABLED && cpu_smt_thread_allowed(cpu)) -+ return true; -+ -+ /* All CPUs are bootable if controls are not configured */ -+ if (cpu_smt_control == CPU_SMT_NOT_IMPLEMENTED) -+ return true; -+ -+ /* All CPUs are bootable if CPU is not SMT capable */ -+ if (cpu_smt_control == CPU_SMT_NOT_SUPPORTED) - return true; - - if (topology_is_primary_thread(cpu)) -@@ -471,7 +493,7 @@ bool cpu_smt_possible(void) - } - EXPORT_SYMBOL_GPL(cpu_smt_possible); - #else --static inline bool cpu_smt_allowed(unsigned int cpu) { return true; } -+static inline bool cpu_bootable(unsigned int cpu) { return true; } - #endif - - static inline enum cpuhp_state -@@ -574,10 +596,10 @@ static int bringup_wait_for_ap(unsigned int cpu) - * SMT soft disabling on X86 requires to bring the CPU out of the - * BIOS 'wait for SIPI' state in order to set the CR4.MCE bit. The - * CPU marked itself as booted_once in notify_cpu_starting() so the -- * cpu_smt_allowed() check will now return false if this is not the -+ * cpu_bootable() check will now return false if this is not the - * primary sibling. - */ -- if (!cpu_smt_allowed(cpu)) -+ if (!cpu_bootable(cpu)) - return -ECANCELED; - - if (st->target <= CPUHP_AP_ONLINE_IDLE) -@@ -1464,7 +1486,7 @@ static int cpu_up(unsigned int cpu, enum cpuhp_state target) - err = -EBUSY; - goto out; - } -- if (!cpu_smt_allowed(cpu)) { -+ if (!cpu_bootable(cpu)) { - err = -EPERM; - goto out; - } -@@ -2294,6 +2316,12 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) - for_each_online_cpu(cpu) { - if (topology_is_primary_thread(cpu)) - continue; -+ /* -+ * Disable can be called with CPU_SMT_ENABLED when changing -+ * from a higher to lower number of SMT threads per core. -+ */ -+ if (ctrlval == CPU_SMT_ENABLED && cpu_smt_thread_allowed(cpu)) -+ continue; - ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE); - if (ret) - break; -@@ -2328,6 +2356,8 @@ int cpuhp_smt_enable(void) - /* Skip online CPUs and CPUs on offline nodes */ - if (cpu_online(cpu) || !node_online(cpu_to_node(cpu))) - continue; -+ if (!cpu_smt_thread_allowed(cpu)) -+ continue; - ret = _cpu_up(cpu, 0, CPUHP_ONLINE); - if (ret) - break; -diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c -index d9a5c1d65a79d..44a4eba80315c 100644 ---- a/kernel/irq/affinity.c -+++ b/kernel/irq/affinity.c -@@ -7,398 +7,7 @@ - #include - #include - #include --#include -- --static void irq_spread_init_one(struct cpumask *irqmsk, struct cpumask *nmsk, -- unsigned int cpus_per_vec) --{ -- const struct cpumask *siblmsk; -- int cpu, sibl; -- -- for ( ; cpus_per_vec > 0; ) { -- cpu = cpumask_first(nmsk); -- -- /* Should not happen, but I'm too lazy to think about it */ -- if (cpu >= nr_cpu_ids) -- return; -- -- cpumask_clear_cpu(cpu, nmsk); -- cpumask_set_cpu(cpu, irqmsk); -- cpus_per_vec--; -- -- /* If the cpu has siblings, use them first */ -- siblmsk = topology_sibling_cpumask(cpu); -- for (sibl = -1; cpus_per_vec > 0; ) { -- sibl = cpumask_next(sibl, siblmsk); -- if (sibl >= nr_cpu_ids) -- break; -- if (!cpumask_test_and_clear_cpu(sibl, nmsk)) -- continue; -- cpumask_set_cpu(sibl, irqmsk); -- cpus_per_vec--; -- } -- } --} -- --static cpumask_var_t *alloc_node_to_cpumask(void) --{ -- cpumask_var_t *masks; -- int node; -- -- masks = kcalloc(nr_node_ids, sizeof(cpumask_var_t), GFP_KERNEL); -- if (!masks) -- return NULL; -- -- for (node = 0; node < nr_node_ids; node++) { -- if (!zalloc_cpumask_var(&masks[node], GFP_KERNEL)) -- goto out_unwind; -- } -- -- return masks; -- --out_unwind: -- while (--node >= 0) -- free_cpumask_var(masks[node]); -- kfree(masks); -- return NULL; --} -- --static void free_node_to_cpumask(cpumask_var_t *masks) --{ -- int node; -- -- for (node = 0; node < nr_node_ids; node++) -- free_cpumask_var(masks[node]); -- kfree(masks); --} -- --static void build_node_to_cpumask(cpumask_var_t *masks) --{ -- int cpu; -- -- for_each_possible_cpu(cpu) -- cpumask_set_cpu(cpu, masks[cpu_to_node(cpu)]); --} -- --static int get_nodes_in_cpumask(cpumask_var_t *node_to_cpumask, -- const struct cpumask *mask, nodemask_t *nodemsk) --{ -- int n, nodes = 0; -- -- /* Calculate the number of nodes in the supplied affinity mask */ -- for_each_node(n) { -- if (cpumask_intersects(mask, node_to_cpumask[n])) { -- node_set(n, *nodemsk); -- nodes++; -- } -- } -- return nodes; --} -- --struct node_vectors { -- unsigned id; -- -- union { -- unsigned nvectors; -- unsigned ncpus; -- }; --}; -- --static int ncpus_cmp_func(const void *l, const void *r) --{ -- const struct node_vectors *ln = l; -- const struct node_vectors *rn = r; -- -- return ln->ncpus - rn->ncpus; --} -- --/* -- * Allocate vector number for each node, so that for each node: -- * -- * 1) the allocated number is >= 1 -- * -- * 2) the allocated numbver is <= active CPU number of this node -- * -- * The actual allocated total vectors may be less than @numvecs when -- * active total CPU number is less than @numvecs. -- * -- * Active CPUs means the CPUs in '@cpu_mask AND @node_to_cpumask[]' -- * for each node. -- */ --static void alloc_nodes_vectors(unsigned int numvecs, -- cpumask_var_t *node_to_cpumask, -- const struct cpumask *cpu_mask, -- const nodemask_t nodemsk, -- struct cpumask *nmsk, -- struct node_vectors *node_vectors) --{ -- unsigned n, remaining_ncpus = 0; -- -- for (n = 0; n < nr_node_ids; n++) { -- node_vectors[n].id = n; -- node_vectors[n].ncpus = UINT_MAX; -- } -- -- for_each_node_mask(n, nodemsk) { -- unsigned ncpus; -- -- cpumask_and(nmsk, cpu_mask, node_to_cpumask[n]); -- ncpus = cpumask_weight(nmsk); -- -- if (!ncpus) -- continue; -- remaining_ncpus += ncpus; -- node_vectors[n].ncpus = ncpus; -- } -- -- numvecs = min_t(unsigned, remaining_ncpus, numvecs); -- -- sort(node_vectors, nr_node_ids, sizeof(node_vectors[0]), -- ncpus_cmp_func, NULL); -- -- /* -- * Allocate vectors for each node according to the ratio of this -- * node's nr_cpus to remaining un-assigned ncpus. 'numvecs' is -- * bigger than number of active numa nodes. Always start the -- * allocation from the node with minimized nr_cpus. -- * -- * This way guarantees that each active node gets allocated at -- * least one vector, and the theory is simple: over-allocation -- * is only done when this node is assigned by one vector, so -- * other nodes will be allocated >= 1 vector, since 'numvecs' is -- * bigger than number of numa nodes. -- * -- * One perfect invariant is that number of allocated vectors for -- * each node is <= CPU count of this node: -- * -- * 1) suppose there are two nodes: A and B -- * ncpu(X) is CPU count of node X -- * vecs(X) is the vector count allocated to node X via this -- * algorithm -- * -- * ncpu(A) <= ncpu(B) -- * ncpu(A) + ncpu(B) = N -- * vecs(A) + vecs(B) = V -- * -- * vecs(A) = max(1, round_down(V * ncpu(A) / N)) -- * vecs(B) = V - vecs(A) -- * -- * both N and V are integer, and 2 <= V <= N, suppose -- * V = N - delta, and 0 <= delta <= N - 2 -- * -- * 2) obviously vecs(A) <= ncpu(A) because: -- * -- * if vecs(A) is 1, then vecs(A) <= ncpu(A) given -- * ncpu(A) >= 1 -- * -- * otherwise, -- * vecs(A) <= V * ncpu(A) / N <= ncpu(A), given V <= N -- * -- * 3) prove how vecs(B) <= ncpu(B): -- * -- * if round_down(V * ncpu(A) / N) == 0, vecs(B) won't be -- * over-allocated, so vecs(B) <= ncpu(B), -- * -- * otherwise: -- * -- * vecs(A) = -- * round_down(V * ncpu(A) / N) = -- * round_down((N - delta) * ncpu(A) / N) = -- * round_down((N * ncpu(A) - delta * ncpu(A)) / N) >= -- * round_down((N * ncpu(A) - delta * N) / N) = -- * cpu(A) - delta -- * -- * then: -- * -- * vecs(A) - V >= ncpu(A) - delta - V -- * => -- * V - vecs(A) <= V + delta - ncpu(A) -- * => -- * vecs(B) <= N - ncpu(A) -- * => -- * vecs(B) <= cpu(B) -- * -- * For nodes >= 3, it can be thought as one node and another big -- * node given that is exactly what this algorithm is implemented, -- * and we always re-calculate 'remaining_ncpus' & 'numvecs', and -- * finally for each node X: vecs(X) <= ncpu(X). -- * -- */ -- for (n = 0; n < nr_node_ids; n++) { -- unsigned nvectors, ncpus; -- -- if (node_vectors[n].ncpus == UINT_MAX) -- continue; -- -- WARN_ON_ONCE(numvecs == 0); -- -- ncpus = node_vectors[n].ncpus; -- nvectors = max_t(unsigned, 1, -- numvecs * ncpus / remaining_ncpus); -- WARN_ON_ONCE(nvectors > ncpus); -- -- node_vectors[n].nvectors = nvectors; -- -- remaining_ncpus -= ncpus; -- numvecs -= nvectors; -- } --} -- --static int __irq_build_affinity_masks(unsigned int startvec, -- unsigned int numvecs, -- unsigned int firstvec, -- cpumask_var_t *node_to_cpumask, -- const struct cpumask *cpu_mask, -- struct cpumask *nmsk, -- struct irq_affinity_desc *masks) --{ -- unsigned int i, n, nodes, cpus_per_vec, extra_vecs, done = 0; -- unsigned int last_affv = firstvec + numvecs; -- unsigned int curvec = startvec; -- nodemask_t nodemsk = NODE_MASK_NONE; -- struct node_vectors *node_vectors; -- -- if (cpumask_empty(cpu_mask)) -- return 0; -- -- nodes = get_nodes_in_cpumask(node_to_cpumask, cpu_mask, &nodemsk); -- -- /* -- * If the number of nodes in the mask is greater than or equal the -- * number of vectors we just spread the vectors across the nodes. -- */ -- if (numvecs <= nodes) { -- for_each_node_mask(n, nodemsk) { -- /* Ensure that only CPUs which are in both masks are set */ -- cpumask_and(nmsk, cpu_mask, node_to_cpumask[n]); -- cpumask_or(&masks[curvec].mask, &masks[curvec].mask, nmsk); -- if (++curvec == last_affv) -- curvec = firstvec; -- } -- return numvecs; -- } -- -- node_vectors = kcalloc(nr_node_ids, -- sizeof(struct node_vectors), -- GFP_KERNEL); -- if (!node_vectors) -- return -ENOMEM; -- -- /* allocate vector number for each node */ -- alloc_nodes_vectors(numvecs, node_to_cpumask, cpu_mask, -- nodemsk, nmsk, node_vectors); -- -- for (i = 0; i < nr_node_ids; i++) { -- unsigned int ncpus, v; -- struct node_vectors *nv = &node_vectors[i]; -- -- if (nv->nvectors == UINT_MAX) -- continue; -- -- /* Get the cpus on this node which are in the mask */ -- cpumask_and(nmsk, cpu_mask, node_to_cpumask[nv->id]); -- ncpus = cpumask_weight(nmsk); -- if (!ncpus) -- continue; -- -- WARN_ON_ONCE(nv->nvectors > ncpus); -- -- /* Account for rounding errors */ -- extra_vecs = ncpus - nv->nvectors * (ncpus / nv->nvectors); -- -- /* Spread allocated vectors on CPUs of the current node */ -- for (v = 0; v < nv->nvectors; v++, curvec++) { -- cpus_per_vec = ncpus / nv->nvectors; -- -- /* Account for extra vectors to compensate rounding errors */ -- if (extra_vecs) { -- cpus_per_vec++; -- --extra_vecs; -- } -- -- /* -- * wrapping has to be considered given 'startvec' -- * may start anywhere -- */ -- if (curvec >= last_affv) -- curvec = firstvec; -- irq_spread_init_one(&masks[curvec].mask, nmsk, -- cpus_per_vec); -- } -- done += nv->nvectors; -- } -- kfree(node_vectors); -- return done; --} -- --/* -- * build affinity in two stages: -- * 1) spread present CPU on these vectors -- * 2) spread other possible CPUs on these vectors -- */ --static int irq_build_affinity_masks(unsigned int startvec, unsigned int numvecs, -- unsigned int firstvec, -- struct irq_affinity_desc *masks) --{ -- unsigned int curvec = startvec, nr_present = 0, nr_others = 0; -- cpumask_var_t *node_to_cpumask; -- cpumask_var_t nmsk, npresmsk; -- int ret = -ENOMEM; -- -- if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL)) -- return ret; -- -- if (!zalloc_cpumask_var(&npresmsk, GFP_KERNEL)) -- goto fail_nmsk; -- -- node_to_cpumask = alloc_node_to_cpumask(); -- if (!node_to_cpumask) -- goto fail_npresmsk; -- -- /* Stabilize the cpumasks */ -- cpus_read_lock(); -- build_node_to_cpumask(node_to_cpumask); -- -- /* Spread on present CPUs starting from affd->pre_vectors */ -- ret = __irq_build_affinity_masks(curvec, numvecs, firstvec, -- node_to_cpumask, cpu_present_mask, -- nmsk, masks); -- if (ret < 0) -- goto fail_build_affinity; -- nr_present = ret; -- -- /* -- * Spread on non present CPUs starting from the next vector to be -- * handled. If the spreading of present CPUs already exhausted the -- * vector space, assign the non present CPUs to the already spread -- * out vectors. -- */ -- if (nr_present >= numvecs) -- curvec = firstvec; -- else -- curvec = firstvec + nr_present; -- cpumask_andnot(npresmsk, cpu_possible_mask, cpu_present_mask); -- ret = __irq_build_affinity_masks(curvec, numvecs, firstvec, -- 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 < numvecs); -- -- free_node_to_cpumask(node_to_cpumask); -- -- fail_npresmsk: -- free_cpumask_var(npresmsk); -- -- fail_nmsk: -- free_cpumask_var(nmsk); -- return ret < 0 ? ret : 0; --} -+#include - - static void default_calc_sets(struct irq_affinity *affd, unsigned int affvecs) - { -@@ -461,14 +70,18 @@ irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd) - */ - for (i = 0, usedvecs = 0; i < affd->nr_sets; i++) { - unsigned int this_vecs = affd->set_size[i]; -- int ret; -+ int j; -+ struct cpumask *result = group_cpus_evenly(this_vecs); - -- ret = irq_build_affinity_masks(curvec, this_vecs, -- curvec, masks); -- if (ret) { -+ if (!result) { - kfree(masks); - return NULL; - } -+ -+ for (j = 0; j < this_vecs; j++) -+ cpumask_copy(&masks[curvec + j].mask, &result[j]); -+ kfree(result); -+ - curvec += this_vecs; - usedvecs += this_vecs; - } -diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c -index 8fdf076720384..929dcbc04d29c 100644 ---- a/kernel/rcu/srcutree.c -+++ b/kernel/rcu/srcutree.c -@@ -1100,10 +1100,37 @@ static unsigned long srcu_gp_start_if_needed(struct srcu_struct *ssp, - spin_lock_irqsave_sdp_contention(sdp, &flags); - if (rhp) - rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp); -+ /* -+ * The snapshot for acceleration must be taken _before_ the read of the -+ * current gp sequence used for advancing, otherwise advancing may fail -+ * and acceleration may then fail too. -+ * -+ * This could happen if: -+ * -+ * 1) The RCU_WAIT_TAIL segment has callbacks (gp_num = X + 4) and the -+ * RCU_NEXT_READY_TAIL also has callbacks (gp_num = X + 8). -+ * -+ * 2) The grace period for RCU_WAIT_TAIL is seen as started but not -+ * completed so rcu_seq_current() returns X + SRCU_STATE_SCAN1. -+ * -+ * 3) This value is passed to rcu_segcblist_advance() which can't move -+ * any segment forward and fails. -+ * -+ * 4) srcu_gp_start_if_needed() still proceeds with callback acceleration. -+ * But then the call to rcu_seq_snap() observes the grace period for the -+ * RCU_WAIT_TAIL segment as completed and the subsequent one for the -+ * RCU_NEXT_READY_TAIL segment as started (ie: X + 4 + SRCU_STATE_SCAN1) -+ * so it returns a snapshot of the next grace period, which is X + 12. -+ * -+ * 5) The value of X + 12 is passed to rcu_segcblist_accelerate() but the -+ * freshly enqueued callback in RCU_NEXT_TAIL can't move to -+ * RCU_NEXT_READY_TAIL which already has callbacks for a previous grace -+ * period (gp_num = X + 8). So acceleration fails. -+ */ -+ s = rcu_seq_snap(&ssp->srcu_gp_seq); - rcu_segcblist_advance(&sdp->srcu_cblist, - rcu_seq_current(&ssp->srcu_gp_seq)); -- s = rcu_seq_snap(&ssp->srcu_gp_seq); -- (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, s); -+ WARN_ON_ONCE(!rcu_segcblist_accelerate(&sdp->srcu_cblist, s) && rhp); - if (ULONG_CMP_LT(sdp->srcu_gp_seq_needed, s)) { - sdp->srcu_gp_seq_needed = s; - needgp = true; -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index 06d52525407b8..71cad4f1323c6 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -646,8 +646,8 @@ static inline bool __rb_time_read(rb_time_t *t, u64 *ret, unsigned long *cnt) - - *cnt = rb_time_cnt(top); - -- /* If top and msb counts don't match, this interrupted a write */ -- if (*cnt != rb_time_cnt(msb)) -+ /* If top, msb or bottom counts don't match, this interrupted a write */ -+ if (*cnt != rb_time_cnt(msb) || *cnt != rb_time_cnt(bottom)) - return false; - - /* The shift to msb will lose its cnt bits */ -diff --git a/lib/Makefile b/lib/Makefile -index 5ffe72ec99797..6f1611d053e6a 100644 ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -361,6 +361,8 @@ obj-$(CONFIG_SBITMAP) += sbitmap.o - - obj-$(CONFIG_PARMAN) += parman.o - -+obj-y += group_cpus.o -+ - # GCC library routines - obj-$(CONFIG_GENERIC_LIB_ASHLDI3) += ashldi3.o - obj-$(CONFIG_GENERIC_LIB_ASHRDI3) += ashrdi3.o -diff --git a/lib/group_cpus.c b/lib/group_cpus.c -new file mode 100644 -index 0000000000000..0292611901b8b ---- /dev/null -+++ b/lib/group_cpus.c -@@ -0,0 +1,438 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2016 Thomas Gleixner. -+ * Copyright (C) 2016-2017 Christoph Hellwig. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_SMP -+ -+static void grp_spread_init_one(struct cpumask *irqmsk, struct cpumask *nmsk, -+ unsigned int cpus_per_grp) -+{ -+ const struct cpumask *siblmsk; -+ int cpu, sibl; -+ -+ for ( ; cpus_per_grp > 0; ) { -+ cpu = cpumask_first(nmsk); -+ -+ /* Should not happen, but I'm too lazy to think about it */ -+ if (cpu >= nr_cpu_ids) -+ return; -+ -+ cpumask_clear_cpu(cpu, nmsk); -+ cpumask_set_cpu(cpu, irqmsk); -+ cpus_per_grp--; -+ -+ /* If the cpu has siblings, use them first */ -+ siblmsk = topology_sibling_cpumask(cpu); -+ for (sibl = -1; cpus_per_grp > 0; ) { -+ sibl = cpumask_next(sibl, siblmsk); -+ if (sibl >= nr_cpu_ids) -+ break; -+ if (!cpumask_test_and_clear_cpu(sibl, nmsk)) -+ continue; -+ cpumask_set_cpu(sibl, irqmsk); -+ cpus_per_grp--; -+ } -+ } -+} -+ -+static cpumask_var_t *alloc_node_to_cpumask(void) -+{ -+ cpumask_var_t *masks; -+ int node; -+ -+ masks = kcalloc(nr_node_ids, sizeof(cpumask_var_t), GFP_KERNEL); -+ if (!masks) -+ return NULL; -+ -+ for (node = 0; node < nr_node_ids; node++) { -+ if (!zalloc_cpumask_var(&masks[node], GFP_KERNEL)) -+ goto out_unwind; -+ } -+ -+ return masks; -+ -+out_unwind: -+ while (--node >= 0) -+ free_cpumask_var(masks[node]); -+ kfree(masks); -+ return NULL; -+} -+ -+static void free_node_to_cpumask(cpumask_var_t *masks) -+{ -+ int node; -+ -+ for (node = 0; node < nr_node_ids; node++) -+ free_cpumask_var(masks[node]); -+ kfree(masks); -+} -+ -+static void build_node_to_cpumask(cpumask_var_t *masks) -+{ -+ int cpu; -+ -+ for_each_possible_cpu(cpu) -+ cpumask_set_cpu(cpu, masks[cpu_to_node(cpu)]); -+} -+ -+static int get_nodes_in_cpumask(cpumask_var_t *node_to_cpumask, -+ const struct cpumask *mask, nodemask_t *nodemsk) -+{ -+ int n, nodes = 0; -+ -+ /* Calculate the number of nodes in the supplied affinity mask */ -+ for_each_node(n) { -+ if (cpumask_intersects(mask, node_to_cpumask[n])) { -+ node_set(n, *nodemsk); -+ nodes++; -+ } -+ } -+ return nodes; -+} -+ -+struct node_groups { -+ unsigned id; -+ -+ union { -+ unsigned ngroups; -+ unsigned ncpus; -+ }; -+}; -+ -+static int ncpus_cmp_func(const void *l, const void *r) -+{ -+ const struct node_groups *ln = l; -+ const struct node_groups *rn = r; -+ -+ return ln->ncpus - rn->ncpus; -+} -+ -+/* -+ * Allocate group number for each node, so that for each node: -+ * -+ * 1) the allocated number is >= 1 -+ * -+ * 2) the allocated number is <= active CPU number of this node -+ * -+ * The actual allocated total groups may be less than @numgrps when -+ * active total CPU number is less than @numgrps. -+ * -+ * Active CPUs means the CPUs in '@cpu_mask AND @node_to_cpumask[]' -+ * for each node. -+ */ -+static void alloc_nodes_groups(unsigned int numgrps, -+ cpumask_var_t *node_to_cpumask, -+ const struct cpumask *cpu_mask, -+ const nodemask_t nodemsk, -+ struct cpumask *nmsk, -+ struct node_groups *node_groups) -+{ -+ unsigned n, remaining_ncpus = 0; -+ -+ for (n = 0; n < nr_node_ids; n++) { -+ node_groups[n].id = n; -+ node_groups[n].ncpus = UINT_MAX; -+ } -+ -+ for_each_node_mask(n, nodemsk) { -+ unsigned ncpus; -+ -+ cpumask_and(nmsk, cpu_mask, node_to_cpumask[n]); -+ ncpus = cpumask_weight(nmsk); -+ -+ if (!ncpus) -+ continue; -+ remaining_ncpus += ncpus; -+ node_groups[n].ncpus = ncpus; -+ } -+ -+ numgrps = min_t(unsigned, remaining_ncpus, numgrps); -+ -+ sort(node_groups, nr_node_ids, sizeof(node_groups[0]), -+ ncpus_cmp_func, NULL); -+ -+ /* -+ * Allocate groups for each node according to the ratio of this -+ * node's nr_cpus to remaining un-assigned ncpus. 'numgrps' is -+ * bigger than number of active numa nodes. Always start the -+ * allocation from the node with minimized nr_cpus. -+ * -+ * This way guarantees that each active node gets allocated at -+ * least one group, and the theory is simple: over-allocation -+ * is only done when this node is assigned by one group, so -+ * other nodes will be allocated >= 1 groups, since 'numgrps' is -+ * bigger than number of numa nodes. -+ * -+ * One perfect invariant is that number of allocated groups for -+ * each node is <= CPU count of this node: -+ * -+ * 1) suppose there are two nodes: A and B -+ * ncpu(X) is CPU count of node X -+ * grps(X) is the group count allocated to node X via this -+ * algorithm -+ * -+ * ncpu(A) <= ncpu(B) -+ * ncpu(A) + ncpu(B) = N -+ * grps(A) + grps(B) = G -+ * -+ * grps(A) = max(1, round_down(G * ncpu(A) / N)) -+ * grps(B) = G - grps(A) -+ * -+ * both N and G are integer, and 2 <= G <= N, suppose -+ * G = N - delta, and 0 <= delta <= N - 2 -+ * -+ * 2) obviously grps(A) <= ncpu(A) because: -+ * -+ * if grps(A) is 1, then grps(A) <= ncpu(A) given -+ * ncpu(A) >= 1 -+ * -+ * otherwise, -+ * grps(A) <= G * ncpu(A) / N <= ncpu(A), given G <= N -+ * -+ * 3) prove how grps(B) <= ncpu(B): -+ * -+ * if round_down(G * ncpu(A) / N) == 0, vecs(B) won't be -+ * over-allocated, so grps(B) <= ncpu(B), -+ * -+ * otherwise: -+ * -+ * grps(A) = -+ * round_down(G * ncpu(A) / N) = -+ * round_down((N - delta) * ncpu(A) / N) = -+ * round_down((N * ncpu(A) - delta * ncpu(A)) / N) >= -+ * round_down((N * ncpu(A) - delta * N) / N) = -+ * cpu(A) - delta -+ * -+ * then: -+ * -+ * grps(A) - G >= ncpu(A) - delta - G -+ * => -+ * G - grps(A) <= G + delta - ncpu(A) -+ * => -+ * grps(B) <= N - ncpu(A) -+ * => -+ * grps(B) <= cpu(B) -+ * -+ * For nodes >= 3, it can be thought as one node and another big -+ * node given that is exactly what this algorithm is implemented, -+ * and we always re-calculate 'remaining_ncpus' & 'numgrps', and -+ * finally for each node X: grps(X) <= ncpu(X). -+ * -+ */ -+ for (n = 0; n < nr_node_ids; n++) { -+ unsigned ngroups, ncpus; -+ -+ if (node_groups[n].ncpus == UINT_MAX) -+ continue; -+ -+ WARN_ON_ONCE(numgrps == 0); -+ -+ ncpus = node_groups[n].ncpus; -+ ngroups = max_t(unsigned, 1, -+ numgrps * ncpus / remaining_ncpus); -+ WARN_ON_ONCE(ngroups > ncpus); -+ -+ node_groups[n].ngroups = ngroups; -+ -+ remaining_ncpus -= ncpus; -+ numgrps -= ngroups; -+ } -+} -+ -+static int __group_cpus_evenly(unsigned int startgrp, unsigned int numgrps, -+ cpumask_var_t *node_to_cpumask, -+ const struct cpumask *cpu_mask, -+ struct cpumask *nmsk, struct cpumask *masks) -+{ -+ unsigned int i, n, nodes, cpus_per_grp, extra_grps, done = 0; -+ unsigned int last_grp = numgrps; -+ unsigned int curgrp = startgrp; -+ nodemask_t nodemsk = NODE_MASK_NONE; -+ struct node_groups *node_groups; -+ -+ if (cpumask_empty(cpu_mask)) -+ return 0; -+ -+ nodes = get_nodes_in_cpumask(node_to_cpumask, cpu_mask, &nodemsk); -+ -+ /* -+ * If the number of nodes in the mask is greater than or equal the -+ * number of groups we just spread the groups across the nodes. -+ */ -+ if (numgrps <= nodes) { -+ for_each_node_mask(n, nodemsk) { -+ /* Ensure that only CPUs which are in both masks are set */ -+ cpumask_and(nmsk, cpu_mask, node_to_cpumask[n]); -+ cpumask_or(&masks[curgrp], &masks[curgrp], nmsk); -+ if (++curgrp == last_grp) -+ curgrp = 0; -+ } -+ return numgrps; -+ } -+ -+ node_groups = kcalloc(nr_node_ids, -+ sizeof(struct node_groups), -+ GFP_KERNEL); -+ if (!node_groups) -+ return -ENOMEM; -+ -+ /* allocate group number for each node */ -+ alloc_nodes_groups(numgrps, node_to_cpumask, cpu_mask, -+ nodemsk, nmsk, node_groups); -+ for (i = 0; i < nr_node_ids; i++) { -+ unsigned int ncpus, v; -+ struct node_groups *nv = &node_groups[i]; -+ -+ if (nv->ngroups == UINT_MAX) -+ continue; -+ -+ /* Get the cpus on this node which are in the mask */ -+ cpumask_and(nmsk, cpu_mask, node_to_cpumask[nv->id]); -+ ncpus = cpumask_weight(nmsk); -+ if (!ncpus) -+ continue; -+ -+ WARN_ON_ONCE(nv->ngroups > ncpus); -+ -+ /* Account for rounding errors */ -+ extra_grps = ncpus - nv->ngroups * (ncpus / nv->ngroups); -+ -+ /* Spread allocated groups on CPUs of the current node */ -+ for (v = 0; v < nv->ngroups; v++, curgrp++) { -+ cpus_per_grp = ncpus / nv->ngroups; -+ -+ /* Account for extra groups to compensate rounding errors */ -+ if (extra_grps) { -+ cpus_per_grp++; -+ --extra_grps; -+ } -+ -+ /* -+ * wrapping has to be considered given 'startgrp' -+ * may start anywhere -+ */ -+ if (curgrp >= last_grp) -+ curgrp = 0; -+ grp_spread_init_one(&masks[curgrp], nmsk, -+ cpus_per_grp); -+ } -+ done += nv->ngroups; -+ } -+ kfree(node_groups); -+ return done; -+} -+ -+/** -+ * group_cpus_evenly - Group all CPUs evenly per NUMA/CPU locality -+ * @numgrps: number of groups -+ * -+ * Return: cpumask array if successful, NULL otherwise. And each element -+ * includes CPUs assigned to this group -+ * -+ * Try to put close CPUs from viewpoint of CPU and NUMA locality into -+ * same group, and run two-stage grouping: -+ * 1) allocate present CPUs on these groups evenly first -+ * 2) allocate other possible CPUs on these groups evenly -+ * -+ * We guarantee in the resulted grouping that all CPUs are covered, and -+ * no same CPU is assigned to multiple groups -+ */ -+struct cpumask *group_cpus_evenly(unsigned int numgrps) -+{ -+ unsigned int curgrp = 0, nr_present = 0, nr_others = 0; -+ cpumask_var_t *node_to_cpumask; -+ cpumask_var_t nmsk, npresmsk; -+ int ret = -ENOMEM; -+ struct cpumask *masks = NULL; -+ -+ if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL)) -+ return NULL; -+ -+ if (!zalloc_cpumask_var(&npresmsk, GFP_KERNEL)) -+ goto fail_nmsk; -+ -+ node_to_cpumask = alloc_node_to_cpumask(); -+ if (!node_to_cpumask) -+ goto fail_npresmsk; -+ -+ masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); -+ if (!masks) -+ goto fail_node_to_cpumask; -+ -+ 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, -+ npresmsk, nmsk, masks); -+ if (ret < 0) -+ goto fail_build_affinity; -+ nr_present = ret; -+ -+ /* -+ * Allocate non present CPUs starting from the next group to be -+ * handled. If the grouping of present CPUs already exhausted the -+ * group space, assign the non present CPUs to the already -+ * allocated out groups. -+ */ -+ if (nr_present >= numgrps) -+ curgrp = 0; -+ else -+ curgrp = nr_present; -+ 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: -+ if (ret >= 0) -+ WARN_ON(nr_present + nr_others < numgrps); -+ -+ fail_node_to_cpumask: -+ free_node_to_cpumask(node_to_cpumask); -+ -+ fail_npresmsk: -+ free_cpumask_var(npresmsk); -+ -+ fail_nmsk: -+ free_cpumask_var(nmsk); -+ if (ret < 0) { -+ kfree(masks); -+ return NULL; -+ } -+ return masks; -+} -+#else /* CONFIG_SMP */ -+struct cpumask *group_cpus_evenly(unsigned int numgrps) -+{ -+ struct cpumask *masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); -+ -+ if (!masks) -+ return NULL; -+ -+ /* assign all CPUs(cpu 0) to the 1st group only */ -+ cpumask_copy(&masks[0], cpu_possible_mask); -+ return masks; -+} -+#endif /* CONFIG_SMP */ -diff --git a/mm/filemap.c b/mm/filemap.c -index 10fe6430693bd..2809b1174f04e 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -4005,6 +4005,8 @@ bool filemap_release_folio(struct folio *folio, gfp_t gfp) - struct address_space * const mapping = folio->mapping; - - BUG_ON(!folio_test_locked(folio)); -+ if (!folio_needs_release(folio)) -+ return true; - if (folio_test_writeback(folio)) - return false; - -diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index 2753fb54cdf38..59577946735b1 100644 ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -2694,8 +2694,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) - gfp = current_gfp_context(mapping_gfp_mask(mapping) & - GFP_RECLAIM_MASK); - -- if (folio_test_private(folio) && -- !filemap_release_folio(folio, gfp)) { -+ if (!filemap_release_folio(folio, gfp)) { - ret = -EBUSY; - goto out; - } -diff --git a/mm/internal.h b/mm/internal.h -index 6b7ef495b56d3..d01130efce5fb 100644 ---- a/mm/internal.h -+++ b/mm/internal.h -@@ -163,6 +163,17 @@ static inline void set_page_refcounted(struct page *page) - set_page_count(page, 1); - } - -+/* -+ * Return true if a folio needs ->release_folio() calling upon it. -+ */ -+static inline bool folio_needs_release(struct folio *folio) -+{ -+ struct address_space *mapping = folio_mapping(folio); -+ -+ return folio_has_private(folio) || -+ (mapping && mapping_release_always(mapping)); -+} -+ - extern unsigned long highest_memmap_pfn; - - /* -diff --git a/mm/khugepaged.c b/mm/khugepaged.c -index ef72d3df4b65b..65bd0b105266a 100644 ---- a/mm/khugepaged.c -+++ b/mm/khugepaged.c -@@ -1818,6 +1818,7 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr, - xas_set(&xas, start); - for (index = start; index < end; index++) { - struct page *page = xas_next(&xas); -+ struct folio *folio; - - VM_BUG_ON(index != xas.xa_index); - if (is_shmem) { -@@ -1844,8 +1845,6 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr, - } - - if (xa_is_value(page) || !PageUptodate(page)) { -- struct folio *folio; -- - xas_unlock_irq(&xas); - /* swap in or instantiate fallocated page */ - if (shmem_get_folio(mapping->host, index, -@@ -1933,13 +1932,15 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr, - goto out_unlock; - } - -- if (page_mapping(page) != mapping) { -+ folio = page_folio(page); -+ -+ if (folio_mapping(folio) != mapping) { - result = SCAN_TRUNCATED; - goto out_unlock; - } - -- if (!is_shmem && (PageDirty(page) || -- PageWriteback(page))) { -+ if (!is_shmem && (folio_test_dirty(folio) || -+ folio_test_writeback(folio))) { - /* - * khugepaged only works on read-only fd, so this - * page is dirty because it hasn't been flushed -@@ -1949,20 +1950,19 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr, - goto out_unlock; - } - -- if (isolate_lru_page(page)) { -+ if (folio_isolate_lru(folio)) { - result = SCAN_DEL_PAGE_LRU; - goto out_unlock; - } - -- if (page_has_private(page) && -- !try_to_release_page(page, GFP_KERNEL)) { -+ if (!filemap_release_folio(folio, GFP_KERNEL)) { - result = SCAN_PAGE_HAS_PRIVATE; -- putback_lru_page(page); -+ folio_putback_lru(folio); - goto out_unlock; - } - -- if (page_mapped(page)) -- try_to_unmap(page_folio(page), -+ if (folio_mapped(folio)) -+ try_to_unmap(folio, - TTU_IGNORE_MLOCK | TTU_BATCH_FLUSH); - - xas_lock_irq(&xas); -diff --git a/mm/memory-failure.c b/mm/memory-failure.c -index ebd717157c813..5b846ed5dcbe9 100644 ---- a/mm/memory-failure.c -+++ b/mm/memory-failure.c -@@ -827,16 +827,15 @@ static int truncate_error_page(struct page *p, unsigned long pfn, - int ret = MF_FAILED; - - if (mapping->a_ops->error_remove_page) { -+ struct folio *folio = page_folio(p); - int err = mapping->a_ops->error_remove_page(mapping, p); - -- if (err != 0) { -+ if (err != 0) - pr_info("%#lx: Failed to punch page: %d\n", pfn, err); -- } else if (page_has_private(p) && -- !try_to_release_page(p, GFP_NOIO)) { -+ else if (!filemap_release_folio(folio, GFP_NOIO)) - pr_info("%#lx: failed to release buffers\n", pfn); -- } else { -+ else - ret = MF_RECOVERED; -- } - } else { - /* - * If the file system doesn't support it just invalidate -diff --git a/mm/memory.c b/mm/memory.c -index 0d1b3ee8fcd7a..fc8b264ec0cac 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -3617,8 +3617,8 @@ EXPORT_SYMBOL_GPL(unmap_mapping_pages); - void unmap_mapping_range(struct address_space *mapping, - loff_t const holebegin, loff_t const holelen, int even_cows) - { -- pgoff_t hba = holebegin >> PAGE_SHIFT; -- pgoff_t hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ pgoff_t hba = (pgoff_t)(holebegin) >> PAGE_SHIFT; -+ pgoff_t hlen = ((pgoff_t)(holelen) + PAGE_SIZE - 1) >> PAGE_SHIFT; - - /* Check for overflow. */ - if (sizeof(holelen) > sizeof(hlen)) { -diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c -index bd2570b4f9b7b..3b9d3a4b43869 100644 ---- a/mm/memory_hotplug.c -+++ b/mm/memory_hotplug.c -@@ -1069,6 +1069,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) - { -@@ -1089,7 +1092,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); -@@ -1148,7 +1150,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: -@@ -1157,7 +1158,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; - } - -@@ -1382,7 +1382,7 @@ int __ref add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags) - ret = create_memory_block_devices(start, size, mhp_altmap.alloc, - group); - if (ret) { -- arch_remove_memory(start, size, NULL); -+ arch_remove_memory(start, size, params.altmap); - goto error; - } - -@@ -1787,6 +1787,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) - { -@@ -1809,8 +1812,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 -@@ -1946,7 +1947,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: -@@ -1961,7 +1961,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/mm/migrate.c b/mm/migrate.c -index 91bd69c61148e..c93dd6a31c31a 100644 ---- a/mm/migrate.c -+++ b/mm/migrate.c -@@ -914,8 +914,7 @@ static int fallback_migrate_folio(struct address_space *mapping, - * Buffers may be managed in a filesystem specific way. - * We must have no buffers or drop them. - */ -- if (folio_test_private(src) && -- !filemap_release_folio(src, GFP_KERNEL)) -+ if (!filemap_release_folio(src, GFP_KERNEL)) - return mode == MIGRATE_SYNC ? -EAGAIN : -EBUSY; - - return migrate_folio(mapping, dst, src, mode); -diff --git a/mm/page-writeback.c b/mm/page-writeback.c -index 7e9d8d857ecca..de5f69921b946 100644 ---- a/mm/page-writeback.c -+++ b/mm/page-writeback.c -@@ -3078,7 +3078,7 @@ EXPORT_SYMBOL_GPL(folio_wait_writeback_killable); - */ - void folio_wait_stable(struct folio *folio) - { -- if (folio_inode(folio)->i_sb->s_iflags & SB_I_STABLE_WRITES) -+ if (mapping_stable_writes(folio_mapping(folio))) - folio_wait_writeback(folio); - } - EXPORT_SYMBOL_GPL(folio_wait_stable); -diff --git a/mm/truncate.c b/mm/truncate.c -index c0be77e5c0083..0d4dd233f5187 100644 ---- a/mm/truncate.c -+++ b/mm/truncate.c -@@ -19,7 +19,6 @@ - #include - #include - #include --#include /* grr. try_to_release_page */ - #include - #include - #include "internal.h" -@@ -276,7 +275,7 @@ static long mapping_evict_folio(struct address_space *mapping, - if (folio_ref_count(folio) > - folio_nr_pages(folio) + folio_has_private(folio) + 1) - return 0; -- if (folio_has_private(folio) && !filemap_release_folio(folio, 0)) -+ if (!filemap_release_folio(folio, 0)) - return 0; - - return remove_mapping(mapping, folio); -@@ -581,8 +580,7 @@ static int invalidate_complete_folio2(struct address_space *mapping, - if (folio->mapping != mapping) - return 0; - -- if (folio_has_private(folio) && -- !filemap_release_folio(folio, GFP_KERNEL)) -+ if (!filemap_release_folio(folio, GFP_KERNEL)) - return 0; - - spin_lock(&mapping->host->i_lock); -diff --git a/mm/vmscan.c b/mm/vmscan.c -index 3f090faa6377f..9f3cfb7caa48d 100644 ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -1992,7 +1992,7 @@ retry: - * (refcount == 1) it can be freed. Otherwise, leave - * the folio on the LRU so it is swappable. - */ -- if (folio_has_private(folio)) { -+ if (folio_needs_release(folio)) { - if (!filemap_release_folio(folio, sc->gfp_mask)) - goto activate_locked; - if (!mapping && folio_ref_count(folio) == 1) { -@@ -2618,9 +2618,9 @@ static void shrink_active_list(unsigned long nr_to_scan, - } - - if (unlikely(buffer_heads_over_limit)) { -- if (folio_test_private(folio) && folio_trylock(folio)) { -- if (folio_test_private(folio)) -- filemap_release_folio(folio, 0); -+ if (folio_needs_release(folio) && -+ folio_trylock(folio)) { -+ filemap_release_folio(folio, 0); - folio_unlock(folio); - } - } -diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c -index 9c828067b4481..b0be23559243c 100644 ---- a/net/can/j1939/socket.c -+++ b/net/can/j1939/socket.c -@@ -974,6 +974,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk, - struct sock_exterr_skb *serr; - struct sk_buff *skb; - char *state = "UNK"; -+ u32 tsflags; - int err; - - jsk = j1939_sk(sk); -@@ -981,13 +982,14 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk, - if (!(jsk->state & J1939_SOCK_ERRQUEUE)) - return; - -+ tsflags = READ_ONCE(sk->sk_tsflags); - switch (type) { - case J1939_ERRQUEUE_TX_ACK: -- if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK)) -+ if (!(tsflags & SOF_TIMESTAMPING_TX_ACK)) - return; - break; - case J1939_ERRQUEUE_TX_SCHED: -- if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED)) -+ if (!(tsflags & SOF_TIMESTAMPING_TX_SCHED)) - return; - break; - case J1939_ERRQUEUE_TX_ABORT: -@@ -997,7 +999,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk, - case J1939_ERRQUEUE_RX_DPO: - fallthrough; - case J1939_ERRQUEUE_RX_ABORT: -- if (!(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE)) -+ if (!(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE)) - return; - break; - default: -@@ -1054,7 +1056,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk, - } - - serr->opt_stats = true; -- if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) -+ if (tsflags & SOF_TIMESTAMPING_OPT_ID) - serr->ee.ee_data = session->tskey; - - netdev_dbg(session->priv->ndev, "%s: 0x%p tskey: %i, state: %s\n", -diff --git a/net/can/raw.c b/net/can/raw.c -index 8c104339d538d..488320738e319 100644 ---- a/net/can/raw.c -+++ b/net/can/raw.c -@@ -881,6 +881,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) - - skb->dev = dev; - skb->priority = sk->sk_priority; -+ skb->mark = sk->sk_mark; - skb->tstamp = sockc.transmit_time; - - skb_setup_tx_timestamp(skb, sockc.tsflags); -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 73b1e0e53534e..8a819d0a7bfb0 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -4913,7 +4913,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb, - serr->ee.ee_info = tstype; - serr->opt_stats = opt_stats; - serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0; -- if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) { -+ if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) { - serr->ee.ee_data = skb_shinfo(skb)->tskey; - if (sk_is_tcp(sk)) - serr->ee.ee_data -= atomic_read(&sk->sk_tskey); -@@ -4969,21 +4969,23 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, - { - struct sk_buff *skb; - bool tsonly, opt_stats = false; -+ u32 tsflags; - - if (!sk) - return; - -- if (!hwtstamps && !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) && -+ tsflags = READ_ONCE(sk->sk_tsflags); -+ if (!hwtstamps && !(tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) && - skb_shinfo(orig_skb)->tx_flags & SKBTX_IN_PROGRESS) - return; - -- tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; -+ tsonly = tsflags & SOF_TIMESTAMPING_OPT_TSONLY; - if (!skb_may_tx_timestamp(sk, tsonly)) - return; - - if (tsonly) { - #ifdef CONFIG_INET -- if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) && -+ if ((tsflags & SOF_TIMESTAMPING_OPT_STATS) && - sk_is_tcp(sk)) { - skb = tcp_get_timestamping_opt_stats(sk, orig_skb, - ack_skb); -diff --git a/net/core/skmsg.c b/net/core/skmsg.c -index a5c1f67dc96ec..3818035ea0021 100644 ---- a/net/core/skmsg.c -+++ b/net/core/skmsg.c -@@ -825,6 +825,8 @@ static void sk_psock_destroy(struct work_struct *work) - - if (psock->sk_redir) - sock_put(psock->sk_redir); -+ if (psock->sk_pair) -+ sock_put(psock->sk_pair); - sock_put(psock->sk); - kfree(psock); - } -diff --git a/net/core/sock.c b/net/core/sock.c -index 4305e55dbfba4..c50a14a02edd4 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -890,7 +890,7 @@ static int sock_timestamping_bind_phc(struct sock *sk, int phc_index) - if (!match) - return -EINVAL; - -- sk->sk_bind_phc = phc_index; -+ WRITE_ONCE(sk->sk_bind_phc, phc_index); - - return 0; - } -@@ -926,7 +926,7 @@ int sock_set_timestamping(struct sock *sk, int optname, - return ret; - } - -- sk->sk_tsflags = val; -+ WRITE_ONCE(sk->sk_tsflags, val); - sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW); - - if (val & SOF_TIMESTAMPING_RX_SOFTWARE) -@@ -1704,9 +1704,16 @@ int sk_getsockopt(struct sock *sk, int level, int optname, - break; - - case SO_TIMESTAMPING_OLD: -+ case SO_TIMESTAMPING_NEW: - lv = sizeof(v.timestamping); -- v.timestamping.flags = sk->sk_tsflags; -- v.timestamping.bind_phc = sk->sk_bind_phc; -+ /* For the later-added case SO_TIMESTAMPING_NEW: Be strict about only -+ * returning the flags when they were set through the same option. -+ * Don't change the beviour for the old case SO_TIMESTAMPING_OLD. -+ */ -+ if (optname == SO_TIMESTAMPING_OLD || sock_flag(sk, SOCK_TSTAMP_NEW)) { -+ v.timestamping.flags = READ_ONCE(sk->sk_tsflags); -+ v.timestamping.bind_phc = READ_ONCE(sk->sk_bind_phc); -+ } - break; - - case SO_RCVTIMEO_OLD: -@@ -2764,6 +2771,7 @@ int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg, - sockc->mark = *(u32 *)CMSG_DATA(cmsg); - break; - case SO_TIMESTAMPING_OLD: -+ case SO_TIMESTAMPING_NEW: - if (cmsg->cmsg_len != CMSG_LEN(sizeof(u32))) - return -EINVAL; - -diff --git a/net/core/sock_map.c b/net/core/sock_map.c -index 38e01f82f2ef3..91140bc0541f3 100644 ---- a/net/core/sock_map.c -+++ b/net/core/sock_map.c -@@ -538,6 +538,8 @@ static bool sock_map_sk_state_allowed(const struct sock *sk) - { - if (sk_is_tcp(sk)) - return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_LISTEN); -+ if (sk_is_stream_unix(sk)) -+ return (1 << sk->sk_state) & TCPF_ESTABLISHED; - return true; - } - -diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c -index 03f8f33dc134c..8324e9f970668 100644 ---- a/net/dns_resolver/dns_key.c -+++ b/net/dns_resolver/dns_key.c -@@ -91,8 +91,6 @@ const struct cred *dns_resolver_cache; - static int - dns_resolver_preparse(struct key_preparsed_payload *prep) - { -- const struct dns_server_list_v1_header *v1; -- const struct dns_payload_header *bin; - struct user_key_payload *upayload; - unsigned long derrno; - int ret; -@@ -103,27 +101,28 @@ dns_resolver_preparse(struct key_preparsed_payload *prep) - return -EINVAL; - - if (data[0] == 0) { -+ const struct dns_server_list_v1_header *v1; -+ - /* It may be a server list. */ -- if (datalen <= sizeof(*bin)) -+ if (datalen <= sizeof(*v1)) - return -EINVAL; - -- bin = (const struct dns_payload_header *)data; -- kenter("[%u,%u],%u", bin->content, bin->version, datalen); -- if (bin->content != DNS_PAYLOAD_IS_SERVER_LIST) { -+ v1 = (const struct dns_server_list_v1_header *)data; -+ kenter("[%u,%u],%u", v1->hdr.content, v1->hdr.version, datalen); -+ if (v1->hdr.content != DNS_PAYLOAD_IS_SERVER_LIST) { - pr_warn_ratelimited( - "dns_resolver: Unsupported content type (%u)\n", -- bin->content); -+ v1->hdr.content); - return -EINVAL; - } - -- if (bin->version != 1) { -+ if (v1->hdr.version != 1) { - pr_warn_ratelimited( - "dns_resolver: Unsupported server list version (%u)\n", -- bin->version); -+ v1->hdr.version); - return -EINVAL; - } - -- v1 = (const struct dns_server_list_v1_header *)bin; - if ((v1->status != DNS_LOOKUP_GOOD && - v1->status != DNS_LOOKUP_GOOD_WITH_BAD)) { - if (prep->expiry == TIME64_MAX) -diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c -index 1a4c11356c96c..fc4ccecf9495c 100644 ---- a/net/ethtool/netlink.c -+++ b/net/ethtool/netlink.c -@@ -509,7 +509,7 @@ lock_and_cont: - cont: - idx++; - } -- -+ ret = 0; - } - rtnl_unlock(); - -diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index 5d379df90c826..347c3768df6e8 100644 ---- a/net/ipv4/af_inet.c -+++ b/net/ipv4/af_inet.c -@@ -838,6 +838,21 @@ int inet_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) - } - EXPORT_SYMBOL(inet_sendmsg); - -+void inet_splice_eof(struct socket *sock) -+{ -+ const struct proto *prot; -+ struct sock *sk = sock->sk; -+ -+ if (unlikely(inet_send_prepare(sk))) -+ return; -+ -+ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ -+ prot = READ_ONCE(sk->sk_prot); -+ if (prot->splice_eof) -+ prot->splice_eof(sock); -+} -+EXPORT_SYMBOL_GPL(inet_splice_eof); -+ - ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, - size_t size, int flags) - { -@@ -1057,6 +1072,7 @@ const struct proto_ops inet_stream_ops = { - #ifdef CONFIG_MMU - .mmap = tcp_mmap, - #endif -+ .splice_eof = inet_splice_eof, - .sendpage = inet_sendpage, - .splice_read = tcp_splice_read, - .read_sock = tcp_read_sock, -@@ -1091,6 +1107,7 @@ const struct proto_ops inet_dgram_ops = { - .read_skb = udp_read_skb, - .recvmsg = inet_recvmsg, - .mmap = sock_no_mmap, -+ .splice_eof = inet_splice_eof, - .sendpage = inet_sendpage, - .set_peek_off = sk_set_peek_off, - #ifdef CONFIG_COMPAT -@@ -1122,6 +1139,7 @@ static const struct proto_ops inet_sockraw_ops = { - .sendmsg = inet_sendmsg, - .recvmsg = inet_recvmsg, - .mmap = sock_no_mmap, -+ .splice_eof = inet_splice_eof, - .sendpage = inet_sendpage, - #ifdef CONFIG_COMPAT - .compat_ioctl = inet_compat_ioctl, -diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c -index 493c679ea54f3..e19ef88ae181f 100644 ---- a/net/ipv4/ip_output.c -+++ b/net/ipv4/ip_output.c -@@ -990,8 +990,8 @@ static int __ip_append_data(struct sock *sk, - mtu = cork->gso_size ? IP_MAX_MTU : cork->fragsize; - paged = !!cork->gso_size; - -- if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && -- sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) -+ if (cork->tx_flags & SKBTX_ANY_TSTAMP && -+ READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) - tskey = atomic_inc_return(&sk->sk_tskey) - 1; - - hh_len = LL_RESERVED_SPACE(rt->dst.dev); -diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c -index 63aa52becd880..c1fb7580ea581 100644 ---- a/net/ipv4/ip_sockglue.c -+++ b/net/ipv4/ip_sockglue.c -@@ -509,7 +509,7 @@ static bool ipv4_datagram_support_cmsg(const struct sock *sk, - * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). - */ - info = PKTINFO_SKB_CB(skb); -- if (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG) || -+ if (!(READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_CMSG) || - !info->ipi_ifindex) - return false; - -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 58409ea2da0af..0b7844a8d5711 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -1492,6 +1492,22 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) - } - EXPORT_SYMBOL(tcp_sendmsg); - -+void tcp_splice_eof(struct socket *sock) -+{ -+ struct sock *sk = sock->sk; -+ struct tcp_sock *tp = tcp_sk(sk); -+ int mss_now, size_goal; -+ -+ if (!tcp_write_queue_tail(sk)) -+ return; -+ -+ lock_sock(sk); -+ mss_now = tcp_send_mss(sk, &size_goal, 0); -+ tcp_push(sk, 0, mss_now, tp->nonagle, size_goal); -+ release_sock(sk); -+} -+EXPORT_SYMBOL_GPL(tcp_splice_eof); -+ - /* - * Handle reading urgent data. BSD has very simple semantics for - * this, no blocking and very strange errors 8) -@@ -2359,14 +2375,14 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, - } - } - -- if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) -+ if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_SOFTWARE) - has_timestamping = true; - else - tss->ts[0] = (struct timespec64) {0}; - } - - if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) { -- if (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) -+ if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_RAW_HARDWARE) - has_timestamping = true; - else - tss->ts[2] = (struct timespec64) {0}; -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index 7ebbbe561e402..be2c807eed15d 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -3067,6 +3067,7 @@ struct proto tcp_prot = { - .keepalive = tcp_set_keepalive, - .recvmsg = tcp_recvmsg, - .sendmsg = tcp_sendmsg, -+ .splice_eof = tcp_splice_eof, - .sendpage = tcp_sendpage, - .backlog_rcv = tcp_v4_do_rcv, - .release_cb = tcp_release_cb, -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 65abc92a81bd0..5672d9a86c5d2 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -733,7 +733,7 @@ int __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable) - iph->saddr, uh->source, skb->dev->ifindex, - inet_sdif(skb), udptable, NULL); - -- if (!sk || udp_sk(sk)->encap_type) { -+ if (!sk || READ_ONCE(udp_sk(sk)->encap_type)) { - /* No socket for error: try tunnels before discarding */ - if (static_branch_unlikely(&udp_encap_needed_key)) { - sk = __udp4_lib_err_encap(net, iph, uh, udptable, sk, skb, -@@ -1068,7 +1068,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - __be16 dport; - u8 tos; - int err, is_udplite = IS_UDPLITE(sk); -- int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE; -+ int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE; - int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); - struct sk_buff *skb; - struct ip_options_data opt_copy; -@@ -1332,57 +1332,33 @@ do_confirm: - } - EXPORT_SYMBOL(udp_sendmsg); - --int udp_sendpage(struct sock *sk, struct page *page, int offset, -- size_t size, int flags) -+void udp_splice_eof(struct socket *sock) - { -- struct inet_sock *inet = inet_sk(sk); -+ struct sock *sk = sock->sk; - struct udp_sock *up = udp_sk(sk); -- int ret; - -- if (flags & MSG_SENDPAGE_NOTLAST) -- flags |= MSG_MORE; -- -- if (!up->pending) { -- struct msghdr msg = { .msg_flags = flags|MSG_MORE }; -- -- /* Call udp_sendmsg to specify destination address which -- * sendpage interface can't pass. -- * This will succeed only when the socket is connected. -- */ -- ret = udp_sendmsg(sk, &msg, 0); -- if (ret < 0) -- return ret; -- } -+ if (!up->pending || udp_test_bit(CORK, sk)) -+ return; - - lock_sock(sk); -+ if (up->pending && !udp_test_bit(CORK, sk)) -+ udp_push_pending_frames(sk); -+ release_sock(sk); -+} -+EXPORT_SYMBOL_GPL(udp_splice_eof); - -- if (unlikely(!up->pending)) { -- release_sock(sk); -- -- net_dbg_ratelimited("cork failed\n"); -- return -EINVAL; -- } -+int udp_sendpage(struct sock *sk, struct page *page, int offset, -+ size_t size, int flags) -+{ -+ struct bio_vec bvec; -+ struct msghdr msg = { .msg_flags = flags | MSG_SPLICE_PAGES }; - -- ret = ip_append_page(sk, &inet->cork.fl.u.ip4, -- page, offset, size, flags); -- if (ret == -EOPNOTSUPP) { -- release_sock(sk); -- return sock_no_sendpage(sk->sk_socket, page, offset, -- size, flags); -- } -- if (ret < 0) { -- udp_flush_pending_frames(sk); -- goto out; -- } -+ if (flags & MSG_SENDPAGE_NOTLAST) -+ msg.msg_flags |= MSG_MORE; - -- up->len += size; -- if (!(READ_ONCE(up->corkflag) || (flags&MSG_MORE))) -- ret = udp_push_pending_frames(sk); -- if (!ret) -- ret = size; --out: -- release_sock(sk); -- return ret; -+ bvec_set_page(&bvec, page, size, offset); -+ iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); -+ return udp_sendmsg(sk, &msg, size); - } - - #define UDP_SKB_IS_STATELESS 0x80000000 -@@ -1925,7 +1901,7 @@ try_again: - (struct sockaddr *)sin); - } - -- if (udp_sk(sk)->gro_enabled) -+ if (udp_test_bit(GRO_ENABLED, sk)) - udp_cmsg_recv(msg, sk, skb); - - if (inet->cmsg_flags) -@@ -2138,7 +2114,8 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) - } - nf_reset_ct(skb); - -- if (static_branch_unlikely(&udp_encap_needed_key) && up->encap_type) { -+ if (static_branch_unlikely(&udp_encap_needed_key) && -+ READ_ONCE(up->encap_type)) { - int (*encap_rcv)(struct sock *sk, struct sk_buff *skb); - - /* -@@ -2669,7 +2646,7 @@ void udp_destroy_sock(struct sock *sk) - if (encap_destroy) - encap_destroy(sk); - } -- if (up->encap_enabled) -+ if (udp_test_bit(ENCAP_ENABLED, sk)) - static_branch_dec(&udp_encap_needed_key); - } - } -@@ -2697,9 +2674,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, - switch (optname) { - case UDP_CORK: - if (val != 0) { -- WRITE_ONCE(up->corkflag, 1); -+ udp_set_bit(CORK, sk); - } else { -- WRITE_ONCE(up->corkflag, 0); -+ udp_clear_bit(CORK, sk); - lock_sock(sk); - push_pending_frames(sk); - release_sock(sk); -@@ -2723,10 +2700,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, - #endif - fallthrough; - case UDP_ENCAP_L2TPINUDP: -- up->encap_type = val; -- lock_sock(sk); -- udp_tunnel_encap_enable(sk->sk_socket); -- release_sock(sk); -+ WRITE_ONCE(up->encap_type, val); -+ udp_tunnel_encap_enable(sk); - break; - default: - err = -ENOPROTOOPT; -@@ -2735,11 +2710,11 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, - break; - - case UDP_NO_CHECK6_TX: -- up->no_check6_tx = valbool; -+ udp_set_no_check6_tx(sk, valbool); - break; - - case UDP_NO_CHECK6_RX: -- up->no_check6_rx = valbool; -+ udp_set_no_check6_rx(sk, valbool); - break; - - case UDP_SEGMENT: -@@ -2749,14 +2724,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, - break; - - case UDP_GRO: -- lock_sock(sk); - - /* when enabling GRO, accept the related GSO packet type */ - if (valbool) -- udp_tunnel_encap_enable(sk->sk_socket); -- up->gro_enabled = valbool; -- up->accept_udp_l4 = valbool; -- release_sock(sk); -+ udp_tunnel_encap_enable(sk); -+ udp_assign_bit(GRO_ENABLED, sk, valbool); -+ udp_assign_bit(ACCEPT_L4, sk, valbool); - break; - - /* -@@ -2824,19 +2797,19 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, - - switch (optname) { - case UDP_CORK: -- val = READ_ONCE(up->corkflag); -+ val = udp_test_bit(CORK, sk); - break; - - case UDP_ENCAP: -- val = up->encap_type; -+ val = READ_ONCE(up->encap_type); - break; - - case UDP_NO_CHECK6_TX: -- val = up->no_check6_tx; -+ val = udp_get_no_check6_tx(sk); - break; - - case UDP_NO_CHECK6_RX: -- val = up->no_check6_rx; -+ val = udp_get_no_check6_rx(sk); - break; - - case UDP_SEGMENT: -@@ -2844,7 +2817,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname, - break; - - case UDP_GRO: -- val = up->gro_enabled; -+ val = udp_test_bit(GRO_ENABLED, sk); - break; - - /* The following two cannot be changed on UDP sockets, the return is -@@ -2946,6 +2919,7 @@ struct proto udp_prot = { - .getsockopt = udp_getsockopt, - .sendmsg = udp_sendmsg, - .recvmsg = udp_recvmsg, -+ .splice_eof = udp_splice_eof, - .sendpage = udp_sendpage, - .release_cb = ip4_datagram_release_cb, - .hash = udp_lib_hash, -diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c -index 6d1a4bec2614d..8096576fd9bde 100644 ---- a/net/ipv4/udp_offload.c -+++ b/net/ipv4/udp_offload.c -@@ -549,10 +549,10 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb, - NAPI_GRO_CB(skb)->is_flist = 0; - if (!sk || !udp_sk(sk)->gro_receive) { - if (skb->dev->features & NETIF_F_GRO_FRAGLIST) -- NAPI_GRO_CB(skb)->is_flist = sk ? !udp_sk(sk)->gro_enabled : 1; -+ NAPI_GRO_CB(skb)->is_flist = sk ? !udp_test_bit(GRO_ENABLED, sk) : 1; - - if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) || -- (sk && udp_sk(sk)->gro_enabled) || NAPI_GRO_CB(skb)->is_flist) -+ (sk && udp_test_bit(GRO_ENABLED, sk)) || NAPI_GRO_CB(skb)->is_flist) - return call_gro_receive(udp_gro_receive_segment, head, skb); - - /* no GRO, be sure flush the current packet */ -diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c -index 5f8104cf082d0..732e21b75ba28 100644 ---- a/net/ipv4/udp_tunnel_core.c -+++ b/net/ipv4/udp_tunnel_core.c -@@ -78,7 +78,7 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock, - udp_sk(sk)->gro_receive = cfg->gro_receive; - udp_sk(sk)->gro_complete = cfg->gro_complete; - -- udp_tunnel_encap_enable(sock); -+ udp_tunnel_encap_enable(sk); - } - EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock); - -diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c -index eac206a290d05..183f6dc372429 100644 ---- a/net/ipv4/xfrm4_input.c -+++ b/net/ipv4/xfrm4_input.c -@@ -85,11 +85,11 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) - struct udphdr *uh; - struct iphdr *iph; - int iphlen, len; -- - __u8 *udpdata; - __be32 *udpdata32; -- __u16 encap_type = up->encap_type; -+ u16 encap_type; - -+ encap_type = READ_ONCE(up->encap_type); - /* if this is not encapsulated socket, then just return now */ - if (!encap_type) - return 1; -diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c -index b5309ae87fd79..a2f29ca516000 100644 ---- a/net/ipv6/af_inet6.c -+++ b/net/ipv6/af_inet6.c -@@ -711,6 +711,7 @@ const struct proto_ops inet6_stream_ops = { - #ifdef CONFIG_MMU - .mmap = tcp_mmap, - #endif -+ .splice_eof = inet_splice_eof, - .sendpage = inet_sendpage, - .sendmsg_locked = tcp_sendmsg_locked, - .sendpage_locked = tcp_sendpage_locked, -diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c -index 3c2b2a85de367..e9ae084d038d1 100644 ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -1506,8 +1506,8 @@ static int __ip6_append_data(struct sock *sk, - mtu = cork->gso_size ? IP6_MAX_MTU : cork->fragsize; - orig_mtu = mtu; - -- if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && -- sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) -+ if (cork->tx_flags & SKBTX_ANY_TSTAMP && -+ READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) - tskey = atomic_inc_return(&sk->sk_tskey) - 1; - - hh_len = LL_RESERVED_SPACE(rt->dst.dev); -diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c -index 4d5a27dd9a4b2..a5d7d1915ba7e 100644 ---- a/net/ipv6/ping.c -+++ b/net/ipv6/ping.c -@@ -119,7 +119,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - return -EINVAL; - - ipcm6_init_sk(&ipc6, np); -- ipc6.sockc.tsflags = sk->sk_tsflags; -+ ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags); - ipc6.sockc.mark = READ_ONCE(sk->sk_mark); - - fl6.flowi6_oif = oif; -diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c -index df3abd9e5237c..dc31752a7edcc 100644 ---- a/net/ipv6/raw.c -+++ b/net/ipv6/raw.c -@@ -776,7 +776,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - fl6.flowi6_uid = sk->sk_uid; - - ipcm6_init(&ipc6); -- ipc6.sockc.tsflags = sk->sk_tsflags; -+ ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags); - ipc6.sockc.mark = fl6.flowi6_mark; - - if (sin6) { -diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c -index 7be89dcfd5fc5..ba9a22db5805c 100644 ---- a/net/ipv6/tcp_ipv6.c -+++ b/net/ipv6/tcp_ipv6.c -@@ -2158,6 +2158,7 @@ struct proto tcpv6_prot = { - .keepalive = tcp_set_keepalive, - .recvmsg = tcp_recvmsg, - .sendmsg = tcp_sendmsg, -+ .splice_eof = tcp_splice_eof, - .sendpage = tcp_sendpage, - .backlog_rcv = tcp_v6_do_rcv, - .release_cb = tcp_release_cb, -diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index 64b36c2ba774a..961106eda69d0 100644 ---- a/net/ipv6/udp.c -+++ b/net/ipv6/udp.c -@@ -440,7 +440,7 @@ try_again: - (struct sockaddr *)sin6); - } - -- if (udp_sk(sk)->gro_enabled) -+ if (udp_test_bit(GRO_ENABLED, sk)) - udp_cmsg_recv(msg, sk, skb); - - if (np->rxopt.all) -@@ -598,7 +598,7 @@ int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, - sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source, - inet6_iif(skb), inet6_sdif(skb), udptable, NULL); - -- if (!sk || udp_sk(sk)->encap_type) { -+ if (!sk || READ_ONCE(udp_sk(sk)->encap_type)) { - /* No socket for error: try tunnels before discarding */ - if (static_branch_unlikely(&udpv6_encap_needed_key)) { - sk = __udp6_lib_err_encap(net, hdr, offset, uh, -@@ -712,7 +712,8 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) - } - nf_reset_ct(skb); - -- if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) { -+ if (static_branch_unlikely(&udpv6_encap_needed_key) && -+ READ_ONCE(up->encap_type)) { - int (*encap_rcv)(struct sock *sk, struct sk_buff *skb); - - /* -@@ -882,7 +883,7 @@ start_lookup: - /* If zero checksum and no_check is not on for - * the socket then skip it. - */ -- if (!uh->check && !udp_sk(sk)->no_check6_rx) -+ if (!uh->check && !udp_get_no_check6_rx(sk)) - continue; - if (!first) { - first = sk; -@@ -1000,7 +1001,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - if (unlikely(rcu_dereference(sk->sk_rx_dst) != dst)) - udp6_sk_rx_dst_set(sk, dst); - -- if (!uh->check && !udp_sk(sk)->no_check6_rx) { -+ if (!uh->check && !udp_get_no_check6_rx(sk)) { - if (refcounted) - sock_put(sk); - goto report_csum_error; -@@ -1022,7 +1023,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, - /* Unicast */ - sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable); - if (sk) { -- if (!uh->check && !udp_sk(sk)->no_check6_rx) -+ if (!uh->check && !udp_get_no_check6_rx(sk)) - goto report_csum_error; - return udp6_unicast_rcv_skb(sk, skb, uh); - } -@@ -1260,7 +1261,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, - kfree_skb(skb); - return -EINVAL; - } -- if (udp_sk(sk)->no_check6_tx) { -+ if (udp_get_no_check6_tx(sk)) { - kfree_skb(skb); - return -EINVAL; - } -@@ -1281,7 +1282,7 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, - - if (is_udplite) - csum = udplite_csum(skb); -- else if (udp_sk(sk)->no_check6_tx) { /* UDP csum disabled */ -+ else if (udp_get_no_check6_tx(sk)) { /* UDP csum disabled */ - skb->ip_summed = CHECKSUM_NONE; - goto send; - } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */ -@@ -1351,14 +1352,14 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - int addr_len = msg->msg_namelen; - bool connected = false; - int ulen = len; -- int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE; -+ int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE; - int err; - int is_udplite = IS_UDPLITE(sk); - int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); - - ipcm6_init(&ipc6); - ipc6.gso_size = READ_ONCE(up->gso_size); -- ipc6.sockc.tsflags = sk->sk_tsflags; -+ ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags); - ipc6.sockc.mark = READ_ONCE(sk->sk_mark); - - /* destination address check */ -@@ -1657,6 +1658,20 @@ do_confirm: - goto out; - } - -+static void udpv6_splice_eof(struct socket *sock) -+{ -+ struct sock *sk = sock->sk; -+ struct udp_sock *up = udp_sk(sk); -+ -+ if (!up->pending || udp_test_bit(CORK, sk)) -+ return; -+ -+ lock_sock(sk); -+ if (up->pending && !udp_test_bit(CORK, sk)) -+ udp_v6_push_pending_frames(sk); -+ release_sock(sk); -+} -+ - void udpv6_destroy_sock(struct sock *sk) - { - struct udp_sock *up = udp_sk(sk); -@@ -1674,7 +1689,7 @@ void udpv6_destroy_sock(struct sock *sk) - if (encap_destroy) - encap_destroy(sk); - } -- if (up->encap_enabled) { -+ if (udp_test_bit(ENCAP_ENABLED, sk)) { - static_branch_dec(&udpv6_encap_needed_key); - udp_encap_disable(); - } -@@ -1768,6 +1783,7 @@ struct proto udpv6_prot = { - .getsockopt = udpv6_getsockopt, - .sendmsg = udpv6_sendmsg, - .recvmsg = udpv6_recvmsg, -+ .splice_eof = udpv6_splice_eof, - .release_cb = ip6_datagram_release_cb, - .hash = udp_lib_hash, - .unhash = udp_lib_unhash, -diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c -index 4907ab241d6be..4156387248e40 100644 ---- a/net/ipv6/xfrm6_input.c -+++ b/net/ipv6/xfrm6_input.c -@@ -81,14 +81,14 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) - struct ipv6hdr *ip6h; - int len; - int ip6hlen = sizeof(struct ipv6hdr); -- - __u8 *udpdata; - __be32 *udpdata32; -- __u16 encap_type = up->encap_type; -+ u16 encap_type; - - if (skb->protocol == htons(ETH_P_IP)) - return xfrm4_udp_encap_rcv(sk, skb); - -+ encap_type = READ_ONCE(up->encap_type); - /* if this is not encapsulated socket, then just return now */ - if (!encap_type) - return 1; -diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c -index 03608d3ded4b8..8d21ff25f1602 100644 ---- a/net/l2tp/l2tp_core.c -+++ b/net/l2tp/l2tp_core.c -@@ -1139,9 +1139,9 @@ static void l2tp_tunnel_destruct(struct sock *sk) - switch (tunnel->encap) { - case L2TP_ENCAPTYPE_UDP: - /* No longer an encapsulation socket. See net/ipv4/udp.c */ -- (udp_sk(sk))->encap_type = 0; -- (udp_sk(sk))->encap_rcv = NULL; -- (udp_sk(sk))->encap_destroy = NULL; -+ WRITE_ONCE(udp_sk(sk)->encap_type, 0); -+ udp_sk(sk)->encap_rcv = NULL; -+ udp_sk(sk)->encap_destroy = NULL; - break; - case L2TP_ENCAPTYPE_IP: - break; -diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c -index d611783c2601f..8ed7769cae836 100644 ---- a/net/mptcp/subflow.c -+++ b/net/mptcp/subflow.c -@@ -1899,6 +1899,17 @@ static void tcp_release_cb_override(struct sock *ssk) - tcp_release_cb(ssk); - } - -+static int tcp_abort_override(struct sock *ssk, int err) -+{ -+ /* closing a listener subflow requires a great deal of care. -+ * keep it simple and just prevent such operation -+ */ -+ if (inet_sk_state_load(ssk) == TCP_LISTEN) -+ return -EINVAL; -+ -+ return tcp_abort(ssk, err); -+} -+ - static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = { - .name = "mptcp", - .owner = THIS_MODULE, -@@ -1942,6 +1953,7 @@ void __init mptcp_subflow_init(void) - - tcp_prot_override = tcp_prot; - tcp_prot_override.release_cb = tcp_release_cb_override; -+ tcp_prot_override.diag_destroy = tcp_abort_override; - - #if IS_ENABLED(CONFIG_MPTCP_IPV6) - /* In struct mptcp_subflow_request_sock, we assume the TCP request sock -@@ -1977,6 +1989,7 @@ void __init mptcp_subflow_init(void) - - tcpv6_prot_override = tcpv6_prot; - tcpv6_prot_override.release_cb = tcp_release_cb_override; -+ tcpv6_prot_override.diag_destroy = tcp_abort_override; - #endif - - mptcp_diag_subflow_init(&subflow_ulp_ops); -diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c -index 7243079ef3546..b452eb3ddcecb 100644 ---- a/net/netfilter/ipvs/ip_vs_xmit.c -+++ b/net/netfilter/ipvs/ip_vs_xmit.c -@@ -994,7 +994,7 @@ ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af, - old_dsfield = ipv4_get_dsfield(old_iph); - *ttl = old_iph->ttl; - if (payload_len) -- *payload_len = ntohs(old_iph->tot_len); -+ *payload_len = skb_ip_totlen(skb); - } - - /* Implement full-functionality option for ECN encapsulation */ -diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c -index 81c26a96c30bb..c1d99cb370b44 100644 ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -314,12 +314,12 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) - EXPORT_SYMBOL_GPL(flow_offload_add); - - void flow_offload_refresh(struct nf_flowtable *flow_table, -- struct flow_offload *flow) -+ struct flow_offload *flow, bool force) - { - u32 timeout; - - timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow); -- if (timeout - READ_ONCE(flow->timeout) > HZ) -+ if (force || timeout - READ_ONCE(flow->timeout) > HZ) - WRITE_ONCE(flow->timeout, timeout); - else - return; -@@ -416,11 +416,18 @@ nf_flow_table_iterate(struct nf_flowtable *flow_table, - return err; - } - -+static bool nf_flow_custom_gc(struct nf_flowtable *flow_table, -+ const struct flow_offload *flow) -+{ -+ return flow_table->type->gc && flow_table->type->gc(flow); -+} -+ - static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table, - struct flow_offload *flow, void *data) - { - if (nf_flow_has_expired(flow) || -- nf_ct_is_dying(flow->ct)) -+ nf_ct_is_dying(flow->ct) || -+ nf_flow_custom_gc(flow_table, flow)) - flow_offload_teardown(flow); - - if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) { -diff --git a/net/netfilter/nf_flow_table_inet.c b/net/netfilter/nf_flow_table_inet.c -index 0ccabf3fa6aa3..9505f9d188ff2 100644 ---- a/net/netfilter/nf_flow_table_inet.c -+++ b/net/netfilter/nf_flow_table_inet.c -@@ -39,7 +39,7 @@ nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb, - } - - static int nf_flow_rule_route_inet(struct net *net, -- const struct flow_offload *flow, -+ struct flow_offload *flow, - enum flow_offload_tuple_dir dir, - struct nf_flow_rule *flow_rule) - { -diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c -index b350fe9d00b0b..6feaac9ab05c8 100644 ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -384,7 +384,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, - if (skb_try_make_writable(skb, thoff + hdrsize)) - return NF_DROP; - -- flow_offload_refresh(flow_table, flow); -+ flow_offload_refresh(flow_table, flow, false); - - nf_flow_encap_pop(skb, tuplehash); - thoff -= offset; -@@ -646,7 +646,7 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, - if (skb_try_make_writable(skb, thoff + hdrsize)) - return NF_DROP; - -- flow_offload_refresh(flow_table, flow); -+ flow_offload_refresh(flow_table, flow, false); - - nf_flow_encap_pop(skb, tuplehash); - -diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c -index 4d9b99abe37d6..1c26f03fc6617 100644 ---- a/net/netfilter/nf_flow_table_offload.c -+++ b/net/netfilter/nf_flow_table_offload.c -@@ -679,7 +679,7 @@ nf_flow_rule_route_common(struct net *net, const struct flow_offload *flow, - return 0; - } - --int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow, -+int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow, - enum flow_offload_tuple_dir dir, - struct nf_flow_rule *flow_rule) - { -@@ -704,7 +704,7 @@ int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow, - } - EXPORT_SYMBOL_GPL(nf_flow_rule_route_ipv4); - --int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow, -+int nf_flow_rule_route_ipv6(struct net *net, struct flow_offload *flow, - enum flow_offload_tuple_dir dir, - struct nf_flow_rule *flow_rule) - { -@@ -735,7 +735,7 @@ nf_flow_offload_rule_alloc(struct net *net, - { - const struct nf_flowtable *flowtable = offload->flowtable; - const struct flow_offload_tuple *tuple, *other_tuple; -- const struct flow_offload *flow = offload->flow; -+ struct flow_offload *flow = offload->flow; - struct dst_entry *other_dst = NULL; - struct nf_flow_rule *flow_rule; - int err = -ENOMEM; -@@ -895,8 +895,9 @@ static int flow_offload_rule_add(struct flow_offload_work *offload, - - ok_count += flow_offload_tuple_add(offload, flow_rule[0], - FLOW_OFFLOAD_DIR_ORIGINAL); -- ok_count += flow_offload_tuple_add(offload, flow_rule[1], -- FLOW_OFFLOAD_DIR_REPLY); -+ if (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags)) -+ ok_count += flow_offload_tuple_add(offload, flow_rule[1], -+ FLOW_OFFLOAD_DIR_REPLY); - if (ok_count == 0) - return -ENOENT; - -@@ -926,7 +927,8 @@ static void flow_offload_work_del(struct flow_offload_work *offload) - { - clear_bit(IPS_HW_OFFLOAD_BIT, &offload->flow->ct->status); - flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL); -- flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY); -+ if (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags)) -+ flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY); - set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags); - } - -@@ -946,7 +948,9 @@ static void flow_offload_work_stats(struct flow_offload_work *offload) - u64 lastused; - - flow_offload_tuple_stats(offload, FLOW_OFFLOAD_DIR_ORIGINAL, &stats[0]); -- flow_offload_tuple_stats(offload, FLOW_OFFLOAD_DIR_REPLY, &stats[1]); -+ if (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags)) -+ flow_offload_tuple_stats(offload, FLOW_OFFLOAD_DIR_REPLY, -+ &stats[1]); - - lastused = max_t(u64, stats[0].lastused, stats[1].lastused); - offload->flow->timeout = max_t(u64, offload->flow->timeout, -diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c -index cb894f0d63e9d..c66689ad2b491 100644 ---- a/net/netfilter/nf_log_syslog.c -+++ b/net/netfilter/nf_log_syslog.c -@@ -322,7 +322,7 @@ dump_ipv4_packet(struct net *net, struct nf_log_buf *m, - - /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */ - nf_log_buf_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", -- ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK, -+ iph_totlen(skb, ih), ih->tos & IPTOS_TOS_MASK, - ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id)); - - /* Max length: 6 "CE DF MF " */ -diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c -index cee3e4e905ec8..e0c117229ee9d 100644 ---- a/net/netfilter/nf_tables_core.c -+++ b/net/netfilter/nf_tables_core.c -@@ -141,7 +141,7 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr, - else { - if (!(pkt->flags & NFT_PKTINFO_L4PROTO)) - return false; -- ptr = skb_network_header(skb) + nft_thoff(pkt); -+ ptr = skb->data + nft_thoff(pkt); - } - - ptr += priv->offset; -diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c -index 5f59dbab3e933..55fcf0280c5c3 100644 ---- a/net/netfilter/nft_immediate.c -+++ b/net/netfilter/nft_immediate.c -@@ -78,7 +78,7 @@ static int nft_immediate_init(const struct nft_ctx *ctx, - case NFT_GOTO: - err = nf_tables_bind_chain(ctx, chain); - if (err < 0) -- return err; -+ goto err1; - break; - default: - break; -diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c -index 9fbfad13176f0..ca730cedb5d41 100644 ---- a/net/netfilter/xt_length.c -+++ b/net/netfilter/xt_length.c -@@ -21,7 +21,7 @@ static bool - length_mt(const struct sk_buff *skb, struct xt_action_param *par) - { - const struct xt_length_info *info = par->matchinfo; -- u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len); -+ u32 pktlen = skb_ip_totlen(skb); - - return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; - } -diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c -index 1dac28136e6a3..18be13fb9b75a 100644 ---- a/net/nfc/llcp_core.c -+++ b/net/nfc/llcp_core.c -@@ -145,6 +145,13 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device, - - static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) - { -+ /* Since using nfc_llcp_local may result in usage of nfc_dev, whenever -+ * we hold a reference to local, we also need to hold a reference to -+ * the device to avoid UAF. -+ */ -+ if (!nfc_get_device(local->dev->idx)) -+ return NULL; -+ - kref_get(&local->ref); - - return local; -@@ -177,10 +184,18 @@ static void local_release(struct kref *ref) - - int nfc_llcp_local_put(struct nfc_llcp_local *local) - { -+ struct nfc_dev *dev; -+ int ret; -+ - if (local == NULL) - return 0; - -- return kref_put(&local->ref, local_release); -+ dev = local->dev; -+ -+ ret = kref_put(&local->ref, local_release); -+ nfc_put_device(dev); -+ -+ return ret; - } - - static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, -@@ -959,8 +974,17 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, - } - - new_sock = nfc_llcp_sock(new_sk); -- new_sock->dev = local->dev; -+ - new_sock->local = nfc_llcp_local_get(local); -+ if (!new_sock->local) { -+ reason = LLCP_DM_REJ; -+ sock_put(&new_sock->sk); -+ release_sock(&sock->sk); -+ sock_put(&sock->sk); -+ goto fail; -+ } -+ -+ new_sock->dev = local->dev; - new_sock->rw = sock->rw; - new_sock->miux = sock->miux; - new_sock->nfc_protocol = sock->nfc_protocol; -@@ -1597,7 +1621,16 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) - if (local == NULL) - return -ENOMEM; - -- local->dev = ndev; -+ /* As we are going to initialize local's refcount, we need to get the -+ * nfc_dev to avoid UAF, otherwise there is no point in continuing. -+ * See nfc_llcp_local_get(). -+ */ -+ local->dev = nfc_get_device(ndev->idx); -+ if (!local->dev) { -+ kfree(local); -+ return -ENODEV; -+ } -+ - INIT_LIST_HEAD(&local->list); - kref_init(&local->ref); - mutex_init(&local->sdp_lock); -diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c -index c8eaf4234b2e0..0591cfb289d50 100644 ---- a/net/openvswitch/conntrack.c -+++ b/net/openvswitch/conntrack.c -@@ -1252,7 +1252,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, - if (err) - return err; - -- nf_conn_act_ct_ext_add(ct); -+ nf_conn_act_ct_ext_add(skb, ct, ctinfo); - } else if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) && - labels_nonzero(&info->labels.mask)) { - err = ovs_ct_set_labels(ct, key, &info->labels.value, -diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c -index 4c7f7861ea967..d6d33f854050a 100644 ---- a/net/sched/act_ct.c -+++ b/net/sched/act_ct.c -@@ -168,11 +168,11 @@ tcf_ct_flow_table_add_action_nat_udp(const struct nf_conntrack_tuple *tuple, - - static void tcf_ct_flow_table_add_action_meta(struct nf_conn *ct, - enum ip_conntrack_dir dir, -+ enum ip_conntrack_info ctinfo, - struct flow_action *action) - { - struct nf_conn_labels *ct_labels; - struct flow_action_entry *entry; -- enum ip_conntrack_info ctinfo; - u32 *act_ct_labels; - - entry = tcf_ct_flow_table_flow_action_get_next(action); -@@ -180,8 +180,6 @@ static void tcf_ct_flow_table_add_action_meta(struct nf_conn *ct, - #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) - entry->ct_metadata.mark = READ_ONCE(ct->mark); - #endif -- ctinfo = dir == IP_CT_DIR_ORIGINAL ? IP_CT_ESTABLISHED : -- IP_CT_ESTABLISHED_REPLY; - /* aligns with the CT reference on the SKB nf_ct_set */ - entry->ct_metadata.cookie = (unsigned long)ct | ctinfo; - entry->ct_metadata.orig_dir = dir == IP_CT_DIR_ORIGINAL; -@@ -235,22 +233,26 @@ static int tcf_ct_flow_table_add_action_nat(struct net *net, - } - - static int tcf_ct_flow_table_fill_actions(struct net *net, -- const struct flow_offload *flow, -+ struct flow_offload *flow, - enum flow_offload_tuple_dir tdir, - struct nf_flow_rule *flow_rule) - { - struct flow_action *action = &flow_rule->rule->action; - int num_entries = action->num_entries; - struct nf_conn *ct = flow->ct; -+ enum ip_conntrack_info ctinfo; - enum ip_conntrack_dir dir; - int i, err; - - switch (tdir) { - case FLOW_OFFLOAD_DIR_ORIGINAL: - dir = IP_CT_DIR_ORIGINAL; -+ ctinfo = IP_CT_ESTABLISHED; -+ set_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags); - break; - case FLOW_OFFLOAD_DIR_REPLY: - dir = IP_CT_DIR_REPLY; -+ ctinfo = IP_CT_ESTABLISHED_REPLY; - break; - default: - return -EOPNOTSUPP; -@@ -260,7 +262,7 @@ static int tcf_ct_flow_table_fill_actions(struct net *net, - if (err) - goto err_nat; - -- tcf_ct_flow_table_add_action_meta(ct, dir, action); -+ tcf_ct_flow_table_add_action_meta(ct, dir, ctinfo, action); - return 0; - - err_nat: -@@ -272,8 +274,39 @@ err_nat: - return err; - } - -+static bool tcf_ct_flow_is_outdated(const struct flow_offload *flow) -+{ -+ return test_bit(IPS_SEEN_REPLY_BIT, &flow->ct->status) && -+ test_bit(IPS_HW_OFFLOAD_BIT, &flow->ct->status) && -+ !test_bit(NF_FLOW_HW_PENDING, &flow->flags) && -+ !test_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags); -+} -+ -+static void tcf_ct_flow_table_get_ref(struct tcf_ct_flow_table *ct_ft); -+ -+static void tcf_ct_nf_get(struct nf_flowtable *ft) -+{ -+ struct tcf_ct_flow_table *ct_ft = -+ container_of(ft, struct tcf_ct_flow_table, nf_ft); -+ -+ tcf_ct_flow_table_get_ref(ct_ft); -+} -+ -+static void tcf_ct_flow_table_put(struct tcf_ct_flow_table *ct_ft); -+ -+static void tcf_ct_nf_put(struct nf_flowtable *ft) -+{ -+ struct tcf_ct_flow_table *ct_ft = -+ container_of(ft, struct tcf_ct_flow_table, nf_ft); -+ -+ tcf_ct_flow_table_put(ct_ft); -+} -+ - static struct nf_flowtable_type flowtable_ct = { -+ .gc = tcf_ct_flow_is_outdated, - .action = tcf_ct_flow_table_fill_actions, -+ .get = tcf_ct_nf_get, -+ .put = tcf_ct_nf_put, - .owner = THIS_MODULE, - }; - -@@ -322,9 +355,13 @@ err_alloc: - return err; - } - -+static void tcf_ct_flow_table_get_ref(struct tcf_ct_flow_table *ct_ft) -+{ -+ refcount_inc(&ct_ft->ref); -+} -+ - static void tcf_ct_flow_table_cleanup_work(struct work_struct *work) - { -- struct flow_block_cb *block_cb, *tmp_cb; - struct tcf_ct_flow_table *ct_ft; - struct flow_block *block; - -@@ -332,24 +369,18 @@ static void tcf_ct_flow_table_cleanup_work(struct work_struct *work) - rwork); - nf_flow_table_free(&ct_ft->nf_ft); - -- /* Remove any remaining callbacks before cleanup */ - block = &ct_ft->nf_ft.flow_block; - down_write(&ct_ft->nf_ft.flow_block_lock); -- list_for_each_entry_safe(block_cb, tmp_cb, &block->cb_list, list) { -- list_del(&block_cb->list); -- flow_block_cb_free(block_cb); -- } -+ WARN_ON(!list_empty(&block->cb_list)); - up_write(&ct_ft->nf_ft.flow_block_lock); - kfree(ct_ft); - - module_put(THIS_MODULE); - } - --static void tcf_ct_flow_table_put(struct tcf_ct_params *params) -+static void tcf_ct_flow_table_put(struct tcf_ct_flow_table *ct_ft) - { -- struct tcf_ct_flow_table *ct_ft = params->ct_ft; -- -- if (refcount_dec_and_test(¶ms->ct_ft->ref)) { -+ if (refcount_dec_and_test(&ct_ft->ref)) { - rhashtable_remove_fast(&zones_ht, &ct_ft->node, zones_params); - INIT_RCU_WORK(&ct_ft->rwork, tcf_ct_flow_table_cleanup_work); - queue_rcu_work(act_ct_wq, &ct_ft->rwork); -@@ -363,9 +394,20 @@ static void tcf_ct_flow_tc_ifidx(struct flow_offload *entry, - entry->tuplehash[dir].tuple.tc.iifidx = act_ct_ext->ifindex[dir]; - } - -+static void tcf_ct_flow_ct_ext_ifidx_update(struct flow_offload *entry) -+{ -+ struct nf_conn_act_ct_ext *act_ct_ext; -+ -+ act_ct_ext = nf_conn_act_ct_ext_find(entry->ct); -+ if (act_ct_ext) { -+ tcf_ct_flow_tc_ifidx(entry, act_ct_ext, FLOW_OFFLOAD_DIR_ORIGINAL); -+ tcf_ct_flow_tc_ifidx(entry, act_ct_ext, FLOW_OFFLOAD_DIR_REPLY); -+ } -+} -+ - static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft, - struct nf_conn *ct, -- bool tcp) -+ bool tcp, bool bidirectional) - { - struct nf_conn_act_ct_ext *act_ct_ext; - struct flow_offload *entry; -@@ -384,6 +426,8 @@ static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft, - ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; - ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; - } -+ if (bidirectional) -+ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &entry->flags); - - act_ct_ext = nf_conn_act_ct_ext_find(ct); - if (act_ct_ext) { -@@ -407,26 +451,34 @@ static void tcf_ct_flow_table_process_conn(struct tcf_ct_flow_table *ct_ft, - struct nf_conn *ct, - enum ip_conntrack_info ctinfo) - { -- bool tcp = false; -- -- if ((ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) || -- !test_bit(IPS_ASSURED_BIT, &ct->status)) -- return; -+ bool tcp = false, bidirectional = true; - - switch (nf_ct_protonum(ct)) { - case IPPROTO_TCP: -- tcp = true; -- if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) -+ if ((ctinfo != IP_CT_ESTABLISHED && -+ ctinfo != IP_CT_ESTABLISHED_REPLY) || -+ !test_bit(IPS_ASSURED_BIT, &ct->status) || -+ ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) - return; -+ -+ tcp = true; - break; - case IPPROTO_UDP: -+ if (!nf_ct_is_confirmed(ct)) -+ return; -+ if (!test_bit(IPS_ASSURED_BIT, &ct->status)) -+ bidirectional = false; - break; - #ifdef CONFIG_NF_CT_PROTO_GRE - case IPPROTO_GRE: { - struct nf_conntrack_tuple *tuple; - -- if (ct->status & IPS_NAT_MASK) -+ if ((ctinfo != IP_CT_ESTABLISHED && -+ ctinfo != IP_CT_ESTABLISHED_REPLY) || -+ !test_bit(IPS_ASSURED_BIT, &ct->status) || -+ ct->status & IPS_NAT_MASK) - return; -+ - tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - /* No support for GRE v1 */ - if (tuple->src.u.gre.key || tuple->dst.u.gre.key) -@@ -442,7 +494,7 @@ static void tcf_ct_flow_table_process_conn(struct tcf_ct_flow_table *ct_ft, - ct->status & IPS_SEQ_ADJUST) - return; - -- tcf_ct_flow_table_add(ct_ft, ct, tcp); -+ tcf_ct_flow_table_add(ct_ft, ct, tcp, bidirectional); - } - - static bool -@@ -596,6 +648,7 @@ static bool tcf_ct_flow_table_lookup(struct tcf_ct_params *p, - struct flow_offload_tuple tuple = {}; - enum ip_conntrack_info ctinfo; - struct tcphdr *tcph = NULL; -+ bool force_refresh = false; - struct flow_offload *flow; - struct nf_conn *ct; - u8 dir; -@@ -621,15 +674,40 @@ static bool tcf_ct_flow_table_lookup(struct tcf_ct_params *p, - flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); - ct = flow->ct; - -+ if (dir == FLOW_OFFLOAD_DIR_REPLY && -+ !test_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags)) { -+ /* Only offload reply direction after connection became -+ * assured. -+ */ -+ if (test_bit(IPS_ASSURED_BIT, &ct->status)) -+ set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags); -+ else if (test_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags)) -+ /* If flow_table flow has already been updated to the -+ * established state, then don't refresh. -+ */ -+ return false; -+ force_refresh = true; -+ } -+ - if (tcph && (unlikely(tcph->fin || tcph->rst))) { - flow_offload_teardown(flow); - return false; - } - -- ctinfo = dir == FLOW_OFFLOAD_DIR_ORIGINAL ? IP_CT_ESTABLISHED : -- IP_CT_ESTABLISHED_REPLY; -+ if (dir == FLOW_OFFLOAD_DIR_ORIGINAL) -+ ctinfo = test_bit(IPS_SEEN_REPLY_BIT, &ct->status) ? -+ IP_CT_ESTABLISHED : IP_CT_NEW; -+ else -+ ctinfo = IP_CT_ESTABLISHED_REPLY; -+ -+ nf_conn_act_ct_ext_fill(skb, ct, ctinfo); -+ tcf_ct_flow_ct_ext_ifidx_update(flow); -+ flow_offload_refresh(nf_ft, flow, force_refresh); -+ if (!test_bit(IPS_ASSURED_BIT, &ct->status)) { -+ /* Process this flow in SW to allow promoting to ASSURED */ -+ return false; -+ } - -- flow_offload_refresh(nf_ft, flow); - nf_conntrack_get(&ct->ct_general); - nf_ct_set(skb, ct, ctinfo); - if (nf_ft->flags & NF_FLOWTABLE_COUNTER) -@@ -832,18 +910,23 @@ out_free: - return err; - } - --static void tcf_ct_params_free(struct rcu_head *head) -+static void tcf_ct_params_free(struct tcf_ct_params *params) - { -- struct tcf_ct_params *params = container_of(head, -- struct tcf_ct_params, rcu); -- -- tcf_ct_flow_table_put(params); -- -+ if (params->ct_ft) -+ tcf_ct_flow_table_put(params->ct_ft); - if (params->tmpl) - nf_ct_put(params->tmpl); - kfree(params); - } - -+static void tcf_ct_params_free_rcu(struct rcu_head *head) -+{ -+ struct tcf_ct_params *params; -+ -+ params = container_of(head, struct tcf_ct_params, rcu); -+ tcf_ct_params_free(params); -+} -+ - #if IS_ENABLED(CONFIG_NF_NAT) - /* Modelled after nf_nat_ipv[46]_fn(). - * range is only used for new, uninitialized NAT state. -@@ -1121,7 +1204,7 @@ do_nat: - tcf_ct_act_set_labels(ct, p->labels, p->labels_mask); - - if (!nf_ct_is_confirmed(ct)) -- nf_conn_act_ct_ext_add(ct); -+ nf_conn_act_ct_ext_add(skb, ct, ctinfo); - - /* This will take care of sending queued events - * even if the connection is already confirmed. -@@ -1390,7 +1473,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, - - err = tcf_ct_flow_table_get(net, params); - if (err) -- goto cleanup_params; -+ goto cleanup; - - spin_lock_bh(&c->tcf_lock); - goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); -@@ -1401,17 +1484,15 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, - if (goto_ch) - tcf_chain_put_by_act(goto_ch); - if (params) -- call_rcu(¶ms->rcu, tcf_ct_params_free); -+ call_rcu(¶ms->rcu, tcf_ct_params_free_rcu); - - return res; - --cleanup_params: -- if (params->tmpl) -- nf_ct_put(params->tmpl); - cleanup: - if (goto_ch) - tcf_chain_put_by_act(goto_ch); -- kfree(params); -+ if (params) -+ tcf_ct_params_free(params); - tcf_idr_release(*a, bind); - return err; - } -@@ -1423,7 +1504,7 @@ static void tcf_ct_cleanup(struct tc_action *a) - - params = rcu_dereference_protected(c->params, 1); - if (params) -- call_rcu(¶ms->rcu, tcf_ct_params_free); -+ call_rcu(¶ms->rcu, tcf_ct_params_free_rcu); - } - - static int tcf_ct_dump_key_val(struct sk_buff *skb, -diff --git a/net/sched/em_text.c b/net/sched/em_text.c -index 6f3c1fb2fb44c..f176afb70559e 100644 ---- a/net/sched/em_text.c -+++ b/net/sched/em_text.c -@@ -97,8 +97,10 @@ retry: - - static void em_text_destroy(struct tcf_ematch *m) - { -- if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) -+ if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) { - textsearch_destroy(EM_TEXT_PRIV(m)->config); -+ kfree(EM_TEXT_PRIV(m)); -+ } - } - - static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) -diff --git a/net/smc/smc_diag.c b/net/smc/smc_diag.c -index 80ea7d954eceb..801044e7d1949 100644 ---- a/net/smc/smc_diag.c -+++ b/net/smc/smc_diag.c -@@ -153,8 +153,7 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb, - .lnk[0].link_id = link->link_id, - }; - -- memcpy(linfo.lnk[0].ibname, -- smc->conn.lgr->lnk[0].smcibdev->ibdev->name, -+ memcpy(linfo.lnk[0].ibname, link->smcibdev->ibdev->name, - sizeof(link->smcibdev->ibdev->name)); - smc_gid_be16_convert(linfo.lnk[0].gid, link->gid); - smc_gid_be16_convert(linfo.lnk[0].peer_gid, link->peer_gid); -diff --git a/net/socket.c b/net/socket.c -index 04cba91c7cbe5..639d76f20384e 100644 ---- a/net/socket.c -+++ b/net/socket.c -@@ -130,6 +130,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, - static ssize_t sock_splice_read(struct file *file, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, - unsigned int flags); -+static void sock_splice_eof(struct file *file); - - #ifdef CONFIG_PROC_FS - static void sock_show_fdinfo(struct seq_file *m, struct file *f) -@@ -164,6 +165,7 @@ static const struct file_operations socket_file_ops = { - .sendpage = sock_sendpage, - .splice_write = generic_splice_sendpage, - .splice_read = sock_splice_read, -+ .splice_eof = sock_splice_eof, - .show_fdinfo = sock_show_fdinfo, - }; - -@@ -740,6 +742,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg) - { - struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name; - struct sockaddr_storage address; -+ int save_len = msg->msg_namelen; - int ret; - - if (msg->msg_name) { -@@ -749,6 +752,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg) - - ret = __sock_sendmsg(sock, msg); - msg->msg_name = save_addr; -+ msg->msg_namelen = save_len; - - return ret; - } -@@ -826,7 +830,7 @@ static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp) - - static ktime_t get_timestamp(struct sock *sk, struct sk_buff *skb, int *if_index) - { -- bool cycles = sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC; -+ bool cycles = READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_BIND_PHC; - struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); - struct net_device *orig_dev; - ktime_t hwtstamp; -@@ -878,12 +882,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, - int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP); - int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW); - struct scm_timestamping_internal tss; -- - int empty = 1, false_tstamp = 0; - struct skb_shared_hwtstamps *shhwtstamps = - skb_hwtstamps(skb); - int if_index; - ktime_t hwtstamp; -+ u32 tsflags; - - /* Race occurred between timestamp enabling and packet - receiving. Fill in the current time for now. */ -@@ -925,11 +929,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, - } - - memset(&tss, 0, sizeof(tss)); -- if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) && -+ tsflags = READ_ONCE(sk->sk_tsflags); -+ if ((tsflags & SOF_TIMESTAMPING_SOFTWARE) && - ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0)) - empty = 0; - if (shhwtstamps && -- (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && -+ (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && - !skb_is_swtx_tstamp(skb, false_tstamp)) { - if_index = 0; - if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV) -@@ -937,14 +942,14 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, - else - hwtstamp = shhwtstamps->hwtstamp; - -- if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) -+ if (tsflags & SOF_TIMESTAMPING_BIND_PHC) - hwtstamp = ptp_convert_timestamp(&hwtstamp, -- sk->sk_bind_phc); -+ READ_ONCE(sk->sk_bind_phc)); - - if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) { - empty = 0; - -- if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && -+ if ((tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && - !skb_is_err_queue(skb)) - put_ts_pktinfo(msg, skb, if_index); - } -@@ -1088,6 +1093,14 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, - return sock->ops->splice_read(sock, ppos, pipe, len, flags); - } - -+static void sock_splice_eof(struct file *file) -+{ -+ struct socket *sock = file->private_data; -+ -+ if (sock->ops->splice_eof) -+ sock->ops->splice_eof(sock); -+} -+ - static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to) - { - struct file *file = iocb->ki_filp; -@@ -2128,6 +2141,7 @@ int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags, - msg.msg_name = (struct sockaddr *)&address; - msg.msg_namelen = addr_len; - } -+ flags &= ~MSG_INTERNAL_SENDMSG_FLAGS; - if (sock->file->f_flags & O_NONBLOCK) - flags |= MSG_DONTWAIT; - msg.msg_flags = flags; -@@ -2479,6 +2493,7 @@ static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys, - msg_sys->msg_control = ctl_buf; - msg_sys->msg_control_is_user = false; - } -+ flags &= ~MSG_INTERNAL_SENDMSG_FLAGS; - msg_sys->msg_flags = flags; - - if (sock->file->f_flags & O_NONBLOCK) -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index 6dbeb80073338..be2ed7b0fe21c 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -211,8 +211,6 @@ static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb) - } - #endif /* CONFIG_SECURITY_NETWORK */ - --#define unix_peer(sk) (unix_sk(sk)->peer) -- - static inline int unix_our_peer(struct sock *sk, struct sock *osk) - { - return unix_peer(osk) == sk; -diff --git a/net/unix/unix_bpf.c b/net/unix/unix_bpf.c -index 2f9d8271c6ec7..7ea7c3a0d0d06 100644 ---- a/net/unix/unix_bpf.c -+++ b/net/unix/unix_bpf.c -@@ -159,12 +159,17 @@ int unix_dgram_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool re - - int unix_stream_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) - { -+ struct sock *sk_pair; -+ - if (restore) { - sk->sk_write_space = psock->saved_write_space; - sock_replace_proto(sk, psock->sk_proto); - return 0; - } - -+ sk_pair = unix_peer(sk); -+ sock_hold(sk_pair); -+ psock->sk_pair = sk_pair; - unix_stream_bpf_check_needs_rebuild(psock->sk_proto); - sock_replace_proto(sk, &unix_stream_bpf_prot); - return 0; -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index a88ed60dcd96a..1c8ffc5cf97f6 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9581,6 +9581,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN), - SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), - SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), -+ SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT), - SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT), - SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), -@@ -9663,6 +9664,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), -+ SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), - SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), - SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), -@@ -9707,6 +9709,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8c70, "HP EliteBook 835 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), -+ SND_PCI_QUIRK(0x103c, 0x8c96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), -@@ -9904,6 +9907,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1558, 0xc019, "Clevo NH77D[BE]Q", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1558, 0xc022, "Clevo NH77[DC][QW]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), -+ SND_PCI_QUIRK(0x17aa, 0x3882, "Lenovo Yoga Pro 7 14APH8", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), - SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340), - SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), - SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), -diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c -index bf94838bdbefe..5c07a8ff0c9c0 100644 ---- a/sound/soc/fsl/fsl_rpmsg.c -+++ b/sound/soc/fsl/fsl_rpmsg.c -@@ -231,7 +231,7 @@ static int fsl_rpmsg_probe(struct platform_device *pdev) - ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, - &fsl_rpmsg_dai, 1); - if (ret) -- return ret; -+ goto err_pm_disable; - - rpmsg->card_pdev = platform_device_register_data(&pdev->dev, - "imx-audio-rpmsg", -@@ -241,16 +241,22 @@ static int fsl_rpmsg_probe(struct platform_device *pdev) - if (IS_ERR(rpmsg->card_pdev)) { - dev_err(&pdev->dev, "failed to register rpmsg card\n"); - ret = PTR_ERR(rpmsg->card_pdev); -- return ret; -+ goto err_pm_disable; - } - - return 0; -+ -+err_pm_disable: -+ pm_runtime_disable(&pdev->dev); -+ return ret; - } - - static int fsl_rpmsg_remove(struct platform_device *pdev) - { - struct fsl_rpmsg *rpmsg = platform_get_drvdata(pdev); - -+ pm_runtime_disable(&pdev->dev); -+ - if (rpmsg->card_pdev) - platform_device_unregister(rpmsg->card_pdev); - -diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c -index 094402470dc23..858b95b199dcb 100644 ---- a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c -+++ b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c -@@ -499,7 +499,7 @@ static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY_S("AUD_PAD_TOP", SUPPLY_SEQ_ADDA_AUD_PAD_TOP, -- 0, 0, 0, -+ AFE_AUD_PAD_TOP, RG_RX_FIFO_ON_SFT, 0, - mtk_adda_pad_top_event, - SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG, -diff --git a/sound/soc/meson/g12a-toacodec.c b/sound/soc/meson/g12a-toacodec.c -index ddc667956cf5e..8d8d848ebd58b 100644 ---- a/sound/soc/meson/g12a-toacodec.c -+++ b/sound/soc/meson/g12a-toacodec.c -@@ -71,6 +71,9 @@ static int g12a_toacodec_mux_put_enum(struct snd_kcontrol *kcontrol, - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int mux, reg; - -+ if (ucontrol->value.enumerated.item[0] >= e->items) -+ return -EINVAL; -+ - mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); - regmap_field_read(priv->field_dat_sel, ®); - -@@ -101,7 +104,7 @@ static int g12a_toacodec_mux_put_enum(struct snd_kcontrol *kcontrol, - - snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); - -- return 0; -+ return 1; - } - - static SOC_ENUM_SINGLE_DECL(g12a_toacodec_mux_enum, TOACODEC_CTRL0, -diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c -index 579a04ad4d197..154c324fdd42a 100644 ---- a/sound/soc/meson/g12a-tohdmitx.c -+++ b/sound/soc/meson/g12a-tohdmitx.c -@@ -45,6 +45,9 @@ static int g12a_tohdmitx_i2s_mux_put_enum(struct snd_kcontrol *kcontrol, - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int mux, changed; - -+ if (ucontrol->value.enumerated.item[0] >= e->items) -+ return -EINVAL; -+ - mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); - changed = snd_soc_component_test_bits(component, e->reg, - CTRL0_I2S_DAT_SEL, -@@ -93,6 +96,9 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol, - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int mux, changed; - -+ if (ucontrol->value.enumerated.item[0] >= e->items) -+ return -EINVAL; -+ - mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]); - changed = snd_soc_component_test_bits(component, TOHDMITX_CTRL0, - CTRL0_SPDIF_SEL, -@@ -112,7 +118,7 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol, - - snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); - -- return 0; -+ return 1; - } - - static SOC_ENUM_SINGLE_DECL(g12a_tohdmitx_spdif_mux_enum, TOHDMITX_CTRL0, -diff --git a/tools/testing/selftests/bpf/verifier/ld_imm64.c b/tools/testing/selftests/bpf/verifier/ld_imm64.c -index f9297900cea6d..78f19c255f20b 100644 ---- a/tools/testing/selftests/bpf/verifier/ld_imm64.c -+++ b/tools/testing/selftests/bpf/verifier/ld_imm64.c -@@ -9,8 +9,8 @@ - BPF_MOV64_IMM(BPF_REG_0, 2), - BPF_EXIT_INSN(), - }, -- .errstr = "invalid BPF_LD_IMM insn", -- .errstr_unpriv = "R1 pointer comparison", -+ .errstr = "jump into the middle of ldimm64 insn 1", -+ .errstr_unpriv = "jump into the middle of ldimm64 insn 1", - .result = REJECT, - }, - { -@@ -23,8 +23,8 @@ - BPF_LD_IMM64(BPF_REG_0, 1), - BPF_EXIT_INSN(), - }, -- .errstr = "invalid BPF_LD_IMM insn", -- .errstr_unpriv = "R1 pointer comparison", -+ .errstr = "jump into the middle of ldimm64 insn 1", -+ .errstr_unpriv = "jump into the middle of ldimm64 insn 1", - .result = REJECT, - }, - { -diff --git a/tools/testing/selftests/drivers/net/bonding/bond-arp-interval-causes-panic.sh b/tools/testing/selftests/drivers/net/bonding/bond-arp-interval-causes-panic.sh -index 71c00bfafbc99..2ff58fed76e28 100755 ---- a/tools/testing/selftests/drivers/net/bonding/bond-arp-interval-causes-panic.sh -+++ b/tools/testing/selftests/drivers/net/bonding/bond-arp-interval-causes-panic.sh -@@ -33,16 +33,16 @@ ip netns add "client" - ip link set dev link1_1 netns client down name eth0 - ip netns exec client ip link add dev bond0 down type bond mode 1 \ - miimon 100 all_slaves_active 1 --ip netns exec client ip link set dev eth0 down master bond0 -+ip netns exec client ip link set dev eth0 master bond0 - ip netns exec client ip link set dev bond0 up - ip netns exec client ip addr add ${client_ip4}/24 dev bond0 - ip netns exec client ping -c 5 $server_ip4 >/dev/null - --ip netns exec client ip link set dev eth0 down nomaster -+ip netns exec client ip link set dev eth0 nomaster - ip netns exec client ip link set dev bond0 down - ip netns exec client ip link set dev bond0 type bond mode 0 \ - arp_interval 1000 arp_ip_target "+${server_ip4}" --ip netns exec client ip link set dev eth0 down master bond0 -+ip netns exec client ip link set dev eth0 master bond0 - ip netns exec client ip link set dev bond0 up - ip netns exec client ping -c 5 $server_ip4 >/dev/null - -diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh -index e52d513009fb0..2107579e2939d 100755 ---- a/tools/testing/selftests/net/mptcp/mptcp_join.sh -+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh -@@ -2167,9 +2167,9 @@ link_failure_tests() - pm_nl_set_limits $ns1 0 2 - pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal - pm_nl_set_limits $ns2 1 2 -- FAILING_LINKS="1" - pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup -- run_tests $ns1 $ns2 10.0.1.1 1 -+ FAILING_LINKS="1" \ -+ run_tests $ns1 $ns2 10.0.1.1 1 - chk_join_nr 2 2 2 - chk_add_nr 1 1 - chk_link_usage $ns2 ns2eth3 $cinsent 0 -@@ -2183,8 +2183,8 @@ link_failure_tests() - pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal - pm_nl_set_limits $ns2 1 2 - pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup -- FAILING_LINKS="1 2" -- run_tests $ns1 $ns2 10.0.1.1 1 -+ FAILING_LINKS="1 2" \ -+ run_tests $ns1 $ns2 10.0.1.1 1 - chk_join_nr 2 2 2 - chk_add_nr 1 1 - chk_stale_nr $ns2 2 4 2 -@@ -2199,8 +2199,8 @@ link_failure_tests() - pm_nl_add_endpoint $ns1 10.0.2.1 dev ns1eth2 flags signal - pm_nl_set_limits $ns2 1 3 - pm_nl_add_endpoint $ns2 10.0.3.2 dev ns2eth3 flags subflow,backup -- FAILING_LINKS="1 2" -- run_tests $ns1 $ns2 10.0.1.1 2 -+ FAILING_LINKS="1 2" \ -+ run_tests $ns1 $ns2 10.0.1.1 2 - chk_join_nr 2 2 2 - chk_add_nr 1 1 - chk_stale_nr $ns2 1 -1 2 -@@ -3041,7 +3041,7 @@ fastclose_tests() - - if reset_check_counter "fastclose server test" "MPTcpExtMPFastcloseRx"; then - run_tests $ns1 $ns2 10.0.1.1 1024 0 fastclose_server -- chk_join_nr 0 0 0 -+ chk_join_nr 0 0 0 0 0 0 1 - chk_fclose_nr 1 1 invert - chk_rst_nr 1 1 - fi -diff --git a/tools/testing/selftests/vm/memfd_secret.c b/tools/testing/selftests/vm/memfd_secret.c -index 957b9e18c7295..9b298f6a04b37 100644 ---- a/tools/testing/selftests/vm/memfd_secret.c -+++ b/tools/testing/selftests/vm/memfd_secret.c -@@ -62,6 +62,9 @@ static void test_mlock_limit(int fd) - char *mem; - - len = mlock_limit_cur; -+ if (len % page_size != 0) -+ len = (len/page_size) * page_size; -+ - mem = mmap(NULL, len, prot, mode, fd, 0); - if (mem == MAP_FAILED) { - fail("unable to mmap secret memory\n"); diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.72-73.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.72-73.patch deleted file mode 100644 index feadcd413e6f..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.72-73.patch +++ /dev/null @@ -1,294 +0,0 @@ -diff --git a/Makefile b/Makefile -index bad3387b3251c..e4f2d019ca745 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 72 -+SUBLEVEL = 73 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c -index b3b4542e31ed5..573de0d49e172 100644 ---- a/fs/nfsd/nfsctl.c -+++ b/fs/nfsd/nfsctl.c -@@ -716,10 +716,8 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred - - err = svc_addsock(nn->nfsd_serv, net, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred); - -- if (err < 0 && !nn->nfsd_serv->sv_nrthreads && !nn->keep_active) -- nfsd_last_thread(net); -- else if (err >= 0 && -- !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) -+ if (err >= 0 && -+ !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) - svc_get(nn->nfsd_serv); - - nfsd_put(net); -@@ -769,9 +767,6 @@ out_close: - svc_xprt_put(xprt); - } - out_err: -- if (!nn->nfsd_serv->sv_nrthreads && !nn->keep_active) -- nfsd_last_thread(net); -- - nfsd_put(net); - return err; - } -diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h -index 53166cce7062c..09726c5b9a317 100644 ---- a/fs/nfsd/nfsd.h -+++ b/fs/nfsd/nfsd.h -@@ -97,12 +97,7 @@ int nfsd_pool_stats_open(struct inode *, struct file *); - int nfsd_pool_stats_release(struct inode *, struct file *); - void nfsd_shutdown_threads(struct net *net); - --static inline void nfsd_put(struct net *net) --{ -- struct nfsd_net *nn = net_generic(net, nfsd_net_id); -- -- svc_put(nn->nfsd_serv); --} -+void nfsd_put(struct net *net); - - bool i_am_nfsd(void); - -@@ -139,7 +134,6 @@ int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change); - int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change); - void nfsd_reset_versions(struct nfsd_net *nn); - int nfsd_create_serv(struct net *net); --void nfsd_last_thread(struct net *net); - - extern int nfsd_max_blksize; - -diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c -index 350c6c72f793f..c7695ebd28dc3 100644 ---- a/fs/nfsd/nfssvc.c -+++ b/fs/nfsd/nfssvc.c -@@ -523,14 +523,9 @@ static struct notifier_block nfsd_inet6addr_notifier = { - /* Only used under nfsd_mutex, so this atomic may be overkill: */ - static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0); - --void nfsd_last_thread(struct net *net) -+static void nfsd_last_thread(struct svc_serv *serv, struct net *net) - { - struct nfsd_net *nn = net_generic(net, nfsd_net_id); -- struct svc_serv *serv = nn->nfsd_serv; -- -- spin_lock(&nfsd_notifier_lock); -- nn->nfsd_serv = NULL; -- spin_unlock(&nfsd_notifier_lock); - - /* check if the notifier still has clients */ - if (atomic_dec_return(&nfsd_notifier_refcount) == 0) { -@@ -540,8 +535,6 @@ void nfsd_last_thread(struct net *net) - #endif - } - -- svc_xprt_destroy_all(serv, net); -- - /* - * write_ports can create the server without actually starting - * any threads--if we get shut down before any threads are -@@ -632,8 +625,7 @@ void nfsd_shutdown_threads(struct net *net) - svc_get(serv); - /* Kill outstanding nfsd threads */ - svc_set_num_threads(serv, NULL, 0); -- nfsd_last_thread(net); -- svc_put(serv); -+ nfsd_put(net); - mutex_unlock(&nfsd_mutex); - } - -@@ -663,6 +655,9 @@ int nfsd_create_serv(struct net *net) - serv->sv_maxconn = nn->max_connections; - error = svc_bind(serv, net); - if (error < 0) { -+ /* NOT nfsd_put() as notifiers (see below) haven't -+ * been set up yet. -+ */ - svc_put(serv); - return error; - } -@@ -705,6 +700,29 @@ int nfsd_get_nrthreads(int n, int *nthreads, struct net *net) - return 0; - } - -+/* This is the callback for kref_put() below. -+ * There is no code here as the first thing to be done is -+ * call svc_shutdown_net(), but we cannot get the 'net' from -+ * the kref. So do all the work when kref_put returns true. -+ */ -+static void nfsd_noop(struct kref *ref) -+{ -+} -+ -+void nfsd_put(struct net *net) -+{ -+ struct nfsd_net *nn = net_generic(net, nfsd_net_id); -+ -+ if (kref_put(&nn->nfsd_serv->sv_refcnt, nfsd_noop)) { -+ svc_xprt_destroy_all(nn->nfsd_serv, net); -+ nfsd_last_thread(nn->nfsd_serv, net); -+ svc_destroy(&nn->nfsd_serv->sv_refcnt); -+ spin_lock(&nfsd_notifier_lock); -+ nn->nfsd_serv = NULL; -+ spin_unlock(&nfsd_notifier_lock); -+ } -+} -+ - int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) - { - int i = 0; -@@ -755,7 +773,7 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) - if (err) - break; - } -- svc_put(nn->nfsd_serv); -+ nfsd_put(net); - return err; - } - -@@ -770,7 +788,6 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) - int error; - bool nfsd_up_before; - struct nfsd_net *nn = net_generic(net, nfsd_net_id); -- struct svc_serv *serv; - - mutex_lock(&nfsd_mutex); - dprintk("nfsd: creating service\n"); -@@ -790,25 +807,22 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) - goto out; - - nfsd_up_before = nn->nfsd_net_up; -- serv = nn->nfsd_serv; - - error = nfsd_startup_net(net, cred); - if (error) - goto out_put; -- error = svc_set_num_threads(serv, NULL, nrservs); -+ error = svc_set_num_threads(nn->nfsd_serv, NULL, nrservs); - if (error) - goto out_shutdown; -- error = serv->sv_nrthreads; -- if (error == 0) -- nfsd_last_thread(net); -+ error = nn->nfsd_serv->sv_nrthreads; - out_shutdown: - if (error < 0 && !nfsd_up_before) - nfsd_shutdown_net(net); - out_put: - /* Threads now hold service active */ - if (xchg(&nn->keep_active, 0)) -- svc_put(serv); -- svc_put(serv); -+ nfsd_put(net); -+ nfsd_put(net); - out: - mutex_unlock(&nfsd_mutex); - return error; -diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c -index 2e15b182e59fc..7286a56aebfa9 100644 ---- a/fs/smb/client/cifsfs.c -+++ b/fs/smb/client/cifsfs.c -@@ -1240,7 +1240,7 @@ static int cifs_flush_folio(struct inode *inode, loff_t pos, loff_t *_fstart, lo - int rc = 0; - - folio = filemap_get_folio(inode->i_mapping, index); -- if (IS_ERR(folio)) -+ if (!folio) - return 0; - - size = folio_size(folio); -diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h -index 88ff7bb2bb9bd..632086b2f644a 100644 ---- a/include/net/dst_ops.h -+++ b/include/net/dst_ops.h -@@ -16,7 +16,7 @@ struct dst_ops { - unsigned short family; - unsigned int gc_thresh; - -- int (*gc)(struct dst_ops *ops); -+ void (*gc)(struct dst_ops *ops); - struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); - unsigned int (*default_advmss)(const struct dst_entry *); - unsigned int (*mtu)(const struct dst_entry *); -diff --git a/net/core/dst.c b/net/core/dst.c -index bc9c9be4e0801..d178c564138ee 100644 ---- a/net/core/dst.c -+++ b/net/core/dst.c -@@ -82,12 +82,8 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, - - if (ops->gc && - !(flags & DST_NOCOUNT) && -- dst_entries_get_fast(ops) > ops->gc_thresh) { -- if (ops->gc(ops)) { -- pr_notice_ratelimited("Route cache is full: consider increasing sysctl net.ipv6.route.max_size.\n"); -- return NULL; -- } -- } -+ dst_entries_get_fast(ops) > ops->gc_thresh) -+ ops->gc(ops); - - dst = kmem_cache_alloc(ops->kmem_cachep, GFP_ATOMIC); - if (!dst) -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 0bcdb675ba2c1..7f65dc750feb8 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -91,7 +91,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *); - static void ip6_dst_destroy(struct dst_entry *); - static void ip6_dst_ifdown(struct dst_entry *, - struct net_device *dev, int how); --static int ip6_dst_gc(struct dst_ops *ops); -+static void ip6_dst_gc(struct dst_ops *ops); - - static int ip6_pkt_discard(struct sk_buff *skb); - static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); -@@ -3288,11 +3288,10 @@ out: - return dst; - } - --static int ip6_dst_gc(struct dst_ops *ops) -+static void ip6_dst_gc(struct dst_ops *ops) - { - struct net *net = container_of(ops, struct net, ipv6.ip6_dst_ops); - int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval; -- int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size; - int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity; - int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout; - unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc; -@@ -3300,11 +3299,10 @@ static int ip6_dst_gc(struct dst_ops *ops) - int entries; - - entries = dst_entries_get_fast(ops); -- if (entries > rt_max_size) -+ if (entries > ops->gc_thresh) - entries = dst_entries_get_slow(ops); - -- if (time_after(rt_last_gc + rt_min_interval, jiffies) && -- entries <= rt_max_size) -+ if (time_after(rt_last_gc + rt_min_interval, jiffies)) - goto out; - - fib6_run_gc(atomic_inc_return(&net->ipv6.ip6_rt_gc_expire), net, true); -@@ -3314,7 +3312,6 @@ static int ip6_dst_gc(struct dst_ops *ops) - out: - val = atomic_read(&net->ipv6.ip6_rt_gc_expire); - atomic_set(&net->ipv6.ip6_rt_gc_expire, val - (val >> rt_elasticity)); -- return entries > rt_max_size; - } - - static int ip6_nh_lookup_table(struct net *net, struct fib6_config *cfg, -@@ -6517,7 +6514,7 @@ static int __net_init ip6_route_net_init(struct net *net) - #endif - - net->ipv6.sysctl.flush_delay = 0; -- net->ipv6.sysctl.ip6_rt_max_size = 4096; -+ net->ipv6.sysctl.ip6_rt_max_size = INT_MAX; - net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2; - net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ; - net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ; diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.73-74.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.73-74.patch deleted file mode 100644 index 4e3e51d3975c..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.73-74.patch +++ /dev/null @@ -1,3175 +0,0 @@ -diff --git a/Makefile b/Makefile -index e4f2d019ca745..63125d1ffd9cf 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 73 -+SUBLEVEL = 74 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c -index 3c1590c27fae3..723abcb10c801 100644 ---- a/arch/arc/kernel/signal.c -+++ b/arch/arc/kernel/signal.c -@@ -61,7 +61,7 @@ struct rt_sigframe { - unsigned int sigret_magic; - }; - --static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs) -+static int save_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs) - { - int err = 0; - #ifndef CONFIG_ISA_ARCOMPACT -@@ -74,12 +74,12 @@ static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs) - #else - v2abi.r58 = v2abi.r59 = 0; - #endif -- err = __copy_to_user(&mctx->v2abi, &v2abi, sizeof(v2abi)); -+ err = __copy_to_user(&mctx->v2abi, (void const *)&v2abi, sizeof(v2abi)); - #endif - return err; - } - --static int restore_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs) -+static int restore_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs) - { - int err = 0; - #ifndef CONFIG_ISA_ARCOMPACT -diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c -index b2f5f4f28705f..f779e386b6e7d 100644 ---- a/arch/arm/mach-sunxi/mc_smp.c -+++ b/arch/arm/mach-sunxi/mc_smp.c -@@ -804,12 +804,12 @@ static int __init sunxi_mc_smp_init(void) - for (i = 0; i < ARRAY_SIZE(sunxi_mc_smp_data); i++) { - ret = of_property_match_string(node, "enable-method", - sunxi_mc_smp_data[i].enable_method); -- if (!ret) -+ if (ret >= 0) - break; - } - - of_node_put(node); -- if (ret) -+ if (ret < 0) - return -ENODEV; - - is_a83t = sunxi_mc_smp_data[i].is_a83t; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi -index ee6095baba4d3..7d9b8064ad2ec 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi -@@ -510,8 +510,7 @@ ap_i2c_tp: &i2c5 { - &pci_rootport { - mvl_wifi: wifi@0,0 { - compatible = "pci1b4b,2b42"; -- reg = <0x83010000 0x0 0x00000000 0x0 0x00100000 -- 0x83010000 0x0 0x00100000 0x0 0x00100000>; -+ reg = <0x0000 0x0 0x0 0x0 0x0>; - interrupt-parent = <&gpio0>; - interrupts = <8 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts -index 853e88455e750..9e4b12ed62cbe 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts -+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts -@@ -34,8 +34,8 @@ - &pci_rootport { - wifi@0,0 { - compatible = "qcom,ath10k"; -- reg = <0x00010000 0x0 0x00000000 0x0 0x00000000>, -- <0x03010010 0x0 0x00000000 0x0 0x00200000>; -+ reg = <0x00000000 0x0 0x00000000 0x0 0x00000000>, -+ <0x03000010 0x0 0x00000000 0x0 0x00200000>; - qcom,ath10k-calibration-variant = "GO_DUMO"; - }; - }; -diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi -index 23bfba86daabe..7ba25315dd9ab 100644 ---- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi -@@ -489,6 +489,7 @@ ap_i2c_audio: &i2c8 { - #address-cells = <3>; - #size-cells = <2>; - ranges; -+ device_type = "pci"; - }; - }; - -diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi -index 234b5bbda1204..f4d6dbbbddcd4 100644 ---- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi -@@ -958,7 +958,7 @@ - , - , - ; -- interrupt-names = "sys", "pmc", "msi", "legacy", "err"; -+ interrupt-names = "sys", "pmc", "msg", "legacy", "err"; - bus-range = <0x0 0xf>; - clocks = <&cru ACLK_PCIE20_MST>, <&cru ACLK_PCIE20_SLV>, - <&cru ACLK_PCIE20_DBI>, <&cru PCLK_PCIE20>, -diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h -index b9a4ab54285c1..9b16a3b8e7060 100644 ---- a/arch/loongarch/include/asm/elf.h -+++ b/arch/loongarch/include/asm/elf.h -@@ -293,7 +293,7 @@ extern const char *__elf_platform; - #define ELF_PLAT_INIT(_r, load_addr) do { \ - _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \ - _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \ -- _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0; \ -+ _r->regs[9] = _r->regs[10] /* syscall n */ = _r->regs[12] = 0; \ - _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0; \ - _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0; \ - _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0; \ -diff --git a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi -index 8143a61111e33..c16b521308cb1 100644 ---- a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi -+++ b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi -@@ -123,8 +123,7 @@ - compatible = "pci0014,7a03.0", - "pci0014,7a03", - "pciclass0c0320", -- "pciclass0c03", -- "loongson, pci-gmac"; -+ "pciclass0c03"; - - reg = <0x1800 0x0 0x0 0x0 0x0>; - interrupts = <12 IRQ_TYPE_LEVEL_LOW>, -diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi -index 2f45fce2cdc4a..ed99ee316febb 100644 ---- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi -+++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi -@@ -186,8 +186,7 @@ - compatible = "pci0014,7a03.0", - "pci0014,7a03", - "pciclass020000", -- "pciclass0200", -- "loongson, pci-gmac"; -+ "pciclass0200"; - - reg = <0x1800 0x0 0x0 0x0 0x0>; - interrupts = <12 IRQ_TYPE_LEVEL_HIGH>, -diff --git a/block/blk-mq.c b/block/blk-mq.c -index 383d94615e502..368f1947c8956 100644 ---- a/block/blk-mq.c -+++ b/block/blk-mq.c -@@ -1500,14 +1500,26 @@ void blk_mq_delay_kick_requeue_list(struct request_queue *q, - } - EXPORT_SYMBOL(blk_mq_delay_kick_requeue_list); - -+static bool blk_is_flush_data_rq(struct request *rq) -+{ -+ return (rq->rq_flags & RQF_FLUSH_SEQ) && !is_flush_rq(rq); -+} -+ - static bool blk_mq_rq_inflight(struct request *rq, void *priv) - { - /* - * If we find a request that isn't idle we know the queue is busy - * as it's checked in the iter. - * Return false to stop the iteration. -+ * -+ * In case of queue quiesce, if one flush data request is completed, -+ * don't count it as inflight given the flush sequence is suspended, -+ * and the original flush data request is invisible to driver, just -+ * like other pending requests because of quiesce - */ -- if (blk_mq_request_started(rq)) { -+ if (blk_mq_request_started(rq) && !(blk_queue_quiesced(rq->q) && -+ blk_is_flush_data_rq(rq) && -+ blk_mq_request_completed(rq))) { - bool *busy = priv; - - *busy = true; -diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c -index c297e40c5bdc0..5ebeb0d7b6be0 100644 ---- a/drivers/acpi/resource.c -+++ b/drivers/acpi/resource.c -@@ -512,6 +512,13 @@ static const struct dmi_system_id maingear_laptop[] = { - DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"), - }, - }, -+ { -+ /* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Eluktronics Inc."), -+ DMI_MATCH(DMI_BOARD_NAME, "RP-15"), -+ }, -+ }, - { - /* TongFang GM6XGxX/TUXEDO Stellaris 16 Gen5 AMD */ - .matches = { -diff --git a/drivers/android/binder.c b/drivers/android/binder.c -index 9cc3a2b1b4fc1..d933ef6cc65af 100644 ---- a/drivers/android/binder.c -+++ b/drivers/android/binder.c -@@ -5005,7 +5005,7 @@ static __poll_t binder_poll(struct file *filp, - - thread = binder_get_thread(proc); - if (!thread) -- return POLLERR; -+ return EPOLLERR; - - binder_inner_proc_lock(thread->proc); - thread->looper |= BINDER_LOOPER_STATE_POLL; -diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c -index cd87f12733f27..ed607850f87fb 100644 ---- a/drivers/android/binder_alloc.c -+++ b/drivers/android/binder_alloc.c -@@ -557,7 +557,7 @@ err_alloc_buf_struct_failed: - * is the sum of the three given sizes (each rounded up to - * pointer-sized boundary) - * -- * Return: The allocated buffer or %NULL if error -+ * Return: The allocated buffer or %ERR_PTR(-errno) if error - */ - struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc, - size_t data_size, -@@ -706,7 +706,7 @@ void binder_alloc_free_buf(struct binder_alloc *alloc, - /* - * We could eliminate the call to binder_alloc_clear_buf() - * from binder_alloc_deferred_release() by moving this to -- * binder_alloc_free_buf_locked(). However, that could -+ * binder_free_buf_locked(). However, that could - * increase contention for the alloc mutex if clear_on_free - * is used frequently for large buffers. The mutex is not - * needed for correctness here. -@@ -1005,7 +1005,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item, - goto err_mmget; - if (!mmap_read_trylock(mm)) - goto err_mmap_read_lock_failed; -- vma = binder_alloc_get_vma(alloc); -+ vma = vma_lookup(mm, page_addr); -+ if (vma && vma != binder_alloc_get_vma(alloc)) -+ goto err_invalid_vma; - - list_lru_isolate(lru, item); - spin_unlock(lock); -@@ -1031,6 +1033,8 @@ enum lru_status binder_alloc_free_page(struct list_head *item, - mutex_unlock(&alloc->mutex); - return LRU_REMOVED_RETRY; - -+err_invalid_vma: -+ mmap_read_unlock(mm); - err_mmap_read_lock_failed: - mmput_async(mm); - err_mmget: -diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c -index efa5535a8e1d8..3124837aa406f 100644 ---- a/drivers/block/virtio_blk.c -+++ b/drivers/block/virtio_blk.c -@@ -609,12 +609,12 @@ static void virtblk_config_changed(struct virtio_device *vdev) - static int init_vq(struct virtio_blk *vblk) - { - int err; -- int i; -+ unsigned short i; - vq_callback_t **callbacks; - const char **names; - struct virtqueue **vqs; - unsigned short num_vqs; -- unsigned int num_poll_vqs; -+ unsigned short num_poll_vqs; - struct virtio_device *vdev = vblk->vdev; - struct irq_affinity desc = { 0, }; - -@@ -658,13 +658,13 @@ static int init_vq(struct virtio_blk *vblk) - - for (i = 0; i < num_vqs - num_poll_vqs; i++) { - callbacks[i] = virtblk_done; -- snprintf(vblk->vqs[i].name, VQ_NAME_LEN, "req.%d", i); -+ snprintf(vblk->vqs[i].name, VQ_NAME_LEN, "req.%u", i); - names[i] = vblk->vqs[i].name; - } - - for (; i < num_vqs; i++) { - callbacks[i] = NULL; -- snprintf(vblk->vqs[i].name, VQ_NAME_LEN, "req_poll.%d", i); -+ snprintf(vblk->vqs[i].name, VQ_NAME_LEN, "req_poll.%u", i); - names[i] = vblk->vqs[i].name; - } - -diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c -index aa53797dbfc14..7782785a86e69 100644 ---- a/drivers/clk/rockchip/clk-rk3128.c -+++ b/drivers/clk/rockchip/clk-rk3128.c -@@ -490,7 +490,7 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { - GATE(HCLK_I2S_2CH, "hclk_i2s_2ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), - GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 13, GFLAGS), - GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), -- GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 13, GFLAGS), -+ GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS), - GATE(0, "hclk_peri_ahb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 14, GFLAGS), - GATE(HCLK_SPDIF, "hclk_spdif", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), - GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 12, GFLAGS), -diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c -index 2f54f630c8b65..1ffb755feea4f 100644 ---- a/drivers/clk/rockchip/clk-rk3568.c -+++ b/drivers/clk/rockchip/clk-rk3568.c -@@ -72,6 +72,7 @@ static struct rockchip_pll_rate_table rk3568_pll_rates[] = { - RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), - RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), - RK3036_PLL_RATE(297000000, 2, 99, 4, 1, 1, 0), -+ RK3036_PLL_RATE(292500000, 1, 195, 4, 4, 1, 0), - RK3036_PLL_RATE(241500000, 2, 161, 4, 2, 1, 0), - RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), - RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0), -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -index fd796574f87a5..8123feb1a1161 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -@@ -479,6 +479,9 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, - if (size & 0x3 || *pos & 0x3) - return -EINVAL; - -+ if (!adev->didt_rreg) -+ return -EOPNOTSUPP; -+ - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); -@@ -535,6 +538,9 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user - if (size & 0x3 || *pos & 0x3) - return -EINVAL; - -+ if (!adev->didt_wreg) -+ return -EOPNOTSUPP; -+ - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); -diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c -index 2eddd7f6cd41e..811dd3ea63620 100644 ---- a/drivers/gpu/drm/amd/amdgpu/soc15.c -+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c -@@ -1411,9 +1411,11 @@ static void soc15_common_get_clockgating_state(void *handle, u64 *flags) - if (amdgpu_sriov_vf(adev)) - *flags = 0; - -- adev->nbio.funcs->get_clockgating_state(adev, flags); -+ if (adev->nbio.funcs && adev->nbio.funcs->get_clockgating_state) -+ adev->nbio.funcs->get_clockgating_state(adev, flags); - -- adev->hdp.funcs->get_clock_gating_state(adev, flags); -+ if (adev->hdp.funcs && adev->hdp.funcs->get_clock_gating_state) -+ adev->hdp.funcs->get_clock_gating_state(adev, flags); - - if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(13, 0, 2)) { - -@@ -1429,9 +1431,11 @@ static void soc15_common_get_clockgating_state(void *handle, u64 *flags) - } - - /* AMD_CG_SUPPORT_ROM_MGCG */ -- adev->smuio.funcs->get_clock_gating_state(adev, flags); -+ if (adev->smuio.funcs && adev->smuio.funcs->get_clock_gating_state) -+ adev->smuio.funcs->get_clock_gating_state(adev, flags); - -- adev->df.funcs->get_clockgating_state(adev, flags); -+ if (adev->df.funcs && adev->df.funcs->get_clockgating_state) -+ adev->df.funcs->get_clockgating_state(adev, flags); - } - - static int soc15_common_set_powergating_state(void *handle, -diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c -index e507d2e1410b7..93e40e0a15087 100644 ---- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c -+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c -@@ -1018,13 +1018,20 @@ static enum bp_result get_ss_info_v4_5( - DC_LOG_BIOS("AS_SIGNAL_TYPE_HDMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage); - break; - case AS_SIGNAL_TYPE_DISPLAY_PORT: -- ss_info->spread_spectrum_percentage = -+ if (bp->base.integrated_info) { -+ DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", bp->base.integrated_info->gpuclk_ss_percentage); -+ ss_info->spread_spectrum_percentage = -+ bp->base.integrated_info->gpuclk_ss_percentage; -+ ss_info->type.CENTER_MODE = -+ bp->base.integrated_info->gpuclk_ss_type; -+ } else { -+ ss_info->spread_spectrum_percentage = - disp_cntl_tbl->dp_ss_percentage; -- ss_info->spread_spectrum_range = -+ ss_info->spread_spectrum_range = - disp_cntl_tbl->dp_ss_rate_10hz * 10; -- if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) -- ss_info->type.CENTER_MODE = true; -- -+ if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) -+ ss_info->type.CENTER_MODE = true; -+ } - DC_LOG_BIOS("AS_SIGNAL_TYPE_DISPLAY_PORT ss_percentage: %d\n", ss_info->spread_spectrum_percentage); - break; - case AS_SIGNAL_TYPE_GPU_PLL: -@@ -2830,6 +2837,8 @@ static enum bp_result get_integrated_info_v2_2( - info->ma_channel_number = info_v2_2->umachannelnumber; - info->dp_ss_control = - le16_to_cpu(info_v2_2->reserved1); -+ info->gpuclk_ss_percentage = info_v2_2->gpuclk_ss_percentage; -+ info->gpuclk_ss_type = info_v2_2->gpuclk_ss_type; - - for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { - info->ext_disp_conn_info.gu_id[i] = -diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c -index 893991a0eb971..28b83133db910 100644 ---- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c -+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c -@@ -324,7 +324,7 @@ static struct wm_table lpddr5_wm_table = { - { - .wm_inst = WM_A, - .wm_type = WM_TYPE_PSTATE_CHG, -- .pstate_latency_us = 11.65333, -+ .pstate_latency_us = 129.0, - .sr_exit_time_us = 11.5, - .sr_enter_plus_exit_time_us = 14.5, - .valid = true, -@@ -332,7 +332,7 @@ static struct wm_table lpddr5_wm_table = { - { - .wm_inst = WM_B, - .wm_type = WM_TYPE_PSTATE_CHG, -- .pstate_latency_us = 11.65333, -+ .pstate_latency_us = 129.0, - .sr_exit_time_us = 11.5, - .sr_enter_plus_exit_time_us = 14.5, - .valid = true, -@@ -340,7 +340,7 @@ static struct wm_table lpddr5_wm_table = { - { - .wm_inst = WM_C, - .wm_type = WM_TYPE_PSTATE_CHG, -- .pstate_latency_us = 11.65333, -+ .pstate_latency_us = 129.0, - .sr_exit_time_us = 11.5, - .sr_enter_plus_exit_time_us = 14.5, - .valid = true, -@@ -348,7 +348,7 @@ static struct wm_table lpddr5_wm_table = { - { - .wm_inst = WM_D, - .wm_type = WM_TYPE_PSTATE_CHG, -- .pstate_latency_us = 11.65333, -+ .pstate_latency_us = 129.0, - .sr_exit_time_us = 11.5, - .sr_enter_plus_exit_time_us = 14.5, - .valid = true, -diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h -index bc96d02113608..813463ffe15c5 100644 ---- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h -+++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h -@@ -417,6 +417,8 @@ struct integrated_info { - /* V2.1 */ - struct edp_info edp1_info; - struct edp_info edp2_info; -+ uint32_t gpuclk_ss_percentage; -+ uint32_t gpuclk_ss_type; - }; - - /* -diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c -index df9bf3c9206e7..cb90e70d85e86 100644 ---- a/drivers/gpu/drm/drm_crtc.c -+++ b/drivers/gpu/drm/drm_crtc.c -@@ -715,8 +715,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, - struct drm_mode_set set; - uint32_t __user *set_connectors_ptr; - struct drm_modeset_acquire_ctx ctx; -- int ret; -- int i; -+ int ret, i, num_connectors = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EOPNOTSUPP; -@@ -871,6 +870,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, - connector->name); - - connector_set[i] = connector; -+ num_connectors++; - } - } - -@@ -879,7 +879,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, - set.y = crtc_req->y; - set.mode = mode; - set.connectors = connector_set; -- set.num_connectors = crtc_req->count_connectors; -+ set.num_connectors = num_connectors; - set.fb = fb; - - if (drm_drv_uses_atomic_modeset(dev)) -@@ -892,7 +892,7 @@ out: - drm_framebuffer_put(fb); - - if (connector_set) { -- for (i = 0; i < crtc_req->count_connectors; i++) { -+ for (i = 0; i < num_connectors; i++) { - if (connector_set[i]) - drm_connector_put(connector_set[i]); - } -diff --git a/drivers/gpu/drm/exynos/exynos_drm_dma.c b/drivers/gpu/drm/exynos/exynos_drm_dma.c -index a971590b81323..e2c7373f20c6b 100644 ---- a/drivers/gpu/drm/exynos/exynos_drm_dma.c -+++ b/drivers/gpu/drm/exynos/exynos_drm_dma.c -@@ -107,18 +107,16 @@ int exynos_drm_register_dma(struct drm_device *drm, struct device *dev, - return 0; - - if (!priv->mapping) { -- void *mapping; -+ void *mapping = NULL; - - if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) - mapping = arm_iommu_create_mapping(&platform_bus_type, - EXYNOS_DEV_ADDR_START, EXYNOS_DEV_ADDR_SIZE); - else if (IS_ENABLED(CONFIG_IOMMU_DMA)) - mapping = iommu_get_domain_for_dev(priv->dma_dev); -- else -- mapping = ERR_PTR(-ENODEV); - -- if (IS_ERR(mapping)) -- return PTR_ERR(mapping); -+ if (!mapping) -+ return -ENODEV; - priv->mapping = mapping; - } - -diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c -index b7c11bdce2c89..1a7194a653ae5 100644 ---- a/drivers/gpu/drm/exynos/exynos_hdmi.c -+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c -@@ -1861,6 +1861,8 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) - return ret; - - crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI); -+ if (IS_ERR(crtc)) -+ return PTR_ERR(crtc); - crtc->pipe_clk = &hdata->phy_clk; - - ret = hdmi_create_connector(encoder); -diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c -index 6cb5eefa45e9a..5a08458fe1b7f 100644 ---- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c -+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c -@@ -31,7 +31,7 @@ tu102_vmm_flush(struct nvkm_vmm *vmm, int depth) - - type |= 0x00000001; /* PAGE_ALL */ - if (atomic_read(&vmm->engref[NVKM_SUBDEV_BAR])) -- type |= 0x00000004; /* HUB_ONLY */ -+ type |= 0x00000006; /* HUB_ONLY | ALL PDB (hack) */ - - mutex_lock(&vmm->mmu->mutex); - -diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c -index 8a8a3dd8af0c1..df07e3ae0ffb4 100644 ---- a/drivers/hid/hid-nintendo.c -+++ b/drivers/hid/hid-nintendo.c -@@ -325,28 +325,28 @@ struct joycon_imu_cal { - * All the controller's button values are stored in a u32. - * They can be accessed with bitwise ANDs. - */ --static const u32 JC_BTN_Y = BIT(0); --static const u32 JC_BTN_X = BIT(1); --static const u32 JC_BTN_B = BIT(2); --static const u32 JC_BTN_A = BIT(3); --static const u32 JC_BTN_SR_R = BIT(4); --static const u32 JC_BTN_SL_R = BIT(5); --static const u32 JC_BTN_R = BIT(6); --static const u32 JC_BTN_ZR = BIT(7); --static const u32 JC_BTN_MINUS = BIT(8); --static const u32 JC_BTN_PLUS = BIT(9); --static const u32 JC_BTN_RSTICK = BIT(10); --static const u32 JC_BTN_LSTICK = BIT(11); --static const u32 JC_BTN_HOME = BIT(12); --static const u32 JC_BTN_CAP = BIT(13); /* capture button */ --static const u32 JC_BTN_DOWN = BIT(16); --static const u32 JC_BTN_UP = BIT(17); --static const u32 JC_BTN_RIGHT = BIT(18); --static const u32 JC_BTN_LEFT = BIT(19); --static const u32 JC_BTN_SR_L = BIT(20); --static const u32 JC_BTN_SL_L = BIT(21); --static const u32 JC_BTN_L = BIT(22); --static const u32 JC_BTN_ZL = BIT(23); -+#define JC_BTN_Y BIT(0) -+#define JC_BTN_X BIT(1) -+#define JC_BTN_B BIT(2) -+#define JC_BTN_A BIT(3) -+#define JC_BTN_SR_R BIT(4) -+#define JC_BTN_SL_R BIT(5) -+#define JC_BTN_R BIT(6) -+#define JC_BTN_ZR BIT(7) -+#define JC_BTN_MINUS BIT(8) -+#define JC_BTN_PLUS BIT(9) -+#define JC_BTN_RSTICK BIT(10) -+#define JC_BTN_LSTICK BIT(11) -+#define JC_BTN_HOME BIT(12) -+#define JC_BTN_CAP BIT(13) /* capture button */ -+#define JC_BTN_DOWN BIT(16) -+#define JC_BTN_UP BIT(17) -+#define JC_BTN_RIGHT BIT(18) -+#define JC_BTN_LEFT BIT(19) -+#define JC_BTN_SR_L BIT(20) -+#define JC_BTN_SL_L BIT(21) -+#define JC_BTN_L BIT(22) -+#define JC_BTN_ZL BIT(23) - - enum joycon_msg_type { - JOYCON_MSG_TYPE_NONE, -@@ -859,14 +859,27 @@ static int joycon_request_calibration(struct joycon_ctlr *ctlr) - */ - static void joycon_calc_imu_cal_divisors(struct joycon_ctlr *ctlr) - { -- int i; -+ int i, divz = 0; - - for (i = 0; i < 3; i++) { - ctlr->imu_cal_accel_divisor[i] = ctlr->accel_cal.scale[i] - - ctlr->accel_cal.offset[i]; - ctlr->imu_cal_gyro_divisor[i] = ctlr->gyro_cal.scale[i] - - ctlr->gyro_cal.offset[i]; -+ -+ if (ctlr->imu_cal_accel_divisor[i] == 0) { -+ ctlr->imu_cal_accel_divisor[i] = 1; -+ divz++; -+ } -+ -+ if (ctlr->imu_cal_gyro_divisor[i] == 0) { -+ ctlr->imu_cal_gyro_divisor[i] = 1; -+ divz++; -+ } - } -+ -+ if (divz) -+ hid_warn(ctlr->hdev, "inaccurate IMU divisors (%d)\n", divz); - } - - static const s16 DFLT_ACCEL_OFFSET /*= 0*/; -@@ -1095,16 +1108,16 @@ static void joycon_parse_imu_report(struct joycon_ctlr *ctlr, - JC_IMU_SAMPLES_PER_DELTA_AVG) { - ctlr->imu_avg_delta_ms = ctlr->imu_delta_samples_sum / - ctlr->imu_delta_samples_count; -- /* don't ever want divide by zero shenanigans */ -- if (ctlr->imu_avg_delta_ms == 0) { -- ctlr->imu_avg_delta_ms = 1; -- hid_warn(ctlr->hdev, -- "calculated avg imu delta of 0\n"); -- } - ctlr->imu_delta_samples_count = 0; - ctlr->imu_delta_samples_sum = 0; - } - -+ /* don't ever want divide by zero shenanigans */ -+ if (ctlr->imu_avg_delta_ms == 0) { -+ ctlr->imu_avg_delta_ms = 1; -+ hid_warn(ctlr->hdev, "calculated avg imu delta of 0\n"); -+ } -+ - /* useful for debugging IMU sample rate */ - hid_dbg(ctlr->hdev, - "imu_report: ms=%u last_ms=%u delta=%u avg_delta=%u\n", -diff --git a/drivers/hwmon/corsair-psu.c b/drivers/hwmon/corsair-psu.c -index 2210aa62e3d06..ec7f27a6ce016 100644 ---- a/drivers/hwmon/corsair-psu.c -+++ b/drivers/hwmon/corsair-psu.c -@@ -837,7 +837,23 @@ static struct hid_driver corsairpsu_driver = { - .reset_resume = corsairpsu_resume, - #endif - }; --module_hid_driver(corsairpsu_driver); -+ -+static int __init corsair_init(void) -+{ -+ return hid_register_driver(&corsairpsu_driver); -+} -+ -+static void __exit corsair_exit(void) -+{ -+ hid_unregister_driver(&corsairpsu_driver); -+} -+ -+/* -+ * With module_init() the driver would load before the HID bus when -+ * built-in, so use late_initcall() instead. -+ */ -+late_initcall(corsair_init); -+module_exit(corsair_exit); - - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Wilken Gottwalt "); -diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h -index 0174fbf1a9637..d8e4d902b01ad 100644 ---- a/drivers/hwtracing/coresight/coresight-etm4x.h -+++ b/drivers/hwtracing/coresight/coresight-etm4x.h -@@ -1032,7 +1032,7 @@ struct etmv4_drvdata { - u8 ctxid_size; - u8 vmid_size; - u8 ccsize; -- u8 ccitmin; -+ u16 ccitmin; - u8 s_ex_level; - u8 ns_ex_level; - u8 q_support; -diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c -index 016220ba0addd..8d8fa8e8afe04 100644 ---- a/drivers/hwtracing/ptt/hisi_ptt.c -+++ b/drivers/hwtracing/ptt/hisi_ptt.c -@@ -342,9 +342,9 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt) - return ret; - - hisi_ptt->trace_irq = pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ); -- ret = devm_request_threaded_irq(&pdev->dev, hisi_ptt->trace_irq, -- NULL, hisi_ptt_isr, 0, -- DRV_NAME, hisi_ptt); -+ ret = devm_request_irq(&pdev->dev, hisi_ptt->trace_irq, hisi_ptt_isr, -+ IRQF_NOBALANCING | IRQF_NO_THREAD, DRV_NAME, -+ hisi_ptt); - if (ret) { - pci_err(pdev, "failed to request irq %d, ret = %d\n", - hisi_ptt->trace_irq, ret); -@@ -659,6 +659,9 @@ static int hisi_ptt_pmu_event_init(struct perf_event *event) - return -EOPNOTSUPP; - } - -+ if (event->attach_state & PERF_ATTACH_TASK) -+ return -EOPNOTSUPP; -+ - if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type) - return -ENOENT; - -diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c -index b31cf4f18f854..6aa4f1f062401 100644 ---- a/drivers/i2c/busses/i2c-rk3x.c -+++ b/drivers/i2c/busses/i2c-rk3x.c -@@ -178,6 +178,7 @@ struct rk3x_i2c_soc_data { - * @clk: function clk for rk3399 or function & Bus clks for others - * @pclk: Bus clk for rk3399 - * @clk_rate_nb: i2c clk rate change notify -+ * @irq: irq number - * @t: I2C known timing information - * @lock: spinlock for the i2c bus - * @wait: the waitqueue to wait for i2c transfer -@@ -200,6 +201,7 @@ struct rk3x_i2c { - struct clk *clk; - struct clk *pclk; - struct notifier_block clk_rate_nb; -+ int irq; - - /* Settings */ - struct i2c_timings t; -@@ -1087,13 +1089,18 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap, - - spin_unlock_irqrestore(&i2c->lock, flags); - -- rk3x_i2c_start(i2c); -- - if (!polling) { -+ rk3x_i2c_start(i2c); -+ - timeout = wait_event_timeout(i2c->wait, !i2c->busy, - msecs_to_jiffies(WAIT_TIMEOUT)); - } else { -+ disable_irq(i2c->irq); -+ rk3x_i2c_start(i2c); -+ - timeout = rk3x_i2c_wait_xfer_poll(i2c); -+ -+ enable_irq(i2c->irq); - } - - spin_lock_irqsave(&i2c->lock, flags); -@@ -1310,6 +1317,8 @@ static int rk3x_i2c_probe(struct platform_device *pdev) - return ret; - } - -+ i2c->irq = irq; -+ - platform_set_drvdata(pdev, i2c); - - if (i2c->soc_data->calc_timings == rk3x_i2c_v0_calc_timings) { -diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c -index 8404286302b0c..e8011d70d0799 100644 ---- a/drivers/input/joystick/xpad.c -+++ b/drivers/input/joystick/xpad.c -@@ -286,6 +286,7 @@ static const struct xpad_device { - { 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, - { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, - { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, -+ { 0x1532, 0x0a29, "Razer Wolverine V2", 0, XTYPE_XBOXONE }, - { 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 }, - { 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, - { 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 }, -diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c -index 246958795f606..e1e4f1133296a 100644 ---- a/drivers/input/keyboard/atkbd.c -+++ b/drivers/input/keyboard/atkbd.c -@@ -746,6 +746,44 @@ static void atkbd_deactivate(struct atkbd *atkbd) - ps2dev->serio->phys); - } - -+#ifdef CONFIG_X86 -+static bool atkbd_is_portable_device(void) -+{ -+ static const char * const chassis_types[] = { -+ "8", /* Portable */ -+ "9", /* Laptop */ -+ "10", /* Notebook */ -+ "14", /* Sub-Notebook */ -+ "31", /* Convertible */ -+ "32", /* Detachable */ -+ }; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(chassis_types); i++) -+ if (dmi_match(DMI_CHASSIS_TYPE, chassis_types[i])) -+ return true; -+ -+ return false; -+} -+ -+/* -+ * On many modern laptops ATKBD_CMD_GETID may cause problems, on these laptops -+ * the controller is always in translated mode. In this mode mice/touchpads will -+ * not work. So in this case simply assume a keyboard is connected to avoid -+ * confusing some laptop keyboards. -+ * -+ * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using a fake id is -+ * ok in translated mode, only atkbd_select_set() checks atkbd->id and in -+ * translated mode that is a no-op. -+ */ -+static bool atkbd_skip_getid(struct atkbd *atkbd) -+{ -+ return atkbd->translated && atkbd_is_portable_device(); -+} -+#else -+static inline bool atkbd_skip_getid(struct atkbd *atkbd) { return false; } -+#endif -+ - /* - * atkbd_probe() probes for an AT keyboard on a serio port. - */ -@@ -775,12 +813,12 @@ static int atkbd_probe(struct atkbd *atkbd) - */ - - param[0] = param[1] = 0xa5; /* initialize with invalid values */ -- if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { -+ if (atkbd_skip_getid(atkbd) || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { - - /* -- * If the get ID command failed, we check if we can at least set the LEDs on -- * the keyboard. This should work on every keyboard out there. It also turns -- * the LEDs off, which we want anyway. -+ * If the get ID command was skipped or failed, we check if we can at least set -+ * the LEDs on the keyboard. This should work on every keyboard out there. -+ * It also turns the LEDs off, which we want anyway. - */ - param[0] = 0; - if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) -diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c -index e43e93ac2798a..b6749af462620 100644 ---- a/drivers/input/mouse/synaptics.c -+++ b/drivers/input/mouse/synaptics.c -@@ -183,6 +183,7 @@ static const char * const smbus_pnp_ids[] = { - "LEN009b", /* T580 */ - "LEN0402", /* X1 Extreme Gen 2 / P1 Gen 2 */ - "LEN040f", /* P1 Gen 3 */ -+ "LEN0411", /* L14 Gen 1 */ - "LEN200f", /* T450s */ - "LEN2044", /* L470 */ - "LEN2054", /* E480 */ -diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h -index 9c39553d30fa2..b585b1dab870e 100644 ---- a/drivers/input/serio/i8042-acpipnpio.h -+++ b/drivers/input/serio/i8042-acpipnpio.h -@@ -360,6 +360,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { - }, - .driver_data = (void *)(SERIO_QUIRK_DRITEK) - }, -+ { -+ /* Acer TravelMate P459-G2-M */ -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate P459-G2-M"), -+ }, -+ .driver_data = (void *)(SERIO_QUIRK_NOMUX) -+ }, - { - /* Amoi M636/A737 */ - .matches = { -diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c -index 8ae0d2d284aff..3e69a7bde9284 100644 ---- a/drivers/leds/trigger/ledtrig-tty.c -+++ b/drivers/leds/trigger/ledtrig-tty.c -@@ -168,6 +168,10 @@ static void ledtrig_tty_deactivate(struct led_classdev *led_cdev) - - cancel_delayed_work_sync(&trigger_data->dwork); - -+ kfree(trigger_data->ttyname); -+ tty_kref_put(trigger_data->tty); -+ trigger_data->tty = NULL; -+ - kfree(trigger_data); - } - -diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig -index 662d219c39bf4..db0e97020256e 100644 ---- a/drivers/md/Kconfig -+++ b/drivers/md/Kconfig -@@ -650,6 +650,7 @@ config DM_ZONED - - config DM_AUDIT - bool "DM audit events" -+ depends on BLK_DEV_DM - depends on AUDIT - help - Generate audit events for device-mapper. -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index e4564ca1f2434..f7783199f81d4 100644 ---- a/drivers/md/raid5.c -+++ b/drivers/md/raid5.c -@@ -36,7 +36,6 @@ - */ - - #include --#include - #include - #include - #include -@@ -6833,18 +6832,7 @@ static void raid5d(struct md_thread *thread) - spin_unlock_irq(&conf->device_lock); - md_check_recovery(mddev); - spin_lock_irq(&conf->device_lock); -- -- /* -- * Waiting on MD_SB_CHANGE_PENDING below may deadlock -- * seeing md_check_recovery() is needed to clear -- * the flag when using mdmon. -- */ -- continue; - } -- -- wait_event_lock_irq(mddev->sb_wait, -- !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags), -- conf->device_lock); - } - pr_debug("%d stripes handled\n", handled); - -diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c -index f60a16de565ed..0c694ab3c110c 100644 ---- a/drivers/net/ethernet/broadcom/tg3.c -+++ b/drivers/net/ethernet/broadcom/tg3.c -@@ -6447,6 +6447,14 @@ static void tg3_dump_state(struct tg3 *tp) - int i; - u32 *regs; - -+ /* If it is a PCI error, all registers will be 0xffff, -+ * we don't dump them out, just report the error and return -+ */ -+ if (tp->pdev->error_state != pci_channel_io_normal) { -+ netdev_err(tp->dev, "PCI channel ERROR!\n"); -+ return; -+ } -+ - regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC); - if (!regs) - return; -@@ -11184,7 +11192,8 @@ static void tg3_reset_task(struct work_struct *work) - rtnl_lock(); - tg3_full_lock(tp, 0); - -- if (tp->pcierr_recovery || !netif_running(tp->dev)) { -+ if (tp->pcierr_recovery || !netif_running(tp->dev) || -+ tp->pdev->error_state != pci_channel_io_normal) { - tg3_flag_clear(tp, RESET_TASK_PENDING); - tg3_full_unlock(tp); - rtnl_unlock(); -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c -index 49c7aa86faaa8..e129ee1020f0a 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c -@@ -59,11 +59,6 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id - return -ENODEV; - } - -- if (!of_device_is_compatible(np, "loongson, pci-gmac")) { -- pr_info("dwmac_loongson_pci: Incompatible OF node\n"); -- return -ENODEV; -- } -- - plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); - if (!plat) - return -ENOMEM; -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -index 57a11ee05bc36..91b73e7a41134 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c -@@ -1381,7 +1381,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, - * if it is true then one of the handlers took the page. - */ - -- if (reclaim) { -+ if (reclaim && txq) { - u16 sequence = le16_to_cpu(pkt->hdr.sequence); - int index = SEQ_TO_INDEX(sequence); - int cmd_index = iwl_txq_get_cmd_index(txq, index); -diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c -index 5b906dbb1096c..0c088db944706 100644 ---- a/drivers/nvme/host/core.c -+++ b/drivers/nvme/host/core.c -@@ -1511,7 +1511,8 @@ static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl, - if (id->ncap == 0) { - /* namespace not allocated or attached */ - info->is_removed = true; -- return -ENODEV; -+ ret = -ENODEV; -+ goto error; - } - - info->anagrpid = id->anagrpid; -@@ -1529,8 +1530,10 @@ static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl, - !memchr_inv(ids->nguid, 0, sizeof(ids->nguid))) - memcpy(ids->nguid, id->nguid, sizeof(ids->nguid)); - } -+ -+error: - kfree(id); -- return 0; -+ return ret; - } - - static int nvme_ns_info_from_id_cs_indep(struct nvme_ctrl *ctrl, -@@ -1922,9 +1925,10 @@ static void nvme_update_disk_info(struct gendisk *disk, - - /* - * The block layer can't support LBA sizes larger than the page size -- * yet, so catch this early and don't allow block I/O. -+ * or smaller than a sector size yet, so catch this early and don't -+ * allow block I/O. - */ -- if (ns->lba_shift > PAGE_SHIFT) { -+ if (ns->lba_shift > PAGE_SHIFT || ns->lba_shift < SECTOR_SHIFT) { - capacity = 0; - bs = (1 << 9); - } -diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h -index 118bf08a708b9..a892d679e3389 100644 ---- a/drivers/nvme/host/nvme.h -+++ b/drivers/nvme/host/nvme.h -@@ -382,6 +382,11 @@ struct nvme_ctrl { - enum nvme_dctype dctype; - }; - -+static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl) -+{ -+ return READ_ONCE(ctrl->state); -+} -+ - enum nvme_iopolicy { - NVME_IOPOLICY_NUMA, - NVME_IOPOLICY_RR, -diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c -index 6a2816f3b4e80..73ae16059a1cb 100644 ---- a/drivers/nvme/target/configfs.c -+++ b/drivers/nvme/target/configfs.c -@@ -16,6 +16,7 @@ - #endif - #include - #include -+#include - - #include "nvmet.h" - -@@ -508,6 +509,7 @@ static ssize_t nvmet_ns_ana_grpid_store(struct config_item *item, - - down_write(&nvmet_ana_sem); - oldgrpid = ns->anagrpid; -+ newgrpid = array_index_nospec(newgrpid, NVMET_MAX_ANAGRPS); - nvmet_ana_group_enabled[newgrpid]++; - ns->anagrpid = newgrpid; - nvmet_ana_group_enabled[oldgrpid]--; -@@ -1580,6 +1582,7 @@ static struct config_group *nvmet_ana_groups_make_group( - grp->grpid = grpid; - - down_write(&nvmet_ana_sem); -+ grpid = array_index_nospec(grpid, NVMET_MAX_ANAGRPS); - nvmet_ana_group_enabled[grpid]++; - up_write(&nvmet_ana_sem); - -diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c -index 9f5d784cd95d5..3644997a83425 100644 ---- a/drivers/parport/parport_serial.c -+++ b/drivers/parport/parport_serial.c -@@ -65,6 +65,10 @@ enum parport_pc_pci_cards { - sunix_5069a, - sunix_5079a, - sunix_5099a, -+ brainboxes_uc257, -+ brainboxes_is300, -+ brainboxes_uc414, -+ brainboxes_px263, - }; - - /* each element directly indexed from enum list, above */ -@@ -158,6 +162,10 @@ static struct parport_pc_pci cards[] = { - /* sunix_5069a */ { 1, { { 1, 2 }, } }, - /* sunix_5079a */ { 1, { { 1, 2 }, } }, - /* sunix_5099a */ { 1, { { 1, 2 }, } }, -+ /* brainboxes_uc257 */ { 1, { { 3, -1 }, } }, -+ /* brainboxes_is300 */ { 1, { { 3, -1 }, } }, -+ /* brainboxes_uc414 */ { 1, { { 3, -1 }, } }, -+ /* brainboxes_px263 */ { 1, { { 3, -1 }, } }, - }; - - static struct pci_device_id parport_serial_pci_tbl[] = { -@@ -277,6 +285,38 @@ static struct pci_device_id parport_serial_pci_tbl[] = { - { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, - 0x0104, 0, 0, sunix_5099a }, - -+ /* Brainboxes UC-203 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0bc1, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0bc2, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, -+ -+ /* Brainboxes UC-257 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0861, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0862, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0863, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, -+ -+ /* Brainboxes UC-414 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0e61, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc414 }, -+ -+ /* Brainboxes UC-475 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0981, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, -+ { PCI_VENDOR_ID_INTASHIELD, 0x0982, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, -+ -+ /* Brainboxes IS-300/IS-500 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x0da0, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_is300 }, -+ -+ /* Brainboxes PX-263/PX-295 */ -+ { PCI_VENDOR_ID_INTASHIELD, 0x402c, -+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_px263 }, -+ - { 0, } /* terminate list */ - }; - MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); -@@ -542,6 +582,30 @@ static struct pciserial_board pci_parport_serial_boards[] = { - .base_baud = 921600, - .uart_offset = 0x8, - }, -+ [brainboxes_uc257] = { -+ .flags = FL_BASE2, -+ .num_ports = 2, -+ .base_baud = 115200, -+ .uart_offset = 8, -+ }, -+ [brainboxes_is300] = { -+ .flags = FL_BASE2, -+ .num_ports = 1, -+ .base_baud = 115200, -+ .uart_offset = 8, -+ }, -+ [brainboxes_uc414] = { -+ .flags = FL_BASE2, -+ .num_ports = 4, -+ .base_baud = 115200, -+ .uart_offset = 8, -+ }, -+ [brainboxes_px263] = { -+ .flags = FL_BASE2, -+ .num_ports = 4, -+ .base_baud = 921600, -+ .uart_offset = 8, -+ }, - }; - - struct parport_serial_private { -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index c132839d99dc8..8765544bac35c 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -4602,17 +4602,21 @@ static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags) - * But the implementation could block peer-to-peer transactions between them - * and provide ACS-like functionality. - */ --static int pci_quirk_zhaoxin_pcie_ports_acs(struct pci_dev *dev, u16 acs_flags) -+static int pci_quirk_zhaoxin_pcie_ports_acs(struct pci_dev *dev, u16 acs_flags) - { - if (!pci_is_pcie(dev) || - ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) && - (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM))) - return -ENOTTY; - -+ /* -+ * Future Zhaoxin Root Ports and Switch Downstream Ports will -+ * implement ACS capability in accordance with the PCIe Spec. -+ */ - switch (dev->device) { - case 0x0710 ... 0x071e: - case 0x0721: -- case 0x0723 ... 0x0732: -+ case 0x0723 ... 0x0752: - return pci_acs_ctrl_enabled(acs_flags, - PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); - } -diff --git a/drivers/pinctrl/cirrus/Kconfig b/drivers/pinctrl/cirrus/Kconfig -index 530426a74f751..b3cea8d56c4f6 100644 ---- a/drivers/pinctrl/cirrus/Kconfig -+++ b/drivers/pinctrl/cirrus/Kconfig -@@ -1,7 +1,8 @@ - # SPDX-License-Identifier: GPL-2.0-only - config PINCTRL_LOCHNAGAR - tristate "Cirrus Logic Lochnagar pinctrl driver" -- depends on MFD_LOCHNAGAR -+ # Avoid clash caused by MIPS defining RST, which is used in the driver -+ depends on MFD_LOCHNAGAR && !MIPS - select GPIOLIB - select PINMUX - select PINCONF -diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c -index 68509a2301b8f..5abab6bc763ae 100644 ---- a/drivers/pinctrl/pinctrl-cy8c95x0.c -+++ b/drivers/pinctrl/pinctrl-cy8c95x0.c -@@ -749,6 +749,8 @@ static int cy8c95x0_gpio_get_pincfg(struct cy8c95x0_pinctrl *chip, - ret = regmap_read(chip->regmap, reg, ®_val); - if (reg_val & bit) - arg = 1; -+ if (param == PIN_CONFIG_OUTPUT_ENABLE) -+ arg = !arg; - - *config = pinconf_to_config_packed(param, (u16)arg); - out: -@@ -857,7 +859,7 @@ static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip) - gc->get_direction = cy8c95x0_gpio_get_direction; - gc->get_multiple = cy8c95x0_gpio_get_multiple; - gc->set_multiple = cy8c95x0_gpio_set_multiple; -- gc->set_config = gpiochip_generic_config, -+ gc->set_config = gpiochip_generic_config; - gc->can_sleep = true; - gc->add_pin_ranges = cy8c95x0_add_pin_ranges; - -diff --git a/drivers/platform/x86/intel/vbtn.c b/drivers/platform/x86/intel/vbtn.c -index c5e4e35c8d204..8e2b07ed2ce94 100644 ---- a/drivers/platform/x86/intel/vbtn.c -+++ b/drivers/platform/x86/intel/vbtn.c -@@ -73,10 +73,10 @@ struct intel_vbtn_priv { - bool wakeup_mode; - }; - --static void detect_tablet_mode(struct platform_device *device) -+static void detect_tablet_mode(struct device *dev) - { -- struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev); -- acpi_handle handle = ACPI_HANDLE(&device->dev); -+ struct intel_vbtn_priv *priv = dev_get_drvdata(dev); -+ acpi_handle handle = ACPI_HANDLE(dev); - unsigned long long vgbs; - acpi_status status; - int m; -@@ -89,6 +89,8 @@ static void detect_tablet_mode(struct platform_device *device) - input_report_switch(priv->switches_dev, SW_TABLET_MODE, m); - m = (vgbs & VGBS_DOCK_MODE_FLAG) ? 1 : 0; - input_report_switch(priv->switches_dev, SW_DOCK, m); -+ -+ input_sync(priv->switches_dev); - } - - /* -@@ -134,7 +136,7 @@ static int intel_vbtn_input_setup(struct platform_device *device) - priv->switches_dev->id.bustype = BUS_HOST; - - if (priv->has_switches) { -- detect_tablet_mode(device); -+ detect_tablet_mode(&device->dev); - - ret = input_register_device(priv->switches_dev); - if (ret) -@@ -198,6 +200,9 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) - autorelease = val && (!ke_rel || ke_rel->type == KE_IGNORE); - - sparse_keymap_report_event(input_dev, event, val, autorelease); -+ -+ /* Some devices need this to report further events */ -+ acpi_evaluate_object(handle, "VBDL", NULL, NULL); - } - - /* -@@ -358,7 +363,13 @@ static void intel_vbtn_pm_complete(struct device *dev) - - static int intel_vbtn_pm_resume(struct device *dev) - { -+ struct intel_vbtn_priv *priv = dev_get_drvdata(dev); -+ - intel_vbtn_pm_complete(dev); -+ -+ if (priv->has_switches) -+ detect_tablet_mode(dev); -+ - return 0; - } - -diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c -index 05a55bc31c796..6edd2e294750e 100644 ---- a/drivers/platform/x86/thinkpad_acpi.c -+++ b/drivers/platform/x86/thinkpad_acpi.c -@@ -8149,8 +8149,19 @@ static struct ibm_struct volume_driver_data = { - * TPACPI_FAN_WR_TPEC is also available and should be used to - * command the fan. The X31/X40/X41 seems to have 8 fan levels, - * but the ACPI tables just mention level 7. -+ * -+ * TPACPI_FAN_RD_TPEC_NS: -+ * This mode is used for a few ThinkPads (L13 Yoga Gen2, X13 Yoga Gen2 etc.) -+ * that are using non-standard EC locations for reporting fan speeds. -+ * Currently these platforms only provide fan rpm reporting. -+ * - */ - -+#define FAN_RPM_CAL_CONST 491520 /* FAN RPM calculation offset for some non-standard ECFW */ -+ -+#define FAN_NS_CTRL_STATUS BIT(2) /* Bit which determines control is enabled or not */ -+#define FAN_NS_CTRL BIT(4) /* Bit which determines control is by host or EC */ -+ - enum { /* Fan control constants */ - fan_status_offset = 0x2f, /* EC register 0x2f */ - fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) -@@ -8158,6 +8169,11 @@ enum { /* Fan control constants */ - fan_select_offset = 0x31, /* EC register 0x31 (Firmware 7M) - bit 0 selects which fan is active */ - -+ fan_status_offset_ns = 0x93, /* Special status/control offset for non-standard EC Fan1 */ -+ fan2_status_offset_ns = 0x96, /* Special status/control offset for non-standard EC Fan2 */ -+ fan_rpm_status_ns = 0x95, /* Special offset for Fan1 RPM status for non-standard EC */ -+ fan2_rpm_status_ns = 0x98, /* Special offset for Fan2 RPM status for non-standard EC */ -+ - TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */ - TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */ - -@@ -8168,6 +8184,7 @@ enum fan_status_access_mode { - TPACPI_FAN_NONE = 0, /* No fan status or control */ - TPACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ - TPACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */ -+ TPACPI_FAN_RD_TPEC_NS, /* Use non-standard ACPI EC regs (eg: L13 Yoga gen2 etc.) */ - }; - - enum fan_control_access_mode { -@@ -8195,6 +8212,8 @@ static u8 fan_control_desired_level; - static u8 fan_control_resume_level; - static int fan_watchdog_maxinterval; - -+static bool fan_with_ns_addr; -+ - static struct mutex fan_mutex; - - static void fan_watchdog_fire(struct work_struct *ignored); -@@ -8325,6 +8344,15 @@ static int fan_get_status(u8 *status) - } - - break; -+ case TPACPI_FAN_RD_TPEC_NS: -+ /* Default mode is AUTO which means controlled by EC */ -+ if (!acpi_ec_read(fan_status_offset_ns, &s)) -+ return -EIO; -+ -+ if (status) -+ *status = s; -+ -+ break; - - default: - return -ENXIO; -@@ -8341,7 +8369,8 @@ static int fan_get_status_safe(u8 *status) - if (mutex_lock_killable(&fan_mutex)) - return -ERESTARTSYS; - rc = fan_get_status(&s); -- if (!rc) -+ /* NS EC doesn't have register with level settings */ -+ if (!rc && !fan_with_ns_addr) - fan_update_desired_level(s); - mutex_unlock(&fan_mutex); - -@@ -8368,7 +8397,13 @@ static int fan_get_speed(unsigned int *speed) - - if (likely(speed)) - *speed = (hi << 8) | lo; -+ break; -+ case TPACPI_FAN_RD_TPEC_NS: -+ if (!acpi_ec_read(fan_rpm_status_ns, &lo)) -+ return -EIO; - -+ if (speed) -+ *speed = lo ? FAN_RPM_CAL_CONST / lo : 0; - break; - - default: -@@ -8380,7 +8415,7 @@ static int fan_get_speed(unsigned int *speed) - - static int fan2_get_speed(unsigned int *speed) - { -- u8 hi, lo; -+ u8 hi, lo, status; - bool rc; - - switch (fan_status_access_mode) { -@@ -8396,7 +8431,21 @@ static int fan2_get_speed(unsigned int *speed) - - if (likely(speed)) - *speed = (hi << 8) | lo; -+ break; - -+ case TPACPI_FAN_RD_TPEC_NS: -+ rc = !acpi_ec_read(fan2_status_offset_ns, &status); -+ if (rc) -+ return -EIO; -+ if (!(status & FAN_NS_CTRL_STATUS)) { -+ pr_info("secondary fan control not supported\n"); -+ return -EIO; -+ } -+ rc = !acpi_ec_read(fan2_rpm_status_ns, &lo); -+ if (rc) -+ return -EIO; -+ if (speed) -+ *speed = lo ? FAN_RPM_CAL_CONST / lo : 0; - break; - - default: -@@ -8899,6 +8948,7 @@ static const struct attribute_group fan_driver_attr_group = { - #define TPACPI_FAN_2FAN 0x0002 /* EC 0x31 bit 0 selects fan2 */ - #define TPACPI_FAN_2CTL 0x0004 /* selects fan2 control */ - #define TPACPI_FAN_NOFAN 0x0008 /* no fan available */ -+#define TPACPI_FAN_NS 0x0010 /* For EC with non-Standard register addresses */ - - static const struct tpacpi_quirk fan_quirk_table[] __initconst = { - TPACPI_QEC_IBM('1', 'Y', TPACPI_FAN_Q1), -@@ -8917,6 +8967,8 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = { - TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (2nd gen) */ - TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL), /* P15 (1st gen) / P15v (1st gen) */ - TPACPI_Q_LNV3('N', '3', '7', TPACPI_FAN_2CTL), /* T15g (2nd gen) */ -+ TPACPI_Q_LNV3('R', '1', 'F', TPACPI_FAN_NS), /* L13 Yoga Gen 2 */ -+ TPACPI_Q_LNV3('N', '2', 'U', TPACPI_FAN_NS), /* X13 Yoga Gen 2*/ - TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */ - }; - -@@ -8951,18 +9003,27 @@ static int __init fan_init(struct ibm_init_struct *iibm) - return -ENODEV; - } - -+ if (quirks & TPACPI_FAN_NS) { -+ pr_info("ECFW with non-standard fan reg control found\n"); -+ fan_with_ns_addr = 1; -+ /* Fan ctrl support from host is undefined for now */ -+ tp_features.fan_ctrl_status_undef = 1; -+ } -+ - if (gfan_handle) { - /* 570, 600e/x, 770e, 770x */ - fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN; - } else { - /* all other ThinkPads: note that even old-style - * ThinkPad ECs supports the fan control register */ -- if (likely(acpi_ec_read(fan_status_offset, -- &fan_control_initial_status))) { -+ if (fan_with_ns_addr || -+ likely(acpi_ec_read(fan_status_offset, &fan_control_initial_status))) { - int res; - unsigned int speed; - -- fan_status_access_mode = TPACPI_FAN_RD_TPEC; -+ fan_status_access_mode = fan_with_ns_addr ? -+ TPACPI_FAN_RD_TPEC_NS : TPACPI_FAN_RD_TPEC; -+ - if (quirks & TPACPI_FAN_Q1) - fan_quirk1_setup(); - /* Try and probe the 2nd fan */ -@@ -8971,7 +9032,8 @@ static int __init fan_init(struct ibm_init_struct *iibm) - if (res >= 0 && speed != FAN_NOT_PRESENT) { - /* It responded - so let's assume it's there */ - tp_features.second_fan = 1; -- tp_features.second_fan_ctl = 1; -+ /* fan control not currently available for ns ECFW */ -+ tp_features.second_fan_ctl = !fan_with_ns_addr; - pr_info("secondary fan control detected & enabled\n"); - } else { - /* Fan not auto-detected */ -@@ -9146,6 +9208,7 @@ static int fan_read(struct seq_file *m) - str_enabled_disabled(status), status); - break; - -+ case TPACPI_FAN_RD_TPEC_NS: - case TPACPI_FAN_RD_TPEC: - /* all except 570, 600e/x, 770e, 770x */ - rc = fan_get_status_safe(&status); -@@ -9160,13 +9223,22 @@ static int fan_read(struct seq_file *m) - - seq_printf(m, "speed:\t\t%d\n", speed); - -- if (status & TP_EC_FAN_FULLSPEED) -- /* Disengaged mode takes precedence */ -- seq_printf(m, "level:\t\tdisengaged\n"); -- else if (status & TP_EC_FAN_AUTO) -- seq_printf(m, "level:\t\tauto\n"); -- else -- seq_printf(m, "level:\t\t%d\n", status); -+ if (fan_status_access_mode == TPACPI_FAN_RD_TPEC_NS) { -+ /* -+ * No full speed bit in NS EC -+ * EC Auto mode is set by default. -+ * No other levels settings available -+ */ -+ seq_printf(m, "level:\t\t%s\n", status & FAN_NS_CTRL ? "unknown" : "auto"); -+ } else { -+ if (status & TP_EC_FAN_FULLSPEED) -+ /* Disengaged mode takes precedence */ -+ seq_printf(m, "level:\t\tdisengaged\n"); -+ else if (status & TP_EC_FAN_AUTO) -+ seq_printf(m, "level:\t\tauto\n"); -+ else -+ seq_printf(m, "level:\t\t%d\n", status); -+ } - break; - - case TPACPI_FAN_NONE: -diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c -index 5ca145b64e63d..30951914afac7 100644 ---- a/drivers/reset/hisilicon/hi6220_reset.c -+++ b/drivers/reset/hisilicon/hi6220_reset.c -@@ -164,7 +164,7 @@ static int hi6220_reset_probe(struct platform_device *pdev) - if (!data) - return -ENOMEM; - -- type = (enum hi6220_reset_ctrl_type)of_device_get_match_data(dev); -+ type = (uintptr_t)of_device_get_match_data(dev); - - regmap = syscon_node_to_regmap(np); - if (IS_ERR(regmap)) { -diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c -index 0c1df1d5f1aca..a165b1a59fde5 100644 ---- a/drivers/s390/block/scm_blk.c -+++ b/drivers/s390/block/scm_blk.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include "scm_blk.h" - -@@ -130,7 +131,7 @@ static void scm_request_done(struct scm_request *scmrq) - - for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) { - msb = &scmrq->aob->msb[i]; -- aidaw = msb->data_addr; -+ aidaw = (u64)phys_to_virt(msb->data_addr); - - if ((msb->flags & MSB_FLAG_IDA) && aidaw && - IS_ALIGNED(aidaw, PAGE_SIZE)) -@@ -195,12 +196,12 @@ static int scm_request_prepare(struct scm_request *scmrq) - msb->scm_addr = scmdev->address + ((u64) blk_rq_pos(req) << 9); - msb->oc = (rq_data_dir(req) == READ) ? MSB_OC_READ : MSB_OC_WRITE; - msb->flags |= MSB_FLAG_IDA; -- msb->data_addr = (u64) aidaw; -+ msb->data_addr = (u64)virt_to_phys(aidaw); - - rq_for_each_segment(bv, req, iter) { - WARN_ON(bv.bv_offset); - msb->blk_count += bv.bv_len >> 12; -- aidaw->data_addr = (u64) page_address(bv.bv_page); -+ aidaw->data_addr = virt_to_phys(page_address(bv.bv_page)); - aidaw++; - } - -diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c -index 43afbb7c5ab91..e55e8cef8defc 100644 ---- a/drivers/uio/uio.c -+++ b/drivers/uio/uio.c -@@ -466,13 +466,13 @@ static int uio_open(struct inode *inode, struct file *filep) - - mutex_lock(&minor_lock); - idev = idr_find(&uio_idr, iminor(inode)); -- mutex_unlock(&minor_lock); - if (!idev) { - ret = -ENODEV; -+ mutex_unlock(&minor_lock); - goto out; - } -- - get_device(&idev->dev); -+ mutex_unlock(&minor_lock); - - if (!try_module_get(idev->owner)) { - ret = -ENODEV; -@@ -1064,9 +1064,8 @@ void uio_unregister_device(struct uio_info *info) - wake_up_interruptible(&idev->wait); - kill_fasync(&idev->async_queue, SIGIO, POLL_HUP); - -- device_unregister(&idev->dev); -- - uio_free_minor(minor); -+ device_unregister(&idev->dev); - - return; - } -diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c -index b54f470e0d031..b38304b444764 100644 ---- a/fs/debugfs/file.c -+++ b/fs/debugfs/file.c -@@ -84,6 +84,14 @@ int debugfs_file_get(struct dentry *dentry) - struct debugfs_fsdata *fsd; - void *d_fsd; - -+ /* -+ * This could only happen if some debugfs user erroneously calls -+ * debugfs_file_get() on a dentry that isn't even a file, let -+ * them know about it. -+ */ -+ if (WARN_ON(!d_is_reg(dentry))) -+ return -EINVAL; -+ - d_fsd = READ_ONCE(dentry->d_fsdata); - if (!((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) { - fsd = d_fsd; -diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c -index 2e8e112b19930..08ef685167ec5 100644 ---- a/fs/debugfs/inode.c -+++ b/fs/debugfs/inode.c -@@ -237,17 +237,19 @@ static const struct super_operations debugfs_super_operations = { - - static void debugfs_release_dentry(struct dentry *dentry) - { -- void *fsd = dentry->d_fsdata; -+ struct debugfs_fsdata *fsd = dentry->d_fsdata; - -- if (!((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) -- kfree(dentry->d_fsdata); -+ if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) -+ return; -+ -+ kfree(fsd); - } - - static struct vfsmount *debugfs_automount(struct path *path) - { -- debugfs_automount_t f; -- f = (debugfs_automount_t)path->dentry->d_fsdata; -- return f(path->dentry, d_inode(path->dentry)->i_private); -+ struct debugfs_fsdata *fsd = path->dentry->d_fsdata; -+ -+ return fsd->automount(path->dentry, d_inode(path->dentry)->i_private); - } - - static const struct dentry_operations debugfs_dops = { -@@ -635,13 +637,23 @@ struct dentry *debugfs_create_automount(const char *name, - void *data) - { - struct dentry *dentry = start_creating(name, parent); -+ struct debugfs_fsdata *fsd; - struct inode *inode; - - if (IS_ERR(dentry)) - return dentry; - -+ fsd = kzalloc(sizeof(*fsd), GFP_KERNEL); -+ if (!fsd) { -+ failed_creating(dentry); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ fsd->automount = f; -+ - if (!(debugfs_allow & DEBUGFS_ALLOW_API)) { - failed_creating(dentry); -+ kfree(fsd); - return ERR_PTR(-EPERM); - } - -@@ -649,13 +661,14 @@ struct dentry *debugfs_create_automount(const char *name, - if (unlikely(!inode)) { - pr_err("out of free dentries, can not create automount '%s'\n", - name); -+ kfree(fsd); - return failed_creating(dentry); - } - - make_empty_dir_inode(inode); - inode->i_flags |= S_AUTOMOUNT; - inode->i_private = data; -- dentry->d_fsdata = (void *)f; -+ dentry->d_fsdata = fsd; - /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inc_nlink(inode); - d_instantiate(dentry, inode); -diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h -index 92af8ae313134..f7c489b5a368c 100644 ---- a/fs/debugfs/internal.h -+++ b/fs/debugfs/internal.h -@@ -17,8 +17,14 @@ extern const struct file_operations debugfs_full_proxy_file_operations; - - struct debugfs_fsdata { - const struct file_operations *real_fops; -- refcount_t active_users; -- struct completion active_users_drained; -+ union { -+ /* automount_fn is used when real_fops is NULL */ -+ debugfs_automount_t automount; -+ struct { -+ refcount_t active_users; -+ struct completion active_users_drained; -+ }; -+ }; - }; - - /* -diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c -index adaad16468d8a..8816e13ca7c9e 100644 ---- a/fs/f2fs/xattr.c -+++ b/fs/f2fs/xattr.c -@@ -754,6 +754,12 @@ retry: - memcpy(pval, value, size); - last->e_value_size = cpu_to_le16(size); - new_hsize += newsize; -+ /* -+ * Explicitly add the null terminator. The unused xattr space -+ * is supposed to always be zeroed, which would make this -+ * unnecessary, but don't depend on that. -+ */ -+ *(u32 *)((u8 *)last + newsize) = 0; - } - - error = write_all_xattrs(inode, new_hsize, base_addr, ipage); -diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c -index f1d9db6686e31..556b259a00ba6 100644 ---- a/fs/jbd2/commit.c -+++ b/fs/jbd2/commit.c -@@ -123,7 +123,7 @@ static int journal_submit_commit_record(journal_t *journal, - struct commit_header *tmp; - struct buffer_head *bh; - struct timespec64 now; -- blk_opf_t write_flags = REQ_OP_WRITE | REQ_SYNC; -+ blk_opf_t write_flags = REQ_OP_WRITE | JBD2_JOURNAL_REQ_FLAGS; - - *cbh = NULL; - -@@ -300,6 +300,7 @@ static int journal_finish_inode_data_buffers(journal_t *journal, - if (!ret) - ret = err; - } -+ cond_resched(); - spin_lock(&journal->j_list_lock); - jinode->i_flags &= ~JI_COMMIT_RUNNING; - smp_mb(); -@@ -429,8 +430,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) - */ - jbd2_journal_update_sb_log_tail(journal, - journal->j_tail_sequence, -- journal->j_tail, -- REQ_SYNC); -+ journal->j_tail, 0); - mutex_unlock(&journal->j_checkpoint_mutex); - } else { - jbd2_debug(3, "superblock not updated\n"); -@@ -749,6 +749,7 @@ start_journal_io: - - for (i = 0; i < bufs; i++) { - struct buffer_head *bh = wbuf[i]; -+ - /* - * Compute checksum. - */ -@@ -761,7 +762,8 @@ start_journal_io: - clear_buffer_dirty(bh); - set_buffer_uptodate(bh); - bh->b_end_io = journal_end_buffer_io_sync; -- submit_bh(REQ_OP_WRITE | REQ_SYNC, bh); -+ submit_bh(REQ_OP_WRITE | JBD2_JOURNAL_REQ_FLAGS, -+ bh); - } - cond_resched(); - -diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c -index 2696f43e7239f..3df45e4699f10 100644 ---- a/fs/jbd2/journal.c -+++ b/fs/jbd2/journal.c -@@ -1109,8 +1109,7 @@ int __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block) - * space and if we lose sb update during power failure we'd replay - * old transaction with possibly newly overwritten data. - */ -- ret = jbd2_journal_update_sb_log_tail(journal, tid, block, -- REQ_SYNC | REQ_FUA); -+ ret = jbd2_journal_update_sb_log_tail(journal, tid, block, REQ_FUA); - if (ret) - goto out; - -@@ -1597,8 +1596,7 @@ static int journal_reset(journal_t *journal) - */ - jbd2_journal_update_sb_log_tail(journal, - journal->j_tail_sequence, -- journal->j_tail, -- REQ_SYNC | REQ_FUA); -+ journal->j_tail, REQ_FUA); - mutex_unlock(&journal->j_checkpoint_mutex); - } - return jbd2_journal_start_thread(journal); -@@ -1620,9 +1618,16 @@ static int jbd2_write_superblock(journal_t *journal, blk_opf_t write_flags) - return -EIO; - } - -- trace_jbd2_write_superblock(journal, write_flags); -+ /* -+ * Always set high priority flags to exempt from block layer's -+ * QOS policies, e.g. writeback throttle. -+ */ -+ write_flags |= JBD2_JOURNAL_REQ_FLAGS; - if (!(journal->j_flags & JBD2_BARRIER)) - write_flags &= ~(REQ_FUA | REQ_PREFLUSH); -+ -+ trace_jbd2_write_superblock(journal, write_flags); -+ - if (buffer_write_io_error(bh)) { - /* - * Oh, dear. A previous attempt to write the journal -@@ -1871,7 +1876,7 @@ void jbd2_journal_update_sb_errno(journal_t *journal) - jbd2_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode); - sb->s_errno = cpu_to_be32(errcode); - -- jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA); -+ jbd2_write_superblock(journal, REQ_FUA); - } - EXPORT_SYMBOL(jbd2_journal_update_sb_errno); - -@@ -2176,8 +2181,7 @@ int jbd2_journal_destroy(journal_t *journal) - ++journal->j_transaction_sequence; - write_unlock(&journal->j_state_lock); - -- jbd2_mark_journal_empty(journal, -- REQ_SYNC | REQ_PREFLUSH | REQ_FUA); -+ jbd2_mark_journal_empty(journal, REQ_PREFLUSH | REQ_FUA); - mutex_unlock(&journal->j_checkpoint_mutex); - } else - err = -EIO; -@@ -2486,7 +2490,7 @@ int jbd2_journal_flush(journal_t *journal, unsigned int flags) - * the magic code for a fully-recovered superblock. Any future - * commits of data to the journal will restore the current - * s_start value. */ -- jbd2_mark_journal_empty(journal, REQ_SYNC | REQ_FUA); -+ jbd2_mark_journal_empty(journal, REQ_FUA); - - if (flags) - err = __jbd2_journal_erase(journal, flags); -@@ -2536,7 +2540,7 @@ int jbd2_journal_wipe(journal_t *journal, int write) - if (write) { - /* Lock to make assertions happy... */ - mutex_lock_io(&journal->j_checkpoint_mutex); -- jbd2_mark_journal_empty(journal, REQ_SYNC | REQ_FUA); -+ jbd2_mark_journal_empty(journal, REQ_FUA); - mutex_unlock(&journal->j_checkpoint_mutex); - } - -diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h -index c403816d0b6c1..97bb1838555b4 100644 ---- a/fs/smb/client/cifspdu.h -+++ b/fs/smb/client/cifspdu.h -@@ -882,11 +882,13 @@ typedef struct smb_com_open_rsp { - __u8 OplockLevel; - __u16 Fid; - __le32 CreateAction; -- __le64 CreationTime; -- __le64 LastAccessTime; -- __le64 LastWriteTime; -- __le64 ChangeTime; -- __le32 FileAttributes; -+ struct_group(common_attributes, -+ __le64 CreationTime; -+ __le64 LastAccessTime; -+ __le64 LastWriteTime; -+ __le64 ChangeTime; -+ __le32 FileAttributes; -+ ); - __le64 AllocationSize; - __le64 EndOfFile; - __le16 FileType; -@@ -2268,11 +2270,13 @@ typedef struct { - /* QueryFileInfo/QueryPathinfo (also for SetPath/SetFile) data buffer formats */ - /******************************************************************************/ - typedef struct { /* data block encoding of response to level 263 QPathInfo */ -- __le64 CreationTime; -- __le64 LastAccessTime; -- __le64 LastWriteTime; -- __le64 ChangeTime; -- __le32 Attributes; -+ struct_group(common_attributes, -+ __le64 CreationTime; -+ __le64 LastAccessTime; -+ __le64 LastWriteTime; -+ __le64 ChangeTime; -+ __le32 Attributes; -+ ); - __u32 Pad1; - __le64 AllocationSize; - __le64 EndOfFile; /* size ie offset to first free byte in file */ -diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c -index c90d4ec9292ca..67c5fc2b2db94 100644 ---- a/fs/smb/client/cifssmb.c -+++ b/fs/smb/client/cifssmb.c -@@ -1234,8 +1234,10 @@ openRetry: - *oplock |= CIFS_CREATE_ACTION; - - if (buf) { -- /* copy from CreationTime to Attributes */ -- memcpy((char *)buf, (char *)&rsp->CreationTime, 36); -+ /* copy commonly used attributes */ -+ memcpy(&buf->common_attributes, -+ &rsp->common_attributes, -+ sizeof(buf->common_attributes)); - /* the file_info buf is endian converted by caller */ - buf->AllocationSize = rsp->AllocationSize; - buf->EndOfFile = rsp->EndOfFile; -diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c -index fdf7a7f188c5f..15fa022e79993 100644 ---- a/fs/smb/client/smb2misc.c -+++ b/fs/smb/client/smb2misc.c -@@ -173,6 +173,21 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server) - } - - mid = le64_to_cpu(shdr->MessageId); -+ if (check_smb2_hdr(shdr, mid)) -+ return 1; -+ -+ if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) { -+ cifs_dbg(VFS, "Invalid structure size %u\n", -+ le16_to_cpu(shdr->StructureSize)); -+ return 1; -+ } -+ -+ command = le16_to_cpu(shdr->Command); -+ if (command >= NUMBER_OF_SMB2_COMMANDS) { -+ cifs_dbg(VFS, "Invalid SMB2 command %d\n", command); -+ return 1; -+ } -+ - if (len < pdu_size) { - if ((len >= hdr_size) - && (shdr->Status != 0)) { -@@ -193,21 +208,6 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server) - return 1; - } - -- if (check_smb2_hdr(shdr, mid)) -- return 1; -- -- if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) { -- cifs_dbg(VFS, "Invalid structure size %u\n", -- le16_to_cpu(shdr->StructureSize)); -- return 1; -- } -- -- command = le16_to_cpu(shdr->Command); -- if (command >= NUMBER_OF_SMB2_COMMANDS) { -- cifs_dbg(VFS, "Invalid SMB2 command %d\n", command); -- return 1; -- } -- - if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) { - if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 || - pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) { -diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c -index 4596d2dfdec3a..5a157000bdfe6 100644 ---- a/fs/smb/client/smb2ops.c -+++ b/fs/smb/client/smb2ops.c -@@ -398,8 +398,10 @@ smb2_dump_detail(void *buf, struct TCP_Server_Info *server) - cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", - shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId, - shdr->Id.SyncId.ProcessId); -- cifs_server_dbg(VFS, "smb buf %p len %u\n", buf, -- server->ops->calc_smb_size(buf)); -+ if (!server->ops->check_message(buf, server->total_read, server)) { -+ cifs_server_dbg(VFS, "smb buf %p len %u\n", buf, -+ server->ops->calc_smb_size(buf)); -+ } - #endif - } - -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index 2dfbf1b23cfa0..e65f998ea4cfc 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -3429,12 +3429,10 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, - } else { - trace_smb3_close_done(xid, persistent_fid, tcon->tid, - ses->Suid); -- /* -- * Note that have to subtract 4 since struct network_open_info -- * has a final 4 byte pad that close response does not have -- */ - if (pbuf) -- memcpy(pbuf, (char *)&rsp->CreationTime, sizeof(*pbuf) - 4); -+ memcpy(&pbuf->network_open_info, -+ &rsp->network_open_info, -+ sizeof(pbuf->network_open_info)); - } - - atomic_dec(&tcon->num_remote_opens); -diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h -index a5773a06aba8e..8d011fedecd03 100644 ---- a/fs/smb/client/smb2pdu.h -+++ b/fs/smb/client/smb2pdu.h -@@ -339,13 +339,15 @@ struct smb2_file_reparse_point_info { - } __packed; - - struct smb2_file_network_open_info { -- __le64 CreationTime; -- __le64 LastAccessTime; -- __le64 LastWriteTime; -- __le64 ChangeTime; -- __le64 AllocationSize; -- __le64 EndOfFile; -- __le32 Attributes; -+ struct_group(network_open_info, -+ __le64 CreationTime; -+ __le64 LastAccessTime; -+ __le64 LastWriteTime; -+ __le64 ChangeTime; -+ __le64 AllocationSize; -+ __le64 EndOfFile; -+ __le32 Attributes; -+ ); - __le32 Reserved; - } __packed; /* level 34 Query also similar returned in close rsp and open rsp */ - -diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h -index 5593bb49954c6..a3936ff53d9d0 100644 ---- a/fs/smb/common/smb2pdu.h -+++ b/fs/smb/common/smb2pdu.h -@@ -699,13 +699,16 @@ struct smb2_close_rsp { - __le16 StructureSize; /* 60 */ - __le16 Flags; - __le32 Reserved; -- __le64 CreationTime; -- __le64 LastAccessTime; -- __le64 LastWriteTime; -- __le64 ChangeTime; -- __le64 AllocationSize; /* Beginning of FILE_STANDARD_INFO equivalent */ -- __le64 EndOfFile; -- __le32 Attributes; -+ struct_group(network_open_info, -+ __le64 CreationTime; -+ __le64 LastAccessTime; -+ __le64 LastWriteTime; -+ __le64 ChangeTime; -+ /* Beginning of FILE_STANDARD_INFO equivalent */ -+ __le64 AllocationSize; -+ __le64 EndOfFile; -+ __le32 Attributes; -+ ); - } __packed; - - -diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c -index 6e5ed0ac578a6..46070951d163a 100644 ---- a/fs/smb/server/smb2pdu.c -+++ b/fs/smb/server/smb2pdu.c -@@ -2969,7 +2969,7 @@ int smb2_open(struct ksmbd_work *work) - &may_flags); - - if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { -- if (open_flags & O_CREAT) { -+ if (open_flags & (O_CREAT | O_TRUNC)) { - ksmbd_debug(SMB, - "User does not have write permission\n"); - rc = -EACCES; -@@ -5941,12 +5941,6 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, - } - case FILE_RENAME_INFORMATION: - { -- if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { -- ksmbd_debug(SMB, -- "User does not have write permission\n"); -- return -EACCES; -- } -- - if (buf_len < sizeof(struct smb2_file_rename_info)) - return -EINVAL; - -@@ -5966,12 +5960,6 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, - } - case FILE_DISPOSITION_INFORMATION: - { -- if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { -- ksmbd_debug(SMB, -- "User does not have write permission\n"); -- return -EACCES; -- } -- - if (buf_len < sizeof(struct smb2_file_disposition_info)) - return -EINVAL; - -@@ -6033,7 +6021,7 @@ int smb2_set_info(struct ksmbd_work *work) - { - struct smb2_set_info_req *req; - struct smb2_set_info_rsp *rsp; -- struct ksmbd_file *fp; -+ struct ksmbd_file *fp = NULL; - int rc = 0; - unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; - -@@ -6053,6 +6041,13 @@ int smb2_set_info(struct ksmbd_work *work) - rsp = smb2_get_msg(work->response_buf); - } - -+ if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { -+ ksmbd_debug(SMB, "User does not have write permission\n"); -+ pr_err("User does not have write permission\n"); -+ rc = -EACCES; -+ goto err_out; -+ } -+ - if (!has_file_id(id)) { - id = req->VolatileFileId; - pid = req->PersistentFileId; -diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c -index d9bbd2eb89c35..6fd3560028d3a 100644 ---- a/fs/smb/server/smbacl.c -+++ b/fs/smb/server/smbacl.c -@@ -401,10 +401,6 @@ static void parse_dacl(struct user_namespace *user_ns, - if (num_aces > ULONG_MAX / sizeof(struct smb_ace *)) - return; - -- ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL); -- if (!ppace) -- return; -- - ret = init_acl_state(&acl_state, num_aces); - if (ret) - return; -@@ -414,6 +410,13 @@ static void parse_dacl(struct user_namespace *user_ns, - return; - } - -+ ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL); -+ if (!ppace) { -+ free_acl_state(&default_acl_state); -+ free_acl_state(&acl_state); -+ return; -+ } -+ - /* - * reset rwx permissions for user/group/other. - * Also, if num_aces is 0 i.e. DACL has no ACEs, -diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h -index 870ae4cd82029..dce105f67b4d8 100644 ---- a/include/linux/ieee80211.h -+++ b/include/linux/ieee80211.h -@@ -2658,12 +2658,14 @@ ieee80211_he_oper_size(const u8 *he_oper_ie) - static inline const struct ieee80211_he_6ghz_oper * - ieee80211_he_6ghz_oper(const struct ieee80211_he_operation *he_oper) - { -- const u8 *ret = (const void *)&he_oper->optional; -+ const u8 *ret; - u32 he_oper_params; - - if (!he_oper) - return NULL; - -+ ret = (const void *)&he_oper->optional; -+ - he_oper_params = le32_to_cpu(he_oper->he_oper_params); - - if (!(he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)) -diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h -index ebb1608d9dcd2..6611af5f1d0c6 100644 ---- a/include/linux/jbd2.h -+++ b/include/linux/jbd2.h -@@ -1374,6 +1374,9 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum2, CSUM_V2) - JBD2_FEATURE_INCOMPAT_FUNCS(csum3, CSUM_V3) - JBD2_FEATURE_INCOMPAT_FUNCS(fast_commit, FAST_COMMIT) - -+/* Journal high priority write IO operation flags */ -+#define JBD2_JOURNAL_REQ_FLAGS (REQ_META | REQ_SYNC | REQ_IDLE) -+ - /* - * Journal flag definitions - */ -diff --git a/init/Kconfig b/init/Kconfig -index de255842f5d09..148704640252e 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1914,7 +1914,7 @@ config RUST - depends on !MODVERSIONS - depends on !GCC_PLUGINS - depends on !RANDSTRUCT -- depends on !DEBUG_INFO_BTF -+ depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE - select CONSTRUCTORS - help - Enables Rust support in the kernel. -diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index 71cad4f1323c6..1285e7fb597ee 100644 ---- a/kernel/trace/ring_buffer.c -+++ b/kernel/trace/ring_buffer.c -@@ -3644,6 +3644,12 @@ rb_reserve_next_event(struct trace_buffer *buffer, - int nr_loops = 0; - int add_ts_default; - -+ /* ring buffer does cmpxchg, make sure it is safe in NMI context */ -+ if (!IS_ENABLED(CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG) && -+ (unlikely(in_nmi()))) { -+ return NULL; -+ } -+ - rb_start_commit(cpu_buffer); - /* The commit page can not change after this */ - -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index deae65af76ecf..2b3c4cd8382b3 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -4679,7 +4679,11 @@ static int s_show(struct seq_file *m, void *v) - iter->leftover = ret; - - } else { -- print_trace_line(iter); -+ ret = print_trace_line(iter); -+ if (ret == TRACE_TYPE_PARTIAL_LINE) { -+ iter->seq.full = 0; -+ trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n"); -+ } - ret = trace_print_seq(m, &iter->seq); - /* - * If we overflow the seq_file buffer, then it will -@@ -4912,6 +4916,12 @@ int tracing_release_file_tr(struct inode *inode, struct file *filp) - return 0; - } - -+int tracing_single_release_file_tr(struct inode *inode, struct file *filp) -+{ -+ tracing_release_file_tr(inode, filp); -+ return single_release(inode, filp); -+} -+ - static int tracing_mark_open(struct inode *inode, struct file *filp) - { - stream_open(inode, filp); -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 10aaafa2936dc..aad7fcd84617c 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -592,6 +592,7 @@ int tracing_open_generic(struct inode *inode, struct file *filp); - int tracing_open_generic_tr(struct inode *inode, struct file *filp); - int tracing_open_file_tr(struct inode *inode, struct file *filp); - int tracing_release_file_tr(struct inode *inode, struct file *filp); -+int tracing_single_release_file_tr(struct inode *inode, struct file *filp); - bool tracing_is_disabled(void); - bool tracer_tracing_is_on(struct trace_array *tr); - void tracer_tracing_on(struct trace_array *tr); -diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c -index 1470af2190735..3b0da1bddf633 100644 ---- a/kernel/trace/trace_events_hist.c -+++ b/kernel/trace/trace_events_hist.c -@@ -5532,10 +5532,12 @@ static int event_hist_open(struct inode *inode, struct file *file) - { - int ret; - -- ret = security_locked_down(LOCKDOWN_TRACEFS); -+ ret = tracing_open_file_tr(inode, file); - if (ret) - return ret; - -+ /* Clear private_data to avoid warning in single_open() */ -+ file->private_data = NULL; - return single_open(file, hist_show, file); - } - -@@ -5543,7 +5545,7 @@ const struct file_operations event_hist_fops = { - .open = event_hist_open, - .read = seq_read, - .llseek = seq_lseek, -- .release = single_release, -+ .release = tracing_single_release_file_tr, - }; - - #ifdef CONFIG_HIST_TRIGGERS_DEBUG -@@ -5809,10 +5811,12 @@ static int event_hist_debug_open(struct inode *inode, struct file *file) - { - int ret; - -- ret = security_locked_down(LOCKDOWN_TRACEFS); -+ ret = tracing_open_file_tr(inode, file); - if (ret) - return ret; - -+ /* Clear private_data to avoid warning in single_open() */ -+ file->private_data = NULL; - return single_open(file, hist_debug_show, file); - } - -@@ -5820,7 +5824,7 @@ const struct file_operations event_hist_debug_fops = { - .open = event_hist_debug_open, - .read = seq_read, - .llseek = seq_lseek, -- .release = single_release, -+ .release = tracing_single_release_file_tr, - }; - #endif - -diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c -index 5cd4fb6563068..bf1965b180992 100644 ---- a/kernel/trace/trace_output.c -+++ b/kernel/trace/trace_output.c -@@ -1445,11 +1445,12 @@ static enum print_line_t trace_print_print(struct trace_iterator *iter, - { - struct print_entry *field; - struct trace_seq *s = &iter->seq; -+ int max = iter->ent_size - offsetof(struct print_entry, buf); - - trace_assign_type(field, iter->ent); - - seq_print_ip_sym(s, field->ip, flags); -- trace_seq_printf(s, ": %s", field->buf); -+ trace_seq_printf(s, ": %.*s", max, field->buf); - - return trace_handle_return(s); - } -@@ -1458,10 +1459,11 @@ static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags, - struct trace_event *event) - { - struct print_entry *field; -+ int max = iter->ent_size - offsetof(struct print_entry, buf); - - trace_assign_type(field, iter->ent); - -- trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf); -+ trace_seq_printf(&iter->seq, "# %lx %.*s", field->ip, max, field->buf); - - return trace_handle_return(&iter->seq); - } -diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug -index 4db0199651f56..95541b99aa8ea 100644 ---- a/lib/Kconfig.debug -+++ b/lib/Kconfig.debug -@@ -364,6 +364,15 @@ config PAHOLE_HAS_BTF_TAG - btf_decl_tag) or not. Currently only clang compiler implements - these attributes, so make the config depend on CC_IS_CLANG. - -+config PAHOLE_HAS_LANG_EXCLUDE -+ def_bool PAHOLE_VERSION >= 124 -+ help -+ Support for the --lang_exclude flag which makes pahole exclude -+ compilation units from the supplied language. Used in Kbuild to -+ omit Rust CUs which are not supported in version 1.24 of pahole, -+ otherwise it would emit malformed kernel and module binaries when -+ using DEBUG_INFO_BTF_MODULES. -+ - config DEBUG_INFO_BTF_MODULES - def_bool y - depends on DEBUG_INFO_BTF && MODULES && PAHOLE_HAS_SPLIT_BTF -diff --git a/lib/idr.c b/lib/idr.c -index 13f2758c23773..da36054c3ca02 100644 ---- a/lib/idr.c -+++ b/lib/idr.c -@@ -508,7 +508,7 @@ void ida_free(struct ida *ida, unsigned int id) - goto delete; - xas_store(&xas, xa_mk_value(v)); - } else { -- if (!test_bit(bit, bitmap->bitmap)) -+ if (!bitmap || !test_bit(bit, bitmap->bitmap)) - goto err; - __clear_bit(bit, bitmap->bitmap); - xas_set_mark(&xas, XA_FREE_MARK); -diff --git a/lib/test_ida.c b/lib/test_ida.c -index b068806259615..55105baa19da9 100644 ---- a/lib/test_ida.c -+++ b/lib/test_ida.c -@@ -150,6 +150,45 @@ static void ida_check_conv(struct ida *ida) - IDA_BUG_ON(ida, !ida_is_empty(ida)); - } - -+/* -+ * Check various situations where we attempt to free an ID we don't own. -+ */ -+static void ida_check_bad_free(struct ida *ida) -+{ -+ unsigned long i; -+ -+ printk("vvv Ignore \"not allocated\" warnings\n"); -+ /* IDA is empty; all of these will fail */ -+ ida_free(ida, 0); -+ for (i = 0; i < 31; i++) -+ ida_free(ida, 1 << i); -+ -+ /* IDA contains a single value entry */ -+ IDA_BUG_ON(ida, ida_alloc_min(ida, 3, GFP_KERNEL) != 3); -+ ida_free(ida, 0); -+ for (i = 0; i < 31; i++) -+ ida_free(ida, 1 << i); -+ -+ /* IDA contains a single bitmap */ -+ IDA_BUG_ON(ida, ida_alloc_min(ida, 1023, GFP_KERNEL) != 1023); -+ ida_free(ida, 0); -+ for (i = 0; i < 31; i++) -+ ida_free(ida, 1 << i); -+ -+ /* IDA contains a tree */ -+ IDA_BUG_ON(ida, ida_alloc_min(ida, (1 << 20) - 1, GFP_KERNEL) != (1 << 20) - 1); -+ ida_free(ida, 0); -+ for (i = 0; i < 31; i++) -+ ida_free(ida, 1 << i); -+ printk("^^^ \"not allocated\" warnings over\n"); -+ -+ ida_free(ida, 3); -+ ida_free(ida, 1023); -+ ida_free(ida, (1 << 20) - 1); -+ -+ IDA_BUG_ON(ida, !ida_is_empty(ida)); -+} -+ - static DEFINE_IDA(ida); - - static int ida_checks(void) -@@ -162,6 +201,7 @@ static int ida_checks(void) - ida_check_leaf(&ida, 1024 * 64); - ida_check_max(&ida); - ida_check_conv(&ida); -+ ida_check_bad_free(&ida); - - printk("IDA: %u of %u tests passed\n", tests_passed, tests_run); - return (tests_run != tests_passed) ? 0 : -EINVAL; -diff --git a/net/core/neighbour.c b/net/core/neighbour.c -index 41daa47d03934..c842f150c3048 100644 ---- a/net/core/neighbour.c -+++ b/net/core/neighbour.c -@@ -253,9 +253,11 @@ static int neigh_forced_gc(struct neigh_table *tbl) - { - int max_clean = atomic_read(&tbl->gc_entries) - - READ_ONCE(tbl->gc_thresh2); -+ u64 tmax = ktime_get_ns() + NSEC_PER_MSEC; - unsigned long tref = jiffies - 5 * HZ; - struct neighbour *n, *tmp; - int shrunk = 0; -+ int loop = 0; - - NEIGH_CACHE_STAT_INC(tbl, forced_gc_runs); - -@@ -278,11 +280,16 @@ static int neigh_forced_gc(struct neigh_table *tbl) - shrunk++; - if (shrunk >= max_clean) - break; -+ if (++loop == 16) { -+ if (ktime_get_ns() > tmax) -+ goto unlock; -+ loop = 0; -+ } - } - } - - WRITE_ONCE(tbl->last_flush, jiffies); -- -+unlock: - write_unlock_bh(&tbl->lock); - - return shrunk; -diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c -index ae42e956eff5a..9bfe128ada47d 100644 ---- a/net/mac80211/ht.c -+++ b/net/mac80211/ht.c -@@ -271,6 +271,7 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata, - case NL80211_CHAN_WIDTH_80: - case NL80211_CHAN_WIDTH_80P80: - case NL80211_CHAN_WIDTH_160: -+ case NL80211_CHAN_WIDTH_320: - bw = ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? - IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; - break; -diff --git a/net/mptcp/options.c b/net/mptcp/options.c -index 0c786ceda5ee6..74027bb5b4296 100644 ---- a/net/mptcp/options.c -+++ b/net/mptcp/options.c -@@ -103,6 +103,7 @@ static void mptcp_parse_option(const struct sk_buff *skb, - mp_opt->suboptions |= OPTION_MPTCP_DSS; - mp_opt->use_map = 1; - mp_opt->mpc_map = 1; -+ mp_opt->use_ack = 0; - mp_opt->data_len = get_unaligned_be16(ptr); - ptr += 2; - } -diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c -index 3e40a1ba48f79..4a13b9f7abb44 100644 ---- a/net/qrtr/ns.c -+++ b/net/qrtr/ns.c -@@ -569,7 +569,9 @@ static int ctrl_cmd_del_server(struct sockaddr_qrtr *from, - if (!node) - return -ENOENT; - -- return server_del(node, port, true); -+ server_del(node, port, true); -+ -+ return 0; - } - - static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, -diff --git a/net/wireless/core.c b/net/wireless/core.c -index 63d75fecc2c53..8809e668ed912 100644 ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -216,7 +216,9 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) - { - struct cfg80211_registered_device *rdev = data; - -+ wiphy_lock(&rdev->wiphy); - rdev_rfkill_poll(rdev); -+ wiphy_unlock(&rdev->wiphy); - } - - void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, -diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh -index 564c5632e1a24..bfe5a4082d8ea 100755 ---- a/scripts/decode_stacktrace.sh -+++ b/scripts/decode_stacktrace.sh -@@ -16,6 +16,21 @@ elif type c++filt >/dev/null 2>&1 ; then - cppfilt_opts=-i - fi - -+UTIL_SUFFIX= -+if [[ -z ${LLVM:-} ]]; then -+ UTIL_PREFIX=${CROSS_COMPILE:-} -+else -+ UTIL_PREFIX=llvm- -+ if [[ ${LLVM} == */ ]]; then -+ UTIL_PREFIX=${LLVM}${UTIL_PREFIX} -+ elif [[ ${LLVM} == -* ]]; then -+ UTIL_SUFFIX=${LLVM} -+ fi -+fi -+ -+READELF=${UTIL_PREFIX}readelf${UTIL_SUFFIX} -+ADDR2LINE=${UTIL_PREFIX}addr2line${UTIL_SUFFIX} -+ - if [[ $1 == "-r" ]] ; then - vmlinux="" - basepath="auto" -@@ -75,7 +90,7 @@ find_module() { - - if [[ "$modpath" != "" ]] ; then - for fn in $(find "$modpath" -name "${module//_/[-_]}.ko*") ; do -- if readelf -WS "$fn" | grep -qwF .debug_line ; then -+ if ${READELF} -WS "$fn" | grep -qwF .debug_line ; then - echo $fn - return - fi -@@ -169,7 +184,7 @@ parse_symbol() { - if [[ $aarray_support == true && "${cache[$module,$address]+isset}" == "isset" ]]; then - local code=${cache[$module,$address]} - else -- local code=$(${CROSS_COMPILE}addr2line -i -e "$objfile" "$address" 2>/dev/null) -+ local code=$(${ADDR2LINE} -i -e "$objfile" "$address" 2>/dev/null) - if [[ $aarray_support == true ]]; then - cache[$module,$address]=$code - fi -diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh -index 0d99ef17e4a52..728d55190d97a 100755 ---- a/scripts/pahole-flags.sh -+++ b/scripts/pahole-flags.sh -@@ -19,5 +19,12 @@ fi - if [ "${pahole_ver}" -ge "122" ]; then - extra_paholeopt="${extra_paholeopt} -j" - fi -+if [ "${pahole_ver}" -ge "124" ]; then -+ # see PAHOLE_HAS_LANG_EXCLUDE -+ extra_paholeopt="${extra_paholeopt} --lang_exclude=rust" -+fi -+if [ "${pahole_ver}" -ge "125" ]; then -+ extra_paholeopt="${extra_paholeopt} --skip_encoding_btf_inconsistent_proto --btf_gen_optimized" -+fi - - echo ${extra_paholeopt} -diff --git a/sound/hda/intel-nhlt.c b/sound/hda/intel-nhlt.c -index 2c4dfc0b7e342..696a958d93e9c 100644 ---- a/sound/hda/intel-nhlt.c -+++ b/sound/hda/intel-nhlt.c -@@ -238,7 +238,7 @@ EXPORT_SYMBOL(intel_nhlt_ssp_mclk_mask); - - static struct nhlt_specific_cfg * - nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch, -- u32 rate, u8 vbps, u8 bps) -+ u32 rate, u8 vbps, u8 bps, bool ignore_vbps) - { - struct nhlt_fmt_cfg *cfg = fmt->fmt_config; - struct wav_fmt *wfmt; -@@ -255,8 +255,12 @@ nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch, - dev_dbg(dev, "Endpoint format: ch=%d fmt=%d/%d rate=%d\n", - wfmt->channels, _vbps, _bps, wfmt->samples_per_sec); - -+ /* -+ * When looking for exact match of configuration ignore the vbps -+ * from NHLT table when ignore_vbps is true -+ */ - if (wfmt->channels == num_ch && wfmt->samples_per_sec == rate && -- vbps == _vbps && bps == _bps) -+ (ignore_vbps || vbps == _vbps) && bps == _bps) - return &cfg->config; - - cfg = (struct nhlt_fmt_cfg *)(cfg->config.caps + cfg->config.size); -@@ -289,6 +293,7 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, - { - struct nhlt_specific_cfg *cfg; - struct nhlt_endpoint *epnt; -+ bool ignore_vbps = false; - struct nhlt_fmt *fmt; - int i; - -@@ -298,7 +303,26 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, - dev_dbg(dev, "Looking for configuration:\n"); - dev_dbg(dev, " vbus_id=%d link_type=%d dir=%d, dev_type=%d\n", - bus_id, link_type, dir, dev_type); -- dev_dbg(dev, " ch=%d fmt=%d/%d rate=%d\n", num_ch, vbps, bps, rate); -+ if (link_type == NHLT_LINK_DMIC && bps == 32 && (vbps == 24 || vbps == 32)) { -+ /* -+ * The DMIC hardware supports only one type of 32 bits sample -+ * size, which is 24 bit sampling on the MSB side and bits[1:0] -+ * are used for indicating the channel number. -+ * It has been observed that some NHLT tables have the vbps -+ * specified as 32 while some uses 24. -+ * The format these variations describe are identical, the -+ * hardware is configured and behaves the same way. -+ * Note: when the samples assumed to be vbps=32 then the 'noise' -+ * introduced by the lower two bits (channel number) have no -+ * real life implication on audio quality. -+ */ -+ dev_dbg(dev, -+ " ch=%d fmt=%d rate=%d (vbps is ignored for DMIC 32bit format)\n", -+ num_ch, bps, rate); -+ ignore_vbps = true; -+ } else { -+ dev_dbg(dev, " ch=%d fmt=%d/%d rate=%d\n", num_ch, vbps, bps, rate); -+ } - dev_dbg(dev, "Endpoint count=%d\n", nhlt->endpoint_count); - - epnt = (struct nhlt_endpoint *)nhlt->desc; -@@ -307,7 +331,8 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt, - if (nhlt_check_ep_match(dev, epnt, bus_id, link_type, dir, dev_type)) { - fmt = (struct nhlt_fmt *)(epnt->config.caps + epnt->config.size); - -- cfg = nhlt_get_specific_cfg(dev, fmt, num_ch, rate, vbps, bps); -+ cfg = nhlt_get_specific_cfg(dev, fmt, num_ch, rate, -+ vbps, bps, ignore_vbps); - if (cfg) - return cfg; - } -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 1c8ffc5cf97f6..5efb3adee48d9 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -7108,6 +7108,7 @@ enum { - ALC290_FIXUP_SUBWOOFER_HSJACK, - ALC269_FIXUP_THINKPAD_ACPI, - ALC269_FIXUP_DMIC_THINKPAD_ACPI, -+ ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO, - ALC255_FIXUP_ACER_MIC_NO_PRESENCE, - ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, - ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, -@@ -7454,6 +7455,14 @@ static const struct hda_fixup alc269_fixups[] = { - .type = HDA_FIXUP_FUNC, - .v.func = alc269_fixup_pincfg_U7x7_headset_mic, - }, -+ [ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO] = { -+ .type = HDA_FIXUP_PINS, -+ .v.pins = (const struct hda_pintbl[]) { -+ { 0x18, 0x03a19020 }, /* headset mic */ -+ { 0x1b, 0x90170150 }, /* speaker */ -+ { } -+ }, -+ }, - [ALC269_FIXUP_AMIC] = { - .type = HDA_FIXUP_PINS, - .v.pins = (const struct hda_pintbl[]) { -@@ -9598,6 +9607,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x8735, "HP ProBook 435 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), - SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT), - SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), -+ SND_PCI_QUIRK(0x103c, 0x876e, "HP ENVY x360 Convertible 13-ay0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), - SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED), - SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED), - SND_PCI_QUIRK(0x103c, 0x8780, "HP ZBook Fury 17 G7 Mobile Workstation", -@@ -9770,17 +9780,20 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS ROG Strix G17 2023 (G713PV)", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), - SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), -+ SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2), - SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), - SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2), - SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2), - SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), -- SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), -+ SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), - SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), - SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), -+ SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), - SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), - SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), - SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2), -+ SND_PCI_QUIRK(0x1043, 0x1f62, "ASUS UX7602ZM", ALC245_FIXUP_CS35L41_SPI_2), - SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401), - SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), - SND_PCI_QUIRK(0x1043, 0x3a20, "ASUS G614JZR", ALC245_FIXUP_CS35L41_SPI_2), -@@ -10032,6 +10045,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC), - SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), -+ SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO), - SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), - SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), - SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), -diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c -index 1dde1f3196acc..808d002826233 100644 ---- a/sound/soc/amd/yc/acp6x-mach.c -+++ b/sound/soc/amd/yc/acp6x-mach.c -@@ -353,6 +353,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_PRODUCT_VERSION, "pang12"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "System76"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "pang13"), -+ } -+ }, - {} - }; - -diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c -index db39abb2a31b5..0b8ecd917a086 100644 ---- a/sound/soc/codecs/cs43130.c -+++ b/sound/soc/codecs/cs43130.c -@@ -579,7 +579,7 @@ static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk, - break; - case SND_SOC_DAIFMT_LEFT_J: - hi_size = bitwidth_sclk; -- frm_delay = 2; -+ frm_delay = 0; - frm_phase = 1; - break; - case SND_SOC_DAIFMT_DSP_A: -@@ -1683,7 +1683,7 @@ static ssize_t hpload_dc_r_show(struct device *dev, - return cs43130_show_dc(dev, buf, HP_RIGHT); - } - --static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = { -+static const u16 cs43130_ac_freq[CS43130_AC_FREQ] = { - 24, - 43, - 93, -@@ -2363,7 +2363,7 @@ static const struct regmap_config cs43130_regmap = { - .use_single_write = true, - }; - --static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = { -+static const u16 cs43130_dc_threshold[CS43130_DC_THRESHOLD] = { - 50, - 120, - }; -diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c -index 9251490548e8c..c8410769188a0 100644 ---- a/sound/soc/codecs/da7219-aad.c -+++ b/sound/soc/codecs/da7219-aad.c -@@ -663,7 +663,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev) - aad_pdata->mic_det_thr = - da7219_aad_fw_mic_det_thr(dev, fw_val32); - else -- aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS; -+ aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_200_OHMS; - - if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0) - aad_pdata->jack_ins_deb = -diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c -index 8af434e14bfba..21a00c86a1398 100644 ---- a/sound/soc/codecs/hdac_hda.c -+++ b/sound/soc/codecs/hdac_hda.c -@@ -124,6 +124,9 @@ static struct snd_soc_dai_driver hdac_hda_dais[] = { - .sig_bits = 24, - }, - }, -+}; -+ -+static struct snd_soc_dai_driver hdac_hda_hdmi_dais[] = { - { - .id = HDAC_HDMI_0_DAI_ID, - .name = "intel-hdmi-hifi1", -@@ -578,8 +581,16 @@ static const struct snd_soc_component_driver hdac_hda_codec = { - .endianness = 1, - }; - -+static const struct snd_soc_component_driver hdac_hda_hdmi_codec = { -+ .probe = hdac_hda_codec_probe, -+ .remove = hdac_hda_codec_remove, -+ .idle_bias_on = false, -+ .endianness = 1, -+}; -+ - static int hdac_hda_dev_probe(struct hdac_device *hdev) - { -+ struct hdac_hda_priv *hda_pvt = dev_get_drvdata(&hdev->dev); - struct hdac_ext_link *hlink; - int ret; - -@@ -592,9 +603,15 @@ static int hdac_hda_dev_probe(struct hdac_device *hdev) - snd_hdac_ext_bus_link_get(hdev->bus, hlink); - - /* ASoC specific initialization */ -- ret = devm_snd_soc_register_component(&hdev->dev, -- &hdac_hda_codec, hdac_hda_dais, -- ARRAY_SIZE(hdac_hda_dais)); -+ if (hda_pvt->need_display_power) -+ ret = devm_snd_soc_register_component(&hdev->dev, -+ &hdac_hda_hdmi_codec, hdac_hda_hdmi_dais, -+ ARRAY_SIZE(hdac_hda_hdmi_dais)); -+ else -+ ret = devm_snd_soc_register_component(&hdev->dev, -+ &hdac_hda_codec, hdac_hda_dais, -+ ARRAY_SIZE(hdac_hda_dais)); -+ - if (ret < 0) { - dev_err(&hdev->dev, "failed to register HDA codec %d\n", ret); - return ret; -diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c -index 1aef281a99727..cd5053cfd5213 100644 ---- a/sound/soc/codecs/nau8822.c -+++ b/sound/soc/codecs/nau8822.c -@@ -184,6 +184,7 @@ static int nau8822_eq_get(struct snd_kcontrol *kcontrol, - struct soc_bytes_ext *params = (void *)kcontrol->private_value; - int i, reg; - u16 reg_val, *val; -+ __be16 tmp; - - val = (u16 *)ucontrol->value.bytes.data; - reg = NAU8822_REG_EQ1; -@@ -192,8 +193,8 @@ static int nau8822_eq_get(struct snd_kcontrol *kcontrol, - /* conversion of 16-bit integers between native CPU format - * and big endian format - */ -- reg_val = cpu_to_be16(reg_val); -- memcpy(val + i, ®_val, sizeof(reg_val)); -+ tmp = cpu_to_be16(reg_val); -+ memcpy(val + i, &tmp, sizeof(tmp)); - } - - return 0; -@@ -216,6 +217,7 @@ static int nau8822_eq_put(struct snd_kcontrol *kcontrol, - void *data; - u16 *val, value; - int i, reg, ret; -+ __be16 *tmp; - - data = kmemdup(ucontrol->value.bytes.data, - params->max, GFP_KERNEL | GFP_DMA); -@@ -228,7 +230,8 @@ static int nau8822_eq_put(struct snd_kcontrol *kcontrol, - /* conversion of 16-bit integers between native CPU format - * and big endian format - */ -- value = be16_to_cpu(*(val + i)); -+ tmp = (__be16 *)(val + i); -+ value = be16_to_cpup(tmp); - ret = snd_soc_component_write(component, reg + i, value); - if (ret) { - dev_err(component->dev, -diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c -index f86fc7cd104d4..60518ee5a86e7 100644 ---- a/sound/soc/codecs/rt5645.c -+++ b/sound/soc/codecs/rt5645.c -@@ -448,6 +448,7 @@ struct rt5645_priv { - struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; - struct rt5645_eq_param_s *eq_param; - struct timer_list btn_check_timer; -+ struct mutex jd_mutex; - - int codec_type; - int sysclk; -@@ -3189,6 +3190,8 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse - rt5645_enable_push_button_irq(component, true); - } - } else { -+ if (rt5645->en_button_func) -+ rt5645_enable_push_button_irq(component, false); - snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); - snd_soc_dapm_sync(dapm); - rt5645->jack_type = SND_JACK_HEADPHONE; -@@ -3269,6 +3272,8 @@ static void rt5645_jack_detect_work(struct work_struct *work) - if (!rt5645->component) - return; - -+ mutex_lock(&rt5645->jd_mutex); -+ - switch (rt5645->pdata.jd_mode) { - case 0: /* Not using rt5645 JD */ - if (rt5645->gpiod_hp_det) { -@@ -3295,7 +3300,7 @@ static void rt5645_jack_detect_work(struct work_struct *work) - - if (!val && (rt5645->jack_type == 0)) { /* jack in */ - report = rt5645_jack_detect(rt5645->component, 1); -- } else if (!val && rt5645->jack_type != 0) { -+ } else if (!val && rt5645->jack_type == SND_JACK_HEADSET) { - /* for push button and jack out */ - btn_type = 0; - if (snd_soc_component_read(rt5645->component, RT5645_INT_IRQ_ST) & 0x4) { -@@ -3351,6 +3356,8 @@ static void rt5645_jack_detect_work(struct work_struct *work) - rt5645_jack_detect(rt5645->component, 0); - } - -+ mutex_unlock(&rt5645->jd_mutex); -+ - snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE); - snd_soc_jack_report(rt5645->mic_jack, report, SND_JACK_MICROPHONE); - if (rt5645->en_button_func) -@@ -4119,6 +4126,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c) - } - timer_setup(&rt5645->btn_check_timer, rt5645_btn_check_callback, 0); - -+ mutex_init(&rt5645->jd_mutex); - INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work); - INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work); - -diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c -index 010a394c705c1..1becbf2c6ffad 100644 ---- a/sound/soc/codecs/wm8974.c -+++ b/sound/soc/codecs/wm8974.c -@@ -186,7 +186,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0), - - /* Boost mixer */ - static const struct snd_kcontrol_new wm8974_boost_mixer[] = { --SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 1), -+SOC_DAPM_SINGLE("PGA Switch", WM8974_INPPGA, 6, 1, 1), - }; - - /* Input PGA */ -@@ -246,8 +246,8 @@ static const struct snd_soc_dapm_route wm8974_dapm_routes[] = { - - /* Boost Mixer */ - {"ADC", NULL, "Boost Mixer"}, -- {"Boost Mixer", "Aux Switch", "Aux Input"}, -- {"Boost Mixer", NULL, "Input PGA"}, -+ {"Boost Mixer", NULL, "Aux Input"}, -+ {"Boost Mixer", "PGA Switch", "Input PGA"}, - {"Boost Mixer", NULL, "MICP"}, - - /* Input PGA */ -diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c -index 783c201259921..797d0a48d6066 100644 ---- a/sound/soc/intel/boards/bytcr_rt5640.c -+++ b/sound/soc/intel/boards/bytcr_rt5640.c -@@ -83,6 +83,7 @@ enum { - #define BYT_RT5640_HSMIC2_ON_IN1 BIT(27) - #define BYT_RT5640_JD_HP_ELITEP_1000G2 BIT(28) - #define BYT_RT5640_USE_AMCR0F28 BIT(29) -+#define BYT_RT5640_SWAPPED_SPEAKERS BIT(30) - - #define BYTCR_INPUT_DEFAULTS \ - (BYT_RT5640_IN3_MAP | \ -@@ -157,6 +158,8 @@ static void log_quirks(struct device *dev) - dev_info(dev, "quirk MONO_SPEAKER enabled\n"); - if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) - dev_info(dev, "quirk NO_SPEAKERS enabled\n"); -+ if (byt_rt5640_quirk & BYT_RT5640_SWAPPED_SPEAKERS) -+ dev_info(dev, "quirk SWAPPED_SPEAKERS enabled\n"); - if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) - dev_info(dev, "quirk LINEOUT enabled\n"); - if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2) -@@ -884,6 +887,19 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { - BYT_RT5640_SSP0_AIF1 | - BYT_RT5640_MCLK_EN), - }, -+ { -+ /* Medion Lifetab S10346 */ -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), -+ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), -+ /* Above strings are much too generic, also match on BIOS date */ -+ DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"), -+ }, -+ .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | -+ BYT_RT5640_SWAPPED_SPEAKERS | -+ BYT_RT5640_SSP0_AIF1 | -+ BYT_RT5640_MCLK_EN), -+ }, - { /* Mele PCG03 Mini PC */ - .matches = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Mini PC"), -@@ -1609,11 +1625,11 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) - const char *platform_name; - struct acpi_device *adev; - struct device *codec_dev; -+ const char *cfg_spk; - bool sof_parent; - int ret_val = 0; - int dai_index = 0; -- int i, cfg_spk; -- int aif; -+ int i, aif; - - is_bytcr = false; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -@@ -1773,13 +1789,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) - } - - if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) { -- cfg_spk = 0; -+ cfg_spk = "0"; - spk_type = "none"; - } else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) { -- cfg_spk = 1; -+ cfg_spk = "1"; - spk_type = "mono"; -+ } else if (byt_rt5640_quirk & BYT_RT5640_SWAPPED_SPEAKERS) { -+ cfg_spk = "swapped"; -+ spk_type = "swapped"; - } else { -- cfg_spk = 2; -+ cfg_spk = "2"; - spk_type = "stereo"; - } - -@@ -1794,7 +1813,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) - headset2_string = " cfg-hs2:in1"; - - snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), -- "cfg-spk:%d cfg-mic:%s aif:%d%s%s", cfg_spk, -+ "cfg-spk:%s cfg-mic:%s aif:%d%s%s", cfg_spk, - map_name[BYT_RT5640_MAP(byt_rt5640_quirk)], aif, - lineout_string, headset2_string); - byt_rt5640_card.components = byt_rt5640_components; -diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c -index 879ebba528322..463ffb85121d3 100644 ---- a/sound/soc/intel/boards/skl_hda_dsp_generic.c -+++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c -@@ -157,6 +157,8 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params) - card->dapm_widgets = skl_hda_widgets; - card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets); - if (!ctx->idisp_codec) { -+ card->dapm_routes = &skl_hda_map[IDISP_ROUTE_COUNT]; -+ num_route -= IDISP_ROUTE_COUNT; - for (i = 0; i < IDISP_DAI_COUNT; i++) { - skl_hda_be_dai_links[i].codecs = dummy_codec; - skl_hda_be_dai_links[i].num_codecs = -diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c -index 1015716f93361..adee4be2dea71 100644 ---- a/sound/soc/intel/skylake/skl-pcm.c -+++ b/sound/soc/intel/skylake/skl-pcm.c -@@ -251,8 +251,10 @@ static int skl_pcm_open(struct snd_pcm_substream *substream, - snd_pcm_set_sync(substream); - - mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); -- if (!mconfig) -+ if (!mconfig) { -+ kfree(dma_params); - return -EINVAL; -+ } - - skl_tplg_d0i3_get(skl, mconfig->d0i3_caps); - -@@ -1471,6 +1473,7 @@ int skl_platform_register(struct device *dev) - dais = krealloc(skl->dais, sizeof(skl_fe_dai) + - sizeof(skl_platform_dai), GFP_KERNEL); - if (!dais) { -+ kfree(skl->dais); - ret = -ENOMEM; - goto err; - } -@@ -1483,8 +1486,10 @@ int skl_platform_register(struct device *dev) - - ret = devm_snd_soc_register_component(dev, &skl_component, - skl->dais, num_dais); -- if (ret) -+ if (ret) { -+ kfree(skl->dais); - dev_err(dev, "soc component registration failed %d\n", ret); -+ } - err: - return ret; - } -diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c -index 7a425271b08b1..fd9624ad5f72b 100644 ---- a/sound/soc/intel/skylake/skl-sst-ipc.c -+++ b/sound/soc/intel/skylake/skl-sst-ipc.c -@@ -1003,8 +1003,10 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc, - - reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK; - buf = krealloc(reply.data, reply.size, GFP_KERNEL); -- if (!buf) -+ if (!buf) { -+ kfree(reply.data); - return -ENOMEM; -+ } - *payload = buf; - *bytes = reply.size; - -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/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c -index f2ec2a6c2e0f3..a0dfd7de431fe 100644 ---- a/sound/soc/sof/intel/hda-codec.c -+++ b/sound/soc/sof/intel/hda-codec.c -@@ -54,8 +54,16 @@ static int request_codec_module(struct hda_codec *codec) - - static int hda_codec_load_module(struct hda_codec *codec) - { -- int ret = request_codec_module(codec); -+ int ret; -+ -+ ret = snd_hdac_device_register(&codec->core); -+ if (ret) { -+ dev_err(&codec->core.dev, "failed to register hdac device\n"); -+ put_device(&codec->core.dev); -+ return ret; -+ } - -+ ret = request_codec_module(codec); - if (ret <= 0) { - codec->probe_id = HDA_CODEC_ID_GENERIC; - ret = request_codec_module(codec); -@@ -112,7 +120,6 @@ EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC); - static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, int type) - { - struct hda_codec *codec; -- int ret; - - codec = snd_hda_codec_device_init(to_hda_bus(bus), addr, "ehdaudio%dD%d", bus->idx, addr); - if (IS_ERR(codec)) { -@@ -122,13 +129,6 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i - - codec->core.type = type; - -- ret = snd_hdac_device_register(&codec->core); -- if (ret) { -- dev_err(bus->dev, "failed to register hdac device\n"); -- put_device(&codec->core.dev); -- return ERR_PTR(ret); -- } -- - return codec; - } - -diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c -index a38b89c280306..37da902545a41 100644 ---- a/tools/testing/selftests/alsa/mixer-test.c -+++ b/tools/testing/selftests/alsa/mixer-test.c -@@ -177,7 +177,7 @@ static void find_controls(void) - err = snd_ctl_elem_info(card_data->handle, - ctl_data->info); - if (err < 0) { -- ksft_print_msg("%s getting info for %d\n", -+ ksft_print_msg("%s getting info for %s\n", - snd_strerror(err), - ctl_data->name); - } diff --git a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.74-75.patch b/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.74-75.patch deleted file mode 100644 index 467e3c0a56c7..000000000000 --- a/patch/kernel/archive/sun50iw9-btt-6.1/linux-6.1.74-75.patch +++ /dev/null @@ -1,15017 +0,0 @@ -diff --git a/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml b/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml -index f333ee2288e76..11ae8ec3c7394 100644 ---- a/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml -+++ b/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml -@@ -126,7 +126,7 @@ examples: - - | - #include - -- gpio@e000a000 { -+ gpio@a0020000 { - compatible = "xlnx,xps-gpio-1.00.a"; - reg = <0xa0020000 0x10000>; - #gpio-cells = <2>; -diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml -index 9cfc0c7d23e06..46730687c6624 100644 ---- a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml -+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml -@@ -61,6 +61,9 @@ properties: - - description: used for 1st data pipe from RDMA - - description: used for 2nd data pipe from RDMA - -+ '#dma-cells': -+ const: 1 -+ - required: - - compatible - - reg -@@ -70,6 +73,7 @@ required: - - clocks - - iommus - - mboxes -+ - '#dma-cells' - - additionalProperties: false - -@@ -80,16 +84,17 @@ examples: - #include - #include - -- mdp3_rdma0: mdp3-rdma0@14001000 { -- compatible = "mediatek,mt8183-mdp3-rdma"; -- reg = <0x14001000 0x1000>; -- mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; -- mediatek,gce-events = , -- ; -- power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; -- clocks = <&mmsys CLK_MM_MDP_RDMA0>, -- <&mmsys CLK_MM_MDP_RSZ1>; -- iommus = <&iommu>; -- mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>, -- <&gce 21 CMDQ_THR_PRIO_LOWEST>; -+ dma-controller@14001000 { -+ compatible = "mediatek,mt8183-mdp3-rdma"; -+ reg = <0x14001000 0x1000>; -+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; -+ mediatek,gce-events = , -+ ; -+ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; -+ clocks = <&mmsys CLK_MM_MDP_RDMA0>, -+ <&mmsys CLK_MM_MDP_RSZ1>; -+ iommus = <&iommu>; -+ mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>, -+ <&gce 21 CMDQ_THR_PRIO_LOWEST>; -+ #dma-cells = <1>; - }; -diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml -index 0baa77198fa21..64ea98aa05928 100644 ---- a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml -+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml -@@ -50,6 +50,9 @@ properties: - iommus: - maxItems: 1 - -+ '#dma-cells': -+ const: 1 -+ - required: - - compatible - - reg -@@ -58,6 +61,7 @@ required: - - power-domains - - clocks - - iommus -+ - '#dma-cells' - - additionalProperties: false - -@@ -68,13 +72,14 @@ examples: - #include - #include - -- mdp3_wrot0: mdp3-wrot0@14005000 { -- compatible = "mediatek,mt8183-mdp3-wrot"; -- reg = <0x14005000 0x1000>; -- mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; -- mediatek,gce-events = , -- ; -- power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; -- clocks = <&mmsys CLK_MM_MDP_WROT0>; -- iommus = <&iommu>; -+ dma-controller@14005000 { -+ compatible = "mediatek,mt8183-mdp3-wrot"; -+ reg = <0x14005000 0x1000>; -+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; -+ mediatek,gce-events = , -+ ; -+ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; -+ clocks = <&mmsys CLK_MM_MDP_WROT0>; -+ iommus = <&iommu>; -+ #dma-cells = <1>; - }; -diff --git a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml -index b3661d7d43572..2a0ad332f5ced 100644 ---- a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml -+++ b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml -@@ -90,15 +90,16 @@ properties: - description: connection point for input on the parallel interface - - properties: -- bus-type: -- enum: [5, 6] -- - endpoint: - $ref: video-interfaces.yaml# - unevaluatedProperties: false - -- required: -- - bus-type -+ properties: -+ bus-type: -+ enum: [5, 6] -+ -+ required: -+ - bus-type - - anyOf: - - required: -diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst -index 44deb52beeb47..d0b241628cf13 100644 ---- a/Documentation/driver-api/pci/p2pdma.rst -+++ b/Documentation/driver-api/pci/p2pdma.rst -@@ -83,19 +83,9 @@ this to include other types of resources like doorbells. - Client Drivers - -------------- - --A client driver typically only has to conditionally change its DMA map --routine to use the mapping function :c:func:`pci_p2pdma_map_sg()` instead --of the usual :c:func:`dma_map_sg()` function. Memory mapped in this --way does not need to be unmapped. -- --The client may also, optionally, make use of --:c:func:`is_pci_p2pdma_page()` to determine when to use the P2P mapping --functions and when to use the regular mapping functions. In some --situations, it may be more appropriate to use a flag to indicate a --given request is P2P memory and map appropriately. It is important to --ensure that struct pages that back P2P memory stay out of code that --does not have support for them as other code may treat the pages as --regular memory which may not be appropriate. -+A client driver only has to use the mapping API :c:func:`dma_map_sg()` -+and :c:func:`dma_unmap_sg()` functions as usual, and the implementation -+will do the right thing for the P2P capable memory. - - - Orchestrator Drivers -diff --git a/Makefile b/Makefile -index 63125d1ffd9cf..7cd49d9eadbfc 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 1 --SUBLEVEL = 74 -+SUBLEVEL = 75 - EXTRAVERSION = - NAME = Curry Ramen - -diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi -index 4b57e9f5bc648..2b3927a829b70 100644 ---- a/arch/arm/boot/dts/qcom-apq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi -@@ -750,7 +750,7 @@ - - xoadc: xoadc@197 { - compatible = "qcom,pm8921-adc"; -- reg = <197>; -+ reg = <0x197>; - interrupts-extended = <&pmicintc 78 IRQ_TYPE_EDGE_RISING>; - #address-cells = <2>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/qcom-sdx65.dtsi b/arch/arm/boot/dts/qcom-sdx65.dtsi -index ecb9171e4da5f..ebb78b489e638 100644 ---- a/arch/arm/boot/dts/qcom-sdx65.dtsi -+++ b/arch/arm/boot/dts/qcom-sdx65.dtsi -@@ -401,7 +401,7 @@ - reg = <0x0c264000 0x1000>; - }; - -- spmi_bus: qcom,spmi@c440000 { -+ spmi_bus: spmi@c440000 { - compatible = "qcom,spmi-pmic-arb"; - reg = <0xc440000 0xd00>, - <0xc600000 0x2000000>, -diff --git a/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts b/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts -index e539cc80bef81..942a6ca38d97e 100644 ---- a/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts -+++ b/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts -@@ -11,7 +11,7 @@ - - / { - model = "STMicroelectronics STM32MP157A-DK1 SCMI Discovery Board"; -- compatible = "st,stm32mp157a-dk1-scmi", "st,stm32mp157a-dk1", "st,stm32mp157"; -+ compatible = "st,stm32mp157a-dk1-scmi", "st,stm32mp157"; - - reserved-memory { - optee@de000000 { -diff --git a/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts b/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts -index 97e4f94b0a24e..99c4ff1f5c214 100644 ---- a/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts -+++ b/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts -@@ -11,7 +11,7 @@ - - / { - model = "STMicroelectronics STM32MP157C-DK2 SCMI Discovery Board"; -- compatible = "st,stm32mp157c-dk2-scmi", "st,stm32mp157c-dk2", "st,stm32mp157"; -+ compatible = "st,stm32mp157c-dk2-scmi", "st,stm32mp157"; - - reserved-memory { - optee@de000000 { -diff --git a/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts b/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts -index 9cf0a44d2f47e..21010458b36f5 100644 ---- a/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts -+++ b/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts -@@ -11,7 +11,7 @@ - - / { - model = "STMicroelectronics STM32MP157C-ED1 SCMI eval daughter"; -- compatible = "st,stm32mp157c-ed1-scmi", "st,stm32mp157c-ed1", "st,stm32mp157"; -+ compatible = "st,stm32mp157c-ed1-scmi", "st,stm32mp157"; - - reserved-memory { - optee@fe000000 { -diff --git a/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts b/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts -index 3b9dd6f4ccc96..d376371499193 100644 ---- a/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts -+++ b/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts -@@ -11,8 +11,7 @@ - - / { - model = "STMicroelectronics STM32MP157C-EV1 SCMI eval daughter on eval mother"; -- compatible = "st,stm32mp157c-ev1-scmi", "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", -- "st,stm32mp157"; -+ compatible = "st,stm32mp157c-ev1-scmi", "st,stm32mp157c-ed1", "st,stm32mp157"; - - reserved-memory { - optee@fe000000 { -diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig -index c8cbd9a307914..672ffb0b5f3af 100644 ---- a/arch/arm/mach-davinci/Kconfig -+++ b/arch/arm/mach-davinci/Kconfig -@@ -4,12 +4,14 @@ menuconfig ARCH_DAVINCI - bool "TI DaVinci" - depends on ARCH_MULTI_V5 - depends on CPU_LITTLE_ENDIAN -+ select CPU_ARM926T - select DAVINCI_TIMER - select ZONE_DMA - select PM_GENERIC_DOMAINS if PM - select PM_GENERIC_DOMAINS_OF if PM && OF - select REGMAP_MMIO - select RESET_CONTROLLER -+ select PINCTRL - select PINCTRL_SINGLE - - if ARCH_DAVINCI -diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi -index d583db18f74cc..7a410d73600b1 100644 ---- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi -+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi -@@ -1303,7 +1303,7 @@ - assigned-clocks = <&clk IMX8MM_CLK_GPU3D_CORE>, - <&clk IMX8MM_GPU_PLL_OUT>; - assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>; -- assigned-clock-rates = <0>, <1000000000>; -+ assigned-clock-rates = <0>, <800000000>; - power-domains = <&pgc_gpu>; - }; - -@@ -1318,7 +1318,7 @@ - assigned-clocks = <&clk IMX8MM_CLK_GPU2D_CORE>, - <&clk IMX8MM_GPU_PLL_OUT>; - assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>; -- assigned-clock-rates = <0>, <1000000000>; -+ assigned-clock-rates = <0>, <800000000>; - power-domains = <&pgc_gpu>; - }; - -diff --git a/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi b/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi -index 970047f2dabd5..c06e011a6c3ff 100644 ---- a/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi -+++ b/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi -@@ -25,9 +25,6 @@ - gpios = <&gpio28 0 0>; - - regulators { -- #address-cells = <1>; -- #size-cells = <0>; -- - ldo3: ldo3 { /* HDMI */ - regulator-name = "ldo3"; - regulator-min-microvolt = <1500000>; -diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts -index 200f97e1c4c9c..37350e5fa253a 100644 ---- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts -+++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts -@@ -130,7 +130,7 @@ - compatible = "microchip,mcp7940x"; - reg = <0x6f>; - interrupt-parent = <&gpiosb>; -- interrupts = <5 0>; /* GPIO2_5 */ -+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO2_5 */ - }; - }; - -diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi -index 10779a9947fe2..d5d9b954c449a 100644 ---- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi -@@ -1586,7 +1586,7 @@ - mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>; - }; - -- mdp3-rdma0@14001000 { -+ dma-controller0@14001000 { - compatible = "mediatek,mt8183-mdp3-rdma"; - reg = <0 0x14001000 0 0x1000>; - mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; -@@ -1598,6 +1598,7 @@ - iommus = <&iommu M4U_PORT_MDP_RDMA0>; - mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>, - <&gce 21 CMDQ_THR_PRIO_LOWEST 0>; -+ #dma-cells = <1>; - }; - - mdp3-rsz0@14003000 { -@@ -1618,7 +1619,7 @@ - clocks = <&mmsys CLK_MM_MDP_RSZ1>; - }; - -- mdp3-wrot0@14005000 { -+ dma-controller@14005000 { - compatible = "mediatek,mt8183-mdp3-wrot"; - reg = <0 0x14005000 0 0x1000>; - mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; -@@ -1627,6 +1628,7 @@ - power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; - clocks = <&mmsys CLK_MM_MDP_WROT0>; - iommus = <&iommu M4U_PORT_MDP_WROT0>; -+ #dma-cells = <1>; - }; - - mdp3-wdma@14006000 { -diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -index 43ff8f1f1475c..1533c61cb106c 100644 ---- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -146,7 +146,7 @@ - ranges; - - rpm_msg_ram: memory@60000 { -- reg = <0x0 0x60000 0x0 0x6000>; -+ reg = <0x0 0x00060000 0x0 0x6000>; - no-map; - }; - -@@ -181,7 +181,7 @@ - - prng: qrng@e1000 { - compatible = "qcom,prng-ee"; -- reg = <0x0 0xe3000 0x0 0x1000>; -+ reg = <0x0 0x000e3000 0x0 0x1000>; - clocks = <&gcc GCC_PRNG_AHB_CLK>; - clock-names = "core"; - }; -@@ -201,8 +201,8 @@ - compatible = "qcom,crypto-v5.1"; - reg = <0x0 0x0073a000 0x0 0x6000>; - clocks = <&gcc GCC_CRYPTO_AHB_CLK>, -- <&gcc GCC_CRYPTO_AXI_CLK>, -- <&gcc GCC_CRYPTO_CLK>; -+ <&gcc GCC_CRYPTO_AXI_CLK>, -+ <&gcc GCC_CRYPTO_CLK>; - clock-names = "iface", "bus", "core"; - dmas = <&cryptobam 2>, <&cryptobam 3>; - dma-names = "rx", "tx"; -@@ -272,7 +272,7 @@ - reg = <0x0 0x078b1000 0x0 0x200>; - interrupts = ; - clocks = <&gcc GCC_BLSP1_UART3_APPS_CLK>, -- <&gcc GCC_BLSP1_AHB_CLK>; -+ <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - status = "disabled"; - }; -@@ -285,7 +285,7 @@ - interrupts = ; - spi-max-frequency = <50000000>; - clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>, -- <&gcc GCC_BLSP1_AHB_CLK>; -+ <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 12>, <&blsp_dma 13>; - dma-names = "tx", "rx"; -@@ -300,7 +300,7 @@ - interrupts = ; - spi-max-frequency = <50000000>; - clocks = <&gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>, -- <&gcc GCC_BLSP1_AHB_CLK>; -+ <&gcc GCC_BLSP1_AHB_CLK>; - clock-names = "core", "iface"; - dmas = <&blsp_dma 14>, <&blsp_dma 15>; - dma-names = "tx", "rx"; -@@ -358,8 +358,8 @@ - clock-names = "core", "aon"; - - dmas = <&qpic_bam 0>, -- <&qpic_bam 1>, -- <&qpic_bam 2>; -+ <&qpic_bam 1>, -+ <&qpic_bam 2>; - dma-names = "tx", "rx", "cmd"; - pinctrl-0 = <&qpic_pins>; - pinctrl-names = "default"; -@@ -372,10 +372,10 @@ - #size-cells = <2>; - interrupt-controller; - #interrupt-cells = <0x3>; -- reg = <0x0 0x0b000000 0x0 0x1000>, /*GICD*/ -- <0x0 0x0b002000 0x0 0x1000>, /*GICC*/ -- <0x0 0x0b001000 0x0 0x1000>, /*GICH*/ -- <0x0 0x0b004000 0x0 0x1000>; /*GICV*/ -+ reg = <0x0 0x0b000000 0x0 0x1000>, /*GICD*/ -+ <0x0 0x0b002000 0x0 0x1000>, /*GICC*/ -+ <0x0 0x0b001000 0x0 0x1000>, /*GICH*/ -+ <0x0 0x0b004000 0x0 0x1000>; /*GICV*/ - interrupts = ; - ranges = <0 0 0 0xb00a000 0 0xffd>; - -@@ -388,7 +388,7 @@ - - pcie_phy: phy@84000 { - compatible = "qcom,ipq6018-qmp-pcie-phy"; -- reg = <0x0 0x84000 0x0 0x1bc>; /* Serdes PLL */ -+ reg = <0x0 0x00084000 0x0 0x1bc>; /* Serdes PLL */ - status = "disabled"; - #address-cells = <2>; - #size-cells = <2>; -@@ -404,9 +404,10 @@ - "common"; - - pcie_phy0: phy@84200 { -- reg = <0x0 0x84200 0x0 0x16c>, /* Serdes Tx */ -- <0x0 0x84400 0x0 0x200>, /* Serdes Rx */ -- <0x0 0x84800 0x0 0x4f4>; /* PCS: Lane0, COM, PCIE */ -+ reg = <0x0 0x00084200 0x0 0x16c>, /* Serdes Tx */ -+ <0x0 0x00084400 0x0 0x200>, /* Serdes Rx */ -+ <0x0 0x00084800 0x0 0x1f0>, /* PCS: Lane0, COM, PCIE */ -+ <0x0 0x00084c00 0x0 0xf4>; /* pcs_misc */ - #phy-cells = <0>; - - clocks = <&gcc GCC_PCIE0_PIPE_CLK>; -@@ -628,7 +629,7 @@ - #address-cells = <1>; - #size-cells = <0>; - compatible = "qcom,ipq6018-mdio", "qcom,ipq4019-mdio"; -- reg = <0x0 0x90000 0x0 0x64>; -+ reg = <0x0 0x00090000 0x0 0x64>; - clocks = <&gcc GCC_MDIO_AHB_CLK>; - clock-names = "gcc_mdio_ahb_clk"; - status = "disabled"; -@@ -636,7 +637,7 @@ - - qusb_phy_1: qusb@59000 { - compatible = "qcom,ipq6018-qusb2-phy"; -- reg = <0x0 0x059000 0x0 0x180>; -+ reg = <0x0 0x00059000 0x0 0x180>; - #phy-cells = <0>; - - clocks = <&gcc GCC_USB1_PHY_CFG_AHB_CLK>, -@@ -668,23 +669,23 @@ - status = "disabled"; - - dwc_1: usb@7000000 { -- compatible = "snps,dwc3"; -- reg = <0x0 0x7000000 0x0 0xcd00>; -- interrupts = ; -- phys = <&qusb_phy_1>; -- phy-names = "usb2-phy"; -- tx-fifo-resize; -- snps,is-utmi-l1-suspend; -- snps,hird-threshold = /bits/ 8 <0x0>; -- snps,dis_u2_susphy_quirk; -- snps,dis_u3_susphy_quirk; -- dr_mode = "host"; -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x07000000 0x0 0xcd00>; -+ interrupts = ; -+ phys = <&qusb_phy_1>; -+ phy-names = "usb2-phy"; -+ tx-fifo-resize; -+ snps,is-utmi-l1-suspend; -+ snps,hird-threshold = /bits/ 8 <0x0>; -+ snps,dis_u2_susphy_quirk; -+ snps,dis_u3_susphy_quirk; -+ dr_mode = "host"; - }; - }; - - ssphy_0: ssphy@78000 { - compatible = "qcom,ipq6018-qmp-usb3-phy"; -- reg = <0x0 0x78000 0x0 0x1C4>; -+ reg = <0x0 0x00078000 0x0 0x1c4>; - #address-cells = <2>; - #size-cells = <2>; - ranges; -@@ -701,7 +702,7 @@ - usb0_ssphy: phy@78200 { - reg = <0x0 0x00078200 0x0 0x130>, /* Tx */ - <0x0 0x00078400 0x0 0x200>, /* Rx */ -- <0x0 0x00078800 0x0 0x1F8>, /* PCS */ -+ <0x0 0x00078800 0x0 0x1f8>, /* PCS */ - <0x0 0x00078600 0x0 0x044>; /* PCS misc */ - #phy-cells = <0>; - #clock-cells = <0>; -@@ -713,7 +714,7 @@ - - qusb_phy_0: qusb@79000 { - compatible = "qcom,ipq6018-qusb2-phy"; -- reg = <0x0 0x079000 0x0 0x180>; -+ reg = <0x0 0x00079000 0x0 0x180>; - #phy-cells = <0>; - - clocks = <&gcc GCC_USB0_PHY_CFG_AHB_CLK>, -@@ -726,7 +727,7 @@ - - usb3: usb@8af8800 { - compatible = "qcom,ipq6018-dwc3", "qcom,dwc3"; -- reg = <0x0 0x8AF8800 0x0 0x400>; -+ reg = <0x0 0x8af8800 0x0 0x400>; - #address-cells = <2>; - #size-cells = <2>; - ranges; -@@ -745,14 +746,14 @@ - <&gcc GCC_USB0_MOCK_UTMI_CLK>; - assigned-clock-rates = <133330000>, - <133330000>, -- <20000000>; -+ <24000000>; - - resets = <&gcc GCC_USB0_BCR>; - status = "disabled"; - - dwc_0: usb@8a00000 { - compatible = "snps,dwc3"; -- reg = <0x0 0x8A00000 0x0 0xcd00>; -+ reg = <0x0 0x8a00000 0x0 0xcd00>; - interrupts = ; - phys = <&qusb_phy_0>, <&usb0_ssphy>; - phy-names = "usb2-phy", "usb3-phy"; -diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts -index 9731a7c63d53b..1defbe0404e2e 100644 ---- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts -+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts -@@ -63,8 +63,8 @@ - function = LED_FUNCTION_INDICATOR; - color = ; - gpios = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; -- linux,default-trigger = "panic-indicator"; - default-state = "off"; -+ panic-indicator; - }; - - led-wlan { -diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi -index 6f0ee4e13ef1d..78e537f1d7965 100644 ---- a/arch/arm64/boot/dts/qcom/sc7180.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi -@@ -3378,7 +3378,7 @@ - compatible = "qcom,apss-wdt-sc7180", "qcom,kpss-wdt"; - reg = <0 0x17c10000 0 0x1000>; - clocks = <&sleep_clk>; -- interrupts = ; -+ interrupts = ; - }; - - timer@17c20000{ -diff --git a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi -index 25f31c81b2b74..efe6ea538ad21 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi -@@ -56,6 +56,26 @@ - }; - }; - -+&lpass_aon { -+ status = "okay"; -+}; -+ -+&lpass_core { -+ status = "okay"; -+}; -+ -+&lpass_hm { -+ status = "okay"; -+}; -+ -+&lpasscc { -+ status = "okay"; -+}; -+ -+&pdc_reset { -+ status = "okay"; -+}; -+ - /* The PMIC PON code isn't compatible w/ how Chrome EC/BIOS handle things. */ - &pmk8350_pon { - status = "disabled"; -@@ -93,6 +113,10 @@ - reg = <0x0 0x9c900000 0x0 0x800000>; - }; - -+&watchdog { -+ status = "okay"; -+}; -+ - &wifi { - status = "okay"; - -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index aea356c63b9a3..7fc8c20450223 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -888,6 +888,7 @@ - - bus-width = <8>; - supports-cqe; -+ dma-coherent; - - qcom,dll-config = <0x0007642c>; - qcom,ddr-config = <0x80040868>; -@@ -2187,6 +2188,7 @@ - clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>; - clock-names = "iface"; - #clock-cells = <1>; -+ status = "reserved"; /* Owned by ADSP firmware */ - }; - - lpass_rx_macro: codec@3200000 { -@@ -2339,6 +2341,7 @@ - clock-names = "bi_tcxo", "bi_tcxo_ao", "iface"; - #clock-cells = <1>; - #power-domain-cells = <1>; -+ status = "reserved"; /* Owned by ADSP firmware */ - }; - - lpass_core: clock-controller@3900000 { -@@ -2349,6 +2352,7 @@ - power-domains = <&lpass_hm LPASS_CORE_CC_LPASS_CORE_HM_GDSC>; - #clock-cells = <1>; - #power-domain-cells = <1>; -+ status = "reserved"; /* Owned by ADSP firmware */ - }; - - lpass_cpu: audio@3987000 { -@@ -2419,6 +2423,7 @@ - clock-names = "bi_tcxo"; - #clock-cells = <1>; - #power-domain-cells = <1>; -+ status = "reserved"; /* Owned by ADSP firmware */ - }; - - lpass_ag_noc: interconnect@3c40000 { -@@ -2529,7 +2534,8 @@ - "cx_mem", - "cx_dbgc"; - interrupts = ; -- iommus = <&adreno_smmu 0 0x401>; -+ iommus = <&adreno_smmu 0 0x400>, -+ <&adreno_smmu 1 0x400>; - operating-points-v2 = <&gpu_opp_table>; - qcom,gmu = <&gmu>; - interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; -@@ -2696,6 +2702,7 @@ - "gpu_cc_hub_aon_clk"; - - power-domains = <&gpucc GPU_CC_CX_GDSC>; -+ dma-coherent; - }; - - remoteproc_mpss: remoteproc@4080000 { -@@ -3265,6 +3272,7 @@ - operating-points-v2 = <&sdhc2_opp_table>; - - bus-width = <4>; -+ dma-coherent; - - qcom,dll-config = <0x0007642c>; - -@@ -3386,8 +3394,8 @@ - assigned-clock-rates = <19200000>, <200000000>; - - interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>, -- <&pdc 12 IRQ_TYPE_EDGE_RISING>, -- <&pdc 13 IRQ_TYPE_EDGE_RISING>; -+ <&pdc 12 IRQ_TYPE_EDGE_BOTH>, -+ <&pdc 13 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "hs_phy_irq", - "dp_hs_phy_irq", - "dm_hs_phy_irq"; -@@ -4195,6 +4203,7 @@ - compatible = "qcom,sc7280-pdc-global"; - reg = <0 0x0b5e0000 0 0x20000>; - #reset-cells = <1>; -+ status = "reserved"; /* Owned by firmware */ - }; - - tsens0: thermal-sensor@c263000 { -@@ -5186,11 +5195,12 @@ - }; - }; - -- watchdog@17c10000 { -+ watchdog: watchdog@17c10000 { - compatible = "qcom,apss-wdt-sc7280", "qcom,kpss-wdt"; - reg = <0 0x17c10000 0 0x1000>; - clocks = <&sleep_clk>; -- interrupts = ; -+ interrupts = ; -+ status = "reserved"; /* Owned by Gunyah hyp */ - }; - - timer@17c20000 { -diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi -index 405835ad28bcd..7e3aaf5de3f5c 100644 ---- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi -@@ -1653,7 +1653,7 @@ - compatible = "qcom,apss-wdt-sc8280xp", "qcom,kpss-wdt"; - reg = <0 0x17c10000 0 0x1000>; - clocks = <&sleep_clk>; -- interrupts = ; -+ interrupts = ; - }; - - timer@17c20000 { -diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -index 8c9ccf5b4ea41..135ff4368c4a6 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts -@@ -66,8 +66,8 @@ - function = LED_FUNCTION_INDICATOR; - color = ; - gpios = <&pm8998_gpio 13 GPIO_ACTIVE_HIGH>; -- linux,default-trigger = "panic-indicator"; - default-state = "off"; -+ panic-indicator; - }; - - led-1 { -diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi -index 52c9f5639f8a2..1e6841902900c 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi -@@ -5019,7 +5019,7 @@ - compatible = "qcom,apss-wdt-sdm845", "qcom,kpss-wdt"; - reg = <0 0x17980000 0 0x1000>; - clocks = <&sleep_clk>; -- interrupts = ; -+ interrupts = ; - }; - - apss_shared: mailbox@17990000 { -diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi -index cea7ca3f326fc..9da373090593c 100644 ---- a/arch/arm64/boot/dts/qcom/sm6350.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi -@@ -1462,7 +1462,7 @@ - compatible = "qcom,apss-wdt-sm6350", "qcom,kpss-wdt"; - reg = <0 0x17c10000 0 0x1000>; - clocks = <&sleep_clk>; -- interrupts = ; -+ interrupts = ; - }; - - timer@17c20000 { -diff --git a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts -index 3331ee957d648..368da4c7f41be 100644 ---- a/arch/arm64/boot/dts/qcom/sm8150-hdk.dts -+++ b/arch/arm64/boot/dts/qcom/sm8150-hdk.dts -@@ -126,8 +126,6 @@ - vdda_sp_sensor: - vdda_ufs_2ln_core_1: - vdda_ufs_2ln_core_2: -- vdda_usb_ss_dp_core_1: -- vdda_usb_ss_dp_core_2: - vdda_qlink_lv: - vdda_qlink_lv_ck: - vreg_l5a_0p875: ldo5 { -@@ -209,6 +207,12 @@ - regulator-max-microvolt = <3008000>; - regulator-initial-mode = ; - }; -+ -+ vreg_l18a_0p8: ldo18 { -+ regulator-min-microvolt = <880000>; -+ regulator-max-microvolt = <880000>; -+ regulator-initial-mode = ; -+ }; - }; - - pm8150l-rpmh-regulators { -@@ -439,13 +443,13 @@ - &usb_1_qmpphy { - status = "okay"; - vdda-phy-supply = <&vreg_l3c_1p2>; -- vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; -+ vdda-pll-supply = <&vreg_l18a_0p8>; - }; - - &usb_2_qmpphy { - status = "okay"; - vdda-phy-supply = <&vreg_l3c_1p2>; -- vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; -+ vdda-pll-supply = <&vreg_l5a_0p875>; - }; - - &usb_1 { -diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi -index c586378fc6bc7..c3c12b0cd4168 100644 ---- a/arch/arm64/boot/dts/qcom/sm8150.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi -@@ -3940,7 +3940,7 @@ - compatible = "qcom,apss-wdt-sm8150", "qcom,kpss-wdt"; - reg = <0 0x17c10000 0 0x1000>; - clocks = <&sleep_clk>; -- interrupts = ; -+ interrupts = ; - }; - - timer@17c20000 { -diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi -index 4d9b30f0b2841..3d02adbc0b62f 100644 ---- a/arch/arm64/boot/dts/qcom/sm8250.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi -@@ -4879,7 +4879,7 @@ - compatible = "qcom,apss-wdt-sm8250", "qcom,kpss-wdt"; - reg = <0 0x17c10000 0 0x1000>; - clocks = <&sleep_clk>; -- interrupts = ; -+ interrupts = ; - }; - - timer@17c20000 { -diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi -index 793768a2c9e1e..888bf4cd73c31 100644 ---- a/arch/arm64/boot/dts/qcom/sm8350.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi -@@ -903,9 +903,9 @@ - }; - }; - -- gpi_dma0: dma-controller@9800000 { -+ gpi_dma0: dma-controller@900000 { - compatible = "qcom,sm8350-gpi-dma", "qcom,sm6350-gpi-dma"; -- reg = <0 0x09800000 0 0x60000>; -+ reg = <0 0x00900000 0 0x60000>; - interrupts = , - , - , -diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi -index 895f0bd9f7540..541b1e73b65e0 100644 ---- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi -+++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi -@@ -125,6 +125,9 @@ - }; - - &hscif0 { -+ pinctrl-0 = <&hscif0_pins>; -+ pinctrl-names = "default"; -+ - status = "okay"; - }; - -diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi -index bc4b50bcd1773..9301ea3888021 100644 ---- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi -@@ -245,7 +245,7 @@ - <193>, <194>, <195>; - interrupt-controller; - #interrupt-cells = <2>; -- ti,ngpio = <87>; -+ ti,ngpio = <92>; - ti,davinci-gpio-unbanked = <0>; - power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>; - clocks = <&k3_clks 77 0>; -@@ -263,7 +263,7 @@ - <183>, <184>, <185>; - interrupt-controller; - #interrupt-cells = <2>; -- ti,ngpio = <88>; -+ ti,ngpio = <52>; - ti,davinci-gpio-unbanked = <0>; - power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>; - clocks = <&k3_clks 78 0>; -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index ebb1c5ce7aece..83dd8993027ab 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -856,7 +856,7 @@ - assigned-clocks = <&k3_clks 67 2>; - assigned-clock-parents = <&k3_clks 67 5>; - -- interrupts = ; -+ interrupts = ; - - dma-coherent; - -diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c -index 00ad6587bee9a..3c344e4cd4cad 100644 ---- a/arch/arm64/kvm/vgic/vgic-its.c -+++ b/arch/arm64/kvm/vgic/vgic-its.c -@@ -584,7 +584,11 @@ static struct vgic_irq *vgic_its_check_cache(struct kvm *kvm, phys_addr_t db, - unsigned long flags; - - raw_spin_lock_irqsave(&dist->lpi_list_lock, flags); -+ - irq = __vgic_its_check_cache(dist, db, devid, eventid); -+ if (irq) -+ vgic_get_irq_kref(irq); -+ - raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags); - - return irq; -@@ -763,6 +767,7 @@ int vgic_its_inject_cached_translation(struct kvm *kvm, struct kvm_msi *msi) - raw_spin_lock_irqsave(&irq->irq_lock, flags); - irq->pending_latch = true; - vgic_queue_irq_unlock(kvm, irq, flags); -+ vgic_put_irq(kvm, irq); - - return 0; - } -diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c -index 871a45d4fc84c..ae5a3a717655e 100644 ---- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c -+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c -@@ -365,19 +365,26 @@ static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu, - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); - - raw_spin_lock_irqsave(&irq->irq_lock, flags); -- if (test_bit(i, &val)) { -- /* -- * pending_latch is set irrespective of irq type -- * (level or edge) to avoid dependency that VM should -- * restore irq config before pending info. -- */ -- irq->pending_latch = true; -- vgic_queue_irq_unlock(vcpu->kvm, irq, flags); -- } else { -+ -+ /* -+ * pending_latch is set irrespective of irq type -+ * (level or edge) to avoid dependency that VM should -+ * restore irq config before pending info. -+ */ -+ irq->pending_latch = test_bit(i, &val); -+ -+ if (irq->hw && vgic_irq_is_sgi(irq->intid)) { -+ irq_set_irqchip_state(irq->host_irq, -+ IRQCHIP_STATE_PENDING, -+ irq->pending_latch); - irq->pending_latch = false; -- raw_spin_unlock_irqrestore(&irq->irq_lock, flags); - } - -+ if (irq->pending_latch) -+ vgic_queue_irq_unlock(vcpu->kvm, irq, flags); -+ else -+ raw_spin_unlock_irqrestore(&irq->irq_lock, flags); -+ - vgic_put_irq(vcpu->kvm, irq); - } - -diff --git a/arch/csky/include/asm/jump_label.h b/arch/csky/include/asm/jump_label.h -index d488ba6084bc6..98a3f4b168bd2 100644 ---- a/arch/csky/include/asm/jump_label.h -+++ b/arch/csky/include/asm/jump_label.h -@@ -43,5 +43,10 @@ label: - return true; - } - -+enum jump_label_type; -+void arch_jump_label_transform_static(struct jump_entry *entry, -+ enum jump_label_type type); -+#define arch_jump_label_transform_static arch_jump_label_transform_static -+ - #endif /* __ASSEMBLY__ */ - #endif /* __ASM_CSKY_JUMP_LABEL_H */ -diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h -index 9b16a3b8e7060..f16bd42456e4c 100644 ---- a/arch/loongarch/include/asm/elf.h -+++ b/arch/loongarch/include/asm/elf.h -@@ -241,8 +241,6 @@ void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs); - do { \ - current->thread.vdso = &vdso_info; \ - \ -- loongarch_set_personality_fcsr(state); \ -- \ - if (personality(current->personality) != PER_LINUX) \ - set_personality(PER_LINUX); \ - } while (0) -@@ -259,7 +257,6 @@ do { \ - clear_thread_flag(TIF_32BIT_ADDR); \ - \ - current->thread.vdso = &vdso_info; \ -- loongarch_set_personality_fcsr(state); \ - \ - p = personality(current->personality); \ - if (p != PER_LINUX32 && p != PER_LINUX) \ -@@ -340,6 +337,4 @@ extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, - extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr, - struct arch_elf_state *state); - --extern void loongarch_set_personality_fcsr(struct arch_elf_state *state); -- - #endif /* _ASM_ELF_H */ -diff --git a/arch/loongarch/kernel/elf.c b/arch/loongarch/kernel/elf.c -index 183e94fc9c69c..0fa81ced28dcd 100644 ---- a/arch/loongarch/kernel/elf.c -+++ b/arch/loongarch/kernel/elf.c -@@ -23,8 +23,3 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr, - { - return 0; - } -- --void loongarch_set_personality_fcsr(struct arch_elf_state *state) --{ -- current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0; --} -diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c -index 90a5de7463326..1259bc3129790 100644 ---- a/arch/loongarch/kernel/process.c -+++ b/arch/loongarch/kernel/process.c -@@ -82,6 +82,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) - euen = regs->csr_euen & ~(CSR_EUEN_FPEN); - regs->csr_euen = euen; - lose_fpu(0); -+ current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0; - - clear_thread_flag(TIF_LSX_CTX_LIVE); - clear_thread_flag(TIF_LASX_CTX_LIVE); -diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c -index 40ed49d9adff5..4e86441e63196 100644 ---- a/arch/loongarch/net/bpf_jit.c -+++ b/arch/loongarch/net/bpf_jit.c -@@ -402,7 +402,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext - const u8 dst = regmap[insn->dst_reg]; - const s16 off = insn->off; - const s32 imm = insn->imm; -- const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm; - const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || BPF_CLASS(insn->code) == BPF_JMP32; - - switch (code) { -@@ -806,8 +805,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext - - /* dst = imm64 */ - case BPF_LD | BPF_IMM | BPF_DW: -+ { -+ const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm; -+ - move_imm(ctx, dst, imm64, is32); - return 1; -+ } - - /* dst = *(size *)(src + off) */ - case BPF_LDX | BPF_MEM | BPF_B: -diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c -index f521874ebb07b..67f067706af27 100644 ---- a/arch/mips/alchemy/devboards/db1200.c -+++ b/arch/mips/alchemy/devboards/db1200.c -@@ -847,7 +847,7 @@ int __init db1200_dev_setup(void) - i2c_register_board_info(0, db1200_i2c_devs, - ARRAY_SIZE(db1200_i2c_devs)); - spi_register_board_info(db1200_spi_devs, -- ARRAY_SIZE(db1200_i2c_devs)); -+ ARRAY_SIZE(db1200_spi_devs)); - - /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI) - * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S) -diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c -index fd91d9c9a2525..6c6837181f555 100644 ---- a/arch/mips/alchemy/devboards/db1550.c -+++ b/arch/mips/alchemy/devboards/db1550.c -@@ -589,7 +589,7 @@ int __init db1550_dev_setup(void) - i2c_register_board_info(0, db1550_i2c_devs, - ARRAY_SIZE(db1550_i2c_devs)); - spi_register_board_info(db1550_spi_devs, -- ARRAY_SIZE(db1550_i2c_devs)); -+ ARRAY_SIZE(db1550_spi_devs)); - - c = clk_get(NULL, "psc0_intclk"); - if (!IS_ERR(c)) { -diff --git a/arch/mips/include/asm/dmi.h b/arch/mips/include/asm/dmi.h -index 27415a288adf5..dc397f630c660 100644 ---- a/arch/mips/include/asm/dmi.h -+++ b/arch/mips/include/asm/dmi.h -@@ -5,7 +5,7 @@ - #include - #include - --#define dmi_early_remap(x, l) ioremap_cache(x, l) -+#define dmi_early_remap(x, l) ioremap(x, l) - #define dmi_early_unmap(x, l) iounmap(x) - #define dmi_remap(x, l) ioremap_cache(x, l) - #define dmi_unmap(x) iounmap(x) -diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c -index 7c540572f1f72..e46e7ec76b4f4 100644 ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -326,11 +326,11 @@ static void __init bootmem_init(void) - panic("Incorrect memory mapping !!!"); - - if (max_pfn > PFN_DOWN(HIGHMEM_START)) { -+ max_low_pfn = PFN_DOWN(HIGHMEM_START); - #ifdef CONFIG_HIGHMEM -- highstart_pfn = PFN_DOWN(HIGHMEM_START); -+ highstart_pfn = max_low_pfn; - highend_pfn = max_pfn; - #else -- max_low_pfn = PFN_DOWN(HIGHMEM_START); - max_pfn = max_low_pfn; - #endif - } -diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c -index 1d93b85271ba8..002c91fcb842e 100644 ---- a/arch/mips/kernel/smp.c -+++ b/arch/mips/kernel/smp.c -@@ -333,10 +333,11 @@ early_initcall(mips_smp_ipi_init); - */ - asmlinkage void start_secondary(void) - { -- unsigned int cpu; -+ unsigned int cpu = raw_smp_processor_id(); - - cpu_probe(); - per_cpu_trap_init(false); -+ rcu_cpu_starting(cpu); - mips_clockevent_init(); - mp_ops->init_secondary(); - cpu_report(); -@@ -348,7 +349,6 @@ asmlinkage void start_secondary(void) - */ - - calibrate_delay(); -- cpu = smp_processor_id(); - cpu_data[cpu].udelay_val = loops_per_jiffy; - - set_cpu_sibling_map(cpu); -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index 6050e6e10d321..2c94f9cf1ce00 100644 ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -806,6 +806,7 @@ config THREAD_SHIFT - int "Thread shift" if EXPERT - range 13 15 - default "15" if PPC_256K_PAGES -+ default "15" if PPC_PSERIES || PPC_POWERNV - default "14" if PPC64 - default "13" - help -diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile -index 054844153b1fd..487e4967b60d2 100644 ---- a/arch/powerpc/Makefile -+++ b/arch/powerpc/Makefile -@@ -42,18 +42,13 @@ machine-$(CONFIG_PPC64) += 64 - machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le - UTS_MACHINE := $(subst $(space),,$(machine-y)) - --# XXX This needs to be before we override LD below --ifdef CONFIG_PPC32 --KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o --else --ifeq ($(call ld-ifversion, -ge, 22500, y),y) -+ifeq ($(CONFIG_PPC64)$(CONFIG_LD_IS_BFD),yy) - # Have the linker provide sfpr if possible. - # There is a corresponding test in arch/powerpc/lib/Makefile - KBUILD_LDFLAGS_MODULE += --save-restore-funcs - else - KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o - endif --endif - - ifdef CONFIG_CPU_LITTLE_ENDIAN - KBUILD_CFLAGS += -mlittle-endian -@@ -391,17 +386,7 @@ endif - endif - - PHONY += checkbin --# Check toolchain versions: --# - gcc-4.6 is the minimum kernel-wide version so nothing required. - checkbin: -- @if test "x${CONFIG_LD_IS_LLD}" != "xy" -a \ -- "x$(call ld-ifversion, -le, 22400, y)" = "xy" ; then \ -- echo -n '*** binutils 2.24 miscompiles weak symbols ' ; \ -- echo 'in some circumstances.' ; \ -- echo '*** binutils 2.23 do not define the TOC symbol ' ; \ -- echo -n '*** Please use a different binutils version.' ; \ -- false ; \ -- fi - @if test "x${CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT}" = "xy" -a \ - "x${CONFIG_LD_IS_BFD}" = "xy" -a \ - "${CONFIG_LD_VERSION}" = "23700" ; then \ -diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile -index 8560c912186df..9b394bab17eba 100644 ---- a/arch/powerpc/lib/Makefile -+++ b/arch/powerpc/lib/Makefile -@@ -42,8 +42,8 @@ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o - # 64-bit linker creates .sfpr on demand for final link (vmlinux), - # so it is only needed for modules, and only for older linkers which - # do not support --save-restore-funcs --ifeq ($(call ld-ifversion, -lt, 22500, y),y) --extra-$(CONFIG_PPC64) += crtsavres.o -+ifndef CONFIG_LD_IS_BFD -+always-$(CONFIG_PPC64) += crtsavres.o - endif - - obj-$(CONFIG_PPC_BOOK3S_64) += copyuser_power7.o copypage_power7.o \ -diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c -index ada817c49b722..56d82f7f9734e 100644 ---- a/arch/powerpc/perf/imc-pmu.c -+++ b/arch/powerpc/perf/imc-pmu.c -@@ -299,6 +299,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) - attr_group->attrs = attrs; - do { - ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i].value); -+ if (!ev_val_str) -+ continue; - dev_str = device_str_attr_create(pmu->events[i].name, ev_val_str); - if (!dev_str) - continue; -@@ -306,6 +308,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) - attrs[j++] = dev_str; - if (pmu->events[i].scale) { - ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale", pmu->events[i].name); -+ if (!ev_scale_str) -+ continue; - dev_str = device_str_attr_create(ev_scale_str, pmu->events[i].scale); - if (!dev_str) - continue; -@@ -315,6 +319,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) - - if (pmu->events[i].unit) { - ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit", pmu->events[i].name); -+ if (!ev_unit_str) -+ continue; - dev_str = device_str_attr_create(ev_unit_str, pmu->events[i].unit); - if (!dev_str) - continue; -diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig -index 25b80cd558f8d..fc79f84669335 100644 ---- a/arch/powerpc/platforms/44x/Kconfig -+++ b/arch/powerpc/platforms/44x/Kconfig -@@ -173,6 +173,7 @@ config ISS4xx - config CURRITUCK - bool "IBM Currituck (476fpe) Support" - depends on PPC_47x -+ select I2C - select SWIOTLB - select 476FPE - select FORCE_PCI -diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c -index d55652b5f6fa4..391f505352007 100644 ---- a/arch/powerpc/platforms/powernv/opal-irqchip.c -+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c -@@ -275,6 +275,8 @@ int __init opal_event_init(void) - else - name = kasprintf(GFP_KERNEL, "opal"); - -+ if (!name) -+ continue; - /* Install interrupt handler */ - rc = request_irq(r->start, opal_interrupt, r->flags & IRQD_TRIGGER_MASK, - name, NULL); -diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c -index 7bfe4cbeb35a9..ea917266aa172 100644 ---- a/arch/powerpc/platforms/powernv/opal-powercap.c -+++ b/arch/powerpc/platforms/powernv/opal-powercap.c -@@ -196,6 +196,12 @@ void __init opal_powercap_init(void) - - j = 0; - pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node); -+ if (!pcaps[i].pg.name) { -+ kfree(pcaps[i].pattrs); -+ kfree(pcaps[i].pg.attrs); -+ goto out_pcaps_pattrs; -+ } -+ - if (has_min) { - powercap_add_attr(min, "powercap-min", - &pcaps[i].pattrs[j]); -diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c -index 6b4eed2ef4fa9..f67235d1ba2c5 100644 ---- a/arch/powerpc/platforms/powernv/opal-xscom.c -+++ b/arch/powerpc/platforms/powernv/opal-xscom.c -@@ -165,6 +165,11 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn, - ent->chip = chip; - snprintf(ent->name, 16, "%08x", chip); - ent->path.data = (void *)kasprintf(GFP_KERNEL, "%pOF", dn); -+ if (!ent->path.data) { -+ kfree(ent); -+ return -ENOMEM; -+ } -+ - ent->path.size = strlen((char *)ent->path.data); - - dir = debugfs_create_dir(ent->name, root); -diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c -index 2e3a317722a81..051a777ba1b27 100644 ---- a/arch/powerpc/platforms/pseries/hotplug-memory.c -+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c -@@ -500,14 +500,15 @@ static int dlpar_memory_remove_by_index(u32 drc_index) - } - } - -- if (!lmb_found) -+ if (!lmb_found) { -+ pr_debug("Failed to look up LMB for drc index %x\n", drc_index); - rc = -EINVAL; -- -- if (rc) -+ } else if (rc) { - pr_debug("Failed to hot-remove memory at %llx\n", - lmb->base_addr); -- else -+ } else { - pr_debug("Memory at %llx was hot-removed\n", lmb->base_addr); -+ } - - return rc; - } -diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h -index 32336e8a17cb0..a393d5035c543 100644 ---- a/arch/riscv/include/asm/sections.h -+++ b/arch/riscv/include/asm/sections.h -@@ -13,6 +13,7 @@ extern char _start_kernel[]; - extern char __init_data_begin[], __init_data_end[]; - extern char __init_text_begin[], __init_text_end[]; - extern char __alt_start[], __alt_end[]; -+extern char __exittext_begin[], __exittext_end[]; - - static inline bool is_va_kernel_text(uintptr_t va) - { -diff --git a/arch/riscv/include/asm/xip_fixup.h b/arch/riscv/include/asm/xip_fixup.h -index d4ffc3c37649f..b65bf6306f69c 100644 ---- a/arch/riscv/include/asm/xip_fixup.h -+++ b/arch/riscv/include/asm/xip_fixup.h -@@ -13,7 +13,7 @@ - add \reg, \reg, t0 - .endm - .macro XIP_FIXUP_FLASH_OFFSET reg -- la t1, __data_loc -+ la t0, __data_loc - REG_L t1, _xip_phys_offset - sub \reg, \reg, t1 - add \reg, \reg, t0 -diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c -index 91fe16bfaa07c..a331001e33e66 100644 ---- a/arch/riscv/kernel/module.c -+++ b/arch/riscv/kernel/module.c -@@ -424,7 +424,8 @@ void *module_alloc(unsigned long size) - { - return __vmalloc_node_range(size, 1, MODULES_VADDR, - MODULES_END, GFP_KERNEL, -- PAGE_KERNEL, 0, NUMA_NO_NODE, -+ PAGE_KERNEL, VM_FLUSH_RESET_PERMS, -+ NUMA_NO_NODE, - __builtin_return_address(0)); - } - #endif -diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c -index e099961453cca..160e5c1caa9c4 100644 ---- a/arch/riscv/kernel/patch.c -+++ b/arch/riscv/kernel/patch.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - struct patch_insn { - void *addr; -@@ -23,6 +24,14 @@ struct patch_insn { - int riscv_patch_in_stop_machine = false; - - #ifdef CONFIG_MMU -+ -+static inline bool is_kernel_exittext(uintptr_t addr) -+{ -+ return system_state < SYSTEM_RUNNING && -+ addr >= (uintptr_t)__exittext_begin && -+ addr < (uintptr_t)__exittext_end; -+} -+ - /* - * The fix_to_virt(, idx) needs a const value (not a dynamic variable of - * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses". -@@ -33,7 +42,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap) - uintptr_t uintaddr = (uintptr_t) addr; - struct page *page; - -- if (core_kernel_text(uintaddr)) -+ if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) - page = phys_to_page(__pa_symbol(addr)); - else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) - page = vmalloc_to_page(addr); -diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S b/arch/riscv/kernel/vmlinux-xip.lds.S -index 75e0fa8a700ae..24a2fdd3be6a0 100644 ---- a/arch/riscv/kernel/vmlinux-xip.lds.S -+++ b/arch/riscv/kernel/vmlinux-xip.lds.S -@@ -29,10 +29,12 @@ SECTIONS - HEAD_TEXT_SECTION - INIT_TEXT_SECTION(PAGE_SIZE) - /* we have to discard exit text and such at runtime, not link time */ -+ __exittext_begin = .; - .exit.text : - { - EXIT_TEXT - } -+ __exittext_end = .; - - .text : { - _text = .; -diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S -index 4e6c88aa4d870..d478e063b8785 100644 ---- a/arch/riscv/kernel/vmlinux.lds.S -+++ b/arch/riscv/kernel/vmlinux.lds.S -@@ -72,10 +72,12 @@ SECTIONS - __soc_builtin_dtb_table_end = .; - } - /* we have to discard exit text and such at runtime, not link time */ -+ __exittext_begin = .; - .exit.text : - { - EXIT_TEXT - } -+ __exittext_end = .; - - __init_text_end = .; - . = ALIGN(SECTION_ALIGN); -diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c -index ea3d61de065b3..9587e44874152 100644 ---- a/arch/riscv/mm/pageattr.c -+++ b/arch/riscv/mm/pageattr.c -@@ -5,6 +5,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -25,19 +26,6 @@ static unsigned long set_pageattr_masks(unsigned long val, struct mm_walk *walk) - return new_val; - } - --static int pageattr_pgd_entry(pgd_t *pgd, unsigned long addr, -- unsigned long next, struct mm_walk *walk) --{ -- pgd_t val = READ_ONCE(*pgd); -- -- if (pgd_leaf(val)) { -- val = __pgd(set_pageattr_masks(pgd_val(val), walk)); -- set_pgd(pgd, val); -- } -- -- return 0; --} -- - static int pageattr_p4d_entry(p4d_t *p4d, unsigned long addr, - unsigned long next, struct mm_walk *walk) - { -@@ -96,7 +84,6 @@ static int pageattr_pte_hole(unsigned long addr, unsigned long next, - } - - static const struct mm_walk_ops pageattr_ops = { -- .pgd_entry = pageattr_pgd_entry, - .p4d_entry = pageattr_p4d_entry, - .pud_entry = pageattr_pud_entry, - .pmd_entry = pageattr_pmd_entry, -@@ -104,12 +91,181 @@ static const struct mm_walk_ops pageattr_ops = { - .pte_hole = pageattr_pte_hole, - }; - -+#ifdef CONFIG_64BIT -+static int __split_linear_mapping_pmd(pud_t *pudp, -+ unsigned long vaddr, unsigned long end) -+{ -+ pmd_t *pmdp; -+ unsigned long next; -+ -+ pmdp = pmd_offset(pudp, vaddr); -+ -+ do { -+ next = pmd_addr_end(vaddr, end); -+ -+ if (next - vaddr >= PMD_SIZE && -+ vaddr <= (vaddr & PMD_MASK) && end >= next) -+ continue; -+ -+ if (pmd_leaf(*pmdp)) { -+ struct page *pte_page; -+ unsigned long pfn = _pmd_pfn(*pmdp); -+ pgprot_t prot = __pgprot(pmd_val(*pmdp) & ~_PAGE_PFN_MASK); -+ pte_t *ptep_new; -+ int i; -+ -+ pte_page = alloc_page(GFP_KERNEL); -+ if (!pte_page) -+ return -ENOMEM; -+ -+ ptep_new = (pte_t *)page_address(pte_page); -+ for (i = 0; i < PTRS_PER_PTE; ++i, ++ptep_new) -+ set_pte(ptep_new, pfn_pte(pfn + i, prot)); -+ -+ smp_wmb(); -+ -+ set_pmd(pmdp, pfn_pmd(page_to_pfn(pte_page), PAGE_TABLE)); -+ } -+ } while (pmdp++, vaddr = next, vaddr != end); -+ -+ return 0; -+} -+ -+static int __split_linear_mapping_pud(p4d_t *p4dp, -+ unsigned long vaddr, unsigned long end) -+{ -+ pud_t *pudp; -+ unsigned long next; -+ int ret; -+ -+ pudp = pud_offset(p4dp, vaddr); -+ -+ do { -+ next = pud_addr_end(vaddr, end); -+ -+ if (next - vaddr >= PUD_SIZE && -+ vaddr <= (vaddr & PUD_MASK) && end >= next) -+ continue; -+ -+ if (pud_leaf(*pudp)) { -+ struct page *pmd_page; -+ unsigned long pfn = _pud_pfn(*pudp); -+ pgprot_t prot = __pgprot(pud_val(*pudp) & ~_PAGE_PFN_MASK); -+ pmd_t *pmdp_new; -+ int i; -+ -+ pmd_page = alloc_page(GFP_KERNEL); -+ if (!pmd_page) -+ return -ENOMEM; -+ -+ pmdp_new = (pmd_t *)page_address(pmd_page); -+ for (i = 0; i < PTRS_PER_PMD; ++i, ++pmdp_new) -+ set_pmd(pmdp_new, -+ pfn_pmd(pfn + ((i * PMD_SIZE) >> PAGE_SHIFT), prot)); -+ -+ smp_wmb(); -+ -+ set_pud(pudp, pfn_pud(page_to_pfn(pmd_page), PAGE_TABLE)); -+ } -+ -+ ret = __split_linear_mapping_pmd(pudp, vaddr, next); -+ if (ret) -+ return ret; -+ } while (pudp++, vaddr = next, vaddr != end); -+ -+ return 0; -+} -+ -+static int __split_linear_mapping_p4d(pgd_t *pgdp, -+ unsigned long vaddr, unsigned long end) -+{ -+ p4d_t *p4dp; -+ unsigned long next; -+ int ret; -+ -+ p4dp = p4d_offset(pgdp, vaddr); -+ -+ do { -+ next = p4d_addr_end(vaddr, end); -+ -+ /* -+ * If [vaddr; end] contains [vaddr & P4D_MASK; next], we don't -+ * need to split, we'll change the protections on the whole P4D. -+ */ -+ if (next - vaddr >= P4D_SIZE && -+ vaddr <= (vaddr & P4D_MASK) && end >= next) -+ continue; -+ -+ if (p4d_leaf(*p4dp)) { -+ struct page *pud_page; -+ unsigned long pfn = _p4d_pfn(*p4dp); -+ pgprot_t prot = __pgprot(p4d_val(*p4dp) & ~_PAGE_PFN_MASK); -+ pud_t *pudp_new; -+ int i; -+ -+ pud_page = alloc_page(GFP_KERNEL); -+ if (!pud_page) -+ return -ENOMEM; -+ -+ /* -+ * Fill the pud level with leaf puds that have the same -+ * protections as the leaf p4d. -+ */ -+ pudp_new = (pud_t *)page_address(pud_page); -+ for (i = 0; i < PTRS_PER_PUD; ++i, ++pudp_new) -+ set_pud(pudp_new, -+ pfn_pud(pfn + ((i * PUD_SIZE) >> PAGE_SHIFT), prot)); -+ -+ /* -+ * Make sure the pud filling is not reordered with the -+ * p4d store which could result in seeing a partially -+ * filled pud level. -+ */ -+ smp_wmb(); -+ -+ set_p4d(p4dp, pfn_p4d(page_to_pfn(pud_page), PAGE_TABLE)); -+ } -+ -+ ret = __split_linear_mapping_pud(p4dp, vaddr, next); -+ if (ret) -+ return ret; -+ } while (p4dp++, vaddr = next, vaddr != end); -+ -+ return 0; -+} -+ -+static int __split_linear_mapping_pgd(pgd_t *pgdp, -+ unsigned long vaddr, -+ unsigned long end) -+{ -+ unsigned long next; -+ int ret; -+ -+ do { -+ next = pgd_addr_end(vaddr, end); -+ /* We never use PGD mappings for the linear mapping */ -+ ret = __split_linear_mapping_p4d(pgdp, vaddr, next); -+ if (ret) -+ return ret; -+ } while (pgdp++, vaddr = next, vaddr != end); -+ -+ return 0; -+} -+ -+static int split_linear_mapping(unsigned long start, unsigned long end) -+{ -+ return __split_linear_mapping_pgd(pgd_offset_k(start), start, end); -+} -+#endif /* CONFIG_64BIT */ -+ - static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, - pgprot_t clear_mask) - { - int ret; - unsigned long start = addr; - unsigned long end = start + PAGE_SIZE * numpages; -+ unsigned long __maybe_unused lm_start; -+ unsigned long __maybe_unused lm_end; - struct pageattr_masks masks = { - .set_mask = set_mask, - .clear_mask = clear_mask -@@ -119,11 +275,72 @@ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, - return 0; - - mmap_write_lock(&init_mm); -+ -+#ifdef CONFIG_64BIT -+ /* -+ * We are about to change the permissions of a kernel mapping, we must -+ * apply the same changes to its linear mapping alias, which may imply -+ * splitting a huge mapping. -+ */ -+ -+ if (is_vmalloc_or_module_addr((void *)start)) { -+ struct vm_struct *area = NULL; -+ int i, page_start; -+ -+ area = find_vm_area((void *)start); -+ page_start = (start - (unsigned long)area->addr) >> PAGE_SHIFT; -+ -+ for (i = page_start; i < page_start + numpages; ++i) { -+ lm_start = (unsigned long)page_address(area->pages[i]); -+ lm_end = lm_start + PAGE_SIZE; -+ -+ ret = split_linear_mapping(lm_start, lm_end); -+ if (ret) -+ goto unlock; -+ -+ ret = walk_page_range_novma(&init_mm, lm_start, lm_end, -+ &pageattr_ops, NULL, &masks); -+ if (ret) -+ goto unlock; -+ } -+ } else if (is_kernel_mapping(start) || is_linear_mapping(start)) { -+ if (is_kernel_mapping(start)) { -+ lm_start = (unsigned long)lm_alias(start); -+ lm_end = (unsigned long)lm_alias(end); -+ } else { -+ lm_start = start; -+ lm_end = end; -+ } -+ -+ ret = split_linear_mapping(lm_start, lm_end); -+ if (ret) -+ goto unlock; -+ -+ ret = walk_page_range_novma(&init_mm, lm_start, lm_end, -+ &pageattr_ops, NULL, &masks); -+ if (ret) -+ goto unlock; -+ } -+ - ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, - &masks); -+ -+unlock: -+ mmap_write_unlock(&init_mm); -+ -+ /* -+ * We can't use flush_tlb_kernel_range() here as we may have split a -+ * hugepage that is larger than that, so let's flush everything. -+ */ -+ flush_tlb_all(); -+#else -+ ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, -+ &masks); -+ - mmap_write_unlock(&init_mm); - - flush_tlb_kernel_range(start, end); -+#endif - - return ret; - } -@@ -158,36 +375,14 @@ int set_memory_nx(unsigned long addr, int numpages) - - int set_direct_map_invalid_noflush(struct page *page) - { -- int ret; -- unsigned long start = (unsigned long)page_address(page); -- unsigned long end = start + PAGE_SIZE; -- struct pageattr_masks masks = { -- .set_mask = __pgprot(0), -- .clear_mask = __pgprot(_PAGE_PRESENT) -- }; -- -- mmap_read_lock(&init_mm); -- ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); -- mmap_read_unlock(&init_mm); -- -- return ret; -+ return __set_memory((unsigned long)page_address(page), 1, -+ __pgprot(0), __pgprot(_PAGE_PRESENT)); - } - - int set_direct_map_default_noflush(struct page *page) - { -- int ret; -- unsigned long start = (unsigned long)page_address(page); -- unsigned long end = start + PAGE_SIZE; -- struct pageattr_masks masks = { -- .set_mask = PAGE_KERNEL, -- .clear_mask = __pgprot(0) -- }; -- -- mmap_read_lock(&init_mm); -- ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); -- mmap_read_unlock(&init_mm); -- -- return ret; -+ return __set_memory((unsigned long)page_address(page), 1, -+ PAGE_KERNEL, __pgprot(_PAGE_EXEC)); - } - - #ifdef CONFIG_DEBUG_PAGEALLOC -diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h -index 287bb88f76986..2686bee800e3d 100644 ---- a/arch/s390/include/asm/pci_io.h -+++ b/arch/s390/include/asm/pci_io.h -@@ -11,6 +11,8 @@ - /* I/O size constraints */ - #define ZPCI_MAX_READ_SIZE 8 - #define ZPCI_MAX_WRITE_SIZE 128 -+#define ZPCI_BOUNDARY_SIZE (1 << 12) -+#define ZPCI_BOUNDARY_MASK (ZPCI_BOUNDARY_SIZE - 1) - - /* I/O Map */ - #define ZPCI_IOMAP_SHIFT 48 -@@ -125,16 +127,18 @@ out: - int zpci_write_block(volatile void __iomem *dst, const void *src, - unsigned long len); - --static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) -+static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max) - { -- int count = len > max ? max : len, size = 1; -+ int offset = dst & ZPCI_BOUNDARY_MASK; -+ int size; - -- while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) { -- dst = dst >> 1; -- src = src >> 1; -- size = size << 1; -- } -- return size; -+ size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max); -+ if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8)) -+ return size; -+ -+ if (size >= 8) -+ return 8; -+ return rounddown_pow_of_two(size); - } - - static inline int zpci_memcpy_fromio(void *dst, -@@ -144,9 +148,9 @@ static inline int zpci_memcpy_fromio(void *dst, - int size, rc = 0; - - while (n > 0) { -- size = zpci_get_max_write_size((u64 __force) src, -- (u64) dst, n, -- ZPCI_MAX_READ_SIZE); -+ size = zpci_get_max_io_size((u64 __force) src, -+ (u64) dst, n, -+ ZPCI_MAX_READ_SIZE); - rc = zpci_read_single(dst, src, size); - if (rc) - break; -@@ -166,9 +170,9 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst, - return -EINVAL; - - while (n > 0) { -- size = zpci_get_max_write_size((u64 __force) dst, -- (u64) src, n, -- ZPCI_MAX_WRITE_SIZE); -+ size = zpci_get_max_io_size((u64 __force) dst, -+ (u64) src, n, -+ ZPCI_MAX_WRITE_SIZE); - if (size > 8) /* main path */ - rc = zpci_write_block(dst, src, size); - else -diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c -index 5880893329310..a90499c087f0c 100644 ---- a/arch/s390/pci/pci_mmio.c -+++ b/arch/s390/pci/pci_mmio.c -@@ -97,9 +97,9 @@ static inline int __memcpy_toio_inuser(void __iomem *dst, - return -EINVAL; - - while (n > 0) { -- size = zpci_get_max_write_size((u64 __force) dst, -- (u64 __force) src, n, -- ZPCI_MAX_WRITE_SIZE); -+ size = zpci_get_max_io_size((u64 __force) dst, -+ (u64 __force) src, n, -+ ZPCI_MAX_WRITE_SIZE); - if (size > 8) /* main path */ - rc = __pcistb_mio_inuser(dst, src, size, &status); - else -@@ -242,9 +242,9 @@ static inline int __memcpy_fromio_inuser(void __user *dst, - u8 status; - - while (n > 0) { -- size = zpci_get_max_write_size((u64 __force) src, -- (u64 __force) dst, n, -- ZPCI_MAX_READ_SIZE); -+ size = zpci_get_max_io_size((u64 __force) src, -+ (u64 __force) dst, n, -+ ZPCI_MAX_READ_SIZE); - rc = __pcilg_mio_inuser(dst, src, size, &status); - if (rc) - break; -diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c -index 12cf2e7ca33cc..87c15ab896517 100644 ---- a/arch/x86/kernel/cpu/mce/inject.c -+++ b/arch/x86/kernel/cpu/mce/inject.c -@@ -747,6 +747,7 @@ static void check_hw_inj_possible(void) - - wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), status); - rdmsrl_safe(mca_msr_reg(bank, MCA_STATUS), &status); -+ wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), 0); - - if (!status) { - hw_injection_possible = false; -diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c -index 16333ba1904ba..c067887d42df5 100644 ---- a/arch/x86/kernel/kvmclock.c -+++ b/arch/x86/kernel/kvmclock.c -@@ -24,8 +24,8 @@ - - static int kvmclock __initdata = 1; - static int kvmclock_vsyscall __initdata = 1; --static int msr_kvm_system_time __ro_after_init = MSR_KVM_SYSTEM_TIME; --static int msr_kvm_wall_clock __ro_after_init = MSR_KVM_WALL_CLOCK; -+static int msr_kvm_system_time __ro_after_init; -+static int msr_kvm_wall_clock __ro_after_init; - static u64 kvm_sched_clock_offset __ro_after_init; - - static int __init parse_no_kvmclock(char *arg) -@@ -195,7 +195,8 @@ static void kvm_setup_secondary_clock(void) - - void kvmclock_disable(void) - { -- native_write_msr(msr_kvm_system_time, 0, 0); -+ if (msr_kvm_system_time) -+ native_write_msr(msr_kvm_system_time, 0, 0); - } - - static void __init kvmclock_init_mem(void) -@@ -294,7 +295,10 @@ void __init kvmclock_init(void) - if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) { - msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW; - msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW; -- } else if (!kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { -+ } else if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { -+ msr_kvm_system_time = MSR_KVM_SYSTEM_TIME; -+ msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK; -+ } else { - return; - } - -diff --git a/arch/x86/lib/misc.c b/arch/x86/lib/misc.c -index a018ec4fba53e..c97be9a1430a0 100644 ---- a/arch/x86/lib/misc.c -+++ b/arch/x86/lib/misc.c -@@ -6,7 +6,7 @@ - */ - int num_digits(int val) - { -- int m = 10; -+ long long m = 10; - int d = 1; - - if (val < 0) { -diff --git a/block/bio.c b/block/bio.c -index 9ec72a78f1149..6c22dd7b6f278 100644 ---- a/block/bio.c -+++ b/block/bio.c -@@ -1109,13 +1109,22 @@ bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len, - - void __bio_release_pages(struct bio *bio, bool mark_dirty) - { -- struct bvec_iter_all iter_all; -- struct bio_vec *bvec; -+ struct folio_iter fi; - -- bio_for_each_segment_all(bvec, bio, iter_all) { -- if (mark_dirty && !PageCompound(bvec->bv_page)) -- set_page_dirty_lock(bvec->bv_page); -- put_page(bvec->bv_page); -+ bio_for_each_folio_all(fi, bio) { -+ struct page *page; -+ size_t done = 0; -+ -+ if (mark_dirty) { -+ folio_lock(fi.folio); -+ folio_mark_dirty(fi.folio); -+ folio_unlock(fi.folio); -+ } -+ page = folio_page(fi.folio, fi.offset / PAGE_SIZE); -+ do { -+ folio_put(fi.folio); -+ done += PAGE_SIZE; -+ } while (done < fi.length); - } - } - EXPORT_SYMBOL_GPL(__bio_release_pages); -@@ -1414,12 +1423,12 @@ EXPORT_SYMBOL(bio_free_pages); - */ - void bio_set_pages_dirty(struct bio *bio) - { -- struct bio_vec *bvec; -- struct bvec_iter_all iter_all; -+ struct folio_iter fi; - -- bio_for_each_segment_all(bvec, bio, iter_all) { -- if (!PageCompound(bvec->bv_page)) -- set_page_dirty_lock(bvec->bv_page); -+ bio_for_each_folio_all(fi, bio) { -+ folio_lock(fi.folio); -+ folio_mark_dirty(fi.folio); -+ folio_unlock(fi.folio); - } - } - -@@ -1462,12 +1471,11 @@ static void bio_dirty_fn(struct work_struct *work) - - void bio_check_pages_dirty(struct bio *bio) - { -- struct bio_vec *bvec; -+ struct folio_iter fi; - unsigned long flags; -- struct bvec_iter_all iter_all; - -- bio_for_each_segment_all(bvec, bio, iter_all) { -- if (!PageDirty(bvec->bv_page) && !PageCompound(bvec->bv_page)) -+ bio_for_each_folio_all(fi, bio) { -+ if (!folio_test_dirty(fi.folio)) - goto defer; - } - -diff --git a/block/blk-mq.c b/block/blk-mq.c -index 368f1947c8956..b3f99dda45300 100644 ---- a/block/blk-mq.c -+++ b/block/blk-mq.c -@@ -2946,12 +2946,6 @@ void blk_mq_submit_bio(struct bio *bio) - blk_status_t ret; - - bio = blk_queue_bounce(bio, q); -- if (bio_may_exceed_limits(bio, &q->limits)) { -- bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); -- if (!bio) -- return; -- } -- - bio_set_ioprio(bio); - - if (plug) { -@@ -2960,6 +2954,11 @@ void blk_mq_submit_bio(struct bio *bio) - rq = NULL; - } - if (rq) { -+ if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { -+ bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); -+ if (!bio) -+ return; -+ } - if (!bio_integrity_prep(bio)) - return; - if (blk_mq_attempt_bio_merge(q, bio, nr_segs)) -@@ -2970,6 +2969,11 @@ void blk_mq_submit_bio(struct bio *bio) - } else { - if (unlikely(bio_queue_enter(bio))) - return; -+ if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { -+ bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); -+ if (!bio) -+ goto fail; -+ } - if (!bio_integrity_prep(bio)) - goto fail; - } -diff --git a/block/blk-settings.c b/block/blk-settings.c -index 86ff375c00ce4..bbca4ce77a2d3 100644 ---- a/block/blk-settings.c -+++ b/block/blk-settings.c -@@ -135,7 +135,7 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto - limits->max_hw_sectors = max_hw_sectors; - - max_sectors = min_not_zero(max_hw_sectors, limits->max_dev_sectors); -- max_sectors = min_t(unsigned int, max_sectors, BLK_DEF_MAX_SECTORS); -+ max_sectors = min(max_sectors, BLK_DEF_MAX_SECTORS); - max_sectors = round_down(max_sectors, - limits->logical_block_size >> SECTOR_SHIFT); - limits->max_sectors = max_sectors; -diff --git a/block/genhd.c b/block/genhd.c -index afab646d12c85..ddb17c4adc8a2 100644 ---- a/block/genhd.c -+++ b/block/genhd.c -@@ -444,7 +444,9 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, - DISK_MAX_PARTS); - disk->minors = DISK_MAX_PARTS; - } -- if (disk->first_minor + disk->minors > MINORMASK + 1) -+ if (disk->first_minor > MINORMASK || -+ disk->minors > MINORMASK + 1 || -+ disk->first_minor + disk->minors > MINORMASK + 1) - goto out_exit_elevator; - } else { - if (WARN_ON(disk->minors)) -@@ -567,6 +569,7 @@ out_del_integrity: - out_del_block_link: - if (!sysfs_deprecated) - sysfs_remove_link(block_depr, dev_name(ddev)); -+ pm_runtime_set_memalloc_noio(ddev, false); - out_device_del: - device_del(ddev); - out_free_ext_minor: -diff --git a/block/ioctl.c b/block/ioctl.c -index 3c475e4166e9f..ebe4a2653622b 100644 ---- a/block/ioctl.c -+++ b/block/ioctl.c -@@ -18,7 +18,7 @@ static int blkpg_do_ioctl(struct block_device *bdev, - { - struct gendisk *disk = bdev->bd_disk; - struct blkpg_partition p; -- long long start, length; -+ sector_t start, length; - - if (disk->flags & GENHD_FL_NO_PART) - return -EINVAL; -@@ -35,14 +35,17 @@ static int blkpg_do_ioctl(struct block_device *bdev, - if (op == BLKPG_DEL_PARTITION) - return bdev_del_partition(disk, p.pno); - -+ if (p.start < 0 || p.length <= 0 || p.start + p.length < 0) -+ return -EINVAL; -+ /* Check that the partition is aligned to the block size */ -+ if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev))) -+ return -EINVAL; -+ - start = p.start >> SECTOR_SHIFT; - length = p.length >> SECTOR_SHIFT; - - switch (op) { - case BLKPG_ADD_PARTITION: -- /* check if partition is aligned to blocksize */ -- if (p.start & (bdev_logical_block_size(bdev) - 1)) -- return -EINVAL; - return bdev_add_partition(disk, p.pno, start, length); - case BLKPG_RESIZE_PARTITION: - return bdev_resize_partition(disk, p.pno, start, length); -diff --git a/crypto/af_alg.c b/crypto/af_alg.c -index e893c0f6c8799..fef69d2a6b183 100644 ---- a/crypto/af_alg.c -+++ b/crypto/af_alg.c -@@ -1045,9 +1045,13 @@ EXPORT_SYMBOL_GPL(af_alg_sendpage); - void af_alg_free_resources(struct af_alg_async_req *areq) - { - struct sock *sk = areq->sk; -+ struct af_alg_ctx *ctx; - - af_alg_free_areq_sgls(areq); - sock_kfree_s(sk, areq, areq->areqlen); -+ -+ ctx = alg_sk(sk)->private; -+ ctx->inflight = false; - } - EXPORT_SYMBOL_GPL(af_alg_free_resources); - -@@ -1117,11 +1121,19 @@ EXPORT_SYMBOL_GPL(af_alg_poll); - struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, - unsigned int areqlen) - { -- struct af_alg_async_req *areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); -+ struct af_alg_ctx *ctx = alg_sk(sk)->private; -+ struct af_alg_async_req *areq; -+ -+ /* Only one AIO request can be in flight. */ -+ if (ctx->inflight) -+ return ERR_PTR(-EBUSY); - -+ areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); - if (unlikely(!areq)) - return ERR_PTR(-ENOMEM); - -+ ctx->inflight = true; -+ - areq->areqlen = areqlen; - areq->sk = sk; - areq->last_rsgl = NULL; -diff --git a/crypto/scompress.c b/crypto/scompress.c -index 738f4f8f0f41a..4d6366a444007 100644 ---- a/crypto/scompress.c -+++ b/crypto/scompress.c -@@ -124,6 +124,7 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) - struct crypto_scomp *scomp = *tfm_ctx; - void **ctx = acomp_request_ctx(req); - struct scomp_scratch *scratch; -+ unsigned int dlen; - int ret; - - if (!req->src || !req->slen || req->slen > SCOMP_SCRATCH_SIZE) -@@ -135,6 +136,8 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) - if (!req->dlen || req->dlen > SCOMP_SCRATCH_SIZE) - req->dlen = SCOMP_SCRATCH_SIZE; - -+ dlen = req->dlen; -+ - scratch = raw_cpu_ptr(&scomp_scratch); - spin_lock(&scratch->lock); - -@@ -152,6 +155,9 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir) - ret = -ENOMEM; - goto out; - } -+ } else if (req->dlen > dlen) { -+ ret = -ENOSPC; -+ goto out; - } - scatterwalk_map_and_copy(scratch->dst, req->dst, 0, req->dlen, - 1); -diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c -index e648158368a7d..088db2356998f 100644 ---- a/drivers/acpi/acpi_extlog.c -+++ b/drivers/acpi/acpi_extlog.c -@@ -145,9 +145,14 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, - static u32 err_seq; - - estatus = extlog_elog_entry_check(cpu, bank); -- if (estatus == NULL || (mce->kflags & MCE_HANDLED_CEC)) -+ if (!estatus) - return NOTIFY_DONE; - -+ if (mce->kflags & MCE_HANDLED_CEC) { -+ estatus->block_status = 0; -+ return NOTIFY_DONE; -+ } -+ - memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN); - /* clear record status to enable BIOS to update it again */ - estatus->block_status = 0; -diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c -index 50540d4d4948e..2c015ecf71853 100644 ---- a/drivers/acpi/acpi_lpit.c -+++ b/drivers/acpi/acpi_lpit.c -@@ -98,7 +98,7 @@ static void lpit_update_residency(struct lpit_residency_info *info, - struct acpi_lpit_native *lpit_native) - { - info->frequency = lpit_native->counter_frequency ? -- lpit_native->counter_frequency : tsc_khz * 1000; -+ lpit_native->counter_frequency : mul_u32_u32(tsc_khz, 1000U); - if (!info->frequency) - info->frequency = 1; - -diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c -index f08ffa75f4a76..8b44743945c8b 100644 ---- a/drivers/acpi/acpi_lpss.c -+++ b/drivers/acpi/acpi_lpss.c -@@ -450,8 +450,9 @@ static int register_device_clock(struct acpi_device *adev, - if (!clk_name) - return -ENOMEM; - clk = clk_register_fractional_divider(NULL, clk_name, parent, -+ 0, prv_base, 1, 15, 16, 15, - CLK_FRAC_DIVIDER_POWER_OF_TWO_PS, -- prv_base, 1, 15, 16, 15, 0, NULL); -+ NULL); - parent = clk_name; - - clk_name = kasprintf(GFP_KERNEL, "%s-update", devname); -diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c -index ed318485eb192..f7852fb75ab39 100644 ---- a/drivers/acpi/acpi_video.c -+++ b/drivers/acpi/acpi_video.c -@@ -1726,12 +1726,12 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) - return; - count++; - -- acpi_get_parent(device->dev->handle, &acpi_parent); -- -- pdev = acpi_get_pci_dev(acpi_parent); -- if (pdev) { -- parent = &pdev->dev; -- pci_dev_put(pdev); -+ if (ACPI_SUCCESS(acpi_get_parent(device->dev->handle, &acpi_parent))) { -+ pdev = acpi_get_pci_dev(acpi_parent); -+ if (pdev) { -+ parent = &pdev->dev; -+ pci_dev_put(pdev); -+ } - } - - memset(&props, 0, sizeof(struct backlight_properties)); -diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c -index 0565c18c2ee31..62aee900af3df 100644 ---- a/drivers/acpi/property.c -+++ b/drivers/acpi/property.c -@@ -851,6 +851,7 @@ static int acpi_get_ref_args(struct fwnode_reference_args *args, - * @index: Index of the reference to return - * @num_args: Maximum number of arguments after each reference - * @args: Location to store the returned reference with optional arguments -+ * (may be NULL) - * - * Find property with @name, verifify that it is a package containing at least - * one object reference and if so, store the ACPI device object pointer to the -@@ -907,6 +908,9 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, - if (!device) - return -EINVAL; - -+ if (!args) -+ return 0; -+ - args->fwnode = acpi_fwnode_handle(device); - args->nargs = 0; - return 0; -diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c -index ed607850f87fb..fcbb750b1ccc3 100644 ---- a/drivers/android/binder_alloc.c -+++ b/drivers/android/binder_alloc.c -@@ -271,7 +271,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, - } - if (mm) { - mmap_write_unlock(mm); -- mmput(mm); -+ mmput_async(mm); - } - return 0; - -@@ -304,7 +304,7 @@ err_page_ptr_cleared: - err_no_vma: - if (mm) { - mmap_write_unlock(mm); -- mmput(mm); -+ mmput_async(mm); - } - return vma ? -ENOMEM : -ESRCH; - } -@@ -344,8 +344,7 @@ static bool debug_low_async_space_locked(struct binder_alloc *alloc, int pid) - continue; - if (!buffer->async_transaction) - continue; -- total_alloc_size += binder_alloc_buffer_size(alloc, buffer) -- + sizeof(struct binder_buffer); -+ total_alloc_size += binder_alloc_buffer_size(alloc, buffer); - num_buffers++; - } - -@@ -407,17 +406,17 @@ static struct binder_buffer *binder_alloc_new_buf_locked( - alloc->pid, extra_buffers_size); - return ERR_PTR(-EINVAL); - } -- if (is_async && -- alloc->free_async_space < size + sizeof(struct binder_buffer)) { -+ -+ /* Pad 0-size buffers so they get assigned unique addresses */ -+ size = max(size, sizeof(void *)); -+ -+ if (is_async && alloc->free_async_space < size) { - binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: binder_alloc_buf size %zd failed, no async space left\n", - alloc->pid, size); - return ERR_PTR(-ENOSPC); - } - -- /* Pad 0-size buffers so they get assigned unique addresses */ -- size = max(size, sizeof(void *)); -- - while (n) { - buffer = rb_entry(n, struct binder_buffer, rb_node); - BUG_ON(!buffer->free); -@@ -519,7 +518,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked( - buffer->pid = pid; - buffer->oneway_spam_suspect = false; - if (is_async) { -- alloc->free_async_space -= size + sizeof(struct binder_buffer); -+ alloc->free_async_space -= size; - binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "%d: binder_alloc_buf size %zd async free %zd\n", - alloc->pid, size, alloc->free_async_space); -@@ -657,8 +656,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc, - BUG_ON(buffer->user_data > alloc->buffer + alloc->buffer_size); - - if (buffer->async_transaction) { -- alloc->free_async_space += buffer_size + sizeof(struct binder_buffer); -- -+ alloc->free_async_space += buffer_size; - binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "%d: binder_free_buf size %zd async free %zd\n", - alloc->pid, size, alloc->free_async_space); -diff --git a/drivers/base/node.c b/drivers/base/node.c -index faf3597a96da9..a4141b57b1478 100644 ---- a/drivers/base/node.c -+++ b/drivers/base/node.c -@@ -859,11 +859,15 @@ int __register_one_node(int nid) - { - int error; - int cpu; -+ struct node *node; - -- node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL); -- if (!node_devices[nid]) -+ node = kzalloc(sizeof(struct node), GFP_KERNEL); -+ if (!node) - return -ENOMEM; - -+ INIT_LIST_HEAD(&node->access_list); -+ node_devices[nid] = node; -+ - error = register_node(node_devices[nid], nid); - - /* link cpu under this node */ -@@ -872,7 +876,6 @@ int __register_one_node(int nid) - register_cpu_under_node(cpu, nid); - } - -- INIT_LIST_HEAD(&node_devices[nid]->access_list); - node_init_caches(nid); - - return error; -diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c -index 0a482212c7e8e..44153caa893ad 100644 ---- a/drivers/base/swnode.c -+++ b/drivers/base/swnode.c -@@ -541,6 +541,9 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, - if (nargs > NR_FWNODE_REFERENCE_ARGS) - return -EINVAL; - -+ if (!args) -+ return 0; -+ - args->fwnode = software_node_get(refnode); - args->nargs = nargs; - -diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 127e3ceb59799..12ff6f58b8a90 100644 ---- a/drivers/block/loop.c -+++ b/drivers/block/loop.c -@@ -165,39 +165,37 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file) - return get_size(lo->lo_offset, lo->lo_sizelimit, file); - } - -+/* -+ * We support direct I/O only if lo_offset is aligned with the logical I/O size -+ * of backing device, and the logical block size of loop is bigger than that of -+ * the backing device. -+ */ -+static bool lo_bdev_can_use_dio(struct loop_device *lo, -+ struct block_device *backing_bdev) -+{ -+ unsigned short sb_bsize = bdev_logical_block_size(backing_bdev); -+ -+ if (queue_logical_block_size(lo->lo_queue) < sb_bsize) -+ return false; -+ if (lo->lo_offset & (sb_bsize - 1)) -+ return false; -+ return true; -+} -+ - static void __loop_update_dio(struct loop_device *lo, bool dio) - { - struct file *file = lo->lo_backing_file; -- struct address_space *mapping = file->f_mapping; -- struct inode *inode = mapping->host; -- unsigned short sb_bsize = 0; -- unsigned dio_align = 0; -+ struct inode *inode = file->f_mapping->host; -+ struct block_device *backing_bdev = NULL; - bool use_dio; - -- if (inode->i_sb->s_bdev) { -- sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev); -- dio_align = sb_bsize - 1; -- } -+ if (S_ISBLK(inode->i_mode)) -+ backing_bdev = I_BDEV(inode); -+ else if (inode->i_sb->s_bdev) -+ backing_bdev = inode->i_sb->s_bdev; - -- /* -- * We support direct I/O only if lo_offset is aligned with the -- * logical I/O size of backing device, and the logical block -- * size of loop is bigger than the backing device's. -- * -- * TODO: the above condition may be loosed in the future, and -- * direct I/O may be switched runtime at that time because most -- * of requests in sane applications should be PAGE_SIZE aligned -- */ -- if (dio) { -- if (queue_logical_block_size(lo->lo_queue) >= sb_bsize && -- !(lo->lo_offset & dio_align) && -- (file->f_mode & FMODE_CAN_ODIRECT)) -- use_dio = true; -- else -- use_dio = false; -- } else { -- use_dio = false; -- } -+ use_dio = dio && (file->f_mode & FMODE_CAN_ODIRECT) && -+ (!backing_bdev || lo_bdev_can_use_dio(lo, backing_bdev)); - - if (lo->use_dio == use_dio) - return; -diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c -index e9f38eba2f133..959952e8ede38 100644 ---- a/drivers/block/null_blk/main.c -+++ b/drivers/block/null_blk/main.c -@@ -2114,11 +2114,8 @@ static int null_add_dev(struct nullb_device *dev) - - blk_queue_logical_block_size(nullb->q, dev->blocksize); - blk_queue_physical_block_size(nullb->q, dev->blocksize); -- if (!dev->max_sectors) -- dev->max_sectors = queue_max_hw_sectors(nullb->q); -- dev->max_sectors = min_t(unsigned int, dev->max_sectors, -- BLK_DEF_MAX_SECTORS); -- blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); -+ if (dev->max_sectors) -+ blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); - - if (dev->virt_boundary) - blk_queue_virt_boundary(nullb->q, PAGE_SIZE - 1); -@@ -2218,12 +2215,6 @@ static int __init null_init(void) - g_bs = PAGE_SIZE; - } - -- if (g_max_sectors > BLK_DEF_MAX_SECTORS) { -- pr_warn("invalid max sectors\n"); -- pr_warn("defaults max sectors to %u\n", BLK_DEF_MAX_SECTORS); -- g_max_sectors = BLK_DEF_MAX_SECTORS; -- } -- - if (g_home_node != NUMA_NO_NODE && g_home_node >= nr_online_nodes) { - pr_err("invalid home_node value\n"); - g_home_node = NUMA_NO_NODE; -diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c -index c98691cdbbd55..04b72394dda5b 100644 ---- a/drivers/bluetooth/btmtkuart.c -+++ b/drivers/bluetooth/btmtkuart.c -@@ -337,7 +337,7 @@ mtk_stp_split(struct btmtkuart_dev *bdev, const unsigned char *data, int count, - return data; - } - --static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) -+static void btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) - { - struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); - const unsigned char *p_left = data, *p_h4; -@@ -376,25 +376,20 @@ static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) - bt_dev_err(bdev->hdev, - "Frame reassembly failed (%d)", err); - bdev->rx_skb = NULL; -- return err; -+ return; - } - - sz_left -= sz_h4; - p_left += sz_h4; - } -- -- return 0; - } - - static int btmtkuart_receive_buf(struct serdev_device *serdev, const u8 *data, - size_t count) - { - struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); -- int err; - -- err = btmtkuart_recv(bdev->hdev, data, count); -- if (err < 0) -- return err; -+ btmtkuart_recv(bdev->hdev, data, count); - - bdev->hdev->stat.byte_rx += count; - -diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c -index c7d8cbd22bacc..5acb35236c58d 100644 ---- a/drivers/clk/clk-si5341.c -+++ b/drivers/clk/clk-si5341.c -@@ -892,10 +892,8 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate, - r[0] = r_div ? (r_div & 0xff) : 1; - r[1] = (r_div >> 8) & 0xff; - r[2] = (r_div >> 16) & 0xff; -- err = regmap_bulk_write(output->data->regmap, -+ return regmap_bulk_write(output->data->regmap, - SI5341_OUT_R_REG(output), r, 3); -- -- return 0; - } - - static int si5341_output_reparent(struct clk_si5341_output *output, u8 index) -diff --git a/drivers/clk/qcom/gpucc-sm8150.c b/drivers/clk/qcom/gpucc-sm8150.c -index 8422fd0474932..c89a5b59ddb7c 100644 ---- a/drivers/clk/qcom/gpucc-sm8150.c -+++ b/drivers/clk/qcom/gpucc-sm8150.c -@@ -37,8 +37,8 @@ static struct alpha_pll_config gpu_cc_pll1_config = { - .config_ctl_hi_val = 0x00002267, - .config_ctl_hi1_val = 0x00000024, - .test_ctl_val = 0x00000000, -- .test_ctl_hi_val = 0x00000002, -- .test_ctl_hi1_val = 0x00000000, -+ .test_ctl_hi_val = 0x00000000, -+ .test_ctl_hi1_val = 0x00000020, - .user_ctl_val = 0x00000000, - .user_ctl_hi_val = 0x00000805, - .user_ctl_hi1_val = 0x000000d0, -diff --git a/drivers/clk/qcom/videocc-sm8150.c b/drivers/clk/qcom/videocc-sm8150.c -index 1afdbe4a249d6..52a9a453a1432 100644 ---- a/drivers/clk/qcom/videocc-sm8150.c -+++ b/drivers/clk/qcom/videocc-sm8150.c -@@ -33,6 +33,7 @@ static struct alpha_pll_config video_pll0_config = { - .config_ctl_val = 0x20485699, - .config_ctl_hi_val = 0x00002267, - .config_ctl_hi1_val = 0x00000024, -+ .test_ctl_hi1_val = 0x00000020, - .user_ctl_val = 0x00000000, - .user_ctl_hi_val = 0x00000805, - .user_ctl_hi1_val = 0x000000D0, -@@ -214,6 +215,10 @@ static const struct regmap_config video_cc_sm8150_regmap_config = { - - static const struct qcom_reset_map video_cc_sm8150_resets[] = { - [VIDEO_CC_MVSC_CORE_CLK_BCR] = { 0x850, 2 }, -+ [VIDEO_CC_INTERFACE_BCR] = { 0x8f0 }, -+ [VIDEO_CC_MVS0_BCR] = { 0x870 }, -+ [VIDEO_CC_MVS1_BCR] = { 0x8b0 }, -+ [VIDEO_CC_MVSC_BCR] = { 0x810 }, - }; - - static const struct qcom_cc_desc video_cc_sm8150_desc = { -diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c -index 84767cfc1e739..473feb36a38f2 100644 ---- a/drivers/clk/renesas/rzg2l-cpg.c -+++ b/drivers/clk/renesas/rzg2l-cpg.c -@@ -1115,41 +1115,33 @@ fail: - - #define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) - --static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, -- unsigned long id) --{ -- struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); -- const struct rzg2l_cpg_info *info = priv->info; -- unsigned int reg = info->resets[id].off; -- u32 dis = BIT(info->resets[id].bit); -- u32 we = dis << 16; -- -- dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); -- -- /* Reset module */ -- writel(we, priv->base + CLK_RST_R(reg)); -- -- /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ -- udelay(35); -- -- /* Release module from reset state */ -- writel(we | dis, priv->base + CLK_RST_R(reg)); -- -- return 0; --} -- - static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, - unsigned long id) - { - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; -- u32 value = BIT(info->resets[id].bit) << 16; -+ u32 mask = BIT(info->resets[id].bit); -+ s8 monbit = info->resets[id].monbit; -+ u32 value = mask << 16; - - dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); - - writel(value, priv->base + CLK_RST_R(reg)); -- return 0; -+ -+ if (info->has_clk_mon_regs) { -+ reg = CLK_MRST_R(reg); -+ } else if (monbit >= 0) { -+ reg = CPG_RST_MON; -+ mask = BIT(monbit); -+ } else { -+ /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ -+ udelay(35); -+ return 0; -+ } -+ -+ return readl_poll_timeout_atomic(priv->base + reg, value, -+ value & mask, 10, 200); - } - - static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, -@@ -1158,14 +1150,40 @@ static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; -- u32 dis = BIT(info->resets[id].bit); -- u32 value = (dis << 16) | dis; -+ u32 mask = BIT(info->resets[id].bit); -+ s8 monbit = info->resets[id].monbit; -+ u32 value = (mask << 16) | mask; - - dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, - CLK_RST_R(reg)); - - writel(value, priv->base + CLK_RST_R(reg)); -- return 0; -+ -+ if (info->has_clk_mon_regs) { -+ reg = CLK_MRST_R(reg); -+ } else if (monbit >= 0) { -+ reg = CPG_RST_MON; -+ mask = BIT(monbit); -+ } else { -+ /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ -+ udelay(35); -+ return 0; -+ } -+ -+ return readl_poll_timeout_atomic(priv->base + reg, value, -+ !(value & mask), 10, 200); -+} -+ -+static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ int ret; -+ -+ ret = rzg2l_cpg_assert(rcdev, id); -+ if (ret) -+ return ret; -+ -+ return rzg2l_cpg_deassert(rcdev, id); - } - - static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, -@@ -1173,18 +1191,21 @@ static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, - { - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; -- unsigned int reg = info->resets[id].off; -- u32 bitmask = BIT(info->resets[id].bit); - s8 monbit = info->resets[id].monbit; -+ unsigned int reg; -+ u32 bitmask; - - if (info->has_clk_mon_regs) { -- return !!(readl(priv->base + CLK_MRST_R(reg)) & bitmask); -+ reg = CLK_MRST_R(info->resets[id].off); -+ bitmask = BIT(info->resets[id].bit); - } else if (monbit >= 0) { -- u32 monbitmask = BIT(monbit); -- -- return !!(readl(priv->base + CPG_RST_MON) & monbitmask); -+ reg = CPG_RST_MON; -+ bitmask = BIT(monbit); -+ } else { -+ return -ENOTSUPP; - } -- return -ENOTSUPP; -+ -+ return !!(readl(priv->base + reg) & bitmask); - } - - static const struct reset_control_ops rzg2l_cpg_reset_ops = { -diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c -index 60359333f26db..9b5d3050b7422 100644 ---- a/drivers/clk/zynqmp/clk-mux-zynqmp.c -+++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c -@@ -89,7 +89,7 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index) - static const struct clk_ops zynqmp_clk_mux_ops = { - .get_parent = zynqmp_clk_mux_get_parent, - .set_parent = zynqmp_clk_mux_set_parent, -- .determine_rate = __clk_mux_determine_rate, -+ .determine_rate = __clk_mux_determine_rate_closest, - }; - - static const struct clk_ops zynqmp_clk_mux_ro_ops = { -diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c -index 33a3b2a226595..5a00487ae408b 100644 ---- a/drivers/clk/zynqmp/divider.c -+++ b/drivers/clk/zynqmp/divider.c -@@ -110,52 +110,6 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, - return DIV_ROUND_UP_ULL(parent_rate, value); - } - --static void zynqmp_get_divider2_val(struct clk_hw *hw, -- unsigned long rate, -- struct zynqmp_clk_divider *divider, -- u32 *bestdiv) --{ -- int div1; -- int div2; -- long error = LONG_MAX; -- unsigned long div1_prate; -- struct clk_hw *div1_parent_hw; -- struct zynqmp_clk_divider *pdivider; -- struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw); -- -- if (!div2_parent_hw) -- return; -- -- pdivider = to_zynqmp_clk_divider(div2_parent_hw); -- if (!pdivider) -- return; -- -- div1_parent_hw = clk_hw_get_parent(div2_parent_hw); -- if (!div1_parent_hw) -- return; -- -- div1_prate = clk_hw_get_rate(div1_parent_hw); -- *bestdiv = 1; -- for (div1 = 1; div1 <= pdivider->max_div;) { -- for (div2 = 1; div2 <= divider->max_div;) { -- long new_error = ((div1_prate / div1) / div2) - rate; -- -- if (abs(new_error) < abs(error)) { -- *bestdiv = div2; -- error = new_error; -- } -- if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) -- div2 = div2 << 1; -- else -- div2++; -- } -- if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO) -- div1 = div1 << 1; -- else -- div1++; -- } --} -- - /** - * zynqmp_clk_divider_round_rate() - Round rate of divider clock - * @hw: handle between common and hardware-specific interfaces -@@ -174,6 +128,7 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, - u32 div_type = divider->div_type; - u32 bestdiv; - int ret; -+ u8 width; - - /* if read only, just return current value */ - if (divider->flags & CLK_DIVIDER_READ_ONLY) { -@@ -193,23 +148,12 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, - return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); - } - -- bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags); -- -- /* -- * In case of two divisors, compute best divider values and return -- * divider2 value based on compute value. div1 will be automatically -- * set to optimum based on required total divider value. -- */ -- if (div_type == TYPE_DIV2 && -- (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { -- zynqmp_get_divider2_val(hw, rate, divider, &bestdiv); -- } -+ width = fls(divider->max_div); - -- if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac) -- bestdiv = rate % *prate ? 1 : bestdiv; -+ rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags); - -- bestdiv = min_t(u32, bestdiv, divider->max_div); -- *prate = rate * bestdiv; -+ if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (rate % *prate)) -+ *prate = rate; - - return rate; - } -diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c -index ec86aecb748f1..7f9c1f58a9477 100644 ---- a/drivers/clocksource/timer-ti-dm.c -+++ b/drivers/clocksource/timer-ti-dm.c -@@ -184,7 +184,7 @@ static inline u32 dmtimer_read(struct dmtimer *timer, u32 reg) - * dmtimer_write - write timer registers in posted and non-posted mode - * @timer: timer pointer over which write operation is to perform - * @reg: lowest byte holds the register offset -- * @value: data to write into the register -+ * @val: data to write into the register - * - * The posted mode bit is encoded in reg. Note that in posted mode, the write - * pending bit must be checked. Otherwise a write on a register which has a -@@ -937,7 +937,7 @@ static int omap_dm_timer_set_int_enable(struct omap_dm_timer *cookie, - - /** - * omap_dm_timer_set_int_disable - disable timer interrupts -- * @timer: pointer to timer handle -+ * @cookie: pointer to timer cookie - * @mask: bit mask of interrupts to be disabled - * - * Disables the specified timer interrupts for a timer. -diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c -index 69a8742c0a7a3..8514bb62dd10b 100644 ---- a/drivers/cpufreq/cpufreq-dt-platdev.c -+++ b/drivers/cpufreq/cpufreq-dt-platdev.c -@@ -176,7 +176,7 @@ static bool __init cpu0_node_has_opp_v2_prop(void) - struct device_node *np = of_cpu_device_node_get(0); - bool ret = false; - -- if (of_get_property(np, "operating-points-v2", NULL)) -+ if (of_property_present(np, "operating-points-v2")) - ret = true; - - of_node_put(np); -diff --git a/drivers/cpufreq/imx-cpufreq-dt.c b/drivers/cpufreq/imx-cpufreq-dt.c -index 76e553af20711..535867a7dfdde 100644 ---- a/drivers/cpufreq/imx-cpufreq-dt.c -+++ b/drivers/cpufreq/imx-cpufreq-dt.c -@@ -89,7 +89,7 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev) - - cpu_dev = get_cpu_device(0); - -- if (!of_find_property(cpu_dev->of_node, "cpu-supply", NULL)) -+ if (!of_property_present(cpu_dev->of_node, "cpu-supply")) - return -ENODEV; - - if (of_machine_is_compatible("fsl,imx7ulp")) { -diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c -index 925fc17eaacb2..39b0362a3b9ac 100644 ---- a/drivers/cpufreq/imx6q-cpufreq.c -+++ b/drivers/cpufreq/imx6q-cpufreq.c -@@ -230,7 +230,7 @@ static int imx6q_opp_check_speed_grading(struct device *dev) - u32 val; - int ret; - -- if (of_find_property(dev->of_node, "nvmem-cells", NULL)) { -+ if (of_property_present(dev->of_node, "nvmem-cells")) { - ret = nvmem_cell_read_u32(dev, "speed_grade", &val); - if (ret) - return ret; -@@ -285,7 +285,7 @@ static int imx6ul_opp_check_speed_grading(struct device *dev) - u32 val; - int ret = 0; - -- if (of_find_property(dev->of_node, "nvmem-cells", NULL)) { -+ if (of_property_present(dev->of_node, "nvmem-cells")) { - ret = nvmem_cell_read_u32(dev, "speed_grade", &val); - if (ret) - return ret; -diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c -index 513a071845c26..028df8a5f537a 100644 ---- a/drivers/cpufreq/scmi-cpufreq.c -+++ b/drivers/cpufreq/scmi-cpufreq.c -@@ -310,8 +310,11 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev) - - #ifdef CONFIG_COMMON_CLK - /* dummy clock provider as needed by OPP if clocks property is used */ -- if (of_find_property(dev->of_node, "#clock-cells", NULL)) -- devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); -+ if (of_property_present(dev->of_node, "#clock-cells")) { -+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); -+ if (ret) -+ return dev_err_probe(dev, ret, "%s: registering clock provider failed\n", __func__); -+ } - #endif - - ret = cpufreq_register_driver(&scmi_cpufreq_driver); -diff --git a/drivers/cpufreq/tegra20-cpufreq.c b/drivers/cpufreq/tegra20-cpufreq.c -index ab7ac7df9e62e..dfd2de4f8e07e 100644 ---- a/drivers/cpufreq/tegra20-cpufreq.c -+++ b/drivers/cpufreq/tegra20-cpufreq.c -@@ -25,7 +25,7 @@ static bool cpu0_node_has_opp_v2_prop(void) - struct device_node *np = of_cpu_device_node_get(0); - bool ret = false; - -- if (of_get_property(np, "operating-points-v2", NULL)) -+ if (of_property_present(np, "operating-points-v2")) - ret = true; - - of_node_put(np); -diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c -index aa4e1a5006919..cb8e99936abb7 100644 ---- a/drivers/crypto/ccp/ccp-ops.c -+++ b/drivers/crypto/ccp/ccp-ops.c -@@ -179,8 +179,11 @@ static int ccp_init_dm_workarea(struct ccp_dm_workarea *wa, - - wa->dma.address = dma_map_single(wa->dev, wa->address, len, - dir); -- if (dma_mapping_error(wa->dev, wa->dma.address)) -+ if (dma_mapping_error(wa->dev, wa->dma.address)) { -+ kfree(wa->address); -+ wa->address = NULL; - return -ENOMEM; -+ } - - wa->dma.length = len; - } -diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c -index ff8a5f20a5df0..269df4ec148ba 100644 ---- a/drivers/crypto/hisilicon/hpre/hpre_main.c -+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c -@@ -118,8 +118,6 @@ - #define HPRE_DFX_COMMON2_LEN 0xE - #define HPRE_DFX_CORE_LEN 0x43 - --#define HPRE_DEV_ALG_MAX_LEN 256 -- - static const char hpre_name[] = "hisi_hpre"; - static struct dentry *hpre_debugfs_root; - static const struct pci_device_id hpre_dev_ids[] = { -@@ -135,12 +133,7 @@ struct hpre_hw_error { - const char *msg; - }; - --struct hpre_dev_alg { -- u32 alg_msk; -- const char *alg; --}; -- --static const struct hpre_dev_alg hpre_dev_algs[] = { -+static const struct qm_dev_alg hpre_dev_algs[] = { - { - .alg_msk = BIT(0), - .alg = "rsa\n" -@@ -233,6 +226,20 @@ static const struct hisi_qm_cap_info hpre_basic_info[] = { - {HPRE_CORE10_ALG_BITMAP_CAP, 0x3170, 0, GENMASK(31, 0), 0x0, 0x10, 0x10} - }; - -+enum hpre_pre_store_cap_idx { -+ HPRE_CLUSTER_NUM_CAP_IDX = 0x0, -+ HPRE_CORE_ENABLE_BITMAP_CAP_IDX, -+ HPRE_DRV_ALG_BITMAP_CAP_IDX, -+ HPRE_DEV_ALG_BITMAP_CAP_IDX, -+}; -+ -+static const u32 hpre_pre_store_caps[] = { -+ HPRE_CLUSTER_NUM_CAP, -+ HPRE_CORE_ENABLE_BITMAP_CAP, -+ HPRE_DRV_ALG_BITMAP_CAP, -+ HPRE_DEV_ALG_BITMAP_CAP, -+}; -+ - static const struct hpre_hw_error hpre_hw_errors[] = { - { - .int_msk = BIT(0), -@@ -352,42 +359,13 @@ bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg) - { - u32 cap_val; - -- cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DRV_ALG_BITMAP_CAP, qm->cap_ver); -+ cap_val = qm->cap_tables.dev_cap_table[HPRE_DRV_ALG_BITMAP_CAP_IDX].cap_val; - if (alg & cap_val) - return true; - - return false; - } - --static int hpre_set_qm_algs(struct hisi_qm *qm) --{ -- struct device *dev = &qm->pdev->dev; -- char *algs, *ptr; -- u32 alg_msk; -- int i; -- -- if (!qm->use_sva) -- return 0; -- -- algs = devm_kzalloc(dev, HPRE_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); -- if (!algs) -- return -ENOMEM; -- -- alg_msk = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DEV_ALG_BITMAP_CAP, qm->cap_ver); -- -- for (i = 0; i < ARRAY_SIZE(hpre_dev_algs); i++) -- if (alg_msk & hpre_dev_algs[i].alg_msk) -- strcat(algs, hpre_dev_algs[i].alg); -- -- ptr = strrchr(algs, '\n'); -- if (ptr) -- *ptr = '\0'; -- -- qm->uacce->algs = algs; -- -- return 0; --} -- - static int hpre_diff_regs_show(struct seq_file *s, void *unused) - { - struct hisi_qm *qm = s->private; -@@ -457,16 +435,6 @@ static u32 vfs_num; - module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444); - MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)"); - --static inline int hpre_cluster_num(struct hisi_qm *qm) --{ -- return hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CLUSTER_NUM_CAP, qm->cap_ver); --} -- --static inline int hpre_cluster_core_mask(struct hisi_qm *qm) --{ -- return hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CORE_ENABLE_BITMAP_CAP, qm->cap_ver); --} -- - struct hisi_qp *hpre_create_qp(u8 type) - { - int node = cpu_to_node(smp_processor_id()); -@@ -533,13 +501,15 @@ static int hpre_cfg_by_dsm(struct hisi_qm *qm) - - static int hpre_set_cluster(struct hisi_qm *qm) - { -- u32 cluster_core_mask = hpre_cluster_core_mask(qm); -- u8 clusters_num = hpre_cluster_num(qm); - struct device *dev = &qm->pdev->dev; - unsigned long offset; -+ u32 cluster_core_mask; -+ u8 clusters_num; - u32 val = 0; - int ret, i; - -+ cluster_core_mask = qm->cap_tables.dev_cap_table[HPRE_CORE_ENABLE_BITMAP_CAP_IDX].cap_val; -+ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; - for (i = 0; i < clusters_num; i++) { - offset = i * HPRE_CLSTR_ADDR_INTRVL; - -@@ -734,11 +704,12 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm) - - static void hpre_cnt_regs_clear(struct hisi_qm *qm) - { -- u8 clusters_num = hpre_cluster_num(qm); - unsigned long offset; -+ u8 clusters_num; - int i; - - /* clear clusterX/cluster_ctrl */ -+ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; - for (i = 0; i < clusters_num; i++) { - offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL; - writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY); -@@ -1025,13 +996,14 @@ static int hpre_pf_comm_regs_debugfs_init(struct hisi_qm *qm) - - static int hpre_cluster_debugfs_init(struct hisi_qm *qm) - { -- u8 clusters_num = hpre_cluster_num(qm); - struct device *dev = &qm->pdev->dev; - char buf[HPRE_DBGFS_VAL_MAX_LEN]; - struct debugfs_regset32 *regset; - struct dentry *tmp_d; -+ u8 clusters_num; - int i, ret; - -+ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; - for (i = 0; i < clusters_num; i++) { - ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); - if (ret >= HPRE_DBGFS_VAL_MAX_LEN) -@@ -1136,8 +1108,37 @@ static void hpre_debugfs_exit(struct hisi_qm *qm) - debugfs_remove_recursive(qm->debug.debug_root); - } - -+static int hpre_pre_store_cap_reg(struct hisi_qm *qm) -+{ -+ struct hisi_qm_cap_record *hpre_cap; -+ struct device *dev = &qm->pdev->dev; -+ size_t i, size; -+ -+ size = ARRAY_SIZE(hpre_pre_store_caps); -+ hpre_cap = devm_kzalloc(dev, sizeof(*hpre_cap) * size, GFP_KERNEL); -+ if (!hpre_cap) -+ return -ENOMEM; -+ -+ for (i = 0; i < size; i++) { -+ hpre_cap[i].type = hpre_pre_store_caps[i]; -+ hpre_cap[i].cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, -+ hpre_pre_store_caps[i], qm->cap_ver); -+ } -+ -+ if (hpre_cap[HPRE_CLUSTER_NUM_CAP_IDX].cap_val > HPRE_CLUSTERS_NUM_MAX) { -+ dev_err(dev, "Device cluster num %u is out of range for driver supports %d!\n", -+ hpre_cap[HPRE_CLUSTER_NUM_CAP_IDX].cap_val, HPRE_CLUSTERS_NUM_MAX); -+ return -EINVAL; -+ } -+ -+ qm->cap_tables.dev_cap_table = hpre_cap; -+ -+ return 0; -+} -+ - static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - { -+ u64 alg_msk; - int ret; - - if (pdev->revision == QM_HW_V1) { -@@ -1168,7 +1169,16 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - return ret; - } - -- ret = hpre_set_qm_algs(qm); -+ /* Fetch and save the value of capability registers */ -+ ret = hpre_pre_store_cap_reg(qm); -+ if (ret) { -+ pci_err(pdev, "Failed to pre-store capability registers!\n"); -+ hisi_qm_uninit(qm); -+ return ret; -+ } -+ -+ alg_msk = qm->cap_tables.dev_cap_table[HPRE_DEV_ALG_BITMAP_CAP_IDX].cap_val; -+ ret = hisi_qm_set_algs(qm, alg_msk, hpre_dev_algs, ARRAY_SIZE(hpre_dev_algs)); - if (ret) { - pci_err(pdev, "Failed to set hpre algs!\n"); - hisi_qm_uninit(qm); -@@ -1181,11 +1191,12 @@ static int hpre_show_last_regs_init(struct hisi_qm *qm) - { - int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs); - int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); -- u8 clusters_num = hpre_cluster_num(qm); - struct qm_debug *debug = &qm->debug; - void __iomem *io_base; -+ u8 clusters_num; - int i, j, idx; - -+ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; - debug->last_words = kcalloc(cluster_dfx_regs_num * clusters_num + - com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); - if (!debug->last_words) -@@ -1222,10 +1233,10 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) - { - int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs); - int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); -- u8 clusters_num = hpre_cluster_num(qm); - struct qm_debug *debug = &qm->debug; - struct pci_dev *pdev = qm->pdev; - void __iomem *io_base; -+ u8 clusters_num; - int i, j, idx; - u32 val; - -@@ -1240,6 +1251,7 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) - hpre_com_dfx_regs[i].name, debug->last_words[i], val); - } - -+ clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; - for (i = 0; i < clusters_num; i++) { - io_base = qm->io_base + hpre_cluster_offsets[i]; - for (j = 0; j < cluster_dfx_regs_num; j++) { -diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c -index f9acf7ecc41be..5539be1bfb402 100644 ---- a/drivers/crypto/hisilicon/qm.c -+++ b/drivers/crypto/hisilicon/qm.c -@@ -237,6 +237,8 @@ - #define QM_QOS_MAX_CIR_S 11 - #define QM_AUTOSUSPEND_DELAY 3000 - -+#define QM_DEV_ALG_MAX_LEN 256 -+ - #define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \ - (((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \ - ((pg_sz) << QM_CQ_PAGE_SIZE_SHIFT) | \ -@@ -315,6 +317,13 @@ enum qm_basic_type { - QM_VF_IRQ_NUM_CAP, - }; - -+enum qm_pre_store_cap_idx { -+ QM_EQ_IRQ_TYPE_CAP_IDX = 0x0, -+ QM_AEQ_IRQ_TYPE_CAP_IDX, -+ QM_ABN_IRQ_TYPE_CAP_IDX, -+ QM_PF2VF_IRQ_TYPE_CAP_IDX, -+}; -+ - static const struct hisi_qm_cap_info qm_cap_info_comm[] = { - {QM_SUPPORT_DB_ISOLATION, 0x30, 0, BIT(0), 0x0, 0x0, 0x0}, - {QM_SUPPORT_FUNC_QOS, 0x3100, 0, BIT(8), 0x0, 0x0, 0x1}, -@@ -344,6 +353,13 @@ static const struct hisi_qm_cap_info qm_basic_info[] = { - {QM_VF_IRQ_NUM_CAP, 0x311c, 0, GENMASK(15, 0), 0x1, 0x2, 0x3}, - }; - -+static const u32 qm_pre_store_caps[] = { -+ QM_EQ_IRQ_TYPE_CAP, -+ QM_AEQ_IRQ_TYPE_CAP, -+ QM_ABN_IRQ_TYPE_CAP, -+ QM_PF2VF_IRQ_TYPE_CAP, -+}; -+ - struct qm_mailbox { - __le16 w0; - __le16 queue_num; -@@ -781,6 +797,40 @@ static void qm_get_xqc_depth(struct hisi_qm *qm, u16 *low_bits, - *high_bits = (depth >> QM_XQ_DEPTH_SHIFT) & QM_XQ_DEPTH_MASK; - } - -+int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs, -+ u32 dev_algs_size) -+{ -+ struct device *dev = &qm->pdev->dev; -+ char *algs, *ptr; -+ int i; -+ -+ if (!qm->uacce) -+ return 0; -+ -+ if (dev_algs_size >= QM_DEV_ALG_MAX_LEN) { -+ dev_err(dev, "algs size %u is equal or larger than %d.\n", -+ dev_algs_size, QM_DEV_ALG_MAX_LEN); -+ return -EINVAL; -+ } -+ -+ algs = devm_kzalloc(dev, QM_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); -+ if (!algs) -+ return -ENOMEM; -+ -+ for (i = 0; i < dev_algs_size; i++) -+ if (alg_msk & dev_algs[i].alg_msk) -+ strcat(algs, dev_algs[i].alg); -+ -+ ptr = strrchr(algs, '\n'); -+ if (ptr) { -+ *ptr = '\0'; -+ qm->uacce->algs = algs; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(hisi_qm_set_algs); -+ - static u32 qm_get_irq_num(struct hisi_qm *qm) - { - if (qm->fun_type == QM_HW_PF) -@@ -4804,7 +4854,7 @@ static void qm_unregister_abnormal_irq(struct hisi_qm *qm) - if (qm->fun_type == QM_HW_VF) - return; - -- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); -+ val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) - return; - -@@ -4821,7 +4871,7 @@ static int qm_register_abnormal_irq(struct hisi_qm *qm) - if (qm->fun_type == QM_HW_VF) - return 0; - -- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); -+ val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) - return 0; - -@@ -4838,7 +4888,7 @@ static void qm_unregister_mb_cmd_irq(struct hisi_qm *qm) - struct pci_dev *pdev = qm->pdev; - u32 irq_vector, val; - -- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); -+ val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) - return; - -@@ -4852,7 +4902,7 @@ static int qm_register_mb_cmd_irq(struct hisi_qm *qm) - u32 irq_vector, val; - int ret; - -- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); -+ val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) - return 0; - -@@ -4869,7 +4919,7 @@ static void qm_unregister_aeq_irq(struct hisi_qm *qm) - struct pci_dev *pdev = qm->pdev; - u32 irq_vector, val; - -- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); -+ val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) - return; - -@@ -4883,7 +4933,7 @@ static int qm_register_aeq_irq(struct hisi_qm *qm) - u32 irq_vector, val; - int ret; - -- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); -+ val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) - return 0; - -@@ -4901,7 +4951,7 @@ static void qm_unregister_eq_irq(struct hisi_qm *qm) - struct pci_dev *pdev = qm->pdev; - u32 irq_vector, val; - -- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); -+ val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) - return; - -@@ -4915,7 +4965,7 @@ static int qm_register_eq_irq(struct hisi_qm *qm) - u32 irq_vector, val; - int ret; - -- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); -+ val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) - return 0; - -@@ -5003,7 +5053,29 @@ static int qm_get_qp_num(struct hisi_qm *qm) - return 0; - } - --static void qm_get_hw_caps(struct hisi_qm *qm) -+static int qm_pre_store_irq_type_caps(struct hisi_qm *qm) -+{ -+ struct hisi_qm_cap_record *qm_cap; -+ struct pci_dev *pdev = qm->pdev; -+ size_t i, size; -+ -+ size = ARRAY_SIZE(qm_pre_store_caps); -+ qm_cap = devm_kzalloc(&pdev->dev, sizeof(*qm_cap) * size, GFP_KERNEL); -+ if (!qm_cap) -+ return -ENOMEM; -+ -+ for (i = 0; i < size; i++) { -+ qm_cap[i].type = qm_pre_store_caps[i]; -+ qm_cap[i].cap_val = hisi_qm_get_hw_info(qm, qm_basic_info, -+ qm_pre_store_caps[i], qm->cap_ver); -+ } -+ -+ qm->cap_tables.qm_cap_table = qm_cap; -+ -+ return 0; -+} -+ -+static int qm_get_hw_caps(struct hisi_qm *qm) - { - const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ? - qm_cap_info_pf : qm_cap_info_vf; -@@ -5034,6 +5106,9 @@ static void qm_get_hw_caps(struct hisi_qm *qm) - if (val) - set_bit(cap_info[i].type, &qm->caps); - } -+ -+ /* Fetch and save the value of irq type related capability registers */ -+ return qm_pre_store_irq_type_caps(qm); - } - - static int qm_get_pci_res(struct hisi_qm *qm) -@@ -5055,7 +5130,10 @@ static int qm_get_pci_res(struct hisi_qm *qm) - goto err_request_mem_regions; - } - -- qm_get_hw_caps(qm); -+ ret = qm_get_hw_caps(qm); -+ if (ret) -+ goto err_ioremap; -+ - if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) { - qm->db_interval = QM_QP_DB_INTERVAL; - qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4); -diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h -index 3e57fc04b3770..410c83712e285 100644 ---- a/drivers/crypto/hisilicon/sec2/sec.h -+++ b/drivers/crypto/hisilicon/sec2/sec.h -@@ -220,6 +220,13 @@ enum sec_cap_type { - SEC_CORE4_ALG_BITMAP_HIGH, - }; - -+enum sec_cap_reg_record_idx { -+ SEC_DRV_ALG_BITMAP_LOW_IDX = 0x0, -+ SEC_DRV_ALG_BITMAP_HIGH_IDX, -+ SEC_DEV_ALG_BITMAP_LOW_IDX, -+ SEC_DEV_ALG_BITMAP_HIGH_IDX, -+}; -+ - void sec_destroy_qps(struct hisi_qp **qps, int qp_num); - struct hisi_qp **sec_create_qps(void); - int sec_register_to_crypto(struct hisi_qm *qm); -diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c -index 84ae8ddd1a131..cae7c414bdaf4 100644 ---- a/drivers/crypto/hisilicon/sec2/sec_crypto.c -+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c -@@ -2546,8 +2546,12 @@ err: - - int sec_register_to_crypto(struct hisi_qm *qm) - { -- u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); -- int ret; -+ u64 alg_mask; -+ int ret = 0; -+ -+ alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, -+ SEC_DRV_ALG_BITMAP_LOW_IDX); -+ - - ret = sec_register_skcipher(alg_mask); - if (ret) -@@ -2562,7 +2566,10 @@ int sec_register_to_crypto(struct hisi_qm *qm) - - void sec_unregister_from_crypto(struct hisi_qm *qm) - { -- u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); -+ u64 alg_mask; -+ -+ alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, -+ SEC_DRV_ALG_BITMAP_LOW_IDX); - - sec_unregister_aead(alg_mask, ARRAY_SIZE(sec_aeads)); - sec_unregister_skcipher(alg_mask, ARRAY_SIZE(sec_skciphers)); -diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c -index e384988bda917..4bab5000a13e5 100644 ---- a/drivers/crypto/hisilicon/sec2/sec_main.c -+++ b/drivers/crypto/hisilicon/sec2/sec_main.c -@@ -121,7 +121,6 @@ - GENMASK_ULL(42, 25)) - #define SEC_AEAD_BITMAP (GENMASK_ULL(7, 6) | GENMASK_ULL(18, 17) | \ - GENMASK_ULL(45, 43)) --#define SEC_DEV_ALG_MAX_LEN 256 - - struct sec_hw_error { - u32 int_msk; -@@ -133,11 +132,6 @@ struct sec_dfx_item { - u32 offset; - }; - --struct sec_dev_alg { -- u64 alg_msk; -- const char *algs; --}; -- - static const char sec_name[] = "hisi_sec2"; - static struct dentry *sec_debugfs_root; - -@@ -174,15 +168,22 @@ static const struct hisi_qm_cap_info sec_basic_info[] = { - {SEC_CORE4_ALG_BITMAP_HIGH, 0x3170, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF}, - }; - --static const struct sec_dev_alg sec_dev_algs[] = { { -+static const u32 sec_pre_store_caps[] = { -+ SEC_DRV_ALG_BITMAP_LOW, -+ SEC_DRV_ALG_BITMAP_HIGH, -+ SEC_DEV_ALG_BITMAP_LOW, -+ SEC_DEV_ALG_BITMAP_HIGH, -+}; -+ -+static const struct qm_dev_alg sec_dev_algs[] = { { - .alg_msk = SEC_CIPHER_BITMAP, -- .algs = "cipher\n", -+ .alg = "cipher\n", - }, { - .alg_msk = SEC_DIGEST_BITMAP, -- .algs = "digest\n", -+ .alg = "digest\n", - }, { - .alg_msk = SEC_AEAD_BITMAP, -- .algs = "aead\n", -+ .alg = "aead\n", - }, - }; - -@@ -395,8 +396,8 @@ u64 sec_get_alg_bitmap(struct hisi_qm *qm, u32 high, u32 low) - { - u32 cap_val_h, cap_val_l; - -- cap_val_h = hisi_qm_get_hw_info(qm, sec_basic_info, high, qm->cap_ver); -- cap_val_l = hisi_qm_get_hw_info(qm, sec_basic_info, low, qm->cap_ver); -+ cap_val_h = qm->cap_tables.dev_cap_table[high].cap_val; -+ cap_val_l = qm->cap_tables.dev_cap_table[low].cap_val; - - return ((u64)cap_val_h << SEC_ALG_BITMAP_SHIFT) | (u64)cap_val_l; - } -@@ -1079,37 +1080,31 @@ static int sec_pf_probe_init(struct sec_dev *sec) - return ret; - } - --static int sec_set_qm_algs(struct hisi_qm *qm) -+static int sec_pre_store_cap_reg(struct hisi_qm *qm) - { -- struct device *dev = &qm->pdev->dev; -- char *algs, *ptr; -- u64 alg_mask; -- int i; -- -- if (!qm->use_sva) -- return 0; -+ struct hisi_qm_cap_record *sec_cap; -+ struct pci_dev *pdev = qm->pdev; -+ size_t i, size; - -- algs = devm_kzalloc(dev, SEC_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); -- if (!algs) -+ size = ARRAY_SIZE(sec_pre_store_caps); -+ sec_cap = devm_kzalloc(&pdev->dev, sizeof(*sec_cap) * size, GFP_KERNEL); -+ if (!sec_cap) - return -ENOMEM; - -- alg_mask = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH, SEC_DEV_ALG_BITMAP_LOW); -- -- for (i = 0; i < ARRAY_SIZE(sec_dev_algs); i++) -- if (alg_mask & sec_dev_algs[i].alg_msk) -- strcat(algs, sec_dev_algs[i].algs); -- -- ptr = strrchr(algs, '\n'); -- if (ptr) -- *ptr = '\0'; -+ for (i = 0; i < size; i++) { -+ sec_cap[i].type = sec_pre_store_caps[i]; -+ sec_cap[i].cap_val = hisi_qm_get_hw_info(qm, sec_basic_info, -+ sec_pre_store_caps[i], qm->cap_ver); -+ } - -- qm->uacce->algs = algs; -+ qm->cap_tables.dev_cap_table = sec_cap; - - return 0; - } - - static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - { -+ u64 alg_msk; - int ret; - - qm->pdev = pdev; -@@ -1144,7 +1139,16 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - return ret; - } - -- ret = sec_set_qm_algs(qm); -+ /* Fetch and save the value of capability registers */ -+ ret = sec_pre_store_cap_reg(qm); -+ if (ret) { -+ pci_err(qm->pdev, "Failed to pre-store capability registers!\n"); -+ hisi_qm_uninit(qm); -+ return ret; -+ } -+ -+ alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH_IDX, SEC_DEV_ALG_BITMAP_LOW_IDX); -+ ret = hisi_qm_set_algs(qm, alg_msk, sec_dev_algs, ARRAY_SIZE(sec_dev_algs)); - if (ret) { - pci_err(qm->pdev, "Failed to set sec algs!\n"); - hisi_qm_uninit(qm); -diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c -index 190b4fecfc747..9e3f5bca27dee 100644 ---- a/drivers/crypto/hisilicon/zip/zip_main.c -+++ b/drivers/crypto/hisilicon/zip/zip_main.c -@@ -74,7 +74,6 @@ - #define HZIP_AXI_SHUTDOWN_ENABLE BIT(14) - #define HZIP_WR_PORT BIT(11) - --#define HZIP_DEV_ALG_MAX_LEN 256 - #define HZIP_ALG_ZLIB_BIT GENMASK(1, 0) - #define HZIP_ALG_GZIP_BIT GENMASK(3, 2) - #define HZIP_ALG_DEFLATE_BIT GENMASK(5, 4) -@@ -107,6 +106,14 @@ - #define HZIP_CLOCK_GATED_EN (HZIP_CORE_GATED_EN | \ - HZIP_CORE_GATED_OOO_EN) - -+/* zip comp high performance */ -+#define HZIP_HIGH_PERF_OFFSET 0x301208 -+ -+enum { -+ HZIP_HIGH_COMP_RATE, -+ HZIP_HIGH_COMP_PERF, -+}; -+ - static const char hisi_zip_name[] = "hisi_zip"; - static struct dentry *hzip_debugfs_root; - -@@ -120,23 +127,18 @@ struct zip_dfx_item { - u32 offset; - }; - --struct zip_dev_alg { -- u32 alg_msk; -- const char *algs; --}; -- --static const struct zip_dev_alg zip_dev_algs[] = { { -+static const struct qm_dev_alg zip_dev_algs[] = { { - .alg_msk = HZIP_ALG_ZLIB_BIT, -- .algs = "zlib\n", -+ .alg = "zlib\n", - }, { - .alg_msk = HZIP_ALG_GZIP_BIT, -- .algs = "gzip\n", -+ .alg = "gzip\n", - }, { - .alg_msk = HZIP_ALG_DEFLATE_BIT, -- .algs = "deflate\n", -+ .alg = "deflate\n", - }, { - .alg_msk = HZIP_ALG_LZ77_BIT, -- .algs = "lz77_zstd\n", -+ .alg = "lz77_zstd\n", - }, - }; - -@@ -247,6 +249,26 @@ static struct hisi_qm_cap_info zip_basic_cap_info[] = { - {ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0} - }; - -+enum zip_pre_store_cap_idx { -+ ZIP_CORE_NUM_CAP_IDX = 0x0, -+ ZIP_CLUSTER_COMP_NUM_CAP_IDX, -+ ZIP_CLUSTER_DECOMP_NUM_CAP_IDX, -+ ZIP_DECOMP_ENABLE_BITMAP_IDX, -+ ZIP_COMP_ENABLE_BITMAP_IDX, -+ ZIP_DRV_ALG_BITMAP_IDX, -+ ZIP_DEV_ALG_BITMAP_IDX, -+}; -+ -+static const u32 zip_pre_store_caps[] = { -+ ZIP_CORE_NUM_CAP, -+ ZIP_CLUSTER_COMP_NUM_CAP, -+ ZIP_CLUSTER_DECOMP_NUM_CAP, -+ ZIP_DECOMP_ENABLE_BITMAP, -+ ZIP_COMP_ENABLE_BITMAP, -+ ZIP_DRV_ALG_BITMAP, -+ ZIP_DEV_ALG_BITMAP, -+}; -+ - enum { - HZIP_COMP_CORE0, - HZIP_COMP_CORE1, -@@ -352,6 +374,37 @@ static int hzip_diff_regs_show(struct seq_file *s, void *unused) - return 0; - } - DEFINE_SHOW_ATTRIBUTE(hzip_diff_regs); -+ -+static int perf_mode_set(const char *val, const struct kernel_param *kp) -+{ -+ int ret; -+ u32 n; -+ -+ if (!val) -+ return -EINVAL; -+ -+ ret = kstrtou32(val, 10, &n); -+ if (ret != 0 || (n != HZIP_HIGH_COMP_PERF && -+ n != HZIP_HIGH_COMP_RATE)) -+ return -EINVAL; -+ -+ return param_set_int(val, kp); -+} -+ -+static const struct kernel_param_ops zip_com_perf_ops = { -+ .set = perf_mode_set, -+ .get = param_get_int, -+}; -+ -+/* -+ * perf_mode = 0 means enable high compression rate mode, -+ * perf_mode = 1 means enable high compression performance mode. -+ * These two modes only apply to the compression direction. -+ */ -+static u32 perf_mode = HZIP_HIGH_COMP_RATE; -+module_param_cb(perf_mode, &zip_com_perf_ops, &perf_mode, 0444); -+MODULE_PARM_DESC(perf_mode, "ZIP high perf mode 0(default), 1(enable)"); -+ - static const struct kernel_param_ops zip_uacce_mode_ops = { - .set = uacce_mode_set, - .get = param_get_int, -@@ -410,40 +463,33 @@ bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg) - { - u32 cap_val; - -- cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DRV_ALG_BITMAP, qm->cap_ver); -+ cap_val = qm->cap_tables.dev_cap_table[ZIP_DRV_ALG_BITMAP_IDX].cap_val; - if ((alg & cap_val) == alg) - return true; - - return false; - } - --static int hisi_zip_set_qm_algs(struct hisi_qm *qm) -+static int hisi_zip_set_high_perf(struct hisi_qm *qm) - { -- struct device *dev = &qm->pdev->dev; -- char *algs, *ptr; -- u32 alg_mask; -- int i; -- -- if (!qm->use_sva) -- return 0; -- -- algs = devm_kzalloc(dev, HZIP_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); -- if (!algs) -- return -ENOMEM; -- -- alg_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver); -- -- for (i = 0; i < ARRAY_SIZE(zip_dev_algs); i++) -- if (alg_mask & zip_dev_algs[i].alg_msk) -- strcat(algs, zip_dev_algs[i].algs); -- -- ptr = strrchr(algs, '\n'); -- if (ptr) -- *ptr = '\0'; -+ u32 val; -+ int ret; - -- qm->uacce->algs = algs; -+ val = readl_relaxed(qm->io_base + HZIP_HIGH_PERF_OFFSET); -+ if (perf_mode == HZIP_HIGH_COMP_PERF) -+ val |= HZIP_HIGH_COMP_PERF; -+ else -+ val &= ~HZIP_HIGH_COMP_PERF; -+ -+ /* Set perf mode */ -+ writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET); -+ ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_HIGH_PERF_OFFSET, -+ val, val == perf_mode, HZIP_DELAY_1_US, -+ HZIP_POLL_TIMEOUT_US); -+ if (ret) -+ pci_err(qm->pdev, "failed to set perf mode\n"); - -- return 0; -+ return ret; - } - - static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm) -@@ -542,10 +588,8 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm) - } - - /* let's open all compression/decompression cores */ -- dcomp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, -- ZIP_DECOMP_ENABLE_BITMAP, qm->cap_ver); -- comp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, -- ZIP_COMP_ENABLE_BITMAP, qm->cap_ver); -+ dcomp_bm = qm->cap_tables.dev_cap_table[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val; -+ comp_bm = qm->cap_tables.dev_cap_table[ZIP_COMP_ENABLE_BITMAP_IDX].cap_val; - writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL); - - /* enable sqc,cqc writeback */ -@@ -772,9 +816,8 @@ static int hisi_zip_core_debug_init(struct hisi_qm *qm) - char buf[HZIP_BUF_SIZE]; - int i; - -- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); -- zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, -- qm->cap_ver); -+ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; -+ zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; - - for (i = 0; i < zip_core_num; i++) { - if (i < zip_comp_core_num) -@@ -916,7 +959,7 @@ static int hisi_zip_show_last_regs_init(struct hisi_qm *qm) - u32 zip_core_num; - int i, j, idx; - -- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); -+ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; - - debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num, - sizeof(unsigned int), GFP_KERNEL); -@@ -972,9 +1015,9 @@ static void hisi_zip_show_last_dfx_regs(struct hisi_qm *qm) - hzip_com_dfx_regs[i].name, debug->last_words[i], val); - } - -- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); -- zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, -- qm->cap_ver); -+ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; -+ zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; -+ - for (i = 0; i < zip_core_num; i++) { - if (i < zip_comp_core_num) - scnprintf(buf, sizeof(buf), "Comp_core-%d", i); -@@ -1115,6 +1158,10 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) - if (ret) - return ret; - -+ ret = hisi_zip_set_high_perf(qm); -+ if (ret) -+ return ret; -+ - hisi_zip_open_sva_prefetch(qm); - hisi_qm_dev_err_init(qm); - hisi_zip_debug_regs_clear(qm); -@@ -1126,8 +1173,31 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) - return ret; - } - -+static int zip_pre_store_cap_reg(struct hisi_qm *qm) -+{ -+ struct hisi_qm_cap_record *zip_cap; -+ struct pci_dev *pdev = qm->pdev; -+ size_t i, size; -+ -+ size = ARRAY_SIZE(zip_pre_store_caps); -+ zip_cap = devm_kzalloc(&pdev->dev, sizeof(*zip_cap) * size, GFP_KERNEL); -+ if (!zip_cap) -+ return -ENOMEM; -+ -+ for (i = 0; i < size; i++) { -+ zip_cap[i].type = zip_pre_store_caps[i]; -+ zip_cap[i].cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, -+ zip_pre_store_caps[i], qm->cap_ver); -+ } -+ -+ qm->cap_tables.dev_cap_table = zip_cap; -+ -+ return 0; -+} -+ - static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - { -+ u64 alg_msk; - int ret; - - qm->pdev = pdev; -@@ -1163,7 +1233,16 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) - return ret; - } - -- ret = hisi_zip_set_qm_algs(qm); -+ /* Fetch and save the value of capability registers */ -+ ret = zip_pre_store_cap_reg(qm); -+ if (ret) { -+ pci_err(qm->pdev, "Failed to pre-store capability registers!\n"); -+ hisi_qm_uninit(qm); -+ return ret; -+ } -+ -+ alg_msk = qm->cap_tables.dev_cap_table[ZIP_DEV_ALG_BITMAP_IDX].cap_val; -+ ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs)); - if (ret) { - pci_err(qm->pdev, "Failed to set zip algs!\n"); - hisi_qm_uninit(qm); -diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c -index 32a37e3850c58..f59e32115268b 100644 ---- a/drivers/crypto/inside-secure/safexcel_cipher.c -+++ b/drivers/crypto/inside-secure/safexcel_cipher.c -@@ -742,9 +742,9 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, - max(totlen_src, totlen_dst)); - return -EINVAL; - } -- if (sreq->nr_src > 0) -- dma_map_sg(priv->dev, src, sreq->nr_src, -- DMA_BIDIRECTIONAL); -+ if (sreq->nr_src > 0 && -+ !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL)) -+ return -EIO; - } else { - if (unlikely(totlen_src && (sreq->nr_src <= 0))) { - dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", -@@ -752,8 +752,9 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, - return -EINVAL; - } - -- if (sreq->nr_src > 0) -- dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); -+ if (sreq->nr_src > 0 && -+ !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE)) -+ return -EIO; - - if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { - dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", -@@ -762,9 +763,11 @@ static int safexcel_send_req(struct crypto_async_request *base, int ring, - goto unmap; - } - -- if (sreq->nr_dst > 0) -- dma_map_sg(priv->dev, dst, sreq->nr_dst, -- DMA_FROM_DEVICE); -+ if (sreq->nr_dst > 0 && -+ !dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE)) { -+ ret = -EIO; -+ goto unmap; -+ } - } - - memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); -diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c -index f4bc06c24ad8f..e7efebf8127f0 100644 ---- a/drivers/crypto/sa2ul.c -+++ b/drivers/crypto/sa2ul.c -@@ -1868,9 +1868,8 @@ static int sa_aead_setkey(struct crypto_aead *authenc, - crypto_aead_set_flags(ctx->fallback.aead, - crypto_aead_get_flags(authenc) & - CRYPTO_TFM_REQ_MASK); -- crypto_aead_setkey(ctx->fallback.aead, key, keylen); - -- return 0; -+ return crypto_aead_setkey(ctx->fallback.aead, key, keylen); - } - - static int sa_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) -diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c -index 7ab20fb95166e..3b946f1313ed7 100644 ---- a/drivers/crypto/sahara.c -+++ b/drivers/crypto/sahara.c -@@ -44,7 +44,6 @@ - #define FLAGS_MODE_MASK 0x000f - #define FLAGS_ENCRYPT BIT(0) - #define FLAGS_CBC BIT(1) --#define FLAGS_NEW_KEY BIT(3) - - #define SAHARA_HDR_BASE 0x00800000 - #define SAHARA_HDR_SKHA_ALG_AES 0 -@@ -142,8 +141,6 @@ struct sahara_hw_link { - }; - - struct sahara_ctx { -- unsigned long flags; -- - /* AES-specific context */ - int keylen; - u8 key[AES_KEYSIZE_128]; -@@ -152,6 +149,7 @@ struct sahara_ctx { - - struct sahara_aes_reqctx { - unsigned long mode; -+ u8 iv_out[AES_BLOCK_SIZE]; - struct skcipher_request fallback_req; // keep at the end - }; - -@@ -447,27 +445,24 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) - int ret; - int i, j; - int idx = 0; -+ u32 len; - -- /* Copy new key if necessary */ -- if (ctx->flags & FLAGS_NEW_KEY) { -- memcpy(dev->key_base, ctx->key, ctx->keylen); -- ctx->flags &= ~FLAGS_NEW_KEY; -+ memcpy(dev->key_base, ctx->key, ctx->keylen); - -- if (dev->flags & FLAGS_CBC) { -- dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; -- dev->hw_desc[idx]->p1 = dev->iv_phys_base; -- } else { -- dev->hw_desc[idx]->len1 = 0; -- dev->hw_desc[idx]->p1 = 0; -- } -- dev->hw_desc[idx]->len2 = ctx->keylen; -- dev->hw_desc[idx]->p2 = dev->key_phys_base; -- dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; -+ if (dev->flags & FLAGS_CBC) { -+ dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; -+ dev->hw_desc[idx]->p1 = dev->iv_phys_base; -+ } else { -+ dev->hw_desc[idx]->len1 = 0; -+ dev->hw_desc[idx]->p1 = 0; -+ } -+ dev->hw_desc[idx]->len2 = ctx->keylen; -+ dev->hw_desc[idx]->p2 = dev->key_phys_base; -+ dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; -+ dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); - -- dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); -+ idx++; - -- idx++; -- } - - dev->nb_in_sg = sg_nents_for_len(dev->in_sg, dev->total); - if (dev->nb_in_sg < 0) { -@@ -489,24 +484,27 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) - DMA_TO_DEVICE); - if (!ret) { - dev_err(dev->device, "couldn't map in sg\n"); -- goto unmap_in; -+ return -EINVAL; - } -+ - ret = dma_map_sg(dev->device, dev->out_sg, dev->nb_out_sg, - DMA_FROM_DEVICE); - if (!ret) { - dev_err(dev->device, "couldn't map out sg\n"); -- goto unmap_out; -+ goto unmap_in; - } - - /* Create input links */ - dev->hw_desc[idx]->p1 = dev->hw_phys_link[0]; - sg = dev->in_sg; -+ len = dev->total; - for (i = 0; i < dev->nb_in_sg; i++) { -- dev->hw_link[i]->len = sg->length; -+ dev->hw_link[i]->len = min(len, sg->length); - dev->hw_link[i]->p = sg->dma_address; - if (i == (dev->nb_in_sg - 1)) { - dev->hw_link[i]->next = 0; - } else { -+ len -= min(len, sg->length); - dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; - sg = sg_next(sg); - } -@@ -515,12 +513,14 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) - /* Create output links */ - dev->hw_desc[idx]->p2 = dev->hw_phys_link[i]; - sg = dev->out_sg; -+ len = dev->total; - for (j = i; j < dev->nb_out_sg + i; j++) { -- dev->hw_link[j]->len = sg->length; -+ dev->hw_link[j]->len = min(len, sg->length); - dev->hw_link[j]->p = sg->dma_address; - if (j == (dev->nb_out_sg + i - 1)) { - dev->hw_link[j]->next = 0; - } else { -+ len -= min(len, sg->length); - dev->hw_link[j]->next = dev->hw_phys_link[j + 1]; - sg = sg_next(sg); - } -@@ -539,9 +539,6 @@ static int sahara_hw_descriptor_create(struct sahara_dev *dev) - - return 0; - --unmap_out: -- dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, -- DMA_FROM_DEVICE); - unmap_in: - dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, - DMA_TO_DEVICE); -@@ -549,8 +546,24 @@ unmap_in: - return -EINVAL; - } - -+static void sahara_aes_cbc_update_iv(struct skcipher_request *req) -+{ -+ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); -+ struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); -+ unsigned int ivsize = crypto_skcipher_ivsize(skcipher); -+ -+ /* Update IV buffer to contain the last ciphertext block */ -+ if (rctx->mode & FLAGS_ENCRYPT) { -+ sg_pcopy_to_buffer(req->dst, sg_nents(req->dst), req->iv, -+ ivsize, req->cryptlen - ivsize); -+ } else { -+ memcpy(req->iv, rctx->iv_out, ivsize); -+ } -+} -+ - static int sahara_aes_process(struct skcipher_request *req) - { -+ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); - struct sahara_dev *dev = dev_ptr; - struct sahara_ctx *ctx; - struct sahara_aes_reqctx *rctx; -@@ -572,8 +585,17 @@ static int sahara_aes_process(struct skcipher_request *req) - rctx->mode &= FLAGS_MODE_MASK; - dev->flags = (dev->flags & ~FLAGS_MODE_MASK) | rctx->mode; - -- if ((dev->flags & FLAGS_CBC) && req->iv) -- memcpy(dev->iv_base, req->iv, AES_KEYSIZE_128); -+ if ((dev->flags & FLAGS_CBC) && req->iv) { -+ unsigned int ivsize = crypto_skcipher_ivsize(skcipher); -+ -+ memcpy(dev->iv_base, req->iv, ivsize); -+ -+ if (!(dev->flags & FLAGS_ENCRYPT)) { -+ sg_pcopy_to_buffer(req->src, sg_nents(req->src), -+ rctx->iv_out, ivsize, -+ req->cryptlen - ivsize); -+ } -+ } - - /* assign new context to device */ - dev->ctx = ctx; -@@ -586,16 +608,20 @@ static int sahara_aes_process(struct skcipher_request *req) - - timeout = wait_for_completion_timeout(&dev->dma_completion, - msecs_to_jiffies(SAHARA_TIMEOUT_MS)); -- if (!timeout) { -- dev_err(dev->device, "AES timeout\n"); -- return -ETIMEDOUT; -- } - - dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, - DMA_FROM_DEVICE); - dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, - DMA_TO_DEVICE); - -+ if (!timeout) { -+ dev_err(dev->device, "AES timeout\n"); -+ return -ETIMEDOUT; -+ } -+ -+ if ((dev->flags & FLAGS_CBC) && req->iv) -+ sahara_aes_cbc_update_iv(req); -+ - return 0; - } - -@@ -609,7 +635,6 @@ static int sahara_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, - /* SAHARA only supports 128bit keys */ - if (keylen == AES_KEYSIZE_128) { - memcpy(ctx->key, key, keylen); -- ctx->flags |= FLAGS_NEW_KEY; - return 0; - } - -@@ -625,12 +650,40 @@ static int sahara_aes_setkey(struct crypto_skcipher *tfm, const u8 *key, - return crypto_skcipher_setkey(ctx->fallback, key, keylen); - } - -+static int sahara_aes_fallback(struct skcipher_request *req, unsigned long mode) -+{ -+ struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); -+ struct sahara_ctx *ctx = crypto_skcipher_ctx( -+ crypto_skcipher_reqtfm(req)); -+ -+ skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); -+ skcipher_request_set_callback(&rctx->fallback_req, -+ req->base.flags, -+ req->base.complete, -+ req->base.data); -+ skcipher_request_set_crypt(&rctx->fallback_req, req->src, -+ req->dst, req->cryptlen, req->iv); -+ -+ if (mode & FLAGS_ENCRYPT) -+ return crypto_skcipher_encrypt(&rctx->fallback_req); -+ -+ return crypto_skcipher_decrypt(&rctx->fallback_req); -+} -+ - static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) - { - struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); -+ struct sahara_ctx *ctx = crypto_skcipher_ctx( -+ crypto_skcipher_reqtfm(req)); - struct sahara_dev *dev = dev_ptr; - int err = 0; - -+ if (!req->cryptlen) -+ return 0; -+ -+ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) -+ return sahara_aes_fallback(req, mode); -+ - dev_dbg(dev->device, "nbytes: %d, enc: %d, cbc: %d\n", - req->cryptlen, !!(mode & FLAGS_ENCRYPT), !!(mode & FLAGS_CBC)); - -@@ -653,81 +706,21 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) - - static int sahara_aes_ecb_encrypt(struct skcipher_request *req) - { -- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); -- struct sahara_ctx *ctx = crypto_skcipher_ctx( -- crypto_skcipher_reqtfm(req)); -- -- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { -- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); -- skcipher_request_set_callback(&rctx->fallback_req, -- req->base.flags, -- req->base.complete, -- req->base.data); -- skcipher_request_set_crypt(&rctx->fallback_req, req->src, -- req->dst, req->cryptlen, req->iv); -- return crypto_skcipher_encrypt(&rctx->fallback_req); -- } -- - return sahara_aes_crypt(req, FLAGS_ENCRYPT); - } - - static int sahara_aes_ecb_decrypt(struct skcipher_request *req) - { -- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); -- struct sahara_ctx *ctx = crypto_skcipher_ctx( -- crypto_skcipher_reqtfm(req)); -- -- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { -- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); -- skcipher_request_set_callback(&rctx->fallback_req, -- req->base.flags, -- req->base.complete, -- req->base.data); -- skcipher_request_set_crypt(&rctx->fallback_req, req->src, -- req->dst, req->cryptlen, req->iv); -- return crypto_skcipher_decrypt(&rctx->fallback_req); -- } -- - return sahara_aes_crypt(req, 0); - } - - static int sahara_aes_cbc_encrypt(struct skcipher_request *req) - { -- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); -- struct sahara_ctx *ctx = crypto_skcipher_ctx( -- crypto_skcipher_reqtfm(req)); -- -- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { -- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); -- skcipher_request_set_callback(&rctx->fallback_req, -- req->base.flags, -- req->base.complete, -- req->base.data); -- skcipher_request_set_crypt(&rctx->fallback_req, req->src, -- req->dst, req->cryptlen, req->iv); -- return crypto_skcipher_encrypt(&rctx->fallback_req); -- } -- - return sahara_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); - } - - static int sahara_aes_cbc_decrypt(struct skcipher_request *req) - { -- struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); -- struct sahara_ctx *ctx = crypto_skcipher_ctx( -- crypto_skcipher_reqtfm(req)); -- -- if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { -- skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); -- skcipher_request_set_callback(&rctx->fallback_req, -- req->base.flags, -- req->base.complete, -- req->base.data); -- skcipher_request_set_crypt(&rctx->fallback_req, req->src, -- req->dst, req->cryptlen, req->iv); -- return crypto_skcipher_decrypt(&rctx->fallback_req); -- } -- - return sahara_aes_crypt(req, FLAGS_CBC); - } - -@@ -784,6 +777,7 @@ static int sahara_sha_hw_links_create(struct sahara_dev *dev, - int start) - { - struct scatterlist *sg; -+ unsigned int len; - unsigned int i; - int ret; - -@@ -805,12 +799,14 @@ static int sahara_sha_hw_links_create(struct sahara_dev *dev, - if (!ret) - return -EFAULT; - -+ len = rctx->total; - for (i = start; i < dev->nb_in_sg + start; i++) { -- dev->hw_link[i]->len = sg->length; -+ dev->hw_link[i]->len = min(len, sg->length); - dev->hw_link[i]->p = sg->dma_address; - if (i == (dev->nb_in_sg + start - 1)) { - dev->hw_link[i]->next = 0; - } else { -+ len -= min(len, sg->length); - dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; - sg = sg_next(sg); - } -@@ -891,24 +887,6 @@ static int sahara_sha_hw_context_descriptor_create(struct sahara_dev *dev, - return 0; - } - --static int sahara_walk_and_recalc(struct scatterlist *sg, unsigned int nbytes) --{ -- if (!sg || !sg->length) -- return nbytes; -- -- while (nbytes && sg) { -- if (nbytes <= sg->length) { -- sg->length = nbytes; -- sg_mark_end(sg); -- break; -- } -- nbytes -= sg->length; -- sg = sg_next(sg); -- } -- -- return nbytes; --} -- - static int sahara_sha_prepare_request(struct ahash_request *req) - { - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); -@@ -945,36 +923,20 @@ static int sahara_sha_prepare_request(struct ahash_request *req) - hash_later, 0); - } - -- /* nbytes should now be multiple of blocksize */ -- req->nbytes = req->nbytes - hash_later; -- -- sahara_walk_and_recalc(req->src, req->nbytes); -- -+ rctx->total = len - hash_later; - /* have data from previous operation and current */ - if (rctx->buf_cnt && req->nbytes) { - sg_init_table(rctx->in_sg_chain, 2); - sg_set_buf(rctx->in_sg_chain, rctx->rembuf, rctx->buf_cnt); -- - sg_chain(rctx->in_sg_chain, 2, req->src); -- -- rctx->total = req->nbytes + rctx->buf_cnt; - rctx->in_sg = rctx->in_sg_chain; -- -- req->src = rctx->in_sg_chain; - /* only data from previous operation */ - } else if (rctx->buf_cnt) { -- if (req->src) -- rctx->in_sg = req->src; -- else -- rctx->in_sg = rctx->in_sg_chain; -- /* buf was copied into rembuf above */ -+ rctx->in_sg = rctx->in_sg_chain; - sg_init_one(rctx->in_sg, rctx->rembuf, rctx->buf_cnt); -- rctx->total = rctx->buf_cnt; - /* no data from previous operation */ - } else { - rctx->in_sg = req->src; -- rctx->total = req->nbytes; -- req->src = rctx->in_sg; - } - - /* on next call, we only have the remaining data in the buffer */ -@@ -995,7 +957,10 @@ static int sahara_sha_process(struct ahash_request *req) - return ret; - - if (rctx->first) { -- sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); -+ ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); -+ if (ret) -+ return ret; -+ - dev->hw_desc[0]->next = 0; - rctx->first = 0; - } else { -@@ -1003,7 +968,10 @@ static int sahara_sha_process(struct ahash_request *req) - - sahara_sha_hw_context_descriptor_create(dev, rctx, req, 0); - dev->hw_desc[0]->next = dev->hw_phys_desc[1]; -- sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); -+ ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); -+ if (ret) -+ return ret; -+ - dev->hw_desc[1]->next = 0; - } - -@@ -1016,18 +984,19 @@ static int sahara_sha_process(struct ahash_request *req) - - timeout = wait_for_completion_timeout(&dev->dma_completion, - msecs_to_jiffies(SAHARA_TIMEOUT_MS)); -- if (!timeout) { -- dev_err(dev->device, "SHA timeout\n"); -- return -ETIMEDOUT; -- } - - if (rctx->sg_in_idx) - dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, - DMA_TO_DEVICE); - -+ if (!timeout) { -+ dev_err(dev->device, "SHA timeout\n"); -+ return -ETIMEDOUT; -+ } -+ - memcpy(rctx->context, dev->context_base, rctx->context_size); - -- if (req->result) -+ if (req->result && rctx->last) - memcpy(req->result, rctx->context, rctx->digest_size); - - return 0; -@@ -1171,8 +1140,7 @@ static int sahara_sha_import(struct ahash_request *req, const void *in) - static int sahara_sha_cra_init(struct crypto_tfm *tfm) - { - crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), -- sizeof(struct sahara_sha_reqctx) + -- SHA_BUFFER_LEN + SHA256_BLOCK_SIZE); -+ sizeof(struct sahara_sha_reqctx)); - - return 0; - } -diff --git a/drivers/crypto/virtio/virtio_crypto_common.h b/drivers/crypto/virtio/virtio_crypto_common.h -index 154590e1f7643..7059bbe5a2eba 100644 ---- a/drivers/crypto/virtio/virtio_crypto_common.h -+++ b/drivers/crypto/virtio/virtio_crypto_common.h -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -28,6 +29,7 @@ struct data_queue { - char name[32]; - - struct crypto_engine *engine; -+ struct tasklet_struct done_task; - }; - - struct virtio_crypto { -diff --git a/drivers/crypto/virtio/virtio_crypto_core.c b/drivers/crypto/virtio/virtio_crypto_core.c -index 3842915ea7437..56dc0935c774a 100644 ---- a/drivers/crypto/virtio/virtio_crypto_core.c -+++ b/drivers/crypto/virtio/virtio_crypto_core.c -@@ -72,27 +72,28 @@ int virtio_crypto_ctrl_vq_request(struct virtio_crypto *vcrypto, struct scatterl - return 0; - } - --static void virtcrypto_dataq_callback(struct virtqueue *vq) -+static void virtcrypto_done_task(unsigned long data) - { -- struct virtio_crypto *vcrypto = vq->vdev->priv; -+ struct data_queue *data_vq = (struct data_queue *)data; -+ struct virtqueue *vq = data_vq->vq; - struct virtio_crypto_request *vc_req; -- unsigned long flags; - unsigned int len; -- unsigned int qid = vq->index; - -- spin_lock_irqsave(&vcrypto->data_vq[qid].lock, flags); - do { - virtqueue_disable_cb(vq); - while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) { -- spin_unlock_irqrestore( -- &vcrypto->data_vq[qid].lock, flags); - if (vc_req->alg_cb) - vc_req->alg_cb(vc_req, len); -- spin_lock_irqsave( -- &vcrypto->data_vq[qid].lock, flags); - } - } while (!virtqueue_enable_cb(vq)); -- spin_unlock_irqrestore(&vcrypto->data_vq[qid].lock, flags); -+} -+ -+static void virtcrypto_dataq_callback(struct virtqueue *vq) -+{ -+ struct virtio_crypto *vcrypto = vq->vdev->priv; -+ struct data_queue *dq = &vcrypto->data_vq[vq->index]; -+ -+ tasklet_schedule(&dq->done_task); - } - - static int virtcrypto_find_vqs(struct virtio_crypto *vi) -@@ -150,6 +151,8 @@ static int virtcrypto_find_vqs(struct virtio_crypto *vi) - ret = -ENOMEM; - goto err_engine; - } -+ tasklet_init(&vi->data_vq[i].done_task, virtcrypto_done_task, -+ (unsigned long)&vi->data_vq[i]); - } - - kfree(names); -@@ -496,12 +499,15 @@ static void virtcrypto_free_unused_reqs(struct virtio_crypto *vcrypto) - static void virtcrypto_remove(struct virtio_device *vdev) - { - struct virtio_crypto *vcrypto = vdev->priv; -+ int i; - - dev_info(&vdev->dev, "Start virtcrypto_remove.\n"); - - flush_work(&vcrypto->config_work); - if (virtcrypto_dev_started(vcrypto)) - virtcrypto_dev_stop(vcrypto); -+ for (i = 0; i < vcrypto->max_data_queues; i++) -+ tasklet_kill(&vcrypto->data_vq[i].done_task); - virtio_reset_device(vdev); - virtcrypto_free_unused_reqs(vcrypto); - virtcrypto_clear_crypto_engines(vcrypto); -diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c -index bd41424319807..1f1483a9e5252 100644 ---- a/drivers/cxl/core/port.c -+++ b/drivers/cxl/core/port.c -@@ -1403,7 +1403,7 @@ static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd, - return -EINVAL; - - write_seqlock(&cxlsd->target_lock); -- for (i = 0; i < cxlsd->nr_targets; i++) { -+ for (i = 0; i < cxlsd->cxld.interleave_ways; i++) { - struct cxl_dport *dport = find_dport(port, target_map[i]); - - if (!dport) { -diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c -index ebc1b028555ca..2f7187dbfa2d9 100644 ---- a/drivers/cxl/core/region.c -+++ b/drivers/cxl/core/region.c -@@ -331,7 +331,7 @@ static ssize_t interleave_ways_store(struct device *dev, - return rc; - - /* -- * Even for x3, x9, and x12 interleaves the region interleave must be a -+ * Even for x3, x6, and x12 interleaves the region interleave must be a - * power of 2 multiple of the host bridge interleave. - */ - if (!is_power_of_2(val / cxld->interleave_ways) || -diff --git a/drivers/edac/thunderx_edac.c b/drivers/edac/thunderx_edac.c -index f13674081cb6b..4dca21b39bf73 100644 ---- a/drivers/edac/thunderx_edac.c -+++ b/drivers/edac/thunderx_edac.c -@@ -1133,7 +1133,7 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) - decode_register(other, OCX_OTHER_SIZE, - ocx_com_errors, ctx->reg_com_int); - -- strncat(msg, other, OCX_MESSAGE_SIZE); -+ strlcat(msg, other, OCX_MESSAGE_SIZE); - - for (lane = 0; lane < OCX_RX_LANES; lane++) - if (ctx->reg_com_int & BIT(lane)) { -@@ -1142,12 +1142,12 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) - lane, ctx->reg_lane_int[lane], - lane, ctx->reg_lane_stat11[lane]); - -- strncat(msg, other, OCX_MESSAGE_SIZE); -+ strlcat(msg, other, OCX_MESSAGE_SIZE); - - decode_register(other, OCX_OTHER_SIZE, - ocx_lane_errors, - ctx->reg_lane_int[lane]); -- strncat(msg, other, OCX_MESSAGE_SIZE); -+ strlcat(msg, other, OCX_MESSAGE_SIZE); - } - - if (ctx->reg_com_int & OCX_COM_INT_CE) -@@ -1217,7 +1217,7 @@ static irqreturn_t thunderx_ocx_lnk_threaded_isr(int irq, void *irq_id) - decode_register(other, OCX_OTHER_SIZE, - ocx_com_link_errors, ctx->reg_com_link_int); - -- strncat(msg, other, OCX_MESSAGE_SIZE); -+ strlcat(msg, other, OCX_MESSAGE_SIZE); - - if (ctx->reg_com_link_int & OCX_COM_LINK_INT_UE) - edac_device_handle_ue(ocx->edac_dev, 0, 0, msg); -@@ -1896,7 +1896,7 @@ static irqreturn_t thunderx_l2c_threaded_isr(int irq, void *irq_id) - - decode_register(other, L2C_OTHER_SIZE, l2_errors, ctx->reg_int); - -- strncat(msg, other, L2C_MESSAGE_SIZE); -+ strlcat(msg, other, L2C_MESSAGE_SIZE); - - if (ctx->reg_int & mask_ue) - edac_device_handle_ue(l2c->edac_dev, 0, 0, msg); -diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c -index d081a6312627b..bf19dd66c2137 100644 ---- a/drivers/firmware/meson/meson_sm.c -+++ b/drivers/firmware/meson/meson_sm.c -@@ -313,11 +313,14 @@ static int __init meson_sm_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, fw); - -- pr_info("secure-monitor enabled\n"); -+ if (devm_of_platform_populate(dev)) -+ goto out_in_base; - - if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group)) - goto out_in_base; - -+ pr_info("secure-monitor enabled\n"); -+ - return 0; - - out_in_base: -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 597d1a367d96d..6231c98ba291a 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -161,7 +161,7 @@ static int ti_sci_debugfs_create(struct platform_device *pdev, - { - struct device *dev = &pdev->dev; - struct resource *res; -- char debug_name[50] = "ti_sci_debug@"; -+ char debug_name[50]; - - /* Debug region is optional */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -@@ -178,10 +178,10 @@ static int ti_sci_debugfs_create(struct platform_device *pdev, - /* Setup NULL termination */ - info->debug_buffer[info->debug_region_size] = 0; - -- info->d = debugfs_create_file(strncat(debug_name, dev_name(dev), -- sizeof(debug_name) - -- sizeof("ti_sci_debug@")), -- 0444, NULL, info, &ti_sci_debug_fops); -+ snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s", -+ dev_name(dev)); -+ info->d = debugfs_create_file(debug_name, 0444, NULL, info, -+ &ti_sci_debug_fops); - if (IS_ERR(info->d)) - return PTR_ERR(info->d); - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -index 8123feb1a1161..06ab6066da61a 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c -@@ -596,7 +596,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, - int r; - - if (!adev->smc_rreg) -- return -EPERM; -+ return -EOPNOTSUPP; - - if (size & 0x3 || *pos & 0x3) - return -EINVAL; -@@ -655,7 +655,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * - int r; - - if (!adev->smc_wreg) -- return -EPERM; -+ return -EOPNOTSUPP; - - if (size & 0x3 || *pos & 0x3) - return -EINVAL; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -index b9983ca99eb7d..a8e1f2cfe12dc 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -@@ -2202,6 +2202,8 @@ retry_init: - - pci_wake_from_d3(pdev, TRUE); - -+ pci_wake_from_d3(pdev, TRUE); -+ - /* - * For runpm implemented via BACO, PMFW will handle the - * timing for BACO in and out: -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c -index 88bf6221d4bef..8a7705db0b9a6 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c -@@ -1019,7 +1019,7 @@ int svm_migrate_init(struct amdgpu_device *adev) - } else { - res = devm_request_free_mem_region(adev->dev, &iomem_resource, size); - if (IS_ERR(res)) -- return -ENOMEM; -+ return PTR_ERR(res); - pgmap->range.start = res->start; - pgmap->range.end = res->end; - pgmap->type = MEMORY_DEVICE_PRIVATE; -@@ -1035,11 +1035,10 @@ int svm_migrate_init(struct amdgpu_device *adev) - r = devm_memremap_pages(adev->dev, pgmap); - if (IS_ERR(r)) { - pr_err("failed to register HMM device memory\n"); -+ if (pgmap->type == MEMORY_DEVICE_PRIVATE) -+ devm_release_mem_region(adev->dev, res->start, resource_size(res)); - /* Disable SVM support capability */ - pgmap->type = 0; -- if (pgmap->type == MEMORY_DEVICE_PRIVATE) -- devm_release_mem_region(adev->dev, res->start, -- res->end - res->start + 1); - return PTR_ERR(r); - } - -diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c -index 713f893d25302..705d9e91b5aa3 100644 ---- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c -+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c -@@ -1403,10 +1403,11 @@ static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int g - num_cpu++; - } - -+ if (list_empty(&kdev->io_link_props)) -+ return -ENODATA; -+ - gpu_link = list_first_entry(&kdev->io_link_props, -- struct kfd_iolink_properties, list); -- if (!gpu_link) -- return -ENOMEM; -+ struct kfd_iolink_properties, list); - - for (i = 0; i < num_cpu; i++) { - /* CPU <--> GPU */ -@@ -1484,15 +1485,17 @@ static int kfd_add_peer_prop(struct kfd_topology_device *kdev, - peer->gpu->adev)) - return ret; - -+ if (list_empty(&kdev->io_link_props)) -+ return -ENODATA; -+ - iolink1 = list_first_entry(&kdev->io_link_props, -- struct kfd_iolink_properties, list); -- if (!iolink1) -- return -ENOMEM; -+ struct kfd_iolink_properties, list); -+ -+ if (list_empty(&peer->io_link_props)) -+ return -ENODATA; - - iolink2 = list_first_entry(&peer->io_link_props, -- struct kfd_iolink_properties, list); -- if (!iolink2) -- return -ENOMEM; -+ struct kfd_iolink_properties, list); - - props = kfd_alloc_struct(props); - if (!props) -diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c -index f5e08b60f66ef..d17bfa111aa74 100644 ---- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c -+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c -@@ -2748,10 +2748,8 @@ static int kv_parse_power_table(struct amdgpu_device *adev) - non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) - &non_clock_info_array->nonClockInfo[non_clock_array_index]; - ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); -- if (ps == NULL) { -- kfree(adev->pm.dpm.ps); -+ if (ps == NULL) - return -ENOMEM; -- } - adev->pm.dpm.ps[i].ps_priv = ps; - k = 0; - idx = (u8 *)&power_state->v2.clockInfoIndex[0]; -diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c -index d3fe149d84765..291223ea7ba7d 100644 ---- a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c -+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c -@@ -272,10 +272,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset)); - ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk, - dep_table); -- if (ret) { -- amdgpu_free_extended_power_table(adev); -+ if (ret) - return ret; -- } - } - if (power_info->pplib4.usVddciDependencyOnMCLKOffset) { - dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) -@@ -283,10 +281,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset)); - ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk, - dep_table); -- if (ret) { -- amdgpu_free_extended_power_table(adev); -+ if (ret) - return ret; -- } - } - if (power_info->pplib4.usVddcDependencyOnMCLKOffset) { - dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) -@@ -294,10 +290,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset)); - ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk, - dep_table); -- if (ret) { -- amdgpu_free_extended_power_table(adev); -+ if (ret) - return ret; -- } - } - if (power_info->pplib4.usMvddDependencyOnMCLKOffset) { - dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) -@@ -305,10 +299,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset)); - ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk, - dep_table); -- if (ret) { -- amdgpu_free_extended_power_table(adev); -+ if (ret) - return ret; -- } - } - if (power_info->pplib4.usMaxClockVoltageOnDCOffset) { - ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v = -@@ -339,10 +331,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - kcalloc(psl->ucNumEntries, - sizeof(struct amdgpu_phase_shedding_limits_entry), - GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) - return -ENOMEM; -- } - - entry = &psl->entries[0]; - for (i = 0; i < psl->ucNumEntries; i++) { -@@ -383,10 +373,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - ATOM_PPLIB_CAC_Leakage_Record *entry; - u32 size = cac_table->ucNumEntries * sizeof(struct amdgpu_cac_leakage_table); - adev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) - return -ENOMEM; -- } - entry = &cac_table->entries[0]; - for (i = 0; i < cac_table->ucNumEntries; i++) { - if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) { -@@ -438,10 +426,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - sizeof(struct amdgpu_vce_clock_voltage_dependency_entry); - adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries = - kzalloc(size, GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) - return -ENOMEM; -- } - adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count = - limits->numEntries; - entry = &limits->entries[0]; -@@ -493,10 +479,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - sizeof(struct amdgpu_uvd_clock_voltage_dependency_entry); - adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries = - kzalloc(size, GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) - return -ENOMEM; -- } - adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count = - limits->numEntries; - entry = &limits->entries[0]; -@@ -525,10 +509,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - sizeof(struct amdgpu_clock_voltage_dependency_entry); - adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries = - kzalloc(size, GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) - return -ENOMEM; -- } - adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count = - limits->numEntries; - entry = &limits->entries[0]; -@@ -548,10 +530,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - le16_to_cpu(ext_hdr->usPPMTableOffset)); - adev->pm.dpm.dyn_state.ppm_table = - kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.ppm_table) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.ppm_table) - return -ENOMEM; -- } - adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign; - adev->pm.dpm.dyn_state.ppm_table->cpu_core_number = - le16_to_cpu(ppm->usCpuCoreNumber); -@@ -583,10 +563,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - sizeof(struct amdgpu_clock_voltage_dependency_entry); - adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries = - kzalloc(size, GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) - return -ENOMEM; -- } - adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count = - limits->numEntries; - entry = &limits->entries[0]; -@@ -606,10 +584,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - ATOM_PowerTune_Table *pt; - adev->pm.dpm.dyn_state.cac_tdp_table = - kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.cac_tdp_table) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.cac_tdp_table) - return -ENOMEM; -- } - if (rev > 0) { - ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *) - (mode_info->atom_context->bios + data_offset + -@@ -645,10 +621,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) - ret = amdgpu_parse_clk_voltage_dep_table( - &adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk, - dep_table); -- if (ret) { -- kfree(adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk.entries); -+ if (ret) - return ret; -- } - } - } - -diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c -index c89cfef7cafa1..dc0a6fba7050f 100644 ---- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c -+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c -@@ -7379,10 +7379,9 @@ static int si_dpm_init(struct amdgpu_device *adev) - kcalloc(4, - sizeof(struct amdgpu_clock_voltage_dependency_entry), - GFP_KERNEL); -- if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { -- amdgpu_free_extended_power_table(adev); -+ if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) - return -ENOMEM; -- } -+ - adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4; - adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0; - adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0; -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -index a31a62a1ce0b2..5e9410117712c 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -@@ -2987,6 +2987,8 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) - result = smu7_get_evv_voltages(hwmgr); - if (result) { - pr_info("Get EVV Voltage Failed. Abort Driver loading!\n"); -+ kfree(hwmgr->backend); -+ hwmgr->backend = NULL; - return -EINVAL; - } - } else { -@@ -3032,8 +3034,10 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) - } - - result = smu7_update_edc_leakage_table(hwmgr); -- if (result) -+ if (result) { -+ smu7_hwmgr_backend_fini(hwmgr); - return result; -+ } - - return 0; - } -diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c -index 946212a955981..5e3b8edcf7948 100644 ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c -@@ -403,7 +403,8 @@ static int _cdns_mhdp_hdcp_disable(struct cdns_mhdp_device *mhdp) - - static int _cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type) - { -- int ret, tries = 3; -+ int ret = -EINVAL; -+ int tries = 3; - u32 i; - - for (i = 0; i < tries; i++) { -diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c -index 7ef78283e3d3e..926ab5c3c31ab 100644 ---- a/drivers/gpu/drm/bridge/tc358767.c -+++ b/drivers/gpu/drm/bridge/tc358767.c -@@ -2097,7 +2097,7 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) - } else { - if (tc->hpd_pin < 0 || tc->hpd_pin > 1) { - dev_err(dev, "failed to parse HPD number\n"); -- return ret; -+ return -EINVAL; - } - } - -diff --git a/drivers/gpu/drm/bridge/ti-tpd12s015.c b/drivers/gpu/drm/bridge/ti-tpd12s015.c -index e0e015243a602..b588fea12502d 100644 ---- a/drivers/gpu/drm/bridge/ti-tpd12s015.c -+++ b/drivers/gpu/drm/bridge/ti-tpd12s015.c -@@ -179,7 +179,7 @@ static int tpd12s015_probe(struct platform_device *pdev) - return 0; - } - --static int __exit tpd12s015_remove(struct platform_device *pdev) -+static int tpd12s015_remove(struct platform_device *pdev) - { - struct tpd12s015_device *tpd = platform_get_drvdata(pdev); - -@@ -197,7 +197,7 @@ MODULE_DEVICE_TABLE(of, tpd12s015_of_match); - - static struct platform_driver tpd12s015_driver = { - .probe = tpd12s015_probe, -- .remove = __exit_p(tpd12s015_remove), -+ .remove = tpd12s015_remove, - .driver = { - .name = "tpd12s015", - .of_match_table = tpd12s015_of_match, -diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c -index 203bf8d6c34c4..d41a5eaa3e892 100644 ---- a/drivers/gpu/drm/drm_drv.c -+++ b/drivers/gpu/drm/drm_drv.c -@@ -895,8 +895,11 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) - goto err_minors; - } - -- if (drm_core_check_feature(dev, DRIVER_MODESET)) -- drm_modeset_register_all(dev); -+ if (drm_core_check_feature(dev, DRIVER_MODESET)) { -+ ret = drm_modeset_register_all(dev); -+ if (ret) -+ goto err_unload; -+ } - - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", - driver->name, driver->major, driver->minor, -@@ -906,6 +909,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) - - goto out_unlock; - -+err_unload: -+ if (dev->driver->unload) -+ dev->driver->unload(dev); - err_minors: - remove_compat_control_link(dev); - drm_minor_unregister(dev, DRM_MINOR_PRIMARY); -diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c -index 6428b6203ffe8..211140e87568d 100644 ---- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c -+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c -@@ -104,7 +104,7 @@ void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt) - mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, - DISP_REG_MERGE_CTRL); - -- if (priv->async_clk) -+ if (!cmdq_pkt && priv->async_clk) - reset_control_reset(priv->reset_ctl); - } - -diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c -index 2c850b6d945bc..519e23a2a017c 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dp.c -+++ b/drivers/gpu/drm/mediatek/mtk_dp.c -@@ -2669,3 +2669,4 @@ MODULE_AUTHOR("Markus Schneider-Pargmann "); - MODULE_AUTHOR("Bo-Chen Chen "); - MODULE_DESCRIPTION("MediaTek DisplayPort Driver"); - MODULE_LICENSE("GPL"); -+MODULE_SOFTDEP("pre: phy_mtk_dp"); -diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c -index eecfa98ff52e8..b288bb6eeecc7 100644 ---- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c -+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c -@@ -223,8 +223,7 @@ int mtk_mdp_rdma_clk_enable(struct device *dev) - { - struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev); - -- clk_prepare_enable(rdma->clk); -- return 0; -+ return clk_prepare_enable(rdma->clk); - } - - void mtk_mdp_rdma_clk_disable(struct device *dev) -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c -index 6c0ffe8e4adbd..5a5821e59dc15 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0-only - /* -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. - * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. - * Copyright (C) 2013 Red Hat - * Author: Rob Clark -@@ -124,7 +124,7 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) - continue; - - /* Calculate MISR over 1 frame */ -- m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); -+ m->hw_lm->ops.setup_misr(m->hw_lm); - } - } - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -index 547f9f2b9fcb5..b0eb881f8af13 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c -@@ -2,7 +2,7 @@ - /* - * Copyright (C) 2013 Red Hat - * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. - * - * Author: Rob Clark - */ -@@ -257,7 +257,7 @@ void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc) - if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr) - continue; - -- phys->hw_intf->ops.setup_misr(phys->hw_intf, true, 1); -+ phys->hw_intf->ops.setup_misr(phys->hw_intf); - } - } - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c -index b9dddf576c029..384558d2f9602 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0-only - /* -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - */ - -@@ -322,9 +322,9 @@ static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf) - return DPU_REG_READ(c, INTF_LINE_COUNT); - } - --static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, u32 frame_count) -+static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf) - { -- dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, enable, frame_count); -+ dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, 0x1); - } - - static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h -index 643dd10bc0306..e75339b96a1d2 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h -@@ -1,6 +1,6 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ - /* -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - */ - -@@ -80,7 +80,7 @@ struct dpu_hw_intf_ops { - void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, - bool enable, - const enum dpu_pingpong pp); -- void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); -+ void (*setup_misr)(struct dpu_hw_intf *intf); - int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); - }; - -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c -index f5120ea91edee..cc04fb979fb5c 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0-only - /* -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. - * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - */ - -@@ -99,9 +99,9 @@ static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx, - } - } - --static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count) -+static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx) - { -- dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, enable, frame_count); -+ dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0); - } - - static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h -index 652ddfdedec37..0a050eb247b99 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h -@@ -1,5 +1,6 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ - /* -+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. - * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - */ - -@@ -57,7 +58,7 @@ struct dpu_hw_lm_ops { - /** - * setup_misr: Enable/disable MISR - */ -- void (*setup_misr)(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count); -+ void (*setup_misr)(struct dpu_hw_mixer *ctx); - - /** - * collect_misr: Read MISR signature -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c -index 8062228eada68..1b7439ae686a7 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0-only - /* -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. - * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - */ - #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ -@@ -450,9 +450,11 @@ u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, - return 0; - } - -+/* -+ * note: Aside from encoders, input_sel should be set to 0x0 by default -+ */ - void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, -- u32 misr_ctrl_offset, -- bool enable, u32 frame_count) -+ u32 misr_ctrl_offset, u8 input_sel) - { - u32 config = 0; - -@@ -461,15 +463,9 @@ void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, - /* Clear old MISR value (in case it's read before a new value is calculated)*/ - wmb(); - -- if (enable) { -- config = (frame_count & MISR_FRAME_COUNT_MASK) | -- MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; -- -- DPU_REG_WRITE(c, misr_ctrl_offset, config); -- } else { -- DPU_REG_WRITE(c, misr_ctrl_offset, 0); -- } -- -+ config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK | -+ ((input_sel & 0xF) << 24); -+ DPU_REG_WRITE(c, misr_ctrl_offset, config); - } - - int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, -diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h -index 27f4c39e35ab3..4ae2a434372cf 100644 ---- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h -+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h -@@ -1,6 +1,6 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ - /* -- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. - * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - */ - -@@ -13,7 +13,7 @@ - #include "dpu_hw_catalog.h" - - #define REG_MASK(n) ((BIT(n)) - 1) --#define MISR_FRAME_COUNT_MASK 0xFF -+#define MISR_FRAME_COUNT 0x1 - #define MISR_CTRL_ENABLE BIT(8) - #define MISR_CTRL_STATUS BIT(9) - #define MISR_CTRL_STATUS_CLEAR BIT(10) -@@ -350,9 +350,7 @@ u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, - u32 total_fl); - - void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, -- u32 misr_ctrl_offset, -- bool enable, -- u32 frame_count); -+ u32 misr_ctrl_offset, u8 input_sel); - - int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, - u32 misr_ctrl_offset, -diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c -index 169f9de4a12a7..3100957225a70 100644 ---- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c -+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c -@@ -269,6 +269,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, - { - struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - struct mdp4_kms *mdp4_kms = get_kms(crtc); -+ unsigned long flags; - - DBG("%s", mdp4_crtc->name); - -@@ -281,6 +282,14 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, - mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); - mdp4_disable(mdp4_kms); - -+ if (crtc->state->event && !crtc->state->active) { -+ WARN_ON(mdp4_crtc->event); -+ spin_lock_irqsave(&mdp4_kms->dev->event_lock, flags); -+ drm_crtc_send_vblank_event(crtc, crtc->state->event); -+ crtc->state->event = NULL; -+ spin_unlock_irqrestore(&mdp4_kms->dev->event_lock, flags); -+ } -+ - mdp4_crtc->enabled = false; - } - -diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c -index 7fc0975cb8693..62bc3756f2e2b 100644 ---- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c -+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c -@@ -512,7 +512,9 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy) - struct device *dev = &phy->pdev->dev; - int ret; - -- pm_runtime_get_sync(dev); -+ ret = pm_runtime_resume_and_get(dev); -+ if (ret) -+ return ret; - - ret = clk_prepare_enable(phy->ahb_clk); - if (ret) { -diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c -index 5b71a5a5cd85c..cdbc75e3d1f66 100644 ---- a/drivers/gpu/drm/nouveau/nv04_fence.c -+++ b/drivers/gpu/drm/nouveau/nv04_fence.c -@@ -39,7 +39,7 @@ struct nv04_fence_priv { - static int - nv04_fence_emit(struct nouveau_fence *fence) - { -- struct nvif_push *push = fence->channel->chan.push; -+ struct nvif_push *push = unrcu_pointer(fence->channel)->chan.push; - int ret = PUSH_WAIT(push, 2); - if (ret == 0) { - PUSH_NVSQ(push, NV_SW, 0x0150, fence->base.seqno); -diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c -index eaf67b9e5f12b..5b6d1668f405c 100644 ---- a/drivers/gpu/drm/omapdrm/omap_drv.c -+++ b/drivers/gpu/drm/omapdrm/omap_drv.c -@@ -68,7 +68,6 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) - { - struct drm_device *dev = old_state->dev; - struct omap_drm_private *priv = dev->dev_private; -- bool fence_cookie = dma_fence_begin_signalling(); - - dispc_runtime_get(priv->dispc); - -@@ -91,6 +90,8 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) - omap_atomic_wait_for_completion(dev, old_state); - - drm_atomic_helper_commit_planes(dev, old_state, 0); -+ -+ drm_atomic_helper_commit_hw_done(old_state); - } else { - /* - * OMAP3 DSS seems to have issues with the work-around above, -@@ -100,11 +101,9 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) - drm_atomic_helper_commit_planes(dev, old_state, 0); - - drm_atomic_helper_commit_modeset_enables(dev, old_state); -- } - -- drm_atomic_helper_commit_hw_done(old_state); -- -- dma_fence_end_signalling(fence_cookie); -+ drm_atomic_helper_commit_hw_done(old_state); -+ } - - /* - * Wait for completion of the page flips to ensure that old buffers -diff --git a/drivers/gpu/drm/panel/panel-elida-kd35t133.c b/drivers/gpu/drm/panel/panel-elida-kd35t133.c -index eee714cf3f490..3a7fc3ca6a6fe 100644 ---- a/drivers/gpu/drm/panel/panel-elida-kd35t133.c -+++ b/drivers/gpu/drm/panel/panel-elida-kd35t133.c -@@ -112,6 +112,8 @@ static int kd35t133_unprepare(struct drm_panel *panel) - return ret; - } - -+ gpiod_set_value_cansleep(ctx->reset_gpio, 1); -+ - regulator_disable(ctx->iovcc); - regulator_disable(ctx->vdd); - -diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/drivers/gpu/drm/panel/panel-sitronix-st7701.c -index 225b9884f61a9..54b28992db5d8 100644 ---- a/drivers/gpu/drm/panel/panel-sitronix-st7701.c -+++ b/drivers/gpu/drm/panel/panel-sitronix-st7701.c -@@ -288,7 +288,7 @@ static void st7701_init_sequence(struct st7701 *st7701) - FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVDD_MASK, - DIV_ROUND_CLOSEST(desc->avdd_mv - 6200, 200)) | - FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVCL_MASK, -- DIV_ROUND_CLOSEST(-4400 + desc->avcl_mv, 200))); -+ DIV_ROUND_CLOSEST(-4400 - desc->avcl_mv, 200))); - - /* T2D = 0.2us * T2D[3:0] */ - ST7701_DSI(st7701, DSI_CMD2_BK1_SPD1, -diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c -index 6452e4e900dd7..55d2430485168 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_gpu.c -+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c -@@ -71,7 +71,12 @@ int panfrost_gpu_soft_reset(struct panfrost_device *pfdev) - } - - gpu_write(pfdev, GPU_INT_CLEAR, GPU_IRQ_MASK_ALL); -- gpu_write(pfdev, GPU_INT_MASK, GPU_IRQ_MASK_ALL); -+ -+ /* Only enable the interrupts we care about */ -+ gpu_write(pfdev, GPU_INT_MASK, -+ GPU_IRQ_MASK_ERROR | -+ GPU_IRQ_PERFCNT_SAMPLE_COMPLETED | -+ GPU_IRQ_CLEAN_CACHES_COMPLETED); - - return 0; - } -@@ -313,28 +318,38 @@ static void panfrost_gpu_init_features(struct panfrost_device *pfdev) - pfdev->features.shader_present, pfdev->features.l2_present); - } - -+static u64 panfrost_get_core_mask(struct panfrost_device *pfdev) -+{ -+ u64 core_mask; -+ -+ if (pfdev->features.l2_present == 1) -+ return U64_MAX; -+ -+ /* -+ * Only support one core group now. -+ * ~(l2_present - 1) unsets all bits in l2_present except -+ * the bottom bit. (l2_present - 2) has all the bits in -+ * the first core group set. AND them together to generate -+ * a mask of cores in the first core group. -+ */ -+ core_mask = ~(pfdev->features.l2_present - 1) & -+ (pfdev->features.l2_present - 2); -+ dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n", -+ hweight64(core_mask), -+ hweight64(pfdev->features.shader_present)); -+ -+ return core_mask; -+} -+ - void panfrost_gpu_power_on(struct panfrost_device *pfdev) - { - int ret; - u32 val; -- u64 core_mask = U64_MAX; -+ u64 core_mask; - - panfrost_gpu_init_quirks(pfdev); -+ core_mask = panfrost_get_core_mask(pfdev); - -- if (pfdev->features.l2_present != 1) { -- /* -- * Only support one core group now. -- * ~(l2_present - 1) unsets all bits in l2_present except -- * the bottom bit. (l2_present - 2) has all the bits in -- * the first core group set. AND them together to generate -- * a mask of cores in the first core group. -- */ -- core_mask = ~(pfdev->features.l2_present - 1) & -- (pfdev->features.l2_present - 2); -- dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n", -- hweight64(core_mask), -- hweight64(pfdev->features.shader_present)); -- } - gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present & core_mask); - ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO, - val, val == (pfdev->features.l2_present & core_mask), -@@ -359,9 +374,26 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev) - - void panfrost_gpu_power_off(struct panfrost_device *pfdev) - { -- gpu_write(pfdev, TILER_PWROFF_LO, 0); -- gpu_write(pfdev, SHADER_PWROFF_LO, 0); -- gpu_write(pfdev, L2_PWROFF_LO, 0); -+ int ret; -+ u32 val; -+ -+ gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present); -+ ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_PWRTRANS_LO, -+ val, !val, 1, 1000); -+ if (ret) -+ dev_err(pfdev->dev, "shader power transition timeout"); -+ -+ gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present); -+ ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_PWRTRANS_LO, -+ val, !val, 1, 1000); -+ if (ret) -+ dev_err(pfdev->dev, "tiler power transition timeout"); -+ -+ gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present); -+ ret = readl_poll_timeout(pfdev->iomem + L2_PWRTRANS_LO, -+ val, !val, 0, 1000); -+ if (ret) -+ dev_err(pfdev->dev, "l2 power transition timeout"); - } - - int panfrost_gpu_init(struct panfrost_device *pfdev) -diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c -index d4f09ecc3d221..f336b5b3b11f4 100644 ---- a/drivers/gpu/drm/radeon/r100.c -+++ b/drivers/gpu/drm/radeon/r100.c -@@ -2321,7 +2321,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) - switch (prim_walk) { - case 1: - for (i = 0; i < track->num_arrays; i++) { -- size = track->arrays[i].esize * track->max_indx * 4; -+ size = track->arrays[i].esize * track->max_indx * 4UL; - if (track->arrays[i].robj == NULL) { - DRM_ERROR("(PW %u) Vertex array %u no buffer " - "bound\n", prim_walk, i); -@@ -2340,7 +2340,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) - break; - case 2: - for (i = 0; i < track->num_arrays; i++) { -- size = track->arrays[i].esize * (nverts - 1) * 4; -+ size = track->arrays[i].esize * (nverts - 1) * 4UL; - if (track->arrays[i].robj == NULL) { - DRM_ERROR("(PW %u) Vertex array %u no buffer " - "bound\n", prim_walk, i); -diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c -index 638f861af80fa..6cf54a747749d 100644 ---- a/drivers/gpu/drm/radeon/r600_cs.c -+++ b/drivers/gpu/drm/radeon/r600_cs.c -@@ -1275,7 +1275,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) - return -EINVAL; - } - tmp = (reg - CB_COLOR0_BASE) / 4; -- track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; -+ track->cb_color_bo_offset[tmp] = (u64)radeon_get_ib_value(p, idx) << 8; - ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); - track->cb_color_base_last[tmp] = ib[idx]; - track->cb_color_bo[tmp] = reloc->robj; -@@ -1302,7 +1302,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) - "0x%04X\n", reg); - return -EINVAL; - } -- track->htile_offset = radeon_get_ib_value(p, idx) << 8; -+ track->htile_offset = (u64)radeon_get_ib_value(p, idx) << 8; - ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); - track->htile_bo = reloc->robj; - track->db_dirty = true; -diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c -index ca5598ae8bfcf..1814bb8e14f10 100644 ---- a/drivers/gpu/drm/radeon/radeon_display.c -+++ b/drivers/gpu/drm/radeon/radeon_display.c -@@ -687,11 +687,16 @@ static void radeon_crtc_init(struct drm_device *dev, int index) - if (radeon_crtc == NULL) - return; - -+ radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); -+ if (!radeon_crtc->flip_queue) { -+ kfree(radeon_crtc); -+ return; -+ } -+ - drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); - - drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); - radeon_crtc->crtc_id = index; -- radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); - rdev->mode_info.crtcs[index] = radeon_crtc; - - if (rdev->family >= CHIP_BONAIRE) { -diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c -index 987cabbf1318e..c38b4d5d6a14f 100644 ---- a/drivers/gpu/drm/radeon/radeon_vm.c -+++ b/drivers/gpu/drm/radeon/radeon_vm.c -@@ -1204,13 +1204,17 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) - r = radeon_bo_create(rdev, pd_size, align, true, - RADEON_GEM_DOMAIN_VRAM, 0, NULL, - NULL, &vm->page_directory); -- if (r) -+ if (r) { -+ kfree(vm->page_tables); -+ vm->page_tables = NULL; - return r; -- -+ } - r = radeon_vm_clear_bo(rdev, vm->page_directory); - if (r) { - radeon_bo_unref(&vm->page_directory); - vm->page_directory = NULL; -+ kfree(vm->page_tables); -+ vm->page_tables = NULL; - return r; - } - -diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c -index a91012447b56e..85e9cba49cecb 100644 ---- a/drivers/gpu/drm/radeon/si.c -+++ b/drivers/gpu/drm/radeon/si.c -@@ -3611,6 +3611,10 @@ static int si_cp_start(struct radeon_device *rdev) - for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { - ring = &rdev->ring[i]; - r = radeon_ring_lock(rdev, ring, 2); -+ if (r) { -+ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); -+ return r; -+ } - - /* clear the compute context state */ - radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); -diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c -index f74f381af05fd..d49c145db4370 100644 ---- a/drivers/gpu/drm/radeon/sumo_dpm.c -+++ b/drivers/gpu/drm/radeon/sumo_dpm.c -@@ -1493,8 +1493,10 @@ static int sumo_parse_power_table(struct radeon_device *rdev) - non_clock_array_index = power_state->v2.nonClockInfoIndex; - non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) - &non_clock_info_array->nonClockInfo[non_clock_array_index]; -- if (!rdev->pm.power_state[i].clock_info) -+ if (!rdev->pm.power_state[i].clock_info) { -+ kfree(rdev->pm.dpm.ps); - return -EINVAL; -+ } - ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); - if (ps == NULL) { - kfree(rdev->pm.dpm.ps); -diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c -index 08ea1c864cb23..ef1cc7bad20a7 100644 ---- a/drivers/gpu/drm/radeon/trinity_dpm.c -+++ b/drivers/gpu/drm/radeon/trinity_dpm.c -@@ -1726,8 +1726,10 @@ static int trinity_parse_power_table(struct radeon_device *rdev) - non_clock_array_index = power_state->v2.nonClockInfoIndex; - non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) - &non_clock_info_array->nonClockInfo[non_clock_array_index]; -- if (!rdev->pm.power_state[i].clock_info) -+ if (!rdev->pm.power_state[i].clock_info) { -+ kfree(rdev->pm.dpm.ps); - return -EINVAL; -+ } - ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); - if (ps == NULL) { - kfree(rdev->pm.dpm.ps); -diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c -index 16301bdfead12..95b75236fe5e8 100644 ---- a/drivers/gpu/drm/tidss/tidss_dispc.c -+++ b/drivers/gpu/drm/tidss/tidss_dispc.c -@@ -2653,18 +2653,69 @@ static void dispc_init_errata(struct dispc_device *dispc) - } - } - --static void dispc_softreset(struct dispc_device *dispc) -+static int dispc_softreset(struct dispc_device *dispc) - { - u32 val; - int ret = 0; - -+ /* K2G display controller does not support soft reset */ -+ if (dispc->feat->subrev == DISPC_K2G) -+ return 0; -+ - /* Soft reset */ - REG_FLD_MOD(dispc, DSS_SYSCONFIG, 1, 1, 1); - /* Wait for reset to complete */ - ret = readl_poll_timeout(dispc->base_common + DSS_SYSSTATUS, - val, val & 1, 100, 5000); -+ if (ret) { -+ dev_err(dispc->dev, "failed to reset dispc\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int dispc_init_hw(struct dispc_device *dispc) -+{ -+ struct device *dev = dispc->dev; -+ int ret; -+ -+ ret = pm_runtime_set_active(dev); -+ if (ret) { -+ dev_err(dev, "Failed to set DSS PM to active\n"); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(dispc->fclk); -+ if (ret) { -+ dev_err(dev, "Failed to enable DSS fclk\n"); -+ goto err_runtime_suspend; -+ } -+ -+ ret = dispc_softreset(dispc); - if (ret) -- dev_warn(dispc->dev, "failed to reset dispc\n"); -+ goto err_clk_disable; -+ -+ clk_disable_unprepare(dispc->fclk); -+ ret = pm_runtime_set_suspended(dev); -+ if (ret) { -+ dev_err(dev, "Failed to set DSS PM to suspended\n"); -+ return ret; -+ } -+ -+ return 0; -+ -+err_clk_disable: -+ clk_disable_unprepare(dispc->fclk); -+ -+err_runtime_suspend: -+ ret = pm_runtime_set_suspended(dev); -+ if (ret) { -+ dev_err(dev, "Failed to set DSS PM to suspended\n"); -+ return ret; -+ } -+ -+ return ret; - } - - int dispc_init(struct tidss_device *tidss) -@@ -2726,10 +2777,6 @@ int dispc_init(struct tidss_device *tidss) - return r; - } - -- /* K2G display controller does not support soft reset */ -- if (feat->subrev != DISPC_K2G) -- dispc_softreset(dispc); -- - for (i = 0; i < dispc->feat->num_vps; i++) { - u32 gamma_size = dispc->feat->vp_feat.color.gamma_size; - u32 *gamma_table; -@@ -2778,6 +2825,10 @@ int dispc_init(struct tidss_device *tidss) - of_property_read_u32(dispc->dev->of_node, "max-memory-bandwidth", - &dispc->memory_bandwidth_limit); - -+ r = dispc_init_hw(dispc); -+ if (r) -+ return r; -+ - tidss->dispc = dispc; - - return 0; -diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c -index afb2879980c6c..995bac488392a 100644 ---- a/drivers/gpu/drm/tidss/tidss_kms.c -+++ b/drivers/gpu/drm/tidss/tidss_kms.c -@@ -4,8 +4,6 @@ - * Author: Tomi Valkeinen - */ - --#include -- - #include - #include - #include -@@ -27,7 +25,6 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) - { - struct drm_device *ddev = old_state->dev; - struct tidss_device *tidss = to_tidss(ddev); -- bool fence_cookie = dma_fence_begin_signalling(); - - dev_dbg(ddev->dev, "%s\n", __func__); - -@@ -38,7 +35,6 @@ static void tidss_atomic_commit_tail(struct drm_atomic_state *old_state) - drm_atomic_helper_commit_modeset_enables(ddev, old_state); - - drm_atomic_helper_commit_hw_done(old_state); -- dma_fence_end_signalling(fence_cookie); - drm_atomic_helper_wait_for_flip_done(ddev, old_state); - - drm_atomic_helper_cleanup_planes(ddev, old_state); -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index f72755b8ea14c..86d34b77b37db 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -138,7 +138,7 @@ static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq) - if (ret) - return ret; - -- priv->irq_enabled = false; -+ priv->irq_enabled = true; - - return 0; - } -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c -index ae01d22b8f840..c46f380d91499 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c -@@ -595,10 +595,9 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp, - if (!(flags & drm_vmw_synccpu_allow_cs)) { - atomic_dec(&vmw_bo->cpu_writers); - } -- ttm_bo_put(&vmw_bo->base); -+ vmw_user_bo_unref(&vmw_bo); - } - -- drm_gem_object_put(&vmw_bo->base.base); - return ret; - } - -@@ -638,8 +637,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data, - return ret; - - ret = vmw_user_bo_synccpu_grab(vbo, arg->flags); -- vmw_bo_unreference(&vbo); -- drm_gem_object_put(&vbo->base.base); -+ vmw_user_bo_unref(&vbo); - if (unlikely(ret != 0)) { - if (ret == -ERESTARTSYS || ret == -EBUSY) - return -EBUSY; -@@ -713,7 +711,6 @@ int vmw_user_bo_lookup(struct drm_file *filp, - } - - *out = gem_to_vmw_bo(gobj); -- ttm_bo_get(&(*out)->base); - - return 0; - } -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c -index 79b30dc9d8253..97e56a94eaf80 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c -@@ -407,8 +407,8 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) - * for the new COTable. Initially pin the buffer object to make sure - * we can use tryreserve without failure. - */ -- ret = vmw_bo_create(dev_priv, new_size, &vmw_mob_placement, -- true, true, vmw_bo_bo_free, &buf); -+ ret = vmw_gem_object_create(dev_priv, new_size, &vmw_mob_placement, -+ true, true, vmw_bo_bo_free, &buf); - if (ret) { - DRM_ERROR("Failed initializing new cotable MOB.\n"); - return ret; -@@ -475,7 +475,7 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) - - vmw_resource_mob_attach(res); - /* Let go of the old mob. */ -- vmw_bo_unreference(&old_buf); -+ vmw_user_bo_unref(&old_buf); - res->id = vcotbl->type; - - ret = dma_resv_reserve_fences(bo->base.resv, 1); -@@ -492,7 +492,7 @@ out_map_new: - out_wait: - ttm_bo_unpin(bo); - ttm_bo_unreserve(bo); -- vmw_bo_unreference(&buf); -+ vmw_user_bo_unref(&buf); - - return ret; - } -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -index 8459fab9d9797..136f1cdcf8cdf 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h -@@ -969,6 +969,11 @@ static inline void vmw_bo_prio_del(struct vmw_buffer_object *vbo, int prio) - /** - * GEM related functionality - vmwgfx_gem.c - */ -+extern int vmw_gem_object_create(struct vmw_private *dev_priv, -+ size_t size, struct ttm_placement *placement, -+ bool interruptible, bool pin, -+ void (*bo_free)(struct ttm_buffer_object *bo), -+ struct vmw_buffer_object **p_bo); - extern int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, - struct drm_file *filp, - uint32_t size, -@@ -1600,6 +1605,21 @@ vmw_bo_reference(struct vmw_buffer_object *buf) - return buf; - } - -+static inline struct vmw_buffer_object *vmw_user_bo_ref(struct vmw_buffer_object *vbo) -+{ -+ drm_gem_object_get(&vbo->base.base); -+ return vbo; -+} -+ -+static inline void vmw_user_bo_unref(struct vmw_buffer_object **buf) -+{ -+ struct vmw_buffer_object *tmp_buf = *buf; -+ -+ *buf = NULL; -+ if (tmp_buf) -+ drm_gem_object_put(&tmp_buf->base.base); -+} -+ - static inline void vmw_fifo_resource_inc(struct vmw_private *dev_priv) - { - atomic_inc(&dev_priv->num_fifo_resources); -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -index 7e59469e1cb9f..bc7f02e4ecebb 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c -@@ -1147,7 +1147,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, - SVGAMobId *id, - struct vmw_buffer_object **vmw_bo_p) - { -- struct vmw_buffer_object *vmw_bo; -+ struct vmw_buffer_object *vmw_bo, *tmp_bo; - uint32_t handle = *id; - struct vmw_relocation *reloc; - int ret; -@@ -1159,8 +1159,8 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, - return PTR_ERR(vmw_bo); - } - ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false); -- ttm_bo_put(&vmw_bo->base); -- drm_gem_object_put(&vmw_bo->base.base); -+ tmp_bo = vmw_bo; -+ vmw_user_bo_unref(&tmp_bo); - if (unlikely(ret != 0)) - return ret; - -@@ -1202,7 +1202,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, - SVGAGuestPtr *ptr, - struct vmw_buffer_object **vmw_bo_p) - { -- struct vmw_buffer_object *vmw_bo; -+ struct vmw_buffer_object *vmw_bo, *tmp_bo; - uint32_t handle = ptr->gmrId; - struct vmw_relocation *reloc; - int ret; -@@ -1214,8 +1214,8 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, - return PTR_ERR(vmw_bo); - } - ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false); -- ttm_bo_put(&vmw_bo->base); -- drm_gem_object_put(&vmw_bo->base.base); -+ tmp_bo = vmw_bo; -+ vmw_user_bo_unref(&tmp_bo); - if (unlikely(ret != 0)) - return ret; - -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c -index 4d2c28e39f4e0..e7a533e39155c 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c -@@ -133,6 +133,22 @@ void vmw_gem_destroy(struct ttm_buffer_object *bo) - kfree(vbo); - } - -+int vmw_gem_object_create(struct vmw_private *vmw, -+ size_t size, struct ttm_placement *placement, -+ bool interruptible, bool pin, -+ void (*bo_free)(struct ttm_buffer_object *bo), -+ struct vmw_buffer_object **p_bo) -+{ -+ int ret = vmw_bo_create(vmw, size, placement, interruptible, pin, bo_free, p_bo); -+ -+ if (ret != 0) -+ goto out_no_bo; -+ -+ (*p_bo)->base.base.funcs = &vmw_gem_object_funcs; -+out_no_bo: -+ return ret; -+} -+ - int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, - struct drm_file *filp, - uint32_t size, -@@ -141,16 +157,14 @@ int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, - { - int ret; - -- ret = vmw_bo_create(dev_priv, size, -- (dev_priv->has_mob) ? -+ ret = vmw_gem_object_create(dev_priv, size, -+ (dev_priv->has_mob) ? - &vmw_sys_placement : - &vmw_vram_sys_placement, -- true, false, &vmw_gem_destroy, p_vbo); -+ true, false, &vmw_gem_destroy, p_vbo); - if (ret != 0) - goto out_no_bo; - -- (*p_vbo)->base.base.funcs = &vmw_gem_object_funcs; -- - ret = drm_gem_handle_create(filp, &(*p_vbo)->base.base, handle); - out_no_bo: - return ret; -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c -index aab6389cb4aab..aa571b75cd07f 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c -@@ -1402,8 +1402,8 @@ static int vmw_create_bo_proxy(struct drm_device *dev, - /* Reserve and switch the backing mob. */ - mutex_lock(&res->dev_priv->cmdbuf_mutex); - (void) vmw_resource_reserve(res, false, true); -- vmw_bo_unreference(&res->backup); -- res->backup = vmw_bo_reference(bo_mob); -+ vmw_user_bo_unref(&res->backup); -+ res->backup = vmw_user_bo_ref(bo_mob); - res->backup_offset = 0; - vmw_resource_unreserve(res, false, false, false, NULL, 0); - mutex_unlock(&res->dev_priv->cmdbuf_mutex); -@@ -1599,10 +1599,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, - - err_out: - /* vmw_user_lookup_handle takes one ref so does new_fb */ -- if (bo) { -- vmw_bo_unreference(&bo); -- drm_gem_object_put(&bo->base.base); -- } -+ if (bo) -+ vmw_user_bo_unref(&bo); - if (surface) - vmw_surface_unreference(&surface); - -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c -index b5b311f2a91a4..abc354ead4e8b 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c -@@ -457,8 +457,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void *data, - - ret = vmw_overlay_update_stream(dev_priv, buf, arg, true); - -- vmw_bo_unreference(&buf); -- drm_gem_object_put(&buf->base.base); -+ vmw_user_bo_unref(&buf); - - out_unlock: - mutex_unlock(&overlay->mutex); -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c -index c7d645e5ec7bf..30d1c1918bb48 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c -@@ -140,7 +140,7 @@ static void vmw_resource_release(struct kref *kref) - if (res->coherent) - vmw_bo_dirty_release(res->backup); - ttm_bo_unreserve(bo); -- vmw_bo_unreference(&res->backup); -+ vmw_user_bo_unref(&res->backup); - } - - if (likely(res->hw_destroy != NULL)) { -@@ -330,10 +330,10 @@ static int vmw_resource_buf_alloc(struct vmw_resource *res, - return 0; - } - -- ret = vmw_bo_create(res->dev_priv, res->backup_size, -- res->func->backup_placement, -- interruptible, false, -- &vmw_bo_bo_free, &backup); -+ ret = vmw_gem_object_create(res->dev_priv, res->backup_size, -+ res->func->backup_placement, -+ interruptible, false, -+ &vmw_bo_bo_free, &backup); - if (unlikely(ret != 0)) - goto out_no_bo; - -@@ -452,11 +452,11 @@ void vmw_resource_unreserve(struct vmw_resource *res, - vmw_resource_mob_detach(res); - if (res->coherent) - vmw_bo_dirty_release(res->backup); -- vmw_bo_unreference(&res->backup); -+ vmw_user_bo_unref(&res->backup); - } - - if (new_backup) { -- res->backup = vmw_bo_reference(new_backup); -+ res->backup = vmw_user_bo_ref(new_backup); - - /* - * The validation code should already have added a -@@ -544,7 +544,7 @@ out_no_reserve: - ttm_bo_put(val_buf->bo); - val_buf->bo = NULL; - if (backup_dirty) -- vmw_bo_unreference(&res->backup); -+ vmw_user_bo_unref(&res->backup); - - return ret; - } -@@ -719,7 +719,7 @@ int vmw_resource_validate(struct vmw_resource *res, bool intr, - goto out_no_validate; - else if (!res->func->needs_backup && res->backup) { - WARN_ON_ONCE(vmw_resource_mob_attached(res)); -- vmw_bo_unreference(&res->backup); -+ vmw_user_bo_unref(&res->backup); - } - - return 0; -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c -index 51e83dfa1cace..303f7a82f3509 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c -@@ -177,7 +177,7 @@ static int vmw_gb_shader_init(struct vmw_private *dev_priv, - - res->backup_size = size; - if (byte_code) { -- res->backup = vmw_bo_reference(byte_code); -+ res->backup = vmw_user_bo_ref(byte_code); - res->backup_offset = offset; - } - shader->size = size; -@@ -806,8 +806,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, - shader_type, num_input_sig, - num_output_sig, tfile, shader_handle); - out_bad_arg: -- vmw_bo_unreference(&buffer); -- drm_gem_object_put(&buffer->base.base); -+ vmw_user_bo_unref(&buffer); - return ret; - } - -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -index 1a1a286bc749f..50769528c3f3c 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c -@@ -683,9 +683,6 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base) - container_of(base, struct vmw_user_surface, prime.base); - struct vmw_resource *res = &user_srf->srf.res; - -- if (res && res->backup) -- drm_gem_object_put(&res->backup->base.base); -- - *p_base = NULL; - vmw_resource_unreference(&res); - } -@@ -848,23 +845,17 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, - * expect a backup buffer to be present. - */ - if (dev_priv->has_mob && req->shareable) { -- uint32_t backup_handle; -- -- ret = vmw_gem_object_create_with_handle(dev_priv, -- file_priv, -- res->backup_size, -- &backup_handle, -- &res->backup); -+ ret = vmw_gem_object_create(dev_priv, -+ res->backup_size, -+ &vmw_sys_placement, -+ true, -+ false, -+ &vmw_gem_destroy, -+ &res->backup); - if (unlikely(ret != 0)) { - vmw_resource_unreference(&res); - goto out_unlock; - } -- vmw_bo_reference(res->backup); -- /* -- * We don't expose the handle to the userspace and surface -- * already holds a gem reference -- */ -- drm_gem_handle_delete(file_priv, backup_handle); - } - - tmp = vmw_resource_reference(&srf->res); -@@ -1505,7 +1496,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, - if (ret == 0) { - if (res->backup->base.base.size < res->backup_size) { - VMW_DEBUG_USER("Surface backup buffer too small.\n"); -- vmw_bo_unreference(&res->backup); -+ vmw_user_bo_unref(&res->backup); - ret = -EINVAL; - goto out_unlock; - } else { -@@ -1519,8 +1510,6 @@ vmw_gb_surface_define_internal(struct drm_device *dev, - res->backup_size, - &backup_handle, - &res->backup); -- if (ret == 0) -- vmw_bo_reference(res->backup); - } - - if (unlikely(ret != 0)) { -diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c -index c1270db121784..165ed872fa4e7 100644 ---- a/drivers/hid/wacom_wac.c -+++ b/drivers/hid/wacom_wac.c -@@ -2646,8 +2646,8 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, - { - struct hid_data *hid_data = &wacom_wac->hid_data; - bool mt = wacom_wac->features.touch_max > 1; -- bool prox = hid_data->tipswitch && -- report_touch_events(wacom_wac); -+ bool touch_down = hid_data->tipswitch && hid_data->confidence; -+ bool prox = touch_down && report_touch_events(wacom_wac); - - if (touch_is_muted(wacom_wac)) { - if (!wacom_wac->shared->touch_down) -@@ -2697,24 +2697,6 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, - } - } - --static bool wacom_wac_slot_is_active(struct input_dev *dev, int key) --{ -- struct input_mt *mt = dev->mt; -- struct input_mt_slot *s; -- -- if (!mt) -- return false; -- -- for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { -- if (s->key == key && -- input_mt_get_value(s, ABS_MT_TRACKING_ID) >= 0) { -- return true; -- } -- } -- -- return false; --} -- - static void wacom_wac_finger_event(struct hid_device *hdev, - struct hid_field *field, struct hid_usage *usage, __s32 value) - { -@@ -2765,14 +2747,8 @@ static void wacom_wac_finger_event(struct hid_device *hdev, - } - - if (usage->usage_index + 1 == field->report_count) { -- if (equivalent_usage == wacom_wac->hid_data.last_slot_field) { -- bool touch_removed = wacom_wac_slot_is_active(wacom_wac->touch_input, -- wacom_wac->hid_data.id) && !wacom_wac->hid_data.tipswitch; -- -- if (wacom_wac->hid_data.confidence || touch_removed) { -- wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); -- } -- } -+ if (equivalent_usage == wacom_wac->hid_data.last_slot_field) -+ wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); - } - } - -diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c -index 36dab9cd208cf..8e3838c42a8c2 100644 ---- a/drivers/i2c/busses/i2c-s3c2410.c -+++ b/drivers/i2c/busses/i2c-s3c2410.c -@@ -220,8 +220,17 @@ static bool is_ack(struct s3c24xx_i2c *i2c) - int tries; - - for (tries = 50; tries; --tries) { -- if (readl(i2c->regs + S3C2410_IICCON) -- & S3C2410_IICCON_IRQPEND) { -+ unsigned long tmp = readl(i2c->regs + S3C2410_IICCON); -+ -+ if (!(tmp & S3C2410_IICCON_ACKEN)) { -+ /* -+ * Wait a bit for the bus to stabilize, -+ * delay estimated experimentally. -+ */ -+ usleep_range(100, 200); -+ return true; -+ } -+ if (tmp & S3C2410_IICCON_IRQPEND) { - if (!(readl(i2c->regs + S3C2410_IICSTAT) - & S3C2410_IICSTAT_LASTBIT)) - return true; -@@ -274,16 +283,6 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c, - - stat |= S3C2410_IICSTAT_START; - writel(stat, i2c->regs + S3C2410_IICSTAT); -- -- if (i2c->quirks & QUIRK_POLL) { -- while ((i2c->msg_num != 0) && is_ack(i2c)) { -- i2c_s3c_irq_nextbyte(i2c, stat); -- stat = readl(i2c->regs + S3C2410_IICSTAT); -- -- if (stat & S3C2410_IICSTAT_ARBITR) -- dev_err(i2c->dev, "deal with arbitration loss\n"); -- } -- } - } - - static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret) -@@ -690,7 +689,7 @@ static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c) - static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, - struct i2c_msg *msgs, int num) - { -- unsigned long timeout; -+ unsigned long timeout = 0; - int ret; - - ret = s3c24xx_i2c_set_master(i2c); -@@ -710,16 +709,19 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, - s3c24xx_i2c_message_start(i2c, msgs); - - if (i2c->quirks & QUIRK_POLL) { -- ret = i2c->msg_idx; -+ while ((i2c->msg_num != 0) && is_ack(i2c)) { -+ unsigned long stat = readl(i2c->regs + S3C2410_IICSTAT); - -- if (ret != num) -- dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); -+ i2c_s3c_irq_nextbyte(i2c, stat); - -- goto out; -+ stat = readl(i2c->regs + S3C2410_IICSTAT); -+ if (stat & S3C2410_IICSTAT_ARBITR) -+ dev_err(i2c->dev, "deal with arbitration loss\n"); -+ } -+ } else { -+ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); - } - -- timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); -- - ret = i2c->msg_idx; - - /* -diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c -index 8e252cde735b9..0e5d3d2e9c985 100644 ---- a/drivers/iio/adc/ad7091r-base.c -+++ b/drivers/iio/adc/ad7091r-base.c -@@ -174,8 +174,8 @@ static const struct iio_info ad7091r_info = { - - static irqreturn_t ad7091r_event_handler(int irq, void *private) - { -- struct ad7091r_state *st = (struct ad7091r_state *) private; -- struct iio_dev *iio_dev = dev_get_drvdata(st->dev); -+ struct iio_dev *iio_dev = private; -+ struct ad7091r_state *st = iio_priv(iio_dev); - unsigned int i, read_val; - int ret; - s64 timestamp = iio_get_time_ns(iio_dev); -@@ -234,7 +234,7 @@ int ad7091r_probe(struct device *dev, const char *name, - if (irq) { - ret = devm_request_threaded_irq(dev, irq, NULL, - ad7091r_event_handler, -- IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, st); -+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, iio_dev); - if (ret) - return ret; - } -diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c -index 7534572f74757..811525857d29f 100644 ---- a/drivers/iio/adc/ad9467.c -+++ b/drivers/iio/adc/ad9467.c -@@ -119,9 +119,9 @@ struct ad9467_state { - struct spi_device *spi; - struct clk *clk; - unsigned int output_mode; -+ unsigned int (*scales)[2]; - - struct gpio_desc *pwrdown_gpio; -- struct gpio_desc *reset_gpio; - }; - - static int ad9467_spi_read(struct spi_device *spi, unsigned int reg) -@@ -163,9 +163,10 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg, - - if (readval == NULL) { - ret = ad9467_spi_write(spi, reg, writeval); -- ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, -- AN877_ADC_TRANSFER_SYNC); -- return ret; -+ if (ret) -+ return ret; -+ return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, -+ AN877_ADC_TRANSFER_SYNC); - } - - ret = ad9467_spi_read(spi, reg); -@@ -212,6 +213,7 @@ static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index, - .channel = _chan, \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ - BIT(IIO_CHAN_INFO_SAMP_FREQ), \ -+ .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \ - .scan_index = _si, \ - .scan_type = { \ - .sign = _sign, \ -@@ -273,10 +275,13 @@ static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2) - const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info); - struct ad9467_state *st = adi_axi_adc_conv_priv(conv); - unsigned int i, vref_val; -+ int ret; - -- vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); -+ ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); -+ if (ret < 0) -+ return ret; - -- vref_val &= info1->vref_mask; -+ vref_val = ret & info1->vref_mask; - - for (i = 0; i < info->num_scales; i++) { - if (vref_val == info->scale_table[i][1]) -@@ -297,6 +302,7 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2) - struct ad9467_state *st = adi_axi_adc_conv_priv(conv); - unsigned int scale_val[2]; - unsigned int i; -+ int ret; - - if (val != 0) - return -EINVAL; -@@ -306,11 +312,13 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2) - if (scale_val[0] != val || scale_val[1] != val2) - continue; - -- ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, -- info->scale_table[i][1]); -- ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, -- AN877_ADC_TRANSFER_SYNC); -- return 0; -+ ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, -+ info->scale_table[i][1]); -+ if (ret < 0) -+ return ret; -+ -+ return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, -+ AN877_ADC_TRANSFER_SYNC); - } - - return -EINVAL; -@@ -359,6 +367,26 @@ static int ad9467_write_raw(struct adi_axi_adc_conv *conv, - } - } - -+static int ad9467_read_avail(struct adi_axi_adc_conv *conv, -+ struct iio_chan_spec const *chan, -+ const int **vals, int *type, int *length, -+ long mask) -+{ -+ const struct adi_axi_adc_chip_info *info = conv->chip_info; -+ struct ad9467_state *st = adi_axi_adc_conv_priv(conv); -+ -+ switch (mask) { -+ case IIO_CHAN_INFO_SCALE: -+ *vals = (const int *)st->scales; -+ *type = IIO_VAL_INT_PLUS_MICRO; -+ /* Values are stored in a 2D matrix */ -+ *length = info->num_scales * 2; -+ return IIO_AVAIL_LIST; -+ default: -+ return -EINVAL; -+ } -+} -+ - static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) - { - int ret; -@@ -371,6 +399,26 @@ static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) - AN877_ADC_TRANSFER_SYNC); - } - -+static int ad9467_scale_fill(struct adi_axi_adc_conv *conv) -+{ -+ const struct adi_axi_adc_chip_info *info = conv->chip_info; -+ struct ad9467_state *st = adi_axi_adc_conv_priv(conv); -+ unsigned int i, val1, val2; -+ -+ st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales, -+ sizeof(*st->scales), GFP_KERNEL); -+ if (!st->scales) -+ return -ENOMEM; -+ -+ for (i = 0; i < info->num_scales; i++) { -+ __ad9467_get_scale(conv, i, &val1, &val2); -+ st->scales[i][0] = val1; -+ st->scales[i][1] = val2; -+ } -+ -+ return 0; -+} -+ - static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) - { - struct ad9467_state *st = adi_axi_adc_conv_priv(conv); -@@ -378,6 +426,21 @@ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) - return ad9467_outputmode_set(st->spi, st->output_mode); - } - -+static int ad9467_reset(struct device *dev) -+{ -+ struct gpio_desc *gpio; -+ -+ gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); -+ if (IS_ERR_OR_NULL(gpio)) -+ return PTR_ERR_OR_ZERO(gpio); -+ -+ fsleep(1); -+ gpiod_set_value_cansleep(gpio, 0); -+ fsleep(10 * USEC_PER_MSEC); -+ -+ return 0; -+} -+ - static int ad9467_probe(struct spi_device *spi) - { - const struct ad9467_chip_info *info; -@@ -406,21 +469,16 @@ static int ad9467_probe(struct spi_device *spi) - if (IS_ERR(st->pwrdown_gpio)) - return PTR_ERR(st->pwrdown_gpio); - -- st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", -- GPIOD_OUT_LOW); -- if (IS_ERR(st->reset_gpio)) -- return PTR_ERR(st->reset_gpio); -- -- if (st->reset_gpio) { -- udelay(1); -- ret = gpiod_direction_output(st->reset_gpio, 1); -- if (ret) -- return ret; -- mdelay(10); -- } -+ ret = ad9467_reset(&spi->dev); -+ if (ret) -+ return ret; - - conv->chip_info = &info->axi_adc_info; - -+ ret = ad9467_scale_fill(conv); -+ if (ret) -+ return ret; -+ - id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); - if (id != conv->chip_info->id) { - dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", -@@ -431,6 +489,7 @@ static int ad9467_probe(struct spi_device *spi) - conv->reg_access = ad9467_reg_access; - conv->write_raw = ad9467_write_raw; - conv->read_raw = ad9467_read_raw; -+ conv->read_avail = ad9467_read_avail; - conv->preenable_setup = ad9467_preenable_setup; - - st->output_mode = info->default_output_mode | -diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c -index e8a8ea4140f16..ad386ac7f03cb 100644 ---- a/drivers/iio/adc/adi-axi-adc.c -+++ b/drivers/iio/adc/adi-axi-adc.c -@@ -143,6 +143,20 @@ static int adi_axi_adc_write_raw(struct iio_dev *indio_dev, - return conv->write_raw(conv, chan, val, val2, mask); - } - -+static int adi_axi_adc_read_avail(struct iio_dev *indio_dev, -+ struct iio_chan_spec const *chan, -+ const int **vals, int *type, int *length, -+ long mask) -+{ -+ struct adi_axi_adc_state *st = iio_priv(indio_dev); -+ struct adi_axi_adc_conv *conv = &st->client->conv; -+ -+ if (!conv->read_avail) -+ return -EOPNOTSUPP; -+ -+ return conv->read_avail(conv, chan, vals, type, length, mask); -+} -+ - static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *scan_mask) - { -@@ -227,69 +241,11 @@ struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev, - } - EXPORT_SYMBOL_NS_GPL(devm_adi_axi_adc_conv_register, IIO_ADI_AXI); - --static ssize_t in_voltage_scale_available_show(struct device *dev, -- struct device_attribute *attr, -- char *buf) --{ -- struct iio_dev *indio_dev = dev_to_iio_dev(dev); -- struct adi_axi_adc_state *st = iio_priv(indio_dev); -- struct adi_axi_adc_conv *conv = &st->client->conv; -- size_t len = 0; -- int i; -- -- for (i = 0; i < conv->chip_info->num_scales; i++) { -- const unsigned int *s = conv->chip_info->scale_table[i]; -- -- len += scnprintf(buf + len, PAGE_SIZE - len, -- "%u.%06u ", s[0], s[1]); -- } -- buf[len - 1] = '\n'; -- -- return len; --} -- --static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); -- --enum { -- ADI_AXI_ATTR_SCALE_AVAIL, --}; -- --#define ADI_AXI_ATTR(_en_, _file_) \ -- [ADI_AXI_ATTR_##_en_] = &iio_dev_attr_##_file_.dev_attr.attr -- --static struct attribute *adi_axi_adc_attributes[] = { -- ADI_AXI_ATTR(SCALE_AVAIL, in_voltage_scale_available), -- NULL --}; -- --static umode_t axi_adc_attr_is_visible(struct kobject *kobj, -- struct attribute *attr, int n) --{ -- struct device *dev = kobj_to_dev(kobj); -- struct iio_dev *indio_dev = dev_to_iio_dev(dev); -- struct adi_axi_adc_state *st = iio_priv(indio_dev); -- struct adi_axi_adc_conv *conv = &st->client->conv; -- -- switch (n) { -- case ADI_AXI_ATTR_SCALE_AVAIL: -- if (!conv->chip_info->num_scales) -- return 0; -- return attr->mode; -- default: -- return attr->mode; -- } --} -- --static const struct attribute_group adi_axi_adc_attribute_group = { -- .attrs = adi_axi_adc_attributes, -- .is_visible = axi_adc_attr_is_visible, --}; -- - static const struct iio_info adi_axi_adc_info = { - .read_raw = &adi_axi_adc_read_raw, - .write_raw = &adi_axi_adc_write_raw, -- .attrs = &adi_axi_adc_attribute_group, - .update_scan_mode = &adi_axi_adc_update_scan_mode, -+ .read_avail = &adi_axi_adc_read_avail, - }; - - static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = { -diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -index c2ee80546d120..58fbb1d3b7f41 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c -@@ -2819,6 +2819,10 @@ static int free_mr_alloc_res(struct hns_roce_dev *hr_dev) - return 0; - - create_failed_qp: -+ for (i--; i >= 0; i--) { -+ hns_roce_v2_destroy_qp(&free_mr->rsv_qp[i]->ibqp, NULL); -+ kfree(free_mr->rsv_qp[i]); -+ } - hns_roce_destroy_cq(cq, NULL); - kfree(cq); - -@@ -5791,7 +5795,7 @@ static int hns_roce_v2_modify_srq(struct ib_srq *ibsrq, - - /* Resizing SRQs is not supported yet */ - if (srq_attr_mask & IB_SRQ_MAX_WR) -- return -EINVAL; -+ return -EOPNOTSUPP; - - if (srq_attr_mask & IB_SRQ_LIMIT) { - if (srq_attr->srq_limit > srq->wqe_cnt) -diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c -index 783e71852c503..bd1fe89ca205e 100644 ---- a/drivers/infiniband/hw/hns/hns_roce_pd.c -+++ b/drivers/infiniband/hw/hns/hns_roce_pd.c -@@ -150,7 +150,7 @@ int hns_roce_alloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata) - int ret; - - if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)) -- return -EINVAL; -+ return -EOPNOTSUPP; - - ret = hns_roce_xrcd_alloc(hr_dev, &xrcd->xrcdn); - if (ret) -diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c -index f330ce895d884..8fe0cef7e2be6 100644 ---- a/drivers/infiniband/hw/mthca/mthca_cmd.c -+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c -@@ -635,7 +635,7 @@ void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox) - - int mthca_SYS_EN(struct mthca_dev *dev) - { -- u64 out; -+ u64 out = 0; - int ret; - - ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, CMD_TIME_CLASS_D); -@@ -1955,7 +1955,7 @@ int mthca_WRITE_MGM(struct mthca_dev *dev, int index, - int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox, - u16 *hash) - { -- u64 imm; -+ u64 imm = 0; - int err; - - err = mthca_cmd_imm(dev, mailbox->dma, &imm, 0, 0, CMD_MGID_HASH, -diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c -index b54bc8865daec..1ab268b770968 100644 ---- a/drivers/infiniband/hw/mthca/mthca_main.c -+++ b/drivers/infiniband/hw/mthca/mthca_main.c -@@ -382,7 +382,7 @@ static int mthca_init_icm(struct mthca_dev *mdev, - struct mthca_init_hca_param *init_hca, - u64 icm_size) - { -- u64 aux_pages; -+ u64 aux_pages = 0; - int err; - - err = mthca_SET_ICM_SIZE(mdev, icm_size, &aux_pages); -diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h -index dee8c97ff0568..d967d55324596 100644 ---- a/drivers/infiniband/ulp/iser/iscsi_iser.h -+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h -@@ -317,12 +317,10 @@ struct iser_device { - * - * @mr: memory region - * @sig_mr: signature memory region -- * @mr_valid: is mr valid indicator - */ - struct iser_reg_resources { - struct ib_mr *mr; - struct ib_mr *sig_mr; -- u8 mr_valid:1; - }; - - /** -diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c -index 7b83f48f60c5e..8ec470c519e82 100644 ---- a/drivers/infiniband/ulp/iser/iser_initiator.c -+++ b/drivers/infiniband/ulp/iser/iser_initiator.c -@@ -580,7 +580,10 @@ static inline int iser_inv_desc(struct iser_fr_desc *desc, u32 rkey) - return -EINVAL; - } - -- desc->rsc.mr_valid = 0; -+ if (desc->sig_protected) -+ desc->rsc.sig_mr->need_inval = false; -+ else -+ desc->rsc.mr->need_inval = false; - - return 0; - } -diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c -index 29ae2c6a250a3..6efcb79c8efe3 100644 ---- a/drivers/infiniband/ulp/iser/iser_memory.c -+++ b/drivers/infiniband/ulp/iser/iser_memory.c -@@ -264,7 +264,7 @@ static int iser_reg_sig_mr(struct iscsi_iser_task *iser_task, - - iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask); - -- if (rsc->mr_valid) -+ if (rsc->sig_mr->need_inval) - iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); - - ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); -@@ -288,7 +288,7 @@ static int iser_reg_sig_mr(struct iscsi_iser_task *iser_task, - wr->access = IB_ACCESS_LOCAL_WRITE | - IB_ACCESS_REMOTE_READ | - IB_ACCESS_REMOTE_WRITE; -- rsc->mr_valid = 1; -+ rsc->sig_mr->need_inval = true; - - sig_reg->sge.lkey = mr->lkey; - sig_reg->rkey = mr->rkey; -@@ -313,7 +313,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task, - struct ib_reg_wr *wr = &tx_desc->reg_wr; - int n; - -- if (rsc->mr_valid) -+ if (rsc->mr->need_inval) - iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); - - ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); -@@ -336,7 +336,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task, - IB_ACCESS_REMOTE_WRITE | - IB_ACCESS_REMOTE_READ; - -- rsc->mr_valid = 1; -+ rsc->mr->need_inval = true; - - reg->sge.lkey = mr->lkey; - reg->rkey = mr->rkey; -diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c -index a00ca117303a9..057e69164e6d7 100644 ---- a/drivers/infiniband/ulp/iser/iser_verbs.c -+++ b/drivers/infiniband/ulp/iser/iser_verbs.c -@@ -135,7 +135,6 @@ iser_create_fastreg_desc(struct iser_device *device, - goto err_alloc_mr_integrity; - } - } -- desc->rsc.mr_valid = 0; - - return desc; - -diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c -index e1e4f1133296a..c4d8caadec59e 100644 ---- a/drivers/input/keyboard/atkbd.c -+++ b/drivers/input/keyboard/atkbd.c -@@ -772,9 +772,9 @@ static bool atkbd_is_portable_device(void) - * not work. So in this case simply assume a keyboard is connected to avoid - * confusing some laptop keyboards. - * -- * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using a fake id is -- * ok in translated mode, only atkbd_select_set() checks atkbd->id and in -- * translated mode that is a no-op. -+ * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using the standard -+ * 0xab83 id is ok in translated mode, only atkbd_select_set() checks atkbd->id -+ * and in translated mode that is a no-op. - */ - static bool atkbd_skip_getid(struct atkbd *atkbd) - { -@@ -792,6 +792,7 @@ static int atkbd_probe(struct atkbd *atkbd) - { - struct ps2dev *ps2dev = &atkbd->ps2dev; - unsigned char param[2]; -+ bool skip_getid; - - /* - * Some systems, where the bit-twiddling when testing the io-lines of the -@@ -813,7 +814,8 @@ static int atkbd_probe(struct atkbd *atkbd) - */ - - param[0] = param[1] = 0xa5; /* initialize with invalid values */ -- if (atkbd_skip_getid(atkbd) || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { -+ skip_getid = atkbd_skip_getid(atkbd); -+ if (skip_getid || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { - - /* - * If the get ID command was skipped or failed, we check if we can at least set -@@ -823,7 +825,7 @@ static int atkbd_probe(struct atkbd *atkbd) - param[0] = 0; - if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) - return -1; -- atkbd->id = 0xabba; -+ atkbd->id = skip_getid ? 0xab83 : 0xabba; - return 0; - } - -diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c -index b2708de25ea34..d80065c8105af 100644 ---- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c -+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c -@@ -243,6 +243,7 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain, - - static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = { - { .compatible = "qcom,adreno" }, -+ { .compatible = "qcom,adreno-gmu" }, - { .compatible = "qcom,mdp4" }, - { .compatible = "qcom,mdss" }, - { .compatible = "qcom,sc7180-mdss" }, -diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c -index 9297b741f5e80..aa6d62cc567ae 100644 ---- a/drivers/iommu/dma-iommu.c -+++ b/drivers/iommu/dma-iommu.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include "dma-iommu.h" - -@@ -999,6 +1000,8 @@ static dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, - return DMA_MAPPING_ERROR; - } - -+ trace_swiotlb_bounced(dev, phys, size); -+ - aligned_size = iova_align(iovad, size); - phys = swiotlb_tbl_map_single(dev, phys, size, aligned_size, - iova_mask(iovad), dir, attrs); -diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig -index 2378cfb7443e4..509d03eb3e8d6 100644 ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -97,6 +97,7 @@ config LEDS_ARIEL - config LEDS_AW2013 - tristate "LED support for Awinic AW2013" - depends on LEDS_CLASS && I2C && OF -+ select REGMAP_I2C - help - This option enables support for the AW2013 3-channel - LED driver. -diff --git a/drivers/md/md.c b/drivers/md/md.c -index 0c2801d770901..6120f26a79696 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -528,6 +528,9 @@ static void md_end_flush(struct bio *bio) - rdev_dec_pending(rdev, mddev); - - if (atomic_dec_and_test(&mddev->flush_pending)) { -+ /* The pair is percpu_ref_get() from md_flush_request() */ -+ percpu_ref_put(&mddev->active_io); -+ - /* The pre-request flush has finished */ - queue_work(md_wq, &mddev->flush_work); - } -@@ -547,12 +550,8 @@ static void submit_flushes(struct work_struct *ws) - rdev_for_each_rcu(rdev, mddev) - if (rdev->raid_disk >= 0 && - !test_bit(Faulty, &rdev->flags)) { -- /* Take two references, one is dropped -- * when request finishes, one after -- * we reclaim rcu_read_lock -- */ - struct bio *bi; -- atomic_inc(&rdev->nr_pending); -+ - atomic_inc(&rdev->nr_pending); - rcu_read_unlock(); - bi = bio_alloc_bioset(rdev->bdev, 0, -@@ -563,7 +562,6 @@ static void submit_flushes(struct work_struct *ws) - atomic_inc(&mddev->flush_pending); - submit_bio(bi); - rcu_read_lock(); -- rdev_dec_pending(rdev, mddev); - } - rcu_read_unlock(); - if (atomic_dec_and_test(&mddev->flush_pending)) -@@ -616,6 +614,18 @@ bool md_flush_request(struct mddev *mddev, struct bio *bio) - /* new request after previous flush is completed */ - if (ktime_after(req_start, mddev->prev_flush_start)) { - WARN_ON(mddev->flush_bio); -+ /* -+ * Grab a reference to make sure mddev_suspend() will wait for -+ * this flush to be done. -+ * -+ * md_flush_reqeust() is called under md_handle_request() and -+ * 'active_io' is already grabbed, hence percpu_ref_is_zero() -+ * won't pass, percpu_ref_tryget_live() can't be used because -+ * percpu_ref_kill() can be called by mddev_suspend() -+ * concurrently. -+ */ -+ WARN_ON(percpu_ref_is_zero(&mddev->active_io)); -+ percpu_ref_get(&mddev->active_io); - mddev->flush_bio = bio; - bio = NULL; - } -diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c -index 30f906a67def4..76f7ca53d8123 100644 ---- a/drivers/md/raid1.c -+++ b/drivers/md/raid1.c -@@ -1972,12 +1972,12 @@ static void end_sync_write(struct bio *bio) - } - - static int r1_sync_page_io(struct md_rdev *rdev, sector_t sector, -- int sectors, struct page *page, int rw) -+ int sectors, struct page *page, blk_opf_t rw) - { - if (sync_page_io(rdev, sector, sectors << 9, page, rw, false)) - /* success */ - return 1; -- if (rw == WRITE) { -+ if (rw == REQ_OP_WRITE) { - set_bit(WriteErrorSeen, &rdev->flags); - if (!test_and_set_bit(WantReplacement, - &rdev->flags)) -@@ -2094,7 +2094,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio) - rdev = conf->mirrors[d].rdev; - if (r1_sync_page_io(rdev, sect, s, - pages[idx], -- WRITE) == 0) { -+ REQ_OP_WRITE) == 0) { - r1_bio->bios[d]->bi_end_io = NULL; - rdev_dec_pending(rdev, mddev); - } -@@ -2109,7 +2109,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio) - rdev = conf->mirrors[d].rdev; - if (r1_sync_page_io(rdev, sect, s, - pages[idx], -- READ) != 0) -+ REQ_OP_READ) != 0) - atomic_add(s, &rdev->corrected_errors); - } - sectors -= s; -@@ -2321,7 +2321,7 @@ static void fix_read_error(struct r1conf *conf, int read_disk, - atomic_inc(&rdev->nr_pending); - rcu_read_unlock(); - r1_sync_page_io(rdev, sect, s, -- conf->tmppage, WRITE); -+ conf->tmppage, REQ_OP_WRITE); - rdev_dec_pending(rdev, mddev); - } else - rcu_read_unlock(); -@@ -2338,7 +2338,7 @@ static void fix_read_error(struct r1conf *conf, int read_disk, - atomic_inc(&rdev->nr_pending); - rcu_read_unlock(); - if (r1_sync_page_io(rdev, sect, s, -- conf->tmppage, READ)) { -+ conf->tmppage, REQ_OP_READ)) { - atomic_add(s, &rdev->corrected_errors); - pr_info("md/raid1:%s: read error corrected (%d sectors at %llu on %pg)\n", - mdname(mddev), s, -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index f7783199f81d4..e4564ca1f2434 100644 ---- a/drivers/md/raid5.c -+++ b/drivers/md/raid5.c -@@ -36,6 +36,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -6832,7 +6833,18 @@ static void raid5d(struct md_thread *thread) - spin_unlock_irq(&conf->device_lock); - md_check_recovery(mddev); - spin_lock_irq(&conf->device_lock); -+ -+ /* -+ * Waiting on MD_SB_CHANGE_PENDING below may deadlock -+ * seeing md_check_recovery() is needed to clear -+ * the flag when using mdmon. -+ */ -+ continue; - } -+ -+ wait_event_lock_irq(mddev->sb_wait, -+ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags), -+ conf->device_lock); - } - pr_debug("%d stripes handled\n", handled); - -diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c -index 9f9a976527080..d352e028491aa 100644 ---- a/drivers/media/dvb-core/dvbdev.c -+++ b/drivers/media/dvb-core/dvbdev.c -@@ -104,6 +104,8 @@ static int dvb_device_open(struct inode *inode, struct file *file) - err = file->f_op->open(inode, file); - up_read(&minor_rwsem); - mutex_unlock(&dvbdev_mutex); -+ if (err) -+ dvb_device_put(dvbdev); - return err; - } - fail: -diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c -index 9a0d43c7ba9e0..ce99f7dfb5a5e 100644 ---- a/drivers/media/dvb-frontends/m88ds3103.c -+++ b/drivers/media/dvb-frontends/m88ds3103.c -@@ -1894,7 +1894,7 @@ static int m88ds3103_probe(struct i2c_client *client, - /* get frontend address */ - ret = regmap_read(dev->regmap, 0x29, &utmp); - if (ret) -- goto err_kfree; -+ goto err_del_adapters; - dev->dt_addr = ((utmp & 0x80) == 0) ? 0x42 >> 1 : 0x40 >> 1; - dev_dbg(&client->dev, "dt addr is 0x%02x\n", dev->dt_addr); - -@@ -1902,11 +1902,14 @@ static int m88ds3103_probe(struct i2c_client *client, - dev->dt_addr); - if (IS_ERR(dev->dt_client)) { - ret = PTR_ERR(dev->dt_client); -- goto err_kfree; -+ goto err_del_adapters; - } - } - - return 0; -+ -+err_del_adapters: -+ i2c_mux_del_adapters(dev->muxc); - err_kfree: - kfree(dev); - err: -diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c -index e9a4f8abd21c5..3071b61946c3b 100644 ---- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c -+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c -@@ -1412,7 +1412,6 @@ static int mtk_jpeg_remove(struct platform_device *pdev) - { - struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev); - -- cancel_delayed_work_sync(&jpeg->job_timeout_work); - pm_runtime_disable(&pdev->dev); - video_unregister_device(jpeg->vdev); - v4l2_m2m_release(jpeg->m2m_dev); -diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c -index afbbfd5d02bcc..6d200e23754e8 100644 ---- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c -+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c -@@ -188,6 +188,7 @@ int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param *param) - - return 0; - } -+EXPORT_SYMBOL_GPL(mtk_jpeg_dec_fill_param); - - u32 mtk_jpeg_dec_get_int_status(void __iomem *base) - { -@@ -199,6 +200,7 @@ u32 mtk_jpeg_dec_get_int_status(void __iomem *base) - - return ret; - } -+EXPORT_SYMBOL_GPL(mtk_jpeg_dec_get_int_status); - - u32 mtk_jpeg_dec_enum_result(u32 irq_result) - { -@@ -215,11 +217,13 @@ u32 mtk_jpeg_dec_enum_result(u32 irq_result) - - return MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN; - } -+EXPORT_SYMBOL_GPL(mtk_jpeg_dec_enum_result); - - void mtk_jpeg_dec_start(void __iomem *base) - { - writel(0, base + JPGDEC_REG_TRIG); - } -+EXPORT_SYMBOL_GPL(mtk_jpeg_dec_start); - - static void mtk_jpeg_dec_soft_reset(void __iomem *base) - { -@@ -239,6 +243,7 @@ void mtk_jpeg_dec_reset(void __iomem *base) - mtk_jpeg_dec_soft_reset(base); - mtk_jpeg_dec_hard_reset(base); - } -+EXPORT_SYMBOL_GPL(mtk_jpeg_dec_reset); - - static void mtk_jpeg_dec_set_brz_factor(void __iomem *base, u8 yscale_w, - u8 yscale_h, u8 uvscale_w, u8 uvscale_h) -@@ -407,3 +412,4 @@ void mtk_jpeg_dec_set_config(void __iomem *base, - config->dma_last_mcu); - mtk_jpeg_dec_set_pause_mcu_idx(base, config->total_mcu); - } -+EXPORT_SYMBOL_GPL(mtk_jpeg_dec_set_config); -diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c -index 905072871ed2e..196f2bba419f9 100644 ---- a/drivers/media/platform/nxp/imx-mipi-csis.c -+++ b/drivers/media/platform/nxp/imx-mipi-csis.c -@@ -1553,8 +1553,10 @@ static int mipi_csis_remove(struct platform_device *pdev) - v4l2_async_nf_cleanup(&csis->notifier); - v4l2_async_unregister_subdev(&csis->sd); - -+ if (!pm_runtime_enabled(&pdev->dev)) -+ mipi_csis_runtime_suspend(&pdev->dev); -+ - pm_runtime_disable(&pdev->dev); -- mipi_csis_runtime_suspend(&pdev->dev); - mipi_csis_clk_disable(csis); - media_entity_cleanup(&csis->sd.entity); - fwnode_handle_put(csis->sd.fwnode); -diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -index f2475c6235ea7..2b76339f9381c 100644 ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c -@@ -582,7 +582,7 @@ static int rkisp1_probe(struct platform_device *pdev) - - ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev); - if (ret) -- goto err_pm_runtime_disable; -+ goto err_media_dev_cleanup; - - ret = media_device_register(&rkisp1->media_dev); - if (ret) { -@@ -617,6 +617,8 @@ err_unreg_media_dev: - media_device_unregister(&rkisp1->media_dev); - err_unreg_v4l2_dev: - v4l2_device_unregister(&rkisp1->v4l2_dev); -+err_media_dev_cleanup: -+ media_device_cleanup(&rkisp1->media_dev); - err_pm_runtime_disable: - pm_runtime_disable(&pdev->dev); - return ret; -@@ -637,6 +639,8 @@ static int rkisp1_remove(struct platform_device *pdev) - media_device_unregister(&rkisp1->media_dev); - v4l2_device_unregister(&rkisp1->v4l2_dev); - -+ media_device_cleanup(&rkisp1->media_dev); -+ - pm_runtime_disable(&pdev->dev); - - return 0; -diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c -index 08840ba313e7a..69a2442f31223 100644 ---- a/drivers/media/platform/verisilicon/hantro_drv.c -+++ b/drivers/media/platform/verisilicon/hantro_drv.c -@@ -813,6 +813,8 @@ static int hantro_add_func(struct hantro_dev *vpu, unsigned int funcid) - - if (funcid == MEDIA_ENT_F_PROC_VIDEO_ENCODER) { - vpu->encoder = func; -+ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); - } else { - vpu->decoder = func; - v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); -diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c -index 30e650edaea8a..b2da48936e3f1 100644 ---- a/drivers/media/platform/verisilicon/hantro_v4l2.c -+++ b/drivers/media/platform/verisilicon/hantro_v4l2.c -@@ -759,6 +759,9 @@ const struct v4l2_ioctl_ops hantro_ioctl_ops = { - .vidioc_g_selection = vidioc_g_selection, - .vidioc_s_selection = vidioc_s_selection, - -+ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, -+ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, -+ - .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, - .vidioc_encoder_cmd = vidioc_encoder_cmd, - }; -diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c -index 727e6268567f7..f1feccc28bf05 100644 ---- a/drivers/media/usb/cx231xx/cx231xx-core.c -+++ b/drivers/media/usb/cx231xx/cx231xx-core.c -@@ -1024,6 +1024,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, - if (!dev->video_mode.isoc_ctl.urb) { - dev_err(dev->dev, - "cannot alloc memory for usb buffers\n"); -+ kfree(dma_q->p_left_data); - return -ENOMEM; - } - -@@ -1033,6 +1034,7 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, - dev_err(dev->dev, - "cannot allocate memory for usbtransfer\n"); - kfree(dev->video_mode.isoc_ctl.urb); -+ kfree(dma_q->p_left_data); - return -ENOMEM; - } - -diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c -index 14170a5d72b35..1764674de98bc 100644 ---- a/drivers/media/usb/pvrusb2/pvrusb2-context.c -+++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c -@@ -268,7 +268,8 @@ void pvr2_context_disconnect(struct pvr2_context *mp) - { - pvr2_hdw_disconnect(mp->hdw); - mp->disconnect_flag = !0; -- pvr2_context_notify(mp); -+ if (!pvr2_context_shutok()) -+ pvr2_context_notify(mp); - } - - -diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c -index cfbee2cfba6b0..c50387600b819 100644 ---- a/drivers/mfd/intel-lpss.c -+++ b/drivers/mfd/intel-lpss.c -@@ -301,8 +301,8 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss, - - snprintf(name, sizeof(name), "%s-div", devname); - tmp = clk_register_fractional_divider(NULL, name, __clk_get_name(tmp), -+ 0, lpss->priv, 1, 15, 16, 15, - CLK_FRAC_DIVIDER_POWER_OF_TWO_PS, -- lpss->priv, 1, 15, 16, 15, 0, - NULL); - if (IS_ERR(tmp)) - return PTR_ERR(tmp); -diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c -index bdb2ce7ff03b9..6196724ef39bb 100644 ---- a/drivers/mfd/syscon.c -+++ b/drivers/mfd/syscon.c -@@ -102,6 +102,10 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) - } - - syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%pa", np, &res.start); -+ if (!syscon_config.name) { -+ ret = -ENOMEM; -+ goto err_regmap; -+ } - syscon_config.reg_stride = reg_io_width; - syscon_config.val_bits = reg_io_width * 8; - syscon_config.max_register = resource_size(&res) - reg_io_width; -diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c -index 43afe40966e50..1ea1ae34b7a74 100644 ---- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c -+++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c -@@ -677,7 +677,7 @@ static int sec_attest_info(struct hl_fpriv *hpriv, struct hl_info_args *args) - if (!sec_attest_info) - return -ENOMEM; - -- info = kmalloc(sizeof(*info), GFP_KERNEL); -+ info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - rc = -ENOMEM; - goto free_sec_attest_info; -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 9b5a2cb110b3e..d84bdb69f56b0 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -1061,14 +1061,15 @@ config MMC_SDHCI_XENON - - config MMC_SDHCI_OMAP - tristate "TI SDHCI Controller Support" -+ depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST - depends on MMC_SDHCI_PLTFM && OF - select THERMAL - imply TI_SOC_THERMAL - select MMC_SDHCI_EXTERNAL_DMA if DMA_ENGINE - help - This selects the Secure Digital Host Controller Interface (SDHCI) -- support present in TI's DRA7 SOCs. The controller supports -- SD/MMC/SDIO devices. -+ support present in TI's Keystone/OMAP2+/DRA7 SOCs. The controller -+ supports SD/MMC/SDIO devices. - - If you have a controller with this interface, say Y or M here. - -@@ -1076,14 +1077,15 @@ config MMC_SDHCI_OMAP - - config MMC_SDHCI_AM654 - tristate "Support for the SDHCI Controller in TI's AM654 SOCs" -+ depends on ARCH_K3 || COMPILE_TEST - depends on MMC_SDHCI_PLTFM && OF - select MMC_SDHCI_IO_ACCESSORS - select MMC_CQHCI - select REGMAP_MMIO - help - This selects the Secure Digital Host Controller Interface (SDHCI) -- support present in TI's AM654 SOCs. The controller supports -- SD/MMC/SDIO devices. -+ support present in TI's AM65x/AM64x/AM62x/J721E SOCs. The controller -+ supports SD/MMC/SDIO devices. - - If you have a controller with this interface, say Y or M here. - -diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c -index 60b222799871e..8ee60605a6dcc 100644 ---- a/drivers/mtd/mtd_blkdevs.c -+++ b/drivers/mtd/mtd_blkdevs.c -@@ -463,7 +463,7 @@ static void blktrans_notify_add(struct mtd_info *mtd) - { - struct mtd_blktrans_ops *tr; - -- if (mtd->type == MTD_ABSENT) -+ if (mtd->type == MTD_ABSENT || mtd->type == MTD_UBIVOLUME) - return; - - list_for_each_entry(tr, &blktrans_majors, list) -@@ -503,7 +503,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) - mutex_lock(&mtd_table_mutex); - list_add(&tr->list, &blktrans_majors); - mtd_for_each_device(mtd) -- if (mtd->type != MTD_ABSENT) -+ if (mtd->type != MTD_ABSENT && mtd->type != MTD_UBIVOLUME) - tr->add_mtd(tr, mtd); - mutex_unlock(&mtd_table_mutex); - return 0; -diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c -index 02d5001768382..bea1a7d3edd78 100644 ---- a/drivers/mtd/nand/raw/fsl_ifc_nand.c -+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c -@@ -20,7 +20,7 @@ - - #define ERR_BYTE 0xFF /* Value returned for read - bytes when read failed */ --#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait -+#define IFC_TIMEOUT_MSECS 1000 /* Maximum timeout to wait - for IFC NAND Machine */ - - struct fsl_ifc_ctrl; -diff --git a/drivers/net/amt.c b/drivers/net/amt.c -index 2d20be6ffb7e5..ddd087c2c3ed4 100644 ---- a/drivers/net/amt.c -+++ b/drivers/net/amt.c -@@ -11,7 +11,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include -@@ -80,11 +80,11 @@ static struct mld2_grec mldv2_zero_grec; - - static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb) - { -- BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct qdisc_skb_cb) > -+ BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct tc_skb_cb) > - sizeof_field(struct sk_buff, cb)); - - return (struct amt_skb_cb *)((void *)skb->cb + -- sizeof(struct qdisc_skb_cb)); -+ sizeof(struct tc_skb_cb)); - } - - static void __amt_source_gc_work(void) -diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c -index ef1a4a7c47b23..3efd556690563 100644 ---- a/drivers/net/dsa/vitesse-vsc73xx-core.c -+++ b/drivers/net/dsa/vitesse-vsc73xx-core.c -@@ -1119,6 +1119,8 @@ static int vsc73xx_gpio_probe(struct vsc73xx *vsc) - - vsc->gc.label = devm_kasprintf(vsc->dev, GFP_KERNEL, "VSC%04x", - vsc->chipid); -+ if (!vsc->gc.label) -+ return -ENOMEM; - vsc->gc.ngpio = 4; - vsc->gc.owner = THIS_MODULE; - vsc->gc.parent = vsc->dev; -diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c -index 2292d63a279c1..83c4659390fd5 100644 ---- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c -+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c -@@ -130,9 +130,15 @@ static int mlxbf_gige_open(struct net_device *netdev) - { - struct mlxbf_gige *priv = netdev_priv(netdev); - struct phy_device *phydev = netdev->phydev; -+ u64 control; - u64 int_en; - int err; - -+ /* Perform general init of GigE block */ -+ control = readq(priv->base + MLXBF_GIGE_CONTROL); -+ control |= MLXBF_GIGE_CONTROL_PORT_EN; -+ writeq(control, priv->base + MLXBF_GIGE_CONTROL); -+ - err = mlxbf_gige_request_irqs(priv); - if (err) - return err; -@@ -147,14 +153,14 @@ static int mlxbf_gige_open(struct net_device *netdev) - */ - priv->valid_polarity = 0; - -- err = mlxbf_gige_rx_init(priv); -+ phy_start(phydev); -+ -+ err = mlxbf_gige_tx_init(priv); - if (err) - goto free_irqs; -- err = mlxbf_gige_tx_init(priv); -+ err = mlxbf_gige_rx_init(priv); - if (err) -- goto rx_deinit; -- -- phy_start(phydev); -+ goto tx_deinit; - - netif_napi_add(netdev, &priv->napi, mlxbf_gige_poll); - napi_enable(&priv->napi); -@@ -176,8 +182,8 @@ static int mlxbf_gige_open(struct net_device *netdev) - - return 0; - --rx_deinit: -- mlxbf_gige_rx_deinit(priv); -+tx_deinit: -+ mlxbf_gige_tx_deinit(priv); - - free_irqs: - mlxbf_gige_free_irqs(priv); -@@ -279,7 +285,6 @@ static int mlxbf_gige_probe(struct platform_device *pdev) - void __iomem *plu_base; - void __iomem *base; - int addr, phy_irq; -- u64 control; - int err; - - base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MAC); -@@ -294,11 +299,6 @@ static int mlxbf_gige_probe(struct platform_device *pdev) - if (IS_ERR(plu_base)) - return PTR_ERR(plu_base); - -- /* Perform general init of GigE block */ -- control = readq(base + MLXBF_GIGE_CONTROL); -- control |= MLXBF_GIGE_CONTROL_PORT_EN; -- writeq(control, base + MLXBF_GIGE_CONTROL); -- - netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv)); - if (!netdev) - return -ENOMEM; -diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c -index 227d01cace3f0..6999843584934 100644 ---- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c -+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c -@@ -142,6 +142,9 @@ int mlxbf_gige_rx_init(struct mlxbf_gige *priv) - writeq(MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS_EN, - priv->base + MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS); - -+ writeq(ilog2(priv->rx_q_entries), -+ priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2); -+ - /* Clear MLXBF_GIGE_INT_MASK 'receive pkt' bit to - * indicate readiness to receive interrupts - */ -@@ -154,9 +157,6 @@ int mlxbf_gige_rx_init(struct mlxbf_gige *priv) - data |= MLXBF_GIGE_RX_DMA_EN; - writeq(data, priv->base + MLXBF_GIGE_RX_DMA); - -- writeq(ilog2(priv->rx_q_entries), -- priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2); -- - return 0; - - free_wqe_and_skb: -diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c -index 4c98950380d53..d231f4d2888be 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c -@@ -301,6 +301,7 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core, - unsigned long *p_index) - { - unsigned int num_rows, entry_size; -+ unsigned long index; - - /* We only allow allocations of entire rows */ - if (num_erps % erp_core->num_erp_banks != 0) -@@ -309,10 +310,11 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core, - entry_size = erp_core->erpt_entries_size[region_type]; - num_rows = num_erps / erp_core->num_erp_banks; - -- *p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); -- if (*p_index == 0) -+ index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); -+ if (!index) - return -ENOBUFS; -- *p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; -+ -+ *p_index = index - MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; - - return 0; - } -diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c -index 27b1663c476e7..64b209a0ad219 100644 ---- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c -+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c -@@ -391,7 +391,7 @@ nla_put_failure: - - struct rtnl_link_ops rmnet_link_ops __read_mostly = { - .kind = "rmnet", -- .maxtype = __IFLA_RMNET_MAX, -+ .maxtype = IFLA_RMNET_MAX, - .priv_size = sizeof(struct rmnet_priv), - .setup = rmnet_vnd_setup, - .validate = rmnet_rtnl_validate, -diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c -index c2c56a5289caf..e7b70006261f7 100644 ---- a/drivers/net/ethernet/renesas/ravb_main.c -+++ b/drivers/net/ethernet/renesas/ravb_main.c -@@ -1965,7 +1965,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) - struct ravb_tstamp_skb *ts_skb; - struct ravb_tx_desc *desc; - unsigned long flags; -- u32 dma_addr; -+ dma_addr_t dma_addr; - void *buffer; - u32 entry; - u32 len; -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h -index bdbf86cb102af..46944c02b45ed 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h -@@ -247,6 +247,7 @@ struct stmmac_priv { - u32 msg_enable; - int wolopts; - int wol_irq; -+ bool wol_irq_disabled; - int clk_csr; - struct timer_list eee_ctrl_timer; - int lpi_irq; -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -index 35c8dd92d3692..f03aa8a0b8954 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -@@ -761,10 +761,16 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) - if (wol->wolopts) { - pr_info("stmmac: wakeup enable\n"); - device_set_wakeup_enable(priv->device, 1); -- enable_irq_wake(priv->wol_irq); -+ /* Avoid unbalanced enable_irq_wake calls */ -+ if (priv->wol_irq_disabled) -+ enable_irq_wake(priv->wol_irq); -+ priv->wol_irq_disabled = false; - } else { - device_set_wakeup_enable(priv->device, 0); -- disable_irq_wake(priv->wol_irq); -+ /* Avoid unbalanced disable_irq_wake calls */ -+ if (!priv->wol_irq_disabled) -+ disable_irq_wake(priv->wol_irq); -+ priv->wol_irq_disabled = true; - } - - mutex_lock(&priv->lock); -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index deb6e95a1bca6..8f8de14347a94 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -3519,6 +3519,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev) - /* Request the Wake IRQ in case of another line - * is used for WoL - */ -+ priv->wol_irq_disabled = true; - if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) { - int_name = priv->int_name_wol; - sprintf(int_name, "%s:%s", dev->name, "wol"); -diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c -index 9f2553799895d..76fabeae512db 100644 ---- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c -+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c -@@ -54,7 +54,7 @@ - #define AM65_CPSW_MAX_PORTS 8 - - #define AM65_CPSW_MIN_PACKET_SIZE VLAN_ETH_ZLEN --#define AM65_CPSW_MAX_PACKET_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) -+#define AM65_CPSW_MAX_PACKET_SIZE 2024 - - #define AM65_CPSW_REG_CTL 0x004 - #define AM65_CPSW_REG_STAT_PORT_EN 0x014 -@@ -1990,7 +1990,8 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) - eth_hw_addr_set(port->ndev, port->slave.mac_addr); - - port->ndev->min_mtu = AM65_CPSW_MIN_PACKET_SIZE; -- port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE; -+ port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE - -+ (VLAN_ETH_HLEN + ETH_FCS_LEN); - port->ndev->hw_features = NETIF_F_SG | - NETIF_F_RXCSUM | - NETIF_F_HW_CSUM | -diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c -index 54a17b576eac0..7cbcf51bae924 100644 ---- a/drivers/net/phy/micrel.c -+++ b/drivers/net/phy/micrel.c -@@ -3302,6 +3302,7 @@ static struct phy_driver ksphy_driver[] = { - .flags = PHY_POLL_CABLE_TEST, - .driver_data = &ksz9021_type, - .probe = kszphy_probe, -+ .soft_reset = genphy_soft_reset, - .config_init = ksz9131_config_init, - .config_intr = kszphy_config_intr, - .handle_interrupt = kszphy_handle_interrupt, -diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c -index 76f275ca53e9c..70d468f013383 100644 ---- a/drivers/net/wireless/ath/ath11k/ahb.c -+++ b/drivers/net/wireless/ath/ath11k/ahb.c -@@ -813,8 +813,8 @@ static int ath11k_core_get_rproc(struct ath11k_base *ab) - - prproc = rproc_get_by_phandle(rproc_phandle); - if (!prproc) { -- ath11k_err(ab, "failed to get rproc\n"); -- return -EINVAL; -+ ath11k_dbg(ab, ATH11K_DBG_AHB, "failed to get rproc, deferring\n"); -+ return -EPROBE_DEFER; - } - ab_ahb->tgt_rproc = prproc; - -diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c -index a3cefbc43e80d..2c14188f34bbc 100644 ---- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c -@@ -99,17 +99,6 @@ static void iwl_mvm_phy_ctxt_set_rxchain(struct iwl_mvm *mvm, - active_cnt = 2; - } - -- /* -- * If the firmware requested it, then we know that it supports -- * getting zero for the values to indicate "use one, but pick -- * which one yourself", which means it can dynamically pick one -- * that e.g. has better RSSI. -- */ -- if (mvm->fw_static_smps_request && active_cnt == 1 && idle_cnt == 1) { -- idle_cnt = 0; -- active_cnt = 0; -- } -- - *rxchain_info = cpu_to_le32(iwl_mvm_get_valid_rx_ant(mvm) << - PHY_RX_CHAIN_VALID_POS); - *rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); -diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -index caaf4d52e2c64..76219486b9c2e 100644 ---- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -@@ -2200,7 +2200,7 @@ int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id, u16 tids) - WARN_ON(!iwl_mvm_has_new_tx_api(mvm)); - - if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TXPATH_FLUSH, 0) > 0) -- cmd.flags |= CMD_WANT_SKB; -+ cmd.flags |= CMD_WANT_SKB | CMD_SEND_IN_RFKILL; - - IWL_DEBUG_TX_QUEUES(mvm, "flush for sta id %d tid mask 0x%x\n", - sta_id, tids); -diff --git a/drivers/net/wireless/marvell/libertas/Kconfig b/drivers/net/wireless/marvell/libertas/Kconfig -index 6d62ab49aa8d4..c7d02adb3eead 100644 ---- a/drivers/net/wireless/marvell/libertas/Kconfig -+++ b/drivers/net/wireless/marvell/libertas/Kconfig -@@ -2,8 +2,6 @@ - config LIBERTAS - tristate "Marvell 8xxx Libertas WLAN driver support" - depends on CFG80211 -- select WIRELESS_EXT -- select WEXT_SPY - select LIB80211 - select FW_LOADER - help -diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c -index bcd564dc3554a..c907da2a4789a 100644 ---- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c -+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c -@@ -2046,6 +2046,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, - - mwifiex_set_sys_config_invalid_data(bss_cfg); - -+ memcpy(bss_cfg->mac_addr, priv->curr_addr, ETH_ALEN); -+ - if (params->beacon_interval) - bss_cfg->beacon_period = params->beacon_interval; - if (params->dtim_period) -diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h -index b4f945a549f71..863f5f2247a08 100644 ---- a/drivers/net/wireless/marvell/mwifiex/fw.h -+++ b/drivers/net/wireless/marvell/mwifiex/fw.h -@@ -165,6 +165,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { - #define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32) - #define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35) - #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) -+#define TLV_TYPE_UAP_MAC_ADDRESS (PROPRIETARY_TLV_BASE_ID + 43) - #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) - #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) - #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) -diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h -index 091e7ca793762..e8825f302de8a 100644 ---- a/drivers/net/wireless/marvell/mwifiex/ioctl.h -+++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h -@@ -107,6 +107,7 @@ struct mwifiex_uap_bss_param { - u8 qos_info; - u8 power_constraint; - struct mwifiex_types_wmm_info wmm_info; -+ u8 mac_addr[ETH_ALEN]; - }; - - enum { -diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c -index e78a201cd1507..491e366119096 100644 ---- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c -+++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c -@@ -468,6 +468,7 @@ void mwifiex_config_uap_11d(struct mwifiex_private *priv, - static int - mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) - { -+ struct host_cmd_tlv_mac_addr *mac_tlv; - struct host_cmd_tlv_dtim_period *dtim_period; - struct host_cmd_tlv_beacon_period *beacon_period; - struct host_cmd_tlv_ssid *ssid; -@@ -487,6 +488,13 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) - int i; - u16 cmd_size = *param_size; - -+ mac_tlv = (struct host_cmd_tlv_mac_addr *)tlv; -+ mac_tlv->header.type = cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS); -+ mac_tlv->header.len = cpu_to_le16(ETH_ALEN); -+ memcpy(mac_tlv->mac_addr, bss_cfg->mac_addr, ETH_ALEN); -+ cmd_size += sizeof(struct host_cmd_tlv_mac_addr); -+ tlv += sizeof(struct host_cmd_tlv_mac_addr); -+ - if (bss_cfg->ssid.ssid_len) { - ssid = (struct host_cmd_tlv_ssid *)tlv; - ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID); -diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c -index 9bc8758573fcc..0a88048b89768 100644 ---- a/drivers/net/wireless/mediatek/mt76/eeprom.c -+++ b/drivers/net/wireless/mediatek/mt76/eeprom.c -@@ -62,7 +62,7 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len) - goto out_put_node; - } - -- offset = be32_to_cpup(list); -+ offset += be32_to_cpup(list); - ret = mtd_read(mtd, offset, len, &retlen, eep); - put_mtd_device(mtd); - if (mtd_is_bitflip(ret)) -diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h -index 9c753c6aabeff..60c9f9c56a4f5 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt76.h -+++ b/drivers/net/wireless/mediatek/mt76/mt76.h -@@ -564,8 +564,7 @@ struct mt76_sdio { - struct mt76_worker txrx_worker; - struct mt76_worker status_worker; - struct mt76_worker net_worker; -- -- struct work_struct stat_work; -+ struct mt76_worker stat_worker; - - u8 *xmit_buf; - u32 xmit_buf_sz; -diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c -index 304212f5f8da7..d742b22428f0c 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c -@@ -205,8 +205,8 @@ static int mt7663s_suspend(struct device *dev) - mt76_worker_disable(&mdev->mt76.sdio.txrx_worker); - mt76_worker_disable(&mdev->mt76.sdio.status_worker); - mt76_worker_disable(&mdev->mt76.sdio.net_worker); -+ mt76_worker_disable(&mdev->mt76.sdio.stat_worker); - -- cancel_work_sync(&mdev->mt76.sdio.stat_work); - clear_bit(MT76_READING_STATS, &mdev->mphy.state); - - mt76_tx_status_check(&mdev->mt76, true); -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -index 10dda1693d7db..19640ff76bdcf 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c -@@ -1036,21 +1036,26 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, - u8 type[2]; - u8 rsvd[64]; - } __packed req = { -+ .ver = 1, - .idx = idx, - .env = env_cap, - }; - int ret, valid_cnt = 0; -- u8 i, *pos; -+ u16 buf_len = 0; -+ u8 *pos; - - if (!clc) - return 0; - -+ buf_len = le16_to_cpu(clc->len) - sizeof(*clc); - pos = clc->data; -- for (i = 0; i < clc->nr_country; i++) { -+ while (buf_len > 16) { - struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos; - u16 len = le16_to_cpu(rule->len); -+ u16 offset = len + sizeof(*rule); - -- pos += len + sizeof(*rule); -+ pos += offset; -+ buf_len -= offset; - if (rule->alpha2[0] != alpha2[0] || - rule->alpha2[1] != alpha2[1]) - continue; -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c -index 3b25a06fd9466..8898ba69b8e97 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c -@@ -222,7 +222,7 @@ static int mt7921s_suspend(struct device *__dev) - mt76_txq_schedule_all(&dev->mphy); - mt76_worker_disable(&mdev->tx_worker); - mt76_worker_disable(&mdev->sdio.status_worker); -- cancel_work_sync(&mdev->sdio.stat_work); -+ mt76_worker_disable(&mdev->sdio.stat_worker); - clear_bit(MT76_READING_STATS, &dev->mphy.state); - mt76_tx_status_check(mdev, true); - -@@ -254,6 +254,7 @@ restore_txrx_worker: - restore_worker: - mt76_worker_enable(&mdev->tx_worker); - mt76_worker_enable(&mdev->sdio.status_worker); -+ mt76_worker_enable(&mdev->sdio.stat_worker); - - if (!pm->ds_enable) - mt76_connac_mcu_set_deep_sleep(mdev, false); -@@ -286,6 +287,7 @@ static int mt7921s_resume(struct device *__dev) - mt76_worker_enable(&mdev->sdio.txrx_worker); - mt76_worker_enable(&mdev->sdio.status_worker); - mt76_worker_enable(&mdev->sdio.net_worker); -+ mt76_worker_enable(&mdev->sdio.stat_worker); - - /* restore previous ds setting */ - if (!pm->ds_enable) -diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c -index 1b3adb3d91e86..fd07b66233920 100644 ---- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c -+++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c -@@ -107,7 +107,7 @@ int mt7921s_mac_reset(struct mt7921_dev *dev) - mt76_worker_disable(&dev->mt76.sdio.txrx_worker); - mt76_worker_disable(&dev->mt76.sdio.status_worker); - mt76_worker_disable(&dev->mt76.sdio.net_worker); -- cancel_work_sync(&dev->mt76.sdio.stat_work); -+ mt76_worker_disable(&dev->mt76.sdio.stat_worker); - - mt7921s_disable_irq(&dev->mt76); - mt7921s_wfsys_reset(dev); -@@ -115,6 +115,7 @@ int mt7921s_mac_reset(struct mt7921_dev *dev) - mt76_worker_enable(&dev->mt76.sdio.txrx_worker); - mt76_worker_enable(&dev->mt76.sdio.status_worker); - mt76_worker_enable(&dev->mt76.sdio.net_worker); -+ mt76_worker_enable(&dev->mt76.sdio.stat_worker); - - dev->fw_assert = false; - clear_bit(MT76_MCU_RESET, &dev->mphy.state); -diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c -index 176207f3177c4..fc4fb94635645 100644 ---- a/drivers/net/wireless/mediatek/mt76/sdio.c -+++ b/drivers/net/wireless/mediatek/mt76/sdio.c -@@ -481,21 +481,21 @@ static void mt76s_status_worker(struct mt76_worker *w) - if (dev->drv->tx_status_data && ndata_frames > 0 && - !test_and_set_bit(MT76_READING_STATS, &dev->phy.state) && - !test_bit(MT76_STATE_SUSPEND, &dev->phy.state)) -- ieee80211_queue_work(dev->hw, &dev->sdio.stat_work); -+ mt76_worker_schedule(&sdio->stat_worker); - } while (nframes > 0); - - if (resched) - mt76_worker_schedule(&dev->tx_worker); - } - --static void mt76s_tx_status_data(struct work_struct *work) -+static void mt76s_tx_status_data(struct mt76_worker *worker) - { - struct mt76_sdio *sdio; - struct mt76_dev *dev; - u8 update = 1; - u16 count = 0; - -- sdio = container_of(work, struct mt76_sdio, stat_work); -+ sdio = container_of(worker, struct mt76_sdio, stat_worker); - dev = container_of(sdio, struct mt76_dev, sdio); - - while (true) { -@@ -508,7 +508,7 @@ static void mt76s_tx_status_data(struct work_struct *work) - } - - if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state)) -- ieee80211_queue_work(dev->hw, &sdio->stat_work); -+ mt76_worker_schedule(&sdio->status_worker); - else - clear_bit(MT76_READING_STATS, &dev->phy.state); - } -@@ -600,8 +600,8 @@ void mt76s_deinit(struct mt76_dev *dev) - mt76_worker_teardown(&sdio->txrx_worker); - mt76_worker_teardown(&sdio->status_worker); - mt76_worker_teardown(&sdio->net_worker); -+ mt76_worker_teardown(&sdio->stat_worker); - -- cancel_work_sync(&sdio->stat_work); - clear_bit(MT76_READING_STATS, &dev->phy.state); - - mt76_tx_status_check(dev, true); -@@ -644,10 +644,14 @@ int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, - if (err) - return err; - -+ err = mt76_worker_setup(dev->hw, &sdio->stat_worker, mt76s_tx_status_data, -+ "sdio-sta"); -+ if (err) -+ return err; -+ - sched_set_fifo_low(sdio->status_worker.task); - sched_set_fifo_low(sdio->net_worker.task); -- -- INIT_WORK(&sdio->stat_work, mt76s_tx_status_data); -+ sched_set_fifo_low(sdio->stat_worker.task); - - dev->queue_ops = &sdio_queue_ops; - dev->bus = bus_ops; -diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c -index 76d0a778636a4..311676c1ece0a 100644 ---- a/drivers/net/wireless/purelifi/plfxlc/usb.c -+++ b/drivers/net/wireless/purelifi/plfxlc/usb.c -@@ -493,9 +493,12 @@ int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer, - void *context) - { - struct usb_device *udev = interface_to_usbdev(usb->ez_usb); -- struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); -+ struct urb *urb; - int r; - -+ urb = usb_alloc_urb(0, GFP_ATOMIC); -+ if (!urb) -+ return -ENOMEM; - usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), - (void *)buffer, buffer_len, complete_fn, context); - -diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c -index ca79f652fef3c..6116c1bec1558 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/pci.c -+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c -@@ -164,21 +164,29 @@ static bool _rtl_pci_platform_switch_device_pci_aspm( - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - -+ value &= PCI_EXP_LNKCTL_ASPMC; -+ - if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) -- value |= 0x40; -+ value |= PCI_EXP_LNKCTL_CCC; - -- pci_write_config_byte(rtlpci->pdev, 0x80, value); -+ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_ASPMC | value, -+ value); - - return false; - } - --/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ --static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) -+/* @value is PCI_EXP_LNKCTL_CLKREQ_EN or 0 to enable/disable clk request. */ -+static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value) - { - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - -- pci_write_config_byte(rtlpci->pdev, 0x81, value); -+ value &= PCI_EXP_LNKCTL_CLKREQ_EN; -+ -+ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, -+ PCI_EXP_LNKCTL_CLKREQ_EN, -+ value); - - if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) - udelay(100); -@@ -192,11 +200,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; -- u8 num4bytes = pcipriv->ndis_adapter.num4bytes; - /*Retrieve original configuration settings. */ - u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg; -- u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter. -- pcibridge_linkctrlreg; - u16 aspmlevel = 0; - u8 tmp_u1b = 0; - -@@ -221,16 +226,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) - /*Set corresponding value. */ - aspmlevel |= BIT(0) | BIT(1); - linkctrl_reg &= ~aspmlevel; -- pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1)); - - _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg); -- udelay(50); -- -- /*4 Disable Pci Bridge ASPM */ -- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), -- pcibridge_linkctrlreg); -- -- udelay(50); - } - - /*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for -@@ -245,9 +242,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; -- u8 num4bytes = pcipriv->ndis_adapter.num4bytes; - u16 aspmlevel; -- u8 u_pcibridge_aspmsetting; - u8 u_device_aspmsetting; - - if (!ppsc->support_aspm) -@@ -259,25 +254,6 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) - return; - } - -- /*4 Enable Pci Bridge ASPM */ -- -- u_pcibridge_aspmsetting = -- pcipriv->ndis_adapter.pcibridge_linkctrlreg | -- rtlpci->const_hostpci_aspm_setting; -- -- if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) -- u_pcibridge_aspmsetting &= ~BIT(0); -- -- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), -- u_pcibridge_aspmsetting); -- -- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, -- "PlatformEnableASPM(): Write reg[%x] = %x\n", -- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), -- u_pcibridge_aspmsetting); -- -- udelay(50); -- - /*Get ASPM level (with/without Clock Req) */ - aspmlevel = rtlpci->const_devicepci_aspm_setting; - u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg; -@@ -291,7 +267,8 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) - - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { - _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level & -- RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); -+ RT_RF_OFF_LEVL_CLK_REQ) ? -+ PCI_EXP_LNKCTL_CLKREQ_EN : 0); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); - } - udelay(100); -@@ -358,22 +335,6 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, - return tpriv != NULL; - } - --static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) --{ -- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); -- struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); -- u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; -- u8 linkctrl_reg; -- u8 num4bbytes; -- -- num4bbytes = (capabilityoffset + 0x10) / 4; -- -- /*Read Link Control Register */ -- pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg); -- -- pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; --} -- - static void rtl_pci_parse_configuration(struct pci_dev *pdev, - struct ieee80211_hw *hw) - { -@@ -2033,12 +1994,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, - PCI_SLOT(bridge_pdev->devfn); - pcipriv->ndis_adapter.pcibridge_funcnum = - PCI_FUNC(bridge_pdev->devfn); -- pcipriv->ndis_adapter.pcibridge_pciehdr_offset = -- pci_pcie_cap(bridge_pdev); -- pcipriv->ndis_adapter.num4bytes = -- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; -- -- rtl_pci_get_linkcontrol_field(hw); - - if (pcipriv->ndis_adapter.pcibridge_vendor == - PCI_BRIDGE_VENDOR_AMD) { -@@ -2055,13 +2010,11 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, - pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); - - rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, -- "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", -+ "pci_bridge busnumber:devnumber:funcnumber:vendor:amd %d:%d:%d:%x:%x\n", - pcipriv->ndis_adapter.pcibridge_busnum, - pcipriv->ndis_adapter.pcibridge_devnum, - pcipriv->ndis_adapter.pcibridge_funcnum, - pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], -- pcipriv->ndis_adapter.pcibridge_pciehdr_offset, -- pcipriv->ndis_adapter.pcibridge_linkctrlreg, - pcipriv->ndis_adapter.amd_l1_patch); - - rtl_pci_parse_configuration(pdev, hw); -diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h -index 866861626a0a1..d6307197dfea0 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/pci.h -+++ b/drivers/net/wireless/realtek/rtlwifi/pci.h -@@ -236,11 +236,6 @@ struct mp_adapter { - u16 pcibridge_vendorid; - u16 pcibridge_deviceid; - -- u8 num4bytes; -- -- u8 pcibridge_pciehdr_offset; -- u8 pcibridge_linkctrlreg; -- - bool amd_l1_patch; - }; - -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c -index 12d0b3a87af7c..0fab3a0c7d49d 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c -@@ -16,12 +16,6 @@ static u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw, - static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); --static u32 _rtl88e_phy_calculate_bit_shift(u32 bitmask) --{ -- u32 i = ffs(bitmask); -- -- return i ? i - 1 : 32; --} - static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw); - static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); - static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, -@@ -51,7 +45,7 @@ u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, -@@ -74,7 +68,7 @@ void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, - - if (bitmask != MASKDWORD) { - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - -@@ -99,7 +93,7 @@ u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, - - - original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); -- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - - spin_unlock(&rtlpriv->locks.rf_lock); -@@ -127,7 +121,7 @@ void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, - original_value = _rtl88e_phy_rf_serial_read(hw, - rfpath, - regaddr); -- bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = - ((original_value & (~bitmask)) | - (data << bitshift)); -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c -index 3d29c8dbb2559..144ee780e1b6a 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c -@@ -17,7 +17,7 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", - regaddr, bitmask); - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, -@@ -40,7 +40,7 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, - - if (bitmask != MASKDWORD) { - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - -@@ -143,14 +143,6 @@ void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - } - EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); - --u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) --{ -- u32 i = ffs(bitmask); -- -- return i ? i - 1 : 32; --} --EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift); -- - static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) - { - rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h -index 75afa6253ad02..e64d377dfe9e2 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h -@@ -196,7 +196,6 @@ bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, - void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); - void rtl92c_phy_set_io(struct ieee80211_hw *hw); - void rtl92c_bb_block_on(struct ieee80211_hw *hw); --u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); - long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - u8 txpwridx); -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c -index da54e51badd3a..fa70a7d5539fd 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c -@@ -39,7 +39,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, - rfpath, regaddr); - } - -- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - - spin_unlock(&rtlpriv->locks.rf_lock); -@@ -110,7 +110,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, - original_value = _rtl92c_phy_rf_serial_read(hw, - rfpath, - regaddr); -- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = - ((original_value & (~bitmask)) | - (data << bitshift)); -@@ -122,7 +122,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, - original_value = _rtl92c_phy_fw_rf_serial_read(hw, - rfpath, - regaddr); -- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = - ((original_value & (~bitmask)) | - (data << bitshift)); -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h -index 7582a162bd112..c7a0d4c776f0a 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h -@@ -94,7 +94,6 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, - u32 offset); - u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); --u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); - void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, u32 data); - void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c -index a8d9fe269f313..0b8cb7e61fd80 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c -@@ -32,7 +32,7 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, - original_value = _rtl92c_phy_fw_rf_serial_read(hw, - rfpath, regaddr); - } -- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", -@@ -56,7 +56,7 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, - original_value = _rtl92c_phy_rf_serial_read(hw, - rfpath, - regaddr); -- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = - ((original_value & (~bitmask)) | - (data << bitshift)); -@@ -67,7 +67,7 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, - original_value = _rtl92c_phy_fw_rf_serial_read(hw, - rfpath, - regaddr); -- bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = - ((original_value & (~bitmask)) | - (data << bitshift)); -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c -index d18c092b61426..d835a27429f0f 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c -@@ -169,13 +169,6 @@ static const u8 channel_all[59] = { - 157, 159, 161, 163, 165 - }; - --static u32 _rtl92d_phy_calculate_bit_shift(u32 bitmask) --{ -- u32 i = ffs(bitmask); -- -- return i ? i - 1 : 32; --} -- - u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) - { - struct rtl_priv *rtlpriv = rtl_priv(hw); -@@ -198,7 +191,7 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) - } else { - originalvalue = rtl_read_dword(rtlpriv, regaddr); - } -- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, - "BBR MASK=0x%x Addr[0x%x]=0x%x\n", -@@ -230,7 +223,7 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, - dbi_direct); - else - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) -@@ -317,7 +310,7 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, - regaddr, rfpath, bitmask); - spin_lock(&rtlpriv->locks.rf_lock); - original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); -- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - spin_unlock(&rtlpriv->locks.rf_lock); - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, -@@ -343,7 +336,7 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _rtl92d_phy_rf_serial_read(hw, - rfpath, regaddr); -- bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = ((original_value & (~bitmask)) | - (data << bitshift)); - } -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c -index cc0bcaf13e96e..73ef602bfb01a 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c -@@ -16,7 +16,6 @@ static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, - static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); --static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask); - static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw); - static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); - static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, -@@ -46,7 +45,7 @@ u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, -@@ -68,7 +67,7 @@ void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, - - if (bitmask != MASKDWORD) { - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - -@@ -92,7 +91,7 @@ u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, - spin_lock(&rtlpriv->locks.rf_lock); - - original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr); -- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - - spin_unlock(&rtlpriv->locks.rf_lock); -@@ -119,7 +118,7 @@ void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw, - - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr); -- bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = (original_value & (~bitmask)) | (data << bitshift); - } - -@@ -201,13 +200,6 @@ static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, - pphyreg->rf3wire_offset, data_and_addr); - } - --static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask) --{ -- u32 i = ffs(bitmask); -- -- return i ? i - 1 : 32; --} -- - bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw) - { - return _rtl92ee_phy_config_mac_with_headerfile(hw); -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c -index aaa004d4d6d0a..0e2b9698088bb 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c -@@ -14,13 +14,6 @@ - #include "hw.h" - #include "table.h" - --static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask) --{ -- u32 i = ffs(bitmask); -- -- return i ? i - 1 : 32; --} -- - u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) - { - struct rtl_priv *rtlpriv = rtl_priv(hw); -@@ -30,7 +23,7 @@ u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) - regaddr, bitmask); - - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - - rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", -@@ -52,7 +45,7 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, - - if (bitmask != MASKDWORD) { - originalvalue = rtl_read_dword(rtlpriv, regaddr); -- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - -@@ -160,7 +153,7 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, - - original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); - -- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - - spin_unlock(&rtlpriv->locks.rf_lock); -@@ -191,7 +184,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, - regaddr); -- bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); -+ bitshift = calculate_bit_shift(bitmask); - data = ((original_value & (~bitmask)) | (data << bitshift)); - } - -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c -index 5323ead30db03..fa1839d8ee55f 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c -@@ -29,9 +29,10 @@ static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw, - u32 data); - static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask) - { -- u32 i = ffs(bitmask); -+ if (WARN_ON_ONCE(!bitmask)) -+ return 0; - -- return i ? i - 1 : 32; -+ return __ffs(bitmask); - } - static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw); - /*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/ -diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h -index 31f9e9e5c6804..0bac788ccd6e3 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/wifi.h -+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h -@@ -3105,4 +3105,11 @@ static inline struct ieee80211_sta *rtl_find_sta(struct ieee80211_hw *hw, - return ieee80211_find_sta(mac->vif, mac_addr); - } - -+static inline u32 calculate_bit_shift(u32 bitmask) -+{ -+ if (WARN_ON_ONCE(!bitmask)) -+ return 0; -+ -+ return __ffs(bitmask); -+} - #endif -diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c -index fabca307867a0..0970d6bcba439 100644 ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -266,9 +266,9 @@ static void rtw_ops_configure_filter(struct ieee80211_hw *hw, - - if (changed_flags & FIF_ALLMULTI) { - if (*new_flags & FIF_ALLMULTI) -- rtwdev->hal.rcr |= BIT_AM | BIT_AB; -+ rtwdev->hal.rcr |= BIT_AM; - else -- rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB); -+ rtwdev->hal.rcr &= ~(BIT_AM); - } - if (changed_flags & FIF_FCSFAIL) { - if (*new_flags & FIF_FCSFAIL) -diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c -index c3a8d78a41a7b..2716040985748 100644 ---- a/drivers/net/xen-netback/netback.c -+++ b/drivers/net/xen-netback/netback.c -@@ -463,12 +463,25 @@ static void xenvif_get_requests(struct xenvif_queue *queue, - } - - for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; -- shinfo->nr_frags++, gop++, nr_slots--) { -+ nr_slots--) { -+ if (unlikely(!txp->size)) { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&queue->response_lock, flags); -+ make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY); -+ push_tx_responses(queue); -+ spin_unlock_irqrestore(&queue->response_lock, flags); -+ ++txp; -+ continue; -+ } -+ - index = pending_index(queue->pending_cons++); - pending_idx = queue->pending_ring[index]; - xenvif_tx_create_map_op(queue, pending_idx, txp, - txp == first ? extra_count : 0, gop); - frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx); -+ ++shinfo->nr_frags; -+ ++gop; - - if (txp == first) - txp = txfrags; -@@ -481,20 +494,39 @@ static void xenvif_get_requests(struct xenvif_queue *queue, - shinfo = skb_shinfo(nskb); - frags = shinfo->frags; - -- for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; -- shinfo->nr_frags++, txp++, gop++) { -+ for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { -+ if (unlikely(!txp->size)) { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&queue->response_lock, flags); -+ make_tx_response(queue, txp, 0, -+ XEN_NETIF_RSP_OKAY); -+ push_tx_responses(queue); -+ spin_unlock_irqrestore(&queue->response_lock, -+ flags); -+ continue; -+ } -+ - index = pending_index(queue->pending_cons++); - pending_idx = queue->pending_ring[index]; - xenvif_tx_create_map_op(queue, pending_idx, txp, 0, - gop); - frag_set_pending_idx(&frags[shinfo->nr_frags], - pending_idx); -+ ++shinfo->nr_frags; -+ ++gop; - } - -- skb_shinfo(skb)->frag_list = nskb; -- } else if (nskb) { -+ if (shinfo->nr_frags) { -+ skb_shinfo(skb)->frag_list = nskb; -+ nskb = NULL; -+ } -+ } -+ -+ if (nskb) { - /* A frag_list skb was allocated but it is no longer needed -- * because enough slots were converted to copy ops above. -+ * because enough slots were converted to copy ops above or some -+ * were empty. - */ - kfree_skb(nskb); - } -diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c -index 355d80323b836..ce42afe8f64ef 100644 ---- a/drivers/nvme/target/tcp.c -+++ b/drivers/nvme/target/tcp.c -@@ -18,6 +18,7 @@ - #include "nvmet.h" - - #define NVMET_TCP_DEF_INLINE_DATA_SIZE (4 * PAGE_SIZE) -+#define NVMET_TCP_MAXH2CDATA 0x400000 /* 16M arbitrary limit */ - - /* Define the socket priority to use for connections were it is desirable - * that the NIC consider performing optimized packet processing or filtering. -@@ -861,7 +862,7 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) - icresp->hdr.pdo = 0; - icresp->hdr.plen = cpu_to_le32(icresp->hdr.hlen); - icresp->pfv = cpu_to_le16(NVME_TCP_PFV_1_0); -- icresp->maxdata = cpu_to_le32(0x400000); /* 16M arbitrary limit */ -+ icresp->maxdata = cpu_to_le32(NVMET_TCP_MAXH2CDATA); - icresp->cpda = 0; - if (queue->hdr_digest) - icresp->digest |= NVME_TCP_HDR_DIGEST_ENABLE; -@@ -914,6 +915,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) - { - struct nvme_tcp_data_pdu *data = &queue->pdu.data; - struct nvmet_tcp_cmd *cmd; -+ unsigned int exp_data_len; - - if (likely(queue->nr_cmds)) { - if (unlikely(data->ttag >= queue->nr_cmds)) { -@@ -932,12 +934,24 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) - data->ttag, le32_to_cpu(data->data_offset), - cmd->rbytes_done); - /* FIXME: use path and transport errors */ -- nvmet_req_complete(&cmd->req, -- NVME_SC_INVALID_FIELD | NVME_SC_DNR); -+ nvmet_tcp_fatal_error(queue); - return -EPROTO; - } - -+ exp_data_len = le32_to_cpu(data->hdr.plen) - -+ nvmet_tcp_hdgst_len(queue) - -+ nvmet_tcp_ddgst_len(queue) - -+ sizeof(*data); -+ - cmd->pdu_len = le32_to_cpu(data->data_length); -+ if (unlikely(cmd->pdu_len != exp_data_len || -+ cmd->pdu_len == 0 || -+ cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) { -+ pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len); -+ /* FIXME: use proper transport errors */ -+ nvmet_tcp_fatal_error(queue); -+ return -EPROTO; -+ } - cmd->pdu_recv = 0; - nvmet_tcp_build_pdu_iovec(cmd); - queue->cmd = cmd; -diff --git a/drivers/nvme/target/trace.h b/drivers/nvme/target/trace.h -index 6109b3806b12b..974d99d47f514 100644 ---- a/drivers/nvme/target/trace.h -+++ b/drivers/nvme/target/trace.h -@@ -53,8 +53,7 @@ static inline void __assign_req_name(char *name, struct nvmet_req *req) - return; - } - -- strncpy(name, req->ns->device_path, -- min_t(size_t, DISK_NAME_LEN, strlen(req->ns->device_path))); -+ strscpy_pad(name, req->ns->device_path, DISK_NAME_LEN); - } - #endif - -@@ -85,7 +84,7 @@ TRACE_EVENT(nvmet_req_init, - __entry->flags = cmd->common.flags; - __entry->nsid = le32_to_cpu(cmd->common.nsid); - __entry->metadata = le64_to_cpu(cmd->common.metadata); -- memcpy(__entry->cdw10, &cmd->common.cdw10, -+ memcpy(__entry->cdw10, &cmd->common.cdws, - sizeof(__entry->cdw10)); - ), - TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, " -diff --git a/drivers/of/base.c b/drivers/of/base.c -index d5a5c35eba72a..f849bbb9ef8c7 100644 ---- a/drivers/of/base.c -+++ b/drivers/of/base.c -@@ -1646,6 +1646,7 @@ int of_parse_phandle_with_args_map(const struct device_node *np, - out_args->np = new; - of_node_put(cur); - cur = new; -+ new = NULL; - } - put: - of_node_put(cur); -diff --git a/drivers/of/unittest-data/tests-phandle.dtsi b/drivers/of/unittest-data/tests-phandle.dtsi -index 6b33be4c4416c..aa0d7027ffa68 100644 ---- a/drivers/of/unittest-data/tests-phandle.dtsi -+++ b/drivers/of/unittest-data/tests-phandle.dtsi -@@ -38,6 +38,13 @@ - phandle-map-pass-thru = <0x0 0xf0>; - }; - -+ provider5: provider5 { -+ #phandle-cells = <2>; -+ phandle-map = <2 7 &provider4 2 3>; -+ phandle-map-mask = <0xff 0xf>; -+ phandle-map-pass-thru = <0x0 0xf0>; -+ }; -+ - consumer-a { - phandle-list = <&provider1 1>, - <&provider2 2 0>, -@@ -64,7 +71,8 @@ - <&provider4 4 0x100>, - <&provider4 0 0x61>, - <&provider0>, -- <&provider4 19 0x20>; -+ <&provider4 19 0x20>, -+ <&provider5 2 7>; - phandle-list-bad-phandle = <12345678 0 0>; - phandle-list-bad-args = <&provider2 1 0>, - <&provider4 0>; -diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index edd2342598e49..e541a8960f1de 100644 ---- a/drivers/of/unittest.c -+++ b/drivers/of/unittest.c -@@ -448,6 +448,9 @@ static void __init of_unittest_parse_phandle_with_args(void) - - unittest(passed, "index %i - data error on node %pOF rc=%i\n", - i, args.np, rc); -+ -+ if (rc == 0) -+ of_node_put(args.np); - } - - /* Check for missing list property */ -@@ -537,8 +540,9 @@ static void __init of_unittest_parse_phandle_with_args(void) - - static void __init of_unittest_parse_phandle_with_args_map(void) - { -- struct device_node *np, *p0, *p1, *p2, *p3; -+ struct device_node *np, *p[6] = {}; - struct of_phandle_args args; -+ unsigned int prefs[6]; - int i, rc; - - np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b"); -@@ -547,34 +551,24 @@ static void __init of_unittest_parse_phandle_with_args_map(void) - return; - } - -- p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); -- if (!p0) { -- pr_err("missing testcase data\n"); -- return; -- } -- -- p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); -- if (!p1) { -- pr_err("missing testcase data\n"); -- return; -- } -- -- p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); -- if (!p2) { -- pr_err("missing testcase data\n"); -- return; -- } -- -- p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); -- if (!p3) { -- pr_err("missing testcase data\n"); -- return; -+ p[0] = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); -+ p[1] = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); -+ p[2] = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); -+ p[3] = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); -+ p[4] = of_find_node_by_path("/testcase-data/phandle-tests/provider4"); -+ p[5] = of_find_node_by_path("/testcase-data/phandle-tests/provider5"); -+ for (i = 0; i < ARRAY_SIZE(p); ++i) { -+ if (!p[i]) { -+ pr_err("missing testcase data\n"); -+ return; -+ } -+ prefs[i] = kref_read(&p[i]->kobj.kref); - } - - rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); -- unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc); -+ unittest(rc == 8, "of_count_phandle_with_args() returned %i, expected 8\n", rc); - -- for (i = 0; i < 8; i++) { -+ for (i = 0; i < 9; i++) { - bool passed = true; - - memset(&args, 0, sizeof(args)); -@@ -585,13 +579,13 @@ static void __init of_unittest_parse_phandle_with_args_map(void) - switch (i) { - case 0: - passed &= !rc; -- passed &= (args.np == p1); -+ passed &= (args.np == p[1]); - passed &= (args.args_count == 1); - passed &= (args.args[0] == 1); - break; - case 1: - passed &= !rc; -- passed &= (args.np == p3); -+ passed &= (args.np == p[3]); - passed &= (args.args_count == 3); - passed &= (args.args[0] == 2); - passed &= (args.args[1] == 5); -@@ -602,28 +596,36 @@ static void __init of_unittest_parse_phandle_with_args_map(void) - break; - case 3: - passed &= !rc; -- passed &= (args.np == p0); -+ passed &= (args.np == p[0]); - passed &= (args.args_count == 0); - break; - case 4: - passed &= !rc; -- passed &= (args.np == p1); -+ passed &= (args.np == p[1]); - passed &= (args.args_count == 1); - passed &= (args.args[0] == 3); - break; - case 5: - passed &= !rc; -- passed &= (args.np == p0); -+ passed &= (args.np == p[0]); - passed &= (args.args_count == 0); - break; - case 6: - passed &= !rc; -- passed &= (args.np == p2); -+ passed &= (args.np == p[2]); - passed &= (args.args_count == 2); - passed &= (args.args[0] == 15); - passed &= (args.args[1] == 0x20); - break; - case 7: -+ passed &= !rc; -+ passed &= (args.np == p[3]); -+ passed &= (args.args_count == 3); -+ passed &= (args.args[0] == 2); -+ passed &= (args.args[1] == 5); -+ passed &= (args.args[2] == 3); -+ break; -+ case 8: - passed &= (rc == -ENOENT); - break; - default: -@@ -632,6 +634,9 @@ static void __init of_unittest_parse_phandle_with_args_map(void) - - unittest(passed, "index %i - data error on node %s rc=%i\n", - i, args.np->full_name, rc); -+ -+ if (rc == 0) -+ of_node_put(args.np); - } - - /* Check for missing list property */ -@@ -678,6 +683,13 @@ static void __init of_unittest_parse_phandle_with_args_map(void) - "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1"); - - unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); -+ -+ for (i = 0; i < ARRAY_SIZE(p); ++i) { -+ unittest(prefs[i] == kref_read(&p[i]->kobj.kref), -+ "provider%d: expected:%d got:%d\n", -+ i, prefs[i], kref_read(&p[i]->kobj.kref)); -+ of_node_put(p[i]); -+ } - } - - static void __init of_unittest_property_string(void) -diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c -index d2634dafb68e5..7ecad72cff7e7 100644 ---- a/drivers/pci/controller/dwc/pci-keystone.c -+++ b/drivers/pci/controller/dwc/pci-keystone.c -@@ -1219,7 +1219,16 @@ static int ks_pcie_probe(struct platform_device *pdev) - goto err_link; - } - -+ /* Obtain references to the PHYs */ -+ for (i = 0; i < num_lanes; i++) -+ phy_pm_runtime_get_sync(ks_pcie->phy[i]); -+ - ret = ks_pcie_enable_phy(ks_pcie); -+ -+ /* Release references to the PHYs */ -+ for (i = 0; i < num_lanes; i++) -+ phy_pm_runtime_put_sync(ks_pcie->phy[i]); -+ - if (ret) { - dev_err(dev, "failed to enable phy\n"); - goto err_link; -diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c -index 83ddb190292e4..59c164b5c64aa 100644 ---- a/drivers/pci/controller/dwc/pcie-designware-ep.c -+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c -@@ -600,6 +600,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, - } - - aligned_offset = msg_addr & (epc->mem->window.page_size - 1); -+ msg_addr &= ~aligned_offset; - ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, - epc->mem->window.page_size); - if (ret) -diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c -index b8612ce5f4d0c..40c38ca5a42e2 100644 ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -245,35 +245,60 @@ static int mtk_pcie_set_trans_table(struct mtk_gen3_pcie *pcie, - resource_size_t cpu_addr, - resource_size_t pci_addr, - resource_size_t size, -- unsigned long type, int num) -+ unsigned long type, int *num) - { -+ resource_size_t remaining = size; -+ resource_size_t table_size; -+ resource_size_t addr_align; -+ const char *range_type; - void __iomem *table; - u32 val; - -- if (num >= PCIE_MAX_TRANS_TABLES) { -- dev_err(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", -- (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); -- return -ENODEV; -- } -+ while (remaining && (*num < PCIE_MAX_TRANS_TABLES)) { -+ /* Table size needs to be a power of 2 */ -+ table_size = BIT(fls(remaining) - 1); -+ -+ if (cpu_addr > 0) { -+ addr_align = BIT(ffs(cpu_addr) - 1); -+ table_size = min(table_size, addr_align); -+ } -+ -+ /* Minimum size of translate table is 4KiB */ -+ if (table_size < 0x1000) { -+ dev_err(pcie->dev, "illegal table size %#llx\n", -+ (unsigned long long)table_size); -+ return -EINVAL; -+ } - -- table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + -- num * PCIE_ATR_TLB_SET_OFFSET; -+ table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + *num * PCIE_ATR_TLB_SET_OFFSET; -+ writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(table_size) - 1), table); -+ writel_relaxed(upper_32_bits(cpu_addr), table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); -+ writel_relaxed(lower_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); -+ writel_relaxed(upper_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); - -- writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(size) - 1), -- table); -- writel_relaxed(upper_32_bits(cpu_addr), -- table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); -- writel_relaxed(lower_32_bits(pci_addr), -- table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); -- writel_relaxed(upper_32_bits(pci_addr), -- table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); -+ if (type == IORESOURCE_IO) { -+ val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; -+ range_type = "IO"; -+ } else { -+ val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; -+ range_type = "MEM"; -+ } - -- if (type == IORESOURCE_IO) -- val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; -- else -- val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; -+ writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); - -- writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); -+ dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", -+ range_type, *num, (unsigned long long)cpu_addr, -+ (unsigned long long)pci_addr, (unsigned long long)table_size); -+ -+ cpu_addr += table_size; -+ pci_addr += table_size; -+ remaining -= table_size; -+ (*num)++; -+ } -+ -+ if (remaining) -+ dev_warn(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", -+ (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); - - return 0; - } -@@ -380,30 +405,20 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) - resource_size_t cpu_addr; - resource_size_t pci_addr; - resource_size_t size; -- const char *range_type; - -- if (type == IORESOURCE_IO) { -+ if (type == IORESOURCE_IO) - cpu_addr = pci_pio_to_address(res->start); -- range_type = "IO"; -- } else if (type == IORESOURCE_MEM) { -+ else if (type == IORESOURCE_MEM) - cpu_addr = res->start; -- range_type = "MEM"; -- } else { -+ else - continue; -- } - - pci_addr = res->start - entry->offset; - size = resource_size(res); - err = mtk_pcie_set_trans_table(pcie, cpu_addr, pci_addr, size, -- type, table_index); -+ type, &table_index); - if (err) - return err; -- -- dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", -- range_type, table_index, (unsigned long long)cpu_addr, -- (unsigned long long)pci_addr, (unsigned long long)size); -- -- table_index++; - } - - return 0; -diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c -index ae5ad05ddc1d4..11bdef206d120 100644 ---- a/drivers/pci/controller/pcie-mediatek.c -+++ b/drivers/pci/controller/pcie-mediatek.c -@@ -617,12 +617,18 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc) - if (status & MSI_STATUS){ - unsigned long imsi_status; - -+ /* -+ * The interrupt status can be cleared even if the -+ * MSI status remains pending. As such, given the -+ * edge-triggered interrupt type, its status should -+ * be cleared before being dispatched to the -+ * handler of the underlying device. -+ */ -+ writel(MSI_STATUS, port->base + PCIE_INT_STATUS); - while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { - for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) - generic_handle_domain_irq(port->inner_domain, bit); - } -- /* Clear MSI interrupt status */ -- writel(MSI_STATUS, port->base + PCIE_INT_STATUS); - } - } - -diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c -index 483bb65651665..40477d1d41b59 100644 ---- a/drivers/platform/x86/intel/vsec.c -+++ b/drivers/platform/x86/intel/vsec.c -@@ -124,36 +124,60 @@ static void intel_vsec_remove_aux(void *data) - auxiliary_device_uninit(data); - } - -+static DEFINE_MUTEX(vsec_ida_lock); -+ - static void intel_vsec_dev_release(struct device *dev) - { - struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev); - -+ xa_erase(&auxdev_array, intel_vsec_dev->id); -+ -+ mutex_lock(&vsec_ida_lock); - ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id); -+ mutex_unlock(&vsec_ida_lock); -+ - kfree(intel_vsec_dev->resource); - kfree(intel_vsec_dev); - } - --static int intel_vsec_add_aux(struct pci_dev *pdev, struct intel_vsec_device *intel_vsec_dev, -- const char *name) -+int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, -+ struct intel_vsec_device *intel_vsec_dev, -+ const char *name) - { - struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev; - int ret, id; - -- ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); -+ ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev, -+ PMT_XA_LIMIT, GFP_KERNEL); - if (ret < 0) { - kfree(intel_vsec_dev->resource); - kfree(intel_vsec_dev); - return ret; - } - -- auxdev->id = ret; -+ mutex_lock(&vsec_ida_lock); -+ id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); -+ mutex_unlock(&vsec_ida_lock); -+ if (id < 0) { -+ xa_erase(&auxdev_array, intel_vsec_dev->id); -+ kfree(intel_vsec_dev->resource); -+ kfree(intel_vsec_dev); -+ return id; -+ } -+ -+ if (!parent) -+ parent = &pdev->dev; -+ -+ auxdev->id = id; - auxdev->name = name; -- auxdev->dev.parent = &pdev->dev; -+ auxdev->dev.parent = parent; - auxdev->dev.release = intel_vsec_dev_release; - - ret = auxiliary_device_init(auxdev); - if (ret < 0) { -+ mutex_lock(&vsec_ida_lock); - ida_free(intel_vsec_dev->ida, auxdev->id); -+ mutex_unlock(&vsec_ida_lock); - kfree(intel_vsec_dev->resource); - kfree(intel_vsec_dev); - return ret; -@@ -165,19 +189,14 @@ static int intel_vsec_add_aux(struct pci_dev *pdev, struct intel_vsec_device *in - return ret; - } - -- ret = devm_add_action_or_reset(&pdev->dev, intel_vsec_remove_aux, -+ ret = devm_add_action_or_reset(parent, intel_vsec_remove_aux, - auxdev); - if (ret < 0) - return ret; - -- /* Add auxdev to list */ -- ret = xa_alloc(&auxdev_array, &id, intel_vsec_dev, PMT_XA_LIMIT, -- GFP_KERNEL); -- if (ret) -- return ret; -- - return 0; - } -+EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC); - - static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header, - struct intel_vsec_platform_info *info) -@@ -235,7 +254,8 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he - else - intel_vsec_dev->ida = &intel_vsec_ida; - -- return intel_vsec_add_aux(pdev, intel_vsec_dev, intel_vsec_name(header->id)); -+ return intel_vsec_add_aux(pdev, NULL, intel_vsec_dev, -+ intel_vsec_name(header->id)); - } - - static bool intel_vsec_walk_header(struct pci_dev *pdev, -diff --git a/drivers/platform/x86/intel/vsec.h b/drivers/platform/x86/intel/vsec.h -index 3deeb05cf394d..330672588868d 100644 ---- a/drivers/platform/x86/intel/vsec.h -+++ b/drivers/platform/x86/intel/vsec.h -@@ -38,8 +38,15 @@ struct intel_vsec_device { - struct ida *ida; - struct intel_vsec_platform_info *info; - int num_resources; -+ int id; /* xa */ -+ void *priv_data; -+ size_t priv_data_size; - }; - -+int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, -+ struct intel_vsec_device *intel_vsec_dev, -+ const char *name); -+ - static inline struct intel_vsec_device *dev_to_ivdev(struct device *dev) - { - return container_of(dev, struct intel_vsec_device, auxdev.dev); -diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c -index 01ad84fd147c8..686eb8d86e221 100644 ---- a/drivers/power/supply/bq256xx_charger.c -+++ b/drivers/power/supply/bq256xx_charger.c -@@ -1514,13 +1514,16 @@ static int bq256xx_hw_init(struct bq256xx_device *bq) - wd_reg_val = i; - break; - } -- if (bq->watchdog_timer > bq256xx_watchdog_time[i] && -+ if (i + 1 < BQ256XX_NUM_WD_VAL && -+ bq->watchdog_timer > bq256xx_watchdog_time[i] && - bq->watchdog_timer < bq256xx_watchdog_time[i + 1]) - wd_reg_val = i; - } - ret = regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_1, - BQ256XX_WATCHDOG_MASK, wd_reg_val << - BQ256XX_WDT_BIT_SHIFT); -+ if (ret) -+ return ret; - - ret = power_supply_get_battery_info(bq->charger, &bat_info); - if (ret == -ENOMEM) -diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c -index 473522b4326ad..9d957cf8edf07 100644 ---- a/drivers/power/supply/cw2015_battery.c -+++ b/drivers/power/supply/cw2015_battery.c -@@ -491,7 +491,7 @@ static int cw_battery_get_property(struct power_supply *psy, - - case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: - if (cw_battery_valid_time_to_empty(cw_bat)) -- val->intval = cw_bat->time_to_empty; -+ val->intval = cw_bat->time_to_empty * 60; - else - val->intval = 0; - break; -diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c -index d333e7422f4a9..9726f96bf7635 100644 ---- a/drivers/pwm/core.c -+++ b/drivers/pwm/core.c -@@ -171,7 +171,7 @@ of_pwm_single_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) - pwm->args.period = args->args[0]; - pwm->args.polarity = PWM_POLARITY_NORMAL; - -- if (args->args_count == 2 && args->args[2] & PWM_POLARITY_INVERTED) -+ if (args->args_count == 2 && args->args[1] & PWM_POLARITY_INVERTED) - pwm->args.polarity = PWM_POLARITY_INVERSED; - - return pwm; -diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c -index a5fdf97c0d2ec..246499128142c 100644 ---- a/drivers/pwm/pwm-jz4740.c -+++ b/drivers/pwm/pwm-jz4740.c -@@ -60,9 +60,10 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) - snprintf(name, sizeof(name), "timer%u", pwm->hwpwm); - - clk = clk_get(chip->dev, name); -- if (IS_ERR(clk)) -- return dev_err_probe(chip->dev, PTR_ERR(clk), -- "Failed to get clock\n"); -+ if (IS_ERR(clk)) { -+ dev_err(chip->dev, "error %pe: Failed to get clock\n", clk); -+ return PTR_ERR(clk); -+ } - - err = clk_prepare_enable(clk); - if (err < 0) { -diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c -index 794ca5b029681..bdcdb7f38312b 100644 ---- a/drivers/pwm/pwm-stm32.c -+++ b/drivers/pwm/pwm-stm32.c -@@ -115,14 +115,14 @@ static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm, - int ret; - - /* Ensure registers have been updated, enable counter and capture */ -- regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); -- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); -+ regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG); -+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); - - /* Use cc1 or cc3 DMA resp for PWM input channels 1 & 2 or 3 & 4 */ - dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3; - ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E; - ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3; -- regmap_update_bits(priv->regmap, TIM_CCER, ccen, ccen); -+ regmap_set_bits(priv->regmap, TIM_CCER, ccen); - - /* - * Timer DMA burst mode. Request 2 registers, 2 bursts, to get both -@@ -160,8 +160,8 @@ static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm, - } - - stop: -- regmap_update_bits(priv->regmap, TIM_CCER, ccen, 0); -- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); -+ regmap_clear_bits(priv->regmap, TIM_CCER, ccen); -+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); - - return ret; - } -@@ -359,7 +359,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch, - - regmap_write(priv->regmap, TIM_PSC, prescaler); - regmap_write(priv->regmap, TIM_ARR, prd - 1); -- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); -+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE); - - /* Calculate the duty cycles */ - dty = prd * duty_ns; -@@ -377,7 +377,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch, - else - regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr); - -- regmap_update_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE, TIM_BDTR_MOE); -+ regmap_set_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE); - - return 0; - } -@@ -411,13 +411,13 @@ static int stm32_pwm_enable(struct stm32_pwm *priv, int ch) - if (priv->have_complementary_output) - mask |= TIM_CCER_CC1NE << (ch * 4); - -- regmap_update_bits(priv->regmap, TIM_CCER, mask, mask); -+ regmap_set_bits(priv->regmap, TIM_CCER, mask); - - /* Make sure that registers are updated */ -- regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); -+ regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG); - - /* Enable controller */ -- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); -+ regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); - - return 0; - } -@@ -431,11 +431,11 @@ static void stm32_pwm_disable(struct stm32_pwm *priv, int ch) - if (priv->have_complementary_output) - mask |= TIM_CCER_CC1NE << (ch * 4); - -- regmap_update_bits(priv->regmap, TIM_CCER, mask, 0); -+ regmap_clear_bits(priv->regmap, TIM_CCER, mask); - - /* When all channels are disabled, we can disable the controller */ - if (!active_channels(priv)) -- regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); -+ regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); - - clk_disable(priv->clk); - } -@@ -568,41 +568,30 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) - * If complementary bit doesn't exist writing 1 will have no - * effect so we can detect it. - */ -- regmap_update_bits(priv->regmap, -- TIM_CCER, TIM_CCER_CC1NE, TIM_CCER_CC1NE); -+ regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE); - regmap_read(priv->regmap, TIM_CCER, &ccer); -- regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE, 0); -+ regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE); - - priv->have_complementary_output = (ccer != 0); - } - --static int stm32_pwm_detect_channels(struct stm32_pwm *priv) -+static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv, -+ unsigned int *num_enabled) - { -- u32 ccer; -- int npwm = 0; -+ u32 ccer, ccer_backup; - - /* - * If channels enable bits don't exist writing 1 will have no - * effect so we can detect and count them. - */ -- regmap_update_bits(priv->regmap, -- TIM_CCER, TIM_CCER_CCXE, TIM_CCER_CCXE); -+ regmap_read(priv->regmap, TIM_CCER, &ccer_backup); -+ regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); - regmap_read(priv->regmap, TIM_CCER, &ccer); -- regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0); -- -- if (ccer & TIM_CCER_CC1E) -- npwm++; -+ regmap_write(priv->regmap, TIM_CCER, ccer_backup); - -- if (ccer & TIM_CCER_CC2E) -- npwm++; -+ *num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE); - -- if (ccer & TIM_CCER_CC3E) -- npwm++; -- -- if (ccer & TIM_CCER_CC4E) -- npwm++; -- -- return npwm; -+ return hweight32(ccer & TIM_CCER_CCXE); - } - - static int stm32_pwm_probe(struct platform_device *pdev) -@@ -611,6 +600,8 @@ static int stm32_pwm_probe(struct platform_device *pdev) - struct device_node *np = dev->of_node; - struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); - struct stm32_pwm *priv; -+ unsigned int num_enabled; -+ unsigned int i; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -@@ -633,7 +624,11 @@ static int stm32_pwm_probe(struct platform_device *pdev) - - priv->chip.dev = dev; - priv->chip.ops = &stm32pwm_ops; -- priv->chip.npwm = stm32_pwm_detect_channels(priv); -+ priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); -+ -+ /* Initialize clock refcount to number of enabled PWM channels. */ -+ for (i = 0; i < num_enabled; i++) -+ clk_enable(priv->clk); - - ret = pwmchip_add(&priv->chip); - if (ret < 0) -diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c -index 6fedc3b7d1ab2..eb895a65ea8fc 100644 ---- a/drivers/scsi/fnic/fnic_debugfs.c -+++ b/drivers/scsi/fnic/fnic_debugfs.c -@@ -52,9 +52,10 @@ int fnic_debugfs_init(void) - fc_trc_flag->fnic_trace = 2; - fc_trc_flag->fc_trace = 3; - fc_trc_flag->fc_clear = 4; -+ return 0; - } - -- return 0; -+ return -ENOMEM; - } - - /* -diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c -index a8142e2b96435..450a8578157cb 100644 ---- a/drivers/scsi/hisi_sas/hisi_sas_main.c -+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c -@@ -1502,12 +1502,12 @@ EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); - static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) - { - if (!hisi_hba->hw->soft_reset) -- return -1; -+ return -ENOENT; - - down(&hisi_hba->sem); - if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { - up(&hisi_hba->sem); -- return -1; -+ return -EPERM; - } - - if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) -diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -index c4305ec38ebf3..0c80ff9affa39 100644 ---- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c -@@ -3330,7 +3330,7 @@ static void debugfs_snapshot_global_reg_v3_hw(struct hisi_hba *hisi_hba) - u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; - int i; - -- for (i = 0; i < debugfs_axi_reg.count; i++, databuf++) -+ for (i = 0; i < debugfs_global_reg.count; i++, databuf++) - *databuf = hisi_sas_read32(hisi_hba, 4 * i); - } - -@@ -4946,6 +4946,7 @@ static void hisi_sas_reset_done_v3_hw(struct pci_dev *pdev) - { - struct sas_ha_struct *sha = pci_get_drvdata(pdev); - struct hisi_hba *hisi_hba = sha->lldd_ha; -+ struct Scsi_Host *shost = hisi_hba->shost; - struct device *dev = hisi_hba->dev; - int rc; - -@@ -4954,6 +4955,10 @@ static void hisi_sas_reset_done_v3_hw(struct pci_dev *pdev) - rc = hw_init_v3_hw(hisi_hba); - if (rc) { - dev_err(dev, "FLR: hw init failed rc=%d\n", rc); -+ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); -+ scsi_unblock_requests(shost); -+ clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); -+ up(&hisi_hba->sem); - return; - } - -@@ -4981,7 +4986,7 @@ static int _suspend_v3_hw(struct device *device) - } - - if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) -- return -1; -+ return -EPERM; - - dev_warn(dev, "entering suspend state\n"); - -diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c -index d10c6afb7f9cd..8c662d08706f1 100644 ---- a/drivers/scsi/mpi3mr/mpi3mr_app.c -+++ b/drivers/scsi/mpi3mr/mpi3mr_app.c -@@ -223,6 +223,22 @@ static long mpi3mr_bsg_pel_enable(struct mpi3mr_ioc *mrioc, - return rval; - } - -+ if (mrioc->unrecoverable) { -+ dprint_bsg_err(mrioc, "%s: unrecoverable controller\n", -+ __func__); -+ return -EFAULT; -+ } -+ -+ if (mrioc->reset_in_progress) { -+ dprint_bsg_err(mrioc, "%s: reset in progress\n", __func__); -+ return -EAGAIN; -+ } -+ -+ if (mrioc->stop_bsgs) { -+ dprint_bsg_err(mrioc, "%s: bsgs are blocked\n", __func__); -+ return -EAGAIN; -+ } -+ - sg_copy_to_buffer(job->request_payload.sg_list, - job->request_payload.sg_cnt, - &pel_enable, sizeof(pel_enable)); -diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c -index 6d55698ea4d16..85f5b349c7e43 100644 ---- a/drivers/scsi/mpi3mr/mpi3mr_os.c -+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c -@@ -1044,8 +1044,14 @@ void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc) - tgtdev = NULL; - list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) { - if ((tgtdev->dev_handle != MPI3MR_INVALID_DEV_HANDLE) && -- !tgtdev->is_hidden && !tgtdev->host_exposed) -- mpi3mr_report_tgtdev_to_host(mrioc, tgtdev->perst_id); -+ !tgtdev->is_hidden) { -+ if (!tgtdev->host_exposed) -+ mpi3mr_report_tgtdev_to_host(mrioc, -+ tgtdev->perst_id); -+ else if (tgtdev->starget) -+ starget_for_each_device(tgtdev->starget, -+ (void *)tgtdev, mpi3mr_update_sdev); -+ } - } - } - -diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c -index bc400669ee022..16a05143d0d62 100644 ---- a/drivers/soc/qcom/llcc-qcom.c -+++ b/drivers/soc/qcom/llcc-qcom.c -@@ -680,14 +680,14 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config, - u32 disable_cap_alloc, retain_pc; - - disable_cap_alloc = config->dis_cap_alloc << config->slice_id; -- ret = regmap_write(drv_data->bcast_regmap, -- LLCC_TRP_SCID_DIS_CAP_ALLOC, disable_cap_alloc); -+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_SCID_DIS_CAP_ALLOC, -+ BIT(config->slice_id), disable_cap_alloc); - if (ret) - return ret; - - retain_pc = config->retain_on_pc << config->slice_id; -- ret = regmap_write(drv_data->bcast_regmap, -- LLCC_TRP_PCB_ACT, retain_pc); -+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_PCB_ACT, -+ BIT(config->slice_id), retain_pc); - if (ret) - return ret; - } -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 946e2186d2448..15ea11ebcbe09 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -1101,9 +1101,10 @@ config SPI_ZYNQ_QSPI - - config SPI_ZYNQMP_GQSPI - tristate "Xilinx ZynqMP GQSPI controller" -- depends on (SPI_MASTER && HAS_DMA) || COMPILE_TEST -+ depends on (SPI_MEM && HAS_DMA) || COMPILE_TEST - help - Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC. -+ This controller only supports SPI memory interface. - - config SPI_AMD - tristate "AMD SPI controller" -diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c -index 9bca3d076f053..51ceaa4857249 100644 ---- a/drivers/spi/spi-sh-msiof.c -+++ b/drivers/spi/spi-sh-msiof.c -@@ -30,12 +30,15 @@ - - #include - -+#define SH_MSIOF_FLAG_FIXED_DTDL_200 BIT(0) -+ - struct sh_msiof_chipdata { - u32 bits_per_word_mask; - u16 tx_fifo_size; - u16 rx_fifo_size; - u16 ctlr_flags; - u16 min_div_pow; -+ u32 flags; - }; - - struct sh_msiof_spi_priv { -@@ -1073,6 +1076,16 @@ static const struct sh_msiof_chipdata rcar_gen3_data = { - .min_div_pow = 1, - }; - -+static const struct sh_msiof_chipdata rcar_r8a7795_data = { -+ .bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) | -+ SPI_BPW_MASK(24) | SPI_BPW_MASK(32), -+ .tx_fifo_size = 64, -+ .rx_fifo_size = 64, -+ .ctlr_flags = SPI_CONTROLLER_MUST_TX, -+ .min_div_pow = 1, -+ .flags = SH_MSIOF_FLAG_FIXED_DTDL_200, -+}; -+ - static const struct of_device_id sh_msiof_match[] = { - { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, - { .compatible = "renesas,msiof-r8a7743", .data = &rcar_gen2_data }, -@@ -1083,6 +1096,7 @@ static const struct of_device_id sh_msiof_match[] = { - { .compatible = "renesas,msiof-r8a7793", .data = &rcar_gen2_data }, - { .compatible = "renesas,msiof-r8a7794", .data = &rcar_gen2_data }, - { .compatible = "renesas,rcar-gen2-msiof", .data = &rcar_gen2_data }, -+ { .compatible = "renesas,msiof-r8a7795", .data = &rcar_r8a7795_data }, - { .compatible = "renesas,msiof-r8a7796", .data = &rcar_gen3_data }, - { .compatible = "renesas,rcar-gen3-msiof", .data = &rcar_gen3_data }, - { .compatible = "renesas,rcar-gen4-msiof", .data = &rcar_gen3_data }, -@@ -1280,6 +1294,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) - return -ENXIO; - } - -+ if (chipdata->flags & SH_MSIOF_FLAG_FIXED_DTDL_200) -+ info->dtdl = 200; -+ - if (info->mode == MSIOF_SPI_SLAVE) - ctlr = spi_alloc_slave(&pdev->dev, - sizeof(struct sh_msiof_spi_priv)); -diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c -index ad511f2c3324e..01e8851e639d5 100644 ---- a/drivers/spmi/spmi-mtk-pmif.c -+++ b/drivers/spmi/spmi-mtk-pmif.c -@@ -50,6 +50,7 @@ struct pmif { - struct clk_bulk_data clks[PMIF_MAX_CLKS]; - size_t nclks; - const struct pmif_data *data; -+ raw_spinlock_t lock; - }; - - static const char * const pmif_clock_names[] = { -@@ -314,6 +315,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, - struct ch_reg *inf_reg; - int ret; - u32 data, cmd; -+ unsigned long flags; - - /* Check for argument validation. */ - if (sid & ~0xf) { -@@ -334,6 +336,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, - else - return -EINVAL; - -+ raw_spin_lock_irqsave(&arb->lock, flags); - /* Wait for Software Interface FSM state to be IDLE. */ - inf_reg = &arb->chan; - ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], -@@ -343,6 +346,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, - /* set channel ready if the data has transferred */ - if (pmif_is_fsm_vldclr(arb)) - pmif_writel(arb, 1, inf_reg->ch_rdy); -+ raw_spin_unlock_irqrestore(&arb->lock, flags); - dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); - return ret; - } -@@ -350,6 +354,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, - /* Send the command. */ - cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr; - pmif_writel(arb, cmd, inf_reg->ch_send); -+ raw_spin_unlock_irqrestore(&arb->lock, flags); - - /* - * Wait for Software Interface FSM state to be WFVLDCLR, -@@ -376,7 +381,8 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, - struct pmif *arb = spmi_controller_get_drvdata(ctrl); - struct ch_reg *inf_reg; - int ret; -- u32 data, cmd; -+ u32 data, wdata, cmd; -+ unsigned long flags; - - if (len > 4) { - dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len); -@@ -394,6 +400,10 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, - else - return -EINVAL; - -+ /* Set the write data. */ -+ memcpy(&wdata, buf, len); -+ -+ raw_spin_lock_irqsave(&arb->lock, flags); - /* Wait for Software Interface FSM state to be IDLE. */ - inf_reg = &arb->chan; - ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], -@@ -403,17 +413,17 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, - /* set channel ready if the data has transferred */ - if (pmif_is_fsm_vldclr(arb)) - pmif_writel(arb, 1, inf_reg->ch_rdy); -+ raw_spin_unlock_irqrestore(&arb->lock, flags); - dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); - return ret; - } - -- /* Set the write data. */ -- memcpy(&data, buf, len); -- pmif_writel(arb, data, inf_reg->wdata); -+ pmif_writel(arb, wdata, inf_reg->wdata); - - /* Send the command. */ - cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr; - pmif_writel(arb, cmd, inf_reg->ch_send); -+ raw_spin_unlock_irqrestore(&arb->lock, flags); - - return 0; - } -@@ -488,6 +498,8 @@ static int mtk_spmi_probe(struct platform_device *pdev) - arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset; - arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset; - -+ raw_spin_lock_init(&arb->lock); -+ - platform_set_drvdata(pdev, ctrl); - - err = spmi_controller_add(ctrl); -diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c -index a9bd1e71ea487..d16cf4115d03a 100644 ---- a/drivers/staging/media/rkvdec/rkvdec.c -+++ b/drivers/staging/media/rkvdec/rkvdec.c -@@ -461,6 +461,9 @@ static const struct v4l2_ioctl_ops rkvdec_ioctl_ops = { - - .vidioc_streamon = v4l2_m2m_ioctl_streamon, - .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, -+ -+ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, -+ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, - }; - - static int rkvdec_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, -diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c -index 7e81a53dbf3ca..8d74e97c98748 100644 ---- a/drivers/target/target_core_file.c -+++ b/drivers/target/target_core_file.c -@@ -338,11 +338,13 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd, - } - - iov_iter_bvec(&iter, is_write, bvec, sgl_nents, len); -- if (is_write) -+ if (is_write) { -+ file_start_write(fd); - ret = vfs_iter_write(fd, &iter, &pos, 0); -- else -+ file_end_write(fd); -+ } else { - ret = vfs_iter_read(fd, &iter, &pos, 0); -- -+ } - if (is_write) { - if (ret < 0 || ret != data_length) { - pr_err("%s() write returned %d\n", __func__, ret); -@@ -474,7 +476,9 @@ fd_execute_write_same(struct se_cmd *cmd) - } - - iov_iter_bvec(&iter, ITER_SOURCE, bvec, nolb, len); -+ file_start_write(fd_dev->fd_file); - ret = vfs_iter_write(fd_dev->fd_file, &iter, &pos, 0); -+ file_end_write(fd_dev->fd_file); - - kfree(bvec); - if (ret < 0 || ret != len) { -diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c -index 15a2387a5b258..4f4502fb5454c 100644 ---- a/drivers/tty/serial/8250/8250_bcm2835aux.c -+++ b/drivers/tty/serial/8250/8250_bcm2835aux.c -@@ -119,6 +119,8 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev) - - /* get the clock - this also enables the HW */ - data->clk = devm_clk_get_optional(&pdev->dev, NULL); -+ if (IS_ERR(data->clk)) -+ return dev_err_probe(&pdev->dev, PTR_ERR(data->clk), "could not get clk\n"); - - /* get the interrupt */ - ret = platform_get_irq(pdev, 0); -diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c -index b406cba10b0eb..dca1abe363248 100644 ---- a/drivers/tty/serial/8250/8250_exar.c -+++ b/drivers/tty/serial/8250/8250_exar.c -@@ -442,7 +442,7 @@ static int generic_rs485_config(struct uart_port *port, struct ktermios *termios - } - - static const struct serial_rs485 generic_rs485_supported = { -- .flags = SER_RS485_ENABLED, -+ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, - }; - - static const struct exar8250_platform exar8250_default_platform = { -@@ -486,7 +486,8 @@ static int iot2040_rs485_config(struct uart_port *port, struct ktermios *termios - } - - static const struct serial_rs485 iot2040_rs485_supported = { -- .flags = SER_RS485_ENABLED | SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS, -+ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | -+ SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS, - }; - - static const struct property_entry iot2040_gpio_properties[] = { -diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c -index 0b04d810b3e61..037d613006f56 100644 ---- a/drivers/tty/serial/8250/8250_omap.c -+++ b/drivers/tty/serial/8250/8250_omap.c -@@ -1476,7 +1476,7 @@ static int omap8250_remove(struct platform_device *pdev) - - err = pm_runtime_resume_and_get(&pdev->dev); - if (err) -- return err; -+ dev_err(&pdev->dev, "Failed to resume hardware\n"); - - serial8250_unregister_port(priv->line); - priv->line = -ENODEV; -diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c -index d2137f6eff327..f8962a3d44216 100644 ---- a/drivers/tty/serial/imx.c -+++ b/drivers/tty/serial/imx.c -@@ -450,13 +450,13 @@ static void imx_uart_stop_tx(struct uart_port *port) - ucr1 = imx_uart_readl(sport, UCR1); - imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1); - -+ ucr4 = imx_uart_readl(sport, UCR4); - usr2 = imx_uart_readl(sport, USR2); -- if (!(usr2 & USR2_TXDC)) { -+ if ((!(usr2 & USR2_TXDC)) && (ucr4 & UCR4_TCEN)) { - /* The shifter is still busy, so retry once TC triggers */ - return; - } - -- ucr4 = imx_uart_readl(sport, UCR4); - ucr4 &= ~UCR4_TCEN; - imx_uart_writel(sport, ucr4, UCR4); - -@@ -2229,7 +2229,6 @@ static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) - return HRTIMER_NORESTART; - } - --static const struct serial_rs485 imx_no_rs485 = {}; /* No RS485 if no RTS */ - static const struct serial_rs485 imx_rs485_supported = { - .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | - SER_RS485_RX_DURING_TX, -@@ -2319,8 +2318,6 @@ static int imx_uart_probe(struct platform_device *pdev) - /* RTS is required to control the RS485 transmitter */ - if (sport->have_rtscts || sport->have_rtsgpio) - sport->port.rs485_supported = imx_rs485_supported; -- else -- sport->port.rs485_supported = imx_no_rs485; - sport->port.flags = UPF_BOOT_AUTOCONF; - timer_setup(&sport->timer, imx_uart_timeout, 0); - -@@ -2347,7 +2344,7 @@ static int imx_uart_probe(struct platform_device *pdev) - /* For register access, we only need to enable the ipg clock. */ - ret = clk_prepare_enable(sport->clk_ipg); - if (ret) { -- dev_err(&pdev->dev, "failed to enable per clk: %d\n", ret); -+ dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret); - return ret; - } - -@@ -2359,14 +2356,8 @@ static int imx_uart_probe(struct platform_device *pdev) - sport->ufcr = readl(sport->port.membase + UFCR); - - ret = uart_get_rs485_mode(&sport->port); -- if (ret) { -- clk_disable_unprepare(sport->clk_ipg); -- return ret; -- } -- -- if (sport->port.rs485.flags & SER_RS485_ENABLED && -- (!sport->have_rtscts && !sport->have_rtsgpio)) -- dev_err(&pdev->dev, "no RTS control, disabling rs485\n"); -+ if (ret) -+ goto err_clk; - - /* - * If using the i.MX UART RTS/CTS control then the RTS (CTS_B) -@@ -2446,8 +2437,6 @@ static int imx_uart_probe(struct platform_device *pdev) - imx_uart_writel(sport, ucr3, UCR3); - } - -- clk_disable_unprepare(sport->clk_ipg); -- - hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - sport->trigger_start_tx.function = imx_trigger_start_tx; -@@ -2463,7 +2452,7 @@ static int imx_uart_probe(struct platform_device *pdev) - if (ret) { - dev_err(&pdev->dev, "failed to request rx irq: %d\n", - ret); -- return ret; -+ goto err_clk; - } - - ret = devm_request_irq(&pdev->dev, txirq, imx_uart_txint, 0, -@@ -2471,7 +2460,7 @@ static int imx_uart_probe(struct platform_device *pdev) - if (ret) { - dev_err(&pdev->dev, "failed to request tx irq: %d\n", - ret); -- return ret; -+ goto err_clk; - } - - ret = devm_request_irq(&pdev->dev, rtsirq, imx_uart_rtsint, 0, -@@ -2479,14 +2468,14 @@ static int imx_uart_probe(struct platform_device *pdev) - if (ret) { - dev_err(&pdev->dev, "failed to request rts irq: %d\n", - ret); -- return ret; -+ goto err_clk; - } - } else { - ret = devm_request_irq(&pdev->dev, rxirq, imx_uart_int, 0, - dev_name(&pdev->dev), sport); - if (ret) { - dev_err(&pdev->dev, "failed to request irq: %d\n", ret); -- return ret; -+ goto err_clk; - } - } - -@@ -2494,7 +2483,12 @@ static int imx_uart_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, sport); - -- return uart_add_one_port(&imx_uart_uart_driver, &sport->port); -+ ret = uart_add_one_port(&imx_uart_uart_driver, &sport->port); -+ -+err_clk: -+ clk_disable_unprepare(sport->clk_ipg); -+ -+ return ret; - } - - static int imx_uart_remove(struct platform_device *pdev) -diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c -index 7d0d2718ef595..beb7896ebf8ae 100644 ---- a/drivers/tty/serial/omap-serial.c -+++ b/drivers/tty/serial/omap-serial.c -@@ -1512,6 +1512,13 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) - return omap_up_info; - } - -+static const struct serial_rs485 serial_omap_rs485_supported = { -+ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | -+ SER_RS485_RX_DURING_TX, -+ .delay_rts_before_send = 1, -+ .delay_rts_after_send = 1, -+}; -+ - static int serial_omap_probe_rs485(struct uart_omap_port *up, - struct device *dev) - { -@@ -1526,6 +1533,9 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, - if (!np) - return 0; - -+ up->port.rs485_config = serial_omap_config_rs485; -+ up->port.rs485_supported = serial_omap_rs485_supported; -+ - ret = uart_get_rs485_mode(&up->port); - if (ret) - return ret; -@@ -1560,13 +1570,6 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, - return 0; - } - --static const struct serial_rs485 serial_omap_rs485_supported = { -- .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | -- SER_RS485_RX_DURING_TX, -- .delay_rts_before_send = 1, -- .delay_rts_after_send = 1, --}; -- - static int serial_omap_probe(struct platform_device *pdev) - { - struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev); -@@ -1634,17 +1637,11 @@ static int serial_omap_probe(struct platform_device *pdev) - dev_info(up->port.dev, "no wakeirq for uart%d\n", - up->port.line); - -- ret = serial_omap_probe_rs485(up, &pdev->dev); -- if (ret < 0) -- goto err_rs485; -- - sprintf(up->name, "OMAP UART%d", up->port.line); - up->port.mapbase = mem->start; - up->port.membase = base; - up->port.flags = omap_up_info->flags; - up->port.uartclk = omap_up_info->uartclk; -- up->port.rs485_config = serial_omap_config_rs485; -- up->port.rs485_supported = serial_omap_rs485_supported; - if (!up->port.uartclk) { - up->port.uartclk = DEFAULT_CLK_SPEED; - dev_warn(&pdev->dev, -@@ -1652,6 +1649,10 @@ static int serial_omap_probe(struct platform_device *pdev) - DEFAULT_CLK_SPEED); - } - -+ ret = serial_omap_probe_rs485(up, &pdev->dev); -+ if (ret < 0) -+ goto err_rs485; -+ - up->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; - up->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; - cpu_latency_qos_add_request(&up->pm_qos_request, up->latency); -diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c -index b4b849415c503..db33790e66754 100644 ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - - #define SC16IS7XX_NAME "sc16is7xx" -@@ -1716,9 +1717,12 @@ static int sc16is7xx_spi_probe(struct spi_device *spi) - - /* Setup SPI bus */ - spi->bits_per_word = 8; -- /* only supports mode 0 on SC16IS762 */ -+ /* For all variants, only mode 0 is supported */ -+ if ((spi->mode & SPI_MODE_X_MASK) != SPI_MODE_0) -+ return dev_err_probe(&spi->dev, -EINVAL, "Unsupported SPI mode\n"); -+ - spi->mode = spi->mode ? : SPI_MODE_0; -- spi->max_speed_hz = spi->max_speed_hz ? : 15000000; -+ spi->max_speed_hz = spi->max_speed_hz ? : 4 * HZ_PER_MHZ; - ret = spi_setup(spi); - if (ret) - return ret; -diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c -index d4e57f9017db9..f0ed30d0a697c 100644 ---- a/drivers/tty/serial/serial_core.c -+++ b/drivers/tty/serial/serial_core.c -@@ -1353,19 +1353,27 @@ static void uart_sanitize_serial_rs485(struct uart_port *port, struct serial_rs4 - return; - } - -+ rs485->flags &= supported_flags; -+ - /* Pick sane settings if the user hasn't */ -- if ((supported_flags & (SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND)) && -- !(rs485->flags & SER_RS485_RTS_ON_SEND) == -+ if (!(rs485->flags & SER_RS485_RTS_ON_SEND) == - !(rs485->flags & SER_RS485_RTS_AFTER_SEND)) { -- dev_warn_ratelimited(port->dev, -- "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", -- port->name, port->line); -- rs485->flags |= SER_RS485_RTS_ON_SEND; -- rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; -- supported_flags |= SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND; -- } -+ if (supported_flags & SER_RS485_RTS_ON_SEND) { -+ rs485->flags |= SER_RS485_RTS_ON_SEND; -+ rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; - -- rs485->flags &= supported_flags; -+ dev_warn_ratelimited(port->dev, -+ "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", -+ port->name, port->line); -+ } else { -+ rs485->flags |= SER_RS485_RTS_AFTER_SEND; -+ rs485->flags &= ~SER_RS485_RTS_ON_SEND; -+ -+ dev_warn_ratelimited(port->dev, -+ "%s (%d): invalid RTS setting, using RTS_AFTER_SEND instead\n", -+ port->name, port->line); -+ } -+ } - - uart_sanitize_serial_rs485_delays(port, rs485); - -@@ -1428,7 +1436,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, - int ret; - unsigned long flags; - -- if (!port->rs485_config) -+ if (!(port->rs485_supported.flags & SER_RS485_ENABLED)) - return -ENOTTY; - - if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user))) -@@ -3420,6 +3428,9 @@ int uart_get_rs485_mode(struct uart_port *port) - u32 rs485_delay[2]; - int ret; - -+ if (!(port->rs485_supported.flags & SER_RS485_ENABLED)) -+ return 0; -+ - ret = device_property_read_u32_array(dev, "rs485-rts-delay", - rs485_delay, 2); - if (!ret) { -diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h -index c5ee219127555..91515e1ebc8d3 100644 ---- a/drivers/tty/tty.h -+++ b/drivers/tty/tty.h -@@ -63,7 +63,7 @@ int tty_check_change(struct tty_struct *tty); - void __stop_tty(struct tty_struct *tty); - void __start_tty(struct tty_struct *tty); - void tty_write_unlock(struct tty_struct *tty); --int tty_write_lock(struct tty_struct *tty, int ndelay); -+int tty_write_lock(struct tty_struct *tty, bool ndelay); - void tty_vhangup_session(struct tty_struct *tty); - void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); - int tty_signal_session_leader(struct tty_struct *tty, int exit_session); -diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c -index 8fb6c6853556a..aaf77a5616ff1 100644 ---- a/drivers/tty/tty_io.c -+++ b/drivers/tty/tty_io.c -@@ -939,7 +939,7 @@ void tty_write_unlock(struct tty_struct *tty) - wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); - } - --int tty_write_lock(struct tty_struct *tty, int ndelay) -+int tty_write_lock(struct tty_struct *tty, bool ndelay) - { - if (!mutex_trylock(&tty->atomic_write_lock)) { - if (ndelay) -@@ -1153,7 +1153,7 @@ int tty_send_xchar(struct tty_struct *tty, char ch) - return 0; - } - -- if (tty_write_lock(tty, 0) < 0) -+ if (tty_write_lock(tty, false) < 0) - return -ERESTARTSYS; - - down_read(&tty->termios_rwsem); -@@ -2472,22 +2472,25 @@ static int send_break(struct tty_struct *tty, unsigned int duration) - return 0; - - if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) -- retval = tty->ops->break_ctl(tty, duration); -- else { -- /* Do the work ourselves */ -- if (tty_write_lock(tty, 0) < 0) -- return -EINTR; -- retval = tty->ops->break_ctl(tty, -1); -- if (retval) -- goto out; -- if (!signal_pending(current)) -- msleep_interruptible(duration); -+ return tty->ops->break_ctl(tty, duration); -+ -+ /* Do the work ourselves */ -+ if (tty_write_lock(tty, false) < 0) -+ return -EINTR; -+ -+ retval = tty->ops->break_ctl(tty, -1); -+ if (!retval) { -+ msleep_interruptible(duration); - retval = tty->ops->break_ctl(tty, 0); --out: -- tty_write_unlock(tty); -- if (signal_pending(current)) -- retval = -EINTR; -+ } else if (retval == -EOPNOTSUPP) { -+ /* some drivers can tell only dynamically */ -+ retval = 0; - } -+ tty_write_unlock(tty); -+ -+ if (signal_pending(current)) -+ retval = -EINTR; -+ - return retval; - } - -diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c -index ad1cf51ecd11d..8767c504b95dd 100644 ---- a/drivers/tty/tty_ioctl.c -+++ b/drivers/tty/tty_ioctl.c -@@ -506,7 +506,7 @@ retry_write_wait: - if (retval < 0) - return retval; - -- if (tty_write_lock(tty, 0) < 0) -+ if (tty_write_lock(tty, false) < 0) - goto retry_write_wait; - - /* Racing writer? */ -diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c -index dc38d1fa77874..474e94a69b185 100644 ---- a/drivers/ufs/core/ufshcd.c -+++ b/drivers/ufs/core/ufshcd.c -@@ -8204,7 +8204,6 @@ static int ufshcd_add_lus(struct ufs_hba *hba) - ufs_bsg_probe(hba); - ufshpb_init(hba); - scsi_scan_host(hba->host); -- pm_runtime_put_sync(hba->dev); - - out: - return ret; -@@ -8331,15 +8330,15 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) - - /* Probe and add UFS logical units */ - ret = ufshcd_add_lus(hba); -+ - out: -+ pm_runtime_put_sync(hba->dev); - /* - * If we failed to initialize the device or the device is not - * present, turn off the power/clocks etc. - */ -- if (ret) { -- pm_runtime_put_sync(hba->dev); -+ if (ret) - ufshcd_hba_exit(hba); -- } - } - - static const struct attribute_group *ufshcd_driver_groups[] = { -diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c -index 69a44bd7e5d02..ccdd525bd7c80 100644 ---- a/drivers/usb/cdns3/cdns3-gadget.c -+++ b/drivers/usb/cdns3/cdns3-gadget.c -@@ -1117,6 +1117,8 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, - dma_addr_t trb_dma; - u32 togle_pcs = 1; - int sg_iter = 0; -+ int num_trb_req; -+ int trb_burst; - int num_trb; - int address; - u32 control; -@@ -1125,15 +1127,13 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, - struct scatterlist *s = NULL; - bool sg_supported = !!(request->num_mapped_sgs); - -+ num_trb_req = sg_supported ? request->num_mapped_sgs : 1; -+ -+ /* ISO transfer require each SOF have a TD, each TD include some TRBs */ - if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) -- num_trb = priv_ep->interval; -+ num_trb = priv_ep->interval * num_trb_req; - else -- num_trb = sg_supported ? request->num_mapped_sgs : 1; -- -- if (num_trb > priv_ep->free_trbs) { -- priv_ep->flags |= EP_RING_FULL; -- return -ENOBUFS; -- } -+ num_trb = num_trb_req; - - priv_req = to_cdns3_request(request); - address = priv_ep->endpoint.desc->bEndpointAddress; -@@ -1182,14 +1182,31 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, - - link_trb->control = cpu_to_le32(((priv_ep->pcs) ? TRB_CYCLE : 0) | - TRB_TYPE(TRB_LINK) | TRB_TOGGLE | ch_bit); -+ -+ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { -+ /* -+ * ISO require LINK TRB must be first one of TD. -+ * Fill LINK TRBs for left trb space to simply software process logic. -+ */ -+ while (priv_ep->enqueue) { -+ *trb = *link_trb; -+ trace_cdns3_prepare_trb(priv_ep, trb); -+ -+ cdns3_ep_inc_enq(priv_ep); -+ trb = priv_ep->trb_pool + priv_ep->enqueue; -+ priv_req->trb = trb; -+ } -+ } -+ } -+ -+ if (num_trb > priv_ep->free_trbs) { -+ priv_ep->flags |= EP_RING_FULL; -+ return -ENOBUFS; - } - - if (priv_dev->dev_ver <= DEV_VER_V2) - togle_pcs = cdns3_wa1_update_guard(priv_ep, trb); - -- if (sg_supported) -- s = request->sg; -- - /* set incorrect Cycle Bit for first trb*/ - control = priv_ep->pcs ? 0 : TRB_CYCLE; - trb->length = 0; -@@ -1207,6 +1224,9 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, - do { - u32 length; - -+ if (!(sg_iter % num_trb_req) && sg_supported) -+ s = request->sg; -+ - /* fill TRB */ - control |= TRB_TYPE(TRB_NORMAL); - if (sg_supported) { -@@ -1221,7 +1241,36 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, - total_tdl += DIV_ROUND_UP(length, - priv_ep->endpoint.maxpacket); - -- trb->length |= cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) | -+ trb_burst = priv_ep->trb_burst_size; -+ -+ /* -+ * Supposed DMA cross 4k bounder problem should be fixed at DEV_VER_V2, but still -+ * met problem when do ISO transfer if sg enabled. -+ * -+ * Data pattern likes below when sg enabled, package size is 1k and mult is 2 -+ * [UVC Header(8B) ] [data(3k - 8)] ... -+ * -+ * The received data at offset 0xd000 will get 0xc000 data, len 0x70. Error happen -+ * as below pattern: -+ * 0xd000: wrong -+ * 0xe000: wrong -+ * 0xf000: correct -+ * 0x10000: wrong -+ * 0x11000: wrong -+ * 0x12000: correct -+ * ... -+ * -+ * But it is still unclear about why error have not happen below 0xd000, it should -+ * cross 4k bounder. But anyway, the below code can fix this problem. -+ * -+ * To avoid DMA cross 4k bounder at ISO transfer, reduce burst len according to 16. -+ */ -+ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_dev->dev_ver <= DEV_VER_V2) -+ if (ALIGN_DOWN(trb->buffer, SZ_4K) != -+ ALIGN_DOWN(trb->buffer + length, SZ_4K)) -+ trb_burst = 16; -+ -+ trb->length |= cpu_to_le32(TRB_BURST_LEN(trb_burst) | - TRB_LEN(length)); - pcs = priv_ep->pcs ? TRB_CYCLE : 0; - -@@ -1248,7 +1297,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, - if (sg_supported) { - trb->control |= cpu_to_le32(TRB_ISP); - /* Don't set chain bit for last TRB */ -- if (sg_iter < num_trb - 1) -+ if ((sg_iter % num_trb_req) < num_trb_req - 1) - trb->control |= cpu_to_le32(TRB_CHAIN); - - s = sg_next(s); -@@ -1506,6 +1555,12 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, - - /* The TRB was changed as link TRB, and the request was handled at ep_dequeue */ - while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) { -+ -+ /* ISO ep_traddr may stop at LINK TRB */ -+ if (priv_ep->dequeue == cdns3_get_dma_pos(priv_dev, priv_ep) && -+ priv_ep->type == USB_ENDPOINT_XFER_ISOC) -+ break; -+ - trace_cdns3_complete_trb(priv_ep, trb); - cdns3_ep_inc_deq(priv_ep); - trb = priv_ep->trb_pool + priv_ep->dequeue; -@@ -1538,6 +1593,10 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, - } - - if (request_handled) { -+ /* TRBs are duplicated by priv_ep->interval time for ISO IN */ -+ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_ep->dir) -+ request->actual /= priv_ep->interval; -+ - cdns3_gadget_giveback(priv_ep, priv_req, 0); - request_handled = false; - transfer_end = false; -@@ -2033,11 +2092,10 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) - bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC); - struct cdns3_device *priv_dev = priv_ep->cdns3_dev; - u32 bEndpointAddress = priv_ep->num | priv_ep->dir; -- u32 max_packet_size = 0; -- u8 maxburst = 0; -+ u32 max_packet_size = priv_ep->wMaxPacketSize; -+ u8 maxburst = priv_ep->bMaxBurst; - u32 ep_cfg = 0; - u8 buffering; -- u8 mult = 0; - int ret; - - buffering = priv_dev->ep_buf_size - 1; -@@ -2059,8 +2117,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) - break; - default: - ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC); -- mult = priv_dev->ep_iso_burst - 1; -- buffering = mult + 1; -+ buffering = (priv_ep->bMaxBurst + 1) * (priv_ep->mult + 1) - 1; - } - - switch (priv_dev->gadget.speed) { -@@ -2071,17 +2128,8 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) - max_packet_size = is_iso_ep ? 1024 : 512; - break; - case USB_SPEED_SUPER: -- /* It's limitation that driver assumes in driver. */ -- mult = 0; -- max_packet_size = 1024; -- if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { -- maxburst = priv_dev->ep_iso_burst - 1; -- buffering = (mult + 1) * -- (maxburst + 1); -- -- if (priv_ep->interval > 1) -- buffering++; -- } else { -+ if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) { -+ max_packet_size = 1024; - maxburst = priv_dev->ep_buf_size - 1; - } - break; -@@ -2110,7 +2158,6 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) - if (priv_dev->dev_ver < DEV_VER_V2) - priv_ep->trb_burst_size = 16; - -- mult = min_t(u8, mult, EP_CFG_MULT_MAX); - buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX); - maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX); - -@@ -2144,7 +2191,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) - } - - ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) | -- EP_CFG_MULT(mult) | -+ EP_CFG_MULT(priv_ep->mult) | /* must match EP setting */ - EP_CFG_BUFFERING(buffering) | - EP_CFG_MAXBURST(maxburst); - -@@ -2234,6 +2281,13 @@ usb_ep *cdns3_gadget_match_ep(struct usb_gadget *gadget, - priv_ep->type = usb_endpoint_type(desc); - priv_ep->flags |= EP_CLAIMED; - priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0; -+ priv_ep->wMaxPacketSize = usb_endpoint_maxp(desc); -+ priv_ep->mult = USB_EP_MAXP_MULT(priv_ep->wMaxPacketSize); -+ priv_ep->wMaxPacketSize &= USB_ENDPOINT_MAXP_MASK; -+ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && comp_desc) { -+ priv_ep->mult = USB_SS_MULT(comp_desc->bmAttributes) - 1; -+ priv_ep->bMaxBurst = comp_desc->bMaxBurst; -+ } - - spin_unlock_irqrestore(&priv_dev->lock, flags); - return &priv_ep->endpoint; -@@ -3015,22 +3069,40 @@ static int cdns3_gadget_check_config(struct usb_gadget *gadget) - struct cdns3_endpoint *priv_ep; - struct usb_ep *ep; - int n_in = 0; -+ int iso = 0; -+ int out = 1; - int total; -+ int n; - - list_for_each_entry(ep, &gadget->ep_list, ep_list) { - priv_ep = ep_to_cdns3_ep(ep); -- if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN)) -- n_in++; -+ if (!(priv_ep->flags & EP_CLAIMED)) -+ continue; -+ -+ n = (priv_ep->mult + 1) * (priv_ep->bMaxBurst + 1); -+ if (ep->address & USB_DIR_IN) { -+ /* -+ * ISO transfer: DMA start move data when get ISO, only transfer -+ * data as min(TD size, iso). No benefit for allocate bigger -+ * internal memory than 'iso'. -+ */ -+ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) -+ iso += n; -+ else -+ n_in++; -+ } else { -+ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) -+ out = max_t(int, out, n); -+ } - } - - /* 2KB are reserved for EP0, 1KB for out*/ -- total = 2 + n_in + 1; -+ total = 2 + n_in + out + iso; - - if (total > priv_dev->onchip_buffers) - return -ENOMEM; - -- priv_dev->ep_buf_size = priv_dev->ep_iso_burst = -- (priv_dev->onchip_buffers - 2) / (n_in + 1); -+ priv_dev->ep_buf_size = (priv_dev->onchip_buffers - 2 - iso) / (n_in + out); - - return 0; - } -diff --git a/drivers/usb/cdns3/cdns3-gadget.h b/drivers/usb/cdns3/cdns3-gadget.h -index fbe4a8e3aa897..086a7bb838975 100644 ---- a/drivers/usb/cdns3/cdns3-gadget.h -+++ b/drivers/usb/cdns3/cdns3-gadget.h -@@ -1168,6 +1168,9 @@ struct cdns3_endpoint { - u8 dir; - u8 num; - u8 type; -+ u8 mult; -+ u8 bMaxBurst; -+ u16 wMaxPacketSize; - int interval; - - int free_trbs; -diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c -index b9227f41cf1c0..763d6858a8e6f 100644 ---- a/drivers/usb/chipidea/core.c -+++ b/drivers/usb/chipidea/core.c -@@ -523,6 +523,13 @@ static irqreturn_t ci_irq_handler(int irq, void *data) - u32 otgsc = 0; - - if (ci->in_lpm) { -+ /* -+ * If we already have a wakeup irq pending there, -+ * let's just return to wait resume finished firstly. -+ */ -+ if (ci->wakeup_int) -+ return IRQ_HANDLED; -+ - disable_irq_nosync(irq); - ci->wakeup_int = true; - pm_runtime_get(ci->dev); -diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c -index 36bf051b345b8..2a7eea4e251a1 100644 ---- a/drivers/usb/class/cdc-acm.c -+++ b/drivers/usb/class/cdc-acm.c -@@ -892,6 +892,9 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state) - struct acm *acm = tty->driver_data; - int retval; - -+ if (!(acm->ctrl_caps & USB_CDC_CAP_BRK)) -+ return -EOPNOTSUPP; -+ - retval = acm_send_break(acm, state ? 0xffff : 0); - if (retval < 0) - dev_dbg(&acm->control->dev, -diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c -index 1f23c96fa94f8..011a3909f9ad1 100644 ---- a/drivers/usb/dwc3/core.c -+++ b/drivers/usb/dwc3/core.c -@@ -277,48 +277,11 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) - /* - * We're resetting only the device side because, if we're in host mode, - * XHCI driver will reset the host block. If dwc3 was configured for -- * host-only mode or current role is host, then we can return early. -+ * host-only mode, then we can return early. - */ - if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) - return 0; - -- /* -- * If the dr_mode is host and the dwc->current_dr_role is not the -- * corresponding DWC3_GCTL_PRTCAP_HOST, then the dwc3_core_init_mode -- * isn't executed yet. Ensure the phy is ready before the controller -- * updates the GCTL.PRTCAPDIR or other settings by soft-resetting -- * the phy. -- * -- * Note: GUSB3PIPECTL[n] and GUSB2PHYCFG[n] are port settings where n -- * is port index. If this is a multiport host, then we need to reset -- * all active ports. -- */ -- if (dwc->dr_mode == USB_DR_MODE_HOST) { -- u32 usb3_port; -- u32 usb2_port; -- -- usb3_port = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); -- usb3_port |= DWC3_GUSB3PIPECTL_PHYSOFTRST; -- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); -- -- usb2_port = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); -- usb2_port |= DWC3_GUSB2PHYCFG_PHYSOFTRST; -- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); -- -- /* Small delay for phy reset assertion */ -- usleep_range(1000, 2000); -- -- usb3_port &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; -- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); -- -- usb2_port &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; -- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); -- -- /* Wait for clock synchronization */ -- msleep(50); -- return 0; -- } -- - reg = dwc3_readl(dwc->regs, DWC3_DCTL); - reg |= DWC3_DCTL_CSFTRST; - reg &= ~DWC3_DCTL_RUN_STOP; -diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c -index 61de693461da4..ec3c33266547c 100644 ---- a/drivers/usb/dwc3/ep0.c -+++ b/drivers/usb/dwc3/ep0.c -@@ -236,7 +236,10 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) - struct dwc3_request *req; - - req = next_request(&dep->pending_list); -- dwc3_gadget_giveback(dep, req, -ECONNRESET); -+ if (!dwc->connected) -+ dwc3_gadget_giveback(dep, req, -ESHUTDOWN); -+ else -+ dwc3_gadget_giveback(dep, req, -ECONNRESET); - } - - dwc->eps[0]->trb_enqueue = 0; -diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c -index a0921687444b1..bb4f80627cdc3 100644 ---- a/drivers/usb/host/xhci-mtk.c -+++ b/drivers/usb/host/xhci-mtk.c -@@ -7,6 +7,7 @@ - * Chunfeng Yun - */ - -+#include - #include - #include - #include -@@ -73,6 +74,9 @@ - #define FRMCNT_LEV1_RANG (0x12b << 8) - #define FRMCNT_LEV1_RANG_MASK GENMASK(19, 8) - -+#define HSCH_CFG1 0x960 -+#define SCH3_RXFIFO_DEPTH_MASK GENMASK(21, 20) -+ - #define SS_GEN2_EOF_CFG 0x990 - #define SSG2EOF_OFFSET 0x3c - -@@ -114,6 +118,8 @@ - #define SSC_IP_SLEEP_EN BIT(4) - #define SSC_SPM_INT_EN BIT(1) - -+#define SCH_FIFO_TO_KB(x) ((x) >> 10) -+ - enum ssusb_uwk_vers { - SSUSB_UWK_V1 = 1, - SSUSB_UWK_V2, -@@ -165,6 +171,35 @@ static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk) - writel(value, hcd->regs + SS_GEN2_EOF_CFG); - } - -+/* -+ * workaround: usb3.2 gen1 isoc rx hw issue -+ * host send out unexpected ACK afer device fininsh a burst transfer with -+ * a short packet. -+ */ -+static void xhci_mtk_rxfifo_depth_set(struct xhci_hcd_mtk *mtk) -+{ -+ struct usb_hcd *hcd = mtk->hcd; -+ u32 value; -+ -+ if (!mtk->rxfifo_depth) -+ return; -+ -+ value = readl(hcd->regs + HSCH_CFG1); -+ value &= ~SCH3_RXFIFO_DEPTH_MASK; -+ value |= FIELD_PREP(SCH3_RXFIFO_DEPTH_MASK, -+ SCH_FIFO_TO_KB(mtk->rxfifo_depth) - 1); -+ writel(value, hcd->regs + HSCH_CFG1); -+} -+ -+static void xhci_mtk_init_quirk(struct xhci_hcd_mtk *mtk) -+{ -+ /* workaround only for mt8195 */ -+ xhci_mtk_set_frame_interval(mtk); -+ -+ /* workaround for SoCs using SSUSB about before IPM v1.6.0 */ -+ xhci_mtk_rxfifo_depth_set(mtk); -+} -+ - static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) - { - struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; -@@ -453,8 +488,7 @@ static int xhci_mtk_setup(struct usb_hcd *hcd) - if (ret) - return ret; - -- /* workaround only for mt8195 */ -- xhci_mtk_set_frame_interval(mtk); -+ xhci_mtk_init_quirk(mtk); - } - - ret = xhci_gen_setup(hcd, xhci_mtk_quirks); -@@ -531,6 +565,8 @@ static int xhci_mtk_probe(struct platform_device *pdev) - of_property_read_u32(node, "mediatek,u2p-dis-msk", - &mtk->u2p_dis_msk); - -+ of_property_read_u32(node, "rx-fifo-depth", &mtk->rxfifo_depth); -+ - ret = usb_wakeup_of_property_parse(mtk, node); - if (ret) { - dev_err(dev, "failed to parse uwk property\n"); -diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h -index 1174a510dd388..2a6a47d0f09a4 100644 ---- a/drivers/usb/host/xhci-mtk.h -+++ b/drivers/usb/host/xhci-mtk.h -@@ -160,6 +160,8 @@ struct xhci_hcd_mtk { - struct regmap *uwk; - u32 uwk_reg_base; - u32 uwk_vers; -+ /* quirk */ -+ u32 rxfifo_depth; - }; - - static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd) -diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c -index 094e812e9e692..35483217b1f6c 100644 ---- a/drivers/usb/mon/mon_bin.c -+++ b/drivers/usb/mon/mon_bin.c -@@ -1247,14 +1247,19 @@ static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf) - struct mon_reader_bin *rp = vmf->vma->vm_private_data; - unsigned long offset, chunk_idx; - struct page *pageptr; -+ unsigned long flags; - -+ spin_lock_irqsave(&rp->b_lock, flags); - offset = vmf->pgoff << PAGE_SHIFT; -- if (offset >= rp->b_size) -+ if (offset >= rp->b_size) { -+ spin_unlock_irqrestore(&rp->b_lock, flags); - return VM_FAULT_SIGBUS; -+ } - chunk_idx = offset / CHUNK_SIZE; - pageptr = rp->b_vec[chunk_idx].pg; - get_page(pageptr); - vmf->page = pageptr; -+ spin_unlock_irqrestore(&rp->b_lock, flags); - return 0; - } - -diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c -index 9299df53eb9df..160c9264339f0 100644 ---- a/drivers/usb/phy/phy-mxs-usb.c -+++ b/drivers/usb/phy/phy-mxs-usb.c -@@ -388,8 +388,7 @@ static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect) - - static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy) - { -- return IS_ENABLED(CONFIG_USB_OTG) && -- mxs_phy->phy.last_event == USB_EVENT_ID; -+ return mxs_phy->phy.last_event == USB_EVENT_ID; - } - - static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) -diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c -index 49d6b2388b874..3da404d5178d3 100644 ---- a/drivers/usb/typec/class.c -+++ b/drivers/usb/typec/class.c -@@ -263,11 +263,13 @@ static void typec_altmode_put_partner(struct altmode *altmode) - { - struct altmode *partner = altmode->partner; - struct typec_altmode *adev; -+ struct typec_altmode *partner_adev; - - if (!partner) - return; - - adev = &altmode->adev; -+ partner_adev = &partner->adev; - - if (is_typec_plug(adev->dev.parent)) { - struct typec_plug *plug = to_typec_plug(adev->dev.parent); -@@ -276,7 +278,7 @@ static void typec_altmode_put_partner(struct altmode *altmode) - } else { - partner->partner = NULL; - } -- put_device(&adev->dev); -+ put_device(&partner_adev->dev); - } - - /** -diff --git a/drivers/vdpa/alibaba/eni_vdpa.c b/drivers/vdpa/alibaba/eni_vdpa.c -index 5a09a09cca709..cce3d1837104c 100644 ---- a/drivers/vdpa/alibaba/eni_vdpa.c -+++ b/drivers/vdpa/alibaba/eni_vdpa.c -@@ -497,7 +497,7 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) - if (!eni_vdpa->vring) { - ret = -ENOMEM; - ENI_ERR(pdev, "failed to allocate virtqueues\n"); -- goto err; -+ goto err_remove_vp_legacy; - } - - for (i = 0; i < eni_vdpa->queues; i++) { -@@ -509,11 +509,13 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) - ret = vdpa_register_device(&eni_vdpa->vdpa, eni_vdpa->queues); - if (ret) { - ENI_ERR(pdev, "failed to register to vdpa bus\n"); -- goto err; -+ goto err_remove_vp_legacy; - } - - return 0; - -+err_remove_vp_legacy: -+ vp_legacy_remove(&eni_vdpa->ldev); - err: - put_device(&eni_vdpa->vdpa.dev); - return ret; -diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c -index a3cf1f764f29b..49883c8012e60 100644 ---- a/drivers/video/fbdev/core/fb_defio.c -+++ b/drivers/video/fbdev/core/fb_defio.c -@@ -132,11 +132,7 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy - return 0; - - inode_lock(inode); -- /* Kill off the delayed work */ -- cancel_delayed_work_sync(&info->deferred_work); -- -- /* Run it immediately */ -- schedule_delayed_work(&info->deferred_work, 0); -+ flush_delayed_work(&info->deferred_work); - inode_unlock(inode); - - return 0; -@@ -321,7 +317,7 @@ static void fb_deferred_io_lastclose(struct fb_info *info) - struct page *page; - int i; - -- cancel_delayed_work_sync(&info->deferred_work); -+ flush_delayed_work(&info->deferred_work); - - /* clear out the mapping that we setup */ - for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { -diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c -index 36ada87b49a49..32b8374abeca5 100644 ---- a/drivers/video/fbdev/imxfb.c -+++ b/drivers/video/fbdev/imxfb.c -@@ -42,6 +42,7 @@ - #include