diff options
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1059_linux-6.1.60.patch | 7686 |
2 files changed, 7690 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 2db06d5c..a3b5d2f0 100644 --- a/0000_README +++ b/0000_README @@ -279,6 +279,10 @@ Patch: 1058_linux-6.1.59.patch From: https://www.kernel.org Desc: Linux 6.1.59 +Patch: 1059_linux-6.1.60.patch +From: https://www.kernel.org +Desc: Linux 6.1.60 + 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/1059_linux-6.1.60.patch b/1059_linux-6.1.60.patch new file mode 100644 index 00000000..512a62e4 --- /dev/null +++ b/1059_linux-6.1.60.patch @@ -0,0 +1,7686 @@ +diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +index a96f143479c79..eb0e9cca70570 100644 +--- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml ++++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +@@ -59,7 +59,7 @@ properties: + maxItems: 4 + + clocks: +- minItems: 3 ++ minItems: 2 + items: + - description: Main peripheral bus clock, PCLK/HCLK - AHB Bus clock + - description: SDC MMC clock, MCLK +diff --git a/Makefile b/Makefile +index 4ad29c852e5f8..d47edcd8888e8 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 1 +-SUBLEVEL = 59 ++SUBLEVEL = 60 + EXTRAVERSION = + NAME = Curry Ramen + +diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi +index d69f0f4b4990d..d2d516d113baa 100644 +--- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi ++++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi +@@ -640,6 +640,7 @@ + &uart3 { + interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core 0x17c>; ++ overrun-throttle-ms = <500>; + }; + + &uart4 { +diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c +index 227cf0a62800b..486aa03abbe17 100644 +--- a/arch/s390/pci/pci_dma.c ++++ b/arch/s390/pci/pci_dma.c +@@ -544,6 +544,17 @@ static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg, + s->dma_length = 0; + } + } ++ ++static unsigned long *bitmap_vzalloc(size_t bits, gfp_t flags) ++{ ++ size_t n = BITS_TO_LONGS(bits); ++ size_t bytes; ++ ++ if (unlikely(check_mul_overflow(n, sizeof(unsigned long), &bytes))) ++ return NULL; ++ ++ return vzalloc(bytes); ++} + + int zpci_dma_init_device(struct zpci_dev *zdev) + { +@@ -584,13 +595,13 @@ int zpci_dma_init_device(struct zpci_dev *zdev) + zdev->end_dma - zdev->start_dma + 1); + zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1; + zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; +- zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); ++ zdev->iommu_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL); + if (!zdev->iommu_bitmap) { + rc = -ENOMEM; + goto free_dma_table; + } + if (!s390_iommu_strict) { +- zdev->lazy_bitmap = vzalloc(zdev->iommu_pages / 8); ++ zdev->lazy_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL); + if (!zdev->lazy_bitmap) { + rc = -ENOMEM; + goto free_bitmap; +diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c +index e65f0968e0d9d..9c91cc40f4565 100644 +--- a/arch/x86/boot/compressed/sev.c ++++ b/arch/x86/boot/compressed/sev.c +@@ -103,6 +103,16 @@ static enum es_result vc_read_mem(struct es_em_ctxt *ctxt, + return ES_OK; + } + ++static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size) ++{ ++ return ES_OK; ++} ++ ++static bool fault_in_kernel_space(unsigned long address) ++{ ++ return false; ++} ++ + #undef __init + #undef __pa + #define __init +diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h +index b475d9a582b88..e829fa4c6788e 100644 +--- a/arch/x86/include/asm/fpu/api.h ++++ b/arch/x86/include/asm/fpu/api.h +@@ -148,7 +148,8 @@ static inline void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd) { + static inline void fpu_sync_guest_vmexit_xfd_state(void) { } + #endif + +-extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, unsigned int size, u32 pkru); ++extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, ++ unsigned int size, u64 xfeatures, u32 pkru); + extern int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf, u64 xcr0, u32 *vpkru); + + static inline void fpstate_set_confidential(struct fpu_guest *gfpu) +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 08a84f801bfea..c1dcaa3d2d6eb 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -1324,7 +1324,6 @@ struct kvm_arch { + * the thread holds the MMU lock in write mode. + */ + spinlock_t tdp_mmu_pages_lock; +- struct workqueue_struct *tdp_mmu_zap_wq; + #endif /* CONFIG_X86_64 */ + + /* +@@ -1727,7 +1726,7 @@ void kvm_mmu_vendor_module_exit(void); + + void kvm_mmu_destroy(struct kvm_vcpu *vcpu); + int kvm_mmu_create(struct kvm_vcpu *vcpu); +-int kvm_mmu_init_vm(struct kvm *kvm); ++void kvm_mmu_init_vm(struct kvm *kvm); + void kvm_mmu_uninit_vm(struct kvm *kvm); + + void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu); +diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h +index 02aac78cb21d4..184fd776cd39f 100644 +--- a/arch/x86/include/asm/svm.h ++++ b/arch/x86/include/asm/svm.h +@@ -259,6 +259,7 @@ enum avic_ipi_failure_cause { + AVIC_IPI_FAILURE_TARGET_NOT_RUNNING, + AVIC_IPI_FAILURE_INVALID_TARGET, + AVIC_IPI_FAILURE_INVALID_BACKING_PAGE, ++ AVIC_IPI_FAILURE_INVALID_IPI_VECTOR, + }; + + #define AVIC_PHYSICAL_MAX_INDEX_MASK GENMASK_ULL(8, 0) +diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c +index a083f9ac9e4f6..1d190761d00fd 100644 +--- a/arch/x86/kernel/fpu/core.c ++++ b/arch/x86/kernel/fpu/core.c +@@ -369,14 +369,15 @@ int fpu_swap_kvm_fpstate(struct fpu_guest *guest_fpu, bool enter_guest) + EXPORT_SYMBOL_GPL(fpu_swap_kvm_fpstate); + + void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, +- unsigned int size, u32 pkru) ++ unsigned int size, u64 xfeatures, u32 pkru) + { + struct fpstate *kstate = gfpu->fpstate; + union fpregs_state *ustate = buf; + struct membuf mb = { .p = buf, .left = size }; + + if (cpu_feature_enabled(X86_FEATURE_XSAVE)) { +- __copy_xstate_to_uabi_buf(mb, kstate, pkru, XSTATE_COPY_XSAVE); ++ __copy_xstate_to_uabi_buf(mb, kstate, xfeatures, pkru, ++ XSTATE_COPY_XSAVE); + } else { + memcpy(&ustate->fxsave, &kstate->regs.fxsave, + sizeof(ustate->fxsave)); +diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c +index 1afbc4866b100..ebe698f8af73b 100644 +--- a/arch/x86/kernel/fpu/xstate.c ++++ b/arch/x86/kernel/fpu/xstate.c +@@ -1053,6 +1053,7 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, + * __copy_xstate_to_uabi_buf - Copy kernel saved xstate to a UABI buffer + * @to: membuf descriptor + * @fpstate: The fpstate buffer from which to copy ++ * @xfeatures: The mask of xfeatures to save (XSAVE mode only) + * @pkru_val: The PKRU value to store in the PKRU component + * @copy_mode: The requested copy mode + * +@@ -1063,7 +1064,8 @@ static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, + * It supports partial copy but @to.pos always starts from zero. + */ + void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, +- u32 pkru_val, enum xstate_copy_mode copy_mode) ++ u64 xfeatures, u32 pkru_val, ++ enum xstate_copy_mode copy_mode) + { + const unsigned int off_mxcsr = offsetof(struct fxregs_state, mxcsr); + struct xregs_state *xinit = &init_fpstate.regs.xsave; +@@ -1087,7 +1089,7 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, + break; + + case XSTATE_COPY_XSAVE: +- header.xfeatures &= fpstate->user_xfeatures; ++ header.xfeatures &= fpstate->user_xfeatures & xfeatures; + break; + } + +@@ -1189,6 +1191,7 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, + enum xstate_copy_mode copy_mode) + { + __copy_xstate_to_uabi_buf(to, tsk->thread.fpu.fpstate, ++ tsk->thread.fpu.fpstate->user_xfeatures, + tsk->thread.pkru, copy_mode); + } + +@@ -1540,10 +1543,7 @@ static int fpstate_realloc(u64 xfeatures, unsigned int ksize, + fpregs_restore_userregs(); + + newfps->xfeatures = curfps->xfeatures | xfeatures; +- +- if (!guest_fpu) +- newfps->user_xfeatures = curfps->user_xfeatures | xfeatures; +- ++ newfps->user_xfeatures = curfps->user_xfeatures | xfeatures; + newfps->xfd = curfps->xfd & ~xfeatures; + + /* Do the final updates within the locked region */ +diff --git a/arch/x86/kernel/fpu/xstate.h b/arch/x86/kernel/fpu/xstate.h +index a4ecb04d8d646..3518fb26d06b0 100644 +--- a/arch/x86/kernel/fpu/xstate.h ++++ b/arch/x86/kernel/fpu/xstate.h +@@ -43,7 +43,8 @@ enum xstate_copy_mode { + + struct membuf; + extern void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, +- u32 pkru_val, enum xstate_copy_mode copy_mode); ++ u64 xfeatures, u32 pkru_val, ++ enum xstate_copy_mode copy_mode); + extern void copy_xstate_to_uabi_buf(struct membuf to, struct task_struct *tsk, + enum xstate_copy_mode mode); + extern int copy_uabi_from_kernel_to_xstate(struct fpstate *fpstate, const void *kbuf, u32 *pkru); +diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c +index 7dce812ce2538..71d8698702ce3 100644 +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -629,6 +629,23 @@ fail: + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); + } + ++static enum es_result vc_insn_string_check(struct es_em_ctxt *ctxt, ++ unsigned long address, ++ bool write) ++{ ++ if (user_mode(ctxt->regs) && fault_in_kernel_space(address)) { ++ ctxt->fi.vector = X86_TRAP_PF; ++ ctxt->fi.error_code = X86_PF_USER; ++ ctxt->fi.cr2 = address; ++ if (write) ++ ctxt->fi.error_code |= X86_PF_WRITE; ++ ++ return ES_EXCEPTION; ++ } ++ ++ return ES_OK; ++} ++ + static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, + void *src, char *buf, + unsigned int data_size, +@@ -636,7 +653,12 @@ static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, + bool backwards) + { + int i, b = backwards ? -1 : 1; +- enum es_result ret = ES_OK; ++ unsigned long address = (unsigned long)src; ++ enum es_result ret; ++ ++ ret = vc_insn_string_check(ctxt, address, false); ++ if (ret != ES_OK) ++ return ret; + + for (i = 0; i < count; i++) { + void *s = src + (i * data_size * b); +@@ -657,7 +679,12 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt, + bool backwards) + { + int i, s = backwards ? -1 : 1; +- enum es_result ret = ES_OK; ++ unsigned long address = (unsigned long)dst; ++ enum es_result ret; ++ ++ ret = vc_insn_string_check(ctxt, address, true); ++ if (ret != ES_OK) ++ return ret; + + for (i = 0; i < count; i++) { + void *d = dst + (i * data_size * s); +@@ -693,6 +720,9 @@ static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt, + static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + { + struct insn *insn = &ctxt->insn; ++ size_t size; ++ u64 port; ++ + *exitinfo = 0; + + switch (insn->opcode.bytes[0]) { +@@ -701,7 +731,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + case 0x6d: + *exitinfo |= IOIO_TYPE_INS; + *exitinfo |= IOIO_SEG_ES; +- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; ++ port = ctxt->regs->dx & 0xffff; + break; + + /* OUTS opcodes */ +@@ -709,41 +739,43 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + case 0x6f: + *exitinfo |= IOIO_TYPE_OUTS; + *exitinfo |= IOIO_SEG_DS; +- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; ++ port = ctxt->regs->dx & 0xffff; + break; + + /* IN immediate opcodes */ + case 0xe4: + case 0xe5: + *exitinfo |= IOIO_TYPE_IN; +- *exitinfo |= (u8)insn->immediate.value << 16; ++ port = (u8)insn->immediate.value & 0xffff; + break; + + /* OUT immediate opcodes */ + case 0xe6: + case 0xe7: + *exitinfo |= IOIO_TYPE_OUT; +- *exitinfo |= (u8)insn->immediate.value << 16; ++ port = (u8)insn->immediate.value & 0xffff; + break; + + /* IN register opcodes */ + case 0xec: + case 0xed: + *exitinfo |= IOIO_TYPE_IN; +- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; ++ port = ctxt->regs->dx & 0xffff; + break; + + /* OUT register opcodes */ + case 0xee: + case 0xef: + *exitinfo |= IOIO_TYPE_OUT; +- *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; ++ port = ctxt->regs->dx & 0xffff; + break; + + default: + return ES_DECODE_FAILED; + } + ++ *exitinfo |= port << 16; ++ + switch (insn->opcode.bytes[0]) { + case 0x6c: + case 0x6e: +@@ -753,12 +785,15 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + case 0xee: + /* Single byte opcodes */ + *exitinfo |= IOIO_DATA_8; ++ size = 1; + break; + default: + /* Length determined by instruction parsing */ + *exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16 + : IOIO_DATA_32; ++ size = (insn->opnd_bytes == 2) ? 2 : 4; + } ++ + switch (insn->addr_bytes) { + case 2: + *exitinfo |= IOIO_ADDR_16; +@@ -774,7 +809,7 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) + if (insn_has_rep_prefix(insn)) + *exitinfo |= IOIO_REP; + +- return ES_OK; ++ return vc_ioio_check(ctxt, (u16)port, size); + } + + static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) +diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c +index afda719dd7253..e7968c41ecf57 100644 +--- a/arch/x86/kernel/sev.c ++++ b/arch/x86/kernel/sev.c +@@ -512,6 +512,33 @@ static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt + return ES_OK; + } + ++static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size) ++{ ++ BUG_ON(size > 4); ++ ++ if (user_mode(ctxt->regs)) { ++ struct thread_struct *t = ¤t->thread; ++ struct io_bitmap *iobm = t->io_bitmap; ++ size_t idx; ++ ++ if (!iobm) ++ goto fault; ++ ++ for (idx = port; idx < port + size; ++idx) { ++ if (test_bit(idx, iobm->bitmap)) ++ goto fault; ++ } ++ } ++ ++ return ES_OK; ++ ++fault: ++ ctxt->fi.vector = X86_TRAP_GP; ++ ctxt->fi.error_code = 0; ++ ++ return ES_EXCEPTION; ++} ++ + /* Include code shared with pre-decompression boot stage */ + #include "sev-shared.c" + +@@ -1552,6 +1579,9 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) + return ES_DECODE_FAILED; + } + ++ if (user_mode(ctxt->regs)) ++ return ES_UNSUPPORTED; ++ + switch (mmio) { + case MMIO_WRITE: + memcpy(ghcb->shared_buffer, reg_data, bytes); +diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c +index 7b4224f5ee2de..c3ef1fc602bf9 100644 +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -338,14 +338,6 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) + vcpu->arch.guest_supported_xcr0 = + cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent); + +- /* +- * FP+SSE can always be saved/restored via KVM_{G,S}ET_XSAVE, even if +- * XSAVE/XCRO are not exposed to the guest, and even if XSAVE isn't +- * supported by the host. +- */ +- vcpu->arch.guest_fpu.fpstate->user_xfeatures = vcpu->arch.guest_supported_xcr0 | +- XFEATURE_MASK_FPSSE; +- + kvm_update_pv_runtime(vcpu); + + vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index 68eba393842f5..7e8dbd54869a6 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -2535,13 +2535,17 @@ int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type) + { + u32 reg = kvm_lapic_get_reg(apic, lvt_type); + int vector, mode, trig_mode; ++ int r; + + if (kvm_apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) { + vector = reg & APIC_VECTOR_MASK; + mode = reg & APIC_MODE_MASK; + trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; +- return __apic_accept_irq(apic, mode, vector, 1, trig_mode, +- NULL); ++ ++ r = __apic_accept_irq(apic, mode, vector, 1, trig_mode, NULL); ++ if (r && lvt_type == APIC_LVTPC) ++ kvm_lapic_set_reg(apic, APIC_LVTPC, reg | APIC_LVT_MASKED); ++ return r; + } + return 0; + } +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index 2a6fec4e2d196..d30325e297a03 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -5994,19 +5994,16 @@ static void kvm_mmu_invalidate_zap_pages_in_memslot(struct kvm *kvm, + kvm_mmu_zap_all_fast(kvm); + } + +-int kvm_mmu_init_vm(struct kvm *kvm) ++void kvm_mmu_init_vm(struct kvm *kvm) + { + struct kvm_page_track_notifier_node *node = &kvm->arch.mmu_sp_tracker; +- int r; + + INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); + INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); + INIT_LIST_HEAD(&kvm->arch.lpage_disallowed_mmu_pages); + spin_lock_init(&kvm->arch.mmu_unsync_pages_lock); + +- r = kvm_mmu_init_tdp_mmu(kvm); +- if (r < 0) +- return r; ++ kvm_mmu_init_tdp_mmu(kvm); + + node->track_write = kvm_mmu_pte_write; + node->track_flush_slot = kvm_mmu_invalidate_zap_pages_in_memslot; +@@ -6019,8 +6016,6 @@ int kvm_mmu_init_vm(struct kvm *kvm) + + kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache; + kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO; +- +- return 0; + } + + static void mmu_free_vm_memory_caches(struct kvm *kvm) +diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h +index 582def531d4d9..0a9d5f2925c33 100644 +--- a/arch/x86/kvm/mmu/mmu_internal.h ++++ b/arch/x86/kvm/mmu/mmu_internal.h +@@ -56,7 +56,12 @@ struct kvm_mmu_page { + + bool tdp_mmu_page; + bool unsync; +- u8 mmu_valid_gen; ++ union { ++ u8 mmu_valid_gen; ++ ++ /* Only accessed under slots_lock. */ ++ bool tdp_mmu_scheduled_root_to_zap; ++ }; + bool lpage_disallowed; /* Can't be replaced by an equiv large page */ + + /* +@@ -92,13 +97,7 @@ struct kvm_mmu_page { + struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */ + tdp_ptep_t ptep; + }; +- union { +- DECLARE_BITMAP(unsync_child_bitmap, 512); +- struct { +- struct work_struct tdp_mmu_async_work; +- void *tdp_mmu_async_data; +- }; +- }; ++ DECLARE_BITMAP(unsync_child_bitmap, 512); + + struct list_head lpage_disallowed_link; + #ifdef CONFIG_X86_32 +diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c +index 9b9fc4e834d09..c3b0f973375b4 100644 +--- a/arch/x86/kvm/mmu/tdp_mmu.c ++++ b/arch/x86/kvm/mmu/tdp_mmu.c +@@ -14,24 +14,16 @@ static bool __read_mostly tdp_mmu_enabled = true; + module_param_named(tdp_mmu, tdp_mmu_enabled, bool, 0644); + + /* Initializes the TDP MMU for the VM, if enabled. */ +-int kvm_mmu_init_tdp_mmu(struct kvm *kvm) ++void kvm_mmu_init_tdp_mmu(struct kvm *kvm) + { +- struct workqueue_struct *wq; +- + if (!tdp_enabled || !READ_ONCE(tdp_mmu_enabled)) +- return 0; +- +- wq = alloc_workqueue("kvm", WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_CPU_INTENSIVE, 0); +- if (!wq) +- return -ENOMEM; ++ return; + + /* This should not be changed for the lifetime of the VM. */ + kvm->arch.tdp_mmu_enabled = true; + INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots); + spin_lock_init(&kvm->arch.tdp_mmu_pages_lock); + INIT_LIST_HEAD(&kvm->arch.tdp_mmu_pages); +- kvm->arch.tdp_mmu_zap_wq = wq; +- return 1; + } + + /* Arbitrarily returns true so that this may be used in if statements. */ +@@ -57,20 +49,15 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) + * ultimately frees all roots. + */ + kvm_tdp_mmu_invalidate_all_roots(kvm); +- +- /* +- * Destroying a workqueue also first flushes the workqueue, i.e. no +- * need to invoke kvm_tdp_mmu_zap_invalidated_roots(). +- */ +- destroy_workqueue(kvm->arch.tdp_mmu_zap_wq); ++ kvm_tdp_mmu_zap_invalidated_roots(kvm); + + WARN_ON(!list_empty(&kvm->arch.tdp_mmu_pages)); + WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); + + /* + * Ensure that all the outstanding RCU callbacks to free shadow pages +- * can run before the VM is torn down. Work items on tdp_mmu_zap_wq +- * can call kvm_tdp_mmu_put_root and create new callbacks. ++ * can run before the VM is torn down. Putting the last reference to ++ * zapped roots will create new callbacks. + */ + rcu_barrier(); + } +@@ -97,46 +84,6 @@ static void tdp_mmu_free_sp_rcu_callback(struct rcu_head *head) + tdp_mmu_free_sp(sp); + } + +-static void tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root, +- bool shared); +- +-static void tdp_mmu_zap_root_work(struct work_struct *work) +-{ +- struct kvm_mmu_page *root = container_of(work, struct kvm_mmu_page, +- tdp_mmu_async_work); +- struct kvm *kvm = root->tdp_mmu_async_data; +- +- read_lock(&kvm->mmu_lock); +- +- /* +- * A TLB flush is not necessary as KVM performs a local TLB flush when +- * allocating a new root (see kvm_mmu_load()), and when migrating vCPU +- * to a different pCPU. Note, the local TLB flush on reuse also +- * invalidates any paging-structure-cache entries, i.e. TLB entries for +- * intermediate paging structures, that may be zapped, as such entries +- * are associated with the ASID on both VMX and SVM. +- */ +- tdp_mmu_zap_root(kvm, root, true); +- +- /* +- * Drop the refcount using kvm_tdp_mmu_put_root() to test its logic for +- * avoiding an infinite loop. By design, the root is reachable while +- * it's being asynchronously zapped, thus a different task can put its +- * last reference, i.e. flowing through kvm_tdp_mmu_put_root() for an +- * asynchronously zapped root is unavoidable. +- */ +- kvm_tdp_mmu_put_root(kvm, root, true); +- +- read_unlock(&kvm->mmu_lock); +-} +- +-static void tdp_mmu_schedule_zap_root(struct kvm *kvm, struct kvm_mmu_page *root) +-{ +- root->tdp_mmu_async_data = kvm; +- INIT_WORK(&root->tdp_mmu_async_work, tdp_mmu_zap_root_work); +- queue_work(kvm->arch.tdp_mmu_zap_wq, &root->tdp_mmu_async_work); +-} +- + void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, + bool shared) + { +@@ -222,11 +169,11 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, + #define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \ + __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true) + +-#define for_each_tdp_mmu_root_yield_safe(_kvm, _root) \ +- for (_root = tdp_mmu_next_root(_kvm, NULL, false, false); \ ++#define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _shared) \ ++ for (_root = tdp_mmu_next_root(_kvm, NULL, _shared, false); \ + _root; \ +- _root = tdp_mmu_next_root(_kvm, _root, false, false)) \ +- if (!kvm_lockdep_assert_mmu_lock_held(_kvm, false)) { \ ++ _root = tdp_mmu_next_root(_kvm, _root, _shared, false)) \ ++ if (!kvm_lockdep_assert_mmu_lock_held(_kvm, _shared)) { \ + } else + + /* +@@ -305,7 +252,7 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu) + * by a memslot update or by the destruction of the VM. Initialize the + * refcount to two; one reference for the vCPU, and one reference for + * the TDP MMU itself, which is held until the root is invalidated and +- * is ultimately put by tdp_mmu_zap_root_work(). ++ * is ultimately put by kvm_tdp_mmu_zap_invalidated_roots(). + */ + refcount_set(&root->tdp_mmu_root_count, 2); + +@@ -963,7 +910,7 @@ bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush) + { + struct kvm_mmu_page *root; + +- for_each_tdp_mmu_root_yield_safe(kvm, root) ++ for_each_tdp_mmu_root_yield_safe(kvm, root, false) + flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush); + + return flush; +@@ -985,7 +932,7 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) + * is being destroyed or the userspace VMM has exited. In both cases, + * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request. + */ +- for_each_tdp_mmu_root_yield_safe(kvm, root) ++ for_each_tdp_mmu_root_yield_safe(kvm, root, false) + tdp_mmu_zap_root(kvm, root, false); + } + +@@ -995,18 +942,47 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) + */ + void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm) + { +- flush_workqueue(kvm->arch.tdp_mmu_zap_wq); ++ struct kvm_mmu_page *root; ++ ++ read_lock(&kvm->mmu_lock); ++ ++ for_each_tdp_mmu_root_yield_safe(kvm, root, true) { ++ if (!root->tdp_mmu_scheduled_root_to_zap) ++ continue; ++ ++ root->tdp_mmu_scheduled_root_to_zap = false; ++ KVM_BUG_ON(!root->role.invalid, kvm); ++ ++ /* ++ * A TLB flush is not necessary as KVM performs a local TLB ++ * flush when allocating a new root (see kvm_mmu_load()), and ++ * when migrating a vCPU to a different pCPU. Note, the local ++ * TLB flush on reuse also invalidates paging-structure-cache ++ * entries, i.e. TLB entries for intermediate paging structures, ++ * that may be zapped, as such entries are associated with the ++ * ASID on both VMX and SVM. ++ */ ++ tdp_mmu_zap_root(kvm, root, true); ++ ++ /* ++ * The referenced needs to be put *after* zapping the root, as ++ * the root must be reachable by mmu_notifiers while it's being ++ * zapped ++ */ ++ kvm_tdp_mmu_put_root(kvm, root, true); ++ } ++ ++ read_unlock(&kvm->mmu_lock); + } + + /* + * Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that + * is about to be zapped, e.g. in response to a memslots update. The actual +- * zapping is performed asynchronously. Using a separate workqueue makes it +- * easy to ensure that the destruction is performed before the "fast zap" +- * completes, without keeping a separate list of invalidated roots; the list is +- * effectively the list of work items in the workqueue. ++ * zapping is done separately so that it happens with mmu_lock with read, ++ * whereas invalidating roots must be done with mmu_lock held for write (unless ++ * the VM is being destroyed). + * +- * Note, the asynchronous worker is gifted the TDP MMU's reference. ++ * Note, kvm_tdp_mmu_zap_invalidated_roots() is gifted the TDP MMU's reference. + * See kvm_tdp_mmu_get_vcpu_root_hpa(). + */ + void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) +@@ -1031,19 +1007,20 @@ void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) + /* + * As above, mmu_lock isn't held when destroying the VM! There can't + * be other references to @kvm, i.e. nothing else can invalidate roots +- * or be consuming roots, but walking the list of roots does need to be +- * guarded against roots being deleted by the asynchronous zap worker. ++ * or get/put references to roots. + */ +- rcu_read_lock(); +- +- list_for_each_entry_rcu(root, &kvm->arch.tdp_mmu_roots, link) { ++ list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) { ++ /* ++ * Note, invalid roots can outlive a memslot update! Invalid ++ * roots must be *zapped* before the memslot update completes, ++ * but a different task can acquire a reference and keep the ++ * root alive after its been zapped. ++ */ + if (!root->role.invalid) { ++ root->tdp_mmu_scheduled_root_to_zap = true; + root->role.invalid = true; +- tdp_mmu_schedule_zap_root(kvm, root); + } + } +- +- rcu_read_unlock(); + } + + /* +diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h +index d0a9fe0770fdd..c82a8bb321bb9 100644 +--- a/arch/x86/kvm/mmu/tdp_mmu.h ++++ b/arch/x86/kvm/mmu/tdp_mmu.h +@@ -65,7 +65,7 @@ u64 *kvm_tdp_mmu_fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, u64 addr, + u64 *spte); + + #ifdef CONFIG_X86_64 +-int kvm_mmu_init_tdp_mmu(struct kvm *kvm); ++void kvm_mmu_init_tdp_mmu(struct kvm *kvm); + void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm); + static inline bool is_tdp_mmu_page(struct kvm_mmu_page *sp) { return sp->tdp_mmu_page; } + +@@ -86,7 +86,7 @@ static inline bool is_tdp_mmu(struct kvm_mmu *mmu) + return sp && is_tdp_mmu_page(sp) && sp->root_count; + } + #else +-static inline int kvm_mmu_init_tdp_mmu(struct kvm *kvm) { return 0; } ++static inline void kvm_mmu_init_tdp_mmu(struct kvm *kvm) {} + static inline void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) {} + static inline bool is_tdp_mmu_page(struct kvm_mmu_page *sp) { return false; } + static inline bool is_tdp_mmu(struct kvm_mmu *mmu) { return false; } +diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c +index d3e66740c7c68..fb125b54ee680 100644 +--- a/arch/x86/kvm/svm/avic.c ++++ b/arch/x86/kvm/svm/avic.c +@@ -542,8 +542,11 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu) + case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE: + WARN_ONCE(1, "Invalid backing page\n"); + break; ++ case AVIC_IPI_FAILURE_INVALID_IPI_VECTOR: ++ /* Invalid IPI with vector < 16 */ ++ break; + default: +- pr_err("Unknown IPI interception\n"); ++ vcpu_unimpl(vcpu, "Unknown avic incomplete IPI interception\n"); + } + + return 1; +diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c +index 8053974af326c..bc288e6bde642 100644 +--- a/arch/x86/kvm/svm/nested.c ++++ b/arch/x86/kvm/svm/nested.c +@@ -1164,6 +1164,9 @@ void svm_leave_nested(struct kvm_vcpu *vcpu) + + nested_svm_uninit_mmu_context(vcpu); + vmcb_mark_all_dirty(svm->vmcb); ++ ++ if (kvm_apicv_activated(vcpu->kvm)) ++ kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu); + } + + kvm_clear_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu); +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 1931d3fcbbe09..4d6baae1ae748 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -5301,26 +5301,37 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, + return 0; + } + +-static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, +- struct kvm_xsave *guest_xsave) +-{ +- if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) +- return; +- +- fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, +- guest_xsave->region, +- sizeof(guest_xsave->region), +- vcpu->arch.pkru); +-} + + static void kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu, + u8 *state, unsigned int size) + { ++ /* ++ * Only copy state for features that are enabled for the guest. The ++ * state itself isn't problematic, but setting bits in the header for ++ * features that are supported in *this* host but not exposed to the ++ * guest can result in KVM_SET_XSAVE failing when live migrating to a ++ * compatible host without the features that are NOT exposed to the ++ * guest. ++ * ++ * FP+SSE can always be saved/restored via KVM_{G,S}ET_XSAVE, even if ++ * XSAVE/XCRO are not exposed to the guest, and even if XSAVE isn't ++ * supported by the host. ++ */ ++ u64 supported_xcr0 = vcpu->arch.guest_supported_xcr0 | ++ XFEATURE_MASK_FPSSE; ++ + if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) + return; + +- fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, +- state, size, vcpu->arch.pkru); ++ fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, state, size, ++ supported_xcr0, vcpu->arch.pkru); ++} ++ ++static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, ++ struct kvm_xsave *guest_xsave) ++{ ++ return kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region, ++ sizeof(guest_xsave->region)); + } + + static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, +@@ -12442,9 +12453,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) + if (ret) + goto out; + +- ret = kvm_mmu_init_vm(kvm); +- if (ret) +- goto out_page_track; ++ kvm_mmu_init_vm(kvm); + + ret = static_call(kvm_x86_vm_init)(kvm); + if (ret) +@@ -12489,7 +12498,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) + + out_uninit_mmu: + kvm_mmu_uninit_vm(kvm); +-out_page_track: + kvm_page_track_cleanup(kvm); + out: + return ret; +diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c +index c2c786eb95abc..1687483ff319e 100644 +--- a/drivers/acpi/irq.c ++++ b/drivers/acpi/irq.c +@@ -57,6 +57,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, + int polarity) + { + struct irq_fwspec fwspec; ++ unsigned int irq; + + fwspec.fwnode = acpi_get_gsi_domain_id(gsi); + if (WARN_ON(!fwspec.fwnode)) { +@@ -68,7 +69,11 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, + fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); + fwspec.param_count = 2; + +- return irq_create_fwspec_mapping(&fwspec); ++ irq = irq_create_fwspec_mapping(&fwspec); ++ if (!irq) ++ return -EINVAL; ++ ++ return irq; + } + EXPORT_SYMBOL_GPL(acpi_register_gsi); + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index fbc231a3f7951..fa2fc1953fc26 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -2456,7 +2456,7 @@ static int ata_dev_config_lba(struct ata_device *dev) + { + const u16 *id = dev->id; + const char *lba_desc; +- char ncq_desc[24]; ++ char ncq_desc[32]; + int ret; + + dev->flags |= ATA_DFLAG_LBA; +diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c +index 2a04dd36a4948..1eaaf01418ea7 100644 +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2247,7 +2247,7 @@ static void ata_eh_link_report(struct ata_link *link) + struct ata_eh_context *ehc = &link->eh_context; + struct ata_queued_cmd *qc; + const char *frozen, *desc; +- char tries_buf[6] = ""; ++ char tries_buf[16] = ""; + int tag, nr_failed = 0; + + if (ehc->i.flags & ATA_EHI_QUIET) +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index 7de1f27d0323d..df1f78abdf266 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -1572,7 +1572,7 @@ static int dev_get_regmap_match(struct device *dev, void *res, void *data) + + /* If the user didn't specify a name match any */ + if (data) +- return !strcmp((*r)->name, data); ++ return (*r)->name && !strcmp((*r)->name, data); + else + return 1; + } +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index f2062c2a28da8..96d4f48e36011 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -3984,6 +3984,7 @@ static int btusb_probe(struct usb_interface *intf, + + if (id->driver_info & BTUSB_QCA_ROME) { + data->setup_on_usb = btusb_setup_qca; ++ hdev->shutdown = btusb_shutdown_qca; + hdev->set_bdaddr = btusb_set_bdaddr_ath3012; + hdev->cmd_timeout = btusb_qca_cmd_timeout; + set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); +diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c +index c443c3b0a4da5..4415d850d698b 100644 +--- a/drivers/bluetooth/hci_vhci.c ++++ b/drivers/bluetooth/hci_vhci.c +@@ -74,7 +74,10 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) + struct vhci_data *data = hci_get_drvdata(hdev); + + memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); ++ ++ mutex_lock(&data->open_mutex); + skb_queue_tail(&data->readq, skb); ++ mutex_unlock(&data->open_mutex); + + wake_up_interruptible(&data->read_wait); + return 0; +diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c +index de14949a3fe5a..92c1f2baa4bff 100644 +--- a/drivers/gpio/gpio-timberdale.c ++++ b/drivers/gpio/gpio-timberdale.c +@@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, + unsigned offset, bool enabled) + { + struct timbgpio *tgpio = gpiochip_get_data(gpio); ++ unsigned long flags; + u32 reg; + +- spin_lock(&tgpio->lock); ++ spin_lock_irqsave(&tgpio->lock, flags); + reg = ioread32(tgpio->membase + offset); + + if (enabled) +@@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, + reg &= ~(1 << index); + + iowrite32(reg, tgpio->membase + offset); +- spin_unlock(&tgpio->lock); ++ spin_unlock_irqrestore(&tgpio->lock, flags); + + return 0; + } +diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c +index a429176673e7a..314dfaa633857 100644 +--- a/drivers/gpio/gpio-vf610.c ++++ b/drivers/gpio/gpio-vf610.c +@@ -30,7 +30,6 @@ struct fsl_gpio_soc_data { + + struct vf610_gpio_port { + struct gpio_chip gc; +- struct irq_chip ic; + void __iomem *base; + void __iomem *gpio_base; + const struct fsl_gpio_soc_data *sdata; +@@ -128,14 +127,14 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, + unsigned long mask = BIT(gpio); + u32 val; + ++ vf610_gpio_set(chip, gpio, value); ++ + if (port->sdata && port->sdata->have_paddr) { + val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR); + val |= mask; + vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR); + } + +- vf610_gpio_set(chip, gpio, value); +- + return pinctrl_gpio_direction_output(chip->base + gpio); + } + +@@ -207,20 +206,24 @@ static int vf610_gpio_irq_set_type(struct irq_data *d, u32 type) + + static void vf610_gpio_irq_mask(struct irq_data *d) + { +- struct vf610_gpio_port *port = +- gpiochip_get_data(irq_data_get_irq_chip_data(d)); +- void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq); ++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); ++ struct vf610_gpio_port *port = gpiochip_get_data(gc); ++ irq_hw_number_t gpio_num = irqd_to_hwirq(d); ++ void __iomem *pcr_base = port->base + PORT_PCR(gpio_num); + + vf610_gpio_writel(0, pcr_base); ++ gpiochip_disable_irq(gc, gpio_num); + } + + static void vf610_gpio_irq_unmask(struct irq_data *d) + { +- struct vf610_gpio_port *port = +- gpiochip_get_data(irq_data_get_irq_chip_data(d)); +- void __iomem *pcr_base = port->base + PORT_PCR(d->hwirq); ++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); ++ struct vf610_gpio_port *port = gpiochip_get_data(gc); ++ irq_hw_number_t gpio_num = irqd_to_hwirq(d); ++ void __iomem *pcr_base = port->base + PORT_PCR(gpio_num); + +- vf610_gpio_writel(port->irqc[d->hwirq] << PORT_PCR_IRQC_OFFSET, ++ gpiochip_enable_irq(gc, gpio_num); ++ vf610_gpio_writel(port->irqc[gpio_num] << PORT_PCR_IRQC_OFFSET, + pcr_base); + } + +@@ -237,6 +240,18 @@ static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable) + return 0; + } + ++static const struct irq_chip vf610_irqchip = { ++ .name = "gpio-vf610", ++ .irq_ack = vf610_gpio_irq_ack, ++ .irq_mask = vf610_gpio_irq_mask, ++ .irq_unmask = vf610_gpio_irq_unmask, ++ .irq_set_type = vf610_gpio_irq_set_type, ++ .irq_set_wake = vf610_gpio_irq_set_wake, ++ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND ++ | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND, ++ GPIOCHIP_IRQ_RESOURCE_HELPERS, ++}; ++ + static void vf610_gpio_disable_clk(void *data) + { + clk_disable_unprepare(data); +@@ -249,7 +264,6 @@ static int vf610_gpio_probe(struct platform_device *pdev) + struct vf610_gpio_port *port; + struct gpio_chip *gc; + struct gpio_irq_chip *girq; +- struct irq_chip *ic; + int i; + int ret; + +@@ -315,14 +329,6 @@ static int vf610_gpio_probe(struct platform_device *pdev) + gc->direction_output = vf610_gpio_direction_output; + gc->set = vf610_gpio_set; + +- ic = &port->ic; +- ic->name = "gpio-vf610"; +- ic->irq_ack = vf610_gpio_irq_ack; +- ic->irq_mask = vf610_gpio_irq_mask; +- ic->irq_unmask = vf610_gpio_irq_unmask; +- ic->irq_set_type = vf610_gpio_irq_set_type; +- ic->irq_set_wake = vf610_gpio_irq_set_wake; +- + /* Mask all GPIO interrupts */ + for (i = 0; i < gc->ngpio; i++) + vf610_gpio_writel(0, port->base + PORT_PCR(i)); +@@ -331,7 +337,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) + vf610_gpio_writel(~0, port->base + PORT_ISFR); + + girq = &gc->irq; +- girq->chip = ic; ++ gpio_irq_chip_set_chip(girq, &vf610_irqchip); + girq->parent_handler = vf610_gpio_irq_handler; + girq->num_parents = 1; + girq->parents = devm_kcalloc(&pdev->dev, 1, +diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c +index 8472013ff38a2..0e78437c8389d 100644 +--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c ++++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c +@@ -1991,6 +1991,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ + case IP_VERSION(11, 0, 0): + case IP_VERSION(11, 0, 1): + case IP_VERSION(11, 0, 2): ++ case IP_VERSION(11, 0, 3): + *states = ATTR_STATE_SUPPORTED; + break; + default: +diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +index b89f7f7ca1885..1b5c27ed27370 100644 +--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c ++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c +@@ -673,7 +673,7 @@ static struct ti_sn65dsi86 *bridge_to_ti_sn65dsi86(struct drm_bridge *bridge) + return container_of(bridge, struct ti_sn65dsi86, bridge); + } + +-static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) ++static int ti_sn_attach_host(struct auxiliary_device *adev, struct ti_sn65dsi86 *pdata) + { + int val; + struct mipi_dsi_host *host; +@@ -688,7 +688,7 @@ static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) + if (!host) + return -EPROBE_DEFER; + +- dsi = devm_mipi_dsi_device_register_full(dev, host, &info); ++ dsi = devm_mipi_dsi_device_register_full(&adev->dev, host, &info); + if (IS_ERR(dsi)) + return PTR_ERR(dsi); + +@@ -706,7 +706,7 @@ static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) + + pdata->dsi = dsi; + +- return devm_mipi_dsi_attach(dev, dsi); ++ return devm_mipi_dsi_attach(&adev->dev, dsi); + } + + static int ti_sn_bridge_attach(struct drm_bridge *bridge, +@@ -1279,9 +1279,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, + struct device_node *np = pdata->dev->of_node; + int ret; + +- pdata->next_bridge = devm_drm_of_get_bridge(pdata->dev, np, 1, 0); ++ pdata->next_bridge = devm_drm_of_get_bridge(&adev->dev, np, 1, 0); + if (IS_ERR(pdata->next_bridge)) +- return dev_err_probe(pdata->dev, PTR_ERR(pdata->next_bridge), ++ return dev_err_probe(&adev->dev, PTR_ERR(pdata->next_bridge), + "failed to create panel bridge\n"); + + ti_sn_bridge_parse_lanes(pdata, np); +@@ -1300,9 +1300,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, + + drm_bridge_add(&pdata->bridge); + +- ret = ti_sn_attach_host(pdata); ++ ret = ti_sn_attach_host(adev, pdata); + if (ret) { +- dev_err_probe(pdata->dev, ret, "failed to attach dsi host\n"); ++ dev_err_probe(&adev->dev, ret, "failed to attach dsi host\n"); + goto err_remove_bridge; + } + +diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c +index 0cb646cb04ee1..d5c15292ae937 100644 +--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c ++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c +@@ -38,6 +38,14 @@ static const struct drm_dmi_panel_orientation_data gpd_micropc = { + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, + }; + ++static const struct drm_dmi_panel_orientation_data gpd_onemix2s = { ++ .width = 1200, ++ .height = 1920, ++ .bios_dates = (const char * const []){ "05/21/2018", "10/26/2018", ++ "03/04/2019", NULL }, ++ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, ++}; ++ + static const struct drm_dmi_panel_orientation_data gpd_pocket = { + .width = 1200, + .height = 1920, +@@ -401,6 +409,14 @@ static const struct dmi_system_id orientation_data[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, ++ }, { /* One Mix 2S (generic strings, also match on bios date) */ ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), ++ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), ++ }, ++ .driver_data = (void *)&gpd_onemix2s, + }, + {} + }; +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c +index d445e2d63c9c8..d7e30d889a5ca 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c +@@ -235,6 +235,7 @@ static vm_fault_t i915_error_to_vmf_fault(int err) + case 0: + case -EAGAIN: + case -ENOSPC: /* transient failure to evict? */ ++ case -ENOBUFS: /* temporarily out of fences? */ + case -ERESTARTSYS: + case -EINTR: + case -EBUSY: +diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c +index 1d0374a577a5e..fb4f0e336b60e 100644 +--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c ++++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c +@@ -234,6 +234,7 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) + npages = obj->size >> PAGE_SHIFT; + mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL); + if (!mtk_gem->pages) { ++ sg_free_table(sgt); + kfree(sgt); + return -ENOMEM; + } +@@ -243,12 +244,15 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) + mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); + if (!mtk_gem->kvaddr) { ++ sg_free_table(sgt); + kfree(sgt); + kfree(mtk_gem->pages); + return -ENOMEM; + } +-out: ++ sg_free_table(sgt); + kfree(sgt); ++ ++out: + iosys_map_set_vaddr(map, mtk_gem->kvaddr); + + return 0; +diff --git a/drivers/hid/.kunitconfig b/drivers/hid/.kunitconfig +index 04daeff5c970e..675a8209c7aeb 100644 +--- a/drivers/hid/.kunitconfig ++++ b/drivers/hid/.kunitconfig +@@ -1,5 +1,6 @@ + CONFIG_KUNIT=y + CONFIG_USB=y + CONFIG_USB_HID=y ++CONFIG_HID_BATTERY_STRENGTH=y + CONFIG_HID_UCLOGIC=y + CONFIG_HID_KUNIT_TEST=y +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index c1873ccc7248d..9ad5e43d9961b 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -1263,6 +1263,7 @@ config HID_MCP2221 + config HID_KUNIT_TEST + tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS + depends on KUNIT ++ depends on HID_BATTERY_STRENGTH + depends on HID_UCLOGIC + default KUNIT_ALL_TESTS + help +diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c +index 403506b9697e7..b346d68a06f5a 100644 +--- a/drivers/hid/hid-holtek-kbd.c ++++ b/drivers/hid/hid-holtek-kbd.c +@@ -130,6 +130,10 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type, + return -ENODEV; + + boot_hid = usb_get_intfdata(boot_interface); ++ if (list_empty(&boot_hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } + boot_hid_input = list_first_entry(&boot_hid->inputs, + struct hid_input, list); + +diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c +new file mode 100644 +index 0000000000000..77c2d45ac62a7 +--- /dev/null ++++ b/drivers/hid/hid-input-test.c +@@ -0,0 +1,80 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * HID to Linux Input mapping ++ * ++ * Copyright (c) 2022 José Expósito <jose.exposito89@gmail.com> ++ */ ++ ++#include <kunit/test.h> ++ ++static void hid_test_input_set_battery_charge_status(struct kunit *test) ++{ ++ struct hid_device *dev; ++ bool handled; ++ ++ dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); ++ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); ++ ++ handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0); ++ KUNIT_EXPECT_FALSE(test, handled); ++ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN); ++ ++ handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0); ++ KUNIT_EXPECT_TRUE(test, handled); ++ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING); ++ ++ handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1); ++ KUNIT_EXPECT_TRUE(test, handled); ++ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING); ++} ++ ++static void hid_test_input_get_battery_property(struct kunit *test) ++{ ++ struct power_supply *psy; ++ struct hid_device *dev; ++ union power_supply_propval val; ++ int ret; ++ ++ dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); ++ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); ++ dev->battery_avoid_query = true; ++ ++ psy = kunit_kzalloc(test, sizeof(*psy), GFP_KERNEL); ++ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, psy); ++ psy->drv_data = dev; ++ ++ dev->battery_status = HID_BATTERY_UNKNOWN; ++ dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; ++ ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); ++ KUNIT_EXPECT_EQ(test, ret, 0); ++ KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_UNKNOWN); ++ ++ dev->battery_status = HID_BATTERY_REPORTED; ++ dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; ++ ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); ++ KUNIT_EXPECT_EQ(test, ret, 0); ++ KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_CHARGING); ++ ++ dev->battery_status = HID_BATTERY_REPORTED; ++ dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; ++ ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); ++ KUNIT_EXPECT_EQ(test, ret, 0); ++ KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_DISCHARGING); ++} ++ ++static struct kunit_case hid_input_tests[] = { ++ KUNIT_CASE(hid_test_input_set_battery_charge_status), ++ KUNIT_CASE(hid_test_input_get_battery_property), ++ { } ++}; ++ ++static struct kunit_suite hid_input_test_suite = { ++ .name = "hid_input", ++ .test_cases = hid_input_tests, ++}; ++ ++kunit_test_suite(hid_input_test_suite); ++ ++MODULE_DESCRIPTION("HID input KUnit tests"); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>"); +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index 77ee5e01e6111..4ba5df3c1e039 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -492,7 +492,7 @@ static int hidinput_get_battery_property(struct power_supply *psy, + if (dev->battery_status == HID_BATTERY_UNKNOWN) + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + else +- val->intval = POWER_SUPPLY_STATUS_DISCHARGING; ++ val->intval = dev->battery_charge_status; + break; + + case POWER_SUPPLY_PROP_SCOPE: +@@ -560,6 +560,7 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, + dev->battery_max = max; + dev->battery_report_type = report_type; + dev->battery_report_id = field->report->id; ++ dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; + + /* + * Stylus is normally not connected to the device and thus we +@@ -626,6 +627,20 @@ static void hidinput_update_battery(struct hid_device *dev, int value) + power_supply_changed(dev->battery); + } + } ++ ++static bool hidinput_set_battery_charge_status(struct hid_device *dev, ++ unsigned int usage, int value) ++{ ++ switch (usage) { ++ case HID_BAT_CHARGING: ++ dev->battery_charge_status = value ? ++ POWER_SUPPLY_STATUS_CHARGING : ++ POWER_SUPPLY_STATUS_DISCHARGING; ++ return true; ++ } ++ ++ return false; ++} + #else /* !CONFIG_HID_BATTERY_STRENGTH */ + static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, + struct hid_field *field, bool is_percentage) +@@ -640,6 +655,12 @@ static void hidinput_cleanup_battery(struct hid_device *dev) + static void hidinput_update_battery(struct hid_device *dev, int value) + { + } ++ ++static bool hidinput_set_battery_charge_status(struct hid_device *dev, ++ unsigned int usage, int value) ++{ ++ return false; ++} + #endif /* CONFIG_HID_BATTERY_STRENGTH */ + + static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field, +@@ -1239,6 +1260,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel + hidinput_setup_battery(device, HID_INPUT_REPORT, field, true); + usage->type = EV_PWR; + return; ++ case HID_BAT_CHARGING: ++ usage->type = EV_PWR; ++ return; + } + goto unknown; + +@@ -1481,7 +1505,11 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct + return; + + if (usage->type == EV_PWR) { +- hidinput_update_battery(hid, value); ++ bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value); ++ ++ if (!handled) ++ hidinput_update_battery(hid, value); ++ + return; + } + +@@ -2346,3 +2374,7 @@ void hidinput_disconnect(struct hid_device *hid) + cancel_work_sync(&hid->led_work); + } + EXPORT_SYMBOL_GPL(hidinput_disconnect); ++ ++#ifdef CONFIG_HID_KUNIT_TEST ++#include "hid-input-test.c" ++#endif +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index fb427391c3b86..8d0dad12b2d37 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -4427,6 +4427,8 @@ static const struct hid_device_id hidpp_devices[] = { + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb008) }, + { /* MX Master mouse over Bluetooth */ + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012) }, ++ { /* M720 Triathlon mouse over Bluetooth */ ++ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb015) }, + { /* MX Ergo trackball over Bluetooth */ + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01d) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e) }, +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 521b2ffb42449..8db4ae05febc8 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -2144,6 +2144,10 @@ static const struct hid_device_id mt_devices[] = { + USB_DEVICE_ID_MTP_STM)}, + + /* Synaptics devices */ ++ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, ++ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, ++ USB_VENDOR_ID_SYNAPTICS, 0xcd7e) }, ++ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_SYNAPTICS, 0xce08) }, +diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c +index 5bfc0c4504608..8a8a3dd8af0c1 100644 +--- a/drivers/hid/hid-nintendo.c ++++ b/drivers/hid/hid-nintendo.c +@@ -2011,7 +2011,9 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) + struct joycon_input_report *report; + + req.subcmd_id = JC_SUBCMD_REQ_DEV_INFO; ++ mutex_lock(&ctlr->output_mutex); + ret = joycon_send_subcmd(ctlr, &req, 0, HZ); ++ mutex_unlock(&ctlr->output_mutex); + if (ret) { + hid_err(ctlr->hdev, "Failed to get joycon info; ret=%d\n", ret); + return ret; +@@ -2040,6 +2042,85 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) + return 0; + } + ++static int joycon_init(struct hid_device *hdev) ++{ ++ struct joycon_ctlr *ctlr = hid_get_drvdata(hdev); ++ int ret = 0; ++ ++ mutex_lock(&ctlr->output_mutex); ++ /* if handshake command fails, assume ble pro controller */ ++ if ((jc_type_is_procon(ctlr) || jc_type_is_chrggrip(ctlr)) && ++ !joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ)) { ++ hid_dbg(hdev, "detected USB controller\n"); ++ /* set baudrate for improved latency */ ++ ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M, HZ); ++ if (ret) { ++ hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ /* handshake */ ++ ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ); ++ if (ret) { ++ hid_err(hdev, "Failed handshake; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ /* ++ * Set no timeout (to keep controller in USB mode). ++ * This doesn't send a response, so ignore the timeout. ++ */ ++ joycon_send_usb(ctlr, JC_USB_CMD_NO_TIMEOUT, HZ/10); ++ } else if (jc_type_is_chrggrip(ctlr)) { ++ hid_err(hdev, "Failed charging grip handshake\n"); ++ ret = -ETIMEDOUT; ++ goto out_unlock; ++ } ++ ++ /* get controller calibration data, and parse it */ ++ ret = joycon_request_calibration(ctlr); ++ if (ret) { ++ /* ++ * We can function with default calibration, but it may be ++ * inaccurate. Provide a warning, and continue on. ++ */ ++ hid_warn(hdev, "Analog stick positions may be inaccurate\n"); ++ } ++ ++ /* get IMU calibration data, and parse it */ ++ ret = joycon_request_imu_calibration(ctlr); ++ if (ret) { ++ /* ++ * We can function with default calibration, but it may be ++ * inaccurate. Provide a warning, and continue on. ++ */ ++ hid_warn(hdev, "Unable to read IMU calibration data\n"); ++ } ++ ++ /* Set the reporting mode to 0x30, which is the full report mode */ ++ ret = joycon_set_report_mode(ctlr); ++ if (ret) { ++ hid_err(hdev, "Failed to set report mode; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ ++ /* Enable rumble */ ++ ret = joycon_enable_rumble(ctlr); ++ if (ret) { ++ hid_err(hdev, "Failed to enable rumble; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ ++ /* Enable the IMU */ ++ ret = joycon_enable_imu(ctlr); ++ if (ret) { ++ hid_err(hdev, "Failed to enable the IMU; ret=%d\n", ret); ++ goto out_unlock; ++ } ++ ++out_unlock: ++ mutex_unlock(&ctlr->output_mutex); ++ return ret; ++} ++ + /* Common handler for parsing inputs */ + static int joycon_ctlr_read_handler(struct joycon_ctlr *ctlr, u8 *data, + int size) +@@ -2171,85 +2252,19 @@ static int nintendo_hid_probe(struct hid_device *hdev, + + hid_device_io_start(hdev); + +- /* Initialize the controller */ +- mutex_lock(&ctlr->output_mutex); +- /* if handshake command fails, assume ble pro controller */ +- if ((jc_type_is_procon(ctlr) || jc_type_is_chrggrip(ctlr)) && +- !joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ)) { +- hid_dbg(hdev, "detected USB controller\n"); +- /* set baudrate for improved latency */ +- ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M, HZ); +- if (ret) { +- hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret); +- goto err_mutex; +- } +- /* handshake */ +- ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ); +- if (ret) { +- hid_err(hdev, "Failed handshake; ret=%d\n", ret); +- goto err_mutex; +- } +- /* +- * Set no timeout (to keep controller in USB mode). +- * This doesn't send a response, so ignore the timeout. +- */ +- joycon_send_usb(ctlr, JC_USB_CMD_NO_TIMEOUT, HZ/10); +- } else if (jc_type_is_chrggrip(ctlr)) { +- hid_err(hdev, "Failed charging grip handshake\n"); +- ret = -ETIMEDOUT; +- goto err_mutex; +- } +- +- /* get controller calibration data, and parse it */ +- ret = joycon_request_calibration(ctlr); ++ ret = joycon_init(hdev); + if (ret) { +- /* +- * We can function with default calibration, but it may be +- * inaccurate. Provide a warning, and continue on. +- */ +- hid_warn(hdev, "Analog stick positions may be inaccurate\n"); +- } +- +- /* get IMU calibration data, and parse it */ +- ret = joycon_request_imu_calibration(ctlr); +- if (ret) { +- /* +- * We can function with default calibration, but it may be +- * inaccurate. Provide a warning, and continue on. +- */ +- hid_warn(hdev, "Unable to read IMU calibration data\n"); +- } +- +- /* Set the reporting mode to 0x30, which is the full report mode */ +- ret = joycon_set_report_mode(ctlr); +- if (ret) { +- hid_err(hdev, "Failed to set report mode; ret=%d\n", ret); +- goto err_mutex; +- } +- +- /* Enable rumble */ +- ret = joycon_enable_rumble(ctlr); +- if (ret) { +- hid_err(hdev, "Failed to enable rumble; ret=%d\n", ret); +- goto err_mutex; +- } +- +- /* Enable the IMU */ +- ret = joycon_enable_imu(ctlr); +- if (ret) { +- hid_err(hdev, "Failed to enable the IMU; ret=%d\n", ret); +- goto err_mutex; ++ hid_err(hdev, "Failed to initialize controller; ret=%d\n", ret); ++ goto err_close; + } + + ret = joycon_read_info(ctlr); + if (ret) { + hid_err(hdev, "Failed to retrieve controller info; ret=%d\n", + ret); +- goto err_mutex; ++ goto err_close; + } + +- mutex_unlock(&ctlr->output_mutex); +- + /* Initialize the leds */ + ret = joycon_leds_create(ctlr); + if (ret) { +@@ -2275,8 +2290,6 @@ static int nintendo_hid_probe(struct hid_device *hdev, + hid_dbg(hdev, "probe - success\n"); + return 0; + +-err_mutex: +- mutex_unlock(&ctlr->output_mutex); + err_close: + hid_hw_close(hdev); + err_stop: +@@ -2306,6 +2319,20 @@ static void nintendo_hid_remove(struct hid_device *hdev) + hid_hw_stop(hdev); + } + ++#ifdef CONFIG_PM ++ ++static int nintendo_hid_resume(struct hid_device *hdev) ++{ ++ int ret = joycon_init(hdev); ++ ++ if (ret) ++ hid_err(hdev, "Failed to restore controller after resume"); ++ ++ return ret; ++} ++ ++#endif ++ + static const struct hid_device_id nintendo_hid_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_PROCON) }, +@@ -2327,6 +2354,10 @@ static struct hid_driver nintendo_hid_driver = { + .probe = nintendo_hid_probe, + .remove = nintendo_hid_remove, + .raw_event = nintendo_hid_event, ++ ++#ifdef CONFIG_PM ++ .resume = nintendo_hid_resume, ++#endif + }; + module_hid_driver(nintendo_hid_driver); + +diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c +index 313904be5f3bd..57ff09f18c371 100644 +--- a/drivers/i2c/i2c-mux.c ++++ b/drivers/i2c/i2c-mux.c +@@ -341,7 +341,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, + priv->adap.lock_ops = &i2c_parent_lock_ops; + + /* Sanity check on class */ +- if (i2c_mux_parent_classes(parent) & class) ++ if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED) + dev_err(&parent->dev, + "Segment %d behind mux can't share classes with ancestors\n", + chan_id); +diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c +index 80eff7090f14a..faf680140c178 100644 +--- a/drivers/iio/adc/ad7192.c ++++ b/drivers/iio/adc/ad7192.c +@@ -177,7 +177,7 @@ struct ad7192_chip_info { + struct ad7192_state { + const struct ad7192_chip_info *chip_info; + struct regulator *avdd; +- struct regulator *dvdd; ++ struct regulator *vref; + struct clk *mclk; + u16 int_vref_mv; + u32 fclk; +@@ -1011,24 +1011,34 @@ static int ad7192_probe(struct spi_device *spi) + if (ret) + return ret; + +- st->dvdd = devm_regulator_get(&spi->dev, "dvdd"); +- if (IS_ERR(st->dvdd)) +- return PTR_ERR(st->dvdd); ++ ret = devm_regulator_get_enable(&spi->dev, "dvdd"); ++ if (ret) ++ return dev_err_probe(&spi->dev, ret, "Failed to enable specified DVdd supply\n"); + +- ret = regulator_enable(st->dvdd); +- if (ret) { +- dev_err(&spi->dev, "Failed to enable specified DVdd supply\n"); +- return ret; +- } ++ st->vref = devm_regulator_get_optional(&spi->dev, "vref"); ++ if (IS_ERR(st->vref)) { ++ if (PTR_ERR(st->vref) != -ENODEV) ++ return PTR_ERR(st->vref); + +- ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->dvdd); +- if (ret) +- return ret; ++ ret = regulator_get_voltage(st->avdd); ++ if (ret < 0) ++ return dev_err_probe(&spi->dev, ret, ++ "Device tree error, AVdd voltage undefined\n"); ++ } else { ++ ret = regulator_enable(st->vref); ++ if (ret) { ++ dev_err(&spi->dev, "Failed to enable specified Vref supply\n"); ++ return ret; ++ } + +- ret = regulator_get_voltage(st->avdd); +- if (ret < 0) { +- dev_err(&spi->dev, "Device tree error, reference voltage undefined\n"); +- return ret; ++ ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->vref); ++ if (ret) ++ return ret; ++ ++ ret = regulator_get_voltage(st->vref); ++ if (ret < 0) ++ return dev_err_probe(&spi->dev, ret, ++ "Device tree error, Vref voltage undefined\n"); + } + st->int_vref_mv = ret / 1000; + +diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +index d98f7e4d202c1..1ddce991fb3f4 100644 +--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c ++++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +@@ -190,8 +190,11 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev, + /* + * Ignore samples if the buffer is not set: it is needed if the ODR is + * set but the buffer is not enabled yet. ++ * ++ * Note: iio_device_claim_buffer_mode() returns -EBUSY if the buffer ++ * is not enabled. + */ +- if (!iio_buffer_enabled(indio_dev)) ++ if (iio_device_claim_buffer_mode(indio_dev) < 0) + return 0; + + out = (s16 *)st->samples; +@@ -210,6 +213,7 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev, + iio_push_to_buffers_with_timestamp(indio_dev, st->samples, + timestamp + delta); + ++ iio_device_release_buffer_mode(indio_dev); + return 0; + } + EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data); +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index f3f8392623a46..c9614982cb671 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -2084,6 +2084,44 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev) + } + EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); + ++/** ++ * iio_device_claim_buffer_mode - Keep device in buffer mode ++ * @indio_dev: the iio_dev associated with the device ++ * ++ * If the device is in buffer mode it is guaranteed to stay ++ * that way until iio_device_release_buffer_mode() is called. ++ * ++ * Use with iio_device_release_buffer_mode(). ++ * ++ * Returns: 0 on success, -EBUSY on failure. ++ */ ++int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) ++{ ++ mutex_lock(&indio_dev->mlock); ++ ++ if (iio_buffer_enabled(indio_dev)) ++ return 0; ++ ++ mutex_unlock(&indio_dev->mlock); ++ return -EBUSY; ++} ++EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); ++ ++/** ++ * iio_device_release_buffer_mode - releases claim on buffer mode ++ * @indio_dev: the iio_dev associated with the device ++ * ++ * Release the claim. Device is no longer guaranteed to stay ++ * in buffer mode. ++ * ++ * Use with iio_device_claim_buffer_mode(). ++ */ ++void iio_device_release_buffer_mode(struct iio_dev *indio_dev) ++{ ++ mutex_unlock(&indio_dev->mlock); ++} ++EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); ++ + /** + * iio_device_get_current_mode() - helper function providing read-only access to + * the opaque @currentmode variable +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index 89cd48fcec79f..4a4bab9aa7263 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -104,7 +104,7 @@ static int mmc_decode_cid(struct mmc_card *card) + case 3: /* MMC v3.1 - v3.3 */ + case 4: /* MMC v4 */ + card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); +- card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); ++ card->cid.oemid = UNSTUFF_BITS(resp, 104, 8); + card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); + card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); + card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); +diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c +index f64b9ac76a5cd..5914516df2f7f 100644 +--- a/drivers/mmc/core/sdio.c ++++ b/drivers/mmc/core/sdio.c +@@ -1089,8 +1089,14 @@ static int mmc_sdio_resume(struct mmc_host *host) + } + err = mmc_sdio_reinit_card(host); + } else if (mmc_card_wake_sdio_irq(host)) { +- /* We may have switched to 1-bit mode during suspend */ ++ /* ++ * We may have switched to 1-bit mode during suspend, ++ * need to hold retuning, because tuning only supprt ++ * 4-bit mode or 8 bit mode. ++ */ ++ mmc_retune_hold_now(host); + err = sdio_enable_4bit_bus(host->card); ++ mmc_retune_release(host); + } + + if (err) +diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c +index 1a0d4dc24717c..70e414027155d 100644 +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -655,11 +655,11 @@ static void msdc_reset_hw(struct msdc_host *host) + u32 val; + + sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); +- readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0); ++ readl_poll_timeout_atomic(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0); + + sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); +- readl_poll_timeout(host->base + MSDC_FIFOCS, val, +- !(val & MSDC_FIFOCS_CLR), 0, 0); ++ readl_poll_timeout_atomic(host->base + MSDC_FIFOCS, val, ++ !(val & MSDC_FIFOCS_CLR), 0, 0); + + val = readl(host->base + MSDC_INT); + writel(val, host->base + MSDC_INT); +diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c +index 4d509f6561887..c580ba089a261 100644 +--- a/drivers/mmc/host/sdhci-pci-gli.c ++++ b/drivers/mmc/host/sdhci-pci-gli.c +@@ -756,42 +756,6 @@ static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg) + return value; + } + +-#ifdef CONFIG_PM_SLEEP +-static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip) +-{ +- struct sdhci_pci_slot *slot = chip->slots[0]; +- +- pci_free_irq_vectors(slot->chip->pdev); +- gli_pcie_enable_msi(slot); +- +- return sdhci_pci_resume_host(chip); +-} +- +-static int sdhci_cqhci_gli_resume(struct sdhci_pci_chip *chip) +-{ +- struct sdhci_pci_slot *slot = chip->slots[0]; +- int ret; +- +- ret = sdhci_pci_gli_resume(chip); +- if (ret) +- return ret; +- +- return cqhci_resume(slot->host->mmc); +-} +- +-static int sdhci_cqhci_gli_suspend(struct sdhci_pci_chip *chip) +-{ +- struct sdhci_pci_slot *slot = chip->slots[0]; +- int ret; +- +- ret = cqhci_suspend(slot->host->mmc); +- if (ret) +- return ret; +- +- return sdhci_suspend_host(slot->host); +-} +-#endif +- + static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc, + struct mmc_ios *ios) + { +@@ -1040,6 +1004,70 @@ static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip) + } + #endif + ++#ifdef CONFIG_PM_SLEEP ++static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip) ++{ ++ struct sdhci_pci_slot *slot = chip->slots[0]; ++ ++ pci_free_irq_vectors(slot->chip->pdev); ++ gli_pcie_enable_msi(slot); ++ ++ return sdhci_pci_resume_host(chip); ++} ++ ++static int gl9763e_resume(struct sdhci_pci_chip *chip) ++{ ++ struct sdhci_pci_slot *slot = chip->slots[0]; ++ int ret; ++ ++ ret = sdhci_pci_gli_resume(chip); ++ if (ret) ++ return ret; ++ ++ ret = cqhci_resume(slot->host->mmc); ++ if (ret) ++ return ret; ++ ++ /* ++ * Disable LPM negotiation to bring device back in sync ++ * with its runtime_pm state. ++ */ ++ gl9763e_set_low_power_negotiation(slot, false); ++ ++ return 0; ++} ++ ++static int gl9763e_suspend(struct sdhci_pci_chip *chip) ++{ ++ struct sdhci_pci_slot *slot = chip->slots[0]; ++ int ret; ++ ++ /* ++ * Certain SoCs can suspend only with the bus in low- ++ * power state, notably x86 SoCs when using S0ix. ++ * Re-enable LPM negotiation to allow entering L1 state ++ * and entering system suspend. ++ */ ++ gl9763e_set_low_power_negotiation(slot, true); ++ ++ ret = cqhci_suspend(slot->host->mmc); ++ if (ret) ++ goto err_suspend; ++ ++ ret = sdhci_suspend_host(slot->host); ++ if (ret) ++ goto err_suspend_host; ++ ++ return 0; ++ ++err_suspend_host: ++ cqhci_resume(slot->host->mmc); ++err_suspend: ++ gl9763e_set_low_power_negotiation(slot, false); ++ return ret; ++} ++#endif ++ + static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot) + { + struct pci_dev *pdev = slot->chip->pdev; +@@ -1147,8 +1175,8 @@ const struct sdhci_pci_fixes sdhci_gl9763e = { + .probe_slot = gli_probe_slot_gl9763e, + .ops = &sdhci_gl9763e_ops, + #ifdef CONFIG_PM_SLEEP +- .resume = sdhci_cqhci_gli_resume, +- .suspend = sdhci_cqhci_gli_suspend, ++ .resume = gl9763e_resume, ++ .suspend = gl9763e_suspend, + #endif + #ifdef CONFIG_PM + .runtime_suspend = gl9763e_runtime_suspend, +diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-core.c +index c73854da51363..19dad5a23f944 100644 +--- a/drivers/mtd/maps/physmap-core.c ++++ b/drivers/mtd/maps/physmap-core.c +@@ -552,6 +552,17 @@ static int physmap_flash_probe(struct platform_device *dev) + if (info->probe_type) { + info->mtds[i] = do_map_probe(info->probe_type, + &info->maps[i]); ++ ++ /* Fall back to mapping region as ROM */ ++ if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) && ++ strcmp(info->probe_type, "map_rom")) { ++ dev_warn(&dev->dev, ++ "map_probe() failed for type %s\n", ++ info->probe_type); ++ ++ info->mtds[i] = do_map_probe("map_rom", ++ &info->maps[i]); ++ } + } else { + int j; + +diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c +index ec7e6eeac55f9..e6ffe87a599eb 100644 +--- a/drivers/mtd/nand/raw/arasan-nand-controller.c ++++ b/drivers/mtd/nand/raw/arasan-nand-controller.c +@@ -515,6 +515,7 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, + struct mtd_info *mtd = nand_to_mtd(chip); + unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0); + dma_addr_t dma_addr; ++ u8 status; + int ret; + struct anfc_op nfc_op = { + .pkt_reg = +@@ -561,10 +562,21 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, + } + + /* Spare data is not protected */ +- if (oob_required) ++ if (oob_required) { + ret = nand_write_oob_std(chip, page); ++ if (ret) ++ return ret; ++ } + +- return ret; ++ /* Check write status on the chip side */ ++ ret = nand_status_op(chip, &status); ++ if (ret) ++ return ret; ++ ++ if (status & NAND_STATUS_FAIL) ++ return -EIO; ++ ++ return 0; + } + + static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index a57a1501449aa..d527c03630bce 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -1154,6 +1154,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, + .ndcb[2] = NDCB2_ADDR5_PAGE(page), + }; + unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0); ++ u8 status; + int ret; + + /* NFCv2 needs more information about the operation being executed */ +@@ -1187,7 +1188,18 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, + + ret = marvell_nfc_wait_op(chip, + PSEC_TO_MSEC(sdr->tPROG_max)); +- return ret; ++ if (ret) ++ return ret; ++ ++ /* Check write status on the chip side */ ++ ret = nand_status_op(chip, &status); ++ if (ret) ++ return ret; ++ ++ if (status & NAND_STATUS_FAIL) ++ return -EIO; ++ ++ return 0; + } + + static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip, +@@ -1616,6 +1628,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip, + int data_len = lt->data_bytes; + int spare_len = lt->spare_bytes; + int chunk, ret; ++ u8 status; + + marvell_nfc_select_target(chip, chip->cur_cs); + +@@ -1652,6 +1665,14 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip, + if (ret) + return ret; + ++ /* Check write status on the chip side */ ++ ret = nand_status_op(chip, &status); ++ if (ret) ++ return ret; ++ ++ if (status & NAND_STATUS_FAIL) ++ return -EIO; ++ + return 0; + } + +diff --git a/drivers/mtd/nand/raw/pl35x-nand-controller.c b/drivers/mtd/nand/raw/pl35x-nand-controller.c +index 3c6f6aff649f8..7bcece135715d 100644 +--- a/drivers/mtd/nand/raw/pl35x-nand-controller.c ++++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c +@@ -513,6 +513,7 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip, + u32 addr1 = 0, addr2 = 0, row; + u32 cmd_addr; + int i, ret; ++ u8 status; + + ret = pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_APB); + if (ret) +@@ -565,6 +566,14 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip, + if (ret) + goto disable_ecc_engine; + ++ /* Check write status on the chip side */ ++ ret = nand_status_op(chip, &status); ++ if (ret) ++ goto disable_ecc_engine; ++ ++ if (status & NAND_STATUS_FAIL) ++ ret = -EIO; ++ + disable_ecc_engine: + pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS); + +diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c +index 198a44794d2dc..fbf36cbcbb18d 100644 +--- a/drivers/mtd/nand/raw/qcom_nandc.c ++++ b/drivers/mtd/nand/raw/qcom_nandc.c +@@ -3310,7 +3310,7 @@ err_nandc_alloc: + err_aon_clk: + clk_disable_unprepare(nandc->core_clk); + err_core_clk: +- dma_unmap_resource(dev, res->start, resource_size(res), ++ dma_unmap_resource(dev, nandc->base_dma, resource_size(res), + DMA_BIDIRECTIONAL, 0); + return ret; + } +diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c +index 50b7295bc9222..12601bc4227a7 100644 +--- a/drivers/mtd/nand/spi/micron.c ++++ b/drivers/mtd/nand/spi/micron.c +@@ -12,7 +12,7 @@ + + #define SPINAND_MFR_MICRON 0x2c + +-#define MICRON_STATUS_ECC_MASK GENMASK(7, 4) ++#define MICRON_STATUS_ECC_MASK GENMASK(6, 4) + #define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4) + #define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4) + #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4) +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 7a3c7a74af04a..b170a3d8d007e 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3990,7 +3990,7 @@ static inline const void *bond_pull_data(struct sk_buff *skb, + if (likely(n <= hlen)) + return data; + else if (skb && likely(pskb_may_pull(skb, n))) +- return skb->head; ++ return skb->data; + + return NULL; + } +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index 72374b066f64a..cd1f240c90f39 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -617,17 +617,16 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) + dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio"); + priv->master_mii_bus = of_mdio_find_bus(dn); + if (!priv->master_mii_bus) { +- of_node_put(dn); +- return -EPROBE_DEFER; ++ err = -EPROBE_DEFER; ++ goto err_of_node_put; + } + +- get_device(&priv->master_mii_bus->dev); + priv->master_mii_dn = dn; + + priv->slave_mii_bus = mdiobus_alloc(); + if (!priv->slave_mii_bus) { +- of_node_put(dn); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto err_put_master_mii_bus_dev; + } + + priv->slave_mii_bus->priv = priv; +@@ -684,11 +683,17 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) + } + + err = mdiobus_register(priv->slave_mii_bus); +- if (err && dn) { +- mdiobus_free(priv->slave_mii_bus); +- of_node_put(dn); +- } ++ if (err && dn) ++ goto err_free_slave_mii_bus; + ++ return 0; ++ ++err_free_slave_mii_bus: ++ mdiobus_free(priv->slave_mii_bus); ++err_put_master_mii_bus_dev: ++ put_device(&priv->master_mii_bus->dev); ++err_of_node_put: ++ of_node_put(dn); + return err; + } + +@@ -696,6 +701,7 @@ static void bcm_sf2_mdio_unregister(struct bcm_sf2_priv *priv) + { + mdiobus_unregister(priv->slave_mii_bus); + mdiobus_free(priv->slave_mii_bus); ++ put_device(&priv->master_mii_bus->dev); + of_node_put(priv->master_mii_dn); + } + +diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c +index a4256087ac828..5e45bef4fd34f 100644 +--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c ++++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c +@@ -911,7 +911,7 @@ static int csk_wait_memory(struct chtls_dev *cdev, + struct sock *sk, long *timeo_p) + { + DEFINE_WAIT_FUNC(wait, woken_wake_function); +- int err = 0; ++ int ret, err = 0; + long current_timeo; + long vm_wait = 0; + bool noblock; +@@ -942,10 +942,13 @@ static int csk_wait_memory(struct chtls_dev *cdev, + + set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + sk->sk_write_pending++; +- sk_wait_event(sk, ¤t_timeo, sk->sk_err || +- (sk->sk_shutdown & SEND_SHUTDOWN) || +- (csk_mem_free(cdev, sk) && !vm_wait), &wait); ++ ret = sk_wait_event(sk, ¤t_timeo, sk->sk_err || ++ (sk->sk_shutdown & SEND_SHUTDOWN) || ++ (csk_mem_free(cdev, sk) && !vm_wait), ++ &wait); + sk->sk_write_pending--; ++ if (ret < 0) ++ goto do_error; + + if (vm_wait) { + vm_wait -= current_timeo; +@@ -1438,6 +1441,7 @@ static int chtls_pt_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + int copied = 0; + int target; + long timeo; ++ int ret; + + buffers_freed = 0; + +@@ -1513,7 +1517,11 @@ static int chtls_pt_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + if (copied >= target) + break; + chtls_cleanup_rbuf(sk, copied); +- sk_wait_data(sk, &timeo, NULL); ++ ret = sk_wait_data(sk, &timeo, NULL); ++ if (ret < 0) { ++ copied = copied ? : ret; ++ goto unlock; ++ } + continue; + found_ok_skb: + if (!skb->len) { +@@ -1608,6 +1616,8 @@ skip_copy: + + if (buffers_freed) + chtls_cleanup_rbuf(sk, copied); ++ ++unlock: + release_sock(sk); + return copied; + } +@@ -1624,6 +1634,7 @@ static int peekmsg(struct sock *sk, struct msghdr *msg, + int copied = 0; + size_t avail; /* amount of available data in current skb */ + long timeo; ++ int ret; + + lock_sock(sk); + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); +@@ -1675,7 +1686,12 @@ static int peekmsg(struct sock *sk, struct msghdr *msg, + release_sock(sk); + lock_sock(sk); + } else { +- sk_wait_data(sk, &timeo, NULL); ++ ret = sk_wait_data(sk, &timeo, NULL); ++ if (ret < 0) { ++ /* here 'copied' is 0 due to previous checks */ ++ copied = ret; ++ break; ++ } + } + + if (unlikely(peek_seq != tp->copied_seq)) { +@@ -1746,6 +1762,7 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + int copied = 0; + long timeo; + int target; /* Read at least this many bytes */ ++ int ret; + + buffers_freed = 0; + +@@ -1837,7 +1854,11 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + if (copied >= target) + break; + chtls_cleanup_rbuf(sk, copied); +- sk_wait_data(sk, &timeo, NULL); ++ ret = sk_wait_data(sk, &timeo, NULL); ++ if (ret < 0) { ++ copied = copied ? : ret; ++ goto unlock; ++ } + continue; + + found_ok_skb: +@@ -1906,6 +1927,7 @@ skip_copy: + if (buffers_freed) + chtls_cleanup_rbuf(sk, copied); + ++unlock: + release_sock(sk); + return copied; + } +diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c +index 82e06272158df..6266756b47b9d 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_common.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_common.c +@@ -1082,7 +1082,7 @@ void i40e_clear_hw(struct i40e_hw *hw) + I40E_PFLAN_QALLOC_FIRSTQ_SHIFT; + j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >> + I40E_PFLAN_QALLOC_LASTQ_SHIFT; +- if (val & I40E_PFLAN_QALLOC_VALID_MASK) ++ if (val & I40E_PFLAN_QALLOC_VALID_MASK && j >= base_queue) + num_queues = (j - base_queue) + 1; + else + num_queues = 0; +@@ -1092,7 +1092,7 @@ void i40e_clear_hw(struct i40e_hw *hw) + I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT; + j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >> + I40E_PF_VT_PFALLOC_LASTVF_SHIFT; +- if (val & I40E_PF_VT_PFALLOC_VALID_MASK) ++ if (val & I40E_PF_VT_PFALLOC_VALID_MASK && j >= i) + num_vfs = (j - i) + 1; + else + num_vfs = 0; +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index 7276badfa19ea..c051503c3a892 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -1100,8 +1100,7 @@ static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) + + ctxt->info.q_opt_rss = ((lut_type << ICE_AQ_VSI_Q_OPT_RSS_LUT_S) & + ICE_AQ_VSI_Q_OPT_RSS_LUT_M) | +- ((hash_type << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) & +- ICE_AQ_VSI_Q_OPT_RSS_HASH_M); ++ (hash_type & ICE_AQ_VSI_Q_OPT_RSS_HASH_M); + } + + static void +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 3f98781e74b28..f0f39364819ac 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -6,6 +6,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #include <generated/utsrelease.h> ++#include <linux/crash_dump.h> + #include "ice.h" + #include "ice_base.h" + #include "ice_lib.h" +@@ -4681,6 +4682,20 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + return -EINVAL; + } + ++ /* when under a kdump kernel initiate a reset before enabling the ++ * device in order to clear out any pending DMA transactions. These ++ * transactions can cause some systems to machine check when doing ++ * the pcim_enable_device() below. ++ */ ++ if (is_kdump_kernel()) { ++ pci_save_state(pdev); ++ pci_clear_master(pdev); ++ err = pcie_flr(pdev); ++ if (err) ++ return err; ++ pci_restore_state(pdev); ++ } ++ + /* this driver uses devres, see + * Documentation/driver-api/driver-model/devres.rst + */ +@@ -4708,7 +4723,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + return err; + } + +- pci_enable_pcie_error_reporting(pdev); + pci_set_master(pdev); + + pf->pdev = pdev; +@@ -5001,7 +5015,6 @@ err_init_pf_unroll: + ice_devlink_destroy_regions(pf); + ice_deinit_hw(hw); + err_exit_unroll: +- pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + return err; + } +@@ -5127,7 +5140,6 @@ static void ice_remove(struct pci_dev *pdev) + ice_reset(&pf->hw, ICE_RESET_PFR); + pci_wait_for_pending_transaction(pdev); + ice_clear_interrupt_scheme(pf); +- pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + } + +diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h +index d3b17aa1d1a83..43c05b41627f7 100644 +--- a/drivers/net/ethernet/intel/igc/igc.h ++++ b/drivers/net/ethernet/intel/igc/igc.h +@@ -183,9 +183,11 @@ struct igc_adapter { + u32 max_frame_size; + u32 min_frame_size; + ++ int tc_setup_type; + ktime_t base_time; + ktime_t cycle_time; + bool qbv_enable; ++ u32 qbv_config_change_errors; + + /* OS defined structs */ + struct pci_dev *pdev; +@@ -228,6 +230,10 @@ struct igc_adapter { + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_caps; + struct work_struct ptp_tx_work; ++ /* Access to ptp_tx_skb and ptp_tx_start are protected by the ++ * ptp_tx_lock. ++ */ ++ spinlock_t ptp_tx_lock; + struct sk_buff *ptp_tx_skb; + struct hwtstamp_config tstamp_config; + unsigned long ptp_tx_start; +@@ -429,7 +435,6 @@ enum igc_state_t { + __IGC_TESTING, + __IGC_RESETTING, + __IGC_DOWN, +- __IGC_PTP_TX_IN_PROGRESS, + }; + + enum igc_tx_flags { +diff --git a/drivers/net/ethernet/intel/igc/igc_base.c b/drivers/net/ethernet/intel/igc/igc_base.c +index a15927e772720..a1d815af507d9 100644 +--- a/drivers/net/ethernet/intel/igc/igc_base.c ++++ b/drivers/net/ethernet/intel/igc/igc_base.c +@@ -396,6 +396,35 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw) + rd32(IGC_MPC); + } + ++bool igc_is_device_id_i225(struct igc_hw *hw) ++{ ++ switch (hw->device_id) { ++ case IGC_DEV_ID_I225_LM: ++ case IGC_DEV_ID_I225_V: ++ case IGC_DEV_ID_I225_I: ++ case IGC_DEV_ID_I225_K: ++ case IGC_DEV_ID_I225_K2: ++ case IGC_DEV_ID_I225_LMVP: ++ case IGC_DEV_ID_I225_IT: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++bool igc_is_device_id_i226(struct igc_hw *hw) ++{ ++ switch (hw->device_id) { ++ case IGC_DEV_ID_I226_LM: ++ case IGC_DEV_ID_I226_V: ++ case IGC_DEV_ID_I226_K: ++ case IGC_DEV_ID_I226_IT: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static struct igc_mac_operations igc_mac_ops_base = { + .init_hw = igc_init_hw_base, + .check_for_link = igc_check_for_copper_link, +diff --git a/drivers/net/ethernet/intel/igc/igc_base.h b/drivers/net/ethernet/intel/igc/igc_base.h +index 52849f5e8048d..9f3827eda157c 100644 +--- a/drivers/net/ethernet/intel/igc/igc_base.h ++++ b/drivers/net/ethernet/intel/igc/igc_base.h +@@ -7,6 +7,8 @@ + /* forward declaration */ + void igc_rx_fifo_flush_base(struct igc_hw *hw); + void igc_power_down_phy_copper_base(struct igc_hw *hw); ++bool igc_is_device_id_i225(struct igc_hw *hw); ++bool igc_is_device_id_i226(struct igc_hw *hw); + + /* Transmit Descriptor - Advanced */ + union igc_adv_tx_desc { +diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h +index 90ca01889cd82..efdabcbd66ddd 100644 +--- a/drivers/net/ethernet/intel/igc/igc_defines.h ++++ b/drivers/net/ethernet/intel/igc/igc_defines.h +@@ -515,6 +515,7 @@ + /* Transmit Scheduling */ + #define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001 + #define IGC_TQAVCTRL_ENHANCED_QAV 0x00000008 ++#define IGC_TQAVCTRL_FUTSCDDIS 0x00000080 + + #define IGC_TXQCTL_QUEUE_MODE_LAUNCHT 0x00000001 + #define IGC_TXQCTL_STRICT_CYCLE 0x00000002 +diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c +index 9166fde40c772..e23b95edb05ef 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c ++++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c +@@ -67,6 +67,7 @@ static const struct igc_stats igc_gstrings_stats[] = { + IGC_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), + IGC_STAT("tx_lpi_counter", stats.tlpic), + IGC_STAT("rx_lpi_counter", stats.rlpic), ++ IGC_STAT("qbv_config_change_errors", qbv_config_change_errors), + }; + + #define IGC_NETDEV_STAT(_net_stat) { \ +diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c +index 1ac836a55cd31..4b6f882b380dc 100644 +--- a/drivers/net/ethernet/intel/igc/igc_main.c ++++ b/drivers/net/ethernet/intel/igc/igc_main.c +@@ -1606,9 +1606,10 @@ done: + * the other timer registers before skipping the + * timestamping request. + */ +- if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && +- !test_and_set_bit_lock(__IGC_PTP_TX_IN_PROGRESS, +- &adapter->state)) { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&adapter->ptp_tx_lock, flags); ++ if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && !adapter->ptp_tx_skb) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + tx_flags |= IGC_TX_FLAGS_TSTAMP; + +@@ -1617,6 +1618,8 @@ done: + } else { + adapter->tx_hwtstamp_skipped++; + } ++ ++ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); + } + + if (skb_vlan_tag_present(skb)) { +@@ -6035,6 +6038,7 @@ static bool validate_schedule(struct igc_adapter *adapter, + const struct tc_taprio_qopt_offload *qopt) + { + int queue_uses[IGC_MAX_TX_QUEUES] = { }; ++ struct igc_hw *hw = &adapter->hw; + struct timespec64 now; + size_t n; + +@@ -6047,8 +6051,10 @@ static bool validate_schedule(struct igc_adapter *adapter, + * in the future, it will hold all the packets until that + * time, causing a lot of TX Hangs, so to avoid that, we + * reject schedules that would start in the future. ++ * Note: Limitation above is no longer in i226. + */ +- if (!is_base_time_past(qopt->base_time, &now)) ++ if (!is_base_time_past(qopt->base_time, &now) && ++ igc_is_device_id_i225(hw)) + return false; + + for (n = 0; n < qopt->num_entries; n++) { +@@ -6103,6 +6109,7 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter) + + adapter->base_time = 0; + adapter->cycle_time = NSEC_PER_SEC; ++ adapter->qbv_config_change_errors = 0; + + for (i = 0; i < adapter->num_tx_queues; i++) { + struct igc_ring *ring = adapter->tx_ring[i]; +@@ -6118,6 +6125,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, + struct tc_taprio_qopt_offload *qopt) + { + bool queue_configured[IGC_MAX_TX_QUEUES] = { }; ++ struct igc_hw *hw = &adapter->hw; + u32 start_time = 0, end_time = 0; + size_t n; + int i; +@@ -6130,7 +6138,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, + if (qopt->base_time < 0) + return -ERANGE; + +- if (adapter->base_time) ++ if (igc_is_device_id_i225(hw) && adapter->base_time) + return -EALREADY; + + if (!validate_schedule(adapter, qopt)) +@@ -6283,6 +6291,8 @@ static int igc_setup_tc(struct net_device *dev, enum tc_setup_type type, + { + struct igc_adapter *adapter = netdev_priv(dev); + ++ adapter->tc_setup_type = type; ++ + switch (type) { + case TC_SETUP_QDISC_TAPRIO: + return igc_tsn_enable_qbv_scheduling(adapter, type_data); +diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c +index d96cdccdc1e1e..14cd7f995280d 100644 +--- a/drivers/net/ethernet/intel/igc/igc_ptp.c ++++ b/drivers/net/ethernet/intel/igc/igc_ptp.c +@@ -622,6 +622,7 @@ static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter, + return 0; + } + ++/* Requires adapter->ptp_tx_lock held by caller. */ + static void igc_ptp_tx_timeout(struct igc_adapter *adapter) + { + struct igc_hw *hw = &adapter->hw; +@@ -629,7 +630,6 @@ static void igc_ptp_tx_timeout(struct igc_adapter *adapter) + dev_kfree_skb_any(adapter->ptp_tx_skb); + adapter->ptp_tx_skb = NULL; + adapter->tx_hwtstamp_timeouts++; +- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state); + /* Clear the tx valid bit in TSYNCTXCTL register to enable interrupt. */ + rd32(IGC_TXSTMPH); + netdev_warn(adapter->netdev, "Tx timestamp timeout\n"); +@@ -637,20 +637,20 @@ static void igc_ptp_tx_timeout(struct igc_adapter *adapter) + + void igc_ptp_tx_hang(struct igc_adapter *adapter) + { +- bool timeout = time_is_before_jiffies(adapter->ptp_tx_start + +- IGC_PTP_TX_TIMEOUT); ++ unsigned long flags; + +- if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state)) +- return; ++ spin_lock_irqsave(&adapter->ptp_tx_lock, flags); + +- /* If we haven't received a timestamp within the timeout, it is +- * reasonable to assume that it will never occur, so we can unlock the +- * timestamp bit when this occurs. +- */ +- if (timeout) { +- cancel_work_sync(&adapter->ptp_tx_work); +- igc_ptp_tx_timeout(adapter); +- } ++ if (!adapter->ptp_tx_skb) ++ goto unlock; ++ ++ if (time_is_after_jiffies(adapter->ptp_tx_start + IGC_PTP_TX_TIMEOUT)) ++ goto unlock; ++ ++ igc_ptp_tx_timeout(adapter); ++ ++unlock: ++ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); + } + + /** +@@ -660,6 +660,8 @@ void igc_ptp_tx_hang(struct igc_adapter *adapter) + * If we were asked to do hardware stamping and such a time stamp is + * available, then it must have been for this skb here because we only + * allow only one such packet into the queue. ++ * ++ * Context: Expects adapter->ptp_tx_lock to be held by caller. + */ + static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) + { +@@ -695,13 +697,7 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) + shhwtstamps.hwtstamp = + ktime_add_ns(shhwtstamps.hwtstamp, adjust); + +- /* Clear the lock early before calling skb_tstamp_tx so that +- * applications are not woken up before the lock bit is clear. We use +- * a copy of the skb pointer to ensure other threads can't change it +- * while we're notifying the stack. +- */ + adapter->ptp_tx_skb = NULL; +- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state); + + /* Notify the stack and free the skb after we've unlocked */ + skb_tstamp_tx(skb, &shhwtstamps); +@@ -712,24 +708,33 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) + * igc_ptp_tx_work + * @work: pointer to work struct + * +- * This work function polls the TSYNCTXCTL valid bit to determine when a +- * timestamp has been taken for the current stored skb. ++ * This work function checks the TSYNCTXCTL valid bit to determine when ++ * a timestamp has been taken for the current stored skb. + */ + static void igc_ptp_tx_work(struct work_struct *work) + { + struct igc_adapter *adapter = container_of(work, struct igc_adapter, + ptp_tx_work); + struct igc_hw *hw = &adapter->hw; ++ unsigned long flags; + u32 tsynctxctl; + +- if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state)) +- return; ++ spin_lock_irqsave(&adapter->ptp_tx_lock, flags); ++ ++ if (!adapter->ptp_tx_skb) ++ goto unlock; + + tsynctxctl = rd32(IGC_TSYNCTXCTL); +- if (WARN_ON_ONCE(!(tsynctxctl & IGC_TSYNCTXCTL_TXTT_0))) +- return; ++ tsynctxctl &= IGC_TSYNCTXCTL_TXTT_0; ++ if (!tsynctxctl) { ++ WARN_ONCE(1, "Received a TSTAMP interrupt but no TSTAMP is ready.\n"); ++ goto unlock; ++ } + + igc_ptp_tx_hwtstamp(adapter); ++ ++unlock: ++ spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags); + } + + /** +@@ -978,6 +983,7 @@ void igc_ptp_init(struct igc_adapter *adapter) + return; + } + ++ spin_lock_init(&adapter->ptp_tx_lock); + spin_lock_init(&adapter->tmreg_lock); + INIT_WORK(&adapter->ptp_tx_work, igc_ptp_tx_work); + +@@ -1042,7 +1048,6 @@ void igc_ptp_suspend(struct igc_adapter *adapter) + cancel_work_sync(&adapter->ptp_tx_work); + dev_kfree_skb_any(adapter->ptp_tx_skb); + adapter->ptp_tx_skb = NULL; +- clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state); + + if (pci_device_is_present(adapter->pdev)) { + igc_ptp_time_save(adapter); +diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c +index 356c7455c5cee..725db36e399d2 100644 +--- a/drivers/net/ethernet/intel/igc/igc_tsn.c ++++ b/drivers/net/ethernet/intel/igc/igc_tsn.c +@@ -2,6 +2,7 @@ + /* Copyright (c) 2019 Intel Corporation */ + + #include "igc.h" ++#include "igc_hw.h" + #include "igc_tsn.h" + + static bool is_any_launchtime(struct igc_adapter *adapter) +@@ -62,7 +63,8 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter) + + tqavctrl = rd32(IGC_TQAVCTRL); + tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN | +- IGC_TQAVCTRL_ENHANCED_QAV); ++ IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS); ++ + wr32(IGC_TQAVCTRL, tqavctrl); + + for (i = 0; i < adapter->num_tx_queues; i++) { +@@ -82,25 +84,16 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter) + static int igc_tsn_enable_offload(struct igc_adapter *adapter) + { + struct igc_hw *hw = &adapter->hw; ++ bool tsn_mode_reconfig = false; + u32 tqavctrl, baset_l, baset_h; + u32 sec, nsec, cycle; + ktime_t base_time, systim; + int i; + +- cycle = adapter->cycle_time; +- base_time = adapter->base_time; +- + wr32(IGC_TSAUXC, 0); + wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN); + wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN); + +- tqavctrl = rd32(IGC_TQAVCTRL); +- tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV; +- wr32(IGC_TQAVCTRL, tqavctrl); +- +- wr32(IGC_QBVCYCLET_S, cycle); +- wr32(IGC_QBVCYCLET, cycle); +- + for (i = 0; i < adapter->num_tx_queues; i++) { + struct igc_ring *ring = adapter->tx_ring[i]; + u32 txqctl = 0; +@@ -203,21 +196,58 @@ skip_cbs: + wr32(IGC_TXQCTL(i), txqctl); + } + ++ tqavctrl = rd32(IGC_TQAVCTRL) & ~IGC_TQAVCTRL_FUTSCDDIS; ++ ++ if (tqavctrl & IGC_TQAVCTRL_TRANSMIT_MODE_TSN) ++ tsn_mode_reconfig = true; ++ ++ tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV; ++ ++ cycle = adapter->cycle_time; ++ base_time = adapter->base_time; ++ + nsec = rd32(IGC_SYSTIML); + sec = rd32(IGC_SYSTIMH); + + systim = ktime_set(sec, nsec); +- + if (ktime_compare(systim, base_time) > 0) { +- s64 n; ++ s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle); + +- n = div64_s64(ktime_sub_ns(systim, base_time), cycle); + base_time = ktime_add_ns(base_time, (n + 1) * cycle); ++ ++ /* Increase the counter if scheduling into the past while ++ * Gate Control List (GCL) is running. ++ */ ++ if ((rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) && ++ (adapter->tc_setup_type == TC_SETUP_QDISC_TAPRIO) && ++ tsn_mode_reconfig) ++ adapter->qbv_config_change_errors++; ++ } else { ++ /* According to datasheet section 7.5.2.9.3.3, FutScdDis bit ++ * has to be configured before the cycle time and base time. ++ * Tx won't hang if there is a GCL is already running, ++ * so in this case we don't need to set FutScdDis. ++ */ ++ if (igc_is_device_id_i226(hw) && ++ !(rd32(IGC_BASET_H) || rd32(IGC_BASET_L))) ++ tqavctrl |= IGC_TQAVCTRL_FUTSCDDIS; + } + +- baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l); ++ wr32(IGC_TQAVCTRL, tqavctrl); + ++ wr32(IGC_QBVCYCLET_S, cycle); ++ wr32(IGC_QBVCYCLET, cycle); ++ ++ baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l); + wr32(IGC_BASET_H, baset_h); ++ ++ /* In i226, Future base time is only supported when FutScdDis bit ++ * is enabled and only active for re-configuration. ++ * In this case, initialize the base time with zero to create ++ * "re-configuration" scenario then only set the desired base time. ++ */ ++ if (tqavctrl & IGC_TQAVCTRL_FUTSCDDIS) ++ wr32(IGC_BASET_L, 0); + wr32(IGC_BASET_L, baset_l); + + return 0; +@@ -244,17 +274,14 @@ int igc_tsn_reset(struct igc_adapter *adapter) + + int igc_tsn_offload_apply(struct igc_adapter *adapter) + { +- int err; ++ struct igc_hw *hw = &adapter->hw; + +- if (netif_running(adapter->netdev)) { ++ if (netif_running(adapter->netdev) && igc_is_device_id_i225(hw)) { + schedule_work(&adapter->reset_task); + return 0; + } + +- err = igc_tsn_enable_offload(adapter); +- if (err < 0) +- return err; ++ igc_tsn_reset(adapter); + +- adapter->flags = igc_tsn_new_flags(adapter); + return 0; + } +diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +index 61354f7985035..e171097c13654 100644 +--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c ++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +@@ -707,20 +707,19 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb, + hw_desc->dptr = tx_buffer->sglist_dma; + } + +- /* Flush the hw descriptor before writing to doorbell */ +- wmb(); +- +- /* Ring Doorbell to notify the NIC there is a new packet */ +- writel(1, iq->doorbell_reg); ++ netdev_tx_sent_queue(iq->netdev_q, skb->len); ++ skb_tx_timestamp(skb); + atomic_inc(&iq->instr_pending); + wi++; + if (wi == iq->max_count) + wi = 0; + iq->host_write_index = wi; ++ /* Flush the hw descriptor before writing to doorbell */ ++ wmb(); + +- netdev_tx_sent_queue(iq->netdev_q, skb->len); ++ /* Ring Doorbell to notify the NIC there is a new packet */ ++ writel(1, iq->doorbell_reg); + iq->stats.instr_posted++; +- skb_tx_timestamp(skb); + return NETDEV_TX_OK; + + dma_map_sg_err: +diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h +index ddec1627f1a7b..8d0bacf4e49cc 100644 +--- a/drivers/net/ethernet/marvell/sky2.h ++++ b/drivers/net/ethernet/marvell/sky2.h +@@ -2195,7 +2195,7 @@ struct rx_ring_info { + struct sk_buff *skb; + dma_addr_t data_addr; + DEFINE_DMA_UNMAP_LEN(data_size); +- dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; ++ dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT ?: 1]; + }; + + enum flow_control { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +index c4e40834e3ff9..374c0011a127b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +@@ -821,7 +821,7 @@ static void mlx5_fw_tracer_ownership_change(struct work_struct *work) + + mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner); + if (tracer->owner) { +- tracer->owner = false; ++ mlx5_fw_tracer_ownership_acquire(tracer); + return; + } + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +index cd15d36b1507e..907ad6ffe7275 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +@@ -23,7 +23,8 @@ static int mlx5e_set_int_port_tunnel(struct mlx5e_priv *priv, + + route_dev = dev_get_by_index(dev_net(e->out_dev), e->route_dev_ifindex); + +- if (!route_dev || !netif_is_ovs_master(route_dev)) ++ if (!route_dev || !netif_is_ovs_master(route_dev) || ++ attr->parse_attr->filter_dev == e->out_dev) + goto out; + + err = mlx5e_set_fwd_to_int_port_actions(priv, attr, e->route_dev_ifindex, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +index 4b9d567c8f473..48939c72b5925 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +@@ -969,11 +969,8 @@ const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) + return ERR_PTR(err); + } + +-static void mlx5_eswitch_event_handlers_register(struct mlx5_eswitch *esw) ++static void mlx5_eswitch_event_handler_register(struct mlx5_eswitch *esw) + { +- MLX5_NB_INIT(&esw->nb, eswitch_vport_event, NIC_VPORT_CHANGE); +- mlx5_eq_notifier_register(esw->dev, &esw->nb); +- + if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) { + MLX5_NB_INIT(&esw->esw_funcs.nb, mlx5_esw_funcs_changed_handler, + ESW_FUNCTIONS_CHANGED); +@@ -981,13 +978,11 @@ static void mlx5_eswitch_event_handlers_register(struct mlx5_eswitch *esw) + } + } + +-static void mlx5_eswitch_event_handlers_unregister(struct mlx5_eswitch *esw) ++static void mlx5_eswitch_event_handler_unregister(struct mlx5_eswitch *esw) + { + if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) + mlx5_eq_notifier_unregister(esw->dev, &esw->esw_funcs.nb); + +- mlx5_eq_notifier_unregister(esw->dev, &esw->nb); +- + flush_workqueue(esw->work_queue); + } + +@@ -1273,6 +1268,9 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) + + mlx5_eswitch_update_num_of_vfs(esw, num_vfs); + ++ MLX5_NB_INIT(&esw->nb, eswitch_vport_event, NIC_VPORT_CHANGE); ++ mlx5_eq_notifier_register(esw->dev, &esw->nb); ++ + if (esw->mode == MLX5_ESWITCH_LEGACY) { + err = esw_legacy_enable(esw); + } else { +@@ -1285,7 +1283,7 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) + + esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED; + +- mlx5_eswitch_event_handlers_register(esw); ++ mlx5_eswitch_event_handler_register(esw); + + esw_info(esw->dev, "Enable: mode(%s), nvfs(%d), active vports(%d)\n", + esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", +@@ -1394,7 +1392,8 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw) + */ + mlx5_esw_mode_change_notify(esw, MLX5_ESWITCH_LEGACY); + +- mlx5_eswitch_event_handlers_unregister(esw); ++ mlx5_eq_notifier_unregister(esw->dev, &esw->nb); ++ mlx5_eswitch_event_handler_unregister(esw); + + esw_info(esw->dev, "Disable: mode(%s), nvfs(%d), active vports(%d)\n", + esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", +diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c +index ed274f033626d..810df65cdf085 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c +@@ -113,7 +113,10 @@ static void qed_ll2b_complete_tx_packet(void *cxt, + static int qed_ll2_alloc_buffer(struct qed_dev *cdev, + u8 **data, dma_addr_t *phys_addr) + { +- *data = kmalloc(cdev->ll2->rx_size, GFP_ATOMIC); ++ size_t size = cdev->ll2->rx_size + NET_SKB_PAD + ++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ ++ *data = kmalloc(size, GFP_ATOMIC); + if (!(*data)) { + DP_INFO(cdev, "Failed to allocate LL2 buffer data\n"); + return -ENOMEM; +@@ -2590,7 +2593,7 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params) + INIT_LIST_HEAD(&cdev->ll2->list); + spin_lock_init(&cdev->ll2->lock); + +- cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN + ++ cdev->ll2->rx_size = PRM_DMA_PAD_BYTES_NUM + ETH_HLEN + + L1_CACHE_BYTES + params->mtu; + + /* Allocate memory for LL2. +diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c +index 6cebf3aaa621f..dc5b27cb48fb0 100644 +--- a/drivers/net/phy/bcm7xxx.c ++++ b/drivers/net/phy/bcm7xxx.c +@@ -907,6 +907,9 @@ static void bcm7xxx_28nm_remove(struct phy_device *phydev) + .name = _name, \ + /* PHY_BASIC_FEATURES */ \ + .flags = PHY_IS_INTERNAL, \ ++ .get_sset_count = bcm_phy_get_sset_count, \ ++ .get_strings = bcm_phy_get_strings, \ ++ .get_stats = bcm7xxx_28nm_get_phy_stats, \ + .probe = bcm7xxx_28nm_probe, \ + .remove = bcm7xxx_28nm_remove, \ + .config_init = bcm7xxx_16nm_ephy_config_init, \ +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 7544df1ff50ec..d373953ddc300 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -3056,10 +3056,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, + struct net *net = sock_net(&tfile->sk); + struct tun_struct *tun; + void __user* argp = (void __user*)arg; +- unsigned int ifindex, carrier; ++ unsigned int carrier; + struct ifreq ifr; + kuid_t owner; + kgid_t group; ++ int ifindex; + int sndbuf; + int vnet_hdr_sz; + int le; +@@ -3115,7 +3116,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, + ret = -EFAULT; + if (copy_from_user(&ifindex, argp, sizeof(ifindex))) + goto unlock; +- ++ ret = -EINVAL; ++ if (ifindex < 0) ++ goto unlock; + ret = 0; + tfile->ifindex = ifindex; + goto unlock; +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index 563ecd27b93ea..17da42fe605c3 100644 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -897,7 +897,7 @@ static int smsc95xx_reset(struct usbnet *dev) + + if (timeout >= 100) { + netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n"); +- return ret; ++ return -ETIMEDOUT; + } + + ret = smsc95xx_set_mac_address(dev); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index 542cfcad6e0e6..2d01f6226b7c6 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -1585,6 +1585,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, + iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); + + memset(&info->status, 0, sizeof(info->status)); ++ info->flags &= ~(IEEE80211_TX_STAT_ACK | IEEE80211_TX_STAT_TX_FILTERED); + + /* inform mac80211 about what happened with the frame */ + switch (status & TX_STATUS_MSK) { +@@ -1936,6 +1937,8 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, + */ + if (!is_flush) + info->flags |= IEEE80211_TX_STAT_ACK; ++ else ++ info->flags &= ~IEEE80211_TX_STAT_ACK; + } + + /* +diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +index 7351acac6932d..54ab8b54369ba 100644 +--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c ++++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +@@ -921,6 +921,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, + while (tlv_buf_left >= sizeof(*tlv_rxba)) { + tlv_type = le16_to_cpu(tlv_rxba->header.type); + tlv_len = le16_to_cpu(tlv_rxba->header.len); ++ if (size_add(sizeof(tlv_rxba->header), tlv_len) > tlv_buf_left) { ++ mwifiex_dbg(priv->adapter, WARN, ++ "TLV size (%zu) overflows event_buf buf_left=%d\n", ++ size_add(sizeof(tlv_rxba->header), tlv_len), ++ tlv_buf_left); ++ return; ++ } ++ + if (tlv_type != TLV_TYPE_RXBA_SYNC) { + mwifiex_dbg(priv->adapter, ERROR, + "Wrong TLV id=0x%x\n", tlv_type); +@@ -929,6 +937,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, + + tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num); + tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len); ++ if (size_add(sizeof(*tlv_rxba), tlv_bitmap_len) > tlv_buf_left) { ++ mwifiex_dbg(priv->adapter, WARN, ++ "TLV size (%zu) overflows event_buf buf_left=%d\n", ++ size_add(sizeof(*tlv_rxba), tlv_bitmap_len), ++ tlv_buf_left); ++ return; ++ } ++ + mwifiex_dbg(priv->adapter, INFO, + "%pM tid=%d seq_num=%d bitmap_len=%d\n", + tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num, +diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c +index 8224675f8de25..b33004a4bcb5a 100644 +--- a/drivers/nvme/host/ioctl.c ++++ b/drivers/nvme/host/ioctl.c +@@ -32,9 +32,13 @@ static void *nvme_add_user_metadata(struct request *req, void __user *ubuf, + if (!buf) + goto out; + +- ret = -EFAULT; +- if ((req_op(req) == REQ_OP_DRV_OUT) && copy_from_user(buf, ubuf, len)) +- goto out_free_meta; ++ if (req_op(req) == REQ_OP_DRV_OUT) { ++ ret = -EFAULT; ++ if (copy_from_user(buf, ubuf, len)) ++ goto out_free_meta; ++ } else { ++ memset(buf, 0, len); ++ } + + bip = bio_integrity_alloc(bio, GFP_KERNEL, 1); + if (IS_ERR(bip)) { +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 64990a2cfd0a7..886c3fc9578e4 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3439,7 +3439,8 @@ static const struct pci_device_id nvme_id_table[] = { + { PCI_VDEVICE(INTEL, 0x0a54), /* Intel P4500/P4600 */ + .driver_data = NVME_QUIRK_STRIPE_SIZE | + NVME_QUIRK_DEALLOCATE_ZEROES | +- NVME_QUIRK_IGNORE_DEV_SUBNQN, }, ++ NVME_QUIRK_IGNORE_DEV_SUBNQN | ++ NVME_QUIRK_BOGUS_NID, }, + { PCI_VDEVICE(INTEL, 0x0a55), /* Dell Express Flash P4600 */ + .driver_data = NVME_QUIRK_STRIPE_SIZE | + NVME_QUIRK_DEALLOCATE_ZEROES, }, +diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c +index c478480f54aa2..aa1734e2fd44e 100644 +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -643,6 +643,9 @@ static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) + + static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) + { ++ if (!test_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags)) ++ return; ++ + mutex_lock(&queue->queue_lock); + if (test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) + __nvme_rdma_stop_queue(queue); +diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c +index 7970a7640e585..fbae76cdc2546 100644 +--- a/drivers/nvme/target/fabrics-cmd-auth.c ++++ b/drivers/nvme/target/fabrics-cmd-auth.c +@@ -337,19 +337,21 @@ done: + __func__, ctrl->cntlid, req->sq->qid, + status, req->error_loc); + req->cqe->result.u64 = 0; +- nvmet_req_complete(req, status); + if (req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2 && + req->sq->dhchap_step != NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) { + unsigned long auth_expire_secs = ctrl->kato ? ctrl->kato : 120; + + mod_delayed_work(system_wq, &req->sq->auth_expired_work, + auth_expire_secs * HZ); +- return; ++ goto complete; + } + /* Final states, clear up variables */ + nvmet_auth_sq_free(req->sq); + if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE2) + nvmet_ctrl_fatal_error(ctrl); ++ ++complete: ++ nvmet_req_complete(req, status); + } + + static int nvmet_auth_challenge(struct nvmet_req *req, void *d, int al) +@@ -527,11 +529,12 @@ void nvmet_execute_auth_receive(struct nvmet_req *req) + kfree(d); + done: + req->cqe->result.u64 = 0; +- nvmet_req_complete(req, status); ++ + if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_SUCCESS2) + nvmet_auth_sq_free(req->sq); + else if (req->sq->dhchap_step == NVME_AUTH_DHCHAP_MESSAGE_FAILURE1) { + nvmet_auth_sq_free(req->sq); + nvmet_ctrl_fatal_error(ctrl); + } ++ nvmet_req_complete(req, status); + } +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 5e29da94f72d6..355d80323b836 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -345,6 +345,7 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue) + + static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status) + { ++ queue->rcv_state = NVMET_TCP_RECV_ERR; + if (status == -EPIPE || status == -ECONNRESET) + kernel_sock_shutdown(queue->sock, SHUT_RDWR); + else +@@ -871,15 +872,11 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue) + iov.iov_len = sizeof(*icresp); + ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len); + if (ret < 0) +- goto free_crypto; ++ return ret; /* queue removal will cleanup */ + + queue->state = NVMET_TCP_Q_LIVE; + nvmet_prepare_receive_pdu(queue); + return 0; +-free_crypto: +- if (queue->hdr_digest || queue->data_digest) +- nvmet_tcp_free_crypto(queue); +- return ret; + } + + static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue, +diff --git a/drivers/phy/motorola/phy-mapphone-mdm6600.c b/drivers/phy/motorola/phy-mapphone-mdm6600.c +index 3cd4d51c247c3..67802f9e40ba0 100644 +--- a/drivers/phy/motorola/phy-mapphone-mdm6600.c ++++ b/drivers/phy/motorola/phy-mapphone-mdm6600.c +@@ -122,16 +122,10 @@ static int phy_mdm6600_power_on(struct phy *x) + { + struct phy_mdm6600 *ddata = phy_get_drvdata(x); + struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE]; +- int error; + + if (!ddata->enabled) + return -ENODEV; + +- error = pinctrl_pm_select_default_state(ddata->dev); +- if (error) +- dev_warn(ddata->dev, "%s: error with default_state: %i\n", +- __func__, error); +- + gpiod_set_value_cansleep(enable_gpio, 1); + + /* Allow aggressive PM for USB, it's only needed for n_gsm port */ +@@ -160,11 +154,6 @@ static int phy_mdm6600_power_off(struct phy *x) + + gpiod_set_value_cansleep(enable_gpio, 0); + +- error = pinctrl_pm_select_sleep_state(ddata->dev); +- if (error) +- dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", +- __func__, error); +- + return 0; + } + +@@ -456,6 +445,7 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata) + { + struct gpio_desc *reset_gpio = + ddata->ctrl_gpios[PHY_MDM6600_RESET]; ++ int error; + + ddata->enabled = false; + phy_mdm6600_cmd(ddata, PHY_MDM6600_CMD_BP_SHUTDOWN_REQ); +@@ -471,6 +461,17 @@ static void phy_mdm6600_device_power_off(struct phy_mdm6600 *ddata) + } else { + dev_err(ddata->dev, "Timed out powering down\n"); + } ++ ++ /* ++ * Keep reset gpio high with padconf internal pull-up resistor to ++ * prevent modem from waking up during deeper SoC idle states. The ++ * gpio bank lines can have glitches if not in the always-on wkup ++ * domain. ++ */ ++ error = pinctrl_pm_select_sleep_state(ddata->dev); ++ if (error) ++ dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", ++ __func__, error); + } + + static void phy_mdm6600_deferred_power_on(struct work_struct *work) +@@ -571,12 +572,6 @@ static int phy_mdm6600_probe(struct platform_device *pdev) + ddata->dev = &pdev->dev; + platform_set_drvdata(pdev, ddata); + +- /* Active state selected in phy_mdm6600_power_on() */ +- error = pinctrl_pm_select_sleep_state(ddata->dev); +- if (error) +- dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", +- __func__, error); +- + error = phy_mdm6600_init_lines(ddata); + if (error) + return error; +@@ -627,10 +622,12 @@ idle: + pm_runtime_put_autosuspend(ddata->dev); + + cleanup: +- if (error < 0) ++ if (error < 0) { + phy_mdm6600_device_power_off(ddata); +- pm_runtime_disable(ddata->dev); +- pm_runtime_dont_use_autosuspend(ddata->dev); ++ pm_runtime_disable(ddata->dev); ++ pm_runtime_dont_use_autosuspend(ddata->dev); ++ } ++ + return error; + } + +@@ -639,6 +636,7 @@ static int phy_mdm6600_remove(struct platform_device *pdev) + struct phy_mdm6600 *ddata = platform_get_drvdata(pdev); + struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET]; + ++ pm_runtime_get_noresume(ddata->dev); + pm_runtime_dont_use_autosuspend(ddata->dev); + pm_runtime_put_sync(ddata->dev); + pm_runtime_disable(ddata->dev); +diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c +index 27e41873c04ff..9e57f4c62e609 100644 +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -1007,20 +1007,17 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev, + + static struct pinctrl *find_pinctrl(struct device *dev) + { +- struct pinctrl *entry, *p = NULL; ++ struct pinctrl *p; + + mutex_lock(&pinctrl_list_mutex); +- +- list_for_each_entry(entry, &pinctrl_list, node) { +- if (entry->dev == dev) { +- p = entry; +- kref_get(&p->users); +- break; ++ list_for_each_entry(p, &pinctrl_list, node) ++ if (p->dev == dev) { ++ mutex_unlock(&pinctrl_list_mutex); ++ return p; + } +- } + + mutex_unlock(&pinctrl_list_mutex); +- return p; ++ return NULL; + } + + static void pinctrl_free(struct pinctrl *p, bool inlist); +@@ -1129,6 +1126,7 @@ struct pinctrl *pinctrl_get(struct device *dev) + p = find_pinctrl(dev); + if (p) { + dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n"); ++ kref_get(&p->users); + return p; + } + +diff --git a/drivers/platform/surface/surface_platform_profile.c b/drivers/platform/surface/surface_platform_profile.c +index fbf2e11fd6ce7..37c761f577149 100644 +--- a/drivers/platform/surface/surface_platform_profile.c ++++ b/drivers/platform/surface/surface_platform_profile.c +@@ -159,8 +159,7 @@ static int surface_platform_profile_probe(struct ssam_device *sdev) + set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, tpd->handler.choices); + set_bit(PLATFORM_PROFILE_PERFORMANCE, tpd->handler.choices); + +- platform_profile_register(&tpd->handler); +- return 0; ++ return platform_profile_register(&tpd->handler); + } + + static void surface_platform_profile_remove(struct ssam_device *sdev) +diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c +index d85d895fee894..df1db54d4e183 100644 +--- a/drivers/platform/x86/asus-nb-wmi.c ++++ b/drivers/platform/x86/asus-nb-wmi.c +@@ -531,6 +531,9 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) + static const struct key_entry asus_nb_wmi_keymap[] = { + { KE_KEY, ASUS_WMI_BRN_DOWN, { KEY_BRIGHTNESSDOWN } }, + { KE_KEY, ASUS_WMI_BRN_UP, { KEY_BRIGHTNESSUP } }, ++ { KE_KEY, 0x2a, { KEY_SELECTIVE_SCREENSHOT } }, ++ { KE_IGNORE, 0x2b, }, /* PrintScreen (also send via PS/2) on newer models */ ++ { KE_IGNORE, 0x2c, }, /* CapsLock (also send via PS/2) on newer models */ + { KE_KEY, 0x30, { KEY_VOLUMEUP } }, + { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, + { KE_KEY, 0x32, { KEY_MUTE } }, +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 36effe04c6f33..49dd55b8e8faf 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -3268,7 +3268,6 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) + { + unsigned int key_value = 1; + bool autorelease = 1; +- int orig_code = code; + + if (asus->driver->key_filter) { + asus->driver->key_filter(asus->driver, &code, &key_value, +@@ -3277,16 +3276,10 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) + return; + } + +- if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) +- code = ASUS_WMI_BRN_UP; +- else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX) +- code = ASUS_WMI_BRN_DOWN; +- +- if (code == ASUS_WMI_BRN_DOWN || code == ASUS_WMI_BRN_UP) { +- if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { +- asus_wmi_backlight_notify(asus, orig_code); +- return; +- } ++ if (acpi_video_get_backlight_type() == acpi_backlight_vendor && ++ code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNDOWN_MAX) { ++ asus_wmi_backlight_notify(asus, code); ++ return; + } + + if (code == NOTIFY_KBD_BRTUP) { +diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h +index a478ebfd34dfa..fc41d1b1bb7f8 100644 +--- a/drivers/platform/x86/asus-wmi.h ++++ b/drivers/platform/x86/asus-wmi.h +@@ -18,7 +18,7 @@ + #include <linux/i8042.h> + + #define ASUS_WMI_KEY_IGNORE (-1) +-#define ASUS_WMI_BRN_DOWN 0x20 ++#define ASUS_WMI_BRN_DOWN 0x2e + #define ASUS_WMI_BRN_UP 0x2f + + struct module; +diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +index fa8f14c925ec3..9b12fe8e95c91 100644 +--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c ++++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +@@ -153,7 +153,7 @@ show_uncore_data(initial_max_freq_khz); + + static int create_attr_group(struct uncore_data *data, char *name) + { +- int ret, index = 0; ++ int ret, freq, index = 0; + + init_attribute_rw(max_freq_khz); + init_attribute_rw(min_freq_khz); +@@ -165,7 +165,11 @@ static int create_attr_group(struct uncore_data *data, char *name) + data->uncore_attrs[index++] = &data->min_freq_khz_dev_attr.attr; + data->uncore_attrs[index++] = &data->initial_min_freq_khz_dev_attr.attr; + data->uncore_attrs[index++] = &data->initial_max_freq_khz_dev_attr.attr; +- data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr; ++ ++ ret = uncore_read_freq(data, &freq); ++ if (!ret) ++ data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr; ++ + data->uncore_attrs[index] = NULL; + + data->uncore_attr_group.name = name; +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index 68e66b60445c3..9a92d515abb9b 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -740,6 +740,21 @@ static const struct ts_dmi_data pipo_w11_data = { + .properties = pipo_w11_props, + }; + ++static const struct property_entry positivo_c4128b_props[] = { ++ PROPERTY_ENTRY_U32("touchscreen-min-x", 4), ++ PROPERTY_ENTRY_U32("touchscreen-min-y", 13), ++ PROPERTY_ENTRY_U32("touchscreen-size-x", 1915), ++ PROPERTY_ENTRY_U32("touchscreen-size-y", 1269), ++ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-positivo-c4128b.fw"), ++ PROPERTY_ENTRY_U32("silead,max-fingers", 10), ++ { } ++}; ++ ++static const struct ts_dmi_data positivo_c4128b_data = { ++ .acpi_name = "MSSL1680:00", ++ .properties = positivo_c4128b_props, ++}; ++ + static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 32), + PROPERTY_ENTRY_U32("touchscreen-min-y", 16), +@@ -1457,6 +1472,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"), + }, + }, ++ { ++ /* Positivo C4128B */ ++ .driver_data = (void *)&positivo_c4128b_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C4128B-1"), ++ }, ++ }, + { + /* Point of View mobii wintab p800w (v2.0) */ + .driver_data = (void *)&pov_mobii_wintab_p800w_v20_data, +diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig +index a8c46ba5878fe..54201f0374104 100644 +--- a/drivers/power/reset/Kconfig ++++ b/drivers/power/reset/Kconfig +@@ -299,7 +299,7 @@ config NVMEM_REBOOT_MODE + + config POWER_MLXBF + tristate "Mellanox BlueField power handling driver" +- depends on (GPIO_MLXBF2 && ACPI) ++ depends on (GPIO_MLXBF2 || GPIO_MLXBF3) && ACPI + help + This driver supports reset or low power mode handling for Mellanox BlueField. + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index f6a95f72af18d..34d3d82819064 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -5725,15 +5725,11 @@ wash: + mutex_lock(®ulator_list_mutex); + regulator_ena_gpio_free(rdev); + mutex_unlock(®ulator_list_mutex); +- put_device(&rdev->dev); +- rdev = NULL; + clean: + if (dangling_of_gpiod) + gpiod_put(config->ena_gpiod); +- if (rdev && rdev->dev.of_node) +- of_node_put(rdev->dev.of_node); +- kfree(rdev); + kfree(config); ++ put_device(&rdev->dev); + rinse: + if (dangling_cfg_gpiod) + gpiod_put(cfg->ena_gpiod); +diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c +index c7db953985002..98a14c1f3d672 100644 +--- a/drivers/s390/cio/css.c ++++ b/drivers/s390/cio/css.c +@@ -233,17 +233,19 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid, + */ + ret = dma_set_coherent_mask(&sch->dev, DMA_BIT_MASK(31)); + if (ret) +- goto err; ++ goto err_lock; + /* + * But we don't have such restrictions imposed on the stuff that + * is handled by the streaming API. + */ + ret = dma_set_mask(&sch->dev, DMA_BIT_MASK(64)); + if (ret) +- goto err; ++ goto err_lock; + + return sch; + ++err_lock: ++ kfree(sch->lock); + err: + kfree(sch); + return ERR_PTR(ret); +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index adc85e250822c..2e21f74a24705 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -32,6 +32,7 @@ + #include "8250.h" + + #define DEFAULT_CLK_SPEED 48000000 ++#define OMAP_UART_REGSHIFT 2 + + #define UART_ERRATA_i202_MDR1_ACCESS (1 << 0) + #define OMAP_UART_WER_HAS_TX_WAKEUP (1 << 1) +@@ -109,6 +110,7 @@ + #define UART_OMAP_RX_LVL 0x19 + + struct omap8250_priv { ++ void __iomem *membase; + int line; + u8 habit; + u8 mdr1; +@@ -152,9 +154,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p); + static inline void omap_8250_rx_dma_flush(struct uart_8250_port *p) { } + #endif + +-static u32 uart_read(struct uart_8250_port *up, u32 reg) ++static u32 uart_read(struct omap8250_priv *priv, u32 reg) + { +- return readl(up->port.membase + (reg << up->port.regshift)); ++ return readl(priv->membase + (reg << OMAP_UART_REGSHIFT)); + } + + /* +@@ -538,7 +540,7 @@ static void omap_serial_fill_features_erratas(struct uart_8250_port *up, + u32 mvr, scheme; + u16 revision, major, minor; + +- mvr = uart_read(up, UART_OMAP_MVER); ++ mvr = uart_read(priv, UART_OMAP_MVER); + + /* Check revision register scheme */ + scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT; +@@ -1319,7 +1321,7 @@ static int omap8250_probe(struct platform_device *pdev) + UPF_HARD_FLOW; + up.port.private_data = priv; + +- up.port.regshift = 2; ++ up.port.regshift = OMAP_UART_REGSHIFT; + up.port.fifosize = 64; + up.tx_loadsz = 64; + up.capabilities = UART_CAP_FIFO; +@@ -1381,6 +1383,8 @@ static int omap8250_probe(struct platform_device *pdev) + DEFAULT_CLK_SPEED); + } + ++ priv->membase = membase; ++ priv->line = -ENODEV; + priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; + priv->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; + cpu_latency_qos_add_request(&priv->pm_qos_request, priv->latency); +@@ -1388,6 +1392,8 @@ static int omap8250_probe(struct platform_device *pdev) + + spin_lock_init(&priv->rx_dma_lock); + ++ platform_set_drvdata(pdev, priv); ++ + device_init_wakeup(&pdev->dev, true); + pm_runtime_enable(&pdev->dev); + pm_runtime_use_autosuspend(&pdev->dev); +@@ -1449,7 +1455,6 @@ static int omap8250_probe(struct platform_device *pdev) + goto err; + } + priv->line = ret; +- platform_set_drvdata(pdev, priv); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + return 0; +@@ -1471,17 +1476,17 @@ static int omap8250_remove(struct platform_device *pdev) + if (err) + return err; + ++ serial8250_unregister_port(priv->line); ++ priv->line = -ENODEV; + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); + flush_work(&priv->qos_work); + pm_runtime_disable(&pdev->dev); +- serial8250_unregister_port(priv->line); + cpu_latency_qos_remove_request(&priv->pm_qos_request); + device_init_wakeup(&pdev->dev, false); + return 0; + } + +-#ifdef CONFIG_PM_SLEEP + static int omap8250_prepare(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); +@@ -1505,7 +1510,7 @@ static int omap8250_suspend(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); + struct uart_8250_port *up = serial8250_get_port(priv->line); +- int err; ++ int err = 0; + + serial8250_suspend_port(priv->line); + +@@ -1515,7 +1520,8 @@ static int omap8250_suspend(struct device *dev) + if (!device_may_wakeup(dev)) + priv->wer = 0; + serial_out(up, UART_OMAP_WER, priv->wer); +- err = pm_runtime_force_suspend(dev); ++ if (uart_console(&up->port) && console_suspend_enabled) ++ err = pm_runtime_force_suspend(dev); + flush_work(&priv->qos_work); + + return err; +@@ -1524,11 +1530,15 @@ static int omap8250_suspend(struct device *dev) + static int omap8250_resume(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); ++ struct uart_8250_port *up = serial8250_get_port(priv->line); + int err; + +- err = pm_runtime_force_resume(dev); +- if (err) +- return err; ++ if (uart_console(&up->port) && console_suspend_enabled) { ++ err = pm_runtime_force_resume(dev); ++ if (err) ++ return err; ++ } ++ + serial8250_resume_port(priv->line); + /* Paired with pm_runtime_resume_and_get() in omap8250_suspend() */ + pm_runtime_mark_last_busy(dev); +@@ -1536,12 +1546,7 @@ static int omap8250_resume(struct device *dev) + + return 0; + } +-#else +-#define omap8250_prepare NULL +-#define omap8250_complete NULL +-#endif + +-#ifdef CONFIG_PM + static int omap8250_lost_context(struct uart_8250_port *up) + { + u32 val; +@@ -1557,11 +1562,15 @@ static int omap8250_lost_context(struct uart_8250_port *up) + return 0; + } + ++static void uart_write(struct omap8250_priv *priv, u32 reg, u32 val) ++{ ++ writel(val, priv->membase + (reg << OMAP_UART_REGSHIFT)); ++} ++ + /* TODO: in future, this should happen via API in drivers/reset/ */ + static int omap8250_soft_reset(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); +- struct uart_8250_port *up = serial8250_get_port(priv->line); + int timeout = 100; + int sysc; + int syss; +@@ -1575,20 +1584,20 @@ static int omap8250_soft_reset(struct device *dev) + * needing omap8250_soft_reset() quirk. Do it in two writes as + * recommended in the comment for omap8250_update_scr(). + */ +- serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1); +- serial_out(up, UART_OMAP_SCR, ++ uart_write(priv, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1); ++ uart_write(priv, UART_OMAP_SCR, + OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL); + +- sysc = serial_in(up, UART_OMAP_SYSC); ++ sysc = uart_read(priv, UART_OMAP_SYSC); + + /* softreset the UART */ + sysc |= OMAP_UART_SYSC_SOFTRESET; +- serial_out(up, UART_OMAP_SYSC, sysc); ++ uart_write(priv, UART_OMAP_SYSC, sysc); + + /* By experiments, 1us enough for reset complete on AM335x */ + do { + udelay(1); +- syss = serial_in(up, UART_OMAP_SYSS); ++ syss = uart_read(priv, UART_OMAP_SYSS); + } while (--timeout && !(syss & OMAP_UART_SYSS_RESETDONE)); + + if (!timeout) { +@@ -1602,23 +1611,10 @@ static int omap8250_soft_reset(struct device *dev) + static int omap8250_runtime_suspend(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); +- struct uart_8250_port *up; ++ struct uart_8250_port *up = NULL; + +- /* In case runtime-pm tries this before we are setup */ +- if (!priv) +- return 0; +- +- up = serial8250_get_port(priv->line); +- /* +- * When using 'no_console_suspend', the console UART must not be +- * suspended. Since driver suspend is managed by runtime suspend, +- * preventing runtime suspend (by returning error) will keep device +- * active during suspend. +- */ +- if (priv->is_suspending && !console_suspend_enabled) { +- if (uart_console(&up->port)) +- return -EBUSY; +- } ++ if (priv->line >= 0) ++ up = serial8250_get_port(priv->line); + + if (priv->habit & UART_ERRATA_CLOCK_DISABLE) { + int ret; +@@ -1627,13 +1623,15 @@ static int omap8250_runtime_suspend(struct device *dev) + if (ret) + return ret; + +- /* Restore to UART mode after reset (for wakeup) */ +- omap8250_update_mdr1(up, priv); +- /* Restore wakeup enable register */ +- serial_out(up, UART_OMAP_WER, priv->wer); ++ if (up) { ++ /* Restore to UART mode after reset (for wakeup) */ ++ omap8250_update_mdr1(up, priv); ++ /* Restore wakeup enable register */ ++ serial_out(up, UART_OMAP_WER, priv->wer); ++ } + } + +- if (up->dma && up->dma->rxchan) ++ if (up && up->dma && up->dma->rxchan) + omap_8250_rx_dma_flush(up); + + priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; +@@ -1645,25 +1643,21 @@ static int omap8250_runtime_suspend(struct device *dev) + static int omap8250_runtime_resume(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); +- struct uart_8250_port *up; ++ struct uart_8250_port *up = NULL; + +- /* In case runtime-pm tries this before we are setup */ +- if (!priv) +- return 0; +- +- up = serial8250_get_port(priv->line); ++ if (priv->line >= 0) ++ up = serial8250_get_port(priv->line); + +- if (omap8250_lost_context(up)) ++ if (up && omap8250_lost_context(up)) + omap8250_restore_regs(up); + +- if (up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) ++ if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) + omap_8250_rx_dma(up); + + priv->latency = priv->calc_latency; + schedule_work(&priv->qos_work); + return 0; + } +-#endif + + #ifdef CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP + static int __init omap8250_console_fixup(void) +@@ -1706,17 +1700,17 @@ console_initcall(omap8250_console_fixup); + #endif + + static const struct dev_pm_ops omap8250_dev_pm_ops = { +- SET_SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume) +- SET_RUNTIME_PM_OPS(omap8250_runtime_suspend, ++ SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume) ++ RUNTIME_PM_OPS(omap8250_runtime_suspend, + omap8250_runtime_resume, NULL) +- .prepare = omap8250_prepare, +- .complete = omap8250_complete, ++ .prepare = pm_sleep_ptr(omap8250_prepare), ++ .complete = pm_sleep_ptr(omap8250_complete), + }; + + static struct platform_driver omap8250_platform_driver = { + .driver = { + .name = "omap8250", +- .pm = &omap8250_dev_pm_ops, ++ .pm = pm_ptr(&omap8250_dev_pm_ops), + .of_match_table = omap8250_dt_ids, + }, + .probe = omap8250_probe, +diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c +index 2cc5c68c8689f..d4e57f9017db9 100644 +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -48,8 +48,6 @@ static struct lock_class_key port_lock_key; + */ + #define RS485_MAX_RTS_DELAY 100 /* msecs */ + +-static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, +- const struct ktermios *old_termios); + static void uart_wait_until_sent(struct tty_struct *tty, int timeout); + static void uart_change_pm(struct uart_state *state, + enum uart_pm_state pm_state); +@@ -177,6 +175,52 @@ static void uart_port_dtr_rts(struct uart_port *uport, int raise) + uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); + } + ++/* Caller holds port mutex */ ++static void uart_change_line_settings(struct tty_struct *tty, struct uart_state *state, ++ const struct ktermios *old_termios) ++{ ++ struct uart_port *uport = uart_port_check(state); ++ struct ktermios *termios; ++ int hw_stopped; ++ ++ /* ++ * If we have no tty, termios, or the port does not exist, ++ * then we can't set the parameters for this port. ++ */ ++ if (!tty || uport->type == PORT_UNKNOWN) ++ return; ++ ++ termios = &tty->termios; ++ uport->ops->set_termios(uport, termios, old_termios); ++ ++ /* ++ * Set modem status enables based on termios cflag ++ */ ++ spin_lock_irq(&uport->lock); ++ if (termios->c_cflag & CRTSCTS) ++ uport->status |= UPSTAT_CTS_ENABLE; ++ else ++ uport->status &= ~UPSTAT_CTS_ENABLE; ++ ++ if (termios->c_cflag & CLOCAL) ++ uport->status &= ~UPSTAT_DCD_ENABLE; ++ else ++ uport->status |= UPSTAT_DCD_ENABLE; ++ ++ /* reset sw-assisted CTS flow control based on (possibly) new mode */ ++ hw_stopped = uport->hw_stopped; ++ uport->hw_stopped = uart_softcts_mode(uport) && ++ !(uport->ops->get_mctrl(uport) & TIOCM_CTS); ++ if (uport->hw_stopped) { ++ if (!hw_stopped) ++ uport->ops->stop_tx(uport); ++ } else { ++ if (hw_stopped) ++ __uart_start(tty); ++ } ++ spin_unlock_irq(&uport->lock); ++} ++ + /* + * Startup the port. This will be called once per open. All calls + * will be serialised by the per-port mutex. +@@ -232,7 +276,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, + /* + * Initialise the hardware port settings. + */ +- uart_change_speed(tty, state, NULL); ++ uart_change_line_settings(tty, state, NULL); + + /* + * Setup the RTS and DTR signals once the +@@ -485,52 +529,6 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) + } + EXPORT_SYMBOL(uart_get_divisor); + +-/* Caller holds port mutex */ +-static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, +- const struct ktermios *old_termios) +-{ +- struct uart_port *uport = uart_port_check(state); +- struct ktermios *termios; +- int hw_stopped; +- +- /* +- * If we have no tty, termios, or the port does not exist, +- * then we can't set the parameters for this port. +- */ +- if (!tty || uport->type == PORT_UNKNOWN) +- return; +- +- termios = &tty->termios; +- uport->ops->set_termios(uport, termios, old_termios); +- +- /* +- * Set modem status enables based on termios cflag +- */ +- spin_lock_irq(&uport->lock); +- if (termios->c_cflag & CRTSCTS) +- uport->status |= UPSTAT_CTS_ENABLE; +- else +- uport->status &= ~UPSTAT_CTS_ENABLE; +- +- if (termios->c_cflag & CLOCAL) +- uport->status &= ~UPSTAT_DCD_ENABLE; +- else +- uport->status |= UPSTAT_DCD_ENABLE; +- +- /* reset sw-assisted CTS flow control based on (possibly) new mode */ +- hw_stopped = uport->hw_stopped; +- uport->hw_stopped = uart_softcts_mode(uport) && +- !(uport->ops->get_mctrl(uport) & TIOCM_CTS); +- if (uport->hw_stopped) { +- if (!hw_stopped) +- uport->ops->stop_tx(uport); +- } else { +- if (hw_stopped) +- __uart_start(tty); +- } +- spin_unlock_irq(&uport->lock); +-} +- + static int uart_put_char(struct tty_struct *tty, unsigned char c) + { + struct uart_state *state = tty->driver_data; +@@ -994,7 +992,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, + current->comm, + tty_name(port->tty)); + } +- uart_change_speed(tty, state, NULL); ++ uart_change_line_settings(tty, state, NULL); + } + } else { + retval = uart_startup(tty, state, 1); +@@ -1389,12 +1387,18 @@ static void uart_set_rs485_termination(struct uart_port *port, + static int uart_rs485_config(struct uart_port *port) + { + struct serial_rs485 *rs485 = &port->rs485; ++ unsigned long flags; + int ret; + ++ if (!(rs485->flags & SER_RS485_ENABLED)) ++ return 0; ++ + uart_sanitize_serial_rs485(port, rs485); + uart_set_rs485_termination(port, rs485); + ++ spin_lock_irqsave(&port->lock, flags); + ret = port->rs485_config(port, NULL, rs485); ++ spin_unlock_irqrestore(&port->lock, flags); + if (ret) + memset(rs485, 0, sizeof(*rs485)); + +@@ -1656,7 +1660,7 @@ static void uart_set_termios(struct tty_struct *tty, + goto out; + } + +- uart_change_speed(tty, state, old_termios); ++ uart_change_line_settings(tty, state, old_termios); + /* reload cflag from termios; port driver may have overridden flags */ + cflag = tty->termios.c_cflag; + +@@ -2456,12 +2460,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) + ret = ops->startup(uport); + if (ret == 0) { + if (tty) +- uart_change_speed(tty, state, NULL); ++ uart_change_line_settings(tty, state, NULL); ++ uart_rs485_config(uport); + spin_lock_irq(&uport->lock); + if (!(uport->rs485.flags & SER_RS485_ENABLED)) + ops->set_mctrl(uport, uport->mctrl); +- else +- uart_rs485_config(uport); + ops->start_tx(uport); + spin_unlock_irq(&uport->lock); + tty_port_set_initialized(port, 1); +@@ -2570,10 +2573,10 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, + port->mctrl &= TIOCM_DTR; + if (!(port->rs485.flags & SER_RS485_ENABLED)) + port->ops->set_mctrl(port, port->mctrl); +- else +- uart_rs485_config(port); + spin_unlock_irqrestore(&port->lock, flags); + ++ uart_rs485_config(port); ++ + /* + * If this driver supports console, and it hasn't been + * successfully registered yet, try to re-register it. +diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c +index 832d3ba9368ff..8edd0375e0a8a 100644 +--- a/drivers/usb/misc/onboard_usb_hub.c ++++ b/drivers/usb/misc/onboard_usb_hub.c +@@ -329,6 +329,7 @@ static struct platform_driver onboard_hub_driver = { + + /************************** USB driver **************************/ + ++#define VENDOR_ID_GENESYS 0x05e3 + #define VENDOR_ID_MICROCHIP 0x0424 + #define VENDOR_ID_REALTEK 0x0bda + #define VENDOR_ID_TI 0x0451 +@@ -405,6 +406,10 @@ static void onboard_hub_usbdev_disconnect(struct usb_device *udev) + } + + static const struct usb_device_id onboard_hub_id_table[] = { ++ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 */ ++ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0610) }, /* Genesys Logic GL852G USB 2.0 */ ++ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0620) }, /* Genesys Logic GL3523 USB 3.1 */ ++ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2412) }, /* USB2412 USB 2.0 */ + { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 */ + { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 */ + { USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 */ +diff --git a/drivers/usb/misc/onboard_usb_hub.h b/drivers/usb/misc/onboard_usb_hub.h +index 2cde54b69eede..d023fb90b4118 100644 +--- a/drivers/usb/misc/onboard_usb_hub.h ++++ b/drivers/usb/misc/onboard_usb_hub.h +@@ -22,11 +22,23 @@ static const struct onboard_hub_pdata ti_tusb8041_data = { + .reset_us = 3000, + }; + ++static const struct onboard_hub_pdata genesys_gl850g_data = { ++ .reset_us = 3, ++}; ++ ++static const struct onboard_hub_pdata genesys_gl852g_data = { ++ .reset_us = 50, ++}; ++ + static const struct of_device_id onboard_hub_match[] = { ++ { .compatible = "usb424,2412", .data = µchip_usb424_data, }, + { .compatible = "usb424,2514", .data = µchip_usb424_data, }, + { .compatible = "usb424,2517", .data = µchip_usb424_data, }, + { .compatible = "usb451,8140", .data = &ti_tusb8041_data, }, + { .compatible = "usb451,8142", .data = &ti_tusb8041_data, }, ++ { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, }, ++ { .compatible = "usb5e3,610", .data = &genesys_gl852g_data, }, ++ { .compatible = "usb5e3,620", .data = &genesys_gl852g_data, }, + { .compatible = "usbbda,411", .data = &realtek_rts5411_data, }, + { .compatible = "usbbda,5411", .data = &realtek_rts5411_data, }, + { .compatible = "usbbda,414", .data = &realtek_rts5411_data, }, +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index f13930b4534c1..b9dd714a3ae69 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -203,6 +203,9 @@ static void option_instat_callback(struct urb *urb); + #define DELL_PRODUCT_5829E_ESIM 0x81e4 + #define DELL_PRODUCT_5829E 0x81e6 + ++#define DELL_PRODUCT_FM101R 0x8213 ++#define DELL_PRODUCT_FM101R_ESIM 0x8215 ++ + #define KYOCERA_VENDOR_ID 0x0c88 + #define KYOCERA_PRODUCT_KPC650 0x17da + #define KYOCERA_PRODUCT_KPC680 0x180a +@@ -1108,6 +1111,8 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(0) | RSVD(6) }, + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM), + .driver_info = RSVD(0) | RSVD(6) }, ++ { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(DELL_VENDOR_ID, DELL_PRODUCT_FM101R_ESIM, 0xff) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, +@@ -1290,6 +1295,7 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(0) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */ + .driver_info = NCTRL(0) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1035, 0xff) }, /* Telit LE910C4-WWX (ECM) */ + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), + .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1), +@@ -2262,6 +2268,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ + { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, + { } /* Terminating entry */ +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 1a327eb3580b4..e08688844f1e1 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -563,18 +563,30 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + u64 search_start; + int ret; + +- if (test_bit(BTRFS_ROOT_DELETING, &root->state)) +- btrfs_err(fs_info, +- "COW'ing blocks on a fs root that's being dropped"); +- +- if (trans->transaction != fs_info->running_transaction) +- WARN(1, KERN_CRIT "trans %llu running %llu\n", +- trans->transid, +- fs_info->running_transaction->transid); ++ if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++ "attempt to COW block %llu on root %llu that is being deleted", ++ buf->start, btrfs_root_id(root)); ++ return -EUCLEAN; ++ } + +- if (trans->transid != fs_info->generation) +- WARN(1, KERN_CRIT "trans %llu running %llu\n", +- trans->transid, fs_info->generation); ++ /* ++ * COWing must happen through a running transaction, which always ++ * matches the current fs generation (it's a transaction with a state ++ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs ++ * into error state to prevent the commit of any transaction. ++ */ ++ if (unlikely(trans->transaction != fs_info->running_transaction || ++ trans->transid != fs_info->generation)) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++"unexpected transaction when attempting to COW block %llu on root %llu, transaction %llu running transaction %llu fs generation %llu", ++ buf->start, btrfs_root_id(root), trans->transid, ++ fs_info->running_transaction->transid, ++ fs_info->generation); ++ return -EUCLEAN; ++ } + + if (!should_cow_block(trans, root, buf)) { + *cow_ret = buf; +@@ -686,8 +698,22 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, + int progress_passed = 0; + struct btrfs_disk_key disk_key; + +- WARN_ON(trans->transaction != fs_info->running_transaction); +- WARN_ON(trans->transid != fs_info->generation); ++ /* ++ * COWing must happen through a running transaction, which always ++ * matches the current fs generation (it's a transaction with a state ++ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs ++ * into error state to prevent the commit of any transaction. ++ */ ++ if (unlikely(trans->transaction != fs_info->running_transaction || ++ trans->transid != fs_info->generation)) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++"unexpected transaction when attempting to reallocate parent %llu for root %llu, transaction %llu running transaction %llu fs generation %llu", ++ parent->start, btrfs_root_id(root), trans->transid, ++ fs_info->running_transaction->transid, ++ fs_info->generation); ++ return -EUCLEAN; ++ } + + parent_nritems = btrfs_header_nritems(parent); + blocksize = fs_info->nodesize; +diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c +index 36a3debe94930..e08e3852c4788 100644 +--- a/fs/btrfs/delayed-ref.c ++++ b/fs/btrfs/delayed-ref.c +@@ -141,24 +141,17 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans) + * Transfer bytes to our delayed refs rsv + * + * @fs_info: the filesystem +- * @src: source block rsv to transfer from + * @num_bytes: number of bytes to transfer + * +- * This transfers up to the num_bytes amount from the src rsv to the ++ * This transfers up to the num_bytes amount, previously reserved, to the + * delayed_refs_rsv. Any extra bytes are returned to the space info. + */ + void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, +- struct btrfs_block_rsv *src, + u64 num_bytes) + { + struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv; + u64 to_free = 0; + +- spin_lock(&src->lock); +- src->reserved -= num_bytes; +- src->size -= num_bytes; +- spin_unlock(&src->lock); +- + spin_lock(&delayed_refs_rsv->lock); + if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) { + u64 delta = delayed_refs_rsv->size - +diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h +index d6304b690ec4a..712a6315e956b 100644 +--- a/fs/btrfs/delayed-ref.h ++++ b/fs/btrfs/delayed-ref.h +@@ -383,7 +383,6 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans); + int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, + enum btrfs_reserve_flush_enum flush); + void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, +- struct btrfs_block_rsv *src, + u64 num_bytes); + int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans); + bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 08ff10a81cb90..2a7c9088fe1f8 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -1663,12 +1663,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, + parent = ref->parent; + ref_root = ref->root; + +- if (node->ref_mod != 1) { ++ if (unlikely(node->ref_mod != 1)) { + btrfs_err(trans->fs_info, +- "btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu", ++ "btree block %llu has %d references rather than 1: action %d ref_root %llu parent %llu", + node->bytenr, node->ref_mod, node->action, ref_root, + parent); +- return -EIO; ++ return -EUCLEAN; + } + if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { + BUG_ON(!extent_op || !extent_op->update_flags); +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 9e323420c96d3..9474265ee7ea3 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -3869,7 +3869,7 @@ static void get_block_group_info(struct list_head *groups_list, + static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info, + void __user *arg) + { +- struct btrfs_ioctl_space_args space_args; ++ struct btrfs_ioctl_space_args space_args = { 0 }; + struct btrfs_ioctl_space_info space; + struct btrfs_ioctl_space_info *dest; + struct btrfs_ioctl_space_info *dest_orig; +@@ -5223,7 +5223,7 @@ static int _btrfs_ioctl_send(struct inode *inode, void __user *argp, bool compat + + if (compat) { + #if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT) +- struct btrfs_ioctl_send_args_32 args32; ++ struct btrfs_ioctl_send_args_32 args32 = { 0 }; + + ret = copy_from_user(&args32, argp, sizeof(args32)); + if (ret) +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index 1193214ba8c10..60db4c3b82fa1 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -614,14 +614,14 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, + reloc_reserved = true; + } + +- ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes, flush); ++ ret = btrfs_reserve_metadata_bytes(fs_info, rsv, num_bytes, flush); + if (ret) + goto reserve_fail; + if (delayed_refs_bytes) { +- btrfs_migrate_to_delayed_refs_rsv(fs_info, rsv, +- delayed_refs_bytes); ++ btrfs_migrate_to_delayed_refs_rsv(fs_info, delayed_refs_bytes); + num_bytes -= delayed_refs_bytes; + } ++ btrfs_block_rsv_add_bytes(rsv, num_bytes, true); + + if (rsv->space_info->force_alloc) + do_chunk_alloc = true; +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index c03ff6a5a7f6b..7c33b28c02aeb 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -4767,7 +4767,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, + struct extent_buffer *leaf; + int slot; + int ins_nr = 0; +- int start_slot; ++ int start_slot = 0; + int ret; + + if (!(inode->flags & BTRFS_INODE_PREALLOC)) +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index a40ebd2321d01..e62b4c139a72d 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -5139,7 +5139,7 @@ static void init_alloc_chunk_ctl_policy_regular( + ASSERT(space_info); + + ctl->max_chunk_size = READ_ONCE(space_info->chunk_size); +- ctl->max_stripe_size = ctl->max_chunk_size; ++ ctl->max_stripe_size = min_t(u64, ctl->max_chunk_size, SZ_1G); + + if (ctl->type & BTRFS_BLOCK_GROUP_SYSTEM) + ctl->devs_max = min_t(int, ctl->devs_max, BTRFS_MAX_DEVS_SYS_CHUNK); +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index d387708977a50..a5c31a479aacc 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -1522,10 +1522,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb, + + if (wbc->pages_skipped) { + /* +- * writeback is not making progress due to locked +- * buffers. Skip this inode for now. ++ * Writeback is not making progress due to locked buffers. ++ * Skip this inode for now. Although having skipped pages ++ * is odd for clean inodes, it can happen for some ++ * filesystems so handle that gracefully. + */ +- redirty_tail_locked(inode, wb); ++ if (inode->i_state & I_DIRTY_ALL) ++ redirty_tail_locked(inode, wb); ++ else ++ inode_cgwb_move_to_attached(inode, wb); + return; + } + +diff --git a/fs/namei.c b/fs/namei.c +index 4248647f1ab24..5e1c2ab2ae709 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -187,7 +187,7 @@ getname_flags(const char __user *filename, int flags, int *empty) + } + } + +- result->refcnt = 1; ++ atomic_set(&result->refcnt, 1); + /* The empty path is special. */ + if (unlikely(!len)) { + if (empty) +@@ -248,7 +248,7 @@ getname_kernel(const char * filename) + memcpy((char *)result->name, filename, len); + result->uptr = NULL; + result->aname = NULL; +- result->refcnt = 1; ++ atomic_set(&result->refcnt, 1); + audit_getname(result); + + return result; +@@ -259,9 +259,10 @@ void putname(struct filename *name) + if (IS_ERR(name)) + return; + +- BUG_ON(name->refcnt <= 0); ++ if (WARN_ON_ONCE(!atomic_read(&name->refcnt))) ++ return; + +- if (--name->refcnt > 0) ++ if (!atomic_dec_and_test(&name->refcnt)) + return; + + if (name->name != name->iname) { +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index 5c69a6e9ab3e1..81bbafab18a99 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -2520,9 +2520,9 @@ ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo, + return i; + } + +-static int +-ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) ++static int ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) + { ++ struct pnfs_layout_hdr *lo; + struct nfs4_flexfile_layout *ff_layout; + const int dev_count = PNFS_LAYOUTSTATS_MAXDEV; + +@@ -2533,11 +2533,14 @@ ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) + return -ENOMEM; + + spin_lock(&args->inode->i_lock); +- ff_layout = FF_LAYOUT_FROM_HDR(NFS_I(args->inode)->layout); +- args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr, +- &args->devinfo[0], +- dev_count, +- NFS4_FF_OP_LAYOUTSTATS); ++ lo = NFS_I(args->inode)->layout; ++ if (lo && pnfs_layout_is_valid(lo)) { ++ ff_layout = FF_LAYOUT_FROM_HDR(lo); ++ args->num_dev = ff_layout_mirror_prepare_stats( ++ &ff_layout->generic_hdr, &args->devinfo[0], dev_count, ++ NFS4_FF_OP_LAYOUTSTATS); ++ } else ++ args->num_dev = 0; + spin_unlock(&args->inode->i_lock); + if (!args->num_dev) { + kfree(args->devinfo); +diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c +index d903ea10410c2..5a8fe0e57a3d3 100644 +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -81,7 +81,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, + if (status == 0) { + if (nfs_should_remove_suid(inode)) { + spin_lock(&inode->i_lock); +- nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE); ++ nfs_set_cache_invalid(inode, ++ NFS_INO_REVAL_FORCED | NFS_INO_INVALID_MODE); + spin_unlock(&inode->i_lock); + } + status = nfs_post_op_update_inode_force_wcc(inode, +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index e1297c6bcfbe2..5cf53def987e5 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -8875,8 +8875,6 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre + /* Save the EXCHANGE_ID verifier session trunk tests */ + memcpy(clp->cl_confirm.data, argp->verifier.data, + sizeof(clp->cl_confirm.data)); +- if (resp->flags & EXCHGID4_FLAG_USE_PNFS_DS) +- set_bit(NFS_CS_DS, &clp->cl_flags); + out: + trace_nfs4_exchange_id(clp, status); + rpc_put_task(task); +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index a5db5158c6345..1ffb1068216b6 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -2634,31 +2634,44 @@ pnfs_should_return_unused_layout(struct pnfs_layout_hdr *lo, + return mode == 0; + } + +-static int +-pnfs_layout_return_unused_byserver(struct nfs_server *server, void *data) ++static int pnfs_layout_return_unused_byserver(struct nfs_server *server, ++ void *data) + { + const struct pnfs_layout_range *range = data; ++ const struct cred *cred; + struct pnfs_layout_hdr *lo; + struct inode *inode; ++ nfs4_stateid stateid; ++ enum pnfs_iomode iomode; ++ + restart: + rcu_read_lock(); + list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) { +- if (!pnfs_layout_can_be_returned(lo) || ++ inode = lo->plh_inode; ++ if (!inode || !pnfs_layout_can_be_returned(lo) || + test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) + continue; +- inode = lo->plh_inode; + spin_lock(&inode->i_lock); +- if (!pnfs_should_return_unused_layout(lo, range)) { ++ if (!lo->plh_inode || ++ !pnfs_should_return_unused_layout(lo, range)) { + spin_unlock(&inode->i_lock); + continue; + } ++ pnfs_get_layout_hdr(lo); ++ pnfs_set_plh_return_info(lo, range->iomode, 0); ++ if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, ++ range, 0) != 0 || ++ !pnfs_prepare_layoutreturn(lo, &stateid, &cred, &iomode)) { ++ spin_unlock(&inode->i_lock); ++ rcu_read_unlock(); ++ pnfs_put_layout_hdr(lo); ++ cond_resched(); ++ goto restart; ++ } + spin_unlock(&inode->i_lock); +- inode = pnfs_grab_inode_layout_hdr(lo); +- if (!inode) +- continue; + rcu_read_unlock(); +- pnfs_mark_layout_for_return(inode, range); +- iput(inode); ++ pnfs_send_layoutreturn(lo, &stateid, &cred, iomode, false); ++ pnfs_put_layout_hdr(lo); + cond_resched(); + goto restart; + } +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index 829b62d3bb889..9c0fc3a29d0c9 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -2428,10 +2428,12 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim) + { + CLST end, i, zone_len, zlen; + struct wnd_bitmap *wnd = &sbi->used.bitmap; ++ bool dirty = false; + + down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS); + if (!wnd_is_used(wnd, lcn, len)) { +- ntfs_set_state(sbi, NTFS_DIRTY_ERROR); ++ /* mark volume as dirty out of wnd->rw_lock */ ++ dirty = true; + + end = lcn + len; + len = 0; +@@ -2485,6 +2487,8 @@ void mark_as_free_ex(struct ntfs_sb_info *sbi, CLST lcn, CLST len, bool trim) + + out: + up_write(&wnd->rw_lock); ++ if (dirty) ++ ntfs_set_state(sbi, NTFS_DIRTY_ERROR); + } + + /* +diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c +index 495cfb37962fa..b89a33f5761ef 100644 +--- a/fs/ntfs3/index.c ++++ b/fs/ntfs3/index.c +@@ -729,6 +729,9 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx, + u32 total = le32_to_cpu(hdr->total); + u16 offs[128]; + ++ if (unlikely(!cmp)) ++ return NULL; ++ + fill_table: + if (end > total) + return NULL; +diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c +index f5d3092f478c5..df15e00c2a3a0 100644 +--- a/fs/ntfs3/xattr.c ++++ b/fs/ntfs3/xattr.c +@@ -209,7 +209,8 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, + size = le32_to_cpu(info->size); + + /* Enumerate all xattrs. */ +- for (ret = 0, off = 0; off < size; off += ea_size) { ++ ret = 0; ++ for (off = 0; off + sizeof(struct EA_FULL) < size; off += ea_size) { + ea = Add2Ptr(ea_all, off); + ea_size = unpacked_ea_size(ea); + +@@ -217,6 +218,10 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, + break; + + if (buffer) { ++ /* Check if we can use field ea->name */ ++ if (off + ea_size > size) ++ break; ++ + if (ret + ea->name_len + 1 > bytes_per_buffer) { + err = -ERANGE; + goto out; +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index e6d711f42607b..86d4b6975dbcb 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -300,7 +300,7 @@ static int ovl_set_timestamps(struct ovl_fs *ofs, struct dentry *upperdentry, + { + struct iattr attr = { + .ia_valid = +- ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, ++ ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_CTIME, + .ia_atime = stat->atime, + .ia_mtime = stat->mtime, + }; +diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h +index 1c2bde0ead736..678f741a7b330 100644 +--- a/include/linux/fprobe.h ++++ b/include/linux/fprobe.h +@@ -13,6 +13,8 @@ + * @nmissed: The counter for missing events. + * @flags: The status flag. + * @rethook: The rethook data structure. (internal data) ++ * @entry_data_size: The private data storage size. ++ * @nr_maxactive: The max number of active functions. + * @entry_handler: The callback function for function entry. + * @exit_handler: The callback function for function exit. + */ +@@ -29,9 +31,13 @@ struct fprobe { + unsigned long nmissed; + unsigned int flags; + struct rethook *rethook; ++ size_t entry_data_size; ++ int nr_maxactive; + +- void (*entry_handler)(struct fprobe *fp, unsigned long entry_ip, struct pt_regs *regs); +- void (*exit_handler)(struct fprobe *fp, unsigned long entry_ip, struct pt_regs *regs); ++ void (*entry_handler)(struct fprobe *fp, unsigned long entry_ip, ++ struct pt_regs *regs, void *entry_data); ++ void (*exit_handler)(struct fprobe *fp, unsigned long entry_ip, ++ struct pt_regs *regs, void *entry_data); + }; + + /* This fprobe is soft-disabled. */ +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 26ea1a0a59a10..dc745317e1bdb 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -2735,7 +2735,7 @@ struct audit_names; + struct filename { + const char *name; /* pointer to actual string */ + const __user char *uptr; /* original userland pointer */ +- int refcnt; ++ atomic_t refcnt; + struct audit_names *aname; + const char iname[]; + }; +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 784dd6b6046eb..58f5ab29c11a7 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -312,6 +312,7 @@ struct hid_item { + #define HID_DG_LATENCYMODE 0x000d0060 + + #define HID_BAT_ABSOLUTESTATEOFCHARGE 0x00850065 ++#define HID_BAT_CHARGING 0x00850044 + + #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076 + +@@ -612,6 +613,7 @@ struct hid_device { /* device report descriptor */ + __s32 battery_max; + __s32 battery_report_type; + __s32 battery_report_id; ++ __s32 battery_charge_status; + enum hid_battery_status battery_status; + bool battery_avoid_query; + ktime_t battery_ratelimit_time; +diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h +index f0ec8a5e5a7a9..9d3bd6379eb87 100644 +--- a/include/linux/iio/iio.h ++++ b/include/linux/iio/iio.h +@@ -629,6 +629,8 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev, + int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); + int iio_device_claim_direct_mode(struct iio_dev *indio_dev); + void iio_device_release_direct_mode(struct iio_dev *indio_dev); ++int iio_device_claim_buffer_mode(struct iio_dev *indio_dev); ++void iio_device_release_buffer_mode(struct iio_dev *indio_dev); + + extern struct bus_type iio_bus_type; + +diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h +index 649faac31ddb1..0cd33be7142ad 100644 +--- a/include/linux/kallsyms.h ++++ b/include/linux/kallsyms.h +@@ -69,6 +69,8 @@ static inline void *dereference_symbol_descriptor(void *ptr) + int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, + unsigned long), + void *data); ++int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long), ++ const char *name, void *data); + + /* Lookup the address for a symbol. Returns 0 if not found. */ + unsigned long kallsyms_lookup_name(const char *name); +@@ -168,6 +170,12 @@ static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct + { + return -EOPNOTSUPP; + } ++ ++static inline int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long), ++ const char *name, void *data) ++{ ++ return -EOPNOTSUPP; ++} + #endif /*CONFIG_KALLSYMS*/ + + static inline void print_ip_sym(const char *loglvl, unsigned long ip) +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index 63fae3c7ae430..1578a4de1f3cb 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -694,6 +694,7 @@ struct perf_event { + /* The cumulative AND of all event_caps for events in this group. */ + int group_caps; + ++ unsigned int group_generation; + struct perf_event *group_leader; + struct pmu *pmu; + void *pmu_private; +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index ddbcbf9ccb2ce..583aebd8c1e01 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -348,7 +348,7 @@ struct hci_dev { + struct list_head list; + struct mutex lock; + +- char name[8]; ++ const char *name; + unsigned long flags; + __u16 id; + __u8 bus; +diff --git a/include/net/bluetooth/hci_mon.h b/include/net/bluetooth/hci_mon.h +index 2d5fcda1bcd05..082f89531b889 100644 +--- a/include/net/bluetooth/hci_mon.h ++++ b/include/net/bluetooth/hci_mon.h +@@ -56,7 +56,7 @@ struct hci_mon_new_index { + __u8 type; + __u8 bus; + bdaddr_t bdaddr; +- char name[8]; ++ char name[8] __nonstring; + } __packed; + #define HCI_MON_NEW_INDEX_SIZE 16 + +diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h +index f0c13864180e2..15de07d365405 100644 +--- a/include/net/ip_fib.h ++++ b/include/net/ip_fib.h +@@ -154,6 +154,7 @@ struct fib_info { + int fib_nhs; + bool fib_nh_is_v6; + bool nh_updated; ++ bool pfsrc_removed; + struct nexthop *nh; + struct rcu_head rcu; + struct fib_nh fib_nh[]; +diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h +index bd7c3be4af5d7..423b52eca908d 100644 +--- a/include/net/netns/xfrm.h ++++ b/include/net/netns/xfrm.h +@@ -50,6 +50,7 @@ struct netns_xfrm { + struct list_head policy_all; + struct hlist_head *policy_byidx; + unsigned int policy_idx_hmask; ++ unsigned int idx_generator; + struct hlist_head policy_inexact[XFRM_POLICY_MAX]; + struct xfrm_policy_hash policy_bydst[XFRM_POLICY_MAX]; + unsigned int policy_count[XFRM_POLICY_MAX * 2]; +diff --git a/include/net/sock.h b/include/net/sock.h +index fe695e8bfe289..a1fcbb2a8a2ce 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -333,7 +333,7 @@ struct sk_filter; + * @sk_cgrp_data: cgroup data for this cgroup + * @sk_memcg: this socket's memory cgroup association + * @sk_write_pending: a write to stream socket waits to start +- * @sk_wait_pending: number of threads blocked on this socket ++ * @sk_disconnects: number of disconnect operations performed on this sock + * @sk_state_change: callback to indicate change in the state of the sock + * @sk_data_ready: callback to indicate there is data to be processed + * @sk_write_space: callback to indicate there is bf sending space available +@@ -426,7 +426,7 @@ struct sock { + unsigned int sk_napi_id; + #endif + int sk_rcvbuf; +- int sk_wait_pending; ++ int sk_disconnects; + + struct sk_filter __rcu *sk_filter; + union { +@@ -1185,8 +1185,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) + } + + #define sk_wait_event(__sk, __timeo, __condition, __wait) \ +- ({ int __rc; \ +- __sk->sk_wait_pending++; \ ++ ({ int __rc, __dis = __sk->sk_disconnects; \ + release_sock(__sk); \ + __rc = __condition; \ + if (!__rc) { \ +@@ -1196,8 +1195,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) + } \ + sched_annotate_sleep(); \ + lock_sock(__sk); \ +- __sk->sk_wait_pending--; \ +- __rc = __condition; \ ++ __rc = __dis == __sk->sk_disconnects ? __condition : -EPIPE; \ + __rc; \ + }) + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 9ebb54122bb71..548c75c8a34c7 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -141,6 +141,9 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); + #define TCP_RTO_MAX ((unsigned)(120*HZ)) + #define TCP_RTO_MIN ((unsigned)(HZ/5)) + #define TCP_TIMEOUT_MIN (2U) /* Min timeout for TCP timers in jiffies */ ++ ++#define TCP_TIMEOUT_MIN_US (2*USEC_PER_MSEC) /* Min TCP timeout in microsecs */ ++ + #define TCP_TIMEOUT_INIT ((unsigned)(1*HZ)) /* RFC6298 2.1 initial RTO value */ + #define TCP_TIMEOUT_FALLBACK ((unsigned)(3*HZ)) /* RFC 1122 initial RTO value, now + * used as a fallback RTO for the +diff --git a/include/trace/events/neigh.h b/include/trace/events/neigh.h +index 5eaa1fa991715..833143d0992e0 100644 +--- a/include/trace/events/neigh.h ++++ b/include/trace/events/neigh.h +@@ -39,7 +39,6 @@ TRACE_EVENT(neigh_create, + ), + + TP_fast_assign( +- struct in6_addr *pin6; + __be32 *p32; + + __entry->family = tbl->family; +@@ -47,7 +46,6 @@ TRACE_EVENT(neigh_create, + __entry->entries = atomic_read(&tbl->gc_entries); + __entry->created = n != NULL; + __entry->gc_exempt = exempt_from_gc; +- pin6 = (struct in6_addr *)__entry->primary_key6; + p32 = (__be32 *)__entry->primary_key4; + + if (tbl->family == AF_INET) +@@ -57,6 +55,8 @@ TRACE_EVENT(neigh_create, + + #if IS_ENABLED(CONFIG_IPV6) + if (tbl->family == AF_INET6) { ++ struct in6_addr *pin6; ++ + pin6 = (struct in6_addr *)__entry->primary_key6; + *pin6 = *(struct in6_addr *)pkey; + } +diff --git a/kernel/auditsc.c b/kernel/auditsc.c +index a2240f54fc224..c5f41fc75d543 100644 +--- a/kernel/auditsc.c ++++ b/kernel/auditsc.c +@@ -2208,7 +2208,7 @@ __audit_reusename(const __user char *uptr) + if (!n->name) + continue; + if (n->name->uptr == uptr) { +- n->name->refcnt++; ++ atomic_inc(&n->name->refcnt); + return n->name; + } + } +@@ -2237,7 +2237,7 @@ void __audit_getname(struct filename *name) + n->name = name; + n->name_len = AUDIT_NAME_FULL; + name->aname = n; +- name->refcnt++; ++ atomic_inc(&name->refcnt); + } + + static inline int audit_copy_fcaps(struct audit_names *name, +@@ -2369,7 +2369,7 @@ out_alloc: + return; + if (name) { + n->name = name; +- name->refcnt++; ++ atomic_inc(&name->refcnt); + } + + out: +@@ -2496,7 +2496,7 @@ void __audit_inode_child(struct inode *parent, + if (found_parent) { + found_child->name = found_parent->name; + found_child->name_len = AUDIT_NAME_FULL; +- found_child->name->refcnt++; ++ atomic_inc(&found_child->name->refcnt); + } + } + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index db1065daabb62..2b8315a948a2c 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1962,6 +1962,7 @@ static void perf_group_attach(struct perf_event *event) + + list_add_tail(&event->sibling_list, &group_leader->sibling_list); + group_leader->nr_siblings++; ++ group_leader->group_generation++; + + perf_event__header_size(group_leader); + +@@ -2156,6 +2157,7 @@ static void perf_group_detach(struct perf_event *event) + if (leader != event) { + list_del_init(&event->sibling_list); + event->group_leader->nr_siblings--; ++ event->group_leader->group_generation++; + goto out; + } + +@@ -5279,7 +5281,7 @@ static int __perf_read_group_add(struct perf_event *leader, + u64 read_format, u64 *values) + { + struct perf_event_context *ctx = leader->ctx; +- struct perf_event *sub; ++ struct perf_event *sub, *parent; + unsigned long flags; + int n = 1; /* skip @nr */ + int ret; +@@ -5289,6 +5291,33 @@ static int __perf_read_group_add(struct perf_event *leader, + return ret; + + raw_spin_lock_irqsave(&ctx->lock, flags); ++ /* ++ * Verify the grouping between the parent and child (inherited) ++ * events is still in tact. ++ * ++ * Specifically: ++ * - leader->ctx->lock pins leader->sibling_list ++ * - parent->child_mutex pins parent->child_list ++ * - parent->ctx->mutex pins parent->sibling_list ++ * ++ * Because parent->ctx != leader->ctx (and child_list nests inside ++ * ctx->mutex), group destruction is not atomic between children, also ++ * see perf_event_release_kernel(). Additionally, parent can grow the ++ * group. ++ * ++ * Therefore it is possible to have parent and child groups in a ++ * different configuration and summing over such a beast makes no sense ++ * what so ever. ++ * ++ * Reject this. ++ */ ++ parent = leader->parent; ++ if (parent && ++ (parent->group_generation != leader->group_generation || ++ parent->nr_siblings != leader->nr_siblings)) { ++ ret = -ECHILD; ++ goto unlock; ++ } + + /* + * Since we co-schedule groups, {enabled,running} times of siblings +@@ -5322,8 +5351,9 @@ static int __perf_read_group_add(struct perf_event *leader, + values[n++] = atomic64_read(&sub->lost_samples); + } + ++unlock: + raw_spin_unlock_irqrestore(&ctx->lock, flags); +- return 0; ++ return ret; + } + + static int perf_read_group(struct perf_event *event, +@@ -5342,10 +5372,6 @@ static int perf_read_group(struct perf_event *event, + + values[0] = 1 + leader->nr_siblings; + +- /* +- * By locking the child_mutex of the leader we effectively +- * lock the child list of all siblings.. XXX explain how. +- */ + mutex_lock(&leader->child_mutex); + + ret = __perf_read_group_add(leader, read_format, values); +@@ -13267,6 +13293,7 @@ static int inherit_group(struct perf_event *parent_event, + !perf_get_aux_event(child_ctr, leader)) + return -EINVAL; + } ++ leader->group_generation = parent_event->group_generation; + return 0; + } + +diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c +index ad3cccb0970f8..824bcc7b5dbc3 100644 +--- a/kernel/kallsyms.c ++++ b/kernel/kallsyms.c +@@ -197,6 +197,16 @@ static int compare_symbol_name(const char *name, char *namebuf) + return strcmp(name, namebuf); + } + ++static unsigned int get_symbol_seq(int index) ++{ ++ unsigned int i, seq = 0; ++ ++ for (i = 0; i < 3; i++) ++ seq = (seq << 8) | kallsyms_seqs_of_names[3 * index + i]; ++ ++ return seq; ++} ++ + static int kallsyms_lookup_names(const char *name, + unsigned int *start, + unsigned int *end) +@@ -211,7 +221,7 @@ static int kallsyms_lookup_names(const char *name, + + while (low <= high) { + mid = low + (high - low) / 2; +- seq = kallsyms_seqs_of_names[mid]; ++ seq = get_symbol_seq(mid); + off = get_symbol_offset(seq); + kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); + ret = compare_symbol_name(name, namebuf); +@@ -228,7 +238,7 @@ static int kallsyms_lookup_names(const char *name, + + low = mid; + while (low) { +- seq = kallsyms_seqs_of_names[low - 1]; ++ seq = get_symbol_seq(low - 1); + off = get_symbol_offset(seq); + kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); + if (compare_symbol_name(name, namebuf)) +@@ -240,7 +250,7 @@ static int kallsyms_lookup_names(const char *name, + if (end) { + high = mid; + while (high < kallsyms_num_syms - 1) { +- seq = kallsyms_seqs_of_names[high + 1]; ++ seq = get_symbol_seq(high + 1); + off = get_symbol_offset(seq); + kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); + if (compare_symbol_name(name, namebuf)) +@@ -265,7 +275,7 @@ unsigned long kallsyms_lookup_name(const char *name) + + ret = kallsyms_lookup_names(name, &i, NULL); + if (!ret) +- return kallsyms_sym_address(kallsyms_seqs_of_names[i]); ++ return kallsyms_sym_address(get_symbol_seq(i)); + + return module_kallsyms_lookup_name(name); + } +@@ -293,6 +303,24 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, + return 0; + } + ++int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long), ++ const char *name, void *data) ++{ ++ int ret; ++ unsigned int i, start, end; ++ ++ ret = kallsyms_lookup_names(name, &start, &end); ++ if (ret) ++ return 0; ++ ++ for (i = start; !ret && i <= end; i++) { ++ ret = fn(data, kallsyms_sym_address(get_symbol_seq(i))); ++ cond_resched(); ++ } ++ ++ return ret; ++} ++ + static unsigned long get_symbol_pos(unsigned long addr, + unsigned long *symbolsize, + unsigned long *offset) +diff --git a/kernel/kallsyms_internal.h b/kernel/kallsyms_internal.h +index a04b7a5cb1e3e..27fabdcc40f57 100644 +--- a/kernel/kallsyms_internal.h ++++ b/kernel/kallsyms_internal.h +@@ -26,6 +26,6 @@ extern const char kallsyms_token_table[] __weak; + extern const u16 kallsyms_token_index[] __weak; + + extern const unsigned int kallsyms_markers[] __weak; +-extern const unsigned int kallsyms_seqs_of_names[] __weak; ++extern const u8 kallsyms_seqs_of_names[] __weak; + + #endif // LINUX_KALLSYMS_INTERNAL_H_ +diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c +index 1207c78f85c11..853a07618a3cf 100644 +--- a/kernel/sched/cpufreq_schedutil.c ++++ b/kernel/sched/cpufreq_schedutil.c +@@ -345,7 +345,8 @@ static void sugov_update_single_freq(struct update_util_data *hook, u64 time, + * Except when the rq is capped by uclamp_max. + */ + if (!uclamp_rq_is_capped(cpu_rq(sg_cpu->cpu)) && +- sugov_cpu_is_busy(sg_cpu) && next_f < sg_policy->next_freq) { ++ sugov_cpu_is_busy(sg_cpu) && next_f < sg_policy->next_freq && ++ !sg_policy->need_freq_update) { + next_f = sg_policy->next_freq; + + /* Restore cached freq as next_freq has changed */ +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index 8c77c54e6348b..f4a494a457c52 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -2646,7 +2646,7 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link, + + static void + kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip, +- struct pt_regs *regs) ++ struct pt_regs *regs, void *data) + { + struct bpf_kprobe_multi_link *link; + +diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c +index 1322247ce6488..f386d6bd8e0e3 100644 +--- a/kernel/trace/fprobe.c ++++ b/kernel/trace/fprobe.c +@@ -17,14 +17,16 @@ + struct fprobe_rethook_node { + struct rethook_node node; + unsigned long entry_ip; ++ char data[]; + }; + + static void fprobe_handler(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *ops, struct ftrace_regs *fregs) + { + struct fprobe_rethook_node *fpr; +- struct rethook_node *rh; ++ struct rethook_node *rh = NULL; + struct fprobe *fp; ++ void *entry_data = NULL; + int bit; + + fp = container_of(ops, struct fprobe, ops); +@@ -37,9 +39,6 @@ static void fprobe_handler(unsigned long ip, unsigned long parent_ip, + return; + } + +- if (fp->entry_handler) +- fp->entry_handler(fp, ip, ftrace_get_regs(fregs)); +- + if (fp->exit_handler) { + rh = rethook_try_get(fp->rethook); + if (!rh) { +@@ -48,9 +47,16 @@ static void fprobe_handler(unsigned long ip, unsigned long parent_ip, + } + fpr = container_of(rh, struct fprobe_rethook_node, node); + fpr->entry_ip = ip; +- rethook_hook(rh, ftrace_get_regs(fregs), true); ++ if (fp->entry_data_size) ++ entry_data = fpr->data; + } + ++ if (fp->entry_handler) ++ fp->entry_handler(fp, ip, ftrace_get_regs(fregs), entry_data); ++ ++ if (rh) ++ rethook_hook(rh, ftrace_get_regs(fregs), true); ++ + out: + ftrace_test_recursion_unlock(bit); + } +@@ -81,7 +87,8 @@ static void fprobe_exit_handler(struct rethook_node *rh, void *data, + + fpr = container_of(rh, struct fprobe_rethook_node, node); + +- fp->exit_handler(fp, fpr->entry_ip, regs); ++ fp->exit_handler(fp, fpr->entry_ip, regs, ++ fp->entry_data_size ? (void *)fpr->data : NULL); + } + NOKPROBE_SYMBOL(fprobe_exit_handler); + +@@ -127,7 +134,7 @@ static int fprobe_init_rethook(struct fprobe *fp, int num) + { + int i, size; + +- if (num < 0) ++ if (num <= 0) + return -EINVAL; + + if (!fp->exit_handler) { +@@ -136,9 +143,12 @@ static int fprobe_init_rethook(struct fprobe *fp, int num) + } + + /* Initialize rethook if needed */ +- size = num * num_possible_cpus() * 2; +- if (size < 0) +- return -E2BIG; ++ if (fp->nr_maxactive) ++ size = fp->nr_maxactive; ++ else ++ size = num * num_possible_cpus() * 2; ++ if (size <= 0) ++ return -EINVAL; + + fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler); + if (!fp->rethook) +@@ -146,7 +156,7 @@ static int fprobe_init_rethook(struct fprobe *fp, int num) + for (i = 0; i < size; i++) { + struct fprobe_rethook_node *node; + +- node = kzalloc(sizeof(*node), GFP_KERNEL); ++ node = kzalloc(sizeof(*node) + fp->entry_data_size, GFP_KERNEL); + if (!node) { + rethook_free(fp->rethook); + fp->rethook = NULL; +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index 9da418442a063..2e3dce5e2575e 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -2777,6 +2777,7 @@ void trace_event_eval_update(struct trace_eval_map **map, int len) + update_event_fields(call, map[i]); + } + } ++ cond_resched(); + } + up_write(&trace_event_sem); + } +diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c +index 5a75b039e5860..22852029c6924 100644 +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -705,6 +705,25 @@ static struct notifier_block trace_kprobe_module_nb = { + .priority = 1 /* Invoked after kprobe module callback */ + }; + ++static int count_symbols(void *data, unsigned long unused) ++{ ++ unsigned int *count = data; ++ ++ (*count)++; ++ ++ return 0; ++} ++ ++static unsigned int number_of_same_symbols(char *func_name) ++{ ++ unsigned int count; ++ ++ count = 0; ++ kallsyms_on_each_match_symbol(count_symbols, func_name, &count); ++ ++ return count; ++} ++ + static int __trace_kprobe_create(int argc, const char *argv[]) + { + /* +@@ -834,6 +853,31 @@ static int __trace_kprobe_create(int argc, const char *argv[]) + } + } + ++ if (symbol && !strchr(symbol, ':')) { ++ unsigned int count; ++ ++ count = number_of_same_symbols(symbol); ++ if (count > 1) { ++ /* ++ * Users should use ADDR to remove the ambiguity of ++ * using KSYM only. ++ */ ++ trace_probe_log_err(0, NON_UNIQ_SYMBOL); ++ ret = -EADDRNOTAVAIL; ++ ++ goto error; ++ } else if (count == 0) { ++ /* ++ * We can return ENOENT earlier than when register the ++ * kprobe. ++ */ ++ trace_probe_log_err(0, BAD_PROBE_ADDR); ++ ret = -ENOENT; ++ ++ goto error; ++ } ++ } ++ + trace_probe_log_set_index(0); + if (event) { + ret = traceprobe_parse_event_name(&event, &group, gbuf, +@@ -1744,6 +1788,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk) + } + + #ifdef CONFIG_PERF_EVENTS ++ + /* create a trace_kprobe, but don't add it to global lists */ + struct trace_event_call * + create_local_trace_kprobe(char *func, void *addr, unsigned long offs, +@@ -1754,6 +1799,24 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs, + int ret; + char *event; + ++ if (func) { ++ unsigned int count; ++ ++ count = number_of_same_symbols(func); ++ if (count > 1) ++ /* ++ * Users should use addr to remove the ambiguity of ++ * using func only. ++ */ ++ return ERR_PTR(-EADDRNOTAVAIL); ++ else if (count == 0) ++ /* ++ * We can return ENOENT earlier than when register the ++ * kprobe. ++ */ ++ return ERR_PTR(-ENOENT); ++ } ++ + /* + * local trace_kprobes are not added to dyn_event, so they are never + * searched in find_trace_kprobe(). Therefore, there is no concern of +diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h +index f41c330bd60f1..f48b3ed20b095 100644 +--- a/kernel/trace/trace_probe.h ++++ b/kernel/trace/trace_probe.h +@@ -404,6 +404,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, + C(BAD_MAXACT, "Invalid maxactive number"), \ + C(MAXACT_TOO_BIG, "Maxactive is too big"), \ + C(BAD_PROBE_ADDR, "Invalid probed address or symbol"), \ ++ C(NON_UNIQ_SYMBOL, "The symbol is not unique"), \ + C(BAD_RETPROBE, "Retprobe address must be an function entry"), \ + C(BAD_ADDR_SUFFIX, "Invalid probed address suffix"), \ + C(NO_GROUP_NAME, "Group name is not specified"), \ +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 12dfe6691dd52..4db0199651f56 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -1219,13 +1219,16 @@ config DEBUG_TIMEKEEPING + config DEBUG_PREEMPT + bool "Debug preemptible kernel" + depends on DEBUG_KERNEL && PREEMPTION && TRACE_IRQFLAGS_SUPPORT +- default y + help + If you say Y here then the kernel will use a debug variant of the + commonly used smp_processor_id() function and will print warnings + if kernel code uses it in a preemption-unsafe way. Also, the kernel + will detect preemption count underflows. + ++ This option has potential to introduce high runtime overhead, ++ depending on workload as it triggers debugging routines for each ++ this_cpu operation. It should only be used for debugging purposes. ++ + menu "Lock Debugging (spinlocks, mutexes, etc...)" + + config LOCK_DEBUGGING_SUPPORT +diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c +index e0381b3ec410c..34fa5a5bbda1f 100644 +--- a/lib/test_fprobe.c ++++ b/lib/test_fprobe.c +@@ -30,7 +30,8 @@ static noinline u32 fprobe_selftest_target2(u32 value) + return (value / div_factor) + 1; + } + +-static notrace void fp_entry_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs) ++static notrace void fp_entry_handler(struct fprobe *fp, unsigned long ip, ++ struct pt_regs *regs, void *data) + { + KUNIT_EXPECT_FALSE(current_test, preemptible()); + /* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */ +@@ -39,7 +40,8 @@ static notrace void fp_entry_handler(struct fprobe *fp, unsigned long ip, struct + entry_val = (rand1 / div_factor); + } + +-static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs) ++static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip, ++ struct pt_regs *regs, void *data) + { + unsigned long ret = regs_return_value(regs); + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 61059571c8779..728be9307f526 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -1583,6 +1583,15 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, + return ERR_PTR(-EOPNOTSUPP); + } + ++ /* Reject outgoing connection to device with same BD ADDR against ++ * CVE-2020-26555 ++ */ ++ if (!bacmp(&hdev->bdaddr, dst)) { ++ bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n", ++ dst); ++ return ERR_PTR(-ECONNREFUSED); ++ } ++ + acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); + if (!acl) { + acl = hci_conn_add(hdev, ACL_LINK, dst, HCI_ROLE_MASTER); +@@ -2355,34 +2364,41 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, + if (!test_bit(HCI_CONN_AUTH, &conn->flags)) + goto auth; + +- /* An authenticated FIPS approved combination key has sufficient +- * security for security level 4. */ +- if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256 && +- sec_level == BT_SECURITY_FIPS) +- goto encrypt; +- +- /* An authenticated combination key has sufficient security for +- security level 3. */ +- if ((conn->key_type == HCI_LK_AUTH_COMBINATION_P192 || +- conn->key_type == HCI_LK_AUTH_COMBINATION_P256) && +- sec_level == BT_SECURITY_HIGH) +- goto encrypt; +- +- /* An unauthenticated combination key has sufficient security for +- security level 1 and 2. */ +- if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 || +- conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) && +- (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) +- goto encrypt; +- +- /* A combination key has always sufficient security for the security +- levels 1 or 2. High security level requires the combination key +- is generated using maximum PIN code length (16). +- For pre 2.1 units. */ +- if (conn->key_type == HCI_LK_COMBINATION && +- (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW || +- conn->pin_length == 16)) +- goto encrypt; ++ switch (conn->key_type) { ++ case HCI_LK_AUTH_COMBINATION_P256: ++ /* An authenticated FIPS approved combination key has ++ * sufficient security for security level 4 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_FIPS) ++ goto encrypt; ++ break; ++ case HCI_LK_AUTH_COMBINATION_P192: ++ /* An authenticated combination key has sufficient security for ++ * security level 3 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_HIGH) ++ goto encrypt; ++ break; ++ case HCI_LK_UNAUTH_COMBINATION_P192: ++ case HCI_LK_UNAUTH_COMBINATION_P256: ++ /* An unauthenticated combination key has sufficient security ++ * for security level 2 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_MEDIUM) ++ goto encrypt; ++ break; ++ case HCI_LK_COMBINATION: ++ /* A combination key has always sufficient security for the ++ * security levels 2 or lower. High security level requires the ++ * combination key is generated using maximum PIN code length ++ * (16). For pre 2.1 units. ++ */ ++ if (sec_level <= BT_SECURITY_MEDIUM || conn->pin_length == 16) ++ goto encrypt; ++ break; ++ default: ++ break; ++ } + + auth: + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index d13b498f148cc..6a1db678d032f 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -2616,7 +2616,11 @@ int hci_register_dev(struct hci_dev *hdev) + if (id < 0) + return id; + +- snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); ++ error = dev_set_name(&hdev->dev, "hci%u", id); ++ if (error) ++ return error; ++ ++ hdev->name = dev_name(&hdev->dev); + hdev->id = id; + + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); +@@ -2638,8 +2642,6 @@ int hci_register_dev(struct hci_dev *hdev) + if (!IS_ERR_OR_NULL(bt_debugfs)) + hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); + +- dev_set_name(&hdev->dev, "%s", hdev->name); +- + error = device_add(&hdev->dev); + if (error < 0) + goto err_wqueue; +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index e4d8857716eb7..c86a45344fe28 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -25,6 +25,8 @@ + /* Bluetooth HCI event handling. */ + + #include <asm/unaligned.h> ++#include <linux/crypto.h> ++#include <crypto/algapi.h> + + #include <net/bluetooth/bluetooth.h> + #include <net/bluetooth/hci_core.h> +@@ -3277,6 +3279,16 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, + + bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type); + ++ /* Reject incoming connection from device with same BD ADDR against ++ * CVE-2020-26555 ++ */ ++ if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) { ++ bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n", ++ &ev->bdaddr); ++ hci_reject_conn(hdev, &ev->bdaddr); ++ return; ++ } ++ + mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, + &flags); + +@@ -4686,6 +4698,15 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data, + if (!conn) + goto unlock; + ++ /* Ignore NULL link key against CVE-2020-26555 */ ++ if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) { ++ bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR", ++ &ev->bdaddr); ++ hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); ++ hci_conn_drop(conn); ++ goto unlock; ++ } ++ + hci_conn_hold(conn); + conn->disc_timeout = HCI_DISCONN_TIMEOUT; + hci_conn_drop(conn); +@@ -5221,8 +5242,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) + * available, then do not declare that OOB data is + * present. + */ +- if (!memcmp(data->rand256, ZERO_KEY, 16) || +- !memcmp(data->hash256, ZERO_KEY, 16)) ++ if (!crypto_memneq(data->rand256, ZERO_KEY, 16) || ++ !crypto_memneq(data->hash256, ZERO_KEY, 16)) + return 0x00; + + return 0x02; +@@ -5232,8 +5253,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) + * not supported by the hardware, then check that if + * P-192 data values are present. + */ +- if (!memcmp(data->rand192, ZERO_KEY, 16) || +- !memcmp(data->hash192, ZERO_KEY, 16)) ++ if (!crypto_memneq(data->rand192, ZERO_KEY, 16) || ++ !crypto_memneq(data->hash192, ZERO_KEY, 16)) + return 0x00; + + return 0x01; +@@ -5250,7 +5271,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data, + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); +- if (!conn) ++ if (!conn || !hci_conn_ssp_enabled(conn)) + goto unlock; + + hci_conn_hold(conn); +@@ -5497,7 +5518,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data, + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); +- if (!conn) ++ if (!conn || !hci_conn_ssp_enabled(conn)) + goto unlock; + + /* Reset the authentication requirement to unknown */ +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index 1d249d839819d..484fc2a8e4baa 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -439,7 +439,8 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) + ni->type = hdev->dev_type; + ni->bus = hdev->bus; + bacpy(&ni->bdaddr, &hdev->bdaddr); +- memcpy(ni->name, hdev->name, 8); ++ memcpy_and_pad(ni->name, sizeof(ni->name), hdev->name, ++ strnlen(hdev->name, sizeof(ni->name)), '\0'); + + opcode = cpu_to_le16(HCI_MON_NEW_INDEX); + break; +diff --git a/net/core/dev.c b/net/core/dev.c +index 5374761f5af2c..0d5aa820fd830 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -345,7 +345,6 @@ int netdev_name_node_alt_create(struct net_device *dev, const char *name) + static void __netdev_name_node_alt_destroy(struct netdev_name_node *name_node) + { + list_del(&name_node->list); +- netdev_name_node_del(name_node); + kfree(name_node->name); + netdev_name_node_free(name_node); + } +@@ -364,6 +363,8 @@ int netdev_name_node_alt_destroy(struct net_device *dev, const char *name) + if (name_node == dev->name_node || name_node->dev != dev) + return -EINVAL; + ++ netdev_name_node_del(name_node); ++ synchronize_rcu(); + __netdev_name_node_alt_destroy(name_node); + + return 0; +@@ -380,6 +381,7 @@ static void netdev_name_node_alt_flush(struct net_device *dev) + /* Device list insertion */ + static void list_netdevice(struct net_device *dev) + { ++ struct netdev_name_node *name_node; + struct net *net = dev_net(dev); + + ASSERT_RTNL(); +@@ -391,6 +393,9 @@ static void list_netdevice(struct net_device *dev) + dev_index_hash(net, dev->ifindex)); + write_unlock(&dev_base_lock); + ++ netdev_for_each_altname(dev, name_node) ++ netdev_name_node_add(net, name_node); ++ + dev_base_seq_inc(net); + } + +@@ -399,8 +404,13 @@ static void list_netdevice(struct net_device *dev) + */ + static void unlist_netdevice(struct net_device *dev, bool lock) + { ++ struct netdev_name_node *name_node; ++ + ASSERT_RTNL(); + ++ netdev_for_each_altname(dev, name_node) ++ netdev_name_node_del(name_node); ++ + /* Unlink dev from the device chain */ + if (lock) + write_lock(&dev_base_lock); +@@ -1053,7 +1063,8 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + + for_each_netdev(net, d) { + struct netdev_name_node *name_node; +- list_for_each_entry(name_node, &d->name_node->list, list) { ++ ++ netdev_for_each_altname(d, name_node) { + if (!sscanf(name_node->name, name, &i)) + continue; + if (i < 0 || i >= max_netdevices) +@@ -1090,6 +1101,26 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + return -ENFILE; + } + ++static int dev_prep_valid_name(struct net *net, struct net_device *dev, ++ const char *want_name, char *out_name) ++{ ++ int ret; ++ ++ if (!dev_valid_name(want_name)) ++ return -EINVAL; ++ ++ if (strchr(want_name, '%')) { ++ ret = __dev_alloc_name(net, want_name, out_name); ++ return ret < 0 ? ret : 0; ++ } else if (netdev_name_in_use(net, want_name)) { ++ return -EEXIST; ++ } else if (out_name != want_name) { ++ strscpy(out_name, want_name, IFNAMSIZ); ++ } ++ ++ return 0; ++} ++ + static int dev_alloc_name_ns(struct net *net, + struct net_device *dev, + const char *name) +@@ -1127,19 +1158,13 @@ EXPORT_SYMBOL(dev_alloc_name); + static int dev_get_valid_name(struct net *net, struct net_device *dev, + const char *name) + { +- BUG_ON(!net); +- +- if (!dev_valid_name(name)) +- return -EINVAL; +- +- if (strchr(name, '%')) +- return dev_alloc_name_ns(net, dev, name); +- else if (netdev_name_in_use(net, name)) +- return -EEXIST; +- else if (dev->name != name) +- strscpy(dev->name, name, IFNAMSIZ); ++ char buf[IFNAMSIZ]; ++ int ret; + +- return 0; ++ ret = dev_prep_valid_name(net, dev, name, buf); ++ if (ret >= 0) ++ strscpy(dev->name, buf, IFNAMSIZ); ++ return ret; + } + + /** +@@ -10930,7 +10955,9 @@ EXPORT_SYMBOL(unregister_netdev); + int __dev_change_net_namespace(struct net_device *dev, struct net *net, + const char *pat, int new_ifindex) + { ++ struct netdev_name_node *name_node; + struct net *net_old = dev_net(dev); ++ char new_name[IFNAMSIZ] = {}; + int err, new_nsid; + + ASSERT_RTNL(); +@@ -10957,10 +10984,15 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, + /* We get here if we can't use the current device name */ + if (!pat) + goto out; +- err = dev_get_valid_name(net, dev, pat); ++ err = dev_prep_valid_name(net, dev, pat, new_name); + if (err < 0) + goto out; + } ++ /* Check that none of the altnames conflicts. */ ++ err = -EEXIST; ++ netdev_for_each_altname(dev, name_node) ++ if (netdev_name_in_use(net, name_node->name)) ++ goto out; + + /* Check that new_ifindex isn't used yet. */ + err = -EBUSY; +@@ -11025,6 +11057,9 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, + kobject_uevent(&dev->dev.kobj, KOBJ_ADD); + netdev_adjacent_add_links(dev); + ++ if (new_name[0]) /* Rename the netdev to prepared name */ ++ strscpy(dev->name, new_name, IFNAMSIZ); ++ + /* Fixup kobjects */ + err = device_rename(&dev->dev, dev->name); + WARN_ON(err); +diff --git a/net/core/dev.h b/net/core/dev.h +index cbb8a925175a2..9ca91457c197e 100644 +--- a/net/core/dev.h ++++ b/net/core/dev.h +@@ -61,6 +61,9 @@ struct netdev_name_node { + int netdev_get_name(struct net *net, char *name, int ifindex); + int dev_change_name(struct net_device *dev, const char *newname); + ++#define netdev_for_each_altname(dev, namenode) \ ++ list_for_each_entry((namenode), &(dev)->name_node->list, list) ++ + int netdev_name_node_alt_create(struct net_device *dev, const char *name); + int netdev_name_node_alt_destroy(struct net_device *dev, const char *name); + +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index c3763056c554a..471d4effa8b49 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -669,19 +669,19 @@ static int pktgen_if_show(struct seq_file *seq, void *v) + seq_puts(seq, " Flags: "); + + for (i = 0; i < NR_PKT_FLAGS; i++) { +- if (i == F_FLOW_SEQ) ++ if (i == FLOW_SEQ_SHIFT) + if (!pkt_dev->cflows) + continue; + +- if (pkt_dev->flags & (1 << i)) ++ if (pkt_dev->flags & (1 << i)) { + seq_printf(seq, "%s ", pkt_flag_names[i]); +- else if (i == F_FLOW_SEQ) +- seq_puts(seq, "FLOW_RND "); +- + #ifdef CONFIG_XFRM +- if (i == F_IPSEC && pkt_dev->spi) +- seq_printf(seq, "spi:%u", pkt_dev->spi); ++ if (i == IPSEC_SHIFT && pkt_dev->spi) ++ seq_printf(seq, "spi:%u ", pkt_dev->spi); + #endif ++ } else if (i == FLOW_SEQ_SHIFT) { ++ seq_puts(seq, "FLOW_RND "); ++ } + } + + seq_puts(seq, "\n"); +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 9d4507aa736b7..854b3fd66b1be 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -5394,13 +5394,11 @@ static unsigned int + rtnl_offload_xstats_get_size_hw_s_info_one(const struct net_device *dev, + enum netdev_offload_xstats_type type) + { +- bool enabled = netdev_offload_xstats_enabled(dev, type); +- + return nla_total_size(0) + + /* IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST */ + nla_total_size(sizeof(u8)) + + /* IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED */ +- (enabled ? nla_total_size(sizeof(u8)) : 0) + ++ nla_total_size(sizeof(u8)) + + 0; + } + +diff --git a/net/core/stream.c b/net/core/stream.c +index 5b05b889d31af..051aa71a8ad0f 100644 +--- a/net/core/stream.c ++++ b/net/core/stream.c +@@ -117,7 +117,7 @@ EXPORT_SYMBOL(sk_stream_wait_close); + */ + int sk_stream_wait_memory(struct sock *sk, long *timeo_p) + { +- int err = 0; ++ int ret, err = 0; + long vm_wait = 0; + long current_timeo = *timeo_p; + DEFINE_WAIT_FUNC(wait, woken_wake_function); +@@ -142,11 +142,13 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) + + set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + sk->sk_write_pending++; +- sk_wait_event(sk, ¤t_timeo, READ_ONCE(sk->sk_err) || +- (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) || +- (sk_stream_memory_free(sk) && +- !vm_wait), &wait); ++ ret = sk_wait_event(sk, ¤t_timeo, READ_ONCE(sk->sk_err) || ++ (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) || ++ (sk_stream_memory_free(sk) && !vm_wait), ++ &wait); + sk->sk_write_pending--; ++ if (ret < 0) ++ goto do_error; + + if (vm_wait) { + vm_wait -= current_timeo; +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 04853c83c85c4..5d379df90c826 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -589,7 +589,6 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) + + add_wait_queue(sk_sleep(sk), &wait); + sk->sk_write_pending += writebias; +- sk->sk_wait_pending++; + + /* Basic assumption: if someone sets sk->sk_err, he _must_ + * change state of the socket from TCP_SYN_*. +@@ -605,7 +604,6 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) + } + remove_wait_queue(sk_sleep(sk), &wait); + sk->sk_write_pending -= writebias; +- sk->sk_wait_pending--; + return timeo; + } + +@@ -634,6 +632,7 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, + return -EINVAL; + + if (uaddr->sa_family == AF_UNSPEC) { ++ sk->sk_disconnects++; + err = sk->sk_prot->disconnect(sk, flags); + sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED; + goto out; +@@ -688,6 +687,7 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, + int writebias = (sk->sk_protocol == IPPROTO_TCP) && + tcp_sk(sk)->fastopen_req && + tcp_sk(sk)->fastopen_req->data ? 1 : 0; ++ int dis = sk->sk_disconnects; + + /* Error code is set above */ + if (!timeo || !inet_wait_for_connect(sk, timeo, writebias)) +@@ -696,6 +696,11 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, + err = sock_intr_errno(timeo); + if (signal_pending(current)) + goto out; ++ ++ if (dis != sk->sk_disconnects) { ++ err = -EPIPE; ++ goto out; ++ } + } + + /* Connection was closed by RST, timeout, ICMP error +@@ -717,6 +722,7 @@ out: + sock_error: + err = sock_error(sk) ? : -ECONNABORTED; + sock->state = SS_UNCONNECTED; ++ sk->sk_disconnects++; + if (sk->sk_prot->disconnect(sk, flags)) + sock->state = SS_DISCONNECTING; + goto out; +diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c +index 2d094d417ecae..e2546961add3e 100644 +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -732,7 +732,9 @@ static inline int esp_remove_trailer(struct sk_buff *skb) + skb->csum = csum_block_sub(skb->csum, csumdiff, + skb->len - trimlen); + } +- pskb_trim(skb, skb->len - trimlen); ++ ret = pskb_trim(skb, skb->len - trimlen); ++ if (unlikely(ret)) ++ return ret; + + ret = nexthdr[1]; + +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index eafa4a0335157..5eb1b8d302bbd 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -1325,15 +1325,18 @@ __be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc, + unsigned char scope) + { + struct fib_nh *nh; ++ __be32 saddr; + + if (nhc->nhc_family != AF_INET) + return inet_select_addr(nhc->nhc_dev, 0, scope); + + nh = container_of(nhc, struct fib_nh, nh_common); +- nh->nh_saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope); +- nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid); ++ saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope); + +- return nh->nh_saddr; ++ WRITE_ONCE(nh->nh_saddr, saddr); ++ WRITE_ONCE(nh->nh_saddr_genid, atomic_read(&net->ipv4.dev_addr_genid)); ++ ++ return saddr; + } + + __be32 fib_result_prefsrc(struct net *net, struct fib_result *res) +@@ -1347,8 +1350,9 @@ __be32 fib_result_prefsrc(struct net *net, struct fib_result *res) + struct fib_nh *nh; + + nh = container_of(nhc, struct fib_nh, nh_common); +- if (nh->nh_saddr_genid == atomic_read(&net->ipv4.dev_addr_genid)) +- return nh->nh_saddr; ++ if (READ_ONCE(nh->nh_saddr_genid) == ++ atomic_read(&net->ipv4.dev_addr_genid)) ++ return READ_ONCE(nh->nh_saddr); + } + + return fib_info_update_nhc_saddr(net, nhc, res->fi->fib_scope); +@@ -1887,6 +1891,7 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local) + continue; + if (fi->fib_prefsrc == local) { + fi->fib_flags |= RTNH_F_DEAD; ++ fi->pfsrc_removed = true; + ret++; + } + } +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index d13fb9e76b971..9bdfdab906fe0 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -2027,6 +2027,7 @@ void fib_table_flush_external(struct fib_table *tb) + int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) + { + struct trie *t = (struct trie *)tb->tb_data; ++ struct nl_info info = { .nl_net = net }; + struct key_vector *pn = t->kv; + unsigned long cindex = 1; + struct hlist_node *tmp; +@@ -2089,6 +2090,9 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) + + fib_notify_alias_delete(net, n->key, &n->leaf, fa, + NULL); ++ if (fi->pfsrc_removed) ++ rtmsg_fib(RTM_DELROUTE, htonl(n->key), fa, ++ KEYLENGTH - fa->fa_slen, tb->tb_id, &info, 0); + hlist_del_rcu(&fa->fa_list); + fib_release_info(fa->fa_info); + alias_free_mem_rcu(fa); +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index 62a3b103f258a..80ce0112e24b4 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -1143,7 +1143,6 @@ struct sock *inet_csk_clone_lock(const struct sock *sk, + if (newsk) { + struct inet_connection_sock *newicsk = inet_csk(newsk); + +- newsk->sk_wait_pending = 0; + inet_sk_set_state(newsk, TCP_SYN_RECV); + newicsk->icsk_bind_hash = NULL; + newicsk->icsk_bind2_hash = NULL; +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index d79de4b95186b..62d9472ac8bca 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -148,8 +148,14 @@ static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2, + const struct sock *sk) + { + #if IS_ENABLED(CONFIG_IPV6) +- if (sk->sk_family != tb2->family) +- return false; ++ if (sk->sk_family != tb2->family) { ++ if (sk->sk_family == AF_INET) ++ return ipv6_addr_v4mapped(&tb2->v6_rcv_saddr) && ++ tb2->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; ++ ++ return ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr) && ++ sk->sk_v6_rcv_saddr.s6_addr32[3] == tb2->rcv_saddr; ++ } + + if (sk->sk_family == AF_INET6) + return ipv6_addr_equal(&tb2->v6_rcv_saddr, +@@ -799,19 +805,7 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb, + tb->l3mdev != l3mdev) + return false; + +-#if IS_ENABLED(CONFIG_IPV6) +- if (sk->sk_family != tb->family) { +- if (sk->sk_family == AF_INET) +- return ipv6_addr_v4mapped(&tb->v6_rcv_saddr) && +- tb->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; +- +- return false; +- } +- +- if (sk->sk_family == AF_INET6) +- return ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); +-#endif +- return tb->rcv_saddr == sk->sk_rcv_saddr; ++ return inet_bind2_bucket_addr_match(tb, sk); + } + + bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const struct net *net, +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 96fdde6e42b1b..288678f17ccaf 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -827,7 +827,9 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, + */ + if (!skb_queue_empty(&sk->sk_receive_queue)) + break; +- sk_wait_data(sk, &timeo, NULL); ++ ret = sk_wait_data(sk, &timeo, NULL); ++ if (ret < 0) ++ break; + if (signal_pending(current)) { + ret = sock_intr_errno(timeo); + break; +@@ -2549,7 +2551,11 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len, + __sk_flush_backlog(sk); + } else { + tcp_cleanup_rbuf(sk, copied); +- sk_wait_data(sk, &timeo, last); ++ err = sk_wait_data(sk, &timeo, last); ++ if (err < 0) { ++ err = copied ? : err; ++ goto out; ++ } + } + + if ((flags & MSG_PEEK) && +@@ -3073,12 +3079,6 @@ int tcp_disconnect(struct sock *sk, int flags) + int old_state = sk->sk_state; + u32 seq; + +- /* Deny disconnect if other threads are blocked in sk_wait_event() +- * or inet_wait_for_connect(). +- */ +- if (sk->sk_wait_pending) +- return -EBUSY; +- + if (old_state != TCP_CLOSE) + tcp_set_state(sk, TCP_CLOSE); + +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index f53380fd89bcf..f8037d142bb75 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -302,6 +302,10 @@ msg_bytes_ready: + } + + data = tcp_msg_wait_data(sk, psock, timeo); ++ if (data < 0) { ++ copied = data; ++ goto unlock; ++ } + if (data && !sk_psock_queue_empty(psock)) + goto msg_bytes_ready; + copied = -EAGAIN; +@@ -312,6 +316,8 @@ out: + tcp_rcv_space_adjust(sk); + if (copied > 0) + __tcp_cleanup_rbuf(sk, copied); ++ ++unlock: + release_sock(sk); + sk_psock_put(sk, psock); + return copied; +@@ -346,6 +352,10 @@ msg_bytes_ready: + + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + data = tcp_msg_wait_data(sk, psock, timeo); ++ if (data < 0) { ++ ret = data; ++ goto unlock; ++ } + if (data) { + if (!sk_psock_queue_empty(psock)) + goto msg_bytes_ready; +@@ -356,6 +366,8 @@ msg_bytes_ready: + copied = -EAGAIN; + } + ret = copied; ++ ++unlock: + release_sock(sk); + sk_psock_put(sk, psock); + return ret; +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index 5df19f93f86ab..7ebbbe561e402 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -1818,6 +1818,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb, + #ifdef CONFIG_TLS_DEVICE + tail->decrypted != skb->decrypted || + #endif ++ !mptcp_skb_can_collapse(tail, skb) || + thtail->doff != th->doff || + memcmp(thtail + 1, th + 1, hdrlen - sizeof(*th))) + goto no_coalesce; +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 443b1cab25299..cc7ed86fb0a57 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2489,6 +2489,18 @@ static bool tcp_pacing_check(struct sock *sk) + return true; + } + ++static bool tcp_rtx_queue_empty_or_single_skb(const struct sock *sk) ++{ ++ const struct rb_node *node = sk->tcp_rtx_queue.rb_node; ++ ++ /* No skb in the rtx queue. */ ++ if (!node) ++ return true; ++ ++ /* Only one skb in rtx queue. */ ++ return !node->rb_left && !node->rb_right; ++} ++ + /* TCP Small Queues : + * Control number of packets in qdisc/devices to two packets / or ~1 ms. + * (These limits are doubled for retransmits) +@@ -2526,12 +2538,12 @@ static bool tcp_small_queue_check(struct sock *sk, const struct sk_buff *skb, + limit += extra_bytes; + } + if (refcount_read(&sk->sk_wmem_alloc) > limit) { +- /* Always send skb if rtx queue is empty. ++ /* Always send skb if rtx queue is empty or has one skb. + * No need to wait for TX completion to call us back, + * after softirq/tasklet schedule. + * This helps when TX completions are delayed too much. + */ +- if (tcp_rtx_queue_empty(sk)) ++ if (tcp_rtx_queue_empty_or_single_skb(sk)) + return false; + + set_bit(TSQ_THROTTLED, &sk->sk_tsq_flags); +@@ -2735,7 +2747,7 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto) + { + struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); +- u32 timeout, rto_delta_us; ++ u32 timeout, timeout_us, rto_delta_us; + int early_retrans; + + /* Don't do any loss probe on a Fast Open connection before 3WHS +@@ -2759,11 +2771,12 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto) + * sample is available then probe after TCP_TIMEOUT_INIT. + */ + if (tp->srtt_us) { +- timeout = usecs_to_jiffies(tp->srtt_us >> 2); ++ timeout_us = tp->srtt_us >> 2; + if (tp->packets_out == 1) +- timeout += TCP_RTO_MIN; ++ timeout_us += tcp_rto_min_us(sk); + else +- timeout += TCP_TIMEOUT_MIN; ++ timeout_us += TCP_TIMEOUT_MIN_US; ++ timeout = usecs_to_jiffies(timeout_us); + } else { + timeout = TCP_TIMEOUT_INIT; + } +diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c +index 50abaa941387d..c085793691102 100644 +--- a/net/ipv4/tcp_recovery.c ++++ b/net/ipv4/tcp_recovery.c +@@ -104,7 +104,7 @@ bool tcp_rack_mark_lost(struct sock *sk) + tp->rack.advanced = 0; + tcp_rack_detect_loss(sk, &timeout); + if (timeout) { +- timeout = usecs_to_jiffies(timeout) + TCP_TIMEOUT_MIN; ++ timeout = usecs_to_jiffies(timeout + TCP_TIMEOUT_MIN_US); + inet_csk_reset_xmit_timer(sk, ICSK_TIME_REO_TIMEOUT, + timeout, inet_csk(sk)->icsk_rto); + } +diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c +index 14ed868680c6a..c2dcb5c613b6b 100644 +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -770,7 +770,9 @@ static inline int esp_remove_trailer(struct sk_buff *skb) + skb->csum = csum_block_sub(skb->csum, csumdiff, + skb->len - trimlen); + } +- pskb_trim(skb, skb->len - trimlen); ++ ret = pskb_trim(skb, skb->len - trimlen); ++ if (unlikely(ret)) ++ return ret; + + ret = nexthdr[1]; + +diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c +index ea435eba30534..f0053087d2e47 100644 +--- a/net/ipv6/xfrm6_policy.c ++++ b/net/ipv6/xfrm6_policy.c +@@ -118,11 +118,11 @@ static void xfrm6_dst_destroy(struct dst_entry *dst) + { + struct xfrm_dst *xdst = (struct xfrm_dst *)dst; + +- if (likely(xdst->u.rt6.rt6i_idev)) +- in6_dev_put(xdst->u.rt6.rt6i_idev); + dst_destroy_metrics_generic(dst); + if (xdst->u.rt6.rt6i_uncached_list) + rt6_uncached_list_del(&xdst->u.rt6); ++ if (likely(xdst->u.rt6.rt6i_idev)) ++ in6_dev_put(xdst->u.rt6.rt6i_idev); + xfrm_dst_destroy(xdst); + } + +diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c +index 0167413d56972..ee9f455bb2d18 100644 +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1748,7 +1748,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, + /* VHT can override some HT caps such as the A-MSDU max length */ + if (params->vht_capa) + ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, +- params->vht_capa, link_sta); ++ params->vht_capa, NULL, ++ link_sta); + + if (params->he_capa) + ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, +diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c +index 9dffc30795887..79d2c55052897 100644 +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -1068,7 +1068,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, + &chandef); + memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie)); + ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, +- &cap_ie, ++ &cap_ie, NULL, + &sta->deflink); + if (memcmp(&cap, &sta->sta.deflink.vht_cap, sizeof(cap))) + rates_updated |= true; +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 27479bbb093ac..99a976ea17498 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2062,6 +2062,7 @@ void + ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, + struct ieee80211_supported_band *sband, + const struct ieee80211_vht_cap *vht_cap_ie, ++ const struct ieee80211_vht_cap *vht_cap_ie2, + struct link_sta_info *link_sta); + enum ieee80211_sta_rx_bandwidth + ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta); +diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c +index ddfe5102b9a43..bd0b7c189adfa 100644 +--- a/net/mac80211/mesh_plink.c ++++ b/net/mac80211/mesh_plink.c +@@ -443,7 +443,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, + changed |= IEEE80211_RC_BW_CHANGED; + + ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, +- elems->vht_cap_elem, ++ elems->vht_cap_elem, NULL, + &sta->deflink); + + ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap, +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index dc9e7eb7dd857..c07645c999f9a 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -4083,10 +4083,33 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, + elems->ht_cap_elem, + link_sta); + +- if (elems->vht_cap_elem && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) ++ if (elems->vht_cap_elem && ++ !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) { ++ const struct ieee80211_vht_cap *bss_vht_cap = NULL; ++ const struct cfg80211_bss_ies *ies; ++ ++ /* ++ * Cisco AP module 9115 with FW 17.3 has a bug and sends a ++ * too large maximum MPDU length in the association response ++ * (indicating 12k) that it cannot actually process ... ++ * Work around that. ++ */ ++ rcu_read_lock(); ++ ies = rcu_dereference(cbss->ies); ++ if (ies) { ++ const struct element *elem; ++ ++ elem = cfg80211_find_elem(WLAN_EID_VHT_CAPABILITY, ++ ies->data, ies->len); ++ if (elem && elem->datalen >= sizeof(*bss_vht_cap)) ++ bss_vht_cap = (const void *)elem->data; ++ } ++ + ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, + elems->vht_cap_elem, +- link_sta); ++ bss_vht_cap, link_sta); ++ rcu_read_unlock(); ++ } + + if (elems->he_operation && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) && + elems->he_cap) { +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index 2f9e1abdf375d..2db103a56a28f 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -680,7 +680,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) + } + + if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED && +- !ieee80211_is_deauth(hdr->frame_control))) ++ !ieee80211_is_deauth(hdr->frame_control)) && ++ tx->skb->protocol != tx->sdata->control_port_protocol) + return TX_DROP; + + if (!skip_hw && tx->key && +diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c +index 803de58814852..f7526be8a1c7e 100644 +--- a/net/mac80211/vht.c ++++ b/net/mac80211/vht.c +@@ -4,7 +4,7 @@ + * + * Portions of this file + * Copyright(c) 2015 - 2016 Intel Deutschland GmbH +- * Copyright (C) 2018 - 2022 Intel Corporation ++ * Copyright (C) 2018 - 2023 Intel Corporation + */ + + #include <linux/ieee80211.h> +@@ -116,12 +116,14 @@ void + ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, + struct ieee80211_supported_band *sband, + const struct ieee80211_vht_cap *vht_cap_ie, ++ const struct ieee80211_vht_cap *vht_cap_ie2, + struct link_sta_info *link_sta) + { + struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap; + struct ieee80211_sta_vht_cap own_cap; + u32 cap_info, i; + bool have_80mhz; ++ u32 mpdu_len; + + memset(vht_cap, 0, sizeof(*vht_cap)); + +@@ -317,11 +319,21 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, + + link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta); + ++ /* ++ * Work around the Cisco 9115 FW 17.3 bug by taking the min of ++ * both reported MPDU lengths. ++ */ ++ mpdu_len = vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK; ++ if (vht_cap_ie2) ++ mpdu_len = min_t(u32, mpdu_len, ++ le32_get_bits(vht_cap_ie2->vht_cap_info, ++ IEEE80211_VHT_CAP_MAX_MPDU_MASK)); ++ + /* + * FIXME - should the amsdu len be per link? store per link + * and maintain a minimum? + */ +- switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) { ++ switch (mpdu_len) { + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: + link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454; + break; +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 881e05193ac97..0eb20274459c8 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1342,7 +1342,7 @@ alloc_skb: + if (copy == 0) { + u64 snd_una = READ_ONCE(msk->snd_una); + +- if (snd_una != msk->snd_nxt) { ++ if (snd_una != msk->snd_nxt || tcp_write_queue_tail(ssk)) { + tcp_remove_empty_skb(ssk); + return 0; + } +@@ -1350,11 +1350,6 @@ alloc_skb: + zero_window_probe = true; + data_seq = snd_una - 1; + copy = 1; +- +- /* all mptcp-level data is acked, no skbs should be present into the +- * ssk write queue +- */ +- WARN_ON_ONCE(reuse_skb); + } + + copy = min_t(size_t, copy, info->limit - info->sent); +@@ -1383,7 +1378,6 @@ alloc_skb: + if (reuse_skb) { + TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; + mpext->data_len += copy; +- WARN_ON_ONCE(zero_window_probe); + goto out; + } + +@@ -2374,6 +2368,26 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) + #define MPTCP_CF_PUSH BIT(1) + #define MPTCP_CF_FASTCLOSE BIT(2) + ++/* be sure to send a reset only if the caller asked for it, also ++ * clean completely the subflow status when the subflow reaches ++ * TCP_CLOSE state ++ */ ++static void __mptcp_subflow_disconnect(struct sock *ssk, ++ struct mptcp_subflow_context *subflow, ++ unsigned int flags) ++{ ++ if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || ++ (flags & MPTCP_CF_FASTCLOSE)) { ++ /* The MPTCP code never wait on the subflow sockets, TCP-level ++ * disconnect should never fail ++ */ ++ WARN_ON_ONCE(tcp_disconnect(ssk, 0)); ++ mptcp_subflow_ctx_reset(subflow); ++ } else { ++ tcp_shutdown(ssk, SEND_SHUTDOWN); ++ } ++} ++ + /* subflow sockets can be either outgoing (connect) or incoming + * (accept). + * +@@ -2411,7 +2425,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, + lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); + + if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) { +- /* be sure to force the tcp_disconnect() path, ++ /* be sure to force the tcp_close path + * to generate the egress reset + */ + ssk->sk_lingertime = 0; +@@ -2421,12 +2435,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, + + need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); + if (!dispose_it) { +- /* The MPTCP code never wait on the subflow sockets, TCP-level +- * disconnect should never fail +- */ +- WARN_ON_ONCE(tcp_disconnect(ssk, 0)); ++ __mptcp_subflow_disconnect(ssk, subflow, flags); + msk->subflow->state = SS_UNCONNECTED; +- mptcp_subflow_ctx_reset(subflow); + release_sock(ssk); + + goto out; +@@ -3107,12 +3117,6 @@ static int mptcp_disconnect(struct sock *sk, int flags) + { + struct mptcp_sock *msk = mptcp_sk(sk); + +- /* Deny disconnect if other threads are blocked in sk_wait_event() +- * or inet_wait_for_connect(). +- */ +- if (sk->sk_wait_pending) +- return -EBUSY; +- + /* We are on the fastopen error path. We can't call straight into the + * subflows cleanup code due to lock nesting (we are already under + * msk->firstsocket lock). +@@ -3180,7 +3184,6 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk, + inet_sk(nsk)->pinet6 = mptcp_inet6_sk(nsk); + #endif + +- nsk->sk_wait_pending = 0; + __mptcp_init_sock(nsk); + + msk = mptcp_sk(nsk); +diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c +index d7de2ecb287eb..f44f2eaf32172 100644 +--- a/net/netfilter/nft_payload.c ++++ b/net/netfilter/nft_payload.c +@@ -132,7 +132,7 @@ void nft_payload_eval(const struct nft_expr *expr, + + switch (priv->base) { + case NFT_PAYLOAD_LL_HEADER: +- if (!skb_mac_header_was_set(skb)) ++ if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) == 0) + goto err; + + if (skb_vlan_tag_present(skb)) { +diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c +index 2660ceab3759d..e34662f4a71e0 100644 +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -568,6 +568,8 @@ static void *nft_rbtree_deactivate(const struct net *net, + nft_rbtree_interval_end(this)) { + parent = parent->rb_right; + continue; ++ } else if (nft_set_elem_expired(&rbe->ext)) { ++ break; + } else if (!nft_set_elem_active(&rbe->ext, genmask)) { + parent = parent->rb_left; + continue; +diff --git a/net/nfc/nci/spi.c b/net/nfc/nci/spi.c +index 0935527d1d12b..b68150c971d0b 100644 +--- a/net/nfc/nci/spi.c ++++ b/net/nfc/nci/spi.c +@@ -151,6 +151,8 @@ static int send_acknowledge(struct nci_spi *nspi, u8 acknowledge) + int ret; + + skb = nci_skb_alloc(nspi->ndev, 0, GFP_KERNEL); ++ if (!skb) ++ return -ENOMEM; + + /* add the NCI SPI header to the start of the buffer */ + hdr = skb_push(skb, NCI_SPI_HDR_LEN); +diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c +index f5afc9bcdee65..2cc95c8dc4c7b 100644 +--- a/net/rfkill/rfkill-gpio.c ++++ b/net/rfkill/rfkill-gpio.c +@@ -98,13 +98,13 @@ static int rfkill_gpio_probe(struct platform_device *pdev) + + rfkill->clk = devm_clk_get(&pdev->dev, NULL); + +- gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW); ++ gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_ASIS); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + + rfkill->reset_gpio = gpio; + +- gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_OUT_LOW); ++ gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_ASIS); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + +diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c +index 61d52594ff6d8..54dddc2ff5025 100644 +--- a/net/sched/sch_hfsc.c ++++ b/net/sched/sch_hfsc.c +@@ -903,6 +903,14 @@ hfsc_change_usc(struct hfsc_class *cl, struct tc_service_curve *usc, + cl->cl_flags |= HFSC_USC; + } + ++static void ++hfsc_upgrade_rt(struct hfsc_class *cl) ++{ ++ cl->cl_fsc = cl->cl_rsc; ++ rtsc_init(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vt, cl->cl_total); ++ cl->cl_flags |= HFSC_FSC; ++} ++ + static const struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = { + [TCA_HFSC_RSC] = { .len = sizeof(struct tc_service_curve) }, + [TCA_HFSC_FSC] = { .len = sizeof(struct tc_service_curve) }, +@@ -1012,10 +1020,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + if (parent == NULL) + return -ENOENT; + } +- if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) { +- NL_SET_ERR_MSG(extack, "Invalid parent - parent class must have FSC"); +- return -EINVAL; +- } + + if (classid == 0 || TC_H_MAJ(classid ^ sch->handle) != 0) + return -EINVAL; +@@ -1066,6 +1070,12 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + cl->cf_tree = RB_ROOT; + + sch_tree_lock(sch); ++ /* Check if the inner class is a misconfigured 'rt' */ ++ if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) { ++ NL_SET_ERR_MSG(extack, ++ "Forced curve change on parent 'rt' to 'sc'"); ++ hfsc_upgrade_rt(parent); ++ } + qdisc_class_hash_insert(&q->clhash, &cl->cl_common); + list_add_tail(&cl->siblings, &parent->children); + if (parent->level == 0) +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index f774d840759d6..4ea41d6e36969 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -1187,6 +1187,7 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc, + struct smc_clc_first_contact_ext *fce = + (struct smc_clc_first_contact_ext *) + (((u8 *)clc_v2) + sizeof(*clc_v2)); ++ struct net *net = sock_net(&smc->sk); + + if (!ini->first_contact_peer || aclc->hdr.version == SMC_V1) + return 0; +@@ -1195,7 +1196,7 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc, + memcpy(ini->smcrv2.nexthop_mac, &aclc->r0.lcl.mac, ETH_ALEN); + ini->smcrv2.uses_gateway = false; + } else { +- if (smc_ib_find_route(smc->clcsock->sk->sk_rcv_saddr, ++ if (smc_ib_find_route(net, smc->clcsock->sk->sk_rcv_saddr, + smc_ib_gid_to_ipv4(aclc->r0.lcl.gid), + ini->smcrv2.nexthop_mac, + &ini->smcrv2.uses_gateway)) +@@ -2322,7 +2323,7 @@ static int smc_listen_find_device(struct smc_sock *new_smc, + smc_find_ism_store_rc(rc, ini); + return (!rc) ? 0 : ini->rc; + } +- return SMC_CLC_DECL_NOSMCDEV; ++ return prfx_rc; + } + + /* listen worker: finish RDMA setup */ +diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c +index 854772dd52fd1..ace8611735321 100644 +--- a/net/smc/smc_ib.c ++++ b/net/smc/smc_ib.c +@@ -193,7 +193,7 @@ bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport) + return smcibdev->pattr[ibport - 1].state == IB_PORT_ACTIVE; + } + +-int smc_ib_find_route(__be32 saddr, __be32 daddr, ++int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr, + u8 nexthop_mac[], u8 *uses_gateway) + { + struct neighbour *neigh = NULL; +@@ -205,7 +205,7 @@ int smc_ib_find_route(__be32 saddr, __be32 daddr, + + if (daddr == cpu_to_be32(INADDR_NONE)) + goto out; +- rt = ip_route_output_flow(&init_net, &fl4, NULL); ++ rt = ip_route_output_flow(net, &fl4, NULL); + if (IS_ERR(rt)) + goto out; + if (rt->rt_uses_gateway && rt->rt_gw_family != AF_INET) +@@ -235,6 +235,7 @@ static int smc_ib_determine_gid_rcu(const struct net_device *ndev, + if (smcrv2 && attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP && + smc_ib_gid_to_ipv4((u8 *)&attr->gid) != cpu_to_be32(INADDR_NONE)) { + struct in_device *in_dev = __in_dev_get_rcu(ndev); ++ struct net *net = dev_net(ndev); + const struct in_ifaddr *ifa; + bool subnet_match = false; + +@@ -248,7 +249,7 @@ static int smc_ib_determine_gid_rcu(const struct net_device *ndev, + } + if (!subnet_match) + goto out; +- if (smcrv2->daddr && smc_ib_find_route(smcrv2->saddr, ++ if (smcrv2->daddr && smc_ib_find_route(net, smcrv2->saddr, + smcrv2->daddr, + smcrv2->nexthop_mac, + &smcrv2->uses_gateway)) +diff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h +index 034295676e881..ebcb05ede7f55 100644 +--- a/net/smc/smc_ib.h ++++ b/net/smc/smc_ib.h +@@ -113,7 +113,7 @@ void smc_ib_sync_sg_for_device(struct smc_link *lnk, + int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport, + unsigned short vlan_id, u8 gid[], u8 *sgid_index, + struct smc_init_info_smcrv2 *smcrv2); +-int smc_ib_find_route(__be32 saddr, __be32 daddr, ++int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr, + u8 nexthop_mac[], u8 *uses_gateway); + bool smc_ib_is_valid_local_systemid(void); + int smcr_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb); +diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c +index f2e7302a4d96b..338a443fa47b2 100644 +--- a/net/tls/tls_main.c ++++ b/net/tls/tls_main.c +@@ -96,8 +96,8 @@ void update_sk_prot(struct sock *sk, struct tls_context *ctx) + + int wait_on_pending_writer(struct sock *sk, long *timeo) + { +- int rc = 0; + DEFINE_WAIT_FUNC(wait, woken_wake_function); ++ int ret, rc = 0; + + add_wait_queue(sk_sleep(sk), &wait); + while (1) { +@@ -111,9 +111,13 @@ int wait_on_pending_writer(struct sock *sk, long *timeo) + break; + } + +- if (sk_wait_event(sk, timeo, +- !READ_ONCE(sk->sk_write_pending), &wait)) ++ ret = sk_wait_event(sk, timeo, ++ !READ_ONCE(sk->sk_write_pending), &wait); ++ if (ret) { ++ if (ret < 0) ++ rc = ret; + break; ++ } + } + remove_wait_queue(sk_sleep(sk), &wait); + return rc; +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index 9be00ebbb2341..2af72d349192e 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -1296,6 +1296,7 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, + struct tls_context *tls_ctx = tls_get_ctx(sk); + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); + DEFINE_WAIT_FUNC(wait, woken_wake_function); ++ int ret = 0; + long timeo; + + timeo = sock_rcvtimeo(sk, nonblock); +@@ -1307,6 +1308,9 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, + if (sk->sk_err) + return sock_error(sk); + ++ if (ret < 0) ++ return ret; ++ + if (!skb_queue_empty(&sk->sk_receive_queue)) { + tls_strp_check_rcv(&ctx->strp); + if (tls_strp_msg_ready(ctx)) +@@ -1325,10 +1329,10 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock, + released = true; + add_wait_queue(sk_sleep(sk), &wait); + sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); +- sk_wait_event(sk, &timeo, +- tls_strp_msg_ready(ctx) || +- !sk_psock_queue_empty(psock), +- &wait); ++ ret = sk_wait_event(sk, &timeo, ++ tls_strp_msg_ready(ctx) || ++ !sk_psock_queue_empty(psock), ++ &wait); + sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); + remove_wait_queue(sk_sleep(sk), &wait); + +@@ -1851,13 +1855,11 @@ tls_read_flush_backlog(struct sock *sk, struct tls_prot_info *prot, + return sk_flush_backlog(sk); + } + +-static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, +- bool nonblock) ++static int tls_rx_reader_acquire(struct sock *sk, struct tls_sw_context_rx *ctx, ++ bool nonblock) + { + long timeo; +- int err; +- +- lock_sock(sk); ++ int ret; + + timeo = sock_rcvtimeo(sk, nonblock); + +@@ -1867,30 +1869,36 @@ static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, + ctx->reader_contended = 1; + + add_wait_queue(&ctx->wq, &wait); +- sk_wait_event(sk, &timeo, +- !READ_ONCE(ctx->reader_present), &wait); ++ ret = sk_wait_event(sk, &timeo, ++ !READ_ONCE(ctx->reader_present), &wait); + remove_wait_queue(&ctx->wq, &wait); + +- if (timeo <= 0) { +- err = -EAGAIN; +- goto err_unlock; +- } +- if (signal_pending(current)) { +- err = sock_intr_errno(timeo); +- goto err_unlock; +- } ++ if (timeo <= 0) ++ return -EAGAIN; ++ if (signal_pending(current)) ++ return sock_intr_errno(timeo); ++ if (ret < 0) ++ return ret; + } + + WRITE_ONCE(ctx->reader_present, 1); + + return 0; ++} + +-err_unlock: +- release_sock(sk); ++static int tls_rx_reader_lock(struct sock *sk, struct tls_sw_context_rx *ctx, ++ bool nonblock) ++{ ++ int err; ++ ++ lock_sock(sk); ++ err = tls_rx_reader_acquire(sk, ctx, nonblock); ++ if (err) ++ release_sock(sk); + return err; + } + +-static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) ++static void tls_rx_reader_release(struct sock *sk, struct tls_sw_context_rx *ctx) + { + if (unlikely(ctx->reader_contended)) { + if (wq_has_sleeper(&ctx->wq)) +@@ -1902,6 +1910,11 @@ static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) + } + + WRITE_ONCE(ctx->reader_present, 0); ++} ++ ++static void tls_rx_reader_unlock(struct sock *sk, struct tls_sw_context_rx *ctx) ++{ ++ tls_rx_reader_release(sk, ctx); + release_sock(sk); + } + +diff --git a/net/wireless/core.c b/net/wireless/core.c +index 2c79604672062..bf2f1f583fb12 100644 +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -1618,7 +1618,7 @@ void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work) + list_add_tail(&work->entry, &rdev->wiphy_work_list); + spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); + +- schedule_work(&rdev->wiphy_work); ++ queue_work(system_unbound_wq, &rdev->wiphy_work); + } + EXPORT_SYMBOL_GPL(wiphy_work_queue); + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 1d993a490ac4b..b19b5acfaf3a9 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -8289,7 +8289,7 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; +- struct mesh_config cfg; ++ struct mesh_config cfg = {}; + u32 mask; + int err; + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index e5c1510c098fd..b7e1631b3d80d 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -876,6 +876,10 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev) + !cfg80211_find_ssid_match(ap, request)) + continue; + ++ if (!is_broadcast_ether_addr(request->bssid) && ++ !ether_addr_equal(request->bssid, ap->bssid)) ++ continue; ++ + if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid) + continue; + +diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c +index d71dbe822096a..85501b77f4e37 100644 +--- a/net/xfrm/xfrm_interface_core.c ++++ b/net/xfrm/xfrm_interface_core.c +@@ -379,8 +379,8 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err) + skb->dev = dev; + + if (err) { +- dev->stats.rx_errors++; +- dev->stats.rx_dropped++; ++ DEV_STATS_INC(dev, rx_errors); ++ DEV_STATS_INC(dev, rx_dropped); + + return 0; + } +@@ -425,7 +425,6 @@ static int + xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + { + struct xfrm_if *xi = netdev_priv(dev); +- struct net_device_stats *stats = &xi->dev->stats; + struct dst_entry *dst = skb_dst(skb); + unsigned int length = skb->len; + struct net_device *tdev; +@@ -464,7 +463,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + tdev = dst->dev; + + if (tdev == dev) { +- stats->collisions++; ++ DEV_STATS_INC(dev, collisions); + net_warn_ratelimited("%s: Local routing loop detected!\n", + dev->name); + goto tx_err_dst_release; +@@ -503,13 +502,13 @@ xmit: + if (net_xmit_eval(err) == 0) { + dev_sw_netstats_tx_add(dev, 1, length); + } else { +- stats->tx_errors++; +- stats->tx_aborted_errors++; ++ DEV_STATS_INC(dev, tx_errors); ++ DEV_STATS_INC(dev, tx_aborted_errors); + } + + return 0; + tx_err_link_failure: +- stats->tx_carrier_errors++; ++ DEV_STATS_INC(dev, tx_carrier_errors); + dst_link_failure(skb); + tx_err_dst_release: + dst_release(dst); +@@ -519,7 +518,6 @@ tx_err_dst_release: + static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct xfrm_if *xi = netdev_priv(dev); +- struct net_device_stats *stats = &xi->dev->stats; + struct dst_entry *dst = skb_dst(skb); + struct flowi fl; + int ret; +@@ -536,7 +534,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) + dst = ip6_route_output(dev_net(dev), NULL, &fl.u.ip6); + if (dst->error) { + dst_release(dst); +- stats->tx_carrier_errors++; ++ DEV_STATS_INC(dev, tx_carrier_errors); + goto tx_err; + } + skb_dst_set(skb, dst); +@@ -552,7 +550,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) + fl.u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + rt = __ip_route_output_key(dev_net(dev), &fl.u.ip4); + if (IS_ERR(rt)) { +- stats->tx_carrier_errors++; ++ DEV_STATS_INC(dev, tx_carrier_errors); + goto tx_err; + } + skb_dst_set(skb, &rt->dst); +@@ -571,8 +569,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_OK; + + tx_err: +- stats->tx_errors++; +- stats->tx_dropped++; ++ DEV_STATS_INC(dev, tx_errors); ++ DEV_STATS_INC(dev, tx_dropped); + kfree_skb(skb); + return NETDEV_TX_OK; + } +diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c +index e65de78cb61bf..e47c670c7e2cd 100644 +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -850,7 +850,7 @@ static void xfrm_policy_inexact_list_reinsert(struct net *net, + struct hlist_node *newpos = NULL; + bool matches_s, matches_d; + +- if (!policy->bydst_reinsert) ++ if (policy->walk.dead || !policy->bydst_reinsert) + continue; + + WARN_ON_ONCE(policy->family != family); +@@ -1255,8 +1255,11 @@ static void xfrm_hash_rebuild(struct work_struct *work) + struct xfrm_pol_inexact_bin *bin; + u8 dbits, sbits; + ++ if (policy->walk.dead) ++ continue; ++ + dir = xfrm_policy_id2dir(policy->index); +- if (policy->walk.dead || dir >= XFRM_POLICY_MAX) ++ if (dir >= XFRM_POLICY_MAX) + continue; + + if ((dir & XFRM_POLICY_MASK) == XFRM_POLICY_OUT) { +@@ -1371,8 +1374,6 @@ EXPORT_SYMBOL(xfrm_policy_hash_rebuild); + * of an absolute inpredictability of ordering of rules. This will not pass. */ + static u32 xfrm_gen_index(struct net *net, int dir, u32 index) + { +- static u32 idx_generator; +- + for (;;) { + struct hlist_head *list; + struct xfrm_policy *p; +@@ -1380,8 +1381,8 @@ static u32 xfrm_gen_index(struct net *net, int dir, u32 index) + int found; + + if (!index) { +- idx = (idx_generator | dir); +- idx_generator += 8; ++ idx = (net->xfrm.idx_generator | dir); ++ net->xfrm.idx_generator += 8; + } else { + idx = index; + index = 0; +@@ -1790,9 +1791,11 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid) + + again: + list_for_each_entry(pol, &net->xfrm.policy_all, walk.all) { ++ if (pol->walk.dead) ++ continue; ++ + dir = xfrm_policy_id2dir(pol->index); +- if (pol->walk.dead || +- dir >= XFRM_POLICY_MAX || ++ if (dir >= XFRM_POLICY_MAX || + pol->type != type) + continue; + +@@ -3138,7 +3141,7 @@ no_transform: + } + + for (i = 0; i < num_pols; i++) +- pols[i]->curlft.use_time = ktime_get_real_seconds(); ++ WRITE_ONCE(pols[i]->curlft.use_time, ktime_get_real_seconds()); + + if (num_xfrms < 0) { + /* Prohibit the flow */ +diff --git a/samples/fprobe/fprobe_example.c b/samples/fprobe/fprobe_example.c +index e22da8573116e..dd794990ad7ec 100644 +--- a/samples/fprobe/fprobe_example.c ++++ b/samples/fprobe/fprobe_example.c +@@ -48,7 +48,8 @@ static void show_backtrace(void) + stack_trace_print(stacks, len, 24); + } + +-static void sample_entry_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs) ++static void sample_entry_handler(struct fprobe *fp, unsigned long ip, ++ struct pt_regs *regs, void *data) + { + if (use_trace) + /* +@@ -63,7 +64,8 @@ static void sample_entry_handler(struct fprobe *fp, unsigned long ip, struct pt_ + show_backtrace(); + } + +-static void sample_exit_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs) ++static void sample_exit_handler(struct fprobe *fp, unsigned long ip, struct pt_regs *regs, ++ void *data) + { + unsigned long rip = instruction_pointer(regs); + +diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c +index 80aab2aa72246..ff8cce1757849 100644 +--- a/scripts/kallsyms.c ++++ b/scripts/kallsyms.c +@@ -602,7 +602,10 @@ static void write_src(void) + sort_symbols_by_name(); + output_label("kallsyms_seqs_of_names"); + for (i = 0; i < table_cnt; i++) +- printf("\t.long\t%u\n", table[i]->seq); ++ printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n", ++ (unsigned char)(table[i]->seq >> 16), ++ (unsigned char)(table[i]->seq >> 8), ++ (unsigned char)(table[i]->seq >> 0)); + printf("\n"); + + output_label("kallsyms_token_table"); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 14e70e2f9c881..0163d4c7fdda8 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7006,6 +7006,24 @@ static void alc287_fixup_bind_dacs(struct hda_codec *codec, + 0x0); /* Make sure 0x14 was disable */ + } + } ++/* Fix none verb table of Headset Mic pin */ ++static void alc_fixup_headset_mic(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ struct alc_spec *spec = codec->spec; ++ static const struct hda_pintbl pincfgs[] = { ++ { 0x19, 0x03a1103c }, ++ { } ++ }; ++ ++ switch (action) { ++ case HDA_FIXUP_ACT_PRE_PROBE: ++ snd_hda_apply_pincfgs(codec, pincfgs); ++ alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12); ++ spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; ++ break; ++ } ++} + + + enum { +@@ -7270,6 +7288,7 @@ enum { + ALC245_FIXUP_HP_X360_MUTE_LEDS, + ALC287_FIXUP_THINKPAD_I2S_SPK, + ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD, ++ ALC2XX_FIXUP_HEADSET_MIC, + }; + + /* A special fixup for Lenovo C940 and Yoga Duet 7; +@@ -9359,6 +9378,10 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI, + }, ++ [ALC2XX_FIXUP_HEADSET_MIC] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc_fixup_headset_mic, ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -9626,6 +9649,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), ++ SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED), +@@ -9694,6 +9718,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), + SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301V", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), ++ SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), +@@ -10633,6 +10658,8 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = { + SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, + {0x19, 0x40000000}, + {0x1a, 0x40000000}), ++ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC2XX_FIXUP_HEADSET_MIC, ++ {0x19, 0x40000000}), + {} + }; + +diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c +index 9c10200ff34b2..5b5b7c267a616 100644 +--- a/sound/soc/codecs/wcd938x-sdw.c ++++ b/sound/soc/codecs/wcd938x-sdw.c +@@ -1278,7 +1278,31 @@ static int wcd9380_probe(struct sdw_slave *pdev, + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + +- return component_add(dev, &wcd938x_sdw_component_ops); ++ ret = component_add(dev, &wcd938x_sdw_component_ops); ++ if (ret) ++ goto err_disable_rpm; ++ ++ return 0; ++ ++err_disable_rpm: ++ pm_runtime_disable(dev); ++ pm_runtime_set_suspended(dev); ++ pm_runtime_dont_use_autosuspend(dev); ++ ++ return ret; ++} ++ ++static int wcd9380_remove(struct sdw_slave *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ ++ component_del(dev, &wcd938x_sdw_component_ops); ++ ++ pm_runtime_disable(dev); ++ pm_runtime_set_suspended(dev); ++ pm_runtime_dont_use_autosuspend(dev); ++ ++ return 0; + } + + static const struct sdw_device_id wcd9380_slave_id[] = { +@@ -1320,6 +1344,7 @@ static const struct dev_pm_ops wcd938x_sdw_pm_ops = { + + static struct sdw_driver wcd9380_codec_driver = { + .probe = wcd9380_probe, ++ .remove = wcd9380_remove, + .ops = &wcd9380_slave_ops, + .id_table = wcd9380_slave_id, + .driver = { +diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c +index 2316481c2541b..c3964aa00b288 100644 +--- a/sound/soc/codecs/wcd938x.c ++++ b/sound/soc/codecs/wcd938x.c +@@ -3441,7 +3441,8 @@ static int wcd938x_bind(struct device *dev) + wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode); + if (!wcd938x->rxdev) { + dev_err(dev, "could not find slave with matching of node\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_unbind; + } + wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev); + wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x; +@@ -3449,46 +3450,47 @@ static int wcd938x_bind(struct device *dev) + wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode); + if (!wcd938x->txdev) { + dev_err(dev, "could not find txslave with matching of node\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_put_rxdev; + } + wcd938x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd938x->txdev); + wcd938x->sdw_priv[AIF1_CAP]->wcd938x = wcd938x; + wcd938x->tx_sdw_dev = dev_to_sdw_dev(wcd938x->txdev); +- if (!wcd938x->tx_sdw_dev) { +- dev_err(dev, "could not get txslave with matching of dev\n"); +- return -EINVAL; +- } + + /* As TX is main CSR reg interface, which should not be suspended first. + * expicilty add the dependency link */ + if (!device_link_add(wcd938x->rxdev, wcd938x->txdev, DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME)) { + dev_err(dev, "could not devlink tx and rx\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_put_txdev; + } + + if (!device_link_add(dev, wcd938x->txdev, DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME)) { + dev_err(dev, "could not devlink wcd and tx\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_remove_rxtx_link; + } + + if (!device_link_add(dev, wcd938x->rxdev, DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME)) { + dev_err(dev, "could not devlink wcd and rx\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_remove_tx_link; + } + + wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL); + if (!wcd938x->regmap) { + dev_err(dev, "could not get TX device regmap\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_remove_rx_link; + } + + ret = wcd938x_irq_init(wcd938x, dev); + if (ret) { + dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret); +- return ret; ++ goto err_remove_rx_link; + } + + wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq; +@@ -3497,27 +3499,45 @@ static int wcd938x_bind(struct device *dev) + ret = wcd938x_set_micbias_data(wcd938x); + if (ret < 0) { + dev_err(dev, "%s: bad micbias pdata\n", __func__); +- return ret; ++ goto err_remove_rx_link; + } + + ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x, + wcd938x_dais, ARRAY_SIZE(wcd938x_dais)); +- if (ret) ++ if (ret) { + dev_err(dev, "%s: Codec registration failed\n", + __func__); ++ goto err_remove_rx_link; ++ } + +- return ret; ++ return 0; ++ ++err_remove_rx_link: ++ device_link_remove(dev, wcd938x->rxdev); ++err_remove_tx_link: ++ device_link_remove(dev, wcd938x->txdev); ++err_remove_rxtx_link: ++ device_link_remove(wcd938x->rxdev, wcd938x->txdev); ++err_put_txdev: ++ put_device(wcd938x->txdev); ++err_put_rxdev: ++ put_device(wcd938x->rxdev); ++err_unbind: ++ component_unbind_all(dev, wcd938x); + ++ return ret; + } + + static void wcd938x_unbind(struct device *dev) + { + struct wcd938x_priv *wcd938x = dev_get_drvdata(dev); + ++ snd_soc_unregister_component(dev); + device_link_remove(dev, wcd938x->txdev); + device_link_remove(dev, wcd938x->rxdev); + device_link_remove(wcd938x->rxdev, wcd938x->txdev); +- snd_soc_unregister_component(dev); ++ put_device(wcd938x->txdev); ++ put_device(wcd938x->rxdev); + component_unbind_all(dev, wcd938x); + } + +diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c +index 430dd446321e5..452f0caf415b9 100644 +--- a/sound/soc/pxa/pxa-ssp.c ++++ b/sound/soc/pxa/pxa-ssp.c +@@ -779,7 +779,7 @@ static int pxa_ssp_probe(struct snd_soc_dai *dai) + if (IS_ERR(priv->extclk)) { + ret = PTR_ERR(priv->extclk); + if (ret == -EPROBE_DEFER) +- return ret; ++ goto err_priv; + + priv->extclk = NULL; + } +diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc +new file mode 100644 +index 0000000000000..bc9514428dbaf +--- /dev/null ++++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc +@@ -0,0 +1,13 @@ ++#!/bin/sh ++# SPDX-License-Identifier: GPL-2.0 ++# description: Test failure of registering kprobe on non unique symbol ++# requires: kprobe_events ++ ++SYMBOL='name_show' ++ ++# We skip this test on kernel where SYMBOL is unique or does not exist. ++if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}" /proc/kallsyms)" -le '1' ]; then ++ exit_unsupported ++fi ++ ++! echo "p:test_non_unique ${SYMBOL}" > kprobe_events +diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh +index 7b20878a1af59..ea6fc59e9f62f 100755 +--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh +@@ -1413,7 +1413,9 @@ chk_rst_nr() + count=$(get_counter ${ns_tx} "MPTcpExtMPRstTx") + if [ -z "$count" ]; then + echo -n "[skip]" +- elif [ $count -lt $rst_tx ]; then ++ # accept more rst than expected except if we don't expect any ++ elif { [ $rst_tx -ne 0 ] && [ $count -lt $rst_tx ]; } || ++ { [ $rst_tx -eq 0 ] && [ $count -ne 0 ]; }; then + echo "[fail] got $count MP_RST[s] TX expected $rst_tx" + fail_test + dump_stats=1 +@@ -1425,7 +1427,9 @@ chk_rst_nr() + count=$(get_counter ${ns_rx} "MPTcpExtMPRstRx") + if [ -z "$count" ]; then + echo -n "[skip]" +- elif [ "$count" -lt "$rst_rx" ]; then ++ # accept more rst than expected except if we don't expect any ++ elif { [ $rst_rx -ne 0 ] && [ $count -lt $rst_rx ]; } || ++ { [ $rst_rx -eq 0 ] && [ $count -ne 0 ]; }; then + echo "[fail] got $count MP_RST[s] RX expected $rst_rx" + fail_test + dump_stats=1 +@@ -2259,6 +2263,7 @@ remove_tests() + run_tests $ns1 $ns2 10.0.1.1 0 0 -1 slow + chk_join_nr 1 1 1 + chk_rm_nr 1 1 ++ chk_rst_nr 0 0 + fi + + # multiple subflows, remove +@@ -2270,6 +2275,7 @@ remove_tests() + run_tests $ns1 $ns2 10.0.1.1 0 0 -2 slow + chk_join_nr 2 2 2 + chk_rm_nr 2 2 ++ chk_rst_nr 0 0 + fi + + # single address, remove +@@ -2281,6 +2287,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_add_nr 1 1 + chk_rm_nr 1 1 invert ++ chk_rst_nr 0 0 + fi + + # subflow and signal, remove +@@ -2293,6 +2300,7 @@ remove_tests() + chk_join_nr 2 2 2 + chk_add_nr 1 1 + chk_rm_nr 1 1 ++ chk_rst_nr 0 0 + fi + + # subflows and signal, remove +@@ -2306,6 +2314,7 @@ remove_tests() + chk_join_nr 3 3 3 + chk_add_nr 1 1 + chk_rm_nr 2 2 ++ chk_rst_nr 0 0 + fi + + # addresses remove +@@ -2319,6 +2328,7 @@ remove_tests() + chk_join_nr 3 3 3 + chk_add_nr 3 3 + chk_rm_nr 3 3 invert ++ chk_rst_nr 0 0 + fi + + # invalid addresses remove +@@ -2332,6 +2342,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_add_nr 3 3 + chk_rm_nr 3 1 invert ++ chk_rst_nr 0 0 + fi + + # subflows and signal, flush +@@ -2345,6 +2356,7 @@ remove_tests() + chk_join_nr 3 3 3 + chk_add_nr 1 1 + chk_rm_nr 1 3 invert simult ++ chk_rst_nr 0 0 + fi + + # subflows flush +@@ -2362,6 +2374,7 @@ remove_tests() + else + chk_rm_nr 3 3 + fi ++ chk_rst_nr 0 0 + fi + + # addresses flush +@@ -2375,6 +2388,7 @@ remove_tests() + chk_join_nr 3 3 3 + chk_add_nr 3 3 + chk_rm_nr 3 3 invert simult ++ chk_rst_nr 0 0 + fi + + # invalid addresses flush +@@ -2388,6 +2402,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_add_nr 3 3 + chk_rm_nr 3 1 invert ++ chk_rst_nr 0 0 + fi + + # remove id 0 subflow +@@ -2398,6 +2413,7 @@ remove_tests() + run_tests $ns1 $ns2 10.0.1.1 0 0 -9 slow + chk_join_nr 1 1 1 + chk_rm_nr 1 1 ++ chk_rst_nr 0 0 + fi + + # remove id 0 address +@@ -2409,6 +2425,7 @@ remove_tests() + chk_join_nr 1 1 1 + chk_add_nr 1 1 + chk_rm_nr 1 1 invert ++ chk_rst_nr 0 0 invert + fi + } + +diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh +index 7ce46700a3ae3..52054a09d575c 100755 +--- a/tools/testing/selftests/net/openvswitch/openvswitch.sh ++++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh +@@ -3,6 +3,8 @@ + # + # OVS kernel module self tests + ++trap ovs_exit_sig EXIT TERM INT ERR ++ + # Kselftest framework requirement - SKIP code is 4. + ksft_skip=4 + +@@ -115,7 +117,7 @@ run_test() { + fi + + if python3 ovs-dpctl.py -h 2>&1 | \ +- grep "Need to install the python" >/dev/null 2>&1; then ++ grep -E "Need to (install|upgrade) the python" >/dev/null 2>&1; then + stdbuf -o0 printf "TEST: %-60s [PYLIB]\n" "${tdesc}" + return $ksft_skip + fi +diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +index 5d467d1993cb1..e787a1f967b0d 100644 +--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py ++++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +@@ -17,8 +17,10 @@ try: + from pyroute2.netlink import nla + from pyroute2.netlink.exceptions import NetlinkError + from pyroute2.netlink.generic import GenericNetlinkSocket ++ import pyroute2 ++ + except ModuleNotFoundError: +- print("Need to install the python pyroute2 package.") ++ print("Need to install the python pyroute2 package >= 0.6.") + sys.exit(0) + + +@@ -280,6 +282,12 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB()): + + + def main(argv): ++ # version check for pyroute2 ++ prverscheck = pyroute2.__version__.split(".") ++ if int(prverscheck[0]) == 0 and int(prverscheck[1]) < 6: ++ print("Need to upgrade the python pyroute2 package to >= 0.6.") ++ sys.exit(0) ++ + parser = argparse.ArgumentParser() + parser.add_argument( + "-v", +diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh +index bb34329e02a7f..5267c88496d51 100755 +--- a/tools/testing/selftests/netfilter/nft_audit.sh ++++ b/tools/testing/selftests/netfilter/nft_audit.sh +@@ -11,6 +11,12 @@ nft --version >/dev/null 2>&1 || { + exit $SKIP_RC + } + ++# Run everything in a separate network namespace ++[ "${1}" != "run" ] && { unshare -n "${0}" run; exit $?; } ++ ++# give other scripts a chance to finish - audit_logread sees all activity ++sleep 1 ++ + logfile=$(mktemp) + rulefile=$(mktemp) + echo "logging into $logfile" +diff --git a/tools/testing/selftests/vm/charge_reserved_hugetlb.sh b/tools/testing/selftests/vm/charge_reserved_hugetlb.sh +index a5cb4b09a46c4..0899019a7fcb4 100644 +--- a/tools/testing/selftests/vm/charge_reserved_hugetlb.sh ++++ b/tools/testing/selftests/vm/charge_reserved_hugetlb.sh +@@ -25,7 +25,7 @@ if [[ "$1" == "-cgroup-v2" ]]; then + fi + + if [[ $cgroup2 ]]; then +- cgroup_path=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') ++ cgroup_path=$(mount -t cgroup2 | head -1 | awk '{print $3}') + if [[ -z "$cgroup_path" ]]; then + cgroup_path=/dev/cgroup/memory + mount -t cgroup2 none $cgroup_path +@@ -33,7 +33,7 @@ if [[ $cgroup2 ]]; then + fi + echo "+hugetlb" >$cgroup_path/cgroup.subtree_control + else +- cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk -e '{print $3}') ++ cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') + if [[ -z "$cgroup_path" ]]; then + cgroup_path=/dev/cgroup/memory + mount -t cgroup memory,hugetlb $cgroup_path +diff --git a/tools/testing/selftests/vm/hugetlb_reparenting_test.sh b/tools/testing/selftests/vm/hugetlb_reparenting_test.sh +index bf2d2a684edfd..14d26075c8635 100644 +--- a/tools/testing/selftests/vm/hugetlb_reparenting_test.sh ++++ b/tools/testing/selftests/vm/hugetlb_reparenting_test.sh +@@ -20,7 +20,7 @@ fi + + + if [[ $cgroup2 ]]; then +- CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') ++ CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk '{print $3}') + if [[ -z "$CGROUP_ROOT" ]]; then + CGROUP_ROOT=/dev/cgroup/memory + mount -t cgroup2 none $CGROUP_ROOT +@@ -28,7 +28,7 @@ if [[ $cgroup2 ]]; then + fi + echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control + else +- CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk -e '{print $3}') ++ CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') + if [[ -z "$CGROUP_ROOT" ]]; then + CGROUP_ROOT=/dev/cgroup/memory + mount -t cgroup memory,hugetlb $CGROUP_ROOT |