diff options
author | 2024-07-05 06:50:06 -0400 | |
---|---|---|
committer | 2024-07-05 06:50:06 -0400 | |
commit | 19cfcaba22fb1f591fb62dd42ed8578d9e786930 (patch) | |
tree | 89c352d89cd6d71768295e3fbd0ab917099301a1 | |
parent | Linux patch 5.15.161 (diff) | |
download | linux-patches-19cfcaba22fb1f591fb62dd42ed8578d9e786930.tar.gz linux-patches-19cfcaba22fb1f591fb62dd42ed8578d9e786930.tar.bz2 linux-patches-19cfcaba22fb1f591fb62dd42ed8578d9e786930.zip |
Linuxpatch 5.15.162
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1161_linux-5.15.162.patch | 14622 |
2 files changed, 14626 insertions, 0 deletions
diff --git a/0000_README b/0000_README index cec781fe..79021360 100644 --- a/0000_README +++ b/0000_README @@ -687,6 +687,10 @@ Patch: 1160_linux-5.15.161.patch From: https://www.kernel.org Desc: Linux 5.15.161 +Patch: 1161_linux-5.15.162.patch +From: https://www.kernel.org +Desc: Linux 5.15.162 + 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/1161_linux-5.15.162.patch b/1161_linux-5.15.162.patch new file mode 100644 index 00000000..35402e0b --- /dev/null +++ b/1161_linux-5.15.162.patch @@ -0,0 +1,14622 @@ +diff --git a/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml b/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml +index b386e4128a791..d3e01d8c043cd 100644 +--- a/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml ++++ b/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml +@@ -22,7 +22,7 @@ description: | + google,cros-ec-spi or google,cros-ec-i2c. + + allOf: +- - $ref: i2c-controller.yaml# ++ - $ref: /schemas/i2c/i2c-controller.yaml# + + properties: + compatible: +diff --git a/Makefile b/Makefile +index 730bbf583015d..790f63b2c80d0 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 15 +-SUBLEVEL = 161 ++SUBLEVEL = 162 + EXTRAVERSION = + NAME = Trick or Treat + +@@ -959,7 +959,6 @@ endif + ifdef CONFIG_LTO_CLANG + ifdef CONFIG_LTO_CLANG_THIN + CC_FLAGS_LTO := -flto=thin -fsplit-lto-unit +-KBUILD_LDFLAGS += --thinlto-cache-dir=$(extmod_prefix).thinlto-cache + else + CC_FLAGS_LTO := -flto + endif +@@ -1560,7 +1559,7 @@ endif # CONFIG_MODULES + # Directories & files removed with 'make clean' + CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \ + modules.builtin modules.builtin.modinfo modules.nsdeps \ +- compile_commands.json .thinlto-cache ++ compile_commands.json + + # Directories & files removed with 'make mrproper' + MRPROPER_FILES += include/config include/generated \ +@@ -1788,7 +1787,7 @@ PHONY += compile_commands.json + + clean-dirs := $(KBUILD_EXTMOD) + clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \ +- $(KBUILD_EXTMOD)/compile_commands.json $(KBUILD_EXTMOD)/.thinlto-cache ++ $(KBUILD_EXTMOD)/compile_commands.json + + PHONY += prepare + # now expand this into a simple variable to reduce the cost of shell evaluations +diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts +index d5797a67bf48d..4cf6ee4a813fc 100644 +--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts ++++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts +@@ -84,7 +84,7 @@ eeprom@52 { + &keypad { + samsung,keypad-num-rows = <2>; + samsung,keypad-num-columns = <8>; +- linux,keypad-no-autorepeat; ++ linux,input-no-autorepeat; + wakeup-source; + pinctrl-names = "default"; + pinctrl-0 = <&keypad_rows &keypad_cols>; +diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts +index 0acb05f0a2b7c..68ed31821a282 100644 +--- a/arch/arm/boot/dts/exynos4412-origen.dts ++++ b/arch/arm/boot/dts/exynos4412-origen.dts +@@ -448,7 +448,7 @@ buck9_reg: BUCK9 { + &keypad { + samsung,keypad-num-rows = <3>; + samsung,keypad-num-columns = <2>; +- linux,keypad-no-autorepeat; ++ linux,input-no-autorepeat; + wakeup-source; + pinctrl-0 = <&keypad_rows &keypad_cols>; + pinctrl-names = "default"; +diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts +index cc99b955af0c8..deebed6ea0031 100644 +--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts ++++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts +@@ -65,7 +65,7 @@ cooling_map1: map1 { + &keypad { + samsung,keypad-num-rows = <3>; + samsung,keypad-num-columns = <8>; +- linux,keypad-no-autorepeat; ++ linux,input-no-autorepeat; + wakeup-source; + pinctrl-0 = <&keypad_rows &keypad_cols>; + pinctrl-names = "default"; +diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi +index ae4055428c5e1..85b5c506662eb 100644 +--- a/arch/arm/boot/dts/rk3066a.dtsi ++++ b/arch/arm/boot/dts/rk3066a.dtsi +@@ -124,6 +124,7 @@ hdmi: hdmi@10116000 { + pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>; + power-domains = <&power RK3066_PD_VIO>; + rockchip,grf = <&grf>; ++ #sound-dai-cells = <0>; + status = "disabled"; + + ports { +diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts +index 607cd6b4e9721..470e4e4aa8c78 100644 +--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts ++++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts +@@ -32,7 +32,7 @@ reg_usdhc2_vmmc: usdhc2-vmmc { + regulator-name = "SD1_SPWR"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; +- gpio = <&lsio_gpio4 19 GPIO_ACTIVE_HIGH>; ++ gpio = <&lsio_gpio4 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts +index 018a3a5075c72..d9905a08c6ce8 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts +@@ -186,8 +186,8 @@ &i2c1 { + rk805: pmic@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; +- interrupt-parent = <&gpio2>; +- interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + gpio-controller; +diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi +index 4c64fbefb4834..ad58930d5ccec 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi +@@ -678,6 +678,7 @@ spdif: spdif@ff880000 { + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx>; ++ #sound-dai-cells = <0>; + status = "disabled"; + }; + +@@ -689,6 +690,7 @@ i2s_2ch: i2s-2ch@ff890000 { + clocks = <&cru SCLK_I2S_2CH>, <&cru HCLK_I2S_2CH>; + dmas = <&dmac_bus 6>, <&dmac_bus 7>; + dma-names = "tx", "rx"; ++ #sound-dai-cells = <0>; + status = "disabled"; + }; + +@@ -702,6 +704,7 @@ i2s_8ch: i2s-8ch@ff898000 { + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s_8ch_bus>; ++ #sound-dai-cells = <0>; + status = "disabled"; + }; + +diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h +index 1713630bf8f5a..91038fa2e5e09 100644 +--- a/arch/arm64/include/asm/kvm_host.h ++++ b/arch/arm64/include/asm/kvm_host.h +@@ -419,6 +419,7 @@ struct kvm_vcpu_arch { + #define KVM_ARM64_EXCEPT_MASK (7 << 9) /* Target EL/MODE */ + #define KVM_ARM64_DEBUG_STATE_SAVE_SPE (1 << 12) /* Save SPE context if active */ + #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE (1 << 13) /* Save TRBE context if active */ ++#define KVM_ARM64_VCPU_IN_WFI (1 << 14) /* WFI instruction trapped */ + + #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \ + KVM_GUESTDBG_USE_SW_BP | \ +diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h +index 844f6ae586625..f4fb040a431cd 100644 +--- a/arch/arm64/include/asm/unistd32.h ++++ b/arch/arm64/include/asm/unistd32.h +@@ -840,7 +840,7 @@ __SYSCALL(__NR_pselect6_time64, compat_sys_pselect6_time64) + #define __NR_ppoll_time64 414 + __SYSCALL(__NR_ppoll_time64, compat_sys_ppoll_time64) + #define __NR_io_pgetevents_time64 416 +-__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents) ++__SYSCALL(__NR_io_pgetevents_time64, compat_sys_io_pgetevents_time64) + #define __NR_recvmmsg_time64 417 + __SYSCALL(__NR_recvmmsg_time64, compat_sys_recvmmsg_time64) + #define __NR_mq_timedsend_time64 418 +diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c +index 47d737672abaf..9ded5443de487 100644 +--- a/arch/arm64/kvm/arm.c ++++ b/arch/arm64/kvm/arm.c +@@ -379,13 +379,15 @@ void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) + */ + preempt_disable(); + kvm_vgic_vmcr_sync(vcpu); +- vgic_v4_put(vcpu, true); ++ vcpu->arch.flags |= KVM_ARM64_VCPU_IN_WFI; ++ vgic_v4_put(vcpu); + preempt_enable(); + } + + void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) + { + preempt_disable(); ++ vcpu->arch.flags &= ~KVM_ARM64_VCPU_IN_WFI; + vgic_v4_load(vcpu); + preempt_enable(); + } +@@ -696,7 +698,7 @@ static void check_vcpu_requests(struct kvm_vcpu *vcpu) + if (kvm_check_request(KVM_REQ_RELOAD_GICv4, vcpu)) { + /* The distributor enable bits were changed */ + preempt_disable(); +- vgic_v4_put(vcpu, false); ++ vgic_v4_put(vcpu); + vgic_v4_load(vcpu); + preempt_enable(); + } +diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c +index 8eb70451323b6..fcd5bb242bcff 100644 +--- a/arch/arm64/kvm/vgic/vgic-v3.c ++++ b/arch/arm64/kvm/vgic/vgic-v3.c +@@ -715,7 +715,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu) + { + struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; + +- WARN_ON(vgic_v4_put(vcpu, false)); ++ WARN_ON(vgic_v4_put(vcpu)); + + vgic_v3_vmcr_sync(vcpu); + +diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c +index f507e3fcffce3..2cf4a60b6e1dd 100644 +--- a/arch/arm64/kvm/vgic/vgic-v4.c ++++ b/arch/arm64/kvm/vgic/vgic-v4.c +@@ -333,14 +333,15 @@ void vgic_v4_teardown(struct kvm *kvm) + its_vm->vpes = NULL; + } + +-int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db) ++int vgic_v4_put(struct kvm_vcpu *vcpu) + { + struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; + + if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident) + return 0; + +- return its_make_vpe_non_resident(vpe, need_db); ++ return its_make_vpe_non_resident(vpe, ++ vcpu->arch.flags & KVM_ARM64_VCPU_IN_WFI); + } + + int vgic_v4_load(struct kvm_vcpu *vcpu) +@@ -351,6 +352,9 @@ int vgic_v4_load(struct kvm_vcpu *vcpu) + if (!vgic_supports_direct_msis(vcpu->kvm) || vpe->resident) + return 0; + ++ if (vcpu->arch.flags & KVM_ARM64_VCPU_IN_WFI) ++ return 0; ++ + /* + * Before making the VPE resident, make sure the redistributor + * corresponding to our current CPU expects us here. See the +diff --git a/arch/csky/include/uapi/asm/unistd.h b/arch/csky/include/uapi/asm/unistd.h +index 7ff6a2466af10..e0594b6370a65 100644 +--- a/arch/csky/include/uapi/asm/unistd.h ++++ b/arch/csky/include/uapi/asm/unistd.h +@@ -6,6 +6,7 @@ + #define __ARCH_WANT_SYS_CLONE3 + #define __ARCH_WANT_SET_GET_RLIMIT + #define __ARCH_WANT_TIME32_SYSCALLS ++#define __ARCH_WANT_SYNC_FILE_RANGE2 + #include <asm-generic/unistd.h> + + #define __NR_set_thread_area (__NR_arch_specific_syscall + 0) +diff --git a/arch/hexagon/include/asm/syscalls.h b/arch/hexagon/include/asm/syscalls.h +new file mode 100644 +index 0000000000000..40f2d08bec92c +--- /dev/null ++++ b/arch/hexagon/include/asm/syscalls.h +@@ -0,0 +1,6 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++#include <asm-generic/syscalls.h> ++ ++asmlinkage long sys_hexagon_fadvise64_64(int fd, int advice, ++ u32 a2, u32 a3, u32 a4, u32 a5); +diff --git a/arch/hexagon/include/uapi/asm/unistd.h b/arch/hexagon/include/uapi/asm/unistd.h +index 432c4db1b6239..21ae22306b5dc 100644 +--- a/arch/hexagon/include/uapi/asm/unistd.h ++++ b/arch/hexagon/include/uapi/asm/unistd.h +@@ -36,5 +36,6 @@ + #define __ARCH_WANT_SYS_VFORK + #define __ARCH_WANT_SYS_FORK + #define __ARCH_WANT_TIME32_SYSCALLS ++#define __ARCH_WANT_SYNC_FILE_RANGE2 + + #include <asm-generic/unistd.h> +diff --git a/arch/hexagon/kernel/syscalltab.c b/arch/hexagon/kernel/syscalltab.c +index 0fadd582cfc77..5d98bdc494ec2 100644 +--- a/arch/hexagon/kernel/syscalltab.c ++++ b/arch/hexagon/kernel/syscalltab.c +@@ -14,6 +14,13 @@ + #undef __SYSCALL + #define __SYSCALL(nr, call) [nr] = (call), + ++SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice, ++ SC_ARG64(offset), SC_ARG64(len)) ++{ ++ return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, len), advice); ++} ++#define sys_fadvise64_64 sys_hexagon_fadvise64_64 ++ + void *sys_call_table[__NR_syscalls] = { + #include <asm/unistd.h> + }; +diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c +index 45c7cf582348e..6e5c2c5070179 100644 +--- a/arch/mips/bmips/setup.c ++++ b/arch/mips/bmips/setup.c +@@ -110,7 +110,8 @@ static void bcm6358_quirks(void) + * RAC flush causes kernel panics on BCM6358 when booting from TP1 + * because the bootloader is not initializing it properly. + */ +- bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)); ++ bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) || ++ !!BMIPS_GET_CBR(); + } + + static void bcm6368_quirks(void) +diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl +index 70e32de2bcaa1..42c07a1b99d90 100644 +--- a/arch/mips/kernel/syscalls/syscall_n32.tbl ++++ b/arch/mips/kernel/syscalls/syscall_n32.tbl +@@ -354,7 +354,7 @@ + 412 n32 utimensat_time64 sys_utimensat + 413 n32 pselect6_time64 compat_sys_pselect6_time64 + 414 n32 ppoll_time64 compat_sys_ppoll_time64 +-416 n32 io_pgetevents_time64 sys_io_pgetevents ++416 n32 io_pgetevents_time64 compat_sys_io_pgetevents_time64 + 417 n32 recvmmsg_time64 compat_sys_recvmmsg_time64 + 418 n32 mq_timedsend_time64 sys_mq_timedsend + 419 n32 mq_timedreceive_time64 sys_mq_timedreceive +diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl +index a61c35edaa74c..ec1119760cd3c 100644 +--- a/arch/mips/kernel/syscalls/syscall_o32.tbl ++++ b/arch/mips/kernel/syscalls/syscall_o32.tbl +@@ -403,7 +403,7 @@ + 412 o32 utimensat_time64 sys_utimensat sys_utimensat + 413 o32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 + 414 o32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 +-416 o32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents ++416 o32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 + 417 o32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 + 418 o32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend + 419 o32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive +diff --git a/arch/mips/pci/ops-rc32434.c b/arch/mips/pci/ops-rc32434.c +index 874ed6df97683..34b9323bdabb0 100644 +--- a/arch/mips/pci/ops-rc32434.c ++++ b/arch/mips/pci/ops-rc32434.c +@@ -112,8 +112,8 @@ static int read_config_dword(struct pci_bus *bus, unsigned int devfn, + * gives them time to settle + */ + if (where == PCI_VENDOR_ID) { +- if (ret == 0xffffffff || ret == 0x00000000 || +- ret == 0x0000ffff || ret == 0xffff0000) { ++ if (*val == 0xffffffff || *val == 0x00000000 || ++ *val == 0x0000ffff || *val == 0xffff0000) { + if (delay > 4) + return 0; + delay *= 2; +diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c +old mode 100644 +new mode 100755 +index d919a0d813a17..38de2a9c3cf1a +--- a/arch/mips/pci/pcie-octeon.c ++++ b/arch/mips/pci/pcie-octeon.c +@@ -230,12 +230,18 @@ static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus, + { + union cvmx_pcie_address pcie_addr; + union cvmx_pciercx_cfg006 pciercx_cfg006; ++ union cvmx_pciercx_cfg032 pciercx_cfg032; + + pciercx_cfg006.u32 = + cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port)); + if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0)) + return 0; + ++ pciercx_cfg032.u32 = ++ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port)); ++ if ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1)) ++ return 0; ++ + pcie_addr.u64 = 0; + pcie_addr.config.upper = 2; + pcie_addr.config.io = 1; +diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig +index 117b0f882750a..6ac0c4b98e281 100644 +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -12,6 +12,7 @@ config PARISC + select ARCH_HAS_STRICT_MODULE_RWX + select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_NO_SG_CHAIN ++ select ARCH_SPLIT_ARG64 if !64BIT + select ARCH_SUPPORTS_HUGETLBFS if PA20 + select ARCH_SUPPORTS_MEMORY_FAILURE + select DMA_OPS +diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c +index 2a12a547b447b..826c8e51b5853 100644 +--- a/arch/parisc/kernel/sys_parisc32.c ++++ b/arch/parisc/kernel/sys_parisc32.c +@@ -23,12 +23,3 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23, + current->comm, current->pid, r20); + return -ENOSYS; + } +- +-asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t flags, +- compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd, +- const char __user * pathname) +-{ +- return sys_fanotify_mark(fanotify_fd, flags, +- ((__u64)mask1 << 32) | mask0, +- dfd, pathname); +-} +diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl +index 50c759f11c25d..5774509ea4a3b 100644 +--- a/arch/parisc/kernel/syscalls/syscall.tbl ++++ b/arch/parisc/kernel/syscalls/syscall.tbl +@@ -108,7 +108,7 @@ + 95 common fchown sys_fchown + 96 common getpriority sys_getpriority + 97 common setpriority sys_setpriority +-98 common recv sys_recv ++98 common recv sys_recv compat_sys_recv + 99 common statfs sys_statfs compat_sys_statfs + 100 common fstatfs sys_fstatfs compat_sys_fstatfs + 101 common stat64 sys_stat64 +@@ -135,7 +135,7 @@ + 120 common clone sys_clone_wrapper + 121 common setdomainname sys_setdomainname + 122 common sendfile sys_sendfile compat_sys_sendfile +-123 common recvfrom sys_recvfrom ++123 common recvfrom sys_recvfrom compat_sys_recvfrom + 124 32 adjtimex sys_adjtimex_time32 + 124 64 adjtimex sys_adjtimex + 125 common mprotect sys_mprotect +@@ -364,7 +364,7 @@ + 320 common accept4 sys_accept4 + 321 common prlimit64 sys_prlimit64 + 322 common fanotify_init sys_fanotify_init +-323 common fanotify_mark sys_fanotify_mark sys32_fanotify_mark ++323 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark + 324 32 clock_adjtime sys_clock_adjtime32 + 324 64 clock_adjtime sys_clock_adjtime + 325 common name_to_handle_at sys_name_to_handle_at +diff --git a/arch/powerpc/include/asm/fadump-internal.h b/arch/powerpc/include/asm/fadump-internal.h +index 8d61c8f3fec47..d06b2be645326 100644 +--- a/arch/powerpc/include/asm/fadump-internal.h ++++ b/arch/powerpc/include/asm/fadump-internal.h +@@ -19,11 +19,6 @@ + + #define memblock_num_regions(memblock_type) (memblock.memblock_type.cnt) + +-/* Alignment per CMA requirement. */ +-#define FADUMP_CMA_ALIGNMENT (PAGE_SIZE << \ +- max_t(unsigned long, MAX_ORDER - 1, \ +- pageblock_order)) +- + /* FAD commands */ + #define FADUMP_REGISTER 1 + #define FADUMP_UNREGISTER 2 +diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h +index c25f160bb9978..47cec207e5571 100644 +--- a/arch/powerpc/include/asm/hvcall.h ++++ b/arch/powerpc/include/asm/hvcall.h +@@ -472,7 +472,7 @@ long plpar_hcall_norets_notrace(unsigned long opcode, ...); + * Used for all but the craziest of phyp interfaces (see plpar_hcall9) + */ + #define PLPAR_HCALL_BUFSIZE 4 +-long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...); ++long plpar_hcall(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...); + + /** + * plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats +@@ -486,7 +486,7 @@ long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...); + * plpar_hcall, but plpar_hcall_raw works in real mode and does not + * calculate hypervisor call statistics. + */ +-long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); ++long plpar_hcall_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...); + + /** + * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments +@@ -497,8 +497,8 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); + * PLPAR_HCALL9_BUFSIZE to size the return argument buffer. + */ + #define PLPAR_HCALL9_BUFSIZE 9 +-long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); +-long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...); ++long plpar_hcall9(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...); ++long plpar_hcall9_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...); + + struct hvcall_mpp_data { + unsigned long entitled_mem; +diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h +index a4fe1292909e6..56eb8ac443930 100644 +--- a/arch/powerpc/include/asm/io.h ++++ b/arch/powerpc/include/asm/io.h +@@ -556,12 +556,12 @@ __do_out_asm(_rec_outl, "stwbrx") + #define __do_inw(port) _rec_inw(port) + #define __do_inl(port) _rec_inl(port) + #else /* CONFIG_PPC32 */ +-#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)_IO_BASE+port); +-#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)_IO_BASE+port); +-#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)_IO_BASE+port); +-#define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port); +-#define __do_inw(port) readw((PCI_IO_ADDR)_IO_BASE + port); +-#define __do_inl(port) readl((PCI_IO_ADDR)_IO_BASE + port); ++#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)(_IO_BASE+port)); ++#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)(_IO_BASE+port)); ++#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)(_IO_BASE+port)); ++#define __do_inb(port) readb((PCI_IO_ADDR)(_IO_BASE + port)); ++#define __do_inw(port) readw((PCI_IO_ADDR)(_IO_BASE + port)); ++#define __do_inl(port) readl((PCI_IO_ADDR)(_IO_BASE + port)); + #endif /* !CONFIG_PPC32 */ + + #ifdef CONFIG_EEH +@@ -577,12 +577,12 @@ __do_out_asm(_rec_outl, "stwbrx") + #define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n)) + #define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n)) + +-#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) +-#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) +-#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) +-#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) +-#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) +-#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) ++#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) ++#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) ++#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) ++#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) ++#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) ++#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) + + #define __do_memset_io(addr, c, n) \ + _memset_io(PCI_FIX_ADDR(addr), c, n) +diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h +index b2680070d65d6..6013a7fc74ba7 100644 +--- a/arch/powerpc/include/asm/uaccess.h ++++ b/arch/powerpc/include/asm/uaccess.h +@@ -90,9 +90,20 @@ __pu_failed: \ + : \ + : label) + ++#ifdef CONFIG_CC_IS_CLANG ++#define DS_FORM_CONSTRAINT "Z<>" ++#else ++#define DS_FORM_CONSTRAINT "YZ<>" ++#endif ++ + #ifdef __powerpc64__ +-#define __put_user_asm2_goto(x, ptr, label) \ +- __put_user_asm_goto(x, ptr, label, "std") ++#define __put_user_asm2_goto(x, addr, label) \ ++ asm goto ("1: std%U1%X1 %0,%1 # put_user\n" \ ++ EX_TABLE(1b, %l2) \ ++ : \ ++ : "r" (x), DS_FORM_CONSTRAINT (*addr) \ ++ : \ ++ : label) + #else /* __powerpc64__ */ + #define __put_user_asm2_goto(x, addr, label) \ + asm_volatile_goto( \ +diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c +index d496dc5151aa1..35b142ad0e40e 100644 +--- a/arch/powerpc/kernel/fadump.c ++++ b/arch/powerpc/kernel/fadump.c +@@ -544,7 +544,7 @@ int __init fadump_reserve_mem(void) + if (!fw_dump.nocma) { + fw_dump.boot_memory_size = + ALIGN(fw_dump.boot_memory_size, +- FADUMP_CMA_ALIGNMENT); ++ CMA_MIN_ALIGNMENT_BYTES); + } + #endif + +diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl +index 7bef917cc84e6..b24711e7f9b3a 100644 +--- a/arch/powerpc/kernel/syscalls/syscall.tbl ++++ b/arch/powerpc/kernel/syscalls/syscall.tbl +@@ -495,7 +495,7 @@ + 412 32 utimensat_time64 sys_utimensat sys_utimensat + 413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 + 414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 +-416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents ++416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 + 417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 + 418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend + 419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive +diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c +index d7115acab3501..c30cc3ac93a72 100644 +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -105,10 +105,9 @@ static void __init print_vm_layout(void) + #endif + print_mlm("lowmem", (unsigned long)PAGE_OFFSET, + (unsigned long)high_memory); +-#ifdef CONFIG_64BIT +- print_mlm("kernel", (unsigned long)KERNEL_LINK_ADDR, +- (unsigned long)ADDRESS_SPACE_END); +-#endif ++ if (IS_ENABLED(CONFIG_64BIT)) ++ print_mlm("kernel", (unsigned long)KERNEL_LINK_ADDR, ++ (unsigned long)ADDRESS_SPACE_END); + } + #else + static void print_vm_layout(void) { } +@@ -166,7 +165,7 @@ static void __init setup_bootmem(void) + { + phys_addr_t vmlinux_end = __pa_symbol(&_end); + phys_addr_t vmlinux_start = __pa_symbol(&_start); +- phys_addr_t __maybe_unused max_mapped_addr; ++ phys_addr_t max_mapped_addr; + phys_addr_t phys_ram_end; + + #ifdef CONFIG_XIP_KERNEL +@@ -175,17 +174,16 @@ static void __init setup_bootmem(void) + + memblock_enforce_memory_limit(memory_limit); + +- /* +- * Reserve from the start of the kernel to the end of the kernel +- */ +-#if defined(CONFIG_64BIT) && defined(CONFIG_STRICT_KERNEL_RWX) + /* + * Make sure we align the reservation on PMD_SIZE since we will + * map the kernel in the linear mapping as read-only: we do not want + * any allocation to happen between _end and the next pmd aligned page. + */ +- vmlinux_end = (vmlinux_end + PMD_SIZE - 1) & PMD_MASK; +-#endif ++ if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) ++ vmlinux_end = (vmlinux_end + PMD_SIZE - 1) & PMD_MASK; ++ /* ++ * Reserve from the start of the kernel to the end of the kernel ++ */ + memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); + + +@@ -193,20 +191,21 @@ static void __init setup_bootmem(void) + #ifndef CONFIG_XIP_KERNEL + phys_ram_base = memblock_start_of_DRAM(); + #endif +-#ifndef CONFIG_64BIT + /* +- * memblock allocator is not aware of the fact that last 4K bytes of +- * the addressable memory can not be mapped because of IS_ERR_VALUE +- * macro. Make sure that last 4k bytes are not usable by memblock +- * if end of dram is equal to maximum addressable memory. For 64-bit +- * kernel, this problem can't happen here as the end of the virtual +- * address space is occupied by the kernel mapping then this check must +- * be done as soon as the kernel mapping base address is determined. ++ * Reserve physical address space that would be mapped to virtual ++ * addresses greater than (void *)(-PAGE_SIZE) because: ++ * - This memory would overlap with ERR_PTR ++ * - This memory belongs to high memory, which is not supported ++ * ++ * This is not applicable to 64-bit kernel, because virtual addresses ++ * after (void *)(-PAGE_SIZE) are not linearly mapped: they are ++ * occupied by kernel mapping. Also it is unrealistic for high memory ++ * to exist on 64-bit platforms. + */ +- max_mapped_addr = __pa(~(ulong)0); +- if (max_mapped_addr == (phys_ram_end - 1)) +- memblock_set_current_limit(max_mapped_addr - 4096); +-#endif ++ if (!IS_ENABLED(CONFIG_64BIT)) { ++ max_mapped_addr = __va_to_pa_nodebug(-PAGE_SIZE); ++ memblock_reserve(max_mapped_addr, (phys_addr_t)-max_mapped_addr); ++ } + + min_low_pfn = PFN_UP(phys_ram_base); + max_low_pfn = max_pfn = PFN_DOWN(phys_ram_end); +@@ -630,14 +629,6 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) + BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0); + BUG_ON((kernel_map.phys_addr % PMD_SIZE) != 0); + +-#ifdef CONFIG_64BIT +- /* +- * The last 4K bytes of the addressable memory can not be mapped because +- * of IS_ERR_VALUE macro. +- */ +- BUG_ON((kernel_map.virt_addr + kernel_map.size) > ADDRESS_SPACE_END - SZ_4K); +-#endif +- + pt_ops.alloc_pte = alloc_pte_early; + pt_ops.get_pte_virt = get_pte_virt_early; + #ifndef __PAGETABLE_PMD_FOLDED +@@ -760,10 +751,9 @@ static void __init setup_vm_final(void) + } + } + +-#ifdef CONFIG_64BIT + /* Map the kernel */ +- create_kernel_page_table(swapper_pg_dir, false); +-#endif ++ if (IS_ENABLED(CONFIG_64BIT)) ++ create_kernel_page_table(swapper_pg_dir, false); + + /* Clear fixmap PTE and PMD mappings */ + clear_fixmap(FIX_PTE); +diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl +index df5261e5cfe1f..970561293edb0 100644 +--- a/arch/s390/kernel/syscalls/syscall.tbl ++++ b/arch/s390/kernel/syscalls/syscall.tbl +@@ -418,7 +418,7 @@ + 412 32 utimensat_time64 - sys_utimensat + 413 32 pselect6_time64 - compat_sys_pselect6_time64 + 414 32 ppoll_time64 - compat_sys_ppoll_time64 +-416 32 io_pgetevents_time64 - sys_io_pgetevents ++416 32 io_pgetevents_time64 - compat_sys_io_pgetevents_time64 + 417 32 recvmmsg_time64 - compat_sys_recvmmsg_time64 + 418 32 mq_timedsend_time64 - sys_mq_timedsend + 419 32 mq_timedreceive_time64 - sys_mq_timedreceive +diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c +index 9dca568509a5e..d6f4afcb0e870 100644 +--- a/arch/sh/kernel/sys_sh32.c ++++ b/arch/sh/kernel/sys_sh32.c +@@ -59,3 +59,14 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, + (u64)len0 << 32 | len1, advice); + #endif + } ++ ++/* ++ * swap the arguments the way that libc wants them instead of ++ * moving flags ahead of the 64-bit nbytes argument ++ */ ++SYSCALL_DEFINE6(sh_sync_file_range6, int, fd, SC_ARG64(offset), ++ SC_ARG64(nbytes), unsigned int, flags) ++{ ++ return ksys_sync_file_range(fd, SC_VAL64(loff_t, offset), ++ SC_VAL64(loff_t, nbytes), flags); ++} +diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl +index 208f131659c5a..938cfe09edba3 100644 +--- a/arch/sh/kernel/syscalls/syscall.tbl ++++ b/arch/sh/kernel/syscalls/syscall.tbl +@@ -321,7 +321,7 @@ + 311 common set_robust_list sys_set_robust_list + 312 common get_robust_list sys_get_robust_list + 313 common splice sys_splice +-314 common sync_file_range sys_sync_file_range ++314 common sync_file_range sys_sh_sync_file_range6 + 315 common tee sys_tee + 316 common vmsplice sys_vmsplice + 317 common move_pages sys_move_pages +@@ -395,6 +395,7 @@ + 385 common pkey_alloc sys_pkey_alloc + 386 common pkey_free sys_pkey_free + 387 common rseq sys_rseq ++388 common sync_file_range2 sys_sync_file_range2 + # room for arch specific syscalls + 393 common semget sys_semget + 394 common semctl sys_semctl +diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S +index a45f0f31fe51a..a3d308f2043e5 100644 +--- a/arch/sparc/kernel/sys32.S ++++ b/arch/sparc/kernel/sys32.S +@@ -18,224 +18,3 @@ sys32_mmap2: + sethi %hi(sys_mmap), %g1 + jmpl %g1 + %lo(sys_mmap), %g0 + sllx %o5, 12, %o5 +- +- .align 32 +- .globl sys32_socketcall +-sys32_socketcall: /* %o0=call, %o1=args */ +- cmp %o0, 1 +- bl,pn %xcc, do_einval +- cmp %o0, 18 +- bg,pn %xcc, do_einval +- sub %o0, 1, %o0 +- sllx %o0, 5, %o0 +- sethi %hi(__socketcall_table_begin), %g2 +- or %g2, %lo(__socketcall_table_begin), %g2 +- jmpl %g2 + %o0, %g0 +- nop +-do_einval: +- retl +- mov -EINVAL, %o0 +- +- .align 32 +-__socketcall_table_begin: +- +- /* Each entry is exactly 32 bytes. */ +-do_sys_socket: /* sys_socket(int, int, int) */ +-1: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_socket), %g1 +-2: ldswa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_socket), %g0 +-3: ldswa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */ +-4: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_bind), %g1 +-5: ldswa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_bind), %g0 +-6: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */ +-7: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_connect), %g1 +-8: ldswa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_connect), %g0 +-9: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_listen: /* sys_listen(int, int) */ +-10: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_listen), %g1 +- jmpl %g1 + %lo(sys_listen), %g0 +-11: ldswa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +- nop +-do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */ +-12: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_accept), %g1 +-13: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_accept), %g0 +-14: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */ +-15: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_getsockname), %g1 +-16: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_getsockname), %g0 +-17: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */ +-18: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_getpeername), %g1 +-19: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_getpeername), %g0 +-20: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */ +-21: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_socketpair), %g1 +-22: ldswa [%o1 + 0x8] %asi, %o2 +-23: lduwa [%o1 + 0xc] %asi, %o3 +- jmpl %g1 + %lo(sys_socketpair), %g0 +-24: ldswa [%o1 + 0x4] %asi, %o1 +- nop +- nop +-do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */ +-25: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_send), %g1 +-26: lduwa [%o1 + 0x8] %asi, %o2 +-27: lduwa [%o1 + 0xc] %asi, %o3 +- jmpl %g1 + %lo(sys_send), %g0 +-28: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +-do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */ +-29: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_recv), %g1 +-30: lduwa [%o1 + 0x8] %asi, %o2 +-31: lduwa [%o1 + 0xc] %asi, %o3 +- jmpl %g1 + %lo(sys_recv), %g0 +-32: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +-do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */ +-33: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_sendto), %g1 +-34: lduwa [%o1 + 0x8] %asi, %o2 +-35: lduwa [%o1 + 0xc] %asi, %o3 +-36: lduwa [%o1 + 0x10] %asi, %o4 +-37: ldswa [%o1 + 0x14] %asi, %o5 +- jmpl %g1 + %lo(sys_sendto), %g0 +-38: lduwa [%o1 + 0x4] %asi, %o1 +-do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */ +-39: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_recvfrom), %g1 +-40: lduwa [%o1 + 0x8] %asi, %o2 +-41: lduwa [%o1 + 0xc] %asi, %o3 +-42: lduwa [%o1 + 0x10] %asi, %o4 +-43: lduwa [%o1 + 0x14] %asi, %o5 +- jmpl %g1 + %lo(sys_recvfrom), %g0 +-44: lduwa [%o1 + 0x4] %asi, %o1 +-do_sys_shutdown: /* sys_shutdown(int, int) */ +-45: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_shutdown), %g1 +- jmpl %g1 + %lo(sys_shutdown), %g0 +-46: ldswa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +- nop +-do_sys_setsockopt: /* sys_setsockopt(int, int, int, char *, int) */ +-47: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_setsockopt), %g1 +-48: ldswa [%o1 + 0x8] %asi, %o2 +-49: lduwa [%o1 + 0xc] %asi, %o3 +-50: ldswa [%o1 + 0x10] %asi, %o4 +- jmpl %g1 + %lo(sys_setsockopt), %g0 +-51: ldswa [%o1 + 0x4] %asi, %o1 +- nop +-do_sys_getsockopt: /* sys_getsockopt(int, int, int, u32, u32) */ +-52: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_getsockopt), %g1 +-53: ldswa [%o1 + 0x8] %asi, %o2 +-54: lduwa [%o1 + 0xc] %asi, %o3 +-55: lduwa [%o1 + 0x10] %asi, %o4 +- jmpl %g1 + %lo(sys_getsockopt), %g0 +-56: ldswa [%o1 + 0x4] %asi, %o1 +- nop +-do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */ +-57: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(compat_sys_sendmsg), %g1 +-58: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(compat_sys_sendmsg), %g0 +-59: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */ +-60: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(compat_sys_recvmsg), %g1 +-61: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(compat_sys_recvmsg), %g0 +-62: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */ +-63: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_accept4), %g1 +-64: lduwa [%o1 + 0x8] %asi, %o2 +-65: ldswa [%o1 + 0xc] %asi, %o3 +- jmpl %g1 + %lo(sys_accept4), %g0 +-66: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- +- .section __ex_table,"a" +- .align 4 +- .word 1b, __retl_efault, 2b, __retl_efault +- .word 3b, __retl_efault, 4b, __retl_efault +- .word 5b, __retl_efault, 6b, __retl_efault +- .word 7b, __retl_efault, 8b, __retl_efault +- .word 9b, __retl_efault, 10b, __retl_efault +- .word 11b, __retl_efault, 12b, __retl_efault +- .word 13b, __retl_efault, 14b, __retl_efault +- .word 15b, __retl_efault, 16b, __retl_efault +- .word 17b, __retl_efault, 18b, __retl_efault +- .word 19b, __retl_efault, 20b, __retl_efault +- .word 21b, __retl_efault, 22b, __retl_efault +- .word 23b, __retl_efault, 24b, __retl_efault +- .word 25b, __retl_efault, 26b, __retl_efault +- .word 27b, __retl_efault, 28b, __retl_efault +- .word 29b, __retl_efault, 30b, __retl_efault +- .word 31b, __retl_efault, 32b, __retl_efault +- .word 33b, __retl_efault, 34b, __retl_efault +- .word 35b, __retl_efault, 36b, __retl_efault +- .word 37b, __retl_efault, 38b, __retl_efault +- .word 39b, __retl_efault, 40b, __retl_efault +- .word 41b, __retl_efault, 42b, __retl_efault +- .word 43b, __retl_efault, 44b, __retl_efault +- .word 45b, __retl_efault, 46b, __retl_efault +- .word 47b, __retl_efault, 48b, __retl_efault +- .word 49b, __retl_efault, 50b, __retl_efault +- .word 51b, __retl_efault, 52b, __retl_efault +- .word 53b, __retl_efault, 54b, __retl_efault +- .word 55b, __retl_efault, 56b, __retl_efault +- .word 57b, __retl_efault, 58b, __retl_efault +- .word 59b, __retl_efault, 60b, __retl_efault +- .word 61b, __retl_efault, 62b, __retl_efault +- .word 63b, __retl_efault, 64b, __retl_efault +- .word 65b, __retl_efault, 66b, __retl_efault +- .previous +diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl +index c37764dc764d1..8969be7acdde0 100644 +--- a/arch/sparc/kernel/syscalls/syscall.tbl ++++ b/arch/sparc/kernel/syscalls/syscall.tbl +@@ -117,7 +117,7 @@ + 90 common dup2 sys_dup2 + 91 32 setfsuid32 sys_setfsuid + 92 common fcntl sys_fcntl compat_sys_fcntl +-93 common select sys_select ++93 common select sys_select compat_sys_select + 94 32 setfsgid32 sys_setfsgid + 95 common fsync sys_fsync + 96 common setpriority sys_setpriority +@@ -155,7 +155,7 @@ + 123 32 fchown sys_fchown16 + 123 64 fchown sys_fchown + 124 common fchmod sys_fchmod +-125 common recvfrom sys_recvfrom ++125 common recvfrom sys_recvfrom compat_sys_recvfrom + 126 32 setreuid sys_setreuid16 + 126 64 setreuid sys_setreuid + 127 32 setregid sys_setregid16 +@@ -247,7 +247,7 @@ + 204 32 readdir sys_old_readdir compat_sys_old_readdir + 204 64 readdir sys_nis_syscall + 205 common readahead sys_readahead compat_sys_readahead +-206 common socketcall sys_socketcall sys32_socketcall ++206 common socketcall sys_socketcall compat_sys_socketcall + 207 common syslog sys_syslog + 208 common lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie + 209 common fadvise64 sys_fadvise64 compat_sys_fadvise64 +@@ -461,7 +461,7 @@ + 412 32 utimensat_time64 sys_utimensat sys_utimensat + 413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 + 414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 +-416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents ++416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 + 417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 + 418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend + 419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive +diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl +index 960a021d543e5..0985d8333368f 100644 +--- a/arch/x86/entry/syscalls/syscall_32.tbl ++++ b/arch/x86/entry/syscalls/syscall_32.tbl +@@ -420,7 +420,7 @@ + 412 i386 utimensat_time64 sys_utimensat + 413 i386 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 + 414 i386 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 +-416 i386 io_pgetevents_time64 sys_io_pgetevents ++416 i386 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 + 417 i386 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 + 418 i386 mq_timedsend_time64 sys_mq_timedsend + 419 i386 mq_timedreceive_time64 sys_mq_timedreceive +diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h +index eb8fcede9e3bf..e8e3dbe7f1730 100644 +--- a/arch/x86/include/asm/cpu_device_id.h ++++ b/arch/x86/include/asm/cpu_device_id.h +@@ -2,6 +2,39 @@ + #ifndef _ASM_X86_CPU_DEVICE_ID + #define _ASM_X86_CPU_DEVICE_ID + ++/* ++ * Can't use <linux/bitfield.h> because it generates expressions that ++ * cannot be used in structure initializers. Bitfield construction ++ * here must match the union in struct cpuinfo_86: ++ * union { ++ * struct { ++ * __u8 x86_model; ++ * __u8 x86; ++ * __u8 x86_vendor; ++ * __u8 x86_reserved; ++ * }; ++ * __u32 x86_vfm; ++ * }; ++ */ ++#define VFM_MODEL_BIT 0 ++#define VFM_FAMILY_BIT 8 ++#define VFM_VENDOR_BIT 16 ++#define VFM_RSVD_BIT 24 ++ ++#define VFM_MODEL_MASK GENMASK(VFM_FAMILY_BIT - 1, VFM_MODEL_BIT) ++#define VFM_FAMILY_MASK GENMASK(VFM_VENDOR_BIT - 1, VFM_FAMILY_BIT) ++#define VFM_VENDOR_MASK GENMASK(VFM_RSVD_BIT - 1, VFM_VENDOR_BIT) ++ ++#define VFM_MODEL(vfm) (((vfm) & VFM_MODEL_MASK) >> VFM_MODEL_BIT) ++#define VFM_FAMILY(vfm) (((vfm) & VFM_FAMILY_MASK) >> VFM_FAMILY_BIT) ++#define VFM_VENDOR(vfm) (((vfm) & VFM_VENDOR_MASK) >> VFM_VENDOR_BIT) ++ ++#define VFM_MAKE(_vendor, _family, _model) ( \ ++ ((_model) << VFM_MODEL_BIT) | \ ++ ((_family) << VFM_FAMILY_BIT) | \ ++ ((_vendor) << VFM_VENDOR_BIT) \ ++) ++ + /* + * Declare drivers belonging to specific x86 CPUs + * Similar in spirit to pci_device_id and related PCI functions +@@ -20,6 +53,9 @@ + #define X86_CENTAUR_FAM6_C7_D 0xd + #define X86_CENTAUR_FAM6_NANO 0xf + ++/* x86_cpu_id::flags */ ++#define X86_CPU_ID_FLAG_ENTRY_VALID BIT(0) ++ + #define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins) + /** + * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching +@@ -46,6 +82,18 @@ + .model = _model, \ + .steppings = _steppings, \ + .feature = _feature, \ ++ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ ++ .driver_data = (unsigned long) _data \ ++} ++ ++#define X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \ ++ _steppings, _feature, _data) { \ ++ .vendor = _vendor, \ ++ .family = _family, \ ++ .model = _model, \ ++ .steppings = _steppings, \ ++ .feature = _feature, \ ++ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ + .driver_data = (unsigned long) _data \ + } + +@@ -164,6 +212,56 @@ + X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \ + steppings, X86_FEATURE_ANY, data) + ++/** ++ * X86_MATCH_VFM - Match encoded vendor/family/model ++ * @vfm: Encoded 8-bits each for vendor, family, model ++ * @data: Driver specific data or NULL. The internal storage ++ * format is unsigned long. The supplied value, pointer ++ * etc. is cast to unsigned long internally. ++ * ++ * Stepping and feature are set to wildcards ++ */ ++#define X86_MATCH_VFM(vfm, data) \ ++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ ++ VFM_VENDOR(vfm), \ ++ VFM_FAMILY(vfm), \ ++ VFM_MODEL(vfm), \ ++ X86_STEPPING_ANY, X86_FEATURE_ANY, data) ++ ++/** ++ * X86_MATCH_VFM_STEPPINGS - Match encoded vendor/family/model/stepping ++ * @vfm: Encoded 8-bits each for vendor, family, model ++ * @steppings: Bitmask of steppings to match ++ * @data: Driver specific data or NULL. The internal storage ++ * format is unsigned long. The supplied value, pointer ++ * etc. is cast to unsigned long internally. ++ * ++ * feature is set to wildcard ++ */ ++#define X86_MATCH_VFM_STEPPINGS(vfm, steppings, data) \ ++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ ++ VFM_VENDOR(vfm), \ ++ VFM_FAMILY(vfm), \ ++ VFM_MODEL(vfm), \ ++ steppings, X86_FEATURE_ANY, data) ++ ++/** ++ * X86_MATCH_VFM_FEATURE - Match encoded vendor/family/model/feature ++ * @vfm: Encoded 8-bits each for vendor, family, model ++ * @feature: A X86_FEATURE bit ++ * @data: Driver specific data or NULL. The internal storage ++ * format is unsigned long. The supplied value, pointer ++ * etc. is cast to unsigned long internally. ++ * ++ * Steppings is set to wildcard ++ */ ++#define X86_MATCH_VFM_FEATURE(vfm, feature, data) \ ++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ ++ VFM_VENDOR(vfm), \ ++ VFM_FAMILY(vfm), \ ++ VFM_MODEL(vfm), \ ++ X86_STEPPING_ANY, feature, data) ++ + /* + * Match specific microcode revisions. + * +diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h +index 63158fd558567..e7c07a182ebdd 100644 +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -386,6 +386,17 @@ static inline void efi_fake_memmap_early(void) + } + #endif + ++extern int __init efi_memmap_alloc(unsigned int num_entries, ++ struct efi_memory_map_data *data); ++extern void __efi_memmap_free(u64 phys, unsigned long size, ++ unsigned long flags); ++ ++extern int __init efi_memmap_install(struct efi_memory_map_data *data); ++extern int __init efi_memmap_split_count(efi_memory_desc_t *md, ++ struct range *range); ++extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, ++ void *buf, struct efi_mem_range *mem); ++ + #define arch_ima_efi_boot_mode \ + ({ extern struct boot_params boot_params; boot_params.secure_boot; }) + +diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c +index c92c9c774c0e5..62cd2af806b47 100644 +--- a/arch/x86/kernel/amd_nb.c ++++ b/arch/x86/kernel/amd_nb.c +@@ -172,7 +172,14 @@ static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write) + + int amd_smn_read(u16 node, u32 address, u32 *value) + { +- return __amd_smn_rw(node, address, value, false); ++ int err = __amd_smn_rw(node, address, value, false); ++ ++ if (PCI_POSSIBLE_ERROR(*value)) { ++ err = -ENODEV; ++ *value = 0; ++ } ++ ++ return err; + } + EXPORT_SYMBOL_GPL(amd_smn_read); + +diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c +index ad6776081e60d..ae71b8ef909c9 100644 +--- a/arch/x86/kernel/cpu/match.c ++++ b/arch/x86/kernel/cpu/match.c +@@ -39,9 +39,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) + const struct x86_cpu_id *m; + struct cpuinfo_x86 *c = &boot_cpu_data; + +- for (m = match; +- m->vendor | m->family | m->model | m->steppings | m->feature; +- m++) { ++ for (m = match; m->flags & X86_CPU_ID_FLAG_ENTRY_VALID; m++) { + if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor) + continue; + if (m->family != X86_FAMILY_ANY && c->x86 != m->family) +diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c +index 3ad1bf5de7373..157008d99f951 100644 +--- a/arch/x86/kernel/fpu/core.c ++++ b/arch/x86/kernel/fpu/core.c +@@ -121,8 +121,8 @@ void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask) + asm volatile( + "fnclex\n\t" + "emms\n\t" +- "fildl %P[addr]" /* set F?P to defined value */ +- : : [addr] "m" (fpstate)); ++ "fildl %[addr]" /* set F?P to defined value */ ++ : : [addr] "m" (*fpstate)); + } + + if (use_xsave()) { +diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c +index 893f040b97b7d..99dd504307fdc 100644 +--- a/arch/x86/kernel/kprobes/core.c ++++ b/arch/x86/kernel/kprobes/core.c +@@ -194,17 +194,10 @@ static unsigned long + __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) + { + struct kprobe *kp; +- unsigned long faddr; ++ bool faddr; + + kp = get_kprobe((void *)addr); +- faddr = ftrace_location(addr); +- /* +- * Addresses inside the ftrace location are refused by +- * arch_check_ftrace_location(). Something went terribly wrong +- * if such an address is checked here. +- */ +- if (WARN_ON(faddr && faddr != addr)) +- return 0UL; ++ faddr = ftrace_location(addr) == addr; + /* + * Use the current code if it is not modified by Kprobe + * and it cannot be modified by ftrace. +diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c +index e42faa792c079..52e1f3f0b361c 100644 +--- a/arch/x86/kernel/time.c ++++ b/arch/x86/kernel/time.c +@@ -27,25 +27,7 @@ + + unsigned long profile_pc(struct pt_regs *regs) + { +- unsigned long pc = instruction_pointer(regs); +- +- if (!user_mode(regs) && in_lock_functions(pc)) { +-#ifdef CONFIG_FRAME_POINTER +- return *(unsigned long *)(regs->bp + sizeof(long)); +-#else +- unsigned long *sp = (unsigned long *)regs->sp; +- /* +- * Return address is either directly at stack pointer +- * or above a saved flags. Eflags has bits 22-31 zero, +- * kernel addresses don't. +- */ +- if (sp[0] >> 22) +- return sp[0]; +- if (sp[1] >> 22) +- return sp[1]; +-#endif +- } +- return pc; ++ return instruction_pointer(regs); + } + EXPORT_SYMBOL(profile_pc); + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 7bfc037022ad5..ef56b79629d1c 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -9654,13 +9654,12 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) + + bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256); + ++ static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); ++ + if (irqchip_split(vcpu->kvm)) + kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); +- else { +- static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); +- if (ioapic_in_kernel(vcpu->kvm)) +- kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); +- } ++ else if (ioapic_in_kernel(vcpu->kvm)) ++ kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); + + if (is_guest_mode(vcpu)) + vcpu->arch.load_eoi_exitmap_pending = true; +diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile +index 84b09c230cbd5..196f61fdbf289 100644 +--- a/arch/x86/platform/efi/Makefile ++++ b/arch/x86/platform/efi/Makefile +@@ -3,5 +3,6 @@ OBJECT_FILES_NON_STANDARD_efi_thunk_$(BITS).o := y + KASAN_SANITIZE := n + GCOV_PROFILE := n + +-obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o ++obj-$(CONFIG_EFI) += memmap.o quirks.o efi.o efi_$(BITS).o \ ++ efi_stub_$(BITS).o + obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o +diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c +index 147c30a81f15b..da17de2483877 100644 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -234,9 +234,11 @@ int __init efi_memblock_x86_reserve_range(void) + data.desc_size = e->efi_memdesc_size; + data.desc_version = e->efi_memdesc_version; + +- rv = efi_memmap_init_early(&data); +- if (rv) +- return rv; ++ if (!efi_enabled(EFI_PARAVIRT)) { ++ rv = efi_memmap_init_early(&data); ++ if (rv) ++ return rv; ++ } + + if (add_efi_memmap || do_efi_soft_reserve()) + do_add_efi_memmap(); +diff --git a/arch/x86/platform/efi/memmap.c b/arch/x86/platform/efi/memmap.c +new file mode 100644 +index 0000000000000..872d310c426e2 +--- /dev/null ++++ b/arch/x86/platform/efi/memmap.c +@@ -0,0 +1,249 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Common EFI memory map functions. ++ */ ++ ++#define pr_fmt(fmt) "efi: " fmt ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/efi.h> ++#include <linux/io.h> ++#include <asm/early_ioremap.h> ++#include <asm/efi.h> ++#include <linux/memblock.h> ++#include <linux/slab.h> ++ ++static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size) ++{ ++ return memblock_phys_alloc(size, SMP_CACHE_BYTES); ++} ++ ++static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size) ++{ ++ unsigned int order = get_order(size); ++ struct page *p = alloc_pages(GFP_KERNEL, order); ++ ++ if (!p) ++ return 0; ++ ++ return PFN_PHYS(page_to_pfn(p)); ++} ++ ++void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags) ++{ ++ if (flags & EFI_MEMMAP_MEMBLOCK) { ++ if (slab_is_available()) ++ memblock_free_late(phys, size); ++ else ++ memblock_free(phys, size); ++ } else if (flags & EFI_MEMMAP_SLAB) { ++ struct page *p = pfn_to_page(PHYS_PFN(phys)); ++ unsigned int order = get_order(size); ++ ++ free_pages((unsigned long) page_address(p), order); ++ } ++} ++ ++/** ++ * efi_memmap_alloc - Allocate memory for the EFI memory map ++ * @num_entries: Number of entries in the allocated map. ++ * @data: efi memmap installation parameters ++ * ++ * Depending on whether mm_init() has already been invoked or not, ++ * either memblock or "normal" page allocation is used. ++ * ++ * Returns zero on success, a negative error code on failure. ++ */ ++int __init efi_memmap_alloc(unsigned int num_entries, ++ struct efi_memory_map_data *data) ++{ ++ /* Expect allocation parameters are zero initialized */ ++ WARN_ON(data->phys_map || data->size); ++ ++ data->size = num_entries * efi.memmap.desc_size; ++ data->desc_version = efi.memmap.desc_version; ++ data->desc_size = efi.memmap.desc_size; ++ data->flags &= ~(EFI_MEMMAP_SLAB | EFI_MEMMAP_MEMBLOCK); ++ data->flags |= efi.memmap.flags & EFI_MEMMAP_LATE; ++ ++ if (slab_is_available()) { ++ data->flags |= EFI_MEMMAP_SLAB; ++ data->phys_map = __efi_memmap_alloc_late(data->size); ++ } else { ++ data->flags |= EFI_MEMMAP_MEMBLOCK; ++ data->phys_map = __efi_memmap_alloc_early(data->size); ++ } ++ ++ if (!data->phys_map) ++ return -ENOMEM; ++ return 0; ++} ++ ++/** ++ * efi_memmap_install - Install a new EFI memory map in efi.memmap ++ * @ctx: map allocation parameters (address, size, flags) ++ * ++ * Unlike efi_memmap_init_*(), this function does not allow the caller ++ * to switch from early to late mappings. It simply uses the existing ++ * mapping function and installs the new memmap. ++ * ++ * Returns zero on success, a negative error code on failure. ++ */ ++int __init efi_memmap_install(struct efi_memory_map_data *data) ++{ ++ unsigned long size = efi.memmap.desc_size * efi.memmap.nr_map; ++ unsigned long flags = efi.memmap.flags; ++ u64 phys = efi.memmap.phys_map; ++ int ret; ++ ++ efi_memmap_unmap(); ++ ++ if (efi_enabled(EFI_PARAVIRT)) ++ return 0; ++ ++ ret = __efi_memmap_init(data); ++ if (ret) ++ return ret; ++ ++ __efi_memmap_free(phys, size, flags); ++ return 0; ++} ++ ++/** ++ * efi_memmap_split_count - Count number of additional EFI memmap entries ++ * @md: EFI memory descriptor to split ++ * @range: Address range (start, end) to split around ++ * ++ * Returns the number of additional EFI memmap entries required to ++ * accommodate @range. ++ */ ++int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range) ++{ ++ u64 m_start, m_end; ++ u64 start, end; ++ int count = 0; ++ ++ start = md->phys_addr; ++ end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; ++ ++ /* modifying range */ ++ m_start = range->start; ++ m_end = range->end; ++ ++ if (m_start <= start) { ++ /* split into 2 parts */ ++ if (start < m_end && m_end < end) ++ count++; ++ } ++ ++ if (start < m_start && m_start < end) { ++ /* split into 3 parts */ ++ if (m_end < end) ++ count += 2; ++ /* split into 2 parts */ ++ if (end <= m_end) ++ count++; ++ } ++ ++ return count; ++} ++ ++/** ++ * efi_memmap_insert - Insert a memory region in an EFI memmap ++ * @old_memmap: The existing EFI memory map structure ++ * @buf: Address of buffer to store new map ++ * @mem: Memory map entry to insert ++ * ++ * It is suggested that you call efi_memmap_split_count() first ++ * to see how large @buf needs to be. ++ */ ++void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, ++ struct efi_mem_range *mem) ++{ ++ u64 m_start, m_end, m_attr; ++ efi_memory_desc_t *md; ++ u64 start, end; ++ void *old, *new; ++ ++ /* modifying range */ ++ m_start = mem->range.start; ++ m_end = mem->range.end; ++ m_attr = mem->attribute; ++ ++ /* ++ * The EFI memory map deals with regions in EFI_PAGE_SIZE ++ * units. Ensure that the region described by 'mem' is aligned ++ * correctly. ++ */ ++ if (!IS_ALIGNED(m_start, EFI_PAGE_SIZE) || ++ !IS_ALIGNED(m_end + 1, EFI_PAGE_SIZE)) { ++ WARN_ON(1); ++ return; ++ } ++ ++ for (old = old_memmap->map, new = buf; ++ old < old_memmap->map_end; ++ old += old_memmap->desc_size, new += old_memmap->desc_size) { ++ ++ /* copy original EFI memory descriptor */ ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ start = md->phys_addr; ++ end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; ++ ++ if (m_start <= start && end <= m_end) ++ md->attribute |= m_attr; ++ ++ if (m_start <= start && ++ (start < m_end && m_end < end)) { ++ /* first part */ ++ md->attribute |= m_attr; ++ md->num_pages = (m_end - md->phys_addr + 1) >> ++ EFI_PAGE_SHIFT; ++ /* latter part */ ++ new += old_memmap->desc_size; ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ md->phys_addr = m_end + 1; ++ md->num_pages = (end - md->phys_addr + 1) >> ++ EFI_PAGE_SHIFT; ++ } ++ ++ if ((start < m_start && m_start < end) && m_end < end) { ++ /* first part */ ++ md->num_pages = (m_start - md->phys_addr) >> ++ EFI_PAGE_SHIFT; ++ /* middle part */ ++ new += old_memmap->desc_size; ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ md->attribute |= m_attr; ++ md->phys_addr = m_start; ++ md->num_pages = (m_end - m_start + 1) >> ++ EFI_PAGE_SHIFT; ++ /* last part */ ++ new += old_memmap->desc_size; ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ md->phys_addr = m_end + 1; ++ md->num_pages = (end - m_end) >> ++ EFI_PAGE_SHIFT; ++ } ++ ++ if ((start < m_start && m_start < end) && ++ (end <= m_end)) { ++ /* first part */ ++ md->num_pages = (m_start - md->phys_addr) >> ++ EFI_PAGE_SHIFT; ++ /* latter part */ ++ new += old_memmap->desc_size; ++ memcpy(new, old, old_memmap->desc_size); ++ md = new; ++ md->phys_addr = m_start; ++ md->num_pages = (end - md->phys_addr + 1) >> ++ EFI_PAGE_SHIFT; ++ md->attribute |= m_attr; ++ } ++ } ++} +diff --git a/block/ioctl.c b/block/ioctl.c +index 7a939c178660f..a260e39e56a48 100644 +--- a/block/ioctl.c ++++ b/block/ioctl.c +@@ -33,7 +33,7 @@ static int blkpg_do_ioctl(struct block_device *bdev, + if (op == BLKPG_DEL_PARTITION) + return bdev_del_partition(disk, p.pno); + +- if (p.start < 0 || p.length <= 0 || p.start + p.length < 0) ++ if (p.start < 0 || p.length <= 0 || LLONG_MAX - p.length < p.start) + return -EINVAL; + /* Check that the partition is aligned to the block size */ + if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev))) +diff --git a/crypto/ecdh.c b/crypto/ecdh.c +index c6f61c2211dc7..865e76e5a51c4 100644 +--- a/crypto/ecdh.c ++++ b/crypto/ecdh.c +@@ -33,6 +33,8 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, + params.key_size > sizeof(u64) * ctx->ndigits) + return -EINVAL; + ++ memset(ctx->private_key, 0, sizeof(ctx->private_key)); ++ + if (!params.key || !params.key_size) + return ecc_gen_privkey(ctx->curve_id, ctx->ndigits, + ctx->private_key); +diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c +index 82b713a9a1939..4b6b53bd90183 100644 +--- a/drivers/acpi/acpica/exregion.c ++++ b/drivers/acpi/acpica/exregion.c +@@ -44,7 +44,6 @@ acpi_ex_system_memory_space_handler(u32 function, + struct acpi_mem_mapping *mm = mem_info->cur_mm; + u32 length; + acpi_size map_length; +- acpi_size page_boundary_map_length; + #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED + u32 remainder; + #endif +@@ -138,26 +137,8 @@ acpi_ex_system_memory_space_handler(u32 function, + map_length = (acpi_size) + ((mem_info->address + mem_info->length) - address); + +- /* +- * If mapping the entire remaining portion of the region will cross +- * a page boundary, just map up to the page boundary, do not cross. +- * On some systems, crossing a page boundary while mapping regions +- * can cause warnings if the pages have different attributes +- * due to resource management. +- * +- * This has the added benefit of constraining a single mapping to +- * one page, which is similar to the original code that used a 4k +- * maximum window. +- */ +- page_boundary_map_length = (acpi_size) +- (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address); +- if (page_boundary_map_length == 0) { +- page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE; +- } +- +- if (map_length > page_boundary_map_length) { +- map_length = page_boundary_map_length; +- } ++ if (map_length > ACPI_DEFAULT_PAGE_SIZE) ++ map_length = ACPI_DEFAULT_PAGE_SIZE; + + /* Create a new mapping starting at the address given */ + +diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c +index a5cb9e1d48bcc..338e1f44906a9 100644 +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -341,6 +341,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "82BK"), + }, + }, ++ { ++ .callback = video_detect_force_native, ++ /* Lenovo Slim 7 16ARH7 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "82UX"), ++ }, ++ }, + { + .callback = video_detect_force_native, + /* Lenovo ThinkPad X131e (3371 AMD version) */ +diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c +index f1dd086d0b87d..aa4f233373afc 100644 +--- a/drivers/acpi/x86/utils.c ++++ b/drivers/acpi/x86/utils.c +@@ -179,16 +179,16 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s + } + + /* +- * AMD systems from Renoir and Lucienne *require* that the NVME controller ++ * AMD systems from Renoir onwards *require* that the NVME controller + * is put into D3 over a Modern Standby / suspend-to-idle cycle. + * + * This is "typically" accomplished using the `StorageD3Enable` + * property in the _DSD that is checked via the `acpi_storage_d3` function +- * but this property was introduced after many of these systems launched +- * and most OEM systems don't have it in their BIOS. ++ * but some OEM systems still don't have it in their BIOS. + * + * The Microsoft documentation for StorageD3Enable mentioned that Windows has +- * a hardcoded allowlist for D3 support, which was used for these platforms. ++ * a hardcoded allowlist for D3 support as well as a registry key to override ++ * the BIOS, which has been used for these cases. + * + * This allows quirking on Linux in a similar fashion. + * +@@ -201,16 +201,13 @@ bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *s + * https://bugzilla.kernel.org/show_bug.cgi?id=216773 + * https://bugzilla.kernel.org/show_bug.cgi?id=217003 + * 2) On at least one HP system StorageD3Enable is missing on the second NVME +- disk in the system. ++ * disk in the system. ++ * 3) On at least one HP Rembrandt system StorageD3Enable is missing on the only ++ * NVME device. + */ +-static const struct x86_cpu_id storage_d3_cpu_ids[] = { +- X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL), /* Renoir */ +- X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL), /* Lucienne */ +- X86_MATCH_VENDOR_FAM_MODEL(AMD, 25, 80, NULL), /* Cezanne */ +- {} +-}; +- + bool force_storage_d3(void) + { +- return x86_match_cpu(storage_d3_cpu_ids); ++ if (!cpu_feature_enabled(X86_FEATURE_ZEN)) ++ return false; ++ return acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0; + } +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 7807c7b9f37ab..ff5f83c5af00e 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -1897,8 +1897,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); + + host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); +- if (!host) +- return -ENOMEM; ++ if (!host) { ++ rc = -ENOMEM; ++ goto err_rm_sysfs_file; ++ } + host->private_data = hpriv; + + if (ahci_init_msi(pdev, n_ports, hpriv) < 0) { +@@ -1951,11 +1953,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + /* initialize adapter */ + rc = ahci_configure_dma_masks(pdev, hpriv); + if (rc) +- return rc; ++ goto err_rm_sysfs_file; + + rc = ahci_pci_reset_controller(host); + if (rc) +- return rc; ++ goto err_rm_sysfs_file; + + ahci_pci_init_controller(host); + ahci_pci_print_info(host); +@@ -1964,10 +1966,15 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + + rc = ahci_host_activate(host, &ahci_sht); + if (rc) +- return rc; ++ goto err_rm_sysfs_file; + + pm_runtime_put_noidle(&pdev->dev); + return 0; ++ ++err_rm_sysfs_file: ++ sysfs_remove_file_from_group(&pdev->dev.kobj, ++ &dev_attr_remapped_nvme.attr, NULL); ++ return rc; + } + + static void ahci_shutdown_one(struct pci_dev *pdev) +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 383398af836c8..31a0818b44406 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -5445,8 +5445,10 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) + if (!host) + return NULL; + +- if (!devres_open_group(dev, NULL, GFP_KERNEL)) +- goto err_free; ++ if (!devres_open_group(dev, NULL, GFP_KERNEL)) { ++ kfree(host); ++ return NULL; ++ } + + dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL); + if (!dr) +@@ -5478,8 +5480,6 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) + + err_out: + devres_release_group(dev, NULL); +- err_free: +- kfree(host); + return NULL; + } + EXPORT_SYMBOL_GPL(ata_host_alloc); +diff --git a/drivers/base/core.c b/drivers/base/core.c +index ca56fd7450211..d995d768c362a 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -2404,8 +2404,11 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, + if (!env) + return -ENOMEM; + ++ /* Synchronize with really_probe() */ ++ device_lock(dev); + /* let the kset specific function add its keys */ + retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); ++ device_unlock(dev); + if (retval) + goto out; + +diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c +index dae54dd1aeac3..0cdeafd9defcf 100644 +--- a/drivers/block/null_blk/zoned.c ++++ b/drivers/block/null_blk/zoned.c +@@ -109,7 +109,7 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q) + if (dev->zone_max_active && dev->zone_max_open > dev->zone_max_active) { + dev->zone_max_open = dev->zone_max_active; + pr_info("changed the maximum number of open zones to %u\n", +- dev->nr_zones); ++ dev->zone_max_open); + } else if (dev->zone_max_open >= dev->nr_zones - dev->zone_nr_conv) { + dev->zone_max_open = 0; + pr_info("zone_max_open limit disabled, limit >= zone count\n"); +diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c +index 759d7828931d9..56ada48104f0e 100644 +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -3,7 +3,6 @@ + * Copyright (c) 2008-2009 Atheros Communications Inc. + */ + +- + #include <linux/module.h> + #include <linux/kernel.h> + #include <linux/init.h> +@@ -129,7 +128,6 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); + * for AR3012 + */ + static const struct usb_device_id ath3k_blist_tbl[] = { +- + /* Atheros AR3012 with sflash firmware*/ + { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, +@@ -203,7 +201,7 @@ static inline void ath3k_log_failed_loading(int err, int len, int size, + #define TIMEGAP_USEC_MAX 100 + + static int ath3k_load_firmware(struct usb_device *udev, +- const struct firmware *firmware) ++ const struct firmware *firmware) + { + u8 *send_buf; + int len = 0; +@@ -238,9 +236,9 @@ static int ath3k_load_firmware(struct usb_device *udev, + memcpy(send_buf, firmware->data + sent, size); + + err = usb_bulk_msg(udev, pipe, send_buf, size, +- &len, 3000); ++ &len, 3000); + +- if (err || (len != size)) { ++ if (err || len != size) { + ath3k_log_failed_loading(err, len, size, count); + goto error; + } +@@ -263,7 +261,7 @@ static int ath3k_get_state(struct usb_device *udev, unsigned char *state) + } + + static int ath3k_get_version(struct usb_device *udev, +- struct ath3k_version *version) ++ struct ath3k_version *version) + { + return usb_control_msg_recv(udev, 0, ATH3K_GETVERSION, + USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, +@@ -272,7 +270,7 @@ static int ath3k_get_version(struct usb_device *udev, + } + + static int ath3k_load_fwfile(struct usb_device *udev, +- const struct firmware *firmware) ++ const struct firmware *firmware) + { + u8 *send_buf; + int len = 0; +@@ -311,8 +309,8 @@ static int ath3k_load_fwfile(struct usb_device *udev, + memcpy(send_buf, firmware->data + sent, size); + + err = usb_bulk_msg(udev, pipe, send_buf, size, +- &len, 3000); +- if (err || (len != size)) { ++ &len, 3000); ++ if (err || len != size) { + ath3k_log_failed_loading(err, len, size, count); + kfree(send_buf); + return err; +@@ -426,7 +424,6 @@ static int ath3k_load_syscfg(struct usb_device *udev) + } + + switch (fw_version.ref_clock) { +- + case ATH3K_XTAL_FREQ_26M: + clk_value = 26; + break; +@@ -442,7 +439,7 @@ static int ath3k_load_syscfg(struct usb_device *udev) + } + + snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", +- le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); ++ le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); + + ret = request_firmware(&firmware, filename, &udev->dev); + if (ret < 0) { +@@ -457,7 +454,7 @@ static int ath3k_load_syscfg(struct usb_device *udev) + } + + static int ath3k_probe(struct usb_interface *intf, +- const struct usb_device_id *id) ++ const struct usb_device_id *id) + { + const struct firmware *firmware; + struct usb_device *udev = interface_to_usbdev(intf); +@@ -506,10 +503,10 @@ static int ath3k_probe(struct usb_interface *intf, + if (ret < 0) { + if (ret == -ENOENT) + BT_ERR("Firmware file \"%s\" not found", +- ATH3K_FIRMWARE); ++ ATH3K_FIRMWARE); + else + BT_ERR("Firmware file \"%s\" request failed (err=%d)", +- ATH3K_FIRMWARE, ret); ++ ATH3K_FIRMWARE, ret); + return ret; + } + +diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c +index d4ae33a5f805e..78244d53dbe0f 100644 +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -98,7 +98,8 @@ static int qca_read_fw_build_info(struct hci_dev *hdev) + { + struct sk_buff *skb; + struct edl_event_hdr *edl; +- char cmd, build_label[QCA_FW_BUILD_VER_LEN]; ++ char *build_label; ++ char cmd; + int build_lbl_len, err = 0; + + bt_dev_dbg(hdev, "QCA read fw build info"); +@@ -113,6 +114,11 @@ static int qca_read_fw_build_info(struct hci_dev *hdev) + return err; + } + ++ if (skb->len < sizeof(*edl)) { ++ err = -EILSEQ; ++ goto out; ++ } ++ + edl = (struct edl_event_hdr *)(skb->data); + if (!edl) { + bt_dev_err(hdev, "QCA read fw build info with no header"); +@@ -128,14 +134,27 @@ static int qca_read_fw_build_info(struct hci_dev *hdev) + goto out; + } + ++ if (skb->len < sizeof(*edl) + 1) { ++ err = -EILSEQ; ++ goto out; ++ } ++ + build_lbl_len = edl->data[0]; +- if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 1) { +- memcpy(build_label, edl->data + 1, build_lbl_len); +- *(build_label + build_lbl_len) = '\0'; ++ ++ if (skb->len < sizeof(*edl) + 1 + build_lbl_len) { ++ err = -EILSEQ; ++ goto out; ++ } ++ ++ build_label = kstrndup(&edl->data[1], build_lbl_len, GFP_KERNEL); ++ if (!build_label) { ++ err = -ENOMEM; ++ goto out; + } + + hci_set_fw_info(hdev, "%s", build_label); + ++ kfree(build_label); + out: + kfree_skb(skb); + return err; +@@ -160,6 +179,49 @@ static int qca_send_reset(struct hci_dev *hdev) + return 0; + } + ++static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid) ++{ ++ u8 cmd; ++ struct sk_buff *skb; ++ struct edl_event_hdr *edl; ++ int err = 0; ++ ++ cmd = EDL_GET_BID_REQ_CMD; ++ skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN, ++ &cmd, 0, HCI_INIT_TIMEOUT); ++ if (IS_ERR(skb)) { ++ err = PTR_ERR(skb); ++ bt_dev_err(hdev, "Reading QCA board ID failed (%d)", err); ++ return err; ++ } ++ ++ edl = skb_pull_data(skb, sizeof(*edl)); ++ if (!edl) { ++ bt_dev_err(hdev, "QCA read board ID with no header"); ++ err = -EILSEQ; ++ goto out; ++ } ++ ++ if (edl->cresp != EDL_CMD_REQ_RES_EVT || ++ edl->rtype != EDL_GET_BID_REQ_CMD) { ++ bt_dev_err(hdev, "QCA Wrong packet: %d %d", edl->cresp, edl->rtype); ++ err = -EIO; ++ goto out; ++ } ++ ++ if (skb->len < 3) { ++ err = -EILSEQ; ++ goto out; ++ } ++ ++ *bid = (edl->data[1] << 8) + edl->data[2]; ++ bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid); ++ ++out: ++ kfree_skb(skb); ++ return err; ++} ++ + int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) + { + struct sk_buff *skb; +@@ -575,6 +637,23 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) + } + EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); + ++static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size, ++ struct qca_btsoc_version ver, u8 rom_ver, u16 bid) ++{ ++ const char *variant; ++ ++ /* hsp gf chip */ ++ if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID) ++ variant = "g"; ++ else ++ variant = ""; ++ ++ if (bid == 0x0) ++ snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant); ++ else ++ snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid); ++} ++ + int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + enum qca_btsoc_type soc_type, struct qca_btsoc_version ver, + const char *firmware_name) +@@ -583,6 +662,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + int err; + u8 rom_ver = 0; + u32 soc_ver; ++ u16 boardid = 0; + + bt_dev_dbg(hdev, "QCA setup on UART"); + +@@ -595,27 +675,45 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + /* Firmware files to download are based on ROM version. + * ROM version is derived from last two bytes of soc_ver. + */ +- rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f); ++ if (soc_type == QCA_WCN3988) ++ rom_ver = ((soc_ver & 0x00000f00) >> 0x05) | (soc_ver & 0x0000000f); ++ else ++ rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f); + + /* Download rampatch file */ + config.type = TLV_TYPE_PATCH; +- if (qca_is_wcn399x(soc_type)) { ++ switch (soc_type) { ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: + snprintf(config.fwname, sizeof(config.fwname), + "qca/crbtfw%02x.tlv", rom_ver); +- } else if (soc_type == QCA_QCA6390) { ++ break; ++ case QCA_WCN3988: ++ snprintf(config.fwname, sizeof(config.fwname), ++ "qca/apbtfw%02x.tlv", rom_ver); ++ break; ++ case QCA_QCA2066: ++ snprintf(config.fwname, sizeof(config.fwname), ++ "qca/hpbtfw%02x.tlv", rom_ver); ++ break; ++ case QCA_QCA6390: + snprintf(config.fwname, sizeof(config.fwname), + "qca/htbtfw%02x.tlv", rom_ver); +- } else if (soc_type == QCA_WCN6750) { ++ break; ++ case QCA_WCN6750: + /* Choose mbn file by default.If mbn file is not found + * then choose tlv file + */ + config.type = ELF_TYPE_PATCH; + snprintf(config.fwname, sizeof(config.fwname), + "qca/msbtfw%02x.mbn", rom_ver); +- } else if (soc_type == QCA_WCN6855) { ++ break; ++ case QCA_WCN6855: + snprintf(config.fwname, sizeof(config.fwname), + "qca/hpbtfw%02x.tlv", rom_ver); +- } else { ++ break; ++ default: + snprintf(config.fwname, sizeof(config.fwname), + "qca/rampatch_%08x.bin", soc_ver); + } +@@ -629,32 +727,53 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + /* Give the controller some time to get ready to receive the NVM */ + msleep(10); + ++ if (soc_type == QCA_QCA2066) ++ qca_read_fw_board_id(hdev, &boardid); ++ + /* Download NVM configuration */ + config.type = TLV_TYPE_NVM; +- if (firmware_name) ++ if (firmware_name) { + snprintf(config.fwname, sizeof(config.fwname), + "qca/%s", firmware_name); +- else if (qca_is_wcn399x(soc_type)) { +- if (ver.soc_id == QCA_WCN3991_SOC_ID) { ++ } else { ++ switch (soc_type) { ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ if (le32_to_cpu(ver.soc_id) == QCA_WCN3991_SOC_ID) { ++ snprintf(config.fwname, sizeof(config.fwname), ++ "qca/crnv%02xu.bin", rom_ver); ++ } else { ++ snprintf(config.fwname, sizeof(config.fwname), ++ "qca/crnv%02x.bin", rom_ver); ++ } ++ break; ++ case QCA_WCN3988: + snprintf(config.fwname, sizeof(config.fwname), +- "qca/crnv%02xu.bin", rom_ver); +- } else { ++ "qca/apnv%02x.bin", rom_ver); ++ break; ++ case QCA_QCA2066: ++ qca_generate_hsp_nvm_name(config.fwname, ++ sizeof(config.fwname), ver, rom_ver, boardid); ++ break; ++ case QCA_QCA6390: ++ snprintf(config.fwname, sizeof(config.fwname), ++ "qca/htnv%02x.bin", rom_ver); ++ break; ++ case QCA_WCN6750: + snprintf(config.fwname, sizeof(config.fwname), +- "qca/crnv%02x.bin", rom_ver); ++ "qca/msnv%02x.bin", rom_ver); ++ break; ++ case QCA_WCN6855: ++ snprintf(config.fwname, sizeof(config.fwname), ++ "qca/hpnv%02x.bin", rom_ver); ++ break; ++ ++ default: ++ snprintf(config.fwname, sizeof(config.fwname), ++ "qca/nvm_%08x.bin", soc_ver); + } + } +- else if (soc_type == QCA_QCA6390) +- snprintf(config.fwname, sizeof(config.fwname), +- "qca/htnv%02x.bin", rom_ver); +- else if (soc_type == QCA_WCN6750) +- snprintf(config.fwname, sizeof(config.fwname), +- "qca/msnv%02x.bin", rom_ver); +- else if (soc_type == QCA_WCN6855) +- snprintf(config.fwname, sizeof(config.fwname), +- "qca/hpnv%02x.bin", rom_ver); +- else +- snprintf(config.fwname, sizeof(config.fwname), +- "qca/nvm_%08x.bin", soc_ver); + + err = qca_download_firmware(hdev, &config, soc_type, rom_ver); + if (err < 0) { +@@ -662,16 +781,25 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + return err; + } + +- if (soc_type >= QCA_WCN3991) { ++ switch (soc_type) { ++ case QCA_WCN3991: ++ case QCA_QCA2066: ++ case QCA_QCA6390: ++ case QCA_WCN6750: ++ case QCA_WCN6855: + err = qca_disable_soc_logging(hdev); + if (err < 0) + return err; ++ break; ++ default: ++ break; + } + + /* WCN399x and WCN6750 supports the Microsoft vendor extension with 0xFD70 as the + * VsMsftOpCode. + */ + switch (soc_type) { ++ case QCA_WCN3988: + case QCA_WCN3990: + case QCA_WCN3991: + case QCA_WCN3998: +diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h +index b83bf202ea604..6a6a286bc8547 100644 +--- a/drivers/bluetooth/btqca.h ++++ b/drivers/bluetooth/btqca.h +@@ -12,6 +12,7 @@ + #define EDL_PATCH_VER_REQ_CMD (0x19) + #define EDL_PATCH_TLV_REQ_CMD (0x1E) + #define EDL_GET_BUILD_INFO_CMD (0x20) ++#define EDL_GET_BID_REQ_CMD (0x23) + #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) + #define MAX_SIZE_PER_TLV_SEGMENT (243) + #define QCA_PRE_SHUTDOWN_CMD (0xFC08) +@@ -44,8 +45,8 @@ + #define get_soc_ver(soc_id, rom_ver) \ + ((le32_to_cpu(soc_id) << 16) | (le16_to_cpu(rom_ver))) + +-#define QCA_FW_BUILD_VER_LEN 255 +- ++#define QCA_HSP_GF_SOC_ID 0x1200 ++#define QCA_HSP_GF_SOC_MASK 0x0000ff00 + + enum qca_baudrate { + QCA_BAUDRATE_115200 = 0, +@@ -140,9 +141,11 @@ enum qca_btsoc_type { + QCA_INVALID = -1, + QCA_AR3002, + QCA_ROME, ++ QCA_WCN3988, + QCA_WCN3990, + QCA_WCN3998, + QCA_WCN3991, ++ QCA_QCA2066, + QCA_QCA6390, + QCA_WCN6750, + QCA_WCN6855, +@@ -158,20 +161,6 @@ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver, + enum qca_btsoc_type); + int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); + int qca_send_pre_shutdown_cmd(struct hci_dev *hdev); +-static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) +-{ +- return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 || +- soc_type == QCA_WCN3998; +-} +-static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type) +-{ +- return soc_type == QCA_WCN6750; +-} +-static inline bool qca_is_wcn6855(enum qca_btsoc_type soc_type) +-{ +- return soc_type == QCA_WCN6855; +-} +- + #else + + static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) +@@ -199,21 +188,6 @@ static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) + return -EOPNOTSUPP; + } + +-static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) +-{ +- return false; +-} +- +-static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type) +-{ +- return false; +-} +- +-static inline bool qca_is_wcn6855(enum qca_btsoc_type soc_type) +-{ +- return false; +-} +- + static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) + { + return -EOPNOTSUPP; +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index fb71caa31daa7..0800f6e62b7f0 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -606,9 +606,18 @@ static int qca_open(struct hci_uart *hu) + if (hu->serdev) { + qcadev = serdev_device_get_drvdata(hu->serdev); + +- if (qca_is_wcn399x(qcadev->btsoc_type) || +- qca_is_wcn6750(qcadev->btsoc_type)) ++ switch (qcadev->btsoc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: + hu->init_speed = qcadev->init_speed; ++ break; ++ ++ default: ++ break; ++ } + + if (qcadev->oper_speed) + hu->oper_speed = qcadev->oper_speed; +@@ -1314,12 +1323,19 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) + msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS)); + + /* Give the controller time to process the request */ +- if (qca_is_wcn399x(qca_soc_type(hu)) || +- qca_is_wcn6750(qca_soc_type(hu)) || +- qca_is_wcn6855(qca_soc_type(hu))) ++ switch (qca_soc_type(hu)) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: + usleep_range(1000, 10000); +- else ++ break; ++ ++ default: + msleep(300); ++ } + + return 0; + } +@@ -1392,13 +1408,19 @@ static unsigned int qca_get_speed(struct hci_uart *hu, + + static int qca_check_speeds(struct hci_uart *hu) + { +- if (qca_is_wcn399x(qca_soc_type(hu)) || +- qca_is_wcn6750(qca_soc_type(hu)) || +- qca_is_wcn6855(qca_soc_type(hu))) { ++ switch (qca_soc_type(hu)) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: + if (!qca_get_speed(hu, QCA_INIT_SPEED) && + !qca_get_speed(hu, QCA_OPER_SPEED)) + return -EINVAL; +- } else { ++ break; ++ ++ default: + if (!qca_get_speed(hu, QCA_INIT_SPEED) || + !qca_get_speed(hu, QCA_OPER_SPEED)) + return -EINVAL; +@@ -1427,14 +1449,28 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) + /* Disable flow control for wcn3990 to deassert RTS while + * changing the baudrate of chip and host. + */ +- if (qca_is_wcn399x(soc_type) || +- qca_is_wcn6750(soc_type) || +- qca_is_wcn6855(soc_type)) ++ switch (soc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: + hci_uart_set_flow_control(hu, true); ++ break; ++ ++ default: ++ break; ++ } + +- if (soc_type == QCA_WCN3990) { ++ switch (soc_type) { ++ case QCA_WCN3990: + reinit_completion(&qca->drop_ev_comp); + set_bit(QCA_DROP_VENDOR_EVENT, &qca->flags); ++ break; ++ ++ default: ++ break; + } + + qca_baudrate = qca_get_baudrate_value(speed); +@@ -1446,12 +1482,22 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) + host_set_baudrate(hu, speed); + + error: +- if (qca_is_wcn399x(soc_type) || +- qca_is_wcn6750(soc_type) || +- qca_is_wcn6855(soc_type)) ++ switch (soc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: + hci_uart_set_flow_control(hu, false); ++ break; + +- if (soc_type == QCA_WCN3990) { ++ default: ++ break; ++ } ++ ++ switch (soc_type) { ++ case QCA_WCN3990: + /* Wait for the controller to send the vendor event + * for the baudrate change command. + */ +@@ -1463,6 +1509,10 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) + } + + clear_bit(QCA_DROP_VENDOR_EVENT, &qca->flags); ++ break; ++ ++ default: ++ break; + } + } + +@@ -1627,12 +1677,20 @@ static int qca_regulator_init(struct hci_uart *hu) + } + } + +- if (qca_is_wcn399x(soc_type)) { ++ switch (soc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: + /* Forcefully enable wcn399x to enter in to boot mode. */ + host_set_baudrate(hu, 2400); + ret = qca_send_power_pulse(hu, false); + if (ret) + return ret; ++ break; ++ ++ default: ++ break; + } + + /* For wcn6750 need to enable gpio bt_en */ +@@ -1649,10 +1707,18 @@ static int qca_regulator_init(struct hci_uart *hu) + + qca_set_speed(hu, QCA_INIT_SPEED); + +- if (qca_is_wcn399x(soc_type)) { ++ switch (soc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: + ret = qca_send_power_pulse(hu, true); + if (ret) + return ret; ++ break; ++ ++ default: ++ break; + } + + /* Now the device is in ready state to communicate with host. +@@ -1686,11 +1752,17 @@ static int qca_power_on(struct hci_dev *hdev) + if (!hu->serdev) + return 0; + +- if (qca_is_wcn399x(soc_type) || +- qca_is_wcn6750(soc_type) || +- qca_is_wcn6855(soc_type)) { ++ switch (soc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: + ret = qca_regulator_init(hu); +- } else { ++ break; ++ ++ default: + qcadev = serdev_device_get_drvdata(hu->serdev); + if (qcadev->bt_en) { + gpiod_set_value_cansleep(qcadev->bt_en, 1); +@@ -1713,6 +1785,7 @@ static int qca_setup(struct hci_uart *hu) + const char *firmware_name = qca_get_firmware_name(hu); + int ret; + struct qca_btsoc_version ver; ++ const char *soc_name; + + ret = qca_check_speeds(hu); + if (ret) +@@ -1727,10 +1800,30 @@ static int qca_setup(struct hci_uart *hu) + */ + set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); + +- bt_dev_info(hdev, "setting up %s", +- qca_is_wcn399x(soc_type) ? "wcn399x" : +- (soc_type == QCA_WCN6750) ? "wcn6750" : +- (soc_type == QCA_WCN6855) ? "wcn6855" : "ROME/QCA6390"); ++ switch (soc_type) { ++ case QCA_QCA2066: ++ soc_name = "qca2066"; ++ break; ++ ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ soc_name = "wcn399x"; ++ break; ++ ++ case QCA_WCN6750: ++ soc_name = "wcn6750"; ++ break; ++ ++ case QCA_WCN6855: ++ soc_name = "wcn6855"; ++ break; ++ ++ default: ++ soc_name = "ROME/QCA6390"; ++ } ++ bt_dev_info(hdev, "setting up %s", soc_name); + + qca->memdump_state = QCA_MEMDUMP_IDLE; + +@@ -1741,15 +1834,21 @@ static int qca_setup(struct hci_uart *hu) + + clear_bit(QCA_SSR_TRIGGERED, &qca->flags); + +- if (qca_is_wcn399x(soc_type) || +- qca_is_wcn6750(soc_type) || +- qca_is_wcn6855(soc_type)) { ++ switch (soc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: + set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); + + ret = qca_read_soc_version(hdev, &ver, soc_type); + if (ret) + goto out; +- } else { ++ break; ++ ++ default: + qca_set_speed(hu, QCA_INIT_SPEED); + } + +@@ -1763,9 +1862,16 @@ static int qca_setup(struct hci_uart *hu) + qca_baudrate = qca_get_baudrate_value(speed); + } + +- if (!(qca_is_wcn399x(soc_type) || +- qca_is_wcn6750(soc_type) || +- qca_is_wcn6855(soc_type))) { ++ switch (soc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: ++ break; ++ ++ default: + /* Get QCA version information */ + ret = qca_read_soc_version(hdev, &ver, soc_type); + if (ret) +@@ -1834,7 +1940,18 @@ static const struct hci_uart_proto qca_proto = { + .dequeue = qca_dequeue, + }; + +-static const struct qca_device_data qca_soc_data_wcn3990 = { ++static const struct qca_device_data qca_soc_data_wcn3988 __maybe_unused = { ++ .soc_type = QCA_WCN3988, ++ .vregs = (struct qca_vreg []) { ++ { "vddio", 15000 }, ++ { "vddxo", 80000 }, ++ { "vddrf", 300000 }, ++ { "vddch0", 450000 }, ++ }, ++ .num_vregs = 4, ++}; ++ ++static const struct qca_device_data qca_soc_data_wcn3990 __maybe_unused = { + .soc_type = QCA_WCN3990, + .vregs = (struct qca_vreg []) { + { "vddio", 15000 }, +@@ -1845,7 +1962,7 @@ static const struct qca_device_data qca_soc_data_wcn3990 = { + .num_vregs = 4, + }; + +-static const struct qca_device_data qca_soc_data_wcn3991 = { ++static const struct qca_device_data qca_soc_data_wcn3991 __maybe_unused = { + .soc_type = QCA_WCN3991, + .vregs = (struct qca_vreg []) { + { "vddio", 15000 }, +@@ -1857,7 +1974,7 @@ static const struct qca_device_data qca_soc_data_wcn3991 = { + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, + }; + +-static const struct qca_device_data qca_soc_data_wcn3998 = { ++static const struct qca_device_data qca_soc_data_wcn3998 __maybe_unused = { + .soc_type = QCA_WCN3998, + .vregs = (struct qca_vreg []) { + { "vddio", 10000 }, +@@ -1868,13 +1985,18 @@ static const struct qca_device_data qca_soc_data_wcn3998 = { + .num_vregs = 4, + }; + +-static const struct qca_device_data qca_soc_data_qca6390 = { ++static const struct qca_device_data qca_soc_data_qca2066 __maybe_unused = { ++ .soc_type = QCA_QCA2066, ++ .num_vregs = 0, ++}; ++ ++static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = { + .soc_type = QCA_QCA6390, + .num_vregs = 0, + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, + }; + +-static const struct qca_device_data qca_soc_data_wcn6750 = { ++static const struct qca_device_data qca_soc_data_wcn6750 __maybe_unused = { + .soc_type = QCA_WCN6750, + .vregs = (struct qca_vreg []) { + { "vddio", 5000 }, +@@ -1930,11 +2052,18 @@ static void qca_power_shutdown(struct hci_uart *hu) + + qcadev = serdev_device_get_drvdata(hu->serdev); + +- if (qca_is_wcn399x(soc_type)) { ++ switch (soc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: + host_set_baudrate(hu, 2400); + qca_send_power_pulse(hu, false); + qca_regulator_disable(qcadev); +- } else if (soc_type == QCA_WCN6750 || soc_type == QCA_WCN6855) { ++ break; ++ ++ case QCA_WCN6750: ++ case QCA_WCN6855: + gpiod_set_value_cansleep(qcadev->bt_en, 0); + msleep(100); + qca_regulator_disable(qcadev); +@@ -1942,7 +2071,9 @@ static void qca_power_shutdown(struct hci_uart *hu) + sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl); + bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state); + } +- } else if (qcadev->bt_en) { ++ break; ++ ++ default: + gpiod_set_value_cansleep(qcadev->bt_en, 0); + } + +@@ -2067,11 +2198,18 @@ static int qca_serdev_probe(struct serdev_device *serdev) + if (!qcadev->oper_speed) + BT_DBG("UART will pick default operating speed"); + +- if (data && +- (qca_is_wcn399x(data->soc_type) || +- qca_is_wcn6750(data->soc_type) || +- qca_is_wcn6855(data->soc_type))) { ++ if (data) + qcadev->btsoc_type = data->soc_type; ++ else ++ qcadev->btsoc_type = QCA_ROME; ++ ++ switch (qcadev->btsoc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: + qcadev->bt_power = devm_kzalloc(&serdev->dev, + sizeof(struct qca_power), + GFP_KERNEL); +@@ -2115,12 +2253,9 @@ static int qca_serdev_probe(struct serdev_device *serdev) + BT_ERR("wcn3990 serdev registration failed"); + return err; + } +- } else { +- if (data) +- qcadev->btsoc_type = data->soc_type; +- else +- qcadev->btsoc_type = QCA_ROME; ++ break; + ++ default: + qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", + GPIOD_OUT_LOW); + if (IS_ERR(qcadev->bt_en)) { +@@ -2176,13 +2311,23 @@ static void qca_serdev_remove(struct serdev_device *serdev) + struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); + struct qca_power *power = qcadev->bt_power; + +- if ((qca_is_wcn399x(qcadev->btsoc_type) || +- qca_is_wcn6750(qcadev->btsoc_type) || +- qca_is_wcn6855(qcadev->btsoc_type)) && +- power->vregs_on) +- qca_power_shutdown(&qcadev->serdev_hu); +- else if (qcadev->susclk) +- clk_disable_unprepare(qcadev->susclk); ++ switch (qcadev->btsoc_type) { ++ case QCA_WCN3988: ++ case QCA_WCN3990: ++ case QCA_WCN3991: ++ case QCA_WCN3998: ++ case QCA_WCN6750: ++ case QCA_WCN6855: ++ if (power->vregs_on) { ++ qca_power_shutdown(&qcadev->serdev_hu); ++ break; ++ } ++ fallthrough; ++ ++ default: ++ if (qcadev->susclk) ++ clk_disable_unprepare(qcadev->susclk); ++ } + + hci_uart_unregister_device(&qcadev->serdev_hu); + } +@@ -2356,9 +2501,11 @@ static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume); + + #ifdef CONFIG_OF + static const struct of_device_id qca_bluetooth_of_match[] = { ++ { .compatible = "qcom,qca2066-bt", .data = &qca_soc_data_qca2066}, + { .compatible = "qcom,qca6174-bt" }, + { .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390}, + { .compatible = "qcom,qca9377-bt" }, ++ { .compatible = "qcom,wcn3988-bt", .data = &qca_soc_data_wcn3988}, + { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, + { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, + { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, +@@ -2371,6 +2518,7 @@ MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); + + #ifdef CONFIG_ACPI + static const struct acpi_device_id qca_bluetooth_acpi_match[] = { ++ { "QCOM2066", (kernel_ulong_t)&qca_soc_data_qca2066 }, + { "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, +diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c +index 80a288c59e56d..8b573ff646f65 100644 +--- a/drivers/clk/sifive/sifive-prci.c ++++ b/drivers/clk/sifive/sifive-prci.c +@@ -4,7 +4,6 @@ + * Copyright (C) 2020 Zong Li + */ + +-#include <linux/clkdev.h> + #include <linux/delay.h> + #include <linux/io.h> + #include <linux/of_device.h> +@@ -541,13 +540,6 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd, + return r; + } + +- r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev)); +- if (r) { +- dev_warn(dev, "Failed to register clkdev for %s: %d\n", +- init.name, r); +- return r; +- } +- + pd->hw_clks.hws[i] = &pic->hw; + } + +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c +index 0d26eda36a526..28c167e1be426 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c +@@ -463,8 +463,10 @@ static void sec_alg_resource_free(struct sec_ctx *ctx, + + if (ctx->pbuf_supported) + sec_free_pbuf_resource(dev, qp_ctx->res); +- if (ctx->alg_type == SEC_AEAD) ++ if (ctx->alg_type == SEC_AEAD) { + sec_free_mac_resource(dev, qp_ctx->res); ++ sec_free_aiv_resource(dev, qp_ctx->res); ++ } + } + + static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx, +diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c +index 5161b73c30c43..e91aeec71c811 100644 +--- a/drivers/dma/dma-axi-dmac.c ++++ b/drivers/dma/dma-axi-dmac.c +@@ -1020,8 +1020,8 @@ static int axi_dmac_remove(struct platform_device *pdev) + { + struct axi_dmac *dmac = platform_get_drvdata(pdev); + +- of_dma_controller_free(pdev->dev.of_node); + free_irq(dmac->irq, dmac); ++ of_dma_controller_free(pdev->dev.of_node); + tasklet_kill(&dmac->chan.vchan.task); + dma_async_device_unregister(&dmac->dma_dev); + clk_disable_unprepare(dmac->clk); +diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +index cfc47efcb5d93..6715ade391aa1 100644 +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +@@ -213,6 +213,7 @@ static struct axi_dma_desc *axi_desc_alloc(u32 num) + kfree(desc); + return NULL; + } ++ desc->nr_hw_descs = num; + + return desc; + } +@@ -239,7 +240,7 @@ static struct axi_dma_lli *axi_desc_get(struct axi_dma_chan *chan, + static void axi_desc_put(struct axi_dma_desc *desc) + { + struct axi_dma_chan *chan = desc->chan; +- int count = atomic_read(&chan->descs_allocated); ++ int count = desc->nr_hw_descs; + struct axi_dma_hw_desc *hw_desc; + int descs_put; + +@@ -1049,9 +1050,6 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan) + /* Remove the completed descriptor from issued list before completing */ + list_del(&vd->node); + vchan_cookie_complete(vd); +- +- /* Submit queued descriptors after processing the completed ones */ +- axi_chan_start_first_queued(chan); + } + + out: +diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +index 380005afde160..58fc6310ee364 100644 +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +@@ -101,6 +101,7 @@ struct axi_dma_desc { + u32 completed_blocks; + u32 length; + u32 period_len; ++ u32 nr_hw_descs; + }; + + static inline struct device *dchan2dev(struct dma_chan *dchan) +diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c +index 6d6af0dc3c0ec..1296076ea217c 100644 +--- a/drivers/dma/idxd/irq.c ++++ b/drivers/dma/idxd/irq.c +@@ -233,11 +233,13 @@ static void irq_process_work_list(struct idxd_irq_entry *irq_entry) + + spin_unlock(&irq_entry->list_lock); + +- list_for_each_entry(desc, &flist, list) { ++ list_for_each_entry_safe(desc, n, &flist, list) { + /* + * Check against the original status as ABORT is software defined + * and 0xff, which DSA_COMP_STATUS_MASK can mask out. + */ ++ list_del(&desc->list); ++ + if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) { + complete_desc(desc, IDXD_COMPLETE_ABORT); + continue; +diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c +index 191b592790073..2a47b9053bad8 100644 +--- a/drivers/dma/ioat/init.c ++++ b/drivers/dma/ioat/init.c +@@ -15,7 +15,6 @@ + #include <linux/workqueue.h> + #include <linux/prefetch.h> + #include <linux/dca.h> +-#include <linux/aer.h> + #include <linux/sizes.h> + #include "dma.h" + #include "registers.h" +@@ -535,18 +534,6 @@ static int ioat_probe(struct ioatdma_device *ioat_dma) + return err; + } + +-static int ioat_register(struct ioatdma_device *ioat_dma) +-{ +- int err = dma_async_device_register(&ioat_dma->dma_dev); +- +- if (err) { +- ioat_disable_interrupts(ioat_dma); +- dma_pool_destroy(ioat_dma->completion_pool); +- } +- +- return err; +-} +- + static void ioat_dma_remove(struct ioatdma_device *ioat_dma) + { + struct dma_device *dma = &ioat_dma->dma_dev; +@@ -1181,9 +1168,9 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca) + ioat_chan->reg_base + IOAT_DCACTRL_OFFSET); + } + +- err = ioat_register(ioat_dma); ++ err = dma_async_device_register(&ioat_dma->dma_dev); + if (err) +- return err; ++ goto err_disable_interrupts; + + ioat_kobject_add(ioat_dma, &ioat_ktype); + +@@ -1191,21 +1178,30 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca) + ioat_dma->dca = ioat_dca_init(pdev, ioat_dma->reg_base); + + /* disable relaxed ordering */ +- err = pcie_capability_read_word(pdev, IOAT_DEVCTRL_OFFSET, &val16); +- if (err) +- return pcibios_err_to_errno(err); ++ err = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &val16); ++ if (err) { ++ err = pcibios_err_to_errno(err); ++ goto err_disable_interrupts; ++ } + + /* clear relaxed ordering enable */ +- val16 &= ~IOAT_DEVCTRL_ROE; +- err = pcie_capability_write_word(pdev, IOAT_DEVCTRL_OFFSET, val16); +- if (err) +- return pcibios_err_to_errno(err); ++ val16 &= ~PCI_EXP_DEVCTL_RELAX_EN; ++ err = pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, val16); ++ if (err) { ++ err = pcibios_err_to_errno(err); ++ goto err_disable_interrupts; ++ } + + if (ioat_dma->cap & IOAT_CAP_DPS) + writeb(ioat_pending_level + 1, + ioat_dma->reg_base + IOAT_PREFETCH_LIMIT_OFFSET); + + return 0; ++ ++err_disable_interrupts: ++ ioat_disable_interrupts(ioat_dma); ++ dma_pool_destroy(ioat_dma->completion_pool); ++ return err; + } + + static void ioat_shutdown(struct pci_dev *pdev) +@@ -1350,6 +1346,8 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + void __iomem * const *iomap; + struct device *dev = &pdev->dev; + struct ioatdma_device *device; ++ unsigned int i; ++ u8 version; + int err; + + err = pcim_enable_device(pdev); +@@ -1363,15 +1361,13 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (!iomap) + return -ENOMEM; + +- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); +- if (err) +- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); +- if (err) +- return err; ++ version = readb(iomap[IOAT_MMIO_BAR] + IOAT_VER_OFFSET); ++ if (version < IOAT_VER_3_0) ++ return -ENODEV; + +- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); ++ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + if (err) +- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); ++ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (err) + return err; + +@@ -1381,22 +1377,19 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + pci_set_master(pdev); + pci_set_drvdata(pdev, device); + +- device->version = readb(device->reg_base + IOAT_VER_OFFSET); ++ device->version = version; + if (device->version >= IOAT_VER_3_4) + ioat_dca_enabled = 0; +- if (device->version >= IOAT_VER_3_0) { +- if (is_skx_ioat(pdev)) +- device->version = IOAT_VER_3_2; +- err = ioat3_dma_probe(device, ioat_dca_enabled); +- +- if (device->version >= IOAT_VER_3_3) +- pci_enable_pcie_error_reporting(pdev); +- } else +- return -ENODEV; + ++ if (is_skx_ioat(pdev)) ++ device->version = IOAT_VER_3_2; ++ ++ err = ioat3_dma_probe(device, ioat_dca_enabled); + if (err) { ++ for (i = 0; i < IOAT_MAX_CHANS; i++) ++ kfree(device->idx[i]); ++ kfree(device); + dev_err(dev, "Intel(R) I/OAT DMA Engine init failed\n"); +- pci_disable_pcie_error_reporting(pdev); + return -ENODEV; + } + +@@ -1419,7 +1412,6 @@ static void ioat_remove(struct pci_dev *pdev) + device->dca = NULL; + } + +- pci_disable_pcie_error_reporting(pdev); + ioat_dma_remove(device); + } + +@@ -1458,6 +1450,7 @@ module_init(ioat_init_module); + static void __exit ioat_exit_module(void) + { + pci_unregister_driver(&ioat_pci_driver); ++ kmem_cache_destroy(ioat_sed_cache); + kmem_cache_destroy(ioat_cache); + } + module_exit(ioat_exit_module); +diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h +index f55a5f92f1857..54cf0ad39887b 100644 +--- a/drivers/dma/ioat/registers.h ++++ b/drivers/dma/ioat/registers.h +@@ -14,13 +14,6 @@ + #define IOAT_PCI_CHANERR_INT_OFFSET 0x180 + #define IOAT_PCI_CHANERRMASK_INT_OFFSET 0x184 + +-/* PCIe config registers */ +- +-/* EXPCAPID + N */ +-#define IOAT_DEVCTRL_OFFSET 0x8 +-/* relaxed ordering enable */ +-#define IOAT_DEVCTRL_ROE 0x10 +- + /* MMIO Device Registers */ + #define IOAT_CHANCNT_OFFSET 0x00 /* 8-bit */ + +diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c +index e901f8564ca0c..0ec83ba580972 100644 +--- a/drivers/firmware/efi/fdtparams.c ++++ b/drivers/firmware/efi/fdtparams.c +@@ -30,11 +30,13 @@ static __initconst const char name[][22] = { + + static __initconst const struct { + const char path[17]; ++ u8 paravirt; + const char params[PARAMCOUNT][26]; + } dt_params[] = { + { + #ifdef CONFIG_XEN // <-------17------> + .path = "/hypervisor/uefi", ++ .paravirt = 1, + .params = { + [SYSTAB] = "xen,uefi-system-table", + [MMBASE] = "xen,uefi-mmap-start", +@@ -121,6 +123,8 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) + pr_err("Can't find property '%s' in DT!\n", pname); + return 0; + } ++ if (dt_params[i].paravirt) ++ set_bit(EFI_PARAVIRT, &efi.flags); + return systab; + } + notfound: +diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c +index 2ff1883dc788d..77dd20f9df312 100644 +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -9,83 +9,11 @@ + #include <linux/kernel.h> + #include <linux/efi.h> + #include <linux/io.h> +-#include <asm/early_ioremap.h> + #include <linux/memblock.h> + #include <linux/slab.h> + +-static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size) +-{ +- return memblock_phys_alloc(size, SMP_CACHE_BYTES); +-} +- +-static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size) +-{ +- unsigned int order = get_order(size); +- struct page *p = alloc_pages(GFP_KERNEL, order); +- +- if (!p) +- return 0; +- +- return PFN_PHYS(page_to_pfn(p)); +-} +- +-void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags) +-{ +- if (flags & EFI_MEMMAP_MEMBLOCK) { +- if (slab_is_available()) +- memblock_free_late(phys, size); +- else +- memblock_free(phys, size); +- } else if (flags & EFI_MEMMAP_SLAB) { +- struct page *p = pfn_to_page(PHYS_PFN(phys)); +- unsigned int order = get_order(size); +- +- free_pages((unsigned long) page_address(p), order); +- } +-} +- +-static void __init efi_memmap_free(void) +-{ +- __efi_memmap_free(efi.memmap.phys_map, +- efi.memmap.desc_size * efi.memmap.nr_map, +- efi.memmap.flags); +-} +- +-/** +- * efi_memmap_alloc - Allocate memory for the EFI memory map +- * @num_entries: Number of entries in the allocated map. +- * @data: efi memmap installation parameters +- * +- * Depending on whether mm_init() has already been invoked or not, +- * either memblock or "normal" page allocation is used. +- * +- * Returns the physical address of the allocated memory map on +- * success, zero on failure. +- */ +-int __init efi_memmap_alloc(unsigned int num_entries, +- struct efi_memory_map_data *data) +-{ +- /* Expect allocation parameters are zero initialized */ +- WARN_ON(data->phys_map || data->size); +- +- data->size = num_entries * efi.memmap.desc_size; +- data->desc_version = efi.memmap.desc_version; +- data->desc_size = efi.memmap.desc_size; +- data->flags &= ~(EFI_MEMMAP_SLAB | EFI_MEMMAP_MEMBLOCK); +- data->flags |= efi.memmap.flags & EFI_MEMMAP_LATE; +- +- if (slab_is_available()) { +- data->flags |= EFI_MEMMAP_SLAB; +- data->phys_map = __efi_memmap_alloc_late(data->size); +- } else { +- data->flags |= EFI_MEMMAP_MEMBLOCK; +- data->phys_map = __efi_memmap_alloc_early(data->size); +- } +- +- if (!data->phys_map) +- return -ENOMEM; +- return 0; +-} ++#include <asm/early_ioremap.h> ++#include <asm/efi.h> + + /** + * __efi_memmap_init - Common code for mapping the EFI memory map +@@ -102,14 +30,11 @@ int __init efi_memmap_alloc(unsigned int num_entries, + * + * Returns zero on success, a negative error code on failure. + */ +-static int __init __efi_memmap_init(struct efi_memory_map_data *data) ++int __init __efi_memmap_init(struct efi_memory_map_data *data) + { + struct efi_memory_map map; + phys_addr_t phys_map; + +- if (efi_enabled(EFI_PARAVIRT)) +- return 0; +- + phys_map = data->phys_map; + + if (data->flags & EFI_MEMMAP_LATE) +@@ -122,9 +47,6 @@ static int __init __efi_memmap_init(struct efi_memory_map_data *data) + return -ENOMEM; + } + +- /* NOP if data->flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB) == 0 */ +- efi_memmap_free(); +- + map.phys_map = data->phys_map; + map.nr_map = data->size / data->desc_size; + map.map_end = map.map + data->size; +@@ -221,158 +143,3 @@ int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size) + + return __efi_memmap_init(&data); + } +- +-/** +- * efi_memmap_install - Install a new EFI memory map in efi.memmap +- * @ctx: map allocation parameters (address, size, flags) +- * +- * Unlike efi_memmap_init_*(), this function does not allow the caller +- * to switch from early to late mappings. It simply uses the existing +- * mapping function and installs the new memmap. +- * +- * Returns zero on success, a negative error code on failure. +- */ +-int __init efi_memmap_install(struct efi_memory_map_data *data) +-{ +- efi_memmap_unmap(); +- +- return __efi_memmap_init(data); +-} +- +-/** +- * efi_memmap_split_count - Count number of additional EFI memmap entries +- * @md: EFI memory descriptor to split +- * @range: Address range (start, end) to split around +- * +- * Returns the number of additional EFI memmap entries required to +- * accomodate @range. +- */ +-int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range) +-{ +- u64 m_start, m_end; +- u64 start, end; +- int count = 0; +- +- start = md->phys_addr; +- end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; +- +- /* modifying range */ +- m_start = range->start; +- m_end = range->end; +- +- if (m_start <= start) { +- /* split into 2 parts */ +- if (start < m_end && m_end < end) +- count++; +- } +- +- if (start < m_start && m_start < end) { +- /* split into 3 parts */ +- if (m_end < end) +- count += 2; +- /* split into 2 parts */ +- if (end <= m_end) +- count++; +- } +- +- return count; +-} +- +-/** +- * efi_memmap_insert - Insert a memory region in an EFI memmap +- * @old_memmap: The existing EFI memory map structure +- * @buf: Address of buffer to store new map +- * @mem: Memory map entry to insert +- * +- * It is suggested that you call efi_memmap_split_count() first +- * to see how large @buf needs to be. +- */ +-void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, +- struct efi_mem_range *mem) +-{ +- u64 m_start, m_end, m_attr; +- efi_memory_desc_t *md; +- u64 start, end; +- void *old, *new; +- +- /* modifying range */ +- m_start = mem->range.start; +- m_end = mem->range.end; +- m_attr = mem->attribute; +- +- /* +- * The EFI memory map deals with regions in EFI_PAGE_SIZE +- * units. Ensure that the region described by 'mem' is aligned +- * correctly. +- */ +- if (!IS_ALIGNED(m_start, EFI_PAGE_SIZE) || +- !IS_ALIGNED(m_end + 1, EFI_PAGE_SIZE)) { +- WARN_ON(1); +- return; +- } +- +- for (old = old_memmap->map, new = buf; +- old < old_memmap->map_end; +- old += old_memmap->desc_size, new += old_memmap->desc_size) { +- +- /* copy original EFI memory descriptor */ +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- start = md->phys_addr; +- end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; +- +- if (m_start <= start && end <= m_end) +- md->attribute |= m_attr; +- +- if (m_start <= start && +- (start < m_end && m_end < end)) { +- /* first part */ +- md->attribute |= m_attr; +- md->num_pages = (m_end - md->phys_addr + 1) >> +- EFI_PAGE_SHIFT; +- /* latter part */ +- new += old_memmap->desc_size; +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- md->phys_addr = m_end + 1; +- md->num_pages = (end - md->phys_addr + 1) >> +- EFI_PAGE_SHIFT; +- } +- +- if ((start < m_start && m_start < end) && m_end < end) { +- /* first part */ +- md->num_pages = (m_start - md->phys_addr) >> +- EFI_PAGE_SHIFT; +- /* middle part */ +- new += old_memmap->desc_size; +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- md->attribute |= m_attr; +- md->phys_addr = m_start; +- md->num_pages = (m_end - m_start + 1) >> +- EFI_PAGE_SHIFT; +- /* last part */ +- new += old_memmap->desc_size; +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- md->phys_addr = m_end + 1; +- md->num_pages = (end - m_end) >> +- EFI_PAGE_SHIFT; +- } +- +- if ((start < m_start && m_start < end) && +- (end <= m_end)) { +- /* first part */ +- md->num_pages = (m_start - md->phys_addr) >> +- EFI_PAGE_SHIFT; +- /* latter part */ +- new += old_memmap->desc_size; +- memcpy(new, old, old_memmap->desc_size); +- md = new; +- md->phys_addr = m_start; +- md->num_pages = (end - md->phys_addr + 1) >> +- EFI_PAGE_SHIFT; +- md->attribute |= m_attr; +- } +- } +-} +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index 7b9def6b10047..a36afb47a6334 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -1396,7 +1396,7 @@ config GPIO_TPS68470 + drivers are loaded. + + config GPIO_TQMX86 +- tristate "TQ-Systems QTMX86 GPIO" ++ tristate "TQ-Systems TQMx86 GPIO" + depends on MFD_TQMX86 || COMPILE_TEST + depends on HAS_IOPORT_MAP + select GPIOLIB_IRQCHIP +diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c +index 0214244e9f01f..d691e2ed88a08 100644 +--- a/drivers/gpio/gpio-davinci.c ++++ b/drivers/gpio/gpio-davinci.c +@@ -227,6 +227,11 @@ static int davinci_gpio_probe(struct platform_device *pdev) + else + nirq = DIV_ROUND_UP(ngpio, 16); + ++ if (nirq > MAX_INT_PER_BANK) { ++ dev_err(dev, "Too many IRQs!\n"); ++ return -EINVAL; ++ } ++ + chips = devm_kzalloc(dev, sizeof(*chips), GFP_KERNEL); + if (!chips) + return -ENOMEM; +diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c +index 5b103221b58dd..02cf4e258bfd2 100644 +--- a/drivers/gpio/gpio-tqmx86.c ++++ b/drivers/gpio/gpio-tqmx86.c +@@ -27,16 +27,20 @@ + #define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */ + #define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */ + ++#define TQMX86_GPII_NONE 0 + #define TQMX86_GPII_FALLING BIT(0) + #define TQMX86_GPII_RISING BIT(1) + #define TQMX86_GPII_MASK (BIT(0) | BIT(1)) + #define TQMX86_GPII_BITS 2 ++/* Stored in irq_type with GPII bits */ ++#define TQMX86_INT_UNMASKED BIT(2) + + struct tqmx86_gpio_data { + struct gpio_chip chip; + struct irq_chip irq_chip; + void __iomem *io_base; + int irq; ++ /* Lock must be held for accessing output and irq_type fields */ + raw_spinlock_t spinlock; + u8 irq_type[TQMX86_NGPI]; + }; +@@ -107,20 +111,30 @@ static int tqmx86_gpio_get_direction(struct gpio_chip *chip, + return GPIO_LINE_DIRECTION_OUT; + } + ++static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset) ++ __must_hold(&gpio->spinlock) ++{ ++ u8 type = TQMX86_GPII_NONE, gpiic; ++ ++ if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) ++ type = gpio->irq_type[offset] & TQMX86_GPII_MASK; ++ ++ gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); ++ gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS)); ++ gpiic |= type << (offset * TQMX86_GPII_BITS); ++ tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); ++} ++ + static void tqmx86_gpio_irq_mask(struct irq_data *data) + { + unsigned int offset = (data->hwirq - TQMX86_NGPO); + struct tqmx86_gpio_data *gpio = gpiochip_get_data( + irq_data_get_irq_chip_data(data)); + unsigned long flags; +- u8 gpiic, mask; +- +- mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS); + + raw_spin_lock_irqsave(&gpio->spinlock, flags); +- gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); +- gpiic &= ~mask; +- tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); ++ gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED; ++ tqmx86_gpio_irq_config(gpio, offset); + raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + } + +@@ -130,15 +144,10 @@ static void tqmx86_gpio_irq_unmask(struct irq_data *data) + struct tqmx86_gpio_data *gpio = gpiochip_get_data( + irq_data_get_irq_chip_data(data)); + unsigned long flags; +- u8 gpiic, mask; +- +- mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS); + + raw_spin_lock_irqsave(&gpio->spinlock, flags); +- gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); +- gpiic &= ~mask; +- gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS); +- tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); ++ gpio->irq_type[offset] |= TQMX86_INT_UNMASKED; ++ tqmx86_gpio_irq_config(gpio, offset); + raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + } + +@@ -149,7 +158,7 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type) + unsigned int offset = (data->hwirq - TQMX86_NGPO); + unsigned int edge_type = type & IRQF_TRIGGER_MASK; + unsigned long flags; +- u8 new_type, gpiic; ++ u8 new_type; + + switch (edge_type) { + case IRQ_TYPE_EDGE_RISING: +@@ -165,13 +174,10 @@ static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type) + return -EINVAL; /* not supported */ + } + +- gpio->irq_type[offset] = new_type; +- + raw_spin_lock_irqsave(&gpio->spinlock, flags); +- gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); +- gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS)); +- gpiic |= new_type << (offset * TQMX86_GPII_BITS); +- tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); ++ gpio->irq_type[offset] &= ~TQMX86_GPII_MASK; ++ gpio->irq_type[offset] |= new_type; ++ tqmx86_gpio_irq_config(gpio, offset); + raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + + return 0; +diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c +index 1db991cb2efce..c2f9d95d1086f 100644 +--- a/drivers/gpio/gpiolib-cdev.c ++++ b/drivers/gpio/gpiolib-cdev.c +@@ -127,6 +127,10 @@ struct linehandle_state { + GPIOHANDLE_REQUEST_OPEN_DRAIN | \ + GPIOHANDLE_REQUEST_OPEN_SOURCE) + ++#define GPIOHANDLE_REQUEST_DIRECTION_FLAGS \ ++ (GPIOHANDLE_REQUEST_INPUT | \ ++ GPIOHANDLE_REQUEST_OUTPUT) ++ + static int linehandle_validate_flags(u32 flags) + { + /* Return an error if an unknown flag is set */ +@@ -207,21 +211,21 @@ static long linehandle_set_config(struct linehandle_state *lh, + if (ret) + return ret; + ++ /* Lines must be reconfigured explicitly as input or output. */ ++ if (!(lflags & GPIOHANDLE_REQUEST_DIRECTION_FLAGS)) ++ return -EINVAL; ++ + for (i = 0; i < lh->num_descs; i++) { + desc = lh->descs[i]; +- linehandle_flags_to_desc_flags(gcnf.flags, &desc->flags); ++ linehandle_flags_to_desc_flags(lflags, &desc->flags); + +- /* +- * Lines have to be requested explicitly for input +- * or output, else the line will be treated "as is". +- */ + if (lflags & GPIOHANDLE_REQUEST_OUTPUT) { + int val = !!gcnf.default_values[i]; + + ret = gpiod_direction_output(desc, val); + if (ret) + return ret; +- } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { ++ } else { + ret = gpiod_direction_input(desc); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +index 083f9c637a82e..fdb03d411195e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +@@ -2,6 +2,7 @@ + + #include <drm/drm_atomic_helper.h> + #include <drm/drm_simple_kms_helper.h> ++#include <drm/drm_gem_framebuffer_helper.h> + #include <drm/drm_vblank.h> + + #include "amdgpu.h" +@@ -315,7 +316,13 @@ static int amdgpu_vkms_prepare_fb(struct drm_plane *plane, + return 0; + } + afb = to_amdgpu_framebuffer(new_state->fb); +- obj = new_state->fb->obj[0]; ++ ++ obj = drm_gem_fb_get_obj(new_state->fb, 0); ++ if (!obj) { ++ DRM_ERROR("Failed to get obj from framebuffer\n"); ++ return -EINVAL; ++ } ++ + rbo = gem_to_amdgpu_bo(obj); + adev = amdgpu_ttm_adev(rbo->tbo.bdev); + INIT_LIST_HEAD(&list); +@@ -364,12 +371,19 @@ static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane, + struct drm_plane_state *old_state) + { + struct amdgpu_bo *rbo; ++ struct drm_gem_object *obj; + int r; + + if (!old_state->fb) + return; + +- rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]); ++ obj = drm_gem_fb_get_obj(old_state->fb, 0); ++ if (!obj) { ++ DRM_ERROR("Failed to get obj from framebuffer\n"); ++ return; ++ } ++ ++ rbo = gem_to_amdgpu_bo(obj); + r = amdgpu_bo_reserve(rbo, false); + if (unlikely(r)) { + DRM_ERROR("failed to reserve rbo before unpin\n"); +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +index ed2f6802b0e20..8ccd43ec68829 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +@@ -1315,14 +1315,11 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; +- } +- +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + + dsc = pipe_ctx->stream_res.dsc; +@@ -1421,12 +1418,14 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + +- if (!pipe_ctx || !pipe_ctx->stream) ++ if (!pipe_ctx->stream) + goto done; + + // Get CRTC state +@@ -1506,14 +1505,11 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; +- } +- +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + + dsc = pipe_ctx->stream_res.dsc; +@@ -1610,12 +1606,14 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + +- if (!pipe_ctx || !pipe_ctx->stream) ++ if (!pipe_ctx->stream) + goto done; + + // Safely get CRTC state +@@ -1695,14 +1693,11 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; +- } +- +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + + dsc = pipe_ctx->stream_res.dsc; +@@ -1799,12 +1794,14 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + +- if (!pipe_ctx || !pipe_ctx->stream) ++ if (!pipe_ctx->stream) + goto done; + + // Get CRTC state +@@ -1880,14 +1877,11 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; +- } +- +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + + dsc = pipe_ctx->stream_res.dsc; +@@ -1981,12 +1975,14 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + +- if (!pipe_ctx || !pipe_ctx->stream) ++ if (!pipe_ctx->stream) + goto done; + + // Get CRTC state +@@ -2060,14 +2056,11 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; +- } +- +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + + dsc = pipe_ctx->stream_res.dsc; +@@ -2121,14 +2114,11 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; +- } +- +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + + dsc = pipe_ctx->stream_res.dsc; +@@ -2197,14 +2187,11 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; +- } +- +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + + dsc = pipe_ctx->stream_res.dsc; +@@ -2273,14 +2260,11 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf, + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; +- if (pipe_ctx && pipe_ctx->stream && +- pipe_ctx->stream->link == aconnector->dc_link) +- break; +- } +- +- if (!pipe_ctx) { +- kfree(rd_buf); +- return -ENXIO; ++ if (pipe_ctx->stream && ++ pipe_ctx->stream->link == aconnector->dc_link && ++ pipe_ctx->stream->sink && ++ pipe_ctx->stream->sink == aconnector->dc_sink) ++ break; + } + + dsc = pipe_ctx->stream_res.dsc; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +index cf364ae931386..d0799c426a84d 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +@@ -644,6 +644,12 @@ void enc1_stream_encoder_set_throttled_vcp_size( + x), + 26)); + ++ // If y rounds up to integer, carry it over to x. ++ if (y >> 26) { ++ x += 1; ++ y = 0; ++ } ++ + REG_SET_2(DP_MSE_RATE_CNTL, 0, + DP_MSE_RATE_X, x, + DP_MSE_RATE_Y, y); +diff --git a/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c b/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c +index b56854c03ead6..4291bf09fc7b4 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c +@@ -163,6 +163,8 @@ static void sumo_construct_vid_mapping_table(struct amdgpu_device *adev, + + for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { + if (table[i].ulSupportedSCLK != 0) { ++ if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) ++ continue; + vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = + table[i].usVoltageID; + vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = +diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +index 88b58153f9d66..c956fda918beb 100644 +--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c ++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +@@ -259,7 +259,7 @@ komeda_component_get_avail_scaler(struct komeda_component *c, + u32 avail_scalers; + + pipe_st = komeda_pipeline_get_state(c->pipeline, state); +- if (!pipe_st) ++ if (IS_ERR_OR_NULL(pipe_st)) + return NULL; + + avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^ +diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c +index b32295abd9e75..e67bcbef0e8ed 100644 +--- a/drivers/gpu/drm/bridge/panel.c ++++ b/drivers/gpu/drm/bridge/panel.c +@@ -253,9 +253,12 @@ EXPORT_SYMBOL(drm_panel_bridge_remove); + + static void devm_drm_panel_bridge_release(struct device *dev, void *res) + { +- struct drm_bridge **bridge = res; ++ struct drm_bridge *bridge = *(struct drm_bridge **)res; + +- drm_panel_bridge_remove(*bridge); ++ if (!bridge) ++ return; ++ ++ drm_bridge_remove(bridge); + } + + /** +diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c +index e1ffe8a28b649..d87ab8ecb0233 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c +@@ -308,6 +308,7 @@ static int vidi_get_modes(struct drm_connector *connector) + struct vidi_context *ctx = ctx_from_connector(connector); + struct edid *edid; + int edid_len; ++ int count; + + /* + * the edid data comes from user side and it would be set +@@ -327,7 +328,11 @@ static int vidi_get_modes(struct drm_connector *connector) + + drm_connector_update_edid_property(connector, edid); + +- return drm_add_edid_modes(connector, edid); ++ count = drm_add_edid_modes(connector, edid); ++ ++ kfree(edid); ++ ++ return count; + } + + static const struct drm_connector_helper_funcs vidi_connector_helper_funcs = { +diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c +index 35be9f024518d..83bd7c50fdf98 100644 +--- a/drivers/gpu/drm/exynos/exynos_hdmi.c ++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c +@@ -887,11 +887,11 @@ static int hdmi_get_modes(struct drm_connector *connector) + int ret; + + if (!hdata->ddc_adpt) +- return 0; ++ goto no_edid; + + edid = drm_get_edid(connector, hdata->ddc_adpt); + if (!edid) +- return 0; ++ goto no_edid; + + hdata->dvi_mode = !drm_detect_hdmi_monitor(edid); + DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n", +@@ -906,6 +906,9 @@ static int hdmi_get_modes(struct drm_connector *connector) + kfree(edid); + + return ret; ++ ++no_edid: ++ return drm_add_modes_noedid(connector, 640, 480); + } + + static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index a0c04b9d9c739..7a3abeca4e518 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -226,6 +226,10 @@ bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp) + struct intel_encoder *encoder = &intel_dig_port->base; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + ++ /* eDP MSO is not compatible with joiner */ ++ if (intel_dp->mso_link_count) ++ return false; ++ + return DISPLAY_VER(dev_priv) >= 12 || + (DISPLAY_VER(dev_priv) == 11 && + encoder->port != PORT_A); +diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +index 209cf265bf746..56985edda8baf 100644 +--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c ++++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +@@ -257,8 +257,13 @@ static void signal_irq_work(struct irq_work *work) + i915_request_put(rq); + } + ++ /* Lazy irq enabling after HW submission */ + if (!READ_ONCE(b->irq_armed) && !list_empty(&b->signalers)) + intel_breadcrumbs_arm_irq(b); ++ ++ /* And confirm that we still want irqs enabled before we yield */ ++ if (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) ++ intel_breadcrumbs_disarm_irq(b); + } + + struct intel_breadcrumbs * +@@ -309,13 +314,7 @@ void __intel_breadcrumbs_park(struct intel_breadcrumbs *b) + return; + + /* Kick the work once more to drain the signalers, and disarm the irq */ +- irq_work_sync(&b->irq_work); +- while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) { +- local_irq_disable(); +- signal_irq_work(&b->irq_work); +- local_irq_enable(); +- cond_resched(); +- } ++ irq_work_queue(&b->irq_work); + } + + void intel_breadcrumbs_free(struct kref *kref) +@@ -398,7 +397,8 @@ static void insert_breadcrumb(struct i915_request *rq) + * the request as it may have completed and raised the interrupt as + * we were attaching it into the lists. + */ +- irq_work_queue(&b->irq_work); ++ if (!READ_ONCE(b->irq_armed) || __i915_request_is_complete(rq)) ++ irq_work_queue(&b->irq_work); + } + + bool i915_request_enable_breadcrumb(struct i915_request *rq) +diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +index f8948de720360..99efb33ebd6f0 100644 +--- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c ++++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +@@ -291,6 +291,7 @@ void i915_vma_revoke_fence(struct i915_vma *vma) + return; + + GEM_BUG_ON(fence->vma != vma); ++ i915_active_wait(&fence->active); + GEM_BUG_ON(!i915_active_is_idle(&fence->active)); + GEM_BUG_ON(atomic_read(&fence->pin_count)); + +diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c +index fbc43f243c54d..6d000504e1a4e 100644 +--- a/drivers/gpu/drm/lima/lima_bcast.c ++++ b/drivers/gpu/drm/lima/lima_bcast.c +@@ -43,6 +43,18 @@ void lima_bcast_suspend(struct lima_ip *ip) + + } + ++int lima_bcast_mask_irq(struct lima_ip *ip) ++{ ++ bcast_write(LIMA_BCAST_BROADCAST_MASK, 0); ++ bcast_write(LIMA_BCAST_INTERRUPT_MASK, 0); ++ return 0; ++} ++ ++int lima_bcast_reset(struct lima_ip *ip) ++{ ++ return lima_bcast_hw_init(ip); ++} ++ + int lima_bcast_init(struct lima_ip *ip) + { + int i; +diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h +index 465ee587bceb2..cd08841e47879 100644 +--- a/drivers/gpu/drm/lima/lima_bcast.h ++++ b/drivers/gpu/drm/lima/lima_bcast.h +@@ -13,4 +13,7 @@ void lima_bcast_fini(struct lima_ip *ip); + + void lima_bcast_enable(struct lima_device *dev, int num_pp); + ++int lima_bcast_mask_irq(struct lima_ip *ip); ++int lima_bcast_reset(struct lima_ip *ip); ++ + #endif +diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c +index 8dd501b7a3d0d..6cf46b653e810 100644 +--- a/drivers/gpu/drm/lima/lima_gp.c ++++ b/drivers/gpu/drm/lima/lima_gp.c +@@ -212,6 +212,13 @@ static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe) + lima_sched_pipe_task_done(pipe); + } + ++static void lima_gp_task_mask_irq(struct lima_sched_pipe *pipe) ++{ ++ struct lima_ip *ip = pipe->processor[0]; ++ ++ gp_write(LIMA_GP_INT_MASK, 0); ++} ++ + static int lima_gp_task_recover(struct lima_sched_pipe *pipe) + { + struct lima_ip *ip = pipe->processor[0]; +@@ -344,6 +351,7 @@ int lima_gp_pipe_init(struct lima_device *dev) + pipe->task_error = lima_gp_task_error; + pipe->task_mmu_error = lima_gp_task_mmu_error; + pipe->task_recover = lima_gp_task_recover; ++ pipe->task_mask_irq = lima_gp_task_mask_irq; + + return 0; + } +diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c +index a5c95bed08c09..54b208a4a768e 100644 +--- a/drivers/gpu/drm/lima/lima_pp.c ++++ b/drivers/gpu/drm/lima/lima_pp.c +@@ -408,6 +408,9 @@ static void lima_pp_task_error(struct lima_sched_pipe *pipe) + + lima_pp_hard_reset(ip); + } ++ ++ if (pipe->bcast_processor) ++ lima_bcast_reset(pipe->bcast_processor); + } + + static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe) +@@ -416,6 +419,20 @@ static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe) + lima_sched_pipe_task_done(pipe); + } + ++static void lima_pp_task_mask_irq(struct lima_sched_pipe *pipe) ++{ ++ int i; ++ ++ for (i = 0; i < pipe->num_processor; i++) { ++ struct lima_ip *ip = pipe->processor[i]; ++ ++ pp_write(LIMA_PP_INT_MASK, 0); ++ } ++ ++ if (pipe->bcast_processor) ++ lima_bcast_mask_irq(pipe->bcast_processor); ++} ++ + static struct kmem_cache *lima_pp_task_slab; + static int lima_pp_task_slab_refcnt; + +@@ -447,6 +464,7 @@ int lima_pp_pipe_init(struct lima_device *dev) + pipe->task_fini = lima_pp_task_fini; + pipe->task_error = lima_pp_task_error; + pipe->task_mmu_error = lima_pp_task_mmu_error; ++ pipe->task_mask_irq = lima_pp_task_mask_irq; + + return 0; + } +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index 2e817dbdcad75..a7572123fee15 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -421,6 +421,13 @@ static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job + struct lima_sched_task *task = to_lima_task(job); + struct lima_device *ldev = pipe->ldev; + ++ /* ++ * The task might still finish while this timeout handler runs. ++ * To prevent a race condition on its completion, mask all irqs ++ * on the running core until the next hard reset completes. ++ */ ++ pipe->task_mask_irq(pipe); ++ + if (!pipe->error) + DRM_ERROR("lima job timeout\n"); + +diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h +index 90f03c48ef4a8..f8bbfa69baea6 100644 +--- a/drivers/gpu/drm/lima/lima_sched.h ++++ b/drivers/gpu/drm/lima/lima_sched.h +@@ -83,6 +83,7 @@ struct lima_sched_pipe { + void (*task_error)(struct lima_sched_pipe *pipe); + void (*task_mmu_error)(struct lima_sched_pipe *pipe); + int (*task_recover)(struct lima_sched_pipe *pipe); ++ void (*task_mask_irq)(struct lima_sched_pipe *pipe); + + struct work_struct recover_work; + }; +diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +index be28e7bd74903..1da9d1e89f91b 100644 +--- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c ++++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +@@ -208,6 +208,8 @@ static int nv17_tv_get_ld_modes(struct drm_encoder *encoder, + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(encoder->dev, tv_mode); ++ if (!mode) ++ continue; + + mode->clock = tv_norm->tv_enc_mode.vrefresh * + mode->htotal / 1000 * +@@ -257,6 +259,8 @@ static int nv17_tv_get_hd_modes(struct drm_encoder *encoder, + if (modes[i].hdisplay == output_mode->hdisplay && + modes[i].vdisplay == output_mode->vdisplay) { + mode = drm_mode_duplicate(encoder->dev, output_mode); ++ if (!mode) ++ continue; + mode->type |= DRM_MODE_TYPE_PREFERRED; + + } else { +@@ -264,6 +268,8 @@ static int nv17_tv_get_hd_modes(struct drm_encoder *encoder, + modes[i].vdisplay, 60, false, + (output_mode->flags & + DRM_MODE_FLAG_INTERLACE), false); ++ if (!mode) ++ continue; + } + + /* CVT modes are sometimes unsuitable... */ +diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +index 534dd7414d428..917cb322bab1a 100644 +--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c ++++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +@@ -506,10 +506,10 @@ static int ili9881c_prepare(struct drm_panel *panel) + msleep(5); + + /* And reset it */ +- gpiod_set_value(ctx->reset, 1); ++ gpiod_set_value_cansleep(ctx->reset, 1); + msleep(20); + +- gpiod_set_value(ctx->reset, 0); ++ gpiod_set_value_cansleep(ctx->reset, 0); + msleep(20); + + for (i = 0; i < ctx->desc->init_length; i++) { +@@ -564,7 +564,7 @@ static int ili9881c_unprepare(struct drm_panel *panel) + + mipi_dsi_dcs_enter_sleep_mode(ctx->dsi); + regulator_disable(ctx->power); +- gpiod_set_value(ctx->reset, 1); ++ gpiod_set_value_cansleep(ctx->reset, 1); + + return 0; + } +diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c +index 0dc4d891fedc2..26c99ffe787cd 100644 +--- a/drivers/gpu/drm/panel/panel-simple.c ++++ b/drivers/gpu/drm/panel/panel-simple.c +@@ -2873,6 +2873,7 @@ static const struct display_timing koe_tx26d202vm0bwa_timing = { + .vfront_porch = { 3, 5, 10 }, + .vback_porch = { 2, 5, 10 }, + .vsync_len = { 5, 5, 5 }, ++ .flags = DISPLAY_FLAGS_DE_HIGH, + }; + + static const struct panel_desc koe_tx26d202vm0bwa = { +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 895776c421d4d..71037061a317b 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -132,7 +132,6 @@ extern int radeon_cik_support; + /* RADEON_IB_POOL_SIZE must be a power of 2 */ + #define RADEON_IB_POOL_SIZE 16 + #define RADEON_DEBUGFS_MAX_COMPONENTS 32 +-#define RADEONFB_CONN_LIMIT 4 + #define RADEON_BIOS_NUM_SCRATCH 8 + + /* internal ring indices */ +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index 6337fad441df3..05c88e41663ee 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -677,7 +677,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) + struct radeon_device *rdev = dev->dev_private; + struct radeon_crtc *radeon_crtc; + +- radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); ++ radeon_crtc = kzalloc(sizeof(*radeon_crtc), GFP_KERNEL); + if (radeon_crtc == NULL) + return; + +@@ -703,12 +703,6 @@ static void radeon_crtc_init(struct drm_device *dev, int index) + dev->mode_config.cursor_width = radeon_crtc->max_cursor_width; + dev->mode_config.cursor_height = radeon_crtc->max_cursor_height; + +-#if 0 +- radeon_crtc->mode_set.crtc = &radeon_crtc->base; +- radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); +- radeon_crtc->mode_set.num_connectors = 0; +-#endif +- + if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom)) + radeon_atombios_init_crtc(dev, radeon_crtc); + else +diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c +index d49c145db4370..f7f1ddc6cdd81 100644 +--- a/drivers/gpu/drm/radeon/sumo_dpm.c ++++ b/drivers/gpu/drm/radeon/sumo_dpm.c +@@ -1621,6 +1621,8 @@ void sumo_construct_vid_mapping_table(struct radeon_device *rdev, + + for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { + if (table[i].ulSupportedSCLK != 0) { ++ if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) ++ continue; + vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = + table[i].usVoltageID; + vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 8449d09c06f7a..0f09a9116b054 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -904,13 +904,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) + vmw_read(dev_priv, + SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); + +- /* +- * Workaround for low memory 2D VMs to compensate for the +- * allocation taken by fbdev +- */ +- if (!(dev_priv->capabilities & SVGA_CAP_3D)) +- mem_size *= 3; +- + dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE; + dev_priv->max_primary_mem = + vmw_read(dev_priv, SVGA_REG_MAX_PRIMARY_MEM); +diff --git a/drivers/greybus/interface.c b/drivers/greybus/interface.c +index 9ec949a438ef6..52ef6be9d4499 100644 +--- a/drivers/greybus/interface.c ++++ b/drivers/greybus/interface.c +@@ -694,6 +694,7 @@ static void gb_interface_release(struct device *dev) + + trace_gb_interface_release(intf); + ++ cancel_work_sync(&intf->mode_switch_work); + kfree(intf); + } + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 7b76405df8c47..15f4a80477974 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1446,7 +1446,6 @@ static void implement(const struct hid_device *hid, u8 *report, + hid_warn(hid, + "%s() called with too large value %d (n: %d)! (%s)\n", + __func__, value, n, current->comm); +- WARN_ON(1); + value &= m; + } + } +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 7b1fdfde5b405..0504bdd465013 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -777,6 +777,7 @@ + #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e + #define USB_DEVICE_ID_LOGITECH_T651 0xb00c + #define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD 0xb309 ++#define USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD 0xbb00 + #define USB_DEVICE_ID_LOGITECH_C007 0xc007 + #define USB_DEVICE_ID_LOGITECH_C077 0xc077 + #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 +diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c +index 57697605b2e24..dc7b0fe83478e 100644 +--- a/drivers/hid/hid-logitech-dj.c ++++ b/drivers/hid/hid-logitech-dj.c +@@ -1284,8 +1284,10 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, + */ + msleep(50); + +- if (retval) ++ if (retval) { ++ kfree(dj_report); + return retval; ++ } + } + + /* +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 2e14e3071aa69..fea27d66d91c0 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -2082,6 +2082,12 @@ static const struct hid_device_id mt_devices[] = { + USB_VENDOR_ID_LENOVO, + USB_DEVICE_ID_LENOVO_X12_TAB) }, + ++ /* Logitech devices */ ++ { .driver_data = MT_CLS_NSMU, ++ HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8, ++ USB_VENDOR_ID_LOGITECH, ++ USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) }, ++ + /* MosArt panels */ + { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, + MT_USB_DEVICE(USB_VENDOR_ID_ASUS, +diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c +index 648893f9e4b67..8dad239aba2ce 100644 +--- a/drivers/hwtracing/intel_th/pci.c ++++ b/drivers/hwtracing/intel_th/pci.c +@@ -294,6 +294,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xae24), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, ++ { ++ /* Meteor Lake-S */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7f26), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, + { + /* Raptor Lake-S */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26), +@@ -304,6 +309,26 @@ static const struct pci_device_id intel_th_pci_id_table[] = { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa76f), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, ++ { ++ /* Granite Rapids */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0963), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, ++ { ++ /* Granite Rapids SOC */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3256), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, ++ { ++ /* Sapphire Rapids SOC */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3456), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, ++ { ++ /* Lunar Lake */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa824), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, + { + /* Alder Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f), +diff --git a/drivers/i2c/busses/i2c-at91-slave.c b/drivers/i2c/busses/i2c-at91-slave.c +index d6eeea5166c04..131a67d9d4a68 100644 +--- a/drivers/i2c/busses/i2c-at91-slave.c ++++ b/drivers/i2c/busses/i2c-at91-slave.c +@@ -106,8 +106,7 @@ static int at91_unreg_slave(struct i2c_client *slave) + + static u32 at91_twi_func(struct i2c_adapter *adapter) + { +- return I2C_FUNC_SLAVE | I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL +- | I2C_FUNC_SMBUS_READ_BLOCK_DATA; ++ return I2C_FUNC_SLAVE; + } + + static const struct i2c_algorithm at91_twi_algorithm_slave = { +diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c +index 0d15f4c1e9f7e..5b54a9b9ed1a3 100644 +--- a/drivers/i2c/busses/i2c-designware-slave.c ++++ b/drivers/i2c/busses/i2c-designware-slave.c +@@ -232,7 +232,7 @@ static const struct i2c_algorithm i2c_dw_algo = { + + void i2c_dw_configure_slave(struct dw_i2c_dev *dev) + { +- dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY; ++ dev->functionality = I2C_FUNC_SLAVE; + + dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL | + DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED; +diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c +index 2e575856c5cd5..a2977ef5d1d41 100644 +--- a/drivers/i2c/busses/i2c-ocores.c ++++ b/drivers/i2c/busses/i2c-ocores.c +@@ -442,8 +442,8 @@ static int ocores_init(struct device *dev, struct ocores_i2c *i2c) + oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); + + /* Init the device */ +- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); ++ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + + return 0; + } +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index 546cc935e035a..6ce05441178a3 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -421,18 +421,12 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle); + + static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) + { +- struct device *dev; +- struct i2c_client *client; +- +- dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); +- if (!dev) +- return NULL; +- +- client = i2c_verify_client(dev); +- if (!client) +- put_device(dev); ++ return i2c_find_device_by_fwnode(acpi_fwnode_handle(adev)); ++} + +- return client; ++static struct i2c_adapter *i2c_acpi_find_adapter_by_adev(struct acpi_device *adev) ++{ ++ return i2c_find_adapter_by_fwnode(acpi_fwnode_handle(adev)); + } + + static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, +@@ -461,11 +455,17 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, + break; + + client = i2c_acpi_find_client_by_adev(adev); +- if (!client) +- break; ++ if (client) { ++ i2c_unregister_device(client); ++ put_device(&client->dev); ++ } ++ ++ adapter = i2c_acpi_find_adapter_by_adev(adev); ++ if (adapter) { ++ acpi_unbind_one(&adapter->dev); ++ put_device(&adapter->dev); ++ } + +- i2c_unregister_device(client); +- put_device(&client->dev); + break; + } + +diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c +index 1810a994c07ca..505eebbc98a09 100644 +--- a/drivers/i2c/i2c-core-base.c ++++ b/drivers/i2c/i2c-core-base.c +@@ -1009,6 +1009,35 @@ void i2c_unregister_device(struct i2c_client *client) + } + EXPORT_SYMBOL_GPL(i2c_unregister_device); + ++/** ++ * i2c_find_device_by_fwnode() - find an i2c_client for the fwnode ++ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_client ++ * ++ * Look up and return the &struct i2c_client corresponding to the @fwnode. ++ * If no client can be found, or @fwnode is NULL, this returns NULL. ++ * ++ * The user must call put_device(&client->dev) once done with the i2c client. ++ */ ++struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode) ++{ ++ struct i2c_client *client; ++ struct device *dev; ++ ++ if (!fwnode) ++ return NULL; ++ ++ dev = bus_find_device_by_fwnode(&i2c_bus_type, fwnode); ++ if (!dev) ++ return NULL; ++ ++ client = i2c_verify_client(dev); ++ if (!client) ++ put_device(dev); ++ ++ return client; ++} ++EXPORT_SYMBOL(i2c_find_device_by_fwnode); ++ + + static const struct i2c_device_id dummy_id[] = { + { "dummy", 0 }, +@@ -1764,6 +1793,75 @@ int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter) + } + EXPORT_SYMBOL_GPL(devm_i2c_add_adapter); + ++static int i2c_dev_or_parent_fwnode_match(struct device *dev, const void *data) ++{ ++ if (dev_fwnode(dev) == data) ++ return 1; ++ ++ if (dev->parent && dev_fwnode(dev->parent) == data) ++ return 1; ++ ++ return 0; ++} ++ ++/** ++ * i2c_find_adapter_by_fwnode() - find an i2c_adapter for the fwnode ++ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_adapter ++ * ++ * Look up and return the &struct i2c_adapter corresponding to the @fwnode. ++ * If no adapter can be found, or @fwnode is NULL, this returns NULL. ++ * ++ * The user must call put_device(&adapter->dev) once done with the i2c adapter. ++ */ ++struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode) ++{ ++ struct i2c_adapter *adapter; ++ struct device *dev; ++ ++ if (!fwnode) ++ return NULL; ++ ++ dev = bus_find_device(&i2c_bus_type, NULL, fwnode, ++ i2c_dev_or_parent_fwnode_match); ++ if (!dev) ++ return NULL; ++ ++ adapter = i2c_verify_adapter(dev); ++ if (!adapter) ++ put_device(dev); ++ ++ return adapter; ++} ++EXPORT_SYMBOL(i2c_find_adapter_by_fwnode); ++ ++/** ++ * i2c_get_adapter_by_fwnode() - find an i2c_adapter for the fwnode ++ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_adapter ++ * ++ * Look up and return the &struct i2c_adapter corresponding to the @fwnode, ++ * and increment the adapter module's use count. If no adapter can be found, ++ * or @fwnode is NULL, this returns NULL. ++ * ++ * The user must call i2c_put_adapter(adapter) once done with the i2c adapter. ++ * Note that this is different from i2c_find_adapter_by_node(). ++ */ ++struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode) ++{ ++ struct i2c_adapter *adapter; ++ ++ adapter = i2c_find_adapter_by_fwnode(fwnode); ++ if (!adapter) ++ return NULL; ++ ++ if (!try_module_get(adapter->owner)) { ++ put_device(&adapter->dev); ++ adapter = NULL; ++ } ++ ++ return adapter; ++} ++EXPORT_SYMBOL(i2c_get_adapter_by_fwnode); ++ + static void i2c_parse_timing(struct device *dev, char *prop_name, u32 *cur_val_p, + u32 def_val, bool use_def) + { +diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c +index 3ed74aa4b44bb..bce6b796e04c2 100644 +--- a/drivers/i2c/i2c-core-of.c ++++ b/drivers/i2c/i2c-core-of.c +@@ -113,72 +113,6 @@ void of_i2c_register_devices(struct i2c_adapter *adap) + of_node_put(bus); + } + +-static int of_dev_or_parent_node_match(struct device *dev, const void *data) +-{ +- if (dev->of_node == data) +- return 1; +- +- if (dev->parent) +- return dev->parent->of_node == data; +- +- return 0; +-} +- +-/* must call put_device() when done with returned i2c_client device */ +-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) +-{ +- struct device *dev; +- struct i2c_client *client; +- +- dev = bus_find_device_by_of_node(&i2c_bus_type, node); +- if (!dev) +- return NULL; +- +- client = i2c_verify_client(dev); +- if (!client) +- put_device(dev); +- +- return client; +-} +-EXPORT_SYMBOL(of_find_i2c_device_by_node); +- +-/* must call put_device() when done with returned i2c_adapter device */ +-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) +-{ +- struct device *dev; +- struct i2c_adapter *adapter; +- +- dev = bus_find_device(&i2c_bus_type, NULL, node, +- of_dev_or_parent_node_match); +- if (!dev) +- return NULL; +- +- adapter = i2c_verify_adapter(dev); +- if (!adapter) +- put_device(dev); +- +- return adapter; +-} +-EXPORT_SYMBOL(of_find_i2c_adapter_by_node); +- +-/* must call i2c_put_adapter() when done with returned i2c_adapter device */ +-struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node) +-{ +- struct i2c_adapter *adapter; +- +- adapter = of_find_i2c_adapter_by_node(node); +- if (!adapter) +- return NULL; +- +- if (!try_module_get(adapter->owner)) { +- put_device(&adapter->dev); +- adapter = NULL; +- } +- +- return adapter; +-} +-EXPORT_SYMBOL(of_get_i2c_adapter_by_node); +- + static const struct of_device_id* + i2c_of_match_device_sysfs(const struct of_device_id *matches, + struct i2c_client *client) +diff --git a/drivers/i2c/i2c-slave-testunit.c b/drivers/i2c/i2c-slave-testunit.c +index 56dae08dfd489..cd0d87b089fec 100644 +--- a/drivers/i2c/i2c-slave-testunit.c ++++ b/drivers/i2c/i2c-slave-testunit.c +@@ -118,9 +118,12 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client, + queue_delayed_work(system_long_wq, &tu->worker, + msecs_to_jiffies(10 * tu->regs[TU_REG_DELAY])); + } +- fallthrough; ++ break; + + case I2C_SLAVE_WRITE_REQUESTED: ++ if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags)) ++ return -EBUSY; ++ + memset(tu->regs, 0, TU_NUM_REGS); + tu->reg_idx = 0; + break; +diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig +index c258ea678470a..839bdcc3e5d60 100644 +--- a/drivers/iio/accel/Kconfig ++++ b/drivers/iio/accel/Kconfig +@@ -235,6 +235,8 @@ config DMARD10 + config FXLS8962AF + tristate + depends on I2C || !I2C # cannot be built-in for modular I2C ++ select IIO_BUFFER ++ select IIO_KFIFO_BUF + + config FXLS8962AF_I2C + tristate "NXP FXLS8962AF/FXLS8964AF Accelerometer I2C Driver" +diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c +index ffae30e5eb5be..8db5611134da4 100644 +--- a/drivers/iio/accel/mxc4005.c ++++ b/drivers/iio/accel/mxc4005.c +@@ -5,6 +5,7 @@ + * Copyright (c) 2014, Intel Corporation. + */ + ++#include <linux/delay.h> + #include <linux/module.h> + #include <linux/i2c.h> + #include <linux/iio/iio.h> +@@ -36,6 +37,7 @@ + + #define MXC4005_REG_INT_CLR1 0x01 + #define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01 ++#define MXC4005_REG_INT_CLR1_SW_RST 0x10 + + #define MXC4005_REG_CONTROL 0x0D + #define MXC4005_REG_CONTROL_MASK_FSR GENMASK(6, 5) +@@ -43,6 +45,9 @@ + + #define MXC4005_REG_DEVICE_ID 0x0E + ++/* Datasheet does not specify a reset time, this is a conservative guess */ ++#define MXC4005_RESET_TIME_US 2000 ++ + enum mxc4005_axis { + AXIS_X, + AXIS_Y, +@@ -66,6 +71,8 @@ struct mxc4005_data { + s64 timestamp __aligned(8); + } scan; + bool trigger_enabled; ++ unsigned int control; ++ unsigned int int_mask1; + }; + + /* +@@ -349,6 +356,7 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig, + return ret; + } + ++ data->int_mask1 = val; + data->trigger_enabled = state; + mutex_unlock(&data->mutex); + +@@ -384,6 +392,13 @@ static int mxc4005_chip_init(struct mxc4005_data *data) + + dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg); + ++ ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1, ++ MXC4005_REG_INT_CLR1_SW_RST); ++ if (ret < 0) ++ return dev_err_probe(data->dev, ret, "resetting chip\n"); ++ ++ fsleep(MXC4005_RESET_TIME_US); ++ + ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0); + if (ret < 0) + return dev_err_probe(data->dev, ret, "writing INT_MASK0\n"); +@@ -480,6 +495,58 @@ static int mxc4005_probe(struct i2c_client *client, + return devm_iio_device_register(&client->dev, indio_dev); + } + ++static int mxc4005_suspend(struct device *dev) ++{ ++ struct iio_dev *indio_dev = dev_get_drvdata(dev); ++ struct mxc4005_data *data = iio_priv(indio_dev); ++ int ret; ++ ++ /* Save control to restore it on resume */ ++ ret = regmap_read(data->regmap, MXC4005_REG_CONTROL, &data->control); ++ if (ret < 0) ++ dev_err(data->dev, "failed to read reg_control\n"); ++ ++ return ret; ++} ++ ++static int mxc4005_resume(struct device *dev) ++{ ++ struct iio_dev *indio_dev = dev_get_drvdata(dev); ++ struct mxc4005_data *data = iio_priv(indio_dev); ++ int ret; ++ ++ ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1, ++ MXC4005_REG_INT_CLR1_SW_RST); ++ if (ret) { ++ dev_err(data->dev, "failed to reset chip: %d\n", ret); ++ return ret; ++ } ++ ++ fsleep(MXC4005_RESET_TIME_US); ++ ++ ret = regmap_write(data->regmap, MXC4005_REG_CONTROL, data->control); ++ if (ret) { ++ dev_err(data->dev, "failed to restore control register\n"); ++ return ret; ++ } ++ ++ ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0); ++ if (ret) { ++ dev_err(data->dev, "failed to restore interrupt 0 mask\n"); ++ return ret; ++ } ++ ++ ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, data->int_mask1); ++ if (ret) { ++ dev_err(data->dev, "failed to restore interrupt 1 mask\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static DEFINE_SIMPLE_DEV_PM_OPS(mxc4005_pm_ops, mxc4005_suspend, mxc4005_resume); ++ + static const struct acpi_device_id mxc4005_acpi_match[] = { + {"MXC4005", 0}, + {"MXC6655", 0}, +@@ -498,6 +565,7 @@ static struct i2c_driver mxc4005_driver = { + .driver = { + .name = MXC4005_DRV_NAME, + .acpi_match_table = ACPI_PTR(mxc4005_acpi_match), ++ .pm = pm_sleep_ptr(&mxc4005_pm_ops), + }, + .probe = mxc4005_probe, + .id_table = mxc4005_id, +diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c +index a8ec3efd659ed..90b9ac589e90e 100644 +--- a/drivers/iio/adc/ad7266.c ++++ b/drivers/iio/adc/ad7266.c +@@ -157,6 +157,8 @@ static int ad7266_read_raw(struct iio_dev *indio_dev, + ret = ad7266_read_single(st, val, chan->address); + iio_device_release_direct_mode(indio_dev); + ++ if (ret < 0) ++ return ret; + *val = (*val >> 2) & 0xfff; + if (chan->scan_type.sign == 's') + *val = sign_extend32(*val, 11); +diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c +index ad94f0abc402a..8003b4e2a1b25 100644 +--- a/drivers/iio/adc/ad9467.c ++++ b/drivers/iio/adc/ad9467.c +@@ -223,11 +223,11 @@ static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index, + } + + static const struct iio_chan_spec ad9434_channels[] = { +- AD9467_CHAN(0, 0, 12, 'S'), ++ AD9467_CHAN(0, 0, 12, 's'), + }; + + static const struct iio_chan_spec ad9467_channels[] = { +- AD9467_CHAN(0, 0, 16, 'S'), ++ AD9467_CHAN(0, 0, 16, 's'), + }; + + static const struct ad9467_chip_info ad9467_chip_tbl[] = { +diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h +index 4edc5d21cb9fa..f959252a4fe66 100644 +--- a/drivers/iio/chemical/bme680.h ++++ b/drivers/iio/chemical/bme680.h +@@ -54,7 +54,9 @@ + #define BME680_NB_CONV_MASK GENMASK(3, 0) + + #define BME680_REG_MEAS_STAT_0 0x1D ++#define BME680_NEW_DATA_BIT BIT(7) + #define BME680_GAS_MEAS_BIT BIT(6) ++#define BME680_MEAS_BIT BIT(5) + + /* Calibration Parameters */ + #define BME680_T2_LSB_REG 0x8A +diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c +index bf23cc7eb99ea..a6697add2cbc1 100644 +--- a/drivers/iio/chemical/bme680_core.c ++++ b/drivers/iio/chemical/bme680_core.c +@@ -10,6 +10,7 @@ + */ + #include <linux/acpi.h> + #include <linux/bitfield.h> ++#include <linux/delay.h> + #include <linux/device.h> + #include <linux/module.h> + #include <linux/log2.h> +@@ -38,7 +39,7 @@ struct bme680_calib { + s8 par_h3; + s8 par_h4; + s8 par_h5; +- s8 par_h6; ++ u8 par_h6; + s8 par_h7; + s8 par_gh1; + s16 par_gh2; +@@ -342,10 +343,10 @@ static s16 bme680_compensate_temp(struct bme680_data *data, + if (!calib->par_t2) + bme680_read_calib(data, calib); + +- var1 = (adc_temp >> 3) - (calib->par_t1 << 1); ++ var1 = (adc_temp >> 3) - ((s32)calib->par_t1 << 1); + var2 = (var1 * calib->par_t2) >> 11; + var3 = ((var1 >> 1) * (var1 >> 1)) >> 12; +- var3 = (var3 * (calib->par_t3 << 4)) >> 14; ++ var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14; + data->t_fine = var2 + var3; + calc_temp = (data->t_fine * 5 + 128) >> 8; + +@@ -368,9 +369,9 @@ static u32 bme680_compensate_press(struct bme680_data *data, + var1 = (data->t_fine >> 1) - 64000; + var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2; + var2 = var2 + (var1 * calib->par_p5 << 1); +- var2 = (var2 >> 2) + (calib->par_p4 << 16); ++ var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16); + var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * +- (calib->par_p3 << 5)) >> 3) + ++ ((s32)calib->par_p3 << 5)) >> 3) + + ((calib->par_p2 * var1) >> 1); + var1 = var1 >> 18; + var1 = ((32768 + var1) * calib->par_p1) >> 15; +@@ -388,7 +389,7 @@ static u32 bme680_compensate_press(struct bme680_data *data, + var3 = ((press_comp >> 8) * (press_comp >> 8) * + (press_comp >> 8) * calib->par_p10) >> 17; + +- press_comp += (var1 + var2 + var3 + (calib->par_p7 << 7)) >> 4; ++ press_comp += (var1 + var2 + var3 + ((s32)calib->par_p7 << 7)) >> 4; + + return press_comp; + } +@@ -414,7 +415,7 @@ static u32 bme680_compensate_humid(struct bme680_data *data, + (((temp_scaled * ((temp_scaled * calib->par_h5) / 100)) + >> 6) / 100) + (1 << 14))) >> 10; + var3 = var1 * var2; +- var4 = calib->par_h6 << 7; ++ var4 = (s32)calib->par_h6 << 7; + var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4; + var5 = ((var3 >> 14) * (var3 >> 14)) >> 10; + var6 = (var4 * var5) >> 1; +@@ -532,6 +533,43 @@ static u8 bme680_oversampling_to_reg(u8 val) + return ilog2(val) + 1; + } + ++/* ++ * Taken from Bosch BME680 API: ++ * https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490 ++ */ ++static int bme680_wait_for_eoc(struct bme680_data *data) ++{ ++ struct device *dev = regmap_get_device(data->regmap); ++ unsigned int check; ++ int ret; ++ /* ++ * (Sum of oversampling ratios * time per oversampling) + ++ * TPH measurement + gas measurement + wait transition from forced mode ++ * + heater duration ++ */ ++ int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press + ++ data->oversampling_humid) * 1936) + (477 * 4) + ++ (477 * 5) + 1000 + (data->heater_dur * 1000); ++ ++ usleep_range(wait_eoc_us, wait_eoc_us + 100); ++ ++ ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check); ++ if (ret) { ++ dev_err(dev, "failed to read measurement status register.\n"); ++ return ret; ++ } ++ if (check & BME680_MEAS_BIT) { ++ dev_err(dev, "Device measurement cycle incomplete.\n"); ++ return -EBUSY; ++ } ++ if (!(check & BME680_NEW_DATA_BIT)) { ++ dev_err(dev, "No new data available from the device.\n"); ++ return -ENODATA; ++ } ++ ++ return 0; ++} ++ + static int bme680_chip_config(struct bme680_data *data) + { + struct device *dev = regmap_get_device(data->regmap); +@@ -622,6 +660,10 @@ static int bme680_read_temp(struct bme680_data *data, int *val) + if (ret < 0) + return ret; + ++ ret = bme680_wait_for_eoc(data); ++ if (ret) ++ return ret; ++ + ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB, + &tmp, 3); + if (ret < 0) { +@@ -678,7 +720,7 @@ static int bme680_read_press(struct bme680_data *data, + } + + *val = bme680_compensate_press(data, adc_press); +- *val2 = 100; ++ *val2 = 1000; + return IIO_VAL_FRACTIONAL; + } + +@@ -738,6 +780,10 @@ static int bme680_read_gas(struct bme680_data *data, + if (ret < 0) + return ret; + ++ ret = bme680_wait_for_eoc(data); ++ if (ret) ++ return ret; ++ + ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check); + if (check & BME680_GAS_MEAS_BIT) { + dev_err(dev, "gas measurement incomplete\n"); +diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c +index 987264410278c..520a3748befa0 100644 +--- a/drivers/iio/dac/ad5592r-base.c ++++ b/drivers/iio/dac/ad5592r-base.c +@@ -411,7 +411,7 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, + s64 tmp = *val * (3767897513LL / 25LL); + *val = div_s64_rem(tmp, 1000000000LL, val2); + +- return IIO_VAL_INT_PLUS_MICRO; ++ return IIO_VAL_INT_PLUS_NANO; + } + + mutex_lock(&st->lock); +diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +index 383cc32503425..a394b667a3e56 100644 +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +@@ -128,10 +128,6 @@ static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev, + /* update data FIFO write */ + inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0); + ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); +- if (ret) +- goto out_unlock; +- +- ret = inv_icm42600_buffer_update_watermark(st); + + out_unlock: + mutex_unlock(&st->lock); +diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +index cec1dd0e04646..22b7ccfa7f4f7 100644 +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +@@ -128,10 +128,6 @@ static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev, + /* update data FIFO write */ + inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0); + ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); +- if (ret) +- goto out_unlock; +- +- ret = inv_icm42600_buffer_update_watermark(st); + + out_unlock: + mutex_unlock(&st->lock); +diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c +index 01a499a8b88db..438ed35881752 100644 +--- a/drivers/infiniband/core/restrack.c ++++ b/drivers/infiniband/core/restrack.c +@@ -37,22 +37,6 @@ int rdma_restrack_init(struct ib_device *dev) + return 0; + } + +-static const char *type2str(enum rdma_restrack_type type) +-{ +- static const char * const names[RDMA_RESTRACK_MAX] = { +- [RDMA_RESTRACK_PD] = "PD", +- [RDMA_RESTRACK_CQ] = "CQ", +- [RDMA_RESTRACK_QP] = "QP", +- [RDMA_RESTRACK_CM_ID] = "CM_ID", +- [RDMA_RESTRACK_MR] = "MR", +- [RDMA_RESTRACK_CTX] = "CTX", +- [RDMA_RESTRACK_COUNTER] = "COUNTER", +- [RDMA_RESTRACK_SRQ] = "SRQ", +- }; +- +- return names[type]; +-}; +- + /** + * rdma_restrack_clean() - clean resource tracking + * @dev: IB device +@@ -60,47 +44,14 @@ static const char *type2str(enum rdma_restrack_type type) + void rdma_restrack_clean(struct ib_device *dev) + { + struct rdma_restrack_root *rt = dev->res; +- struct rdma_restrack_entry *e; +- char buf[TASK_COMM_LEN]; +- bool found = false; +- const char *owner; + int i; + + for (i = 0 ; i < RDMA_RESTRACK_MAX; i++) { + struct xarray *xa = &dev->res[i].xa; + +- if (!xa_empty(xa)) { +- unsigned long index; +- +- if (!found) { +- pr_err("restrack: %s", CUT_HERE); +- dev_err(&dev->dev, "BUG: RESTRACK detected leak of resources\n"); +- } +- xa_for_each(xa, index, e) { +- if (rdma_is_kernel_res(e)) { +- owner = e->kern_name; +- } else { +- /* +- * There is no need to call get_task_struct here, +- * because we can be here only if there are more +- * get_task_struct() call than put_task_struct(). +- */ +- get_task_comm(buf, e->task); +- owner = buf; +- } +- +- pr_err("restrack: %s %s object allocated by %s is not freed\n", +- rdma_is_kernel_res(e) ? "Kernel" : +- "User", +- type2str(e->type), owner); +- } +- found = true; +- } ++ WARN_ON(!xa_empty(xa)); + xa_destroy(xa); + } +- if (found) +- pr_err("restrack: %s", CUT_HERE); +- + kfree(rt); + } + +diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c +index 191c4ee7db620..dfed4c4321337 100644 +--- a/drivers/infiniband/hw/mlx5/srq.c ++++ b/drivers/infiniband/hw/mlx5/srq.c +@@ -200,17 +200,20 @@ int mlx5_ib_create_srq(struct ib_srq *ib_srq, + int err; + struct mlx5_srq_attr in = {}; + __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz); ++ __u32 max_sge_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq) / ++ sizeof(struct mlx5_wqe_data_seg); + + if (init_attr->srq_type != IB_SRQT_BASIC && + init_attr->srq_type != IB_SRQT_XRC && + init_attr->srq_type != IB_SRQT_TM) + return -EOPNOTSUPP; + +- /* Sanity check SRQ size before proceeding */ +- if (init_attr->attr.max_wr >= max_srq_wqes) { +- mlx5_ib_dbg(dev, "max_wr %d, cap %d\n", +- init_attr->attr.max_wr, +- max_srq_wqes); ++ /* Sanity check SRQ and sge size before proceeding */ ++ if (init_attr->attr.max_wr >= max_srq_wqes || ++ init_attr->attr.max_sge > max_sge_sz) { ++ mlx5_ib_dbg(dev, "max_wr %d,wr_cap %d,max_sge %d, sge_cap:%d\n", ++ init_attr->attr.max_wr, max_srq_wqes, ++ init_attr->attr.max_sge, max_sge_sz); + return -EINVAL; + } + +diff --git a/drivers/input/input.c b/drivers/input/input.c +index 5ca3f11d2d759..171f71bd4c2a2 100644 +--- a/drivers/input/input.c ++++ b/drivers/input/input.c +@@ -1360,19 +1360,19 @@ static int input_print_modalias_bits(char *buf, int size, + char name, unsigned long *bm, + unsigned int min_bit, unsigned int max_bit) + { +- int len = 0, i; ++ int bit = min_bit; ++ int len = 0; + + len += snprintf(buf, max(size, 0), "%c", name); +- for (i = min_bit; i < max_bit; i++) +- if (bm[BIT_WORD(i)] & BIT_MASK(i)) +- len += snprintf(buf + len, max(size - len, 0), "%X,", i); ++ for_each_set_bit_from(bit, bm, max_bit) ++ len += snprintf(buf + len, max(size - len, 0), "%X,", bit); + return len; + } + +-static int input_print_modalias(char *buf, int size, struct input_dev *id, +- int add_cr) ++static int input_print_modalias_parts(char *buf, int size, int full_len, ++ struct input_dev *id) + { +- int len; ++ int len, klen, remainder, space; + + len = snprintf(buf, max(size, 0), + "input:b%04Xv%04Xp%04Xe%04X-", +@@ -1381,8 +1381,49 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id, + + len += input_print_modalias_bits(buf + len, size - len, + 'e', id->evbit, 0, EV_MAX); +- len += input_print_modalias_bits(buf + len, size - len, ++ ++ /* ++ * Calculate the remaining space in the buffer making sure we ++ * have place for the terminating 0. ++ */ ++ space = max(size - (len + 1), 0); ++ ++ klen = input_print_modalias_bits(buf + len, size - len, + 'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX); ++ len += klen; ++ ++ /* ++ * If we have more data than we can fit in the buffer, check ++ * if we can trim key data to fit in the rest. We will indicate ++ * that key data is incomplete by adding "+" sign at the end, like ++ * this: * "k1,2,3,45,+,". ++ * ++ * Note that we shortest key info (if present) is "k+," so we ++ * can only try to trim if key data is longer than that. ++ */ ++ if (full_len && size < full_len + 1 && klen > 3) { ++ remainder = full_len - len; ++ /* ++ * We can only trim if we have space for the remainder ++ * and also for at least "k+," which is 3 more characters. ++ */ ++ if (remainder <= space - 3) { ++ int i; ++ /* ++ * We are guaranteed to have 'k' in the buffer, so ++ * we need at least 3 additional bytes for storing ++ * "+," in addition to the remainder. ++ */ ++ for (i = size - 1 - remainder - 3; i >= 0; i--) { ++ if (buf[i] == 'k' || buf[i] == ',') { ++ strcpy(buf + i + 1, "+,"); ++ len = i + 3; /* Not counting '\0' */ ++ break; ++ } ++ } ++ } ++ } ++ + len += input_print_modalias_bits(buf + len, size - len, + 'r', id->relbit, 0, REL_MAX); + len += input_print_modalias_bits(buf + len, size - len, +@@ -1398,12 +1439,25 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id, + len += input_print_modalias_bits(buf + len, size - len, + 'w', id->swbit, 0, SW_MAX); + +- if (add_cr) +- len += snprintf(buf + len, max(size - len, 0), "\n"); +- + return len; + } + ++static int input_print_modalias(char *buf, int size, struct input_dev *id) ++{ ++ int full_len; ++ ++ /* ++ * Printing is done in 2 passes: first one figures out total length ++ * needed for the modalias string, second one will try to trim key ++ * data in case when buffer is too small for the entire modalias. ++ * If the buffer is too small regardless, it will fill as much as it ++ * can (without trimming key data) into the buffer and leave it to ++ * the caller to figure out what to do with the result. ++ */ ++ full_len = input_print_modalias_parts(NULL, 0, 0, id); ++ return input_print_modalias_parts(buf, size, full_len, id); ++} ++ + static ssize_t input_dev_show_modalias(struct device *dev, + struct device_attribute *attr, + char *buf) +@@ -1411,7 +1465,9 @@ static ssize_t input_dev_show_modalias(struct device *dev, + struct input_dev *id = to_input_dev(dev); + ssize_t len; + +- len = input_print_modalias(buf, PAGE_SIZE, id, 1); ++ len = input_print_modalias(buf, PAGE_SIZE, id); ++ if (len < PAGE_SIZE - 2) ++ len += snprintf(buf + len, PAGE_SIZE - len, "\n"); + + return min_t(int, len, PAGE_SIZE); + } +@@ -1623,6 +1679,23 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, + return 0; + } + ++/* ++ * This is a pretty gross hack. When building uevent data the driver core ++ * may try adding more environment variables to kobj_uevent_env without ++ * telling us, so we have no idea how much of the buffer we can use to ++ * avoid overflows/-ENOMEM elsewhere. To work around this let's artificially ++ * reduce amount of memory we will use for the modalias environment variable. ++ * ++ * The potential additions are: ++ * ++ * SEQNUM=18446744073709551615 - (%llu - 28 bytes) ++ * HOME=/ (6 bytes) ++ * PATH=/sbin:/bin:/usr/sbin:/usr/bin (34 bytes) ++ * ++ * 68 bytes total. Allow extra buffer - 96 bytes ++ */ ++#define UEVENT_ENV_EXTRA_LEN 96 ++ + static int input_add_uevent_modalias_var(struct kobj_uevent_env *env, + struct input_dev *dev) + { +@@ -1632,9 +1705,11 @@ static int input_add_uevent_modalias_var(struct kobj_uevent_env *env, + return -ENOMEM; + + len = input_print_modalias(&env->buf[env->buflen - 1], +- sizeof(env->buf) - env->buflen, +- dev, 0); +- if (len >= (sizeof(env->buf) - env->buflen)) ++ (int)sizeof(env->buf) - env->buflen - ++ UEVENT_ENV_EXTRA_LEN, ++ dev); ++ if (len >= ((int)sizeof(env->buf) - env->buflen - ++ UEVENT_ENV_EXTRA_LEN)) + return -ENOMEM; + + env->buflen += len; +diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c +index f437eefec94ad..9452a12ddb096 100644 +--- a/drivers/input/touchscreen/ili210x.c ++++ b/drivers/input/touchscreen/ili210x.c +@@ -231,8 +231,8 @@ static int ili251x_read_touch_data(struct i2c_client *client, u8 *data) + if (!error && data[0] == 2) { + error = i2c_master_recv(client, data + ILI251X_DATA_SIZE1, + ILI251X_DATA_SIZE2); +- if (error >= 0 && error != ILI251X_DATA_SIZE2) +- error = -EIO; ++ if (error >= 0) ++ error = error == ILI251X_DATA_SIZE2 ? 0 : -EIO; + } + + return error; +diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h +index 390f10060c82b..2dc025acad4ce 100644 +--- a/drivers/iommu/amd/amd_iommu_types.h ++++ b/drivers/iommu/amd/amd_iommu_types.h +@@ -450,6 +450,11 @@ extern bool amd_iommu_irq_remap; + /* kmem_cache to get tables with 128 byte alignement */ + extern struct kmem_cache *amd_iommu_irq_cache; + ++/* Make iterating over all pci segment easier */ ++#define for_each_pci_segment(pci_seg) \ ++ list_for_each_entry((pci_seg), &amd_iommu_pci_seg_list, list) ++#define for_each_pci_segment_safe(pci_seg, next) \ ++ list_for_each_entry_safe((pci_seg), (next), &amd_iommu_pci_seg_list, list) + /* + * Make iterating over all IOMMUs easier + */ +@@ -524,6 +529,17 @@ struct protection_domain { + unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */ + }; + ++/* ++ * This structure contains information about one PCI segment in the system. ++ */ ++struct amd_iommu_pci_seg { ++ /* List with all PCI segments in the system */ ++ struct list_head list; ++ ++ /* PCI segment number */ ++ u16 id; ++}; ++ + /* + * Structure where we save information about one hardware AMD IOMMU in the + * system. +@@ -575,7 +591,7 @@ struct amd_iommu { + u16 cap_ptr; + + /* pci domain of this IOMMU */ +- u16 pci_seg; ++ struct amd_iommu_pci_seg *pci_seg; + + /* start of exclusion range of that IOMMU */ + u64 exclusion_start; +@@ -703,6 +719,12 @@ extern struct list_head ioapic_map; + extern struct list_head hpet_map; + extern struct list_head acpihid_map; + ++/* ++ * List with all PCI segments in the system. This list is not locked because ++ * it is only written at driver initialization time ++ */ ++extern struct list_head amd_iommu_pci_seg_list; ++ + /* + * List with all IOMMUs in the system. This list is not locked because it is + * only written and read at driver initialization or suspend time +diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c +index ef855495c210e..70f3720d96c7e 100644 +--- a/drivers/iommu/amd/init.c ++++ b/drivers/iommu/amd/init.c +@@ -167,6 +167,7 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have + LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings + we find in ACPI */ + ++LIST_HEAD(amd_iommu_pci_seg_list); /* list of all PCI segments */ + LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the + system */ + +@@ -1455,8 +1456,54 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, + return 0; + } + ++/* Allocate PCI segment data structure */ ++static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id) ++{ ++ struct amd_iommu_pci_seg *pci_seg; ++ ++ pci_seg = kzalloc(sizeof(struct amd_iommu_pci_seg), GFP_KERNEL); ++ if (pci_seg == NULL) ++ return NULL; ++ ++ pci_seg->id = id; ++ list_add_tail(&pci_seg->list, &amd_iommu_pci_seg_list); ++ ++ return pci_seg; ++} ++ ++static struct amd_iommu_pci_seg *__init get_pci_segment(u16 id) ++{ ++ struct amd_iommu_pci_seg *pci_seg; ++ ++ for_each_pci_segment(pci_seg) { ++ if (pci_seg->id == id) ++ return pci_seg; ++ } ++ ++ return alloc_pci_segment(id); ++} ++ ++static void __init free_pci_segments(void) ++{ ++ struct amd_iommu_pci_seg *pci_seg, *next; ++ ++ for_each_pci_segment_safe(pci_seg, next) { ++ list_del(&pci_seg->list); ++ kfree(pci_seg); ++ } ++} ++ ++static void __init free_sysfs(struct amd_iommu *iommu) ++{ ++ if (iommu->iommu.dev) { ++ iommu_device_unregister(&iommu->iommu); ++ iommu_device_sysfs_remove(&iommu->iommu); ++ } ++} ++ + static void __init free_iommu_one(struct amd_iommu *iommu) + { ++ free_sysfs(iommu); + free_cwwb_sem(iommu); + free_command_buffer(iommu); + free_event_buffer(iommu); +@@ -1541,8 +1588,14 @@ static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu) + */ + static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) + { ++ struct amd_iommu_pci_seg *pci_seg; + int ret; + ++ pci_seg = get_pci_segment(h->pci_seg); ++ if (pci_seg == NULL) ++ return -ENOMEM; ++ iommu->pci_seg = pci_seg; ++ + raw_spin_lock_init(&iommu->lock); + iommu->cmd_sem_val = 0; + +@@ -1563,7 +1616,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) + */ + iommu->devid = h->devid; + iommu->cap_ptr = h->cap_ptr; +- iommu->pci_seg = h->pci_seg; + iommu->mmio_phys = h->mmio_phys; + + switch (h->type) { +@@ -2604,6 +2656,7 @@ static void __init free_iommu_resources(void) + amd_iommu_dev_table = NULL; + + free_iommu_all(); ++ free_pci_segments(); + } + + /* SB IOAPIC is always on this device in AMD systems */ +diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +index 761cb657f2561..ec4c87095c6cd 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +@@ -3239,7 +3239,7 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) + } + + /* Add callback to free MSIs on teardown */ +- devm_add_action(dev, arm_smmu_free_msis, dev); ++ devm_add_action_or_reset(dev, arm_smmu_free_msis, dev); + } + + static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu) +diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c +index 94d38e8a59b32..cb544207427b1 100644 +--- a/drivers/md/bcache/bset.c ++++ b/drivers/md/bcache/bset.c +@@ -54,7 +54,7 @@ void bch_dump_bucket(struct btree_keys *b) + int __bch_count_data(struct btree_keys *b) + { + unsigned int ret = 0; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bkey *k; + + if (b->ops->is_extents) +@@ -67,7 +67,7 @@ void __bch_check_keys(struct btree_keys *b, const char *fmt, ...) + { + va_list args; + struct bkey *k, *p = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + const char *err; + + for_each_key(b, k, &iter) { +@@ -879,7 +879,7 @@ unsigned int bch_btree_insert_key(struct btree_keys *b, struct bkey *k, + unsigned int status = BTREE_INSERT_STATUS_NO_INSERT; + struct bset *i = bset_tree_last(b)->data; + struct bkey *m, *prev = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bkey preceding_key_on_stack = ZERO_KEY; + struct bkey *preceding_key_p = &preceding_key_on_stack; + +@@ -895,9 +895,9 @@ unsigned int bch_btree_insert_key(struct btree_keys *b, struct bkey *k, + else + preceding_key(k, &preceding_key_p); + +- m = bch_btree_iter_init(b, &iter, preceding_key_p); ++ m = bch_btree_iter_stack_init(b, &iter, preceding_key_p); + +- if (b->ops->insert_fixup(b, k, &iter, replace_key)) ++ if (b->ops->insert_fixup(b, k, &iter.iter, replace_key)) + return status; + + status = BTREE_INSERT_STATUS_INSERT; +@@ -1100,33 +1100,33 @@ void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k, + btree_iter_cmp)); + } + +-static struct bkey *__bch_btree_iter_init(struct btree_keys *b, +- struct btree_iter *iter, +- struct bkey *search, +- struct bset_tree *start) ++static struct bkey *__bch_btree_iter_stack_init(struct btree_keys *b, ++ struct btree_iter_stack *iter, ++ struct bkey *search, ++ struct bset_tree *start) + { + struct bkey *ret = NULL; + +- iter->size = ARRAY_SIZE(iter->data); +- iter->used = 0; ++ iter->iter.size = ARRAY_SIZE(iter->stack_data); ++ iter->iter.used = 0; + + #ifdef CONFIG_BCACHE_DEBUG +- iter->b = b; ++ iter->iter.b = b; + #endif + + for (; start <= bset_tree_last(b); start++) { + ret = bch_bset_search(b, start, search); +- bch_btree_iter_push(iter, ret, bset_bkey_last(start->data)); ++ bch_btree_iter_push(&iter->iter, ret, bset_bkey_last(start->data)); + } + + return ret; + } + +-struct bkey *bch_btree_iter_init(struct btree_keys *b, +- struct btree_iter *iter, ++struct bkey *bch_btree_iter_stack_init(struct btree_keys *b, ++ struct btree_iter_stack *iter, + struct bkey *search) + { +- return __bch_btree_iter_init(b, iter, search, b->set); ++ return __bch_btree_iter_stack_init(b, iter, search, b->set); + } + + static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter, +@@ -1293,10 +1293,10 @@ void bch_btree_sort_partial(struct btree_keys *b, unsigned int start, + struct bset_sort_state *state) + { + size_t order = b->page_order, keys = 0; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + int oldsize = bch_count_data(b); + +- __bch_btree_iter_init(b, &iter, NULL, &b->set[start]); ++ __bch_btree_iter_stack_init(b, &iter, NULL, &b->set[start]); + + if (start) { + unsigned int i; +@@ -1307,7 +1307,7 @@ void bch_btree_sort_partial(struct btree_keys *b, unsigned int start, + order = get_order(__set_bytes(b->set->data, keys)); + } + +- __btree_sort(b, &iter, start, order, false, state); ++ __btree_sort(b, &iter.iter, start, order, false, state); + + EBUG_ON(oldsize >= 0 && bch_count_data(b) != oldsize); + } +@@ -1323,11 +1323,11 @@ void bch_btree_sort_into(struct btree_keys *b, struct btree_keys *new, + struct bset_sort_state *state) + { + uint64_t start_time = local_clock(); +- struct btree_iter iter; ++ struct btree_iter_stack iter; + +- bch_btree_iter_init(b, &iter, NULL); ++ bch_btree_iter_stack_init(b, &iter, NULL); + +- btree_mergesort(b, new->set->data, &iter, false, true); ++ btree_mergesort(b, new->set->data, &iter.iter, false, true); + + bch_time_stats_update(&state->time, start_time); + +diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h +index a50dcfda656f5..2ed6dbd35d6e5 100644 +--- a/drivers/md/bcache/bset.h ++++ b/drivers/md/bcache/bset.h +@@ -321,7 +321,14 @@ struct btree_iter { + #endif + struct btree_iter_set { + struct bkey *k, *end; +- } data[MAX_BSETS]; ++ } data[]; ++}; ++ ++/* Fixed-size btree_iter that can be allocated on the stack */ ++ ++struct btree_iter_stack { ++ struct btree_iter iter; ++ struct btree_iter_set stack_data[MAX_BSETS]; + }; + + typedef bool (*ptr_filter_fn)(struct btree_keys *b, const struct bkey *k); +@@ -333,9 +340,9 @@ struct bkey *bch_btree_iter_next_filter(struct btree_iter *iter, + + void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k, + struct bkey *end); +-struct bkey *bch_btree_iter_init(struct btree_keys *b, +- struct btree_iter *iter, +- struct bkey *search); ++struct bkey *bch_btree_iter_stack_init(struct btree_keys *b, ++ struct btree_iter_stack *iter, ++ struct bkey *search); + + struct bkey *__bch_bset_search(struct btree_keys *b, struct bset_tree *t, + const struct bkey *search); +@@ -350,13 +357,14 @@ static inline struct bkey *bch_bset_search(struct btree_keys *b, + return search ? __bch_bset_search(b, t, search) : t->data->start; + } + +-#define for_each_key_filter(b, k, iter, filter) \ +- for (bch_btree_iter_init((b), (iter), NULL); \ +- ((k) = bch_btree_iter_next_filter((iter), (b), filter));) ++#define for_each_key_filter(b, k, stack_iter, filter) \ ++ for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \ ++ ((k) = bch_btree_iter_next_filter(&((stack_iter)->iter), (b), \ ++ filter));) + +-#define for_each_key(b, k, iter) \ +- for (bch_btree_iter_init((b), (iter), NULL); \ +- ((k) = bch_btree_iter_next(iter));) ++#define for_each_key(b, k, stack_iter) \ ++ for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \ ++ ((k) = bch_btree_iter_next(&((stack_iter)->iter)));) + + /* Sorting */ + +diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c +index e22dfcf1ed6d8..066b4aafd49e5 100644 +--- a/drivers/md/bcache/btree.c ++++ b/drivers/md/bcache/btree.c +@@ -1283,7 +1283,7 @@ static bool btree_gc_mark_node(struct btree *b, struct gc_stat *gc) + uint8_t stale = 0; + unsigned int keys = 0, good_keys = 0; + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bset_tree *t; + + gc->nodes++; +@@ -1544,7 +1544,7 @@ static int btree_gc_rewrite_node(struct btree *b, struct btree_op *op, + static unsigned int btree_gc_count_keys(struct btree *b) + { + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + unsigned int ret = 0; + + for_each_key_filter(&b->keys, k, &iter, bch_ptr_bad) +@@ -1585,17 +1585,18 @@ static int btree_gc_recurse(struct btree *b, struct btree_op *op, + int ret = 0; + bool should_rewrite; + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct gc_merge_info r[GC_MERGE_NODES]; + struct gc_merge_info *i, *last = r + ARRAY_SIZE(r) - 1; + +- bch_btree_iter_init(&b->keys, &iter, &b->c->gc_done); ++ bch_btree_iter_stack_init(&b->keys, &iter, &b->c->gc_done); + + for (i = r; i < r + ARRAY_SIZE(r); i++) + i->b = ERR_PTR(-EINTR); + + while (1) { +- k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad); ++ k = bch_btree_iter_next_filter(&iter.iter, &b->keys, ++ bch_ptr_bad); + if (k) { + r->b = bch_btree_node_get(b->c, op, k, b->level - 1, + true, b); +@@ -1885,7 +1886,7 @@ static int bch_btree_check_recurse(struct btree *b, struct btree_op *op) + { + int ret = 0; + struct bkey *k, *p = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + + for_each_key_filter(&b->keys, k, &iter, bch_ptr_invalid) + bch_initial_mark_key(b->c, b->level, k); +@@ -1893,10 +1894,10 @@ static int bch_btree_check_recurse(struct btree *b, struct btree_op *op) + bch_initial_mark_key(b->c, b->level + 1, &b->key); + + if (b->level) { +- bch_btree_iter_init(&b->keys, &iter, NULL); ++ bch_btree_iter_stack_init(&b->keys, &iter, NULL); + + do { +- k = bch_btree_iter_next_filter(&iter, &b->keys, ++ k = bch_btree_iter_next_filter(&iter.iter, &b->keys, + bch_ptr_bad); + if (k) { + btree_node_prefetch(b, k); +@@ -1924,7 +1925,7 @@ static int bch_btree_check_thread(void *arg) + struct btree_check_info *info = arg; + struct btree_check_state *check_state = info->state; + struct cache_set *c = check_state->c; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bkey *k, *p; + int cur_idx, prev_idx, skip_nr; + +@@ -1933,8 +1934,8 @@ static int bch_btree_check_thread(void *arg) + ret = 0; + + /* root node keys are checked before thread created */ +- bch_btree_iter_init(&c->root->keys, &iter, NULL); +- k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); ++ bch_btree_iter_stack_init(&c->root->keys, &iter, NULL); ++ k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad); + BUG_ON(!k); + + p = k; +@@ -1952,7 +1953,7 @@ static int bch_btree_check_thread(void *arg) + skip_nr = cur_idx - prev_idx; + + while (skip_nr) { +- k = bch_btree_iter_next_filter(&iter, ++ k = bch_btree_iter_next_filter(&iter.iter, + &c->root->keys, + bch_ptr_bad); + if (k) +@@ -2025,7 +2026,7 @@ int bch_btree_check(struct cache_set *c) + int ret = 0; + int i; + struct bkey *k = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct btree_check_state check_state; + + /* check and mark root node keys */ +@@ -2521,11 +2522,11 @@ static int bch_btree_map_nodes_recurse(struct btree *b, struct btree_op *op, + + if (b->level) { + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + +- bch_btree_iter_init(&b->keys, &iter, from); ++ bch_btree_iter_stack_init(&b->keys, &iter, from); + +- while ((k = bch_btree_iter_next_filter(&iter, &b->keys, ++ while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys, + bch_ptr_bad))) { + ret = bcache_btree(map_nodes_recurse, k, b, + op, from, fn, flags); +@@ -2554,11 +2555,12 @@ int bch_btree_map_keys_recurse(struct btree *b, struct btree_op *op, + { + int ret = MAP_CONTINUE; + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + +- bch_btree_iter_init(&b->keys, &iter, from); ++ bch_btree_iter_stack_init(&b->keys, &iter, from); + +- while ((k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad))) { ++ while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys, ++ bch_ptr_bad))) { + ret = !b->level + ? fn(op, b, k) + : bcache_btree(map_keys_recurse, k, +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index 8ec48d8a5821c..48624e6bf0d79 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1920,8 +1920,9 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) + INIT_LIST_HEAD(&c->btree_cache_freed); + INIT_LIST_HEAD(&c->data_buckets); + +- iter_size = ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size + 1) * +- sizeof(struct btree_iter_set); ++ iter_size = sizeof(struct btree_iter) + ++ ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size) * ++ sizeof(struct btree_iter_set); + + c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL); + if (!c->devices) +diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c +index fa146012003df..7024eaed8d486 100644 +--- a/drivers/md/bcache/sysfs.c ++++ b/drivers/md/bcache/sysfs.c +@@ -658,7 +658,7 @@ static unsigned int bch_root_usage(struct cache_set *c) + unsigned int bytes = 0; + struct bkey *k; + struct btree *b; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + + goto lock_root; + +diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c +index 1e96679afcf4a..142eaf0ff9aea 100644 +--- a/drivers/md/bcache/writeback.c ++++ b/drivers/md/bcache/writeback.c +@@ -898,15 +898,15 @@ static int bch_dirty_init_thread(void *arg) + struct dirty_init_thrd_info *info = arg; + struct bch_dirty_init_state *state = info->state; + struct cache_set *c = state->c; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bkey *k, *p; + int cur_idx, prev_idx, skip_nr; + + k = p = NULL; + prev_idx = 0; + +- bch_btree_iter_init(&c->root->keys, &iter, NULL); +- k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); ++ bch_btree_iter_stack_init(&c->root->keys, &iter, NULL); ++ k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad); + BUG_ON(!k); + + p = k; +@@ -920,7 +920,7 @@ static int bch_dirty_init_thread(void *arg) + skip_nr = cur_idx - prev_idx; + + while (skip_nr) { +- k = bch_btree_iter_next_filter(&iter, ++ k = bch_btree_iter_next_filter(&iter.iter, + &c->root->keys, + bch_ptr_bad); + if (k) +@@ -969,7 +969,7 @@ void bch_sectors_dirty_init(struct bcache_device *d) + int i; + struct btree *b = NULL; + struct bkey *k = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct sectors_dirty_init op; + struct cache_set *c = d->c; + struct bch_dirty_init_state state; +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 23a0c209744dc..661588fc64f6a 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -974,7 +974,7 @@ int dvb_usercopy(struct file *file, + int (*func)(struct file *file, + unsigned int cmd, void *arg)) + { +- char sbuf[128]; ++ char sbuf[128] = {}; + void *mbuf = NULL; + void *parg = NULL; + int err = -EINVAL; +diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c +index 188d847662ff7..7b8e92bcaa98d 100644 +--- a/drivers/misc/mei/pci-me.c ++++ b/drivers/misc/mei/pci-me.c +@@ -400,8 +400,10 @@ static int mei_me_pci_resume(struct device *device) + } + + err = mei_restart(dev); +- if (err) ++ if (err) { ++ free_irq(pdev->irq, dev); + return err; ++ } + + /* Start timer if stopped in suspend */ + schedule_delayed_work(&dev->timer_work, HZ); +diff --git a/drivers/misc/pvpanic/pvpanic-mmio.c b/drivers/misc/pvpanic/pvpanic-mmio.c +index 61dbff5f0065c..9715798acce3d 100644 +--- a/drivers/misc/pvpanic/pvpanic-mmio.c ++++ b/drivers/misc/pvpanic/pvpanic-mmio.c +@@ -24,53 +24,9 @@ MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>"); + MODULE_DESCRIPTION("pvpanic-mmio device driver"); + MODULE_LICENSE("GPL"); + +-static ssize_t capability_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%x\n", pi->capability); +-} +-static DEVICE_ATTR_RO(capability); +- +-static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%x\n", pi->events); +-} +- +-static ssize_t events_store(struct device *dev, struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- unsigned int tmp; +- int err; +- +- err = kstrtouint(buf, 16, &tmp); +- if (err) +- return err; +- +- if ((tmp & pi->capability) != tmp) +- return -EINVAL; +- +- pi->events = tmp; +- +- return count; +-} +-static DEVICE_ATTR_RW(events); +- +-static struct attribute *pvpanic_mmio_dev_attrs[] = { +- &dev_attr_capability.attr, +- &dev_attr_events.attr, +- NULL +-}; +-ATTRIBUTE_GROUPS(pvpanic_mmio_dev); +- + static int pvpanic_mmio_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- struct pvpanic_instance *pi; + struct resource *res; + void __iomem *base; + +@@ -93,18 +49,7 @@ static int pvpanic_mmio_probe(struct platform_device *pdev) + return -EINVAL; + } + +- pi = devm_kmalloc(dev, sizeof(*pi), GFP_KERNEL); +- if (!pi) +- return -ENOMEM; +- +- pi->base = base; +- pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; +- +- /* initialize capability by RDPT */ +- pi->capability &= ioread8(base); +- pi->events = pi->capability; +- +- return devm_pvpanic_probe(dev, pi); ++ return devm_pvpanic_probe(dev, base); + } + + static const struct of_device_id pvpanic_mmio_match[] = { +@@ -124,7 +69,7 @@ static struct platform_driver pvpanic_mmio_driver = { + .name = "pvpanic-mmio", + .of_match_table = pvpanic_mmio_match, + .acpi_match_table = pvpanic_device_ids, +- .dev_groups = pvpanic_mmio_dev_groups, ++ .dev_groups = pvpanic_dev_groups, + }, + .probe = pvpanic_mmio_probe, + }; +diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c +index 741116b3d9958..2494725dfacfa 100644 +--- a/drivers/misc/pvpanic/pvpanic-pci.c ++++ b/drivers/misc/pvpanic/pvpanic-pci.c +@@ -19,61 +19,11 @@ + #define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011 + + MODULE_AUTHOR("Mihai Carabas <mihai.carabas@oracle.com>"); +-MODULE_DESCRIPTION("pvpanic device driver "); ++MODULE_DESCRIPTION("pvpanic device driver"); + MODULE_LICENSE("GPL"); + +-static const struct pci_device_id pvpanic_pci_id_tbl[] = { +- { PCI_DEVICE(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_PVPANIC)}, +- {} +-}; +- +-static ssize_t capability_show(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%x\n", pi->capability); +-} +-static DEVICE_ATTR_RO(capability); +- +-static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) ++static int pvpanic_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- +- return sysfs_emit(buf, "%x\n", pi->events); +-} +- +-static ssize_t events_store(struct device *dev, struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- struct pvpanic_instance *pi = dev_get_drvdata(dev); +- unsigned int tmp; +- int err; +- +- err = kstrtouint(buf, 16, &tmp); +- if (err) +- return err; +- +- if ((tmp & pi->capability) != tmp) +- return -EINVAL; +- +- pi->events = tmp; +- +- return count; +-} +-static DEVICE_ATTR_RW(events); +- +-static struct attribute *pvpanic_pci_dev_attrs[] = { +- &dev_attr_capability.attr, +- &dev_attr_events.attr, +- NULL +-}; +-ATTRIBUTE_GROUPS(pvpanic_pci_dev); +- +-static int pvpanic_pci_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent) +-{ +- struct pvpanic_instance *pi; + void __iomem *base; + int ret; + +@@ -85,29 +35,19 @@ static int pvpanic_pci_probe(struct pci_dev *pdev, + if (!base) + return -ENOMEM; + +- pi = devm_kmalloc(&pdev->dev, sizeof(*pi), GFP_KERNEL); +- if (!pi) +- return -ENOMEM; +- +- pi->base = base; +- pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; +- +- /* initlize capability by RDPT */ +- pi->capability &= ioread8(base); +- pi->events = pi->capability; +- +- return devm_pvpanic_probe(&pdev->dev, pi); ++ return devm_pvpanic_probe(&pdev->dev, base); + } + ++static const struct pci_device_id pvpanic_pci_id_tbl[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_PVPANIC)}, ++ {} ++}; ++MODULE_DEVICE_TABLE(pci, pvpanic_pci_id_tbl); ++ + static struct pci_driver pvpanic_pci_driver = { + .name = "pvpanic-pci", + .id_table = pvpanic_pci_id_tbl, + .probe = pvpanic_pci_probe, +- .driver = { +- .dev_groups = pvpanic_pci_dev_groups, +- }, ++ .dev_groups = pvpanic_dev_groups, + }; +- +-MODULE_DEVICE_TABLE(pci, pvpanic_pci_id_tbl); +- + module_pci_driver(pvpanic_pci_driver); +diff --git a/drivers/misc/pvpanic/pvpanic.c b/drivers/misc/pvpanic/pvpanic.c +index b9e6400a574b0..305b367e0ce34 100644 +--- a/drivers/misc/pvpanic/pvpanic.c ++++ b/drivers/misc/pvpanic/pvpanic.c +@@ -7,6 +7,7 @@ + * Copyright (C) 2021 Oracle. + */ + ++#include <linux/device.h> + #include <linux/io.h> + #include <linux/kernel.h> + #include <linux/kexec.h> +@@ -23,9 +24,16 @@ + #include "pvpanic.h" + + MODULE_AUTHOR("Mihai Carabas <mihai.carabas@oracle.com>"); +-MODULE_DESCRIPTION("pvpanic device driver "); ++MODULE_DESCRIPTION("pvpanic device driver"); + MODULE_LICENSE("GPL"); + ++struct pvpanic_instance { ++ void __iomem *base; ++ unsigned int capability; ++ unsigned int events; ++ struct list_head list; ++}; ++ + static struct list_head pvpanic_list; + static spinlock_t pvpanic_lock; + +@@ -45,8 +53,7 @@ pvpanic_send_event(unsigned int event) + } + + static int +-pvpanic_panic_notify(struct notifier_block *nb, unsigned long code, +- void *unused) ++pvpanic_panic_notify(struct notifier_block *nb, unsigned long code, void *unused) + { + unsigned int event = PVPANIC_PANICKED; + +@@ -82,11 +89,75 @@ static void pvpanic_remove(void *param) + spin_unlock(&pvpanic_lock); + } + +-int devm_pvpanic_probe(struct device *dev, struct pvpanic_instance *pi) ++static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct pvpanic_instance *pi = dev_get_drvdata(dev); ++ ++ return sysfs_emit(buf, "%x\n", pi->capability); ++} ++static DEVICE_ATTR_RO(capability); ++ ++static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct pvpanic_instance *pi = dev_get_drvdata(dev); ++ ++ return sysfs_emit(buf, "%x\n", pi->events); ++} ++ ++static ssize_t events_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) + { +- if (!pi || !pi->base) ++ struct pvpanic_instance *pi = dev_get_drvdata(dev); ++ unsigned int tmp; ++ int err; ++ ++ err = kstrtouint(buf, 16, &tmp); ++ if (err) ++ return err; ++ ++ if ((tmp & pi->capability) != tmp) + return -EINVAL; + ++ pi->events = tmp; ++ ++ return count; ++} ++static DEVICE_ATTR_RW(events); ++ ++static struct attribute *pvpanic_dev_attrs[] = { ++ &dev_attr_capability.attr, ++ &dev_attr_events.attr, ++ NULL ++}; ++ ++static const struct attribute_group pvpanic_dev_group = { ++ .attrs = pvpanic_dev_attrs, ++}; ++ ++const struct attribute_group *pvpanic_dev_groups[] = { ++ &pvpanic_dev_group, ++ NULL ++}; ++EXPORT_SYMBOL_GPL(pvpanic_dev_groups); ++ ++int devm_pvpanic_probe(struct device *dev, void __iomem *base) ++{ ++ struct pvpanic_instance *pi; ++ ++ if (!base) ++ return -EINVAL; ++ ++ pi = devm_kmalloc(dev, sizeof(*pi), GFP_KERNEL); ++ if (!pi) ++ return -ENOMEM; ++ ++ pi->base = base; ++ pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; ++ ++ /* initlize capability by RDPT */ ++ pi->capability &= ioread8(base); ++ pi->events = pi->capability; ++ + spin_lock(&pvpanic_lock); + list_add(&pi->list, &pvpanic_list); + spin_unlock(&pvpanic_lock); +@@ -102,18 +173,15 @@ static int pvpanic_init(void) + INIT_LIST_HEAD(&pvpanic_list); + spin_lock_init(&pvpanic_lock); + +- atomic_notifier_chain_register(&panic_notifier_list, +- &pvpanic_panic_nb); ++ atomic_notifier_chain_register(&panic_notifier_list, &pvpanic_panic_nb); + + return 0; + } ++module_init(pvpanic_init); + + static void pvpanic_exit(void) + { +- atomic_notifier_chain_unregister(&panic_notifier_list, +- &pvpanic_panic_nb); ++ atomic_notifier_chain_unregister(&panic_notifier_list, &pvpanic_panic_nb); + + } +- +-module_init(pvpanic_init); + module_exit(pvpanic_exit); +diff --git a/drivers/misc/pvpanic/pvpanic.h b/drivers/misc/pvpanic/pvpanic.h +index 4935459517548..46ffb10438adf 100644 +--- a/drivers/misc/pvpanic/pvpanic.h ++++ b/drivers/misc/pvpanic/pvpanic.h +@@ -8,13 +8,7 @@ + #ifndef PVPANIC_H_ + #define PVPANIC_H_ + +-struct pvpanic_instance { +- void __iomem *base; +- unsigned int capability; +- unsigned int events; +- struct list_head list; +-}; +- +-int devm_pvpanic_probe(struct device *dev, struct pvpanic_instance *pi); ++int devm_pvpanic_probe(struct device *dev, void __iomem *base); ++extern const struct attribute_group *pvpanic_dev_groups[]; + + #endif /* PVPANIC_H_ */ +diff --git a/drivers/misc/vmw_vmci/vmci_event.c b/drivers/misc/vmw_vmci/vmci_event.c +index e3436abf39f45..5b7ef47f4c118 100644 +--- a/drivers/misc/vmw_vmci/vmci_event.c ++++ b/drivers/misc/vmw_vmci/vmci_event.c +@@ -9,6 +9,7 @@ + #include <linux/vmw_vmci_api.h> + #include <linux/list.h> + #include <linux/module.h> ++#include <linux/nospec.h> + #include <linux/sched.h> + #include <linux/slab.h> + #include <linux/rculist.h> +@@ -86,9 +87,12 @@ static void event_deliver(struct vmci_event_msg *event_msg) + { + struct vmci_subscription *cur; + struct list_head *subscriber_list; ++ u32 sanitized_event, max_vmci_event; + + rcu_read_lock(); +- subscriber_list = &subscriber_array[event_msg->event_data.event]; ++ max_vmci_event = ARRAY_SIZE(subscriber_array); ++ sanitized_event = array_index_nospec(event_msg->event_data.event, max_vmci_event); ++ subscriber_list = &subscriber_array[sanitized_event]; + list_for_each_entry_rcu(cur, subscriber_list, node) { + cur->callback(cur->id, &event_msg->event_data, + cur->callback_data); +diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c +index 80de660027d89..e0175808c3b0d 100644 +--- a/drivers/mmc/host/davinci_mmc.c ++++ b/drivers/mmc/host/davinci_mmc.c +@@ -1347,7 +1347,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev) + return ret; + } + +-static int __exit davinci_mmcsd_remove(struct platform_device *pdev) ++static void davinci_mmcsd_remove(struct platform_device *pdev) + { + struct mmc_davinci_host *host = platform_get_drvdata(pdev); + +@@ -1356,8 +1356,6 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev) + davinci_release_dma_channels(host); + clk_disable_unprepare(host->clk); + mmc_free_host(host->mmc); +- +- return 0; + } + + #ifdef CONFIG_PM +@@ -1404,7 +1402,7 @@ static struct platform_driver davinci_mmcsd_driver = { + .of_match_table = davinci_mmc_dt_ids, + }, + .probe = davinci_mmcsd_probe, +- .remove = __exit_p(davinci_mmcsd_remove), ++ .remove_new = davinci_mmcsd_remove, + .id_table = davinci_mmc_devtype, + }; + +diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c +index 8736e04fa73cc..7c231557855f1 100644 +--- a/drivers/mmc/host/sdhci-pci-core.c ++++ b/drivers/mmc/host/sdhci-pci-core.c +@@ -1399,7 +1399,7 @@ static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) + + ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch); + if (ret) +- return ret; ++ goto fail; + + /* + * Turn PMOS on [bit 0], set over current detection to 2.4 V +@@ -1410,7 +1410,10 @@ static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) + else + scratch &= ~0x47; + +- return pci_write_config_byte(chip->pdev, 0xAE, scratch); ++ ret = pci_write_config_byte(chip->pdev, 0xAE, scratch); ++ ++fail: ++ return pcibios_err_to_errno(ret); + } + + static int jmicron_probe(struct sdhci_pci_chip *chip) +@@ -2327,7 +2330,7 @@ static int sdhci_pci_probe(struct pci_dev *pdev, + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); + if (ret) +- return ret; ++ return pcibios_err_to_errno(ret); + + slots = PCI_SLOT_INFO_SLOTS(slots) + 1; + dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); +@@ -2336,7 +2339,7 @@ static int sdhci_pci_probe(struct pci_dev *pdev, + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); + if (ret) +- return ret; ++ return pcibios_err_to_errno(ret); + + first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; + +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index d897c981b079f..c0900b2f7b5c8 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -2487,26 +2487,29 @@ static int sdhci_get_cd(struct mmc_host *mmc) + + static int sdhci_check_ro(struct sdhci_host *host) + { +- unsigned long flags; ++ bool allow_invert = false; + int is_readonly; + +- spin_lock_irqsave(&host->lock, flags); +- +- if (host->flags & SDHCI_DEVICE_DEAD) ++ if (host->flags & SDHCI_DEVICE_DEAD) { + is_readonly = 0; +- else if (host->ops->get_ro) ++ } else if (host->ops->get_ro) { + is_readonly = host->ops->get_ro(host); +- else if (mmc_can_gpio_ro(host->mmc)) ++ } else if (mmc_can_gpio_ro(host->mmc)) { + is_readonly = mmc_gpio_get_ro(host->mmc); +- else ++ /* Do not invert twice */ ++ allow_invert = !(host->mmc->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); ++ } else { + is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) + & SDHCI_WRITE_PROTECT); ++ allow_invert = true; ++ } + +- spin_unlock_irqrestore(&host->lock, flags); ++ if (is_readonly >= 0 && ++ allow_invert && ++ (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)) ++ is_readonly = !is_readonly; + +- /* This quirk needs to be replaced by a callback-function later */ +- return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? +- !is_readonly : is_readonly; ++ return is_readonly; + } + + #define SAMPLE_COUNT 5 +diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c +index a16b42a885816..3b55b676ca6b9 100644 +--- a/drivers/mtd/parsers/redboot.c ++++ b/drivers/mtd/parsers/redboot.c +@@ -102,7 +102,7 @@ static int parse_redboot_partitions(struct mtd_info *master, + offset -= master->erasesize; + } + } else { +- offset = directory * master->erasesize; ++ offset = (unsigned long) directory * master->erasesize; + while (mtd_block_isbad(master, offset)) { + offset += master->erasesize; + if (offset == master->size) +diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c +index bf788e17f408f..d61ad951e8a86 100644 +--- a/drivers/net/dsa/microchip/ksz9477.c ++++ b/drivers/net/dsa/microchip/ksz9477.c +@@ -195,7 +195,6 @@ static int ksz9477_wait_alu_sta_ready(struct ksz_device *dev) + + static int ksz9477_reset_switch(struct ksz_device *dev) + { +- u8 data8; + u32 data32; + + /* reset switch */ +@@ -206,10 +205,8 @@ static int ksz9477_reset_switch(struct ksz_device *dev) + SPI_AUTO_EDGE_DETECTION, 0); + + /* default configuration */ +- ksz_read8(dev, REG_SW_LUE_CTRL_1, &data8); +- data8 = SW_AGING_ENABLE | SW_LINK_AUTO_AGING | +- SW_SRC_ADDR_FILTER | SW_FLUSH_STP_TABLE | SW_FLUSH_MSTP_TABLE; +- ksz_write8(dev, REG_SW_LUE_CTRL_1, data8); ++ ksz_write8(dev, REG_SW_LUE_CTRL_1, ++ SW_AGING_ENABLE | SW_LINK_AUTO_AGING | SW_SRC_ADDR_FILTER); + + /* disable interrupts */ + ksz_write32(dev, REG_SW_INT_MASK__4, SWITCH_INT_MASK); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 3888561a5cc8f..f3c6a122a079a 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -667,9 +667,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_OK; + + tx_dma_error: +- if (BNXT_TX_PTP_IS_SET(lflags)) +- atomic_inc(&bp->ptp_cfg->tx_avail); +- + last_frag = i; + + /* start back at beginning and unmap skb */ +@@ -691,6 +688,8 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) + tx_free: + dev_kfree_skb_any(skb); + tx_kick_pending: ++ if (BNXT_TX_PTP_IS_SET(lflags)) ++ atomic_inc(&bp->ptp_cfg->tx_avail); + if (txr->kick_pending) + bnxt_txr_db_kick(bp, txr, txr->tx_prod); + txr->tx_buf_ring[txr->tx_prod].skb = NULL; +diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c +index 600de587d7a98..e70b9ccca380e 100644 +--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c ++++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c +@@ -272,13 +272,12 @@ lio_vf_rep_copy_packet(struct octeon_device *oct, + pg_info->page_offset; + memcpy(skb->data, va, MIN_SKB_SIZE); + skb_put(skb, MIN_SKB_SIZE); ++ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, ++ pg_info->page, ++ pg_info->page_offset + MIN_SKB_SIZE, ++ len - MIN_SKB_SIZE, ++ LIO_RXBUFFER_SZ); + } +- +- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, +- pg_info->page, +- pg_info->page_offset + MIN_SKB_SIZE, +- len - MIN_SKB_SIZE, +- LIO_RXBUFFER_SZ); + } else { + struct octeon_skb_page_info *pg_info = + ((struct octeon_skb_page_info *)(skb->cb)); +diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +index 78040a09313ef..fa1b1b7dd8a06 100644 +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +@@ -2468,11 +2468,14 @@ static int dpaa2_eth_xdp_xmit(struct net_device *net_dev, int n, + static int update_xps(struct dpaa2_eth_priv *priv) + { + struct net_device *net_dev = priv->net_dev; +- struct cpumask xps_mask; +- struct dpaa2_eth_fq *fq; + int i, num_queues, netdev_queues; ++ struct dpaa2_eth_fq *fq; ++ cpumask_var_t xps_mask; + int err = 0; + ++ if (!alloc_cpumask_var(&xps_mask, GFP_KERNEL)) ++ return -ENOMEM; ++ + num_queues = dpaa2_eth_queue_count(priv); + netdev_queues = (net_dev->num_tc ? : 1) * num_queues; + +@@ -2482,16 +2485,17 @@ static int update_xps(struct dpaa2_eth_priv *priv) + for (i = 0; i < netdev_queues; i++) { + fq = &priv->fq[i % num_queues]; + +- cpumask_clear(&xps_mask); +- cpumask_set_cpu(fq->target_cpu, &xps_mask); ++ cpumask_clear(xps_mask); ++ cpumask_set_cpu(fq->target_cpu, xps_mask); + +- err = netif_set_xps_queue(net_dev, &xps_mask, i); ++ err = netif_set_xps_queue(net_dev, xps_mask, i); + if (err) { + netdev_warn_once(net_dev, "Error setting XPS queue\n"); + break; + } + } + ++ free_cpumask_var(xps_mask); + return err; + } + +diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h +index 08f4c0595efae..822bdaff66f69 100644 +--- a/drivers/net/ethernet/google/gve/gve.h ++++ b/drivers/net/ethernet/google/gve/gve.h +@@ -144,6 +144,15 @@ struct gve_index_list { + s16 tail; + }; + ++/* A single received packet split across multiple buffers may be ++ * reconstructed using the information in this structure. ++ */ ++struct gve_rx_ctx { ++ /* head and tail of skb chain for the current packet or NULL if none */ ++ struct sk_buff *skb_head; ++ struct sk_buff *skb_tail; ++}; ++ + /* Contains datapath state used to represent an RX queue. */ + struct gve_rx_ring { + struct gve_priv *gve; +@@ -208,9 +217,7 @@ struct gve_rx_ring { + dma_addr_t q_resources_bus; /* dma address for the queue resources */ + struct u64_stats_sync statss; /* sync stats for 32bit archs */ + +- /* head and tail of skb chain for the current packet or NULL if none */ +- struct sk_buff *skb_head; +- struct sk_buff *skb_tail; ++ struct gve_rx_ctx ctx; /* Info for packet currently being processed in this ring. */ + }; + + /* A TX desc ring entry */ +diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c +index d947c2c334128..8756f9cbd631e 100644 +--- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c ++++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c +@@ -240,8 +240,8 @@ static int gve_rx_alloc_ring_dqo(struct gve_priv *priv, int idx) + rx->dqo.bufq.mask = buffer_queue_slots - 1; + rx->dqo.complq.num_free_slots = completion_queue_slots; + rx->dqo.complq.mask = completion_queue_slots - 1; +- rx->skb_head = NULL; +- rx->skb_tail = NULL; ++ rx->ctx.skb_head = NULL; ++ rx->ctx.skb_tail = NULL; + + rx->dqo.num_buf_states = min_t(s16, S16_MAX, buffer_queue_slots * 4); + rx->dqo.buf_states = kvcalloc(rx->dqo.num_buf_states, +@@ -465,14 +465,16 @@ static void gve_rx_skb_hash(struct sk_buff *skb, + skb_set_hash(skb, le32_to_cpu(compl_desc->hash), hash_type); + } + +-static void gve_rx_free_skb(struct gve_rx_ring *rx) ++static void gve_rx_free_skb(struct napi_struct *napi, struct gve_rx_ring *rx) + { +- if (!rx->skb_head) ++ if (!rx->ctx.skb_head) + return; + +- dev_kfree_skb_any(rx->skb_head); +- rx->skb_head = NULL; +- rx->skb_tail = NULL; ++ if (rx->ctx.skb_head == napi->skb) ++ napi->skb = NULL; ++ dev_kfree_skb_any(rx->ctx.skb_head); ++ rx->ctx.skb_head = NULL; ++ rx->ctx.skb_tail = NULL; + } + + /* Chains multi skbs for single rx packet. +@@ -483,7 +485,7 @@ static int gve_rx_append_frags(struct napi_struct *napi, + u16 buf_len, struct gve_rx_ring *rx, + struct gve_priv *priv) + { +- int num_frags = skb_shinfo(rx->skb_tail)->nr_frags; ++ int num_frags = skb_shinfo(rx->ctx.skb_tail)->nr_frags; + + if (unlikely(num_frags == MAX_SKB_FRAGS)) { + struct sk_buff *skb; +@@ -492,17 +494,17 @@ static int gve_rx_append_frags(struct napi_struct *napi, + if (!skb) + return -1; + +- skb_shinfo(rx->skb_tail)->frag_list = skb; +- rx->skb_tail = skb; ++ skb_shinfo(rx->ctx.skb_tail)->frag_list = skb; ++ rx->ctx.skb_tail = skb; + num_frags = 0; + } +- if (rx->skb_tail != rx->skb_head) { +- rx->skb_head->len += buf_len; +- rx->skb_head->data_len += buf_len; +- rx->skb_head->truesize += priv->data_buffer_size_dqo; ++ if (rx->ctx.skb_tail != rx->ctx.skb_head) { ++ rx->ctx.skb_head->len += buf_len; ++ rx->ctx.skb_head->data_len += buf_len; ++ rx->ctx.skb_head->truesize += priv->data_buffer_size_dqo; + } + +- skb_add_rx_frag(rx->skb_tail, num_frags, ++ skb_add_rx_frag(rx->ctx.skb_tail, num_frags, + buf_state->page_info.page, + buf_state->page_info.page_offset, + buf_len, priv->data_buffer_size_dqo); +@@ -556,7 +558,7 @@ static int gve_rx_dqo(struct napi_struct *napi, struct gve_rx_ring *rx, + buf_len, DMA_FROM_DEVICE); + + /* Append to current skb if one exists. */ +- if (rx->skb_head) { ++ if (rx->ctx.skb_head) { + if (unlikely(gve_rx_append_frags(napi, buf_state, buf_len, rx, + priv)) != 0) { + goto error; +@@ -567,11 +569,11 @@ static int gve_rx_dqo(struct napi_struct *napi, struct gve_rx_ring *rx, + } + + if (eop && buf_len <= priv->rx_copybreak) { +- rx->skb_head = gve_rx_copy(priv->dev, napi, +- &buf_state->page_info, buf_len, 0); +- if (unlikely(!rx->skb_head)) ++ rx->ctx.skb_head = gve_rx_copy(priv->dev, napi, ++ &buf_state->page_info, buf_len, 0); ++ if (unlikely(!rx->ctx.skb_head)) + goto error; +- rx->skb_tail = rx->skb_head; ++ rx->ctx.skb_tail = rx->ctx.skb_head; + + u64_stats_update_begin(&rx->statss); + rx->rx_copied_pkt++; +@@ -583,12 +585,12 @@ static int gve_rx_dqo(struct napi_struct *napi, struct gve_rx_ring *rx, + return 0; + } + +- rx->skb_head = napi_get_frags(napi); +- if (unlikely(!rx->skb_head)) ++ rx->ctx.skb_head = napi_get_frags(napi); ++ if (unlikely(!rx->ctx.skb_head)) + goto error; +- rx->skb_tail = rx->skb_head; ++ rx->ctx.skb_tail = rx->ctx.skb_head; + +- skb_add_rx_frag(rx->skb_head, 0, buf_state->page_info.page, ++ skb_add_rx_frag(rx->ctx.skb_head, 0, buf_state->page_info.page, + buf_state->page_info.page_offset, buf_len, + priv->data_buffer_size_dqo); + gve_dec_pagecnt_bias(&buf_state->page_info); +@@ -635,27 +637,27 @@ static int gve_rx_complete_skb(struct gve_rx_ring *rx, struct napi_struct *napi, + rx->gve->ptype_lut_dqo->ptypes[desc->packet_type]; + int err; + +- skb_record_rx_queue(rx->skb_head, rx->q_num); ++ skb_record_rx_queue(rx->ctx.skb_head, rx->q_num); + + if (feat & NETIF_F_RXHASH) +- gve_rx_skb_hash(rx->skb_head, desc, ptype); ++ gve_rx_skb_hash(rx->ctx.skb_head, desc, ptype); + + if (feat & NETIF_F_RXCSUM) +- gve_rx_skb_csum(rx->skb_head, desc, ptype); ++ gve_rx_skb_csum(rx->ctx.skb_head, desc, ptype); + + /* RSC packets must set gso_size otherwise the TCP stack will complain + * that packets are larger than MTU. + */ + if (desc->rsc) { +- err = gve_rx_complete_rsc(rx->skb_head, desc, ptype); ++ err = gve_rx_complete_rsc(rx->ctx.skb_head, desc, ptype); + if (err < 0) + return err; + } + +- if (skb_headlen(rx->skb_head) == 0) ++ if (skb_headlen(rx->ctx.skb_head) == 0) + napi_gro_frags(napi); + else +- napi_gro_receive(napi, rx->skb_head); ++ napi_gro_receive(napi, rx->ctx.skb_head); + + return 0; + } +@@ -690,7 +692,7 @@ int gve_rx_poll_dqo(struct gve_notify_block *block, int budget) + + err = gve_rx_dqo(napi, rx, compl_desc, rx->q_num); + if (err < 0) { +- gve_rx_free_skb(rx); ++ gve_rx_free_skb(napi, rx); + u64_stats_update_begin(&rx->statss); + if (err == -ENOMEM) + rx->rx_skb_alloc_fail++; +@@ -717,23 +719,23 @@ int gve_rx_poll_dqo(struct gve_notify_block *block, int budget) + /* Free running counter of completed descriptors */ + rx->cnt++; + +- if (!rx->skb_head) ++ if (!rx->ctx.skb_head) + continue; + + if (!compl_desc->end_of_packet) + continue; + + work_done++; +- pkt_bytes = rx->skb_head->len; ++ pkt_bytes = rx->ctx.skb_head->len; + /* The ethernet header (first ETH_HLEN bytes) is snipped off + * by eth_type_trans. + */ +- if (skb_headlen(rx->skb_head)) ++ if (skb_headlen(rx->ctx.skb_head)) + pkt_bytes += ETH_HLEN; + + /* gve_rx_complete_skb() will consume skb if successful */ + if (gve_rx_complete_skb(rx, napi, compl_desc, feat) != 0) { +- gve_rx_free_skb(rx); ++ gve_rx_free_skb(napi, rx); + u64_stats_update_begin(&rx->statss); + rx->rx_desc_err_dropped_pkt++; + u64_stats_update_end(&rx->statss); +@@ -741,8 +743,8 @@ int gve_rx_poll_dqo(struct gve_notify_block *block, int budget) + } + + bytes += pkt_bytes; +- rx->skb_head = NULL; +- rx->skb_tail = NULL; ++ rx->ctx.skb_head = NULL; ++ rx->ctx.skb_tail = NULL; + } + + gve_rx_post_buffers_dqo(rx); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index bbbafd8aa1b09..e48d33927c176 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -3342,6 +3342,9 @@ static int hns3_alloc_ring_buffers(struct hns3_enet_ring *ring) + ret = hns3_alloc_and_attach_buffer(ring, i); + if (ret) + goto out_buffer_fail; ++ ++ if (!(i % HNS3_RESCHED_BD_NUM)) ++ cond_resched(); + } + + return 0; +@@ -4887,6 +4890,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv) + } + + u64_stats_init(&priv->ring[i].syncp); ++ cond_resched(); + } + + return 0; +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +index 91b656adaacb0..f60ba2ee8b8b1 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +@@ -206,6 +206,8 @@ enum hns3_nic_state { + #define HNS3_CQ_MODE_EQE 1U + #define HNS3_CQ_MODE_CQE 0U + ++#define HNS3_RESCHED_BD_NUM 1024 ++ + enum hns3_pkt_l2t_type { + HNS3_L2_TYPE_UNICAST, + HNS3_L2_TYPE_MULTICAST, +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index d58048b056781..c3690e49c3d95 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -2948,9 +2948,7 @@ static void hclge_push_link_status(struct hclge_dev *hdev) + + static void hclge_update_link_status(struct hclge_dev *hdev) + { +- struct hnae3_handle *rhandle = &hdev->vport[0].roce; + struct hnae3_handle *handle = &hdev->vport[0].nic; +- struct hnae3_client *rclient = hdev->roce_client; + struct hnae3_client *client = hdev->nic_client; + int state; + int ret; +@@ -2974,8 +2972,15 @@ static void hclge_update_link_status(struct hclge_dev *hdev) + + client->ops->link_status_change(handle, state); + hclge_config_mac_tnl_int(hdev, state); +- if (rclient && rclient->ops->link_status_change) +- rclient->ops->link_status_change(rhandle, state); ++ ++ if (test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state)) { ++ struct hnae3_handle *rhandle = &hdev->vport[0].roce; ++ struct hnae3_client *rclient = hdev->roce_client; ++ ++ if (rclient && rclient->ops->link_status_change) ++ rclient->ops->link_status_change(rhandle, ++ state); ++ } + + hclge_push_link_status(hdev); + } +@@ -11431,6 +11436,12 @@ static int hclge_init_client_instance(struct hnae3_client *client, + return ret; + } + ++static bool hclge_uninit_need_wait(struct hclge_dev *hdev) ++{ ++ return test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || ++ test_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state); ++} ++ + static void hclge_uninit_client_instance(struct hnae3_client *client, + struct hnae3_ae_dev *ae_dev) + { +@@ -11439,7 +11450,7 @@ static void hclge_uninit_client_instance(struct hnae3_client *client, + + if (hdev->roce_client) { + clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state); +- while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) ++ while (hclge_uninit_need_wait(hdev)) + msleep(HCLGE_WAIT_RESET_DONE); + + hdev->roce_client->ops->uninit_instance(&vport->roce, 0); +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 890e27b986e2a..7f4539a2e5517 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -3409,6 +3409,12 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter, bool do_h_free) + adapter->num_active_tx_scrqs = 0; + } + ++ /* Clean any remaining outstanding SKBs ++ * we freed the irq so we won't be hearing ++ * from them ++ */ ++ clean_tx_pools(adapter); ++ + if (adapter->rx_scrq) { + for (i = 0; i < adapter->num_active_rx_scrqs; i++) { + if (!adapter->rx_scrq[i]) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +index c6b6d709e5908..84003243e3b75 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +@@ -2459,7 +2459,17 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc, + * - when available free entries are less. + * Lower priority ones out of avaialble free entries are always + * chosen when 'high vs low' question arises. ++ * ++ * For a VF base MCAM match rule is set by its PF. And all the ++ * further MCAM rules installed by VF on its own are ++ * concatenated with the base rule set by its PF. Hence PF entries ++ * should be at lower priority compared to VF entries. Otherwise ++ * base rule is hit always and rules installed by VF will be of ++ * no use. Hence if the request is from PF then allocate low ++ * priority entries. + */ ++ if (!(pcifunc & RVU_PFVF_FUNC_MASK)) ++ goto lprio_alloc; + + /* Get the search range for priority allocation request */ + if (req->priority) { +@@ -2468,17 +2478,6 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc, + goto alloc; + } + +- /* For a VF base MCAM match rule is set by its PF. And all the +- * further MCAM rules installed by VF on its own are +- * concatenated with the base rule set by its PF. Hence PF entries +- * should be at lower priority compared to VF entries. Otherwise +- * base rule is hit always and rules installed by VF will be of +- * no use. Hence if the request is from PF and NOT a priority +- * allocation request then allocate low priority entries. +- */ +- if (!(pcifunc & RVU_PFVF_FUNC_MASK)) +- goto lprio_alloc; +- + /* Find out the search range for non-priority allocation request + * + * Get MCAM free entry count in middle zone. +@@ -2508,6 +2507,18 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc, + reverse = true; + start = 0; + end = mcam->bmap_entries; ++ /* Ensure PF requests are always at bottom and if PF requests ++ * for higher/lower priority entry wrt reference entry then ++ * honour that criteria and start search for entries from bottom ++ * and not in mid zone. ++ */ ++ if (!(pcifunc & RVU_PFVF_FUNC_MASK) && ++ req->priority == NPC_MCAM_HIGHER_PRIO) ++ end = req->ref_entry; ++ ++ if (!(pcifunc & RVU_PFVF_FUNC_MASK) && ++ req->priority == NPC_MCAM_LOWER_PRIO) ++ start = req->ref_entry; + } + + alloc: +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +index d1e3928a24f5c..761eb8671096e 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +@@ -933,8 +933,11 @@ bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq, + + if (skb_shinfo(skb)->gso_size && !is_hw_tso_supported(pfvf, skb)) { + /* Insert vlan tag before giving pkt to tso */ +- if (skb_vlan_tag_present(skb)) ++ if (skb_vlan_tag_present(skb)) { + skb = __vlan_hwaccel_push_inside(skb); ++ if (!skb) ++ return true; ++ } + otx2_sq_append_tso(pfvf, sq, skb, qidx); + return true; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 79d687c663d54..a0870da414538 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -3989,7 +3989,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv, + + /* Verify if UDP port is being offloaded by HW */ + if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port)) +- return features; ++ return vxlan_features_check(skb, features); + + #if IS_ENABLED(CONFIG_GENEVE) + /* Support Geneve offload for default UDP port */ +@@ -4015,7 +4015,6 @@ netdev_features_t mlx5e_features_check(struct sk_buff *skb, + struct mlx5e_priv *priv = netdev_priv(netdev); + + features = vlan_features_check(skb, features); +- features = vxlan_features_check(skb, features); + + /* Validate if the tunneled packet is being offloaded by HW */ + if (skb->encapsulation && +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +index 1f84ba638e6eb..b791fba82c2fd 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c +@@ -283,10 +283,8 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq) + if (ret) + return ret; + +- if (qcq->napi.poll) +- napi_enable(&qcq->napi); +- + if (qcq->flags & IONIC_QCQ_F_INTR) { ++ napi_enable(&qcq->napi); + irq_set_affinity_hint(qcq->intr.vector, + &qcq->intr.affinity_mask); + ionic_intr_mask(idev->intr_ctrl, qcq->intr.index, +diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c +index 8b61bebd96e4b..9819a0c810f5c 100644 +--- a/drivers/net/ethernet/qualcomm/qca_debug.c ++++ b/drivers/net/ethernet/qualcomm/qca_debug.c +@@ -111,10 +111,8 @@ qcaspi_info_show(struct seq_file *s, void *what) + + seq_printf(s, "IRQ : %d\n", + qca->spi_dev->irq); +- seq_printf(s, "INTR REQ : %u\n", +- qca->intr_req); +- seq_printf(s, "INTR SVC : %u\n", +- qca->intr_svc); ++ seq_printf(s, "INTR : %lx\n", ++ qca->intr); + + seq_printf(s, "SPI max speed : %lu\n", + (unsigned long)qca->spi_dev->max_speed_hz); +diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c +index e02f6ac0125d1..385e4c62ca03c 100644 +--- a/drivers/net/ethernet/qualcomm/qca_spi.c ++++ b/drivers/net/ethernet/qualcomm/qca_spi.c +@@ -49,6 +49,8 @@ + + #define MAX_DMA_BURST_LEN 5000 + ++#define SPI_INTR 0 ++ + /* Modules parameters */ + #define QCASPI_CLK_SPEED_MIN 1000000 + #define QCASPI_CLK_SPEED_MAX 16000000 +@@ -593,14 +595,14 @@ qcaspi_spi_thread(void *data) + continue; + } + +- if ((qca->intr_req == qca->intr_svc) && ++ if (!test_bit(SPI_INTR, &qca->intr) && + !qca->txr.skb[qca->txr.head]) + schedule(); + + set_current_state(TASK_RUNNING); + +- netdev_dbg(qca->net_dev, "have work to do. int: %d, tx_skb: %p\n", +- qca->intr_req - qca->intr_svc, ++ netdev_dbg(qca->net_dev, "have work to do. int: %lu, tx_skb: %p\n", ++ qca->intr, + qca->txr.skb[qca->txr.head]); + + qcaspi_qca7k_sync(qca, QCASPI_EVENT_UPDATE); +@@ -614,8 +616,7 @@ qcaspi_spi_thread(void *data) + msleep(QCASPI_QCA7K_REBOOT_TIME_MS); + } + +- if (qca->intr_svc != qca->intr_req) { +- qca->intr_svc = qca->intr_req; ++ if (test_and_clear_bit(SPI_INTR, &qca->intr)) { + start_spi_intr_handling(qca, &intr_cause); + + if (intr_cause & SPI_INT_CPU_ON) { +@@ -677,7 +678,7 @@ qcaspi_intr_handler(int irq, void *data) + { + struct qcaspi *qca = data; + +- qca->intr_req++; ++ set_bit(SPI_INTR, &qca->intr); + if (qca->spi_thread) + wake_up_process(qca->spi_thread); + +@@ -693,8 +694,7 @@ qcaspi_netdev_open(struct net_device *dev) + if (!qca) + return -EINVAL; + +- qca->intr_req = 1; +- qca->intr_svc = 0; ++ set_bit(SPI_INTR, &qca->intr); + qca->sync = QCASPI_SYNC_UNKNOWN; + qcafrm_fsm_init_spi(&qca->frm_handle); + +diff --git a/drivers/net/ethernet/qualcomm/qca_spi.h b/drivers/net/ethernet/qualcomm/qca_spi.h +index 3067356106f0b..58ad910068d4b 100644 +--- a/drivers/net/ethernet/qualcomm/qca_spi.h ++++ b/drivers/net/ethernet/qualcomm/qca_spi.h +@@ -93,8 +93,7 @@ struct qcaspi { + struct qcafrm_handle frm_handle; + struct sk_buff *rx_skb; + +- unsigned int intr_req; +- unsigned int intr_svc; ++ unsigned long intr; + u16 reset_count; + + #ifdef CONFIG_DEBUG_FS +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +index 2c6245b2281ca..0d3d7874f0fc6 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +@@ -176,6 +176,7 @@ static void timestamp_interrupt(struct stmmac_priv *priv) + { + u32 num_snapshot, ts_status, tsync_int; + struct ptp_clock_event event; ++ u32 acr_value, channel; + unsigned long flags; + u64 ptp_time; + int i; +@@ -201,12 +202,15 @@ static void timestamp_interrupt(struct stmmac_priv *priv) + num_snapshot = (ts_status & GMAC_TIMESTAMP_ATSNS_MASK) >> + GMAC_TIMESTAMP_ATSNS_SHIFT; + ++ acr_value = readl(priv->ptpaddr + PTP_ACR); ++ channel = ilog2(FIELD_GET(PTP_ACR_MASK, acr_value)); ++ + for (i = 0; i < num_snapshot; i++) { + spin_lock_irqsave(&priv->ptp_lock, flags); + get_ptptime(priv->ptpaddr, &ptp_time); + spin_unlock_irqrestore(&priv->ptp_lock, flags); + event.type = PTP_CLOCK_EXTTS; +- event.index = 0; ++ event.index = channel; + event.timestamp = ptp_time; + ptp_clock_event(priv->ptp_clock, &event); + } +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +index 08cffc0558743..b1a5a02bef08e 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +@@ -341,10 +341,11 @@ static int tc_setup_cbs(struct stmmac_priv *priv, + struct tc_cbs_qopt_offload *qopt) + { + u32 tx_queues_count = priv->plat->tx_queues_to_use; ++ s64 port_transmit_rate_kbps; + u32 queue = qopt->queue; +- u32 ptr, speed_div; + u32 mode_to_use; + u64 value; ++ u32 ptr; + int ret; + + /* Queue 0 is not AVB capable */ +@@ -353,30 +354,30 @@ static int tc_setup_cbs(struct stmmac_priv *priv, + if (!priv->dma_cap.av) + return -EOPNOTSUPP; + +- /* Port Transmit Rate and Speed Divider */ +- switch (priv->speed) { +- case SPEED_10000: +- ptr = 32; +- speed_div = 10000000; +- break; +- case SPEED_5000: +- ptr = 32; +- speed_div = 5000000; +- break; +- case SPEED_2500: +- ptr = 8; +- speed_div = 2500000; +- break; +- case SPEED_1000: +- ptr = 8; +- speed_div = 1000000; +- break; +- case SPEED_100: +- ptr = 4; +- speed_div = 100000; +- break; +- default: +- return -EOPNOTSUPP; ++ port_transmit_rate_kbps = qopt->idleslope - qopt->sendslope; ++ ++ if (qopt->enable) { ++ /* Port Transmit Rate and Speed Divider */ ++ switch (div_s64(port_transmit_rate_kbps, 1000)) { ++ case SPEED_10000: ++ case SPEED_5000: ++ ptr = 32; ++ break; ++ case SPEED_2500: ++ case SPEED_1000: ++ ptr = 8; ++ break; ++ case SPEED_100: ++ ptr = 4; ++ break; ++ default: ++ netdev_err(priv->dev, ++ "Invalid portTransmitRate %lld (idleSlope - sendSlope)\n", ++ port_transmit_rate_kbps); ++ return -EINVAL; ++ } ++ } else { ++ ptr = 0; + } + + mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use; +@@ -396,10 +397,10 @@ static int tc_setup_cbs(struct stmmac_priv *priv, + } + + /* Final adjustments for HW */ +- value = div_s64(qopt->idleslope * 1024ll * ptr, speed_div); ++ value = div_s64(qopt->idleslope * 1024ll * ptr, port_transmit_rate_kbps); + priv->plat->tx_queues_cfg[queue].idle_slope = value & GENMASK(31, 0); + +- value = div_s64(-qopt->sendslope * 1024ll * ptr, speed_div); ++ value = div_s64(-qopt->sendslope * 1024ll * ptr, port_transmit_rate_kbps); + priv->plat->tx_queues_cfg[queue].send_slope = value & GENMASK(31, 0); + + value = qopt->hicredit * 1024ll * 8; +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index 59d05a1672ece..f1a6cc7ccf1a3 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -1798,6 +1798,7 @@ static struct mdio_device_id __maybe_unused micrel_tbl[] = { + { PHY_ID_KSZ8081, MICREL_PHY_ID_MASK }, + { PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK }, + { PHY_ID_KSZ886X, MICREL_PHY_ID_MASK }, ++ { PHY_ID_KSZ9477, MICREL_PHY_ID_MASK }, + { PHY_ID_LAN8814, MICREL_PHY_ID_MASK }, + { } + }; +diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c +index d5918605eae6f..2bb30d635bbca 100644 +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -2004,8 +2004,7 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event) + + /* Handle remove event globally, it resets this state machine */ + if (event == SFP_E_REMOVE) { +- if (sfp->sm_mod_state > SFP_MOD_PROBE) +- sfp_sm_mod_remove(sfp); ++ sfp_sm_mod_remove(sfp); + sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); + return; + } +diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c +index 868fad2f8c78a..2d6b8fddb9d4e 100644 +--- a/drivers/net/usb/ax88179_178a.c ++++ b/drivers/net/usb/ax88179_178a.c +@@ -326,7 +326,8 @@ static void ax88179_status(struct usbnet *dev, struct urb *urb) + + if (netif_carrier_ok(dev->net) != link) { + usbnet_link_change(dev, link, 1); +- netdev_info(dev->net, "ax88179 - Link status is: %d\n", link); ++ if (!link) ++ netdev_info(dev->net, "ax88179 - Link status is: 0\n"); + } + } + +@@ -1558,6 +1559,7 @@ static int ax88179_link_reset(struct usbnet *dev) + GMII_PHY_PHYSR, 2, &tmp16); + + if (!(tmp16 & GMII_PHY_PHYSR_LINK)) { ++ netdev_info(dev->net, "ax88179 - Link status is: 0\n"); + return 0; + } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) { + mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ; +@@ -1595,6 +1597,8 @@ static int ax88179_link_reset(struct usbnet *dev) + + netif_carrier_on(dev->net); + ++ netdev_info(dev->net, "ax88179 - Link status is: 1\n"); ++ + return 0; + } + +diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c +index 4a1b0e0fc3a3a..17b87aba11d19 100644 +--- a/drivers/net/usb/rtl8150.c ++++ b/drivers/net/usb/rtl8150.c +@@ -778,7 +778,8 @@ static int rtl8150_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *ecmd) + { + rtl8150_t *dev = netdev_priv(netdev); +- short lpa, bmcr; ++ short lpa = 0; ++ short bmcr = 0; + u32 supported; + + supported = (SUPPORTED_10baseT_Half | +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 6a655bd442fe3..bd0cb3a03b7b2 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3211,8 +3211,16 @@ static int virtnet_probe(struct virtio_device *vdev) + dev->features |= dev->hw_features & NETIF_F_ALL_TSO; + /* (!csum && gso) case will be fixed by register_netdev() */ + } +- if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) +- dev->features |= NETIF_F_RXCSUM; ++ ++ /* 1. With VIRTIO_NET_F_GUEST_CSUM negotiation, the driver doesn't ++ * need to calculate checksums for partially checksummed packets, ++ * as they're considered valid by the upper layer. ++ * 2. Without VIRTIO_NET_F_GUEST_CSUM negotiation, the driver only ++ * receives fully checksummed packets. The device may assist in ++ * validating these packets' checksums, so the driver won't have to. ++ */ ++ dev->features |= NETIF_F_RXCSUM; ++ + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) + dev->features |= NETIF_F_GRO_HW; +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index 41b1b23fdd3e9..65a2f4ab89970 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -1493,6 +1493,10 @@ static bool vxlan_snoop(struct net_device *dev, + struct vxlan_fdb *f; + u32 ifindex = 0; + ++ /* Ignore packets from invalid src-address */ ++ if (!is_valid_ether_addr(src_mac)) ++ return true; ++ + #if IS_ENABLED(CONFIG_IPV6) + if (src_ip->sa.sa_family == AF_INET6 && + (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)) +diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h +index f02a308a9ffc5..34654f710d8a1 100644 +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -171,8 +171,10 @@ struct ath_common { + unsigned int clockrate; + + spinlock_t cc_lock; +- struct ath_cycle_counters cc_ani; +- struct ath_cycle_counters cc_survey; ++ struct_group(cc, ++ struct ath_cycle_counters cc_ani; ++ struct ath_cycle_counters cc_survey; ++ ); + + struct ath_regulatory regulatory; + struct ath_regulatory reg_world_copy; +diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig +index ca007b800f756..02ca6f8d788d8 100644 +--- a/drivers/net/wireless/ath/ath10k/Kconfig ++++ b/drivers/net/wireless/ath/ath10k/Kconfig +@@ -44,6 +44,7 @@ config ATH10K_SNOC + tristate "Qualcomm ath10k SNOC support" + depends on ATH10K + depends on ARCH_QCOM || COMPILE_TEST ++ depends on QCOM_RPROC_COMMON || QCOM_RPROC_COMMON=n + select QCOM_SCM + select QCOM_QMI_HELPERS + help +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index 9e6d088bd2818..1b71fb1d04719 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -135,8 +135,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc) + if (power_mode != ATH9K_PM_AWAKE) { + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); +- memset(&common->cc_survey, 0, sizeof(common->cc_survey)); +- memset(&common->cc_ani, 0, sizeof(common->cc_ani)); ++ memset(&common->cc, 0, sizeof(common->cc)); + spin_unlock(&common->cc_lock); + } + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +index 524b0ad873578..afa89deb7bc3a 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +@@ -1667,8 +1667,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) + err_fw: + #ifdef CONFIG_IWLWIFI_DEBUGFS + debugfs_remove_recursive(drv->dbgfs_drv); +- iwl_dbg_tlv_free(drv->trans); + #endif ++ iwl_dbg_tlv_free(drv->trans); + kfree(drv); + err: + return ERR_PTR(ret); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +index d22a5628f9e0d..578956032e08b 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +@@ -95,20 +95,10 @@ void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm, + { + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_mfu_assert_dump_notif *mfu_dump_notif = (void *)pkt->data; +- __le32 *dump_data = mfu_dump_notif->data; +- int n_words = le32_to_cpu(mfu_dump_notif->data_size) / sizeof(__le32); +- int i; + + if (mfu_dump_notif->index_num == 0) + IWL_INFO(mvm, "MFUART assert id 0x%x occurred\n", + le32_to_cpu(mfu_dump_notif->assert_id)); +- +- for (i = 0; i < n_words; i++) +- IWL_DEBUG_INFO(mvm, +- "MFUART assert dump, dword %u: 0x%08x\n", +- le16_to_cpu(mfu_dump_notif->index_num) * +- n_words + i, +- le32_to_cpu(dump_data[i])); + } + + static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +index 32104c9f8f5ee..d59a47637d120 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +@@ -133,13 +133,8 @@ enum { + + #define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) + #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) +-/* +- * FIXME - various places in firmware API still use u8, +- * e.g. LQ command and SCD config command. +- * This should be 256 instead. +- */ +-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (255) +-#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (255) ++#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (64) ++#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (64) + #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) + + #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +index c0ffa26bc5aaa..0605363b62720 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +@@ -1312,7 +1312,7 @@ static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm, + if (IWL_MVM_ADWELL_MAX_BUDGET) + cmd->v7.adwell_max_budget = + cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET); +- else if (params->ssids && params->ssids[0].ssid_len) ++ else if (params->n_ssids && params->ssids[0].ssid_len) + cmd->v7.adwell_max_budget = + cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN); + else +@@ -1414,7 +1414,7 @@ iwl_mvm_scan_umac_dwell_v10(struct iwl_mvm *mvm, + if (IWL_MVM_ADWELL_MAX_BUDGET) + general_params->adwell_max_budget = + cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET); +- else if (params->ssids && params->ssids[0].ssid_len) ++ else if (params->n_ssids && params->ssids[0].ssid_len) + general_params->adwell_max_budget = + cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN); + else +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +index c3c07ca77614a..56b5cd032a9ac 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +@@ -892,8 +892,8 @@ static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl) + u8 place = chnl; + + if (chnl > 14) { +- for (place = 14; place < sizeof(channel5g); place++) { +- if (channel5g[place] == chnl) { ++ for (place = 14; place < ARRAY_SIZE(channel_all); place++) { ++ if (channel_all[place] == chnl) { + place++; + break; + } +@@ -1359,7 +1359,7 @@ u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl) + u8 place; + + if (chnl > 14) { +- for (place = 14; place < sizeof(channel_all); place++) { ++ for (place = 14; place < ARRAY_SIZE(channel_all); place++) { + if (channel_all[place] == chnl) + return place - 13; + } +@@ -2417,7 +2417,7 @@ static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel) + + int i; + +- for (i = 0; i < sizeof(channel5g); i++) ++ for (i = 0; i < ARRAY_SIZE(channel5g); i++) + if (channel == channel5g[i]) + return true; + return false; +@@ -2681,9 +2681,8 @@ void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw) + u8 i; + + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "settings regs %d default regs %d\n", +- (int)(sizeof(rtlphy->iqk_matrix) / +- sizeof(struct iqk_matrix_regs)), ++ "settings regs %zu default regs %d\n", ++ ARRAY_SIZE(rtlphy->iqk_matrix), + IQK_MATRIX_REG_NUM); + /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */ + for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { +@@ -2850,16 +2849,14 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) + case BAND_ON_5G: + /* Get first channel error when change between + * 5G and 2.4G band. */ +- if (channel <= 14) ++ if (WARN_ONCE(channel <= 14, "rtl8192de: 5G but channel<=14\n")) + return 0; +- WARN_ONCE((channel <= 14), "rtl8192de: 5G but channel<=14\n"); + break; + case BAND_ON_2_4G: + /* Get first channel error when change between + * 5G and 2.4G band. */ +- if (channel > 14) ++ if (WARN_ONCE(channel > 14, "rtl8192de: 2G but channel>14\n")) + return 0; +- WARN_ONCE((channel > 14), "rtl8192de: 2G but channel>14\n"); + break; + default: + WARN_ONCE(true, "rtl8192de: Invalid WirelessMode(%#x)!!\n", +diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h +index a1f223c8848b9..0bac788ccd6e3 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -108,7 +108,6 @@ + #define CHANNEL_GROUP_IDX_5GM 6 + #define CHANNEL_GROUP_IDX_5GH 9 + #define CHANNEL_GROUP_MAX_5G 9 +-#define CHANNEL_MAX_NUMBER_2G 14 + #define AVG_THERMAL_NUM 8 + #define AVG_THERMAL_NUM_88E 4 + #define AVG_THERMAL_NUM_8723BE 4 +diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c +index 9e949ddcb1464..6ec668ae2d6fa 100644 +--- a/drivers/of/of_reserved_mem.c ++++ b/drivers/of/of_reserved_mem.c +@@ -22,6 +22,7 @@ + #include <linux/slab.h> + #include <linux/memblock.h> + #include <linux/kmemleak.h> ++#include <linux/cma.h> + + #include "of_private.h" + +@@ -117,12 +118,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node, + if (IS_ENABLED(CONFIG_CMA) + && of_flat_dt_is_compatible(node, "shared-dma-pool") + && of_get_flat_dt_prop(node, "reusable", NULL) +- && !nomap) { +- unsigned long order = +- max_t(unsigned long, MAX_ORDER - 1, pageblock_order); +- +- align = max(align, (phys_addr_t)PAGE_SIZE << order); +- } ++ && !nomap) ++ align = max_t(phys_addr_t, align, CMA_MIN_ALIGNMENT_BYTES); + + prop = of_get_flat_dt_prop(node, "alloc-ranges", &len); + if (prop) { +diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c +index 0af0e965fb57e..1e3c3192d122c 100644 +--- a/drivers/pci/controller/pcie-rockchip-ep.c ++++ b/drivers/pci/controller/pcie-rockchip-ep.c +@@ -98,10 +98,8 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn, + + /* All functions share the same vendor ID with function 0 */ + if (fn == 0) { +- u32 vid_regs = (hdr->vendorid & GENMASK(15, 0)) | +- (hdr->subsys_vendor_id & GENMASK(31, 16)) << 16; +- +- rockchip_pcie_write(rockchip, vid_regs, ++ rockchip_pcie_write(rockchip, ++ hdr->vendorid | hdr->subsys_vendor_id << 16, + PCIE_CORE_CONFIG_VENDOR); + } + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 36f1e604191e5..67216f4ea2151 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -2901,6 +2901,18 @@ static const struct dmi_system_id bridge_d3_blacklist[] = { + DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"), + }, + }, ++ { ++ /* ++ * Changing power state of root port dGPU is connected fails ++ * https://gitlab.freedesktop.org/drm/amd/-/issues/3229 ++ */ ++ .ident = "Hewlett-Packard HP Pavilion 17 Notebook PC/1972", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_BOARD_NAME, "1972"), ++ DMI_MATCH(DMI_BOARD_VERSION, "95.33"), ++ }, ++ }, + #endif + { } + }; +diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c +index 46a06067e9947..f567805cbde8e 100644 +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -1092,8 +1092,8 @@ static struct pinctrl *create_pinctrl(struct device *dev, + * an -EPROBE_DEFER later, as that is the worst case. + */ + if (ret == -EPROBE_DEFER) { +- pinctrl_free(p, false); + mutex_unlock(&pinctrl_maps_mutex); ++ pinctrl_free(p, false); + return ERR_PTR(ret); + } + } +diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c +index a6f4aca9c61c4..4ff70527755a3 100644 +--- a/drivers/pinctrl/pinctrl-rockchip.c ++++ b/drivers/pinctrl/pinctrl-rockchip.c +@@ -564,23 +564,68 @@ static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { + + static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { + { +- .num = 2, +- .pin = 12, +- .reg = 0x24, +- .bit = 8, +- .mask = 0x3 +- }, { ++ /* gpio2_b7_sel */ + .num = 2, + .pin = 15, + .reg = 0x28, + .bit = 0, + .mask = 0x7 + }, { ++ /* gpio2_c7_sel */ + .num = 2, + .pin = 23, + .reg = 0x30, + .bit = 14, + .mask = 0x3 ++ }, { ++ /* gpio3_b1_sel */ ++ .num = 3, ++ .pin = 9, ++ .reg = 0x44, ++ .bit = 2, ++ .mask = 0x3 ++ }, { ++ /* gpio3_b2_sel */ ++ .num = 3, ++ .pin = 10, ++ .reg = 0x44, ++ .bit = 4, ++ .mask = 0x3 ++ }, { ++ /* gpio3_b3_sel */ ++ .num = 3, ++ .pin = 11, ++ .reg = 0x44, ++ .bit = 6, ++ .mask = 0x3 ++ }, { ++ /* gpio3_b4_sel */ ++ .num = 3, ++ .pin = 12, ++ .reg = 0x44, ++ .bit = 8, ++ .mask = 0x3 ++ }, { ++ /* gpio3_b5_sel */ ++ .num = 3, ++ .pin = 13, ++ .reg = 0x44, ++ .bit = 10, ++ .mask = 0x3 ++ }, { ++ /* gpio3_b6_sel */ ++ .num = 3, ++ .pin = 14, ++ .reg = 0x44, ++ .bit = 12, ++ .mask = 0x3 ++ }, { ++ /* gpio3_b7_sel */ ++ .num = 3, ++ .pin = 15, ++ .reg = 0x44, ++ .bit = 14, ++ .mask = 0x3 + }, + }; + +@@ -1891,6 +1936,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) + case RK3188: + case RK3288: + case RK3308: ++ case RK3328: + case RK3368: + case RK3399: + case RK3568: +@@ -1947,6 +1993,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, + case RK3188: + case RK3288: + case RK3308: ++ case RK3328: + case RK3368: + case RK3399: + case RK3568: +@@ -2159,8 +2206,10 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, + + if (ret) { + /* revert the already done pin settings */ +- for (cnt--; cnt >= 0; cnt--) ++ for (cnt--; cnt >= 0; cnt--) { ++ bank = pin_to_bank(info, pins[cnt]); + rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); ++ } + + return ret; + } +@@ -2207,6 +2256,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, + case RK3188: + case RK3288: + case RK3308: ++ case RK3328: + case RK3368: + case RK3399: + case RK3568: +@@ -3181,7 +3231,7 @@ static struct rockchip_pin_bank rk3328_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, +- IOMUX_WIDTH_3BIT, ++ 0, + IOMUX_WIDTH_3BIT, + 0), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", +@@ -3195,7 +3245,7 @@ static struct rockchip_pin_ctrl rk3328_pin_ctrl = { + .pin_banks = rk3328_pin_banks, + .nr_banks = ARRAY_SIZE(rk3328_pin_banks), + .label = "RK3328-GPIO", +- .type = RK3288, ++ .type = RK3328, + .grf_mux_offset = 0x0, + .iomux_recalced = rk3328_mux_recalced_data, + .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), +diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h +index 59116e13758d0..d4a6e1276bab3 100644 +--- a/drivers/pinctrl/pinctrl-rockchip.h ++++ b/drivers/pinctrl/pinctrl-rockchip.h +@@ -27,6 +27,7 @@ enum rockchip_pinctrl_type { + RK3188, + RK3288, + RK3308, ++ RK3328, + RK3368, + RK3399, + RK3568, +diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c +index fc086b66f70b3..77b0f5bbe3acc 100644 +--- a/drivers/platform/x86/dell/dell-smbios-base.c ++++ b/drivers/platform/x86/dell/dell-smbios-base.c +@@ -25,11 +25,16 @@ static u32 da_supported_commands; + static int da_num_tokens; + static struct platform_device *platform_device; + static struct calling_interface_token *da_tokens; +-static struct device_attribute *token_location_attrs; +-static struct device_attribute *token_value_attrs; ++static struct token_sysfs_data *token_entries; + static struct attribute **token_attrs; + static DEFINE_MUTEX(smbios_mutex); + ++struct token_sysfs_data { ++ struct device_attribute location_attr; ++ struct device_attribute value_attr; ++ struct calling_interface_token *token; ++}; ++ + struct smbios_device { + struct list_head list; + struct device *device; +@@ -416,47 +421,26 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy) + } + } + +-static int match_attribute(struct device *dev, +- struct device_attribute *attr) +-{ +- int i; +- +- for (i = 0; i < da_num_tokens * 2; i++) { +- if (!token_attrs[i]) +- continue; +- if (strcmp(token_attrs[i]->name, attr->attr.name) == 0) +- return i/2; +- } +- dev_dbg(dev, "couldn't match: %s\n", attr->attr.name); +- return -EINVAL; +-} +- + static ssize_t location_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +- int i; ++ struct token_sysfs_data *data = container_of(attr, struct token_sysfs_data, location_attr); + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- i = match_attribute(dev, attr); +- if (i > 0) +- return scnprintf(buf, PAGE_SIZE, "%08x", da_tokens[i].location); +- return 0; ++ return sysfs_emit(buf, "%08x", data->token->location); + } + + static ssize_t value_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +- int i; ++ struct token_sysfs_data *data = container_of(attr, struct token_sysfs_data, value_attr); + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- i = match_attribute(dev, attr); +- if (i > 0) +- return scnprintf(buf, PAGE_SIZE, "%08x", da_tokens[i].value); +- return 0; ++ return sysfs_emit(buf, "%08x", data->token->value); + } + + static struct attribute_group smbios_attribute_group = { +@@ -473,22 +457,15 @@ static int build_tokens_sysfs(struct platform_device *dev) + { + char *location_name; + char *value_name; +- size_t size; + int ret; + int i, j; + +- /* (number of tokens + 1 for null terminated */ +- size = sizeof(struct device_attribute) * (da_num_tokens + 1); +- token_location_attrs = kzalloc(size, GFP_KERNEL); +- if (!token_location_attrs) ++ token_entries = kcalloc(da_num_tokens, sizeof(*token_entries), GFP_KERNEL); ++ if (!token_entries) + return -ENOMEM; +- token_value_attrs = kzalloc(size, GFP_KERNEL); +- if (!token_value_attrs) +- goto out_allocate_value; + + /* need to store both location and value + terminator*/ +- size = sizeof(struct attribute *) * ((2 * da_num_tokens) + 1); +- token_attrs = kzalloc(size, GFP_KERNEL); ++ token_attrs = kcalloc((2 * da_num_tokens) + 1, sizeof(*token_attrs), GFP_KERNEL); + if (!token_attrs) + goto out_allocate_attrs; + +@@ -496,27 +473,32 @@ static int build_tokens_sysfs(struct platform_device *dev) + /* skip empty */ + if (da_tokens[i].tokenID == 0) + continue; ++ ++ token_entries[i].token = &da_tokens[i]; ++ + /* add location */ + location_name = kasprintf(GFP_KERNEL, "%04x_location", + da_tokens[i].tokenID); + if (location_name == NULL) + goto out_unwind_strings; +- sysfs_attr_init(&token_location_attrs[i].attr); +- token_location_attrs[i].attr.name = location_name; +- token_location_attrs[i].attr.mode = 0444; +- token_location_attrs[i].show = location_show; +- token_attrs[j++] = &token_location_attrs[i].attr; ++ ++ sysfs_attr_init(&token_entries[i].location_attr.attr); ++ token_entries[i].location_attr.attr.name = location_name; ++ token_entries[i].location_attr.attr.mode = 0444; ++ token_entries[i].location_attr.show = location_show; ++ token_attrs[j++] = &token_entries[i].location_attr.attr; + + /* add value */ + value_name = kasprintf(GFP_KERNEL, "%04x_value", + da_tokens[i].tokenID); + if (value_name == NULL) + goto loop_fail_create_value; +- sysfs_attr_init(&token_value_attrs[i].attr); +- token_value_attrs[i].attr.name = value_name; +- token_value_attrs[i].attr.mode = 0444; +- token_value_attrs[i].show = value_show; +- token_attrs[j++] = &token_value_attrs[i].attr; ++ ++ sysfs_attr_init(&token_entries[i].value_attr.attr); ++ token_entries[i].value_attr.attr.name = value_name; ++ token_entries[i].value_attr.attr.mode = 0444; ++ token_entries[i].value_attr.show = value_show; ++ token_attrs[j++] = &token_entries[i].value_attr.attr; + continue; + + loop_fail_create_value: +@@ -532,14 +514,12 @@ static int build_tokens_sysfs(struct platform_device *dev) + + out_unwind_strings: + while (i--) { +- kfree(token_location_attrs[i].attr.name); +- kfree(token_value_attrs[i].attr.name); ++ kfree(token_entries[i].location_attr.attr.name); ++ kfree(token_entries[i].value_attr.attr.name); + } + kfree(token_attrs); + out_allocate_attrs: +- kfree(token_value_attrs); +-out_allocate_value: +- kfree(token_location_attrs); ++ kfree(token_entries); + + return -ENOMEM; + } +@@ -551,12 +531,11 @@ static void free_group(struct platform_device *pdev) + sysfs_remove_group(&pdev->dev.kobj, + &smbios_attribute_group); + for (i = 0; i < da_num_tokens; i++) { +- kfree(token_location_attrs[i].attr.name); +- kfree(token_value_attrs[i].attr.name); ++ kfree(token_entries[i].location_attr.attr.name); ++ kfree(token_entries[i].value_attr.attr.name); + } + kfree(token_attrs); +- kfree(token_value_attrs); +- kfree(token_location_attrs); ++ kfree(token_entries); + } + + static int __init dell_smbios_init(void) +diff --git a/drivers/power/supply/cros_usbpd-charger.c b/drivers/power/supply/cros_usbpd-charger.c +index 0a4f02e4ae7ba..d7ee1eb9ca880 100644 +--- a/drivers/power/supply/cros_usbpd-charger.c ++++ b/drivers/power/supply/cros_usbpd-charger.c +@@ -5,6 +5,7 @@ + * Copyright (c) 2014 - 2018 Google, Inc + */ + ++#include <linux/mod_devicetable.h> + #include <linux/module.h> + #include <linux/platform_data/cros_ec_commands.h> + #include <linux/platform_data/cros_ec_proto.h> +@@ -711,16 +712,22 @@ static int cros_usbpd_charger_resume(struct device *dev) + static SIMPLE_DEV_PM_OPS(cros_usbpd_charger_pm_ops, NULL, + cros_usbpd_charger_resume); + ++static const struct platform_device_id cros_usbpd_charger_id[] = { ++ { DRV_NAME, 0 }, ++ {} ++}; ++MODULE_DEVICE_TABLE(platform, cros_usbpd_charger_id); ++ + static struct platform_driver cros_usbpd_charger_driver = { + .driver = { + .name = DRV_NAME, + .pm = &cros_usbpd_charger_pm_ops, + }, +- .probe = cros_usbpd_charger_probe ++ .probe = cros_usbpd_charger_probe, ++ .id_table = cros_usbpd_charger_id, + }; + + module_platform_driver(cros_usbpd_charger_driver); + + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("ChromeOS EC USBPD charger"); +-MODULE_ALIAS("platform:" DRV_NAME); +diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c +index 9311f3d09c8fc..8eb902fe73a98 100644 +--- a/drivers/ptp/ptp_chardev.c ++++ b/drivers/ptp/ptp_chardev.c +@@ -84,7 +84,8 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, + } + + if (info->verify(info, pin, func, chan)) { +- pr_err("driver cannot use function %u on pin %u\n", func, chan); ++ pr_err("driver cannot use function %u and channel %u on pin %u\n", ++ func, chan, pin); + return -EOPNOTSUPP; + } + +diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c +index 0bdfdd4bb0fa2..be58d5257bcb6 100644 +--- a/drivers/ptp/ptp_sysfs.c ++++ b/drivers/ptp/ptp_sysfs.c +@@ -280,8 +280,7 @@ static ssize_t max_vclocks_store(struct device *dev, + if (max < ptp->n_vclocks) + goto out; + +- size = sizeof(int) * max; +- vclock_index = kzalloc(size, GFP_KERNEL); ++ vclock_index = kcalloc(max, sizeof(int), GFP_KERNEL); + if (!vclock_index) { + err = -ENOMEM; + goto out; +diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c +index bdcdb7f38312b..c40a6548ce7d4 100644 +--- a/drivers/pwm/pwm-stm32.c ++++ b/drivers/pwm/pwm-stm32.c +@@ -340,6 +340,9 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch, + + prd = div; + ++ if (!prd) ++ return -EINVAL; ++ + if (prescaler > MAX_TIM_PSC) + return -EINVAL; + +diff --git a/drivers/regulator/bd71815-regulator.c b/drivers/regulator/bd71815-regulator.c +index 16edd9062ca91..5d468303f1029 100644 +--- a/drivers/regulator/bd71815-regulator.c ++++ b/drivers/regulator/bd71815-regulator.c +@@ -257,7 +257,7 @@ static int buck12_set_hw_dvs_levels(struct device_node *np, + * 10: 2.50mV/usec 10mV 4uS + * 11: 1.25mV/usec 10mV 8uS + */ +-static const unsigned int bd7181x_ramp_table[] = { 1250, 2500, 5000, 10000 }; ++static const unsigned int bd7181x_ramp_table[] = { 10000, 5000, 2500, 1250 }; + + static int bd7181x_led_set_current_limit(struct regulator_dev *rdev, + int min_uA, int max_uA) +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index d6febb9ec60d9..879f4a77e91db 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -3297,6 +3297,7 @@ struct regmap *regulator_get_regmap(struct regulator *regulator) + + return map ? map : ERR_PTR(-EOPNOTSUPP); + } ++EXPORT_SYMBOL_GPL(regulator_get_regmap); + + /** + * regulator_get_hardware_vsel_register - get the HW voltage selector register +diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h +index 2cc42432bd0c0..26043e05ca302 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr.h ++++ b/drivers/scsi/mpi3mr/mpi3mr.h +@@ -38,6 +38,7 @@ + #include <scsi/scsi_device.h> + #include <scsi/scsi_host.h> + #include <scsi/scsi_tcq.h> ++#include <scsi/scsi_transport_sas.h> + + #include "mpi/mpi30_transport.h" + #include "mpi/mpi30_cnfg.h" +diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c +index a0d3e2eb8c1a6..859e2c1e38e12 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_os.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c +@@ -3549,6 +3549,72 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost, + return retval; + } + ++/** ++ * sas_ncq_prio_supported_show - Indicate if device supports NCQ priority ++ * @dev: pointer to embedded device ++ * @attr: sas_ncq_prio_supported attribute descriptor ++ * @buf: the buffer returned ++ * ++ * A sysfs 'read-only' sdev attribute, only works with SATA devices ++ */ ++static ssize_t ++sas_ncq_prio_supported_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ ++ return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev)); ++} ++static DEVICE_ATTR_RO(sas_ncq_prio_supported); ++ ++/** ++ * sas_ncq_prio_enable_show - send prioritized io commands to device ++ * @dev: pointer to embedded device ++ * @attr: sas_ncq_prio_enable attribute descriptor ++ * @buf: the buffer returned ++ * ++ * A sysfs 'read/write' sdev attribute, only works with SATA devices ++ */ ++static ssize_t ++sas_ncq_prio_enable_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct mpi3mr_sdev_priv_data *sdev_priv_data = sdev->hostdata; ++ ++ if (!sdev_priv_data) ++ return 0; ++ ++ return sysfs_emit(buf, "%d\n", sdev_priv_data->ncq_prio_enable); ++} ++ ++static ssize_t ++sas_ncq_prio_enable_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct scsi_device *sdev = to_scsi_device(dev); ++ struct mpi3mr_sdev_priv_data *sdev_priv_data = sdev->hostdata; ++ bool ncq_prio_enable = 0; ++ ++ if (kstrtobool(buf, &ncq_prio_enable)) ++ return -EINVAL; ++ ++ if (!sas_ata_ncq_prio_supported(sdev)) ++ return -EINVAL; ++ ++ sdev_priv_data->ncq_prio_enable = ncq_prio_enable; ++ ++ return strlen(buf); ++} ++static DEVICE_ATTR_RW(sas_ncq_prio_enable); ++ ++static struct device_attribute *mpi3mr_dev_attrs[] = { ++ &dev_attr_sas_ncq_prio_supported, ++ &dev_attr_sas_ncq_prio_enable, ++ NULL, ++}; ++ + static struct scsi_host_template mpi3mr_driver_template = { + .module = THIS_MODULE, + .name = "MPI3 Storage Controller", +@@ -3577,6 +3643,7 @@ static struct scsi_host_template mpi3mr_driver_template = { + .cmd_per_lun = MPI3MR_MAX_CMDS_LUN, + .track_queue_depth = 1, + .cmd_size = sizeof(struct scmd_priv), ++ .sdev_attrs = mpi3mr_dev_attrs, + }; + + /** +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 8325875bfc4ed..8428411ee9593 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -8337,6 +8337,12 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) + ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8); + if (ioc->facts.MaxDevHandle % 8) + ioc->pd_handles_sz++; ++ /* ++ * pd_handles_sz should have, at least, the minimal room for ++ * set_bit()/test_bit(), otherwise out-of-memory touch may occur. ++ */ ++ ioc->pd_handles_sz = ALIGN(ioc->pd_handles_sz, sizeof(unsigned long)); ++ + ioc->pd_handles = kzalloc(ioc->pd_handles_sz, + GFP_KERNEL); + if (!ioc->pd_handles) { +@@ -8354,6 +8360,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) + ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8); + if (ioc->facts.MaxDevHandle % 8) + ioc->pend_os_device_add_sz++; ++ ++ /* ++ * pend_os_device_add_sz should have, at least, the minimal room for ++ * set_bit()/test_bit(), otherwise out-of-memory may occur. ++ */ ++ ioc->pend_os_device_add_sz = ALIGN(ioc->pend_os_device_add_sz, ++ sizeof(unsigned long)); + ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz, + GFP_KERNEL); + if (!ioc->pend_os_device_add) { +@@ -8645,6 +8658,12 @@ _base_check_ioc_facts_changes(struct MPT3SAS_ADAPTER *ioc) + if (ioc->facts.MaxDevHandle % 8) + pd_handles_sz++; + ++ /* ++ * pd_handles should have, at least, the minimal room for ++ * set_bit()/test_bit(), otherwise out-of-memory touch may ++ * occur. ++ */ ++ pd_handles_sz = ALIGN(pd_handles_sz, sizeof(unsigned long)); + pd_handles = krealloc(ioc->pd_handles, pd_handles_sz, + GFP_KERNEL); + if (!pd_handles) { +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 0ff208a41a476..60fd8192c0593 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -2010,9 +2010,6 @@ void + mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, + struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request); + +-/* NCQ Prio Handling Check */ +-bool scsih_ncq_prio_supp(struct scsi_device *sdev); +- + void mpt3sas_setup_debugfs(struct MPT3SAS_ADAPTER *ioc); + void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc); + void mpt3sas_init_debugfs(void); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index 1b79f01f03a4a..20336175c14f5 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -3933,7 +3933,7 @@ sas_ncq_prio_supported_show(struct device *dev, + { + struct scsi_device *sdev = to_scsi_device(dev); + +- return sysfs_emit(buf, "%d\n", scsih_ncq_prio_supp(sdev)); ++ return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev)); + } + static DEVICE_ATTR_RO(sas_ncq_prio_supported); + +@@ -3968,7 +3968,7 @@ sas_ncq_prio_enable_store(struct device *dev, + if (kstrtobool(buf, &ncq_prio_enable)) + return -EINVAL; + +- if (!scsih_ncq_prio_supp(sdev)) ++ if (!sas_ata_ncq_prio_supported(sdev)) + return -EINVAL; + + sas_device_priv_data->ncq_prio_enable = ncq_prio_enable; +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index c9f85605349bf..bbef78608a676 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -12580,31 +12580,6 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev) + return PCI_ERS_RESULT_RECOVERED; + } + +-/** +- * scsih_ncq_prio_supp - Check for NCQ command priority support +- * @sdev: scsi device struct +- * +- * This is called when a user indicates they would like to enable +- * ncq command priorities. This works only on SATA devices. +- */ +-bool scsih_ncq_prio_supp(struct scsi_device *sdev) +-{ +- unsigned char *buf; +- bool ncq_prio_supp = false; +- +- if (!scsi_device_supports_vpd(sdev)) +- return ncq_prio_supp; +- +- buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL); +- if (!buf) +- return ncq_prio_supp; +- +- if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN)) +- ncq_prio_supp = (buf[213] >> 4) & 1; +- +- kfree(buf); +- return ncq_prio_supp; +-} + /* + * The pci device ids are defined in mpi/mpi2_cnfg.h. + */ +diff --git a/drivers/scsi/qedi/qedi_debugfs.c b/drivers/scsi/qedi/qedi_debugfs.c +index 42f5afb60055c..6e724f47ab9e8 100644 +--- a/drivers/scsi/qedi/qedi_debugfs.c ++++ b/drivers/scsi/qedi/qedi_debugfs.c +@@ -120,15 +120,11 @@ static ssize_t + qedi_dbg_do_not_recover_cmd_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) + { +- size_t cnt = 0; +- +- if (*ppos) +- return 0; ++ char buf[64]; ++ int len; + +- cnt = sprintf(buffer, "do_not_recover=%d\n", qedi_do_not_recover); +- cnt = min_t(int, count, cnt - *ppos); +- *ppos += cnt; +- return cnt; ++ len = sprintf(buf, "do_not_recover=%d\n", qedi_do_not_recover); ++ return simple_read_from_buffer(buffer, count, ppos, buf, len); + } + + static int +diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c +index c6256fdc24b10..8649608faec2c 100644 +--- a/drivers/scsi/scsi_transport_sas.c ++++ b/drivers/scsi/scsi_transport_sas.c +@@ -410,6 +410,35 @@ unsigned int sas_is_tlr_enabled(struct scsi_device *sdev) + } + EXPORT_SYMBOL_GPL(sas_is_tlr_enabled); + ++/** ++ * sas_ata_ncq_prio_supported - Check for ATA NCQ command priority support ++ * @sdev: SCSI device ++ * ++ * Check if an ATA device supports NCQ priority using VPD page 89h (ATA ++ * Information). Since this VPD page is implemented only for ATA devices, ++ * this function always returns false for SCSI devices. ++ */ ++bool sas_ata_ncq_prio_supported(struct scsi_device *sdev) ++{ ++ unsigned char *buf; ++ bool ncq_prio_supported = false; ++ ++ if (!scsi_device_supports_vpd(sdev)) ++ return false; ++ ++ buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL); ++ if (!buf) ++ return false; ++ ++ if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN)) ++ ncq_prio_supported = (buf[213] >> 4) & 1; ++ ++ kfree(buf); ++ ++ return ncq_prio_supported; ++} ++EXPORT_SYMBOL_GPL(sas_ata_ncq_prio_supported); ++ + /* + * SAS Phy attributes + */ +diff --git a/drivers/soc/ti/ti_sci_pm_domains.c b/drivers/soc/ti/ti_sci_pm_domains.c +index a33ec7eaf23d1..17984a7bffba5 100644 +--- a/drivers/soc/ti/ti_sci_pm_domains.c ++++ b/drivers/soc/ti/ti_sci_pm_domains.c +@@ -114,6 +114,18 @@ static const struct of_device_id ti_sci_pm_domain_matches[] = { + }; + MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches); + ++static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32 idx) ++{ ++ struct ti_sci_pm_domain *pd; ++ ++ list_for_each_entry(pd, &pd_provider->pd_list, node) { ++ if (pd->idx == idx) ++ return true; ++ } ++ ++ return false; ++} ++ + static int ti_sci_pm_domain_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -153,8 +165,14 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) + break; + + if (args.args_count >= 1 && args.np == dev->of_node) { +- if (args.args[0] > max_id) ++ if (args.args[0] > max_id) { + max_id = args.args[0]; ++ } else { ++ if (ti_sci_pm_idx_exists(pd_provider, args.args[0])) { ++ index++; ++ continue; ++ } ++ } + + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); + if (!pd) +diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c +index 8b3ff44fd9010..967c40059a431 100644 +--- a/drivers/soc/ti/wkup_m3_ipc.c ++++ b/drivers/soc/ti/wkup_m3_ipc.c +@@ -14,7 +14,6 @@ + #include <linux/irq.h> + #include <linux/module.h> + #include <linux/of.h> +-#include <linux/omap-mailbox.h> + #include <linux/platform_device.h> + #include <linux/remoteproc.h> + #include <linux/suspend.h> +@@ -151,7 +150,6 @@ static irqreturn_t wkup_m3_txev_handler(int irq, void *ipc_data) + static int wkup_m3_ping(struct wkup_m3_ipc *m3_ipc) + { + struct device *dev = m3_ipc->dev; +- mbox_msg_t dummy_msg = 0; + int ret; + + if (!m3_ipc->mbox) { +@@ -167,7 +165,7 @@ static int wkup_m3_ping(struct wkup_m3_ipc *m3_ipc) + * the RX callback to avoid multiple interrupts being received + * by the CM3. + */ +- ret = mbox_send_message(m3_ipc->mbox, &dummy_msg); ++ ret = mbox_send_message(m3_ipc->mbox, NULL); + if (ret < 0) { + dev_err(dev, "%s: mbox_send_message() failed: %d\n", + __func__, ret); +@@ -189,7 +187,6 @@ static int wkup_m3_ping(struct wkup_m3_ipc *m3_ipc) + static int wkup_m3_ping_noirq(struct wkup_m3_ipc *m3_ipc) + { + struct device *dev = m3_ipc->dev; +- mbox_msg_t dummy_msg = 0; + int ret; + + if (!m3_ipc->mbox) { +@@ -198,7 +195,7 @@ static int wkup_m3_ping_noirq(struct wkup_m3_ipc *m3_ipc) + return -EIO; + } + +- ret = mbox_send_message(m3_ipc->mbox, &dummy_msg); ++ ret = mbox_send_message(m3_ipc->mbox, NULL); + if (ret < 0) { + dev_err(dev, "%s: mbox_send_message() failed: %d\n", + __func__, ret); +diff --git a/drivers/spmi/hisi-spmi-controller.c b/drivers/spmi/hisi-spmi-controller.c +index 5bd23262abd61..6f065159f3de3 100644 +--- a/drivers/spmi/hisi-spmi-controller.c ++++ b/drivers/spmi/hisi-spmi-controller.c +@@ -303,7 +303,6 @@ static int spmi_controller_probe(struct platform_device *pdev) + + spin_lock_init(&spmi_controller->lock); + +- ctrl->nr = spmi_controller->channel; + ctrl->dev.parent = pdev->dev.parent; + ctrl->dev.of_node = of_node_get(pdev->dev.of_node); + +diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c +index 48769e059772a..a38820a1c5cd2 100644 +--- a/drivers/tty/serial/8250/8250_exar.c ++++ b/drivers/tty/serial/8250/8250_exar.c +@@ -41,8 +41,50 @@ + #define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 + #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 + ++#define PCI_VENDOR_ID_CONNECT_TECH 0x12c4 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_SP_OPTO 0x0340 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_SP_OPTO_A 0x0341 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_SP_OPTO_B 0x0342 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS 0x0350 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_A 0x0351 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_B 0x0352 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS 0x0353 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_A 0x0354 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_B 0x0355 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS_OPTO 0x0360 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_A 0x0361 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_B 0x0362 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP 0x0370 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_232 0x0371 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_485 0x0372 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4_SP 0x0373 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_6_2_SP 0x0374 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_6_SP 0x0375 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_232_NS 0x0376 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XP_OPTO_LEFT 0x0380 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XP_OPTO_RIGHT 0x0381 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XP_OPTO 0x0382 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4_XPRS_OPTO 0x0392 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP 0x03A0 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_232 0x03A1 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_485 0x03A2 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_232_NS 0x03A3 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XEG001 0x0602 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_BASE 0x1000 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_2 0x1002 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_4 0x1004 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_8 0x1008 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_12 0x100C ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_16 0x1010 ++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_12_XIG00X 0x110c ++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_12_XIG01X 0x110d ++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_16 0x1110 ++ + #define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 + #define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 ++#define PCI_DEVICE_ID_EXAR_XR17V252 0x0252 ++#define PCI_DEVICE_ID_EXAR_XR17V254 0x0254 ++#define PCI_DEVICE_ID_EXAR_XR17V258 0x0258 + + #define PCI_SUBDEVICE_ID_USR_2980 0x0128 + #define PCI_SUBDEVICE_ID_USR_2981 0x0129 +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 770c4cabdf9b7..1f389670dfdfd 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -159,6 +159,10 @@ static u32 uart_read(struct omap8250_priv *priv, u32 reg) + return readl(priv->membase + (reg << OMAP_UART_REGSHIFT)); + } + ++/* Timeout low and High */ ++#define UART_OMAP_TO_L 0x26 ++#define UART_OMAP_TO_H 0x27 ++ + /* + * Called on runtime PM resume path from omap8250_restore_regs(), and + * omap8250_set_mctrl(). +@@ -642,13 +646,25 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) + + /* + * On K3 SoCs, it is observed that RX TIMEOUT is signalled after +- * FIFO has been drained, in which case a dummy read of RX FIFO +- * is required to clear RX TIMEOUT condition. ++ * FIFO has been drained or erroneously. ++ * So apply solution of Errata i2310 as mentioned in ++ * https://www.ti.com/lit/pdf/sprz536 + */ + if (priv->habit & UART_RX_TIMEOUT_QUIRK && + (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT && + serial_port_in(port, UART_OMAP_RX_LVL) == 0) { +- serial_port_in(port, UART_RX); ++ unsigned char efr2, timeout_h, timeout_l; ++ ++ efr2 = serial_in(up, UART_OMAP_EFR2); ++ timeout_h = serial_in(up, UART_OMAP_TO_H); ++ timeout_l = serial_in(up, UART_OMAP_TO_L); ++ serial_out(up, UART_OMAP_TO_H, 0xFF); ++ serial_out(up, UART_OMAP_TO_L, 0xFF); ++ serial_out(up, UART_OMAP_EFR2, UART_OMAP_EFR2_TIMEOUT_BEHAVE); ++ serial_in(up, UART_IIR); ++ serial_out(up, UART_OMAP_EFR2, efr2); ++ serial_out(up, UART_OMAP_TO_H, timeout_h); ++ serial_out(up, UART_OMAP_TO_L, timeout_l); + } + + /* Stop processing interrupts on input overrun */ +diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c +index 33ca98bfa5b37..0780f5d7be62b 100644 +--- a/drivers/tty/serial/8250/8250_pxa.c ++++ b/drivers/tty/serial/8250/8250_pxa.c +@@ -125,6 +125,7 @@ static int serial_pxa_probe(struct platform_device *pdev) + uart.port.regshift = 2; + uart.port.irq = irq; + uart.port.fifosize = 64; ++ uart.tx_loadsz = 32; + uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST | UPF_FIXED_TYPE; + uart.port.dev = &pdev->dev; + uart.port.uartclk = clk_get_rate(data->clk); +diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c +index 0587beaaea08d..b9ef426d5aae3 100644 +--- a/drivers/tty/serial/imx.c ++++ b/drivers/tty/serial/imx.c +@@ -27,6 +27,7 @@ + #include <linux/of.h> + #include <linux/of_device.h> + #include <linux/io.h> ++#include <linux/iopoll.h> + #include <linux/dma-mapping.h> + + #include <asm/irq.h> +@@ -2024,7 +2025,7 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) + struct imx_port *sport = imx_uart_ports[co->index]; + struct imx_port_ucrs old_ucr; + unsigned long flags; +- unsigned int ucr1; ++ unsigned int ucr1, usr2; + int locked = 1; + + if (sport->port.sysrq) +@@ -2055,8 +2056,8 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) + * Finally, wait for transmitter to become empty + * and restore UCR1/2/3 + */ +- while (!(imx_uart_readl(sport, USR2) & USR2_TXDC)); +- ++ read_poll_timeout_atomic(imx_uart_readl, usr2, usr2 & USR2_TXDC, ++ 0, USEC_PER_SEC, false, sport, USR2); + imx_uart_ucrs_restore(sport, &old_ucr); + + if (locked) +diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c +index c7cec7d036203..f6ea3b65cdfa0 100644 +--- a/drivers/tty/serial/mcf.c ++++ b/drivers/tty/serial/mcf.c +@@ -477,7 +477,7 @@ static const struct uart_ops mcf_uart_ops = { + .verify_port = mcf_verify_port, + }; + +-static struct mcf_uart mcf_ports[4]; ++static struct mcf_uart mcf_ports[10]; + + #define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) + +diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c +index 35f8675db1d89..d274a847c6ab3 100644 +--- a/drivers/tty/serial/sc16is7xx.c ++++ b/drivers/tty/serial/sc16is7xx.c +@@ -490,16 +490,28 @@ static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg) + return reg == SC16IS7XX_RHR_REG; + } + ++/* ++ * Configure programmable baud rate generator (divisor) according to the ++ * desired baud rate. ++ * ++ * From the datasheet, the divisor is computed according to: ++ * ++ * XTAL1 input frequency ++ * ----------------------- ++ * prescaler ++ * divisor = --------------------------- ++ * baud-rate x sampling-rate ++ */ + static int sc16is7xx_set_baud(struct uart_port *port, int baud) + { + struct sc16is7xx_port *s = dev_get_drvdata(port->dev); + u8 lcr; +- u8 prescaler = 0; ++ unsigned int prescaler = 1; + unsigned long clk = port->uartclk, div = clk / 16 / baud; + +- if (div > 0xffff) { +- prescaler = SC16IS7XX_MCR_CLKSEL_BIT; +- div /= 4; ++ if (div >= BIT(16)) { ++ prescaler = 4; ++ div /= prescaler; + } + + /* In an amazing feat of design, the Enhanced Features Register shares +@@ -534,9 +546,10 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) + + mutex_unlock(&s->efr_lock); + ++ /* If bit MCR_CLKSEL is set, the divide by 4 prescaler is activated. */ + sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, + SC16IS7XX_MCR_CLKSEL_BIT, +- prescaler); ++ prescaler == 1 ? 0 : SC16IS7XX_MCR_CLKSEL_BIT); + + /* Open the LCR divisors for configuration */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, +@@ -551,7 +564,7 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) + /* Put LCR back to the normal mode */ + sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); + +- return DIV_ROUND_CLOSEST(clk / 16, div); ++ return DIV_ROUND_CLOSEST((clk / prescaler) / 16, div); + } + + static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen, +diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c +index 3b7d4481edbea..c20f8917ebffb 100644 +--- a/drivers/tty/serial/stm32-usart.c ++++ b/drivers/tty/serial/stm32-usart.c +@@ -220,66 +220,60 @@ static int stm32_usart_init_rs485(struct uart_port *port, + return uart_get_rs485_mode(port); + } + +-static int stm32_usart_pending_rx(struct uart_port *port, u32 *sr, +- int *last_res, bool threaded) ++static bool stm32_usart_rx_dma_enabled(struct uart_port *port) + { + struct stm32_port *stm32_port = to_stm32_port(port); + const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +- enum dma_status status; +- struct dma_tx_state state; + +- *sr = readl_relaxed(port->membase + ofs->isr); ++ if (!stm32_port->rx_ch) ++ return false; + +- if (threaded && stm32_port->rx_ch) { +- status = dmaengine_tx_status(stm32_port->rx_ch, +- stm32_port->rx_ch->cookie, +- &state); +- if (status == DMA_IN_PROGRESS && (*last_res != state.residue)) +- return 1; +- else +- return 0; +- } else if (*sr & USART_SR_RXNE) { +- return 1; ++ return !!(readl_relaxed(port->membase + ofs->cr3) & USART_CR3_DMAR); ++} ++ ++/* Return true when data is pending (in pio mode), and false when no data is pending. */ ++static bool stm32_usart_pending_rx_pio(struct uart_port *port, u32 *sr) ++{ ++ struct stm32_port *stm32_port = to_stm32_port(port); ++ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; ++ ++ *sr = readl_relaxed(port->membase + ofs->isr); ++ /* Get pending characters in RDR or FIFO */ ++ if (*sr & USART_SR_RXNE) { ++ /* Get all pending characters from the RDR or the FIFO when using interrupts */ ++ if (!stm32_usart_rx_dma_enabled(port)) ++ return true; ++ ++ /* Handle only RX data errors when using DMA */ ++ if (*sr & USART_SR_ERR_MASK) ++ return true; + } +- return 0; ++ ++ return false; + } + +-static unsigned long stm32_usart_get_char(struct uart_port *port, u32 *sr, +- int *last_res) ++static unsigned long stm32_usart_get_char_pio(struct uart_port *port) + { + struct stm32_port *stm32_port = to_stm32_port(port); + const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + unsigned long c; + +- if (stm32_port->rx_ch) { +- c = stm32_port->rx_buf[RX_BUF_L - (*last_res)--]; +- if ((*last_res) == 0) +- *last_res = RX_BUF_L; +- } else { +- c = readl_relaxed(port->membase + ofs->rdr); +- /* apply RDR data mask */ +- c &= stm32_port->rdr_mask; +- } ++ c = readl_relaxed(port->membase + ofs->rdr); ++ /* Apply RDR data mask */ ++ c &= stm32_port->rdr_mask; + + return c; + } + +-static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) ++static void stm32_usart_receive_chars_pio(struct uart_port *port) + { +- struct tty_port *tport = &port->state->port; + struct stm32_port *stm32_port = to_stm32_port(port); + const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +- unsigned long c, flags; ++ unsigned long c; + u32 sr; + char flag; + +- if (irqflag) +- spin_lock_irqsave(&port->lock, flags); +- else +- spin_lock(&port->lock); +- +- while (stm32_usart_pending_rx(port, &sr, &stm32_port->last_res, +- irqflag)) { ++ while (stm32_usart_pending_rx_pio(port, &sr)) { + sr |= USART_SR_DUMMY_RX; + flag = TTY_NORMAL; + +@@ -298,7 +292,7 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) + writel_relaxed(sr & USART_SR_ERR_MASK, + port->membase + ofs->icr); + +- c = stm32_usart_get_char(port, &sr, &stm32_port->last_res); ++ c = stm32_usart_get_char_pio(port); + port->icount.rx++; + if (sr & USART_SR_ERR_MASK) { + if (sr & USART_SR_ORE) { +@@ -332,6 +326,94 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) + continue; + uart_insert_char(port, sr, USART_SR_ORE, c, flag); + } ++} ++ ++static void stm32_usart_push_buffer_dma(struct uart_port *port, unsigned int dma_size) ++{ ++ struct stm32_port *stm32_port = to_stm32_port(port); ++ struct tty_port *ttyport = &stm32_port->port.state->port; ++ unsigned char *dma_start; ++ int dma_count, i; ++ ++ dma_start = stm32_port->rx_buf + (RX_BUF_L - stm32_port->last_res); ++ ++ /* ++ * Apply rdr_mask on buffer in order to mask parity bit. ++ * This loop is useless in cs8 mode because DMA copies only ++ * 8 bits and already ignores parity bit. ++ */ ++ if (!(stm32_port->rdr_mask == (BIT(8) - 1))) ++ for (i = 0; i < dma_size; i++) ++ *(dma_start + i) &= stm32_port->rdr_mask; ++ ++ dma_count = tty_insert_flip_string(ttyport, dma_start, dma_size); ++ port->icount.rx += dma_count; ++ if (dma_count != dma_size) ++ port->icount.buf_overrun++; ++ stm32_port->last_res -= dma_count; ++ if (stm32_port->last_res == 0) ++ stm32_port->last_res = RX_BUF_L; ++} ++ ++static void stm32_usart_receive_chars_dma(struct uart_port *port) ++{ ++ struct stm32_port *stm32_port = to_stm32_port(port); ++ unsigned int dma_size; ++ ++ /* DMA buffer is configured in cyclic mode and handles the rollback of the buffer. */ ++ if (stm32_port->rx_dma_state.residue > stm32_port->last_res) { ++ /* Conditional first part: from last_res to end of DMA buffer */ ++ dma_size = stm32_port->last_res; ++ stm32_usart_push_buffer_dma(port, dma_size); ++ } ++ ++ dma_size = stm32_port->last_res - stm32_port->rx_dma_state.residue; ++ stm32_usart_push_buffer_dma(port, dma_size); ++} ++ ++static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) ++{ ++ struct tty_port *tport = &port->state->port; ++ struct stm32_port *stm32_port = to_stm32_port(port); ++ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; ++ enum dma_status rx_dma_status; ++ unsigned long flags; ++ u32 sr; ++ ++ if (irqflag) ++ spin_lock_irqsave(&port->lock, flags); ++ else ++ spin_lock(&port->lock); ++ ++ if (stm32_usart_rx_dma_enabled(port)) { ++ rx_dma_status = dmaengine_tx_status(stm32_port->rx_ch, ++ stm32_port->rx_ch->cookie, ++ &stm32_port->rx_dma_state); ++ if (rx_dma_status == DMA_IN_PROGRESS) { ++ /* Empty DMA buffer */ ++ stm32_usart_receive_chars_dma(port); ++ sr = readl_relaxed(port->membase + ofs->isr); ++ if (sr & USART_SR_ERR_MASK) { ++ /* Disable DMA request line */ ++ stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); ++ ++ /* Switch to PIO mode to handle the errors */ ++ stm32_usart_receive_chars_pio(port); ++ ++ /* Switch back to DMA mode */ ++ stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR); ++ } ++ } else { ++ /* Disable RX DMA */ ++ dmaengine_terminate_async(stm32_port->rx_ch); ++ stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); ++ /* Fall back to interrupt mode */ ++ dev_dbg(port->dev, "DMA error, fallback to irq mode\n"); ++ stm32_usart_receive_chars_pio(port); ++ } ++ } else { ++ stm32_usart_receive_chars_pio(port); ++ } + + if (irqflag) + uart_unlock_and_check_sysrq_irqrestore(port, irqflag); +@@ -373,6 +455,13 @@ static void stm32_usart_tx_interrupt_enable(struct uart_port *port) + stm32_usart_set_bits(port, ofs->cr1, USART_CR1_TXEIE); + } + ++static void stm32_usart_rx_dma_complete(void *arg) ++{ ++ struct uart_port *port = arg; ++ ++ stm32_usart_receive_chars(port, true); ++} ++ + static void stm32_usart_tc_interrupt_enable(struct uart_port *port) + { + struct stm32_port *stm32_port = to_stm32_port(port); +@@ -588,7 +677,12 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) + pm_wakeup_event(tport->tty->dev, 0); + } + +- if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch)) ++ /* ++ * rx errors in dma mode has to be handled ASAP to avoid overrun as the DMA request ++ * line has been masked by HW and rx data are stacking in FIFO. ++ */ ++ if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_enabled(port)) || ++ ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_enabled(port))) + stm32_usart_receive_chars(port, false); + + if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) { +@@ -597,7 +691,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) + spin_unlock(&port->lock); + } + +- if (stm32_port->rx_ch) ++ if (stm32_usart_rx_dma_enabled(port)) + return IRQ_WAKE_THREAD; + else + return IRQ_HANDLED; +@@ -903,9 +997,11 @@ static void stm32_usart_set_termios(struct uart_port *port, + stm32_port->cr1_irq = USART_CR1_RTOIE; + writel_relaxed(bits, port->membase + ofs->rtor); + cr2 |= USART_CR2_RTOEN; +- /* Not using dma, enable fifo threshold irq */ +- if (!stm32_port->rx_ch) +- stm32_port->cr3_irq = USART_CR3_RXFTIE; ++ /* ++ * Enable fifo threshold irq in two cases, either when there is no DMA, or when ++ * wake up over usart, from low power until the DMA gets re-enabled by resume. ++ */ ++ stm32_port->cr3_irq = USART_CR3_RXFTIE; + } + + cr1 |= stm32_port->cr1_irq; +@@ -968,8 +1064,16 @@ static void stm32_usart_set_termios(struct uart_port *port, + if ((termios->c_cflag & CREAD) == 0) + port->ignore_status_mask |= USART_SR_DUMMY_RX; + +- if (stm32_port->rx_ch) ++ if (stm32_port->rx_ch) { ++ /* ++ * Setup DMA to collect only valid data and enable error irqs. ++ * This also enables break reception when using DMA. ++ */ ++ cr1 |= USART_CR1_PEIE; ++ cr3 |= USART_CR3_EIE; + cr3 |= USART_CR3_DMAR; ++ cr3 |= USART_CR3_DDRE; ++ } + + if (rs485conf->flags & SER_RS485_ENABLED) { + stm32_usart_config_reg_rs485(&cr1, &cr3, +@@ -1298,9 +1402,9 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, + return -ENODEV; + } + +- /* No callback as dma buffer is drained on usart interrupt */ +- desc->callback = NULL; +- desc->callback_param = NULL; ++ /* Set DMA callback */ ++ desc->callback = stm32_usart_rx_dma_complete; ++ desc->callback_param = port; + + /* Push current DMA transaction in the pending queue */ + ret = dma_submit_error(dmaengine_submit(desc)); +@@ -1464,6 +1568,7 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) + struct stm32_port *stm32_port = to_stm32_port(port); + const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + int err; ++ u32 cr3; + + pm_runtime_get_sync(&pdev->dev); + err = uart_remove_one_port(&stm32_usart_driver, port); +@@ -1474,7 +1579,12 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + +- stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); ++ stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_PEIE); ++ cr3 = readl_relaxed(port->membase + ofs->cr3); ++ cr3 &= ~USART_CR3_EIE; ++ cr3 &= ~USART_CR3_DMAR; ++ cr3 &= ~USART_CR3_DDRE; ++ writel_relaxed(cr3, port->membase + ofs->cr3); + + if (stm32_port->tx_ch) { + stm32_usart_of_dma_tx_remove(stm32_port, pdev); +diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h +index ad6335155de2d..852573e1a690a 100644 +--- a/drivers/tty/serial/stm32-usart.h ++++ b/drivers/tty/serial/stm32-usart.h +@@ -109,7 +109,7 @@ struct stm32_usart_info stm32h7_info = { + /* USART_SR (F4) / USART_ISR (F7) */ + #define USART_SR_PE BIT(0) + #define USART_SR_FE BIT(1) +-#define USART_SR_NF BIT(2) ++#define USART_SR_NE BIT(2) /* F7 (NF for F4) */ + #define USART_SR_ORE BIT(3) + #define USART_SR_IDLE BIT(4) + #define USART_SR_RXNE BIT(5) +@@ -126,7 +126,8 @@ struct stm32_usart_info stm32h7_info = { + #define USART_SR_SBKF BIT(18) /* F7 */ + #define USART_SR_WUF BIT(20) /* H7 */ + #define USART_SR_TEACK BIT(21) /* F7 */ +-#define USART_SR_ERR_MASK (USART_SR_ORE | USART_SR_FE | USART_SR_PE) ++#define USART_SR_ERR_MASK (USART_SR_ORE | USART_SR_NE | USART_SR_FE |\ ++ USART_SR_PE) + /* Dummy bits */ + #define USART_SR_DUMMY_RX BIT(16) + +@@ -246,9 +247,9 @@ struct stm32_usart_info stm32h7_info = { + #define STM32_SERIAL_NAME "ttySTM" + #define STM32_MAX_PORTS 8 + +-#define RX_BUF_L 200 /* dma rx buffer length */ +-#define RX_BUF_P RX_BUF_L /* dma rx buffer period */ +-#define TX_BUF_L 200 /* dma tx buffer length */ ++#define RX_BUF_L 4096 /* dma rx buffer length */ ++#define RX_BUF_P (RX_BUF_L / 2) /* dma rx buffer period */ ++#define TX_BUF_L RX_BUF_L /* dma tx buffer length */ + + struct stm32_port { + struct uart_port port; +@@ -273,6 +274,7 @@ struct stm32_port { + bool wakeup_src; + int rdr_mask; /* receive data register mask */ + struct mctrl_gpios *gpios; /* modem control gpios */ ++ struct dma_tx_state rx_dma_state; + }; + + static struct stm32_port stm32_ports[STM32_MAX_PORTS]; +diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c +index 4ce7cba2b48aa..8f3b9a0a38e1d 100644 +--- a/drivers/usb/atm/cxacru.c ++++ b/drivers/usb/atm/cxacru.c +@@ -1131,6 +1131,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, + struct cxacru_data *instance; + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD]; ++ struct usb_endpoint_descriptor *in, *out; + int ret; + + /* instance init */ +@@ -1177,6 +1178,19 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, + goto fail; + } + ++ if (usb_endpoint_xfer_int(&cmd_ep->desc)) ++ ret = usb_find_common_endpoints(intf->cur_altsetting, ++ NULL, NULL, &in, &out); ++ else ++ ret = usb_find_common_endpoints(intf->cur_altsetting, ++ &in, &out, NULL, NULL); ++ ++ if (ret) { ++ usb_err(usbatm_instance, "cxacru_bind: interface has incorrect endpoints\n"); ++ ret = -ENODEV; ++ goto fail; ++ } ++ + if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT) { + usb_fill_int_urb(instance->rcv_urb, +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 0d99ba64ea528..d85606bad5628 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -266,14 +266,14 @@ static void wdm_int_callback(struct urb *urb) + dev_err(&desc->intf->dev, "Stall on int endpoint\n"); + goto sw; /* halt is cleared in work */ + default: +- dev_err(&desc->intf->dev, ++ dev_err_ratelimited(&desc->intf->dev, + "nonzero urb status received: %d\n", status); + break; + } + } + + if (urb->actual_length < sizeof(struct usb_cdc_notification)) { +- dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n", ++ dev_err_ratelimited(&desc->intf->dev, "wdm_int_callback - %d bytes\n", + urb->actual_length); + goto exit; + } +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index a469d05247894..1dc417da1a0fe 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1752,7 +1752,6 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc) + + static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + { +- unsigned long flags; + u32 reg; + + switch (dwc->current_dr_role) { +@@ -1790,9 +1789,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + break; + + if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { +- spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_suspend(dwc); +- spin_unlock_irqrestore(&dwc->lock, flags); + synchronize_irq(dwc->irq_gadget); + } + +@@ -1809,7 +1806,6 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + + static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) + { +- unsigned long flags; + int ret; + u32 reg; + +@@ -1858,9 +1854,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) + if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) { + dwc3_otg_host_init(dwc); + } else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { +- spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_resume(dwc); +- spin_unlock_irqrestore(&dwc->lock, flags); + } + + break; +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index a4367a43cdd87..ad858044e0bfd 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -830,9 +830,9 @@ static void ffs_user_copy_worker(struct work_struct *work) + { + struct ffs_io_data *io_data = container_of(work, struct ffs_io_data, + work); +- int ret = io_data->req->status ? io_data->req->status : +- io_data->req->actual; ++ int ret = io_data->status; + bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD; ++ unsigned long flags; + + if (io_data->read && ret > 0) { + kthread_use_mm(io_data->mm); +@@ -845,7 +845,10 @@ static void ffs_user_copy_worker(struct work_struct *work) + if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd) + eventfd_signal(io_data->ffs->ffs_eventfd, 1); + ++ spin_lock_irqsave(&io_data->ffs->eps_lock, flags); + usb_ep_free_request(io_data->ep, io_data->req); ++ io_data->req = NULL; ++ spin_unlock_irqrestore(&io_data->ffs->eps_lock, flags); + + if (io_data->read) + kfree(io_data->to_free); +@@ -861,6 +864,8 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep, + + ENTER(); + ++ io_data->status = req->status ? req->status : req->actual; ++ + INIT_WORK(&io_data->work, ffs_user_copy_worker); + queue_work(ffs->io_completion_wq, &io_data->work); + } +diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c +index a881c69b1f2bf..728cb9702d5a9 100644 +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -210,6 +210,7 @@ static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, + struct usb_endpoint_descriptor *ss) + { + switch (gadget->speed) { ++ case USB_SPEED_SUPER_PLUS: + case USB_SPEED_SUPER: + return ss; + case USB_SPEED_HIGH: +@@ -447,11 +448,8 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) + mutex_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + +- if (dev->interface < 0) { +- spin_unlock_irqrestore(&dev->lock, flags); +- mutex_unlock(&dev->lock_printer_io); +- return -ENODEV; +- } ++ if (dev->interface < 0) ++ goto out_disabled; + + /* We will use this flag later to check if a printer reset happened + * after we turn interrupts back on. +@@ -459,6 +457,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) + dev->reset_printer = 0; + + setup_rx_reqs(dev); ++ /* this dropped the lock - need to retest */ ++ if (dev->interface < 0) ++ goto out_disabled; + + bytes_copied = 0; + current_rx_req = dev->current_rx_req; +@@ -492,6 +493,8 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) + wait_event_interruptible(dev->rx_wait, + (likely(!list_empty(&dev->rx_buffers)))); + spin_lock_irqsave(&dev->lock, flags); ++ if (dev->interface < 0) ++ goto out_disabled; + } + + /* We have data to return then copy it to the caller's buffer.*/ +@@ -535,6 +538,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) + return -EAGAIN; + } + ++ if (dev->interface < 0) ++ goto out_disabled; ++ + /* If we not returning all the data left in this RX request + * buffer then adjust the amount of data left in the buffer. + * Othewise if we are done with this RX request buffer then +@@ -564,6 +570,11 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) + return bytes_copied; + else + return -EAGAIN; ++ ++out_disabled: ++ spin_unlock_irqrestore(&dev->lock, flags); ++ mutex_unlock(&dev->lock_printer_io); ++ return -ENODEV; + } + + static ssize_t +@@ -584,11 +595,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) + mutex_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + +- if (dev->interface < 0) { +- spin_unlock_irqrestore(&dev->lock, flags); +- mutex_unlock(&dev->lock_printer_io); +- return -ENODEV; +- } ++ if (dev->interface < 0) ++ goto out_disabled; + + /* Check if a printer reset happens while we have interrupts on */ + dev->reset_printer = 0; +@@ -611,6 +619,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) + wait_event_interruptible(dev->tx_wait, + (likely(!list_empty(&dev->tx_reqs)))); + spin_lock_irqsave(&dev->lock, flags); ++ if (dev->interface < 0) ++ goto out_disabled; + } + + while (likely(!list_empty(&dev->tx_reqs)) && len) { +@@ -660,6 +670,9 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) + return -EAGAIN; + } + ++ if (dev->interface < 0) ++ goto out_disabled; ++ + list_add(&req->list, &dev->tx_reqs_active); + + /* here, we unlock, and only unlock, to avoid deadlock. */ +@@ -672,6 +685,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) + mutex_unlock(&dev->lock_printer_io); + return -EAGAIN; + } ++ if (dev->interface < 0) ++ goto out_disabled; + } + + spin_unlock_irqrestore(&dev->lock, flags); +@@ -683,6 +698,11 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) + return bytes_copied; + else + return -EAGAIN; ++ ++out_disabled: ++ spin_unlock_irqrestore(&dev->lock, flags); ++ mutex_unlock(&dev->lock_printer_io); ++ return -ENODEV; + } + + static int +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index f501eb3efca78..f317931545b94 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -36,6 +36,7 @@ + + #define PCI_VENDOR_ID_ETRON 0x1b6f + #define PCI_DEVICE_ID_EJ168 0x7023 ++#define PCI_DEVICE_ID_EJ188 0x7052 + + #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 + #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 +@@ -276,6 +277,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + xhci->quirks |= XHCI_TRUST_TX_LENGTH; + xhci->quirks |= XHCI_BROKEN_STREAMS; + } ++ if (pdev->vendor == PCI_VENDOR_ID_ETRON && ++ pdev->device == PCI_DEVICE_ID_EJ188) { ++ xhci->quirks |= XHCI_RESET_ON_RESUME; ++ xhci->quirks |= XHCI_BROKEN_STREAMS; ++ } ++ + if (pdev->vendor == PCI_VENDOR_ID_RENESAS && + pdev->device == 0x0014) { + xhci->quirks |= XHCI_TRUST_TX_LENGTH; +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 31d355613933f..ddb5640a8bf39 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -994,13 +994,27 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) + break; + case TD_DIRTY: /* TD is cached, clear it */ + case TD_HALTED: ++ case TD_CLEARING_CACHE_DEFERRED: ++ if (cached_td) { ++ if (cached_td->urb->stream_id != td->urb->stream_id) { ++ /* Multiple streams case, defer move dq */ ++ xhci_dbg(xhci, ++ "Move dq deferred: stream %u URB %p\n", ++ td->urb->stream_id, td->urb); ++ td->cancel_status = TD_CLEARING_CACHE_DEFERRED; ++ break; ++ } ++ ++ /* Should never happen, but clear the TD if it does */ ++ xhci_warn(xhci, ++ "Found multiple active URBs %p and %p in stream %u?\n", ++ td->urb, cached_td->urb, ++ td->urb->stream_id); ++ td_to_noop(xhci, ring, cached_td, false); ++ cached_td->cancel_status = TD_CLEARED; ++ } ++ + td->cancel_status = TD_CLEARING_CACHE; +- if (cached_td) +- /* FIXME stream case, several stopped rings */ +- xhci_dbg(xhci, +- "Move dq past stream %u URB %p instead of stream %u URB %p\n", +- td->urb->stream_id, td->urb, +- cached_td->urb->stream_id, cached_td->urb); + cached_td = td; + break; + } +@@ -1020,10 +1034,16 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) + if (err) { + /* Failed to move past cached td, just set cached TDs to no-op */ + list_for_each_entry_safe(td, tmp_td, &ep->cancelled_td_list, cancelled_td_list) { +- if (td->cancel_status != TD_CLEARING_CACHE) ++ /* ++ * Deferred TDs need to have the deq pointer set after the above command ++ * completes, so if that failed we just give up on all of them (and ++ * complain loudly since this could cause issues due to caching). ++ */ ++ if (td->cancel_status != TD_CLEARING_CACHE && ++ td->cancel_status != TD_CLEARING_CACHE_DEFERRED) + continue; +- xhci_dbg(xhci, "Failed to clear cancelled cached URB %p, mark clear anyway\n", +- td->urb); ++ xhci_warn(xhci, "Failed to clear cancelled cached URB %p, mark clear anyway\n", ++ td->urb); + td_to_noop(xhci, ring, td, false); + td->cancel_status = TD_CLEARED; + } +@@ -1366,6 +1386,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, + struct xhci_ep_ctx *ep_ctx; + struct xhci_slot_ctx *slot_ctx; + struct xhci_td *td, *tmp_td; ++ bool deferred = false; + + ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3])); + stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2])); +@@ -1452,6 +1473,8 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, + xhci_dbg(ep->xhci, "%s: Giveback cancelled URB %p TD\n", + __func__, td->urb); + xhci_td_cleanup(ep->xhci, td, ep_ring, td->status); ++ } else if (td->cancel_status == TD_CLEARING_CACHE_DEFERRED) { ++ deferred = true; + } else { + xhci_dbg(ep->xhci, "%s: Keep cancelled URB %p TD as cancel_status is %d\n", + __func__, td->urb, td->cancel_status); +@@ -1461,8 +1484,17 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, + ep->ep_state &= ~SET_DEQ_PENDING; + ep->queued_deq_seg = NULL; + ep->queued_deq_ptr = NULL; +- /* Restart any rings with pending URBs */ +- ring_doorbell_for_active_rings(xhci, slot_id, ep_index); ++ ++ if (deferred) { ++ /* We have more streams to clear */ ++ xhci_dbg(ep->xhci, "%s: Pending TDs to clear, continuing with invalidation\n", ++ __func__); ++ xhci_invalidate_cancelled_tds(ep); ++ } else { ++ /* Restart any rings with pending URBs */ ++ xhci_dbg(ep->xhci, "%s: All TDs cleared, ring doorbell\n", __func__); ++ ring_doorbell_for_active_rings(xhci, slot_id, ep_index); ++ } + } + + static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id, +@@ -2570,9 +2602,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, + goto finish_td; + case COMP_STOPPED_LENGTH_INVALID: + /* stopped on ep trb with invalid length, exclude it */ +- ep_trb_len = 0; +- remaining = 0; +- break; ++ td->urb->actual_length = sum_trb_lengths(xhci, ep_ring, ep_trb); ++ goto finish_td; + case COMP_USB_TRANSACTION_ERROR: + if (xhci->quirks & XHCI_NO_SOFT_RETRY || + (ep->err_count++ > MAX_SOFT_RETRY) || +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 0e46b9e45c20c..4709d509c6972 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1556,6 +1556,7 @@ enum xhci_cancelled_td_status { + TD_DIRTY = 0, + TD_HALTED, + TD_CLEARING_CACHE, ++ TD_CLEARING_CACHE_DEFERRED, + TD_CLEARED, + }; + +diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c +index 0be8efcda15d5..d972c09629397 100644 +--- a/drivers/usb/misc/uss720.c ++++ b/drivers/usb/misc/uss720.c +@@ -677,7 +677,7 @@ static int uss720_probe(struct usb_interface *intf, + struct parport_uss720_private *priv; + struct parport *pp; + unsigned char reg; +- int i; ++ int ret; + + dev_dbg(&intf->dev, "probe: vendor id 0x%x, device id 0x%x\n", + le16_to_cpu(usbdev->descriptor.idVendor), +@@ -688,8 +688,8 @@ static int uss720_probe(struct usb_interface *intf, + usb_put_dev(usbdev); + return -ENODEV; + } +- i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2); +- dev_dbg(&intf->dev, "set interface result %d\n", i); ++ ret = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2); ++ dev_dbg(&intf->dev, "set interface result %d\n", ret); + + interface = intf->cur_altsetting; + +@@ -725,12 +725,18 @@ static int uss720_probe(struct usb_interface *intf, + set_1284_register(pp, 7, 0x00, GFP_KERNEL); + set_1284_register(pp, 6, 0x30, GFP_KERNEL); /* PS/2 mode */ + set_1284_register(pp, 2, 0x0c, GFP_KERNEL); +- /* debugging */ +- get_1284_register(pp, 0, ®, GFP_KERNEL); ++ ++ /* The Belkin F5U002 Rev 2 P80453-B USB parallel port adapter shares the ++ * device ID 050d:0002 with some other device that works with this ++ * driver, but it itself does not. Detect and handle the bad cable ++ * here. */ ++ ret = get_1284_register(pp, 0, ®, GFP_KERNEL); + dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg); ++ if (ret < 0) ++ return ret; + +- i = usb_find_last_int_in_endpoint(interface, &epd); +- if (!i) { ++ ret = usb_find_last_int_in_endpoint(interface, &epd); ++ if (!ret) { + dev_dbg(&intf->dev, "epaddr %d interval %d\n", + epd->bEndpointAddress, epd->bInterval); + } +diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c +index 1c023c0091c4b..ad336daa93447 100644 +--- a/drivers/usb/musb/da8xx.c ++++ b/drivers/usb/musb/da8xx.c +@@ -556,7 +556,7 @@ static int da8xx_probe(struct platform_device *pdev) + ret = of_platform_populate(pdev->dev.of_node, NULL, + da8xx_auxdata_lookup, &pdev->dev); + if (ret) +- return ret; ++ goto err_unregister_phy; + + memset(musb_resources, 0x00, sizeof(*musb_resources) * + ARRAY_SIZE(musb_resources)); +@@ -582,9 +582,13 @@ static int da8xx_probe(struct platform_device *pdev) + ret = PTR_ERR_OR_ZERO(glue->musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); +- usb_phy_generic_unregister(glue->usb_phy); ++ goto err_unregister_phy; + } + ++ return 0; ++ ++err_unregister_phy: ++ usb_phy_generic_unregister(glue->usb_phy); + return ret; + } + +diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c +index dcc4778d1ae99..17fe35083f048 100644 +--- a/drivers/usb/storage/alauda.c ++++ b/drivers/usb/storage/alauda.c +@@ -105,6 +105,8 @@ struct alauda_info { + unsigned char sense_key; + unsigned long sense_asc; /* additional sense code */ + unsigned long sense_ascq; /* additional sense code qualifier */ ++ ++ bool media_initialized; + }; + + #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) +@@ -476,11 +478,12 @@ static int alauda_check_media(struct us_data *us) + } + + /* Check for media change */ +- if (status[0] & 0x08) { ++ if (status[0] & 0x08 || !info->media_initialized) { + usb_stor_dbg(us, "Media change detected\n"); + alauda_free_maps(&MEDIA_INFO(us)); +- alauda_init_media(us); +- ++ rc = alauda_init_media(us); ++ if (rc == USB_STOR_TRANSPORT_GOOD) ++ info->media_initialized = true; + info->sense_key = UNIT_ATTENTION; + info->sense_asc = 0x28; + info->sense_ascq = 0x00; +diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c +index 359c9bd7848fb..5a5886cb0c002 100644 +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -5351,6 +5351,7 @@ static void _tcpm_pd_hard_reset(struct tcpm_port *port) + port->tcpc->set_bist_data(port->tcpc, false); + + switch (port->state) { ++ case TOGGLING: + case ERROR_RECOVERY: + case PORT_RESET: + case PORT_RESET_WAIT_OFF: +diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c +index 564864f039d20..4684d4756b427 100644 +--- a/drivers/vdpa/vdpa_user/vduse_dev.c ++++ b/drivers/vdpa/vdpa_user/vduse_dev.c +@@ -8,6 +8,7 @@ + * + */ + ++#include "linux/virtio_net.h" + #include <linux/init.h> + #include <linux/module.h> + #include <linux/cdev.h> +@@ -26,6 +27,7 @@ + #include <uapi/linux/virtio_config.h> + #include <uapi/linux/virtio_ids.h> + #include <uapi/linux/virtio_blk.h> ++#include <uapi/linux/virtio_ring.h> + #include <linux/mod_devicetable.h> + + #include "iova_domain.h" +@@ -1227,13 +1229,17 @@ static bool device_is_allowed(u32 device_id) + return false; + } + +-static bool features_is_valid(u64 features) ++static bool features_is_valid(struct vduse_dev_config *config) + { +- if (!(features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) ++ if (!(config->features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM))) + return false; + + /* Now we only support read-only configuration space */ +- if (features & (1ULL << VIRTIO_BLK_F_CONFIG_WCE)) ++ if ((config->device_id == VIRTIO_ID_BLOCK) && ++ (config->features & BIT_ULL(VIRTIO_BLK_F_CONFIG_WCE))) ++ return false; ++ else if ((config->device_id == VIRTIO_ID_NET) && ++ (config->features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ))) + return false; + + return true; +@@ -1260,7 +1266,7 @@ static bool vduse_validate_config(struct vduse_dev_config *config) + if (!device_is_allowed(config->device_id)) + return false; + +- if (!features_is_valid(config->features)) ++ if (!features_is_valid(config)) + return false; + + return true; +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 4ca6828586af5..eeaa38b67c4b3 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -1493,6 +1493,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) + container_of(work, struct btrfs_fs_info, reclaim_bgs_work); + struct btrfs_block_group *bg; + struct btrfs_space_info *space_info; ++ LIST_HEAD(retry_list); + + if (!test_bit(BTRFS_FS_OPEN, &fs_info->flags)) + return; +@@ -1583,8 +1584,11 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) + } + + next: +- if (ret) +- btrfs_mark_bg_to_reclaim(bg); ++ if (ret) { ++ /* Refcount held by the reclaim_bgs list after splice. */ ++ btrfs_get_block_group(bg); ++ list_add_tail(&bg->bg_list, &retry_list); ++ } + btrfs_put_block_group(bg); + + mutex_unlock(&fs_info->reclaim_bgs_lock); +@@ -1604,6 +1608,9 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) + spin_unlock(&fs_info->unused_bgs_lock); + mutex_unlock(&fs_info->reclaim_bgs_lock); + end: ++ spin_lock(&fs_info->unused_bgs_lock); ++ list_splice_tail(&retry_list, &fs_info->reclaim_bgs); ++ spin_unlock(&fs_info->unused_bgs_lock); + btrfs_exclop_finish(fs_info); + sb_end_write(fs_info->sb); + } +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index c1dfde886b1e3..092ebed754b0c 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4707,19 +4707,11 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, + struct btrfs_fs_info *fs_info) + { + struct rb_node *node; +- struct btrfs_delayed_ref_root *delayed_refs; ++ struct btrfs_delayed_ref_root *delayed_refs = &trans->delayed_refs; + struct btrfs_delayed_ref_node *ref; + int ret = 0; + +- delayed_refs = &trans->delayed_refs; +- + spin_lock(&delayed_refs->lock); +- if (atomic_read(&delayed_refs->num_entries) == 0) { +- spin_unlock(&delayed_refs->lock); +- btrfs_debug(fs_info, "delayed_refs has NO entry"); +- return ret; +- } +- + while ((node = rb_first_cached(&delayed_refs->href_root)) != NULL) { + struct btrfs_delayed_ref_head *head; + struct rb_node *n; +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index d3adcb9e70a66..c254e714f7ceb 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -99,7 +99,7 @@ module_param(enable_oplocks, bool, 0644); + MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1"); + + module_param(enable_gcm_256, bool, 0644); +-MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: n/N/0"); ++MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/0"); + + module_param(require_gcm_256, bool, 0644); + MODULE_PARM_DESC(require_gcm_256, "Require strongest (256 bit) GCM encryption. Default: n/N/0"); +diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c +index 0f2e0ce84a03f..ffae3a7f46ce4 100644 +--- a/fs/cifs/smb2transport.c ++++ b/fs/cifs/smb2transport.c +@@ -194,8 +194,8 @@ smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid) + } + tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid); + if (!tcon) { +- cifs_put_smb_ses(ses); + spin_unlock(&cifs_tcp_ses_lock); ++ cifs_put_smb_ses(ses); + return NULL; + } + spin_unlock(&cifs_tcp_ses_lock); +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index df1e5496352c2..706d7adda3b22 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -2068,8 +2068,6 @@ static void default_options(struct f2fs_sb_info *sbi) + F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS; + F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON; + +- sbi->sb->s_flags &= ~SB_INLINECRYPT; +- + set_opt(sbi, INLINE_XATTR); + set_opt(sbi, INLINE_DATA); + set_opt(sbi, INLINE_DENTRY); +diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c +index f9273f6901c8d..07df16ce80064 100644 +--- a/fs/jfs/xattr.c ++++ b/fs/jfs/xattr.c +@@ -557,9 +557,11 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) + + size_check: + if (EALIST_SIZE(ea_buf->xattr) != ea_size) { ++ int size = min_t(int, EALIST_SIZE(ea_buf->xattr), ea_size); ++ + printk(KERN_ERR "ea_get: invalid extended attribute\n"); + print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, +- ea_buf->xattr, ea_size, 1); ++ ea_buf->xattr, size, 1); + ea_release(inode, ea_buf); + rc = -EIO; + goto clean_up; +diff --git a/fs/ksmbd/mgmt/share_config.c b/fs/ksmbd/mgmt/share_config.c +index a2f0a2edceb8a..e0a6b758094fc 100644 +--- a/fs/ksmbd/mgmt/share_config.c ++++ b/fs/ksmbd/mgmt/share_config.c +@@ -165,8 +165,12 @@ static struct ksmbd_share_config *share_config_request(struct unicode_map *um, + + share->path = kstrndup(ksmbd_share_config_path(resp), path_len, + GFP_KERNEL); +- if (share->path) ++ if (share->path) { + share->path_sz = strlen(share->path); ++ while (share->path_sz > 1 && ++ share->path[share->path_sz - 1] == '/') ++ share->path[--share->path_sz] = '\0'; ++ } + share->create_mask = resp->create_mask; + share->directory_mask = resp->directory_mask; + share->force_create_mode = resp->force_create_mode; +diff --git a/fs/nfs/read.c b/fs/nfs/read.c +index 08d6cc57cbc37..b02372ec07a52 100644 +--- a/fs/nfs/read.c ++++ b/fs/nfs/read.c +@@ -120,12 +120,8 @@ static void nfs_readpage_release(struct nfs_page *req, int error) + if (nfs_error_is_fatal_on_server(error) && error != -ETIMEDOUT) + SetPageError(page); + if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) { +- struct address_space *mapping = page_file_mapping(page); +- + if (PageUptodate(page)) + nfs_readpage_to_fscache(inode, page, 0); +- else if (!PageError(page) && !PagePrivate(page)) +- generic_error_remove_page(mapping, page); + unlock_page(page); + } + nfs_release_request(req); +diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c +index 8c52b6c9d31a2..3a2ad88ae6481 100644 +--- a/fs/nfsd/nfsfh.c ++++ b/fs/nfsd/nfsfh.c +@@ -569,7 +569,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, + _fh_update(fhp, exp, dentry); + if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) { + fh_put(fhp); +- return nfserr_opnotsupp; ++ return nfserr_stale; + } + + return 0; +@@ -595,7 +595,7 @@ fh_update(struct svc_fh *fhp) + + _fh_update(fhp, fhp->fh_export, dentry); + if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) +- return nfserr_opnotsupp; ++ return nfserr_stale; + return 0; + out_bad: + printk(KERN_ERR "fh_update: fh not verified!\n"); +diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c +index eb7de9e2a384e..552234ef22fe7 100644 +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -186,19 +186,24 @@ static bool nilfs_check_page(struct page *page) + return false; + } + +-static struct page *nilfs_get_page(struct inode *dir, unsigned long n) ++static void *nilfs_get_page(struct inode *dir, unsigned long n, ++ struct page **pagep) + { + struct address_space *mapping = dir->i_mapping; + struct page *page = read_mapping_page(mapping, n, NULL); ++ void *kaddr; + +- if (!IS_ERR(page)) { +- kmap(page); +- if (unlikely(!PageChecked(page))) { +- if (PageError(page) || !nilfs_check_page(page)) +- goto fail; +- } ++ if (IS_ERR(page)) ++ return page; ++ ++ kaddr = kmap(page); ++ if (unlikely(!PageChecked(page))) { ++ if (!nilfs_check_page(page)) ++ goto fail; + } +- return page; ++ ++ *pagep = page; ++ return kaddr; + + fail: + nilfs_put_page(page); +@@ -275,14 +280,14 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx) + for ( ; n < npages; n++, offset = 0) { + char *kaddr, *limit; + struct nilfs_dir_entry *de; +- struct page *page = nilfs_get_page(inode, n); ++ struct page *page; + +- if (IS_ERR(page)) { ++ kaddr = nilfs_get_page(inode, n, &page); ++ if (IS_ERR(kaddr)) { + nilfs_error(sb, "bad page in #%lu", inode->i_ino); + ctx->pos += PAGE_SIZE - offset; + return -EIO; + } +- kaddr = page_address(page); + de = (struct nilfs_dir_entry *)(kaddr + offset); + limit = kaddr + nilfs_last_byte(inode, n) - + NILFS_DIR_REC_LEN(1); +@@ -345,11 +350,9 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, + start = 0; + n = start; + do { +- char *kaddr; ++ char *kaddr = nilfs_get_page(dir, n, &page); + +- page = nilfs_get_page(dir, n); +- if (!IS_ERR(page)) { +- kaddr = page_address(page); ++ if (!IS_ERR(kaddr)) { + de = (struct nilfs_dir_entry *)kaddr; + kaddr += nilfs_last_byte(dir, n) - reclen; + while ((char *) de <= kaddr) { +@@ -387,15 +390,11 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, + + struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p) + { +- struct page *page = nilfs_get_page(dir, 0); +- struct nilfs_dir_entry *de = NULL; ++ struct nilfs_dir_entry *de = nilfs_get_page(dir, 0, p); + +- if (!IS_ERR(page)) { +- de = nilfs_next_entry( +- (struct nilfs_dir_entry *)page_address(page)); +- *p = page; +- } +- return de; ++ if (IS_ERR(de)) ++ return NULL; ++ return nilfs_next_entry(de); + } + + ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr) +@@ -459,12 +458,11 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode) + for (n = 0; n <= npages; n++) { + char *dir_end; + +- page = nilfs_get_page(dir, n); +- err = PTR_ERR(page); +- if (IS_ERR(page)) ++ kaddr = nilfs_get_page(dir, n, &page); ++ err = PTR_ERR(kaddr); ++ if (IS_ERR(kaddr)) + goto out; + lock_page(page); +- kaddr = page_address(page); + dir_end = kaddr + nilfs_last_byte(dir, n); + de = (struct nilfs_dir_entry *)kaddr; + kaddr += PAGE_SIZE - reclen; +@@ -627,11 +625,10 @@ int nilfs_empty_dir(struct inode *inode) + char *kaddr; + struct nilfs_dir_entry *de; + +- page = nilfs_get_page(inode, i); +- if (IS_ERR(page)) +- continue; ++ kaddr = nilfs_get_page(inode, i, &page); ++ if (IS_ERR(kaddr)) ++ return 0; + +- kaddr = page_address(page); + de = (struct nilfs_dir_entry *)kaddr; + kaddr += nilfs_last_byte(inode, i) - NILFS_DIR_REC_LEN(1); + +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index 1a5f2daa4a95b..440e628f9d4fc 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -1692,6 +1692,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) + if (bh->b_page != bd_page) { + if (bd_page) { + lock_page(bd_page); ++ wait_on_page_writeback(bd_page); + clear_page_dirty_for_io(bd_page); + set_page_writeback(bd_page); + unlock_page(bd_page); +@@ -1705,6 +1706,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) + if (bh == segbuf->sb_super_root) { + if (bh->b_page != bd_page) { + lock_page(bd_page); ++ wait_on_page_writeback(bd_page); + clear_page_dirty_for_io(bd_page); + set_page_writeback(bd_page); + unlock_page(bd_page); +@@ -1721,6 +1723,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) + } + if (bd_page) { + lock_page(bd_page); ++ wait_on_page_writeback(bd_page); + clear_page_dirty_for_io(bd_page); + set_page_writeback(bd_page); + unlock_page(bd_page); +diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c +index c051074016cec..8ad70949d7f8a 100644 +--- a/fs/ocfs2/aops.c ++++ b/fs/ocfs2/aops.c +@@ -2370,6 +2370,11 @@ static int ocfs2_dio_end_io_write(struct inode *inode, + } + + list_for_each_entry(ue, &dwc->dw_zero_list, ue_node) { ++ ret = ocfs2_assure_trans_credits(handle, credits); ++ if (ret < 0) { ++ mlog_errno(ret); ++ break; ++ } + ret = ocfs2_mark_extent_written(inode, &et, handle, + ue->ue_cpos, 1, + ue->ue_phys, +diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c +index d64aea53e1506..403c71a485c7c 100644 +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -1940,6 +1940,8 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + + inode_lock(inode); + ++ /* Wait all existing dio workers, newcomers will block on i_rwsem */ ++ inode_dio_wait(inode); + /* + * This prevents concurrent writes on other nodes + */ +diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c +index 86864a90de2cd..c0450463b489b 100644 +--- a/fs/ocfs2/journal.c ++++ b/fs/ocfs2/journal.c +@@ -447,6 +447,23 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks) + return status; + } + ++/* ++ * Make sure handle has at least 'nblocks' credits available. If it does not ++ * have that many credits available, we will try to extend the handle to have ++ * enough credits. If that fails, we will restart transaction to have enough ++ * credits. Similar notes regarding data consistency and locking implications ++ * as for ocfs2_extend_trans() apply here. ++ */ ++int ocfs2_assure_trans_credits(handle_t *handle, int nblocks) ++{ ++ int old_nblks = jbd2_handle_buffer_credits(handle); ++ ++ trace_ocfs2_assure_trans_credits(old_nblks); ++ if (old_nblks >= nblocks) ++ return 0; ++ return ocfs2_extend_trans(handle, nblocks - old_nblks); ++} ++ + /* + * If we have fewer than thresh credits, extend by OCFS2_MAX_TRANS_DATA. + * If that fails, restart the transaction & regain write access for the +diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h +index a54f20bce9fef..405066a8779b2 100644 +--- a/fs/ocfs2/journal.h ++++ b/fs/ocfs2/journal.h +@@ -242,6 +242,8 @@ handle_t *ocfs2_start_trans(struct ocfs2_super *osb, + int ocfs2_commit_trans(struct ocfs2_super *osb, + handle_t *handle); + int ocfs2_extend_trans(handle_t *handle, int nblocks); ++int ocfs2_assure_trans_credits(handle_t *handle, ++ int nblocks); + int ocfs2_allocate_extend_trans(handle_t *handle, + int thresh); + +diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c +index 0b4f3d287cbc0..69aff1d5946d2 100644 +--- a/fs/ocfs2/namei.c ++++ b/fs/ocfs2/namei.c +@@ -566,7 +566,7 @@ static int __ocfs2_mknod_locked(struct inode *dir, + fe->i_last_eb_blk = 0; + strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE); + fe->i_flags |= cpu_to_le32(OCFS2_VALID_FL); +- ktime_get_real_ts64(&ts); ++ ktime_get_coarse_real_ts64(&ts); + fe->i_atime = fe->i_ctime = fe->i_mtime = + cpu_to_le64(ts.tv_sec); + fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec = +diff --git a/fs/ocfs2/ocfs2_trace.h b/fs/ocfs2/ocfs2_trace.h +index dc4bce1649c1b..7a9cfd61145a0 100644 +--- a/fs/ocfs2/ocfs2_trace.h ++++ b/fs/ocfs2/ocfs2_trace.h +@@ -2578,6 +2578,8 @@ DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_commit_cache_end); + + DEFINE_OCFS2_INT_INT_EVENT(ocfs2_extend_trans); + ++DEFINE_OCFS2_INT_EVENT(ocfs2_assure_trans_credits); ++ + DEFINE_OCFS2_INT_EVENT(ocfs2_extend_trans_restart); + + DEFINE_OCFS2_INT_INT_EVENT(ocfs2_allocate_extend_trans); +diff --git a/fs/open.c b/fs/open.c +index 43e5ca4324bc0..97932af49071a 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -199,13 +199,13 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small) + return error; + } + +-SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) ++SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, length) + { + return do_sys_ftruncate(fd, length, 1); + } + + #ifdef CONFIG_COMPAT +-COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length) ++COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_off_t, length) + { + return do_sys_ftruncate(fd, length, 1); + } +diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c +index e5730986758fa..36b7316ef48d3 100644 +--- a/fs/proc/vmcore.c ++++ b/fs/proc/vmcore.c +@@ -373,6 +373,8 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos, + /* leave now if filled buffer already */ + if (buflen == 0) + return acc; ++ ++ cond_resched(); + } + + list_for_each_entry(m, &vmcore_list, list) { +diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c +index fce4ad976c8c2..26169b1f482c3 100644 +--- a/fs/udf/udftime.c ++++ b/fs/udf/udftime.c +@@ -60,13 +60,18 @@ udf_disk_stamp_to_time(struct timespec64 *dest, struct timestamp src) + dest->tv_sec = mktime64(year, src.month, src.day, src.hour, src.minute, + src.second); + dest->tv_sec -= offset * 60; +- dest->tv_nsec = 1000 * (src.centiseconds * 10000 + +- src.hundredsOfMicroseconds * 100 + src.microseconds); ++ + /* + * Sanitize nanosecond field since reportedly some filesystems are + * recorded with bogus sub-second values. + */ +- dest->tv_nsec %= NSEC_PER_SEC; ++ if (src.centiseconds < 100 && src.hundredsOfMicroseconds < 100 && ++ src.microseconds < 100) { ++ dest->tv_nsec = 1000 * (src.centiseconds * 10000 + ++ src.hundredsOfMicroseconds * 100 + src.microseconds); ++ } else { ++ dest->tv_nsec = 0; ++ } + } + + void +diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h +index e602d848fc1ab..e9caa57cd633a 100644 +--- a/include/kvm/arm_vgic.h ++++ b/include/kvm/arm_vgic.h +@@ -423,6 +423,6 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq, + + int vgic_v4_load(struct kvm_vcpu *vcpu); + void vgic_v4_commit(struct kvm_vcpu *vcpu); +-int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db); ++int vgic_v4_put(struct kvm_vcpu *vcpu); + + #endif /* __KVM_ARM_VGIC_H */ +diff --git a/include/linux/cma.h b/include/linux/cma.h +index 53fd8c3cdbd04..1b302e204c09b 100644 +--- a/include/linux/cma.h ++++ b/include/linux/cma.h +@@ -20,6 +20,15 @@ + + #define CMA_MAX_NAME 64 + ++/* ++ * TODO: once the buddy -- especially pageblock merging and alloc_contig_range() ++ * -- can deal with only some pageblocks of a higher-order page being ++ * MIGRATE_CMA, we can use pageblock_nr_pages. ++ */ ++#define CMA_MIN_ALIGNMENT_PAGES max_t(phys_addr_t, MAX_ORDER_NR_PAGES, \ ++ pageblock_nr_pages) ++#define CMA_MIN_ALIGNMENT_BYTES (PAGE_SIZE * CMA_MIN_ALIGNMENT_PAGES) ++ + struct cma; + + extern unsigned long totalcma_pages; +diff --git a/include/linux/compat.h b/include/linux/compat.h +index 01fddf72a81f0..d91fb5225dbf4 100644 +--- a/include/linux/compat.h ++++ b/include/linux/compat.h +@@ -590,7 +590,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, + asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, + struct compat_statfs64 __user *buf); + asmlinkage long compat_sys_truncate(const char __user *, compat_off_t); +-asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t); ++asmlinkage long compat_sys_ftruncate(unsigned int, compat_off_t); + /* No generic prototype for truncate64, ftruncate64, fallocate */ + asmlinkage long compat_sys_openat(int dfd, const char __user *filename, + int flags, umode_t mode); +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 5598fc348c69a..7e396e31e0b77 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -627,18 +627,10 @@ static inline efi_status_t efi_query_variable_store(u32 attributes, + #endif + extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); + +-extern int __init efi_memmap_alloc(unsigned int num_entries, +- struct efi_memory_map_data *data); +-extern void __efi_memmap_free(u64 phys, unsigned long size, +- unsigned long flags); ++extern int __init __efi_memmap_init(struct efi_memory_map_data *data); + extern int __init efi_memmap_init_early(struct efi_memory_map_data *data); + extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size); + extern void __init efi_memmap_unmap(void); +-extern int __init efi_memmap_install(struct efi_memory_map_data *data); +-extern int __init efi_memmap_split_count(efi_memory_desc_t *md, +- struct range *range); +-extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, +- void *buf, struct efi_mem_range *mem); + + #ifdef CONFIG_EFI_ESRT + extern void __init efi_esrt_init(void); +diff --git a/include/linux/filter.h b/include/linux/filter.h +index af0103bebb7bf..9cb3558683393 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -875,14 +875,15 @@ bpf_ctx_narrow_access_offset(u32 off, u32 size, u32 size_default) + + #define bpf_classic_proglen(fprog) (fprog->len * sizeof(fprog->filter[0])) + +-static inline void bpf_prog_lock_ro(struct bpf_prog *fp) ++static inline int __must_check bpf_prog_lock_ro(struct bpf_prog *fp) + { + #ifndef CONFIG_BPF_JIT_ALWAYS_ON + if (!fp->jited) { + set_vm_flush_reset_perms(fp); +- set_memory_ro((unsigned long)fp, fp->pages); ++ return set_memory_ro((unsigned long)fp, fp->pages); + } + #endif ++ return 0; + } + + static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr) +diff --git a/include/linux/i2c.h b/include/linux/i2c.h +index 2ce3efbe9198a..f071a121ed914 100644 +--- a/include/linux/i2c.h ++++ b/include/linux/i2c.h +@@ -954,15 +954,33 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr); + + #endif /* I2C */ + ++/* must call put_device() when done with returned i2c_client device */ ++struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode); ++ ++/* must call put_device() when done with returned i2c_adapter device */ ++struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode); ++ ++/* must call i2c_put_adapter() when done with returned i2c_adapter device */ ++struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode); ++ + #if IS_ENABLED(CONFIG_OF) + /* must call put_device() when done with returned i2c_client device */ +-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); ++static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) ++{ ++ return i2c_find_device_by_fwnode(of_fwnode_handle(node)); ++} + + /* must call put_device() when done with returned i2c_adapter device */ +-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node); ++static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) ++{ ++ return i2c_find_adapter_by_fwnode(of_fwnode_handle(node)); ++} + + /* must call i2c_put_adapter() when done with returned i2c_adapter device */ +-struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node); ++static inline struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node) ++{ ++ return i2c_get_adapter_by_fwnode(of_fwnode_handle(node)); ++} + + const struct of_device_id + *i2c_of_match_device(const struct of_device_id *matches, +diff --git a/include/linux/iommu.h b/include/linux/iommu.h +index d2f3435e7d176..2202a665b0927 100644 +--- a/include/linux/iommu.h ++++ b/include/linux/iommu.h +@@ -1038,7 +1038,7 @@ iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev) + static inline struct iommu_sva * + iommu_sva_bind_device(struct device *dev, struct mm_struct *mm, void *drvdata) + { +- return NULL; ++ return ERR_PTR(-ENODEV); + } + + static inline void iommu_sva_unbind_device(struct iommu_sva *handle) +diff --git a/include/linux/kcov.h b/include/linux/kcov.h +index 55dc338f6bcdd..492af783eb9b4 100644 +--- a/include/linux/kcov.h ++++ b/include/linux/kcov.h +@@ -21,6 +21,8 @@ enum kcov_mode { + KCOV_MODE_TRACE_PC = 2, + /* Collecting comparison operands mode. */ + KCOV_MODE_TRACE_CMP = 3, ++ /* The process owns a KCOV remote reference. */ ++ KCOV_MODE_REMOTE = 4, + }; + + #define KCOV_IN_CTXSW (1 << 30) +diff --git a/include/linux/mdio.h b/include/linux/mdio.h +index 5e6dc38f418e4..3a6ff4e7284a8 100644 +--- a/include/linux/mdio.h ++++ b/include/linux/mdio.h +@@ -7,6 +7,7 @@ + #define __LINUX_MDIO_H__ + + #include <uapi/linux/mdio.h> ++#include <linux/bitfield.h> + #include <linux/mod_devicetable.h> + + /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit +@@ -14,6 +15,7 @@ + */ + #define MII_ADDR_C45 (1<<30) + #define MII_DEVADDR_C45_SHIFT 16 ++#define MII_DEVADDR_C45_MASK GENMASK(20, 16) + #define MII_REGADDR_C45_MASK GENMASK(15, 0) + + struct gpio_desc; +@@ -355,6 +357,16 @@ static inline u32 mdiobus_c45_addr(int devad, u16 regnum) + return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum; + } + ++static inline u16 mdiobus_c45_regad(u32 regnum) ++{ ++ return FIELD_GET(MII_REGADDR_C45_MASK, regnum); ++} ++ ++static inline u16 mdiobus_c45_devad(u32 regnum) ++{ ++ return FIELD_GET(MII_DEVADDR_C45_MASK, regnum); ++} ++ + static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad, + u16 regnum) + { +diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h +index ae2e75d15b219..63f804574c4e9 100644 +--- a/include/linux/mod_devicetable.h ++++ b/include/linux/mod_devicetable.h +@@ -676,6 +676,8 @@ struct x86_cpu_id { + __u16 model; + __u16 steppings; + __u16 feature; /* bit index */ ++ /* Solely for kernel-internal use: DO NOT EXPORT to userspace! */ ++ __u16 flags; + kernel_ulong_t driver_data; + }; + +diff --git a/include/linux/nvme.h b/include/linux/nvme.h +index 461ee0ee59fe4..537cc5b7e0500 100644 +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -71,8 +71,8 @@ enum { + NVMF_RDMA_QPTYPE_DATAGRAM = 2, /* Reliable Datagram */ + }; + +-/* RDMA QP Service Type codes for Discovery Log Page entry TSAS +- * RDMA_QPTYPE field ++/* RDMA Provider Type codes for Discovery Log Page entry TSAS ++ * RDMA_PRTYPE field + */ + enum { + NVMF_RDMA_PRTYPE_NOT_SPECIFIED = 1, /* No Provider Specified */ +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 25e2e7756b1d8..32805c3a37bb3 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -154,6 +154,15 @@ enum pci_interrupt_pin { + /* The number of legacy PCI INTx interrupts */ + #define PCI_NUM_INTX 4 + ++/* ++ * Reading from a device that doesn't respond typically returns ~0. A ++ * successful read from a device may also return ~0, so you need additional ++ * information to reliably identify errors. ++ */ ++#define PCI_ERROR_RESPONSE (~0ULL) ++#define PCI_SET_ERROR_RESPONSE(val) (*(val) = ((typeof(*(val))) PCI_ERROR_RESPONSE)) ++#define PCI_POSSIBLE_ERROR(val) ((val) == ((typeof(val)) PCI_ERROR_RESPONSE)) ++ + /* + * pci_power_t values must match the bits in the Capabilities PME_Support + * and Control/Status PowerState fields in the Power Management capability. +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 15de91c65a09a..b230c422dc3b9 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2447,6 +2447,8 @@ static inline void *skb_pull_inline(struct sk_buff *skb, unsigned int len) + return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len); + } + ++void *skb_pull_data(struct sk_buff *skb, size_t len); ++ + void *__pskb_pull_tail(struct sk_buff *skb, int delta); + + static inline void *__pskb_pull(struct sk_buff *skb, unsigned int len) +diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h +index 7a1446a7e336b..b8037a46ff41d 100644 +--- a/include/linux/syscalls.h ++++ b/include/linux/syscalls.h +@@ -453,7 +453,7 @@ asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user *buf); + asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, + struct statfs64 __user *buf); + asmlinkage long sys_truncate(const char __user *path, long length); +-asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length); ++asmlinkage long sys_ftruncate(unsigned int fd, off_t length); + #if BITS_PER_LONG == 32 + asmlinkage long sys_truncate64(const char __user *path, loff_t length); + asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length); +@@ -959,9 +959,15 @@ asmlinkage long sys_prlimit64(pid_t pid, unsigned int resource, + const struct rlimit64 __user *new_rlim, + struct rlimit64 __user *old_rlim); + asmlinkage long sys_fanotify_init(unsigned int flags, unsigned int event_f_flags); ++#if defined(CONFIG_ARCH_SPLIT_ARG64) ++asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, ++ unsigned int mask_1, unsigned int mask_2, ++ int dfd, const char __user * pathname); ++#else + asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, + u64 mask, int fd, + const char __user *pathname); ++#endif + asmlinkage long sys_name_to_handle_at(int dfd, const char __user *name, + struct file_handle __user *handle, + int __user *mnt_id, int flag); +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index b6114bc0dd0f2..d5935610c6602 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1690,18 +1690,46 @@ static inline int hci_check_conn_params(u16 min, u16 max, u16 latency, + { + u16 max_latency; + +- if (min > max || min < 6 || max > 3200) ++ if (min > max) { ++ BT_WARN("min %d > max %d", min, max); + return -EINVAL; ++ } ++ ++ if (min < 6) { ++ BT_WARN("min %d < 6", min); ++ return -EINVAL; ++ } ++ ++ if (max > 3200) { ++ BT_WARN("max %d > 3200", max); ++ return -EINVAL; ++ } ++ ++ if (to_multiplier < 10) { ++ BT_WARN("to_multiplier %d < 10", to_multiplier); ++ return -EINVAL; ++ } + +- if (to_multiplier < 10 || to_multiplier > 3200) ++ if (to_multiplier > 3200) { ++ BT_WARN("to_multiplier %d > 3200", to_multiplier); + return -EINVAL; ++ } + +- if (max >= to_multiplier * 8) ++ if (max >= to_multiplier * 8) { ++ BT_WARN("max %d >= to_multiplier %d * 8", max, to_multiplier); + return -EINVAL; ++ } + + max_latency = (to_multiplier * 4 / max) - 1; +- if (latency > 499 || latency > max_latency) ++ if (latency > 499) { ++ BT_WARN("latency %d > 499", latency); + return -EINVAL; ++ } ++ ++ if (latency > max_latency) { ++ BT_WARN("latency %d > max_latency %d", latency, max_latency); ++ return -EINVAL; ++ } + + return 0; + } +diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h +index b6b7e210f9d7a..53ec06703fe4e 100644 +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -260,7 +260,7 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, + struct sock *inet_csk_reqsk_queue_add(struct sock *sk, + struct request_sock *req, + struct sock *child); +-void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, ++bool inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, + unsigned long timeout); + struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child, + struct request_sock *req, +@@ -284,6 +284,14 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) + bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); + void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req); + ++static inline unsigned long ++reqsk_timeout(struct request_sock *req, unsigned long max_timeout) ++{ ++ u64 timeout = (u64)req->timeout << req->num_timeout; ++ ++ return (unsigned long)min_t(u64, timeout, max_timeout); ++} ++ + static inline void inet_csk_prepare_for_destroy_sock(struct sock *sk) + { + /* The below has to be done to allow calling inet_csk_destroy_sock */ +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 1e6e4af4df0ae..3ff6b3362800b 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -567,6 +567,11 @@ static inline void *nft_set_priv(const struct nft_set *set) + return (void *)set->data; + } + ++static inline enum nft_data_types nft_set_datatype(const struct nft_set *set) ++{ ++ return set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE; ++} ++ + static inline bool nft_set_gc_is_pending(const struct nft_set *s) + { + return refcount_read(&s->refs) != 1; +diff --git a/include/net/request_sock.h b/include/net/request_sock.h +index 29e41ff3ec933..144c39db9898a 100644 +--- a/include/net/request_sock.h ++++ b/include/net/request_sock.h +@@ -70,6 +70,7 @@ struct request_sock { + struct saved_syn *saved_syn; + u32 secid; + u32 peer_secid; ++ u32 timeout; + }; + + static inline struct request_sock *inet_reqsk(const struct sock *sk) +@@ -104,6 +105,7 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener, + sk_node_init(&req_to_sk(req)->sk_node); + sk_tx_queue_clear(req_to_sk(req)); + req->saved_syn = NULL; ++ req->timeout = 0; + req->num_timeout = 0; + req->num_retrans = 0; + req->sk = NULL; +diff --git a/include/net/sock.h b/include/net/sock.h +index b8de579b916e8..146f1b9c30636 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1460,13 +1460,21 @@ proto_memory_pressure(struct proto *prot) + + + #ifdef CONFIG_PROC_FS +-/* Called with local bh disabled */ +-void sock_prot_inuse_add(struct net *net, struct proto *prot, int inc); ++#define PROTO_INUSE_NR 64 /* should be enough for the first time */ ++struct prot_inuse { ++ int val[PROTO_INUSE_NR]; ++}; ++ ++static inline void sock_prot_inuse_add(const struct net *net, ++ const struct proto *prot, int val) ++{ ++ this_cpu_add(net->core.prot_inuse->val[prot->inuse_idx], val); ++} + int sock_prot_inuse_get(struct net *net, struct proto *proto); + int sock_inuse_get(struct net *net); + #else +-static inline void sock_prot_inuse_add(struct net *net, struct proto *prot, +- int inc) ++static inline void sock_prot_inuse_add(const struct net *net, ++ const struct proto *prot, int val) + { + } + #endif +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 08923ed4278f0..30f8111f750b5 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -2362,7 +2362,7 @@ static inline u32 tcp_timeout_init(struct sock *sk) + + if (timeout <= 0) + timeout = TCP_TIMEOUT_INIT; +- return timeout; ++ return min_t(int, timeout, TCP_RTO_MAX); + } + + static inline u32 tcp_rwnd_init_bpf(struct sock *sk) +diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h +index 05ec927a3c729..7460f730f7d72 100644 +--- a/include/scsi/scsi_transport_sas.h ++++ b/include/scsi/scsi_transport_sas.h +@@ -199,6 +199,8 @@ unsigned int sas_is_tlr_enabled(struct scsi_device *); + void sas_disable_tlr(struct scsi_device *); + void sas_enable_tlr(struct scsi_device *); + ++bool sas_ata_ncq_prio_supported(struct scsi_device *sdev); ++ + extern struct sas_rphy *sas_end_device_alloc(struct sas_port *); + extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type); + void sas_rphy_free(struct sas_rphy *); +diff --git a/include/trace/events/qdisc.h b/include/trace/events/qdisc.h +index 5180da19d837f..3169ff0973c0c 100644 +--- a/include/trace/events/qdisc.h ++++ b/include/trace/events/qdisc.h +@@ -81,14 +81,14 @@ TRACE_EVENT(qdisc_reset, + TP_ARGS(q), + + TP_STRUCT__entry( +- __string( dev, qdisc_dev(q)->name ) ++ __string( dev, qdisc_dev(q) ? qdisc_dev(q)->name : "(null)" ) + __string( kind, q->ops->id ) + __field( u32, parent ) + __field( u32, handle ) + ), + + TP_fast_assign( +- __assign_str(dev, qdisc_dev(q)->name); ++ __assign_str(dev, qdisc_dev(q) ? qdisc_dev(q)->name : "(null)"); + __assign_str(kind, q->ops->id); + __entry->parent = q->parent; + __entry->handle = q->handle; +diff --git a/include/uapi/asm-generic/hugetlb_encode.h b/include/uapi/asm-generic/hugetlb_encode.h +index 4f3d5aaa11f53..de687009bfe53 100644 +--- a/include/uapi/asm-generic/hugetlb_encode.h ++++ b/include/uapi/asm-generic/hugetlb_encode.h +@@ -20,18 +20,18 @@ + #define HUGETLB_FLAG_ENCODE_SHIFT 26 + #define HUGETLB_FLAG_ENCODE_MASK 0x3f + +-#define HUGETLB_FLAG_ENCODE_16KB (14 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_32MB (25 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_512MB (29 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_16KB (14U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_64KB (16U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_512KB (19U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_1MB (20U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_2MB (21U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_8MB (23U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_16MB (24U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_32MB (25U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_256MB (28U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_512MB (29U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_1GB (30U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_2GB (31U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_16GB (34U << HUGETLB_FLAG_ENCODE_SHIFT) + + #endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */ +diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h +index 1c5fb86d455ab..17a5a317f3c7a 100644 +--- a/include/uapi/asm-generic/unistd.h ++++ b/include/uapi/asm-generic/unistd.h +@@ -805,7 +805,7 @@ __SC_COMP(__NR_pselect6_time64, sys_pselect6, compat_sys_pselect6_time64) + #define __NR_ppoll_time64 414 + __SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64) + #define __NR_io_pgetevents_time64 416 +-__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents) ++__SC_COMP(__NR_io_pgetevents_time64, sys_io_pgetevents, compat_sys_io_pgetevents_time64) + #define __NR_recvmmsg_time64 417 + __SC_COMP(__NR_recvmmsg_time64, sys_recvmmsg, compat_sys_recvmmsg_time64) + #define __NR_mq_timedsend_time64 418 +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 36c2896ee45f4..f36f7b71dc07b 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -1940,7 +1940,9 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err) + } + + finalize: +- bpf_prog_lock_ro(fp); ++ *err = bpf_prog_lock_ro(fp); ++ if (*err) ++ return fp; + + /* The tail call compatibility check can only be done at + * this late stage as we need to determine, if we deal +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index 4fa75791b45e2..1bffee0458863 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -108,18 +108,6 @@ static void bpf_trampoline_module_put(struct bpf_trampoline *tr) + tr->mod = NULL; + } + +-static int is_ftrace_location(void *ip) +-{ +- long addr; +- +- addr = ftrace_location((long)ip); +- if (!addr) +- return 0; +- if (WARN_ON_ONCE(addr != (long)ip)) +- return -EFAULT; +- return 1; +-} +- + static int unregister_fentry(struct bpf_trampoline *tr, void *old_addr) + { + void *ip = tr->func.addr; +@@ -151,12 +139,12 @@ static int modify_fentry(struct bpf_trampoline *tr, void *old_addr, void *new_ad + static int register_fentry(struct bpf_trampoline *tr, void *new_addr) + { + void *ip = tr->func.addr; ++ unsigned long faddr; + int ret; + +- ret = is_ftrace_location(ip); +- if (ret < 0) +- return ret; +- tr->func.ftrace_managed = ret; ++ faddr = ftrace_location((unsigned long)ip); ++ if (faddr) ++ tr->func.ftrace_managed = true; + + if (bpf_trampoline_module_get(tr)) + return -ENOENT; +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 07ca1157f97cf..b9f63c4b8598c 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -12812,10 +12812,14 @@ static int jit_subprogs(struct bpf_verifier_env *env) + * bpf_prog_load will add the kallsyms for the main program. + */ + for (i = 1; i < env->subprog_cnt; i++) { +- bpf_prog_lock_ro(func[i]); +- bpf_prog_kallsyms_add(func[i]); ++ err = bpf_prog_lock_ro(func[i]); ++ if (err) ++ goto out_free; + } + ++ for (i = 1; i < env->subprog_cnt; i++) ++ bpf_prog_kallsyms_add(func[i]); ++ + /* Last step: make now unused interpreter insns from main + * prog consistent for later dump requests, so they can + * later look the same as if they were interpreted only. +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 1c370f87d86f5..acf16e3426518 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -2058,7 +2058,7 @@ EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance); + * The caller needs to hold cpus read locked while calling this function. + * Return: + * On success: +- * Positive state number if @state is CPUHP_AP_ONLINE_DYN; ++ * Positive state number if @state is CPUHP_AP_ONLINE_DYN or CPUHP_BP_PREPARE_DYN; + * 0 for all other states + * On failure: proper (negative) error code + */ +@@ -2081,7 +2081,7 @@ int __cpuhp_setup_state_cpuslocked(enum cpuhp_state state, + ret = cpuhp_store_callbacks(state, name, startup, teardown, + multi_instance); + +- dynstate = state == CPUHP_AP_ONLINE_DYN; ++ dynstate = state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN; + if (ret > 0 && dynstate) { + state = ret; + ret = 0; +@@ -2112,8 +2112,8 @@ int __cpuhp_setup_state_cpuslocked(enum cpuhp_state state, + out: + mutex_unlock(&cpuhp_state_mutex); + /* +- * If the requested state is CPUHP_AP_ONLINE_DYN, return the +- * dynamically allocated state in case of success. ++ * If the requested state is CPUHP_AP_ONLINE_DYN or CPUHP_BP_PREPARE_DYN, ++ * return the dynamically allocated state in case of success. + */ + if (!ret && dynstate) + return state; +diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c +index 3d63d91cba5cf..6ea80ae426228 100644 +--- a/kernel/dma/contiguous.c ++++ b/kernel/dma/contiguous.c +@@ -399,8 +399,6 @@ static const struct reserved_mem_ops rmem_cma_ops = { + + static int __init rmem_cma_setup(struct reserved_mem *rmem) + { +- phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); +- phys_addr_t mask = align - 1; + unsigned long node = rmem->fdt_node; + bool default_cma = of_get_flat_dt_prop(node, "linux,cma-default", NULL); + struct cma *cma; +@@ -416,7 +414,7 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem) + of_get_flat_dt_prop(node, "no-map", NULL)) + return -EINVAL; + +- if ((rmem->base & mask) || (rmem->size & mask)) { ++ if (!IS_ALIGNED(rmem->base | rmem->size, CMA_MIN_ALIGNMENT_BYTES)) { + pr_err("Reserved memory: incorrect alignment of CMA region\n"); + return -EINVAL; + } +diff --git a/kernel/events/core.c b/kernel/events/core.c +index e79cd0fd1d2b7..80d9c8fcc30a6 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -5276,6 +5276,7 @@ int perf_event_release_kernel(struct perf_event *event) + again: + mutex_lock(&event->child_mutex); + list_for_each_entry(child, &event->child_list, child_list) { ++ void *var = NULL; + + /* + * Cannot change, child events are not migrated, see the +@@ -5316,11 +5317,23 @@ int perf_event_release_kernel(struct perf_event *event) + * this can't be the last reference. + */ + put_event(event); ++ } else { ++ var = &ctx->refcount; + } + + mutex_unlock(&event->child_mutex); + mutex_unlock(&ctx->mutex); + put_ctx(ctx); ++ ++ if (var) { ++ /* ++ * If perf_event_free_task() has deleted all events from the ++ * ctx while the child_mutex got released above, make sure to ++ * notify about the preceding put_ctx(). ++ */ ++ smp_mb(); /* pairs with wait_var_event() */ ++ wake_up_var(var); ++ } + goto again; + } + mutex_unlock(&event->child_mutex); +diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c +index 74a4ef1da9ad7..fd75b4a484d76 100644 +--- a/kernel/gcov/gcc_4_7.c ++++ b/kernel/gcov/gcc_4_7.c +@@ -18,7 +18,9 @@ + #include <linux/mm.h> + #include "gcov.h" + +-#if (__GNUC__ >= 10) ++#if (__GNUC__ >= 14) ++#define GCOV_COUNTERS 9 ++#elif (__GNUC__ >= 10) + #define GCOV_COUNTERS 8 + #elif (__GNUC__ >= 7) + #define GCOV_COUNTERS 9 +diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh +index 1966a749e0d96..c618e37ccea98 100755 +--- a/kernel/gen_kheaders.sh ++++ b/kernel/gen_kheaders.sh +@@ -81,12 +81,9 @@ find $cpio_dir -type f -print0 | + xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' + + # Create archive and try to normalize metadata for reproducibility. +-# For compatibility with older versions of tar, files are fed to tar +-# pre-sorted, as --sort=name might not be available. +-find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \ +- tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ +- --owner=0 --group=0 --numeric-owner --no-recursion \ +- -I $XZ -cf $tarfile -C $cpio_dir/ -T - > /dev/null ++tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ ++ --owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X \ ++ -I $XZ -cf $tarfile -C $cpio_dir/ . > /dev/null + + echo $headers_md5 > kernel/kheaders.md5 + echo "$this_file_md5" >> kernel/kheaders.md5 +diff --git a/kernel/kcov.c b/kernel/kcov.c +index 80bfe71bbe13e..793486e00dd6f 100644 +--- a/kernel/kcov.c ++++ b/kernel/kcov.c +@@ -635,6 +635,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, + return -EINVAL; + kcov->mode = mode; + t->kcov = kcov; ++ t->kcov_mode = KCOV_MODE_REMOTE; + kcov->t = t; + kcov->remote = true; + kcov->remote_size = remote_arg->area_size; +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index af57705e1fef3..258d425b2c4a5 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1526,14 +1526,10 @@ static inline int warn_kprobe_rereg(struct kprobe *p) + + int __weak arch_check_ftrace_location(struct kprobe *p) + { +- unsigned long ftrace_addr; ++ unsigned long addr = (unsigned long)p->addr; + +- ftrace_addr = ftrace_location((unsigned long)p->addr); +- if (ftrace_addr) { ++ if (ftrace_location(addr) == addr) { + #ifdef CONFIG_KPROBES_ON_FTRACE +- /* Given address is not on the instruction boundary */ +- if ((unsigned long)p->addr != ftrace_addr) +- return -EILSEQ; + p->flags |= KPROBE_FLAG_FTRACE; + #else /* !CONFIG_KPROBES_ON_FTRACE */ + return -EINVAL; +diff --git a/kernel/padata.c b/kernel/padata.c +index 47f146f061fb1..809978bb249c2 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -98,7 +98,7 @@ static int __init padata_work_alloc_mt(int nworks, void *data, + { + int i; + +- spin_lock(&padata_works_lock); ++ spin_lock_bh(&padata_works_lock); + /* Start at 1 because the current task participates in the job. */ + for (i = 1; i < nworks; ++i) { + struct padata_work *pw = padata_work_alloc(); +@@ -108,7 +108,7 @@ static int __init padata_work_alloc_mt(int nworks, void *data, + padata_work_init(pw, padata_mt_helper, data, 0); + list_add(&pw->pw_list, head); + } +- spin_unlock(&padata_works_lock); ++ spin_unlock_bh(&padata_works_lock); + + return i; + } +@@ -126,12 +126,12 @@ static void __init padata_works_free(struct list_head *works) + if (list_empty(works)) + return; + +- spin_lock(&padata_works_lock); ++ spin_lock_bh(&padata_works_lock); + list_for_each_entry_safe(cur, next, works, pw_list) { + list_del(&cur->pw_list); + padata_work_free(cur); + } +- spin_unlock(&padata_works_lock); ++ spin_unlock_bh(&padata_works_lock); + } + + static void padata_parallel_worker(struct work_struct *parallel_work) +diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c +index 259fc4ca0d9cc..40b011f880675 100644 +--- a/kernel/pid_namespace.c ++++ b/kernel/pid_namespace.c +@@ -214,6 +214,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) + */ + do { + clear_thread_flag(TIF_SIGPENDING); ++ clear_thread_flag(TIF_NOTIFY_SIGNAL); + rc = kernel_wait4(-1, NULL, __WALL, NULL); + } while (rc != -ECHILD); + +diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c +index d820ef615475b..9d8d1f233d7bd 100644 +--- a/kernel/rcu/rcutorture.c ++++ b/kernel/rcu/rcutorture.c +@@ -1604,7 +1604,8 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid) + preempt_disable(); + pipe_count = READ_ONCE(p->rtort_pipe_count); + if (pipe_count > RCU_TORTURE_PIPE_LEN) { +- /* Should not happen, but... */ ++ // Should not happen in a correct RCU implementation, ++ // happens quite often for torture_type=busted. + pipe_count = RCU_TORTURE_PIPE_LEN; + } + completed = cur_ops->get_gp_seq(); +@@ -2060,8 +2061,8 @@ static int rcu_torture_stall(void *args) + preempt_disable(); + pr_alert("%s start on CPU %d.\n", + __func__, raw_smp_processor_id()); +- while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(), +- stop_at)) ++ while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(), stop_at) && ++ !kthread_should_stop()) + if (stall_cpu_block) { + #ifdef CONFIG_PREEMPTION + preempt_schedule(); +@@ -2532,11 +2533,12 @@ static void rcu_torture_barrier_cbf(struct rcu_head *rcu) + } + + /* IPI handler to get callback posted on desired CPU, if online. */ +-static void rcu_torture_barrier1cb(void *rcu_void) ++static int rcu_torture_barrier1cb(void *rcu_void) + { + struct rcu_head *rhp = rcu_void; + + cur_ops->call(rhp, rcu_torture_barrier_cbf); ++ return 0; + } + + /* kthread function to register callbacks used to test RCU barriers. */ +@@ -2562,11 +2564,9 @@ static int rcu_torture_barrier_cbs(void *arg) + * The above smp_load_acquire() ensures barrier_phase load + * is ordered before the following ->call(). + */ +- if (smp_call_function_single(myid, rcu_torture_barrier1cb, +- &rcu, 1)) { +- // IPI failed, so use direct call from current CPU. ++ if (smp_call_on_cpu(myid, rcu_torture_barrier1cb, &rcu, 1)) + cur_ops->call(&rcu, rcu_torture_barrier_cbf); +- } ++ + if (atomic_dec_and_test(&barrier_cbs_count)) + wake_up(&barrier_wq); + } while (!torture_must_stop()); +diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c +index 126380696f9c5..8671c37f0d7a5 100644 +--- a/kernel/sys_ni.c ++++ b/kernel/sys_ni.c +@@ -46,8 +46,8 @@ COND_SYSCALL(io_getevents_time32); + COND_SYSCALL(io_getevents); + COND_SYSCALL(io_pgetevents_time32); + COND_SYSCALL(io_pgetevents); +-COND_SYSCALL_COMPAT(io_pgetevents_time32); + COND_SYSCALL_COMPAT(io_pgetevents); ++COND_SYSCALL_COMPAT(io_pgetevents_time64); + COND_SYSCALL(io_uring_setup); + COND_SYSCALL(io_uring_enter); + COND_SYSCALL(io_uring_register); +diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c +index e9138cd7a0f52..7f2b17fc8ce40 100644 +--- a/kernel/time/tick-common.c ++++ b/kernel/time/tick-common.c +@@ -179,26 +179,6 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast) + } + } + +-#ifdef CONFIG_NO_HZ_FULL +-static void giveup_do_timer(void *info) +-{ +- int cpu = *(unsigned int *)info; +- +- WARN_ON(tick_do_timer_cpu != smp_processor_id()); +- +- tick_do_timer_cpu = cpu; +-} +- +-static void tick_take_do_timer_from_boot(void) +-{ +- int cpu = smp_processor_id(); +- int from = tick_do_timer_boot_cpu; +- +- if (from >= 0 && from != cpu) +- smp_call_function_single(from, giveup_do_timer, &cpu, 1); +-} +-#endif +- + /* + * Setup the tick device + */ +@@ -222,19 +202,25 @@ static void tick_setup_device(struct tick_device *td, + tick_next_period = ktime_get(); + #ifdef CONFIG_NO_HZ_FULL + /* +- * The boot CPU may be nohz_full, in which case set +- * tick_do_timer_boot_cpu so the first housekeeping +- * secondary that comes up will take do_timer from +- * us. ++ * The boot CPU may be nohz_full, in which case the ++ * first housekeeping secondary will take do_timer() ++ * from it. + */ + if (tick_nohz_full_cpu(cpu)) + tick_do_timer_boot_cpu = cpu; + +- } else if (tick_do_timer_boot_cpu != -1 && +- !tick_nohz_full_cpu(cpu)) { +- tick_take_do_timer_from_boot(); ++ } else if (tick_do_timer_boot_cpu != -1 && !tick_nohz_full_cpu(cpu)) { + tick_do_timer_boot_cpu = -1; +- WARN_ON(tick_do_timer_cpu != cpu); ++ /* ++ * The boot CPU will stay in periodic (NOHZ disabled) ++ * mode until clocksource_done_booting() called after ++ * smp_init() selects a high resolution clocksource and ++ * timekeeping_notify() kicks the NOHZ stuff alive. ++ * ++ * So this WRITE_ONCE can only race with the READ_ONCE ++ * check in tick_periodic() but this race is harmless. ++ */ ++ WRITE_ONCE(tick_do_timer_cpu, cpu); + #endif + } + +diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig +index 4265d125d50f3..193ca0cf5d122 100644 +--- a/kernel/trace/Kconfig ++++ b/kernel/trace/Kconfig +@@ -991,7 +991,7 @@ config PREEMPTIRQ_DELAY_TEST + + config SYNTH_EVENT_GEN_TEST + tristate "Test module for in-kernel synthetic event generation" +- depends on SYNTH_EVENTS ++ depends on SYNTH_EVENTS && m + help + This option creates a test module to check the base + functionality of in-kernel synthetic event definition and +@@ -1004,7 +1004,7 @@ config SYNTH_EVENT_GEN_TEST + + config KPROBE_EVENT_GEN_TEST + tristate "Test module for in-kernel kprobe event generation" +- depends on KPROBE_EVENTS ++ depends on KPROBE_EVENTS && m + help + This option creates a test module to check the base + functionality of in-kernel kprobe event definition. +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 157a1d2d9802f..780f1c0563f58 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -1566,26 +1566,43 @@ static struct dyn_ftrace *lookup_rec(unsigned long start, unsigned long end) + unsigned long ftrace_location_range(unsigned long start, unsigned long end) + { + struct dyn_ftrace *rec; ++ unsigned long ip = 0; + ++ rcu_read_lock(); + rec = lookup_rec(start, end); + if (rec) +- return rec->ip; ++ ip = rec->ip; ++ rcu_read_unlock(); + +- return 0; ++ return ip; + } + + /** +- * ftrace_location - return true if the ip giving is a traced location ++ * ftrace_location - return the ftrace location + * @ip: the instruction pointer to check + * +- * Returns rec->ip if @ip given is a pointer to a ftrace location. +- * That is, the instruction that is either a NOP or call to +- * the function tracer. It checks the ftrace internal tables to +- * determine if the address belongs or not. ++ * If @ip matches the ftrace location, return @ip. ++ * If @ip matches sym+0, return sym's ftrace location. ++ * Otherwise, return 0. + */ + unsigned long ftrace_location(unsigned long ip) + { +- return ftrace_location_range(ip, ip); ++ unsigned long loc; ++ unsigned long offset; ++ unsigned long size; ++ ++ loc = ftrace_location_range(ip, ip); ++ if (!loc) { ++ if (!kallsyms_lookup_size_offset(ip, &size, &offset)) ++ goto out; ++ ++ /* map sym+0 to __fentry__ */ ++ if (!offset) ++ loc = ftrace_location_range(ip, ip + size - 1); ++ } ++ ++out: ++ return loc; + } + + /** +@@ -4942,7 +4959,8 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) + { + struct ftrace_func_entry *entry; + +- if (!ftrace_location(ip)) ++ ip = ftrace_location(ip); ++ if (!ip) + return -EINVAL; + + if (remove) { +@@ -5090,11 +5108,16 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr) + struct ftrace_func_entry *entry; + struct ftrace_hash *free_hash = NULL; + struct dyn_ftrace *rec; +- int ret = -EBUSY; ++ int ret = -ENODEV; + + mutex_lock(&direct_mutex); + ++ ip = ftrace_location(ip); ++ if (!ip) ++ goto out_unlock; ++ + /* See if there's a direct function at @ip already */ ++ ret = -EBUSY; + if (ftrace_find_rec_direct(ip)) + goto out_unlock; + +@@ -5223,6 +5246,10 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr) + + mutex_lock(&direct_mutex); + ++ ip = ftrace_location(ip); ++ if (!ip) ++ goto out_unlock; ++ + entry = find_direct_entry(&ip, NULL); + if (!entry) + goto out_unlock; +@@ -5354,6 +5381,11 @@ int modify_ftrace_direct(unsigned long ip, + mutex_lock(&direct_mutex); + + mutex_lock(&ftrace_lock); ++ ++ ip = ftrace_location(ip); ++ if (!ip) ++ goto out_unlock; ++ + entry = find_direct_entry(&ip, &rec); + if (!entry) + goto out_unlock; +@@ -6293,6 +6325,8 @@ static int ftrace_process_locs(struct module *mod, + /* We should have used all pages unless we skipped some */ + if (pg_unuse) { + WARN_ON(!skipped); ++ /* Need to synchronize with ftrace_location_range() */ ++ synchronize_rcu(); + ftrace_free_pages(pg_unuse); + } + return ret; +@@ -6475,6 +6509,9 @@ void ftrace_release_mod(struct module *mod) + out_unlock: + mutex_unlock(&ftrace_lock); + ++ /* Need to synchronize with ftrace_location_range() */ ++ if (tmp_page) ++ synchronize_rcu(); + for (pg = tmp_page; pg; pg = tmp_page) { + + /* Needs to be called outside of ftrace_lock */ +@@ -6797,6 +6834,7 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) + unsigned long start = (unsigned long)(start_ptr); + unsigned long end = (unsigned long)(end_ptr); + struct ftrace_page **last_pg = &ftrace_pages_start; ++ struct ftrace_page *tmp_page = NULL; + struct ftrace_page *pg; + struct dyn_ftrace *rec; + struct dyn_ftrace key; +@@ -6840,12 +6878,8 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) + ftrace_update_tot_cnt--; + if (!pg->index) { + *last_pg = pg->next; +- if (pg->records) { +- free_pages((unsigned long)pg->records, pg->order); +- ftrace_number_of_pages -= 1 << pg->order; +- } +- ftrace_number_of_groups--; +- kfree(pg); ++ pg->next = tmp_page; ++ tmp_page = pg; + pg = container_of(last_pg, struct ftrace_page, next); + if (!(*last_pg)) + ftrace_pages = pg; +@@ -6862,6 +6896,11 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) + clear_func_from_hashes(func); + kfree(func); + } ++ /* Need to synchronize with ftrace_location_range() */ ++ if (tmp_page) { ++ synchronize_rcu(); ++ ftrace_free_pages(tmp_page); ++ } + } + + void __init ftrace_free_init_mem(void) +diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c +index 8c4ffd0761624..cb0871fbdb07f 100644 +--- a/kernel/trace/preemptirq_delay_test.c ++++ b/kernel/trace/preemptirq_delay_test.c +@@ -215,4 +215,5 @@ static void __exit preemptirq_delay_exit(void) + + module_init(preemptirq_delay_init) + module_exit(preemptirq_delay_exit) ++MODULE_DESCRIPTION("Preempt / IRQ disable delay thread to test latency tracers"); + MODULE_LICENSE("GPL v2"); +diff --git a/mm/cma.c b/mm/cma.c +index 26967c70e9c73..88fbd4f8124d3 100644 +--- a/mm/cma.c ++++ b/mm/cma.c +@@ -169,7 +169,6 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, + struct cma **res_cma) + { + struct cma *cma; +- phys_addr_t alignment; + + /* Sanity checks */ + if (cma_area_count == ARRAY_SIZE(cma_areas)) { +@@ -181,14 +180,7 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, + return -EINVAL; + + /* ensure minimal alignment required by mm core */ +- alignment = PAGE_SIZE << +- max_t(unsigned long, MAX_ORDER - 1, pageblock_order); +- +- /* alignment should be aligned with order_per_bit */ +- if (!IS_ALIGNED(alignment >> PAGE_SHIFT, 1 << order_per_bit)) +- return -EINVAL; +- +- if (ALIGN(base, alignment) != base || ALIGN(size, alignment) != size) ++ if (!IS_ALIGNED(base | size, CMA_MIN_ALIGNMENT_BYTES)) + return -EINVAL; + + /* +@@ -263,14 +255,8 @@ int __init cma_declare_contiguous_nid(phys_addr_t base, + if (alignment && !is_power_of_2(alignment)) + return -EINVAL; + +- /* +- * Sanitise input arguments. +- * Pages both ends in CMA area could be merged into adjacent unmovable +- * migratetype page by page allocator's buddy algorithm. In the case, +- * you couldn't get a contiguous memory, which is not what we want. +- */ +- alignment = max(alignment, (phys_addr_t)PAGE_SIZE << +- max_t(unsigned long, MAX_ORDER - 1, pageblock_order)); ++ /* Sanitise input arguments. */ ++ alignment = max_t(phys_addr_t, alignment, CMA_MIN_ALIGNMENT_BYTES); + if (fixed && base & (alignment - 1)) { + ret = -EINVAL; + pr_err("Region at %pa must be aligned to %pa bytes\n", +diff --git a/mm/memory-failure.c b/mm/memory-failure.c +index 1f23baa98ee9b..8be244f6c3202 100644 +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -2051,6 +2051,13 @@ int unpoison_memory(unsigned long pfn) + + mutex_lock(&mf_mutex); + ++ if (is_huge_zero_page(page)) { ++ unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n", ++ pfn, &unpoison_rs); ++ ret = -EOPNOTSUPP; ++ goto unlock_mutex; ++ } ++ + if (!PageHWPoison(p)) { + unpoison_pr_info("Unpoison: Page was already unpoisoned %#lx\n", + pfn, &unpoison_rs); +diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c +index aadc653ca1d80..49ce22278fcbc 100644 +--- a/net/batman-adv/originator.c ++++ b/net/batman-adv/originator.c +@@ -11,6 +11,7 @@ + #include <linux/errno.h> + #include <linux/etherdevice.h> + #include <linux/gfp.h> ++#include <linux/if_vlan.h> + #include <linux/jiffies.h> + #include <linux/kernel.h> + #include <linux/kref.h> +@@ -131,6 +132,29 @@ batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node, + return vlan; + } + ++/** ++ * batadv_vlan_id_valid() - check if vlan id is in valid batman-adv encoding ++ * @vid: the VLAN identifier ++ * ++ * Return: true when either no vlan is set or if VLAN is in correct range, ++ * false otherwise ++ */ ++static bool batadv_vlan_id_valid(unsigned short vid) ++{ ++ unsigned short non_vlan = vid & ~(BATADV_VLAN_HAS_TAG | VLAN_VID_MASK); ++ ++ if (vid == 0) ++ return true; ++ ++ if (!(vid & BATADV_VLAN_HAS_TAG)) ++ return false; ++ ++ if (non_vlan) ++ return false; ++ ++ return true; ++} ++ + /** + * batadv_orig_node_vlan_new() - search and possibly create an orig_node_vlan + * object +@@ -149,6 +173,9 @@ batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node, + { + struct batadv_orig_node_vlan *vlan; + ++ if (!batadv_vlan_id_valid(vid)) ++ return NULL; ++ + spin_lock_bh(&orig_node->vlan_list_lock); + + /* first look if an object for this vid already exists */ +@@ -1238,6 +1265,8 @@ void batadv_purge_orig_ref(struct batadv_priv *bat_priv) + /* for all origins... */ + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; ++ if (hlist_empty(head)) ++ continue; + list_lock = &hash->list_locks[i]; + + spin_lock_bh(list_lock); +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 900b352975856..43a21a90619d9 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -5617,13 +5617,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, + + memset(&rsp, 0, sizeof(rsp)); + +- if (max > hcon->le_conn_max_interval) { +- BT_DBG("requested connection interval exceeds current bounds."); +- err = -EINVAL; +- } else { +- err = hci_check_conn_params(min, max, latency, to_multiplier); +- } +- ++ err = hci_check_conn_params(min, max, latency, to_multiplier); + if (err) + rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); + else +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 11d254ce3581c..a0d75c33b5d6a 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -326,10 +326,16 @@ static void + __bpf_prog_test_run_raw_tp(void *data) + { + struct bpf_raw_tp_test_run_info *info = data; ++ struct bpf_trace_run_ctx run_ctx = {}; ++ struct bpf_run_ctx *old_run_ctx; ++ ++ old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); + + rcu_read_lock(); + info->retval = bpf_prog_run(info->prog, info->ctx); + rcu_read_unlock(); ++ ++ bpf_reset_run_ctx(old_run_ctx); + } + + int bpf_prog_test_run_raw_tp(struct bpf_prog *prog, +diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c +index 0ef399abd0975..cc03ea2f897fd 100644 +--- a/net/can/j1939/main.c ++++ b/net/can/j1939/main.c +@@ -30,10 +30,6 @@ MODULE_ALIAS("can-proto-" __stringify(CAN_J1939)); + /* CAN_HDR: #bytes before can_frame data part */ + #define J1939_CAN_HDR (offsetof(struct can_frame, data)) + +-/* CAN_FTR: #bytes beyond data part */ +-#define J1939_CAN_FTR (sizeof(struct can_frame) - J1939_CAN_HDR - \ +- sizeof(((struct can_frame *)0)->data)) +- + /* lowest layer */ + static void j1939_can_recv(struct sk_buff *iskb, void *data) + { +@@ -338,7 +334,7 @@ int j1939_send_one(struct j1939_priv *priv, struct sk_buff *skb) + memset(cf, 0, J1939_CAN_HDR); + + /* make it a full can frame again */ +- skb_put(skb, J1939_CAN_FTR + (8 - dlc)); ++ skb_put_zero(skb, 8 - dlc); + + canid = CAN_EFF_FLAG | + (skcb->priority << 26) | +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index bd8ec24338324..25e7339834670 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1593,8 +1593,8 @@ j1939_session *j1939_xtp_rx_rts_session_new(struct j1939_priv *priv, + struct j1939_sk_buff_cb skcb = *j1939_skb_to_cb(skb); + struct j1939_session *session; + const u8 *dat; ++ int len, ret; + pgn_t pgn; +- int len; + + netdev_dbg(priv->ndev, "%s\n", __func__); + +@@ -1653,7 +1653,22 @@ j1939_session *j1939_xtp_rx_rts_session_new(struct j1939_priv *priv, + session->tskey = priv->rx_tskey++; + j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_RTS); + +- WARN_ON_ONCE(j1939_session_activate(session)); ++ ret = j1939_session_activate(session); ++ if (ret) { ++ /* Entering this scope indicates an issue with the J1939 bus. ++ * Possible scenarios include: ++ * - A time lapse occurred, and a new session was initiated ++ * due to another packet being sent correctly. This could ++ * have been caused by too long interrupt, debugger, or being ++ * out-scheduled by another task. ++ * - The bus is receiving numerous erroneous packets, either ++ * from a malfunctioning device or during a test scenario. ++ */ ++ netdev_alert(priv->ndev, "%s: 0x%p: concurrent session with same addr (%02x %02x) is already active.\n", ++ __func__, session, skcb.addr.sa, skcb.addr.da); ++ j1939_session_put(session); ++ return NULL; ++ } + + return session; + } +@@ -1681,6 +1696,8 @@ static int j1939_xtp_rx_rts_session_active(struct j1939_session *session, + + j1939_session_timers_cancel(session); + j1939_session_cancel(session, J1939_XTP_ABORT_BUSY); ++ if (session->transmission) ++ j1939_session_deactivate_activate_next(session); + + return -EBUSY; + } +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index 937d74aeef547..d9a6cdc48cb2c 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -73,7 +73,7 @@ struct net_dm_hw_entries { + }; + + struct per_cpu_dm_data { +- spinlock_t lock; /* Protects 'skb', 'hw_entries' and ++ raw_spinlock_t lock; /* Protects 'skb', 'hw_entries' and + * 'send_timer' + */ + union { +@@ -169,9 +169,9 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) + err: + mod_timer(&data->send_timer, jiffies + HZ / 10); + out: +- spin_lock_irqsave(&data->lock, flags); ++ raw_spin_lock_irqsave(&data->lock, flags); + swap(data->skb, skb); +- spin_unlock_irqrestore(&data->lock, flags); ++ raw_spin_unlock_irqrestore(&data->lock, flags); + + if (skb) { + struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data; +@@ -226,7 +226,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location) + + local_irq_save(flags); + data = this_cpu_ptr(&dm_cpu_data); +- spin_lock(&data->lock); ++ raw_spin_lock(&data->lock); + dskb = data->skb; + + if (!dskb) +@@ -260,7 +260,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location) + } + + out: +- spin_unlock_irqrestore(&data->lock, flags); ++ raw_spin_unlock_irqrestore(&data->lock, flags); + } + + static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, +@@ -321,9 +321,9 @@ net_dm_hw_reset_per_cpu_data(struct per_cpu_dm_data *hw_data) + mod_timer(&hw_data->send_timer, jiffies + HZ / 10); + } + +- spin_lock_irqsave(&hw_data->lock, flags); ++ raw_spin_lock_irqsave(&hw_data->lock, flags); + swap(hw_data->hw_entries, hw_entries); +- spin_unlock_irqrestore(&hw_data->lock, flags); ++ raw_spin_unlock_irqrestore(&hw_data->lock, flags); + + return hw_entries; + } +@@ -455,7 +455,7 @@ net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink, + return; + + hw_data = this_cpu_ptr(&dm_hw_cpu_data); +- spin_lock_irqsave(&hw_data->lock, flags); ++ raw_spin_lock_irqsave(&hw_data->lock, flags); + hw_entries = hw_data->hw_entries; + + if (!hw_entries) +@@ -484,7 +484,7 @@ net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink, + } + + out: +- spin_unlock_irqrestore(&hw_data->lock, flags); ++ raw_spin_unlock_irqrestore(&hw_data->lock, flags); + } + + static const struct net_dm_alert_ops net_dm_alert_summary_ops = { +@@ -1671,7 +1671,7 @@ static struct notifier_block dropmon_net_notifier = { + + static void __net_dm_cpu_data_init(struct per_cpu_dm_data *data) + { +- spin_lock_init(&data->lock); ++ raw_spin_lock_init(&data->lock); + skb_queue_head_init(&data->drop_queue); + u64_stats_init(&data->stats.syncp); + } +diff --git a/net/core/filter.c b/net/core/filter.c +index 47eb1bd47aa6e..a873c8fd51b67 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -79,6 +79,9 @@ + #include <net/tls.h> + #include <net/xdp.h> + ++/* Keep the struct bpf_fib_lookup small so that it fits into a cacheline */ ++static_assert(sizeof(struct bpf_fib_lookup) == 64, "struct bpf_fib_lookup size check"); ++ + static const struct bpf_func_proto * + bpf_sk_base_func_proto(enum bpf_func_id func_id); + +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index a209db33fa5f7..3addbce20f8ed 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -651,11 +651,16 @@ EXPORT_SYMBOL_GPL(__put_net); + * get_net_ns - increment the refcount of the network namespace + * @ns: common namespace (net) + * +- * Returns the net's common namespace. ++ * Returns the net's common namespace or ERR_PTR() if ref is zero. + */ + struct ns_common *get_net_ns(struct ns_common *ns) + { +- return &get_net(container_of(ns, struct net, ns))->ns; ++ struct net *net; ++ ++ net = maybe_get_net(container_of(ns, struct net, ns)); ++ if (net) ++ return &net->ns; ++ return ERR_PTR(-EINVAL); + } + EXPORT_SYMBOL_GPL(get_net_ns); + +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index 47a86da6ab980..2a9d95368d5a2 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -316,7 +316,7 @@ static int netpoll_owner_active(struct net_device *dev) + struct napi_struct *napi; + + list_for_each_entry_rcu(napi, &dev->napi_list, dev_list) { +- if (napi->poll_owner == smp_processor_id()) ++ if (READ_ONCE(napi->poll_owner) == smp_processor_id()) + return 1; + } + return 0; +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 4ec8cfd357eba..17073429cc365 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -2071,6 +2071,30 @@ void *skb_pull(struct sk_buff *skb, unsigned int len) + } + EXPORT_SYMBOL(skb_pull); + ++/** ++ * skb_pull_data - remove data from the start of a buffer returning its ++ * original position. ++ * @skb: buffer to use ++ * @len: amount of data to remove ++ * ++ * This function removes data from the start of a buffer, returning ++ * the memory to the headroom. A pointer to the original data in the buffer ++ * is returned after checking if there is enough data to pull. Once the ++ * data has been pulled future pushes will overwrite the old data. ++ */ ++void *skb_pull_data(struct sk_buff *skb, size_t len) ++{ ++ void *data = skb->data; ++ ++ if (skb->len < len) ++ return NULL; ++ ++ skb_pull(skb, len); ++ ++ return data; ++} ++EXPORT_SYMBOL(skb_pull_data); ++ + /** + * skb_trim - remove end from a buffer + * @skb: buffer to alter +diff --git a/net/core/sock.c b/net/core/sock.c +index 62e376f09f957..046943b6efb1f 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -3413,7 +3413,8 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname, + { + struct sock *sk = sock->sk; + +- return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ return READ_ONCE(sk->sk_prot)->getsockopt(sk, level, optname, optval, optlen); + } + EXPORT_SYMBOL(sock_common_getsockopt); + +@@ -3440,7 +3441,8 @@ int sock_common_setsockopt(struct socket *sock, int level, int optname, + { + struct sock *sk = sock->sk; + +- return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen); ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ return READ_ONCE(sk->sk_prot)->setsockopt(sk, level, optname, optval, optlen); + } + EXPORT_SYMBOL(sock_common_setsockopt); + +@@ -3459,6 +3461,9 @@ void sk_common_release(struct sock *sk) + + sk->sk_prot->unhash(sk); + ++ if (sk->sk_socket) ++ sk->sk_socket->sk = NULL; ++ + /* + * In this point socket cannot receive new packets, but it is possible + * that some packets are in flight because some CPU runs receiver and +@@ -3497,19 +3502,8 @@ void sk_get_meminfo(const struct sock *sk, u32 *mem) + } + + #ifdef CONFIG_PROC_FS +-#define PROTO_INUSE_NR 64 /* should be enough for the first time */ +-struct prot_inuse { +- int val[PROTO_INUSE_NR]; +-}; +- + static DECLARE_BITMAP(proto_inuse_idx, PROTO_INUSE_NR); + +-void sock_prot_inuse_add(struct net *net, struct proto *prot, int val) +-{ +- __this_cpu_add(net->core.prot_inuse->val[prot->inuse_idx], val); +-} +-EXPORT_SYMBOL_GPL(sock_prot_inuse_add); +- + int sock_prot_inuse_get(struct net *net, struct proto *prot) + { + int cpu, idx = prot->inuse_idx; +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index 2ded250ac0d2b..0f9648c6bcf76 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -1566,19 +1566,23 @@ void sock_map_close(struct sock *sk, long timeout) + + lock_sock(sk); + rcu_read_lock(); +- psock = sk_psock_get(sk); +- if (unlikely(!psock)) { +- rcu_read_unlock(); +- release_sock(sk); +- saved_close = READ_ONCE(sk->sk_prot)->close; +- } else { ++ psock = sk_psock(sk); ++ if (likely(psock)) { + saved_close = psock->saved_close; + sock_map_remove_links(sk, psock); ++ psock = sk_psock_get(sk); ++ if (unlikely(!psock)) ++ goto no_psock; + rcu_read_unlock(); + sk_psock_stop(psock); + release_sock(sk); + cancel_delayed_work_sync(&psock->work); + sk_psock_put(sk, psock); ++ } else { ++ saved_close = READ_ONCE(sk->sk_prot)->close; ++no_psock: ++ rcu_read_unlock(); ++ release_sock(sk); + } + + /* Make sure we do not recurse. This is a bug. +diff --git a/net/core/xdp.c b/net/core/xdp.c +index a3e3d2538a3a8..e9a9694c4fdcc 100644 +--- a/net/core/xdp.c ++++ b/net/core/xdp.c +@@ -292,10 +292,8 @@ static struct xdp_mem_allocator *__xdp_reg_mem_model(struct xdp_mem_info *mem, + mutex_lock(&mem_id_lock); + ret = __mem_id_init_hash_table(); + mutex_unlock(&mem_id_lock); +- if (ret < 0) { +- WARN_ON(1); ++ if (ret < 0) + return ERR_PTR(ret); +- } + } + + xdp_alloc = kzalloc(sizeof(*xdp_alloc), gfp); +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index cab82344de9be..aaef9557d9425 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -649,8 +649,11 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) + if (dccp_v4_send_response(sk, req)) + goto drop_and_free; + +- inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); +- reqsk_put(req); ++ if (unlikely(!inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT))) ++ reqsk_free(req); ++ else ++ reqsk_put(req); ++ + return 0; + + drop_and_free: +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index 6f05e9d0d4287..f7c88b860d5d5 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -397,8 +397,11 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + if (dccp_v6_send_response(sk, req)) + goto drop_and_free; + +- inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); +- reqsk_put(req); ++ if (unlikely(!inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT))) ++ reqsk_free(req); ++ else ++ reqsk_put(req); ++ + return 0; + + drop_and_free: +diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c +index c33f46c9b6b34..586a6c4adf246 100644 +--- a/net/ieee802154/socket.c ++++ b/net/ieee802154/socket.c +@@ -174,8 +174,8 @@ static int raw_hash(struct sock *sk) + { + write_lock_bh(&raw_lock); + sk_add_node(sk, &raw_head); +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + write_unlock_bh(&raw_lock); ++ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + + return 0; + } +@@ -458,8 +458,8 @@ static int dgram_hash(struct sock *sk) + { + write_lock_bh(&dgram_lock); + sk_add_node(sk, &dgram_head); +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + write_unlock_bh(&dgram_lock); ++ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + + return 0; + } +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 487f75993bf4f..110ac22d3ce20 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -565,22 +565,27 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr, + int addr_len, int flags) + { + struct sock *sk = sock->sk; ++ const struct proto *prot; + int err; + + if (addr_len < sizeof(uaddr->sa_family)) + return -EINVAL; ++ ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ prot = READ_ONCE(sk->sk_prot); ++ + if (uaddr->sa_family == AF_UNSPEC) +- return sk->sk_prot->disconnect(sk, flags); ++ return prot->disconnect(sk, flags); + + if (BPF_CGROUP_PRE_CONNECT_ENABLED(sk)) { +- err = sk->sk_prot->pre_connect(sk, uaddr, addr_len); ++ err = prot->pre_connect(sk, uaddr, addr_len); + if (err) + return err; + } + + if (data_race(!inet_sk(sk)->inet_num) && inet_autobind(sk)) + return -EAGAIN; +- return sk->sk_prot->connect(sk, uaddr, addr_len); ++ return prot->connect(sk, uaddr, addr_len); + } + EXPORT_SYMBOL(inet_dgram_connect); + +@@ -743,10 +748,11 @@ EXPORT_SYMBOL(inet_stream_connect); + int inet_accept(struct socket *sock, struct socket *newsock, int flags, + bool kern) + { +- struct sock *sk1 = sock->sk; ++ struct sock *sk1 = sock->sk, *sk2; + int err = -EINVAL; +- struct sock *sk2 = sk1->sk_prot->accept(sk1, flags, &err, kern); + ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ sk2 = READ_ONCE(sk1->sk_prot)->accept(sk1, flags, &err, kern); + if (!sk2) + goto do_err; + +@@ -834,12 +840,15 @@ ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, + size_t size, int flags) + { + struct sock *sk = sock->sk; ++ const struct proto *prot; + + if (unlikely(inet_send_prepare(sk))) + return -EAGAIN; + +- if (sk->sk_prot->sendpage) +- return sk->sk_prot->sendpage(sk, page, offset, size, flags); ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ prot = READ_ONCE(sk->sk_prot); ++ if (prot->sendpage) ++ return prot->sendpage(sk, page, offset, size, flags); + return sock_no_sendpage(sock, page, offset, size, flags); + } + EXPORT_SYMBOL(inet_sendpage); +diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c +index 75ac145253445..016ebcbc8a633 100644 +--- a/net/ipv4/cipso_ipv4.c ++++ b/net/ipv4/cipso_ipv4.c +@@ -2015,12 +2015,16 @@ static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr) + * from there we can determine the new total option length */ + iter = 0; + optlen_new = 0; +- while (iter < opt->opt.optlen) +- if (opt->opt.__data[iter] != IPOPT_NOP) { ++ while (iter < opt->opt.optlen) { ++ if (opt->opt.__data[iter] == IPOPT_END) { ++ break; ++ } else if (opt->opt.__data[iter] == IPOPT_NOP) { ++ iter++; ++ } else { + iter += opt->opt.__data[iter + 1]; + optlen_new = iter; +- } else +- iter++; ++ } ++ } + hdr_delta = opt->opt.optlen; + opt->opt.optlen = (optlen_new + 3) & ~3; + hdr_delta -= opt->opt.optlen; +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index 27975a44d1f9d..75c2f7ffe5be4 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -889,12 +889,9 @@ static void reqsk_timer_handler(struct timer_list *t) + (!resend || + !inet_rtx_syn_ack(sk_listener, req) || + inet_rsk(req)->acked)) { +- unsigned long timeo; +- + if (req->num_timeout++ == 0) + atomic_dec(&queue->young); +- timeo = min(TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX); +- mod_timer(&req->rsk_timer, jiffies + timeo); ++ mod_timer(&req->rsk_timer, jiffies + reqsk_timeout(req, TCP_RTO_MAX)); + + if (!nreq) + return; +@@ -930,25 +927,34 @@ static void reqsk_timer_handler(struct timer_list *t) + inet_csk_reqsk_queue_drop_and_put(oreq->rsk_listener, oreq); + } + +-static void reqsk_queue_hash_req(struct request_sock *req, ++static bool reqsk_queue_hash_req(struct request_sock *req, + unsigned long timeout) + { ++ bool found_dup_sk = false; ++ ++ if (!inet_ehash_insert(req_to_sk(req), NULL, &found_dup_sk)) ++ return false; ++ ++ /* The timer needs to be setup after a successful insertion. */ + timer_setup(&req->rsk_timer, reqsk_timer_handler, TIMER_PINNED); + mod_timer(&req->rsk_timer, jiffies + timeout); + +- inet_ehash_insert(req_to_sk(req), NULL, NULL); + /* before letting lookups find us, make sure all req fields + * are committed to memory and refcnt initialized. + */ + smp_wmb(); + refcount_set(&req->rsk_refcnt, 2 + 1); ++ return true; + } + +-void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, ++bool inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, + unsigned long timeout) + { +- reqsk_queue_hash_req(req, timeout); ++ if (!reqsk_queue_hash_req(req, timeout)) ++ return false; ++ + inet_csk_reqsk_queue_added(sk); ++ return true; + } + EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add); + +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index f532589d26926..cc8e946768e43 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -99,8 +99,8 @@ int raw_hash_sk(struct sock *sk) + + write_lock_bh(&h->lock); + sk_add_node(sk, head); +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + write_unlock_bh(&h->lock); ++ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + + return 0; + } +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 9c7998377d6bd..c1602b36dee42 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2619,6 +2619,10 @@ void tcp_set_state(struct sock *sk, int state) + if (oldstate != TCP_ESTABLISHED) + TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); + break; ++ case TCP_CLOSE_WAIT: ++ if (oldstate == TCP_SYN_RECV) ++ TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); ++ break; + + case TCP_CLOSE: + if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED) +@@ -2630,7 +2634,7 @@ void tcp_set_state(struct sock *sk, int state) + inet_put_port(sk); + fallthrough; + default: +- if (oldstate == TCP_ESTABLISHED) ++ if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT) + TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); + } + +@@ -3704,8 +3708,9 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, + const struct inet_connection_sock *icsk = inet_csk(sk); + + if (level != SOL_TCP) +- return icsk->icsk_af_ops->setsockopt(sk, level, optname, +- optval, optlen); ++ /* Paired with WRITE_ONCE() in do_ipv6_setsockopt() and tcp_v6_connect() */ ++ return READ_ONCE(icsk->icsk_af_ops)->setsockopt(sk, level, optname, ++ optval, optlen); + return do_tcp_setsockopt(sk, level, optname, optval, optlen); + } + EXPORT_SYMBOL(tcp_setsockopt); +@@ -4303,8 +4308,9 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, + struct inet_connection_sock *icsk = inet_csk(sk); + + if (level != SOL_TCP) +- return icsk->icsk_af_ops->getsockopt(sk, level, optname, +- optval, optlen); ++ /* Paired with WRITE_ONCE() in do_ipv6_setsockopt() and tcp_v6_connect() */ ++ return READ_ONCE(icsk->icsk_af_ops)->getsockopt(sk, level, optname, ++ optval, optlen); + return do_tcp_getsockopt(sk, level, optname, optval, optlen); + } + EXPORT_SYMBOL(tcp_getsockopt); +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 52a9d7f96da43..eaa66f51c6a84 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -2747,13 +2747,37 @@ static void tcp_mtup_probe_success(struct sock *sk) + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMTUPSUCCESS); + } + ++/* Sometimes we deduce that packets have been dropped due to reasons other than ++ * congestion, like path MTU reductions or failed client TFO attempts. In these ++ * cases we call this function to retransmit as many packets as cwnd allows, ++ * without reducing cwnd. Given that retransmits will set retrans_stamp to a ++ * non-zero value (and may do so in a later calling context due to TSQ), we ++ * also enter CA_Loss so that we track when all retransmitted packets are ACKed ++ * and clear retrans_stamp when that happens (to ensure later recurring RTOs ++ * are using the correct retrans_stamp and don't declare ETIMEDOUT ++ * prematurely). ++ */ ++static void tcp_non_congestion_loss_retransmit(struct sock *sk) ++{ ++ const struct inet_connection_sock *icsk = inet_csk(sk); ++ struct tcp_sock *tp = tcp_sk(sk); ++ ++ if (icsk->icsk_ca_state != TCP_CA_Loss) { ++ tp->high_seq = tp->snd_nxt; ++ tp->snd_ssthresh = tcp_current_ssthresh(sk); ++ tp->prior_ssthresh = 0; ++ tp->undo_marker = 0; ++ tcp_set_ca_state(sk, TCP_CA_Loss); ++ } ++ tcp_xmit_retransmit_queue(sk); ++} ++ + /* Do a simple retransmit without using the backoff mechanisms in + * tcp_timer. This is used for path mtu discovery. + * The socket is already locked here. + */ + void tcp_simple_retransmit(struct sock *sk) + { +- const struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb; + int mss; +@@ -2793,14 +2817,7 @@ void tcp_simple_retransmit(struct sock *sk) + * in network, but units changed and effective + * cwnd/ssthresh really reduced now. + */ +- if (icsk->icsk_ca_state != TCP_CA_Loss) { +- tp->high_seq = tp->snd_nxt; +- tp->snd_ssthresh = tcp_current_ssthresh(sk); +- tp->prior_ssthresh = 0; +- tp->undo_marker = 0; +- tcp_set_ca_state(sk, TCP_CA_Loss); +- } +- tcp_xmit_retransmit_queue(sk); ++ tcp_non_congestion_loss_retransmit(sk); + } + EXPORT_SYMBOL(tcp_simple_retransmit); + +@@ -6103,7 +6120,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, + tp->fastopen_client_fail = TFO_DATA_NOT_ACKED; + skb_rbtree_walk_from(data) + tcp_mark_skb_lost(sk, data); +- tcp_xmit_retransmit_queue(sk); ++ tcp_non_congestion_loss_retransmit(sk); + NET_INC_STATS(sock_net(sk), + LINUX_MIB_TCPFASTOPENACTIVEFAIL); + return true; +@@ -6768,6 +6785,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops, + ireq->ireq_state = TCP_NEW_SYN_RECV; + write_pnet(&ireq->ireq_net, sock_net(sk_listener)); + ireq->ireq_family = sk_listener->sk_family; ++ req->timeout = TCP_TIMEOUT_INIT; + } + + return req; +@@ -6990,9 +7008,15 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, + sock_put(fastopen_sk); + } else { + tcp_rsk(req)->tfo_listener = false; +- if (!want_cookie) +- inet_csk_reqsk_queue_hash_add(sk, req, +- tcp_timeout_init((struct sock *)req)); ++ if (!want_cookie) { ++ req->timeout = tcp_timeout_init((struct sock *)req); ++ if (unlikely(!inet_csk_reqsk_queue_hash_add(sk, req, ++ req->timeout))) { ++ reqsk_free(req); ++ return 0; ++ } ++ ++ } + af_ops->send_synack(sk, dst, &fl, req, &foc, + !want_cookie ? TCP_SYNACK_NORMAL : + TCP_SYNACK_COOKIE, +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index 2606a5571116a..d84b71f70766b 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -593,7 +593,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, + * it can be estimated (approximately) + * from another data. + */ +- tmp_opt.ts_recent_stamp = ktime_get_seconds() - ((TCP_TIMEOUT_INIT/HZ)<<req->num_timeout); ++ tmp_opt.ts_recent_stamp = ktime_get_seconds() - reqsk_timeout(req, TCP_RTO_MAX) / HZ; + paws_reject = tcp_paws_reject(&tmp_opt, th->rst); + } + } +@@ -632,8 +632,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, + !inet_rtx_syn_ack(sk, req)) { + unsigned long expires = jiffies; + +- expires += min(TCP_TIMEOUT_INIT << req->num_timeout, +- TCP_RTO_MAX); ++ expires += reqsk_timeout(req, TCP_RTO_MAX); + if (!fastopen) + mod_timer_pending(&req->rsk_timer, expires); + else +diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c +index 8e0c33b683010..bbfa5d3a16f01 100644 +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -452,11 +452,14 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + { + struct sock *sk = sock->sk; + u32 flags = BIND_WITH_LOCK; ++ const struct proto *prot; + int err = 0; + ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ prot = READ_ONCE(sk->sk_prot); + /* If the socket has its own bind function then use it. */ +- if (sk->sk_prot->bind) +- return sk->sk_prot->bind(sk, uaddr, addr_len); ++ if (prot->bind) ++ return prot->bind(sk, uaddr, addr_len); + + if (addr_len < SIN6_LEN_RFC2133) + return -EINVAL; +@@ -572,6 +575,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + void __user *argp = (void __user *)arg; + struct sock *sk = sock->sk; + struct net *net = sock_net(sk); ++ const struct proto *prot; + + switch (cmd) { + case SIOCADDRT: +@@ -589,9 +593,11 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + case SIOCSIFDSTADDR: + return addrconf_set_dstaddr(net, argp); + default: +- if (!sk->sk_prot->ioctl) ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ prot = READ_ONCE(sk->sk_prot); ++ if (!prot->ioctl) + return -ENOIOCTLCMD; +- return sk->sk_prot->ioctl(sk, cmd, arg); ++ return prot->ioctl(sk, cmd, arg); + } + /*NOTREACHED*/ + return 0; +@@ -653,11 +659,14 @@ INDIRECT_CALLABLE_DECLARE(int udpv6_sendmsg(struct sock *, struct msghdr *, + int inet6_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) + { + struct sock *sk = sock->sk; ++ const struct proto *prot; + + if (unlikely(inet_send_prepare(sk))) + return -EAGAIN; + +- return INDIRECT_CALL_2(sk->sk_prot->sendmsg, tcp_sendmsg, udpv6_sendmsg, ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ prot = READ_ONCE(sk->sk_prot); ++ return INDIRECT_CALL_2(prot->sendmsg, tcp_sendmsg, udpv6_sendmsg, + sk, msg, size); + } + +@@ -667,13 +676,16 @@ int inet6_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, + int flags) + { + struct sock *sk = sock->sk; ++ const struct proto *prot; + int addr_len = 0; + int err; + + if (likely(!(flags & MSG_ERRQUEUE))) + sock_rps_record_flow(sk); + +- err = INDIRECT_CALL_2(sk->sk_prot->recvmsg, tcp_recvmsg, udpv6_recvmsg, ++ /* IPV6_ADDRFORM can change sk->sk_prot under us. */ ++ prot = READ_ONCE(sk->sk_prot); ++ err = INDIRECT_CALL_2(prot->recvmsg, tcp_recvmsg, udpv6_recvmsg, + sk, msg, size, flags & MSG_DONTWAIT, + flags & ~MSG_DONTWAIT, &addr_len); + if (err >= 0) +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index c0ff5ee490e7b..7d09193c14445 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -961,6 +961,7 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh, + if (!fib6_nh->rt6i_pcpu) + return; + ++ rcu_read_lock(); + /* release the reference to this fib entry from + * all of its cached pcpu routes + */ +@@ -969,7 +970,9 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh, + struct rt6_info *pcpu_rt; + + ppcpu_rt = per_cpu_ptr(fib6_nh->rt6i_pcpu, cpu); +- pcpu_rt = *ppcpu_rt; ++ ++ /* Paired with xchg() in rt6_get_pcpu_route() */ ++ pcpu_rt = READ_ONCE(*ppcpu_rt); + + /* only dropping the 'from' reference if the cached route + * is using 'match'. The cached pcpu_rt->from only changes +@@ -983,6 +986,7 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh, + fib6_info_release(from); + } + } ++ rcu_read_unlock(); + } + + struct fib6_nh_pcpu_arg { +diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c +index 197e12d5607f1..41e8b02c12c83 100644 +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -471,12 +471,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, + + if (sk->sk_protocol == IPPROTO_TCP) { + struct inet_connection_sock *icsk = inet_csk(sk); +- local_bh_disable(); ++ + sock_prot_inuse_add(net, sk->sk_prot, -1); + sock_prot_inuse_add(net, &tcp_prot, 1); +- local_bh_enable(); +- sk->sk_prot = &tcp_prot; +- icsk->icsk_af_ops = &ipv4_specific; ++ ++ /* Paired with READ_ONCE(sk->sk_prot) in inet6_stream_ops */ ++ WRITE_ONCE(sk->sk_prot, &tcp_prot); ++ /* Paired with READ_ONCE() in tcp_(get|set)sockopt() */ ++ WRITE_ONCE(icsk->icsk_af_ops, &ipv4_specific); + sk->sk_socket->ops = &inet_stream_ops; + sk->sk_family = PF_INET; + tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); +@@ -485,11 +487,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, + + if (sk->sk_protocol == IPPROTO_UDPLITE) + prot = &udplite_prot; +- local_bh_disable(); ++ + sock_prot_inuse_add(net, sk->sk_prot, -1); + sock_prot_inuse_add(net, prot, 1); +- local_bh_enable(); +- sk->sk_prot = prot; ++ ++ /* Paired with READ_ONCE(sk->sk_prot) in inet6_dgram_ops */ ++ WRITE_ONCE(sk->sk_prot, prot); + sk->sk_socket->ops = &inet_dgram_ops; + sk->sk_family = PF_INET; + } +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 3bc3a30363e19..d937ee942a4fc 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -634,6 +634,8 @@ static void rt6_probe(struct fib6_nh *fib6_nh) + rcu_read_lock_bh(); + last_probe = READ_ONCE(fib6_nh->last_probe); + idev = __in6_dev_get(dev); ++ if (!idev) ++ goto out; + neigh = __ipv6_neigh_lookup_noref(dev, nh_gw); + if (neigh) { + if (neigh->nud_state & NUD_VALID) +@@ -1398,6 +1400,7 @@ static struct rt6_info *rt6_get_pcpu_route(const struct fib6_result *res) + struct rt6_info *prev, **p; + + p = this_cpu_ptr(res->nh->rt6i_pcpu); ++ /* Paired with READ_ONCE() in __fib6_drop_pcpu_from() */ + prev = xchg(p, NULL); + if (prev) { + dst_dev_put(&prev->dst); +@@ -3598,7 +3601,7 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, + if (!dev) + goto out; + +- if (idev->cnf.disable_ipv6) { ++ if (!idev || idev->cnf.disable_ipv6) { + NL_SET_ERR_MSG(extack, "IPv6 is disabled on nexthop device"); + err = -EACCES; + goto out; +@@ -6345,12 +6348,12 @@ static int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write, + if (!write) + return -EINVAL; + +- net = (struct net *)ctl->extra1; +- delay = net->ipv6.sysctl.flush_delay; + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) + return ret; + ++ net = (struct net *)ctl->extra1; ++ delay = net->ipv6.sysctl.flush_delay; + fib6_run_gc(delay <= 0 ? 0 : (unsigned long)delay, net, delay > 0); + return 0; + } +diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c +index f98bb719190be..135712649d25f 100644 +--- a/net/ipv6/seg6_iptunnel.c ++++ b/net/ipv6/seg6_iptunnel.c +@@ -332,9 +332,8 @@ static int seg6_input_core(struct net *net, struct sock *sk, + + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + +- preempt_disable(); ++ local_bh_disable(); + dst = dst_cache_get(&slwt->cache); +- preempt_enable(); + + skb_dst_drop(skb); + +@@ -342,14 +341,13 @@ static int seg6_input_core(struct net *net, struct sock *sk, + ip6_route_input(skb); + dst = skb_dst(skb); + if (!dst->error) { +- preempt_disable(); + dst_cache_set_ip6(&slwt->cache, dst, + &ipv6_hdr(skb)->saddr); +- preempt_enable(); + } + } else { + skb_dst_set(skb, dst); + } ++ local_bh_enable(); + + err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); + if (unlikely(err)) +@@ -405,9 +403,9 @@ static int seg6_output_core(struct net *net, struct sock *sk, + + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + +- preempt_disable(); ++ local_bh_disable(); + dst = dst_cache_get(&slwt->cache); +- preempt_enable(); ++ local_bh_enable(); + + if (unlikely(!dst)) { + struct ipv6hdr *hdr = ipv6_hdr(skb); +@@ -427,9 +425,9 @@ static int seg6_output_core(struct net *net, struct sock *sk, + goto drop; + } + +- preempt_disable(); ++ local_bh_disable(); + dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); +- preempt_enable(); ++ local_bh_enable(); + } + + skb_dst_drop(skb); +diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c +index 59454285d5c58..f15f3cb1d5ec2 100644 +--- a/net/ipv6/seg6_local.c ++++ b/net/ipv6/seg6_local.c +@@ -427,8 +427,8 @@ static int input_action_end_dx6(struct sk_buff *skb, + + if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) + return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, +- dev_net(skb->dev), NULL, skb, NULL, +- skb_dst(skb)->dev, input_action_end_dx6_finish); ++ dev_net(skb->dev), NULL, skb, skb->dev, ++ NULL, input_action_end_dx6_finish); + + return input_action_end_dx6_finish(dev_net(skb->dev), NULL, skb); + drop: +@@ -477,8 +477,8 @@ static int input_action_end_dx4(struct sk_buff *skb, + + if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) + return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, +- dev_net(skb->dev), NULL, skb, NULL, +- skb_dst(skb)->dev, input_action_end_dx4_finish); ++ dev_net(skb->dev), NULL, skb, skb->dev, ++ NULL, input_action_end_dx4_finish); + + return input_action_end_dx4_finish(dev_net(skb->dev), NULL, skb); + drop: +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index c18fdddbfa09d..78c7b0fb6ffe7 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -237,7 +237,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + sin.sin_port = usin->sin6_port; + sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; + +- icsk->icsk_af_ops = &ipv6_mapped; ++ /* Paired with READ_ONCE() in tcp_(get|set)sockopt() */ ++ WRITE_ONCE(icsk->icsk_af_ops, &ipv6_mapped); + if (sk_is_mptcp(sk)) + mptcpv6_handle_mapped(sk, true); + sk->sk_backlog_rcv = tcp_v4_do_rcv; +@@ -249,7 +250,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + + if (err) { + icsk->icsk_ext_hdr_len = exthdrlen; +- icsk->icsk_af_ops = &ipv6_specific; ++ /* Paired with READ_ONCE() in tcp_(get|set)sockopt() */ ++ WRITE_ONCE(icsk->icsk_af_ops, &ipv6_specific); + if (sk_is_mptcp(sk)) + mptcpv6_handle_mapped(sk, false); + sk->sk_backlog_rcv = tcp_v6_do_rcv; +@@ -1331,7 +1333,6 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * + */ + + newsk->sk_gso_type = SKB_GSO_TCPV6; +- ip6_dst_store(newsk, dst, NULL, NULL); + inet6_sk_rx_dst_set(newsk, skb); + + inet_sk(newsk)->pinet6 = tcp_inet6_sk(newsk); +@@ -1342,6 +1343,8 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * + + memcpy(newnp, np, sizeof(struct ipv6_pinfo)); + ++ ip6_dst_store(newsk, dst, NULL, NULL); ++ + newsk->sk_v6_daddr = ireq->ir_v6_rmt_addr; + newnp->saddr = ireq->ir_v6_loc_addr; + newsk->sk_v6_rcv_saddr = ireq->ir_v6_loc_addr; +diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c +index 4c3aa97f23faa..7c903e0e446cb 100644 +--- a/net/ipv6/xfrm6_policy.c ++++ b/net/ipv6/xfrm6_policy.c +@@ -57,12 +57,18 @@ static int xfrm6_get_saddr(struct net *net, int oif, + { + struct dst_entry *dst; + struct net_device *dev; ++ struct inet6_dev *idev; + + dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr, mark); + if (IS_ERR(dst)) + return -EHOSTUNREACH; + +- dev = ip6_dst_idev(dst)->dev; ++ idev = ip6_dst_idev(dst); ++ if (!idev) { ++ dst_release(dst); ++ return -EHOSTUNREACH; ++ } ++ dev = idev->dev; + ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6); + dst_release(dst); + return 0; +diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c +index 68edefed79f16..30fc78236050a 100644 +--- a/net/iucv/iucv.c ++++ b/net/iucv/iucv.c +@@ -519,7 +519,7 @@ static void iucv_setmask_mp(void) + */ + static void iucv_setmask_up(void) + { +- cpumask_t cpumask; ++ static cpumask_t cpumask; + int cpu; + + /* Disable all cpu but the first in cpu_irq_cpumask. */ +@@ -627,23 +627,33 @@ static int iucv_cpu_online(unsigned int cpu) + + static int iucv_cpu_down_prep(unsigned int cpu) + { +- cpumask_t cpumask; ++ cpumask_var_t cpumask; ++ int ret = 0; + + if (!iucv_path_table) + return 0; + +- cpumask_copy(&cpumask, &iucv_buffer_cpumask); +- cpumask_clear_cpu(cpu, &cpumask); +- if (cpumask_empty(&cpumask)) ++ if (!alloc_cpumask_var(&cpumask, GFP_KERNEL)) ++ return -ENOMEM; ++ ++ cpumask_copy(cpumask, &iucv_buffer_cpumask); ++ cpumask_clear_cpu(cpu, cpumask); ++ if (cpumask_empty(cpumask)) { + /* Can't offline last IUCV enabled cpu. */ +- return -EINVAL; ++ ret = -EINVAL; ++ goto __free_cpumask; ++ } + + iucv_retrieve_cpu(NULL); + if (!cpumask_empty(&iucv_irq_cpumask)) +- return 0; ++ goto __free_cpumask; ++ + smp_call_function_single(cpumask_first(&iucv_buffer_cpumask), + iucv_allow_cpu, NULL, 1); +- return 0; ++ ++__free_cpumask: ++ free_cpumask_var(cpumask); ++ return ret; + } + + /** +diff --git a/net/mac80211/he.c b/net/mac80211/he.c +index c05af7018f79f..c730ce5132cbc 100644 +--- a/net/mac80211/he.c ++++ b/net/mac80211/he.c +@@ -223,15 +223,21 @@ ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif, + + if (!he_spr_ie_elem) + return; ++ ++ he_obss_pd->sr_ctrl = he_spr_ie_elem->he_sr_control; + data = he_spr_ie_elem->optional; + + if (he_spr_ie_elem->he_sr_control & + IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT) +- data++; ++ he_obss_pd->non_srg_max_offset = *data++; ++ + if (he_spr_ie_elem->he_sr_control & + IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) { +- he_obss_pd->max_offset = *data++; + he_obss_pd->min_offset = *data++; ++ he_obss_pd->max_offset = *data++; ++ memcpy(he_obss_pd->bss_color_bitmap, data, 8); ++ data += 8; ++ memcpy(he_obss_pd->partial_bssid_bitmap, data, 8); + he_obss_pd->enable = true; + } + } +diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c +index 69d5e1ec6edef..e7b9dcf30adc9 100644 +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -723,10 +723,23 @@ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, + */ + void mesh_path_flush_pending(struct mesh_path *mpath) + { ++ struct ieee80211_sub_if_data *sdata = mpath->sdata; ++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; ++ struct mesh_preq_queue *preq, *tmp; + struct sk_buff *skb; + + while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL) + mesh_path_discard_frame(mpath->sdata, skb); ++ ++ spin_lock_bh(&ifmsh->mesh_preq_queue_lock); ++ list_for_each_entry_safe(preq, tmp, &ifmsh->preq_queue.list, list) { ++ if (ether_addr_equal(mpath->dst, preq->dst)) { ++ list_del(&preq->list); ++ kfree(preq); ++ --ifmsh->preq_queue_len; ++ } ++ } ++ spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); + } + + /** +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index f4deee1926e58..6d2b42cb3ad58 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -1339,7 +1339,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) + skb_queue_head_init(&pending); + + /* sync with ieee80211_tx_h_unicast_ps_buf */ +- spin_lock(&sta->ps_lock); ++ spin_lock_bh(&sta->ps_lock); + /* Send all buffered frames to the station */ + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + int count = skb_queue_len(&pending), tmp; +@@ -1368,7 +1368,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) + */ + clear_sta_flag(sta, WLAN_STA_PSPOLL); + clear_sta_flag(sta, WLAN_STA_UAPSD); +- spin_unlock(&sta->ps_lock); ++ spin_unlock_bh(&sta->ps_lock); + + atomic_dec(&ps->num_sta_ps); + +diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c +index 651f2c158637c..7b312aa03e6b5 100644 +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -608,6 +608,7 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) + struct mptcp_addr_info remote; + unsigned int subflows_max; + bool reset_port = false; ++ bool sf_created = false; + int i, nr; + + add_addr_accept_max = mptcp_pm_get_add_addr_accept_max(msk); +@@ -632,16 +633,19 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) + */ + nr = fill_local_addresses_vec(msk, addrs); + +- msk->pm.add_addr_accepted++; +- if (msk->pm.add_addr_accepted >= add_addr_accept_max || +- msk->pm.subflows >= subflows_max) +- WRITE_ONCE(msk->pm.accept_addr, false); +- + spin_unlock_bh(&msk->pm.lock); + for (i = 0; i < nr; i++) +- __mptcp_subflow_connect(sk, &addrs[i], &remote); ++ if (__mptcp_subflow_connect(sk, &addrs[i], &remote) == 0) ++ sf_created = true; + spin_lock_bh(&msk->pm.lock); + ++ if (sf_created) { ++ msk->pm.add_addr_accepted++; ++ if (msk->pm.add_addr_accepted >= add_addr_accept_max || ++ msk->pm.subflows >= subflows_max) ++ WRITE_ONCE(msk->pm.accept_addr, false); ++ } ++ + /* be sure to echo exactly the received address */ + if (reset_port) + remote.port = 0; +@@ -757,8 +761,11 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk, + + removed = true; + msk->pm.subflows--; +- __MPTCP_INC_STATS(sock_net(sk), rm_type); ++ if (rm_type == MPTCP_MIB_RMSUBFLOW) ++ __MPTCP_INC_STATS(sock_net(sk), rm_type); + } ++ if (rm_type == MPTCP_MIB_RMADDR) ++ __MPTCP_INC_STATS(sock_net(sk), rm_type); + if (!removed) + continue; + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 3c3f630f4943c..081c8d00472d4 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -3398,6 +3398,7 @@ static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr, + + WRITE_ONCE(msk->write_seq, subflow->idsn); + WRITE_ONCE(msk->snd_nxt, subflow->idsn); ++ WRITE_ONCE(msk->snd_una, subflow->idsn); + if (likely(!__mptcp_check_fallback(msk))) + MPTCP_INC_STATS(sock_net(sock->sk), MPTCP_MIB_MPCAPABLEACTIVE); + +diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h +index 374412ed780b6..ef0f8f73826f5 100644 +--- a/net/ncsi/internal.h ++++ b/net/ncsi/internal.h +@@ -325,6 +325,7 @@ struct ncsi_dev_priv { + spinlock_t lock; /* Protect the NCSI device */ + unsigned int package_probe_id;/* Current ID during probe */ + unsigned int package_num; /* Number of packages */ ++ unsigned int channel_probe_id;/* Current cahnnel ID during probe */ + struct list_head packages; /* List of packages */ + struct ncsi_channel *hot_channel; /* Channel was ever active */ + struct ncsi_request requests[256]; /* Request table */ +@@ -343,6 +344,7 @@ struct ncsi_dev_priv { + bool multi_package; /* Enable multiple packages */ + bool mlx_multi_host; /* Enable multi host Mellanox */ + u32 package_whitelist; /* Packages to configure */ ++ unsigned char channel_count; /* Num of channels to probe */ + }; + + struct ncsi_cmd_arg { +diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c +index 7121ce2a47c0b..30f5502530374 100644 +--- a/net/ncsi/ncsi-manage.c ++++ b/net/ncsi/ncsi-manage.c +@@ -510,17 +510,19 @@ static void ncsi_suspend_channel(struct ncsi_dev_priv *ndp) + + break; + case ncsi_dev_state_suspend_gls: +- ndp->pending_req_num = np->channel_num; ++ ndp->pending_req_num = 1; + + nca.type = NCSI_PKT_CMD_GLS; + nca.package = np->id; ++ nca.channel = ndp->channel_probe_id; ++ ret = ncsi_xmit_cmd(&nca); ++ if (ret) ++ goto error; ++ ndp->channel_probe_id++; + +- nd->state = ncsi_dev_state_suspend_dcnt; +- NCSI_FOR_EACH_CHANNEL(np, nc) { +- nca.channel = nc->id; +- ret = ncsi_xmit_cmd(&nca); +- if (ret) +- goto error; ++ if (ndp->channel_probe_id == ndp->channel_count) { ++ ndp->channel_probe_id = 0; ++ nd->state = ncsi_dev_state_suspend_dcnt; + } + + break; +@@ -689,8 +691,6 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc, + return 0; + } + +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY) +- + static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca) + { + unsigned char data[NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN]; +@@ -716,10 +716,6 @@ static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca) + return ret; + } + +-#endif +- +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC) +- + /* NCSI OEM Command APIs */ + static int ncsi_oem_gma_handler_bcm(struct ncsi_cmd_arg *nca) + { +@@ -856,8 +852,6 @@ static int ncsi_gma_handler(struct ncsi_cmd_arg *nca, unsigned int mf_id) + return nch->handler(nca); + } + +-#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */ +- + /* Determine if a given channel from the channel_queue should be used for Tx */ + static bool ncsi_channel_is_tx(struct ncsi_dev_priv *ndp, + struct ncsi_channel *nc) +@@ -1039,20 +1033,18 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) + goto error; + } + +- nd->state = ncsi_dev_state_config_oem_gma; ++ nd->state = IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC) ++ ? ncsi_dev_state_config_oem_gma ++ : ncsi_dev_state_config_clear_vids; + break; + case ncsi_dev_state_config_oem_gma: + nd->state = ncsi_dev_state_config_clear_vids; +- ret = -1; + +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC) + nca.type = NCSI_PKT_CMD_OEM; + nca.package = np->id; + nca.channel = nc->id; + ndp->pending_req_num = 1; + ret = ncsi_gma_handler(&nca, nc->version.mf_id); +-#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */ +- + if (ret < 0) + schedule_work(&ndp->work); + +@@ -1350,7 +1342,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + { + struct ncsi_dev *nd = &ndp->ndev; + struct ncsi_package *np; +- struct ncsi_channel *nc; + struct ncsi_cmd_arg nca; + unsigned char index; + int ret; +@@ -1404,7 +1395,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + + schedule_work(&ndp->work); + break; +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC) + case ncsi_dev_state_probe_mlx_gma: + ndp->pending_req_num = 1; + +@@ -1429,25 +1419,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + + nd->state = ncsi_dev_state_probe_cis; + break; +-#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */ +- case ncsi_dev_state_probe_cis: +- ndp->pending_req_num = NCSI_RESERVED_CHANNEL; +- +- /* Clear initial state */ +- nca.type = NCSI_PKT_CMD_CIS; +- nca.package = ndp->active_package->id; +- for (index = 0; index < NCSI_RESERVED_CHANNEL; index++) { +- nca.channel = index; +- ret = ncsi_xmit_cmd(&nca); +- if (ret) +- goto error; +- } +- +- nd->state = ncsi_dev_state_probe_gvi; +- if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)) +- nd->state = ncsi_dev_state_probe_keep_phy; +- break; +-#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY) + case ncsi_dev_state_probe_keep_phy: + ndp->pending_req_num = 1; + +@@ -1460,15 +1431,17 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + + nd->state = ncsi_dev_state_probe_gvi; + break; +-#endif /* CONFIG_NCSI_OEM_CMD_KEEP_PHY */ ++ case ncsi_dev_state_probe_cis: + case ncsi_dev_state_probe_gvi: + case ncsi_dev_state_probe_gc: + case ncsi_dev_state_probe_gls: + np = ndp->active_package; +- ndp->pending_req_num = np->channel_num; ++ ndp->pending_req_num = 1; + +- /* Retrieve version, capability or link status */ +- if (nd->state == ncsi_dev_state_probe_gvi) ++ /* Clear initial state Retrieve version, capability or link status */ ++ if (nd->state == ncsi_dev_state_probe_cis) ++ nca.type = NCSI_PKT_CMD_CIS; ++ else if (nd->state == ncsi_dev_state_probe_gvi) + nca.type = NCSI_PKT_CMD_GVI; + else if (nd->state == ncsi_dev_state_probe_gc) + nca.type = NCSI_PKT_CMD_GC; +@@ -1476,19 +1449,29 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + nca.type = NCSI_PKT_CMD_GLS; + + nca.package = np->id; +- NCSI_FOR_EACH_CHANNEL(np, nc) { +- nca.channel = nc->id; +- ret = ncsi_xmit_cmd(&nca); +- if (ret) +- goto error; +- } ++ nca.channel = ndp->channel_probe_id; ++ ++ ret = ncsi_xmit_cmd(&nca); ++ if (ret) ++ goto error; + +- if (nd->state == ncsi_dev_state_probe_gvi) ++ if (nd->state == ncsi_dev_state_probe_cis) { ++ nd->state = ncsi_dev_state_probe_gvi; ++ if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY) && ndp->channel_probe_id == 0) ++ nd->state = ncsi_dev_state_probe_keep_phy; ++ } else if (nd->state == ncsi_dev_state_probe_gvi) { + nd->state = ncsi_dev_state_probe_gc; +- else if (nd->state == ncsi_dev_state_probe_gc) ++ } else if (nd->state == ncsi_dev_state_probe_gc) { + nd->state = ncsi_dev_state_probe_gls; +- else ++ } else { ++ nd->state = ncsi_dev_state_probe_cis; ++ ndp->channel_probe_id++; ++ } ++ ++ if (ndp->channel_probe_id == ndp->channel_count) { ++ ndp->channel_probe_id = 0; + nd->state = ncsi_dev_state_probe_dp; ++ } + break; + case ncsi_dev_state_probe_dp: + ndp->pending_req_num = 1; +@@ -1789,6 +1772,7 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev, + ndp->requests[i].ndp = ndp; + timer_setup(&ndp->requests[i].timer, ncsi_request_timeout, 0); + } ++ ndp->channel_count = NCSI_RESERVED_CHANNEL; + + spin_lock_irqsave(&ncsi_dev_lock, flags); + list_add_tail_rcu(&ndp->node, &ncsi_dev_list); +@@ -1821,6 +1805,7 @@ int ncsi_start_dev(struct ncsi_dev *nd) + + if (!(ndp->flags & NCSI_DEV_PROBED)) { + ndp->package_probe_id = 0; ++ ndp->channel_probe_id = 0; + nd->state = ncsi_dev_state_probe; + schedule_work(&ndp->work); + return 0; +diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c +index 480e80e3c2836..f22d67cb04d37 100644 +--- a/net/ncsi/ncsi-rsp.c ++++ b/net/ncsi/ncsi-rsp.c +@@ -795,12 +795,13 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr) + struct ncsi_rsp_gc_pkt *rsp; + struct ncsi_dev_priv *ndp = nr->ndp; + struct ncsi_channel *nc; ++ struct ncsi_package *np; + size_t size; + + /* Find the channel */ + rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp); + ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, +- NULL, &nc); ++ &np, &nc); + if (!nc) + return -ENODEV; + +@@ -835,6 +836,7 @@ static int ncsi_rsp_handler_gc(struct ncsi_request *nr) + */ + nc->vlan_filter.bitmap = U64_MAX; + nc->vlan_filter.n_vids = rsp->vlan_cnt; ++ np->ndp->channel_count = rsp->channel_cnt; + + return 0; + } +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 01cedf416b10a..f2f6b7325c706 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -53,12 +53,13 @@ MODULE_DESCRIPTION("core IP set support"); + MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); + + /* When the nfnl mutex or ip_set_ref_lock is held: */ +-#define ip_set_dereference(p) \ +- rcu_dereference_protected(p, \ ++#define ip_set_dereference(inst) \ ++ rcu_dereference_protected((inst)->ip_set_list, \ + lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \ +- lockdep_is_held(&ip_set_ref_lock)) ++ lockdep_is_held(&ip_set_ref_lock) || \ ++ (inst)->is_deleted) + #define ip_set(inst, id) \ +- ip_set_dereference((inst)->ip_set_list)[id] ++ ip_set_dereference(inst)[id] + #define ip_set_ref_netlink(inst,id) \ + rcu_dereference_raw((inst)->ip_set_list)[id] + #define ip_set_dereference_nfnl(p) \ +@@ -1135,7 +1136,7 @@ static int ip_set_create(struct sk_buff *skb, const struct nfnl_info *info, + if (!list) + goto cleanup; + /* nfnl mutex is held, both lists are valid */ +- tmp = ip_set_dereference(inst->ip_set_list); ++ tmp = ip_set_dereference(inst); + memcpy(list, tmp, sizeof(struct ip_set *) * inst->ip_set_max); + rcu_assign_pointer(inst->ip_set_list, list); + /* Make sure all current packets have passed through */ +@@ -1174,23 +1175,50 @@ ip_set_setname_policy[IPSET_ATTR_CMD_MAX + 1] = { + .len = IPSET_MAXNAMELEN - 1 }, + }; + ++/* In order to return quickly when destroying a single set, it is split ++ * into two stages: ++ * - Cancel garbage collector ++ * - Destroy the set itself via call_rcu() ++ */ ++ + static void +-ip_set_destroy_set(struct ip_set *set) ++ip_set_destroy_set_rcu(struct rcu_head *head) + { +- pr_debug("set: %s\n", set->name); ++ struct ip_set *set = container_of(head, struct ip_set, rcu); + +- /* Must call it without holding any lock */ + set->variant->destroy(set); + module_put(set->type->me); + kfree(set); + } + + static void +-ip_set_destroy_set_rcu(struct rcu_head *head) ++_destroy_all_sets(struct ip_set_net *inst) + { +- struct ip_set *set = container_of(head, struct ip_set, rcu); ++ struct ip_set *set; ++ ip_set_id_t i; ++ bool need_wait = false; + +- ip_set_destroy_set(set); ++ /* First cancel gc's: set:list sets are flushed as well */ ++ for (i = 0; i < inst->ip_set_max; i++) { ++ set = ip_set(inst, i); ++ if (set) { ++ set->variant->cancel_gc(set); ++ if (set->type->features & IPSET_TYPE_NAME) ++ need_wait = true; ++ } ++ } ++ /* Must wait for flush to be really finished */ ++ if (need_wait) ++ rcu_barrier(); ++ for (i = 0; i < inst->ip_set_max; i++) { ++ set = ip_set(inst, i); ++ if (set) { ++ ip_set(inst, i) = NULL; ++ set->variant->destroy(set); ++ module_put(set->type->me); ++ kfree(set); ++ } ++ } + } + + static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, +@@ -1204,11 +1232,10 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, + if (unlikely(protocol_min_failed(attr))) + return -IPSET_ERR_PROTOCOL; + +- + /* Commands are serialized and references are + * protected by the ip_set_ref_lock. + * External systems (i.e. xt_set) must call +- * ip_set_put|get_nfnl_* functions, that way we ++ * ip_set_nfnl_get_* functions, that way we + * can safely check references here. + * + * list:set timer can only decrement the reference +@@ -1216,8 +1243,6 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, + * without holding the lock. + */ + if (!attr[IPSET_ATTR_SETNAME]) { +- /* Must wait for flush to be really finished in list:set */ +- rcu_barrier(); + read_lock_bh(&ip_set_ref_lock); + for (i = 0; i < inst->ip_set_max; i++) { + s = ip_set(inst, i); +@@ -1228,15 +1253,7 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, + } + inst->is_destroyed = true; + read_unlock_bh(&ip_set_ref_lock); +- for (i = 0; i < inst->ip_set_max; i++) { +- s = ip_set(inst, i); +- if (s) { +- ip_set(inst, i) = NULL; +- /* Must cancel garbage collectors */ +- s->variant->cancel_gc(s); +- ip_set_destroy_set(s); +- } +- } ++ _destroy_all_sets(inst); + /* Modified by ip_set_destroy() only, which is serialized */ + inst->is_destroyed = false; + } else { +@@ -1257,12 +1274,12 @@ static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info, + features = s->type->features; + ip_set(inst, i) = NULL; + read_unlock_bh(&ip_set_ref_lock); ++ /* Must cancel garbage collectors */ ++ s->variant->cancel_gc(s); + if (features & IPSET_TYPE_NAME) { + /* Must wait for flush to be really finished */ + rcu_barrier(); + } +- /* Must cancel garbage collectors */ +- s->variant->cancel_gc(s); + call_rcu(&s->rcu, ip_set_destroy_set_rcu); + } + return 0; +@@ -2365,30 +2382,25 @@ ip_set_net_init(struct net *net) + } + + static void __net_exit +-ip_set_net_exit(struct net *net) ++ip_set_net_pre_exit(struct net *net) + { + struct ip_set_net *inst = ip_set_pernet(net); + +- struct ip_set *set = NULL; +- ip_set_id_t i; +- + inst->is_deleted = true; /* flag for ip_set_nfnl_put */ ++} + +- nfnl_lock(NFNL_SUBSYS_IPSET); +- for (i = 0; i < inst->ip_set_max; i++) { +- set = ip_set(inst, i); +- if (set) { +- ip_set(inst, i) = NULL; +- set->variant->cancel_gc(set); +- ip_set_destroy_set(set); +- } +- } +- nfnl_unlock(NFNL_SUBSYS_IPSET); ++static void __net_exit ++ip_set_net_exit(struct net *net) ++{ ++ struct ip_set_net *inst = ip_set_pernet(net); ++ ++ _destroy_all_sets(inst); + kvfree(rcu_dereference_protected(inst->ip_set_list, 1)); + } + + static struct pernet_operations ip_set_net_ops = { + .init = ip_set_net_init, ++ .pre_exit = ip_set_net_pre_exit, + .exit = ip_set_net_exit, + .id = &ip_set_net_id, + .size = sizeof(struct ip_set_net), +diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c +index 6bc7019982b05..e839c356bcb56 100644 +--- a/net/netfilter/ipset/ip_set_list_set.c ++++ b/net/netfilter/ipset/ip_set_list_set.c +@@ -79,7 +79,7 @@ list_set_kadd(struct ip_set *set, const struct sk_buff *skb, + struct set_elem *e; + int ret; + +- list_for_each_entry(e, &map->members, list) { ++ list_for_each_entry_rcu(e, &map->members, list) { + if (SET_WITH_TIMEOUT(set) && + ip_set_timeout_expired(ext_timeout(e, set))) + continue; +@@ -99,7 +99,7 @@ list_set_kdel(struct ip_set *set, const struct sk_buff *skb, + struct set_elem *e; + int ret; + +- list_for_each_entry(e, &map->members, list) { ++ list_for_each_entry_rcu(e, &map->members, list) { + if (SET_WITH_TIMEOUT(set) && + ip_set_timeout_expired(ext_timeout(e, set))) + continue; +@@ -188,9 +188,10 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext, + struct list_set *map = set->data; + struct set_adt_elem *d = value; + struct set_elem *e, *next, *prev = NULL; +- int ret; ++ int ret = 0; + +- list_for_each_entry(e, &map->members, list) { ++ rcu_read_lock(); ++ list_for_each_entry_rcu(e, &map->members, list) { + if (SET_WITH_TIMEOUT(set) && + ip_set_timeout_expired(ext_timeout(e, set))) + continue; +@@ -201,6 +202,7 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext, + + if (d->before == 0) { + ret = 1; ++ goto out; + } else if (d->before > 0) { + next = list_next_entry(e, list); + ret = !list_is_last(&e->list, &map->members) && +@@ -208,9 +210,11 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext, + } else { + ret = prev && prev->id == d->refid; + } +- return ret; ++ goto out; + } +- return 0; ++out: ++ rcu_read_unlock(); ++ return ret; + } + + static void +@@ -239,7 +243,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext, + + /* Find where to add the new entry */ + n = prev = next = NULL; +- list_for_each_entry(e, &map->members, list) { ++ list_for_each_entry_rcu(e, &map->members, list) { + if (SET_WITH_TIMEOUT(set) && + ip_set_timeout_expired(ext_timeout(e, set))) + continue; +@@ -316,9 +320,9 @@ list_set_udel(struct ip_set *set, void *value, const struct ip_set_ext *ext, + { + struct list_set *map = set->data; + struct set_adt_elem *d = value; +- struct set_elem *e, *next, *prev = NULL; ++ struct set_elem *e, *n, *next, *prev = NULL; + +- list_for_each_entry(e, &map->members, list) { ++ list_for_each_entry_safe(e, n, &map->members, list) { + if (SET_WITH_TIMEOUT(set) && + ip_set_timeout_expired(ext_timeout(e, set))) + continue; +@@ -424,14 +428,8 @@ static void + list_set_destroy(struct ip_set *set) + { + struct list_set *map = set->data; +- struct set_elem *e, *n; + +- list_for_each_entry_safe(e, n, &map->members, list) { +- list_del(&e->list); +- ip_set_put_byindex(map->net, e->id); +- ip_set_ext_destroy(set, e); +- kfree(e); +- } ++ WARN_ON_ONCE(!list_empty(&map->members)); + kfree(map); + + set->data = NULL; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 3999b89793fce..506dc5c4cdccb 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -5328,8 +5328,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, + + if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) && + nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext), +- set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE, +- set->dlen) < 0) ++ nft_set_datatype(set), set->dlen) < 0) + goto nla_put_failure; + + if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPRESSIONS) && +@@ -10249,6 +10248,9 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, + + return 0; + default: ++ if (type != NFT_DATA_VALUE) ++ return -EINVAL; ++ + if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE) + return -EINVAL; + if (len == 0) +@@ -10257,8 +10259,6 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, + sizeof_field(struct nft_regs, data)) + return -ERANGE; + +- if (data != NULL && type != NFT_DATA_VALUE) +- return -EINVAL; + return 0; + } + } +diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c +index 9d18c5428d53c..b9df27c2718be 100644 +--- a/net/netfilter/nft_lookup.c ++++ b/net/netfilter/nft_lookup.c +@@ -136,7 +136,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx, + return -EINVAL; + + err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG], +- &priv->dreg, NULL, set->dtype, ++ &priv->dreg, NULL, ++ nft_set_datatype(set), + set->dlen); + if (err < 0) + return err; +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 216445dd44db9..18a38db2b27eb 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -711,9 +711,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol, + if (err < 0) + goto out_module; + +- local_bh_disable(); + sock_prot_inuse_add(net, &netlink_proto, 1); +- local_bh_enable(); + + nlk = nlk_sk(sock->sk); + nlk->module = module; +@@ -813,9 +811,7 @@ static int netlink_release(struct socket *sock) + netlink_table_ungrab(); + } + +- local_bh_disable(); + sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1); +- local_bh_enable(); + call_rcu(&nlk->rcu, deferred_put_nlk_sk); + return 0; + } +diff --git a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c +index 4e7c968cde2dc..5e3ca068f04e0 100644 +--- a/net/netrom/nr_timer.c ++++ b/net/netrom/nr_timer.c +@@ -121,7 +121,8 @@ static void nr_heartbeat_expiry(struct timer_list *t) + is accepted() it isn't 'dead' so doesn't get removed. */ + if (sock_flag(sk, SOCK_DESTROY) || + (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { +- sock_hold(sk); ++ if (sk->sk_state == TCP_LISTEN) ++ sock_hold(sk); + bh_unlock_sock(sk); + nr_destroy_socket(sk); + goto out; +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 0ab3b09f863ba..8d0feb9ad5a52 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3092,9 +3092,7 @@ static int packet_release(struct socket *sock) + sk_del_node_init_rcu(sk); + mutex_unlock(&net->packet.sklist_lock); + +- preempt_disable(); + sock_prot_inuse_add(net, sk->sk_prot, -1); +- preempt_enable(); + + spin_lock(&po->bind_lock); + unregister_prot_hook(sk, false); +@@ -3361,9 +3359,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, + sk_add_node_tail_rcu(sk, &net->packet.sklist); + mutex_unlock(&net->packet.sklist_lock); + +- preempt_disable(); + sock_prot_inuse_add(net, &packet_proto, 1); +- preempt_enable(); + + return 0; + out2: +@@ -3761,28 +3757,30 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, + case PACKET_TX_RING: + { + union tpacket_req_u req_u; +- int len; + ++ ret = -EINVAL; + lock_sock(sk); + switch (po->tp_version) { + case TPACKET_V1: + case TPACKET_V2: +- len = sizeof(req_u.req); ++ if (optlen < sizeof(req_u.req)) ++ break; ++ ret = copy_from_sockptr(&req_u.req, optval, ++ sizeof(req_u.req)) ? ++ -EINVAL : 0; + break; + case TPACKET_V3: + default: +- len = sizeof(req_u.req3); ++ if (optlen < sizeof(req_u.req3)) ++ break; ++ ret = copy_from_sockptr(&req_u.req3, optval, ++ sizeof(req_u.req3)) ? ++ -EINVAL : 0; + break; + } +- if (optlen < len) { +- ret = -EINVAL; +- } else { +- if (copy_from_sockptr(&req_u.req, optval, len)) +- ret = -EFAULT; +- else +- ret = packet_set_ring(sk, &req_u, 0, +- optname == PACKET_TX_RING); +- } ++ if (!ret) ++ ret = packet_set_ring(sk, &req_u, 0, ++ optname == PACKET_TX_RING); + release_sock(sk); + return ret; + } +diff --git a/net/sched/act_api.c b/net/sched/act_api.c +index d775676956bf9..0b4deb33bdf7a 100644 +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -555,6 +555,9 @@ EXPORT_SYMBOL(tcf_idr_cleanup); + * its reference and bind counters, and return 1. Otherwise insert temporary + * error pointer (to prevent concurrent users from inserting actions with same + * index) and return 0. ++ * ++ * May return -EAGAIN for binding actions in case of a parallel add/delete on ++ * the requested index. + */ + + int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, +@@ -563,43 +566,60 @@ int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, + struct tcf_idrinfo *idrinfo = tn->idrinfo; + struct tc_action *p; + int ret; ++ u32 max; + +-again: +- mutex_lock(&idrinfo->lock); + if (*index) { ++ rcu_read_lock(); + p = idr_find(&idrinfo->action_idr, *index); ++ + if (IS_ERR(p)) { + /* This means that another process allocated + * index but did not assign the pointer yet. + */ +- mutex_unlock(&idrinfo->lock); +- goto again; ++ rcu_read_unlock(); ++ return -EAGAIN; + } + +- if (p) { +- refcount_inc(&p->tcfa_refcnt); +- if (bind) +- atomic_inc(&p->tcfa_bindcnt); +- *a = p; +- ret = 1; +- } else { +- *a = NULL; +- ret = idr_alloc_u32(&idrinfo->action_idr, NULL, index, +- *index, GFP_KERNEL); +- if (!ret) +- idr_replace(&idrinfo->action_idr, +- ERR_PTR(-EBUSY), *index); ++ if (!p) { ++ /* Empty slot, try to allocate it */ ++ max = *index; ++ rcu_read_unlock(); ++ goto new; + } ++ ++ if (!refcount_inc_not_zero(&p->tcfa_refcnt)) { ++ /* Action was deleted in parallel */ ++ rcu_read_unlock(); ++ return -EAGAIN; ++ } ++ ++ if (bind) ++ atomic_inc(&p->tcfa_bindcnt); ++ *a = p; ++ ++ rcu_read_unlock(); ++ ++ return 1; + } else { ++ /* Find a slot */ + *index = 1; +- *a = NULL; +- ret = idr_alloc_u32(&idrinfo->action_idr, NULL, index, +- UINT_MAX, GFP_KERNEL); +- if (!ret) +- idr_replace(&idrinfo->action_idr, ERR_PTR(-EBUSY), +- *index); ++ max = UINT_MAX; + } ++ ++new: ++ *a = NULL; ++ ++ mutex_lock(&idrinfo->lock); ++ ret = idr_alloc_u32(&idrinfo->action_idr, ERR_PTR(-EBUSY), index, max, ++ GFP_KERNEL); + mutex_unlock(&idrinfo->lock); ++ ++ /* N binds raced for action allocation, ++ * retry for all the ones that failed. ++ */ ++ if (ret == -ENOSPC && *index == max) ++ ret = -EAGAIN; ++ + return ret; + } + EXPORT_SYMBOL(tcf_idr_check_alloc); +diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c +index b4c42b257ae7c..5319de38cc6df 100644 +--- a/net/sched/act_ct.c ++++ b/net/sched/act_ct.c +@@ -38,21 +38,26 @@ static struct workqueue_struct *act_ct_wq; + static struct rhashtable zones_ht; + static DEFINE_MUTEX(zones_mutex); + ++struct zones_ht_key { ++ struct net *net; ++ u16 zone; ++}; ++ + struct tcf_ct_flow_table { + struct rhash_head node; /* In zones tables */ + + struct rcu_work rwork; + struct nf_flowtable nf_ft; + refcount_t ref; +- u16 zone; ++ struct zones_ht_key key; + + bool dying; + }; + + static const struct rhashtable_params zones_params = { + .head_offset = offsetof(struct tcf_ct_flow_table, node), +- .key_offset = offsetof(struct tcf_ct_flow_table, zone), +- .key_len = sizeof_field(struct tcf_ct_flow_table, zone), ++ .key_offset = offsetof(struct tcf_ct_flow_table, key), ++ .key_len = sizeof_field(struct tcf_ct_flow_table, key), + .automatic_shrinking = true, + }; + +@@ -276,13 +281,14 @@ static struct nf_flowtable_type flowtable_ct = { + .owner = THIS_MODULE, + }; + +-static int tcf_ct_flow_table_get(struct tcf_ct_params *params) ++static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params) + { ++ struct zones_ht_key key = { .net = net, .zone = params->zone }; + struct tcf_ct_flow_table *ct_ft; + int err = -ENOMEM; + + mutex_lock(&zones_mutex); +- ct_ft = rhashtable_lookup_fast(&zones_ht, ¶ms->zone, zones_params); ++ ct_ft = rhashtable_lookup_fast(&zones_ht, &key, zones_params); + if (ct_ft && refcount_inc_not_zero(&ct_ft->ref)) + goto out_unlock; + +@@ -291,7 +297,7 @@ static int tcf_ct_flow_table_get(struct tcf_ct_params *params) + goto err_alloc; + refcount_set(&ct_ft->ref, 1); + +- ct_ft->zone = params->zone; ++ ct_ft->key = key; + err = rhashtable_insert_fast(&zones_ht, &ct_ft->node, zones_params); + if (err) + goto err_insert; +@@ -302,6 +308,7 @@ static int tcf_ct_flow_table_get(struct tcf_ct_params *params) + err = nf_flow_table_init(&ct_ft->nf_ft); + if (err) + goto err_init; ++ write_pnet(&ct_ft->nf_ft.net, net); + + __module_get(THIS_MODULE); + out_unlock: +@@ -1304,7 +1311,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, + if (err) + goto cleanup; + +- err = tcf_ct_flow_table_get(params); ++ err = tcf_ct_flow_table_get(net, params); + if (err) + goto cleanup_params; + +diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c +index 8b99f07aa3a76..caa76c96b02ba 100644 +--- a/net/sched/sch_multiq.c ++++ b/net/sched/sch_multiq.c +@@ -185,7 +185,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt, + + qopt->bands = qdisc_dev(sch)->real_num_tx_queues; + +- removed = kmalloc(sizeof(*removed) * (q->max_bands - q->bands), ++ removed = kmalloc(sizeof(*removed) * (q->max_bands - qopt->bands), + GFP_KERNEL); + if (!removed) + return -ENOMEM; +diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c +index e40b4425eb6b5..4a0986843fb5d 100644 +--- a/net/sched/sch_taprio.c ++++ b/net/sched/sch_taprio.c +@@ -947,16 +947,13 @@ static int taprio_parse_mqprio_opt(struct net_device *dev, + { + int i, j; + +- if (!qopt && !dev->num_tc) { +- NL_SET_ERR_MSG(extack, "'mqprio' configuration is necessary"); +- return -EINVAL; +- } +- +- /* If num_tc is already set, it means that the user already +- * configured the mqprio part +- */ +- if (dev->num_tc) ++ if (!qopt) { ++ if (!dev->num_tc) { ++ NL_SET_ERR_MSG(extack, "'mqprio' configuration is necessary"); ++ return -EINVAL; ++ } + return 0; ++ } + + /* Verify num_tc is not out of max range */ + if (qopt->num_tc > TC_MAX_QUEUE) { +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 57acf7ed80de3..d9271ffb29781 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -5073,12 +5073,9 @@ static int sctp_init_sock(struct sock *sk) + + SCTP_DBG_OBJCNT_INC(sock); + +- local_bh_disable(); + sk_sockets_allocated_inc(sk); + sock_prot_inuse_add(net, sk->sk_prot, 1); + +- local_bh_enable(); +- + return 0; + } + +@@ -5104,10 +5101,8 @@ static void sctp_destroy_sock(struct sock *sk) + list_del(&sp->auto_asconf_list); + } + sctp_endpoint_free(sp->ep); +- local_bh_disable(); + sk_sockets_allocated_dec(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); +- local_bh_enable(); + } + + /* Triggered when there are no references on the socket anymore */ +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index 8c11eb70c0f69..bd0b3a8b95d50 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -88,8 +88,8 @@ int smc_hash_sk(struct sock *sk) + + write_lock_bh(&h->lock); + sk_add_node(sk, head); +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + write_unlock_bh(&h->lock); ++ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + + return 0; + } +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index 2ff66a6a7e54c..7ce4a6b7cfae6 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -1855,8 +1855,10 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, + offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; + maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages); + /* slack space should prevent this ever happening: */ +- if (unlikely(snd_buf->len > snd_buf->buflen)) ++ if (unlikely(snd_buf->len > snd_buf->buflen)) { ++ status = -EIO; + goto wrap_failed; ++ } + /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was + * done anyway, so it's safe to put the request on the wire: */ + if (maj_stat == GSS_S_CONTEXT_EXPIRED) +diff --git a/net/tipc/node.c b/net/tipc/node.c +index a9c5b6594889b..cf9d9f9b97844 100644 +--- a/net/tipc/node.c ++++ b/net/tipc/node.c +@@ -2107,6 +2107,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) + } else { + n = tipc_node_find_by_id(net, ehdr->id); + } ++ skb_dst_force(skb); + tipc_crypto_rcv(net, (n) ? n->crypto_rx : NULL, &skb, b); + if (!skb) + return; +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 80f91b5ab4012..e73c1bbc5ff8a 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -190,15 +190,9 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk) + return unix_peer(osk) == NULL || unix_our_peer(sk, osk); + } + +-static inline int unix_recvq_full(const struct sock *sk) +-{ +- return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog; +-} +- + static inline int unix_recvq_full_lockless(const struct sock *sk) + { +- return skb_queue_len_lockless(&sk->sk_receive_queue) > +- READ_ONCE(sk->sk_max_ack_backlog); ++ return skb_queue_len_lockless(&sk->sk_receive_queue) > sk->sk_max_ack_backlog; + } + + struct sock *unix_peer_get(struct sock *s) +@@ -455,9 +449,9 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) + return 0; + } + +-static int unix_writable(const struct sock *sk) ++static int unix_writable(const struct sock *sk, unsigned char state) + { +- return sk->sk_state != TCP_LISTEN && ++ return state != TCP_LISTEN && + (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf; + } + +@@ -466,7 +460,7 @@ static void unix_write_space(struct sock *sk) + struct socket_wq *wq; + + rcu_read_lock(); +- if (unix_writable(sk)) { ++ if (unix_writable(sk, READ_ONCE(sk->sk_state))) { + wq = rcu_dereference(sk->sk_wq); + if (skwq_has_sleeper(wq)) + wake_up_interruptible_sync_poll(&wq->wait, +@@ -491,11 +485,10 @@ static void unix_dgram_disconnected(struct sock *sk, struct sock *other) + * when peer was not connected to us. + */ + if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) { +- other->sk_err = ECONNRESET; ++ WRITE_ONCE(other->sk_err, ECONNRESET); + sk_error_report(other); + } + } +- other->sk_state = TCP_CLOSE; + } + + static void unix_sock_destructor(struct sock *sk) +@@ -516,9 +509,7 @@ static void unix_sock_destructor(struct sock *sk) + unix_release_addr(u->addr); + + atomic_long_dec(&unix_nr_socks); +- local_bh_disable(); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); +- local_bh_enable(); + #ifdef UNIX_REFCNT_DEBUG + pr_debug("UNIX %p is destroyed, %ld are still alive.\n", sk, + atomic_long_read(&unix_nr_socks)); +@@ -543,7 +534,7 @@ static void unix_release_sock(struct sock *sk, int embrion) + u->path.dentry = NULL; + u->path.mnt = NULL; + state = sk->sk_state; +- sk->sk_state = TCP_CLOSE; ++ WRITE_ONCE(sk->sk_state, TCP_CLOSE); + + skpair = unix_peer(sk); + unix_peer(sk) = NULL; +@@ -564,8 +555,8 @@ static void unix_release_sock(struct sock *sk, int embrion) + unix_state_lock(skpair); + /* No more writes */ + WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK); +- if (!skb_queue_empty(&sk->sk_receive_queue) || embrion) +- skpair->sk_err = ECONNRESET; ++ if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || embrion) ++ WRITE_ONCE(skpair->sk_err, ECONNRESET); + unix_state_unlock(skpair); + skpair->sk_state_change(skpair); + sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); +@@ -665,7 +656,8 @@ static int unix_listen(struct socket *sock, int backlog) + if (backlog > sk->sk_max_ack_backlog) + wake_up_interruptible_all(&u->peer_wait); + sk->sk_max_ack_backlog = backlog; +- sk->sk_state = TCP_LISTEN; ++ WRITE_ONCE(sk->sk_state, TCP_LISTEN); ++ + /* set credentials so connect can copy them */ + init_peercred(sk); + err = 0; +@@ -875,7 +867,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, + + sk->sk_allocation = GFP_KERNEL_ACCOUNT; + sk->sk_write_space = unix_write_space; +- sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen; ++ sk->sk_max_ack_backlog = READ_ONCE(net->unx.sysctl_max_dgram_qlen); + sk->sk_destruct = unix_sock_destructor; + u = unix_sk(sk); + u->inflight = 0; +@@ -890,9 +882,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, + memset(&u->scm_stat, 0, sizeof(struct scm_stat)); + unix_insert_socket(unix_sockets_unbound(sk), sk); + +- local_bh_disable(); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); +- local_bh_enable(); + + return sk; + +@@ -1255,7 +1245,8 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, + if (err) + goto out_unlock; + +- sk->sk_state = other->sk_state = TCP_ESTABLISHED; ++ WRITE_ONCE(sk->sk_state, TCP_ESTABLISHED); ++ WRITE_ONCE(other->sk_state, TCP_ESTABLISHED); + } else { + /* + * 1003.1g breaking connected state with AF_UNSPEC +@@ -1272,13 +1263,20 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, + + unix_peer(sk) = other; + if (!other) +- sk->sk_state = TCP_CLOSE; ++ WRITE_ONCE(sk->sk_state, TCP_CLOSE); + unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer); + + unix_state_double_unlock(sk, other); + +- if (other != old_peer) ++ if (other != old_peer) { + unix_dgram_disconnected(sk, old_peer); ++ ++ unix_state_lock(old_peer); ++ if (!unix_peer(old_peer)) ++ WRITE_ONCE(old_peer->sk_state, TCP_CLOSE); ++ unix_state_unlock(old_peer); ++ } ++ + sock_put(old_peer); + } else { + unix_peer(sk) = other; +@@ -1327,7 +1325,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + struct sock *other = NULL; + struct sk_buff *skb = NULL; + unsigned int hash; +- int st; + int err; + long timeo; + +@@ -1384,7 +1381,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + if (other->sk_shutdown & RCV_SHUTDOWN) + goto out_unlock; + +- if (unix_recvq_full(other)) { ++ if (unix_recvq_full_lockless(other)) { + err = -EAGAIN; + if (!timeo) + goto out_unlock; +@@ -1409,9 +1406,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + + Well, and we have to recheck the state after socket locked. + */ +- st = sk->sk_state; +- +- switch (st) { ++ switch (READ_ONCE(sk->sk_state)) { + case TCP_CLOSE: + /* This is ok... continue with connect */ + break; +@@ -1426,7 +1421,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + + unix_state_lock_nested(sk, U_LOCK_SECOND); + +- if (sk->sk_state != st) { ++ if (sk->sk_state != TCP_CLOSE) { + unix_state_unlock(sk); + unix_state_unlock(other); + sock_put(other); +@@ -1478,7 +1473,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + copy_peercred(sk, other); + + sock->state = SS_CONNECTED; +- sk->sk_state = TCP_ESTABLISHED; ++ WRITE_ONCE(sk->sk_state, TCP_ESTABLISHED); + sock_hold(newsk); + + smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */ +@@ -1874,7 +1869,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, + unix_peer(sk) = NULL; + unix_dgram_peer_wake_disconnect_wakeup(sk, other); + +- sk->sk_state = TCP_CLOSE; ++ WRITE_ONCE(sk->sk_state, TCP_CLOSE); + unix_state_unlock(sk); + + unix_dgram_disconnected(sk, other); +@@ -2050,7 +2045,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, + } + + if (msg->msg_namelen) { +- err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; ++ err = READ_ONCE(sk->sk_state) == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; + goto out_err; + } else { + err = -ENOTCONN; +@@ -2262,7 +2257,7 @@ static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg, + if (err) + return err; + +- if (sk->sk_state != TCP_ESTABLISHED) ++ if (READ_ONCE(sk->sk_state) != TCP_ESTABLISHED) + return -ENOTCONN; + + if (msg->msg_namelen) +@@ -2276,7 +2271,7 @@ static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg, + { + struct sock *sk = sock->sk; + +- if (sk->sk_state != TCP_ESTABLISHED) ++ if (READ_ONCE(sk->sk_state) != TCP_ESTABLISHED) + return -ENOTCONN; + + return unix_dgram_recvmsg(sock, msg, size, flags); +@@ -2570,18 +2565,18 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk, + if (skb == u->oob_skb) { + if (copied) { + skb = NULL; +- } else if (sock_flag(sk, SOCK_URGINLINE)) { +- if (!(flags & MSG_PEEK)) { ++ } else if (!(flags & MSG_PEEK)) { ++ if (sock_flag(sk, SOCK_URGINLINE)) { + WRITE_ONCE(u->oob_skb, NULL); + consume_skb(skb); ++ } else { ++ __skb_unlink(skb, &sk->sk_receive_queue); ++ WRITE_ONCE(u->oob_skb, NULL); ++ unlinked_skb = skb; ++ skb = skb_peek(&sk->sk_receive_queue); + } +- } else if (flags & MSG_PEEK) { +- skb = NULL; +- } else { +- __skb_unlink(skb, &sk->sk_receive_queue); +- WRITE_ONCE(u->oob_skb, NULL); +- unlinked_skb = skb; +- skb = skb_peek(&sk->sk_receive_queue); ++ } else if (!sock_flag(sk, SOCK_URGINLINE)) { ++ skb = skb_peek_next(skb, &sk->sk_receive_queue); + } + } + +@@ -2599,7 +2594,7 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk, + static int unix_stream_read_sock(struct sock *sk, read_descriptor_t *desc, + sk_read_actor_t recv_actor) + { +- if (unlikely(sk->sk_state != TCP_ESTABLISHED)) ++ if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)) + return -ENOTCONN; + + return unix_read_sock(sk, desc, recv_actor); +@@ -2623,7 +2618,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, + size_t size = state->size; + unsigned int last_len; + +- if (unlikely(sk->sk_state != TCP_ESTABLISHED)) { ++ if (unlikely(READ_ONCE(sk->sk_state) != TCP_ESTABLISHED)) { + err = -EINVAL; + goto out; + } +@@ -2949,7 +2944,7 @@ long unix_inq_len(struct sock *sk) + struct sk_buff *skb; + long amount = 0; + +- if (sk->sk_state == TCP_LISTEN) ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) + return -EINVAL; + + spin_lock(&sk->sk_receive_queue.lock); +@@ -3061,15 +3056,17 @@ static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon + static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait) + { + struct sock *sk = sock->sk; ++ unsigned char state; + __poll_t mask; + u8 shutdown; + + sock_poll_wait(file, sock, wait); + mask = 0; + shutdown = READ_ONCE(sk->sk_shutdown); ++ state = READ_ONCE(sk->sk_state); + + /* exceptional events? */ +- if (sk->sk_err) ++ if (READ_ONCE(sk->sk_err)) + mask |= EPOLLERR; + if (shutdown == SHUTDOWN_MASK) + mask |= EPOLLHUP; +@@ -3088,14 +3085,14 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa + + /* Connection-based need to check for termination and startup */ + if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && +- sk->sk_state == TCP_CLOSE) ++ state == TCP_CLOSE) + mask |= EPOLLHUP; + + /* + * we set writable also when the other side has shut down the + * connection. This prevents stuck sockets. + */ +- if (unix_writable(sk)) ++ if (unix_writable(sk, state)) + mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND; + + return mask; +@@ -3106,15 +3103,18 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, + { + struct sock *sk = sock->sk, *other; + unsigned int writable; ++ unsigned char state; + __poll_t mask; + u8 shutdown; + + sock_poll_wait(file, sock, wait); + mask = 0; + shutdown = READ_ONCE(sk->sk_shutdown); ++ state = READ_ONCE(sk->sk_state); + + /* exceptional events? */ +- if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) ++ if (READ_ONCE(sk->sk_err) || ++ !skb_queue_empty_lockless(&sk->sk_error_queue)) + mask |= EPOLLERR | + (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0); + +@@ -3130,19 +3130,14 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, + mask |= EPOLLIN | EPOLLRDNORM; + + /* Connection-based need to check for termination and startup */ +- if (sk->sk_type == SOCK_SEQPACKET) { +- if (sk->sk_state == TCP_CLOSE) +- mask |= EPOLLHUP; +- /* connection hasn't started yet? */ +- if (sk->sk_state == TCP_SYN_SENT) +- return mask; +- } ++ if (sk->sk_type == SOCK_SEQPACKET && state == TCP_CLOSE) ++ mask |= EPOLLHUP; + + /* No write status requested, avoid expensive OUT tests. */ + if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT))) + return mask; + +- writable = unix_writable(sk); ++ writable = unix_writable(sk, state); + if (writable) { + unix_state_lock(sk); + +diff --git a/net/unix/diag.c b/net/unix/diag.c +index daef19932f780..486276a1782ed 100644 +--- a/net/unix/diag.c ++++ b/net/unix/diag.c +@@ -64,7 +64,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) + u32 *buf; + int i; + +- if (sk->sk_state == TCP_LISTEN) { ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) { + spin_lock(&sk->sk_receive_queue.lock); + + attr = nla_reserve(nlskb, UNIX_DIAG_ICONS, +@@ -102,8 +102,8 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) + { + struct unix_diag_rqlen rql; + +- if (sk->sk_state == TCP_LISTEN) { +- rql.udiag_rqueue = sk->sk_receive_queue.qlen; ++ if (READ_ONCE(sk->sk_state) == TCP_LISTEN) { ++ rql.udiag_rqueue = skb_queue_len_lockless(&sk->sk_receive_queue); + rql.udiag_wqueue = sk->sk_max_ack_backlog; + } else { + rql.udiag_rqueue = (u32) unix_inq_len(sk); +@@ -135,7 +135,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r + rep = nlmsg_data(nlh); + rep->udiag_family = AF_UNIX; + rep->udiag_type = sk->sk_type; +- rep->udiag_state = sk->sk_state; ++ rep->udiag_state = READ_ONCE(sk->sk_state); + rep->pad = 0; + rep->udiag_ino = sk_ino; + sock_diag_save_cookie(sk, rep->udiag_cookie); +@@ -164,7 +164,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r + sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) + goto out_nlmsg_trim; + +- if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown)) ++ if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, READ_ONCE(sk->sk_shutdown))) + goto out_nlmsg_trim; + + if ((req->udiag_show & UDIAG_SHOW_UID) && +@@ -218,7 +218,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) + continue; + if (num < s_num) + goto next; +- if (!(req->udiag_states & (1 << sk->sk_state))) ++ if (!(req->udiag_states & (1 << READ_ONCE(sk->sk_state)))) + goto next; + if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk), + NETLINK_CB(cb->skb).portid, +diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c +index 328cf54bda826..65fa39275f73f 100644 +--- a/net/wireless/pmsr.c ++++ b/net/wireless/pmsr.c +@@ -58,7 +58,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, + out->ftm.burst_period = 0; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]) + out->ftm.burst_period = +- nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]); ++ nla_get_u16(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]); + + out->ftm.asap = !!tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP]; + if (out->ftm.asap && !capa->ftm.asap) { +@@ -77,7 +77,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, + out->ftm.num_bursts_exp = 0; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]) + out->ftm.num_bursts_exp = +- nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]); ++ nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]); + + if (capa->ftm.max_bursts_exponent >= 0 && + out->ftm.num_bursts_exp > capa->ftm.max_bursts_exponent) { +@@ -90,7 +90,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, + out->ftm.burst_duration = 15; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]) + out->ftm.burst_duration = +- nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]); ++ nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]); + + out->ftm.ftms_per_burst = 0; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]) +@@ -109,7 +109,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, + out->ftm.ftmr_retries = 3; + if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]) + out->ftm.ftmr_retries = +- nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]); ++ nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]); + + out->ftm.request_lci = !!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI]; + if (out->ftm.request_lci && !capa->ftm.request_lci) { +diff --git a/net/wireless/util.c b/net/wireless/util.c +index cb15d7f4eb05a..d40c2cf777dc0 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -2033,6 +2033,7 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, + { + struct cfg80211_registered_device *rdev; + struct wireless_dev *wdev; ++ int ret; + + wdev = dev->ieee80211_ptr; + if (!wdev) +@@ -2044,7 +2045,11 @@ int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, + + memset(sinfo, 0, sizeof(*sinfo)); + +- return rdev_get_station(rdev, dev, mac_addr, sinfo); ++ wiphy_lock(&rdev->wiphy); ++ ret = rdev_get_station(rdev, dev, mac_addr, sinfo); ++ wiphy_unlock(&rdev->wiphy); ++ ++ return ret; + } + EXPORT_SYMBOL(cfg80211_get_station); + +diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c +index 1f61d15b3d1d4..da31a99ce6521 100644 +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -842,9 +842,7 @@ static int xsk_release(struct socket *sock) + sk_del_node_init_rcu(sk); + mutex_unlock(&net->xdp.lock); + +- local_bh_disable(); + sock_prot_inuse_add(net, sk->sk_prot, -1); +- local_bh_enable(); + + xsk_delete_from_maps(xs); + mutex_lock(&xs->mutex); +@@ -1465,9 +1463,7 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol, + sk_add_node_rcu(sk, &net->xdp.list); + mutex_unlock(&net->xdp.lock); + +- local_bh_disable(); + sock_prot_inuse_add(net, &xsk_proto, 1); +- local_bh_enable(); + + return 0; + } +diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst +index 190d781e84f4b..3668259ddb65d 100644 +--- a/scripts/Makefile.dtbinst ++++ b/scripts/Makefile.dtbinst +@@ -24,7 +24,7 @@ __dtbs_install: $(dtbs) $(subdirs) + @: + + quiet_cmd_dtb_install = INSTALL $@ +- cmd_dtb_install = install -D $< $@ ++ cmd_dtb_install = install -D -m 0644 $< $@ + + $(dst)/%.dtb: $(obj)/%.dtb + $(call cmd,dtb_install) +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index c7529aa13f944..ae59b208f12ac 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9463,6 +9463,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ + SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), + SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), ++ SND_PCI_QUIRK(0x1c6c, 0x122a, "Positivo N14AP7", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x1c6c, 0x1251, "Positivo N14KP6-TG", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_SET_COEF_DEFAULTS), + SND_PCI_QUIRK(0x1d05, 0x1096, "TongFang GMxMRxx", ALC269_FIXUP_NO_SHUTUP), +diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c +index 5000d779aade2..98a157e46637a 100644 +--- a/sound/soc/fsl/fsl-asoc-card.c ++++ b/sound/soc/fsl/fsl-asoc-card.c +@@ -548,6 +548,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) + if (!priv) + return -ENOMEM; + ++ priv->pdev = pdev; ++ + cpu_np = of_parse_phandle(np, "audio-cpu", 0); + /* Give a chance to old DT binding */ + if (!cpu_np) +@@ -742,7 +744,6 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) + } + + /* Initialize sound card */ +- priv->pdev = pdev; + priv->card.dev = &pdev->dev; + priv->card.owner = THIS_MODULE; + ret = snd_soc_of_parse_card_name(&priv->card, "model"); +diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c +index 16f00097cb95a..eed47e4830248 100644 +--- a/sound/synth/emux/soundfont.c ++++ b/sound/synth/emux/soundfont.c +@@ -701,7 +701,6 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count) + struct snd_soundfont *sf; + struct soundfont_sample_info sample_info; + struct snd_sf_sample *sp; +- long off; + + /* patch must be opened */ + sf = sflist->currsf; +@@ -711,12 +710,16 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count) + if (is_special_type(sf->type)) + return -EINVAL; + ++ if (count < (long)sizeof(sample_info)) { ++ return -EINVAL; ++ } + if (copy_from_user(&sample_info, data, sizeof(sample_info))) + return -EFAULT; ++ data += sizeof(sample_info); ++ count -= sizeof(sample_info); + +- off = sizeof(sample_info); +- +- if (sample_info.size != (count-off)/2) ++ // SoundFont uses S16LE samples. ++ if (sample_info.size * 2 != count) + return -EINVAL; + + /* Check for dup */ +@@ -744,7 +747,7 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count) + int rc; + rc = sflist->callback.sample_new + (sflist->callback.private_data, sp, sflist->memhdr, +- data + off, count - off); ++ data, count); + if (rc < 0) { + sf_sample_delete(sflist, sf, sp); + return rc; +@@ -957,10 +960,12 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data, + } + if (copy_from_user(&patch, data, sizeof(patch))) + return -EFAULT; +- + count -= sizeof(patch); + data += sizeof(patch); + ++ if ((patch.len << (patch.mode & WAVE_16_BITS ? 1 : 0)) != count) ++ return -EINVAL; ++ + sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL); + if (sf == NULL) + return -ENOMEM; +diff --git a/tools/include/asm-generic/hugetlb_encode.h b/tools/include/asm-generic/hugetlb_encode.h +index 4f3d5aaa11f53..de687009bfe53 100644 +--- a/tools/include/asm-generic/hugetlb_encode.h ++++ b/tools/include/asm-generic/hugetlb_encode.h +@@ -20,18 +20,18 @@ + #define HUGETLB_FLAG_ENCODE_SHIFT 26 + #define HUGETLB_FLAG_ENCODE_MASK 0x3f + +-#define HUGETLB_FLAG_ENCODE_16KB (14 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_32MB (25 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_512MB (29 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT) +-#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_16KB (14U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_64KB (16U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_512KB (19U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_1MB (20U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_2MB (21U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_8MB (23U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_16MB (24U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_32MB (25U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_256MB (28U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_512MB (29U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_1GB (30U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_2GB (31U << HUGETLB_FLAG_ENCODE_SHIFT) ++#define HUGETLB_FLAG_ENCODE_16GB (34U << HUGETLB_FLAG_ENCODE_SHIFT) + + #endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */ +diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt +index c80515243560c..fa6a78c472bc1 100644 +--- a/tools/perf/Documentation/perf-script.txt ++++ b/tools/perf/Documentation/perf-script.txt +@@ -423,9 +423,10 @@ include::itrace.txt[] + will be printed. Each entry has function name and file/line. Enabled by + default, disable with --no-inline. + +---insn-trace:: +- Show instruction stream for intel_pt traces. Combine with --xed to +- show disassembly. ++--insn-trace[=<raw|disasm>]:: ++ Show instruction stream in bytes (raw) or disassembled (disasm) ++ for intel_pt traces. The default is 'raw'. To use xed, combine ++ 'raw' with --xed to show disassembly done by xed. + + --xed:: + Run xed disassembler on output. Requires installing the xed disassembler. +diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c +index 34e809c934d72..78ee2c2978ac3 100644 +--- a/tools/perf/builtin-script.c ++++ b/tools/perf/builtin-script.c +@@ -3585,11 +3585,25 @@ static int perf_script__process_auxtrace_info(struct perf_session *session, + #endif + + static int parse_insn_trace(const struct option *opt __maybe_unused, +- const char *str __maybe_unused, +- int unset __maybe_unused) ++ const char *str, int unset __maybe_unused) + { +- parse_output_fields(NULL, "+insn,-event,-period", 0); +- itrace_parse_synth_opts(opt, "i0ns", 0); ++ const char *fields = "+insn,-event,-period"; ++ int ret; ++ ++ if (str) { ++ if (strcmp(str, "disasm") == 0) ++ fields = "+disasm,-event,-period"; ++ else if (strlen(str) != 0 && strcmp(str, "raw") != 0) { ++ fprintf(stderr, "Only accept raw|disasm\n"); ++ return -EINVAL; ++ } ++ } ++ ++ ret = parse_output_fields(NULL, fields, 0); ++ if (ret < 0) ++ return ret; ++ ++ itrace_parse_synth_opts(opt, "i0nse", 0); + symbol_conf.nanosecs = true; + return 0; + } +@@ -3728,7 +3742,7 @@ int cmd_script(int argc, const char **argv) + "only consider these symbols"), + OPT_INTEGER(0, "addr-range", &symbol_conf.addr_range, + "Use with -S to list traced records within address range"), +- OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, NULL, ++ OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, "raw|disasm", + "Decode instructions from itrace", parse_insn_trace), + OPT_CALLBACK_OPTARG(0, "xed", NULL, NULL, NULL, + "Run xed disassembler on output", parse_xed), +diff --git a/tools/testing/selftests/arm64/tags/tags_test.c b/tools/testing/selftests/arm64/tags/tags_test.c +index 5701163460ef7..955f87c1170d7 100644 +--- a/tools/testing/selftests/arm64/tags/tags_test.c ++++ b/tools/testing/selftests/arm64/tags/tags_test.c +@@ -6,6 +6,7 @@ + #include <stdint.h> + #include <sys/prctl.h> + #include <sys/utsname.h> ++#include "../../kselftest.h" + + #define SHIFT_TAG(tag) ((uint64_t)(tag) << 56) + #define SET_TAG(ptr, tag) (((uint64_t)(ptr) & ~SHIFT_TAG(0xff)) | \ +@@ -21,6 +22,9 @@ int main(void) + if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) + tbi_enabled = 1; + ptr = (struct utsname *)malloc(sizeof(*ptr)); ++ if (!ptr) ++ ksft_exit_fail_msg("Failed to allocate utsname buffer\n"); ++ + if (tbi_enabled) + tag = 0x42; + ptr = (struct utsname *)SET_TAG(ptr, tag); +diff --git a/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c b/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c +index eb90a6b8850d2..f4d753185001a 100644 +--- a/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c ++++ b/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c +@@ -25,7 +25,7 @@ static void test_lookup_update(void) + int map1_fd, map2_fd, map3_fd, map4_fd, map5_fd, map1_id, map2_id; + int outer_arr_fd, outer_hash_fd, outer_arr_dyn_fd; + struct test_btf_map_in_map *skel; +- int err, key = 0, val, i, fd; ++ int err, key = 0, val, i; + + skel = test_btf_map_in_map__open_and_load(); + if (CHECK(!skel, "skel_open", "failed to open&load skeleton\n")) +@@ -102,30 +102,6 @@ static void test_lookup_update(void) + CHECK(map1_id == 0, "map1_id", "failed to get ID 1\n"); + CHECK(map2_id == 0, "map2_id", "failed to get ID 2\n"); + +- test_btf_map_in_map__destroy(skel); +- skel = NULL; +- +- /* we need to either wait for or force synchronize_rcu(), before +- * checking for "still exists" condition, otherwise map could still be +- * resolvable by ID, causing false positives. +- * +- * Older kernels (5.8 and earlier) freed map only after two +- * synchronize_rcu()s, so trigger two, to be entirely sure. +- */ +- CHECK(kern_sync_rcu(), "sync_rcu", "failed\n"); +- CHECK(kern_sync_rcu(), "sync_rcu", "failed\n"); +- +- fd = bpf_map_get_fd_by_id(map1_id); +- if (CHECK(fd >= 0, "map1_leak", "inner_map1 leaked!\n")) { +- close(fd); +- goto cleanup; +- } +- fd = bpf_map_get_fd_by_id(map2_id); +- if (CHECK(fd >= 0, "map2_leak", "inner_map2 leaked!\n")) { +- close(fd); +- goto cleanup; +- } +- + cleanup: + test_btf_map_in_map__destroy(skel); + } +diff --git a/tools/testing/selftests/bpf/test_tc_tunnel.sh b/tools/testing/selftests/bpf/test_tc_tunnel.sh +index 088fcad138c98..38c6e9f16f41e 100755 +--- a/tools/testing/selftests/bpf/test_tc_tunnel.sh ++++ b/tools/testing/selftests/bpf/test_tc_tunnel.sh +@@ -71,7 +71,6 @@ cleanup() { + server_listen() { + ip netns exec "${ns2}" nc "${netcat_opt}" -l "${port}" > "${outfile}" & + server_pid=$! +- sleep 0.2 + } + + client_connect() { +@@ -92,6 +91,16 @@ verify_data() { + fi + } + ++wait_for_port() { ++ for i in $(seq 20); do ++ if ip netns exec "${ns2}" ss ${2:--4}OHntl | grep -q "$1"; then ++ return 0 ++ fi ++ sleep 0.1 ++ done ++ return 1 ++} ++ + set -e + + # no arguments: automated test, run all +@@ -189,6 +198,7 @@ setup + # basic communication works + echo "test basic connectivity" + server_listen ++wait_for_port ${port} ${netcat_opt} + client_connect + verify_data + +@@ -200,6 +210,7 @@ ip netns exec "${ns1}" tc filter add dev veth1 egress \ + section "encap_${tuntype}_${mac}" + echo "test bpf encap without decap (expect failure)" + server_listen ++wait_for_port ${port} ${netcat_opt} + ! client_connect + + if [[ "$tuntype" =~ "udp" ]]; then +diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc +index 1f6981ef7afa0..ba19b81cef39a 100644 +--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc ++++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc +@@ -30,7 +30,8 @@ find_dot_func() { + fi + + grep " [tT] .*\.isra\..*" /proc/kallsyms | cut -f 3 -d " " | while read f; do +- if grep -s $f available_filter_functions; then ++ cnt=`grep -s $f available_filter_functions | wc -l`; ++ if [ $cnt -eq 1 ]; then + echo $f + break + fi +diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh +index a68048f1fc5a4..e725285298a02 100755 +--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh +@@ -1306,9 +1306,10 @@ remove_tests() + reset + ip netns exec $ns1 ./pm_nl_ctl limits 3 3 + ip netns exec $ns1 ./pm_nl_ctl add 10.0.12.1 flags signal ++ # broadcast IP: no packet for this address will be received on ns1 ++ ip netns exec $ns1 ./pm_nl_ctl add 224.0.0.1 flags signal + ip netns exec $ns1 ./pm_nl_ctl add 10.0.3.1 flags signal +- ip netns exec $ns1 ./pm_nl_ctl add 10.0.14.1 flags signal +- ip netns exec $ns2 ./pm_nl_ctl limits 3 3 ++ ip netns exec $ns2 ./pm_nl_ctl limits 2 2 + run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow + chk_join_nr "remove invalid addresses" 1 1 1 + chk_add_nr 3 3 +diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c +index 9b420140ba2ba..7c260060a1a6b 100644 +--- a/tools/testing/selftests/vm/compaction_test.c ++++ b/tools/testing/selftests/vm/compaction_test.c +@@ -33,7 +33,7 @@ int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize) + FILE *cmdfile = popen(cmd, "r"); + + if (!(fgets(buffer, sizeof(buffer), cmdfile))) { +- perror("Failed to read meminfo\n"); ++ ksft_print_msg("Failed to read meminfo: %s\n", strerror(errno)); + return -1; + } + +@@ -44,7 +44,7 @@ int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize) + cmdfile = popen(cmd, "r"); + + if (!(fgets(buffer, sizeof(buffer), cmdfile))) { +- perror("Failed to read meminfo\n"); ++ ksft_print_msg("Failed to read meminfo: %s\n", strerror(errno)); + return -1; + } + +@@ -62,14 +62,14 @@ int prereq(void) + fd = open("/proc/sys/vm/compact_unevictable_allowed", + O_RDONLY | O_NONBLOCK); + if (fd < 0) { +- perror("Failed to open\n" +- "/proc/sys/vm/compact_unevictable_allowed\n"); ++ ksft_print_msg("Failed to open /proc/sys/vm/compact_unevictable_allowed: %s\n", ++ strerror(errno)); + return -1; + } + + if (read(fd, &allowed, sizeof(char)) != sizeof(char)) { +- perror("Failed to read from\n" +- "/proc/sys/vm/compact_unevictable_allowed\n"); ++ ksft_print_msg("Failed to read from /proc/sys/vm/compact_unevictable_allowed: %s\n", ++ strerror(errno)); + close(fd); + return -1; + } +@@ -78,15 +78,17 @@ int prereq(void) + if (allowed == '1') + return 0; + ++ ksft_print_msg("Compaction isn't allowed\n"); + return -1; + } + +-int check_compaction(unsigned long mem_free, unsigned int hugepage_size) ++int check_compaction(unsigned long mem_free, unsigned long hugepage_size) + { +- int fd; ++ unsigned long nr_hugepages_ul; ++ int fd, ret = -1; + int compaction_index = 0; +- char initial_nr_hugepages[10] = {0}; +- char nr_hugepages[10] = {0}; ++ char initial_nr_hugepages[20] = {0}; ++ char nr_hugepages[20] = {0}; + + /* We want to test with 80% of available memory. Else, OOM killer comes + in to play */ +@@ -94,18 +96,23 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + + fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK); + if (fd < 0) { +- perror("Failed to open /proc/sys/vm/nr_hugepages"); ++ ksft_test_result_fail("Failed to open /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + return -1; + } + + if (read(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) <= 0) { +- perror("Failed to read from /proc/sys/vm/nr_hugepages"); ++ ksft_test_result_fail("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + ++ lseek(fd, 0, SEEK_SET); ++ + /* Start with the initial condition of 0 huge pages*/ + if (write(fd, "0", sizeof(char)) != sizeof(char)) { +- perror("Failed to write 0 to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +@@ -114,82 +121,80 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size) + /* Request a large number of huge pages. The Kernel will allocate + as much as it can */ + if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { +- perror("Failed to write 100000 to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + + lseek(fd, 0, SEEK_SET); + + if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { +- perror("Failed to re-read from /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to re-read from /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + + /* We should have been able to request at least 1/3 rd of the memory in + huge pages */ +- compaction_index = mem_free/(atoi(nr_hugepages) * hugepage_size); +- +- if (compaction_index > 3) { +- printf("No of huge pages allocated = %d\n", +- (atoi(nr_hugepages))); +- fprintf(stderr, "ERROR: Less that 1/%d of memory is available\n" +- "as huge pages\n", compaction_index); ++ nr_hugepages_ul = strtoul(nr_hugepages, NULL, 10); ++ if (!nr_hugepages_ul) { ++ ksft_print_msg("ERROR: No memory is available as huge pages\n"); + goto close_fd; + } +- +- printf("No of huge pages allocated = %d\n", +- (atoi(nr_hugepages))); ++ compaction_index = mem_free/(nr_hugepages_ul * hugepage_size); + + lseek(fd, 0, SEEK_SET); + + if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) + != strlen(initial_nr_hugepages)) { +- perror("Failed to write value to /proc/sys/vm/nr_hugepages\n"); ++ ksft_test_result_fail("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n", ++ strerror(errno)); + goto close_fd; + } + +- close(fd); +- return 0; ++ if (compaction_index > 3) { ++ ksft_print_msg("ERROR: Less than 1/%d of memory is available\n" ++ "as huge pages\n", compaction_index); ++ ksft_test_result_fail("No of huge pages allocated = %d\n", (atoi(nr_hugepages))); ++ goto close_fd; ++ } ++ ++ ksft_test_result_pass("Memory compaction succeeded. No of huge pages allocated = %d\n", ++ (atoi(nr_hugepages))); ++ ret = 0; + + close_fd: + close(fd); +- printf("Not OK. Compaction test failed."); +- return -1; ++ return ret; + } + + + int main(int argc, char **argv) + { + struct rlimit lim; +- struct map_list *list, *entry; ++ struct map_list *list = NULL, *entry; + size_t page_size, i; + void *map = NULL; + unsigned long mem_free = 0; + unsigned long hugepage_size = 0; + long mem_fragmentable_MB = 0; + +- if (prereq() != 0) { +- printf("Either the sysctl compact_unevictable_allowed is not\n" +- "set to 1 or couldn't read the proc file.\n" +- "Skipping the test\n"); +- return KSFT_SKIP; +- } ++ ksft_print_header(); ++ ++ if (prereq() != 0) ++ return ksft_exit_pass(); ++ ++ ksft_set_plan(1); + + lim.rlim_cur = RLIM_INFINITY; + lim.rlim_max = RLIM_INFINITY; +- if (setrlimit(RLIMIT_MEMLOCK, &lim)) { +- perror("Failed to set rlimit:\n"); +- return -1; +- } ++ if (setrlimit(RLIMIT_MEMLOCK, &lim)) ++ ksft_exit_fail_msg("Failed to set rlimit: %s\n", strerror(errno)); + + page_size = getpagesize(); + +- list = NULL; +- +- if (read_memory_info(&mem_free, &hugepage_size) != 0) { +- printf("ERROR: Cannot read meminfo\n"); +- return -1; +- } ++ if (read_memory_info(&mem_free, &hugepage_size) != 0) ++ ksft_exit_fail_msg("Failed to get meminfo\n"); + + mem_fragmentable_MB = mem_free * 0.8 / 1024; + +@@ -225,7 +230,7 @@ int main(int argc, char **argv) + } + + if (check_compaction(mem_free, hugepage_size) == 0) +- return 0; ++ return ksft_exit_pass(); + +- return -1; ++ return ksft_exit_fail(); + } |