From 0657d1eca6b1ec32f0609e718ee3c22fc57274e7 Mon Sep 17 00:00:00 2001 From: Piotr Szczepanik Date: Sun, 5 Jan 2020 17:22:02 +0100 Subject: [PATCH 01/12] Temporary workaround for ethernet in rockchip64-current (#1721) --- .../general-temporary-ethernet-fixup.patch | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 patch/kernel/rockchip64-current/general-temporary-ethernet-fixup.patch diff --git a/patch/kernel/rockchip64-current/general-temporary-ethernet-fixup.patch b/patch/kernel/rockchip64-current/general-temporary-ethernet-fixup.patch new file mode 100644 index 0000000000..7bea4e6b9d --- /dev/null +++ b/patch/kernel/rockchip64-current/general-temporary-ethernet-fixup.patch @@ -0,0 +1,23 @@ +This is a temporary fix for ethernet with kernels 5.4.7+ + +It reverts the following change: https://patchwork.ozlabs.org/patch/1213121/ +which disabled mdio init for most of the boards except NanoPi M4(V2) +or NanoPC T4 which have proper device tree definition for mdio/phy. + +The proper fix will be to add phy device tree node for boards that miss +it. + +--- +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +index 170c3a052b14..1f230bd854c4 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +@@ -320,7 +320,7 @@ out: + static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, + struct device_node *np, struct device *dev) + { +- bool mdio = false; ++ bool mdio = true; + static const struct of_device_id need_mdio_ids[] = { + { .compatible = "snps,dwc-qos-ethernet-4.10" }, + {}, From c14dad452c5b847361e0da378b19c97acd83b571 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Sun, 5 Jan 2020 23:15:21 +0100 Subject: [PATCH 02/12] General: bump with version and adjust few targets --- VERSION | 2 +- config/targets.conf | 15 ++++++++++++--- lib/build-all-ng.sh | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 729b18d89d..8bda73742f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -19.11.6 +19.11.7 diff --git a/config/targets.conf b/config/targets.conf index f550365c59..ad5e1f6cdb 100644 --- a/config/targets.conf +++ b/config/targets.conf @@ -78,6 +78,7 @@ cubietruck current buster desktop stable yes cubietruck current buster cli stable yes cubietruck current bionic cli stable yes cubietruck current stretch cli stable yes +cubietruck current bullseye cli stable yes # Cubox-i cubox-i current buster cli stable yes @@ -333,6 +334,7 @@ odroidn2 current bionic minimal stable yes odroidxu4 legacy buster cli stable yes odroidxu4 legacy buster desktop stable yes +odroidxu4 legacy bionic desktop stable yes odroidxu4 legacy stretch cli stable yes odroidxu4 current bionic desktop stable yes odroidxu4 current buster minimal stable yes @@ -470,12 +472,14 @@ orangepizeroplus current bionic cli stable yes orangepizeroplus2-h3 current buster cli stable yes orangepizeroplus2-h3 current stretch cli stable yes +orangepizeroplus2-h3 current bionic minimal stable yes orangepizeroplus2-h3 current bullseye cli stable yes # orangepizeroplus2-h5 orangepizeroplus2-h5 current buster cli stable yes orangepizeroplus2-h5 current stretch cli stable yes +orangepizeroplus2-h5 current bionic minimal stable yes orangepizeroplus2-h5 current bullseye cli stable yes # LinkSprite pcDuino3 @@ -534,6 +538,8 @@ rock64 current bionic desktop stable yes rockpi-4b legacy buster cli stable yes rockpi-4b current buster cli stable yes +rockpi-4b current bionic minimal stable yes +rockpi-4b legacy bionic minimal stable yes rockpi-4b legacy bionic desktop stable yes rockpi-4b current buster desktop stable yes @@ -541,6 +547,8 @@ rockpi-4b current buster desktop stable yes rockpi-4a legacy buster cli stable yes rockpi-4a current buster cli stable yes +rockpi-4a current bionic minimal stable yes +rockpi-4a legacy bionic minimal stable yes rockpi-4a legacy bionic desktop stable yes rockpi-4a current buster desktop stable yes @@ -556,6 +564,7 @@ rockpro64 legacy buster cli stable yes rockpro64 legacy bionic desktop stable yes rockpro64 current buster desktop stable yes rockpro64 current bionic cli stable yes +rockpro64 current bullseye cli stable yes # Teres A64 @@ -564,9 +573,9 @@ teres-a64 current buster desktop stable yes # Tinkerboard -#tinkerboard legacy buster cli stable yes -#tinkerboard legacy bionic desktop stable yes -#tinkerboard legacy bionic cli stable yes +tinkerboard legacy buster cli stable yes +tinkerboard legacy bionic desktop stable yes +tinkerboard legacy bionic cli stable yes tinkerboard current bionic desktop stable yes tinkerboard current buster minimal stable yes tinkerboard current bullseye cli stable yes diff --git a/lib/build-all-ng.sh b/lib/build-all-ng.sh index c0da7122ea..b4750a79ac 100644 --- a/lib/build-all-ng.sh +++ b/lib/build-all-ng.sh @@ -209,7 +209,7 @@ function build_all() # unset also board related variables unset BOARDFAMILY DESKTOP_AUTOLOGIN DEFAULT_CONSOLE FULL_DESKTOP MODULES_CURRENT MODULES_LEGACY MODULES_DEV \ BOOTCONFIG MODULES_BLACKLIST_LEGACY MODULES_BLACKLIST_CURRENT MODULES_BLACKLIST_DEV DEFAULT_OVERLAYS SERIALCON \ - BUILD_MINIMAL RELEASE + BUILD_MINIMAL RELEASE ATFBRANCH read -r BOARD BRANCH RELEASE BUILD_TARGET BUILD_STABILITY BUILD_IMAGE <<< "${line}" From 4d479cbd2fda6b5481b3cc24b2c0cf51e5197526 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Sun, 5 Jan 2020 17:51:39 -0500 Subject: [PATCH 03/12] add fix-uartC-pinctrl-in-LE-branch.patch --- .../fix-uartC-pinctrl-in-LE-branch.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 patch/kernel/meson64-current/fix-uartC-pinctrl-in-LE-branch.patch diff --git a/patch/kernel/meson64-current/fix-uartC-pinctrl-in-LE-branch.patch b/patch/kernel/meson64-current/fix-uartC-pinctrl-in-LE-branch.patch new file mode 100644 index 0000000000..0e1bd670cd --- /dev/null +++ b/patch/kernel/meson64-current/fix-uartC-pinctrl-in-LE-branch.patch @@ -0,0 +1,19 @@ +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +index 111c198..b0d0ff9 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +@@ -463,10 +463,10 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = { + GROUP(tsin_a_clk, 3, 0), + GROUP(tsin_a_d0, 3, 4), + GROUP(tsin_a_dp, 3, 5), +- GROUP(uart_cts_c, 1, 19), +- GROUP(uart_rts_c, 1, 18), +- GROUP(uart_tx_c, 1, 17), +- GROUP(uart_rx_c, 1, 16), ++ GROUP(uart_cts_c, 1, 17), ++ GROUP(uart_rts_c, 1, 16), ++ GROUP(uart_tx_c, 1, 19), ++ GROUP(uart_rx_c, 1, 18), + GROUP(pwm_a_y, 1, 21), + GROUP(pwm_f_y, 1, 20), + GROUP(i2s_out_ch23_y, 1, 5), From d9fe2201e8fa1c4a191761d0de8bc6b2c1ee3f91 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Sun, 5 Jan 2020 17:54:52 -0500 Subject: [PATCH 04/12] make meson64 spi-gpio disabled by default and fix it cs-gpios --- .../meson64-current/board-odroidc2-enable-SPI.patch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/patch/kernel/meson64-current/board-odroidc2-enable-SPI.patch b/patch/kernel/meson64-current/board-odroidc2-enable-SPI.patch index 71081322d5..62305f74e5 100644 --- a/patch/kernel/meson64-current/board-odroidc2-enable-SPI.patch +++ b/patch/kernel/meson64-current/board-odroidc2-enable-SPI.patch @@ -12,12 +12,12 @@ index 0916dcb..cbc03df 100644 + #address-cells = <0x1>; + #size-cells = <0x0>; + ranges; -+ status = "ok"; ++ status = "disabled"; + sck-gpios = <&gpio GPIOX_2 0>; + miso-gpios = <&gpio GPIOX_4 0>; + mosi-gpios = <&gpio GPIOX_7 0>; -+ cs-gpios = <&gpio GPIOX_1 0 -+ &gpio GPIOY_14 0>; ++ cs-gpios = <&gpio GPIOX_3 0 ++ &gpio GPIOX_1 0>; + num-chipselects = <2>; + + /* clients */ @@ -34,4 +34,4 @@ index 0916dcb..cbc03df 100644 + }; sound { - compatible = "simple-audio-card"; \ No newline at end of file + compatible = "simple-audio-card"; From eb586f8135d075e9bca730c6d9eed4097d3dd088 Mon Sep 17 00:00:00 2001 From: Nick Breen Date: Tue, 7 Jan 2020 04:55:48 +1300 Subject: [PATCH 05/12] modified anx6345 patch to log errno from read edid from device tree (#1720) --- .../0130-drm-bridge-Add-Analogix-anx6345-support.patch | 2 +- .../0130-drm-bridge-Add-Analogix-anx6345-support.patch-disabled | 2 +- .../0130-drm-bridge-Add-Analogix-anx6345-support.patch | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/patch/kernel/sunxi-current/0130-drm-bridge-Add-Analogix-anx6345-support.patch b/patch/kernel/sunxi-current/0130-drm-bridge-Add-Analogix-anx6345-support.patch index 24f15e63f9..fd3920124b 100644 --- a/patch/kernel/sunxi-current/0130-drm-bridge-Add-Analogix-anx6345-support.patch +++ b/patch/kernel/sunxi-current/0130-drm-bridge-Add-Analogix-anx6345-support.patch @@ -604,7 +604,7 @@ index 000000000000..81676407aa6d + if (!anx6345->edid) { + err = anx6345_probe_edid_from_of(anx6345); + if (err) { -+ DRM_ERROR("Failed to probe EDID from device tree\n"); ++ DRM_ERROR("Failed to probe EDID from device tree: %d\n", err); + goto unlock; + } + } diff --git a/patch/kernel/sunxi-dev/0130-drm-bridge-Add-Analogix-anx6345-support.patch-disabled b/patch/kernel/sunxi-dev/0130-drm-bridge-Add-Analogix-anx6345-support.patch-disabled index 2e7ceffadb..dc8de6a678 100644 --- a/patch/kernel/sunxi-dev/0130-drm-bridge-Add-Analogix-anx6345-support.patch-disabled +++ b/patch/kernel/sunxi-dev/0130-drm-bridge-Add-Analogix-anx6345-support.patch-disabled @@ -604,7 +604,7 @@ index 000000000000..81676407aa6d + if (!anx6345->edid) { + err = anx6345_probe_edid_from_of(anx6345); + if (err) { -+ DRM_ERROR("Failed to probe EDID from device tree\n"); ++ DRM_ERROR("Failed to probe EDID from device tree: &d\n", err); + goto unlock; + } + } diff --git a/patch/kernel/sunxi-legacy/0130-drm-bridge-Add-Analogix-anx6345-support.patch b/patch/kernel/sunxi-legacy/0130-drm-bridge-Add-Analogix-anx6345-support.patch index 208115606b..bbe395f57e 100644 --- a/patch/kernel/sunxi-legacy/0130-drm-bridge-Add-Analogix-anx6345-support.patch +++ b/patch/kernel/sunxi-legacy/0130-drm-bridge-Add-Analogix-anx6345-support.patch @@ -603,7 +603,7 @@ index 000000000000..81676407aa6d + if (!anx6345->edid) { + err = anx6345_probe_edid_from_of(anx6345); + if (err) { -+ DRM_ERROR("Failed to probe EDID from device tree\n"); ++ DRM_ERROR("Failed to probe EDID from device tree: %d\n", err); + goto unlock; + } + } From ff0dca98407284d2693f9270b744213259706a0d Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Mon, 6 Jan 2020 20:15:44 +0100 Subject: [PATCH 06/12] Remove OdroidXU4 upstream patches which seems to contribute to https://forum.armbian.com/topic/12598-armbian-config-on-odroid-hc1/?tab=comments#comment-92351 --- .../odroidxu4-current/patch-5.4.3-4.patch | 6079 ----------------- .../odroidxu4-current/patch-5.4.4-5.patch | 2510 ------- .../odroidxu4-current/patch-5.4.5-6.patch | 3420 ---------- 3 files changed, 12009 deletions(-) delete mode 100644 patch/kernel/odroidxu4-current/patch-5.4.3-4.patch delete mode 100644 patch/kernel/odroidxu4-current/patch-5.4.4-5.patch delete mode 100644 patch/kernel/odroidxu4-current/patch-5.4.5-6.patch diff --git a/patch/kernel/odroidxu4-current/patch-5.4.3-4.patch b/patch/kernel/odroidxu4-current/patch-5.4.3-4.patch deleted file mode 100644 index 25e714e592..0000000000 --- a/patch/kernel/odroidxu4-current/patch-5.4.3-4.patch +++ /dev/null @@ -1,6079 +0,0 @@ -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 9983ac73b66d..f5a551e4332d 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -5101,13 +5101,13 @@ - Flags is a set of characters, each corresponding - to a common usb-storage quirk flag as follows: - a = SANE_SENSE (collect more than 18 bytes -- of sense data); -+ of sense data, not on uas); - b = BAD_SENSE (don't collect more than 18 -- bytes of sense data); -+ bytes of sense data, not on uas); - c = FIX_CAPACITY (decrease the reported - device capacity by one sector); - d = NO_READ_DISC_INFO (don't use -- READ_DISC_INFO command); -+ READ_DISC_INFO command, not on uas); - e = NO_READ_CAPACITY_16 (don't use - READ_CAPACITY_16 command); - f = NO_REPORT_OPCODES (don't use report opcodes -@@ -5122,17 +5122,18 @@ - j = NO_REPORT_LUNS (don't use report luns - command, uas only); - l = NOT_LOCKABLE (don't try to lock and -- unlock ejectable media); -+ unlock ejectable media, not on uas); - m = MAX_SECTORS_64 (don't transfer more -- than 64 sectors = 32 KB at a time); -+ than 64 sectors = 32 KB at a time, -+ not on uas); - n = INITIAL_READ10 (force a retry of the -- initial READ(10) command); -+ initial READ(10) command, not on uas); - o = CAPACITY_OK (accept the capacity -- reported by the device); -+ reported by the device, not on uas); - p = WRITE_CACHE (the device cache is ON -- by default); -+ by default, not on uas); - r = IGNORE_RESIDUE (the device reports -- bogus residue values); -+ bogus residue values, not on uas); - s = SINGLE_LUN (the device has only one - Logical Unit); - t = NO_ATA_1X (don't allow ATA(12) and ATA(16) -@@ -5141,7 +5142,8 @@ - w = NO_WP_DETECT (don't test whether the - medium is write-protected). - y = ALWAYS_SYNC (issue a SYNCHRONIZE_CACHE -- even if the device claims no cache) -+ even if the device claims no cache, -+ not on uas) - Example: quirks=0419:aaf5:rl,0421:0433:rc - - user_debug= [KNL,ARM] -diff --git a/Makefile b/Makefile -index 07998b60d56c..144daf02c78a 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 5 - PATCHLEVEL = 4 --SUBLEVEL = 3 -+SUBLEVEL = 4 - EXTRAVERSION = - NAME = Kleptomaniac Octopus - -diff --git a/arch/arm/boot/dts/omap3-pandora-common.dtsi b/arch/arm/boot/dts/omap3-pandora-common.dtsi -index ec5891718ae6..150d5be42d27 100644 ---- a/arch/arm/boot/dts/omap3-pandora-common.dtsi -+++ b/arch/arm/boot/dts/omap3-pandora-common.dtsi -@@ -226,6 +226,17 @@ - gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* GPIO_164 */ - }; - -+ /* wl1251 wifi+bt module */ -+ wlan_en: fixed-regulator-wg7210_en { -+ compatible = "regulator-fixed"; -+ regulator-name = "vwlan"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ startup-delay-us = <50000>; -+ enable-active-high; -+ gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>; -+ }; -+ - /* wg7210 (wifi+bt module) 32k clock buffer */ - wg7210_32k: fixed-regulator-wg7210_32k { - compatible = "regulator-fixed"; -@@ -522,9 +533,30 @@ - /*wp-gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;*/ /* GPIO_127 */ - }; - --/* mmc3 is probed using pdata-quirks to pass wl1251 card data */ - &mmc3 { -- status = "disabled"; -+ vmmc-supply = <&wlan_en>; -+ -+ bus-width = <4>; -+ non-removable; -+ ti,non-removable; -+ cap-power-off-card; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc3_pins>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ wlan: wifi@1 { -+ compatible = "ti,wl1251"; -+ -+ reg = <1>; -+ -+ interrupt-parent = <&gpio1>; -+ interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* GPIO_21 */ -+ -+ ti,wl1251-has-eeprom; -+ }; - }; - - /* bluetooth*/ -diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi -index a7a04d78deeb..f24e2326cfa7 100644 ---- a/arch/arm/boot/dts/omap3-tao3530.dtsi -+++ b/arch/arm/boot/dts/omap3-tao3530.dtsi -@@ -222,7 +222,7 @@ - pinctrl-0 = <&mmc1_pins>; - vmmc-supply = <&vmmc1>; - vqmmc-supply = <&vsim>; -- cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>; -+ cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>; - bus-width = <8>; - }; - -diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c -index 2efd18e8824c..1b7cf81ff035 100644 ---- a/arch/arm/mach-omap2/pdata-quirks.c -+++ b/arch/arm/mach-omap2/pdata-quirks.c -@@ -7,7 +7,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -311,118 +310,15 @@ static void __init omap3_logicpd_torpedo_init(void) - } - - /* omap3pandora legacy devices */ --#define PANDORA_WIFI_IRQ_GPIO 21 --#define PANDORA_WIFI_NRESET_GPIO 23 - - static struct platform_device pandora_backlight = { - .name = "pandora-backlight", - .id = -1, - }; - --static struct regulator_consumer_supply pandora_vmmc3_supply[] = { -- REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"), --}; -- --static struct regulator_init_data pandora_vmmc3 = { -- .constraints = { -- .valid_ops_mask = REGULATOR_CHANGE_STATUS, -- }, -- .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc3_supply), -- .consumer_supplies = pandora_vmmc3_supply, --}; -- --static struct fixed_voltage_config pandora_vwlan = { -- .supply_name = "vwlan", -- .microvolts = 1800000, /* 1.8V */ -- .startup_delay = 50000, /* 50ms */ -- .init_data = &pandora_vmmc3, --}; -- --static struct platform_device pandora_vwlan_device = { -- .name = "reg-fixed-voltage", -- .id = 1, -- .dev = { -- .platform_data = &pandora_vwlan, -- }, --}; -- --static struct gpiod_lookup_table pandora_vwlan_gpiod_table = { -- .dev_id = "reg-fixed-voltage.1", -- .table = { -- /* -- * As this is a low GPIO number it should be at the first -- * GPIO bank. -- */ -- GPIO_LOOKUP("gpio-0-31", PANDORA_WIFI_NRESET_GPIO, -- NULL, GPIO_ACTIVE_HIGH), -- { }, -- }, --}; -- --static void pandora_wl1251_init_card(struct mmc_card *card) --{ -- /* -- * We have TI wl1251 attached to MMC3. Pass this information to -- * SDIO core because it can't be probed by normal methods. -- */ -- if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) { -- card->quirks |= MMC_QUIRK_NONSTD_SDIO; -- card->cccr.wide_bus = 1; -- card->cis.vendor = 0x104c; -- card->cis.device = 0x9066; -- card->cis.blksize = 512; -- card->cis.max_dtr = 24000000; -- card->ocr = 0x80; -- } --} -- --static struct omap2_hsmmc_info pandora_mmc3[] = { -- { -- .mmc = 3, -- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, -- .init_card = pandora_wl1251_init_card, -- }, -- {} /* Terminator */ --}; -- --static void __init pandora_wl1251_init(void) --{ -- struct wl1251_platform_data pandora_wl1251_pdata; -- int ret; -- -- memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); -- -- pandora_wl1251_pdata.power_gpio = -1; -- -- ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); -- if (ret < 0) -- goto fail; -- -- pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO); -- if (pandora_wl1251_pdata.irq < 0) -- goto fail_irq; -- -- pandora_wl1251_pdata.use_eeprom = true; -- ret = wl1251_set_platform_data(&pandora_wl1251_pdata); -- if (ret < 0) -- goto fail_irq; -- -- return; -- --fail_irq: -- gpio_free(PANDORA_WIFI_IRQ_GPIO); --fail: -- pr_err("wl1251 board initialisation failed\n"); --} -- - static void __init omap3_pandora_legacy_init(void) - { - platform_device_register(&pandora_backlight); -- gpiod_add_lookup_table(&pandora_vwlan_gpiod_table); -- platform_device_register(&pandora_vwlan_device); -- omap_hsmmc_init(pandora_mmc3); -- omap_hsmmc_late_init(pandora_mmc3); -- pandora_wl1251_init(); - } - #endif /* CONFIG_ARCH_OMAP3 */ - -diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h -index 5a9b6eb651b6..d19871763ed4 100644 ---- a/arch/powerpc/include/asm/sections.h -+++ b/arch/powerpc/include/asm/sections.h -@@ -5,8 +5,22 @@ - - #include - #include -+ -+#define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed -+ - #include - -+extern bool init_mem_is_free; -+ -+static inline int arch_is_kernel_initmem_freed(unsigned long addr) -+{ -+ if (!init_mem_is_free) -+ return 0; -+ -+ return addr >= (unsigned long)__init_begin && -+ addr < (unsigned long)__init_end; -+} -+ - extern char __head_end[]; - - #ifdef __powerpc64__ -diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h -index c61d59ed3b45..2ccb938d8544 100644 ---- a/arch/powerpc/include/asm/vdso_datapage.h -+++ b/arch/powerpc/include/asm/vdso_datapage.h -@@ -82,6 +82,7 @@ struct vdso_data { - __s32 wtom_clock_nsec; /* Wall to monotonic clock nsec */ - __s64 wtom_clock_sec; /* Wall to monotonic clock sec */ - struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ -+ __u32 hrtimer_res; /* hrtimer resolution */ - __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ - __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ - }; -@@ -103,6 +104,7 @@ struct vdso_data { - __s32 wtom_clock_nsec; - struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ - __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ -+ __u32 hrtimer_res; /* hrtimer resolution */ - __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ - __u32 dcache_block_size; /* L1 d-cache block size */ - __u32 icache_block_size; /* L1 i-cache block size */ -diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile -index a7ca8fe62368..3c02445cf086 100644 ---- a/arch/powerpc/kernel/Makefile -+++ b/arch/powerpc/kernel/Makefile -@@ -5,8 +5,8 @@ - - CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' - --# Disable clang warning for using setjmp without setjmp.h header --CFLAGS_crash.o += $(call cc-disable-warning, builtin-requires-header) -+# Avoid clang warnings around longjmp/setjmp declarations -+CFLAGS_crash.o += -ffreestanding - - ifdef CONFIG_PPC64 - CFLAGS_prom_init.o += $(NO_MINIMAL_TOC) -diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c -index 484f54dab247..5c0a1e17219b 100644 ---- a/arch/powerpc/kernel/asm-offsets.c -+++ b/arch/powerpc/kernel/asm-offsets.c -@@ -387,6 +387,7 @@ int main(void) - OFFSET(WTOM_CLOCK_NSEC, vdso_data, wtom_clock_nsec); - OFFSET(STAMP_XTIME, vdso_data, stamp_xtime); - OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction); -+ OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res); - OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size); - OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size); - OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size); -@@ -417,7 +418,6 @@ int main(void) - DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); - DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); - DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); -- DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); - - #ifdef CONFIG_BUG - DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); -diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S -index b55a7b4cb543..9bc0aa9aeb65 100644 ---- a/arch/powerpc/kernel/misc_64.S -+++ b/arch/powerpc/kernel/misc_64.S -@@ -82,7 +82,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - subf r8,r6,r4 /* compute length */ - add r8,r8,r5 /* ensure we get enough */ - lwz r9,DCACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of cache block size */ -- srw. r8,r8,r9 /* compute line count */ -+ srd. r8,r8,r9 /* compute line count */ - beqlr /* nothing to do? */ - mtctr r8 - 1: dcbst 0,r6 -@@ -98,7 +98,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - subf r8,r6,r4 /* compute length */ - add r8,r8,r5 - lwz r9,ICACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of Icache block size */ -- srw. r8,r8,r9 /* compute line count */ -+ srd. r8,r8,r9 /* compute line count */ - beqlr /* nothing to do? */ - mtctr r8 - 2: icbi 0,r6 -diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c -index 694522308cd5..619447b1b797 100644 ---- a/arch/powerpc/kernel/time.c -+++ b/arch/powerpc/kernel/time.c -@@ -959,6 +959,7 @@ void update_vsyscall(struct timekeeper *tk) - vdso_data->wtom_clock_nsec = tk->wall_to_monotonic.tv_nsec; - vdso_data->stamp_xtime = xt; - vdso_data->stamp_sec_fraction = frac_sec; -+ vdso_data->hrtimer_res = hrtimer_resolution; - smp_wmb(); - ++(vdso_data->tb_update_count); - } -diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S -index becd9f8767ed..a967e795b96d 100644 ---- a/arch/powerpc/kernel/vdso32/gettimeofday.S -+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S -@@ -156,12 +156,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) - cror cr0*4+eq,cr0*4+eq,cr1*4+eq - bne cr0,99f - -+ mflr r12 -+ .cfi_register lr,r12 -+ bl __get_datapage@local /* get data page */ -+ lwz r5, CLOCK_HRTIMER_RES(r3) -+ mtlr r12 - li r3,0 - cmpli cr0,r4,0 - crclr cr0*4+so - beqlr -- lis r5,CLOCK_REALTIME_RES@h -- ori r5,r5,CLOCK_REALTIME_RES@l - stw r3,TSPC32_TV_SEC(r4) - stw r5,TSPC32_TV_NSEC(r4) - blr -diff --git a/arch/powerpc/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S -index 3f92561a64c4..526f5ba2593e 100644 ---- a/arch/powerpc/kernel/vdso64/cacheflush.S -+++ b/arch/powerpc/kernel/vdso64/cacheflush.S -@@ -35,7 +35,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) - subf r8,r6,r4 /* compute length */ - add r8,r8,r5 /* ensure we get enough */ - lwz r9,CFG_DCACHE_LOGBLOCKSZ(r10) -- srw. r8,r8,r9 /* compute line count */ -+ srd. r8,r8,r9 /* compute line count */ - crclr cr0*4+so - beqlr /* nothing to do? */ - mtctr r8 -@@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) - subf r8,r6,r4 /* compute length */ - add r8,r8,r5 - lwz r9,CFG_ICACHE_LOGBLOCKSZ(r10) -- srw. r8,r8,r9 /* compute line count */ -+ srd. r8,r8,r9 /* compute line count */ - crclr cr0*4+so - beqlr /* nothing to do? */ - mtctr r8 -diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S -index 07bfe33fe874..81757f06bbd7 100644 ---- a/arch/powerpc/kernel/vdso64/gettimeofday.S -+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S -@@ -186,12 +186,15 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) - cror cr0*4+eq,cr0*4+eq,cr1*4+eq - bne cr0,99f - -+ mflr r12 -+ .cfi_register lr,r12 -+ bl V_LOCAL_FUNC(__get_datapage) -+ lwz r5, CLOCK_HRTIMER_RES(r3) -+ mtlr r12 - li r3,0 - cmpldi cr0,r4,0 - crclr cr0*4+so - beqlr -- lis r5,CLOCK_REALTIME_RES@h -- ori r5,r5,CLOCK_REALTIME_RES@l - std r3,TSPC64_TV_SEC(r4) - std r5,TSPC64_TV_NSEC(r4) - blr -diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c -index e04b20625cb9..7ccc5c85c74e 100644 ---- a/arch/powerpc/platforms/powernv/opal-imc.c -+++ b/arch/powerpc/platforms/powernv/opal-imc.c -@@ -285,7 +285,14 @@ static int opal_imc_counters_probe(struct platform_device *pdev) - domain = IMC_DOMAIN_THREAD; - break; - case IMC_TYPE_TRACE: -- domain = IMC_DOMAIN_TRACE; -+ /* -+ * FIXME. Using trace_imc events to monitor application -+ * or KVM thread performance can cause a checkstop -+ * (system crash). -+ * Disable it for now. -+ */ -+ pr_info_once("IMC: disabling trace_imc PMU\n"); -+ domain = -1; - break; - default: - pr_warn("IMC Unknown Device type \n"); -diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c -index df832b09e3e9..f5fadbd2533a 100644 ---- a/arch/powerpc/sysdev/xive/common.c -+++ b/arch/powerpc/sysdev/xive/common.c -@@ -1035,6 +1035,15 @@ static int xive_irq_alloc_data(unsigned int virq, irq_hw_number_t hw) - xd->target = XIVE_INVALID_TARGET; - irq_set_handler_data(virq, xd); - -+ /* -+ * Turn OFF by default the interrupt being mapped. A side -+ * effect of this check is the mapping the ESB page of the -+ * interrupt in the Linux address space. This prevents page -+ * fault issues in the crash handler which masks all -+ * interrupts. -+ */ -+ xive_esb_read(xd, XIVE_ESB_SET_PQ_01); -+ - return 0; - } - -diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c -index 33c10749edec..55dc61cb4867 100644 ---- a/arch/powerpc/sysdev/xive/spapr.c -+++ b/arch/powerpc/sysdev/xive/spapr.c -@@ -392,20 +392,28 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) - data->esb_shift = esb_shift; - data->trig_page = trig_page; - -+ data->hw_irq = hw_irq; -+ - /* - * No chip-id for the sPAPR backend. This has an impact how we - * pick a target. See xive_pick_irq_target(). - */ - data->src_chip = XIVE_INVALID_CHIP_ID; - -+ /* -+ * When the H_INT_ESB flag is set, the H_INT_ESB hcall should -+ * be used for interrupt management. Skip the remapping of the -+ * ESB pages which are not available. -+ */ -+ if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB) -+ return 0; -+ - data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift); - if (!data->eoi_mmio) { - pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq); - return -ENOMEM; - } - -- data->hw_irq = hw_irq; -- - /* Full function page supports trigger */ - if (flags & XIVE_SRC_TRIGGER) { - data->trig_mmio = data->eoi_mmio; -diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile -index f142570ad860..c3842dbeb1b7 100644 ---- a/arch/powerpc/xmon/Makefile -+++ b/arch/powerpc/xmon/Makefile -@@ -1,8 +1,8 @@ - # SPDX-License-Identifier: GPL-2.0 - # Makefile for xmon - --# Disable clang warning for using setjmp without setjmp.h header --subdir-ccflags-y := $(call cc-disable-warning, builtin-requires-header) -+# Avoid clang warnings around longjmp/setjmp declarations -+subdir-ccflags-y := -ffreestanding - - GCOV_PROFILE := n - KCOV_INSTRUMENT := n -diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c -index 5367950510f6..fa0150285d38 100644 ---- a/arch/s390/boot/startup.c -+++ b/arch/s390/boot/startup.c -@@ -170,6 +170,11 @@ void startup_kernel(void) - handle_relocs(__kaslr_offset); - - if (__kaslr_offset) { -+ /* -+ * Save KASLR offset for early dumps, before vmcore_info is set. -+ * Mark as uneven to distinguish from real vmcore_info pointer. -+ */ -+ S390_lowcore.vmcore_info = __kaslr_offset | 0x1UL; - /* Clear non-relocated kernel */ - if (IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) - memset(img, 0, vmlinux.image_size); -diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h -index 5ff98d76a66c..a9e46b83c536 100644 ---- a/arch/s390/include/asm/pgtable.h -+++ b/arch/s390/include/asm/pgtable.h -@@ -1173,8 +1173,6 @@ void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr); - static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t entry) - { -- if (!MACHINE_HAS_NX) -- pte_val(entry) &= ~_PAGE_NOEXEC; - if (pte_present(entry)) - pte_val(entry) &= ~_PAGE_UNUSED; - if (mm_has_pgste(mm)) -@@ -1191,6 +1189,8 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) - { - pte_t __pte; - pte_val(__pte) = physpage + pgprot_val(pgprot); -+ if (!MACHINE_HAS_NX) -+ pte_val(__pte) &= ~_PAGE_NOEXEC; - return pte_mkyoung(__pte); - } - -diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c -index 444a19125a81..d402ced7f7c3 100644 ---- a/arch/s390/kernel/machine_kexec.c -+++ b/arch/s390/kernel/machine_kexec.c -@@ -254,10 +254,10 @@ void arch_crash_save_vmcoreinfo(void) - VMCOREINFO_SYMBOL(lowcore_ptr); - VMCOREINFO_SYMBOL(high_memory); - VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS); -- mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note()); - vmcoreinfo_append_str("SDMA=%lx\n", __sdma); - vmcoreinfo_append_str("EDMA=%lx\n", __edma); - vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); -+ mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note()); - } - - void machine_shutdown(void) -diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c -index 44974654cbd0..d95c85780e07 100644 ---- a/arch/s390/kernel/smp.c -+++ b/arch/s390/kernel/smp.c -@@ -262,10 +262,13 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) - lc->spinlock_index = 0; - lc->percpu_offset = __per_cpu_offset[cpu]; - lc->kernel_asce = S390_lowcore.kernel_asce; -+ lc->user_asce = S390_lowcore.kernel_asce; - lc->machine_flags = S390_lowcore.machine_flags; - lc->user_timer = lc->system_timer = - lc->steal_timer = lc->avg_steal_timer = 0; - __ctl_store(lc->cregs_save_area, 0, 15); -+ lc->cregs_save_area[1] = lc->kernel_asce; -+ lc->cregs_save_area[7] = lc->vdso_asce; - save_access_regs((unsigned int *) lc->access_regs_save_area); - memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list, - sizeof(lc->stfle_fac_list)); -@@ -816,6 +819,8 @@ static void smp_init_secondary(void) - - S390_lowcore.last_update_clock = get_tod_clock(); - restore_access_regs(S390_lowcore.access_regs_save_area); -+ set_cpu_flag(CIF_ASCE_PRIMARY); -+ set_cpu_flag(CIF_ASCE_SECONDARY); - cpu_init(); - preempt_disable(); - init_cpu_timer(); -diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c -index a0d3ce30fa08..a09ab0c3d074 100644 ---- a/block/blk-mq-sysfs.c -+++ b/block/blk-mq-sysfs.c -@@ -166,20 +166,25 @@ static ssize_t blk_mq_hw_sysfs_nr_reserved_tags_show(struct blk_mq_hw_ctx *hctx, - - static ssize_t blk_mq_hw_sysfs_cpus_show(struct blk_mq_hw_ctx *hctx, char *page) - { -+ const size_t size = PAGE_SIZE - 1; - unsigned int i, first = 1; -- ssize_t ret = 0; -+ int ret = 0, pos = 0; - - for_each_cpu(i, hctx->cpumask) { - if (first) -- ret += sprintf(ret + page, "%u", i); -+ ret = snprintf(pos + page, size - pos, "%u", i); - else -- ret += sprintf(ret + page, ", %u", i); -+ ret = snprintf(pos + page, size - pos, ", %u", i); -+ -+ if (ret >= size - pos) -+ break; - - first = 0; -+ pos += ret; - } - -- ret += sprintf(ret + page, "\n"); -- return ret; -+ ret = snprintf(pos + page, size + 1 - pos, "\n"); -+ return pos + ret; - } - - static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_nr_tags = { -diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c -index 60bbc5090abe..751ed38f2a10 100644 ---- a/drivers/acpi/acpi_lpss.c -+++ b/drivers/acpi/acpi_lpss.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -463,6 +464,18 @@ struct lpss_device_links { - const char *consumer_hid; - const char *consumer_uid; - u32 flags; -+ const struct dmi_system_id *dep_missing_ids; -+}; -+ -+/* Please keep this list sorted alphabetically by vendor and model */ -+static const struct dmi_system_id i2c1_dep_missing_dmi_ids[] = { -+ { -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), -+ DMI_MATCH(DMI_PRODUCT_NAME, "T200TA"), -+ }, -+ }, -+ {} - }; - - /* -@@ -473,9 +486,17 @@ struct lpss_device_links { - * the supplier is not enumerated until after the consumer is probed. - */ - static const struct lpss_device_links lpss_device_links[] = { -+ /* CHT External sdcard slot controller depends on PMIC I2C ctrl */ - {"808622C1", "7", "80860F14", "3", DL_FLAG_PM_RUNTIME}, -+ /* CHT iGPU depends on PMIC I2C controller */ - {"808622C1", "7", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME}, -+ /* BYT iGPU depends on the Embedded Controller I2C controller (UID 1) */ -+ {"80860F41", "1", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME, -+ i2c1_dep_missing_dmi_ids}, -+ /* BYT CR iGPU depends on PMIC I2C controller (UID 5 on CR) */ - {"80860F41", "5", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME}, -+ /* BYT iGPU depends on PMIC I2C controller (UID 7 on non CR) */ -+ {"80860F41", "7", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME}, - }; - - static bool hid_uid_match(struct acpi_device *adev, -@@ -570,7 +591,8 @@ static void acpi_lpss_link_consumer(struct device *dev1, - if (!dev2) - return; - -- if (acpi_lpss_dep(ACPI_COMPANION(dev2), ACPI_HANDLE(dev1))) -+ if ((link->dep_missing_ids && dmi_check_system(link->dep_missing_ids)) -+ || acpi_lpss_dep(ACPI_COMPANION(dev2), ACPI_HANDLE(dev1))) - device_link_add(dev2, dev1, link->flags); - - put_device(dev2); -@@ -585,7 +607,8 @@ static void acpi_lpss_link_supplier(struct device *dev1, - if (!dev2) - return; - -- if (acpi_lpss_dep(ACPI_COMPANION(dev1), ACPI_HANDLE(dev2))) -+ if ((link->dep_missing_ids && dmi_check_system(link->dep_missing_ids)) -+ || acpi_lpss_dep(ACPI_COMPANION(dev1), ACPI_HANDLE(dev2))) - device_link_add(dev1, dev2, link->flags); - - put_device(dev2); -diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c -index 48bc96d45bab..54002670cb7a 100644 ---- a/drivers/acpi/bus.c -+++ b/drivers/acpi/bus.c -@@ -153,7 +153,7 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data) - { - acpi_status status; - -- if (!*data) -+ if (!data) - return -EINVAL; - - status = acpi_get_data(handle, acpi_bus_private_data_handler, data); -diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c -index 08bb9f2f2d23..5e4a8860a9c0 100644 ---- a/drivers/acpi/device_pm.c -+++ b/drivers/acpi/device_pm.c -@@ -1314,9 +1314,19 @@ static void acpi_dev_pm_detach(struct device *dev, bool power_off) - */ - int acpi_dev_pm_attach(struct device *dev, bool power_on) - { -+ /* -+ * Skip devices whose ACPI companions match the device IDs below, -+ * because they require special power management handling incompatible -+ * with the generic ACPI PM domain. -+ */ -+ static const struct acpi_device_id special_pm_ids[] = { -+ {"PNP0C0B", }, /* Generic ACPI fan */ -+ {"INT3404", }, /* Fan */ -+ {} -+ }; - struct acpi_device *adev = ACPI_COMPANION(dev); - -- if (!adev) -+ if (!adev || !acpi_match_device_ids(adev, special_pm_ids)) - return 0; - - /* -diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c -index da1e5c5ce150..bd75caff8322 100644 ---- a/drivers/acpi/ec.c -+++ b/drivers/acpi/ec.c -@@ -525,26 +525,10 @@ static void acpi_ec_enable_event(struct acpi_ec *ec) - } - - #ifdef CONFIG_PM_SLEEP --static bool acpi_ec_query_flushed(struct acpi_ec *ec) -+static void __acpi_ec_flush_work(void) - { -- bool flushed; -- unsigned long flags; -- -- spin_lock_irqsave(&ec->lock, flags); -- flushed = !ec->nr_pending_queries; -- spin_unlock_irqrestore(&ec->lock, flags); -- return flushed; --} -- --static void __acpi_ec_flush_event(struct acpi_ec *ec) --{ -- /* -- * When ec_freeze_events is true, we need to flush events in -- * the proper position before entering the noirq stage. -- */ -- wait_event(ec->wait, acpi_ec_query_flushed(ec)); -- if (ec_query_wq) -- flush_workqueue(ec_query_wq); -+ flush_scheduled_work(); /* flush ec->work */ -+ flush_workqueue(ec_query_wq); /* flush queries */ - } - - static void acpi_ec_disable_event(struct acpi_ec *ec) -@@ -554,15 +538,21 @@ static void acpi_ec_disable_event(struct acpi_ec *ec) - spin_lock_irqsave(&ec->lock, flags); - __acpi_ec_disable_event(ec); - spin_unlock_irqrestore(&ec->lock, flags); -- __acpi_ec_flush_event(ec); -+ -+ /* -+ * When ec_freeze_events is true, we need to flush events in -+ * the proper position before entering the noirq stage. -+ */ -+ __acpi_ec_flush_work(); - } - - void acpi_ec_flush_work(void) - { -- if (first_ec) -- __acpi_ec_flush_event(first_ec); -+ /* Without ec_query_wq there is nothing to flush. */ -+ if (!ec_query_wq) -+ return; - -- flush_scheduled_work(); -+ __acpi_ec_flush_work(); - } - #endif /* CONFIG_PM_SLEEP */ - -diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c -index a2e844a8e9ed..41168c027a5a 100644 ---- a/drivers/acpi/osl.c -+++ b/drivers/acpi/osl.c -@@ -374,19 +374,21 @@ void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size) - } - EXPORT_SYMBOL_GPL(acpi_os_map_memory); - --static void acpi_os_drop_map_ref(struct acpi_ioremap *map) -+/* Must be called with mutex_lock(&acpi_ioremap_lock) */ -+static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map) - { -- if (!--map->refcount) -+ unsigned long refcount = --map->refcount; -+ -+ if (!refcount) - list_del_rcu(&map->list); -+ return refcount; - } - - static void acpi_os_map_cleanup(struct acpi_ioremap *map) - { -- if (!map->refcount) { -- synchronize_rcu_expedited(); -- acpi_unmap(map->phys, map->virt); -- kfree(map); -- } -+ synchronize_rcu_expedited(); -+ acpi_unmap(map->phys, map->virt); -+ kfree(map); - } - - /** -@@ -406,6 +408,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map) - void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) - { - struct acpi_ioremap *map; -+ unsigned long refcount; - - if (!acpi_permanent_mmap) { - __acpi_unmap_table(virt, size); -@@ -419,10 +422,11 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) - WARN(true, PREFIX "%s: bad address %p\n", __func__, virt); - return; - } -- acpi_os_drop_map_ref(map); -+ refcount = acpi_os_drop_map_ref(map); - mutex_unlock(&acpi_ioremap_lock); - -- acpi_os_map_cleanup(map); -+ if (!refcount) -+ acpi_os_map_cleanup(map); - } - EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem); - -@@ -457,6 +461,7 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas) - { - u64 addr; - struct acpi_ioremap *map; -+ unsigned long refcount; - - if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) - return; -@@ -472,10 +477,11 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas) - mutex_unlock(&acpi_ioremap_lock); - return; - } -- acpi_os_drop_map_ref(map); -+ refcount = acpi_os_drop_map_ref(map); - mutex_unlock(&acpi_ioremap_lock); - -- acpi_os_map_cleanup(map); -+ if (!refcount) -+ acpi_os_map_cleanup(map); - } - EXPORT_SYMBOL(acpi_os_unmap_generic_address); - -diff --git a/drivers/android/binder.c b/drivers/android/binder.c -index 265d9dd46a5e..976a69420c16 100644 ---- a/drivers/android/binder.c -+++ b/drivers/android/binder.c -@@ -3314,7 +3314,7 @@ static void binder_transaction(struct binder_proc *proc, - binder_size_t parent_offset; - struct binder_fd_array_object *fda = - to_binder_fd_array_object(hdr); -- size_t num_valid = (buffer_offset - off_start_offset) * -+ size_t num_valid = (buffer_offset - off_start_offset) / - sizeof(binder_size_t); - struct binder_buffer_object *parent = - binder_validate_ptr(target_proc, t->buffer, -@@ -3388,7 +3388,7 @@ static void binder_transaction(struct binder_proc *proc, - t->buffer->user_data + sg_buf_offset; - sg_buf_offset += ALIGN(bp->length, sizeof(u64)); - -- num_valid = (buffer_offset - off_start_offset) * -+ num_valid = (buffer_offset - off_start_offset) / - sizeof(binder_size_t); - ret = binder_fixup_parent(t, thread, bp, - off_start_offset, -diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c -index b27f39688b5e..e329f82c0467 100644 ---- a/drivers/char/hw_random/omap-rng.c -+++ b/drivers/char/hw_random/omap-rng.c -@@ -66,6 +66,13 @@ - #define OMAP4_RNG_OUTPUT_SIZE 0x8 - #define EIP76_RNG_OUTPUT_SIZE 0x10 - -+/* -+ * EIP76 RNG takes approx. 700us to produce 16 bytes of output data -+ * as per testing results. And to account for the lack of udelay()'s -+ * reliability, we keep the timeout as 1000us. -+ */ -+#define RNG_DATA_FILL_TIMEOUT 100 -+ - enum { - RNG_OUTPUT_0_REG = 0, - RNG_OUTPUT_1_REG, -@@ -176,7 +183,7 @@ static int omap_rng_do_read(struct hwrng *rng, void *data, size_t max, - if (max < priv->pdata->data_size) - return 0; - -- for (i = 0; i < 20; i++) { -+ for (i = 0; i < RNG_DATA_FILL_TIMEOUT; i++) { - present = priv->pdata->data_present(priv); - if (present || !wait) - break; -diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c -index c86f18aa8985..34bb88fe0b0a 100644 ---- a/drivers/char/ppdev.c -+++ b/drivers/char/ppdev.c -@@ -619,20 +619,27 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - if (copy_from_user(time32, argp, sizeof(time32))) - return -EFAULT; - -+ if ((time32[0] < 0) || (time32[1] < 0)) -+ return -EINVAL; -+ - return pp_set_timeout(pp->pdev, time32[0], time32[1]); - - case PPSETTIME64: - if (copy_from_user(time64, argp, sizeof(time64))) - return -EFAULT; - -+ if ((time64[0] < 0) || (time64[1] < 0)) -+ return -EINVAL; -+ -+ if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall()) -+ time64[1] >>= 32; -+ - return pp_set_timeout(pp->pdev, time64[0], time64[1]); - - case PPGETTIME32: - jiffies_to_timespec64(pp->pdev->timeout, &ts); - time32[0] = ts.tv_sec; - time32[1] = ts.tv_nsec / NSEC_PER_USEC; -- if ((time32[0] < 0) || (time32[1] < 0)) -- return -EINVAL; - - if (copy_to_user(argp, time32, sizeof(time32))) - return -EFAULT; -@@ -643,8 +650,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - jiffies_to_timespec64(pp->pdev->timeout, &ts); - time64[0] = ts.tv_sec; - time64[1] = ts.tv_nsec / NSEC_PER_USEC; -- if ((time64[0] < 0) || (time64[1] < 0)) -- return -EINVAL; -+ -+ if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall()) -+ time64[1] <<= 32; - - if (copy_to_user(argp, time64, sizeof(time64))) - return -EFAULT; -diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c -index ba9acae83bff..5817dfe5c5d2 100644 ---- a/drivers/char/tpm/tpm2-cmd.c -+++ b/drivers/char/tpm/tpm2-cmd.c -@@ -939,6 +939,10 @@ static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip) - - chip->cc_attrs_tbl = devm_kcalloc(&chip->dev, 4, nr_commands, - GFP_KERNEL); -+ if (!chip->cc_attrs_tbl) { -+ rc = -ENOMEM; -+ goto out; -+ } - - rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY); - if (rc) -diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c -index e4fdde93ed4c..e7df342a317d 100644 ---- a/drivers/char/tpm/tpm_tis.c -+++ b/drivers/char/tpm/tpm_tis.c -@@ -286,7 +286,7 @@ static int tpm_tis_plat_probe(struct platform_device *pdev) - } - tpm_info.res = *res; - -- tpm_info.irq = platform_get_irq(pdev, 0); -+ tpm_info.irq = platform_get_irq_optional(pdev, 0); - if (tpm_info.irq <= 0) { - if (pdev != force_pdev) - tpm_info.irq = -1; -diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c -index 6061850e59c9..56f4bc0d209e 100644 ---- a/drivers/cpufreq/powernv-cpufreq.c -+++ b/drivers/cpufreq/powernv-cpufreq.c -@@ -1041,9 +1041,14 @@ static struct cpufreq_driver powernv_cpufreq_driver = { - - static int init_chip_info(void) - { -- unsigned int chip[256]; -+ unsigned int *chip; - unsigned int cpu, i; - unsigned int prev_chip_id = UINT_MAX; -+ int ret = 0; -+ -+ chip = kcalloc(num_possible_cpus(), sizeof(*chip), GFP_KERNEL); -+ if (!chip) -+ return -ENOMEM; - - for_each_possible_cpu(cpu) { - unsigned int id = cpu_to_chip_id(cpu); -@@ -1055,8 +1060,10 @@ static int init_chip_info(void) - } - - chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL); -- if (!chips) -- return -ENOMEM; -+ if (!chips) { -+ ret = -ENOMEM; -+ goto free_and_return; -+ } - - for (i = 0; i < nr_chips; i++) { - chips[i].id = chip[i]; -@@ -1066,7 +1073,9 @@ static int init_chip_info(void) - per_cpu(chip_info, cpu) = &chips[i]; - } - -- return 0; -+free_and_return: -+ kfree(chip); -+ return ret; - } - - static inline void clean_chip_info(void) -diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c -index 0895b988fa92..29d2d7a21bd7 100644 ---- a/drivers/cpuidle/cpuidle.c -+++ b/drivers/cpuidle/cpuidle.c -@@ -384,6 +384,7 @@ u64 cpuidle_poll_time(struct cpuidle_driver *drv, - continue; - - limit_ns = (u64)drv->states[i].target_residency * NSEC_PER_USEC; -+ break; - } - - dev->poll_limit_ns = limit_ns; -diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c -index 80c1a830d991..9db154224999 100644 ---- a/drivers/cpuidle/driver.c -+++ b/drivers/cpuidle/driver.c -@@ -62,24 +62,23 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv) - * __cpuidle_set_driver - set per CPU driver variables for the given driver. - * @drv: a valid pointer to a struct cpuidle_driver - * -- * For each CPU in the driver's cpumask, unset the registered driver per CPU -- * to @drv. -- * -- * Returns 0 on success, -EBUSY if the CPUs have driver(s) already. -+ * Returns 0 on success, -EBUSY if any CPU in the cpumask have a driver -+ * different from drv already. - */ - static inline int __cpuidle_set_driver(struct cpuidle_driver *drv) - { - int cpu; - - for_each_cpu(cpu, drv->cpumask) { -+ struct cpuidle_driver *old_drv; - -- if (__cpuidle_get_cpu_driver(cpu)) { -- __cpuidle_unset_driver(drv); -+ old_drv = __cpuidle_get_cpu_driver(cpu); -+ if (old_drv && old_drv != drv) - return -EBUSY; -- } -+ } - -+ for_each_cpu(cpu, drv->cpumask) - per_cpu(cpuidle_drivers, cpu) = drv; -- } - - return 0; - } -diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c -index b5a0e498f798..b9b9156618e6 100644 ---- a/drivers/cpuidle/governors/teo.c -+++ b/drivers/cpuidle/governors/teo.c -@@ -233,7 +233,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, - { - struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu); - int latency_req = cpuidle_governor_latency_req(dev->cpu); -- unsigned int duration_us, count; -+ unsigned int duration_us, hits, misses, early_hits; - int max_early_idx, constraint_idx, idx, i; - ktime_t delta_tick; - -@@ -247,7 +247,9 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, - cpu_data->sleep_length_ns = tick_nohz_get_sleep_length(&delta_tick); - duration_us = ktime_to_us(cpu_data->sleep_length_ns); - -- count = 0; -+ hits = 0; -+ misses = 0; -+ early_hits = 0; - max_early_idx = -1; - constraint_idx = drv->state_count; - idx = -1; -@@ -258,23 +260,61 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, - - if (s->disabled || su->disable) { - /* -- * If the "early hits" metric of a disabled state is -- * greater than the current maximum, it should be taken -- * into account, because it would be a mistake to select -- * a deeper state with lower "early hits" metric. The -- * index cannot be changed to point to it, however, so -- * just increase the max count alone and let the index -- * still point to a shallower idle state. -+ * Ignore disabled states with target residencies beyond -+ * the anticipated idle duration. - */ -- if (max_early_idx >= 0 && -- count < cpu_data->states[i].early_hits) -- count = cpu_data->states[i].early_hits; -+ if (s->target_residency > duration_us) -+ continue; -+ -+ /* -+ * This state is disabled, so the range of idle duration -+ * values corresponding to it is covered by the current -+ * candidate state, but still the "hits" and "misses" -+ * metrics of the disabled state need to be used to -+ * decide whether or not the state covering the range in -+ * question is good enough. -+ */ -+ hits = cpu_data->states[i].hits; -+ misses = cpu_data->states[i].misses; -+ -+ if (early_hits >= cpu_data->states[i].early_hits || -+ idx < 0) -+ continue; -+ -+ /* -+ * If the current candidate state has been the one with -+ * the maximum "early hits" metric so far, the "early -+ * hits" metric of the disabled state replaces the -+ * current "early hits" count to avoid selecting a -+ * deeper state with lower "early hits" metric. -+ */ -+ if (max_early_idx == idx) { -+ early_hits = cpu_data->states[i].early_hits; -+ continue; -+ } -+ -+ /* -+ * The current candidate state is closer to the disabled -+ * one than the current maximum "early hits" state, so -+ * replace the latter with it, but in case the maximum -+ * "early hits" state index has not been set so far, -+ * check if the current candidate state is not too -+ * shallow for that role. -+ */ -+ if (!(tick_nohz_tick_stopped() && -+ drv->states[idx].target_residency < TICK_USEC)) { -+ early_hits = cpu_data->states[i].early_hits; -+ max_early_idx = idx; -+ } - - continue; - } - -- if (idx < 0) -+ if (idx < 0) { - idx = i; /* first enabled state */ -+ hits = cpu_data->states[i].hits; -+ misses = cpu_data->states[i].misses; -+ } - - if (s->target_residency > duration_us) - break; -@@ -283,11 +323,13 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, - constraint_idx = i; - - idx = i; -+ hits = cpu_data->states[i].hits; -+ misses = cpu_data->states[i].misses; - -- if (count < cpu_data->states[i].early_hits && -+ if (early_hits < cpu_data->states[i].early_hits && - !(tick_nohz_tick_stopped() && - drv->states[i].target_residency < TICK_USEC)) { -- count = cpu_data->states[i].early_hits; -+ early_hits = cpu_data->states[i].early_hits; - max_early_idx = i; - } - } -@@ -300,8 +342,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, - * "early hits" metric, but if that cannot be determined, just use the - * state selected so far. - */ -- if (cpu_data->states[idx].hits <= cpu_data->states[idx].misses && -- max_early_idx >= 0) { -+ if (hits <= misses && max_early_idx >= 0) { - idx = max_early_idx; - duration_us = drv->states[idx].target_residency; - } -@@ -316,10 +357,9 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, - if (idx < 0) { - idx = 0; /* No states enabled. Must use 0. */ - } else if (idx > 0) { -+ unsigned int count = 0; - u64 sum = 0; - -- count = 0; -- - /* - * Count and sum the most recent idle duration values less than - * the current expected idle duration value. -diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c -index 446490c9d635..3a1484e7a3ae 100644 ---- a/drivers/devfreq/devfreq.c -+++ b/drivers/devfreq/devfreq.c -@@ -160,6 +160,7 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) - int lev, prev_lev, ret = 0; - unsigned long cur_time; - -+ lockdep_assert_held(&devfreq->lock); - cur_time = jiffies; - - /* Immediately exit if previous_freq is not initialized yet. */ -@@ -1397,12 +1398,17 @@ static ssize_t trans_stat_show(struct device *dev, - int i, j; - unsigned int max_state = devfreq->profile->max_state; - -- if (!devfreq->stop_polling && -- devfreq_update_status(devfreq, devfreq->previous_freq)) -- return 0; - if (max_state == 0) - return sprintf(buf, "Not Supported.\n"); - -+ mutex_lock(&devfreq->lock); -+ if (!devfreq->stop_polling && -+ devfreq_update_status(devfreq, devfreq->previous_freq)) { -+ mutex_unlock(&devfreq->lock); -+ return 0; -+ } -+ mutex_unlock(&devfreq->lock); -+ - len = sprintf(buf, " From : To\n"); - len += sprintf(buf + len, " :"); - for (i = 0; i < max_state; i++) -diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c -index fbda4b876afd..0be3d1b17f03 100644 ---- a/drivers/edac/altera_edac.c -+++ b/drivers/edac/altera_edac.c -@@ -560,6 +560,7 @@ static const struct regmap_config s10_sdram_regmap_cfg = { - .reg_write = s10_protected_reg_write, - .use_single_read = true, - .use_single_write = true, -+ .fast_io = true, - }; - - /************** ***********/ -diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c -index f6f6a688c009..296e714bf553 100644 ---- a/drivers/edac/ghes_edac.c -+++ b/drivers/edac/ghes_edac.c -@@ -566,8 +566,8 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev) - ghes_pvt = pvt; - spin_unlock_irqrestore(&ghes_lock, flags); - -- /* only increment on success */ -- refcount_inc(&ghes_refcount); -+ /* only set on success */ -+ refcount_set(&ghes_refcount, 1); - - unlock: - mutex_unlock(&ghes_reg_mutex); -diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c -index 91d5ad7cf58b..25e0f60c759a 100644 ---- a/drivers/firmware/qcom_scm-64.c -+++ b/drivers/firmware/qcom_scm-64.c -@@ -150,7 +150,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, - kfree(args_virt); - } - -- if (res->a0 < 0) -+ if ((long)res->a0 < 0) - return qcom_scm_remap_error(res->a0); - - return 0; -diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c -index f21bc8a7ee3a..bdf91b75328e 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_drv.c -+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c -@@ -443,7 +443,7 @@ panfrost_postclose(struct drm_device *dev, struct drm_file *file) - { - struct panfrost_file_priv *panfrost_priv = file->driver_priv; - -- panfrost_perfcnt_close(panfrost_priv); -+ panfrost_perfcnt_close(file); - panfrost_job_close(panfrost_priv); - - panfrost_mmu_pgtable_free(panfrost_priv); -diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c -index acb07fe06580..bc3ff22e5e85 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_gem.c -+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c -@@ -41,7 +41,7 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) - drm_gem_shmem_free_object(obj); - } - --static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) -+int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) - { - int ret; - size_t size = obj->size; -@@ -80,7 +80,7 @@ static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_p - return ret; - } - --static void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv) -+void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv) - { - struct panfrost_gem_object *bo = to_panfrost_bo(obj); - struct panfrost_file_priv *priv = file_priv->driver_priv; -diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h -index 50920819cc16..4b17e7308764 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_gem.h -+++ b/drivers/gpu/drm/panfrost/panfrost_gem.h -@@ -45,6 +45,10 @@ panfrost_gem_create_with_handle(struct drm_file *file_priv, - u32 flags, - uint32_t *handle); - -+int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv); -+void panfrost_gem_close(struct drm_gem_object *obj, -+ struct drm_file *file_priv); -+ - void panfrost_gem_shrinker_init(struct drm_device *dev); - void panfrost_gem_shrinker_cleanup(struct drm_device *dev); - -diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c -index 2dba192bf198..2c04e858c50a 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c -+++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c -@@ -67,9 +67,10 @@ static int panfrost_perfcnt_dump_locked(struct panfrost_device *pfdev) - } - - static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, -- struct panfrost_file_priv *user, -+ struct drm_file *file_priv, - unsigned int counterset) - { -+ struct panfrost_file_priv *user = file_priv->driver_priv; - struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; - struct drm_gem_shmem_object *bo; - u32 cfg; -@@ -91,14 +92,14 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, - perfcnt->bo = to_panfrost_bo(&bo->base); - - /* Map the perfcnt buf in the address space attached to file_priv. */ -- ret = panfrost_mmu_map(perfcnt->bo); -+ ret = panfrost_gem_open(&perfcnt->bo->base.base, file_priv); - if (ret) - goto err_put_bo; - - perfcnt->buf = drm_gem_shmem_vmap(&bo->base); - if (IS_ERR(perfcnt->buf)) { - ret = PTR_ERR(perfcnt->buf); -- goto err_put_bo; -+ goto err_close_bo; - } - - /* -@@ -157,14 +158,17 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, - - err_vunmap: - drm_gem_shmem_vunmap(&perfcnt->bo->base.base, perfcnt->buf); -+err_close_bo: -+ panfrost_gem_close(&perfcnt->bo->base.base, file_priv); - err_put_bo: - drm_gem_object_put_unlocked(&bo->base); - return ret; - } - - static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev, -- struct panfrost_file_priv *user) -+ struct drm_file *file_priv) - { -+ struct panfrost_file_priv *user = file_priv->driver_priv; - struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; - - if (user != perfcnt->user) -@@ -180,6 +184,7 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev, - perfcnt->user = NULL; - drm_gem_shmem_vunmap(&perfcnt->bo->base.base, perfcnt->buf); - perfcnt->buf = NULL; -+ panfrost_gem_close(&perfcnt->bo->base.base, file_priv); - drm_gem_object_put_unlocked(&perfcnt->bo->base.base); - perfcnt->bo = NULL; - pm_runtime_mark_last_busy(pfdev->dev); -@@ -191,7 +196,6 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev, - int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data, - struct drm_file *file_priv) - { -- struct panfrost_file_priv *pfile = file_priv->driver_priv; - struct panfrost_device *pfdev = dev->dev_private; - struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; - struct drm_panfrost_perfcnt_enable *req = data; -@@ -207,10 +211,10 @@ int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data, - - mutex_lock(&perfcnt->lock); - if (req->enable) -- ret = panfrost_perfcnt_enable_locked(pfdev, pfile, -+ ret = panfrost_perfcnt_enable_locked(pfdev, file_priv, - req->counterset); - else -- ret = panfrost_perfcnt_disable_locked(pfdev, pfile); -+ ret = panfrost_perfcnt_disable_locked(pfdev, file_priv); - mutex_unlock(&perfcnt->lock); - - return ret; -@@ -248,15 +252,16 @@ out: - return ret; - } - --void panfrost_perfcnt_close(struct panfrost_file_priv *pfile) -+void panfrost_perfcnt_close(struct drm_file *file_priv) - { -+ struct panfrost_file_priv *pfile = file_priv->driver_priv; - struct panfrost_device *pfdev = pfile->pfdev; - struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; - - pm_runtime_get_sync(pfdev->dev); - mutex_lock(&perfcnt->lock); - if (perfcnt->user == pfile) -- panfrost_perfcnt_disable_locked(pfdev, pfile); -+ panfrost_perfcnt_disable_locked(pfdev, file_priv); - mutex_unlock(&perfcnt->lock); - pm_runtime_mark_last_busy(pfdev->dev); - pm_runtime_put_autosuspend(pfdev->dev); -diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.h b/drivers/gpu/drm/panfrost/panfrost_perfcnt.h -index 13b8fdaa1b43..8bbcf5f5fb33 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.h -+++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.h -@@ -9,7 +9,7 @@ void panfrost_perfcnt_sample_done(struct panfrost_device *pfdev); - void panfrost_perfcnt_clean_cache_done(struct panfrost_device *pfdev); - int panfrost_perfcnt_init(struct panfrost_device *pfdev); - void panfrost_perfcnt_fini(struct panfrost_device *pfdev); --void panfrost_perfcnt_close(struct panfrost_file_priv *pfile); -+void panfrost_perfcnt_close(struct drm_file *file_priv); - int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data, - struct drm_file *file_priv); - int panfrost_ioctl_perfcnt_dump(struct drm_device *dev, void *data, -diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c -index 05f7896c3a01..b605889b507a 100644 ---- a/drivers/hwtracing/coresight/coresight-funnel.c -+++ b/drivers/hwtracing/coresight/coresight-funnel.c -@@ -38,12 +38,14 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel"); - * @atclk: optional clock for the core parts of the funnel. - * @csdev: component vitals needed by the framework. - * @priority: port selection order. -+ * @spinlock: serialize enable/disable operations. - */ - struct funnel_drvdata { - void __iomem *base; - struct clk *atclk; - struct coresight_device *csdev; - unsigned long priority; -+ spinlock_t spinlock; - }; - - static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port) -@@ -76,11 +78,21 @@ static int funnel_enable(struct coresight_device *csdev, int inport, - { - int rc = 0; - struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); -- -- if (drvdata->base) -- rc = dynamic_funnel_enable_hw(drvdata, inport); -- -+ unsigned long flags; -+ bool first_enable = false; -+ -+ spin_lock_irqsave(&drvdata->spinlock, flags); -+ if (atomic_read(&csdev->refcnt[inport]) == 0) { -+ if (drvdata->base) -+ rc = dynamic_funnel_enable_hw(drvdata, inport); -+ if (!rc) -+ first_enable = true; -+ } - if (!rc) -+ atomic_inc(&csdev->refcnt[inport]); -+ spin_unlock_irqrestore(&drvdata->spinlock, flags); -+ -+ if (first_enable) - dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", inport); - return rc; - } -@@ -107,11 +119,19 @@ static void funnel_disable(struct coresight_device *csdev, int inport, - int outport) - { - struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); -+ unsigned long flags; -+ bool last_disable = false; -+ -+ spin_lock_irqsave(&drvdata->spinlock, flags); -+ if (atomic_dec_return(&csdev->refcnt[inport]) == 0) { -+ if (drvdata->base) -+ dynamic_funnel_disable_hw(drvdata, inport); -+ last_disable = true; -+ } -+ spin_unlock_irqrestore(&drvdata->spinlock, flags); - -- if (drvdata->base) -- dynamic_funnel_disable_hw(drvdata, inport); -- -- dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport); -+ if (last_disable) -+ dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport); - } - - static const struct coresight_ops_link funnel_link_ops = { -diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c -index b29ba640eb25..43304196a1a6 100644 ---- a/drivers/hwtracing/coresight/coresight-replicator.c -+++ b/drivers/hwtracing/coresight/coresight-replicator.c -@@ -31,11 +31,13 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator"); - * whether this one is programmable or not. - * @atclk: optional clock for the core parts of the replicator. - * @csdev: component vitals needed by the framework -+ * @spinlock: serialize enable/disable operations. - */ - struct replicator_drvdata { - void __iomem *base; - struct clk *atclk; - struct coresight_device *csdev; -+ spinlock_t spinlock; - }; - - static void dynamic_replicator_reset(struct replicator_drvdata *drvdata) -@@ -97,10 +99,22 @@ static int replicator_enable(struct coresight_device *csdev, int inport, - { - int rc = 0; - struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); -- -- if (drvdata->base) -- rc = dynamic_replicator_enable(drvdata, inport, outport); -+ unsigned long flags; -+ bool first_enable = false; -+ -+ spin_lock_irqsave(&drvdata->spinlock, flags); -+ if (atomic_read(&csdev->refcnt[outport]) == 0) { -+ if (drvdata->base) -+ rc = dynamic_replicator_enable(drvdata, inport, -+ outport); -+ if (!rc) -+ first_enable = true; -+ } - if (!rc) -+ atomic_inc(&csdev->refcnt[outport]); -+ spin_unlock_irqrestore(&drvdata->spinlock, flags); -+ -+ if (first_enable) - dev_dbg(&csdev->dev, "REPLICATOR enabled\n"); - return rc; - } -@@ -137,10 +151,19 @@ static void replicator_disable(struct coresight_device *csdev, int inport, - int outport) - { - struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); -+ unsigned long flags; -+ bool last_disable = false; -+ -+ spin_lock_irqsave(&drvdata->spinlock, flags); -+ if (atomic_dec_return(&csdev->refcnt[outport]) == 0) { -+ if (drvdata->base) -+ dynamic_replicator_disable(drvdata, inport, outport); -+ last_disable = true; -+ } -+ spin_unlock_irqrestore(&drvdata->spinlock, flags); - -- if (drvdata->base) -- dynamic_replicator_disable(drvdata, inport, outport); -- dev_dbg(&csdev->dev, "REPLICATOR disabled\n"); -+ if (last_disable) -+ dev_dbg(&csdev->dev, "REPLICATOR disabled\n"); - } - - static const struct coresight_ops_link replicator_link_ops = { -diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c -index 807416b75ecc..d0cc3985b72a 100644 ---- a/drivers/hwtracing/coresight/coresight-tmc-etf.c -+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c -@@ -334,9 +334,10 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) - static int tmc_enable_etf_link(struct coresight_device *csdev, - int inport, int outport) - { -- int ret; -+ int ret = 0; - unsigned long flags; - struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); -+ bool first_enable = false; - - spin_lock_irqsave(&drvdata->spinlock, flags); - if (drvdata->reading) { -@@ -344,12 +345,18 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, - return -EBUSY; - } - -- ret = tmc_etf_enable_hw(drvdata); -+ if (atomic_read(&csdev->refcnt[0]) == 0) { -+ ret = tmc_etf_enable_hw(drvdata); -+ if (!ret) { -+ drvdata->mode = CS_MODE_SYSFS; -+ first_enable = true; -+ } -+ } - if (!ret) -- drvdata->mode = CS_MODE_SYSFS; -+ atomic_inc(&csdev->refcnt[0]); - spin_unlock_irqrestore(&drvdata->spinlock, flags); - -- if (!ret) -+ if (first_enable) - dev_dbg(&csdev->dev, "TMC-ETF enabled\n"); - return ret; - } -@@ -359,6 +366,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, - { - unsigned long flags; - struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); -+ bool last_disable = false; - - spin_lock_irqsave(&drvdata->spinlock, flags); - if (drvdata->reading) { -@@ -366,11 +374,15 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, - return; - } - -- tmc_etf_disable_hw(drvdata); -- drvdata->mode = CS_MODE_DISABLED; -+ if (atomic_dec_return(&csdev->refcnt[0]) == 0) { -+ tmc_etf_disable_hw(drvdata); -+ drvdata->mode = CS_MODE_DISABLED; -+ last_disable = true; -+ } - spin_unlock_irqrestore(&drvdata->spinlock, flags); - -- dev_dbg(&csdev->dev, "TMC-ETF disabled\n"); -+ if (last_disable) -+ dev_dbg(&csdev->dev, "TMC-ETF disabled\n"); - } - - static void *tmc_alloc_etf_buffer(struct coresight_device *csdev, -diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c -index 6453c67a4d01..0bbce0d29158 100644 ---- a/drivers/hwtracing/coresight/coresight.c -+++ b/drivers/hwtracing/coresight/coresight.c -@@ -253,9 +253,9 @@ static int coresight_enable_link(struct coresight_device *csdev, - struct coresight_device *parent, - struct coresight_device *child) - { -- int ret; -+ int ret = 0; - int link_subtype; -- int refport, inport, outport; -+ int inport, outport; - - if (!parent || !child) - return -EINVAL; -@@ -264,29 +264,17 @@ static int coresight_enable_link(struct coresight_device *csdev, - outport = coresight_find_link_outport(csdev, child); - link_subtype = csdev->subtype.link_subtype; - -- if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) -- refport = inport; -- else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) -- refport = outport; -- else -- refport = 0; -- -- if (refport < 0) -- return refport; -+ if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && inport < 0) -+ return inport; -+ if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && outport < 0) -+ return outport; - -- if (atomic_inc_return(&csdev->refcnt[refport]) == 1) { -- if (link_ops(csdev)->enable) { -- ret = link_ops(csdev)->enable(csdev, inport, outport); -- if (ret) { -- atomic_dec(&csdev->refcnt[refport]); -- return ret; -- } -- } -- } -- -- csdev->enable = true; -+ if (link_ops(csdev)->enable) -+ ret = link_ops(csdev)->enable(csdev, inport, outport); -+ if (!ret) -+ csdev->enable = true; - -- return 0; -+ return ret; - } - - static void coresight_disable_link(struct coresight_device *csdev, -@@ -295,7 +283,7 @@ static void coresight_disable_link(struct coresight_device *csdev, - { - int i, nr_conns; - int link_subtype; -- int refport, inport, outport; -+ int inport, outport; - - if (!parent || !child) - return; -@@ -305,20 +293,15 @@ static void coresight_disable_link(struct coresight_device *csdev, - link_subtype = csdev->subtype.link_subtype; - - if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { -- refport = inport; - nr_conns = csdev->pdata->nr_inport; - } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { -- refport = outport; - nr_conns = csdev->pdata->nr_outport; - } else { -- refport = 0; - nr_conns = 1; - } - -- if (atomic_dec_return(&csdev->refcnt[refport]) == 0) { -- if (link_ops(csdev)->disable) -- link_ops(csdev)->disable(csdev, inport, outport); -- } -+ if (link_ops(csdev)->disable) -+ link_ops(csdev)->disable(csdev, inport, outport); - - for (i = 0; i < nr_conns; i++) - if (atomic_read(&csdev->refcnt[i]) != 0) -diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c -index d5c1821b31c6..0dfd97bbde9e 100644 ---- a/drivers/hwtracing/intel_th/core.c -+++ b/drivers/hwtracing/intel_th/core.c -@@ -649,10 +649,8 @@ intel_th_subdevice_alloc(struct intel_th *th, - } - - err = intel_th_device_add_resources(thdev, res, subdev->nres); -- if (err) { -- put_device(&thdev->dev); -+ if (err) - goto fail_put_device; -- } - - if (subdev->type == INTEL_TH_OUTPUT) { - if (subdev->mknode) -@@ -667,10 +665,8 @@ intel_th_subdevice_alloc(struct intel_th *th, - } - - err = device_add(&thdev->dev); -- if (err) { -- put_device(&thdev->dev); -+ if (err) - goto fail_free_res; -- } - - /* need switch driver to be loaded to enumerate the rest */ - if (subdev->type == INTEL_TH_SWITCH && !req) { -diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c -index 03ca5b1bef9f..ebf3e30e989a 100644 ---- a/drivers/hwtracing/intel_th/pci.c -+++ b/drivers/hwtracing/intel_th/pci.c -@@ -209,6 +209,16 @@ static const struct pci_device_id intel_th_pci_id_table[] = { - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, -+ { -+ /* Ice Lake CPU */ -+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29), -+ .driver_data = (kernel_ulong_t)&intel_th_2x, -+ }, -+ { -+ /* Tiger Lake CPU */ -+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33), -+ .driver_data = (kernel_ulong_t)&intel_th_2x, -+ }, - { - /* Tiger Lake PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), -diff --git a/drivers/hwtracing/stm/policy.c b/drivers/hwtracing/stm/policy.c -index 4b9e44b227d8..4f932a419752 100644 ---- a/drivers/hwtracing/stm/policy.c -+++ b/drivers/hwtracing/stm/policy.c -@@ -345,7 +345,11 @@ void stp_policy_unbind(struct stp_policy *policy) - stm->policy = NULL; - policy->stm = NULL; - -+ /* -+ * Drop the reference on the protocol driver and lose the link. -+ */ - stm_put_protocol(stm->pdrv); -+ stm->pdrv = NULL; - stm_put_device(stm); - } - -diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c -index edc6f1cc90b2..3f03abf100b5 100644 ---- a/drivers/iio/adc/ad7124.c -+++ b/drivers/iio/adc/ad7124.c -@@ -39,6 +39,8 @@ - #define AD7124_STATUS_POR_FLAG_MSK BIT(4) - - /* AD7124_ADC_CONTROL */ -+#define AD7124_ADC_CTRL_REF_EN_MSK BIT(8) -+#define AD7124_ADC_CTRL_REF_EN(x) FIELD_PREP(AD7124_ADC_CTRL_REF_EN_MSK, x) - #define AD7124_ADC_CTRL_PWR_MSK GENMASK(7, 6) - #define AD7124_ADC_CTRL_PWR(x) FIELD_PREP(AD7124_ADC_CTRL_PWR_MSK, x) - #define AD7124_ADC_CTRL_MODE_MSK GENMASK(5, 2) -@@ -424,7 +426,10 @@ static int ad7124_init_channel_vref(struct ad7124_state *st, - break; - case AD7124_INT_REF: - st->channel_config[channel_number].vref_mv = 2500; -- break; -+ st->adc_control &= ~AD7124_ADC_CTRL_REF_EN_MSK; -+ st->adc_control |= AD7124_ADC_CTRL_REF_EN(1); -+ return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, -+ 2, st->adc_control); - default: - dev_err(&st->sd.spi->dev, "Invalid reference %d\n", refsel); - return -EINVAL; -diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c -index f5ba94c03a8d..e4683a68522a 100644 ---- a/drivers/iio/adc/ad7606.c -+++ b/drivers/iio/adc/ad7606.c -@@ -85,7 +85,7 @@ err_unlock: - - static int ad7606_read_samples(struct ad7606_state *st) - { -- unsigned int num = st->chip_info->num_channels; -+ unsigned int num = st->chip_info->num_channels - 1; - u16 *data = st->data; - int ret; - -diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c -index ac0ffff6c5ae..6b51bfcad0d0 100644 ---- a/drivers/iio/adc/ad7949.c -+++ b/drivers/iio/adc/ad7949.c -@@ -57,29 +57,11 @@ struct ad7949_adc_chip { - u32 buffer ____cacheline_aligned; - }; - --static bool ad7949_spi_cfg_is_read_back(struct ad7949_adc_chip *ad7949_adc) --{ -- if (!(ad7949_adc->cfg & AD7949_CFG_READ_BACK)) -- return true; -- -- return false; --} -- --static int ad7949_spi_bits_per_word(struct ad7949_adc_chip *ad7949_adc) --{ -- int ret = ad7949_adc->resolution; -- -- if (ad7949_spi_cfg_is_read_back(ad7949_adc)) -- ret += AD7949_CFG_REG_SIZE_BITS; -- -- return ret; --} -- - static int ad7949_spi_write_cfg(struct ad7949_adc_chip *ad7949_adc, u16 val, - u16 mask) - { - int ret; -- int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc); -+ int bits_per_word = ad7949_adc->resolution; - int shift = bits_per_word - AD7949_CFG_REG_SIZE_BITS; - struct spi_message msg; - struct spi_transfer tx[] = { -@@ -107,7 +89,8 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val, - unsigned int channel) - { - int ret; -- int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc); -+ int i; -+ int bits_per_word = ad7949_adc->resolution; - int mask = GENMASK(ad7949_adc->resolution, 0); - struct spi_message msg; - struct spi_transfer tx[] = { -@@ -118,12 +101,23 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val, - }, - }; - -- ret = ad7949_spi_write_cfg(ad7949_adc, -- channel << AD7949_OFFSET_CHANNEL_SEL, -- AD7949_MASK_CHANNEL_SEL); -- if (ret) -- return ret; -+ /* -+ * 1: write CFG for sample N and read old data (sample N-2) -+ * 2: if CFG was not changed since sample N-1 then we'll get good data -+ * at the next xfer, so we bail out now, otherwise we write something -+ * and we read garbage (sample N-1 configuration). -+ */ -+ for (i = 0; i < 2; i++) { -+ ret = ad7949_spi_write_cfg(ad7949_adc, -+ channel << AD7949_OFFSET_CHANNEL_SEL, -+ AD7949_MASK_CHANNEL_SEL); -+ if (ret) -+ return ret; -+ if (channel == ad7949_adc->current_channel) -+ break; -+ } - -+ /* 3: write something and read actual data */ - ad7949_adc->buffer = 0; - spi_message_init_with_transfers(&msg, tx, 1); - ret = spi_sync(ad7949_adc->spi, &msg); -@@ -138,10 +132,7 @@ static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val, - - ad7949_adc->current_channel = channel; - -- if (ad7949_spi_cfg_is_read_back(ad7949_adc)) -- *val = (ad7949_adc->buffer >> AD7949_CFG_REG_SIZE_BITS) & mask; -- else -- *val = ad7949_adc->buffer & mask; -+ *val = ad7949_adc->buffer & mask; - - return 0; - } -diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c -index bfe1cdb16846..dcf5a5bdfaa8 100644 ---- a/drivers/iio/humidity/hdc100x.c -+++ b/drivers/iio/humidity/hdc100x.c -@@ -229,7 +229,7 @@ static int hdc100x_read_raw(struct iio_dev *indio_dev, - *val2 = 65536; - return IIO_VAL_FRACTIONAL; - } else { -- *val = 100; -+ *val = 100000; - *val2 = 65536; - return IIO_VAL_FRACTIONAL; - } -diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c -index 8743b2f376e2..7b966a41d623 100644 ---- a/drivers/iio/imu/adis16480.c -+++ b/drivers/iio/imu/adis16480.c -@@ -623,9 +623,13 @@ static int adis16480_read_raw(struct iio_dev *indio_dev, - *val2 = (st->chip_info->temp_scale % 1000) * 1000; - return IIO_VAL_INT_PLUS_MICRO; - case IIO_PRESSURE: -- *val = 0; -- *val2 = 4000; /* 40ubar = 0.004 kPa */ -- return IIO_VAL_INT_PLUS_MICRO; -+ /* -+ * max scale is 1310 mbar -+ * max raw value is 32767 shifted for 32bits -+ */ -+ *val = 131; /* 1310mbar = 131 kPa */ -+ *val2 = 32767 << 16; -+ return IIO_VAL_FRACTIONAL; - default: - return -EINVAL; - } -@@ -786,13 +790,14 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - .channels = adis16485_channels, - .num_channels = ARRAY_SIZE(adis16485_channels), - /* -- * storing the value in rad/degree and the scale in degree -- * gives us the result in rad and better precession than -- * storing the scale directly in rad. -+ * Typically we do IIO_RAD_TO_DEGREE in the denominator, which -+ * is exactly the same as IIO_DEGREE_TO_RAD in numerator, since -+ * it gives better approximation. However, in this case we -+ * cannot do it since it would not fit in a 32bit variable. - */ -- .gyro_max_val = IIO_RAD_TO_DEGREE(22887), -- .gyro_max_scale = 300, -- .accel_max_val = IIO_M_S_2_TO_G(21973), -+ .gyro_max_val = 22887 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(300), -+ .accel_max_val = IIO_M_S_2_TO_G(21973 << 16), - .accel_max_scale = 18, - .temp_scale = 5650, /* 5.65 milli degree Celsius */ - .int_clk = 2460000, -@@ -802,9 +807,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16480] = { - .channels = adis16480_channels, - .num_channels = ARRAY_SIZE(adis16480_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(22500), -- .gyro_max_scale = 450, -- .accel_max_val = IIO_M_S_2_TO_G(12500), -+ .gyro_max_val = 22500 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(450), -+ .accel_max_val = IIO_M_S_2_TO_G(12500 << 16), - .accel_max_scale = 10, - .temp_scale = 5650, /* 5.65 milli degree Celsius */ - .int_clk = 2460000, -@@ -814,9 +819,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16485] = { - .channels = adis16485_channels, - .num_channels = ARRAY_SIZE(adis16485_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(22500), -- .gyro_max_scale = 450, -- .accel_max_val = IIO_M_S_2_TO_G(20000), -+ .gyro_max_val = 22500 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(450), -+ .accel_max_val = IIO_M_S_2_TO_G(20000 << 16), - .accel_max_scale = 5, - .temp_scale = 5650, /* 5.65 milli degree Celsius */ - .int_clk = 2460000, -@@ -826,9 +831,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16488] = { - .channels = adis16480_channels, - .num_channels = ARRAY_SIZE(adis16480_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(22500), -- .gyro_max_scale = 450, -- .accel_max_val = IIO_M_S_2_TO_G(22500), -+ .gyro_max_val = 22500 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(450), -+ .accel_max_val = IIO_M_S_2_TO_G(22500 << 16), - .accel_max_scale = 18, - .temp_scale = 5650, /* 5.65 milli degree Celsius */ - .int_clk = 2460000, -@@ -838,9 +843,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16495_1] = { - .channels = adis16485_channels, - .num_channels = ARRAY_SIZE(adis16485_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(20000), -- .gyro_max_scale = 125, -- .accel_max_val = IIO_M_S_2_TO_G(32000), -+ .gyro_max_val = 20000 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(125), -+ .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), - .accel_max_scale = 8, - .temp_scale = 12500, /* 12.5 milli degree Celsius */ - .int_clk = 4250000, -@@ -851,9 +856,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16495_2] = { - .channels = adis16485_channels, - .num_channels = ARRAY_SIZE(adis16485_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(18000), -- .gyro_max_scale = 450, -- .accel_max_val = IIO_M_S_2_TO_G(32000), -+ .gyro_max_val = 18000 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(450), -+ .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), - .accel_max_scale = 8, - .temp_scale = 12500, /* 12.5 milli degree Celsius */ - .int_clk = 4250000, -@@ -864,9 +869,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16495_3] = { - .channels = adis16485_channels, - .num_channels = ARRAY_SIZE(adis16485_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(20000), -- .gyro_max_scale = 2000, -- .accel_max_val = IIO_M_S_2_TO_G(32000), -+ .gyro_max_val = 20000 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(2000), -+ .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), - .accel_max_scale = 8, - .temp_scale = 12500, /* 12.5 milli degree Celsius */ - .int_clk = 4250000, -@@ -877,9 +882,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16497_1] = { - .channels = adis16485_channels, - .num_channels = ARRAY_SIZE(adis16485_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(20000), -- .gyro_max_scale = 125, -- .accel_max_val = IIO_M_S_2_TO_G(32000), -+ .gyro_max_val = 20000 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(125), -+ .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), - .accel_max_scale = 40, - .temp_scale = 12500, /* 12.5 milli degree Celsius */ - .int_clk = 4250000, -@@ -890,9 +895,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16497_2] = { - .channels = adis16485_channels, - .num_channels = ARRAY_SIZE(adis16485_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(18000), -- .gyro_max_scale = 450, -- .accel_max_val = IIO_M_S_2_TO_G(32000), -+ .gyro_max_val = 18000 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(450), -+ .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), - .accel_max_scale = 40, - .temp_scale = 12500, /* 12.5 milli degree Celsius */ - .int_clk = 4250000, -@@ -903,9 +908,9 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { - [ADIS16497_3] = { - .channels = adis16485_channels, - .num_channels = ARRAY_SIZE(adis16485_channels), -- .gyro_max_val = IIO_RAD_TO_DEGREE(20000), -- .gyro_max_scale = 2000, -- .accel_max_val = IIO_M_S_2_TO_G(32000), -+ .gyro_max_val = 20000 << 16, -+ .gyro_max_scale = IIO_DEGREE_TO_RAD(2000), -+ .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), - .accel_max_scale = 40, - .temp_scale = 12500, /* 12.5 milli degree Celsius */ - .int_clk = 4250000, -@@ -919,6 +924,7 @@ static const struct iio_info adis16480_info = { - .read_raw = &adis16480_read_raw, - .write_raw = &adis16480_write_raw, - .update_scan_mode = adis_update_scan_mode, -+ .debugfs_reg_access = adis_debugfs_reg_access, - }; - - static int adis16480_stop_device(struct iio_dev *indio_dev) -diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c -index 868281b8adb0..2261c6c4ac65 100644 ---- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c -+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c -@@ -115,6 +115,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_6050, - .config = &chip_config_6050, - .fifo_size = 1024, -+ .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, - }, - { - .whoami = INV_MPU6500_WHOAMI_VALUE, -@@ -122,6 +123,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_6500, - .config = &chip_config_6050, - .fifo_size = 512, -+ .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, - }, - { - .whoami = INV_MPU6515_WHOAMI_VALUE, -@@ -129,6 +131,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_6500, - .config = &chip_config_6050, - .fifo_size = 512, -+ .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, - }, - { - .whoami = INV_MPU6000_WHOAMI_VALUE, -@@ -136,6 +139,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_6050, - .config = &chip_config_6050, - .fifo_size = 1024, -+ .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, - }, - { - .whoami = INV_MPU9150_WHOAMI_VALUE, -@@ -143,6 +147,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_6050, - .config = &chip_config_6050, - .fifo_size = 1024, -+ .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, - }, - { - .whoami = INV_MPU9250_WHOAMI_VALUE, -@@ -150,6 +155,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_6500, - .config = &chip_config_6050, - .fifo_size = 512, -+ .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, - }, - { - .whoami = INV_MPU9255_WHOAMI_VALUE, -@@ -157,6 +163,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_6500, - .config = &chip_config_6050, - .fifo_size = 512, -+ .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, - }, - { - .whoami = INV_ICM20608_WHOAMI_VALUE, -@@ -164,6 +171,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_6500, - .config = &chip_config_6050, - .fifo_size = 512, -+ .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, - }, - { - .whoami = INV_ICM20602_WHOAMI_VALUE, -@@ -171,6 +179,7 @@ static const struct inv_mpu6050_hw hw_info[] = { - .reg = ®_set_icm20602, - .config = &chip_config_6050, - .fifo_size = 1008, -+ .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, - }, - }; - -@@ -471,12 +480,8 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, - - return IIO_VAL_INT_PLUS_MICRO; - case IIO_TEMP: -- *val = 0; -- if (st->chip_type == INV_ICM20602) -- *val2 = INV_ICM20602_TEMP_SCALE; -- else -- *val2 = INV_MPU6050_TEMP_SCALE; -- -+ *val = st->hw->temp.scale / 1000000; -+ *val2 = st->hw->temp.scale % 1000000; - return IIO_VAL_INT_PLUS_MICRO; - default: - return -EINVAL; -@@ -484,11 +489,7 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, - case IIO_CHAN_INFO_OFFSET: - switch (chan->type) { - case IIO_TEMP: -- if (st->chip_type == INV_ICM20602) -- *val = INV_ICM20602_TEMP_OFFSET; -- else -- *val = INV_MPU6050_TEMP_OFFSET; -- -+ *val = st->hw->temp.offset; - return IIO_VAL_INT; - default: - return -EINVAL; -diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h -index 51235677c534..c32bd0c012b5 100644 ---- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h -+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h -@@ -101,6 +101,7 @@ struct inv_mpu6050_chip_config { - * @reg: register map of the chip. - * @config: configuration of the chip. - * @fifo_size: size of the FIFO in bytes. -+ * @temp: offset and scale to apply to raw temperature. - */ - struct inv_mpu6050_hw { - u8 whoami; -@@ -108,6 +109,10 @@ struct inv_mpu6050_hw { - const struct inv_mpu6050_reg_map *reg; - const struct inv_mpu6050_chip_config *config; - size_t fifo_size; -+ struct { -+ int offset; -+ int scale; -+ } temp; - }; - - /* -@@ -218,16 +223,19 @@ struct inv_mpu6050_state { - #define INV_MPU6050_REG_UP_TIME_MIN 5000 - #define INV_MPU6050_REG_UP_TIME_MAX 10000 - --#define INV_MPU6050_TEMP_OFFSET 12421 --#define INV_MPU6050_TEMP_SCALE 2941 -+#define INV_MPU6050_TEMP_OFFSET 12420 -+#define INV_MPU6050_TEMP_SCALE 2941176 - #define INV_MPU6050_MAX_GYRO_FS_PARAM 3 - #define INV_MPU6050_MAX_ACCL_FS_PARAM 3 - #define INV_MPU6050_THREE_AXIS 3 - #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3 - #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3 - --#define INV_ICM20602_TEMP_OFFSET 8170 --#define INV_ICM20602_TEMP_SCALE 3060 -+#define INV_MPU6500_TEMP_OFFSET 7011 -+#define INV_MPU6500_TEMP_SCALE 2995178 -+ -+#define INV_ICM20608_TEMP_OFFSET 8170 -+#define INV_ICM20608_TEMP_SCALE 3059976 - - /* 6 + 6 round up and plus 8 */ - #define INV_MPU6050_OUTPUT_DATA_SIZE 24 -diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c -index fd5ebe1e1594..28e011b35f21 100644 ---- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c -+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c -@@ -985,8 +985,7 @@ int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val) - return -EINVAL; - - *val = odr_table->odr_avl[i].val; -- -- return 0; -+ return odr_table->odr_avl[i].hz; - } - - static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr, -@@ -1149,8 +1148,10 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, - case IIO_CHAN_INFO_SAMP_FREQ: { - u8 data; - -- err = st_lsm6dsx_check_odr(sensor, val, &data); -- if (!err) -+ val = st_lsm6dsx_check_odr(sensor, val, &data); -+ if (val < 0) -+ err = val; -+ else - sensor->odr = val; - break; - } -diff --git a/drivers/interconnect/qcom/qcs404.c b/drivers/interconnect/qcom/qcs404.c -index b4966d8f3348..8e0735a87040 100644 ---- a/drivers/interconnect/qcom/qcs404.c -+++ b/drivers/interconnect/qcom/qcs404.c -@@ -414,7 +414,7 @@ static int qnoc_probe(struct platform_device *pdev) - struct icc_provider *provider; - struct qcom_icc_node **qnodes; - struct qcom_icc_provider *qp; -- struct icc_node *node; -+ struct icc_node *node, *tmp; - size_t num_nodes, i; - int ret; - -@@ -494,7 +494,7 @@ static int qnoc_probe(struct platform_device *pdev) - - return 0; - err: -- list_for_each_entry(node, &provider->nodes, node_list) { -+ list_for_each_entry_safe(node, tmp, &provider->nodes, node_list) { - icc_node_del(node); - icc_node_destroy(node->id); - } -@@ -508,9 +508,9 @@ static int qnoc_remove(struct platform_device *pdev) - { - struct qcom_icc_provider *qp = platform_get_drvdata(pdev); - struct icc_provider *provider = &qp->provider; -- struct icc_node *n; -+ struct icc_node *n, *tmp; - -- list_for_each_entry(n, &provider->nodes, node_list) { -+ list_for_each_entry_safe(n, tmp, &provider->nodes, node_list) { - icc_node_del(n); - icc_node_destroy(n->id); - } -diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c -index 502a6c22b41e..387267ee9648 100644 ---- a/drivers/interconnect/qcom/sdm845.c -+++ b/drivers/interconnect/qcom/sdm845.c -@@ -868,9 +868,9 @@ static int qnoc_remove(struct platform_device *pdev) - { - struct qcom_icc_provider *qp = platform_get_drvdata(pdev); - struct icc_provider *provider = &qp->provider; -- struct icc_node *n; -+ struct icc_node *n, *tmp; - -- list_for_each_entry(n, &provider->nodes, node_list) { -+ list_for_each_entry_safe(n, tmp, &provider->nodes, node_list) { - icc_node_del(n); - icc_node_destroy(n->id); - } -diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c -index d06b8aa41e26..43d1af1d8173 100644 ---- a/drivers/md/dm-writecache.c -+++ b/drivers/md/dm-writecache.c -@@ -1218,7 +1218,8 @@ bio_copy: - } - } while (bio->bi_iter.bi_size); - -- if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) -+ if (unlikely(bio->bi_opf & REQ_FUA || -+ wc->uncommitted_blocks >= wc->autocommit_blocks)) - writecache_flush(wc); - else - writecache_schedule_autocommit(wc); -diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c -index 595a73110e17..ac1179ca80d9 100644 ---- a/drivers/md/dm-zoned-metadata.c -+++ b/drivers/md/dm-zoned-metadata.c -@@ -554,6 +554,7 @@ static struct dmz_mblock *dmz_get_mblock(struct dmz_metadata *zmd, - TASK_UNINTERRUPTIBLE); - if (test_bit(DMZ_META_ERROR, &mblk->state)) { - dmz_release_mblock(zmd, mblk); -+ dmz_check_bdev(zmd->dev); - return ERR_PTR(-EIO); - } - -@@ -625,6 +626,8 @@ static int dmz_rdwr_block(struct dmz_metadata *zmd, int op, sector_t block, - ret = submit_bio_wait(bio); - bio_put(bio); - -+ if (ret) -+ dmz_check_bdev(zmd->dev); - return ret; - } - -@@ -691,6 +694,7 @@ static int dmz_write_dirty_mblocks(struct dmz_metadata *zmd, - TASK_UNINTERRUPTIBLE); - if (test_bit(DMZ_META_ERROR, &mblk->state)) { - clear_bit(DMZ_META_ERROR, &mblk->state); -+ dmz_check_bdev(zmd->dev); - ret = -EIO; - } - nr_mblks_submitted--; -@@ -768,7 +772,7 @@ int dmz_flush_metadata(struct dmz_metadata *zmd) - /* If there are no dirty metadata blocks, just flush the device cache */ - if (list_empty(&write_list)) { - ret = blkdev_issue_flush(zmd->dev->bdev, GFP_NOIO, NULL); -- goto out; -+ goto err; - } - - /* -@@ -778,7 +782,7 @@ int dmz_flush_metadata(struct dmz_metadata *zmd) - */ - ret = dmz_log_dirty_mblocks(zmd, &write_list); - if (ret) -- goto out; -+ goto err; - - /* - * The log is on disk. It is now safe to update in place -@@ -786,11 +790,11 @@ int dmz_flush_metadata(struct dmz_metadata *zmd) - */ - ret = dmz_write_dirty_mblocks(zmd, &write_list, zmd->mblk_primary); - if (ret) -- goto out; -+ goto err; - - ret = dmz_write_sb(zmd, zmd->mblk_primary); - if (ret) -- goto out; -+ goto err; - - while (!list_empty(&write_list)) { - mblk = list_first_entry(&write_list, struct dmz_mblock, link); -@@ -805,16 +809,20 @@ int dmz_flush_metadata(struct dmz_metadata *zmd) - - zmd->sb_gen++; - out: -- if (ret && !list_empty(&write_list)) { -- spin_lock(&zmd->mblk_lock); -- list_splice(&write_list, &zmd->mblk_dirty_list); -- spin_unlock(&zmd->mblk_lock); -- } -- - dmz_unlock_flush(zmd); - up_write(&zmd->mblk_sem); - - return ret; -+ -+err: -+ if (!list_empty(&write_list)) { -+ spin_lock(&zmd->mblk_lock); -+ list_splice(&write_list, &zmd->mblk_dirty_list); -+ spin_unlock(&zmd->mblk_lock); -+ } -+ if (!dmz_check_bdev(zmd->dev)) -+ ret = -EIO; -+ goto out; - } - - /* -@@ -1244,6 +1252,7 @@ static int dmz_update_zone(struct dmz_metadata *zmd, struct dm_zone *zone) - if (ret) { - dmz_dev_err(zmd->dev, "Get zone %u report failed", - dmz_id(zmd, zone)); -+ dmz_check_bdev(zmd->dev); - return ret; - } - -diff --git a/drivers/md/dm-zoned-reclaim.c b/drivers/md/dm-zoned-reclaim.c -index d240d7ca8a8a..e7ace908a9b7 100644 ---- a/drivers/md/dm-zoned-reclaim.c -+++ b/drivers/md/dm-zoned-reclaim.c -@@ -82,6 +82,7 @@ static int dmz_reclaim_align_wp(struct dmz_reclaim *zrc, struct dm_zone *zone, - "Align zone %u wp %llu to %llu (wp+%u) blocks failed %d", - dmz_id(zmd, zone), (unsigned long long)wp_block, - (unsigned long long)block, nr_blocks, ret); -+ dmz_check_bdev(zrc->dev); - return ret; - } - -@@ -489,12 +490,7 @@ static void dmz_reclaim_work(struct work_struct *work) - ret = dmz_do_reclaim(zrc); - if (ret) { - dmz_dev_debug(zrc->dev, "Reclaim error %d\n", ret); -- if (ret == -EIO) -- /* -- * LLD might be performing some error handling sequence -- * at the underlying device. To not interfere, do not -- * attempt to schedule the next reclaim run immediately. -- */ -+ if (!dmz_check_bdev(zrc->dev)) - return; - } - -diff --git a/drivers/md/dm-zoned-target.c b/drivers/md/dm-zoned-target.c -index d3bcc4197f5d..4574e0dedbd6 100644 ---- a/drivers/md/dm-zoned-target.c -+++ b/drivers/md/dm-zoned-target.c -@@ -80,6 +80,8 @@ static inline void dmz_bio_endio(struct bio *bio, blk_status_t status) - - if (status != BLK_STS_OK && bio->bi_status == BLK_STS_OK) - bio->bi_status = status; -+ if (bio->bi_status != BLK_STS_OK) -+ bioctx->target->dev->flags |= DMZ_CHECK_BDEV; - - if (refcount_dec_and_test(&bioctx->ref)) { - struct dm_zone *zone = bioctx->zone; -@@ -565,31 +567,51 @@ out: - } - - /* -- * Check the backing device availability. If it's on the way out, -+ * Check if the backing device is being removed. If it's on the way out, - * start failing I/O. Reclaim and metadata components also call this - * function to cleanly abort operation in the event of such failure. - */ - bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev) - { -- struct gendisk *disk; -+ if (dmz_dev->flags & DMZ_BDEV_DYING) -+ return true; - -- if (!(dmz_dev->flags & DMZ_BDEV_DYING)) { -- disk = dmz_dev->bdev->bd_disk; -- if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) { -- dmz_dev_warn(dmz_dev, "Backing device queue dying"); -- dmz_dev->flags |= DMZ_BDEV_DYING; -- } else if (disk->fops->check_events) { -- if (disk->fops->check_events(disk, 0) & -- DISK_EVENT_MEDIA_CHANGE) { -- dmz_dev_warn(dmz_dev, "Backing device offline"); -- dmz_dev->flags |= DMZ_BDEV_DYING; -- } -- } -+ if (dmz_dev->flags & DMZ_CHECK_BDEV) -+ return !dmz_check_bdev(dmz_dev); -+ -+ if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) { -+ dmz_dev_warn(dmz_dev, "Backing device queue dying"); -+ dmz_dev->flags |= DMZ_BDEV_DYING; - } - - return dmz_dev->flags & DMZ_BDEV_DYING; - } - -+/* -+ * Check the backing device availability. This detects such events as -+ * backing device going offline due to errors, media removals, etc. -+ * This check is less efficient than dmz_bdev_is_dying() and should -+ * only be performed as a part of error handling. -+ */ -+bool dmz_check_bdev(struct dmz_dev *dmz_dev) -+{ -+ struct gendisk *disk; -+ -+ dmz_dev->flags &= ~DMZ_CHECK_BDEV; -+ -+ if (dmz_bdev_is_dying(dmz_dev)) -+ return false; -+ -+ disk = dmz_dev->bdev->bd_disk; -+ if (disk->fops->check_events && -+ disk->fops->check_events(disk, 0) & DISK_EVENT_MEDIA_CHANGE) { -+ dmz_dev_warn(dmz_dev, "Backing device offline"); -+ dmz_dev->flags |= DMZ_BDEV_DYING; -+ } -+ -+ return !(dmz_dev->flags & DMZ_BDEV_DYING); -+} -+ - /* - * Process a new BIO. - */ -@@ -902,8 +924,8 @@ static int dmz_prepare_ioctl(struct dm_target *ti, struct block_device **bdev) - { - struct dmz_target *dmz = ti->private; - -- if (dmz_bdev_is_dying(dmz->dev)) -- return -ENODEV; -+ if (!dmz_check_bdev(dmz->dev)) -+ return -EIO; - - *bdev = dmz->dev->bdev; - -diff --git a/drivers/md/dm-zoned.h b/drivers/md/dm-zoned.h -index d8e70b0ade35..5b5e493d479c 100644 ---- a/drivers/md/dm-zoned.h -+++ b/drivers/md/dm-zoned.h -@@ -72,6 +72,7 @@ struct dmz_dev { - - /* Device flags. */ - #define DMZ_BDEV_DYING (1 << 0) -+#define DMZ_CHECK_BDEV (2 << 0) - - /* - * Zone descriptor. -@@ -255,5 +256,6 @@ void dmz_schedule_reclaim(struct dmz_reclaim *zrc); - * Functions defined in dm-zoned-target.c - */ - bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev); -+bool dmz_check_bdev(struct dmz_dev *dmz_dev); - - #endif /* DM_ZONED_H */ -diff --git a/drivers/md/md-linear.c b/drivers/md/md-linear.c -index c766c559d36d..26c75c0199fa 100644 ---- a/drivers/md/md-linear.c -+++ b/drivers/md/md-linear.c -@@ -244,10 +244,9 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio) - sector_t start_sector, end_sector, data_offset; - sector_t bio_sector = bio->bi_iter.bi_sector; - -- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { -- md_flush_request(mddev, bio); -+ if (unlikely(bio->bi_opf & REQ_PREFLUSH) -+ && md_flush_request(mddev, bio)) - return true; -- } - - tmp_dev = which_dev(mddev, bio_sector); - start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors; -diff --git a/drivers/md/md-multipath.c b/drivers/md/md-multipath.c -index 6780938d2991..152f9e65a226 100644 ---- a/drivers/md/md-multipath.c -+++ b/drivers/md/md-multipath.c -@@ -104,10 +104,9 @@ static bool multipath_make_request(struct mddev *mddev, struct bio * bio) - struct multipath_bh * mp_bh; - struct multipath_info *multipath; - -- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { -- md_flush_request(mddev, bio); -+ if (unlikely(bio->bi_opf & REQ_PREFLUSH) -+ && md_flush_request(mddev, bio)) - return true; -- } - - mp_bh = mempool_alloc(&conf->pool, GFP_NOIO); - -diff --git a/drivers/md/md.c b/drivers/md/md.c -index 1be7abeb24fd..b8dd56b746da 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -550,7 +550,13 @@ static void md_submit_flush_data(struct work_struct *ws) - } - } - --void md_flush_request(struct mddev *mddev, struct bio *bio) -+/* -+ * Manages consolidation of flushes and submitting any flushes needed for -+ * a bio with REQ_PREFLUSH. Returns true if the bio is finished or is -+ * being finished in another context. Returns false if the flushing is -+ * complete but still needs the I/O portion of the bio to be processed. -+ */ -+bool md_flush_request(struct mddev *mddev, struct bio *bio) - { - ktime_t start = ktime_get_boottime(); - spin_lock_irq(&mddev->lock); -@@ -575,9 +581,10 @@ void md_flush_request(struct mddev *mddev, struct bio *bio) - bio_endio(bio); - else { - bio->bi_opf &= ~REQ_PREFLUSH; -- mddev->pers->make_request(mddev, bio); -+ return false; - } - } -+ return true; - } - EXPORT_SYMBOL(md_flush_request); - -diff --git a/drivers/md/md.h b/drivers/md/md.h -index c5e3ff398b59..5f86f8adb0a4 100644 ---- a/drivers/md/md.h -+++ b/drivers/md/md.h -@@ -550,7 +550,7 @@ struct md_personality - int level; - struct list_head list; - struct module *owner; -- bool (*make_request)(struct mddev *mddev, struct bio *bio); -+ bool __must_check (*make_request)(struct mddev *mddev, struct bio *bio); - /* - * start up works that do NOT require md_thread. tasks that - * requires md_thread should go into start() -@@ -703,7 +703,7 @@ extern void md_error(struct mddev *mddev, struct md_rdev *rdev); - extern void md_finish_reshape(struct mddev *mddev); - - extern int mddev_congested(struct mddev *mddev, int bits); --extern void md_flush_request(struct mddev *mddev, struct bio *bio); -+extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio); - extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev, - sector_t sector, int size, struct page *page); - extern int md_super_wait(struct mddev *mddev); -diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c -index aa88bdeb9978..b7c20979bd19 100644 ---- a/drivers/md/raid0.c -+++ b/drivers/md/raid0.c -@@ -575,10 +575,9 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio) - unsigned chunk_sects; - unsigned sectors; - -- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { -- md_flush_request(mddev, bio); -+ if (unlikely(bio->bi_opf & REQ_PREFLUSH) -+ && md_flush_request(mddev, bio)) - return true; -- } - - if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) { - raid0_handle_discard(mddev, bio); -diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c -index 0466ee2453b4..bb29aeefcbd0 100644 ---- a/drivers/md/raid1.c -+++ b/drivers/md/raid1.c -@@ -1567,10 +1567,9 @@ static bool raid1_make_request(struct mddev *mddev, struct bio *bio) - { - sector_t sectors; - -- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { -- md_flush_request(mddev, bio); -+ if (unlikely(bio->bi_opf & REQ_PREFLUSH) -+ && md_flush_request(mddev, bio)) - return true; -- } - - /* - * There is a limit to the maximum size, but -diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c -index 8a62c920bb65..ec136e44aef7 100644 ---- a/drivers/md/raid10.c -+++ b/drivers/md/raid10.c -@@ -1525,10 +1525,9 @@ static bool raid10_make_request(struct mddev *mddev, struct bio *bio) - int chunk_sects = chunk_mask + 1; - int sectors = bio_sectors(bio); - -- if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { -- md_flush_request(mddev, bio); -+ if (unlikely(bio->bi_opf & REQ_PREFLUSH) -+ && md_flush_request(mddev, bio)) - return true; -- } - - if (!md_write_start(mddev, bio)) - return false; -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index 223e97ab27e6..12a8ce83786e 100644 ---- a/drivers/md/raid5.c -+++ b/drivers/md/raid5.c -@@ -5592,8 +5592,8 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi) - if (ret == 0) - return true; - if (ret == -ENODEV) { -- md_flush_request(mddev, bi); -- return true; -+ if (md_flush_request(mddev, bi)) -+ return true; - } - /* ret == -EAGAIN, fallback */ - /* -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index 952fa4063ff8..d0df054b0b47 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -1512,6 +1512,36 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card) - - if (mmc_pdata(host)->init_card) - mmc_pdata(host)->init_card(card); -+ else if (card->type == MMC_TYPE_SDIO || -+ card->type == MMC_TYPE_SD_COMBO) { -+ struct device_node *np = mmc_dev(mmc)->of_node; -+ -+ /* -+ * REVISIT: should be moved to sdio core and made more -+ * general e.g. by expanding the DT bindings of child nodes -+ * to provide a mechanism to provide this information: -+ * Documentation/devicetree/bindings/mmc/mmc-card.txt -+ */ -+ -+ np = of_get_compatible_child(np, "ti,wl1251"); -+ if (np) { -+ /* -+ * We have TI wl1251 attached to MMC3. Pass this -+ * information to the SDIO core because it can't be -+ * probed by normal methods. -+ */ -+ -+ dev_info(host->dev, "found wl1251\n"); -+ card->quirks |= MMC_QUIRK_NONSTD_SDIO; -+ card->cccr.wide_bus = 1; -+ card->cis.vendor = 0x104c; -+ card->cis.device = 0x9066; -+ card->cis.blksize = 512; -+ card->cis.max_dtr = 24000000; -+ card->ocr = 0x80; -+ of_node_put(np); -+ } -+ } - } - - static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable) -diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c -index 986f81d2f93e..47ad0766affa 100644 ---- a/drivers/mtd/devices/spear_smi.c -+++ b/drivers/mtd/devices/spear_smi.c -@@ -592,6 +592,26 @@ static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, - return 0; - } - -+/* -+ * The purpose of this function is to ensure a memcpy_toio() with byte writes -+ * only. Its structure is inspired from the ARM implementation of _memcpy_toio() -+ * which also does single byte writes but cannot be used here as this is just an -+ * implementation detail and not part of the API. Not mentioning the comment -+ * stating that _memcpy_toio() should be optimized. -+ */ -+static void spear_smi_memcpy_toio_b(volatile void __iomem *dest, -+ const void *src, size_t len) -+{ -+ const unsigned char *from = src; -+ -+ while (len) { -+ len--; -+ writeb(*from, dest); -+ from++; -+ dest++; -+ } -+} -+ - static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank, - void __iomem *dest, const void *src, size_t len) - { -@@ -614,7 +634,23 @@ static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank, - ctrlreg1 = readl(dev->io_base + SMI_CR1); - writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1); - -- memcpy_toio(dest, src, len); -+ /* -+ * In Write Burst mode (WB_MODE), the specs states that writes must be: -+ * - incremental -+ * - of the same size -+ * The ARM implementation of memcpy_toio() will optimize the number of -+ * I/O by using as much 4-byte writes as possible, surrounded by -+ * 2-byte/1-byte access if: -+ * - the destination is not 4-byte aligned -+ * - the length is not a multiple of 4-byte. -+ * Avoid this alternance of write access size by using our own 'byte -+ * access' helper if at least one of the two conditions above is true. -+ */ -+ if (IS_ALIGNED(len, sizeof(u32)) && -+ IS_ALIGNED((uintptr_t)dest, sizeof(u32))) -+ memcpy_toio(dest, src, len); -+ else -+ spear_smi_memcpy_toio_b(dest, src, len); - - writel(ctrlreg1, dev->io_base + SMI_CR1); - -diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c -index 5c2c30a7dffa..f64e3b6605c6 100644 ---- a/drivers/mtd/nand/raw/nand_base.c -+++ b/drivers/mtd/nand/raw/nand_base.c -@@ -292,12 +292,16 @@ int nand_bbm_get_next_page(struct nand_chip *chip, int page) - struct mtd_info *mtd = nand_to_mtd(chip); - int last_page = ((mtd->erasesize - mtd->writesize) >> - chip->page_shift) & chip->pagemask; -+ unsigned int bbm_flags = NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE -+ | NAND_BBM_LASTPAGE; - -+ if (page == 0 && !(chip->options & bbm_flags)) -+ return 0; - if (page == 0 && chip->options & NAND_BBM_FIRSTPAGE) - return 0; -- else if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE) -+ if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE) - return 1; -- else if (page <= last_page && chip->options & NAND_BBM_LASTPAGE) -+ if (page <= last_page && chip->options & NAND_BBM_LASTPAGE) - return last_page; - - return -EINVAL; -diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c -index 8ca9fad6e6ad..56654030ec7f 100644 ---- a/drivers/mtd/nand/raw/nand_micron.c -+++ b/drivers/mtd/nand/raw/nand_micron.c -@@ -446,8 +446,10 @@ static int micron_nand_init(struct nand_chip *chip) - if (ret) - goto err_free_manuf_data; - -+ chip->options |= NAND_BBM_FIRSTPAGE; -+ - if (mtd->writesize == 2048) -- chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; -+ chip->options |= NAND_BBM_SECONDPAGE; - - ondie = micron_supports_on_die_ecc(chip); - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 1d67eeeab79d..235d51ea4d39 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -4145,7 +4145,7 @@ static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28: - r8168dp_hw_jumbo_disable(tp); - break; -- case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_34: -+ case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33: - r8168e_hw_jumbo_disable(tp); - break; - default: -diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c -index b94759daeacc..da2d179430ca 100644 ---- a/drivers/net/wireless/ath/ar5523/ar5523.c -+++ b/drivers/net/wireless/ath/ar5523/ar5523.c -@@ -255,7 +255,8 @@ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata, - - if (flags & AR5523_CMD_FLAG_MAGIC) - hdr->magic = cpu_to_be32(1 << 24); -- memcpy(hdr + 1, idata, ilen); -+ if (ilen) -+ memcpy(hdr + 1, idata, ilen); - - cmd->odata = odata; - cmd->olen = olen; -diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c -index 153b84447e40..41389c1eb252 100644 ---- a/drivers/net/wireless/ath/wil6210/wmi.c -+++ b/drivers/net/wireless/ath/wil6210/wmi.c -@@ -2505,7 +2505,8 @@ int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie) - cmd->mgmt_frm_type = type; - /* BUG: FW API define ieLen as u8. Will fix FW */ - cmd->ie_len = cpu_to_le16(ie_len); -- memcpy(cmd->ie_info, ie, ie_len); -+ if (ie_len) -+ memcpy(cmd->ie_info, ie, ie_len); - rc = wmi_send(wil, WMI_SET_APPIE_CMDID, vif->mid, cmd, len); - kfree(cmd); - out: -@@ -2541,7 +2542,8 @@ int wmi_update_ft_ies(struct wil6210_vif *vif, u16 ie_len, const void *ie) - } - - cmd->ie_len = cpu_to_le16(ie_len); -- memcpy(cmd->ie_info, ie, ie_len); -+ if (ie_len) -+ memcpy(cmd->ie_info, ie, ie_len); - rc = wmi_send(wil, WMI_UPDATE_FT_IES_CMDID, vif->mid, cmd, len); - kfree(cmd); - -diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -index 6c463475e90b..3be60aef5465 100644 ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -1427,6 +1427,8 @@ static int brcmf_pcie_reset(struct device *dev) - struct brcmf_fw_request *fwreq; - int err; - -+ brcmf_pcie_intr_disable(devinfo); -+ - brcmf_pcie_bus_console_read(devinfo, true); - - brcmf_detach(dev); -diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c -index d80f71f82a6d..97cb3a8d505c 100644 ---- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c -+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c -@@ -468,6 +468,7 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, - dma_addr_t tb_phys; - int len, tb1_len, tb2_len; - void *tb1_addr; -+ struct sk_buff *frag; - - tb_phys = iwl_pcie_get_first_tb_dma(txq, idx); - -@@ -516,6 +517,19 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, - if (iwl_pcie_gen2_tx_add_frags(trans, skb, tfd, out_meta)) - goto out_err; - -+ skb_walk_frags(skb, frag) { -+ tb_phys = dma_map_single(trans->dev, frag->data, -+ skb_headlen(frag), DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(trans->dev, tb_phys))) -+ goto out_err; -+ iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, skb_headlen(frag)); -+ trace_iwlwifi_dev_tx_tb(trans->dev, skb, -+ frag->data, -+ skb_headlen(frag)); -+ if (iwl_pcie_gen2_tx_add_frags(trans, frag, tfd, out_meta)) -+ goto out_err; -+ } -+ - return tfd; - - out_err: -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c -index c7f29a9be50d..146fe144f5f5 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c -@@ -1176,6 +1176,7 @@ void rtl92de_enable_interrupt(struct ieee80211_hw *hw) - - rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); - rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); -+ rtlpci->irq_enabled = true; - } - - void rtl92de_disable_interrupt(struct ieee80211_hw *hw) -@@ -1185,7 +1186,7 @@ void rtl92de_disable_interrupt(struct ieee80211_hw *hw) - - rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); - rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); -- synchronize_irq(rtlpci->pdev->irq); -+ rtlpci->irq_enabled = false; - } - - static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) -@@ -1351,7 +1352,7 @@ void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw) - - bcn_interval = mac->beacon_interval; - atim_window = 2; -- /*rtl92de_disable_interrupt(hw); */ -+ rtl92de_disable_interrupt(hw); - rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); - rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); -@@ -1371,9 +1372,9 @@ void rtl92de_set_beacon_interval(struct ieee80211_hw *hw) - - RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - "beacon_interval:%d\n", bcn_interval); -- /* rtl92de_disable_interrupt(hw); */ -+ rtl92de_disable_interrupt(hw); - rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); -- /* rtl92de_enable_interrupt(hw); */ -+ rtl92de_enable_interrupt(hw); - } - - void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c -index 99e5cd9a5c86..1dbdddce0823 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c -@@ -216,6 +216,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = { - .led_control = rtl92de_led_control, - .set_desc = rtl92de_set_desc, - .get_desc = rtl92de_get_desc, -+ .is_tx_desc_closed = rtl92de_is_tx_desc_closed, - .tx_polling = rtl92de_tx_polling, - .enable_hw_sec = rtl92de_enable_hw_security_config, - .set_key = rtl92de_set_key, -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c -index 2494e1f118f8..92c9fb45f800 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c -@@ -804,13 +804,15 @@ u64 rtl92de_get_desc(struct ieee80211_hw *hw, - break; - } - } else { -- struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; - switch (desc_name) { - case HW_DESC_OWN: -- ret = GET_RX_DESC_OWN(pdesc); -+ ret = GET_RX_DESC_OWN(p_desc); - break; - case HW_DESC_RXPKT_LEN: -- ret = GET_RX_DESC_PKT_LEN(pdesc); -+ ret = GET_RX_DESC_PKT_LEN(p_desc); -+ break; -+ case HW_DESC_RXBUFF_ADDR: -+ ret = GET_RX_DESC_BUFF_ADDR(p_desc); - break; - default: - WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n", -@@ -821,6 +823,23 @@ u64 rtl92de_get_desc(struct ieee80211_hw *hw, - return ret; - } - -+bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw, -+ u8 hw_queue, u16 index) -+{ -+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); -+ struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; -+ u8 *entry = (u8 *)(&ring->desc[ring->idx]); -+ u8 own = (u8)rtl92de_get_desc(hw, entry, true, HW_DESC_OWN); -+ -+ /* a beacon packet will only use the first -+ * descriptor by defaut, and the own bit may not -+ * be cleared by the hardware -+ */ -+ if (own) -+ return false; -+ return true; -+} -+ - void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) - { - struct rtl_priv *rtlpriv = rtl_priv(hw); -diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h -index 36820070fd76..635989e15282 100644 ---- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h -+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h -@@ -715,6 +715,8 @@ void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, - u8 desc_name, u8 *val); - u64 rtl92de_get_desc(struct ieee80211_hw *hw, - u8 *p_desc, bool istx, u8 desc_name); -+bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw, -+ u8 hw_queue, u16 index); - void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); - void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, - bool b_firstseg, bool b_lastseg, -diff --git a/drivers/net/wireless/virt_wifi.c b/drivers/net/wireless/virt_wifi.c -index 7997cc6de334..01305ba2d3aa 100644 ---- a/drivers/net/wireless/virt_wifi.c -+++ b/drivers/net/wireless/virt_wifi.c -@@ -450,7 +450,6 @@ static void virt_wifi_net_device_destructor(struct net_device *dev) - */ - kfree(dev->ieee80211_ptr); - dev->ieee80211_ptr = NULL; -- free_netdev(dev); - } - - /* No lock interaction. */ -@@ -458,7 +457,7 @@ static void virt_wifi_setup(struct net_device *dev) - { - ether_setup(dev); - dev->netdev_ops = &virt_wifi_ops; -- dev->priv_destructor = virt_wifi_net_device_destructor; -+ dev->needs_free_netdev = true; - } - - /* Called in a RCU read critical section from netif_receive_skb */ -@@ -544,6 +543,7 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev, - goto unregister_netdev; - } - -+ dev->priv_destructor = virt_wifi_net_device_destructor; - priv->being_deleted = false; - priv->is_connected = false; - priv->is_up = false; -diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c -index fa7ba09dca77..af3212aec871 100644 ---- a/drivers/nvme/host/core.c -+++ b/drivers/nvme/host/core.c -@@ -1727,6 +1727,8 @@ static int nvme_report_ns_ids(struct nvme_ctrl *ctrl, unsigned int nsid, - if (ret) - dev_warn(ctrl->device, - "Identify Descriptors failed (%d)\n", ret); -+ if (ret > 0) -+ ret = 0; - } - return ret; - } -@@ -2404,16 +2406,6 @@ static const struct nvme_core_quirk_entry core_quirks[] = { - .vid = 0x14a4, - .fr = "22301111", - .quirks = NVME_QUIRK_SIMPLE_SUSPEND, -- }, -- { -- /* -- * This Kingston E8FK11.T firmware version has no interrupt -- * after resume with actions related to suspend to idle -- * https://bugzilla.kernel.org/show_bug.cgi?id=204887 -- */ -- .vid = 0x2646, -- .fr = "E8FK11.T", -- .quirks = NVME_QUIRK_SIMPLE_SUSPEND, - } - }; - -diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c -index e4c46637f32f..b3869951c0eb 100644 ---- a/drivers/pci/hotplug/acpiphp_glue.c -+++ b/drivers/pci/hotplug/acpiphp_glue.c -@@ -449,8 +449,15 @@ static void acpiphp_native_scan_bridge(struct pci_dev *bridge) - - /* Scan non-hotplug bridges that need to be reconfigured */ - for_each_pci_bridge(dev, bus) { -- if (!hotplug_is_native(dev)) -- max = pci_scan_bridge(bus, dev, max, 1); -+ if (hotplug_is_native(dev)) -+ continue; -+ -+ max = pci_scan_bridge(bus, dev, max, 1); -+ if (dev->subordinate) { -+ pcibios_resource_survey_bus(dev->subordinate); -+ pci_bus_size_bridges(dev->subordinate); -+ pci_bus_assign_resources(dev->subordinate); -+ } - } - } - -@@ -480,7 +487,6 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge) - if (PCI_SLOT(dev->devfn) == slot->device) - acpiphp_native_scan_bridge(dev); - } -- pci_assign_unassigned_bridge_resources(bus->self); - } else { - LIST_HEAD(add_list); - int max, pass; -diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c -index b7f6b1324395..6fd1390fd06e 100644 ---- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c -+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -320,9 +321,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, - if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch)) - return -EIO; - -- if (!strncmp(buf, "host", strlen("host"))) -+ if (sysfs_streq(buf, "host")) - new_mode = PHY_MODE_USB_HOST; -- else if (!strncmp(buf, "peripheral", strlen("peripheral"))) -+ else if (sysfs_streq(buf, "peripheral")) - new_mode = PHY_MODE_USB_DEVICE; - else - return -EINVAL; -diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c -index f2f5fcd9a237..83e585c5a613 100644 ---- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c -+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c -@@ -595,10 +595,10 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type) - regmap_read(info->regmap, in_reg, &in_val); - - /* Set initial polarity based on current input level. */ -- if (in_val & d->mask) -- val |= d->mask; /* falling */ -+ if (in_val & BIT(d->hwirq % GPIO_PER_REG)) -+ val |= BIT(d->hwirq % GPIO_PER_REG); /* falling */ - else -- val &= ~d->mask; /* rising */ -+ val &= ~(BIT(d->hwirq % GPIO_PER_REG)); /* rising */ - break; - } - default: -diff --git a/drivers/pinctrl/pinctrl-rza2.c b/drivers/pinctrl/pinctrl-rza2.c -index 3be1d833bf25..eda88cdf870d 100644 ---- a/drivers/pinctrl/pinctrl-rza2.c -+++ b/drivers/pinctrl/pinctrl-rza2.c -@@ -213,8 +213,8 @@ static const char * const rza2_gpio_names[] = { - "PC_0", "PC_1", "PC_2", "PC_3", "PC_4", "PC_5", "PC_6", "PC_7", - "PD_0", "PD_1", "PD_2", "PD_3", "PD_4", "PD_5", "PD_6", "PD_7", - "PE_0", "PE_1", "PE_2", "PE_3", "PE_4", "PE_5", "PE_6", "PE_7", -- "PF_0", "PF_1", "PF_2", "PF_3", "P0_4", "PF_5", "PF_6", "PF_7", -- "PG_0", "PG_1", "PG_2", "P0_3", "PG_4", "PG_5", "PG_6", "PG_7", -+ "PF_0", "PF_1", "PF_2", "PF_3", "PF_4", "PF_5", "PF_6", "PF_7", -+ "PG_0", "PG_1", "PG_2", "PG_3", "PG_4", "PG_5", "PG_6", "PG_7", - "PH_0", "PH_1", "PH_2", "PH_3", "PH_4", "PH_5", "PH_6", "PH_7", - /* port I does not exist */ - "PJ_0", "PJ_1", "PJ_2", "PJ_3", "PJ_4", "PJ_5", "PJ_6", "PJ_7", -diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c -index c93ef33b01d3..5c1378d2fab3 100644 ---- a/drivers/rtc/interface.c -+++ b/drivers/rtc/interface.c -@@ -125,7 +125,7 @@ EXPORT_SYMBOL_GPL(rtc_read_time); - - int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) - { -- int err; -+ int err, uie; - - err = rtc_valid_tm(tm); - if (err != 0) -@@ -137,6 +137,17 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) - - rtc_subtract_offset(rtc, tm); - -+#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL -+ uie = rtc->uie_rtctimer.enabled || rtc->uie_irq_active; -+#else -+ uie = rtc->uie_rtctimer.enabled; -+#endif -+ if (uie) { -+ err = rtc_update_irq_enable(rtc, 0); -+ if (err) -+ return err; -+ } -+ - err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return err; -@@ -153,6 +164,12 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) - /* A timer might have just expired */ - schedule_work(&rtc->irqwork); - -+ if (uie) { -+ err = rtc_update_irq_enable(rtc, 1); -+ if (err) -+ return err; -+ } -+ - trace_rtc_set_time(rtc_tm_to_time64(tm), err); - return err; - } -diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c -index dccdb41bed8c..1234294700c4 100644 ---- a/drivers/s390/scsi/zfcp_dbf.c -+++ b/drivers/s390/scsi/zfcp_dbf.c -@@ -95,11 +95,9 @@ void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req) - memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual, - FSF_STATUS_QUALIFIER_SIZE); - -- if (q_head->fsf_command != FSF_QTCB_FCP_CMND) { -- rec->pl_len = q_head->log_length; -- zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, -- rec->pl_len, "fsf_res", req->req_id); -- } -+ rec->pl_len = q_head->log_length; -+ zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, -+ rec->pl_len, "fsf_res", req->req_id); - - debug_event(dbf->hba, level, rec, sizeof(*rec)); - spin_unlock_irqrestore(&dbf->hba_lock, flags); -diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c -index 6822cd9ff8f1..ad8ef67a1db3 100644 ---- a/drivers/scsi/lpfc/lpfc_scsi.c -+++ b/drivers/scsi/lpfc/lpfc_scsi.c -@@ -526,7 +526,7 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, - &qp->lpfc_abts_io_buf_list, list) { - if (psb->cur_iocbq.sli4_xritag == xri) { - list_del_init(&psb->list); -- psb->exch_busy = 0; -+ psb->flags &= ~LPFC_SBUF_XBUSY; - psb->status = IOSTAT_SUCCESS; - if (psb->cur_iocbq.iocb_flag == LPFC_IO_NVME) { - qp->abts_nvme_io_bufs--; -@@ -566,7 +566,7 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, - if (iocbq->sli4_xritag != xri) - continue; - psb = container_of(iocbq, struct lpfc_io_buf, cur_iocbq); -- psb->exch_busy = 0; -+ psb->flags &= ~LPFC_SBUF_XBUSY; - spin_unlock_irqrestore(&phba->hbalock, iflag); - if (!list_empty(&pring->txq)) - lpfc_worker_wake_up(phba); -@@ -786,7 +786,7 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *psb) - psb->prot_seg_cnt = 0; - - qp = psb->hdwq; -- if (psb->exch_busy) { -+ if (psb->flags & LPFC_SBUF_XBUSY) { - spin_lock_irqsave(&qp->abts_io_buf_list_lock, iflag); - psb->pCmd = NULL; - list_add_tail(&psb->list, &qp->lpfc_abts_io_buf_list); -@@ -3835,7 +3835,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, - lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK); - lpfc_cmd->status = pIocbOut->iocb.ulpStatus; - /* pick up SLI4 exhange busy status from HBA */ -- lpfc_cmd->exch_busy = pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY; -+ if (pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY) -+ lpfc_cmd->flags |= LPFC_SBUF_XBUSY; -+ else -+ lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY; - - #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - if (lpfc_cmd->prot_data_type) { -diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c -index 614f78dddafe..5ed4219675eb 100644 ---- a/drivers/scsi/lpfc/lpfc_sli.c -+++ b/drivers/scsi/lpfc/lpfc_sli.c -@@ -11736,7 +11736,10 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, - !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) { - lpfc_cmd = container_of(cmdiocbq, struct lpfc_io_buf, - cur_iocbq); -- lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY; -+ if (rspiocbq && (rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY)) -+ lpfc_cmd->flags |= LPFC_SBUF_XBUSY; -+ else -+ lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY; - } - - pdone_q = cmdiocbq->context_un.wait_queue; -diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h -index 37fbcb46387e..7bcf922a8be2 100644 ---- a/drivers/scsi/lpfc/lpfc_sli.h -+++ b/drivers/scsi/lpfc/lpfc_sli.h -@@ -384,14 +384,13 @@ struct lpfc_io_buf { - - struct lpfc_nodelist *ndlp; - uint32_t timeout; -- uint16_t flags; /* TBD convert exch_busy to flags */ -+ uint16_t flags; - #define LPFC_SBUF_XBUSY 0x1 /* SLI4 hba reported XB on WCQE cmpl */ - #define LPFC_SBUF_BUMP_QDEPTH 0x2 /* bumped queue depth counter */ - /* External DIF device IO conversions */ - #define LPFC_SBUF_NORMAL_DIF 0x4 /* normal mode to insert/strip */ - #define LPFC_SBUF_PASS_DIF 0x8 /* insert/strip mode to passthru */ - #define LPFC_SBUF_NOT_POSTED 0x10 /* SGL failed post to FW. */ -- uint16_t exch_busy; /* SLI4 hba reported XB on complete WCQE */ - uint16_t status; /* From IOCB Word 7- ulpStatus */ - uint32_t result; /* From IOCB Word 4. */ - -diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h -index 6ffa9877c28b..d5386edddaf6 100644 ---- a/drivers/scsi/qla2xxx/qla_def.h -+++ b/drivers/scsi/qla2xxx/qla_def.h -@@ -591,19 +591,23 @@ typedef struct srb { - */ - uint8_t cmd_type; - uint8_t pad[3]; -- atomic_t ref_count; - struct kref cmd_kref; /* need to migrate ref_count over to this */ - void *priv; - wait_queue_head_t nvme_ls_waitq; - struct fc_port *fcport; - struct scsi_qla_host *vha; - unsigned int start_timer:1; -+ unsigned int abort:1; -+ unsigned int aborted:1; -+ unsigned int completed:1; -+ - uint32_t handle; - uint16_t flags; - uint16_t type; - const char *name; - int iocbs; - struct qla_qpair *qpair; -+ struct srb *cmd_sp; - struct list_head elem; - u32 gen1; /* scratch */ - u32 gen2; /* scratch */ -diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c -index 5298ed10059f..84bb4a048016 100644 ---- a/drivers/scsi/qla2xxx/qla_gs.c -+++ b/drivers/scsi/qla2xxx/qla_gs.c -@@ -3005,7 +3005,7 @@ static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res) - fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); - - if (res == QLA_FUNCTION_TIMEOUT) -- return; -+ goto done; - - if (res == (DID_ERROR << 16)) { - /* entry status error */ -diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c -index 1d041313ec52..d400b51929a6 100644 ---- a/drivers/scsi/qla2xxx/qla_init.c -+++ b/drivers/scsi/qla2xxx/qla_init.c -@@ -101,8 +101,22 @@ static void qla24xx_abort_iocb_timeout(void *data) - u32 handle; - unsigned long flags; - -+ if (sp->cmd_sp) -+ ql_dbg(ql_dbg_async, sp->vha, 0x507c, -+ "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n", -+ sp->cmd_sp->handle, sp->cmd_sp->type, -+ sp->handle, sp->type); -+ else -+ ql_dbg(ql_dbg_async, sp->vha, 0x507c, -+ "Abort timeout 2 - hdl=%x, type=%x\n", -+ sp->handle, sp->type); -+ - spin_lock_irqsave(qpair->qp_lock_ptr, flags); - for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) { -+ if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] == -+ sp->cmd_sp)) -+ qpair->req->outstanding_cmds[handle] = NULL; -+ - /* removing the abort */ - if (qpair->req->outstanding_cmds[handle] == sp) { - qpair->req->outstanding_cmds[handle] = NULL; -@@ -111,6 +125,9 @@ static void qla24xx_abort_iocb_timeout(void *data) - } - spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); - -+ if (sp->cmd_sp) -+ sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED); -+ - abt->u.abt.comp_status = CS_TIMEOUT; - sp->done(sp, QLA_OS_TIMER_EXPIRED); - } -@@ -142,6 +159,7 @@ static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) - sp->type = SRB_ABT_CMD; - sp->name = "abort"; - sp->qpair = cmd_sp->qpair; -+ sp->cmd_sp = cmd_sp; - if (wait) - sp->flags = SRB_WAKEUP_ON_COMP; - -@@ -1135,19 +1153,18 @@ static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) - "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n", - sp->name, res, fcport->port_name, mb[1], mb[2]); - -- if (res == QLA_FUNCTION_TIMEOUT) { -- dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, -- sp->u.iocb_cmd.u.mbx.in_dma); -- return; -- } -- - fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); -+ -+ if (res == QLA_FUNCTION_TIMEOUT) -+ goto done; -+ - memset(&ea, 0, sizeof(ea)); - ea.fcport = fcport; - ea.sp = sp; - - qla24xx_handle_gpdb_event(vha, &ea); - -+done: - dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, - sp->u.iocb_cmd.u.mbx.in_dma); - -@@ -9003,8 +9020,6 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair) - struct qla_hw_data *ha = qpair->hw; - - qpair->delete_in_progress = 1; -- while (atomic_read(&qpair->ref_count)) -- msleep(500); - - ret = qla25xx_delete_req_que(vha, qpair->req); - if (ret != QLA_SUCCESS) -diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c -index 009fd5a33fcd..9204e8467a4e 100644 ---- a/drivers/scsi/qla2xxx/qla_isr.c -+++ b/drivers/scsi/qla2xxx/qla_isr.c -@@ -2466,6 +2466,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) - return; - } - -+ if (sp->abort) -+ sp->aborted = 1; -+ else -+ sp->completed = 1; -+ - if (sp->cmd_type != TYPE_SRB) { - req->outstanding_cmds[handle] = NULL; - ql_dbg(ql_dbg_io, vha, 0x3015, -diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c -index 4a1f21c11758..4d90cf101f5f 100644 ---- a/drivers/scsi/qla2xxx/qla_mbx.c -+++ b/drivers/scsi/qla2xxx/qla_mbx.c -@@ -6287,17 +6287,13 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) - case QLA_SUCCESS: - ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n", - __func__, sp->name); -- sp->free(sp); - break; - default: - ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n", - __func__, sp->name, rval); -- sp->free(sp); - break; - } - -- return rval; -- - done_free_sp: - sp->free(sp); - done: -diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c -index 238240984bc1..eabc5127174e 100644 ---- a/drivers/scsi/qla2xxx/qla_mid.c -+++ b/drivers/scsi/qla2xxx/qla_mid.c -@@ -946,7 +946,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) - - sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL); - if (!sp) -- goto done; -+ return rval; - - sp->type = SRB_CTRL_VP; - sp->name = "ctrl_vp"; -@@ -962,7 +962,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) - ql_dbg(ql_dbg_async, vha, 0xffff, - "%s: %s Failed submission. %x.\n", - __func__, sp->name, rval); -- goto done_free_sp; -+ goto done; - } - - ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n", -@@ -980,16 +980,13 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) - case QLA_SUCCESS: - ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n", - __func__, sp->name); -- goto done_free_sp; -+ break; - default: - ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n", - __func__, sp->name, rval); -- goto done_free_sp; -+ break; - } - done: -- return rval; -- --done_free_sp: - sp->free(sp); - return rval; - } -diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c -index 6cc19e060afc..941aa53363f5 100644 ---- a/drivers/scsi/qla2xxx/qla_nvme.c -+++ b/drivers/scsi/qla2xxx/qla_nvme.c -@@ -224,8 +224,8 @@ static void qla_nvme_abort_work(struct work_struct *work) - - if (ha->flags.host_shutting_down) { - ql_log(ql_log_info, sp->fcport->vha, 0xffff, -- "%s Calling done on sp: %p, type: 0x%x, sp->ref_count: 0x%x\n", -- __func__, sp, sp->type, atomic_read(&sp->ref_count)); -+ "%s Calling done on sp: %p, type: 0x%x\n", -+ __func__, sp, sp->type); - sp->done(sp, 0); - goto out; - } -diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c -index 726ad4cbf4a6..06037e3c7854 100644 ---- a/drivers/scsi/qla2xxx/qla_os.c -+++ b/drivers/scsi/qla2xxx/qla_os.c -@@ -698,11 +698,6 @@ void qla2x00_sp_compl(srb_t *sp, int res) - struct scsi_cmnd *cmd = GET_CMD_SP(sp); - struct completion *comp = sp->comp; - -- if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) -- return; -- -- atomic_dec(&sp->ref_count); -- - sp->free(sp); - cmd->result = res; - CMD_SP(cmd) = NULL; -@@ -794,11 +789,6 @@ void qla2xxx_qpair_sp_compl(srb_t *sp, int res) - struct scsi_cmnd *cmd = GET_CMD_SP(sp); - struct completion *comp = sp->comp; - -- if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) -- return; -- -- atomic_dec(&sp->ref_count); -- - sp->free(sp); - cmd->result = res; - CMD_SP(cmd) = NULL; -@@ -903,7 +893,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) - - sp->u.scmd.cmd = cmd; - sp->type = SRB_SCSI_CMD; -- atomic_set(&sp->ref_count, 1); -+ - CMD_SP(cmd) = (void *)sp; - sp->free = qla2x00_sp_free_dma; - sp->done = qla2x00_sp_compl; -@@ -985,18 +975,16 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, - - sp->u.scmd.cmd = cmd; - sp->type = SRB_SCSI_CMD; -- atomic_set(&sp->ref_count, 1); - CMD_SP(cmd) = (void *)sp; - sp->free = qla2xxx_qpair_sp_free_dma; - sp->done = qla2xxx_qpair_sp_compl; -- sp->qpair = qpair; - - rval = ha->isp_ops->start_scsi_mq(sp); - if (rval != QLA_SUCCESS) { - ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078, - "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd); - if (rval == QLA_INTERFACE_ERROR) -- goto qc24_fail_command; -+ goto qc24_free_sp_fail_command; - goto qc24_host_busy_free_sp; - } - -@@ -1008,6 +996,11 @@ qc24_host_busy_free_sp: - qc24_target_busy: - return SCSI_MLQUEUE_TARGET_BUSY; - -+qc24_free_sp_fail_command: -+ sp->free(sp); -+ CMD_SP(cmd) = NULL; -+ qla2xxx_rel_qpair_sp(sp->qpair, sp); -+ - qc24_fail_command: - cmd->scsi_done(cmd); - -@@ -1184,16 +1177,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha) - return return_status; - } - --static int --sp_get(struct srb *sp) --{ -- if (!refcount_inc_not_zero((refcount_t *)&sp->ref_count)) -- /* kref get fail */ -- return ENXIO; -- else -- return 0; --} -- - #define ISP_REG_DISCONNECT 0xffffffffU - /************************************************************************** - * qla2x00_isp_reg_stat -@@ -1249,6 +1232,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) - uint64_t lun; - int rval; - struct qla_hw_data *ha = vha->hw; -+ uint32_t ratov_j; -+ struct qla_qpair *qpair; -+ unsigned long flags; - - if (qla2x00_isp_reg_stat(ha)) { - ql_log(ql_log_info, vha, 0x8042, -@@ -1261,13 +1247,26 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) - return ret; - - sp = scsi_cmd_priv(cmd); -+ qpair = sp->qpair; - -- if (sp->fcport && sp->fcport->deleted) -+ if ((sp->fcport && sp->fcport->deleted) || !qpair) - return SUCCESS; - -- /* Return if the command has already finished. */ -- if (sp_get(sp)) -+ spin_lock_irqsave(qpair->qp_lock_ptr, flags); -+ if (sp->completed) { -+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); - return SUCCESS; -+ } -+ -+ if (sp->abort || sp->aborted) { -+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); -+ return FAILED; -+ } -+ -+ sp->abort = 1; -+ sp->comp = ∁ -+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); -+ - - id = cmd->device->id; - lun = cmd->device->lun; -@@ -1276,47 +1275,37 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) - "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n", - vha->host_no, id, lun, sp, cmd, sp->handle); - -+ /* -+ * Abort will release the original Command/sp from FW. Let the -+ * original command call scsi_done. In return, he will wakeup -+ * this sleeping thread. -+ */ - rval = ha->isp_ops->abort_command(sp); -+ - ql_dbg(ql_dbg_taskm, vha, 0x8003, - "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval); - -+ /* Wait for the command completion. */ -+ ratov_j = ha->r_a_tov/10 * 4 * 1000; -+ ratov_j = msecs_to_jiffies(ratov_j); - switch (rval) { - case QLA_SUCCESS: -- /* -- * The command has been aborted. That means that the firmware -- * won't report a completion. -- */ -- sp->done(sp, DID_ABORT << 16); -- ret = SUCCESS; -- break; -- case QLA_FUNCTION_PARAMETER_ERROR: { -- /* Wait for the command completion. */ -- uint32_t ratov = ha->r_a_tov/10; -- uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000); -- -- WARN_ON_ONCE(sp->comp); -- sp->comp = ∁ - if (!wait_for_completion_timeout(&comp, ratov_j)) { - ql_dbg(ql_dbg_taskm, vha, 0xffff, - "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", -- __func__, ha->r_a_tov); -+ __func__, ha->r_a_tov/10); - ret = FAILED; - } else { - ret = SUCCESS; - } - break; -- } - default: -- /* -- * Either abort failed or abort and completion raced. Let -- * the SCSI core retry the abort in the former case. -- */ - ret = FAILED; - break; - } - - sp->comp = NULL; -- atomic_dec(&sp->ref_count); -+ - ql_log(ql_log_info, vha, 0x801c, - "Abort command issued nexus=%ld:%d:%llu -- %x.\n", - vha->host_no, id, lun, ret); -@@ -1708,32 +1697,53 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, - scsi_qla_host_t *vha = qp->vha; - struct qla_hw_data *ha = vha->hw; - int rval; -+ bool ret_cmd; -+ uint32_t ratov_j; - -- if (sp_get(sp)) -+ if (qla2x00_chip_is_down(vha)) { -+ sp->done(sp, res); - return; -+ } - - if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS || - (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy && - !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && - !qla2x00_isp_reg_stat(ha))) { -+ if (sp->comp) { -+ sp->done(sp, res); -+ return; -+ } -+ - sp->comp = ∁ -+ sp->abort = 1; - spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); -- rval = ha->isp_ops->abort_command(sp); - -+ rval = ha->isp_ops->abort_command(sp); -+ /* Wait for command completion. */ -+ ret_cmd = false; -+ ratov_j = ha->r_a_tov/10 * 4 * 1000; -+ ratov_j = msecs_to_jiffies(ratov_j); - switch (rval) { - case QLA_SUCCESS: -- sp->done(sp, res); -+ if (wait_for_completion_timeout(&comp, ratov_j)) { -+ ql_dbg(ql_dbg_taskm, vha, 0xffff, -+ "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", -+ __func__, ha->r_a_tov/10); -+ ret_cmd = true; -+ } -+ /* else FW return SP to driver */ - break; -- case QLA_FUNCTION_PARAMETER_ERROR: -- wait_for_completion(&comp); -+ default: -+ ret_cmd = true; - break; - } - - spin_lock_irqsave(qp->qp_lock_ptr, *flags); -- sp->comp = NULL; -+ if (ret_cmd && (!sp->completed || !sp->aborted)) -+ sp->done(sp, res); -+ } else { -+ sp->done(sp, res); - } -- -- atomic_dec(&sp->ref_count); - } - - static void -@@ -1755,7 +1765,6 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) - for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { - sp = req->outstanding_cmds[cnt]; - if (sp) { -- req->outstanding_cmds[cnt] = NULL; - switch (sp->cmd_type) { - case TYPE_SRB: - qla2x00_abort_srb(qp, sp, res, &flags); -@@ -1777,6 +1786,7 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) - default: - break; - } -+ req->outstanding_cmds[cnt] = NULL; - } - } - spin_unlock_irqrestore(qp->qp_lock_ptr, flags); -@@ -4666,7 +4676,8 @@ qla2x00_mem_free(struct qla_hw_data *ha) - ha->sfp_data = NULL; - - if (ha->flt) -- dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, -+ dma_free_coherent(&ha->pdev->dev, -+ sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, - ha->flt, ha->flt_dma); - ha->flt = NULL; - ha->flt_dma = 0; -diff --git a/drivers/staging/exfat/exfat.h b/drivers/staging/exfat/exfat.h -index 3abab33e932c..4973c9edc26e 100644 ---- a/drivers/staging/exfat/exfat.h -+++ b/drivers/staging/exfat/exfat.h -@@ -943,8 +943,8 @@ s32 create_dir(struct inode *inode, struct chain_t *p_dir, - s32 create_file(struct inode *inode, struct chain_t *p_dir, - struct uni_name_t *p_uniname, u8 mode, struct file_id_t *fid); - void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry); --s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry, -- struct uni_name_t *p_uniname, struct file_id_t *fid); -+s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry, -+ struct uni_name_t *p_uniname, struct file_id_t *fid); - s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry, - struct chain_t *p_newdir, struct uni_name_t *p_uniname, - struct file_id_t *fid); -diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c -index 79174e5c4145..f3774a1912d1 100644 ---- a/drivers/staging/exfat/exfat_core.c -+++ b/drivers/staging/exfat/exfat_core.c -@@ -3381,8 +3381,8 @@ void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry) - fs_func->delete_dir_entry(sb, p_dir, entry, 0, num_entries); - } - --s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry, -- struct uni_name_t *p_uniname, struct file_id_t *fid) -+s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry, -+ struct uni_name_t *p_uniname, struct file_id_t *fid) - { - s32 ret, newentry = -1, num_old_entries, num_new_entries; - sector_t sector_old, sector_new; -diff --git a/drivers/staging/exfat/exfat_super.c b/drivers/staging/exfat/exfat_super.c -index 3b2b0ceb7297..58c7d66060f7 100644 ---- a/drivers/staging/exfat/exfat_super.c -+++ b/drivers/staging/exfat/exfat_super.c -@@ -1308,8 +1308,8 @@ static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid, - fs_set_vol_flags(sb, VOL_DIRTY); - - if (olddir.dir == newdir.dir) -- ret = rename_file(new_parent_inode, &olddir, dentry, &uni_name, -- fid); -+ ret = exfat_rename_file(new_parent_inode, &olddir, dentry, -+ &uni_name, fid); - else - ret = move_file(new_parent_inode, &olddir, dentry, &newdir, - &uni_name, fid); -diff --git a/drivers/staging/isdn/gigaset/usb-gigaset.c b/drivers/staging/isdn/gigaset/usb-gigaset.c -index 1b9b43659bdf..a20c0bfa68f3 100644 ---- a/drivers/staging/isdn/gigaset/usb-gigaset.c -+++ b/drivers/staging/isdn/gigaset/usb-gigaset.c -@@ -571,8 +571,7 @@ static int gigaset_initcshw(struct cardstate *cs) - { - struct usb_cardstate *ucs; - -- cs->hw.usb = ucs = -- kmalloc(sizeof(struct usb_cardstate), GFP_KERNEL); -+ cs->hw.usb = ucs = kzalloc(sizeof(struct usb_cardstate), GFP_KERNEL); - if (!ucs) { - pr_err("out of memory\n"); - return -ENOMEM; -@@ -584,9 +583,6 @@ static int gigaset_initcshw(struct cardstate *cs) - ucs->bchars[3] = 0; - ucs->bchars[4] = 0x11; - ucs->bchars[5] = 0x13; -- ucs->bulk_out_buffer = NULL; -- ucs->bulk_out_urb = NULL; -- ucs->read_urb = NULL; - tasklet_init(&cs->write_tasklet, - gigaset_modem_fill, (unsigned long) cs); - -@@ -685,6 +681,11 @@ static int gigaset_probe(struct usb_interface *interface, - return -ENODEV; - } - -+ if (hostif->desc.bNumEndpoints < 2) { -+ dev_err(&interface->dev, "missing endpoints\n"); -+ return -ENODEV; -+ } -+ - dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); - - /* allocate memory for our device state and initialize it */ -@@ -704,6 +705,12 @@ static int gigaset_probe(struct usb_interface *interface, - - endpoint = &hostif->endpoint[0].desc; - -+ if (!usb_endpoint_is_bulk_out(endpoint)) { -+ dev_err(&interface->dev, "missing bulk-out endpoint\n"); -+ retval = -ENODEV; -+ goto error; -+ } -+ - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - ucs->bulk_out_size = buffer_size; - ucs->bulk_out_epnum = usb_endpoint_num(endpoint); -@@ -723,6 +730,12 @@ static int gigaset_probe(struct usb_interface *interface, - - endpoint = &hostif->endpoint[1].desc; - -+ if (!usb_endpoint_is_int_in(endpoint)) { -+ dev_err(&interface->dev, "missing int-in endpoint\n"); -+ retval = -ENODEV; -+ goto error; -+ } -+ - ucs->busy = 0; - - ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL); -diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c -index 4fac9dca798e..a7cac0719b8b 100644 ---- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c -+++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c -@@ -70,7 +70,7 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf) - phost_conf = pusbd->actconfig; - pconf_desc = &phost_conf->desc; - -- phost_iface = &usb_intf->altsetting[0]; -+ phost_iface = usb_intf->cur_altsetting; - piface_desc = &phost_iface->desc; - - pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces; -diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c -index ba1288297ee4..a87562f632a7 100644 ---- a/drivers/staging/rtl8712/usb_intf.c -+++ b/drivers/staging/rtl8712/usb_intf.c -@@ -247,7 +247,7 @@ static uint r8712_usb_dvobj_init(struct _adapter *padapter) - - pdvobjpriv->padapter = padapter; - padapter->eeprom_address_size = 6; -- phost_iface = &pintf->altsetting[0]; -+ phost_iface = pintf->cur_altsetting; - piface_desc = &phost_iface->desc; - pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; - if (pusbd->speed == USB_SPEED_HIGH) { -diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -index b1595b13dea8..af6bf0736b52 100644 ---- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -3299,7 +3299,7 @@ static int __init vchiq_driver_init(void) - return 0; - - region_unregister: -- platform_driver_unregister(&vchiq_driver); -+ unregister_chrdev_region(vchiq_devid, 1); - - class_destroy: - class_destroy(vchiq_class); -diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c -index 8b0ea8c70d73..635cf0466b59 100644 ---- a/drivers/usb/atm/ueagle-atm.c -+++ b/drivers/usb/atm/ueagle-atm.c -@@ -2124,10 +2124,11 @@ resubmit: - /* - * Start the modem : init the data and start kernel thread - */ --static int uea_boot(struct uea_softc *sc) -+static int uea_boot(struct uea_softc *sc, struct usb_interface *intf) - { -- int ret, size; - struct intr_pkt *intr; -+ int ret = -ENOMEM; -+ int size; - - uea_enters(INS_TO_USBDEV(sc)); - -@@ -2152,6 +2153,11 @@ static int uea_boot(struct uea_softc *sc) - if (UEA_CHIP_VERSION(sc) == ADI930) - load_XILINX_firmware(sc); - -+ if (intf->cur_altsetting->desc.bNumEndpoints < 1) { -+ ret = -ENODEV; -+ goto err0; -+ } -+ - intr = kmalloc(size, GFP_KERNEL); - if (!intr) - goto err0; -@@ -2163,8 +2169,7 @@ static int uea_boot(struct uea_softc *sc) - usb_fill_int_urb(sc->urb_int, sc->usb_dev, - usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), - intr, size, uea_intr, sc, -- sc->usb_dev->actconfig->interface[0]->altsetting[0]. -- endpoint[0].desc.bInterval); -+ intf->cur_altsetting->endpoint[0].desc.bInterval); - - ret = usb_submit_urb(sc->urb_int, GFP_KERNEL); - if (ret < 0) { -@@ -2179,6 +2184,7 @@ static int uea_boot(struct uea_softc *sc) - sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm"); - if (IS_ERR(sc->kthread)) { - uea_err(INS_TO_USBDEV(sc), "failed to create thread\n"); -+ ret = PTR_ERR(sc->kthread); - goto err2; - } - -@@ -2193,7 +2199,7 @@ err1: - kfree(intr); - err0: - uea_leaves(INS_TO_USBDEV(sc)); -- return -ENOMEM; -+ return ret; - } - - /* -@@ -2548,7 +2554,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, - } - } - -- ret = uea_boot(sc); -+ ret = uea_boot(sc, intf); - if (ret < 0) - goto error; - -diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c -index 87338f9eb5be..ed204cbb63ea 100644 ---- a/drivers/usb/common/usb-conn-gpio.c -+++ b/drivers/usb/common/usb-conn-gpio.c -@@ -156,7 +156,8 @@ static int usb_conn_probe(struct platform_device *pdev) - - info->vbus = devm_regulator_get(dev, "vbus"); - if (IS_ERR(info->vbus)) { -- dev_err(dev, "failed to get vbus\n"); -+ if (PTR_ERR(info->vbus) != -EPROBE_DEFER) -+ dev_err(dev, "failed to get vbus\n"); - return PTR_ERR(info->vbus); - } - -diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 236313f41f4a..dfe9ac8d2375 100644 ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -5814,7 +5814,7 @@ re_enumerate_no_bos: - - /** - * usb_reset_device - warn interface drivers and perform a USB port reset -- * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) -+ * @udev: device to reset (not in NOTATTACHED state) - * - * Warns all drivers bound to registered interfaces (using their pre_reset - * method), performs the port reset, and then lets the drivers know that -@@ -5842,8 +5842,7 @@ int usb_reset_device(struct usb_device *udev) - struct usb_host_config *config = udev->actconfig; - struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); - -- if (udev->state == USB_STATE_NOTATTACHED || -- udev->state == USB_STATE_SUSPENDED) { -+ if (udev->state == USB_STATE_NOTATTACHED) { - dev_dbg(&udev->dev, "device reset not allowed in state %d\n", - udev->state); - return -EINVAL; -diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c -index 0eab79f82ce4..da923ec17612 100644 ---- a/drivers/usb/core/urb.c -+++ b/drivers/usb/core/urb.c -@@ -45,6 +45,7 @@ void usb_init_urb(struct urb *urb) - if (urb) { - memset(urb, 0, sizeof(*urb)); - kref_init(&urb->kref); -+ INIT_LIST_HEAD(&urb->urb_list); - INIT_LIST_HEAD(&urb->anchor_list); - } - } -diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c -index 023f0357efd7..294276f7deb9 100644 ---- a/drivers/usb/dwc3/dwc3-pci.c -+++ b/drivers/usb/dwc3/dwc3-pci.c -@@ -29,7 +29,8 @@ - #define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa - #define PCI_DEVICE_ID_INTEL_APL 0x5aaa - #define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 --#define PCI_DEVICE_ID_INTEL_CMLH 0x02ee -+#define PCI_DEVICE_ID_INTEL_CMLLP 0x02ee -+#define PCI_DEVICE_ID_INTEL_CMLH 0x06ee - #define PCI_DEVICE_ID_INTEL_GLK 0x31aa - #define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee - #define PCI_DEVICE_ID_INTEL_CNPH 0xa36e -@@ -308,6 +309,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = { - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD), - (kernel_ulong_t) &dwc3_pci_mrfld_properties, }, - -+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLLP), -+ (kernel_ulong_t) &dwc3_pci_intel_properties, }, -+ - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLH), - (kernel_ulong_t) &dwc3_pci_intel_properties, }, - -diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c -index 3996b9c4ff8d..fd1b100d2927 100644 ---- a/drivers/usb/dwc3/ep0.c -+++ b/drivers/usb/dwc3/ep0.c -@@ -1117,6 +1117,9 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, - void dwc3_ep0_interrupt(struct dwc3 *dwc, - const struct dwc3_event_depevt *event) - { -+ struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; -+ u8 cmd; -+ - switch (event->endpoint_event) { - case DWC3_DEPEVT_XFERCOMPLETE: - dwc3_ep0_xfer_complete(dwc, event); -@@ -1129,7 +1132,12 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc, - case DWC3_DEPEVT_XFERINPROGRESS: - case DWC3_DEPEVT_RXTXFIFOEVT: - case DWC3_DEPEVT_STREAMEVT: -+ break; - case DWC3_DEPEVT_EPCMDCMPLT: -+ cmd = DEPEVT_PARAMETER_CMD(event->parameters); -+ -+ if (cmd == DWC3_DEPCMD_ENDTRANSFER) -+ dep->flags &= ~DWC3_EP_TRANSFER_STARTED; - break; - } - } -diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c -index a9aba716bf80..0c960a97ea02 100644 ---- a/drivers/usb/dwc3/gadget.c -+++ b/drivers/usb/dwc3/gadget.c -@@ -2491,7 +2491,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, - - req->request.actual = req->request.length - req->remaining; - -- if (!dwc3_gadget_ep_request_completed(req) && -+ if (!dwc3_gadget_ep_request_completed(req) || - req->num_pending_sgs) { - __dwc3_gadget_kick_transfer(dep); - goto out; -@@ -2719,6 +2719,9 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, - WARN_ON_ONCE(ret); - dep->resource_index = 0; - -+ if (!interrupt) -+ dep->flags &= ~DWC3_EP_TRANSFER_STARTED; -+ - if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A) - udelay(100); - } -diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c -index 33852c2b29d1..ab9ac48a751a 100644 ---- a/drivers/usb/gadget/configfs.c -+++ b/drivers/usb/gadget/configfs.c -@@ -1544,6 +1544,7 @@ static struct config_group *gadgets_make( - gi->composite.resume = NULL; - gi->composite.max_speed = USB_SPEED_SUPER; - -+ spin_lock_init(&gi->spinlock); - mutex_init(&gi->lock); - INIT_LIST_HEAD(&gi->string_list); - INIT_LIST_HEAD(&gi->available_func); -diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c -index 3d499d93c083..a8f1e5707c14 100644 ---- a/drivers/usb/gadget/udc/dummy_hcd.c -+++ b/drivers/usb/gadget/udc/dummy_hcd.c -@@ -2725,7 +2725,7 @@ static struct platform_driver dummy_hcd_driver = { - }; - - /*-------------------------------------------------------------------------*/ --#define MAX_NUM_UDC 2 -+#define MAX_NUM_UDC 32 - static struct platform_device *the_udc_pdev[MAX_NUM_UDC]; - static struct platform_device *the_hcd_pdev[MAX_NUM_UDC]; - -diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c -index 265dab2bbfac..3344fb8c4181 100644 ---- a/drivers/usb/gadget/udc/pch_udc.c -+++ b/drivers/usb/gadget/udc/pch_udc.c -@@ -1519,7 +1519,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev, - td = phys_to_virt(addr); - addr2 = (dma_addr_t)td->next; - dma_pool_free(dev->data_requests, td, addr); -- td->next = 0x00; - addr = addr2; - } - req->chain_len = 1; -diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c -index b7d23c438756..7a3a29e5e9d2 100644 ---- a/drivers/usb/host/xhci-hub.c -+++ b/drivers/usb/host/xhci-hub.c -@@ -806,7 +806,7 @@ static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, - - static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, - u32 *status, u32 portsc, -- unsigned long flags) -+ unsigned long *flags) - { - struct xhci_bus_state *bus_state; - struct xhci_hcd *xhci; -@@ -860,11 +860,11 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, - xhci_test_and_clear_bit(xhci, port, PORT_PLC); - xhci_set_link_state(xhci, port, XDEV_U0); - -- spin_unlock_irqrestore(&xhci->lock, flags); -+ spin_unlock_irqrestore(&xhci->lock, *flags); - time_left = wait_for_completion_timeout( - &bus_state->rexit_done[wIndex], - msecs_to_jiffies(XHCI_MAX_REXIT_TIMEOUT_MS)); -- spin_lock_irqsave(&xhci->lock, flags); -+ spin_lock_irqsave(&xhci->lock, *flags); - - if (time_left) { - slot_id = xhci_find_slot_id_by_port(hcd, xhci, -@@ -920,11 +920,13 @@ static void xhci_get_usb3_port_status(struct xhci_port *port, u32 *status, - { - struct xhci_bus_state *bus_state; - struct xhci_hcd *xhci; -+ struct usb_hcd *hcd; - u32 link_state; - u32 portnum; - - bus_state = &port->rhub->bus_state; - xhci = hcd_to_xhci(port->rhub->hcd); -+ hcd = port->rhub->hcd; - link_state = portsc & PORT_PLS_MASK; - portnum = port->hcd_portnum; - -@@ -952,12 +954,20 @@ static void xhci_get_usb3_port_status(struct xhci_port *port, u32 *status, - bus_state->suspended_ports &= ~(1 << portnum); - } - -+ /* remote wake resume signaling complete */ -+ if (bus_state->port_remote_wakeup & (1 << portnum) && -+ link_state != XDEV_RESUME && -+ link_state != XDEV_RECOVERY) { -+ bus_state->port_remote_wakeup &= ~(1 << portnum); -+ usb_hcd_end_port_resume(&hcd->self, portnum); -+ } -+ - xhci_hub_report_usb3_link_state(xhci, status, portsc); - xhci_del_comp_mod_timer(xhci, portsc, portnum); - } - - static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status, -- u32 portsc, unsigned long flags) -+ u32 portsc, unsigned long *flags) - { - struct xhci_bus_state *bus_state; - u32 link_state; -@@ -1007,7 +1017,7 @@ static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status, - static u32 xhci_get_port_status(struct usb_hcd *hcd, - struct xhci_bus_state *bus_state, - u16 wIndex, u32 raw_port_status, -- unsigned long flags) -+ unsigned long *flags) - __releases(&xhci->lock) - __acquires(&xhci->lock) - { -@@ -1130,7 +1140,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, - } - trace_xhci_get_port_status(wIndex, temp); - status = xhci_get_port_status(hcd, bus_state, wIndex, temp, -- flags); -+ &flags); - if (status == 0xffffffff) - goto error; - -diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c -index e16eda6e2b8b..3b1388fa2f36 100644 ---- a/drivers/usb/host/xhci-mem.c -+++ b/drivers/usb/host/xhci-mem.c -@@ -1909,13 +1909,17 @@ no_bw: - xhci->usb3_rhub.num_ports = 0; - xhci->num_active_eps = 0; - kfree(xhci->usb2_rhub.ports); -+ kfree(xhci->usb2_rhub.psi); - kfree(xhci->usb3_rhub.ports); -+ kfree(xhci->usb3_rhub.psi); - kfree(xhci->hw_ports); - kfree(xhci->rh_bw); - kfree(xhci->ext_caps); - - xhci->usb2_rhub.ports = NULL; -+ xhci->usb2_rhub.psi = NULL; - xhci->usb3_rhub.ports = NULL; -+ xhci->usb3_rhub.psi = NULL; - xhci->hw_ports = NULL; - xhci->rh_bw = NULL; - xhci->ext_caps = NULL; -diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c -index 1e0236e90687..1904ef56f61c 100644 ---- a/drivers/usb/host/xhci-pci.c -+++ b/drivers/usb/host/xhci-pci.c -@@ -519,6 +519,18 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) - } - #endif /* CONFIG_PM */ - -+static void xhci_pci_shutdown(struct usb_hcd *hcd) -+{ -+ struct xhci_hcd *xhci = hcd_to_xhci(hcd); -+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller); -+ -+ xhci_shutdown(hcd); -+ -+ /* Yet another workaround for spurious wakeups at shutdown with HSW */ -+ if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) -+ pci_set_power_state(pdev, PCI_D3hot); -+} -+ - /*-------------------------------------------------------------------------*/ - - /* PCI driver selection metadata; PCI hotplugging uses this */ -@@ -554,6 +566,7 @@ static int __init xhci_pci_init(void) - #ifdef CONFIG_PM - xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; - xhci_pci_hc_driver.pci_resume = xhci_pci_resume; -+ xhci_pci_hc_driver.shutdown = xhci_pci_shutdown; - #endif - return pci_register_driver(&xhci_pci_driver); - } -diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c -index e7aab31fd9a5..4a2fe56940bd 100644 ---- a/drivers/usb/host/xhci-ring.c -+++ b/drivers/usb/host/xhci-ring.c -@@ -1624,7 +1624,6 @@ static void handle_port_status(struct xhci_hcd *xhci, - slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1); - if (slot_id && xhci->devs[slot_id]) - xhci->devs[slot_id]->flags |= VDEV_PORT_ERROR; -- bus_state->port_remote_wakeup &= ~(1 << hcd_portnum); - } - - if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) { -@@ -1644,6 +1643,7 @@ static void handle_port_status(struct xhci_hcd *xhci, - */ - bus_state->port_remote_wakeup |= 1 << hcd_portnum; - xhci_test_and_clear_bit(xhci, port, PORT_PLC); -+ usb_hcd_start_port_resume(&hcd->self, hcd_portnum); - xhci_set_link_state(xhci, port, XDEV_U0); - /* Need to wait until the next link state change - * indicates the device is actually in U0. -@@ -1684,7 +1684,6 @@ static void handle_port_status(struct xhci_hcd *xhci, - if (slot_id && xhci->devs[slot_id]) - xhci_ring_device(xhci, slot_id); - if (bus_state->port_remote_wakeup & (1 << hcd_portnum)) { -- bus_state->port_remote_wakeup &= ~(1 << hcd_portnum); - xhci_test_and_clear_bit(xhci, port, PORT_PLC); - usb_wakeup_notification(hcd->self.root_hub, - hcd_portnum + 1); -@@ -2378,7 +2377,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, - case COMP_SUCCESS: - if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) - break; -- if (xhci->quirks & XHCI_TRUST_TX_LENGTH) -+ if (xhci->quirks & XHCI_TRUST_TX_LENGTH || -+ ep_ring->last_td_was_short) - trb_comp_code = COMP_SHORT_PACKET; - else - xhci_warn_ratelimited(xhci, -diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c -index 2ff7c911fbd0..dc172513a4aa 100644 ---- a/drivers/usb/host/xhci-tegra.c -+++ b/drivers/usb/host/xhci-tegra.c -@@ -755,7 +755,6 @@ static int tegra_xusb_runtime_suspend(struct device *dev) - { - struct tegra_xusb *tegra = dev_get_drvdata(dev); - -- tegra_xusb_phy_disable(tegra); - regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); - tegra_xusb_clk_disable(tegra); - -@@ -779,16 +778,8 @@ static int tegra_xusb_runtime_resume(struct device *dev) - goto disable_clk; - } - -- err = tegra_xusb_phy_enable(tegra); -- if (err < 0) { -- dev_err(dev, "failed to enable PHYs: %d\n", err); -- goto disable_regulator; -- } -- - return 0; - --disable_regulator: -- regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); - disable_clk: - tegra_xusb_clk_disable(tegra); - return err; -@@ -1181,6 +1172,12 @@ static int tegra_xusb_probe(struct platform_device *pdev) - */ - platform_set_drvdata(pdev, tegra); - -+ err = tegra_xusb_phy_enable(tegra); -+ if (err < 0) { -+ dev_err(&pdev->dev, "failed to enable PHYs: %d\n", err); -+ goto put_hcd; -+ } -+ - pm_runtime_enable(&pdev->dev); - if (pm_runtime_enabled(&pdev->dev)) - err = pm_runtime_get_sync(&pdev->dev); -@@ -1189,7 +1186,7 @@ static int tegra_xusb_probe(struct platform_device *pdev) - - if (err < 0) { - dev_err(&pdev->dev, "failed to enable device: %d\n", err); -- goto disable_rpm; -+ goto disable_phy; - } - - tegra_xusb_config(tegra, regs); -@@ -1275,9 +1272,11 @@ remove_usb2: - put_rpm: - if (!pm_runtime_status_suspended(&pdev->dev)) - tegra_xusb_runtime_suspend(&pdev->dev); --disable_rpm: -- pm_runtime_disable(&pdev->dev); -+put_hcd: - usb_put_hcd(tegra->hcd); -+disable_phy: -+ tegra_xusb_phy_disable(tegra); -+ pm_runtime_disable(&pdev->dev); - put_powerdomains: - if (!of_property_read_bool(pdev->dev.of_node, "power-domains")) { - tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC); -@@ -1314,6 +1313,8 @@ static int tegra_xusb_remove(struct platform_device *pdev) - tegra_xusb_powerdomain_remove(&pdev->dev, tegra); - } - -+ tegra_xusb_phy_disable(tegra); -+ - tegra_xusb_padctl_put(tegra->padctl); - - return 0; -diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c -index 6c17e3fe181a..9b3b1b16eafb 100644 ---- a/drivers/usb/host/xhci.c -+++ b/drivers/usb/host/xhci.c -@@ -770,7 +770,7 @@ static void xhci_stop(struct usb_hcd *hcd) - * - * This will only ever be called with the main usb_hcd (the USB3 roothub). - */ --static void xhci_shutdown(struct usb_hcd *hcd) -+void xhci_shutdown(struct usb_hcd *hcd) - { - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - -@@ -789,11 +789,8 @@ static void xhci_shutdown(struct usb_hcd *hcd) - xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "xhci_shutdown completed - status = %x", - readl(&xhci->op_regs->status)); -- -- /* Yet another workaround for spurious wakeups at shutdown with HSW */ -- if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) -- pci_set_power_state(to_pci_dev(hcd->self.sysdev), PCI_D3hot); - } -+EXPORT_SYMBOL_GPL(xhci_shutdown); - - #ifdef CONFIG_PM - static void xhci_save_registers(struct xhci_hcd *xhci) -@@ -973,7 +970,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci) - int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) - { - int rc = 0; -- unsigned int delay = XHCI_MAX_HALT_USEC; -+ unsigned int delay = XHCI_MAX_HALT_USEC * 2; - struct usb_hcd *hcd = xhci_to_hcd(xhci); - u32 command; - u32 res; -diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h -index f9f88626a57a..973d665052a2 100644 ---- a/drivers/usb/host/xhci.h -+++ b/drivers/usb/host/xhci.h -@@ -2050,6 +2050,7 @@ int xhci_start(struct xhci_hcd *xhci); - int xhci_reset(struct xhci_hcd *xhci); - int xhci_run(struct usb_hcd *hcd); - int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); -+void xhci_shutdown(struct usb_hcd *hcd); - void xhci_init_driver(struct hc_driver *drv, - const struct xhci_driver_overrides *over); - int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); -diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c -index 6f5edb9fc61e..d8d157c4c271 100644 ---- a/drivers/usb/misc/adutux.c -+++ b/drivers/usb/misc/adutux.c -@@ -669,7 +669,7 @@ static int adu_probe(struct usb_interface *interface, - init_waitqueue_head(&dev->read_wait); - init_waitqueue_head(&dev->write_wait); - -- res = usb_find_common_endpoints_reverse(&interface->altsetting[0], -+ res = usb_find_common_endpoints_reverse(interface->cur_altsetting, - NULL, NULL, - &dev->interrupt_in_endpoint, - &dev->interrupt_out_endpoint); -diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c -index 20b0f91a5d9b..bb24527f3c70 100644 ---- a/drivers/usb/misc/idmouse.c -+++ b/drivers/usb/misc/idmouse.c -@@ -337,7 +337,7 @@ static int idmouse_probe(struct usb_interface *interface, - int result; - - /* check if we have gotten the data or the hid interface */ -- iface_desc = &interface->altsetting[0]; -+ iface_desc = interface->cur_altsetting; - if (iface_desc->desc.bInterfaceClass != 0x0A) - return -ENODEV; - -diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c -index ac2b4fcc265f..f48a23adbc35 100644 ---- a/drivers/usb/mon/mon_bin.c -+++ b/drivers/usb/mon/mon_bin.c -@@ -1039,12 +1039,18 @@ static long mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg - - mutex_lock(&rp->fetch_lock); - spin_lock_irqsave(&rp->b_lock, flags); -- mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE); -- kfree(rp->b_vec); -- rp->b_vec = vec; -- rp->b_size = size; -- rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0; -- rp->cnt_lost = 0; -+ if (rp->mmap_active) { -+ mon_free_buff(vec, size/CHUNK_SIZE); -+ kfree(vec); -+ ret = -EBUSY; -+ } else { -+ mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE); -+ kfree(rp->b_vec); -+ rp->b_vec = vec; -+ rp->b_size = size; -+ rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0; -+ rp->cnt_lost = 0; -+ } - spin_unlock_irqrestore(&rp->b_lock, flags); - mutex_unlock(&rp->fetch_lock); - } -@@ -1216,13 +1222,21 @@ mon_bin_poll(struct file *file, struct poll_table_struct *wait) - static void mon_bin_vma_open(struct vm_area_struct *vma) - { - struct mon_reader_bin *rp = vma->vm_private_data; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&rp->b_lock, flags); - rp->mmap_active++; -+ spin_unlock_irqrestore(&rp->b_lock, flags); - } - - static void mon_bin_vma_close(struct vm_area_struct *vma) - { -+ unsigned long flags; -+ - struct mon_reader_bin *rp = vma->vm_private_data; -+ spin_lock_irqsave(&rp->b_lock, flags); - rp->mmap_active--; -+ spin_unlock_irqrestore(&rp->b_lock, flags); - } - - /* -@@ -1234,16 +1248,12 @@ static vm_fault_t mon_bin_vma_fault(struct vm_fault *vmf) - unsigned long offset, chunk_idx; - struct page *pageptr; - -- mutex_lock(&rp->fetch_lock); - offset = vmf->pgoff << PAGE_SHIFT; -- if (offset >= rp->b_size) { -- mutex_unlock(&rp->fetch_lock); -+ if (offset >= rp->b_size) - return VM_FAULT_SIGBUS; -- } - chunk_idx = offset / CHUNK_SIZE; - pageptr = rp->b_vec[chunk_idx].pg; - get_page(pageptr); -- mutex_unlock(&rp->fetch_lock); - vmf->page = pageptr; - return 0; - } -diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c -index 94b4e7db2b94..97e3d75b19a3 100644 ---- a/drivers/usb/roles/class.c -+++ b/drivers/usb/roles/class.c -@@ -169,8 +169,8 @@ EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); - void usb_role_switch_put(struct usb_role_switch *sw) - { - if (!IS_ERR_OR_NULL(sw)) { -- put_device(&sw->dev); - module_put(sw->dev.parent->driver->owner); -+ put_device(&sw->dev); - } - } - EXPORT_SYMBOL_GPL(usb_role_switch_put); -diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c -index 48a439298a68..9690a5f4b9d6 100644 ---- a/drivers/usb/serial/io_edgeport.c -+++ b/drivers/usb/serial/io_edgeport.c -@@ -2901,16 +2901,18 @@ static int edge_startup(struct usb_serial *serial) - response = 0; - - if (edge_serial->is_epic) { -+ struct usb_host_interface *alt; -+ -+ alt = serial->interface->cur_altsetting; -+ - /* EPIC thing, set up our interrupt polling now and our read - * urb, so that the device knows it really is connected. */ - interrupt_in_found = bulk_in_found = bulk_out_found = false; -- for (i = 0; i < serial->interface->altsetting[0] -- .desc.bNumEndpoints; ++i) { -+ for (i = 0; i < alt->desc.bNumEndpoints; ++i) { - struct usb_endpoint_descriptor *endpoint; - int buffer_size; - -- endpoint = &serial->interface->altsetting[0]. -- endpoint[i].desc; -+ endpoint = &alt->endpoint[i].desc; - buffer_size = usb_endpoint_maxp(endpoint); - if (!interrupt_in_found && - (usb_endpoint_is_int_in(endpoint))) { -diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c -index 34538253f12c..475b9c692827 100644 ---- a/drivers/usb/storage/uas.c -+++ b/drivers/usb/storage/uas.c -@@ -825,6 +825,10 @@ static int uas_slave_configure(struct scsi_device *sdev) - sdev->wce_default_on = 1; - } - -+ /* Some disks cannot handle READ_CAPACITY_16 */ -+ if (devinfo->flags & US_FL_NO_READ_CAPACITY_16) -+ sdev->no_read_capacity_16 = 1; -+ - /* - * Some disks return the total number of blocks in response - * to READ CAPACITY rather than the highest block number. -@@ -833,6 +837,12 @@ static int uas_slave_configure(struct scsi_device *sdev) - if (devinfo->flags & US_FL_FIX_CAPACITY) - sdev->fix_capacity = 1; - -+ /* -+ * in some cases we have to guess -+ */ -+ if (devinfo->flags & US_FL_CAPACITY_HEURISTICS) -+ sdev->guess_capacity = 1; -+ - /* - * Some devices don't like MODE SENSE with page=0x3f, - * which is the command used for checking if a device -diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c -index 94a3eda62add..a400b65cf17b 100644 ---- a/drivers/usb/typec/class.c -+++ b/drivers/usb/typec/class.c -@@ -1592,14 +1592,16 @@ struct typec_port *typec_register_port(struct device *parent, - - port->sw = typec_switch_get(&port->dev); - if (IS_ERR(port->sw)) { -+ ret = PTR_ERR(port->sw); - put_device(&port->dev); -- return ERR_CAST(port->sw); -+ return ERR_PTR(ret); - } - - port->mux = typec_mux_get(&port->dev, NULL); - if (IS_ERR(port->mux)) { -+ ret = PTR_ERR(port->mux); - put_device(&port->dev); -- return ERR_CAST(port->mux); -+ return ERR_PTR(ret); - } - - ret = device_add(&port->dev); -diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c -index b939bc28d886..9c82e2a0a411 100644 ---- a/drivers/video/hdmi.c -+++ b/drivers/video/hdmi.c -@@ -1576,12 +1576,12 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, - if (ptr[0] & 0x10) - frame->active_aspect = ptr[1] & 0xf; - if (ptr[0] & 0x8) { -- frame->top_bar = (ptr[5] << 8) + ptr[6]; -- frame->bottom_bar = (ptr[7] << 8) + ptr[8]; -+ frame->top_bar = (ptr[6] << 8) | ptr[5]; -+ frame->bottom_bar = (ptr[8] << 8) | ptr[7]; - } - if (ptr[0] & 0x4) { -- frame->left_bar = (ptr[9] << 8) + ptr[10]; -- frame->right_bar = (ptr[11] << 8) + ptr[12]; -+ frame->left_bar = (ptr[10] << 8) | ptr[9]; -+ frame->right_bar = (ptr[12] << 8) | ptr[11]; - } - frame->scan_mode = ptr[0] & 0x3; - -diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c -index e05679c478e2..9f4117766bb1 100644 ---- a/drivers/virtio/virtio_balloon.c -+++ b/drivers/virtio/virtio_balloon.c -@@ -721,6 +721,17 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, - - get_page(newpage); /* balloon reference */ - -+ /* -+ * When we migrate a page to a different zone and adjusted the -+ * managed page count when inflating, we have to fixup the count of -+ * both involved zones. -+ */ -+ if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM) && -+ page_zone(page) != page_zone(newpage)) { -+ adjust_managed_page_count(page, 1); -+ adjust_managed_page_count(newpage, -1); -+ } -+ - /* balloon's page migration 1st step -- inflate "newpage" */ - spin_lock_irqsave(&vb_dev_info->pages_lock, flags); - balloon_page_insert(vb_dev_info, newpage); -diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c -index 670700cb1110..0d2da2366869 100644 ---- a/fs/btrfs/block-group.c -+++ b/fs/btrfs/block-group.c -@@ -2662,7 +2662,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans, - * is because we need the unpinning stage to actually add the - * space back to the block group, otherwise we will leak space. - */ -- if (!alloc && cache->cached == BTRFS_CACHE_NO) -+ if (!alloc && !btrfs_block_group_cache_done(cache)) - btrfs_cache_block_group(cache, 1); - - byte_in_group = bytenr - cache->key.objectid; -diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c -index 1f7f39b10bd0..57a9ad3e8c29 100644 ---- a/fs/btrfs/delayed-inode.c -+++ b/fs/btrfs/delayed-inode.c -@@ -1949,12 +1949,19 @@ void btrfs_kill_all_delayed_nodes(struct btrfs_root *root) - } - - inode_id = delayed_nodes[n - 1]->inode_id + 1; -- -- for (i = 0; i < n; i++) -- refcount_inc(&delayed_nodes[i]->refs); -+ for (i = 0; i < n; i++) { -+ /* -+ * Don't increase refs in case the node is dead and -+ * about to be removed from the tree in the loop below -+ */ -+ if (!refcount_inc_not_zero(&delayed_nodes[i]->refs)) -+ delayed_nodes[i] = NULL; -+ } - spin_unlock(&root->inode_lock); - - for (i = 0; i < n; i++) { -+ if (!delayed_nodes[i]) -+ continue; - __btrfs_kill_delayed_node(delayed_nodes[i]); - btrfs_release_delayed_node(delayed_nodes[i]); - } -diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c -index cceaf05aada2..4905f48587df 100644 ---- a/fs/btrfs/extent_io.c -+++ b/fs/btrfs/extent_io.c -@@ -4121,7 +4121,7 @@ retry: - for (i = 0; i < nr_pages; i++) { - struct page *page = pvec.pages[i]; - -- done_index = page->index; -+ done_index = page->index + 1; - /* - * At this point we hold neither the i_pages lock nor - * the page lock: the page may be truncated or -@@ -4156,16 +4156,6 @@ retry: - - ret = __extent_writepage(page, wbc, epd); - if (ret < 0) { -- /* -- * done_index is set past this page, -- * so media errors will not choke -- * background writeout for the entire -- * file. This has consequences for -- * range_cyclic semantics (ie. it may -- * not be suitable for data integrity -- * writeout). -- */ -- done_index = page->index + 1; - done = 1; - break; - } -diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c -index 435a502a3226..c332968f9056 100644 ---- a/fs/btrfs/file.c -+++ b/fs/btrfs/file.c -@@ -1636,6 +1636,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, - break; - } - -+ only_release_metadata = false; - sector_offset = pos & (fs_info->sectorsize - 1); - reserve_bytes = round_up(write_bytes + sector_offset, - fs_info->sectorsize); -@@ -1791,7 +1792,6 @@ again: - set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, - lockend, EXTENT_NORESERVE, NULL, - NULL, GFP_NOFS); -- only_release_metadata = false; - } - - btrfs_drop_pages(pages, num_pages); -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index d54dcd0ab230..d86ada9c3c54 100644 ---- a/fs/btrfs/free-space-cache.c -+++ b/fs/btrfs/free-space-cache.c -@@ -385,6 +385,12 @@ static int io_ctl_prepare_pages(struct btrfs_io_ctl *io_ctl, struct inode *inode - if (uptodate && !PageUptodate(page)) { - btrfs_readpage(NULL, page); - lock_page(page); -+ if (page->mapping != inode->i_mapping) { -+ btrfs_err(BTRFS_I(inode)->root->fs_info, -+ "free space cache page truncated"); -+ io_ctl_drop_pages(io_ctl); -+ return -EIO; -+ } - if (!PageUptodate(page)) { - btrfs_err(BTRFS_I(inode)->root->fs_info, - "error reading free space cache"); -diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 015910079e73..10a01dd0c4e6 100644 ---- a/fs/btrfs/inode.c -+++ b/fs/btrfs/inode.c -@@ -2214,12 +2214,16 @@ again: - mapping_set_error(page->mapping, ret); - end_extent_writepage(page, ret, page_start, page_end); - ClearPageChecked(page); -- goto out; -+ goto out_reserved; - } - - ClearPageChecked(page); - set_page_dirty(page); -+out_reserved: - btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE); -+ if (ret) -+ btrfs_delalloc_release_space(inode, data_reserved, page_start, -+ PAGE_SIZE, true); - out: - unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end, - &cached_state); -@@ -9550,6 +9554,9 @@ static int btrfs_rename_exchange(struct inode *old_dir, - goto out_notrans; - } - -+ if (dest != root) -+ btrfs_record_root_in_trans(trans, dest); -+ - /* - * We need to find a free sequence number both in the source and - * in the destination directory for the exchange. -diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c -index 123ac54af071..518ec1265a0c 100644 ---- a/fs/btrfs/send.c -+++ b/fs/btrfs/send.c -@@ -24,6 +24,14 @@ - #include "transaction.h" - #include "compression.h" - -+/* -+ * Maximum number of references an extent can have in order for us to attempt to -+ * issue clone operations instead of write operations. This currently exists to -+ * avoid hitting limitations of the backreference walking code (taking a lot of -+ * time and using too much memory for extents with large number of references). -+ */ -+#define SEND_MAX_EXTENT_REFS 64 -+ - /* - * A fs_path is a helper to dynamically build path names with unknown size. - * It reallocates the internal buffer on demand. -@@ -1302,6 +1310,7 @@ static int find_extent_clone(struct send_ctx *sctx, - struct clone_root *cur_clone_root; - struct btrfs_key found_key; - struct btrfs_path *tmp_path; -+ struct btrfs_extent_item *ei; - int compressed; - u32 i; - -@@ -1349,7 +1358,6 @@ static int find_extent_clone(struct send_ctx *sctx, - ret = extent_from_logical(fs_info, disk_byte, tmp_path, - &found_key, &flags); - up_read(&fs_info->commit_root_sem); -- btrfs_release_path(tmp_path); - - if (ret < 0) - goto out; -@@ -1358,6 +1366,21 @@ static int find_extent_clone(struct send_ctx *sctx, - goto out; - } - -+ ei = btrfs_item_ptr(tmp_path->nodes[0], tmp_path->slots[0], -+ struct btrfs_extent_item); -+ /* -+ * Backreference walking (iterate_extent_inodes() below) is currently -+ * too expensive when an extent has a large number of references, both -+ * in time spent and used memory. So for now just fallback to write -+ * operations instead of clone operations when an extent has more than -+ * a certain amount of references. -+ */ -+ if (btrfs_extent_refs(tmp_path->nodes[0], ei) > SEND_MAX_EXTENT_REFS) { -+ ret = -ENOENT; -+ goto out; -+ } -+ btrfs_release_path(tmp_path); -+ - /* - * Setup the clone roots. - */ -diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h -index a7da1f3e3627..5acf5c507ec2 100644 ---- a/fs/btrfs/volumes.h -+++ b/fs/btrfs/volumes.h -@@ -330,7 +330,6 @@ struct btrfs_bio { - u64 map_type; /* get from map_lookup->type */ - bio_end_io_t *end_io; - struct bio *orig_bio; -- unsigned long flags; - void *private; - atomic_t error; - int max_errors; -diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c -index d17a789fd856..2e4764fd1872 100644 ---- a/fs/ceph/dir.c -+++ b/fs/ceph/dir.c -@@ -1809,6 +1809,7 @@ const struct file_operations ceph_dir_fops = { - .open = ceph_open, - .release = ceph_release, - .unlocked_ioctl = ceph_ioctl, -+ .compat_ioctl = compat_ptr_ioctl, - .fsync = ceph_fsync, - .lock = ceph_lock, - .flock = ceph_flock, -diff --git a/fs/ceph/file.c b/fs/ceph/file.c -index 8de633964dc3..11929d2bb594 100644 ---- a/fs/ceph/file.c -+++ b/fs/ceph/file.c -@@ -2188,7 +2188,7 @@ const struct file_operations ceph_file_fops = { - .splice_read = generic_file_splice_read, - .splice_write = iter_file_splice_write, - .unlocked_ioctl = ceph_ioctl, -- .compat_ioctl = ceph_ioctl, -+ .compat_ioctl = compat_ptr_ioctl, - .fallocate = ceph_fallocate, - .copy_file_range = ceph_copy_file_range, - }; -diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c -index a13a78725c57..b766c3ee5fa8 100644 ---- a/fs/erofs/xattr.c -+++ b/fs/erofs/xattr.c -@@ -649,6 +649,8 @@ ssize_t erofs_listxattr(struct dentry *dentry, - struct listxattr_iter it; - - ret = init_inode_xattrs(d_inode(dentry)); -+ if (ret == -ENOATTR) -+ return 0; - if (ret) - return ret; - -diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c -index 7004ce581a32..a16c53655e77 100644 ---- a/fs/ext2/inode.c -+++ b/fs/ext2/inode.c -@@ -701,10 +701,13 @@ static int ext2_get_blocks(struct inode *inode, - if (!partial) { - count++; - mutex_unlock(&ei->truncate_mutex); -- if (err) -- goto cleanup; - goto got_it; - } -+ -+ if (err) { -+ mutex_unlock(&ei->truncate_mutex); -+ goto cleanup; -+ } - } - - /* -diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c -index 764ff4c56233..564e2ceb8417 100644 ---- a/fs/ext4/ialloc.c -+++ b/fs/ext4/ialloc.c -@@ -265,13 +265,8 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) - ext4_debug("freeing inode %lu\n", ino); - trace_ext4_free_inode(inode); - -- /* -- * Note: we must free any quota before locking the superblock, -- * as writing the quota to disk may need the lock as well. -- */ - dquot_initialize(inode); - dquot_free_inode(inode); -- dquot_drop(inode); - - is_directory = S_ISDIR(inode->i_mode); - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index d691d1783ed6..91da21890360 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -196,7 +196,12 @@ void ext4_evict_inode(struct inode *inode) - { - handle_t *handle; - int err; -- int extra_credits = 3; -+ /* -+ * Credits for final inode cleanup and freeing: -+ * sb + inode (ext4_orphan_del()), block bitmap, group descriptor -+ * (xattr block freeing), bitmap, group descriptor (inode freeing) -+ */ -+ int extra_credits = 6; - struct ext4_xattr_inode_array *ea_inode_array = NULL; - - trace_ext4_evict_inode(inode); -@@ -252,8 +257,12 @@ void ext4_evict_inode(struct inode *inode) - if (!IS_NOQUOTA(inode)) - extra_credits += EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb); - -+ /* -+ * Block bitmap, group descriptor, and inode are accounted in both -+ * ext4_blocks_for_truncate() and extra_credits. So subtract 3. -+ */ - handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, -- ext4_blocks_for_truncate(inode)+extra_credits); -+ ext4_blocks_for_truncate(inode) + extra_credits - 3); - if (IS_ERR(handle)) { - ext4_std_error(inode->i_sb, PTR_ERR(handle)); - /* -@@ -5450,11 +5459,15 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode) - - offset = inode->i_size & (PAGE_SIZE - 1); - /* -- * All buffers in the last page remain valid? Then there's nothing to -- * do. We do the check mainly to optimize the common PAGE_SIZE == -- * blocksize case -+ * If the page is fully truncated, we don't need to wait for any commit -+ * (and we even should not as __ext4_journalled_invalidatepage() may -+ * strip all buffers from the page but keep the page dirty which can then -+ * confuse e.g. concurrent ext4_writepage() seeing dirty page without -+ * buffers). Also we don't need to wait for any commit if all buffers in -+ * the page remain valid. This is most beneficial for the common case of -+ * blocksize == PAGESIZE. - */ -- if (offset > PAGE_SIZE - i_blocksize(inode)) -+ if (!offset || offset > (PAGE_SIZE - i_blocksize(inode))) - return; - while (1) { - page = find_lock_page(inode->i_mapping, -diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c -index a427d2031a8d..923476e3aefb 100644 ---- a/fs/ext4/namei.c -+++ b/fs/ext4/namei.c -@@ -3182,18 +3182,17 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) - if (IS_DIRSYNC(dir)) - ext4_handle_sync(handle); - -- if (inode->i_nlink == 0) { -- ext4_warning_inode(inode, "Deleting file '%.*s' with no links", -- dentry->d_name.len, dentry->d_name.name); -- set_nlink(inode, 1); -- } - retval = ext4_delete_entry(handle, dir, de, bh); - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = current_time(dir); - ext4_update_dx_flag(dir); - ext4_mark_inode_dirty(handle, dir); -- drop_nlink(inode); -+ if (inode->i_nlink == 0) -+ ext4_warning_inode(inode, "Deleting file '%.*s' with no links", -+ dentry->d_name.len, dentry->d_name.name); -+ else -+ drop_nlink(inode); - if (!inode->i_nlink) - ext4_orphan_add(handle, inode); - inode->i_ctime = current_time(inode); -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 73578359d451..98d37b8d0050 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -1172,9 +1172,9 @@ void ext4_clear_inode(struct inode *inode) - { - invalidate_inode_buffers(inode); - clear_inode(inode); -- dquot_drop(inode); - ext4_discard_preallocations(inode); - ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS); -+ dquot_drop(inode); - if (EXT4_I(inode)->jinode) { - jbd2_journal_release_jbd_inode(EXT4_JOURNAL(inode), - EXT4_I(inode)->jinode); -diff --git a/fs/ioctl.c b/fs/ioctl.c -index fef3a6bf7c78..3118da0de158 100644 ---- a/fs/ioctl.c -+++ b/fs/ioctl.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -719,3 +720,37 @@ SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) - { - return ksys_ioctl(fd, cmd, arg); - } -+ -+#ifdef CONFIG_COMPAT -+/** -+ * compat_ptr_ioctl - generic implementation of .compat_ioctl file operation -+ * -+ * This is not normally called as a function, but instead set in struct -+ * file_operations as -+ * -+ * .compat_ioctl = compat_ptr_ioctl, -+ * -+ * On most architectures, the compat_ptr_ioctl() just passes all arguments -+ * to the corresponding ->ioctl handler. The exception is arch/s390, where -+ * compat_ptr() clears the top bit of a 32-bit pointer value, so user space -+ * pointers to the second 2GB alias the first 2GB, as is the case for -+ * native 32-bit s390 user space. -+ * -+ * The compat_ptr_ioctl() function must therefore be used only with ioctl -+ * functions that either ignore the argument or pass a pointer to a -+ * compatible data type. -+ * -+ * If any ioctl command handled by fops->unlocked_ioctl passes a plain -+ * integer instead of a pointer, or any of the passed data types -+ * is incompatible between 32-bit and 64-bit architectures, a proper -+ * handler is required instead of compat_ptr_ioctl. -+ */ -+long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ if (!file->f_op->unlocked_ioctl) -+ return -ENOIOCTLCMD; -+ -+ return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); -+} -+EXPORT_SYMBOL(compat_ptr_ioctl); -+#endif -diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c -index 7a922190a8c7..eda83487c9ec 100644 ---- a/fs/ocfs2/quota_global.c -+++ b/fs/ocfs2/quota_global.c -@@ -728,7 +728,7 @@ static int ocfs2_release_dquot(struct dquot *dquot) - - mutex_lock(&dquot->dq_lock); - /* Check whether we are not racing with some other dqget() */ -- if (atomic_read(&dquot->dq_count) > 1) -+ if (dquot_is_busy(dquot)) - goto out; - /* Running from downconvert thread? Postpone quota processing to wq */ - if (current == osb->dc_task) { -diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c -index 702aa63f6774..29abdb1d3b5c 100644 ---- a/fs/overlayfs/dir.c -+++ b/fs/overlayfs/dir.c -@@ -1170,7 +1170,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, - if (newdentry == trap) - goto out_dput; - -- if (WARN_ON(olddentry->d_inode == newdentry->d_inode)) -+ if (olddentry->d_inode == newdentry->d_inode) - goto out_dput; - - err = 0; -diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c -index bc14781886bf..b045cf1826fc 100644 ---- a/fs/overlayfs/inode.c -+++ b/fs/overlayfs/inode.c -@@ -200,8 +200,14 @@ int ovl_getattr(const struct path *path, struct kstat *stat, - if (ovl_test_flag(OVL_INDEX, d_inode(dentry)) || - (!ovl_verify_lower(dentry->d_sb) && - (is_dir || lowerstat.nlink == 1))) { -- stat->ino = lowerstat.ino; - lower_layer = ovl_layer_lower(dentry); -+ /* -+ * Cannot use origin st_dev;st_ino because -+ * origin inode content may differ from overlay -+ * inode content. -+ */ -+ if (samefs || lower_layer->fsid) -+ stat->ino = lowerstat.ino; - } - - /* -diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c -index e9717c2f7d45..f47c591402d7 100644 ---- a/fs/overlayfs/namei.c -+++ b/fs/overlayfs/namei.c -@@ -325,6 +325,14 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, - int i; - - for (i = 0; i < ofs->numlower; i++) { -+ /* -+ * If lower fs uuid is not unique among lower fs we cannot match -+ * fh->uuid to layer. -+ */ -+ if (ofs->lower_layers[i].fsid && -+ ofs->lower_layers[i].fs->bad_uuid) -+ continue; -+ - origin = ovl_decode_real_fh(fh, ofs->lower_layers[i].mnt, - connected); - if (origin) -diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h -index a8279280e88d..28348c44ea5b 100644 ---- a/fs/overlayfs/ovl_entry.h -+++ b/fs/overlayfs/ovl_entry.h -@@ -22,6 +22,8 @@ struct ovl_config { - struct ovl_sb { - struct super_block *sb; - dev_t pseudo_dev; -+ /* Unusable (conflicting) uuid */ -+ bool bad_uuid; - }; - - struct ovl_layer { -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index afbcb116a7f1..7621ff176d15 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -1255,7 +1255,7 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid) - { - unsigned int i; - -- if (!ofs->config.nfs_export && !(ofs->config.index && ofs->upper_mnt)) -+ if (!ofs->config.nfs_export && !ofs->upper_mnt) - return true; - - for (i = 0; i < ofs->numlowerfs; i++) { -@@ -1263,9 +1263,13 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid) - * We use uuid to associate an overlay lower file handle with a - * lower layer, so we can accept lower fs with null uuid as long - * as all lower layers with null uuid are on the same fs. -+ * if we detect multiple lower fs with the same uuid, we -+ * disable lower file handle decoding on all of them. - */ -- if (uuid_equal(&ofs->lower_fs[i].sb->s_uuid, uuid)) -+ if (uuid_equal(&ofs->lower_fs[i].sb->s_uuid, uuid)) { -+ ofs->lower_fs[i].bad_uuid = true; - return false; -+ } - } - return true; - } -@@ -1277,6 +1281,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) - unsigned int i; - dev_t dev; - int err; -+ bool bad_uuid = false; - - /* fsid 0 is reserved for upper fs even with non upper overlay */ - if (ofs->upper_mnt && ofs->upper_mnt->mnt_sb == sb) -@@ -1288,11 +1293,15 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) - } - - if (!ovl_lower_uuid_ok(ofs, &sb->s_uuid)) { -- ofs->config.index = false; -- ofs->config.nfs_export = false; -- pr_warn("overlayfs: %s uuid detected in lower fs '%pd2', falling back to index=off,nfs_export=off.\n", -- uuid_is_null(&sb->s_uuid) ? "null" : "conflicting", -- path->dentry); -+ bad_uuid = true; -+ if (ofs->config.index || ofs->config.nfs_export) { -+ ofs->config.index = false; -+ ofs->config.nfs_export = false; -+ pr_warn("overlayfs: %s uuid detected in lower fs '%pd2', falling back to index=off,nfs_export=off.\n", -+ uuid_is_null(&sb->s_uuid) ? "null" : -+ "conflicting", -+ path->dentry); -+ } - } - - err = get_anon_bdev(&dev); -@@ -1303,6 +1312,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) - - ofs->lower_fs[ofs->numlowerfs].sb = sb; - ofs->lower_fs[ofs->numlowerfs].pseudo_dev = dev; -+ ofs->lower_fs[ofs->numlowerfs].bad_uuid = bad_uuid; - ofs->numlowerfs++; - - return ofs->numlowerfs; -diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c -index 6e826b454082..7f0b39da5022 100644 ---- a/fs/quota/dquot.c -+++ b/fs/quota/dquot.c -@@ -497,7 +497,7 @@ int dquot_release(struct dquot *dquot) - - mutex_lock(&dquot->dq_lock); - /* Check whether we are not racing with some other dqget() */ -- if (atomic_read(&dquot->dq_count) > 1) -+ if (dquot_is_busy(dquot)) - goto out_dqlock; - if (dqopt->ops[dquot->dq_id.type]->release_dqblk) { - ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot); -@@ -623,7 +623,7 @@ EXPORT_SYMBOL(dquot_scan_active); - /* Write all dquot structures to quota files */ - int dquot_writeback_dquots(struct super_block *sb, int type) - { -- struct list_head *dirty; -+ struct list_head dirty; - struct dquot *dquot; - struct quota_info *dqopt = sb_dqopt(sb); - int cnt; -@@ -637,9 +637,10 @@ int dquot_writeback_dquots(struct super_block *sb, int type) - if (!sb_has_quota_active(sb, cnt)) - continue; - spin_lock(&dq_list_lock); -- dirty = &dqopt->info[cnt].dqi_dirty_list; -- while (!list_empty(dirty)) { -- dquot = list_first_entry(dirty, struct dquot, -+ /* Move list away to avoid livelock. */ -+ list_replace_init(&dqopt->info[cnt].dqi_dirty_list, &dirty); -+ while (!list_empty(&dirty)) { -+ dquot = list_first_entry(&dirty, struct dquot, - dq_dirty); - - WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)); -diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c -index 132ec4406ed0..6419e6dacc39 100644 ---- a/fs/reiserfs/inode.c -+++ b/fs/reiserfs/inode.c -@@ -2097,6 +2097,15 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, - goto out_inserted_sd; - } - -+ /* -+ * Mark it private if we're creating the privroot -+ * or something under it. -+ */ -+ if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) { -+ inode->i_flags |= S_PRIVATE; -+ inode->i_opflags &= ~IOP_XATTR; -+ } -+ - if (reiserfs_posixacl(inode->i_sb)) { - reiserfs_write_unlock(inode->i_sb); - retval = reiserfs_inherit_default_acl(th, dir, dentry, inode); -@@ -2111,8 +2120,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, - reiserfs_warning(inode->i_sb, "jdm-13090", - "ACLs aren't enabled in the fs, " - "but vfs thinks they are!"); -- } else if (IS_PRIVATE(dir)) -- inode->i_flags |= S_PRIVATE; -+ } - - if (security->name) { - reiserfs_write_unlock(inode->i_sb); -diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c -index 97f3fc4fdd79..959a066b7bb0 100644 ---- a/fs/reiserfs/namei.c -+++ b/fs/reiserfs/namei.c -@@ -377,10 +377,13 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, - - /* - * Propagate the private flag so we know we're -- * in the priv tree -+ * in the priv tree. Also clear IOP_XATTR -+ * since we don't have xattrs on xattr files. - */ -- if (IS_PRIVATE(dir)) -+ if (IS_PRIVATE(dir)) { - inode->i_flags |= S_PRIVATE; -+ inode->i_opflags &= ~IOP_XATTR; -+ } - } - reiserfs_write_unlock(dir->i_sb); - if (retval == IO_ERROR) { -diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h -index e5ca9ed79e54..726580114d55 100644 ---- a/fs/reiserfs/reiserfs.h -+++ b/fs/reiserfs/reiserfs.h -@@ -1168,6 +1168,8 @@ static inline int bmap_would_wrap(unsigned bmap_nr) - return bmap_nr > ((1LL << 16) - 1); - } - -+extern const struct xattr_handler *reiserfs_xattr_handlers[]; -+ - /* - * this says about version of key of all items (but stat data) the - * object consists of -diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c -index d69b4ac0ae2f..3244037b1286 100644 ---- a/fs/reiserfs/super.c -+++ b/fs/reiserfs/super.c -@@ -2049,6 +2049,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) - if (replay_only(s)) - goto error_unlocked; - -+ s->s_xattr = reiserfs_xattr_handlers; -+ - if (bdev_read_only(s->s_bdev) && !sb_rdonly(s)) { - SWARN(silent, s, "clm-7000", - "Detected readonly device, marking FS readonly"); -diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c -index b5b26d8a192c..62b40df36c98 100644 ---- a/fs/reiserfs/xattr.c -+++ b/fs/reiserfs/xattr.c -@@ -122,13 +122,13 @@ static struct dentry *open_xa_root(struct super_block *sb, int flags) - struct dentry *xaroot; - - if (d_really_is_negative(privroot)) -- return ERR_PTR(-ENODATA); -+ return ERR_PTR(-EOPNOTSUPP); - - inode_lock_nested(d_inode(privroot), I_MUTEX_XATTR); - - xaroot = dget(REISERFS_SB(sb)->xattr_root); - if (!xaroot) -- xaroot = ERR_PTR(-ENODATA); -+ xaroot = ERR_PTR(-EOPNOTSUPP); - else if (d_really_is_negative(xaroot)) { - int err = -ENODATA; - -@@ -619,6 +619,10 @@ int reiserfs_xattr_set(struct inode *inode, const char *name, - int error, error2; - size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size); - -+ /* Check before we start a transaction and then do nothing. */ -+ if (!d_really_is_positive(REISERFS_SB(inode->i_sb)->priv_root)) -+ return -EOPNOTSUPP; -+ - if (!(flags & XATTR_REPLACE)) - jbegin_count += reiserfs_xattr_jcreate_nblocks(inode); - -@@ -841,8 +845,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) - if (d_really_is_negative(dentry)) - return -EINVAL; - -- if (!dentry->d_sb->s_xattr || -- get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) -+ if (get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) - return -EOPNOTSUPP; - - dir = open_xa_dir(d_inode(dentry), XATTR_REPLACE); -@@ -882,6 +885,7 @@ static int create_privroot(struct dentry *dentry) - } - - d_inode(dentry)->i_flags |= S_PRIVATE; -+ d_inode(dentry)->i_opflags &= ~IOP_XATTR; - reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr " - "storage.\n", PRIVROOT_NAME); - -@@ -895,7 +899,7 @@ static int create_privroot(struct dentry *dentry) { return 0; } - #endif - - /* Actual operations that are exported to VFS-land */ --static const struct xattr_handler *reiserfs_xattr_handlers[] = { -+const struct xattr_handler *reiserfs_xattr_handlers[] = { - #ifdef CONFIG_REISERFS_FS_XATTR - &reiserfs_xattr_user_handler, - &reiserfs_xattr_trusted_handler, -@@ -966,8 +970,10 @@ int reiserfs_lookup_privroot(struct super_block *s) - if (!IS_ERR(dentry)) { - REISERFS_SB(s)->priv_root = dentry; - d_set_d_op(dentry, &xattr_lookup_poison_ops); -- if (d_really_is_positive(dentry)) -+ if (d_really_is_positive(dentry)) { - d_inode(dentry)->i_flags |= S_PRIVATE; -+ d_inode(dentry)->i_opflags &= ~IOP_XATTR; -+ } - } else - err = PTR_ERR(dentry); - inode_unlock(d_inode(s->s_root)); -@@ -996,7 +1002,6 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) - } - - if (d_really_is_positive(privroot)) { -- s->s_xattr = reiserfs_xattr_handlers; - inode_lock(d_inode(privroot)); - if (!REISERFS_SB(s)->xattr_root) { - struct dentry *dentry; -diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c -index aa9380bac196..05f666794561 100644 ---- a/fs/reiserfs/xattr_acl.c -+++ b/fs/reiserfs/xattr_acl.c -@@ -320,10 +320,8 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, - * would be useless since permissions are ignored, and a pain because - * it introduces locking cycles - */ -- if (IS_PRIVATE(dir)) { -- inode->i_flags |= S_PRIVATE; -+ if (IS_PRIVATE(inode)) - goto apply_umask; -- } - - err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); - if (err) -diff --git a/fs/splice.c b/fs/splice.c -index 98412721f056..e509239d7e06 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -945,12 +945,13 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, - WARN_ON_ONCE(pipe->nrbufs != 0); - - while (len) { -+ unsigned int pipe_pages; - size_t read_len; - loff_t pos = sd->pos, prev_pos = pos; - - /* Don't try to read more the pipe has space for. */ -- read_len = min_t(size_t, len, -- (pipe->buffers - pipe->nrbufs) << PAGE_SHIFT); -+ pipe_pages = pipe->buffers - pipe->nrbufs; -+ read_len = min(len, (size_t)pipe_pages << PAGE_SHIFT); - ret = do_splice_to(in, &pos, pipe, read_len, flags); - if (unlikely(ret <= 0)) - goto out_release; -@@ -1180,8 +1181,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, - - pipe_lock(opipe); - ret = wait_for_space(opipe, flags); -- if (!ret) -+ if (!ret) { -+ unsigned int pipe_pages; -+ -+ /* Don't try to read more the pipe has space for. */ -+ pipe_pages = opipe->buffers - opipe->nrbufs; -+ len = min(len, (size_t)pipe_pages << PAGE_SHIFT); -+ - ret = do_splice_to(in, &offset, opipe, len, flags); -+ } - pipe_unlock(opipe); - if (ret > 0) - wakeup_pipe_readers(opipe); -diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h -index 175f7b40c585..3f6fddeb7519 100644 ---- a/include/acpi/acpi_bus.h -+++ b/include/acpi/acpi_bus.h -@@ -78,9 +78,6 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev, - bool acpi_dev_found(const char *hid); - bool acpi_dev_present(const char *hid, const char *uid, s64 hrv); - --struct acpi_device * --acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv); -- - #ifdef CONFIG_ACPI - - #include -@@ -683,6 +680,9 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev) - adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set); - } - -+struct acpi_device * -+acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv); -+ - static inline void acpi_dev_put(struct acpi_device *adev) - { - put_device(&adev->dev); -diff --git a/include/linux/fs.h b/include/linux/fs.h -index e0d909d35763..0b4d8fc79e0f 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1727,6 +1727,13 @@ int vfs_mkobj(struct dentry *, umode_t, - - extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); - -+#ifdef CONFIG_COMPAT -+extern long compat_ptr_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg); -+#else -+#define compat_ptr_ioctl NULL -+#endif -+ - /* - * VFS file helper functions. - */ -diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h -index 7cfd2b0504df..a59bf323f713 100644 ---- a/include/linux/mfd/rk808.h -+++ b/include/linux/mfd/rk808.h -@@ -610,7 +610,7 @@ enum { - RK808_ID = 0x0000, - RK809_ID = 0x8090, - RK817_ID = 0x8170, -- RK818_ID = 0x8181, -+ RK818_ID = 0x8180, - }; - - struct rk808 { -diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h -index 185d94829701..91e0b7624053 100644 ---- a/include/linux/quotaops.h -+++ b/include/linux/quotaops.h -@@ -54,6 +54,16 @@ static inline struct dquot *dqgrab(struct dquot *dquot) - atomic_inc(&dquot->dq_count); - return dquot; - } -+ -+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) -+ return true; -+ return false; -+} -+ - void dqput(struct dquot *dquot); - int dquot_scan_active(struct super_block *sb, - int (*fn)(struct dquot *dquot, unsigned long priv), -diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h -index e7e733add99f..44c52639db55 100644 ---- a/include/rdma/ib_verbs.h -+++ b/include/rdma/ib_verbs.h -@@ -4043,9 +4043,7 @@ static inline void ib_dma_unmap_sg_attrs(struct ib_device *dev, - */ - static inline unsigned int ib_dma_max_seg_size(struct ib_device *dev) - { -- struct device_dma_parameters *p = dev->dma_device->dma_parms; -- -- return p ? p->max_segment_size : UINT_MAX; -+ return dma_get_max_seg_size(dev->dma_device); - } - - /** -diff --git a/kernel/cgroup/pids.c b/kernel/cgroup/pids.c -index 8e513a573fe9..138059eb730d 100644 ---- a/kernel/cgroup/pids.c -+++ b/kernel/cgroup/pids.c -@@ -45,7 +45,7 @@ struct pids_cgroup { - * %PIDS_MAX = (%PID_MAX_LIMIT + 1). - */ - atomic64_t counter; -- int64_t limit; -+ atomic64_t limit; - - /* Handle for "pids.events" */ - struct cgroup_file events_file; -@@ -73,8 +73,8 @@ pids_css_alloc(struct cgroup_subsys_state *parent) - if (!pids) - return ERR_PTR(-ENOMEM); - -- pids->limit = PIDS_MAX; - atomic64_set(&pids->counter, 0); -+ atomic64_set(&pids->limit, PIDS_MAX); - atomic64_set(&pids->events_limit, 0); - return &pids->css; - } -@@ -146,13 +146,14 @@ static int pids_try_charge(struct pids_cgroup *pids, int num) - - for (p = pids; parent_pids(p); p = parent_pids(p)) { - int64_t new = atomic64_add_return(num, &p->counter); -+ int64_t limit = atomic64_read(&p->limit); - - /* - * Since new is capped to the maximum number of pid_t, if - * p->limit is %PIDS_MAX then we know that this test will never - * fail. - */ -- if (new > p->limit) -+ if (new > limit) - goto revert; - } - -@@ -277,7 +278,7 @@ set_limit: - * Limit updates don't need to be mutex'd, since it isn't - * critical that any racing fork()s follow the new limit. - */ -- pids->limit = limit; -+ atomic64_set(&pids->limit, limit); - return nbytes; - } - -@@ -285,7 +286,7 @@ static int pids_max_show(struct seq_file *sf, void *v) - { - struct cgroup_subsys_state *css = seq_css(sf); - struct pids_cgroup *pids = css_pids(css); -- int64_t limit = pids->limit; -+ int64_t limit = atomic64_read(&pids->limit); - - if (limit >= PIDS_MAX) - seq_printf(sf, "%s\n", PIDS_MAX_STR); -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index bc2e09a8ea61..649687622654 100644 ---- a/kernel/workqueue.c -+++ b/kernel/workqueue.c -@@ -2532,8 +2532,14 @@ repeat: - */ - if (need_to_create_worker(pool)) { - spin_lock(&wq_mayday_lock); -- get_pwq(pwq); -- list_move_tail(&pwq->mayday_node, &wq->maydays); -+ /* -+ * Queue iff we aren't racing destruction -+ * and somebody else hasn't queued it already. -+ */ -+ if (wq->rescuer && list_empty(&pwq->mayday_node)) { -+ get_pwq(pwq); -+ list_add_tail(&pwq->mayday_node, &wq->maydays); -+ } - spin_unlock(&wq_mayday_lock); - } - } -@@ -4325,9 +4331,29 @@ void destroy_workqueue(struct workqueue_struct *wq) - struct pool_workqueue *pwq; - int node; - -+ /* -+ * Remove it from sysfs first so that sanity check failure doesn't -+ * lead to sysfs name conflicts. -+ */ -+ workqueue_sysfs_unregister(wq); -+ - /* drain it before proceeding with destruction */ - drain_workqueue(wq); - -+ /* kill rescuer, if sanity checks fail, leave it w/o rescuer */ -+ if (wq->rescuer) { -+ struct worker *rescuer = wq->rescuer; -+ -+ /* this prevents new queueing */ -+ spin_lock_irq(&wq_mayday_lock); -+ wq->rescuer = NULL; -+ spin_unlock_irq(&wq_mayday_lock); -+ -+ /* rescuer will empty maydays list before exiting */ -+ kthread_stop(rescuer->task); -+ kfree(rescuer); -+ } -+ - /* sanity checks */ - mutex_lock(&wq->mutex); - for_each_pwq(pwq, wq) { -@@ -4359,11 +4385,6 @@ void destroy_workqueue(struct workqueue_struct *wq) - list_del_rcu(&wq->list); - mutex_unlock(&wq_pool_mutex); - -- workqueue_sysfs_unregister(wq); -- -- if (wq->rescuer) -- kthread_stop(wq->rescuer->task); -- - if (!(wq->flags & WQ_UNBOUND)) { - wq_unregister_lockdep(wq); - /* -@@ -4638,7 +4659,8 @@ static void show_pwq(struct pool_workqueue *pwq) - pr_info(" pwq %d:", pool->id); - pr_cont_pool_info(pool); - -- pr_cont(" active=%d/%d%s\n", pwq->nr_active, pwq->max_active, -+ pr_cont(" active=%d/%d refcnt=%d%s\n", -+ pwq->nr_active, pwq->max_active, pwq->refcnt, - !list_empty(&pwq->mayday_node) ? " MAYDAY" : ""); - - hash_for_each(pool->busy_hash, bkt, worker, hentry) { -diff --git a/lib/raid6/unroll.awk b/lib/raid6/unroll.awk -index c6aa03631df8..0809805a7e23 100644 ---- a/lib/raid6/unroll.awk -+++ b/lib/raid6/unroll.awk -@@ -13,7 +13,7 @@ BEGIN { - for (i = 0; i < rep; ++i) { - tmp = $0 - gsub(/\$\$/, i, tmp) -- gsub(/\$\#/, n, tmp) -+ gsub(/\$#/, n, tmp) - gsub(/\$\*/, "$", tmp) - print tmp - } -diff --git a/mm/shmem.c b/mm/shmem.c -index 220be9fa2c41..7a22e3e03d11 100644 ---- a/mm/shmem.c -+++ b/mm/shmem.c -@@ -2213,11 +2213,14 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) - return -EPERM; - - /* -- * Since the F_SEAL_FUTURE_WRITE seals allow for a MAP_SHARED -- * read-only mapping, take care to not allow mprotect to revert -- * protections. -+ * Since an F_SEAL_FUTURE_WRITE sealed memfd can be mapped as -+ * MAP_SHARED and read-only, take care to not allow mprotect to -+ * revert protections on such mappings. Do this only for shared -+ * mappings. For private mappings, don't need to mask -+ * VM_MAYWRITE as we still want them to be COW-writable. - */ -- vma->vm_flags &= ~(VM_MAYWRITE); -+ if (vma->vm_flags & VM_SHARED) -+ vma->vm_flags &= ~(VM_MAYWRITE); - } - - file_accessed(file); -@@ -2742,7 +2745,7 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, - } - - shmem_falloc.waitq = &shmem_falloc_waitq; -- shmem_falloc.start = unmap_start >> PAGE_SHIFT; -+ shmem_falloc.start = (u64)unmap_start >> PAGE_SHIFT; - shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT; - spin_lock(&inode->i_lock); - inode->i_private = &shmem_falloc; -diff --git a/mm/slab_common.c b/mm/slab_common.c -index f9fb27b4c843..78402b362df9 100644 ---- a/mm/slab_common.c -+++ b/mm/slab_common.c -@@ -904,6 +904,18 @@ static void flush_memcg_workqueue(struct kmem_cache *s) - * previous workitems on workqueue are processed. - */ - flush_workqueue(memcg_kmem_cache_wq); -+ -+ /* -+ * If we're racing with children kmem_cache deactivation, it might -+ * take another rcu grace period to complete their destruction. -+ * At this moment the corresponding percpu_ref_kill() call should be -+ * done, but it might take another rcu grace period to complete -+ * switching to the atomic mode. -+ * Please, note that we check without grabbing the slab_mutex. It's safe -+ * because at this moment the children list can't grow. -+ */ -+ if (!list_empty(&s->memcg_params.children)) -+ rcu_barrier(); - } - #else - static inline int shutdown_memcg_caches(struct kmem_cache *s) -diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c -index 9eab3ad283ce..df6ff2df0124 100644 ---- a/sound/firewire/fireface/ff-pcm.c -+++ b/sound/firewire/fireface/ff-pcm.c -@@ -219,7 +219,7 @@ static int pcm_hw_params(struct snd_pcm_substream *substream, - mutex_unlock(&ff->mutex); - } - -- return 0; -+ return err; - } - - static int pcm_hw_free(struct snd_pcm_substream *substream) -diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c -index 7c6d1c277d4d..78d906af9c00 100644 ---- a/sound/firewire/oxfw/oxfw-pcm.c -+++ b/sound/firewire/oxfw/oxfw-pcm.c -@@ -255,7 +255,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream, - mutex_unlock(&oxfw->mutex); - } - -- return 0; -+ return err; - } - - static int pcm_capture_hw_free(struct snd_pcm_substream *substream) -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index ed3e314b5233..e1229dbad6b2 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -7672,11 +7672,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { - {0x1a, 0x90a70130}, - {0x1b, 0x90170110}, - {0x21, 0x03211020}), -- SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, -- {0x12, 0xb7a60130}, -- {0x13, 0xb8a61140}, -- {0x16, 0x90170110}, -- {0x21, 0x04211020}), - SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, - {0x12, 0x90a60130}, - {0x14, 0x90170110}, -@@ -7864,6 +7859,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(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, -+ {0x19, 0x40000000}, -+ {0x1a, 0x40000000}), - {} - }; - -diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c -index 1c06b3b9218c..19662ee330d6 100644 ---- a/sound/soc/codecs/rt5645.c -+++ b/sound/soc/codecs/rt5645.c -@@ -3270,6 +3270,9 @@ static void rt5645_jack_detect_work(struct work_struct *work) - snd_soc_jack_report(rt5645->mic_jack, - report, SND_JACK_MICROPHONE); - return; -+ case 4: -+ val = snd_soc_component_read32(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020; -+ break; - default: /* read rt5645 jd1_1 status */ - val = snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000; - break; -@@ -3603,7 +3606,7 @@ static const struct rt5645_platform_data intel_braswell_platform_data = { - static const struct rt5645_platform_data buddy_platform_data = { - .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, - .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, -- .jd_mode = 3, -+ .jd_mode = 4, - .level_trigger_irq = true, - }; - -@@ -3999,6 +4002,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, - RT5645_JD1_MODE_1); - break; - case 3: -+ case 4: - regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1, - RT5645_JD1_MODE_MASK, - RT5645_JD1_MODE_2); -diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c -index c7e4e9757dce..a1db1bce330f 100644 ---- a/sound/soc/fsl/fsl_audmix.c -+++ b/sound/soc/fsl/fsl_audmix.c -@@ -286,6 +286,7 @@ static int fsl_audmix_dai_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) - { - struct fsl_audmix *priv = snd_soc_dai_get_drvdata(dai); -+ unsigned long lock_flags; - - /* Capture stream shall not be handled */ - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) -@@ -295,12 +296,16 @@ static int fsl_audmix_dai_trigger(struct snd_pcm_substream *substream, int cmd, - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ spin_lock_irqsave(&priv->lock, lock_flags); - priv->tdms |= BIT(dai->driver->id); -+ spin_unlock_irqrestore(&priv->lock, lock_flags); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ spin_lock_irqsave(&priv->lock, lock_flags); - priv->tdms &= ~BIT(dai->driver->id); -+ spin_unlock_irqrestore(&priv->lock, lock_flags); - break; - default: - return -EINVAL; -@@ -491,6 +496,7 @@ static int fsl_audmix_probe(struct platform_device *pdev) - return PTR_ERR(priv->ipg_clk); - } - -+ spin_lock_init(&priv->lock); - platform_set_drvdata(pdev, priv); - pm_runtime_enable(dev); - -diff --git a/sound/soc/fsl/fsl_audmix.h b/sound/soc/fsl/fsl_audmix.h -index 7812ffec45c5..479f05695d53 100644 ---- a/sound/soc/fsl/fsl_audmix.h -+++ b/sound/soc/fsl/fsl_audmix.h -@@ -96,6 +96,7 @@ struct fsl_audmix { - struct platform_device *pdev; - struct regmap *regmap; - struct clk *ipg_clk; -+ spinlock_t lock; /* Protect tdms */ - u8 tdms; - }; - -diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c -index a71d2340eb05..b5748dcd490f 100644 ---- a/sound/soc/soc-jack.c -+++ b/sound/soc/soc-jack.c -@@ -82,10 +82,9 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) - unsigned int sync = 0; - int enable; - -- trace_snd_soc_jack_report(jack, mask, status); -- - if (!jack) - return; -+ trace_snd_soc_jack_report(jack, mask, status); - - dapm = &jack->card->dapm; - -diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c -index 338cd9faa835..5128f727c0ef 100644 ---- a/tools/perf/tests/backward-ring-buffer.c -+++ b/tools/perf/tests/backward-ring-buffer.c -@@ -147,6 +147,15 @@ int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __m - goto out_delete_evlist; - } - -+ evlist__close(evlist); -+ -+ err = evlist__open(evlist); -+ if (err < 0) { -+ pr_debug("perf_evlist__open: %s\n", -+ str_error_r(errno, sbuf, sizeof(sbuf))); -+ goto out_delete_evlist; -+ } -+ - err = do_test(evlist, 1, &sample_count, &comm_count); - if (err != TEST_OK) - goto out_delete_evlist; -diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c -index 7f8b5c8982e3..b505bb062d07 100644 ---- a/tools/testing/selftests/seccomp/seccomp_bpf.c -+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -3077,7 +3078,7 @@ static int user_trap_syscall(int nr, unsigned int flags) - return seccomp(SECCOMP_SET_MODE_FILTER, flags, &prog); - } - --#define USER_NOTIF_MAGIC 116983961184613L -+#define USER_NOTIF_MAGIC INT_MAX - TEST(user_notification_basic) - { - pid_t pid; diff --git a/patch/kernel/odroidxu4-current/patch-5.4.4-5.patch b/patch/kernel/odroidxu4-current/patch-5.4.4-5.patch deleted file mode 100644 index 491146c981..0000000000 --- a/patch/kernel/odroidxu4-current/patch-5.4.4-5.patch +++ /dev/null @@ -1,2510 +0,0 @@ -diff --git a/Makefile b/Makefile -index 144daf02c78a..0f6e72d5e4f1 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 5 - PATCHLEVEL = 4 --SUBLEVEL = 4 -+SUBLEVEL = 5 - EXTRAVERSION = - NAME = Kleptomaniac Octopus - -diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c -index 6d7ec371e7b2..606fa6d86685 100644 ---- a/drivers/infiniband/core/addr.c -+++ b/drivers/infiniband/core/addr.c -@@ -421,16 +421,15 @@ static int addr6_resolve(struct sockaddr *src_sock, - (const struct sockaddr_in6 *)dst_sock; - struct flowi6 fl6; - struct dst_entry *dst; -- int ret; - - memset(&fl6, 0, sizeof fl6); - fl6.daddr = dst_in->sin6_addr; - fl6.saddr = src_in->sin6_addr; - fl6.flowi6_oif = addr->bound_dev_if; - -- ret = ipv6_stub->ipv6_dst_lookup(addr->net, NULL, &dst, &fl6); -- if (ret < 0) -- return ret; -+ dst = ipv6_stub->ipv6_dst_lookup_flow(addr->net, NULL, &fl6, NULL); -+ if (IS_ERR(dst)) -+ return PTR_ERR(dst); - - if (ipv6_addr_any(&src_in->sin6_addr)) - src_in->sin6_addr = fl6.saddr; -diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c -index 5a3474f9351b..312c2fc961c0 100644 ---- a/drivers/infiniband/sw/rxe/rxe_net.c -+++ b/drivers/infiniband/sw/rxe/rxe_net.c -@@ -117,10 +117,12 @@ static struct dst_entry *rxe_find_route6(struct net_device *ndev, - memcpy(&fl6.daddr, daddr, sizeof(*daddr)); - fl6.flowi6_proto = IPPROTO_UDP; - -- if (unlikely(ipv6_stub->ipv6_dst_lookup(sock_net(recv_sockets.sk6->sk), -- recv_sockets.sk6->sk, &ndst, &fl6))) { -+ ndst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(recv_sockets.sk6->sk), -+ recv_sockets.sk6->sk, &fl6, -+ NULL); -+ if (unlikely(IS_ERR(ndst))) { - pr_err_ratelimited("no route to %pI6\n", daddr); -- goto put; -+ return NULL; - } - - if (unlikely(ndst->error)) { -diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c -index acb016834f04..6cc100e7d5c0 100644 ---- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c -+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c -@@ -1115,7 +1115,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid) - phy_interface_mode(lmac->lmac_type))) - return -ENODEV; - -- phy_start_aneg(lmac->phydev); -+ phy_start(lmac->phydev); - return 0; - } - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h -index f1a7bc46f1c0..2c16add0b642 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en.h -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h -@@ -816,7 +816,7 @@ struct mlx5e_xsk { - struct mlx5e_priv { - /* priv data path fields - start */ - struct mlx5e_txqsq *txq2sq[MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC]; -- int channel_tc2txq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC]; -+ int channel_tc2realtxq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC]; - #ifdef CONFIG_MLX5_CORE_EN_DCB - struct mlx5e_dcbx_dp dcbx_dp; - #endif -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c -index f777994f3005..fce6eccdcf8b 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c -@@ -73,6 +73,7 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = { - [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = 50000, - [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = 50000, - [MLX5E_CAUI_4_100GBASE_CR4_KR4] = 100000, -+ [MLX5E_100GAUI_2_100GBASE_CR2_KR2] = 100000, - [MLX5E_200GAUI_4_200GBASE_CR4_KR4] = 200000, - [MLX5E_400GAUI_8] = 400000, - }; -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c -index 633b117eb13e..99c7cdd0404a 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c -@@ -155,8 +155,11 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, - } - - if (port_buffer->buffer[i].size < -- (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) -+ (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) { -+ pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n", -+ i, port_buffer->buffer[i].size); - return -ENOMEM; -+ } - - port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - xoff; - port_buffer->buffer[i].xon = -@@ -232,6 +235,26 @@ static int update_buffer_lossy(unsigned int max_mtu, - return 0; - } - -+static int fill_pfc_en(struct mlx5_core_dev *mdev, u8 *pfc_en) -+{ -+ u32 g_rx_pause, g_tx_pause; -+ int err; -+ -+ err = mlx5_query_port_pause(mdev, &g_rx_pause, &g_tx_pause); -+ if (err) -+ return err; -+ -+ /* If global pause enabled, set all active buffers to lossless. -+ * Otherwise, check PFC setting. -+ */ -+ if (g_rx_pause || g_tx_pause) -+ *pfc_en = 0xff; -+ else -+ err = mlx5_query_port_pfc(mdev, pfc_en, NULL); -+ -+ return err; -+} -+ - #define MINIMUM_MAX_MTU 9216 - int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, - u32 change, unsigned int mtu, -@@ -277,7 +300,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, - - if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) { - update_prio2buffer = true; -- err = mlx5_query_port_pfc(priv->mdev, &curr_pfc_en, NULL); -+ err = fill_pfc_en(priv->mdev, &curr_pfc_en); - if (err) - return err; - -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 745ab6cd7c30..362f01bc8372 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c -@@ -144,10 +144,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv, - #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) - int ret; - -- ret = ipv6_stub->ipv6_dst_lookup(dev_net(mirred_dev), NULL, &dst, -- fl6); -- if (ret < 0) -- return ret; -+ dst = ipv6_stub->ipv6_dst_lookup_flow(dev_net(mirred_dev), NULL, fl6, -+ NULL); -+ if (IS_ERR(dst)) -+ return PTR_ERR(dst); - - if (!(*out_ttl)) - *out_ttl = ip6_dst_hoplimit(dst); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -index 95601269fa2e..c6776f308d5e 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -@@ -1027,18 +1027,11 @@ static bool ext_link_mode_requested(const unsigned long *adver) - return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS); - } - --static bool ext_speed_requested(u32 speed) --{ --#define MLX5E_MAX_PTYS_LEGACY_SPEED 100000 -- return !!(speed > MLX5E_MAX_PTYS_LEGACY_SPEED); --} -- --static bool ext_requested(u8 autoneg, const unsigned long *adver, u32 speed) -+static bool ext_requested(u8 autoneg, const unsigned long *adver, bool ext_supported) - { - bool ext_link_mode = ext_link_mode_requested(adver); -- bool ext_speed = ext_speed_requested(speed); - -- return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_speed; -+ return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_supported; - } - - int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, -@@ -1065,8 +1058,8 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, - autoneg = link_ksettings->base.autoneg; - speed = link_ksettings->base.speed; - -- ext = ext_requested(autoneg, adver, speed), - ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); -+ ext = ext_requested(autoneg, adver, ext_supported); - if (!ext_supported && ext) - return -EOPNOTSUPP; - -@@ -1643,7 +1636,7 @@ static int mlx5e_get_module_info(struct net_device *netdev, - break; - case MLX5_MODULE_ID_SFP: - modinfo->type = ETH_MODULE_SFF_8472; -- modinfo->eeprom_len = MLX5_EEPROM_PAGE_LENGTH; -+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; - break; - default: - netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n", -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -index 2a56e66f58d8..6abd4ed5b69b 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -@@ -1693,11 +1693,10 @@ static int mlx5e_open_sqs(struct mlx5e_channel *c, - struct mlx5e_params *params, - struct mlx5e_channel_param *cparam) - { -- struct mlx5e_priv *priv = c->priv; - int err, tc; - - for (tc = 0; tc < params->num_tc; tc++) { -- int txq_ix = c->ix + tc * priv->max_nch; -+ int txq_ix = c->ix + tc * params->num_channels; - - err = mlx5e_open_txqsq(c, c->priv->tisn[c->lag_port][tc], txq_ix, - params, &cparam->sq, &c->sq[tc], tc); -@@ -2878,26 +2877,21 @@ static void mlx5e_netdev_set_tcs(struct net_device *netdev) - netdev_set_tc_queue(netdev, tc, nch, 0); - } - --static void mlx5e_build_tc2txq_maps(struct mlx5e_priv *priv) -+static void mlx5e_build_txq_maps(struct mlx5e_priv *priv) - { -- int i, tc; -+ int i, ch; - -- for (i = 0; i < priv->max_nch; i++) -- for (tc = 0; tc < priv->profile->max_tc; tc++) -- priv->channel_tc2txq[i][tc] = i + tc * priv->max_nch; --} -+ ch = priv->channels.num; - --static void mlx5e_build_tx2sq_maps(struct mlx5e_priv *priv) --{ -- struct mlx5e_channel *c; -- struct mlx5e_txqsq *sq; -- int i, tc; -+ for (i = 0; i < ch; i++) { -+ int tc; -+ -+ for (tc = 0; tc < priv->channels.params.num_tc; tc++) { -+ struct mlx5e_channel *c = priv->channels.c[i]; -+ struct mlx5e_txqsq *sq = &c->sq[tc]; - -- for (i = 0; i < priv->channels.num; i++) { -- c = priv->channels.c[i]; -- for (tc = 0; tc < c->num_tc; tc++) { -- sq = &c->sq[tc]; - priv->txq2sq[sq->txq_ix] = sq; -+ priv->channel_tc2realtxq[i][tc] = i + tc * ch; - } - } - } -@@ -2912,7 +2906,7 @@ void mlx5e_activate_priv_channels(struct mlx5e_priv *priv) - netif_set_real_num_tx_queues(netdev, num_txqs); - netif_set_real_num_rx_queues(netdev, num_rxqs); - -- mlx5e_build_tx2sq_maps(priv); -+ mlx5e_build_txq_maps(priv); - mlx5e_activate_channels(&priv->channels); - mlx5e_xdp_tx_enable(priv); - netif_tx_start_all_queues(priv->netdev); -@@ -5028,7 +5022,6 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev, - if (err) - mlx5_core_err(mdev, "TLS initialization failed, %d\n", err); - mlx5e_build_nic_netdev(netdev); -- mlx5e_build_tc2txq_maps(priv); - mlx5e_health_create_reporters(priv); - - return 0; -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c -index 7e6ebd0505cc..9f09253f9f46 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c -@@ -1601,7 +1601,7 @@ static int mlx5e_grp_channels_fill_strings(struct mlx5e_priv *priv, u8 *data, - for (j = 0; j < NUM_SQ_STATS; j++) - sprintf(data + (idx++) * ETH_GSTRING_LEN, - sq_stats_desc[j].format, -- priv->channel_tc2txq[i][tc]); -+ i + tc * max_nch); - - for (i = 0; i < max_nch; i++) { - for (j = 0; j < NUM_XSKSQ_STATS * is_xsk; j++) -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c -index f90a9f8e0fc6..c2c7f214a56a 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c -@@ -1616,7 +1616,7 @@ static void __mlx5e_tc_del_fdb_peer_flow(struct mlx5e_tc_flow *flow) - flow_flag_clear(flow, DUP); - - mlx5e_tc_del_fdb_flow(flow->peer_flow->priv, flow->peer_flow); -- kvfree(flow->peer_flow); -+ kfree(flow->peer_flow); - flow->peer_flow = NULL; - } - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c -index 67dc4f0921b6..dee12f17f9c2 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c -@@ -93,7 +93,7 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb, - if (txq_ix >= num_channels) - txq_ix = priv->txq2sq[txq_ix]->ch_ix; - -- return priv->channel_tc2txq[txq_ix][up]; -+ return priv->channel_tc2realtxq[txq_ix][up]; - } - - static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb) -diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c -index 672ea1342add..da1fd0e08c36 100644 ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -1979,14 +1979,18 @@ static struct ptp_clock_info ocelot_ptp_clock_info = { - - static int ocelot_init_timestamp(struct ocelot *ocelot) - { -+ struct ptp_clock *ptp_clock; -+ - ocelot->ptp_info = ocelot_ptp_clock_info; -- ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); -- if (IS_ERR(ocelot->ptp_clock)) -- return PTR_ERR(ocelot->ptp_clock); -+ ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); -+ if (IS_ERR(ptp_clock)) -+ return PTR_ERR(ptp_clock); - /* Check if PHC support is missing at the configuration level */ -- if (!ocelot->ptp_clock) -+ if (!ptp_clock) - return 0; - -+ ocelot->ptp_clock = ptp_clock; -+ - ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG); - ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW); - ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH); -@@ -2213,6 +2217,8 @@ void ocelot_deinit(struct ocelot *ocelot) - destroy_workqueue(ocelot->stats_queue); - mutex_destroy(&ocelot->stats_lock); - ocelot_ace_deinit(); -+ if (ocelot->ptp_clock) -+ ptp_clock_unregister(ocelot->ptp_clock); - - for (i = 0; i < ocelot->num_phys_ports; i++) { - port = ocelot->ports[i]; -diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c -index 20faa8d24c9f..134640412d7b 100644 ---- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c -+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c -@@ -1364,12 +1364,9 @@ int ionic_lif_rss_config(struct ionic_lif *lif, const u16 types, - - static int ionic_lif_rss_init(struct ionic_lif *lif) - { -- u8 rss_key[IONIC_RSS_HASH_KEY_SIZE]; - unsigned int tbl_sz; - unsigned int i; - -- netdev_rss_key_fill(rss_key, IONIC_RSS_HASH_KEY_SIZE); -- - lif->rss_types = IONIC_RSS_TYPE_IPV4 | - IONIC_RSS_TYPE_IPV4_TCP | - IONIC_RSS_TYPE_IPV4_UDP | -@@ -1382,12 +1379,18 @@ static int ionic_lif_rss_init(struct ionic_lif *lif) - for (i = 0; i < tbl_sz; i++) - lif->rss_ind_tbl[i] = ethtool_rxfh_indir_default(i, lif->nxqs); - -- return ionic_lif_rss_config(lif, lif->rss_types, rss_key, NULL); -+ return ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL); - } - --static int ionic_lif_rss_deinit(struct ionic_lif *lif) -+static void ionic_lif_rss_deinit(struct ionic_lif *lif) - { -- return ionic_lif_rss_config(lif, 0x0, NULL, NULL); -+ int tbl_sz; -+ -+ tbl_sz = le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz); -+ memset(lif->rss_ind_tbl, 0, tbl_sz); -+ memset(lif->rss_hash_key, 0, IONIC_RSS_HASH_KEY_SIZE); -+ -+ ionic_lif_rss_config(lif, 0x0, NULL, NULL); - } - - static void ionic_txrx_disable(struct ionic_lif *lif) -@@ -1710,6 +1713,7 @@ static struct ionic_lif *ionic_lif_alloc(struct ionic *ionic, unsigned int index - dev_err(dev, "Failed to allocate rss indirection table, aborting\n"); - goto err_out_free_qcqs; - } -+ netdev_rss_key_fill(lif->rss_hash_key, IONIC_RSS_HASH_KEY_SIZE); - - list_add_tail(&lif->list, &ionic->lifs); - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 235d51ea4d39..4fe0977d01fa 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -3920,7 +3920,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_32: - case RTL_GIGA_MAC_VER_33: - case RTL_GIGA_MAC_VER_34: -- case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_51: -+ case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_61: - RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | - AcceptBroadcast | AcceptMulticast | AcceptMyPhys); - break; -diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -index f826365c979d..271a00f24f45 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -1502,10 +1502,8 @@ static void free_dma_rx_desc_resources(struct stmmac_priv *priv) - rx_q->dma_erx, rx_q->dma_rx_phy); - - kfree(rx_q->buf_pool); -- if (rx_q->page_pool) { -- page_pool_request_shutdown(rx_q->page_pool); -+ if (rx_q->page_pool) - page_pool_destroy(rx_q->page_pool); -- } - } - } - -diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c -index f298d714efd6..d7a953c647b4 100644 ---- a/drivers/net/ethernet/ti/cpsw.c -+++ b/drivers/net/ethernet/ti/cpsw.c -@@ -890,8 +890,8 @@ static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id) - { - struct cpsw_common *cpsw = dev_id; - -- cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX); - writel(0, &cpsw->wr_regs->rx_en); -+ cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX); - - if (cpsw->quirk_irq) { - disable_irq_nosync(cpsw->irqs_table[0]); -diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c -index 3ab24fdccd3b..5c6b7fc04ea6 100644 ---- a/drivers/net/geneve.c -+++ b/drivers/net/geneve.c -@@ -853,7 +853,9 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, - if (dst) - return dst; - } -- if (ipv6_stub->ipv6_dst_lookup(geneve->net, gs6->sock->sk, &dst, fl6)) { -+ dst = ipv6_stub->ipv6_dst_lookup_flow(geneve->net, gs6->sock->sk, fl6, -+ NULL); -+ if (IS_ERR(dst)) { - netdev_dbg(dev, "no route to %pI6\n", &fl6->daddr); - return ERR_PTR(-ENETUNREACH); - } -diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c -index 8869154fad88..404ac3a0d1c3 100644 ---- a/drivers/net/vxlan.c -+++ b/drivers/net/vxlan.c -@@ -2276,7 +2276,6 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, - bool use_cache = ip_tunnel_dst_cache_usable(skb, info); - struct dst_entry *ndst; - struct flowi6 fl6; -- int err; - - if (!sock6) - return ERR_PTR(-EIO); -@@ -2299,10 +2298,9 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, - fl6.fl6_dport = dport; - fl6.fl6_sport = sport; - -- err = ipv6_stub->ipv6_dst_lookup(vxlan->net, -- sock6->sock->sk, -- &ndst, &fl6); -- if (unlikely(err < 0)) { -+ ndst = ipv6_stub->ipv6_dst_lookup_flow(vxlan->net, sock6->sock->sk, -+ &fl6, NULL); -+ if (unlikely(IS_ERR(ndst))) { - netdev_dbg(dev, "no route to %pI6\n", daddr); - return ERR_PTR(-ENETUNREACH); - } -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index c20f190b4c18..76d952aeb0fc 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1867,6 +1867,11 @@ struct net_device { - unsigned char if_port; - unsigned char dma; - -+ /* Note : dev->mtu is often read without holding a lock. -+ * Writers usually hold RTNL. -+ * It is recommended to use READ_ONCE() to annotate the reads, -+ * and to use WRITE_ONCE() to annotate the writes. -+ */ - unsigned int mtu; - unsigned int min_mtu; - unsigned int max_mtu; -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index 8688f7adfda7..1ba6e2cc2725 100644 ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -3527,8 +3527,9 @@ int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci); - int skb_vlan_pop(struct sk_buff *skb); - int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); - int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, -- int mac_len); --int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len); -+ int mac_len, bool ethernet); -+int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len, -+ bool ethernet); - int skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse); - int skb_mpls_dec_ttl(struct sk_buff *skb); - struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy, -diff --git a/include/linux/time.h b/include/linux/time.h -index 27d83fd2ae61..5f3e49978837 100644 ---- a/include/linux/time.h -+++ b/include/linux/time.h -@@ -96,4 +96,17 @@ static inline bool itimerspec64_valid(const struct itimerspec64 *its) - */ - #define time_after32(a, b) ((s32)((u32)(b) - (u32)(a)) < 0) - #define time_before32(b, a) time_after32(a, b) -+ -+/** -+ * time_between32 - check if a 32-bit timestamp is within a given time range -+ * @t: the time which may be within [l,h] -+ * @l: the lower bound of the range -+ * @h: the higher bound of the range -+ * -+ * time_before32(t, l, h) returns true if @l <= @t <= @h. All operands are -+ * treated as 32-bit integers. -+ * -+ * Equivalent to !(time_before32(@t, @l) || time_after32(@t, @h)). -+ */ -+#define time_between32(t, l, h) ((u32)(h) - (u32)(l) >= (u32)(t) - (u32)(l)) - #endif -diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h -index 5cd12276ae21..e5fc8db1f783 100644 ---- a/include/net/flow_dissector.h -+++ b/include/net/flow_dissector.h -@@ -229,6 +229,7 @@ enum flow_dissector_key_id { - FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */ - FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */ - FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */ -+ FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */ - FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */ - FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */ - FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */ -diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h -index 86c567f531f3..c6f7bd22db60 100644 ---- a/include/net/flow_offload.h -+++ b/include/net/flow_offload.h -@@ -380,19 +380,18 @@ static inline void flow_block_init(struct flow_block *flow_block) - typedef int flow_indr_block_bind_cb_t(struct net_device *dev, void *cb_priv, - enum tc_setup_type type, void *type_data); - --typedef void flow_indr_block_ing_cmd_t(struct net_device *dev, -- flow_indr_block_bind_cb_t *cb, -- void *cb_priv, -- enum flow_block_command command); -+typedef void flow_indr_block_cmd_t(struct net_device *dev, -+ flow_indr_block_bind_cb_t *cb, void *cb_priv, -+ enum flow_block_command command); - --struct flow_indr_block_ing_entry { -- flow_indr_block_ing_cmd_t *cb; -+struct flow_indr_block_entry { -+ flow_indr_block_cmd_t *cb; - struct list_head list; - }; - --void flow_indr_add_block_ing_cb(struct flow_indr_block_ing_entry *entry); -+void flow_indr_add_block_cb(struct flow_indr_block_entry *entry); - --void flow_indr_del_block_ing_cb(struct flow_indr_block_ing_entry *entry); -+void flow_indr_del_block_cb(struct flow_indr_block_entry *entry); - - int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv, - flow_indr_block_bind_cb_t *cb, -diff --git a/include/net/ip.h b/include/net/ip.h -index a2c61c36dc4a..4b15cc1c224c 100644 ---- a/include/net/ip.h -+++ b/include/net/ip.h -@@ -760,4 +760,9 @@ int ip_misc_proc_init(void); - int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family, - struct netlink_ext_ack *extack); - -+static inline bool inetdev_valid_mtu(unsigned int mtu) -+{ -+ return likely(mtu >= IPV4_MIN_MTU); -+} -+ - #endif /* _IP_H */ -diff --git a/include/net/ipv6.h b/include/net/ipv6.h -index 009605c56f20..b59b3dae0f71 100644 ---- a/include/net/ipv6.h -+++ b/include/net/ipv6.h -@@ -1017,7 +1017,7 @@ static inline struct sk_buff *ip6_finish_skb(struct sock *sk) - - int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, - struct flowi6 *fl6); --struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6, -+struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, - const struct in6_addr *final_dst); - struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, - const struct in6_addr *final_dst, -diff --git a/include/net/ipv6_stubs.h b/include/net/ipv6_stubs.h -index 5c93e942c50b..3e7d2c0e79ca 100644 ---- a/include/net/ipv6_stubs.h -+++ b/include/net/ipv6_stubs.h -@@ -24,8 +24,10 @@ struct ipv6_stub { - const struct in6_addr *addr); - int (*ipv6_sock_mc_drop)(struct sock *sk, int ifindex, - const struct in6_addr *addr); -- int (*ipv6_dst_lookup)(struct net *net, struct sock *sk, -- struct dst_entry **dst, struct flowi6 *fl6); -+ struct dst_entry *(*ipv6_dst_lookup_flow)(struct net *net, -+ const struct sock *sk, -+ struct flowi6 *fl6, -+ const struct in6_addr *final_dst); - int (*ipv6_route_input)(struct sk_buff *skb); - - struct fib6_table *(*fib6_get_table)(struct net *net, u32 id); -diff --git a/include/net/page_pool.h b/include/net/page_pool.h -index 2cbcdbdec254..1121faa99c12 100644 ---- a/include/net/page_pool.h -+++ b/include/net/page_pool.h -@@ -70,7 +70,12 @@ struct page_pool_params { - struct page_pool { - struct page_pool_params p; - -- u32 pages_state_hold_cnt; -+ struct delayed_work release_dw; -+ void (*disconnect)(void *); -+ unsigned long defer_start; -+ unsigned long defer_warn; -+ -+ u32 pages_state_hold_cnt; - - /* - * Data structure for allocation side -@@ -129,25 +134,19 @@ inline enum dma_data_direction page_pool_get_dma_dir(struct page_pool *pool) - - struct page_pool *page_pool_create(const struct page_pool_params *params); - --void __page_pool_free(struct page_pool *pool); --static inline void page_pool_free(struct page_pool *pool) --{ -- /* When page_pool isn't compiled-in, net/core/xdp.c doesn't -- * allow registering MEM_TYPE_PAGE_POOL, but shield linker. -- */ - #ifdef CONFIG_PAGE_POOL -- __page_pool_free(pool); --#endif --} -- --/* Drivers use this instead of page_pool_free */ -+void page_pool_destroy(struct page_pool *pool); -+void page_pool_use_xdp_mem(struct page_pool *pool, void (*disconnect)(void *)); -+#else - static inline void page_pool_destroy(struct page_pool *pool) - { -- if (!pool) -- return; -+} - -- page_pool_free(pool); -+static inline void page_pool_use_xdp_mem(struct page_pool *pool, -+ void (*disconnect)(void *)) -+{ - } -+#endif - - /* Never call this directly, use helpers below */ - void __page_pool_put_page(struct page_pool *pool, -@@ -170,24 +169,6 @@ static inline void page_pool_recycle_direct(struct page_pool *pool, - __page_pool_put_page(pool, page, true); - } - --/* API user MUST have disconnected alloc-side (not allowed to call -- * page_pool_alloc_pages()) before calling this. The free-side can -- * still run concurrently, to handle in-flight packet-pages. -- * -- * A request to shutdown can fail (with false) if there are still -- * in-flight packet-pages. -- */ --bool __page_pool_request_shutdown(struct page_pool *pool); --static inline bool page_pool_request_shutdown(struct page_pool *pool) --{ -- bool safe_to_remove = false; -- --#ifdef CONFIG_PAGE_POOL -- safe_to_remove = __page_pool_request_shutdown(pool); --#endif -- return safe_to_remove; --} -- - /* Disconnects a page (from a page_pool). API users can have a need - * to disconnect a page (from a page_pool), to allow it to be used as - * a regular page (that will eventually be returned to the normal -@@ -216,11 +197,6 @@ static inline bool is_page_pool_compiled_in(void) - #endif - } - --static inline void page_pool_get(struct page_pool *pool) --{ -- refcount_inc(&pool->user_cnt); --} -- - static inline bool page_pool_put(struct page_pool *pool) - { - return refcount_dec_and_test(&pool->user_cnt); -diff --git a/include/net/tcp.h b/include/net/tcp.h -index ab4eb5eb5d07..b2367cfe0bda 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -494,15 +494,16 @@ static inline void tcp_synq_overflow(const struct sock *sk) - reuse = rcu_dereference(sk->sk_reuseport_cb); - if (likely(reuse)) { - last_overflow = READ_ONCE(reuse->synq_overflow_ts); -- if (time_after32(now, last_overflow + HZ)) -+ if (!time_between32(now, last_overflow, -+ last_overflow + HZ)) - WRITE_ONCE(reuse->synq_overflow_ts, now); - return; - } - } - -- last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp; -- if (time_after32(now, last_overflow + HZ)) -- tcp_sk(sk)->rx_opt.ts_recent_stamp = now; -+ last_overflow = READ_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp); -+ if (!time_between32(now, last_overflow, last_overflow + HZ)) -+ WRITE_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp, now); - } - - /* syncookies: no recent synqueue overflow on this listening socket? */ -@@ -517,13 +518,23 @@ static inline bool tcp_synq_no_recent_overflow(const struct sock *sk) - reuse = rcu_dereference(sk->sk_reuseport_cb); - if (likely(reuse)) { - last_overflow = READ_ONCE(reuse->synq_overflow_ts); -- return time_after32(now, last_overflow + -- TCP_SYNCOOKIE_VALID); -+ return !time_between32(now, last_overflow - HZ, -+ last_overflow + -+ TCP_SYNCOOKIE_VALID); - } - } - -- last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp; -- return time_after32(now, last_overflow + TCP_SYNCOOKIE_VALID); -+ last_overflow = READ_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp); -+ -+ /* If last_overflow <= jiffies <= last_overflow + TCP_SYNCOOKIE_VALID, -+ * then we're under synflood. However, we have to use -+ * 'last_overflow - HZ' as lower bound. That's because a concurrent -+ * tcp_synq_overflow() could update .ts_recent_stamp after we read -+ * jiffies but before we store .ts_recent_stamp into last_overflow, -+ * which could lead to rejecting a valid syncookie. -+ */ -+ return !time_between32(now, last_overflow - HZ, -+ last_overflow + TCP_SYNCOOKIE_VALID); - } - - static inline u32 tcp_cookie_time(void) -diff --git a/include/net/xdp_priv.h b/include/net/xdp_priv.h -index 6a8cba6ea79a..a9d5b7603b89 100644 ---- a/include/net/xdp_priv.h -+++ b/include/net/xdp_priv.h -@@ -12,12 +12,8 @@ struct xdp_mem_allocator { - struct page_pool *page_pool; - struct zero_copy_allocator *zc_alloc; - }; -- int disconnect_cnt; -- unsigned long defer_start; - struct rhash_head node; - struct rcu_head rcu; -- struct delayed_work defer_wq; -- unsigned long defer_warn; - }; - - #endif /* __LINUX_NET_XDP_PRIV_H__ */ -diff --git a/include/trace/events/xdp.h b/include/trace/events/xdp.h -index 8c8420230a10..c79943e82a54 100644 ---- a/include/trace/events/xdp.h -+++ b/include/trace/events/xdp.h -@@ -317,19 +317,15 @@ __MEM_TYPE_MAP(__MEM_TYPE_TP_FN) - - TRACE_EVENT(mem_disconnect, - -- TP_PROTO(const struct xdp_mem_allocator *xa, -- bool safe_to_remove, bool force), -+ TP_PROTO(const struct xdp_mem_allocator *xa), - -- TP_ARGS(xa, safe_to_remove, force), -+ TP_ARGS(xa), - - TP_STRUCT__entry( - __field(const struct xdp_mem_allocator *, xa) - __field(u32, mem_id) - __field(u32, mem_type) - __field(const void *, allocator) -- __field(bool, safe_to_remove) -- __field(bool, force) -- __field(int, disconnect_cnt) - ), - - TP_fast_assign( -@@ -337,19 +333,12 @@ TRACE_EVENT(mem_disconnect, - __entry->mem_id = xa->mem.id; - __entry->mem_type = xa->mem.type; - __entry->allocator = xa->allocator; -- __entry->safe_to_remove = safe_to_remove; -- __entry->force = force; -- __entry->disconnect_cnt = xa->disconnect_cnt; - ), - -- TP_printk("mem_id=%d mem_type=%s allocator=%p" -- " safe_to_remove=%s force=%s disconnect_cnt=%d", -+ TP_printk("mem_id=%d mem_type=%s allocator=%p", - __entry->mem_id, - __print_symbolic(__entry->mem_type, __MEM_TYPE_SYM_TAB), -- __entry->allocator, -- __entry->safe_to_remove ? "true" : "false", -- __entry->force ? "true" : "false", -- __entry->disconnect_cnt -+ __entry->allocator - ) - ); - -diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c -index e804a3016902..022dc6e504c4 100644 ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -245,6 +245,12 @@ static int br_set_mac_address(struct net_device *dev, void *p) - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - -+ /* dev_set_mac_addr() can be called by a master device on bridge's -+ * NETDEV_UNREGISTER, but since it's being destroyed do nothing -+ */ -+ if (dev->reg_state != NETREG_REGISTERED) -+ return -EBUSY; -+ - spin_lock_bh(&br->lock); - if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { - /* Mac address will be changed in br_stp_change_bridge_id(). */ -diff --git a/net/core/dev.c b/net/core/dev.c -index 99ac84ff398f..046307445ece 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -7967,7 +7967,8 @@ int __dev_set_mtu(struct net_device *dev, int new_mtu) - if (ops->ndo_change_mtu) - return ops->ndo_change_mtu(dev, new_mtu); - -- dev->mtu = new_mtu; -+ /* Pairs with all the lockless reads of dev->mtu in the stack */ -+ WRITE_ONCE(dev->mtu, new_mtu); - return 0; - } - EXPORT_SYMBOL(__dev_set_mtu); -diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c -index 68eda10d0680..1292f3f0f93f 100644 ---- a/net/core/flow_dissector.c -+++ b/net/core/flow_dissector.c -@@ -683,6 +683,31 @@ __skb_flow_dissect_tcp(const struct sk_buff *skb, - key_tcp->flags = (*(__be16 *) &tcp_flag_word(th) & htons(0x0FFF)); - } - -+static void -+__skb_flow_dissect_ports(const struct sk_buff *skb, -+ struct flow_dissector *flow_dissector, -+ void *target_container, void *data, int nhoff, -+ u8 ip_proto, int hlen) -+{ -+ enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX; -+ struct flow_dissector_key_ports *key_ports; -+ -+ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) -+ dissector_ports = FLOW_DISSECTOR_KEY_PORTS; -+ else if (dissector_uses_key(flow_dissector, -+ FLOW_DISSECTOR_KEY_PORTS_RANGE)) -+ dissector_ports = FLOW_DISSECTOR_KEY_PORTS_RANGE; -+ -+ if (dissector_ports == FLOW_DISSECTOR_KEY_MAX) -+ return; -+ -+ key_ports = skb_flow_dissector_target(flow_dissector, -+ dissector_ports, -+ target_container); -+ key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto, -+ data, hlen); -+} -+ - static void - __skb_flow_dissect_ipv4(const struct sk_buff *skb, - struct flow_dissector *flow_dissector, -@@ -852,7 +877,6 @@ bool __skb_flow_dissect(const struct net *net, - struct flow_dissector_key_control *key_control; - struct flow_dissector_key_basic *key_basic; - struct flow_dissector_key_addrs *key_addrs; -- struct flow_dissector_key_ports *key_ports; - struct flow_dissector_key_icmp *key_icmp; - struct flow_dissector_key_tags *key_tags; - struct flow_dissector_key_vlan *key_vlan; -@@ -870,9 +894,10 @@ bool __skb_flow_dissect(const struct net *net, - nhoff = skb_network_offset(skb); - hlen = skb_headlen(skb); - #if IS_ENABLED(CONFIG_NET_DSA) -- if (unlikely(skb->dev && netdev_uses_dsa(skb->dev))) { -+ if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) && -+ proto == htons(ETH_P_XDSA))) { - const struct dsa_device_ops *ops; -- int offset; -+ int offset = 0; - - ops = skb->dev->dsa_ptr->tag_ops; - if (ops->flow_dissect && -@@ -1299,14 +1324,9 @@ ip_proto_again: - break; - } - -- if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS) && -- !(key_control->flags & FLOW_DIS_IS_FRAGMENT)) { -- key_ports = skb_flow_dissector_target(flow_dissector, -- FLOW_DISSECTOR_KEY_PORTS, -- target_container); -- key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto, -- data, hlen); -- } -+ if (!(key_control->flags & FLOW_DIS_IS_FRAGMENT)) -+ __skb_flow_dissect_ports(skb, flow_dissector, target_container, -+ data, nhoff, ip_proto, hlen); - - if (dissector_uses_key(flow_dissector, - FLOW_DISSECTOR_KEY_ICMP)) { -diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c -index cf52d9c422fa..45b6a59ac124 100644 ---- a/net/core/flow_offload.c -+++ b/net/core/flow_offload.c -@@ -283,7 +283,7 @@ int flow_block_cb_setup_simple(struct flow_block_offload *f, - } - EXPORT_SYMBOL(flow_block_cb_setup_simple); - --static LIST_HEAD(block_ing_cb_list); -+static LIST_HEAD(block_cb_list); - - static struct rhashtable indr_setup_block_ht; - -@@ -391,20 +391,19 @@ static void flow_indr_block_cb_del(struct flow_indr_block_cb *indr_block_cb) - kfree(indr_block_cb); - } - --static DEFINE_MUTEX(flow_indr_block_ing_cb_lock); -+static DEFINE_MUTEX(flow_indr_block_cb_lock); - --static void flow_block_ing_cmd(struct net_device *dev, -- flow_indr_block_bind_cb_t *cb, -- void *cb_priv, -- enum flow_block_command command) -+static void flow_block_cmd(struct net_device *dev, -+ flow_indr_block_bind_cb_t *cb, void *cb_priv, -+ enum flow_block_command command) - { -- struct flow_indr_block_ing_entry *entry; -+ struct flow_indr_block_entry *entry; - -- mutex_lock(&flow_indr_block_ing_cb_lock); -- list_for_each_entry(entry, &block_ing_cb_list, list) { -+ mutex_lock(&flow_indr_block_cb_lock); -+ list_for_each_entry(entry, &block_cb_list, list) { - entry->cb(dev, cb, cb_priv, command); - } -- mutex_unlock(&flow_indr_block_ing_cb_lock); -+ mutex_unlock(&flow_indr_block_cb_lock); - } - - int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv, -@@ -424,8 +423,8 @@ int __flow_indr_block_cb_register(struct net_device *dev, void *cb_priv, - if (err) - goto err_dev_put; - -- flow_block_ing_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv, -- FLOW_BLOCK_BIND); -+ flow_block_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv, -+ FLOW_BLOCK_BIND); - - return 0; - -@@ -464,8 +463,8 @@ void __flow_indr_block_cb_unregister(struct net_device *dev, - if (!indr_block_cb) - return; - -- flow_block_ing_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv, -- FLOW_BLOCK_UNBIND); -+ flow_block_cmd(dev, indr_block_cb->cb, indr_block_cb->cb_priv, -+ FLOW_BLOCK_UNBIND); - - flow_indr_block_cb_del(indr_block_cb); - flow_indr_block_dev_put(indr_dev); -@@ -499,21 +498,21 @@ void flow_indr_block_call(struct net_device *dev, - } - EXPORT_SYMBOL_GPL(flow_indr_block_call); - --void flow_indr_add_block_ing_cb(struct flow_indr_block_ing_entry *entry) -+void flow_indr_add_block_cb(struct flow_indr_block_entry *entry) - { -- mutex_lock(&flow_indr_block_ing_cb_lock); -- list_add_tail(&entry->list, &block_ing_cb_list); -- mutex_unlock(&flow_indr_block_ing_cb_lock); -+ mutex_lock(&flow_indr_block_cb_lock); -+ list_add_tail(&entry->list, &block_cb_list); -+ mutex_unlock(&flow_indr_block_cb_lock); - } --EXPORT_SYMBOL_GPL(flow_indr_add_block_ing_cb); -+EXPORT_SYMBOL_GPL(flow_indr_add_block_cb); - --void flow_indr_del_block_ing_cb(struct flow_indr_block_ing_entry *entry) -+void flow_indr_del_block_cb(struct flow_indr_block_entry *entry) - { -- mutex_lock(&flow_indr_block_ing_cb_lock); -+ mutex_lock(&flow_indr_block_cb_lock); - list_del(&entry->list); -- mutex_unlock(&flow_indr_block_ing_cb_lock); -+ mutex_unlock(&flow_indr_block_cb_lock); - } --EXPORT_SYMBOL_GPL(flow_indr_del_block_ing_cb); -+EXPORT_SYMBOL_GPL(flow_indr_del_block_cb); - - static int __init init_flow_indr_rhashtable(void) - { -diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c -index 74cfb8b5ab33..99a6de52b21d 100644 ---- a/net/core/lwt_bpf.c -+++ b/net/core/lwt_bpf.c -@@ -230,9 +230,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb) - fl6.daddr = iph6->daddr; - fl6.saddr = iph6->saddr; - -- err = ipv6_stub->ipv6_dst_lookup(net, skb->sk, &dst, &fl6); -- if (unlikely(err)) -- goto err; -+ dst = ipv6_stub->ipv6_dst_lookup_flow(net, skb->sk, &fl6, NULL); - if (IS_ERR(dst)) { - err = PTR_ERR(dst); - goto err; -diff --git a/net/core/page_pool.c b/net/core/page_pool.c -index 5bc65587f1c4..dfc2501c35d9 100644 ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -18,6 +18,9 @@ - - #include - -+#define DEFER_TIME (msecs_to_jiffies(1000)) -+#define DEFER_WARN_INTERVAL (60 * HZ) -+ - static int page_pool_init(struct page_pool *pool, - const struct page_pool_params *params) - { -@@ -193,22 +196,14 @@ static s32 page_pool_inflight(struct page_pool *pool) - { - u32 release_cnt = atomic_read(&pool->pages_state_release_cnt); - u32 hold_cnt = READ_ONCE(pool->pages_state_hold_cnt); -- s32 distance; -- -- distance = _distance(hold_cnt, release_cnt); -- -- trace_page_pool_inflight(pool, distance, hold_cnt, release_cnt); -- return distance; --} -+ s32 inflight; - --static bool __page_pool_safe_to_destroy(struct page_pool *pool) --{ -- s32 inflight = page_pool_inflight(pool); -+ inflight = _distance(hold_cnt, release_cnt); - -- /* The distance should not be able to become negative */ -+ trace_page_pool_inflight(pool, inflight, hold_cnt, release_cnt); - WARN(inflight < 0, "Negative(%d) inflight packet-pages", inflight); - -- return (inflight == 0); -+ return inflight; - } - - /* Cleanup page_pool state from page */ -@@ -216,6 +211,7 @@ static void __page_pool_clean_page(struct page_pool *pool, - struct page *page) - { - dma_addr_t dma; -+ int count; - - if (!(pool->p.flags & PP_FLAG_DMA_MAP)) - goto skip_dma_unmap; -@@ -227,9 +223,11 @@ static void __page_pool_clean_page(struct page_pool *pool, - DMA_ATTR_SKIP_CPU_SYNC); - page->dma_addr = 0; - skip_dma_unmap: -- atomic_inc(&pool->pages_state_release_cnt); -- trace_page_pool_state_release(pool, page, -- atomic_read(&pool->pages_state_release_cnt)); -+ /* This may be the last page returned, releasing the pool, so -+ * it is not safe to reference pool afterwards. -+ */ -+ count = atomic_inc_return(&pool->pages_state_release_cnt); -+ trace_page_pool_state_release(pool, page, count); - } - - /* unmap the page and clean our state */ -@@ -338,31 +336,10 @@ static void __page_pool_empty_ring(struct page_pool *pool) - } - } - --static void __warn_in_flight(struct page_pool *pool) -+static void page_pool_free(struct page_pool *pool) - { -- u32 release_cnt = atomic_read(&pool->pages_state_release_cnt); -- u32 hold_cnt = READ_ONCE(pool->pages_state_hold_cnt); -- s32 distance; -- -- distance = _distance(hold_cnt, release_cnt); -- -- /* Drivers should fix this, but only problematic when DMA is used */ -- WARN(1, "Still in-flight pages:%d hold:%u released:%u", -- distance, hold_cnt, release_cnt); --} -- --void __page_pool_free(struct page_pool *pool) --{ -- /* Only last user actually free/release resources */ -- if (!page_pool_put(pool)) -- return; -- -- WARN(pool->alloc.count, "API usage violation"); -- WARN(!ptr_ring_empty(&pool->ring), "ptr_ring is not empty"); -- -- /* Can happen due to forced shutdown */ -- if (!__page_pool_safe_to_destroy(pool)) -- __warn_in_flight(pool); -+ if (pool->disconnect) -+ pool->disconnect(pool); - - ptr_ring_cleanup(&pool->ring, NULL); - -@@ -371,12 +348,8 @@ void __page_pool_free(struct page_pool *pool) - - kfree(pool); - } --EXPORT_SYMBOL(__page_pool_free); - --/* Request to shutdown: release pages cached by page_pool, and check -- * for in-flight pages -- */ --bool __page_pool_request_shutdown(struct page_pool *pool) -+static void page_pool_scrub(struct page_pool *pool) - { - struct page *page; - -@@ -393,7 +366,64 @@ bool __page_pool_request_shutdown(struct page_pool *pool) - * be in-flight. - */ - __page_pool_empty_ring(pool); -+} -+ -+static int page_pool_release(struct page_pool *pool) -+{ -+ int inflight; -+ -+ page_pool_scrub(pool); -+ inflight = page_pool_inflight(pool); -+ if (!inflight) -+ page_pool_free(pool); -+ -+ return inflight; -+} -+ -+static void page_pool_release_retry(struct work_struct *wq) -+{ -+ struct delayed_work *dwq = to_delayed_work(wq); -+ struct page_pool *pool = container_of(dwq, typeof(*pool), release_dw); -+ int inflight; -+ -+ inflight = page_pool_release(pool); -+ if (!inflight) -+ return; -+ -+ /* Periodic warning */ -+ if (time_after_eq(jiffies, pool->defer_warn)) { -+ int sec = (s32)((u32)jiffies - (u32)pool->defer_start) / HZ; -+ -+ pr_warn("%s() stalled pool shutdown %d inflight %d sec\n", -+ __func__, inflight, sec); -+ pool->defer_warn = jiffies + DEFER_WARN_INTERVAL; -+ } -+ -+ /* Still not ready to be disconnected, retry later */ -+ schedule_delayed_work(&pool->release_dw, DEFER_TIME); -+} -+ -+void page_pool_use_xdp_mem(struct page_pool *pool, void (*disconnect)(void *)) -+{ -+ refcount_inc(&pool->user_cnt); -+ pool->disconnect = disconnect; -+} -+ -+void page_pool_destroy(struct page_pool *pool) -+{ -+ if (!pool) -+ return; -+ -+ if (!page_pool_put(pool)) -+ return; -+ -+ if (!page_pool_release(pool)) -+ return; -+ -+ pool->defer_start = jiffies; -+ pool->defer_warn = jiffies + DEFER_WARN_INTERVAL; - -- return __page_pool_safe_to_destroy(pool); -+ INIT_DELAYED_WORK(&pool->release_dw, page_pool_release_retry); -+ schedule_delayed_work(&pool->release_dw, DEFER_TIME); - } --EXPORT_SYMBOL(__page_pool_request_shutdown); -+EXPORT_SYMBOL(page_pool_destroy); -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 867e61df00db..973a71f4bc89 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -5484,7 +5484,7 @@ static void skb_mod_eth_type(struct sk_buff *skb, struct ethhdr *hdr, - * Returns 0 on success, -errno otherwise. - */ - int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, -- int mac_len) -+ int mac_len, bool ethernet) - { - struct mpls_shim_hdr *lse; - int err; -@@ -5515,7 +5515,7 @@ int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, - lse->label_stack_entry = mpls_lse; - skb_postpush_rcsum(skb, lse, MPLS_HLEN); - -- if (skb->dev && skb->dev->type == ARPHRD_ETHER) -+ if (ethernet) - skb_mod_eth_type(skb, eth_hdr(skb), mpls_proto); - skb->protocol = mpls_proto; - -@@ -5529,12 +5529,14 @@ EXPORT_SYMBOL_GPL(skb_mpls_push); - * @skb: buffer - * @next_proto: ethertype of header after popped MPLS header - * @mac_len: length of the MAC header -+ * @ethernet: flag to indicate if ethernet header is present in packet - * - * Expects skb->data at mac header. - * - * Returns 0 on success, -errno otherwise. - */ --int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len) -+int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len, -+ bool ethernet) - { - int err; - -@@ -5553,7 +5555,7 @@ int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len) - skb_reset_mac_header(skb); - skb_set_network_header(skb, mac_len); - -- if (skb->dev && skb->dev->type == ARPHRD_ETHER) { -+ if (ethernet) { - struct ethhdr *hdr; - - /* use mpls_hdr() to get ethertype to account for VLANs. */ -diff --git a/net/core/xdp.c b/net/core/xdp.c -index d7bf62ffbb5e..b3f463c6543f 100644 ---- a/net/core/xdp.c -+++ b/net/core/xdp.c -@@ -70,10 +70,6 @@ static void __xdp_mem_allocator_rcu_free(struct rcu_head *rcu) - - xa = container_of(rcu, struct xdp_mem_allocator, rcu); - -- /* Allocator have indicated safe to remove before this is called */ -- if (xa->mem.type == MEM_TYPE_PAGE_POOL) -- page_pool_free(xa->page_pool); -- - /* Allow this ID to be reused */ - ida_simple_remove(&mem_id_pool, xa->mem.id); - -@@ -85,62 +81,57 @@ static void __xdp_mem_allocator_rcu_free(struct rcu_head *rcu) - kfree(xa); - } - --static bool __mem_id_disconnect(int id, bool force) -+static void mem_xa_remove(struct xdp_mem_allocator *xa) -+{ -+ trace_mem_disconnect(xa); -+ -+ if (!rhashtable_remove_fast(mem_id_ht, &xa->node, mem_id_rht_params)) -+ call_rcu(&xa->rcu, __xdp_mem_allocator_rcu_free); -+} -+ -+static void mem_allocator_disconnect(void *allocator) - { - struct xdp_mem_allocator *xa; -- bool safe_to_remove = true; -+ struct rhashtable_iter iter; - - mutex_lock(&mem_id_lock); - -- xa = rhashtable_lookup_fast(mem_id_ht, &id, mem_id_rht_params); -- if (!xa) { -- mutex_unlock(&mem_id_lock); -- WARN(1, "Request remove non-existing id(%d), driver bug?", id); -- return true; -- } -- xa->disconnect_cnt++; -+ rhashtable_walk_enter(mem_id_ht, &iter); -+ do { -+ rhashtable_walk_start(&iter); - -- /* Detects in-flight packet-pages for page_pool */ -- if (xa->mem.type == MEM_TYPE_PAGE_POOL) -- safe_to_remove = page_pool_request_shutdown(xa->page_pool); -+ while ((xa = rhashtable_walk_next(&iter)) && !IS_ERR(xa)) { -+ if (xa->allocator == allocator) -+ mem_xa_remove(xa); -+ } - -- trace_mem_disconnect(xa, safe_to_remove, force); -+ rhashtable_walk_stop(&iter); - -- if ((safe_to_remove || force) && -- !rhashtable_remove_fast(mem_id_ht, &xa->node, mem_id_rht_params)) -- call_rcu(&xa->rcu, __xdp_mem_allocator_rcu_free); -+ } while (xa == ERR_PTR(-EAGAIN)); -+ rhashtable_walk_exit(&iter); - - mutex_unlock(&mem_id_lock); -- return (safe_to_remove|force); - } - --#define DEFER_TIME (msecs_to_jiffies(1000)) --#define DEFER_WARN_INTERVAL (30 * HZ) --#define DEFER_MAX_RETRIES 120 -- --static void mem_id_disconnect_defer_retry(struct work_struct *wq) -+static void mem_id_disconnect(int id) - { -- struct delayed_work *dwq = to_delayed_work(wq); -- struct xdp_mem_allocator *xa = container_of(dwq, typeof(*xa), defer_wq); -- bool force = false; -+ struct xdp_mem_allocator *xa; - -- if (xa->disconnect_cnt > DEFER_MAX_RETRIES) -- force = true; -+ mutex_lock(&mem_id_lock); - -- if (__mem_id_disconnect(xa->mem.id, force)) -+ xa = rhashtable_lookup_fast(mem_id_ht, &id, mem_id_rht_params); -+ if (!xa) { -+ mutex_unlock(&mem_id_lock); -+ WARN(1, "Request remove non-existing id(%d), driver bug?", id); - return; -+ } - -- /* Periodic warning */ -- if (time_after_eq(jiffies, xa->defer_warn)) { -- int sec = (s32)((u32)jiffies - (u32)xa->defer_start) / HZ; -+ trace_mem_disconnect(xa); - -- pr_warn("%s() stalled mem.id=%u shutdown %d attempts %d sec\n", -- __func__, xa->mem.id, xa->disconnect_cnt, sec); -- xa->defer_warn = jiffies + DEFER_WARN_INTERVAL; -- } -+ if (!rhashtable_remove_fast(mem_id_ht, &xa->node, mem_id_rht_params)) -+ call_rcu(&xa->rcu, __xdp_mem_allocator_rcu_free); - -- /* Still not ready to be disconnected, retry later */ -- schedule_delayed_work(&xa->defer_wq, DEFER_TIME); -+ mutex_unlock(&mem_id_lock); - } - - void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq) -@@ -153,38 +144,21 @@ void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq) - return; - } - -- if (xdp_rxq->mem.type != MEM_TYPE_PAGE_POOL && -- xdp_rxq->mem.type != MEM_TYPE_ZERO_COPY) { -- return; -- } -- - if (id == 0) - return; - -- if (__mem_id_disconnect(id, false)) -- return; -- -- /* Could not disconnect, defer new disconnect attempt to later */ -- mutex_lock(&mem_id_lock); -+ if (xdp_rxq->mem.type == MEM_TYPE_ZERO_COPY) -+ return mem_id_disconnect(id); - -- xa = rhashtable_lookup_fast(mem_id_ht, &id, mem_id_rht_params); -- if (!xa) { -- mutex_unlock(&mem_id_lock); -- return; -+ if (xdp_rxq->mem.type == MEM_TYPE_PAGE_POOL) { -+ rcu_read_lock(); -+ xa = rhashtable_lookup(mem_id_ht, &id, mem_id_rht_params); -+ page_pool_destroy(xa->page_pool); -+ rcu_read_unlock(); - } -- xa->defer_start = jiffies; -- xa->defer_warn = jiffies + DEFER_WARN_INTERVAL; -- -- INIT_DELAYED_WORK(&xa->defer_wq, mem_id_disconnect_defer_retry); -- mutex_unlock(&mem_id_lock); -- schedule_delayed_work(&xa->defer_wq, DEFER_TIME); - } - EXPORT_SYMBOL_GPL(xdp_rxq_info_unreg_mem_model); - --/* This unregister operation will also cleanup and destroy the -- * allocator. The page_pool_free() operation is first called when it's -- * safe to remove, possibly deferred to a workqueue. -- */ - void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq) - { - /* Simplify driver cleanup code paths, allow unreg "unused" */ -@@ -371,7 +345,7 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq, - } - - if (type == MEM_TYPE_PAGE_POOL) -- page_pool_get(xdp_alloc->page_pool); -+ page_pool_use_xdp_mem(allocator, mem_allocator_disconnect); - - mutex_unlock(&mem_id_lock); - -@@ -402,15 +376,8 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct, - /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */ - xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); - page = virt_to_head_page(data); -- if (likely(xa)) { -- napi_direct &= !xdp_return_frame_no_direct(); -- page_pool_put_page(xa->page_pool, page, napi_direct); -- } else { -- /* Hopefully stack show who to blame for late return */ -- WARN_ONCE(1, "page_pool gone mem.id=%d", mem->id); -- trace_mem_return_failed(mem, page); -- put_page(page); -- } -+ napi_direct &= !xdp_return_frame_no_direct(); -+ page_pool_put_page(xa->page_pool, page, napi_direct); - rcu_read_unlock(); - break; - case MEM_TYPE_PAGE_SHARED: -diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c -index 25aab672fc99..1e5e08cc0bfc 100644 ---- a/net/dccp/ipv6.c -+++ b/net/dccp/ipv6.c -@@ -210,7 +210,7 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req - final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); - rcu_read_unlock(); - -- dst = ip6_dst_lookup_flow(sk, &fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); - if (IS_ERR(dst)) { - err = PTR_ERR(dst); - dst = NULL; -@@ -282,7 +282,7 @@ static void dccp_v6_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb) - security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6)); - - /* sk = NULL, but it is safe for now. RST socket required. */ -- dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL); -+ dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL); - if (!IS_ERR(dst)) { - skb_dst_set(skb, dst); - ip6_xmit(ctl_sk, skb, &fl6, 0, NULL, 0, 0); -@@ -912,7 +912,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, - opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk)); - final_p = fl6_update_dst(&fl6, opt, &final); - -- dst = ip6_dst_lookup_flow(sk, &fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); - if (IS_ERR(dst)) { - err = PTR_ERR(dst); - goto failure; -diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c -index f509b495451a..b01e1bae4ddc 100644 ---- a/net/hsr/hsr_device.c -+++ b/net/hsr/hsr_device.c -@@ -227,8 +227,13 @@ static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev) - struct hsr_port *master; - - master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); -- skb->dev = master->dev; -- hsr_forward_skb(skb, master); -+ if (master) { -+ skb->dev = master->dev; -+ hsr_forward_skb(skb, master); -+ } else { -+ atomic_long_inc(&dev->tx_dropped); -+ dev_kfree_skb_any(skb); -+ } - return NETDEV_TX_OK; - } - -diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c -index a4b5bd4d2c89..e4632bd2026d 100644 ---- a/net/ipv4/devinet.c -+++ b/net/ipv4/devinet.c -@@ -1496,11 +1496,6 @@ skip: - } - } - --static bool inetdev_valid_mtu(unsigned int mtu) --{ -- return mtu >= IPV4_MIN_MTU; --} -- - static void inetdev_send_gratuitous_arp(struct net_device *dev, - struct in_device *in_dev) - -diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c -index 44bfeecac33e..5fd6e8ed02b5 100644 ---- a/net/ipv4/gre_demux.c -+++ b/net/ipv4/gre_demux.c -@@ -127,7 +127,7 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, - if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr))) - return -EINVAL; - -- ershdr = (struct erspan_base_hdr *)options; -+ ershdr = (struct erspan_base_hdr *)(skb->data + nhs + hdr_len); - tpi->key = cpu_to_be32(get_session_id(ershdr)); - } - -diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c -index 3d8baaaf7086..b268ee1c1b44 100644 ---- a/net/ipv4/ip_output.c -+++ b/net/ipv4/ip_output.c -@@ -1258,15 +1258,18 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, - cork->addr = ipc->addr; - } - -- /* -- * We steal reference to this route, caller should not release it -- */ -- *rtp = NULL; - cork->fragsize = ip_sk_use_pmtu(sk) ? -- dst_mtu(&rt->dst) : rt->dst.dev->mtu; -+ dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu); -+ -+ if (!inetdev_valid_mtu(cork->fragsize)) -+ return -ENETUNREACH; - - cork->gso_size = ipc->gso_size; -+ - cork->dst = &rt->dst; -+ /* We stole this route, caller should not release it. */ -+ *rtp = NULL; -+ - cork->length = 0; - cork->ttl = ipc->ttl; - cork->tos = ipc->tos; -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index 0488607c5cd3..762edd800d78 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -755,8 +755,9 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb - min_t(unsigned int, eff_sacks, - (remaining - TCPOLEN_SACK_BASE_ALIGNED) / - TCPOLEN_SACK_PERBLOCK); -- size += TCPOLEN_SACK_BASE_ALIGNED + -- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; -+ if (likely(opts->num_sack_blocks)) -+ size += TCPOLEN_SACK_BASE_ALIGNED + -+ opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; - } - - return size; -diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c -index 2fc079284ca4..ea00ce3d4117 100644 ---- a/net/ipv6/addrconf_core.c -+++ b/net/ipv6/addrconf_core.c -@@ -129,11 +129,12 @@ int inet6addr_validator_notifier_call_chain(unsigned long val, void *v) - } - EXPORT_SYMBOL(inet6addr_validator_notifier_call_chain); - --static int eafnosupport_ipv6_dst_lookup(struct net *net, struct sock *u1, -- struct dst_entry **u2, -- struct flowi6 *u3) -+static struct dst_entry *eafnosupport_ipv6_dst_lookup_flow(struct net *net, -+ const struct sock *sk, -+ struct flowi6 *fl6, -+ const struct in6_addr *final_dst) - { -- return -EAFNOSUPPORT; -+ return ERR_PTR(-EAFNOSUPPORT); - } - - static int eafnosupport_ipv6_route_input(struct sk_buff *skb) -@@ -190,7 +191,7 @@ static int eafnosupport_ip6_del_rt(struct net *net, struct fib6_info *rt) - } - - const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) { -- .ipv6_dst_lookup = eafnosupport_ipv6_dst_lookup, -+ .ipv6_dst_lookup_flow = eafnosupport_ipv6_dst_lookup_flow, - .ipv6_route_input = eafnosupport_ipv6_route_input, - .fib6_get_table = eafnosupport_fib6_get_table, - .fib6_table_lookup = eafnosupport_fib6_table_lookup, -diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c -index ef37e0574f54..14ac1d911287 100644 ---- a/net/ipv6/af_inet6.c -+++ b/net/ipv6/af_inet6.c -@@ -765,7 +765,7 @@ int inet6_sk_rebuild_header(struct sock *sk) - &final); - rcu_read_unlock(); - -- dst = ip6_dst_lookup_flow(sk, &fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); - if (IS_ERR(dst)) { - sk->sk_route_caps = 0; - sk->sk_err_soft = -PTR_ERR(dst); -@@ -946,7 +946,7 @@ static int ipv6_route_input(struct sk_buff *skb) - static const struct ipv6_stub ipv6_stub_impl = { - .ipv6_sock_mc_join = ipv6_sock_mc_join, - .ipv6_sock_mc_drop = ipv6_sock_mc_drop, -- .ipv6_dst_lookup = ip6_dst_lookup, -+ .ipv6_dst_lookup_flow = ip6_dst_lookup_flow, - .ipv6_route_input = ipv6_route_input, - .fib6_get_table = fib6_get_table, - .fib6_table_lookup = fib6_table_lookup, -diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c -index 96f939248d2f..390bedde21a5 100644 ---- a/net/ipv6/datagram.c -+++ b/net/ipv6/datagram.c -@@ -85,7 +85,7 @@ int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr) - final_p = fl6_update_dst(&fl6, opt, &final); - rcu_read_unlock(); - -- dst = ip6_dst_lookup_flow(sk, &fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); - if (IS_ERR(dst)) { - err = PTR_ERR(dst); - goto out; -diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c -index 0a0945a5b30d..fe9cb8d1adca 100644 ---- a/net/ipv6/inet6_connection_sock.c -+++ b/net/ipv6/inet6_connection_sock.c -@@ -48,7 +48,7 @@ struct dst_entry *inet6_csk_route_req(const struct sock *sk, - fl6->flowi6_uid = sk->sk_uid; - security_req_classify_flow(req, flowi6_to_flowi(fl6)); - -- dst = ip6_dst_lookup_flow(sk, fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p); - if (IS_ERR(dst)) - return NULL; - -@@ -103,7 +103,7 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, - - dst = __inet6_csk_dst_check(sk, np->dst_cookie); - if (!dst) { -- dst = ip6_dst_lookup_flow(sk, fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p); - - if (!IS_ERR(dst)) - ip6_dst_store(sk, dst, NULL, NULL); -diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c -index 71827b56c006..78d495581d69 100644 ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -1144,19 +1144,19 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup); - * It returns a valid dst pointer on success, or a pointer encoded - * error code. - */ --struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6, -+struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, - const struct in6_addr *final_dst) - { - struct dst_entry *dst = NULL; - int err; - -- err = ip6_dst_lookup_tail(sock_net(sk), sk, &dst, fl6); -+ err = ip6_dst_lookup_tail(net, sk, &dst, fl6); - if (err) - return ERR_PTR(err); - if (final_dst) - fl6->daddr = *final_dst; - -- return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); -+ return xfrm_lookup_route(net, dst, flowi6_to_flowi(fl6), sk, 0); - } - EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); - -@@ -1188,7 +1188,7 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, - if (dst) - return dst; - -- dst = ip6_dst_lookup_flow(sk, fl6, final_dst); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_dst); - if (connected && !IS_ERR(dst)) - ip6_sk_dst_store_flow(sk, dst_clone(dst), fl6); - -diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c -index a77f6b7d3a7c..dfe5e603ffe1 100644 ---- a/net/ipv6/raw.c -+++ b/net/ipv6/raw.c -@@ -925,7 +925,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - - fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); - -- dst = ip6_dst_lookup_flow(sk, &fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); - if (IS_ERR(dst)) { - err = PTR_ERR(dst); - goto out; -diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c -index 16632e02e9b0..30915f6f31e3 100644 ---- a/net/ipv6/syncookies.c -+++ b/net/ipv6/syncookies.c -@@ -235,7 +235,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) - fl6.flowi6_uid = sk->sk_uid; - security_req_classify_flow(req, flowi6_to_flowi(&fl6)); - -- dst = ip6_dst_lookup_flow(sk, &fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); - if (IS_ERR(dst)) - goto out_free; - } -diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c -index 4804b6dc5e65..b42fa41cfceb 100644 ---- a/net/ipv6/tcp_ipv6.c -+++ b/net/ipv6/tcp_ipv6.c -@@ -275,7 +275,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, - - security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - -- dst = ip6_dst_lookup_flow(sk, &fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); - if (IS_ERR(dst)) { - err = PTR_ERR(dst); - goto failure; -@@ -906,7 +906,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 - * Underlying function will use this to retrieve the network - * namespace - */ -- dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL); -+ dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL); - if (!IS_ERR(dst)) { - skb_dst_set(buff, dst); - ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, tclass, -diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c -index 802f19aba7e3..d148766f40d1 100644 ---- a/net/l2tp/l2tp_ip6.c -+++ b/net/l2tp/l2tp_ip6.c -@@ -615,7 +615,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) - - fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); - -- dst = ip6_dst_lookup_flow(sk, &fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); - if (IS_ERR(dst)) { - err = PTR_ERR(dst); - goto out; -diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c -index c312741df2ce..4701edffb1f7 100644 ---- a/net/mpls/af_mpls.c -+++ b/net/mpls/af_mpls.c -@@ -617,16 +617,15 @@ static struct net_device *inet6_fib_lookup_dev(struct net *net, - struct net_device *dev; - struct dst_entry *dst; - struct flowi6 fl6; -- int err; - - if (!ipv6_stub) - return ERR_PTR(-EAFNOSUPPORT); - - memset(&fl6, 0, sizeof(fl6)); - memcpy(&fl6.daddr, addr, sizeof(struct in6_addr)); -- err = ipv6_stub->ipv6_dst_lookup(net, NULL, &dst, &fl6); -- if (err) -- return ERR_PTR(err); -+ dst = ipv6_stub->ipv6_dst_lookup_flow(net, NULL, &fl6, NULL); -+ if (IS_ERR(dst)) -+ return ERR_CAST(dst); - - dev = dst->dev; - dev_hold(dev); -diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c -index e25dab8128db..5f6037695dee 100644 ---- a/net/netfilter/nf_tables_offload.c -+++ b/net/netfilter/nf_tables_offload.c -@@ -455,7 +455,7 @@ static int nft_offload_netdev_event(struct notifier_block *this, - return NOTIFY_DONE; - } - --static struct flow_indr_block_ing_entry block_ing_entry = { -+static struct flow_indr_block_entry block_ing_entry = { - .cb = nft_indr_block_cb, - .list = LIST_HEAD_INIT(block_ing_entry.list), - }; -@@ -472,13 +472,13 @@ int nft_offload_init(void) - if (err < 0) - return err; - -- flow_indr_add_block_ing_cb(&block_ing_entry); -+ flow_indr_add_block_cb(&block_ing_entry); - - return 0; - } - - void nft_offload_exit(void) - { -- flow_indr_del_block_ing_cb(&block_ing_entry); -+ flow_indr_del_block_cb(&block_ing_entry); - unregister_netdevice_notifier(&nft_offload_netdev_notifier); - } -diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c -index 1c77f520f474..99352f09deaa 100644 ---- a/net/openvswitch/actions.c -+++ b/net/openvswitch/actions.c -@@ -166,7 +166,8 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, - int err; - - err = skb_mpls_push(skb, mpls->mpls_lse, mpls->mpls_ethertype, -- skb->mac_len); -+ skb->mac_len, -+ ovs_key_mac_proto(key) == MAC_PROTO_ETHERNET); - if (err) - return err; - -@@ -179,7 +180,8 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key, - { - int err; - -- err = skb_mpls_pop(skb, ethertype, skb->mac_len); -+ err = skb_mpls_pop(skb, ethertype, skb->mac_len, -+ ovs_key_mac_proto(key) == MAC_PROTO_ETHERNET); - if (err) - return err; - -diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c -index 05249eb45082..283e8f9a5fd2 100644 ---- a/net/openvswitch/conntrack.c -+++ b/net/openvswitch/conntrack.c -@@ -903,6 +903,17 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key, - } - err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype); - -+ if (err == NF_ACCEPT && -+ ct->status & IPS_SRC_NAT && ct->status & IPS_DST_NAT) { -+ if (maniptype == NF_NAT_MANIP_SRC) -+ maniptype = NF_NAT_MANIP_DST; -+ else -+ maniptype = NF_NAT_MANIP_SRC; -+ -+ err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, -+ maniptype); -+ } -+ - /* Mark NAT done if successful and update the flow key. */ - if (err == NF_ACCEPT) - ovs_nat_update_key(key, skb, maniptype); -diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c -index fcc46025e790..f3232a00970f 100644 ---- a/net/sched/act_ct.c -+++ b/net/sched/act_ct.c -@@ -329,6 +329,7 @@ static int tcf_ct_act_nat(struct sk_buff *skb, - bool commit) - { - #if IS_ENABLED(CONFIG_NF_NAT) -+ int err; - enum nf_nat_manip_type maniptype; - - if (!(ct_action & TCA_CT_ACT_NAT)) -@@ -359,7 +360,17 @@ static int tcf_ct_act_nat(struct sk_buff *skb, - return NF_ACCEPT; - } - -- return ct_nat_execute(skb, ct, ctinfo, range, maniptype); -+ err = ct_nat_execute(skb, ct, ctinfo, range, maniptype); -+ if (err == NF_ACCEPT && -+ ct->status & IPS_SRC_NAT && ct->status & IPS_DST_NAT) { -+ if (maniptype == NF_NAT_MANIP_SRC) -+ maniptype = NF_NAT_MANIP_DST; -+ else -+ maniptype = NF_NAT_MANIP_SRC; -+ -+ err = ct_nat_execute(skb, ct, ctinfo, range, maniptype); -+ } -+ return err; - #else - return NF_ACCEPT; - #endif -diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c -index 4cf6c553bb0b..db570d2bd0e0 100644 ---- a/net/sched/act_mpls.c -+++ b/net/sched/act_mpls.c -@@ -1,6 +1,7 @@ - // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) - /* Copyright (C) 2019 Netronome Systems, Inc. */ - -+#include - #include - #include - #include -@@ -76,12 +77,14 @@ static int tcf_mpls_act(struct sk_buff *skb, const struct tc_action *a, - - switch (p->tcfm_action) { - case TCA_MPLS_ACT_POP: -- if (skb_mpls_pop(skb, p->tcfm_proto, mac_len)) -+ if (skb_mpls_pop(skb, p->tcfm_proto, mac_len, -+ skb->dev && skb->dev->type == ARPHRD_ETHER)) - goto drop; - break; - case TCA_MPLS_ACT_PUSH: - new_lse = tcf_mpls_get_lse(NULL, p, !eth_p_mpls(skb->protocol)); -- if (skb_mpls_push(skb, new_lse, p->tcfm_proto, mac_len)) -+ if (skb_mpls_push(skb, new_lse, p->tcfm_proto, mac_len, -+ skb->dev && skb->dev->type == ARPHRD_ETHER)) - goto drop; - break; - case TCA_MPLS_ACT_MODIFY: -diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c -index 20d60b8fcb70..6a0eacafdb19 100644 ---- a/net/sched/cls_api.c -+++ b/net/sched/cls_api.c -@@ -626,15 +626,15 @@ static void tcf_chain_flush(struct tcf_chain *chain, bool rtnl_held) - static int tcf_block_setup(struct tcf_block *block, - struct flow_block_offload *bo); - --static void tc_indr_block_ing_cmd(struct net_device *dev, -- struct tcf_block *block, -- flow_indr_block_bind_cb_t *cb, -- void *cb_priv, -- enum flow_block_command command) -+static void tc_indr_block_cmd(struct net_device *dev, struct tcf_block *block, -+ flow_indr_block_bind_cb_t *cb, void *cb_priv, -+ enum flow_block_command command, bool ingress) - { - struct flow_block_offload bo = { - .command = command, -- .binder_type = FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS, -+ .binder_type = ingress ? -+ FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS : -+ FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS, - .net = dev_net(dev), - .block_shared = tcf_block_non_null_shared(block), - }; -@@ -652,9 +652,10 @@ static void tc_indr_block_ing_cmd(struct net_device *dev, - up_write(&block->cb_lock); - } - --static struct tcf_block *tc_dev_ingress_block(struct net_device *dev) -+static struct tcf_block *tc_dev_block(struct net_device *dev, bool ingress) - { - const struct Qdisc_class_ops *cops; -+ const struct Qdisc_ops *ops; - struct Qdisc *qdisc; - - if (!dev_ingress_queue(dev)) -@@ -664,24 +665,37 @@ static struct tcf_block *tc_dev_ingress_block(struct net_device *dev) - if (!qdisc) - return NULL; - -- cops = qdisc->ops->cl_ops; -+ ops = qdisc->ops; -+ if (!ops) -+ return NULL; -+ -+ if (!ingress && !strcmp("ingress", ops->id)) -+ return NULL; -+ -+ cops = ops->cl_ops; - if (!cops) - return NULL; - - if (!cops->tcf_block) - return NULL; - -- return cops->tcf_block(qdisc, TC_H_MIN_INGRESS, NULL); -+ return cops->tcf_block(qdisc, -+ ingress ? TC_H_MIN_INGRESS : TC_H_MIN_EGRESS, -+ NULL); - } - --static void tc_indr_block_get_and_ing_cmd(struct net_device *dev, -- flow_indr_block_bind_cb_t *cb, -- void *cb_priv, -- enum flow_block_command command) -+static void tc_indr_block_get_and_cmd(struct net_device *dev, -+ flow_indr_block_bind_cb_t *cb, -+ void *cb_priv, -+ enum flow_block_command command) - { -- struct tcf_block *block = tc_dev_ingress_block(dev); -+ struct tcf_block *block; -+ -+ block = tc_dev_block(dev, true); -+ tc_indr_block_cmd(dev, block, cb, cb_priv, command, true); - -- tc_indr_block_ing_cmd(dev, block, cb, cb_priv, command); -+ block = tc_dev_block(dev, false); -+ tc_indr_block_cmd(dev, block, cb, cb_priv, command, false); - } - - static void tc_indr_block_call(struct tcf_block *block, -@@ -2721,13 +2735,19 @@ static int tc_chain_tmplt_add(struct tcf_chain *chain, struct net *net, - struct netlink_ext_ack *extack) - { - const struct tcf_proto_ops *ops; -+ char name[IFNAMSIZ]; - void *tmplt_priv; - - /* If kind is not set, user did not specify template. */ - if (!tca[TCA_KIND]) - return 0; - -- ops = tcf_proto_lookup_ops(nla_data(tca[TCA_KIND]), true, extack); -+ if (tcf_proto_check_kind(tca[TCA_KIND], name)) { -+ NL_SET_ERR_MSG(extack, "Specified TC chain template name too long"); -+ return -EINVAL; -+ } -+ -+ ops = tcf_proto_lookup_ops(name, true, extack); - if (IS_ERR(ops)) - return PTR_ERR(ops); - if (!ops->tmplt_create || !ops->tmplt_destroy || !ops->tmplt_dump) { -@@ -3626,9 +3646,9 @@ static struct pernet_operations tcf_net_ops = { - .size = sizeof(struct tcf_net), - }; - --static struct flow_indr_block_ing_entry block_ing_entry = { -- .cb = tc_indr_block_get_and_ing_cmd, -- .list = LIST_HEAD_INIT(block_ing_entry.list), -+static struct flow_indr_block_entry block_entry = { -+ .cb = tc_indr_block_get_and_cmd, -+ .list = LIST_HEAD_INIT(block_entry.list), - }; - - static int __init tc_filter_init(void) -@@ -3643,7 +3663,7 @@ static int __init tc_filter_init(void) - if (err) - goto err_register_pernet_subsys; - -- flow_indr_add_block_ing_cb(&block_ing_entry); -+ flow_indr_add_block_cb(&block_entry); - - rtnl_register(PF_UNSPEC, RTM_NEWTFILTER, tc_new_tfilter, NULL, - RTNL_FLAG_DOIT_UNLOCKED); -diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c -index 74221e3351c3..4ac110bf19c5 100644 ---- a/net/sched/cls_flower.c -+++ b/net/sched/cls_flower.c -@@ -54,8 +54,13 @@ struct fl_flow_key { - struct flow_dissector_key_ip ip; - struct flow_dissector_key_ip enc_ip; - struct flow_dissector_key_enc_opts enc_opts; -- struct flow_dissector_key_ports tp_min; -- struct flow_dissector_key_ports tp_max; -+ union { -+ struct flow_dissector_key_ports tp; -+ struct { -+ struct flow_dissector_key_ports tp_min; -+ struct flow_dissector_key_ports tp_max; -+ }; -+ } tp_range; - struct flow_dissector_key_ct ct; - } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */ - -@@ -198,19 +203,19 @@ static bool fl_range_port_dst_cmp(struct cls_fl_filter *filter, - { - __be16 min_mask, max_mask, min_val, max_val; - -- min_mask = htons(filter->mask->key.tp_min.dst); -- max_mask = htons(filter->mask->key.tp_max.dst); -- min_val = htons(filter->key.tp_min.dst); -- max_val = htons(filter->key.tp_max.dst); -+ min_mask = htons(filter->mask->key.tp_range.tp_min.dst); -+ max_mask = htons(filter->mask->key.tp_range.tp_max.dst); -+ min_val = htons(filter->key.tp_range.tp_min.dst); -+ max_val = htons(filter->key.tp_range.tp_max.dst); - - if (min_mask && max_mask) { -- if (htons(key->tp.dst) < min_val || -- htons(key->tp.dst) > max_val) -+ if (htons(key->tp_range.tp.dst) < min_val || -+ htons(key->tp_range.tp.dst) > max_val) - return false; - - /* skb does not have min and max values */ -- mkey->tp_min.dst = filter->mkey.tp_min.dst; -- mkey->tp_max.dst = filter->mkey.tp_max.dst; -+ mkey->tp_range.tp_min.dst = filter->mkey.tp_range.tp_min.dst; -+ mkey->tp_range.tp_max.dst = filter->mkey.tp_range.tp_max.dst; - } - return true; - } -@@ -221,19 +226,19 @@ static bool fl_range_port_src_cmp(struct cls_fl_filter *filter, - { - __be16 min_mask, max_mask, min_val, max_val; - -- min_mask = htons(filter->mask->key.tp_min.src); -- max_mask = htons(filter->mask->key.tp_max.src); -- min_val = htons(filter->key.tp_min.src); -- max_val = htons(filter->key.tp_max.src); -+ min_mask = htons(filter->mask->key.tp_range.tp_min.src); -+ max_mask = htons(filter->mask->key.tp_range.tp_max.src); -+ min_val = htons(filter->key.tp_range.tp_min.src); -+ max_val = htons(filter->key.tp_range.tp_max.src); - - if (min_mask && max_mask) { -- if (htons(key->tp.src) < min_val || -- htons(key->tp.src) > max_val) -+ if (htons(key->tp_range.tp.src) < min_val || -+ htons(key->tp_range.tp.src) > max_val) - return false; - - /* skb does not have min and max values */ -- mkey->tp_min.src = filter->mkey.tp_min.src; -- mkey->tp_max.src = filter->mkey.tp_max.src; -+ mkey->tp_range.tp_min.src = filter->mkey.tp_range.tp_min.src; -+ mkey->tp_range.tp_max.src = filter->mkey.tp_range.tp_max.src; - } - return true; - } -@@ -715,23 +720,25 @@ static void fl_set_key_val(struct nlattr **tb, - static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key, - struct fl_flow_key *mask) - { -- fl_set_key_val(tb, &key->tp_min.dst, -- TCA_FLOWER_KEY_PORT_DST_MIN, &mask->tp_min.dst, -- TCA_FLOWER_UNSPEC, sizeof(key->tp_min.dst)); -- fl_set_key_val(tb, &key->tp_max.dst, -- TCA_FLOWER_KEY_PORT_DST_MAX, &mask->tp_max.dst, -- TCA_FLOWER_UNSPEC, sizeof(key->tp_max.dst)); -- fl_set_key_val(tb, &key->tp_min.src, -- TCA_FLOWER_KEY_PORT_SRC_MIN, &mask->tp_min.src, -- TCA_FLOWER_UNSPEC, sizeof(key->tp_min.src)); -- fl_set_key_val(tb, &key->tp_max.src, -- TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_max.src, -- TCA_FLOWER_UNSPEC, sizeof(key->tp_max.src)); -- -- if ((mask->tp_min.dst && mask->tp_max.dst && -- htons(key->tp_max.dst) <= htons(key->tp_min.dst)) || -- (mask->tp_min.src && mask->tp_max.src && -- htons(key->tp_max.src) <= htons(key->tp_min.src))) -+ fl_set_key_val(tb, &key->tp_range.tp_min.dst, -+ TCA_FLOWER_KEY_PORT_DST_MIN, &mask->tp_range.tp_min.dst, -+ TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_min.dst)); -+ fl_set_key_val(tb, &key->tp_range.tp_max.dst, -+ TCA_FLOWER_KEY_PORT_DST_MAX, &mask->tp_range.tp_max.dst, -+ TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.dst)); -+ fl_set_key_val(tb, &key->tp_range.tp_min.src, -+ TCA_FLOWER_KEY_PORT_SRC_MIN, &mask->tp_range.tp_min.src, -+ TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_min.src)); -+ fl_set_key_val(tb, &key->tp_range.tp_max.src, -+ TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_range.tp_max.src, -+ TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src)); -+ -+ if ((mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst && -+ htons(key->tp_range.tp_max.dst) <= -+ htons(key->tp_range.tp_min.dst)) || -+ (mask->tp_range.tp_min.src && mask->tp_range.tp_max.src && -+ htons(key->tp_range.tp_max.src) <= -+ htons(key->tp_range.tp_min.src))) - return -EINVAL; - - return 0; -@@ -1320,9 +1327,10 @@ static void fl_init_dissector(struct flow_dissector *dissector, - FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4); - FL_KEY_SET_IF_MASKED(mask, keys, cnt, - FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6); -- if (FL_KEY_IS_MASKED(mask, tp) || -- FL_KEY_IS_MASKED(mask, tp_min) || FL_KEY_IS_MASKED(mask, tp_max)) -- FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_PORTS, tp); -+ FL_KEY_SET_IF_MASKED(mask, keys, cnt, -+ FLOW_DISSECTOR_KEY_PORTS, tp); -+ FL_KEY_SET_IF_MASKED(mask, keys, cnt, -+ FLOW_DISSECTOR_KEY_PORTS_RANGE, tp_range); - FL_KEY_SET_IF_MASKED(mask, keys, cnt, - FLOW_DISSECTOR_KEY_IP, ip); - FL_KEY_SET_IF_MASKED(mask, keys, cnt, -@@ -1371,8 +1379,10 @@ static struct fl_flow_mask *fl_create_new_mask(struct cls_fl_head *head, - - fl_mask_copy(newmask, mask); - -- if ((newmask->key.tp_min.dst && newmask->key.tp_max.dst) || -- (newmask->key.tp_min.src && newmask->key.tp_max.src)) -+ if ((newmask->key.tp_range.tp_min.dst && -+ newmask->key.tp_range.tp_max.dst) || -+ (newmask->key.tp_range.tp_min.src && -+ newmask->key.tp_range.tp_max.src)) - newmask->flags |= TCA_FLOWER_MASK_FLAGS_RANGE; - - err = fl_init_mask_hashtable(newmask); -@@ -1970,18 +1980,22 @@ static int fl_dump_key_val(struct sk_buff *skb, - static int fl_dump_key_port_range(struct sk_buff *skb, struct fl_flow_key *key, - struct fl_flow_key *mask) - { -- if (fl_dump_key_val(skb, &key->tp_min.dst, TCA_FLOWER_KEY_PORT_DST_MIN, -- &mask->tp_min.dst, TCA_FLOWER_UNSPEC, -- sizeof(key->tp_min.dst)) || -- fl_dump_key_val(skb, &key->tp_max.dst, TCA_FLOWER_KEY_PORT_DST_MAX, -- &mask->tp_max.dst, TCA_FLOWER_UNSPEC, -- sizeof(key->tp_max.dst)) || -- fl_dump_key_val(skb, &key->tp_min.src, TCA_FLOWER_KEY_PORT_SRC_MIN, -- &mask->tp_min.src, TCA_FLOWER_UNSPEC, -- sizeof(key->tp_min.src)) || -- fl_dump_key_val(skb, &key->tp_max.src, TCA_FLOWER_KEY_PORT_SRC_MAX, -- &mask->tp_max.src, TCA_FLOWER_UNSPEC, -- sizeof(key->tp_max.src))) -+ if (fl_dump_key_val(skb, &key->tp_range.tp_min.dst, -+ TCA_FLOWER_KEY_PORT_DST_MIN, -+ &mask->tp_range.tp_min.dst, TCA_FLOWER_UNSPEC, -+ sizeof(key->tp_range.tp_min.dst)) || -+ fl_dump_key_val(skb, &key->tp_range.tp_max.dst, -+ TCA_FLOWER_KEY_PORT_DST_MAX, -+ &mask->tp_range.tp_max.dst, TCA_FLOWER_UNSPEC, -+ sizeof(key->tp_range.tp_max.dst)) || -+ fl_dump_key_val(skb, &key->tp_range.tp_min.src, -+ TCA_FLOWER_KEY_PORT_SRC_MIN, -+ &mask->tp_range.tp_min.src, TCA_FLOWER_UNSPEC, -+ sizeof(key->tp_range.tp_min.src)) || -+ fl_dump_key_val(skb, &key->tp_range.tp_max.src, -+ TCA_FLOWER_KEY_PORT_SRC_MAX, -+ &mask->tp_range.tp_max.src, TCA_FLOWER_UNSPEC, -+ sizeof(key->tp_range.tp_max.src))) - return -1; - - return 0; -diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c -index 278c0b2dc523..e79f1afe0cfd 100644 ---- a/net/sched/sch_mq.c -+++ b/net/sched/sch_mq.c -@@ -153,6 +153,7 @@ static int mq_dump(struct Qdisc *sch, struct sk_buff *skb) - __gnet_stats_copy_queue(&sch->qstats, - qdisc->cpu_qstats, - &qdisc->qstats, qlen); -+ sch->q.qlen += qlen; - } else { - sch->q.qlen += qdisc->q.qlen; - sch->bstats.bytes += qdisc->bstats.bytes; -diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c -index 0d0113a24962..8766ab5b8788 100644 ---- a/net/sched/sch_mqprio.c -+++ b/net/sched/sch_mqprio.c -@@ -411,6 +411,7 @@ static int mqprio_dump(struct Qdisc *sch, struct sk_buff *skb) - __gnet_stats_copy_queue(&sch->qstats, - qdisc->cpu_qstats, - &qdisc->qstats, qlen); -+ sch->q.qlen += qlen; - } else { - sch->q.qlen += qdisc->q.qlen; - sch->bstats.bytes += qdisc->bstats.bytes; -@@ -433,7 +434,7 @@ static int mqprio_dump(struct Qdisc *sch, struct sk_buff *skb) - opt.offset[tc] = dev->tc_to_txq[tc].offset; - } - -- if (nla_put(skb, TCA_OPTIONS, NLA_ALIGN(sizeof(opt)), &opt)) -+ if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt)) - goto nla_put_failure; - - if ((priv->flags & TC_MQPRIO_F_MODE) && -diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c -index dd860fea0148..bc734cfaa29e 100644 ---- a/net/sctp/ipv6.c -+++ b/net/sctp/ipv6.c -@@ -275,7 +275,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, - final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); - rcu_read_unlock(); - -- dst = ip6_dst_lookup_flow(sk, fl6, final_p); -+ dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p); - if (!asoc || saddr) - goto out; - -@@ -328,7 +328,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, - fl6->saddr = laddr->a.v6.sin6_addr; - fl6->fl6_sport = laddr->a.v6.sin6_port; - final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); -- bdst = ip6_dst_lookup_flow(sk, fl6, final_p); -+ bdst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p); - - if (IS_ERR(bdst)) - continue; -diff --git a/net/tipc/core.c b/net/tipc/core.c -index 8f35060a24e1..12192e7f4050 100644 ---- a/net/tipc/core.c -+++ b/net/tipc/core.c -@@ -125,14 +125,6 @@ static int __init tipc_init(void) - sysctl_tipc_rmem[1] = RCVBUF_DEF; - sysctl_tipc_rmem[2] = RCVBUF_MAX; - -- err = tipc_netlink_start(); -- if (err) -- goto out_netlink; -- -- err = tipc_netlink_compat_start(); -- if (err) -- goto out_netlink_compat; -- - err = tipc_register_sysctl(); - if (err) - goto out_sysctl; -@@ -153,8 +145,21 @@ static int __init tipc_init(void) - if (err) - goto out_bearer; - -+ err = tipc_netlink_start(); -+ if (err) -+ goto out_netlink; -+ -+ err = tipc_netlink_compat_start(); -+ if (err) -+ goto out_netlink_compat; -+ - pr_info("Started in single node mode\n"); - return 0; -+ -+out_netlink_compat: -+ tipc_netlink_stop(); -+out_netlink: -+ tipc_bearer_cleanup(); - out_bearer: - unregister_pernet_device(&tipc_topsrv_net_ops); - out_pernet_topsrv: -@@ -164,22 +169,18 @@ out_socket: - out_pernet: - tipc_unregister_sysctl(); - out_sysctl: -- tipc_netlink_compat_stop(); --out_netlink_compat: -- tipc_netlink_stop(); --out_netlink: - pr_err("Unable to start in single node mode\n"); - return err; - } - - static void __exit tipc_exit(void) - { -+ tipc_netlink_compat_stop(); -+ tipc_netlink_stop(); - tipc_bearer_cleanup(); - unregister_pernet_device(&tipc_topsrv_net_ops); - tipc_socket_stop(); - unregister_pernet_device(&tipc_net_ops); -- tipc_netlink_stop(); -- tipc_netlink_compat_stop(); - tipc_unregister_sysctl(); - - pr_info("Deactivated\n"); -diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c -index 287df68721df..186c78431217 100644 ---- a/net/tipc/udp_media.c -+++ b/net/tipc/udp_media.c -@@ -195,10 +195,13 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, - .saddr = src->ipv6, - .flowi6_proto = IPPROTO_UDP - }; -- err = ipv6_stub->ipv6_dst_lookup(net, ub->ubsock->sk, -- &ndst, &fl6); -- if (err) -+ ndst = ipv6_stub->ipv6_dst_lookup_flow(net, -+ ub->ubsock->sk, -+ &fl6, NULL); -+ if (IS_ERR(ndst)) { -+ err = PTR_ERR(ndst); - goto tx_error; -+ } - dst_cache_set_ip6(cache, ndst, &fl6.saddr); - } - ttl = ip6_dst_hoplimit(ndst); -diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c -index 683d00837693..3f5209e2d4ee 100644 ---- a/net/tls/tls_device.c -+++ b/net/tls/tls_device.c -@@ -417,7 +417,7 @@ static int tls_push_data(struct sock *sk, - - if (flags & - ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_SENDPAGE_NOTLAST)) -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - - if (sk->sk_err) - return -sk->sk_err; -@@ -560,7 +560,7 @@ int tls_device_sendpage(struct sock *sk, struct page *page, - lock_sock(sk); - - if (flags & MSG_OOB) { -- rc = -ENOTSUPP; -+ rc = -EOPNOTSUPP; - goto out; - } - -@@ -999,7 +999,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx) - } - - if (!(netdev->features & NETIF_F_HW_TLS_TX)) { -- rc = -ENOTSUPP; -+ rc = -EOPNOTSUPP; - goto release_netdev; - } - -@@ -1071,7 +1071,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx) - } - - if (!(netdev->features & NETIF_F_HW_TLS_RX)) { -- rc = -ENOTSUPP; -+ rc = -EOPNOTSUPP; - goto release_netdev; - } - -diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c -index eff444293594..82d0beed8f07 100644 ---- a/net/tls/tls_main.c -+++ b/net/tls/tls_main.c -@@ -482,7 +482,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval, - /* check version */ - if (crypto_info->version != TLS_1_2_VERSION && - crypto_info->version != TLS_1_3_VERSION) { -- rc = -ENOTSUPP; -+ rc = -EINVAL; - goto err_crypto_info; - } - -@@ -778,7 +778,7 @@ static int tls_init(struct sock *sk) - * share the ulp context. - */ - if (sk->sk_state != TCP_ESTABLISHED) -- return -ENOTSUPP; -+ return -ENOTCONN; - - tls_build_proto(sk); - -diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c -index 5dd0f01913c0..c70cf30c5492 100644 ---- a/net/tls/tls_sw.c -+++ b/net/tls/tls_sw.c -@@ -900,7 +900,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) - int ret = 0; - - if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL)) -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - - mutex_lock(&tls_ctx->tx_lock); - lock_sock(sk); -@@ -1215,7 +1215,7 @@ int tls_sw_sendpage_locked(struct sock *sk, struct page *page, - if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | - MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY | - MSG_NO_SHARED_FRAGS)) -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - - return tls_sw_do_sendpage(sk, page, offset, size, flags); - } -@@ -1228,7 +1228,7 @@ int tls_sw_sendpage(struct sock *sk, struct page *page, - - if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | - MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY)) -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - - mutex_lock(&tls_ctx->tx_lock); - lock_sock(sk); -@@ -1927,7 +1927,7 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos, - - /* splice does not support reading control messages */ - if (ctx->control != TLS_RECORD_TYPE_DATA) { -- err = -ENOTSUPP; -+ err = -EINVAL; - goto splice_read_end; - } - -diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c -index 46abcae47dee..13e5ef615026 100644 ---- a/tools/testing/selftests/net/tls.c -+++ b/tools/testing/selftests/net/tls.c -@@ -25,10 +25,6 @@ - #define TLS_PAYLOAD_MAX_LEN 16384 - #define SOL_TLS 282 - --#ifndef ENOTSUPP --#define ENOTSUPP 524 --#endif -- - FIXTURE(tls_basic) - { - int fd, cfd; -@@ -1205,11 +1201,11 @@ TEST(non_established) { - /* TLS ULP not supported */ - if (errno == ENOENT) - return; -- EXPECT_EQ(errno, ENOTSUPP); -+ EXPECT_EQ(errno, ENOTCONN); - - ret = setsockopt(sfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls")); - EXPECT_EQ(ret, -1); -- EXPECT_EQ(errno, ENOTSUPP); -+ EXPECT_EQ(errno, ENOTCONN); - - ret = getsockname(sfd, &addr, &len); - ASSERT_EQ(ret, 0); diff --git a/patch/kernel/odroidxu4-current/patch-5.4.5-6.patch b/patch/kernel/odroidxu4-current/patch-5.4.5-6.patch deleted file mode 100644 index d35757d8b2..0000000000 --- a/patch/kernel/odroidxu4-current/patch-5.4.5-6.patch +++ /dev/null @@ -1,3420 +0,0 @@ -diff --git a/Makefile b/Makefile -index 0f6e72d5e4f1..20ec7c20279e 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 5 - PATCHLEVEL = 4 --SUBLEVEL = 5 -+SUBLEVEL = 6 - EXTRAVERSION = - NAME = Kleptomaniac Octopus - -diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts -index 0e159c884f97..1aeac33b0d34 100644 ---- a/arch/arm/boot/dts/s3c6410-mini6410.dts -+++ b/arch/arm/boot/dts/s3c6410-mini6410.dts -@@ -165,6 +165,10 @@ - }; - }; - -+&clocks { -+ clocks = <&fin_pll>; -+}; -+ - &sdhci0 { - pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; -diff --git a/arch/arm/boot/dts/s3c6410-smdk6410.dts b/arch/arm/boot/dts/s3c6410-smdk6410.dts -index a9a5689dc462..3bf6c450a26e 100644 ---- a/arch/arm/boot/dts/s3c6410-smdk6410.dts -+++ b/arch/arm/boot/dts/s3c6410-smdk6410.dts -@@ -69,6 +69,10 @@ - }; - }; - -+&clocks { -+ clocks = <&fin_pll>; -+}; -+ - &sdhci0 { - pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; -diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S -index 67b763fea005..e3f34815c9da 100644 ---- a/arch/arm/mach-tegra/reset-handler.S -+++ b/arch/arm/mach-tegra/reset-handler.S -@@ -44,16 +44,16 @@ ENTRY(tegra_resume) - cmp r6, #TEGRA20 - beq 1f @ Yes - /* Clear the flow controller flags for this CPU. */ -- cpu_to_csr_reg r1, r0 -+ cpu_to_csr_reg r3, r0 - mov32 r2, TEGRA_FLOW_CTRL_BASE -- ldr r1, [r2, r1] -+ ldr r1, [r2, r3] - /* Clear event & intr flag */ - orr r1, r1, \ - #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG - movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps - @ & ext flags for CPU power mgnt - bic r1, r1, r0 -- str r1, [r2] -+ str r1, [r2, r3] - 1: - - mov32 r9, 0xc09 -diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h -index 359ab40e935a..c90fb944f9d8 100644 ---- a/arch/xtensa/include/asm/syscall.h -+++ b/arch/xtensa/include/asm/syscall.h -@@ -51,7 +51,7 @@ static inline void syscall_set_return_value(struct task_struct *task, - struct pt_regs *regs, - int error, long val) - { -- regs->areg[0] = (long) error ? error : val; -+ regs->areg[2] = (long) error ? error : val; - } - - #define SYSCALL_MAX_ARGS 6 -diff --git a/arch/xtensa/mm/kasan_init.c b/arch/xtensa/mm/kasan_init.c -index af7152560bc3..b771459778fe 100644 ---- a/arch/xtensa/mm/kasan_init.c -+++ b/arch/xtensa/mm/kasan_init.c -@@ -56,7 +56,9 @@ static void __init populate(void *start, void *end) - - for (k = 0; k < PTRS_PER_PTE; ++k, ++j) { - phys_addr_t phys = -- memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); -+ memblock_phys_alloc_range(PAGE_SIZE, PAGE_SIZE, -+ 0, -+ MEMBLOCK_ALLOC_ANYWHERE); - - if (!phys) - panic("Failed to allocate page table page\n"); -diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c -index 59153d0aa890..b43f03620843 100644 ---- a/arch/xtensa/mm/tlb.c -+++ b/arch/xtensa/mm/tlb.c -@@ -216,6 +216,8 @@ static int check_tlb_entry(unsigned w, unsigned e, bool dtlb) - unsigned tlbidx = w | (e << PAGE_SHIFT); - unsigned r0 = dtlb ? - read_dtlb_virtual(tlbidx) : read_itlb_virtual(tlbidx); -+ unsigned r1 = dtlb ? -+ read_dtlb_translation(tlbidx) : read_itlb_translation(tlbidx); - unsigned vpn = (r0 & PAGE_MASK) | (e << PAGE_SHIFT); - unsigned pte = get_pte_for_vaddr(vpn); - unsigned mm_asid = (get_rasid_register() >> 8) & ASID_MASK; -@@ -231,8 +233,6 @@ static int check_tlb_entry(unsigned w, unsigned e, bool dtlb) - } - - if (tlb_asid == mm_asid) { -- unsigned r1 = dtlb ? read_dtlb_translation(tlbidx) : -- read_itlb_translation(tlbidx); - if ((pte ^ r1) & PAGE_MASK) { - pr_err("%cTLB: way: %u, entry: %u, mapping: %08x->%08x, PTE: %08x\n", - dtlb ? 'D' : 'I', w, e, r0, r1, pte); -diff --git a/block/bio.c b/block/bio.c -index b1170ec18464..43df756b68c4 100644 ---- a/block/bio.c -+++ b/block/bio.c -@@ -751,10 +751,12 @@ bool __bio_try_merge_page(struct bio *bio, struct page *page, - if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED))) - return false; - -- if (bio->bi_vcnt > 0 && !bio_full(bio, len)) { -+ if (bio->bi_vcnt > 0) { - struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; - - if (page_is_mergeable(bv, page, len, off, same_page)) { -+ if (bio->bi_iter.bi_size > UINT_MAX - len) -+ return false; - bv->bv_len += len; - bio->bi_iter.bi_size += len; - return true; -diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c -index 25c5c071645b..91185db9a952 100644 ---- a/drivers/dma-buf/sync_file.c -+++ b/drivers/dma-buf/sync_file.c -@@ -221,7 +221,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, - a_fences = get_fences(a, &a_num_fences); - b_fences = get_fences(b, &b_num_fences); - if (a_num_fences > INT_MAX - b_num_fences) -- return NULL; -+ goto err; - - num_fences = a_num_fences + b_num_fences; - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h -index b6e1d98ef01e..aef6c396bd58 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h -@@ -77,6 +77,7 @@ struct amdgpu_gmc_fault { - struct amdgpu_vmhub { - uint32_t ctx0_ptb_addr_lo32; - uint32_t ctx0_ptb_addr_hi32; -+ uint32_t vm_inv_eng0_sem; - uint32_t vm_inv_eng0_req; - uint32_t vm_inv_eng0_ack; - uint32_t vm_context0_cntl; -diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c -index 53090eae0082..596722e79a26 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c -@@ -1785,27 +1785,52 @@ static void gfx_v10_0_enable_gui_idle_interrupt(struct amdgpu_device *adev, - WREG32_SOC15(GC, 0, mmCP_INT_CNTL_RING0, tmp); - } - --static void gfx_v10_0_init_csb(struct amdgpu_device *adev) -+static int gfx_v10_0_init_csb(struct amdgpu_device *adev) - { -+ int r; -+ -+ if (adev->in_gpu_reset) { -+ r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); -+ if (r) -+ return r; -+ -+ r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, -+ (void **)&adev->gfx.rlc.cs_ptr); -+ if (!r) { -+ adev->gfx.rlc.funcs->get_csb_buffer(adev, -+ adev->gfx.rlc.cs_ptr); -+ amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); -+ } -+ -+ amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); -+ if (r) -+ return r; -+ } -+ - /* csib */ - WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_HI, - adev->gfx.rlc.clear_state_gpu_addr >> 32); - WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_LO, - adev->gfx.rlc.clear_state_gpu_addr & 0xfffffffc); - WREG32_SOC15(GC, 0, mmRLC_CSIB_LENGTH, adev->gfx.rlc.clear_state_size); -+ -+ return 0; - } - --static void gfx_v10_0_init_pg(struct amdgpu_device *adev) -+static int gfx_v10_0_init_pg(struct amdgpu_device *adev) - { - int i; -+ int r; - -- gfx_v10_0_init_csb(adev); -+ r = gfx_v10_0_init_csb(adev); -+ if (r) -+ return r; - - for (i = 0; i < adev->num_vmhubs; i++) - amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0); - - /* TODO: init power gating */ -- return; -+ return 0; - } - - void gfx_v10_0_rlc_stop(struct amdgpu_device *adev) -@@ -1907,7 +1932,10 @@ static int gfx_v10_0_rlc_resume(struct amdgpu_device *adev) - r = gfx_v10_0_wait_for_rlc_autoload_complete(adev); - if (r) - return r; -- gfx_v10_0_init_pg(adev); -+ -+ r = gfx_v10_0_init_pg(adev); -+ if (r) -+ return r; - - /* enable RLC SRM */ - gfx_v10_0_rlc_enable_srm(adev); -@@ -1933,7 +1961,10 @@ static int gfx_v10_0_rlc_resume(struct amdgpu_device *adev) - return r; - } - -- gfx_v10_0_init_pg(adev); -+ r = gfx_v10_0_init_pg(adev); -+ if (r) -+ return r; -+ - adev->gfx.rlc.funcs->start(adev); - - if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) { -@@ -2400,7 +2431,7 @@ static int gfx_v10_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev) - return 0; - } - --static void gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) -+static int gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) - { - int i; - u32 tmp = RREG32_SOC15(GC, 0, mmCP_ME_CNTL); -@@ -2413,7 +2444,17 @@ static void gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) - adev->gfx.gfx_ring[i].sched.ready = false; - } - WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp); -- udelay(50); -+ -+ for (i = 0; i < adev->usec_timeout; i++) { -+ if (RREG32_SOC15(GC, 0, mmCP_STAT) == 0) -+ break; -+ udelay(1); -+ } -+ -+ if (i >= adev->usec_timeout) -+ DRM_ERROR("failed to %s cp gfx\n", enable ? "unhalt" : "halt"); -+ -+ return 0; - } - - static int gfx_v10_0_cp_gfx_load_pfp_microcode(struct amdgpu_device *adev) -diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c -index 6ce37ce77d14..d6fbdc6c0548 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c -@@ -365,6 +365,8 @@ void gfxhub_v1_0_init(struct amdgpu_device *adev) - hub->ctx0_ptb_addr_hi32 = - SOC15_REG_OFFSET(GC, 0, - mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); -+ hub->vm_inv_eng0_sem = -+ SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG0_SEM); - hub->vm_inv_eng0_req = - SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG0_REQ); - hub->vm_inv_eng0_ack = -diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c -index db10640a3b2f..fbe06c13a09c 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c -@@ -350,6 +350,8 @@ void gfxhub_v2_0_init(struct amdgpu_device *adev) - hub->ctx0_ptb_addr_hi32 = - SOC15_REG_OFFSET(GC, 0, - mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); -+ hub->vm_inv_eng0_sem = -+ SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_SEM); - hub->vm_inv_eng0_req = - SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_REQ); - hub->vm_inv_eng0_ack = -diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c -index 5c7d5f73f54f..a7ba4c6cf7a1 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c -@@ -235,6 +235,29 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, - const unsigned eng = 17; - unsigned int i; - -+ spin_lock(&adev->gmc.invalidate_lock); -+ /* -+ * It may lose gpuvm invalidate acknowldege state across power-gating -+ * off cycle, add semaphore acquire before invalidation and semaphore -+ * release after invalidation to avoid entering power gated state -+ * to WA the Issue -+ */ -+ -+ /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ -+ if (vmhub == AMDGPU_MMHUB_0 || -+ vmhub == AMDGPU_MMHUB_1) { -+ for (i = 0; i < adev->usec_timeout; i++) { -+ /* a read return value of 1 means semaphore acuqire */ -+ tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng); -+ if (tmp & 0x1) -+ break; -+ udelay(1); -+ } -+ -+ if (i >= adev->usec_timeout) -+ DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); -+ } -+ - WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); - - /* -@@ -254,6 +277,17 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, - udelay(1); - } - -+ /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ -+ if (vmhub == AMDGPU_MMHUB_0 || -+ vmhub == AMDGPU_MMHUB_1) -+ /* -+ * add semaphore release after invalidation, -+ * write with 0 means semaphore release -+ */ -+ WREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng, 0); -+ -+ spin_unlock(&adev->gmc.invalidate_lock); -+ - if (i < adev->usec_timeout) - return; - -@@ -338,6 +372,20 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, - uint32_t req = gmc_v10_0_get_invalidate_req(vmid, 0); - unsigned eng = ring->vm_inv_eng; - -+ /* -+ * It may lose gpuvm invalidate acknowldege state across power-gating -+ * off cycle, add semaphore acquire before invalidation and semaphore -+ * release after invalidation to avoid entering power gated state -+ * to WA the Issue -+ */ -+ -+ /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ -+ if (ring->funcs->vmhub == AMDGPU_MMHUB_0 || -+ ring->funcs->vmhub == AMDGPU_MMHUB_1) -+ /* a read return value of 1 means semaphore acuqire */ -+ amdgpu_ring_emit_reg_wait(ring, -+ hub->vm_inv_eng0_sem + eng, 0x1, 0x1); -+ - amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid), - lower_32_bits(pd_addr)); - -@@ -348,6 +396,15 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, - hub->vm_inv_eng0_ack + eng, - req, 1 << vmid); - -+ /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ -+ if (ring->funcs->vmhub == AMDGPU_MMHUB_0 || -+ ring->funcs->vmhub == AMDGPU_MMHUB_1) -+ /* -+ * add semaphore release after invalidation, -+ * write with 0 means semaphore release -+ */ -+ amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_sem + eng, 0); -+ - return pd_addr; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c -index f91337030dc0..d7caca042173 100644 ---- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c -@@ -448,6 +448,24 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid, - return req; - } - -+/** -+ * gmc_v9_0_use_invalidate_semaphore - judge whether to use semaphore -+ * -+ * @adev: amdgpu_device pointer -+ * @vmhub: vmhub type -+ * -+ */ -+static bool gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev, -+ uint32_t vmhub) -+{ -+ return ((vmhub == AMDGPU_MMHUB_0 || -+ vmhub == AMDGPU_MMHUB_1) && -+ (!amdgpu_sriov_vf(adev)) && -+ (!(adev->asic_type == CHIP_RAVEN && -+ adev->rev_id < 0x8 && -+ adev->pdev->device == 0x15d8))); -+} -+ - /* - * GART - * VMID 0 is the physical GPU addresses as used by the kernel. -@@ -467,6 +485,7 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid, - static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, - uint32_t vmhub, uint32_t flush_type) - { -+ bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub); - const unsigned eng = 17; - u32 j, tmp; - struct amdgpu_vmhub *hub; -@@ -491,6 +510,28 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, - } - - spin_lock(&adev->gmc.invalidate_lock); -+ -+ /* -+ * It may lose gpuvm invalidate acknowldege state across power-gating -+ * off cycle, add semaphore acquire before invalidation and semaphore -+ * release after invalidation to avoid entering power gated state -+ * to WA the Issue -+ */ -+ -+ /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ -+ if (use_semaphore) { -+ for (j = 0; j < adev->usec_timeout; j++) { -+ /* a read return value of 1 means semaphore acuqire */ -+ tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng); -+ if (tmp & 0x1) -+ break; -+ udelay(1); -+ } -+ -+ if (j >= adev->usec_timeout) -+ DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); -+ } -+ - WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); - - /* -@@ -506,7 +547,17 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, - break; - udelay(1); - } -+ -+ /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ -+ if (use_semaphore) -+ /* -+ * add semaphore release after invalidation, -+ * write with 0 means semaphore release -+ */ -+ WREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng, 0); -+ - spin_unlock(&adev->gmc.invalidate_lock); -+ - if (j < adev->usec_timeout) - return; - -@@ -516,11 +567,25 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, - static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, - unsigned vmid, uint64_t pd_addr) - { -+ bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(ring->adev, ring->funcs->vmhub); - struct amdgpu_device *adev = ring->adev; - struct amdgpu_vmhub *hub = &adev->vmhub[ring->funcs->vmhub]; - uint32_t req = gmc_v9_0_get_invalidate_req(vmid, 0); - unsigned eng = ring->vm_inv_eng; - -+ /* -+ * It may lose gpuvm invalidate acknowldege state across power-gating -+ * off cycle, add semaphore acquire before invalidation and semaphore -+ * release after invalidation to avoid entering power gated state -+ * to WA the Issue -+ */ -+ -+ /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ -+ if (use_semaphore) -+ /* a read return value of 1 means semaphore acuqire */ -+ amdgpu_ring_emit_reg_wait(ring, -+ hub->vm_inv_eng0_sem + eng, 0x1, 0x1); -+ - amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid), - lower_32_bits(pd_addr)); - -@@ -531,6 +596,14 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, - hub->vm_inv_eng0_ack + eng, - req, 1 << vmid); - -+ /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ -+ if (use_semaphore) -+ /* -+ * add semaphore release after invalidation, -+ * write with 0 means semaphore release -+ */ -+ amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_sem + eng, 0); -+ - return pd_addr; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c -index 04cd4b6f95d4..641f1258f08d 100644 ---- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c -@@ -418,6 +418,8 @@ void mmhub_v1_0_init(struct amdgpu_device *adev) - hub->ctx0_ptb_addr_hi32 = - SOC15_REG_OFFSET(MMHUB, 0, - mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); -+ hub->vm_inv_eng0_sem = -+ SOC15_REG_OFFSET(MMHUB, 0, mmVM_INVALIDATE_ENG0_SEM); - hub->vm_inv_eng0_req = - SOC15_REG_OFFSET(MMHUB, 0, mmVM_INVALIDATE_ENG0_REQ); - hub->vm_inv_eng0_ack = -diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c -index b39bea6f54e9..096bb883c29d 100644 ---- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c -+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c -@@ -341,6 +341,8 @@ void mmhub_v2_0_init(struct amdgpu_device *adev) - hub->ctx0_ptb_addr_hi32 = - SOC15_REG_OFFSET(MMHUB, 0, - mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); -+ hub->vm_inv_eng0_sem = -+ SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_SEM); - hub->vm_inv_eng0_req = - SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_REQ); - hub->vm_inv_eng0_ack = -diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c -index 9ed178fa241c..fb161c83e409 100644 ---- a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c -+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c -@@ -502,6 +502,10 @@ void mmhub_v9_4_init(struct amdgpu_device *adev) - SOC15_REG_OFFSET(MMHUB, 0, - mmVML2VC0_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32) + - i * MMHUB_INSTANCE_REGISTER_OFFSET; -+ hub[i]->vm_inv_eng0_sem = -+ SOC15_REG_OFFSET(MMHUB, 0, -+ mmVML2VC0_VM_INVALIDATE_ENG0_SEM) + -+ i * MMHUB_INSTANCE_REGISTER_OFFSET; - hub[i]->vm_inv_eng0_req = - SOC15_REG_OFFSET(MMHUB, 0, - mmVML2VC0_VM_INVALIDATE_ENG0_REQ) + -diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.h b/drivers/gpu/drm/amd/amdgpu/soc15.h -index a3dde0c31f57..a1d4ea69a284 100644 ---- a/drivers/gpu/drm/amd/amdgpu/soc15.h -+++ b/drivers/gpu/drm/amd/amdgpu/soc15.h -@@ -28,8 +28,8 @@ - #include "nbio_v7_0.h" - #include "nbio_v7_4.h" - --#define SOC15_FLUSH_GPU_TLB_NUM_WREG 4 --#define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 1 -+#define SOC15_FLUSH_GPU_TLB_NUM_WREG 6 -+#define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 3 - - extern const struct amd_ip_funcs soc15_common_ip_funcs; - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c -index f4cfa0caeba8..785322cd4c6c 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c -@@ -342,7 +342,8 @@ bool dm_pp_get_clock_levels_by_type( - if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) { - if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle, - dc_to_pp_clock_type(clk_type), &pp_clks)) { -- /* Error in pplib. Provide default values. */ -+ /* Error in pplib. Provide default values. */ -+ get_default_clock_levels(clk_type, dc_clks); - return true; - } - } else if (adev->smu.funcs && adev->smu.funcs->get_clock_by_type) { -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 1212da12c414..b3ae1c41fc69 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -@@ -1103,6 +1103,25 @@ void dcn20_pipe_control_lock( - if (pipe->plane_state != NULL) - flip_immediate = pipe->plane_state->flip_immediate; - -+ if (flip_immediate && lock) { -+ const int TIMEOUT_FOR_FLIP_PENDING = 100000; -+ int i; -+ -+ for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { -+ if (!pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->plane_res.hubp)) -+ break; -+ udelay(1); -+ } -+ -+ if (pipe->bottom_pipe != NULL) { -+ for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { -+ if (!pipe->bottom_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->bottom_pipe->plane_res.hubp)) -+ break; -+ udelay(1); -+ } -+ } -+ } -+ - /* In flip immediate and pipe splitting case, we need to use GSL - * for synchronization. Only do setup on locking and on flip type change. - */ -diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c -index 82add736e17d..86c17896b532 100644 ---- a/drivers/gpu/drm/drm_dp_mst_topology.c -+++ b/drivers/gpu/drm/drm_dp_mst_topology.c -@@ -2465,9 +2465,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) - drm_dp_mst_topology_put_port(port); - } - -- for (i = 0; i < mgr->max_payloads; i++) { -- if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) -+ for (i = 0; i < mgr->max_payloads; /* do nothing */) { -+ if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) { -+ i++; - continue; -+ } - - DRM_DEBUG_KMS("removing payload %d\n", i); - for (j = i; j < mgr->max_payloads - 1; j++) { -diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c -index 16ed44bfd734..07a038f21619 100644 ---- a/drivers/gpu/drm/i915/display/intel_fbc.c -+++ b/drivers/gpu/drm/i915/display/intel_fbc.c -@@ -1284,7 +1284,7 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv) - return 0; - - /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */ -- if (IS_GEMINILAKE(dev_priv)) -+ if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) - return 0; - - if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) -diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c -index e753b1e706e2..fc29a3705354 100644 ---- a/drivers/gpu/drm/i915/gvt/cmd_parser.c -+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c -@@ -1597,9 +1597,9 @@ static int cmd_handler_mi_op_2f(struct parser_exec_state *s) - if (!(cmd_val(s, 0) & (1 << 22))) - return ret; - -- /* check if QWORD */ -- if (DWORD_FIELD(0, 20, 19) == 1) -- valid_len += 8; -+ /* check inline data */ -+ if (cmd_val(s, 0) & BIT(18)) -+ valid_len = CMD_LEN(9); - ret = gvt_check_valid_cmd_length(cmd_length(s), - valid_len); - if (ret) -diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c -index 9ab27aecfcf3..1bd6b6d15ffb 100644 ---- a/drivers/gpu/drm/meson/meson_venc_cvbs.c -+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c -@@ -64,6 +64,25 @@ struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = { - }, - }; - -+static const struct meson_cvbs_mode * -+meson_cvbs_get_mode(const struct drm_display_mode *req_mode) -+{ -+ int i; -+ -+ for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { -+ struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; -+ -+ if (drm_mode_match(req_mode, &meson_mode->mode, -+ DRM_MODE_MATCH_TIMINGS | -+ DRM_MODE_MATCH_CLOCK | -+ DRM_MODE_MATCH_FLAGS | -+ DRM_MODE_MATCH_3D_FLAGS)) -+ return meson_mode; -+ } -+ -+ return NULL; -+} -+ - /* Connector */ - - static void meson_cvbs_connector_destroy(struct drm_connector *connector) -@@ -136,14 +155,8 @@ static int meson_venc_cvbs_encoder_atomic_check(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) - { -- int i; -- -- for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { -- struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; -- -- if (drm_mode_equal(&crtc_state->mode, &meson_mode->mode)) -- return 0; -- } -+ if (meson_cvbs_get_mode(&crtc_state->mode)) -+ return 0; - - return -EINVAL; - } -@@ -191,24 +204,17 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) - { -+ const struct meson_cvbs_mode *meson_mode = meson_cvbs_get_mode(mode); - struct meson_venc_cvbs *meson_venc_cvbs = - encoder_to_meson_venc_cvbs(encoder); - struct meson_drm *priv = meson_venc_cvbs->priv; -- int i; - -- for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { -- struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; -+ if (meson_mode) { -+ meson_venci_cvbs_mode_set(priv, meson_mode->enci); - -- if (drm_mode_equal(mode, &meson_mode->mode)) { -- meson_venci_cvbs_mode_set(priv, -- meson_mode->enci); -- -- /* Setup 27MHz vclk2 for ENCI and VDAC */ -- meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, -- MESON_VCLK_CVBS, MESON_VCLK_CVBS, -- MESON_VCLK_CVBS, true); -- break; -- } -+ /* Setup 27MHz vclk2 for ENCI and VDAC */ -+ meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS, -+ MESON_VCLK_CVBS, MESON_VCLK_CVBS, true); - } - } - -diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c -index afd9119b6cf1..c96c4393b124 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_drv.c -+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c -@@ -30,7 +30,8 @@ module_param_named(modeset, mgag200_modeset, int, 0400); - static struct drm_driver driver; - - static const struct pci_device_id pciidlist[] = { -- { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A }, -+ { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, -+ G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD}, - { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B }, - { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV }, - { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB }, -@@ -63,6 +64,35 @@ static const struct file_operations mgag200_driver_fops = { - DRM_VRAM_MM_FILE_OPERATIONS - }; - -+static bool mgag200_pin_bo_at_0(const struct mga_device *mdev) -+{ -+ return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD; -+} -+ -+int mgag200_driver_dumb_create(struct drm_file *file, -+ struct drm_device *dev, -+ struct drm_mode_create_dumb *args) -+{ -+ struct mga_device *mdev = dev->dev_private; -+ unsigned long pg_align; -+ -+ if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) -+ return -EINVAL; -+ -+ pg_align = 0ul; -+ -+ /* -+ * Aligning scanout buffers to the size of the video ram forces -+ * placement at offset 0. Works around a bug where HW does not -+ * respect 'startadd' field. -+ */ -+ if (mgag200_pin_bo_at_0(mdev)) -+ pg_align = PFN_UP(mdev->mc.vram_size); -+ -+ return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, -+ pg_align, false, args); -+} -+ - static struct drm_driver driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET, - .load = mgag200_driver_load, -@@ -74,7 +104,9 @@ static struct drm_driver driver = { - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -- DRM_GEM_VRAM_DRIVER -+ .dumb_create = mgag200_driver_dumb_create, -+ .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, -+ .gem_prime_mmap = drm_gem_prime_mmap, - }; - - static struct pci_driver mgag200_pci_driver = { -diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h -index 1c93f8dc08c7..7cc1a242df5f 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_drv.h -+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h -@@ -159,6 +159,12 @@ enum mga_type { - G200_EW3, - }; - -+/* HW does not handle 'startadd' field correct. */ -+#define MGAG200_FLAG_HW_BUG_NO_STARTADD (1ul << 8) -+ -+#define MGAG200_TYPE_MASK (0x000000ff) -+#define MGAG200_FLAG_MASK (0x00ffff00) -+ - #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) - - struct mga_device { -@@ -188,6 +194,18 @@ struct mga_device { - u32 unique_rev_id; - }; - -+static inline enum mga_type -+mgag200_type_from_driver_data(kernel_ulong_t driver_data) -+{ -+ return (enum mga_type)(driver_data & MGAG200_TYPE_MASK); -+} -+ -+static inline unsigned long -+mgag200_flags_from_driver_data(kernel_ulong_t driver_data) -+{ -+ return driver_data & MGAG200_FLAG_MASK; -+} -+ - /* mgag200_mode.c */ - int mgag200_modeset_init(struct mga_device *mdev); - void mgag200_modeset_fini(struct mga_device *mdev); -diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c -index a9773334dedf..388212b2d63f 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_main.c -+++ b/drivers/gpu/drm/mgag200/mgag200_main.c -@@ -94,7 +94,8 @@ static int mgag200_device_init(struct drm_device *dev, - struct mga_device *mdev = dev->dev_private; - int ret, option; - -- mdev->type = flags; -+ mdev->flags = mgag200_flags_from_driver_data(flags); -+ mdev->type = mgag200_type_from_driver_data(flags); - - /* Hardcode the number of CRTCs to 1 */ - mdev->num_crtc = 1; -diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h -index 43df86c38f58..24f7700768da 100644 ---- a/drivers/gpu/drm/nouveau/dispnv50/atom.h -+++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h -@@ -114,6 +114,7 @@ struct nv50_head_atom { - u8 nhsync:1; - u8 nvsync:1; - u8 depth:4; -+ u8 bpc; - } or; - - /* Currently only used for MST */ -diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c -index b46be8a091e9..b5b1a34f896f 100644 ---- a/drivers/gpu/drm/nouveau/dispnv50/disp.c -+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c -@@ -353,10 +353,20 @@ nv50_outp_atomic_check(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) - { -- struct nouveau_connector *nv_connector = -- nouveau_connector(conn_state->connector); -- return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, -- nv_connector->native_mode); -+ struct drm_connector *connector = conn_state->connector; -+ struct nouveau_connector *nv_connector = nouveau_connector(connector); -+ struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); -+ int ret; -+ -+ ret = nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, -+ nv_connector->native_mode); -+ if (ret) -+ return ret; -+ -+ if (crtc_state->mode_changed || crtc_state->connectors_changed) -+ asyh->or.bpc = connector->display_info.bpc; -+ -+ return 0; - } - - /****************************************************************************** -@@ -770,32 +780,54 @@ nv50_msto_atomic_check(struct drm_encoder *encoder, - struct nv50_mstm *mstm = mstc->mstm; - struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); - int slots; -+ int ret; -+ -+ ret = nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, -+ mstc->native); -+ if (ret) -+ return ret; -+ -+ if (!crtc_state->mode_changed && !crtc_state->connectors_changed) -+ return 0; -+ -+ /* -+ * When restoring duplicated states, we need to make sure that the bw -+ * remains the same and avoid recalculating it, as the connector's bpc -+ * may have changed after the state was duplicated -+ */ -+ if (!state->duplicated) { -+ const int clock = crtc_state->adjusted_mode.clock; - -- if (crtc_state->mode_changed || crtc_state->connectors_changed) { - /* -- * When restoring duplicated states, we need to make sure that -- * the bw remains the same and avoid recalculating it, as the -- * connector's bpc may have changed after the state was -- * duplicated -+ * XXX: Since we don't use HDR in userspace quite yet, limit -+ * the bpc to 8 to save bandwidth on the topology. In the -+ * future, we'll want to properly fix this by dynamically -+ * selecting the highest possible bpc that would fit in the -+ * topology - */ -- if (!state->duplicated) { -- const int bpp = connector->display_info.bpc * 3; -- const int clock = crtc_state->adjusted_mode.clock; -+ asyh->or.bpc = min(connector->display_info.bpc, 8U); -+ asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3); -+ } - -- asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, bpp); -- } -+ slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, mstc->port, -+ asyh->dp.pbn); -+ if (slots < 0) -+ return slots; - -- slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, -- mstc->port, -- asyh->dp.pbn); -- if (slots < 0) -- return slots; -+ asyh->dp.tu = slots; - -- asyh->dp.tu = slots; -- } -+ return 0; -+} - -- return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, -- mstc->native); -+static u8 -+nv50_dp_bpc_to_depth(unsigned int bpc) -+{ -+ switch (bpc) { -+ case 6: return 0x2; -+ case 8: return 0x5; -+ case 10: /* fall-through */ -+ default: return 0x6; -+ } - } - - static void -@@ -808,7 +840,7 @@ nv50_msto_enable(struct drm_encoder *encoder) - struct nv50_mstm *mstm = NULL; - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; -- u8 proto, depth; -+ u8 proto; - bool r; - - drm_connector_list_iter_begin(encoder->dev, &conn_iter); -@@ -837,14 +869,8 @@ nv50_msto_enable(struct drm_encoder *encoder) - else - proto = 0x9; - -- switch (mstc->connector.display_info.bpc) { -- case 6: depth = 0x2; break; -- case 8: depth = 0x5; break; -- case 10: -- default: depth = 0x6; break; -- } -- -- mstm->outp->update(mstm->outp, head->base.index, armh, proto, depth); -+ mstm->outp->update(mstm->outp, head->base.index, armh, proto, -+ nv50_dp_bpc_to_depth(armh->or.bpc)); - - msto->head = head; - msto->mstc = mstc; -@@ -1498,20 +1524,14 @@ nv50_sor_enable(struct drm_encoder *encoder) - lvds.lvds.script |= 0x0200; - } - -- if (nv_connector->base.display_info.bpc == 8) -+ if (asyh->or.bpc == 8) - lvds.lvds.script |= 0x0200; - } - - nvif_mthd(&disp->disp->object, 0, &lvds, sizeof(lvds)); - break; - case DCB_OUTPUT_DP: -- if (nv_connector->base.display_info.bpc == 6) -- depth = 0x2; -- else -- if (nv_connector->base.display_info.bpc == 8) -- depth = 0x5; -- else -- depth = 0x6; -+ depth = nv50_dp_bpc_to_depth(asyh->or.bpc); - - if (nv_encoder->link & 1) - proto = 0x8; -@@ -1662,7 +1682,7 @@ nv50_pior_enable(struct drm_encoder *encoder) - nv50_outp_acquire(nv_encoder); - - nv_connector = nouveau_encoder_connector_get(nv_encoder); -- switch (nv_connector->base.display_info.bpc) { -+ switch (asyh->or.bpc) { - case 10: asyh->or.depth = 0x6; break; - case 8: asyh->or.depth = 0x5; break; - case 6: asyh->or.depth = 0x2; break; -diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c -index 71c23bf1fe25..c9692df2b76c 100644 ---- a/drivers/gpu/drm/nouveau/dispnv50/head.c -+++ b/drivers/gpu/drm/nouveau/dispnv50/head.c -@@ -81,18 +81,17 @@ nv50_head_atomic_check_dither(struct nv50_head_atom *armh, - struct nv50_head_atom *asyh, - struct nouveau_conn_atom *asyc) - { -- struct drm_connector *connector = asyc->state.connector; - u32 mode = 0x00; - - if (asyc->dither.mode == DITHERING_MODE_AUTO) { -- if (asyh->base.depth > connector->display_info.bpc * 3) -+ if (asyh->base.depth > asyh->or.bpc * 3) - mode = DITHERING_MODE_DYNAMIC2X2; - } else { - mode = asyc->dither.mode; - } - - if (asyc->dither.depth == DITHERING_DEPTH_AUTO) { -- if (connector->display_info.bpc >= 8) -+ if (asyh->or.bpc >= 8) - mode |= DITHERING_DEPTH_8BPC; - } else { - mode |= asyc->dither.depth; -diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c -index bdf91b75328e..1c67ac434e10 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_drv.c -+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c -@@ -303,14 +303,17 @@ static int panfrost_ioctl_mmap_bo(struct drm_device *dev, void *data, - } - - /* Don't allow mmapping of heap objects as pages are not pinned. */ -- if (to_panfrost_bo(gem_obj)->is_heap) -- return -EINVAL; -+ if (to_panfrost_bo(gem_obj)->is_heap) { -+ ret = -EINVAL; -+ goto out; -+ } - - ret = drm_gem_create_mmap_offset(gem_obj); - if (ret == 0) - args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); -- drm_gem_object_put_unlocked(gem_obj); - -+out: -+ drm_gem_object_put_unlocked(gem_obj); - return ret; - } - -@@ -347,20 +350,19 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, - return -ENOENT; - } - -+ mutex_lock(&pfdev->shrinker_lock); - args->retained = drm_gem_shmem_madvise(gem_obj, args->madv); - - if (args->retained) { - struct panfrost_gem_object *bo = to_panfrost_bo(gem_obj); - -- mutex_lock(&pfdev->shrinker_lock); -- - if (args->madv == PANFROST_MADV_DONTNEED) -- list_add_tail(&bo->base.madv_list, &pfdev->shrinker_list); -+ list_add_tail(&bo->base.madv_list, -+ &pfdev->shrinker_list); - else if (args->madv == PANFROST_MADV_WILLNEED) - list_del_init(&bo->base.madv_list); -- -- mutex_unlock(&pfdev->shrinker_lock); - } -+ mutex_unlock(&pfdev->shrinker_lock); - - drm_gem_object_put_unlocked(gem_obj); - return 0; -diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c -index bc3ff22e5e85..92a95210a899 100644 ---- a/drivers/gpu/drm/panfrost/panfrost_gem.c -+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c -@@ -19,6 +19,16 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) - struct panfrost_gem_object *bo = to_panfrost_bo(obj); - struct panfrost_device *pfdev = obj->dev->dev_private; - -+ /* -+ * Make sure the BO is no longer inserted in the shrinker list before -+ * taking care of the destruction itself. If we don't do that we have a -+ * race condition between this function and what's done in -+ * panfrost_gem_shrinker_scan(). -+ */ -+ mutex_lock(&pfdev->shrinker_lock); -+ list_del_init(&bo->base.madv_list); -+ mutex_unlock(&pfdev->shrinker_lock); -+ - if (bo->sgts) { - int i; - int n_sgt = bo->base.base.size / SZ_2M; -@@ -33,11 +43,6 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) - kfree(bo->sgts); - } - -- mutex_lock(&pfdev->shrinker_lock); -- if (!list_empty(&bo->base.madv_list)) -- list_del(&bo->base.madv_list); -- mutex_unlock(&pfdev->shrinker_lock); -- - drm_gem_shmem_free_object(obj); - } - -diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c -index 7089dfc8c2a9..110fb38004b1 100644 ---- a/drivers/gpu/drm/radeon/r100.c -+++ b/drivers/gpu/drm/radeon/r100.c -@@ -1826,8 +1826,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, - track->textures[i].use_pitch = 1; - } else { - track->textures[i].use_pitch = 0; -- track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); -- track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); -+ track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT); -+ track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT); - } - if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) - track->textures[i].tex_coord_type = 2; -diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c -index 840401413c58..f5f2ffea5ab2 100644 ---- a/drivers/gpu/drm/radeon/r200.c -+++ b/drivers/gpu/drm/radeon/r200.c -@@ -476,8 +476,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, - track->textures[i].use_pitch = 1; - } else { - track->textures[i].use_pitch = 0; -- track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); -- track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); -+ track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT); -+ track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT); - } - if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) - track->textures[i].lookup_disable = true; -diff --git a/drivers/md/dm-clone-metadata.c b/drivers/md/dm-clone-metadata.c -index 6bc8c1d1c351..54e4fdd607e1 100644 ---- a/drivers/md/dm-clone-metadata.c -+++ b/drivers/md/dm-clone-metadata.c -@@ -67,23 +67,34 @@ struct superblock_disk { - * To save constantly doing look ups on disk we keep an in core copy of the - * on-disk bitmap, the region_map. - * -- * To further reduce metadata I/O overhead we use a second bitmap, the dmap -- * (dirty bitmap), which tracks the dirty words, i.e. longs, of the region_map. -+ * In order to track which regions are hydrated during a metadata transaction, -+ * we use a second set of bitmaps, the dmap (dirty bitmap), which includes two -+ * bitmaps, namely dirty_regions and dirty_words. The dirty_regions bitmap -+ * tracks the regions that got hydrated during the current metadata -+ * transaction. The dirty_words bitmap tracks the dirty words, i.e. longs, of -+ * the dirty_regions bitmap. -+ * -+ * This allows us to precisely track the regions that were hydrated during the -+ * current metadata transaction and update the metadata accordingly, when we -+ * commit the current transaction. This is important because dm-clone should -+ * only commit the metadata of regions that were properly flushed to the -+ * destination device beforehand. Otherwise, in case of a crash, we could end -+ * up with a corrupted dm-clone device. - * - * When a region finishes hydrating dm-clone calls - * dm_clone_set_region_hydrated(), or for discard requests - * dm_clone_cond_set_range(), which sets the corresponding bits in region_map - * and dmap. - * -- * During a metadata commit we scan the dmap for dirty region_map words (longs) -- * and update accordingly the on-disk metadata. Thus, we don't have to flush to -- * disk the whole region_map. We can just flush the dirty region_map words. -+ * During a metadata commit we scan dmap->dirty_words and dmap->dirty_regions -+ * and update the on-disk metadata accordingly. Thus, we don't have to flush to -+ * disk the whole region_map. We can just flush the dirty region_map bits. - * -- * We use a dirty bitmap, which is smaller than the original region_map, to -- * reduce the amount of memory accesses during a metadata commit. As dm-bitset -- * accesses the on-disk bitmap in 64-bit word granularity, there is no -- * significant benefit in tracking the dirty region_map bits with a smaller -- * granularity. -+ * We use the helper dmap->dirty_words bitmap, which is smaller than the -+ * original region_map, to reduce the amount of memory accesses during a -+ * metadata commit. Moreover, as dm-bitset also accesses the on-disk bitmap in -+ * 64-bit word granularity, the dirty_words bitmap helps us avoid useless disk -+ * accesses. - * - * We could update directly the on-disk bitmap, when dm-clone calls either - * dm_clone_set_region_hydrated() or dm_clone_cond_set_range(), buts this -@@ -92,12 +103,13 @@ struct superblock_disk { - * e.g., in a hooked overwrite bio's completion routine, and further reduce the - * I/O completion latency. - * -- * We maintain two dirty bitmaps. During a metadata commit we atomically swap -- * the currently used dmap with the unused one. This allows the metadata update -- * functions to run concurrently with an ongoing commit. -+ * We maintain two dirty bitmap sets. During a metadata commit we atomically -+ * swap the currently used dmap with the unused one. This allows the metadata -+ * update functions to run concurrently with an ongoing commit. - */ - struct dirty_map { - unsigned long *dirty_words; -+ unsigned long *dirty_regions; - unsigned int changed; - }; - -@@ -115,6 +127,9 @@ struct dm_clone_metadata { - struct dirty_map dmap[2]; - struct dirty_map *current_dmap; - -+ /* Protected by lock */ -+ struct dirty_map *committing_dmap; -+ - /* - * In core copy of the on-disk bitmap to save constantly doing look ups - * on disk. -@@ -461,34 +476,53 @@ static size_t bitmap_size(unsigned long nr_bits) - return BITS_TO_LONGS(nr_bits) * sizeof(long); - } - --static int dirty_map_init(struct dm_clone_metadata *cmd) -+static int __dirty_map_init(struct dirty_map *dmap, unsigned long nr_words, -+ unsigned long nr_regions) - { -- cmd->dmap[0].changed = 0; -- cmd->dmap[0].dirty_words = kvzalloc(bitmap_size(cmd->nr_words), GFP_KERNEL); -+ dmap->changed = 0; - -- if (!cmd->dmap[0].dirty_words) { -- DMERR("Failed to allocate dirty bitmap"); -+ dmap->dirty_words = kvzalloc(bitmap_size(nr_words), GFP_KERNEL); -+ if (!dmap->dirty_words) -+ return -ENOMEM; -+ -+ dmap->dirty_regions = kvzalloc(bitmap_size(nr_regions), GFP_KERNEL); -+ if (!dmap->dirty_regions) { -+ kvfree(dmap->dirty_words); - return -ENOMEM; - } - -- cmd->dmap[1].changed = 0; -- cmd->dmap[1].dirty_words = kvzalloc(bitmap_size(cmd->nr_words), GFP_KERNEL); -+ return 0; -+} -+ -+static void __dirty_map_exit(struct dirty_map *dmap) -+{ -+ kvfree(dmap->dirty_words); -+ kvfree(dmap->dirty_regions); -+} -+ -+static int dirty_map_init(struct dm_clone_metadata *cmd) -+{ -+ if (__dirty_map_init(&cmd->dmap[0], cmd->nr_words, cmd->nr_regions)) { -+ DMERR("Failed to allocate dirty bitmap"); -+ return -ENOMEM; -+ } - -- if (!cmd->dmap[1].dirty_words) { -+ if (__dirty_map_init(&cmd->dmap[1], cmd->nr_words, cmd->nr_regions)) { - DMERR("Failed to allocate dirty bitmap"); -- kvfree(cmd->dmap[0].dirty_words); -+ __dirty_map_exit(&cmd->dmap[0]); - return -ENOMEM; - } - - cmd->current_dmap = &cmd->dmap[0]; -+ cmd->committing_dmap = NULL; - - return 0; - } - - static void dirty_map_exit(struct dm_clone_metadata *cmd) - { -- kvfree(cmd->dmap[0].dirty_words); -- kvfree(cmd->dmap[1].dirty_words); -+ __dirty_map_exit(&cmd->dmap[0]); -+ __dirty_map_exit(&cmd->dmap[1]); - } - - static int __load_bitset_in_core(struct dm_clone_metadata *cmd) -@@ -633,21 +667,23 @@ unsigned long dm_clone_find_next_unhydrated_region(struct dm_clone_metadata *cmd - return find_next_zero_bit(cmd->region_map, cmd->nr_regions, start); - } - --static int __update_metadata_word(struct dm_clone_metadata *cmd, unsigned long word) -+static int __update_metadata_word(struct dm_clone_metadata *cmd, -+ unsigned long *dirty_regions, -+ unsigned long word) - { - int r; - unsigned long index = word * BITS_PER_LONG; - unsigned long max_index = min(cmd->nr_regions, (word + 1) * BITS_PER_LONG); - - while (index < max_index) { -- if (test_bit(index, cmd->region_map)) { -+ if (test_bit(index, dirty_regions)) { - r = dm_bitset_set_bit(&cmd->bitset_info, cmd->bitset_root, - index, &cmd->bitset_root); -- - if (r) { - DMERR("dm_bitset_set_bit failed"); - return r; - } -+ __clear_bit(index, dirty_regions); - } - index++; - } -@@ -721,7 +757,7 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap) - if (word == cmd->nr_words) - break; - -- r = __update_metadata_word(cmd, word); -+ r = __update_metadata_word(cmd, dmap->dirty_regions, word); - - if (r) - return r; -@@ -743,16 +779,18 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap) - return 0; - } - --int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) -+int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd) - { -- int r = -EPERM; -+ int r = 0; - unsigned long flags; - struct dirty_map *dmap, *next_dmap; - - down_write(&cmd->lock); - -- if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) -+ if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { -+ r = -EPERM; - goto out; -+ } - - /* Get current dirty bitmap */ - dmap = cmd->current_dmap; -@@ -764,7 +802,7 @@ int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) - * The last commit failed, so we don't have a clean dirty-bitmap to - * use. - */ -- if (WARN_ON(next_dmap->changed)) { -+ if (WARN_ON(next_dmap->changed || cmd->committing_dmap)) { - r = -EINVAL; - goto out; - } -@@ -774,11 +812,33 @@ int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) - cmd->current_dmap = next_dmap; - spin_unlock_irqrestore(&cmd->bitmap_lock, flags); - -- /* -- * No one is accessing the old dirty bitmap anymore, so we can flush -- * it. -- */ -- r = __flush_dmap(cmd, dmap); -+ /* Set old dirty bitmap as currently committing */ -+ cmd->committing_dmap = dmap; -+out: -+ up_write(&cmd->lock); -+ -+ return r; -+} -+ -+int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) -+{ -+ int r = -EPERM; -+ -+ down_write(&cmd->lock); -+ -+ if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) -+ goto out; -+ -+ if (WARN_ON(!cmd->committing_dmap)) { -+ r = -EINVAL; -+ goto out; -+ } -+ -+ r = __flush_dmap(cmd, cmd->committing_dmap); -+ if (!r) { -+ /* Clear committing dmap */ -+ cmd->committing_dmap = NULL; -+ } - out: - up_write(&cmd->lock); - -@@ -803,6 +863,7 @@ int dm_clone_set_region_hydrated(struct dm_clone_metadata *cmd, unsigned long re - dmap = cmd->current_dmap; - - __set_bit(word, dmap->dirty_words); -+ __set_bit(region_nr, dmap->dirty_regions); - __set_bit(region_nr, cmd->region_map); - dmap->changed = 1; - -@@ -831,6 +892,7 @@ int dm_clone_cond_set_range(struct dm_clone_metadata *cmd, unsigned long start, - if (!test_bit(region_nr, cmd->region_map)) { - word = region_nr / BITS_PER_LONG; - __set_bit(word, dmap->dirty_words); -+ __set_bit(region_nr, dmap->dirty_regions); - __set_bit(region_nr, cmd->region_map); - dmap->changed = 1; - } -diff --git a/drivers/md/dm-clone-metadata.h b/drivers/md/dm-clone-metadata.h -index 434bff08508b..c7848c49aef8 100644 ---- a/drivers/md/dm-clone-metadata.h -+++ b/drivers/md/dm-clone-metadata.h -@@ -73,7 +73,23 @@ void dm_clone_metadata_close(struct dm_clone_metadata *cmd); - - /* - * Commit dm-clone metadata to disk. -+ * -+ * We use a two phase commit: -+ * -+ * 1. dm_clone_metadata_pre_commit(): Prepare the current transaction for -+ * committing. After this is called, all subsequent metadata updates, done -+ * through either dm_clone_set_region_hydrated() or -+ * dm_clone_cond_set_range(), will be part of the **next** transaction. -+ * -+ * 2. dm_clone_metadata_commit(): Actually commit the current transaction to -+ * disk and start a new transaction. -+ * -+ * This allows dm-clone to flush the destination device after step (1) to -+ * ensure that all freshly hydrated regions, for which we are updating the -+ * metadata, are properly written to non-volatile storage and won't be lost in -+ * case of a crash. - */ -+int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd); - int dm_clone_metadata_commit(struct dm_clone_metadata *cmd); - - /* -@@ -110,6 +126,7 @@ int dm_clone_metadata_abort(struct dm_clone_metadata *cmd); - * Switches metadata to a read only mode. Once read-only mode has been entered - * the following functions will return -EPERM: - * -+ * dm_clone_metadata_pre_commit() - * dm_clone_metadata_commit() - * dm_clone_set_region_hydrated() - * dm_clone_cond_set_range() -diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c -index 4ca8f1977222..e6e5d24a79f5 100644 ---- a/drivers/md/dm-clone-target.c -+++ b/drivers/md/dm-clone-target.c -@@ -86,6 +86,12 @@ struct clone { - - struct dm_clone_metadata *cmd; - -+ /* -+ * bio used to flush the destination device, before committing the -+ * metadata. -+ */ -+ struct bio flush_bio; -+ - /* Region hydration hash table */ - struct hash_table_bucket *ht; - -@@ -1106,10 +1112,13 @@ static bool need_commit_due_to_time(struct clone *clone) - /* - * A non-zero return indicates read-only or fail mode. - */ --static int commit_metadata(struct clone *clone) -+static int commit_metadata(struct clone *clone, bool *dest_dev_flushed) - { - int r = 0; - -+ if (dest_dev_flushed) -+ *dest_dev_flushed = false; -+ - mutex_lock(&clone->commit_lock); - - if (!dm_clone_changed_this_transaction(clone->cmd)) -@@ -1120,8 +1129,26 @@ static int commit_metadata(struct clone *clone) - goto out; - } - -- r = dm_clone_metadata_commit(clone->cmd); -+ r = dm_clone_metadata_pre_commit(clone->cmd); -+ if (unlikely(r)) { -+ __metadata_operation_failed(clone, "dm_clone_metadata_pre_commit", r); -+ goto out; -+ } - -+ bio_reset(&clone->flush_bio); -+ bio_set_dev(&clone->flush_bio, clone->dest_dev->bdev); -+ clone->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; -+ -+ r = submit_bio_wait(&clone->flush_bio); -+ if (unlikely(r)) { -+ __metadata_operation_failed(clone, "flush destination device", r); -+ goto out; -+ } -+ -+ if (dest_dev_flushed) -+ *dest_dev_flushed = true; -+ -+ r = dm_clone_metadata_commit(clone->cmd); - if (unlikely(r)) { - __metadata_operation_failed(clone, "dm_clone_metadata_commit", r); - goto out; -@@ -1194,6 +1221,7 @@ static void process_deferred_flush_bios(struct clone *clone) - { - struct bio *bio; - unsigned long flags; -+ bool dest_dev_flushed; - struct bio_list bios = BIO_EMPTY_LIST; - struct bio_list bio_completions = BIO_EMPTY_LIST; - -@@ -1213,7 +1241,7 @@ static void process_deferred_flush_bios(struct clone *clone) - !(dm_clone_changed_this_transaction(clone->cmd) && need_commit_due_to_time(clone))) - return; - -- if (commit_metadata(clone)) { -+ if (commit_metadata(clone, &dest_dev_flushed)) { - bio_list_merge(&bios, &bio_completions); - - while ((bio = bio_list_pop(&bios))) -@@ -1227,8 +1255,17 @@ static void process_deferred_flush_bios(struct clone *clone) - while ((bio = bio_list_pop(&bio_completions))) - bio_endio(bio); - -- while ((bio = bio_list_pop(&bios))) -- generic_make_request(bio); -+ while ((bio = bio_list_pop(&bios))) { -+ if ((bio->bi_opf & REQ_PREFLUSH) && dest_dev_flushed) { -+ /* We just flushed the destination device as part of -+ * the metadata commit, so there is no reason to send -+ * another flush. -+ */ -+ bio_endio(bio); -+ } else { -+ generic_make_request(bio); -+ } -+ } - } - - static void do_worker(struct work_struct *work) -@@ -1400,7 +1437,7 @@ static void clone_status(struct dm_target *ti, status_type_t type, - - /* Commit to ensure statistics aren't out-of-date */ - if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) -- (void) commit_metadata(clone); -+ (void) commit_metadata(clone, NULL); - - r = dm_clone_get_free_metadata_block_count(clone->cmd, &nr_free_metadata_blocks); - -@@ -1834,6 +1871,7 @@ static int clone_ctr(struct dm_target *ti, unsigned int argc, char **argv) - bio_list_init(&clone->deferred_flush_completions); - clone->hydration_offset = 0; - atomic_set(&clone->hydrations_in_flight, 0); -+ bio_init(&clone->flush_bio, NULL, 0); - - clone->wq = alloc_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM, 0); - if (!clone->wq) { -@@ -1907,6 +1945,7 @@ static void clone_dtr(struct dm_target *ti) - struct clone *clone = ti->private; - - mutex_destroy(&clone->commit_lock); -+ bio_uninit(&clone->flush_bio); - - for (i = 0; i < clone->nr_ctr_args; i++) - kfree(clone->ctr_args[i]); -@@ -1961,7 +2000,7 @@ static void clone_postsuspend(struct dm_target *ti) - wait_event(clone->hydration_stopped, !atomic_read(&clone->hydrations_in_flight)); - flush_workqueue(clone->wq); - -- (void) commit_metadata(clone); -+ (void) commit_metadata(clone, NULL); - } - - static void clone_resume(struct dm_target *ti) -diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c -index dbcc1e41cd57..e0c32793c248 100644 ---- a/drivers/md/dm-mpath.c -+++ b/drivers/md/dm-mpath.c -@@ -599,45 +599,10 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) - return pgpath; - } - --static struct pgpath *__map_bio_fast(struct multipath *m, struct bio *bio) --{ -- struct pgpath *pgpath; -- unsigned long flags; -- -- /* Do we need to select a new pgpath? */ -- /* -- * FIXME: currently only switching path if no path (due to failure, etc) -- * - which negates the point of using a path selector -- */ -- pgpath = READ_ONCE(m->current_pgpath); -- if (!pgpath) -- pgpath = choose_pgpath(m, bio->bi_iter.bi_size); -- -- if (!pgpath) { -- if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { -- /* Queue for the daemon to resubmit */ -- spin_lock_irqsave(&m->lock, flags); -- bio_list_add(&m->queued_bios, bio); -- spin_unlock_irqrestore(&m->lock, flags); -- queue_work(kmultipathd, &m->process_queued_bios); -- -- return ERR_PTR(-EAGAIN); -- } -- return NULL; -- } -- -- return pgpath; --} -- - static int __multipath_map_bio(struct multipath *m, struct bio *bio, - struct dm_mpath_io *mpio) - { -- struct pgpath *pgpath; -- -- if (!m->hw_handler_name) -- pgpath = __map_bio_fast(m, bio); -- else -- pgpath = __map_bio(m, bio); -+ struct pgpath *pgpath = __map_bio(m, bio); - - if (IS_ERR(pgpath)) - return DM_MAPIO_SUBMITTED; -diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c -index 4c68a7b93d5e..b88d6d701f5b 100644 ---- a/drivers/md/dm-thin-metadata.c -+++ b/drivers/md/dm-thin-metadata.c -@@ -188,6 +188,15 @@ struct dm_pool_metadata { - unsigned long flags; - sector_t data_block_size; - -+ /* -+ * Pre-commit callback. -+ * -+ * This allows the thin provisioning target to run a callback before -+ * the metadata are committed. -+ */ -+ dm_pool_pre_commit_fn pre_commit_fn; -+ void *pre_commit_context; -+ - /* - * We reserve a section of the metadata for commit overhead. - * All reported space does *not* include this. -@@ -826,6 +835,14 @@ static int __commit_transaction(struct dm_pool_metadata *pmd) - if (unlikely(!pmd->in_service)) - return 0; - -+ if (pmd->pre_commit_fn) { -+ r = pmd->pre_commit_fn(pmd->pre_commit_context); -+ if (r < 0) { -+ DMERR("pre-commit callback failed"); -+ return r; -+ } -+ } -+ - r = __write_changed_details(pmd); - if (r < 0) - return r; -@@ -892,6 +909,8 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev, - pmd->in_service = false; - pmd->bdev = bdev; - pmd->data_block_size = data_block_size; -+ pmd->pre_commit_fn = NULL; -+ pmd->pre_commit_context = NULL; - - r = __create_persistent_data_objects(pmd, format_device); - if (r) { -@@ -2044,6 +2063,16 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, - return r; - } - -+void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, -+ dm_pool_pre_commit_fn fn, -+ void *context) -+{ -+ pmd_write_lock_in_core(pmd); -+ pmd->pre_commit_fn = fn; -+ pmd->pre_commit_context = context; -+ pmd_write_unlock(pmd); -+} -+ - int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd) - { - int r = -EINVAL; -diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h -index f6be0d733c20..7ef56bd2a7e3 100644 ---- a/drivers/md/dm-thin-metadata.h -+++ b/drivers/md/dm-thin-metadata.h -@@ -230,6 +230,13 @@ bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd); - */ - void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd); - -+/* Pre-commit callback */ -+typedef int (*dm_pool_pre_commit_fn)(void *context); -+ -+void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, -+ dm_pool_pre_commit_fn fn, -+ void *context); -+ - /*----------------------------------------------------------------*/ - - #endif -diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c -index fcd887703f95..1696bfd23ad1 100644 ---- a/drivers/md/dm-thin.c -+++ b/drivers/md/dm-thin.c -@@ -328,6 +328,7 @@ struct pool_c { - dm_block_t low_water_blocks; - struct pool_features requested_pf; /* Features requested during table load */ - struct pool_features adjusted_pf; /* Features used after adjusting for constituent devices */ -+ struct bio flush_bio; - }; - - /* -@@ -2392,8 +2393,16 @@ static void process_deferred_bios(struct pool *pool) - while ((bio = bio_list_pop(&bio_completions))) - bio_endio(bio); - -- while ((bio = bio_list_pop(&bios))) -- generic_make_request(bio); -+ while ((bio = bio_list_pop(&bios))) { -+ /* -+ * The data device was flushed as part of metadata commit, -+ * so complete redundant flushes immediately. -+ */ -+ if (bio->bi_opf & REQ_PREFLUSH) -+ bio_endio(bio); -+ else -+ generic_make_request(bio); -+ } - } - - static void do_worker(struct work_struct *ws) -@@ -3127,6 +3136,7 @@ static void pool_dtr(struct dm_target *ti) - __pool_dec(pt->pool); - dm_put_device(ti, pt->metadata_dev); - dm_put_device(ti, pt->data_dev); -+ bio_uninit(&pt->flush_bio); - kfree(pt); - - mutex_unlock(&dm_thin_pool_table.mutex); -@@ -3192,6 +3202,29 @@ static void metadata_low_callback(void *context) - dm_table_event(pool->ti->table); - } - -+/* -+ * We need to flush the data device **before** committing the metadata. -+ * -+ * This ensures that the data blocks of any newly inserted mappings are -+ * properly written to non-volatile storage and won't be lost in case of a -+ * crash. -+ * -+ * Failure to do so can result in data corruption in the case of internal or -+ * external snapshots and in the case of newly provisioned blocks, when block -+ * zeroing is enabled. -+ */ -+static int metadata_pre_commit_callback(void *context) -+{ -+ struct pool_c *pt = context; -+ struct bio *flush_bio = &pt->flush_bio; -+ -+ bio_reset(flush_bio); -+ bio_set_dev(flush_bio, pt->data_dev->bdev); -+ flush_bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; -+ -+ return submit_bio_wait(flush_bio); -+} -+ - static sector_t get_dev_size(struct block_device *bdev) - { - return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; -@@ -3360,6 +3393,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) - pt->data_dev = data_dev; - pt->low_water_blocks = low_water_blocks; - pt->adjusted_pf = pt->requested_pf = pf; -+ bio_init(&pt->flush_bio, NULL, 0); - ti->num_flush_bios = 1; - - /* -@@ -3386,6 +3420,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) - if (r) - goto out_flags_changed; - -+ dm_pool_register_pre_commit_callback(pt->pool->pmd, -+ metadata_pre_commit_callback, -+ pt); -+ - pt->callbacks.congested_fn = pool_is_congested; - dm_table_add_target_callbacks(ti->table, &pt->callbacks); - -diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c -index 21ea537bd55e..eff04fa23dfa 100644 ---- a/drivers/md/persistent-data/dm-btree-remove.c -+++ b/drivers/md/persistent-data/dm-btree-remove.c -@@ -203,7 +203,13 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent, - struct btree_node *right = r->n; - uint32_t nr_left = le32_to_cpu(left->header.nr_entries); - uint32_t nr_right = le32_to_cpu(right->header.nr_entries); -- unsigned threshold = 2 * merge_threshold(left) + 1; -+ /* -+ * Ensure the number of entries in each child will be greater -+ * than or equal to (max_entries / 3 + 1), so no matter which -+ * child is used for removal, the number will still be not -+ * less than (max_entries / 3). -+ */ -+ unsigned int threshold = 2 * (merge_threshold(left) + 1); - - if (nr_left + nr_right < threshold) { - /* -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index 2c71a434c915..95b41c0891d0 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -408,38 +408,6 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr, - return 0; - } - --static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status, -- u32 retries_max) --{ -- int err; -- u32 retry_count = 0; -- -- if (!status || !retries_max) -- return -EINVAL; -- -- do { -- err = __mmc_send_status(card, status, 5); -- if (err) -- break; -- -- if (!R1_STATUS(*status) && -- (R1_CURRENT_STATE(*status) != R1_STATE_PRG)) -- break; /* RPMB programming operation complete */ -- -- /* -- * Rechedule to give the MMC device a chance to continue -- * processing the previous command without being polled too -- * frequently. -- */ -- usleep_range(1000, 5000); -- } while (++retry_count < retries_max); -- -- if (retry_count == retries_max) -- err = -EPERM; -- -- return err; --} -- - static int ioctl_do_sanitize(struct mmc_card *card) - { - int err; -@@ -468,6 +436,58 @@ out: - return err; - } - -+static inline bool mmc_blk_in_tran_state(u32 status) -+{ -+ /* -+ * Some cards mishandle the status bits, so make sure to check both the -+ * busy indication and the card state. -+ */ -+ return status & R1_READY_FOR_DATA && -+ (R1_CURRENT_STATE(status) == R1_STATE_TRAN); -+} -+ -+static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, -+ u32 *resp_errs) -+{ -+ unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); -+ int err = 0; -+ u32 status; -+ -+ do { -+ bool done = time_after(jiffies, timeout); -+ -+ err = __mmc_send_status(card, &status, 5); -+ if (err) { -+ dev_err(mmc_dev(card->host), -+ "error %d requesting status\n", err); -+ return err; -+ } -+ -+ /* Accumulate any response error bits seen */ -+ if (resp_errs) -+ *resp_errs |= status; -+ -+ /* -+ * Timeout if the device never becomes ready for data and never -+ * leaves the program state. -+ */ -+ if (done) { -+ dev_err(mmc_dev(card->host), -+ "Card stuck in wrong state! %s status: %#x\n", -+ __func__, status); -+ return -ETIMEDOUT; -+ } -+ -+ /* -+ * Some cards mishandle the status bits, -+ * so make sure to check both the busy -+ * indication and the card state. -+ */ -+ } while (!mmc_blk_in_tran_state(status)); -+ -+ return err; -+} -+ - static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - struct mmc_blk_ioc_data *idata) - { -@@ -477,7 +497,6 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - struct scatterlist sg; - int err; - unsigned int target_part; -- u32 status = 0; - - if (!card || !md || !idata) - return -EINVAL; -@@ -611,16 +630,12 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - - memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); - -- if (idata->rpmb) { -+ if (idata->rpmb || (cmd.flags & MMC_RSP_R1B)) { - /* -- * Ensure RPMB command has completed by polling CMD13 -+ * Ensure RPMB/R1B command has completed by polling CMD13 - * "Send Status". - */ -- err = ioctl_rpmb_card_status_poll(card, &status, 5); -- if (err) -- dev_err(mmc_dev(card->host), -- "%s: Card Status=0x%08X, error %d\n", -- __func__, status, err); -+ err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, NULL); - } - - return err; -@@ -970,58 +985,6 @@ static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host, - return ms; - } - --static inline bool mmc_blk_in_tran_state(u32 status) --{ -- /* -- * Some cards mishandle the status bits, so make sure to check both the -- * busy indication and the card state. -- */ -- return status & R1_READY_FOR_DATA && -- (R1_CURRENT_STATE(status) == R1_STATE_TRAN); --} -- --static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, -- struct request *req, u32 *resp_errs) --{ -- unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); -- int err = 0; -- u32 status; -- -- do { -- bool done = time_after(jiffies, timeout); -- -- err = __mmc_send_status(card, &status, 5); -- if (err) { -- pr_err("%s: error %d requesting status\n", -- req->rq_disk->disk_name, err); -- return err; -- } -- -- /* Accumulate any response error bits seen */ -- if (resp_errs) -- *resp_errs |= status; -- -- /* -- * Timeout if the device never becomes ready for data and never -- * leaves the program state. -- */ -- if (done) { -- pr_err("%s: Card stuck in wrong state! %s %s status: %#x\n", -- mmc_hostname(card->host), -- req->rq_disk->disk_name, __func__, status); -- return -ETIMEDOUT; -- } -- -- /* -- * Some cards mishandle the status bits, -- * so make sure to check both the busy -- * indication and the card state. -- */ -- } while (!mmc_blk_in_tran_state(status)); -- -- return err; --} -- - static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host, - int type) - { -@@ -1671,7 +1634,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req) - - mmc_blk_send_stop(card, timeout); - -- err = card_busy_detect(card, timeout, req, NULL); -+ err = card_busy_detect(card, timeout, NULL); - - mmc_retune_release(card->host); - -@@ -1895,7 +1858,7 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req) - if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ) - return 0; - -- err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, req, &status); -+ err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, &status); - - /* - * Do not assume data transferred correctly if there are any error bits -diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -index 221127324709..abf8f5eb0a1c 100644 ---- a/drivers/mmc/core/core.c -+++ b/drivers/mmc/core/core.c -@@ -1469,8 +1469,7 @@ void mmc_detach_bus(struct mmc_host *host) - mmc_bus_put(host); - } - --static void _mmc_detect_change(struct mmc_host *host, unsigned long delay, -- bool cd_irq) -+void _mmc_detect_change(struct mmc_host *host, unsigned long delay, bool cd_irq) - { - /* - * If the device is configured as wakeup, we prevent a new sleep for -@@ -2129,7 +2128,7 @@ int mmc_hw_reset(struct mmc_host *host) - ret = host->bus_ops->hw_reset(host); - mmc_bus_put(host); - -- if (ret) -+ if (ret < 0) - pr_warn("%s: tried to HW reset card, got error %d\n", - mmc_hostname(host), ret); - -@@ -2297,11 +2296,8 @@ void mmc_rescan(struct work_struct *work) - - mmc_bus_get(host); - -- /* -- * if there is a _removable_ card registered, check whether it is -- * still present -- */ -- if (host->bus_ops && !host->bus_dead && mmc_card_is_removable(host)) -+ /* Verify a registered card to be functional, else remove it. */ -+ if (host->bus_ops && !host->bus_dead) - host->bus_ops->detect(host); - - host->detect_change = 0; -diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h -index 328c78dbee66..575ac0257af2 100644 ---- a/drivers/mmc/core/core.h -+++ b/drivers/mmc/core/core.h -@@ -70,6 +70,8 @@ void mmc_rescan(struct work_struct *work); - void mmc_start_host(struct mmc_host *host); - void mmc_stop_host(struct mmc_host *host); - -+void _mmc_detect_change(struct mmc_host *host, unsigned long delay, -+ bool cd_irq); - int _mmc_detect_card_removed(struct mmc_host *host); - int mmc_detect_card_removed(struct mmc_host *host); - -diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c -index 26cabd53ddc5..ebb387aa5158 100644 ---- a/drivers/mmc/core/sdio.c -+++ b/drivers/mmc/core/sdio.c -@@ -1048,9 +1048,35 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host) - return ret; - } - -+/* -+ * SDIO HW reset -+ * -+ * Returns 0 if the HW reset was executed synchronously, returns 1 if the HW -+ * reset was asynchronously scheduled, else a negative error code. -+ */ - static int mmc_sdio_hw_reset(struct mmc_host *host) - { -- mmc_power_cycle(host, host->card->ocr); -+ struct mmc_card *card = host->card; -+ -+ /* -+ * In case the card is shared among multiple func drivers, reset the -+ * card through a rescan work. In this way it will be removed and -+ * re-detected, thus all func drivers becomes informed about it. -+ */ -+ if (atomic_read(&card->sdio_funcs_probed) > 1) { -+ if (mmc_card_removed(card)) -+ return 1; -+ host->rescan_entered = 0; -+ mmc_card_set_removed(card); -+ _mmc_detect_change(host, 0, false); -+ return 1; -+ } -+ -+ /* -+ * A single func driver has been probed, then let's skip the heavy -+ * hotplug dance above and execute the reset immediately. -+ */ -+ mmc_power_cycle(host, card->ocr); - return mmc_sdio_reinit_card(host); - } - -diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c -index 2963e6542958..3cc928282af7 100644 ---- a/drivers/mmc/core/sdio_bus.c -+++ b/drivers/mmc/core/sdio_bus.c -@@ -138,6 +138,8 @@ static int sdio_bus_probe(struct device *dev) - if (ret) - return ret; - -+ atomic_inc(&func->card->sdio_funcs_probed); -+ - /* Unbound SDIO functions are always suspended. - * During probe, the function is set active and the usage count - * is incremented. If the driver supports runtime PM, -@@ -153,7 +155,10 @@ static int sdio_bus_probe(struct device *dev) - /* Set the default block size so the driver is sure it's something - * sensible. */ - sdio_claim_host(func); -- ret = sdio_set_block_size(func, 0); -+ if (mmc_card_removed(func->card)) -+ ret = -ENOMEDIUM; -+ else -+ ret = sdio_set_block_size(func, 0); - sdio_release_host(func); - if (ret) - goto disable_runtimepm; -@@ -165,6 +170,7 @@ static int sdio_bus_probe(struct device *dev) - return 0; - - disable_runtimepm: -+ atomic_dec(&func->card->sdio_funcs_probed); - if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) - pm_runtime_put_noidle(dev); - dev_pm_domain_detach(dev, false); -@@ -181,6 +187,7 @@ static int sdio_bus_remove(struct device *dev) - pm_runtime_get_sync(dev); - - drv->remove(func); -+ atomic_dec(&func->card->sdio_funcs_probed); - - if (func->irq_handler) { - pr_warn("WARNING: driver %s did not remove its interrupt handler!\n", -diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c -index f6a669a9af41..1ad0b56f11b4 100644 ---- a/drivers/pci/controller/pcie-rcar.c -+++ b/drivers/pci/controller/pcie-rcar.c -@@ -93,8 +93,11 @@ - #define LINK_SPEED_2_5GTS (1 << 16) - #define LINK_SPEED_5_0GTS (2 << 16) - #define MACCTLR 0x011058 -+#define MACCTLR_NFTS_MASK GENMASK(23, 16) /* The name is from SH7786 */ - #define SPEED_CHANGE BIT(24) - #define SCRAMBLE_DISABLE BIT(27) -+#define LTSMDIS BIT(31) -+#define MACCTLR_INIT_VAL (LTSMDIS | MACCTLR_NFTS_MASK) - #define PMSR 0x01105c - #define MACS2R 0x011078 - #define MACCGSPSETR 0x011084 -@@ -615,6 +618,8 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie) - if (IS_ENABLED(CONFIG_PCI_MSI)) - rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR); - -+ rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR); -+ - /* Finish initialization - establish a PCI Express link */ - rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); - -@@ -1237,6 +1242,7 @@ static int rcar_pcie_resume_noirq(struct device *dev) - return 0; - - /* Re-establish the PCIe link */ -+ rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR); - rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); - return rcar_pcie_wait_for_dl(pcie); - } -diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h -index 654c972b8ea0..882ce82c4699 100644 ---- a/drivers/pci/hotplug/pciehp.h -+++ b/drivers/pci/hotplug/pciehp.h -@@ -72,6 +72,7 @@ extern int pciehp_poll_time; - * @reset_lock: prevents access to the Data Link Layer Link Active bit in the - * Link Status register and to the Presence Detect State bit in the Slot - * Status register during a slot reset which may cause them to flap -+ * @ist_running: flag to keep user request waiting while IRQ thread is running - * @request_result: result of last user request submitted to the IRQ thread - * @requester: wait queue to wake up on completion of user request, - * used for synchronous slot enable/disable request via sysfs -@@ -101,6 +102,7 @@ struct controller { - - struct hotplug_slot hotplug_slot; /* hotplug core interface */ - struct rw_semaphore reset_lock; -+ unsigned int ist_running; - int request_result; - wait_queue_head_t requester; - }; -diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c -index 21af7b16d7a4..dd8e4a5fb282 100644 ---- a/drivers/pci/hotplug/pciehp_ctrl.c -+++ b/drivers/pci/hotplug/pciehp_ctrl.c -@@ -375,7 +375,8 @@ int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot) - ctrl->request_result = -ENODEV; - pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC); - wait_event(ctrl->requester, -- !atomic_read(&ctrl->pending_events)); -+ !atomic_read(&ctrl->pending_events) && -+ !ctrl->ist_running); - return ctrl->request_result; - case POWERON_STATE: - ctrl_info(ctrl, "Slot(%s): Already in powering on state\n", -@@ -408,7 +409,8 @@ int pciehp_sysfs_disable_slot(struct hotplug_slot *hotplug_slot) - mutex_unlock(&ctrl->state_lock); - pciehp_request(ctrl, DISABLE_SLOT); - wait_event(ctrl->requester, -- !atomic_read(&ctrl->pending_events)); -+ !atomic_read(&ctrl->pending_events) && -+ !ctrl->ist_running); - return ctrl->request_result; - case POWEROFF_STATE: - ctrl_info(ctrl, "Slot(%s): Already in powering off state\n", -diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c -index 1a522c1c4177..86d97f3112f0 100644 ---- a/drivers/pci/hotplug/pciehp_hpc.c -+++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -583,6 +583,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) - irqreturn_t ret; - u32 events; - -+ ctrl->ist_running = true; - pci_config_pm_runtime_get(pdev); - - /* rerun pciehp_isr() if the port was inaccessible on interrupt */ -@@ -629,6 +630,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) - up_read(&ctrl->reset_lock); - - pci_config_pm_runtime_put(pdev); -+ ctrl->ist_running = false; - wake_up(&ctrl->requester); - return IRQ_HANDLED; - } -diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c -index 0884bedcfc7a..771041784e64 100644 ---- a/drivers/pci/msi.c -+++ b/drivers/pci/msi.c -@@ -213,12 +213,13 @@ u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag) - - if (pci_msi_ignore_mask) - return 0; -+ - desc_addr = pci_msix_desc_addr(desc); - if (!desc_addr) - return 0; - - mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; -- if (flag) -+ if (flag & PCI_MSIX_ENTRY_CTRL_MASKBIT) - mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; - - writel(mask_bits, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); -diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c -index a8124e47bf6e..d4ac8ce8c1f9 100644 ---- a/drivers/pci/pci-driver.c -+++ b/drivers/pci/pci-driver.c -@@ -1076,17 +1076,22 @@ static int pci_pm_thaw_noirq(struct device *dev) - return error; - } - -- if (pci_has_legacy_pm_support(pci_dev)) -- return pci_legacy_resume_early(dev); -- - /* -- * pci_restore_state() requires the device to be in D0 (because of MSI -- * restoration among other things), so force it into D0 in case the -- * driver's "freeze" callbacks put it into a low-power state directly. -+ * Both the legacy ->resume_early() and the new pm->thaw_noirq() -+ * callbacks assume the device has been returned to D0 and its -+ * config state has been restored. -+ * -+ * In addition, pci_restore_state() restores MSI-X state in MMIO -+ * space, which requires the device to be in D0, so return it to D0 -+ * in case the driver's "freeze" callbacks put it into a low-power -+ * state. - */ - pci_set_power_state(pci_dev, PCI_D0); - pci_restore_state(pci_dev); - -+ if (pci_has_legacy_pm_support(pci_dev)) -+ return pci_legacy_resume_early(dev); -+ - if (drv && drv->pm && drv->pm->thaw_noirq) - error = drv->pm->thaw_noirq(dev); - -diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c -index 3d5271a7a849..64ebe3e5e611 100644 ---- a/drivers/pci/probe.c -+++ b/drivers/pci/probe.c -@@ -1089,14 +1089,15 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, - * @sec: updated with secondary bus number from EA - * @sub: updated with subordinate bus number from EA - * -- * If @dev is a bridge with EA capability, update @sec and @sub with -- * fixed bus numbers from the capability and return true. Otherwise, -- * return false. -+ * If @dev is a bridge with EA capability that specifies valid secondary -+ * and subordinate bus numbers, return true with the bus numbers in @sec -+ * and @sub. Otherwise return false. - */ - static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub) - { - int ea, offset; - u32 dw; -+ u8 ea_sec, ea_sub; - - if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) - return false; -@@ -1108,8 +1109,13 @@ static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub) - - offset = ea + PCI_EA_FIRST_ENT; - pci_read_config_dword(dev, offset, &dw); -- *sec = dw & PCI_EA_SEC_BUS_MASK; -- *sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; -+ ea_sec = dw & PCI_EA_SEC_BUS_MASK; -+ ea_sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; -+ if (ea_sec == 0 || ea_sub < ea_sec) -+ return false; -+ -+ *sec = ea_sec; -+ *sub = ea_sub; - return true; - } - -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index 320255e5e8f8..308f744393eb 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -4313,15 +4313,21 @@ static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) - - static bool pci_quirk_cavium_acs_match(struct pci_dev *dev) - { -+ if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) -+ return false; -+ -+ switch (dev->device) { - /* -- * Effectively selects all downstream ports for whole ThunderX 1 -- * family by 0xf800 mask (which represents 8 SoCs), while the lower -- * bits of device ID are used to indicate which subdevice is used -- * within the SoC. -+ * Effectively selects all downstream ports for whole ThunderX1 -+ * (which represents 8 SoCs). - */ -- return (pci_is_pcie(dev) && -- (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) && -- ((dev->device & 0xf800) == 0xa000)); -+ case 0xa000 ... 0xa7ff: /* ThunderX1 */ -+ case 0xaf84: /* ThunderX2 */ -+ case 0xb884: /* ThunderX3 */ -+ return true; -+ default: -+ return false; -+ } - } - - static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) -@@ -4706,7 +4712,7 @@ int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags) - #define INTEL_BSPR_REG_BPPD (1 << 9) - - /* Upstream Peer Decode Configuration Register */ --#define INTEL_UPDCR_REG 0x1114 -+#define INTEL_UPDCR_REG 0x1014 - /* 5:0 Peer Decode Enable bits */ - #define INTEL_UPDCR_REG_MASK 0x3f - -diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c -index 8c94cd3fd1f2..465d6afd826e 100644 ---- a/drivers/pci/switch/switchtec.c -+++ b/drivers/pci/switch/switchtec.c -@@ -675,7 +675,7 @@ static int ioctl_event_summary(struct switchtec_dev *stdev, - return -ENOMEM; - - s->global = ioread32(&stdev->mmio_sw_event->global_summary); -- s->part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap); -+ s->part_bitmap = ioread64(&stdev->mmio_sw_event->part_event_bitmap); - s->local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); - - for (i = 0; i < stdev->partition_count; i++) { -diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c -index 621f1afd4d6b..1995f5b3ea67 100644 ---- a/drivers/rpmsg/qcom_glink_native.c -+++ b/drivers/rpmsg/qcom_glink_native.c -@@ -241,10 +241,31 @@ static void qcom_glink_channel_release(struct kref *ref) - { - struct glink_channel *channel = container_of(ref, struct glink_channel, - refcount); -+ struct glink_core_rx_intent *intent; -+ struct glink_core_rx_intent *tmp; - unsigned long flags; -+ int iid; -+ -+ /* cancel pending rx_done work */ -+ cancel_work_sync(&channel->intent_work); - - spin_lock_irqsave(&channel->intent_lock, flags); -+ /* Free all non-reuse intents pending rx_done work */ -+ list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) { -+ if (!intent->reuse) { -+ kfree(intent->data); -+ kfree(intent); -+ } -+ } -+ -+ idr_for_each_entry(&channel->liids, tmp, iid) { -+ kfree(tmp->data); -+ kfree(tmp); -+ } - idr_destroy(&channel->liids); -+ -+ idr_for_each_entry(&channel->riids, tmp, iid) -+ kfree(tmp); - idr_destroy(&channel->riids); - spin_unlock_irqrestore(&channel->intent_lock, flags); - -@@ -1094,13 +1115,12 @@ static int qcom_glink_create_remote(struct qcom_glink *glink, - close_link: - /* - * Send a close request to "undo" our open-ack. The close-ack will -- * release the last reference. -+ * release qcom_glink_send_open_req() reference and the last reference -+ * will be relesed after receiving remote_close or transport unregister -+ * by calling qcom_glink_native_remove(). - */ - qcom_glink_send_close_req(glink, channel); - -- /* Release qcom_glink_send_open_req() reference */ -- kref_put(&channel->refcount, qcom_glink_channel_release); -- - return ret; - } - -@@ -1415,15 +1435,13 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, - - ret = rpmsg_register_device(rpdev); - if (ret) -- goto free_rpdev; -+ goto rcid_remove; - - channel->rpdev = rpdev; - } - - return 0; - --free_rpdev: -- kfree(rpdev); - rcid_remove: - spin_lock_irqsave(&glink->idr_lock, flags); - idr_remove(&glink->rcids, channel->rcid); -@@ -1544,6 +1562,18 @@ static void qcom_glink_work(struct work_struct *work) - } - } - -+static void qcom_glink_cancel_rx_work(struct qcom_glink *glink) -+{ -+ struct glink_defer_cmd *dcmd; -+ struct glink_defer_cmd *tmp; -+ -+ /* cancel any pending deferred rx_work */ -+ cancel_work_sync(&glink->rx_work); -+ -+ list_for_each_entry_safe(dcmd, tmp, &glink->rx_queue, node) -+ kfree(dcmd); -+} -+ - struct qcom_glink *qcom_glink_native_probe(struct device *dev, - unsigned long features, - struct qcom_glink_pipe *rx, -@@ -1619,23 +1649,24 @@ void qcom_glink_native_remove(struct qcom_glink *glink) - struct glink_channel *channel; - int cid; - int ret; -- unsigned long flags; - - disable_irq(glink->irq); -- cancel_work_sync(&glink->rx_work); -+ qcom_glink_cancel_rx_work(glink); - - ret = device_for_each_child(glink->dev, NULL, qcom_glink_remove_device); - if (ret) - dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret); - -- spin_lock_irqsave(&glink->idr_lock, flags); - /* Release any defunct local channels, waiting for close-ack */ - idr_for_each_entry(&glink->lcids, channel, cid) - kref_put(&channel->refcount, qcom_glink_channel_release); - -+ /* Release any defunct local channels, waiting for close-req */ -+ idr_for_each_entry(&glink->rcids, channel, cid) -+ kref_put(&channel->refcount, qcom_glink_channel_release); -+ - idr_destroy(&glink->lcids); - idr_destroy(&glink->rcids); -- spin_unlock_irqrestore(&glink->idr_lock, flags); - mbox_free_channel(glink->mbox_chan); - } - EXPORT_SYMBOL_GPL(qcom_glink_native_remove); -diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c -index 4238383d8685..579bc4443f6d 100644 ---- a/drivers/rpmsg/qcom_glink_smem.c -+++ b/drivers/rpmsg/qcom_glink_smem.c -@@ -105,7 +105,7 @@ static void glink_smem_rx_advance(struct qcom_glink_pipe *np, - tail = le32_to_cpu(*pipe->tail); - - tail += count; -- if (tail > pipe->native.length) -+ if (tail >= pipe->native.length) - tail -= pipe->native.length; - - *pipe->tail = cpu_to_le32(tail); -diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c -index ebd47c0cf9e9..70b99c0e2e67 100644 ---- a/drivers/scsi/libiscsi.c -+++ b/drivers/scsi/libiscsi.c -@@ -1945,7 +1945,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) - - ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc); - -- spin_lock(&session->frwd_lock); -+ spin_lock_bh(&session->frwd_lock); - task = (struct iscsi_task *)sc->SCp.ptr; - if (!task) { - /* -@@ -2072,7 +2072,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) - done: - if (task) - task->last_timeout = jiffies; -- spin_unlock(&session->frwd_lock); -+ spin_unlock_bh(&session->frwd_lock); - ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? - "timer reset" : "shutdown or nh"); - return rc; -diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c -index 7259bce85e0e..1fbc5c6c6c14 100644 ---- a/drivers/scsi/qla2xxx/qla_attr.c -+++ b/drivers/scsi/qla2xxx/qla_attr.c -@@ -176,6 +176,7 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, - - faddr = ha->flt_region_nvram; - if (IS_QLA28XX(ha)) { -+ qla28xx_get_aux_images(vha, &active_regions); - if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) - faddr = ha->flt_region_nvram_sec; - } -diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c -index 99f0a1a08143..cbaf178fc979 100644 ---- a/drivers/scsi/qla2xxx/qla_bsg.c -+++ b/drivers/scsi/qla2xxx/qla_bsg.c -@@ -2399,7 +2399,7 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job) - struct qla_active_regions regions = { }; - struct active_regions active_regions = { }; - -- qla28xx_get_aux_images(vha, &active_regions); -+ qla27xx_get_active_image(vha, &active_regions); - regions.global_image = active_regions.global; - - if (IS_QLA28XX(ha)) { -diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h -index 732bb871c433..dc2366a29665 100644 ---- a/drivers/scsi/qla2xxx/qla_fw.h -+++ b/drivers/scsi/qla2xxx/qla_fw.h -@@ -1523,6 +1523,10 @@ struct qla_flt_header { - #define FLT_REG_NVRAM_SEC_28XX_1 0x10F - #define FLT_REG_NVRAM_SEC_28XX_2 0x111 - #define FLT_REG_NVRAM_SEC_28XX_3 0x113 -+#define FLT_REG_MPI_PRI_28XX 0xD3 -+#define FLT_REG_MPI_SEC_28XX 0xF0 -+#define FLT_REG_PEP_PRI_28XX 0xD1 -+#define FLT_REG_PEP_SEC_28XX 0xF1 - - struct qla_flt_region { - uint16_t code; -diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c -index d400b51929a6..5d31e3d52b6b 100644 ---- a/drivers/scsi/qla2xxx/qla_init.c -+++ b/drivers/scsi/qla2xxx/qla_init.c -@@ -534,6 +534,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport) - - e->u.fcport.fcport = fcport; - fcport->flags |= FCF_ASYNC_ACTIVE; -+ fcport->disc_state = DSC_LOGIN_PEND; - return qla2x00_post_work(vha, e); - } - -@@ -4847,6 +4848,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) - } - - INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn); -+ INIT_WORK(&fcport->free_work, qlt_free_session_done); - INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); - INIT_LIST_HEAD(&fcport->gnl_entry); - INIT_LIST_HEAD(&fcport->list); -diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c -index f2d5115b2d8d..bbe90354f49b 100644 ---- a/drivers/scsi/qla2xxx/qla_sup.c -+++ b/drivers/scsi/qla2xxx/qla_sup.c -@@ -847,15 +847,15 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) - ha->flt_region_img_status_pri = start; - break; - case FLT_REG_IMG_SEC_27XX: -- if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) -+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) - ha->flt_region_img_status_sec = start; - break; - case FLT_REG_FW_SEC_27XX: -- if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) -+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) - ha->flt_region_fw_sec = start; - break; - case FLT_REG_BOOTLOAD_SEC_27XX: -- if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) -+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) - ha->flt_region_boot_sec = start; - break; - case FLT_REG_AUX_IMG_PRI_28XX: -@@ -2725,8 +2725,11 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, - ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, - "Region %x is secure\n", region.code); - -- if (region.code == FLT_REG_FW || -- region.code == FLT_REG_FW_SEC_27XX) { -+ switch (region.code) { -+ case FLT_REG_FW: -+ case FLT_REG_FW_SEC_27XX: -+ case FLT_REG_MPI_PRI_28XX: -+ case FLT_REG_MPI_SEC_28XX: - fw_array = dwptr; - - /* 1st fw array */ -@@ -2757,9 +2760,23 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, - buf_size_without_sfub += risc_size; - fw_array += risc_size; - } -- } else { -- ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, -- "Secure region %x not supported\n", -+ break; -+ -+ case FLT_REG_PEP_PRI_28XX: -+ case FLT_REG_PEP_SEC_28XX: -+ fw_array = dwptr; -+ -+ /* 1st fw array */ -+ risc_size = be32_to_cpu(fw_array[3]); -+ risc_attr = be32_to_cpu(fw_array[9]); -+ -+ buf_size_without_sfub = risc_size; -+ fw_array += risc_size; -+ break; -+ -+ default: -+ ql_log(ql_log_warn + ql_dbg_verbose, vha, -+ 0xffff, "Secure region %x not supported\n", - region.code); - rval = QLA_COMMAND_ERROR; - goto done; -@@ -2880,7 +2897,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, - "Sending Secure Flash MB Cmd\n"); - rval = qla28xx_secure_flash_update(vha, 0, region.code, - buf_size_without_sfub, sfub_dma, -- sizeof(struct secure_flash_update_block)); -+ sizeof(struct secure_flash_update_block) >> 2); - if (rval != QLA_SUCCESS) { - ql_log(ql_log_warn, vha, 0xffff, - "Secure Flash MB Cmd failed %x.", rval); -diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c -index a06e56224a55..a9bd0f513316 100644 ---- a/drivers/scsi/qla2xxx/qla_target.c -+++ b/drivers/scsi/qla2xxx/qla_target.c -@@ -1160,7 +1160,6 @@ void qlt_unreg_sess(struct fc_port *sess) - sess->last_rscn_gen = sess->rscn_gen; - sess->last_login_gen = sess->login_gen; - -- INIT_WORK(&sess->free_work, qlt_free_session_done); - queue_work(sess->vha->hw->wq, &sess->free_work); - } - EXPORT_SYMBOL(qlt_unreg_sess); -diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c -index 042a24314edc..bab2073c1f72 100644 ---- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c -+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c -@@ -246,6 +246,8 @@ static void tcm_qla2xxx_complete_mcmd(struct work_struct *work) - */ - static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) - { -+ if (!mcmd) -+ return; - INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd); - queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work); - } -diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c -index b2af04c57a39..6feeb0faf123 100644 ---- a/drivers/scsi/ufs/cdns-pltfrm.c -+++ b/drivers/scsi/ufs/cdns-pltfrm.c -@@ -99,6 +99,12 @@ static int cdns_ufs_link_startup_notify(struct ufs_hba *hba, - */ - ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); - -+ /* -+ * Disabling Autohibern8 feature in cadence UFS -+ * to mask unexpected interrupt trigger. -+ */ -+ hba->ahit = 0; -+ - return 0; - } - -diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c -index f225eaa98ff8..d0f45600b669 100644 ---- a/drivers/usb/core/hcd.c -+++ b/drivers/usb/core/hcd.c -@@ -1409,7 +1409,17 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, - if (usb_endpoint_xfer_control(&urb->ep->desc)) { - if (hcd->self.uses_pio_for_control) - return ret; -- if (hcd_uses_dma(hcd)) { -+ if (hcd->localmem_pool) { -+ ret = hcd_alloc_coherent( -+ urb->dev->bus, mem_flags, -+ &urb->setup_dma, -+ (void **)&urb->setup_packet, -+ sizeof(struct usb_ctrlrequest), -+ DMA_TO_DEVICE); -+ if (ret) -+ return ret; -+ urb->transfer_flags |= URB_SETUP_MAP_LOCAL; -+ } else if (hcd_uses_dma(hcd)) { - if (is_vmalloc_addr(urb->setup_packet)) { - WARN_ONCE(1, "setup packet is not dma capable\n"); - return -EAGAIN; -@@ -1427,23 +1437,22 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, - urb->setup_dma)) - return -EAGAIN; - urb->transfer_flags |= URB_SETUP_MAP_SINGLE; -- } else if (hcd->localmem_pool) { -- ret = hcd_alloc_coherent( -- urb->dev->bus, mem_flags, -- &urb->setup_dma, -- (void **)&urb->setup_packet, -- sizeof(struct usb_ctrlrequest), -- DMA_TO_DEVICE); -- if (ret) -- return ret; -- urb->transfer_flags |= URB_SETUP_MAP_LOCAL; - } - } - - dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - if (urb->transfer_buffer_length != 0 - && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { -- if (hcd_uses_dma(hcd)) { -+ if (hcd->localmem_pool) { -+ ret = hcd_alloc_coherent( -+ urb->dev->bus, mem_flags, -+ &urb->transfer_dma, -+ &urb->transfer_buffer, -+ urb->transfer_buffer_length, -+ dir); -+ if (ret == 0) -+ urb->transfer_flags |= URB_MAP_LOCAL; -+ } else if (hcd_uses_dma(hcd)) { - if (urb->num_sgs) { - int n; - -@@ -1497,15 +1506,6 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, - else - urb->transfer_flags |= URB_DMA_MAP_SINGLE; - } -- } else if (hcd->localmem_pool) { -- ret = hcd_alloc_coherent( -- urb->dev->bus, mem_flags, -- &urb->transfer_dma, -- &urb->transfer_buffer, -- urb->transfer_buffer_length, -- dir); -- if (ret == 0) -- urb->transfer_flags |= URB_MAP_LOCAL; - } - if (ret && (urb->transfer_flags & (URB_SETUP_MAP_SINGLE | - URB_SETUP_MAP_LOCAL))) -diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c -index 54a3c8195c96..2adcabe060c5 100644 ---- a/drivers/usb/storage/scsiglue.c -+++ b/drivers/usb/storage/scsiglue.c -@@ -135,7 +135,8 @@ static int slave_configure(struct scsi_device *sdev) - * For such controllers we need to make sure the block layer sets - * up bounce buffers in addressable memory. - */ -- if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus))) -+ if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus)) || -+ (bus_to_hcd(us->pusb_dev->bus)->localmem_pool != NULL)) - blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH); - - /* -diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c -index 3fa3f728fb39..2056f3f85f59 100644 ---- a/drivers/vfio/pci/vfio_pci_intrs.c -+++ b/drivers/vfio/pci/vfio_pci_intrs.c -@@ -294,8 +294,8 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev, - irq = pci_irq_vector(pdev, vector); - - if (vdev->ctx[vector].trigger) { -- free_irq(irq, vdev->ctx[vector].trigger); - irq_bypass_unregister_producer(&vdev->ctx[vector].producer); -+ free_irq(irq, vdev->ctx[vector].trigger); - kfree(vdev->ctx[vector].name); - eventfd_ctx_put(vdev->ctx[vector].trigger); - vdev->ctx[vector].trigger = NULL; -diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c -index 0b4eee3bed66..efb2928ff6c8 100644 ---- a/fs/cifs/cifs_debug.c -+++ b/fs/cifs/cifs_debug.c -@@ -256,6 +256,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) - if (!server->rdma) - goto skip_rdma; - -+ if (!server->smbd_conn) { -+ seq_printf(m, "\nSMBDirect transport not available"); -+ goto skip_rdma; -+ } -+ - seq_printf(m, "\nSMBDirect (in hex) protocol version: %x " - "transport status: %x", - server->smbd_conn->protocol, -diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h -index d78bfcc19156..5d2dd04b55a6 100644 ---- a/fs/cifs/cifsglob.h -+++ b/fs/cifs/cifsglob.h -@@ -1524,6 +1524,7 @@ struct mid_q_entry { - struct TCP_Server_Info *server; /* server corresponding to this mid */ - __u64 mid; /* multiplex id */ - __u16 credits; /* number of credits consumed by this mid */ -+ __u16 credits_received; /* number of credits from the response */ - __u32 pid; /* process id */ - __u32 sequence_number; /* for CIFS signing */ - unsigned long when_alloc; /* when mid was created */ -diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c -index ccaa8bad336f..20c70cbab1ad 100644 ---- a/fs/cifs/connect.c -+++ b/fs/cifs/connect.c -@@ -905,6 +905,20 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) - spin_unlock(&GlobalMid_Lock); - } - -+static unsigned int -+smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server) -+{ -+ struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer; -+ -+ /* -+ * SMB1 does not use credits. -+ */ -+ if (server->vals->header_preamble_size) -+ return 0; -+ -+ return le16_to_cpu(shdr->CreditRequest); -+} -+ - static void - handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, - char *buf, int malformed) -@@ -912,6 +926,7 @@ handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, - if (server->ops->check_trans2 && - server->ops->check_trans2(mid, server, buf, malformed)) - return; -+ mid->credits_received = smb2_get_credits_from_hdr(buf, server); - mid->resp_buf = buf; - mid->large_buf = server->large_buf; - /* Was previous buf put in mpx struct for multi-rsp? */ -@@ -1222,12 +1237,6 @@ next_pdu: - for (i = 0; i < num_mids; i++) { - if (mids[i] != NULL) { - mids[i]->resp_buf_size = server->pdu_size; -- if ((mids[i]->mid_flags & MID_WAIT_CANCELLED) && -- mids[i]->mid_state == MID_RESPONSE_RECEIVED && -- server->ops->handle_cancelled_mid) -- server->ops->handle_cancelled_mid( -- mids[i]->resp_buf, -- server); - - if (!mids[i]->multiRsp || mids[i]->multiEnd) - mids[i]->callback(mids[i]); -@@ -4700,6 +4709,17 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, - } - - #ifdef CONFIG_CIFS_DFS_UPCALL -+static inline void set_root_tcon(struct cifs_sb_info *cifs_sb, -+ struct cifs_tcon *tcon, -+ struct cifs_tcon **root) -+{ -+ spin_lock(&cifs_tcp_ses_lock); -+ tcon->tc_count++; -+ tcon->remap = cifs_remap(cifs_sb); -+ spin_unlock(&cifs_tcp_ses_lock); -+ *root = tcon; -+} -+ - int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) - { - int rc = 0; -@@ -4801,18 +4821,10 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) - /* Cache out resolved root server */ - (void)dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), - root_path + 1, NULL, NULL); -- /* -- * Save root tcon for additional DFS requests to update or create a new -- * DFS cache entry, or even perform DFS failover. -- */ -- spin_lock(&cifs_tcp_ses_lock); -- tcon->tc_count++; -- tcon->dfs_path = root_path; -+ kfree(root_path); - root_path = NULL; -- tcon->remap = cifs_remap(cifs_sb); -- spin_unlock(&cifs_tcp_ses_lock); - -- root_tcon = tcon; -+ set_root_tcon(cifs_sb, tcon, &root_tcon); - - for (count = 1; ;) { - if (!rc && tcon) { -@@ -4849,6 +4861,15 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) - mount_put_conns(cifs_sb, xid, server, ses, tcon); - rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, - &tcon); -+ /* -+ * Ensure that DFS referrals go through new root server. -+ */ -+ if (!rc && tcon && -+ (tcon->share_flags & (SHI1005_FLAGS_DFS | -+ SHI1005_FLAGS_DFS_ROOT))) { -+ cifs_put_tcon(root_tcon); -+ set_root_tcon(cifs_sb, tcon, &root_tcon); -+ } - } - if (rc) { - if (rc == -EACCES || rc == -EOPNOTSUPP) -diff --git a/fs/cifs/file.c b/fs/cifs/file.c -index a3b6be80f8a9..c32650f14c9b 100644 ---- a/fs/cifs/file.c -+++ b/fs/cifs/file.c -@@ -729,6 +729,13 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) - if (backup_cred(cifs_sb)) - create_options |= CREATE_OPEN_BACKUP_INTENT; - -+ /* O_SYNC also has bit for O_DSYNC so following check picks up either */ -+ if (cfile->f_flags & O_SYNC) -+ create_options |= CREATE_WRITE_THROUGH; -+ -+ if (cfile->f_flags & O_DIRECT) -+ create_options |= CREATE_NO_BUFFER; -+ - if (server->ops->get_lease_key) - server->ops->get_lease_key(inode, &cfile->fid); - -diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c -index 449d1584ff72..766974fe637a 100644 ---- a/fs/cifs/smb2misc.c -+++ b/fs/cifs/smb2misc.c -@@ -743,36 +743,67 @@ smb2_cancelled_close_fid(struct work_struct *work) - kfree(cancelled); - } - -+/* Caller should already has an extra reference to @tcon */ -+static int -+__smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, -+ __u64 volatile_fid) -+{ -+ struct close_cancelled_open *cancelled; -+ -+ cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); -+ if (!cancelled) -+ return -ENOMEM; -+ -+ cancelled->fid.persistent_fid = persistent_fid; -+ cancelled->fid.volatile_fid = volatile_fid; -+ cancelled->tcon = tcon; -+ INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); -+ WARN_ON(queue_work(cifsiod_wq, &cancelled->work) == false); -+ -+ return 0; -+} -+ -+int -+smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, -+ __u64 volatile_fid) -+{ -+ int rc; -+ -+ cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count); -+ spin_lock(&cifs_tcp_ses_lock); -+ tcon->tc_count++; -+ spin_unlock(&cifs_tcp_ses_lock); -+ -+ rc = __smb2_handle_cancelled_close(tcon, persistent_fid, volatile_fid); -+ if (rc) -+ cifs_put_tcon(tcon); -+ -+ return rc; -+} -+ - int - smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) - { - struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer; - struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; - struct cifs_tcon *tcon; -- struct close_cancelled_open *cancelled; -+ int rc; - - if (sync_hdr->Command != SMB2_CREATE || - sync_hdr->Status != STATUS_SUCCESS) - return 0; - -- cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); -- if (!cancelled) -- return -ENOMEM; -- - tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId, - sync_hdr->TreeId); -- if (!tcon) { -- kfree(cancelled); -+ if (!tcon) - return -ENOENT; -- } - -- cancelled->fid.persistent_fid = rsp->PersistentFileId; -- cancelled->fid.volatile_fid = rsp->VolatileFileId; -- cancelled->tcon = tcon; -- INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); -- queue_work(cifsiod_wq, &cancelled->work); -+ rc = __smb2_handle_cancelled_close(tcon, rsp->PersistentFileId, -+ rsp->VolatileFileId); -+ if (rc) -+ cifs_put_tcon(tcon); - -- return 0; -+ return rc; - } - - /** -diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c -index cd55af9b7cc5..b5c1cba3e6a1 100644 ---- a/fs/cifs/smb2ops.c -+++ b/fs/cifs/smb2ops.c -@@ -151,13 +151,7 @@ smb2_get_credits_field(struct TCP_Server_Info *server, const int optype) - static unsigned int - smb2_get_credits(struct mid_q_entry *mid) - { -- struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)mid->resp_buf; -- -- if (mid->mid_state == MID_RESPONSE_RECEIVED -- || mid->mid_state == MID_RESPONSE_MALFORMED) -- return le16_to_cpu(shdr->CreditRequest); -- -- return 0; -+ return mid->credits_received; - } - - static int -diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c -index 05149862aea4..c985caa2d955 100644 ---- a/fs/cifs/smb2pdu.c -+++ b/fs/cifs/smb2pdu.c -@@ -2972,7 +2972,21 @@ int - SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, - u64 persistent_fid, u64 volatile_fid) - { -- return SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0); -+ int rc; -+ int tmp_rc; -+ -+ rc = SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0); -+ -+ /* retry close in a worker thread if this one is interrupted */ -+ if (rc == -EINTR) { -+ tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid, -+ volatile_fid); -+ if (tmp_rc) -+ cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n", -+ persistent_fid, tmp_rc); -+ } -+ -+ return rc; - } - - int -diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h -index 71b2930b8e0b..2a12a2fa38a2 100644 ---- a/fs/cifs/smb2proto.h -+++ b/fs/cifs/smb2proto.h -@@ -212,6 +212,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, - extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, - const u64 persistent_fid, const u64 volatile_fid, - const __u8 oplock_level); -+extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon, -+ __u64 persistent_fid, -+ __u64 volatile_fid); - extern int smb2_handle_cancelled_mid(char *buffer, - struct TCP_Server_Info *server); - void smb2_cancelled_close_fid(struct work_struct *work); -diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c -index 3c91fa97c9a8..5b1b97e9e0c9 100644 ---- a/fs/cifs/smbdirect.c -+++ b/fs/cifs/smbdirect.c -@@ -1069,7 +1069,7 @@ static int smbd_post_send_data( - - if (n_vec > SMBDIRECT_MAX_SGE) { - cifs_dbg(VFS, "Can't fit data to SGL, n_vec=%d\n", n_vec); -- return -ENOMEM; -+ return -EINVAL; - } - - sg_init_table(sgl, n_vec); -@@ -1476,6 +1476,7 @@ void smbd_destroy(struct TCP_Server_Info *server) - info->transport_status = SMBD_DESTROYED; - - destroy_workqueue(info->workqueue); -+ log_rdma_event(INFO, "rdma session destroyed\n"); - kfree(info); - } - -@@ -1505,8 +1506,9 @@ create_conn: - log_rdma_event(INFO, "creating rdma session\n"); - server->smbd_conn = smbd_get_connection( - server, (struct sockaddr *) &server->dstaddr); -- log_rdma_event(INFO, "created rdma session info=%p\n", -- server->smbd_conn); -+ -+ if (server->smbd_conn) -+ cifs_dbg(VFS, "RDMA transport re-established\n"); - - return server->smbd_conn ? 0 : -ENOENT; - } -@@ -1970,7 +1972,7 @@ read_rfc1002_done: - - if (info->transport_status != SMBD_CONNECTED) { - log_read(ERR, "disconnected\n"); -- return 0; -+ return -ECONNABORTED; - } - - goto again; -@@ -2269,12 +2271,7 @@ static void smbd_mr_recovery_work(struct work_struct *work) - int rc; - - list_for_each_entry(smbdirect_mr, &info->mr_list, list) { -- if (smbdirect_mr->state == MR_INVALIDATED) -- ib_dma_unmap_sg( -- info->id->device, smbdirect_mr->sgl, -- smbdirect_mr->sgl_count, -- smbdirect_mr->dir); -- else if (smbdirect_mr->state == MR_ERROR) { -+ if (smbdirect_mr->state == MR_ERROR) { - - /* recover this MR entry */ - rc = ib_dereg_mr(smbdirect_mr->mr); -@@ -2602,11 +2599,20 @@ int smbd_deregister_mr(struct smbd_mr *smbdirect_mr) - */ - smbdirect_mr->state = MR_INVALIDATED; - -- /* -- * Schedule the work to do MR recovery for future I/Os -- * MR recovery is slow and we don't want it to block the current I/O -- */ -- queue_work(info->workqueue, &info->mr_recovery_work); -+ if (smbdirect_mr->state == MR_INVALIDATED) { -+ ib_dma_unmap_sg( -+ info->id->device, smbdirect_mr->sgl, -+ smbdirect_mr->sgl_count, -+ smbdirect_mr->dir); -+ smbdirect_mr->state = MR_READY; -+ if (atomic_inc_return(&info->mr_ready_count) == 1) -+ wake_up_interruptible(&info->wait_mr); -+ } else -+ /* -+ * Schedule the work to do MR recovery for future I/Os MR -+ * recovery is slow and don't want it to block current I/O -+ */ -+ queue_work(info->workqueue, &info->mr_recovery_work); - - done: - if (atomic_dec_and_test(&info->mr_used_count)) -diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c -index ca3de62688d6..755434d5e4e7 100644 ---- a/fs/cifs/transport.c -+++ b/fs/cifs/transport.c -@@ -93,8 +93,14 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) - __u16 smb_cmd = le16_to_cpu(midEntry->command); - unsigned long now; - unsigned long roundtrip_time; -- struct TCP_Server_Info *server = midEntry->server; - #endif -+ struct TCP_Server_Info *server = midEntry->server; -+ -+ if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && -+ midEntry->mid_state == MID_RESPONSE_RECEIVED && -+ server->ops->handle_cancelled_mid) -+ server->ops->handle_cancelled_mid(midEntry->resp_buf, server); -+ - midEntry->mid_state = MID_FREE; - atomic_dec(&midCount); - if (midEntry->large_buf) -@@ -319,8 +325,11 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, - int val = 1; - __be32 rfc1002_marker; - -- if (cifs_rdma_enabled(server) && server->smbd_conn) { -- rc = smbd_send(server, num_rqst, rqst); -+ if (cifs_rdma_enabled(server)) { -+ /* return -EAGAIN when connecting or reconnecting */ -+ rc = -EAGAIN; -+ if (server->smbd_conn) -+ rc = smbd_send(server, num_rqst, rqst); - goto smbd_done; - } - -@@ -1119,8 +1128,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, - midQ[i]->mid, le16_to_cpu(midQ[i]->command)); - send_cancel(server, &rqst[i], midQ[i]); - spin_lock(&GlobalMid_Lock); -+ midQ[i]->mid_flags |= MID_WAIT_CANCELLED; - if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { -- midQ[i]->mid_flags |= MID_WAIT_CANCELLED; - midQ[i]->callback = cifs_cancelled_callback; - cancelled_mid[i] = true; - credits[i].value = 0; -diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c -index 997b326247e2..c53e3b892210 100644 ---- a/fs/gfs2/file.c -+++ b/fs/gfs2/file.c -@@ -381,27 +381,28 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) - /** - * gfs2_allocate_page_backing - Allocate blocks for a write fault - * @page: The (locked) page to allocate backing for -+ * @length: Size of the allocation - * - * We try to allocate all the blocks required for the page in one go. This - * might fail for various reasons, so we keep trying until all the blocks to - * back this page are allocated. If some of the blocks are already allocated, - * that is ok too. - */ --static int gfs2_allocate_page_backing(struct page *page) -+static int gfs2_allocate_page_backing(struct page *page, unsigned int length) - { - u64 pos = page_offset(page); -- u64 size = PAGE_SIZE; - - do { - struct iomap iomap = { }; - -- if (gfs2_iomap_get_alloc(page->mapping->host, pos, 1, &iomap)) -+ if (gfs2_iomap_get_alloc(page->mapping->host, pos, length, &iomap)) - return -EIO; - -- iomap.length = min(iomap.length, size); -- size -= iomap.length; -+ if (length < iomap.length) -+ iomap.length = length; -+ length -= iomap.length; - pos += iomap.length; -- } while (size > 0); -+ } while (length > 0); - - return 0; - } -@@ -501,7 +502,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf) - if (gfs2_is_stuffed(ip)) - ret = gfs2_unstuff_dinode(ip, page); - if (ret == 0) -- ret = gfs2_allocate_page_backing(page); -+ ret = gfs2_allocate_page_backing(page, PAGE_SIZE); - - out_trans_end: - if (ret) -diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c -index 58e237fba565..2aed73666a65 100644 ---- a/fs/gfs2/log.c -+++ b/fs/gfs2/log.c -@@ -609,6 +609,14 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) - list_add(&bd->bd_list, &sdp->sd_log_revokes); - } - -+void gfs2_glock_remove_revoke(struct gfs2_glock *gl) -+{ -+ if (atomic_dec_return(&gl->gl_revokes) == 0) { -+ clear_bit(GLF_LFLUSH, &gl->gl_flags); -+ gfs2_glock_queue_put(gl); -+ } -+} -+ - void gfs2_write_revokes(struct gfs2_sbd *sdp) - { - struct gfs2_trans *tr; -diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h -index 2315fca47a2b..c762da494546 100644 ---- a/fs/gfs2/log.h -+++ b/fs/gfs2/log.h -@@ -77,6 +77,7 @@ extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) - extern void gfs2_log_shutdown(struct gfs2_sbd *sdp); - extern int gfs2_logd(void *data); - extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); -+extern void gfs2_glock_remove_revoke(struct gfs2_glock *gl); - extern void gfs2_write_revokes(struct gfs2_sbd *sdp); - - #endif /* __LOG_DOT_H__ */ -diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c -index 5b17979af539..e2437b775456 100644 ---- a/fs/gfs2/lops.c -+++ b/fs/gfs2/lops.c -@@ -882,10 +882,7 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) - bd = list_entry(head->next, struct gfs2_bufdata, bd_list); - list_del_init(&bd->bd_list); - gl = bd->bd_gl; -- if (atomic_dec_return(&gl->gl_revokes) == 0) { -- clear_bit(GLF_LFLUSH, &gl->gl_flags); -- gfs2_glock_queue_put(gl); -- } -+ gfs2_glock_remove_revoke(gl); - kmem_cache_free(gfs2_bufdata_cachep, bd); - } - } -diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c -index 35e3059255fe..9d4227330de4 100644 ---- a/fs/gfs2/trans.c -+++ b/fs/gfs2/trans.c -@@ -262,6 +262,8 @@ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) - list_del_init(&bd->bd_list); - gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); - sdp->sd_log_num_revoke--; -+ if (bd->bd_gl) -+ gfs2_glock_remove_revoke(bd->bd_gl); - kmem_cache_free(gfs2_bufdata_cachep, bd); - tr->tr_num_revoke--; - if (--n == 0) -diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h -index 9b6336ad3266..e459b38ef33c 100644 ---- a/include/linux/mmc/card.h -+++ b/include/linux/mmc/card.h -@@ -291,6 +291,7 @@ struct mmc_card { - struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ - - unsigned int sdio_funcs; /* number of SDIO functions */ -+ atomic_t sdio_funcs_probed; /* number of probed SDIO funcs */ - struct sdio_cccr cccr; /* common card info */ - struct sdio_cis cis; /* common tuple info */ - struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */ -diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h -index ebf5ef17cc2a..24a6263c9931 100644 ---- a/include/linux/pm_qos.h -+++ b/include/linux/pm_qos.h -@@ -256,7 +256,7 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev) - #endif - - #define FREQ_QOS_MIN_DEFAULT_VALUE 0 --#define FREQ_QOS_MAX_DEFAULT_VALUE (-1) -+#define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX - - enum freq_qos_req_type { - FREQ_QOS_MIN = 1, -diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c -index f9707fb05efe..682ed39f79b0 100644 ---- a/sound/hda/hdac_stream.c -+++ b/sound/hda/hdac_stream.c -@@ -120,10 +120,8 @@ void snd_hdac_stream_clear(struct hdac_stream *azx_dev) - snd_hdac_stream_updateb(azx_dev, SD_CTL, - SD_CTL_DMA_START | SD_INT_MASK, 0); - snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */ -- if (azx_dev->stripe) { -+ if (azx_dev->stripe) - snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0); -- azx_dev->stripe = 0; -- } - azx_dev->running = false; - } - EXPORT_SYMBOL_GPL(snd_hdac_stream_clear); -diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c -index 4dafc864d765..488c17c9f375 100644 ---- a/sound/pci/hda/patch_hdmi.c -+++ b/sound/pci/hda/patch_hdmi.c -@@ -1983,6 +1983,8 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, - per_cvt->assigned = 0; - hinfo->nid = 0; - -+ azx_stream(get_azx_dev(substream))->stripe = 0; -+ - mutex_lock(&spec->pcm_lock); - snd_hda_spdif_ctls_unassign(codec, pcm_idx); - clear_bit(pcm_idx, &spec->pcm_in_use); From 5c7e7c72356cbafb439daa65b57f80301c4e6587 Mon Sep 17 00:00:00 2001 From: zciendor <37557036+zciendor@users.noreply.github.com> Date: Mon, 6 Jan 2020 22:31:54 +0000 Subject: [PATCH 07/12] fix for https://github.com/armbian/build/issues/1584 (#1723) Since Debian buster the final `update-initramfs` call must be made on the finished image where the final root device is mounted, else `cryptsetup-initramfs` hooks fail to detect the root device. --- lib/debootstrap.sh | 24 +++++++++++++++--------- lib/distributions.sh | 3 +-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/debootstrap.sh b/lib/debootstrap.sh index d1b555f6ad..707b37c60d 100644 --- a/lib/debootstrap.sh +++ b/lib/debootstrap.sh @@ -75,8 +75,6 @@ debootstrap_ng() source $SRC/lib/fel-load.sh else prepare_partitions - # update initramfs to reflect any configuration changes since kernel installation - update_initramfs create_image fi @@ -525,18 +523,23 @@ prepare_partitions() # for cryptroot-unlock to work: # https://serverfault.com/questions/907254/cryproot-unlock-with-dropbear-timeout-while-waiting-for-askpass # -update_initramfs() { - +# since Debian buster, it has to be called within create_image() on the $MOUNT +# path instead of $SDCARD (which can be a tmpfs and breaks cryptsetup-initramfs). +# see: https://github.com/armbian/build/issues/1584 +# +update_initramfs() +{ + local chroot_target=$1 update_initramfs_cmd="update-initramfs -uv -k ${VER}-${LINUXFAMILY}" display_alert "Updating initramfs..." "$update_initramfs_cmd" "" - cp /usr/bin/$QEMU_BINARY $SDCARD/usr/bin/ - mount_chroot "$SDCARD/" + cp /usr/bin/$QEMU_BINARY $chroot_target/usr/bin/ + mount_chroot "$chroot_target/" - chroot $SDCARD /bin/bash -c "$update_initramfs_cmd" >> $DEST/debug/install.log 2>&1 + chroot $chroot_target /bin/bash -c "$update_initramfs_cmd" >> $DEST/debug/install.log 2>&1 display_alert "Updated initramfs." "for details see: $DEST/debug/install.log" "ext" - umount_chroot "$SDCARD/" - rm $SDCARD/usr/bin/$QEMU_BINARY + umount_chroot "$chroot_target/" + rm $chroot_target/usr/bin/$QEMU_BINARY } ############################################################################# @@ -572,6 +575,9 @@ create_image() rsync -aHWXh --info=progress2,stats1 $SDCARD/boot $MOUNT fi + # stage: create final initramfs + update_initramfs $MOUNT + # DEBUG: print free space display_alert "Free space:" "SD card" "info" eval 'df -h' ${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} diff --git a/lib/distributions.sh b/lib/distributions.sh index e4048eca5a..94d6b7c71b 100644 --- a/lib/distributions.sh +++ b/lib/distributions.sh @@ -59,8 +59,7 @@ install_common() # /usr/share/initramfs-tools/hooks/dropbear will automatically add 'id_ecdsa.pub' to authorized_keys file # during mkinitramfs of update-initramfs #cat $SDCARD/etc/dropbear-initramfs/id_ecdsa.pub > $SDCARD/etc/dropbear-initramfs/authorized_keys - CRYPTROOT_SSH_UNLOCK_KEY_NAME=\ - "Armbian_${REVISION}_${BOARD^}_${DISTRIBUTION}_${RELEASE}_${BRANCH}_${VER/-$LINUXFAMILY/}".key + CRYPTROOT_SSH_UNLOCK_KEY_NAME="Armbian_${REVISION}_${BOARD^}_${RELEASE}_${BRANCH}_${VER/-$LINUXFAMILY/}".key # copy dropbear ssh key to image output dir for convenience cp "${SDCARD}"/etc/dropbear-initramfs/id_ecdsa "${DEST}/images/${CRYPTROOT_SSH_UNLOCK_KEY_NAME}" display_alert "SSH private key for dropbear (initramfs) has been copied to:" \ From 3e38b4b71520ae329fe4823a65a9e8c8fa035df6 Mon Sep 17 00:00:00 2001 From: zhangn1985 <832666+zhangn1985@users.noreply.github.com> Date: Tue, 7 Jan 2020 06:45:28 +0800 Subject: [PATCH 08/12] build optimize for upstream (#1713) * add tuna debian-security mirror Signed-off-by: Zhang Ning <832666+zhangn1985@users.noreply.github.com> * replace apt-get with apt Signed-off-by: Zhang Ning <832666+zhangn1985@users.noreply.github.com> * speed up desktop build Signed-off-by: Zhang Ning <832666+zhangn1985@users.noreply.github.com> --- README.md | 2 +- compile.sh | 10 +++++----- lib/chroot-buildpackages.sh | 14 +++++++------- lib/configuration.sh | 2 ++ lib/debootstrap.sh | 8 ++++---- lib/desktop.sh | 10 +++++----- lib/general.sh | 4 ++-- lib/image-helpers.sh | 2 +- 8 files changed, 27 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index c1e8cdc4f9..58176de213 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Supported build environment is **Ubuntu Bionic 18.04 x64** ([minimal iso image]( **Execution** - apt-get -y install git + apt -y install git git clone https://github.com/armbian/build cd build ./compile.sh diff --git a/compile.sh b/compile.sh index ed5a6bdce1..6257109dbc 100755 --- a/compile.sh +++ b/compile.sh @@ -87,8 +87,8 @@ rm $TMPFILE # Check for Vagrant if [[ "$1" == vagrant && -z "$(which vagrant)" ]]; then display_alert "Vagrant not installed." "Installing" - sudo apt-get update - sudo apt-get install -y vagrant virtualbox + sudo apt update + sudo apt install -y vagrant virtualbox fi if [[ "$1" == dockerpurge && -f /etc/debian_version ]]; then @@ -116,12 +116,12 @@ if [[ "$1" == docker && -f /etc/debian_version && -z "$(which docker)" ]]; then do [[ ! $(which $i) ]] && install_packages+=$i" " done - [[ -z $install_packages ]] && apt-get update;apt-get install -y -qq --no-install-recommends $install_packages + [[ -z $install_packages ]] && apt update;apt install -y -qq --no-install-recommends $install_packages curl -fsSL "https://download.docker.com/linux/$(lsb_release -is | awk '{print tolower($0)}')/gpg" | apt-key add -qq - > /dev/null 2>&1 export DEBIAN_FRONTEND=noninteractive - apt-get update - apt-get install -y -qq --no-install-recommends docker-ce + apt update + apt install -y -qq --no-install-recommends docker-ce display_alert "Add yourself to docker group to avoid root privileges" "" "wrn" "$SRC/compile.sh" "$@" exit $? diff --git a/lib/chroot-buildpackages.sh b/lib/chroot-buildpackages.sh index fdba393ca0..c67e9b9272 100644 --- a/lib/chroot-buildpackages.sh +++ b/lib/chroot-buildpackages.sh @@ -156,7 +156,7 @@ chroot_build_packages() local t=$target_dir/root/.update-timestamp if [[ ! -f $t || $(( ($(date +%s) - $(<$t)) / 86400 )) -gt 7 ]]; then display_alert "Upgrading packages" "$release/$arch" "info" - systemd-nspawn -a -q -D $target_dir /bin/bash -c "apt-get -q update; apt-get -q -y upgrade; apt-get clean" + systemd-nspawn -a -q -D $target_dir /bin/bash -c "apt -q update; apt -q -y upgrade; apt clean" date +%s > $t fi @@ -219,8 +219,8 @@ chroot_build_packages() for packet in $package_builddeps; do grep -q -x -e "\$packet" <<< "\$installed" || deps+=("\$packet"); done if [[ \${#deps[@]} -gt 0 ]]; then display_alert "Installing build dependencies" - apt-get -y -q update - apt-get -y -q --no-install-recommends --show-progress -o DPKG::Progress-Fancy=1 install "\${deps[@]}" + apt -y -q update + apt -y -q --no-install-recommends --show-progress -o DPKG::Progress-Fancy=1 install "\${deps[@]}" fi fi display_alert "Copying sources" @@ -333,17 +333,17 @@ chroot_installpackages() cat <<-EOF > "${SDCARD}"/tmp/install.sh #!/bin/bash [[ "$remote_only" != yes ]] && apt-key add /tmp/buildpkg.key - apt-get $apt_extra -q update + apt $apt_extra -q update # uncomment to debug # /bin/bash # TODO: check if package exists in case new config was added #if [[ -n "$remote_only" == yes ]]; then # for p in $install_list; do # if grep -qE "apt.armbian.com|localhost" <(apt-cache madison \$p); then - # if apt-get -s -qq install \$p; then + # if apt -s -qq install \$p; then #fi - apt-get -q $apt_extra --show-progress -o DPKG::Progress-Fancy=1 install -y $install_list - apt-get clean + apt -q $apt_extra --show-progress -o DPKG::Progress-Fancy=1 install -y $install_list + apt clean [[ "$remote_only" != yes ]] && apt-key del "925644A6" rm /etc/apt/sources.list.d/armbian-temp.list 2>/dev/null rm /etc/apt/preferences.d/90-armbian-temp.pref 2>/dev/null diff --git a/lib/configuration.sh b/lib/configuration.sh index ff310df4a4..ba55de0d6d 100644 --- a/lib/configuration.sh +++ b/lib/configuration.sh @@ -252,10 +252,12 @@ esac DEBIAN_MIRROR='httpredir.debian.org/debian' +DEBIAN_SECURTY='http://security.debian.org/' UBUNTU_MIRROR='ports.ubuntu.com/' if [[ $DOWNLOAD_MIRROR == china ]] ; then DEBIAN_MIRROR='mirrors.tuna.tsinghua.edu.cn/debian' + DEBIAN_SECURTY='mirrors.tuna.tsinghua.edu.cn/debian-security' UBUNTU_MIRROR='mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/' fi diff --git a/lib/debootstrap.sh b/lib/debootstrap.sh index 707b37c60d..7a992f8238 100644 --- a/lib/debootstrap.sh +++ b/lib/debootstrap.sh @@ -124,7 +124,7 @@ create_rootfs_cache() # stage: debootstrap base system if [[ $NO_APT_CACHER != yes ]]; then - # apt-cacher-ng apt-get proxy parameter + # apt-cacher-ng apt proxy parameter local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\"" local apt_mirror="http://${APT_PROXY_ADDR:-localhost:3142}/$APT_MIRROR" else @@ -194,7 +194,7 @@ create_rootfs_cache() # stage: update packages list display_alert "Updating package list" "$RELEASE" "info" - eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "apt-get -q -y $apt_extra update"' \ + eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "apt -q -y $apt_extra update"' \ ${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \ ${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Updating package lists..." $TTY_Y $TTY_X'} \ ${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} @@ -203,7 +203,7 @@ create_rootfs_cache() # stage: upgrade base packages from xxx-updates and xxx-backports repository branches display_alert "Upgrading base packages" "Armbian" "info" - eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -y -q \ + eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -y -q \ $apt_extra $apt_extra_progress upgrade"' \ ${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \ ${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Upgrading base packages..." $TTY_Y $TTY_X'} \ @@ -222,7 +222,7 @@ create_rootfs_cache() [[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Installation of Armbian packages failed" # stage: remove downloaded packages - chroot $SDCARD /bin/bash -c "apt-get clean" + chroot $SDCARD /bin/bash -c "apt clean" # DEBUG: print free space echo -e "\nFree space:" diff --git a/lib/desktop.sh b/lib/desktop.sh index 68ce71875a..4a47cbbf91 100644 --- a/lib/desktop.sh +++ b/lib/desktop.sh @@ -120,18 +120,18 @@ desktop_postinstall () { # disable display manager for first run chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload disable lightdm.service >/dev/null 2>&1" + chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt update" >> "${DEST}"/debug/install.log if [[ ${FULL_DESKTOP} == yes ]]; then - chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get update" >> "${DEST}"/debug/install.log - chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get update; apt-get -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FULL" >> "${DEST}"/debug/install.log + chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FULL" >> "${DEST}"/debug/install.log fi if [[ -n ${PACKAGE_LIST_DESKTOP_BOARD} ]]; then - chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get update; apt-get -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_BOARD" >> "${DEST}"/debug/install.log + chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_BOARD" >> "${DEST}"/debug/install.log fi if [[ -n ${PACKAGE_LIST_DESKTOP_FAMILY} ]]; then - chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get update; apt-get -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FAMILY" >> "${DEST}"/debug/install.log - fi + chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FAMILY" >> "${DEST}"/debug/install.log + fi # Compile Turbo Frame buffer for sunxi if [[ $LINUXFAMILY == sun* && $BRANCH == default ]]; then diff --git a/lib/general.sh b/lib/general.sh index 10b7589d2e..887f28e197 100644 --- a/lib/general.sh +++ b/lib/general.sh @@ -144,8 +144,8 @@ create_sources_list() deb http://${DEBIAN_MIRROR} ${release}-backports main contrib non-free #deb-src http://${DEBIAN_MIRROR} ${release}-backports main contrib non-free - deb http://security.debian.org/ ${release}/updates main contrib non-free - #deb-src http://security.debian.org/ ${release}/updates main contrib non-free + deb http://${DEBIAN_SECURTY} ${release}/updates main contrib non-free + #deb-src http://${DEBIAN_SECURTY} ${release}/updates main contrib non-free EOF ;; diff --git a/lib/image-helpers.sh b/lib/image-helpers.sh index dc9541dfd1..7afaaa3e6d 100644 --- a/lib/image-helpers.sh +++ b/lib/image-helpers.sh @@ -126,7 +126,7 @@ install_deb_chroot() cp "${package}" "${SDCARD}/root/${name}" display_alert "Installing" "$name" [[ $NO_APT_CACHER != yes ]] && local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\"" - LC_ALL=C LANG=C chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq \ + LC_ALL=C LANG=C chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq \ $apt_extra --no-install-recommends install ./root/$name" >> "${DEST}"/debug/install.log 2>&1 rm -f "${SDCARD}/root/${name}" From 9b8116b75fdd6299cc4863917d953ee302770e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Pe=C4=8Dovnik?= Date: Mon, 6 Jan 2020 23:52:36 +0100 Subject: [PATCH 09/12] Cosmetic fix --- lib/configuration.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configuration.sh b/lib/configuration.sh index ba55de0d6d..32851d0ad5 100644 --- a/lib/configuration.sh +++ b/lib/configuration.sh @@ -314,7 +314,7 @@ Build directory permissions: $(getfacl -p "${SRC}") Temp directory permissions: -$(getfacl -p "${SRC}"/.tmp) +$(getfacl -p "${SRC}"/.tmp 2> /dev/null) ## BUILD CONFIGURATION From 7bf126caf1fb2e99c2034329f7065fea53618d6f Mon Sep 17 00:00:00 2001 From: "m][sko" Date: Tue, 7 Jan 2020 00:43:04 +0100 Subject: [PATCH 10/12] fix gpu power on firefly rk3399 (#1724) --- .../board-firefly-rk3399-fix-gpu-power.patch | 25 +++++++++++++++++++ .../board-firefly-rk3399-fix-gpu-power.patch | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 patch/kernel/rockchip64-current/board-firefly-rk3399-fix-gpu-power.patch create mode 100644 patch/kernel/rockchip64-dev/board-firefly-rk3399-fix-gpu-power.patch diff --git a/patch/kernel/rockchip64-current/board-firefly-rk3399-fix-gpu-power.patch b/patch/kernel/rockchip64-current/board-firefly-rk3399-fix-gpu-power.patch new file mode 100644 index 0000000000..8e6b237ca5 --- /dev/null +++ b/patch/kernel/rockchip64-current/board-firefly-rk3399-fix-gpu-power.patch @@ -0,0 +1,25 @@ +From 2345073b11f6bfa5faa2e514b9d4ca03157e5149 Mon Sep 17 00:00:00 2001 +From: Michal Lazo +Date: Mon, 6 Jan 2020 14:52:00 -0800 +Subject: [PATCH 1/1] mali power fix + +--- + arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +index c706db0ee..0fd8ef955 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +@@ -803,3 +803,8 @@ + &vopl_mmu { + status = "okay"; + }; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; +-- +2.17.1 + diff --git a/patch/kernel/rockchip64-dev/board-firefly-rk3399-fix-gpu-power.patch b/patch/kernel/rockchip64-dev/board-firefly-rk3399-fix-gpu-power.patch new file mode 100644 index 0000000000..8e6b237ca5 --- /dev/null +++ b/patch/kernel/rockchip64-dev/board-firefly-rk3399-fix-gpu-power.patch @@ -0,0 +1,25 @@ +From 2345073b11f6bfa5faa2e514b9d4ca03157e5149 Mon Sep 17 00:00:00 2001 +From: Michal Lazo +Date: Mon, 6 Jan 2020 14:52:00 -0800 +Subject: [PATCH 1/1] mali power fix + +--- + arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +index c706db0ee..0fd8ef955 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +@@ -803,3 +803,8 @@ + &vopl_mmu { + status = "okay"; + }; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; +-- +2.17.1 + From 76a61a0d1ec376d1283f1219f3012b16e6f64195 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Tue, 7 Jan 2020 13:01:07 -0500 Subject: [PATCH 11/12] fix fix-usb1-vbus-opiwin.patch and re-enable it --- ...n.patch.disabled => fix-usb1-vbus-opiwin.patch} | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) rename patch/u-boot/u-boot-sunxi/{fix-usb1-vbus-opiwin.patch.disabled => fix-usb1-vbus-opiwin.patch} (87%) diff --git a/patch/u-boot/u-boot-sunxi/fix-usb1-vbus-opiwin.patch.disabled b/patch/u-boot/u-boot-sunxi/fix-usb1-vbus-opiwin.patch similarity index 87% rename from patch/u-boot/u-boot-sunxi/fix-usb1-vbus-opiwin.patch.disabled rename to patch/u-boot/u-boot-sunxi/fix-usb1-vbus-opiwin.patch index 18436a503e..261ac44193 100644 --- a/patch/u-boot/u-boot-sunxi/fix-usb1-vbus-opiwin.patch.disabled +++ b/patch/u-boot/u-boot-sunxi/fix-usb1-vbus-opiwin.patch @@ -38,8 +38,8 @@ index cf76c35..a7d36a5 100644 }; &ehci1 { -@@ -83,6 +96,13 @@ - status = "okay"; +@@ -180,6 +222,13 @@ + status = "okay"; }; +&pio { @@ -49,14 +49,6 @@ index cf76c35..a7d36a5 100644 + }; +}; + - &uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; -@@ -198,6 +198,7 @@ - }; - - &usbphy { -+ usb1_vbus-supply = <®_usb1_vbus>; + &r_rsb { status = "okay"; - }; From f0e5086f972bf299c5e8363679a489e4e5f013bc Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Tue, 7 Jan 2020 19:42:21 +0100 Subject: [PATCH 12/12] Bump with version of freshly recreated rootfs cache --- lib/configuration.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/configuration.sh b/lib/configuration.sh index 32851d0ad5..2f48c66c24 100644 --- a/lib/configuration.sh +++ b/lib/configuration.sh @@ -20,7 +20,7 @@ TZDATA=$(cat /etc/timezone) # Timezone for target is taken from host or defined USEALLCORES=yes # Use all CPU cores for compiling EXIT_PATCHING_ERROR="" # exit patching if failed [[ -z $HOST ]] && HOST="$(echo "$BOARD" | cut -f1 -d-)" # set hostname to the board -ROOTFSCACHE_VERSION=15 +ROOTFSCACHE_VERSION=16 CHROOT_CACHE_VERSION=7 BUILD_REPOSITORY_URL=$(git remote get-url $(git remote 2>/dev/null) 2>/dev/null) BUILD_REPOSITORY_COMMIT=$(git describe --match=d_e_a_d_b_e_e_f --always --dirty 2>/dev/null)