public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:6.0 commit in: /
Date: Fri,  2 Dec 2022 17:23:45 +0000 (UTC)	[thread overview]
Message-ID: <1670001814.6bdec7c135eddb0a34e89f2eac3ef9628666542b.mpagano@gentoo> (raw)

commit:     6bdec7c135eddb0a34e89f2eac3ef9628666542b
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Dec  2 17:23:34 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Dec  2 17:23:34 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6bdec7c1

Linux patch 6.0.11

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README             |     4 +
 1010_linux-6.0.11.patch | 10345 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 10349 insertions(+)

diff --git a/0000_README b/0000_README
index bf26e8c8..12c46dfc 100644
--- a/0000_README
+++ b/0000_README
@@ -83,6 +83,10 @@ Patch:  1009_linux-6.0.10.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.10
 
+Patch:  1010_linux-6.0.11.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.11
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1010_linux-6.0.11.patch b/1010_linux-6.0.11.patch
new file mode 100644
index 00000000..43ca90bb
--- /dev/null
+++ b/1010_linux-6.0.11.patch
@@ -0,0 +1,10345 @@
+diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
+index b283c8ca2bbfc..5c08d8b6e9951 100644
+--- a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
++++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
+@@ -62,13 +62,6 @@ properties:
+     description:
+       Inform the driver that last channel will be used to sensor battery.
+ 
+-  aspeed,trim-data-valid:
+-    type: boolean
+-    description: |
+-      The ADC reference voltage can be calibrated to obtain the trimming
+-      data which will be stored in otp. This property informs the driver that
+-      the data store in the otp is valid.
+-
+ required:
+   - compatible
+   - reg
+diff --git a/Makefile b/Makefile
+index 4f7da26fef784..9fecb094c28a2 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 10
++SUBLEVEL = 11
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm/boot/dts/am335x-pcm-953.dtsi b/arch/arm/boot/dts/am335x-pcm-953.dtsi
+index dae448040a97b..9474974139778 100644
+--- a/arch/arm/boot/dts/am335x-pcm-953.dtsi
++++ b/arch/arm/boot/dts/am335x-pcm-953.dtsi
+@@ -12,22 +12,20 @@
+ 	compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx";
+ 
+ 	/* Power */
+-	regulators {
+-		vcc3v3: fixedregulator@1 {
+-			compatible = "regulator-fixed";
+-			regulator-name = "vcc3v3";
+-			regulator-min-microvolt = <3300000>;
+-			regulator-max-microvolt = <3300000>;
+-			regulator-boot-on;
+-		};
++	vcc3v3: fixedregulator1 {
++		compatible = "regulator-fixed";
++		regulator-name = "vcc3v3";
++		regulator-min-microvolt = <3300000>;
++		regulator-max-microvolt = <3300000>;
++		regulator-boot-on;
++	};
+ 
+-		vcc1v8: fixedregulator@2 {
+-			compatible = "regulator-fixed";
+-			regulator-name = "vcc1v8";
+-			regulator-min-microvolt = <1800000>;
+-			regulator-max-microvolt = <1800000>;
+-			regulator-boot-on;
+-		};
++	vcc1v8: fixedregulator2 {
++		compatible = "regulator-fixed";
++		regulator-name = "vcc1v8";
++		regulator-min-microvolt = <1800000>;
++		regulator-max-microvolt = <1800000>;
++		regulator-boot-on;
+ 	};
+ 
+ 	/* User IO */
+diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+index 60d61291f3444..024af2db638eb 100644
+--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
++++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+@@ -39,6 +39,13 @@
+ 
+ 				};
+ 
++				usb1 {
++					pinctrl_usb1_vbus_gpio: usb1_vbus_gpio {
++						atmel,pins =
++							<AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;	/* PC5 GPIO */
++					};
++				};
++
+ 				mmc0_slot1 {
+ 					pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+ 						atmel,pins =
+@@ -84,6 +91,8 @@
+ 			};
+ 
+ 			usb1: gadget@fffa4000 {
++				pinctrl-0 = <&pinctrl_usb1_vbus_gpio>;
++				pinctrl-names = "default";
+ 				atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+ 				status = "okay";
+ 			};
+diff --git a/arch/arm/boot/dts/imx6q-prti6q.dts b/arch/arm/boot/dts/imx6q-prti6q.dts
+index b4605edfd2ab8..d8fa83effd638 100644
+--- a/arch/arm/boot/dts/imx6q-prti6q.dts
++++ b/arch/arm/boot/dts/imx6q-prti6q.dts
+@@ -364,8 +364,8 @@
+ 		pinctrl-names = "default";
+ 		pinctrl-0 = <&pinctrl_wifi>;
+ 		interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>;
+-		ref-clock-frequency = "38400000";
+-		tcxo-clock-frequency = "19200000";
++		ref-clock-frequency = <38400000>;
++		tcxo-clock-frequency = <19200000>;
+ 	};
+ };
+ 
+diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
+index 25c9d184fa4c6..1c57ac4016493 100644
+--- a/arch/arm/mach-mxs/mach-mxs.c
++++ b/arch/arm/mach-mxs/mach-mxs.c
+@@ -393,8 +393,10 @@ static void __init mxs_machine_init(void)
+ 
+ 	root = of_find_node_by_path("/");
+ 	ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+-	if (ret)
++	if (ret) {
++		kfree(soc_dev_attr);
+ 		return;
++	}
+ 
+ 	soc_dev_attr->family = "Freescale MXS Family";
+ 	soc_dev_attr->soc_id = mxs_get_soc_id();
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+index 04c752f49be98..115c14c0a3c68 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+@@ -207,7 +207,7 @@
+ 	cap-sd-highspeed;
+ 	cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+ 	disable-wp;
+-	max-frequency = <150000000>;
++	max-frequency = <40000000>;
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ 	vmmc-supply = <&vcc3v3_baseboard>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+index a05460b924153..25a8c781f4e75 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+@@ -740,7 +740,7 @@
+ 
+ &uart1 {
+ 	pinctrl-names = "default";
+-	pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn>;
++	pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
+ 	status = "okay";
+ 	uart-has-rtscts;
+ 
+@@ -748,13 +748,14 @@
+ 		compatible = "brcm,bcm43438-bt";
+ 		clocks = <&rk817 1>;
+ 		clock-names = "lpo";
+-		device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
+-		host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
++		host-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
++		device-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
+ 		shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ 		pinctrl-names = "default";
+ 		pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
+ 		vbat-supply = <&vcc_sys>;
+ 		vddio-supply = <&vcca1v8_pmu>;
++		max-speed = <3000000>;
+ 	};
+ };
+ 
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
+index 528bb4e8ac776..a2d0524e0ec90 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
+@@ -176,7 +176,7 @@
+ 		compatible = "rockchip,rk809";
+ 		reg = <0x20>;
+ 		interrupt-parent = <&gpio0>;
+-		interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>;
++		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ 		clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ 
+ 		pinctrl-names = "default";
+diff --git a/arch/arm64/include/asm/syscall_wrapper.h b/arch/arm64/include/asm/syscall_wrapper.h
+index b383b4802a7bd..d30217c21eff7 100644
+--- a/arch/arm64/include/asm/syscall_wrapper.h
++++ b/arch/arm64/include/asm/syscall_wrapper.h
+@@ -8,7 +8,7 @@
+ #ifndef __ASM_SYSCALL_WRAPPER_H
+ #define __ASM_SYSCALL_WRAPPER_H
+ 
+-struct pt_regs;
++#include <asm/ptrace.h>
+ 
+ #define SC_ARM64_REGS_TO_ARGS(x, ...)				\
+ 	__MAP(x,__SC_ARGS					\
+diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
+index 8ea57e2f0e04c..cc0674d1b8f0f 100644
+--- a/arch/loongarch/include/asm/pgtable.h
++++ b/arch/loongarch/include/asm/pgtable.h
+@@ -349,7 +349,9 @@ static inline pte_t pte_mkclean(pte_t pte)
+ 
+ static inline pte_t pte_mkdirty(pte_t pte)
+ {
+-	pte_val(pte) |= (_PAGE_DIRTY | _PAGE_MODIFIED);
++	pte_val(pte) |= _PAGE_MODIFIED;
++	if (pte_val(pte) & _PAGE_WRITE)
++		pte_val(pte) |= _PAGE_DIRTY;
+ 	return pte;
+ }
+ 
+@@ -475,7 +477,9 @@ static inline pmd_t pmd_mkclean(pmd_t pmd)
+ 
+ static inline pmd_t pmd_mkdirty(pmd_t pmd)
+ {
+-	pmd_val(pmd) |= (_PAGE_DIRTY | _PAGE_MODIFIED);
++	pmd_val(pmd) |= _PAGE_MODIFIED;
++	if (pmd_val(pmd) & _PAGE_WRITE)
++		pmd_val(pmd) |= _PAGE_DIRTY;
+ 	return pmd;
+ }
+ 
+diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
+index 660492f064e7e..6ae7c669ee642 100644
+--- a/arch/loongarch/kernel/process.c
++++ b/arch/loongarch/kernel/process.c
+@@ -152,7 +152,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
+ 		childregs->csr_crmd = p->thread.csr_crmd;
+ 		childregs->csr_prmd = p->thread.csr_prmd;
+ 		childregs->csr_ecfg = p->thread.csr_ecfg;
+-		return 0;
++		goto out;
+ 	}
+ 
+ 	/* user thread */
+@@ -171,14 +171,15 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
+ 	 */
+ 	childregs->csr_euen = 0;
+ 
++	if (clone_flags & CLONE_SETTLS)
++		childregs->regs[2] = tls;
++
++out:
+ 	clear_tsk_thread_flag(p, TIF_USEDFPU);
+ 	clear_tsk_thread_flag(p, TIF_USEDSIMD);
+ 	clear_tsk_thread_flag(p, TIF_LSX_CTX_LIVE);
+ 	clear_tsk_thread_flag(p, TIF_LASX_CTX_LIVE);
+ 
+-	if (clone_flags & CLONE_SETTLS)
+-		childregs->regs[2] = tls;
+-
+ 	return 0;
+ }
+ 
+diff --git a/arch/mips/include/asm/fw/fw.h b/arch/mips/include/asm/fw/fw.h
+index d0ef8b4892bbe..d0494ce4b3373 100644
+--- a/arch/mips/include/asm/fw/fw.h
++++ b/arch/mips/include/asm/fw/fw.h
+@@ -26,6 +26,6 @@ extern char *fw_getcmdline(void);
+ extern void fw_meminit(void);
+ extern char *fw_getenv(char *name);
+ extern unsigned long fw_getenvl(char *name);
+-extern void fw_init_early_console(char port);
++extern void fw_init_early_console(void);
+ 
+ #endif /* __ASM_FW_H_ */
+diff --git a/arch/mips/pic32/pic32mzda/early_console.c b/arch/mips/pic32/pic32mzda/early_console.c
+index 25372e62783b5..3cd1b408fa1cb 100644
+--- a/arch/mips/pic32/pic32mzda/early_console.c
++++ b/arch/mips/pic32/pic32mzda/early_console.c
+@@ -27,7 +27,7 @@
+ #define U_BRG(x)	(UART_BASE(x) + 0x40)
+ 
+ static void __iomem *uart_base;
+-static char console_port = -1;
++static int console_port = -1;
+ 
+ static int __init configure_uart_pins(int port)
+ {
+@@ -47,7 +47,7 @@ static int __init configure_uart_pins(int port)
+ 	return 0;
+ }
+ 
+-static void __init configure_uart(char port, int baud)
++static void __init configure_uart(int port, int baud)
+ {
+ 	u32 pbclk;
+ 
+@@ -60,7 +60,7 @@ static void __init configure_uart(char port, int baud)
+ 		     uart_base + PIC32_SET(U_STA(port)));
+ }
+ 
+-static void __init setup_early_console(char port, int baud)
++static void __init setup_early_console(int port, int baud)
+ {
+ 	if (configure_uart_pins(port))
+ 		return;
+@@ -130,16 +130,15 @@ _out:
+ 	return baud;
+ }
+ 
+-void __init fw_init_early_console(char port)
++void __init fw_init_early_console(void)
+ {
+ 	char *arch_cmdline = pic32_getcmdline();
+-	int baud = -1;
++	int baud, port;
+ 
+ 	uart_base = ioremap(PIC32_BASE_UART, 0xc00);
+ 
+ 	baud = get_baud_from_cmdline(arch_cmdline);
+-	if (port == -1)
+-		port = get_port_from_cmdline(arch_cmdline);
++	port = get_port_from_cmdline(arch_cmdline);
+ 
+ 	if (port == -1)
+ 		port = EARLY_CONSOLE_PORT;
+diff --git a/arch/mips/pic32/pic32mzda/init.c b/arch/mips/pic32/pic32mzda/init.c
+index d9c8c4e46aff9..58d8ca730df73 100644
+--- a/arch/mips/pic32/pic32mzda/init.c
++++ b/arch/mips/pic32/pic32mzda/init.c
+@@ -47,7 +47,7 @@ void __init plat_mem_setup(void)
+ 		strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+ 
+ #ifdef CONFIG_EARLY_PRINTK
+-	fw_init_early_console(-1);
++	fw_init_early_console();
+ #endif
+ 	pic32_config_init();
+ }
+diff --git a/arch/nios2/boot/Makefile b/arch/nios2/boot/Makefile
+index 8c3ad76602f3e..29c11a06b750a 100644
+--- a/arch/nios2/boot/Makefile
++++ b/arch/nios2/boot/Makefile
+@@ -20,7 +20,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
+ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
+ 	$(call if_changed,gzip)
+ 
+-$(obj)/vmImage: $(obj)/vmlinux.gz
++$(obj)/vmImage: $(obj)/vmlinux.gz FORCE
+ 	$(call if_changed,uimage)
+ 	@$(kecho) 'Kernel: $@ is ready'
+ 
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+index ced0d4e479385..900a50526d771 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+@@ -3,6 +3,8 @@
+ 
+ #include "fu540-c000.dtsi"
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pwm/pwm.h>
+ 
+ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
+ #define RTCCLK_FREQ		1000000
+@@ -42,6 +44,42 @@
+ 		compatible = "gpio-restart";
+ 		gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+ 	};
++
++	led-controller {
++		compatible = "pwm-leds";
++
++		led-d1 {
++			pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
++			active-low;
++			color = <LED_COLOR_ID_GREEN>;
++			max-brightness = <255>;
++			label = "d1";
++		};
++
++		led-d2 {
++			pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
++			active-low;
++			color = <LED_COLOR_ID_GREEN>;
++			max-brightness = <255>;
++			label = "d2";
++		};
++
++		led-d3 {
++			pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
++			active-low;
++			color = <LED_COLOR_ID_GREEN>;
++			max-brightness = <255>;
++			label = "d3";
++		};
++
++		led-d4 {
++			pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
++			active-low;
++			color = <LED_COLOR_ID_GREEN>;
++			max-brightness = <255>;
++			label = "d4";
++		};
++	};
+ };
+ 
+ &uart0 {
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
+index 84ac0fe612e79..db6548509bb3e 100644
+--- a/arch/riscv/kernel/vdso/Makefile
++++ b/arch/riscv/kernel/vdso/Makefile
+@@ -28,6 +28,9 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+ 
+ obj-y += vdso.o
+ CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
++ifneq ($(filter vgettimeofday, $(vdso-syms)),)
++CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY
++endif
+ 
+ # Disable -pg to prevent insert call site
+ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S
+index 01d94aae5bf51..150b1a572e619 100644
+--- a/arch/riscv/kernel/vdso/vdso.lds.S
++++ b/arch/riscv/kernel/vdso/vdso.lds.S
+@@ -68,9 +68,11 @@ VERSION
+ 	LINUX_4.15 {
+ 	global:
+ 		__vdso_rt_sigreturn;
++#ifdef HAS_VGETTIMEOFDAY
+ 		__vdso_gettimeofday;
+ 		__vdso_clock_gettime;
+ 		__vdso_clock_getres;
++#endif
+ 		__vdso_getcpu;
+ 		__vdso_flush_icache;
+ 	local: *;
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 318fce77601d3..de575af02ffea 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -568,8 +568,7 @@ config EXPOLINE_FULL
+ endchoice
+ 
+ config RELOCATABLE
+-	bool "Build a relocatable kernel"
+-	default y
++	def_bool y
+ 	help
+ 	  This builds a kernel image that retains relocation information
+ 	  so it can be loaded at an arbitrary address.
+@@ -578,10 +577,11 @@ config RELOCATABLE
+ 	  bootup process.
+ 	  The relocations make the kernel image about 15% larger (compressed
+ 	  10%), but are discarded at runtime.
++	  Note: this option exists only for documentation purposes, please do
++	  not remove it.
+ 
+ config RANDOMIZE_BASE
+ 	bool "Randomize the address of the kernel image (KASLR)"
+-	depends on RELOCATABLE
+ 	default y
+ 	help
+ 	  In support of Kernel Address Space Layout Randomization (KASLR),
+diff --git a/arch/s390/Makefile b/arch/s390/Makefile
+index 4cb5d17e7ead6..47bec926d6c09 100644
+--- a/arch/s390/Makefile
++++ b/arch/s390/Makefile
+@@ -14,10 +14,8 @@ KBUILD_AFLAGS_MODULE += -fPIC
+ KBUILD_CFLAGS_MODULE += -fPIC
+ KBUILD_AFLAGS	+= -m64
+ KBUILD_CFLAGS	+= -m64
+-ifeq ($(CONFIG_RELOCATABLE),y)
+ KBUILD_CFLAGS	+= -fPIE
+ LDFLAGS_vmlinux	:= -pie
+-endif
+ aflags_dwarf	:= -Wa,-gdwarf-2
+ KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__
+ ifndef CONFIG_AS_IS_LLVM
+diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
+index 883357a211a3b..d52c3e2e16bc5 100644
+--- a/arch/s390/boot/Makefile
++++ b/arch/s390/boot/Makefile
+@@ -37,9 +37,8 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
+ 
+ obj-y	:= head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
+ obj-y	+= string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
+-obj-y	+= version.o pgm_check_info.o ctype.o ipl_data.o
++obj-y	+= version.o pgm_check_info.o ctype.o ipl_data.o machine_kexec_reloc.o
+ obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE))	+= uv.o
+-obj-$(CONFIG_RELOCATABLE)	+= machine_kexec_reloc.o
+ obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
+ obj-y	+= $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
+ obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
+diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
+index bc48fe82d949a..e5026e1d277fb 100644
+--- a/arch/s390/boot/startup.c
++++ b/arch/s390/boot/startup.c
+@@ -285,8 +285,7 @@ void startup_kernel(void)
+ 
+ 	clear_bss_section();
+ 	copy_bootdata();
+-	if (IS_ENABLED(CONFIG_RELOCATABLE))
+-		handle_relocs(__kaslr_offset);
++	handle_relocs(__kaslr_offset);
+ 
+ 	if (__kaslr_offset) {
+ 		/*
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index bad8f47fc5d69..c1b2b0d4af773 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -45,7 +45,7 @@ struct save_area {
+ 	u64 fprs[16];
+ 	u32 fpc;
+ 	u32 prefix;
+-	u64 todpreg;
++	u32 todpreg;
+ 	u64 timer;
+ 	u64 todcmp;
+ 	u64 vxrs_low[16];
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index 3de6d8b533672..a0165df3c4d8c 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -77,7 +77,7 @@ static int hyperv_init_ghcb(void)
+ static int hv_cpu_init(unsigned int cpu)
+ {
+ 	union hv_vp_assist_msr_contents msr = { 0 };
+-	struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];
++	struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu];
+ 	int ret;
+ 
+ 	ret = hv_common_cpu_init(cpu);
+@@ -87,34 +87,32 @@ static int hv_cpu_init(unsigned int cpu)
+ 	if (!hv_vp_assist_page)
+ 		return 0;
+ 
+-	if (!*hvp) {
+-		if (hv_root_partition) {
+-			/*
+-			 * For root partition we get the hypervisor provided VP assist
+-			 * page, instead of allocating a new page.
+-			 */
+-			rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+-			*hvp = memremap(msr.pfn <<
+-					HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
+-					PAGE_SIZE, MEMREMAP_WB);
+-		} else {
+-			/*
+-			 * The VP assist page is an "overlay" page (see Hyper-V TLFS's
+-			 * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
+-			 * out to make sure we always write the EOI MSR in
+-			 * hv_apic_eoi_write() *after* the EOI optimization is disabled
+-			 * in hv_cpu_die(), otherwise a CPU may not be stopped in the
+-			 * case of CPU offlining and the VM will hang.
+-			 */
++	if (hv_root_partition) {
++		/*
++		 * For root partition we get the hypervisor provided VP assist
++		 * page, instead of allocating a new page.
++		 */
++		rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
++		*hvp = memremap(msr.pfn << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
++				PAGE_SIZE, MEMREMAP_WB);
++	} else {
++		/*
++		 * The VP assist page is an "overlay" page (see Hyper-V TLFS's
++		 * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
++		 * out to make sure we always write the EOI MSR in
++		 * hv_apic_eoi_write() *after* the EOI optimization is disabled
++		 * in hv_cpu_die(), otherwise a CPU may not be stopped in the
++		 * case of CPU offlining and the VM will hang.
++		 */
++		if (!*hvp)
+ 			*hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO);
+-			if (*hvp)
+-				msr.pfn = vmalloc_to_pfn(*hvp);
+-		}
+-		WARN_ON(!(*hvp));
+-		if (*hvp) {
+-			msr.enable = 1;
+-			wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+-		}
++		if (*hvp)
++			msr.pfn = vmalloc_to_pfn(*hvp);
++
++	}
++	if (!WARN_ON(!(*hvp))) {
++		msr.enable = 1;
++		wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+ 	}
+ 
+ 	return hyperv_init_ghcb();
+diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
+index ef4775c6db01c..dfa672bec6109 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -305,6 +305,9 @@
+ #define X86_FEATURE_USE_IBPB_FW		(11*32+16) /* "" Use IBPB during runtime firmware calls */
+ #define X86_FEATURE_RSB_VMEXIT_LITE	(11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */
+ 
++
++#define X86_FEATURE_MSR_TSX_CTRL	(11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */
++
+ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
+ #define X86_FEATURE_AVX_VNNI		(12*32+ 4) /* AVX VNNI instructions */
+ #define X86_FEATURE_AVX512_BF16		(12*32+ 5) /* AVX512 BFLOAT16 instructions */
+diff --git a/arch/x86/kernel/cpu/tsx.c b/arch/x86/kernel/cpu/tsx.c
+index ec7bbac3a9f29..8009c8346d8f8 100644
+--- a/arch/x86/kernel/cpu/tsx.c
++++ b/arch/x86/kernel/cpu/tsx.c
+@@ -58,24 +58,6 @@ static void tsx_enable(void)
+ 	wrmsrl(MSR_IA32_TSX_CTRL, tsx);
+ }
+ 
+-static bool tsx_ctrl_is_supported(void)
+-{
+-	u64 ia32_cap = x86_read_arch_cap_msr();
+-
+-	/*
+-	 * TSX is controlled via MSR_IA32_TSX_CTRL.  However, support for this
+-	 * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
+-	 *
+-	 * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
+-	 * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
+-	 * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
+-	 * MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
+-	 * tsx= cmdline requests will do nothing on CPUs without
+-	 * MSR_IA32_TSX_CTRL support.
+-	 */
+-	return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);
+-}
+-
+ static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
+ {
+ 	if (boot_cpu_has_bug(X86_BUG_TAA))
+@@ -135,7 +117,7 @@ static void tsx_clear_cpuid(void)
+ 		rdmsrl(MSR_TSX_FORCE_ABORT, msr);
+ 		msr |= MSR_TFA_TSX_CPUID_CLEAR;
+ 		wrmsrl(MSR_TSX_FORCE_ABORT, msr);
+-	} else if (tsx_ctrl_is_supported()) {
++	} else if (cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL)) {
+ 		rdmsrl(MSR_IA32_TSX_CTRL, msr);
+ 		msr |= TSX_CTRL_CPUID_CLEAR;
+ 		wrmsrl(MSR_IA32_TSX_CTRL, msr);
+@@ -158,7 +140,8 @@ static void tsx_dev_mode_disable(void)
+ 	u64 mcu_opt_ctrl;
+ 
+ 	/* Check if RTM_ALLOW exists */
+-	if (!boot_cpu_has_bug(X86_BUG_TAA) || !tsx_ctrl_is_supported() ||
++	if (!boot_cpu_has_bug(X86_BUG_TAA) ||
++	    !cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL) ||
+ 	    !cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL))
+ 		return;
+ 
+@@ -191,7 +174,20 @@ void __init tsx_init(void)
+ 		return;
+ 	}
+ 
+-	if (!tsx_ctrl_is_supported()) {
++	/*
++	 * TSX is controlled via MSR_IA32_TSX_CTRL.  However, support for this
++	 * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
++	 *
++	 * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
++	 * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
++	 * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
++	 * MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
++	 * tsx= cmdline requests will do nothing on CPUs without
++	 * MSR_IA32_TSX_CTRL support.
++	 */
++	if (x86_read_arch_cap_msr() & ARCH_CAP_TSX_CTRL_MSR) {
++		setup_force_cpu_cap(X86_FEATURE_MSR_TSX_CTRL);
++	} else {
+ 		tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED;
+ 		return;
+ 	}
+diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
+index 83e30e4db2ae0..0a163ba9fa1a2 100644
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -2431,6 +2431,7 @@ static bool __kvm_mmu_prepare_zap_page(struct kvm *kvm,
+ {
+ 	bool list_unstable, zapped_root = false;
+ 
++	lockdep_assert_held_write(&kvm->mmu_lock);
+ 	trace_kvm_mmu_prepare_zap_page(sp);
+ 	++kvm->stat.mmu_shadow_zapped;
+ 	*nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list);
+@@ -4250,14 +4251,14 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
+ 	if (is_page_fault_stale(vcpu, fault, mmu_seq))
+ 		goto out_unlock;
+ 
+-	r = make_mmu_pages_available(vcpu);
+-	if (r)
+-		goto out_unlock;
+-
+-	if (is_tdp_mmu_fault)
++	if (is_tdp_mmu_fault) {
+ 		r = kvm_tdp_mmu_map(vcpu, fault);
+-	else
++	} else {
++		r = make_mmu_pages_available(vcpu);
++		if (r)
++			goto out_unlock;
+ 		r = __direct_map(vcpu, fault);
++	}
+ 
+ out_unlock:
+ 	if (is_tdp_mmu_fault)
+diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
+index 76dcc8a3e8496..630359bce06d4 100644
+--- a/arch/x86/kvm/svm/nested.c
++++ b/arch/x86/kvm/svm/nested.c
+@@ -1143,6 +1143,9 @@ void svm_free_nested(struct vcpu_svm *svm)
+ 	if (!svm->nested.initialized)
+ 		return;
+ 
++	if (WARN_ON_ONCE(svm->vmcb != svm->vmcb01.ptr))
++		svm_switch_vmcb(svm, &svm->vmcb01);
++
+ 	svm_vcpu_free_msrpm(svm->nested.msrpm);
+ 	svm->nested.msrpm = NULL;
+ 
+@@ -1161,9 +1164,6 @@ void svm_free_nested(struct vcpu_svm *svm)
+ 	svm->nested.initialized = false;
+ }
+ 
+-/*
+- * Forcibly leave nested mode in order to be able to reset the VCPU later on.
+- */
+ void svm_leave_nested(struct kvm_vcpu *vcpu)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index e80756ab141bf..6431019d0eff0 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -346,12 +346,6 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
+ 	return 0;
+ }
+ 
+-static int is_external_interrupt(u32 info)
+-{
+-	info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
+-	return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
+-}
+-
+ static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+@@ -1440,6 +1434,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
+ 	 */
+ 	svm_clear_current_vmcb(svm->vmcb);
+ 
++	svm_leave_nested(vcpu);
+ 	svm_free_nested(svm);
+ 
+ 	sev_free_vcpu(vcpu);
+@@ -3426,15 +3421,6 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
+ 		return 0;
+ 	}
+ 
+-	if (is_external_interrupt(svm->vmcb->control.exit_int_info) &&
+-	    exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR &&
+-	    exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH &&
+-	    exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI)
+-		printk(KERN_ERR "%s: unexpected exit_int_info 0x%x "
+-		       "exit_code 0x%x\n",
+-		       __func__, svm->vmcb->control.exit_int_info,
+-		       exit_code);
+-
+ 	if (exit_fastpath != EXIT_FASTPATH_NONE)
+ 		return 1;
+ 
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 03d348fa6485a..f56cc2382edf9 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -6294,9 +6294,6 @@ out:
+ 	return kvm_state.size;
+ }
+ 
+-/*
+- * Forcibly leave nested mode in order to be able to reset the VCPU later on.
+- */
+ void vmx_leave_nested(struct kvm_vcpu *vcpu)
+ {
+ 	if (is_guest_mode(vcpu)) {
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 71cbafd67319b..5d38409913a9d 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -611,6 +611,12 @@ void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu)
+ }
+ EXPORT_SYMBOL_GPL(kvm_deliver_exception_payload);
+ 
++/* Forcibly leave the nested mode in cases like a vCPU reset */
++static void kvm_leave_nested(struct kvm_vcpu *vcpu)
++{
++	kvm_x86_ops.nested_ops->leave_nested(vcpu);
++}
++
+ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
+ 		unsigned nr, bool has_error, u32 error_code,
+ 	        bool has_payload, unsigned long payload, bool reinject)
+@@ -5154,7 +5160,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
+ 
+ 	if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
+ 		if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
+-			kvm_x86_ops.nested_ops->leave_nested(vcpu);
++			kvm_leave_nested(vcpu);
+ 			kvm_smm_changed(vcpu, events->smi.smm);
+ 		}
+ 
+@@ -11789,8 +11795,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
+ 	WARN_ON_ONCE(!init_event &&
+ 		     (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu)));
+ 
++	/*
++	 * SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's
++	 * possible to INIT the vCPU while L2 is active.  Force the vCPU back
++	 * into L1 as EFER.SVME is cleared on INIT (along with all other EFER
++	 * bits), i.e. virtualization is disabled.
++	 */
++	if (is_guest_mode(vcpu))
++		kvm_leave_nested(vcpu);
++
+ 	kvm_lapic_reset(vcpu, init_event);
+ 
++	WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
+ 	vcpu->arch.hflags = 0;
+ 
+ 	vcpu->arch.smi_pending = 0;
+diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
+index 9a1950879fc44..8333b6c50e93c 100644
+--- a/arch/x86/kvm/xen.c
++++ b/arch/x86/kvm/xen.c
+@@ -954,6 +954,14 @@ static int kvm_xen_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
+ 	return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result);
+ }
+ 
++static inline int max_evtchn_port(struct kvm *kvm)
++{
++	if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
++		return EVTCHN_2L_NR_CHANNELS;
++	else
++		return COMPAT_EVTCHN_2L_NR_CHANNELS;
++}
++
+ static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports,
+ 			       evtchn_port_t *ports)
+ {
+@@ -1042,6 +1050,10 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
+ 			*r = -EFAULT;
+ 			goto out;
+ 		}
++		if (ports[i] >= max_evtchn_port(vcpu->kvm)) {
++			*r = -EINVAL;
++			goto out;
++		}
+ 	}
+ 
+ 	if (sched_poll.nr_ports == 1)
+@@ -1216,6 +1228,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ 	bool longmode;
+ 	u64 input, params[6], r = -ENOSYS;
+ 	bool handled = false;
++	u8 cpl;
+ 
+ 	input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX);
+ 
+@@ -1243,9 +1256,17 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ 		params[5] = (u64)kvm_r9_read(vcpu);
+ 	}
+ #endif
++	cpl = static_call(kvm_x86_get_cpl)(vcpu);
+ 	trace_kvm_xen_hypercall(input, params[0], params[1], params[2],
+ 				params[3], params[4], params[5]);
+ 
++	/*
++	 * Only allow hypercall acceleration for CPL0. The rare hypercalls that
++	 * are permitted in guest userspace can be handled by the VMM.
++	 */
++	if (unlikely(cpl > 0))
++		goto handle_in_userspace;
++
+ 	switch (input) {
+ 	case __HYPERVISOR_xen_version:
+ 		if (params[0] == XENVER_version && vcpu->kvm->arch.xen.xen_version) {
+@@ -1280,10 +1301,11 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ 	if (handled)
+ 		return kvm_xen_hypercall_set_result(vcpu, r);
+ 
++handle_in_userspace:
+ 	vcpu->run->exit_reason = KVM_EXIT_XEN;
+ 	vcpu->run->xen.type = KVM_EXIT_XEN_HCALL;
+ 	vcpu->run->xen.u.hcall.longmode = longmode;
+-	vcpu->run->xen.u.hcall.cpl = static_call(kvm_x86_get_cpl)(vcpu);
++	vcpu->run->xen.u.hcall.cpl = cpl;
+ 	vcpu->run->xen.u.hcall.input = input;
+ 	vcpu->run->xen.u.hcall.params[0] = params[0];
+ 	vcpu->run->xen.u.hcall.params[1] = params[1];
+@@ -1298,14 +1320,6 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ 	return 0;
+ }
+ 
+-static inline int max_evtchn_port(struct kvm *kvm)
+-{
+-	if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
+-		return EVTCHN_2L_NR_CHANNELS;
+-	else
+-		return COMPAT_EVTCHN_2L_NR_CHANNELS;
+-}
+-
+ static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port)
+ {
+ 	int poll_evtchn = vcpu->arch.xen.poll_evtchn;
+diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
+index 1ad0228f8ceb9..19058d7466957 100644
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -216,9 +216,15 @@ __ioremap_caller(resource_size_t phys_addr, unsigned long size,
+ 	 * Mappings have to be page-aligned
+ 	 */
+ 	offset = phys_addr & ~PAGE_MASK;
+-	phys_addr &= PHYSICAL_PAGE_MASK;
++	phys_addr &= PAGE_MASK;
+ 	size = PAGE_ALIGN(last_addr+1) - phys_addr;
+ 
++	/*
++	 * Mask out any bits not part of the actual physical
++	 * address, like memory encryption bits.
++	 */
++	phys_addr &= PHYSICAL_PAGE_MASK;
++
+ 	retval = memtype_reserve(phys_addr, (u64)phys_addr + size,
+ 						pcm, &new_pcm);
+ 	if (retval) {
+diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
+index 4cd39f304e206..93ae33248f421 100644
+--- a/arch/x86/power/cpu.c
++++ b/arch/x86/power/cpu.c
+@@ -513,16 +513,23 @@ static int pm_cpu_check(const struct x86_cpu_id *c)
+ 
+ static void pm_save_spec_msr(void)
+ {
+-	u32 spec_msr_id[] = {
+-		MSR_IA32_SPEC_CTRL,
+-		MSR_IA32_TSX_CTRL,
+-		MSR_TSX_FORCE_ABORT,
+-		MSR_IA32_MCU_OPT_CTRL,
+-		MSR_AMD64_LS_CFG,
+-		MSR_AMD64_DE_CFG,
++	struct msr_enumeration {
++		u32 msr_no;
++		u32 feature;
++	} msr_enum[] = {
++		{ MSR_IA32_SPEC_CTRL,	 X86_FEATURE_MSR_SPEC_CTRL },
++		{ MSR_IA32_TSX_CTRL,	 X86_FEATURE_MSR_TSX_CTRL },
++		{ MSR_TSX_FORCE_ABORT,	 X86_FEATURE_TSX_FORCE_ABORT },
++		{ MSR_IA32_MCU_OPT_CTRL, X86_FEATURE_SRBDS_CTRL },
++		{ MSR_AMD64_LS_CFG,	 X86_FEATURE_LS_CFG_SSBD },
++		{ MSR_AMD64_DE_CFG,	 X86_FEATURE_LFENCE_RDTSC },
+ 	};
++	int i;
+ 
+-	msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id));
++	for (i = 0; i < ARRAY_SIZE(msr_enum); i++) {
++		if (boot_cpu_has(msr_enum[i].feature))
++			msr_build_context(&msr_enum[i].msr_no, 1);
++	}
+ }
+ 
+ static int pm_check_save_msr(void)
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+index 30b15a9a47c4f..249f489d115f0 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -615,6 +615,10 @@ struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio)
+ 	struct bfq_group *bfqg;
+ 
+ 	while (blkg) {
++		if (!blkg->online) {
++			blkg = blkg->parent;
++			continue;
++		}
+ 		bfqg = blkg_to_bfqg(blkg);
+ 		if (bfqg->online) {
+ 			bio_associate_blkg_from_css(bio, &blkg->blkcg->css);
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 4402e4ecb8b11..3f1f5e3e0951d 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -3956,9 +3956,14 @@ EXPORT_SYMBOL(__blk_mq_alloc_disk);
+ struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
+ 		struct lock_class_key *lkclass)
+ {
++	struct gendisk *disk;
++
+ 	if (!blk_get_queue(q))
+ 		return NULL;
+-	return __alloc_disk_node(q, NUMA_NO_NODE, lkclass);
++	disk = __alloc_disk_node(q, NUMA_NO_NODE, lkclass);
++	if (!disk)
++		blk_put_queue(q);
++	return disk;
+ }
+ EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue);
+ 
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 4949ed3ce7c95..8ac1038d0c797 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -59,7 +59,6 @@ void blk_set_default_limits(struct queue_limits *lim)
+ 	lim->zone_write_granularity = 0;
+ 	lim->dma_alignment = 511;
+ }
+-EXPORT_SYMBOL(blk_set_default_limits);
+ 
+ /**
+  * blk_set_stacking_limits - set default limits for stacking devices
+diff --git a/block/blk.h b/block/blk.h
+index 52432eab621e5..ff0bec16f0fa0 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -324,6 +324,7 @@ void blk_rq_set_mixed_merge(struct request *rq);
+ bool blk_rq_merge_ok(struct request *rq, struct bio *bio);
+ enum elv_merge blk_try_merge(struct request *rq, struct bio *bio);
+ 
++void blk_set_default_limits(struct queue_limits *lim);
+ int blk_dev_init(void);
+ 
+ /*
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 68a566f696845..aae9261c424a3 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -578,6 +578,20 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ 		DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
+ 		},
+ 	},
++	/*
++	 * Models which have nvidia-ec-wmi support, but should not use it.
++	 * Note this indicates a likely firmware bug on these models and should
++	 * be revisited if/when Linux gets support for dynamic mux mode.
++	 */
++	{
++	 .callback = video_detect_force_native,
++	 /* Dell G15 5515 */
++	 .matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++		DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
++		},
++	},
++
+ 	/*
+ 	 * Desktops which falsely report a backlight and which our heuristics
+ 	 * for this do not catch.
+diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
+index 9b1778c006103..64999777e0bf5 100644
+--- a/drivers/android/binder_alloc.c
++++ b/drivers/android/binder_alloc.c
+@@ -760,6 +760,12 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
+ 	const char *failure_string;
+ 	struct binder_buffer *buffer;
+ 
++	if (unlikely(vma->vm_mm != alloc->vma_vm_mm)) {
++		ret = -EINVAL;
++		failure_string = "invalid vma->vm_mm";
++		goto err_invalid_mm;
++	}
++
+ 	mutex_lock(&binder_alloc_mmap_lock);
+ 	if (alloc->buffer_size) {
+ 		ret = -EBUSY;
+@@ -806,6 +812,7 @@ err_alloc_pages_failed:
+ 	alloc->buffer_size = 0;
+ err_already_mapped:
+ 	mutex_unlock(&binder_alloc_mmap_lock);
++err_invalid_mm:
+ 	binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
+ 			   "%s: %d %lx-%lx %s failed %d\n", __func__,
+ 			   alloc->pid, vma->vm_start, vma->vm_end,
+diff --git a/drivers/bus/intel-ixp4xx-eb.c b/drivers/bus/intel-ixp4xx-eb.c
+index a4388440aca7a..91db001eb69a6 100644
+--- a/drivers/bus/intel-ixp4xx-eb.c
++++ b/drivers/bus/intel-ixp4xx-eb.c
+@@ -49,7 +49,7 @@
+ #define IXP4XX_EXP_SIZE_SHIFT		10
+ #define IXP4XX_EXP_CNFG_0		BIT(9) /* Always zero */
+ #define IXP43X_EXP_SYNC_INTEL		BIT(8) /* Only on IXP43x */
+-#define IXP43X_EXP_EXP_CHIP		BIT(7) /* Only on IXP43x */
++#define IXP43X_EXP_EXP_CHIP		BIT(7) /* Only on IXP43x, dangerous to touch on IXP42x */
+ #define IXP4XX_EXP_BYTE_RD16		BIT(6)
+ #define IXP4XX_EXP_HRDY_POL		BIT(5) /* Only on IXP42x */
+ #define IXP4XX_EXP_MUX_EN		BIT(4)
+@@ -57,8 +57,6 @@
+ #define IXP4XX_EXP_WORD			BIT(2) /* Always zero */
+ #define IXP4XX_EXP_WR_EN		BIT(1)
+ #define IXP4XX_EXP_BYTE_EN		BIT(0)
+-#define IXP42X_RESERVED			(BIT(30)|IXP4XX_EXP_CNFG_0|BIT(8)|BIT(7)|IXP4XX_EXP_WORD)
+-#define IXP43X_RESERVED			(BIT(30)|IXP4XX_EXP_CNFG_0|BIT(5)|IXP4XX_EXP_WORD)
+ 
+ #define IXP4XX_EXP_CNFG0		0x20
+ #define IXP4XX_EXP_CNFG0_MEM_MAP	BIT(31)
+@@ -252,10 +250,9 @@ static void ixp4xx_exp_setup_chipselect(struct ixp4xx_eb *eb,
+ 		cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT;
+ 	}
+ 
+-	if (eb->is_42x)
+-		cs_cfg &= ~IXP42X_RESERVED;
+ 	if (eb->is_43x) {
+-		cs_cfg &= ~IXP43X_RESERVED;
++		/* Should always be zero */
++		cs_cfg &= ~IXP4XX_EXP_WORD;
+ 		/*
+ 		 * This bit for Intel strata flash is currently unused, but let's
+ 		 * report it if we find one.
+diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
+index 4cd2e127946ea..3aa91aed3bf73 100644
+--- a/drivers/bus/sunxi-rsb.c
++++ b/drivers/bus/sunxi-rsb.c
+@@ -267,6 +267,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register);
+ /* common code that starts a transfer */
+ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ {
++	u32 int_mask, status;
++	bool timeout;
++
+ 	if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
+ 		dev_dbg(rsb->dev, "RSB transfer still in progress\n");
+ 		return -EBUSY;
+@@ -274,13 +277,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ 
+ 	reinit_completion(&rsb->complete);
+ 
+-	writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
+-	       rsb->regs + RSB_INTE);
++	int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER;
++	writel(int_mask, rsb->regs + RSB_INTE);
+ 	writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
+ 	       rsb->regs + RSB_CTRL);
+ 
+-	if (!wait_for_completion_io_timeout(&rsb->complete,
+-					    msecs_to_jiffies(100))) {
++	if (irqs_disabled()) {
++		timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS,
++						    status, (status & int_mask),
++						    10, 100000);
++		writel(status, rsb->regs + RSB_INTS);
++	} else {
++		timeout = !wait_for_completion_io_timeout(&rsb->complete,
++							  msecs_to_jiffies(100));
++		status = rsb->status;
++	}
++
++	if (timeout) {
+ 		dev_dbg(rsb->dev, "RSB timeout\n");
+ 
+ 		/* abort the transfer */
+@@ -292,18 +305,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ 		return -ETIMEDOUT;
+ 	}
+ 
+-	if (rsb->status & RSB_INTS_LOAD_BSY) {
++	if (status & RSB_INTS_LOAD_BSY) {
+ 		dev_dbg(rsb->dev, "RSB busy\n");
+ 		return -EBUSY;
+ 	}
+ 
+-	if (rsb->status & RSB_INTS_TRANS_ERR) {
+-		if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
++	if (status & RSB_INTS_TRANS_ERR) {
++		if (status & RSB_INTS_TRANS_ERR_ACK) {
+ 			dev_dbg(rsb->dev, "RSB slave nack\n");
+ 			return -EINVAL;
+ 		}
+ 
+-		if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
++		if (status & RSB_INTS_TRANS_ERR_DATA) {
+ 			dev_dbg(rsb->dev, "RSB transfer data error\n");
+ 			return -EIO;
+ 		}
+@@ -812,14 +825,6 @@ static int sunxi_rsb_remove(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
+-static void sunxi_rsb_shutdown(struct platform_device *pdev)
+-{
+-	struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+-
+-	pm_runtime_disable(&pdev->dev);
+-	sunxi_rsb_hw_exit(rsb);
+-}
+-
+ static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
+ 	SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend,
+ 			   sunxi_rsb_runtime_resume, NULL)
+@@ -835,7 +840,6 @@ MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
+ static struct platform_driver sunxi_rsb_driver = {
+ 	.probe = sunxi_rsb_probe,
+ 	.remove	= sunxi_rsb_remove,
+-	.shutdown = sunxi_rsb_shutdown,
+ 	.driver	= {
+ 		.name = RSB_CTRL_NAME,
+ 		.of_match_table = sunxi_rsb_of_match_table,
+diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
+index 55516043b656b..8184378f67efa 100644
+--- a/drivers/cpufreq/Kconfig.x86
++++ b/drivers/cpufreq/Kconfig.x86
+@@ -35,7 +35,7 @@ config X86_PCC_CPUFREQ
+ 	  If in doubt, say N.
+ 
+ config X86_AMD_PSTATE
+-	tristate "AMD Processor P-State driver"
++	bool "AMD Processor P-State driver"
+ 	depends on X86 && ACPI
+ 	select ACPI_PROCESSOR
+ 	select ACPI_CPPC_LIB if X86_64
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index d63a28c5f95a9..5b788492ce5e7 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -483,12 +483,22 @@ static void amd_pstate_boost_init(struct amd_cpudata *cpudata)
+ 	amd_pstate_driver.boost_enabled = true;
+ }
+ 
++static void amd_perf_ctl_reset(unsigned int cpu)
++{
++	wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0);
++}
++
+ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+ {
+ 	int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
+ 	struct device *dev;
+ 	struct amd_cpudata *cpudata;
+ 
++	/*
++	 * Resetting PERF_CTL_MSR will put the CPU in P0 frequency,
++	 * which is ideal for initialization process.
++	 */
++	amd_perf_ctl_reset(policy->cpu);
+ 	dev = get_cpu_device(policy->cpu);
+ 	if (!dev)
+ 		return -ENODEV;
+@@ -718,16 +728,7 @@ static int __init amd_pstate_init(void)
+ 
+ 	return ret;
+ }
+-
+-static void __exit amd_pstate_exit(void)
+-{
+-	cpufreq_unregister_driver(&amd_pstate_driver);
+-
+-	amd_pstate_enable(false);
+-}
+-
+-module_init(amd_pstate_init);
+-module_exit(amd_pstate_exit);
++device_initcall(amd_pstate_init);
+ 
+ MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
+ MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
+diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
+index efb4990b29e10..c6f08066e1653 100644
+--- a/drivers/dma-buf/dma-buf.c
++++ b/drivers/dma-buf/dma-buf.c
+@@ -15,6 +15,7 @@
+ #include <linux/slab.h>
+ #include <linux/dma-buf.h>
+ #include <linux/dma-fence.h>
++#include <linux/dma-fence-unwrap.h>
+ #include <linux/anon_inodes.h>
+ #include <linux/export.h>
+ #include <linux/debugfs.h>
+@@ -391,8 +392,10 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
+ 				     const void __user *user_data)
+ {
+ 	struct dma_buf_import_sync_file arg;
+-	struct dma_fence *fence;
++	struct dma_fence *fence, *f;
+ 	enum dma_resv_usage usage;
++	struct dma_fence_unwrap iter;
++	unsigned int num_fences;
+ 	int ret = 0;
+ 
+ 	if (copy_from_user(&arg, user_data, sizeof(arg)))
+@@ -411,13 +414,21 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
+ 	usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE :
+ 						   DMA_RESV_USAGE_READ;
+ 
+-	dma_resv_lock(dmabuf->resv, NULL);
++	num_fences = 0;
++	dma_fence_unwrap_for_each(f, &iter, fence)
++		++num_fences;
+ 
+-	ret = dma_resv_reserve_fences(dmabuf->resv, 1);
+-	if (!ret)
+-		dma_resv_add_fence(dmabuf->resv, fence, usage);
++	if (num_fences > 0) {
++		dma_resv_lock(dmabuf->resv, NULL);
+ 
+-	dma_resv_unlock(dmabuf->resv);
++		ret = dma_resv_reserve_fences(dmabuf->resv, num_fences);
++		if (!ret) {
++			dma_fence_unwrap_for_each(f, &iter, fence)
++				dma_resv_add_fence(dmabuf->resv, f, usage);
++		}
++
++		dma_resv_unlock(dmabuf->resv);
++	}
+ 
+ 	dma_fence_put(fence);
+ 
+diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
+index 8f5848aa144fe..59d158873f4cb 100644
+--- a/drivers/dma-buf/dma-heap.c
++++ b/drivers/dma-buf/dma-heap.c
+@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
+ 		return ERR_PTR(-EINVAL);
+ 	}
+ 
+-	/* check the name is unique */
+-	mutex_lock(&heap_list_lock);
+-	list_for_each_entry(h, &heap_list, list) {
+-		if (!strcmp(h->name, exp_info->name)) {
+-			mutex_unlock(&heap_list_lock);
+-			pr_err("dma_heap: Already registered heap named %s\n",
+-			       exp_info->name);
+-			return ERR_PTR(-EINVAL);
+-		}
+-	}
+-	mutex_unlock(&heap_list_lock);
+-
+ 	heap = kzalloc(sizeof(*heap), GFP_KERNEL);
+ 	if (!heap)
+ 		return ERR_PTR(-ENOMEM);
+@@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
+ 		err_ret = ERR_CAST(dev_ret);
+ 		goto err2;
+ 	}
+-	/* Add heap to the list */
++
+ 	mutex_lock(&heap_list_lock);
++	/* check the name is unique */
++	list_for_each_entry(h, &heap_list, list) {
++		if (!strcmp(h->name, exp_info->name)) {
++			mutex_unlock(&heap_list_lock);
++			pr_err("dma_heap: Already registered heap named %s\n",
++			       exp_info->name);
++			err_ret = ERR_PTR(-EINVAL);
++			goto err3;
++		}
++	}
++
++	/* Add heap to the list */
+ 	list_add(&heap->list, &heap_list);
+ 	mutex_unlock(&heap_list_lock);
+ 
+ 	return heap;
+ 
++err3:
++	device_destroy(dma_heap_class, heap->heap_devt);
+ err2:
+ 	cdev_del(&heap->heap_cdev);
+ err1:
+diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
+index 6c416955da532..bbe0a7cabb75f 100644
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -246,7 +246,9 @@ config FPGA_MGR_VERSAL_FPGA
+ 
+ config FPGA_M10_BMC_SEC_UPDATE
+ 	tristate "Intel MAX10 BMC Secure Update driver"
+-	depends on MFD_INTEL_M10_BMC && FW_UPLOAD
++	depends on MFD_INTEL_M10_BMC
++	select FW_LOADER
++	select FW_UPLOAD
+ 	help
+ 	  Secure update support for the Intel MAX10 board management
+ 	  controller.
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
+index c8935d7182073..4485bb29bec96 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
+@@ -41,5 +41,6 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
+ 	.get_atc_vmid_pasid_mapping_info =
+ 				kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
+ 	.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
++	.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
+ 	.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 93ad00453f4b3..7db4aef9c45cb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -170,9 +170,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
+ 	    (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
+ 	     kfd_mem_limit.max_ttm_mem_limit) ||
+ 	    (adev && adev->kfd.vram_used + vram_needed >
+-	     adev->gmc.real_vram_size -
+-	     atomic64_read(&adev->vram_pin_size) -
+-	     reserved_for_pt)) {
++	     adev->gmc.real_vram_size - reserved_for_pt)) {
+ 		ret = -ENOMEM;
+ 		goto release;
+ 	}
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+index 491d4846fc02c..cfb262911bfc7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+@@ -328,7 +328,6 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector)
+ 
+ 	kfree(amdgpu_connector->edid);
+ 	amdgpu_connector->edid = NULL;
+-	drm_connector_update_edid_property(connector, NULL);
+ }
+ 
+ static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+index 8ef31d687ef3b..111484ceb47d7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+@@ -413,11 +413,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+ 	if (r)
+ 		goto release_object;
+ 
+-	if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) {
+-		r = amdgpu_mn_register(bo, args->addr);
+-		if (r)
+-			goto release_object;
+-	}
++	r = amdgpu_mn_register(bo, args->addr);
++	if (r)
++		goto release_object;
+ 
+ 	if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
+ 		r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+index aebc384531ac8..bff5d8c832add 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+@@ -479,6 +479,12 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
+ 	unsigned i;
+ 	unsigned vmhub, inv_eng;
+ 
++	if (adev->enable_mes) {
++		/* reserve engine 5 for firmware */
++		for (vmhub = 0; vmhub < AMDGPU_MAX_VMHUBS; vmhub++)
++			vm_inv_engs[vmhub] &= ~(1 << 5);
++	}
++
+ 	for (i = 0; i < adev->num_rings; ++i) {
+ 		ring = adev->rings[i];
+ 		vmhub = ring->funcs->vmhub;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+index c9dec2434f370..cfa45a697d241 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+@@ -171,6 +171,7 @@ void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
+ {
+ 	amdgpu_bo_free_kernel(&mem_ctx->shared_bo, &mem_ctx->shared_mc_addr,
+ 			      &mem_ctx->shared_buf);
++	mem_ctx->shared_bo = NULL;
+ }
+ 
+ static void psp_free_shared_bufs(struct psp_context *psp)
+@@ -181,6 +182,7 @@ static void psp_free_shared_bufs(struct psp_context *psp)
+ 	/* free TMR memory buffer */
+ 	pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
+ 	amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++	psp->tmr_bo = NULL;
+ 
+ 	/* free xgmi shared memory */
+ 	psp_ta_free_shared_buf(&psp->xgmi_context.context.mem_context);
+@@ -728,7 +730,7 @@ static int psp_load_toc(struct psp_context *psp,
+ /* Set up Trusted Memory Region */
+ static int psp_tmr_init(struct psp_context *psp)
+ {
+-	int ret;
++	int ret = 0;
+ 	int tmr_size;
+ 	void *tmr_buf;
+ 	void **pptr;
+@@ -755,10 +757,12 @@ static int psp_tmr_init(struct psp_context *psp)
+ 		}
+ 	}
+ 
+-	pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
+-	ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
+-				      AMDGPU_GEM_DOMAIN_VRAM,
+-				      &psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++	if (!psp->tmr_bo) {
++		pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
++		ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
++					      AMDGPU_GEM_DOMAIN_VRAM,
++					      &psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++	}
+ 
+ 	return ret;
+ }
+@@ -2720,8 +2724,6 @@ static int psp_suspend(void *handle)
+ 	}
+ 
+ out:
+-	psp_free_shared_bufs(psp);
+-
+ 	return ret;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 04130f8813ef1..369c0d03e3c6a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -143,32 +143,6 @@ int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ 	return 0;
+ }
+ 
+-/*
+- * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
+- * happens while holding this lock anywhere to prevent deadlocks when
+- * an MMU notifier runs in reclaim-FS context.
+- */
+-static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
+-{
+-	mutex_lock(&vm->eviction_lock);
+-	vm->saved_flags = memalloc_noreclaim_save();
+-}
+-
+-static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
+-{
+-	if (mutex_trylock(&vm->eviction_lock)) {
+-		vm->saved_flags = memalloc_noreclaim_save();
+-		return 1;
+-	}
+-	return 0;
+-}
+-
+-static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
+-{
+-	memalloc_noreclaim_restore(vm->saved_flags);
+-	mutex_unlock(&vm->eviction_lock);
+-}
+-
+ /**
+  * amdgpu_vm_bo_evicted - vm_bo is evicted
+  *
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+index 278512535b518..39d2898caedef 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+@@ -503,4 +503,30 @@ static inline uint64_t amdgpu_vm_tlb_seq(struct amdgpu_vm *vm)
+ 	return atomic64_read(&vm->tlb_seq);
+ }
+ 
++/*
++ * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
++ * happens while holding this lock anywhere to prevent deadlocks when
++ * an MMU notifier runs in reclaim-FS context.
++ */
++static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
++{
++	mutex_lock(&vm->eviction_lock);
++	vm->saved_flags = memalloc_noreclaim_save();
++}
++
++static inline bool amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
++{
++	if (mutex_trylock(&vm->eviction_lock)) {
++		vm->saved_flags = memalloc_noreclaim_save();
++		return true;
++	}
++	return false;
++}
++
++static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
++{
++	memalloc_noreclaim_restore(vm->saved_flags);
++	mutex_unlock(&vm->eviction_lock);
++}
++
+ #endif
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+index 88de9f0d4728a..9838995744648 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+@@ -597,7 +597,9 @@ static int amdgpu_vm_pt_alloc(struct amdgpu_device *adev,
+ 	if (entry->bo)
+ 		return 0;
+ 
++	amdgpu_vm_eviction_unlock(vm);
+ 	r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt);
++	amdgpu_vm_eviction_lock(vm);
+ 	if (r)
+ 		return r;
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+index 3bff0ae15e64e..3175b9c1849dd 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+@@ -190,7 +190,11 @@ static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes,
+ 	mes_add_queue_pkt.trap_handler_addr = input->tba_addr;
+ 	mes_add_queue_pkt.tma_addr = input->tma_addr;
+ 	mes_add_queue_pkt.is_kfd_process = input->is_kfd_process;
+-	mes_add_queue_pkt.trap_en = 1;
++
++	if (!(((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 4) &&
++		  (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0)) &&
++		  (adev->ip_versions[GC_HWIP][0] <= IP_VERSION(11, 0, 3))))
++		mes_add_queue_pkt.trap_en = 1;
+ 
+ 	/* For KFD, gds_size is re-used for queue size (needed in MES for AQL queues) */
+ 	mes_add_queue_pkt.is_aql_queue = input->is_aql_queue;
+diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
+index 60a81649cf128..0c4c5499bb5cc 100644
+--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
++++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
+@@ -742,7 +742,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 	0xbf88fffe, 0x877aff7f,
+ 	0x04000000, 0x8f7a857a,
+ 	0x886d7a6d, 0xb97b02dc,
+-	0x8f7b997b, 0xb97a2a05,
++	0x8f7b997b, 0xb97a3a05,
+ 	0x807a817a, 0xbf0d997b,
+ 	0xbf850002, 0x8f7a897a,
+ 	0xbf820001, 0x8f7a8a7a,
+@@ -819,7 +819,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 	0xbefe037c, 0xbefc0370,
+ 	0xf4611c7a, 0xf8000000,
+ 	0x80708470, 0xbefc037e,
+-	0xb9702a05, 0x80708170,
++	0xb9703a05, 0x80708170,
+ 	0xbf0d9973, 0xbf850002,
+ 	0x8f708970, 0xbf820001,
+ 	0x8f708a70, 0xb97a1e06,
+@@ -1069,7 +1069,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 	0xb9f9f816, 0x876f7bff,
+ 	0xfffff800, 0x906f8b6f,
+ 	0xb9efa2c3, 0xb9f3f801,
+-	0xb96e2a05, 0x806e816e,
++	0xb96e3a05, 0x806e816e,
+ 	0xbf0d9972, 0xbf850002,
+ 	0x8f6e896e, 0xbf820001,
+ 	0x8f6e8a6e, 0xb96f1e06,
+@@ -2114,7 +2114,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0x007a0000, 0x7e000280,
+ 	0xbefe037a, 0xbeff037b,
+ 	0xb97b02dc, 0x8f7b997b,
+-	0xb97a2a05, 0x807a817a,
++	0xb97a3a05, 0x807a817a,
+ 	0xbf0d997b, 0xbf850002,
+ 	0x8f7a897a, 0xbf820001,
+ 	0x8f7a8a7a, 0xb97b1e06,
+@@ -2157,7 +2157,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0x01000000, 0xe0704100,
+ 	0x705d0100, 0xe0704200,
+ 	0x705d0200, 0xe0704300,
+-	0x705d0300, 0xb9702a05,
++	0x705d0300, 0xb9703a05,
+ 	0x80708170, 0xbf0d9973,
+ 	0xbf850002, 0x8f708970,
+ 	0xbf820001, 0x8f708a70,
+@@ -2189,7 +2189,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0xbefe03ff, 0x0000ffff,
+ 	0xbeff0380, 0xe0704000,
+ 	0x705d0200, 0xbefe03c1,
+-	0xb9702a05, 0x80708170,
++	0xb9703a05, 0x80708170,
+ 	0xbf0d9973, 0xbf850002,
+ 	0x8f708970, 0xbf820001,
+ 	0x8f708a70, 0xb97a1e06,
+@@ -2475,7 +2475,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0xb9ef4803, 0x876f7bff,
+ 	0xfffff800, 0x906f8b6f,
+ 	0xb9efa2c3, 0xb9f3f801,
+-	0xb96e2a05, 0x806e816e,
++	0xb96e3a05, 0x806e816e,
+ 	0xbf0d9972, 0xbf850002,
+ 	0x8f6e896e, 0xbf820001,
+ 	0x8f6e8a6e, 0xb96f1e06,
+@@ -2494,11 +2494,13 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0xbf9f0000, 0xbf9f0000,
+ 	0xbf9f0000, 0x00000000,
+ };
+-
+ static const uint32_t cwsr_trap_gfx11_hex[] = {
+-	0xbfa00001, 0xbfa0021b,
++	0xbfa00001, 0xbfa00221,
+ 	0xb0804006, 0xb8f8f802,
+-	0x91788678, 0xb8fbf803,
++	0x9178ff78, 0x00020006,
++	0xb8fbf803, 0xbf0d9e6d,
++	0xbfa10001, 0xbfbd0000,
++	0xbf0d9f6d, 0xbfa20006,
+ 	0x8b6eff78, 0x00002000,
+ 	0xbfa10009, 0x8b6eff6d,
+ 	0x00ff0000, 0xbfa2001e,
+@@ -2766,7 +2768,7 @@ static const uint32_t cwsr_trap_gfx11_hex[] = {
+ 	0x701d0000, 0x807d817d,
+ 	0x8070ff70, 0x00000080,
+ 	0xbf0a7b7d, 0xbfa2fff8,
+-	0xbfa00141, 0xbef4007e,
++	0xbfa00146, 0xbef4007e,
+ 	0x8b75ff7f, 0x0000ffff,
+ 	0x8c75ff75, 0x00040000,
+ 	0xbef60080, 0xbef700ff,
+@@ -2926,8 +2928,11 @@ static const uint32_t cwsr_trap_gfx11_hex[] = {
+ 	0xf8000074, 0xbf89fc07,
+ 	0x8b6dff6d, 0x0000ffff,
+ 	0x8bfe7e7e, 0x8bea6a6a,
+-	0xb97af802, 0xbe804a6c,
+-	0xbfb00000, 0xbf9f0000,
++	0xb8eef802, 0xbf0d866e,
++	0xbfa20002, 0xb97af802,
++	0xbe80486c, 0xb97af802,
++	0xbe804a6c, 0xbfb00000,
+ 	0xbf9f0000, 0xbf9f0000,
+ 	0xbf9f0000, 0xbf9f0000,
++	0xbf9f0000, 0x00000000,
+ };
+diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
+index 250ab007399bd..8b92c33c2a7c5 100644
+--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
++++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
+@@ -43,12 +43,14 @@
+ #define HAVE_XNACK (ASIC_FAMILY < CHIP_SIENNA_CICHLID)
+ #define HAVE_SENDMSG_RTN (ASIC_FAMILY >= CHIP_PLUM_BONITO)
+ #define HAVE_BUFFER_LDS_LOAD (ASIC_FAMILY < CHIP_PLUM_BONITO)
++#define SW_SA_TRAP (ASIC_FAMILY >= CHIP_PLUM_BONITO)
+ 
+ var SINGLE_STEP_MISSED_WORKAROUND		= 1	//workaround for lost MODE.DEBUG_EN exception when SAVECTX raised
+ 
+ var SQ_WAVE_STATUS_SPI_PRIO_MASK		= 0x00000006
+ var SQ_WAVE_STATUS_HALT_MASK			= 0x2000
+ var SQ_WAVE_STATUS_ECC_ERR_MASK			= 0x20000
++var SQ_WAVE_STATUS_TRAP_EN_SHIFT		= 6
+ 
+ var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT		= 12
+ var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE		= 9
+@@ -183,6 +185,19 @@ L_SKIP_RESTORE:
+ 
+ 	s_getreg_b32	s_save_trapsts, hwreg(HW_REG_TRAPSTS)
+ 
++#if SW_SA_TRAP
++	// If ttmp1[30] is set then issue s_barrier to unblock dependent waves.
++	s_bitcmp1_b32	s_save_pc_hi, 30
++	s_cbranch_scc0	L_TRAP_NO_BARRIER
++	s_barrier
++
++L_TRAP_NO_BARRIER:
++	// If ttmp1[31] is set then trap may occur early.
++	// Spin wait until SAVECTX exception is raised.
++	s_bitcmp1_b32	s_save_pc_hi, 31
++	s_cbranch_scc1  L_CHECK_SAVE
++#endif
++
+ 	s_and_b32       ttmp2, s_save_status, SQ_WAVE_STATUS_HALT_MASK
+ 	s_cbranch_scc0	L_NOT_HALTED
+ 
+@@ -1061,8 +1076,20 @@ L_RESTORE_HWREG:
+ 	s_and_b32	s_restore_pc_hi, s_restore_pc_hi, 0x0000ffff		//pc[47:32] //Do it here in order not to affect STATUS
+ 	s_and_b64	exec, exec, exec					// Restore STATUS.EXECZ, not writable by s_setreg_b32
+ 	s_and_b64	vcc, vcc, vcc						// Restore STATUS.VCCZ, not writable by s_setreg_b32
++
++#if SW_SA_TRAP
++	// If traps are enabled then return to the shader with PRIV=0.
++	// Otherwise retain PRIV=1 for subsequent context save requests.
++	s_getreg_b32	s_restore_tmp, hwreg(HW_REG_STATUS)
++	s_bitcmp1_b32	s_restore_tmp, SQ_WAVE_STATUS_TRAP_EN_SHIFT
++	s_cbranch_scc1	L_RETURN_WITHOUT_PRIV
++
+ 	s_setreg_b32	hwreg(HW_REG_STATUS), s_restore_status			// SCC is included, which is changed by previous salu
++	s_setpc_b64	[s_restore_pc_lo, s_restore_pc_hi]
++L_RETURN_WITHOUT_PRIV:
++#endif
+ 
++	s_setreg_b32	hwreg(HW_REG_STATUS), s_restore_status			// SCC is included, which is changed by previous salu
+ 	s_rfe_b64	s_restore_pc_lo						//Return to the main shader program and resume execution
+ 
+ L_END_PGM:
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 7f8eb09b0b7cb..4b16d9d1e058c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1371,7 +1371,44 @@ static const struct dmi_system_id hpd_disconnect_quirk_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"),
+ 		},
+ 	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"),
++		},
++	},
+ 	{}
++	/* TODO: refactor this from a fixed table to a dynamic option */
+ };
+ 
+ static void retrieve_dmi_info(struct amdgpu_display_manager *dm)
+@@ -7650,9 +7687,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ 		bundle->surface_updates[planes_count].plane_info =
+ 			&bundle->plane_infos[planes_count];
+ 
+-		fill_dc_dirty_rects(plane, old_plane_state, new_plane_state,
+-				    new_crtc_state,
+-				    &bundle->flip_addrs[planes_count]);
++		if (acrtc_state->stream->link->psr_settings.psr_feature_enabled)
++			fill_dc_dirty_rects(plane, old_plane_state,
++					    new_plane_state, new_crtc_state,
++					    &bundle->flip_addrs[planes_count]);
+ 
+ 		/*
+ 		 * Only allow immediate flips for fast updates that don't
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index dbf8158b832e4..fcddf60d3c10d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -746,6 +746,9 @@ struct dc_debug_options {
+ 	bool force_disable_subvp;
+ 	bool force_subvp_mclk_switch;
+ 	bool allow_sw_cursor_fallback;
++	unsigned int force_subvp_num_ways;
++	unsigned int force_mall_ss_num_ways;
++	bool alloc_extra_way_for_cursor;
+ 	bool force_usr_allow;
+ 	/* uses value at boot and disables switch */
+ 	bool disable_dtb_ref_clk_switch;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+index 1b70b78e2fa15..af631085e88c5 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+@@ -359,7 +359,8 @@ static const struct dce_audio_registers audio_regs[] = {
+ 	audio_regs(2),
+ 	audio_regs(3),
+ 	audio_regs(4),
+-	audio_regs(5)
++	audio_regs(5),
++	audio_regs(6),
+ };
+ 
+ #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index c72166e096bad..bbc0bfbec6c42 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -49,6 +49,7 @@
+ #include "dcn20/dcn20_optc.h"
+ #include "dmub_subvp_state.h"
+ #include "dce/dmub_hw_lock_mgr.h"
++#include "dcn32_resource.h"
+ #include "dc_link_dp.h"
+ #include "dmub/inc/dmub_subvp_state.h"
+ 
+@@ -198,42 +199,6 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
+ 	return false;
+ }
+ 
+-/* This function takes in the start address and surface size to be cached in CAB
+- * and calculates the total number of cache lines required to store the surface.
+- * The number of cache lines used for each surface is calculated independently of
+- * one another. For example, if there is a primary surface(1), meta surface(2), and
+- * cursor(3), this function should be called 3 times to calculate the number of cache
+- * lines used for each of those surfaces.
+- */
+-static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_size, uint64_t start_address)
+-{
+-	uint32_t lines_used = 1;
+-	uint32_t num_cached_bytes = 0;
+-	uint32_t remaining_size = 0;
+-	uint32_t cache_line_size = dc->caps.cache_line_size;
+-	uint32_t remainder = 0;
+-
+-	/* 1. Calculate surface size minus the number of bytes stored
+-	 * in the first cache line (all bytes in first cache line might
+-	 * not be fully used).
+-	 */
+-	div_u64_rem(start_address, cache_line_size, &remainder);
+-	num_cached_bytes = cache_line_size - remainder;
+-	remaining_size = surface_size - num_cached_bytes;
+-
+-	/* 2. Calculate number of cache lines that will be fully used with
+-	 * the remaining number of bytes to be stored.
+-	 */
+-	lines_used += (remaining_size / cache_line_size);
+-
+-	/* 3. Check if we need an extra line due to the remaining size not being
+-	 * a multiple of CACHE_LINE_SIZE.
+-	 */
+-	if (remaining_size % cache_line_size > 0)
+-		lines_used++;
+-
+-	return lines_used;
+-}
+ 
+ /* This function loops through every surface that needs to be cached in CAB for SS,
+  * and calculates the total number of ways required to store all surfaces (primary,
+@@ -241,94 +206,115 @@ static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_si
+  */
+ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
+ {
+-	uint8_t i, j;
++	uint8_t i;
++	int j;
+ 	struct dc_stream_state *stream = NULL;
+ 	struct dc_plane_state *plane = NULL;
+-	uint32_t surface_size = 0;
+ 	uint32_t cursor_size = 0;
+-	uint32_t cache_lines_used = 0;
+ 	uint32_t total_lines = 0;
+ 	uint32_t lines_per_way = 0;
+-	uint32_t num_ways = 0;
+-	uint32_t prev_addr_low = 0;
++	uint8_t num_ways = 0;
++	uint8_t bytes_per_pixel = 0;
++	uint8_t cursor_bpp = 0;
++	uint16_t mblk_width = 0;
++	uint16_t mblk_height = 0;
++	uint16_t mall_alloc_width_blk_aligned = 0;
++	uint16_t mall_alloc_height_blk_aligned = 0;
++	uint16_t num_mblks = 0;
++	uint32_t bytes_in_mall = 0;
++	uint32_t cache_lines_used = 0;
++	uint32_t cache_lines_per_plane = 0;
+ 
+-	for (i = 0; i < ctx->stream_count; i++) {
+-		stream = ctx->streams[i];
++	for (i = 0; i < dc->res_pool->pipe_count; i++) {
++		struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ 
+-		// Don't include PSR surface in the total surface size for CAB allocation
+-		if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
++		if (!pipe->stream || !pipe->plane_state ||
++				pipe->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED ||
++				pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)
+ 			continue;
+ 
+-		if (ctx->stream_status[i].plane_count == 0)
+-			continue;
++		bytes_per_pixel = pipe->plane_state->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4;
++		mblk_width = DCN3_2_MBLK_WIDTH;
++		mblk_height = bytes_per_pixel == 4 ? DCN3_2_MBLK_HEIGHT_4BPE : DCN3_2_MBLK_HEIGHT_8BPE;
+ 
+-		// For each stream, loop through each plane to calculate the number of cache
+-		// lines required to store the surface in CAB
+-		for (j = 0; j < ctx->stream_status[i].plane_count; j++) {
+-			plane = ctx->stream_status[i].plane_states[j];
++		/* full_vp_width_blk_aligned = FLOOR(vp_x_start + full_vp_width + blk_width - 1, blk_width) -
++		 * FLOOR(vp_x_start, blk_width)
++		 *
++		 * mall_alloc_width_blk_aligned_l/c = full_vp_width_blk_aligned_l/c
++		 */
++		mall_alloc_width_blk_aligned = ((pipe->plane_res.scl_data.viewport.x +
++				pipe->plane_res.scl_data.viewport.width + mblk_width - 1) / mblk_width * mblk_width) +
++						(pipe->plane_res.scl_data.viewport.x / mblk_width * mblk_width);
++
++		/* full_vp_height_blk_aligned = FLOOR(vp_y_start + full_vp_height + blk_height - 1, blk_height) -
++		 * FLOOR(vp_y_start, blk_height)
++		 *
++		 * mall_alloc_height_blk_aligned_l/c = full_vp_height_blk_aligned_l/c
++		 */
++		mall_alloc_height_blk_aligned = ((pipe->plane_res.scl_data.viewport.y +
++				pipe->plane_res.scl_data.viewport.height + mblk_height - 1) / mblk_height * mblk_height) +
++						(pipe->plane_res.scl_data.viewport.y / mblk_height * mblk_height);
+ 
+-			// Calculate total surface size
+-			if (prev_addr_low != plane->address.grph.addr.u.low_part) {
+-				/* if plane address are different from prev FB, then userspace allocated separate FBs*/
+-				surface_size += plane->plane_size.surface_pitch *
+-					plane->plane_size.surface_size.height *
+-					(plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
++		num_mblks = ((mall_alloc_width_blk_aligned + mblk_width - 1) / mblk_width) *
++				((mall_alloc_height_blk_aligned + mblk_height - 1) / mblk_height);
+ 
+-				prev_addr_low = plane->address.grph.addr.u.low_part;
+-			} else {
+-				/* We have the same fb for all the planes.
+-				 * Xorg always creates one giant fb that holds all surfaces,
+-				 * so allocating it once is sufficient.
+-				 * */
+-				continue;
+-			}
+-			// Convert surface size + starting address to number of cache lines required
+-			// (alignment accounted for)
+-			cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
+-					plane->address.grph.addr.quad_part);
+-
+-			if (plane->address.grph.meta_addr.quad_part) {
+-				// Meta surface
+-				cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
+-						plane->address.grph.meta_addr.quad_part);
+-			}
+-		}
++		/* For DCC:
++		 * meta_num_mblk = CEILING(full_mblk_width_ub_l*full_mblk_height_ub_l*Bpe/256/mblk_bytes, 1)
++		 */
++		if (pipe->plane_state->dcc.enable)
++			num_mblks += (mall_alloc_width_blk_aligned * mall_alloc_width_blk_aligned * bytes_per_pixel +
++					(256 * DCN3_2_MALL_MBLK_SIZE_BYTES) - 1) / (256 * DCN3_2_MALL_MBLK_SIZE_BYTES);
+ 
+-		// Include cursor size for CAB allocation
+-		for (j = 0; j < dc->res_pool->pipe_count; j++) {
+-			struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j];
+-			struct hubp *hubp = pipe->plane_res.hubp;
++		bytes_in_mall = num_mblks * DCN3_2_MALL_MBLK_SIZE_BYTES;
+ 
+-			if (pipe->stream && pipe->plane_state && hubp)
+-				/* Find the cursor plane and use the exact size instead of
+-				 * using the max for calculation
+-				 */
+-				if (hubp->curs_attr.width > 0) {
+-					cursor_size = hubp->curs_attr.width * hubp->curs_attr.height;
+-					break;
+-				}
+-		}
++		/* (cache lines used is total bytes / cache_line size. Add +2 for worst case alignment
++		 * (MALL is 64-byte aligned)
++		 */
++		cache_lines_per_plane = bytes_in_mall / dc->caps.cache_line_size + 2;
++		cache_lines_used += cache_lines_per_plane;
++	}
+ 
+-		switch (stream->cursor_attributes.color_format) {
+-		case CURSOR_MODE_MONO:
+-			cursor_size /= 2;
+-			break;
+-		case CURSOR_MODE_COLOR_1BIT_AND:
+-		case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
+-		case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
+-			cursor_size *= 4;
+-			break;
++	// Include cursor size for CAB allocation
++	for (j = 0; j < dc->res_pool->pipe_count; j++) {
++		struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j];
++		struct hubp *hubp = pipe->plane_res.hubp;
+ 
+-		case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
+-		case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
+-			cursor_size *= 8;
+-			break;
+-		}
++		if (pipe->stream && pipe->plane_state && hubp)
++			/* Find the cursor plane and use the exact size instead of
++			using the max for calculation */
+ 
+-		if (stream->cursor_position.enable && plane->address.grph.cursor_cache_addr.quad_part) {
+-			cache_lines_used += dcn32_cache_lines_for_surface(dc, cursor_size,
+-					plane->address.grph.cursor_cache_addr.quad_part);
+-		}
++		if (hubp->curs_attr.width > 0) {
++				cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height;
++
++				switch (pipe->stream->cursor_attributes.color_format) {
++				case CURSOR_MODE_MONO:
++					cursor_size /= 2;
++					cursor_bpp = 4;
++					break;
++				case CURSOR_MODE_COLOR_1BIT_AND:
++				case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
++				case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
++					cursor_size *= 4;
++					cursor_bpp = 4;
++					break;
++
++				case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
++				case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
++					cursor_size *= 8;
++					cursor_bpp = 8;
++					break;
++				}
++
++				if (pipe->stream->cursor_position.enable && !dc->debug.alloc_extra_way_for_cursor &&
++						cursor_size > 16384) {
++					/* cursor_num_mblk = CEILING(num_cursors*cursor_width*cursor_width*cursor_Bpe/mblk_bytes, 1)
++					 */
++					cache_lines_used += (((cursor_size + DCN3_2_MALL_MBLK_SIZE_BYTES - 1) /
++							DCN3_2_MALL_MBLK_SIZE_BYTES) * DCN3_2_MALL_MBLK_SIZE_BYTES) /
++							dc->caps.cache_line_size + 2;
++				}
++				break;
++			}
+ 	}
+ 
+ 	// Convert number of cache lines required to number of ways
+@@ -345,8 +331,8 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
+ 			plane = ctx->stream_status[i].plane_states[j];
+ 
+ 			if (stream->cursor_position.enable && plane &&
+-				!plane->address.grph.cursor_cache_addr.quad_part &&
+-				cursor_size > 16384) {
++					dc->debug.alloc_extra_way_for_cursor &&
++					cursor_size > 16384) {
+ 				/* Cursor caching is not supported since it won't be on the same line.
+ 				 * So we need an extra line to accommodate it. With large cursors and a single 4k monitor
+ 				 * this case triggers corruption. If we're at the edge, then dont trigger display refresh
+@@ -358,7 +344,9 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
+ 			}
+ 		}
+ 	}
+-
++	if (dc->debug.force_mall_ss_num_ways > 0) {
++		num_ways = dc->debug.force_mall_ss_num_ways;
++	}
+ 	return num_ways;
+ }
+ 
+@@ -741,10 +729,7 @@ void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)
+ 		struct hubp *hubp = pipe->plane_res.hubp;
+ 
+ 		if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) {
+-			//Round cursor width up to next multiple of 64
+-			int cursor_width = ((hubp->curs_attr.width + 63) / 64) * 64;
+-			int cursor_height = hubp->curs_attr.height;
+-			int cursor_size = cursor_width * cursor_height;
++			int cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height;
+ 
+ 			switch (hubp->curs_attr.color_format) {
+ 			case CURSOR_MODE_MONO:
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+index c3b783cea8a03..6f1bcb45a3b2d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+@@ -872,6 +872,7 @@ static const struct dc_debug_options debug_defaults_drv = {
+ 	.enable_single_display_2to1_odm_policy = true,
+ 	.enable_dp_dig_pixel_rate_div_policy = 1,
+ 	.allow_sw_cursor_fallback = false,
++	.alloc_extra_way_for_cursor = true,
+ };
+ 
+ static const struct dc_debug_options debug_defaults_diags = {
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+index 13cd1f2e50ca3..7c37575d69c73 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+@@ -54,13 +54,14 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ 	uint32_t num_mblks = 0;
+ 	uint32_t cache_lines_per_plane = 0;
+ 	uint32_t i = 0, j = 0;
+-	uint32_t mblk_width = 0;
+-	uint32_t mblk_height = 0;
++	uint16_t mblk_width = 0;
++	uint16_t mblk_height = 0;
+ 	uint32_t full_vp_width_blk_aligned = 0;
+ 	uint32_t full_vp_height_blk_aligned = 0;
+ 	uint32_t mall_alloc_width_blk_aligned = 0;
+ 	uint32_t mall_alloc_height_blk_aligned = 0;
+-	uint32_t full_vp_height = 0;
++	uint16_t full_vp_height = 0;
++	bool subvp_in_use = false;
+ 
+ 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+@@ -70,6 +71,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ 				pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+ 			struct pipe_ctx *main_pipe = NULL;
+ 
++			subvp_in_use = true;
+ 			/* Get full viewport height from main pipe (required for MBLK calculation) */
+ 			for (j = 0; j < dc->res_pool->pipe_count; j++) {
+ 				main_pipe = &context->res_ctx.pipe_ctx[j];
+@@ -129,6 +131,9 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ 	if (cache_lines_used % lines_per_way > 0)
+ 		num_ways++;
+ 
++	if (subvp_in_use && dc->debug.force_subvp_num_ways > 0)
++		num_ways = dc->debug.force_subvp_num_ways;
++
+ 	return num_ways;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+index 7309eed33a61c..d074716dc1972 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+@@ -873,6 +873,7 @@ static const struct dc_debug_options debug_defaults_drv = {
+ 	.enable_single_display_2to1_odm_policy = true,
+ 	.enable_dp_dig_pixel_rate_div_policy = 1,
+ 	.allow_sw_cursor_fallback = false,
++	.alloc_extra_way_for_cursor = true,
+ };
+ 
+ static const struct dc_debug_options debug_defaults_diags = {
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+index b9d3a4000c3d4..2f996fdaa70dd 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+@@ -157,7 +157,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
+ 	.dispclk_dppclk_vco_speed_mhz = 4300.0,
+ 	.do_urgent_latency_adjustment = true,
+ 	.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
+-	.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
++	.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
+ };
+ 
+ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+@@ -211,7 +211,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+ 	/* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */
+ 	if (clk_mgr->base.ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) {
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true;
+-		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 38;
++		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 50;
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us;
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us;
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
+@@ -221,7 +221,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
+ 		clk_mgr->base.bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz * 16;
+-		clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38;
++		clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 50;
+ 		clk_mgr->base.bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[1].memclk_mhz * 16;
+ 		clk_mgr->base.bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9;
+ 		clk_mgr->base.bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[2].memclk_mhz * 16;
+@@ -1700,6 +1700,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ 			 */
+ 			context->bw_ctx.dml.soc.dram_clock_change_latency_us =
+ 					dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
++			/* For DCN32/321 need to validate with fclk pstate change latency equal to dummy so
++			 * prefetch is scheduled correctly to account for dummy pstate.
++			 */
++			if (dummy_latency_index == 0)
++				context->bw_ctx.dml.soc.fclk_change_latency_us =
++						dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
+ 			dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
+ 			maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
+ 			dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+@@ -1879,6 +1885,10 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ 
+ 	context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod;
+ 
++	if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && dummy_latency_index == 0)
++		context->bw_ctx.dml.soc.fclk_change_latency_us =
++				dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
++
+ 	dcn32_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+ 
+ 	if (!pstate_en)
+@@ -1886,8 +1896,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ 		context->bw_ctx.dml.soc.dram_clock_change_latency_us =
+ 				dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
+ 
+-	if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
++	if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
+ 		dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context);
++		if (dummy_latency_index == 0)
++			context->bw_ctx.dml.soc.fclk_change_latency_us =
++					dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us;
++	}
+ }
+ 
+ static void dcn32_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index bea380407151a..042f9a62c4c50 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -3197,6 +3197,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ 							mode_lib->vba.FCLKChangeLatency, mode_lib->vba.UrgLatency[i],
+ 							mode_lib->vba.SREnterPlusExitTime);
+ 
++					memset(&v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull, 0, sizeof(DmlPipe));
+ 					v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dppclk = mode_lib->vba.RequiredDPPCLK[i][j][k];
+ 					v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dispclk = mode_lib->vba.RequiredDISPCLK[i][j];
+ 					v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.PixelClock = mode_lib->vba.PixelClock[k];
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+index 67af8f4df8b8f..d9141ef2fefdd 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+@@ -4396,7 +4396,7 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
+ 
+ 		if (v->NumberOfActiveSurfaces > 1) {
+ 			ActiveClockChangeLatencyHidingY = ActiveClockChangeLatencyHidingY
+-					- (1 - 1 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k]
++					- (1.0 - 1.0 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k]
+ 							/ v->PixelClock[k] / v->VRatio[k];
+ 		}
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
+index 0b427d89b3c5d..f174f5c5ff921 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
+@@ -30,7 +30,7 @@
+ #include "os_types.h"
+ #include "../dc_features.h"
+ #include "../display_mode_structs.h"
+-#include "dml/display_mode_vba.h"
++#include "../display_mode_vba.h"
+ 
+ unsigned int dml32_dscceComputeDelay(
+ 		unsigned int bpc,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+index aa976fe4d426d..0ab8e48b68416 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+@@ -125,9 +125,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
+ 	.sr_enter_plus_exit_z8_time_us = 320,
+ 	.writeback_latency_us = 12.0,
+ 	.round_trip_ping_latency_dcfclk_cycles = 263,
+-	.urgent_latency_pixel_data_only_us = 9.35,
+-	.urgent_latency_pixel_mixed_with_vm_data_us = 9.35,
+-	.urgent_latency_vm_data_only_us = 9.35,
++	.urgent_latency_pixel_data_only_us = 4,
++	.urgent_latency_pixel_mixed_with_vm_data_us = 4,
++	.urgent_latency_vm_data_only_us = 4,
+ 	.fclk_change_latency_us = 20,
+ 	.usr_retraining_latency_us = 2,
+ 	.smn_latency_us = 2,
+@@ -155,7 +155,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
+ 	.dispclk_dppclk_vco_speed_mhz = 4300.0,
+ 	.do_urgent_latency_adjustment = true,
+ 	.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
+-	.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
++	.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
+ };
+ 
+ static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry)
+diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
+index d635b73af46fe..0ea52ba5ac827 100644
+--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
++++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
+@@ -107,6 +107,13 @@ static const struct ddc_registers ddc_data_regs_dcn[] = {
+ 	ddc_data_regs_dcn2(3),
+ 	ddc_data_regs_dcn2(4),
+ 	ddc_data_regs_dcn2(5),
++	{
++		// add a dummy entry for cases no such port
++		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
++		.ddc_setup = 0,
++		.phy_aux_cntl = 0,
++		.dc_gpio_aux_ctrl_5 = 0
++	},
+ 	{
+ 			DDC_GPIO_VGA_REG_LIST(DATA),
+ 			.ddc_setup = 0,
+@@ -121,6 +128,13 @@ static const struct ddc_registers ddc_clk_regs_dcn[] = {
+ 	ddc_clk_regs_dcn2(3),
+ 	ddc_clk_regs_dcn2(4),
+ 	ddc_clk_regs_dcn2(5),
++	{
++		// add a dummy entry for cases no such port
++		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
++		.ddc_setup = 0,
++		.phy_aux_cntl = 0,
++		.dc_gpio_aux_ctrl_5 = 0
++	},
+ 	{
+ 			DDC_GPIO_VGA_REG_LIST(CLK),
+ 			.ddc_setup = 0,
+diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
+index 6fd38cdd68c0c..525bc8881950d 100644
+--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
+@@ -94,11 +94,14 @@ static enum gpio_result set_config(
+ 		 * is required for detection of AUX mode */
+ 		if (hw_gpio->base.en != GPIO_DDC_LINE_VIP_PAD) {
+ 			if (!ddc_data_pd_en || !ddc_clk_pd_en) {
+-
+-				REG_SET_2(gpio.MASK_reg, regval,
++				if (hw_gpio->base.en == GPIO_DDC_LINE_DDC_VGA) {
++					// bit 4 of mask has different usage in some cases
++					REG_SET(gpio.MASK_reg, regval, DC_GPIO_DDC1DATA_PD_EN, 1);
++				} else {
++					REG_SET_2(gpio.MASK_reg, regval,
+ 						DC_GPIO_DDC1DATA_PD_EN, 1,
+ 						DC_GPIO_DDC1CLK_PD_EN, 1);
+-
++				}
+ 				if (config_data->type ==
+ 						GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
+ 					msleep(3);
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
+index dad3e3741a4e8..190af79f3236f 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
+@@ -67,22 +67,21 @@ int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
+ int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr,
+ 		uint32_t *speed)
+ {
+-	uint32_t current_rpm;
+-	uint32_t percent = 0;
+-
+-	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+-		return 0;
++	struct amdgpu_device *adev = hwmgr->adev;
++	uint32_t duty100, duty;
++	uint64_t tmp64;
+ 
+-	if (vega10_get_current_rpm(hwmgr, &current_rpm))
+-		return -1;
++	duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
++				CG_FDO_CTRL1, FMAX_DUTY100);
++	duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS),
++				CG_THERMAL_STATUS, FDO_PWM_DUTY);
+ 
+-	if (hwmgr->thermal_controller.
+-			advanceFanControlParameters.usMaxFanRPM != 0)
+-		percent = current_rpm * 255 /
+-			hwmgr->thermal_controller.
+-			advanceFanControlParameters.usMaxFanRPM;
++	if (!duty100)
++		return -EINVAL;
+ 
+-	*speed = MIN(percent, 255);
++	tmp64 = (uint64_t)duty * 255;
++	do_div(tmp64, duty100);
++	*speed = MIN((uint32_t)tmp64, 255);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+index 8292839bc42a9..9ce0dcc5bb90a 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+@@ -378,6 +378,10 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu)
+ 		    ((adev->pdev->device == 0x73BF) &&
+ 		    (adev->pdev->revision == 0xCF)) ||
+ 		    ((adev->pdev->device == 0x7422) &&
++		    (adev->pdev->revision == 0x00)) ||
++		    ((adev->pdev->device == 0x73A3) &&
++		    (adev->pdev->revision == 0x00)) ||
++		    ((adev->pdev->device == 0x73E3) &&
+ 		    (adev->pdev->revision == 0x00)))
+ 			smu_baco->platform_support = false;
+ 
+diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+index 7a94a5288e8d7..855297e69f04c 100644
+--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+@@ -5293,7 +5293,7 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm
+ 	mst_state = drm_atomic_get_mst_topology_state(state, mgr);
+ 
+ 	if (IS_ERR(mst_state))
+-		return -EINVAL;
++		return PTR_ERR(mst_state);
+ 
+ 	list_for_each_entry(pos, &mst_state->vcpis, next) {
+ 
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index 8a0c0e0bb5bd2..52d8800a8ab86 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -134,6 +134,12 @@ static const struct dmi_system_id orientation_data[] = {
+ 		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
+ 		},
+ 		.driver_data = (void *)&lcd800x1280_rightside_up,
++	}, {	/* Acer Switch V 10 (SW5-017) */
++		.matches = {
++		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
++		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++		},
++		.driver_data = (void *)&lcd800x1280_rightside_up,
+ 	}, {	/* Anbernic Win600 */
+ 		.matches = {
+ 		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"),
+@@ -319,6 +325,12 @@ static const struct dmi_system_id orientation_data[] = {
+ 		 DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
+ 		},
+ 		.driver_data = (void *)&lcd1200x1920_rightside_up,
++	}, {	/* Nanote UMPC-01 */
++		.matches = {
++		 DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"),
++		 DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"),
++		},
++		.driver_data = (void *)&lcd1200x1920_rightside_up,
+ 	}, {	/* OneGX1 Pro */
+ 		.matches = {
+ 		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"),
+diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
+index 589af257edebc..3bb113b42cfa2 100644
+--- a/drivers/gpu/drm/i915/display/intel_display_power.c
++++ b/drivers/gpu/drm/i915/display/intel_display_power.c
+@@ -2427,7 +2427,7 @@ intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port)
+ {
+ 	const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port);
+ 
+-	if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_io == POWER_DOMAIN_INVALID)
++	if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_io == POWER_DOMAIN_INVALID))
+ 		return POWER_DOMAIN_PORT_DDI_IO_A;
+ 
+ 	return domains->ddi_io + (int)(port - domains->port_start);
+@@ -2438,7 +2438,7 @@ intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port po
+ {
+ 	const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port);
+ 
+-	if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_lanes == POWER_DOMAIN_INVALID)
++	if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_lanes == POWER_DOMAIN_INVALID))
+ 		return POWER_DOMAIN_PORT_DDI_LANES_A;
+ 
+ 	return domains->ddi_lanes + (int)(port - domains->port_start);
+@@ -2464,7 +2464,7 @@ intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch
+ {
+ 	const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch);
+ 
+-	if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID)
++	if (drm_WARN_ON(&i915->drm, !domains || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID))
+ 		return POWER_DOMAIN_AUX_A;
+ 
+ 	return domains->aux_legacy_usbc + (int)(aux_ch - domains->aux_ch_start);
+@@ -2475,7 +2475,7 @@ intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch au
+ {
+ 	const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch);
+ 
+-	if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_tbt == POWER_DOMAIN_INVALID)
++	if (drm_WARN_ON(&i915->drm, !domains || domains->aux_tbt == POWER_DOMAIN_INVALID))
+ 		return POWER_DOMAIN_AUX_TBT1;
+ 
+ 	return domains->aux_tbt + (int)(aux_ch - domains->aux_ch_start);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+index e85cfc36359a4..f5a803060515c 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+@@ -642,6 +642,10 @@ static int i915_ttm_truncate(struct drm_i915_gem_object *obj)
+ 
+ 	WARN_ON_ONCE(obj->mm.madv == I915_MADV_WILLNEED);
+ 
++	err = ttm_bo_wait(bo, true, false);
++	if (err)
++		return err;
++
+ 	err = i915_ttm_move_notify(bo);
+ 	if (err)
+ 		return err;
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
+index f435e06125aab..f158f6a08e757 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt.c
+@@ -961,6 +961,11 @@ static void mmio_invalidate_full(struct intel_gt *gt)
+ 		if (!i915_mmio_reg_offset(rb.reg))
+ 			continue;
+ 
++		if (GRAPHICS_VER(i915) == 12 && (engine->class == VIDEO_DECODE_CLASS ||
++		    engine->class == VIDEO_ENHANCEMENT_CLASS ||
++		    engine->class == COMPUTE_CLASS))
++			rb.bit = _MASKED_BIT_ENABLE(rb.bit);
++
+ 		intel_uncore_write_fw(uncore, rb.reg, rb.bit);
+ 		awake |= engine->mask;
+ 	}
+diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
+index de89946c4817f..f671ae5a3b7b4 100644
+--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
++++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
+@@ -765,8 +765,6 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
+ 		return -ESRCH;
+ 	}
+ 
+-	kvm_get_kvm(vgpu->vfio_device.kvm);
+-
+ 	if (__kvmgt_vgpu_exist(vgpu))
+ 		return -EEXIST;
+ 
+@@ -777,6 +775,7 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
+ 
+ 	vgpu->track_node.track_write = kvmgt_page_track_write;
+ 	vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
++	kvm_get_kvm(vgpu->vfio_device.kvm);
+ 	kvm_page_track_register_notifier(vgpu->vfio_device.kvm,
+ 					 &vgpu->track_node);
+ 
+diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
+index 6748ec1e00057..a1f909dac89a7 100644
+--- a/drivers/gpu/drm/tegra/drm.c
++++ b/drivers/gpu/drm/tegra/drm.c
+@@ -1093,6 +1093,10 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev)
+ 	struct host1x *host1x = dev_get_drvdata(dev->dev.parent);
+ 	struct iommu_domain *domain;
+ 
++	/* Our IOMMU usage policy doesn't currently play well with GART */
++	if (of_machine_is_compatible("nvidia,tegra20"))
++		return false;
++
+ 	/*
+ 	 * If the Tegra DRM clients are backed by an IOMMU, push buffers are
+ 	 * likely to be allocated beyond the 32-bit boundary if sufficient
+diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
+index 0cd3f97e7e49f..f60ea24db0ec8 100644
+--- a/drivers/gpu/host1x/dev.c
++++ b/drivers/gpu/host1x/dev.c
+@@ -292,6 +292,10 @@ static void host1x_setup_virtualization_tables(struct host1x *host)
+ 
+ static bool host1x_wants_iommu(struct host1x *host1x)
+ {
++	/* Our IOMMU usage policy doesn't currently play well with GART */
++	if (of_machine_is_compatible("nvidia,tegra20"))
++		return false;
++
+ 	/*
+ 	 * If we support addressing a maximum of 32 bits of physical memory
+ 	 * and if the host1x firewall is enabled, there's no need to enable
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 5b120402d4057..cc23b90cae02f 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -533,13 +533,17 @@ static void vmbus_add_channel_work(struct work_struct *work)
+ 	 * Add the new device to the bus. This will kick off device-driver
+ 	 * binding which eventually invokes the device driver's AddDevice()
+ 	 * method.
++	 *
++	 * If vmbus_device_register() fails, the 'device_obj' is freed in
++	 * vmbus_device_release() as called by device_unregister() in the
++	 * error path of vmbus_device_register(). In the outside error
++	 * path, there's no need to free it.
+ 	 */
+ 	ret = vmbus_device_register(newchannel->device_obj);
+ 
+ 	if (ret != 0) {
+ 		pr_err("unable to add child device object (relid %d)\n",
+ 			newchannel->offermsg.child_relid);
+-		kfree(newchannel->device_obj);
+ 		goto err_deq_chan;
+ 	}
+ 
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 3c833ea60db65..939ccf921e71b 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -2083,6 +2083,7 @@ int vmbus_device_register(struct hv_device *child_device_obj)
+ 	ret = device_register(&child_device_obj->device);
+ 	if (ret) {
+ 		pr_err("Unable to register child device\n");
++		put_device(&child_device_obj->device);
+ 		return ret;
+ 	}
+ 
+diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
+index 29c9fa99c2bd3..dea438b9eb9e3 100644
+--- a/drivers/iio/accel/bma400_core.c
++++ b/drivers/iio/accel/bma400_core.c
+@@ -673,8 +673,10 @@ static int bma400_get_steps_reg(struct bma400_data *data, int *val)
+ 
+ 	ret = regmap_bulk_read(data->regmap, BMA400_STEP_CNT0_REG,
+ 			       steps_raw, BMA400_STEP_RAW_LEN);
+-	if (ret)
++	if (ret) {
++		kfree(steps_raw);
+ 		return ret;
++	}
+ 	*val = get_unaligned_le24(steps_raw);
+ 	kfree(steps_raw);
+ 	return IIO_VAL_INT;
+diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
+index 9341e0e0eb556..998e8bcc06e1d 100644
+--- a/drivers/iio/adc/aspeed_adc.c
++++ b/drivers/iio/adc/aspeed_adc.c
+@@ -202,6 +202,8 @@ static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev)
+ 				((scu_otp) &
+ 				 (data->model_data->trim_locate->field)) >>
+ 				__ffs(data->model_data->trim_locate->field);
++			if (!trimming_val)
++				trimming_val = 0x8;
+ 		}
+ 		dev_dbg(data->dev,
+ 			"trimming val = %d, offset = %08x, fields = %08x\n",
+@@ -563,12 +565,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		return ret;
+ 
+-	if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid",
+-			     NULL)) {
+-		ret = aspeed_adc_set_trim_data(indio_dev);
+-		if (ret)
+-			return ret;
+-	}
++	ret = aspeed_adc_set_trim_data(indio_dev);
++	if (ret)
++		return ret;
+ 
+ 	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
+ 			     NULL)) {
+diff --git a/drivers/iio/industrialio-sw-trigger.c b/drivers/iio/industrialio-sw-trigger.c
+index 994f03a715204..d86a3305d9e8d 100644
+--- a/drivers/iio/industrialio-sw-trigger.c
++++ b/drivers/iio/industrialio-sw-trigger.c
+@@ -58,8 +58,12 @@ int iio_register_sw_trigger_type(struct iio_sw_trigger_type *t)
+ 
+ 	t->group = configfs_register_default_group(iio_triggers_group, t->name,
+ 						&iio_trigger_type_group_type);
+-	if (IS_ERR(t->group))
++	if (IS_ERR(t->group)) {
++		mutex_lock(&iio_trigger_types_lock);
++		list_del(&t->list);
++		mutex_unlock(&iio_trigger_types_lock);
+ 		ret = PTR_ERR(t->group);
++	}
+ 
+ 	return ret;
+ }
+diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c
+index 09b831f9f40b6..795224a38bef8 100644
+--- a/drivers/iio/light/apds9960.c
++++ b/drivers/iio/light/apds9960.c
+@@ -54,9 +54,6 @@
+ #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT	2
+ 
+ #define APDS9960_REG_CONFIG_2	0x90
+-#define APDS9960_REG_CONFIG_2_GGAIN_MASK	0x60
+-#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT	5
+-
+ #define APDS9960_REG_ID		0x92
+ 
+ #define APDS9960_REG_STATUS	0x93
+@@ -77,6 +74,9 @@
+ #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT	6
+ 
+ #define APDS9960_REG_GCONF_2	0xa3
++#define APDS9960_REG_GCONF_2_GGAIN_MASK			0x60
++#define APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT		5
++
+ #define APDS9960_REG_GOFFSET_U	0xa4
+ #define APDS9960_REG_GOFFSET_D	0xa5
+ #define APDS9960_REG_GPULSE	0xa6
+@@ -396,9 +396,9 @@ static int apds9960_set_pxs_gain(struct apds9960_data *data, int val)
+ 			}
+ 
+ 			ret = regmap_update_bits(data->regmap,
+-				APDS9960_REG_CONFIG_2,
+-				APDS9960_REG_CONFIG_2_GGAIN_MASK,
+-				idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT);
++				APDS9960_REG_GCONF_2,
++				APDS9960_REG_GCONF_2_GGAIN_MASK,
++				idx << APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT);
+ 			if (!ret)
+ 				data->pxs_gain = idx;
+ 			mutex_unlock(&data->lock);
+diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
+index 480476121c010..09489380afda7 100644
+--- a/drivers/input/misc/soc_button_array.c
++++ b/drivers/input/misc/soc_button_array.c
+@@ -18,6 +18,10 @@
+ #include <linux/gpio.h>
+ #include <linux/platform_device.h>
+ 
++static bool use_low_level_irq;
++module_param(use_low_level_irq, bool, 0444);
++MODULE_PARM_DESC(use_low_level_irq, "Use low-level triggered IRQ instead of edge triggered");
++
+ struct soc_button_info {
+ 	const char *name;
+ 	int acpi_index;
+@@ -73,6 +77,13 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+ 		},
+ 	},
++	{
++		/* Acer Switch V 10 SW5-017, same issue as Acer Switch 10 SW5-012. */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++		},
++	},
+ 	{
+ 		/*
+ 		 * Acer One S1003. _LID method messes with power-button GPIO
+@@ -164,7 +175,8 @@ soc_button_device_create(struct platform_device *pdev,
+ 		}
+ 
+ 		/* See dmi_use_low_level_irq[] comment */
+-		if (!autorepeat && dmi_check_system(dmi_use_low_level_irq)) {
++		if (!autorepeat && (use_low_level_irq ||
++				    dmi_check_system(dmi_use_low_level_irq))) {
+ 			irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
+ 			gpio_keys[n_buttons].irq = irq;
+ 			gpio_keys[n_buttons].gpio = -ENOENT;
+diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
+index ffad142801b39..973a4c1d5d09f 100644
+--- a/drivers/input/mouse/synaptics.c
++++ b/drivers/input/mouse/synaptics.c
+@@ -191,6 +191,7 @@ static const char * const smbus_pnp_ids[] = {
+ 	"SYN3221", /* HP 15-ay000 */
+ 	"SYN323d", /* HP Spectre X360 13-w013dx */
+ 	"SYN3257", /* HP Envy 13-ad105ng */
++	"SYN3286", /* HP Laptop 15-da3001TU */
+ 	NULL
+ };
+ 
+diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
+index 4fbec7bbeccaa..5043dc7b8fb3a 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -114,18 +114,18 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
+ 		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER)
+ 	},
+ 	{
+-		/* ASUS ZenBook UX425UA */
++		/* ASUS ZenBook UX425UA/QA */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425"),
+ 		},
+ 		.driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+ 	},
+ 	{
+-		/* ASUS ZenBook UM325UA */
++		/* ASUS ZenBook UM325UA/QA */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325"),
+ 		},
+ 		.driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+ 	},
+diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
+index 21c0dddbe41d4..25e6ba132bbc2 100644
+--- a/drivers/input/touchscreen/goodix.c
++++ b/drivers/input/touchscreen/goodix.c
+@@ -1158,6 +1158,7 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
+ 	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
+ 	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+ 
++retry_read_config:
+ 	/* Read configuration and apply touchscreen parameters */
+ 	goodix_read_config(ts);
+ 
+@@ -1165,6 +1166,16 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
+ 	touchscreen_parse_properties(ts->input_dev, true, &ts->prop);
+ 
+ 	if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) {
++		if (!ts->reset_controller_at_probe &&
++		    ts->irq_pin_access_method != IRQ_PIN_ACCESS_NONE) {
++			dev_info(&ts->client->dev, "Config not set, resetting controller\n");
++			/* Retry after a controller reset */
++			ts->reset_controller_at_probe = true;
++			error = goodix_reset(ts);
++			if (error)
++				return error;
++			goto retry_read_config;
++		}
+ 		dev_err(&ts->client->dev,
+ 			"Invalid config (%d, %d, %d), using defaults\n",
+ 			ts->prop.max_x, ts->prop.max_y, ts->max_touch_num);
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index aaf2472df6e58..e97e9f97456d4 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -263,6 +263,7 @@ struct dm_integrity_c {
+ 
+ 	struct completion crypto_backoff;
+ 
++	bool wrote_to_journal;
+ 	bool journal_uptodate;
+ 	bool just_formatted;
+ 	bool recalculate_flag;
+@@ -2375,6 +2376,8 @@ static void integrity_commit(struct work_struct *w)
+ 	if (!commit_sections)
+ 		goto release_flush_bios;
+ 
++	ic->wrote_to_journal = true;
++
+ 	i = commit_start;
+ 	for (n = 0; n < commit_sections; n++) {
+ 		for (j = 0; j < ic->journal_section_entries; j++) {
+@@ -2591,10 +2594,6 @@ static void integrity_writer(struct work_struct *w)
+ 
+ 	unsigned prev_free_sectors;
+ 
+-	/* the following test is not needed, but it tests the replay code */
+-	if (unlikely(dm_post_suspending(ic->ti)) && !ic->meta_dev)
+-		return;
+-
+ 	spin_lock_irq(&ic->endio_wait.lock);
+ 	write_start = ic->committed_section;
+ 	write_sections = ic->n_committed_sections;
+@@ -3101,10 +3100,17 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
+ 	drain_workqueue(ic->commit_wq);
+ 
+ 	if (ic->mode == 'J') {
+-		if (ic->meta_dev)
+-			queue_work(ic->writer_wq, &ic->writer_work);
++		queue_work(ic->writer_wq, &ic->writer_work);
+ 		drain_workqueue(ic->writer_wq);
+ 		dm_integrity_flush_buffers(ic, true);
++		if (ic->wrote_to_journal) {
++			init_journal(ic, ic->free_section,
++				     ic->journal_sections - ic->free_section, ic->commit_seq);
++			if (ic->free_section) {
++				init_journal(ic, 0, ic->free_section,
++					     next_commit_seq(ic->commit_seq));
++			}
++		}
+ 	}
+ 
+ 	if (ic->mode == 'B') {
+@@ -3132,6 +3138,8 @@ static void dm_integrity_resume(struct dm_target *ti)
+ 
+ 	DEBUG_print("resume\n");
+ 
++	ic->wrote_to_journal = false;
++
+ 	if (ic->provided_data_sectors != old_provided_data_sectors) {
+ 		if (ic->provided_data_sectors > old_provided_data_sectors &&
+ 		    ic->mode == 'B' &&
+@@ -3370,6 +3378,7 @@ static void dm_integrity_io_hints(struct dm_target *ti, struct queue_limits *lim
+ 		limits->logical_block_size = ic->sectors_per_block << SECTOR_SHIFT;
+ 		limits->physical_block_size = ic->sectors_per_block << SECTOR_SHIFT;
+ 		blk_limits_io_min(limits, ic->sectors_per_block << SECTOR_SHIFT);
++		limits->dma_alignment = limits->logical_block_size - 1;
+ 	}
+ }
+ 
+diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
+index 20fd688f72e7c..178e13a5b059f 100644
+--- a/drivers/md/dm-log-writes.c
++++ b/drivers/md/dm-log-writes.c
+@@ -875,6 +875,7 @@ static void log_writes_io_hints(struct dm_target *ti, struct queue_limits *limit
+ 	limits->logical_block_size = bdev_logical_block_size(lc->dev->bdev);
+ 	limits->physical_block_size = bdev_physical_block_size(lc->dev->bdev);
+ 	limits->io_min = limits->physical_block_size;
++	limits->dma_alignment = limits->logical_block_size - 1;
+ }
+ 
+ #if IS_ENABLED(CONFIG_FS_DAX)
+diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
+index 24150c933fcbe..dc3253b318daf 100644
+--- a/drivers/net/arcnet/com20020_cs.c
++++ b/drivers/net/arcnet/com20020_cs.c
+@@ -113,6 +113,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
+ 	struct com20020_dev *info;
+ 	struct net_device *dev;
+ 	struct arcnet_local *lp;
++	int ret = -ENOMEM;
+ 
+ 	dev_dbg(&p_dev->dev, "com20020_attach()\n");
+ 
+@@ -142,12 +143,18 @@ static int com20020_probe(struct pcmcia_device *p_dev)
+ 	info->dev = dev;
+ 	p_dev->priv = info;
+ 
+-	return com20020_config(p_dev);
++	ret = com20020_config(p_dev);
++	if (ret)
++		goto fail_config;
++
++	return 0;
+ 
++fail_config:
++	free_arcdev(dev);
+ fail_alloc_dev:
+ 	kfree(info);
+ fail_alloc_info:
+-	return -ENOMEM;
++	return ret;
+ } /* com20020_attach */
+ 
+ static void com20020_detach(struct pcmcia_device *link)
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 86d42306aa5ee..76dd5ff1d99d5 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3231,16 +3231,23 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
+ 		       struct slave *slave)
+ {
+ 	struct slave *curr_active_slave, *curr_arp_slave;
+-	struct icmp6hdr *hdr = icmp6_hdr(skb);
+ 	struct in6_addr *saddr, *daddr;
++	struct {
++		struct ipv6hdr ip6;
++		struct icmp6hdr icmp6;
++	} *combined, _combined;
+ 
+ 	if (skb->pkt_type == PACKET_OTHERHOST ||
+-	    skb->pkt_type == PACKET_LOOPBACK ||
+-	    hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
++	    skb->pkt_type == PACKET_LOOPBACK)
++		goto out;
++
++	combined = skb_header_pointer(skb, 0, sizeof(_combined), &_combined);
++	if (!combined || combined->ip6.nexthdr != NEXTHDR_ICMP ||
++	    combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
+ 		goto out;
+ 
+-	saddr = &ipv6_hdr(skb)->saddr;
+-	daddr = &ipv6_hdr(skb)->daddr;
++	saddr = &combined->ip6.saddr;
++	daddr = &combined->ip6.saddr;
+ 
+ 	slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n",
+ 		  __func__, slave->dev->name, bond_slave_state(slave),
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index cd4115a1b81c6..0deac073d9cfa 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -268,8 +268,6 @@ struct gs_can {
+ 
+ 	struct usb_anchor tx_submitted;
+ 	atomic_t active_tx_urbs;
+-	void *rxbuf[GS_MAX_RX_URBS];
+-	dma_addr_t rxbuf_dma[GS_MAX_RX_URBS];
+ };
+ 
+ /* usb interface struct */
+@@ -587,9 +585,6 @@ static void gs_usb_xmit_callback(struct urb *urb)
+ 
+ 	if (urb->status)
+ 		netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);
+-
+-	usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+-			  urb->transfer_buffer, urb->transfer_dma);
+ }
+ 
+ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+@@ -618,8 +613,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 	if (!urb)
+ 		goto nomem_urb;
+ 
+-	hf = usb_alloc_coherent(dev->udev, dev->hf_size_tx, GFP_ATOMIC,
+-				&urb->transfer_dma);
++	hf = kmalloc(dev->hf_size_tx, GFP_ATOMIC);
+ 	if (!hf) {
+ 		netdev_err(netdev, "No memory left for USB buffer\n");
+ 		goto nomem_hf;
+@@ -663,7 +657,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 			  hf, dev->hf_size_tx,
+ 			  gs_usb_xmit_callback, txc);
+ 
+-	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++	urb->transfer_flags |= URB_FREE_BUFFER;
+ 	usb_anchor_urb(urb, &dev->tx_submitted);
+ 
+ 	can_put_echo_skb(skb, netdev, idx, 0);
+@@ -678,8 +672,6 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 		gs_free_tx_context(txc);
+ 
+ 		usb_unanchor_urb(urb);
+-		usb_free_coherent(dev->udev, urb->transfer_buffer_length,
+-				  urb->transfer_buffer, urb->transfer_dma);
+ 
+ 		if (rc == -ENODEV) {
+ 			netif_device_detach(netdev);
+@@ -699,8 +691,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 	return NETDEV_TX_OK;
+ 
+  badidx:
+-	usb_free_coherent(dev->udev, urb->transfer_buffer_length,
+-			  urb->transfer_buffer, urb->transfer_dma);
++	kfree(hf);
+  nomem_hf:
+ 	usb_free_urb(urb);
+ 
+@@ -744,7 +735,6 @@ static int gs_can_open(struct net_device *netdev)
+ 		for (i = 0; i < GS_MAX_RX_URBS; i++) {
+ 			struct urb *urb;
+ 			u8 *buf;
+-			dma_addr_t buf_dma;
+ 
+ 			/* alloc rx urb */
+ 			urb = usb_alloc_urb(0, GFP_KERNEL);
+@@ -752,10 +742,8 @@ static int gs_can_open(struct net_device *netdev)
+ 				return -ENOMEM;
+ 
+ 			/* alloc rx buffer */
+-			buf = usb_alloc_coherent(dev->udev,
+-						 dev->parent->hf_size_rx,
+-						 GFP_KERNEL,
+-						 &buf_dma);
++			buf = kmalloc(dev->parent->hf_size_rx,
++				      GFP_KERNEL);
+ 			if (!buf) {
+ 				netdev_err(netdev,
+ 					   "No memory left for USB buffer\n");
+@@ -763,8 +751,6 @@ static int gs_can_open(struct net_device *netdev)
+ 				return -ENOMEM;
+ 			}
+ 
+-			urb->transfer_dma = buf_dma;
+-
+ 			/* fill, anchor, and submit rx urb */
+ 			usb_fill_bulk_urb(urb,
+ 					  dev->udev,
+@@ -773,7 +759,7 @@ static int gs_can_open(struct net_device *netdev)
+ 					  buf,
+ 					  dev->parent->hf_size_rx,
+ 					  gs_usb_receive_bulk_callback, parent);
+-			urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++			urb->transfer_flags |= URB_FREE_BUFFER;
+ 
+ 			usb_anchor_urb(urb, &parent->rx_submitted);
+ 
+@@ -786,17 +772,10 @@ static int gs_can_open(struct net_device *netdev)
+ 					   "usb_submit failed (err=%d)\n", rc);
+ 
+ 				usb_unanchor_urb(urb);
+-				usb_free_coherent(dev->udev,
+-						  sizeof(struct gs_host_frame),
+-						  buf,
+-						  buf_dma);
+ 				usb_free_urb(urb);
+ 				break;
+ 			}
+ 
+-			dev->rxbuf[i] = buf;
+-			dev->rxbuf_dma[i] = buf_dma;
+-
+ 			/* Drop reference,
+ 			 * USB core will take care of freeing it
+ 			 */
+@@ -854,7 +833,6 @@ static int gs_can_close(struct net_device *netdev)
+ 	int rc;
+ 	struct gs_can *dev = netdev_priv(netdev);
+ 	struct gs_usb *parent = dev->parent;
+-	unsigned int i;
+ 
+ 	netif_stop_queue(netdev);
+ 
+@@ -862,11 +840,6 @@ static int gs_can_close(struct net_device *netdev)
+ 	parent->active_channels--;
+ 	if (!parent->active_channels) {
+ 		usb_kill_anchored_urbs(&parent->rx_submitted);
+-		for (i = 0; i < GS_MAX_RX_URBS; i++)
+-			usb_free_coherent(dev->udev,
+-					  sizeof(struct gs_host_frame),
+-					  dev->rxbuf[i],
+-					  dev->rxbuf_dma[i]);
+ 	}
+ 
+ 	/* Stop sending URBs */
+diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
+index 215dd17ca7906..4059fcc8c8326 100644
+--- a/drivers/net/dsa/sja1105/sja1105_mdio.c
++++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
+@@ -256,6 +256,9 @@ static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
+ 	u32 tmp;
+ 	int rc;
+ 
++	if (reg & MII_ADDR_C45)
++		return -EOPNOTSUPP;
++
+ 	rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
+ 			      &tmp, NULL);
+ 	if (rc < 0)
+@@ -272,6 +275,9 @@ static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
+ 	const struct sja1105_regs *regs = priv->info->regs;
+ 	u32 tmp = val;
+ 
++	if (reg & MII_ADDR_C45)
++		return -EOPNOTSUPP;
++
+ 	return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
+ 				&tmp, NULL);
+ }
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+index 11d15cd036005..77d4cb4ad7823 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+@@ -795,16 +795,20 @@ static void bnx2x_vf_enable_traffic(struct bnx2x *bp, struct bnx2x_virtf *vf)
+ 
+ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
+ {
+-	struct pci_dev *dev;
+ 	struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
++	struct pci_dev *dev;
++	bool pending;
+ 
+ 	if (!vf)
+ 		return false;
+ 
+ 	dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn);
+-	if (dev)
+-		return bnx2x_is_pcie_pending(dev);
+-	return false;
++	if (!dev)
++		return false;
++	pending = bnx2x_is_pcie_pending(dev);
++	pci_dev_put(dev);
++
++	return pending;
+ }
+ 
+ int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)
+diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+index bf6a721430400..1e5dc0ea0e311 100644
+--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+@@ -1799,7 +1799,7 @@ static int liquidio_open(struct net_device *netdev)
+ 
+ 	ifstate_set(lio, LIO_IFSTATE_RUNNING);
+ 
+-	if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on)) {
++	if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) {
+ 		ret = setup_tx_poll_fn(netdev);
+ 		if (ret)
+ 			goto err_poll;
+@@ -1829,7 +1829,7 @@ static int liquidio_open(struct net_device *netdev)
+ 	return 0;
+ 
+ err_rx_ctrl:
+-	if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on))
++	if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on)
+ 		cleanup_tx_poll_fn(netdev);
+ err_poll:
+ 	if (lio->ptp_clock) {
+diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+index 2f6484dc186ab..7eb2ddbe9bad6 100644
+--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+@@ -1436,8 +1436,10 @@ static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
+ 		return AE_OK;
+ 	}
+ 
+-	if (strncmp(string.pointer, bgx_sel, 4))
++	if (strncmp(string.pointer, bgx_sel, 4)) {
++		kfree(string.pointer);
+ 		return AE_OK;
++	}
+ 
+ 	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ 			    bgx_acpi_register_phy, NULL, bgx, NULL);
+diff --git a/drivers/net/ethernet/davicom/dm9051.c b/drivers/net/ethernet/davicom/dm9051.c
+index a523ddda76093..de7105a847479 100644
+--- a/drivers/net/ethernet/davicom/dm9051.c
++++ b/drivers/net/ethernet/davicom/dm9051.c
+@@ -798,8 +798,10 @@ static int dm9051_loop_rx(struct board_info *db)
+ 		}
+ 
+ 		ret = dm9051_stop_mrcmd(db);
+-		if (ret)
++		if (ret) {
++			dev_kfree_skb(skb);
+ 			return ret;
++		}
+ 
+ 		skb->protocol = eth_type_trans(skb, db->ndev);
+ 		if (db->ndev->features & NETIF_F_RXCSUM)
+diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c
+index a5f7152a17160..6a2617cc54908 100644
+--- a/drivers/net/ethernet/engleder/tsnep_main.c
++++ b/drivers/net/ethernet/engleder/tsnep_main.c
+@@ -504,6 +504,27 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
+ 	return (budget != 0);
+ }
+ 
++static bool tsnep_tx_pending(struct tsnep_tx *tx)
++{
++	unsigned long flags;
++	struct tsnep_tx_entry *entry;
++	bool pending = false;
++
++	spin_lock_irqsave(&tx->lock, flags);
++
++	if (tx->read != tx->write) {
++		entry = &tx->entry[tx->read];
++		if ((__le32_to_cpu(entry->desc_wb->properties) &
++		     TSNEP_TX_DESC_OWNER_MASK) ==
++		    (entry->properties & TSNEP_TX_DESC_OWNER_MASK))
++			pending = true;
++	}
++
++	spin_unlock_irqrestore(&tx->lock, flags);
++
++	return pending;
++}
++
+ static int tsnep_tx_open(struct tsnep_adapter *adapter, void __iomem *addr,
+ 			 struct tsnep_tx *tx)
+ {
+@@ -751,6 +772,19 @@ static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi,
+ 	return done;
+ }
+ 
++static bool tsnep_rx_pending(struct tsnep_rx *rx)
++{
++	struct tsnep_rx_entry *entry;
++
++	entry = &rx->entry[rx->read];
++	if ((__le32_to_cpu(entry->desc_wb->properties) &
++	     TSNEP_DESC_OWNER_COUNTER_MASK) ==
++	    (entry->properties & TSNEP_DESC_OWNER_COUNTER_MASK))
++		return true;
++
++	return false;
++}
++
+ static int tsnep_rx_open(struct tsnep_adapter *adapter, void __iomem *addr,
+ 			 struct tsnep_rx *rx)
+ {
+@@ -795,6 +829,17 @@ static void tsnep_rx_close(struct tsnep_rx *rx)
+ 	tsnep_rx_ring_cleanup(rx);
+ }
+ 
++static bool tsnep_pending(struct tsnep_queue *queue)
++{
++	if (queue->tx && tsnep_tx_pending(queue->tx))
++		return true;
++
++	if (queue->rx && tsnep_rx_pending(queue->rx))
++		return true;
++
++	return false;
++}
++
+ static int tsnep_poll(struct napi_struct *napi, int budget)
+ {
+ 	struct tsnep_queue *queue = container_of(napi, struct tsnep_queue,
+@@ -815,9 +860,19 @@ static int tsnep_poll(struct napi_struct *napi, int budget)
+ 	if (!complete)
+ 		return budget;
+ 
+-	if (likely(napi_complete_done(napi, done)))
++	if (likely(napi_complete_done(napi, done))) {
+ 		tsnep_enable_irq(queue->adapter, queue->irq_mask);
+ 
++		/* reschedule if work is already pending, prevent rotten packets
++		 * which are transmitted or received after polling but before
++		 * interrupt enable
++		 */
++		if (tsnep_pending(queue)) {
++			tsnep_disable_irq(queue->adapter, queue->irq_mask);
++			napi_schedule(napi);
++		}
++	}
++
+ 	return min(done, budget - 1);
+ }
+ 
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index d0fd3045ce111..1d8ec1b120a13 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -2058,7 +2058,7 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+ 	/* enable Tx ints by setting pkt thr to 1 */
+ 	enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1);
+ 
+-	tbmr = ENETC_TBMR_EN;
++	tbmr = ENETC_TBMR_EN | ENETC_TBMR_SET_PRIO(tx_ring->prio);
+ 	if (tx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
+ 		tbmr |= ENETC_TBMR_VIH;
+ 
+@@ -2121,13 +2121,14 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+ 
+ static void enetc_setup_bdrs(struct enetc_ndev_priv *priv)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_setup_txbdr(&priv->si->hw, priv->tx_ring[i]);
++		enetc_setup_txbdr(hw, priv->tx_ring[i]);
+ 
+ 	for (i = 0; i < priv->num_rx_rings; i++)
+-		enetc_setup_rxbdr(&priv->si->hw, priv->rx_ring[i]);
++		enetc_setup_rxbdr(hw, priv->rx_ring[i]);
+ }
+ 
+ static void enetc_clear_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+@@ -2160,13 +2161,14 @@ static void enetc_clear_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+ 
+ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_clear_txbdr(&priv->si->hw, priv->tx_ring[i]);
++		enetc_clear_txbdr(hw, priv->tx_ring[i]);
+ 
+ 	for (i = 0; i < priv->num_rx_rings; i++)
+-		enetc_clear_rxbdr(&priv->si->hw, priv->rx_ring[i]);
++		enetc_clear_rxbdr(hw, priv->rx_ring[i]);
+ 
+ 	udelay(1);
+ }
+@@ -2174,13 +2176,13 @@ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
+ static int enetc_setup_irqs(struct enetc_ndev_priv *priv)
+ {
+ 	struct pci_dev *pdev = priv->si->pdev;
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i, j, err;
+ 
+ 	for (i = 0; i < priv->bdr_int_num; i++) {
+ 		int irq = pci_irq_vector(pdev, ENETC_BDR_INT_BASE_IDX + i);
+ 		struct enetc_int_vector *v = priv->int_vector[i];
+ 		int entry = ENETC_BDR_INT_BASE_IDX + i;
+-		struct enetc_hw *hw = &priv->si->hw;
+ 
+ 		snprintf(v->name, sizeof(v->name), "%s-rxtx%d",
+ 			 priv->ndev->name, i);
+@@ -2268,13 +2270,14 @@ static void enetc_setup_interrupts(struct enetc_ndev_priv *priv)
+ 
+ static void enetc_clear_interrupts(struct enetc_ndev_priv *priv)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_txbdr_wr(&priv->si->hw, i, ENETC_TBIER, 0);
++		enetc_txbdr_wr(hw, i, ENETC_TBIER, 0);
+ 
+ 	for (i = 0; i < priv->num_rx_rings; i++)
+-		enetc_rxbdr_wr(&priv->si->hw, i, ENETC_RBIER, 0);
++		enetc_rxbdr_wr(hw, i, ENETC_RBIER, 0);
+ }
+ 
+ static int enetc_phylink_connect(struct net_device *ndev)
+@@ -2441,6 +2444,7 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ {
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ 	struct tc_mqprio_qopt *mqprio = type_data;
++	struct enetc_hw *hw = &priv->si->hw;
+ 	struct enetc_bdr *tx_ring;
+ 	int num_stack_tx_queues;
+ 	u8 num_tc;
+@@ -2457,7 +2461,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ 		/* Reset all ring priorities to 0 */
+ 		for (i = 0; i < priv->num_tx_rings; i++) {
+ 			tx_ring = priv->tx_ring[i];
+-			enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, 0);
++			tx_ring->prio = 0;
++			enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
+ 		}
+ 
+ 		return 0;
+@@ -2476,7 +2481,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ 	 */
+ 	for (i = 0; i < num_tc; i++) {
+ 		tx_ring = priv->tx_ring[i];
+-		enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, i);
++		tx_ring->prio = i;
++		enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
+ 	}
+ 
+ 	/* Reset the number of netdev queues based on the TC count */
+@@ -2589,19 +2595,21 @@ static int enetc_set_rss(struct net_device *ndev, int en)
+ static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
+ {
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_rx_rings; i++)
+-		enetc_bdr_enable_rxvlan(&priv->si->hw, i, en);
++		enetc_bdr_enable_rxvlan(hw, i, en);
+ }
+ 
+ static void enetc_enable_txvlan(struct net_device *ndev, bool en)
+ {
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_bdr_enable_txvlan(&priv->si->hw, i, en);
++		enetc_bdr_enable_txvlan(hw, i, en);
+ }
+ 
+ void enetc_set_features(struct net_device *ndev, netdev_features_t features)
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
+index 2cfe6944ebd32..bb1b3b0e40e4d 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.h
++++ b/drivers/net/ethernet/freescale/enetc/enetc.h
+@@ -95,6 +95,7 @@ struct enetc_bdr {
+ 		void __iomem *rcir;
+ 	};
+ 	u16 index;
++	u16 prio;
+ 	int bd_count; /* # of BDs */
+ 	int next_to_use;
+ 	int next_to_clean;
+@@ -467,19 +468,20 @@ int enetc_set_psfp(struct net_device *ndev, bool en);
+ 
+ static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	u32 reg;
+ 
+-	reg = enetc_port_rd(&priv->si->hw, ENETC_PSIDCAPR);
++	reg = enetc_port_rd(hw, ENETC_PSIDCAPR);
+ 	priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK;
+ 	/* Port stream filter capability */
+-	reg = enetc_port_rd(&priv->si->hw, ENETC_PSFCAPR);
++	reg = enetc_port_rd(hw, ENETC_PSFCAPR);
+ 	priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK;
+ 	/* Port stream gate capability */
+-	reg = enetc_port_rd(&priv->si->hw, ENETC_PSGCAPR);
++	reg = enetc_port_rd(hw, ENETC_PSGCAPR);
+ 	priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK);
+ 	priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16;
+ 	/* Port flow meter capability */
+-	reg = enetc_port_rd(&priv->si->hw, ENETC_PFMCAPR);
++	reg = enetc_port_rd(hw, ENETC_PFMCAPR);
+ 	priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK;
+ }
+ 
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+index f8a2f02ce22de..5fcb02b006999 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+@@ -17,8 +17,9 @@ static u16 enetc_get_max_gcl_len(struct enetc_hw *hw)
+ 
+ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	u32 old_speed = priv->speed;
+-	u32 pspeed;
++	u32 pspeed, tmp;
+ 
+ 	if (speed == old_speed)
+ 		return;
+@@ -39,16 +40,15 @@ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
+ 	}
+ 
+ 	priv->speed = speed;
+-	enetc_port_wr(&priv->si->hw, ENETC_PMR,
+-		      (enetc_port_rd(&priv->si->hw, ENETC_PMR)
+-		      & (~ENETC_PMR_PSPEED_MASK))
+-		      | pspeed);
++	tmp = enetc_port_rd(hw, ENETC_PMR);
++	enetc_port_wr(hw, ENETC_PMR, (tmp & ~ENETC_PMR_PSPEED_MASK) | pspeed);
+ }
+ 
+ static int enetc_setup_taprio(struct net_device *ndev,
+ 			      struct tc_taprio_qopt_offload *admin_conf)
+ {
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
+ 	struct enetc_cbd cbd = {.cmd = 0};
+ 	struct tgs_gcl_conf *gcl_config;
+ 	struct tgs_gcl_data *gcl_data;
+@@ -61,15 +61,13 @@ static int enetc_setup_taprio(struct net_device *ndev,
+ 	int err;
+ 	int i;
+ 
+-	if (admin_conf->num_entries > enetc_get_max_gcl_len(&priv->si->hw))
++	if (admin_conf->num_entries > enetc_get_max_gcl_len(hw))
+ 		return -EINVAL;
+ 	gcl_len = admin_conf->num_entries;
+ 
+-	tge = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET);
++	tge = enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET);
+ 	if (!admin_conf->enable) {
+-		enetc_wr(&priv->si->hw,
+-			 ENETC_QBV_PTGCR_OFFSET,
+-			 tge & (~ENETC_QBV_TGE));
++		enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
+ 
+ 		priv->active_offloads &= ~ENETC_F_QBV;
+ 
+@@ -117,14 +115,11 @@ static int enetc_setup_taprio(struct net_device *ndev,
+ 	cbd.cls = BDCR_CMD_PORT_GCL;
+ 	cbd.status_flags = 0;
+ 
+-	enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET,
+-		 tge | ENETC_QBV_TGE);
++	enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge | ENETC_QBV_TGE);
+ 
+ 	err = enetc_send_cmd(priv->si, &cbd);
+ 	if (err)
+-		enetc_wr(&priv->si->hw,
+-			 ENETC_QBV_PTGCR_OFFSET,
+-			 tge & (~ENETC_QBV_TGE));
++		enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
+ 
+ 	enetc_cbd_free_data_mem(priv->si, data_size, tmp, &dma);
+ 
+@@ -138,6 +133,8 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+ {
+ 	struct tc_taprio_qopt_offload *taprio = type_data;
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
++	struct enetc_bdr *tx_ring;
+ 	int err;
+ 	int i;
+ 
+@@ -146,18 +143,20 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+ 		if (priv->tx_ring[i]->tsd_enable)
+ 			return -EBUSY;
+ 
+-	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_set_bdr_prio(&priv->si->hw,
+-				   priv->tx_ring[i]->index,
+-				   taprio->enable ? i : 0);
++	for (i = 0; i < priv->num_tx_rings; i++) {
++		tx_ring = priv->tx_ring[i];
++		tx_ring->prio = taprio->enable ? i : 0;
++		enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
++	}
+ 
+ 	err = enetc_setup_taprio(ndev, taprio);
+-
+-	if (err)
+-		for (i = 0; i < priv->num_tx_rings; i++)
+-			enetc_set_bdr_prio(&priv->si->hw,
+-					   priv->tx_ring[i]->index,
+-					   taprio->enable ? 0 : i);
++	if (err) {
++		for (i = 0; i < priv->num_tx_rings; i++) {
++			tx_ring = priv->tx_ring[i];
++			tx_ring->prio = taprio->enable ? 0 : i;
++			enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
++		}
++	}
+ 
+ 	return err;
+ }
+@@ -178,7 +177,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 	struct tc_cbs_qopt_offload *cbs = type_data;
+ 	u32 port_transmit_rate = priv->speed;
+ 	u8 tc_nums = netdev_get_num_tc(ndev);
+-	struct enetc_si *si = priv->si;
++	struct enetc_hw *hw = &priv->si->hw;
+ 	u32 hi_credit_bit, hi_credit_reg;
+ 	u32 max_interference_size;
+ 	u32 port_frame_max_size;
+@@ -199,15 +198,15 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 		 * lower than this TC have been disabled.
+ 		 */
+ 		if (tc == prio_top &&
+-		    enetc_get_cbs_enable(&si->hw, prio_next)) {
++		    enetc_get_cbs_enable(hw, prio_next)) {
+ 			dev_err(&ndev->dev,
+ 				"Disable TC%d before disable TC%d\n",
+ 				prio_next, tc);
+ 			return -EINVAL;
+ 		}
+ 
+-		enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0);
+-		enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0);
++		enetc_port_wr(hw, ENETC_PTCCBSR1(tc), 0);
++		enetc_port_wr(hw, ENETC_PTCCBSR0(tc), 0);
+ 
+ 		return 0;
+ 	}
+@@ -224,13 +223,13 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 	 * higher than this TC have been enabled.
+ 	 */
+ 	if (tc == prio_next) {
+-		if (!enetc_get_cbs_enable(&si->hw, prio_top)) {
++		if (!enetc_get_cbs_enable(hw, prio_top)) {
+ 			dev_err(&ndev->dev,
+ 				"Enable TC%d first before enable TC%d\n",
+ 				prio_top, prio_next);
+ 			return -EINVAL;
+ 		}
+-		bw_sum += enetc_get_cbs_bw(&si->hw, prio_top);
++		bw_sum += enetc_get_cbs_bw(hw, prio_top);
+ 	}
+ 
+ 	if (bw_sum + bw >= 100) {
+@@ -239,7 +238,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 		return -EINVAL;
+ 	}
+ 
+-	enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc));
++	enetc_port_rd(hw, ENETC_PTCMSDUR(tc));
+ 
+ 	/* For top prio TC, the max_interfrence_size is maxSizedFrame.
+ 	 *
+@@ -259,8 +258,8 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 		u32 m0, ma, r0, ra;
+ 
+ 		m0 = port_frame_max_size * 8;
+-		ma = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(prio_top)) * 8;
+-		ra = enetc_get_cbs_bw(&si->hw, prio_top) *
++		ma = enetc_port_rd(hw, ENETC_PTCMSDUR(prio_top)) * 8;
++		ra = enetc_get_cbs_bw(hw, prio_top) *
+ 			port_transmit_rate * 10000ULL;
+ 		r0 = port_transmit_rate * 1000000ULL;
+ 		max_interference_size = m0 + ma +
+@@ -280,10 +279,10 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 	hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit,
+ 				     port_transmit_rate * 1000000ULL);
+ 
+-	enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
++	enetc_port_wr(hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
+ 
+ 	/* Set bw register and enable this traffic class */
+-	enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
++	enetc_port_wr(hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
+ 
+ 	return 0;
+ }
+@@ -293,6 +292,7 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ 	struct tc_etf_qopt_offload *qopt = type_data;
+ 	u8 tc_nums = netdev_get_num_tc(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int tc;
+ 
+ 	if (!tc_nums)
+@@ -304,12 +304,11 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+ 		return -EINVAL;
+ 
+ 	/* TSD and Qbv are mutually exclusive in hardware */
+-	if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
++	if (enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
+ 		return -EBUSY;
+ 
+ 	priv->tx_ring[tc]->tsd_enable = qopt->enable;
+-	enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc),
+-		      qopt->enable ? ENETC_TSDE : 0);
++	enetc_port_wr(hw, ENETC_PTCTSDR(tc), qopt->enable ? ENETC_TSDE : 0);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 3f6187c164240..0d1bab4ac1b07 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -298,7 +298,6 @@ struct iavf_adapter {
+ #define IAVF_FLAG_QUEUES_DISABLED		BIT(17)
+ #define IAVF_FLAG_SETUP_NETDEV_FEATURES		BIT(18)
+ #define IAVF_FLAG_REINIT_MSIX_NEEDED		BIT(20)
+-#define IAVF_FLAG_INITIAL_MAC_SET		BIT(23)
+ /* duplicates for common code */
+ #define IAVF_FLAG_DCB_ENABLED			0
+ 	/* flags for admin queue service task */
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 79fef8c59d652..cff03723f4f9f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1087,12 +1087,6 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
+ 	if (ret)
+ 		return ret;
+ 
+-	/* If this is an initial set MAC during VF spawn do not wait */
+-	if (adapter->flags & IAVF_FLAG_INITIAL_MAC_SET) {
+-		adapter->flags &= ~IAVF_FLAG_INITIAL_MAC_SET;
+-		return 0;
+-	}
+-
+ 	ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
+ 					       iavf_is_mac_set_handled(netdev, addr->sa_data),
+ 					       msecs_to_jiffies(2500));
+@@ -2605,8 +2599,6 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter)
+ 		ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr);
+ 	}
+ 
+-	adapter->flags |= IAVF_FLAG_INITIAL_MAC_SET;
+-
+ 	adapter->tx_desc_count = IAVF_DEFAULT_TXD;
+ 	adapter->rx_desc_count = IAVF_DEFAULT_RXD;
+ 	err = iavf_init_interrupt_scheme(adapter);
+@@ -2921,7 +2913,6 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
+ 	iavf_free_queues(adapter);
+ 	memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
+ 	iavf_shutdown_adminq(&adapter->hw);
+-	adapter->netdev->flags &= ~IFF_UP;
+ 	adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
+ 	iavf_change_state(adapter, __IAVF_DOWN);
+ 	wake_up(&adapter->down_waitqueue);
+@@ -3021,6 +3012,11 @@ static void iavf_reset_task(struct work_struct *work)
+ 		iavf_disable_vf(adapter);
+ 		mutex_unlock(&adapter->client_lock);
+ 		mutex_unlock(&adapter->crit_lock);
++		if (netif_running(netdev)) {
++			rtnl_lock();
++			dev_close(netdev);
++			rtnl_unlock();
++		}
+ 		return; /* Do not attempt to reinit. It's dead, Jim. */
+ 	}
+ 
+@@ -3033,6 +3029,7 @@ continue_reset:
+ 
+ 	if (running) {
+ 		netif_carrier_off(netdev);
++		netif_tx_stop_all_queues(netdev);
+ 		adapter->link_up = false;
+ 		iavf_napi_disable_all(adapter);
+ 	}
+@@ -3172,6 +3169,16 @@ reset_err:
+ 
+ 	mutex_unlock(&adapter->client_lock);
+ 	mutex_unlock(&adapter->crit_lock);
++
++	if (netif_running(netdev)) {
++		/* Close device to ensure that Tx queues will not be started
++		 * during netif_device_attach() at the end of the reset task.
++		 */
++		rtnl_lock();
++		dev_close(netdev);
++		rtnl_unlock();
++	}
++
+ 	dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
+ reset_finish:
+ 	rtnl_lock();
+@@ -5035,23 +5042,21 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
+ static void iavf_remove(struct pci_dev *pdev)
+ {
+ 	struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
+-	struct net_device *netdev = adapter->netdev;
+ 	struct iavf_fdir_fltr *fdir, *fdirtmp;
+ 	struct iavf_vlan_filter *vlf, *vlftmp;
++	struct iavf_cloud_filter *cf, *cftmp;
+ 	struct iavf_adv_rss *rss, *rsstmp;
+ 	struct iavf_mac_filter *f, *ftmp;
+-	struct iavf_cloud_filter *cf, *cftmp;
+-	struct iavf_hw *hw = &adapter->hw;
++	struct net_device *netdev;
++	struct iavf_hw *hw;
+ 	int err;
+ 
+-	/* When reboot/shutdown is in progress no need to do anything
+-	 * as the adapter is already REMOVE state that was set during
+-	 * iavf_shutdown() callback.
+-	 */
+-	if (adapter->state == __IAVF_REMOVE)
++	netdev = adapter->netdev;
++	hw = &adapter->hw;
++
++	if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
+ 		return;
+ 
+-	set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
+ 	/* Wait until port initialization is complete.
+ 	 * There are flows where register/unregister netdev may race.
+ 	 */
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index eaa51cd7456b6..8f86be995092b 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7352,6 +7352,7 @@ static int mvpp2_get_sram(struct platform_device *pdev,
+ 			  struct mvpp2 *priv)
+ {
+ 	struct resource *res;
++	void __iomem *base;
+ 
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ 	if (!res) {
+@@ -7362,9 +7363,12 @@ static int mvpp2_get_sram(struct platform_device *pdev,
+ 		return 0;
+ 	}
+ 
+-	priv->cm3_base = devm_ioremap_resource(&pdev->dev, res);
++	base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(base))
++		return PTR_ERR(base);
+ 
+-	return PTR_ERR_OR_ZERO(priv->cm3_base);
++	priv->cm3_base = base;
++	return 0;
+ }
+ 
+ static int mvpp2_probe(struct platform_device *pdev)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+index f42a09f04b256..70cda15713245 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+@@ -535,6 +535,8 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
+ 		sprintf(lmac, "LMAC%d", lmac_id);
+ 		seq_printf(filp, "%s\t0x%x\t\tNIX%d\t\t%s\t%s\n",
+ 			   dev_name(&pdev->dev), pcifunc, blkid, cgx, lmac);
++
++		pci_dev_put(pdev);
+ 	}
+ 	return 0;
+ }
+@@ -2221,6 +2223,7 @@ static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
+ 		}
+ 	}
+ 
++	pci_dev_put(pdev);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index 0879a48411f31..3dc90060d70d7 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -4979,6 +4979,8 @@ static int nix_setup_ipolicers(struct rvu *rvu,
+ 		ipolicer->ref_count = devm_kcalloc(rvu->dev,
+ 						   ipolicer->band_prof.max,
+ 						   sizeof(u16), GFP_KERNEL);
++		if (!ipolicer->ref_count)
++			return -ENOMEM;
+ 	}
+ 
+ 	/* Set policer timeunit to 2us ie  (19 + 1) * 100 nsec = 2us */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+index b04fb226f708a..ae50d56258ec6 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+@@ -62,15 +62,18 @@ int rvu_sdp_init(struct rvu *rvu)
+ 		pfvf->sdp_info = devm_kzalloc(rvu->dev,
+ 					      sizeof(struct sdp_node_info),
+ 					      GFP_KERNEL);
+-		if (!pfvf->sdp_info)
++		if (!pfvf->sdp_info) {
++			pci_dev_put(pdev);
+ 			return -ENOMEM;
++		}
+ 
+ 		dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]);
+ 
+-		put_device(&pdev->dev);
+ 		i++;
+ 	}
+ 
++	pci_dev_put(pdev);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+index a0ad0bcbf89f4..9f588ecba93e2 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+@@ -730,6 +730,7 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id)
+ 	return 0;
+ 
+ err_sfp_bind:
++	unregister_netdev(dev);
+ err_register_netdev:
+ 	prestera_port_list_del(port);
+ err_port_init:
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 84433f3a3e228..5380caf0acc2f 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2363,8 +2363,10 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
+ 				data + NET_SKB_PAD + eth->ip_align,
+ 				ring->buf_size, DMA_FROM_DEVICE);
+ 			if (unlikely(dma_mapping_error(eth->dma_dev,
+-						       dma_addr)))
++						       dma_addr))) {
++				skb_free_frag(data);
+ 				return -ENOMEM;
++			}
+ 		}
+ 		rxd->rxd1 = (unsigned int)dma_addr;
+ 		ring->data[i] = data;
+@@ -2979,8 +2981,10 @@ static int mtk_open(struct net_device *dev)
+ 		u32 gdm_config = MTK_GDMA_TO_PDMA;
+ 
+ 		err = mtk_start_dma(eth);
+-		if (err)
++		if (err) {
++			phylink_disconnect_phy(mac->phylink);
+ 			return err;
++		}
+ 
+ 		if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
+ 			gdm_config = MTK_GDMA_TO_PPE;
+@@ -4103,12 +4107,12 @@ static int mtk_probe(struct platform_device *pdev)
+ 		eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
+ 		if (!eth->ppe) {
+ 			err = -ENOMEM;
+-			goto err_free_dev;
++			goto err_deinit_mdio;
+ 		}
+ 
+ 		err = mtk_eth_offload_init(eth);
+ 		if (err)
+-			goto err_free_dev;
++			goto err_deinit_mdio;
+ 	}
+ 
+ 	for (i = 0; i < MTK_MAX_DEVS; i++) {
+diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
+index b149e601f6737..48cfaa7eaf50c 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
++++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
+@@ -697,7 +697,8 @@ static int mlx4_create_zones(struct mlx4_dev *dev,
+ 			err = mlx4_bitmap_init(*bitmap + k, 1,
+ 					       MLX4_QP_TABLE_RAW_ETH_SIZE - 1, 0,
+ 					       0);
+-			mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
++			if (!err)
++				mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
+ 		}
+ 
+ 		if (err)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 2e0d59ca62b50..74bd05e5dda23 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -45,6 +45,8 @@
+ #include "mlx5_core.h"
+ #include "lib/eq.h"
+ #include "lib/tout.h"
++#define CREATE_TRACE_POINTS
++#include "diag/cmd_tracepoint.h"
+ 
+ enum {
+ 	CMD_IF_REV = 5,
+@@ -785,27 +787,14 @@ EXPORT_SYMBOL(mlx5_cmd_out_err);
+ static void cmd_status_print(struct mlx5_core_dev *dev, void *in, void *out)
+ {
+ 	u16 opcode, op_mod;
+-	u32 syndrome;
+-	u8  status;
+ 	u16 uid;
+-	int err;
+-
+-	syndrome = MLX5_GET(mbox_out, out, syndrome);
+-	status = MLX5_GET(mbox_out, out, status);
+ 
+ 	opcode = MLX5_GET(mbox_in, in, opcode);
+ 	op_mod = MLX5_GET(mbox_in, in, op_mod);
+ 	uid    = MLX5_GET(mbox_in, in, uid);
+ 
+-	err = cmd_status_to_err(status);
+-
+ 	if (!uid && opcode != MLX5_CMD_OP_DESTROY_MKEY)
+ 		mlx5_cmd_out_err(dev, opcode, op_mod, out);
+-	else
+-		mlx5_core_dbg(dev,
+-			"%s(0x%x) op_mod(0x%x) uid(%d) failed, status %s(0x%x), syndrome (0x%x), err(%d)\n",
+-			mlx5_command_str(opcode), opcode, op_mod, uid,
+-			cmd_status_str(status), status, syndrome, err);
+ }
+ 
+ int mlx5_cmd_check(struct mlx5_core_dev *dev, int err, void *in, void *out)
+@@ -1016,6 +1005,7 @@ static void cmd_work_handler(struct work_struct *work)
+ 		cmd_ent_get(ent);
+ 	set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
+ 
++	cmd_ent_get(ent); /* for the _real_ FW event on completion */
+ 	/* Skip sending command to fw if internal error */
+ 	if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) {
+ 		ent->ret = -ENXIO;
+@@ -1023,7 +1013,6 @@ static void cmd_work_handler(struct work_struct *work)
+ 		return;
+ 	}
+ 
+-	cmd_ent_get(ent); /* for the _real_ FW event on completion */
+ 	/* ring doorbell after the descriptor is valid */
+ 	mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx);
+ 	wmb();
+@@ -1672,8 +1661,8 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
+ 				cmd_ent_put(ent); /* timeout work was canceled */
+ 
+ 			if (!forced || /* Real FW completion */
+-			    pci_channel_offline(dev->pdev) || /* FW is inaccessible */
+-			    dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
++			     mlx5_cmd_is_down(dev) || /* No real FW completion is expected */
++			     !opcode_allowed(cmd, ent->op))
+ 				cmd_ent_put(ent);
+ 
+ 			ent->ts2 = ktime_get_ns();
+@@ -1892,6 +1881,16 @@ out_in:
+ 	return err;
+ }
+ 
++static void mlx5_cmd_err_trace(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod, void *out)
++{
++	u32 syndrome = MLX5_GET(mbox_out, out, syndrome);
++	u8 status = MLX5_GET(mbox_out, out, status);
++
++	trace_mlx5_cmd(mlx5_command_str(opcode), opcode, op_mod,
++		       cmd_status_str(status), status, syndrome,
++		       cmd_status_to_err(status));
++}
++
+ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,
+ 			   u32 syndrome, int err)
+ {
+@@ -1914,7 +1913,7 @@ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,
+ }
+ 
+ /* preserve -EREMOTEIO for outbox.status != OK, otherwise return err as is */
+-static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, void *out)
++static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, u16 op_mod, void *out)
+ {
+ 	u32 syndrome = MLX5_GET(mbox_out, out, syndrome);
+ 	u8 status = MLX5_GET(mbox_out, out, status);
+@@ -1922,8 +1921,10 @@ static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, void *
+ 	if (err == -EREMOTEIO) /* -EREMOTEIO is preserved */
+ 		err = -EIO;
+ 
+-	if (!err && status != MLX5_CMD_STAT_OK)
++	if (!err && status != MLX5_CMD_STAT_OK) {
+ 		err = -EREMOTEIO;
++		mlx5_cmd_err_trace(dev, opcode, op_mod, out);
++	}
+ 
+ 	cmd_status_log(dev, opcode, status, syndrome, err);
+ 	return err;
+@@ -1951,9 +1952,9 @@ int mlx5_cmd_do(struct mlx5_core_dev *dev, void *in, int in_size, void *out, int
+ {
+ 	int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, false);
+ 	u16 opcode = MLX5_GET(mbox_in, in, opcode);
++	u16 op_mod = MLX5_GET(mbox_in, in, op_mod);
+ 
+-	err = cmd_status_err(dev, err, opcode, out);
+-	return err;
++	return cmd_status_err(dev, err, opcode, op_mod, out);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_do);
+ 
+@@ -1997,8 +1998,9 @@ int mlx5_cmd_exec_polling(struct mlx5_core_dev *dev, void *in, int in_size,
+ {
+ 	int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, true);
+ 	u16 opcode = MLX5_GET(mbox_in, in, opcode);
++	u16 op_mod = MLX5_GET(mbox_in, in, op_mod);
+ 
+-	err = cmd_status_err(dev, err, opcode, out);
++	err = cmd_status_err(dev, err, opcode, op_mod, out);
+ 	return mlx5_cmd_check(dev, err, in, out);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_exec_polling);
+@@ -2034,7 +2036,7 @@ static void mlx5_cmd_exec_cb_handler(int status, void *_work)
+ 	struct mlx5_async_ctx *ctx;
+ 
+ 	ctx = work->ctx;
+-	status = cmd_status_err(ctx->dev, status, work->opcode, work->out);
++	status = cmd_status_err(ctx->dev, status, work->opcode, work->op_mod, work->out);
+ 	work->user_callback(status, work);
+ 	if (atomic_dec_and_test(&ctx->num_inflight))
+ 		complete(&ctx->inflight_done);
+@@ -2049,6 +2051,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
+ 	work->ctx = ctx;
+ 	work->user_callback = callback;
+ 	work->opcode = MLX5_GET(mbox_in, in, opcode);
++	work->op_mod = MLX5_GET(mbox_in, in, op_mod);
+ 	work->out = out;
+ 	if (WARN_ON(!atomic_inc_not_zero(&ctx->num_inflight)))
+ 		return -EIO;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h
+new file mode 100644
+index 0000000000000..406ebe17405f9
+--- /dev/null
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h
+@@ -0,0 +1,45 @@
++/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
++/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM mlx5
++
++#if !defined(_MLX5_CMD_TP_H_) || defined(TRACE_HEADER_MULTI_READ)
++#define _MLX5_CMD_TP_H_
++
++#include <linux/tracepoint.h>
++#include <linux/trace_seq.h>
++
++TRACE_EVENT(mlx5_cmd,
++	    TP_PROTO(const char *command_str, u16 opcode, u16 op_mod,
++		     const char *status_str, u8 status, u32 syndrome, int err),
++	    TP_ARGS(command_str, opcode, op_mod, status_str, status, syndrome, err),
++	    TP_STRUCT__entry(__string(command_str, command_str)
++			     __field(u16, opcode)
++			     __field(u16, op_mod)
++			    __string(status_str, status_str)
++			    __field(u8, status)
++			    __field(u32, syndrome)
++			    __field(int, err)
++			    ),
++	    TP_fast_assign(__assign_str(command_str, command_str);
++			__entry->opcode = opcode;
++			__entry->op_mod = op_mod;
++			__assign_str(status_str, status_str);
++			__entry->status = status;
++			__entry->syndrome = syndrome;
++			__entry->err = err;
++	    ),
++	    TP_printk("%s(0x%x) op_mod(0x%x) failed, status %s(0x%x), syndrome (0x%x), err(%d)",
++		      __get_str(command_str), __entry->opcode, __entry->op_mod,
++		      __get_str(status_str), __entry->status, __entry->syndrome,
++		      __entry->err)
++);
++
++#endif /* _MLX5_CMD_TP_H_ */
++
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH ./diag
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE cmd_tracepoint
++#include <trace/define_trace.h>
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 978a2bb8e1220..21831386b26e8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -638,7 +638,7 @@ static void mlx5_tracer_handle_timestamp_trace(struct mlx5_fw_tracer *tracer,
+ 			trace_timestamp = (timestamp_event.timestamp & MASK_52_7) |
+ 					  (str_frmt->timestamp & MASK_6_0);
+ 		else
+-			trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) |
++			trace_timestamp = ((timestamp_event.timestamp - 1) & MASK_52_7) |
+ 					  (str_frmt->timestamp & MASK_6_0);
+ 
+ 		mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+index 5aff979143678..ff73d25bc6eb8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+@@ -224,15 +224,16 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ 	list_for_each_entry(flow, flow_list, tmp_list) {
+ 		if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
+ 			continue;
+-		spec = &flow->attr->parse_attr->spec;
+-
+-		/* update from encap rule to slow path rule */
+-		rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+ 
+ 		attr = mlx5e_tc_get_encap_attr(flow);
+ 		esw_attr = attr->esw_attr;
+ 		/* mark the flow's encap dest as non-valid */
+ 		esw_attr->dests[flow->tmp_entry_index].flags &= ~MLX5_ESW_DEST_ENCAP_VALID;
++		esw_attr->dests[flow->tmp_entry_index].pkt_reformat = NULL;
++
++		/* update from encap rule to slow path rule */
++		spec = &flow->attr->parse_attr->spec;
++		rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+ 
+ 		if (IS_ERR(rule)) {
+ 			err = PTR_ERR(rule);
+@@ -251,6 +252,7 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ 	/* we know that the encap is valid */
+ 	e->flags &= ~MLX5_ENCAP_ENTRY_VALID;
+ 	mlx5_packet_reformat_dealloc(priv->mdev, e->pkt_reformat);
++	e->pkt_reformat = NULL;
+ }
+ 
+ static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow,
+@@ -762,8 +764,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
+ 		       struct net_device *mirred_dev,
+ 		       int out_index,
+ 		       struct netlink_ext_ack *extack,
+-		       struct net_device **encap_dev,
+-		       bool *encap_valid)
++		       struct net_device **encap_dev)
+ {
+ 	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+ 	struct mlx5e_tc_flow_parse_attr *parse_attr;
+@@ -878,9 +879,8 @@ attach_flow:
+ 	if (e->flags & MLX5_ENCAP_ENTRY_VALID) {
+ 		attr->esw_attr->dests[out_index].pkt_reformat = e->pkt_reformat;
+ 		attr->esw_attr->dests[out_index].flags |= MLX5_ESW_DEST_ENCAP_VALID;
+-		*encap_valid = true;
+ 	} else {
+-		*encap_valid = false;
++		flow_flag_set(flow, SLOW);
+ 	}
+ 	mutex_unlock(&esw->offloads.encap_tbl_lock);
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
+index d542b8476491e..8ad273dde40ee 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
+@@ -17,8 +17,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
+ 		       struct net_device *mirred_dev,
+ 		       int out_index,
+ 		       struct netlink_ext_ack *extack,
+-		       struct net_device **encap_dev,
+-		       bool *encap_valid);
++		       struct net_device **encap_dev);
+ 
+ int mlx5e_attach_decap(struct mlx5e_priv *priv,
+ 		       struct mlx5e_tc_flow *flow,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index 229c14b1af004..949ef560df787 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -1620,7 +1620,6 @@ set_encap_dests(struct mlx5e_priv *priv,
+ 		struct mlx5e_tc_flow *flow,
+ 		struct mlx5_flow_attr *attr,
+ 		struct netlink_ext_ack *extack,
+-		bool *encap_valid,
+ 		bool *vf_tun)
+ {
+ 	struct mlx5e_tc_flow_parse_attr *parse_attr;
+@@ -1637,7 +1636,6 @@ set_encap_dests(struct mlx5e_priv *priv,
+ 	parse_attr = attr->parse_attr;
+ 	esw_attr = attr->esw_attr;
+ 	*vf_tun = false;
+-	*encap_valid = true;
+ 
+ 	for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
+ 		struct net_device *out_dev;
+@@ -1654,7 +1652,7 @@ set_encap_dests(struct mlx5e_priv *priv,
+ 			goto out;
+ 		}
+ 		err = mlx5e_attach_encap(priv, flow, attr, out_dev, out_index,
+-					 extack, &encap_dev, encap_valid);
++					 extack, &encap_dev);
+ 		dev_put(out_dev);
+ 		if (err)
+ 			goto out;
+@@ -1718,8 +1716,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ 	struct mlx5e_tc_flow_parse_attr *parse_attr;
+ 	struct mlx5_flow_attr *attr = flow->attr;
+ 	struct mlx5_esw_flow_attr *esw_attr;
+-	bool vf_tun, encap_valid;
+ 	u32 max_prio, max_chain;
++	bool vf_tun;
+ 	int err = 0;
+ 
+ 	parse_attr = attr->parse_attr;
+@@ -1809,7 +1807,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ 		esw_attr->int_port = int_port;
+ 	}
+ 
+-	err = set_encap_dests(priv, flow, attr, extack, &encap_valid, &vf_tun);
++	err = set_encap_dests(priv, flow, attr, extack, &vf_tun);
+ 	if (err)
+ 		goto err_out;
+ 
+@@ -1839,7 +1837,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ 	 * (1) there's no error
+ 	 * (2) there's an encap action and we don't have valid neigh
+ 	 */
+-	if (!encap_valid || flow_flag_test(flow, SLOW))
++	if (flow_flag_test(flow, SLOW))
+ 		flow->rule[0] = mlx5e_tc_offload_to_slow_path(esw, flow, &parse_attr->spec);
+ 	else
+ 		flow->rule[0] = mlx5e_tc_offload_fdb_rules(esw, flow, &parse_attr->spec, attr);
+@@ -3737,7 +3735,7 @@ alloc_flow_post_acts(struct mlx5e_tc_flow *flow, struct netlink_ext_ack *extack)
+ 	struct mlx5e_post_act *post_act = get_post_action(flow->priv);
+ 	struct mlx5_flow_attr *attr, *next_attr = NULL;
+ 	struct mlx5e_post_act_handle *handle;
+-	bool vf_tun, encap_valid = true;
++	bool vf_tun;
+ 	int err;
+ 
+ 	/* This is going in reverse order as needed.
+@@ -3759,13 +3757,10 @@ alloc_flow_post_acts(struct mlx5e_tc_flow *flow, struct netlink_ext_ack *extack)
+ 		if (list_is_last(&attr->list, &flow->attrs))
+ 			break;
+ 
+-		err = set_encap_dests(flow->priv, flow, attr, extack, &encap_valid, &vf_tun);
++		err = set_encap_dests(flow->priv, flow, attr, extack, &vf_tun);
+ 		if (err)
+ 			goto out_free;
+ 
+-		if (!encap_valid)
+-			flow_flag_set(flow, SLOW);
+-
+ 		err = actions_prepare_mod_hdr_actions(flow->priv, flow, attr, extack);
+ 		if (err)
+ 			goto out_free;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 3c68cac4a9c2c..061ac87993546 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -431,7 +431,7 @@ esw_setup_vport_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *f
+ 		    mlx5_lag_mpesw_is_activated(esw->dev))
+ 			dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_UPLINK;
+ 	}
+-	if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) {
++	if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP_VALID) {
+ 		if (pkt_reformat) {
+ 			flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
+ 			flow_act->pkt_reformat = esw_attr->dests[attr_idx].pkt_reformat;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 9d908a0ccfef1..1e46f9afa40e0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -9,7 +9,8 @@ enum {
+ 	MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+ 	MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+ 	MLX5_FW_RESET_FLAGS_PENDING_COMP,
+-	MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS
++	MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
++	MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
+ };
+ 
+ struct mlx5_fw_reset {
+@@ -406,7 +407,7 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ 	err = mlx5_pci_link_toggle(dev);
+ 	if (err) {
+ 		mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, no reset done, err %d\n", err);
+-		goto done;
++		set_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags);
+ 	}
+ 
+ 	mlx5_enter_error_state(dev, true);
+@@ -482,6 +483,10 @@ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev)
+ 		goto out;
+ 	}
+ 	err = fw_reset->ret;
++	if (test_and_clear_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags)) {
++		mlx5_unload_one_devl_locked(dev);
++		mlx5_load_one_devl_locked(dev, false);
++	}
+ out:
+ 	clear_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags);
+ 	return err;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index e5e32430b6afd..ac178796e484f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1759,7 +1759,8 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
+ 	res = state == pci_channel_io_perm_failure ?
+ 		PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
+ 
+-	mlx5_pci_trace(dev, "Exit, result = %d, %s\n",  res, result2str(res));
++	mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, result = %d, %s\n",
++		       __func__, dev->state, dev->pci_status, res, result2str(res));
+ 	return res;
+ }
+ 
+@@ -1798,7 +1799,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
+ 	struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
+ 	int err;
+ 
+-	mlx5_pci_trace(dev, "Enter\n");
++	mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Enter\n",
++		       __func__, dev->state, dev->pci_status);
+ 
+ 	err = mlx5_pci_enable_device(dev);
+ 	if (err) {
+@@ -1820,7 +1822,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
+ 
+ 	res = PCI_ERS_RESULT_RECOVERED;
+ out:
+-	mlx5_pci_trace(dev, "Exit, err = %d, result = %d, %s\n", err, res, result2str(res));
++	mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, err = %d, result = %d, %s\n",
++		       __func__, dev->state, dev->pci_status, err, res, result2str(res));
+ 	return res;
+ }
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
+index 7da012ff0d419..8e2abbab05f04 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
+@@ -18,6 +18,10 @@ struct mlx5_sf_dev_table {
+ 	phys_addr_t base_address;
+ 	u64 sf_bar_length;
+ 	struct notifier_block nb;
++	struct mutex table_lock; /* Serializes sf life cycle and vhca state change handler */
++	struct workqueue_struct *active_wq;
++	struct work_struct work;
++	u8 stop_active_wq:1;
+ 	struct mlx5_core_dev *dev;
+ };
+ 
+@@ -168,6 +172,7 @@ mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_
+ 		return 0;
+ 
+ 	sf_index = event->function_id - base_id;
++	mutex_lock(&table->table_lock);
+ 	sf_dev = xa_load(&table->devices, sf_index);
+ 	switch (event->new_vhca_state) {
+ 	case MLX5_VHCA_STATE_INVALID:
+@@ -191,6 +196,7 @@ mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_
+ 	default:
+ 		break;
+ 	}
++	mutex_unlock(&table->table_lock);
+ 	return 0;
+ }
+ 
+@@ -215,6 +221,78 @@ static int mlx5_sf_dev_vhca_arm_all(struct mlx5_sf_dev_table *table)
+ 	return 0;
+ }
+ 
++static void mlx5_sf_dev_add_active_work(struct work_struct *work)
++{
++	struct mlx5_sf_dev_table *table = container_of(work, struct mlx5_sf_dev_table, work);
++	u32 out[MLX5_ST_SZ_DW(query_vhca_state_out)] = {};
++	struct mlx5_core_dev *dev = table->dev;
++	u16 max_functions;
++	u16 function_id;
++	u16 sw_func_id;
++	int err = 0;
++	u8 state;
++	int i;
++
++	max_functions = mlx5_sf_max_functions(dev);
++	function_id = MLX5_CAP_GEN(dev, sf_base_id);
++	for (i = 0; i < max_functions; i++, function_id++) {
++		if (table->stop_active_wq)
++			return;
++		err = mlx5_cmd_query_vhca_state(dev, function_id, out, sizeof(out));
++		if (err)
++			/* A failure of specific vhca doesn't mean others will
++			 * fail as well.
++			 */
++			continue;
++		state = MLX5_GET(query_vhca_state_out, out, vhca_state_context.vhca_state);
++		if (state != MLX5_VHCA_STATE_ACTIVE)
++			continue;
++
++		sw_func_id = MLX5_GET(query_vhca_state_out, out, vhca_state_context.sw_function_id);
++		mutex_lock(&table->table_lock);
++		/* Don't probe device which is already probe */
++		if (!xa_load(&table->devices, i))
++			mlx5_sf_dev_add(dev, i, function_id, sw_func_id);
++		/* There is a race where SF got inactive after the query
++		 * above. e.g.: the query returns that the state of the
++		 * SF is active, and after that the eswitch manager set it to
++		 * inactive.
++		 * This case cannot be managed in SW, since the probing of the
++		 * SF is on one system, and the inactivation is on a different
++		 * system.
++		 * If the inactive is done after the SF perform init_hca(),
++		 * the SF will fully probe and then removed. If it was
++		 * done before init_hca(), the SF probe will fail.
++		 */
++		mutex_unlock(&table->table_lock);
++	}
++}
++
++/* In case SFs are generated externally, probe active SFs */
++static int mlx5_sf_dev_queue_active_work(struct mlx5_sf_dev_table *table)
++{
++	if (MLX5_CAP_GEN(table->dev, eswitch_manager))
++		return 0; /* the table is local */
++
++	/* Use a workqueue to probe active SFs, which are in large
++	 * quantity and may take up to minutes to probe.
++	 */
++	table->active_wq = create_singlethread_workqueue("mlx5_active_sf");
++	if (!table->active_wq)
++		return -ENOMEM;
++	INIT_WORK(&table->work, &mlx5_sf_dev_add_active_work);
++	queue_work(table->active_wq, &table->work);
++	return 0;
++}
++
++static void mlx5_sf_dev_destroy_active_work(struct mlx5_sf_dev_table *table)
++{
++	if (table->active_wq) {
++		table->stop_active_wq = true;
++		destroy_workqueue(table->active_wq);
++	}
++}
++
+ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ {
+ 	struct mlx5_sf_dev_table *table;
+@@ -240,11 +318,17 @@ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ 	table->base_address = pci_resource_start(dev->pdev, 2);
+ 	table->max_sfs = max_sfs;
+ 	xa_init(&table->devices);
++	mutex_init(&table->table_lock);
+ 	dev->priv.sf_dev_table = table;
+ 
+ 	err = mlx5_vhca_event_notifier_register(dev, &table->nb);
+ 	if (err)
+ 		goto vhca_err;
++
++	err = mlx5_sf_dev_queue_active_work(table);
++	if (err)
++		goto add_active_err;
++
+ 	err = mlx5_sf_dev_vhca_arm_all(table);
+ 	if (err)
+ 		goto arm_err;
+@@ -252,6 +336,8 @@ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ 	return;
+ 
+ arm_err:
++	mlx5_sf_dev_destroy_active_work(table);
++add_active_err:
+ 	mlx5_vhca_event_notifier_unregister(dev, &table->nb);
+ vhca_err:
+ 	table->max_sfs = 0;
+@@ -279,7 +365,9 @@ void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev)
+ 	if (!table)
+ 		return;
+ 
++	mlx5_sf_dev_destroy_active_work(table);
+ 	mlx5_vhca_event_notifier_unregister(dev, &table->nb);
++	mutex_destroy(&table->table_lock);
+ 
+ 	/* Now that event handler is not running, it is safe to destroy
+ 	 * the sf device without race.
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+index af4d3e1f1a6d9..3f112a897a601 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+@@ -103,7 +103,7 @@ static int sparx5_port_open(struct net_device *ndev)
+ 	err = phylink_of_phy_connect(port->phylink, port->of_node, 0);
+ 	if (err) {
+ 		netdev_err(ndev, "Could not attach to PHY\n");
+-		return err;
++		goto err_connect;
+ 	}
+ 
+ 	phylink_start(port->phylink);
+@@ -115,10 +115,20 @@ static int sparx5_port_open(struct net_device *ndev)
+ 			err = sparx5_serdes_set(port->sparx5, port, &port->conf);
+ 		else
+ 			err = phy_power_on(port->serdes);
+-		if (err)
++		if (err) {
+ 			netdev_err(ndev, "%s failed\n", __func__);
++			goto out_power;
++		}
+ 	}
+ 
++	return 0;
++
++out_power:
++	phylink_stop(port->phylink);
++	phylink_disconnect_phy(port->phylink);
++err_connect:
++	sparx5_port_enable(port, false);
++
+ 	return err;
+ }
+ 
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+index 405786c003347..cb08d7bf95241 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+@@ -341,7 +341,7 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
+ 		return ret;
+ 
+ 	attrs.split = eth_port.is_split;
+-	attrs.splittable = !attrs.split;
++	attrs.splittable = eth_port.port_lanes > 1 && !attrs.split;
+ 	attrs.lanes = eth_port.port_lanes;
+ 	attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ 	attrs.phys.port_number = eth_port.label_port;
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+index b19bff0db1fdc..400b22ad6a346 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+@@ -1395,6 +1395,9 @@ nfp_port_get_module_info(struct net_device *netdev,
+ 	u8 data;
+ 
+ 	port = nfp_port_from_netdev(netdev);
++	if (!port)
++		return -EOPNOTSUPP;
++
+ 	/* update port state to get latest interface */
+ 	set_bit(NFP_PORT_CHANGED, &port->flags);
+ 	eth_port = nfp_port_get_eth_port(port);
+diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+index 46da937ad27f8..63b6b7d86ccbe 100644
+--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+@@ -1143,6 +1143,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
+ 		buffer_info->dma = 0;
+ 		buffer_info->time_stamp = 0;
+ 		tx_ring->next_to_use = ring_num;
++		dev_kfree_skb_any(skb);
+ 		return;
+ 	}
+ 	buffer_info->mapped = true;
+@@ -2459,6 +2460,7 @@ static void pch_gbe_remove(struct pci_dev *pdev)
+ 	unregister_netdev(netdev);
+ 
+ 	pch_gbe_phy_hw_reset(&adapter->hw);
++	pci_dev_put(adapter->ptp_pdev);
+ 
+ 	free_netdev(netdev);
+ }
+@@ -2534,7 +2536,7 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+ 	/* setup the private structure */
+ 	ret = pch_gbe_sw_init(adapter);
+ 	if (ret)
+-		goto err_free_netdev;
++		goto err_put_dev;
+ 
+ 	/* Initialize PHY */
+ 	ret = pch_gbe_init_phy(adapter);
+@@ -2592,6 +2594,8 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+ 
+ err_free_adapter:
+ 	pch_gbe_phy_hw_reset(&adapter->hw);
++err_put_dev:
++	pci_dev_put(adapter->ptp_pdev);
+ err_free_netdev:
+ 	free_netdev(netdev);
+ 	return ret;
+diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
+index 06f4d9a9e9388..5a2d70a91868e 100644
+--- a/drivers/net/ethernet/qlogic/qla3xxx.c
++++ b/drivers/net/ethernet/qlogic/qla3xxx.c
+@@ -2471,6 +2471,7 @@ static netdev_tx_t ql3xxx_send(struct sk_buff *skb,
+ 					     skb_shinfo(skb)->nr_frags);
+ 	if (tx_cb->seg_count == -1) {
+ 		netdev_err(ndev, "%s: invalid segment count!\n", __func__);
++		dev_kfree_skb_any(skb);
+ 		return NETDEV_TX_OK;
+ 	}
+ 
+diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
+index 17b9d37218cbc..4c33c3b5f32b5 100644
+--- a/drivers/net/ethernet/sfc/ef100_netdev.c
++++ b/drivers/net/ethernet/sfc/ef100_netdev.c
+@@ -217,6 +217,7 @@ netdev_tx_t __ef100_hard_start_xmit(struct sk_buff *skb,
+ 		   skb->len, skb->data_len, channel->channel);
+ 	if (!efx->n_channels || !efx->n_tx_channels || !channel) {
+ 		netif_stop_queue(net_dev);
++		dev_kfree_skb_any(skb);
+ 		goto err;
+ 	}
+ 
+diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
+index de94921cbef9f..025e0c19ec255 100644
+--- a/drivers/net/ipvlan/ipvlan.h
++++ b/drivers/net/ipvlan/ipvlan.h
+@@ -98,6 +98,7 @@ struct ipvl_port {
+ 	struct sk_buff_head	backlog;
+ 	int			count;
+ 	struct ida		ida;
++	netdevice_tracker	dev_tracker;
+ };
+ 
+ struct ipvl_skb_cb {
+diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
+index 49ba8a50dfb1e..9043bcd1b41db 100644
+--- a/drivers/net/ipvlan/ipvlan_main.c
++++ b/drivers/net/ipvlan/ipvlan_main.c
+@@ -83,6 +83,7 @@ static int ipvlan_port_create(struct net_device *dev)
+ 	if (err)
+ 		goto err;
+ 
++	netdev_hold(dev, &port->dev_tracker, GFP_KERNEL);
+ 	return 0;
+ 
+ err:
+@@ -95,6 +96,7 @@ static void ipvlan_port_destroy(struct net_device *dev)
+ 	struct ipvl_port *port = ipvlan_port_get_rtnl(dev);
+ 	struct sk_buff *skb;
+ 
++	netdev_put(dev, &port->dev_tracker);
+ 	if (port->mode == IPVLAN_MODE_L3S)
+ 		ipvlan_l3s_unregister(port);
+ 	netdev_rx_handler_unregister(dev);
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index ddfa853ec9b53..104fc564a766e 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -2685,11 +2685,6 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ 	if (ret)
+ 		goto rollback;
+ 
+-	/* Force features update, since they are different for SW MACSec and
+-	 * HW offloading cases.
+-	 */
+-	netdev_update_features(dev);
+-
+ 	rtnl_unlock();
+ 	return 0;
+ 
+@@ -3457,16 +3452,9 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
+ 	return ret;
+ }
+ 
+-#define SW_MACSEC_FEATURES \
++#define MACSEC_FEATURES \
+ 	(NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
+ 
+-/* If h/w offloading is enabled, use real device features save for
+- *   VLAN_FEATURES - they require additional ops
+- *   HW_MACSEC - no reason to report it
+- */
+-#define REAL_DEV_FEATURES(dev) \
+-	((dev)->features & ~(NETIF_F_VLAN_FEATURES | NETIF_F_HW_MACSEC))
+-
+ static int macsec_dev_init(struct net_device *dev)
+ {
+ 	struct macsec_dev *macsec = macsec_priv(dev);
+@@ -3483,12 +3471,8 @@ static int macsec_dev_init(struct net_device *dev)
+ 		return err;
+ 	}
+ 
+-	if (macsec_is_offloaded(macsec)) {
+-		dev->features = REAL_DEV_FEATURES(real_dev);
+-	} else {
+-		dev->features = real_dev->features & SW_MACSEC_FEATURES;
+-		dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
+-	}
++	dev->features = real_dev->features & MACSEC_FEATURES;
++	dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
+ 
+ 	dev->needed_headroom = real_dev->needed_headroom +
+ 			       MACSEC_NEEDED_HEADROOM;
+@@ -3520,10 +3504,7 @@ static netdev_features_t macsec_fix_features(struct net_device *dev,
+ 	struct macsec_dev *macsec = macsec_priv(dev);
+ 	struct net_device *real_dev = macsec->real_dev;
+ 
+-	if (macsec_is_offloaded(macsec))
+-		return REAL_DEV_FEATURES(real_dev);
+-
+-	features &= (real_dev->features & SW_MACSEC_FEATURES) |
++	features &= (real_dev->features & MACSEC_FEATURES) |
+ 		    NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES;
+ 	features |= NETIF_F_LLTX;
+ 
+@@ -3874,7 +3855,6 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
+ 	if (macsec_is_offloaded(macsec)) {
+ 		const struct macsec_ops *ops;
+ 		struct macsec_context ctx;
+-		int ret;
+ 
+ 		ops = macsec_get_ops(netdev_priv(dev), &ctx);
+ 		if (!ops) {
+diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
+index 59fe356942b51..249e7ee4a2bb9 100644
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -862,8 +862,10 @@ static int at803x_probe(struct phy_device *phydev)
+ 			.wolopts = 0,
+ 		};
+ 
+-		if (ccr < 0)
++		if (ccr < 0) {
++			ret = ccr;
+ 			goto err;
++		}
+ 		mode_cfg = ccr & AT803X_MODE_CFG_MASK;
+ 
+ 		switch (mode_cfg) {
+diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
+index 8d5cbda33f66f..0897fdb6254b8 100644
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -1915,6 +1915,7 @@ static const struct driver_info cdc_ncm_zlp_info = {
+ 	.status = cdc_ncm_status,
+ 	.rx_fixup = cdc_ncm_rx_fixup,
+ 	.tx_fixup = cdc_ncm_tx_fixup,
++	.set_rx_mode = usbnet_cdc_update_filter,
+ };
+ 
+ /* Same as cdc_ncm_info, but with FLAG_WWAN */
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 26c34a7c21bdd..afd6faa4c2ec9 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1357,6 +1357,7 @@ static const struct usb_device_id products[] = {
+ 	{QMI_FIXED_INTF(0x2357, 0x0201, 4)},	/* TP-LINK HSUPA Modem MA180 */
+ 	{QMI_FIXED_INTF(0x2357, 0x9000, 4)},	/* TP-LINK MA260 */
+ 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */
++	{QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */
+ 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)},	/* Telit LE922A */
+ 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)},	/* Telit FN980 */
+ 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1057, 2)},	/* Telit FN980 */
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 9cce7dec7366d..f5c88d232b110 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -3933,12 +3933,11 @@ static int virtnet_probe(struct virtio_device *vdev)
+ 	return 0;
+ 
+ free_unregister_netdev:
+-	virtio_reset_device(vdev);
+-
+ 	unregister_netdev(dev);
+ free_failover:
+ 	net_failover_destroy(vi->failover);
+ free_vqs:
++	virtio_reset_device(vdev);
+ 	cancel_delayed_work_sync(&vi->refill);
+ 	free_receive_page_frags(vi);
+ 	virtnet_del_vqs(vi);
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
+index 2ec56a34fa810..0909d53cefebc 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.h
++++ b/drivers/net/wireless/ath/ath11k/qmi.h
+@@ -27,7 +27,7 @@
+ #define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01	52
+ #define ATH11K_QMI_CALDB_SIZE			0x480000
+ #define ATH11K_QMI_BDF_EXT_STR_LENGTH		0x20
+-#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT	3
++#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT	5
+ 
+ #define QMI_WLFW_REQUEST_MEM_IND_V01		0x0035
+ #define QMI_WLFW_FW_MEM_READY_IND_V01		0x0037
+diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c
+index 10daef81c3553..fb2c35bd73bb1 100644
+--- a/drivers/net/wireless/cisco/airo.c
++++ b/drivers/net/wireless/cisco/airo.c
+@@ -5232,7 +5232,7 @@ static int get_wep_tx_idx(struct airo_info *ai)
+ 	return -1;
+ }
+ 
+-static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
++static int set_wep_key(struct airo_info *ai, u16 index, const u8 *key,
+ 		       u16 keylen, int perm, int lock)
+ {
+ 	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
+@@ -5283,7 +5283,7 @@ static void proc_wepkey_on_close(struct inode *inode, struct file *file)
+ 	struct net_device *dev = pde_data(inode);
+ 	struct airo_info *ai = dev->ml_priv;
+ 	int i, rc;
+-	char key[16];
++	u8 key[16];
+ 	u16 index = 0;
+ 	int j = 0;
+ 
+@@ -5311,12 +5311,22 @@ static void proc_wepkey_on_close(struct inode *inode, struct file *file)
+ 	}
+ 
+ 	for (i = 0; i < 16*3 && data->wbuffer[i+j]; i++) {
++		int val;
++
++		if (i % 3 == 2)
++			continue;
++
++		val = hex_to_bin(data->wbuffer[i+j]);
++		if (val < 0) {
++			airo_print_err(ai->dev->name, "WebKey passed invalid key hex");
++			return;
++		}
+ 		switch(i%3) {
+ 		case 0:
+-			key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4;
++			key[i/3] = (u8)val << 4;
+ 			break;
+ 		case 1:
+-			key[i/3] |= hex_to_bin(data->wbuffer[i+j]);
++			key[i/3] |= (u8)val;
+ 			break;
+ 		}
+ 	}
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index a074552bcec3d..3179682daca70 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -910,6 +910,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
+ 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+ 	struct sk_buff *skb;
+ 	struct ieee80211_hdr *hdr;
++	struct ieee80211_tx_info *cb;
+ 
+ 	if (!vp->assoc)
+ 		return;
+@@ -931,6 +932,10 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
+ 	memcpy(hdr->addr2, mac, ETH_ALEN);
+ 	memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
+ 
++	cb = IEEE80211_SKB_CB(skb);
++	cb->control.rates[0].count = 1;
++	cb->control.rates[1].idx = -1;
++
+ 	rcu_read_lock();
+ 	mac80211_hwsim_tx_frame(data->hw, skb,
+ 				rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan);
+diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+index 3ac373d29d936..7362d4d5ea852 100644
+--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+@@ -956,30 +956,51 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
+ 		return;
+ 
+ 	while (index + sizeof(*e) <= len) {
++		u16 attr_size;
++
+ 		e = (struct wilc_attr_entry *)&buf[index];
+-		if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
++		attr_size = le16_to_cpu(e->attr_len);
++
++		if (index + sizeof(*e) + attr_size > len)
++			return;
++
++		if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST &&
++		    attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e)))
+ 			ch_list_idx = index;
+-		else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
++		else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
++			 attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
+ 			op_ch_idx = index;
++
+ 		if (ch_list_idx && op_ch_idx)
+ 			break;
+-		index += le16_to_cpu(e->attr_len) + sizeof(*e);
++
++		index += sizeof(*e) + attr_size;
+ 	}
+ 
+ 	if (ch_list_idx) {
+-		u16 attr_size;
+-		struct wilc_ch_list_elem *e;
+-		int i;
++		u16 elem_size;
+ 
+ 		ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
+-		attr_size = le16_to_cpu(ch_list->attr_len);
+-		for (i = 0; i < attr_size;) {
++		/* the number of bytes following the final 'elem' member */
++		elem_size = le16_to_cpu(ch_list->attr_len) -
++			(sizeof(*ch_list) - sizeof(struct wilc_attr_entry));
++		for (unsigned int i = 0; i < elem_size;) {
++			struct wilc_ch_list_elem *e;
++
+ 			e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
++
++			i += sizeof(*e);
++			if (i > elem_size)
++				break;
++
++			i += e->no_of_channels;
++			if (i > elem_size)
++				break;
++
+ 			if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
+ 				memset(e->ch_list, sta_ch, e->no_of_channels);
+ 				break;
+ 			}
+-			i += e->no_of_channels;
+ 		}
+ 	}
+ 
+diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
+index eb1d1ba3a443a..67df8221b5aeb 100644
+--- a/drivers/net/wireless/microchip/wilc1000/hif.c
++++ b/drivers/net/wireless/microchip/wilc1000/hif.c
+@@ -482,14 +482,25 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ 
+ 	rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
+ 	if (rsn_ie) {
++		int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
+ 		int offset = 8;
+ 
+-		param->mode_802_11i = 2;
+-		param->rsn_found = true;
+ 		/* extract RSN capabilities */
+-		offset += (rsn_ie[offset] * 4) + 2;
+-		offset += (rsn_ie[offset] * 4) + 2;
+-		memcpy(param->rsn_cap, &rsn_ie[offset], 2);
++		if (offset < rsn_ie_len) {
++			/* skip over pairwise suites */
++			offset += (rsn_ie[offset] * 4) + 2;
++
++			if (offset < rsn_ie_len) {
++				/* skip over authentication suites */
++				offset += (rsn_ie[offset] * 4) + 2;
++
++				if (offset + 1 < rsn_ie_len) {
++					param->mode_802_11i = 2;
++					param->rsn_found = true;
++					memcpy(param->rsn_cap, &rsn_ie[offset], 2);
++				}
++			}
++		}
+ 	}
+ 
+ 	if (param->rsn_found) {
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_coredump.c b/drivers/net/wwan/iosm/iosm_ipc_coredump.c
+index 9acd87724c9de..26ca30476f409 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_coredump.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_coredump.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (C) 2020-2021 Intel Corporation.
+  */
++#include <linux/vmalloc.h>
+ 
+ #include "iosm_ipc_coredump.h"
+ 
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_devlink.c b/drivers/net/wwan/iosm/iosm_ipc_devlink.c
+index 17da85a8f3371..2fe724d623c06 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_devlink.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_devlink.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (C) 2020-2021 Intel Corporation.
+  */
++#include <linux/vmalloc.h>
+ 
+ #include "iosm_ipc_chnl_cfg.h"
+ #include "iosm_ipc_coredump.h"
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+index 97cb6846c6ae2..f604d4a01e1b2 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+@@ -249,7 +249,7 @@ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
+ 	if (object->integer.value == 3)
+ 		sleep_state = IPC_PCIE_D3L2;
+ 
+-	kfree(object);
++	ACPI_FREE(object);
+ 
+ default_ret:
+ 	return sleep_state;
+diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+index 3458af31e8647..7d0f5e4f0a781 100644
+--- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
++++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+@@ -165,6 +165,8 @@ static int t7xx_acpi_reset(struct t7xx_pci_dev *t7xx_dev, char *fn_name)
+ 		return -EFAULT;
+ 	}
+ 
++	kfree(buffer.pointer);
++
+ #endif
+ 	return 0;
+ }
+diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c
+index 7764b1a4c3cf8..ec87dd21e054a 100644
+--- a/drivers/nfc/st-nci/se.c
++++ b/drivers/nfc/st-nci/se.c
+@@ -312,6 +312,8 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+ 	int r = 0;
+ 	struct device *dev = &ndev->nfc_dev->dev;
+ 	struct nfc_evt_transaction *transaction;
++	u32 aid_len;
++	u8 params_len;
+ 
+ 	pr_debug("connectivity gate event: %x\n", event);
+ 
+@@ -325,26 +327,47 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+ 		 * Description  Tag     Length
+ 		 * AID          81      5 to 16
+ 		 * PARAMETERS   82      0 to 255
++		 *
++		 * The key differences are aid storage length is variably sized
++		 * in the packet, but fixed in nfc_evt_transaction, and that
++		 * the aid_len is u8 in the packet, but u32 in the structure,
++		 * and the tags in the packet are not included in
++		 * nfc_evt_transaction.
++		 *
++		 * size(b):  1          1       5-16 1             1           0-255
++		 * offset:   0          1       2    aid_len + 2   aid_len + 3 aid_len + 4
++		 * mem name: aid_tag(M) aid_len aid  params_tag(M) params_len  params
++		 * example:  0x81       5-16    X    0x82          0-255       X
+ 		 */
+-		if (skb->len < NFC_MIN_AID_LENGTH + 2 &&
+-		    skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
++		if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+ 			return -EPROTO;
+ 
+-		transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL);
+-		if (!transaction)
+-			return -ENOMEM;
++		aid_len = skb->data[1];
+ 
+-		transaction->aid_len = skb->data[1];
+-		memcpy(transaction->aid, &skb->data[2], transaction->aid_len);
++		if (skb->len < aid_len + 4 ||
++		    aid_len > sizeof(transaction->aid))
++			return -EPROTO;
+ 
+-		/* Check next byte is PARAMETERS tag (82) */
+-		if (skb->data[transaction->aid_len + 2] !=
+-		    NFC_EVT_TRANSACTION_PARAMS_TAG)
++		params_len = skb->data[aid_len + 3];
++
++		/* Verify PARAMETERS tag is (82), and final check that there is
++		 * enough space in the packet to read everything.
++		 */
++		if (skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG ||
++		    skb->len < aid_len + 4 + params_len)
+ 			return -EPROTO;
+ 
+-		transaction->params_len = skb->data[transaction->aid_len + 3];
+-		memcpy(transaction->params, skb->data +
+-		       transaction->aid_len + 4, transaction->params_len);
++		transaction = devm_kzalloc(dev, sizeof(*transaction) +
++					   params_len, GFP_KERNEL);
++		if (!transaction)
++			return -ENOMEM;
++
++		transaction->aid_len = aid_len;
++		transaction->params_len = params_len;
++
++		memcpy(transaction->aid, &skb->data[2], aid_len);
++		memcpy(transaction->params, &skb->data[aid_len + 4],
++		       params_len);
+ 
+ 		r = nfc_se_transaction(ndev->nfc_dev, host, transaction);
+ 		break;
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index ed47c256dbd27..01c36284e5428 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -675,6 +675,7 @@ void nvme_init_request(struct request *req, struct nvme_command *cmd)
+ 	if (req->mq_hctx->type == HCTX_TYPE_POLL)
+ 		req->cmd_flags |= REQ_POLLED;
+ 	nvme_clear_nvme_request(req);
++	req->rq_flags |= RQF_QUIET;
+ 	memcpy(nvme_req(req)->cmd, cmd, sizeof(*cmd));
+ }
+ EXPORT_SYMBOL_GPL(nvme_init_request);
+@@ -1037,7 +1038,6 @@ int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
+ 			goto out;
+ 	}
+ 
+-	req->rq_flags |= RQF_QUIET;
+ 	ret = nvme_execute_rq(req, at_head);
+ 	if (result && ret >= 0)
+ 		*result = nvme_req(req)->result;
+@@ -1225,7 +1225,6 @@ static void nvme_keep_alive_work(struct work_struct *work)
+ 	rq->timeout = ctrl->kato * HZ;
+ 	rq->end_io = nvme_keep_alive_end_io;
+ 	rq->end_io_data = ctrl;
+-	rq->rq_flags |= RQF_QUIET;
+ 	blk_execute_rq_nowait(rq, false);
+ }
+ 
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 1a6423e94eb30..0f34114c4596d 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -1438,7 +1438,6 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
+ 
+ 	abort_req->end_io = abort_endio;
+ 	abort_req->end_io_data = NULL;
+-	abort_req->rq_flags |= RQF_QUIET;
+ 	blk_execute_rq_nowait(abort_req, false);
+ 
+ 	/*
+@@ -2489,7 +2488,6 @@ static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode)
+ 	req->end_io_data = nvmeq;
+ 
+ 	init_completion(&nvmeq->delete_done);
+-	req->rq_flags |= RQF_QUIET;
+ 	blk_execute_rq_nowait(req, false);
+ 	return 0;
+ }
+diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
+index 7f52d9dac4432..a79eadb953de9 100644
+--- a/drivers/nvme/target/configfs.c
++++ b/drivers/nvme/target/configfs.c
+@@ -1215,6 +1215,7 @@ static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
+ 		const char *page, size_t count)
+ {
+ 	int pos = 0, len;
++	char *val;
+ 
+ 	if (subsys->subsys_discovered) {
+ 		pr_err("Can't set model number. %s is already assigned\n",
+@@ -1237,9 +1238,11 @@ static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
+ 			return -EINVAL;
+ 	}
+ 
+-	subsys->model_number = kmemdup_nul(page, len, GFP_KERNEL);
+-	if (!subsys->model_number)
++	val = kmemdup_nul(page, len, GFP_KERNEL);
++	if (!val)
+ 		return -ENOMEM;
++	kfree(subsys->model_number);
++	subsys->model_number = val;
+ 	return count;
+ }
+ 
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
+index ba64284eaf9fa..f1ec8931dfbc5 100644
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -1613,7 +1613,7 @@ out:
+ }
+ 
+ static u32 hv_compose_msi_req_v1(
+-	struct pci_create_interrupt *int_pkt, const struct cpumask *affinity,
++	struct pci_create_interrupt *int_pkt,
+ 	u32 slot, u8 vector, u16 vector_count)
+ {
+ 	int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
+@@ -1631,6 +1631,35 @@ static u32 hv_compose_msi_req_v1(
+ 	return sizeof(*int_pkt);
+ }
+ 
++/*
++ * The vCPU selected by hv_compose_multi_msi_req_get_cpu() and
++ * hv_compose_msi_req_get_cpu() is a "dummy" vCPU because the final vCPU to be
++ * interrupted is specified later in hv_irq_unmask() and communicated to Hyper-V
++ * via the HVCALL_RETARGET_INTERRUPT hypercall. But the choice of dummy vCPU is
++ * not irrelevant because Hyper-V chooses the physical CPU to handle the
++ * interrupts based on the vCPU specified in message sent to the vPCI VSP in
++ * hv_compose_msi_msg(). Hyper-V's choice of pCPU is not visible to the guest,
++ * but assigning too many vPCI device interrupts to the same pCPU can cause a
++ * performance bottleneck. So we spread out the dummy vCPUs to influence Hyper-V
++ * to spread out the pCPUs that it selects.
++ *
++ * For the single-MSI and MSI-X cases, it's OK for hv_compose_msi_req_get_cpu()
++ * to always return the same dummy vCPU, because a second call to
++ * hv_compose_msi_msg() contains the "real" vCPU, causing Hyper-V to choose a
++ * new pCPU for the interrupt. But for the multi-MSI case, the second call to
++ * hv_compose_msi_msg() exits without sending a message to the vPCI VSP, so the
++ * original dummy vCPU is used. This dummy vCPU must be round-robin'ed so that
++ * the pCPUs are spread out. All interrupts for a multi-MSI device end up using
++ * the same pCPU, even though the vCPUs will be spread out by later calls
++ * to hv_irq_unmask(), but that is the best we can do now.
++ *
++ * With Hyper-V in Nov 2022, the HVCALL_RETARGET_INTERRUPT hypercall does *not*
++ * cause Hyper-V to reselect the pCPU based on the specified vCPU. Such an
++ * enhancement is planned for a future version. With that enhancement, the
++ * dummy vCPU selection won't matter, and interrupts for the same multi-MSI
++ * device will be spread across multiple pCPUs.
++ */
++
+ /*
+  * Create MSI w/ dummy vCPU set targeting just one vCPU, overwritten
+  * by subsequent retarget in hv_irq_unmask().
+@@ -1640,18 +1669,39 @@ static int hv_compose_msi_req_get_cpu(const struct cpumask *affinity)
+ 	return cpumask_first_and(affinity, cpu_online_mask);
+ }
+ 
+-static u32 hv_compose_msi_req_v2(
+-	struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity,
+-	u32 slot, u8 vector, u16 vector_count)
++/*
++ * Make sure the dummy vCPU values for multi-MSI don't all point to vCPU0.
++ */
++static int hv_compose_multi_msi_req_get_cpu(void)
+ {
++	static DEFINE_SPINLOCK(multi_msi_cpu_lock);
++
++	/* -1 means starting with CPU 0 */
++	static int cpu_next = -1;
++
++	unsigned long flags;
+ 	int cpu;
+ 
++	spin_lock_irqsave(&multi_msi_cpu_lock, flags);
++
++	cpu_next = cpumask_next_wrap(cpu_next, cpu_online_mask, nr_cpu_ids,
++				     false);
++	cpu = cpu_next;
++
++	spin_unlock_irqrestore(&multi_msi_cpu_lock, flags);
++
++	return cpu;
++}
++
++static u32 hv_compose_msi_req_v2(
++	struct pci_create_interrupt2 *int_pkt, int cpu,
++	u32 slot, u8 vector, u16 vector_count)
++{
+ 	int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE2;
+ 	int_pkt->wslot.slot = slot;
+ 	int_pkt->int_desc.vector = vector;
+ 	int_pkt->int_desc.vector_count = vector_count;
+ 	int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+-	cpu = hv_compose_msi_req_get_cpu(affinity);
+ 	int_pkt->int_desc.processor_array[0] =
+ 		hv_cpu_number_to_vp_number(cpu);
+ 	int_pkt->int_desc.processor_count = 1;
+@@ -1660,18 +1710,15 @@ static u32 hv_compose_msi_req_v2(
+ }
+ 
+ static u32 hv_compose_msi_req_v3(
+-	struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity,
++	struct pci_create_interrupt3 *int_pkt, int cpu,
+ 	u32 slot, u32 vector, u16 vector_count)
+ {
+-	int cpu;
+-
+ 	int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE3;
+ 	int_pkt->wslot.slot = slot;
+ 	int_pkt->int_desc.vector = vector;
+ 	int_pkt->int_desc.reserved = 0;
+ 	int_pkt->int_desc.vector_count = vector_count;
+ 	int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+-	cpu = hv_compose_msi_req_get_cpu(affinity);
+ 	int_pkt->int_desc.processor_array[0] =
+ 		hv_cpu_number_to_vp_number(cpu);
+ 	int_pkt->int_desc.processor_count = 1;
+@@ -1715,12 +1762,18 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 			struct pci_create_interrupt3 v3;
+ 		} int_pkts;
+ 	} __packed ctxt;
++	bool multi_msi;
+ 	u64 trans_id;
+ 	u32 size;
+ 	int ret;
++	int cpu;
++
++	msi_desc  = irq_data_get_msi_desc(data);
++	multi_msi = !msi_desc->pci.msi_attrib.is_msix &&
++		    msi_desc->nvec_used > 1;
+ 
+ 	/* Reuse the previous allocation */
+-	if (data->chip_data) {
++	if (data->chip_data && multi_msi) {
+ 		int_desc = data->chip_data;
+ 		msg->address_hi = int_desc->address >> 32;
+ 		msg->address_lo = int_desc->address & 0xffffffff;
+@@ -1728,7 +1781,6 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 		return;
+ 	}
+ 
+-	msi_desc  = irq_data_get_msi_desc(data);
+ 	pdev = msi_desc_to_pci_dev(msi_desc);
+ 	dest = irq_data_get_effective_affinity_mask(data);
+ 	pbus = pdev->bus;
+@@ -1738,11 +1790,18 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 	if (!hpdev)
+ 		goto return_null_message;
+ 
++	/* Free any previous message that might have already been composed. */
++	if (data->chip_data && !multi_msi) {
++		int_desc = data->chip_data;
++		data->chip_data = NULL;
++		hv_int_desc_free(hpdev, int_desc);
++	}
++
+ 	int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC);
+ 	if (!int_desc)
+ 		goto drop_reference;
+ 
+-	if (!msi_desc->pci.msi_attrib.is_msix && msi_desc->nvec_used > 1) {
++	if (multi_msi) {
+ 		/*
+ 		 * If this is not the first MSI of Multi MSI, we already have
+ 		 * a mapping.  Can exit early.
+@@ -1767,9 +1826,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 		 */
+ 		vector = 32;
+ 		vector_count = msi_desc->nvec_used;
++		cpu = hv_compose_multi_msi_req_get_cpu();
+ 	} else {
+ 		vector = hv_msi_get_int_vector(data);
+ 		vector_count = 1;
++		cpu = hv_compose_msi_req_get_cpu(dest);
+ 	}
+ 
+ 	/*
+@@ -1785,7 +1846,6 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 	switch (hbus->protocol_version) {
+ 	case PCI_PROTOCOL_VERSION_1_1:
+ 		size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
+-					dest,
+ 					hpdev->desc.win_slot.slot,
+ 					(u8)vector,
+ 					vector_count);
+@@ -1794,7 +1854,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 	case PCI_PROTOCOL_VERSION_1_2:
+ 	case PCI_PROTOCOL_VERSION_1_3:
+ 		size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
+-					dest,
++					cpu,
+ 					hpdev->desc.win_slot.slot,
+ 					(u8)vector,
+ 					vector_count);
+@@ -1802,7 +1862,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 
+ 	case PCI_PROTOCOL_VERSION_1_4:
+ 		size = hv_compose_msi_req_v3(&ctxt.int_pkts.v3,
+-					dest,
++					cpu,
+ 					hpdev->desc.win_slot.slot,
+ 					vector,
+ 					vector_count);
+diff --git a/drivers/pinctrl/qcom/pinctrl-sc8280xp.c b/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
+index aa2075390f3eb..e96c00686a25b 100644
+--- a/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
++++ b/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
+@@ -1873,8 +1873,8 @@ static const struct msm_pingroup sc8280xp_groups[] = {
+ 	[225] = PINGROUP(225, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+ 	[226] = PINGROUP(226, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+ 	[227] = PINGROUP(227, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+-	[228] = UFS_RESET(ufs_reset, 0xf1004),
+-	[229] = UFS_RESET(ufs1_reset, 0xf3004),
++	[228] = UFS_RESET(ufs_reset, 0xf1000),
++	[229] = UFS_RESET(ufs1_reset, 0xf3000),
+ 	[230] = SDC_QDSD_PINGROUP(sdc2_clk, 0xe8000, 14, 6),
+ 	[231] = SDC_QDSD_PINGROUP(sdc2_cmd, 0xe8000, 11, 3),
+ 	[232] = SDC_QDSD_PINGROUP(sdc2_data, 0xe8000, 9, 0),
+diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
+index 585911020cea0..023f126121d7d 100644
+--- a/drivers/platform/surface/surface_aggregator_registry.c
++++ b/drivers/platform/surface/surface_aggregator_registry.c
+@@ -234,6 +234,19 @@ static const struct software_node *ssam_node_group_sl3[] = {
+ 	NULL,
+ };
+ 
++/* Devices for Surface Laptop 5. */
++static const struct software_node *ssam_node_group_sl5[] = {
++	&ssam_node_root,
++	&ssam_node_bat_ac,
++	&ssam_node_bat_main,
++	&ssam_node_tmp_pprof,
++	&ssam_node_hid_main_keyboard,
++	&ssam_node_hid_main_touchpad,
++	&ssam_node_hid_main_iid5,
++	&ssam_node_hid_sam_ucm_ucsi,
++	NULL,
++};
++
+ /* Devices for Surface Laptop Studio. */
+ static const struct software_node *ssam_node_group_sls[] = {
+ 	&ssam_node_root,
+@@ -268,6 +281,7 @@ static const struct software_node *ssam_node_group_sp7[] = {
+ 	NULL,
+ };
+ 
++/* Devices for Surface Pro 8 */
+ static const struct software_node *ssam_node_group_sp8[] = {
+ 	&ssam_node_root,
+ 	&ssam_node_hub_kip,
+@@ -284,6 +298,23 @@ static const struct software_node *ssam_node_group_sp8[] = {
+ 	NULL,
+ };
+ 
++/* Devices for Surface Pro 9 */
++static const struct software_node *ssam_node_group_sp9[] = {
++	&ssam_node_root,
++	&ssam_node_hub_kip,
++	&ssam_node_bat_ac,
++	&ssam_node_bat_main,
++	&ssam_node_tmp_pprof,
++	/* TODO: Tablet mode switch (via POS subsystem) */
++	&ssam_node_hid_kip_keyboard,
++	&ssam_node_hid_kip_penstash,
++	&ssam_node_hid_kip_touchpad,
++	&ssam_node_hid_kip_fwupd,
++	&ssam_node_hid_sam_sensors,
++	&ssam_node_hid_sam_ucm_ucsi,
++	NULL,
++};
++
+ 
+ /* -- SSAM platform/meta-hub driver. ---------------------------------------- */
+ 
+@@ -303,6 +334,9 @@ static const struct acpi_device_id ssam_platform_hub_match[] = {
+ 	/* Surface Pro 8 */
+ 	{ "MSHW0263", (unsigned long)ssam_node_group_sp8 },
+ 
++	/* Surface Pro 9 */
++	{ "MSHW0343", (unsigned long)ssam_node_group_sp9 },
++
+ 	/* Surface Book 2 */
+ 	{ "MSHW0107", (unsigned long)ssam_node_group_gen5 },
+ 
+@@ -324,6 +358,9 @@ static const struct acpi_device_id ssam_platform_hub_match[] = {
+ 	/* Surface Laptop 4 (13", Intel) */
+ 	{ "MSHW0250", (unsigned long)ssam_node_group_sl3 },
+ 
++	/* Surface Laptop 5 */
++	{ "MSHW0350", (unsigned long)ssam_node_group_sl5 },
++
+ 	/* Surface Laptop Go 1 */
+ 	{ "MSHW0118", (unsigned long)ssam_node_group_slg1 },
+ 
+diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
+index f1259d81d86da..df4c1f08f0c6a 100644
+--- a/drivers/platform/x86/acer-wmi.c
++++ b/drivers/platform/x86/acer-wmi.c
+@@ -564,6 +564,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
+ 		},
+ 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
+ 	},
++	{
++		.callback = set_force_caps,
++		.ident = "Acer Aspire Switch V 10 SW5-017",
++		.matches = {
++			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
++			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++		},
++		.driver_data = (void *)ACER_CAP_KBD_DOCK,
++	},
+ 	{
+ 		.callback = set_force_caps,
+ 		.ident = "Acer One 10 (S1003)",
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index eec7d0ed7cf21..8e1979b477a7d 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -1656,6 +1656,8 @@ static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
+ 	pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
+ 				cpu_to_le32(ports_available));
+ 
++	pci_dev_put(xhci_pdev);
++
+ 	pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n",
+ 			orig_ports_available, ports_available);
+ }
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index 4fbe91769c915..788381e4c6a64 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -90,6 +90,7 @@ enum hp_wmi_event_ids {
+ 	HPWMI_PEAKSHIFT_PERIOD		= 0x0F,
+ 	HPWMI_BATTERY_CHARGE_PERIOD	= 0x10,
+ 	HPWMI_SANITIZATION_MODE		= 0x17,
++	HPWMI_SMART_EXPERIENCE_APP	= 0x21,
+ };
+ 
+ /*
+@@ -857,6 +858,8 @@ static void hp_wmi_notify(u32 value, void *context)
+ 		break;
+ 	case HPWMI_SANITIZATION_MODE:
+ 		break;
++	case HPWMI_SMART_EXPERIENCE_APP:
++		break;
+ 	default:
+ 		pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
+ 		break;
+diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
+index abd0c81d62c40..3ea8fc6a9ca36 100644
+--- a/drivers/platform/x86/ideapad-laptop.c
++++ b/drivers/platform/x86/ideapad-laptop.c
+@@ -136,6 +136,7 @@ struct ideapad_private {
+ 		bool dytc                 : 1;
+ 		bool fan_mode             : 1;
+ 		bool fn_lock              : 1;
++		bool set_fn_lock_led      : 1;
+ 		bool hw_rfkill_switch     : 1;
+ 		bool kbd_bl               : 1;
+ 		bool touchpad_ctrl_via_ec : 1;
+@@ -154,7 +155,21 @@ MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth.");
+ 
+ static bool allow_v4_dytc;
+ module_param(allow_v4_dytc, bool, 0444);
+-MODULE_PARM_DESC(allow_v4_dytc, "Enable DYTC version 4 platform-profile support.");
++MODULE_PARM_DESC(allow_v4_dytc,
++	"Enable DYTC version 4 platform-profile support. "
++	"If you need this please report this to: platform-driver-x86@vger.kernel.org");
++
++static bool hw_rfkill_switch;
++module_param(hw_rfkill_switch, bool, 0444);
++MODULE_PARM_DESC(hw_rfkill_switch,
++	"Enable rfkill support for laptops with a hw on/off wifi switch/slider. "
++	"If you need this please report this to: platform-driver-x86@vger.kernel.org");
++
++static bool set_fn_lock_led;
++module_param(set_fn_lock_led, bool, 0444);
++MODULE_PARM_DESC(set_fn_lock_led,
++	"Enable driver based updates of the fn-lock LED on fn-lock changes. "
++	"If you need this please report this to: platform-driver-x86@vger.kernel.org");
+ 
+ /*
+  * ACPI Helpers
+@@ -1501,6 +1516,9 @@ static void ideapad_wmi_notify(u32 value, void *context)
+ 		ideapad_input_report(priv, value);
+ 		break;
+ 	case 208:
++		if (!priv->features.set_fn_lock_led)
++			break;
++
+ 		if (!eval_hals(priv->adev->handle, &result)) {
+ 			bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result);
+ 
+@@ -1514,6 +1532,18 @@ static void ideapad_wmi_notify(u32 value, void *context)
+ }
+ #endif
+ 
++/* On some models we need to call exec_sals(SALS_FNLOCK_ON/OFF) to set the LED */
++static const struct dmi_system_id set_fn_lock_led_list[] = {
++	{
++		/* https://bugzilla.kernel.org/show_bug.cgi?id=212671 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion R7000P2020H"),
++		}
++	},
++	{}
++};
++
+ /*
+  * Some ideapads have a hardware rfkill switch, but most do not have one.
+  * Reading VPCCMD_R_RF always results in 0 on models without a hardware rfkill,
+@@ -1533,15 +1563,41 @@ static const struct dmi_system_id hw_rfkill_list[] = {
+ 	{}
+ };
+ 
++static const struct dmi_system_id no_touchpad_switch_list[] = {
++	{
++	.ident = "Lenovo Yoga 3 Pro 1370",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3"),
++		},
++	},
++	{
++	.ident = "ZhaoYang K4e-IML",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		DMI_MATCH(DMI_PRODUCT_VERSION, "ZhaoYang K4e-IML"),
++		},
++	},
++	{}
++};
++
+ static void ideapad_check_features(struct ideapad_private *priv)
+ {
+ 	acpi_handle handle = priv->adev->handle;
+ 	unsigned long val;
+ 
+-	priv->features.hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
++	priv->features.set_fn_lock_led =
++		set_fn_lock_led || dmi_check_system(set_fn_lock_led_list);
++	priv->features.hw_rfkill_switch =
++		hw_rfkill_switch || dmi_check_system(hw_rfkill_list);
+ 
+ 	/* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */
+-	priv->features.touchpad_ctrl_via_ec = !acpi_dev_present("ELAN0634", NULL, -1);
++	if (acpi_dev_present("ELAN0634", NULL, -1))
++		priv->features.touchpad_ctrl_via_ec = 0;
++	else if (dmi_check_system(no_touchpad_switch_list))
++		priv->features.touchpad_ctrl_via_ec = 0;
++	else
++		priv->features.touchpad_ctrl_via_ec = 1;
+ 
+ 	if (!read_ec_data(handle, VPCCMD_R_FAN, &val))
+ 		priv->features.fan_mode = true;
+diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c
+index 79cff1fc675c2..b6313ecd190c0 100644
+--- a/drivers/platform/x86/intel/hid.c
++++ b/drivers/platform/x86/intel/hid.c
+@@ -27,6 +27,9 @@ static const struct acpi_device_id intel_hid_ids[] = {
+ 	{"INTC1051", 0},
+ 	{"INTC1054", 0},
+ 	{"INTC1070", 0},
++	{"INTC1076", 0},
++	{"INTC1077", 0},
++	{"INTC1078", 0},
+ 	{"", 0},
+ };
+ MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
+diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
+index 53d7fd2943b4c..46598dcb634aa 100644
+--- a/drivers/platform/x86/intel/pmt/class.c
++++ b/drivers/platform/x86/intel/pmt/class.c
+@@ -9,6 +9,7 @@
+  */
+ 
+ #include <linux/kernel.h>
++#include <linux/io-64-nonatomic-lo-hi.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/pci.h>
+@@ -19,6 +20,7 @@
+ #define PMT_XA_START		0
+ #define PMT_XA_MAX		INT_MAX
+ #define PMT_XA_LIMIT		XA_LIMIT(PMT_XA_START, PMT_XA_MAX)
++#define GUID_SPR_PUNIT		0x9956f43f
+ 
+ bool intel_pmt_is_early_client_hw(struct device *dev)
+ {
+@@ -33,6 +35,29 @@ bool intel_pmt_is_early_client_hw(struct device *dev)
+ }
+ EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw);
+ 
++static inline int
++pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count)
++{
++	int i, remain;
++	u64 *buf = to;
++
++	if (!IS_ALIGNED((unsigned long)from, 8))
++		return -EFAULT;
++
++	for (i = 0; i < count/8; i++)
++		buf[i] = readq(&from[i]);
++
++	/* Copy any remaining bytes */
++	remain = count % 8;
++	if (remain) {
++		u64 tmp = readq(&from[i]);
++
++		memcpy(&buf[i], &tmp, remain);
++	}
++
++	return count;
++}
++
+ /*
+  * sysfs
+  */
+@@ -54,7 +79,11 @@ intel_pmt_read(struct file *filp, struct kobject *kobj,
+ 	if (count > entry->size - off)
+ 		count = entry->size - off;
+ 
+-	memcpy_fromio(buf, entry->base + off, count);
++	if (entry->guid == GUID_SPR_PUNIT)
++		/* PUNIT on SPR only supports aligned 64-bit read */
++		count = pmt_memcpy64_fromio(buf, entry->base + off, count);
++	else
++		memcpy_fromio(buf, entry->base + off, count);
+ 
+ 	return count;
+ }
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 353507d18e11c..67dc335fca0c6 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -4497,6 +4497,14 @@ static const struct dmi_system_id fwbug_list[] __initconst = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "21A0"),
+ 		}
+ 	},
++	{
++		.ident = "P14s Gen2 AMD",
++		.driver_data = &quirk_s2idle_bug,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "21A1"),
++		}
++	},
+ 	{}
+ };
+ 
+diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
+index bc97bfa8e8a65..baae3120efd05 100644
+--- a/drivers/platform/x86/touchscreen_dmi.c
++++ b/drivers/platform/x86/touchscreen_dmi.c
+@@ -770,6 +770,22 @@ static const struct ts_dmi_data predia_basic_data = {
+ 	.properties	= predia_basic_props,
+ };
+ 
++static const struct property_entry rca_cambio_w101_v2_props[] = {
++	PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
++	PROPERTY_ENTRY_U32("touchscreen-min-y", 20),
++	PROPERTY_ENTRY_U32("touchscreen-size-x", 1644),
++	PROPERTY_ENTRY_U32("touchscreen-size-y", 874),
++	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
++	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rca-cambio-w101-v2.fw"),
++	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
++	{ }
++};
++
++static const struct ts_dmi_data rca_cambio_w101_v2_data = {
++	.acpi_name = "MSSL1680:00",
++	.properties = rca_cambio_w101_v2_props,
++};
++
+ static const struct property_entry rwc_nanote_p8_props[] = {
+ 	PROPERTY_ENTRY_U32("touchscreen-min-y", 46),
+ 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
+@@ -1409,6 +1425,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
+ 		},
+ 	},
++	{
++		/* RCA Cambio W101 v2 */
++		/* https://github.com/onitake/gsl-firmware/discussions/193 */
++		.driver_data = (void *)&rca_cambio_w101_v2_data,
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "RCA"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "W101SA23T1"),
++		},
++	},
+ 	{
+ 		/* RWC NANOTE P8 */
+ 		.driver_data = (void *)&rwc_nanote_p8_data,
+diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c
+index 863fabe05bdcf..307ee6f71042e 100644
+--- a/drivers/power/supply/ab8500_btemp.c
++++ b/drivers/power/supply/ab8500_btemp.c
+@@ -725,7 +725,14 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
+ 	/* Get thermal zone and ADC */
+ 	di->tz = thermal_zone_get_zone_by_name("battery-thermal");
+ 	if (IS_ERR(di->tz)) {
+-		return dev_err_probe(dev, PTR_ERR(di->tz),
++		ret = PTR_ERR(di->tz);
++		/*
++		 * This usually just means we are probing before the thermal
++		 * zone, so just defer.
++		 */
++		if (ret == -ENODEV)
++			ret = -EPROBE_DEFER;
++		return dev_err_probe(dev, ret,
+ 				     "failed to get battery thermal zone\n");
+ 	}
+ 	di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl");
+diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c
+index 218e8e689a3fb..00221e9c0bfcc 100644
+--- a/drivers/power/supply/ip5xxx_power.c
++++ b/drivers/power/supply/ip5xxx_power.c
+@@ -352,7 +352,7 @@ static int ip5xxx_battery_get_property(struct power_supply *psy,
+ 		ret = ip5xxx_battery_read_adc(ip5xxx, IP5XXX_BATIADC_DAT0,
+ 					      IP5XXX_BATIADC_DAT1, &raw);
+ 
+-		val->intval = DIV_ROUND_CLOSEST(raw * 745985, 1000);
++		val->intval = DIV_ROUND_CLOSEST(raw * 149197, 200);
+ 		return 0;
+ 
+ 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index c3871565fd7d2..c0f368f1b49f7 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -5138,6 +5138,7 @@ static void regulator_dev_release(struct device *dev)
+ {
+ 	struct regulator_dev *rdev = dev_get_drvdata(dev);
+ 
++	debugfs_remove_recursive(rdev->debugfs);
+ 	kfree(rdev->constraints);
+ 	of_node_put(rdev->dev.of_node);
+ 	kfree(rdev);
+@@ -5616,11 +5617,15 @@ wash:
+ 	mutex_lock(&regulator_list_mutex);
+ 	regulator_ena_gpio_free(rdev);
+ 	mutex_unlock(&regulator_list_mutex);
++	put_device(&rdev->dev);
++	rdev = NULL;
+ clean:
+ 	if (dangling_of_gpiod)
+ 		gpiod_put(config->ena_gpiod);
++	if (rdev && rdev->dev.of_node)
++		of_node_put(rdev->dev.of_node);
++	kfree(rdev);
+ 	kfree(config);
+-	put_device(&rdev->dev);
+ rinse:
+ 	if (dangling_cfg_gpiod)
+ 		gpiod_put(cfg->ena_gpiod);
+@@ -5649,7 +5654,6 @@ void regulator_unregister(struct regulator_dev *rdev)
+ 
+ 	mutex_lock(&regulator_list_mutex);
+ 
+-	debugfs_remove_recursive(rdev->debugfs);
+ 	WARN_ON(rdev->open_count);
+ 	regulator_remove_coupling(rdev);
+ 	unset_regulator_supplies(rdev);
+diff --git a/drivers/regulator/rt5759-regulator.c b/drivers/regulator/rt5759-regulator.c
+index 6b96899eb27e3..8488417f4b2cf 100644
+--- a/drivers/regulator/rt5759-regulator.c
++++ b/drivers/regulator/rt5759-regulator.c
+@@ -243,6 +243,7 @@ static int rt5759_regulator_register(struct rt5759_priv *priv)
+ 	if (priv->chip_type == CHIP_TYPE_RT5759A)
+ 		reg_desc->uV_step = RT5759A_STEP_UV;
+ 
++	memset(&reg_cfg, 0, sizeof(reg_cfg));
+ 	reg_cfg.dev = priv->dev;
+ 	reg_cfg.of_node = np;
+ 	reg_cfg.init_data = of_get_regulator_init_data(priv->dev, np, reg_desc);
+diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c
+index 430265c404d65..7c7e3648ea4bf 100644
+--- a/drivers/regulator/twl6030-regulator.c
++++ b/drivers/regulator/twl6030-regulator.c
+@@ -530,6 +530,7 @@ static const struct twlreg_info TWL6030_INFO_##label = { \
+ #define TWL6032_ADJUSTABLE_LDO(label, offset) \
+ static const struct twlreg_info TWL6032_INFO_##label = { \
+ 	.base = offset, \
++	.features = TWL6032_SUBCLASS, \
+ 	.desc = { \
+ 		.name = #label, \
+ 		.id = TWL6032_REG_##label, \
+@@ -562,6 +563,7 @@ static const struct twlreg_info TWLFIXED_INFO_##label = { \
+ #define TWL6032_ADJUSTABLE_SMPS(label, offset) \
+ static const struct twlreg_info TWLSMPS_INFO_##label = { \
+ 	.base = offset, \
++	.features = TWL6032_SUBCLASS, \
+ 	.desc = { \
+ 		.name = #label, \
+ 		.id = TWL6032_REG_##label, \
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index 3cc93e2e4e15a..2dec81e7e6ab1 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -4681,7 +4681,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+ 	struct dasd_device *basedev;
+ 	struct req_iterator iter;
+ 	struct dasd_ccw_req *cqr;
+-	unsigned int first_offs;
+ 	unsigned int trkcount;
+ 	unsigned long *idaws;
+ 	unsigned int size;
+@@ -4715,7 +4714,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+ 	last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /
+ 		DASD_RAW_SECTORS_PER_TRACK;
+ 	trkcount = last_trk - first_trk + 1;
+-	first_offs = 0;
+ 
+ 	if (rq_data_dir(req) == READ)
+ 		cmd = DASD_ECKD_CCW_READ_TRACK;
+@@ -4759,13 +4757,13 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+ 
+ 	if (use_prefix) {
+ 		prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev,
+-			   startdev, 1, first_offs + 1, trkcount, 0, 0);
++			   startdev, 1, 0, trkcount, 0, 0);
+ 	} else {
+ 		define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0);
+ 		ccw[-1].flags |= CCW_FLAG_CC;
+ 
+ 		data += sizeof(struct DE_eckd_data);
+-		locate_record_ext(ccw++, data, first_trk, first_offs + 1,
++		locate_record_ext(ccw++, data, first_trk, 0,
+ 				  trkcount, cmd, basedev, 0, 0);
+ 	}
+ 
+diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
+index 59ac98f2bd275..b02c631f3b71a 100644
+--- a/drivers/s390/crypto/ap_bus.c
++++ b/drivers/s390/crypto/ap_bus.c
+@@ -233,8 +233,11 @@ static void __init ap_init_qci_info(void)
+ 	if (!ap_qci_info)
+ 		return;
+ 	ap_qci_info_old = kzalloc(sizeof(*ap_qci_info_old), GFP_KERNEL);
+-	if (!ap_qci_info_old)
++	if (!ap_qci_info_old) {
++		kfree(ap_qci_info);
++		ap_qci_info = NULL;
+ 		return;
++	}
+ 	if (ap_fetch_qci_info(ap_qci_info) != 0) {
+ 		kfree(ap_qci_info);
+ 		kfree(ap_qci_info_old);
+diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
+index 8fb34b8eeb189..5ad2514775931 100644
+--- a/drivers/s390/crypto/zcrypt_msgtype6.c
++++ b/drivers/s390/crypto/zcrypt_msgtype6.c
+@@ -342,7 +342,10 @@ static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
+ 	};
+ 	struct {
+ 		struct type6_hdr hdr;
+-		struct CPRBX cprbx;
++		union {
++			struct CPRBX cprbx;
++			DECLARE_FLEX_ARRAY(u8, userdata);
++		};
+ 	} __packed * msg = ap_msg->msg;
+ 
+ 	int rcblen = CEIL4(xcrb->request_control_blk_length);
+@@ -403,7 +406,8 @@ static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
+ 	msg->hdr.fromcardlen2 = xcrb->reply_data_length;
+ 
+ 	/* prepare CPRB */
+-	if (z_copy_from_user(userspace, &msg->cprbx, xcrb->request_control_blk_addr,
++	if (z_copy_from_user(userspace, msg->userdata,
++			     xcrb->request_control_blk_addr,
+ 			     xcrb->request_control_blk_length))
+ 		return -EFAULT;
+ 	if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
+@@ -469,9 +473,14 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap
+ 
+ 	struct {
+ 		struct type6_hdr hdr;
+-		struct ep11_cprb cprbx;
+-		unsigned char	pld_tag;	/* fixed value 0x30 */
+-		unsigned char	pld_lenfmt;	/* payload length format */
++		union {
++			struct {
++				struct ep11_cprb cprbx;
++				unsigned char pld_tag;    /* fixed value 0x30 */
++				unsigned char pld_lenfmt; /* length format */
++			} __packed;
++			DECLARE_FLEX_ARRAY(u8, userdata);
++		};
+ 	} __packed * msg = ap_msg->msg;
+ 
+ 	struct pld_hdr {
+@@ -500,7 +509,7 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap
+ 	msg->hdr.fromcardlen1 = xcrb->resp_len;
+ 
+ 	/* Import CPRB data from the ioctl input parameter */
+-	if (z_copy_from_user(userspace, &msg->cprbx.cprb_len,
++	if (z_copy_from_user(userspace, msg->userdata,
+ 			     (char __force __user *)xcrb->req, xcrb->req_len)) {
+ 		return -EFAULT;
+ 	}
+diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
+index 00684e11976be..1a0c0b7289d26 100644
+--- a/drivers/scsi/ibmvscsi/ibmvfc.c
++++ b/drivers/scsi/ibmvscsi/ibmvfc.c
+@@ -708,8 +708,13 @@ static void ibmvfc_init_host(struct ibmvfc_host *vhost)
+ 		memset(vhost->async_crq.msgs.async, 0, PAGE_SIZE);
+ 		vhost->async_crq.cur = 0;
+ 
+-		list_for_each_entry(tgt, &vhost->targets, queue)
+-			ibmvfc_del_tgt(tgt);
++		list_for_each_entry(tgt, &vhost->targets, queue) {
++			if (vhost->client_migrated)
++				tgt->need_login = 1;
++			else
++				ibmvfc_del_tgt(tgt);
++		}
++
+ 		scsi_block_requests(vhost->host);
+ 		ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT);
+ 		vhost->job_step = ibmvfc_npiv_login;
+@@ -3235,9 +3240,12 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost,
+ 			/* We need to re-setup the interpartition connection */
+ 			dev_info(vhost->dev, "Partition migrated, Re-enabling adapter\n");
+ 			vhost->client_migrated = 1;
++
++			scsi_block_requests(vhost->host);
+ 			ibmvfc_purge_requests(vhost, DID_REQUEUE);
+-			ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
++			ibmvfc_set_host_state(vhost, IBMVFC_LINK_DOWN);
+ 			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_REENABLE);
++			wake_up(&vhost->work_wait_q);
+ 		} else if (crq->format == IBMVFC_PARTNER_FAILED || crq->format == IBMVFC_PARTNER_DEREGISTER) {
+ 			dev_err(vhost->dev, "Host partner adapter deregistered or failed (rc=%d)\n", crq->format);
+ 			ibmvfc_purge_requests(vhost, DID_ERROR);
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
+index bfa1165e23b67..1b4d1e562de86 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
+@@ -2930,7 +2930,8 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc,
+ 	}
+ 
+ 	if (scmd->result != (DID_OK << 16) && (scmd->cmnd[0] != ATA_12) &&
+-	    (scmd->cmnd[0] != ATA_16)) {
++	    (scmd->cmnd[0] != ATA_16) &&
++	    mrioc->logging_level & MPI3_DEBUG_SCSI_ERROR) {
+ 		ioc_info(mrioc, "%s :scmd->result 0x%x\n", __func__,
+ 		    scmd->result);
+ 		scsi_print_command(scmd);
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 95f940f5c996d..7346098c1c68f 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -1899,6 +1899,13 @@ static int resp_readcap16(struct scsi_cmnd *scp,
+ 			arr[14] |= 0x40;
+ 	}
+ 
++	/*
++	 * Since the scsi_debug READ CAPACITY implementation always reports the
++	 * total disk capacity, set RC BASIS = 1 for host-managed ZBC devices.
++	 */
++	if (devip->zmodel == BLK_ZONED_HM)
++		arr[12] |= 1 << 4;
++
+ 	arr[15] = sdebug_lowest_aligned & 0xff;
+ 
+ 	if (have_dif_prot) {
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index cd3db9684e52d..f473c002fa4d6 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -231,7 +231,7 @@ iscsi_create_endpoint(int dd_size)
+ 	dev_set_name(&ep->dev, "ep-%d", id);
+ 	err = device_register(&ep->dev);
+         if (err)
+-		goto free_id;
++		goto put_dev;
+ 
+ 	err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group);
+ 	if (err)
+@@ -245,10 +245,12 @@ unregister_dev:
+ 	device_unregister(&ep->dev);
+ 	return NULL;
+ 
+-free_id:
++put_dev:
+ 	mutex_lock(&iscsi_ep_idr_mutex);
+ 	idr_remove(&iscsi_ep_idr, id);
+ 	mutex_unlock(&iscsi_ep_idr_mutex);
++	put_device(&ep->dev);
++	return NULL;
+ free_ep:
+ 	kfree(ep);
+ 	return NULL;
+@@ -766,7 +768,7 @@ iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
+ 
+ 	err = device_register(&iface->dev);
+ 	if (err)
+-		goto free_iface;
++		goto put_dev;
+ 
+ 	err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group);
+ 	if (err)
+@@ -780,9 +782,8 @@ unreg_iface:
+ 	device_unregister(&iface->dev);
+ 	return NULL;
+ 
+-free_iface:
+-	put_device(iface->dev.parent);
+-	kfree(iface);
++put_dev:
++	put_device(&iface->dev);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_iface);
+@@ -1251,15 +1252,15 @@ iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
+ 
+ 	err = device_register(&fnode_sess->dev);
+ 	if (err)
+-		goto free_fnode_sess;
++		goto put_dev;
+ 
+ 	if (dd_size)
+ 		fnode_sess->dd_data = &fnode_sess[1];
+ 
+ 	return fnode_sess;
+ 
+-free_fnode_sess:
+-	kfree(fnode_sess);
++put_dev:
++	put_device(&fnode_sess->dev);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
+@@ -1299,15 +1300,15 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,
+ 
+ 	err = device_register(&fnode_conn->dev);
+ 	if (err)
+-		goto free_fnode_conn;
++		goto put_dev;
+ 
+ 	if (dd_size)
+ 		fnode_conn->dd_data = &fnode_conn[1];
+ 
+ 	return fnode_conn;
+ 
+-free_fnode_conn:
+-	kfree(fnode_conn);
++put_dev:
++	put_device(&fnode_conn->dev);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
+@@ -4815,7 +4816,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
+ 	dev_set_name(&priv->dev, "%s", tt->name);
+ 	err = device_register(&priv->dev);
+ 	if (err)
+-		goto free_priv;
++		goto put_dev;
+ 
+ 	err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
+ 	if (err)
+@@ -4850,8 +4851,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
+ unregister_dev:
+ 	device_unregister(&priv->dev);
+ 	return NULL;
+-free_priv:
+-	kfree(priv);
++put_dev:
++	put_device(&priv->dev);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_register_transport);
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 8ced292c4b962..d93604318ecd3 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -300,16 +300,21 @@ enum storvsc_request_type {
+ };
+ 
+ /*
+- * SRB status codes and masks; a subset of the codes used here.
++ * SRB status codes and masks. In the 8-bit field, the two high order bits
++ * are flags, while the remaining 6 bits are an integer status code.  The
++ * definitions here include only the subset of the integer status codes that
++ * are tested for in this driver.
+  */
+-
+ #define SRB_STATUS_AUTOSENSE_VALID	0x80
+ #define SRB_STATUS_QUEUE_FROZEN		0x40
+-#define SRB_STATUS_INVALID_LUN	0x20
+-#define SRB_STATUS_SUCCESS	0x01
+-#define SRB_STATUS_ABORTED	0x02
+-#define SRB_STATUS_ERROR	0x04
+-#define SRB_STATUS_DATA_OVERRUN	0x12
++
++/* SRB status integer codes */
++#define SRB_STATUS_SUCCESS		0x01
++#define SRB_STATUS_ABORTED		0x02
++#define SRB_STATUS_ERROR		0x04
++#define SRB_STATUS_INVALID_REQUEST	0x06
++#define SRB_STATUS_DATA_OVERRUN		0x12
++#define SRB_STATUS_INVALID_LUN		0x20
+ 
+ #define SRB_STATUS(status) \
+ 	(status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
+@@ -966,38 +971,25 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+ 	void (*process_err_fn)(struct work_struct *work);
+ 	struct hv_host_device *host_dev = shost_priv(host);
+ 
+-	/*
+-	 * In some situations, Hyper-V sets multiple bits in the
+-	 * srb_status, such as ABORTED and ERROR. So process them
+-	 * individually, with the most specific bits first.
+-	 */
+-
+-	if (vm_srb->srb_status & SRB_STATUS_INVALID_LUN) {
+-		set_host_byte(scmnd, DID_NO_CONNECT);
+-		process_err_fn = storvsc_remove_lun;
+-		goto do_work;
+-	}
++	switch (SRB_STATUS(vm_srb->srb_status)) {
++	case SRB_STATUS_ERROR:
++	case SRB_STATUS_ABORTED:
++	case SRB_STATUS_INVALID_REQUEST:
++		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) {
++			/* Check for capacity change */
++			if ((asc == 0x2a) && (ascq == 0x9)) {
++				process_err_fn = storvsc_device_scan;
++				/* Retry the I/O that triggered this. */
++				set_host_byte(scmnd, DID_REQUEUE);
++				goto do_work;
++			}
+ 
+-	if (vm_srb->srb_status & SRB_STATUS_ABORTED) {
+-		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID &&
+-		    /* Capacity data has changed */
+-		    (asc == 0x2a) && (ascq == 0x9)) {
+-			process_err_fn = storvsc_device_scan;
+ 			/*
+-			 * Retry the I/O that triggered this.
++			 * Otherwise, let upper layer deal with the
++			 * error when sense message is present
+ 			 */
+-			set_host_byte(scmnd, DID_REQUEUE);
+-			goto do_work;
+-		}
+-	}
+-
+-	if (vm_srb->srb_status & SRB_STATUS_ERROR) {
+-		/*
+-		 * Let upper layer deal with error when
+-		 * sense message is present.
+-		 */
+-		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
+ 			return;
++		}
+ 
+ 		/*
+ 		 * If there is an error; offline the device since all
+@@ -1020,6 +1012,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+ 		default:
+ 			set_host_byte(scmnd, DID_ERROR);
+ 		}
++		return;
++
++	case SRB_STATUS_INVALID_LUN:
++		set_host_byte(scmnd, DID_NO_CONNECT);
++		process_err_fn = storvsc_remove_lun;
++		goto do_work;
++
+ 	}
+ 	return;
+ 
+diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
+index 1322b8cce5b7c..ababb910b3914 100644
+--- a/drivers/spi/spi-dw-dma.c
++++ b/drivers/spi/spi-dw-dma.c
+@@ -128,12 +128,15 @@ static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
+ 
+ 	dw_spi_dma_sg_burst_init(dws);
+ 
++	pci_dev_put(dma_dev);
++
+ 	return 0;
+ 
+ free_rxchan:
+ 	dma_release_channel(dws->rxchan);
+ 	dws->rxchan = NULL;
+ err_exit:
++	pci_dev_put(dma_dev);
+ 	return -EBUSY;
+ }
+ 
+diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
+index 30d82cc7300b2..d209930069cf3 100644
+--- a/drivers/spi/spi-imx.c
++++ b/drivers/spi/spi-imx.c
+@@ -444,8 +444,7 @@ static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx,
+ 	unsigned int pre, post;
+ 	unsigned int fin = spi_imx->spi_clk;
+ 
+-	if (unlikely(fspi > fin))
+-		return 0;
++	fspi = min(fspi, fin);
+ 
+ 	post = fls(fin) - fls(fspi);
+ 	if (fin > fspi << post)
+@@ -1607,6 +1606,13 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
+ 	if (spi_imx->slave_mode)
+ 		return spi_imx_pio_transfer_slave(spi, transfer);
+ 
++	/*
++	 * If we decided in spi_imx_can_dma() that we want to do a DMA
++	 * transfer, the SPI transfer has already been mapped, so we
++	 * have to do the DMA transfer here.
++	 */
++	if (spi_imx->usedma)
++		return spi_imx_dma_transfer(spi_imx, transfer);
+ 	/*
+ 	 * Calculate the estimated time in us the transfer runs. Find
+ 	 * the number of Hz per byte per polling limit.
+@@ -1618,9 +1624,6 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
+ 	if (transfer->len < byte_limit)
+ 		return spi_imx_poll_transfer(spi, transfer);
+ 
+-	if (spi_imx->usedma)
+-		return spi_imx_dma_transfer(spi_imx, transfer);
+-
+ 	return spi_imx_pio_transfer(spi, transfer);
+ }
+ 
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 3c2fa2e2f94a3..def09cf0dc147 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -434,7 +434,7 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
+ 	u32 div, mbrdiv;
+ 
+ 	/* Ensure spi->clk_rate is even */
+-	div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz);
++	div = DIV_ROUND_CLOSEST(spi->clk_rate & ~0x1, speed_hz);
+ 
+ 	/*
+ 	 * SPI framework set xfer->speed_hz to master->max_speed_hz if
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index 904972606bd45..9f356612ba7e5 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -720,6 +720,9 @@ static int tegra_qspi_start_cpu_based_transfer(struct tegra_qspi *qspi, struct s
+ 
+ static void tegra_qspi_deinit_dma(struct tegra_qspi *tqspi)
+ {
++	if (!tqspi->soc_data->has_dma)
++		return;
++
+ 	if (tqspi->tx_dma_buf) {
+ 		dma_free_coherent(tqspi->dev, tqspi->dma_buf_size,
+ 				  tqspi->tx_dma_buf, tqspi->tx_dma_phys);
+@@ -750,6 +753,9 @@ static int tegra_qspi_init_dma(struct tegra_qspi *tqspi)
+ 	u32 *dma_buf;
+ 	int err;
+ 
++	if (!tqspi->soc_data->has_dma)
++		return 0;
++
+ 	dma_chan = dma_request_chan(tqspi->dev, "rx");
+ 	if (IS_ERR(dma_chan)) {
+ 		err = PTR_ERR(dma_chan);
+@@ -918,8 +924,9 @@ static int tegra_qspi_start_transfer_one(struct spi_device *spi,
+ static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_device *spi)
+ {
+ 	struct tegra_qspi_client_data *cdata;
++	struct tegra_qspi *tqspi = spi_master_get_devdata(spi->master);
+ 
+-	cdata = devm_kzalloc(&spi->dev, sizeof(*cdata), GFP_KERNEL);
++	cdata = devm_kzalloc(tqspi->dev, sizeof(*cdata), GFP_KERNEL);
+ 	if (!cdata)
+ 		return NULL;
+ 
+diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c
+index f3947be13e2e5..64f0e047c23d2 100644
+--- a/drivers/tee/optee/device.c
++++ b/drivers/tee/optee/device.c
+@@ -80,7 +80,7 @@ static int optee_register_device(const uuid_t *device_uuid)
+ 	rc = device_register(&optee_device->dev);
+ 	if (rc) {
+ 		pr_err("device registration failed, err: %d\n", rc);
+-		kfree(optee_device);
++		put_device(&optee_device->dev);
+ 	}
+ 
+ 	return rc;
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 2a0de70e0be41..ae02aed6bd0c2 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -248,7 +248,7 @@ struct gsm_mux {
+ 	bool constipated;		/* Asked by remote to shut up */
+ 	bool has_devices;		/* Devices were registered */
+ 
+-	struct mutex tx_mutex;
++	spinlock_t tx_lock;
+ 	unsigned int tx_bytes;		/* TX data outstanding */
+ #define TX_THRESH_HI		8192
+ #define TX_THRESH_LO		2048
+@@ -256,7 +256,7 @@ struct gsm_mux {
+ 	struct list_head tx_data_list;	/* Pending data packets */
+ 
+ 	/* Control messages */
+-	struct delayed_work kick_timeout;	/* Kick TX queuing on timeout */
++	struct timer_list kick_timer;	/* Kick TX queuing on timeout */
+ 	struct timer_list t2_timer;	/* Retransmit timer for commands */
+ 	int cretries;			/* Command retry counter */
+ 	struct gsm_control *pending_cmd;/* Our current pending command */
+@@ -680,6 +680,7 @@ static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+ 	struct gsm_msg *msg;
+ 	u8 *dp;
+ 	int ocr;
++	unsigned long flags;
+ 
+ 	msg = gsm_data_alloc(gsm, addr, 0, control);
+ 	if (!msg)
+@@ -701,10 +702,10 @@ static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+ 
+ 	gsm_print_packet("Q->", addr, cr, control, NULL, 0);
+ 
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	list_add_tail(&msg->list, &gsm->tx_ctrl_list);
+ 	gsm->tx_bytes += msg->len;
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ 	gsmld_write_trigger(gsm);
+ 
+ 	return 0;
+@@ -729,7 +730,7 @@ static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ 	spin_unlock_irqrestore(&dlci->lock, flags);
+ 
+ 	/* Clear data packets in MUX write queue */
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
+ 		if (msg->addr != addr)
+ 			continue;
+@@ -737,7 +738,7 @@ static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ 		list_del(&msg->list);
+ 		kfree(msg);
+ 	}
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+ 
+ /**
+@@ -1008,7 +1009,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ 	gsm->tx_bytes += msg->len;
+ 
+ 	gsmld_write_trigger(gsm);
+-	schedule_delayed_work(&gsm->kick_timeout, 10 * gsm->t1 * HZ / 100);
++	mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100);
+ }
+ 
+ /**
+@@ -1023,9 +1024,10 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ 
+ static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ {
+-	mutex_lock(&dlci->gsm->tx_mutex);
++	unsigned long flags;
++	spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+ 	__gsm_data_queue(dlci, msg);
+-	mutex_unlock(&dlci->gsm->tx_mutex);
++	spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
+ }
+ 
+ /**
+@@ -1037,7 +1039,7 @@ static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+  *	is data. Keep to the MRU of the mux. This path handles the usual tty
+  *	interface which is a byte stream with optional modem data.
+  *
+- *	Caller must hold the tx_mutex of the mux.
++ *	Caller must hold the tx_lock of the mux.
+  */
+ 
+ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+@@ -1097,7 +1099,7 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+  *	is data. Keep to the MRU of the mux. This path handles framed data
+  *	queued as skbuffs to the DLCI.
+  *
+- *	Caller must hold the tx_mutex of the mux.
++ *	Caller must hold the tx_lock of the mux.
+  */
+ 
+ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+@@ -1113,7 +1115,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+ 	if (dlci->adaption == 4)
+ 		overhead = 1;
+ 
+-	/* dlci->skb is locked by tx_mutex */
++	/* dlci->skb is locked by tx_lock */
+ 	if (dlci->skb == NULL) {
+ 		dlci->skb = skb_dequeue_tail(&dlci->skb_list);
+ 		if (dlci->skb == NULL)
+@@ -1167,7 +1169,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+  *	Push an empty frame in to the transmit queue to update the modem status
+  *	bits and to transmit an optional break.
+  *
+- *	Caller must hold the tx_mutex of the mux.
++ *	Caller must hold the tx_lock of the mux.
+  */
+ 
+ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
+@@ -1281,12 +1283,13 @@ static int gsm_dlci_data_sweep(struct gsm_mux *gsm)
+ 
+ static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
+ {
++	unsigned long flags;
+ 	int sweep;
+ 
+ 	if (dlci->constipated)
+ 		return;
+ 
+-	mutex_lock(&dlci->gsm->tx_mutex);
++	spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+ 	/* If we have nothing running then we need to fire up */
+ 	sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO);
+ 	if (dlci->gsm->tx_bytes == 0) {
+@@ -1297,7 +1300,7 @@ static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
+ 	}
+ 	if (sweep)
+ 		gsm_dlci_data_sweep(dlci->gsm);
+-	mutex_unlock(&dlci->gsm->tx_mutex);
++	spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
+ }
+ 
+ /*
+@@ -1981,23 +1984,24 @@ static void gsm_dlci_command(struct gsm_dlci *dlci, const u8 *data, int len)
+ }
+ 
+ /**
+- *	gsm_kick_timeout	-	transmit if possible
+- *	@work: work contained in our gsm object
++ *	gsm_kick_timer	-	transmit if possible
++ *	@t: timer contained in our gsm object
+  *
+  *	Transmit data from DLCIs if the queue is empty. We can't rely on
+  *	a tty wakeup except when we filled the pipe so we need to fire off
+  *	new data ourselves in other cases.
+  */
+-static void gsm_kick_timeout(struct work_struct *work)
++static void gsm_kick_timer(struct timer_list *t)
+ {
+-	struct gsm_mux *gsm = container_of(work, struct gsm_mux, kick_timeout.work);
++	struct gsm_mux *gsm = from_timer(gsm, t, kick_timer);
++	unsigned long flags;
+ 	int sent = 0;
+ 
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	/* If we have nothing running then we need to fire up */
+ 	if (gsm->tx_bytes < TX_THRESH_LO)
+ 		sent = gsm_dlci_data_sweep(gsm);
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ 
+ 	if (sent && debug & 4)
+ 		pr_info("%s TX queue stalled\n", __func__);
+@@ -2454,7 +2458,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ 	}
+ 
+ 	/* Finish outstanding timers, making sure they are done */
+-	cancel_delayed_work_sync(&gsm->kick_timeout);
++	del_timer_sync(&gsm->kick_timer);
+ 	del_timer_sync(&gsm->t2_timer);
+ 
+ 	/* Finish writing to ldisc */
+@@ -2527,7 +2531,6 @@ static void gsm_free_mux(struct gsm_mux *gsm)
+ 			break;
+ 		}
+ 	}
+-	mutex_destroy(&gsm->tx_mutex);
+ 	mutex_destroy(&gsm->mutex);
+ 	kfree(gsm->txframe);
+ 	kfree(gsm->buf);
+@@ -2599,15 +2602,15 @@ static struct gsm_mux *gsm_alloc_mux(void)
+ 	}
+ 	spin_lock_init(&gsm->lock);
+ 	mutex_init(&gsm->mutex);
+-	mutex_init(&gsm->tx_mutex);
+ 	kref_init(&gsm->ref);
+ 	INIT_LIST_HEAD(&gsm->tx_ctrl_list);
+ 	INIT_LIST_HEAD(&gsm->tx_data_list);
+-	INIT_DELAYED_WORK(&gsm->kick_timeout, gsm_kick_timeout);
++	timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ 	timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+ 	INIT_WORK(&gsm->tx_work, gsmld_write_task);
+ 	init_waitqueue_head(&gsm->event);
+ 	spin_lock_init(&gsm->control_lock);
++	spin_lock_init(&gsm->tx_lock);
+ 
+ 	gsm->t1 = T1;
+ 	gsm->t2 = T2;
+@@ -2632,7 +2635,6 @@ static struct gsm_mux *gsm_alloc_mux(void)
+ 	}
+ 	spin_unlock(&gsm_mux_lock);
+ 	if (i == MAX_MUX) {
+-		mutex_destroy(&gsm->tx_mutex);
+ 		mutex_destroy(&gsm->mutex);
+ 		kfree(gsm->txframe);
+ 		kfree(gsm->buf);
+@@ -2788,16 +2790,17 @@ static void gsmld_write_trigger(struct gsm_mux *gsm)
+ static void gsmld_write_task(struct work_struct *work)
+ {
+ 	struct gsm_mux *gsm = container_of(work, struct gsm_mux, tx_work);
++	unsigned long flags;
+ 	int i, ret;
+ 
+ 	/* All outstanding control channel and control messages and one data
+ 	 * frame is sent.
+ 	 */
+ 	ret = -ENODEV;
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	if (gsm->tty)
+ 		ret = gsm_data_kick(gsm);
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ 
+ 	if (ret >= 0)
+ 		for (i = 0; i < NUM_DLCI; i++)
+@@ -3005,6 +3008,7 @@ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+ 			   const unsigned char *buf, size_t nr)
+ {
+ 	struct gsm_mux *gsm = tty->disc_data;
++	unsigned long flags;
+ 	int space;
+ 	int ret;
+ 
+@@ -3012,13 +3016,13 @@ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+ 		return -ENODEV;
+ 
+ 	ret = -ENOBUFS;
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	space = tty_write_room(tty);
+ 	if (space >= nr)
+ 		ret = tty->ops->write(tty, buf, nr);
+ 	else
+ 		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ 
+ 	return ret;
+ }
+@@ -3315,13 +3319,14 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
+ static void gsm_modem_upd_via_data(struct gsm_dlci *dlci, u8 brk)
+ {
+ 	struct gsm_mux *gsm = dlci->gsm;
++	unsigned long flags;
+ 
+ 	if (dlci->state != DLCI_OPEN || dlci->adaption != 2)
+ 		return;
+ 
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	gsm_dlci_modem_output(gsm, dlci, brk);
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+ 
+ /**
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index b96fbf8d31df7..2ad735dd6c05d 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -293,6 +293,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ {
+ 	struct omap8250_priv *priv = up->port.private_data;
+ 	struct uart_8250_dma	*dma = up->dma;
++	u8 mcr = serial8250_in_MCR(up);
+ 
+ 	if (dma && dma->tx_running) {
+ 		/*
+@@ -309,7 +310,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ 	serial_out(up, UART_EFR, UART_EFR_ECB);
+ 
+ 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+-	serial8250_out_MCR(up, UART_MCR_TCRTLR);
++	serial8250_out_MCR(up, mcr | UART_MCR_TCRTLR);
+ 	serial_out(up, UART_FCR, up->fcr);
+ 
+ 	omap8250_update_scr(up, priv);
+@@ -325,7 +326,8 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ 	serial_out(up, UART_LCR, 0);
+ 
+ 	/* drop TCR + TLR access, we setup XON/XOFF later */
+-	serial8250_out_MCR(up, up->mcr);
++	serial8250_out_MCR(up, mcr);
++
+ 	serial_out(up, UART_IER, up->ier);
+ 
+ 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+@@ -670,7 +672,6 @@ static int omap_8250_startup(struct uart_port *port)
+ 
+ 	pm_runtime_get_sync(port->dev);
+ 
+-	up->mcr = 0;
+ 	serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+ 
+ 	serial_out(up, UART_LCR, UART_LCR_WLEN8);
+diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c
+index c67715f6f756d..f9aa50ff14d42 100644
+--- a/drivers/usb/cdns3/cdnsp-gadget.c
++++ b/drivers/usb/cdns3/cdnsp-gadget.c
+@@ -600,11 +600,11 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
+ 
+ 	trace_cdnsp_ep_halt(value ? "Set" : "Clear");
+ 
+-	if (value) {
+-		ret = cdnsp_cmd_stop_ep(pdev, pep);
+-		if (ret)
+-			return ret;
++	ret = cdnsp_cmd_stop_ep(pdev, pep);
++	if (ret)
++		return ret;
+ 
++	if (value) {
+ 		if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_STOPPED) {
+ 			cdnsp_queue_halt_endpoint(pdev, pep->idx);
+ 			cdnsp_ring_cmd_db(pdev);
+@@ -613,10 +613,6 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
+ 
+ 		pep->ep_state |= EP_HALTED;
+ 	} else {
+-		/*
+-		 * In device mode driver can call reset endpoint command
+-		 * from any endpoint state.
+-		 */
+ 		cdnsp_queue_reset_ep(pdev, pep->idx);
+ 		cdnsp_ring_cmd_db(pdev);
+ 		ret = cdnsp_wait_for_cmd_compl(pdev);
+diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c
+index 794e413800ae8..2f29431f612e0 100644
+--- a/drivers/usb/cdns3/cdnsp-ring.c
++++ b/drivers/usb/cdns3/cdnsp-ring.c
+@@ -1763,10 +1763,15 @@ static u32 cdnsp_td_remainder(struct cdnsp_device *pdev,
+ 			      int trb_buff_len,
+ 			      unsigned int td_total_len,
+ 			      struct cdnsp_request *preq,
+-			      bool more_trbs_coming)
++			      bool more_trbs_coming,
++			      bool zlp)
+ {
+ 	u32 maxp, total_packet_count;
+ 
++	/* Before ZLP driver needs set TD_SIZE = 1. */
++	if (zlp)
++		return 1;
++
+ 	/* One TRB with a zero-length data packet. */
+ 	if (!more_trbs_coming || (transferred == 0 && trb_buff_len == 0) ||
+ 	    trb_buff_len == td_total_len)
+@@ -1960,7 +1965,8 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ 		/* Set the TRB length, TD size, and interrupter fields. */
+ 		remainder = cdnsp_td_remainder(pdev, enqd_len, trb_buff_len,
+ 					       full_len, preq,
+-					       more_trbs_coming);
++					       more_trbs_coming,
++					       zero_len_trb);
+ 
+ 		length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) |
+ 			TRB_INTR_TARGET(0);
+@@ -2025,7 +2031,7 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ 
+ 	if (preq->request.length > 0) {
+ 		remainder = cdnsp_td_remainder(pdev, 0, preq->request.length,
+-					       preq->request.length, preq, 1);
++					       preq->request.length, preq, 1, 0);
+ 
+ 		length_field = TRB_LEN(preq->request.length) |
+ 				TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0);
+@@ -2076,7 +2082,8 @@ int cdnsp_cmd_stop_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
+ 	u32 ep_state = GET_EP_CTX_STATE(pep->out_ctx);
+ 	int ret = 0;
+ 
+-	if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED) {
++	if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED ||
++	    ep_state == EP_STATE_HALTED) {
+ 		trace_cdnsp_ep_stopped_or_disabled(pep->out_ctx);
+ 		goto ep_stopped;
+ 	}
+@@ -2225,7 +2232,7 @@ static int cdnsp_queue_isoc_tx(struct cdnsp_device *pdev,
+ 		/* Set the TRB length, TD size, & interrupter fields. */
+ 		remainder = cdnsp_td_remainder(pdev, running_total,
+ 					       trb_buff_len, td_len, preq,
+-					       more_trbs_coming);
++					       more_trbs_coming, 0);
+ 
+ 		length_field = TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0);
+ 
+diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
+index 0ecf20eeceee9..4be6a873bd071 100644
+--- a/drivers/usb/dwc3/dwc3-exynos.c
++++ b/drivers/usb/dwc3/dwc3-exynos.c
+@@ -37,15 +37,6 @@ struct dwc3_exynos {
+ 	struct regulator	*vdd10;
+ };
+ 
+-static int dwc3_exynos_remove_child(struct device *dev, void *unused)
+-{
+-	struct platform_device *pdev = to_platform_device(dev);
+-
+-	platform_device_unregister(pdev);
+-
+-	return 0;
+-}
+-
+ static int dwc3_exynos_probe(struct platform_device *pdev)
+ {
+ 	struct dwc3_exynos	*exynos;
+@@ -142,7 +133,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
+ 	struct dwc3_exynos	*exynos = platform_get_drvdata(pdev);
+ 	int i;
+ 
+-	device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
++	of_platform_depopulate(&pdev->dev);
+ 
+ 	for (i = exynos->num_clks - 1; i >= 0; i--)
+ 		clk_disable_unprepare(exynos->clks[i]);
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 0ed9826a4c470..6f61a288073bb 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -965,7 +965,7 @@ out:
+ 	return 0;
+ }
+ 
+-static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
++static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status)
+ {
+ 	struct dwc3_request		*req;
+ 
+@@ -975,19 +975,19 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
+ 	while (!list_empty(&dep->started_list)) {
+ 		req = next_request(&dep->started_list);
+ 
+-		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++		dwc3_gadget_giveback(dep, req, status);
+ 	}
+ 
+ 	while (!list_empty(&dep->pending_list)) {
+ 		req = next_request(&dep->pending_list);
+ 
+-		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++		dwc3_gadget_giveback(dep, req, status);
+ 	}
+ 
+ 	while (!list_empty(&dep->cancelled_list)) {
+ 		req = next_request(&dep->cancelled_list);
+ 
+-		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++		dwc3_gadget_giveback(dep, req, status);
+ 	}
+ }
+ 
+@@ -1016,18 +1016,18 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
+ 	reg &= ~DWC3_DALEPENA_EP(dep->number);
+ 	dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+ 
++	dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
++
++	dep->stream_capable = false;
++	dep->type = 0;
++	dep->flags &= DWC3_EP_TXFIFO_RESIZED;
++
+ 	/* Clear out the ep descriptors for non-ep0 */
+ 	if (dep->number > 1) {
+ 		dep->endpoint.comp_desc = NULL;
+ 		dep->endpoint.desc = NULL;
+ 	}
+ 
+-	dwc3_remove_requests(dwc, dep);
+-
+-	dep->stream_capable = false;
+-	dep->type = 0;
+-	dep->flags &= DWC3_EP_TXFIFO_RESIZED;
+-
+ 	return 0;
+ }
+ 
+@@ -2350,7 +2350,7 @@ static void dwc3_stop_active_transfers(struct dwc3 *dwc)
+ 		if (!dep)
+ 			continue;
+ 
+-		dwc3_remove_requests(dwc, dep);
++		dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
+ 	}
+ }
+ 
+diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
+index f422f9c58ba79..1ea6d2e5b2187 100644
+--- a/drivers/virt/coco/sev-guest/sev-guest.c
++++ b/drivers/virt/coco/sev-guest/sev-guest.c
+@@ -67,8 +67,27 @@ static bool is_vmpck_empty(struct snp_guest_dev *snp_dev)
+ 	return true;
+ }
+ 
++/*
++ * If an error is received from the host or AMD Secure Processor (ASP) there
++ * are two options. Either retry the exact same encrypted request or discontinue
++ * using the VMPCK.
++ *
++ * This is because in the current encryption scheme GHCB v2 uses AES-GCM to
++ * encrypt the requests. The IV for this scheme is the sequence number. GCM
++ * cannot tolerate IV reuse.
++ *
++ * The ASP FW v1.51 only increments the sequence numbers on a successful
++ * guest<->ASP back and forth and only accepts messages at its exact sequence
++ * number.
++ *
++ * So if the sequence number were to be reused the encryption scheme is
++ * vulnerable. If the sequence number were incremented for a fresh IV the ASP
++ * will reject the request.
++ */
+ static void snp_disable_vmpck(struct snp_guest_dev *snp_dev)
+ {
++	dev_alert(snp_dev->dev, "Disabling vmpck_id %d to prevent IV reuse.\n",
++		  vmpck_id);
+ 	memzero_explicit(snp_dev->vmpck, VMPCK_KEY_LEN);
+ 	snp_dev->vmpck = NULL;
+ }
+@@ -321,34 +340,71 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
+ 	if (rc)
+ 		return rc;
+ 
+-	/* Call firmware to process the request */
++	/*
++	 * Call firmware to process the request. In this function the encrypted
++	 * message enters shared memory with the host. So after this call the
++	 * sequence number must be incremented or the VMPCK must be deleted to
++	 * prevent reuse of the IV.
++	 */
+ 	rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
++
++	/*
++	 * If the extended guest request fails due to having too small of a
++	 * certificate data buffer, retry the same guest request without the
++	 * extended data request in order to increment the sequence number
++	 * and thus avoid IV reuse.
++	 */
++	if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST &&
++	    err == SNP_GUEST_REQ_INVALID_LEN) {
++		const unsigned int certs_npages = snp_dev->input.data_npages;
++
++		exit_code = SVM_VMGEXIT_GUEST_REQUEST;
++
++		/*
++		 * If this call to the firmware succeeds, the sequence number can
++		 * be incremented allowing for continued use of the VMPCK. If
++		 * there is an error reflected in the return value, this value
++		 * is checked further down and the result will be the deletion
++		 * of the VMPCK and the error code being propagated back to the
++		 * user as an ioctl() return code.
++		 */
++		rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
++
++		/*
++		 * Override the error to inform callers the given extended
++		 * request buffer size was too small and give the caller the
++		 * required buffer size.
++		 */
++		err = SNP_GUEST_REQ_INVALID_LEN;
++		snp_dev->input.data_npages = certs_npages;
++	}
++
+ 	if (fw_err)
+ 		*fw_err = err;
+ 
+-	if (rc)
+-		return rc;
++	if (rc) {
++		dev_alert(snp_dev->dev,
++			  "Detected error from ASP request. rc: %d, fw_err: %llu\n",
++			  rc, *fw_err);
++		goto disable_vmpck;
++	}
+ 
+-	/*
+-	 * The verify_and_dec_payload() will fail only if the hypervisor is
+-	 * actively modifying the message header or corrupting the encrypted payload.
+-	 * This hints that hypervisor is acting in a bad faith. Disable the VMPCK so that
+-	 * the key cannot be used for any communication. The key is disabled to ensure
+-	 * that AES-GCM does not use the same IV while encrypting the request payload.
+-	 */
+ 	rc = verify_and_dec_payload(snp_dev, resp_buf, resp_sz);
+ 	if (rc) {
+ 		dev_alert(snp_dev->dev,
+-			  "Detected unexpected decode failure, disabling the vmpck_id %d\n",
+-			  vmpck_id);
+-		snp_disable_vmpck(snp_dev);
+-		return rc;
++			  "Detected unexpected decode failure from ASP. rc: %d\n",
++			  rc);
++		goto disable_vmpck;
+ 	}
+ 
+ 	/* Increment to new message sequence after payload decryption was successful. */
+ 	snp_inc_msg_seqno(snp_dev);
+ 
+ 	return 0;
++
++disable_vmpck:
++	snp_disable_vmpck(snp_dev);
++	return rc;
+ }
+ 
+ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
+diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
+index 18f0ed8b1f93b..6ebd819338ecb 100644
+--- a/drivers/xen/platform-pci.c
++++ b/drivers/xen/platform-pci.c
+@@ -144,7 +144,7 @@ static int platform_pci_probe(struct pci_dev *pdev,
+ 		if (ret) {
+ 			dev_warn(&pdev->dev, "Unable to set the evtchn callback "
+ 					 "err=%d\n", ret);
+-			goto out;
++			goto irq_out;
+ 		}
+ 	}
+ 
+@@ -152,13 +152,16 @@ static int platform_pci_probe(struct pci_dev *pdev,
+ 	grant_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
+ 	ret = gnttab_setup_auto_xlat_frames(grant_frames);
+ 	if (ret)
+-		goto out;
++		goto irq_out;
+ 	ret = gnttab_init();
+ 	if (ret)
+ 		goto grant_out;
+ 	return 0;
+ grant_out:
+ 	gnttab_free_auto_xlat_frames();
++irq_out:
++	if (!xen_have_vector_callback)
++		free_irq(pdev->irq, pdev);
+ out:
+ 	pci_release_region(pdev, 0);
+ mem_out:
+diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c
+index 5e53b4817f167..097316a741268 100644
+--- a/drivers/xen/xen-pciback/conf_space_capability.c
++++ b/drivers/xen/xen-pciback/conf_space_capability.c
+@@ -190,13 +190,16 @@ static const struct config_field caplist_pm[] = {
+ };
+ 
+ static struct msi_msix_field_config {
+-	u16          enable_bit; /* bit for enabling MSI/MSI-X */
+-	unsigned int int_type;   /* interrupt type for exclusiveness check */
++	u16          enable_bit;   /* bit for enabling MSI/MSI-X */
++	u16          allowed_bits; /* bits allowed to be changed */
++	unsigned int int_type;     /* interrupt type for exclusiveness check */
+ } msi_field_config = {
+ 	.enable_bit	= PCI_MSI_FLAGS_ENABLE,
++	.allowed_bits	= PCI_MSI_FLAGS_ENABLE,
+ 	.int_type	= INTERRUPT_TYPE_MSI,
+ }, msix_field_config = {
+ 	.enable_bit	= PCI_MSIX_FLAGS_ENABLE,
++	.allowed_bits	= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL,
+ 	.int_type	= INTERRUPT_TYPE_MSIX,
+ };
+ 
+@@ -229,7 +232,7 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
+ 		return 0;
+ 
+ 	if (!dev_data->allow_interrupt_control ||
+-	    (new_value ^ old_value) & ~field_config->enable_bit)
++	    (new_value ^ old_value) & ~field_config->allowed_bits)
+ 		return PCIBIOS_SET_FAILED;
+ 
+ 	if (new_value & field_config->enable_bit) {
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index fe0cc816b4eba..4fff0067bd2a9 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3105,6 +3105,8 @@ static int btrfs_ioctl_get_subvol_info(struct inode *inode, void __user *argp)
+ 		}
+ 	}
+ 
++	btrfs_free_path(path);
++	path = NULL;
+ 	if (copy_to_user(argp, subvol_info, sizeof(*subvol_info)))
+ 		ret = -EFAULT;
+ 
+@@ -3194,6 +3196,8 @@ static int btrfs_ioctl_get_subvol_rootref(struct btrfs_root *root,
+ 	}
+ 
+ out:
++	btrfs_free_path(path);
++
+ 	if (!ret || ret == -EOVERFLOW) {
+ 		rootrefs->num_items = found;
+ 		/* update min_treeid for next search */
+@@ -3205,7 +3209,6 @@ out:
+ 	}
+ 
+ 	kfree(rootrefs);
+-	btrfs_free_path(path);
+ 
+ 	return ret;
+ }
+@@ -4231,6 +4234,8 @@ static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg)
+ 		ipath->fspath->val[i] = rel_ptr;
+ 	}
+ 
++	btrfs_free_path(path);
++	path = NULL;
+ 	ret = copy_to_user((void __user *)(unsigned long)ipa->fspath,
+ 			   ipath->fspath, size);
+ 	if (ret) {
+@@ -4281,21 +4286,20 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_fs_info *fs_info,
+ 		size = min_t(u32, loi->size, SZ_16M);
+ 	}
+ 
+-	path = btrfs_alloc_path();
+-	if (!path) {
+-		ret = -ENOMEM;
+-		goto out;
+-	}
+-
+ 	inodes = init_data_container(size);
+ 	if (IS_ERR(inodes)) {
+ 		ret = PTR_ERR(inodes);
+-		inodes = NULL;
+-		goto out;
++		goto out_loi;
+ 	}
+ 
++	path = btrfs_alloc_path();
++	if (!path) {
++		ret = -ENOMEM;
++		goto out;
++	}
+ 	ret = iterate_inodes_from_logical(loi->logical, fs_info, path,
+ 					  inodes, ignore_offset);
++	btrfs_free_path(path);
+ 	if (ret == -EINVAL)
+ 		ret = -ENOENT;
+ 	if (ret < 0)
+@@ -4307,7 +4311,6 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_fs_info *fs_info,
+ 		ret = -EFAULT;
+ 
+ out:
+-	btrfs_free_path(path);
+ 	kvfree(inodes);
+ out_loi:
+ 	kfree(loi);
+diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
+index d5d0717fd09a3..00b97e6eb5078 100644
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -2251,8 +2251,11 @@ int __init btrfs_init_sysfs(void)
+ 
+ #ifdef CONFIG_BTRFS_DEBUG
+ 	ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_debug_feature_attr_group);
+-	if (ret)
+-		goto out2;
++	if (ret) {
++		sysfs_unmerge_group(&btrfs_kset->kobj,
++				    &btrfs_static_feature_attr_group);
++		goto out_remove_group;
++	}
+ #endif
+ 
+ 	return 0;
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 9205c4a5ca81d..11f70ba981407 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -3834,15 +3834,29 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
+ 				  u64 *last_old_dentry_offset)
+ {
+ 	struct btrfs_root *log = inode->root->log_root;
+-	struct extent_buffer *src = path->nodes[0];
+-	const int nritems = btrfs_header_nritems(src);
++	struct extent_buffer *src;
++	const int nritems = btrfs_header_nritems(path->nodes[0]);
+ 	const u64 ino = btrfs_ino(inode);
+ 	bool last_found = false;
+ 	int batch_start = 0;
+ 	int batch_size = 0;
+ 	int i;
+ 
+-	for (i = path->slots[0]; i < nritems; i++) {
++	/*
++	 * We need to clone the leaf, release the read lock on it, and use the
++	 * clone before modifying the log tree. See the comment at copy_items()
++	 * about why we need to do this.
++	 */
++	src = btrfs_clone_extent_buffer(path->nodes[0]);
++	if (!src)
++		return -ENOMEM;
++
++	i = path->slots[0];
++	btrfs_release_path(path);
++	path->nodes[0] = src;
++	path->slots[0] = i;
++
++	for (; i < nritems; i++) {
+ 		struct btrfs_dir_item *di;
+ 		struct btrfs_key key;
+ 		int ret;
+@@ -4414,7 +4428,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
+ {
+ 	struct btrfs_root *log = inode->root->log_root;
+ 	struct btrfs_file_extent_item *extent;
+-	struct extent_buffer *src = src_path->nodes[0];
++	struct extent_buffer *src;
+ 	int ret = 0;
+ 	struct btrfs_key *ins_keys;
+ 	u32 *ins_sizes;
+@@ -4425,6 +4439,43 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
+ 	const bool skip_csum = (inode->flags & BTRFS_INODE_NODATASUM);
+ 	const u64 i_size = i_size_read(&inode->vfs_inode);
+ 
++	/*
++	 * To keep lockdep happy and avoid deadlocks, clone the source leaf and
++	 * use the clone. This is because otherwise we would be changing the log
++	 * tree, to insert items from the subvolume tree or insert csum items,
++	 * while holding a read lock on a leaf from the subvolume tree, which
++	 * creates a nasty lock dependency when COWing log tree nodes/leaves:
++	 *
++	 * 1) Modifying the log tree triggers an extent buffer allocation while
++	 *    holding a write lock on a parent extent buffer from the log tree.
++	 *    Allocating the pages for an extent buffer, or the extent buffer
++	 *    struct, can trigger inode eviction and finally the inode eviction
++	 *    will trigger a release/remove of a delayed node, which requires
++	 *    taking the delayed node's mutex;
++	 *
++	 * 2) Allocating a metadata extent for a log tree can trigger the async
++	 *    reclaim thread and make us wait for it to release enough space and
++	 *    unblock our reservation ticket. The reclaim thread can start
++	 *    flushing delayed items, and that in turn results in the need to
++	 *    lock delayed node mutexes and in the need to write lock extent
++	 *    buffers of a subvolume tree - all this while holding a write lock
++	 *    on the parent extent buffer in the log tree.
++	 *
++	 * So one task in scenario 1) running in parallel with another task in
++	 * scenario 2) could lead to a deadlock, one wanting to lock a delayed
++	 * node mutex while having a read lock on a leaf from the subvolume,
++	 * while the other is holding the delayed node's mutex and wants to
++	 * write lock the same subvolume leaf for flushing delayed items.
++	 */
++	src = btrfs_clone_extent_buffer(src_path->nodes[0]);
++	if (!src)
++		return -ENOMEM;
++
++	i = src_path->slots[0];
++	btrfs_release_path(src_path);
++	src_path->nodes[0] = src;
++	src_path->slots[0] = i;
++
+ 	ins_data = kmalloc(nr * sizeof(struct btrfs_key) +
+ 			   nr * sizeof(u32), GFP_NOFS);
+ 	if (!ins_data)
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index a227d27a63bfd..9ea40ddcc4251 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -134,7 +134,8 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
+ 			super[i] = page_address(page[i]);
+ 		}
+ 
+-		if (super[0]->generation > super[1]->generation)
++		if (btrfs_super_generation(super[0]) >
++		    btrfs_super_generation(super[1]))
+ 			sector = zones[1].start;
+ 		else
+ 			sector = zones[0].start;
+@@ -466,7 +467,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ 		goto out;
+ 	}
+ 
+-	zones = kcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL);
++	zones = kvcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL);
+ 	if (!zones) {
+ 		ret = -ENOMEM;
+ 		goto out;
+@@ -585,7 +586,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ 	}
+ 
+ 
+-	kfree(zones);
++	kvfree(zones);
+ 
+ 	switch (bdev_zoned_model(bdev)) {
+ 	case BLK_ZONED_HM:
+@@ -617,7 +618,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ 	return 0;
+ 
+ out:
+-	kfree(zones);
++	kvfree(zones);
+ out_free_zone_info:
+ 	btrfs_destroy_dev_zone_info(device);
+ 
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index 53cfe026b3ea5..02b5c0ac56547 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -2247,7 +2247,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
+ 	struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
+ 	struct ceph_inode_info *ci = ceph_inode(inode);
+ 	struct ceph_mds_request *req1 = NULL, *req2 = NULL;
+-	unsigned int max_sessions;
+ 	int ret, err = 0;
+ 
+ 	spin_lock(&ci->i_unsafe_lock);
+@@ -2265,28 +2264,24 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
+ 	}
+ 	spin_unlock(&ci->i_unsafe_lock);
+ 
+-	/*
+-	 * The mdsc->max_sessions is unlikely to be changed
+-	 * mostly, here we will retry it by reallocating the
+-	 * sessions array memory to get rid of the mdsc->mutex
+-	 * lock.
+-	 */
+-retry:
+-	max_sessions = mdsc->max_sessions;
+-
+ 	/*
+ 	 * Trigger to flush the journal logs in all the relevant MDSes
+ 	 * manually, or in the worst case we must wait at most 5 seconds
+ 	 * to wait the journal logs to be flushed by the MDSes periodically.
+ 	 */
+-	if ((req1 || req2) && likely(max_sessions)) {
+-		struct ceph_mds_session **sessions = NULL;
+-		struct ceph_mds_session *s;
++	if (req1 || req2) {
+ 		struct ceph_mds_request *req;
++		struct ceph_mds_session **sessions;
++		struct ceph_mds_session *s;
++		unsigned int max_sessions;
+ 		int i;
+ 
+-		sessions = kzalloc(max_sessions * sizeof(s), GFP_KERNEL);
++		mutex_lock(&mdsc->mutex);
++		max_sessions = mdsc->max_sessions;
++
++		sessions = kcalloc(max_sessions, sizeof(s), GFP_KERNEL);
+ 		if (!sessions) {
++			mutex_unlock(&mdsc->mutex);
+ 			err = -ENOMEM;
+ 			goto out;
+ 		}
+@@ -2298,16 +2293,6 @@ retry:
+ 				s = req->r_session;
+ 				if (!s)
+ 					continue;
+-				if (unlikely(s->s_mds >= max_sessions)) {
+-					spin_unlock(&ci->i_unsafe_lock);
+-					for (i = 0; i < max_sessions; i++) {
+-						s = sessions[i];
+-						if (s)
+-							ceph_put_mds_session(s);
+-					}
+-					kfree(sessions);
+-					goto retry;
+-				}
+ 				if (!sessions[s->s_mds]) {
+ 					s = ceph_get_mds_session(s);
+ 					sessions[s->s_mds] = s;
+@@ -2320,16 +2305,6 @@ retry:
+ 				s = req->r_session;
+ 				if (!s)
+ 					continue;
+-				if (unlikely(s->s_mds >= max_sessions)) {
+-					spin_unlock(&ci->i_unsafe_lock);
+-					for (i = 0; i < max_sessions; i++) {
+-						s = sessions[i];
+-						if (s)
+-							ceph_put_mds_session(s);
+-					}
+-					kfree(sessions);
+-					goto retry;
+-				}
+ 				if (!sessions[s->s_mds]) {
+ 					s = ceph_get_mds_session(s);
+ 					sessions[s->s_mds] = s;
+@@ -2341,11 +2316,12 @@ retry:
+ 		/* the auth MDS */
+ 		spin_lock(&ci->i_ceph_lock);
+ 		if (ci->i_auth_cap) {
+-		      s = ci->i_auth_cap->session;
+-		      if (!sessions[s->s_mds])
+-			      sessions[s->s_mds] = ceph_get_mds_session(s);
++			s = ci->i_auth_cap->session;
++			if (!sessions[s->s_mds])
++				sessions[s->s_mds] = ceph_get_mds_session(s);
+ 		}
+ 		spin_unlock(&ci->i_ceph_lock);
++		mutex_unlock(&mdsc->mutex);
+ 
+ 		/* send flush mdlog request to MDSes */
+ 		for (i = 0; i < max_sessions; i++) {
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 6bc8be9ed2a56..ccad85feb24e8 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -1252,7 +1252,7 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
+ 	rc = filemap_write_and_wait_range(src_inode->i_mapping, off,
+ 					  off + len - 1);
+ 	if (rc)
+-		goto out;
++		goto unlock;
+ 
+ 	/* should we flush first and last page first */
+ 	truncate_inode_pages(&target_inode->i_data, 0);
+@@ -1268,6 +1268,8 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
+ 	 * that target is updated on the server
+ 	 */
+ 	CIFS_I(target_inode)->time = 0;
++
++unlock:
+ 	/* although unlocking in the reverse order from locking is not
+ 	 * strictly necessary here it is a little cleaner to be consistent
+ 	 */
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 11cd06aa74f0a..6a85136da27ce 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -302,14 +302,14 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
+ 
+ 	/* now drop the ref to the current iface */
+ 	if (old_iface && iface) {
+-		kref_put(&old_iface->refcount, release_iface);
+ 		cifs_dbg(FYI, "replacing iface: %pIS with %pIS\n",
+ 			 &old_iface->sockaddr,
+ 			 &iface->sockaddr);
+-	} else if (old_iface) {
+ 		kref_put(&old_iface->refcount, release_iface);
++	} else if (old_iface) {
+ 		cifs_dbg(FYI, "releasing ref to iface: %pIS\n",
+ 			 &old_iface->sockaddr);
++		kref_put(&old_iface->refcount, release_iface);
+ 	} else {
+ 		WARN_ON(!iface);
+ 		cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr);
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 5235974126bd3..8378b86c1b496 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5183,6 +5183,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ 	 * and it is decreased till we reach start.
+ 	 */
+ again:
++	ret = 0;
+ 	if (SHIFT == SHIFT_LEFT)
+ 		iterator = &start;
+ 	else
+@@ -5226,14 +5227,21 @@ again:
+ 					ext4_ext_get_actual_len(extent);
+ 		} else {
+ 			extent = EXT_FIRST_EXTENT(path[depth].p_hdr);
+-			if (le32_to_cpu(extent->ee_block) > 0)
++			if (le32_to_cpu(extent->ee_block) > start)
+ 				*iterator = le32_to_cpu(extent->ee_block) - 1;
+-			else
+-				/* Beginning is reached, end of the loop */
++			else if (le32_to_cpu(extent->ee_block) == start)
+ 				iterator = NULL;
+-			/* Update path extent in case we need to stop */
+-			while (le32_to_cpu(extent->ee_block) < start)
++			else {
++				extent = EXT_LAST_EXTENT(path[depth].p_hdr);
++				while (le32_to_cpu(extent->ee_block) >= start)
++					extent--;
++
++				if (extent == EXT_LAST_EXTENT(path[depth].p_hdr))
++					break;
++
+ 				extent++;
++				iterator = NULL;
++			}
+ 			path[depth].p_ext = extent;
+ 		}
+ 		ret = ext4_ext_shift_path_extents(path, shift, inode,
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 443f83382b9bd..9958d40207712 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1712,18 +1712,26 @@ static int writeback_single_inode(struct inode *inode,
+ 	wb = inode_to_wb_and_lock_list(inode);
+ 	spin_lock(&inode->i_lock);
+ 	/*
+-	 * If the inode is now fully clean, then it can be safely removed from
+-	 * its writeback list (if any).  Otherwise the flusher threads are
+-	 * responsible for the writeback lists.
++	 * If the inode is freeing, its i_io_list shoudn't be updated
++	 * as it can be finally deleted at this moment.
+ 	 */
+-	if (!(inode->i_state & I_DIRTY_ALL))
+-		inode_cgwb_move_to_attached(inode, wb);
+-	else if (!(inode->i_state & I_SYNC_QUEUED)) {
+-		if ((inode->i_state & I_DIRTY))
+-			redirty_tail_locked(inode, wb);
+-		else if (inode->i_state & I_DIRTY_TIME) {
+-			inode->dirtied_when = jiffies;
+-			inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
++	if (!(inode->i_state & I_FREEING)) {
++		/*
++		 * If the inode is now fully clean, then it can be safely
++		 * removed from its writeback list (if any). Otherwise the
++		 * flusher threads are responsible for the writeback lists.
++		 */
++		if (!(inode->i_state & I_DIRTY_ALL))
++			inode_cgwb_move_to_attached(inode, wb);
++		else if (!(inode->i_state & I_SYNC_QUEUED)) {
++			if ((inode->i_state & I_DIRTY))
++				redirty_tail_locked(inode, wb);
++			else if (inode->i_state & I_DIRTY_TIME) {
++				inode->dirtied_when = jiffies;
++				inode_io_list_move_locked(inode,
++							  wb,
++							  &wb->b_dirty_time);
++			}
+ 		}
+ 	}
+ 
+diff --git a/fs/fscache/volume.c b/fs/fscache/volume.c
+index a058e0136bfeb..ab8ceddf9efad 100644
+--- a/fs/fscache/volume.c
++++ b/fs/fscache/volume.c
+@@ -203,7 +203,11 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
+ 	struct fscache_volume *volume;
+ 	struct fscache_cache *cache;
+ 	size_t klen, hlen;
+-	char *key;
++	u8 *key;
++
++	klen = strlen(volume_key);
++	if (klen > NAME_MAX)
++		return NULL;
+ 
+ 	if (!coherency_data)
+ 		coherency_len = 0;
+@@ -229,7 +233,6 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
+ 	/* Stick the length on the front of the key and pad it out to make
+ 	 * hashing easier.
+ 	 */
+-	klen = strlen(volume_key);
+ 	hlen = round_up(1 + klen + 1, sizeof(__le32));
+ 	key = kzalloc(hlen, GFP_KERNEL);
+ 	if (!key)
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 71bfb663aac58..89f4741728ba3 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -2963,11 +2963,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+ 		.mode = mode
+ 	};
+ 	int err;
+-	bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
+-			   (mode & (FALLOC_FL_PUNCH_HOLE |
+-				    FALLOC_FL_ZERO_RANGE));
+-
+-	bool block_faults = FUSE_IS_DAX(inode) && lock_inode;
++	bool block_faults = FUSE_IS_DAX(inode) &&
++		(!(mode & FALLOC_FL_KEEP_SIZE) ||
++		 (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)));
+ 
+ 	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+ 		     FALLOC_FL_ZERO_RANGE))
+@@ -2976,22 +2974,20 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+ 	if (fm->fc->no_fallocate)
+ 		return -EOPNOTSUPP;
+ 
+-	if (lock_inode) {
+-		inode_lock(inode);
+-		if (block_faults) {
+-			filemap_invalidate_lock(inode->i_mapping);
+-			err = fuse_dax_break_layouts(inode, 0, 0);
+-			if (err)
+-				goto out;
+-		}
++	inode_lock(inode);
++	if (block_faults) {
++		filemap_invalidate_lock(inode->i_mapping);
++		err = fuse_dax_break_layouts(inode, 0, 0);
++		if (err)
++			goto out;
++	}
+ 
+-		if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) {
+-			loff_t endbyte = offset + length - 1;
++	if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) {
++		loff_t endbyte = offset + length - 1;
+ 
+-			err = fuse_writeback_range(inode, offset, endbyte);
+-			if (err)
+-				goto out;
+-		}
++		err = fuse_writeback_range(inode, offset, endbyte);
++		if (err)
++			goto out;
+ 	}
+ 
+ 	if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+@@ -3039,8 +3035,7 @@ out:
+ 	if (block_faults)
+ 		filemap_invalidate_unlock(inode->i_mapping);
+ 
+-	if (lock_inode)
+-		inode_unlock(inode);
++	inode_unlock(inode);
+ 
+ 	fuse_flush_time_update(inode);
+ 
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index fc17b0ac87297..f3cd614e1f1e9 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -847,10 +847,11 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+ 	struct svc_rqst *rqstp = sd->u.data;
+ 	struct page *page = buf->page;	// may be a compound one
+ 	unsigned offset = buf->offset;
++	struct page *last_page;
+ 
+-	page += offset / PAGE_SIZE;
+-	for (int i = sd->len; i > 0; i -= PAGE_SIZE)
+-		svc_rqst_replace_page(rqstp, page++);
++	last_page = page + (offset + sd->len - 1) / PAGE_SIZE;
++	for (page += offset / PAGE_SIZE; page <= last_page; page++)
++		svc_rqst_replace_page(rqstp, page);
+ 	if (rqstp->rq_res.page_len == 0)	// first call
+ 		rqstp->rq_res.page_base = offset % PAGE_SIZE;
+ 	rqstp->rq_res.page_len += sd->len;
+diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
+index 77ff8e95421fa..dc359b56fdfac 100644
+--- a/fs/nilfs2/sufile.c
++++ b/fs/nilfs2/sufile.c
+@@ -495,14 +495,22 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
+ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
+ {
+ 	struct buffer_head *bh;
++	void *kaddr;
++	struct nilfs_segment_usage *su;
+ 	int ret;
+ 
++	down_write(&NILFS_MDT(sufile)->mi_sem);
+ 	ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
+ 	if (!ret) {
+ 		mark_buffer_dirty(bh);
+ 		nilfs_mdt_mark_dirty(sufile);
++		kaddr = kmap_atomic(bh->b_page);
++		su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
++		nilfs_segment_usage_set_dirty(su);
++		kunmap_atomic(kaddr);
+ 		brelse(bh);
+ 	}
++	up_write(&NILFS_MDT(sufile)->mi_sem);
+ 	return ret;
+ }
+ 
+diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
+index 860f0b1032c65..2c53fbb8d918e 100644
+--- a/fs/zonefs/super.c
++++ b/fs/zonefs/super.c
+@@ -40,6 +40,13 @@ static void zonefs_account_active(struct inode *inode)
+ 	if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
+ 		return;
+ 
++	/*
++	 * For zones that transitioned to the offline or readonly condition,
++	 * we only need to clear the active state.
++	 */
++	if (zi->i_flags & (ZONEFS_ZONE_OFFLINE | ZONEFS_ZONE_READONLY))
++		goto out;
++
+ 	/*
+ 	 * If the zone is active, that is, if it is explicitly open or
+ 	 * partially written, check if it was already accounted as active.
+@@ -53,6 +60,7 @@ static void zonefs_account_active(struct inode *inode)
+ 		return;
+ 	}
+ 
++out:
+ 	/* The zone is not active. If it was, update the active count */
+ 	if (zi->i_flags & ZONEFS_ZONE_ACTIVE) {
+ 		zi->i_flags &= ~ZONEFS_ZONE_ACTIVE;
+@@ -324,6 +332,7 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
+ 		inode->i_flags |= S_IMMUTABLE;
+ 		inode->i_mode &= ~0777;
+ 		zone->wp = zone->start;
++		zi->i_flags |= ZONEFS_ZONE_OFFLINE;
+ 		return 0;
+ 	case BLK_ZONE_COND_READONLY:
+ 		/*
+@@ -342,8 +351,10 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
+ 			zone->cond = BLK_ZONE_COND_OFFLINE;
+ 			inode->i_mode &= ~0777;
+ 			zone->wp = zone->start;
++			zi->i_flags |= ZONEFS_ZONE_OFFLINE;
+ 			return 0;
+ 		}
++		zi->i_flags |= ZONEFS_ZONE_READONLY;
+ 		inode->i_mode &= ~0222;
+ 		return i_size_read(inode);
+ 	case BLK_ZONE_COND_FULL:
+@@ -478,14 +489,22 @@ static void __zonefs_io_error(struct inode *inode, bool write)
+ 	struct super_block *sb = inode->i_sb;
+ 	struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
+ 	unsigned int noio_flag;
+-	unsigned int nr_zones =
+-		zi->i_zone_size >> (sbi->s_zone_sectors_shift + SECTOR_SHIFT);
++	unsigned int nr_zones = 1;
+ 	struct zonefs_ioerr_data err = {
+ 		.inode = inode,
+ 		.write = write,
+ 	};
+ 	int ret;
+ 
++	/*
++	 * The only files that have more than one zone are conventional zone
++	 * files with aggregated conventional zones, for which the inode zone
++	 * size is always larger than the device zone size.
++	 */
++	if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev))
++		nr_zones = zi->i_zone_size >>
++			(sbi->s_zone_sectors_shift + SECTOR_SHIFT);
++
+ 	/*
+ 	 * Memory allocations in blkdev_report_zones() can trigger a memory
+ 	 * reclaim which may in turn cause a recursion into zonefs as well as
+@@ -1407,6 +1426,14 @@ static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
+ 	zi->i_ztype = type;
+ 	zi->i_zsector = zone->start;
+ 	zi->i_zone_size = zone->len << SECTOR_SHIFT;
++	if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT &&
++	    !(sbi->s_features & ZONEFS_F_AGGRCNV)) {
++		zonefs_err(sb,
++			   "zone size %llu doesn't match device's zone sectors %llu\n",
++			   zi->i_zone_size,
++			   bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT);
++		return -EINVAL;
++	}
+ 
+ 	zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE,
+ 			       zone->capacity << SECTOR_SHIFT);
+@@ -1456,11 +1483,11 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
+ 	struct inode *dir = d_inode(parent);
+ 	struct dentry *dentry;
+ 	struct inode *inode;
+-	int ret;
++	int ret = -ENOMEM;
+ 
+ 	dentry = d_alloc_name(parent, name);
+ 	if (!dentry)
+-		return NULL;
++		return ERR_PTR(ret);
+ 
+ 	inode = new_inode(parent->d_sb);
+ 	if (!inode)
+@@ -1485,7 +1512,7 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
+ dput:
+ 	dput(dentry);
+ 
+-	return NULL;
++	return ERR_PTR(ret);
+ }
+ 
+ struct zonefs_zone_data {
+@@ -1505,7 +1532,7 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ 	struct blk_zone *zone, *next, *end;
+ 	const char *zgroup_name;
+ 	char *file_name;
+-	struct dentry *dir;
++	struct dentry *dir, *dent;
+ 	unsigned int n = 0;
+ 	int ret;
+ 
+@@ -1523,8 +1550,8 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ 		zgroup_name = "seq";
+ 
+ 	dir = zonefs_create_inode(sb->s_root, zgroup_name, NULL, type);
+-	if (!dir) {
+-		ret = -ENOMEM;
++	if (IS_ERR(dir)) {
++		ret = PTR_ERR(dir);
+ 		goto free;
+ 	}
+ 
+@@ -1570,8 +1597,9 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ 		 * Use the file number within its group as file name.
+ 		 */
+ 		snprintf(file_name, ZONEFS_NAME_MAX - 1, "%u", n);
+-		if (!zonefs_create_inode(dir, file_name, zone, type)) {
+-			ret = -ENOMEM;
++		dent = zonefs_create_inode(dir, file_name, zone, type);
++		if (IS_ERR(dent)) {
++			ret = PTR_ERR(dent);
+ 			goto free;
+ 		}
+ 
+@@ -1905,18 +1933,18 @@ static int __init zonefs_init(void)
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = register_filesystem(&zonefs_type);
++	ret = zonefs_sysfs_init();
+ 	if (ret)
+ 		goto destroy_inodecache;
+ 
+-	ret = zonefs_sysfs_init();
++	ret = register_filesystem(&zonefs_type);
+ 	if (ret)
+-		goto unregister_fs;
++		goto sysfs_exit;
+ 
+ 	return 0;
+ 
+-unregister_fs:
+-	unregister_filesystem(&zonefs_type);
++sysfs_exit:
++	zonefs_sysfs_exit();
+ destroy_inodecache:
+ 	zonefs_destroy_inodecache();
+ 
+@@ -1925,9 +1953,9 @@ destroy_inodecache:
+ 
+ static void __exit zonefs_exit(void)
+ {
++	unregister_filesystem(&zonefs_type);
+ 	zonefs_sysfs_exit();
+ 	zonefs_destroy_inodecache();
+-	unregister_filesystem(&zonefs_type);
+ }
+ 
+ MODULE_AUTHOR("Damien Le Moal");
+diff --git a/fs/zonefs/zonefs.h b/fs/zonefs/zonefs.h
+index 4b3de66c32334..1dbe78119ff16 100644
+--- a/fs/zonefs/zonefs.h
++++ b/fs/zonefs/zonefs.h
+@@ -39,8 +39,10 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
+ 	return ZONEFS_ZTYPE_SEQ;
+ }
+ 
+-#define ZONEFS_ZONE_OPEN	(1 << 0)
+-#define ZONEFS_ZONE_ACTIVE	(1 << 1)
++#define ZONEFS_ZONE_OPEN	(1U << 0)
++#define ZONEFS_ZONE_ACTIVE	(1U << 1)
++#define ZONEFS_ZONE_OFFLINE	(1U << 2)
++#define ZONEFS_ZONE_READONLY	(1U << 3)
+ 
+ /*
+  * In-memory inode data.
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 79624711fda7c..e6bf06dc07704 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -946,7 +946,6 @@ extern void blk_queue_io_min(struct request_queue *q, unsigned int min);
+ extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt);
+ extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);
+ extern void blk_set_queue_depth(struct request_queue *q, unsigned int depth);
+-extern void blk_set_default_limits(struct queue_limits *lim);
+ extern void blk_set_stacking_limits(struct queue_limits *lim);
+ extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ 			    sector_t offset);
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 73662fbabd78f..e811e2f99a617 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -27,6 +27,7 @@
+ #include <linux/bpfptr.h>
+ #include <linux/btf.h>
+ #include <linux/rcupdate_trace.h>
++#include <linux/static_call.h>
+ 
+ struct bpf_verifier_env;
+ struct bpf_verifier_log;
+@@ -894,6 +895,10 @@ struct bpf_dispatcher {
+ 	void *rw_image;
+ 	u32 image_off;
+ 	struct bpf_ksym ksym;
++#ifdef CONFIG_HAVE_STATIC_CALL
++	struct static_call_key *sc_key;
++	void *sc_tramp;
++#endif
+ };
+ 
+ static __always_inline __nocfi unsigned int bpf_dispatcher_nop_func(
+@@ -911,6 +916,34 @@ struct bpf_trampoline *bpf_trampoline_get(u64 key,
+ 					  struct bpf_attach_target_info *tgt_info);
+ void bpf_trampoline_put(struct bpf_trampoline *tr);
+ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs);
++
++/*
++ * When the architecture supports STATIC_CALL replace the bpf_dispatcher_fn
++ * indirection with a direct call to the bpf program. If the architecture does
++ * not have STATIC_CALL, avoid a double-indirection.
++ */
++#ifdef CONFIG_HAVE_STATIC_CALL
++
++#define __BPF_DISPATCHER_SC_INIT(_name)				\
++	.sc_key = &STATIC_CALL_KEY(_name),			\
++	.sc_tramp = STATIC_CALL_TRAMP_ADDR(_name),
++
++#define __BPF_DISPATCHER_SC(name)				\
++	DEFINE_STATIC_CALL(bpf_dispatcher_##name##_call, bpf_dispatcher_nop_func)
++
++#define __BPF_DISPATCHER_CALL(name)				\
++	static_call(bpf_dispatcher_##name##_call)(ctx, insnsi, bpf_func)
++
++#define __BPF_DISPATCHER_UPDATE(_d, _new)			\
++	__static_call_update((_d)->sc_key, (_d)->sc_tramp, (_new))
++
++#else
++#define __BPF_DISPATCHER_SC_INIT(name)
++#define __BPF_DISPATCHER_SC(name)
++#define __BPF_DISPATCHER_CALL(name)		bpf_func(ctx, insnsi)
++#define __BPF_DISPATCHER_UPDATE(_d, _new)
++#endif
++
+ #define BPF_DISPATCHER_INIT(_name) {				\
+ 	.mutex = __MUTEX_INITIALIZER(_name.mutex),		\
+ 	.func = &_name##_func,					\
+@@ -922,25 +955,29 @@ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_func
+ 		.name  = #_name,				\
+ 		.lnode = LIST_HEAD_INIT(_name.ksym.lnode),	\
+ 	},							\
++	__BPF_DISPATCHER_SC_INIT(_name##_call)			\
+ }
+ 
+ #define DEFINE_BPF_DISPATCHER(name)					\
++	__BPF_DISPATCHER_SC(name);					\
+ 	noinline __nocfi unsigned int bpf_dispatcher_##name##_func(	\
+ 		const void *ctx,					\
+ 		const struct bpf_insn *insnsi,				\
+ 		bpf_func_t bpf_func)					\
+ 	{								\
+-		return bpf_func(ctx, insnsi);				\
++		return __BPF_DISPATCHER_CALL(name);			\
+ 	}								\
+ 	EXPORT_SYMBOL(bpf_dispatcher_##name##_func);			\
+ 	struct bpf_dispatcher bpf_dispatcher_##name =			\
+ 		BPF_DISPATCHER_INIT(bpf_dispatcher_##name);
++
+ #define DECLARE_BPF_DISPATCHER(name)					\
+ 	unsigned int bpf_dispatcher_##name##_func(			\
+ 		const void *ctx,					\
+ 		const struct bpf_insn *insnsi,				\
+ 		bpf_func_t bpf_func);					\
+ 	extern struct bpf_dispatcher bpf_dispatcher_##name;
++
+ #define BPF_DISPATCHER_FUNC(name) bpf_dispatcher_##name##_func
+ #define BPF_DISPATCHER_PTR(name) (&bpf_dispatcher_##name)
+ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
+diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h
+index 9f6e25467844a..444236dadcf08 100644
+--- a/include/linux/fault-inject.h
++++ b/include/linux/fault-inject.h
+@@ -20,7 +20,6 @@ struct fault_attr {
+ 	atomic_t space;
+ 	unsigned long verbose;
+ 	bool task_filter;
+-	bool no_warn;
+ 	unsigned long stacktrace_depth;
+ 	unsigned long require_start;
+ 	unsigned long require_end;
+@@ -32,6 +31,10 @@ struct fault_attr {
+ 	struct dentry *dname;
+ };
+ 
++enum fault_flags {
++	FAULT_NOWARN =	1 << 0,
++};
++
+ #define FAULT_ATTR_INITIALIZER {					\
+ 		.interval = 1,						\
+ 		.times = ATOMIC_INIT(1),				\
+@@ -40,11 +43,11 @@ struct fault_attr {
+ 		.ratelimit_state = RATELIMIT_STATE_INIT_DISABLED,	\
+ 		.verbose = 2,						\
+ 		.dname = NULL,						\
+-		.no_warn = false,					\
+ 	}
+ 
+ #define DECLARE_FAULT_ATTR(name) struct fault_attr name = FAULT_ATTR_INITIALIZER
+ int setup_fault_attr(struct fault_attr *attr, char *str);
++bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags);
+ bool should_fail(struct fault_attr *attr, ssize_t size);
+ 
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/include/linux/fscache.h b/include/linux/fscache.h
+index 36e5dd84cf599..8e312c8323a8e 100644
+--- a/include/linux/fscache.h
++++ b/include/linux/fscache.h
+@@ -75,7 +75,7 @@ struct fscache_volume {
+ 	atomic_t			n_accesses;	/* Number of cache accesses in progress */
+ 	unsigned int			debug_id;
+ 	unsigned int			key_hash;	/* Hash of key string */
+-	char				*key;		/* Volume ID, eg. "afs@example.com@1234" */
++	u8				*key;		/* Volume ID, eg. "afs@example.com@1234" */
+ 	struct list_head		proc_link;	/* Link in /proc/fs/fscache/volumes */
+ 	struct hlist_bl_node		hash_link;	/* Link in hash table */
+ 	struct work_struct		work;
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 454dab40baf69..2d56cfe0911d7 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -984,6 +984,7 @@ struct mlx5_async_work {
+ 	struct mlx5_async_ctx *ctx;
+ 	mlx5_async_cbk_t user_callback;
+ 	u16 opcode; /* cmd opcode */
++	u16 op_mod; /* cmd op_mod */
+ 	void *out; /* pointer to the cmd output buffer */
+ };
+ 
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index 3827a6b395fdb..bce6b228cf56e 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -83,7 +83,7 @@ struct neigh_parms {
+ 	struct rcu_head rcu_head;
+ 
+ 	int	reachable_time;
+-	int	qlen;
++	u32	qlen;
+ 	int	data[NEIGH_VAR_DATA_MAX];
+ 	DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX);
+ };
+diff --git a/include/sound/sof/info.h b/include/sound/sof/info.h
+index 65e86e4e9fd8e..75193850ead0c 100644
+--- a/include/sound/sof/info.h
++++ b/include/sound/sof/info.h
+@@ -36,6 +36,10 @@ enum sof_ipc_ext_data {
+ 	SOF_IPC_EXT_USER_ABI_INFO	= 4,
+ };
+ 
++/* Build u32 number in format MMmmmppp */
++#define SOF_FW_VER(MAJOR, MINOR, PATCH) ((uint32_t)( \
++	((MAJOR) << 24) | ((MINOR) << 12) | (PATCH)))
++
+ /* FW version - SOF_IPC_GLB_VERSION */
+ struct sof_ipc_fw_version {
+ 	struct sof_ipc_hdr hdr;
+diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
+index 7c1dc818b1d56..d676ed2b246ec 100644
+--- a/include/uapi/linux/audit.h
++++ b/include/uapi/linux/audit.h
+@@ -187,7 +187,7 @@
+ #define AUDIT_MAX_KEY_LEN  256
+ #define AUDIT_BITMASK_SIZE 64
+ #define AUDIT_WORD(nr) ((__u32)((nr)/32))
+-#define AUDIT_BIT(nr)  (1 << ((nr) - AUDIT_WORD(nr)*32))
++#define AUDIT_BIT(nr)  (1U << ((nr) - AUDIT_WORD(nr)*32))
+ 
+ #define AUDIT_SYSCALL_CLASSES 16
+ #define AUDIT_CLASS_DIR_WRITE 0
+diff --git a/init/Kconfig b/init/Kconfig
+index 532362fcfe31f..d1d779d6ba430 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -76,7 +76,7 @@ config CC_HAS_ASM_GOTO_OUTPUT
+ config CC_HAS_ASM_GOTO_TIED_OUTPUT
+ 	depends on CC_HAS_ASM_GOTO_OUTPUT
+ 	# Detect buggy gcc and clang, fixed in gcc-11 clang-14.
+-	def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .\n": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
++	def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
+ 
+ config TOOLS_SUPPORT_RELR
+ 	def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
+diff --git a/io_uring/filetable.c b/io_uring/filetable.c
+index 7b473259f3f45..68dfc6936aa72 100644
+--- a/io_uring/filetable.c
++++ b/io_uring/filetable.c
+@@ -101,8 +101,6 @@ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
+ err:
+ 	if (needs_switch)
+ 		io_rsrc_node_switch(ctx, ctx->file_data);
+-	if (ret)
+-		fput(file);
+ 	return ret;
+ }
+ 
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 1b552d2137635..585f97b31a93d 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -229,9 +229,14 @@ static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx)
+ 
+ static inline bool io_run_task_work(void)
+ {
++	/*
++	 * Always check-and-clear the task_work notification signal. With how
++	 * signaling works for task_work, we can find it set with nothing to
++	 * run. We need to clear it for that case, like get_signal() does.
++	 */
++	if (test_thread_flag(TIF_NOTIFY_SIGNAL))
++		clear_notify_signal();
+ 	if (task_work_pending(current)) {
+-		if (test_thread_flag(TIF_NOTIFY_SIGNAL))
+-			clear_notify_signal();
+ 		__set_current_state(TASK_RUNNING);
+ 		task_work_run();
+ 		return 1;
+diff --git a/io_uring/poll.c b/io_uring/poll.c
+index ba0f684669306..d9bf1767867e6 100644
+--- a/io_uring/poll.c
++++ b/io_uring/poll.c
+@@ -40,7 +40,14 @@ struct io_poll_table {
+ };
+ 
+ #define IO_POLL_CANCEL_FLAG	BIT(31)
+-#define IO_POLL_REF_MASK	GENMASK(30, 0)
++#define IO_POLL_RETRY_FLAG	BIT(30)
++#define IO_POLL_REF_MASK	GENMASK(29, 0)
++
++/*
++ * We usually have 1-2 refs taken, 128 is more than enough and we want to
++ * maximise the margin between this amount and the moment when it overflows.
++ */
++#define IO_POLL_REF_BIAS	128
+ 
+ #define IO_WQE_F_DOUBLE		1
+ 
+@@ -58,6 +65,21 @@ static inline bool wqe_is_double(struct wait_queue_entry *wqe)
+ 	return priv & IO_WQE_F_DOUBLE;
+ }
+ 
++static bool io_poll_get_ownership_slowpath(struct io_kiocb *req)
++{
++	int v;
++
++	/*
++	 * poll_refs are already elevated and we don't have much hope for
++	 * grabbing the ownership. Instead of incrementing set a retry flag
++	 * to notify the loop that there might have been some change.
++	 */
++	v = atomic_fetch_or(IO_POLL_RETRY_FLAG, &req->poll_refs);
++	if (v & IO_POLL_REF_MASK)
++		return false;
++	return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK);
++}
++
+ /*
+  * If refs part of ->poll_refs (see IO_POLL_REF_MASK) is 0, it's free. We can
+  * bump it and acquire ownership. It's disallowed to modify requests while not
+@@ -66,6 +88,8 @@ static inline bool wqe_is_double(struct wait_queue_entry *wqe)
+  */
+ static inline bool io_poll_get_ownership(struct io_kiocb *req)
+ {
++	if (unlikely(atomic_read(&req->poll_refs) >= IO_POLL_REF_BIAS))
++		return io_poll_get_ownership_slowpath(req);
+ 	return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK);
+ }
+ 
+@@ -116,6 +140,8 @@ static void io_poll_req_insert_locked(struct io_kiocb *req)
+ 	struct io_hash_table *table = &req->ctx->cancel_table_locked;
+ 	u32 index = hash_long(req->cqe.user_data, table->hash_bits);
+ 
++	lockdep_assert_held(&req->ctx->uring_lock);
++
+ 	hlist_add_head(&req->hash_node, &table->hbs[index].list);
+ }
+ 
+@@ -233,6 +259,16 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ 		 */
+ 		if ((v & IO_POLL_REF_MASK) != 1)
+ 			req->cqe.res = 0;
++		if (v & IO_POLL_RETRY_FLAG) {
++			req->cqe.res = 0;
++			/*
++			 * We won't find new events that came in between
++			 * vfs_poll and the ref put unless we clear the flag
++			 * in advance.
++			 */
++			atomic_andnot(IO_POLL_RETRY_FLAG, &req->poll_refs);
++			v &= ~IO_POLL_RETRY_FLAG;
++		}
+ 
+ 		/* the mask was stashed in __io_poll_execute */
+ 		if (!req->cqe.res) {
+@@ -272,7 +308,8 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ 		 * Release all references, retry if someone tried to restart
+ 		 * task_work while we were executing it.
+ 		 */
+-	} while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs));
++	} while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs) &
++					IO_POLL_REF_MASK);
+ 
+ 	return IOU_POLL_NO_ACTION;
+ }
+@@ -516,7 +553,6 @@ static int __io_arm_poll_handler(struct io_kiocb *req,
+ 				 unsigned issue_flags)
+ {
+ 	struct io_ring_ctx *ctx = req->ctx;
+-	int v;
+ 
+ 	INIT_HLIST_NODE(&req->hash_node);
+ 	req->work.cancel_seq = atomic_read(&ctx->cancel_seq);
+@@ -584,11 +620,10 @@ static int __io_arm_poll_handler(struct io_kiocb *req,
+ 
+ 	if (ipt->owning) {
+ 		/*
+-		 * Release ownership. If someone tried to queue a tw while it was
+-		 * locked, kick it off for them.
++		 * Try to release ownership. If we see a change of state, e.g.
++		 * poll was waken up, queue up a tw, it'll deal with it.
+ 		 */
+-		v = atomic_dec_return(&req->poll_refs);
+-		if (unlikely(v & IO_POLL_REF_MASK))
++		if (atomic_cmpxchg(&req->poll_refs, 1, 0) != 1)
+ 			__io_poll_execute(req, 0);
+ 	}
+ 	return 0;
+diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
+index fa64b80b8bcab..c19719f48ce06 100644
+--- a/kernel/bpf/dispatcher.c
++++ b/kernel/bpf/dispatcher.c
+@@ -4,6 +4,7 @@
+ #include <linux/hash.h>
+ #include <linux/bpf.h>
+ #include <linux/filter.h>
++#include <linux/static_call.h>
+ 
+ /* The BPF dispatcher is a multiway branch code generator. The
+  * dispatcher is a mechanism to avoid the performance penalty of an
+@@ -104,17 +105,11 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image, void *b
+ 
+ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ {
+-	void *old, *new, *tmp;
+-	u32 noff;
+-	int err;
+-
+-	if (!prev_num_progs) {
+-		old = NULL;
+-		noff = 0;
+-	} else {
+-		old = d->image + d->image_off;
++	void *new, *tmp;
++	u32 noff = 0;
++
++	if (prev_num_progs)
+ 		noff = d->image_off ^ (PAGE_SIZE / 2);
+-	}
+ 
+ 	new = d->num_progs ? d->image + noff : NULL;
+ 	tmp = d->num_progs ? d->rw_image + noff : NULL;
+@@ -128,11 +123,10 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ 			return;
+ 	}
+ 
+-	err = bpf_arch_text_poke(d->func, BPF_MOD_JUMP, old, new);
+-	if (err || !new)
+-		return;
++	__BPF_DISPATCHER_UPDATE(d, new ?: (void *)&bpf_dispatcher_nop_func);
+ 
+-	d->image_off = noff;
++	if (new)
++		d->image_off = noff;
+ }
+ 
+ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
+diff --git a/kernel/gcov/clang.c b/kernel/gcov/clang.c
+index cbb0bed958abd..7670a811a5657 100644
+--- a/kernel/gcov/clang.c
++++ b/kernel/gcov/clang.c
+@@ -280,6 +280,8 @@ void gcov_info_add(struct gcov_info *dst, struct gcov_info *src)
+ 
+ 		for (i = 0; i < sfn_ptr->num_counters; i++)
+ 			dfn_ptr->counters[i] += sfn_ptr->counters[i];
++
++		sfn_ptr = list_next_entry(sfn_ptr, head);
+ 	}
+ }
+ 
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index cb131fad117cc..997d23641448a 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -2095,6 +2095,7 @@ config KPROBES_SANITY_TEST
+ 	depends on DEBUG_KERNEL
+ 	depends on KPROBES
+ 	depends on KUNIT
++	select STACKTRACE if ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
+ 	default KUNIT_ALL_TESTS
+ 	help
+ 	  This option provides for testing basic kprobes functionality on
+diff --git a/lib/fault-inject.c b/lib/fault-inject.c
+index 423784d9c058e..70768d8a2200b 100644
+--- a/lib/fault-inject.c
++++ b/lib/fault-inject.c
+@@ -41,9 +41,6 @@ EXPORT_SYMBOL_GPL(setup_fault_attr);
+ 
+ static void fail_dump(struct fault_attr *attr)
+ {
+-	if (attr->no_warn)
+-		return;
+-
+ 	if (attr->verbose > 0 && __ratelimit(&attr->ratelimit_state)) {
+ 		printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure.\n"
+ 		       "name %pd, interval %lu, probability %lu, "
+@@ -103,7 +100,7 @@ static inline bool fail_stacktrace(struct fault_attr *attr)
+  * http://www.nongnu.org/failmalloc/
+  */
+ 
+-bool should_fail(struct fault_attr *attr, ssize_t size)
++bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags)
+ {
+ 	if (in_task()) {
+ 		unsigned int fail_nth = READ_ONCE(current->fail_nth);
+@@ -146,13 +143,19 @@ bool should_fail(struct fault_attr *attr, ssize_t size)
+ 		return false;
+ 
+ fail:
+-	fail_dump(attr);
++	if (!(flags & FAULT_NOWARN))
++		fail_dump(attr);
+ 
+ 	if (atomic_read(&attr->times) != -1)
+ 		atomic_dec_not_zero(&attr->times);
+ 
+ 	return true;
+ }
++
++bool should_fail(struct fault_attr *attr, ssize_t size)
++{
++	return should_fail_ex(attr, size, 0);
++}
+ EXPORT_SYMBOL_GPL(should_fail);
+ 
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/lib/vdso/Makefile b/lib/vdso/Makefile
+index c415a685d61bb..e814061d6aa01 100644
+--- a/lib/vdso/Makefile
++++ b/lib/vdso/Makefile
+@@ -17,6 +17,6 @@ $(error ARCH_REL_TYPE_ABS is not set)
+ endif
+ 
+ quiet_cmd_vdso_check = VDSOCHK $@
+-      cmd_vdso_check = if $(OBJDUMP) -R $@ | egrep -h "$(ARCH_REL_TYPE_ABS)"; \
++      cmd_vdso_check = if $(OBJDUMP) -R $@ | grep -E -h "$(ARCH_REL_TYPE_ABS)"; \
+ 		       then (echo >&2 "$@: dynamic relocations are not supported"; \
+ 			     rm -f $@; /bin/false); fi
+diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
+index bdef9682d0a00..b4b9614eecbed 100644
+--- a/mm/damon/sysfs.c
++++ b/mm/damon/sysfs.c
+@@ -2342,6 +2342,10 @@ static int damon_sysfs_upd_schemes_stats(struct damon_sysfs_kdamond *kdamond)
+ 	damon_for_each_scheme(scheme, ctx) {
+ 		struct damon_sysfs_stats *sysfs_stats;
+ 
++		/* user could have removed the scheme sysfs dir */
++		if (schemes_idx >= sysfs_schemes->nr)
++			break;
++
+ 		sysfs_stats = sysfs_schemes->schemes_arr[schemes_idx++]->stats;
+ 		sysfs_stats->nr_tried = scheme->stat.nr_tried;
+ 		sysfs_stats->sz_tried = scheme->stat.sz_tried;
+diff --git a/mm/failslab.c b/mm/failslab.c
+index 58df9789f1d22..ffc420c0e767f 100644
+--- a/mm/failslab.c
++++ b/mm/failslab.c
+@@ -16,6 +16,8 @@ static struct {
+ 
+ bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags)
+ {
++	int flags = 0;
++
+ 	/* No fault-injection for bootstrap cache */
+ 	if (unlikely(s == kmem_cache))
+ 		return false;
+@@ -30,10 +32,16 @@ bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags)
+ 	if (failslab.cache_filter && !(s->flags & SLAB_FAILSLAB))
+ 		return false;
+ 
++	/*
++	 * In some cases, it expects to specify __GFP_NOWARN
++	 * to avoid printing any information(not just a warning),
++	 * thus avoiding deadlocks. See commit 6b9dbedbe349 for
++	 * details.
++	 */
+ 	if (gfpflags & __GFP_NOWARN)
+-		failslab.attr.no_warn = true;
++		flags |= FAULT_NOWARN;
+ 
+-	return should_fail(&failslab.attr, s->object_size);
++	return should_fail_ex(&failslab.attr, s->object_size, flags);
+ }
+ 
+ static int __init setup_failslab(char *str)
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index b69979c9ced5c..6a95ea7c5ee70 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -2971,7 +2971,7 @@ struct obj_cgroup *get_obj_cgroup_from_page(struct page *page)
+ {
+ 	struct obj_cgroup *objcg;
+ 
+-	if (!memcg_kmem_enabled() || memcg_kmem_bypass())
++	if (!memcg_kmem_enabled())
+ 		return NULL;
+ 
+ 	if (PageMemcgKmem(page)) {
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 19749f5409e72..5d9b98774a826 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -3883,6 +3883,8 @@ __setup("fail_page_alloc=", setup_fail_page_alloc);
+ 
+ static bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
+ {
++	int flags = 0;
++
+ 	if (order < fail_page_alloc.min_order)
+ 		return false;
+ 	if (gfp_mask & __GFP_NOFAIL)
+@@ -3893,10 +3895,11 @@ static bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
+ 			(gfp_mask & __GFP_DIRECT_RECLAIM))
+ 		return false;
+ 
++	/* See comment in __should_failslab() */
+ 	if (gfp_mask & __GFP_NOWARN)
+-		fail_page_alloc.attr.no_warn = true;
++		flags |= FAULT_NOWARN;
+ 
+-	return should_fail(&fail_page_alloc.attr, 1 << order);
++	return should_fail_ex(&fail_page_alloc.attr, 1 << order, flags);
+ }
+ 
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 382dbe97329f3..a69f32dd5ce5d 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2472,8 +2472,20 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
+ 	 * the flushers simply cannot keep up with the allocation
+ 	 * rate. Nudge the flusher threads in case they are asleep.
+ 	 */
+-	if (stat.nr_unqueued_dirty == nr_taken)
++	if (stat.nr_unqueued_dirty == nr_taken) {
+ 		wakeup_flusher_threads(WB_REASON_VMSCAN);
++		/*
++		 * For cgroupv1 dirty throttling is achieved by waking up
++		 * the kernel flusher here and later waiting on folios
++		 * which are in writeback to finish (see shrink_folio_list()).
++		 *
++		 * Flusher may not be able to issue writeback quickly
++		 * enough for cgroupv1 writeback throttling to work
++		 * on a large system.
++		 */
++		if (!writeback_throttling_sane(sc))
++			reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK);
++	}
+ 
+ 	sc->nr.dirty += stat.nr_dirty;
+ 	sc->nr.congested += stat.nr_congested;
+@@ -2955,8 +2967,8 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ 	enum lru_list lru;
+ 	unsigned long nr_reclaimed = 0;
+ 	unsigned long nr_to_reclaim = sc->nr_to_reclaim;
++	bool proportional_reclaim;
+ 	struct blk_plug plug;
+-	bool scan_adjusted;
+ 
+ 	get_scan_count(lruvec, sc, nr);
+ 
+@@ -2974,8 +2986,8 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ 	 * abort proportional reclaim if either the file or anon lru has already
+ 	 * dropped to zero at the first pass.
+ 	 */
+-	scan_adjusted = (!cgroup_reclaim(sc) && !current_is_kswapd() &&
+-			 sc->priority == DEF_PRIORITY);
++	proportional_reclaim = (!cgroup_reclaim(sc) && !current_is_kswapd() &&
++				sc->priority == DEF_PRIORITY);
+ 
+ 	blk_start_plug(&plug);
+ 	while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
+@@ -2995,7 +3007,7 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ 
+ 		cond_resched();
+ 
+-		if (nr_reclaimed < nr_to_reclaim || scan_adjusted)
++		if (nr_reclaimed < nr_to_reclaim || proportional_reclaim)
+ 			continue;
+ 
+ 		/*
+@@ -3046,8 +3058,6 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ 		nr_scanned = targets[lru] - nr[lru];
+ 		nr[lru] = targets[lru] * (100 - percentage) / 100;
+ 		nr[lru] -= min(nr[lru], nr_scanned);
+-
+-		scan_adjusted = true;
+ 	}
+ 	blk_finish_plug(&plug);
+ 	sc->nr_reclaimed += nr_reclaimed;
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 0191f22d1ec35..8487321c1fc78 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -202,9 +202,11 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+ 
+ 	list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
+ 		list_move(&req->req_list, &cancel_list);
++		req->status = REQ_STATUS_ERROR;
+ 	}
+ 	list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
+ 		list_move(&req->req_list, &cancel_list);
++		req->status = REQ_STATUS_ERROR;
+ 	}
+ 
+ 	spin_unlock(&m->req_lock);
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 7105529abb0f6..c433b1fb961ab 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -272,7 +272,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb,
+ 	key->ct_zone = ct->zone.id;
+ #endif
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-	key->ct_mark = ct->mark;
++	key->ct_mark = READ_ONCE(ct->mark);
+ #endif
+ 
+ 	cl = nf_ct_labels_find(ct);
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 84755db81e9d9..35f5a3125808d 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -307,7 +307,31 @@ static int neigh_del_timer(struct neighbour *n)
+ 	return 0;
+ }
+ 
+-static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
++static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev,
++						   int family)
++{
++	switch (family) {
++	case AF_INET:
++		return __in_dev_arp_parms_get_rcu(dev);
++	case AF_INET6:
++		return __in6_dev_nd_parms_get_rcu(dev);
++	}
++	return NULL;
++}
++
++static void neigh_parms_qlen_dec(struct net_device *dev, int family)
++{
++	struct neigh_parms *p;
++
++	rcu_read_lock();
++	p = neigh_get_dev_parms_rcu(dev, family);
++	if (p)
++		p->qlen--;
++	rcu_read_unlock();
++}
++
++static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net,
++			       int family)
+ {
+ 	struct sk_buff_head tmp;
+ 	unsigned long flags;
+@@ -321,13 +345,7 @@ static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
+ 		struct net_device *dev = skb->dev;
+ 
+ 		if (net == NULL || net_eq(dev_net(dev), net)) {
+-			struct in_device *in_dev;
+-
+-			rcu_read_lock();
+-			in_dev = __in_dev_get_rcu(dev);
+-			if (in_dev)
+-				in_dev->arp_parms->qlen--;
+-			rcu_read_unlock();
++			neigh_parms_qlen_dec(dev, family);
+ 			__skb_unlink(skb, list);
+ 			__skb_queue_tail(&tmp, skb);
+ 		}
+@@ -409,7 +427,8 @@ static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
+ 	write_lock_bh(&tbl->lock);
+ 	neigh_flush_dev(tbl, dev, skip_perm);
+ 	pneigh_ifdown_and_unlock(tbl, dev);
+-	pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL);
++	pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL,
++			   tbl->family);
+ 	if (skb_queue_empty_lockless(&tbl->proxy_queue))
+ 		del_timer_sync(&tbl->proxy_timer);
+ 	return 0;
+@@ -1621,13 +1640,8 @@ static void neigh_proxy_process(struct timer_list *t)
+ 
+ 		if (tdif <= 0) {
+ 			struct net_device *dev = skb->dev;
+-			struct in_device *in_dev;
+ 
+-			rcu_read_lock();
+-			in_dev = __in_dev_get_rcu(dev);
+-			if (in_dev)
+-				in_dev->arp_parms->qlen--;
+-			rcu_read_unlock();
++			neigh_parms_qlen_dec(dev, tbl->family);
+ 			__skb_unlink(skb, &tbl->proxy_queue);
+ 
+ 			if (tbl->proxy_redo && netif_running(dev)) {
+@@ -1821,7 +1835,7 @@ int neigh_table_clear(int index, struct neigh_table *tbl)
+ 	cancel_delayed_work_sync(&tbl->managed_work);
+ 	cancel_delayed_work_sync(&tbl->gc_work);
+ 	del_timer_sync(&tbl->proxy_timer);
+-	pneigh_queue_purge(&tbl->proxy_queue, NULL);
++	pneigh_queue_purge(&tbl->proxy_queue, NULL, tbl->family);
+ 	neigh_ifdown(tbl, NULL);
+ 	if (atomic_read(&tbl->entries))
+ 		pr_crit("neighbour leakage\n");
+@@ -3542,18 +3556,6 @@ static int proc_unres_qlen(struct ctl_table *ctl, int write,
+ 	return ret;
+ }
+ 
+-static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev,
+-						   int family)
+-{
+-	switch (family) {
+-	case AF_INET:
+-		return __in_dev_arp_parms_get_rcu(dev);
+-	case AF_INET6:
+-		return __in6_dev_nd_parms_get_rcu(dev);
+-	}
+-	return NULL;
+-}
+-
+ static void neigh_copy_dflt_parms(struct net *net, struct neigh_parms *p,
+ 				  int index)
+ {
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index da6e3b20cd758..60379ad7ae06d 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -136,6 +136,8 @@ failure:
+ 	 * This unhashes the socket and releases the local port, if necessary.
+ 	 */
+ 	dccp_set_state(sk, DCCP_CLOSED);
++	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++		inet_reset_saddr(sk);
+ 	ip_rt_put(rt);
+ 	sk->sk_route_caps = 0;
+ 	inet->inet_dport = 0;
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index fd44638ec16b8..f9ed81a0ddbb9 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -967,6 +967,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
+ 
+ late_failure:
+ 	dccp_set_state(sk, DCCP_CLOSED);
++	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++		inet_reset_saddr(sk);
+ 	__sk_dst_reset(sk);
+ failure:
+ 	inet->inet_dport = 0;
+diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
+index e983bb0c50127..2dfb12230f089 100644
+--- a/net/ipv4/Kconfig
++++ b/net/ipv4/Kconfig
+@@ -402,6 +402,16 @@ config INET_IPCOMP
+ 
+ 	  If unsure, say Y.
+ 
++config INET_TABLE_PERTURB_ORDER
++	int "INET: Source port perturbation table size (as power of 2)" if EXPERT
++	default 16
++	help
++	  Source port perturbation table size (as power of 2) for
++	  RFC 6056 3.3.4.  Algorithm 4: Double-Hash Port Selection Algorithm.
++
++	  The default is almost always what you want.
++	  Only change this if you know what you are doing.
++
+ config INET_XFRM_TUNNEL
+ 	tristate
+ 	select INET_TUNNEL
+diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
+index 170152772d332..3969fa805679c 100644
+--- a/net/ipv4/esp4_offload.c
++++ b/net/ipv4/esp4_offload.c
+@@ -314,6 +314,9 @@ static int esp_xmit(struct xfrm_state *x, struct sk_buff *skb,  netdev_features_
+ 			xo->seq.low += skb_shinfo(skb)->gso_segs;
+ 	}
+ 
++	if (xo->seq.low < seq)
++		xo->seq.hi++;
++
+ 	esp.seqno = cpu_to_be64(seq + ((u64)xo->seq.hi << 32));
+ 
+ 	ip_hdr(skb)->tot_len = htons(skb->len);
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 452ff177e4da9..f26d5ac117d62 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1381,8 +1381,10 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ 
+ 	/* The alias was already inserted, so the node must exist. */
+ 	l = l ? l : fib_find_node(t, &tp, key);
+-	if (WARN_ON_ONCE(!l))
++	if (WARN_ON_ONCE(!l)) {
++		err = -ENOENT;
+ 		goto out_free_new_fa;
++	}
+ 
+ 	if (fib_find_alias(&l->leaf, new_fa->fa_slen, 0, 0, tb->tb_id, true) ==
+ 	    new_fa) {
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index f5950a7172d61..1e45fe6276f72 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -679,13 +679,13 @@ EXPORT_SYMBOL_GPL(inet_unhash);
+  * Note that we use 32bit integers (vs RFC 'short integers')
+  * because 2^16 is not a multiple of num_ephemeral and this
+  * property might be used by clever attacker.
++ *
+  * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, though
+- * attacks were since demonstrated, thus we use 65536 instead to really
+- * give more isolation and privacy, at the expense of 256kB of kernel
+- * memory.
++ * attacks were since demonstrated, thus we use 65536 by default instead
++ * to really give more isolation and privacy, at the expense of 256kB
++ * of kernel memory.
+  */
+-#define INET_TABLE_PERTURB_SHIFT 16
+-#define INET_TABLE_PERTURB_SIZE (1 << INET_TABLE_PERTURB_SHIFT)
++#define INET_TABLE_PERTURB_SIZE (1 << CONFIG_INET_TABLE_PERTURB_ORDER)
+ static u32 *table_perturb;
+ 
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
+index 1b512390b3cf3..e880ce77322aa 100644
+--- a/net/ipv4/ip_input.c
++++ b/net/ipv4/ip_input.c
+@@ -366,6 +366,11 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+ 					   iph->tos, dev);
+ 		if (unlikely(err))
+ 			goto drop_error;
++	} else {
++		struct in_device *in_dev = __in_dev_get_rcu(dev);
++
++		if (in_dev && IN_DEV_ORCONF(in_dev, NOPOLICY))
++			IPCB(skb)->flags |= IPSKB_NOPOLICY;
+ 	}
+ 
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+index f8e176c77d1c1..b3cc416ed2923 100644
+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+@@ -435,7 +435,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ 
+ 	switch (ctinfo) {
+ 	case IP_CT_NEW:
+-		ct->mark = hash;
++		WRITE_ONCE(ct->mark, hash);
+ 		break;
+ 	case IP_CT_RELATED:
+ 	case IP_CT_RELATED_REPLY:
+@@ -452,7 +452,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ #ifdef DEBUG
+ 	nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ #endif
+-	pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
++	pr_debug("hash=%u ct_hash=%u ", hash, READ_ONCE(ct->mark));
+ 	if (!clusterip_responsible(cipinfo->config, hash)) {
+ 		pr_debug("not responsible\n");
+ 		return NF_DROP;
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index fe9a6022db66d..ef8013e2134fd 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -323,6 +323,8 @@ failure:
+ 	 * if necessary.
+ 	 */
+ 	tcp_set_state(sk, TCP_CLOSE);
++	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++		inet_reset_saddr(sk);
+ 	ip_rt_put(rt);
+ 	sk->sk_route_caps = 0;
+ 	inet->inet_dport = 0;
+diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
+index 79d43548279cb..242f4295940e6 100644
+--- a/net/ipv6/esp6_offload.c
++++ b/net/ipv6/esp6_offload.c
+@@ -346,6 +346,9 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb,  netdev_features
+ 			xo->seq.low += skb_shinfo(skb)->gso_segs;
+ 	}
+ 
++	if (xo->seq.low < seq)
++		xo->seq.hi++;
++
+ 	esp.seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32));
+ 
+ 	len = skb->len - sizeof(struct ipv6hdr);
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index e54eee80ce5f3..5516cfb96c488 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -340,6 +340,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
+ 
+ late_failure:
+ 	tcp_set_state(sk, TCP_CLOSE);
++	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++		inet_reset_saddr(sk);
+ failure:
+ 	inet->inet_dport = 0;
+ 	sk->sk_route_caps = 0;
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 4a4b0e49ec92d..ea435eba30534 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -287,9 +287,13 @@ int __init xfrm6_init(void)
+ 	if (ret)
+ 		goto out_state;
+ 
+-	register_pernet_subsys(&xfrm6_net_ops);
++	ret = register_pernet_subsys(&xfrm6_net_ops);
++	if (ret)
++		goto out_protocol;
+ out:
+ 	return ret;
++out_protocol:
++	xfrm6_protocol_fini();
+ out_state:
+ 	xfrm6_state_fini();
+ out_policy:
+diff --git a/net/key/af_key.c b/net/key/af_key.c
+index c85df5b958d26..95edcbedf6ef2 100644
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -2905,7 +2905,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
+ 			break;
+ 		if (!aalg->pfkey_supported)
+ 			continue;
+-		if (aalg_tmpl_set(t, aalg) && aalg->available)
++		if (aalg_tmpl_set(t, aalg))
+ 			sz += sizeof(struct sadb_comb);
+ 	}
+ 	return sz + sizeof(struct sadb_prop);
+@@ -2923,7 +2923,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+ 		if (!ealg->pfkey_supported)
+ 			continue;
+ 
+-		if (!(ealg_tmpl_set(t, ealg) && ealg->available))
++		if (!(ealg_tmpl_set(t, ealg)))
+ 			continue;
+ 
+ 		for (k = 1; ; k++) {
+@@ -2934,16 +2934,17 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+ 			if (!aalg->pfkey_supported)
+ 				continue;
+ 
+-			if (aalg_tmpl_set(t, aalg) && aalg->available)
++			if (aalg_tmpl_set(t, aalg))
+ 				sz += sizeof(struct sadb_comb);
+ 		}
+ 	}
+ 	return sz + sizeof(struct sadb_prop);
+ }
+ 
+-static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
++static int dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ {
+ 	struct sadb_prop *p;
++	int sz = 0;
+ 	int i;
+ 
+ 	p = skb_put(skb, sizeof(struct sadb_prop));
+@@ -2971,13 +2972,17 @@ static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ 			c->sadb_comb_soft_addtime = 20*60*60;
+ 			c->sadb_comb_hard_usetime = 8*60*60;
+ 			c->sadb_comb_soft_usetime = 7*60*60;
++			sz += sizeof(*c);
+ 		}
+ 	}
++
++	return sz + sizeof(*p);
+ }
+ 
+-static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
++static int dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ {
+ 	struct sadb_prop *p;
++	int sz = 0;
+ 	int i, k;
+ 
+ 	p = skb_put(skb, sizeof(struct sadb_prop));
+@@ -3019,8 +3024,11 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ 			c->sadb_comb_soft_addtime = 20*60*60;
+ 			c->sadb_comb_hard_usetime = 8*60*60;
+ 			c->sadb_comb_soft_usetime = 7*60*60;
++			sz += sizeof(*c);
+ 		}
+ 	}
++
++	return sz + sizeof(*p);
+ }
+ 
+ static int key_notify_policy_expire(struct xfrm_policy *xp, const struct km_event *c)
+@@ -3150,6 +3158,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ 	struct sadb_x_sec_ctx *sec_ctx;
+ 	struct xfrm_sec_ctx *xfrm_ctx;
+ 	int ctx_size = 0;
++	int alg_size = 0;
+ 
+ 	sockaddr_size = pfkey_sockaddr_size(x->props.family);
+ 	if (!sockaddr_size)
+@@ -3161,16 +3170,16 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ 		sizeof(struct sadb_x_policy);
+ 
+ 	if (x->id.proto == IPPROTO_AH)
+-		size += count_ah_combs(t);
++		alg_size = count_ah_combs(t);
+ 	else if (x->id.proto == IPPROTO_ESP)
+-		size += count_esp_combs(t);
++		alg_size = count_esp_combs(t);
+ 
+ 	if ((xfrm_ctx = x->security)) {
+ 		ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
+ 		size +=  sizeof(struct sadb_x_sec_ctx) + ctx_size;
+ 	}
+ 
+-	skb =  alloc_skb(size + 16, GFP_ATOMIC);
++	skb =  alloc_skb(size + alg_size + 16, GFP_ATOMIC);
+ 	if (skb == NULL)
+ 		return -ENOMEM;
+ 
+@@ -3224,10 +3233,13 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ 	pol->sadb_x_policy_priority = xp->priority;
+ 
+ 	/* Set sadb_comb's. */
++	alg_size = 0;
+ 	if (x->id.proto == IPPROTO_AH)
+-		dump_ah_combs(skb, t);
++		alg_size = dump_ah_combs(skb, t);
+ 	else if (x->id.proto == IPPROTO_ESP)
+-		dump_esp_combs(skb, t);
++		alg_size = dump_esp_combs(skb, t);
++
++	hdr->sadb_msg_len += alg_size / 8;
+ 
+ 	/* security context */
+ 	if (xfrm_ctx) {
+@@ -3382,7 +3394,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
+ 	hdr->sadb_msg_len = size / sizeof(uint64_t);
+ 	hdr->sadb_msg_errno = 0;
+ 	hdr->sadb_msg_reserved = 0;
+-	hdr->sadb_msg_seq = x->km.seq = get_acqseq();
++	hdr->sadb_msg_seq = x->km.seq;
+ 	hdr->sadb_msg_pid = 0;
+ 
+ 	/* SA */
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index 5b1c47ed0cc08..87e24bba4c673 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1437,8 +1437,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+ 	ieee80211_led_exit(local);
+ 	destroy_workqueue(local->workqueue);
+  fail_workqueue:
+-	if (local->wiphy_ciphers_allocated)
++	if (local->wiphy_ciphers_allocated) {
+ 		kfree(local->hw.wiphy->cipher_suites);
++		local->wiphy_ciphers_allocated = false;
++	}
+ 	kfree(local->int_scan_req);
+ 	return result;
+ }
+@@ -1506,8 +1508,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
+ 	mutex_destroy(&local->iflist_mtx);
+ 	mutex_destroy(&local->mtx);
+ 
+-	if (local->wiphy_ciphers_allocated)
++	if (local->wiphy_ciphers_allocated) {
+ 		kfree(local->hw.wiphy->cipher_suites);
++		local->wiphy_ciphers_allocated = false;
++	}
+ 
+ 	idr_for_each(&local->ack_status_frames,
+ 		     ieee80211_free_ack_frame, NULL);
+diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
+index acc1c299f1ae5..69d5e1ec6edef 100644
+--- a/net/mac80211/mesh_pathtbl.c
++++ b/net/mac80211/mesh_pathtbl.c
+@@ -710,7 +710,7 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
+ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
+ 			     struct sk_buff *skb)
+ {
+-	kfree_skb(skb);
++	ieee80211_free_txskb(&sdata->local->hw, skb);
+ 	sdata->u.mesh.mshstats.dropped_frames_no_route++;
+ }
+ 
+diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
+index 3adc291d9ce18..7499192af5866 100644
+--- a/net/netfilter/ipset/ip_set_hash_gen.h
++++ b/net/netfilter/ipset/ip_set_hash_gen.h
+@@ -916,7 +916,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+ #ifdef IP_SET_HASH_WITH_MULTI
+ 		if (h->bucketsize >= AHASH_MAX_TUNED)
+ 			goto set_full;
+-		else if (h->bucketsize < multi)
++		else if (h->bucketsize <= multi)
+ 			h->bucketsize += AHASH_INIT_SIZE;
+ #endif
+ 		if (n->size >= AHASH_MAX(h)) {
+diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
+index dd30c03d5a23f..75d556d71652d 100644
+--- a/net/netfilter/ipset/ip_set_hash_ip.c
++++ b/net/netfilter/ipset/ip_set_hash_ip.c
+@@ -151,18 +151,16 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
+ 		return -ERANGE;
+ 
+-	if (retried) {
++	if (retried)
+ 		ip = ntohl(h->next.ip);
+-		e.ip = htonl(ip);
+-	}
+ 	for (; ip <= ip_to;) {
++		e.ip = htonl(ip);
+ 		ret = adtfn(set, &e, &ext, &ext, flags);
+ 		if (ret && !ip_set_eexist(ret, flags))
+ 			return ret;
+ 
+ 		ip += hosts;
+-		e.ip = htonl(ip);
+-		if (e.ip == 0)
++		if (ip == 0)
+ 			return 0;
+ 
+ 		ret = 0;
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 8f261cd5b3a50..60289c074eef4 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1781,7 +1781,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
+ 			}
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-			ct->mark = exp->master->mark;
++			ct->mark = READ_ONCE(exp->master->mark);
+ #endif
+ #ifdef CONFIG_NF_CONNTRACK_SECMARK
+ 			ct->secmark = exp->master->secmark;
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index 7562b215b932a..d71150a40fb08 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -328,9 +328,9 @@ nla_put_failure:
+ }
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
++static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
+ {
+-	if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
++	if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
+ 		goto nla_put_failure;
+ 	return 0;
+ 
+@@ -543,7 +543,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
+ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ 	if (ctnetlink_dump_status(skb, ct) < 0 ||
+-	    ctnetlink_dump_mark(skb, ct) < 0 ||
++	    ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
+ 	    ctnetlink_dump_secctx(skb, ct) < 0 ||
+ 	    ctnetlink_dump_id(skb, ct) < 0 ||
+ 	    ctnetlink_dump_use(skb, ct) < 0 ||
+@@ -722,6 +722,7 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ 	struct sk_buff *skb;
+ 	unsigned int type;
+ 	unsigned int flags = 0, group;
++	u32 mark;
+ 	int err;
+ 
+ 	if (events & (1 << IPCT_DESTROY)) {
+@@ -826,8 +827,9 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ 	}
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	if ((events & (1 << IPCT_MARK) || ct->mark)
+-	    && ctnetlink_dump_mark(skb, ct) < 0)
++	mark = READ_ONCE(ct->mark);
++	if ((events & (1 << IPCT_MARK) || mark) &&
++	    ctnetlink_dump_mark(skb, mark) < 0)
+ 		goto nla_put_failure;
+ #endif
+ 	nlmsg_end(skb, nlh);
+@@ -1154,7 +1156,7 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
+ 	}
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	if ((ct->mark & filter->mark.mask) != filter->mark.val)
++	if ((READ_ONCE(ct->mark) & filter->mark.mask) != filter->mark.val)
+ 		goto ignore_entry;
+ #endif
+ 	status = (u32)READ_ONCE(ct->status);
+@@ -2002,9 +2004,9 @@ static void ctnetlink_change_mark(struct nf_conn *ct,
+ 		mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
+ 
+ 	mark = ntohl(nla_get_be32(cda[CTA_MARK]));
+-	newmark = (ct->mark & mask) ^ mark;
+-	if (newmark != ct->mark)
+-		ct->mark = newmark;
++	newmark = (READ_ONCE(ct->mark) & mask) ^ mark;
++	if (newmark != READ_ONCE(ct->mark))
++		WRITE_ONCE(ct->mark, newmark);
+ }
+ #endif
+ 
+@@ -2669,6 +2671,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ 	const struct nf_conntrack_zone *zone;
+ 	struct nlattr *nest_parms;
++	u32 mark;
+ 
+ 	zone = nf_ct_zone(ct);
+ 
+@@ -2730,7 +2733,8 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ 		goto nla_put_failure;
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0)
++	mark = READ_ONCE(ct->mark);
++	if (mark && ctnetlink_dump_mark(skb, mark) < 0)
+ 		goto nla_put_failure;
+ #endif
+ 	if (ctnetlink_dump_labels(skb, ct) < 0)
+diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
+index 4ffe84c5a82cb..bca839ab1ae8d 100644
+--- a/net/netfilter/nf_conntrack_standalone.c
++++ b/net/netfilter/nf_conntrack_standalone.c
+@@ -366,7 +366,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
+ 		goto release;
+ 
+ #if defined(CONFIG_NF_CONNTRACK_MARK)
+-	seq_printf(s, "mark=%u ", ct->mark);
++	seq_printf(s, "mark=%u ", READ_ONCE(ct->mark));
+ #endif
+ 
+ 	ct_show_secctx(s, ct);
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index b04645ced89ba..00b522890d77b 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -1098,6 +1098,7 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
+ 	struct flow_block_cb *block_cb, *next;
+ 	int err = 0;
+ 
++	down_write(&flowtable->flow_block_lock);
+ 	switch (cmd) {
+ 	case FLOW_BLOCK_BIND:
+ 		list_splice(&bo->cb_list, &flowtable->flow_block.cb_list);
+@@ -1112,6 +1113,7 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
+ 		WARN_ON_ONCE(1);
+ 		err = -EOPNOTSUPP;
+ 	}
++	up_write(&flowtable->flow_block_lock);
+ 
+ 	return err;
+ }
+@@ -1168,7 +1170,9 @@ static int nf_flow_table_offload_cmd(struct flow_block_offload *bo,
+ 
+ 	nf_flow_table_block_offload_init(bo, dev_net(dev), cmd, flowtable,
+ 					 extack);
++	down_write(&flowtable->flow_block_lock);
+ 	err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_FT, bo);
++	up_write(&flowtable->flow_block_lock);
+ 	if (err < 0)
+ 		return err;
+ 
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 42e370575c304..0a6f3c1e9ab75 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5958,7 +5958,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ 					    &timeout);
+ 		if (err)
+ 			return err;
+-	} else if (set->flags & NFT_SET_TIMEOUT) {
++	} else if (set->flags & NFT_SET_TIMEOUT &&
++		   !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+ 		timeout = set->timeout;
+ 	}
+ 
+@@ -6024,7 +6025,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ 			err = -EOPNOTSUPP;
+ 			goto err_set_elem_expr;
+ 		}
+-	} else if (set->num_exprs > 0) {
++	} else if (set->num_exprs > 0 &&
++		   !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+ 		err = nft_set_elem_expr_clone(ctx, set, expr_array);
+ 		if (err < 0)
+ 			goto err_set_elem_expr_clone;
+diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
+index a3f01f209a533..641dc21f92b43 100644
+--- a/net/netfilter/nft_ct.c
++++ b/net/netfilter/nft_ct.c
+@@ -98,7 +98,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
+ 		return;
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+ 	case NFT_CT_MARK:
+-		*dest = ct->mark;
++		*dest = READ_ONCE(ct->mark);
+ 		return;
+ #endif
+ #ifdef CONFIG_NF_CONNTRACK_SECMARK
+@@ -297,8 +297,8 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
+ 	switch (priv->key) {
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+ 	case NFT_CT_MARK:
+-		if (ct->mark != value) {
+-			ct->mark = value;
++		if (READ_ONCE(ct->mark) != value) {
++			WRITE_ONCE(ct->mark, value);
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 		}
+ 		break;
+diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
+index e5ebc0810675a..ad3c033db64e7 100644
+--- a/net/netfilter/xt_connmark.c
++++ b/net/netfilter/xt_connmark.c
+@@ -30,6 +30,7 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+ 	u_int32_t new_targetmark;
+ 	struct nf_conn *ct;
+ 	u_int32_t newmark;
++	u_int32_t oldmark;
+ 
+ 	ct = nf_ct_get(skb, &ctinfo);
+ 	if (ct == NULL)
+@@ -37,14 +38,15 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+ 
+ 	switch (info->mode) {
+ 	case XT_CONNMARK_SET:
+-		newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
++		oldmark = READ_ONCE(ct->mark);
++		newmark = (oldmark & ~info->ctmask) ^ info->ctmark;
+ 		if (info->shift_dir == D_SHIFT_RIGHT)
+ 			newmark >>= info->shift_bits;
+ 		else
+ 			newmark <<= info->shift_bits;
+ 
+-		if (ct->mark != newmark) {
+-			ct->mark = newmark;
++		if (READ_ONCE(ct->mark) != newmark) {
++			WRITE_ONCE(ct->mark, newmark);
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 		}
+ 		break;
+@@ -55,15 +57,15 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+ 		else
+ 			new_targetmark <<= info->shift_bits;
+ 
+-		newmark = (ct->mark & ~info->ctmask) ^
++		newmark = (READ_ONCE(ct->mark) & ~info->ctmask) ^
+ 			  new_targetmark;
+-		if (ct->mark != newmark) {
+-			ct->mark = newmark;
++		if (READ_ONCE(ct->mark) != newmark) {
++			WRITE_ONCE(ct->mark, newmark);
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 		}
+ 		break;
+ 	case XT_CONNMARK_RESTORE:
+-		new_targetmark = (ct->mark & info->ctmask);
++		new_targetmark = (READ_ONCE(ct->mark) & info->ctmask);
+ 		if (info->shift_dir == D_SHIFT_RIGHT)
+ 			new_targetmark >>= info->shift_bits;
+ 		else
+@@ -126,7 +128,7 @@ connmark_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ 	if (ct == NULL)
+ 		return false;
+ 
+-	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
++	return ((READ_ONCE(ct->mark) & info->mask) == info->mark) ^ info->invert;
+ }
+ 
+ static int connmark_mt_check(const struct xt_mtchk_param *par)
+diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
+index 6a193cce2a754..4ffdf2f45c444 100644
+--- a/net/nfc/nci/core.c
++++ b/net/nfc/nci/core.c
+@@ -542,7 +542,7 @@ static int nci_open_device(struct nci_dev *ndev)
+ 		skb_queue_purge(&ndev->tx_q);
+ 
+ 		ndev->ops->close(ndev);
+-		ndev->flags = 0;
++		ndev->flags &= BIT(NCI_UNREG);
+ 	}
+ 
+ done:
+diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
+index aa5e712adf078..3d36ea5701f02 100644
+--- a/net/nfc/nci/data.c
++++ b/net/nfc/nci/data.c
+@@ -279,8 +279,10 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb)
+ 		 nci_plen(skb->data));
+ 
+ 	conn_info = nci_get_conn_info_by_conn_id(ndev, nci_conn_id(skb->data));
+-	if (!conn_info)
++	if (!conn_info) {
++		kfree_skb(skb);
+ 		return;
++	}
+ 
+ 	/* strip the nci data header */
+ 	skb_pull(skb, NCI_DATA_HDR_SIZE);
+diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
+index 4e70df91d0f2a..fc5b374fe5686 100644
+--- a/net/openvswitch/conntrack.c
++++ b/net/openvswitch/conntrack.c
+@@ -152,7 +152,7 @@ static u8 ovs_ct_get_state(enum ip_conntrack_info ctinfo)
+ static u32 ovs_ct_get_mark(const struct nf_conn *ct)
+ {
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-	return ct ? ct->mark : 0;
++	return ct ? READ_ONCE(ct->mark) : 0;
+ #else
+ 	return 0;
+ #endif
+@@ -340,9 +340,9 @@ static int ovs_ct_set_mark(struct nf_conn *ct, struct sw_flow_key *key,
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+ 	u32 new_mark;
+ 
+-	new_mark = ct_mark | (ct->mark & ~(mask));
+-	if (ct->mark != new_mark) {
+-		ct->mark = new_mark;
++	new_mark = ct_mark | (READ_ONCE(ct->mark) & ~(mask));
++	if (READ_ONCE(ct->mark) != new_mark) {
++		WRITE_ONCE(ct->mark, new_mark);
+ 		if (nf_ct_is_confirmed(ct))
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 		key->ct.mark = new_mark;
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index 62c70709d7980..e0123efa2a623 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -399,6 +399,7 @@ enum rxrpc_conn_proto_state {
+ struct rxrpc_bundle {
+ 	struct rxrpc_conn_parameters params;
+ 	refcount_t		ref;
++	atomic_t		active;		/* Number of active users */
+ 	unsigned int		debug_id;
+ 	bool			try_upgrade;	/* True if the bundle is attempting upgrade */
+ 	bool			alloc_conn;	/* True if someone's getting a conn */
+diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
+index 3c9eeb5b750c1..bdb335cb2d057 100644
+--- a/net/rxrpc/conn_client.c
++++ b/net/rxrpc/conn_client.c
+@@ -40,6 +40,8 @@ __read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ;
+ DEFINE_IDR(rxrpc_client_conn_ids);
+ static DEFINE_SPINLOCK(rxrpc_conn_id_lock);
+ 
++static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
++
+ /*
+  * Get a connection ID and epoch for a client connection from the global pool.
+  * The connection struct pointer is then recorded in the idr radix tree.  The
+@@ -123,6 +125,7 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
+ 		bundle->params = *cp;
+ 		rxrpc_get_peer(bundle->params.peer);
+ 		refcount_set(&bundle->ref, 1);
++		atomic_set(&bundle->active, 1);
+ 		spin_lock_init(&bundle->channel_lock);
+ 		INIT_LIST_HEAD(&bundle->waiting_calls);
+ 	}
+@@ -149,7 +152,7 @@ void rxrpc_put_bundle(struct rxrpc_bundle *bundle)
+ 
+ 	dead = __refcount_dec_and_test(&bundle->ref, &r);
+ 
+-	_debug("PUT B=%x %d", d, r);
++	_debug("PUT B=%x %d", d, r - 1);
+ 	if (dead)
+ 		rxrpc_free_bundle(bundle);
+ }
+@@ -338,6 +341,7 @@ found_bundle_free:
+ 	rxrpc_free_bundle(candidate);
+ found_bundle:
+ 	rxrpc_get_bundle(bundle);
++	atomic_inc(&bundle->active);
+ 	spin_unlock(&local->client_bundles_lock);
+ 	_leave(" = %u [found]", bundle->debug_id);
+ 	return bundle;
+@@ -435,6 +439,7 @@ static void rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle, gfp_t gfp)
+ 			if (old)
+ 				trace_rxrpc_client(old, -1, rxrpc_client_replace);
+ 			candidate->bundle_shift = shift;
++			atomic_inc(&bundle->active);
+ 			bundle->conns[i] = candidate;
+ 			for (j = 0; j < RXRPC_MAXCALLS; j++)
+ 				set_bit(shift + j, &bundle->avail_chans);
+@@ -725,6 +730,7 @@ granted_channel:
+ 	smp_rmb();
+ 
+ out_put_bundle:
++	rxrpc_deactivate_bundle(bundle);
+ 	rxrpc_put_bundle(bundle);
+ out:
+ 	_leave(" = %d", ret);
+@@ -900,9 +906,8 @@ out:
+ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ {
+ 	struct rxrpc_bundle *bundle = conn->bundle;
+-	struct rxrpc_local *local = bundle->params.local;
+ 	unsigned int bindex;
+-	bool need_drop = false, need_put = false;
++	bool need_drop = false;
+ 	int i;
+ 
+ 	_enter("C=%x", conn->debug_id);
+@@ -921,15 +926,22 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ 	}
+ 	spin_unlock(&bundle->channel_lock);
+ 
+-	/* If there are no more connections, remove the bundle */
+-	if (!bundle->avail_chans) {
+-		_debug("maybe unbundle");
+-		spin_lock(&local->client_bundles_lock);
++	if (need_drop) {
++		rxrpc_deactivate_bundle(bundle);
++		rxrpc_put_connection(conn);
++	}
++}
+ 
+-		for (i = 0; i < ARRAY_SIZE(bundle->conns); i++)
+-			if (bundle->conns[i])
+-				break;
+-		if (i == ARRAY_SIZE(bundle->conns) && !bundle->params.exclusive) {
++/*
++ * Drop the active count on a bundle.
++ */
++static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)
++{
++	struct rxrpc_local *local = bundle->params.local;
++	bool need_put = false;
++
++	if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) {
++		if (!bundle->params.exclusive) {
+ 			_debug("erase bundle");
+ 			rb_erase(&bundle->local_node, &local->client_bundles);
+ 			need_put = true;
+@@ -939,10 +951,6 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ 		if (need_put)
+ 			rxrpc_put_bundle(bundle);
+ 	}
+-
+-	if (need_drop)
+-		rxrpc_put_connection(conn);
+-	_leave("");
+ }
+ 
+ /*
+diff --git a/net/sched/Kconfig b/net/sched/Kconfig
+index 1e8ab4749c6c3..4662a6ce8a7e7 100644
+--- a/net/sched/Kconfig
++++ b/net/sched/Kconfig
+@@ -976,7 +976,7 @@ config NET_ACT_TUNNEL_KEY
+ 
+ config NET_ACT_CT
+ 	tristate "connection tracking tc action"
+-	depends on NET_CLS_ACT && NF_CONNTRACK && NF_NAT && NF_FLOW_TABLE
++	depends on NET_CLS_ACT && NF_CONNTRACK && (!NF_NAT || NF_NAT) && NF_FLOW_TABLE
+ 	help
+ 	  Say Y here to allow sending the packets to conntrack module.
+ 
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 09e2aafc8943b..0deb4e96a6c2e 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -62,7 +62,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+ 
+ 	c = nf_ct_get(skb, &ctinfo);
+ 	if (c) {
+-		skb->mark = c->mark;
++		skb->mark = READ_ONCE(c->mark);
+ 		/* using overlimits stats to count how many packets marked */
+ 		ca->tcf_qstats.overlimits++;
+ 		goto out;
+@@ -82,7 +82,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+ 	c = nf_ct_tuplehash_to_ctrack(thash);
+ 	/* using overlimits stats to count how many packets marked */
+ 	ca->tcf_qstats.overlimits++;
+-	skb->mark = c->mark;
++	skb->mark = READ_ONCE(c->mark);
+ 	nf_ct_put(c);
+ 
+ out:
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
+index 5950974ae8f64..a015915e5b726 100644
+--- a/net/sched/act_ct.c
++++ b/net/sched/act_ct.c
+@@ -178,7 +178,7 @@ static void tcf_ct_flow_table_add_action_meta(struct nf_conn *ct,
+ 	entry = tcf_ct_flow_table_flow_action_get_next(action);
+ 	entry->id = FLOW_ACTION_CT_METADATA;
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-	entry->ct_metadata.mark = ct->mark;
++	entry->ct_metadata.mark = READ_ONCE(ct->mark);
+ #endif
+ 	ctinfo = dir == IP_CT_DIR_ORIGINAL ? IP_CT_ESTABLISHED :
+ 					     IP_CT_ESTABLISHED_REPLY;
+@@ -940,9 +940,9 @@ static void tcf_ct_act_set_mark(struct nf_conn *ct, u32 mark, u32 mask)
+ 	if (!mask)
+ 		return;
+ 
+-	new_mark = mark | (ct->mark & ~(mask));
+-	if (ct->mark != new_mark) {
+-		ct->mark = new_mark;
++	new_mark = mark | (READ_ONCE(ct->mark) & ~(mask));
++	if (READ_ONCE(ct->mark) != new_mark) {
++		WRITE_ONCE(ct->mark, new_mark);
+ 		if (nf_ct_is_confirmed(ct))
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 	}
+diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c
+index 0281e45987a47..65a20f3c9514e 100644
+--- a/net/sched/act_ctinfo.c
++++ b/net/sched/act_ctinfo.c
+@@ -33,7 +33,7 @@ static void tcf_ctinfo_dscp_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ {
+ 	u8 dscp, newdscp;
+ 
+-	newdscp = (((ct->mark & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
++	newdscp = (((READ_ONCE(ct->mark) & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
+ 		     ~INET_ECN_MASK;
+ 
+ 	switch (proto) {
+@@ -73,7 +73,7 @@ static void tcf_ctinfo_cpmark_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ 				  struct sk_buff *skb)
+ {
+ 	ca->stats_cpmark_set++;
+-	skb->mark = ct->mark & cp->cpmarkmask;
++	skb->mark = READ_ONCE(ct->mark) & cp->cpmarkmask;
+ }
+ 
+ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -131,7 +131,7 @@ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+ 	}
+ 
+ 	if (cp->mode & CTINFO_MODE_DSCP)
+-		if (!cp->dscpstatemask || (ct->mark & cp->dscpstatemask))
++		if (!cp->dscpstatemask || (READ_ONCE(ct->mark) & cp->dscpstatemask))
+ 			tcf_ctinfo_dscp_set(ct, ca, cp, skb, wlen, proto);
+ 
+ 	if (cp->mode & CTINFO_MODE_CPMARK)
+diff --git a/net/tipc/discover.c b/net/tipc/discover.c
+index e8630707901e3..e8dcdf267c0c3 100644
+--- a/net/tipc/discover.c
++++ b/net/tipc/discover.c
+@@ -211,7 +211,10 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
+ 	u32 self;
+ 	int err;
+ 
+-	skb_linearize(skb);
++	if (skb_linearize(skb)) {
++		kfree_skb(skb);
++		return;
++	}
+ 	hdr = buf_msg(skb);
+ 
+ 	if (caps & TIPC_NODE_ID128)
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index d92ec92f0b71d..e3b427a703980 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -176,7 +176,7 @@ static void tipc_conn_close(struct tipc_conn *con)
+ 	conn_put(con);
+ }
+ 
+-static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
++static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *sock)
+ {
+ 	struct tipc_conn *con;
+ 	int ret;
+@@ -202,10 +202,12 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
+ 	}
+ 	con->conid = ret;
+ 	s->idr_in_use++;
+-	spin_unlock_bh(&s->idr_lock);
+ 
+ 	set_bit(CF_CONNECTED, &con->flags);
+ 	con->server = s;
++	con->sock = sock;
++	conn_get(con);
++	spin_unlock_bh(&s->idr_lock);
+ 
+ 	return con;
+ }
+@@ -467,7 +469,7 @@ static void tipc_topsrv_accept(struct work_struct *work)
+ 		ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
+ 		if (ret < 0)
+ 			return;
+-		con = tipc_conn_alloc(srv);
++		con = tipc_conn_alloc(srv, newsock);
+ 		if (IS_ERR(con)) {
+ 			ret = PTR_ERR(con);
+ 			sock_release(newsock);
+@@ -479,11 +481,11 @@ static void tipc_topsrv_accept(struct work_struct *work)
+ 		newsk->sk_data_ready = tipc_conn_data_ready;
+ 		newsk->sk_write_space = tipc_conn_write_space;
+ 		newsk->sk_user_data = con;
+-		con->sock = newsock;
+ 		write_unlock_bh(&newsk->sk_callback_lock);
+ 
+ 		/* Wake up receive process in case of 'SYN+' message */
+ 		newsk->sk_data_ready(newsk);
++		conn_put(con);
+ 	}
+ }
+ 
+@@ -577,17 +579,17 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
+ 	sub.filter = filter;
+ 	*(u64 *)&sub.usr_handle = (u64)port;
+ 
+-	con = tipc_conn_alloc(tipc_topsrv(net));
++	con = tipc_conn_alloc(tipc_topsrv(net), NULL);
+ 	if (IS_ERR(con))
+ 		return false;
+ 
+ 	*conid = con->conid;
+-	con->sock = NULL;
+ 	rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
+-	if (rc >= 0)
+-		return true;
++	if (rc)
++		conn_put(con);
++
+ 	conn_put(con);
+-	return false;
++	return !rc;
+ }
+ 
+ void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 775836f6785ab..450d609b512a1 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -1555,10 +1555,12 @@ static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate)
+ 	tmp = result;
+ 	tmp *= SCALE;
+ 	do_div(tmp, mcs_divisors[rate->mcs]);
+-	result = tmp;
+ 
+ 	/* and take NSS */
+-	result = (result * rate->nss) / 8;
++	tmp *= rate->nss;
++	do_div(tmp, 8);
++
++	result = tmp;
+ 
+ 	return result / 10000;
+ }
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 637ca88384368..9af6bf1652e48 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -97,6 +97,18 @@ static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
+ 	}
+ }
+ 
++static inline bool xmit_xfrm_check_overflow(struct sk_buff *skb)
++{
++	struct xfrm_offload *xo = xfrm_offload(skb);
++	__u32 seq = xo->seq.low;
++
++	seq += skb_shinfo(skb)->gso_segs;
++	if (unlikely(seq < xo->seq.low))
++		return true;
++
++	return false;
++}
++
+ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
+ {
+ 	int err;
+@@ -134,7 +146,8 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ 		return skb;
+ 	}
+ 
+-	if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
++	if (skb_is_gso(skb) && (unlikely(x->xso.dev != dev) ||
++				unlikely(xmit_xfrm_check_overflow(skb)))) {
+ 		struct sk_buff *segs;
+ 
+ 		/* Packet got rerouted, fixup features and segment it. */
+diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
+index 9277d81b344cb..49dd788859d8b 100644
+--- a/net/xfrm/xfrm_replay.c
++++ b/net/xfrm/xfrm_replay.c
+@@ -714,7 +714,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
+ 			oseq += skb_shinfo(skb)->gso_segs;
+ 		}
+ 
+-		if (unlikely(oseq < replay_esn->oseq)) {
++		if (unlikely(xo->seq.low < replay_esn->oseq)) {
+ 			XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi;
+ 			xo->seq.hi = oseq_hi;
+ 			replay_esn->oseq_hi = oseq_hi;
+diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
+index b9eb3208f2888..ae31bb1275940 100644
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -320,6 +320,11 @@ static const struct config_entry config_table[] = {
+ 			{}
+ 		}
+ 	},
++	{
++		.flags = FLAG_SOF,
++		.device = 0x34c8,
++		.codec_hid =  &essx_83x6,
++	},
+ 	{
+ 		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ 		.device = 0x34c8,
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 6c0f1de10429a..d9715bea965e1 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -206,6 +206,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"),
+ 		}
+ 	},
++	{
++		.driver_data = &acp6x_card,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
++		}
++	},
+ 	{}
+ };
+ 
+diff --git a/sound/soc/codecs/hdac_hda.h b/sound/soc/codecs/hdac_hda.h
+index d0efc5e254ae9..da0ed74758b05 100644
+--- a/sound/soc/codecs/hdac_hda.h
++++ b/sound/soc/codecs/hdac_hda.h
+@@ -14,7 +14,7 @@ enum {
+ 	HDAC_HDMI_1_DAI_ID,
+ 	HDAC_HDMI_2_DAI_ID,
+ 	HDAC_HDMI_3_DAI_ID,
+-	HDAC_LAST_DAI_ID = HDAC_HDMI_3_DAI_ID,
++	HDAC_DAI_ID_NUM
+ };
+ 
+ struct hdac_hda_pcm {
+@@ -24,7 +24,7 @@ struct hdac_hda_pcm {
+ 
+ struct hdac_hda_priv {
+ 	struct hda_codec codec;
+-	struct hdac_hda_pcm pcm[HDAC_LAST_DAI_ID];
++	struct hdac_hda_pcm pcm[HDAC_DAI_ID_NUM];
+ 	bool need_display_power;
+ };
+ 
+diff --git a/sound/soc/codecs/max98373-i2c.c b/sound/soc/codecs/max98373-i2c.c
+index 3e04c7f0cce43..ec0905df65d18 100644
+--- a/sound/soc/codecs/max98373-i2c.c
++++ b/sound/soc/codecs/max98373-i2c.c
+@@ -549,6 +549,10 @@ static int max98373_i2c_probe(struct i2c_client *i2c)
+ 	max98373->cache = devm_kcalloc(&i2c->dev, max98373->cache_num,
+ 				       sizeof(*max98373->cache),
+ 				       GFP_KERNEL);
++	if (!max98373->cache) {
++		ret = -ENOMEM;
++		return ret;
++	}
+ 
+ 	for (i = 0; i < max98373->cache_num; i++)
+ 		max98373->cache[i].reg = max98373_i2c_cache_reg[i];
+diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
+index 3fafd9fc5cfd6..75a45ad55aa87 100644
+--- a/sound/soc/codecs/sgtl5000.c
++++ b/sound/soc/codecs/sgtl5000.c
+@@ -1794,6 +1794,7 @@ static int sgtl5000_i2c_remove(struct i2c_client *client)
+ {
+ 	struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
+ 
++	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL, SGTL5000_CHIP_CLK_CTRL_DEFAULT);
+ 	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT);
+ 	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT);
+ 
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 6432b83f616f3..a935c5fd9edbc 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -443,6 +443,13 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
+ 					| BYT_CHT_ES8316_INTMIC_IN2_MAP
+ 					| BYT_CHT_ES8316_JD_INVERTED),
+ 	},
++	{	/* Nanote UMPC-01 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"),
++		},
++		.driver_data = (void *)BYT_CHT_ES8316_INTMIC_IN1_MAP,
++	},
+ 	{	/* Teclast X98 Plus II */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
+index 606cc3242a60f..5c218a39ca201 100644
+--- a/sound/soc/intel/boards/sof_es8336.c
++++ b/sound/soc/intel/boards/sof_es8336.c
+@@ -63,6 +63,7 @@ struct sof_es8336_private {
+ 	struct snd_soc_jack jack;
+ 	struct list_head hdmi_pcm_list;
+ 	bool speaker_en;
++	struct delayed_work pcm_pop_work;
+ };
+ 
+ struct sof_hdmi_pcm {
+@@ -111,6 +112,46 @@ static void log_quirks(struct device *dev)
+ 		dev_info(dev, "quirk headset at mic1 port enabled\n");
+ }
+ 
++static void pcm_pop_work_events(struct work_struct *work)
++{
++	struct sof_es8336_private *priv =
++		container_of(work, struct sof_es8336_private, pcm_pop_work.work);
++
++	gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
++
++	if (quirk & SOF_ES8336_HEADPHONE_GPIO)
++		gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
++
++}
++
++static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
++	struct snd_soc_card *card = rtd->card;
++	struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
++
++	switch (cmd) {
++	case SNDRV_PCM_TRIGGER_START:
++	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++	case SNDRV_PCM_TRIGGER_RESUME:
++		break;
++
++	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++	case SNDRV_PCM_TRIGGER_SUSPEND:
++	case SNDRV_PCM_TRIGGER_STOP:
++		if (priv->speaker_en == false)
++			if (substream->stream == 0) {
++				cancel_delayed_work(&priv->pcm_pop_work);
++				gpiod_set_value_cansleep(priv->gpio_speakers, true);
++			}
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
+ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+ 					  struct snd_kcontrol *kcontrol, int event)
+ {
+@@ -122,19 +163,7 @@ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+ 
+ 	priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event);
+ 
+-	if (SND_SOC_DAPM_EVENT_ON(event))
+-		msleep(70);
+-
+-	gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
+-
+-	if (!(quirk & SOF_ES8336_HEADPHONE_GPIO))
+-		return 0;
+-
+-	if (SND_SOC_DAPM_EVENT_ON(event))
+-		msleep(70);
+-
+-	gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
+-
++	queue_delayed_work(system_wq, &priv->pcm_pop_work, msecs_to_jiffies(70));
+ 	return 0;
+ }
+ 
+@@ -344,6 +373,7 @@ static int sof_es8336_hw_params(struct snd_pcm_substream *substream,
+ /* machine stream operations */
+ static struct snd_soc_ops sof_es8336_ops = {
+ 	.hw_params = sof_es8336_hw_params,
++	.trigger = sof_8336_trigger,
+ };
+ 
+ static struct snd_soc_dai_link_component platform_component[] = {
+@@ -722,7 +752,8 @@ static int sof_es8336_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	INIT_LIST_HEAD(&priv->hdmi_pcm_list);
+-
++	INIT_DELAYED_WORK(&priv->pcm_pop_work,
++				pcm_pop_work_events);
+ 	snd_soc_card_set_drvdata(card, priv);
+ 
+ 	if (mach->mach_params.dmic_num > 0) {
+@@ -751,6 +782,7 @@ static int sof_es8336_remove(struct platform_device *pdev)
+ 	struct snd_soc_card *card = platform_get_drvdata(pdev);
+ 	struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
+ 
++	cancel_delayed_work(&priv->pcm_pop_work);
+ 	gpiod_put(priv->gpio_speakers);
+ 	device_remove_software_node(priv->codec_dev);
+ 	put_device(priv->codec_dev);
+diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+index b032bc07de8bf..d0062f2cd2566 100644
+--- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c
++++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+@@ -10,6 +10,11 @@
+ #include <sound/soc-acpi-intel-match.h>
+ #include "../skylake/skl.h"
+ 
++static const struct snd_soc_acpi_codecs essx_83x6 = {
++	.num_codecs = 3,
++	.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
++};
++
+ static struct skl_machine_pdata icl_pdata = {
+ 	.use_tplg_pcm = true,
+ };
+@@ -27,6 +32,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = {
+ 		.drv_name = "sof_rt5682",
+ 		.sof_tplg_filename = "sof-icl-rt5682.tplg",
+ 	},
++	{
++		.comp_ids = &essx_83x6,
++		.drv_name = "sof-essx8336",
++		.sof_tplg_filename = "sof-icl-es8336", /* the tplg suffix is added at run time */
++		.tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
++					SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
++					SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
++	},
+ 	{},
+ };
+ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines);
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 4d9b91e7e14f1..f6a996f0f9c74 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -800,11 +800,6 @@ static int __soc_pcm_open(struct snd_soc_pcm_runtime *rtd,
+ 		ret = snd_soc_dai_startup(dai, substream);
+ 		if (ret < 0)
+ 			goto err;
+-
+-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-			dai->tx_mask = 0;
+-		else
+-			dai->rx_mask = 0;
+ 	}
+ 
+ 	/* Dynamic PCM DAI links compat checks use dynamic capabilities */
+diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
+index a39b43850f0ed..bf8a46463cec7 100644
+--- a/sound/soc/sof/ipc3-topology.c
++++ b/sound/soc/sof/ipc3-topology.c
+@@ -2242,6 +2242,7 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ 	struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
+ 	struct snd_sof_widget *swidget;
+ 	struct snd_sof_route *sroute;
++	bool dyn_widgets = false;
+ 	int ret;
+ 
+ 	/*
+@@ -2251,12 +2252,14 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ 	 * topology loading the sound card unavailable to open PCMs.
+ 	 */
+ 	list_for_each_entry(swidget, &sdev->widget_list, list) {
+-		if (swidget->dynamic_pipeline_widget)
++		if (swidget->dynamic_pipeline_widget) {
++			dyn_widgets = true;
+ 			continue;
++		}
+ 
+-		/* Do not free widgets for static pipelines with FW ABI older than 3.19 */
++		/* Do not free widgets for static pipelines with FW older than SOF2.2 */
+ 		if (!verify && !swidget->dynamic_pipeline_widget &&
+-		    v->abi_version < SOF_ABI_VER(3, 19, 0)) {
++		    SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) {
+ 			swidget->use_count = 0;
+ 			swidget->complete = 0;
+ 			continue;
+@@ -2270,9 +2273,11 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ 	/*
+ 	 * Tear down all pipelines associated with PCMs that did not get suspended
+ 	 * and unset the prepare flag so that they can be set up again during resume.
+-	 * Skip this step for older firmware.
++	 * Skip this step for older firmware unless topology has any
++	 * dynamic pipeline (in which case the step is mandatory).
+ 	 */
+-	if (!verify && v->abi_version >= SOF_ABI_VER(3, 19, 0)) {
++	if (!verify && (dyn_widgets || SOF_FW_VER(v->major, v->minor, v->micro) >=
++	    SOF_FW_VER(2, 2, 0))) {
+ 		ret = sof_tear_down_left_over_pipelines(sdev);
+ 		if (ret < 0) {
+ 			dev_err(sdev->dev, "failed to tear down paused pipelines\n");
+diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
+index 643fc8a170184..837c1848d9bff 100644
+--- a/sound/soc/stm/stm32_adfsdm.c
++++ b/sound/soc/stm/stm32_adfsdm.c
+@@ -304,6 +304,11 @@ static int stm32_adfsdm_dummy_cb(const void *data, void *private)
+ 	return 0;
+ }
+ 
++static void stm32_adfsdm_cleanup(void *data)
++{
++	iio_channel_release_all_cb(data);
++}
++
+ static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
+ 	.open		= stm32_adfsdm_pcm_open,
+ 	.close		= stm32_adfsdm_pcm_close,
+@@ -350,6 +355,12 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
+ 	if (IS_ERR(priv->iio_cb))
+ 		return PTR_ERR(priv->iio_cb);
+ 
++	ret = devm_add_action_or_reset(&pdev->dev, stm32_adfsdm_cleanup, priv->iio_cb);
++	if (ret < 0)  {
++		dev_err(&pdev->dev, "Unable to add action\n");
++		return ret;
++	}
++
+ 	component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
+ 	if (!component)
+ 		return -ENOMEM;
+diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
+index 2420dc994632a..4c9ea13f72d48 100644
+--- a/sound/usb/endpoint.c
++++ b/sound/usb/endpoint.c
+@@ -923,7 +923,8 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
+ 	usb_audio_dbg(chip, "Closing EP 0x%x (count %d)\n",
+ 		      ep->ep_num, ep->opened);
+ 
+-	if (!--ep->iface_ref->opened)
++	if (!--ep->iface_ref->opened &&
++		!(chip->quirk_flags & QUIRK_FLAG_IFACE_SKIP_CLOSE))
+ 		endpoint_set_interface(chip, ep, false);
+ 
+ 	if (!--ep->opened) {
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 250bda7cda075..4f914dce6bbf9 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2186,6 +2186,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+ 	DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
+ 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
++	DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
++		   QUIRK_FLAG_IFACE_SKIP_CLOSE),
+ 
+ 	/* Vendor matches */
+ 	VENDOR_FLG(0x045e, /* MS Lifecam */
+diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
+index 2c6575029b1cd..e97141ef730ad 100644
+--- a/sound/usb/usbaudio.h
++++ b/sound/usb/usbaudio.h
+@@ -170,6 +170,8 @@ extern bool snd_usb_skip_validation;
+  *  Apply the generic implicit feedback sync mode (same as implicit_fb=1 option)
+  * QUIRK_FLAG_SKIP_IMPLICIT_FB
+  *  Don't apply implicit feedback sync mode
++ * QUIRK_FLAG_IFACE_SKIP_CLOSE
++ *  Don't closed interface during setting sample rate
+  */
+ 
+ #define QUIRK_FLAG_GET_SAMPLE_RATE	(1U << 0)
+@@ -191,5 +193,6 @@ extern bool snd_usb_skip_validation;
+ #define QUIRK_FLAG_SET_IFACE_FIRST	(1U << 16)
+ #define QUIRK_FLAG_GENERIC_IMPLICIT_FB	(1U << 17)
+ #define QUIRK_FLAG_SKIP_IMPLICIT_FB	(1U << 18)
++#define QUIRK_FLAG_IFACE_SKIP_CLOSE	(1U << 19)
+ 
+ #endif /* __USBAUDIO_H */
+diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c
+index 2491c54a5e4fb..f8deae4e26a15 100644
+--- a/tools/iio/iio_generic_buffer.c
++++ b/tools/iio/iio_generic_buffer.c
+@@ -715,12 +715,12 @@ int main(int argc, char **argv)
+ 				continue;
+ 			}
+ 
+-			toread = buf_len;
+ 		} else {
+ 			usleep(timedelay);
+-			toread = 64;
+ 		}
+ 
++		toread = buf_len;
++
+ 		read_size = read(buf_fd, data, toread * scan_size);
+ 		if (read_size < 0) {
+ 			if (errno == EAGAIN) {
+diff --git a/tools/testing/selftests/bpf/verifier/ref_tracking.c b/tools/testing/selftests/bpf/verifier/ref_tracking.c
+index 57a83d763ec17..6dc65b2501ed2 100644
+--- a/tools/testing/selftests/bpf/verifier/ref_tracking.c
++++ b/tools/testing/selftests/bpf/verifier/ref_tracking.c
+@@ -905,3 +905,39 @@
+ 	.result_unpriv = REJECT,
+ 	.errstr_unpriv = "unknown func",
+ },
++{
++	"reference tracking: try to leak released ptr reg",
++	.insns = {
++		BPF_MOV64_IMM(BPF_REG_0, 0),
++		BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4),
++		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
++		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
++		BPF_LD_MAP_FD(BPF_REG_1, 0),
++		BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
++		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
++		BPF_EXIT_INSN(),
++		BPF_MOV64_REG(BPF_REG_9, BPF_REG_0),
++
++		BPF_MOV64_IMM(BPF_REG_0, 0),
++		BPF_LD_MAP_FD(BPF_REG_1, 0),
++		BPF_MOV64_IMM(BPF_REG_2, 8),
++		BPF_MOV64_IMM(BPF_REG_3, 0),
++		BPF_EMIT_CALL(BPF_FUNC_ringbuf_reserve),
++		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
++		BPF_EXIT_INSN(),
++		BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
++
++		BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
++		BPF_MOV64_IMM(BPF_REG_2, 0),
++		BPF_EMIT_CALL(BPF_FUNC_ringbuf_discard),
++		BPF_MOV64_IMM(BPF_REG_0, 0),
++
++		BPF_STX_MEM(BPF_DW, BPF_REG_9, BPF_REG_8, 0),
++		BPF_EXIT_INSN()
++	},
++	.fixup_map_array_48b = { 4 },
++	.fixup_map_ringbuf = { 11 },
++	.result = ACCEPT,
++	.result_unpriv = REJECT,
++	.errstr_unpriv = "R8 !read_ok"
++},
+diff --git a/tools/testing/selftests/net/io_uring_zerocopy_tx.sh b/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
+index 32aa6e9dacc26..9ac4456d48fcc 100755
+--- a/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
++++ b/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
+@@ -29,7 +29,7 @@ if [[ "$#" -eq "0" ]]; then
+ 	for IP in "${IPs[@]}"; do
+ 		for mode in $(seq 1 3); do
+ 			$0 "$IP" udp -m "$mode" -t 1 -n 32
+-			$0 "$IP" tcp -m "$mode" -t 1 -n 32
++			$0 "$IP" tcp -m "$mode" -t 1 -n 1
+ 		done
+ 	done
+ 
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+index ff83ef426df52..e52b794401239 100755
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -2105,7 +2105,7 @@ remove_tests()
+ 		pm_nl_set_limits $ns2 1 3
+ 		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
+ 		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
+-		run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 slow
++		run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 speed_10
+ 		chk_join_nr 3 3 3
+ 		chk_add_nr 1 1
+ 		chk_rm_nr 2 2
+@@ -2118,7 +2118,7 @@ remove_tests()
+ 		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
+ 		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
+ 		pm_nl_set_limits $ns2 3 3
+-		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
++		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10
+ 		chk_join_nr 3 3 3
+ 		chk_add_nr 3 3
+ 		chk_rm_nr 3 3 invert
+@@ -2131,7 +2131,7 @@ remove_tests()
+ 		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
+ 		pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
+ 		pm_nl_set_limits $ns2 3 3
+-		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
++		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10
+ 		chk_join_nr 1 1 1
+ 		chk_add_nr 3 3
+ 		chk_rm_nr 3 1 invert
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+index 0879da915014f..80d36f7cfee8a 100755
+--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+@@ -35,8 +35,9 @@ init()
+ 
+ 	ns1="ns1-$rndh"
+ 	ns2="ns2-$rndh"
++	ns_sbox="ns_sbox-$rndh"
+ 
+-	for netns in "$ns1" "$ns2";do
++	for netns in "$ns1" "$ns2" "$ns_sbox";do
+ 		ip netns add $netns || exit $ksft_skip
+ 		ip -net $netns link set lo up
+ 		ip netns exec $netns sysctl -q net.mptcp.enabled=1
+@@ -73,7 +74,7 @@ init()
+ 
+ cleanup()
+ {
+-	for netns in "$ns1" "$ns2"; do
++	for netns in "$ns1" "$ns2" "$ns_sbox"; do
+ 		ip netns del $netns
+ 	done
+ 	rm -f "$cin" "$cout"
+@@ -243,7 +244,7 @@ do_mptcp_sockopt_tests()
+ {
+ 	local lret=0
+ 
+-	./mptcp_sockopt
++	ip netns exec "$ns_sbox" ./mptcp_sockopt
+ 	lret=$?
+ 
+ 	if [ $lret -ne 0 ]; then
+@@ -252,7 +253,7 @@ do_mptcp_sockopt_tests()
+ 		return
+ 	fi
+ 
+-	./mptcp_sockopt -6
++	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
+ 	lret=$?
+ 
+ 	if [ $lret -ne 0 ]; then
+diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
+index ffa13a957a363..40aeb5a71a2a6 100755
+--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
++++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
+@@ -247,9 +247,10 @@ run_test()
+ 	tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1
+ 	tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2
+ 
+-	# time is measured in ms, account for transfer size, affegated link speed
++	# time is measured in ms, account for transfer size, aggregated link speed
+ 	# and header overhead (10%)
+-	local time=$((size * 8 * 1000 * 10 / (( $rate1 + $rate2) * 1024 *1024 * 9) ))
++	#              ms    byte -> bit   10%        mbit      -> kbit -> bit  10%
++	local time=$((1000 * size  *  8  * 10 / ((rate1 + rate2) * 1000 * 1000 * 9) ))
+ 
+ 	# mptcp_connect will do some sleeps to allow the mp_join handshake
+ 	# completion (see mptcp_connect): 200ms on each side, add some slack
+diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh
+index ebbd0b2824327..6a443ca3cd3a4 100755
+--- a/tools/testing/selftests/net/udpgro.sh
++++ b/tools/testing/selftests/net/udpgro.sh
+@@ -50,7 +50,7 @@ run_one() {
+ 		echo "failed" &
+ 
+ 	# Hack: let bg programs complete the startup
+-	sleep 0.1
++	sleep 0.2
+ 	./udpgso_bench_tx ${tx_args}
+ 	ret=$?
+ 	wait $(jobs -p)
+@@ -117,7 +117,7 @@ run_one_2sock() {
+ 		echo "failed" &
+ 
+ 	# Hack: let bg programs complete the startup
+-	sleep 0.1
++	sleep 0.2
+ 	./udpgso_bench_tx ${tx_args} -p 12345
+ 	sleep 0.1
+ 	# first UDP GSO socket should be closed at this point
+diff --git a/tools/testing/selftests/net/udpgro_bench.sh b/tools/testing/selftests/net/udpgro_bench.sh
+index fad2d1a71cac3..8a1109a545dba 100755
+--- a/tools/testing/selftests/net/udpgro_bench.sh
++++ b/tools/testing/selftests/net/udpgro_bench.sh
+@@ -39,7 +39,7 @@ run_one() {
+ 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -t ${rx_args} -r &
+ 
+ 	# Hack: let bg programs complete the startup
+-	sleep 0.1
++	sleep 0.2
+ 	./udpgso_bench_tx ${tx_args}
+ }
+ 
+diff --git a/tools/testing/selftests/net/udpgro_frglist.sh b/tools/testing/selftests/net/udpgro_frglist.sh
+index 832c738cc3c29..7fe85ba51075d 100755
+--- a/tools/testing/selftests/net/udpgro_frglist.sh
++++ b/tools/testing/selftests/net/udpgro_frglist.sh
+@@ -44,7 +44,7 @@ run_one() {
+ 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r &
+ 
+ 	# Hack: let bg programs complete the startup
+-	sleep 0.1
++	sleep 0.2
+ 	./udpgso_bench_tx ${tx_args}
+ }
+ 
+diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
+index 346e47f155724..7c248193ca26e 100644
+--- a/virt/kvm/pfncache.c
++++ b/virt/kvm/pfncache.c
+@@ -297,7 +297,12 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ 	if (!gpc->valid || old_uhva != gpc->uhva) {
+ 		ret = hva_to_pfn_retry(kvm, gpc);
+ 	} else {
+-		/* If the HVA→PFN mapping was already valid, don't unmap it. */
++		/*
++		 * If the HVA→PFN mapping was already valid, don't unmap it.
++		 * But do update gpc->khva because the offset within the page
++		 * may have changed.
++		 */
++		gpc->khva = old_khva + page_offset;
+ 		old_pfn = KVM_PFN_ERR_FAULT;
+ 		old_khva = NULL;
+ 		ret = 0;


             reply	other threads:[~2022-12-02 17:23 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-02 17:23 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2023-01-12 12:17 [gentoo-commits] proj/linux-patches:6.0 commit in: / Mike Pagano
2023-01-07 11:11 Mike Pagano
2023-01-04 11:38 Mike Pagano
2022-12-31 15:29 Mike Pagano
2022-12-21 18:50 Alice Ferrazzi
2022-12-19 12:23 Alice Ferrazzi
2022-12-16 19:56 Mike Pagano
2022-12-14 12:51 Mike Pagano
2022-12-14 12:13 Mike Pagano
2022-12-08 11:40 Alice Ferrazzi
2022-12-06 13:46 Mike Pagano
2022-12-06 13:00 Mike Pagano
2022-11-26 11:55 Mike Pagano
2022-11-16 11:16 Alice Ferrazzi
2022-11-10 18:18 Mike Pagano
2022-11-10 18:10 Mike Pagano
2022-11-09 19:00 Mike Pagano
2022-11-03 15:27 Mike Pagano
2022-11-01 12:46 Mike Pagano
2022-10-29  9:54 Mike Pagano
2022-10-26 11:24 Mike Pagano
2022-10-21 13:14 Mike Pagano
2022-10-15 10:03 Mike Pagano
2022-10-12 11:16 Mike Pagano
2022-10-03  9:31 Mike Pagano
2022-09-11 22:30 Mike Pagano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1670001814.6bdec7c135eddb0a34e89f2eac3ef9628666542b.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox