From faeab2754ec5d68c53edb5980435be933c285186 Mon Sep 17 00:00:00 2001 From: Mike Pagano Date: Wed, 25 Oct 2023 07:34:55 -0400 Subject: Linux patch 6.5.9 Signed-off-by: Mike Pagano --- 0000_README | 4 + 1008_linux-6.5.9.patch | 8349 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 8353 insertions(+) create mode 100644 1008_linux-6.5.9.patch diff --git a/0000_README b/0000_README index 0f2b2d88..63f98435 100644 --- a/0000_README +++ b/0000_README @@ -75,6 +75,10 @@ Patch: 1007_linux-6.5.8.patch From: https://www.kernel.org Desc: Linux 6.5.8 +Patch: 1008_linux-6.5.9.patch +From: https://www.kernel.org +Desc: Linux 6.5.9 + 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/1008_linux-6.5.9.patch b/1008_linux-6.5.9.patch new file mode 100644 index 00000000..6ce021b0 --- /dev/null +++ b/1008_linux-6.5.9.patch @@ -0,0 +1,8349 @@ +diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +index 6da28e6305778..30a2c1e36b970 100644 +--- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml ++++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +@@ -69,7 +69,7 @@ properties: + maxItems: 4 + + clocks: +- minItems: 3 ++ minItems: 2 + items: + - description: Main peripheral bus clock, PCLK/HCLK - AHB Bus clock + - description: SDC MMC clock, MCLK +diff --git a/Documentation/networking/representors.rst b/Documentation/networking/representors.rst +index ee1f5cd54496e..decb39c19b9ed 100644 +--- a/Documentation/networking/representors.rst ++++ b/Documentation/networking/representors.rst +@@ -162,9 +162,11 @@ How are representors identified? + The representor netdevice should *not* directly refer to a PCIe device (e.g. + through ``net_dev->dev.parent`` / ``SET_NETDEV_DEV()``), either of the + representee or of the switchdev function. +-Instead, it should implement the ``ndo_get_devlink_port()`` netdevice op, which +-the kernel uses to provide the ``phys_switch_id`` and ``phys_port_name`` sysfs +-nodes. (Some legacy drivers implement ``ndo_get_port_parent_id()`` and ++Instead, the driver should use the ``SET_NETDEV_DEVLINK_PORT`` macro to ++assign a devlink port instance to the netdevice before registering the ++netdevice; the kernel uses the devlink port to provide the ``phys_switch_id`` ++and ``phys_port_name`` sysfs nodes. ++(Some legacy drivers implement ``ndo_get_port_parent_id()`` and + ``ndo_get_phys_port_name()`` directly, but this is deprecated.) See + :ref:`Documentation/networking/devlink/devlink-port.rst ` for the + details of this API. +diff --git a/Documentation/rust/general-information.rst b/Documentation/rust/general-information.rst +index 49029ee82e559..081397827a7ea 100644 +--- a/Documentation/rust/general-information.rst ++++ b/Documentation/rust/general-information.rst +@@ -29,7 +29,7 @@ target with the same invocation used for compilation, e.g.:: + + To read the docs locally in your web browser, run e.g.:: + +- xdg-open rust/doc/kernel/index.html ++ xdg-open Documentation/output/rust/rustdoc/kernel/index.html + + To learn about how to write the documentation, please see coding-guidelines.rst. + +diff --git a/Documentation/rust/index.rst b/Documentation/rust/index.rst +index 4ae8c66b94faf..e599be2cec9ba 100644 +--- a/Documentation/rust/index.rst ++++ b/Documentation/rust/index.rst +@@ -6,6 +6,14 @@ Rust + Documentation related to Rust within the kernel. To start using Rust + in the kernel, please read the quick-start.rst guide. + ++.. only:: rustdoc and html ++ ++ You can also browse `rustdoc documentation `_. ++ ++.. only:: not rustdoc and html ++ ++ This documentation does not include rustdoc generated information. ++ + .. toctree:: + :maxdepth: 1 + +diff --git a/Makefile b/Makefile +index a687c9a0646cb..fc83c079c4716 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 5 +-SUBLEVEL = 8 ++SUBLEVEL = 9 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +@@ -1595,7 +1595,7 @@ endif + # 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 rust/test rust/doc \ ++ compile_commands.json .thinlto-cache rust/test \ + rust-project.json .vmlinux.objs .vmlinux.export.c + + # Directories & files removed with 'make mrproper' +diff --git a/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi +index d69f0f4b4990d..d2d516d113baa 100644 +--- a/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi ++++ b/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi +@@ -640,6 +640,7 @@ + &uart3 { + interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core 0x17c>; ++ overrun-throttle-ms = <500>; + }; + + &uart4 { +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index 43011bc41da77..54c674c45b49a 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -2958,7 +2958,7 @@ + clock-names = "merge","merge_async"; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xc000 0x1000>; +- mediatek,merge-mute = <1>; ++ mediatek,merge-mute; + resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC>; + }; + +@@ -2971,7 +2971,7 @@ + clock-names = "merge","merge_async"; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xd000 0x1000>; +- mediatek,merge-mute = <1>; ++ mediatek,merge-mute; + resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC>; + }; + +@@ -2984,7 +2984,7 @@ + clock-names = "merge","merge_async"; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xe000 0x1000>; +- mediatek,merge-mute = <1>; ++ mediatek,merge-mute; + resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC>; + }; + +@@ -2997,7 +2997,7 @@ + clock-names = "merge","merge_async"; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xf000 0x1000>; +- mediatek,merge-mute = <1>; ++ mediatek,merge-mute; + resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC>; + }; + +@@ -3010,7 +3010,7 @@ + clock-names = "merge","merge_async"; + power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x0000 0x1000>; +- mediatek,merge-fifo-en = <1>; ++ mediatek,merge-fifo-en; + resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>; + }; + +diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig +index 0b1172cbeccb3..b3fdb3d268367 100644 +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -917,7 +917,7 @@ config ARCH_FORCE_MAX_ORDER + default "6" if PPC32 && PPC_64K_PAGES + range 4 10 if PPC32 && PPC_256K_PAGES + default "4" if PPC32 && PPC_256K_PAGES +- range 10 10 ++ range 10 12 + default "10" + help + The kernel page allocator limits the size of maximal physically +diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c +index 253620979d0cd..6dd2f46bd3ef6 100644 +--- a/arch/powerpc/lib/qspinlock.c ++++ b/arch/powerpc/lib/qspinlock.c +@@ -406,6 +406,9 @@ static __always_inline bool yield_to_prev(struct qspinlock *lock, struct qnode * + if ((yield_count & 1) == 0) + goto yield_prev; /* owner vcpu is running */ + ++ if (get_owner_cpu(READ_ONCE(lock->val)) != yield_cpu) ++ goto yield_prev; /* re-sample lock owner */ ++ + spin_end(); + + preempted = true; +diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c +index 2d9b01d7ca4c5..99209085c75bc 100644 +--- a/arch/s390/pci/pci_dma.c ++++ b/arch/s390/pci/pci_dma.c +@@ -564,6 +564,17 @@ static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg, + s->dma_length = 0; + } + } ++ ++static unsigned long *bitmap_vzalloc(size_t bits, gfp_t flags) ++{ ++ size_t n = BITS_TO_LONGS(bits); ++ size_t bytes; ++ ++ if (unlikely(check_mul_overflow(n, sizeof(unsigned long), &bytes))) ++ return NULL; ++ ++ return vzalloc(bytes); ++} + + int zpci_dma_init_device(struct zpci_dev *zdev) + { +@@ -604,13 +615,13 @@ int zpci_dma_init_device(struct zpci_dev *zdev) + zdev->end_dma - zdev->start_dma + 1); + zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1; + zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; +- zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); ++ zdev->iommu_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL); + if (!zdev->iommu_bitmap) { + rc = -ENOMEM; + goto free_dma_table; + } + if (!s390_iommu_strict) { +- zdev->lazy_bitmap = vzalloc(zdev->iommu_pages / 8); ++ zdev->lazy_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL); + if (!zdev->lazy_bitmap) { + rc = -ENOMEM; + goto free_bitmap; +diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c +index c3e343bd4760e..45dd3ca2c737d 100644 +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -103,6 +103,16 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, + return ES_OK; + } + ++static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size) ++{ ++ return ES_OK; ++} ++ ++static bool fault_in_kernel_space(unsigned long address) ++{ ++ return false; ++} ++ + #undef __init + #define __init + +diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h +index b475d9a582b88..e829fa4c6788e 100644 +--- a/arch/x86/include/asm/fpu/api.h ++++ b/arch/x86/include/asm/fpu/api.h +@@ -148,7 +148,8 @@ static inline void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd) { + static inline void fpu_sync_guest_vmexit_xfd_state(void) { } + #endif + +-extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, unsigned int size, u32 pkru); ++extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, ++ unsigned int size, u64 xfeatures, u32 pkru); + extern int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf, u64 xcr0, u32 *vpkru); + + static inline void fpstate_set_confidential(struct fpu_guest *gfpu) +diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h +index e7c7379d6ac7b..3aa23b250d5e1 100644 +--- a/arch/x86/include/asm/svm.h ++++ b/arch/x86/include/asm/svm.h +@@ -268,6 +268,7 @@ enum avic_ipi_failure_cause { + AVIC_IPI_FAILURE_TARGET_NOT_RUNNING, + AVIC_IPI_FAILURE_INVALID_TARGET, + AVIC_IPI_FAILURE_INVALID_BACKING_PAGE, ++ AVIC_IPI_FAILURE_INVALID_IPI_VECTOR, + }; + + #define AVIC_PHYSICAL_MAX_INDEX_MASK GENMASK_ULL(8, 0) +diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c +index 98e507cc7d34c..b582325b9c374 100644 +--- a/arch/x86/kernel/fpu/core.c ++++ b/arch/x86/kernel/fpu/core.c +@@ -369,14 +369,15 @@ int fpu_swap_kvm_fpstate(struct fpu_guest *guest_fpu, bool enter_guest) + EXPORT_SYMBOL_GPL(fpu_swap_kvm_fpstate); + + void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, +- unsigned int size, u32 pkru) ++ unsigned int size, u64 xfeatures, u32 pkru) + { + struct fpstate *kstate = gfpu->fpstate; + union fpregs_state *ustate = buf; + struct membuf mb = { .p = buf, .left = size }; + + if (cpu_feature_enabled(X86_FEATURE_XSAVE)) { +- __copy_xstate_to_uabi_buf(mb, kstate, pkru, XSTATE_COPY_XSAVE); ++ __copy_xstate_to_uabi_buf(mb, kstate, xfeatures, pkru, ++ XSTATE_COPY_XSAVE); + } else { + memcpy(&ustate->fxsave, &kstate->regs.fxsave, + sizeof(ustate->fxsave)); +diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c +index 1afbc4866b100..ebe698f8af73b 100644 +--- a/arch/x86/kernel/fpu/xstate.c ++++ b/arch/x86/kernel/fpu/xstate.c +@@ -1053,6 +1053,7 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, + * __copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer + * @to: membuf descriptor + * @fpstate: The fpstate buffer from which to copy ++ * @xfeatures: The mask of xfeatures to save (XSAVE mode only) + * @pkru_val: The PKRU value to store in the PKRU component + * @copy_mode: The requested copy mode + * +@@ -1063,7 +1064,8 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, + * It supports partial copy but @to.pos always starts from zero. + */ + void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, +- u32 pkru_val, enum xstate_copy_mode copy_mode) ++ u64 xfeatures, u32 pkru_val, ++ enum xstate_copy_mode copy_mode) + { + const unsigned int off_mxcsr = offsetof(struct fxregs_state, mxcsr); + struct xregs_state *xinit = &init_fpstate.regs.xsave; +@@ -1087,7 +1089,7 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, + break; + + case XSTATE_COPY_XSAVE: +- header.xfeatures &= fpstate->user_xfeatures; ++ header.xfeatures &= fpstate->user_xfeatures & xfeatures; + break; + } + +@@ -1189,6 +1191,7 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, + enum xstate_copy_mode copy_mode) + { + __copy_xstate_to_uabi_buf(to, tsk->thread.fpu.fpstate, ++ tsk->thread.fpu.fpstate->user_xfeatures, + tsk->thread.pkru, copy_mode); + } + +@@ -1540,10 +1543,7 @@ static int fpstate_realloc(u64 xfeatures, unsigned int ksize, + fpregs_restore_userregs(); + + newfps->xfeatures = curfps->xfeatures | xfeatures; +- +- if (!guest_fpu) +- newfps->user_xfeatures = curfps->user_xfeatures | xfeatures; +- ++ newfps->user_xfeatures = curfps->user_xfeatures | xfeatures; + newfps->xfd = curfps->xfd & ~xfeatures; + + /* Do the final updates within the locked region */ +diff --git a/arch/x86/kernel/fpu/xstate.h b/arch/x86/kernel/fpu/xstate.h +index a4ecb04d8d646..3518fb26d06b0 100644 +--- a/arch/x86/kernel/fpu/xstate.h ++++ b/arch/x86/kernel/fpu/xstate.h +@@ -43,7 +43,8 @@ enum xstate_copy_mode { + + struct membuf; + extern void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, +- u32 pkru_val, enum xstate_copy_mode copy_mode); ++ u64 xfeatures, u32 pkru_val, ++ enum xstate_copy_mode copy_mode); + extern void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, + enum xstate_copy_mode mode); + extern int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf, u32 *pkru); +diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c +index dcf325b7b0229..ccb0915e84e10 100644 +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -632,6 +632,23 @@ fail: + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); + } + ++static enum es_result vc_insn_string_check(struct es_em_ctxt *ctxt, ++ unsigned long address, ++ bool write) ++{ ++ if (user_mode(ctxt->regs) && fault_in_kernel_space(address)) { ++ ctxt->fi.vector = X86_TRAP_PF; ++ ctxt->fi.error_code = X86_PF_USER; ++ ctxt->fi.cr2 = address; ++ if (write) ++ ctxt->fi.error_code |= X86_PF_WRITE; ++ ++ return ES_EXCEPTION; ++ } ++ ++ return ES_OK; ++} ++ + static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, + void *src, char *buf, + unsigned int data_size, +@@ -639,7 +656,12 @@ static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, + bool backwards) + { + int i, b = backwards ? -1 : 1; +- enum es_result ret = ES_OK; ++ unsigned long address = (unsigned long)src; ++ enum es_result ret; ++ ++ ret = vc_insn_string_check(ctxt, address, false); ++ if (ret != ES_OK) ++ return ret; + + for (i = 0; i < count; i++) { + void *s = src + (i * data_size * b); +@@ -660,7 +682,12 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt, + bool backwards) + { + int i, s = backwards ? -1 : 1; +- enum es_result ret = ES_OK; ++ unsigned long address = (unsigned long)dst; ++ enum es_result ret; ++ ++ ret = vc_insn_string_check(ctxt, address, true); ++ if (ret != ES_OK) ++ return ret; + + for (i = 0; i < count; i++) { + void *d = dst + (i * data_size * s); +@@ -696,6 +723,9 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt, + static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + { + struct insn *insn = &ctxt->insn; ++ size_t size; ++ u64 port; ++ + *exitinfo = 0; + + switch (insn->opcode.bytes[0]) { +@@ -704,7 +734,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + case 0x6d: + *exitinfo |= IOIO_TYPE_INS; + *exitinfo |= IOIO_SEG_ES; +- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; ++ port = ctxt->regs->dx & 0xffff; + break; + + /* OUTS opcodes */ +@@ -712,41 +742,43 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + case 0x6f: + *exitinfo |= IOIO_TYPE_OUTS; + *exitinfo |= IOIO_SEG_DS; +- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; ++ port = ctxt->regs->dx & 0xffff; + break; + + /* IN immediate opcodes */ + case 0xe4: + case 0xe5: + *exitinfo |= IOIO_TYPE_IN; +- *exitinfo |= (u8)insn->immediate.value << 16; ++ port = (u8)insn->immediate.value & 0xffff; + break; + + /* OUT immediate opcodes */ + case 0xe6: + case 0xe7: + *exitinfo |= IOIO_TYPE_OUT; +- *exitinfo |= (u8)insn->immediate.value << 16; ++ port = (u8)insn->immediate.value & 0xffff; + break; + + /* IN register opcodes */ + case 0xec: + case 0xed: + *exitinfo |= IOIO_TYPE_IN; +- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; ++ port = ctxt->regs->dx & 0xffff; + break; + + /* OUT register opcodes */ + case 0xee: + case 0xef: + *exitinfo |= IOIO_TYPE_OUT; +- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; ++ port = ctxt->regs->dx & 0xffff; + break; + + default: + return ES_DECODE_FAILED; + } + ++ *exitinfo |= port << 16; ++ + switch (insn->opcode.bytes[0]) { + case 0x6c: + case 0x6e: +@@ -756,12 +788,15 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + case 0xee: + /* Single byte opcodes */ + *exitinfo |= IOIO_DATA_8; ++ size = 1; + break; + default: + /* Length determined by instruction parsing */ + *exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16 + : IOIO_DATA_32; ++ size = (insn->opnd_bytes == 2) ? 2 : 4; + } ++ + switch (insn->addr_bytes) { + case 2: + *exitinfo |= IOIO_ADDR_16; +@@ -777,7 +812,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + if (insn_has_rep_prefix(insn)) + *exitinfo |= IOIO_REP; + +- return ES_OK; ++ return vc_ioio_check(ctxt, (u16)port, size); + } + + static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) +diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c +index 2b0342a03c1ba..60ea3f1a9653e 100644 +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -524,6 +524,33 @@ static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt + return ES_OK; + } + ++static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size) ++{ ++ BUG_ON(size > 4); ++ ++ if (user_mode(ctxt->regs)) { ++ struct thread_struct *t = ¤t->thread; ++ struct io_bitmap *iobm = t->io_bitmap; ++ size_t idx; ++ ++ if (!iobm) ++ goto fault; ++ ++ for (idx = port; idx < port + size; ++idx) { ++ if (test_bit(idx, iobm->bitmap)) ++ goto fault; ++ } ++ } ++ ++ return ES_OK; ++ ++fault: ++ ctxt->fi.vector = X86_TRAP_GP; ++ ctxt->fi.error_code = 0; ++ ++ return ES_EXCEPTION; ++} ++ + /* Include code shared with pre-decompression boot stage */ + #include "sev-shared.c" + +@@ -1508,6 +1535,9 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) + return ES_DECODE_FAILED; + } + ++ if (user_mode(ctxt->regs)) ++ return ES_UNSUPPORTED; ++ + switch (mmio) { + case INSN_MMIO_WRITE: + memcpy(ghcb->shared_buffer, reg_data, bytes); +diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c +index d3432687c9e63..7bdc66abfc92f 100644 +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -326,14 +326,6 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) + vcpu->arch.guest_supported_xcr0 = + cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent); + +- /* +- * FP+SSE can always be saved/restored via KVM_{G,S}ET_XSAVE, even if +- * XSAVE/XCRO are not exposed to the guest, and even if XSAVE isn't +- * supported by the host. +- */ +- vcpu->arch.guest_fpu.fpstate->user_xfeatures = vcpu->arch.guest_supported_xcr0 | +- XFEATURE_MASK_FPSSE; +- + kvm_update_pv_runtime(vcpu); + + vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index a983a16163b13..e74e223f46aa3 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -2738,13 +2738,17 @@ int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type) + { + u32 reg = kvm_lapic_get_reg(apic, lvt_type); + int vector, mode, trig_mode; ++ int r; + + if (kvm_apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) { + vector = reg & APIC_VECTOR_MASK; + mode = reg & APIC_MODE_MASK; + trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; +- return __apic_accept_irq(apic, mode, vector, 1, trig_mode, +- NULL); ++ ++ r = __apic_accept_irq(apic, mode, vector, 1, trig_mode, NULL); ++ if (r && lvt_type == APIC_LVTPC) ++ kvm_lapic_set_reg(apic, APIC_LVTPC, reg | APIC_LVT_MASKED); ++ return r; + } + return 0; + } +diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h +index 7d9ba301c0906..1d64113de4883 100644 +--- a/arch/x86/kvm/pmu.h ++++ b/arch/x86/kvm/pmu.h +@@ -74,6 +74,12 @@ static inline u64 pmc_read_counter(struct kvm_pmc *pmc) + return counter & pmc_bitmask(pmc); + } + ++static inline void pmc_write_counter(struct kvm_pmc *pmc, u64 val) ++{ ++ pmc->counter += val - pmc_read_counter(pmc); ++ pmc->counter &= pmc_bitmask(pmc); ++} ++ + static inline void pmc_release_perf_event(struct kvm_pmc *pmc) + { + if (pmc->perf_event) { +diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c +index 2092db892d7d0..4b74ea91f4e6b 100644 +--- a/arch/x86/kvm/svm/avic.c ++++ b/arch/x86/kvm/svm/avic.c +@@ -529,8 +529,11 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu) + case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE: + WARN_ONCE(1, "Invalid backing page\n"); + break; ++ case AVIC_IPI_FAILURE_INVALID_IPI_VECTOR: ++ /* Invalid IPI with vector < 16 */ ++ break; + default: +- pr_err("Unknown IPI interception\n"); ++ vcpu_unimpl(vcpu, "Unknown avic incomplete IPI interception\n"); + } + + return 1; +diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c +index c66c823ae222a..36482780a42f5 100644 +--- a/arch/x86/kvm/svm/nested.c ++++ b/arch/x86/kvm/svm/nested.c +@@ -1243,6 +1243,9 @@ void svm_leave_nested(struct kvm_vcpu *vcpu) + + nested_svm_uninit_mmu_context(vcpu); + vmcb_mark_all_dirty(svm->vmcb); ++ ++ if (kvm_apicv_activated(vcpu->kvm)) ++ kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu); + } + + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); +diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c +index cef5a3d0abd09..373ff6a6687b3 100644 +--- a/arch/x86/kvm/svm/pmu.c ++++ b/arch/x86/kvm/svm/pmu.c +@@ -160,7 +160,7 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + /* MSR_PERFCTRn */ + pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER); + if (pmc) { +- pmc->counter += data - pmc_read_counter(pmc); ++ pmc_write_counter(pmc, data); + pmc_update_sample_period(pmc); + return 0; + } +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index e3d92670c1115..c8466bc64b873 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -829,8 +829,7 @@ void svm_set_x2apic_msr_interception(struct vcpu_svm *svm, bool intercept) + if (intercept == svm->x2avic_msrs_intercepted) + return; + +- if (!x2avic_enabled || +- !apic_x2apic_mode(svm->vcpu.arch.apic)) ++ if (!x2avic_enabled) + return; + + for (i = 0; i < MAX_DIRECT_ACCESS_MSRS; i++) { +diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c +index 80c769c58a876..18a658aa2a8d2 100644 +--- a/arch/x86/kvm/vmx/pmu_intel.c ++++ b/arch/x86/kvm/vmx/pmu_intel.c +@@ -406,11 +406,11 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + if (!msr_info->host_initiated && + !(msr & MSR_PMC_FULL_WIDTH_BIT)) + data = (s64)(s32)data; +- pmc->counter += data - pmc_read_counter(pmc); ++ pmc_write_counter(pmc, data); + pmc_update_sample_period(pmc); + break; + } else if ((pmc = get_fixed_pmc(pmu, msr))) { +- pmc->counter += data - pmc_read_counter(pmc); ++ pmc_write_counter(pmc, data); + pmc_update_sample_period(pmc); + break; + } else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) { +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index e24bbc8d1fc19..7bcf1a76a6abc 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -5385,26 +5385,37 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, + return 0; + } + +-static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, +- struct kvm_xsave *guest_xsave) +-{ +- if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) +- return; +- +- fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, +- guest_xsave->region, +- sizeof(guest_xsave->region), +- vcpu->arch.pkru); +-} + + static void kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu, + u8 *state, unsigned int size) + { ++ /* ++ * Only copy state for features that are enabled for the guest. The ++ * state itself isn't problematic, but setting bits in the header for ++ * features that are supported in *this* host but not exposed to the ++ * guest can result in KVM_SET_XSAVE failing when live migrating to a ++ * compatible host without the features that are NOT exposed to the ++ * guest. ++ * ++ * FP+SSE can always be saved/restored via KVM_{G,S}ET_XSAVE, even if ++ * XSAVE/XCRO are not exposed to the guest, and even if XSAVE isn't ++ * supported by the host. ++ */ ++ u64 supported_xcr0 = vcpu->arch.guest_supported_xcr0 | ++ XFEATURE_MASK_FPSSE; ++ + if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) + return; + +- fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, +- state, size, vcpu->arch.pkru); ++ fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, state, size, ++ supported_xcr0, vcpu->arch.pkru); ++} ++ ++static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, ++ struct kvm_xsave *guest_xsave) ++{ ++ return kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region, ++ sizeof(guest_xsave->region)); + } + + static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, +diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c +index 773e159dbbcb8..a957304304be3 100644 +--- a/crypto/asymmetric_keys/public_key.c ++++ b/crypto/asymmetric_keys/public_key.c +@@ -81,14 +81,13 @@ software_key_determine_akcipher(const struct public_key *pkey, + * RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2]. + */ + if (strcmp(encoding, "pkcs1") == 0) { ++ *sig = op == kernel_pkey_sign || ++ op == kernel_pkey_verify; + if (!hash_algo) { +- *sig = false; + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, + "pkcs1pad(%s)", + pkey->pkey_algo); + } else { +- *sig = op == kernel_pkey_sign || +- op == kernel_pkey_verify; + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, + "pkcs1pad(%s,%s)", + pkey->pkey_algo, hash_algo); +diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c +index 8396db2b52030..09dee5be20700 100644 +--- a/drivers/accel/ivpu/ivpu_drv.c ++++ b/drivers/accel/ivpu/ivpu_drv.c +@@ -303,7 +303,7 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev) + } + + if (!ret) +- ivpu_info(vdev, "VPU ready message received successfully\n"); ++ ivpu_dbg(vdev, PM, "VPU ready message received successfully\n"); + else + ivpu_hw_diagnose_failure(vdev); + +diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c +index 93c69aaa6218d..34e4026c77589 100644 +--- a/drivers/accel/ivpu/ivpu_fw.c ++++ b/drivers/accel/ivpu/ivpu_fw.c +@@ -195,8 +195,7 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev) + if (ret) + return ret; + +- fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, +- DRM_IVPU_BO_CACHED | DRM_IVPU_BO_NOSNOOP); ++ fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, DRM_IVPU_BO_WC); + if (!fw->mem) { + ivpu_err(vdev, "Failed to allocate firmware runtime memory\n"); + return -ENOMEM; +@@ -273,7 +272,7 @@ int ivpu_fw_load(struct ivpu_device *vdev) + memset(start, 0, size); + } + +- clflush_cache_range(fw->mem->kvaddr, fw->mem->base.size); ++ wmb(); /* Flush WC buffers after writing fw->mem */ + + return 0; + } +@@ -375,7 +374,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params + if (!ivpu_fw_is_cold_boot(vdev)) { + boot_params->save_restore_ret_address = 0; + vdev->pm->is_warmboot = true; +- clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K); ++ wmb(); /* Flush WC buffers after writing save_restore_ret_address */ + return; + } + +@@ -430,7 +429,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params + boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev); + boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev); + +- clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K); ++ wmb(); /* Flush WC buffers after writing bootparams */ + + ivpu_fw_boot_params_print(vdev, boot_params); + } +diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h +index f4130586ff1b2..6b0ceda5f2537 100644 +--- a/drivers/accel/ivpu/ivpu_gem.h ++++ b/drivers/accel/ivpu/ivpu_gem.h +@@ -8,8 +8,6 @@ + #include + #include + +-#define DRM_IVPU_BO_NOSNOOP 0x10000000 +- + struct dma_buf; + struct ivpu_bo_ops; + struct ivpu_file_priv; +@@ -85,9 +83,6 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo) + + static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo) + { +- if (bo->flags & DRM_IVPU_BO_NOSNOOP) +- return false; +- + return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED; + } + +diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c +index 2fc2b43a4ed38..6d3b878a13588 100644 +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -1387,10 +1387,10 @@ static int __init acpi_init(void) + acpi_init_ffh(); + + pci_mmcfg_late_init(); +- acpi_arm_init(); + acpi_viot_early_init(); + acpi_hest_init(); + acpi_ghes_init(); ++ acpi_arm_init(); + acpi_scan_init(); + acpi_ec_init(); + acpi_debugfs_init(); +diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c +index c2c786eb95abc..1687483ff319e 100644 +--- a/drivers/acpi/irq.c ++++ b/drivers/acpi/irq.c +@@ -57,6 +57,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, + int polarity) + { + struct irq_fwspec fwspec; ++ unsigned int irq; + + fwspec.fwnode = acpi_get_gsi_domain_id(gsi); + if (WARN_ON(!fwspec.fwnode)) { +@@ -68,7 +69,11 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, + fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); + fwspec.param_count = 2; + +- return irq_create_fwspec_mapping(&fwspec); ++ irq = irq_create_fwspec_mapping(&fwspec); ++ if (!irq) ++ return -EINVAL; ++ ++ return irq; + } + EXPORT_SYMBOL_GPL(acpi_register_gsi); + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 2a21f4d9500db..97a842b57a751 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -2624,7 +2624,7 @@ static int ata_dev_config_lba(struct ata_device *dev) + { + const u16 *id = dev->id; + const char *lba_desc; +- char ncq_desc[24]; ++ char ncq_desc[32]; + int ret; + + dev->flags |= ATA_DFLAG_LBA; +diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c +index 150e7ab62d1ae..e7c4edb04f8ed 100644 +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2366,7 +2366,7 @@ static void ata_eh_link_report(struct ata_link *link) + struct ata_eh_context *ehc = &link->eh_context; + struct ata_queued_cmd *qc; + const char *frozen, *desc; +- char tries_buf[6] = ""; ++ char tries_buf[16] = ""; + int tag, nr_failed = 0; + + if (ehc->i.flags & ATA_EHI_QUIET) +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index 1bfd1727b4da7..bb2f41043f602 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -1572,7 +1572,7 @@ static int dev_get_regmap_match(struct device *dev, void *res, void *data) + + /* If the user didn't specify a name match any */ + if (data) +- return !strcmp((*r)->name, data); ++ return (*r)->name && !strcmp((*r)->name, data); + else + return 1; + } +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index dfdfb72d350fe..ca9e2a210fff2 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -4348,6 +4348,7 @@ static int btusb_probe(struct usb_interface *intf, + + if (id->driver_info & BTUSB_QCA_ROME) { + data->setup_on_usb = btusb_setup_qca; ++ hdev->shutdown = btusb_shutdown_qca; + hdev->set_bdaddr = btusb_set_bdaddr_ath3012; + hdev->cmd_timeout = btusb_qca_cmd_timeout; + set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); +diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c +index 40e2b9fa11a26..f3892e9ce800f 100644 +--- a/drivers/bluetooth/hci_vhci.c ++++ b/drivers/bluetooth/hci_vhci.c +@@ -74,7 +74,10 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) + struct vhci_data *data = hci_get_drvdata(hdev); + + memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); ++ ++ mutex_lock(&data->open_mutex); + skb_queue_tail(&data->readq, skb); ++ mutex_unlock(&data->open_mutex); + + wake_up_interruptible(&data->read_wait); + return 0; +diff --git a/drivers/firmware/efi/unaccepted_memory.c b/drivers/firmware/efi/unaccepted_memory.c +index 853f7dc3c21d8..135278ddaf627 100644 +--- a/drivers/firmware/efi/unaccepted_memory.c ++++ b/drivers/firmware/efi/unaccepted_memory.c +@@ -5,9 +5,17 @@ + #include + #include + +-/* Protects unaccepted memory bitmap */ ++/* Protects unaccepted memory bitmap and accepting_list */ + static DEFINE_SPINLOCK(unaccepted_memory_lock); + ++struct accept_range { ++ struct list_head list; ++ unsigned long start; ++ unsigned long end; ++}; ++ ++static LIST_HEAD(accepting_list); ++ + /* + * accept_memory() -- Consult bitmap and accept the memory if needed. + * +@@ -24,6 +32,7 @@ void accept_memory(phys_addr_t start, phys_addr_t end) + { + struct efi_unaccepted_memory *unaccepted; + unsigned long range_start, range_end; ++ struct accept_range range, *entry; + unsigned long flags; + u64 unit_size; + +@@ -78,20 +87,67 @@ void accept_memory(phys_addr_t start, phys_addr_t end) + if (end > unaccepted->size * unit_size * BITS_PER_BYTE) + end = unaccepted->size * unit_size * BITS_PER_BYTE; + +- range_start = start / unit_size; +- ++ range.start = start / unit_size; ++ range.end = DIV_ROUND_UP(end, unit_size); ++retry: + spin_lock_irqsave(&unaccepted_memory_lock, flags); ++ ++ /* ++ * Check if anybody works on accepting the same range of the memory. ++ * ++ * The check is done with unit_size granularity. It is crucial to catch ++ * all accept requests to the same unit_size block, even if they don't ++ * overlap on physical address level. ++ */ ++ list_for_each_entry(entry, &accepting_list, list) { ++ if (entry->end < range.start) ++ continue; ++ if (entry->start >= range.end) ++ continue; ++ ++ /* ++ * Somebody else accepting the range. Or at least part of it. ++ * ++ * Drop the lock and retry until it is complete. ++ */ ++ spin_unlock_irqrestore(&unaccepted_memory_lock, flags); ++ goto retry; ++ } ++ ++ /* ++ * Register that the range is about to be accepted. ++ * Make sure nobody else will accept it. ++ */ ++ list_add(&range.list, &accepting_list); ++ ++ range_start = range.start; + for_each_set_bitrange_from(range_start, range_end, unaccepted->bitmap, +- DIV_ROUND_UP(end, unit_size)) { ++ range.end) { + unsigned long phys_start, phys_end; + unsigned long len = range_end - range_start; + + phys_start = range_start * unit_size + unaccepted->phys_base; + phys_end = range_end * unit_size + unaccepted->phys_base; + ++ /* ++ * Keep interrupts disabled until the accept operation is ++ * complete in order to prevent deadlocks. ++ * ++ * Enabling interrupts before calling arch_accept_memory() ++ * creates an opportunity for an interrupt handler to request ++ * acceptance for the same memory. The handler will continuously ++ * spin with interrupts disabled, preventing other task from ++ * making progress with the acceptance process. ++ */ ++ spin_unlock(&unaccepted_memory_lock); ++ + arch_accept_memory(phys_start, phys_end); ++ ++ spin_lock(&unaccepted_memory_lock); + bitmap_clear(unaccepted->bitmap, range_start, len); + } ++ ++ list_del(&range.list); + spin_unlock_irqrestore(&unaccepted_memory_lock, flags); + } + +diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c +index de14949a3fe5a..92c1f2baa4bff 100644 +--- a/drivers/gpio/gpio-timberdale.c ++++ b/drivers/gpio/gpio-timberdale.c +@@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, + unsigned offset, bool enabled) + { + struct timbgpio *tgpio = gpiochip_get_data(gpio); ++ unsigned long flags; + u32 reg; + +- spin_lock(&tgpio->lock); ++ spin_lock_irqsave(&tgpio->lock, flags); + reg = ioread32(tgpio->membase + offset); + + if (enabled) +@@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, + reg &= ~(1 << index); + + iowrite32(reg, tgpio->membase + offset); +- spin_unlock(&tgpio->lock); ++ spin_unlock_irqrestore(&tgpio->lock, flags); + + return 0; + } +diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c +index d3f3a69d49077..314dfaa633857 100644 +--- a/drivers/gpio/gpio-vf610.c ++++ b/drivers/gpio/gpio-vf610.c +@@ -127,14 +127,14 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, + unsigned long mask = BIT(gpio); + u32 val; + ++ vf610_gpio_set(chip, gpio, value); ++ + if (port->sdata && port->sdata->have_paddr) { + val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR); + val |= mask; + vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR); + } + +- vf610_gpio_set(chip, gpio, value); +- + return pinctrl_gpio_direction_output(chip->base + gpio); + } + +@@ -247,7 +247,8 @@ static const struct irq_chip vf610_irqchip = { + .irq_unmask = vf610_gpio_irq_unmask, + .irq_set_type = vf610_gpio_irq_set_type, + .irq_set_wake = vf610_gpio_irq_set_wake, +- .flags = IRQCHIP_IMMUTABLE, ++ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND ++ | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND, + GPIOCHIP_IRQ_RESOURCE_HELPERS, + }; + +diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c +index 97496c0f91330..a775d2bdac94f 100644 +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -951,6 +951,7 @@ static struct gpio_desc *acpi_get_gpiod_from_data(struct fwnode_handle *fwnode, + if (!propname) + return ERR_PTR(-EINVAL); + ++ memset(&lookup, 0, sizeof(lookup)); + lookup.index = index; + + ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +index ec1ec08d40584..7a67bb1490159 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -1094,7 +1094,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, + struct drm_gem_object *gobj = dma_buf->priv; + struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj); + +- if (abo->tbo.resource->mem_type == TTM_PL_VRAM) ++ if (abo->tbo.resource && ++ abo->tbo.resource->mem_type == TTM_PL_VRAM) + bo = gem_to_amdgpu_bo(gobj); + } + mem = bo->tbo.resource; +diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c +index d68fe5474676b..7f7a476b6829c 100644 +--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c ++++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c +@@ -2077,6 +2077,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ + case IP_VERSION(11, 0, 0): + case IP_VERSION(11, 0, 1): + case IP_VERSION(11, 0, 2): ++ case IP_VERSION(11, 0, 3): + *states = ATTR_STATE_SUPPORTED; + break; + default: +diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +index f448b903e1907..84148a79414b7 100644 +--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c ++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +@@ -692,7 +692,7 @@ static struct ti_sn65dsi86 *bridge_to_ti_sn65dsi86(struct drm_bridge *bridge) + return container_of(bridge, struct ti_sn65dsi86, bridge); + } + +-static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) ++static int ti_sn_attach_host(struct auxiliary_device *adev, struct ti_sn65dsi86 *pdata) + { + int val; + struct mipi_dsi_host *host; +@@ -707,7 +707,7 @@ static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) + if (!host) + return -EPROBE_DEFER; + +- dsi = devm_mipi_dsi_device_register_full(dev, host, &info); ++ dsi = devm_mipi_dsi_device_register_full(&adev->dev, host, &info); + if (IS_ERR(dsi)) + return PTR_ERR(dsi); + +@@ -725,7 +725,7 @@ static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) + + pdata->dsi = dsi; + +- return devm_mipi_dsi_attach(dev, dsi); ++ return devm_mipi_dsi_attach(&adev->dev, dsi); + } + + static int ti_sn_bridge_attach(struct drm_bridge *bridge, +@@ -1298,9 +1298,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, + struct device_node *np = pdata->dev->of_node; + int ret; + +- pdata->next_bridge = devm_drm_of_get_bridge(pdata->dev, np, 1, 0); ++ pdata->next_bridge = devm_drm_of_get_bridge(&adev->dev, np, 1, 0); + if (IS_ERR(pdata->next_bridge)) +- return dev_err_probe(pdata->dev, PTR_ERR(pdata->next_bridge), ++ return dev_err_probe(&adev->dev, PTR_ERR(pdata->next_bridge), + "failed to create panel bridge\n"); + + ti_sn_bridge_parse_lanes(pdata, np); +@@ -1319,9 +1319,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, + + drm_bridge_add(&pdata->bridge); + +- ret = ti_sn_attach_host(pdata); ++ ret = ti_sn_attach_host(adev, pdata); + if (ret) { +- dev_err_probe(pdata->dev, ret, "failed to attach dsi host\n"); ++ dev_err_probe(&adev->dev, ret, "failed to attach dsi host\n"); + goto err_remove_bridge; + } + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 9271e47d66572..69d855123d3e3 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -123,6 +123,9 @@ static const struct edid_quirk { + /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */ + EDID_QUIRK('A', 'E', 'O', 0, EDID_QUIRK_FORCE_6BPC), + ++ /* BenQ GW2765 */ ++ EDID_QUIRK('B', 'N', 'Q', 0x78d6, EDID_QUIRK_FORCE_8BPC), ++ + /* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc panel */ + EDID_QUIRK('B', 'O', 'E', 0x78b, EDID_QUIRK_FORCE_6BPC), + +diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c +index 0cb646cb04ee1..d5c15292ae937 100644 +--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c ++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c +@@ -38,6 +38,14 @@ static const struct drm_dmi_panel_orientation_data gpd_micropc = { + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, + }; + ++static const struct drm_dmi_panel_orientation_data gpd_onemix2s = { ++ .width = 1200, ++ .height = 1920, ++ .bios_dates = (const char * const []){ "05/21/2018", "10/26/2018", ++ "03/04/2019", NULL }, ++ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, ++}; ++ + static const struct drm_dmi_panel_orientation_data gpd_pocket = { + .width = 1200, + .height = 1920, +@@ -401,6 +409,14 @@ static const struct dmi_system_id orientation_data[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, ++ }, { /* One Mix 2S (generic strings, also match on bios date) */ ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), ++ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), ++ }, ++ .driver_data = (void *)&gpd_onemix2s, + }, + {} + }; +diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c +index 719447ce86e70..974dd52e720c1 100644 +--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c ++++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c +@@ -2554,8 +2554,7 @@ static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915, + drm_warn(&i915->drm, "PHY %c failed to bring out of SOC reset after %dus.\n", + phy_name(phy), XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US); + +- intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port), +- XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1), ++ intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port), lane_pipe_reset, + lane_pipe_reset); + + if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL2(port), +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c +index aa4d842d4c5a8..310654542b42c 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c +@@ -235,6 +235,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err) + case 0: + case -EAGAIN: + case -ENOSPC: /* transient failure to evict? */ ++ case -ENOBUFS: /* temporarily out of fences? */ + case -ERESTARTSYS: + case -EINTR: + case -EBUSY: +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c +index 9f364df52478d..0e0a41b2f57f0 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c +@@ -239,6 +239,7 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) + npages = obj->size >> PAGE_SHIFT; + mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL); + if (!mtk_gem->pages) { ++ sg_free_table(sgt); + kfree(sgt); + return -ENOMEM; + } +@@ -248,12 +249,15 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) + mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); + if (!mtk_gem->kvaddr) { ++ sg_free_table(sgt); + kfree(sgt); + kfree(mtk_gem->pages); + return -ENOMEM; + } +-out: ++ sg_free_table(sgt); + kfree(sgt); ++ ++out: + iosys_map_set_vaddr(map, mtk_gem->kvaddr); + + return 0; +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c +index 46b057fe1412e..3249e5c1c8930 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c +@@ -62,6 +62,18 @@ nvkm_uconn_uevent_gpio(struct nvkm_object *object, u64 token, u32 bits) + return object->client->event(token, &args, sizeof(args.v0)); + } + ++static bool ++nvkm_connector_is_dp_dms(u8 type) ++{ ++ switch (type) { ++ case DCB_CONNECTOR_DMS59_DP0: ++ case DCB_CONNECTOR_DMS59_DP1: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static int + nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent) + { +@@ -101,7 +113,7 @@ nvkm_uconn_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_ + if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO; + if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ) { + /* TODO: support DP IRQ on ANX9805 and remove this hack. */ +- if (!outp->info.location) ++ if (!outp->info.location && !nvkm_connector_is_dp_dms(conn->info.type)) + return -EINVAL; + } + +diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c +index 403506b9697e7..b346d68a06f5a 100644 +--- a/drivers/hid/hid-holtek-kbd.c ++++ b/drivers/hid/hid-holtek-kbd.c +@@ -130,6 +130,10 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type, + return -ENODEV; + + boot_hid = usb_get_intfdata(boot_interface); ++ if (list_empty(&boot_hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } + boot_hid_input = list_first_entry(&boot_hid->inputs, + struct hid_input, list); + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 8a310f8ff20f5..cc0d0186a0d95 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -425,6 +425,7 @@ + #define I2C_DEVICE_ID_HP_SPECTRE_X360_13T_AW100 0x29F5 + #define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V1 0x2BED + #define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2 0x2BEE ++#define I2C_DEVICE_ID_HP_ENVY_X360_15_EU0556NG 0x2D02 + + #define USB_VENDOR_ID_ELECOM 0x056e + #define USB_DEVICE_ID_ELECOM_BM084 0x0061 +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index 40a5645f8fe81..5e2f721855e59 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -406,6 +406,8 @@ static const struct hid_device_id hid_battery_quirks[] = { + HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2), + HID_BATTERY_QUIRK_IGNORE }, ++ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15_EU0556NG), ++ HID_BATTERY_QUIRK_IGNORE }, + {} + }; + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index 1c00e4121c7ef..08b68f8476dbb 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -4676,6 +4676,8 @@ static const struct hid_device_id hidpp_devices[] = { + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb008) }, + { /* MX Master mouse over Bluetooth */ + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012) }, ++ { /* M720 Triathlon mouse over Bluetooth */ ++ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb015) }, + { /* MX Ergo trackball over Bluetooth */ + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01d) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e) }, +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 521b2ffb42449..8db4ae05febc8 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -2144,6 +2144,10 @@ static const struct hid_device_id mt_devices[] = { + USB_DEVICE_ID_MTP_STM)}, + + /* Synaptics devices */ ++ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, ++ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, ++ USB_VENDOR_ID_SYNAPTICS, 0xcd7e) }, ++ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_SYNAPTICS, 0xce08) }, +diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c +index 250f5d2f888ab..10468f727e5bb 100644 +--- a/drivers/hid/hid-nintendo.c ++++ b/drivers/hid/hid-nintendo.c +@@ -2088,7 +2088,9 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) + struct joycon_input_report *report; + + req.subcmd_id = JC_SUBCMD_REQ_DEV_INFO; ++ mutex_lock(&ctlr->output_mutex); + ret = joycon_send_subcmd(ctlr, &req, 0, HZ); ++ mutex_unlock(&ctlr->output_mutex); + if (ret) { + hid_err(ctlr->hdev, "Failed to get joycon info; ret=%d\n", ret); + return ret; +@@ -2117,6 +2119,85 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) + return 0; + } + ++static int joycon_init(struct hid_device *hdev) ++{ ++ struct joycon_ctlr *ctlr = hid_get_drvdata(hdev); ++ int ret = 0; ++ ++ mutex_lock(&ctlr->output_mutex); ++ /* if handshake command fails, assume ble pro controller */ ++ if ((jc_type_is_procon(ctlr) || jc_type_is_chrggrip(ctlr)) && ++ !joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ)) { ++ hid_dbg(hdev, "detected USB controller\n"); ++ /* set baudrate for improved latency */ ++ ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M, HZ); ++ if (ret) { ++ hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ /* handshake */ ++ ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ); ++ if (ret) { ++ hid_err(hdev, "Failed handshake; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ /* ++ * Set no timeout (to keep controller in USB mode). ++ * This doesn't send a response, so ignore the timeout. ++ */ ++ joycon_send_usb(ctlr, JC_USB_CMD_NO_TIMEOUT, HZ/10); ++ } else if (jc_type_is_chrggrip(ctlr)) { ++ hid_err(hdev, "Failed charging grip handshake\n"); ++ ret = -ETIMEDOUT; ++ goto out_unlock; ++ } ++ ++ /* get controller calibration data, and parse it */ ++ ret = joycon_request_calibration(ctlr); ++ if (ret) { ++ /* ++ * We can function with default calibration, but it may be ++ * inaccurate. Provide a warning, and continue on. ++ */ ++ hid_warn(hdev, "Analog stick positions may be inaccurate\n"); ++ } ++ ++ /* get IMU calibration data, and parse it */ ++ ret = joycon_request_imu_calibration(ctlr); ++ if (ret) { ++ /* ++ * We can function with default calibration, but it may be ++ * inaccurate. Provide a warning, and continue on. ++ */ ++ hid_warn(hdev, "Unable to read IMU calibration data\n"); ++ } ++ ++ /* Set the reporting mode to 0x30, which is the full report mode */ ++ ret = joycon_set_report_mode(ctlr); ++ if (ret) { ++ hid_err(hdev, "Failed to set report mode; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ ++ /* Enable rumble */ ++ ret = joycon_enable_rumble(ctlr); ++ if (ret) { ++ hid_err(hdev, "Failed to enable rumble; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ ++ /* Enable the IMU */ ++ ret = joycon_enable_imu(ctlr); ++ if (ret) { ++ hid_err(hdev, "Failed to enable the IMU; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ ++out_unlock: ++ mutex_unlock(&ctlr->output_mutex); ++ return ret; ++} ++ + /* Common handler for parsing inputs */ + static int joycon_ctlr_read_handler(struct joycon_ctlr *ctlr, u8 *data, + int size) +@@ -2248,85 +2329,19 @@ static int nintendo_hid_probe(struct hid_device *hdev, + + hid_device_io_start(hdev); + +- /* Initialize the controller */ +- mutex_lock(&ctlr->output_mutex); +- /* if handshake command fails, assume ble pro controller */ +- if ((jc_type_is_procon(ctlr) || jc_type_is_chrggrip(ctlr)) && +- !joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ)) { +- hid_dbg(hdev, "detected USB controller\n"); +- /* set baudrate for improved latency */ +- ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M, HZ); +- if (ret) { +- hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret); +- goto err_mutex; +- } +- /* handshake */ +- ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ); +- if (ret) { +- hid_err(hdev, "Failed handshake; ret=%d\n", ret); +- goto err_mutex; +- } +- /* +- * Set no timeout (to keep controller in USB mode). +- * This doesn't send a response, so ignore the timeout. +- */ +- joycon_send_usb(ctlr, JC_USB_CMD_NO_TIMEOUT, HZ/10); +- } else if (jc_type_is_chrggrip(ctlr)) { +- hid_err(hdev, "Failed charging grip handshake\n"); +- ret = -ETIMEDOUT; +- goto err_mutex; +- } +- +- /* get controller calibration data, and parse it */ +- ret = joycon_request_calibration(ctlr); ++ ret = joycon_init(hdev); + if (ret) { +- /* +- * We can function with default calibration, but it may be +- * inaccurate. Provide a warning, and continue on. +- */ +- hid_warn(hdev, "Analog stick positions may be inaccurate\n"); +- } +- +- /* get IMU calibration data, and parse it */ +- ret = joycon_request_imu_calibration(ctlr); +- if (ret) { +- /* +- * We can function with default calibration, but it may be +- * inaccurate. Provide a warning, and continue on. +- */ +- hid_warn(hdev, "Unable to read IMU calibration data\n"); +- } +- +- /* Set the reporting mode to 0x30, which is the full report mode */ +- ret = joycon_set_report_mode(ctlr); +- if (ret) { +- hid_err(hdev, "Failed to set report mode; ret=%d\n", ret); +- goto err_mutex; +- } +- +- /* Enable rumble */ +- ret = joycon_enable_rumble(ctlr); +- if (ret) { +- hid_err(hdev, "Failed to enable rumble; ret=%d\n", ret); +- goto err_mutex; +- } +- +- /* Enable the IMU */ +- ret = joycon_enable_imu(ctlr); +- if (ret) { +- hid_err(hdev, "Failed to enable the IMU; ret=%d\n", ret); +- goto err_mutex; ++ hid_err(hdev, "Failed to initialize controller; ret=%d\n", ret); ++ goto err_close; + } + + ret = joycon_read_info(ctlr); + if (ret) { + hid_err(hdev, "Failed to retrieve controller info; ret=%d\n", + ret); +- goto err_mutex; ++ goto err_close; + } + +- mutex_unlock(&ctlr->output_mutex); +- + /* Initialize the leds */ + ret = joycon_leds_create(ctlr); + if (ret) { +@@ -2352,8 +2367,6 @@ static int nintendo_hid_probe(struct hid_device *hdev, + hid_dbg(hdev, "probe - success\n"); + return 0; + +-err_mutex: +- mutex_unlock(&ctlr->output_mutex); + err_close: + hid_hw_close(hdev); + err_stop: +@@ -2383,6 +2396,20 @@ static void nintendo_hid_remove(struct hid_device *hdev) + hid_hw_stop(hdev); + } + ++#ifdef CONFIG_PM ++ ++static int nintendo_hid_resume(struct hid_device *hdev) ++{ ++ int ret = joycon_init(hdev); ++ ++ if (ret) ++ hid_err(hdev, "Failed to restore controller after resume"); ++ ++ return ret; ++} ++ ++#endif ++ + static const struct hid_device_id nintendo_hid_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_PROCON) }, +@@ -2404,6 +2431,10 @@ static struct hid_driver nintendo_hid_driver = { + .probe = nintendo_hid_probe, + .remove = nintendo_hid_remove, + .raw_event = nintendo_hid_event, ++ ++#ifdef CONFIG_PM ++ .resume = nintendo_hid_resume, ++#endif + }; + module_hid_driver(nintendo_hid_driver); + +diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c +index 313904be5f3bd..57ff09f18c371 100644 +--- a/drivers/i2c/i2c-mux.c ++++ b/drivers/i2c/i2c-mux.c +@@ -341,7 +341,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, + priv->adap.lock_ops = &i2c_parent_lock_ops; + + /* Sanity check on class */ +- if (i2c_mux_parent_classes(parent) & class) ++ if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED) + dev_err(&parent->dev, + "Segment %d behind mux can't share classes with ancestors\n", + chan_id); +diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c +index 7c7362e288213..66433886b7b03 100644 +--- a/drivers/iio/light/vcnl4000.c ++++ b/drivers/iio/light/vcnl4000.c +@@ -994,7 +994,6 @@ static int vcnl4040_write_event_config(struct iio_dev *indio_dev, + + out: + mutex_unlock(&data->vcnl4000_lock); +- data->chip_spec->set_power_state(data, data->ps_int != 0); + + return ret; + } +diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c +index b6f4be25b31b0..b66aa5de2ddec 100644 +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -179,6 +179,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, + struct mmc_queue *mq); + static void mmc_blk_hsq_req_done(struct mmc_request *mrq); + static int mmc_spi_err_check(struct mmc_card *card); ++static int mmc_blk_busy_cb(void *cb_data, bool *busy); + + static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) + { +@@ -470,7 +471,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, + struct mmc_data data = {}; + struct mmc_request mrq = {}; + struct scatterlist sg; +- bool r1b_resp, use_r1b_resp = false; ++ bool r1b_resp; + unsigned int busy_timeout_ms; + int err; + unsigned int target_part; +@@ -551,8 +552,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, + busy_timeout_ms = idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS; + r1b_resp = (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B; + if (r1b_resp) +- use_r1b_resp = mmc_prepare_busy_cmd(card->host, &cmd, +- busy_timeout_ms); ++ mmc_prepare_busy_cmd(card->host, &cmd, busy_timeout_ms); + + mmc_wait_for_req(card->host, &mrq); + memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp)); +@@ -605,19 +605,28 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, + if (idata->ic.postsleep_min_us) + usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); + +- /* No need to poll when using HW busy detection. */ +- if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) +- return 0; +- + if (mmc_host_is_spi(card->host)) { + if (idata->ic.write_flag || r1b_resp || cmd.flags & MMC_RSP_SPI_BUSY) + return mmc_spi_err_check(card); + return err; + } +- /* Ensure RPMB/R1B command has completed by polling with CMD13. */ +- if (idata->rpmb || r1b_resp) +- err = mmc_poll_for_busy(card, busy_timeout_ms, false, +- MMC_BUSY_IO); ++ ++ /* ++ * Ensure RPMB, writes and R1B responses are completed by polling with ++ * CMD13. Note that, usually we don't need to poll when using HW busy ++ * detection, but here it's needed since some commands may indicate the ++ * error through the R1 status bits. ++ */ ++ if (idata->rpmb || idata->ic.write_flag || r1b_resp) { ++ struct mmc_blk_busy_data cb_data = { ++ .card = card, ++ }; ++ ++ err = __mmc_poll_for_busy(card->host, 0, busy_timeout_ms, ++ &mmc_blk_busy_cb, &cb_data); ++ ++ idata->ic.response[0] = cb_data.status; ++ } + + return err; + } +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index 89cd48fcec79f..4a4bab9aa7263 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -104,7 +104,7 @@ static int mmc_decode_cid(struct mmc_card *card) + case 3: /* MMC v3.1 - v3.3 */ + case 4: /* MMC v4 */ + card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); +- card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); ++ card->cid.oemid = UNSTUFF_BITS(resp, 104, 8); + card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); + card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); + card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); +diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c +index f64b9ac76a5cd..5914516df2f7f 100644 +--- a/drivers/mmc/core/sdio.c ++++ b/drivers/mmc/core/sdio.c +@@ -1089,8 +1089,14 @@ static int mmc_sdio_resume(struct mmc_host *host) + } + err = mmc_sdio_reinit_card(host); + } else if (mmc_card_wake_sdio_irq(host)) { +- /* We may have switched to 1-bit mode during suspend */ ++ /* ++ * We may have switched to 1-bit mode during suspend, ++ * need to hold retuning, because tuning only supprt ++ * 4-bit mode or 8 bit mode. ++ */ ++ mmc_retune_hold_now(host); + err = sdio_enable_4bit_bus(host->card); ++ mmc_retune_release(host); + } + + if (err) +diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c +index 02403ff99e0d4..41111c5502777 100644 +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -671,11 +671,11 @@ static void msdc_reset_hw(struct msdc_host *host) + u32 val; + + sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); +- readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0); ++ readl_poll_timeout_atomic(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0); + + sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); +- readl_poll_timeout(host->base + MSDC_FIFOCS, val, +- !(val & MSDC_FIFOCS_CLR), 0, 0); ++ readl_poll_timeout_atomic(host->base + MSDC_FIFOCS, val, ++ !(val & MSDC_FIFOCS_CLR), 0, 0); + + val = readl(host->base + MSDC_INT); + writel(val, host->base + MSDC_INT); +diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c +index ae8c307b7aa7b..109d4b010f978 100644 +--- a/drivers/mmc/host/sdhci-pci-gli.c ++++ b/drivers/mmc/host/sdhci-pci-gli.c +@@ -1144,42 +1144,6 @@ static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg) + return value; + } + +-#ifdef CONFIG_PM_SLEEP +-static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip) +-{ +- struct sdhci_pci_slot *slot = chip->slots[0]; +- +- pci_free_irq_vectors(slot->chip->pdev); +- gli_pcie_enable_msi(slot); +- +- return sdhci_pci_resume_host(chip); +-} +- +-static int sdhci_cqhci_gli_resume(struct sdhci_pci_chip *chip) +-{ +- struct sdhci_pci_slot *slot = chip->slots[0]; +- int ret; +- +- ret = sdhci_pci_gli_resume(chip); +- if (ret) +- return ret; +- +- return cqhci_resume(slot->host->mmc); +-} +- +-static int sdhci_cqhci_gli_suspend(struct sdhci_pci_chip *chip) +-{ +- struct sdhci_pci_slot *slot = chip->slots[0]; +- int ret; +- +- ret = cqhci_suspend(slot->host->mmc); +- if (ret) +- return ret; +- +- return sdhci_suspend_host(slot->host); +-} +-#endif +- + static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc, + struct mmc_ios *ios) + { +@@ -1420,6 +1384,70 @@ static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip) + } + #endif + ++#ifdef CONFIG_PM_SLEEP ++static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip) ++{ ++ struct sdhci_pci_slot *slot = chip->slots[0]; ++ ++ pci_free_irq_vectors(slot->chip->pdev); ++ gli_pcie_enable_msi(slot); ++ ++ return sdhci_pci_resume_host(chip); ++} ++ ++static int gl9763e_resume(struct sdhci_pci_chip *chip) ++{ ++ struct sdhci_pci_slot *slot = chip->slots[0]; ++ int ret; ++ ++ ret = sdhci_pci_gli_resume(chip); ++ if (ret) ++ return ret; ++ ++ ret = cqhci_resume(slot->host->mmc); ++ if (ret) ++ return ret; ++ ++ /* ++ * Disable LPM negotiation to bring device back in sync ++ * with its runtime_pm state. ++ */ ++ gl9763e_set_low_power_negotiation(slot, false); ++ ++ return 0; ++} ++ ++static int gl9763e_suspend(struct sdhci_pci_chip *chip) ++{ ++ struct sdhci_pci_slot *slot = chip->slots[0]; ++ int ret; ++ ++ /* ++ * Certain SoCs can suspend only with the bus in low- ++ * power state, notably x86 SoCs when using S0ix. ++ * Re-enable LPM negotiation to allow entering L1 state ++ * and entering system suspend. ++ */ ++ gl9763e_set_low_power_negotiation(slot, true); ++ ++ ret = cqhci_suspend(slot->host->mmc); ++ if (ret) ++ goto err_suspend; ++ ++ ret = sdhci_suspend_host(slot->host); ++ if (ret) ++ goto err_suspend_host; ++ ++ return 0; ++ ++err_suspend_host: ++ cqhci_resume(slot->host->mmc); ++err_suspend: ++ gl9763e_set_low_power_negotiation(slot, false); ++ return ret; ++} ++#endif ++ + static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot) + { + struct pci_dev *pdev = slot->chip->pdev; +@@ -1527,8 +1555,8 @@ const struct sdhci_pci_fixes sdhci_gl9763e = { + .probe_slot = gli_probe_slot_gl9763e, + .ops = &sdhci_gl9763e_ops, + #ifdef CONFIG_PM_SLEEP +- .resume = sdhci_cqhci_gli_resume, +- .suspend = sdhci_cqhci_gli_suspend, ++ .resume = gl9763e_resume, ++ .suspend = gl9763e_suspend, + #endif + #ifdef CONFIG_PM + .runtime_suspend = gl9763e_runtime_suspend, +diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-core.c +index c73854da51363..19dad5a23f944 100644 +--- a/drivers/mtd/maps/physmap-core.c ++++ b/drivers/mtd/maps/physmap-core.c +@@ -552,6 +552,17 @@ static int physmap_flash_probe(struct platform_device *dev) + if (info->probe_type) { + info->mtds[i] = do_map_probe(info->probe_type, + &info->maps[i]); ++ ++ /* Fall back to mapping region as ROM */ ++ if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) && ++ strcmp(info->probe_type, "map_rom")) { ++ dev_warn(&dev->dev, ++ "map_probe() failed for type %s\n", ++ info->probe_type); ++ ++ info->mtds[i] = do_map_probe("map_rom", ++ &info->maps[i]); ++ } + } else { + int j; + +diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c +index 906eef70cb6d9..487c139316fea 100644 +--- a/drivers/mtd/nand/raw/arasan-nand-controller.c ++++ b/drivers/mtd/nand/raw/arasan-nand-controller.c +@@ -515,6 +515,7 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, + struct mtd_info *mtd = nand_to_mtd(chip); + unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0); + dma_addr_t dma_addr; ++ u8 status; + int ret; + struct anfc_op nfc_op = { + .pkt_reg = +@@ -561,10 +562,21 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, + } + + /* Spare data is not protected */ +- if (oob_required) ++ if (oob_required) { + ret = nand_write_oob_std(chip, page); ++ if (ret) ++ return ret; ++ } + +- return ret; ++ /* Check write status on the chip side */ ++ ret = nand_status_op(chip, &status); ++ if (ret) ++ return ret; ++ ++ if (status & NAND_STATUS_FAIL) ++ return -EIO; ++ ++ return 0; + } + + static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index 30c15e4e1cc0d..576441095012c 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -1162,6 +1162,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, + .ndcb[2] = NDCB2_ADDR5_PAGE(page), + }; + unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0); ++ u8 status; + int ret; + + /* NFCv2 needs more information about the operation being executed */ +@@ -1195,7 +1196,18 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, + + ret = marvell_nfc_wait_op(chip, + PSEC_TO_MSEC(sdr->tPROG_max)); +- return ret; ++ if (ret) ++ return ret; ++ ++ /* Check write status on the chip side */ ++ ret = nand_status_op(chip, &status); ++ if (ret) ++ return ret; ++ ++ if (status & NAND_STATUS_FAIL) ++ return -EIO; ++ ++ return 0; + } + + static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip, +@@ -1624,6 +1636,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip, + int data_len = lt->data_bytes; + int spare_len = lt->spare_bytes; + int chunk, ret; ++ u8 status; + + marvell_nfc_select_target(chip, chip->cur_cs); + +@@ -1660,6 +1673,14 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip, + if (ret) + return ret; + ++ /* Check write status on the chip side */ ++ ret = nand_status_op(chip, &status); ++ if (ret) ++ return ret; ++ ++ if (status & NAND_STATUS_FAIL) ++ return -EIO; ++ + return 0; + } + +diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c +index a6af521832aa4..458ff93eb88ae 100644 +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -5109,6 +5109,9 @@ static void rawnand_check_cont_read_support(struct nand_chip *chip) + { + struct mtd_info *mtd = nand_to_mtd(chip); + ++ if (!chip->parameters.supports_read_cache) ++ return; ++ + if (chip->read_retries) + return; + +diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c +index 836757717660b..b3cc8f3605291 100644 +--- a/drivers/mtd/nand/raw/nand_jedec.c ++++ b/drivers/mtd/nand/raw/nand_jedec.c +@@ -94,6 +94,9 @@ int nand_jedec_detect(struct nand_chip *chip) + goto free_jedec_param_page; + } + ++ if (p->opt_cmd[0] & JEDEC_OPT_CMD_READ_CACHE) ++ chip->parameters.supports_read_cache = true; ++ + memorg->pagesize = le32_to_cpu(p->byte_per_page); + mtd->writesize = memorg->pagesize; + +diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c +index f15ef90aec8cd..861975e44b552 100644 +--- a/drivers/mtd/nand/raw/nand_onfi.c ++++ b/drivers/mtd/nand/raw/nand_onfi.c +@@ -303,6 +303,9 @@ int nand_onfi_detect(struct nand_chip *chip) + ONFI_FEATURE_ADDR_TIMING_MODE, 1); + } + ++ if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_READ_CACHE) ++ chip->parameters.supports_read_cache = true; ++ + onfi = kzalloc(sizeof(*onfi), GFP_KERNEL); + if (!onfi) { + ret = -ENOMEM; +diff --git a/drivers/mtd/nand/raw/pl35x-nand-controller.c b/drivers/mtd/nand/raw/pl35x-nand-controller.c +index 28b7bd7e22eb4..9dd06eeb021e1 100644 +--- a/drivers/mtd/nand/raw/pl35x-nand-controller.c ++++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c +@@ -513,6 +513,7 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip, + u32 addr1 = 0, addr2 = 0, row; + u32 cmd_addr; + int i, ret; ++ u8 status; + + ret = pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_APB); + if (ret) +@@ -565,6 +566,14 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip, + if (ret) + goto disable_ecc_engine; + ++ /* Check write status on the chip side */ ++ ret = nand_status_op(chip, &status); ++ if (ret) ++ goto disable_ecc_engine; ++ ++ if (status & NAND_STATUS_FAIL) ++ ret = -EIO; ++ + disable_ecc_engine: + pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS); + +diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c +index 72d6168d8a1be..ce8b539de900d 100644 +--- a/drivers/mtd/nand/raw/qcom_nandc.c ++++ b/drivers/mtd/nand/raw/qcom_nandc.c +@@ -3309,7 +3309,7 @@ err_nandc_alloc: + err_aon_clk: + clk_disable_unprepare(nandc->core_clk); + err_core_clk: +- dma_unmap_resource(dev, res->start, resource_size(res), ++ dma_unmap_resource(dev, nandc->base_dma, resource_size(res), + DMA_BIDIRECTIONAL, 0); + return ret; + } +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index 50b7295bc9222..12601bc4227a7 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -12,7 +12,7 @@ + + #define SPINAND_MFR_MICRON 0x2c + +-#define MICRON_STATUS_ECC_MASK GENMASK(7, 4) ++#define MICRON_STATUS_ECC_MASK GENMASK(6, 4) + #define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4) + #define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4) + #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4) +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 447b06ea4fc9c..a64ebb7f5b712 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4022,7 +4022,7 @@ static inline const void *bond_pull_data(struct sk_buff *skb, + if (likely(n <= hlen)) + return data; + else if (skb && likely(pskb_may_pull(skb, n))) +- return skb->head; ++ return skb->data; + + return NULL; + } +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index 72374b066f64a..cd1f240c90f39 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -617,17 +617,16 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) + dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio"); + priv->master_mii_bus = of_mdio_find_bus(dn); + if (!priv->master_mii_bus) { +- of_node_put(dn); +- return -EPROBE_DEFER; ++ err = -EPROBE_DEFER; ++ goto err_of_node_put; + } + +- get_device(&priv->master_mii_bus->dev); + priv->master_mii_dn = dn; + + priv->slave_mii_bus = mdiobus_alloc(); + if (!priv->slave_mii_bus) { +- of_node_put(dn); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto err_put_master_mii_bus_dev; + } + + priv->slave_mii_bus->priv = priv; +@@ -684,11 +683,17 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) + } + + err = mdiobus_register(priv->slave_mii_bus); +- if (err && dn) { +- mdiobus_free(priv->slave_mii_bus); +- of_node_put(dn); +- } ++ if (err && dn) ++ goto err_free_slave_mii_bus; + ++ return 0; ++ ++err_free_slave_mii_bus: ++ mdiobus_free(priv->slave_mii_bus); ++err_put_master_mii_bus_dev: ++ put_device(&priv->master_mii_bus->dev); ++err_of_node_put: ++ of_node_put(dn); + return err; + } + +@@ -696,6 +701,7 @@ static void bcm_sf2_mdio_unregister(struct bcm_sf2_priv *priv) + { + mdiobus_unregister(priv->slave_mii_bus); + mdiobus_free(priv->slave_mii_bus); ++ put_device(&priv->master_mii_bus->dev); + of_node_put(priv->master_mii_dn); + } + +diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c +index 5fc64e47568a9..d567e42e17601 100644 +--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c ++++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c +@@ -911,7 +911,7 @@ static int csk_wait_memory(struct chtls_dev *cdev, + struct sock *sk, long *timeo_p) + { + DEFINE_WAIT_FUNC(wait, woken_wake_function); +- int err = 0; ++ int ret, err = 0; + long current_timeo; + long vm_wait = 0; + bool noblock; +@@ -942,10 +942,13 @@ static int csk_wait_memory(struct chtls_dev *cdev, + + set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + sk->sk_write_pending++; +- sk_wait_event(sk, ¤t_timeo, sk->sk_err || +- (sk->sk_shutdown & SEND_SHUTDOWN) || +- (csk_mem_free(cdev, sk) && !vm_wait), &wait); ++ ret = sk_wait_event(sk, ¤t_timeo, sk->sk_err || ++ (sk->sk_shutdown & SEND_SHUTDOWN) || ++ (csk_mem_free(cdev, sk) && !vm_wait), ++ &wait); + sk->sk_write_pending--; ++ if (ret < 0) ++ goto do_error; + + if (vm_wait) { + vm_wait -= current_timeo; +@@ -1348,6 +1351,7 @@ static int chtls_pt_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + int copied = 0; + int target; + long timeo; ++ int ret; + + buffers_freed = 0; + +@@ -1423,7 +1427,11 @@ static int chtls_pt_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + if (copied >= target) + break; + chtls_cleanup_rbuf(sk, copied); +- sk_wait_data(sk, &timeo, NULL); ++ ret = sk_wait_data(sk, &timeo, NULL); ++ if (ret < 0) { ++ copied = copied ? : ret; ++ goto unlock; ++ } + continue; + found_ok_skb: + if (!skb->len) { +@@ -1518,6 +1526,8 @@ skip_copy: + + if (buffers_freed) + chtls_cleanup_rbuf(sk, copied); ++ ++unlock: + release_sock(sk); + return copied; + } +@@ -1534,6 +1544,7 @@ static int peekmsg(struct sock *sk, struct msghdr *msg, + int copied = 0; + size_t avail; /* amount of available data in current skb */ + long timeo; ++ int ret; + + lock_sock(sk); + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); +@@ -1585,7 +1596,12 @@ static int peekmsg(struct sock *sk, struct msghdr *msg, + release_sock(sk); + lock_sock(sk); + } else { +- sk_wait_data(sk, &timeo, NULL); ++ ret = sk_wait_data(sk, &timeo, NULL); ++ if (ret < 0) { ++ /* here 'copied' is 0 due to previous checks */ ++ copied = ret; ++ break; ++ } + } + + if (unlikely(peek_seq != tp->copied_seq)) { +@@ -1656,6 +1672,7 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + int copied = 0; + long timeo; + int target; /* Read at least this many bytes */ ++ int ret; + + buffers_freed = 0; + +@@ -1747,7 +1764,11 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + if (copied >= target) + break; + chtls_cleanup_rbuf(sk, copied); +- sk_wait_data(sk, &timeo, NULL); ++ ret = sk_wait_data(sk, &timeo, NULL); ++ if (ret < 0) { ++ copied = copied ? : ret; ++ goto unlock; ++ } + continue; + + found_ok_skb: +@@ -1816,6 +1837,7 @@ skip_copy: + if (buffers_freed) + chtls_cleanup_rbuf(sk, copied); + ++unlock: + release_sock(sk); + return copied; + } +diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c +index d1da7413dc4de..e84a066aa1a40 100644 +--- a/drivers/net/ethernet/google/gve/gve_rx.c ++++ b/drivers/net/ethernet/google/gve/gve_rx.c +@@ -146,7 +146,7 @@ static int gve_prefill_rx_pages(struct gve_rx_ring *rx) + err = gve_rx_alloc_buffer(priv, &priv->pdev->dev, &rx->data.page_info[i], + &rx->data.data_ring[i]); + if (err) +- goto alloc_err; ++ goto alloc_err_rda; + } + + if (!rx->data.raw_addressing) { +@@ -171,12 +171,26 @@ static int gve_prefill_rx_pages(struct gve_rx_ring *rx) + return slots; + + alloc_err_qpl: ++ /* Fully free the copy pool pages. */ + while (j--) { + page_ref_sub(rx->qpl_copy_pool[j].page, + rx->qpl_copy_pool[j].pagecnt_bias - 1); + put_page(rx->qpl_copy_pool[j].page); + } +-alloc_err: ++ ++ /* Do not fully free QPL pages - only remove the bias added in this ++ * function with gve_setup_rx_buffer. ++ */ ++ while (i--) ++ page_ref_sub(rx->data.page_info[i].page, ++ rx->data.page_info[i].pagecnt_bias - 1); ++ ++ gve_unassign_qpl(priv, rx->data.qpl->id); ++ rx->data.qpl = NULL; ++ ++ return err; ++ ++alloc_err_rda: + while (i--) + gve_rx_free_buffer(&priv->pdev->dev, + &rx->data.page_info[i], +diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c +index ed88e38d488b2..95843f0f1a3e8 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_common.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_common.c +@@ -1082,7 +1082,7 @@ void i40e_clear_hw(struct i40e_hw *hw) + I40E_PFLAN_QALLOC_FIRSTQ_SHIFT; + j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >> + I40E_PFLAN_QALLOC_LASTQ_SHIFT; +- if (val & I40E_PFLAN_QALLOC_VALID_MASK) ++ if (val & I40E_PFLAN_QALLOC_VALID_MASK && j >= base_queue) + num_queues = (j - base_queue) + 1; + else + num_queues = 0; +@@ -1092,7 +1092,7 @@ void i40e_clear_hw(struct i40e_hw *hw) + I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT; + j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >> + I40E_PF_VT_PFALLOC_LASTVF_SHIFT; +- if (val & I40E_PF_VT_PFALLOC_VALID_MASK) ++ if (val & I40E_PF_VT_PFALLOC_VALID_MASK && j >= i) + num_vfs = (j - i) + 1; + else + num_vfs = 0; +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index 0054d7e64ec31..40234ddf10733 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -1201,8 +1201,7 @@ static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) + + ctxt->info.q_opt_rss = ((lut_type << ICE_AQ_VSI_Q_OPT_RSS_LUT_S) & + ICE_AQ_VSI_Q_OPT_RSS_LUT_M) | +- ((hash_type << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) & +- ICE_AQ_VSI_Q_OPT_RSS_HASH_M); ++ (hash_type & ICE_AQ_VSI_Q_OPT_RSS_HASH_M); + } + + static void +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index c2cdc79308dc1..5c940da8717b4 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -6,6 +6,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #include ++#include + #include "ice.h" + #include "ice_base.h" + #include "ice_lib.h" +@@ -4632,6 +4633,9 @@ static void ice_init_features(struct ice_pf *pf) + + static void ice_deinit_features(struct ice_pf *pf) + { ++ if (ice_is_safe_mode(pf)) ++ return; ++ + ice_deinit_lag(pf); + if (test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)) + ice_cfg_lldp_mib_change(&pf->hw, false); +@@ -4963,6 +4967,20 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + return -EINVAL; + } + ++ /* when under a kdump kernel initiate a reset before enabling the ++ * device in order to clear out any pending DMA transactions. These ++ * transactions can cause some systems to machine check when doing ++ * the pcim_enable_device() below. ++ */ ++ if (is_kdump_kernel()) { ++ pci_save_state(pdev); ++ pci_clear_master(pdev); ++ err = pcie_flr(pdev); ++ if (err) ++ return err; ++ pci_restore_state(pdev); ++ } ++ + /* this driver uses devres, see + * Documentation/driver-api/driver-model/devres.rst + */ +diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +index dbc518ff82768..5b46ca47c8e59 100644 +--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c ++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +@@ -715,20 +715,19 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb, + hw_desc->dptr = tx_buffer->sglist_dma; + } + +- /* Flush the hw descriptor before writing to doorbell */ +- wmb(); +- +- /* Ring Doorbell to notify the NIC there is a new packet */ +- writel(1, iq->doorbell_reg); ++ netdev_tx_sent_queue(iq->netdev_q, skb->len); ++ skb_tx_timestamp(skb); + atomic_inc(&iq->instr_pending); + wi++; + if (wi == iq->max_count) + wi = 0; + iq->host_write_index = wi; ++ /* Flush the hw descriptor before writing to doorbell */ ++ wmb(); + +- netdev_tx_sent_queue(iq->netdev_q, skb->len); ++ /* Ring Doorbell to notify the NIC there is a new packet */ ++ writel(1, iq->doorbell_reg); + iq->stats.instr_posted++; +- skb_tx_timestamp(skb); + return NETDEV_TX_OK; + + dma_map_sg_err: +diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h +index ddec1627f1a7b..8d0bacf4e49cc 100644 +--- a/drivers/net/ethernet/marvell/sky2.h ++++ b/drivers/net/ethernet/marvell/sky2.h +@@ -2195,7 +2195,7 @@ struct rx_ring_info { + struct sk_buff *skb; + dma_addr_t data_addr; + DEFINE_DMA_UNMAP_LEN(data_size); +- dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; ++ dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT ?: 1]; + }; + + enum flow_control { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +index 7c0f2adbea000..ad789349c06e6 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +@@ -848,7 +848,7 @@ static void mlx5_fw_tracer_ownership_change(struct work_struct *work) + + mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner); + if (tracer->owner) { +- tracer->owner = false; ++ mlx5_fw_tracer_ownership_acquire(tracer); + return; + } + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +index 1730f6a716eea..b10e40e1a9c14 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +@@ -24,7 +24,8 @@ static int mlx5e_set_int_port_tunnel(struct mlx5e_priv *priv, + + route_dev = dev_get_by_index(dev_net(e->out_dev), e->route_dev_ifindex); + +- if (!route_dev || !netif_is_ovs_master(route_dev)) ++ if (!route_dev || !netif_is_ovs_master(route_dev) || ++ attr->parse_attr->filter_dev == e->out_dev) + goto out; + + err = mlx5e_set_fwd_to_int_port_actions(priv, attr, e->route_dev_ifindex, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c +index 40589cebb7730..4fd4c9febab95 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c +@@ -873,11 +873,11 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, + } + + out: +- if (flags & XDP_XMIT_FLUSH) { +- if (sq->mpwqe.wqe) +- mlx5e_xdp_mpwqe_complete(sq); ++ if (sq->mpwqe.wqe) ++ mlx5e_xdp_mpwqe_complete(sq); ++ ++ if (flags & XDP_XMIT_FLUSH) + mlx5e_xmit_xdp_doorbell(sq); +- } + + return nxmit; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +index 99b3843396f33..0cd44ef190058 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +@@ -704,7 +704,7 @@ mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) + + /* update HW stats in background for next time */ + mlx5e_queue_update_stats(priv); +- memcpy(stats, &priv->stats.vf_vport, sizeof(*stats)); ++ mlx5e_stats_copy_rep_stats(stats, &priv->stats.rep_stats); + } + + static int mlx5e_rep_change_mtu(struct net_device *netdev, int new_mtu) +@@ -772,6 +772,7 @@ static int mlx5e_rep_max_nch_limit(struct mlx5_core_dev *mdev) + + static void mlx5e_build_rep_params(struct net_device *netdev) + { ++ const bool take_rtnl = netdev->reg_state == NETREG_REGISTERED; + struct mlx5e_priv *priv = netdev_priv(netdev); + struct mlx5e_rep_priv *rpriv = priv->ppriv; + struct mlx5_eswitch_rep *rep = rpriv->rep; +@@ -797,8 +798,15 @@ static void mlx5e_build_rep_params(struct net_device *netdev) + /* RQ */ + mlx5e_build_rq_params(mdev, params); + ++ /* If netdev is already registered (e.g. move from nic profile to uplink, ++ * RTNL lock must be held before triggering netdev notifiers. ++ */ ++ if (take_rtnl) ++ rtnl_lock(); + /* update XDP supported features */ + mlx5e_set_xdp_feature(netdev); ++ if (take_rtnl) ++ rtnl_unlock(); + + /* CQ moderation params */ + params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index 41d37159e027b..5df970e6e29d5 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -457,26 +457,41 @@ static int mlx5e_alloc_rx_wqes(struct mlx5e_rq *rq, u16 ix, int wqe_bulk) + static int mlx5e_refill_rx_wqes(struct mlx5e_rq *rq, u16 ix, int wqe_bulk) + { + int remaining = wqe_bulk; +- int i = 0; ++ int total_alloc = 0; ++ int refill_alloc; ++ int refill; + + /* The WQE bulk is split into smaller bulks that are sized + * according to the page pool cache refill size to avoid overflowing + * the page pool cache due to too many page releases at once. + */ + do { +- int refill = min_t(u16, rq->wqe.info.refill_unit, remaining); +- int alloc_count; ++ refill = min_t(u16, rq->wqe.info.refill_unit, remaining); + +- mlx5e_free_rx_wqes(rq, ix + i, refill); +- alloc_count = mlx5e_alloc_rx_wqes(rq, ix + i, refill); +- i += alloc_count; +- if (unlikely(alloc_count != refill)) +- break; ++ mlx5e_free_rx_wqes(rq, ix + total_alloc, refill); ++ refill_alloc = mlx5e_alloc_rx_wqes(rq, ix + total_alloc, refill); ++ if (unlikely(refill_alloc != refill)) ++ goto err_free; + ++ total_alloc += refill_alloc; + remaining -= refill; + } while (remaining); + +- return i; ++ return total_alloc; ++ ++err_free: ++ mlx5e_free_rx_wqes(rq, ix, total_alloc + refill_alloc); ++ ++ for (int i = 0; i < total_alloc + refill; i++) { ++ int j = mlx5_wq_cyc_ctr2ix(&rq->wqe.wq, ix + i); ++ struct mlx5e_wqe_frag_info *frag; ++ ++ frag = get_frag(rq, j); ++ for (int k = 0; k < rq->wqe.info.num_frags; k++, frag++) ++ frag->flags |= BIT(MLX5E_WQE_FRAG_SKIP_RELEASE); ++ } ++ ++ return 0; + } + + static void +@@ -816,6 +831,8 @@ err_unmap: + mlx5e_page_release_fragmented(rq, frag_page); + } + ++ bitmap_fill(wi->skip_release_bitmap, rq->mpwqe.pages_per_wqe); ++ + err: + rq->stats->buff_alloc_err++; + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +index 1ff8a06027dcf..67938b4ea1b90 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +@@ -475,11 +475,20 @@ struct mlx5e_stats { + struct mlx5e_vnic_env_stats vnic; + struct mlx5e_vport_stats vport; + struct mlx5e_pport_stats pport; +- struct rtnl_link_stats64 vf_vport; + struct mlx5e_pcie_stats pcie; + struct mlx5e_rep_stats rep_stats; + }; + ++static inline void mlx5e_stats_copy_rep_stats(struct rtnl_link_stats64 *vf_vport, ++ struct mlx5e_rep_stats *rep_stats) ++{ ++ memset(vf_vport, 0, sizeof(*vf_vport)); ++ vf_vport->rx_packets = rep_stats->vport_rx_packets; ++ vf_vport->tx_packets = rep_stats->vport_tx_packets; ++ vf_vport->rx_bytes = rep_stats->vport_rx_bytes; ++ vf_vport->tx_bytes = rep_stats->vport_tx_bytes; ++} ++ + extern mlx5e_stats_grp_t mlx5e_nic_stats_grps[]; + unsigned int mlx5e_nic_stats_grps_num(struct mlx5e_priv *priv); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 4b22a91482cec..5797d8607633e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -4931,7 +4931,8 @@ static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv, + if (err) + return err; + +- rpriv->prev_vf_vport_stats = priv->stats.vf_vport; ++ mlx5e_stats_copy_rep_stats(&rpriv->prev_vf_vport_stats, ++ &priv->stats.rep_stats); + break; + default: + NL_SET_ERR_MSG_MOD(extack, "mlx5 supports only police action for matchall"); +@@ -4971,7 +4972,7 @@ void mlx5e_tc_stats_matchall(struct mlx5e_priv *priv, + u64 dbytes; + u64 dpkts; + +- cur_stats = priv->stats.vf_vport; ++ mlx5e_stats_copy_rep_stats(&cur_stats, &priv->stats.rep_stats); + dpkts = cur_stats.rx_packets - rpriv->prev_vf_vport_stats.rx_packets; + dbytes = cur_stats.rx_bytes - rpriv->prev_vf_vport_stats.rx_bytes; + rpriv->prev_vf_vport_stats = cur_stats; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +index 6e9b1b183190d..51afb97b9e452 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +@@ -1022,11 +1022,8 @@ const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) + return ERR_PTR(err); + } + +-static void mlx5_eswitch_event_handlers_register(struct mlx5_eswitch *esw) ++static void mlx5_eswitch_event_handler_register(struct mlx5_eswitch *esw) + { +- MLX5_NB_INIT(&esw->nb, eswitch_vport_event, NIC_VPORT_CHANGE); +- mlx5_eq_notifier_register(esw->dev, &esw->nb); +- + if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) { + MLX5_NB_INIT(&esw->esw_funcs.nb, mlx5_esw_funcs_changed_handler, + ESW_FUNCTIONS_CHANGED); +@@ -1034,13 +1031,11 @@ static void mlx5_eswitch_event_handlers_register(struct mlx5_eswitch *esw) + } + } + +-static void mlx5_eswitch_event_handlers_unregister(struct mlx5_eswitch *esw) ++static void mlx5_eswitch_event_handler_unregister(struct mlx5_eswitch *esw) + { + if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) + mlx5_eq_notifier_unregister(esw->dev, &esw->esw_funcs.nb); + +- mlx5_eq_notifier_unregister(esw->dev, &esw->nb); +- + flush_workqueue(esw->work_queue); + } + +@@ -1419,6 +1414,9 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) + + mlx5_eswitch_update_num_of_vfs(esw, num_vfs); + ++ MLX5_NB_INIT(&esw->nb, eswitch_vport_event, NIC_VPORT_CHANGE); ++ mlx5_eq_notifier_register(esw->dev, &esw->nb); ++ + if (esw->mode == MLX5_ESWITCH_LEGACY) { + err = esw_legacy_enable(esw); + } else { +@@ -1431,7 +1429,7 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) + + esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED; + +- mlx5_eswitch_event_handlers_register(esw); ++ mlx5_eswitch_event_handler_register(esw); + + esw_info(esw->dev, "Enable: mode(%s), nvfs(%d), necvfs(%d), active vports(%d)\n", + esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", +@@ -1558,7 +1556,8 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw) + */ + mlx5_esw_mode_change_notify(esw, MLX5_ESWITCH_LEGACY); + +- mlx5_eswitch_event_handlers_unregister(esw); ++ mlx5_eq_notifier_unregister(esw->dev, &esw->nb); ++ mlx5_eswitch_event_handler_unregister(esw); + + esw_info(esw->dev, "Disable: mode(%s), nvfs(%d), necvfs(%d), active vports(%d)\n", + esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", +diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c +index 717a0b3f89bd5..ab5ef254a7483 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c +@@ -113,7 +113,10 @@ static void qed_ll2b_complete_tx_packet(void *cxt, + static int qed_ll2_alloc_buffer(struct qed_dev *cdev, + u8 **data, dma_addr_t *phys_addr) + { +- *data = kmalloc(cdev->ll2->rx_size, GFP_ATOMIC); ++ size_t size = cdev->ll2->rx_size + NET_SKB_PAD + ++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ ++ *data = kmalloc(size, GFP_ATOMIC); + if (!(*data)) { + DP_INFO(cdev, "Failed to allocate LL2 buffer data\n"); + return -ENOMEM; +@@ -2589,7 +2592,7 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params) + INIT_LIST_HEAD(&cdev->ll2->list); + spin_lock_init(&cdev->ll2->lock); + +- cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN + ++ cdev->ll2->rx_size = PRM_DMA_PAD_BYTES_NUM + ETH_HLEN + + L1_CACHE_BYTES + params->mtu; + + /* Allocate memory for LL2. +diff --git a/drivers/net/mdio/mdio-mux.c b/drivers/net/mdio/mdio-mux.c +index a881e35233283..bef4cce71287c 100644 +--- a/drivers/net/mdio/mdio-mux.c ++++ b/drivers/net/mdio/mdio-mux.c +@@ -55,6 +55,27 @@ out: + return r; + } + ++static int mdio_mux_read_c45(struct mii_bus *bus, int phy_id, int dev_addr, ++ int regnum) ++{ ++ struct mdio_mux_child_bus *cb = bus->priv; ++ struct mdio_mux_parent_bus *pb = cb->parent; ++ int r; ++ ++ mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX); ++ r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); ++ if (r) ++ goto out; ++ ++ pb->current_child = cb->bus_number; ++ ++ r = pb->mii_bus->read_c45(pb->mii_bus, phy_id, dev_addr, regnum); ++out: ++ mutex_unlock(&pb->mii_bus->mdio_lock); ++ ++ return r; ++} ++ + /* + * The parent bus' lock is used to order access to the switch_fn. + */ +@@ -80,6 +101,28 @@ out: + return r; + } + ++static int mdio_mux_write_c45(struct mii_bus *bus, int phy_id, int dev_addr, ++ int regnum, u16 val) ++{ ++ struct mdio_mux_child_bus *cb = bus->priv; ++ struct mdio_mux_parent_bus *pb = cb->parent; ++ ++ int r; ++ ++ mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX); ++ r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); ++ if (r) ++ goto out; ++ ++ pb->current_child = cb->bus_number; ++ ++ r = pb->mii_bus->write_c45(pb->mii_bus, phy_id, dev_addr, regnum, val); ++out: ++ mutex_unlock(&pb->mii_bus->mdio_lock); ++ ++ return r; ++} ++ + static int parent_count; + + static void mdio_mux_uninit_children(struct mdio_mux_parent_bus *pb) +@@ -173,6 +216,10 @@ int mdio_mux_init(struct device *dev, + cb->mii_bus->parent = dev; + cb->mii_bus->read = mdio_mux_read; + cb->mii_bus->write = mdio_mux_write; ++ if (parent_bus->read_c45) ++ cb->mii_bus->read_c45 = mdio_mux_read_c45; ++ if (parent_bus->write_c45) ++ cb->mii_bus->write_c45 = mdio_mux_write_c45; + r = of_mdiobus_register(cb->mii_bus, child_bus_node); + if (r) { + mdiobus_free(cb->mii_bus); +diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c +index f8c17a253f8b3..efe2542d08815 100644 +--- a/drivers/net/phy/bcm7xxx.c ++++ b/drivers/net/phy/bcm7xxx.c +@@ -894,6 +894,9 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev) + .name = _name, \ + /* PHY_BASIC_FEATURES */ \ + .flags = PHY_IS_INTERNAL, \ ++ .get_sset_count = bcm_phy_get_sset_count, \ ++ .get_strings = bcm_phy_get_strings, \ ++ .get_stats = bcm7xxx_28nm_get_phy_stats, \ + .probe = bcm7xxx_28nm_probe, \ + .config_init = bcm7xxx_16nm_ephy_config_init, \ + .config_aneg = genphy_config_aneg, \ +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 100339bc8b04a..bd3fc4b9d61af 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -3068,10 +3068,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, + struct net *net = sock_net(&tfile->sk); + struct tun_struct *tun; + void __user* argp = (void __user*)arg; +- unsigned int ifindex, carrier; ++ unsigned int carrier; + struct ifreq ifr; + kuid_t owner; + kgid_t group; ++ int ifindex; + int sndbuf; + int vnet_hdr_sz; + int le; +@@ -3127,7 +3128,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, + ret = -EFAULT; + if (copy_from_user(&ifindex, argp, sizeof(ifindex))) + goto unlock; +- ++ ret = -EINVAL; ++ if (ifindex < 0) ++ goto unlock; + ret = 0; + tfile->ifindex = ifindex; + goto unlock; +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index 563ecd27b93ea..17da42fe605c3 100644 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -897,7 +897,7 @@ static int smsc95xx_reset(struct usbnet *dev) + + if (timeout >= 100) { + netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n"); +- return ret; ++ return -ETIMEDOUT; + } + + ret = smsc95xx_set_mac_address(dev); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 36d70d589aedd..898dca3936435 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -1612,6 +1612,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, + iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); + + memset(&info->status, 0, sizeof(info->status)); ++ info->flags &= ~(IEEE80211_TX_STAT_ACK | IEEE80211_TX_STAT_TX_FILTERED); + + /* inform mac80211 about what happened with the frame */ + switch (status & TX_STATUS_MSK) { +@@ -1964,6 +1965,8 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, + */ + if (!is_flush) + info->flags |= IEEE80211_TX_STAT_ACK; ++ else ++ info->flags &= ~IEEE80211_TX_STAT_ACK; + } + + /* +diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +index d1d3632a3ed7b..4ab3a14567b65 100644 +--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c ++++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +@@ -921,6 +921,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, + while (tlv_buf_left >= sizeof(*tlv_rxba)) { + tlv_type = le16_to_cpu(tlv_rxba->header.type); + tlv_len = le16_to_cpu(tlv_rxba->header.len); ++ if (size_add(sizeof(tlv_rxba->header), tlv_len) > tlv_buf_left) { ++ mwifiex_dbg(priv->adapter, WARN, ++ "TLV size (%zu) overflows event_buf buf_left=%d\n", ++ size_add(sizeof(tlv_rxba->header), tlv_len), ++ tlv_buf_left); ++ return; ++ } ++ + if (tlv_type != TLV_TYPE_RXBA_SYNC) { + mwifiex_dbg(priv->adapter, ERROR, + "Wrong TLV id=0x%x\n", tlv_type); +@@ -929,6 +937,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, + + tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num); + tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len); ++ if (size_add(sizeof(*tlv_rxba), tlv_bitmap_len) > tlv_buf_left) { ++ mwifiex_dbg(priv->adapter, WARN, ++ "TLV size (%zu) overflows event_buf buf_left=%d\n", ++ size_add(sizeof(*tlv_rxba), tlv_bitmap_len), ++ tlv_buf_left); ++ return; ++ } ++ + mwifiex_dbg(priv->adapter, INFO, + "%pM tid=%d seq_num=%d bitmap_len=%d\n", + tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num, +diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem.c b/drivers/net/wwan/iosm/iosm_ipc_imem.c +index 635301d677e18..829515a601b37 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_imem.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_imem.c +@@ -4,7 +4,6 @@ + */ + + #include +-#include + + #include "iosm_ipc_chnl_cfg.h" + #include "iosm_ipc_devlink.h" +@@ -632,11 +631,6 @@ static void ipc_imem_run_state_worker(struct work_struct *instance) + /* Complete all memory stores after setting bit */ + smp_mb__after_atomic(); + +- if (ipc_imem->pcie->pci->device == INTEL_CP_DEVICE_7560_ID) { +- pm_runtime_mark_last_busy(ipc_imem->dev); +- pm_runtime_put_autosuspend(ipc_imem->dev); +- } +- + return; + + err_ipc_mux_deinit: +@@ -1240,7 +1234,6 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem) + + /* forward MDM_NOT_READY to listeners */ + ipc_uevent_send(ipc_imem->dev, UEVENT_MDM_NOT_READY); +- pm_runtime_get_sync(ipc_imem->dev); + + hrtimer_cancel(&ipc_imem->td_alloc_timer); + hrtimer_cancel(&ipc_imem->tdupdate_timer); +@@ -1426,16 +1419,6 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, + + set_bit(IOSM_DEVLINK_INIT, &ipc_imem->flag); + } +- +- if (!pm_runtime_enabled(ipc_imem->dev)) +- pm_runtime_enable(ipc_imem->dev); +- +- pm_runtime_set_autosuspend_delay(ipc_imem->dev, +- IPC_MEM_AUTO_SUSPEND_DELAY_MS); +- pm_runtime_use_autosuspend(ipc_imem->dev); +- pm_runtime_allow(ipc_imem->dev); +- pm_runtime_mark_last_busy(ipc_imem->dev); +- + return ipc_imem; + devlink_channel_fail: + ipc_devlink_deinit(ipc_imem->ipc_devlink); +diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem.h b/drivers/net/wwan/iosm/iosm_ipc_imem.h +index 0144b45e2afb3..5664ac507c902 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_imem.h ++++ b/drivers/net/wwan/iosm/iosm_ipc_imem.h +@@ -103,8 +103,6 @@ struct ipc_chnl_cfg; + #define FULLY_FUNCTIONAL 0 + #define IOSM_DEVLINK_INIT 1 + +-#define IPC_MEM_AUTO_SUSPEND_DELAY_MS 5000 +- + /* List of the supported UL/DL pipes. */ + enum ipc_mem_pipes { + IPC_MEM_PIPE_0 = 0, +diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c +index 3a259c9abefdf..04517bd3325a2 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c +@@ -6,7 +6,6 @@ + #include + #include + #include +-#include + #include + + #include "iosm_ipc_imem.h" +@@ -438,8 +437,7 @@ static int __maybe_unused ipc_pcie_resume_cb(struct device *dev) + return 0; + } + +-static DEFINE_RUNTIME_DEV_PM_OPS(iosm_ipc_pm, ipc_pcie_suspend_cb, +- ipc_pcie_resume_cb, NULL); ++static SIMPLE_DEV_PM_OPS(iosm_ipc_pm, ipc_pcie_suspend_cb, ipc_pcie_resume_cb); + + static struct pci_driver iosm_ipc_driver = { + .name = KBUILD_MODNAME, +diff --git a/drivers/net/wwan/iosm/iosm_ipc_port.c b/drivers/net/wwan/iosm/iosm_ipc_port.c +index 2ba1ddca3945b..5d5b4183e14a3 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_port.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_port.c +@@ -3,8 +3,6 @@ + * Copyright (C) 2020-21 Intel Corporation. + */ + +-#include +- + #include "iosm_ipc_chnl_cfg.h" + #include "iosm_ipc_imem_ops.h" + #include "iosm_ipc_port.h" +@@ -15,16 +13,12 @@ static int ipc_port_ctrl_start(struct wwan_port *port) + struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port); + int ret = 0; + +- pm_runtime_get_sync(ipc_port->ipc_imem->dev); + ipc_port->channel = ipc_imem_sys_port_open(ipc_port->ipc_imem, + ipc_port->chl_id, + IPC_HP_CDEV_OPEN); + if (!ipc_port->channel) + ret = -EIO; + +- pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev); +- pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev); +- + return ret; + } + +@@ -33,24 +27,15 @@ static void ipc_port_ctrl_stop(struct wwan_port *port) + { + struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port); + +- pm_runtime_get_sync(ipc_port->ipc_imem->dev); + ipc_imem_sys_port_close(ipc_port->ipc_imem, ipc_port->channel); +- pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev); +- pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev); + } + + /* transfer control data to modem */ + static int ipc_port_ctrl_tx(struct wwan_port *port, struct sk_buff *skb) + { + struct iosm_cdev *ipc_port = wwan_port_get_drvdata(port); +- int ret; + +- pm_runtime_get_sync(ipc_port->ipc_imem->dev); +- ret = ipc_imem_sys_cdev_write(ipc_port, skb); +- pm_runtime_mark_last_busy(ipc_port->ipc_imem->dev); +- pm_runtime_put_autosuspend(ipc_port->ipc_imem->dev); +- +- return ret; ++ return ipc_imem_sys_cdev_write(ipc_port, skb); + } + + static const struct wwan_port_ops ipc_wwan_ctrl_ops = { +diff --git a/drivers/net/wwan/iosm/iosm_ipc_trace.c b/drivers/net/wwan/iosm/iosm_ipc_trace.c +index 4368373797b69..eeecfa3d10c5a 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_trace.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_trace.c +@@ -3,9 +3,7 @@ + * Copyright (C) 2020-2021 Intel Corporation. + */ + +-#include + #include +- + #include "iosm_ipc_trace.h" + + /* sub buffer size and number of sub buffer */ +@@ -99,8 +97,6 @@ static ssize_t ipc_trace_ctrl_file_write(struct file *filp, + if (ret) + return ret; + +- pm_runtime_get_sync(ipc_trace->ipc_imem->dev); +- + mutex_lock(&ipc_trace->trc_mutex); + if (val == TRACE_ENABLE && ipc_trace->mode != TRACE_ENABLE) { + ipc_trace->channel = ipc_imem_sys_port_open(ipc_trace->ipc_imem, +@@ -121,10 +117,6 @@ static ssize_t ipc_trace_ctrl_file_write(struct file *filp, + ret = count; + unlock: + mutex_unlock(&ipc_trace->trc_mutex); +- +- pm_runtime_mark_last_busy(ipc_trace->ipc_imem->dev); +- pm_runtime_put_autosuspend(ipc_trace->ipc_imem->dev); +- + return ret; + } + +diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c +index 93d17de08786c..ff747fc79aaf8 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c +@@ -6,7 +6,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -52,13 +51,11 @@ static int ipc_wwan_link_open(struct net_device *netdev) + struct iosm_netdev_priv *priv = wwan_netdev_drvpriv(netdev); + struct iosm_wwan *ipc_wwan = priv->ipc_wwan; + int if_id = priv->if_id; +- int ret = 0; + + if (if_id < IP_MUX_SESSION_START || + if_id >= ARRAY_SIZE(ipc_wwan->sub_netlist)) + return -EINVAL; + +- pm_runtime_get_sync(ipc_wwan->ipc_imem->dev); + /* get channel id */ + priv->ch_id = ipc_imem_sys_wwan_open(ipc_wwan->ipc_imem, if_id); + +@@ -66,8 +63,7 @@ static int ipc_wwan_link_open(struct net_device *netdev) + dev_err(ipc_wwan->dev, + "cannot connect wwan0 & id %d to the IPC mem layer", + if_id); +- ret = -ENODEV; +- goto err_out; ++ return -ENODEV; + } + + /* enable tx path, DL data may follow */ +@@ -76,11 +72,7 @@ static int ipc_wwan_link_open(struct net_device *netdev) + dev_dbg(ipc_wwan->dev, "Channel id %d allocated to if_id %d", + priv->ch_id, priv->if_id); + +-err_out: +- pm_runtime_mark_last_busy(ipc_wwan->ipc_imem->dev); +- pm_runtime_put_autosuspend(ipc_wwan->ipc_imem->dev); +- +- return ret; ++ return 0; + } + + /* Bring-down the wwan net link */ +@@ -90,12 +82,9 @@ static int ipc_wwan_link_stop(struct net_device *netdev) + + netif_stop_queue(netdev); + +- pm_runtime_get_sync(priv->ipc_wwan->ipc_imem->dev); + ipc_imem_sys_wwan_close(priv->ipc_wwan->ipc_imem, priv->if_id, + priv->ch_id); + priv->ch_id = -1; +- pm_runtime_mark_last_busy(priv->ipc_wwan->ipc_imem->dev); +- pm_runtime_put_autosuspend(priv->ipc_wwan->ipc_imem->dev); + + return 0; + } +@@ -117,7 +106,6 @@ static netdev_tx_t ipc_wwan_link_transmit(struct sk_buff *skb, + if_id >= ARRAY_SIZE(ipc_wwan->sub_netlist)) + return -EINVAL; + +- pm_runtime_get(ipc_wwan->ipc_imem->dev); + /* Send the SKB to device for transmission */ + ret = ipc_imem_sys_wwan_transmit(ipc_wwan->ipc_imem, + if_id, priv->ch_id, skb); +@@ -131,14 +119,9 @@ static netdev_tx_t ipc_wwan_link_transmit(struct sk_buff *skb, + ret = NETDEV_TX_BUSY; + dev_err(ipc_wwan->dev, "unable to push packets"); + } else { +- pm_runtime_mark_last_busy(ipc_wwan->ipc_imem->dev); +- pm_runtime_put_autosuspend(ipc_wwan->ipc_imem->dev); + goto exit; + } + +- pm_runtime_mark_last_busy(ipc_wwan->ipc_imem->dev); +- pm_runtime_put_autosuspend(ipc_wwan->ipc_imem->dev); +- + return ret; + + exit: +diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c +index daf5d144a8eaf..064592a5d546a 100644 +--- a/drivers/nvme/host/auth.c ++++ b/drivers/nvme/host/auth.c +@@ -341,7 +341,7 @@ static int nvme_auth_process_dhchap_success1(struct nvme_ctrl *ctrl, + struct nvmf_auth_dhchap_success1_data *data = chap->buf; + size_t size = sizeof(*data); + +- if (chap->ctrl_key) ++ if (chap->s2) + size += chap->hash_len; + + if (size > CHAP_BUF_SIZE) { +@@ -825,7 +825,7 @@ static void nvme_queue_auth_work(struct work_struct *work) + goto fail2; + } + +- if (chap->ctrl_key) { ++ if (chap->s2) { + /* DH-HMAC-CHAP Step 5: send success2 */ + dev_dbg(ctrl->device, "%s: qid %d send success2\n", + __func__, chap->qid); +diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c +index d39f3219358b9..09a223642bc12 100644 +--- a/drivers/nvme/host/ioctl.c ++++ b/drivers/nvme/host/ioctl.c +@@ -108,9 +108,13 @@ static void *nvme_add_user_metadata(struct request *req, void __user *ubuf, + if (!buf) + goto out; + +- ret = -EFAULT; +- if ((req_op(req) == REQ_OP_DRV_OUT) && copy_from_user(buf, ubuf, len)) +- goto out_free_meta; ++ if (req_op(req) == REQ_OP_DRV_OUT) { ++ ret = -EFAULT; ++ if (copy_from_user(buf, ubuf, len)) ++ goto out_free_meta; ++ } else { ++ memset(buf, 0, len); ++ } + + bip = bio_integrity_alloc(bio, GFP_KERNEL, 1); + if (IS_ERR(bip)) { +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 347cb5daebc3c..3f0c9ee09a12b 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3329,7 +3329,8 @@ static const struct pci_device_id nvme_id_table[] = { + { PCI_VDEVICE(INTEL, 0x0a54), /* Intel P4500/P4600 */ + .driver_data = NVME_QUIRK_STRIPE_SIZE | + NVME_QUIRK_DEALLOCATE_ZEROES | +- NVME_QUIRK_IGNORE_DEV_SUBNQN, }, ++ NVME_QUIRK_IGNORE_DEV_SUBNQN | ++ NVME_QUIRK_BOGUS_NID, }, + { PCI_VDEVICE(INTEL, 0x0a55), /* Dell Express Flash P4600 */ + .driver_data = NVME_QUIRK_STRIPE_SIZE | + NVME_QUIRK_DEALLOCATE_ZEROES, }, +diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c +index 337a624a537ce..a7fea4cbacd75 100644 +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -638,6 +638,9 @@ static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) + + static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) + { ++ if (!test_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags)) ++ return; ++ + mutex_lock(&queue->queue_lock); + if (test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) + __nvme_rdma_stop_queue(queue); +diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c +index 586458f765f17..1d9854484e2e8 100644 +--- a/drivers/nvme/target/fabrics-cmd-auth.c ++++ b/drivers/nvme/target/fabrics-cmd-auth.c +@@ -333,19 +333,21 @@ done: + __func__, ctrl->cntlid, req->sq->qid, + status, req->error_loc); + req->cqe->result.u64 = 0; +- nvmet_req_complete(req, status); + if (req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2 && + req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) { + unsigned long auth_expire_secs = ctrl->kato ? ctrl->kato : 120; + + mod_delayed_work(system_wq, &req->sq->auth_expired_work, + auth_expire_secs * HZ); +- return; ++ goto complete; + } + /* Final states, clear up variables */ + nvmet_auth_sq_free(req->sq); + if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) + nvmet_ctrl_fatal_error(ctrl); ++ ++complete: ++ nvmet_req_complete(req, status); + } + + static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al) +@@ -514,11 +516,12 @@ void nvmet_execute_auth_receive(struct nvmet_req *req) + kfree(d); + done: + req->cqe->result.u64 = 0; +- nvmet_req_complete(req, status); ++ + if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2) + nvmet_auth_sq_free(req->sq); + else if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE1) { + nvmet_auth_sq_free(req->sq); + nvmet_ctrl_fatal_error(ctrl); + } ++ nvmet_req_complete(req, status); + } +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index cd92d7ddf5ed1..197fc2ecb164d 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -372,6 +372,7 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue) + + static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status) + { ++ queue->rcv_state = NVMET_TCP_RECV_ERR; + if (status == -EPIPE || status == -ECONNRESET) + kernel_sock_shutdown(queue->sock, SHUT_RDWR); + else +@@ -910,15 +911,11 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) + iov.iov_len = sizeof(*icresp); + ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len); + if (ret < 0) +- goto free_crypto; ++ return ret; /* queue removal will cleanup */ + + queue->state = NVMET_TCP_Q_LIVE; + nvmet_prepare_receive_pdu(queue); + return 0; +-free_crypto: +- if (queue->hdr_digest || queue->data_digest) +- nvmet_tcp_free_crypto(queue); +- return ret; + } + + static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue, +diff --git a/drivers/phy/motorola/phy-mapphone-mdm6600.c b/drivers/phy/motorola/phy-mapphone-mdm6600.c +index 1d567604b650d..376d023a0aa90 100644 +--- a/drivers/phy/motorola/phy-mapphone-mdm6600.c ++++ b/drivers/phy/motorola/phy-mapphone-mdm6600.c +@@ -122,16 +122,10 @@ static int phy_mdm6600_power_on(struct phy *x) + { + struct phy_mdm6600 *ddata = phy_get_drvdata(x); + struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE]; +- int error; + + if (!ddata->enabled) + return -ENODEV; + +- error = pinctrl_pm_select_default_state(ddata->dev); +- if (error) +- dev_warn(ddata->dev, "%s: error with default_state: %i\n", +- __func__, error); +- + gpiod_set_value_cansleep(enable_gpio, 1); + + /* Allow aggressive PM for USB, it's only needed for n_gsm port */ +@@ -160,11 +154,6 @@ static int phy_mdm6600_power_off(struct phy *x) + + gpiod_set_value_cansleep(enable_gpio, 0); + +- error = pinctrl_pm_select_sleep_state(ddata->dev); +- if (error) +- dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", +- __func__, error); +- + return 0; + } + +@@ -456,6 +445,7 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata) + { + struct gpio_desc *reset_gpio = + ddata->ctrl_gpios[PHY_MDM6600_RESET]; ++ int error; + + ddata->enabled = false; + phy_mdm6600_cmd(ddata, PHY_MDM6600_CMD_BP_SHUTDOWN_REQ); +@@ -471,6 +461,17 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata) + } else { + dev_err(ddata->dev, "Timed out powering down\n"); + } ++ ++ /* ++ * Keep reset gpio high with padconf internal pull-up resistor to ++ * prevent modem from waking up during deeper SoC idle states. The ++ * gpio bank lines can have glitches if not in the always-on wkup ++ * domain. ++ */ ++ error = pinctrl_pm_select_sleep_state(ddata->dev); ++ if (error) ++ dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", ++ __func__, error); + } + + static void phy_mdm6600_deferred_power_on(struct work_struct *work) +@@ -571,12 +572,6 @@ static int phy_mdm6600_probe(struct platform_device *pdev) + ddata->dev = &pdev->dev; + platform_set_drvdata(pdev, ddata); + +- /* Active state selected in phy_mdm6600_power_on() */ +- error = pinctrl_pm_select_sleep_state(ddata->dev); +- if (error) +- dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", +- __func__, error); +- + error = phy_mdm6600_init_lines(ddata); + if (error) + return error; +@@ -627,10 +622,12 @@ idle: + pm_runtime_put_autosuspend(ddata->dev); + + cleanup: +- if (error < 0) ++ if (error < 0) { + phy_mdm6600_device_power_off(ddata); +- pm_runtime_disable(ddata->dev); +- pm_runtime_dont_use_autosuspend(ddata->dev); ++ pm_runtime_disable(ddata->dev); ++ pm_runtime_dont_use_autosuspend(ddata->dev); ++ } ++ + return error; + } + +@@ -639,6 +636,7 @@ static void phy_mdm6600_remove(struct platform_device *pdev) + struct phy_mdm6600 *ddata = platform_get_drvdata(pdev); + struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET]; + ++ pm_runtime_get_noresume(ddata->dev); + pm_runtime_dont_use_autosuspend(ddata->dev); + pm_runtime_put_sync(ddata->dev); + pm_runtime_disable(ddata->dev); +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +index bebce8c591a30..3e6bec4c4d6ce 100644 +--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +@@ -772,10 +772,10 @@ static const struct qmp_phy_init_tbl sm8550_usb3_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_PCS_TX_RX_CONFIG, 0x0c), + QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_EQ_CONFIG1, 0x4b), + QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_EQ_CONFIG5, 0x10), +- QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1, 0x68), + }; + + static const struct qmp_phy_init_tbl sm8550_usb3_pcs_usb_tbl[] = { ++ QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1, 0x68), + QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8), + QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07), + QMP_PHY_INIT_CFG(QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L, 0x40), +@@ -2649,6 +2649,7 @@ static int qmp_combo_usb_power_on(struct phy *phy) + void __iomem *tx2 = qmp->tx2; + void __iomem *rx2 = qmp->rx2; + void __iomem *pcs = qmp->pcs; ++ void __iomem *pcs_usb = qmp->pcs_usb; + void __iomem *status; + unsigned int val; + int ret; +@@ -2670,6 +2671,9 @@ static int qmp_combo_usb_power_on(struct phy *phy) + + qmp_combo_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); + ++ if (pcs_usb) ++ qmp_combo_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num); ++ + if (cfg->has_pwrdn_delay) + usleep_range(10, 20); + +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h +index 9510e63ba9d8a..c38530d6776b4 100644 +--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-usb-v6.h +@@ -12,7 +12,7 @@ + #define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG3 0xcc + #define QPHY_USB_V6_PCS_LOCK_DETECT_CONFIG6 0xd8 + #define QPHY_USB_V6_PCS_REFGEN_REQ_CONFIG1 0xdc +-#define QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1 0x90 ++#define QPHY_USB_V6_PCS_POWER_STATE_CONFIG1 0x90 + #define QPHY_USB_V6_PCS_RX_SIGDET_LVL 0x188 + #define QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 + #define QPHY_USB_V6_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 +@@ -23,6 +23,7 @@ + #define QPHY_USB_V6_PCS_EQ_CONFIG1 0x1dc + #define QPHY_USB_V6_PCS_EQ_CONFIG5 0x1ec + ++#define QPHY_USB_V6_PCS_USB3_POWER_STATE_CONFIG1 0x00 + #define QPHY_USB_V6_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL 0x18 + #define QPHY_USB_V6_PCS_USB3_RXEQTRAINING_DFE_TIME_S2 0x3c + #define QPHY_USB_V6_PCS_USB3_RCVR_DTCT_DLY_U3_L 0x40 +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +index 466f0a56c82e1..575329004b901 100644 +--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +@@ -1480,8 +1480,6 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V5_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0xaa), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCS_TX_RX_CONFIG, 0x0c), +- QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07), +- QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_CDR_RESET_TIME, 0x0a), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG1, 0x88), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG2, 0x13), +@@ -1490,6 +1488,11 @@ static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21), + }; + ++static const struct qmp_phy_init_tbl sc8280xp_usb3_uniphy_pcs_usb_tbl[] = { ++ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07), ++ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8), ++}; ++ + static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG1, 0xc4), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_LOCK_DETECT_CONFIG2, 0x89), +@@ -1499,9 +1502,6 @@ static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V5_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0xaa), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCS_TX_RX_CONFIG, 0x0c), +- QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07), +- QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8), +- QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_POWER_STATE_CONFIG1, 0x6f), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_CDR_RESET_TIME, 0x0a), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG1, 0x88), + QMP_PHY_INIT_CFG(QPHY_V5_PCS_ALIGN_DETECT_CONFIG2, 0x13), +@@ -1510,6 +1510,12 @@ static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x21), + }; + ++static const struct qmp_phy_init_tbl sa8775p_usb3_uniphy_pcs_usb_tbl[] = { ++ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2, 0x07), ++ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL, 0xf8), ++ QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_POWER_STATE_CONFIG1, 0x6f), ++}; ++ + struct qmp_usb_offsets { + u16 serdes; + u16 pcs; +@@ -1788,6 +1794,8 @@ static const struct qmp_phy_cfg sa8775p_usb3_uniphy_cfg = { + .rx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_rx_tbl), + .pcs_tbl = sa8775p_usb3_uniphy_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_tbl), ++ .pcs_usb_tbl = sa8775p_usb3_uniphy_pcs_usb_tbl, ++ .pcs_usb_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_usb_tbl), + .clk_list = qmp_v4_phy_clk_l, + .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), + .reset_list = qcm2290_usb3phy_reset_l, +@@ -1833,6 +1841,8 @@ static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = { + .rx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_rx_tbl), + .pcs_tbl = sc8280xp_usb3_uniphy_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_pcs_tbl), ++ .pcs_usb_tbl = sc8280xp_usb3_uniphy_pcs_usb_tbl, ++ .pcs_usb_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_pcs_usb_tbl), + .clk_list = qmp_v4_phy_clk_l, + .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), + .reset_list = qcm2290_usb3phy_reset_l, +@@ -2233,6 +2243,7 @@ static int qmp_usb_power_on(struct phy *phy) + void __iomem *tx = qmp->tx; + void __iomem *rx = qmp->rx; + void __iomem *pcs = qmp->pcs; ++ void __iomem *pcs_usb = qmp->pcs_usb; + void __iomem *status; + unsigned int val; + int ret; +@@ -2256,6 +2267,9 @@ static int qmp_usb_power_on(struct phy *phy) + + qmp_usb_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); + ++ if (pcs_usb) ++ qmp_usb_configure(pcs_usb, cfg->pcs_usb_tbl, cfg->pcs_usb_tbl_num); ++ + if (cfg->has_pwrdn_delay) + usleep_range(10, 20); + +diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c +index b84781cfc2596..401886c813449 100644 +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -1012,20 +1012,17 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev, + + static struct pinctrl *find_pinctrl(struct device *dev) + { +- struct pinctrl *entry, *p = NULL; ++ struct pinctrl *p; + + mutex_lock(&pinctrl_list_mutex); +- +- list_for_each_entry(entry, &pinctrl_list, node) { +- if (entry->dev == dev) { +- p = entry; +- kref_get(&p->users); +- break; ++ list_for_each_entry(p, &pinctrl_list, node) ++ if (p->dev == dev) { ++ mutex_unlock(&pinctrl_list_mutex); ++ return p; + } +- } + + mutex_unlock(&pinctrl_list_mutex); +- return p; ++ return NULL; + } + + static void pinctrl_free(struct pinctrl *p, bool inlist); +@@ -1133,6 +1130,7 @@ struct pinctrl *pinctrl_get(struct device *dev) + p = find_pinctrl(dev); + if (p) { + dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n"); ++ kref_get(&p->users); + return p; + } + +diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c +index fdb6585a92346..65088972dc942 100644 +--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c ++++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c +@@ -31,7 +31,8 @@ struct lpi_pinctrl { + char __iomem *tlmm_base; + char __iomem *slew_base; + struct clk_bulk_data clks[MAX_LPI_NUM_CLKS]; +- struct mutex slew_access_lock; ++ /* Protects from concurrent register updates */ ++ struct mutex lock; + DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO); + const struct lpi_pinctrl_variant_data *data; + }; +@@ -102,6 +103,7 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function, + if (WARN_ON(i == g->nfuncs)) + return -EINVAL; + ++ mutex_lock(&pctrl->lock); + val = lpi_gpio_read(pctrl, pin, LPI_GPIO_CFG_REG); + + /* +@@ -127,6 +129,7 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function, + + u32p_replace_bits(&val, i, LPI_GPIO_FUNCTION_MASK); + lpi_gpio_write(pctrl, pin, LPI_GPIO_CFG_REG, val); ++ mutex_unlock(&pctrl->lock); + + return 0; + } +@@ -232,14 +235,14 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group, + if (slew_offset == LPI_NO_SLEW) + break; + +- mutex_lock(&pctrl->slew_access_lock); ++ mutex_lock(&pctrl->lock); + + sval = ioread32(pctrl->slew_base + LPI_SLEW_RATE_CTL_REG); + sval &= ~(LPI_SLEW_RATE_MASK << slew_offset); + sval |= arg << slew_offset; + iowrite32(sval, pctrl->slew_base + LPI_SLEW_RATE_CTL_REG); + +- mutex_unlock(&pctrl->slew_access_lock); ++ mutex_unlock(&pctrl->lock); + break; + default: + return -EINVAL; +@@ -255,6 +258,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group, + lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG, val); + } + ++ mutex_lock(&pctrl->lock); + val = lpi_gpio_read(pctrl, group, LPI_GPIO_CFG_REG); + + u32p_replace_bits(&val, pullup, LPI_GPIO_PULL_MASK); +@@ -263,6 +267,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group, + u32p_replace_bits(&val, output_enabled, LPI_GPIO_OE_MASK); + + lpi_gpio_write(pctrl, group, LPI_GPIO_CFG_REG, val); ++ mutex_unlock(&pctrl->lock); + + return 0; + } +@@ -464,7 +469,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev) + pctrl->chip.label = dev_name(dev); + pctrl->chip.can_sleep = false; + +- mutex_init(&pctrl->slew_access_lock); ++ mutex_init(&pctrl->lock); + + pctrl->ctrl = devm_pinctrl_register(dev, &pctrl->desc, pctrl); + if (IS_ERR(pctrl->ctrl)) { +@@ -486,7 +491,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev) + return 0; + + err_pinctrl: +- mutex_destroy(&pctrl->slew_access_lock); ++ mutex_destroy(&pctrl->lock); + clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks); + + return ret; +@@ -498,7 +503,7 @@ int lpi_pinctrl_remove(struct platform_device *pdev) + struct lpi_pinctrl *pctrl = platform_get_drvdata(pdev); + int i; + +- mutex_destroy(&pctrl->slew_access_lock); ++ mutex_destroy(&pctrl->lock); + clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks); + + for (i = 0; i < pctrl->data->npins; i++) +diff --git a/drivers/platform/surface/surface_platform_profile.c b/drivers/platform/surface/surface_platform_profile.c +index f433a13c3689a..a5a3941b3f43a 100644 +--- a/drivers/platform/surface/surface_platform_profile.c ++++ b/drivers/platform/surface/surface_platform_profile.c +@@ -159,8 +159,7 @@ static int surface_platform_profile_probe(struct ssam_device *sdev) + set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, tpd->handler.choices); + set_bit(PLATFORM_PROFILE_PERFORMANCE, tpd->handler.choices); + +- platform_profile_register(&tpd->handler); +- return 0; ++ return platform_profile_register(&tpd->handler); + } + + static void surface_platform_profile_remove(struct ssam_device *sdev) +diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c +index cadbb557a108b..1417e230edbd8 100644 +--- a/drivers/platform/x86/apple-gmux.c ++++ b/drivers/platform/x86/apple-gmux.c +@@ -105,6 +105,8 @@ struct apple_gmux_config { + #define GMUX_BRIGHTNESS_MASK 0x00ffffff + #define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK + ++# define MMIO_GMUX_MAX_BRIGHTNESS 0xffff ++ + static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port) + { + return inb(gmux_data->iostart + port); +@@ -857,7 +859,17 @@ get_version: + + memset(&props, 0, sizeof(props)); + props.type = BACKLIGHT_PLATFORM; +- props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS); ++ ++ /* ++ * All MMIO gmux's have 0xffff as max brightness, but some iMacs incorrectly ++ * report 0x03ff, despite the firmware being happy to set 0xffff as the brightness ++ * at boot. Force 0xffff for all MMIO gmux's so they all have the correct brightness ++ * range. ++ */ ++ if (type == APPLE_GMUX_TYPE_MMIO) ++ props.max_brightness = MMIO_GMUX_MAX_BRIGHTNESS; ++ else ++ props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS); + + #if IS_REACHABLE(CONFIG_ACPI_VIDEO) + register_bdev = acpi_video_get_backlight_type() == acpi_backlight_apple_gmux; +diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c +index d85d895fee894..df1db54d4e183 100644 +--- a/drivers/platform/x86/asus-nb-wmi.c ++++ b/drivers/platform/x86/asus-nb-wmi.c +@@ -531,6 +531,9 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) + static const struct key_entry asus_nb_wmi_keymap[] = { + { KE_KEY, ASUS_WMI_BRN_DOWN, { KEY_BRIGHTNESSDOWN } }, + { KE_KEY, ASUS_WMI_BRN_UP, { KEY_BRIGHTNESSUP } }, ++ { KE_KEY, 0x2a, { KEY_SELECTIVE_SCREENSHOT } }, ++ { KE_IGNORE, 0x2b, }, /* PrintScreen (also send via PS/2) on newer models */ ++ { KE_IGNORE, 0x2c, }, /* CapsLock (also send via PS/2) on newer models */ + { KE_KEY, 0x30, { KEY_VOLUMEUP } }, + { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, + { KE_KEY, 0x32, { KEY_MUTE } }, +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 8bef66a2f0ce7..66b9fa1d76985 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -3268,7 +3268,6 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) + { + unsigned int key_value = 1; + bool autorelease = 1; +- int orig_code = code; + + if (asus->driver->key_filter) { + asus->driver->key_filter(asus->driver, &code, &key_value, +@@ -3277,16 +3276,10 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) + return; + } + +- if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) +- code = ASUS_WMI_BRN_UP; +- else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX) +- code = ASUS_WMI_BRN_DOWN; +- +- if (code == ASUS_WMI_BRN_DOWN || code == ASUS_WMI_BRN_UP) { +- if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { +- asus_wmi_backlight_notify(asus, orig_code); +- return; +- } ++ if (acpi_video_get_backlight_type() == acpi_backlight_vendor && ++ code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNDOWN_MAX) { ++ asus_wmi_backlight_notify(asus, code); ++ return; + } + + if (code == NOTIFY_KBD_BRTUP) { +diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h +index a478ebfd34dfa..fc41d1b1bb7f8 100644 +--- a/drivers/platform/x86/asus-wmi.h ++++ b/drivers/platform/x86/asus-wmi.h +@@ -18,7 +18,7 @@ + #include + + #define ASUS_WMI_KEY_IGNORE (-1) +-#define ASUS_WMI_BRN_DOWN 0x20 ++#define ASUS_WMI_BRN_DOWN 0x2e + #define ASUS_WMI_BRN_UP 0x2f + + struct module; +diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +index 1152deaa0078e..33ab207493e3e 100644 +--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c ++++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +@@ -176,7 +176,7 @@ show_uncore_data(initial_max_freq_khz); + + static int create_attr_group(struct uncore_data *data, char *name) + { +- int ret, index = 0; ++ int ret, freq, index = 0; + + init_attribute_rw(max_freq_khz); + init_attribute_rw(min_freq_khz); +@@ -197,7 +197,11 @@ static int create_attr_group(struct uncore_data *data, char *name) + data->uncore_attrs[index++] = &data->min_freq_khz_dev_attr.attr; + data->uncore_attrs[index++] = &data->initial_min_freq_khz_dev_attr.attr; + data->uncore_attrs[index++] = &data->initial_max_freq_khz_dev_attr.attr; +- data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr; ++ ++ ret = uncore_read_freq(data, &freq); ++ if (!ret) ++ data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr; ++ + data->uncore_attrs[index] = NULL; + + data->uncore_attr_group.name = name; +diff --git a/drivers/platform/x86/msi-ec.c b/drivers/platform/x86/msi-ec.c +index f26a3121092f9..492eb383ee7a9 100644 +--- a/drivers/platform/x86/msi-ec.c ++++ b/drivers/platform/x86/msi-ec.c +@@ -276,14 +276,13 @@ static struct msi_ec_conf CONF2 __initdata = { + + static const char * const ALLOWED_FW_3[] __initconst = { + "1592EMS1.111", +- "E1592IMS.10C", + NULL + }; + + static struct msi_ec_conf CONF3 __initdata = { + .allowed_fw = ALLOWED_FW_3, + .charge_control = { +- .address = 0xef, ++ .address = 0xd7, + .offset_start = 0x8a, + .offset_end = 0x80, + .range_min = 0x8a, +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index f9301a9382e74..0c67337726984 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -42,6 +42,21 @@ static const struct ts_dmi_data archos_101_cesium_educ_data = { + .properties = archos_101_cesium_educ_props, + }; + ++static const struct property_entry bush_bush_windows_tablet_props[] = { ++ PROPERTY_ENTRY_U32("touchscreen-size-x", 1850), ++ PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), ++ PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), ++ PROPERTY_ENTRY_U32("silead,max-fingers", 10), ++ PROPERTY_ENTRY_BOOL("silead,home-button"), ++ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-bush-bush-windows-tablet.fw"), ++ { } ++}; ++ ++static const struct ts_dmi_data bush_bush_windows_tablet_data = { ++ .acpi_name = "MSSL1680:00", ++ .properties = bush_bush_windows_tablet_props, ++}; ++ + static const struct property_entry chuwi_hi8_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 1665), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), +@@ -756,6 +771,21 @@ static const struct ts_dmi_data pipo_w11_data = { + .properties = pipo_w11_props, + }; + ++static const struct property_entry positivo_c4128b_props[] = { ++ PROPERTY_ENTRY_U32("touchscreen-min-x", 4), ++ PROPERTY_ENTRY_U32("touchscreen-min-y", 13), ++ PROPERTY_ENTRY_U32("touchscreen-size-x", 1915), ++ PROPERTY_ENTRY_U32("touchscreen-size-y", 1269), ++ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-positivo-c4128b.fw"), ++ PROPERTY_ENTRY_U32("silead,max-fingers", 10), ++ { } ++}; ++ ++static const struct ts_dmi_data positivo_c4128b_data = { ++ .acpi_name = "MSSL1680:00", ++ .properties = positivo_c4128b_props, ++}; ++ + static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 32), + PROPERTY_ENTRY_U32("touchscreen-min-y", 16), +@@ -1070,6 +1100,13 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "ARCHOS 101 Cesium Educ"), + }, + }, ++ { ++ /* Bush Windows tablet */ ++ .driver_data = (void *)&bush_bush_windows_tablet_data, ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_NAME, "Bush Windows tablet"), ++ }, ++ }, + { + /* Chuwi Hi8 */ + .driver_data = (void *)&chuwi_hi8_data, +@@ -1480,6 +1517,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"), + }, + }, ++ { ++ /* Positivo C4128B */ ++ .driver_data = (void *)&positivo_c4128b_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C4128B-1"), ++ }, ++ }, + { + /* Point of View mobii wintab p800w (v2.0) */ + .driver_data = (void *)&pov_mobii_wintab_p800w_v20_data, +diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig +index fff07b2bd77b9..62f592e617339 100644 +--- a/drivers/power/reset/Kconfig ++++ b/drivers/power/reset/Kconfig +@@ -307,7 +307,7 @@ config NVMEM_REBOOT_MODE + + config POWER_MLXBF + tristate "Mellanox BlueField power handling driver" +- depends on (GPIO_MLXBF2 && ACPI) ++ depends on (GPIO_MLXBF2 || GPIO_MLXBF3) && ACPI + help + This driver supports reset or low power mode handling for Mellanox BlueField. + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 2820badc7a126..3137e40fcd3e0 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -5724,15 +5724,11 @@ wash: + mutex_lock(®ulator_list_mutex); + regulator_ena_gpio_free(rdev); + mutex_unlock(®ulator_list_mutex); +- put_device(&rdev->dev); +- rdev = NULL; + clean: + if (dangling_of_gpiod) + gpiod_put(config->ena_gpiod); +- if (rdev && rdev->dev.of_node) +- of_node_put(rdev->dev.of_node); +- kfree(rdev); + kfree(config); ++ put_device(&rdev->dev); + rinse: + if (dangling_cfg_gpiod) + gpiod_put(cfg->ena_gpiod); +diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c +index 3ef636935a547..3ff46fc694f85 100644 +--- a/drivers/s390/cio/css.c ++++ b/drivers/s390/cio/css.c +@@ -233,17 +233,19 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid, + */ + ret = dma_set_coherent_mask(&sch->dev, DMA_BIT_MASK(31)); + if (ret) +- goto err; ++ goto err_lock; + /* + * But we don't have such restrictions imposed on the stuff that + * is handled by the streaming API. + */ + ret = dma_set_mask(&sch->dev, DMA_BIT_MASK(64)); + if (ret) +- goto err; ++ goto err_lock; + + return sch; + ++err_lock: ++ kfree(sch->lock); + err: + kfree(sch); + return ERR_PTR(ret); +diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c +index 3fb4553a6442b..7c0c46be3fdb5 100644 +--- a/drivers/thunderbolt/tb.c ++++ b/drivers/thunderbolt/tb.c +@@ -1907,14 +1907,14 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) + in = &sw->ports[ev->port]; + if (!tb_port_is_dpin(in)) { + tb_port_warn(in, "bandwidth request to non-DP IN adapter\n"); +- goto unlock; ++ goto put_sw; + } + + tb_port_dbg(in, "handling bandwidth allocation request\n"); + + if (!usb4_dp_port_bandwidth_mode_enabled(in)) { + tb_port_warn(in, "bandwidth allocation mode not enabled\n"); +- goto unlock; ++ goto put_sw; + } + + ret = usb4_dp_port_requested_bandwidth(in); +@@ -1923,7 +1923,7 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) + tb_port_dbg(in, "no bandwidth request active\n"); + else + tb_port_warn(in, "failed to read requested bandwidth\n"); +- goto unlock; ++ goto put_sw; + } + requested_bw = ret; + +@@ -1932,7 +1932,7 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) + tunnel = tb_find_tunnel(tb, TB_TUNNEL_DP, in, NULL); + if (!tunnel) { + tb_port_warn(in, "failed to find tunnel\n"); +- goto unlock; ++ goto put_sw; + } + + out = tunnel->dst_port; +@@ -1959,6 +1959,8 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) + tb_recalc_estimated_bandwidth(tb); + } + ++put_sw: ++ tb_switch_put(sw); + unlock: + mutex_unlock(&tb->lock); + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 7994a4549a6c8..45dcfaadaf98e 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -203,6 +203,9 @@ static void option_instat_callback(struct urb *urb); + #define DELL_PRODUCT_5829E_ESIM 0x81e4 + #define DELL_PRODUCT_5829E 0x81e6 + ++#define DELL_PRODUCT_FM101R 0x8213 ++#define DELL_PRODUCT_FM101R_ESIM 0x8215 ++ + #define KYOCERA_VENDOR_ID 0x0c88 + #define KYOCERA_PRODUCT_KPC650 0x17da + #define KYOCERA_PRODUCT_KPC680 0x180a +@@ -1108,6 +1111,8 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(0) | RSVD(6) }, + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM), + .driver_info = RSVD(0) | RSVD(6) }, ++ { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R_ESIM, 0xff) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, +@@ -1290,6 +1295,7 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(0) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */ + .driver_info = NCTRL(0) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1035, 0xff) }, /* Telit LE910C4-WWX (ECM) */ + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), + .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1), +@@ -2262,6 +2268,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ + { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, + { } /* Terminating entry */ +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index a4cb4b6429870..da519c1b6ad08 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -682,18 +682,30 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + u64 search_start; + int ret; + +- if (test_bit(BTRFS_ROOT_DELETING, &root->state)) +- btrfs_err(fs_info, +- "COW'ing blocks on a fs root that's being dropped"); +- +- if (trans->transaction != fs_info->running_transaction) +- WARN(1, KERN_CRIT "trans %llu running %llu\n", +- trans->transid, +- fs_info->running_transaction->transid); ++ if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++ "attempt to COW block %llu on root %llu that is being deleted", ++ buf->start, btrfs_root_id(root)); ++ return -EUCLEAN; ++ } + +- if (trans->transid != fs_info->generation) +- WARN(1, KERN_CRIT "trans %llu running %llu\n", +- trans->transid, fs_info->generation); ++ /* ++ * COWing must happen through a running transaction, which always ++ * matches the current fs generation (it's a transaction with a state ++ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs ++ * into error state to prevent the commit of any transaction. ++ */ ++ if (unlikely(trans->transaction != fs_info->running_transaction || ++ trans->transid != fs_info->generation)) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++"unexpected transaction when attempting to COW block %llu on root %llu, transaction %llu running transaction %llu fs generation %llu", ++ buf->start, btrfs_root_id(root), trans->transid, ++ fs_info->running_transaction->transid, ++ fs_info->generation); ++ return -EUCLEAN; ++ } + + if (!should_cow_block(trans, root, buf)) { + *cow_ret = buf; +@@ -805,8 +817,22 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, + int progress_passed = 0; + struct btrfs_disk_key disk_key; + +- WARN_ON(trans->transaction != fs_info->running_transaction); +- WARN_ON(trans->transid != fs_info->generation); ++ /* ++ * COWing must happen through a running transaction, which always ++ * matches the current fs generation (it's a transaction with a state ++ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs ++ * into error state to prevent the commit of any transaction. ++ */ ++ if (unlikely(trans->transaction != fs_info->running_transaction || ++ trans->transid != fs_info->generation)) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++"unexpected transaction when attempting to reallocate parent %llu for root %llu, transaction %llu running transaction %llu fs generation %llu", ++ parent->start, btrfs_root_id(root), trans->transid, ++ fs_info->running_transaction->transid, ++ fs_info->generation); ++ return -EUCLEAN; ++ } + + parent_nritems = btrfs_header_nritems(parent); + blocksize = fs_info->nodesize; +diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c +index 6a13cf00218bc..9fe4ccca50a06 100644 +--- a/fs/btrfs/delayed-ref.c ++++ b/fs/btrfs/delayed-ref.c +@@ -103,24 +103,17 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans) + * Transfer bytes to our delayed refs rsv. + * + * @fs_info: the filesystem +- * @src: source block rsv to transfer from + * @num_bytes: number of bytes to transfer + * +- * This transfers up to the num_bytes amount from the src rsv to the ++ * This transfers up to the num_bytes amount, previously reserved, to the + * delayed_refs_rsv. Any extra bytes are returned to the space info. + */ + void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, +- struct btrfs_block_rsv *src, + u64 num_bytes) + { + struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv; + u64 to_free = 0; + +- spin_lock(&src->lock); +- src->reserved -= num_bytes; +- src->size -= num_bytes; +- spin_unlock(&src->lock); +- + spin_lock(&delayed_refs_rsv->lock); + if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) { + u64 delta = delayed_refs_rsv->size - +@@ -163,6 +156,8 @@ int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, + struct btrfs_block_rsv *block_rsv = &fs_info->delayed_refs_rsv; + u64 limit = btrfs_calc_delayed_ref_bytes(fs_info, 1); + u64 num_bytes = 0; ++ u64 refilled_bytes; ++ u64 to_free; + int ret = -ENOSPC; + + spin_lock(&block_rsv->lock); +@@ -178,9 +173,38 @@ int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, + ret = btrfs_reserve_metadata_bytes(fs_info, block_rsv, num_bytes, flush); + if (ret) + return ret; +- btrfs_block_rsv_add_bytes(block_rsv, num_bytes, false); +- trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv", +- 0, num_bytes, 1); ++ ++ /* ++ * We may have raced with someone else, so check again if we the block ++ * reserve is still not full and release any excess space. ++ */ ++ spin_lock(&block_rsv->lock); ++ if (block_rsv->reserved < block_rsv->size) { ++ u64 needed = block_rsv->size - block_rsv->reserved; ++ ++ if (num_bytes >= needed) { ++ block_rsv->reserved += needed; ++ block_rsv->full = true; ++ to_free = num_bytes - needed; ++ refilled_bytes = needed; ++ } else { ++ block_rsv->reserved += num_bytes; ++ to_free = 0; ++ refilled_bytes = num_bytes; ++ } ++ } else { ++ to_free = num_bytes; ++ refilled_bytes = 0; ++ } ++ spin_unlock(&block_rsv->lock); ++ ++ if (to_free > 0) ++ btrfs_space_info_free_bytes_may_use(fs_info, block_rsv->space_info, ++ to_free); ++ ++ if (refilled_bytes > 0) ++ trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv", 0, ++ refilled_bytes, 1); + return 0; + } + +diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h +index b8e14b0ba5f16..fd9bf2b709c0e 100644 +--- a/fs/btrfs/delayed-ref.h ++++ b/fs/btrfs/delayed-ref.h +@@ -407,7 +407,6 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans); + int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, + enum btrfs_reserve_flush_enum flush); + void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, +- struct btrfs_block_rsv *src, + u64 num_bytes); + bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 0917c5f39e3d0..2cf8d646085c2 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -1715,12 +1715,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, + parent = ref->parent; + ref_root = ref->root; + +- if (node->ref_mod != 1) { ++ if (unlikely(node->ref_mod != 1)) { + btrfs_err(trans->fs_info, +- "btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu", ++ "btree block %llu has %d references rather than 1: action %d ref_root %llu parent %llu", + node->bytenr, node->ref_mod, node->action, ref_root, + parent); +- return -EIO; ++ return -EUCLEAN; + } + if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { + BUG_ON(!extent_op || !extent_op->update_flags); +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index d27b0d86b8e2c..bf35b6fce8f07 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -2978,7 +2978,7 @@ static void get_block_group_info(struct list_head *groups_list, + static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info, + void __user *arg) + { +- struct btrfs_ioctl_space_args space_args; ++ struct btrfs_ioctl_space_args space_args = { 0 }; + struct btrfs_ioctl_space_info space; + struct btrfs_ioctl_space_info *dest; + struct btrfs_ioctl_space_info *dest_orig; +@@ -4338,7 +4338,7 @@ static int _btrfs_ioctl_send(struct inode *inode, void __user *argp, bool compat + + if (compat) { + #if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT) +- struct btrfs_ioctl_send_args_32 args32; ++ struct btrfs_ioctl_send_args_32 args32 = { 0 }; + + ret = copy_from_user(&args32, argp, sizeof(args32)); + if (ret) +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index 5bbd288b9cb54..0554ca2a8e3ba 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -625,14 +625,14 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, + reloc_reserved = true; + } + +- ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes, flush); ++ ret = btrfs_reserve_metadata_bytes(fs_info, rsv, num_bytes, flush); + if (ret) + goto reserve_fail; + if (delayed_refs_bytes) { +- btrfs_migrate_to_delayed_refs_rsv(fs_info, rsv, +- delayed_refs_bytes); ++ btrfs_migrate_to_delayed_refs_rsv(fs_info, delayed_refs_bytes); + num_bytes -= delayed_refs_bytes; + } ++ btrfs_block_rsv_add_bytes(rsv, num_bytes, true); + + if (rsv->space_info->force_alloc) + do_chunk_alloc = true; +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 365a1cc0a3c35..a00e7a0bc713d 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -4722,7 +4722,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, + struct extent_buffer *leaf; + int slot; + int ins_nr = 0; +- int start_slot; ++ int start_slot = 0; + int ret; + + if (!(inode->flags & BTRFS_INODE_PREALLOC)) +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 51070c0d4141e..5019e9244d2d2 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -5125,7 +5125,7 @@ static void init_alloc_chunk_ctl_policy_regular( + ASSERT(space_info); + + ctl->max_chunk_size = READ_ONCE(space_info->chunk_size); +- ctl->max_stripe_size = ctl->max_chunk_size; ++ ctl->max_stripe_size = min_t(u64, ctl->max_chunk_size, SZ_1G); + + if (ctl->type & BTRFS_BLOCK_GROUP_SYSTEM) + ctl->devs_max = min_t(int, ctl->devs_max, BTRFS_MAX_DEVS_SYS_CHUNK); +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index aca4b48113945..d532a93e980d7 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -1535,10 +1535,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb, + + if (wbc->pages_skipped) { + /* +- * writeback is not making progress due to locked +- * buffers. Skip this inode for now. ++ * Writeback is not making progress due to locked buffers. ++ * Skip this inode for now. Although having skipped pages ++ * is odd for clean inodes, it can happen for some ++ * filesystems so handle that gracefully. + */ +- redirty_tail_locked(inode, wb); ++ if (inode->i_state & I_DIRTY_ALL) ++ redirty_tail_locked(inode, wb); ++ else ++ inode_cgwb_move_to_attached(inode, wb); + return; + } + +diff --git a/fs/namei.c b/fs/namei.c +index 567ee547492bc..94565bd7e73f6 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -188,7 +188,7 @@ getname_flags(const char __user *filename, int flags, int *empty) + } + } + +- result->refcnt = 1; ++ atomic_set(&result->refcnt, 1); + /* The empty path is special. */ + if (unlikely(!len)) { + if (empty) +@@ -249,7 +249,7 @@ getname_kernel(const char * filename) + memcpy((char *)result->name, filename, len); + result->uptr = NULL; + result->aname = NULL; +- result->refcnt = 1; ++ atomic_set(&result->refcnt, 1); + audit_getname(result); + + return result; +@@ -261,9 +261,10 @@ void putname(struct filename *name) + if (IS_ERR(name)) + return; + +- BUG_ON(name->refcnt <= 0); ++ if (WARN_ON_ONCE(!atomic_read(&name->refcnt))) ++ return; + +- if (--name->refcnt > 0) ++ if (!atomic_dec_and_test(&name->refcnt)) + return; + + if (name->name != name->iname) { +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index a1dc338649062..ef817a0475ffa 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -2520,9 +2520,9 @@ ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo, + return i; + } + +-static int +-ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) ++static int ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) + { ++ struct pnfs_layout_hdr *lo; + struct nfs4_flexfile_layout *ff_layout; + const int dev_count = PNFS_LAYOUTSTATS_MAXDEV; + +@@ -2533,11 +2533,14 @@ ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) + return -ENOMEM; + + spin_lock(&args->inode->i_lock); +- ff_layout = FF_LAYOUT_FROM_HDR(NFS_I(args->inode)->layout); +- args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr, +- &args->devinfo[0], +- dev_count, +- NFS4_FF_OP_LAYOUTSTATS); ++ lo = NFS_I(args->inode)->layout; ++ if (lo && pnfs_layout_is_valid(lo)) { ++ ff_layout = FF_LAYOUT_FROM_HDR(lo); ++ args->num_dev = ff_layout_mirror_prepare_stats( ++ &ff_layout->generic_hdr, &args->devinfo[0], dev_count, ++ NFS4_FF_OP_LAYOUTSTATS); ++ } else ++ args->num_dev = 0; + spin_unlock(&args->inode->i_lock); + if (!args->num_dev) { + kfree(args->devinfo); +diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c +index 063e00aff87ed..28704f924612c 100644 +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -81,7 +81,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, + if (status == 0) { + if (nfs_should_remove_suid(inode)) { + spin_lock(&inode->i_lock); +- nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE); ++ nfs_set_cache_invalid(inode, ++ NFS_INO_REVAL_FORCED | NFS_INO_INVALID_MODE); + spin_unlock(&inode->i_lock); + } + status = nfs_post_op_update_inode_force_wcc(inode, +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 51029e4b60f56..5f088e3eeca1d 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -8870,8 +8870,6 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre + /* Save the EXCHANGE_ID verifier session trunk tests */ + memcpy(clp->cl_confirm.data, argp->verifier.data, + sizeof(clp->cl_confirm.data)); +- if (resp->flags & EXCHGID4_FLAG_USE_PNFS_DS) +- set_bit(NFS_CS_DS, &clp->cl_flags); + out: + trace_nfs4_exchange_id(clp, status); + rpc_put_task(task); +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index 306cba0b9e69a..84343aefbbd64 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -2634,31 +2634,44 @@ pnfs_should_return_unused_layout(struct pnfs_layout_hdr *lo, + return mode == 0; + } + +-static int +-pnfs_layout_return_unused_byserver(struct nfs_server *server, void *data) ++static int pnfs_layout_return_unused_byserver(struct nfs_server *server, ++ void *data) + { + const struct pnfs_layout_range *range = data; ++ const struct cred *cred; + struct pnfs_layout_hdr *lo; + struct inode *inode; ++ nfs4_stateid stateid; ++ enum pnfs_iomode iomode; ++ + restart: + rcu_read_lock(); + list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) { +- if (!pnfs_layout_can_be_returned(lo) || ++ inode = lo->plh_inode; ++ if (!inode || !pnfs_layout_can_be_returned(lo) || + test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) + continue; +- inode = lo->plh_inode; + spin_lock(&inode->i_lock); +- if (!pnfs_should_return_unused_layout(lo, range)) { ++ if (!lo->plh_inode || ++ !pnfs_should_return_unused_layout(lo, range)) { + spin_unlock(&inode->i_lock); + continue; + } ++ pnfs_get_layout_hdr(lo); ++ pnfs_set_plh_return_info(lo, range->iomode, 0); ++ if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, ++ range, 0) != 0 || ++ !pnfs_prepare_layoutreturn(lo, &stateid, &cred, &iomode)) { ++ spin_unlock(&inode->i_lock); ++ rcu_read_unlock(); ++ pnfs_put_layout_hdr(lo); ++ cond_resched(); ++ goto restart; ++ } + spin_unlock(&inode->i_lock); +- inode = pnfs_grab_inode_layout_hdr(lo); +- if (!inode) +- continue; + rcu_read_unlock(); +- pnfs_mark_layout_for_return(inode, range); +- iput(inode); ++ pnfs_send_layoutreturn(lo, &stateid, &cred, iomode, false); ++ pnfs_put_layout_hdr(lo); + cond_resched(); + goto restart; + } +diff --git a/fs/nfs/write.c b/fs/nfs/write.c +index 8c1ee1a1a28f1..9d82d50ce0b12 100644 +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -788,6 +788,8 @@ static void nfs_inode_add_request(struct nfs_page *req) + */ + static void nfs_inode_remove_request(struct nfs_page *req) + { ++ struct nfs_inode *nfsi = NFS_I(nfs_page_to_inode(req)); ++ + if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) { + struct folio *folio = nfs_page_to_folio(req->wb_head); + struct address_space *mapping = folio_file_mapping(folio); +@@ -802,8 +804,8 @@ static void nfs_inode_remove_request(struct nfs_page *req) + } + + if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) { ++ atomic_long_dec(&nfsi->nrequests); + nfs_release_request(req); +- atomic_long_dec(&NFS_I(nfs_page_to_inode(req))->nrequests); + } + } + +diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c +index f69c451018e33..62fe0b679e586 100644 +--- a/fs/notify/fanotify/fanotify_user.c ++++ b/fs/notify/fanotify/fanotify_user.c +@@ -1585,16 +1585,25 @@ static int fanotify_test_fsid(struct dentry *dentry, __kernel_fsid_t *fsid) + } + + /* Check if filesystem can encode a unique fid */ +-static int fanotify_test_fid(struct dentry *dentry) ++static int fanotify_test_fid(struct dentry *dentry, unsigned int flags) + { ++ unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS; ++ const struct export_operations *nop = dentry->d_sb->s_export_op; ++ ++ /* ++ * We need to make sure that the filesystem supports encoding of ++ * file handles so user can use name_to_handle_at() to compare fids ++ * reported with events to the file handle of watched objects. ++ */ ++ if (!nop) ++ return -EOPNOTSUPP; ++ + /* +- * We need to make sure that the file system supports at least +- * encoding a file handle so user can use name_to_handle_at() to +- * compare fid returned with event to the file handle of watched +- * objects. However, even the relaxed AT_HANDLE_FID flag requires +- * at least empty export_operations for ecoding unique file ids. ++ * For sb/mount mark, we also need to make sure that the filesystem ++ * supports decoding file handles, so user has a way to map back the ++ * reported fids to filesystem objects. + */ +- if (!dentry->d_sb->s_export_op) ++ if (mark_type != FAN_MARK_INODE && !nop->fh_to_dentry) + return -EOPNOTSUPP; + + return 0; +@@ -1812,7 +1821,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, + if (ret) + goto path_put_and_out; + +- ret = fanotify_test_fid(path.dentry); ++ ret = fanotify_test_fid(path.dentry, flags); + if (ret) + goto path_put_and_out; + +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index 33afee0f55593..9ddb2ab23b954 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -2461,10 +2461,12 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim) + { + CLST end, i, zone_len, zlen; + struct wnd_bitmap *wnd = &sbi->used.bitmap; ++ bool dirty = false; + + down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS); + if (!wnd_is_used(wnd, lcn, len)) { +- ntfs_set_state(sbi, NTFS_DIRTY_ERROR); ++ /* mark volume as dirty out of wnd->rw_lock */ ++ dirty = true; + + end = lcn + len; + len = 0; +@@ -2518,6 +2520,8 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim) + + out: + up_write(&wnd->rw_lock); ++ if (dirty) ++ ntfs_set_state(sbi, NTFS_DIRTY_ERROR); + } + + /* +diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c +index 124c6e822623f..cf92b2433f7a7 100644 +--- a/fs/ntfs3/index.c ++++ b/fs/ntfs3/index.c +@@ -729,6 +729,9 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx, + u32 total = le32_to_cpu(hdr->total); + u16 offs[128]; + ++ if (unlikely(!cmp)) ++ return NULL; ++ + fill_table: + if (end > total) + return NULL; +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index 629403ede6e5f..788567d71d939 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -42,9 +42,11 @@ enum utf16_endian; + #define MINUS_ONE_T ((size_t)(-1)) + /* Biggest MFT / smallest cluster */ + #define MAXIMUM_BYTES_PER_MFT 4096 ++#define MAXIMUM_SHIFT_BYTES_PER_MFT 12 + #define NTFS_BLOCKS_PER_MFT_RECORD (MAXIMUM_BYTES_PER_MFT / 512) + + #define MAXIMUM_BYTES_PER_INDEX 4096 ++#define MAXIMUM_SHIFT_BYTES_PER_INDEX 12 + #define NTFS_BLOCKS_PER_INODE (MAXIMUM_BYTES_PER_INDEX / 512) + + /* NTFS specific error code when fixup failed. */ +diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c +index 1a02072b6b0e1..d6b5170253a69 100644 +--- a/fs/ntfs3/super.c ++++ b/fs/ntfs3/super.c +@@ -855,6 +855,11 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size, + + check_boot: + err = -EINVAL; ++ ++ /* Corrupted image; do not read OOB */ ++ if (bh->b_size - sizeof(*boot) < boot_off) ++ goto out; ++ + boot = (struct NTFS_BOOT *)Add2Ptr(bh->b_data, boot_off); + + if (memcmp(boot->system_id, "NTFS ", sizeof("NTFS ") - 1)) { +@@ -901,9 +906,17 @@ check_boot: + goto out; + } + +- sbi->record_size = record_size = +- boot->record_size < 0 ? 1 << (-boot->record_size) : +- (u32)boot->record_size << cluster_bits; ++ if (boot->record_size >= 0) { ++ record_size = (u32)boot->record_size << cluster_bits; ++ } else if (-boot->record_size <= MAXIMUM_SHIFT_BYTES_PER_MFT) { ++ record_size = 1u << (-boot->record_size); ++ } else { ++ ntfs_err(sb, "%s: invalid record size %d.", hint, ++ boot->record_size); ++ goto out; ++ } ++ ++ sbi->record_size = record_size; + sbi->record_bits = blksize_bits(record_size); + sbi->attr_size_tr = (5 * record_size >> 4); // ~320 bytes + +@@ -920,9 +933,15 @@ check_boot: + goto out; + } + +- sbi->index_size = boot->index_size < 0 ? +- 1u << (-boot->index_size) : +- (u32)boot->index_size << cluster_bits; ++ if (boot->index_size >= 0) { ++ sbi->index_size = (u32)boot->index_size << cluster_bits; ++ } else if (-boot->index_size <= MAXIMUM_SHIFT_BYTES_PER_INDEX) { ++ sbi->index_size = 1u << (-boot->index_size); ++ } else { ++ ntfs_err(sb, "%s: invalid index size %d.", hint, ++ boot->index_size); ++ goto out; ++ } + + /* Check index record size. */ + if (sbi->index_size < SECTOR_SIZE || !is_power_of_2(sbi->index_size)) { +diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c +index 023f314e89501..c59d6f5a725a9 100644 +--- a/fs/ntfs3/xattr.c ++++ b/fs/ntfs3/xattr.c +@@ -211,7 +211,8 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, + size = le32_to_cpu(info->size); + + /* Enumerate all xattrs. */ +- for (ret = 0, off = 0; off < size; off += ea_size) { ++ ret = 0; ++ for (off = 0; off + sizeof(struct EA_FULL) < size; off += ea_size) { + ea = Add2Ptr(ea_all, off); + ea_size = unpacked_ea_size(ea); + +@@ -219,6 +220,10 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, + break; + + if (buffer) { ++ /* Check if we can use field ea->name */ ++ if (off + ea_size > size) ++ break; ++ + if (ret + ea->name_len + 1 > bytes_per_buffer) { + err = -ERANGE; + goto out; +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 986d37a4c2750..ab32c6b28d400 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -337,7 +337,7 @@ static int ovl_set_timestamps(struct ovl_fs *ofs, struct dentry *upperdentry, + { + struct iattr attr = { + .ia_valid = +- ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, ++ ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_CTIME, + .ia_atime = stat->atime, + .ia_mtime = stat->mtime, + }; +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 562f2623c9c9f..87a21a18d114a 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -2318,7 +2318,7 @@ struct audit_names; + struct filename { + const char *name; /* pointer to actual string */ + const __user char *uptr; /* original userland pointer */ +- int refcnt; ++ atomic_t refcnt; + struct audit_names *aname; + const char iname[]; + }; +diff --git a/include/linux/mtd/jedec.h b/include/linux/mtd/jedec.h +index 0b6b59f7cfbdc..56047a4e54c9c 100644 +--- a/include/linux/mtd/jedec.h ++++ b/include/linux/mtd/jedec.h +@@ -21,6 +21,9 @@ struct jedec_ecc_info { + /* JEDEC features */ + #define JEDEC_FEATURE_16_BIT_BUS (1 << 0) + ++/* JEDEC Optional Commands */ ++#define JEDEC_OPT_CMD_READ_CACHE BIT(1) ++ + struct nand_jedec_params { + /* rev info and features block */ + /* 'J' 'E' 'S' 'D' */ +diff --git a/include/linux/mtd/onfi.h b/include/linux/mtd/onfi.h +index a7376f9beddfd..55ab2e4d62f94 100644 +--- a/include/linux/mtd/onfi.h ++++ b/include/linux/mtd/onfi.h +@@ -55,6 +55,7 @@ + #define ONFI_SUBFEATURE_PARAM_LEN 4 + + /* ONFI optional commands SET/GET FEATURES supported? */ ++#define ONFI_OPT_CMD_READ_CACHE BIT(1) + #define ONFI_OPT_CMD_SET_GET_FEATURES BIT(2) + + struct nand_onfi_params { +diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h +index 5159d692f9ce5..e8864c4f3921d 100644 +--- a/include/linux/mtd/rawnand.h ++++ b/include/linux/mtd/rawnand.h +@@ -225,6 +225,7 @@ struct gpio_desc; + * struct nand_parameters - NAND generic parameters from the parameter page + * @model: Model name + * @supports_set_get_features: The NAND chip supports setting/getting features ++ * @supports_read_cache: The NAND chip supports read cache operations + * @set_feature_list: Bitmap of features that can be set + * @get_feature_list: Bitmap of features that can be get + * @onfi: ONFI specific parameters +@@ -233,6 +234,7 @@ struct nand_parameters { + /* Generic parameters */ + const char *model; + bool supports_set_get_features; ++ bool supports_read_cache; + DECLARE_BITMAP(set_feature_list, ONFI_FEATURE_NUMBER); + DECLARE_BITMAP(get_feature_list, ONFI_FEATURE_NUMBER); + +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index e657916c9509c..227e9d45f61b6 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -704,6 +704,7 @@ struct perf_event { + /* The cumulative AND of all event_caps for events in this group. */ + int group_caps; + ++ unsigned int group_generation; + struct perf_event *group_leader; + /* + * event->pmu will always point to pmu in which this event belongs. +diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h +index 7b4dd69555e49..27cc1d4643219 100644 +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -3,8 +3,8 @@ + #define _LINUX_VIRTIO_NET_H + + #include ++#include + #include +-#include + #include + + static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_type) +@@ -151,9 +151,22 @@ retry: + unsigned int nh_off = p_off; + struct skb_shared_info *shinfo = skb_shinfo(skb); + +- /* UFO may not include transport header in gso_size. */ +- if (gso_type & SKB_GSO_UDP) ++ switch (gso_type & ~SKB_GSO_TCP_ECN) { ++ case SKB_GSO_UDP: ++ /* UFO may not include transport header in gso_size. */ + nh_off -= thlen; ++ break; ++ case SKB_GSO_UDP_L4: ++ if (!(hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) ++ return -EINVAL; ++ if (skb->csum_offset != offsetof(struct udphdr, check)) ++ return -EINVAL; ++ if (skb->len - p_off > gso_size * UDP_MAX_SEGMENTS) ++ return -EINVAL; ++ if (gso_type != SKB_GSO_UDP_L4) ++ return -EINVAL; ++ break; ++ } + + /* Kernel has a special handling for GSO_BY_FRAGS. */ + if (gso_size == GSO_BY_FRAGS) +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index c0a87558aea71..abb7cb5db9457 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -350,7 +350,7 @@ struct hci_dev { + struct list_head list; + struct mutex lock; + +- char name[8]; ++ const char *name; + unsigned long flags; + __u16 id; + __u8 bus; +@@ -1426,6 +1426,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role); + void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); + + void hci_conn_failed(struct hci_conn *conn, u8 status); ++u8 hci_conn_set_handle(struct hci_conn *conn, u16 handle); + + /* + * hci_conn_get() and hci_conn_put() are used to control the life-time of an +diff --git a/include/net/bluetooth/hci_mon.h b/include/net/bluetooth/hci_mon.h +index 2d5fcda1bcd05..082f89531b889 100644 +--- a/include/net/bluetooth/hci_mon.h ++++ b/include/net/bluetooth/hci_mon.h +@@ -56,7 +56,7 @@ struct hci_mon_new_index { + __u8 type; + __u8 bus; + bdaddr_t bdaddr; +- char name[8]; ++ char name[8] __nonstring; + } __packed; + #define HCI_MON_NEW_INDEX_SIZE 16 + +diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h +index b516a0f4a55b8..57eeb07aeb251 100644 +--- a/include/net/bluetooth/hci_sync.h ++++ b/include/net/bluetooth/hci_sync.h +@@ -5,6 +5,9 @@ + * Copyright (C) 2021 Intel Corporation + */ + ++#define UINT_PTR(_handle) ((void *)((uintptr_t)_handle)) ++#define PTR_UINT(_ptr) ((uintptr_t)((void *)_ptr)) ++ + typedef int (*hci_cmd_sync_work_func_t)(struct hci_dev *hdev, void *data); + typedef void (*hci_cmd_sync_work_destroy_t)(struct hci_dev *hdev, void *data, + int err); +diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h +index f0c13864180e2..15de07d365405 100644 +--- a/include/net/ip_fib.h ++++ b/include/net/ip_fib.h +@@ -154,6 +154,7 @@ struct fib_info { + int fib_nhs; + bool fib_nh_is_v6; + bool nh_updated; ++ bool pfsrc_removed; + struct nexthop *nh; + struct rcu_head rcu; + struct fib_nh fib_nh[]; +diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h +index bd7c3be4af5d7..423b52eca908d 100644 +--- a/include/net/netns/xfrm.h ++++ b/include/net/netns/xfrm.h +@@ -50,6 +50,7 @@ struct netns_xfrm { + struct list_head policy_all; + struct hlist_head *policy_byidx; + unsigned int policy_idx_hmask; ++ unsigned int idx_generator; + struct hlist_head policy_inexact[XFRM_POLICY_MAX]; + struct xfrm_policy_hash policy_bydst[XFRM_POLICY_MAX]; + unsigned int policy_count[XFRM_POLICY_MAX * 2]; +diff --git a/include/net/sock.h b/include/net/sock.h +index 4e787285fc66b..fc189910e63fc 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -336,7 +336,7 @@ struct sk_filter; + * @sk_cgrp_data: cgroup data for this cgroup + * @sk_memcg: this socket's memory cgroup association + * @sk_write_pending: a write to stream socket waits to start +- * @sk_wait_pending: number of threads blocked on this socket ++ * @sk_disconnects: number of disconnect operations performed on this sock + * @sk_state_change: callback to indicate change in the state of the sock + * @sk_data_ready: callback to indicate there is data to be processed + * @sk_write_space: callback to indicate there is bf sending space available +@@ -429,7 +429,7 @@ struct sock { + unsigned int sk_napi_id; + #endif + int sk_rcvbuf; +- int sk_wait_pending; ++ int sk_disconnects; + + struct sk_filter __rcu *sk_filter; + union { +@@ -1189,8 +1189,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) + } + + #define sk_wait_event(__sk, __timeo, __condition, __wait) \ +- ({ int __rc; \ +- __sk->sk_wait_pending++; \ ++ ({ int __rc, __dis = __sk->sk_disconnects; \ + release_sock(__sk); \ + __rc = __condition; \ + if (!__rc) { \ +@@ -1200,8 +1199,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) + } \ + sched_annotate_sleep(); \ + lock_sock(__sk); \ +- __sk->sk_wait_pending--; \ +- __rc = __condition; \ ++ __rc = __dis == __sk->sk_disconnects ? __condition : -EPIPE; \ + __rc; \ + }) + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index b1b1e01c69839..7f684806c2912 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -142,6 +142,9 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); + #define TCP_RTO_MAX ((unsigned)(120*HZ)) + #define TCP_RTO_MIN ((unsigned)(HZ/5)) + #define TCP_TIMEOUT_MIN (2U) /* Min timeout for TCP timers in jiffies */ ++ ++#define TCP_TIMEOUT_MIN_US (2*USEC_PER_MSEC) /* Min TCP timeout in microsecs */ ++ + #define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC6298 2.1 initial RTO value */ + #define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value, now + * used as a fallback RTO for the +diff --git a/include/trace/events/neigh.h b/include/trace/events/neigh.h +index 5eaa1fa991715..833143d0992e0 100644 +--- a/include/trace/events/neigh.h ++++ b/include/trace/events/neigh.h +@@ -39,7 +39,6 @@ TRACE_EVENT(neigh_create, + ), + + TP_fast_assign( +- struct in6_addr *pin6; + __be32 *p32; + + __entry->family = tbl->family; +@@ -47,7 +46,6 @@ TRACE_EVENT(neigh_create, + __entry->entries = atomic_read(&tbl->gc_entries); + __entry->created = n != NULL; + __entry->gc_exempt = exempt_from_gc; +- pin6 = (struct in6_addr *)__entry->primary_key6; + p32 = (__be32 *)__entry->primary_key4; + + if (tbl->family == AF_INET) +@@ -57,6 +55,8 @@ TRACE_EVENT(neigh_create, + + #if IS_ENABLED(CONFIG_IPV6) + if (tbl->family == AF_INET6) { ++ struct in6_addr *pin6; ++ + pin6 = (struct in6_addr *)__entry->primary_key6; + *pin6 = *(struct in6_addr *)pkey; + } +diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c +index 2c03bc881edfd..fbab9b2727fde 100644 +--- a/io_uring/io-wq.c ++++ b/io_uring/io-wq.c +@@ -1130,9 +1130,6 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) + wq = kzalloc(sizeof(struct io_wq), GFP_KERNEL); + if (!wq) + return ERR_PTR(-ENOMEM); +- ret = cpuhp_state_add_instance_nocalls(io_wq_online, &wq->cpuhp_node); +- if (ret) +- goto err_wq; + + refcount_inc(&data->hash->refs); + wq->hash = data->hash; +@@ -1165,13 +1162,14 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) + wq->task = get_task_struct(data->task); + atomic_set(&wq->worker_refs, 1); + init_completion(&wq->worker_done); ++ ret = cpuhp_state_add_instance_nocalls(io_wq_online, &wq->cpuhp_node); ++ if (ret) ++ goto err; ++ + return wq; + err: + io_wq_put_hash(data->hash); +- cpuhp_state_remove_instance_nocalls(io_wq_online, &wq->cpuhp_node); +- + free_cpumask_var(wq->cpu_mask); +-err_wq: + kfree(wq); + return ERR_PTR(ret); + } +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 9736416136a10..3a55d2be8e25b 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -2666,7 +2666,11 @@ static void io_pages_free(struct page ***pages, int npages) + + if (!pages) + return; ++ + page_array = *pages; ++ if (!page_array) ++ return; ++ + for (i = 0; i < npages; i++) + unpin_user_page(page_array[i]); + kvfree(page_array); +@@ -2750,7 +2754,9 @@ static void io_rings_free(struct io_ring_ctx *ctx) + ctx->sq_sqes = NULL; + } else { + io_pages_free(&ctx->ring_pages, ctx->n_ring_pages); ++ ctx->n_ring_pages = 0; + io_pages_free(&ctx->sqe_pages, ctx->n_sqe_pages); ++ ctx->n_sqe_pages = 0; + } + } + +diff --git a/kernel/auditsc.c b/kernel/auditsc.c +index eae5dfe9b9a01..28ea7411ff66f 100644 +--- a/kernel/auditsc.c ++++ b/kernel/auditsc.c +@@ -2210,7 +2210,7 @@ __audit_reusename(const __user char *uptr) + if (!n->name) + continue; + if (n->name->uptr == uptr) { +- n->name->refcnt++; ++ atomic_inc(&n->name->refcnt); + return n->name; + } + } +@@ -2239,7 +2239,7 @@ void __audit_getname(struct filename *name) + n->name = name; + n->name_len = AUDIT_NAME_FULL; + name->aname = n; +- name->refcnt++; ++ atomic_inc(&name->refcnt); + } + + static inline int audit_copy_fcaps(struct audit_names *name, +@@ -2371,7 +2371,7 @@ out_alloc: + return; + if (name) { + n->name = name; +- name->refcnt++; ++ atomic_inc(&name->refcnt); + } + + out: +@@ -2498,7 +2498,7 @@ void __audit_inode_child(struct inode *parent, + if (found_parent) { + found_child->name = found_parent->name; + found_child->name_len = AUDIT_NAME_FULL; +- found_child->name->refcnt++; ++ atomic_inc(&found_child->name->refcnt); + } + } + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 78ae7b6f90fdb..b3d800738fc5f 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1954,6 +1954,7 @@ static void perf_group_attach(struct perf_event *event) + + list_add_tail(&event->sibling_list, &group_leader->sibling_list); + group_leader->nr_siblings++; ++ group_leader->group_generation++; + + perf_event__header_size(group_leader); + +@@ -2144,6 +2145,7 @@ static void perf_group_detach(struct perf_event *event) + if (leader != event) { + list_del_init(&event->sibling_list); + event->group_leader->nr_siblings--; ++ event->group_leader->group_generation++; + goto out; + } + +@@ -5440,7 +5442,7 @@ static int __perf_read_group_add(struct perf_event *leader, + u64 read_format, u64 *values) + { + struct perf_event_context *ctx = leader->ctx; +- struct perf_event *sub; ++ struct perf_event *sub, *parent; + unsigned long flags; + int n = 1; /* skip @nr */ + int ret; +@@ -5450,6 +5452,33 @@ static int __perf_read_group_add(struct perf_event *leader, + return ret; + + raw_spin_lock_irqsave(&ctx->lock, flags); ++ /* ++ * Verify the grouping between the parent and child (inherited) ++ * events is still in tact. ++ * ++ * Specifically: ++ * - leader->ctx->lock pins leader->sibling_list ++ * - parent->child_mutex pins parent->child_list ++ * - parent->ctx->mutex pins parent->sibling_list ++ * ++ * Because parent->ctx != leader->ctx (and child_list nests inside ++ * ctx->mutex), group destruction is not atomic between children, also ++ * see perf_event_release_kernel(). Additionally, parent can grow the ++ * group. ++ * ++ * Therefore it is possible to have parent and child groups in a ++ * different configuration and summing over such a beast makes no sense ++ * what so ever. ++ * ++ * Reject this. ++ */ ++ parent = leader->parent; ++ if (parent && ++ (parent->group_generation != leader->group_generation || ++ parent->nr_siblings != leader->nr_siblings)) { ++ ret = -ECHILD; ++ goto unlock; ++ } + + /* + * Since we co-schedule groups, {enabled,running} times of siblings +@@ -5483,8 +5512,9 @@ static int __perf_read_group_add(struct perf_event *leader, + values[n++] = atomic64_read(&sub->lost_samples); + } + ++unlock: + raw_spin_unlock_irqrestore(&ctx->lock, flags); +- return 0; ++ return ret; + } + + static int perf_read_group(struct perf_event *event, +@@ -5503,10 +5533,6 @@ static int perf_read_group(struct perf_event *event, + + values[0] = 1 + leader->nr_siblings; + +- /* +- * By locking the child_mutex of the leader we effectively +- * lock the child list of all siblings.. XXX explain how. +- */ + mutex_lock(&leader->child_mutex); + + ret = __perf_read_group_add(leader, read_format, values); +@@ -13357,6 +13383,7 @@ static int inherit_group(struct perf_event *parent_event, + !perf_get_aux_event(child_ctr, leader)) + return -EINVAL; + } ++ leader->group_generation = parent_event->group_generation; + return 0; + } + +diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c +index 4492608b7d7f1..458d359f5991c 100644 +--- a/kernel/sched/cpufreq_schedutil.c ++++ b/kernel/sched/cpufreq_schedutil.c +@@ -350,7 +350,8 @@ static void sugov_update_single_freq(struct update_util_data *hook, u64 time, + * Except when the rq is capped by uclamp_max. + */ + if (!uclamp_rq_is_capped(cpu_rq(sg_cpu->cpu)) && +- sugov_cpu_is_busy(sg_cpu) && next_f < sg_policy->next_freq) { ++ sugov_cpu_is_busy(sg_cpu) && next_f < sg_policy->next_freq && ++ !sg_policy->need_freq_update) { + next_f = sg_policy->next_freq; + + /* Restore cached freq as next_freq has changed */ +diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c +index 3b21f40632582..881f90f0cbcfa 100644 +--- a/kernel/trace/fprobe.c ++++ b/kernel/trace/fprobe.c +@@ -189,7 +189,7 @@ static int fprobe_init_rethook(struct fprobe *fp, int num) + { + int i, size; + +- if (num < 0) ++ if (num <= 0) + return -EINVAL; + + if (!fp->exit_handler) { +@@ -202,8 +202,8 @@ static int fprobe_init_rethook(struct fprobe *fp, int num) + size = fp->nr_maxactive; + else + size = num * num_possible_cpus() * 2; +- if (size < 0) +- return -E2BIG; ++ if (size <= 0) ++ return -EINVAL; + + fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler); + if (!fp->rethook) +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index 0cf84a7449f5b..9841589b4af7f 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -2777,6 +2777,7 @@ void trace_event_eval_update(struct trace_eval_map **map, int len) + update_event_fields(call, map[i]); + } + } ++ cond_resched(); + } + up_write(&trace_event_sem); + } +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 23dba01831f79..92dbb21c69616 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -705,6 +705,25 @@ static struct notifier_block trace_kprobe_module_nb = { + .priority = 1 /* Invoked after kprobe module callback */ + }; + ++static int count_symbols(void *data, unsigned long unused) ++{ ++ unsigned int *count = data; ++ ++ (*count)++; ++ ++ return 0; ++} ++ ++static unsigned int number_of_same_symbols(char *func_name) ++{ ++ unsigned int count; ++ ++ count = 0; ++ kallsyms_on_each_match_symbol(count_symbols, func_name, &count); ++ ++ return count; ++} ++ + static int __trace_kprobe_create(int argc, const char *argv[]) + { + /* +@@ -836,6 +855,31 @@ static int __trace_kprobe_create(int argc, const char *argv[]) + } + } + ++ if (symbol && !strchr(symbol, ':')) { ++ unsigned int count; ++ ++ count = number_of_same_symbols(symbol); ++ if (count > 1) { ++ /* ++ * Users should use ADDR to remove the ambiguity of ++ * using KSYM only. ++ */ ++ trace_probe_log_err(0, NON_UNIQ_SYMBOL); ++ ret = -EADDRNOTAVAIL; ++ ++ goto error; ++ } else if (count == 0) { ++ /* ++ * We can return ENOENT earlier than when register the ++ * kprobe. ++ */ ++ trace_probe_log_err(0, BAD_PROBE_ADDR); ++ ret = -ENOENT; ++ ++ goto error; ++ } ++ } ++ + trace_probe_log_set_index(0); + if (event) { + ret = traceprobe_parse_event_name(&event, &group, gbuf, +@@ -1699,6 +1743,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk) + } + + #ifdef CONFIG_PERF_EVENTS ++ + /* create a trace_kprobe, but don't add it to global lists */ + struct trace_event_call * + create_local_trace_kprobe(char *func, void *addr, unsigned long offs, +@@ -1709,6 +1754,24 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs, + int ret; + char *event; + ++ if (func) { ++ unsigned int count; ++ ++ count = number_of_same_symbols(func); ++ if (count > 1) ++ /* ++ * Users should use addr to remove the ambiguity of ++ * using func only. ++ */ ++ return ERR_PTR(-EADDRNOTAVAIL); ++ else if (count == 0) ++ /* ++ * We can return ENOENT earlier than when register the ++ * kprobe. ++ */ ++ return ERR_PTR(-ENOENT); ++ } ++ + /* + * local trace_kprobes are not added to dyn_event, so they are never + * searched in find_trace_kprobe(). Therefore, there is no concern of +diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h +index 01ea148723de2..975161164366f 100644 +--- a/kernel/trace/trace_probe.h ++++ b/kernel/trace/trace_probe.h +@@ -438,6 +438,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, + C(BAD_MAXACT, "Invalid maxactive number"), \ + C(MAXACT_TOO_BIG, "Maxactive is too big"), \ + C(BAD_PROBE_ADDR, "Invalid probed address or symbol"), \ ++ C(NON_UNIQ_SYMBOL, "The symbol is not unique"), \ + C(BAD_RETPROBE, "Retprobe address must be an function entry"), \ + C(NO_TRACEPOINT, "Tracepoint is not found"), \ + C(BAD_ADDR_SUFFIX, "Invalid probed address suffix"), \ +diff --git a/mm/slab_common.c b/mm/slab_common.c +index 5658da50a2d07..e2701dbb88721 100644 +--- a/mm/slab_common.c ++++ b/mm/slab_common.c +@@ -864,11 +864,13 @@ void __init setup_kmalloc_cache_index_table(void) + + static unsigned int __kmalloc_minalign(void) + { ++ unsigned int minalign = dma_get_cache_alignment(); ++ + #ifdef CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC + if (io_tlb_default_mem.nslabs) +- return ARCH_KMALLOC_MINALIGN; ++ minalign = ARCH_KMALLOC_MINALIGN; + #endif +- return dma_get_cache_alignment(); ++ return max(minalign, arch_slab_minalign()); + } + + void __init +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index ce76931d11d86..6d6192f514d0f 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -874,7 +874,7 @@ static void bis_cleanup(struct hci_conn *conn) + + static int remove_cig_sync(struct hci_dev *hdev, void *data) + { +- u8 handle = PTR_ERR(data); ++ u8 handle = PTR_UINT(data); + + return hci_le_remove_cig_sync(hdev, handle); + } +@@ -883,7 +883,8 @@ static int hci_le_remove_cig(struct hci_dev *hdev, u8 handle) + { + bt_dev_dbg(hdev, "handle 0x%2.2x", handle); + +- return hci_cmd_sync_queue(hdev, remove_cig_sync, ERR_PTR(handle), NULL); ++ return hci_cmd_sync_queue(hdev, remove_cig_sync, UINT_PTR(handle), ++ NULL); + } + + static void find_cis(struct hci_conn *conn, void *data) +@@ -1248,9 +1249,41 @@ void hci_conn_failed(struct hci_conn *conn, u8 status) + hci_conn_del(conn); + } + ++/* This function requires the caller holds hdev->lock */ ++u8 hci_conn_set_handle(struct hci_conn *conn, u16 handle) ++{ ++ struct hci_dev *hdev = conn->hdev; ++ ++ bt_dev_dbg(hdev, "hcon %p handle 0x%4.4x", conn, handle); ++ ++ if (conn->handle == handle) ++ return 0; ++ ++ if (handle > HCI_CONN_HANDLE_MAX) { ++ bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", ++ handle, HCI_CONN_HANDLE_MAX); ++ return HCI_ERROR_INVALID_PARAMETERS; ++ } ++ ++ /* If abort_reason has been sent it means the connection is being ++ * aborted and the handle shall not be changed. ++ */ ++ if (conn->abort_reason) ++ return conn->abort_reason; ++ ++ conn->handle = handle; ++ ++ return 0; ++} ++ + static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err) + { +- struct hci_conn *conn = data; ++ struct hci_conn *conn; ++ u16 handle = PTR_UINT(data); ++ ++ conn = hci_conn_hash_lookup_handle(hdev, handle); ++ if (!conn) ++ return; + + bt_dev_dbg(hdev, "err %d", err); + +@@ -1275,10 +1308,17 @@ done: + + static int hci_connect_le_sync(struct hci_dev *hdev, void *data) + { +- struct hci_conn *conn = data; ++ struct hci_conn *conn; ++ u16 handle = PTR_UINT(data); ++ ++ conn = hci_conn_hash_lookup_handle(hdev, handle); ++ if (!conn) ++ return 0; + + bt_dev_dbg(hdev, "conn %p", conn); + ++ conn->state = BT_CONNECT; ++ + return hci_le_create_conn_sync(hdev, conn); + } + +@@ -1348,10 +1388,10 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, + conn->sec_level = BT_SECURITY_LOW; + conn->conn_timeout = conn_timeout; + +- conn->state = BT_CONNECT; + clear_bit(HCI_CONN_SCANNING, &conn->flags); + +- err = hci_cmd_sync_queue(hdev, hci_connect_le_sync, conn, ++ err = hci_cmd_sync_queue(hdev, hci_connect_le_sync, ++ UINT_PTR(conn->handle), + create_le_conn_complete); + if (err) { + hci_conn_del(conn); +@@ -1589,6 +1629,15 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, + return ERR_PTR(-EOPNOTSUPP); + } + ++ /* Reject outgoing connection to device with same BD ADDR against ++ * CVE-2020-26555 ++ */ ++ if (!bacmp(&hdev->bdaddr, dst)) { ++ bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n", ++ dst); ++ return ERR_PTR(-ECONNREFUSED); ++ } ++ + acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); + if (!acl) { + acl = hci_conn_add(hdev, ACL_LINK, dst, HCI_ROLE_MASTER); +@@ -1719,7 +1768,7 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos) + + static int set_cig_params_sync(struct hci_dev *hdev, void *data) + { +- u8 cig_id = PTR_ERR(data); ++ u8 cig_id = PTR_UINT(data); + struct hci_conn *conn; + struct bt_iso_qos *qos; + struct iso_cig_params pdu; +@@ -1829,7 +1878,7 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos) + + done: + if (hci_cmd_sync_queue(hdev, set_cig_params_sync, +- ERR_PTR(qos->ucast.cig), NULL) < 0) ++ UINT_PTR(qos->ucast.cig), NULL) < 0) + return false; + + return true; +@@ -2364,34 +2413,41 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, + if (!test_bit(HCI_CONN_AUTH, &conn->flags)) + goto auth; + +- /* An authenticated FIPS approved combination key has sufficient +- * security for security level 4. */ +- if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256 && +- sec_level == BT_SECURITY_FIPS) +- goto encrypt; +- +- /* An authenticated combination key has sufficient security for +- security level 3. */ +- if ((conn->key_type == HCI_LK_AUTH_COMBINATION_P192 || +- conn->key_type == HCI_LK_AUTH_COMBINATION_P256) && +- sec_level == BT_SECURITY_HIGH) +- goto encrypt; +- +- /* An unauthenticated combination key has sufficient security for +- security level 1 and 2. */ +- if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 || +- conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) && +- (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) +- goto encrypt; +- +- /* A combination key has always sufficient security for the security +- levels 1 or 2. High security level requires the combination key +- is generated using maximum PIN code length (16). +- For pre 2.1 units. */ +- if (conn->key_type == HCI_LK_COMBINATION && +- (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW || +- conn->pin_length == 16)) +- goto encrypt; ++ switch (conn->key_type) { ++ case HCI_LK_AUTH_COMBINATION_P256: ++ /* An authenticated FIPS approved combination key has ++ * sufficient security for security level 4 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_FIPS) ++ goto encrypt; ++ break; ++ case HCI_LK_AUTH_COMBINATION_P192: ++ /* An authenticated combination key has sufficient security for ++ * security level 3 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_HIGH) ++ goto encrypt; ++ break; ++ case HCI_LK_UNAUTH_COMBINATION_P192: ++ case HCI_LK_UNAUTH_COMBINATION_P256: ++ /* An unauthenticated combination key has sufficient security ++ * for security level 2 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_MEDIUM) ++ goto encrypt; ++ break; ++ case HCI_LK_COMBINATION: ++ /* A combination key has always sufficient security for the ++ * security levels 2 or lower. High security level requires the ++ * combination key is generated using maximum PIN code length ++ * (16). For pre 2.1 units. ++ */ ++ if (sec_level <= BT_SECURITY_MEDIUM || conn->pin_length == 16) ++ goto encrypt; ++ break; ++ default: ++ break; ++ } + + auth: + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) +@@ -2836,7 +2892,7 @@ u32 hci_conn_get_phy(struct hci_conn *conn) + static int abort_conn_sync(struct hci_dev *hdev, void *data) + { + struct hci_conn *conn; +- u16 handle = PTR_ERR(data); ++ u16 handle = PTR_UINT(data); + + conn = hci_conn_hash_lookup_handle(hdev, handle); + if (!conn) +@@ -2862,6 +2918,9 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason) + /* If the connection is pending check the command opcode since that + * might be blocking on hci_cmd_sync_work while waiting its respective + * event so we need to hci_cmd_sync_cancel to cancel it. ++ * ++ * hci_connect_le serializes the connection attempts so only one ++ * connection can be in BT_CONNECT at time. + */ + if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) { + switch (hci_skb_event(hdev->sent_cmd)) { +@@ -2873,6 +2932,6 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason) + } + } + +- return hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle), ++ return hci_cmd_sync_queue(hdev, abort_conn_sync, UINT_PTR(conn->handle), + NULL); + } +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 26a265d9c59cd..63d4d38863acb 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -2617,7 +2617,11 @@ int hci_register_dev(struct hci_dev *hdev) + if (id < 0) + return id; + +- snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); ++ error = dev_set_name(&hdev->dev, "hci%u", id); ++ if (error) ++ return error; ++ ++ hdev->name = dev_name(&hdev->dev); + hdev->id = id; + + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); +@@ -2639,8 +2643,6 @@ int hci_register_dev(struct hci_dev *hdev) + if (!IS_ERR_OR_NULL(bt_debugfs)) + hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); + +- dev_set_name(&hdev->dev, "%s", hdev->name); +- + error = device_add(&hdev->dev); + if (error < 0) + goto err_wqueue; +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index a77234478b2c4..dd70fd5313840 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -26,6 +26,8 @@ + /* Bluetooth HCI event handling. */ + + #include ++#include ++#include + + #include + #include +@@ -3180,13 +3182,9 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, + } + + if (!status) { +- conn->handle = __le16_to_cpu(ev->handle); +- if (conn->handle > HCI_CONN_HANDLE_MAX) { +- bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", +- conn->handle, HCI_CONN_HANDLE_MAX); +- status = HCI_ERROR_INVALID_PARAMETERS; ++ status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle)); ++ if (status) + goto done; +- } + + if (conn->type == ACL_LINK) { + conn->state = BT_CONFIG; +@@ -3272,6 +3270,16 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, + + bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type); + ++ /* Reject incoming connection from device with same BD ADDR against ++ * CVE-2020-26555 ++ */ ++ if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) { ++ bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n", ++ &ev->bdaddr); ++ hci_reject_conn(hdev, &ev->bdaddr); ++ return; ++ } ++ + mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, + &flags); + +@@ -3869,11 +3877,9 @@ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data, + if (conn->state != BT_BOUND && conn->state != BT_CONNECT) + continue; + +- conn->handle = __le16_to_cpu(rp->handle[i]); ++ if (hci_conn_set_handle(conn, __le16_to_cpu(rp->handle[i]))) ++ continue; + +- bt_dev_dbg(hdev, "%p handle 0x%4.4x parent %p", conn, +- conn->handle, conn->parent); +- + if (conn->state == BT_CONNECT) + pending = true; + } +@@ -4725,6 +4731,15 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data, + if (!conn) + goto unlock; + ++ /* Ignore NULL link key against CVE-2020-26555 */ ++ if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) { ++ bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR", ++ &ev->bdaddr); ++ hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); ++ hci_conn_drop(conn); ++ goto unlock; ++ } ++ + hci_conn_hold(conn); + conn->disc_timeout = HCI_DISCONN_TIMEOUT; + hci_conn_drop(conn); +@@ -5036,11 +5051,8 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data, + + switch (status) { + case 0x00: +- conn->handle = __le16_to_cpu(ev->handle); +- if (conn->handle > HCI_CONN_HANDLE_MAX) { +- bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", +- conn->handle, HCI_CONN_HANDLE_MAX); +- status = HCI_ERROR_INVALID_PARAMETERS; ++ status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle)); ++ if (status) { + conn->state = BT_CLOSED; + break; + } +@@ -5260,8 +5272,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) + * available, then do not declare that OOB data is + * present. + */ +- if (!memcmp(data->rand256, ZERO_KEY, 16) || +- !memcmp(data->hash256, ZERO_KEY, 16)) ++ if (!crypto_memneq(data->rand256, ZERO_KEY, 16) || ++ !crypto_memneq(data->hash256, ZERO_KEY, 16)) + return 0x00; + + return 0x02; +@@ -5271,8 +5283,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) + * not supported by the hardware, then check that if + * P-192 data values are present. + */ +- if (!memcmp(data->rand192, ZERO_KEY, 16) || +- !memcmp(data->hash192, ZERO_KEY, 16)) ++ if (!crypto_memneq(data->rand192, ZERO_KEY, 16) || ++ !crypto_memneq(data->hash192, ZERO_KEY, 16)) + return 0x00; + + return 0x01; +@@ -5289,7 +5301,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data, + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); +- if (!conn) ++ if (!conn || !hci_conn_ssp_enabled(conn)) + goto unlock; + + hci_conn_hold(conn); +@@ -5536,7 +5548,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data, + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); +- if (!conn) ++ if (!conn || !hci_conn_ssp_enabled(conn)) + goto unlock; + + /* Reset the authentication requirement to unknown */ +@@ -6968,12 +6980,20 @@ unlock: + hci_dev_unlock(hdev); + } + ++static int hci_iso_term_big_sync(struct hci_dev *hdev, void *data) ++{ ++ u8 handle = PTR_UINT(data); ++ ++ return hci_le_terminate_big_sync(hdev, handle, ++ HCI_ERROR_LOCAL_HOST_TERM); ++} ++ + static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data, + struct sk_buff *skb) + { + struct hci_evt_le_create_big_complete *ev = data; + struct hci_conn *conn; +- __u8 bis_idx = 0; ++ __u8 i = 0; + + BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); + +@@ -6991,7 +7011,9 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data, + conn->iso_qos.bcast.big != ev->handle) + continue; + +- conn->handle = __le16_to_cpu(ev->bis_handle[bis_idx++]); ++ if (hci_conn_set_handle(conn, ++ __le16_to_cpu(ev->bis_handle[i++]))) ++ continue; + + if (!ev->status) { + conn->state = BT_CONNECTED; +@@ -7010,16 +7032,17 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data, + rcu_read_lock(); + } + +- if (!ev->status && !bis_idx) ++ rcu_read_unlock(); ++ ++ if (!ev->status && !i) + /* If no BISes have been connected for the BIG, + * terminate. This is in case all bound connections + * have been closed before the BIG creation + * has completed. + */ +- hci_le_terminate_big_sync(hdev, ev->handle, +- HCI_ERROR_LOCAL_HOST_TERM); ++ hci_cmd_sync_queue(hdev, hci_iso_term_big_sync, ++ UINT_PTR(ev->handle), NULL); + +- rcu_read_unlock(); + hci_dev_unlock(hdev); + } + +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index 1d249d839819d..484fc2a8e4baa 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -439,7 +439,8 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) + ni->type = hdev->dev_type; + ni->bus = hdev->bus; + bacpy(&ni->bdaddr, &hdev->bdaddr); +- memcpy(ni->name, hdev->name, 8); ++ memcpy_and_pad(ni->name, sizeof(ni->name), hdev->name, ++ strnlen(hdev->name, sizeof(ni->name)), '\0'); + + opcode = cpu_to_le16(HCI_MON_NEW_INDEX); + break; +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index 6aaecd6e656bc..360813ab0c4db 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -5290,6 +5290,28 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn, + if (conn->type == LE_LINK) + return hci_le_connect_cancel_sync(hdev, conn, reason); + ++ if (conn->type == ISO_LINK) { ++ /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E ++ * page 1857: ++ * ++ * If this command is issued for a CIS on the Central and the ++ * CIS is successfully terminated before being established, ++ * then an HCI_LE_CIS_Established event shall also be sent for ++ * this CIS with the Status Operation Cancelled by Host (0x44). ++ */ ++ if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags)) ++ return hci_disconnect_sync(hdev, conn, reason); ++ ++ /* CIS with no Create CIS sent have nothing to cancel */ ++ if (bacmp(&conn->dst, BDADDR_ANY)) ++ return HCI_ERROR_LOCAL_HOST_TERM; ++ ++ /* There is no way to cancel a BIS without terminating the BIG ++ * which is done later on connection cleanup. ++ */ ++ return 0; ++ } ++ + if (hdev->hci_ver < BLUETOOTH_VER_1_2) + return 0; + +@@ -5316,11 +5338,27 @@ static int hci_reject_sco_sync(struct hci_dev *hdev, struct hci_conn *conn, + sizeof(cp), &cp, HCI_CMD_TIMEOUT); + } + ++static int hci_le_reject_cis_sync(struct hci_dev *hdev, struct hci_conn *conn, ++ u8 reason) ++{ ++ struct hci_cp_le_reject_cis cp; ++ ++ memset(&cp, 0, sizeof(cp)); ++ cp.handle = cpu_to_le16(conn->handle); ++ cp.reason = reason; ++ ++ return __hci_cmd_sync_status(hdev, HCI_OP_LE_REJECT_CIS, ++ sizeof(cp), &cp, HCI_CMD_TIMEOUT); ++} ++ + static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, + u8 reason) + { + struct hci_cp_reject_conn_req cp; + ++ if (conn->type == ISO_LINK) ++ return hci_le_reject_cis_sync(hdev, conn, reason); ++ + if (conn->type == SCO_LINK || conn->type == ESCO_LINK) + return hci_reject_sco_sync(hdev, conn, reason); + +@@ -5336,6 +5374,7 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason) + { + int err = 0; + u16 handle = conn->handle; ++ bool disconnect = false; + struct hci_conn *c; + + switch (conn->state) { +@@ -5350,27 +5389,16 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason) + err = hci_reject_conn_sync(hdev, conn, reason); + break; + case BT_OPEN: +- /* Cleanup bises that failed to be established */ +- if (test_and_clear_bit(HCI_CONN_BIG_SYNC_FAILED, &conn->flags)) { +- hci_dev_lock(hdev); +- hci_conn_failed(conn, reason); +- hci_dev_unlock(hdev); +- } ++ case BT_BOUND: + break; + default: +- hci_dev_lock(hdev); +- conn->state = BT_CLOSED; +- hci_disconn_cfm(conn, reason); +- hci_conn_del(conn); +- hci_dev_unlock(hdev); +- return 0; ++ disconnect = true; ++ break; + } + + hci_dev_lock(hdev); + +- /* Check if the connection hasn't been cleanup while waiting +- * commands to complete. +- */ ++ /* Check if the connection has been cleaned up concurrently */ + c = hci_conn_hash_lookup_handle(hdev, handle); + if (!c || c != conn) { + err = 0; +@@ -5382,7 +5410,13 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason) + * or in case of LE it was still scanning so it can be cleanup + * safely. + */ +- hci_conn_failed(conn, reason); ++ if (disconnect) { ++ conn->state = BT_CLOSED; ++ hci_disconn_cfm(conn, reason); ++ hci_conn_del(conn); ++ } else { ++ hci_conn_failed(conn, reason); ++ } + + unlock: + hci_dev_unlock(hdev); +@@ -6511,7 +6545,7 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, + + static int _update_adv_data_sync(struct hci_dev *hdev, void *data) + { +- u8 instance = PTR_ERR(data); ++ u8 instance = PTR_UINT(data); + + return hci_update_adv_data_sync(hdev, instance); + } +@@ -6519,5 +6553,5 @@ static int _update_adv_data_sync(struct hci_dev *hdev, void *data) + int hci_update_adv_data(struct hci_dev *hdev, u8 instance) + { + return hci_cmd_sync_queue(hdev, _update_adv_data_sync, +- ERR_PTR(instance), NULL); ++ UINT_PTR(instance), NULL); + } +diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c +index 42f7b257bdfbc..c8460eb7f5c0b 100644 +--- a/net/bluetooth/iso.c ++++ b/net/bluetooth/iso.c +@@ -622,18 +622,6 @@ static void iso_sock_kill(struct sock *sk) + sock_put(sk); + } + +-static void iso_conn_defer_reject(struct hci_conn *conn) +-{ +- struct hci_cp_le_reject_cis cp; +- +- BT_DBG("conn %p", conn); +- +- memset(&cp, 0, sizeof(cp)); +- cp.handle = cpu_to_le16(conn->handle); +- cp.reason = HCI_ERROR_REJ_BAD_ADDR; +- hci_send_cmd(conn->hdev, HCI_OP_LE_REJECT_CIS, sizeof(cp), &cp); +-} +- + static void __iso_sock_close(struct sock *sk) + { + BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); +@@ -658,8 +646,6 @@ static void __iso_sock_close(struct sock *sk) + break; + + case BT_CONNECT2: +- if (iso_pi(sk)->conn->hcon) +- iso_conn_defer_reject(iso_pi(sk)->conn->hcon); + iso_chan_del(sk, ECONNRESET); + break; + case BT_CONNECT: +diff --git a/net/core/dev.c b/net/core/dev.c +index 968be1c20ca1f..fe8c46c46505b 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -343,7 +343,6 @@ int netdev_name_node_alt_create(struct net_device *dev, const char *name) + static void __netdev_name_node_alt_destroy(struct netdev_name_node *name_node) + { + list_del(&name_node->list); +- netdev_name_node_del(name_node); + kfree(name_node->name); + netdev_name_node_free(name_node); + } +@@ -362,6 +361,8 @@ int netdev_name_node_alt_destroy(struct net_device *dev, const char *name) + if (name_node == dev->name_node || name_node->dev != dev) + return -EINVAL; + ++ netdev_name_node_del(name_node); ++ synchronize_rcu(); + __netdev_name_node_alt_destroy(name_node); + + return 0; +@@ -378,6 +379,7 @@ static void netdev_name_node_alt_flush(struct net_device *dev) + /* Device list insertion */ + static void list_netdevice(struct net_device *dev) + { ++ struct netdev_name_node *name_node; + struct net *net = dev_net(dev); + + ASSERT_RTNL(); +@@ -389,6 +391,9 @@ static void list_netdevice(struct net_device *dev) + dev_index_hash(net, dev->ifindex)); + write_unlock(&dev_base_lock); + ++ netdev_for_each_altname(dev, name_node) ++ netdev_name_node_add(net, name_node); ++ + dev_base_seq_inc(net); + } + +@@ -397,8 +402,13 @@ static void list_netdevice(struct net_device *dev) + */ + static void unlist_netdevice(struct net_device *dev, bool lock) + { ++ struct netdev_name_node *name_node; ++ + ASSERT_RTNL(); + ++ netdev_for_each_altname(dev, name_node) ++ netdev_name_node_del(name_node); ++ + /* Unlink dev from the device chain */ + if (lock) + write_lock(&dev_base_lock); +@@ -1078,7 +1088,8 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + + for_each_netdev(net, d) { + struct netdev_name_node *name_node; +- list_for_each_entry(name_node, &d->name_node->list, list) { ++ ++ netdev_for_each_altname(d, name_node) { + if (!sscanf(name_node->name, name, &i)) + continue; + if (i < 0 || i >= max_netdevices) +@@ -1115,6 +1126,26 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + return -ENFILE; + } + ++static int dev_prep_valid_name(struct net *net, struct net_device *dev, ++ const char *want_name, char *out_name) ++{ ++ int ret; ++ ++ if (!dev_valid_name(want_name)) ++ return -EINVAL; ++ ++ if (strchr(want_name, '%')) { ++ ret = __dev_alloc_name(net, want_name, out_name); ++ return ret < 0 ? ret : 0; ++ } else if (netdev_name_in_use(net, want_name)) { ++ return -EEXIST; ++ } else if (out_name != want_name) { ++ strscpy(out_name, want_name, IFNAMSIZ); ++ } ++ ++ return 0; ++} ++ + static int dev_alloc_name_ns(struct net *net, + struct net_device *dev, + const char *name) +@@ -1152,19 +1183,13 @@ EXPORT_SYMBOL(dev_alloc_name); + static int dev_get_valid_name(struct net *net, struct net_device *dev, + const char *name) + { +- BUG_ON(!net); +- +- if (!dev_valid_name(name)) +- return -EINVAL; +- +- if (strchr(name, '%')) +- return dev_alloc_name_ns(net, dev, name); +- else if (netdev_name_in_use(net, name)) +- return -EEXIST; +- else if (dev->name != name) +- strscpy(dev->name, name, IFNAMSIZ); ++ char buf[IFNAMSIZ]; ++ int ret; + +- return 0; ++ ret = dev_prep_valid_name(net, dev, name, buf); ++ if (ret >= 0) ++ strscpy(dev->name, buf, IFNAMSIZ); ++ return ret; + } + + /** +@@ -10949,7 +10974,9 @@ EXPORT_SYMBOL(unregister_netdev); + int __dev_change_net_namespace(struct net_device *dev, struct net *net, + const char *pat, int new_ifindex) + { ++ struct netdev_name_node *name_node; + struct net *net_old = dev_net(dev); ++ char new_name[IFNAMSIZ] = {}; + int err, new_nsid; + + ASSERT_RTNL(); +@@ -10976,10 +11003,15 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, + /* We get here if we can't use the current device name */ + if (!pat) + goto out; +- err = dev_get_valid_name(net, dev, pat); ++ err = dev_prep_valid_name(net, dev, pat, new_name); + if (err < 0) + goto out; + } ++ /* Check that none of the altnames conflicts. */ ++ err = -EEXIST; ++ netdev_for_each_altname(dev, name_node) ++ if (netdev_name_in_use(net, name_node->name)) ++ goto out; + + /* Check that new_ifindex isn't used yet. */ + err = -EBUSY; +@@ -11044,6 +11076,9 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, + kobject_uevent(&dev->dev.kobj, KOBJ_ADD); + netdev_adjacent_add_links(dev); + ++ if (new_name[0]) /* Rename the netdev to prepared name */ ++ strscpy(dev->name, new_name, IFNAMSIZ); ++ + /* Fixup kobjects */ + err = device_rename(&dev->dev, dev->name); + WARN_ON(err); +diff --git a/net/core/dev.h b/net/core/dev.h +index e075e198092cc..fa2e9c5c41224 100644 +--- a/net/core/dev.h ++++ b/net/core/dev.h +@@ -62,6 +62,9 @@ struct netdev_name_node { + int netdev_get_name(struct net *net, char *name, int ifindex); + int dev_change_name(struct net_device *dev, const char *newname); + ++#define netdev_for_each_altname(dev, namenode) \ ++ list_for_each_entry((namenode), &(dev)->name_node->list, list) ++ + int netdev_name_node_alt_create(struct net_device *dev, const char *name); + int netdev_name_node_alt_destroy(struct net_device *dev, const char *name); + +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index f56b8d6970147..4d1696677c48c 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -669,19 +669,19 @@ static int pktgen_if_show(struct seq_file *seq, void *v) + seq_puts(seq, " Flags: "); + + for (i = 0; i < NR_PKT_FLAGS; i++) { +- if (i == F_FLOW_SEQ) ++ if (i == FLOW_SEQ_SHIFT) + if (!pkt_dev->cflows) + continue; + +- if (pkt_dev->flags & (1 << i)) ++ if (pkt_dev->flags & (1 << i)) { + seq_printf(seq, "%s ", pkt_flag_names[i]); +- else if (i == F_FLOW_SEQ) +- seq_puts(seq, "FLOW_RND "); +- + #ifdef CONFIG_XFRM +- if (i == F_IPSEC && pkt_dev->spi) +- seq_printf(seq, "spi:%u", pkt_dev->spi); ++ if (i == IPSEC_SHIFT && pkt_dev->spi) ++ seq_printf(seq, "spi:%u ", pkt_dev->spi); + #endif ++ } else if (i == FLOW_SEQ_SHIFT) { ++ seq_puts(seq, "FLOW_RND "); ++ } + } + + seq_puts(seq, "\n"); +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 00c94d9622b4a..c1a6f58cb2f68 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -5504,13 +5504,11 @@ static unsigned int + rtnl_offload_xstats_get_size_hw_s_info_one(const struct net_device *dev, + enum netdev_offload_xstats_type type) + { +- bool enabled = netdev_offload_xstats_enabled(dev, type); +- + return nla_total_size(0) + + /* IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST */ + nla_total_size(sizeof(u8)) + + /* IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED */ +- (enabled ? nla_total_size(sizeof(u8)) : 0) + ++ nla_total_size(sizeof(u8)) + + 0; + } + +diff --git a/net/core/stream.c b/net/core/stream.c +index f5c4e47df1650..96fbcb9bbb30a 100644 +--- a/net/core/stream.c ++++ b/net/core/stream.c +@@ -117,7 +117,7 @@ EXPORT_SYMBOL(sk_stream_wait_close); + */ + int sk_stream_wait_memory(struct sock *sk, long *timeo_p) + { +- int err = 0; ++ int ret, err = 0; + long vm_wait = 0; + long current_timeo = *timeo_p; + DEFINE_WAIT_FUNC(wait, woken_wake_function); +@@ -142,11 +142,13 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) + + set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + sk->sk_write_pending++; +- sk_wait_event(sk, ¤t_timeo, READ_ONCE(sk->sk_err) || +- (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) || +- (sk_stream_memory_free(sk) && +- !vm_wait), &wait); ++ ret = sk_wait_event(sk, ¤t_timeo, READ_ONCE(sk->sk_err) || ++ (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) || ++ (sk_stream_memory_free(sk) && !vm_wait), ++ &wait); + sk->sk_write_pending--; ++ if (ret < 0) ++ goto do_error; + + if (vm_wait) { + vm_wait -= current_timeo; +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 02736b83c3032..0c0ae021b7ff5 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -587,7 +587,6 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) + + add_wait_queue(sk_sleep(sk), &wait); + sk->sk_write_pending += writebias; +- sk->sk_wait_pending++; + + /* Basic assumption: if someone sets sk->sk_err, he _must_ + * change state of the socket from TCP_SYN_*. +@@ -603,7 +602,6 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) + } + remove_wait_queue(sk_sleep(sk), &wait); + sk->sk_write_pending -= writebias; +- sk->sk_wait_pending--; + return timeo; + } + +@@ -632,6 +630,7 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, + return -EINVAL; + + if (uaddr->sa_family == AF_UNSPEC) { ++ sk->sk_disconnects++; + err = sk->sk_prot->disconnect(sk, flags); + sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED; + goto out; +@@ -686,6 +685,7 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, + int writebias = (sk->sk_protocol == IPPROTO_TCP) && + tcp_sk(sk)->fastopen_req && + tcp_sk(sk)->fastopen_req->data ? 1 : 0; ++ int dis = sk->sk_disconnects; + + /* Error code is set above */ + if (!timeo || !inet_wait_for_connect(sk, timeo, writebias)) +@@ -694,6 +694,11 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, + err = sock_intr_errno(timeo); + if (signal_pending(current)) + goto out; ++ ++ if (dis != sk->sk_disconnects) { ++ err = -EPIPE; ++ goto out; ++ } + } + + /* Connection was closed by RST, timeout, ICMP error +@@ -715,6 +720,7 @@ out: + sock_error: + err = sock_error(sk) ? : -ECONNABORTED; + sock->state = SS_UNCONNECTED; ++ sk->sk_disconnects++; + if (sk->sk_prot->disconnect(sk, flags)) + sock->state = SS_DISCONNECTING; + goto out; +diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c +index 2be2d49225573..d18f0f092fe73 100644 +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -732,7 +732,9 @@ static inline int esp_remove_trailer(struct sk_buff *skb) + skb->csum = csum_block_sub(skb->csum, csumdiff, + skb->len - trimlen); + } +- pskb_trim(skb, skb->len - trimlen); ++ ret = pskb_trim(skb, skb->len - trimlen); ++ if (unlikely(ret)) ++ return ret; + + ret = nexthdr[1]; + +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index eafa4a0335157..5eb1b8d302bbd 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -1325,15 +1325,18 @@ __be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc, + unsigned char scope) + { + struct fib_nh *nh; ++ __be32 saddr; + + if (nhc->nhc_family != AF_INET) + return inet_select_addr(nhc->nhc_dev, 0, scope); + + nh = container_of(nhc, struct fib_nh, nh_common); +- nh->nh_saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope); +- nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid); ++ saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope); + +- return nh->nh_saddr; ++ WRITE_ONCE(nh->nh_saddr, saddr); ++ WRITE_ONCE(nh->nh_saddr_genid, atomic_read(&net->ipv4.dev_addr_genid)); ++ ++ return saddr; + } + + __be32 fib_result_prefsrc(struct net *net, struct fib_result *res) +@@ -1347,8 +1350,9 @@ __be32 fib_result_prefsrc(struct net *net, struct fib_result *res) + struct fib_nh *nh; + + nh = container_of(nhc, struct fib_nh, nh_common); +- if (nh->nh_saddr_genid == atomic_read(&net->ipv4.dev_addr_genid)) +- return nh->nh_saddr; ++ if (READ_ONCE(nh->nh_saddr_genid) == ++ atomic_read(&net->ipv4.dev_addr_genid)) ++ return READ_ONCE(nh->nh_saddr); + } + + return fib_info_update_nhc_saddr(net, nhc, res->fi->fib_scope); +@@ -1887,6 +1891,7 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local) + continue; + if (fi->fib_prefsrc == local) { + fi->fib_flags |= RTNH_F_DEAD; ++ fi->pfsrc_removed = true; + ret++; + } + } +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index d13fb9e76b971..9bdfdab906fe0 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -2027,6 +2027,7 @@ void fib_table_flush_external(struct fib_table *tb) + int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) + { + struct trie *t = (struct trie *)tb->tb_data; ++ struct nl_info info = { .nl_net = net }; + struct key_vector *pn = t->kv; + unsigned long cindex = 1; + struct hlist_node *tmp; +@@ -2089,6 +2090,9 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) + + fib_notify_alias_delete(net, n->key, &n->leaf, fa, + NULL); ++ if (fi->pfsrc_removed) ++ rtmsg_fib(RTM_DELROUTE, htonl(n->key), fa, ++ KEYLENGTH - fa->fa_slen, tb->tb_id, &info, 0); + hlist_del_rcu(&fa->fa_list); + fib_release_info(fa->fa_info); + alias_free_mem_rcu(fa); +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index aeebe88166899..394a498c28232 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -1145,7 +1145,6 @@ struct sock *inet_csk_clone_lock(const struct sock *sk, + if (newsk) { + struct inet_connection_sock *newicsk = inet_csk(newsk); + +- newsk->sk_wait_pending = 0; + inet_sk_set_state(newsk, TCP_SYN_RECV); + newicsk->icsk_bind_hash = NULL; + newicsk->icsk_bind2_hash = NULL; +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index ae5e786a0598d..60cffabfd4788 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -148,8 +148,14 @@ static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2, + const struct sock *sk) + { + #if IS_ENABLED(CONFIG_IPV6) +- if (sk->sk_family != tb2->family) +- return false; ++ if (sk->sk_family != tb2->family) { ++ if (sk->sk_family == AF_INET) ++ return ipv6_addr_v4mapped(&tb2->v6_rcv_saddr) && ++ tb2->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; ++ ++ return ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr) && ++ sk->sk_v6_rcv_saddr.s6_addr32[3] == tb2->rcv_saddr; ++ } + + if (sk->sk_family == AF_INET6) + return ipv6_addr_equal(&tb2->v6_rcv_saddr, +@@ -799,19 +805,7 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb, + tb->l3mdev != l3mdev) + return false; + +-#if IS_ENABLED(CONFIG_IPV6) +- if (sk->sk_family != tb->family) { +- if (sk->sk_family == AF_INET) +- return ipv6_addr_v4mapped(&tb->v6_rcv_saddr) && +- tb->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; +- +- return false; +- } +- +- if (sk->sk_family == AF_INET6) +- return ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); +-#endif +- return tb->rcv_saddr == sk->sk_rcv_saddr; ++ return inet_bind2_bucket_addr_match(tb, sk); + } + + bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const struct net *net, +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 9cfc07d1e4252..9bdc1b2eaf734 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -829,7 +829,9 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, + */ + if (!skb_queue_empty(&sk->sk_receive_queue)) + break; +- sk_wait_data(sk, &timeo, NULL); ++ ret = sk_wait_data(sk, &timeo, NULL); ++ if (ret < 0) ++ break; + if (signal_pending(current)) { + ret = sock_intr_errno(timeo); + break; +@@ -2442,7 +2444,11 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len, + __sk_flush_backlog(sk); + } else { + tcp_cleanup_rbuf(sk, copied); +- sk_wait_data(sk, &timeo, last); ++ err = sk_wait_data(sk, &timeo, last); ++ if (err < 0) { ++ err = copied ? : err; ++ goto out; ++ } + } + + if ((flags & MSG_PEEK) && +@@ -2966,12 +2972,6 @@ int tcp_disconnect(struct sock *sk, int flags) + int old_state = sk->sk_state; + u32 seq; + +- /* Deny disconnect if other threads are blocked in sk_wait_event() +- * or inet_wait_for_connect(). +- */ +- if (sk->sk_wait_pending) +- return -EBUSY; +- + if (old_state != TCP_CLOSE) + tcp_set_state(sk, TCP_CLOSE); + +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index 3272682030015..53b0d62fd2c2d 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -307,6 +307,10 @@ msg_bytes_ready: + } + + data = tcp_msg_wait_data(sk, psock, timeo); ++ if (data < 0) { ++ copied = data; ++ goto unlock; ++ } + if (data && !sk_psock_queue_empty(psock)) + goto msg_bytes_ready; + copied = -EAGAIN; +@@ -317,6 +321,8 @@ out: + tcp_rcv_space_adjust(sk); + if (copied > 0) + __tcp_cleanup_rbuf(sk, copied); ++ ++unlock: + release_sock(sk); + sk_psock_put(sk, psock); + return copied; +@@ -351,6 +357,10 @@ msg_bytes_ready: + + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + data = tcp_msg_wait_data(sk, psock, timeo); ++ if (data < 0) { ++ ret = data; ++ goto unlock; ++ } + if (data) { + if (!sk_psock_queue_empty(psock)) + goto msg_bytes_ready; +@@ -361,6 +371,8 @@ msg_bytes_ready: + copied = -EAGAIN; + } + ret = copied; ++ ++unlock: + release_sock(sk); + sk_psock_put(sk, psock); + return ret; +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 2dbdc26da86e4..38528d110288b 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -1869,6 +1869,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb, + #ifdef CONFIG_TLS_DEVICE + tail->decrypted != skb->decrypted || + #endif ++ !mptcp_skb_can_collapse(tail, skb) || + thtail->doff != th->doff || + memcmp(thtail + 1, th + 1, hdrlen - sizeof(*th))) + goto no_coalesce; +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index a8f58f5e99a77..afa819eede6a3 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2527,6 +2527,18 @@ static bool tcp_pacing_check(struct sock *sk) + return true; + } + ++static bool tcp_rtx_queue_empty_or_single_skb(const struct sock *sk) ++{ ++ const struct rb_node *node = sk->tcp_rtx_queue.rb_node; ++ ++ /* No skb in the rtx queue. */ ++ if (!node) ++ return true; ++ ++ /* Only one skb in rtx queue. */ ++ return !node->rb_left && !node->rb_right; ++} ++ + /* TCP Small Queues : + * Control number of packets in qdisc/devices to two packets / or ~1 ms. + * (These limits are doubled for retransmits) +@@ -2564,12 +2576,12 @@ static bool tcp_small_queue_check(struct sock *sk, const struct sk_buff *skb, + limit += extra_bytes; + } + if (refcount_read(&sk->sk_wmem_alloc) > limit) { +- /* Always send skb if rtx queue is empty. ++ /* Always send skb if rtx queue is empty or has one skb. + * No need to wait for TX completion to call us back, + * after softirq/tasklet schedule. + * This helps when TX completions are delayed too much. + */ +- if (tcp_rtx_queue_empty(sk)) ++ if (tcp_rtx_queue_empty_or_single_skb(sk)) + return false; + + set_bit(TSQ_THROTTLED, &sk->sk_tsq_flags); +@@ -2773,7 +2785,7 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto) + { + struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); +- u32 timeout, rto_delta_us; ++ u32 timeout, timeout_us, rto_delta_us; + int early_retrans; + + /* Don't do any loss probe on a Fast Open connection before 3WHS +@@ -2797,11 +2809,12 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto) + * sample is available then probe after TCP_TIMEOUT_INIT. + */ + if (tp->srtt_us) { +- timeout = usecs_to_jiffies(tp->srtt_us >> 2); ++ timeout_us = tp->srtt_us >> 2; + if (tp->packets_out == 1) +- timeout += TCP_RTO_MIN; ++ timeout_us += tcp_rto_min_us(sk); + else +- timeout += TCP_TIMEOUT_MIN; ++ timeout_us += TCP_TIMEOUT_MIN_US; ++ timeout = usecs_to_jiffies(timeout_us); + } else { + timeout = TCP_TIMEOUT_INIT; + } +diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c +index acf4869c5d3b5..bba10110fbbc1 100644 +--- a/net/ipv4/tcp_recovery.c ++++ b/net/ipv4/tcp_recovery.c +@@ -104,7 +104,7 @@ bool tcp_rack_mark_lost(struct sock *sk) + tp->rack.advanced = 0; + tcp_rack_detect_loss(sk, &timeout); + if (timeout) { +- timeout = usecs_to_jiffies(timeout) + TCP_TIMEOUT_MIN; ++ timeout = usecs_to_jiffies(timeout + TCP_TIMEOUT_MIN_US); + inet_csk_reset_xmit_timer(sk, ICSK_TIME_REO_TIMEOUT, + timeout, inet_csk(sk)->icsk_rto); + } +diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c +index fddd0cbdede15..e023d29e919c1 100644 +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -770,7 +770,9 @@ static inline int esp_remove_trailer(struct sk_buff *skb) + skb->csum = csum_block_sub(skb->csum, csumdiff, + skb->len - trimlen); + } +- pskb_trim(skb, skb->len - trimlen); ++ ret = pskb_trim(skb, skb->len - trimlen); ++ if (unlikely(ret)) ++ return ret; + + ret = nexthdr[1]; + +diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c +index eecc5e59da17c..50c278f1c1063 100644 +--- a/net/ipv6/xfrm6_policy.c ++++ b/net/ipv6/xfrm6_policy.c +@@ -117,10 +117,10 @@ static void xfrm6_dst_destroy(struct dst_entry *dst) + { + struct xfrm_dst *xdst = (struct xfrm_dst *)dst; + +- if (likely(xdst->u.rt6.rt6i_idev)) +- in6_dev_put(xdst->u.rt6.rt6i_idev); + dst_destroy_metrics_generic(dst); + rt6_uncached_list_del(&xdst->u.rt6); ++ if (likely(xdst->u.rt6.rt6i_idev)) ++ in6_dev_put(xdst->u.rt6.rt6i_idev); + xfrm_dst_destroy(xdst); + } + +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index e883c41a2163b..0e3a1753a51c6 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1860,7 +1860,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, + /* VHT can override some HT caps such as the A-MSDU max length */ + if (params->vht_capa) + ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, +- params->vht_capa, link_sta); ++ params->vht_capa, NULL, ++ link_sta); + + if (params->he_capa) + ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index e1900077bc4b9..5542c93edfba0 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -1072,7 +1072,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, + &chandef); + memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie)); + ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, +- &cap_ie, ++ &cap_ie, NULL, + &sta->deflink); + if (memcmp(&cap, &sta->sta.deflink.vht_cap, sizeof(cap))) + rates_updated |= true; +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index f8cd94ba55ccc..2cce9eba6a120 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2142,6 +2142,7 @@ void + ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, + struct ieee80211_supported_band *sband, + const struct ieee80211_vht_cap *vht_cap_ie, ++ const struct ieee80211_vht_cap *vht_cap_ie2, + struct link_sta_info *link_sta); + enum ieee80211_sta_rx_bandwidth + ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta); +diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c +index f3d5bb0a59f10..a1e526419e9d2 100644 +--- a/net/mac80211/mesh_plink.c ++++ b/net/mac80211/mesh_plink.c +@@ -451,7 +451,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, + changed |= IEEE80211_RC_BW_CHANGED; + + ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, +- elems->vht_cap_elem, ++ elems->vht_cap_elem, NULL, + &sta->deflink); + + ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap, +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 24b2833e0e475..0c9198997482b 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -4202,10 +4202,33 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, + elems->ht_cap_elem, + link_sta); + +- if (elems->vht_cap_elem && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) ++ if (elems->vht_cap_elem && ++ !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) { ++ const struct ieee80211_vht_cap *bss_vht_cap = NULL; ++ const struct cfg80211_bss_ies *ies; ++ ++ /* ++ * Cisco AP module 9115 with FW 17.3 has a bug and sends a ++ * too large maximum MPDU length in the association response ++ * (indicating 12k) that it cannot actually process ... ++ * Work around that. ++ */ ++ rcu_read_lock(); ++ ies = rcu_dereference(cbss->ies); ++ if (ies) { ++ const struct element *elem; ++ ++ elem = cfg80211_find_elem(WLAN_EID_VHT_CAPABILITY, ++ ies->data, ies->len); ++ if (elem && elem->datalen >= sizeof(*bss_vht_cap)) ++ bss_vht_cap = (const void *)elem->data; ++ } ++ + ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, + elems->vht_cap_elem, +- link_sta); ++ bss_vht_cap, link_sta); ++ rcu_read_unlock(); ++ } + + if (elems->he_operation && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) && + elems->he_cap) { +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index 7fe7280e84374..d45d4be63dd87 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -665,7 +665,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) + } + + if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED && +- !ieee80211_is_deauth(hdr->frame_control))) ++ !ieee80211_is_deauth(hdr->frame_control)) && ++ tx->skb->protocol != tx->sdata->control_port_protocol) + return TX_DROP; + + if (!skip_hw && tx->key && +diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c +index c1250aa478083..b3a5c3e96a720 100644 +--- a/net/mac80211/vht.c ++++ b/net/mac80211/vht.c +@@ -4,7 +4,7 @@ + * + * Portions of this file + * Copyright(c) 2015 - 2016 Intel Deutschland GmbH +- * Copyright (C) 2018 - 2022 Intel Corporation ++ * Copyright (C) 2018 - 2023 Intel Corporation + */ + + #include +@@ -116,12 +116,14 @@ void + ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, + struct ieee80211_supported_band *sband, + const struct ieee80211_vht_cap *vht_cap_ie, ++ const struct ieee80211_vht_cap *vht_cap_ie2, + struct link_sta_info *link_sta) + { + struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap; + struct ieee80211_sta_vht_cap own_cap; + u32 cap_info, i; + bool have_80mhz; ++ u32 mpdu_len; + + memset(vht_cap, 0, sizeof(*vht_cap)); + +@@ -317,11 +319,21 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, + + link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta); + ++ /* ++ * Work around the Cisco 9115 FW 17.3 bug by taking the min of ++ * both reported MPDU lengths. ++ */ ++ mpdu_len = vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK; ++ if (vht_cap_ie2) ++ mpdu_len = min_t(u32, mpdu_len, ++ le32_get_bits(vht_cap_ie2->vht_cap_info, ++ IEEE80211_VHT_CAP_MAX_MPDU_MASK)); ++ + /* + * FIXME - should the amsdu len be per link? store per link + * and maintain a minimum? + */ +- switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) { ++ switch (mpdu_len) { + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: + link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454; + break; +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 679c2732b5d01..636580c4736c9 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1300,7 +1300,7 @@ alloc_skb: + if (copy == 0) { + u64 snd_una = READ_ONCE(msk->snd_una); + +- if (snd_una != msk->snd_nxt) { ++ if (snd_una != msk->snd_nxt || tcp_write_queue_tail(ssk)) { + tcp_remove_empty_skb(ssk); + return 0; + } +@@ -1308,11 +1308,6 @@ alloc_skb: + zero_window_probe = true; + data_seq = snd_una - 1; + copy = 1; +- +- /* all mptcp-level data is acked, no skbs should be present into the +- * ssk write queue +- */ +- WARN_ON_ONCE(reuse_skb); + } + + copy = min_t(size_t, copy, info->limit - info->sent); +@@ -1341,7 +1336,6 @@ alloc_skb: + if (reuse_skb) { + TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; + mpext->data_len += copy; +- WARN_ON_ONCE(zero_window_probe); + goto out; + } + +@@ -2342,6 +2336,26 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) + #define MPTCP_CF_PUSH BIT(1) + #define MPTCP_CF_FASTCLOSE BIT(2) + ++/* be sure to send a reset only if the caller asked for it, also ++ * clean completely the subflow status when the subflow reaches ++ * TCP_CLOSE state ++ */ ++static void __mptcp_subflow_disconnect(struct sock *ssk, ++ struct mptcp_subflow_context *subflow, ++ unsigned int flags) ++{ ++ if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || ++ (flags & MPTCP_CF_FASTCLOSE)) { ++ /* The MPTCP code never wait on the subflow sockets, TCP-level ++ * disconnect should never fail ++ */ ++ WARN_ON_ONCE(tcp_disconnect(ssk, 0)); ++ mptcp_subflow_ctx_reset(subflow); ++ } else { ++ tcp_shutdown(ssk, SEND_SHUTDOWN); ++ } ++} ++ + /* subflow sockets can be either outgoing (connect) or incoming + * (accept). + * +@@ -2379,7 +2393,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, + lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); + + if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) { +- /* be sure to force the tcp_disconnect() path, ++ /* be sure to force the tcp_close path + * to generate the egress reset + */ + ssk->sk_lingertime = 0; +@@ -2389,12 +2403,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, + + need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); + if (!dispose_it) { +- /* The MPTCP code never wait on the subflow sockets, TCP-level +- * disconnect should never fail +- */ +- WARN_ON_ONCE(tcp_disconnect(ssk, 0)); ++ __mptcp_subflow_disconnect(ssk, subflow, flags); + msk->subflow->state = SS_UNCONNECTED; +- mptcp_subflow_ctx_reset(subflow); + release_sock(ssk); + + goto out; +@@ -3069,12 +3079,6 @@ static int mptcp_disconnect(struct sock *sk, int flags) + { + struct mptcp_sock *msk = mptcp_sk(sk); + +- /* Deny disconnect if other threads are blocked in sk_wait_event() +- * or inet_wait_for_connect(). +- */ +- if (sk->sk_wait_pending) +- return -EBUSY; +- + /* We are on the fastopen error path. We can't call straight into the + * subflows cleanup code due to lock nesting (we are already under + * msk->firstsocket lock). +@@ -3145,7 +3149,6 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk, + inet_sk(nsk)->pinet6 = mptcp_inet6_sk(nsk); + #endif + +- nsk->sk_wait_pending = 0; + __mptcp_init_sock(nsk); + + msk = mptcp_sk(nsk); +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index be5869366c7d3..e43d9508e7a9c 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3166,7 +3166,7 @@ int nft_expr_inner_parse(const struct nft_ctx *ctx, const struct nlattr *nla, + if (err < 0) + return err; + +- if (!tb[NFTA_EXPR_DATA]) ++ if (!tb[NFTA_EXPR_DATA] || !tb[NFTA_EXPR_NAME]) + return -EINVAL; + + type = __nft_expr_type_get(ctx->family, tb[NFTA_EXPR_NAME]); +@@ -5553,7 +5553,6 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, + const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); + unsigned char *b = skb_tail_pointer(skb); + struct nlattr *nest; +- u64 timeout = 0; + + nest = nla_nest_start_noflag(skb, NFTA_LIST_ELEM); + if (nest == NULL) +@@ -5589,15 +5588,11 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, + htonl(*nft_set_ext_flags(ext)))) + goto nla_put_failure; + +- if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) { +- timeout = *nft_set_ext_timeout(ext); +- if (nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT, +- nf_jiffies64_to_msecs(timeout), +- NFTA_SET_ELEM_PAD)) +- goto nla_put_failure; +- } else if (set->flags & NFT_SET_TIMEOUT) { +- timeout = READ_ONCE(set->timeout); +- } ++ if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) && ++ nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT, ++ nf_jiffies64_to_msecs(*nft_set_ext_timeout(ext)), ++ NFTA_SET_ELEM_PAD)) ++ goto nla_put_failure; + + if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) { + u64 expires, now = get_jiffies_64(); +@@ -5612,9 +5607,6 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, + nf_jiffies64_to_msecs(expires), + NFTA_SET_ELEM_PAD)) + goto nla_put_failure; +- +- if (reset) +- *nft_set_ext_expiration(ext) = now + timeout; + } + + if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) { +diff --git a/net/netfilter/nft_inner.c b/net/netfilter/nft_inner.c +index 28e2873ba24e4..928312d01eb1d 100644 +--- a/net/netfilter/nft_inner.c ++++ b/net/netfilter/nft_inner.c +@@ -298,6 +298,7 @@ static int nft_inner_init(const struct nft_ctx *ctx, + int err; + + if (!tb[NFTA_INNER_FLAGS] || ++ !tb[NFTA_INNER_NUM] || + !tb[NFTA_INNER_HDRSIZE] || + !tb[NFTA_INNER_TYPE] || + !tb[NFTA_INNER_EXPR]) +diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c +index 120f6d395b98b..0a689c8e0295d 100644 +--- a/net/netfilter/nft_payload.c ++++ b/net/netfilter/nft_payload.c +@@ -179,7 +179,7 @@ void nft_payload_eval(const struct nft_expr *expr, + + switch (priv->base) { + case NFT_PAYLOAD_LL_HEADER: +- if (!skb_mac_header_was_set(skb)) ++ if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) == 0) + goto err; + + if (skb_vlan_tag_present(skb) && +diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c +index 2660ceab3759d..e34662f4a71e0 100644 +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -568,6 +568,8 @@ static void *nft_rbtree_deactivate(const struct net *net, + nft_rbtree_interval_end(this)) { + parent = parent->rb_right; + continue; ++ } else if (nft_set_elem_expired(&rbe->ext)) { ++ break; + } else if (!nft_set_elem_active(&rbe->ext, genmask)) { + parent = parent->rb_left; + continue; +diff --git a/net/nfc/nci/spi.c b/net/nfc/nci/spi.c +index 0935527d1d12b..b68150c971d0b 100644 +--- a/net/nfc/nci/spi.c ++++ b/net/nfc/nci/spi.c +@@ -151,6 +151,8 @@ static int send_acknowledge(struct nci_spi *nspi, u8 acknowledge) + int ret; + + skb = nci_skb_alloc(nspi->ndev, 0, GFP_KERNEL); ++ if (!skb) ++ return -ENOMEM; + + /* add the NCI SPI header to the start of the buffer */ + hdr = skb_push(skb, NCI_SPI_HDR_LEN); +diff --git a/net/rfkill/core.c b/net/rfkill/core.c +index 01fca7a10b4bb..14cc8fe8584bd 100644 +--- a/net/rfkill/core.c ++++ b/net/rfkill/core.c +@@ -48,6 +48,7 @@ struct rfkill { + bool persistent; + bool polling_paused; + bool suspended; ++ bool need_sync; + + const struct rfkill_ops *ops; + void *data; +@@ -368,6 +369,17 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked) + rfkill_event(rfkill); + } + ++static void rfkill_sync(struct rfkill *rfkill) ++{ ++ lockdep_assert_held(&rfkill_global_mutex); ++ ++ if (!rfkill->need_sync) ++ return; ++ ++ rfkill_set_block(rfkill, rfkill_global_states[rfkill->type].cur); ++ rfkill->need_sync = false; ++} ++ + static void rfkill_update_global_state(enum rfkill_type type, bool blocked) + { + int i; +@@ -730,6 +742,10 @@ static ssize_t soft_show(struct device *dev, struct device_attribute *attr, + { + struct rfkill *rfkill = to_rfkill(dev); + ++ mutex_lock(&rfkill_global_mutex); ++ rfkill_sync(rfkill); ++ mutex_unlock(&rfkill_global_mutex); ++ + return sysfs_emit(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0); + } + +@@ -751,6 +767,7 @@ static ssize_t soft_store(struct device *dev, struct device_attribute *attr, + return -EINVAL; + + mutex_lock(&rfkill_global_mutex); ++ rfkill_sync(rfkill); + rfkill_set_block(rfkill, state); + mutex_unlock(&rfkill_global_mutex); + +@@ -783,6 +800,10 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr, + { + struct rfkill *rfkill = to_rfkill(dev); + ++ mutex_lock(&rfkill_global_mutex); ++ rfkill_sync(rfkill); ++ mutex_unlock(&rfkill_global_mutex); ++ + return sysfs_emit(buf, "%d\n", user_state_from_blocked(rfkill->state)); + } + +@@ -805,6 +826,7 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, + return -EINVAL; + + mutex_lock(&rfkill_global_mutex); ++ rfkill_sync(rfkill); + rfkill_set_block(rfkill, state == RFKILL_USER_STATE_SOFT_BLOCKED); + mutex_unlock(&rfkill_global_mutex); + +@@ -1032,14 +1054,10 @@ static void rfkill_uevent_work(struct work_struct *work) + + static void rfkill_sync_work(struct work_struct *work) + { +- struct rfkill *rfkill; +- bool cur; +- +- rfkill = container_of(work, struct rfkill, sync_work); ++ struct rfkill *rfkill = container_of(work, struct rfkill, sync_work); + + mutex_lock(&rfkill_global_mutex); +- cur = rfkill_global_states[rfkill->type].cur; +- rfkill_set_block(rfkill, cur); ++ rfkill_sync(rfkill); + mutex_unlock(&rfkill_global_mutex); + } + +@@ -1087,6 +1105,7 @@ int __must_check rfkill_register(struct rfkill *rfkill) + round_jiffies_relative(POLL_INTERVAL)); + + if (!rfkill->persistent || rfkill_epo_lock_active) { ++ rfkill->need_sync = true; + schedule_work(&rfkill->sync_work); + } else { + #ifdef CONFIG_RFKILL_INPUT +@@ -1161,7 +1180,6 @@ static int rfkill_fop_open(struct inode *inode, struct file *file) + init_waitqueue_head(&data->read_wait); + + mutex_lock(&rfkill_global_mutex); +- mutex_lock(&data->mtx); + /* + * start getting events from elsewhere but hold mtx to get + * startup events added first +@@ -1171,11 +1189,13 @@ static int rfkill_fop_open(struct inode *inode, struct file *file) + ev = kzalloc(sizeof(*ev), GFP_KERNEL); + if (!ev) + goto free; ++ rfkill_sync(rfkill); + rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD); ++ mutex_lock(&data->mtx); + list_add_tail(&ev->list, &data->events); ++ mutex_unlock(&data->mtx); + } + list_add(&data->list, &rfkill_fds); +- mutex_unlock(&data->mtx); + mutex_unlock(&rfkill_global_mutex); + + file->private_data = data; +@@ -1183,7 +1203,6 @@ static int rfkill_fop_open(struct inode *inode, struct file *file) + return stream_open(inode, file); + + free: +- mutex_unlock(&data->mtx); + mutex_unlock(&rfkill_global_mutex); + mutex_destroy(&data->mtx); + list_for_each_entry_safe(ev, tmp, &data->events, list) +diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c +index e9d1b2f2ff0ad..5a81505fba9ac 100644 +--- a/net/rfkill/rfkill-gpio.c ++++ b/net/rfkill/rfkill-gpio.c +@@ -108,13 +108,13 @@ static int rfkill_gpio_probe(struct platform_device *pdev) + + rfkill->clk = devm_clk_get(&pdev->dev, NULL); + +- gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW); ++ gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_ASIS); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + + rfkill->reset_gpio = gpio; + +- gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_OUT_LOW); ++ gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_ASIS); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + +diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c +index 61d52594ff6d8..54dddc2ff5025 100644 +--- a/net/sched/sch_hfsc.c ++++ b/net/sched/sch_hfsc.c +@@ -903,6 +903,14 @@ hfsc_change_usc(struct hfsc_class *cl, struct tc_service_curve *usc, + cl->cl_flags |= HFSC_USC; + } + ++static void ++hfsc_upgrade_rt(struct hfsc_class *cl) ++{ ++ cl->cl_fsc = cl->cl_rsc; ++ rtsc_init(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vt, cl->cl_total); ++ cl->cl_flags |= HFSC_FSC; ++} ++ + static const struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = { + [TCA_HFSC_RSC] = { .len = sizeof(struct tc_service_curve) }, + [TCA_HFSC_FSC] = { .len = sizeof(struct tc_service_curve) }, +@@ -1012,10 +1020,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + if (parent == NULL) + return -ENOENT; + } +- if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) { +- NL_SET_ERR_MSG(extack, "Invalid parent - parent class must have FSC"); +- return -EINVAL; +- } + + if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0) + return -EINVAL; +@@ -1066,6 +1070,12 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + cl->cf_tree = RB_ROOT; + + sch_tree_lock(sch); ++ /* Check if the inner class is a misconfigured 'rt' */ ++ if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) { ++ NL_SET_ERR_MSG(extack, ++ "Forced curve change on parent 'rt' to 'sc'"); ++ hfsc_upgrade_rt(parent); ++ } + qdisc_class_hash_insert(&q->clhash, &cl->cl_common); + list_add_tail(&cl->siblings, &parent->children); + if (parent->level == 0) +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index 7c77565c39d19..c0e4e587b4994 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -2335,7 +2335,7 @@ static int smc_listen_find_device(struct smc_sock *new_smc, + smc_find_ism_store_rc(rc, ini); + return (!rc) ? 0 : ini->rc; + } +- return SMC_CLC_DECL_NOSMCDEV; ++ return prfx_rc; + } + + /* listen worker: finish RDMA setup */ +diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c +index 2f16f9d179662..814b0169f9723 100644 +--- a/net/sunrpc/auth.c ++++ b/net/sunrpc/auth.c +@@ -769,9 +769,14 @@ int rpcauth_wrap_req(struct rpc_task *task, struct xdr_stream *xdr) + * @task: controlling RPC task + * @xdr: xdr_stream containing RPC Reply header + * +- * On success, @xdr is updated to point past the verifier and +- * zero is returned. Otherwise, @xdr is in an undefined state +- * and a negative errno is returned. ++ * Return values: ++ * %0: Verifier is valid. @xdr now points past the verifier. ++ * %-EIO: Verifier is corrupted or message ended early. ++ * %-EACCES: Verifier is intact but not valid. ++ * %-EPROTONOSUPPORT: Server does not support the requested auth type. ++ * ++ * When a negative errno is returned, @xdr is left in an undefined ++ * state. + */ + int + rpcauth_checkverf(struct rpc_task *task, struct xdr_stream *xdr) +diff --git a/net/sunrpc/auth_tls.c b/net/sunrpc/auth_tls.c +index de7678f8a23d2..87f570fd3b00e 100644 +--- a/net/sunrpc/auth_tls.c ++++ b/net/sunrpc/auth_tls.c +@@ -129,9 +129,9 @@ static int tls_validate(struct rpc_task *task, struct xdr_stream *xdr) + if (*p != rpc_auth_null) + return -EIO; + if (xdr_stream_decode_opaque_inline(xdr, &str, starttls_len) != starttls_len) +- return -EIO; ++ return -EPROTONOSUPPORT; + if (memcmp(str, starttls_token, starttls_len)) +- return -EIO; ++ return -EPROTONOSUPPORT; + return 0; + } + +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index be6be7d785315..9fb0ccabc1a26 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -2721,7 +2721,15 @@ out_unparsable: + + out_verifier: + trace_rpc_bad_verifier(task); +- goto out_garbage; ++ switch (error) { ++ case -EPROTONOSUPPORT: ++ goto out_err; ++ case -EACCES: ++ /* Re-encode with a fresh cred */ ++ fallthrough; ++ default: ++ goto out_garbage; ++ } + + out_msg_denied: + error = -EACCES; +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 9f010369100a2..f392718951b1e 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -2645,6 +2645,10 @@ static void xs_tcp_tls_setup_socket(struct work_struct *work) + rcu_read_lock(); + lower_xprt = rcu_dereference(lower_clnt->cl_xprt); + rcu_read_unlock(); ++ ++ if (wait_on_bit_lock(&lower_xprt->state, XPRT_LOCKED, TASK_KILLABLE)) ++ goto out_unlock; ++ + status = xs_tls_handshake_sync(lower_xprt, &upper_xprt->xprtsec); + if (status) { + trace_rpc_tls_not_started(upper_clnt, upper_xprt); +@@ -2654,6 +2658,7 @@ static void xs_tcp_tls_setup_socket(struct work_struct *work) + status = xs_tcp_tls_finish_connecting(lower_xprt, upper_transport); + if (status) + goto out_close; ++ xprt_release_write(lower_xprt, NULL); + + trace_rpc_socket_connect(upper_xprt, upper_transport->sock, 0); + if (!xprt_test_and_set_connected(upper_xprt)) { +@@ -2675,6 +2680,7 @@ out_unlock: + return; + + out_close: ++ xprt_release_write(lower_xprt, NULL); + rpc_shutdown_client(lower_clnt); + + /* xprt_force_disconnect() wakes tasks with a fixed tk_status code. +diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c +index 4a8ee2f6badb9..f3d3fc1c32676 100644 +--- a/net/tls/tls_main.c ++++ b/net/tls/tls_main.c +@@ -96,8 +96,8 @@ void update_sk_prot(struct sock *sk, struct tls_context *ctx) + + int wait_on_pending_writer(struct sock *sk, long *timeo) + { +- int rc = 0; + DEFINE_WAIT_FUNC(wait, woken_wake_function); ++ int ret, rc = 0; + + add_wait_queue(sk_sleep(sk), &wait); + while (1) { +@@ -111,9 +111,13 @@ int wait_on_pending_writer(struct sock *sk, long *timeo) + break; + } + +- if (sk_wait_event(sk, timeo, +- !READ_ONCE(sk->sk_write_pending), &wait)) ++ ret = sk_wait_event(sk, timeo, ++ !READ_ONCE(sk->sk_write_pending), &wait); ++ if (ret) { ++ if (ret < 0) ++ rc = ret; + break; ++ } + } + remove_wait_queue(sk_sleep(sk), &wait); + return rc; +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index e047abc600893..ce925f3a52492 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -1288,6 +1288,7 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, + struct tls_context *tls_ctx = tls_get_ctx(sk); + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); + DEFINE_WAIT_FUNC(wait, woken_wake_function); ++ int ret = 0; + long timeo; + + timeo = sock_rcvtimeo(sk, nonblock); +@@ -1299,6 +1300,9 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, + if (sk->sk_err) + return sock_error(sk); + ++ if (ret < 0) ++ return ret; ++ + if (!skb_queue_empty(&sk->sk_receive_queue)) { + tls_strp_check_rcv(&ctx->strp); + if (tls_strp_msg_ready(ctx)) +@@ -1317,10 +1321,10 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, + released = true; + add_wait_queue(sk_sleep(sk), &wait); + sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); +- sk_wait_event(sk, &timeo, +- tls_strp_msg_ready(ctx) || +- !sk_psock_queue_empty(psock), +- &wait); ++ ret = sk_wait_event(sk, &timeo, ++ tls_strp_msg_ready(ctx) || ++ !sk_psock_queue_empty(psock), ++ &wait); + sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); + remove_wait_queue(sk_sleep(sk), &wait); + +@@ -1845,13 +1849,11 @@ tls_read_flush_backlog(struct sock *sk, struct tls_prot_info *prot, + return sk_flush_backlog(sk); + } + +-static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, +- bool nonblock) ++static int tls_rx_reader_acquire(struct sock *sk, struct tls_sw_context_rx *ctx, ++ bool nonblock) + { + long timeo; +- int err; +- +- lock_sock(sk); ++ int ret; + + timeo = sock_rcvtimeo(sk, nonblock); + +@@ -1861,30 +1863,36 @@ static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, + ctx->reader_contended = 1; + + add_wait_queue(&ctx->wq, &wait); +- sk_wait_event(sk, &timeo, +- !READ_ONCE(ctx->reader_present), &wait); ++ ret = sk_wait_event(sk, &timeo, ++ !READ_ONCE(ctx->reader_present), &wait); + remove_wait_queue(&ctx->wq, &wait); + +- if (timeo <= 0) { +- err = -EAGAIN; +- goto err_unlock; +- } +- if (signal_pending(current)) { +- err = sock_intr_errno(timeo); +- goto err_unlock; +- } ++ if (timeo <= 0) ++ return -EAGAIN; ++ if (signal_pending(current)) ++ return sock_intr_errno(timeo); ++ if (ret < 0) ++ return ret; + } + + WRITE_ONCE(ctx->reader_present, 1); + + return 0; ++} + +-err_unlock: +- release_sock(sk); ++static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, ++ bool nonblock) ++{ ++ int err; ++ ++ lock_sock(sk); ++ err = tls_rx_reader_acquire(sk, ctx, nonblock); ++ if (err) ++ release_sock(sk); + return err; + } + +-static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) ++static void tls_rx_reader_release(struct sock *sk, struct tls_sw_context_rx *ctx) + { + if (unlikely(ctx->reader_contended)) { + if (wq_has_sleeper(&ctx->wq)) +@@ -1896,6 +1904,11 @@ static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) + } + + WRITE_ONCE(ctx->reader_present, 0); ++} ++ ++static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) ++{ ++ tls_rx_reader_release(sk, ctx); + release_sock(sk); + } + +diff --git a/net/wireless/core.c b/net/wireless/core.c +index 64e8616171104..acec41c1809a8 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -1622,7 +1622,7 @@ void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work) + list_add_tail(&work->entry, &rdev->wiphy_work_list); + spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); + +- schedule_work(&rdev->wiphy_work); ++ queue_work(system_unbound_wq, &rdev->wiphy_work); + } + EXPORT_SYMBOL_GPL(wiphy_work_queue); + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 705d1cf048309..bf968cdbfbb51 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -5910,6 +5910,21 @@ out: + nlmsg_free(msg); + } + ++static int nl80211_validate_ap_phy_operation(struct cfg80211_ap_settings *params) ++{ ++ struct ieee80211_channel *channel = params->chandef.chan; ++ ++ if ((params->he_cap || params->he_oper) && ++ (channel->flags & IEEE80211_CHAN_NO_HE)) ++ return -EOPNOTSUPP; ++ ++ if ((params->eht_cap || params->eht_oper) && ++ (channel->flags & IEEE80211_CHAN_NO_EHT)) ++ return -EOPNOTSUPP; ++ ++ return 0; ++} ++ + static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) + { + struct cfg80211_registered_device *rdev = info->user_ptr[0]; +@@ -6179,6 +6194,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) + if (err) + goto out_unlock; + ++ err = nl80211_validate_ap_phy_operation(params); ++ if (err) ++ goto out_unlock; ++ + if (info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]) + params->flags = nla_get_u32( + info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]); +@@ -8483,7 +8502,7 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; +- struct mesh_config cfg; ++ struct mesh_config cfg = {}; + u32 mask; + int err; + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 0cf1ce7b69342..939deecf0bbef 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -908,6 +908,10 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev) + !cfg80211_find_ssid_match(ap, request)) + continue; + ++ if (!is_broadcast_ether_addr(request->bssid) && ++ !ether_addr_equal(request->bssid, ap->bssid)) ++ continue; ++ + if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid) + continue; + +diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c +index b864740846902..e21cc71095bb2 100644 +--- a/net/xfrm/xfrm_interface_core.c ++++ b/net/xfrm/xfrm_interface_core.c +@@ -380,8 +380,8 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err) + skb->dev = dev; + + if (err) { +- dev->stats.rx_errors++; +- dev->stats.rx_dropped++; ++ DEV_STATS_INC(dev, rx_errors); ++ DEV_STATS_INC(dev, rx_dropped); + + return 0; + } +@@ -426,7 +426,6 @@ static int + xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + { + struct xfrm_if *xi = netdev_priv(dev); +- struct net_device_stats *stats = &xi->dev->stats; + struct dst_entry *dst = skb_dst(skb); + unsigned int length = skb->len; + struct net_device *tdev; +@@ -473,7 +472,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + tdev = dst->dev; + + if (tdev == dev) { +- stats->collisions++; ++ DEV_STATS_INC(dev, collisions); + net_warn_ratelimited("%s: Local routing loop detected!\n", + dev->name); + goto tx_err_dst_release; +@@ -512,13 +511,13 @@ xmit: + if (net_xmit_eval(err) == 0) { + dev_sw_netstats_tx_add(dev, 1, length); + } else { +- stats->tx_errors++; +- stats->tx_aborted_errors++; ++ DEV_STATS_INC(dev, tx_errors); ++ DEV_STATS_INC(dev, tx_aborted_errors); + } + + return 0; + tx_err_link_failure: +- stats->tx_carrier_errors++; ++ DEV_STATS_INC(dev, tx_carrier_errors); + dst_link_failure(skb); + tx_err_dst_release: + dst_release(dst); +@@ -528,7 +527,6 @@ tx_err_dst_release: + static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct xfrm_if *xi = netdev_priv(dev); +- struct net_device_stats *stats = &xi->dev->stats; + struct dst_entry *dst = skb_dst(skb); + struct flowi fl; + int ret; +@@ -545,7 +543,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) + dst = ip6_route_output(dev_net(dev), NULL, &fl.u.ip6); + if (dst->error) { + dst_release(dst); +- stats->tx_carrier_errors++; ++ DEV_STATS_INC(dev, tx_carrier_errors); + goto tx_err; + } + skb_dst_set(skb, dst); +@@ -561,7 +559,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) + fl.u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + rt = __ip_route_output_key(dev_net(dev), &fl.u.ip4); + if (IS_ERR(rt)) { +- stats->tx_carrier_errors++; ++ DEV_STATS_INC(dev, tx_carrier_errors); + goto tx_err; + } + skb_dst_set(skb, &rt->dst); +@@ -580,8 +578,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_OK; + + tx_err: +- stats->tx_errors++; +- stats->tx_dropped++; ++ DEV_STATS_INC(dev, tx_errors); ++ DEV_STATS_INC(dev, tx_dropped); + kfree_skb(skb); + return NETDEV_TX_OK; + } +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index d6b405782b636..d24b4d4f620ea 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -851,7 +851,7 @@ static void xfrm_policy_inexact_list_reinsert(struct net *net, + struct hlist_node *newpos = NULL; + bool matches_s, matches_d; + +- if (!policy->bydst_reinsert) ++ if (policy->walk.dead || !policy->bydst_reinsert) + continue; + + WARN_ON_ONCE(policy->family != family); +@@ -1256,8 +1256,11 @@ static void xfrm_hash_rebuild(struct work_struct *work) + struct xfrm_pol_inexact_bin *bin; + u8 dbits, sbits; + ++ if (policy->walk.dead) ++ continue; ++ + dir = xfrm_policy_id2dir(policy->index); +- if (policy->walk.dead || dir >= XFRM_POLICY_MAX) ++ if (dir >= XFRM_POLICY_MAX) + continue; + + if ((dir & XFRM_POLICY_MASK) == XFRM_POLICY_OUT) { +@@ -1372,8 +1375,6 @@ EXPORT_SYMBOL(xfrm_policy_hash_rebuild); + * of an absolute inpredictability of ordering of rules. This will not pass. */ + static u32 xfrm_gen_index(struct net *net, int dir, u32 index) + { +- static u32 idx_generator; +- + for (;;) { + struct hlist_head *list; + struct xfrm_policy *p; +@@ -1381,8 +1382,8 @@ static u32 xfrm_gen_index(struct net *net, int dir, u32 index) + int found; + + if (!index) { +- idx = (idx_generator | dir); +- idx_generator += 8; ++ idx = (net->xfrm.idx_generator | dir); ++ net->xfrm.idx_generator += 8; + } else { + idx = index; + index = 0; +@@ -1823,9 +1824,11 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid) + + again: + list_for_each_entry(pol, &net->xfrm.policy_all, walk.all) { ++ if (pol->walk.dead) ++ continue; ++ + dir = xfrm_policy_id2dir(pol->index); +- if (pol->walk.dead || +- dir >= XFRM_POLICY_MAX || ++ if (dir >= XFRM_POLICY_MAX || + pol->type != type) + continue; + +@@ -1862,9 +1865,11 @@ int xfrm_dev_policy_flush(struct net *net, struct net_device *dev, + + again: + list_for_each_entry(pol, &net->xfrm.policy_all, walk.all) { ++ if (pol->walk.dead) ++ continue; ++ + dir = xfrm_policy_id2dir(pol->index); +- if (pol->walk.dead || +- dir >= XFRM_POLICY_MAX || ++ if (dir >= XFRM_POLICY_MAX || + pol->xdo.dev != dev) + continue; + +@@ -3215,7 +3220,7 @@ no_transform: + } + + for (i = 0; i < num_pols; i++) +- pols[i]->curlft.use_time = ktime_get_real_seconds(); ++ WRITE_ONCE(pols[i]->curlft.use_time, ktime_get_real_seconds()); + + if (num_xfrms < 0) { + /* Prohibit the flow */ +diff --git a/rust/Makefile b/rust/Makefile +index 4124bfa01798d..467f50a752dbd 100644 +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -1,5 +1,8 @@ + # SPDX-License-Identifier: GPL-2.0 + ++# Where to place rustdoc generated documentation ++rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc ++ + obj-$(CONFIG_RUST) += core.o compiler_builtins.o + always-$(CONFIG_RUST) += exports_core_generated.h + +@@ -65,7 +68,7 @@ quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< + OBJTREE=$(abspath $(objtree)) \ + $(RUSTDOC) $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags)) \ + $(rustc_target_flags) -L$(objtree)/$(obj) \ +- --output $(objtree)/$(obj)/doc \ ++ --output $(rustdoc_output) \ + --crate-name $(subst rustdoc-,,$@) \ + @$(objtree)/include/generated/rustc_cfg $< + +@@ -82,15 +85,14 @@ quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< + # and then retouch the generated files. + rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ + rustdoc-alloc rustdoc-kernel +- $(Q)cp $(srctree)/Documentation/images/logo.svg $(objtree)/$(obj)/doc +- $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(objtree)/$(obj)/doc +- $(Q)find $(objtree)/$(obj)/doc -name '*.html' -type f -print0 | xargs -0 sed -Ei \ +- -e 's:rust-logo\.svg:logo.svg:g' \ +- -e 's:rust-logo\.png:logo.svg:g' \ +- -e 's:favicon\.svg:logo.svg:g' \ +- -e 's:::g' +- $(Q)echo '.logo-container > img { object-fit: contain; }' \ +- >> $(objtree)/$(obj)/doc/rustdoc.css ++ $(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.files/ ++ $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/static.files/ ++ $(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \ ++ -e 's:rust-logo-[0-9a-f]+\.svg:logo.svg:g' \ ++ -e 's:favicon-[0-9a-f]+\.svg:logo.svg:g' \ ++ -e 's:::g' ++ $(Q)for f in $(rustdoc_output)/static.files/rustdoc-*.css; do \ ++ echo ".logo-container > img { object-fit: contain; }" >> $$f; done + + rustdoc-macros: private rustdoc_host = yes + rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ +@@ -154,7 +156,7 @@ quiet_cmd_rustdoc_test = RUSTDOC T $< + @$(objtree)/include/generated/rustc_cfg \ + $(rustc_target_flags) $(rustdoc_test_target_flags) \ + --sysroot $(objtree)/$(obj)/test/sysroot $(rustdoc_test_quiet) \ +- -L$(objtree)/$(obj)/test --output $(objtree)/$(obj)/doc \ ++ -L$(objtree)/$(obj)/test --output $(rustdoc_output) \ + --crate-name $(subst rusttest-,,$@) $< + + # We cannot use `-Zpanic-abort-tests` because some tests are dynamic, +diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs +index 05fcab6abfe63..0f29e7b2194c0 100644 +--- a/rust/kernel/error.rs ++++ b/rust/kernel/error.rs +@@ -37,7 +37,7 @@ pub mod code { + declare_err!(E2BIG, "Argument list too long."); + declare_err!(ENOEXEC, "Exec format error."); + declare_err!(EBADF, "Bad file number."); +- declare_err!(ECHILD, "Exec format error."); ++ declare_err!(ECHILD, "No child processes."); + declare_err!(EAGAIN, "Try again."); + declare_err!(ENOMEM, "Out of memory."); + declare_err!(EACCES, "Permission denied."); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 10703a3df7ea4..c2fbf484b1104 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7009,6 +7009,24 @@ static void alc287_fixup_bind_dacs(struct hda_codec *codec, + 0x0); /* Make sure 0x14 was disable */ + } + } ++/* Fix none verb table of Headset Mic pin */ ++static void alc_fixup_headset_mic(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ struct alc_spec *spec = codec->spec; ++ static const struct hda_pintbl pincfgs[] = { ++ { 0x19, 0x03a1103c }, ++ { } ++ }; ++ ++ switch (action) { ++ case HDA_FIXUP_ACT_PRE_PROBE: ++ snd_hda_apply_pincfgs(codec, pincfgs); ++ alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12); ++ spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; ++ break; ++ } ++} + + + enum { +@@ -7274,6 +7292,7 @@ enum { + ALC245_FIXUP_HP_X360_MUTE_LEDS, + ALC287_FIXUP_THINKPAD_I2S_SPK, + ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD, ++ ALC2XX_FIXUP_HEADSET_MIC, + }; + + /* A special fixup for Lenovo C940 and Yoga Duet 7; +@@ -9372,6 +9391,10 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI, + }, ++ [ALC2XX_FIXUP_HEADSET_MIC] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc_fixup_headset_mic, ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -9646,6 +9669,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), ++ SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED), +@@ -9715,6 +9739,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), + SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301V", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), ++ SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), +@@ -10656,6 +10681,8 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = { + SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, + {0x19, 0x40000000}, + {0x1a, 0x40000000}), ++ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC2XX_FIXUP_HEADSET_MIC, ++ {0x19, 0x40000000}), + {} + }; + +diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c +index 7e241908b5f16..4d7ccf682647e 100644 +--- a/sound/soc/codecs/cs35l56.c ++++ b/sound/soc/codecs/cs35l56.c +@@ -879,7 +879,7 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56) + + mutex_lock(&cs35l56->irq_lock); + +- init_completion(&cs35l56->init_completion); ++ reinit_completion(&cs35l56->init_completion); + + cs35l56_system_reset(cs35l56); + +diff --git a/sound/soc/codecs/cs42l42-sdw.c b/sound/soc/codecs/cs42l42-sdw.c +index 974bae4abfad1..94a66a325303b 100644 +--- a/sound/soc/codecs/cs42l42-sdw.c ++++ b/sound/soc/codecs/cs42l42-sdw.c +@@ -6,6 +6,7 @@ + + #include + #include ++#include + #include + #include + #include +diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c +index bd0e9fbc12ebf..6405fed9f095f 100644 +--- a/sound/soc/codecs/wcd938x-sdw.c ++++ b/sound/soc/codecs/wcd938x-sdw.c +@@ -1278,7 +1278,31 @@ static int wcd9380_probe(struct sdw_slave *pdev, + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + +- return component_add(dev, &wcd938x_sdw_component_ops); ++ ret = component_add(dev, &wcd938x_sdw_component_ops); ++ if (ret) ++ goto err_disable_rpm; ++ ++ return 0; ++ ++err_disable_rpm: ++ pm_runtime_disable(dev); ++ pm_runtime_set_suspended(dev); ++ pm_runtime_dont_use_autosuspend(dev); ++ ++ return ret; ++} ++ ++static int wcd9380_remove(struct sdw_slave *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ ++ component_del(dev, &wcd938x_sdw_component_ops); ++ ++ pm_runtime_disable(dev); ++ pm_runtime_set_suspended(dev); ++ pm_runtime_dont_use_autosuspend(dev); ++ ++ return 0; + } + + static const struct sdw_device_id wcd9380_slave_id[] = { +@@ -1320,6 +1344,7 @@ static const struct dev_pm_ops wcd938x_sdw_pm_ops = { + + static struct sdw_driver wcd9380_codec_driver = { + .probe = wcd9380_probe, ++ .remove = wcd9380_remove, + .ops = &wcd9380_slave_ops, + .id_table = wcd9380_slave_id, + .driver = { +diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c +index a3c6806613777..d27b919c63b41 100644 +--- a/sound/soc/codecs/wcd938x.c ++++ b/sound/soc/codecs/wcd938x.c +@@ -3325,8 +3325,10 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device + return dev_err_probe(dev, ret, "Failed to get supplies\n"); + + ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies); +- if (ret) ++ if (ret) { ++ regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); + return dev_err_probe(dev, ret, "Failed to enable supplies\n"); ++ } + + wcd938x_dt_parse_micbias_info(dev, wcd938x); + +@@ -3435,7 +3437,8 @@ static int wcd938x_bind(struct device *dev) + wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode); + if (!wcd938x->rxdev) { + dev_err(dev, "could not find slave with matching of node\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_unbind; + } + wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev); + wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x; +@@ -3443,46 +3446,47 @@ static int wcd938x_bind(struct device *dev) + wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode); + if (!wcd938x->txdev) { + dev_err(dev, "could not find txslave with matching of node\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_put_rxdev; + } + wcd938x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd938x->txdev); + wcd938x->sdw_priv[AIF1_CAP]->wcd938x = wcd938x; + wcd938x->tx_sdw_dev = dev_to_sdw_dev(wcd938x->txdev); +- if (!wcd938x->tx_sdw_dev) { +- dev_err(dev, "could not get txslave with matching of dev\n"); +- return -EINVAL; +- } + + /* As TX is main CSR reg interface, which should not be suspended first. + * expicilty add the dependency link */ + if (!device_link_add(wcd938x->rxdev, wcd938x->txdev, DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME)) { + dev_err(dev, "could not devlink tx and rx\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_put_txdev; + } + + if (!device_link_add(dev, wcd938x->txdev, DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME)) { + dev_err(dev, "could not devlink wcd and tx\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_remove_rxtx_link; + } + + if (!device_link_add(dev, wcd938x->rxdev, DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME)) { + dev_err(dev, "could not devlink wcd and rx\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_remove_tx_link; + } + + wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL); + if (!wcd938x->regmap) { + dev_err(dev, "could not get TX device regmap\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_remove_rx_link; + } + + ret = wcd938x_irq_init(wcd938x, dev); + if (ret) { + dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret); +- return ret; ++ goto err_remove_rx_link; + } + + wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq; +@@ -3491,27 +3495,45 @@ static int wcd938x_bind(struct device *dev) + ret = wcd938x_set_micbias_data(wcd938x); + if (ret < 0) { + dev_err(dev, "%s: bad micbias pdata\n", __func__); +- return ret; ++ goto err_remove_rx_link; + } + + ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x, + wcd938x_dais, ARRAY_SIZE(wcd938x_dais)); +- if (ret) ++ if (ret) { + dev_err(dev, "%s: Codec registration failed\n", + __func__); ++ goto err_remove_rx_link; ++ } + +- return ret; ++ return 0; + ++err_remove_rx_link: ++ device_link_remove(dev, wcd938x->rxdev); ++err_remove_tx_link: ++ device_link_remove(dev, wcd938x->txdev); ++err_remove_rxtx_link: ++ device_link_remove(wcd938x->rxdev, wcd938x->txdev); ++err_put_txdev: ++ put_device(wcd938x->txdev); ++err_put_rxdev: ++ put_device(wcd938x->rxdev); ++err_unbind: ++ component_unbind_all(dev, wcd938x); ++ ++ return ret; + } + + static void wcd938x_unbind(struct device *dev) + { + struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); + ++ snd_soc_unregister_component(dev); + device_link_remove(dev, wcd938x->txdev); + device_link_remove(dev, wcd938x->rxdev); + device_link_remove(wcd938x->rxdev, wcd938x->txdev); +- snd_soc_unregister_component(dev); ++ put_device(wcd938x->txdev); ++ put_device(wcd938x->rxdev); + component_unbind_all(dev, wcd938x); + } + +@@ -3572,13 +3594,13 @@ static int wcd938x_probe(struct platform_device *pdev) + + ret = wcd938x_add_slave_components(wcd938x, dev, &match); + if (ret) +- return ret; ++ goto err_disable_regulators; + + wcd938x_reset(wcd938x); + + ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match); + if (ret) +- return ret; ++ goto err_disable_regulators; + + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); +@@ -3588,11 +3610,27 @@ static int wcd938x_probe(struct platform_device *pdev) + pm_runtime_idle(dev); + + return 0; ++ ++err_disable_regulators: ++ regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); ++ regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); ++ ++ return ret; + } + + static void wcd938x_remove(struct platform_device *pdev) + { +- component_master_del(&pdev->dev, &wcd938x_comp_ops); ++ struct device *dev = &pdev->dev; ++ struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); ++ ++ component_master_del(dev, &wcd938x_comp_ops); ++ ++ pm_runtime_disable(dev); ++ pm_runtime_set_suspended(dev); ++ pm_runtime_dont_use_autosuspend(dev); ++ ++ regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); ++ regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); + } + + #if defined(CONFIG_OF) +diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c +index 430dd446321e5..452f0caf415b9 100644 +--- a/sound/soc/pxa/pxa-ssp.c ++++ b/sound/soc/pxa/pxa-ssp.c +@@ -779,7 +779,7 @@ static int pxa_ssp_probe(struct snd_soc_dai *dai) + if (IS_ERR(priv->extclk)) { + ret = PTR_ERR(priv->extclk); + if (ret == -EPROBE_DEFER) +- return ret; ++ goto err_priv; + + priv->extclk = NULL; + } +diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c +index e0f822ebb9b97..38a33c7b39084 100644 +--- a/tools/perf/util/dlfilter.c ++++ b/tools/perf/util/dlfilter.c +@@ -280,13 +280,21 @@ static struct perf_event_attr *dlfilter__attr(void *ctx) + return &d->evsel->core.attr; + } + ++static __s32 code_read(__u64 ip, struct map *map, struct machine *machine, void *buf, __u32 len) ++{ ++ u64 offset = map__map_ip(map, ip); ++ ++ if (ip + len >= map__end(map)) ++ len = map__end(map) - ip; ++ ++ return dso__data_read_offset(map__dso(map), machine, offset, buf, len); ++} ++ + static __s32 dlfilter__object_code(void *ctx, __u64 ip, void *buf, __u32 len) + { + struct dlfilter *d = (struct dlfilter *)ctx; + struct addr_location *al; + struct addr_location a; +- struct map *map; +- u64 offset; + __s32 ret; + + if (!d->ctx_valid) +@@ -296,27 +304,17 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip, void *buf, __u32 len) + if (!al) + return -1; + +- map = al->map; +- +- if (map && ip >= map__start(map) && ip < map__end(map) && ++ if (al->map && ip >= map__start(al->map) && ip < map__end(al->map) && + machine__kernel_ip(d->machine, ip) == machine__kernel_ip(d->machine, d->sample->ip)) +- goto have_map; ++ return code_read(ip, al->map, d->machine, buf, len); + + addr_location__init(&a); ++ + thread__find_map_fb(al->thread, d->sample->cpumode, ip, &a); +- if (!a.map) { +- ret = -1; +- goto out; +- } ++ ret = a.map ? code_read(ip, a.map, d->machine, buf, len) : -1; + +- map = a.map; +-have_map: +- offset = map__map_ip(map, ip); +- if (ip + len >= map__end(map)) +- len = map__end(map) - ip; +- ret = dso__data_read_offset(map__dso(map), d->machine, offset, buf, len); +-out: + addr_location__exit(&a); ++ + return ret; + } + +diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc +new file mode 100644 +index 0000000000000..bc9514428dbaf +--- /dev/null ++++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc +@@ -0,0 +1,13 @@ ++#!/bin/sh ++# SPDX-License-Identifier: GPL-2.0 ++# description: Test failure of registering kprobe on non unique symbol ++# requires: kprobe_events ++ ++SYMBOL='name_show' ++ ++# We skip this test on kernel where SYMBOL is unique or does not exist. ++if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}" /proc/kallsyms)" -le '1' ]; then ++ exit_unsupported ++fi ++ ++! echo "p:test_non_unique ${SYMBOL}" > kprobe_events +diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh +index d01b73a8ed0f0..621b1964ea6f3 100755 +--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh +@@ -1383,7 +1383,9 @@ chk_rst_nr() + count=$(get_counter ${ns_tx} "MPTcpExtMPRstTx") + if [ -z "$count" ]; then + echo -n "[skip]" +- elif [ $count -lt $rst_tx ]; then ++ # accept more rst than expected except if we don't expect any ++ elif { [ $rst_tx -ne 0 ] && [ $count -lt $rst_tx ]; } || ++ { [ $rst_tx -eq 0 ] && [ $count -ne 0 ]; }; then + echo "[fail] got $count MP_RST[s] TX expected $rst_tx" + fail_test + else +@@ -1394,7 +1396,9 @@ chk_rst_nr() + count=$(get_counter ${ns_rx} "MPTcpExtMPRstRx") + if [ -z "$count" ]; then + echo -n "[skip]" +- elif [ "$count" -lt "$rst_rx" ]; then ++ # accept more rst than expected except if we don't expect any ++ elif { [ $rst_rx -ne 0 ] && [ $count -lt $rst_rx ]; } || ++ { [ $rst_rx -eq 0 ] && [ $count -ne 0 ]; }; then + echo "[fail] got $count MP_RST[s] RX expected $rst_rx" + fail_test + else +@@ -2282,6 +2286,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_rm_tx_nr 1 + chk_rm_nr 1 1 ++ chk_rst_nr 0 0 + fi + + # multiple subflows, remove +@@ -2294,6 +2299,7 @@ remove_tests() + run_tests $ns1 $ns2 10.0.1.1 slow + chk_join_nr 2 2 2 + chk_rm_nr 2 2 ++ chk_rst_nr 0 0 + fi + + # single address, remove +@@ -2306,6 +2312,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_add_nr 1 1 + chk_rm_nr 1 1 invert ++ chk_rst_nr 0 0 + fi + + # subflow and signal, remove +@@ -2319,6 +2326,7 @@ remove_tests() + chk_join_nr 2 2 2 + chk_add_nr 1 1 + chk_rm_nr 1 1 ++ chk_rst_nr 0 0 + fi + + # subflows and signal, remove +@@ -2333,6 +2341,7 @@ remove_tests() + chk_join_nr 3 3 3 + chk_add_nr 1 1 + chk_rm_nr 2 2 ++ chk_rst_nr 0 0 + fi + + # addresses remove +@@ -2347,6 +2356,7 @@ remove_tests() + chk_join_nr 3 3 3 + chk_add_nr 3 3 + chk_rm_nr 3 3 invert ++ chk_rst_nr 0 0 + fi + + # invalid addresses remove +@@ -2361,6 +2371,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_add_nr 3 3 + chk_rm_nr 3 1 invert ++ chk_rst_nr 0 0 + fi + + # subflows and signal, flush +@@ -2375,6 +2386,7 @@ remove_tests() + chk_join_nr 3 3 3 + chk_add_nr 1 1 + chk_rm_nr 1 3 invert simult ++ chk_rst_nr 0 0 + fi + + # subflows flush +@@ -2394,6 +2406,7 @@ remove_tests() + else + chk_rm_nr 3 3 + fi ++ chk_rst_nr 0 0 + fi + + # addresses flush +@@ -2408,6 +2421,7 @@ remove_tests() + chk_join_nr 3 3 3 + chk_add_nr 3 3 + chk_rm_nr 3 3 invert simult ++ chk_rst_nr 0 0 + fi + + # invalid addresses flush +@@ -2422,6 +2436,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_add_nr 3 3 + chk_rm_nr 3 1 invert ++ chk_rst_nr 0 0 + fi + + # remove id 0 subflow +@@ -2433,6 +2448,7 @@ remove_tests() + run_tests $ns1 $ns2 10.0.1.1 slow + chk_join_nr 1 1 1 + chk_rm_nr 1 1 ++ chk_rst_nr 0 0 + fi + + # remove id 0 address +@@ -2445,6 +2461,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_add_nr 1 1 + chk_rm_nr 1 1 invert ++ chk_rst_nr 0 0 invert + fi + } + +diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh +index 3117a4be0cd04..e175cf2e7b50b 100755 +--- a/tools/testing/selftests/net/openvswitch/openvswitch.sh ++++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh +@@ -3,6 +3,8 @@ + # + # OVS kernel module self tests + ++trap ovs_exit_sig EXIT TERM INT ERR ++ + # Kselftest framework requirement - SKIP code is 4. + ksft_skip=4 + +@@ -202,7 +204,7 @@ run_test() { + fi + + if python3 ovs-dpctl.py -h 2>&1 | \ +- grep "Need to install the python" >/dev/null 2>&1; then ++ grep -E "Need to (install|upgrade) the python" >/dev/null 2>&1; then + stdbuf -o0 printf "TEST: %-60s [PYLIB]\n" "${tdesc}" + return $ksft_skip + fi +diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +index 1c8b36bc15d48..0d9bb167ebf4f 100644 +--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py ++++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +@@ -25,8 +25,10 @@ try: + from pyroute2.netlink import nlmsg_atoms + from pyroute2.netlink.exceptions import NetlinkError + from pyroute2.netlink.generic import GenericNetlinkSocket ++ import pyroute2 ++ + except ModuleNotFoundError: +- print("Need to install the python pyroute2 package.") ++ print("Need to install the python pyroute2 package >= 0.6.") + sys.exit(0) + + +@@ -732,12 +734,14 @@ class ovskey(nla): + "src", + lambda x: str(ipaddress.IPv4Address(x)), + int, ++ convert_ipv4, + ), + ( + "dst", + "dst", +- lambda x: str(ipaddress.IPv6Address(x)), ++ lambda x: str(ipaddress.IPv4Address(x)), + int, ++ convert_ipv4, + ), + ("tp_src", "tp_src", "%d", int), + ("tp_dst", "tp_dst", "%d", int), +@@ -1457,6 +1461,12 @@ def main(argv): + nlmsg_atoms.ovskey = ovskey + nlmsg_atoms.ovsactions = ovsactions + ++ # version check for pyroute2 ++ prverscheck = pyroute2.__version__.split(".") ++ if int(prverscheck[0]) == 0 and int(prverscheck[1]) < 6: ++ print("Need to upgrade the python pyroute2 package to >= 0.6.") ++ sys.exit(0) ++ + parser = argparse.ArgumentParser() + parser.add_argument( + "-v", +diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh +index bb34329e02a7f..5267c88496d51 100755 +--- a/tools/testing/selftests/netfilter/nft_audit.sh ++++ b/tools/testing/selftests/netfilter/nft_audit.sh +@@ -11,6 +11,12 @@ nft --version >/dev/null 2>&1 || { + exit $SKIP_RC + } + ++# Run everything in a separate network namespace ++[ "${1}" != "run" ] && { unshare -n "${0}" run; exit $?; } ++ ++# give other scripts a chance to finish - audit_logread sees all activity ++sleep 1 ++ + logfile=$(mktemp) + rulefile=$(mktemp) + echo "logging into $logfile" -- cgit v1.2.3-65-gdbad